@nocoo/pew 0.4.0 → 0.6.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 (88) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +117 -8
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/session-sync.d.ts +62 -0
  5. package/dist/commands/session-sync.d.ts.map +1 -0
  6. package/dist/commands/session-sync.js +443 -0
  7. package/dist/commands/session-sync.js.map +1 -0
  8. package/dist/commands/session-upload.d.ts +39 -0
  9. package/dist/commands/session-upload.d.ts.map +1 -0
  10. package/dist/commands/session-upload.js +45 -0
  11. package/dist/commands/session-upload.js.map +1 -0
  12. package/dist/commands/status.d.ts +9 -0
  13. package/dist/commands/status.d.ts.map +1 -1
  14. package/dist/commands/status.js +22 -11
  15. package/dist/commands/status.js.map +1 -1
  16. package/dist/commands/sync.d.ts +12 -0
  17. package/dist/commands/sync.d.ts.map +1 -1
  18. package/dist/commands/sync.js +159 -3
  19. package/dist/commands/sync.js.map +1 -1
  20. package/dist/commands/upload-engine.d.ts +63 -0
  21. package/dist/commands/upload-engine.d.ts.map +1 -0
  22. package/dist/commands/upload-engine.js +164 -0
  23. package/dist/commands/upload-engine.js.map +1 -0
  24. package/dist/commands/upload.d.ts +5 -21
  25. package/dist/commands/upload.d.ts.map +1 -1
  26. package/dist/commands/upload.js +11 -144
  27. package/dist/commands/upload.js.map +1 -1
  28. package/dist/discovery/sources.d.ts +5 -0
  29. package/dist/discovery/sources.d.ts.map +1 -1
  30. package/dist/discovery/sources.js +7 -0
  31. package/dist/discovery/sources.js.map +1 -1
  32. package/dist/parsers/claude-session.d.ts +19 -0
  33. package/dist/parsers/claude-session.d.ts.map +1 -0
  34. package/dist/parsers/claude-session.js +131 -0
  35. package/dist/parsers/claude-session.js.map +1 -0
  36. package/dist/parsers/codex-session.d.ts +24 -0
  37. package/dist/parsers/codex-session.d.ts.map +1 -0
  38. package/dist/parsers/codex-session.js +140 -0
  39. package/dist/parsers/codex-session.js.map +1 -0
  40. package/dist/parsers/codex.d.ts +37 -0
  41. package/dist/parsers/codex.d.ts.map +1 -0
  42. package/dist/parsers/codex.js +136 -0
  43. package/dist/parsers/codex.js.map +1 -0
  44. package/dist/parsers/gemini-session.d.ts +19 -0
  45. package/dist/parsers/gemini-session.d.ts.map +1 -0
  46. package/dist/parsers/gemini-session.js +103 -0
  47. package/dist/parsers/gemini-session.js.map +1 -0
  48. package/dist/parsers/openclaw-session.d.ts +20 -0
  49. package/dist/parsers/openclaw-session.d.ts.map +1 -0
  50. package/dist/parsers/openclaw-session.js +122 -0
  51. package/dist/parsers/openclaw-session.js.map +1 -0
  52. package/dist/parsers/opencode-session.d.ts +15 -0
  53. package/dist/parsers/opencode-session.d.ts.map +1 -0
  54. package/dist/parsers/opencode-session.js +131 -0
  55. package/dist/parsers/opencode-session.js.map +1 -0
  56. package/dist/parsers/opencode-sqlite-db.d.ts +29 -0
  57. package/dist/parsers/opencode-sqlite-db.d.ts.map +1 -0
  58. package/dist/parsers/opencode-sqlite-db.js +71 -0
  59. package/dist/parsers/opencode-sqlite-db.js.map +1 -0
  60. package/dist/parsers/opencode-sqlite-session.d.ts +32 -0
  61. package/dist/parsers/opencode-sqlite-session.d.ts.map +1 -0
  62. package/dist/parsers/opencode-sqlite-session.js +121 -0
  63. package/dist/parsers/opencode-sqlite-session.js.map +1 -0
  64. package/dist/parsers/opencode-sqlite.d.ts +53 -0
  65. package/dist/parsers/opencode-sqlite.d.ts.map +1 -0
  66. package/dist/parsers/opencode-sqlite.js +104 -0
  67. package/dist/parsers/opencode-sqlite.js.map +1 -0
  68. package/dist/storage/base-queue.d.ts +40 -0
  69. package/dist/storage/base-queue.d.ts.map +1 -0
  70. package/dist/storage/base-queue.js +89 -0
  71. package/dist/storage/base-queue.js.map +1 -0
  72. package/dist/storage/local-queue.d.ts +4 -24
  73. package/dist/storage/local-queue.d.ts.map +1 -1
  74. package/dist/storage/local-queue.js +5 -64
  75. package/dist/storage/local-queue.js.map +1 -1
  76. package/dist/storage/session-cursor-store.d.ts +14 -0
  77. package/dist/storage/session-cursor-store.d.ts.map +1 -0
  78. package/dist/storage/session-cursor-store.js +34 -0
  79. package/dist/storage/session-cursor-store.js.map +1 -0
  80. package/dist/storage/session-queue.d.ts +10 -0
  81. package/dist/storage/session-queue.d.ts.map +1 -0
  82. package/dist/storage/session-queue.js +11 -0
  83. package/dist/storage/session-queue.js.map +1 -0
  84. package/dist/utils/paths.d.ts +4 -0
  85. package/dist/utils/paths.d.ts.map +1 -1
  86. package/dist/utils/paths.js +5 -0
  87. package/dist/utils/paths.js.map +1 -1
  88. package/package.json +1 -1
@@ -1,22 +1,11 @@
1
1
  /**
2
- * CLI upload command — sends local queue records to the Pew SaaS.
2
+ * CLI upload command — sends local token queue records to the Pew SaaS.
3
3
  *
4
- * Flow:
5
- * 1. Load API key from config
6
- * 2. Read un-uploaded records from queue (using saved offset)
7
- * 3. Split into batches of ≤50 (D1 Free plan: 50 queries/Worker invocation)
8
- * 4. POST each batch to /api/ingest with Bearer token
9
- * 5. Persist offset after each successful batch (for resume on failure)
10
- * 6. Retry on 5xx with exponential backoff
4
+ * Thin wrapper around the generic upload engine with token-specific
5
+ * preprocessing (aggregation by source/model/hour_start).
11
6
  */
12
- import { ConfigManager } from "../config/manager.js";
13
7
  import { LocalQueue } from "../storage/local-queue.js";
14
- // ---------------------------------------------------------------------------
15
- // Constants
16
- // ---------------------------------------------------------------------------
17
- const DEFAULT_BATCH_SIZE = 50;
18
- const DEFAULT_MAX_RETRIES = 2;
19
- const DEFAULT_RETRY_DELAY_MS = 1000;
8
+ import { createUploadEngine } from "./upload-engine.js";
20
9
  // ---------------------------------------------------------------------------
21
10
  // Pre-aggregation — merge QueueRecords with the same (source, model, hour_start)
22
11
  // ---------------------------------------------------------------------------
@@ -51,135 +40,13 @@ export function aggregateRecords(records) {
51
40
  // Implementation
52
41
  // ---------------------------------------------------------------------------
53
42
  export async function executeUpload(opts) {
54
- const { stateDir, apiUrl, dev = false, fetch: fetchFn, batchSize = DEFAULT_BATCH_SIZE, maxRetries = DEFAULT_MAX_RETRIES, retryDelayMs = DEFAULT_RETRY_DELAY_MS, onProgress, } = opts;
55
- // 1. Load API key
56
- const configManager = new ConfigManager(stateDir, dev);
57
- const config = await configManager.load();
58
- if (!config.token) {
59
- return {
60
- success: false,
61
- uploaded: 0,
62
- batches: 0,
63
- error: "Not logged in. Run `pew login` first.",
64
- };
65
- }
66
- // 2. Read un-uploaded records
67
- const queue = new LocalQueue(stateDir);
68
- const currentOffset = await queue.loadOffset();
69
- const { records: rawRecords, newOffset } = await queue.readFromOffset(currentOffset);
70
- if (rawRecords.length === 0) {
71
- return { success: true, uploaded: 0, batches: 0 };
72
- }
73
- // 2b. Pre-aggregate by (source, model, hour_start) for idempotent upsert
74
- const records = aggregateRecords(rawRecords);
75
- // 3. Split into batches
76
- const batches = [];
77
- for (let i = 0; i < records.length; i += batchSize) {
78
- batches.push(records.slice(i, i + batchSize));
79
- }
80
- // 4. Upload each batch
81
- const endpoint = `${apiUrl}/api/ingest`;
82
- let totalUploaded = 0;
83
- let batchesCompleted = 0;
84
- for (let batchIdx = 0; batchIdx < batches.length; batchIdx++) {
85
- const batch = batches[batchIdx];
86
- onProgress?.({
87
- phase: "uploading",
88
- batch: batchIdx + 1,
89
- totalBatches: batches.length,
90
- total: records.length,
91
- message: `Uploading batch ${batchIdx + 1}/${batches.length} (${batch.length} records)...`,
92
- });
93
- const result = await sendBatchWithRetry({
94
- endpoint,
95
- token: config.token,
96
- batch,
97
- fetchFn,
98
- maxRetries,
99
- retryDelayMs,
100
- });
101
- if (!result.ok) {
102
- // With idempotent overwrite upsert, don't save partial offset.
103
- // Next retry will re-aggregate and re-send everything safely.
104
- return {
105
- success: false,
106
- uploaded: totalUploaded,
107
- batches: batchesCompleted,
108
- error: result.error,
109
- };
110
- }
111
- totalUploaded += batch.length;
112
- batchesCompleted++;
113
- }
114
- // 5. All batches succeeded — save final offset
115
- await queue.saveOffset(newOffset);
116
- onProgress?.({
117
- phase: "done",
118
- total: totalUploaded,
119
- message: `Uploaded ${totalUploaded} records in ${batchesCompleted} batch(es).`,
43
+ const queue = new LocalQueue(opts.stateDir);
44
+ const engine = createUploadEngine({
45
+ queue,
46
+ endpoint: "/api/ingest",
47
+ entityName: "records",
48
+ preprocess: aggregateRecords,
120
49
  });
121
- return {
122
- success: true,
123
- uploaded: totalUploaded,
124
- batches: batchesCompleted,
125
- };
126
- }
127
- async function sendBatchWithRetry(opts) {
128
- const { endpoint, token, batch, fetchFn, maxRetries, retryDelayMs } = opts;
129
- let lastError = "";
130
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
131
- if (attempt > 0 && retryDelayMs > 0) {
132
- await sleep(retryDelayMs * 2 ** (attempt - 1));
133
- }
134
- try {
135
- const resp = await fetchFn(endpoint, {
136
- method: "POST",
137
- headers: {
138
- "Content-Type": "application/json",
139
- Authorization: `Bearer ${token}`,
140
- },
141
- body: JSON.stringify(batch),
142
- });
143
- if (resp.ok) {
144
- return { ok: true };
145
- }
146
- // 429 — rate limited, retry with Retry-After if available
147
- if (resp.status === 429) {
148
- const retryAfter = resp.headers.get("Retry-After");
149
- const retryMs = retryAfter
150
- ? Math.max(Number(retryAfter) * 1000, retryDelayMs)
151
- : retryDelayMs * 2 ** attempt;
152
- if (attempt < maxRetries && retryMs > 0) {
153
- await sleep(retryMs);
154
- }
155
- const body = await resp.json().catch(() => ({}));
156
- lastError = `429: ${body.error ?? "Too Many Requests"}`;
157
- continue;
158
- }
159
- // 4xx — client error, don't retry
160
- if (resp.status >= 400 && resp.status < 500) {
161
- const body = await resp.json().catch(() => ({}));
162
- const msg = body.error ?? `HTTP ${resp.status}`;
163
- return { ok: false, error: `${resp.status}: ${msg}` };
164
- }
165
- // 5xx — server error, retry
166
- const body = await resp.json().catch(() => ({}));
167
- lastError = `${resp.status}: ${body.error ?? "Server Error"}`;
168
- }
169
- catch (err) {
170
- lastError = String(err.message ?? err);
171
- // Network errors — don't retry if maxRetries is 0
172
- if (attempt >= maxRetries) {
173
- return { ok: false, error: lastError };
174
- }
175
- }
176
- }
177
- return {
178
- ok: false,
179
- error: `Upload failed after ${maxRetries + 1} attempts: ${lastError}`,
180
- };
181
- }
182
- function sleep(ms) {
183
- return new Promise((resolve) => setTimeout(resolve, ms));
50
+ return engine.execute(opts);
184
51
  }
185
52
  //# sourceMappingURL=upload.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAiCxD,8EAA8E;AAC9E,iFAAiF;AACjF,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAsB;IACrD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEpC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAuB,CAAC;IAE3C,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;QACrD,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,YAAY,IAAI,CAAC,CAAC,YAAY,CAAC;YACxC,QAAQ,CAAC,mBAAmB,IAAI,CAAC,CAAC,mBAAmB,CAAC;YACtD,QAAQ,CAAC,aAAa,IAAI,CAAC,CAAC,aAAa,CAAC;YAC1C,QAAQ,CAAC,uBAAuB,IAAI,CAAC,CAAC,uBAAuB,CAAC;YAC9D,QAAQ,CAAC,YAAY,IAAI,CAAC,CAAC,YAAY,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;AAC3B,CAAC;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAmB;IACrD,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAE5C,MAAM,MAAM,GAAG,kBAAkB,CAAc;QAC7C,KAAK;QACL,QAAQ,EAAE,aAAa;QACvB,UAAU,EAAE,SAAS;QACrB,UAAU,EAAE,gBAAgB;KAC7B,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC"}
@@ -34,4 +34,9 @@ export declare function discoverOpenCodeFiles(messageDir: string, knownDirMtimes
34
34
  * Path pattern: ~/.openclaw/agents/\*\/sessions/*.jsonl
35
35
  */
36
36
  export declare function discoverOpenClawFiles(openclawDir: string): Promise<string[]>;
37
+ /**
38
+ * Discover Codex CLI rollout files.
39
+ * Path pattern: ~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl
40
+ */
41
+ export declare function discoverCodexFiles(codexSessionsDir: string): Promise<string[]>;
37
42
  //# sourceMappingURL=sources.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../../src/discovery/sources.ts"],"names":[],"mappings":"AAoCA;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC,CAGnB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC,CAKnB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,6DAA6D;IAC7D,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACtC,OAAO,CAAC,uBAAuB,CAAC,CAiDlC;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,EAAE,CAAC,CAGnB"}
1
+ {"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../../src/discovery/sources.ts"],"names":[],"mappings":"AAoCA;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC,CAGnB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC,CAKnB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,6DAA6D;IAC7D,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACtC,OAAO,CAAC,uBAAuB,CAAC,CAiDlC;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,EAAE,CAAC,CAGnB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC,CAInB"}
@@ -107,4 +107,11 @@ export async function discoverOpenClawFiles(openclawDir) {
107
107
  const agentsDir = join(openclawDir, "agents");
108
108
  return collectFiles(agentsDir, (name) => name.endsWith(".jsonl"));
109
109
  }
110
+ /**
111
+ * Discover Codex CLI rollout files.
112
+ * Path pattern: ~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl
113
+ */
114
+ export async function discoverCodexFiles(codexSessionsDir) {
115
+ return collectFiles(codexSessionsDir, (name) => name.startsWith("rollout-") && name.endsWith(".jsonl"));
116
+ }
110
117
  //# sourceMappingURL=sources.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sources.js","sourceRoot":"","sources":["../../src/discovery/sources.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sources.js","sourceRoot":"","sources":["../../src/discovery/sources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Claude Code session collector.
3
+ *
4
+ * Full-scans a Claude JSONL file and extracts session-level metadata.
5
+ * Groups lines by sessionId, counts message types, computes duration.
6
+ */
7
+ import type { SessionSnapshot } from "@pew/core";
8
+ /**
9
+ * Collect session snapshots from a Claude Code JSONL file.
10
+ *
11
+ * Each line may contain a sessionId. Lines are grouped by sessionId,
12
+ * and for each group we produce a SessionSnapshot with:
13
+ * - message counts (user/assistant/total)
14
+ * - wall-clock duration (min timestamp → max timestamp)
15
+ * - last seen model
16
+ * - project ref from file path
17
+ */
18
+ export declare function collectClaudeSessions(filePath: string): Promise<SessionSnapshot[]>;
19
+ //# sourceMappingURL=claude-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-session.d.ts","sourceRoot":"","sources":["../../src/parsers/claude-session.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAU,MAAM,WAAW,CAAC;AA2BzD;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,EAAE,CAAC,CA0G5B"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Claude Code session collector.
3
+ *
4
+ * Full-scans a Claude JSONL file and extracts session-level metadata.
5
+ * Groups lines by sessionId, counts message types, computes duration.
6
+ */
7
+ import { createReadStream } from "node:fs";
8
+ import { stat } from "node:fs/promises";
9
+ import { createInterface } from "node:readline";
10
+ /**
11
+ * Extract the project reference from a Claude file path.
12
+ *
13
+ * Claude stores files under ~/.claude/projects/{hash}/{file}.jsonl.
14
+ * We extract the directory name immediately after "projects/".
15
+ * Returns null if the path doesn't contain "projects/".
16
+ */
17
+ function extractProjectRef(filePath) {
18
+ const parts = filePath.split("/");
19
+ const projectsIdx = parts.lastIndexOf("projects");
20
+ if (projectsIdx < 0 || projectsIdx + 1 >= parts.length - 1)
21
+ return null;
22
+ return parts[projectsIdx + 1] || null;
23
+ }
24
+ /**
25
+ * Collect session snapshots from a Claude Code JSONL file.
26
+ *
27
+ * Each line may contain a sessionId. Lines are grouped by sessionId,
28
+ * and for each group we produce a SessionSnapshot with:
29
+ * - message counts (user/assistant/total)
30
+ * - wall-clock duration (min timestamp → max timestamp)
31
+ * - last seen model
32
+ * - project ref from file path
33
+ */
34
+ export async function collectClaudeSessions(filePath) {
35
+ const st = await stat(filePath).catch(() => null);
36
+ if (!st || !st.isFile() || st.size === 0)
37
+ return [];
38
+ const sessions = new Map();
39
+ const stream = createReadStream(filePath, { encoding: "utf8" });
40
+ const rl = createInterface({ input: stream, crlfDelay: Infinity });
41
+ try {
42
+ for await (const line of rl) {
43
+ if (!line)
44
+ continue;
45
+ let obj;
46
+ try {
47
+ obj = JSON.parse(line);
48
+ }
49
+ catch {
50
+ continue;
51
+ }
52
+ const sessionId = typeof obj.sessionId === "string" ? obj.sessionId : null;
53
+ if (!sessionId)
54
+ continue;
55
+ const timestamp = typeof obj.timestamp === "string" ? obj.timestamp : null;
56
+ const type = typeof obj.type === "string" ? obj.type : null;
57
+ // Get or create session accumulator
58
+ let accum = sessions.get(sessionId);
59
+ if (!accum) {
60
+ accum = {
61
+ sessionId,
62
+ userMessages: 0,
63
+ assistantMessages: 0,
64
+ totalMessages: 0,
65
+ minTimestamp: null,
66
+ maxTimestamp: null,
67
+ lastModel: null,
68
+ };
69
+ sessions.set(sessionId, accum);
70
+ }
71
+ // Count messages
72
+ accum.totalMessages++;
73
+ if (type === "user") {
74
+ accum.userMessages++;
75
+ }
76
+ else if (type === "assistant") {
77
+ accum.assistantMessages++;
78
+ }
79
+ // Track timestamps
80
+ if (timestamp) {
81
+ if (!accum.minTimestamp || timestamp < accum.minTimestamp) {
82
+ accum.minTimestamp = timestamp;
83
+ }
84
+ if (!accum.maxTimestamp || timestamp > accum.maxTimestamp) {
85
+ accum.maxTimestamp = timestamp;
86
+ }
87
+ }
88
+ // Track model (from message.model or obj.model)
89
+ const msg = obj.message;
90
+ const model = typeof msg?.model === "string"
91
+ ? msg.model.trim()
92
+ : typeof obj.model === "string"
93
+ ? obj.model.trim()
94
+ : null;
95
+ if (model) {
96
+ accum.lastModel = model;
97
+ }
98
+ }
99
+ }
100
+ finally {
101
+ rl.close();
102
+ stream.destroy();
103
+ }
104
+ // Convert accumulators to snapshots
105
+ const projectRef = extractProjectRef(filePath);
106
+ const snapshotAt = new Date().toISOString();
107
+ const results = [];
108
+ for (const accum of sessions.values()) {
109
+ if (!accum.minTimestamp)
110
+ continue; // no valid timestamps → skip
111
+ const startedAt = accum.minTimestamp;
112
+ const lastMessageAt = accum.maxTimestamp ?? accum.minTimestamp;
113
+ const durationMs = new Date(lastMessageAt).getTime() - new Date(startedAt).getTime();
114
+ results.push({
115
+ sessionKey: `claude:${accum.sessionId}`,
116
+ source: "claude-code",
117
+ kind: "human",
118
+ startedAt,
119
+ lastMessageAt,
120
+ durationSeconds: Math.max(0, Math.floor(durationMs / 1000)),
121
+ userMessages: accum.userMessages,
122
+ assistantMessages: accum.assistantMessages,
123
+ totalMessages: accum.totalMessages,
124
+ projectRef,
125
+ model: accum.lastModel,
126
+ snapshotAt,
127
+ });
128
+ }
129
+ return results;
130
+ }
131
+ //# sourceMappingURL=claude-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-session.js","sourceRoot":"","sources":["../../src/parsers/claude-session.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAehD;;;;;;GAMG;AACH,SAAS,iBAAiB,CAAC,QAAgB;IACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAClD,IAAI,WAAW,GAAG,CAAC,IAAI,WAAW,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACxE,OAAO,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;AACxC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,QAAgB;IAEhB,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEpD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAwB,CAAC;IAEjD,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IAChE,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEnE,IAAI,CAAC;QACH,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,EAAE,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI;gBAAE,SAAS;YAEpB,IAAI,GAA4B,CAAC;YACjC,IAAI,CAAC;gBACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YAED,MAAM,SAAS,GAAG,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;YAC3E,IAAI,CAAC,SAAS;gBAAE,SAAS;YAEzB,MAAM,SAAS,GAAG,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;YAC3E,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;YAE5D,oCAAoC;YACpC,IAAI,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACpC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,KAAK,GAAG;oBACN,SAAS;oBACT,YAAY,EAAE,CAAC;oBACf,iBAAiB,EAAE,CAAC;oBACpB,aAAa,EAAE,CAAC;oBAChB,YAAY,EAAE,IAAI;oBAClB,YAAY,EAAE,IAAI;oBAClB,SAAS,EAAE,IAAI;iBAChB,CAAC;gBACF,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YACjC,CAAC;YAED,iBAAiB;YACjB,KAAK,CAAC,aAAa,EAAE,CAAC;YACtB,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBACpB,KAAK,CAAC,YAAY,EAAE,CAAC;YACvB,CAAC;iBAAM,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;gBAChC,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,CAAC;YAED,mBAAmB;YACnB,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,SAAS,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC;oBAC1D,KAAK,CAAC,YAAY,GAAG,SAAS,CAAC;gBACjC,CAAC;gBACD,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,SAAS,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC;oBAC1D,KAAK,CAAC,YAAY,GAAG,SAAS,CAAC;gBACjC,CAAC;YACH,CAAC;YAED,gDAAgD;YAChD,MAAM,GAAG,GAAG,GAAG,CAAC,OAA8C,CAAC;YAC/D,MAAM,KAAK,GACT,OAAO,GAAG,EAAE,KAAK,KAAK,QAAQ;gBAC5B,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE;gBAClB,CAAC,CAAC,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ;oBAC7B,CAAC,CAAE,GAAG,CAAC,KAAgB,CAAC,IAAI,EAAE;oBAC9B,CAAC,CAAC,IAAI,CAAC;YACb,IAAI,KAAK,EAAE,CAAC;gBACV,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;IAED,oCAAoC;IACpC,MAAM,UAAU,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAsB,EAAE,CAAC;IAEtC,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;QACtC,IAAI,CAAC,KAAK,CAAC,YAAY;YAAE,SAAS,CAAC,6BAA6B;QAEhE,MAAM,SAAS,GAAG,KAAK,CAAC,YAAY,CAAC;QACrC,MAAM,aAAa,GAAG,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,YAAY,CAAC;QAC/D,MAAM,UAAU,GACd,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QAEpE,OAAO,CAAC,IAAI,CAAC;YACX,UAAU,EAAE,UAAU,KAAK,CAAC,SAAS,EAAE;YACvC,MAAM,EAAE,aAAuB;YAC/B,IAAI,EAAE,OAAO;YACb,SAAS;YACT,aAAa;YACb,eAAe,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;YAC3D,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;YAC1C,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,UAAU;YACV,KAAK,EAAE,KAAK,CAAC,SAAS;YACtB,UAAU;SACX,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Codex CLI session collector.
3
+ *
4
+ * Full-scans a Codex JSONL rollout file and produces a single SessionSnapshot.
5
+ * Each rollout file represents one session. Codex is user-driven (kind: "human").
6
+ *
7
+ * Session ID comes from session_meta.payload.id (UUID).
8
+ * Project ref is a SHA-256 hash of session_meta.payload.cwd (privacy-safe).
9
+ * Model comes from turn_context.payload.model (preferred) or session_meta.payload.model (fallback).
10
+ *
11
+ * Message counting:
12
+ * - response_item with payload.role === "user" → userMessages
13
+ * - response_item with payload.role === "assistant" → assistantMessages
14
+ * - All valid JSON lines → totalMessages
15
+ */
16
+ import type { SessionSnapshot } from "@pew/core";
17
+ /**
18
+ * Collect session snapshots from a Codex CLI JSONL rollout file.
19
+ *
20
+ * Reads every line, extracts session metadata, counts messages,
21
+ * and produces 0 or 1 SessionSnapshot.
22
+ */
23
+ export declare function collectCodexSessions(filePath: string): Promise<SessionSnapshot[]>;
24
+ //# sourceMappingURL=codex-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-session.d.ts","sourceRoot":"","sources":["../../src/parsers/codex-session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAU,MAAM,WAAW,CAAC;AAEzD;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,EAAE,CAAC,CA2H5B"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Codex CLI session collector.
3
+ *
4
+ * Full-scans a Codex JSONL rollout file and produces a single SessionSnapshot.
5
+ * Each rollout file represents one session. Codex is user-driven (kind: "human").
6
+ *
7
+ * Session ID comes from session_meta.payload.id (UUID).
8
+ * Project ref is a SHA-256 hash of session_meta.payload.cwd (privacy-safe).
9
+ * Model comes from turn_context.payload.model (preferred) or session_meta.payload.model (fallback).
10
+ *
11
+ * Message counting:
12
+ * - response_item with payload.role === "user" → userMessages
13
+ * - response_item with payload.role === "assistant" → assistantMessages
14
+ * - All valid JSON lines → totalMessages
15
+ */
16
+ import { createReadStream } from "node:fs";
17
+ import { stat } from "node:fs/promises";
18
+ import { createInterface } from "node:readline";
19
+ import { createHash } from "node:crypto";
20
+ import { resolve } from "node:path";
21
+ /**
22
+ * Collect session snapshots from a Codex CLI JSONL rollout file.
23
+ *
24
+ * Reads every line, extracts session metadata, counts messages,
25
+ * and produces 0 or 1 SessionSnapshot.
26
+ */
27
+ export async function collectCodexSessions(filePath) {
28
+ const st = await stat(filePath).catch(() => null);
29
+ if (!st || !st.isFile() || st.size === 0)
30
+ return [];
31
+ let sessionId = null;
32
+ let projectRef = null;
33
+ let lastModel = null;
34
+ let userMessages = 0;
35
+ let assistantMessages = 0;
36
+ let totalMessages = 0;
37
+ let minTimestamp = null;
38
+ let maxTimestamp = null;
39
+ const stream = createReadStream(filePath, { encoding: "utf8" });
40
+ const rl = createInterface({ input: stream, crlfDelay: Infinity });
41
+ try {
42
+ for await (const line of rl) {
43
+ if (!line)
44
+ continue;
45
+ let obj;
46
+ try {
47
+ obj = JSON.parse(line);
48
+ }
49
+ catch {
50
+ continue;
51
+ }
52
+ totalMessages++;
53
+ const type = typeof obj.type === "string" ? obj.type : null;
54
+ const timestamp = typeof obj.timestamp === "string" ? obj.timestamp : null;
55
+ // Track timestamps
56
+ if (timestamp) {
57
+ if (!minTimestamp || timestamp < minTimestamp) {
58
+ minTimestamp = timestamp;
59
+ }
60
+ if (!maxTimestamp || timestamp > maxTimestamp) {
61
+ maxTimestamp = timestamp;
62
+ }
63
+ }
64
+ const payload = obj.payload;
65
+ // Extract session ID and project ref from session_meta
66
+ if (type === "session_meta" && payload) {
67
+ if (typeof payload.id === "string" && payload.id) {
68
+ sessionId = payload.id;
69
+ }
70
+ if (typeof payload.cwd === "string" && payload.cwd) {
71
+ projectRef = createHash("sha256")
72
+ .update(payload.cwd)
73
+ .digest("hex")
74
+ .slice(0, 12);
75
+ }
76
+ // Fallback model from session_meta
77
+ if (typeof payload.model === "string" && payload.model.trim()) {
78
+ lastModel = payload.model.trim();
79
+ }
80
+ continue;
81
+ }
82
+ // Track model from turn_context (overrides session_meta)
83
+ if (type === "turn_context" && payload) {
84
+ if (typeof payload.model === "string" && payload.model.trim()) {
85
+ lastModel = payload.model.trim();
86
+ }
87
+ continue;
88
+ }
89
+ // Count user/assistant messages from response_item
90
+ if (type === "response_item" && payload) {
91
+ const role = typeof payload.role === "string" ? payload.role : null;
92
+ if (role === "user") {
93
+ userMessages++;
94
+ }
95
+ else if (role === "assistant") {
96
+ assistantMessages++;
97
+ }
98
+ }
99
+ }
100
+ }
101
+ finally {
102
+ rl.close();
103
+ stream.destroy();
104
+ }
105
+ // No valid timestamps → can't produce a snapshot
106
+ if (!minTimestamp)
107
+ return [];
108
+ const startedAt = minTimestamp;
109
+ const lastMessageAt = maxTimestamp ?? minTimestamp;
110
+ const durationMs = new Date(lastMessageAt).getTime() - new Date(startedAt).getTime();
111
+ // Session key: prefer native UUID from session_meta, fallback to sha256 of path
112
+ let sessionKey;
113
+ if (sessionId) {
114
+ sessionKey = `codex:${sessionId}`;
115
+ }
116
+ else {
117
+ const hash = createHash("sha256")
118
+ .update(resolve(filePath))
119
+ .digest("hex")
120
+ .slice(0, 16);
121
+ sessionKey = `codex:${hash}`;
122
+ }
123
+ return [
124
+ {
125
+ sessionKey,
126
+ source: "codex",
127
+ kind: "human",
128
+ startedAt,
129
+ lastMessageAt,
130
+ durationSeconds: Math.max(0, Math.floor(durationMs / 1000)),
131
+ userMessages,
132
+ assistantMessages,
133
+ totalMessages,
134
+ projectRef,
135
+ model: lastModel,
136
+ snapshotAt: new Date().toISOString(),
137
+ },
138
+ ];
139
+ }
140
+ //# sourceMappingURL=codex-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-session.js","sourceRoot":"","sources":["../../src/parsers/codex-session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Codex CLI token parser.
3
+ *
4
+ * Parses Codex JSONL rollout files (~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl)
5
+ * incrementally from a byte offset.
6
+ *
7
+ * Strategy: Cumulative total_token_usage with diff (like Gemini).
8
+ * Each `event_msg` with `payload.type === "token_count"` contains running totals.
9
+ * We diff consecutive totals to produce per-turn deltas.
10
+ *
11
+ * Model is tracked from `turn_context.payload.model` or `session_meta.payload.model`.
12
+ */
13
+ import type { TokenDelta } from "@pew/core";
14
+ import type { ParsedDelta } from "./claude.js";
15
+ /** Result of parsing a single Codex JSONL rollout file */
16
+ export interface CodexFileResult {
17
+ deltas: ParsedDelta[];
18
+ endOffset: number;
19
+ /** Last seen cumulative totals (for resuming incremental parsing) */
20
+ lastTotals: TokenDelta | null;
21
+ /** Last seen model identifier */
22
+ lastModel: string | null;
23
+ }
24
+ /**
25
+ * Parse a Codex CLI JSONL rollout file incrementally from a byte offset.
26
+ *
27
+ * Extracts token deltas from `event_msg` lines with `payload.type === "token_count"`.
28
+ * Uses cumulative `total_token_usage` with diff strategy.
29
+ * Tracks model from `turn_context` and `session_meta` events.
30
+ */
31
+ export declare function parseCodexFile(opts: {
32
+ filePath: string;
33
+ startOffset: number;
34
+ lastTotals: TokenDelta | null;
35
+ lastModel: string | null;
36
+ }): Promise<CodexFileResult>;
37
+ //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/parsers/codex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAU,UAAU,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,0DAA0D;AAC1D,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,iCAAiC;IACjC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AA0CD;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GAAG,OAAO,CAAC,eAAe,CAAC,CAoF3B"}