@linghun/tui 0.1.3 → 0.1.4

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 (94) hide show
  1. package/dist/background-control-runtime.js +29 -29
  2. package/dist/cache-command-runtime.js +3 -3
  3. package/dist/capability-runtime.js +17 -17
  4. package/dist/{chunk-QD4SCW4A.js → chunk-2JFSRRK7.js} +21 -21
  5. package/dist/{chunk-6JPUBF7B.js → chunk-2JZBPXHF.js} +12 -12
  6. package/dist/{chunk-J7AAPUTV.js → chunk-33WA4BDG.js} +4 -4
  7. package/dist/{chunk-NWZ44SFI.js → chunk-3KRRVLS4.js} +111 -78
  8. package/dist/{chunk-ZPFOP557.js → chunk-4UER2AKI.js} +0 -190
  9. package/dist/{chunk-YBTXLLO5.js → chunk-7ODJHN53.js} +1 -1
  10. package/dist/{chunk-6DBBXNEG.js → chunk-7VGFNZPN.js} +38 -2
  11. package/dist/{chunk-QXV2N4F2.js → chunk-AFNWUI6R.js} +1 -1
  12. package/dist/{chunk-G7O26P5X.js → chunk-BRNV6757.js} +1 -1
  13. package/dist/{chunk-7XAOTGHZ.js → chunk-CL3U56EI.js} +1 -1
  14. package/dist/{chunk-OH35XDD4.js → chunk-HMGGPN4J.js} +1 -1
  15. package/dist/{chunk-CQCJGMXG.js → chunk-IU7NZO6B.js} +2 -2
  16. package/dist/{chunk-3LT6OWQ2.js → chunk-IWBV4CEI.js} +1 -1
  17. package/dist/{chunk-DEIYY6NI.js → chunk-JY2DO7OF.js} +4 -155
  18. package/dist/{chunk-OV5OT66G.js → chunk-KI7NO6IF.js} +216 -5
  19. package/dist/{chunk-KKZBBCHK.js → chunk-NL4M3V5D.js} +1 -1
  20. package/dist/{chunk-IQS34W5A.js → chunk-NR3MFRPO.js} +1 -1
  21. package/dist/{chunk-ESAACKVG.js → chunk-R7BB45CP.js} +1 -1
  22. package/dist/{chunk-RDTVAQBD.js → chunk-RKFC3V6A.js} +112 -26
  23. package/dist/{chunk-PBIPV4LD.js → chunk-RMXEIZYR.js} +1 -1
  24. package/dist/{chunk-4TO2LDMP.js → chunk-SEVD3KES.js} +2 -2
  25. package/dist/{chunk-5OZEJQBH.js → chunk-T2V2USR3.js} +1 -1
  26. package/dist/{chunk-XYY5LRSF.js → chunk-T7LHFTVM.js} +3 -3
  27. package/dist/{chunk-7RZE45OT.js → chunk-UN3MMVE4.js} +1 -1
  28. package/dist/{chunk-TO6IN4LA.js → chunk-UUWG4VXV.js} +5 -195
  29. package/dist/{chunk-GYHEUVR2.js → chunk-UYEVRXUA.js} +3 -3
  30. package/dist/{chunk-RDGM4RUE.js → chunk-VZFP7NWI.js} +1 -1
  31. package/dist/{chunk-7ZMDQZ22.js → chunk-W6O7KDNM.js} +1 -1
  32. package/dist/{chunk-2YL5VKJ5.js → chunk-WO56RSMP.js} +1 -1
  33. package/dist/{chunk-BEDD7OFL.js → chunk-WRVHCSM2.js} +24 -8
  34. package/dist/{chunk-EGHM55EV.js → chunk-WXQSF2AS.js} +3 -3
  35. package/dist/{chunk-Q57WS7YZ.js → chunk-ZNAYWBBI.js} +2 -2
  36. package/dist/command-panel-runtime.js +16 -16
  37. package/dist/compact-cache-command-runtime.js +29 -29
  38. package/dist/compact-preflight-runtime.js +10 -10
  39. package/dist/connector-runtime.js +18 -18
  40. package/dist/deferred-tools-catalog.d.ts +2 -1
  41. package/dist/deferred-tools-catalog.d.ts.map +1 -1
  42. package/dist/deferred-tools-catalog.js +3 -1
  43. package/dist/details-status-runtime.js +16 -16
  44. package/dist/evidence-runtime.d.ts.map +1 -1
  45. package/dist/evidence-runtime.js +6 -6
  46. package/dist/extension-command-runtime.js +3 -3
  47. package/dist/extension-slash-runtime.js +17 -17
  48. package/dist/failure-learning-command-runtime.js +17 -17
  49. package/dist/final-answer-gate.d.ts +0 -1
  50. package/dist/final-answer-gate.d.ts.map +1 -1
  51. package/dist/final-answer-gate.js +2 -4
  52. package/dist/git-command-runtime.js +17 -17
  53. package/dist/handoff-session-runtime.js +3 -3
  54. package/dist/headless-bench-runtime.d.ts +1 -19
  55. package/dist/headless-bench-runtime.d.ts.map +1 -1
  56. package/dist/headless-bench-runtime.js +1 -3
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +32 -42
  59. package/dist/job-agent-command-runtime.js +16 -16
  60. package/dist/mcp-index-runtime.d.ts +8 -0
  61. package/dist/mcp-index-runtime.d.ts.map +1 -1
  62. package/dist/mcp-index-runtime.js +19 -17
  63. package/dist/memory-command-runtime.js +17 -17
  64. package/dist/meta-scheduler-runtime.js +2 -2
  65. package/dist/model-command-runtime.js +17 -17
  66. package/dist/model-doctor-runtime.d.ts +1 -0
  67. package/dist/model-doctor-runtime.d.ts.map +1 -1
  68. package/dist/model-doctor-runtime.js +1 -1
  69. package/dist/model-loop-runtime.d.ts +15 -1
  70. package/dist/model-loop-runtime.d.ts.map +1 -1
  71. package/dist/model-loop-runtime.js +29 -1
  72. package/dist/model-prompt-runtime.d.ts.map +1 -1
  73. package/dist/model-prompt-runtime.js +3 -3
  74. package/dist/model-stream-runtime.js +29 -29
  75. package/dist/model-tool-runtime.d.ts +7 -0
  76. package/dist/model-tool-runtime.d.ts.map +1 -1
  77. package/dist/model-tool-runtime.js +31 -29
  78. package/dist/permission-approval-runtime.js +29 -29
  79. package/dist/provider-loop-runtime.js +3 -3
  80. package/dist/remote-command-runtime.js +17 -17
  81. package/dist/shell/components/ProductBlock.js +2 -2
  82. package/dist/shell/components/ShellApp.js +12 -12
  83. package/dist/shell/ink-renderer.js +12 -12
  84. package/dist/shell/view-model.js +4 -4
  85. package/dist/slash-command-runtime.js +29 -29
  86. package/dist/terminal-readiness-runtime.js +3 -3
  87. package/dist/tui-agent-job-runtime.js +4 -4
  88. package/dist/tui-context-runtime.js +3 -3
  89. package/dist/tui-model-runtime.js +2 -2
  90. package/dist/tui-output-surface.js +5 -5
  91. package/dist/verification-command-runtime.js +5 -5
  92. package/dist/workflow-command-runtime.js +16 -16
  93. package/package.json +4 -4
  94. package/dist/{chunk-Z265MCGC.js → chunk-VWEAK3UV.js} +3 -3
@@ -55,10 +55,6 @@ async function resolveHeadlessBenchConfig(input) {
55
55
  testTimeoutMs,
56
56
  maxRepairAttempts,
57
57
  requiredArtifacts,
58
- validationContract: createValidationContract({
59
- prompt: input.prompt,
60
- requiredArtifacts
61
- }),
62
58
  preflight: input.options?.preflight ?? parseBoolean(env.LINGHUN_HEADLESS_PREFLIGHT) ?? true,
63
59
  environmentSetupRetries
64
60
  };
@@ -81,7 +77,6 @@ async function runHeadlessEnvironmentPreflight(projectPath) {
81
77
  function createHeadlessBenchInitialPrompt(input) {
82
78
  if (!input.config.enabled) return input.originalPrompt;
83
79
  const required = input.config.requiredArtifacts.length ? `Required artifacts detected: ${input.config.requiredArtifacts.join(", ")}. Verify they exist and are readable before final.` : "No explicit output artifact path was detected; still verify observable task completion.";
84
- const contract = formatValidationContractPromptLines(input.config.validationContract);
85
80
  const test = input.config.testCommand ? `Official test command available: ${input.config.testCommand}. Prefer it over ad-hoc smoke tests before final.` : "No official test command was detected; use the strongest task-local verification available.";
86
81
  const preflight = input.preflight ? `Environment preflight: ${input.preflight.summary}` : "";
87
82
  return [
@@ -90,11 +85,9 @@ function createHeadlessBenchInitialPrompt(input) {
90
85
  "[Linghun headless bench guard]",
91
86
  test,
92
87
  required,
93
- ...contract,
94
88
  preflight,
95
89
  formatInitialProfileStrategy(input.config.profile),
96
90
  "If rg is unavailable, use grep/find/sed/awk fallbacks instead of failing the task.",
97
- ...formatCommonBenchStabilityGuidance(),
98
91
  "Do not claim completion from a self-written smoke test when an official test entrypoint is available."
99
92
  ].filter(Boolean).join("\n");
100
93
  }
@@ -224,9 +217,7 @@ function createHeadlessBenchRepairPrompt(input) {
224
217
  "Continue from the current workspace. Do not restart from scratch unless necessary.",
225
218
  "Use the official test failure and current files to make the smallest fix, then rerun the official test or artifact check.",
226
219
  formatRepairProfileStrategy(input.failure.category, input.profile ?? "generic"),
227
- ...formatCommonBenchStabilityGuidance(),
228
220
  input.preflight?.missingTools.includes("rg") ? "rg is missing in this environment; use grep/find/sed/awk fallbacks." : "",
229
- ...formatValidationContractPromptLines(input.validationContract),
230
221
  artifactLine,
231
222
  logLine,
232
223
  "",
@@ -237,183 +228,6 @@ function createHeadlessBenchRepairPrompt(input) {
237
228
  input.originalPrompt
238
229
  ].filter(Boolean).join("\n");
239
230
  }
240
- function createValidationContract(input) {
241
- const items = [];
242
- for (const path of input.requiredArtifacts) {
243
- pushValidationContractItem(items, {
244
- id: `artifact:${path}`,
245
- kind: "artifact",
246
- path,
247
- requiredTool: "Bash.artifact"
248
- });
249
- }
250
- for (const target of detectExplicitServiceTargets(input.prompt)) {
251
- const semanticTokens = detectServiceSemanticTokens(input.prompt);
252
- const semantic = semanticTokens.length >= 2 && hasSemanticServiceExpectation(input.prompt);
253
- const validationTarget = semantic ? normalizeServiceReadinessTarget(target) : target;
254
- pushValidationContractItem(items, {
255
- id: `service:${validationTarget}`,
256
- kind: "service",
257
- target: validationTarget,
258
- validation: semantic ? "semantic" : "readiness",
259
- ...semantic ? { semanticTokens } : {},
260
- requiredTool: "Bash.service"
261
- });
262
- }
263
- if (hasPreservationRequirement(input.prompt)) {
264
- for (const path of detectEngineeringArtifactTargets(input.prompt)) {
265
- pushValidationContractItem(items, {
266
- id: `preservation:${path}`,
267
- kind: "preservation",
268
- path,
269
- requiredTool: "Bash.artifact"
270
- });
271
- }
272
- }
273
- for (const path of uniqueStrings([
274
- ...input.requiredArtifacts.filter(isBinaryLikePath),
275
- ...detectEngineeringArtifactTargets(input.prompt).filter(
276
- (path2) => isBinaryLikePath(path2) || hasBinaryRequirementNearPath(input.prompt, path2)
277
- )
278
- ])) {
279
- pushValidationContractItem(items, {
280
- id: `binary:${path}`,
281
- kind: "binary",
282
- path,
283
- requiredTool: "Bash.binary"
284
- });
285
- }
286
- return { items };
287
- }
288
- function pushValidationContractItem(items, item) {
289
- if (items.some(
290
- (existing) => existing.kind === item.kind && existing.path === item.path && normalizeContractTarget(existing.target) === normalizeContractTarget(item.target)
291
- )) {
292
- return;
293
- }
294
- items.push(item);
295
- }
296
- function formatValidationContractPromptLines(contract) {
297
- if (!contract?.items.length) return [];
298
- return [
299
- "Validation contract: before final, satisfy each item with the required explicit tool.",
300
- ...contract.items.map((item) => {
301
- const subject = item.path ?? item.target ?? item.id;
302
- const semantic = item.kind === "service" && item.validation === "semantic" ? `; also run semantic request/response probes for expected fields/values (${(item.semanticTokens ?? []).join(", ")}) including representative and adversarial cases` : "";
303
- return `- ${item.kind}: ${subject}; required Bash input: ${formatValidationContractToolInput(item)}${semantic}`;
304
- })
305
- ];
306
- }
307
- function formatValidationContractToolInput(item) {
308
- if (item.requiredTool === "Bash.service") {
309
- const target = item.target ?? "http://127.0.0.1:PORT/";
310
- const url = target.startsWith("http://") || target.startsWith("https://") ? target : `http://${target}`;
311
- return `{ "service": { "action": "fetch", "url": ${JSON.stringify(url)}, "expectStatus": 200, "retry": 5 } }`;
312
- }
313
- if (item.requiredTool === "Bash.binary") {
314
- return `{ "binary": { "path": ${JSON.stringify(item.path ?? "PATH")} } }`;
315
- }
316
- if (item.kind === "preservation") {
317
- return `{ "artifact": { "path": ${JSON.stringify(item.path ?? "PATH")}, "preserve": { "mode": "compareNormalizedHtml", "expectedPath": "EXPECTED_PATH" } } }`;
318
- }
319
- return `{ "artifact": { "path": ${JSON.stringify(item.path ?? "PATH")} } }`;
320
- }
321
- function detectExplicitServiceTargets(prompt) {
322
- const targets = [];
323
- const urlPattern = /https?:\/\/(?:localhost|127\.0\.0\.1)(?::\d{1,5})?(?:\/[^\s`"')\]}<>]*)?/giu;
324
- for (const match of prompt.matchAll(urlPattern)) {
325
- targets.push(normalizeServiceTarget(match[0]));
326
- }
327
- const hostPortPattern = /\b(?:localhost|127\.0\.0\.1):\d{1,5}\b/giu;
328
- for (const match of prompt.matchAll(hostPortPattern)) {
329
- targets.push(normalizeServiceTarget(match[0]));
330
- }
331
- if (hasExplicitServicePortContext(prompt)) {
332
- const portPattern = /\b(?:port\s+(\d{1,5})|listen(?:ing)?(?:\s+on)?\s+(?:port\s+)?(\d{1,5})|localhost\s+port\s+(\d{1,5})|127\.0\.0\.1\s+port\s+(\d{1,5}))\b/giu;
333
- for (const match of prompt.matchAll(portPattern)) {
334
- const port = match[1] ?? match[2] ?? match[3] ?? match[4];
335
- if (port) targets.push(`127.0.0.1:${port}`);
336
- }
337
- }
338
- return uniqueStrings(targets).filter(hasValidServicePort);
339
- }
340
- function hasExplicitServicePortContext(prompt) {
341
- return /\b(?:service|server|serve|listen|http|endpoint|health|localhost|127\.0\.0\.1)\b/iu.test(prompt);
342
- }
343
- function hasSemanticServiceExpectation(prompt) {
344
- return /\b(?:api|endpoint|json|response|respond|return|schema|field|classification|sentiment|confidence|prediction|inference|request)\b|接口|响应|返回|字段|分类|预测/iu.test(
345
- prompt
346
- );
347
- }
348
- function detectServiceSemanticTokens(prompt) {
349
- const tokens = [];
350
- for (const match of prompt.matchAll(/["']([A-Za-z][A-Za-z0-9_-]{1,39})["']\s*:/gu)) {
351
- tokens.push(match[1]);
352
- }
353
- for (const match of prompt.matchAll(/\b(?:positive|negative|true|false|pass|fail|success|error|valid|invalid)\b/giu)) {
354
- tokens.push(match[0].toLowerCase());
355
- }
356
- return uniqueStrings(tokens).slice(0, 8);
357
- }
358
- function normalizeServiceTarget(value) {
359
- return value.replace(/[),.;!?]+$/u, "");
360
- }
361
- function normalizeServiceReadinessTarget(target) {
362
- try {
363
- const url = target.startsWith("http://") || target.startsWith("https://") ? new URL(target) : new URL(`http://${target}`);
364
- return target.startsWith("http://") || target.startsWith("https://") ? url.origin : `${url.hostname}:${url.port || (url.protocol === "https:" ? "443" : "80")}`;
365
- } catch {
366
- return target;
367
- }
368
- }
369
- function normalizeContractTarget(target) {
370
- if (!target) return void 0;
371
- try {
372
- const url = target.startsWith("http://") || target.startsWith("https://") ? new URL(target) : new URL(`http://${target}`);
373
- const port = url.port || (url.protocol === "https:" ? "443" : "80");
374
- const path = url.pathname.replace(/\/$/u, "");
375
- return `${url.hostname}:${port}${path}`;
376
- } catch {
377
- return target.replace(/\/$/u, "");
378
- }
379
- }
380
- function hasValidServicePort(target) {
381
- try {
382
- const url = target.startsWith("http://") || target.startsWith("https://") ? new URL(target) : new URL(`http://${target}`);
383
- const port = Number(url.port || (url.protocol === "https:" ? 443 : 80));
384
- return Number.isInteger(port) && port > 0 && port <= 65535;
385
- } catch {
386
- return false;
387
- }
388
- }
389
- function hasPreservationRequirement(prompt) {
390
- return /(?:\bpreserve\b|\bclean\b|\boriginal\b|\bunchanged\b|don't modify|do not modify|不要修改|保持原样|保留原始)/iu.test(
391
- prompt
392
- );
393
- }
394
- function isBinaryLikePath(path) {
395
- return /\.(?:bin|elf|so|dll|dylib|exe|o|a|class|wasm|7z|zip|tar|gz|xz|bz2)$/iu.test(path);
396
- }
397
- function hasBinaryRequirementNearPath(prompt, path) {
398
- const index = prompt.indexOf(path);
399
- if (index < 0) return false;
400
- const window = prompt.slice(Math.max(0, index - 80), Math.min(prompt.length, index + path.length + 80));
401
- return /(?:\bbinary\b|\bELF\b|二进制)/iu.test(window);
402
- }
403
- function formatCommonBenchStabilityGuidance() {
404
- return [
405
- "Command environment: prefer python3 over bare python. If a command reports python not found, treat it as recoverable and retry with python3.",
406
- 'Python dependencies: before relying on optional imports, probe with python3 -c "import X"; install only when appropriate, otherwise use a stdlib fallback.',
407
- "Services: after starting HTTP/gRPC/server processes, poll the port or health endpoint with a bounded timeout and inspect logs before final verification.",
408
- "Time budget: build the smallest verifiable solution first, run focused checks early, and avoid long blind builds/training runs near the deadline.",
409
- "Verifier alignment: read task-local tests/verifier expectations and confirm output path, filename, port, and answer format instead of only matching examples.",
410
- "Artifact checks: match validation commands to the artifact language or file type; do not run shell syntax checks on Python/JS/C++ source files.",
411
- "Preservation tasks: when unchanged/clean/original content must survive, avoid parser/serializer round-trips unless tests allow reformatting; make targeted edits and compare preserved regions.",
412
- "Sanitizer/filter tasks: run negative clean-sample checks that compare parser-normalized or whitespace-stripped output against the original; unsafe-case smoke tests alone are not enough.",
413
- "Answer extraction: inspect tests/expected files for required count, ordering, and multi-line answers; do not stop at the first plausible value when the verifier expects multiple outputs.",
414
- "Puzzle answer tasks: if multiple equally optimal or valid answers can exist and the output format allows a list, enumerate all required answers rather than a single example."
415
- ];
416
- }
417
231
  async function detectHeadlessBenchTaskProfile(input) {
418
232
  const files = await listProjectFiles(input.projectPath, 220);
419
233
  const haystack = `${input.prompt}
@@ -553,9 +367,6 @@ function formatRepairProfileStrategy(category, profile) {
553
367
  if (category === "missing_artifact") {
554
368
  return "Repair route: generate or write the required artifact now, then verify it exists, is readable, and is non-empty.";
555
369
  }
556
- if (category === "validation_contract") {
557
- return "Repair route: run the required explicit validation tool for the contract item, then repair any failed evidence before final.";
558
- }
559
370
  if (category === "test_timeout") {
560
371
  return "Repair route: narrow validation to focused tests or logs first; avoid repeatedly launching full expensive runs.";
561
372
  }
@@ -816,7 +627,6 @@ export {
816
627
  collectHeadlessArtifactChecklist,
817
628
  classifyEnvironmentSetupFailure,
818
629
  createHeadlessBenchRepairPrompt,
819
- createValidationContract,
820
630
  detectHeadlessBenchTaskProfile,
821
631
  detectEngineeringTaskProfile,
822
632
  classifyHeadlessFailure,
@@ -17,7 +17,7 @@ import {
17
17
  } from "./chunk-PI6T2AGS.js";
18
18
  import {
19
19
  MAX_BACKGROUND_TASKS
20
- } from "./chunk-RDGM4RUE.js";
20
+ } from "./chunk-VZFP7NWI.js";
21
21
  import {
22
22
  formatIndexRuntimeRef
23
23
  } from "./chunk-TYTVAFGB.js";
@@ -75,6 +75,28 @@ var CODEBASE_MEMORY_DESCRIPTIONS = {
75
75
  trace_path: "Trace a function call chain from -> to in an indexed project.",
76
76
  search_graph: "Find similar implementations / SIMILAR_TO entries in a project."
77
77
  };
78
+ var PRE_ENGINE_DESCRIPTIONS = {
79
+ pre_context: "Repository analysis: provide structured code facts (AST-based) for the current task context.",
80
+ pre_impact: "Repository impact analysis: analyze planned change scope via AST cross-references.",
81
+ pre_plan: "Repository edit planning: generate structured implementation hints from AST analysis.",
82
+ pre_verify: "Repository analysis verification: verify code change correctness via AST structural checks."
83
+ };
84
+ var PRE_ENGINE_REQUIRED_ARGS = {
85
+ pre_context: ["symbol"],
86
+ pre_impact: ["changes"],
87
+ pre_plan: ["task"],
88
+ pre_verify: ["changed_files"]
89
+ };
90
+ function listPreEngineDeferredTools() {
91
+ return Object.keys(PRE_ENGINE_DESCRIPTIONS).sort((a, b) => a.localeCompare(b)).map((name) => ({
92
+ name,
93
+ kind: "pre-engine",
94
+ description: PRE_ENGINE_DESCRIPTIONS[name] ?? `pre-engine tool: ${name}`,
95
+ requiredArgs: PRE_ENGINE_REQUIRED_ARGS[name] ?? [],
96
+ executable: true,
97
+ reason: "pre-engine static whitelist; readonly AST query, no mutation."
98
+ }));
99
+ }
78
100
  function listCodebaseMemoryDeferredTools() {
79
101
  const required = codebaseMemoryRequiredArgs();
80
102
  return Object.keys(required).sort((a, b) => a.localeCompare(b)).map((name) => ({
@@ -161,6 +183,7 @@ function pluginManifestHasContribution(plugin) {
161
183
  function listDeferredTools(context) {
162
184
  return [
163
185
  ...listCodebaseMemoryDeferredTools(),
186
+ ...listPreEngineDeferredTools(),
164
187
  ...listMcpDeferredTools(context),
165
188
  ...listSkillDeferredTools(context),
166
189
  ...listPluginDeferredTools(context)
@@ -170,6 +193,7 @@ function snapshotDeferredTools(context) {
170
193
  const tools = listDeferredTools(context);
171
194
  const byKind = {
172
195
  "codebase-memory": 0,
196
+ "pre-engine": 0,
173
197
  mcp: 0,
174
198
  skill: 0,
175
199
  plugin: 0
@@ -195,6 +219,13 @@ function snapshotDeferredToolsSummary(context) {
195
219
  executableCount: snapshot.executableCount
196
220
  };
197
221
  }
222
+ function registerPreEngineDeferredToolsForRuntime(context, snapshot) {
223
+ const names = snapshot.tools.filter((tool) => tool.kind === "pre-engine" && tool.executable).map((tool) => tool.name).sort((a, b) => a.localeCompare(b));
224
+ for (const name of names) {
225
+ context.discoveredDeferredToolNames.add(name);
226
+ }
227
+ return names;
228
+ }
198
229
  var DISCOVERED_NAME_MAX_LEN = 80;
199
230
  var DISCOVERED_NAMES_MAX_COUNT = 32;
200
231
  function sanitizeDiscoveredDeferredToolName(name) {
@@ -217,9 +248,13 @@ function snapshotDiscoveredDeferredToolsSummary(context) {
217
248
  function searchDeferredTools(query, tools) {
218
249
  const trimmed = query.trim().toLowerCase();
219
250
  if (trimmed === "") return tools;
251
+ const tokens = trimmed.split(/[^a-z0-9_:.-]+/u).filter((token) => token.length >= 3);
220
252
  return tools.filter((tool) => {
221
253
  const haystack = `${tool.name} ${tool.description} ${tool.kind}`.toLowerCase();
222
- return haystack.includes(trimmed);
254
+ if (haystack.includes(trimmed)) return true;
255
+ if (tokens.length === 0) return false;
256
+ const hits = tokens.filter((token) => haystack.includes(token)).length;
257
+ return hits >= Math.min(2, tokens.length);
223
258
  });
224
259
  }
225
260
  function findDeferredTool(toolName, tools) {
@@ -235,7 +270,7 @@ function deferredToolListHashInput(tools) {
235
270
  }
236
271
  function formatDeferredToolsSystemReminder(language, snapshot) {
237
272
  if (snapshot.total === 0) return void 0;
238
- return language === "en-US" ? "Additional tools must be discovered via SearchExtraTools, then invoked via ExecuteExtraTool. Built-in tools (Read/ReadSnippets/SourcePack/Edit/Write/Bash/Grep/Glob/Todo) are still called directly." : "Additional tools must be discovered via SearchExtraTools, then invoked via ExecuteExtraTool.";
273
+ return language === "en-US" ? "Additional tools must be discovered via SearchExtraTools, then invoked via ExecuteExtraTool. For repository code understanding, impact analysis, edit planning, or quick verification, discover specialized repository tools before broad manual exploration. If codebase-memory index is ready, prefer index-backed search/graph/architecture tools for broad repository discovery, then use pre-engine for AST precision; if the index is missing or stale, use pre-engine as the fast repository-analysis entry. Built-in tools (Read/ReadSnippets/SourcePack/Edit/Write/Bash/Grep/Glob/Todo) are still called directly." : "Additional tools must be discovered via SearchExtraTools, then invoked via ExecuteExtraTool. For repository code understanding, impact analysis, edit planning, or quick verification, discover specialized repository tools before broad manual exploration. If codebase-memory index is ready, prefer index-backed search/graph/architecture tools for broad repository discovery, then use pre-engine for AST precision; if the index is missing or stale, use pre-engine as the fast repository-analysis entry.";
239
274
  }
240
275
  function isCodebaseMemoryToolName(name) {
241
276
  return name in codebaseMemoryRequiredArgs();
@@ -268,6 +303,7 @@ export {
268
303
  listDeferredTools,
269
304
  snapshotDeferredTools,
270
305
  snapshotDeferredToolsSummary,
306
+ registerPreEngineDeferredToolsForRuntime,
271
307
  sanitizeDiscoveredDeferredToolName,
272
308
  snapshotDiscoveredDeferredToolsSummary,
273
309
  searchDeferredTools,
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-A4H3UTJZ.js";
4
4
  import {
5
5
  showCommandPanel
6
- } from "./chunk-6JPUBF7B.js";
6
+ } from "./chunk-2JZBPXHF.js";
7
7
  import {
8
8
  findFailureRecord,
9
9
  setFailureRecordStatus,
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-GTP2KPLY.js";
6
6
  import {
7
7
  showCommandPanel
8
- } from "./chunk-6JPUBF7B.js";
8
+ } from "./chunk-2JZBPXHF.js";
9
9
  import {
10
10
  MANAGED_WORKTREE_DIRNAME,
11
11
  redactWorktreePath,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  rememberBackgroundTask
3
- } from "./chunk-YBTXLLO5.js";
3
+ } from "./chunk-7ODJHN53.js";
4
4
  import {
5
5
  createProcessGuard
6
6
  } from "./chunk-VDQTNA4W.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createOutputBlock
3
- } from "./chunk-ESAACKVG.js";
3
+ } from "./chunk-R7BB45CP.js";
4
4
  import {
5
5
  writeLine
6
6
  } from "./chunk-UGYFQF6M.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ensureSession,
3
3
  showCommandPanel
4
- } from "./chunk-6JPUBF7B.js";
4
+ } from "./chunk-2JZBPXHF.js";
5
5
  import {
6
6
  decidePermission
7
7
  } from "./chunk-PHPEPZAA.js";
@@ -10,7 +10,7 @@ import {
10
10
  budgetToolResultTranscriptContent,
11
11
  createEvidenceRecord,
12
12
  rememberEvidence
13
- } from "./chunk-DEIYY6NI.js";
13
+ } from "./chunk-JY2DO7OF.js";
14
14
  import {
15
15
  sanitizeDiagnosticText,
16
16
  truncateDisplay,
@@ -5,7 +5,7 @@ import {
5
5
  hasOpenAiCompatibleProviderSetupProblem,
6
6
  inferProviderForRouteModel,
7
7
  isDefaultExecutorRoute
8
- } from "./chunk-2YL5VKJ5.js";
8
+ } from "./chunk-WO56RSMP.js";
9
9
 
10
10
  // src/tui-model-runtime.ts
11
11
  import { randomUUID } from "crypto";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  MAX_EVIDENCE_RECORDS
3
- } from "./chunk-RDGM4RUE.js";
3
+ } from "./chunk-VZFP7NWI.js";
4
4
  import {
5
5
  applyToolResultBudgetToMessages,
6
6
  formatToolResultBudgetEvidenceSummary,
@@ -15,10 +15,10 @@ import {
15
15
  } from "./chunk-IWUIOLMF.js";
16
16
  import {
17
17
  writeHandoffPacket
18
- } from "./chunk-7ZMDQZ22.js";
18
+ } from "./chunk-W6O7KDNM.js";
19
19
  import {
20
20
  deriveToolSupportsClaims
21
- } from "./chunk-NWZ44SFI.js";
21
+ } from "./chunk-3KRRVLS4.js";
22
22
  import {
23
23
  mergeFailureRecord,
24
24
  writeFailureRecord
@@ -234,10 +234,6 @@ async function recordToolEvidence(context, sessionId, name, output, input) {
234
234
  output.fullOutputPath ?? name,
235
235
  supportsClaims
236
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
- }
241
237
  rememberEvidence(context, evidence);
242
238
  await context.store.appendEvent(sessionId, {
243
239
  type: "evidence_record",
@@ -498,23 +494,14 @@ function compactToolOutputDataForTranscript(data) {
498
494
  };
499
495
  }
500
496
  function compactToolStructuredDataForTranscript(data) {
501
- const compact = {};
502
497
  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;
498
+ return diagnostics;
507
499
  }
508
500
  function compactDiagnosticsDataForTranscript(data) {
509
501
  const diagnostics = readDiagnosticsForTranscript(data);
510
502
  if (!diagnostics) return void 0;
511
503
  return { diagnostics };
512
504
  }
513
- function compactValidationEvidenceDataForTranscript(data) {
514
- const validationEvidence = readValidationEvidenceForTranscript(data);
515
- if (!validationEvidence) return void 0;
516
- return { validationEvidence };
517
- }
518
505
  function readDiagnosticsForTranscript(data) {
519
506
  if (!data || typeof data !== "object") return void 0;
520
507
  const diagnostics = data.diagnostics;
@@ -638,45 +625,8 @@ function compactToolEvidenceData(data) {
638
625
  for (const key of ["service", "serviceHint", "artifactHint", "binaryHint", "binaryPreflight"]) {
639
626
  if (record[key] !== void 0) compact[key] = record[key];
640
627
  }
641
- const validationEvidence = readValidationEvidenceForTranscript(data);
642
- if (validationEvidence) compact.validationEvidence = validationEvidence;
643
628
  return Object.keys(compact).length > 0 ? compact : void 0;
644
629
  }
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
630
  function rememberRecentDiagnostics(context, source, content, toolUseId, evidenceId) {
681
631
  const diagnostics = readDiagnosticsForTranscript(content?.data);
682
632
  if (!diagnostics || diagnostics.length === 0) return;
@@ -706,107 +656,6 @@ function appendToolResultContentDiagnostics(content) {
706
656
  text: diagnostics ? appendCompactDiagnostics(output.text, diagnostics) : output.text
707
657
  };
708
658
  }
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
- }
810
659
  async function budgetToolResultTranscriptContent(context, sessionId, toolUseId, content) {
811
660
  const contentText = stringifyToolResultContentForBudget(content);
812
661
  if (!contentText || contentText.startsWith("<persisted-tool-result>")) return content;