@nocoo/pew 0.7.0 → 0.9.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 (91) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +30 -1
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/notify.d.ts +7 -2
  5. package/dist/commands/notify.d.ts.map +1 -1
  6. package/dist/commands/notify.js +48 -10
  7. package/dist/commands/notify.js.map +1 -1
  8. package/dist/commands/session-sync.d.ts +12 -0
  9. package/dist/commands/session-sync.d.ts.map +1 -1
  10. package/dist/commands/session-sync.js +99 -311
  11. package/dist/commands/session-sync.js.map +1 -1
  12. package/dist/commands/sync.d.ts.map +1 -1
  13. package/dist/commands/sync.js +112 -330
  14. package/dist/commands/sync.js.map +1 -1
  15. package/dist/drivers/registry.d.ts +63 -0
  16. package/dist/drivers/registry.d.ts.map +1 -0
  17. package/dist/drivers/registry.js +88 -0
  18. package/dist/drivers/registry.js.map +1 -0
  19. package/dist/drivers/session/claude-session-driver.d.ts +10 -0
  20. package/dist/drivers/session/claude-session-driver.d.ts.map +1 -0
  21. package/dist/drivers/session/claude-session-driver.js +29 -0
  22. package/dist/drivers/session/claude-session-driver.js.map +1 -0
  23. package/dist/drivers/session/codex-session-driver.d.ts +10 -0
  24. package/dist/drivers/session/codex-session-driver.d.ts.map +1 -0
  25. package/dist/drivers/session/codex-session-driver.js +29 -0
  26. package/dist/drivers/session/codex-session-driver.js.map +1 -0
  27. package/dist/drivers/session/gemini-session-driver.d.ts +10 -0
  28. package/dist/drivers/session/gemini-session-driver.d.ts.map +1 -0
  29. package/dist/drivers/session/gemini-session-driver.js +29 -0
  30. package/dist/drivers/session/gemini-session-driver.js.map +1 -0
  31. package/dist/drivers/session/openclaw-session-driver.d.ts +10 -0
  32. package/dist/drivers/session/openclaw-session-driver.d.ts.map +1 -0
  33. package/dist/drivers/session/openclaw-session-driver.js +29 -0
  34. package/dist/drivers/session/openclaw-session-driver.js.map +1 -0
  35. package/dist/drivers/session/opencode-json-session-driver.d.ts +14 -0
  36. package/dist/drivers/session/opencode-json-session-driver.d.ts.map +1 -0
  37. package/dist/drivers/session/opencode-json-session-driver.js +51 -0
  38. package/dist/drivers/session/opencode-json-session-driver.js.map +1 -0
  39. package/dist/drivers/session/opencode-sqlite-session-driver.d.ts +23 -0
  40. package/dist/drivers/session/opencode-sqlite-session-driver.d.ts.map +1 -0
  41. package/dist/drivers/session/opencode-sqlite-session-driver.js +88 -0
  42. package/dist/drivers/session/opencode-sqlite-session-driver.js.map +1 -0
  43. package/dist/drivers/token/claude-token-driver.d.ts +11 -0
  44. package/dist/drivers/token/claude-token-driver.d.ts.map +1 -0
  45. package/dist/drivers/token/claude-token-driver.js +42 -0
  46. package/dist/drivers/token/claude-token-driver.js.map +1 -0
  47. package/dist/drivers/token/codex-token-driver.d.ts +11 -0
  48. package/dist/drivers/token/codex-token-driver.d.ts.map +1 -0
  49. package/dist/drivers/token/codex-token-driver.js +59 -0
  50. package/dist/drivers/token/codex-token-driver.js.map +1 -0
  51. package/dist/drivers/token/gemini-token-driver.d.ts +11 -0
  52. package/dist/drivers/token/gemini-token-driver.d.ts.map +1 -0
  53. package/dist/drivers/token/gemini-token-driver.js +57 -0
  54. package/dist/drivers/token/gemini-token-driver.js.map +1 -0
  55. package/dist/drivers/token/openclaw-token-driver.d.ts +11 -0
  56. package/dist/drivers/token/openclaw-token-driver.d.ts.map +1 -0
  57. package/dist/drivers/token/openclaw-token-driver.js +42 -0
  58. package/dist/drivers/token/openclaw-token-driver.js.map +1 -0
  59. package/dist/drivers/token/opencode-json-token-driver.d.ts +15 -0
  60. package/dist/drivers/token/opencode-json-token-driver.d.ts.map +1 -0
  61. package/dist/drivers/token/opencode-json-token-driver.js +73 -0
  62. package/dist/drivers/token/opencode-json-token-driver.js.map +1 -0
  63. package/dist/drivers/token/opencode-sqlite-token-driver.d.ts +25 -0
  64. package/dist/drivers/token/opencode-sqlite-token-driver.d.ts.map +1 -0
  65. package/dist/drivers/token/opencode-sqlite-token-driver.js +99 -0
  66. package/dist/drivers/token/opencode-sqlite-token-driver.js.map +1 -0
  67. package/dist/drivers/types.d.ts +202 -0
  68. package/dist/drivers/types.d.ts.map +1 -0
  69. package/dist/drivers/types.js +12 -0
  70. package/dist/drivers/types.js.map +1 -0
  71. package/dist/notifier/coordinator.d.ts +3 -2
  72. package/dist/notifier/coordinator.d.ts.map +1 -1
  73. package/dist/notifier/coordinator.js +76 -5
  74. package/dist/notifier/coordinator.js.map +1 -1
  75. package/dist/storage/base-cursor-store.d.ts +16 -0
  76. package/dist/storage/base-cursor-store.d.ts.map +1 -0
  77. package/dist/storage/base-cursor-store.js +33 -0
  78. package/dist/storage/base-cursor-store.js.map +1 -0
  79. package/dist/storage/cursor-store.d.ts +2 -6
  80. package/dist/storage/cursor-store.d.ts.map +1 -1
  81. package/dist/storage/cursor-store.js +4 -25
  82. package/dist/storage/cursor-store.js.map +1 -1
  83. package/dist/storage/session-cursor-store.d.ts +2 -6
  84. package/dist/storage/session-cursor-store.d.ts.map +1 -1
  85. package/dist/storage/session-cursor-store.js +4 -25
  86. package/dist/storage/session-cursor-store.js.map +1 -1
  87. package/dist/utils/file-changed.d.ts +35 -0
  88. package/dist/utils/file-changed.d.ts.map +1 -0
  89. package/dist/utils/file-changed.js +34 -0
  90. package/dist/utils/file-changed.js.map +1 -0
  91. package/package.json +1 -1
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Driver Registry — single entry point for constructing active driver sets.
3
+ *
4
+ * Returns drivers for enabled sources based on which directories/DB paths
5
+ * exist in the provided options. File-based drivers are singletons;
6
+ * DB-based drivers are constructed via factory functions (need DI params).
7
+ *
8
+ * The orchestrator (sync.ts / session-sync.ts) calls these once per run
9
+ * and iterates the returned arrays with generic loops.
10
+ */
11
+ // -- Token driver singletons --
12
+ import { claudeTokenDriver } from "./token/claude-token-driver.js";
13
+ import { geminiTokenDriver } from "./token/gemini-token-driver.js";
14
+ import { openCodeJsonTokenDriver } from "./token/opencode-json-token-driver.js";
15
+ import { openClawTokenDriver } from "./token/openclaw-token-driver.js";
16
+ import { codexTokenDriver } from "./token/codex-token-driver.js";
17
+ import { createOpenCodeSqliteTokenDriver, } from "./token/opencode-sqlite-token-driver.js";
18
+ // -- Session driver singletons --
19
+ import { claudeSessionDriver } from "./session/claude-session-driver.js";
20
+ import { geminiSessionDriver } from "./session/gemini-session-driver.js";
21
+ import { openCodeJsonSessionDriver } from "./session/opencode-json-session-driver.js";
22
+ import { openClawSessionDriver } from "./session/openclaw-session-driver.js";
23
+ import { codexSessionDriver } from "./session/codex-session-driver.js";
24
+ import { createOpenCodeSqliteSessionDriver, } from "./session/opencode-sqlite-session-driver.js";
25
+ /**
26
+ * Construct the active token driver set based on which sources are available.
27
+ *
28
+ * A file driver is included when its corresponding directory option is truthy.
29
+ * The SQLite DB driver is included when both `openCodeDbPath` and `openMessageDb` are provided.
30
+ */
31
+ export function createTokenDrivers(opts) {
32
+ const fileDrivers = [];
33
+ const dbDrivers = [];
34
+ if (opts.claudeDir) {
35
+ fileDrivers.push(claudeTokenDriver);
36
+ }
37
+ if (opts.geminiDir) {
38
+ fileDrivers.push(geminiTokenDriver);
39
+ }
40
+ if (opts.openCodeMessageDir) {
41
+ fileDrivers.push(openCodeJsonTokenDriver);
42
+ }
43
+ if (opts.openclawDir) {
44
+ fileDrivers.push(openClawTokenDriver);
45
+ }
46
+ if (opts.codexSessionsDir) {
47
+ fileDrivers.push(codexTokenDriver);
48
+ }
49
+ if (opts.openCodeDbPath && opts.openMessageDb) {
50
+ dbDrivers.push(createOpenCodeSqliteTokenDriver({
51
+ dbPath: opts.openCodeDbPath,
52
+ openMessageDb: opts.openMessageDb,
53
+ }));
54
+ }
55
+ return { fileDrivers, dbDrivers };
56
+ }
57
+ /**
58
+ * Construct the active session driver set based on which sources are available.
59
+ *
60
+ * Same pattern as token drivers: directory presence → file driver, DB opts → DB driver.
61
+ */
62
+ export function createSessionDrivers(opts) {
63
+ const fileDrivers = [];
64
+ const dbDrivers = [];
65
+ if (opts.claudeDir) {
66
+ fileDrivers.push(claudeSessionDriver);
67
+ }
68
+ if (opts.geminiDir) {
69
+ fileDrivers.push(geminiSessionDriver);
70
+ }
71
+ if (opts.openCodeMessageDir) {
72
+ fileDrivers.push(openCodeJsonSessionDriver);
73
+ }
74
+ if (opts.openclawDir) {
75
+ fileDrivers.push(openClawSessionDriver);
76
+ }
77
+ if (opts.codexSessionsDir) {
78
+ fileDrivers.push(codexSessionDriver);
79
+ }
80
+ if (opts.openCodeDbPath && opts.openSessionDb) {
81
+ dbDrivers.push(createOpenCodeSqliteSessionDriver({
82
+ dbPath: opts.openCodeDbPath,
83
+ openSessionDb: opts.openSessionDb,
84
+ }));
85
+ }
86
+ return { fileDrivers, dbDrivers };
87
+ }
88
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/drivers/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Claude Code file session driver.
3
+ *
4
+ * Strategy: Full-scan on change (mtime + size dual-check).
5
+ * Parser: collectClaudeSessions(filePath)
6
+ */
7
+ import type { SessionFileCursor } from "@pew/core";
8
+ import type { FileSessionDriver } from "../types.js";
9
+ export declare const claudeSessionDriver: FileSessionDriver<SessionFileCursor>;
10
+ //# sourceMappingURL=claude-session-driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-session-driver.d.ts","sourceRoot":"","sources":["../../../src/drivers/session/claude-session-driver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAGnD,OAAO,KAAK,EAAE,iBAAiB,EAAiC,MAAM,aAAa,CAAC;AAEpF,eAAO,MAAM,mBAAmB,EAAE,iBAAiB,CAAC,iBAAiB,CAqBpE,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Claude Code file session driver.
3
+ *
4
+ * Strategy: Full-scan on change (mtime + size dual-check).
5
+ * Parser: collectClaudeSessions(filePath)
6
+ */
7
+ import { discoverClaudeFiles } from "../../discovery/sources.js";
8
+ import { collectClaudeSessions } from "../../parsers/claude-session.js";
9
+ export const claudeSessionDriver = {
10
+ kind: "file",
11
+ source: "claude-code",
12
+ async discover(opts) {
13
+ if (!opts.claudeDir)
14
+ return [];
15
+ return discoverClaudeFiles(opts.claudeDir);
16
+ },
17
+ shouldSkip(cursor, fingerprint) {
18
+ if (!cursor)
19
+ return false;
20
+ return cursor.mtimeMs === fingerprint.mtimeMs && cursor.size === fingerprint.size;
21
+ },
22
+ async parse(filePath) {
23
+ return collectClaudeSessions(filePath);
24
+ },
25
+ buildCursor(fingerprint) {
26
+ return { mtimeMs: fingerprint.mtimeMs, size: fingerprint.size };
27
+ },
28
+ };
29
+ //# sourceMappingURL=claude-session-driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-session-driver.js","sourceRoot":"","sources":["../../../src/drivers/session/claude-session-driver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAGxE,MAAM,CAAC,MAAM,mBAAmB,GAAyC;IACvE,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,aAAa;IAErB,KAAK,CAAC,QAAQ,CAAC,IAAkB;QAC/B,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,CAAC;QAC/B,OAAO,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;IAED,UAAU,CAAC,MAAqC,EAAE,WAA4B;QAC5E,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC1B,OAAO,MAAM,CAAC,OAAO,KAAK,WAAW,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,CAAC;IACpF,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB;QAC1B,OAAO,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAED,WAAW,CAAC,WAA4B;QACtC,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC;IAClE,CAAC;CACF,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Codex CLI file session driver.
3
+ *
4
+ * Strategy: Full-scan on change (mtime + size dual-check).
5
+ * Parser: collectCodexSessions(filePath)
6
+ */
7
+ import type { SessionFileCursor } from "@pew/core";
8
+ import type { FileSessionDriver } from "../types.js";
9
+ export declare const codexSessionDriver: FileSessionDriver<SessionFileCursor>;
10
+ //# sourceMappingURL=codex-session-driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-session-driver.d.ts","sourceRoot":"","sources":["../../../src/drivers/session/codex-session-driver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAGnD,OAAO,KAAK,EAAE,iBAAiB,EAAiC,MAAM,aAAa,CAAC;AAEpF,eAAO,MAAM,kBAAkB,EAAE,iBAAiB,CAAC,iBAAiB,CAqBnE,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Codex CLI file session driver.
3
+ *
4
+ * Strategy: Full-scan on change (mtime + size dual-check).
5
+ * Parser: collectCodexSessions(filePath)
6
+ */
7
+ import { discoverCodexFiles } from "../../discovery/sources.js";
8
+ import { collectCodexSessions } from "../../parsers/codex-session.js";
9
+ export const codexSessionDriver = {
10
+ kind: "file",
11
+ source: "codex",
12
+ async discover(opts) {
13
+ if (!opts.codexSessionsDir)
14
+ return [];
15
+ return discoverCodexFiles(opts.codexSessionsDir);
16
+ },
17
+ shouldSkip(cursor, fingerprint) {
18
+ if (!cursor)
19
+ return false;
20
+ return cursor.mtimeMs === fingerprint.mtimeMs && cursor.size === fingerprint.size;
21
+ },
22
+ async parse(filePath) {
23
+ return collectCodexSessions(filePath);
24
+ },
25
+ buildCursor(fingerprint) {
26
+ return { mtimeMs: fingerprint.mtimeMs, size: fingerprint.size };
27
+ },
28
+ };
29
+ //# sourceMappingURL=codex-session-driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-session-driver.js","sourceRoot":"","sources":["../../../src/drivers/session/codex-session-driver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAGtE,MAAM,CAAC,MAAM,kBAAkB,GAAyC;IACtE,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,OAAO;IAEf,KAAK,CAAC,QAAQ,CAAC,IAAkB;QAC/B,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE,OAAO,EAAE,CAAC;QACtC,OAAO,kBAAkB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACnD,CAAC;IAED,UAAU,CAAC,MAAqC,EAAE,WAA4B;QAC5E,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC1B,OAAO,MAAM,CAAC,OAAO,KAAK,WAAW,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,CAAC;IACpF,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB;QAC1B,OAAO,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,WAAW,CAAC,WAA4B;QACtC,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC;IAClE,CAAC;CACF,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Gemini CLI file session driver.
3
+ *
4
+ * Strategy: Full-scan on change (mtime + size dual-check).
5
+ * Parser: collectGeminiSessions(filePath)
6
+ */
7
+ import type { SessionFileCursor } from "@pew/core";
8
+ import type { FileSessionDriver } from "../types.js";
9
+ export declare const geminiSessionDriver: FileSessionDriver<SessionFileCursor>;
10
+ //# sourceMappingURL=gemini-session-driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-session-driver.d.ts","sourceRoot":"","sources":["../../../src/drivers/session/gemini-session-driver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAGnD,OAAO,KAAK,EAAE,iBAAiB,EAAiC,MAAM,aAAa,CAAC;AAEpF,eAAO,MAAM,mBAAmB,EAAE,iBAAiB,CAAC,iBAAiB,CAqBpE,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Gemini CLI file session driver.
3
+ *
4
+ * Strategy: Full-scan on change (mtime + size dual-check).
5
+ * Parser: collectGeminiSessions(filePath)
6
+ */
7
+ import { discoverGeminiFiles } from "../../discovery/sources.js";
8
+ import { collectGeminiSessions } from "../../parsers/gemini-session.js";
9
+ export const geminiSessionDriver = {
10
+ kind: "file",
11
+ source: "gemini-cli",
12
+ async discover(opts) {
13
+ if (!opts.geminiDir)
14
+ return [];
15
+ return discoverGeminiFiles(opts.geminiDir);
16
+ },
17
+ shouldSkip(cursor, fingerprint) {
18
+ if (!cursor)
19
+ return false;
20
+ return cursor.mtimeMs === fingerprint.mtimeMs && cursor.size === fingerprint.size;
21
+ },
22
+ async parse(filePath) {
23
+ return collectGeminiSessions(filePath);
24
+ },
25
+ buildCursor(fingerprint) {
26
+ return { mtimeMs: fingerprint.mtimeMs, size: fingerprint.size };
27
+ },
28
+ };
29
+ //# sourceMappingURL=gemini-session-driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-session-driver.js","sourceRoot":"","sources":["../../../src/drivers/session/gemini-session-driver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAGxE,MAAM,CAAC,MAAM,mBAAmB,GAAyC;IACvE,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,YAAY;IAEpB,KAAK,CAAC,QAAQ,CAAC,IAAkB;QAC/B,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,CAAC;QAC/B,OAAO,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;IAED,UAAU,CAAC,MAAqC,EAAE,WAA4B;QAC5E,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC1B,OAAO,MAAM,CAAC,OAAO,KAAK,WAAW,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,CAAC;IACpF,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB;QAC1B,OAAO,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAED,WAAW,CAAC,WAA4B;QACtC,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC;IAClE,CAAC;CACF,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * OpenClaw file session driver.
3
+ *
4
+ * Strategy: Full-scan on change (mtime + size dual-check).
5
+ * Parser: collectOpenClawSessions(filePath)
6
+ */
7
+ import type { SessionFileCursor } from "@pew/core";
8
+ import type { FileSessionDriver } from "../types.js";
9
+ export declare const openClawSessionDriver: FileSessionDriver<SessionFileCursor>;
10
+ //# sourceMappingURL=openclaw-session-driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openclaw-session-driver.d.ts","sourceRoot":"","sources":["../../../src/drivers/session/openclaw-session-driver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAGnD,OAAO,KAAK,EAAE,iBAAiB,EAAiC,MAAM,aAAa,CAAC;AAEpF,eAAO,MAAM,qBAAqB,EAAE,iBAAiB,CAAC,iBAAiB,CAqBtE,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * OpenClaw file session driver.
3
+ *
4
+ * Strategy: Full-scan on change (mtime + size dual-check).
5
+ * Parser: collectOpenClawSessions(filePath)
6
+ */
7
+ import { discoverOpenClawFiles } from "../../discovery/sources.js";
8
+ import { collectOpenClawSessions } from "../../parsers/openclaw-session.js";
9
+ export const openClawSessionDriver = {
10
+ kind: "file",
11
+ source: "openclaw",
12
+ async discover(opts) {
13
+ if (!opts.openclawDir)
14
+ return [];
15
+ return discoverOpenClawFiles(opts.openclawDir);
16
+ },
17
+ shouldSkip(cursor, fingerprint) {
18
+ if (!cursor)
19
+ return false;
20
+ return cursor.mtimeMs === fingerprint.mtimeMs && cursor.size === fingerprint.size;
21
+ },
22
+ async parse(filePath) {
23
+ return collectOpenClawSessions(filePath);
24
+ },
25
+ buildCursor(fingerprint) {
26
+ return { mtimeMs: fingerprint.mtimeMs, size: fingerprint.size };
27
+ },
28
+ };
29
+ //# sourceMappingURL=openclaw-session-driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openclaw-session-driver.js","sourceRoot":"","sources":["../../../src/drivers/session/openclaw-session-driver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAG5E,MAAM,CAAC,MAAM,qBAAqB,GAAyC;IACzE,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,UAAU;IAElB,KAAK,CAAC,QAAQ,CAAC,IAAkB;QAC/B,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO,EAAE,CAAC;QACjC,OAAO,qBAAqB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACjD,CAAC;IAED,UAAU,CAAC,MAAqC,EAAE,WAA4B;QAC5E,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC1B,OAAO,MAAM,CAAC,OAAO,KAAK,WAAW,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,CAAC;IACpF,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB;QAC1B,OAAO,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAED,WAAW,CAAC,WAA4B;QACtC,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC;IAClE,CAAC;CACF,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * OpenCode JSON file session driver.
3
+ *
4
+ * Strategy: Full-scan on change (mtime only — size unreliable for dirs).
5
+ * Discovers directories (not files) under the message dir.
6
+ * Parser: collectOpenCodeSessions(sessionDir)
7
+ */
8
+ import type { FileSessionDriver } from "../types.js";
9
+ /** Cursor for OpenCode JSON session directories — mtime only */
10
+ export interface OpenCodeJsonSessionCursor {
11
+ mtimeMs: number;
12
+ }
13
+ export declare const openCodeJsonSessionDriver: FileSessionDriver<OpenCodeJsonSessionCursor>;
14
+ //# sourceMappingURL=opencode-json-session-driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode-json-session-driver.d.ts","sourceRoot":"","sources":["../../../src/drivers/session/opencode-json-session-driver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAiC,MAAM,aAAa,CAAC;AAGpF,gEAAgE;AAChE,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;CACjB;AAwBD,eAAO,MAAM,yBAAyB,EAAE,iBAAiB,CAAC,yBAAyB,CAyBlF,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * OpenCode JSON file session driver.
3
+ *
4
+ * Strategy: Full-scan on change (mtime only — size unreliable for dirs).
5
+ * Discovers directories (not files) under the message dir.
6
+ * Parser: collectOpenCodeSessions(sessionDir)
7
+ */
8
+ import { readdir } from "node:fs/promises";
9
+ import { join } from "node:path";
10
+ import { collectOpenCodeSessions } from "../../parsers/opencode-session.js";
11
+ /**
12
+ * Discover OpenCode session directories.
13
+ *
14
+ * Lists subdirectories under the message dir (e.g. ses_xxx/).
15
+ * Returns absolute paths to session directories, sorted.
16
+ */
17
+ async function discoverOpenCodeSessionDirs(messageDir) {
18
+ let entries;
19
+ try {
20
+ entries = await readdir(messageDir, { withFileTypes: true });
21
+ }
22
+ catch {
23
+ return [];
24
+ }
25
+ return entries
26
+ .filter((e) => e.isDirectory())
27
+ .map((e) => join(messageDir, e.name))
28
+ .sort();
29
+ }
30
+ export const openCodeJsonSessionDriver = {
31
+ kind: "file",
32
+ source: "opencode",
33
+ async discover(opts) {
34
+ if (!opts.openCodeMessageDir)
35
+ return [];
36
+ return discoverOpenCodeSessionDirs(opts.openCodeMessageDir);
37
+ },
38
+ shouldSkip(cursor, fingerprint) {
39
+ if (!cursor)
40
+ return false;
41
+ // Directories: mtime-only comparison (size unreliable across filesystems)
42
+ return cursor.mtimeMs === fingerprint.mtimeMs;
43
+ },
44
+ async parse(dirPath) {
45
+ return collectOpenCodeSessions(dirPath);
46
+ },
47
+ buildCursor(fingerprint) {
48
+ return { mtimeMs: fingerprint.mtimeMs };
49
+ },
50
+ };
51
+ //# sourceMappingURL=opencode-json-session-driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode-json-session-driver.js","sourceRoot":"","sources":["../../../src/drivers/session/opencode-json-session-driver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAO5E;;;;;GAKG;AACH,KAAK,UAAU,2BAA2B,CACxC,UAAkB;IAElB,IAAI,OAAmC,CAAC;IACxC,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;SACpC,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,CAAC,MAAM,yBAAyB,GAAiD;IACrF,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,UAAU;IAElB,KAAK,CAAC,QAAQ,CAAC,IAAkB;QAC/B,IAAI,CAAC,IAAI,CAAC,kBAAkB;YAAE,OAAO,EAAE,CAAC;QACxC,OAAO,2BAA2B,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC9D,CAAC;IAED,UAAU,CACR,MAA6C,EAC7C,WAA4B;QAE5B,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC1B,0EAA0E;QAC1E,OAAO,MAAM,CAAC,OAAO,KAAK,WAAW,CAAC,OAAO,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAAe;QACzB,OAAO,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,WAAW,CAAC,WAA4B;QACtC,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC;IAC1C,CAAC;CACF,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * OpenCode SQLite DB session driver.
3
+ *
4
+ * Strategy: Watermark-based query (WHERE time_updated >= ?).
5
+ * Manages its own DB handle lifecycle.
6
+ * Deduplicates via lastProcessedIds for same-millisecond boundary rows.
7
+ */
8
+ import type { OpenCodeSqliteSessionCursor } from "@pew/core";
9
+ import type { SessionRow, SessionMessageRow } from "../../parsers/opencode-sqlite-session.js";
10
+ import type { DbSessionDriver } from "../types.js";
11
+ /** Options needed to construct the SQLite session driver */
12
+ export interface OpenCodeSqliteSessionDriverOpts {
13
+ /** Path to the OpenCode SQLite database */
14
+ dbPath: string;
15
+ /** Factory for opening the DB (DI for testability) */
16
+ openSessionDb: (dbPath: string) => {
17
+ querySessions: (lastTimeUpdated: number) => SessionRow[];
18
+ querySessionMessages: (sessionIds: string[]) => SessionMessageRow[];
19
+ close: () => void;
20
+ } | null;
21
+ }
22
+ export declare function createOpenCodeSqliteSessionDriver(opts: OpenCodeSqliteSessionDriverOpts): DbSessionDriver<OpenCodeSqliteSessionCursor>;
23
+ //# sourceMappingURL=opencode-sqlite-session-driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode-sqlite-session-driver.d.ts","sourceRoot":"","sources":["../../../src/drivers/session/opencode-sqlite-session-driver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAC;AAE7D,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAC9F,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,aAAa,CAAC;AAEjF,4DAA4D;AAC5D,MAAM,WAAW,+BAA+B;IAC9C,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK;QACjC,aAAa,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,UAAU,EAAE,CAAC;QACzD,oBAAoB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,iBAAiB,EAAE,CAAC;QACpE,KAAK,EAAE,MAAM,IAAI,CAAC;KACnB,GAAG,IAAI,CAAC;CACV;AAED,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,+BAA+B,GACpC,eAAe,CAAC,2BAA2B,CAAC,CA6F9C"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * OpenCode SQLite DB session driver.
3
+ *
4
+ * Strategy: Watermark-based query (WHERE time_updated >= ?).
5
+ * Manages its own DB handle lifecycle.
6
+ * Deduplicates via lastProcessedIds for same-millisecond boundary rows.
7
+ */
8
+ import { stat } from "node:fs/promises";
9
+ import { collectOpenCodeSqliteSessions } from "../../parsers/opencode-sqlite-session.js";
10
+ export function createOpenCodeSqliteSessionDriver(opts) {
11
+ return {
12
+ kind: "db",
13
+ source: "opencode",
14
+ async run(prevCursor, _ctx) {
15
+ // Check if DB file exists
16
+ const dbStat = await stat(opts.dbPath).catch(() => null);
17
+ if (!dbStat) {
18
+ return {
19
+ snapshots: [],
20
+ cursor: prevCursor ?? {
21
+ lastTimeUpdated: 0,
22
+ lastProcessedIds: [],
23
+ inode: 0,
24
+ updatedAt: new Date().toISOString(),
25
+ },
26
+ rowCount: 0,
27
+ };
28
+ }
29
+ const dbInode = dbStat.ino;
30
+ // If inode changed (DB recreated), reset cursor
31
+ const lastTimeUpdated = prevCursor && prevCursor.inode === dbInode
32
+ ? prevCursor.lastTimeUpdated
33
+ : 0;
34
+ const prevProcessedIds = new Set(prevCursor && prevCursor.inode === dbInode
35
+ ? (prevCursor.lastProcessedIds ?? [])
36
+ : []);
37
+ const handle = opts.openSessionDb(opts.dbPath);
38
+ if (!handle) {
39
+ return {
40
+ snapshots: [],
41
+ cursor: prevCursor ?? {
42
+ lastTimeUpdated: 0,
43
+ lastProcessedIds: [],
44
+ inode: dbInode,
45
+ updatedAt: new Date().toISOString(),
46
+ },
47
+ rowCount: 0,
48
+ };
49
+ }
50
+ try {
51
+ // Query uses >= to avoid missing same-millisecond rows.
52
+ // We dedup previously-processed IDs from the prior batch.
53
+ const rawSessions = handle.querySessions(lastTimeUpdated);
54
+ const sessions = prevProcessedIds.size > 0
55
+ ? rawSessions.filter((s) => !prevProcessedIds.has(s.id))
56
+ : rawSessions;
57
+ let snapshots = [];
58
+ if (sessions.length > 0) {
59
+ const sessionIds = sessions.map((s) => s.id);
60
+ const messages = handle.querySessionMessages(sessionIds);
61
+ snapshots = collectOpenCodeSqliteSessions(sessions, messages);
62
+ }
63
+ // Update cursor — advance past ALL queried sessions.
64
+ // Sessions are ORDER BY time_updated ASC, so last has the max.
65
+ const maxTimeUpdated = rawSessions.length > 0
66
+ ? rawSessions[rawSessions.length - 1].time_updated
67
+ : lastTimeUpdated;
68
+ const idsAtMax = rawSessions
69
+ .filter((s) => s.time_updated === maxTimeUpdated)
70
+ .map((s) => s.id);
71
+ return {
72
+ snapshots,
73
+ cursor: {
74
+ lastTimeUpdated: maxTimeUpdated,
75
+ lastProcessedIds: idsAtMax,
76
+ inode: dbInode,
77
+ updatedAt: new Date().toISOString(),
78
+ },
79
+ rowCount: rawSessions.length,
80
+ };
81
+ }
82
+ finally {
83
+ handle.close();
84
+ }
85
+ },
86
+ };
87
+ }
88
+ //# sourceMappingURL=opencode-sqlite-session-driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode-sqlite-session-driver.js","sourceRoot":"","sources":["../../../src/drivers/session/opencode-sqlite-session-driver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Claude Code file token driver.
3
+ *
4
+ * Strategy: Byte-offset JSONL streaming.
5
+ * Skip gate: fileUnchanged() (inode + mtimeMs + size).
6
+ * Parser: parseClaudeFile({ filePath, startOffset })
7
+ */
8
+ import type { ByteOffsetCursor } from "@pew/core";
9
+ import type { FileTokenDriver } from "../types.js";
10
+ export declare const claudeTokenDriver: FileTokenDriver<ByteOffsetCursor>;
11
+ //# sourceMappingURL=claude-token-driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-token-driver.d.ts","sourceRoot":"","sources":["../../../src/drivers/token/claude-token-driver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAIlD,OAAO,KAAK,EACV,eAAe,EAOhB,MAAM,aAAa,CAAC;AAOrB,eAAO,MAAM,iBAAiB,EAAE,eAAe,CAAC,gBAAgB,CAuC/D,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Claude Code file token driver.
3
+ *
4
+ * Strategy: Byte-offset JSONL streaming.
5
+ * Skip gate: fileUnchanged() (inode + mtimeMs + size).
6
+ * Parser: parseClaudeFile({ filePath, startOffset })
7
+ */
8
+ import { discoverClaudeFiles } from "../../discovery/sources.js";
9
+ import { parseClaudeFile } from "../../parsers/claude.js";
10
+ import { fileUnchanged } from "../../utils/file-changed.js";
11
+ export const claudeTokenDriver = {
12
+ kind: "file",
13
+ source: "claude-code",
14
+ async discover(opts, _ctx) {
15
+ if (!opts.claudeDir)
16
+ return [];
17
+ return discoverClaudeFiles(opts.claudeDir);
18
+ },
19
+ shouldSkip(cursor, fingerprint) {
20
+ return fileUnchanged(cursor, fingerprint);
21
+ },
22
+ resumeState(cursor, fingerprint) {
23
+ const startOffset = cursor && cursor.inode === fingerprint.inode ? (cursor.offset ?? 0) : 0;
24
+ return { kind: "byte-offset", startOffset };
25
+ },
26
+ async parse(filePath, resume) {
27
+ const r = resume;
28
+ const result = await parseClaudeFile({ filePath, startOffset: r.startOffset });
29
+ return { deltas: result.deltas, endOffset: result.endOffset };
30
+ },
31
+ buildCursor(fingerprint, result, _prev) {
32
+ const r = result;
33
+ return {
34
+ inode: fingerprint.inode,
35
+ mtimeMs: fingerprint.mtimeMs,
36
+ size: fingerprint.size,
37
+ offset: r.endOffset,
38
+ updatedAt: new Date().toISOString(),
39
+ };
40
+ },
41
+ };
42
+ //# sourceMappingURL=claude-token-driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-token-driver.js","sourceRoot":"","sources":["../../../src/drivers/token/claude-token-driver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAgB5D,MAAM,CAAC,MAAM,iBAAiB,GAAsC;IAClE,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,aAAa;IAErB,KAAK,CAAC,QAAQ,CAAC,IAAkB,EAAE,IAAiB;QAClD,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,CAAC;QAC/B,OAAO,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;IAED,UAAU,CAAC,MAAoC,EAAE,WAA4B;QAC3E,OAAO,aAAa,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC5C,CAAC;IAED,WAAW,CAAC,MAAoC,EAAE,WAA4B;QAC5E,MAAM,WAAW,GACf,MAAM,IAAI,MAAM,CAAC,KAAK,KAAK,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1E,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB,EAAE,MAAmB;QAC/C,MAAM,CAAC,GAAG,MAA+B,CAAC;QAC1C,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAC/E,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;IAChE,CAAC;IAED,WAAW,CACT,WAA4B,EAC5B,MAAwB,EACxB,KAAwB;QAExB,MAAM,CAAC,GAAG,MAA2B,CAAC;QACtC,OAAO;YACL,KAAK,EAAE,WAAW,CAAC,KAAK;YACxB,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,MAAM,EAAE,CAAC,CAAC,SAAS;YACnB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Codex CLI file token driver.
3
+ *
4
+ * Strategy: Byte-offset JSONL streaming + cumulative diff.
5
+ * Skip gate: fileUnchanged() (inode + mtimeMs + size).
6
+ * Parser: parseCodexFile({ filePath, startOffset, lastTotals, lastModel })
7
+ */
8
+ import type { CodexCursor } from "@pew/core";
9
+ import type { FileTokenDriver } from "../types.js";
10
+ export declare const codexTokenDriver: FileTokenDriver<CodexCursor>;
11
+ //# sourceMappingURL=codex-token-driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-token-driver.d.ts","sourceRoot":"","sources":["../../../src/drivers/token/codex-token-driver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,WAAW,CAAC;AAIzD,OAAO,KAAK,EACV,eAAe,EAOhB,MAAM,aAAa,CAAC;AASrB,eAAO,MAAM,gBAAgB,EAAE,eAAe,CAAC,WAAW,CAuDzD,CAAC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Codex CLI file token driver.
3
+ *
4
+ * Strategy: Byte-offset JSONL streaming + cumulative diff.
5
+ * Skip gate: fileUnchanged() (inode + mtimeMs + size).
6
+ * Parser: parseCodexFile({ filePath, startOffset, lastTotals, lastModel })
7
+ */
8
+ import { discoverCodexFiles } from "../../discovery/sources.js";
9
+ import { parseCodexFile } from "../../parsers/codex.js";
10
+ import { fileUnchanged } from "../../utils/file-changed.js";
11
+ export const codexTokenDriver = {
12
+ kind: "file",
13
+ source: "codex",
14
+ async discover(opts, _ctx) {
15
+ if (!opts.codexSessionsDir)
16
+ return [];
17
+ return discoverCodexFiles(opts.codexSessionsDir);
18
+ },
19
+ shouldSkip(cursor, fingerprint) {
20
+ return fileUnchanged(cursor, fingerprint);
21
+ },
22
+ resumeState(cursor, fingerprint) {
23
+ const sameFile = cursor && cursor.inode === fingerprint.inode;
24
+ return {
25
+ kind: "codex",
26
+ startOffset: sameFile ? (cursor.offset ?? 0) : 0,
27
+ lastTotals: sameFile ? (cursor.lastTotals ?? null) : null,
28
+ lastModel: sameFile ? (cursor.lastModel ?? null) : null,
29
+ };
30
+ },
31
+ async parse(filePath, resume) {
32
+ const r = resume;
33
+ const result = await parseCodexFile({
34
+ filePath,
35
+ startOffset: r.startOffset,
36
+ lastTotals: r.lastTotals,
37
+ lastModel: r.lastModel,
38
+ });
39
+ return {
40
+ deltas: result.deltas,
41
+ endOffset: result.endOffset,
42
+ lastTotals: result.lastTotals,
43
+ lastModel: result.lastModel,
44
+ };
45
+ },
46
+ buildCursor(fingerprint, result, _prev) {
47
+ const r = result;
48
+ return {
49
+ inode: fingerprint.inode,
50
+ mtimeMs: fingerprint.mtimeMs,
51
+ size: fingerprint.size,
52
+ offset: r.endOffset,
53
+ lastTotals: r.lastTotals,
54
+ lastModel: r.lastModel,
55
+ updatedAt: new Date().toISOString(),
56
+ };
57
+ },
58
+ };
59
+ //# sourceMappingURL=codex-token-driver.js.map