@tekmidian/pai 0.54.1 → 0.56.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-CZKlI0hq.mjs → chain-26f7uGUs.mjs} +4 -4
- package/dist/{chain-CZKlI0hq.mjs.map → chain-26f7uGUs.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-BOWol-LF.mjs +19 -0
- package/dist/{daemon-aJTxzg20.mjs → daemon-BsuM0UdV.mjs} +97 -466
- package/dist/daemon-BsuM0UdV.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-CCFIpPha.mjs → fallback-CVe3sb94.mjs} +192 -134
- package/dist/fallback-CVe3sb94.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-D3keWys5.mjs → planner-ye7wrrfB.mjs} +7 -7
- package/dist/{planner-D3keWys5.mjs.map → planner-ye7wrrfB.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-B3eRMhff.mjs → program-DuC1RcaO.mjs} +2268 -1402
- package/dist/program-DuC1RcaO.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-DLG25bzt.mjs → run-CqRvXGjd.mjs} +309 -49
- package/dist/run-CqRvXGjd.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-DklS8VmU.mjs → session-keepalive-BQ6AQ9ez.mjs} +7 -7
- package/dist/{session-keepalive-DklS8VmU.mjs.map → session-keepalive-BQ6AQ9ez.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-CknQ6YGZ.mjs +0 -25
- package/dist/daemon-aJTxzg20.mjs.map +0 -1
- 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-CCFIpPha.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-B3eRMhff.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-DLG25bzt.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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as paiHomePath, n as migratePaiDir, o as resolvePaiFile } from "./pai-home-
|
|
1
|
+
import { a as paiHomePath, n as migratePaiDir, o as resolvePaiFile } from "./pai-home-CeOIYltV.mjs";
|
|
2
2
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -10,7 +10,7 @@ import { join } from "node:path";
|
|
|
10
10
|
* When memory_search or zettel_converse returns results, the query + result
|
|
11
11
|
* metadata is saved to ~/.config/pai/queries/ as a markdown file with YAML
|
|
12
12
|
* frontmatter. The daemon indexer picks these up on the next cycle and indexes
|
|
13
|
-
* them into
|
|
13
|
+
* them into the storage backend, creating a self-reinforcing feedback loop: past
|
|
14
14
|
* queries become searchable context for future queries.
|
|
15
15
|
*/
|
|
16
16
|
function oldQueriesDir() {
|
|
@@ -85,4 +85,4 @@ function saveQueryResult(record) {
|
|
|
85
85
|
|
|
86
86
|
//#endregion
|
|
87
87
|
export { queriesDirPath as n, saveQueryResult as r, migrateQueriesDir as t };
|
|
88
|
-
//# sourceMappingURL=query-feedback-
|
|
88
|
+
//# sourceMappingURL=query-feedback-xz5axTj3.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-feedback-xz5axTj3.mjs","names":[],"sources":["../src/zettelkasten/query-feedback.ts"],"sourcesContent":["/**\n * Query feedback loop — persist search queries and results as markdown files.\n *\n * When memory_search or zettel_converse returns results, the query + result\n * metadata is saved to ~/.config/pai/queries/ as a markdown file with YAML\n * frontmatter. The daemon indexer picks these up on the next cycle and indexes\n * them into the storage backend, creating a self-reinforcing feedback loop: past\n * queries become searchable context for future queries.\n */\n\nimport { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { paiHomePath, resolvePaiFile, migratePaiDir, type MigrateDirResult } from \"../config/pai-home.js\";\n\nexport interface QueryRecord {\n /** The original query string. */\n query: string;\n /** Timestamp of the query. */\n timestamp: number;\n /** Tool that produced the result: 'memory_search' | 'zettel_converse'. */\n source: string;\n /** Slugs of the top result paths (for linking back). */\n sourceSlugs: string[];\n /** Preview of the answer/result (first 500 chars). */\n answerPreview: string;\n /** Number of results returned. */\n resultCount: number;\n}\n\nfunction oldQueriesDir(): string {\n return join(homedir(), \".config\", \"pai\", \"queries\");\n}\n\n/** Where queries live: the new PAI_HOME dir if it has anything in it or was\n * already created, else the pre-2026-09-19 ~/.config/pai/queries (printing\n * a one-time notice), else the new dir (the target a first write creates). */\nexport function queriesDirPath(): string {\n return resolvePaiFile(paiHomePath(\"queries\"), [oldQueriesDir()], \"pai config migrate\");\n}\n\nexport function migrateQueriesDir(opts: { dryRun?: boolean } = {}): MigrateDirResult {\n return migratePaiDir(paiHomePath(\"queries\"), [oldQueriesDir()], opts);\n}\n\n/**\n * Ensure the queries directory exists.\n */\nfunction ensureQueriesDir(): void {\n const dir = paiHomePath(\"queries\");\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n}\n\n/**\n * Generate a filename-safe slug from a query string.\n */\nfunction querySlug(query: string, timestamp: number): string {\n const slug = query\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, \"\")\n .replace(/\\s+/g, \"-\")\n .slice(0, 60);\n const ts = new Date(timestamp).toISOString().slice(0, 10);\n const shortHash = timestamp.toString(36).slice(-4);\n return `${ts}-${slug}-${shortHash}`;\n}\n\n/**\n * Save a query + result record as a markdown file with YAML frontmatter.\n *\n * The file is written to PAI_HOME's queries/ dir and will be picked up by\n * the daemon indexer on the next cycle.\n */\nexport function saveQueryResult(record: QueryRecord): string | null {\n try {\n ensureQueriesDir();\n\n const filename = querySlug(record.query, record.timestamp) + \".md\";\n const filepath = join(paiHomePath(\"queries\"), filename);\n\n // Don't overwrite if the exact file already exists\n if (existsSync(filepath)) return filepath;\n\n const frontmatter = [\n \"---\",\n `query: \"${record.query.replace(/\"/g, '\\\\\"')}\"`,\n `timestamp: ${new Date(record.timestamp).toISOString()}`,\n `source: ${record.source}`,\n `result_count: ${record.resultCount}`,\n `source_slugs:`,\n ...record.sourceSlugs.map((s) => ` - \"${s}\"`),\n \"---\",\n ].join(\"\\n\");\n\n const body = [\n \"\",\n `# Query: ${record.query}`,\n \"\",\n `**Source:** ${record.source} `,\n `**Date:** ${new Date(record.timestamp).toISOString().slice(0, 19).replace(\"T\", \" \")} `,\n `**Results:** ${record.resultCount}`,\n \"\",\n \"## Answer Preview\",\n \"\",\n record.answerPreview,\n \"\",\n \"## Source Paths\",\n \"\",\n ...record.sourceSlugs.map((s) => `- \\`${s}\\``),\n \"\",\n ].join(\"\\n\");\n\n writeFileSync(filepath, frontmatter + body, \"utf8\");\n return filepath;\n } catch {\n // Non-critical — don't crash the parent tool if query logging fails\n return null;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AA8BA,SAAS,gBAAwB;AAC/B,QAAO,KAAK,SAAS,EAAE,WAAW,OAAO,UAAU;;;;;AAMrD,SAAgB,iBAAyB;AACvC,QAAO,eAAe,YAAY,UAAU,EAAE,CAAC,eAAe,CAAC,EAAE,qBAAqB;;AAGxF,SAAgB,kBAAkB,OAA6B,EAAE,EAAoB;AACnF,QAAO,cAAc,YAAY,UAAU,EAAE,CAAC,eAAe,CAAC,EAAE,KAAK;;;;;AAMvE,SAAS,mBAAyB;CAChC,MAAM,MAAM,YAAY,UAAU;AAClC,KAAI,CAAC,WAAW,IAAI,CAClB,WAAU,KAAK,EAAE,WAAW,MAAM,CAAC;;;;;AAOvC,SAAS,UAAU,OAAe,WAA2B;CAC3D,MAAM,OAAO,MACV,aAAa,CACb,QAAQ,gBAAgB,GAAG,CAC3B,QAAQ,QAAQ,IAAI,CACpB,MAAM,GAAG,GAAG;AAGf,QAAO,GAFI,IAAI,KAAK,UAAU,CAAC,aAAa,CAAC,MAAM,GAAG,GAAG,CAE5C,GAAG,KAAK,GADH,UAAU,SAAS,GAAG,CAAC,MAAM,GAAG;;;;;;;;AAUpD,SAAgB,gBAAgB,QAAoC;AAClE,KAAI;AACF,oBAAkB;EAElB,MAAM,WAAW,UAAU,OAAO,OAAO,OAAO,UAAU,GAAG;EAC7D,MAAM,WAAW,KAAK,YAAY,UAAU,EAAE,SAAS;AAGvD,MAAI,WAAW,SAAS,CAAE,QAAO;AA+BjC,gBAAc,UA7BM;GAClB;GACA,WAAW,OAAO,MAAM,QAAQ,MAAM,OAAM,CAAC;GAC7C,cAAc,IAAI,KAAK,OAAO,UAAU,CAAC,aAAa;GACtD,WAAW,OAAO;GAClB,iBAAiB,OAAO;GACxB;GACA,GAAG,OAAO,YAAY,KAAK,MAAM,QAAQ,EAAE,GAAG;GAC9C;GACD,CAAC,KAAK,KAAK,GAEC;GACX;GACA,YAAY,OAAO;GACnB;GACA,eAAe,OAAO,OAAO;GAC7B,aAAa,IAAI,KAAK,OAAO,UAAU,CAAC,aAAa,CAAC,MAAM,GAAG,GAAG,CAAC,QAAQ,KAAK,IAAI,CAAC;GACrF,gBAAgB,OAAO;GACvB;GACA;GACA;GACA,OAAO;GACP;GACA;GACA;GACA,GAAG,OAAO,YAAY,KAAK,MAAM,OAAO,EAAE,IAAI;GAC9C;GACD,CAAC,KAAK,KAAK,EAEgC,OAAO;AACnD,SAAO;SACD;AAEN,SAAO"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { a as paiHomePath, o as resolvePaiFile } from "./pai-home-
|
|
1
|
+
import { a as paiHomePath, o as resolvePaiFile } from "./pai-home-CeOIYltV.mjs";
|
|
2
2
|
import { mkdirSync } from "node:fs";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
5
5
|
import BetterSqlite3 from "better-sqlite3";
|
|
6
6
|
|
|
7
|
-
//#region src/registry
|
|
7
|
+
//#region src/storage/sqlite/registry-schema.ts
|
|
8
8
|
const SCHEMA_VERSION = 4;
|
|
9
9
|
const CREATE_TABLES_SQL = `
|
|
10
10
|
PRAGMA journal_mode = WAL;
|
|
@@ -168,7 +168,7 @@ function runMigrations(db) {
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
//#endregion
|
|
171
|
-
//#region src/registry
|
|
171
|
+
//#region src/storage/sqlite/registry-db.ts
|
|
172
172
|
/**
|
|
173
173
|
* Database connection helper for the PAI registry.
|
|
174
174
|
*
|
|
@@ -209,5 +209,5 @@ function openRegistry(path = registryDbPath()) {
|
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
//#endregion
|
|
212
|
-
export {
|
|
213
|
-
//# sourceMappingURL=db-
|
|
212
|
+
export { openRegistry as n, registryDbPath as r, oldRegistryPath as t };
|
|
213
|
+
//# sourceMappingURL=registry-db-Bkpbp7Gf.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-db-Bkpbp7Gf.mjs","names":[],"sources":["../src/storage/sqlite/registry-schema.ts","../src/storage/sqlite/registry-db.ts"],"sourcesContent":["/**\n * SQLite DDL for the PAI registry database.\n *\n * Tables:\n * - projects — tracked project directories with type and status\n * - sessions — per-project session notes\n * - tags — normalised tag vocabulary\n * - project_tags — M:N join between projects and tags\n * - session_tags — M:N join between sessions and tags\n * - aliases — alternative slugs that resolve to a project\n * - compaction_log — audit trail for context-compaction events\n * - schema_version — single-row migration version tracking\n */\n\nimport type { Database } from \"better-sqlite3\";\n\nexport const SCHEMA_VERSION = 4;\n\nexport 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`;\n\n/**\n * Run the full DDL against an open database connection.\n *\n * The function is idempotent — every statement uses IF NOT EXISTS so it is\n * safe to call on an already-initialised database. After creating the tables\n * it inserts the current SCHEMA_VERSION into schema_version if no row exists\n * yet.\n */\nexport function initializeSchema(db: Database): void {\n // better-sqlite3's exec() runs multiple semicolon-separated statements\n db.exec(CREATE_TABLES_SQL);\n\n const row = db\n .prepare(\"SELECT version FROM schema_version WHERE version = ?\")\n .get(SCHEMA_VERSION);\n\n if (!row) {\n db.prepare(\n \"INSERT INTO schema_version (version, applied_at) VALUES (?, ?)\"\n ).run(SCHEMA_VERSION, Date.now());\n }\n}\n\n/**\n * Apply incremental schema migrations to an already-initialised database.\n *\n * Each migration is guarded by a version check so it is safe to call on\n * databases at any schema version — already-applied migrations are skipped.\n */\nexport function runMigrations(db: Database): void {\n const currentRow = db\n .prepare(\"SELECT version FROM schema_version ORDER BY version DESC LIMIT 1\")\n .get() as { version: number } | undefined;\n\n const current = currentRow?.version ?? 0;\n\n // Migration v1 → v2: add claude_notes_dir column to projects\n if (current < 2) {\n db.transaction(() => {\n // Use a try/catch so re-running on a DB that already has the column is safe\n try {\n db.exec(\"ALTER TABLE projects ADD COLUMN claude_notes_dir TEXT\");\n } catch {\n // Column may already exist (e.g. fresh DB created with v2 DDL)\n }\n db.prepare(\n \"INSERT OR REPLACE INTO schema_version (version, applied_at) VALUES (?, ?)\"\n ).run(2, Date.now());\n })();\n }\n\n // Migration v2 → v3: add links table for cross-project session references\n if (current < 3) {\n db.transaction(() => {\n try {\n db.exec(`\n CREATE 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 `);\n } catch {\n // Table may already exist (fresh DB created with v3 DDL)\n }\n db.prepare(\n \"INSERT OR REPLACE INTO schema_version (version, applied_at) VALUES (?, ?)\"\n ).run(3, Date.now());\n })();\n }\n\n // Migration v3 → v4: add session_config column to projects\n if (current < 4) {\n db.transaction(() => {\n try {\n db.exec(\"ALTER TABLE projects ADD COLUMN session_config TEXT\");\n } catch {\n // Column may already exist\n }\n db.prepare(\n \"INSERT OR REPLACE INTO schema_version (version, applied_at) VALUES (?, ?)\"\n ).run(4, Date.now());\n })();\n }\n}\n","/**\n * Database connection helper for the PAI registry.\n *\n * Uses better-sqlite3 (synchronous API) to open or create registry.db.\n * On first open it runs the full DDL via initializeSchema().\n */\n\nimport { mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport BetterSqlite3 from \"better-sqlite3\";\nimport type { Database } from \"better-sqlite3\";\nimport { initializeSchema, runMigrations } from \"./registry-schema.js\";\nimport { paiHomePath, resolvePaiFile } from \"../../config/pai-home.js\";\n\nexport type { Database };\n\n/** Old registry path, inside the ~/.pai/ directory (pre-2026-09-19). */\nexport function oldRegistryPath(): string {\n return join(homedir(), \".pai\", \"registry.db\");\n}\n\n/** Registry path: PAI_HOME/registry.db if present, else the old\n * ~/.pai/registry.db (one-time stderr notice), else the new path. */\nexport function registryDbPath(): string {\n return resolvePaiFile(paiHomePath(\"registry.db\"), [oldRegistryPath()], \"pai config migrate --registry\");\n}\n\n/**\n * Open (or create) the PAI registry database.\n *\n * @param path Absolute path to registry.db. Defaults to PAI_HOME/registry.db\n * (falling back to the pre-2026-09-19 ~/.pai/registry.db).\n * @returns An open better-sqlite3 Database instance.\n *\n * Side effects on first call:\n * - Creates the parent directory if it does not exist.\n * - Enables WAL journal mode.\n * - Runs initializeSchema() if schema_version is empty.\n */\nexport function openRegistry(path: string = registryDbPath()): Database {\n // Ensure the directory exists before SQLite tries to create the file\n mkdirSync(dirname(path), { recursive: true });\n\n const db = new BetterSqlite3(path);\n\n // WAL gives better concurrent read performance and crash safety\n db.pragma(\"journal_mode = WAL\");\n db.pragma(\"foreign_keys = ON\");\n\n // Check whether the schema has been applied before\n const tableExists = db\n .prepare(\n `SELECT name FROM sqlite_master\n WHERE type = 'table' AND name = 'schema_version'`\n )\n .get();\n\n if (!tableExists) {\n // Brand-new database — apply the full schema\n initializeSchema(db);\n } else {\n const row = db\n .prepare(\"SELECT version FROM schema_version LIMIT 1\")\n .get() as { version: number } | undefined;\n\n if (!row) {\n // Table exists but is empty — apply schema (handles partial init)\n initializeSchema(db);\n }\n }\n\n // Apply any pending incremental migrations\n runMigrations(db);\n\n return db;\n}\n"],"mappings":";;;;;;;AAgBA,MAAa,iBAAiB;AAE9B,MAAa,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsHjC,SAAgB,iBAAiB,IAAoB;AAEnD,IAAG,KAAK,kBAAkB;AAM1B,KAAI,CAJQ,GACT,QAAQ,uDAAuD,CAC/D,IAAI,eAAe,CAGpB,IAAG,QACD,iEACD,CAAC,IAAI,gBAAgB,KAAK,KAAK,CAAC;;;;;;;;AAUrC,SAAgB,cAAc,IAAoB;CAKhD,MAAM,UAJa,GAChB,QAAQ,mEAAmE,CAC3E,KAAK,EAEoB,WAAW;AAGvC,KAAI,UAAU,EACZ,IAAG,kBAAkB;AAEnB,MAAI;AACF,MAAG,KAAK,wDAAwD;UAC1D;AAGR,KAAG,QACD,4EACD,CAAC,IAAI,GAAG,KAAK,KAAK,CAAC;GACpB,EAAE;AAIN,KAAI,UAAU,EACZ,IAAG,kBAAkB;AACnB,MAAI;AACF,MAAG,KAAK;;;;;;;;;;;;UAYN;UACI;AAGR,KAAG,QACD,4EACD,CAAC,IAAI,GAAG,KAAK,KAAK,CAAC;GACpB,EAAE;AAIN,KAAI,UAAU,EACZ,IAAG,kBAAkB;AACnB,MAAI;AACF,MAAG,KAAK,sDAAsD;UACxD;AAGR,KAAG,QACD,4EACD,CAAC,IAAI,GAAG,KAAK,KAAK,CAAC;GACpB,EAAE;;;;;;;;;;;;ACtMR,SAAgB,kBAA0B;AACxC,QAAO,KAAK,SAAS,EAAE,QAAQ,cAAc;;;;AAK/C,SAAgB,iBAAyB;AACvC,QAAO,eAAe,YAAY,cAAc,EAAE,CAAC,iBAAiB,CAAC,EAAE,gCAAgC;;;;;;;;;;;;;;AAezG,SAAgB,aAAa,OAAe,gBAAgB,EAAY;AAEtE,WAAU,QAAQ,KAAK,EAAE,EAAE,WAAW,MAAM,CAAC;CAE7C,MAAM,KAAK,IAAI,cAAc,KAAK;AAGlC,IAAG,OAAO,qBAAqB;AAC/B,IAAG,OAAO,oBAAoB;AAU9B,KAAI,CAPgB,GACjB,QACC;yDAED,CACA,KAAK,CAIN,kBAAiB,GAAG;UAMhB,CAJQ,GACT,QAAQ,6CAA6C,CACrD,KAAK,CAIN,kBAAiB,GAAG;AAKxB,eAAc,GAAG;AAEjB,QAAO"}
|