@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.
Files changed (137) hide show
  1. package/ARCHITECTURE.md +72 -1
  2. package/README.md +107 -3
  3. package/dist/{auto-route-BG6I_4B1.mjs → auto-route-C-DrW6BL.mjs} +3 -3
  4. package/dist/{auto-route-BG6I_4B1.mjs.map → auto-route-C-DrW6BL.mjs.map} +1 -1
  5. package/dist/cli/index.mjs +1897 -1569
  6. package/dist/cli/index.mjs.map +1 -1
  7. package/dist/clusters-JIDQW65f.mjs +201 -0
  8. package/dist/clusters-JIDQW65f.mjs.map +1 -0
  9. package/dist/{config-Cf92lGX_.mjs → config-BuhHWyOK.mjs} +21 -6
  10. package/dist/config-BuhHWyOK.mjs.map +1 -0
  11. package/dist/daemon/index.mjs +12 -9
  12. package/dist/daemon/index.mjs.map +1 -1
  13. package/dist/{daemon-D9evGlgR.mjs → daemon-D3hYb5_C.mjs} +670 -219
  14. package/dist/daemon-D3hYb5_C.mjs.map +1 -0
  15. package/dist/daemon-mcp/index.mjs +4597 -4
  16. package/dist/daemon-mcp/index.mjs.map +1 -1
  17. package/dist/{db-4lSqLFb8.mjs → db-BtuN768f.mjs} +9 -2
  18. package/dist/db-BtuN768f.mjs.map +1 -0
  19. package/dist/db-DdUperSl.mjs +110 -0
  20. package/dist/db-DdUperSl.mjs.map +1 -0
  21. package/dist/{detect-BU3Nx_2L.mjs → detect-CdaA48EI.mjs} +1 -1
  22. package/dist/{detect-BU3Nx_2L.mjs.map → detect-CdaA48EI.mjs.map} +1 -1
  23. package/dist/{detector-Bp-2SM3x.mjs → detector-jGBuYQJM.mjs} +2 -2
  24. package/dist/{detector-Bp-2SM3x.mjs.map → detector-jGBuYQJM.mjs.map} +1 -1
  25. package/dist/{factory-Bzcy70G9.mjs → factory-Ygqe_bVZ.mjs} +7 -5
  26. package/dist/{factory-Bzcy70G9.mjs.map → factory-Ygqe_bVZ.mjs.map} +1 -1
  27. package/dist/helpers-BEST-4Gx.mjs +420 -0
  28. package/dist/helpers-BEST-4Gx.mjs.map +1 -0
  29. package/dist/hooks/capture-all-events.mjs +19 -4
  30. package/dist/hooks/capture-all-events.mjs.map +4 -4
  31. package/dist/hooks/capture-session-summary.mjs +38 -0
  32. package/dist/hooks/capture-session-summary.mjs.map +3 -3
  33. package/dist/hooks/cleanup-session-files.mjs +6 -12
  34. package/dist/hooks/cleanup-session-files.mjs.map +4 -4
  35. package/dist/hooks/context-compression-hook.mjs +105 -111
  36. package/dist/hooks/context-compression-hook.mjs.map +4 -4
  37. package/dist/hooks/initialize-session.mjs +26 -17
  38. package/dist/hooks/initialize-session.mjs.map +4 -4
  39. package/dist/hooks/inject-observations.mjs +220 -0
  40. package/dist/hooks/inject-observations.mjs.map +7 -0
  41. package/dist/hooks/load-core-context.mjs +18 -2
  42. package/dist/hooks/load-core-context.mjs.map +4 -4
  43. package/dist/hooks/load-project-context.mjs +102 -97
  44. package/dist/hooks/load-project-context.mjs.map +4 -4
  45. package/dist/hooks/observe.mjs +354 -0
  46. package/dist/hooks/observe.mjs.map +7 -0
  47. package/dist/hooks/stop-hook.mjs +174 -90
  48. package/dist/hooks/stop-hook.mjs.map +4 -4
  49. package/dist/hooks/sync-todo-to-md.mjs +31 -33
  50. package/dist/hooks/sync-todo-to-md.mjs.map +4 -4
  51. package/dist/index.d.mts +32 -9
  52. package/dist/index.d.mts.map +1 -1
  53. package/dist/index.mjs +6 -9
  54. package/dist/indexer-D53l5d1U.mjs +1 -0
  55. package/dist/{indexer-backend-CIMXedqk.mjs → indexer-backend-jcJFsmB4.mjs} +37 -127
  56. package/dist/indexer-backend-jcJFsmB4.mjs.map +1 -0
  57. package/dist/{ipc-client-Bjg_a1dc.mjs → ipc-client-CoyUHPod.mjs} +2 -7
  58. package/dist/{ipc-client-Bjg_a1dc.mjs.map → ipc-client-CoyUHPod.mjs.map} +1 -1
  59. package/dist/latent-ideas-bTJo6Omd.mjs +191 -0
  60. package/dist/latent-ideas-bTJo6Omd.mjs.map +1 -0
  61. package/dist/neighborhood-BYYbEkUJ.mjs +135 -0
  62. package/dist/neighborhood-BYYbEkUJ.mjs.map +1 -0
  63. package/dist/note-context-BK24bX8Y.mjs +126 -0
  64. package/dist/note-context-BK24bX8Y.mjs.map +1 -0
  65. package/dist/postgres-CKf-EDtS.mjs +846 -0
  66. package/dist/postgres-CKf-EDtS.mjs.map +1 -0
  67. package/dist/{reranker-D7bRAHi6.mjs → reranker-CMNZcfVx.mjs} +1 -1
  68. package/dist/{reranker-D7bRAHi6.mjs.map → reranker-CMNZcfVx.mjs.map} +1 -1
  69. package/dist/{search-_oHfguA5.mjs → search-DC1qhkKn.mjs} +2 -58
  70. package/dist/search-DC1qhkKn.mjs.map +1 -0
  71. package/dist/{sqlite-WWBq7_2C.mjs → sqlite-l-s9xPjY.mjs} +160 -3
  72. package/dist/sqlite-l-s9xPjY.mjs.map +1 -0
  73. package/dist/state-C6_vqz7w.mjs +102 -0
  74. package/dist/state-C6_vqz7w.mjs.map +1 -0
  75. package/dist/stop-words-BaMEGVeY.mjs +326 -0
  76. package/dist/stop-words-BaMEGVeY.mjs.map +1 -0
  77. package/dist/{indexer-CMPOiY1r.mjs → sync-BOsnEj2-.mjs} +14 -216
  78. package/dist/sync-BOsnEj2-.mjs.map +1 -0
  79. package/dist/themes-BvYF0W8T.mjs +148 -0
  80. package/dist/themes-BvYF0W8T.mjs.map +1 -0
  81. package/dist/{tools-DV_lsiCc.mjs → tools-DcaJlYDN.mjs} +162 -273
  82. package/dist/tools-DcaJlYDN.mjs.map +1 -0
  83. package/dist/trace-CRx9lPuc.mjs +137 -0
  84. package/dist/trace-CRx9lPuc.mjs.map +1 -0
  85. package/dist/{vault-indexer-DXWs9pDn.mjs → vault-indexer-Bi2cRmn7.mjs} +174 -138
  86. package/dist/vault-indexer-Bi2cRmn7.mjs.map +1 -0
  87. package/dist/zettelkasten-cdajbnPr.mjs +708 -0
  88. package/dist/zettelkasten-cdajbnPr.mjs.map +1 -0
  89. package/package.json +1 -2
  90. package/src/hooks/ts/capture-all-events.ts +6 -0
  91. package/src/hooks/ts/lib/project-utils/index.ts +50 -0
  92. package/src/hooks/ts/lib/project-utils/notify.ts +75 -0
  93. package/src/hooks/ts/lib/project-utils/paths.ts +218 -0
  94. package/src/hooks/ts/lib/project-utils/session-notes.ts +363 -0
  95. package/src/hooks/ts/lib/project-utils/todo.ts +178 -0
  96. package/src/hooks/ts/lib/project-utils/tokens.ts +39 -0
  97. package/src/hooks/ts/lib/project-utils.ts +40 -999
  98. package/src/hooks/ts/post-tool-use/observe.ts +327 -0
  99. package/src/hooks/ts/pre-compact/context-compression-hook.ts +6 -0
  100. package/src/hooks/ts/session-end/capture-session-summary.ts +41 -0
  101. package/src/hooks/ts/session-start/initialize-session.ts +7 -1
  102. package/src/hooks/ts/session-start/inject-observations.ts +254 -0
  103. package/src/hooks/ts/session-start/load-core-context.ts +7 -0
  104. package/src/hooks/ts/session-start/load-project-context.ts +8 -1
  105. package/src/hooks/ts/stop/stop-hook.ts +28 -0
  106. package/templates/claude-md.template.md +7 -74
  107. package/templates/skills/user/.gitkeep +0 -0
  108. package/dist/chunker-CbnBe0s0.mjs +0 -191
  109. package/dist/chunker-CbnBe0s0.mjs.map +0 -1
  110. package/dist/config-Cf92lGX_.mjs.map +0 -1
  111. package/dist/daemon-D9evGlgR.mjs.map +0 -1
  112. package/dist/db-4lSqLFb8.mjs.map +0 -1
  113. package/dist/db-Dp8VXIMR.mjs +0 -212
  114. package/dist/db-Dp8VXIMR.mjs.map +0 -1
  115. package/dist/indexer-CMPOiY1r.mjs.map +0 -1
  116. package/dist/indexer-backend-CIMXedqk.mjs.map +0 -1
  117. package/dist/mcp/index.d.mts +0 -1
  118. package/dist/mcp/index.mjs +0 -500
  119. package/dist/mcp/index.mjs.map +0 -1
  120. package/dist/postgres-FXrHDPcE.mjs +0 -358
  121. package/dist/postgres-FXrHDPcE.mjs.map +0 -1
  122. package/dist/schemas-BFIgGntb.mjs +0 -3405
  123. package/dist/schemas-BFIgGntb.mjs.map +0 -1
  124. package/dist/search-_oHfguA5.mjs.map +0 -1
  125. package/dist/sqlite-WWBq7_2C.mjs.map +0 -1
  126. package/dist/tools-DV_lsiCc.mjs.map +0 -1
  127. package/dist/vault-indexer-DXWs9pDn.mjs.map +0 -1
  128. package/dist/zettelkasten-e-a4rW_6.mjs +0 -901
  129. package/dist/zettelkasten-e-a4rW_6.mjs.map +0 -1
  130. package/templates/README.md +0 -181
  131. package/templates/skills/createskill-skill.template.md +0 -78
  132. package/templates/skills/history-system.template.md +0 -371
  133. package/templates/skills/hook-system.template.md +0 -913
  134. package/templates/skills/sessions-skill.template.md +0 -102
  135. package/templates/skills/skill-system.template.md +0 -214
  136. package/templates/skills/terminal-tabs.template.md +0 -120
  137. package/templates/templates.md +0 -20
@@ -1,18 +1,12 @@
1
1
  #!/usr/bin/env node
2
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
- }) : x)(function(x) {
5
- if (typeof require !== "undefined") return require.apply(this, arguments);
6
- throw Error('Dynamic require of "' + x + '" is not supported');
7
- });
8
2
 
9
3
  // src/hooks/ts/pre-compact/context-compression-hook.ts
10
- import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
11
- import { basename as basename2, dirname, join as join3 } from "path";
4
+ import { existsSync as existsSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
5
+ import { basename as basename3, dirname, join as join6 } from "path";
12
6
  import { tmpdir } from "os";
13
7
 
14
- // src/hooks/ts/lib/project-utils.ts
15
- import { existsSync as existsSync2, mkdirSync, readdirSync, readFileSync as readFileSync2, writeFileSync, renameSync } from "fs";
8
+ // src/hooks/ts/lib/project-utils/paths.ts
9
+ import { existsSync as existsSync2, mkdirSync, readdirSync, renameSync } from "fs";
16
10
  import { join as join2, basename } from "path";
17
11
 
18
12
  // src/hooks/ts/lib/pai-paths.ts
@@ -73,8 +67,16 @@ function validatePAIStructure() {
73
67
  }
74
68
  validatePAIStructure();
75
69
 
76
- // src/hooks/ts/lib/project-utils.ts
70
+ // src/hooks/ts/lib/project-utils/paths.ts
77
71
  var PROJECTS_DIR = join2(PAI_DIR, "projects");
72
+ var PROBE_CWD_PATTERNS = [
73
+ "/CodexBar/ClaudeProbe",
74
+ "/ClaudeProbe"
75
+ ];
76
+ function isProbeSession(cwd) {
77
+ const dir = cwd || process.cwd();
78
+ return PROBE_CWD_PATTERNS.some((pattern) => dir.includes(pattern));
79
+ }
78
80
  function encodePath(path) {
79
81
  return path.replace(/\//g, "-").replace(/\./g, "-").replace(/ /g, "-");
80
82
  }
@@ -102,14 +104,30 @@ function findNotesDir(cwd) {
102
104
  }
103
105
  return { path: getNotesDir(cwd), isLocal: false };
104
106
  }
107
+ function findTodoPath(cwd) {
108
+ const localPaths = [
109
+ join2(cwd, "TODO.md"),
110
+ join2(cwd, "notes", "TODO.md"),
111
+ join2(cwd, "Notes", "TODO.md"),
112
+ join2(cwd, ".claude", "TODO.md")
113
+ ];
114
+ for (const path of localPaths) {
115
+ if (existsSync2(path)) return path;
116
+ }
117
+ return join2(getNotesDir(cwd), "TODO.md");
118
+ }
119
+
120
+ // src/hooks/ts/lib/project-utils/notify.ts
121
+ import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
122
+ import { join as join3 } from "path";
123
+ import { homedir as homedir2 } from "os";
105
124
  function isWhatsAppEnabled() {
106
125
  try {
107
- const { homedir: homedir2 } = __require("os");
108
- const settingsPath = join2(homedir2(), ".claude", "settings.json");
109
- if (!existsSync2(settingsPath)) return false;
126
+ const settingsPath = join3(homedir2(), ".claude", "settings.json");
127
+ if (!existsSync3(settingsPath)) return false;
110
128
  const settings = JSON.parse(readFileSync2(settingsPath, "utf-8"));
111
129
  const enabled = settings.enabledMcpjsonServers || [];
112
- return enabled.includes("whazaa");
130
+ return enabled.includes("aibroker") || enabled.includes("whazaa") || enabled.includes("telex");
113
131
  } catch {
114
132
  return false;
115
133
  }
@@ -150,22 +168,24 @@ async function sendNtfyNotification(message, retries = 2) {
150
168
  console.error("ntfy.sh notification failed after all retries");
151
169
  return false;
152
170
  }
171
+
172
+ // src/hooks/ts/lib/project-utils/session-notes.ts
173
+ import { existsSync as existsSync4, mkdirSync as mkdirSync2, readdirSync as readdirSync2, readFileSync as readFileSync3, writeFileSync, renameSync as renameSync2 } from "fs";
174
+ import { join as join4, basename as basename2 } from "path";
153
175
  function getMonthDir(notesDir) {
154
176
  const now = /* @__PURE__ */ new Date();
155
177
  const year = String(now.getFullYear());
156
178
  const month = String(now.getMonth() + 1).padStart(2, "0");
157
- const monthDir = join2(notesDir, year, month);
158
- if (!existsSync2(monthDir)) {
159
- mkdirSync(monthDir, { recursive: true });
179
+ const monthDir = join4(notesDir, year, month);
180
+ if (!existsSync4(monthDir)) {
181
+ mkdirSync2(monthDir, { recursive: true });
160
182
  }
161
183
  return monthDir;
162
184
  }
163
185
  function getNextNoteNumber(notesDir) {
164
186
  const monthDir = getMonthDir(notesDir);
165
- const files = readdirSync(monthDir).filter((f) => f.match(/^\d{3,4}[\s_-]/)).filter((f) => f.endsWith(".md")).sort();
166
- if (files.length === 0) {
167
- return "0001";
168
- }
187
+ const files = readdirSync2(monthDir).filter((f) => f.match(/^\d{3,4}[\s_-]/)).filter((f) => f.endsWith(".md")).sort();
188
+ if (files.length === 0) return "0001";
169
189
  let maxNumber = 0;
170
190
  for (const file of files) {
171
191
  const digitMatch = file.match(/^(\d+)/);
@@ -177,29 +197,27 @@ function getNextNoteNumber(notesDir) {
177
197
  return String(maxNumber + 1).padStart(4, "0");
178
198
  }
179
199
  function getCurrentNotePath(notesDir) {
180
- if (!existsSync2(notesDir)) {
181
- return null;
182
- }
200
+ if (!existsSync4(notesDir)) return null;
183
201
  const findLatestIn = (dir) => {
184
- if (!existsSync2(dir)) return null;
185
- const files = readdirSync(dir).filter((f) => f.match(/^\d{3,4}[\s_-].*\.md$/)).sort((a, b) => {
202
+ if (!existsSync4(dir)) return null;
203
+ const files = readdirSync2(dir).filter((f) => f.match(/^\d{3,4}[\s_-].*\.md$/)).sort((a, b) => {
186
204
  const numA = parseInt(a.match(/^(\d+)/)?.[1] || "0", 10);
187
205
  const numB = parseInt(b.match(/^(\d+)/)?.[1] || "0", 10);
188
206
  return numA - numB;
189
207
  });
190
208
  if (files.length === 0) return null;
191
- return join2(dir, files[files.length - 1]);
209
+ return join4(dir, files[files.length - 1]);
192
210
  };
193
211
  const now = /* @__PURE__ */ new Date();
194
212
  const year = String(now.getFullYear());
195
213
  const month = String(now.getMonth() + 1).padStart(2, "0");
196
- const currentMonthDir = join2(notesDir, year, month);
214
+ const currentMonthDir = join4(notesDir, year, month);
197
215
  const found = findLatestIn(currentMonthDir);
198
216
  if (found) return found;
199
217
  const prevDate = new Date(now.getFullYear(), now.getMonth() - 1, 1);
200
218
  const prevYear = String(prevDate.getFullYear());
201
219
  const prevMonth = String(prevDate.getMonth() + 1).padStart(2, "0");
202
- const prevMonthDir = join2(notesDir, prevYear, prevMonth);
220
+ const prevMonthDir = join4(notesDir, prevYear, prevMonth);
203
221
  const prevFound = findLatestIn(prevMonthDir);
204
222
  if (prevFound) return prevFound;
205
223
  return findLatestIn(notesDir);
@@ -207,10 +225,9 @@ function getCurrentNotePath(notesDir) {
207
225
  function createSessionNote(notesDir, description) {
208
226
  const noteNumber = getNextNoteNumber(notesDir);
209
227
  const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
210
- const safeDescription = "New Session";
211
228
  const monthDir = getMonthDir(notesDir);
212
- const filename = `${noteNumber} - ${date} - ${safeDescription}.md`;
213
- const filepath = join2(monthDir, filename);
229
+ const filename = `${noteNumber} - ${date} - New Session.md`;
230
+ const filepath = join4(monthDir, filename);
214
231
  const content = `# Session ${noteNumber}: ${description}
215
232
 
216
233
  **Date:** ${date}
@@ -237,14 +254,12 @@ function createSessionNote(notesDir, description) {
237
254
  return filepath;
238
255
  }
239
256
  function appendCheckpoint(notePath, checkpoint) {
240
- if (!existsSync2(notePath)) {
257
+ if (!existsSync4(notePath)) {
241
258
  console.error(`Note file not found, recreating: ${notePath}`);
242
259
  try {
243
- const parentDir = join2(notePath, "..");
244
- if (!existsSync2(parentDir)) {
245
- mkdirSync(parentDir, { recursive: true });
246
- }
247
- const noteFilename = basename(notePath);
260
+ const parentDir = join4(notePath, "..");
261
+ if (!existsSync4(parentDir)) mkdirSync2(parentDir, { recursive: true });
262
+ const noteFilename = basename2(notePath);
248
263
  const numberMatch = noteFilename.match(/^(\d+)/);
249
264
  const noteNumber = numberMatch ? numberMatch[1] : "0000";
250
265
  const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
@@ -276,7 +291,7 @@ function appendCheckpoint(notePath, checkpoint) {
276
291
  return;
277
292
  }
278
293
  }
279
- const content = readFileSync2(notePath, "utf-8");
294
+ const content = readFileSync3(notePath, "utf-8");
280
295
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
281
296
  const checkpointText = `
282
297
  ### Checkpoint ${timestamp}
@@ -284,28 +299,21 @@ function appendCheckpoint(notePath, checkpoint) {
284
299
  ${checkpoint}
285
300
  `;
286
301
  const nextStepsIndex = content.indexOf("## Next Steps");
287
- let newContent;
288
- if (nextStepsIndex !== -1) {
289
- newContent = content.substring(0, nextStepsIndex) + checkpointText + content.substring(nextStepsIndex);
290
- } else {
291
- newContent = content + checkpointText;
292
- }
302
+ const newContent = nextStepsIndex !== -1 ? content.substring(0, nextStepsIndex) + checkpointText + content.substring(nextStepsIndex) : content + checkpointText;
293
303
  writeFileSync(notePath, newContent);
294
- console.error(`Checkpoint added to: ${basename(notePath)}`);
304
+ console.error(`Checkpoint added to: ${basename2(notePath)}`);
295
305
  }
296
306
  function addWorkToSessionNote(notePath, workItems, sectionTitle) {
297
- if (!existsSync2(notePath)) {
307
+ if (!existsSync4(notePath)) {
298
308
  console.error(`Note file not found: ${notePath}`);
299
309
  return;
300
310
  }
301
- let content = readFileSync2(notePath, "utf-8");
311
+ let content = readFileSync3(notePath, "utf-8");
302
312
  let workText = "";
303
- if (sectionTitle) {
304
- workText += `
313
+ if (sectionTitle) workText += `
305
314
  ### ${sectionTitle}
306
315
 
307
316
  `;
308
- }
309
317
  for (const item of workItems) {
310
318
  const checkbox = item.completed !== false ? "[x]" : "[ ]";
311
319
  workText += `- ${checkbox} **${item.title}**
@@ -328,30 +336,24 @@ function addWorkToSessionNote(notePath, workItems, sectionTitle) {
328
336
  }
329
337
  }
330
338
  writeFileSync(notePath, content);
331
- console.error(`Added ${workItems.length} work item(s) to: ${basename(notePath)}`);
339
+ console.error(`Added ${workItems.length} work item(s) to: ${basename2(notePath)}`);
332
340
  }
333
341
  function renameSessionNote(notePath, meaningfulName) {
334
- if (!meaningfulName || !existsSync2(notePath)) {
335
- return notePath;
336
- }
337
- const dir = join2(notePath, "..");
338
- const oldFilename = basename(notePath);
342
+ if (!meaningfulName || !existsSync4(notePath)) return notePath;
343
+ const dir = join4(notePath, "..");
344
+ const oldFilename = basename2(notePath);
339
345
  const correctMatch = oldFilename.match(/^(\d{3,4}) - (\d{4}-\d{2}-\d{2}) - .*\.md$/);
340
346
  const legacyMatch = oldFilename.match(/^(\d{3,4})_(\d{4}-\d{2}-\d{2})_.*\.md$/);
341
347
  const match = correctMatch || legacyMatch;
342
- if (!match) {
343
- return notePath;
344
- }
348
+ if (!match) return notePath;
345
349
  const [, noteNumber, date] = match;
346
350
  const titleCaseName = meaningfulName.split(/[\s_-]+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ").trim();
347
351
  const paddedNumber = noteNumber.padStart(4, "0");
348
352
  const newFilename = `${paddedNumber} - ${date} - ${titleCaseName}.md`;
349
- const newPath = join2(dir, newFilename);
350
- if (newFilename === oldFilename) {
351
- return notePath;
352
- }
353
+ const newPath = join4(dir, newFilename);
354
+ if (newFilename === oldFilename) return notePath;
353
355
  try {
354
- renameSync(notePath, newPath);
356
+ renameSync2(notePath, newPath);
355
357
  console.error(`Renamed note: ${oldFilename} \u2192 ${newFilename}`);
356
358
  return newPath;
357
359
  } catch (error) {
@@ -359,12 +361,13 @@ function renameSessionNote(notePath, meaningfulName) {
359
361
  return notePath;
360
362
  }
361
363
  }
364
+
365
+ // src/hooks/ts/lib/project-utils/tokens.ts
366
+ import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
362
367
  function calculateSessionTokens(jsonlPath) {
363
- if (!existsSync2(jsonlPath)) {
364
- return 0;
365
- }
368
+ if (!existsSync5(jsonlPath)) return 0;
366
369
  try {
367
- const content = readFileSync2(jsonlPath, "utf-8");
370
+ const content = readFileSync4(jsonlPath, "utf-8");
368
371
  const lines = content.trim().split("\n");
369
372
  let totalTokens = 0;
370
373
  for (const line of lines) {
@@ -386,27 +389,15 @@ function calculateSessionTokens(jsonlPath) {
386
389
  return 0;
387
390
  }
388
391
  }
389
- function findTodoPath(cwd) {
390
- const localPaths = [
391
- join2(cwd, "TODO.md"),
392
- join2(cwd, "notes", "TODO.md"),
393
- join2(cwd, "Notes", "TODO.md"),
394
- join2(cwd, ".claude", "TODO.md")
395
- ];
396
- for (const path of localPaths) {
397
- if (existsSync2(path)) {
398
- return path;
399
- }
400
- }
401
- return join2(getNotesDir(cwd), "TODO.md");
402
- }
392
+
393
+ // src/hooks/ts/lib/project-utils/todo.ts
394
+ import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
395
+ import { join as join5 } from "path";
403
396
  function ensureTodoMd(cwd) {
404
397
  const todoPath = findTodoPath(cwd);
405
- if (!existsSync2(todoPath)) {
406
- const parentDir = join2(todoPath, "..");
407
- if (!existsSync2(parentDir)) {
408
- mkdirSync(parentDir, { recursive: true });
409
- }
398
+ if (!existsSync6(todoPath)) {
399
+ const parentDir = join5(todoPath, "..");
400
+ if (!existsSync6(parentDir)) mkdirSync3(parentDir, { recursive: true });
410
401
  const content = `# TODO
411
402
 
412
403
  ## Current Session
@@ -421,17 +412,17 @@ function ensureTodoMd(cwd) {
421
412
 
422
413
  *Last updated: ${(/* @__PURE__ */ new Date()).toISOString()}*
423
414
  `;
424
- writeFileSync(todoPath, content);
415
+ writeFileSync2(todoPath, content);
425
416
  console.error(`Created TODO.md: ${todoPath}`);
426
417
  }
427
418
  return todoPath;
428
419
  }
429
420
  function updateTodoContinue(cwd, noteFilename, state, tokenDisplay) {
430
421
  const todoPath = ensureTodoMd(cwd);
431
- let content = readFileSync2(todoPath, "utf-8");
422
+ let content = readFileSync5(todoPath, "utf-8");
432
423
  content = content.replace(/## Continue\n[\s\S]*?\n---\n+/, "");
433
424
  const now = (/* @__PURE__ */ new Date()).toISOString();
434
- const stateLines = state ? state.split("\n").filter((l) => l.trim()).slice(0, 10).map((l) => `> ${l}`).join("\n") : `> Check the latest session note for details.`;
425
+ const stateLines = state ? state.split("\n").filter((l) => l.trim()).slice(0, 10).map((l) => `> ${l}`).join("\n") : `> Working directory: ${cwd}. Check the latest session note for details.`;
435
426
  const continueSection = `## Continue
436
427
 
437
428
  > **Last session:** ${noteFilename.replace(".md", "")}
@@ -456,7 +447,7 @@ ${stateLines}
456
447
 
457
448
  *Last updated: ${now}*
458
449
  `;
459
- writeFileSync(todoPath, content);
450
+ writeFileSync2(todoPath, content);
460
451
  console.error("TODO.md ## Continue section updated");
461
452
  }
462
453
 
@@ -475,7 +466,7 @@ function contentToText(content) {
475
466
  }
476
467
  function getTranscriptStats(transcriptPath) {
477
468
  try {
478
- const content = readFileSync3(transcriptPath, "utf-8");
469
+ const content = readFileSync6(transcriptPath, "utf-8");
479
470
  const lines = content.trim().split("\n");
480
471
  let userMessages = 0;
481
472
  let assistantMessages = 0;
@@ -504,7 +495,7 @@ function parseTranscript(transcriptPath) {
504
495
  workItems: []
505
496
  };
506
497
  try {
507
- const raw = readFileSync3(transcriptPath, "utf-8");
498
+ const raw = readFileSync6(transcriptPath, "utf-8");
508
499
  const lines = raw.trim().split("\n");
509
500
  const seenSummaries = /* @__PURE__ */ new Set();
510
501
  for (const line of lines) {
@@ -621,7 +612,7 @@ function deriveTitle(data) {
621
612
  }
622
613
  if (!title && data.filesModified.length > 0) {
623
614
  const basenames = data.filesModified.slice(-5).map((f) => {
624
- const b = basename2(f);
615
+ const b = basename3(f);
625
616
  return b.replace(/\.[^.]+$/, "");
626
617
  });
627
618
  const unique = [...new Set(basenames)];
@@ -632,9 +623,9 @@ function deriveTitle(data) {
632
623
  var CUMULATIVE_STATE_FILE = ".compact-state.json";
633
624
  function loadCumulativeState(notesDir) {
634
625
  try {
635
- const filePath = join3(notesDir, CUMULATIVE_STATE_FILE);
636
- if (!existsSync3(filePath)) return null;
637
- const raw = JSON.parse(readFileSync3(filePath, "utf-8"));
626
+ const filePath = join6(notesDir, CUMULATIVE_STATE_FILE);
627
+ if (!existsSync7(filePath)) return null;
628
+ const raw = JSON.parse(readFileSync6(filePath, "utf-8"));
638
629
  return {
639
630
  userMessages: raw.userMessages || [],
640
631
  summaries: raw.summaries || [],
@@ -666,8 +657,8 @@ function mergeTranscriptData(accumulated, current) {
666
657
  }
667
658
  function saveCumulativeState(notesDir, data, notePath) {
668
659
  try {
669
- const filePath = join3(notesDir, CUMULATIVE_STATE_FILE);
670
- writeFileSync2(filePath, JSON.stringify({
660
+ const filePath = join6(notesDir, CUMULATIVE_STATE_FILE);
661
+ writeFileSync3(filePath, JSON.stringify({
671
662
  ...data,
672
663
  notePath,
673
664
  lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
@@ -678,6 +669,9 @@ function saveCumulativeState(notesDir, data, notePath) {
678
669
  }
679
670
  }
680
671
  async function main() {
672
+ if (isProbeSession()) {
673
+ process.exit(0);
674
+ }
681
675
  let hookInput = null;
682
676
  try {
683
677
  const decoder = new TextDecoder();
@@ -705,9 +699,9 @@ async function main() {
705
699
  const data = parseTranscript(hookInput.transcript_path);
706
700
  let notesInfo;
707
701
  try {
708
- notesInfo = hookInput.cwd ? findNotesDir(hookInput.cwd) : { path: join3(dirname(hookInput.transcript_path), "Notes"), isLocal: false };
702
+ notesInfo = hookInput.cwd ? findNotesDir(hookInput.cwd) : { path: join6(dirname(hookInput.transcript_path), "Notes"), isLocal: false };
709
703
  } catch {
710
- notesInfo = { path: join3(dirname(hookInput.transcript_path), "Notes"), isLocal: false };
704
+ notesInfo = { path: join6(dirname(hookInput.transcript_path), "Notes"), isLocal: false };
711
705
  }
712
706
  const accumulated = loadCumulativeState(notesInfo.path);
713
707
  const merged = mergeTranscriptData(accumulated, data);
@@ -723,9 +717,9 @@ async function main() {
723
717
  notePath = createSessionNote(notesInfo.path, "Recovered Session");
724
718
  } else {
725
719
  try {
726
- const noteContent = readFileSync3(notePath, "utf-8");
720
+ const noteContent = readFileSync6(notePath, "utf-8");
727
721
  if (noteContent.includes("**Status:** Completed") || noteContent.includes("**Completed:**")) {
728
- console.error(`Latest note is completed (${basename2(notePath)}) \u2014 creating new one`);
722
+ console.error(`Latest note is completed (${basename3(notePath)}) \u2014 creating new one`);
729
723
  notePath = createSessionNote(notesInfo.path, "Continued Session");
730
724
  }
731
725
  } catch {
@@ -744,26 +738,26 @@ ${state}` : `Context compression triggered at ~${tokenDisplay} tokens with ${sta
744
738
  const newPath = renameSessionNote(notePath, title);
745
739
  if (newPath !== notePath) {
746
740
  try {
747
- let noteContent = readFileSync3(newPath, "utf-8");
741
+ let noteContent = readFileSync6(newPath, "utf-8");
748
742
  noteContent = noteContent.replace(
749
743
  /^(# Session \d+:)\s*.*$/m,
750
744
  `$1 ${title}`
751
745
  );
752
- writeFileSync2(newPath, noteContent);
746
+ writeFileSync3(newPath, noteContent);
753
747
  console.error(`Updated note H1 to match rename`);
754
748
  } catch {
755
749
  }
756
750
  notePath = newPath;
757
751
  }
758
752
  }
759
- console.error(`Rich checkpoint saved: ${basename2(notePath)}`);
753
+ console.error(`Rich checkpoint saved: ${basename3(notePath)}`);
760
754
  } catch (noteError) {
761
755
  console.error(`Could not save checkpoint: ${noteError}`);
762
756
  }
763
757
  saveCumulativeState(notesInfo.path, merged, notePath);
764
758
  if (hookInput.cwd && notePath) {
765
759
  try {
766
- const noteFilename = basename2(notePath);
760
+ const noteFilename = basename3(notePath);
767
761
  updateTodoContinue(hookInput.cwd, noteFilename, state, tokenDisplay);
768
762
  console.error("TODO.md ## Continue section updated");
769
763
  } catch (todoError) {
@@ -790,8 +784,8 @@ rename it based on actual work done and add a rich summary.` : "";
790
784
  "</system-reminder>"
791
785
  ].join("\n");
792
786
  try {
793
- const stateFile = join3(tmpdir(), `pai-compact-state-${hookInput.session_id}.txt`);
794
- writeFileSync2(stateFile, injection, "utf-8");
787
+ const stateFile = join6(tmpdir(), `pai-compact-state-${hookInput.session_id}.txt`);
788
+ writeFileSync3(stateFile, injection, "utf-8");
795
789
  console.error(`Session state saved to ${stateFile} (${injection.length} chars)`);
796
790
  } catch (err) {
797
791
  console.error(`Failed to save state file: ${err}`);