@linghun/tui 0.1.1 → 0.1.3

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 (204) hide show
  1. package/dist/agent-completion-finalizer.js +3 -3
  2. package/dist/background-control-runtime.js +55 -55
  3. package/dist/cache-command-runtime.js +3 -3
  4. package/dist/capability-runtime.js +34 -34
  5. package/dist/{chunk-TJLC3QAS.js → chunk-36ZWUJQS.js} +1 -1
  6. package/dist/{chunk-DTK5NBTV.js → chunk-4BFCUJX6.js} +95 -11
  7. package/dist/{chunk-YH6UIHNF.js → chunk-4QWCNMP6.js} +2 -2
  8. package/dist/{chunk-WKMBK5UP.js → chunk-4TO2LDMP.js} +1 -1
  9. package/dist/{chunk-QG2FJ3NR.js → chunk-5OZEJQBH.js} +3 -3
  10. package/dist/{chunk-J7ZE2JKP.js → chunk-6C32YAB5.js} +19 -7
  11. package/dist/{chunk-W3KHJNSH.js → chunk-6CHUZ2NF.js} +2 -2
  12. package/dist/{chunk-I3NTAIMF.js → chunk-6DBBXNEG.js} +3 -3
  13. package/dist/{chunk-GDQQNPBP.js → chunk-6GXIGN5W.js} +1 -1
  14. package/dist/{chunk-QLRTQHTR.js → chunk-6JGRNES6.js} +2 -2
  15. package/dist/{chunk-AZU7HXIT.js → chunk-6JPUBF7B.js} +18 -18
  16. package/dist/{chunk-KO64OFSG.js → chunk-7C6T7RKJ.js} +1 -1
  17. package/dist/{chunk-LDABZV5V.js → chunk-7RZE45OT.js} +1 -1
  18. package/dist/{chunk-4E56DWEZ.js → chunk-7XAOTGHZ.js} +5 -5
  19. package/dist/{chunk-MLUIOBKL.js → chunk-7ZMDQZ22.js} +4 -4
  20. package/dist/{chunk-X7A22JHP.js → chunk-A4H3UTJZ.js} +1 -1
  21. package/dist/{chunk-D3UTL2QX.js → chunk-ATY7WBIT.js} +1 -1
  22. package/dist/{chunk-ZOSK2UEU.js → chunk-BBK5BA5C.js} +99 -117
  23. package/dist/{chunk-7TYK55JT.js → chunk-BEDD7OFL.js} +5 -5
  24. package/dist/{chunk-SRZIA6B4.js → chunk-BNC4F63N.js} +1 -1
  25. package/dist/{chunk-LIPZJNXS.js → chunk-CQCJGMXG.js} +4 -4
  26. package/dist/{chunk-L2GU3PWU.js → chunk-DEIYY6NI.js} +324 -16
  27. package/dist/{chunk-5CXN4JLE.js → chunk-EGHM55EV.js} +4 -4
  28. package/dist/{chunk-HIIYRATQ.js → chunk-ESAACKVG.js} +11 -7
  29. package/dist/{chunk-O6MKVGVK.js → chunk-G7O26P5X.js} +1 -1
  30. package/dist/{chunk-APJIC2O5.js → chunk-GTIZNO5O.js} +84 -0
  31. package/dist/{chunk-UOHZQIVL.js → chunk-GXFYUZAM.js} +1 -1
  32. package/dist/{chunk-Y5ZV47XC.js → chunk-GYHEUVR2.js} +7 -7
  33. package/dist/{chunk-QTDGRZMZ.js → chunk-HJOC5WUV.js} +1 -1
  34. package/dist/{chunk-KOULRCYJ.js → chunk-HMGYFENJ.js} +2 -2
  35. package/dist/{chunk-SYBNJZEL.js → chunk-HPMBSOQ4.js} +1 -1
  36. package/dist/{chunk-4K6UB524.js → chunk-IPZZGDUU.js} +1 -1
  37. package/dist/{chunk-JJQETFCR.js → chunk-IQS34W5A.js} +4 -4
  38. package/dist/{chunk-WOBNOBB5.js → chunk-J7AAPUTV.js} +3 -3
  39. package/dist/{chunk-6CI6TKLN.js → chunk-JAVRQ3LM.js} +1 -1
  40. package/dist/{chunk-VCSRBS47.js → chunk-JLAJZPOC.js} +1 -1
  41. package/dist/{chunk-CD54BQJ5.js → chunk-JMUAQUQQ.js} +4 -4
  42. package/dist/{chunk-NL4M3V5D.js → chunk-KKZBBCHK.js} +1 -1
  43. package/dist/{chunk-RMLTVKOY.js → chunk-L4YVE3RG.js} +2 -2
  44. package/dist/{chunk-F6TVBCZV.js → chunk-LWW2IAFC.js} +1 -1
  45. package/dist/{chunk-VAGL7CNR.js → chunk-NMOVU75L.js} +4 -4
  46. package/dist/{chunk-K56D3X7S.js → chunk-NWZ44SFI.js} +112 -5
  47. package/dist/{chunk-DYDTLRHB.js → chunk-OH35XDD4.js} +2 -2
  48. package/dist/{chunk-BOV4K7FP.js → chunk-OI5TZ37D.js} +36 -1
  49. package/dist/{chunk-LQTVYUT3.js → chunk-OJTMM5CV.js} +2 -2
  50. package/dist/{chunk-SILJJAK2.js → chunk-OMWSM2DA.js} +2 -2
  51. package/dist/{chunk-HW2TBXVK.js → chunk-OPVRII63.js} +1 -1
  52. package/dist/{chunk-XWRHWM4H.js → chunk-OV5OT66G.js} +11 -11
  53. package/dist/{chunk-F43AMWLZ.js → chunk-PDTJVJVD.js} +1 -1
  54. package/dist/{chunk-DDXS2RDZ.js → chunk-PHPEPZAA.js} +1 -1
  55. package/dist/{chunk-UDQT5CWK.js → chunk-PI6T2AGS.js} +1 -1
  56. package/dist/{chunk-3BPKJMIV.js → chunk-Q57WS7YZ.js} +4 -4
  57. package/dist/{chunk-33E6RDCY.js → chunk-QD4SCW4A.js} +229 -192
  58. package/dist/{chunk-QJTET7EZ.js → chunk-QXV2N4F2.js} +4 -4
  59. package/dist/{chunk-RFSSKGCE.js → chunk-RDTVAQBD.js} +239 -75
  60. package/dist/{chunk-SOPYWTFV.js → chunk-RRUI3VWQ.js} +1 -1
  61. package/dist/{chunk-IN42UISW.js → chunk-SRJ4XWOR.js} +10 -5
  62. package/dist/{chunk-6RJVTUWI.js → chunk-T6UOCF5D.js} +5 -1
  63. package/dist/{chunk-P277M7Z5.js → chunk-TO6IN4LA.js} +201 -5
  64. package/dist/{chunk-VTQL23UM.js → chunk-TVNWAEJR.js} +1 -1
  65. package/dist/chunk-TY4KIVA6.js +50 -0
  66. package/dist/{chunk-UT2TYK2A.js → chunk-TYTVAFGB.js} +1 -1
  67. package/dist/{chunk-OMZYPQVA.js → chunk-UGYFQF6M.js} +1 -1
  68. package/dist/{chunk-JGDIO2NF.js → chunk-UO3KYTBU.js} +1 -1
  69. package/dist/{chunk-MXPBYB54.js → chunk-UYU4QN3P.js} +2 -2
  70. package/dist/{chunk-J6CYFWSW.js → chunk-VDQTNA4W.js} +20 -1
  71. package/dist/{chunk-KI7C6ZOD.js → chunk-VIJ7GDKI.js} +1 -1
  72. package/dist/{chunk-NKFKOEYX.js → chunk-WCMHJ6SS.js} +1 -1
  73. package/dist/{chunk-EORRZP3F.js → chunk-WX2OTJXL.js} +1 -1
  74. package/dist/{chunk-CRQORMFF.js → chunk-X37FSYAX.js} +1 -1
  75. package/dist/chunk-X7HMDZZQ.js +85 -0
  76. package/dist/{chunk-624A7BBJ.js → chunk-XYY5LRSF.js} +4 -4
  77. package/dist/{chunk-CDVYF7RU.js → chunk-YBTXLLO5.js} +4 -4
  78. package/dist/{chunk-UN53MBAR.js → chunk-YGXPS5F2.js} +2 -2
  79. package/dist/chunk-YQNK7HK3.js +87 -0
  80. package/dist/{chunk-KJVHLTQR.js → chunk-Z265MCGC.js} +12 -8
  81. package/dist/{chunk-RM5QMOFY.js → chunk-ZKPQ4KLK.js} +1 -1
  82. package/dist/{chunk-4UER2AKI.js → chunk-ZPFOP557.js} +190 -0
  83. package/dist/command-panel-runtime.js +33 -33
  84. package/dist/compact-cache-command-runtime.js +55 -55
  85. package/dist/compact-preflight-runtime.js +20 -20
  86. package/dist/connector-runtime.js +35 -35
  87. package/dist/deep-compact-runtime.js +6 -6
  88. package/dist/deferred-tools-catalog.js +5 -5
  89. package/dist/details-status-runtime.js +33 -33
  90. package/dist/evidence-runtime.d.ts.map +1 -1
  91. package/dist/evidence-runtime.js +12 -11
  92. package/dist/extension-command-runtime.js +7 -7
  93. package/dist/extension-slash-runtime.js +34 -34
  94. package/dist/failure-learning-command-runtime.js +35 -35
  95. package/dist/failure-learning-presenter.js +4 -4
  96. package/dist/failure-learning-runtime.js +3 -3
  97. package/dist/final-answer-gate.d.ts +1 -0
  98. package/dist/final-answer-gate.d.ts.map +1 -1
  99. package/dist/final-answer-gate.js +4 -2
  100. package/dist/git-command-runtime.js +34 -34
  101. package/dist/handoff-session-runtime.js +8 -8
  102. package/dist/headless-bench-runtime.d.ts +19 -1
  103. package/dist/headless-bench-runtime.d.ts.map +1 -1
  104. package/dist/headless-bench-runtime.js +3 -1
  105. package/dist/index-result-presenter.js +5 -5
  106. package/dist/index-runtime.js +5 -5
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +143 -69
  109. package/dist/job-agent-command-runtime.js +33 -33
  110. package/dist/job-runner-presenter.js +3 -3
  111. package/dist/job-runtime.js +9 -9
  112. package/dist/mcp-index-command-runtime.js +5 -5
  113. package/dist/mcp-index-runtime.js +38 -38
  114. package/dist/mcp-sse-runtime.js +3 -3
  115. package/dist/mcp-stdio-runtime.js +4 -4
  116. package/dist/memory-command-runtime.js +35 -35
  117. package/dist/memory-extraction-runtime.js +3 -3
  118. package/dist/memory-rules-runtime.js +3 -3
  119. package/dist/meta-scheduler-runtime.js +2 -2
  120. package/dist/model-command-runtime.js +34 -34
  121. package/dist/model-loop-runtime.d.ts +1 -1
  122. package/dist/model-loop-runtime.d.ts.map +1 -1
  123. package/dist/model-loop-runtime.js +1 -1
  124. package/dist/model-prompt-runtime.js +10 -10
  125. package/dist/model-stream-runtime.d.ts.map +1 -1
  126. package/dist/model-stream-runtime.js +55 -55
  127. package/dist/model-tool-runtime.d.ts +1 -0
  128. package/dist/model-tool-runtime.d.ts.map +1 -1
  129. package/dist/model-tool-runtime.js +57 -55
  130. package/dist/pending-details-presenter.js +3 -3
  131. package/dist/permission-approval-runtime.js +55 -55
  132. package/dist/permission-continuation-runtime.d.ts.map +1 -1
  133. package/dist/permission-continuation-runtime.js +4 -4
  134. package/dist/process-command-runtime.js +4 -4
  135. package/dist/process-guard.d.ts +3 -0
  136. package/dist/process-guard.d.ts.map +1 -1
  137. package/dist/process-guard.js +5 -1
  138. package/dist/provider-loop-runtime.js +3 -3
  139. package/dist/remote-command-runtime.js +34 -34
  140. package/dist/runner-runtime.js +8 -8
  141. package/dist/runtime-status-presenter.js +3 -3
  142. package/dist/runtime-status-snapshot.js +4 -4
  143. package/dist/shell/components/AgentProgressTree.js +2 -2
  144. package/dist/shell/components/BackgroundTaskOverlay.js +2 -2
  145. package/dist/shell/components/BtwPanel.js +2 -2
  146. package/dist/shell/components/CommandPanel.js +2 -2
  147. package/dist/shell/components/Composer.d.ts +16 -2
  148. package/dist/shell/components/Composer.d.ts.map +1 -1
  149. package/dist/shell/components/Composer.js +9 -7
  150. package/dist/shell/components/ConfigPanel.js +2 -2
  151. package/dist/shell/components/HelpPanel.js +2 -2
  152. package/dist/shell/components/HistorySearchPanel.js +2 -2
  153. package/dist/shell/components/MessageMarkdown.d.ts +23 -0
  154. package/dist/shell/components/MessageMarkdown.d.ts.map +1 -1
  155. package/dist/shell/components/MessageMarkdown.js +5 -3
  156. package/dist/shell/components/MouseInputRouter.js +5 -80
  157. package/dist/shell/components/OutputLine.d.ts.map +1 -1
  158. package/dist/shell/components/OutputLine.js +5 -3
  159. package/dist/shell/components/ProductBlock.d.ts.map +1 -1
  160. package/dist/shell/components/ProductBlock.js +4 -4
  161. package/dist/shell/components/ScrollViewport.js +3 -82
  162. package/dist/shell/components/SessionsPanel.js +2 -2
  163. package/dist/shell/components/ShellApp.d.ts.map +1 -1
  164. package/dist/shell/components/ShellApp.js +28 -23
  165. package/dist/shell/components/SlashSuggestions.js +2 -2
  166. package/dist/shell/components/StatusFooter.js +2 -2
  167. package/dist/shell/components/StatusTray.d.ts.map +1 -1
  168. package/dist/shell/components/StatusTray.js +2 -1
  169. package/dist/shell/components/StructuredDiff.js +2 -2
  170. package/dist/shell/components/TaskListView.js +2 -2
  171. package/dist/shell/components/TaskSuggestionBar.js +2 -2
  172. package/dist/shell/components/WorkflowProgressView.js +2 -2
  173. package/dist/shell/components/useAnchoredCursor.d.ts +6 -9
  174. package/dist/shell/components/useAnchoredCursor.d.ts.map +1 -1
  175. package/dist/shell/components/useAnchoredCursor.js +1 -1
  176. package/dist/shell/ink-renderer.d.ts.map +1 -1
  177. package/dist/shell/ink-renderer.js +28 -23
  178. package/dist/shell/models/transcript-selection-state.js +2 -2
  179. package/dist/shell/plain-renderer.d.ts.map +1 -1
  180. package/dist/shell/plain-renderer.js +2 -2
  181. package/dist/shell/text-utils.d.ts +16 -0
  182. package/dist/shell/text-utils.d.ts.map +1 -1
  183. package/dist/shell/text-utils.js +3 -1
  184. package/dist/shell/view-model.js +14 -14
  185. package/dist/slash-command-runtime.js +55 -55
  186. package/dist/slash-dispatch.js +4 -4
  187. package/dist/startup-runtime.js +2 -2
  188. package/dist/tool-output-presenter.d.ts +1 -0
  189. package/dist/tool-output-presenter.d.ts.map +1 -1
  190. package/dist/tool-output-presenter.js +3 -1
  191. package/dist/tui-agent-job-runtime.js +11 -11
  192. package/dist/tui-context-runtime.d.ts +2 -0
  193. package/dist/tui-context-runtime.d.ts.map +1 -1
  194. package/dist/tui-data-types.d.ts +1 -0
  195. package/dist/tui-data-types.d.ts.map +1 -1
  196. package/dist/tui-details-runtime.js +10 -10
  197. package/dist/tui-memory-runtime.js +5 -5
  198. package/dist/tui-output-surface.js +15 -15
  199. package/dist/tui-permission-runtime.js +5 -5
  200. package/dist/tui-state-runtime.js +4 -4
  201. package/dist/verification-command-runtime.js +12 -12
  202. package/dist/workflow-command-runtime.js +33 -33
  203. package/package.json +5 -5
  204. package/dist/chunk-GW5YDCRZ.js +0 -42
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  ensureSession,
3
3
  showCommandPanel
4
- } from "./chunk-AZU7HXIT.js";
4
+ } from "./chunk-6JPUBF7B.js";
5
5
  import {
6
6
  decidePermission
7
- } from "./chunk-DDXS2RDZ.js";
7
+ } from "./chunk-PHPEPZAA.js";
8
8
  import {
9
9
  appendSystemEvent,
10
10
  budgetToolResultTranscriptContent,
11
11
  createEvidenceRecord,
12
12
  rememberEvidence
13
- } from "./chunk-L2GU3PWU.js";
13
+ } from "./chunk-DEIYY6NI.js";
14
14
  import {
15
15
  sanitizeDiagnosticText,
16
16
  truncateDisplay,
17
17
  writeLine
18
- } from "./chunk-OMZYPQVA.js";
18
+ } from "./chunk-UGYFQF6M.js";
19
19
 
20
20
  // src/capability-runtime.ts
21
21
  import { randomUUID } from "crypto";
@@ -6,26 +6,29 @@ import {
6
6
  formatToolResultBudgetEvidenceSummary,
7
7
  formatToolResultBudgetSystemEvent
8
8
  } from "./chunk-O7S3HYE6.js";
9
+ import {
10
+ formatToolDiagnosticsSummary
11
+ } from "./chunk-OI5TZ37D.js";
9
12
  import {
10
13
  LINGHUN_DEFAULT_TOOL_RESULT_CHARS,
11
14
  LINGHUN_MAX_TOOL_RESULT_BYTES
12
15
  } from "./chunk-IWUIOLMF.js";
13
16
  import {
14
17
  writeHandoffPacket
15
- } from "./chunk-MLUIOBKL.js";
18
+ } from "./chunk-7ZMDQZ22.js";
16
19
  import {
17
20
  deriveToolSupportsClaims
18
- } from "./chunk-K56D3X7S.js";
21
+ } from "./chunk-NWZ44SFI.js";
19
22
  import {
20
23
  mergeFailureRecord,
21
24
  writeFailureRecord
22
- } from "./chunk-GDQQNPBP.js";
25
+ } from "./chunk-6GXIGN5W.js";
23
26
  import {
24
27
  classifyProviderFailure
25
28
  } from "./chunk-OZMX3E35.js";
26
29
  import {
27
30
  truncateDisplay
28
- } from "./chunk-OMZYPQVA.js";
31
+ } from "./chunk-UGYFQF6M.js";
29
32
  import {
30
33
  summarizeArchitectureCard
31
34
  } from "./chunk-MVONSJEN.js";
@@ -37,6 +40,7 @@ var TRANSCRIPT_TOOL_OUTPUT_MAX_CHARS = 8e3;
37
40
  var MAX_ROUND_ASSISTANT_CHARS_FOR_PROVIDER = 16e3;
38
41
  var ROUND_ASSISTANT_HEAD_CHARS = 4e3;
39
42
  var ROUND_ASSISTANT_TAIL_CHARS = 4e3;
43
+ var RECENT_DIAGNOSTICS_LIMIT = 20;
40
44
  function createEvidenceRecord(kind, summary, source, supportsClaims) {
41
45
  return {
42
46
  id: randomUUID(),
@@ -215,20 +219,25 @@ async function recordArchitectureRuntimeCard(context, sessionId, card) {
215
219
  return evidence;
216
220
  }
217
221
  async function recordToolEvidence(context, sessionId, name, output, input) {
218
- const kind = name === "Read" ? "file_read" : name === "Grep" || name === "Glob" ? "grep_result" : name === "Bash" || name === "Write" || name === "Edit" || name === "MultiEdit" ? "command_output" : null;
222
+ const kind = name === "Read" || name === "ReadSnippets" || name === "SourcePack" ? "file_read" : name === "Grep" || name === "Glob" ? "grep_result" : name === "Bash" || name === "Write" || name === "Edit" || name === "MultiEdit" ? "command_output" : null;
219
223
  if (!kind) {
220
224
  return null;
221
225
  }
222
- const readOnlyEvidence = name === "Read" || name === "Grep" || name === "Glob";
226
+ const readOnlyEvidence = name === "Read" || name === "ReadSnippets" || name === "SourcePack" || name === "Grep" || name === "Glob";
227
+ const supportsClaims = [
228
+ ...deriveToolSupportsClaims(name, input, output),
229
+ ...readOnlyEvidence ? ["readonly_low_noise_evidence"] : []
230
+ ];
223
231
  const evidence = createEvidenceRecord(
224
232
  kind,
225
233
  readOnlyEvidence ? formatReadOnlyToolEvidenceSummary(name, output, input) : `${name}: ${truncateDisplay(output.text.replace(/\s+/g, " "), 120)}`,
226
234
  output.fullOutputPath ?? name,
227
- [
228
- ...deriveToolSupportsClaims(name, input, output),
229
- ...readOnlyEvidence ? ["readonly_low_noise_evidence"] : []
230
- ]
235
+ supportsClaims
231
236
  );
237
+ const semanticProbe = supportsClaims.includes("bash_exit_0") ? compactSemanticProbeEvidence(context, output, input) : void 0;
238
+ if (semanticProbe) {
239
+ evidence.data = { ...typeof evidence.data === "object" && evidence.data ? evidence.data : {}, semanticProbe };
240
+ }
232
241
  rememberEvidence(context, evidence);
233
242
  await context.store.appendEvent(sessionId, {
234
243
  type: "evidence_record",
@@ -237,11 +246,44 @@ async function recordToolEvidence(context, sessionId, name, output, input) {
237
246
  return evidence;
238
247
  }
239
248
  function formatReadOnlyToolEvidenceSummary(name, output, input) {
240
- const target = readToolEvidenceTarget(input);
249
+ const target = name === "SourcePack" ? sourcePackEvidenceTarget(input, output) : name === "ReadSnippets" ? readSnippetsEvidenceTarget(input) : readToolEvidenceTarget(input);
241
250
  const artifact = output.fullOutputPath ? "artifact=yes" : "artifact=no";
242
251
  const bytes = output.text.length;
243
252
  return `${name}: ${target}; output_chars=${bytes}; ${artifact}`;
244
253
  }
254
+ function sourcePackEvidenceTarget(input, output) {
255
+ const query = readStringField(input, "query");
256
+ const paths = extractOutputCandidatePaths(output.data);
257
+ const pathText = paths.length > 0 ? `; paths=${truncateDisplay(paths.slice(0, 4).join(","), 120)}` : "";
258
+ return `query=${truncateDisplay((query ?? "unspecified").replace(/\s+/g, " "), 90)}${pathText}`;
259
+ }
260
+ function readSnippetsEvidenceTarget(input) {
261
+ if (!input || typeof input !== "object" || Array.isArray(input)) return "ranges=unspecified";
262
+ const ranges = input.ranges;
263
+ if (!Array.isArray(ranges)) return "ranges=unspecified";
264
+ const paths = ranges.map(
265
+ (item) => item && typeof item === "object" && typeof item.path === "string" ? item.path : void 0
266
+ ).filter((item) => Boolean(item));
267
+ return paths.length > 0 ? `ranges=${truncateDisplay(paths.slice(0, 4).join(","), 120)}` : "ranges=unspecified";
268
+ }
269
+ function readStringField(input, key) {
270
+ if (!input || typeof input !== "object" || Array.isArray(input)) return void 0;
271
+ const value = input[key];
272
+ return typeof value === "string" && value.trim() ? value : void 0;
273
+ }
274
+ function extractOutputCandidatePaths(data) {
275
+ if (!data || typeof data !== "object" || Array.isArray(data)) return [];
276
+ const record = data;
277
+ const candidatePaths = record.candidatePaths;
278
+ if (Array.isArray(candidatePaths)) {
279
+ return candidatePaths.filter((item) => typeof item === "string");
280
+ }
281
+ const snippets = record.snippets;
282
+ if (!Array.isArray(snippets)) return [];
283
+ return snippets.map(
284
+ (item) => item && typeof item === "object" && typeof item.path === "string" ? item.path : void 0
285
+ ).filter((item) => Boolean(item));
286
+ }
245
287
  function readToolEvidenceTarget(input) {
246
288
  if (!input || typeof input !== "object" || Array.isArray(input)) return "target=unspecified";
247
289
  const record = input;
@@ -258,6 +300,15 @@ function readToolEvidenceTarget(input) {
258
300
  return `paths=${truncateDisplay(values.slice(0, 3).join(","), 90)}`;
259
301
  }
260
302
  }
303
+ const ranges = record.ranges;
304
+ if (Array.isArray(ranges)) {
305
+ const values = ranges.map(
306
+ (item) => item && typeof item === "object" && typeof item.path === "string" ? item.path : void 0
307
+ ).filter((item) => Boolean(item));
308
+ if (values.length > 0) {
309
+ return `ranges=${truncateDisplay(values.slice(0, 3).join(","), 90)}`;
310
+ }
311
+ }
261
312
  return "target=unspecified";
262
313
  }
263
314
  async function recordVerificationEvidence(context, sessionId, report) {
@@ -378,8 +429,12 @@ function createToolEndEvent(id, output) {
378
429
  };
379
430
  }
380
431
  function summarizeToolEndOutputForTranscript(output) {
432
+ const diagnostics = formatToolDiagnosticsSummary(output);
381
433
  const text = compactToolEndTextForTranscript(
382
- output.summary || output.preview || output.text || "tool call completed",
434
+ appendCompactDiagnostics(
435
+ output.summary || output.preview || output.text || "tool call completed",
436
+ diagnostics
437
+ ),
383
438
  output.fullOutputPath
384
439
  );
385
440
  return {
@@ -389,9 +444,15 @@ function summarizeToolEndOutputForTranscript(output) {
389
444
  truncated: output.truncated,
390
445
  fullOutputPath: output.fullOutputPath,
391
446
  evidenceId: output.evidenceId,
392
- changedFiles: output.changedFiles
447
+ changedFiles: output.changedFiles,
448
+ data: compactToolStructuredDataForTranscript(output.data)
393
449
  };
394
450
  }
451
+ function appendCompactDiagnostics(text, diagnostics) {
452
+ if (!diagnostics || text.includes("Linghun diagnostics:")) return text;
453
+ return `${diagnostics}
454
+ ${text}`;
455
+ }
395
456
  function compactToolEndTextForTranscript(text, fullOutputPath) {
396
457
  const bytes = Buffer.byteLength(text, "utf8");
397
458
  if (text.length <= TRANSCRIPT_TOOL_OUTPUT_MAX_CHARS && bytes <= TRANSCRIPT_TOOL_OUTPUT_MAX_CHARS) {
@@ -432,12 +493,69 @@ function compactToolOutputDataForTranscript(data) {
432
493
  return {
433
494
  truncated: true,
434
495
  originalChars: serialized.length,
435
- preview: serialized.slice(0, TRANSCRIPT_TOOL_OUTPUT_PREVIEW_CHARS)
496
+ preview: serialized.slice(0, TRANSCRIPT_TOOL_OUTPUT_PREVIEW_CHARS),
497
+ ...compactToolStructuredDataForTranscript(data)
498
+ };
499
+ }
500
+ function compactToolStructuredDataForTranscript(data) {
501
+ const compact = {};
502
+ const diagnostics = compactDiagnosticsDataForTranscript(data);
503
+ const validationEvidence = compactValidationEvidenceDataForTranscript(data);
504
+ if (diagnostics) Object.assign(compact, diagnostics);
505
+ if (validationEvidence) Object.assign(compact, validationEvidence);
506
+ return Object.keys(compact).length > 0 ? compact : void 0;
507
+ }
508
+ function compactDiagnosticsDataForTranscript(data) {
509
+ const diagnostics = readDiagnosticsForTranscript(data);
510
+ if (!diagnostics) return void 0;
511
+ return { diagnostics };
512
+ }
513
+ function compactValidationEvidenceDataForTranscript(data) {
514
+ const validationEvidence = readValidationEvidenceForTranscript(data);
515
+ if (!validationEvidence) return void 0;
516
+ return { validationEvidence };
517
+ }
518
+ function readDiagnosticsForTranscript(data) {
519
+ if (!data || typeof data !== "object") return void 0;
520
+ const diagnostics = data.diagnostics;
521
+ if (!Array.isArray(diagnostics) || diagnostics.length === 0) return void 0;
522
+ return diagnostics.slice(0, 5).map(compactDiagnosticForTranscript).filter((diagnostic) => Boolean(diagnostic));
523
+ }
524
+ function compactDiagnosticForTranscript(value) {
525
+ if (!value || typeof value !== "object") return void 0;
526
+ const record = value;
527
+ const type = typeof record.type === "string" ? record.type : void 0;
528
+ const severity = typeof record.severity === "string" ? record.severity : void 0;
529
+ const evidence = typeof record.evidence === "string" ? truncateDisplay(record.evidence.replace(/\s+/g, " "), 160) : void 0;
530
+ if (!type || !evidence) return void 0;
531
+ return {
532
+ type,
533
+ severity,
534
+ evidence,
535
+ ...readCompactDiagnosticTargetFields(record)
536
+ };
537
+ }
538
+ function readCompactDiagnosticTargetFields(record) {
539
+ const target = typeof record.target === "string" ? record.target : void 0;
540
+ const path = typeof record.path === "string" ? record.path : void 0;
541
+ const command = typeof record.command === "string" ? record.command : void 0;
542
+ const fallback = typeof record.fallback === "string" ? record.fallback : void 0;
543
+ const targetHost = typeof record.targetHost === "string" ? record.targetHost : void 0;
544
+ const targetPort = typeof record.targetPort === "number" ? record.targetPort : void 0;
545
+ return {
546
+ ...command ? { command } : {},
547
+ ...fallback ? { fallback } : {},
548
+ ...target ? { target } : {},
549
+ ...path ? { path } : {},
550
+ ...targetHost ? { targetHost } : {},
551
+ ...targetPort !== void 0 ? { targetPort } : {}
436
552
  };
437
553
  }
438
554
  function isToolOutputFailure(name, output) {
439
555
  if (name === "Bash") {
440
- const exitCode = output.data?.exitCode;
556
+ const data = output.data;
557
+ if (data?.isError === false) return false;
558
+ const exitCode = data?.exitCode;
441
559
  return typeof exitCode === "number" && exitCode !== 0;
442
560
  }
443
561
  return false;
@@ -483,11 +601,14 @@ async function appendDeferredToolResultEvent(context, sessionId, toolUseId, disp
483
601
  });
484
602
  }
485
603
  async function appendToolResultEvent(context, sessionId, toolUseId, toolName, content, isError, evidenceId) {
604
+ rememberRecentDiagnostics(context, toolName, content, toolUseId, evidenceId);
605
+ rememberToolEvidenceData(context, evidenceId, content);
606
+ const contentWithDiagnostics = appendToolResultContentDiagnostics(content);
486
607
  const budgetedContent = await budgetToolResultTranscriptContent(
487
608
  context,
488
609
  sessionId,
489
610
  toolUseId,
490
- content
611
+ contentWithDiagnostics
491
612
  );
492
613
  await context.store.appendEvent(sessionId, {
493
614
  type: "tool_result",
@@ -499,6 +620,193 @@ async function appendToolResultEvent(context, sessionId, toolUseId, toolName, co
499
620
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
500
621
  });
501
622
  }
623
+ function rememberToolEvidenceData(context, evidenceId, content) {
624
+ if (!evidenceId || !content || typeof content !== "object") return;
625
+ if (!Array.isArray(context.evidence)) return;
626
+ const output = content;
627
+ const compact = compactToolEvidenceData(output.data);
628
+ if (!compact) return;
629
+ const evidence = context.evidence.find((item) => item.id === evidenceId);
630
+ if (evidence) {
631
+ evidence.data = { ...typeof evidence.data === "object" && evidence.data ? evidence.data : {}, ...compact };
632
+ }
633
+ }
634
+ function compactToolEvidenceData(data) {
635
+ if (!data || typeof data !== "object") return void 0;
636
+ const record = data;
637
+ const compact = {};
638
+ for (const key of ["service", "serviceHint", "artifactHint", "binaryHint", "binaryPreflight"]) {
639
+ if (record[key] !== void 0) compact[key] = record[key];
640
+ }
641
+ const validationEvidence = readValidationEvidenceForTranscript(data);
642
+ if (validationEvidence) compact.validationEvidence = validationEvidence;
643
+ return Object.keys(compact).length > 0 ? compact : void 0;
644
+ }
645
+ function compactSemanticProbeEvidence(context, output, input) {
646
+ const tokens = collectSemanticContractTokens(context);
647
+ if (tokens.length === 0) return void 0;
648
+ if (!looksLikeServiceProbeCommand(input)) return void 0;
649
+ const haystack = [output.text, output.summary, output.preview].filter((item) => typeof item === "string" && item.length > 0).join("\n").toLowerCase();
650
+ if (!haystack) return void 0;
651
+ const matched = tokens.filter((token) => haystack.includes(token.toLowerCase()));
652
+ const required = Math.min(2, tokens.length);
653
+ if (matched.length < required) return void 0;
654
+ return { tokens: matched.slice(0, 12) };
655
+ }
656
+ function looksLikeServiceProbeCommand(input) {
657
+ if (!input || typeof input !== "object" || Array.isArray(input)) return false;
658
+ const command = input.command;
659
+ if (typeof command !== "string") return false;
660
+ return /\b(?:curl|wget|http|httpie|python|python3|node|deno|ruby|perl|php)\b|(?:requests|fetch|urllib|http\.client|axios|localhost|127\.0\.0\.1)/iu.test(
661
+ command
662
+ );
663
+ }
664
+ function collectSemanticContractTokens(context) {
665
+ const tools = context.tools;
666
+ if (tools.headlessBench?.enabled !== true) return [];
667
+ const tokens = /* @__PURE__ */ new Set();
668
+ for (const item of tools.validationContract?.items ?? []) {
669
+ if (item.kind !== "service" || item.validation !== "semantic" || !Array.isArray(item.semanticTokens)) {
670
+ continue;
671
+ }
672
+ for (const token of item.semanticTokens) {
673
+ if (typeof token === "string" && token.trim()) {
674
+ tokens.add(token.trim());
675
+ }
676
+ }
677
+ }
678
+ return [...tokens];
679
+ }
680
+ function rememberRecentDiagnostics(context, source, content, toolUseId, evidenceId) {
681
+ const diagnostics = readDiagnosticsForTranscript(content?.data);
682
+ if (!diagnostics || diagnostics.length === 0) return;
683
+ const createdAt = (/* @__PURE__ */ new Date()).toISOString();
684
+ const entries = diagnostics.map((diagnostic) => ({
685
+ source,
686
+ ...diagnostic,
687
+ createdAt,
688
+ toolUseId,
689
+ evidenceId
690
+ }));
691
+ context.tools.recentDiagnostics = [
692
+ ...entries,
693
+ ...context.tools.recentDiagnostics ?? []
694
+ ].slice(0, RECENT_DIAGNOSTICS_LIMIT);
695
+ }
696
+ function appendToolResultContentDiagnostics(content) {
697
+ if (!content || typeof content !== "object") return content;
698
+ const output = content;
699
+ if (typeof output.text !== "string") return content;
700
+ const diagnostics = formatToolDiagnosticsSummary(output);
701
+ const compactData = compactToolStructuredDataForTranscript(output.data);
702
+ if (!diagnostics && !compactData) return content;
703
+ return {
704
+ ...output,
705
+ data: compactData,
706
+ text: diagnostics ? appendCompactDiagnostics(output.text, diagnostics) : output.text
707
+ };
708
+ }
709
+ function readValidationEvidenceForTranscript(data) {
710
+ if (!data || typeof data !== "object") return void 0;
711
+ const record = data;
712
+ const entries = [
713
+ readArtifactValidationEvidence(record),
714
+ readPreservationValidationEvidence(record),
715
+ readServiceValidationEvidence(record),
716
+ readBinaryValidationEvidence(record)
717
+ ].filter((item) => Boolean(item));
718
+ return entries.length > 0 ? entries : void 0;
719
+ }
720
+ function readArtifactValidationEvidence(record) {
721
+ const artifact = readRecord(record.artifact);
722
+ if (!artifact) return void 0;
723
+ const path = readString(artifact.path);
724
+ if (!path) return void 0;
725
+ return {
726
+ kind: "artifact",
727
+ path,
728
+ tool: "Bash.artifact",
729
+ ok: record.exitCode === 0 && artifact.exists === true && checksOk(readRecord(artifact.checks)),
730
+ ...artifact.checks && typeof artifact.checks === "object" ? { checks: compactArtifactChecks(artifact.checks) } : {}
731
+ };
732
+ }
733
+ function readPreservationValidationEvidence(record) {
734
+ const artifact = readRecord(record.artifact);
735
+ const checks = readRecord(artifact?.checks);
736
+ const preserve = readRecord(checks?.preserve);
737
+ const path = readString(artifact?.path);
738
+ if (!artifact || !checks || !preserve || !path) return void 0;
739
+ return {
740
+ kind: "preservation",
741
+ path,
742
+ tool: "Bash.artifact",
743
+ ok: record.exitCode === 0 && preserve.ok === true,
744
+ checks: { preserve: compactCheckRecord(preserve) }
745
+ };
746
+ }
747
+ function readServiceValidationEvidence(record) {
748
+ const service = readRecord(record.service);
749
+ if (!service) return void 0;
750
+ const target = readString(service.target) ?? readServiceTargetFromHostPort(service);
751
+ if (!target) return void 0;
752
+ const readiness = readRecord(service.readiness);
753
+ const fetch = readRecord(service.fetch);
754
+ return {
755
+ kind: "service",
756
+ target,
757
+ tool: "Bash.service",
758
+ ok: record.exitCode === 0 && (service.ready === true || readiness?.ok === true),
759
+ ...readiness || fetch ? { checks: { ...readiness ? { readiness: compactCheckRecord(readiness) } : {}, ...fetch ? { fetch: compactCheckRecord(fetch) } : {} } } : {}
760
+ };
761
+ }
762
+ function readBinaryValidationEvidence(record) {
763
+ const binary = readRecord(record.binary);
764
+ if (!binary) return void 0;
765
+ const path = readString(binary.path);
766
+ if (!path) return void 0;
767
+ return {
768
+ kind: "binary",
769
+ path,
770
+ tool: "Bash.binary",
771
+ ok: record.exitCode === 0,
772
+ checks: compactCheckRecord(binary)
773
+ };
774
+ }
775
+ function readRecord(value) {
776
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
777
+ }
778
+ function readString(value) {
779
+ return typeof value === "string" && value.trim() ? value : void 0;
780
+ }
781
+ function readServiceTargetFromHostPort(service) {
782
+ const host = readString(service.targetHost);
783
+ const port = typeof service.targetPort === "number" ? service.targetPort : void 0;
784
+ return host && port !== void 0 ? `${host}:${port}` : void 0;
785
+ }
786
+ function checksOk(checks) {
787
+ if (!checks) return true;
788
+ return Object.values(checks).every((value) => {
789
+ const check = readRecord(value);
790
+ return !check || check.ok !== false;
791
+ });
792
+ }
793
+ function compactArtifactChecks(value) {
794
+ const checks = readRecord(value);
795
+ if (!checks) return {};
796
+ const compact = {};
797
+ for (const key of ["header", "json", "executable", "text", "preserve"]) {
798
+ const check = readRecord(checks[key]);
799
+ if (check) compact[key] = compactCheckRecord(check);
800
+ }
801
+ return compact;
802
+ }
803
+ function compactCheckRecord(record) {
804
+ const compact = {};
805
+ for (const key of ["ok", "mode", "status", "expectedStatus", "missingBody", "contains", "lineSet", "exact", "magic", "size"]) {
806
+ if (record[key] !== void 0) compact[key] = record[key];
807
+ }
808
+ return compact;
809
+ }
502
810
  async function budgetToolResultTranscriptContent(context, sessionId, toolUseId, content) {
503
811
  const contentText = stringifyToolResultContentForBudget(content);
504
812
  if (!contentText || contentText.startsWith("<persisted-tool-result>")) return content;
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  createCompactBoundaryBlock
3
- } from "./chunk-HIIYRATQ.js";
3
+ } from "./chunk-ESAACKVG.js";
4
4
  import {
5
5
  createEvidenceRecord,
6
6
  rememberEvidence
7
- } from "./chunk-L2GU3PWU.js";
7
+ } from "./chunk-DEIYY6NI.js";
8
8
  import {
9
9
  applyToolResultBudgetToMessages
10
10
  } from "./chunk-O7S3HYE6.js";
11
11
  import {
12
12
  injectDeepCompactSummary,
13
13
  maybeRunDeepCompactBeforeProvider
14
- } from "./chunk-RMLTVKOY.js";
14
+ } from "./chunk-L4YVE3RG.js";
15
15
  import {
16
16
  getContextWindowForModel
17
17
  } from "./chunk-K4FSYBSY.js";
@@ -28,7 +28,7 @@ import {
28
28
  sanitizeDiagnosticText,
29
29
  sanitizeDisplayPaths,
30
30
  truncateDisplay
31
- } from "./chunk-OMZYPQVA.js";
31
+ } from "./chunk-UGYFQF6M.js";
32
32
 
33
33
  // src/compact-preflight-runtime.ts
34
34
  import "@linghun/providers";
@@ -2,7 +2,7 @@ import {
2
2
  buildTranscriptScreenBuffer,
3
3
  selectionLineIndexesForBlock,
4
4
  selectionLineRangesForBlock
5
- } from "./chunk-NKFKOEYX.js";
5
+ } from "./chunk-WCMHJ6SS.js";
6
6
  import {
7
7
  buildHelpPanelData
8
8
  } from "./chunk-3AKXDMVS.js";
@@ -24,16 +24,16 @@ import {
24
24
  formatPermissionModeLabel,
25
25
  permissionModeColor,
26
26
  permissionModeSymbol
27
- } from "./chunk-KI7C6ZOD.js";
27
+ } from "./chunk-VIJ7GDKI.js";
28
28
  import {
29
29
  sanitizeMainScreenLeakage
30
- } from "./chunk-7TYK55JT.js";
30
+ } from "./chunk-BEDD7OFL.js";
31
31
  import {
32
32
  SLASH_COMMAND_REGISTRY
33
33
  } from "./chunk-PGNALDEH.js";
34
34
  import {
35
35
  formatElapsedSince
36
- } from "./chunk-UDQT5CWK.js";
36
+ } from "./chunk-PI6T2AGS.js";
37
37
  import {
38
38
  DEFAULT_KEYBINDINGS
39
39
  } from "./chunk-6SMM5CMP.js";
@@ -42,7 +42,7 @@ import {
42
42
  } from "./chunk-K4FSYBSY.js";
43
43
  import {
44
44
  truncateMiddle
45
- } from "./chunk-APJIC2O5.js";
45
+ } from "./chunk-GTIZNO5O.js";
46
46
 
47
47
  // src/shell/view-model.ts
48
48
  import { basename } from "path";
@@ -1136,7 +1136,9 @@ function buildPermissionExplanationLinesFromVerdict(verdict, risk, language) {
1136
1136
  function inferSemanticByToolName(toolName) {
1137
1137
  if (toolName === "Bash") return "destructive";
1138
1138
  if (toolName === "Write" || toolName === "Edit" || toolName === "MultiEdit") return "mutating";
1139
- if (toolName === "Read" || toolName === "Glob" || toolName === "Grep") return "readonly";
1139
+ if (toolName === "Read" || toolName === "ReadSnippets" || toolName === "SourcePack" || toolName === "Glob" || toolName === "Grep") {
1140
+ return "readonly";
1141
+ }
1140
1142
  if (toolName === "WebSearch" || toolName === "WebFetch") return "network";
1141
1143
  return "unknown";
1142
1144
  }
@@ -1169,9 +1171,11 @@ function buildPermissionActionSummary(language, toolName, input) {
1169
1171
  const path = str("file_path") ?? str("path");
1170
1172
  if (path) return zh ? `\u4FEE\u6539\u6587\u4EF6\uFF1A${path}` : `Edit file: ${path}`;
1171
1173
  }
1172
- if (toolName === "Read") {
1174
+ if (toolName === "Read" || toolName === "ReadSnippets" || toolName === "SourcePack") {
1173
1175
  const path = str("path") ?? str("file_path");
1174
1176
  if (path) return zh ? `\u8BFB\u53D6\u6587\u4EF6\uFF1A${path}` : `Read file: ${path}`;
1177
+ if (toolName === "ReadSnippets") return zh ? "\u8BFB\u53D6\u4EE3\u7801\u7247\u6BB5" : "Read snippets";
1178
+ if (toolName === "SourcePack") return zh ? "\u5B9A\u4F4D\u4EE3\u7801\u7247\u6BB5" : "Locate source snippets";
1175
1179
  }
1176
1180
  if (toolName === "Glob" || toolName === "Grep") {
1177
1181
  const target = str("pattern") ?? str("path");
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-GTP2KPLY.js";
6
6
  import {
7
7
  showCommandPanel
8
- } from "./chunk-AZU7HXIT.js";
8
+ } from "./chunk-6JPUBF7B.js";
9
9
  import {
10
10
  MANAGED_WORKTREE_DIRNAME,
11
11
  redactWorktreePath,
@@ -47,6 +47,89 @@ function displayWidth(value) {
47
47
  for (const char of value) width += charWidth(char);
48
48
  return width;
49
49
  }
50
+ function computeWrappedInputState(input) {
51
+ const normalizedText = String(input.text ?? "").replace(/\r/g, "");
52
+ const chars = Array.from(normalizedText);
53
+ const cursorOffset = clamp(input.cursorOffset, 0, chars.length);
54
+ const safeWidth = Math.max(0, Math.floor(Number.isFinite(input.width) ? input.width : 0));
55
+ const safePrefixWidth = Math.max(0, Math.floor(input.prefixWidth ?? 0));
56
+ const safePaddingLeft = Math.max(0, Math.floor(input.paddingLeft ?? 0));
57
+ const safePaddingRight = Math.max(0, Math.floor(input.paddingRight ?? 0));
58
+ const safeMinContentWidth = Math.max(0, Math.floor(input.minContentWidth ?? 0));
59
+ const contentWidth = Math.max(
60
+ safeMinContentWidth,
61
+ safeWidth - safePaddingLeft - safePaddingRight
62
+ );
63
+ const firstLineWidth = Math.max(1, contentWidth - safePrefixWidth);
64
+ const wrappedLines = [];
65
+ let cursorRow = 0;
66
+ let cursorCol = 0;
67
+ let cursorResolved = false;
68
+ const logicalLines = normalizedText.split("\n");
69
+ let logicalLineStart = 0;
70
+ let fallbackLineStart = 0;
71
+ let fallbackLineChars = [];
72
+ for (let logicalIndex = 0; logicalIndex < logicalLines.length; logicalIndex += 1) {
73
+ const lineText = logicalLines[logicalIndex] ?? "";
74
+ const lineChars = Array.from(lineText);
75
+ const lineStartOffset = logicalLineStart;
76
+ const lineEndOffset = lineStartOffset + lineChars.length;
77
+ const wrapWidth = logicalIndex === 0 ? firstLineWidth : Math.max(1, contentWidth);
78
+ const segments = wrapInputLine(lineChars, wrapWidth);
79
+ fallbackLineStart = lineStartOffset;
80
+ fallbackLineChars = lineChars;
81
+ for (const segment of segments) {
82
+ const segmentText = lineChars.slice(segment.start, segment.end).join("");
83
+ wrappedLines.push(segmentText);
84
+ if (!cursorResolved && cursorOffset >= lineStartOffset && cursorOffset <= lineEndOffset) {
85
+ const lineCursorOffset = cursorOffset - lineStartOffset;
86
+ if (lineCursorOffset >= segment.start && lineCursorOffset <= segment.end) {
87
+ cursorRow = wrappedLines.length - 1;
88
+ cursorCol = displayWidth(lineChars.slice(segment.start, lineCursorOffset).join(""));
89
+ cursorResolved = true;
90
+ }
91
+ }
92
+ }
93
+ logicalLineStart += lineChars.length + 1;
94
+ }
95
+ if (!cursorResolved) {
96
+ cursorRow = Math.max(0, wrappedLines.length - 1);
97
+ cursorCol = displayWidth(
98
+ fallbackLineChars.slice(0, clamp(cursorOffset - fallbackLineStart, 0, fallbackLineChars.length)).join("")
99
+ );
100
+ if (chars.length === 0) cursorCol = 0;
101
+ }
102
+ return {
103
+ lines: wrappedLines.length > 0 ? wrappedLines : [""],
104
+ cursorRow,
105
+ cursorCol,
106
+ contentWidth
107
+ };
108
+ }
109
+ function wrapInputLine(chars, wrapWidth) {
110
+ const safeWrapWidth = Math.max(1, Math.floor(wrapWidth));
111
+ const segments = [];
112
+ let start = 0;
113
+ while (start < chars.length || chars.length === 0 && start === 0) {
114
+ let end = start;
115
+ let width = 0;
116
+ while (end < chars.length) {
117
+ const nextWidth = charWidth(chars[end] ?? "");
118
+ if (width > 0 && width + nextWidth > safeWrapWidth) break;
119
+ width += nextWidth;
120
+ end += 1;
121
+ }
122
+ if (end === start && chars.length > 0) end += 1;
123
+ segments.push({ start, end });
124
+ if (chars.length === 0) break;
125
+ start = end;
126
+ }
127
+ return segments;
128
+ }
129
+ function clamp(value, min, max) {
130
+ if (!Number.isFinite(value)) return min;
131
+ return Math.min(max, Math.max(min, Math.floor(value)));
132
+ }
50
133
  function truncateDisplay(value, max) {
51
134
  const normalized = String(value || "").replace(/\s+/gu, " ").trim();
52
135
  if (displayWidth(normalized) <= max) return normalized;
@@ -140,6 +223,7 @@ export {
140
223
  wrapText,
141
224
  charWidth,
142
225
  displayWidth,
226
+ computeWrappedInputState,
143
227
  truncateDisplay,
144
228
  truncateMiddle,
145
229
  composerMaxWidth,
@@ -5,7 +5,7 @@ import {
5
5
  fitText,
6
6
  lineChar,
7
7
  wrapText
8
- } from "./chunk-APJIC2O5.js";
8
+ } from "./chunk-GTIZNO5O.js";
9
9
 
10
10
  // src/shell/components/CommandPanel.tsx
11
11
  import { Box, Text } from "@linghun/ink-runtime";