skein-cli 0.1.0-alpha.1

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 (250) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +180 -0
  3. package/bin/skein.mjs +7 -0
  4. package/dist/adapters/aider/conv-reader.d.ts +7 -0
  5. package/dist/adapters/aider/conv-reader.js +203 -0
  6. package/dist/adapters/aider/conv-reader.js.map +1 -0
  7. package/dist/adapters/aider/index.d.ts +2 -0
  8. package/dist/adapters/aider/index.js +123 -0
  9. package/dist/adapters/aider/index.js.map +1 -0
  10. package/dist/adapters/base.d.ts +71 -0
  11. package/dist/adapters/base.js +38 -0
  12. package/dist/adapters/base.js.map +1 -0
  13. package/dist/adapters/claude-code/conv-reader.d.ts +2 -0
  14. package/dist/adapters/claude-code/conv-reader.js +155 -0
  15. package/dist/adapters/claude-code/conv-reader.js.map +1 -0
  16. package/dist/adapters/claude-code/index.d.ts +3 -0
  17. package/dist/adapters/claude-code/index.js +517 -0
  18. package/dist/adapters/claude-code/index.js.map +1 -0
  19. package/dist/adapters/claude-desktop/index.d.ts +2 -0
  20. package/dist/adapters/claude-desktop/index.js +95 -0
  21. package/dist/adapters/claude-desktop/index.js.map +1 -0
  22. package/dist/adapters/codex/index.d.ts +2 -0
  23. package/dist/adapters/codex/index.js +472 -0
  24. package/dist/adapters/codex/index.js.map +1 -0
  25. package/dist/adapters/cursor/index.d.ts +2 -0
  26. package/dist/adapters/cursor/index.js +255 -0
  27. package/dist/adapters/cursor/index.js.map +1 -0
  28. package/dist/adapters/opencode/conv-reader.d.ts +3 -0
  29. package/dist/adapters/opencode/conv-reader.js +190 -0
  30. package/dist/adapters/opencode/conv-reader.js.map +1 -0
  31. package/dist/adapters/opencode/index.d.ts +2 -0
  32. package/dist/adapters/opencode/index.js +349 -0
  33. package/dist/adapters/opencode/index.js.map +1 -0
  34. package/dist/adapters/registry.d.ts +4 -0
  35. package/dist/adapters/registry.js +26 -0
  36. package/dist/adapters/registry.js.map +1 -0
  37. package/dist/cli.d.ts +3 -0
  38. package/dist/cli.js +54 -0
  39. package/dist/cli.js.map +1 -0
  40. package/dist/commands/conv.d.ts +2 -0
  41. package/dist/commands/conv.js +261 -0
  42. package/dist/commands/conv.js.map +1 -0
  43. package/dist/commands/doctor.d.ts +2 -0
  44. package/dist/commands/doctor.js +85 -0
  45. package/dist/commands/doctor.js.map +1 -0
  46. package/dist/commands/init.d.ts +2 -0
  47. package/dist/commands/init.js +38 -0
  48. package/dist/commands/init.js.map +1 -0
  49. package/dist/commands/memory.d.ts +2 -0
  50. package/dist/commands/memory.js +197 -0
  51. package/dist/commands/memory.js.map +1 -0
  52. package/dist/commands/migrate.d.ts +2 -0
  53. package/dist/commands/migrate.js +102 -0
  54. package/dist/commands/migrate.js.map +1 -0
  55. package/dist/commands/profile.d.ts +2 -0
  56. package/dist/commands/profile.js +183 -0
  57. package/dist/commands/profile.js.map +1 -0
  58. package/dist/commands/redact.d.ts +2 -0
  59. package/dist/commands/redact.js +73 -0
  60. package/dist/commands/redact.js.map +1 -0
  61. package/dist/commands/trace.d.ts +2 -0
  62. package/dist/commands/trace.js +181 -0
  63. package/dist/commands/trace.js.map +1 -0
  64. package/dist/commands/view.d.ts +13 -0
  65. package/dist/commands/view.js +184 -0
  66. package/dist/commands/view.js.map +1 -0
  67. package/dist/commands/watch.d.ts +6 -0
  68. package/dist/commands/watch.js +61 -0
  69. package/dist/commands/watch.js.map +1 -0
  70. package/dist/commands/wrap.d.ts +2 -0
  71. package/dist/commands/wrap.js +131 -0
  72. package/dist/commands/wrap.js.map +1 -0
  73. package/dist/conv/chatgpt-import.d.ts +33 -0
  74. package/dist/conv/chatgpt-import.js +145 -0
  75. package/dist/conv/chatgpt-import.js.map +1 -0
  76. package/dist/conv/cursor.d.ts +12 -0
  77. package/dist/conv/cursor.js +55 -0
  78. package/dist/conv/cursor.js.map +1 -0
  79. package/dist/conv/export.d.ts +40 -0
  80. package/dist/conv/export.js +215 -0
  81. package/dist/conv/export.js.map +1 -0
  82. package/dist/conv/replay/aider.d.ts +24 -0
  83. package/dist/conv/replay/aider.js +56 -0
  84. package/dist/conv/replay/aider.js.map +1 -0
  85. package/dist/conv/replay/claude-code.d.ts +38 -0
  86. package/dist/conv/replay/claude-code.js +80 -0
  87. package/dist/conv/replay/claude-code.js.map +1 -0
  88. package/dist/conv/replay/context.d.ts +25 -0
  89. package/dist/conv/replay/context.js +63 -0
  90. package/dist/conv/replay/context.js.map +1 -0
  91. package/dist/conv/replay/index.d.ts +22 -0
  92. package/dist/conv/replay/index.js +84 -0
  93. package/dist/conv/replay/index.js.map +1 -0
  94. package/dist/conv/search.d.ts +67 -0
  95. package/dist/conv/search.js +379 -0
  96. package/dist/conv/search.js.map +1 -0
  97. package/dist/conv/sink.d.ts +26 -0
  98. package/dist/conv/sink.js +76 -0
  99. package/dist/conv/sink.js.map +1 -0
  100. package/dist/conv/sources/aider.d.ts +13 -0
  101. package/dist/conv/sources/aider.js +95 -0
  102. package/dist/conv/sources/aider.js.map +1 -0
  103. package/dist/conv/sources/claude-code.d.ts +13 -0
  104. package/dist/conv/sources/claude-code.js +189 -0
  105. package/dist/conv/sources/claude-code.js.map +1 -0
  106. package/dist/conv/sources/codex.d.ts +15 -0
  107. package/dist/conv/sources/codex.js +175 -0
  108. package/dist/conv/sources/codex.js.map +1 -0
  109. package/dist/conv/sources/opencode.d.ts +12 -0
  110. package/dist/conv/sources/opencode.js +92 -0
  111. package/dist/conv/sources/opencode.js.map +1 -0
  112. package/dist/conv/store.d.ts +10 -0
  113. package/dist/conv/store.js +75 -0
  114. package/dist/conv/store.js.map +1 -0
  115. package/dist/conv/title.d.ts +9 -0
  116. package/dist/conv/title.js +74 -0
  117. package/dist/conv/title.js.map +1 -0
  118. package/dist/conv/watcher.d.ts +28 -0
  119. package/dist/conv/watcher.js +75 -0
  120. package/dist/conv/watcher.js.map +1 -0
  121. package/dist/conv/zip.d.ts +11 -0
  122. package/dist/conv/zip.js +82 -0
  123. package/dist/conv/zip.js.map +1 -0
  124. package/dist/hf/client.d.ts +41 -0
  125. package/dist/hf/client.js +87 -0
  126. package/dist/hf/client.js.map +1 -0
  127. package/dist/index.d.ts +5 -0
  128. package/dist/index.js +6 -0
  129. package/dist/index.js.map +1 -0
  130. package/dist/ir/index.d.ts +24 -0
  131. package/dist/ir/index.js +23 -0
  132. package/dist/ir/index.js.map +1 -0
  133. package/dist/ir/profile.d.ts +55 -0
  134. package/dist/ir/profile.js +177 -0
  135. package/dist/ir/profile.js.map +1 -0
  136. package/dist/memory/index.d.ts +41 -0
  137. package/dist/memory/index.js +109 -0
  138. package/dist/memory/index.js.map +1 -0
  139. package/dist/memory/search.d.ts +24 -0
  140. package/dist/memory/search.js +114 -0
  141. package/dist/memory/search.js.map +1 -0
  142. package/dist/memory/sinks/claude-mem.d.ts +13 -0
  143. package/dist/memory/sinks/claude-mem.js +100 -0
  144. package/dist/memory/sinks/claude-mem.js.map +1 -0
  145. package/dist/memory/sinks/codex.d.ts +12 -0
  146. package/dist/memory/sinks/codex.js +82 -0
  147. package/dist/memory/sinks/codex.js.map +1 -0
  148. package/dist/memory/sinks/context.d.ts +21 -0
  149. package/dist/memory/sinks/context.js +42 -0
  150. package/dist/memory/sinks/context.js.map +1 -0
  151. package/dist/memory/sources/chatgpt.d.ts +22 -0
  152. package/dist/memory/sources/chatgpt.js +98 -0
  153. package/dist/memory/sources/chatgpt.js.map +1 -0
  154. package/dist/memory/sources/claude-mem.d.ts +8 -0
  155. package/dist/memory/sources/claude-mem.js +104 -0
  156. package/dist/memory/sources/claude-mem.js.map +1 -0
  157. package/dist/memory/sources/codex.d.ts +8 -0
  158. package/dist/memory/sources/codex.js +77 -0
  159. package/dist/memory/sources/codex.js.map +1 -0
  160. package/dist/memory/store.d.ts +19 -0
  161. package/dist/memory/store.js +82 -0
  162. package/dist/memory/store.js.map +1 -0
  163. package/dist/proxy/http.d.ts +21 -0
  164. package/dist/proxy/http.js +205 -0
  165. package/dist/proxy/http.js.map +1 -0
  166. package/dist/proxy/recorder.d.ts +35 -0
  167. package/dist/proxy/recorder.js +221 -0
  168. package/dist/proxy/recorder.js.map +1 -0
  169. package/dist/proxy/streaming.d.ts +33 -0
  170. package/dist/proxy/streaming.js +185 -0
  171. package/dist/proxy/streaming.js.map +1 -0
  172. package/dist/redactor/entropy.d.ts +29 -0
  173. package/dist/redactor/entropy.js +98 -0
  174. package/dist/redactor/entropy.js.map +1 -0
  175. package/dist/redactor/index.d.ts +52 -0
  176. package/dist/redactor/index.js +152 -0
  177. package/dist/redactor/index.js.map +1 -0
  178. package/dist/redactor/ner.d.ts +53 -0
  179. package/dist/redactor/ner.js +97 -0
  180. package/dist/redactor/ner.js.map +1 -0
  181. package/dist/redactor/pii-patterns.d.ts +22 -0
  182. package/dist/redactor/pii-patterns.js +187 -0
  183. package/dist/redactor/pii-patterns.js.map +1 -0
  184. package/dist/redactor/secret-patterns.d.ts +27 -0
  185. package/dist/redactor/secret-patterns.js +475 -0
  186. package/dist/redactor/secret-patterns.js.map +1 -0
  187. package/dist/schema/conv.d.ts +698 -0
  188. package/dist/schema/conv.js +85 -0
  189. package/dist/schema/conv.js.map +1 -0
  190. package/dist/schema/index.d.ts +2 -0
  191. package/dist/schema/index.js +3 -0
  192. package/dist/schema/index.js.map +1 -0
  193. package/dist/schema/manifest.d.ts +1531 -0
  194. package/dist/schema/manifest.js +179 -0
  195. package/dist/schema/manifest.js.map +1 -0
  196. package/dist/schema/memory.d.ts +107 -0
  197. package/dist/schema/memory.js +45 -0
  198. package/dist/schema/memory.js.map +1 -0
  199. package/dist/schema/trace.d.ts +164 -0
  200. package/dist/schema/trace.js +89 -0
  201. package/dist/schema/trace.js.map +1 -0
  202. package/dist/trace/consent.d.ts +30 -0
  203. package/dist/trace/consent.js +60 -0
  204. package/dist/trace/consent.js.map +1 -0
  205. package/dist/trace/extract.d.ts +22 -0
  206. package/dist/trace/extract.js +168 -0
  207. package/dist/trace/extract.js.map +1 -0
  208. package/dist/trace/ml-pii.d.ts +33 -0
  209. package/dist/trace/ml-pii.js +35 -0
  210. package/dist/trace/ml-pii.js.map +1 -0
  211. package/dist/trace/push.d.ts +59 -0
  212. package/dist/trace/push.js +141 -0
  213. package/dist/trace/push.js.map +1 -0
  214. package/dist/trace/serialize.d.ts +23 -0
  215. package/dist/trace/serialize.js +67 -0
  216. package/dist/trace/serialize.js.map +1 -0
  217. package/dist/ui/banner.d.ts +2 -0
  218. package/dist/ui/banner.js +17 -0
  219. package/dist/ui/banner.js.map +1 -0
  220. package/dist/ui/box.d.ts +4 -0
  221. package/dist/ui/box.js +38 -0
  222. package/dist/ui/box.js.map +1 -0
  223. package/dist/ui/index.d.ts +5 -0
  224. package/dist/ui/index.js +5 -0
  225. package/dist/ui/index.js.map +1 -0
  226. package/dist/ui/spinner.d.ts +10 -0
  227. package/dist/ui/spinner.js +44 -0
  228. package/dist/ui/spinner.js.map +1 -0
  229. package/dist/ui/table.d.ts +9 -0
  230. package/dist/ui/table.js +55 -0
  231. package/dist/ui/table.js.map +1 -0
  232. package/dist/util/frontmatter.d.ts +6 -0
  233. package/dist/util/frontmatter.js +20 -0
  234. package/dist/util/frontmatter.js.map +1 -0
  235. package/dist/util/fs.d.ts +5 -0
  236. package/dist/util/fs.js +41 -0
  237. package/dist/util/fs.js.map +1 -0
  238. package/dist/util/ids.d.ts +3 -0
  239. package/dist/util/ids.js +16 -0
  240. package/dist/util/ids.js.map +1 -0
  241. package/dist/util/log.d.ts +13 -0
  242. package/dist/util/log.js +33 -0
  243. package/dist/util/log.js.map +1 -0
  244. package/dist/util/paths.d.ts +18 -0
  245. package/dist/util/paths.js +36 -0
  246. package/dist/util/paths.js.map +1 -0
  247. package/dist/version.d.ts +5 -0
  248. package/dist/version.js +32 -0
  249. package/dist/version.js.map +1 -0
  250. package/package.json +86 -0
@@ -0,0 +1,76 @@
1
+ import { createWriteStream } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { CONV_SCHEMA } from '../version.js';
4
+ import { ensureDir, exists } from '../util/fs.js';
5
+ import { getToolPaths, SKEIN_SUBDIRS } from '../util/paths.js';
6
+ import { redactText } from '../redactor/index.js';
7
+ export class JsonlSink {
8
+ streams = new Map();
9
+ /**
10
+ * Make sure a session JSONL is open. If the file does not yet exist,
11
+ * a `session.start` event is emitted with the provided metadata.
12
+ */
13
+ async openSession(sessionId, opts) {
14
+ if (this.streams.has(sessionId))
15
+ return;
16
+ const month = monthSlug(opts.startedAt);
17
+ const paths = getToolPaths();
18
+ const dir = join(paths.skeinDir, SKEIN_SUBDIRS.convSessions, month);
19
+ await ensureDir(dir);
20
+ const path = join(dir, `${sanitize(sessionId)}.jsonl`);
21
+ const fileExisted = await exists(path);
22
+ const stream = createWriteStream(path, { flags: 'a' });
23
+ this.streams.set(sessionId, { path, stream, startedAt: opts.startedAt });
24
+ if (!fileExisted) {
25
+ const startEvent = {
26
+ type: 'session.start',
27
+ id: sessionId,
28
+ tool: opts.tool,
29
+ ...(opts.toolVersion ? { toolVersion: opts.toolVersion } : {}),
30
+ ...(opts.model ? { model: opts.model } : {}),
31
+ ...(opts.modelKind ? { modelKind: opts.modelKind } : {}),
32
+ ...(opts.provider ? { provider: opts.provider } : {}),
33
+ ...(opts.effort ? { effort: opts.effort } : {}),
34
+ ...(opts.project ? { project: opts.project } : {}),
35
+ ...(opts.title ? { title: opts.title } : {}),
36
+ schema: CONV_SCHEMA,
37
+ ts: opts.startedAt,
38
+ };
39
+ await this.write(sessionId, startEvent);
40
+ }
41
+ }
42
+ async write(sessionId, event) {
43
+ const open = this.streams.get(sessionId);
44
+ if (!open) {
45
+ throw new Error(`JsonlSink: session ${sessionId} not opened — call openSession first`);
46
+ }
47
+ const line = `${redactText(JSON.stringify(event)).text}\n`;
48
+ await new Promise((resolve, reject) => open.stream.write(line, err => (err ? reject(err) : resolve())));
49
+ }
50
+ async close(sessionId) {
51
+ const open = this.streams.get(sessionId);
52
+ if (!open)
53
+ return;
54
+ this.streams.delete(sessionId);
55
+ await new Promise(resolve => open.stream.end(resolve));
56
+ }
57
+ async closeAll() {
58
+ await Promise.all([...this.streams.keys()].map(id => this.close(id)));
59
+ }
60
+ pathFor(sessionId) {
61
+ return this.streams.get(sessionId)?.path;
62
+ }
63
+ size() {
64
+ return this.streams.size;
65
+ }
66
+ }
67
+ function monthSlug(iso) {
68
+ const d = new Date(iso);
69
+ if (Number.isNaN(d.getTime()))
70
+ return 'unknown';
71
+ return `${d.getUTCFullYear()}/${String(d.getUTCMonth() + 1).padStart(2, '0')}`;
72
+ }
73
+ function sanitize(id) {
74
+ return id.replace(/[^a-zA-Z0-9._-]/g, '_');
75
+ }
76
+ //# sourceMappingURL=sink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sink.js","sourceRoot":"","sources":["../../src/conv/sink.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { JsonlSink } from '../sink.js';
2
+ export interface AiderWatcherOptions {
3
+ homeDir: string;
4
+ projectPath?: string;
5
+ intervalMs?: number;
6
+ cursorPrefix?: string;
7
+ }
8
+ export interface AiderWatcher {
9
+ start(): Promise<void>;
10
+ stop(): Promise<void>;
11
+ tally(): number;
12
+ }
13
+ export declare function startAiderWatcher(sink: JsonlSink, opts: AiderWatcherOptions): AiderWatcher;
@@ -0,0 +1,95 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { CursorStore } from '../cursor.js';
4
+ import { aiderConvReader } from '../../adapters/aider/conv-reader.js';
5
+ /**
6
+ * Live tee source for Aider.
7
+ *
8
+ * Aider writes one markdown file per project root:
9
+ * `.aider.chat.history.md`. We re-parse on every interval and emit
10
+ * only sessions whose id we haven't seen yet (the id encodes the
11
+ * project basename + chat-start timestamp, so it's stable across
12
+ * re-reads).
13
+ */
14
+ const POLL_INTERVAL_MS = 1_500;
15
+ export function startAiderWatcher(sink, opts) {
16
+ const interval = opts.intervalMs ?? POLL_INTERVAL_MS;
17
+ const prefix = opts.cursorPrefix ?? 'aider:';
18
+ const cursors = new CursorStore();
19
+ const projectPath = opts.projectPath ?? process.cwd();
20
+ const historyPath = join(projectPath, '.aider.chat.history.md');
21
+ let timer;
22
+ let running = false;
23
+ let totalEvents = 0;
24
+ const emittedSessions = new Set();
25
+ return {
26
+ async start() {
27
+ if (running)
28
+ return;
29
+ running = true;
30
+ await cursors.load();
31
+ const tick = async () => {
32
+ if (!running)
33
+ return;
34
+ try {
35
+ totalEvents += await poll(projectPath, historyPath, sink, cursors, prefix, emittedSessions);
36
+ }
37
+ catch (err) {
38
+ process.emit('warning', err);
39
+ }
40
+ if (running)
41
+ timer = setTimeout(tick, interval);
42
+ };
43
+ await tick();
44
+ },
45
+ async stop() {
46
+ running = false;
47
+ if (timer)
48
+ clearTimeout(timer);
49
+ timer = undefined;
50
+ },
51
+ tally() {
52
+ return totalEvents;
53
+ },
54
+ };
55
+ }
56
+ async function poll(projectPath, historyPath, sink, cursors, prefix, emittedSessions) {
57
+ try {
58
+ await fs.access(historyPath);
59
+ }
60
+ catch {
61
+ return 0;
62
+ }
63
+ let total = 0;
64
+ for await (const summary of aiderConvReader.listSessions({ homeDir: '', projectPath })) {
65
+ const key = `${prefix}${summary.id}`;
66
+ if (cursors.get(key) > 0 || emittedSessions.has(summary.id))
67
+ continue;
68
+ let opened = false;
69
+ let seq = 0;
70
+ for await (const event of aiderConvReader.readSession(summary.id, {
71
+ homeDir: '',
72
+ projectPath,
73
+ })) {
74
+ if (event.type === 'session.start') {
75
+ await sink.openSession(event.id, {
76
+ tool: 'aider',
77
+ ...(event.title ? { title: event.title } : {}),
78
+ ...(event.project ? { project: event.project } : {}),
79
+ startedAt: event.ts,
80
+ });
81
+ opened = true;
82
+ continue;
83
+ }
84
+ if (event.type === 'message' && opened) {
85
+ await sink.write(event.session, event);
86
+ seq += 1;
87
+ total += 1;
88
+ }
89
+ }
90
+ emittedSessions.add(summary.id);
91
+ await cursors.set(key, Math.max(seq, 1));
92
+ }
93
+ return total;
94
+ }
95
+ //# sourceMappingURL=aider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aider.js","sourceRoot":"","sources":["../../../src/conv/sources/aider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { JsonlSink } from '../sink.js';
2
+ export interface ClaudeCodeWatcherOptions {
3
+ homeDir: string;
4
+ intervalMs?: number;
5
+ /** Cursor key prefix (allows tests to isolate). Defaults to "cc:" */
6
+ cursorPrefix?: string;
7
+ }
8
+ export interface ClaudeCodeWatcher {
9
+ start(): Promise<void>;
10
+ stop(): Promise<void>;
11
+ tally(): number;
12
+ }
13
+ export declare function startClaudeCodeWatcher(sink: JsonlSink, opts: ClaudeCodeWatcherOptions): ClaudeCodeWatcher;
@@ -0,0 +1,189 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { CursorStore } from '../cursor.js';
4
+ import { ensureDir } from '../../util/fs.js';
5
+ /**
6
+ * Live tee for Claude Code.
7
+ *
8
+ * Claude Code writes each session as `~/.claude/projects/<encoded-cwd>/<uuid>.jsonl`
9
+ * in append mode. To follow it live we:
10
+ *
11
+ * 1. Poll the projects/ tree on a short interval (fs.watch is unreliable
12
+ * on macOS for recursive dirs without spawning threads we don't want).
13
+ * 2. For each `*.jsonl` file, read from the persistent byte cursor and
14
+ * emit new lines as `claude-code` events. The original Claude Code
15
+ * event shape passes through unchanged — the sink does redaction.
16
+ * 3. Persist the new cursor only after every line for that file lands
17
+ * in the sink.
18
+ *
19
+ * Crash safety: cursors persist after each batch; partial writes lose the
20
+ * in-flight line only.
21
+ */
22
+ const POLL_INTERVAL_MS = 1_000;
23
+ export function startClaudeCodeWatcher(sink, opts) {
24
+ const interval = opts.intervalMs ?? POLL_INTERVAL_MS;
25
+ const prefix = opts.cursorPrefix ?? 'cc:';
26
+ const cursors = new CursorStore();
27
+ const projectsRoot = join(opts.homeDir, '.claude', 'projects');
28
+ let timer;
29
+ let running = false;
30
+ let totalEvents = 0;
31
+ return {
32
+ async start() {
33
+ if (running)
34
+ return;
35
+ running = true;
36
+ await cursors.load();
37
+ await ensureDir(projectsRoot).catch(() => { });
38
+ const tick = async () => {
39
+ if (!running)
40
+ return;
41
+ try {
42
+ totalEvents += await poll(projectsRoot, sink, cursors, prefix);
43
+ }
44
+ catch (err) {
45
+ process.emit('warning', err);
46
+ }
47
+ if (running)
48
+ timer = setTimeout(tick, interval);
49
+ };
50
+ await tick();
51
+ },
52
+ async stop() {
53
+ running = false;
54
+ if (timer)
55
+ clearTimeout(timer);
56
+ timer = undefined;
57
+ },
58
+ tally() {
59
+ return totalEvents;
60
+ },
61
+ };
62
+ }
63
+ async function poll(root, sink, cursors, prefix) {
64
+ const dirs = await readDirSafe(root);
65
+ let totalNew = 0;
66
+ for (const dirName of dirs) {
67
+ const dir = join(root, dirName);
68
+ const stat = await safeStat(dir);
69
+ if (!stat?.isDirectory())
70
+ continue;
71
+ const files = await readDirSafe(dir);
72
+ for (const file of files) {
73
+ if (!file.endsWith('.jsonl'))
74
+ continue;
75
+ const full = join(dir, file);
76
+ const fStat = await safeStat(full);
77
+ if (!fStat)
78
+ continue;
79
+ const key = `${prefix}${full}`;
80
+ const start = cursors.get(key);
81
+ if (fStat.size <= start)
82
+ continue;
83
+ const newlyEmitted = await emitNewLines(full, start, fStat.size, sink, cursors, key, dirName);
84
+ totalNew += newlyEmitted;
85
+ }
86
+ }
87
+ return totalNew;
88
+ }
89
+ async function emitNewLines(path, start, end, sink, cursors, key, encodedDir) {
90
+ const fd = await fs.open(path, 'r');
91
+ try {
92
+ const length = end - start;
93
+ const buffer = Buffer.alloc(length);
94
+ await fd.read(buffer, 0, length, start);
95
+ const text = buffer.toString('utf8');
96
+ const lines = text.split('\n');
97
+ const lastNewline = text.lastIndexOf('\n');
98
+ const consumed = lastNewline === -1 ? 0 : lastNewline + 1;
99
+ const completeLines = lines.slice(0, -1);
100
+ let emitted = 0;
101
+ let sessionOpened;
102
+ let project = decodeProjectDir(encodedDir);
103
+ let model;
104
+ let toolVersion;
105
+ let title;
106
+ let lastTs;
107
+ let sessionId;
108
+ for (const raw of completeLines) {
109
+ if (!raw.trim())
110
+ continue;
111
+ const obj = safeParseJson(raw);
112
+ if (!obj)
113
+ continue;
114
+ if (typeof obj.sessionId === 'string')
115
+ sessionId ??= obj.sessionId;
116
+ if (typeof obj.version === 'string')
117
+ toolVersion ??= obj.version;
118
+ if (typeof obj.message?.model === 'string')
119
+ model ??= obj.message.model;
120
+ if (obj.type === 'ai-title' && typeof obj.aiTitle === 'string')
121
+ title ??= obj.aiTitle;
122
+ if (typeof obj.timestamp === 'string')
123
+ lastTs = obj.timestamp;
124
+ if (!sessionId)
125
+ continue;
126
+ if (!sessionOpened) {
127
+ await sink.openSession(sessionId, {
128
+ tool: 'claude-code',
129
+ ...(toolVersion ? { toolVersion } : {}),
130
+ ...(model ? { model } : {}),
131
+ ...(project ? { project } : {}),
132
+ ...(title ? { title } : {}),
133
+ startedAt: lastTs ?? new Date().toISOString(),
134
+ });
135
+ sessionOpened = sessionId;
136
+ }
137
+ if (obj.type !== 'user' && obj.type !== 'assistant')
138
+ continue;
139
+ if (!obj.message?.content || !Array.isArray(obj.message.content))
140
+ continue;
141
+ emitted += 1;
142
+ await sink.write(sessionId, {
143
+ type: 'message',
144
+ session: sessionId,
145
+ seq: emitted,
146
+ role: obj.message.role ??
147
+ obj.type,
148
+ content: obj.message.content,
149
+ ts: obj.timestamp ?? new Date().toISOString(),
150
+ });
151
+ }
152
+ if (consumed > 0)
153
+ await cursors.set(key, start + consumed);
154
+ return emitted;
155
+ }
156
+ finally {
157
+ await fd.close();
158
+ }
159
+ }
160
+ function decodeProjectDir(encoded) {
161
+ if (encoded.startsWith('-'))
162
+ return encoded.replace(/-/g, '/');
163
+ return encoded;
164
+ }
165
+ function safeParseJson(line) {
166
+ try {
167
+ return JSON.parse(line);
168
+ }
169
+ catch {
170
+ return undefined;
171
+ }
172
+ }
173
+ async function safeStat(path) {
174
+ try {
175
+ return await fs.stat(path);
176
+ }
177
+ catch {
178
+ return undefined;
179
+ }
180
+ }
181
+ async function readDirSafe(path) {
182
+ try {
183
+ return await fs.readdir(path);
184
+ }
185
+ catch {
186
+ return [];
187
+ }
188
+ }
189
+ //# sourceMappingURL=claude-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/conv/sources/claude-code.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { JsonlSink } from '../sink.js';
2
+ export interface CodexWatcherOptions {
3
+ homeDir: string;
4
+ /** Override the state_5 sqlite path (default: ~/.codex/state_5.sqlite). */
5
+ statePath?: string;
6
+ intervalMs?: number;
7
+ /** Cursor key prefix; tests can isolate. Defaults to "codex:". */
8
+ cursorPrefix?: string;
9
+ }
10
+ export interface CodexWatcher {
11
+ start(): Promise<void>;
12
+ stop(): Promise<void>;
13
+ tally(): number;
14
+ }
15
+ export declare function startCodexWatcher(sink: JsonlSink, opts: CodexWatcherOptions): CodexWatcher;
@@ -0,0 +1,175 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import { createRequire } from 'node:module';
3
+ import { join } from 'node:path';
4
+ import { CursorStore } from '../cursor.js';
5
+ const POLL_INTERVAL_MS = 2_000;
6
+ const requireSqlite = createRequire(import.meta.url);
7
+ let cachedSqlite;
8
+ function loadSqlite() {
9
+ if (!cachedSqlite) {
10
+ cachedSqlite = requireSqlite('node:sqlite');
11
+ }
12
+ return cachedSqlite;
13
+ }
14
+ export function startCodexWatcher(sink, opts) {
15
+ const interval = opts.intervalMs ?? POLL_INTERVAL_MS;
16
+ const statePath = opts.statePath ?? join(opts.homeDir, '.codex', 'state_5.sqlite');
17
+ const prefix = opts.cursorPrefix ?? 'codex:';
18
+ const cursorKey = `${prefix}max-thread-rowid:${statePath}`;
19
+ const cursors = new CursorStore();
20
+ let timer;
21
+ let running = false;
22
+ let totalEvents = 0;
23
+ return {
24
+ async start() {
25
+ if (running)
26
+ return;
27
+ running = true;
28
+ await cursors.load();
29
+ const tick = async () => {
30
+ if (!running)
31
+ return;
32
+ try {
33
+ totalEvents += await poll(statePath, sink, cursors, cursorKey);
34
+ }
35
+ catch (err) {
36
+ process.emit('warning', err);
37
+ }
38
+ if (running)
39
+ timer = setTimeout(tick, interval);
40
+ };
41
+ await tick();
42
+ },
43
+ async stop() {
44
+ running = false;
45
+ if (timer)
46
+ clearTimeout(timer);
47
+ timer = undefined;
48
+ },
49
+ tally() {
50
+ return totalEvents;
51
+ },
52
+ };
53
+ }
54
+ async function poll(statePath, sink, cursors, cursorKey) {
55
+ try {
56
+ await fs.access(statePath);
57
+ }
58
+ catch {
59
+ return 0;
60
+ }
61
+ const { DatabaseSync } = loadSqlite();
62
+ const db = new DatabaseSync(statePath);
63
+ let totalNew = 0;
64
+ try {
65
+ const lastRowid = cursors.get(cursorKey);
66
+ const rows = db
67
+ .prepare(`SELECT rowid AS rowid, id, rollout_path, created_at, title, model, model_provider,
68
+ cwd, cli_version, first_user_message
69
+ FROM threads
70
+ WHERE rowid > ?
71
+ ORDER BY rowid ASC
72
+ LIMIT 100`)
73
+ .all(lastRowid);
74
+ for (const row of rows) {
75
+ const startedAt = new Date(row.created_at * 1000).toISOString();
76
+ const sessionId = `codex-${row.id}`;
77
+ await sink.openSession(sessionId, {
78
+ tool: 'codex',
79
+ ...(row.cli_version ? { toolVersion: row.cli_version } : {}),
80
+ ...(row.model ? { model: row.model } : {}),
81
+ ...(row.cwd ? { project: row.cwd } : {}),
82
+ title: row.title || row.first_user_message?.slice(0, 80) || `codex thread ${row.id.slice(0, 8)}`,
83
+ startedAt,
84
+ });
85
+ totalNew += await emitRolloutMessages(sink, sessionId, row.rollout_path, startedAt);
86
+ await cursors.set(cursorKey, row.rowid);
87
+ }
88
+ }
89
+ finally {
90
+ db.close();
91
+ }
92
+ return totalNew;
93
+ }
94
+ async function emitRolloutMessages(sink, sessionId, rolloutPath, fallbackTs) {
95
+ if (!rolloutPath)
96
+ return 0;
97
+ let raw;
98
+ try {
99
+ raw = await fs.readFile(rolloutPath, 'utf8');
100
+ }
101
+ catch {
102
+ return 0;
103
+ }
104
+ let seq = 0;
105
+ for (const line of raw.split('\n')) {
106
+ const trimmed = line.trim();
107
+ if (!trimmed)
108
+ continue;
109
+ const event = safeJson(trimmed);
110
+ if (!event)
111
+ continue;
112
+ const role = inferRole(event);
113
+ const content = inferContent(event);
114
+ if (!role || content.length === 0)
115
+ continue;
116
+ seq += 1;
117
+ await sink.write(sessionId, {
118
+ type: 'message',
119
+ session: sessionId,
120
+ seq,
121
+ role,
122
+ content,
123
+ ts: typeof event['timestamp'] === 'string' ? event['timestamp'] : fallbackTs,
124
+ });
125
+ }
126
+ return seq;
127
+ }
128
+ function inferRole(event) {
129
+ const explicit = event['role'];
130
+ if (explicit === 'user' || explicit === 'assistant' || explicit === 'system')
131
+ return explicit;
132
+ const t = event['type'];
133
+ if (t === 'user_message' || t === 'user')
134
+ return 'user';
135
+ if (t === 'assistant_message' || t === 'assistant' || t === 'agent_message')
136
+ return 'assistant';
137
+ if (t === 'system_message')
138
+ return 'system';
139
+ return undefined;
140
+ }
141
+ function inferContent(event) {
142
+ const raw = event['content'];
143
+ if (typeof raw === 'string')
144
+ return [{ type: 'text', text: raw }];
145
+ if (Array.isArray(raw)) {
146
+ const blocks = [];
147
+ for (const item of raw) {
148
+ if (item['type'] === 'text' && typeof item['text'] === 'string') {
149
+ blocks.push({ type: 'text', text: item['text'] });
150
+ }
151
+ else if (item['type'] === 'input_text' && typeof item['text'] === 'string') {
152
+ blocks.push({ type: 'text', text: item['text'] });
153
+ }
154
+ else if (item['type'] === 'output_text' && typeof item['text'] === 'string') {
155
+ blocks.push({ type: 'text', text: item['text'] });
156
+ }
157
+ }
158
+ return blocks;
159
+ }
160
+ if (typeof event['text'] === 'string')
161
+ return [{ type: 'text', text: event['text'] }];
162
+ if (typeof event['message'] === 'string') {
163
+ return [{ type: 'text', text: event['message'] }];
164
+ }
165
+ return [];
166
+ }
167
+ function safeJson(raw) {
168
+ try {
169
+ return JSON.parse(raw);
170
+ }
171
+ catch {
172
+ return undefined;
173
+ }
174
+ }
175
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../src/conv/sources/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAqC1C,MAAM,gBAAgB,GAAG,KAAK,CAAA;AAC9B,MAAM,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACpD,IAAI,YAA0C,CAAA;AAC9C,SAAS,UAAU;IACjB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,YAAY,GAAG,aAAa,CAAC,aAAa,CAAqB,CAAA;IACjE,CAAC;IACD,OAAO,YAAY,CAAA;AACrB,CAAC;AA8BD,MAAM,UAAU,iBAAiB,CAAC,IAAe,EAAE,IAAyB;IAC1E,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,IAAI,gBAAgB,CAAA;IACpD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAA;IAClF,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAA;IAC5C,MAAM,SAAS,GAAG,GAAG,MAAM,oBAAoB,SAAS,EAAE,CAAA;IAC1D,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;IACjC,IAAI,KAAiC,CAAA;IACrC,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,IAAI,WAAW,GAAG,CAAC,CAAA;IAEnB,OAAO;QACL,KAAK,CAAC,KAAK;YACT,IAAI,OAAO;gBAAE,OAAM;YACnB,OAAO,GAAG,IAAI,CAAA;YACd,MAAM,OAAO,CAAC,IAAI,EAAE,CAAA;YACpB,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;gBACtB,IAAI,CAAC,OAAO;oBAAE,OAAM;gBACpB,IAAI,CAAC;oBACH,WAAW,IAAI,MAAM,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,CAAA;gBAChE,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAY,CAAC,CAAA;gBACvC,CAAC;gBACD,IAAI,OAAO;oBAAE,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;YACjD,CAAC,CAAA;YACD,MAAM,IAAI,EAAE,CAAA;QACd,CAAC;QACD,KAAK,CAAC,IAAI;YACR,OAAO,GAAG,KAAK,CAAA;YACf,IAAI,KAAK;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAA;YAC9B,KAAK,GAAG,SAAS,CAAA;QACnB,CAAC;QACD,KAAK;YACH,OAAO,WAAW,CAAA;QACpB,CAAC;KACF,CAAA;AACH,CAAC;AAED,KAAK,UAAU,IAAI,CACjB,SAAiB,EACjB,IAAe,EACf,OAAoB,EACpB,SAAiB;IAEjB,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAA;IACV,CAAC;IACD,MAAM,EAAE,YAAY,EAAE,GAAG,UAAU,EAAE,CAAA;IACrC,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,SAAS,CAAC,CAAA;IACtC,IAAI,QAAQ,GAAG,CAAC,CAAA;IAChB,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QACxC,MAAM,IAAI,GAAG,EAAE;aACZ,OAAO,CACN;;;;;mBAKW,CACZ;aACA,GAAG,CAAC,SAAS,CAAgB,CAAA;QAChC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA;YAC/D,MAAM,SAAS,GAAG,SAAS,GAAG,CAAC,EAAE,EAAE,CAAA;YACnC,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE;gBAChC,IAAI,EAAE,OAAO;gBACb,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5D,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1C,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxC,KAAK,EACH,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,gBAAgB,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;gBAC3F,SAAS;aACV,CAAC,CAAA;YACF,QAAQ,IAAI,MAAM,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,YAAY,EAAE,SAAS,CAAC,CAAA;YACnF,MAAM,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,CAAA;QACzC,CAAC;IACH,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAA;IACZ,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,IAAe,EACf,SAAiB,EACjB,WAAmB,EACnB,UAAkB;IAElB,IAAI,CAAC,WAAW;QAAE,OAAO,CAAC,CAAA;IAC1B,IAAI,GAAW,CAAA;IACf,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAA;IACV,CAAC;IACD,IAAI,GAAG,GAAG,CAAC,CAAA;IACX,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAC3B,IAAI,CAAC,OAAO;YAAE,SAAQ;QACtB,MAAM,KAAK,GAAG,QAAQ,CAA0B,OAAO,CAAC,CAAA;QACxD,IAAI,CAAC,KAAK;YAAE,SAAQ;QACpB,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;QAC7B,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;QACnC,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,SAAQ;QAC3C,GAAG,IAAI,CAAC,CAAA;QACR,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE;YAC1B,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,SAAS;YAClB,GAAG;YACH,IAAI;YACJ,OAAO;YACP,EAAE,EAAE,OAAO,KAAK,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,KAAK,CAAC,WAAW,CAAY,CAAC,CAAC,CAAC,UAAU;SACzF,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,SAAS,CAAC,KAA8B;IAC/C,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAA;IAC9B,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAA;IAC7F,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAA;IACvB,IAAI,CAAC,KAAK,cAAc,IAAI,CAAC,KAAK,MAAM;QAAE,OAAO,MAAM,CAAA;IACvD,IAAI,CAAC,KAAK,mBAAmB,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,eAAe;QAAE,OAAO,WAAW,CAAA;IAC/F,IAAI,CAAC,KAAK,gBAAgB;QAAE,OAAO,QAAQ,CAAA;IAC3C,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,YAAY,CAAC,KAA8B;IAClD,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC,CAAA;IAC5B,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAA;IACjE,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,MAAM,GAAmB,EAAE,CAAA;QACjC,KAAK,MAAM,IAAI,IAAI,GAAqC,EAAE,CAAC;YACzD,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAChE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YACnD,CAAC;iBAAM,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,YAAY,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAC7E,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YACnD,CAAC;iBAAM,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,aAAa,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAC9E,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YACnD,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAW,EAAE,CAAC,CAAA;IAC/F,IAAI,OAAO,KAAK,CAAC,SAAS,CAAC,KAAK,QAAQ,EAAE,CAAC;QACzC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,CAAW,EAAE,CAAC,CAAA;IAC7D,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC;AAED,SAAS,QAAQ,CAAI,GAAW;IAC9B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAM,CAAA;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { JsonlSink } from '../sink.js';
2
+ export interface OpencodeWatcherOptions {
3
+ homeDir: string;
4
+ intervalMs?: number;
5
+ cursorPrefix?: string;
6
+ }
7
+ export interface OpencodeWatcher {
8
+ start(): Promise<void>;
9
+ stop(): Promise<void>;
10
+ tally(): number;
11
+ }
12
+ export declare function startOpencodeWatcher(sink: JsonlSink, opts: OpencodeWatcherOptions): OpencodeWatcher;