Files
obelisk/skill-doc/references/api-reference.md
T
tommy0103 90191e4604 feat(cli): extract Obelisk runtime into npm package
Add @obelisk-apps/cli with the existing build, search, query, and attune contract plus official skill installation.

Separate the docs-only skill artifact, bootstrap installer, release layout, cross-platform CI, and package-level regression coverage.
2026-07-16 17:26:23 +08:00

470 lines
14 KiB
Markdown

# Obelisk -- Helper API Reference
Detailed reference for globals available inside `obelisk --query` and
`obelisk --attune` scripts.
- Use `references/schema.md` for raw SQL table/field/join checks.
- Use `references/query-patterns.md` for copyable retrieval plans.
- Use `references/retrieval-semantics.md` for query design and scope choices.
- Use `references/pitfalls.md` after runtime errors or confusing row shapes.
Query scripts run inside an async IIFE with a 30-second timeout. Use `return` to
emit JSON. `--query` scripts are read-only. `--attune` scripts expose only
memory mutation helpers.
## Query API Reference
### Read Helpers
These globals are available only in `obelisk --query` scripts:
```js
sql, search, context, trace, thread, raw,
overview, sessions, recent, summaries, memories,
subagents, workflows, workflowTree, fileHistory, failures
```
All list helpers accept bounded `limit` options. Many helpers also accept
`project`, `sessionId`, `sessions`, `after`, `before`, `branch`, and `source`
when the underlying table can express that scope. Passing a string to many list
helpers is treated as `sessionId`; passing a number is treated as `limit`.
### Mutation Helpers
These globals are available only in `obelisk --attune` scripts:
```js
remember, forget
```
`--attune` does not expose `search()`, `sql()`, `memories()`, or other read
helpers. If you need IDs, discover them first with a normal `--query` script.
---
## Core Helpers
#### `search(text, opts?)`
Full-text search across all indexed message text using FTS5.
| Param | Type | Description |
| --- | --- | --- |
| `text` | `string` | FTS5 query string |
| `opts.limit` | `number` | Max results, default 20 |
| `opts.sessionId` | `string` | Restrict to one session |
| `opts.project` | `string` | SQL `LIKE` pattern over `sessions.project` |
| `opts.after` | `string` | ISO lower bound on message timestamp |
| `opts.before` | `string` | ISO upper bound on message timestamp |
| `opts.cwd` | `string` | SQL `LIKE` filter over `messages.cwd` |
| `opts.source` | `string` | `"claude"`, `"codex"`, or omitted/all |
| `opts.includeMeta` | `boolean` | Include `is_meta=1` rows, default false |
Returns:
```js
Array<{
message: { uuid, text, content_type, is_meta, role, timestamp, model, cwd, source },
session: { id, title, project, started_at, source },
rank,
context
}>
```
`context` is temporal neighbor context in the same session, not a parent chain.
Use `context(uuid)` or `trace(uuid)` for causal/parent-chain expansion. Lower
FTS rank sorts earlier; prefer returned order unless deliberately inspecting
FTS ranking.
Valid FTS5 syntax in `text` is honored. Input that FTS5 would reject as
malformed (for example a hyphenated term like `foo-bar`) does not error: it
falls back to safe per-token quoting — the same tokenization `memories()` uses —
so ordinary text never crashes the query.
#### `context(uuid)`
Full indexed context around one message.
| Param | Type | Description |
| --- | --- | --- |
| `uuid` | `string` | Message UUID |
Returns:
```js
{ message, parentChain, session, subagent, workflow } | null
```
`parentChain` contains ancestors, not temporal neighbors. If the message belongs
to a subagent or workflow agent, `subagent` or `workflow` is populated when the
metadata exists.
#### `sql(query, ...params)`
Read-only SQL helper with positional `?` bindings.
| Param | Type | Description |
| --- | --- | --- |
| `query` | `string` | `SELECT` or `WITH` statement |
| `...params` | `any` | Bind values |
Returns `Array<object>`.
Write statements are rejected. Use `references/schema.md` before non-trivial SQL
joins, and use `--attune` with `remember()` / `forget()` for memory mutation.
---
## Orientation And Lists
#### `overview(opts?)`
Compact orientation map for choosing retrieval scope. It is not evidence: it
does not return snippets, full messages, or markdown memory contents.
Passing a string is treated as `project`. Passing a number is treated as
`limit`.
| Param | Type | Description |
| --- | --- | --- |
| `opts.project` | `string` | Project slug or SQL `LIKE` pattern to use as current scope |
| `opts.limit` | `number` | Max recent sessions in `current_project.sessions`, default 8 |
| `opts.projectLimit` | `number` | Max global project rows, default 20 |
| `opts.memoryLimit` | `number` | Max memories in `current_project.memories`, default 100 |
If `opts.project` is absent, `overview()` tries to identify the current project
from `process.cwd()` against `sessions.project_path`, then from exact
`messages.cwd` matches. It does not guess the current session.
Returns:
```js
{
current: {
cwd,
project: {
project,
project_path,
source: 'opts' | 'cwd_project_path' | 'cwd_messages',
confidence: 'exact' | 'inferred' | 'unknown'
} | null
},
current_project: {
project,
project_path,
session_total,
sessions: [
{ id, title, project, project_path, started_at, ended_at, git_branch, message_count, source }
],
memory_total,
memories: [
{ id, path, anchors, summary, session_id, project, created_at }
]
} | null,
projects: [
{
project,
project_path,
session_count,
memory_count,
last_session_at,
last_memory_at,
recent_branches
}
],
totals: {
projects,
sessions,
memories,
sources: [{ source: 'claude' | 'codex', session_count, last_session_at }]
}
}
```
Confirm facts with `memories()`, `search()`, other helpers, or `sql()`.
#### `sessions(opts?)`
Session rows ordered by `ended_at` descending. Passing a number is treated as
`limit`.
| Param | Type | Description |
| --- | --- | --- |
| `opts.project` | `string` | SQL `LIKE` pattern over `sessions.project` |
| `opts.after` | `string` | ISO lower bound on `started_at` |
| `opts.before` | `string` | ISO upper bound on `started_at` |
| `opts.limit` | `number` | Max rows, default 50 |
| `opts.branch` | `string` | Exact git branch |
| `opts.source` | `string` | `"claude"`, `"codex"`, or omitted/all |
| `opts.sessionId` | `string` | Exact session ID |
| `opts.sessions` | `string[]` | Restrict to session IDs |
Returns `Array<session_row>`.
#### `recent(n?)`
Shorthand for `sessions({ limit: n })`. Default `n` is 10.
Returns `Array<session_row>`.
#### `summaries(opts?)`
Session summary rows ordered by summary `timestamp` descending. Passing a string
is treated as `sessionId`; passing a number is treated as `limit`.
| Param | Type | Description |
| --- | --- | --- |
| `opts.sessionId` | `string` | Restrict to one session |
| `opts.sessions` | `string[]` | Restrict to session IDs |
| `opts.project` | `string` | SQL `LIKE` pattern over source session project |
| `opts.after` | `string` | ISO lower bound on summary timestamp |
| `opts.before` | `string` | ISO upper bound on summary timestamp |
| `opts.branch` | `string` | Exact source session branch |
| `opts.source` | `string` | Provider filter through joined session |
| `opts.limit` | `number` | Max rows, default 100 |
Returns:
```js
Array<summary_row & { session_title, project }>
```
`summaries.source` is the summary kind, such as `away_summary`; it is not the
provider source.
#### `memories(opts?)`
Active registered markdown memory records. Passing a string is treated as
`sessionId`; passing a number is treated as `limit`.
| Param | Type | Description |
| --- | --- | --- |
| `opts.query` | `string` | English recall query over `summary` and `path` |
| `opts.project` | `string` | SQL `LIKE` pattern over `memories.project` |
| `opts.sessionId` | `string` | Restrict to one source session |
| `opts.sessions` | `string[]` | Restrict to source session IDs |
| `opts.after` | `string` | ISO lower bound on `created_at` |
| `opts.before` | `string` | ISO upper bound on `created_at` |
| `opts.branch` | `string` | Exact source session branch |
| `opts.source` | `string` | Provider filter through the source session |
| `opts.limit` | `number` | Max rows, default 50 |
Returns:
```js
Array<memory_row & { rank?: number }>
```
Archived memories are omitted. Without `query`, rows are newest first. With
`query`, rows are ordered by safe FTS rank first, then `created_at` descending.
Lower rank sorts earlier. Translate non-English requests into concise English
query terms before calling `memories()`. Read the markdown file at `path` for
full content.
---
## Structural Expansion Helpers
#### `trace(uuid)`
Walk the `parent_uuid` chain from a message to the conversation root.
Returns `Array<message>` ordered root-first.
#### `thread(sessionId, opts?)`
Messages in a session ordered by timestamp.
| Param | Type | Description |
| --- | --- | --- |
| `sessionId` | `string` | Session ID |
| `opts.includeMeta` | `boolean` | Include injected/control-plane rows, default false |
Returns `Array<message>`. Use `thread()` as a last resort; prefer targeted
search/context or compact SQL projections.
#### `raw(uuid, opts?)`
Windowed access to the original JSONL line for one indexed message. Use this
when indexed text, tool inputs, or tool results were truncated and you need the
raw source.
| Param | Type | Description |
| --- | --- | --- |
| `uuid` | `string` | Message UUID |
| `opts.offset` | `number` | Character offset into the JSONL line, default 0 |
| `opts.limit` | `number` | Max characters, default 10000 |
Returns:
```js
{ text, totalLength, offset, limit, hasMore } | null
```
`raw()` resolves main-session, subagent, workflow-agent, and Codex JSONL paths
from indexed metadata.
---
## Agent And Workflow Helpers
#### `subagents(opts?)`
Subagent metadata plus message counts. Passing a string is treated as
`sessionId`.
| Param | Type | Description |
| --- | --- | --- |
| `opts.sessionId` | `string` | Restrict to one session |
| `opts.project` | `string` | SQL `LIKE` pattern over source session project |
| `opts.source` | `string` | Provider filter |
| `opts.limit` | `number` | Max rows, default 100 |
Returns:
```js
Array<{ ...subagent_row, messageCount }>
```
#### `workflows(opts?)`
Workflow run rows ordered newest first. Passing a string is treated as
`sessionId`.
| Param | Type | Description |
| --- | --- | --- |
| `opts.sessionId` | `string` | Restrict to one session |
| `opts.project` | `string` | SQL `LIKE` pattern over source session project |
| `opts.after` | `string` | ISO lower bound on workflow timestamp |
| `opts.before` | `string` | ISO upper bound on workflow timestamp |
| `opts.source` | `string` | Provider filter |
| `opts.limit` | `number` | Max rows, default 100 |
Returns `Array<workflow_row>`.
#### `workflowTree(runId)`
Lightweight execution tree for one workflow run. It parses `result_json` and
adds per-agent message counts. It does not load agent messages.
Returns:
```js
{ ...workflow_row, result: object | null, agents: Array<{ ...workflow_agent_row, messageCount }> } | null
```
---
## Evidence Helpers
#### `fileHistory(filePath, opts?)`
Tool calls that touched one file, ordered oldest first. Includes `Read` rows as
well as `Edit`/`Write`.
| Param | Type | Description |
| --- | --- | --- |
| `filePath` | `string` | Absolute file path |
| `opts.after` | `string` | ISO lower bound |
| `opts.before` | `string` | ISO upper bound |
| `opts.source` | `string` | Provider filter |
| `opts.limit` | `number` | Max rows, default 200 |
Returns:
```js
Array<{
toolCall: { id, message_uuid, name, input_json },
session: { id, title, project },
timestamp
}>
```
Use raw SQL with `ORDER BY m.timestamp DESC` when you need newest-first file
history.
#### `failures(opts?)`
Failed tool results with tool/session context and the next three messages after
the failure. Passing a string is treated as `sessionId`.
| Param | Type | Description |
| --- | --- | --- |
| `opts.sessionId` | `string` | Restrict to one session |
| `opts.project` | `string` | SQL `LIKE` pattern over source session project |
| `opts.after` | `string` | ISO lower bound on result message timestamp |
| `opts.before` | `string` | ISO upper bound on result message timestamp |
| `opts.source` | `string` | Provider filter |
| `opts.limit` | `number` | Max rows, default 50 |
Returns:
```js
Array<{ toolCall, result, session, nextMessages }>
```
Use SQL for precise counts and grouping; treat `failures()` as compact evidence,
not a counting primitive.
---
## Memory Mutation Helpers
#### `remember(record)`
Register a human-approved markdown memory file. Available only in
`obelisk --attune` scripts.
| Param | Type | Description |
| --- | --- | --- |
| `record.path` | `string` | Existing markdown file path |
| `record.summary` | `string` | Required English retrieval summary |
| `record.session_id` | `string` | Source session ID, if known |
| `record.message_start` | `string` | First relevant source message UUID |
| `record.message_end` | `string` | Last relevant source message UUID |
| `record.project` | `string` | Project slug override |
| `record.anchors` | `array` or JSON `string` | Optional recall anchors |
Relative paths resolve against the source session `project_path` when
`session_id` is provided, otherwise against the runtime cwd. `remember()`
validates that `path` exists and is a regular file, rejects obvious CJK text in
`summary`, stores the normalized absolute path, and accepts nullable `anchors`.
Returns:
```js
{ id, path, project, anchors, created_at }
```
#### `forget(record)`
Archive a human-approved memory record. Available only in
`obelisk --attune` scripts.
| Param | Type | Description |
| --- | --- | --- |
| `record.id` | `string` | Exact memory ID |
| `record.reason` | `string` | Required archive reason |
`forget()` sets `deleted_at` and `deleted_reason`. It does not delete the
markdown file at `path`. Active recall helpers omit archived rows.
Returns:
```js
{ id, deleted_at, deleted_reason } |
{ id, deleted_at, deleted_reason, already_deleted: true }
```
### Memory Mutation Approval
Agents may decide whether to use, ignore, or verify memory in a single answer
without approval. Approval is required only for persistent memory mutations.
When the user explicitly says a memory is wrong, outdated, should be forgotten,
or should say something else, that utterance is approval to mutate the exact
matching memory. If multiple memories could match, ask the user to choose.
Updating is not in-place: archive the old record with `forget()`, then write and
register a replacement markdown file with `remember()` under the same approval.