cli-jaw 2.17.61 → 2.17.62

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 (100) hide show
  1. package/README.ja.md +376 -339
  2. package/README.ko.md +338 -393
  3. package/README.md +163 -508
  4. package/README.zh-CN.md +365 -376
  5. package/dist/server.js +3 -0
  6. package/dist/server.js.map +1 -1
  7. package/dist/src/agent/pi-runtime.js +37 -18
  8. package/dist/src/agent/pi-runtime.js.map +1 -1
  9. package/dist/src/agent/runtime/acp/permissions.js +2 -3
  10. package/dist/src/agent/runtime/acp/permissions.js.map +1 -1
  11. package/dist/src/agent/runtime/pi-turn.js +7 -0
  12. package/dist/src/agent/runtime/pi-turn.js.map +1 -1
  13. package/dist/src/agent/spawn/line-buffer.js +84 -13
  14. package/dist/src/agent/spawn/line-buffer.js.map +1 -1
  15. package/dist/src/agent/spawn.js +26 -15
  16. package/dist/src/agent/spawn.js.map +1 -1
  17. package/dist/src/code-mode/host.js +34 -5
  18. package/dist/src/code-mode/host.js.map +1 -1
  19. package/dist/src/code-mode/manager.js +24 -7
  20. package/dist/src/code-mode/manager.js.map +1 -1
  21. package/dist/src/code-mode/providers/provider-live-models.js +3 -1
  22. package/dist/src/code-mode/providers/provider-live-models.js.map +1 -1
  23. package/dist/src/code-mode/store.js +31 -6
  24. package/dist/src/code-mode/store.js.map +1 -1
  25. package/dist/src/core/config.js +119 -17
  26. package/dist/src/core/config.js.map +1 -1
  27. package/dist/src/core/runtime-settings.js +7 -1
  28. package/dist/src/core/runtime-settings.js.map +1 -1
  29. package/dist/src/core/settings-merge.js +9 -0
  30. package/dist/src/core/settings-merge.js.map +1 -1
  31. package/dist/src/core/settings-watch.js +19 -1
  32. package/dist/src/core/settings-watch.js.map +1 -1
  33. package/dist/src/discord/bot.js +6 -4
  34. package/dist/src/discord/bot.js.map +1 -1
  35. package/dist/src/discord/send-only-client.js +37 -3
  36. package/dist/src/discord/send-only-client.js.map +1 -1
  37. package/dist/src/manager/memory/embedding/sync.js +6 -0
  38. package/dist/src/manager/memory/embedding/sync.js.map +1 -1
  39. package/dist/src/manager/routes/dashboard-memory.js +20 -7
  40. package/dist/src/manager/routes/dashboard-memory.js.map +1 -1
  41. package/dist/src/manager/server.js +8 -0
  42. package/dist/src/manager/server.js.map +1 -1
  43. package/dist/src/manager/shutdown.js +29 -3
  44. package/dist/src/manager/shutdown.js.map +1 -1
  45. package/dist/src/manager/worker-events.js +70 -8
  46. package/dist/src/manager/worker-events.js.map +1 -1
  47. package/dist/src/routes/code-native.js +23 -3
  48. package/dist/src/routes/code-native.js.map +1 -1
  49. package/dist/src/routes/events.js +4 -0
  50. package/dist/src/routes/events.js.map +1 -1
  51. package/dist/src/routes/settings.js +45 -1
  52. package/dist/src/routes/settings.js.map +1 -1
  53. package/dist/src/routes/sse-connections.js +31 -0
  54. package/dist/src/routes/sse-connections.js.map +1 -0
  55. package/dist/src/shared/permissions.js +47 -0
  56. package/dist/src/shared/permissions.js.map +1 -0
  57. package/package.json +1 -1
  58. package/public/dist/.vite/manifest.json +31 -31
  59. package/public/dist/assets/AdvancedExport-B7h_ZvBu.js +1 -0
  60. package/public/dist/assets/Agent-DnbZJP7b.js +1 -0
  61. package/public/dist/assets/{ChannelEnablementControl-B2tq8Ji4.js → ChannelEnablementControl-Dl0uYx38.js} +5 -5
  62. package/public/dist/assets/ChannelSetupEntry-DxtOrN01.js +1 -0
  63. package/public/dist/assets/ChannelsDiscord-BEGGwd_3.js +1 -0
  64. package/public/dist/assets/{ChannelsSlack-B9FV0ftr.js → ChannelsSlack-BryC2Ahr.js} +1 -1
  65. package/public/dist/assets/ChannelsTelegram-CGSpaImJ.js +1 -0
  66. package/public/dist/assets/CodeCanvas-DpkFi5Au.js +2 -0
  67. package/public/dist/assets/Permissions-BwiMEoTV.js +1 -0
  68. package/public/dist/assets/Permissions-CodIW-Yd.js +1 -0
  69. package/public/dist/assets/{manager-C5cU1joU.js → manager-Bi_xw7TW.js} +2 -2
  70. package/public/dist/assets/{settings-CA2LQDGh.js → settings-W4KG9ivu.js} +1 -1
  71. package/public/dist/assets/{settings-embedding-oGvFayh-.js → settings-embedding-BfWzWKMM.js} +1 -1
  72. package/public/dist/manager/index.html +1 -1
  73. package/public/dist/settings/index.html +1 -1
  74. package/public/js/features/settings-discord.ts +39 -5
  75. package/public/js/features/settings-telegram.ts +38 -4
  76. package/public/js/features/settings-types.ts +2 -0
  77. package/public/locales/en.json +2 -0
  78. package/public/locales/ja.json +2 -0
  79. package/public/locales/ko.json +2 -0
  80. package/public/locales/zh.json +2 -0
  81. package/public/manager/src/App.tsx +4 -1
  82. package/public/manager/src/code/code-controller-runtime.ts +13 -6
  83. package/public/manager/src/code/code-session-client.ts +1 -1
  84. package/public/manager/src/code/session-order.ts +6 -7
  85. package/public/manager/src/dashboard-url-state.ts +8 -0
  86. package/public/manager/src/settings/pages/AdvancedExport.tsx +2 -0
  87. package/public/manager/src/settings/pages/Agent.tsx +13 -5
  88. package/public/manager/src/settings/pages/ChannelsDiscord.tsx +27 -4
  89. package/public/manager/src/settings/pages/ChannelsTelegram.tsx +26 -4
  90. package/public/manager/src/settings/pages/Permissions.tsx +50 -27
  91. package/public/manager/src/settings/pages/components/ChannelSetupEntry.tsx +4 -3
  92. package/public/manager/src/settings/pages/components/agent/PermissionQuickSection.tsx +10 -2
  93. package/public/dist/assets/AdvancedExport-BNMjYkw6.js +0 -1
  94. package/public/dist/assets/Agent-D4g8TPjm.js +0 -1
  95. package/public/dist/assets/ChannelSetupEntry-zKYImWXx.js +0 -1
  96. package/public/dist/assets/ChannelsDiscord-CWRKV-Zl.js +0 -1
  97. package/public/dist/assets/ChannelsTelegram-BdK-fTPI.js +0 -1
  98. package/public/dist/assets/CodeCanvas-D5jp8-t5.js +0 -2
  99. package/public/dist/assets/Permissions-Bh947tUG.js +0 -1
  100. package/public/dist/assets/Permissions-DzNJCt8K.js +0 -1
@@ -9,21 +9,92 @@
9
9
  *
10
10
  * The cap is generous enough that a legitimately long JSON line still parses,
11
11
  * and it is only reached when no newline has been seen at all.
12
+ *
13
+ * ## Frame contract (#784)
14
+ *
15
+ * Two distinct limits share `maxChars`:
16
+ *
17
+ * - **Pending cap** — the memory bound on the in-flight partial frame. The
18
+ * framer never retains more than `maxChars` of one frame's head, and while
19
+ * draining a dropped frame it keeps only a fixed `OVERFLOW_HEAD_SAMPLE_CHARS`
20
+ * diagnostic sample plus a counter.
21
+ * - **Frame cap** — the accept/reject rule for a completed frame. A frame is
22
+ * dispatched iff its total length is ≤ `maxChars`. Because the pending cap
23
+ * trips exactly when a frame exceeds `maxChars`, the verdict is identical no
24
+ * matter how the payload is split across chunks: the same bytes always get
25
+ * the same answer.
26
+ *
27
+ * Once a frame crosses the cap it is poisoned: the framer freezes a bounded,
28
+ * surrogate-safe head sample, counts the rest, and drains everything up to the
29
+ * frame's LF. The dropped frame surfaces as a `NdjsonDrop` — the truncated head
30
+ * is never spliced with a later suffix into a parseable-but-wrong message. The
31
+ * LF that ends the poisoned frame resyncs the stream, so following frames
32
+ * dispatch normally. EOF mid-overflow reports the drop too; no truncated
33
+ * payload is emitted.
12
34
  */
13
35
  import { sliceWithoutSplittingSurrogate } from '../stream-text.js';
14
36
  export const MAX_PENDING_LINE_CHARS = 8 * 1024 * 1024;
15
- /**
16
- * Clamp a pending (newline-free) line buffer.
17
- *
18
- * Keeps the HEAD rather than the tail: for a stream that never terminates a
19
- * line, the beginning is what identifies the malformed payload, and discarding
20
- * the head would leave an unparseable fragment either way.
21
- */
22
- export function clampPendingLine(buffer, maxChars = MAX_PENDING_LINE_CHARS) {
23
- if (buffer.length <= maxChars)
24
- return { buffer, overflowed: false };
25
- // Slice on a code-point boundary: a bare slice can cut between a high and low
26
- // surrogate and emit half an emoji at the cap (#372).
27
- return { buffer: sliceWithoutSplittingSurrogate(buffer, maxChars), overflowed: true };
37
+ /** Bounded head of a dropped frame, kept so the drop can be identified. */
38
+ export const OVERFLOW_HEAD_SAMPLE_CHARS = 512;
39
+ export function createNdjsonFramer(maxChars = MAX_PENDING_LINE_CHARS) {
40
+ let pending = '';
41
+ let overflowing = false;
42
+ let frameChars = 0;
43
+ let headSample = '';
44
+ return {
45
+ push(text) {
46
+ const lines = [];
47
+ const drops = [];
48
+ let offset = 0;
49
+ while (offset <= text.length) {
50
+ const nl = text.indexOf('\n', offset);
51
+ const end = nl === -1 ? text.length : nl;
52
+ const segLen = end - offset;
53
+ if (overflowing) {
54
+ frameChars += segLen;
55
+ }
56
+ else if (pending.length + segLen > maxChars) {
57
+ // One extra code unit: slicing exactly at the bound would
58
+ // skip the surrogate check and could keep half a pair.
59
+ const headSource = pending.length > OVERFLOW_HEAD_SAMPLE_CHARS
60
+ ? pending
61
+ : pending + text.slice(offset, offset + OVERFLOW_HEAD_SAMPLE_CHARS + 1);
62
+ headSample = sliceWithoutSplittingSurrogate(headSource, OVERFLOW_HEAD_SAMPLE_CHARS);
63
+ frameChars = pending.length + segLen;
64
+ pending = '';
65
+ overflowing = true;
66
+ }
67
+ else {
68
+ pending += text.slice(offset, end);
69
+ }
70
+ if (nl === -1)
71
+ break;
72
+ if (overflowing) {
73
+ drops.push({ frameChars, headSample });
74
+ overflowing = false;
75
+ frameChars = 0;
76
+ headSample = '';
77
+ }
78
+ else {
79
+ lines.push(pending);
80
+ pending = '';
81
+ }
82
+ offset = nl + 1;
83
+ }
84
+ return { lines, drops };
85
+ },
86
+ end() {
87
+ if (overflowing) {
88
+ const drop = { frameChars, headSample };
89
+ overflowing = false;
90
+ frameChars = 0;
91
+ headSample = '';
92
+ return { tail: '', drop };
93
+ }
94
+ const tail = pending;
95
+ pending = '';
96
+ return { tail, drop: null };
97
+ },
98
+ };
28
99
  }
29
100
  //# sourceMappingURL=line-buffer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"line-buffer.js","sourceRoot":"","sources":["../../../../src/agent/spawn/line-buffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AAEnE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAStD;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC5B,MAAc,EACd,WAAmB,sBAAsB;IAEzC,IAAI,MAAM,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IACpE,8EAA8E;IAC9E,sDAAsD;IACtD,OAAO,EAAE,MAAM,EAAE,8BAA8B,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AAC1F,CAAC"}
1
+ {"version":3,"file":"line-buffer.js","sourceRoot":"","sources":["../../../../src/agent/spawn/line-buffer.ts"],"names":[],"mappings":"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"}
@@ -180,7 +180,7 @@ import { stopCauseFromKillReason } from './spawn/stop-cause.js';
180
180
  import { buildSteerStartedEvent } from './spawn/steer-event.js';
181
181
  import { armExitSettle, captureExitSettler, settleCapturedExit, settleExit, waitForExitSettled, } from './spawn/exit-settle.js';
182
182
  import { releaseChildOutputAfterExit } from './spawn/exit-drain.js';
183
- import { clampPendingLine } from './spawn/line-buffer.js';
183
+ import { createNdjsonFramer, MAX_PENDING_LINE_CHARS } from './spawn/line-buffer.js';
184
184
  import { appendBoundedFullText } from './events/fulltext-bound.js';
185
185
  /** No provider turn was dispatched; preserve the captured cancellation receipt. */
186
186
  function stoppedBeforeStart(reason, traceRunId) {
@@ -3710,7 +3710,16 @@ export function spawnAgent(prompt, opts = {}) {
3710
3710
  },
3711
3711
  });
3712
3712
  }
3713
- let buffer = '';
3713
+ const ndjsonFramer = createNdjsonFramer();
3714
+ const reportNdjsonDrop = (drop) => {
3715
+ console.warn(`[jaw:${agentLabel}] stdout frame exceeded the ${MAX_PENDING_LINE_CHARS}-char limit — dropping the frame and draining to its newline`);
3716
+ appendTraceEvent({
3717
+ runId: ctx.traceRunId,
3718
+ source: 'cli_raw',
3719
+ eventType: 'ndjson_overflow',
3720
+ raw: { droppedFrameChars: drop.frameChars, headSample: drop.headSample },
3721
+ });
3722
+ };
3714
3723
  const recordOpencodeEvent = (line, event) => {
3715
3724
  if (cli !== 'opencode')
3716
3725
  return;
@@ -3865,15 +3874,10 @@ export function spawnAgent(prompt, opts = {}) {
3865
3874
  }
3866
3875
  return;
3867
3876
  }
3868
- buffer += stdoutReader.write(chunk);
3869
- const lines = buffer.split('\n');
3870
- buffer = lines.pop() ?? '';
3871
- const clampedPending = clampPendingLine(buffer);
3872
- if (clampedPending.overflowed) {
3873
- console.warn(`[jaw:${agentLabel}] stdout line exceeded the pending-line cap without a newline — truncating`);
3874
- buffer = clampedPending.buffer;
3875
- }
3876
- for (const line of lines) {
3877
+ const framed = ndjsonFramer.push(stdoutReader.write(chunk));
3878
+ for (const drop of framed.drops)
3879
+ reportNdjsonDrop(drop);
3880
+ for (const line of framed.lines) {
3877
3881
  if (!line.trim())
3878
3882
  continue;
3879
3883
  dispatchNdjsonLine(line);
@@ -3921,7 +3925,12 @@ export function spawnAgent(prompt, opts = {}) {
3921
3925
  emitKiroStreamEvents(processKiroStdoutChunk(ctx, stdoutResidual), ctx, agentLabel, cli, empTag, traceAudience);
3922
3926
  }
3923
3927
  else {
3924
- buffer += stdoutResidual;
3928
+ const framed = ndjsonFramer.push(stdoutResidual);
3929
+ for (const drop of framed.drops)
3930
+ reportNdjsonDrop(drop);
3931
+ for (const line of framed.lines)
3932
+ if (line.trim())
3933
+ dispatchNdjsonLine(line);
3925
3934
  }
3926
3935
  }
3927
3936
  const stderrEnd = stderrReader.end();
@@ -3930,9 +3939,11 @@ export function spawnAgent(prompt, opts = {}) {
3930
3939
  ctx.stderrBuf = sliceWithoutSplittingSurrogate(ctx.stderrBuf + stderrResidual, STDERR_BUF_CAP);
3931
3940
  }
3932
3941
  // Flush residual NDJSON buffer — last event may lack a trailing newline
3933
- if (buffer.trim()) {
3934
- dispatchNdjsonLine(buffer);
3935
- buffer = '';
3942
+ const ndjsonTail = ndjsonFramer.end();
3943
+ if (ndjsonTail.drop)
3944
+ reportNdjsonDrop(ndjsonTail.drop);
3945
+ if (ndjsonTail.tail.trim()) {
3946
+ dispatchNdjsonLine(ndjsonTail.tail);
3936
3947
  }
3937
3948
  flushClaudeBuffers(ctx, agentLabel, empTag); // flush any pending thinking/input buffers
3938
3949
  if (cli === 'opencode')