@tekmidian/pai 0.66.0 → 0.66.2
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-B8c42Lh8.mjs → aibroker-client-CHEEvJZW.mjs} +2 -2
- package/dist/{aibroker-client-C5Fw7DNz.mjs → aibroker-client-Dfv7j1Od.mjs} +3 -3
- package/dist/{aibroker-client-C5Fw7DNz.mjs.map → aibroker-client-Dfv7j1Od.mjs.map} +1 -1
- package/dist/{auto-route-o0BOsXn7.mjs → auto-route-BnizyALK.mjs} +65 -4
- package/dist/auto-route-BnizyALK.mjs.map +1 -0
- package/dist/auto-route-D6fW1Q8z.mjs +3 -0
- package/dist/{chain-D4PuQ2c-.mjs → chain-D5876UQX.mjs} +3 -4
- package/dist/{chain-D4PuQ2c-.mjs.map → chain-D5876UQX.mjs.map} +1 -1
- package/dist/cli/index.mjs +18 -23
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/program.mjs +17 -22
- package/dist/{config-BbLFD7Uf.mjs → config-C-LiGlop.mjs} +2 -2
- package/dist/{config-BbLFD7Uf.mjs.map → config-C-LiGlop.mjs.map} +1 -1
- package/dist/{config-YinjgXEJ.mjs → config-DKIA7wgF.mjs} +1 -1
- package/dist/{context-handover-cache-pkHzmL3c.mjs → context-handover-cache-9PGvXRIw.mjs} +984 -10
- package/dist/context-handover-cache-9PGvXRIw.mjs.map +1 -0
- package/dist/daemon/index.mjs +17 -19
- package/dist/daemon/index.mjs.map +1 -1
- package/dist/daemon-BUgNvMUh.mjs +5029 -0
- package/dist/daemon-BUgNvMUh.mjs.map +1 -0
- package/dist/daemon-DL0eglMJ.mjs +18 -0
- package/dist/daemon-mcp/index.mjs +15 -10
- package/dist/daemon-mcp/index.mjs.map +1 -1
- package/dist/{embeddings-CcscYWwk.mjs → embeddings-CEBGrzwu.mjs} +1 -1
- package/dist/{embeddings-Bx3q0QOY.mjs → embeddings-DOLZnT1X.mjs} +1 -1
- package/dist/{embeddings-Bx3q0QOY.mjs.map → embeddings-DOLZnT1X.mjs.map} +1 -1
- package/dist/{env-JNEIrQWg.mjs → env-DiolswKQ.mjs} +1 -1
- package/dist/{env-JNEIrQWg.mjs.map → env-DiolswKQ.mjs.map} +1 -1
- package/dist/factory-DrBg24UT.mjs +8 -0
- package/dist/factory-Ypf8r0fK.mjs +2892 -0
- package/dist/factory-Ypf8r0fK.mjs.map +1 -0
- package/dist/{fallback-B5svk75f.mjs → fallback-D51R4shY.mjs} +27 -13
- package/dist/fallback-D51R4shY.mjs.map +1 -0
- package/dist/{chunker-BH4i-F2b.mjs → helpers-CZsi_49C.mjs} +221 -2
- package/dist/helpers-CZsi_49C.mjs.map +1 -0
- package/dist/hooks/block-sleep-poll.mjs.map +2 -2
- package/dist/hooks/load-project-context.mjs.map +2 -2
- package/dist/hooks/worker-guard.mjs +5 -0
- package/dist/hooks/worker-guard.mjs.map +2 -2
- package/dist/hooks/worker-status-line.mjs +1 -0
- package/dist/hooks/worker-status-line.mjs.map +2 -2
- package/dist/index.mjs +6 -7
- package/dist/{ipc-client-D16Xw6Uo.mjs → ipc-client-BLYX51nG.mjs} +2 -2
- package/dist/{ipc-client-D16Xw6Uo.mjs.map → ipc-client-BLYX51nG.mjs.map} +1 -1
- package/dist/main-resolver-BYgP86C1.mjs +7 -0
- package/dist/{main-resolver-DPPwHNtn.mjs → main-resolver-kVkMJZUD.mjs} +6 -6
- package/dist/{main-resolver-DPPwHNtn.mjs.map → main-resolver-kVkMJZUD.mjs.map} +1 -1
- package/dist/{migrate-BD7D8EEh.mjs → migrate-Bq0esMOa.mjs} +2 -2
- package/dist/{migrate-BD7D8EEh.mjs.map → migrate-Bq0esMOa.mjs.map} +1 -1
- package/dist/{pai-marker-D1MMswkz.mjs → pai-marker-DXVpFsYz.mjs} +1 -1
- package/dist/{pai-marker-D1MMswkz.mjs.map → pai-marker-DXVpFsYz.mjs.map} +1 -1
- package/dist/{planner-EJPZnnif.mjs → planner-D5yt0EfA.mjs} +10 -7
- package/dist/{planner-EJPZnnif.mjs.map → planner-D5yt0EfA.mjs.map} +1 -1
- package/dist/postgres-BmLr0MUm.mjs +5 -0
- package/dist/{postgres-Ceqsa64C.mjs → postgres-D3xc2RB4.mjs} +364 -9
- package/dist/postgres-D3xc2RB4.mjs.map +1 -0
- package/dist/{program-DSETzrWg.mjs → program-DIXRtAFy.mjs} +80 -70
- package/dist/program-DIXRtAFy.mjs.map +1 -0
- package/dist/{query-feedback-BIaZTTFO.mjs → query-feedback-B7FYE4JR.mjs} +1 -1
- package/dist/{query-feedback-BIaZTTFO.mjs.map → query-feedback-B7FYE4JR.mjs.map} +1 -1
- package/dist/{reranker-DKv80KO5.mjs → reranker-3lnggwgq.mjs} +1 -1
- package/dist/{reranker-DKv80KO5.mjs.map → reranker-3lnggwgq.mjs.map} +1 -1
- package/dist/{reranker-CFiEzHQu.mjs → reranker-CZ2mP4cf.mjs} +1 -1
- package/dist/router-BK-hFeQ6.mjs +3 -0
- package/dist/{router-a5G7q8_3.mjs → router-BaTbc9VX.mjs} +2 -2
- package/dist/{router-a5G7q8_3.mjs.map → router-BaTbc9VX.mjs.map} +1 -1
- package/dist/{run-Z4akoa8G.mjs → run-CLYTOm0x.mjs} +764 -25
- package/dist/run-CLYTOm0x.mjs.map +1 -0
- package/dist/{run-env-DRcp7A8K.mjs → run-env-Bnmf6bRI.mjs} +2 -2
- package/dist/{run-env-DRcp7A8K.mjs.map → run-env-Bnmf6bRI.mjs.map} +1 -1
- package/dist/{runtime-paths-CHTg3ywb.mjs → runtime-paths-D3FKAm69.mjs} +1 -1
- package/dist/{runtime-paths-CHTg3ywb.mjs.map → runtime-paths-D3FKAm69.mjs.map} +1 -1
- package/dist/{search-BOSphCJ1.mjs → search-CNAGTiJP.mjs} +2 -2
- package/dist/{search-BOSphCJ1.mjs.map → search-CNAGTiJP.mjs.map} +1 -1
- package/dist/{sources-CijVso3n.mjs → sources-CM2g-CLT.mjs} +2 -2
- package/dist/{sources-CijVso3n.mjs.map → sources-CM2g-CLT.mjs.map} +1 -1
- package/dist/{stop-words-BdQuaE9K.mjs → stop-words-DtxaTWU_.mjs} +1 -1
- package/dist/{stop-words-BdQuaE9K.mjs.map → stop-words-DtxaTWU_.mjs.map} +1 -1
- package/dist/{utils-C9HsYDpO.mjs → utils-DddRwMsG.mjs} +2 -2
- package/dist/{utils-C9HsYDpO.mjs.map → utils-DddRwMsG.mjs.map} +1 -1
- package/dist/{zettelkasten-CtGHQWPU.mjs → zettelkasten-BhZMvmoK.mjs} +149 -7
- package/dist/zettelkasten-BhZMvmoK.mjs.map +1 -0
- package/dist/zettelkasten-BwV1pluL.mjs +5 -0
- package/docs/commands/worker.md +2 -0
- package/package.json +1 -1
- package/src/hooks/ts/lib/worker-guard.test.ts +12 -0
- package/src/hooks/ts/lib/worker-guard.ts +9 -0
- package/dist/async-C2Bm_Lal.mjs +0 -300
- package/dist/async-C2Bm_Lal.mjs.map +0 -1
- package/dist/auto-route-o0BOsXn7.mjs.map +0 -1
- package/dist/chunker-BH4i-F2b.mjs.map +0 -1
- package/dist/clusters-BCtD3fbe.mjs +0 -169
- package/dist/clusters-BCtD3fbe.mjs.map +0 -1
- package/dist/context-handover-cache-pkHzmL3c.mjs.map +0 -1
- package/dist/daemon-BEoVgVfJ.mjs +0 -1741
- package/dist/daemon-BEoVgVfJ.mjs.map +0 -1
- package/dist/daemon-DPAYU9hp.mjs +0 -19
- package/dist/detector-BEPFsINR.mjs +0 -3
- package/dist/detector-BRTtAWrM.mjs +0 -65
- package/dist/detector-BRTtAWrM.mjs.map +0 -1
- package/dist/factory-CNpPQQ-5.mjs +0 -249
- package/dist/factory-CNpPQQ-5.mjs.map +0 -1
- package/dist/factory-DY7x73mE.mjs +0 -3
- package/dist/fallback-B5svk75f.mjs.map +0 -1
- package/dist/federation-db-BTyoufBh.mjs +0 -139
- package/dist/federation-db-BTyoufBh.mjs.map +0 -1
- package/dist/federation-db-HfIFc7FG.mjs +0 -3
- package/dist/helpers-BRCJg0G3.mjs +0 -223
- package/dist/helpers-BRCJg0G3.mjs.map +0 -1
- package/dist/indexer-backend-DFF2FrYx.mjs +0 -5
- package/dist/indexer-backend-isSLg6yE.mjs +0 -1
- package/dist/kg-entity-DCOcsVFD.mjs +0 -29
- package/dist/kg-entity-DCOcsVFD.mjs.map +0 -1
- package/dist/latent-ideas-wwAXquGe.mjs +0 -191
- package/dist/latent-ideas-wwAXquGe.mjs.map +0 -1
- package/dist/link-boost-CnI7UVMJ.mjs +0 -34
- package/dist/link-boost-CnI7UVMJ.mjs.map +0 -1
- package/dist/main-resolver-BKz_OuEh.mjs +0 -7
- package/dist/merge-2gqRPFu2.mjs +0 -3
- package/dist/merge-DgU9OgZy.mjs +0 -6
- package/dist/merge-DgU9OgZy.mjs.map +0 -1
- package/dist/module-paths-DdRzbkUI.mjs +0 -44
- package/dist/module-paths-DdRzbkUI.mjs.map +0 -1
- package/dist/neighborhood-2FsmzoxG.mjs +0 -114
- package/dist/neighborhood-2FsmzoxG.mjs.map +0 -1
- package/dist/note-context-De63k8na.mjs +0 -106
- package/dist/note-context-De63k8na.mjs.map +0 -1
- package/dist/postgres-Ceqsa64C.mjs.map +0 -1
- package/dist/program-DSETzrWg.mjs.map +0 -1
- package/dist/query-feedback-B_iigYj-.mjs +0 -3
- package/dist/registry-db-C7voqML9.mjs +0 -213
- package/dist/registry-db-C7voqML9.mjs.map +0 -1
- package/dist/registry-db-JHPhA8vF.mjs +0 -3
- package/dist/registry-postgres-nOfyBSIW.mjs +0 -795
- package/dist/registry-postgres-nOfyBSIW.mjs.map +0 -1
- package/dist/registry-sqlite-DrCW1aRK.mjs +0 -593
- package/dist/registry-sqlite-DrCW1aRK.mjs.map +0 -1
- package/dist/router-CXUGsv85.mjs +0 -3
- package/dist/run-Z4akoa8G.mjs.map +0 -1
- package/dist/search-Bf3Kub3F.mjs +0 -3
- package/dist/server-DgmAHyFK.mjs +0 -403
- package/dist/server-DgmAHyFK.mjs.map +0 -1
- package/dist/session-keepalive-BDhytXEo.mjs +0 -582
- package/dist/session-keepalive-BDhytXEo.mjs.map +0 -1
- package/dist/sqlite-CqsTy6xo.mjs +0 -936
- package/dist/sqlite-CqsTy6xo.mjs.map +0 -1
- package/dist/state-DW8zdweW.mjs +0 -3
- package/dist/state-HyjqTihC.mjs +0 -76
- package/dist/state-HyjqTihC.mjs.map +0 -1
- package/dist/themes-CTaOj3e1.mjs +0 -148
- package/dist/themes-CTaOj3e1.mjs.map +0 -1
- package/dist/tools-BcOKPBtg.mjs +0 -1489
- package/dist/tools-BcOKPBtg.mjs.map +0 -1
- package/dist/tools-C-_l0o8Z.mjs +0 -6
- package/dist/trace-CtV0RO6n.mjs +0 -137
- package/dist/trace-CtV0RO6n.mjs.map +0 -1
- package/dist/utils-BrX9FLeK.mjs +0 -3
- package/dist/vault-indexer-BG1sEVyM.mjs +0 -537
- package/dist/vault-indexer-BG1sEVyM.mjs.map +0 -1
- package/dist/wakeup-D8n33hYV.mjs +0 -335
- package/dist/wakeup-D8n33hYV.mjs.map +0 -1
- package/dist/work-queue-worker-4tLa5gpQ.mjs +0 -567
- package/dist/work-queue-worker-4tLa5gpQ.mjs.map +0 -1
- package/dist/work-queue-worker-rFZvTO3p.mjs +0 -11
- package/dist/zettelkasten-CtGHQWPU.mjs.map +0 -1
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import { a as paiHomePath, o as resolvePaiFile } from "./pai-home-Cm9rcJgX.mjs";
|
|
2
|
-
import { mkdirSync } from "node:fs";
|
|
3
|
-
import { homedir } from "node:os";
|
|
4
|
-
import { dirname, join } from "node:path";
|
|
5
|
-
import BetterSqlite3 from "better-sqlite3";
|
|
6
|
-
|
|
7
|
-
//#region src/storage/sqlite/registry-schema.ts
|
|
8
|
-
const SCHEMA_VERSION = 4;
|
|
9
|
-
const CREATE_TABLES_SQL = `
|
|
10
|
-
PRAGMA journal_mode = WAL;
|
|
11
|
-
PRAGMA foreign_keys = ON;
|
|
12
|
-
|
|
13
|
-
CREATE TABLE IF NOT EXISTS projects (
|
|
14
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
15
|
-
slug TEXT NOT NULL UNIQUE,
|
|
16
|
-
display_name TEXT NOT NULL,
|
|
17
|
-
root_path TEXT NOT NULL UNIQUE,
|
|
18
|
-
encoded_dir TEXT NOT NULL UNIQUE,
|
|
19
|
-
type TEXT NOT NULL DEFAULT 'local'
|
|
20
|
-
CHECK(type IN ('local','central','obsidian-linked','external')),
|
|
21
|
-
status TEXT NOT NULL DEFAULT 'active'
|
|
22
|
-
CHECK(status IN ('active','archived','migrating')),
|
|
23
|
-
parent_id INTEGER,
|
|
24
|
-
obsidian_link TEXT,
|
|
25
|
-
claude_notes_dir TEXT,
|
|
26
|
-
session_config TEXT,
|
|
27
|
-
created_at INTEGER NOT NULL,
|
|
28
|
-
updated_at INTEGER NOT NULL,
|
|
29
|
-
archived_at INTEGER,
|
|
30
|
-
FOREIGN KEY (parent_id) REFERENCES projects(id)
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
CREATE TABLE IF NOT EXISTS sessions (
|
|
34
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
35
|
-
project_id INTEGER NOT NULL,
|
|
36
|
-
number INTEGER NOT NULL,
|
|
37
|
-
date TEXT NOT NULL,
|
|
38
|
-
slug TEXT NOT NULL,
|
|
39
|
-
title TEXT NOT NULL,
|
|
40
|
-
filename TEXT NOT NULL,
|
|
41
|
-
status TEXT NOT NULL DEFAULT 'open'
|
|
42
|
-
CHECK(status IN ('open','completed','compacted')),
|
|
43
|
-
claude_session_id TEXT,
|
|
44
|
-
token_count INTEGER,
|
|
45
|
-
created_at INTEGER NOT NULL,
|
|
46
|
-
closed_at INTEGER,
|
|
47
|
-
UNIQUE (project_id, number),
|
|
48
|
-
FOREIGN KEY (project_id) REFERENCES projects(id)
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
CREATE TABLE IF NOT EXISTS tags (
|
|
52
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
53
|
-
name TEXT NOT NULL UNIQUE
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
CREATE TABLE IF NOT EXISTS project_tags (
|
|
57
|
-
project_id INTEGER NOT NULL,
|
|
58
|
-
tag_id INTEGER NOT NULL,
|
|
59
|
-
PRIMARY KEY (project_id, tag_id),
|
|
60
|
-
FOREIGN KEY (project_id) REFERENCES projects(id),
|
|
61
|
-
FOREIGN KEY (tag_id) REFERENCES tags(id)
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
CREATE TABLE IF NOT EXISTS session_tags (
|
|
65
|
-
session_id INTEGER NOT NULL,
|
|
66
|
-
tag_id INTEGER NOT NULL,
|
|
67
|
-
PRIMARY KEY (session_id, tag_id),
|
|
68
|
-
FOREIGN KEY (session_id) REFERENCES sessions(id),
|
|
69
|
-
FOREIGN KEY (tag_id) REFERENCES tags(id)
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
CREATE TABLE IF NOT EXISTS aliases (
|
|
73
|
-
alias TEXT PRIMARY KEY,
|
|
74
|
-
project_id INTEGER NOT NULL,
|
|
75
|
-
FOREIGN KEY (project_id) REFERENCES projects(id)
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
CREATE TABLE IF NOT EXISTS compaction_log (
|
|
79
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
80
|
-
project_id INTEGER NOT NULL,
|
|
81
|
-
session_id INTEGER,
|
|
82
|
-
trigger TEXT NOT NULL
|
|
83
|
-
CHECK(trigger IN ('precompact','manual','end-session')),
|
|
84
|
-
files_written TEXT NOT NULL,
|
|
85
|
-
token_count INTEGER,
|
|
86
|
-
created_at INTEGER NOT NULL,
|
|
87
|
-
FOREIGN KEY (project_id) REFERENCES projects(id),
|
|
88
|
-
FOREIGN KEY (session_id) REFERENCES sessions(id)
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
CREATE TABLE IF NOT EXISTS links (
|
|
92
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
93
|
-
session_id INTEGER NOT NULL,
|
|
94
|
-
target_project_id INTEGER NOT NULL,
|
|
95
|
-
link_type TEXT NOT NULL DEFAULT 'related'
|
|
96
|
-
CHECK(link_type IN ('related','follow-up','reference')),
|
|
97
|
-
created_at INTEGER NOT NULL,
|
|
98
|
-
UNIQUE (session_id, target_project_id),
|
|
99
|
-
FOREIGN KEY (session_id) REFERENCES sessions(id),
|
|
100
|
-
FOREIGN KEY (target_project_id) REFERENCES projects(id)
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
CREATE TABLE IF NOT EXISTS schema_version (
|
|
104
|
-
version INTEGER PRIMARY KEY,
|
|
105
|
-
applied_at INTEGER NOT NULL
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
-- Indexes
|
|
109
|
-
CREATE INDEX IF NOT EXISTS idx_projects_slug ON projects(slug);
|
|
110
|
-
CREATE INDEX IF NOT EXISTS idx_projects_status ON projects(status);
|
|
111
|
-
CREATE INDEX IF NOT EXISTS idx_projects_type ON projects(type);
|
|
112
|
-
CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_id);
|
|
113
|
-
CREATE INDEX IF NOT EXISTS idx_sessions_date ON sessions(date);
|
|
114
|
-
CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
|
|
115
|
-
CREATE INDEX IF NOT EXISTS idx_sessions_claude ON sessions(claude_session_id);
|
|
116
|
-
CREATE INDEX IF NOT EXISTS idx_pc_project ON project_tags(project_id);
|
|
117
|
-
`;
|
|
118
|
-
/**
|
|
119
|
-
* Run the full DDL against an open database connection.
|
|
120
|
-
*
|
|
121
|
-
* The function is idempotent — every statement uses IF NOT EXISTS so it is
|
|
122
|
-
* safe to call on an already-initialised database. After creating the tables
|
|
123
|
-
* it inserts the current SCHEMA_VERSION into schema_version if no row exists
|
|
124
|
-
* yet.
|
|
125
|
-
*/
|
|
126
|
-
function initializeSchema(db) {
|
|
127
|
-
db.exec(CREATE_TABLES_SQL);
|
|
128
|
-
if (!db.prepare("SELECT version FROM schema_version WHERE version = ?").get(SCHEMA_VERSION)) db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (?, ?)").run(SCHEMA_VERSION, Date.now());
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Apply incremental schema migrations to an already-initialised database.
|
|
132
|
-
*
|
|
133
|
-
* Each migration is guarded by a version check so it is safe to call on
|
|
134
|
-
* databases at any schema version — already-applied migrations are skipped.
|
|
135
|
-
*/
|
|
136
|
-
function runMigrations(db) {
|
|
137
|
-
const current = db.prepare("SELECT version FROM schema_version ORDER BY version DESC LIMIT 1").get()?.version ?? 0;
|
|
138
|
-
if (current < 2) db.transaction(() => {
|
|
139
|
-
try {
|
|
140
|
-
db.exec("ALTER TABLE projects ADD COLUMN claude_notes_dir TEXT");
|
|
141
|
-
} catch {}
|
|
142
|
-
db.prepare("INSERT OR REPLACE INTO schema_version (version, applied_at) VALUES (?, ?)").run(2, Date.now());
|
|
143
|
-
})();
|
|
144
|
-
if (current < 3) db.transaction(() => {
|
|
145
|
-
try {
|
|
146
|
-
db.exec(`
|
|
147
|
-
CREATE TABLE IF NOT EXISTS links (
|
|
148
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
149
|
-
session_id INTEGER NOT NULL,
|
|
150
|
-
target_project_id INTEGER NOT NULL,
|
|
151
|
-
link_type TEXT NOT NULL DEFAULT 'related'
|
|
152
|
-
CHECK(link_type IN ('related','follow-up','reference')),
|
|
153
|
-
created_at INTEGER NOT NULL,
|
|
154
|
-
UNIQUE (session_id, target_project_id),
|
|
155
|
-
FOREIGN KEY (session_id) REFERENCES sessions(id),
|
|
156
|
-
FOREIGN KEY (target_project_id) REFERENCES projects(id)
|
|
157
|
-
)
|
|
158
|
-
`);
|
|
159
|
-
} catch {}
|
|
160
|
-
db.prepare("INSERT OR REPLACE INTO schema_version (version, applied_at) VALUES (?, ?)").run(3, Date.now());
|
|
161
|
-
})();
|
|
162
|
-
if (current < 4) db.transaction(() => {
|
|
163
|
-
try {
|
|
164
|
-
db.exec("ALTER TABLE projects ADD COLUMN session_config TEXT");
|
|
165
|
-
} catch {}
|
|
166
|
-
db.prepare("INSERT OR REPLACE INTO schema_version (version, applied_at) VALUES (?, ?)").run(4, Date.now());
|
|
167
|
-
})();
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
//#endregion
|
|
171
|
-
//#region src/storage/sqlite/registry-db.ts
|
|
172
|
-
/**
|
|
173
|
-
* Database connection helper for the PAI registry.
|
|
174
|
-
*
|
|
175
|
-
* Uses better-sqlite3 (synchronous API) to open or create registry.db.
|
|
176
|
-
* On first open it runs the full DDL via initializeSchema().
|
|
177
|
-
*/
|
|
178
|
-
/** Old registry path, inside the ~/.pai/ directory (pre-2026-09-19). */
|
|
179
|
-
function oldRegistryPath() {
|
|
180
|
-
return join(homedir(), ".pai", "registry.db");
|
|
181
|
-
}
|
|
182
|
-
/** Registry path: PAI_HOME/registry.db if present, else the old
|
|
183
|
-
* ~/.pai/registry.db (one-time stderr notice), else the new path. */
|
|
184
|
-
function registryDbPath() {
|
|
185
|
-
return resolvePaiFile(paiHomePath("registry.db"), [oldRegistryPath()], "pai config migrate --registry");
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Open (or create) the PAI registry database.
|
|
189
|
-
*
|
|
190
|
-
* @param path Absolute path to registry.db. Defaults to PAI_HOME/registry.db
|
|
191
|
-
* (falling back to the pre-2026-09-19 ~/.pai/registry.db).
|
|
192
|
-
* @returns An open better-sqlite3 Database instance.
|
|
193
|
-
*
|
|
194
|
-
* Side effects on first call:
|
|
195
|
-
* - Creates the parent directory if it does not exist.
|
|
196
|
-
* - Enables WAL journal mode.
|
|
197
|
-
* - Runs initializeSchema() if schema_version is empty.
|
|
198
|
-
*/
|
|
199
|
-
function openRegistry(path = registryDbPath()) {
|
|
200
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
201
|
-
const db = new BetterSqlite3(path);
|
|
202
|
-
db.pragma("journal_mode = WAL");
|
|
203
|
-
db.pragma("foreign_keys = ON");
|
|
204
|
-
if (!db.prepare(`SELECT name FROM sqlite_master
|
|
205
|
-
WHERE type = 'table' AND name = 'schema_version'`).get()) initializeSchema(db);
|
|
206
|
-
else if (!db.prepare("SELECT version FROM schema_version LIMIT 1").get()) initializeSchema(db);
|
|
207
|
-
runMigrations(db);
|
|
208
|
-
return db;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
//#endregion
|
|
212
|
-
export { openRegistry as n, registryDbPath as r, oldRegistryPath as t };
|
|
213
|
-
//# sourceMappingURL=registry-db-C7voqML9.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"registry-db-C7voqML9.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"}
|