From 90191e4604fbc2ad637383564234f46f3e682fba Mon Sep 17 00:00:00 2001 From: tommy0103 Date: Thu, 16 Jul 2026 17:26:23 +0800 Subject: [PATCH] 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. --- .github/workflows/cli.yml | 32 ++ CONTEXT.md | 13 +- README.md | 89 ++-- SKILL.md | 413 ++---------------- app/tests/electron-session-virtualization.mjs | 2 +- .../adr/0001-parse-core-and-persist-layers.md | 13 +- docs/adr/0002-two-tier-runtime-contract.md | 8 +- .../0003-core-typescript-esm-precompiled.md | 27 +- ...004-skill-artifact-readable-not-bundled.md | 33 +- docs/adr/0005-app-electron-vite-ts-esm.md | 2 +- ...te-transaction-rollback-and-concurrency.md | 10 +- eslint.config.js | 7 +- install.sh | 31 ++ package-lock.json | 15 + package.json | 4 +- packages/cli/README.md | 16 + packages/cli/package.json | 24 + packages/cli/scripts/build.mjs | 19 + packages/cli/src/obelisk.ts | 71 +++ packages/cli/tsconfig.build.json | 17 + packages/core/src/core.ts | 6 +- packages/core/src/persist.ts | 2 +- packages/core/src/runtime.ts | 49 --- packages/core/src/tx.ts | 2 +- packaging/build-skill.mjs | 13 + packaging/publish-skill.sh | 2 +- packaging/skill-README.md | 10 +- packaging/skill-package.json | 3 +- packaging/stage-skill-repo.sh | 2 +- skill-doc/SKILL.md | 406 +++++++++++++++++ .../references}/api-reference.md | 12 +- .../references}/pitfalls.md | 0 .../references}/query-patterns.md | 6 +- .../references}/recap-patterns.md | 0 .../references}/recap-writing.md | 0 .../references}/recap/overview.md | 0 .../references}/recap/pattern1-cover.md | 0 .../references}/recap/pattern2-thinking.md | 0 .../references}/recap/pattern3-vibe.md | 0 .../references}/recap/pattern4-workflow.md | 0 .../references}/recap/pattern5-closing.md | 0 .../references}/recap/writing1-cover.md | 0 .../references}/recap/writing2-thinking.md | 0 .../references}/recap/writing3-vibe.md | 0 .../references}/recap/writing4-workflow.md | 0 .../references}/recap/writing5-closing.md | 0 .../references}/retrieval-semantics.md | 0 .../references}/schema.md | 2 +- tests/build-skill.test.mjs | 90 ---- tests/cli-bootstrap-install.test.mjs | 59 +++ tests/cli-package.test.mjs | 122 ++++++ tests/cli-test-helpers.mjs | 18 + tests/codex-index.test.mjs | 11 +- tests/contract-helper-shapes.test.mjs | 2 +- tests/daemon-arbitration.test.mjs | 29 +- tests/db-schema.test.mjs | 8 +- tests/incremental-index.test.mjs | 11 +- tests/publish-skill-layout.test.mjs | 4 +- tests/recap-patterns.test.mjs | 66 +-- tests/runtime-cli-envelope.test.mjs | 17 +- tests/runtime.test.mjs | 15 +- tests/skill-doc-artifact.test.mjs | 31 ++ tsconfig.json | 2 +- tsconfig.skill.json | 11 - 64 files changed, 1112 insertions(+), 745 deletions(-) create mode 100644 .github/workflows/cli.yml create mode 100755 install.sh create mode 100644 packages/cli/README.md create mode 100644 packages/cli/package.json create mode 100644 packages/cli/scripts/build.mjs create mode 100644 packages/cli/src/obelisk.ts create mode 100644 packages/cli/tsconfig.build.json delete mode 100644 packages/core/src/runtime.ts create mode 100644 packaging/build-skill.mjs create mode 100644 skill-doc/SKILL.md rename {references => skill-doc/references}/api-reference.md (97%) rename {references => skill-doc/references}/pitfalls.md (100%) rename {references => skill-doc/references}/query-patterns.md (99%) rename {references => skill-doc/references}/recap-patterns.md (100%) rename {references => skill-doc/references}/recap-writing.md (100%) rename {references => skill-doc/references}/recap/overview.md (100%) rename {references => skill-doc/references}/recap/pattern1-cover.md (100%) rename {references => skill-doc/references}/recap/pattern2-thinking.md (100%) rename {references => skill-doc/references}/recap/pattern3-vibe.md (100%) rename {references => skill-doc/references}/recap/pattern4-workflow.md (100%) rename {references => skill-doc/references}/recap/pattern5-closing.md (100%) rename {references => skill-doc/references}/recap/writing1-cover.md (100%) rename {references => skill-doc/references}/recap/writing2-thinking.md (100%) rename {references => skill-doc/references}/recap/writing3-vibe.md (100%) rename {references => skill-doc/references}/recap/writing4-workflow.md (100%) rename {references => skill-doc/references}/recap/writing5-closing.md (100%) rename {references => skill-doc/references}/retrieval-semantics.md (100%) rename {references => skill-doc/references}/schema.md (98%) delete mode 100644 tests/build-skill.test.mjs create mode 100644 tests/cli-bootstrap-install.test.mjs create mode 100644 tests/cli-package.test.mjs create mode 100644 tests/cli-test-helpers.mjs create mode 100644 tests/skill-doc-artifact.test.mjs delete mode 100644 tsconfig.skill.json diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml new file mode 100644 index 0000000..069667c --- /dev/null +++ b/.github/workflows/cli.yml @@ -0,0 +1,32 @@ +name: CLI + +on: + pull_request: + push: + branches: [main] + +jobs: + package: + name: Node 22 / ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: npm + + - run: npm ci + - run: npm run build:cli + - name: Verify CLI package and runtime contract + run: node --experimental-test-module-mocks --test tests/cli-package.test.mjs tests/runtime-cli-envelope.test.mjs tests/runtime.test.mjs + + - name: Verify POSIX bootstrap installer + if: runner.os != 'Windows' + run: node --test tests/cli-bootstrap-install.test.mjs diff --git a/CONTEXT.md b/CONTEXT.md index 0b07070..b1eaea1 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -10,8 +10,9 @@ not a spec. **Runtime interface**: The public contract, expressed as four verbs — `build`, `search(text)`, -`query(code)`, `attune(code)`. Skill, CLI, and MCP are transports over this same -shape; none of them add their own retrieval surface. +`query(code)`, `attune(code)`. CLI and a future MCP server are transports over +this same shape; neither adds its own retrieval surface. The agent skill is +docs-only guidance that invokes the CLI rather than a transport of its own. _Avoid_: API, tool surface **CodeAct**: @@ -44,7 +45,7 @@ persistence happens. **Persist layer**: The single shared, provider- and binding-agnostic writer that consumes records from any adapter and writes them into an injected SQLite handle inside a -transaction. The binding is injected — `node:sqlite` (skill/CLI) or +transaction. The binding is injected — `node:sqlite` (CLI) or `better-sqlite3` (app) — so there is one persist implementation, not one per binding. _Avoid_: writer, sink, DAO @@ -56,8 +57,8 @@ as files change. _Avoid_: watcher mode, live indexing **Passive pull mode**: -On-demand incremental indexing performed by the skill when there is no active -daemon: an invocation of the runtime brings the index up to date, then answers. +On-demand incremental indexing performed by a CLI invocation when there is no +active daemon: the command brings the index up to date, then answers. _Avoid_: lazy indexing, on-read indexing **index_state**: @@ -68,7 +69,7 @@ arbitration. **Daemon arbitration**: The policy by which the passive pull mode detects a fresh daemon from the -`__app_heartbeat__` marker and skips every skill-side mutation, including schema +`__app_heartbeat__` marker and skips every CLI-side mutation, including schema setup, indexing, checkpointing, and `attune`. The heartbeat alone means “the daemon should write”; `__app_last_successful_build__` records coverage/freshness, not ownership. Both indexing modes use the same persist layer. diff --git a/README.md b/README.md index 1ba78a3..b516468 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,9 @@ Every past Claude Code and Codex session -- queryable by your agent, browsable b Obelisk has two sides that share one SQLite index: -**Skill side** — an agent skill that lets coding agents search and query their own session history. The agent writes JS queries, runs them locally, answers in plain language. +**Agent side** — the `obelisk` CLI owns the local runtime, while a separate +agent skill teaches coding agents how to search and query their session history. +The agent writes JS queries, runs them locally, and answers in plain language. **App side** — an Electron desktop app for humans to browse sessions, manage memories, view usage stats, and see weekly recap cards. @@ -51,11 +53,31 @@ You can use obelisk like: ### Install +Obelisk requires Node.js 22.13 or newer. Install the platform-neutral CLI first: + ```bash -npx skills add tommy0103/obelisk-skill +npm install --global @obelisk-apps/cli +obelisk --version ``` -Or manually: copy `obelisk-skill/skills/obelisk into your project's `.claude/skills/` +On macOS, Linux, or WSL, the CLI-only installer is equivalent: + +```bash +curl -fsSL https://raw.githubusercontent.com/tommy0103/obelisk/main/install.sh | sh +``` + +Then install the agent skill: + +```bash +obelisk install +``` + +`obelisk install` delegates to the standard skills installer for +`tommy0103/obelisk-skill`. To let an agent perform the one-time bootstrap, give +it the repository's root +[`SKILL.md`](https://raw.githubusercontent.com/tommy0103/obelisk/main/SKILL.md). +That document installs the CLI and formal skill; it is not the query skill +itself. Then in any Claude Code session: @@ -72,7 +94,7 @@ You ask a question ↓ Agent writes a JS query against the SQLite index ↓ -Runs it via node $SKILL_DIR/scripts/runtime.js --query