@tekmidian/pai 0.5.6 → 0.6.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/ARCHITECTURE.md +72 -1
- package/README.md +107 -3
- package/dist/{auto-route-BG6I_4B1.mjs → auto-route-C-DrW6BL.mjs} +3 -3
- package/dist/{auto-route-BG6I_4B1.mjs.map → auto-route-C-DrW6BL.mjs.map} +1 -1
- package/dist/cli/index.mjs +1897 -1569
- package/dist/cli/index.mjs.map +1 -1
- package/dist/clusters-JIDQW65f.mjs +201 -0
- package/dist/clusters-JIDQW65f.mjs.map +1 -0
- package/dist/{config-Cf92lGX_.mjs → config-BuhHWyOK.mjs} +21 -6
- package/dist/config-BuhHWyOK.mjs.map +1 -0
- package/dist/daemon/index.mjs +12 -9
- package/dist/daemon/index.mjs.map +1 -1
- package/dist/{daemon-D9evGlgR.mjs → daemon-D3hYb5_C.mjs} +670 -219
- package/dist/daemon-D3hYb5_C.mjs.map +1 -0
- package/dist/daemon-mcp/index.mjs +4597 -4
- package/dist/daemon-mcp/index.mjs.map +1 -1
- package/dist/{db-4lSqLFb8.mjs → db-BtuN768f.mjs} +9 -2
- package/dist/db-BtuN768f.mjs.map +1 -0
- package/dist/db-DdUperSl.mjs +110 -0
- package/dist/db-DdUperSl.mjs.map +1 -0
- package/dist/{detect-BU3Nx_2L.mjs → detect-CdaA48EI.mjs} +1 -1
- package/dist/{detect-BU3Nx_2L.mjs.map → detect-CdaA48EI.mjs.map} +1 -1
- package/dist/{detector-Bp-2SM3x.mjs → detector-jGBuYQJM.mjs} +2 -2
- package/dist/{detector-Bp-2SM3x.mjs.map → detector-jGBuYQJM.mjs.map} +1 -1
- package/dist/{factory-Bzcy70G9.mjs → factory-Ygqe_bVZ.mjs} +7 -5
- package/dist/{factory-Bzcy70G9.mjs.map → factory-Ygqe_bVZ.mjs.map} +1 -1
- package/dist/helpers-BEST-4Gx.mjs +420 -0
- package/dist/helpers-BEST-4Gx.mjs.map +1 -0
- package/dist/hooks/capture-all-events.mjs +19 -4
- package/dist/hooks/capture-all-events.mjs.map +4 -4
- package/dist/hooks/capture-session-summary.mjs +38 -0
- package/dist/hooks/capture-session-summary.mjs.map +3 -3
- package/dist/hooks/cleanup-session-files.mjs +6 -12
- package/dist/hooks/cleanup-session-files.mjs.map +4 -4
- package/dist/hooks/context-compression-hook.mjs +105 -111
- package/dist/hooks/context-compression-hook.mjs.map +4 -4
- package/dist/hooks/initialize-session.mjs +26 -17
- package/dist/hooks/initialize-session.mjs.map +4 -4
- package/dist/hooks/inject-observations.mjs +220 -0
- package/dist/hooks/inject-observations.mjs.map +7 -0
- package/dist/hooks/load-core-context.mjs +18 -2
- package/dist/hooks/load-core-context.mjs.map +4 -4
- package/dist/hooks/load-project-context.mjs +102 -97
- package/dist/hooks/load-project-context.mjs.map +4 -4
- package/dist/hooks/observe.mjs +354 -0
- package/dist/hooks/observe.mjs.map +7 -0
- package/dist/hooks/stop-hook.mjs +174 -90
- package/dist/hooks/stop-hook.mjs.map +4 -4
- package/dist/hooks/sync-todo-to-md.mjs +31 -33
- package/dist/hooks/sync-todo-to-md.mjs.map +4 -4
- package/dist/index.d.mts +32 -9
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +6 -9
- package/dist/indexer-D53l5d1U.mjs +1 -0
- package/dist/{indexer-backend-CIMXedqk.mjs → indexer-backend-jcJFsmB4.mjs} +37 -127
- package/dist/indexer-backend-jcJFsmB4.mjs.map +1 -0
- package/dist/{ipc-client-Bjg_a1dc.mjs → ipc-client-CoyUHPod.mjs} +2 -7
- package/dist/{ipc-client-Bjg_a1dc.mjs.map → ipc-client-CoyUHPod.mjs.map} +1 -1
- package/dist/latent-ideas-bTJo6Omd.mjs +191 -0
- package/dist/latent-ideas-bTJo6Omd.mjs.map +1 -0
- package/dist/neighborhood-BYYbEkUJ.mjs +135 -0
- package/dist/neighborhood-BYYbEkUJ.mjs.map +1 -0
- package/dist/note-context-BK24bX8Y.mjs +126 -0
- package/dist/note-context-BK24bX8Y.mjs.map +1 -0
- package/dist/postgres-CKf-EDtS.mjs +846 -0
- package/dist/postgres-CKf-EDtS.mjs.map +1 -0
- package/dist/{reranker-D7bRAHi6.mjs → reranker-CMNZcfVx.mjs} +1 -1
- package/dist/{reranker-D7bRAHi6.mjs.map → reranker-CMNZcfVx.mjs.map} +1 -1
- package/dist/{search-_oHfguA5.mjs → search-DC1qhkKn.mjs} +2 -58
- package/dist/search-DC1qhkKn.mjs.map +1 -0
- package/dist/{sqlite-WWBq7_2C.mjs → sqlite-l-s9xPjY.mjs} +160 -3
- package/dist/sqlite-l-s9xPjY.mjs.map +1 -0
- package/dist/state-C6_vqz7w.mjs +102 -0
- package/dist/state-C6_vqz7w.mjs.map +1 -0
- package/dist/stop-words-BaMEGVeY.mjs +326 -0
- package/dist/stop-words-BaMEGVeY.mjs.map +1 -0
- package/dist/{indexer-CMPOiY1r.mjs → sync-BOsnEj2-.mjs} +14 -216
- package/dist/sync-BOsnEj2-.mjs.map +1 -0
- package/dist/themes-BvYF0W8T.mjs +148 -0
- package/dist/themes-BvYF0W8T.mjs.map +1 -0
- package/dist/{tools-DV_lsiCc.mjs → tools-DcaJlYDN.mjs} +162 -273
- package/dist/tools-DcaJlYDN.mjs.map +1 -0
- package/dist/trace-CRx9lPuc.mjs +137 -0
- package/dist/trace-CRx9lPuc.mjs.map +1 -0
- package/dist/{vault-indexer-DXWs9pDn.mjs → vault-indexer-Bi2cRmn7.mjs} +174 -138
- package/dist/vault-indexer-Bi2cRmn7.mjs.map +1 -0
- package/dist/zettelkasten-cdajbnPr.mjs +708 -0
- package/dist/zettelkasten-cdajbnPr.mjs.map +1 -0
- package/package.json +1 -2
- package/src/hooks/ts/capture-all-events.ts +6 -0
- package/src/hooks/ts/lib/project-utils/index.ts +50 -0
- package/src/hooks/ts/lib/project-utils/notify.ts +75 -0
- package/src/hooks/ts/lib/project-utils/paths.ts +218 -0
- package/src/hooks/ts/lib/project-utils/session-notes.ts +363 -0
- package/src/hooks/ts/lib/project-utils/todo.ts +178 -0
- package/src/hooks/ts/lib/project-utils/tokens.ts +39 -0
- package/src/hooks/ts/lib/project-utils.ts +40 -999
- package/src/hooks/ts/post-tool-use/observe.ts +327 -0
- package/src/hooks/ts/pre-compact/context-compression-hook.ts +6 -0
- package/src/hooks/ts/session-end/capture-session-summary.ts +41 -0
- package/src/hooks/ts/session-start/initialize-session.ts +7 -1
- package/src/hooks/ts/session-start/inject-observations.ts +254 -0
- package/src/hooks/ts/session-start/load-core-context.ts +7 -0
- package/src/hooks/ts/session-start/load-project-context.ts +8 -1
- package/src/hooks/ts/stop/stop-hook.ts +28 -0
- package/templates/claude-md.template.md +7 -74
- package/templates/skills/user/.gitkeep +0 -0
- package/dist/chunker-CbnBe0s0.mjs +0 -191
- package/dist/chunker-CbnBe0s0.mjs.map +0 -1
- package/dist/config-Cf92lGX_.mjs.map +0 -1
- package/dist/daemon-D9evGlgR.mjs.map +0 -1
- package/dist/db-4lSqLFb8.mjs.map +0 -1
- package/dist/db-Dp8VXIMR.mjs +0 -212
- package/dist/db-Dp8VXIMR.mjs.map +0 -1
- package/dist/indexer-CMPOiY1r.mjs.map +0 -1
- package/dist/indexer-backend-CIMXedqk.mjs.map +0 -1
- package/dist/mcp/index.d.mts +0 -1
- package/dist/mcp/index.mjs +0 -500
- package/dist/mcp/index.mjs.map +0 -1
- package/dist/postgres-FXrHDPcE.mjs +0 -358
- package/dist/postgres-FXrHDPcE.mjs.map +0 -1
- package/dist/schemas-BFIgGntb.mjs +0 -3405
- package/dist/schemas-BFIgGntb.mjs.map +0 -1
- package/dist/search-_oHfguA5.mjs.map +0 -1
- package/dist/sqlite-WWBq7_2C.mjs.map +0 -1
- package/dist/tools-DV_lsiCc.mjs.map +0 -1
- package/dist/vault-indexer-DXWs9pDn.mjs.map +0 -1
- package/dist/zettelkasten-e-a4rW_6.mjs +0 -901
- package/dist/zettelkasten-e-a4rW_6.mjs.map +0 -1
- package/templates/README.md +0 -181
- package/templates/skills/createskill-skill.template.md +0 -78
- package/templates/skills/history-system.template.md +0 -371
- package/templates/skills/hook-system.template.md +0 -913
- package/templates/skills/sessions-skill.template.md +0 -102
- package/templates/skills/skill-system.template.md +0 -214
- package/templates/skills/terminal-tabs.template.md +0 -120
- package/templates/templates.md +0 -20
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-C6_vqz7w.mjs","names":[],"sources":["../src/daemon/daemon/state.ts"],"sourcesContent":["/**\n * Shared mutable daemon state — module-level singletons used across all daemon sub-modules.\n */\n\nimport { openRegistry } from \"../../registry/db.js\";\nimport type { StorageBackend } from \"../../storage/interface.js\";\nimport type { NotificationConfig } from \"../../notifications/types.js\";\nimport type { PaiDaemonConfig } from \"../config.js\";\n\n// ---------------------------------------------------------------------------\n// Core singletons (assigned at startup by serve())\n// ---------------------------------------------------------------------------\n\nexport let registryDb: ReturnType<typeof openRegistry>;\nexport let storageBackend: StorageBackend;\nexport let daemonConfig: PaiDaemonConfig;\nexport let startTime = Date.now();\n\n// ---------------------------------------------------------------------------\n// Scheduler state\n// ---------------------------------------------------------------------------\n\n/** True while a project index pass is running. */\nexport let indexInProgress = false;\nexport let lastIndexTime = 0;\nexport let indexSchedulerTimer: ReturnType<typeof setInterval> | null = null;\n\n/** True while an embedding pass is running. */\nexport let embedInProgress = false;\nexport let lastEmbedTime = 0;\nexport let embedSchedulerTimer: ReturnType<typeof setInterval> | null = null;\n\n/** True while a vault index pass is running. */\nexport let vaultIndexInProgress = false;\nexport let lastVaultIndexTime = 0;\n\n// ---------------------------------------------------------------------------\n// Notification state\n// ---------------------------------------------------------------------------\n\n/** Mutable notification config — loaded from disk at startup, patchable at runtime. */\nexport let notificationConfig: NotificationConfig;\n\n// ---------------------------------------------------------------------------\n// Graceful shutdown flag\n// ---------------------------------------------------------------------------\n\n/**\n * Set to true when a SIGTERM/SIGINT is received so that long-running loops\n * (embed, index) can detect the signal and exit their inner loops before the\n * pool/backend is closed.\n */\nexport let shutdownRequested = false;\n\n// ---------------------------------------------------------------------------\n// Setters (TypeScript requires assignment functions for exported `let` vars\n// that need to be mutated across module boundaries)\n// ---------------------------------------------------------------------------\n\nexport function setRegistryDb(db: ReturnType<typeof openRegistry>): void { registryDb = db; }\nexport function setStorageBackend(b: StorageBackend): void { storageBackend = b; }\nexport function setDaemonConfig(c: PaiDaemonConfig): void { daemonConfig = c; }\nexport function setStartTime(t: number): void { startTime = t; }\nexport function setNotificationConfig(c: NotificationConfig): void { notificationConfig = c; }\nexport function setShutdownRequested(v: boolean): void { shutdownRequested = v; }\nexport function setIndexInProgress(v: boolean): void { indexInProgress = v; }\nexport function setLastIndexTime(v: number): void { lastIndexTime = v; }\nexport function setIndexSchedulerTimer(v: ReturnType<typeof setInterval> | null): void { indexSchedulerTimer = v; }\nexport function setEmbedInProgress(v: boolean): void { embedInProgress = v; }\nexport function setLastEmbedTime(v: number): void { lastEmbedTime = v; }\nexport function setEmbedSchedulerTimer(v: ReturnType<typeof setInterval> | null): void { embedSchedulerTimer = v; }\nexport function setVaultIndexInProgress(v: boolean): void { vaultIndexInProgress = v; }\nexport function setLastVaultIndexTime(v: number): void { lastVaultIndexTime = v; }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,IAAW;AACX,IAAW;AACX,IAAW;AACX,IAAW,YAAY,KAAK,KAAK;;AAOjC,IAAW,kBAAkB;AAC7B,IAAW,gBAAgB;AAC3B,IAAW,sBAA6D;;AAGxE,IAAW,kBAAkB;AAC7B,IAAW,gBAAgB;AAC3B,IAAW,sBAA6D;;AAGxE,IAAW,uBAAuB;AAClC,IAAW,qBAAqB;;AAOhC,IAAW;;;;;;AAWX,IAAW,oBAAoB;AAO/B,SAAgB,cAAc,IAA2C;AAAE,cAAa;;AACxF,SAAgB,kBAAkB,GAAyB;AAAE,kBAAiB;;AAC9E,SAAgB,gBAAgB,GAA0B;AAAE,gBAAe;;AAC3E,SAAgB,aAAa,GAAiB;AAAE,aAAY;;AAC5D,SAAgB,sBAAsB,GAA6B;AAAE,sBAAqB;;AAC1F,SAAgB,qBAAqB,GAAkB;AAAE,qBAAoB;;AAC7E,SAAgB,mBAAmB,GAAkB;AAAE,mBAAkB;;AACzE,SAAgB,iBAAiB,GAAiB;AAAE,iBAAgB;;AACpE,SAAgB,uBAAuB,GAAgD;AAAE,uBAAsB;;AAC/G,SAAgB,mBAAmB,GAAkB;AAAE,mBAAkB;;AACzE,SAAgB,iBAAiB,GAAiB;AAAE,iBAAgB;;AACpE,SAAgB,uBAAuB,GAAgD;AAAE,uBAAsB;;AAC/G,SAAgB,wBAAwB,GAAkB;AAAE,wBAAuB;;AACnF,SAAgB,sBAAsB,GAAiB;AAAE,sBAAqB"}
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
//#region src/utils/stop-words.ts
|
|
2
|
+
/**
|
|
3
|
+
* Shared stop-word list used across memory search, slug generation, graph clustering,
|
|
4
|
+
* and zettelkasten modules. This is the union of all per-file sets that previously
|
|
5
|
+
* existed in 7 different files.
|
|
6
|
+
*/
|
|
7
|
+
const STOP_WORDS = new Set([
|
|
8
|
+
"a",
|
|
9
|
+
"an",
|
|
10
|
+
"the",
|
|
11
|
+
"and",
|
|
12
|
+
"or",
|
|
13
|
+
"but",
|
|
14
|
+
"if",
|
|
15
|
+
"then",
|
|
16
|
+
"else",
|
|
17
|
+
"so",
|
|
18
|
+
"because",
|
|
19
|
+
"as",
|
|
20
|
+
"although",
|
|
21
|
+
"however",
|
|
22
|
+
"therefore",
|
|
23
|
+
"thus",
|
|
24
|
+
"hence",
|
|
25
|
+
"meanwhile",
|
|
26
|
+
"moreover",
|
|
27
|
+
"furthermore",
|
|
28
|
+
"otherwise",
|
|
29
|
+
"instead",
|
|
30
|
+
"anyway",
|
|
31
|
+
"at",
|
|
32
|
+
"to",
|
|
33
|
+
"for",
|
|
34
|
+
"of",
|
|
35
|
+
"with",
|
|
36
|
+
"by",
|
|
37
|
+
"from",
|
|
38
|
+
"in",
|
|
39
|
+
"on",
|
|
40
|
+
"out",
|
|
41
|
+
"off",
|
|
42
|
+
"over",
|
|
43
|
+
"under",
|
|
44
|
+
"up",
|
|
45
|
+
"into",
|
|
46
|
+
"without",
|
|
47
|
+
"per",
|
|
48
|
+
"via",
|
|
49
|
+
"i",
|
|
50
|
+
"you",
|
|
51
|
+
"we",
|
|
52
|
+
"they",
|
|
53
|
+
"he",
|
|
54
|
+
"she",
|
|
55
|
+
"it",
|
|
56
|
+
"me",
|
|
57
|
+
"us",
|
|
58
|
+
"him",
|
|
59
|
+
"her",
|
|
60
|
+
"my",
|
|
61
|
+
"your",
|
|
62
|
+
"our",
|
|
63
|
+
"their",
|
|
64
|
+
"his",
|
|
65
|
+
"its",
|
|
66
|
+
"who",
|
|
67
|
+
"whom",
|
|
68
|
+
"what",
|
|
69
|
+
"which",
|
|
70
|
+
"this",
|
|
71
|
+
"that",
|
|
72
|
+
"these",
|
|
73
|
+
"those",
|
|
74
|
+
"is",
|
|
75
|
+
"are",
|
|
76
|
+
"was",
|
|
77
|
+
"were",
|
|
78
|
+
"be",
|
|
79
|
+
"been",
|
|
80
|
+
"being",
|
|
81
|
+
"have",
|
|
82
|
+
"has",
|
|
83
|
+
"had",
|
|
84
|
+
"do",
|
|
85
|
+
"does",
|
|
86
|
+
"did",
|
|
87
|
+
"will",
|
|
88
|
+
"would",
|
|
89
|
+
"could",
|
|
90
|
+
"should",
|
|
91
|
+
"may",
|
|
92
|
+
"might",
|
|
93
|
+
"can",
|
|
94
|
+
"shall",
|
|
95
|
+
"want",
|
|
96
|
+
"need",
|
|
97
|
+
"know",
|
|
98
|
+
"think",
|
|
99
|
+
"see",
|
|
100
|
+
"look",
|
|
101
|
+
"make",
|
|
102
|
+
"get",
|
|
103
|
+
"go",
|
|
104
|
+
"come",
|
|
105
|
+
"take",
|
|
106
|
+
"use",
|
|
107
|
+
"find",
|
|
108
|
+
"give",
|
|
109
|
+
"tell",
|
|
110
|
+
"say",
|
|
111
|
+
"said",
|
|
112
|
+
"try",
|
|
113
|
+
"keep",
|
|
114
|
+
"run",
|
|
115
|
+
"set",
|
|
116
|
+
"put",
|
|
117
|
+
"add",
|
|
118
|
+
"show",
|
|
119
|
+
"check",
|
|
120
|
+
"let",
|
|
121
|
+
"not",
|
|
122
|
+
"no",
|
|
123
|
+
"yes",
|
|
124
|
+
"just",
|
|
125
|
+
"also",
|
|
126
|
+
"very",
|
|
127
|
+
"really",
|
|
128
|
+
"about",
|
|
129
|
+
"after",
|
|
130
|
+
"before",
|
|
131
|
+
"more",
|
|
132
|
+
"most",
|
|
133
|
+
"some",
|
|
134
|
+
"any",
|
|
135
|
+
"all",
|
|
136
|
+
"each",
|
|
137
|
+
"every",
|
|
138
|
+
"both",
|
|
139
|
+
"few",
|
|
140
|
+
"many",
|
|
141
|
+
"much",
|
|
142
|
+
"other",
|
|
143
|
+
"another",
|
|
144
|
+
"such",
|
|
145
|
+
"only",
|
|
146
|
+
"own",
|
|
147
|
+
"same",
|
|
148
|
+
"than",
|
|
149
|
+
"too",
|
|
150
|
+
"ok",
|
|
151
|
+
"okay",
|
|
152
|
+
"sure",
|
|
153
|
+
"please",
|
|
154
|
+
"thanks",
|
|
155
|
+
"thank",
|
|
156
|
+
"here",
|
|
157
|
+
"there",
|
|
158
|
+
"now",
|
|
159
|
+
"well",
|
|
160
|
+
"like",
|
|
161
|
+
"going",
|
|
162
|
+
"done",
|
|
163
|
+
"got",
|
|
164
|
+
"https",
|
|
165
|
+
"http",
|
|
166
|
+
"www",
|
|
167
|
+
"com",
|
|
168
|
+
"org",
|
|
169
|
+
"net",
|
|
170
|
+
"io",
|
|
171
|
+
"null",
|
|
172
|
+
"undefined",
|
|
173
|
+
"true",
|
|
174
|
+
"false",
|
|
175
|
+
"ll",
|
|
176
|
+
"ve",
|
|
177
|
+
"re",
|
|
178
|
+
"don",
|
|
179
|
+
"thats",
|
|
180
|
+
"heres",
|
|
181
|
+
"theres",
|
|
182
|
+
"youre",
|
|
183
|
+
"theyre",
|
|
184
|
+
"didnt",
|
|
185
|
+
"dont",
|
|
186
|
+
"doesnt",
|
|
187
|
+
"havent",
|
|
188
|
+
"hasnt",
|
|
189
|
+
"wont",
|
|
190
|
+
"cant",
|
|
191
|
+
"shouldnt",
|
|
192
|
+
"wouldnt",
|
|
193
|
+
"couldnt",
|
|
194
|
+
"isnt",
|
|
195
|
+
"arent",
|
|
196
|
+
"wasnt",
|
|
197
|
+
"werent",
|
|
198
|
+
"never",
|
|
199
|
+
"ever",
|
|
200
|
+
"still",
|
|
201
|
+
"already",
|
|
202
|
+
"yet",
|
|
203
|
+
"back",
|
|
204
|
+
"away",
|
|
205
|
+
"down",
|
|
206
|
+
"right",
|
|
207
|
+
"left",
|
|
208
|
+
"next",
|
|
209
|
+
"last",
|
|
210
|
+
"first",
|
|
211
|
+
"second",
|
|
212
|
+
"third",
|
|
213
|
+
"then",
|
|
214
|
+
"again",
|
|
215
|
+
"once",
|
|
216
|
+
"twice",
|
|
217
|
+
"since",
|
|
218
|
+
"while",
|
|
219
|
+
"though",
|
|
220
|
+
"actually",
|
|
221
|
+
"basically",
|
|
222
|
+
"literally",
|
|
223
|
+
"simply",
|
|
224
|
+
"exactly",
|
|
225
|
+
"probably",
|
|
226
|
+
"possibly",
|
|
227
|
+
"maybe",
|
|
228
|
+
"perhaps",
|
|
229
|
+
"certainly",
|
|
230
|
+
"definitely",
|
|
231
|
+
"absolutely",
|
|
232
|
+
"completely",
|
|
233
|
+
"totally",
|
|
234
|
+
"quite",
|
|
235
|
+
"rather",
|
|
236
|
+
"fairly",
|
|
237
|
+
"nearly",
|
|
238
|
+
"almost",
|
|
239
|
+
"barely",
|
|
240
|
+
"hardly",
|
|
241
|
+
"quickly",
|
|
242
|
+
"slowly",
|
|
243
|
+
"easily",
|
|
244
|
+
"likely",
|
|
245
|
+
"unlikely",
|
|
246
|
+
"one",
|
|
247
|
+
"two",
|
|
248
|
+
"three",
|
|
249
|
+
"four",
|
|
250
|
+
"five",
|
|
251
|
+
"six",
|
|
252
|
+
"seven",
|
|
253
|
+
"eight",
|
|
254
|
+
"nine",
|
|
255
|
+
"ten",
|
|
256
|
+
"time",
|
|
257
|
+
"way",
|
|
258
|
+
"thing",
|
|
259
|
+
"something",
|
|
260
|
+
"anything",
|
|
261
|
+
"nothing",
|
|
262
|
+
"everything",
|
|
263
|
+
"someone",
|
|
264
|
+
"anyone",
|
|
265
|
+
"everyone",
|
|
266
|
+
"new",
|
|
267
|
+
"note",
|
|
268
|
+
"untitled",
|
|
269
|
+
"page",
|
|
270
|
+
"file",
|
|
271
|
+
"doc",
|
|
272
|
+
"code",
|
|
273
|
+
"session",
|
|
274
|
+
"notes",
|
|
275
|
+
"moc",
|
|
276
|
+
"template",
|
|
277
|
+
"content",
|
|
278
|
+
"attachment",
|
|
279
|
+
"etc",
|
|
280
|
+
"ie",
|
|
281
|
+
"eg",
|
|
282
|
+
"vs",
|
|
283
|
+
"les",
|
|
284
|
+
"des",
|
|
285
|
+
"une",
|
|
286
|
+
"est",
|
|
287
|
+
"que",
|
|
288
|
+
"qui",
|
|
289
|
+
"dans",
|
|
290
|
+
"pour",
|
|
291
|
+
"sur",
|
|
292
|
+
"par",
|
|
293
|
+
"pas",
|
|
294
|
+
"son",
|
|
295
|
+
"ses",
|
|
296
|
+
"aux",
|
|
297
|
+
"avec",
|
|
298
|
+
"tout",
|
|
299
|
+
"mais",
|
|
300
|
+
"und",
|
|
301
|
+
"der",
|
|
302
|
+
"die",
|
|
303
|
+
"das",
|
|
304
|
+
"ein",
|
|
305
|
+
"eine",
|
|
306
|
+
"ist",
|
|
307
|
+
"den",
|
|
308
|
+
"dem",
|
|
309
|
+
"von",
|
|
310
|
+
"mit",
|
|
311
|
+
"auf",
|
|
312
|
+
"nicht",
|
|
313
|
+
"sich",
|
|
314
|
+
"auch",
|
|
315
|
+
"noch",
|
|
316
|
+
"wie"
|
|
317
|
+
]);
|
|
318
|
+
/**
|
|
319
|
+
* Alias used by graph modules that need stop-word filtering specifically for
|
|
320
|
+
* vault note titles (same set, just semantically named for clarity).
|
|
321
|
+
*/
|
|
322
|
+
const TITLE_STOP_WORDS = STOP_WORDS;
|
|
323
|
+
|
|
324
|
+
//#endregion
|
|
325
|
+
export { TITLE_STOP_WORDS as n, STOP_WORDS as t };
|
|
326
|
+
//# sourceMappingURL=stop-words-BaMEGVeY.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop-words-BaMEGVeY.mjs","names":[],"sources":["../src/utils/stop-words.ts"],"sourcesContent":["/**\n * Shared stop-word list used across memory search, slug generation, graph clustering,\n * and zettelkasten modules. This is the union of all per-file sets that previously\n * existed in 7 different files.\n */\n\nexport const STOP_WORDS = new Set([\n // Articles / determiners\n \"a\", \"an\", \"the\",\n // Conjunctions\n \"and\", \"or\", \"but\", \"if\", \"then\", \"else\", \"so\", \"because\", \"as\",\n \"although\", \"however\", \"therefore\", \"thus\", \"hence\", \"meanwhile\",\n \"moreover\", \"furthermore\", \"otherwise\", \"instead\", \"anyway\",\n // Prepositions\n \"at\", \"to\", \"for\", \"of\", \"with\", \"by\", \"from\", \"in\", \"on\", \"out\",\n \"off\", \"over\", \"under\", \"up\", \"into\", \"without\", \"per\", \"via\",\n // Pronouns\n \"i\", \"you\", \"we\", \"they\", \"he\", \"she\", \"it\", \"me\", \"us\", \"him\", \"her\",\n \"my\", \"your\", \"our\", \"their\", \"his\", \"its\", \"who\", \"whom\", \"what\",\n \"which\", \"this\", \"that\", \"these\", \"those\",\n // Common verbs\n \"is\", \"are\", \"was\", \"were\", \"be\", \"been\", \"being\",\n \"have\", \"has\", \"had\", \"do\", \"does\", \"did\",\n \"will\", \"would\", \"could\", \"should\", \"may\", \"might\", \"can\", \"shall\",\n \"want\", \"need\", \"know\", \"think\", \"see\", \"look\", \"make\", \"get\", \"go\",\n \"come\", \"take\", \"use\", \"find\", \"give\", \"tell\", \"say\", \"said\", \"try\",\n \"keep\", \"run\", \"set\", \"put\", \"add\", \"show\", \"check\", \"let\",\n // Negation / common function words\n \"not\", \"no\", \"yes\", \"just\", \"also\", \"very\", \"really\",\n \"about\", \"after\", \"before\",\n \"more\", \"most\", \"some\", \"any\", \"all\", \"each\", \"every\", \"both\", \"few\",\n \"many\", \"much\", \"other\", \"another\", \"such\", \"only\", \"own\", \"same\",\n \"than\", \"too\", \"ok\", \"okay\", \"sure\",\n \"please\", \"thanks\", \"thank\", \"here\", \"there\", \"now\", \"well\", \"like\",\n \"going\", \"done\", \"got\",\n // Tech/URL junk\n \"https\", \"http\", \"www\", \"com\", \"org\", \"net\", \"io\",\n \"null\", \"undefined\", \"true\", \"false\",\n // Contractions (de-apostrophe'd forms that appear after tokenisation)\n \"ll\", \"ve\", \"re\", \"don\", \"thats\", \"heres\", \"theres\",\n \"youre\", \"theyre\", \"didnt\", \"dont\", \"doesnt\", \"havent\", \"hasnt\",\n \"wont\", \"cant\", \"shouldnt\", \"wouldnt\", \"couldnt\", \"isnt\", \"arent\",\n \"wasnt\", \"werent\",\n // Filler adverbs\n \"never\", \"ever\", \"still\", \"already\", \"yet\", \"back\",\n \"away\", \"down\", \"right\", \"left\", \"next\", \"last\", \"first\", \"second\",\n \"third\",\n \"then\", \"again\", \"once\", \"twice\", \"since\", \"while\", \"though\",\n \"actually\", \"basically\", \"literally\", \"simply\", \"exactly\", \"probably\",\n \"possibly\", \"maybe\", \"perhaps\", \"certainly\", \"definitely\", \"absolutely\",\n \"completely\", \"totally\", \"quite\", \"rather\", \"fairly\", \"nearly\",\n \"almost\", \"barely\", \"hardly\", \"quickly\", \"slowly\", \"easily\", \"likely\",\n \"unlikely\",\n // Numbers (spelled out)\n \"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"seven\",\n \"eight\", \"nine\", \"ten\",\n // Common nouns (too generic for search/slug)\n \"time\", \"way\", \"thing\", \"something\", \"anything\", \"nothing\",\n \"everything\", \"someone\", \"anyone\", \"everyone\",\n // Zettelkasten / vault-specific noise\n \"new\", \"note\", \"untitled\", \"page\", \"file\", \"doc\", \"code\",\n \"session\", \"notes\", \"moc\", \"template\", \"content\", \"attachment\",\n // Misc abbreviations\n \"etc\", \"ie\", \"eg\", \"vs\",\n // French stop words (for multilingual vaults)\n \"les\", \"des\", \"une\", \"est\", \"que\", \"qui\", \"dans\", \"pour\", \"sur\",\n \"par\", \"pas\", \"son\", \"ses\", \"aux\", \"avec\", \"tout\", \"mais\",\n // German stop words (for multilingual vaults)\n \"und\", \"der\", \"die\", \"das\", \"ein\", \"eine\", \"ist\", \"den\", \"dem\",\n \"von\", \"mit\", \"auf\", \"nicht\", \"sich\", \"auch\", \"noch\", \"wie\",\n]);\n\n/**\n * Alias used by graph modules that need stop-word filtering specifically for\n * vault note titles (same set, just semantically named for clarity).\n */\nexport const TITLE_STOP_WORDS = STOP_WORDS;\n"],"mappings":";;;;;;AAMA,MAAa,aAAa,IAAI,IAAI;CAEhC;CAAK;CAAM;CAEX;CAAO;CAAM;CAAO;CAAM;CAAQ;CAAQ;CAAM;CAAW;CAC3D;CAAY;CAAW;CAAa;CAAQ;CAAS;CACrD;CAAY;CAAe;CAAa;CAAW;CAEnD;CAAM;CAAM;CAAO;CAAM;CAAQ;CAAM;CAAQ;CAAM;CAAM;CAC3D;CAAO;CAAQ;CAAS;CAAM;CAAQ;CAAW;CAAO;CAExD;CAAK;CAAO;CAAM;CAAQ;CAAM;CAAO;CAAM;CAAM;CAAM;CAAO;CAChE;CAAM;CAAQ;CAAO;CAAS;CAAO;CAAO;CAAO;CAAQ;CAC3D;CAAS;CAAQ;CAAQ;CAAS;CAElC;CAAM;CAAO;CAAO;CAAQ;CAAM;CAAQ;CAC1C;CAAQ;CAAO;CAAO;CAAM;CAAQ;CACpC;CAAQ;CAAS;CAAS;CAAU;CAAO;CAAS;CAAO;CAC3D;CAAQ;CAAQ;CAAQ;CAAS;CAAO;CAAQ;CAAQ;CAAO;CAC/D;CAAQ;CAAQ;CAAO;CAAQ;CAAQ;CAAQ;CAAO;CAAQ;CAC9D;CAAQ;CAAO;CAAO;CAAO;CAAO;CAAQ;CAAS;CAErD;CAAO;CAAM;CAAO;CAAQ;CAAQ;CAAQ;CAC5C;CAAS;CAAS;CAClB;CAAQ;CAAQ;CAAQ;CAAO;CAAO;CAAQ;CAAS;CAAQ;CAC/D;CAAQ;CAAQ;CAAS;CAAW;CAAQ;CAAQ;CAAO;CAC3D;CAAQ;CAAO;CAAM;CAAQ;CAC7B;CAAU;CAAU;CAAS;CAAQ;CAAS;CAAO;CAAQ;CAC7D;CAAS;CAAQ;CAEjB;CAAS;CAAQ;CAAO;CAAO;CAAO;CAAO;CAC7C;CAAQ;CAAa;CAAQ;CAE7B;CAAM;CAAM;CAAM;CAAO;CAAS;CAAS;CAC3C;CAAS;CAAU;CAAS;CAAQ;CAAU;CAAU;CACxD;CAAQ;CAAQ;CAAY;CAAW;CAAW;CAAQ;CAC1D;CAAS;CAET;CAAS;CAAQ;CAAS;CAAW;CAAO;CAC5C;CAAQ;CAAQ;CAAS;CAAQ;CAAQ;CAAQ;CAAS;CAC1D;CACA;CAAQ;CAAS;CAAQ;CAAS;CAAS;CAAS;CACpD;CAAY;CAAa;CAAa;CAAU;CAAW;CAC3D;CAAY;CAAS;CAAW;CAAa;CAAc;CAC3D;CAAc;CAAW;CAAS;CAAU;CAAU;CACtD;CAAU;CAAU;CAAU;CAAW;CAAU;CAAU;CAC7D;CAEA;CAAO;CAAO;CAAS;CAAQ;CAAQ;CAAO;CAC9C;CAAS;CAAQ;CAEjB;CAAQ;CAAO;CAAS;CAAa;CAAY;CACjD;CAAc;CAAW;CAAU;CAEnC;CAAO;CAAQ;CAAY;CAAQ;CAAQ;CAAO;CAClD;CAAW;CAAS;CAAO;CAAY;CAAW;CAElD;CAAO;CAAM;CAAM;CAEnB;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAQ;CAAQ;CAC1D;CAAO;CAAO;CAAO;CAAO;CAAO;CAAQ;CAAQ;CAEnD;CAAO;CAAO;CAAO;CAAO;CAAO;CAAQ;CAAO;CAAO;CACzD;CAAO;CAAO;CAAO;CAAS;CAAQ;CAAQ;CAAQ;CACvD,CAAC;;;;;AAMF,MAAa,mBAAmB"}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { existsSync, readFileSync,
|
|
3
|
-
import {
|
|
4
|
-
import { basename, join, normalize, relative } from "node:path";
|
|
5
|
-
import { createHash } from "node:crypto";
|
|
1
|
+
import { a as parseSessionTitleChunk, c as yieldToEventLoop, f as sha256File, i as isPathTooBroadForContentScan, l as chunkMarkdown, n as chunkId, o as walkContentFiles, r as detectTier, s as walkMdFiles, t as INDEX_YIELD_EVERY } from "./helpers-BEST-4Gx.mjs";
|
|
2
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
3
|
+
import { basename, join, relative } from "node:path";
|
|
6
4
|
|
|
7
|
-
//#region src/memory/indexer.ts
|
|
5
|
+
//#region src/memory/indexer/sync.ts
|
|
8
6
|
/**
|
|
9
|
-
*
|
|
7
|
+
* Synchronous (SQLite) indexer for the PAI federation memory engine.
|
|
10
8
|
*
|
|
11
9
|
* Scans project memory/ and Notes/ directories, chunks markdown files, and
|
|
12
10
|
* inserts the resulting chunks into federation.db for BM25 search.
|
|
@@ -14,41 +12,10 @@ import { createHash } from "node:crypto";
|
|
|
14
12
|
* Change detection: files whose SHA-256 hash has not changed since the last
|
|
15
13
|
* index run are skipped, keeping incremental re-indexing fast.
|
|
16
14
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
15
|
+
* Uses raw better-sqlite3 Database directly for maximum SQLite performance
|
|
16
|
+
* (synchronous transactions, no serialisation overhead).
|
|
19
17
|
*/
|
|
20
18
|
/**
|
|
21
|
-
* Classify a relative file path into one of the four memory tiers.
|
|
22
|
-
*
|
|
23
|
-
* Rules (in priority order):
|
|
24
|
-
* - MEMORY.md anywhere in memory/ → 'evergreen'
|
|
25
|
-
* - YYYY-MM-DD.md in memory/ → 'daily'
|
|
26
|
-
* - anything else in memory/ → 'topic'
|
|
27
|
-
* - anything in Notes/ → 'session'
|
|
28
|
-
*/
|
|
29
|
-
function detectTier(relativePath) {
|
|
30
|
-
const p = relativePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
31
|
-
if (p.startsWith("Notes/") || p === "Notes") return "session";
|
|
32
|
-
const fileName = basename(p);
|
|
33
|
-
if (fileName === "MEMORY.md") return "evergreen";
|
|
34
|
-
if (/^\d{4}-\d{2}-\d{2}\.md$/.test(fileName)) return "daily";
|
|
35
|
-
return "topic";
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Generate a deterministic chunk ID from its coordinates.
|
|
39
|
-
* Format: sha256("projectId:path:chunkIndex:startLine:endLine")
|
|
40
|
-
*
|
|
41
|
-
* The chunkIndex (0-based position within the file) is included so that
|
|
42
|
-
* chunks with approximated line numbers (e.g. from splitBySentences) never
|
|
43
|
-
* produce colliding IDs even when multiple chunks share the same startLine/endLine.
|
|
44
|
-
*/
|
|
45
|
-
function chunkId(projectId, path, chunkIndex, startLine, endLine) {
|
|
46
|
-
return createHash("sha256").update(`${projectId}:${path}:${chunkIndex}:${startLine}:${endLine}`).digest("hex");
|
|
47
|
-
}
|
|
48
|
-
function sha256File(content) {
|
|
49
|
-
return createHash("sha256").update(content).digest("hex");
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
19
|
* Index a single file into the federation database.
|
|
53
20
|
*
|
|
54
21
|
* @returns true if the file was re-indexed (changed or new), false if skipped.
|
|
@@ -106,169 +73,15 @@ function indexFile(db, projectId, rootPath, relativePath, source, tier) {
|
|
|
106
73
|
return true;
|
|
107
74
|
}
|
|
108
75
|
/**
|
|
109
|
-
* Safety cap: maximum number of .md files collected per project scan.
|
|
110
|
-
* Prevents runaway scans on huge root paths (e.g. home directory).
|
|
111
|
-
* Projects with more files than this are scanned up to the cap only.
|
|
112
|
-
*/
|
|
113
|
-
const MAX_FILES_PER_PROJECT = 5e3;
|
|
114
|
-
/**
|
|
115
|
-
* Maximum recursion depth for directory walks.
|
|
116
|
-
* Prevents deep traversal of large directory trees (e.g. development repos).
|
|
117
|
-
* Depth 0 = the given directory itself (no recursion).
|
|
118
|
-
* Value 6 allows: root → subdirs → sub-subdirs → ... up to 6 levels.
|
|
119
|
-
* Sufficient for memory/, Notes/, and typical docs structures.
|
|
120
|
-
*/
|
|
121
|
-
const MAX_WALK_DEPTH = 6;
|
|
122
|
-
/**
|
|
123
|
-
* Recursively collect all .md files under a directory.
|
|
124
|
-
* Returns absolute paths. Stops early if the accumulated count hits the cap
|
|
125
|
-
* or if the recursion depth exceeds MAX_WALK_DEPTH.
|
|
126
|
-
*
|
|
127
|
-
* @param dir Directory to scan.
|
|
128
|
-
* @param acc Shared accumulator array (mutated in place for early exit).
|
|
129
|
-
* @param cap Maximum number of files to collect (across all recursive calls).
|
|
130
|
-
* @param depth Current recursion depth (0 = the initial call).
|
|
131
|
-
*/
|
|
132
|
-
function walkMdFiles(dir, acc, cap = MAX_FILES_PER_PROJECT, depth = 0) {
|
|
133
|
-
const results = acc ?? [];
|
|
134
|
-
if (!existsSync(dir)) return results;
|
|
135
|
-
if (results.length >= cap) return results;
|
|
136
|
-
if (depth > MAX_WALK_DEPTH) return results;
|
|
137
|
-
try {
|
|
138
|
-
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
139
|
-
if (results.length >= cap) break;
|
|
140
|
-
if (entry.isSymbolicLink()) continue;
|
|
141
|
-
if (ALWAYS_SKIP_DIRS.has(entry.name)) continue;
|
|
142
|
-
const full = join(dir, entry.name);
|
|
143
|
-
if (entry.isDirectory()) walkMdFiles(full, results, cap, depth + 1);
|
|
144
|
-
else if (entry.isFile() && entry.name.endsWith(".md")) results.push(full);
|
|
145
|
-
}
|
|
146
|
-
} catch {}
|
|
147
|
-
return results;
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Directories to ALWAYS skip, at any depth, during any directory walk.
|
|
151
|
-
* These are build artifacts, dependency trees, and VCS internals that
|
|
152
|
-
* should never be indexed regardless of where they appear in the tree.
|
|
153
|
-
*/
|
|
154
|
-
const ALWAYS_SKIP_DIRS = new Set([
|
|
155
|
-
".git",
|
|
156
|
-
"node_modules",
|
|
157
|
-
"vendor",
|
|
158
|
-
"Pods",
|
|
159
|
-
"dist",
|
|
160
|
-
"build",
|
|
161
|
-
"out",
|
|
162
|
-
"DerivedData",
|
|
163
|
-
".next",
|
|
164
|
-
".venv",
|
|
165
|
-
"venv",
|
|
166
|
-
"__pycache__",
|
|
167
|
-
".cache",
|
|
168
|
-
".bun"
|
|
169
|
-
]);
|
|
170
|
-
/**
|
|
171
|
-
* Directories to skip when doing a root-level content scan.
|
|
172
|
-
* These are either already handled by dedicated scans or should never be indexed.
|
|
173
|
-
*/
|
|
174
|
-
const ROOT_SCAN_SKIP_DIRS = new Set([
|
|
175
|
-
"memory",
|
|
176
|
-
"Notes",
|
|
177
|
-
".claude",
|
|
178
|
-
".DS_Store",
|
|
179
|
-
...ALWAYS_SKIP_DIRS
|
|
180
|
-
]);
|
|
181
|
-
/**
|
|
182
|
-
* Additional directories to skip at the content-scan level (first level below root).
|
|
183
|
-
* These are common macOS/Linux home-directory or repo noise directories that are
|
|
184
|
-
* never meaningful as project content.
|
|
185
|
-
*/
|
|
186
|
-
const CONTENT_SCAN_SKIP_DIRS = new Set([
|
|
187
|
-
"Library",
|
|
188
|
-
"Applications",
|
|
189
|
-
"Music",
|
|
190
|
-
"Movies",
|
|
191
|
-
"Pictures",
|
|
192
|
-
"Desktop",
|
|
193
|
-
"Downloads",
|
|
194
|
-
"Public",
|
|
195
|
-
"coverage",
|
|
196
|
-
...ALWAYS_SKIP_DIRS
|
|
197
|
-
]);
|
|
198
|
-
/**
|
|
199
|
-
* Recursively collect all .md files under rootPath, excluding directories
|
|
200
|
-
* that are already covered by dedicated scans (memory/, Notes/) and
|
|
201
|
-
* common noise directories (.git, node_modules, etc.).
|
|
202
|
-
*
|
|
203
|
-
* Returns absolute paths for files NOT already handled by the specific scanners.
|
|
204
|
-
* Stops collecting once MAX_FILES_PER_PROJECT is reached.
|
|
205
|
-
*/
|
|
206
|
-
function walkContentFiles(rootPath) {
|
|
207
|
-
if (!existsSync(rootPath)) return [];
|
|
208
|
-
const results = [];
|
|
209
|
-
try {
|
|
210
|
-
for (const entry of readdirSync(rootPath, { withFileTypes: true })) {
|
|
211
|
-
if (results.length >= MAX_FILES_PER_PROJECT) break;
|
|
212
|
-
if (entry.isSymbolicLink()) continue;
|
|
213
|
-
if (ROOT_SCAN_SKIP_DIRS.has(entry.name)) continue;
|
|
214
|
-
if (CONTENT_SCAN_SKIP_DIRS.has(entry.name)) continue;
|
|
215
|
-
const full = join(rootPath, entry.name);
|
|
216
|
-
if (entry.isDirectory()) walkMdFiles(full, results, MAX_FILES_PER_PROJECT);
|
|
217
|
-
else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
218
|
-
if (entry.name !== "MEMORY.md") results.push(full);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
} catch {}
|
|
222
|
-
return results;
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
76
|
* Index all memory, Notes, and content files for a single registered project.
|
|
226
77
|
*
|
|
227
78
|
* Scans:
|
|
228
79
|
* - {rootPath}/MEMORY.md → source='memory', tier='evergreen'
|
|
229
80
|
* - {rootPath}/memory/ → source='memory', tier from detectTier()
|
|
230
81
|
* - {rootPath}/Notes/ → source='notes', tier='session'
|
|
231
|
-
* - {rootPath}
|
|
82
|
+
* - {rootPath}/**\/*.md → source='content', tier='topic' (all other .md files, recursive)
|
|
232
83
|
* - {claudeNotesDir}/ → source='notes', tier='session' (if set and different)
|
|
233
|
-
*
|
|
234
|
-
* The content scan covers projects like job-discussions where markdown files
|
|
235
|
-
* live in date/topic subdirectories rather than a memory/ folder. The
|
|
236
|
-
* memory/, Notes/, .git/, and node_modules/ directories are excluded from
|
|
237
|
-
* the content scan to avoid double-indexing.
|
|
238
|
-
*
|
|
239
|
-
* The claudeNotesDir parameter points to ~/.claude/projects/{encoded}/Notes/
|
|
240
|
-
* where Claude Code writes session notes for a given working directory.
|
|
241
|
-
* It is stored on the project row as claude_notes_dir after a registry scan.
|
|
242
84
|
*/
|
|
243
|
-
/**
|
|
244
|
-
* Number of files to process before yielding to the event loop inside
|
|
245
|
-
* indexProject. Keeps IPC responsive even while indexing large projects.
|
|
246
|
-
* Lower = more responsive but more overhead. 10 is a good balance.
|
|
247
|
-
*/
|
|
248
|
-
const INDEX_YIELD_EVERY = 10;
|
|
249
|
-
/**
|
|
250
|
-
* Returns true if rootPath should skip the recursive content scan.
|
|
251
|
-
*
|
|
252
|
-
* Skips content scanning for:
|
|
253
|
-
* - The home directory itself or any ancestor (too broad — millions of files)
|
|
254
|
-
* - Git repositories (code repos — index memory/ and Notes/ only, not all .md files)
|
|
255
|
-
*
|
|
256
|
-
* The content scan is still useful for Obsidian vaults, Notes folders, and
|
|
257
|
-
* other doc-centric project trees where ALL markdown files are meaningful.
|
|
258
|
-
*
|
|
259
|
-
* The memory/, Notes/, and claude_notes_dir scans always run regardless.
|
|
260
|
-
*/
|
|
261
|
-
function isPathTooBroadForContentScan(rootPath) {
|
|
262
|
-
const normalized = normalize(rootPath);
|
|
263
|
-
const home = homedir();
|
|
264
|
-
if (home.startsWith(normalized) || normalized === "/") return true;
|
|
265
|
-
if (normalized.startsWith(home)) {
|
|
266
|
-
const rel = normalized.slice(home.length).replace(/^\//, "");
|
|
267
|
-
if ((rel ? rel.split("/").length : 0) === 0) return true;
|
|
268
|
-
}
|
|
269
|
-
if (existsSync(join(normalized, ".git"))) return true;
|
|
270
|
-
return false;
|
|
271
|
-
}
|
|
272
85
|
async function indexProject(db, projectId, rootPath, claudeNotesDir) {
|
|
273
86
|
const result = {
|
|
274
87
|
filesProcessed: 0,
|
|
@@ -301,7 +114,6 @@ async function indexProject(db, projectId, rootPath, claudeNotesDir) {
|
|
|
301
114
|
tier: "session"
|
|
302
115
|
});
|
|
303
116
|
{
|
|
304
|
-
const SESSION_TITLE_RE = /^(\d{4})\s*-\s*(\d{4}-\d{2}-\d{2})\s*-\s*(.+)\.md$/;
|
|
305
117
|
const titleInsertChunk = db.prepare(`
|
|
306
118
|
INSERT OR IGNORE INTO memory_chunks (id, project_id, source, tier, path, start_line, end_line, hash, text, updated_at)
|
|
307
119
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
@@ -312,11 +124,8 @@ async function indexProject(db, projectId, rootPath, claudeNotesDir) {
|
|
|
312
124
|
`);
|
|
313
125
|
const updatedAt = Date.now();
|
|
314
126
|
for (const absPath of walkMdFiles(notesDir)) {
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
if (!m) continue;
|
|
318
|
-
const [, num, date, title] = m;
|
|
319
|
-
const text = `Session #${num} ${date}: ${title}`;
|
|
127
|
+
const text = parseSessionTitleChunk(basename(absPath));
|
|
128
|
+
if (!text) continue;
|
|
320
129
|
const syntheticPath = `${relative(rootPath, absPath)}::title`;
|
|
321
130
|
const id = chunkId(projectId, syntheticPath, 0, 0, 0);
|
|
322
131
|
const hash = sha256File(text);
|
|
@@ -340,7 +149,6 @@ async function indexProject(db, projectId, rootPath, claudeNotesDir) {
|
|
|
340
149
|
tier: "session"
|
|
341
150
|
});
|
|
342
151
|
{
|
|
343
|
-
const SESSION_TITLE_RE_CLAUDE = /^(\d{4})\s*-\s*(\d{4}-\d{2}-\d{2})\s*-\s*(.+)\.md$/;
|
|
344
152
|
const updatedAt = Date.now();
|
|
345
153
|
const titleInsertChunk2 = db.prepare(`
|
|
346
154
|
INSERT OR IGNORE INTO memory_chunks (id, project_id, source, tier, path, start_line, end_line, hash, text, updated_at)
|
|
@@ -351,11 +159,8 @@ async function indexProject(db, projectId, rootPath, claudeNotesDir) {
|
|
|
351
159
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
352
160
|
`);
|
|
353
161
|
for (const absPath of walkMdFiles(claudeNotesDir)) {
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
if (!m) continue;
|
|
357
|
-
const [, num, date, title] = m;
|
|
358
|
-
const text = `Session #${num} ${date}: ${title}`;
|
|
162
|
+
const text = parseSessionTitleChunk(basename(absPath));
|
|
163
|
+
if (!text) continue;
|
|
359
164
|
const syntheticPath = `${relative(claudeNotesDir, absPath)}::title`;
|
|
360
165
|
const id = chunkId(projectId, syntheticPath, 0, 0, 0);
|
|
361
166
|
const hash = sha256File(text);
|
|
@@ -425,13 +230,6 @@ async function indexProject(db, projectId, rootPath, claudeNotesDir) {
|
|
|
425
230
|
return result;
|
|
426
231
|
}
|
|
427
232
|
/**
|
|
428
|
-
* Yield to the Node.js event loop between projects so the IPC server
|
|
429
|
-
* remains responsive during long index runs.
|
|
430
|
-
*/
|
|
431
|
-
function yieldToEventLoop() {
|
|
432
|
-
return new Promise((resolve) => setImmediate(resolve));
|
|
433
|
-
}
|
|
434
|
-
/**
|
|
435
233
|
* Index all active projects registered in the registry DB.
|
|
436
234
|
*
|
|
437
235
|
* Async: yields to the event loop between each project so that the daemon's
|
|
@@ -508,5 +306,5 @@ async function embedChunks(db, projectId, batchSize = 50, onProgress) {
|
|
|
508
306
|
}
|
|
509
307
|
|
|
510
308
|
//#endregion
|
|
511
|
-
export { indexProject as
|
|
512
|
-
//# sourceMappingURL=
|
|
309
|
+
export { indexProject as i, indexAll as n, indexFile as r, embedChunks as t };
|
|
310
|
+
//# sourceMappingURL=sync-BOsnEj2-.mjs.map
|