npm package: @sincover/stele-sdk
Description: STELE JavaScript SDK (Node.js) + optional local bootstrap helpers.
Latest version: 0.2.2

# stele (Node.js)

Dependency-light JavaScript SDK for STELE (CommonJS, Node 18+).

This package contains:
- `index.js`: HTTP client (`SteleClient`)
- `local.js`: optional local bootstrap helpers (`ensureRunning`) that can start a local `steled`
- `index.d.ts` / `local.d.ts`: TypeScript definitions

If you want a deeper dive, see the repo docs at `docs/sdk/js.md`.

## Install

```bash
npm install @sincover/stele-sdk
```

```js
const { SteleClient, APIError } = require("@sincover/stele-sdk");
```

## Client Configuration

```js
const client = new SteleClient({
  baseUrl: "http://127.0.0.1:8080",
  apiVersion: "v1",
  agentId: "agent-1",
  sessionId: "session-1",
  clientId: "my-app",

  // Optional:
  embedderOverride: "",
  opsAuthToken: process.env.STELE_OPS_AUTH_TOKEN, // bearer token for ops endpoints
  timeoutMs: 15000,
});
```

Environment defaults (when not passed explicitly):
- `STELE_BASE_URL`
- `STELE_API_VERSION`
- `STELE_AGENT_ID`
- `STELE_SESSION_ID`
- `STELE_CLIENT_ID`
- `STELE_EMBEDDER_OVERRIDE`
- `STELE_OPS_AUTH_TOKEN` (ops endpoints)
- `STELE_MCP_AUTH_TOKEN` (ops endpoints; convenience fallback)

## Minimal Example: Write + Query

```js
const { SteleClient } = require("@sincover/stele-sdk");

async function main() {
  const client = new SteleClient({
    baseUrl: "http://127.0.0.1:8080",
    agentId: "agent-1",
    sessionId: "session-1",
  });

  const write = await client.write({
    memory: {
      content: "Remember: export returns NDJSON bytes, not a JSON summary.",
      type: "MEMORY_TYPE_PROCEDURAL",
      scope: "SCOPE_AGENT",
      provenance: {
        source_refs: ["run:sdk/js/README.md#minimal-example"],
        citations: [],
        origin_turn_id: "",
      },
      timestamp_ms: Date.now(),
    },
  });

  console.log("wrote:", write?.memory?.id);

  const query = await client.query({
    query_text: "How does export work?",
    budget_tokens: 250,
    scope_order: ["SCOPE_AGENT", "SCOPE_TEAM", "SCOPE_PROJECT", "SCOPE_GLOBAL"],
  });
  console.log("recall count:", (query?.memories || []).length);
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});
```

## Optional: Local Bootstrap (No Go Toolchain)

If you have GitHub Release assets published for this repo, you can bootstrap a local `steled` before creating the client:

```js
const { ensureRunning } = require("@sincover/stele-sdk/local");
const { SteleClient } = require("@sincover/stele-sdk");

async function main() {
  await ensureRunning();
  const client = new SteleClient({ agentId: "agent-1", sessionId: "session-1" });
  console.log(await client.query({ query_text: "sanity check" }));
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});
```

## Error Handling

Non-2xx responses throw `APIError`:

```js
try {
  await client.reindex({});
} catch (err) {
  if (err instanceof APIError) {
    console.error(err.statusCode, err.code, err.requestId, err.message);
  } else {
    console.error(err);
  }
}
```

## Graph Example: Add Edge + List

```js
await client.edgeAdd({
  edge: {
    from_id: "mem-aaa",
    to_id: "mem-bbb",
    type: "EDGE_TYPE_RELATES_TO",
    weight: 1,
    created_at_ms: Date.now(),
  },
});

const edges = await client.edgeList({ node_id: "mem-aaa" });
console.log(edges.edges);
```

## Proactive Surfacing Helper

Use the built-in trigger orchestrator when you want SDK-side proactive suggest parity:

```js
const suggestor = client.createProactiveSuggestor();
await suggestor.trigger("bootstrap", { active_files: ["README.md"] });
await suggestor.trigger("context_shift", {
  active_files: ["src/auth/handler.go"],
  recent_commands: ["plan:implement"],
});
await suggestor.trigger("pre_edit", { active_symbols: ["AuthHandler"] });
```

`ProactiveSuggestor` enforces debounce, context-hash dedupe, rate limits, and payload caps before calling `suggest`.

## Ops Endpoints (Bearer Token)

Ops endpoints require `opsAuthToken` (or env `STELE_OPS_AUTH_TOKEN` / `STELE_MCP_AUTH_TOKEN`):
- `bulkForget`
- `exportNDJSON` / `exportToFile`
- `import`
- `maintenance`
- `reindex`
- `decay`

### Export to File (Convenience)

```js
const ops = new SteleClient({
  baseUrl: "http://127.0.0.1:8080",
  agentId: "agent-1",
  sessionId: "session-1",
  opsAuthToken: process.env.STELE_OPS_AUTH_TOKEN,
});

await ops.exportToFile({ outputPath: "stele-export.jsonl" });
```

### Import

```js
const fs = require("node:fs/promises");
const ndjson = await fs.readFile("stele-export.jsonl", "utf8");
await ops.import({ data: ndjson, strict: false });
```

## API Coverage (Method Map)

Methods map closely to `steled` routes:
- Core: `write`, `query`, `feedback`, `protect`, `supersede`, `forget`
- Retrieval utils: `list`, `get`, `search`, `update`, `verify`, `extract`
- Bulk: `bulkWrite`, `bulkForget` (ops)
- Ops: `exportNDJSON`/`exportToFile`, `import`, `schema`, `metrics`, `maintenance`, `reindex`, `decay`
- Graph: `edgeAdd`, `edgeDelete`, `edgeList`, `edgeTraverse`, `edgeSuggest`
- Proactive/stream: `suggest`, `watch`
- Sharing: `learnShare` (mistake-only)
- Agent/system: `agentGet`, `agentUpsert`, `accessMarkUsed`, `events`, `membershipAdd/remove/list`, `health`, `stats`