@codedeck/codedeck 2026.3.1-4.63

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 (239) hide show
  1. package/README.md +38 -0
  2. package/config/default.yaml +51 -0
  3. package/dist/agent/brain-dispatcher.d.ts +67 -0
  4. package/dist/agent/brain-dispatcher.d.ts.map +1 -0
  5. package/dist/agent/brain-dispatcher.js +136 -0
  6. package/dist/agent/brain-dispatcher.js.map +1 -0
  7. package/dist/agent/detect.d.ts +20 -0
  8. package/dist/agent/detect.d.ts.map +1 -0
  9. package/dist/agent/detect.js +187 -0
  10. package/dist/agent/detect.js.map +1 -0
  11. package/dist/agent/drivers/base.d.ts +57 -0
  12. package/dist/agent/drivers/base.d.ts.map +1 -0
  13. package/dist/agent/drivers/base.js +3 -0
  14. package/dist/agent/drivers/base.js.map +1 -0
  15. package/dist/agent/drivers/claude-code.d.ts +14 -0
  16. package/dist/agent/drivers/claude-code.d.ts.map +1 -0
  17. package/dist/agent/drivers/claude-code.js +112 -0
  18. package/dist/agent/drivers/claude-code.js.map +1 -0
  19. package/dist/agent/drivers/codex.d.ts +14 -0
  20. package/dist/agent/drivers/codex.d.ts.map +1 -0
  21. package/dist/agent/drivers/codex.js +77 -0
  22. package/dist/agent/drivers/codex.js.map +1 -0
  23. package/dist/agent/drivers/gemini.d.ts +24 -0
  24. package/dist/agent/drivers/gemini.d.ts.map +1 -0
  25. package/dist/agent/drivers/gemini.js +142 -0
  26. package/dist/agent/drivers/gemini.js.map +1 -0
  27. package/dist/agent/drivers/opencode.d.ts +18 -0
  28. package/dist/agent/drivers/opencode.d.ts.map +1 -0
  29. package/dist/agent/drivers/opencode.js +50 -0
  30. package/dist/agent/drivers/opencode.js.map +1 -0
  31. package/dist/agent/drivers/shell.d.ts +13 -0
  32. package/dist/agent/drivers/shell.d.ts.map +1 -0
  33. package/dist/agent/drivers/shell.js +30 -0
  34. package/dist/agent/drivers/shell.js.map +1 -0
  35. package/dist/agent/env-isolation.d.ts +26 -0
  36. package/dist/agent/env-isolation.d.ts.map +1 -0
  37. package/dist/agent/env-isolation.js +103 -0
  38. package/dist/agent/env-isolation.js.map +1 -0
  39. package/dist/agent/notify-setup.d.ts +18 -0
  40. package/dist/agent/notify-setup.d.ts.map +1 -0
  41. package/dist/agent/notify-setup.js +68 -0
  42. package/dist/agent/notify-setup.js.map +1 -0
  43. package/dist/agent/session-manager.d.ts +75 -0
  44. package/dist/agent/session-manager.d.ts.map +1 -0
  45. package/dist/agent/session-manager.js +407 -0
  46. package/dist/agent/session-manager.js.map +1 -0
  47. package/dist/agent/signal.d.ts +32 -0
  48. package/dist/agent/signal.d.ts.map +1 -0
  49. package/dist/agent/signal.js +199 -0
  50. package/dist/agent/signal.js.map +1 -0
  51. package/dist/agent/status-poller.d.ts +27 -0
  52. package/dist/agent/status-poller.d.ts.map +1 -0
  53. package/dist/agent/status-poller.js +76 -0
  54. package/dist/agent/status-poller.js.map +1 -0
  55. package/dist/agent/templates/brain-prompt.d.ts +14 -0
  56. package/dist/agent/templates/brain-prompt.d.ts.map +1 -0
  57. package/dist/agent/templates/brain-prompt.js +57 -0
  58. package/dist/agent/templates/brain-prompt.js.map +1 -0
  59. package/dist/agent/templates/identity.d.ts +19 -0
  60. package/dist/agent/templates/identity.d.ts.map +1 -0
  61. package/dist/agent/templates/identity.js +97 -0
  62. package/dist/agent/templates/identity.js.map +1 -0
  63. package/dist/agent/tmux.d.ts +90 -0
  64. package/dist/agent/tmux.d.ts.map +1 -0
  65. package/dist/agent/tmux.js +386 -0
  66. package/dist/agent/tmux.js.map +1 -0
  67. package/dist/autofix/audit-engine.d.ts +35 -0
  68. package/dist/autofix/audit-engine.d.ts.map +1 -0
  69. package/dist/autofix/audit-engine.js +144 -0
  70. package/dist/autofix/audit-engine.js.map +1 -0
  71. package/dist/autofix/branch-manager.d.ts +44 -0
  72. package/dist/autofix/branch-manager.d.ts.map +1 -0
  73. package/dist/autofix/branch-manager.js +97 -0
  74. package/dist/autofix/branch-manager.js.map +1 -0
  75. package/dist/autofix/decision-engine.d.ts +38 -0
  76. package/dist/autofix/decision-engine.d.ts.map +1 -0
  77. package/dist/autofix/decision-engine.js +115 -0
  78. package/dist/autofix/decision-engine.js.map +1 -0
  79. package/dist/autofix/index.d.ts +23 -0
  80. package/dist/autofix/index.d.ts.map +1 -0
  81. package/dist/autofix/index.js +192 -0
  82. package/dist/autofix/index.js.map +1 -0
  83. package/dist/autofix/prompt-builder.d.ts +25 -0
  84. package/dist/autofix/prompt-builder.d.ts.map +1 -0
  85. package/dist/autofix/prompt-builder.js +137 -0
  86. package/dist/autofix/prompt-builder.js.map +1 -0
  87. package/dist/autofix/report-parser.d.ts +18 -0
  88. package/dist/autofix/report-parser.d.ts.map +1 -0
  89. package/dist/autofix/report-parser.js +74 -0
  90. package/dist/autofix/report-parser.js.map +1 -0
  91. package/dist/autofix/state-machine.d.ts +40 -0
  92. package/dist/autofix/state-machine.d.ts.map +1 -0
  93. package/dist/autofix/state-machine.js +76 -0
  94. package/dist/autofix/state-machine.js.map +1 -0
  95. package/dist/bind/bind-flow.d.ts +15 -0
  96. package/dist/bind/bind-flow.d.ts.map +1 -0
  97. package/dist/bind/bind-flow.js +198 -0
  98. package/dist/bind/bind-flow.js.map +1 -0
  99. package/dist/config.d.ts +53 -0
  100. package/dist/config.d.ts.map +1 -0
  101. package/dist/config.js +89 -0
  102. package/dist/config.js.map +1 -0
  103. package/dist/daemon/codex-watcher.d.ts +46 -0
  104. package/dist/daemon/codex-watcher.d.ts.map +1 -0
  105. package/dist/daemon/codex-watcher.js +533 -0
  106. package/dist/daemon/codex-watcher.js.map +1 -0
  107. package/dist/daemon/command-handler.d.ts +6 -0
  108. package/dist/daemon/command-handler.d.ts.map +1 -0
  109. package/dist/daemon/command-handler.js +770 -0
  110. package/dist/daemon/command-handler.js.map +1 -0
  111. package/dist/daemon/discussion-orchestrator.d.ts +63 -0
  112. package/dist/daemon/discussion-orchestrator.d.ts.map +1 -0
  113. package/dist/daemon/discussion-orchestrator.js +482 -0
  114. package/dist/daemon/discussion-orchestrator.js.map +1 -0
  115. package/dist/daemon/gemini-watcher.d.ts +42 -0
  116. package/dist/daemon/gemini-watcher.d.ts.map +1 -0
  117. package/dist/daemon/gemini-watcher.js +463 -0
  118. package/dist/daemon/gemini-watcher.js.map +1 -0
  119. package/dist/daemon/hook-server.d.ts +42 -0
  120. package/dist/daemon/hook-server.d.ts.map +1 -0
  121. package/dist/daemon/hook-server.js +160 -0
  122. package/dist/daemon/hook-server.js.map +1 -0
  123. package/dist/daemon/jsonl-watcher.d.ts +35 -0
  124. package/dist/daemon/jsonl-watcher.d.ts.map +1 -0
  125. package/dist/daemon/jsonl-watcher.js +635 -0
  126. package/dist/daemon/jsonl-watcher.js.map +1 -0
  127. package/dist/daemon/lifecycle.d.ts +20 -0
  128. package/dist/daemon/lifecycle.d.ts.map +1 -0
  129. package/dist/daemon/lifecycle.js +331 -0
  130. package/dist/daemon/lifecycle.js.map +1 -0
  131. package/dist/daemon/server-link.d.ts +44 -0
  132. package/dist/daemon/server-link.d.ts.map +1 -0
  133. package/dist/daemon/server-link.js +232 -0
  134. package/dist/daemon/server-link.js.map +1 -0
  135. package/dist/daemon/subsession-manager.d.ts +37 -0
  136. package/dist/daemon/subsession-manager.d.ts.map +1 -0
  137. package/dist/daemon/subsession-manager.js +240 -0
  138. package/dist/daemon/subsession-manager.js.map +1 -0
  139. package/dist/daemon/terminal-parser.d.ts +42 -0
  140. package/dist/daemon/terminal-parser.d.ts.map +1 -0
  141. package/dist/daemon/terminal-parser.js +278 -0
  142. package/dist/daemon/terminal-parser.js.map +1 -0
  143. package/dist/daemon/terminal-streamer.d.ts +93 -0
  144. package/dist/daemon/terminal-streamer.d.ts.map +1 -0
  145. package/dist/daemon/terminal-streamer.js +451 -0
  146. package/dist/daemon/terminal-streamer.js.map +1 -0
  147. package/dist/daemon/timeline-emitter.d.ts +32 -0
  148. package/dist/daemon/timeline-emitter.d.ts.map +1 -0
  149. package/dist/daemon/timeline-emitter.js +97 -0
  150. package/dist/daemon/timeline-emitter.js.map +1 -0
  151. package/dist/daemon/timeline-event.d.ts +23 -0
  152. package/dist/daemon/timeline-event.d.ts.map +1 -0
  153. package/dist/daemon/timeline-event.js +7 -0
  154. package/dist/daemon/timeline-event.js.map +1 -0
  155. package/dist/daemon/timeline-store.d.ts +40 -0
  156. package/dist/daemon/timeline-store.d.ts.map +1 -0
  157. package/dist/daemon/timeline-store.js +153 -0
  158. package/dist/daemon/timeline-store.js.map +1 -0
  159. package/dist/index.d.ts +3 -0
  160. package/dist/index.d.ts.map +1 -0
  161. package/dist/index.js +149 -0
  162. package/dist/index.js.map +1 -0
  163. package/dist/memory/claude-mem.d.ts +9 -0
  164. package/dist/memory/claude-mem.d.ts.map +1 -0
  165. package/dist/memory/claude-mem.js +58 -0
  166. package/dist/memory/claude-mem.js.map +1 -0
  167. package/dist/memory/context-builder.d.ts +4 -0
  168. package/dist/memory/context-builder.d.ts.map +1 -0
  169. package/dist/memory/context-builder.js +35 -0
  170. package/dist/memory/context-builder.js.map +1 -0
  171. package/dist/memory/detector.d.ts +7 -0
  172. package/dist/memory/detector.d.ts.map +1 -0
  173. package/dist/memory/detector.js +17 -0
  174. package/dist/memory/detector.js.map +1 -0
  175. package/dist/memory/extractor.d.ts +21 -0
  176. package/dist/memory/extractor.d.ts.map +1 -0
  177. package/dist/memory/extractor.js +83 -0
  178. package/dist/memory/extractor.js.map +1 -0
  179. package/dist/memory/injector.d.ts +7 -0
  180. package/dist/memory/injector.d.ts.map +1 -0
  181. package/dist/memory/injector.js +18 -0
  182. package/dist/memory/injector.js.map +1 -0
  183. package/dist/memory/interface.d.ts +25 -0
  184. package/dist/memory/interface.d.ts.map +1 -0
  185. package/dist/memory/interface.js +3 -0
  186. package/dist/memory/interface.js.map +1 -0
  187. package/dist/memory/mem0.d.ts +12 -0
  188. package/dist/memory/mem0.d.ts.map +1 -0
  189. package/dist/memory/mem0.js +93 -0
  190. package/dist/memory/mem0.js.map +1 -0
  191. package/dist/router/command-parser.d.ts +33 -0
  192. package/dist/router/command-parser.d.ts.map +1 -0
  193. package/dist/router/command-parser.js +66 -0
  194. package/dist/router/command-parser.js.map +1 -0
  195. package/dist/router/message-router.d.ts +42 -0
  196. package/dist/router/message-router.d.ts.map +1 -0
  197. package/dist/router/message-router.js +222 -0
  198. package/dist/router/message-router.js.map +1 -0
  199. package/dist/router/response-collector.d.ts +28 -0
  200. package/dist/router/response-collector.d.ts.map +1 -0
  201. package/dist/router/response-collector.js +164 -0
  202. package/dist/router/response-collector.js.map +1 -0
  203. package/dist/store/project-store.d.ts +37 -0
  204. package/dist/store/project-store.d.ts.map +1 -0
  205. package/dist/store/project-store.js +70 -0
  206. package/dist/store/project-store.js.map +1 -0
  207. package/dist/store/session-store.d.ts +32 -0
  208. package/dist/store/session-store.d.ts.map +1 -0
  209. package/dist/store/session-store.js +67 -0
  210. package/dist/store/session-store.js.map +1 -0
  211. package/dist/tracker/branch.d.ts +24 -0
  212. package/dist/tracker/branch.d.ts.map +1 -0
  213. package/dist/tracker/branch.js +55 -0
  214. package/dist/tracker/branch.js.map +1 -0
  215. package/dist/tracker/github.d.ts +31 -0
  216. package/dist/tracker/github.d.ts.map +1 -0
  217. package/dist/tracker/github.js +117 -0
  218. package/dist/tracker/github.js.map +1 -0
  219. package/dist/tracker/gitlab.d.ts +31 -0
  220. package/dist/tracker/gitlab.d.ts.map +1 -0
  221. package/dist/tracker/gitlab.js +116 -0
  222. package/dist/tracker/gitlab.js.map +1 -0
  223. package/dist/tracker/index.d.ts +9 -0
  224. package/dist/tracker/index.d.ts.map +1 -0
  225. package/dist/tracker/index.js +28 -0
  226. package/dist/tracker/index.js.map +1 -0
  227. package/dist/tracker/interface.d.ts +39 -0
  228. package/dist/tracker/interface.d.ts.map +1 -0
  229. package/dist/tracker/interface.js +7 -0
  230. package/dist/tracker/interface.js.map +1 -0
  231. package/dist/tracker/priority.d.ts +19 -0
  232. package/dist/tracker/priority.d.ts.map +1 -0
  233. package/dist/tracker/priority.js +40 -0
  234. package/dist/tracker/priority.js.map +1 -0
  235. package/dist/util/logger.d.ts +4 -0
  236. package/dist/util/logger.d.ts.map +1 -0
  237. package/dist/util/logger.js +14 -0
  238. package/dist/util/logger.js.map +1 -0
  239. package/package.json +65 -0
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Watches Gemini CLI conversation JSON files for structured events.
3
+ *
4
+ * Gemini writes per-session JSON files (overwritten, not appended) to:
5
+ * ~/.gemini/tmp/<project-slug>/chats/session-<YYYY-MM-DD>T<HH>-<MM>-<uuid[:8]>.json
6
+ *
7
+ * Message types:
8
+ * - "user" → content: [{ text }] → user.message
9
+ * - "gemini" → content: string → assistant.text
10
+ * thoughts: [{ description }] → assistant.thinking
11
+ * toolCalls: [{ name, args }] → tool.call + tool.result
12
+ *
13
+ * Because the file is overwritten on each update (not appended), we track
14
+ * the seen message count and only process newly appended messages.
15
+ */
16
+ /**
17
+ * Snapshot all existing Gemini session files.
18
+ * Used before launching a new session so the watcher can detect which file is NEW.
19
+ */
20
+ export declare function snapshotSessionFiles(): Promise<Set<string>>;
21
+ /**
22
+ * Start watching a Gemini session by UUID.
23
+ * Polls for the session file to appear, then tails new messages.
24
+ */
25
+ export declare function startWatching(sessionName: string, sessionUuid: string): Promise<void>;
26
+ /**
27
+ * Start watching for the most recently modified Gemini session file.
28
+ * Used for sub-sessions launched without a pre-known UUID (e.g. `--resume latest`).
29
+ */
30
+ export declare function startWatchingLatest(sessionName: string): Promise<void>;
31
+ /**
32
+ * Start watching for a NEW Gemini session file that wasn't in the pre-launch snapshot.
33
+ * Used when resolveSessionId() failed and we launched fresh — detects the file by diffing
34
+ * against the snapshot taken before launch.
35
+ *
36
+ * @param onDiscovered Called with (sessionId, filePath) when the new file is found.
37
+ * Callers can persist the sessionId for future daemon restarts.
38
+ */
39
+ export declare function startWatchingNew(sessionName: string, existingFiles: Set<string>, onDiscovered?: (sessionId: string, filePath: string) => void): Promise<void>;
40
+ export declare function isWatching(sessionName: string): boolean;
41
+ export declare function stopWatching(sessionName: string): void;
42
+ //# sourceMappingURL=gemini-watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-watcher.d.ts","sourceRoot":"","sources":["../../src/daemon/gemini-watcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAsFH;;;GAGG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAejE;AA8ND;;;GAGG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoC3F;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,EAC1B,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,GAC3D,OAAO,CAAC,IAAI,CAAC,CAyEf;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAQtD"}
@@ -0,0 +1,463 @@
1
+ "use strict";
2
+ /**
3
+ * Watches Gemini CLI conversation JSON files for structured events.
4
+ *
5
+ * Gemini writes per-session JSON files (overwritten, not appended) to:
6
+ * ~/.gemini/tmp/<project-slug>/chats/session-<YYYY-MM-DD>T<HH>-<MM>-<uuid[:8]>.json
7
+ *
8
+ * Message types:
9
+ * - "user" → content: [{ text }] → user.message
10
+ * - "gemini" → content: string → assistant.text
11
+ * thoughts: [{ description }] → assistant.thinking
12
+ * toolCalls: [{ name, args }] → tool.call + tool.result
13
+ *
14
+ * Because the file is overwritten on each update (not appended), we track
15
+ * the seen message count and only process newly appended messages.
16
+ */
17
+ var __importDefault = (this && this.__importDefault) || function (mod) {
18
+ return (mod && mod.__esModule) ? mod : { "default": mod };
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.snapshotSessionFiles = snapshotSessionFiles;
22
+ exports.startWatching = startWatching;
23
+ exports.startWatchingLatest = startWatchingLatest;
24
+ exports.startWatchingNew = startWatchingNew;
25
+ exports.isWatching = isWatching;
26
+ exports.stopWatching = stopWatching;
27
+ const promises_1 = require("fs/promises");
28
+ const path_1 = require("path");
29
+ const os_1 = require("os");
30
+ const timeline_emitter_js_1 = require("./timeline-emitter.js");
31
+ const logger_js_1 = __importDefault(require("../util/logger.js"));
32
+ // ── Path helpers ───────────────────────────────────────────────────────────────
33
+ const GEMINI_TMP_DIR = (0, path_1.join)((0, os_1.homedir)(), '.gemini', 'tmp');
34
+ /**
35
+ * Find the conversation JSON file for a given session UUID.
36
+ * Filename format: session-<timestamp>-<uuid[:8]>.json
37
+ * Scans all project-slug subdirectories under ~/.gemini/tmp/.
38
+ */
39
+ async function findSessionFile(sessionUuid) {
40
+ const prefix = sessionUuid.slice(0, 8);
41
+ let slugs;
42
+ try {
43
+ slugs = await (0, promises_1.readdir)(GEMINI_TMP_DIR);
44
+ }
45
+ catch {
46
+ return null;
47
+ }
48
+ for (const slug of slugs) {
49
+ const chatsDir = (0, path_1.join)(GEMINI_TMP_DIR, slug, 'chats');
50
+ let entries;
51
+ try {
52
+ entries = await (0, promises_1.readdir)(chatsDir);
53
+ }
54
+ catch {
55
+ continue;
56
+ }
57
+ for (const entry of entries) {
58
+ if (entry.startsWith('session-') && entry.endsWith(`-${prefix}.json`)) {
59
+ return (0, path_1.join)(chatsDir, entry);
60
+ }
61
+ }
62
+ }
63
+ return null;
64
+ }
65
+ /**
66
+ * Find the most recently modified Gemini session file across all project slugs.
67
+ * Used when no UUID is known (e.g. sub-sessions launched with `--resume latest`).
68
+ * Excludes files already claimed by other watchers.
69
+ */
70
+ async function findLatestSessionFile(excludeClaimed = true) {
71
+ let slugs;
72
+ try {
73
+ slugs = await (0, promises_1.readdir)(GEMINI_TMP_DIR);
74
+ }
75
+ catch {
76
+ return null;
77
+ }
78
+ let bestPath = null;
79
+ let bestMtime = 0;
80
+ for (const slug of slugs) {
81
+ const chatsDir = (0, path_1.join)(GEMINI_TMP_DIR, slug, 'chats');
82
+ let entries;
83
+ try {
84
+ entries = await (0, promises_1.readdir)(chatsDir);
85
+ }
86
+ catch {
87
+ continue;
88
+ }
89
+ for (const entry of entries) {
90
+ if (!entry.startsWith('session-') || !entry.endsWith('.json'))
91
+ continue;
92
+ const fullPath = (0, path_1.join)(chatsDir, entry);
93
+ if (excludeClaimed && claimedFiles.has(fullPath))
94
+ continue;
95
+ try {
96
+ const s = await (0, promises_1.stat)(fullPath);
97
+ if (s.mtimeMs > bestMtime) {
98
+ bestMtime = s.mtimeMs;
99
+ bestPath = fullPath;
100
+ }
101
+ }
102
+ catch {
103
+ // ignore
104
+ }
105
+ }
106
+ }
107
+ return bestPath;
108
+ }
109
+ /**
110
+ * Snapshot all existing Gemini session files.
111
+ * Used before launching a new session so the watcher can detect which file is NEW.
112
+ */
113
+ async function snapshotSessionFiles() {
114
+ const files = new Set();
115
+ let slugs;
116
+ try {
117
+ slugs = await (0, promises_1.readdir)(GEMINI_TMP_DIR);
118
+ }
119
+ catch {
120
+ return files;
121
+ }
122
+ for (const slug of slugs) {
123
+ const chatsDir = (0, path_1.join)(GEMINI_TMP_DIR, slug, 'chats');
124
+ let entries;
125
+ try {
126
+ entries = await (0, promises_1.readdir)(chatsDir);
127
+ }
128
+ catch {
129
+ continue;
130
+ }
131
+ for (const entry of entries) {
132
+ if (entry.startsWith('session-') && entry.endsWith('.json')) {
133
+ files.add((0, path_1.join)(chatsDir, entry));
134
+ }
135
+ }
136
+ }
137
+ return files;
138
+ }
139
+ function parseMessage(sessionName, msg) {
140
+ if (msg.type === 'user') {
141
+ const blocks = Array.isArray(msg.content) ? msg.content : [];
142
+ for (const block of blocks) {
143
+ if (block.text?.trim()) {
144
+ timeline_emitter_js_1.timelineEmitter.emit(sessionName, 'user.message', { text: block.text }, { source: 'daemon', confidence: 'high' });
145
+ }
146
+ }
147
+ return;
148
+ }
149
+ if (msg.type === 'gemini') {
150
+ // Emit thinking blocks first
151
+ if (msg.thoughts) {
152
+ for (const t of msg.thoughts) {
153
+ const text = t.description ?? t.subject;
154
+ if (text?.trim()) {
155
+ timeline_emitter_js_1.timelineEmitter.emit(sessionName, 'assistant.thinking', { text }, { source: 'daemon', confidence: 'high' });
156
+ }
157
+ }
158
+ }
159
+ // Emit tool calls
160
+ if (msg.toolCalls) {
161
+ for (const tc of msg.toolCalls) {
162
+ if (!tc.name)
163
+ continue;
164
+ // Extract a short input summary
165
+ const input = extractToolInput(tc.name, tc.args);
166
+ timeline_emitter_js_1.timelineEmitter.emit(sessionName, 'tool.call', { tool: tc.name, ...(input ? { input } : {}) }, { source: 'daemon', confidence: 'high' });
167
+ // Emit tool result
168
+ const isError = tc.status === 'error';
169
+ const output = tc.result?.[0]?.functionResponse?.response?.output;
170
+ timeline_emitter_js_1.timelineEmitter.emit(sessionName, 'tool.result', { ...(isError ? { error: output ?? 'error' } : {}) }, { source: 'daemon', confidence: 'high' });
171
+ }
172
+ }
173
+ // Emit assistant text (final response string)
174
+ if (typeof msg.content === 'string' && msg.content.trim()) {
175
+ timeline_emitter_js_1.timelineEmitter.emit(sessionName, 'assistant.text', { text: msg.content, streaming: false }, { source: 'daemon', confidence: 'high' });
176
+ }
177
+ // Emit token usage + model for context bar
178
+ if (msg.tokens && typeof msg.tokens.input === 'number') {
179
+ timeline_emitter_js_1.timelineEmitter.emit(sessionName, 'usage.update', {
180
+ inputTokens: msg.tokens.input,
181
+ cacheTokens: msg.tokens.cached ?? 0,
182
+ contextWindow: 1_000_000,
183
+ ...(msg.model ? { model: msg.model } : {}),
184
+ }, { source: 'daemon', confidence: 'high' });
185
+ }
186
+ }
187
+ }
188
+ function extractToolInput(name, args) {
189
+ if (!args)
190
+ return '';
191
+ // Common Gemini built-in tools
192
+ switch (name) {
193
+ case 'read_file': return String(args['path'] ?? args['file_path'] ?? '');
194
+ case 'write_file': return String(args['path'] ?? args['file_path'] ?? '');
195
+ case 'run_shell_command': return String(args['command'] ?? '').split('\n')[0] ?? '';
196
+ case 'search_files': return String(args['pattern'] ?? args['query'] ?? '');
197
+ case 'list_directory': return String(args['path'] ?? '');
198
+ default: {
199
+ // Try common keys
200
+ const val = args['command'] ?? args['path'] ?? args['query'] ?? args['objective'] ?? '';
201
+ return String(val).split('\n')[0] ?? '';
202
+ }
203
+ }
204
+ }
205
+ const watchers = new Map();
206
+ /** Files already claimed by a watcher — prevents two watchers from tracking the same file */
207
+ const claimedFiles = new Set();
208
+ // ── Core poll logic ────────────────────────────────────────────────────────────
209
+ async function readConversation(filePath) {
210
+ try {
211
+ const { readFile } = await import('fs/promises');
212
+ const raw = await readFile(filePath, 'utf8');
213
+ return JSON.parse(raw);
214
+ }
215
+ catch {
216
+ return null;
217
+ }
218
+ }
219
+ async function pollTick(sessionName, state) {
220
+ // Try to find the file if we don't have it yet
221
+ if (!state.activeFile) {
222
+ const found = state.sessionUuid
223
+ ? await findSessionFile(state.sessionUuid)
224
+ : await findLatestSessionFile();
225
+ if (found) {
226
+ state.activeFile = found;
227
+ claimedFiles.add(found);
228
+ logger_js_1.default.debug({ sessionName, file: found }, 'gemini-watcher: found session file');
229
+ }
230
+ else {
231
+ return;
232
+ }
233
+ }
234
+ const conv = await readConversation(state.activeFile);
235
+ if (!conv)
236
+ return;
237
+ // No new messages
238
+ if (conv.messages.length <= state.seenCount)
239
+ return;
240
+ // No change in lastUpdated for same count (shouldn't happen but be safe)
241
+ if (conv.lastUpdated === state.lastUpdated && conv.messages.length === state.seenCount)
242
+ return;
243
+ const newMessages = conv.messages.slice(state.seenCount);
244
+ state.seenCount = conv.messages.length;
245
+ state.lastUpdated = conv.lastUpdated;
246
+ // Emit running when new activity starts
247
+ if (!state.emittedRunning) {
248
+ state.emittedRunning = true;
249
+ timeline_emitter_js_1.timelineEmitter.emit(sessionName, 'session.state', { state: 'running' });
250
+ }
251
+ for (const msg of newMessages) {
252
+ if (state.stopped)
253
+ break;
254
+ parseMessage(sessionName, msg);
255
+ // Idle detection: a gemini message WITHOUT toolCalls is the final response
256
+ // in a turn — the agent is done and waiting for user input.
257
+ if (msg.type === 'gemini' && !msg.toolCalls?.length) {
258
+ state.emittedRunning = false;
259
+ timeline_emitter_js_1.timelineEmitter.emit(sessionName, 'session.state', { state: 'idle' });
260
+ }
261
+ }
262
+ }
263
+ // ── History replay ─────────────────────────────────────────────────────────────
264
+ async function emitRecentHistory(sessionName, filePath) {
265
+ const conv = await readConversation(filePath);
266
+ if (!conv)
267
+ return;
268
+ const HISTORY_MAX = 100;
269
+ const slice = conv.messages.slice(-HISTORY_MAX);
270
+ for (const msg of slice) {
271
+ parseMessage(sessionName, msg);
272
+ }
273
+ }
274
+ // ── Public API ─────────────────────────────────────────────────────────────────
275
+ /**
276
+ * Start watching a Gemini session by UUID.
277
+ * Polls for the session file to appear, then tails new messages.
278
+ */
279
+ async function startWatching(sessionName, sessionUuid) {
280
+ if (watchers.has(sessionName)) {
281
+ stopWatching(sessionName);
282
+ }
283
+ const state = {
284
+ sessionUuid,
285
+ activeFile: null,
286
+ seenCount: 0,
287
+ lastUpdated: '',
288
+ abort: new AbortController(),
289
+ stopped: false,
290
+ };
291
+ watchers.set(sessionName, state);
292
+ // Try to find the file immediately
293
+ const found = await findSessionFile(sessionUuid);
294
+ if (found) {
295
+ state.activeFile = found;
296
+ claimedFiles.add(found);
297
+ const conv = await readConversation(found);
298
+ if (conv) {
299
+ // Start from end so we only emit new messages going forward
300
+ state.seenCount = conv.messages.length;
301
+ state.lastUpdated = conv.lastUpdated;
302
+ await emitRecentHistory(sessionName, found);
303
+ }
304
+ }
305
+ // Poll every 2s as reliable fallback
306
+ state.pollTimer = setInterval(() => {
307
+ void pollTick(sessionName, state);
308
+ }, 2000);
309
+ // Also watch the gemini tmp dir for faster notification
310
+ void watchGeminiDir(sessionName, state);
311
+ }
312
+ /**
313
+ * Start watching for the most recently modified Gemini session file.
314
+ * Used for sub-sessions launched without a pre-known UUID (e.g. `--resume latest`).
315
+ */
316
+ async function startWatchingLatest(sessionName) {
317
+ return startWatching(sessionName, '');
318
+ }
319
+ /**
320
+ * Start watching for a NEW Gemini session file that wasn't in the pre-launch snapshot.
321
+ * Used when resolveSessionId() failed and we launched fresh — detects the file by diffing
322
+ * against the snapshot taken before launch.
323
+ *
324
+ * @param onDiscovered Called with (sessionId, filePath) when the new file is found.
325
+ * Callers can persist the sessionId for future daemon restarts.
326
+ */
327
+ async function startWatchingNew(sessionName, existingFiles, onDiscovered) {
328
+ if (watchers.has(sessionName)) {
329
+ stopWatching(sessionName);
330
+ }
331
+ const state = {
332
+ sessionUuid: '',
333
+ activeFile: null,
334
+ seenCount: 0,
335
+ lastUpdated: '',
336
+ abort: new AbortController(),
337
+ stopped: false,
338
+ };
339
+ watchers.set(sessionName, state);
340
+ // Poll for a new file that wasn't in the snapshot
341
+ const findNewFile = async () => {
342
+ let slugs;
343
+ try {
344
+ slugs = await (0, promises_1.readdir)(GEMINI_TMP_DIR);
345
+ }
346
+ catch {
347
+ return null;
348
+ }
349
+ let bestPath = null;
350
+ let bestMtime = 0;
351
+ for (const slug of slugs) {
352
+ const chatsDir = (0, path_1.join)(GEMINI_TMP_DIR, slug, 'chats');
353
+ let entries;
354
+ try {
355
+ entries = await (0, promises_1.readdir)(chatsDir);
356
+ }
357
+ catch {
358
+ continue;
359
+ }
360
+ for (const entry of entries) {
361
+ if (!entry.startsWith('session-') || !entry.endsWith('.json'))
362
+ continue;
363
+ const fullPath = (0, path_1.join)(chatsDir, entry);
364
+ if (existingFiles.has(fullPath))
365
+ continue; // existed before launch
366
+ if (claimedFiles.has(fullPath))
367
+ continue; // claimed by another watcher
368
+ try {
369
+ const s = await (0, promises_1.stat)(fullPath);
370
+ if (s.mtimeMs > bestMtime) {
371
+ bestMtime = s.mtimeMs;
372
+ bestPath = fullPath;
373
+ }
374
+ }
375
+ catch { /* ignore */ }
376
+ }
377
+ }
378
+ return bestPath;
379
+ };
380
+ // Try to find the new file (may take a few seconds for Gemini to create it)
381
+ for (let i = 0; i < 60 && !state.stopped; i++) {
382
+ const found = await findNewFile();
383
+ if (found) {
384
+ state.activeFile = found;
385
+ claimedFiles.add(found);
386
+ logger_js_1.default.info({ sessionName, file: found }, 'gemini-watcher: found new session file via snapshot diff');
387
+ // Read sessionId from JSON and notify caller
388
+ const conv = await readConversation(found);
389
+ if (conv) {
390
+ state.seenCount = conv.messages.length;
391
+ state.lastUpdated = conv.lastUpdated;
392
+ await emitRecentHistory(sessionName, found);
393
+ if (conv.sessionId && onDiscovered) {
394
+ onDiscovered(conv.sessionId, found);
395
+ }
396
+ }
397
+ break;
398
+ }
399
+ await new Promise((r) => setTimeout(r, 2000));
400
+ }
401
+ // Start polling
402
+ state.pollTimer = setInterval(() => {
403
+ void pollTick(sessionName, state);
404
+ }, 2000);
405
+ if (state.activeFile) {
406
+ void watchGeminiDir(sessionName, state);
407
+ }
408
+ }
409
+ function isWatching(sessionName) {
410
+ return watchers.has(sessionName);
411
+ }
412
+ function stopWatching(sessionName) {
413
+ const state = watchers.get(sessionName);
414
+ if (!state)
415
+ return;
416
+ if (state.activeFile)
417
+ claimedFiles.delete(state.activeFile);
418
+ state.stopped = true;
419
+ state.abort.abort();
420
+ if (state.pollTimer)
421
+ clearInterval(state.pollTimer);
422
+ watchers.delete(sessionName);
423
+ }
424
+ // ── fs.watch for faster updates ────────────────────────────────────────────────
425
+ async function watchGeminiDir(sessionName, state) {
426
+ // Watch ~/.gemini/tmp for new slug directories / file changes
427
+ // When activeFile is known, watch its parent dir directly
428
+ const waitForFile = async () => {
429
+ for (let i = 0; i < 60 && !state.stopped; i++) {
430
+ const found = state.sessionUuid
431
+ ? await findSessionFile(state.sessionUuid)
432
+ : await findLatestSessionFile();
433
+ if (found)
434
+ return found;
435
+ await new Promise((r) => setTimeout(r, 1000));
436
+ }
437
+ return null;
438
+ };
439
+ if (!state.activeFile) {
440
+ const found = await waitForFile();
441
+ if (!found || state.stopped)
442
+ return;
443
+ state.activeFile = found;
444
+ }
445
+ const dir = state.activeFile.substring(0, state.activeFile.lastIndexOf('/'));
446
+ const filename = state.activeFile.substring(state.activeFile.lastIndexOf('/') + 1);
447
+ try {
448
+ const watcher = (0, promises_1.watch)(dir, { persistent: false, signal: state.abort.signal });
449
+ for await (const event of watcher) {
450
+ if (state.stopped)
451
+ break;
452
+ if (event.filename !== filename)
453
+ continue;
454
+ await pollTick(sessionName, state);
455
+ }
456
+ }
457
+ catch (err) {
458
+ if (!state.stopped) {
459
+ logger_js_1.default.debug({ sessionName, err }, 'gemini-watcher: dir watch error');
460
+ }
461
+ }
462
+ }
463
+ //# sourceMappingURL=gemini-watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-watcher.js","sourceRoot":"","sources":["../../src/daemon/gemini-watcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Local HTTP server for agent hook callbacks.
3
+ *
4
+ * POST /notify { event: "idle"|"notification"|"tool_start"|"tool_end", session, ... }
5
+ *
6
+ * Port selection:
7
+ * 1. Load persisted port from ~/.codedeck/hook-port (remembered across restarts)
8
+ * 2. Try to bind; if EADDRINUSE, increment and retry (up to 20 attempts)
9
+ * 3. Save the successfully bound port back to the file
10
+ *
11
+ * After startHookServer() resolves, `activeHookPort` holds the actual port.
12
+ * All hook scripts and plugins read this value at write time.
13
+ */
14
+ import http from 'http';
15
+ export declare const DEFAULT_HOOK_PORT = 51913;
16
+ /** The port the hook server is currently listening on. Set after startHookServer() resolves. */
17
+ export declare let activeHookPort: number;
18
+ export type HookPayload = {
19
+ event: 'idle';
20
+ session: string;
21
+ agentType: string;
22
+ } | {
23
+ event: 'notification';
24
+ session: string;
25
+ title: string;
26
+ message: string;
27
+ } | {
28
+ event: 'tool_start';
29
+ session: string;
30
+ tool: string;
31
+ } | {
32
+ event: 'tool_end';
33
+ session: string;
34
+ };
35
+ export type HookCallback = (payload: HookPayload) => void;
36
+ /** @deprecated Use HookCallback instead */
37
+ export type IdleCallback = (sessionName: string, agentType: string) => void;
38
+ export declare function startHookServer(onHook: HookCallback): Promise<{
39
+ server: http.Server;
40
+ port: number;
41
+ }>;
42
+ //# sourceMappingURL=hook-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-server.d.ts","sourceRoot":"","sources":["../../src/daemon/hook-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,IAAI,MAAM,MAAM,CAAC;AAOxB,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AAGvC,gGAAgG;AAChG,eAAO,IAAI,cAAc,EAAE,MAA0B,CAAC;AAEtD,MAAM,MAAM,WAAW,GACnB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,KAAK,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC1E;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3C,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;AAE1D,2CAA2C;AAC3C,MAAM,MAAM,YAAY,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;AAiD5E,wBAAsB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAiF1G"}