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.
This commit is contained in:
tommy0103
2026-07-16 17:26:23 +08:00
parent 49158e9b9c
commit 90191e4604
64 changed files with 1112 additions and 745 deletions
@@ -7,7 +7,8 @@
> persist layer, not one per binding.
**Context.** Obelisk had two divergent full indexers — the former
`scripts/indexer.mjs` (`node:sqlite`, skill/runtime) and `app/indexer.js`
`scripts/indexer.mjs` (`node:sqlite`, the former skill-embedded runtime) and
`app/indexer.js`
(`better-sqlite3`, Electron
app) — that duplicated the same Claude and Codex JSONL parsing and had silently
diverged in write semantics (`INSERT OR REPLACE` vs `ON CONFLICT DO UPDATE`,
@@ -31,14 +32,14 @@ binding-agnostic and does not need a per-binding implementation.
incremental `index_state` bookkeeping, FTS maintenance, and the canonical
**upsert** (`ON CONFLICT(uuid) DO UPDATE`) write semantics reconciled from the
drift on 2026-07-08. The database handle is *injected*, so `node:sqlite`
(skill/CLI) and `better-sqlite3` (app) run the same code — there is no
(CLI) and `better-sqlite3` (app) run the same code — there is no
per-binding persist layer.
**Two indexing modes** share all of the above and differ only in trigger:
**daemon mode** (app/CLI watches and keeps the index fresh) and **passive pull
mode** (skill indexes on invocation when no daemon is active). They never write
concurrently — passive mode detects a fresh daemon via heartbeat markers in
`index_state` (**daemon arbitration**).
**daemon mode** (the app, and potentially a future CLI daemon, watches and keeps
the index fresh) and **passive pull mode** (a CLI command indexes on invocation
when no daemon is active). They never write concurrently — passive mode detects
a fresh daemon via heartbeat markers in `index_state` (**daemon arbitration**).
**Consequences.** Golden tests anchor on each adapter's `parse` output (feed
fixture JSONL, assert the yielded record sequence) — independent of binding and