@vibecook/spaghetti-sdk · RFC 011

API reference

One async product service over a Rust-owned canonical database. Claude Code, Codex, and Grok use the same adapter-neutral query contract.

Install

Requires a supported platform prebuild for @vibecook/spaghetti-sdk-native and Node ≥ 22.13.0.

shell
npm install @vibecook/spaghetti-sdk
ⓘ
Rust only: a missing native binary is an actionable startup error. The retired TypeScript engine is not a package export or fallback.

Quickstart

Configure explicit roots, initialize once, await reads, and always dispose.

app.ts
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();

createObservationService

function createObservationService(options: ObservationServiceOptions): ObservationService
OptionTypeDefaultDescription
dbPathstringrequiredFile-backed database exclusively owned by this host.
sourcesObservationHostSource[]requiredUnique adapter IDs with one or more explicit native roots.
queryWorkersnumber2Persistent read-only SQLite workers.
ownerLabelstringSDK labelDiagnostic owner metadata.
livebooleantrueSubscribe to durable committed changes.
signalAbortSignal—Cancel startup with complete partial-owner cleanup.

Lifecycle

  • initialize(): Promise<void>
  • isReady(): boolean
  • rebuildIndex(): Promise<{ durationMs: number }>
  • snapshot(signal?): Promise<ObservationHostSnapshot>
  • dispose(): Promise<void>

shutdown() starts disposal for compatibility; await dispose() whenever teardown ordering matters.

Async product queries

History

getSourceIds, getProjectList, getSessionList, getSessionMessages, timeline and facets.

Artifacts

Memory, todos, tasks, plans, tool results, subagents, workflows, and teams.

Discovery

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.

Lifecycle and change events

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.

Canonical observation host

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();

Client transports

@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.

Ownership and errors

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.

!
Legacy engine selectors (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.