@tekmidian/pai 0.54.0 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{aibroker-client-CNfIBrl5.mjs → aibroker-client-B8Wtasez.mjs} +1 -1
- package/dist/{aibroker-client-DzkTpVjx.mjs → aibroker-client-BK1h--W_.mjs} +3 -3
- package/dist/{aibroker-client-DzkTpVjx.mjs.map → aibroker-client-BK1h--W_.mjs.map} +1 -1
- package/dist/{indexer-backend-CdvCJCkD.mjs → async-CLvuY7b-.mjs} +7 -7
- package/dist/async-CLvuY7b-.mjs.map +1 -0
- package/dist/auto-route-CF8WNaoy.mjs +100 -0
- package/dist/auto-route-CF8WNaoy.mjs.map +1 -0
- package/dist/{chain-BcBDJ1Id.mjs → chain-DogidBji.mjs} +4 -4
- package/dist/{chain-BcBDJ1Id.mjs.map → chain-DogidBji.mjs.map} +1 -1
- package/dist/cli/index.mjs +22 -23
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/program.d.mts.map +1 -1
- package/dist/cli/program.mjs +22 -23
- package/dist/{clusters-Cw_P6lO-.mjs → clusters-Ci1mseh2.mjs} +4 -36
- package/dist/clusters-Ci1mseh2.mjs.map +1 -0
- package/dist/{config-B3EPzRjf.mjs → config-B93YS8tP.mjs} +3 -3
- package/dist/{config-B3EPzRjf.mjs.map → config-B93YS8tP.mjs.map} +1 -1
- package/dist/{config-Bn9jpblO.mjs → config-D1omG_UU.mjs} +3 -3
- package/dist/{config-Bn9jpblO.mjs.map → config-D1omG_UU.mjs.map} +1 -1
- package/dist/{config-RjeVGJ7K.mjs → config-DCYWFaEi.mjs} +1 -1
- package/dist/{context-handover-cache-CXyH6QsC.mjs → context-handover-cache-k2kWbE6G.mjs} +82 -99
- package/dist/context-handover-cache-k2kWbE6G.mjs.map +1 -0
- package/dist/daemon/index.mjs +18 -24
- package/dist/daemon/index.mjs.map +1 -1
- package/dist/daemon-B7Y8GQnt.mjs +19 -0
- package/dist/{daemon-BkJNFWr9.mjs → daemon-Cgrdvdo6.mjs} +97 -466
- package/dist/daemon-Cgrdvdo6.mjs.map +1 -0
- package/dist/daemon-mcp/index.mjs +10 -10
- package/dist/daemon-mcp/index.mjs.map +1 -1
- package/dist/{detector-DWXkeTlk.mjs → detector-3g7XuU1r.mjs} +5 -12
- package/dist/detector-3g7XuU1r.mjs.map +1 -0
- package/dist/detector-DgDn56j-.mjs +3 -0
- package/dist/{embeddings-ClqKtLZ8.mjs → embeddings-BNv3TQC5.mjs} +1 -1
- package/dist/{embeddings-DvRKcQyt.mjs → embeddings-DfrYNIng.mjs} +1 -1
- package/dist/{embeddings-DvRKcQyt.mjs.map → embeddings-DfrYNIng.mjs.map} +1 -1
- package/dist/factory-C9wGUe30.mjs +3 -0
- package/dist/factory-DiuntvwG.mjs +250 -0
- package/dist/factory-DiuntvwG.mjs.map +1 -0
- package/dist/{fallback-CPfyTSTx.mjs → fallback-DS6AEJsU.mjs} +190 -132
- package/dist/fallback-DS6AEJsU.mjs.map +1 -0
- package/dist/federation-db-CJDw_Pwq.mjs +3 -0
- package/dist/{db-DJ8rk0VM.mjs → federation-db-w8e-sKjp.mjs} +5 -5
- package/dist/federation-db-w8e-sKjp.mjs.map +1 -0
- package/dist/{helpers-crDEr6S2.mjs → helpers-D9WkIf9R.mjs} +1 -1
- package/dist/{helpers-crDEr6S2.mjs.map → helpers-D9WkIf9R.mjs.map} +1 -1
- package/dist/hooks/capture-all-events.mjs.map +1 -1
- package/dist/hooks/capture-session-summary.mjs.map +1 -1
- package/dist/hooks/capture-tool-output.mjs.map +1 -1
- package/dist/hooks/context-compression-hook.mjs.map +1 -1
- package/dist/hooks/load-core-context.mjs +5 -0
- package/dist/hooks/load-core-context.mjs.map +2 -2
- package/dist/hooks/load-project-context.mjs.map +1 -1
- package/dist/hooks/post-compact-inject.mjs.map +1 -1
- package/dist/hooks/route-agents-to-worker.mjs.map +1 -1
- package/dist/hooks/route-edits-to-worker.mjs +1 -1
- package/dist/hooks/route-edits-to-worker.mjs.map +2 -2
- package/dist/hooks/security-validator.mjs +8367 -19
- package/dist/hooks/security-validator.mjs.map +4 -4
- package/dist/hooks/stop-hook.mjs.map +2 -2
- package/dist/hooks/whisper-rules.mjs.map +2 -2
- package/dist/hooks/worker-proxy.mjs.map +1 -1
- package/dist/hooks/worker-status-line.mjs.map +2 -2
- package/dist/hooks/worker-supervision.mjs.map +1 -1
- package/dist/index.d.mts +327 -100
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +7 -11
- package/dist/indexer-backend-Cc-_NK3q.mjs +1 -0
- package/dist/indexer-backend-DcDtin1O.mjs +5 -0
- package/dist/{ipc-client-C6NryMMb.mjs → ipc-client-Dasm515c.mjs} +2 -2
- package/dist/{ipc-client-C6NryMMb.mjs.map → ipc-client-Dasm515c.mjs.map} +1 -1
- package/dist/kg-entity-Cj8Q6YmU.mjs +29 -0
- package/dist/kg-entity-Cj8Q6YmU.mjs.map +1 -0
- package/dist/{latent-ideas-BfL4nCQ3.mjs → latent-ideas-BRy6HNwg.mjs} +4 -4
- package/dist/{latent-ideas-BfL4nCQ3.mjs.map → latent-ideas-BRy6HNwg.mjs.map} +1 -1
- package/dist/{link-boost-C5PaNdzm.mjs → link-boost-BptbAPuv.mjs} +1 -1
- package/dist/{link-boost-C5PaNdzm.mjs.map → link-boost-BptbAPuv.mjs.map} +1 -1
- package/dist/{main-resolver-Bt1f6jJc.mjs → main-resolver-Dx-pxic1.mjs} +56 -31
- package/dist/main-resolver-Dx-pxic1.mjs.map +1 -0
- package/dist/main-resolver-uDtK9p6e.mjs +7 -0
- package/dist/merge-BncjJTfb.mjs +3 -0
- package/dist/merge-xoyfZQ4W.mjs +6 -0
- package/dist/merge-xoyfZQ4W.mjs.map +1 -0
- package/dist/{migrate-CfERwXhY.mjs → migrate-BD7D8EEh.mjs} +21 -54
- package/dist/migrate-BD7D8EEh.mjs.map +1 -0
- package/dist/{neighborhood-CETR_P4y.mjs → neighborhood-D8uscnGy.mjs} +4 -25
- package/dist/neighborhood-D8uscnGy.mjs.map +1 -0
- package/dist/{note-context-DCcRWBoN.mjs → note-context-CgffaUMh.mjs} +3 -23
- package/dist/note-context-CgffaUMh.mjs.map +1 -0
- package/dist/{pai-home-ChAOupZc.mjs → pai-home-CeOIYltV.mjs} +2 -2
- package/dist/pai-home-CeOIYltV.mjs.map +1 -0
- package/dist/{pai-marker-B20KqhA8.mjs → pai-marker-D1MMswkz.mjs} +1 -1
- package/dist/{pai-marker-B20KqhA8.mjs.map → pai-marker-D1MMswkz.mjs.map} +1 -1
- package/dist/{planner-BLbCtBUa.mjs → planner-C2wWnZrZ.mjs} +7 -7
- package/dist/{planner-BLbCtBUa.mjs.map → planner-C2wWnZrZ.mjs.map} +1 -1
- package/dist/{postgres-CUSXWgTG.mjs → postgres-nvU5pShF.mjs} +863 -4
- package/dist/postgres-nvU5pShF.mjs.map +1 -0
- package/dist/{program-DYux0CW2.mjs → program-Cb-9J5Ie.mjs} +2260 -1399
- package/dist/program-Cb-9J5Ie.mjs.map +1 -0
- package/dist/query-feedback-COYCnvHQ.mjs +3 -0
- package/dist/{query-feedback-CTs_jx6i.mjs → query-feedback-xz5axTj3.mjs} +3 -3
- package/dist/query-feedback-xz5axTj3.mjs.map +1 -0
- package/dist/{db-Ddns80yf.mjs → registry-db-Bkpbp7Gf.mjs} +5 -5
- package/dist/registry-db-Bkpbp7Gf.mjs.map +1 -0
- package/dist/registry-db-DwXpf7yF.mjs +3 -0
- package/dist/registry-postgres-B07-hmn8.mjs +795 -0
- package/dist/registry-postgres-B07-hmn8.mjs.map +1 -0
- package/dist/registry-sqlite-CkGND_tm.mjs +593 -0
- package/dist/registry-sqlite-CkGND_tm.mjs.map +1 -0
- package/dist/{reranker-B5qUTamW.mjs → reranker-BS5gqGeF.mjs} +1 -1
- package/dist/{reranker-HHmhZk6v.mjs → reranker-CRVawoEh.mjs} +1 -1
- package/dist/{reranker-HHmhZk6v.mjs.map → reranker-CRVawoEh.mjs.map} +1 -1
- package/dist/router-BXOf_e9e.mjs +3 -0
- package/dist/{router-DBAZfE7X.mjs → router-BdxdsAvs.mjs} +2 -2
- package/dist/{router-DBAZfE7X.mjs.map → router-BdxdsAvs.mjs.map} +1 -1
- package/dist/{run-C7EDdVAB.mjs → run-DkTrZejF.mjs} +268 -53
- package/dist/run-DkTrZejF.mjs.map +1 -0
- package/dist/{runtime-paths-B0P1TvUr.mjs → runtime-paths-BRwDeBEg.mjs} +1 -1
- package/dist/{runtime-paths-B0P1TvUr.mjs.map → runtime-paths-BRwDeBEg.mjs.map} +1 -1
- package/dist/search-BQHL5wDr.mjs +3 -0
- package/dist/search-BaTbyWjK.mjs +107 -0
- package/dist/search-BaTbyWjK.mjs.map +1 -0
- package/dist/{server-CGiHdaUp.mjs → server-CGuZFOeR.mjs} +4 -4
- package/dist/{server-CGiHdaUp.mjs.map → server-CGuZFOeR.mjs.map} +1 -1
- package/dist/{session-keepalive-DC2JGggK.mjs → session-keepalive-C5_69Av6.mjs} +7 -7
- package/dist/{session-keepalive-DC2JGggK.mjs.map → session-keepalive-C5_69Av6.mjs.map} +1 -1
- package/dist/skills/Plan/SKILL.md +1 -1
- package/dist/{sources-KBGEA_E6.mjs → sources-BBe3AZ-W.mjs} +8 -27
- package/dist/sources-BBe3AZ-W.mjs.map +1 -0
- package/dist/sqlite-D9p5a4qe.mjs +935 -0
- package/dist/sqlite-D9p5a4qe.mjs.map +1 -0
- package/dist/state-CwlGAKgF.mjs +3 -0
- package/dist/{state-DwrsOoMi.mjs → state-n13uPK5B.mjs} +6 -5
- package/dist/state-n13uPK5B.mjs.map +1 -0
- package/dist/{stop-words-BaMEGVeY.mjs → stop-words-ClCwO8mZ.mjs} +1 -1
- package/dist/{stop-words-BaMEGVeY.mjs.map → stop-words-ClCwO8mZ.mjs.map} +1 -1
- package/dist/{themes-BVoAnLZj.mjs → themes-B2v7RNnA.mjs} +3 -3
- package/dist/{themes-BVoAnLZj.mjs.map → themes-B2v7RNnA.mjs.map} +1 -1
- package/dist/{tools-BEqiJt_j.mjs → tools-Diro2s8J.mjs} +157 -398
- package/dist/tools-Diro2s8J.mjs.map +1 -0
- package/dist/{tools-BwsOTmjh.mjs → tools-KgL1rkPD.mjs} +4 -4
- package/dist/{trace-Cy8quQTm.mjs → trace-BRflVyBi.mjs} +1 -1
- package/dist/{trace-Cy8quQTm.mjs.map → trace-BRflVyBi.mjs.map} +1 -1
- package/dist/{utils-BD8g8oSf.mjs → utils-BrX9FLeK.mjs} +1 -1
- package/dist/{utils-CJymHkYm.mjs → utils-C9HsYDpO.mjs} +1 -1
- package/dist/{utils-CJymHkYm.mjs.map → utils-C9HsYDpO.mjs.map} +1 -1
- package/dist/{vault-indexer-C5i-OAyr.mjs → vault-indexer-DHYBpRZ5.mjs} +2 -2
- package/dist/{vault-indexer-C5i-OAyr.mjs.map → vault-indexer-DHYBpRZ5.mjs.map} +1 -1
- package/dist/{wakeup-Yk5lQ0jb.mjs → wakeup-D0uvqLsE.mjs} +95 -4
- package/dist/wakeup-D0uvqLsE.mjs.map +1 -0
- package/dist/work-queue-worker-DEbWsrDQ.mjs +11 -0
- package/dist/{work-queue-worker-utPp4hUv.mjs → work-queue-worker-DufMOtrL.mjs} +9 -9
- package/dist/work-queue-worker-DufMOtrL.mjs.map +1 -0
- package/dist/{zettelkasten-DezbXghl.mjs → zettelkasten-BPxSOalU.mjs} +4 -4
- package/dist/{zettelkasten-DezbXghl.mjs.map → zettelkasten-BPxSOalU.mjs.map} +1 -1
- package/docker/init.sql +5 -1
- package/docs/commands/README.md +5 -0
- package/docs/commands/audit.md +1 -1
- package/docs/commands/backup.md +1 -1
- package/docs/commands/clear-names.md +1 -1
- package/docs/commands/config.md +4 -4
- package/docs/commands/daemon.md +1 -1
- package/docs/commands/db.md +15 -1
- package/docs/commands/end.md +1 -1
- package/docs/commands/help.md +1 -1
- package/docs/commands/hooks-db.md +47 -0
- package/docs/commands/identity.md +1 -1
- package/docs/commands/kg.md +1 -1
- package/docs/commands/launch.md +1 -1
- package/docs/commands/mcp.md +1 -1
- package/docs/commands/memory.md +1 -1
- package/docs/commands/notify.md +1 -1
- package/docs/commands/observation.md +1 -1
- package/docs/commands/obsidian.md +1 -1
- package/docs/commands/pause.md +1 -1
- package/docs/commands/project.md +1 -1
- package/docs/commands/projects.md +1 -1
- package/docs/commands/registry.md +1 -1
- package/docs/commands/restore.md +1 -1
- package/docs/commands/session.md +2 -2
- package/docs/commands/sessions.md +1 -1
- package/docs/commands/setup.md +1 -1
- package/docs/commands/shell-init.md +1 -1
- package/docs/commands/skill.md +1 -1
- package/docs/commands/task.md +1 -1
- package/docs/commands/topic.md +1 -1
- package/docs/commands/update.md +1 -1
- package/docs/commands/worker.md +1 -1
- package/docs/commands/zettel.md +1 -1
- package/docs/design/postgres-only.md +438 -0
- package/docs/design/registry-method-map.md +174 -0
- package/package.json +1 -1
- package/src/hooks/pre-compact.sh +2 -40
- package/src/hooks/session-hooks-db.test.ts +93 -0
- package/src/hooks/session-stop.sh +2 -26
- package/src/hooks/ts/lib/edit-gate.test.ts +9 -0
- package/src/hooks/ts/lib/edit-gate.ts +5 -2
- package/src/hooks/ts/lib/plutil-guard.test.ts +54 -0
- package/src/hooks/ts/lib/plutil-guard.ts +43 -0
- package/src/hooks/ts/lib/worker-git-guard.test.ts +134 -0
- package/src/hooks/ts/lib/worker-git-guard.ts +103 -0
- package/src/hooks/ts/pre-tool-use/security-validator.test.ts +68 -0
- package/src/hooks/ts/pre-tool-use/security-validator.ts +69 -21
- package/src/hooks/ts/session-start/load-core-context.ts +13 -0
- package/src/hooks/ts/session-start/session-start-worker-guard.test.ts +13 -0
- package/dist/auto-route-CcD0OWWB.mjs +0 -86
- package/dist/auto-route-CcD0OWWB.mjs.map +0 -1
- package/dist/clusters-Cw_P6lO-.mjs.map +0 -1
- package/dist/context-handover-cache-CXyH6QsC.mjs.map +0 -1
- package/dist/daemon-BkJNFWr9.mjs.map +0 -1
- package/dist/daemon-CiythMfR.mjs +0 -25
- package/dist/db-BOBfewFH.mjs +0 -3
- package/dist/db-DJ8rk0VM.mjs.map +0 -1
- package/dist/db-DbY2O8QO.mjs +0 -3
- package/dist/db-Ddns80yf.mjs.map +0 -1
- package/dist/detect-Bf2z-oKB.mjs +0 -86
- package/dist/detect-Bf2z-oKB.mjs.map +0 -1
- package/dist/detector-CkwkXuGh.mjs +0 -5
- package/dist/detector-DWXkeTlk.mjs.map +0 -1
- package/dist/factory-Ba8j9K7q.mjs +0 -3
- package/dist/factory-Bt7TWQje.mjs +0 -150
- package/dist/factory-Bt7TWQje.mjs.map +0 -1
- package/dist/fallback-CPfyTSTx.mjs.map +0 -1
- package/dist/indexer-backend-CdvCJCkD.mjs.map +0 -1
- package/dist/kg-entity-BSW7ra8i.mjs +0 -176
- package/dist/kg-entity-BSW7ra8i.mjs.map +0 -1
- package/dist/main-resolver-Bt1f6jJc.mjs.map +0 -1
- package/dist/main-resolver-DYHhw5Ig.mjs +0 -7
- package/dist/migrate-CfERwXhY.mjs.map +0 -1
- package/dist/neighborhood-CETR_P4y.mjs.map +0 -1
- package/dist/note-context-DCcRWBoN.mjs.map +0 -1
- package/dist/pai-home-ChAOupZc.mjs.map +0 -1
- package/dist/postgres-CUSXWgTG.mjs.map +0 -1
- package/dist/program-DYux0CW2.mjs.map +0 -1
- package/dist/query-feedback-Bm6XvCmg.mjs +0 -3
- package/dist/query-feedback-CTs_jx6i.mjs.map +0 -1
- package/dist/router-CremHKTI.mjs +0 -3
- package/dist/run-C7EDdVAB.mjs.map +0 -1
- package/dist/search-B69cQwDB.mjs +0 -303
- package/dist/search-B69cQwDB.mjs.map +0 -1
- package/dist/search-fb-5ovj4.mjs +0 -4
- package/dist/sources-KBGEA_E6.mjs.map +0 -1
- package/dist/sqlite-By6r2YhZ.mjs +0 -271
- package/dist/sqlite-By6r2YhZ.mjs.map +0 -1
- package/dist/state-Ca0ltLgI.mjs +0 -3
- package/dist/state-DwrsOoMi.mjs.map +0 -1
- package/dist/sync-Btcb6xA4.mjs +0 -310
- package/dist/sync-Btcb6xA4.mjs.map +0 -1
- package/dist/tools-BEqiJt_j.mjs.map +0 -1
- package/dist/wakeup-Yk5lQ0jb.mjs.map +0 -1
- package/dist/work-queue-worker-DsdJx-jn.mjs +0 -14
- package/dist/work-queue-worker-utPp4hUv.mjs.map +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,32 +1,329 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
//#region src/registry/schema.d.ts
|
|
4
|
-
declare const SCHEMA_VERSION = 4;
|
|
5
|
-
declare const CREATE_TABLES_SQL = "\nPRAGMA journal_mode = WAL;\nPRAGMA foreign_keys = ON;\n\nCREATE TABLE IF NOT EXISTS projects (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n slug TEXT NOT NULL UNIQUE,\n display_name TEXT NOT NULL,\n root_path TEXT NOT NULL UNIQUE,\n encoded_dir TEXT NOT NULL UNIQUE,\n type TEXT NOT NULL DEFAULT 'local'\n CHECK(type IN ('local','central','obsidian-linked','external')),\n status TEXT NOT NULL DEFAULT 'active'\n CHECK(status IN ('active','archived','migrating')),\n parent_id INTEGER,\n obsidian_link TEXT,\n claude_notes_dir TEXT,\n session_config TEXT,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n archived_at INTEGER,\n FOREIGN KEY (parent_id) REFERENCES projects(id)\n);\n\nCREATE TABLE IF NOT EXISTS sessions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n project_id INTEGER NOT NULL,\n number INTEGER NOT NULL,\n date TEXT NOT NULL,\n slug TEXT NOT NULL,\n title TEXT NOT NULL,\n filename TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'open'\n CHECK(status IN ('open','completed','compacted')),\n claude_session_id TEXT,\n token_count INTEGER,\n created_at INTEGER NOT NULL,\n closed_at INTEGER,\n UNIQUE (project_id, number),\n FOREIGN KEY (project_id) REFERENCES projects(id)\n);\n\nCREATE TABLE IF NOT EXISTS tags (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL UNIQUE\n);\n\nCREATE TABLE IF NOT EXISTS project_tags (\n project_id INTEGER NOT NULL,\n tag_id INTEGER NOT NULL,\n PRIMARY KEY (project_id, tag_id),\n FOREIGN KEY (project_id) REFERENCES projects(id),\n FOREIGN KEY (tag_id) REFERENCES tags(id)\n);\n\nCREATE TABLE IF NOT EXISTS session_tags (\n session_id INTEGER NOT NULL,\n tag_id INTEGER NOT NULL,\n PRIMARY KEY (session_id, tag_id),\n FOREIGN KEY (session_id) REFERENCES sessions(id),\n FOREIGN KEY (tag_id) REFERENCES tags(id)\n);\n\nCREATE TABLE IF NOT EXISTS aliases (\n alias TEXT PRIMARY KEY,\n project_id INTEGER NOT NULL,\n FOREIGN KEY (project_id) REFERENCES projects(id)\n);\n\nCREATE TABLE IF NOT EXISTS compaction_log (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n project_id INTEGER NOT NULL,\n session_id INTEGER,\n trigger TEXT NOT NULL\n CHECK(trigger IN ('precompact','manual','end-session')),\n files_written TEXT NOT NULL,\n token_count INTEGER,\n created_at INTEGER NOT NULL,\n FOREIGN KEY (project_id) REFERENCES projects(id),\n FOREIGN KEY (session_id) REFERENCES sessions(id)\n);\n\nCREATE TABLE IF NOT EXISTS links (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id INTEGER NOT NULL,\n target_project_id INTEGER NOT NULL,\n link_type TEXT NOT NULL DEFAULT 'related'\n CHECK(link_type IN ('related','follow-up','reference')),\n created_at INTEGER NOT NULL,\n UNIQUE (session_id, target_project_id),\n FOREIGN KEY (session_id) REFERENCES sessions(id),\n FOREIGN KEY (target_project_id) REFERENCES projects(id)\n);\n\nCREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER PRIMARY KEY,\n applied_at INTEGER NOT NULL\n);\n\n-- Indexes\nCREATE INDEX IF NOT EXISTS idx_projects_slug ON projects(slug);\nCREATE INDEX IF NOT EXISTS idx_projects_status ON projects(status);\nCREATE INDEX IF NOT EXISTS idx_projects_type ON projects(type);\nCREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_id);\nCREATE INDEX IF NOT EXISTS idx_sessions_date ON sessions(date);\nCREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);\nCREATE INDEX IF NOT EXISTS idx_sessions_claude ON sessions(claude_session_id);\nCREATE INDEX IF NOT EXISTS idx_pc_project ON project_tags(project_id);\n";
|
|
1
|
+
//#region src/registry/merge.d.ts
|
|
6
2
|
/**
|
|
7
|
-
*
|
|
3
|
+
* merge.ts — pure types and error class shared by the merge implementations.
|
|
8
4
|
*
|
|
9
|
-
* The
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
//#endregion
|
|
16
|
-
//#region src/registry/db.d.ts
|
|
17
|
-
/**
|
|
18
|
-
* Open (or create) the PAI registry database.
|
|
19
|
-
*
|
|
20
|
-
* @param path Absolute path to registry.db. Defaults to PAI_HOME/registry.db
|
|
21
|
-
* (falling back to the pre-2026-09-19 ~/.pai/registry.db).
|
|
22
|
-
* @returns An open better-sqlite3 Database instance.
|
|
5
|
+
* The actual SQLite implementation (planMerge/applyMerge, taking a raw
|
|
6
|
+
* better-sqlite3 Database) lives in src/storage/sqlite/registry-merge.ts —
|
|
7
|
+
* moved there so nothing outside src/storage/ imports better-sqlite3. The
|
|
8
|
+
* Postgres implementation lives in src/storage/registry-postgres.ts. Both are
|
|
9
|
+
* reached through RegistryBackend.planProjectMerge/applyProjectMerge
|
|
10
|
+
* (src/storage/registry-interface.ts), never directly.
|
|
23
11
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* - Enables WAL journal mode.
|
|
27
|
-
* - Runs initializeSchema() if schema_version is empty.
|
|
12
|
+
* See src/storage/sqlite/registry-merge.ts for the "why one function" design
|
|
13
|
+
* rationale (five tables reference a project, foreign_keys is off).
|
|
28
14
|
*/
|
|
29
|
-
|
|
15
|
+
interface MergePlan {
|
|
16
|
+
fromId: number;
|
|
17
|
+
fromSlug: string;
|
|
18
|
+
intoId: number;
|
|
19
|
+
intoSlug: string;
|
|
20
|
+
/** Sessions to move, with the numbers they will be given. */
|
|
21
|
+
sessions: {
|
|
22
|
+
id: number;
|
|
23
|
+
from: number;
|
|
24
|
+
to: number;
|
|
25
|
+
}[];
|
|
26
|
+
tags: number;
|
|
27
|
+
aliases: number;
|
|
28
|
+
compactions: number;
|
|
29
|
+
links: number;
|
|
30
|
+
/** The losing slug is kept as an alias, so `pai <old-name>` still resolves. */
|
|
31
|
+
aliasToAdd?: string;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/storage/registry-interface.d.ts
|
|
35
|
+
type ProjectType = "local" | "central" | "obsidian-linked" | "external";
|
|
36
|
+
type ProjectStatus = "active" | "archived" | "migrating";
|
|
37
|
+
type SessionStatus = "open" | "completed" | "compacted";
|
|
38
|
+
type LinkType = "related" | "follow-up" | "reference";
|
|
39
|
+
type CompactionTrigger = "precompact" | "manual" | "end-session";
|
|
40
|
+
interface Project {
|
|
41
|
+
id: number;
|
|
42
|
+
slug: string;
|
|
43
|
+
display_name: string;
|
|
44
|
+
root_path: string;
|
|
45
|
+
encoded_dir: string;
|
|
46
|
+
type: ProjectType;
|
|
47
|
+
status: ProjectStatus;
|
|
48
|
+
parent_id: number | null;
|
|
49
|
+
obsidian_link: string | null;
|
|
50
|
+
claude_notes_dir: string | null;
|
|
51
|
+
session_config: string | null;
|
|
52
|
+
created_at: number;
|
|
53
|
+
updated_at: number;
|
|
54
|
+
archived_at: number | null;
|
|
55
|
+
}
|
|
56
|
+
interface ProjectWithSessionStats extends Project {
|
|
57
|
+
session_count: number;
|
|
58
|
+
last_active: number | null;
|
|
59
|
+
}
|
|
60
|
+
interface Session {
|
|
61
|
+
id: number;
|
|
62
|
+
project_id: number;
|
|
63
|
+
number: number;
|
|
64
|
+
date: string;
|
|
65
|
+
slug: string;
|
|
66
|
+
title: string;
|
|
67
|
+
filename: string;
|
|
68
|
+
status: SessionStatus;
|
|
69
|
+
claude_session_id: string | null;
|
|
70
|
+
token_count: number | null;
|
|
71
|
+
created_at: number;
|
|
72
|
+
closed_at: number | null;
|
|
73
|
+
}
|
|
74
|
+
interface SessionWithProject extends Session {
|
|
75
|
+
project_slug: string;
|
|
76
|
+
project_name: string;
|
|
77
|
+
}
|
|
78
|
+
interface NewProject {
|
|
79
|
+
slug: string;
|
|
80
|
+
displayName: string;
|
|
81
|
+
rootPath: string;
|
|
82
|
+
encodedDir: string;
|
|
83
|
+
type?: ProjectType;
|
|
84
|
+
status?: ProjectStatus;
|
|
85
|
+
createdAt: number;
|
|
86
|
+
updatedAt: number;
|
|
87
|
+
}
|
|
88
|
+
/** Insert a project row, retrying with a numeric slug suffix on collision. */
|
|
89
|
+
interface NewProjectWithSlugRetry {
|
|
90
|
+
baseSlug: string;
|
|
91
|
+
displayName: string;
|
|
92
|
+
rootPath: string;
|
|
93
|
+
encodedDir: string;
|
|
94
|
+
createdAt: number;
|
|
95
|
+
updatedAt: number;
|
|
96
|
+
}
|
|
97
|
+
interface NewSession {
|
|
98
|
+
projectId: number;
|
|
99
|
+
number: number;
|
|
100
|
+
date: string;
|
|
101
|
+
slug: string;
|
|
102
|
+
title: string;
|
|
103
|
+
filename: string;
|
|
104
|
+
status?: SessionStatus;
|
|
105
|
+
createdAt: number;
|
|
106
|
+
}
|
|
107
|
+
interface NewCompactionLogEntry {
|
|
108
|
+
projectId: number;
|
|
109
|
+
sessionId: number | null;
|
|
110
|
+
trigger: CompactionTrigger;
|
|
111
|
+
filesWritten: string;
|
|
112
|
+
tokenCount: number | null;
|
|
113
|
+
createdAt: number;
|
|
114
|
+
}
|
|
115
|
+
interface ListProjectsOptions {
|
|
116
|
+
status?: ProjectStatus;
|
|
117
|
+
/** WHERE status != 'archived' */
|
|
118
|
+
excludeArchived?: boolean;
|
|
119
|
+
tagName?: string;
|
|
120
|
+
orderBy?: "status_updated" | "updated_desc" | "slug" | "id";
|
|
121
|
+
limit?: number;
|
|
122
|
+
}
|
|
123
|
+
interface ListProjectsByPathLengthOptions {
|
|
124
|
+
excludeArchived?: boolean;
|
|
125
|
+
}
|
|
126
|
+
interface ListProjectsWithStatsOptions {
|
|
127
|
+
status?: ProjectStatus;
|
|
128
|
+
tagId?: number;
|
|
129
|
+
orderBy?: "status_updated" | "updated_desc";
|
|
130
|
+
}
|
|
131
|
+
interface ListNamedProjectsOptions {
|
|
132
|
+
/** LEFT JOIN aliases instead of JOIN, so unnamed projects are included too. */
|
|
133
|
+
includeUnnamed?: boolean;
|
|
134
|
+
}
|
|
135
|
+
interface ListSessionsOptions {
|
|
136
|
+
projectId?: number;
|
|
137
|
+
status?: SessionStatus | string;
|
|
138
|
+
limit?: number;
|
|
139
|
+
}
|
|
140
|
+
interface ListSessionsForProjectOptions {
|
|
141
|
+
orderBy?: "number_asc" | "created_desc";
|
|
142
|
+
limit?: number;
|
|
143
|
+
}
|
|
144
|
+
interface RegistryBackend {
|
|
145
|
+
readonly backendType: "sqlite" | "postgres";
|
|
146
|
+
close(): Promise<void>;
|
|
147
|
+
/**
|
|
148
|
+
* Erase every row from every registry table (projects, sessions, tags,
|
|
149
|
+
* project_tags, session_tags, aliases, links, compaction_log). Used by
|
|
150
|
+
* `pai registry rebuild`. Does not touch schema/DDL — only data.
|
|
151
|
+
*/
|
|
152
|
+
resetRegistry(): Promise<void>;
|
|
153
|
+
getProjectById(id: number): Promise<Project | null>;
|
|
154
|
+
/** Exact slug match; caseInsensitive uses lower(slug) = lower(?). excludeId excludes a row by id (conflict checks). */
|
|
155
|
+
getProjectBySlug(slug: string, opts?: {
|
|
156
|
+
caseInsensitive?: boolean;
|
|
157
|
+
excludeId?: number;
|
|
158
|
+
}): Promise<Project | null>;
|
|
159
|
+
getProjectByAlias(alias: string, opts?: {
|
|
160
|
+
caseInsensitive?: boolean;
|
|
161
|
+
}): Promise<Project | null>;
|
|
162
|
+
getProjectByRootPath(rootPath: string, opts?: {
|
|
163
|
+
excludeId?: number;
|
|
164
|
+
}): Promise<Project | null>;
|
|
165
|
+
getProjectByEncodedDir(encodedDir: string, opts?: {
|
|
166
|
+
excludeId?: number;
|
|
167
|
+
}): Promise<Project | null>;
|
|
168
|
+
/** status='active' AND cwd LIKE root_path || '%' ORDER BY length(root_path) DESC LIMIT 1. */
|
|
169
|
+
findProjectByCwdPrefix(cwd: string): Promise<Project | null>;
|
|
170
|
+
listProjects(opts?: ListProjectsOptions): Promise<Project[]>;
|
|
171
|
+
/** All projects ordered by LENGTH(root_path) DESC, for caller-side prefix matching. */
|
|
172
|
+
listProjectsByPathLengthDesc(opts?: ListProjectsByPathLengthOptions): Promise<Project[]>;
|
|
173
|
+
listProjectsWithSessionStats(opts?: ListProjectsWithStatsOptions): Promise<ProjectWithSessionStats[]>;
|
|
174
|
+
/** Projects joined to their curated alias ("name"), status='active'. */
|
|
175
|
+
listNamedProjects(opts?: ListNamedProjectsOptions): Promise<Array<ProjectWithSessionStats & {
|
|
176
|
+
name: string | null;
|
|
177
|
+
}>>;
|
|
178
|
+
searchProjects(query: string, limit?: number): Promise<Project[]>;
|
|
179
|
+
countProjects(opts?: {
|
|
180
|
+
status?: ProjectStatus;
|
|
181
|
+
}): Promise<number>;
|
|
182
|
+
getMostRecentProjectUpdatedAt(): Promise<number | null>;
|
|
183
|
+
countChildProjects(parentId: number): Promise<number>;
|
|
184
|
+
/** Sibling projects (slug variants) with at least one session, for split-identity detection. */
|
|
185
|
+
findSiblingProjectsBySlugPattern(excludeProjectId: number, slug: string, limit?: number): Promise<Array<{
|
|
186
|
+
slug: string;
|
|
187
|
+
root_path: string;
|
|
188
|
+
session_count: number;
|
|
189
|
+
}>>;
|
|
190
|
+
createProject(input: NewProject): Promise<Project>;
|
|
191
|
+
createProjectWithSlugRetry(input: NewProjectWithSlugRetry): Promise<{
|
|
192
|
+
id: number;
|
|
193
|
+
slug: string;
|
|
194
|
+
created: boolean;
|
|
195
|
+
}>;
|
|
196
|
+
updateProjectPath(id: number, patch: {
|
|
197
|
+
rootPath?: string;
|
|
198
|
+
encodedDir?: string;
|
|
199
|
+
}, updatedAt?: number): Promise<void>;
|
|
200
|
+
updateProjectStatus(id: number, status: ProjectStatus, opts?: {
|
|
201
|
+
archivedAt?: number | null;
|
|
202
|
+
updatedAt?: number;
|
|
203
|
+
requireCurrentStatus?: ProjectStatus;
|
|
204
|
+
}): Promise<void>;
|
|
205
|
+
updateProjectDisplayName(id: number, displayName: string, updatedAt?: number): Promise<void>;
|
|
206
|
+
updateProjectType(id: number, type: ProjectType, updatedAt?: number): Promise<void>;
|
|
207
|
+
updateProjectSessionConfig(id: number, config: string | null, updatedAt?: number): Promise<void>;
|
|
208
|
+
updateProjectClaudeNotesDir(id: number, dir: string | null, updatedAt?: number): Promise<void>;
|
|
209
|
+
updateProjectObsidianLink(id: number, link: string | null, updatedAt?: number): Promise<void>;
|
|
210
|
+
updateProjectSlug(id: number, slug: string, updatedAt: number): Promise<void>;
|
|
211
|
+
/** UPDATE projects SET parent_id = toParentId WHERE parent_id = fromParentId. Returns rows changed. */
|
|
212
|
+
reassignProjectParent(fromParentId: number, toParentId: number): Promise<number>;
|
|
213
|
+
deleteProject(id: number): Promise<void>;
|
|
214
|
+
/** Atomic cascade: links, compaction_log, project_tags, aliases, sessions, then the project row. */
|
|
215
|
+
deleteProjectCascade(id: number): Promise<void>;
|
|
216
|
+
listTagsForProject(projectId: number): Promise<string[]>;
|
|
217
|
+
listAllTags(): Promise<Array<{
|
|
218
|
+
id: number;
|
|
219
|
+
name: string;
|
|
220
|
+
}>>;
|
|
221
|
+
/** INSERT OR IGNORE then SELECT id — returns the tag's id either way. */
|
|
222
|
+
upsertTag(name: string): Promise<number>;
|
|
223
|
+
addProjectTag(projectId: number, tagId: number): Promise<void>;
|
|
224
|
+
projectHasTag(projectId: number, tagId: number): Promise<boolean>;
|
|
225
|
+
deleteProjectTag(projectId: number, tagId: number): Promise<void>;
|
|
226
|
+
reassignProjectTag(fromProjectId: number, toProjectId: number, tagId: number): Promise<void>;
|
|
227
|
+
listProjectTagIds(projectId: number): Promise<number[]>;
|
|
228
|
+
countProjectTagsForProject(projectId: number): Promise<number>;
|
|
229
|
+
/** INSERT OR IGNORE INTO project_tags SELECT toProjectId, tag_id FROM project_tags WHERE project_id = fromProjectId. */
|
|
230
|
+
copyProjectTags(fromProjectId: number, toProjectId: number): Promise<void>;
|
|
231
|
+
deleteProjectTagsForProject(projectId: number): Promise<void>;
|
|
232
|
+
/** Look up the project_id an alias resolves to, or null. */
|
|
233
|
+
resolveAlias(alias: string): Promise<number | null>;
|
|
234
|
+
listAliasesForProject(projectId: number): Promise<string[]>;
|
|
235
|
+
addAlias(alias: string, projectId: number): Promise<void>;
|
|
236
|
+
removeAlias(alias: string): Promise<void>;
|
|
237
|
+
countAliasesForProject(projectId: number): Promise<number>;
|
|
238
|
+
/** Bulk UPDATE aliases SET project_id = toProjectId WHERE project_id = fromProjectId. */
|
|
239
|
+
moveProjectAliases(fromProjectId: number, toProjectId: number): Promise<void>;
|
|
240
|
+
/** Repoint a single alias to another project (used when folding duplicates). */
|
|
241
|
+
reassignAlias(alias: string, toProjectId: number): Promise<void>;
|
|
242
|
+
/** aliases JOIN projects, for task-owner resolution. Excludes archived projects. */
|
|
243
|
+
listAliasMap(): Promise<Array<{
|
|
244
|
+
alias: string;
|
|
245
|
+
slug: string;
|
|
246
|
+
root_path: string;
|
|
247
|
+
}>>;
|
|
248
|
+
getSessionById(id: number): Promise<Session | null>;
|
|
249
|
+
getSessionByNumber(projectId: number, number: number): Promise<Session | null>;
|
|
250
|
+
getLatestSessionForProject(projectId: number): Promise<Session | null>;
|
|
251
|
+
getMaxSessionNumber(projectId: number): Promise<number>;
|
|
252
|
+
listSessionsForProject(projectId: number, opts?: ListSessionsForProjectOptions): Promise<Session[]>;
|
|
253
|
+
/** Sessions joined to their project's slug/display_name, with optional project/status filters. */
|
|
254
|
+
listSessions(opts?: ListSessionsOptions): Promise<SessionWithProject[]>;
|
|
255
|
+
findSessionByFilename(projectId: number, filename: string): Promise<{
|
|
256
|
+
id: number;
|
|
257
|
+
} | null>;
|
|
258
|
+
sessionNumberTaken(projectId: number, number: number): Promise<boolean>;
|
|
259
|
+
createSession(input: NewSession): Promise<Session>;
|
|
260
|
+
/** Insert only if (project_id, number) is free. Returns true if newly inserted. */
|
|
261
|
+
upsertSessionIfAbsent(input: NewSession): Promise<boolean>;
|
|
262
|
+
updateSessionMeta(id: number, patch: {
|
|
263
|
+
slug?: string;
|
|
264
|
+
title?: string;
|
|
265
|
+
filename?: string;
|
|
266
|
+
}): Promise<void>;
|
|
267
|
+
updateSessionNumber(id: number, number: number, opts?: {
|
|
268
|
+
filename?: string;
|
|
269
|
+
}): Promise<void>;
|
|
270
|
+
updateSessionFilename(id: number, filename: string): Promise<void>;
|
|
271
|
+
/** Sets status, and closed_at when opts.closedAt is passed (session-stop/pre-compact hooks). */
|
|
272
|
+
updateSessionStatus(id: number, status: SessionStatus, opts?: {
|
|
273
|
+
closedAt?: number;
|
|
274
|
+
}): Promise<void>;
|
|
275
|
+
moveSessionToProject(id: number, projectId: number, opts?: {
|
|
276
|
+
number?: number;
|
|
277
|
+
}): Promise<void>;
|
|
278
|
+
deleteSession(id: number): Promise<void>;
|
|
279
|
+
/** Backfill claude_session_id/token_count/closed_at/status from dropId into keepId (COALESCE semantics), then leaves dropId untouched — caller deletes it separately via deleteSession. */
|
|
280
|
+
backfillFoldedSession(keepId: number, dropId: number): Promise<void>;
|
|
281
|
+
countSessionsForProject(projectId: number): Promise<number>;
|
|
282
|
+
/** Total session count across all projects. */
|
|
283
|
+
countSessions(): Promise<number>;
|
|
284
|
+
getMostRecentSessionDate(projectId: number): Promise<string | null>;
|
|
285
|
+
getMostRecentSessionCreatedAt(): Promise<number | null>;
|
|
286
|
+
listSessionTagIds(sessionId: number): Promise<number[]>;
|
|
287
|
+
sessionHasTag(sessionId: number, tagId: number): Promise<boolean>;
|
|
288
|
+
addSessionTag(sessionId: number, tagId: number): Promise<void>;
|
|
289
|
+
deleteSessionTag(sessionId: number, tagId: number): Promise<void>;
|
|
290
|
+
reassignSessionTag(fromSessionId: number, toSessionId: number, tagId: number): Promise<void>;
|
|
291
|
+
listTagsForSession(sessionId: number): Promise<string[]>;
|
|
292
|
+
addLink(input: {
|
|
293
|
+
sessionId: number;
|
|
294
|
+
targetProjectId: number;
|
|
295
|
+
linkType: LinkType;
|
|
296
|
+
createdAt: number;
|
|
297
|
+
}): Promise<void>;
|
|
298
|
+
listLinksForSession(sessionId: number): Promise<Array<{
|
|
299
|
+
id: number;
|
|
300
|
+
target_project_id: number;
|
|
301
|
+
}>>;
|
|
302
|
+
listLinksForProject(projectId: number): Promise<Array<{
|
|
303
|
+
id: number;
|
|
304
|
+
session_id: number;
|
|
305
|
+
}>>;
|
|
306
|
+
linkExists(sessionId: number, targetProjectId: number): Promise<boolean>;
|
|
307
|
+
deleteLink(id: number): Promise<void>;
|
|
308
|
+
deleteLinksTargetingProject(projectId: number): Promise<void>;
|
|
309
|
+
/** DELETE FROM links WHERE session_id IN (SELECT id FROM sessions WHERE project_id = ?). */
|
|
310
|
+
deleteLinksFromProjectSessions(projectId: number): Promise<void>;
|
|
311
|
+
retargetLink(id: number, targetProjectId: number): Promise<void>;
|
|
312
|
+
moveLinkToSession(id: number, sessionId: number): Promise<void>;
|
|
313
|
+
/** Bulk UPDATE OR IGNORE links SET target_project_id = toProjectId WHERE target_project_id = fromProjectId. */
|
|
314
|
+
reassignLinksTarget(fromProjectId: number, toProjectId: number): Promise<void>;
|
|
315
|
+
countLinksForProject(projectId: number): Promise<number>;
|
|
316
|
+
/** Self-links created by a merge: DELETE FROM links WHERE target_project_id = ? AND session_id IN (SELECT id FROM sessions WHERE project_id = ?), same id both sides. */
|
|
317
|
+
deleteSelfLinksForProject(projectId: number): Promise<void>;
|
|
318
|
+
appendCompactionLog(entry: NewCompactionLogEntry): Promise<void>;
|
|
319
|
+
countCompactionLogsForProject(projectId: number): Promise<number>;
|
|
320
|
+
/** Returns rows changed. */
|
|
321
|
+
moveCompactionLogsByProject(fromProjectId: number, toProjectId: number): Promise<number>;
|
|
322
|
+
moveCompactionLogsBySession(fromSessionId: number, toSessionId: number): Promise<void>;
|
|
323
|
+
deleteCompactionLogsForProject(projectId: number): Promise<void>;
|
|
324
|
+
planProjectMerge(fromSlug: string, intoSlug: string): Promise<MergePlan>;
|
|
325
|
+
applyProjectMerge(plan: MergePlan): Promise<void>;
|
|
326
|
+
}
|
|
30
327
|
//#endregion
|
|
31
328
|
//#region src/registry/migrate.d.ts
|
|
32
329
|
/**
|
|
@@ -82,16 +379,16 @@ interface MigrationResult {
|
|
|
82
379
|
errors: string[];
|
|
83
380
|
}
|
|
84
381
|
/**
|
|
85
|
-
* Migrate the existing JSON session-registry into the
|
|
382
|
+
* Migrate the existing JSON session-registry into the registry backend.
|
|
86
383
|
*
|
|
87
|
-
* @param
|
|
384
|
+
* @param backend Target RegistryBackend (SQLite or Postgres).
|
|
88
385
|
* @param registryPath Path to session-registry.json.
|
|
89
386
|
* Defaults to ~/.claude/session-registry.json.
|
|
90
387
|
*
|
|
91
388
|
* The migration is idempotent: projects and sessions that already exist
|
|
92
389
|
* (matched by slug / project_id+number) are silently skipped.
|
|
93
390
|
*/
|
|
94
|
-
declare function migrateFromJson(
|
|
391
|
+
declare function migrateFromJson(backend: RegistryBackend, registryPath?: string): Promise<MigrationResult>;
|
|
95
392
|
//#endregion
|
|
96
393
|
//#region src/registry/pai-marker.d.ts
|
|
97
394
|
interface PaiMarker {
|
|
@@ -135,34 +432,6 @@ declare function readPaiMarker(projectRoot: string): {
|
|
|
135
432
|
*/
|
|
136
433
|
declare function discoverPaiMarkers(searchDirs: string[]): PaiMarker[];
|
|
137
434
|
//#endregion
|
|
138
|
-
//#region src/memory/schema.d.ts
|
|
139
|
-
declare const FEDERATION_SCHEMA_SQL = "\nPRAGMA journal_mode = WAL;\nPRAGMA foreign_keys = ON;\n\nCREATE TABLE IF NOT EXISTS memory_files (\n project_id INTEGER NOT NULL,\n path TEXT NOT NULL,\n source TEXT NOT NULL DEFAULT 'memory',\n tier TEXT NOT NULL DEFAULT 'topic',\n hash TEXT NOT NULL,\n mtime INTEGER NOT NULL,\n size INTEGER NOT NULL,\n PRIMARY KEY (project_id, path)\n);\n\nCREATE TABLE IF NOT EXISTS memory_chunks (\n id TEXT PRIMARY KEY,\n project_id INTEGER NOT NULL,\n source TEXT NOT NULL DEFAULT 'memory',\n tier TEXT NOT NULL DEFAULT 'topic',\n path TEXT NOT NULL,\n start_line INTEGER NOT NULL,\n end_line INTEGER NOT NULL,\n hash TEXT NOT NULL,\n text TEXT NOT NULL,\n updated_at INTEGER NOT NULL,\n last_accessed_at INTEGER,\n relevance_score REAL DEFAULT 0.5,\n embedding BLOB\n);\n\nCREATE VIRTUAL TABLE IF NOT EXISTS memory_fts USING fts5(\n text,\n id UNINDEXED,\n project_id UNINDEXED,\n path UNINDEXED,\n source UNINDEXED,\n tier UNINDEXED,\n start_line UNINDEXED,\n end_line UNINDEXED\n);\n\nCREATE INDEX IF NOT EXISTS idx_mc_project ON memory_chunks(project_id);\nCREATE INDEX IF NOT EXISTS idx_mc_source ON memory_chunks(project_id, source);\nCREATE INDEX IF NOT EXISTS idx_mc_tier ON memory_chunks(tier);\nCREATE INDEX IF NOT EXISTS idx_mf_project ON memory_files(project_id);\n\nCREATE TABLE IF NOT EXISTS kg_entities (\n entity_id TEXT PRIMARY KEY,\n tenant_id TEXT NOT NULL DEFAULT 'default',\n name TEXT NOT NULL,\n type TEXT NOT NULL DEFAULT 'unknown',\n description TEXT,\n first_seen INTEGER,\n last_seen INTEGER,\n mention_count INTEGER NOT NULL DEFAULT 1,\n feedback_weight REAL NOT NULL DEFAULT 0.5,\n UNIQUE(tenant_id, entity_id)\n);\n\nCREATE INDEX IF NOT EXISTS idx_kge_tenant ON kg_entities(tenant_id);\nCREATE INDEX IF NOT EXISTS idx_kge_name ON kg_entities(tenant_id, name);\nCREATE INDEX IF NOT EXISTS idx_kge_type ON kg_entities(tenant_id, type);\n";
|
|
140
|
-
/**
|
|
141
|
-
* Apply the full federation schema to an open database.
|
|
142
|
-
*
|
|
143
|
-
* Idempotent — all statements use IF NOT EXISTS so calling this on an
|
|
144
|
-
* already-initialised database is safe.
|
|
145
|
-
*
|
|
146
|
-
* Also runs any necessary migrations for existing databases (e.g. adding the
|
|
147
|
-
* embedding column to an older schema that was created without it).
|
|
148
|
-
*/
|
|
149
|
-
declare function initializeFederationSchema(db: Database): void;
|
|
150
|
-
//#endregion
|
|
151
|
-
//#region src/memory/db.d.ts
|
|
152
|
-
/**
|
|
153
|
-
* Open (or create) the PAI federation database.
|
|
154
|
-
*
|
|
155
|
-
* @param path Absolute path to federation.db. Defaults to PAI_HOME/federation.db
|
|
156
|
-
* (falling back to the pre-2026-09-19 ~/.pai/federation.db).
|
|
157
|
-
* @returns An open better-sqlite3 Database instance.
|
|
158
|
-
*
|
|
159
|
-
* Side effects on first call:
|
|
160
|
-
* - Creates the parent directory if it does not exist.
|
|
161
|
-
* - Enables WAL journal mode.
|
|
162
|
-
* - Runs initializeFederationSchema() to ensure tables exist.
|
|
163
|
-
*/
|
|
164
|
-
declare function openFederation(path?: string): Database$1;
|
|
165
|
-
//#endregion
|
|
166
435
|
//#region src/memory/chunker.d.ts
|
|
167
436
|
/**
|
|
168
437
|
* Markdown text chunker for the PAI memory engine.
|
|
@@ -218,35 +487,6 @@ interface IndexResult {
|
|
|
218
487
|
filesSkipped: number;
|
|
219
488
|
}
|
|
220
489
|
//#endregion
|
|
221
|
-
//#region src/memory/indexer/sync.d.ts
|
|
222
|
-
/**
|
|
223
|
-
* Index a single file into the federation database.
|
|
224
|
-
*
|
|
225
|
-
* @returns true if the file was re-indexed (changed or new), false if skipped.
|
|
226
|
-
*/
|
|
227
|
-
declare function indexFile(db: Database, projectId: number, rootPath: string, relativePath: string, source: string, tier: string): boolean;
|
|
228
|
-
/**
|
|
229
|
-
* Index all memory, Notes, and content files for a single registered project.
|
|
230
|
-
*
|
|
231
|
-
* Scans:
|
|
232
|
-
* - {rootPath}/MEMORY.md → source='memory', tier='evergreen'
|
|
233
|
-
* - {rootPath}/memory/ → source='memory', tier from detectTier()
|
|
234
|
-
* - {rootPath}/Notes/ → source='notes', tier='session'
|
|
235
|
-
* - {rootPath}/**\/*.md → source='content', tier='topic' (all other .md files, recursive)
|
|
236
|
-
* - {claudeNotesDir}/ → source='notes', tier='session' (if set and different)
|
|
237
|
-
*/
|
|
238
|
-
declare function indexProject(db: Database, projectId: number, rootPath: string, claudeNotesDir?: string | null): Promise<IndexResult>;
|
|
239
|
-
/**
|
|
240
|
-
* Index all active projects registered in the registry DB.
|
|
241
|
-
*
|
|
242
|
-
* Async: yields to the event loop between each project so that the daemon's
|
|
243
|
-
* Unix socket server can process IPC requests (e.g. status) while indexing.
|
|
244
|
-
*/
|
|
245
|
-
declare function indexAll(db: Database, registryDb: Database): Promise<{
|
|
246
|
-
projects: number;
|
|
247
|
-
result: IndexResult;
|
|
248
|
-
}>;
|
|
249
|
-
//#endregion
|
|
250
490
|
//#region src/memory/search.d.ts
|
|
251
491
|
interface SearchResult {
|
|
252
492
|
projectId: number;
|
|
@@ -275,24 +515,11 @@ interface SearchOptions {
|
|
|
275
515
|
minScore?: number;
|
|
276
516
|
}
|
|
277
517
|
declare function buildFtsQuery(query: string): string;
|
|
278
|
-
/**
|
|
279
|
-
* Search across all indexed memory using FTS5 BM25 ranking.
|
|
280
|
-
*
|
|
281
|
-
* Results are ordered by BM25 score (most relevant first).
|
|
282
|
-
* FTS5 bm25() returns negative values; closer to 0 = more relevant.
|
|
283
|
-
* We negate the score so callers get positive values where higher = better.
|
|
284
|
-
*
|
|
285
|
-
* Multilingual note: SQLite FTS5 uses the `unicode61` tokenizer by default,
|
|
286
|
-
* which handles Unicode correctly (German umlauts, French accents, etc.) without
|
|
287
|
-
* language-specific stemming. No changes needed here — it is already
|
|
288
|
-
* multilingual-safe.
|
|
289
|
-
*/
|
|
290
|
-
declare function searchMemory(db: Database, query: string, opts?: SearchOptions): SearchResult[];
|
|
291
518
|
/**
|
|
292
519
|
* Populate the projectSlug field on search results by looking up project IDs
|
|
293
520
|
* in the registry database.
|
|
294
521
|
*/
|
|
295
|
-
declare function populateSlugs(results: SearchResult[],
|
|
522
|
+
declare function populateSlugs(results: SearchResult[], registry: RegistryBackend): Promise<SearchResult[]>;
|
|
296
523
|
//#endregion
|
|
297
524
|
//#region src/memory/reranker.d.ts
|
|
298
525
|
/**
|
|
@@ -321,5 +548,5 @@ interface RerankOptions {
|
|
|
321
548
|
*/
|
|
322
549
|
declare function rerankResults(query: string, results: SearchResult[], opts?: RerankOptions): Promise<SearchResult[]>;
|
|
323
550
|
//#endregion
|
|
324
|
-
export {
|
|
551
|
+
export { Chunk, ChunkOptions, IndexResult, MigrationResult, PaiMarker, RerankOptions, SearchOptions, SearchResult, buildFtsQuery, chunkMarkdown, configureRerankerModel, decodeEncodedDir, detectTier, discoverPaiMarkers, ensurePaiMarker, estimateTokens, migrateFromJson, parseSessionFilename, populateSlugs, readPaiMarker, rerankResults, slugify };
|
|
325
552
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/registry/
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/registry/merge.ts","../src/storage/registry-interface.ts","../src/registry/migrate.ts","../src/registry/pai-marker.ts","../src/memory/chunker.ts","../src/memory/indexer/helpers.ts","../src/memory/indexer/types.ts","../src/memory/search.ts","../src/memory/reranker.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import "./
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { i as indexProject, n as indexAll, r as indexFile } from "./sync-Btcb6xA4.mjs";
|
|
8
|
-
import "./embeddings-DvRKcQyt.mjs";
|
|
9
|
-
import { a as searchMemory, i as populateSlugs, n as buildFtsQuery } from "./search-B69cQwDB.mjs";
|
|
10
|
-
import { n as rerankResults, t as configureRerankerModel } from "./reranker-HHmhZk6v.mjs";
|
|
1
|
+
import "./utils-C9HsYDpO.mjs";
|
|
2
|
+
import { a as slugify, i as parseSessionFilename, n as decodeEncodedDir, r as migrateFromJson } from "./migrate-BD7D8EEh.mjs";
|
|
3
|
+
import { n as ensurePaiMarker, r as readPaiMarker, t as discoverPaiMarkers } from "./pai-marker-D1MMswkz.mjs";
|
|
4
|
+
import { l as chunkMarkdown, r as detectTier, u as estimateTokens } from "./helpers-D9WkIf9R.mjs";
|
|
5
|
+
import { i as populateSlugs, n as buildFtsQuery } from "./search-BaTbyWjK.mjs";
|
|
6
|
+
import { n as rerankResults, t as configureRerankerModel } from "./reranker-CRVawoEh.mjs";
|
|
11
7
|
|
|
12
|
-
export {
|
|
8
|
+
export { buildFtsQuery, chunkMarkdown, configureRerankerModel, decodeEncodedDir, detectTier, discoverPaiMarkers, ensurePaiMarker, estimateTokens, migrateFromJson, parseSessionFilename, populateSlugs, readPaiMarker, rerankResults, slugify };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { a as parseSessionTitleChunk } from "./helpers-D9WkIf9R.mjs";
|
|
2
|
+
import { i as indexProjectWithBackend, n as indexAllWithBackend, r as indexFileWithBackend, t as embedChunksWithBackend } from "./async-CLvuY7b-.mjs";
|
|
3
|
+
import "./indexer-backend-Cc-_NK3q.mjs";
|
|
4
|
+
|
|
5
|
+
export { embedChunksWithBackend };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as paiSocketPath } from "./runtime-paths-
|
|
1
|
+
import { i as paiSocketPath } from "./runtime-paths-BRwDeBEg.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { connect } from "node:net";
|
|
4
4
|
|
|
@@ -155,4 +155,4 @@ var PaiClient = class {
|
|
|
155
155
|
|
|
156
156
|
//#endregion
|
|
157
157
|
export { PaiClient as t };
|
|
158
|
-
//# sourceMappingURL=ipc-client-
|
|
158
|
+
//# sourceMappingURL=ipc-client-Dasm515c.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ipc-client-C6NryMMb.mjs","names":[],"sources":["../src/daemon/ipc-client.ts"],"sourcesContent":["/**\n * ipc-client.ts — IPC client for the PAI Daemon MCP shim\n *\n * PaiClient connects to the Unix Domain Socket served by daemon.ts\n * and forwards tool calls to the daemon. Uses a fresh socket connection per\n * call (connect → write JSON + newline → read response line → parse → destroy).\n * This keeps the client stateless and avoids connection management complexity.\n *\n * Adapted from the Coogle ipc-client pattern (which was adapted from Whazaa).\n */\n\nimport { connect, Socket } from \"node:net\";\nimport { randomUUID } from \"node:crypto\";\nimport type {\n NotificationConfig,\n NotificationMode,\n NotificationEvent,\n SendResult,\n} from \"../notifications/types.js\";\nimport type { TopicCheckParams, TopicCheckResult } from \"../topics/detector.js\";\nimport type { AutoRouteResult } from \"../session/auto-route.js\";\nimport { paiSocketPath } from \"../runtime-paths.js\";\n\n// ---------------------------------------------------------------------------\n// Protocol types\n// ---------------------------------------------------------------------------\n\n/** Default socket path */\nexport const IPC_SOCKET_PATH = paiSocketPath();\n\n/** Timeout for IPC calls (60 seconds) */\nconst IPC_TIMEOUT_MS = 60_000;\n\ninterface IpcRequest {\n id: string;\n method: string;\n params: Record<string, unknown>;\n}\n\ninterface IpcResponse {\n id: string;\n ok: boolean;\n result?: unknown;\n error?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Client\n// ---------------------------------------------------------------------------\n\n/**\n * Thin IPC proxy that forwards tool calls to pai-daemon over a Unix\n * Domain Socket. Each call opens a fresh connection, sends one NDJSON request,\n * reads the response, and closes. Stateless and simple.\n */\nexport class PaiClient {\n private readonly socketPath: string;\n\n constructor(socketPath?: string) {\n this.socketPath = socketPath ?? IPC_SOCKET_PATH;\n }\n\n /**\n * Call a PAI tool by name with the given params.\n * Returns the tool result or throws on error.\n *\n * `timeoutMs` overrides the default 60s wait — for a caller on a hook's\n * critical path (e.g. the threshold-triggered handover enqueue in\n * `cli/commands/session/autosave.ts`) where the actual work happens later,\n * asynchronously, in the daemon's worker loop, and only the cheap\n * enqueue handshake itself should ever be waited on.\n */\n async call(method: string, params: Record<string, unknown>, timeoutMs?: number): Promise<unknown> {\n return this.send(method, params, timeoutMs);\n }\n\n /**\n * Check daemon status.\n */\n async status(): Promise<Record<string, unknown>> {\n const result = await this.send(\"status\", {});\n return result as Record<string, unknown>;\n }\n\n /**\n * Trigger an immediate index run.\n */\n async triggerIndex(): Promise<void> {\n await this.send(\"index_now\", {});\n }\n\n // -------------------------------------------------------------------------\n // Notification methods\n // -------------------------------------------------------------------------\n\n /**\n * Get the current notification config from the daemon.\n */\n async getNotificationConfig(): Promise<{\n config: NotificationConfig;\n activeChannels: string[];\n }> {\n const result = await this.send(\"notification_get_config\", {});\n return result as { config: NotificationConfig; activeChannels: string[] };\n }\n\n /**\n * Patch the notification config on the daemon (and persist to disk).\n */\n async setNotificationConfig(patch: {\n mode?: NotificationMode;\n channels?: Partial<NotificationConfig[\"channels\"]>;\n routing?: Partial<NotificationConfig[\"routing\"]>;\n }): Promise<{ config: NotificationConfig }> {\n const result = await this.send(\"notification_set_config\", patch as Record<string, unknown>);\n return result as { config: NotificationConfig };\n }\n\n /**\n * Send a notification via the daemon (routes to configured channels).\n */\n async sendNotification(payload: {\n event: NotificationEvent;\n message: string;\n title?: string;\n }): Promise<SendResult> {\n const result = await this.send(\"notification_send\", payload as Record<string, unknown>);\n return result as SendResult;\n }\n\n // -------------------------------------------------------------------------\n // Topic detection methods\n // -------------------------------------------------------------------------\n\n /**\n * Check whether the provided context text has drifted to a different project\n * than the session's current routing.\n */\n async topicCheck(params: TopicCheckParams): Promise<TopicCheckResult> {\n const result = await this.send(\"topic_check\", params as unknown as Record<string, unknown>);\n return result as TopicCheckResult;\n }\n\n // -------------------------------------------------------------------------\n // Session routing methods\n // -------------------------------------------------------------------------\n\n /**\n * Automatically detect which project a session belongs to.\n * Tries path match, PAI.md marker walk, then topic detection (if context given).\n */\n async sessionAutoRoute(params: {\n cwd?: string;\n context?: string;\n }): Promise<AutoRouteResult | null> {\n // session_auto_route returns a ToolResult (content array). Extract the text\n // and parse JSON from it.\n const result = await this.send(\"session_auto_route\", params as Record<string, unknown>);\n const toolResult = result as { content?: Array<{ text: string }>; isError?: boolean };\n if (toolResult.isError) return null;\n const text = toolResult.content?.[0]?.text ?? \"\";\n // Text is either JSON (on match) or a human-readable \"no match\" message\n try {\n return JSON.parse(text) as AutoRouteResult;\n } catch {\n return null;\n }\n }\n\n // -------------------------------------------------------------------------\n // Internal transport\n // -------------------------------------------------------------------------\n\n /**\n * Send a single IPC request and wait for the response.\n * Opens a new socket connection per call — simple and reliable.\n */\n private send(\n method: string,\n params: Record<string, unknown>,\n timeoutMs: number = IPC_TIMEOUT_MS\n ): Promise<unknown> {\n const socketPath = this.socketPath;\n\n return new Promise((resolve, reject) => {\n let socket: Socket | null = null;\n let done = false;\n let buffer = \"\";\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n function finish(error: Error | null, value?: unknown): void {\n if (done) return;\n done = true;\n if (timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n try {\n socket?.destroy();\n } catch {\n // ignore\n }\n if (error) {\n reject(error);\n } else {\n resolve(value);\n }\n }\n\n socket = connect(socketPath, () => {\n const request: IpcRequest = {\n id: randomUUID(),\n method,\n params,\n };\n socket!.write(JSON.stringify(request) + \"\\n\");\n });\n\n socket.on(\"data\", (chunk: Buffer) => {\n buffer += chunk.toString();\n const nl = buffer.indexOf(\"\\n\");\n if (nl === -1) return;\n\n const line = buffer.slice(0, nl);\n buffer = buffer.slice(nl + 1);\n\n let response: IpcResponse;\n try {\n response = JSON.parse(line) as IpcResponse;\n } catch {\n finish(new Error(`IPC parse error: ${line}`));\n return;\n }\n\n if (!response.ok) {\n finish(new Error(response.error ?? \"IPC call failed\"));\n } else {\n finish(null, response.result);\n }\n });\n\n socket.on(\"error\", (e: NodeJS.ErrnoException) => {\n if (e.code === \"ENOENT\" || e.code === \"ECONNREFUSED\") {\n finish(\n new Error(\n \"PAI daemon not running. Start it with: pai daemon serve\"\n )\n );\n } else {\n finish(e);\n }\n });\n\n socket.on(\"end\", () => {\n if (!done) {\n finish(new Error(\"IPC connection closed before response\"));\n }\n });\n\n timer = setTimeout(() => {\n finish(new Error(`IPC call timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA4BA,MAAa,kBAAkB,eAAe;;AAG9C,MAAM,iBAAiB;;;;;;AAwBvB,IAAa,YAAb,MAAuB;CACrB,AAAiB;CAEjB,YAAY,YAAqB;AAC/B,OAAK,aAAa,cAAc;;;;;;;;;;;;CAalC,MAAM,KAAK,QAAgB,QAAiC,WAAsC;AAChG,SAAO,KAAK,KAAK,QAAQ,QAAQ,UAAU;;;;;CAM7C,MAAM,SAA2C;AAE/C,SADe,MAAM,KAAK,KAAK,UAAU,EAAE,CAAC;;;;;CAO9C,MAAM,eAA8B;AAClC,QAAM,KAAK,KAAK,aAAa,EAAE,CAAC;;;;;CAUlC,MAAM,wBAGH;AAED,SADe,MAAM,KAAK,KAAK,2BAA2B,EAAE,CAAC;;;;;CAO/D,MAAM,sBAAsB,OAIgB;AAE1C,SADe,MAAM,KAAK,KAAK,2BAA2B,MAAiC;;;;;CAO7F,MAAM,iBAAiB,SAIC;AAEtB,SADe,MAAM,KAAK,KAAK,qBAAqB,QAAmC;;;;;;CAYzF,MAAM,WAAW,QAAqD;AAEpE,SADe,MAAM,KAAK,KAAK,eAAe,OAA6C;;;;;;CAY7F,MAAM,iBAAiB,QAGa;EAIlC,MAAM,aADS,MAAM,KAAK,KAAK,sBAAsB,OAAkC;AAEvF,MAAI,WAAW,QAAS,QAAO;EAC/B,MAAM,OAAO,WAAW,UAAU,IAAI,QAAQ;AAE9C,MAAI;AACF,UAAO,KAAK,MAAM,KAAK;UACjB;AACN,UAAO;;;;;;;CAYX,AAAQ,KACN,QACA,QACA,YAAoB,gBACF;EAClB,MAAM,aAAa,KAAK;AAExB,SAAO,IAAI,SAAS,SAAS,WAAW;GACtC,IAAI,SAAwB;GAC5B,IAAI,OAAO;GACX,IAAI,SAAS;GACb,IAAI,QAA8C;GAElD,SAAS,OAAO,OAAqB,OAAuB;AAC1D,QAAI,KAAM;AACV,WAAO;AACP,QAAI,UAAU,MAAM;AAClB,kBAAa,MAAM;AACnB,aAAQ;;AAEV,QAAI;AACF,aAAQ,SAAS;YACX;AAGR,QAAI,MACF,QAAO,MAAM;QAEb,SAAQ,MAAM;;AAIlB,YAAS,QAAQ,kBAAkB;IACjC,MAAM,UAAsB;KAC1B,IAAI,YAAY;KAChB;KACA;KACD;AACD,WAAQ,MAAM,KAAK,UAAU,QAAQ,GAAG,KAAK;KAC7C;AAEF,UAAO,GAAG,SAAS,UAAkB;AACnC,cAAU,MAAM,UAAU;IAC1B,MAAM,KAAK,OAAO,QAAQ,KAAK;AAC/B,QAAI,OAAO,GAAI;IAEf,MAAM,OAAO,OAAO,MAAM,GAAG,GAAG;AAChC,aAAS,OAAO,MAAM,KAAK,EAAE;IAE7B,IAAI;AACJ,QAAI;AACF,gBAAW,KAAK,MAAM,KAAK;YACrB;AACN,4BAAO,IAAI,MAAM,oBAAoB,OAAO,CAAC;AAC7C;;AAGF,QAAI,CAAC,SAAS,GACZ,QAAO,IAAI,MAAM,SAAS,SAAS,kBAAkB,CAAC;QAEtD,QAAO,MAAM,SAAS,OAAO;KAE/B;AAEF,UAAO,GAAG,UAAU,MAA6B;AAC/C,QAAI,EAAE,SAAS,YAAY,EAAE,SAAS,eACpC,wBACE,IAAI,MACF,0DACD,CACF;QAED,QAAO,EAAE;KAEX;AAEF,UAAO,GAAG,aAAa;AACrB,QAAI,CAAC,KACH,wBAAO,IAAI,MAAM,wCAAwC,CAAC;KAE5D;AAEF,WAAQ,iBAAiB;AACvB,2BAAO,IAAI,MAAM,4BAA4B,UAAU,IAAI,CAAC;MAC3D,UAAU;IACb"}
|
|
1
|
+
{"version":3,"file":"ipc-client-Dasm515c.mjs","names":[],"sources":["../src/daemon/ipc-client.ts"],"sourcesContent":["/**\n * ipc-client.ts — IPC client for the PAI Daemon MCP shim\n *\n * PaiClient connects to the Unix Domain Socket served by daemon.ts\n * and forwards tool calls to the daemon. Uses a fresh socket connection per\n * call (connect → write JSON + newline → read response line → parse → destroy).\n * This keeps the client stateless and avoids connection management complexity.\n *\n * Adapted from the Coogle ipc-client pattern (which was adapted from Whazaa).\n */\n\nimport { connect, Socket } from \"node:net\";\nimport { randomUUID } from \"node:crypto\";\nimport type {\n NotificationConfig,\n NotificationMode,\n NotificationEvent,\n SendResult,\n} from \"../notifications/types.js\";\nimport type { TopicCheckParams, TopicCheckResult } from \"../topics/detector.js\";\nimport type { AutoRouteResult } from \"../session/auto-route.js\";\nimport { paiSocketPath } from \"../runtime-paths.js\";\n\n// ---------------------------------------------------------------------------\n// Protocol types\n// ---------------------------------------------------------------------------\n\n/** Default socket path */\nexport const IPC_SOCKET_PATH = paiSocketPath();\n\n/** Timeout for IPC calls (60 seconds) */\nconst IPC_TIMEOUT_MS = 60_000;\n\ninterface IpcRequest {\n id: string;\n method: string;\n params: Record<string, unknown>;\n}\n\ninterface IpcResponse {\n id: string;\n ok: boolean;\n result?: unknown;\n error?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Client\n// ---------------------------------------------------------------------------\n\n/**\n * Thin IPC proxy that forwards tool calls to pai-daemon over a Unix\n * Domain Socket. Each call opens a fresh connection, sends one NDJSON request,\n * reads the response, and closes. Stateless and simple.\n */\nexport class PaiClient {\n private readonly socketPath: string;\n\n constructor(socketPath?: string) {\n this.socketPath = socketPath ?? IPC_SOCKET_PATH;\n }\n\n /**\n * Call a PAI tool by name with the given params.\n * Returns the tool result or throws on error.\n *\n * `timeoutMs` overrides the default 60s wait — for a caller on a hook's\n * critical path (e.g. the threshold-triggered handover enqueue in\n * `cli/commands/session/autosave.ts`) where the actual work happens later,\n * asynchronously, in the daemon's worker loop, and only the cheap\n * enqueue handshake itself should ever be waited on.\n */\n async call(method: string, params: Record<string, unknown>, timeoutMs?: number): Promise<unknown> {\n return this.send(method, params, timeoutMs);\n }\n\n /**\n * Check daemon status.\n */\n async status(): Promise<Record<string, unknown>> {\n const result = await this.send(\"status\", {});\n return result as Record<string, unknown>;\n }\n\n /**\n * Trigger an immediate index run.\n */\n async triggerIndex(): Promise<void> {\n await this.send(\"index_now\", {});\n }\n\n // -------------------------------------------------------------------------\n // Notification methods\n // -------------------------------------------------------------------------\n\n /**\n * Get the current notification config from the daemon.\n */\n async getNotificationConfig(): Promise<{\n config: NotificationConfig;\n activeChannels: string[];\n }> {\n const result = await this.send(\"notification_get_config\", {});\n return result as { config: NotificationConfig; activeChannels: string[] };\n }\n\n /**\n * Patch the notification config on the daemon (and persist to disk).\n */\n async setNotificationConfig(patch: {\n mode?: NotificationMode;\n channels?: Partial<NotificationConfig[\"channels\"]>;\n routing?: Partial<NotificationConfig[\"routing\"]>;\n }): Promise<{ config: NotificationConfig }> {\n const result = await this.send(\"notification_set_config\", patch as Record<string, unknown>);\n return result as { config: NotificationConfig };\n }\n\n /**\n * Send a notification via the daemon (routes to configured channels).\n */\n async sendNotification(payload: {\n event: NotificationEvent;\n message: string;\n title?: string;\n }): Promise<SendResult> {\n const result = await this.send(\"notification_send\", payload as Record<string, unknown>);\n return result as SendResult;\n }\n\n // -------------------------------------------------------------------------\n // Topic detection methods\n // -------------------------------------------------------------------------\n\n /**\n * Check whether the provided context text has drifted to a different project\n * than the session's current routing.\n */\n async topicCheck(params: TopicCheckParams): Promise<TopicCheckResult> {\n const result = await this.send(\"topic_check\", params as unknown as Record<string, unknown>);\n return result as TopicCheckResult;\n }\n\n // -------------------------------------------------------------------------\n // Session routing methods\n // -------------------------------------------------------------------------\n\n /**\n * Automatically detect which project a session belongs to.\n * Tries path match, PAI.md marker walk, then topic detection (if context given).\n */\n async sessionAutoRoute(params: {\n cwd?: string;\n context?: string;\n }): Promise<AutoRouteResult | null> {\n // session_auto_route returns a ToolResult (content array). Extract the text\n // and parse JSON from it.\n const result = await this.send(\"session_auto_route\", params as Record<string, unknown>);\n const toolResult = result as { content?: Array<{ text: string }>; isError?: boolean };\n if (toolResult.isError) return null;\n const text = toolResult.content?.[0]?.text ?? \"\";\n // Text is either JSON (on match) or a human-readable \"no match\" message\n try {\n return JSON.parse(text) as AutoRouteResult;\n } catch {\n return null;\n }\n }\n\n // -------------------------------------------------------------------------\n // Internal transport\n // -------------------------------------------------------------------------\n\n /**\n * Send a single IPC request and wait for the response.\n * Opens a new socket connection per call — simple and reliable.\n */\n private send(\n method: string,\n params: Record<string, unknown>,\n timeoutMs: number = IPC_TIMEOUT_MS\n ): Promise<unknown> {\n const socketPath = this.socketPath;\n\n return new Promise((resolve, reject) => {\n let socket: Socket | null = null;\n let done = false;\n let buffer = \"\";\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n function finish(error: Error | null, value?: unknown): void {\n if (done) return;\n done = true;\n if (timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n try {\n socket?.destroy();\n } catch {\n // ignore\n }\n if (error) {\n reject(error);\n } else {\n resolve(value);\n }\n }\n\n socket = connect(socketPath, () => {\n const request: IpcRequest = {\n id: randomUUID(),\n method,\n params,\n };\n socket!.write(JSON.stringify(request) + \"\\n\");\n });\n\n socket.on(\"data\", (chunk: Buffer) => {\n buffer += chunk.toString();\n const nl = buffer.indexOf(\"\\n\");\n if (nl === -1) return;\n\n const line = buffer.slice(0, nl);\n buffer = buffer.slice(nl + 1);\n\n let response: IpcResponse;\n try {\n response = JSON.parse(line) as IpcResponse;\n } catch {\n finish(new Error(`IPC parse error: ${line}`));\n return;\n }\n\n if (!response.ok) {\n finish(new Error(response.error ?? \"IPC call failed\"));\n } else {\n finish(null, response.result);\n }\n });\n\n socket.on(\"error\", (e: NodeJS.ErrnoException) => {\n if (e.code === \"ENOENT\" || e.code === \"ECONNREFUSED\") {\n finish(\n new Error(\n \"PAI daemon not running. Start it with: pai daemon serve\"\n )\n );\n } else {\n finish(e);\n }\n });\n\n socket.on(\"end\", () => {\n if (!done) {\n finish(new Error(\"IPC connection closed before response\"));\n }\n });\n\n timer = setTimeout(() => {\n finish(new Error(`IPC call timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA4BA,MAAa,kBAAkB,eAAe;;AAG9C,MAAM,iBAAiB;;;;;;AAwBvB,IAAa,YAAb,MAAuB;CACrB,AAAiB;CAEjB,YAAY,YAAqB;AAC/B,OAAK,aAAa,cAAc;;;;;;;;;;;;CAalC,MAAM,KAAK,QAAgB,QAAiC,WAAsC;AAChG,SAAO,KAAK,KAAK,QAAQ,QAAQ,UAAU;;;;;CAM7C,MAAM,SAA2C;AAE/C,SADe,MAAM,KAAK,KAAK,UAAU,EAAE,CAAC;;;;;CAO9C,MAAM,eAA8B;AAClC,QAAM,KAAK,KAAK,aAAa,EAAE,CAAC;;;;;CAUlC,MAAM,wBAGH;AAED,SADe,MAAM,KAAK,KAAK,2BAA2B,EAAE,CAAC;;;;;CAO/D,MAAM,sBAAsB,OAIgB;AAE1C,SADe,MAAM,KAAK,KAAK,2BAA2B,MAAiC;;;;;CAO7F,MAAM,iBAAiB,SAIC;AAEtB,SADe,MAAM,KAAK,KAAK,qBAAqB,QAAmC;;;;;;CAYzF,MAAM,WAAW,QAAqD;AAEpE,SADe,MAAM,KAAK,KAAK,eAAe,OAA6C;;;;;;CAY7F,MAAM,iBAAiB,QAGa;EAIlC,MAAM,aADS,MAAM,KAAK,KAAK,sBAAsB,OAAkC;AAEvF,MAAI,WAAW,QAAS,QAAO;EAC/B,MAAM,OAAO,WAAW,UAAU,IAAI,QAAQ;AAE9C,MAAI;AACF,UAAO,KAAK,MAAM,KAAK;UACjB;AACN,UAAO;;;;;;;CAYX,AAAQ,KACN,QACA,QACA,YAAoB,gBACF;EAClB,MAAM,aAAa,KAAK;AAExB,SAAO,IAAI,SAAS,SAAS,WAAW;GACtC,IAAI,SAAwB;GAC5B,IAAI,OAAO;GACX,IAAI,SAAS;GACb,IAAI,QAA8C;GAElD,SAAS,OAAO,OAAqB,OAAuB;AAC1D,QAAI,KAAM;AACV,WAAO;AACP,QAAI,UAAU,MAAM;AAClB,kBAAa,MAAM;AACnB,aAAQ;;AAEV,QAAI;AACF,aAAQ,SAAS;YACX;AAGR,QAAI,MACF,QAAO,MAAM;QAEb,SAAQ,MAAM;;AAIlB,YAAS,QAAQ,kBAAkB;IACjC,MAAM,UAAsB;KAC1B,IAAI,YAAY;KAChB;KACA;KACD;AACD,WAAQ,MAAM,KAAK,UAAU,QAAQ,GAAG,KAAK;KAC7C;AAEF,UAAO,GAAG,SAAS,UAAkB;AACnC,cAAU,MAAM,UAAU;IAC1B,MAAM,KAAK,OAAO,QAAQ,KAAK;AAC/B,QAAI,OAAO,GAAI;IAEf,MAAM,OAAO,OAAO,MAAM,GAAG,GAAG;AAChC,aAAS,OAAO,MAAM,KAAK,EAAE;IAE7B,IAAI;AACJ,QAAI;AACF,gBAAW,KAAK,MAAM,KAAK;YACrB;AACN,4BAAO,IAAI,MAAM,oBAAoB,OAAO,CAAC;AAC7C;;AAGF,QAAI,CAAC,SAAS,GACZ,QAAO,IAAI,MAAM,SAAS,SAAS,kBAAkB,CAAC;QAEtD,QAAO,MAAM,SAAS,OAAO;KAE/B;AAEF,UAAO,GAAG,UAAU,MAA6B;AAC/C,QAAI,EAAE,SAAS,YAAY,EAAE,SAAS,eACpC,wBACE,IAAI,MACF,0DACD,CACF;QAED,QAAO,EAAE;KAEX;AAEF,UAAO,GAAG,aAAa;AACrB,QAAI,CAAC,KACH,wBAAO,IAAI,MAAM,wCAAwC,CAAC;KAE5D;AAEF,WAAQ,iBAAiB;AACvB,2BAAO,IAAI,MAAM,4BAA4B,UAAU,IAAI,CAAC;MAC3D,UAAU;IACb"}
|