History
getSourceIds, getProjectList, getSessionList, getSessionMessages, timeline and facets.
One async product service over a Rust-owned canonical database. Claude Code, Codex, and Grok use the same adapter-neutral query contract.
Requires a supported platform prebuild for @vibecook/spaghetti-sdk-native and Node ≥ 22.13.0.
npm install @vibecook/spaghetti-sdkConfigure explicit roots, initialize once, await reads, and always dispose.
import { homedir } from 'node:os';
import { join } from 'node:path';
import { createObservationService } from '@vibecook/spaghetti-sdk';
const api = createObservationService({
dbPath: join(homedir(), '.spaghetti/cache/spaghetti-rs.db'),
sources: [
{ adapterId: 'claude-code', roots: [join(homedir(), '.claude')] },
{ adapterId: 'codex', roots: [join(homedir(), '.codex')] },
{ adapterId: 'grok', roots: [join(homedir(), '.grok')] },
],
live: true,
});
await api.initialize();
const projects = await api.getProjectList();
const sourceId = projects[0].members[0].sourceId;
const sessions = await api.getSessionList(projects[0], { sourceId });
const hits = await api.search({ text: 'refactor parser', sourceId });
await api.dispose();function createObservationService(options: ObservationServiceOptions): ObservationService
| Option | Type | Default | Description |
|---|---|---|---|
| dbPath | string | required | File-backed database exclusively owned by this host. |
| sources | ObservationHostSource[] | required | Unique adapter IDs with one or more explicit native roots. |
| queryWorkers | number | 2 | Persistent read-only SQLite workers. |
| ownerLabel | string | SDK label | Diagnostic owner metadata. |
| live | boolean | true | Subscribe to durable committed changes. |
| signal | AbortSignal | — | Cancel startup with complete partial-owner cleanup. |
initialize(): Promise<void>isReady(): booleanrebuildIndex(): Promise<{ durationMs: number }>snapshot(signal?): Promise<ObservationHostSnapshot>dispose(): Promise<void>shutdown() starts disposal for compatibility; await dispose() whenever teardown ordering matters.
getSourceIds, getProjectList, getSessionList, getSessionMessages, timeline and facets.
Memory, todos, tasks, plans, tool results, subagents, workflows, and teams.
search, token activity, and getStats. Multi-source drill-downs accept sourceId.
Returned message DTOs are identical across adapters. Source-native envelopes stay in Rust detail storage and are never interpreted by applications.
const offProgress = api.onProgress((progress) => console.log(progress));
const offReady = api.onReady((info) => console.log(info.durationMs));
const offChange = api.onChange(() => refreshVisibleSnapshot());
Changes are durable projection invalidations. Consumers refresh through queries instead of decoding source paths or maintaining a second event-semantic authority.
Import openObservationHost from @vibecook/spaghetti-sdk/observation for typed canonical DTOs and direct access to host.client.
const host = await openObservationHost({ dbPath, sources });
const sourcePage = await host.client.listSources();
const projectPage = await host.client.listProjects();
await host.dispose();
@vibecook/spaghetti-sdk/client provides the same negotiated protocol over embedded N-API and framed IPC transports. Electron can keep N-API in one utility owner while main and renderer processes use portable clients.
Exactly one host may own a database. A competing owner is rejected with diagnostic metadata. Startup cancellation or adapter failure disposes every supervisor, worker, client, and lock before rejecting.
SPAG_ENGINE, SPAG_NATIVE_INGEST, and persisted engine: "ts") are ignored. Use a repository differential command—not an application setting—to run old oracle code.