@songsid/agend 2.2.0-beta.7 → 2.2.0-beta.8

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 (72) hide show
  1. package/dist/agent-whats-new.js +9 -3
  2. package/dist/agent-whats-new.js.map +1 -1
  3. package/dist/backend/kiro.d.ts +9 -0
  4. package/dist/backend/kiro.js +23 -0
  5. package/dist/backend/kiro.js.map +1 -1
  6. package/dist/channel/mcp-tools.js +1 -1
  7. package/dist/channel/mcp-tools.js.map +1 -1
  8. package/dist/config-validator.js +3 -0
  9. package/dist/config-validator.js.map +1 -1
  10. package/dist/daemon.d.ts +2 -0
  11. package/dist/daemon.js +2 -0
  12. package/dist/daemon.js.map +1 -1
  13. package/dist/fleet-manager.d.ts +12 -0
  14. package/dist/fleet-manager.js +45 -0
  15. package/dist/fleet-manager.js.map +1 -1
  16. package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +2 -0
  17. package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
  18. package/dist/instance-config-impact.js +1 -0
  19. package/dist/instance-config-impact.js.map +1 -1
  20. package/dist/log-service.d.ts +99 -0
  21. package/dist/log-service.js +235 -0
  22. package/dist/log-service.js.map +1 -0
  23. package/dist/log-steps.d.ts +143 -0
  24. package/dist/log-steps.js +646 -0
  25. package/dist/log-steps.js.map +1 -0
  26. package/dist/public-web-gateway.js +1 -1
  27. package/dist/public-web-gateway.js.map +1 -1
  28. package/dist/public-web-link.js +15 -3
  29. package/dist/public-web-link.js.map +1 -1
  30. package/dist/settings-api.js +4 -0
  31. package/dist/settings-api.js.map +1 -1
  32. package/dist/settings-change.js +2 -0
  33. package/dist/settings-change.js.map +1 -1
  34. package/dist/settings-effect.js +2 -0
  35. package/dist/settings-effect.js.map +1 -1
  36. package/dist/tool-progress.js +3 -2
  37. package/dist/tool-progress.js.map +1 -1
  38. package/dist/transcript-jsonl.d.ts +80 -3
  39. package/dist/transcript-jsonl.js +147 -10
  40. package/dist/transcript-jsonl.js.map +1 -1
  41. package/dist/transcript-monitor.d.ts +11 -0
  42. package/dist/transcript-monitor.js +61 -13
  43. package/dist/transcript-monitor.js.map +1 -1
  44. package/dist/transcript-sources.d.ts +24 -0
  45. package/dist/transcript-sources.js +205 -55
  46. package/dist/transcript-sources.js.map +1 -1
  47. package/dist/types.d.ts +6 -0
  48. package/dist/ui/panel-log.js +388 -0
  49. package/dist/ui/panel-settings.js +6 -1
  50. package/dist/ui/settings-strings.js +2 -0
  51. package/dist/ui/shared/app-i18n.js +2 -2
  52. package/dist/ui/shared/app-route.js +6 -1
  53. package/dist/ui/shared/app-shell.js +3 -3
  54. package/dist/ui/shared/app-stream.js +2 -1
  55. package/dist/ui/shared/app.css +40 -5
  56. package/dist/ui/shared/app.js +5 -0
  57. package/dist/ui/shared/fonts/README.md +1 -1
  58. package/dist/ui/shared/instance-nav.js +9 -6
  59. package/dist/ui/shared/instance-switch.js +4 -4
  60. package/dist/ui/shared/tokens.css +1 -1
  61. package/dist/web-api.d.ts +3 -0
  62. package/dist/web-api.js +41 -0
  63. package/dist/web-api.js.map +1 -1
  64. package/dist/web-auth.js +2 -1
  65. package/dist/web-auth.js.map +1 -1
  66. package/dist/web-settings-patch.d.ts +3 -1
  67. package/dist/web-settings-patch.js +4 -1
  68. package/dist/web-settings-patch.js.map +1 -1
  69. package/dist/web-shell-routes.d.ts +4 -0
  70. package/dist/web-shell-routes.js +9 -0
  71. package/dist/web-shell-routes.js.map +1 -1
  72. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import { EventEmitter } from "node:events";
2
2
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
3
3
  import { join } from "node:path";
4
- import { lastLineBoundary, readNewLines } from "./transcript-jsonl.js";
4
+ import { LOOKS_PER_POLL, isClaudeAssistantHead, lastLineBoundary, readNewLines, resolveLongLines } from "./transcript-jsonl.js";
5
5
  /**
6
6
  * Emits tool_use / tool_result / assistant_text events off the CLI's own
7
7
  * conversation record.
@@ -18,6 +18,10 @@ export class TranscriptMonitor extends EventEmitter {
18
18
  logger;
19
19
  source;
20
20
  byteOffset = 0;
21
+ /** #1218 P0: the offset is inside a long line being skipped (readNewLines `skipping`). */
22
+ skipping = false;
23
+ /** #1218 P0: a long assistant line being skipped, to be read whole once its end is found. */
24
+ pendingLong = null;
21
25
  transcriptPath = null;
22
26
  pollTimer = null;
23
27
  offsetFile;
@@ -40,6 +44,8 @@ export class TranscriptMonitor extends EventEmitter {
40
44
  if (existsSync(this.offsetFile)) {
41
45
  const data = JSON.parse(readFileSync(this.offsetFile, "utf-8"));
42
46
  this.byteOffset = data.offset ?? 0;
47
+ this.skipping = false;
48
+ this.pendingLong = null;
43
49
  this.transcriptPath = data.path ?? null;
44
50
  }
45
51
  }
@@ -60,6 +66,8 @@ export class TranscriptMonitor extends EventEmitter {
60
66
  // Non-critical — will re-read some entries on restart
61
67
  }
62
68
  }
69
+ /** #1218: the transcript followed now — the source's, or claude-code's own — for the Log tab's on-demand read. */
70
+ currentPath() { return this.source ? this.source.currentPath?.() ?? null : this.transcriptPath; }
63
71
  async resolveTranscriptPath() {
64
72
  const statusFile = join(this.instanceDir, "statusline.json");
65
73
  if (existsSync(statusFile)) {
@@ -158,6 +166,8 @@ export class TranscriptMonitor extends EventEmitter {
158
166
  // Work resumed during our own startup must be observable → read the
159
167
  // replacement from the top.
160
168
  this.byteOffset = 0;
169
+ this.skipping = false;
170
+ this.pendingLong = null;
161
171
  this.saveOffset();
162
172
  }
163
173
  else {
@@ -167,6 +177,8 @@ export class TranscriptMonitor extends EventEmitter {
167
177
  // replay the whole history.
168
178
  try {
169
179
  this.byteOffset = await lastLineBoundary(current);
180
+ this.skipping = false;
181
+ this.pendingLong = null;
170
182
  }
171
183
  catch {
172
184
  this.transcriptPath = null;
@@ -179,25 +191,59 @@ export class TranscriptMonitor extends EventEmitter {
179
191
  if (!this.transcriptPath || !existsSync(this.transcriptPath))
180
192
  return;
181
193
  try {
182
- const { lines, newOffset } = await readNewLines(this.transcriptPath, this.byteOffset);
183
- if (newOffset === this.byteOffset)
184
- return;
185
- this.byteOffset = newOffset;
186
- for (const line of lines) {
187
- try {
188
- const entry = JSON.parse(line);
189
- this.processEntry(entry);
190
- }
191
- catch {
192
- // Malformed complete JSONL line in transcript — skip
194
+ // #1218 P0: bounded looks (READ_MAX_BYTES each), a few per poll, each awaited; the rest waits for the next poll.
195
+ const generation = this.generation;
196
+ for (let look = 0; look < LOOKS_PER_POLL; look++) {
197
+ const read = await readNewLines(this.transcriptPath, this.byteOffset, { skipping: this.skipping });
198
+ if (generation !== this.generation)
199
+ return;
200
+ this.skipping = read.skipping;
201
+ if (read.newOffset === this.byteOffset)
202
+ break;
203
+ this.byteOffset = read.newOffset;
204
+ // An assistant line over the line limit (a long reply, a Write of a big file) is read whole (bounded):
205
+ // its text and tool calls matter. A long tool result is known by its head.
206
+ const resolved = await resolveLongLines(this.transcriptPath, read, this.pendingLong, isClaudeAssistantHead);
207
+ if (generation !== this.generation)
208
+ return;
209
+ this.pendingLong = resolved.pending;
210
+ for (const record of resolved.records) {
211
+ if ("long" in record) {
212
+ this.processLongHead(record.long.head);
213
+ continue;
214
+ }
215
+ try {
216
+ const entry = JSON.parse(record.line);
217
+ this.processEntry(entry);
218
+ }
219
+ catch {
220
+ // Malformed complete JSONL line in transcript — skip
221
+ }
193
222
  }
223
+ this.saveOffset();
224
+ if (!read.more)
225
+ break;
194
226
  }
195
- this.saveOffset();
196
227
  }
197
228
  catch (err) {
198
229
  this.logger.debug({ err }, "TranscriptMonitor poll error");
199
230
  }
200
231
  }
232
+ /**
233
+ * #1218 P0: a line too long to parse (a tool result of MBs, a Write with a huge input) — what its head still says:
234
+ * the results it carries (by tool_use_id) and the tools it calls (by name), so the bubble does not lose the step.
235
+ */
236
+ processLongHead(head) {
237
+ if (head.includes('"type":"tool_result"')) {
238
+ for (const m of head.matchAll(/"tool_use_id":"([^"]{1,200})"/g))
239
+ this.emit("tool_result", m[1], undefined);
240
+ }
241
+ for (const m of head.matchAll(/"type":"tool_use"/g)) {
242
+ const name = /"name":"([^"]{1,200})"/.exec(head.slice(m.index, m.index + 400));
243
+ if (name)
244
+ this.emit("tool_use", name[1], {});
245
+ }
246
+ }
201
247
  processEntry(entry) {
202
248
  const msg = entry.message;
203
249
  if (!msg?.role || !msg?.content)
@@ -255,6 +301,8 @@ export class TranscriptMonitor extends EventEmitter {
255
301
  resetOffset() {
256
302
  this.generation++;
257
303
  this.byteOffset = 0;
304
+ this.skipping = false;
305
+ this.pendingLong = null;
258
306
  this.transcriptPath = null;
259
307
  this.source?.reset();
260
308
  this.saveOffset();
@@ -1 +1 @@
1
- {"version":3,"file":"transcript-monitor.js","sourceRoot":"","sources":["../src/transcript-monitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAEvE;;;;;;;;;;GAUG;AACH,MAAM,OAAO,iBAAkB,SAAQ,YAAY;IASvC;IACA;IACA;IAVF,UAAU,GAAW,CAAC,CAAC;IACvB,cAAc,GAAkB,IAAI,CAAC;IACrC,SAAS,GAA0C,IAAI,CAAC;IACxD,UAAU,CAAS;IACnB,OAAO,GAAG,KAAK,CAAC,CAAC,kCAAkC;IACnD,UAAU,GAAG,CAAC,CAAC;IAEvB,YACU,WAAmB,EACnB,MAAc,EACd,SAAkC,IAAI;QAE9C,KAAK,EAAE,CAAC;QAJA,gBAAW,GAAX,WAAW,CAAQ;QACnB,WAAM,GAAN,MAAM,CAAQ;QACd,WAAM,GAAN,MAAM,CAAgC;QAG9C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;QACzD,wEAAwE;QACxE,0EAA0E;QAC1E,4DAA4D;QAC5D,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,IAAI,CAAC,UAAU,EAAE,CAAC;IACtC,CAAC;IAEO,UAAU;QAChB,IAAI,CAAC;YACH,IAAI,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;gBAChC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;gBAChE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;gBACnC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;YAC1C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,yBAAyB;QAC3B,CAAC;IACH,CAAC;IAEO,UAAU;QAChB,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC;YACH,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC;gBAC5C,MAAM,EAAE,IAAI,CAAC,UAAU;gBACvB,IAAI,EAAE,IAAI,CAAC,cAAc;aAC1B,CAAC,CAAC,CAAC;QACN,CAAC;QAAC,MAAM,CAAC;YACP,sDAAsD;QACxD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,qBAAqB;QACzB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAC7D,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;gBAC3D,IAAI,IAAI,CAAC,eAAe;oBAAE,OAAO,IAAI,CAAC,eAAe,CAAC;YACxD,CAAC;YAAC,MAAM,CAAC;gBACP,4DAA4D;YAC9D,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4EAA4E;IAC5E,KAAK,CAAC,wBAAwB;QAC5B,IAAI,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC;YAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;YACnC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YAClD,iHAAiH;YACjH,mEAAmE;YACnE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC;YAC9C,IAAI,KAAK,CAAC,MAAM,IAAI,UAAU,KAAK,IAAI,CAAC,UAAU;gBAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC9E,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAChD,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,IAAI,CAAC;YACH,2FAA2F;YAC3F,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QACzE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,yEAAyE;QACzE,yEAAyE;QACzE,oEAAoE;QACpE,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACvB,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,UAAU;QACtB,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAO,CAAC,IAAI,EAAE,CAAC;YACzC,IAAI,UAAU,KAAK,IAAI,CAAC,UAAU;gBAAE,OAAO;YAC3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAAC,IAAI,UAAU,KAAK,IAAI,CAAC,UAAU;oBAAE,OAAO;gBAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;YAAC,CAAC;YAC9H,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBAAC,IAAI,UAAU,KAAK,IAAI,CAAC,UAAU;oBAAE,OAAO;gBAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAAC,CAAC;YAC1I,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;gBAAC,IAAI,UAAU,KAAK,IAAI,CAAC,UAAU;oBAAE,OAAO;gBAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;YAAC,CAAC;YAC5H,6FAA6F;YAC7F,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,IAAI,UAAU,KAAK,IAAI,CAAC,UAAU;gBAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/F,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,6BAA6B,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,OAAO;QACnB,sEAAsE;QACtE,sEAAsE;QACtE,0EAA0E;QAC1E,2EAA2E;QAC3E,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACnD,IAAI,OAAO,IAAI,OAAO,KAAK,IAAI,CAAC,cAAc,EAAE,CAAC;YAC/C,MAAM,uBAAuB,GAAG,IAAI,CAAC,cAAc,KAAK,IAAI,CAAC;YAC7D,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;YAC9B,IAAI,uBAAuB,EAAE,CAAC;gBAC5B,oEAAoE;gBACpE,4BAA4B;gBAC5B,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;gBACpB,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,kGAAkG;gBAClG,wGAAwG;gBACxG,qGAAqG;gBACrG,4BAA4B;gBAC5B,IAAI,CAAC;oBACH,IAAI,CAAC,UAAU,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,CAAC;gBACpD,CAAC;gBAAC,MAAM,CAAC;oBACP,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;oBAC3B,OAAO;gBACT,CAAC;gBACD,IAAI,CAAC,UAAU,EAAE,CAAC;gBAClB,OAAO;YACT,CAAC;QACH,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC;YAAE,OAAO;QAErE,IAAI,CAAC;YACH,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YACtF,IAAI,SAAS,KAAK,IAAI,CAAC,UAAU;gBAAE,OAAO;YAC1C,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;YAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC/B,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;gBAC3B,CAAC;gBAAC,MAAM,CAAC;oBACP,qDAAqD;gBACvD,CAAC;YACH,CAAC;YACD,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,8BAA8B,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,KAAU;QAC7B,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC;QAC1B,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,OAAO;YAAE,OAAO;QAExC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAElG,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC9B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,IAAI,SAAS,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YACpE,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBACxC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,WAAW,IAAI,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YAC1E,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;gBACnF,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;IACH,CAAC;IAED,YAAY,CAAC,UAAU,GAAG,IAAI;QAC5B,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,UAAU,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,UAAU,KAAoB,MAAM,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC;IAExE,IAAI;QACF,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACxB,CAAC;QACD,qEAAqE;QACrE,0EAA0E;QAC1E,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;IAED;;;;OAIG;IACH,SAAS;QACP,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,KAAK,IAAI,CAAC;QACtF,OAAO,IAAI,CAAC,cAAc,KAAK,IAAI,CAAC;IACtC,CAAC;IAED,oIAAoI;IACpI,cAAc;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACtE,CAAC;IAED,iBAAiB,CAAC,IAAY;QAC5B,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YACjC,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC7B,CAAC;IAED,WAAW;QACT,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,wGAAwG;QACxG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;CACF"}
1
+ {"version":3,"file":"transcript-monitor.js","sourceRoot":"","sources":["../src/transcript-monitor.ts"],"names":[],"mappings":"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"}
@@ -44,7 +44,16 @@ export interface TranscriptSource {
44
44
  turnStateKnown?(): boolean;
45
45
  /** #1641 R3: turn records a checkpoint decided (it moved the source past them), for the monitor to hand on at once. */
46
46
  takeTurns?(): TranscriptTurnEvent[];
47
+ /** #1218: the transcript file being followed now (for the Log tab's on-demand read), or null. */
48
+ currentPath?(): string | null;
47
49
  }
50
+ /**
51
+ * #1641 R3: the complete records in [from, to) that `keep` accepts — `to` is a line boundary (a checkpoint's), so
52
+ * nothing is cut. #1218 P0: read in READ_MAX_BYTES chunks (the range a checkpoint skips can be many MB), and only kept
53
+ * lines are held. A line over LINE_MAX_BYTES is judged by its head: kept, it is read whole (≤ WHOLE_LINE_MAX_BYTES —
54
+ * a turn's record must not be lost to the limit, #1786 review); otherwise it is skipped without being decoded.
55
+ */
56
+ export declare function readLineRange(path: string, from: number, to: number, keep?: (line: string) => boolean): Promise<string[]>;
48
57
  /** #1641 R2: how far back from the baseline a rollout is scanned for the last turn boundary (a turn writes a lot). */
49
58
  export declare const ROLLOUT_TURN_SCAN_MAX_BYTES: number;
50
59
  /**
@@ -70,7 +79,13 @@ export declare class CodexRolloutSource implements TranscriptSource {
70
79
  private workingDirectory;
71
80
  private sessionsDir;
72
81
  private currentFile;
82
+ /** #1218: the rollout followed now. */
83
+ currentPath(): string | null;
73
84
  private byteOffset;
85
+ /** #1218 P0: the offset is inside a long line being skipped (readNewLines `skipping`). */
86
+ private skipping;
87
+ /** #1218 P0: a long line being skipped that is to be read whole once its end is found. */
88
+ private pendingLong;
74
89
  /** EOF snapshots taken when the monitor attaches; existing history is skipped. */
75
90
  private initialOffsets;
76
91
  /** Files whose session_meta was read and did NOT match our cwd. */
@@ -126,6 +141,8 @@ export declare class CodexRolloutSource implements TranscriptSource {
126
141
  * Baselines and checkpoints ask for a fresh listing; the 2 s poll takes the shared one.
127
142
  */
128
143
  private candidateFiles;
144
+ /** The first of `files` that is ours (in order), or undefined. Verdicts are cached, so a known file costs no read. */
145
+ private firstOwned;
129
146
  private fileBelongsToUs;
130
147
  poll(): Promise<TranscriptEvents>;
131
148
  }
@@ -161,6 +178,9 @@ export declare class MuseSessionSource implements TranscriptSource {
161
178
  private baselineComplete;
162
179
  private rejected;
163
180
  private sizes;
181
+ /** #1218 P0: per log, whether its offset is inside a long line being skipped, and a long turn record held for its end. */
182
+ private skipping;
183
+ private pendingLong;
164
184
  private listedAt;
165
185
  private baselined;
166
186
  /** intent_id → its text and time, until it materializes (bounded). */
@@ -225,6 +245,10 @@ export declare class KiroSessionSource implements TranscriptSource {
225
245
  private lane;
226
246
  private currentFile;
227
247
  private byteOffset;
248
+ /** #1218 P0: the offset is inside a long line being skipped (readNewLines `skipping`). */
249
+ private skipping;
250
+ /** #1218 P0: a long line being skipped that is to be read whole once its end is found. */
251
+ private pendingLong;
228
252
  private readonly createdAt;
229
253
  private generation;
230
254
  private cursor;
@@ -26,7 +26,7 @@ import { measureSyncWork } from "./sync-work-attribution.js";
26
26
  * - Every poll re-resolves which transcript is active. Pinning to the first
27
27
  * one found silently goes blind when the CLI starts a new session.
28
28
  */
29
- import { closeSync, existsSync, openSync, readSync, realpathSync } from "node:fs";
29
+ import { existsSync, realpathSync } from "node:fs";
30
30
  import { open as openFile, readdir, readFile, stat } from "node:fs/promises";
31
31
  import { homedir } from "node:os";
32
32
  import { join, resolve } from "node:path";
@@ -34,21 +34,63 @@ import { sharedRolloutIndex } from "./rollout-index.js";
34
34
  import Database from "better-sqlite3";
35
35
  import { sharedKiroTranscriptLane } from "./kiro-transcript-lane.js";
36
36
  export { extractKiroAssistantStrings } from "./kiro-db-reader.js";
37
- import { lastLineBoundary, readNewLines } from "./transcript-jsonl.js";
37
+ import { LINE_MAX_BYTES, LONG_HEAD_BYTES, LOOKS_PER_POLL, READ_MAX_BYTES, lastLineBoundary, readNewLines, readWholeLine, resolveLongLines } from "./transcript-jsonl.js";
38
38
  import { museSessionCwd, readFileHeadSync } from "./backend/muse.js";
39
39
  import { performance } from "node:perf_hooks";
40
- /** #1641 R3: the complete records in [from, to) — `to` is a line boundary (a checkpoint's), so nothing is cut. */
41
- async function readLineRange(path, from, to) {
40
+ /**
41
+ * #1641 R3: the complete records in [from, to) that `keep` accepts — `to` is a line boundary (a checkpoint's), so
42
+ * nothing is cut. #1218 P0: read in READ_MAX_BYTES chunks (the range a checkpoint skips can be many MB), and only kept
43
+ * lines are held. A line over LINE_MAX_BYTES is judged by its head: kept, it is read whole (≤ WHOLE_LINE_MAX_BYTES —
44
+ * a turn's record must not be lost to the limit, #1786 review); otherwise it is skipped without being decoded.
45
+ */
46
+ export async function readLineRange(path, from, to, keep = () => true) {
42
47
  const fh = await openFile(path, "r");
48
+ const out = [];
49
+ const whole = async (offset, bytes, head) => {
50
+ if (!keep(head))
51
+ return;
52
+ const line = await readWholeLine(path, offset, bytes);
53
+ if (line !== null && line.trim() && keep(line))
54
+ out.push(line);
55
+ };
43
56
  try {
44
- const buffer = Buffer.alloc(to - from);
45
- for (let filled = 0; filled < buffer.length;) {
46
- const { bytesRead } = await fh.read(buffer, filled, buffer.length - filled, from + filled);
47
- if (bytesRead <= 0)
48
- throw new Error(`readLineRange: no progress reading ${path} at ${from + filled}`);
49
- filled += bytesRead;
57
+ let pos = from;
58
+ let long = null; // a long line that started in an earlier chunk
59
+ while (pos < to) {
60
+ const buffer = Buffer.alloc(Math.min(READ_MAX_BYTES, to - pos));
61
+ for (let filled = 0; filled < buffer.length;) {
62
+ const { bytesRead } = await fh.read(buffer, filled, buffer.length - filled, pos + filled);
63
+ if (bytesRead <= 0)
64
+ throw new Error(`readLineRange: no progress reading ${path} at ${pos + filled}`);
65
+ filled += bytesRead;
66
+ }
67
+ // Up to the last line end in this chunk (the range's end is one); a chunk with none is inside one long line.
68
+ const complete = buffer.lastIndexOf(0x0a) + 1;
69
+ if (complete === 0) {
70
+ long ??= { start: pos, head: buffer.toString("utf8", 0, Math.min(LONG_HEAD_BYTES, buffer.length)) };
71
+ pos += buffer.length;
72
+ continue;
73
+ }
74
+ let start = 0;
75
+ while (start < complete) {
76
+ const end = buffer.indexOf(0x0a, start);
77
+ if (long) {
78
+ await whole(long.start, pos + end - long.start, long.head);
79
+ long = null;
80
+ }
81
+ else if (end - start > LINE_MAX_BYTES) {
82
+ await whole(pos + start, end - start, buffer.toString("utf8", start, start + LONG_HEAD_BYTES));
83
+ }
84
+ else {
85
+ const line = buffer.toString("utf8", start, end);
86
+ if (line.trim() && keep(line))
87
+ out.push(line);
88
+ }
89
+ start = end + 1;
90
+ }
91
+ pos += complete;
50
92
  }
51
- return buffer.toString("utf8").split("\n").filter(line => line.trim());
93
+ return out;
52
94
  }
53
95
  finally {
54
96
  await fh.close();
@@ -117,7 +159,13 @@ export class CodexRolloutSource {
117
159
  workingDirectory;
118
160
  sessionsDir;
119
161
  currentFile = null;
162
+ /** #1218: the rollout followed now. */
163
+ currentPath() { return this.currentFile; }
120
164
  byteOffset = 0;
165
+ /** #1218 P0: the offset is inside a long line being skipped (readNewLines `skipping`). */
166
+ skipping = false;
167
+ /** #1218 P0: a long line being skipped that is to be read whole once its end is found. */
168
+ pendingLong = null;
121
169
  /** EOF snapshots taken when the monitor attaches; existing history is skipped. */
122
170
  initialOffsets = new Map();
123
171
  /** Files whose session_meta was read and did NOT match our cwd. */
@@ -161,13 +209,15 @@ export class CodexRolloutSource {
161
209
  this.pendingTurns = [];
162
210
  this.currentFile = null;
163
211
  this.byteOffset = 0;
212
+ this.skipping = false;
213
+ this.pendingLong = null;
164
214
  this.openTurnId = "";
165
215
  this.rejected.clear();
166
216
  this.accepted.clear();
167
217
  this.snapshotExistingFiles();
168
218
  }
169
219
  async checkpoint() {
170
- const active = this.candidateFiles(true).find(file => this.fileBelongsToUs(file.path));
220
+ const active = await this.firstOwned(this.candidateFiles(true));
171
221
  if (!active)
172
222
  return null;
173
223
  try {
@@ -178,7 +228,7 @@ export class CodexRolloutSource {
178
228
  else if (offset > this.byteOffset) {
179
229
  // #1641 R3: the range this checkpoint skips is never polled — its turn boundaries (and user records) are taken
180
230
  // now, so the turn state stays the file's. Tool and text records stay skipped, as before.
181
- for (const line of await readLineRange(active.path, this.byteOffset, offset)) {
231
+ for (const line of await readLineRange(active.path, this.byteOffset, offset, (l) => l.includes('"event_msg"') || l.includes('"role":"user"'))) {
182
232
  let entry;
183
233
  try {
184
234
  entry = JSON.parse(line);
@@ -191,6 +241,8 @@ export class CodexRolloutSource {
191
241
  }
192
242
  this.currentFile = active.path;
193
243
  this.byteOffset = offset;
244
+ this.skipping = false;
245
+ this.pendingLong = null;
194
246
  return { path: active.path, offset, sessionId: active.path };
195
247
  }
196
248
  catch {
@@ -224,6 +276,8 @@ export class CodexRolloutSource {
224
276
  this.turnKnown = known;
225
277
  this.currentFile = path;
226
278
  this.byteOffset = offset;
279
+ this.skipping = false;
280
+ this.pendingLong = null;
227
281
  this.openTurnId = this.openTurn ?? ""; // a steer after the baseline belongs to the carried-in turn
228
282
  }
229
283
  /**
@@ -279,23 +333,31 @@ export class CodexRolloutSource {
279
333
  candidateFiles(fresh = false) {
280
334
  return this.index.list(fresh);
281
335
  }
282
- fileBelongsToUs(path) {
336
+ /** The first of `files` that is ours (in order), or undefined. Verdicts are cached, so a known file costs no read. */
337
+ async firstOwned(files) {
338
+ for (const file of files)
339
+ if (await this.fileBelongsToUs(file.path))
340
+ return file;
341
+ return undefined;
342
+ }
343
+ async fileBelongsToUs(path) {
283
344
  if (this.rejected.has(path))
284
345
  return false;
285
346
  if (this.accepted.has(path))
286
347
  return true;
287
348
  try {
288
349
  // session_meta is the first line. It can carry long instructions, so
289
- // give it headroom — but never read the whole rollout.
290
- const fd = openSync(path, "r");
350
+ // give it headroom — but never read the whole rollout. #1218 P0: read asynchronously, off the fleet loop's
351
+ // critical path (it was a synchronous 64 KiB read per new rollout).
352
+ const fh = await openFile(path, "r");
291
353
  let head;
292
354
  try {
293
355
  const buf = Buffer.alloc(65536);
294
- const bytes = readSync(fd, buf, 0, buf.length, 0);
295
- head = buf.toString("utf-8", 0, bytes);
356
+ const { bytesRead } = await fh.read(buf, 0, buf.length, 0);
357
+ head = buf.toString("utf-8", 0, bytesRead);
296
358
  }
297
359
  finally {
298
- closeSync(fd);
360
+ await fh.close();
299
361
  }
300
362
  const firstLine = head.split("\n")[0];
301
363
  const meta = JSON.parse(firstLine);
@@ -316,7 +378,7 @@ export class CodexRolloutSource {
316
378
  // Re-resolve every poll: a restarted codex writes a NEW rollout, and
317
379
  // staying pinned to the old one goes silently blind (#528 trap 1).
318
380
  const candidates = this.candidateFiles();
319
- const active = candidates.find(c => this.fileBelongsToUs(c.path));
381
+ const active = await this.firstOwned(candidates);
320
382
  // Cleared only by a real loss (none found, an adoption or read that failed) — never for the length of a poll's
321
383
  // await, when a capture reading following() would drop the veto mid-turn.
322
384
  if (!active) {
@@ -343,20 +405,37 @@ export class CodexRolloutSource {
343
405
  }
344
406
  await this.adopt(active.path, offset);
345
407
  }
346
- let read;
347
- try {
348
- read = await readNewLines(active.path, this.byteOffset);
349
- }
350
- catch (err) {
351
- this.lastPollFollowed = false;
352
- throw err;
408
+ // #1218 P0: bounded looks (READ_MAX_BYTES each), a few per poll, each awaited (a sampled rollout was 322 MB).
409
+ const records = [];
410
+ for (let look = 0; look < LOOKS_PER_POLL; look++) {
411
+ let read;
412
+ try {
413
+ read = await readNewLines(active.path, this.byteOffset, { skipping: this.skipping });
414
+ }
415
+ catch (err) {
416
+ this.lastPollFollowed = false;
417
+ throw err;
418
+ }
419
+ this.skipping = read.skipping;
420
+ const moved = read.newOffset !== this.byteOffset;
421
+ this.byteOffset = read.newOffset;
422
+ // #1786 review: a long turn record (task_complete with a long final reply, a pasted prompt) is read whole — a
423
+ // turn's end must never be lost to the line limit. Long outputs stay head-only.
424
+ const resolved = await resolveLongLines(active.path, read, this.pendingLong, codexWholeLine);
425
+ this.pendingLong = resolved.pending;
426
+ records.push(...resolved.records);
427
+ if (!moved || !read.more)
428
+ break;
353
429
  }
354
- const { lines, newOffset } = read;
355
- this.byteOffset = newOffset;
356
430
  this.lastPollFollowed = true;
357
431
  const events = emptyEvents();
358
432
  const turns = this.pendingTurns.splice(0);
359
- for (const line of lines) {
433
+ for (const record of records) {
434
+ if ("long" in record) {
435
+ codexLongHead(record.long.head, events);
436
+ continue;
437
+ }
438
+ const line = record.line;
360
439
  let entry;
361
440
  try {
362
441
  entry = JSON.parse(line);
@@ -405,6 +484,25 @@ export class CodexRolloutSource {
405
484
  return events;
406
485
  }
407
486
  }
487
+ /** #1786 review: the long rollout lines read whole — turn records (event_msg) and messages (a pasted prompt, a long reply). */
488
+ function codexWholeLine(head) {
489
+ return head.includes('"type":"event_msg"') || (head.includes('"type":"response_item"') && /"payload":\{"type":"message"/.test(head));
490
+ }
491
+ /**
492
+ * #1218 P0: a rollout line too long to parse (an output of MBs, a huge call input) — what its head still says, so the
493
+ * bubble keeps the step: a call by its name, or an output. Turn records and messages are read whole (codexWholeLine).
494
+ */
495
+ function codexLongHead(head, events) {
496
+ if (!head.includes('"type":"response_item"'))
497
+ return;
498
+ const type = /"payload":\{[^{}]{0,400}?"type":"(function_call|custom_tool_call|function_call_output|custom_tool_call_output)"/.exec(head)?.[1];
499
+ if (type === "function_call" || type === "custom_tool_call") {
500
+ const name = /"name":"([^"]{1,200})"/.exec(head)?.[1];
501
+ events.toolUses.push({ name: name ?? "unknown", input: undefined });
502
+ }
503
+ else if (type)
504
+ events.toolResults.push({ name: "unknown" });
505
+ }
408
506
  /* -------------------------------------------------------------------- muse */
409
507
  /**
410
508
  * #1510: muse's turn boundaries, from its session logs (`<root>/<YYYY>/<MM>/<DD>/<id>/session.jsonl`, recorded on
@@ -438,6 +536,9 @@ export class MuseSessionSource {
438
536
  baselineComplete = false;
439
537
  rejected = new Set();
440
538
  sizes = new Map();
539
+ /** #1218 P0: per log, whether its offset is inside a long line being skipped, and a long turn record held for its end. */
540
+ skipping = new Map();
541
+ pendingLong = new Map();
441
542
  listedAt = Number.NEGATIVE_INFINITY;
442
543
  baselined = false;
443
544
  /** intent_id → its text and time, until it materializes (bounded). */
@@ -454,6 +555,8 @@ export class MuseSessionSource {
454
555
  this.rejected.clear();
455
556
  this.sizes.clear();
456
557
  this.intents.clear();
558
+ this.skipping.clear();
559
+ this.pendingLong.clear();
457
560
  this.listedAt = Number.NEGATIVE_INFINITY;
458
561
  this.baselined = false;
459
562
  this.baselineComplete = false;
@@ -513,22 +616,45 @@ export class MuseSessionSource {
513
616
  continue;
514
617
  }
515
618
  }
516
- let read;
517
- try {
518
- read = await readNewLines(path, from);
519
- }
520
- catch {
521
- continue;
522
- }
523
- this.files.set(path, read.newOffset);
524
- this.sizes.set(path, size);
525
- // One record at a time: a record of an unexpected shape is skipped, never the batch it came in.
526
- for (const line of read.lines) {
619
+ // #1218 P0 (#1786 review): bounded looks, as the other sources; the size is remembered only once the log has been
620
+ // read to it, so the rest of a delta over the look budget is read next poll, not when the log grows again.
621
+ let caughtUp = false;
622
+ for (let look = 0; look < LOOKS_PER_POLL; look++) {
623
+ let read;
527
624
  try {
528
- this.parse(line, turns);
625
+ read = await readNewLines(path, from, { skipping: this.skipping.get(path) ?? false });
626
+ }
627
+ catch {
628
+ break;
529
629
  }
530
- catch { /* skipped */ }
630
+ this.skipping.set(path, read.skipping);
631
+ const moved = read.newOffset !== from;
632
+ from = read.newOffset;
633
+ this.files.set(path, from);
634
+ // A long turn record (a pasted prompt in user_intent.accepted) is read whole, bounded.
635
+ const resolved = await resolveLongLines(path, read, this.pendingLong.get(path) ?? null, (head) => head.includes('"payload_type":"runtime.'));
636
+ if (resolved.pending)
637
+ this.pendingLong.set(path, resolved.pending);
638
+ else
639
+ this.pendingLong.delete(path);
640
+ // One record at a time: a record of an unexpected shape is skipped, never the batch it came in.
641
+ for (const record of resolved.records) {
642
+ if (!("line" in record))
643
+ continue;
644
+ try {
645
+ this.parse(record.line, turns);
646
+ }
647
+ catch { /* skipped */ }
648
+ }
649
+ if (!read.more) {
650
+ caughtUp = !read.skipping;
651
+ break;
652
+ }
653
+ if (!moved)
654
+ break;
531
655
  }
656
+ if (caughtUp)
657
+ this.sizes.set(path, size);
532
658
  }
533
659
  const events = emptyEvents();
534
660
  if (turns.length)
@@ -725,6 +851,10 @@ export class KiroSessionSource {
725
851
  lane;
726
852
  currentFile = null;
727
853
  byteOffset = 0;
854
+ /** #1218 P0: the offset is inside a long line being skipped (readNewLines `skipping`). */
855
+ skipping = false;
856
+ /** #1218 P0: a long line being skipped that is to be read whole once its end is found. */
857
+ pendingLong = null;
728
858
  createdAt;
729
859
  generation = 0;
730
860
  cursor;
@@ -758,6 +888,8 @@ export class KiroSessionSource {
758
888
  this.close();
759
889
  this.currentFile = null;
760
890
  this.byteOffset = 0;
891
+ this.skipping = false;
892
+ this.pendingLong = null;
761
893
  this.cursor = undefined;
762
894
  this.needsBaseline = true;
763
895
  void this.initialize();
@@ -895,6 +1027,8 @@ export class KiroSessionSource {
895
1027
  if (active.createdAtMs >= this.createdAt) {
896
1028
  this.currentFile = active.jsonlPath;
897
1029
  this.byteOffset = 0; // our own fresh session — observable from the start
1030
+ this.skipping = false;
1031
+ this.pendingLong = null;
898
1032
  }
899
1033
  else {
900
1034
  // An older session is attached at its last line boundary. If that cannot be read now, nothing is adopted
@@ -910,23 +1044,39 @@ export class KiroSessionSource {
910
1044
  return EMPTY;
911
1045
  this.currentFile = active.jsonlPath;
912
1046
  this.byteOffset = offset;
1047
+ this.skipping = false;
1048
+ this.pendingLong = null;
913
1049
  return EMPTY;
914
1050
  }
915
1051
  }
916
- const { lines, newOffset } = await readNewLines(this.currentFile, this.byteOffset);
917
- if (generation !== this.generation)
918
- return EMPTY;
919
- this.byteOffset = newOffset;
1052
+ // #1218 P0: bounded looks, as the other JSONL sources. Kiro's nesting needs the whole record: a long line is read
1053
+ // whole up to WHOLE_LINE_MAX_BYTES (as every line was before), and skipped beyond it.
920
1054
  const events = emptyEvents();
921
- for (const line of lines) {
922
- let entry;
923
- try {
924
- entry = JSON.parse(line);
925
- }
926
- catch {
927
- continue;
1055
+ for (let look = 0; look < LOOKS_PER_POLL; look++) {
1056
+ const read = await readNewLines(this.currentFile, this.byteOffset, { skipping: this.skipping });
1057
+ if (generation !== this.generation)
1058
+ return EMPTY;
1059
+ this.skipping = read.skipping;
1060
+ const moved = read.newOffset !== this.byteOffset;
1061
+ this.byteOffset = read.newOffset;
1062
+ const resolved = await resolveLongLines(this.currentFile, read, this.pendingLong, () => true);
1063
+ if (generation !== this.generation)
1064
+ return EMPTY;
1065
+ this.pendingLong = resolved.pending;
1066
+ for (const record of resolved.records) {
1067
+ if (!("line" in record))
1068
+ continue;
1069
+ let entry;
1070
+ try {
1071
+ entry = JSON.parse(record.line);
1072
+ }
1073
+ catch {
1074
+ continue;
1075
+ }
1076
+ collectKiroEvents(entry, events);
928
1077
  }
929
- collectKiroEvents(entry, events);
1078
+ if (!moved || !read.more)
1079
+ break;
930
1080
  }
931
1081
  return events;
932
1082
  }