omnius 1.0.486 → 1.0.488

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.
package/dist/index.js CHANGED
@@ -11973,7 +11973,12 @@ function findSystemChromiumExecutable() {
11973
11973
  if (existsSync17(candidate))
11974
11974
  return candidate;
11975
11975
  }
11976
- for (const command of ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"]) {
11976
+ for (const command of [
11977
+ "google-chrome",
11978
+ "google-chrome-stable",
11979
+ "chromium",
11980
+ "chromium-browser"
11981
+ ]) {
11977
11982
  const resolved = which(command);
11978
11983
  if (resolved)
11979
11984
  return resolved;
@@ -12010,7 +12015,15 @@ function runNpm(args, timeout2 = 3e5, extraEnv = {}) {
12010
12015
  async function installPlaywrightPackage() {
12011
12016
  try {
12012
12017
  mkdirSync11(PLAYWRIGHT_RUNTIME_DIR, { recursive: true });
12013
- runNpm(["install", "--prefix", PLAYWRIGHT_RUNTIME_DIR, "playwright@latest", "--no-audit", "--no-fund", "--loglevel=error"]);
12018
+ runNpm([
12019
+ "install",
12020
+ "--prefix",
12021
+ PLAYWRIGHT_RUNTIME_DIR,
12022
+ "playwright@latest",
12023
+ "--no-audit",
12024
+ "--no-fund",
12025
+ "--loglevel=error"
12026
+ ]);
12014
12027
  if (await importPlaywrightFromRuntime())
12015
12028
  return null;
12016
12029
  return `Playwright installed under ${PLAYWRIGHT_RUNTIME_DIR}, but the module entry was not found.`;
@@ -12048,7 +12061,15 @@ async function installPlaywrightBrowser() {
12048
12061
  if (packageErr)
12049
12062
  return packageErr;
12050
12063
  }
12051
- runNpm(["exec", "--prefix", PLAYWRIGHT_RUNTIME_DIR, "--", "playwright", "install", "chromium"], 3e5, {
12064
+ runNpm([
12065
+ "exec",
12066
+ "--prefix",
12067
+ PLAYWRIGHT_RUNTIME_DIR,
12068
+ "--",
12069
+ "playwright",
12070
+ "install",
12071
+ "chromium"
12072
+ ], 3e5, {
12052
12073
  PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: void 0
12053
12074
  });
12054
12075
  return null;
@@ -12107,7 +12128,11 @@ async function ensureBrowser(options2 = {}) {
12107
12128
  browser = await pw.chromium.launch({
12108
12129
  headless: desiredHeadless,
12109
12130
  ...executablePath ? { executablePath } : {},
12110
- args: ["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage"]
12131
+ args: [
12132
+ "--no-sandbox",
12133
+ "--disable-setuid-sandbox",
12134
+ "--disable-dev-shm-usage"
12135
+ ]
12111
12136
  });
12112
12137
  context = await browser.newContext({
12113
12138
  viewport: { width: 1280, height: 720 },
@@ -12124,7 +12149,11 @@ async function ensureBrowser(options2 = {}) {
12124
12149
  try {
12125
12150
  browser = await pw.chromium.launch({
12126
12151
  headless: desiredHeadless,
12127
- args: ["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage"]
12152
+ args: [
12153
+ "--no-sandbox",
12154
+ "--disable-setuid-sandbox",
12155
+ "--disable-dev-shm-usage"
12156
+ ]
12128
12157
  });
12129
12158
  context = await browser.newContext({
12130
12159
  viewport: { width: 1280, height: 720 },
@@ -12160,7 +12189,7 @@ function attachDiagnosticListeners(p2) {
12160
12189
  pushBounded(consoleBuffer, {
12161
12190
  ts: Date.now(),
12162
12191
  type: String(msg.type?.() ?? "log"),
12163
- text: String(msg.text?.() ?? "").slice(0, 600),
12192
+ text: String(msg.text?.() ?? "").slice(0, 2e3),
12164
12193
  loc: loc?.url ? `${loc.url}:${loc.lineNumber ?? 0}:${loc.columnNumber ?? 0}` : void 0
12165
12194
  });
12166
12195
  } catch {
@@ -12169,15 +12198,15 @@ function attachDiagnosticListeners(p2) {
12169
12198
  p2.on("pageerror", (err) => {
12170
12199
  pushBounded(errorBuffer, {
12171
12200
  ts: Date.now(),
12172
- message: String(err?.message ?? err).slice(0, 600),
12173
- stack: typeof err?.stack === "string" ? err.stack.slice(0, 1500) : void 0
12201
+ message: String(err?.message ?? err).slice(0, 2e3),
12202
+ stack: typeof err?.stack === "string" ? err.stack.slice(0, 3e3) : void 0
12174
12203
  });
12175
12204
  });
12176
12205
  p2.on("requestfailed", (req3) => {
12177
12206
  pushBounded(networkBuffer, {
12178
12207
  ts: Date.now(),
12179
12208
  method: String(req3.method?.() ?? "GET"),
12180
- url: String(req3.url?.() ?? "").slice(0, 600),
12209
+ url: String(req3.url?.() ?? "").slice(0, 1e3),
12181
12210
  failure: String(req3.failure?.()?.errorText ?? "request failed").slice(0, 200),
12182
12211
  ok: false
12183
12212
  });
@@ -12188,20 +12217,168 @@ function attachDiagnosticListeners(p2) {
12188
12217
  pushBounded(networkBuffer, {
12189
12218
  ts: Date.now(),
12190
12219
  method: String(resp.request?.()?.method?.() ?? "GET"),
12191
- url: String(resp.url?.() ?? "").slice(0, 600),
12220
+ url: String(resp.url?.() ?? "").slice(0, 1e3),
12192
12221
  status,
12193
12222
  ok: status >= 200 && status < 400
12194
12223
  });
12195
12224
  } catch {
12196
12225
  }
12197
12226
  });
12227
+ p2.on("crash", () => {
12228
+ crashCount++;
12229
+ pushBounded(errorBuffer, {
12230
+ ts: Date.now(),
12231
+ message: `[BROWSER_CRASH] Page crashed (crash #${crashCount})`
12232
+ });
12233
+ });
12234
+ p2.on("worker", (worker2) => {
12235
+ try {
12236
+ const workerUrl = String(worker2.url?.() ?? "unknown");
12237
+ pushBounded(consoleBuffer, {
12238
+ ts: Date.now(),
12239
+ type: "worker",
12240
+ text: `Worker created: ${workerUrl}`
12241
+ });
12242
+ worker2.on("console", (msg) => {
12243
+ try {
12244
+ pushBounded(consoleBuffer, {
12245
+ ts: Date.now(),
12246
+ type: `worker:${String(msg.type?.() ?? "log")}`,
12247
+ text: `[worker] ${String(msg.text?.() ?? "")}`.slice(0, 2e3)
12248
+ });
12249
+ } catch {
12250
+ }
12251
+ });
12252
+ worker2.on("pageerror", (err) => {
12253
+ pushBounded(errorBuffer, {
12254
+ ts: Date.now(),
12255
+ message: `[worker] ${String(err?.message ?? err)}`.slice(0, 2e3),
12256
+ stack: typeof err?.stack === "string" ? err.stack.slice(0, 3e3) : void 0
12257
+ });
12258
+ });
12259
+ worker2.on("close", () => {
12260
+ pushBounded(consoleBuffer, {
12261
+ ts: Date.now(),
12262
+ type: "worker",
12263
+ text: `Worker closed: ${workerUrl}`
12264
+ });
12265
+ });
12266
+ } catch {
12267
+ }
12268
+ });
12269
+ p2.on("websocket", (ws) => {
12270
+ try {
12271
+ const wsUrl = String(ws.url?.() ?? "unknown");
12272
+ pushBounded(wsBuffer, {
12273
+ ts: Date.now(),
12274
+ kind: "recv",
12275
+ payload: `WebSocket opened: ${wsUrl}`,
12276
+ url: wsUrl
12277
+ });
12278
+ ws.on("framesent", (frame) => {
12279
+ try {
12280
+ pushBounded(wsBuffer, {
12281
+ ts: Date.now(),
12282
+ kind: "send",
12283
+ payload: String(frame.payload ?? "").slice(0, 500),
12284
+ url: wsUrl
12285
+ });
12286
+ } catch {
12287
+ }
12288
+ });
12289
+ ws.on("framereceived", (frame) => {
12290
+ try {
12291
+ pushBounded(wsBuffer, {
12292
+ ts: Date.now(),
12293
+ kind: "recv",
12294
+ payload: String(frame.payload ?? "").slice(0, 500),
12295
+ url: wsUrl
12296
+ });
12297
+ } catch {
12298
+ }
12299
+ });
12300
+ ws.on("close", (code8, reason) => {
12301
+ pushBounded(wsBuffer, {
12302
+ ts: Date.now(),
12303
+ kind: "close",
12304
+ payload: `WebSocket closed: code=${code8 ?? "?"} reason=${String(reason ?? "").slice(0, 200)}`,
12305
+ url: wsUrl
12306
+ });
12307
+ });
12308
+ ws.on("socketerror", (err) => {
12309
+ pushBounded(wsBuffer, {
12310
+ ts: Date.now(),
12311
+ kind: "error",
12312
+ payload: `WebSocket error: ${String(err?.message ?? err ?? "unknown")}`.slice(0, 500),
12313
+ url: wsUrl
12314
+ });
12315
+ });
12316
+ } catch {
12317
+ }
12318
+ });
12319
+ if (!initScriptInstalled) {
12320
+ try {
12321
+ p2.addInitScript(`(() => {
12322
+ if (window.__browserEvents) return;
12323
+ window.__browserEvents = [];
12324
+ const push = (evt) => {
12325
+ window.__browserEvents.push(evt);
12326
+ if (window.__browserEvents.length > 2000) window.__browserEvents.splice(0, window.__browserEvents.length - 2000);
12327
+ };
12328
+ const origError = console.error;
12329
+ console.error = function() {
12330
+ push({ ts: Date.now(), type: "console:error", text: Array.from(arguments).map(String).join(" ").slice(0, 2000) });
12331
+ return origError.apply(console, arguments);
12332
+ };
12333
+ const origWarn = console.warn;
12334
+ console.warn = function() {
12335
+ push({ ts: Date.now(), type: "console:warn", text: Array.from(arguments).map(String).join(" ").slice(0, 2000) });
12336
+ return origWarn.apply(console, arguments);
12337
+ };
12338
+ window.onerror = function(msg, source, lineno, colno, err) {
12339
+ push({ ts: Date.now(), type: "onerror", text: String(msg).slice(0, 2000), stack: err instanceof Error ? (err.stack || "").slice(0, 3000) : "" });
12340
+ };
12341
+ window.onunhandledrejection = function(evt) {
12342
+ const r = evt.reason;
12343
+ push({ ts: Date.now(), type: "unhandledRejection", text: String(r?.message ?? r ?? "unknown").slice(0, 2000), stack: typeof r?.stack === "string" ? r.stack.slice(0, 3000) : "" });
12344
+ };
12345
+ })()`);
12346
+ initScriptInstalled = true;
12347
+ } catch {
12348
+ }
12349
+ }
12198
12350
  }
12199
12351
  function clearDiagnosticBuffers() {
12200
12352
  consoleBuffer = [];
12201
12353
  networkBuffer = [];
12202
12354
  errorBuffer = [];
12355
+ wsBuffer = [];
12356
+ crashCount = 0;
12203
12357
  lastDomSummarySelectors = /* @__PURE__ */ new Map();
12204
12358
  }
12359
+ function formatDiagnosticSummary() {
12360
+ const errCount = errorBuffer.length;
12361
+ const consoleErrors = consoleBuffer.filter((e2) => /error/i.test(e2.type)).length;
12362
+ const consoleWarnings = consoleBuffer.filter((e2) => /warn/i.test(e2.type)).length;
12363
+ const netFailures = networkBuffer.filter((e2) => e2.ok === false).length;
12364
+ const wsErrors = wsBuffer.filter((e2) => e2.kind === "error" || e2.kind === "close").length;
12365
+ if (!errCount && !consoleErrors && !consoleWarnings && !netFailures && !wsErrors && !crashCount)
12366
+ return "";
12367
+ const parts = [];
12368
+ if (errCount)
12369
+ parts.push(`${errCount} page error(s)`);
12370
+ if (consoleErrors)
12371
+ parts.push(`${consoleErrors} console error(s)`);
12372
+ if (consoleWarnings)
12373
+ parts.push(`${consoleWarnings} console warning(s)`);
12374
+ if (netFailures)
12375
+ parts.push(`${netFailures} network failure(s)`);
12376
+ if (wsErrors)
12377
+ parts.push(`${wsErrors} websocket event(s)`);
12378
+ if (crashCount)
12379
+ parts.push(`${crashCount} crash(es)`);
12380
+ return ` [browser diagnostics: ${parts.join(", ")}. Use console_logs/page_errors/network_log/websocket_log to inspect.]`;
12381
+ }
12205
12382
  function resolveDomSummarySelector(selector) {
12206
12383
  const match = selector.trim().match(/^\[(\d+)\]$/);
12207
12384
  if (!match)
@@ -12262,7 +12439,10 @@ async function describeFocusedEditableInContext(context2, frameMeta) {
12262
12439
  return frameMeta ? { ...active, frame: frameMeta } : active;
12263
12440
  }
12264
12441
  async function describeFocusedEditable(pageHandle) {
12265
- const main2 = await describeFocusedEditableInContext(pageHandle, { kind: "main", url: pageHandle.url?.() ?? "" }).catch(() => null);
12442
+ const main2 = await describeFocusedEditableInContext(pageHandle, {
12443
+ kind: "main",
12444
+ url: pageHandle.url?.() ?? ""
12445
+ }).catch(() => null);
12266
12446
  if (main2?.["isEditable"])
12267
12447
  return main2;
12268
12448
  const frames = typeof pageHandle.frames === "function" ? pageHandle.frames() : [];
@@ -12384,14 +12564,24 @@ ${input.text.slice(0, 2e4)}`.toLowerCase();
12384
12564
  return {
12385
12565
  kind: "geo_or_policy_block",
12386
12566
  confidence: 0.72,
12387
- evidence: [`HTTP ${statusFailures[0].status} seen for ${statusFailures[0].url}`]
12567
+ evidence: [
12568
+ `HTTP ${statusFailures[0].status} seen for ${statusFailures[0].url}`
12569
+ ]
12388
12570
  };
12389
12571
  }
12390
12572
  if (/\b(enable javascript|javascript is disabled|please enable cookies)\b/i.test(haystack)) {
12391
- return { kind: "js_render_failed", confidence: 0.72, evidence: ["JavaScript/cookie render warning found"] };
12573
+ return {
12574
+ kind: "js_render_failed",
12575
+ confidence: 0.72,
12576
+ evidence: ["JavaScript/cookie render warning found"]
12577
+ };
12392
12578
  }
12393
12579
  if (input.errors.length > 0) {
12394
- return { kind: "network_failure", confidence: 0.45, evidence: [`${input.errors.length} page error(s) buffered`] };
12580
+ return {
12581
+ kind: "network_failure",
12582
+ confidence: 0.45,
12583
+ evidence: [`${input.errors.length} page error(s) buffered`]
12584
+ };
12395
12585
  }
12396
12586
  return { kind: "none", confidence: 0, evidence: [] };
12397
12587
  }
@@ -12661,13 +12851,19 @@ async function findBrowserVisualCandidate(pageHandle, target, visualX, visualY,
12661
12851
  }
12662
12852
  return candidates.filter((candidate) => includeOffscreen || candidate["visible"] === true).sort((a2, b) => Number(b["score"] ?? 0) - Number(a2["score"] ?? 0))[0] ?? null;
12663
12853
  }
12664
- function ok(output, start2) {
12665
- return { success: true, output, durationMs: Date.now() - start2 };
12854
+ function ok(output, start2, skipDiag = false) {
12855
+ const diag = skipDiag ? "" : formatDiagnosticSummary();
12856
+ return {
12857
+ success: true,
12858
+ output: diag ? `${output}
12859
+ ${diag}` : output,
12860
+ durationMs: Date.now() - start2
12861
+ };
12666
12862
  }
12667
12863
  function fail(error, start2) {
12668
12864
  return { success: false, output: "", error, durationMs: Date.now() - start2 };
12669
12865
  }
12670
- var pw, browser, context, page, browserHeadless, MAX_BUFFER, consoleBuffer, networkBuffer, errorBuffer, lastDomSummarySelectors, dynamicImport, PLAYWRIGHT_RUNTIME_DIR, PLAYWRIGHT_BROWSERS_DIR, PlaywrightBrowserTool;
12866
+ var pw, browser, context, page, browserHeadless, MAX_BUFFER, consoleBuffer, networkBuffer, errorBuffer, wsBuffer, crashCount, initScriptInstalled, lastDomSummarySelectors, dynamicImport, PLAYWRIGHT_RUNTIME_DIR, PLAYWRIGHT_BROWSERS_DIR, PlaywrightBrowserTool;
12671
12867
  var init_playwright_browser = __esm({
12672
12868
  "packages/execution/dist/tools/playwright-browser.js"() {
12673
12869
  "use strict";
@@ -12680,17 +12876,20 @@ var init_playwright_browser = __esm({
12680
12876
  context = null;
12681
12877
  page = null;
12682
12878
  browserHeadless = null;
12683
- MAX_BUFFER = 200;
12879
+ MAX_BUFFER = 5e3;
12684
12880
  consoleBuffer = [];
12685
12881
  networkBuffer = [];
12686
12882
  errorBuffer = [];
12883
+ wsBuffer = [];
12884
+ crashCount = 0;
12885
+ initScriptInstalled = false;
12687
12886
  lastDomSummarySelectors = /* @__PURE__ */ new Map();
12688
12887
  dynamicImport = new Function("mod", "return import(mod)");
12689
12888
  PLAYWRIGHT_RUNTIME_DIR = join15(homedir5(), ".omnius", "playwright-runtime");
12690
12889
  PLAYWRIGHT_BROWSERS_DIR = join15(PLAYWRIGHT_RUNTIME_DIR, "browsers");
12691
12890
  PlaywrightBrowserTool = class {
12692
12891
  name = "playwright_browser";
12693
- description = "Full-scope Playwright browser automation + diagnostic capture. Launches a persistent headless Chromium session by default, with optional visible/headed mode when a GUI display is available. Beyond navigation/interaction, this tool buffers everything the running app emits (console messages, network requests, JS exceptions, accessibility tree) so the agent can verify what is ACTUALLY happening — not just what the build/test reports. Auto-installs Playwright + Chromium on first use without sudo or OS package manager escalation. Diagnostic actions: observe_bundle, dom_summary, dom, console_logs, network_log, page_errors, a11y_snapshot, bounding_box, query_all, performance, cookies, storage, viewport, clear_diagnostics. Interaction actions: navigate, click, visual_click, fill, type, press, select, check, hover. Use fill with a selector or natural-language target for form fields; avoid raw evaluate for form filling because direct .value assignment does not fire app input/change events. This is a separate browser/runtime from browser_action; once you start a workflow here, continue here unless you intentionally navigate browser_action to the same URL. Capture actions: screenshot, pdf, content, innerText, innerHTML, getAttribute, evaluate. Loopback URLs (localhost, 127.0.0.1, ::1) are allowed for local development servers; private LAN and metadata URLs remain blocked. Workflow for user-facing work: start/serve the system with the stack-native tool, navigate to the real URL, then inspect page_errors, console_logs, network_log, DOM/accessibility, and screenshot evidence before completion. Build/typecheck/test output is only one layer; runtime browser evidence is required when the delivered artifact is a page, app, dashboard, game, form, visualization, or other UI. Repeat navigate/act/observe until the actual user flow is clean.";
12892
+ description = "Full-scope Playwright browser automation + diagnostic capture. Launches a persistent headless Chromium session by default, with optional visible/headed mode when a GUI display is available. Beyond navigation/interaction, this tool buffers everything the running app emits (console messages, network requests, JS exceptions, accessibility tree) so the agent can verify what is ACTUALLY happening — not just what the build/test reports. Auto-installs Playwright + Chromium on first use without sudo or OS package manager escalation. Diagnostic actions: observe_bundle, dom_summary, dom, console_logs, network_log, page_errors, websocket_log, a11y_snapshot, bounding_box, query_all, performance, cookies, storage, viewport, clear_diagnostics. Interaction actions: navigate, click, visual_click, fill, type, press, select, check, hover. Use fill with a selector or natural-language target for form fields; avoid raw evaluate for form filling because direct .value assignment does not fire app input/change events. This is a separate browser/runtime from browser_action; once you start a workflow here, continue here unless you intentionally navigate browser_action to the same URL. Capture actions: screenshot, pdf, content, innerText, innerHTML, getAttribute, evaluate. Loopback URLs (localhost, 127.0.0.1, ::1) are allowed for local development servers; private LAN and metadata URLs remain blocked. Workflow for user-facing work: start/serve the system with the stack-native tool, navigate to the real URL, then inspect page_errors, console_logs, network_log, DOM/accessibility, and screenshot evidence before completion. Build/typecheck/test output is only one layer; runtime browser evidence is required when the delivered artifact is a page, app, dashboard, game, form, visualization, or other UI. Repeat navigate/act/observe until the actual user flow is clean.";
12694
12893
  parameters = {
12695
12894
  type: "object",
12696
12895
  properties: {
@@ -12728,6 +12927,7 @@ var init_playwright_browser = __esm({
12728
12927
  "console_logs",
12729
12928
  "network_log",
12730
12929
  "page_errors",
12930
+ "websocket_log",
12731
12931
  "a11y_snapshot",
12732
12932
  "bounding_box",
12733
12933
  "query_all",
@@ -12827,13 +13027,27 @@ var init_playwright_browser = __esm({
12827
13027
  const delayMs = typeof args.delay_ms === "number" ? Math.max(0, Math.min(3e4, Math.round(args.delay_ms))) : 700;
12828
13028
  if (action === "close") {
12829
13029
  await closeBrowserSession();
12830
- return { success: true, output: "Browser closed.", durationMs: Date.now() - start2 };
13030
+ return {
13031
+ success: true,
13032
+ output: "Browser closed.",
13033
+ durationMs: Date.now() - start2
13034
+ };
12831
13035
  }
12832
13036
  const err = await ensureBrowser({ headless, forceNew });
12833
13037
  if (err)
12834
- return { success: false, output: "", error: err, durationMs: Date.now() - start2 };
13038
+ return {
13039
+ success: false,
13040
+ output: "",
13041
+ error: err,
13042
+ durationMs: Date.now() - start2
13043
+ };
12835
13044
  if (!page)
12836
- return { success: false, output: "", error: "No page available", durationMs: Date.now() - start2 };
13045
+ return {
13046
+ success: false,
13047
+ output: "",
13048
+ error: "No page available",
13049
+ durationMs: Date.now() - start2
13050
+ };
12837
13051
  try {
12838
13052
  switch (action) {
12839
13053
  // ── Navigation ──
@@ -12846,7 +13060,10 @@ var init_playwright_browser = __esm({
12846
13060
  } catch (err2) {
12847
13061
  return fail(networkEgressErrorMessage(err2), start2);
12848
13062
  }
12849
- const resp = await page.goto(url, { waitUntil: "domcontentloaded", timeout: timeout2 });
13063
+ const resp = await page.goto(url, {
13064
+ waitUntil: "domcontentloaded",
13065
+ timeout: timeout2
13066
+ });
12850
13067
  return ok(`Navigated to ${url} (status: ${resp?.status() ?? "unknown"})`, start2);
12851
13068
  }
12852
13069
  case "goBack": {
@@ -13036,14 +13253,20 @@ var init_playwright_browser = __esm({
13036
13253
  // ── Screenshot / PDF ──
13037
13254
  case "screenshot": {
13038
13255
  if (width || height) {
13039
- const current = page.viewportSize?.() ?? { width: 1280, height: 720 };
13256
+ const current = page.viewportSize?.() ?? {
13257
+ width: 1280,
13258
+ height: 720
13259
+ };
13040
13260
  await page.setViewportSize({
13041
13261
  width: width ?? current.width ?? 1280,
13042
13262
  height: height ?? current.height ?? 720
13043
13263
  });
13044
13264
  }
13045
13265
  const filePath = outputPath3 || value2 || "screenshot.png";
13046
- await page.screenshot({ path: filePath, fullPage: args.full_page === true });
13266
+ await page.screenshot({
13267
+ path: filePath,
13268
+ fullPage: args.full_page === true
13269
+ });
13047
13270
  const resolvedScreenshotPath = resolve9(process.cwd(), filePath);
13048
13271
  let screenshotEventBuffer = null;
13049
13272
  try {
@@ -13134,16 +13357,16 @@ var init_playwright_browser = __esm({
13134
13357
  case "console_logs": {
13135
13358
  const filter2 = (text2 || "").toLowerCase();
13136
13359
  const entries = filter2 ? consoleBuffer.filter((e2) => e2.type.toLowerCase().includes(filter2)) : consoleBuffer;
13137
- const tail = entries.slice(-50);
13360
+ const tail = entries.slice(-200);
13138
13361
  if (tail.length === 0) {
13139
- return ok(`No console messages buffered yet${filter2 ? ` (filter="${filter2}")` : ""}. Buffer holds last 200 messages.`, start2);
13362
+ return ok(`No console messages buffered yet${filter2 ? ` (filter="${filter2}")` : ""}.`, start2, true);
13140
13363
  }
13141
13364
  const lines = tail.map((e2) => {
13142
13365
  const at = new Date(e2.ts).toISOString().slice(11, 19);
13143
13366
  return `[${at}] ${e2.type.toUpperCase()}: ${e2.text}${e2.loc ? ` (${e2.loc})` : ""}`;
13144
13367
  });
13145
13368
  return ok(`Console messages (${tail.length}/${entries.length} shown${filter2 ? `, filter="${filter2}"` : ""}):
13146
- ${lines.join("\n")}`, start2);
13369
+ ${lines.join("\n")}`, start2, true);
13147
13370
  }
13148
13371
  case "network_log": {
13149
13372
  const mode = (text2 || "").toLowerCase();
@@ -13151,9 +13374,9 @@ ${lines.join("\n")}`, start2);
13151
13374
  if (mode === "failed" || mode === "errors") {
13152
13375
  entries = entries.filter((e2) => e2.ok === false);
13153
13376
  }
13154
- const tail = entries.slice(-50);
13377
+ const tail = entries.slice(-200);
13155
13378
  if (tail.length === 0) {
13156
- return ok(`No network entries buffered${mode ? ` (mode="${mode}")` : ""}. Navigate to a URL to populate.`, start2);
13379
+ return ok(`No network entries buffered${mode ? ` (mode="${mode}")` : ""}. Navigate to a URL to populate.`, start2, true);
13157
13380
  }
13158
13381
  const lines = tail.map((e2) => {
13159
13382
  const at = new Date(e2.ts).toISOString().slice(11, 19);
@@ -13161,11 +13384,11 @@ ${lines.join("\n")}`, start2);
13161
13384
  return `[${at}] ${e2.method} ${tag} ${e2.url}`;
13162
13385
  });
13163
13386
  return ok(`Network log (${tail.length}/${entries.length} shown${mode ? `, mode="${mode}"` : ""}):
13164
- ${lines.join("\n")}`, start2);
13387
+ ${lines.join("\n")}`, start2, true);
13165
13388
  }
13166
13389
  case "page_errors": {
13167
13390
  if (errorBuffer.length === 0) {
13168
- return ok("No uncaught page errors recorded.", start2);
13391
+ return ok("No uncaught page errors recorded.", start2, true);
13169
13392
  }
13170
13393
  const lines = errorBuffer.map((e2) => {
13171
13394
  const at = new Date(e2.ts).toISOString().slice(11, 19);
@@ -13173,11 +13396,31 @@ ${lines.join("\n")}`, start2);
13173
13396
  ${e2.stack.split("\n").slice(0, 4).join("\n ")}` : ""}`;
13174
13397
  });
13175
13398
  return ok(`Uncaught page errors (${errorBuffer.length}):
13176
- ${lines.join("\n\n")}`, start2);
13399
+ ${lines.join("\n\n")}`, start2, true);
13400
+ }
13401
+ case "websocket_log": {
13402
+ const filter2 = (text2 || "").toLowerCase();
13403
+ let entries = wsBuffer;
13404
+ if (filter2) {
13405
+ entries = wsBuffer.filter((e2) => e2.payload.toLowerCase().includes(filter2) || (e2.url || "").toLowerCase().includes(filter2));
13406
+ }
13407
+ if (entries.length === 0) {
13408
+ return ok(`No WebSocket events buffered${filter2 ? ` (filter="${filter2}")` : ""}.`, start2, true);
13409
+ }
13410
+ const tail = entries.slice(-100);
13411
+ const lines = tail.map((e2) => {
13412
+ const at = new Date(e2.ts).toISOString().slice(11, 19);
13413
+ return `[${at}] [${e2.kind.toUpperCase()}] ${e2.payload.slice(0, 400)}${e2.url ? ` (${e2.url})` : ""}`;
13414
+ });
13415
+ return ok(`WebSocket events (${tail.length}/${entries.length} shown${filter2 ? `, filter="${filter2}"` : ""}):
13416
+ ${lines.join("\n")}`, start2, true);
13177
13417
  }
13178
13418
  case "a11y_snapshot": {
13179
13419
  const root = selector ? await page.locator(selector).first().elementHandle() : null;
13180
- const tree2 = await page.accessibility.snapshot({ root: root ?? void 0, interestingOnly: true });
13420
+ const tree2 = await page.accessibility.snapshot({
13421
+ root: root ?? void 0,
13422
+ interestingOnly: true
13423
+ });
13181
13424
  if (!tree2)
13182
13425
  return ok("No accessibility tree (page may be empty).", start2);
13183
13426
  const render2 = (n2, depth = 0) => {
@@ -13277,7 +13520,10 @@ ${JSON.stringify(data, null, 2)}`, start2);
13277
13520
  }
13278
13521
  case "viewport": {
13279
13522
  if (width || height) {
13280
- const current = page.viewportSize?.() ?? { width: 1280, height: 720 };
13523
+ const current = page.viewportSize?.() ?? {
13524
+ width: 1280,
13525
+ height: 720
13526
+ };
13281
13527
  const next = {
13282
13528
  width: width ?? current.width ?? 1280,
13283
13529
  height: height ?? current.height ?? 720
@@ -13301,7 +13547,10 @@ ${JSON.stringify(data, null, 2)}`, start2);
13301
13547
  }
13302
13548
  case "observe_bundle": {
13303
13549
  if (width || height) {
13304
- const current = page.viewportSize?.() ?? { width: 1280, height: 720 };
13550
+ const current = page.viewportSize?.() ?? {
13551
+ width: 1280,
13552
+ height: 720
13553
+ };
13305
13554
  await page.setViewportSize({
13306
13555
  width: width ?? current.width ?? 1280,
13307
13556
  height: height ?? current.height ?? 720
@@ -13393,7 +13642,10 @@ ${JSON.stringify(data, null, 2)}`, start2);
13393
13642
  if (!visualTarget)
13394
13643
  return fail("target or text is required for visual_click", start2);
13395
13644
  if (width || height) {
13396
- const current = page.viewportSize?.() ?? { width: 1280, height: 720 };
13645
+ const current = page.viewportSize?.() ?? {
13646
+ width: 1280,
13647
+ height: 720
13648
+ };
13397
13649
  await page.setViewportSize({
13398
13650
  width: width ?? current.width ?? 1280,
13399
13651
  height: height ?? current.height ?? 720
@@ -13415,13 +13667,20 @@ ${JSON.stringify(data, null, 2)}`, start2);
13415
13667
  success: false,
13416
13668
  output: "",
13417
13669
  error: `Browser gate detected (${beforeGate.kind}); refusing to click through a bot/CAPTCHA challenge. Evidence: ${beforeGate.evidence.join("; ")}`,
13418
- llmContent: JSON.stringify({ gate: beforeGate, url: page.url(), title: await page.title() }, null, 2),
13670
+ llmContent: JSON.stringify({
13671
+ gate: beforeGate,
13672
+ url: page.url(),
13673
+ title: await page.title()
13674
+ }, null, 2),
13419
13675
  durationMs: Date.now() - start2
13420
13676
  };
13421
13677
  }
13422
13678
  const beforeBuffer = await page.screenshot({ fullPage: false });
13423
13679
  const beforePath = saveBuffer(defaultArtifactPath("visual-before", "png"), beforeBuffer);
13424
- const viewport = page.viewportSize?.() ?? { width: 1280, height: 720 };
13680
+ const viewport = page.viewportSize?.() ?? {
13681
+ width: 1280,
13682
+ height: 720
13683
+ };
13425
13684
  const screenshotSize = pngDimensions(beforeBuffer) ?? viewport;
13426
13685
  let pointResult = null;
13427
13686
  let visionError = null;
@@ -13464,7 +13723,12 @@ ${JSON.stringify(data, null, 2)}`, start2);
13464
13723
  ...diagnostics.map((line) => ` ${line}`)
13465
13724
  ].filter(Boolean).join("\n"),
13466
13725
  error: "No vision point returned for target.",
13467
- llmContent: JSON.stringify({ target: visualTarget, beforePath, diagnostics, visionError }, null, 2),
13726
+ llmContent: JSON.stringify({
13727
+ target: visualTarget,
13728
+ beforePath,
13729
+ diagnostics,
13730
+ visionError
13731
+ }, null, 2),
13468
13732
  durationMs: Date.now() - start2
13469
13733
  };
13470
13734
  }
@@ -13561,7 +13825,10 @@ ${JSON.stringify(data, null, 2)}`, start2);
13561
13825
  gateKind: beforeGate.kind,
13562
13826
  gateConfidence: beforeGate.confidence,
13563
13827
  gateEvidence: beforeGate.evidence,
13564
- metadata: { mode: browserHeadless === false ? "headed" : "headless", engine: "playwright" }
13828
+ metadata: {
13829
+ mode: browserHeadless === false ? "headed" : "headless",
13830
+ engine: "playwright"
13831
+ }
13565
13832
  }),
13566
13833
  after: createEvidenceObservation({
13567
13834
  screenshotPath: afterPath,
@@ -13578,7 +13845,10 @@ ${JSON.stringify(data, null, 2)}`, start2);
13578
13845
  gateKind: afterGate.kind,
13579
13846
  gateConfidence: afterGate.confidence,
13580
13847
  gateEvidence: afterGate.evidence,
13581
- metadata: { mode: browserHeadless === false ? "headed" : "headless", engine: "playwright" }
13848
+ metadata: {
13849
+ mode: browserHeadless === false ? "headed" : "headless",
13850
+ engine: "playwright"
13851
+ }
13582
13852
  }),
13583
13853
  delta: {
13584
13854
  screenshotChanged,
@@ -13641,16 +13911,21 @@ ${JSON.stringify(data, null, 2)}`, start2);
13641
13911
  };
13642
13912
  }
13643
13913
  case "clear_diagnostics": {
13644
- const sizes = `console=${consoleBuffer.length} network=${networkBuffer.length} errors=${errorBuffer.length}`;
13914
+ const sizes = `console=${consoleBuffer.length} network=${networkBuffer.length} errors=${errorBuffer.length} ws=${wsBuffer.length}`;
13645
13915
  clearDiagnosticBuffers();
13646
- return ok(`Cleared diagnostic buffers (${sizes}).`, start2);
13916
+ return ok(`Cleared diagnostic buffers (${sizes}).`, start2, true);
13647
13917
  }
13648
13918
  default:
13649
13919
  return fail(`Unknown action: ${action}`, start2);
13650
13920
  }
13651
13921
  } catch (err2) {
13652
13922
  const msg = err2 instanceof Error ? err2.message : String(err2);
13653
- return { success: false, output: "", error: msg.slice(0, 500), durationMs: Date.now() - start2 };
13923
+ return {
13924
+ success: false,
13925
+ output: "",
13926
+ error: msg.slice(0, 500),
13927
+ durationMs: Date.now() - start2
13928
+ };
13654
13929
  }
13655
13930
  }
13656
13931
  };
@@ -26388,7 +26663,34 @@ var init_compaction_policy = __esm({
26388
26663
  "[FAILED] Took",
26389
26664
  "[TOOL ACTION REASON CONTRACT]",
26390
26665
  "RUNTIME TOOL ARGUMENT REPAIR",
26391
- "trust_tier:tool_output_untrusted"
26666
+ "trust_tier:tool_output_untrusted",
26667
+ // Shell/build noise
26668
+ "exit code:",
26669
+ "Traceback (most recent call last)",
26670
+ "npm ERR!",
26671
+ "Build failed",
26672
+ "TS2304",
26673
+ "TS2322",
26674
+ "TS2584",
26675
+ "TS2742",
26676
+ "TS2339",
26677
+ "Module not found",
26678
+ "ERR_PNPM",
26679
+ "SyntaxError",
26680
+ "TypeError:",
26681
+ // Redundancy markers
26682
+ "[cache hit]",
26683
+ "[RESULT CACHED]",
26684
+ "[STOP RE-READING",
26685
+ "[SIBLING CACHE",
26686
+ "[CACHED RESULT",
26687
+ // Command echo / noise
26688
+ "source_tool:shell:",
26689
+ "$ ",
26690
+ "> ",
26691
+ // Verbosity (long separator lines)
26692
+ "━━━━━━━━━━━━━━━━━━━━",
26693
+ "────────────────────"
26392
26694
  ];
26393
26695
  }
26394
26696
  });
@@ -26523,6 +26825,7 @@ __export(dist_exports, {
26523
26825
  DECAY_TAU: () => DECAY_TAU,
26524
26826
  DEFAULT_CRL_CONFIG: () => DEFAULT_CRL_CONFIG,
26525
26827
  DEFAULT_ENCODING: () => DEFAULT_ENCODING,
26828
+ DEFAULT_NOISE_MARKERS: () => DEFAULT_NOISE_MARKERS,
26526
26829
  DEFAULT_RETRIEVAL: () => DEFAULT_RETRIEVAL,
26527
26830
  DEFAULT_TARGET: () => DEFAULT_TARGET,
26528
26831
  DEFAULT_WINDOW_MS: () => DEFAULT_WINDOW_MS,
@@ -574773,6 +575076,7 @@ function analyzeContextWindowDumpRequest(request) {
574773
575076
  let systemChars = 0;
574774
575077
  let userChars = 0;
574775
575078
  let assistantChars = 0;
575079
+ const allMessageParts = [];
574776
575080
  for (const message2 of messages2) {
574777
575081
  const rec = message2 && typeof message2 === "object" ? message2 : {};
574778
575082
  const role = typeof rec["role"] === "string" ? rec["role"] : "unknown";
@@ -574783,6 +575087,7 @@ function analyzeContextWindowDumpRequest(request) {
574783
575087
  totalChars += chars;
574784
575088
  roleCounts[role] = (roleCounts[role] ?? 0) + 1;
574785
575089
  roleChars[role] = (roleChars[role] ?? 0) + chars;
575090
+ allMessageParts.push(extracted.textWithoutImages);
574786
575091
  if (role === "system")
574787
575092
  systemChars += chars;
574788
575093
  if (role === "user")
@@ -574806,8 +575111,13 @@ function analyzeContextWindowDumpRequest(request) {
574806
575111
  }
574807
575112
  const toolSchemaChars = tools.reduce((sum2, tool) => sum2 + JSON.stringify(tool).length, 0);
574808
575113
  const structuralSignalChars = userChars + activeEvidenceChars + activeContextFrameChars + compactedDiscoveryChars + assistantChars;
574809
- const structuralNoiseCandidateChars = rawDiscoveryToolChars;
574810
- const ratio = structuralNoiseCandidateChars > 0 ? Number((structuralSignalChars / structuralNoiseCandidateChars).toFixed(3)) : null;
575114
+ const allText = allMessageParts.join("\n");
575115
+ const lineNoise = computeSignalToNoise(allText, DEFAULT_NOISE_MARKERS);
575116
+ const lineNoiseChars = lineNoise.noiseChars;
575117
+ const rawDiscoveryPenalty = rawDiscoveryToolChars * 0.5;
575118
+ const structuralNoiseCandidateChars = lineNoiseChars + rawDiscoveryPenalty;
575119
+ const ratio = Number((structuralSignalChars / Math.max(1, structuralNoiseCandidateChars)).toFixed(3));
575120
+ const snrDb = ratio > 0 ? Number((10 * Math.log10(ratio)).toFixed(2)) : -Infinity;
574811
575121
  return {
574812
575122
  messageCount: messages2.length,
574813
575123
  estimatedTokens: Math.ceil((totalChars + toolSchemaChars + imageCount * 6e3) / 4),
@@ -574828,7 +575138,9 @@ function analyzeContextWindowDumpRequest(request) {
574828
575138
  signalToNoise: {
574829
575139
  structuralSignalChars,
574830
575140
  structuralNoiseCandidateChars,
574831
- ratio
575141
+ ratio,
575142
+ snrDb,
575143
+ lineNoiseChars
574832
575144
  }
574833
575145
  };
574834
575146
  }
@@ -574856,9 +575168,22 @@ function textAndImagesFromContent(content) {
574856
575168
  return { textWithoutImages: text2.join("\n"), imageCount };
574857
575169
  }
574858
575170
  function isRawDiscoveryToolResult(text2) {
574859
- if (!text2.includes("source_tool:file_read") && !text2.includes("source_tool:list_directory") && !text2.includes("source_tool:find_files") && !text2.includes("source_tool:grep_search")) {
575171
+ const DISCOVERY_SOURCE_TOOLS = [
575172
+ "source_tool:file_read",
575173
+ "source_tool:list_directory",
575174
+ "source_tool:find_files",
575175
+ "source_tool:grep_search",
575176
+ "source_tool:glob_search",
575177
+ "source_tool:shell",
575178
+ "source_tool:web_search",
575179
+ "source_tool:web_fetch",
575180
+ "source_tool:git",
575181
+ "source_tool:npm",
575182
+ "source_tool:npx"
575183
+ ];
575184
+ const isDiscovery = DISCOVERY_SOURCE_TOOLS.some((t2) => text2.includes(t2));
575185
+ if (!isDiscovery)
574860
575186
  return false;
574861
- }
574862
575187
  return !text2.includes("[DISCOVERY COMPACTED") && !text2.includes("[DISCOVERY BOUNDED") && !text2.includes("[STOP RE-READING") && !text2.includes("[BRANCH-EXTRACT]");
574863
575188
  }
574864
575189
  function toSummary(record, path13) {
@@ -574930,6 +575255,7 @@ var IMAGE_BASE64_RE, DEFAULT_MAX_FILES, lastPruneAtMs;
574930
575255
  var init_contextWindowDump = __esm({
574931
575256
  "packages/orchestrator/dist/contextWindowDump.js"() {
574932
575257
  "use strict";
575258
+ init_dist();
574933
575259
  IMAGE_BASE64_RE = /\[IMAGE_BASE64:[^\]]+\]/g;
574934
575260
  DEFAULT_MAX_FILES = 200;
574935
575261
  lastPruneAtMs = 0;
@@ -576531,7 +576857,7 @@ var init_focusSupervisor = __esm({
576531
576857
  const oldS = this.lastContext.signalToNoiseRatio;
576532
576858
  const newS = input.context.signalToNoiseRatio;
576533
576859
  const pressureShift = oldP > 0 ? Math.abs(newP - oldP) / oldP : 0;
576534
- const snrShift = oldS !== null && oldS !== void 0 && oldS > 0 ? Math.abs((newS ?? 0) - oldS) / oldS : 0;
576860
+ const snrShift = oldS !== void 0 && oldS > 0 ? Math.abs((newS ?? 0) - oldS) / oldS : 0;
576535
576861
  if (pressureShift > 0.2 || snrShift > 0.2) {
576536
576862
  this.ignoredDirectiveStreak = 0;
576537
576863
  }
@@ -576877,7 +577203,7 @@ var init_focusSupervisor = __esm({
576877
577203
  return false;
576878
577204
  const pressure = context2.pressureRatio ?? 0;
576879
577205
  const ratio = context2.signalToNoiseRatio;
576880
- return pressure >= 0.85 || ratio !== null && ratio !== void 0 && ratio < 1.2;
577206
+ return pressure >= 0.85 || ratio !== void 0 && ratio < 1.2;
576881
577207
  }
576882
577208
  hasLowSignalContext(context2) {
576883
577209
  if (!context2)
@@ -577400,6 +577726,736 @@ var init_decomposition_orchestrator = __esm({
577400
577726
  }
577401
577727
  });
577402
577728
 
577729
+ // packages/orchestrator/dist/contextSNR.js
577730
+ function computeDPrime(signalScores, noiseScores) {
577731
+ if (signalScores.length === 0 || noiseScores.length === 0)
577732
+ return 0;
577733
+ const mean = (arr) => arr.reduce((s2, v) => s2 + v, 0) / arr.length;
577734
+ const variance = (arr, mu) => arr.reduce((s2, v) => s2 + (v - mu) ** 2, 0) / Math.max(1, arr.length - 1);
577735
+ const muSignal = mean(signalScores);
577736
+ const muNoise = mean(noiseScores);
577737
+ const varSignal = variance(signalScores, muSignal);
577738
+ const varNoise = variance(noiseScores, muNoise);
577739
+ const pooledStd = Math.sqrt((varSignal + varNoise) / 2);
577740
+ if (pooledStd < 0.01)
577741
+ return muSignal > muNoise ? (muSignal - muNoise) / 0.01 : 0;
577742
+ return (muSignal - muNoise) / pooledStd;
577743
+ }
577744
+ function toSnrDb(ratio) {
577745
+ if (ratio <= 0)
577746
+ return -Infinity;
577747
+ return Number((10 * Math.log10(ratio)).toFixed(2));
577748
+ }
577749
+ function computeContextSNR(input) {
577750
+ const { allMessageText, structuralSignalChars, rawDiscoveryToolChars, estimatedTokens, contextWindowSize, contradictionLoad, redundancyLoad, stalenessLoad, browserNoiseLoad, totalEstimatedTokens } = input;
577751
+ const lineNoise = computeSignalToNoise(allMessageText, DEFAULT_NOISE_MARKERS);
577752
+ const lineNoiseDimension = {
577753
+ label: "noise-markers",
577754
+ signalChars: lineNoise.signalChars,
577755
+ noiseChars: lineNoise.noiseChars,
577756
+ ratio: lineNoise.ratio
577757
+ };
577758
+ const rawDiscoveryPenalty = rawDiscoveryToolChars * 0.5;
577759
+ const rawDiscoveryDimension = {
577760
+ label: "raw-discovery",
577761
+ signalChars: 0,
577762
+ noiseChars: rawDiscoveryPenalty,
577763
+ ratio: rawDiscoveryToolChars === 0 ? 1 : 0
577764
+ };
577765
+ const totalChars = allMessageText.length || totalEstimatedTokens || 1;
577766
+ const contradictionDimension = contradictionLoad !== void 0 ? {
577767
+ label: "contradiction",
577768
+ load: contradictionLoad,
577769
+ noiseChars: Math.round(contradictionLoad * totalChars),
577770
+ ratio: contradictionLoad > 0 ? Number((1 / (contradictionLoad * 10)).toFixed(3)) : 1
577771
+ } : void 0;
577772
+ const redundancyDimension = redundancyLoad !== void 0 ? {
577773
+ label: "redundancy",
577774
+ load: redundancyLoad,
577775
+ noiseChars: Math.round(redundancyLoad * totalChars),
577776
+ ratio: redundancyLoad > 0 ? Number((1 / Math.max(redundancyLoad, 1e-3)).toFixed(3)) : 1
577777
+ } : void 0;
577778
+ const stalenessDimension = stalenessLoad !== void 0 ? {
577779
+ label: "staleness",
577780
+ load: stalenessLoad,
577781
+ noiseChars: Math.round(stalenessLoad * totalChars),
577782
+ ratio: stalenessLoad > 0 ? Number((1 / Math.max(stalenessLoad, 1e-3)).toFixed(3)) : 1
577783
+ } : void 0;
577784
+ const browserNoiseDimension = browserNoiseLoad !== void 0 ? {
577785
+ label: "browser-noise",
577786
+ load: browserNoiseLoad,
577787
+ noiseChars: Math.round(browserNoiseLoad * totalChars),
577788
+ ratio: browserNoiseLoad > 0 ? Number((1 / Math.max(browserNoiseLoad, 1e-3)).toFixed(3)) : 1
577789
+ } : void 0;
577790
+ const browserNoisePenalty = browserNoiseLoad !== void 0 ? browserNoiseLoad * totalChars : 0;
577791
+ const totalNoise = lineNoise.noiseChars + rawDiscoveryPenalty + browserNoisePenalty;
577792
+ const overallRatio = structuralSignalChars / Math.max(1, totalNoise);
577793
+ const capacityWindow = contextWindowSize ?? estimatedTokens ?? 128e3;
577794
+ const effectiveSlots = Math.max(1, Math.floor(capacityWindow / 100));
577795
+ const capacityWarning = allMessageText.length > effectiveSlots * 14;
577796
+ return {
577797
+ overall: {
577798
+ ratio: Number(overallRatio.toFixed(3)),
577799
+ snrDb: toSnrDb(overallRatio)
577800
+ },
577801
+ dimensions: {
577802
+ noiseMarkers: lineNoiseDimension,
577803
+ rawDiscovery: rawDiscoveryDimension,
577804
+ contradiction: contradictionDimension,
577805
+ redundancy: redundancyDimension,
577806
+ staleness: stalenessDimension,
577807
+ browserNoise: browserNoiseDimension
577808
+ },
577809
+ capacityWarning
577810
+ };
577811
+ }
577812
+ var init_contextSNR = __esm({
577813
+ "packages/orchestrator/dist/contextSNR.js"() {
577814
+ "use strict";
577815
+ init_dist();
577816
+ }
577817
+ });
577818
+
577819
+ // packages/orchestrator/dist/groundedness.js
577820
+ function extractClaims(text2) {
577821
+ if (!text2 || text2.length < 10)
577822
+ return [];
577823
+ const lines = text2.split("\n");
577824
+ const claims = [];
577825
+ const ASSERTION_PATTERNS = [
577826
+ /\b(is|are|was|were|has|have|had|contains|contained|includes|included|returns|returned|produces|produced|creates|created|modifies|modified|writes|wrote|reads|read|deletes|deleted|fixes|fixed|implements|implemented|adds|added|removes|removed|changes|changed|updates|updated|renames|renamed|refactors|refactored)\b/i,
577827
+ /\b(file|function|class|method|module|package|test|result|output|error|value|type|property)\b.{0,40}\b(is|was|contains|has|returns|does|will|should|could)\b/i,
577828
+ /^[A-Z][^.!?]{10,}\.(?!\s*[a-z])/,
577829
+ /\b(found|discovered|confirmed|verified|noticed|observed|detected|identified)\b/i,
577830
+ /\b(does not|will not|cannot|doesn't|won't|can't)\b.{5,}\./i
577831
+ ];
577832
+ const NON_CLAIM_PATTERNS = [
577833
+ /^```/,
577834
+ // Code blocks
577835
+ /^[-\*]\s/,
577836
+ // Bullet list items (too ambiguous)
577837
+ /^\d+[\.\)]\s/,
577838
+ // Numbered list items
577839
+ /^(let|const|var|import|export|function|class|interface|type)\s/,
577840
+ // Code
577841
+ /\?$/,
577842
+ // Questions
577843
+ /^(please|try|could you|would you|let's|we should|we need|make sure|ensure|check|verify|run|execute|call)\b/i,
577844
+ // Commands
577845
+ /^(i'll|i will|i'm going to|next|then|after that|first|second)\b/i,
577846
+ // Future plans
577847
+ /^(the (file|code|function|class|method).*is located|located at|can be found)/i,
577848
+ // Directions not claims
577849
+ /^(you can|you should|you'll need|you might)/i,
577850
+ // Instructions to user
577851
+ /tool_call|tool_result/i
577852
+ ];
577853
+ for (const line of lines) {
577854
+ const trimmed = line.trim();
577855
+ if (!trimmed)
577856
+ continue;
577857
+ if (NON_CLAIM_PATTERNS.some((p2) => p2.test(trimmed)))
577858
+ continue;
577859
+ if (!/[.!]/.test(trimmed))
577860
+ continue;
577861
+ const isAssertion = ASSERTION_PATTERNS.some((p2) => p2.test(trimmed));
577862
+ const hasColonAssertion = /^[A-Z][^:]{5,}:\s/.test(trimmed);
577863
+ const looksFactual = /^(result|output|status|exit|error|build|test)/i.test(trimmed) && /:/.test(trimmed) || /^(successfully|failed|completed|finished|created|deleted|modified|updated)\b/i.test(trimmed);
577864
+ if (isAssertion || hasColonAssertion || looksFactual) {
577865
+ const clean5 = trimmed.replace(/[`*_~#]/g, "").replace(/\s+/g, " ").trim();
577866
+ if (clean5.length >= 15 && clean5.length <= 600) {
577867
+ claims.push(clean5);
577868
+ }
577869
+ }
577870
+ }
577871
+ return deduplicateClaims(claims);
577872
+ }
577873
+ function deduplicateClaims(claims) {
577874
+ const seen = /* @__PURE__ */ new Set();
577875
+ const result = [];
577876
+ for (const claim of claims) {
577877
+ const key = claim.toLowerCase().replace(/[^a-z0-9]/g, "").slice(0, 80);
577878
+ if (seen.has(key))
577879
+ continue;
577880
+ seen.add(key);
577881
+ result.push(claim);
577882
+ }
577883
+ return result;
577884
+ }
577885
+ function mapClaimsToSpans(claims, contextSpans) {
577886
+ const claimToSpans = /* @__PURE__ */ new Map();
577887
+ const spanToClaims = /* @__PURE__ */ new Map();
577888
+ if (contextSpans.length === 0) {
577889
+ for (const claim of claims)
577890
+ claimToSpans.set(claim, []);
577891
+ return { claimToSpans, spanToClaims };
577892
+ }
577893
+ const spanNgrams = /* @__PURE__ */ new Map();
577894
+ for (const span of contextSpans) {
577895
+ spanNgrams.set(span.span_id, extractSignificantNgrams(span.content));
577896
+ }
577897
+ for (const claim of claims) {
577898
+ const claimNgrams = extractSignificantNgrams(claim);
577899
+ if (claimNgrams.size === 0) {
577900
+ claimToSpans.set(claim, []);
577901
+ continue;
577902
+ }
577903
+ const supportingSpans = [];
577904
+ for (const span of contextSpans) {
577905
+ const spanGrams = spanNgrams.get(span.span_id);
577906
+ if (!spanGrams || spanGrams.size === 0)
577907
+ continue;
577908
+ let overlap = 0;
577909
+ for (const gram of claimNgrams) {
577910
+ if (spanGrams.has(gram))
577911
+ overlap++;
577912
+ }
577913
+ const denom = Math.min(claimNgrams.size, spanGrams.size);
577914
+ const score = denom > 0 ? overlap / denom : 0;
577915
+ if (score >= 0.15 || overlap >= 2) {
577916
+ supportingSpans.push(span.span_id);
577917
+ }
577918
+ }
577919
+ claimToSpans.set(claim, supportingSpans);
577920
+ for (const sid of supportingSpans) {
577921
+ const existing = spanToClaims.get(sid) ?? [];
577922
+ existing.push(claim);
577923
+ spanToClaims.set(sid, existing);
577924
+ }
577925
+ }
577926
+ return { claimToSpans, spanToClaims };
577927
+ }
577928
+ function extractSignificantNgrams(text2) {
577929
+ const STOP_WORDS2 = /* @__PURE__ */ new Set([
577930
+ "the",
577931
+ "a",
577932
+ "an",
577933
+ "is",
577934
+ "was",
577935
+ "are",
577936
+ "were",
577937
+ "be",
577938
+ "been",
577939
+ "being",
577940
+ "have",
577941
+ "has",
577942
+ "had",
577943
+ "do",
577944
+ "does",
577945
+ "did",
577946
+ "will",
577947
+ "would",
577948
+ "could",
577949
+ "should",
577950
+ "may",
577951
+ "might",
577952
+ "shall",
577953
+ "can",
577954
+ "to",
577955
+ "of",
577956
+ "in",
577957
+ "for",
577958
+ "on",
577959
+ "with",
577960
+ "at",
577961
+ "by",
577962
+ "from",
577963
+ "as",
577964
+ "into",
577965
+ "through",
577966
+ "during",
577967
+ "before",
577968
+ "after",
577969
+ "above",
577970
+ "below",
577971
+ "between",
577972
+ "out",
577973
+ "off",
577974
+ "over",
577975
+ "under",
577976
+ "again",
577977
+ "further",
577978
+ "then",
577979
+ "once",
577980
+ "here",
577981
+ "there",
577982
+ "when",
577983
+ "where",
577984
+ "why",
577985
+ "how",
577986
+ "all",
577987
+ "each",
577988
+ "every",
577989
+ "both",
577990
+ "few",
577991
+ "more",
577992
+ "most",
577993
+ "other",
577994
+ "some",
577995
+ "such",
577996
+ "no",
577997
+ "nor",
577998
+ "not",
577999
+ "only",
578000
+ "own",
578001
+ "same",
578002
+ "so",
578003
+ "than",
578004
+ "too",
578005
+ "very",
578006
+ "just",
578007
+ "because",
578008
+ "and",
578009
+ "but",
578010
+ "or",
578011
+ "if",
578012
+ "while",
578013
+ "that",
578014
+ "this",
578015
+ "these",
578016
+ "those",
578017
+ "it",
578018
+ "its",
578019
+ "i",
578020
+ "you",
578021
+ "he",
578022
+ "she",
578023
+ "we",
578024
+ "they"
578025
+ ]);
578026
+ const grams = /* @__PURE__ */ new Set();
578027
+ const words = text2.toLowerCase().replace(/[^a-z0-9\s]/g, " ").split(/\s+/).filter((w) => w.length > 0 && !STOP_WORDS2.has(w));
578028
+ if (words.length < 2)
578029
+ return grams;
578030
+ for (let i2 = 0; i2 < words.length - 1; i2++) {
578031
+ grams.add(`2:${words[i2]}:${words[i2 + 1]}`);
578032
+ }
578033
+ for (let i2 = 0; i2 < words.length - 2; i2++) {
578034
+ grams.add(`3:${words[i2]}:${words[i2 + 1]}:${words[i2 + 2]}`);
578035
+ }
578036
+ if (words.length < 4) {
578037
+ for (const w of words) {
578038
+ if (w.length >= 4)
578039
+ grams.add(`1:${w}`);
578040
+ }
578041
+ }
578042
+ return grams;
578043
+ }
578044
+ function computeGroundedness(responseText, contextSpans, turn) {
578045
+ const claims = extractClaims(responseText);
578046
+ const total_claims = claims.length;
578047
+ if (total_claims === 0) {
578048
+ return {
578049
+ turn,
578050
+ total_claims: 0,
578051
+ supported_claims: 0,
578052
+ unsupported_claims: [],
578053
+ supporting_spans: [],
578054
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
578055
+ };
578056
+ }
578057
+ const mapping = mapClaimsToSpans(claims, contextSpans);
578058
+ const unsupported_claims = [];
578059
+ const allSupportingSpans = /* @__PURE__ */ new Set();
578060
+ for (const [claim, spanIds] of mapping.claimToSpans) {
578061
+ if (spanIds.length === 0) {
578062
+ unsupported_claims.push(claim);
578063
+ } else {
578064
+ for (const sid of spanIds)
578065
+ allSupportingSpans.add(sid);
578066
+ }
578067
+ }
578068
+ return {
578069
+ turn,
578070
+ total_claims,
578071
+ supported_claims: total_claims - unsupported_claims.length,
578072
+ unsupported_claims,
578073
+ supporting_spans: Array.from(allSupportingSpans),
578074
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
578075
+ };
578076
+ }
578077
+ function extractContextSpansForGroundedness(messages2) {
578078
+ const spans = [];
578079
+ for (const msg of messages2) {
578080
+ if (!msg.spanMeta)
578081
+ continue;
578082
+ if (msg.role === "system") {
578083
+ if (msg.spanMeta.provenance === "system_prompt_root")
578084
+ continue;
578085
+ }
578086
+ const content = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content ?? "");
578087
+ if (content.length >= 20) {
578088
+ spans.push({ span_id: msg.spanMeta.span_id, content });
578089
+ }
578090
+ }
578091
+ return spans;
578092
+ }
578093
+ var init_groundedness = __esm({
578094
+ "packages/orchestrator/dist/groundedness.js"() {
578095
+ "use strict";
578096
+ }
578097
+ });
578098
+
578099
+ // packages/orchestrator/dist/staleness.js
578100
+ function classifyProvenance(provenance) {
578101
+ const p2 = provenance.toLowerCase().replace(/[-_]/g, "_");
578102
+ if (p2.includes("file_read"))
578103
+ return "file_read";
578104
+ if (p2.includes("shell"))
578105
+ return "shell";
578106
+ if (p2.includes("sub_agent"))
578107
+ return "sub_agent";
578108
+ return void 0;
578109
+ }
578110
+ function computeStalenessLoad(messages2, currentTurn, stalenessThresholds) {
578111
+ const th = {
578112
+ file_read: stalenessThresholds?.file_read ?? STALENESS_THRESHOLD_DEFAULTS.file_read,
578113
+ shell: stalenessThresholds?.shell ?? STALENESS_THRESHOLD_DEFAULTS.shell,
578114
+ sub_agent: stalenessThresholds?.sub_agent ?? STALENESS_THRESHOLD_DEFAULTS.sub_agent
578115
+ };
578116
+ const timed = messages2.filter((m2) => m2.spanMeta != null && typeof m2.spanMeta.timestamp === "number" && !Number.isNaN(m2.spanMeta.timestamp));
578117
+ if (timed.length === 0) {
578118
+ return {
578119
+ stalenessLoad: 0,
578120
+ staleSpanIds: [],
578121
+ detail: "No messages with spanMeta.timestamp; staleness undefined."
578122
+ };
578123
+ }
578124
+ let minTs = Infinity;
578125
+ let maxTs = -Infinity;
578126
+ for (const m2 of timed) {
578127
+ if (m2.spanMeta.timestamp < minTs)
578128
+ minTs = m2.spanMeta.timestamp;
578129
+ if (m2.spanMeta.timestamp > maxTs)
578130
+ maxTs = m2.spanMeta.timestamp;
578131
+ }
578132
+ const now2 = Date.now();
578133
+ const refMax = Math.max(now2, maxTs);
578134
+ const totalSpan = refMax - minTs;
578135
+ if (totalSpan === 0 || currentTurn <= 1) {
578136
+ return {
578137
+ stalenessLoad: 0,
578138
+ staleSpanIds: [],
578139
+ detail: totalSpan === 0 ? "All timed messages share the same timestamp; cannot determine age." : "currentTurn <= 1; no staleness on first turn."
578140
+ };
578141
+ }
578142
+ let totalTokens = 0;
578143
+ let staleTokens = 0;
578144
+ const staleSpanIds = [];
578145
+ const detailParts = [];
578146
+ for (const m2 of timed) {
578147
+ const { span_id, token_count, timestamp, provenance } = m2.spanMeta;
578148
+ const tok = typeof token_count === "number" && !Number.isNaN(token_count) ? token_count : 0;
578149
+ totalTokens += tok;
578150
+ const pos = (timestamp - minTs) / totalSpan;
578151
+ const estimatedTurn = 1 + pos * (currentTurn - 1);
578152
+ const turnAge = currentTurn - estimatedTurn;
578153
+ const type = classifyProvenance(provenance);
578154
+ if (!type) {
578155
+ continue;
578156
+ }
578157
+ const threshold = th[type];
578158
+ if (turnAge > threshold) {
578159
+ staleTokens += tok;
578160
+ staleSpanIds.push(span_id);
578161
+ detailParts.push(`${type}#${span_id.slice(0, 8)} age=${turnAge.toFixed(2)} > ${threshold}`);
578162
+ }
578163
+ }
578164
+ const stalenessLoad = totalTokens > 0 ? staleTokens / totalTokens : 0;
578165
+ const detail = detailParts.length > 0 ? detailParts.join("; ") : "No stale spans detected.";
578166
+ return { stalenessLoad, staleSpanIds, detail };
578167
+ }
578168
+ var STALENESS_THRESHOLD_DEFAULTS;
578169
+ var init_staleness = __esm({
578170
+ "packages/orchestrator/dist/staleness.js"() {
578171
+ "use strict";
578172
+ STALENESS_THRESHOLD_DEFAULTS = {
578173
+ file_read: 20,
578174
+ shell: 12,
578175
+ sub_agent: 30
578176
+ };
578177
+ }
578178
+ });
578179
+
578180
+ // packages/orchestrator/dist/redundancy.js
578181
+ function computeRedundancyLoad(messages2) {
578182
+ const groups = /* @__PURE__ */ new Map();
578183
+ let totalTokens = 0;
578184
+ for (const msg of messages2) {
578185
+ if (!msg.spanMeta?.content_hash) {
578186
+ continue;
578187
+ }
578188
+ const { content_hash, span_id, token_count } = msg.spanMeta;
578189
+ totalTokens += token_count;
578190
+ if (!groups.has(content_hash)) {
578191
+ groups.set(content_hash, { spanIds: [], tokens: [] });
578192
+ }
578193
+ const g = groups.get(content_hash);
578194
+ g.spanIds.push(span_id);
578195
+ g.tokens.push(token_count);
578196
+ }
578197
+ let duplicateTokens = 0;
578198
+ const duplicateGroups = [];
578199
+ for (const [, g] of groups) {
578200
+ if (g.spanIds.length < 2)
578201
+ continue;
578202
+ const primary = g.spanIds[0];
578203
+ const duplicates = g.spanIds.slice(1);
578204
+ const tok = g.tokens.slice(1).reduce((a2, b) => a2 + b, 0);
578205
+ duplicateTokens += tok;
578206
+ duplicateGroups.push({
578207
+ primary,
578208
+ duplicates,
578209
+ tokenCount: tok
578210
+ });
578211
+ }
578212
+ const redundancyLoad = totalTokens > 0 ? duplicateTokens / totalTokens : 0;
578213
+ const dupCount = duplicateGroups.length;
578214
+ const dupMsgCount = duplicateGroups.reduce((s2, g) => s2 + g.duplicates.length, 0);
578215
+ const detail = `Redundancy load: ${(redundancyLoad * 100).toFixed(1)}% (${duplicateTokens} duplicate tokens out of ${totalTokens} total). Found ${dupCount} duplicate group(s) spanning ${dupMsgCount} redundant message(s).`;
578216
+ return { redundancyLoad, duplicateGroups, detail };
578217
+ }
578218
+ var init_redundancy = __esm({
578219
+ "packages/orchestrator/dist/redundancy.js"() {
578220
+ "use strict";
578221
+ }
578222
+ });
578223
+
578224
+ // packages/orchestrator/dist/contradiction.js
578225
+ function textFromMessage(msg) {
578226
+ if (typeof msg.content === "string")
578227
+ return msg.content;
578228
+ if (!Array.isArray(msg.content))
578229
+ return "";
578230
+ let out = "";
578231
+ for (const part of msg.content) {
578232
+ if (part.type === "text" && part.text)
578233
+ out += part.text + "\n";
578234
+ }
578235
+ return out.trimEnd();
578236
+ }
578237
+ function computeContradictionLoad(messages2, spanMetaArray) {
578238
+ const limit = Math.min(messages2.length, spanMetaArray.length);
578239
+ const grouped = /* @__PURE__ */ new Map();
578240
+ for (let i2 = 0; i2 < limit; i2++) {
578241
+ const meta = spanMetaArray[i2];
578242
+ const key = meta.content_hash.slice(0, 16);
578243
+ const entry = {
578244
+ span_id: meta.span_id,
578245
+ token_count: meta.token_count,
578246
+ text: textFromMessage(messages2[i2])
578247
+ };
578248
+ const g = grouped.get(key);
578249
+ if (g)
578250
+ g.push(entry);
578251
+ else
578252
+ grouped.set(key, [entry]);
578253
+ }
578254
+ const contradictoryPairs = [];
578255
+ let contradictoryTokens = 0;
578256
+ let totalTokens = 0;
578257
+ for (const entries of grouped.values()) {
578258
+ const groupTokens = entries.reduce((s2, e2) => s2 + e2.token_count, 0);
578259
+ totalTokens += groupTokens;
578260
+ if (entries.length < 2)
578261
+ continue;
578262
+ const firstText = entries[0].text;
578263
+ const hasContradiction = entries.some((e2) => e2.text !== firstText);
578264
+ if (hasContradiction) {
578265
+ contradictoryTokens += groupTokens;
578266
+ for (let i2 = 0; i2 < entries.length; i2++) {
578267
+ for (let j = i2 + 1; j < entries.length; j++) {
578268
+ contradictoryPairs.push([entries[i2].span_id, entries[j].span_id]);
578269
+ }
578270
+ }
578271
+ }
578272
+ }
578273
+ const contradictionLoad = totalTokens > 0 ? contradictoryTokens / totalTokens : 0;
578274
+ const detail = `Identified ${contradictoryPairs.length} contradictory span pair(s) across ${grouped.size} content-hash group(s); contradiction load ${(contradictionLoad * 100).toFixed(2)}% (${contradictoryTokens}/${totalTokens} tokens)`;
578275
+ return { contradictionLoad, contradictoryPairs, detail };
578276
+ }
578277
+ var init_contradiction = __esm({
578278
+ "packages/orchestrator/dist/contradiction.js"() {
578279
+ "use strict";
578280
+ }
578281
+ });
578282
+
578283
+ // packages/orchestrator/dist/adaptivePolicy.js
578284
+ var DEFAULT_ADAPTIVE_POLICY_CONFIG, AdaptiveCompactionPolicy;
578285
+ var init_adaptivePolicy = __esm({
578286
+ "packages/orchestrator/dist/adaptivePolicy.js"() {
578287
+ "use strict";
578288
+ DEFAULT_ADAPTIVE_POLICY_CONFIG = {
578289
+ windowSize: 5,
578290
+ minSnrDb: 10,
578291
+ maxAggression: 0.9,
578292
+ minAggression: 0.2,
578293
+ learningRate: 0.15,
578294
+ defaultAggression: 0.5
578295
+ };
578296
+ AdaptiveCompactionPolicy = class {
578297
+ config;
578298
+ _snrHistory = [];
578299
+ _currentAggression;
578300
+ constructor(config) {
578301
+ this.config = { ...DEFAULT_ADAPTIVE_POLICY_CONFIG, ...config };
578302
+ this._currentAggression = this.config.defaultAggression;
578303
+ }
578304
+ get currentAggression() {
578305
+ return this._currentAggression;
578306
+ }
578307
+ get snrHistory() {
578308
+ return this._snrHistory;
578309
+ }
578310
+ /**
578311
+ * Feed a new SNR measurement and compute the adjusted aggression.
578312
+ * Returns the new aggression value.
578313
+ */
578314
+ adjust(snrDb) {
578315
+ this._snrHistory.push(snrDb);
578316
+ if (this._snrHistory.length > this.config.windowSize) {
578317
+ this._snrHistory.shift();
578318
+ }
578319
+ const meanSnr = this._snrHistory.reduce((a2, b) => a2 + b, 0) / this._snrHistory.length;
578320
+ let targetAggression;
578321
+ if (meanSnr < this.config.minSnrDb) {
578322
+ const deficit = this.config.minSnrDb - meanSnr;
578323
+ const ratio = Math.min(1, deficit / this.config.minSnrDb);
578324
+ targetAggression = this.config.defaultAggression + ratio * (this.config.maxAggression - this.config.defaultAggression);
578325
+ } else {
578326
+ const surplus = meanSnr - this.config.minSnrDb;
578327
+ const ratio = Math.min(1, surplus / 20);
578328
+ targetAggression = this.config.defaultAggression - ratio * (this.config.defaultAggression - this.config.minAggression);
578329
+ }
578330
+ targetAggression = Math.max(this.config.minAggression, Math.min(this.config.maxAggression, targetAggression));
578331
+ this._currentAggression = this._currentAggression + (targetAggression - this._currentAggression) * this.config.learningRate;
578332
+ return Math.round(this._currentAggression * 100) / 100;
578333
+ }
578334
+ /** Reset to default state. */
578335
+ reset() {
578336
+ this._snrHistory = [];
578337
+ this._currentAggression = this.config.defaultAggression;
578338
+ }
578339
+ };
578340
+ }
578341
+ });
578342
+
578343
+ // packages/orchestrator/dist/domainDetector.js
578344
+ function detectDomain(messages2, maxScanMessages = 20) {
578345
+ const scanMessages = messages2.slice(-maxScanMessages);
578346
+ const text2 = scanMessages.map((m2) => typeof m2.content === "string" ? m2.content : "").join("\n");
578347
+ if (!text2)
578348
+ return "general";
578349
+ const scores = DOMAIN_CONFIGS.map((cfg) => {
578350
+ if (cfg.signals.length === 0)
578351
+ return { domain: cfg.domain, score: 0 };
578352
+ let score = 0;
578353
+ for (const signal of cfg.signals) {
578354
+ const matches = text2.match(signal);
578355
+ if (matches)
578356
+ score += matches.length;
578357
+ }
578358
+ score = score / Math.max(1, text2.length) * 1e3;
578359
+ return { domain: cfg.domain, score };
578360
+ });
578361
+ scores.sort((a2, b) => b.score - a2.score);
578362
+ return scores[0].score > 0 ? scores[0].domain : "general";
578363
+ }
578364
+ function getDomainConfig(domain) {
578365
+ return DOMAIN_CONFIGS.find((c9) => c9.domain === domain) ?? DOMAIN_CONFIGS[6];
578366
+ }
578367
+ function getDomainCompactionThreshold(domain) {
578368
+ return getDomainConfig(domain).maxMessagesBeforeCompaction;
578369
+ }
578370
+ function getDomainProfile(domain) {
578371
+ const cfg = getDomainConfig(domain);
578372
+ return {
578373
+ compactAboveMessages: cfg.maxMessagesBeforeCompaction,
578374
+ keepRecentMultiplier: 1 - cfg.compactionAggression
578375
+ };
578376
+ }
578377
+ var DOMAIN_CONFIGS;
578378
+ var init_domainDetector = __esm({
578379
+ "packages/orchestrator/dist/domainDetector.js"() {
578380
+ "use strict";
578381
+ DOMAIN_CONFIGS = [
578382
+ {
578383
+ domain: "coding",
578384
+ label: "Coding / Software Engineering",
578385
+ compactionAggression: 0.5,
578386
+ maxMessagesBeforeCompaction: 35,
578387
+ signals: [
578388
+ /\b(function|class|import|export|const|let|var|async|await|interface|type|extends|implements)\b/i,
578389
+ /\b(debug|compile|build|test|lint|typecheck|deploy|refactor)\b/i,
578390
+ /\.(ts|js|tsx|jsx|py|rs|go|java|cpp|c|h|rb|php|swift|kt)$/
578391
+ ]
578392
+ },
578393
+ {
578394
+ domain: "research",
578395
+ label: "Research / Analysis",
578396
+ compactionAggression: 0.3,
578397
+ maxMessagesBeforeCompaction: 50,
578398
+ signals: [
578399
+ /\b(paper|research|study|analysis|survey|literature|reference|citation|bibliography)\b/i,
578400
+ /\b(hypothesis|methodology|findings|results|conclusion|evidence)\b/i,
578401
+ /\.(pdf|bib|doi|arxiv)\b/i
578402
+ ]
578403
+ },
578404
+ {
578405
+ domain: "writing",
578406
+ label: "Writing / Documentation",
578407
+ compactionAggression: 0.4,
578408
+ maxMessagesBeforeCompaction: 40,
578409
+ signals: [
578410
+ /\b(essay|article|blog|documentation|doc|readme|manual|guide|tutorial)\b/i,
578411
+ /\b(write|draft|edit|proofread|revise|rewrite|compose)\b/i,
578412
+ /\b(paragraph|section|chapter|appendix|glossary)\b/i
578413
+ ]
578414
+ },
578415
+ {
578416
+ domain: "devops",
578417
+ label: "DevOps / Infrastructure",
578418
+ compactionAggression: 0.7,
578419
+ maxMessagesBeforeCompaction: 25,
578420
+ signals: [
578421
+ /\b(kubernetes|k8s|docker|terraform|ansible|helm|deployment|infrastructure)\b/i,
578422
+ /\b(ci|cd|pipeline|deploy|rollback|monitoring|alert|scaling)\b/i,
578423
+ /\.(yaml|yml|toml|dockerfile|tf|hcl)/i
578424
+ ]
578425
+ },
578426
+ {
578427
+ domain: "data_science",
578428
+ label: "Data Science / ML",
578429
+ compactionAggression: 0.4,
578430
+ maxMessagesBeforeCompaction: 45,
578431
+ signals: [
578432
+ /\b(dataset|model|training|inference|accuracy|precision|recall|f1|loss|epoch)\b/i,
578433
+ /\b(regression|classification|clustering|nlp|cv|neural|deep learning|transformer)\b/i,
578434
+ /\.(csv|json|parquet|npy|pkl|h5|pt)$/
578435
+ ]
578436
+ },
578437
+ {
578438
+ domain: "creative",
578439
+ label: "Creative / Design",
578440
+ compactionAggression: 0.6,
578441
+ maxMessagesBeforeCompaction: 30,
578442
+ signals: [
578443
+ /\b(design|ui|ux|wireframe|mockup|prototype|figma|sketch|photoshop)\b/i,
578444
+ /\b(creative|art|illustration|animation|story|character|worldbuilding)\b/i,
578445
+ /\.(png|jpg|svg|psd|ai|blend|ma)$/
578446
+ ]
578447
+ },
578448
+ {
578449
+ domain: "general",
578450
+ label: "General",
578451
+ compactionAggression: 0.5,
578452
+ maxMessagesBeforeCompaction: 35,
578453
+ signals: []
578454
+ }
578455
+ ];
578456
+ }
578457
+ });
578458
+
577403
578459
  // packages/orchestrator/dist/longhaul-integration.js
577404
578460
  import fs6 from "node:fs";
577405
578461
  import path7 from "node:path";
@@ -577456,6 +578512,13 @@ var init_longhaul_integration = __esm({
577456
578512
  init_dist5();
577457
578513
  init_dist();
577458
578514
  init_dist();
578515
+ init_contextSNR();
578516
+ init_groundedness();
578517
+ init_staleness();
578518
+ init_redundancy();
578519
+ init_contradiction();
578520
+ init_adaptivePolicy();
578521
+ init_domainDetector();
577459
578522
  JsonConvergenceStore = class {
577460
578523
  file;
577461
578524
  cache = /* @__PURE__ */ new Map();
@@ -577514,6 +578577,16 @@ var init_longhaul_integration = __esm({
577514
578577
  lockedSource = /* @__PURE__ */ new Map();
577515
578578
  /** Persisted contract output path (relative to stateDir). */
577516
578579
  lockedContractPath;
578580
+ // ── SNR telemetry state ────────────────────────────────────────────────
578581
+ _snrTelemetry = [];
578582
+ _adaptivePolicy;
578583
+ _groundednessHistory = [];
578584
+ _causalAblationConfig = {
578585
+ enabled: false,
578586
+ dimensions: ["contradiction", "redundancy", "staleness"],
578587
+ bootstrapResamples: 100,
578588
+ maxAblationTurns: 5
578589
+ };
577517
578590
  constructor(options2) {
577518
578591
  this.lockedContractPath = path7.join(options2.stateDir, LOCKED_CONTRACT_FILE);
577519
578592
  this.convergenceBreaker = new ConvergenceBreaker({
@@ -577529,6 +578602,7 @@ var init_longhaul_integration = __esm({
577529
578602
  regenThreshold: options2.coherenceRegenThreshold
577530
578603
  });
577531
578604
  this.contextFolder = new ContextFolder();
578605
+ this._adaptivePolicy = new AdaptiveCompactionPolicy();
577532
578606
  }
577533
578607
  /**
577534
578608
  * WO-8: record an edit tool outcome and return a rewrite recommendation when
@@ -577812,14 +578886,259 @@ The sub-agent works in its own small context; when it folds back, run the build
577812
578886
  /** Telemetry snapshot for the context-window dump. */
577813
578887
  telemetry() {
577814
578888
  try {
578889
+ const lastSnr = this._snrTelemetry.length > 0 ? this._snrTelemetry[this._snrTelemetry.length - 1] : null;
577815
578890
  return {
577816
578891
  convergence: this.convergenceBreaker.snapshot(),
577817
- foldedSegments: this.contextFolder.foldedSegments().length
578892
+ foldedSegments: this.contextFolder.foldedSegments().length,
578893
+ snr: lastSnr ? {
578894
+ snrDb: lastSnr.snrDb,
578895
+ combinedNoiseRatio: lastSnr.combinedNoiseRatio,
578896
+ contradictionLoad: lastSnr.contradictionLoad,
578897
+ redundancyLoad: lastSnr.redundancyLoad,
578898
+ stalenessLoad: lastSnr.stalenessLoad
578899
+ } : void 0,
578900
+ adaptiveAggression: this._adaptivePolicy.currentAggression,
578901
+ groundednessHistoryLength: this._groundednessHistory.length,
578902
+ snrTelemetryLength: this._snrTelemetry.length
577818
578903
  };
577819
578904
  } catch {
577820
578905
  return {};
577821
578906
  }
577822
578907
  }
578908
+ // ── SNR Phase B: Groundedness ──────────────────────────────────────────
578909
+ /**
578910
+ * Compute per-turn groundedness for an assistant response.
578911
+ * Stores the result in an internal history and returns the report.
578912
+ */
578913
+ computeGroundedness(responseText, messages2, turn) {
578914
+ try {
578915
+ const contextSpans = extractContextSpansForGroundedness(messages2);
578916
+ const report2 = computeGroundedness(responseText, contextSpans, turn);
578917
+ this._groundednessHistory.push(report2);
578918
+ return report2;
578919
+ } catch {
578920
+ return {
578921
+ turn,
578922
+ total_claims: 0,
578923
+ supported_claims: 0,
578924
+ unsupported_claims: [],
578925
+ supporting_spans: [],
578926
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
578927
+ };
578928
+ }
578929
+ }
578930
+ /** Get the full groundedness history. */
578931
+ get groundednessHistory() {
578932
+ return this._groundednessHistory;
578933
+ }
578934
+ /** Mean groundedness ratio across all recorded turns. */
578935
+ get meanGroundednessRatio() {
578936
+ if (this._groundednessHistory.length === 0)
578937
+ return 0;
578938
+ const ratios = this._groundednessHistory.map((r2) => r2.total_claims > 0 ? r2.supported_claims / r2.total_claims : 1);
578939
+ return ratios.reduce((a2, b) => a2 + b, 0) / ratios.length;
578940
+ }
578941
+ // ── SNR Phase C: Load Metrics ──────────────────────────────────────────
578942
+ /**
578943
+ * Compute contradiction load from messages with spanMeta.
578944
+ */
578945
+ computeContradictionLoad(messages2) {
578946
+ try {
578947
+ const metaArr = messages2.filter((m2) => m2.spanMeta != null).map((m2) => ({
578948
+ span_id: m2.spanMeta.span_id,
578949
+ content_hash: m2.spanMeta.content_hash,
578950
+ token_count: m2.spanMeta.token_count,
578951
+ provenance: m2.spanMeta.provenance,
578952
+ timestamp: m2.spanMeta.timestamp
578953
+ }));
578954
+ return computeContradictionLoad(messages2, metaArr);
578955
+ } catch {
578956
+ return {
578957
+ contradictionLoad: 0,
578958
+ contradictoryPairs: [],
578959
+ detail: "contradiction computation skipped"
578960
+ };
578961
+ }
578962
+ }
578963
+ /**
578964
+ * Compute redundancy load from messages with spanMeta.
578965
+ */
578966
+ computeRedundancyLoad(messages2) {
578967
+ try {
578968
+ return computeRedundancyLoad(messages2);
578969
+ } catch {
578970
+ return {
578971
+ redundancyLoad: 0,
578972
+ duplicateGroups: [],
578973
+ detail: "redundancy computation skipped"
578974
+ };
578975
+ }
578976
+ }
578977
+ /**
578978
+ * Compute staleness load from messages with spanMeta.
578979
+ */
578980
+ computeStalenessLoad(messages2, currentTurn) {
578981
+ try {
578982
+ return computeStalenessLoad(messages2, currentTurn);
578983
+ } catch {
578984
+ return {
578985
+ stalenessLoad: 0,
578986
+ staleSpanIds: [],
578987
+ detail: "staleness computation skipped"
578988
+ };
578989
+ }
578990
+ }
578991
+ // ── SNR Phase A+C Composite: Unified SNR Report ────────────────────────
578992
+ /**
578993
+ * Compute a composite ContextQualityReport by gathering all signal/noise
578994
+ * dimensions into one pipeline call. This is the primary integration point
578995
+ * for per-turn SNR assessment.
578996
+ */
578997
+ computeContextSNR(input) {
578998
+ try {
578999
+ return computeContextSNR(input);
579000
+ } catch {
579001
+ return {
579002
+ overall: { ratio: 0, snrDb: -Infinity },
579003
+ dimensions: {
579004
+ noiseMarkers: {
579005
+ label: "noise-markers",
579006
+ signalChars: 0,
579007
+ noiseChars: 0,
579008
+ ratio: 0
579009
+ },
579010
+ rawDiscovery: {
579011
+ label: "raw-discovery",
579012
+ signalChars: 0,
579013
+ noiseChars: 0,
579014
+ ratio: 0
579015
+ }
579016
+ },
579017
+ capacityWarning: false
579018
+ };
579019
+ }
579020
+ }
579021
+ // ── SNR Phase F: Per-Session Telemetry ─────────────────────────────────
579022
+ /**
579023
+ * Record a LoadMetricsReport for the current turn. Stores in internal
579024
+ * telemetry array for final aggregation.
579025
+ */
579026
+ recordSnrTelemetry(report2) {
579027
+ this._snrTelemetry.push(report2);
579028
+ try {
579029
+ this._adaptivePolicy.adjust(report2.snrDb);
579030
+ } catch {
579031
+ }
579032
+ }
579033
+ /** Access the raw SNR telemetry array. */
579034
+ get snrTelemetry() {
579035
+ return this._snrTelemetry;
579036
+ }
579037
+ /**
579038
+ * Build a LoadMetricsReport for one turn from raw measurements.
579039
+ * This is a convenience builder so callers don't construct the type manually.
579040
+ */
579041
+ buildLoadMetricsReport(input) {
579042
+ const combined = Math.min(1, input.contradictionLoad + input.redundancyLoad + input.stalenessLoad + (input.browserNoiseLoad ?? 0));
579043
+ const signalTokens = Math.round(input.totalTokens * (1 - combined));
579044
+ const noiseTokens = input.totalTokens - signalTokens;
579045
+ const snrDb = noiseTokens > 0 ? Number((10 * Math.log10(signalTokens / noiseTokens)).toFixed(2)) : Infinity;
579046
+ return {
579047
+ turn: input.turn,
579048
+ contradictionLoad: input.contradictionLoad,
579049
+ redundancyLoad: input.redundancyLoad,
579050
+ stalenessLoad: input.stalenessLoad,
579051
+ combinedNoiseRatio: combined,
579052
+ snrDb,
579053
+ estimatedSignalTokens: signalTokens,
579054
+ estimatedNoiseTokens: noiseTokens,
579055
+ totalTokens: input.totalTokens,
579056
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
579057
+ };
579058
+ }
579059
+ /**
579060
+ * Final aggregated SNR report for the entire session.
579061
+ * Call on agent shutdown to get mean/variance across all turns.
579062
+ */
579063
+ finalizeSNRReport() {
579064
+ if (this._snrTelemetry.length === 0) {
579065
+ return {
579066
+ turnCount: 0,
579067
+ meanSnrDb: 0,
579068
+ meanGroundednessRatio: this.meanGroundednessRatio,
579069
+ meanCombinedNoiseRatio: 0,
579070
+ adaptivePolicyAggression: this._adaptivePolicy.currentAggression,
579071
+ breakdown: {
579072
+ meanContradiction: 0,
579073
+ meanRedundancy: 0,
579074
+ meanStaleness: 0
579075
+ }
579076
+ };
579077
+ }
579078
+ const n2 = this._snrTelemetry.length;
579079
+ const sumSnr = this._snrTelemetry.reduce((s2, r2) => s2 + r2.snrDb, 0);
579080
+ const sumNoise = this._snrTelemetry.reduce((s2, r2) => s2 + r2.combinedNoiseRatio, 0);
579081
+ const sumContra = this._snrTelemetry.reduce((s2, r2) => s2 + r2.contradictionLoad, 0);
579082
+ const sumRedun = this._snrTelemetry.reduce((s2, r2) => s2 + r2.redundancyLoad, 0);
579083
+ const sumStale = this._snrTelemetry.reduce((s2, r2) => s2 + r2.stalenessLoad, 0);
579084
+ return {
579085
+ turnCount: n2,
579086
+ meanSnrDb: Math.round(sumSnr / n2 * 100) / 100,
579087
+ meanGroundednessRatio: this.meanGroundednessRatio,
579088
+ meanCombinedNoiseRatio: Math.round(sumNoise / n2 * 100) / 100,
579089
+ adaptivePolicyAggression: this._adaptivePolicy.currentAggression,
579090
+ breakdown: {
579091
+ meanContradiction: Math.round(sumContra / n2 * 100) / 100,
579092
+ meanRedundancy: Math.round(sumRedun / n2 * 100) / 100,
579093
+ meanStaleness: Math.round(sumStale / n2 * 100) / 100
579094
+ }
579095
+ };
579096
+ }
579097
+ // ── SNR Phase G+H: Domain Detection + Adaptive Policy ──────────────────
579098
+ /**
579099
+ * Detect the domain of the current conversation from message content.
579100
+ */
579101
+ detectDomain(messages2, maxScanMessages) {
579102
+ try {
579103
+ return detectDomain(messages2, maxScanMessages);
579104
+ } catch {
579105
+ return "general";
579106
+ }
579107
+ }
579108
+ /**
579109
+ * Get the compaction profile for a detected domain.
579110
+ */
579111
+ domainCompactionProfile(domain) {
579112
+ try {
579113
+ return getDomainProfile(domain);
579114
+ } catch {
579115
+ return { compactAboveMessages: 35, keepRecentMultiplier: 0.5 };
579116
+ }
579117
+ }
579118
+ /**
579119
+ * Access the adaptive compaction policy (SNR-driven aggression).
579120
+ */
579121
+ get adaptivePolicy() {
579122
+ return this._adaptivePolicy;
579123
+ }
579124
+ /**
579125
+ * Configure causal ablation. Off by default.
579126
+ */
579127
+ setCausalAblationConfig(config) {
579128
+ this._causalAblationConfig = { ...this._causalAblationConfig, ...config };
579129
+ }
579130
+ /** Get the current causal ablation config. */
579131
+ get causalAblationConfig() {
579132
+ return this._causalAblationConfig;
579133
+ }
579134
+ /**
579135
+ * Reset all SNR telemetry state (for fresh runs).
579136
+ */
579137
+ resetSnrState() {
579138
+ this._snrTelemetry = [];
579139
+ this._groundednessHistory = [];
579140
+ this._adaptivePolicy.reset();
579141
+ }
577823
579142
  };
577824
579143
  FIELD_STOPWORDS = /^(struct|class|public|private|protected|const|unsigned|signed|static|typedef|enum|union|namespace|template|int|char|float|double|void|bool|long|short|size_t|uint\d+_t|int\d+_t|string|number|boolean|readonly)$/;
577825
579144
  }
@@ -607647,6 +608966,126 @@ var init_conversational_scrutiny = __esm({
607647
608966
  }
607648
608967
  });
607649
608968
 
608969
+ // packages/orchestrator/dist/causalAblation.js
608970
+ function _identifyAblationTargets(messages2, dimension) {
608971
+ const targets = [];
608972
+ for (let i2 = 0; i2 < messages2.length; i2++) {
608973
+ const m2 = messages2[i2];
608974
+ if (!m2.spanMeta)
608975
+ continue;
608976
+ switch (dimension) {
608977
+ case "contradiction": {
608978
+ const sameHash = messages2.filter((o2) => o2.spanMeta && o2.spanMeta.content_hash === m2.spanMeta.content_hash && o2.spanMeta.span_id !== m2.spanMeta.span_id);
608979
+ if (sameHash.length > 0)
608980
+ targets.push(i2);
608981
+ break;
608982
+ }
608983
+ case "redundancy": {
608984
+ const firstIdx = messages2.findIndex((o2) => o2.spanMeta && o2.spanMeta.content_hash === m2.spanMeta.content_hash);
608985
+ if (firstIdx >= 0 && firstIdx !== i2)
608986
+ targets.push(i2);
608987
+ break;
608988
+ }
608989
+ case "staleness": {
608990
+ if (m2.spanMeta.provenance === "compressed")
608991
+ targets.push(i2);
608992
+ break;
608993
+ }
608994
+ case "groundedness": {
608995
+ if (m2.role === "assistant") {
608996
+ const hasToolResults = messages2.some((o2) => o2.spanMeta && o2.spanMeta.provenance?.startsWith("file_read"));
608997
+ if (!hasToolResults)
608998
+ targets.push(i2);
608999
+ }
609000
+ break;
609001
+ }
609002
+ }
609003
+ }
609004
+ return [...new Set(targets)];
609005
+ }
609006
+ function ablateContext(messages2, dimension) {
609007
+ const targets = new Set(_identifyAblationTargets(messages2, dimension));
609008
+ return messages2.filter((_, i2) => !targets.has(i2));
609009
+ }
609010
+ async function measureContextSNR(messages2, config, comparator = defaultComparator) {
609011
+ const measurements = [];
609012
+ const fullScore = await comparator(messages2);
609013
+ const totalTokens = messages2.reduce((s2, m2) => s2 + (m2.spanMeta?.token_count ?? 0), 0);
609014
+ for (const dimension of config.dimensions) {
609015
+ const ablated = ablateContext(messages2, dimension);
609016
+ if (ablated.length === messages2.length) {
609017
+ measurements.push({
609018
+ span_id: `causal:${dimension}`,
609019
+ category: dimension,
609020
+ causal_signal: fullScore,
609021
+ causal_noise: fullScore,
609022
+ causal_snr_db: 0,
609023
+ confidenceInterval95: null
609024
+ });
609025
+ continue;
609026
+ }
609027
+ const ablatedScore = await comparator(ablated);
609028
+ const noise2 = Math.max(ablatedScore, 1e-3);
609029
+ const snrDb = fullScore > 0 ? 10 * Math.log10(fullScore / noise2) : 0;
609030
+ let ci = null;
609031
+ if (config.bootstrapResamples > 0 && totalTokens > 0) {
609032
+ ci = _bootstrapCI(messages2, dimension, comparator, config.bootstrapResamples);
609033
+ }
609034
+ measurements.push({
609035
+ span_id: `causal:${dimension}`,
609036
+ category: dimension,
609037
+ causal_signal: fullScore,
609038
+ causal_noise: ablatedScore,
609039
+ causal_snr_db: Math.round(snrDb * 100) / 100,
609040
+ confidenceInterval95: ci
609041
+ });
609042
+ }
609043
+ return measurements;
609044
+ }
609045
+ function _bootstrapCI(messages2, dimension, comparator, resamples) {
609046
+ const snrSamples = [];
609047
+ const baseAblated = ablateContext(messages2, dimension);
609048
+ if (baseAblated.length >= messages2.length)
609049
+ return null;
609050
+ const fullScore = comparator(messages2);
609051
+ if (typeof fullScore !== "number")
609052
+ return null;
609053
+ for (let r2 = 0; r2 < resamples; r2++) {
609054
+ const sample = [];
609055
+ for (let i2 = 0; i2 < messages2.length; i2++) {
609056
+ const idx = Math.floor(Math.random() * messages2.length);
609057
+ sample.push(messages2[idx]);
609058
+ }
609059
+ const ablated = ablateContext(sample, dimension);
609060
+ if (ablated.length === sample.length)
609061
+ continue;
609062
+ const ablatedScore = comparator(ablated);
609063
+ if (typeof ablatedScore !== "number")
609064
+ continue;
609065
+ const snr = fullScore > 0 ? 10 * Math.log10(fullScore / Math.max(ablatedScore, 1e-3)) : 0;
609066
+ snrSamples.push(snr);
609067
+ }
609068
+ if (snrSamples.length < 30)
609069
+ return null;
609070
+ snrSamples.sort((a2, b) => a2 - b);
609071
+ const lower = snrSamples[Math.floor(0.025 * snrSamples.length)];
609072
+ const upper = snrSamples[Math.floor(0.975 * snrSamples.length)];
609073
+ return [Math.round(lower * 100) / 100, Math.round(upper * 100) / 100];
609074
+ }
609075
+ var defaultComparator, defaultCausalAblationConfig;
609076
+ var init_causalAblation = __esm({
609077
+ "packages/orchestrator/dist/causalAblation.js"() {
609078
+ "use strict";
609079
+ defaultComparator = () => 0.5;
609080
+ defaultCausalAblationConfig = {
609081
+ enabled: false,
609082
+ dimensions: ["contradiction", "redundancy", "staleness"],
609083
+ bootstrapResamples: 100,
609084
+ maxAblationTurns: 5
609085
+ };
609086
+ }
609087
+ });
609088
+
607650
609089
  // packages/orchestrator/dist/subagent-prompt.js
607651
609090
  function genericPurpose(type) {
607652
609091
  return {
@@ -607799,6 +609238,7 @@ var init_subagent_prompt = __esm({
607799
609238
  var dist_exports3 = {};
607800
609239
  __export(dist_exports3, {
607801
609240
  AGENT_DISALLOWED_TOOLS: () => AGENT_DISALLOWED_TOOLS,
609241
+ AdaptiveCompactionPolicy: () => AdaptiveCompactionPolicy,
607802
609242
  AgentDeploymentPatternRegistry: () => AgentDeploymentPatternRegistry,
607803
609243
  AgentLoop: () => AgentLoop,
607804
609244
  AgentTaskManager: () => AgentTaskManager,
@@ -607817,6 +609257,7 @@ __export(dist_exports3, {
607817
609257
  ConvergenceBreaker: () => ConvergenceBreaker,
607818
609258
  CoordinatorManager: () => CoordinatorManager,
607819
609259
  CostTracker: () => CostTracker,
609260
+ DEFAULT_ADAPTIVE_POLICY_CONFIG: () => DEFAULT_ADAPTIVE_POLICY_CONFIG,
607820
609261
  DEFAULT_COORDINATOR_CONFIG: () => DEFAULT_COORDINATOR_CONFIG,
607821
609262
  DEFAULT_PLAN_MODE_CONFIG: () => DEFAULT_PLAN_MODE_CONFIG,
607822
609263
  DefaultContextEngine: () => DefaultContextEngine,
@@ -607846,12 +609287,14 @@ __export(dist_exports3, {
607846
609287
  READ_ONLY_TOOLS: () => READ_ONLY_TOOLS,
607847
609288
  RalphLoop: () => RalphLoop,
607848
609289
  RetryController: () => RetryController,
609290
+ STALENESS_THRESHOLD_DEFAULTS: () => STALENESS_THRESHOLD_DEFAULTS,
607849
609291
  ScoutRunner: () => ScoutRunner,
607850
609292
  SessionMetrics: () => SessionMetrics,
607851
609293
  StreamingToolExecutor: () => StreamingToolExecutor,
607852
609294
  TaskNormalizer: () => TaskNormalizer,
607853
609295
  VerifierRunner: () => VerifierRunner,
607854
609296
  WorkEvaluator: () => WorkEvaluator,
609297
+ ablateContext: () => ablateContext,
607855
609298
  addCompletionClaims: () => addCompletionClaims,
607856
609299
  addFeature: () => addFeature,
607857
609300
  analyzeContextWindowDumpRequest: () => analyzeContextWindowDumpRequest,
@@ -607896,7 +609339,13 @@ __export(dist_exports3, {
607896
609339
  completionEvidenceDirective: () => completionEvidenceDirective,
607897
609340
  compressFindings: () => compressFindings,
607898
609341
  computeArc: () => computeArc,
609342
+ computeContextSNR: () => computeContextSNR,
609343
+ computeContradictionLoad: () => computeContradictionLoad,
609344
+ computeDPrime: () => computeDPrime,
609345
+ computeGroundedness: () => computeGroundedness,
609346
+ computeRedundancyLoad: () => computeRedundancyLoad,
607899
609347
  computeStabilityHash: () => computeStabilityHash,
609348
+ computeStalenessLoad: () => computeStalenessLoad,
607900
609349
  computeTodoReminder: () => computeTodoReminder,
607901
609350
  confabulationDirective: () => confabulationDirective,
607902
609351
  contextWindowDumpDir: () => contextWindowDumpDir,
@@ -607914,10 +609363,13 @@ __export(dist_exports3, {
607914
609363
  debugArtifactRoot: () => debugArtifactRoot,
607915
609364
  decomposeSpec: () => decomposeSpec,
607916
609365
  decomposeToUnits: () => decomposeToUnits,
609366
+ defaultCausalAblationConfig: () => defaultCausalAblationConfig,
609367
+ defaultComparator: () => defaultComparator,
607917
609368
  defaultContextWindowDumpLocations: () => defaultContextWindowDumpLocations,
607918
609369
  deleteAgentTaskSidecar: () => deleteAgentTaskSidecar,
607919
609370
  deriveClaimsFromProposedText: () => deriveClaimsFromProposedText,
607920
609371
  deriveRegions: () => deriveRegions,
609372
+ detectDomain: () => detectDomain,
607921
609373
  detectExitCodeMisread: () => detectExitCodeMisread,
607922
609374
  detectExplorationIntent: () => detectExplorationIntent,
607923
609375
  detectPressure: () => detectPressure,
@@ -607930,7 +609382,9 @@ __export(dist_exports3, {
607930
609382
  executeBatch: () => executeBatch,
607931
609383
  executeHook: () => executeHook,
607932
609384
  expandContextReference: () => expandContextReference,
609385
+ extractClaims: () => extractClaims,
607933
609386
  extractConstraint: () => extractConstraint,
609387
+ extractContextSpansForGroundedness: () => extractContextSpansForGroundedness,
607934
609388
  extractLessons: () => extractLessons,
607935
609389
  extractMidTaskSteeringInput: () => extractMidTaskSteeringInput,
607936
609390
  extractPathFindings: () => extractPathFindings,
@@ -607956,6 +609410,9 @@ __export(dist_exports3, {
607956
609410
  getAllRubrics: () => getAllRubrics,
607957
609411
  getCommand: () => getCommand,
607958
609412
  getDefaultPricing: () => getDefaultPricing,
609413
+ getDomainCompactionThreshold: () => getDomainCompactionThreshold,
609414
+ getDomainConfig: () => getDomainConfig,
609415
+ getDomainProfile: () => getDomainProfile,
607959
609416
  getHardwareSnapshot: () => getHardwareSnapshot,
607960
609417
  getOllamaPool: () => getOllamaPool,
607961
609418
  getPlanModeConfig: () => getPlanModeConfig,
@@ -607989,7 +609446,9 @@ __export(dist_exports3, {
607989
609446
  loadCompletionLedger: () => loadCompletionLedger,
607990
609447
  loadMemoryWeightingConfig: () => loadMemoryWeightingConfig,
607991
609448
  loadStabilityIndex: () => loadStabilityIndex,
609449
+ mapClaimsToSpans: () => mapClaimsToSpans,
607992
609450
  materializeMemoryItems: () => materializeMemoryItems,
609451
+ measureContextSNR: () => measureContextSNR,
607993
609452
  memoryCosine: () => cosine4,
607994
609453
  mergeDigests: () => mergeDigests,
607995
609454
  normalizeCompletionKey: () => normalizeCompletionKey,
@@ -608072,6 +609531,7 @@ __export(dist_exports3, {
608072
609531
  stripYamlFrontmatter: () => stripYamlFrontmatter,
608073
609532
  subAgentPurpose: () => subAgentPurpose,
608074
609533
  tierForWeight: () => tierForWeight,
609534
+ toSnrDb: () => toSnrDb,
608075
609535
  truncateContent: () => truncateContent,
608076
609536
  updateAssertionResult: () => updateAssertionResult,
608077
609537
  updateMemoryStability: () => updateMemoryStability,
@@ -608159,6 +609619,14 @@ var init_dist8 = __esm({
608159
609619
  init_coherence_gate();
608160
609620
  init_spec_gate();
608161
609621
  init_longhaul_integration();
609622
+ init_contextSNR();
609623
+ init_groundedness();
609624
+ init_staleness();
609625
+ init_redundancy();
609626
+ init_contradiction();
609627
+ init_causalAblation();
609628
+ init_adaptivePolicy();
609629
+ init_domainDetector();
608162
609630
  init_decomposition_orchestrator();
608163
609631
  init_subagent_prompt();
608164
609632
  }
@@ -615496,6 +616964,147 @@ reason=${decision2.reason} confidence=${decision2.confidence.toFixed(2)} source=
615496
616964
  }
615497
616965
  });
615498
616966
 
616967
+ // packages/cli/src/tui/conversation-context.ts
616968
+ import { statfsSync as statfsSync7 } from "node:fs";
616969
+ function buildConversationRuntimeContext(now2 = /* @__PURE__ */ new Date(), repoRoot) {
616970
+ const date = new Intl.DateTimeFormat("en-US", {
616971
+ weekday: "long",
616972
+ year: "numeric",
616973
+ month: "long",
616974
+ day: "numeric"
616975
+ }).format(now2);
616976
+ const time = new Intl.DateTimeFormat("en-US", {
616977
+ hour: "numeric",
616978
+ minute: "2-digit",
616979
+ second: "2-digit",
616980
+ timeZoneName: "short"
616981
+ }).format(now2);
616982
+ const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || process.env["TZ"] || "system";
616983
+ let diskLine = "";
616984
+ if (repoRoot) {
616985
+ try {
616986
+ const stats = statfsSync7(repoRoot);
616987
+ const totalBytes = Number(stats.blocks) * Number(stats.bsize);
616988
+ const freeBytes = Number(stats.bavail) * Number(stats.bsize);
616989
+ const usedBytes = totalBytes - freeBytes;
616990
+ const totalGB = Math.round(totalBytes / 1024 ** 3);
616991
+ const freeGB = Math.round(freeBytes / 1024 ** 3);
616992
+ const usedGB = Math.round(usedBytes / 1024 ** 3);
616993
+ const usedPct = totalBytes > 0 ? Math.round(usedBytes / totalBytes * 100) : 0;
616994
+ diskLine = `Disk: disk_available_gb=${freeGB} disk_used_gb=${usedGB} disk_total_gb=${totalGB} disk_used_pct=${usedPct} path=${repoRoot}`;
616995
+ } catch {
616996
+ }
616997
+ }
616998
+ return [
616999
+ `Current date: ${date}`,
617000
+ `Current time: ${time}`,
617001
+ `Current ISO timestamp: ${now2.toISOString()}`,
617002
+ `Timezone: ${timezone}`,
617003
+ repoRoot ? `Working directory: ${repoRoot}` : "",
617004
+ diskLine
617005
+ ].filter(Boolean).join("\n");
617006
+ }
617007
+ function quoteConversationBlock(value2, maxChars = 2400) {
617008
+ const text2 = String(value2 ?? "").replace(/\r\n/g, "\n").trim();
617009
+ if (!text2) return "> (empty)";
617010
+ const clipped = text2.length > maxChars ? `${text2.slice(0, Math.max(0, maxChars - 1))}...` : text2;
617011
+ return clipped.split("\n").map((line) => `> ${line}`).join("\n");
617012
+ }
617013
+ function buildScopedConversationMessages(turns, options2) {
617014
+ const pinned = [];
617015
+ const dynamic = [];
617016
+ let latestContextFrame = null;
617017
+ for (const turn of turns) {
617018
+ if (options2.isPinnedSystemTurn(turn) && !pinned.some((p2) => p2.content === turn.content)) {
617019
+ pinned.push(turn);
617020
+ } else if (options2.isContextFrameTurn?.(turn)) {
617021
+ latestContextFrame = turn;
617022
+ } else {
617023
+ dynamic.push(turn);
617024
+ }
617025
+ }
617026
+ if (latestContextFrame) {
617027
+ if (options2.placeContextFrameBeforeLastUser !== false) {
617028
+ let lastUserIdx = -1;
617029
+ for (let i2 = dynamic.length - 1; i2 >= 0; i2--) {
617030
+ if (dynamic[i2].role === "user") {
617031
+ lastUserIdx = i2;
617032
+ break;
617033
+ }
617034
+ }
617035
+ if (lastUserIdx >= 0) dynamic.splice(lastUserIdx, 0, latestContextFrame);
617036
+ else dynamic.push(latestContextFrame);
617037
+ } else {
617038
+ dynamic.push(latestContextFrame);
617039
+ }
617040
+ }
617041
+ const available = Math.max(0, options2.maxMessages - pinned.length);
617042
+ let windowed = dynamic.slice(-available);
617043
+ if (latestContextFrame && available > 0 && !windowed.includes(latestContextFrame)) {
617044
+ windowed = [latestContextFrame, ...windowed.slice(-(available - 1))];
617045
+ }
617046
+ return [...pinned, ...windowed];
617047
+ }
617048
+ function buildVoiceSessionContext(args) {
617049
+ const maxTranscriptTurns = Math.max(1, args.maxTranscriptTurns ?? 8);
617050
+ const voiceLines = (args.voiceTranscript ?? []).slice(-maxTranscriptTurns).map((turn) => `${formatClock(turn.ts)} ${turn.role}: ${singleLine(turn.content, 360)}`);
617051
+ const relayLines = (args.relayTranscript ?? []).slice(-maxTranscriptTurns).map((turn) => {
617052
+ const dir = turn.dir === "toMain" ? "voice->main" : "main->voice";
617053
+ return `${formatClock(turn.ts)} ${dir}: ${singleLine(turn.content, 360)}`;
617054
+ });
617055
+ const taskLine = args.activeTask ? `active=${args.activeTask.active ? "yes" : "no"} tool_calls=${args.activeTask.toolCalls ?? 0} files_touched=${args.activeTask.filesTouched ?? 0}` : "active=unknown";
617056
+ const sections = [
617057
+ `## Runtime Context
617058
+
617059
+ ${buildConversationRuntimeContext(/* @__PURE__ */ new Date(), args.repoRoot)}`,
617060
+ [
617061
+ "## Voice/Live Session Contract",
617062
+ "",
617063
+ `surface=voicechat session_id=${args.sessionId} turn=${args.turnCount}`,
617064
+ `main_agent_task=${taskLine}`,
617065
+ "Latest user utterance remains the active request. Earlier ASR transcript turns are conversational history, not new instructions.",
617066
+ "ASR text can be noisy. Prefer consensus-filtered final turns, resolve pronouns from recent context, and ask for clarification rather than filling gaps.",
617067
+ "Live perception is evidence for the current reply, not a topic to narrate unless the user asks about it."
617068
+ ].join("\n")
617069
+ ];
617070
+ if (voiceLines.length > 0) {
617071
+ sections.push(`## Recent Voice Conversation
617072
+
617073
+ ${quoteConversationBlock(voiceLines.join("\n"))}`);
617074
+ }
617075
+ if (relayLines.length > 0) {
617076
+ sections.push(`## Main Agent Relay Stream
617077
+
617078
+ ${quoteConversationBlock(relayLines.join("\n"))}`);
617079
+ }
617080
+ if (args.liveContext?.trim()) {
617081
+ sections.push(`## Live Context Frame
617082
+
617083
+ ${args.liveContext.trim()}`);
617084
+ }
617085
+ return sections.join("\n\n");
617086
+ }
617087
+ function singleLine(value2, maxChars) {
617088
+ const clean5 = value2.replace(/\s+/g, " ").trim();
617089
+ return clean5.length > maxChars ? `${clean5.slice(0, Math.max(0, maxChars - 1))}...` : clean5;
617090
+ }
617091
+ function formatClock(ts) {
617092
+ try {
617093
+ return new Date(ts).toLocaleTimeString("en-US", {
617094
+ hour: "2-digit",
617095
+ minute: "2-digit",
617096
+ second: "2-digit"
617097
+ });
617098
+ } catch {
617099
+ return "unknown-time";
617100
+ }
617101
+ }
617102
+ var init_conversation_context = __esm({
617103
+ "packages/cli/src/tui/conversation-context.ts"() {
617104
+ "use strict";
617105
+ }
617106
+ });
617107
+
615499
617108
  // packages/cli/src/tui/generative-progress.ts
615500
617109
  function generationKindForToolName(toolName) {
615501
617110
  if (toolName === "generate_image") return "image";
@@ -626805,7 +628414,7 @@ import { EventEmitter as EventEmitter8 } from "node:events";
626805
628414
  import { randomBytes as randomBytes22, timingSafeEqual } from "node:crypto";
626806
628415
  import { URL as URL2 } from "node:url";
626807
628416
  import { loadavg as loadavg2, cpus as cpus4, totalmem as totalmem7, freemem as freemem6 } from "node:os";
626808
- import { existsSync as existsSync119, readFileSync as readFileSync98, writeFileSync as writeFileSync61, unlinkSync as unlinkSync21, mkdirSync as mkdirSync73, readdirSync as readdirSync39, statSync as statSync47, statfsSync as statfsSync7 } from "node:fs";
628417
+ import { existsSync as existsSync119, readFileSync as readFileSync98, writeFileSync as writeFileSync61, unlinkSync as unlinkSync21, mkdirSync as mkdirSync73, readdirSync as readdirSync39, statSync as statSync47, statfsSync as statfsSync8 } from "node:fs";
626809
628418
  import { join as join133 } from "node:path";
626810
628419
  function cleanForwardHeaders(raw, targetHost) {
626811
628420
  const out = {};
@@ -627075,7 +628684,7 @@ async function collectSystemMetricsAsync() {
627075
628684
  utilization: -1
627076
628685
  };
627077
628686
  try {
627078
- const fs12 = statfsSync7(process.cwd());
628687
+ const fs12 = statfsSync8(process.cwd());
627079
628688
  const totalBytes = fs12.blocks * fs12.bsize;
627080
628689
  const freeBytes = fs12.bavail * fs12.bsize;
627081
628690
  const usedBytes = totalBytes - freeBytes;
@@ -634689,7 +636298,7 @@ function setTerminalTitle(task, version5) {
634689
636298
  process.stdout.write(data);
634690
636299
  }
634691
636300
  }
634692
- var EXPERT_TOOL_BASELINES, CONTEXT_SWITCH_OVERHEAD, TURN_PLANNING_OVERHEAD, DEFAULT_TOOL_BASELINE, CODE_READ_CHARS_PER_SEC, PROSE_READ_CHARS_PER_SEC, MIN_CONTENT_FOR_READING, CODE_CONTENT_TOOLS, PROSE_CONTENT_TOOLS, HumanSpeedTracker, PANEL_BG_SEQ, CONTENT_BG_SEQ, BOX_FG, TEXT_PRIMARY, TEXT_DIM, NO_SUB_AGENTS_HEADER_LABEL, HEADER_BUTTON_GLYPH_FG, HEADER_BUTTON_BG, HEADER_BUTTON_FG, HEADER_ACCENT_BOLD_FG, HEADER_TELEGRAM_FG, BOX_TL3, BOX_TR3, BOX_BL3, BOX_BR3, BOX_H3, BOX_V3, BOX_BJ, _globalFooterLock, RESET4, CURSOR_BLINK_BLOCK, _isWindows, HEADER_BUTTON_LEFT, HEADER_BUTTON_RIGHT, SPONSOR_HEADER_LABEL_MAX, _termTitleWriter, StatusBar;
636301
+ var EXPERT_TOOL_BASELINES, CONTEXT_SWITCH_OVERHEAD, TURN_PLANNING_OVERHEAD, DEFAULT_TOOL_BASELINE, CODE_READ_CHARS_PER_SEC, PROSE_READ_CHARS_PER_SEC, MIN_CONTENT_FOR_READING, CODE_CONTENT_TOOLS, PROSE_CONTENT_TOOLS, HumanSpeedTracker, PANEL_BG_SEQ, CONTENT_BG_SEQ, BOX_FG, TEXT_PRIMARY, TEXT_DIM, NO_SUB_AGENTS_HEADER_LABEL, HEADER_BUTTON_GLYPH_FG, HEADER_BUTTON_BG, HEADER_BUTTON_FG, HEADER_ACCENT_BOLD_FG, HEADER_TELEGRAM_FG, BOX_TL3, BOX_TR3, BOX_BL3, BOX_BR3, BOX_H3, BOX_V3, BOX_BJ, BOX_TJ, ENHANCE_SEG_INNER, ENHANCE_SPIN_FRAMES, _globalFooterLock, RESET4, CURSOR_BLINK_BLOCK, _isWindows, HEADER_BUTTON_LEFT, HEADER_BUTTON_RIGHT, SPONSOR_HEADER_LABEL_MAX, _termTitleWriter, StatusBar;
634693
636302
  var init_status_bar = __esm({
634694
636303
  "packages/cli/src/tui/status-bar.ts"() {
634695
636304
  "use strict";
@@ -634882,6 +636491,20 @@ var init_status_bar = __esm({
634882
636491
  BOX_H3 = "─";
634883
636492
  BOX_V3 = "│";
634884
636493
  BOX_BJ = "┴";
636494
+ BOX_TJ = "┬";
636495
+ ENHANCE_SEG_INNER = 11;
636496
+ ENHANCE_SPIN_FRAMES = [
636497
+ "⠋",
636498
+ "⠙",
636499
+ "⠹",
636500
+ "⠸",
636501
+ "⠼",
636502
+ "⠴",
636503
+ "⠦",
636504
+ "⠧",
636505
+ "⠇",
636506
+ "⠏"
636507
+ ];
634885
636508
  _globalFooterLock = false;
634886
636509
  RESET4 = "\x1B[0m";
634887
636510
  CURSOR_BLINK_BLOCK = "\x1B[1 q";
@@ -635051,6 +636674,23 @@ var init_status_bar = __esm({
635051
636674
  * own output is suppressed.
635052
636675
  */
635053
636676
  inputStateProvider = null;
636677
+ // ── Input-box "enhance" prompt-expansion button ──────────────────────
636678
+ /** Mutates the underlying input buffer (line + cursor). Wired to DirectInput.setLine. */
636679
+ _inputMutator = null;
636680
+ /** Runs the inference-based prompt expansion. Returns the enhanced prompt or null. */
636681
+ _enhanceHandler = null;
636682
+ /** Current enhance-button lifecycle state. */
636683
+ _enhanceState = "idle";
636684
+ /** The pre-expansion seed text, restored when the user rejects the expansion. */
636685
+ _enhanceOriginal = null;
636686
+ /** Transient press-flash target for visual click feedback. */
636687
+ _enhancePressed = null;
636688
+ /** Spinner animation frame index while state === "busy". */
636689
+ _enhanceSpinFrame = 0;
636690
+ /** Spinner redraw timer while state === "busy". */
636691
+ _enhanceSpinTimer = null;
636692
+ /** Sub-zones for the accept (✔) / reject (✖) confirm glyphs (confirm state only). */
636693
+ _enhanceConfirmZones = null;
635054
636694
  /** Whether microphone is recording (blinking indicator) */
635055
636695
  _recording = false;
635056
636696
  /** Whether speech is currently detected on the mic (from ListenEngine metering) */
@@ -637056,6 +638696,7 @@ var init_status_bar = __esm({
637056
638696
  if (viewId) this.switchToView(viewId);
637057
638697
  return;
637058
638698
  }
638699
+ if (type === "press" && this.handleFooterInputClick(row, col)) return;
637059
638700
  const L = layout();
637060
638701
  const inContent = row >= this.scrollRegionTop && row <= L.contentBottom;
637061
638702
  if (inContent) {
@@ -637334,8 +638975,7 @@ var init_status_bar = __esm({
637334
638975
  for (let row = clearStart; row <= rows; row++) {
637335
638976
  buf += `\x1B[${row};1H\x1B[2K`;
637336
638977
  }
637337
- const boxInnerP = w - 2;
637338
- buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_TL3}${BOX_H3.repeat(Math.max(0, boxInnerP))}${BOX_TR3}${RESET4}${PANEL_BG_SEQ}`;
638978
+ buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildInputBoxTop(w)}${PANEL_BG_SEQ}`;
637339
638979
  for (let i2 = 0; i2 < inputWrap.lines.length; i2++) {
637340
638980
  const row = pos.inputStartRow + 1 + i2;
637341
638981
  const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
@@ -637344,7 +638984,12 @@ var init_status_bar = __esm({
637344
638984
  buf += `${BOX_FG}${BOX_V3}${RESET4}${PANEL_BG_SEQ}${lineContent}`;
637345
638985
  buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
637346
638986
  }
637347
- buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL3}${BOX_H3.repeat(Math.max(0, boxInnerP))}${BOX_BR3}${RESET4}${PANEL_BG_SEQ}`;
638987
+ buf += this.buildEnhanceSegment(
638988
+ w,
638989
+ pos.inputStartRow + 1,
638990
+ inputWrap.lines.length
638991
+ );
638992
+ buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildInputBoxBottom(w)}${PANEL_BG_SEQ}`;
637348
638993
  if (pos.metricsRow > 0) {
637349
638994
  buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}${PANEL_BG_SEQ}`;
637350
638995
  }
@@ -638758,9 +640403,268 @@ ${CONTENT_BG_SEQ}`);
638758
640403
  this._brailleSpinner.setMetrics({ contextPct });
638759
640404
  }
638760
640405
  /** Compute how many visual lines the current input text occupies */
640406
+ // ── "enhance" segment geometry ───────────────────────────────────────
640407
+ /** Whether the enhance segment is wired and the terminal is wide enough. */
640408
+ enhanceSegEnabled(termWidth) {
640409
+ if (!this._enhanceHandler) return false;
640410
+ const w = termWidth ?? getTermWidth();
640411
+ return w >= this.promptWidth + ENHANCE_SEG_INNER + 16;
640412
+ }
640413
+ /** Column of the │ divider that separates the input area from the button cell. */
640414
+ enhanceDividerCol(termWidth) {
640415
+ const w = termWidth ?? getTermWidth();
640416
+ return w - 1 - ENHANCE_SEG_INNER;
640417
+ }
638761
640418
  inputTextWidth(termWidth) {
638762
640419
  const w = termWidth ?? getTermWidth();
638763
- return Math.max(1, w - this.promptWidth - 2);
640420
+ const seg = this.enhanceSegEnabled(w) ? ENHANCE_SEG_INNER + 1 : 0;
640421
+ return Math.max(1, w - this.promptWidth - 2 - seg);
640422
+ }
640423
+ /** Box top border with an optional ┬ carving out the enhance segment. */
640424
+ buildInputBoxTop(w) {
640425
+ if (!this.enhanceSegEnabled(w)) {
640426
+ return `${BOX_FG}${BOX_TL3}${BOX_H3.repeat(Math.max(0, w - 2))}${BOX_TR3}${RESET4}`;
640427
+ }
640428
+ const dividerCol = this.enhanceDividerCol(w);
640429
+ const leftDashes = Math.max(0, dividerCol - 2);
640430
+ return `${BOX_FG}${BOX_TL3}${BOX_H3.repeat(leftDashes)}${BOX_TJ}${BOX_H3.repeat(ENHANCE_SEG_INNER)}${BOX_TR3}${RESET4}`;
640431
+ }
640432
+ /** Box bottom border with an optional ┴ closing the enhance segment. */
640433
+ buildInputBoxBottom(w) {
640434
+ if (!this.enhanceSegEnabled(w)) {
640435
+ return `${BOX_FG}${BOX_BL3}${BOX_H3.repeat(Math.max(0, w - 2))}${BOX_BR3}${RESET4}`;
640436
+ }
640437
+ const dividerCol = this.enhanceDividerCol(w);
640438
+ const leftDashes = Math.max(0, dividerCol - 2);
640439
+ return `${BOX_FG}${BOX_BL3}${BOX_H3.repeat(leftDashes)}${BOX_BJ}${BOX_H3.repeat(ENHANCE_SEG_INNER)}${BOX_BR3}${RESET4}`;
640440
+ }
640441
+ /**
640442
+ * Draw the │ divider down each input row plus the enhance/confirm button in
640443
+ * the right-hand cell (button label on the first input row only). Returns an
640444
+ * ANSI overlay string (with CUP moves) that callers append AFTER painting the
640445
+ * input-row content, so it lands on top of the erase-to-EOL fill. Also records
640446
+ * the click zones consumed by handleFooterInputClick().
640447
+ */
640448
+ buildEnhanceSegment(w, firstInputRow, rowCount) {
640449
+ if (!this.enhanceSegEnabled(w) || rowCount < 1) {
640450
+ this._enhanceConfirmZones = null;
640451
+ return "";
640452
+ }
640453
+ const dividerCol = this.enhanceDividerCol(w);
640454
+ const cellStart = dividerCol + 1;
640455
+ const cellEnd = w - 1;
640456
+ let buf = "";
640457
+ for (let i2 = 0; i2 < rowCount; i2++) {
640458
+ const row = firstInputRow + i2;
640459
+ buf += `\x1B[${row};${dividerCol}H${BOX_FG}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
640460
+ if (i2 > 0) {
640461
+ buf += `\x1B[${row};${cellStart}H${PANEL_BG_SEQ}${" ".repeat(ENHANCE_SEG_INNER)}`;
640462
+ }
640463
+ }
640464
+ buf += this.buildEnhanceButtonCell(firstInputRow, cellStart);
640465
+ void cellEnd;
640466
+ return buf;
640467
+ }
640468
+ /** Render the button-cell content for the current enhance state (width = ENHANCE_SEG_INNER). */
640469
+ buildEnhanceButtonCell(row, cellStart) {
640470
+ const cup = `\x1B[${row};${cellStart}H`;
640471
+ if (this._enhanceState === "busy") {
640472
+ this._enhanceConfirmZones = null;
640473
+ const frame = ENHANCE_SPIN_FRAMES[this._enhanceSpinFrame % ENHANCE_SPIN_FRAMES.length] ?? "⠋";
640474
+ const pad = Math.floor((ENHANCE_SEG_INNER - 1) / 2);
640475
+ const cell = " ".repeat(pad) + frame + " ".repeat(ENHANCE_SEG_INNER - 1 - pad);
640476
+ return `${cup}${PANEL_BG_SEQ}\x1B[38;5;${TEXT_DIM}m${cell}${RESET4}${PANEL_BG_SEQ}`;
640477
+ }
640478
+ if (this._enhanceState === "confirm") {
640479
+ const rejectIdx = 2;
640480
+ const acceptIdx = ENHANCE_SEG_INNER - 3;
640481
+ const rejectPressed = this._enhancePressed === "reject";
640482
+ const acceptPressed = this._enhancePressed === "accept";
640483
+ const rejectFg = rejectPressed ? "\x1B[1;7;38;5;196m" : "\x1B[1;38;5;196m";
640484
+ const acceptFg = acceptPressed ? "\x1B[1;7;38;5;40m" : "\x1B[1;38;5;40m";
640485
+ let out = `${cup}${PANEL_BG_SEQ}`;
640486
+ for (let i2 = 0; i2 < ENHANCE_SEG_INNER; i2++) {
640487
+ if (i2 === rejectIdx) out += `${rejectFg}✖${RESET4}${PANEL_BG_SEQ}`;
640488
+ else if (i2 === acceptIdx) out += `${acceptFg}✔${RESET4}${PANEL_BG_SEQ}`;
640489
+ else out += " ";
640490
+ }
640491
+ this._enhanceConfirmZones = {
640492
+ reject: { c0: cellStart + rejectIdx, c1: cellStart + rejectIdx },
640493
+ accept: { c0: cellStart + acceptIdx, c1: cellStart + acceptIdx }
640494
+ };
640495
+ return out;
640496
+ }
640497
+ this._enhanceConfirmZones = null;
640498
+ const label = "enhance";
640499
+ const totalPad = ENHANCE_SEG_INNER - label.length;
640500
+ const left = Math.floor(totalPad / 2);
640501
+ const chip = " ".repeat(left) + label + " ".repeat(totalPad - left);
640502
+ const pressed = this._enhancePressed === "enhance";
640503
+ const body = pressed ? `\x1B[7m${HEADER_BUTTON_BG}${HEADER_BUTTON_FG}${chip}${RESET4}` : `${HEADER_BUTTON_BG}${HEADER_BUTTON_FG}${chip}${RESET4}`;
640504
+ return `${cup}${body}${PANEL_BG_SEQ}`;
640505
+ }
640506
+ // ── "enhance" public API + lifecycle ─────────────────────────────────
640507
+ /** Wire the buffer mutator (DirectInput.setLine) so clicks can move the cursor / swap text. */
640508
+ setInputMutator(fn) {
640509
+ this._inputMutator = fn;
640510
+ }
640511
+ /**
640512
+ * Wire the inference-backed prompt-expansion handler. Passing a handler also
640513
+ * enables the enhance segment in the input box. `seed` is the current input
640514
+ * text; resolve with the expanded prompt, or null to abort (no change).
640515
+ */
640516
+ setEnhanceHandler(fn) {
640517
+ this._enhanceHandler = fn;
640518
+ }
640519
+ /** Reset the enhance button to idle (called on submit / escape / new prompt). */
640520
+ resetEnhance() {
640521
+ const wasActive = this._enhanceState !== "idle";
640522
+ this.stopEnhanceSpinner();
640523
+ this._enhanceState = "idle";
640524
+ this._enhanceOriginal = null;
640525
+ this._enhancePressed = null;
640526
+ if (wasActive && this.active && !this._resizing) {
640527
+ this.renderFooterAndPositionInput();
640528
+ }
640529
+ }
640530
+ startEnhanceSpinner() {
640531
+ this.stopEnhanceSpinner();
640532
+ this._enhanceSpinTimer = setInterval(() => {
640533
+ if (this._enhanceState !== "busy") {
640534
+ this.stopEnhanceSpinner();
640535
+ return;
640536
+ }
640537
+ this._enhanceSpinFrame++;
640538
+ if (this.active && !this._resizing && this.writeDepth === 0) {
640539
+ this.renderFooterAndPositionInput();
640540
+ }
640541
+ }, 120);
640542
+ if (typeof this._enhanceSpinTimer.unref === "function") {
640543
+ this._enhanceSpinTimer.unref();
640544
+ }
640545
+ }
640546
+ stopEnhanceSpinner() {
640547
+ if (this._enhanceSpinTimer) {
640548
+ clearInterval(this._enhanceSpinTimer);
640549
+ this._enhanceSpinTimer = null;
640550
+ }
640551
+ }
640552
+ /** Kick off the expansion inference for the current input text. */
640553
+ beginEnhance() {
640554
+ if (this._enhanceState !== "idle" || !this._enhanceHandler) return;
640555
+ const state = this.inputStateProvider?.();
640556
+ const original = state?.line ?? "";
640557
+ const seed = original.trim();
640558
+ if (!seed) return;
640559
+ this._enhanceOriginal = original;
640560
+ this._enhanceState = "busy";
640561
+ this._enhanceSpinFrame = 0;
640562
+ this._enhancePressed = null;
640563
+ this.startEnhanceSpinner();
640564
+ if (this.active && !this._resizing) this.renderFooterAndPositionInput();
640565
+ const handler = this._enhanceHandler;
640566
+ void (async () => {
640567
+ let expanded = null;
640568
+ try {
640569
+ expanded = await handler(seed);
640570
+ } catch {
640571
+ expanded = null;
640572
+ }
640573
+ this.stopEnhanceSpinner();
640574
+ if (this._enhanceState !== "busy") {
640575
+ if (this.active && !this._resizing) this.renderFooterAndPositionInput();
640576
+ return;
640577
+ }
640578
+ const clean5 = (expanded ?? "").trim();
640579
+ if (clean5 && clean5 !== seed) {
640580
+ this._inputMutator?.(clean5, clean5.length);
640581
+ this._enhanceState = "confirm";
640582
+ } else {
640583
+ this._enhanceState = "idle";
640584
+ this._enhanceOriginal = null;
640585
+ }
640586
+ if (this.active && !this._resizing) this.renderFooterAndPositionInput();
640587
+ })();
640588
+ }
640589
+ /** Resolve the confirm state: accept keeps the expansion, reject restores the seed. */
640590
+ resolveEnhance(accept) {
640591
+ if (this._enhanceState !== "confirm") return;
640592
+ if (!accept && this._enhanceOriginal != null) {
640593
+ const orig = this._enhanceOriginal;
640594
+ this._inputMutator?.(orig, orig.length);
640595
+ }
640596
+ this._enhanceState = "idle";
640597
+ this._enhanceOriginal = null;
640598
+ this._enhancePressed = null;
640599
+ if (this.active && !this._resizing) this.renderFooterAndPositionInput();
640600
+ }
640601
+ /** Brief press-flash for click feedback, then repaint. */
640602
+ flashEnhancePress(which3) {
640603
+ this._enhancePressed = which3;
640604
+ if (this.active && !this._resizing) this.renderFooterAndPositionInput();
640605
+ setTimeout(() => {
640606
+ if (this._enhancePressed === which3) {
640607
+ this._enhancePressed = null;
640608
+ if (this.active && !this._resizing) this.renderFooterAndPositionInput();
640609
+ }
640610
+ }, 130);
640611
+ }
640612
+ /**
640613
+ * Handle a press inside the footer input box: the enhance/confirm button,
640614
+ * or a click in the text area to reposition the cursor. Returns true when the
640615
+ * click was consumed.
640616
+ */
640617
+ handleFooterInputClick(row, col) {
640618
+ if (!this.inputStateProvider) return false;
640619
+ const w = getTermWidth();
640620
+ const pos = this.rowPositions(termRows());
640621
+ const inputLines = this.computeInputLineCount(w);
640622
+ const firstInputRow = pos.inputStartRow + 1;
640623
+ const lastInputRow = firstInputRow + inputLines - 1;
640624
+ if (row < firstInputRow || row > lastInputRow) return false;
640625
+ if (this.enhanceSegEnabled(w)) {
640626
+ const dividerCol = this.enhanceDividerCol(w);
640627
+ const cellStart = dividerCol + 1;
640628
+ const cellEnd = w - 1;
640629
+ if (col >= dividerCol && col <= cellEnd) {
640630
+ if (this._enhanceState === "confirm") {
640631
+ const mid = Math.floor((cellStart + cellEnd) / 2);
640632
+ if (col <= mid) {
640633
+ this.flashEnhancePress("reject");
640634
+ this.resolveEnhance(false);
640635
+ } else {
640636
+ this.flashEnhancePress("accept");
640637
+ this.resolveEnhance(true);
640638
+ }
640639
+ return true;
640640
+ }
640641
+ if (this._enhanceState === "idle") {
640642
+ this.flashEnhancePress("enhance");
640643
+ this.beginEnhance();
640644
+ return true;
640645
+ }
640646
+ return true;
640647
+ }
640648
+ if (col >= dividerCol) return false;
640649
+ }
640650
+ const availWidth = this.inputTextWidth(w);
640651
+ const line = this.inputStateProvider().line ?? "";
640652
+ const { rawLines, charPositions } = this.wrapPlainInputText(
640653
+ line,
640654
+ availWidth
640655
+ );
640656
+ const lineIdx = Math.min(
640657
+ Math.max(0, row - firstInputRow),
640658
+ rawLines.length - 1
640659
+ );
640660
+ const rawLine = rawLines[lineIdx] ?? "";
640661
+ let charInLine = col - this.promptWidth - 2;
640662
+ if (charInLine < 0) charInLine = 0;
640663
+ if (charInLine > rawLine.length) charInLine = rawLine.length;
640664
+ const newCursor = (charPositions[lineIdx] ?? 0) + charInLine;
640665
+ this._inputMutator?.(line, Math.min(newCursor, line.length));
640666
+ if (this.active && !this._resizing) this.renderFooterAndPositionInput();
640667
+ return true;
638764
640668
  }
638765
640669
  wrapPlainInputText(text2, availWidth) {
638766
640670
  const width = Math.max(1, availWidth);
@@ -638994,8 +640898,7 @@ ${CONTENT_BG_SEQ}`);
638994
640898
  }
638995
640899
  const inputWrap = this.wrapInput(w);
638996
640900
  let buf = "\x1B[?7l";
638997
- const boxInner = w - 2;
638998
- buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_TL3}${BOX_H3.repeat(Math.max(0, boxInner))}${BOX_TR3}${RESET4}${PANEL_BG_SEQ}`;
640901
+ buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildInputBoxTop(w)}${PANEL_BG_SEQ}`;
638999
640902
  const Lspacer = layout();
639000
640903
  const spacerRow = pos.inputStartRow - 1;
639001
640904
  const tasksOccupiesSpacer = Lspacer.tasksHeight > 0 && spacerRow >= Lspacer.tasksTop && spacerRow <= Lspacer.tasksBottom;
@@ -639011,6 +640914,11 @@ ${CONTENT_BG_SEQ}`);
639011
640914
  buf += `${PANEL_BG_SEQ}\x1B[K`;
639012
640915
  buf += `\x1B[${row};${w}H${BOX_FG}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
639013
640916
  }
640917
+ buf += this.buildEnhanceSegment(
640918
+ w,
640919
+ pos.inputStartRow + 1,
640920
+ inputWrap.lines.length
640921
+ );
639014
640922
  const cursorTermRow = pos.inputStartRow + 1 + inputWrap.cursorRow;
639015
640923
  if (this._suggestions.length > 0 && pos.suggestStartRow > 0) {
639016
640924
  for (let si = 0; si < this._suggestions.length; si++) {
@@ -639027,9 +640935,9 @@ ${CONTENT_BG_SEQ}`);
639027
640935
  buf += `\x1B[${row};${w}H${BOX_FG}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
639028
640936
  }
639029
640937
  const suggestBottomRow = pos.suggestStartRow + this._suggestions.length;
639030
- buf += `\x1B[${suggestBottomRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL3}${BOX_H3.repeat(Math.max(0, boxInner))}${BOX_BR3}${RESET4}${PANEL_BG_SEQ}`;
640938
+ buf += `\x1B[${suggestBottomRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildInputBoxBottom(w)}${PANEL_BG_SEQ}`;
639031
640939
  } else {
639032
- buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL3}${BOX_H3.repeat(Math.max(0, boxInner))}${BOX_BR3}${RESET4}${PANEL_BG_SEQ}`;
640940
+ buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildInputBoxBottom(w)}${PANEL_BG_SEQ}`;
639033
640941
  }
639034
640942
  if (pos.metricsRow > 0) {
639035
640943
  buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}${PANEL_BG_SEQ}`;
@@ -639069,7 +640977,6 @@ ${CONTENT_BG_SEQ}`);
639069
640977
  if (pos.tabBarRow > 0) {
639070
640978
  buf += `\x1B[${pos.tabBarRow};1H${PANEL_BG_SEQ}\x1B[2K${RESET4}`;
639071
640979
  }
639072
- const boxInnerR = w - 2;
639073
640980
  if (this._suggestions.length > 0 && pos.suggestStartRow > 0) {
639074
640981
  for (let si = 0; si < this._suggestions.length; si++) {
639075
640982
  const row = pos.suggestStartRow + si;
@@ -639080,9 +640987,9 @@ ${CONTENT_BG_SEQ}`);
639080
640987
  buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_V3}${RESET4}${PANEL_BG_SEQ} ${marker}\x1B[38;5;${TEXT_DIM}m/${fg2}${cmd}`;
639081
640988
  buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${BOX_V3}${RESET4}`;
639082
640989
  }
639083
- buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL3}${BOX_H3.repeat(Math.max(0, boxInnerR))}${BOX_BR3}${RESET4}`;
640990
+ buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildInputBoxBottom(w)}`;
639084
640991
  } else {
639085
- buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL3}${BOX_H3.repeat(Math.max(0, boxInnerR))}${BOX_BR3}${RESET4}`;
640992
+ buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildInputBoxBottom(w)}`;
639086
640993
  }
639087
640994
  if (pos.metricsRow > 0) {
639088
640995
  buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}${PANEL_BG_SEQ}`;
@@ -639136,14 +641043,18 @@ ${CONTENT_BG_SEQ}`);
639136
641043
  }
639137
641044
  }
639138
641045
  buf += "\x1B[?7l";
639139
- const boxInnerH = w - 2;
639140
- buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_TL3}${BOX_H3.repeat(Math.max(0, boxInnerH))}${BOX_TR3}${RESET4}`;
641046
+ buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildInputBoxTop(w)}`;
639141
641047
  for (let i2 = 0; i2 < inputWrap.lines.length; i2++) {
639142
641048
  const row = pos.inputStartRow + 1 + i2;
639143
641049
  const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
639144
641050
  const lineContent = `${prefix}${inputWrap.lines[i2]}`;
639145
641051
  buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_V3}${RESET4}${PANEL_BG_SEQ}${lineContent}${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${BOX_V3}${RESET4}`;
639146
641052
  }
641053
+ buf += this.buildEnhanceSegment(
641054
+ w,
641055
+ pos.inputStartRow + 1,
641056
+ inputWrap.lines.length
641057
+ );
639147
641058
  if (this._suggestions.length > 0 && pos.suggestStartRow > 0) {
639148
641059
  for (let si = 0; si < this._suggestions.length; si++) {
639149
641060
  const row = pos.suggestStartRow + si;
@@ -639157,8 +641068,7 @@ ${CONTENT_BG_SEQ}`);
639157
641068
  buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${BOX_V3}${RESET4}`;
639158
641069
  }
639159
641070
  }
639160
- const boxInnerS = w - 2;
639161
- buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL3}${BOX_H3.repeat(Math.max(0, boxInnerS))}${BOX_BR3}${RESET4}`;
641071
+ buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildInputBoxBottom(w)}`;
639162
641072
  if (pos.metricsRow > 0) {
639163
641073
  buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}`;
639164
641074
  }
@@ -639175,8 +641085,7 @@ ${CONTENT_BG_SEQ}`);
639175
641085
  if (heightDelta !== 0) this.refreshTasksPanelAfterLayoutChange();
639176
641086
  } else {
639177
641087
  let buf = "\x1B7\x1B[?25l\x1B[?7l";
639178
- const boxInnerH = w - 2;
639179
- buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_TL3}${BOX_H3.repeat(Math.max(0, boxInnerH))}${BOX_TR3}${RESET4}${PANEL_BG_SEQ}`;
641088
+ buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildInputBoxTop(w)}${PANEL_BG_SEQ}`;
639180
641089
  for (let i2 = 0; i2 < inputWrap.lines.length; i2++) {
639181
641090
  const row = pos.inputStartRow + 1 + i2;
639182
641091
  const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
@@ -639186,6 +641095,11 @@ ${CONTENT_BG_SEQ}`);
639186
641095
  buf += `${PANEL_BG_SEQ}\x1B[K`;
639187
641096
  buf += `\x1B[${row};${w}H${BOX_FG}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
639188
641097
  }
641098
+ buf += this.buildEnhanceSegment(
641099
+ w,
641100
+ pos.inputStartRow + 1,
641101
+ inputWrap.lines.length
641102
+ );
639189
641103
  if (this._suggestions.length > 0 && pos.suggestStartRow > 0) {
639190
641104
  for (let si = 0; si < this._suggestions.length; si++) {
639191
641105
  const row = pos.suggestStartRow + si;
@@ -639199,7 +641113,7 @@ ${CONTENT_BG_SEQ}`);
639199
641113
  buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
639200
641114
  }
639201
641115
  }
639202
- buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL3}${BOX_H3.repeat(Math.max(0, boxInnerH))}${BOX_BR3}${RESET4}${PANEL_BG_SEQ}`;
641116
+ buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildInputBoxBottom(w)}${PANEL_BG_SEQ}`;
639203
641117
  if (pos.metricsRow > 0) {
639204
641118
  buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}${PANEL_BG_SEQ}`;
639205
641119
  }
@@ -678170,7 +680084,7 @@ var init_edit_history = __esm({
678170
680084
  // packages/cli/src/tui/snr-engine.ts
678171
680085
  import { existsSync as existsSync149, readdirSync as readdirSync52, readFileSync as readFileSync122, writeFileSync as writeFileSync78, mkdirSync as mkdirSync91, rmSync as rmSync13 } from "node:fs";
678172
680086
  import { join as join161, basename as basename35 } from "node:path";
678173
- function computeDPrime(signalScores, noiseScores) {
680087
+ function computeDPrime2(signalScores, noiseScores) {
678174
680088
  if (signalScores.length === 0 || noiseScores.length === 0) return 0;
678175
680089
  const mean = (arr) => arr.reduce((s2, v) => s2 + v, 0) / arr.length;
678176
680090
  const variance = (arr, mu) => arr.reduce((s2, v) => s2 + (v - mu) ** 2, 0) / Math.max(1, arr.length - 1);
@@ -678266,7 +680180,7 @@ var init_snr_engine = __esm({
678266
680180
  const threshold = Math.max(0.1, mean + 0.5 * std);
678267
680181
  const signalScores = allScores.filter((s2) => s2 >= threshold);
678268
680182
  const noiseScores = allScores.filter((s2) => s2 < threshold);
678269
- const dPrime = computeDPrime(
680183
+ const dPrime = computeDPrime2(
678270
680184
  signalScores.length > 0 ? signalScores : [mean],
678271
680185
  noiseScores.length > 0 ? noiseScores : [0]
678272
680186
  );
@@ -678385,7 +680299,7 @@ Call task_complete with the JSON array when done.`,
678385
680299
  const threshold = Math.max(0.3, mean);
678386
680300
  const signalEntries = combinedScores.filter((s2) => s2 >= threshold);
678387
680301
  const noiseEntries = combinedScores.filter((s2) => s2 < threshold);
678388
- const dPrime = computeDPrime(
680302
+ const dPrime = computeDPrime2(
678389
680303
  signalEntries.length > 0 ? signalEntries : [mean],
678390
680304
  noiseEntries.length > 0 ? noiseEntries : [0.1]
678391
680305
  );
@@ -682538,147 +684452,6 @@ var init_emotion_engine = __esm({
682538
684452
  }
682539
684453
  });
682540
684454
 
682541
- // packages/cli/src/tui/conversation-context.ts
682542
- import { statfsSync as statfsSync8 } from "node:fs";
682543
- function buildConversationRuntimeContext(now2 = /* @__PURE__ */ new Date(), repoRoot) {
682544
- const date = new Intl.DateTimeFormat("en-US", {
682545
- weekday: "long",
682546
- year: "numeric",
682547
- month: "long",
682548
- day: "numeric"
682549
- }).format(now2);
682550
- const time = new Intl.DateTimeFormat("en-US", {
682551
- hour: "numeric",
682552
- minute: "2-digit",
682553
- second: "2-digit",
682554
- timeZoneName: "short"
682555
- }).format(now2);
682556
- const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || process.env["TZ"] || "system";
682557
- let diskLine = "";
682558
- if (repoRoot) {
682559
- try {
682560
- const stats = statfsSync8(repoRoot);
682561
- const totalBytes = Number(stats.blocks) * Number(stats.bsize);
682562
- const freeBytes = Number(stats.bavail) * Number(stats.bsize);
682563
- const usedBytes = totalBytes - freeBytes;
682564
- const totalGB = Math.round(totalBytes / 1024 ** 3);
682565
- const freeGB = Math.round(freeBytes / 1024 ** 3);
682566
- const usedGB = Math.round(usedBytes / 1024 ** 3);
682567
- const usedPct = totalBytes > 0 ? Math.round(usedBytes / totalBytes * 100) : 0;
682568
- diskLine = `Disk: disk_available_gb=${freeGB} disk_used_gb=${usedGB} disk_total_gb=${totalGB} disk_used_pct=${usedPct} path=${repoRoot}`;
682569
- } catch {
682570
- }
682571
- }
682572
- return [
682573
- `Current date: ${date}`,
682574
- `Current time: ${time}`,
682575
- `Current ISO timestamp: ${now2.toISOString()}`,
682576
- `Timezone: ${timezone}`,
682577
- repoRoot ? `Working directory: ${repoRoot}` : "",
682578
- diskLine
682579
- ].filter(Boolean).join("\n");
682580
- }
682581
- function quoteConversationBlock(value2, maxChars = 2400) {
682582
- const text2 = String(value2 ?? "").replace(/\r\n/g, "\n").trim();
682583
- if (!text2) return "> (empty)";
682584
- const clipped = text2.length > maxChars ? `${text2.slice(0, Math.max(0, maxChars - 1))}...` : text2;
682585
- return clipped.split("\n").map((line) => `> ${line}`).join("\n");
682586
- }
682587
- function buildScopedConversationMessages(turns, options2) {
682588
- const pinned = [];
682589
- const dynamic = [];
682590
- let latestContextFrame = null;
682591
- for (const turn of turns) {
682592
- if (options2.isPinnedSystemTurn(turn) && !pinned.some((p2) => p2.content === turn.content)) {
682593
- pinned.push(turn);
682594
- } else if (options2.isContextFrameTurn?.(turn)) {
682595
- latestContextFrame = turn;
682596
- } else {
682597
- dynamic.push(turn);
682598
- }
682599
- }
682600
- if (latestContextFrame) {
682601
- if (options2.placeContextFrameBeforeLastUser !== false) {
682602
- let lastUserIdx = -1;
682603
- for (let i2 = dynamic.length - 1; i2 >= 0; i2--) {
682604
- if (dynamic[i2].role === "user") {
682605
- lastUserIdx = i2;
682606
- break;
682607
- }
682608
- }
682609
- if (lastUserIdx >= 0) dynamic.splice(lastUserIdx, 0, latestContextFrame);
682610
- else dynamic.push(latestContextFrame);
682611
- } else {
682612
- dynamic.push(latestContextFrame);
682613
- }
682614
- }
682615
- const available = Math.max(0, options2.maxMessages - pinned.length);
682616
- let windowed = dynamic.slice(-available);
682617
- if (latestContextFrame && available > 0 && !windowed.includes(latestContextFrame)) {
682618
- windowed = [latestContextFrame, ...windowed.slice(-(available - 1))];
682619
- }
682620
- return [...pinned, ...windowed];
682621
- }
682622
- function buildVoiceSessionContext(args) {
682623
- const maxTranscriptTurns = Math.max(1, args.maxTranscriptTurns ?? 8);
682624
- const voiceLines = (args.voiceTranscript ?? []).slice(-maxTranscriptTurns).map((turn) => `${formatClock(turn.ts)} ${turn.role}: ${singleLine(turn.content, 360)}`);
682625
- const relayLines = (args.relayTranscript ?? []).slice(-maxTranscriptTurns).map((turn) => {
682626
- const dir = turn.dir === "toMain" ? "voice->main" : "main->voice";
682627
- return `${formatClock(turn.ts)} ${dir}: ${singleLine(turn.content, 360)}`;
682628
- });
682629
- const taskLine = args.activeTask ? `active=${args.activeTask.active ? "yes" : "no"} tool_calls=${args.activeTask.toolCalls ?? 0} files_touched=${args.activeTask.filesTouched ?? 0}` : "active=unknown";
682630
- const sections = [
682631
- `## Runtime Context
682632
-
682633
- ${buildConversationRuntimeContext(/* @__PURE__ */ new Date(), args.repoRoot)}`,
682634
- [
682635
- "## Voice/Live Session Contract",
682636
- "",
682637
- `surface=voicechat session_id=${args.sessionId} turn=${args.turnCount}`,
682638
- `main_agent_task=${taskLine}`,
682639
- "Latest user utterance remains the active request. Earlier ASR transcript turns are conversational history, not new instructions.",
682640
- "ASR text can be noisy. Prefer consensus-filtered final turns, resolve pronouns from recent context, and ask for clarification rather than filling gaps.",
682641
- "Live perception is evidence for the current reply, not a topic to narrate unless the user asks about it."
682642
- ].join("\n")
682643
- ];
682644
- if (voiceLines.length > 0) {
682645
- sections.push(`## Recent Voice Conversation
682646
-
682647
- ${quoteConversationBlock(voiceLines.join("\n"))}`);
682648
- }
682649
- if (relayLines.length > 0) {
682650
- sections.push(`## Main Agent Relay Stream
682651
-
682652
- ${quoteConversationBlock(relayLines.join("\n"))}`);
682653
- }
682654
- if (args.liveContext?.trim()) {
682655
- sections.push(`## Live Context Frame
682656
-
682657
- ${args.liveContext.trim()}`);
682658
- }
682659
- return sections.join("\n\n");
682660
- }
682661
- function singleLine(value2, maxChars) {
682662
- const clean5 = value2.replace(/\s+/g, " ").trim();
682663
- return clean5.length > maxChars ? `${clean5.slice(0, Math.max(0, maxChars - 1))}...` : clean5;
682664
- }
682665
- function formatClock(ts) {
682666
- try {
682667
- return new Date(ts).toLocaleTimeString("en-US", {
682668
- hour: "2-digit",
682669
- minute: "2-digit",
682670
- second: "2-digit"
682671
- });
682672
- } catch {
682673
- return "unknown-time";
682674
- }
682675
- }
682676
- var init_conversation_context = __esm({
682677
- "packages/cli/src/tui/conversation-context.ts"() {
682678
- "use strict";
682679
- }
682680
- });
682681
-
682682
684455
  // packages/cli/src/tui/telegram-format.ts
682683
684456
  function escapeHtml2(text2) {
682684
684457
  return String(text2 ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
@@ -743612,6 +745385,118 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
743612
745385
  }
743613
745386
  };
743614
745387
  }
745388
+ function extractEnhancedPrompt(raw) {
745389
+ const text2 = raw.trim();
745390
+ if (!text2) return null;
745391
+ const tryParse = (candidate) => {
745392
+ try {
745393
+ const obj = JSON.parse(candidate);
745394
+ const v = obj["enhancedPrompt"] ?? obj["enhanced_prompt"] ?? obj["prompt"] ?? obj["result"];
745395
+ return typeof v === "string" && v.trim() ? v : null;
745396
+ } catch {
745397
+ return null;
745398
+ }
745399
+ };
745400
+ const direct = tryParse(text2);
745401
+ if (direct) return direct;
745402
+ const fenced = text2.match(/```(?:json)?\s*([\s\S]*?)```/i);
745403
+ if (fenced?.[1]) {
745404
+ const f2 = tryParse(fenced[1].trim());
745405
+ if (f2) return f2;
745406
+ }
745407
+ const brace = text2.match(/\{[\s\S]*\}/);
745408
+ if (brace?.[0]) {
745409
+ const b = tryParse(brace[0]);
745410
+ if (b) return b;
745411
+ }
745412
+ const keyed = text2.match(
745413
+ /"enhanced_?[Pp]rompt"\s*:\s*"((?:[^"\\]|\\.)*)"/
745414
+ );
745415
+ if (keyed?.[1]) {
745416
+ try {
745417
+ return JSON.parse('"' + keyed[1] + '"');
745418
+ } catch {
745419
+ return keyed[1];
745420
+ }
745421
+ }
745422
+ if (!text2.startsWith("{") && !text2.startsWith("[")) return text2;
745423
+ return null;
745424
+ }
745425
+ async function enhancePromptViaInference(seed, ctx3) {
745426
+ const seedText = seed.trim();
745427
+ if (!seedText) return null;
745428
+ let backend;
745429
+ try {
745430
+ if (ctx3.config.backendType === "nexus") {
745431
+ const nexusTool = new NexusTool(ctx3.repoRoot);
745432
+ const peer = ctx3.config.backendUrl.startsWith("peer://") ? ctx3.config.backendUrl.slice(7) : void 0;
745433
+ backend = new NexusAgenticBackend(
745434
+ nexusTool.sendCommand.bind(nexusTool),
745435
+ ctx3.config.model,
745436
+ peer,
745437
+ ctx3.config.apiKey
745438
+ );
745439
+ } else {
745440
+ backend = new OllamaAgenticBackend(
745441
+ ctx3.config.backendUrl,
745442
+ ctx3.config.model,
745443
+ ctx3.config.apiKey
745444
+ );
745445
+ }
745446
+ } catch {
745447
+ return null;
745448
+ }
745449
+ const recent = ctx3.recentHistory.filter((h) => h && h.trim()).slice(0, 5).map((h, i2) => ` ${i2 + 1}. ${h.trim().slice(0, 240)}`).join("\n");
745450
+ let runtimeCtx = "";
745451
+ try {
745452
+ runtimeCtx = buildConversationRuntimeContext(/* @__PURE__ */ new Date(), ctx3.repoRoot);
745453
+ } catch {
745454
+ runtimeCtx = "";
745455
+ }
745456
+ const userPrompt = [
745457
+ "Expand the SEED PROMPT below into a comprehensive, precise, self-contained instruction set for an agentic coding assistant.",
745458
+ "Preserve the user's original intent exactly. Do NOT answer or solve it, do NOT invent unrelated scope.",
745459
+ "Clarify the goal, surface implied requirements, relevant constraints, edge cases, and concrete acceptance criteria.",
745460
+ "Fold in only the session context that is actually relevant. Keep it phrased as an instruction in the user's voice.",
745461
+ "Return no preamble and no meta-commentary about the prompt itself.",
745462
+ ctx3.activeGoal ? `
745463
+ Task currently in progress: ${ctx3.activeGoal.slice(0, 400)}` : "",
745464
+ recent ? `
745465
+ Recent prompts this session (newest first):
745466
+ ${recent}` : "",
745467
+ runtimeCtx ? `
745468
+ Session/runtime context:
745469
+ ${runtimeCtx}` : "",
745470
+ `
745471
+ SEED PROMPT:
745472
+ ${seedText}`
745473
+ ].filter(Boolean).join("\n");
745474
+ try {
745475
+ const resp = await backend.chatCompletion({
745476
+ messages: [
745477
+ {
745478
+ role: "system",
745479
+ content: `You are a prompt-expansion engine. You rewrite a user's short seed prompt into a richer, unambiguous instruction that fully captures their intent. Return strict JSON only: {"enhancedPrompt": string}.`
745480
+ },
745481
+ { role: "user", content: userPrompt }
745482
+ ],
745483
+ tools: [],
745484
+ temperature: 0.4,
745485
+ maxTokens: 1400,
745486
+ timeoutMs: 6e4,
745487
+ think: false,
745488
+ responseFormat: { type: "json_object" }
745489
+ });
745490
+ const rawContent2 = resp.choices?.[0]?.message?.content ?? "";
745491
+ if (!rawContent2) return null;
745492
+ const enhanced = extractEnhancedPrompt(rawContent2);
745493
+ if (!enhanced) return null;
745494
+ const clean5 = enhanced.trim();
745495
+ return clean5 && clean5 !== seedText ? clean5 : null;
745496
+ } catch {
745497
+ return null;
745498
+ }
745499
+ }
743615
745500
  async function startInteractive(config, repoPath2) {
743616
745501
  const repoRoot = resolve74(repoPath2 ?? cwd());
743617
745502
  try {
@@ -745196,6 +747081,20 @@ This is an independent background session started from /background.`
745196
747081
  }
745197
747082
  })();
745198
747083
  });
747084
+ statusBar.setInputMutator((line, cursor) => {
747085
+ try {
747086
+ rl.setLine(line, cursor);
747087
+ } catch {
747088
+ }
747089
+ });
747090
+ statusBar.setEnhanceHandler(async (seedPrompt) => {
747091
+ return enhancePromptViaInference(seedPrompt, {
747092
+ config: currentConfig,
747093
+ repoRoot,
747094
+ recentHistory: savedHistory,
747095
+ activeGoal: activeTask ? lastSubmittedPrompt : void 0
747096
+ });
747097
+ });
745199
747098
  if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
745200
747099
  process.stdin.setRawMode(true);
745201
747100
  }
@@ -748712,6 +750611,7 @@ ${result.content.slice(0, 2e3)}${result.content.length > 2e3 ? "\n[truncated]" :
748712
750611
  };
748713
750612
  };
748714
750613
  rl.on("line", (line) => {
750614
+ statusBar.resetEnhance?.();
748715
750615
  if (!setupReady) return;
748716
750616
  idleMemoryMaintenance?.notifyActivity();
748717
750617
  persistHistoryLine(line);
@@ -749704,6 +751604,7 @@ ${c3.dim("(Use /quit to exit)")}
749704
751604
  showPrompt();
749705
751605
  });
749706
751606
  _escapeHandler = () => {
751607
+ statusBar.resetEnhance?.();
749707
751608
  if (!activeTask && statusBar.activeViewId !== "main") {
749708
751609
  statusBar.switchToView("main");
749709
751610
  statusBar.beginContentWrite();
@@ -750214,6 +752115,7 @@ var init_interactive = __esm({
750214
752115
  init_memory_paths();
750215
752116
  init_visual_sensor_guidance();
750216
752117
  init_live_sensors();
752118
+ init_conversation_context();
750217
752119
  init_dist8();
750218
752120
  init_dist8();
750219
752121
  init_dist8();