token-harness 0.1.25 → 0.1.26

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/token-harness.mjs CHANGED
@@ -9862,7 +9862,7 @@ var TOOL_VERSION;
9862
9862
  var init_version2 = __esm({
9863
9863
  "apps/cli/dist/src/version.js"() {
9864
9864
  "use strict";
9865
- TOOL_VERSION = "0.1.25";
9865
+ TOOL_VERSION = "0.1.26";
9866
9866
  }
9867
9867
  });
9868
9868
 
@@ -11923,6 +11923,50 @@ var init_windows_command_line = __esm({
11923
11923
  import { spawn } from "node:child_process";
11924
11924
  import { win32 as win324 } from "node:path";
11925
11925
  import process3 from "node:process";
11926
+ function launchGuidedApplication(input) {
11927
+ return new Promise((resolve, reject) => {
11928
+ const child = spawn(input.executable, [input.entryScript, "ui", "--no-open"], {
11929
+ cwd: input.cwd,
11930
+ env: minimalChildEnvironment({ facts: input.facts, ambient: input.env }),
11931
+ shell: false,
11932
+ windowsHide: true,
11933
+ detached: true,
11934
+ stdio: ["ignore", "ignore", "ignore", "ipc"]
11935
+ });
11936
+ let settled = false;
11937
+ const finish5 = (url) => {
11938
+ if (settled)
11939
+ return;
11940
+ settled = true;
11941
+ clearTimeout(timer);
11942
+ if (child.connected)
11943
+ child.disconnect();
11944
+ if (url === null) {
11945
+ child.kill();
11946
+ reject(new Error("The updated app could not start. The current dashboard remains open."));
11947
+ } else {
11948
+ child.unref();
11949
+ resolve(url);
11950
+ }
11951
+ };
11952
+ const timer = setTimeout(() => finish5(null), input.timeoutMs ?? 2e4);
11953
+ child.once("error", () => finish5(null));
11954
+ child.once("exit", () => finish5(null));
11955
+ child.on("message", (message) => {
11956
+ if (message === null || typeof message !== "object")
11957
+ return;
11958
+ const value3 = message;
11959
+ if (value3["type"] !== "token-harness-guide-ready" || typeof value3["url"] !== "string")
11960
+ return;
11961
+ try {
11962
+ const url = new URL(value3["url"]);
11963
+ if (url.protocol === "http:" && url.hostname === "127.0.0.1" && url.port !== "" && url.pathname === "/" && url.search === "" && url.hash === "" && url.username === "" && url.password === "")
11964
+ finish5(url.href);
11965
+ } catch {
11966
+ }
11967
+ });
11968
+ });
11969
+ }
11926
11970
  function boundedCapture(limit) {
11927
11971
  const chunks = [];
11928
11972
  let size = 0;
@@ -14819,7 +14863,7 @@ function record5(value3) {
14819
14863
  function tuple(event, matcher, command) {
14820
14864
  return JSON.stringify([event, matcher, command]);
14821
14865
  }
14822
- async function readCodexHookEnablement(context, config) {
14866
+ async function readCodexHookEnablement(context, config, routingOnly = false) {
14823
14867
  const expected = [];
14824
14868
  try {
14825
14869
  const stat3 = await context.fs.stat(config.path);
@@ -14831,8 +14875,15 @@ async function readCodexHookEnablement(context, config) {
14831
14875
  return null;
14832
14876
  for (const [event, native] of [
14833
14877
  ["PreToolUse", "preToolUse"],
14834
- ["PostToolUse", "postToolUse"]
14878
+ ["PostToolUse", "postToolUse"],
14879
+ ...routingOnly ? [
14880
+ ["UserPromptSubmit", "userPromptSubmit"],
14881
+ ["SubagentStart", "subagentStart"],
14882
+ ["SubagentStop", "subagentStop"]
14883
+ ] : []
14835
14884
  ]) {
14885
+ if (routingOnly && !["UserPromptSubmit", "SubagentStart", "SubagentStop"].includes(event))
14886
+ continue;
14836
14887
  const entries = parsed["hooks"][event];
14837
14888
  if (!Array.isArray(entries))
14838
14889
  continue;
@@ -14841,7 +14892,7 @@ async function readCodexHookEnablement(context, config) {
14841
14892
  continue;
14842
14893
  const matcher = typeof entry["matcher"] === "string" ? entry["matcher"] : null;
14843
14894
  for (const handler of entry["hooks"]) {
14844
- if (record5(handler) && handler["type"] === "command" && typeof handler["command"] === "string") {
14895
+ if (record5(handler) && handler["type"] === "command" && typeof handler["command"] === "string" && (!routingOnly || handler["command"].includes("__internal-prompt-router"))) {
14845
14896
  expected.push(tuple(native, matcher, handler["command"]));
14846
14897
  }
14847
14898
  }
@@ -16737,7 +16788,13 @@ var init_pi = __esm({
16737
16788
  });
16738
16789
 
16739
16790
  // packages/adapters/dist/src/harnesses/native-prompt-routing.js
16740
- function nativePromptRoutingHookEntries(harness, executable = "token-harness") {
16791
+ function nativePromptRoutingVersionSupported(harness, version3) {
16792
+ const parsed = version3 === null ? null : parseSemanticVersion(version3);
16793
+ if (parsed === null || parsed.prerelease !== null)
16794
+ return false;
16795
+ return harness === "codex" ? parsed.major === 0 && (parsed.minor === 159 && parsed.patch <= 1 || parsed.minor === 160 && parsed.patch === 0) : harness === "claude" && parsed.major === 2 && parsed.minor === 1 && parsed.patch >= 274 && parsed.patch <= 288;
16796
+ }
16797
+ function nativePromptRoutingHookEntries(harness, executable = "token-harness", platform = "linux") {
16741
16798
  return NATIVE_PROMPT_ROUTING_EVENTS.map(({ eventName, commandEvent }) => {
16742
16799
  if (harness === "codex") {
16743
16800
  const command = `${executable} __internal-prompt-router codex ${commandEvent}`;
@@ -16751,7 +16808,11 @@ function nativePromptRoutingHookEntries(harness, executable = "token-harness") {
16751
16808
  handler2["additionalContextLimit"] = 500;
16752
16809
  return { eventName, value: { hooks: [handler2] } };
16753
16810
  }
16754
- const handler = {
16811
+ const handler = platform === "windows" ? {
16812
+ type: "command",
16813
+ command: `${executable} __internal-prompt-router claude ${commandEvent}`,
16814
+ timeout: 10
16815
+ } : {
16755
16816
  type: "command",
16756
16817
  command: executable,
16757
16818
  args: ["__internal-prompt-router", "claude", commandEvent],
@@ -16764,6 +16825,7 @@ var NATIVE_PROMPT_ROUTING_EVENTS;
16764
16825
  var init_native_prompt_routing = __esm({
16765
16826
  "packages/adapters/dist/src/harnesses/native-prompt-routing.js"() {
16766
16827
  "use strict";
16828
+ init_src();
16767
16829
  NATIVE_PROMPT_ROUTING_EVENTS = [
16768
16830
  { eventName: "UserPromptSubmit", commandEvent: "prompt-submit" },
16769
16831
  { eventName: "SubagentStart", commandEvent: "subagent-start" },
@@ -16797,6 +16859,7 @@ var init_harnesses = __esm({
16797
16859
  init_pi();
16798
16860
  init_claude();
16799
16861
  init_native_prompt_routing();
16862
+ init_codex_hooks();
16800
16863
  HARNESS_ADAPTERS = [
16801
16864
  claudeAdapter,
16802
16865
  codexAdapter,
@@ -20343,7 +20406,20 @@ ${help.stderr}`) : { compact: false, json: false };
20343
20406
  detail: ready ? `mcptoon ${version3} exposes the compact/JSON CLI surfaces used by the managed integration` : `mcptoon ${version3} no longer advertises the compact/JSON CLI surfaces required by the managed integration`
20344
20407
  };
20345
20408
  }
20346
- function mcptoonInstallAction() {
20409
+ async function mcptoonInstallChannel(context) {
20410
+ for (const channel of ["pipx", "uv"]) {
20411
+ const result6 = await context.runner.run({
20412
+ executable: channel,
20413
+ args: ["--version"],
20414
+ cwd: context.projectRoot,
20415
+ timeoutMs: 2e4
20416
+ });
20417
+ if (result6.failure === null && result6.exitCode === 0)
20418
+ return channel;
20419
+ }
20420
+ return null;
20421
+ }
20422
+ function mcptoonInstallAction(channel) {
20347
20423
  return {
20348
20424
  kind: "package-manager-install",
20349
20425
  id: `mcptoon:install:${MCPTOON_REVIEWED_INSTALL_VERSION}`,
@@ -20351,12 +20427,14 @@ function mcptoonInstallAction() {
20351
20427
  requiresNetwork: true,
20352
20428
  requiresElevation: false,
20353
20429
  affectedPaths: [],
20354
- affectedProcesses: ["pipx"],
20355
- preconditions: ["pipx remains runnable and the reviewed mcptoon release remains installable"],
20356
- postconditions: [`mcptoon ${MCPTOON_REVIEWED_INSTALL_VERSION} is installed through pipx`],
20430
+ affectedProcesses: [channel],
20431
+ preconditions: [
20432
+ `${channel} remains runnable and the reviewed mcptoon release remains installable`
20433
+ ],
20434
+ postconditions: [`mcptoon ${MCPTOON_REVIEWED_INSTALL_VERSION} is installed through ${channel}`],
20357
20435
  rollbackData: "package-inventory",
20358
- explanation: `Install reviewed mcptoon ${MCPTOON_REVIEWED_INSTALL_VERSION} in an isolated pipx environment`,
20359
- packageManager: "pipx",
20436
+ explanation: `Install reviewed mcptoon ${MCPTOON_REVIEWED_INSTALL_VERSION} in an isolated ${channel} environment`,
20437
+ packageManager: channel,
20360
20438
  packageName: "mcptoon",
20361
20439
  version: MCPTOON_REVIEWED_INSTALL_VERSION
20362
20440
  };
@@ -20577,13 +20655,8 @@ async function planMcptoonManagedActivation(context, harness) {
20577
20655
  if (activation.actions.length === 0 && !activationSatisfied) {
20578
20656
  return activation;
20579
20657
  }
20580
- const pipx = await context.runner.run({
20581
- executable: "pipx",
20582
- args: ["--version"],
20583
- cwd: context.projectRoot,
20584
- timeoutMs: 2e4
20585
- });
20586
- if (pipx.failure !== null || pipx.exitCode !== 0) {
20658
+ const channel = await mcptoonInstallChannel(context);
20659
+ if (channel === null) {
20587
20660
  return {
20588
20661
  harness,
20589
20662
  target: activation.target,
@@ -20594,22 +20667,22 @@ async function planMcptoonManagedActivation(context, harness) {
20594
20667
  severity: "warning",
20595
20668
  code: "mcptoon-pipx-unavailable",
20596
20669
  subject: harness,
20597
- message: "mcptoon is absent and the isolated pipx installer is not available",
20598
- remediation: "Install pipx, then refresh Token Harness; Token Harness will not bootstrap a Python package manager implicitly"
20670
+ message: "mcptoon needs an isolated installer: pipx or uv",
20671
+ remediation: "Install pipx or uv, then Refresh to enable Install mcptoon. See Installation options for the platform instructions."
20599
20672
  })
20600
20673
  ]
20601
20674
  };
20602
20675
  }
20603
20676
  return {
20604
20677
  ...activation,
20605
- actions: [mcptoonInstallAction(), ...activation.actions],
20678
+ actions: [mcptoonInstallAction(channel), ...activation.actions],
20606
20679
  diagnostics: [
20607
20680
  ...activation.diagnostics,
20608
20681
  diagnostic({
20609
20682
  severity: "info",
20610
20683
  code: "mcptoon-managed-install-planned",
20611
20684
  subject: harness,
20612
- message: `mcptoon is absent; install reviewed ${MCPTOON_REVIEWED_INSTALL_VERSION} through pipx before enabling agent guidance`,
20685
+ message: `mcptoon is absent; install reviewed ${MCPTOON_REVIEWED_INSTALL_VERSION} through ${channel} before enabling agent guidance`,
20613
20686
  remediation: null
20614
20687
  })
20615
20688
  ]
@@ -20743,20 +20816,15 @@ async function mcptoonDetection(context) {
20743
20816
  configuredHarnesses.push(harness);
20744
20817
  }
20745
20818
  }
20746
- const pipx = observation.absent ? await context.runner.run({
20747
- executable: "pipx",
20748
- args: ["--version"],
20749
- cwd: context.projectRoot,
20750
- timeoutMs: 2e4
20751
- }) : null;
20752
- const canInstall = observation.absent && pipx !== null && pipx.failure === null && pipx.exitCode === 0;
20819
+ const channel = observation.absent ? await mcptoonInstallChannel(context) : null;
20820
+ const canInstall = observation.absent && channel !== null;
20753
20821
  const warnings = observation.absent && !canInstall ? [
20754
20822
  diagnostic({
20755
20823
  severity: "warning",
20756
20824
  code: "mcptoon-pipx-unavailable",
20757
20825
  subject: "mcptoon",
20758
- message: "mcptoon is not installed and pipx is not available in this terminal",
20759
- remediation: "Install pipx or make it available on PATH, then refresh. Token Harness will use it to install the reviewed mcptoon build."
20826
+ message: "mcptoon is not installed; pipx or uv is required",
20827
+ remediation: "Install pipx or uv, then Refresh to enable Install mcptoon. Open Installation options for your platform."
20760
20828
  })
20761
20829
  ] : !observation.absent && !observation.ready ? [warning("mcptoon-provider-capability-unavailable", "mcptoon", observation.detail)] : [];
20762
20830
  return {
@@ -20764,7 +20832,7 @@ async function mcptoonDetection(context) {
20764
20832
  state: observation.absent ? "absent" : configuredHarnesses.length > 0 ? "configured" : "installed",
20765
20833
  version: observation.version,
20766
20834
  executable: observation.executable,
20767
- installationChannel: observation.absent ? "pipx" : null,
20835
+ installationChannel: observation.absent ? channel : null,
20768
20836
  versionVerdict: versionVerdict(observation.version, MCPTOON_REVIEWED_BENCHMARK_VERSION),
20769
20837
  configuredHarnesses,
20770
20838
  unmanagedHarnessesConfigured: [],
@@ -20975,6 +21043,16 @@ var init_managed_optimization_tools = __esm({
20975
21043
  requiresNetwork: true,
20976
21044
  requiresElevation: false,
20977
21045
  digestAvailable: false
21046
+ },
21047
+ {
21048
+ id: "uv",
21049
+ packageId: "mcptoon",
21050
+ kind: "uv",
21051
+ priority: 1,
21052
+ platforms: ["windows", "macos", "linux"],
21053
+ requiresNetwork: true,
21054
+ requiresElevation: false,
21055
+ digestAvailable: false
20978
21056
  }
20979
21057
  ],
20980
21058
  metrics: { source: "none", mode: "unavailable", locations: [] },
@@ -22989,9 +23067,6 @@ var init_argv = __esm({
22989
23067
  function isHarness(value3) {
22990
23068
  return value3 === "claude" || value3 === "codex";
22991
23069
  }
22992
- function expectedVersions(harness) {
22993
- return harness === "codex" ? ["0.159.0", "0.160.0"] : ["2.1.274", "2.1.288"];
22994
- }
22995
23070
  function configTarget(input) {
22996
23071
  if (!isHarness(input.harness) || input.home === null)
22997
23072
  return null;
@@ -23013,8 +23088,8 @@ function configTarget(input) {
23013
23088
  fileContext
23014
23089
  };
23015
23090
  }
23016
- function hookEntries(harness) {
23017
- return nativePromptRoutingHookEntries(harnessId(harness), "token-harness");
23091
+ function hookEntries(harness, platform = "linux") {
23092
+ return nativePromptRoutingHookEntries(harnessId(harness), "token-harness", platform);
23018
23093
  }
23019
23094
  function asRecord(value3) {
23020
23095
  return typeof value3 === "object" && value3 !== null && !Array.isArray(value3) ? value3 : null;
@@ -23054,13 +23129,13 @@ function containsRouterCommand(value3, harness) {
23054
23129
  if (harness === "codex")
23055
23130
  return [handler["command"], handler["commandWindows"]].some((command) => typeof command === "string" && command.includes(ROUTE_MARKER));
23056
23131
  const args = handler["args"];
23057
- return handler["command"] === "token-harness" && Array.isArray(args) && args[0] === ROUTE_MARKER;
23132
+ return typeof handler["command"] === "string" && handler["command"].includes(ROUTE_MARKER) || handler["command"] === "token-harness" && Array.isArray(args) && args[0] === ROUTE_MARKER;
23058
23133
  });
23059
23134
  }
23060
- function configHasExactRouter(hooks, harness) {
23135
+ function configHasExactRouter(hooks, harness, platform) {
23061
23136
  let exactCount = 0;
23062
23137
  let routeCount = 0;
23063
- for (const expected of hookEntries(harness)) {
23138
+ for (const expected of hookEntries(harness, platform)) {
23064
23139
  const live = hooks[expected.eventName];
23065
23140
  const entries = Array.isArray(live) ? live : [];
23066
23141
  const routeEntries = entries.filter((entry) => containsRouterCommand(entry, harness));
@@ -23069,13 +23144,13 @@ function configHasExactRouter(hooks, harness) {
23069
23144
  exactCount += 1;
23070
23145
  }
23071
23146
  return {
23072
- complete: exactCount === hookEntries(harness).length,
23073
- partial: routeCount > 0 && exactCount !== hookEntries(harness).length,
23147
+ complete: exactCount === hookEntries(harness, platform).length,
23148
+ partial: routeCount > 0 && exactCount !== hookEntries(harness, platform).length,
23074
23149
  conflict: routeCount > exactCount
23075
23150
  };
23076
23151
  }
23077
- function routerOwnedArtifacts(journals, path, harness) {
23078
- const expected = hookEntries(harness);
23152
+ function routerOwnedArtifacts(journals, path, harness, platform) {
23153
+ const expected = hookEntries(harness, platform);
23079
23154
  for (const journal of journals) {
23080
23155
  const disabledHere = journal.entries.some((entry) => entry.actionId.startsWith(`native-prompt-routing:${harness}:disable:`) && entry.snapshots.some((snapshot) => snapshot.path === path));
23081
23156
  if (disabledHere && journal.outcome === "committed")
@@ -23114,14 +23189,14 @@ async function planNativePromptRoutingInstall(input) {
23114
23189
  }));
23115
23190
  return { target: null, actions: [], diagnostics };
23116
23191
  }
23117
- if (!expectedVersions(target.harness).includes(target.version ?? "")) {
23192
+ if (!nativePromptRoutingVersionSupported(harnessId(target.harness), target.version)) {
23118
23193
  diagnostics.push(diagnostic({
23119
23194
  severity: "warning",
23120
23195
  code: "prompt-routing-version-unverified",
23121
23196
  subject: target.harness,
23122
- message: `Native prompt routing has no hook fixture for ${target.harness} ${target.version ?? "unknown"}`,
23197
+ message: `Routing is not supported for ${target.harness} ${target.version ?? "(version unknown)"}. Check Token Harness updates in Health and updates, then retry.`,
23123
23198
  path: target.path,
23124
- remediation: "Refresh Token Harness after the installed harness hook schema is fixture-tested"
23199
+ remediation: "Check for Token Harness updates; this agent version needs a verified hook fixture"
23125
23200
  }));
23126
23201
  return { target: target.path, actions: [], diagnostics };
23127
23202
  }
@@ -23171,7 +23246,7 @@ async function planNativePromptRoutingInstall(input) {
23171
23246
  }
23172
23247
  hooks = parsed.hooks;
23173
23248
  }
23174
- const existing = configHasExactRouter(hooks, target.harness);
23249
+ const existing = configHasExactRouter(hooks, target.harness, input.facts.os);
23175
23250
  if (existing.complete) {
23176
23251
  diagnostics.push(diagnostic({
23177
23252
  severity: "info",
@@ -23183,7 +23258,10 @@ async function planNativePromptRoutingInstall(input) {
23183
23258
  }));
23184
23259
  return { target: target.path, actions: [], diagnostics };
23185
23260
  }
23186
- if (existing.partial || existing.conflict) {
23261
+ const legacy = target.harness === "claude" && input.facts.os === "windows" ? configHasExactRouter(hooks, target.harness, "linux") : null;
23262
+ const legacyOwned = legacy?.complete && !legacy.conflict ? routerOwnedArtifacts(await journalsFor({ fs: input.fs, stateRoot: input.stateRoot ?? null }), target.path, target.harness, "linux") : [];
23263
+ const repair = legacyOwned.length === 3;
23264
+ if ((existing.partial || existing.conflict) && !repair) {
23187
23265
  diagnostics.push(diagnostic({
23188
23266
  severity: "error",
23189
23267
  code: "prompt-routing-existing-hook-conflict",
@@ -23194,7 +23272,7 @@ async function planNativePromptRoutingInstall(input) {
23194
23272
  }));
23195
23273
  return { target: target.path, actions: [], diagnostics };
23196
23274
  }
23197
- const entries = hookEntries(target.harness);
23275
+ const entries = hookEntries(target.harness, input.facts.os);
23198
23276
  const action = {
23199
23277
  kind: "merge-json",
23200
23278
  id: actionId(target.harness, "enable", "all"),
@@ -23220,7 +23298,8 @@ async function planNativePromptRoutingInstall(input) {
23220
23298
  })),
23221
23299
  createIfMissing: true
23222
23300
  };
23223
- return { target: target.path, actions: [action], diagnostics };
23301
+ const removals = repair ? await planNativePromptRoutingRemoval({ ...input, stateRoot: input.stateRoot ?? null }) : null;
23302
+ return { target: target.path, actions: [...removals?.actions ?? [], action], diagnostics };
23224
23303
  }
23225
23304
  async function planNativePromptRoutingRemoval(input) {
23226
23305
  const diagnostics = [];
@@ -23235,9 +23314,13 @@ async function planNativePromptRoutingRemoval(input) {
23235
23314
  }));
23236
23315
  return { target: target?.path ?? null, actions: [], diagnostics };
23237
23316
  }
23238
- const expected = hookEntries(target.harness);
23317
+ let expected = hookEntries(target.harness, input.facts.os);
23239
23318
  const journals = await journalsFor({ fs: input.fs, stateRoot: input.stateRoot });
23240
- const artifacts = routerOwnedArtifacts(journals, target.path, target.harness);
23319
+ let artifacts = routerOwnedArtifacts(journals, target.path, target.harness, input.facts.os);
23320
+ if (artifacts.length === 0 && target.harness === "claude" && input.facts.os === "windows") {
23321
+ expected = hookEntries(target.harness, "linux");
23322
+ artifacts = routerOwnedArtifacts(journals, target.path, target.harness, "linux");
23323
+ }
23241
23324
  const actions = expected.flatMap((entry) => {
23242
23325
  const pointer = `hooks.${entry.eventName}`;
23243
23326
  const targetArtifact = artifacts.find((artifact) => artifact.kind === "owned-json-entry" && artifact.pointer === pointer && artifact.valueDigest === jsonValueDigest(entry.value));
@@ -23381,7 +23464,9 @@ async function observeNativePromptRouting(input) {
23381
23464
  subagentsStopped: 0,
23382
23465
  reportedModels: [],
23383
23466
  lastObservedAt: null,
23384
- receiptState: "unavailable"
23467
+ receiptState: "unavailable",
23468
+ enablement: "unknown",
23469
+ verificationTier: "config-only"
23385
23470
  };
23386
23471
  const target = configTarget({ ...input, harness: input.harness });
23387
23472
  if (target === null)
@@ -23442,7 +23527,23 @@ async function observeNativePromptRouting(input) {
23442
23527
  receiptState: eventResult.state
23443
23528
  };
23444
23529
  }
23445
- const match = configHasExactRouter(hooks, harness);
23530
+ const match = configHasExactRouter(hooks, harness, input.facts.os);
23531
+ if (harness === "claude" && input.facts.os === "windows" && (match.partial || match.conflict)) {
23532
+ const legacy = configHasExactRouter(hooks, harness, "linux");
23533
+ const owned = routerOwnedArtifacts(await journalsFor(input), target.path, harness, "linux");
23534
+ if (legacy.complete && !legacy.conflict && owned.length === 3)
23535
+ return {
23536
+ ...base,
23537
+ ...summary,
23538
+ state: "managed",
23539
+ label: "Repair required",
23540
+ configured: false,
23541
+ configPath: target.path,
23542
+ needsRepair: true,
23543
+ receiptState: eventResult.state,
23544
+ detail: "The installed routing hook cannot launch the Windows npm command. Choose Repair routing once; future prompts run automatically."
23545
+ };
23546
+ }
23446
23547
  if (match.conflict || match.partial) {
23447
23548
  return {
23448
23549
  ...base,
@@ -23466,16 +23567,54 @@ async function observeNativePromptRouting(input) {
23466
23567
  receiptState: eventResult.state
23467
23568
  };
23468
23569
  }
23469
- const artifacts = routerOwnedArtifacts(await journalsFor(input), target.path, harness);
23470
- const state = artifacts.length === hookEntries(harness).length ? "managed" : "external";
23570
+ const artifacts = routerOwnedArtifacts(await journalsFor(input), target.path, harness, input.facts.os);
23571
+ const state = artifacts.length === hookEntries(harness, input.facts.os).length ? "managed" : "external";
23471
23572
  const hasRuntimeReceipt = summary.promptSubmissions > 0;
23472
- const label = state === "external" ? hasRuntimeReceipt ? "Runtime observed \xB7 external" : "Enabled externally" : hasRuntimeReceipt ? "Runtime observed" : harness === "codex" ? "Configured \xB7 trust or runtime pending" : "Configured \xB7 runtime pending";
23473
- const detail2 = summary.promptSubmissions > 0 ? `${String(summary.promptSubmissions)} prompt hook(s), ${String(summary.subagentsStarted)} native agent start(s), ${String(summary.subagentsStopped)} stop(s) observed in this project during the last 30 days.${eventResult.state === "limited" ? " Counts are partial because the local receipt scan reached its safety limit." : eventResult.state === "unavailable" ? " Local runtime receipts could not be read." : ""}` : harness === "codex" ? "The hook is configured. Review and trust it in Codex with /hooks, then submit a prompt to produce a runtime receipt." : "The hook is configured. Start a new Claude Code session, submit a prompt, and Token Harness will show the runtime receipt.";
23573
+ let enablement = "unknown";
23574
+ if (harness === "codex") {
23575
+ const declaration = findHarnessAdapter(harnessId(harness)).manifest.configFiles.find((file) => file.parser === "json" && file.scope === "user");
23576
+ const check = await readCodexHookEnablement(target.fileContext, {
23577
+ declaration,
23578
+ path: target.path,
23579
+ exists: true,
23580
+ parsed: true,
23581
+ configuredPoints: [],
23582
+ matchers: [],
23583
+ commands: []
23584
+ }, true);
23585
+ if (check?.status === "pass")
23586
+ enablement = "enabled";
23587
+ else if (check?.status === "fail")
23588
+ enablement = /[1-9]\d* untrusted/.test(check.summary) ? "untrusted" : "disabled";
23589
+ } else {
23590
+ const adapter = findHarnessAdapter(harnessId(harness));
23591
+ let disabled = false;
23592
+ let readable = true;
23593
+ for (const declaration of adapter.manifest.configFiles) {
23594
+ const path = resolveConfigPath(declaration, target.fileContext);
23595
+ if ((await input.fs.stat(path))?.kind !== "file")
23596
+ continue;
23597
+ try {
23598
+ const doc = asRecord(JSON.parse(DECODER4.decode(await input.fs.readFile(path))));
23599
+ if (typeof doc?.["disableAllHooks"] === "boolean")
23600
+ disabled = doc["disableAllHooks"];
23601
+ } catch {
23602
+ readable = false;
23603
+ }
23604
+ }
23605
+ enablement = readable ? disabled ? "disabled" : "enabled" : "unknown";
23606
+ }
23607
+ const blocked = enablement === "untrusted" || enablement === "disabled";
23608
+ const label = blocked ? enablement === "untrusted" ? "Authorization required" : "Hooks disabled" : hasRuntimeReceipt ? "Runtime observed" : enablement === "enabled" ? "Ready \xB7 awaiting prompt" : "Configured \xB7 check authorization";
23609
+ const scope = input.projectId === null ? "across projects" : "in this project";
23610
+ const detail2 = blocked ? harness === "codex" ? "Open Codex /hooks. Enable and trust the three Token Harness routing hooks once, then send a prompt." : "Hooks are disabled in Claude settings. Enable hooks in /hooks, then send a prompt." : hasRuntimeReceipt ? `${String(summary.promptSubmissions)} prompt callbacks, ${String(summary.subagentsStarted)} agent starts, ${String(summary.subagentsStopped)} stops ${scope} in the last 30 days. Routing runs automatically on each prompt.${eventResult.state === "limited" ? " Counts are partial." : ""}` : enablement === "enabled" ? "Ready. Send a prompt in a new session; the first callback will appear here automatically. No skill or command is needed per prompt." : harness === "codex" ? "Open Codex /hooks and check the three Token Harness routing hooks are enabled and trusted. Do this once, then send a prompt in a new session." : "Check the Claude hook settings can be read and hooks are enabled in /hooks, then send a prompt in a new session.";
23474
23611
  return {
23475
23612
  ...base,
23476
23613
  state,
23477
23614
  label,
23478
23615
  detail: detail2,
23616
+ enablement,
23617
+ verificationTier: hasRuntimeReceipt && !blocked ? "runtime-observed" : "config-only",
23479
23618
  configPath: target.path,
23480
23619
  configured: true,
23481
23620
  ...summary,
@@ -27376,7 +27515,7 @@ async function runApply(context) {
27376
27515
  now: context.now,
27377
27516
  verifyPostconditions: async () => [
27378
27517
  ...await verifyManagedIntegrationPostconditions(context, computed.managedIntegrations),
27379
- ...await verifyNativePromptRoutingPostconditions(context, actions)
27518
+ ...await verifyNativePromptRoutingPostconditions(planningContext, actions)
27380
27519
  ]
27381
27520
  });
27382
27521
  diagnostics.push(...transaction.diagnostics);
@@ -35504,7 +35643,7 @@ function guideSetupTargets(report, harness) {
35504
35643
  function explainGuideIssue(diagnostics, fallback) {
35505
35644
  const known = diagnostics.find((entry) => entry.severity === "error" && ISSUE_COPY[entry.code] !== void 0) ?? diagnostics.find((entry) => entry.severity === "warning" && ISSUE_COPY[entry.code] !== void 0) ?? diagnostics.find((entry) => entry.severity === "info" && ISSUE_COPY[entry.code] !== void 0);
35506
35645
  if (known !== void 0)
35507
- return ISSUE_COPY[known.code];
35646
+ return known.code === "prompt-routing-version-unverified" ? known.message : ISSUE_COPY[known.code];
35508
35647
  const blocked = diagnostics.find((entry) => /compatibility|unsupported|unreviewed|no-row/.test(entry.code));
35509
35648
  if (blocked !== void 0)
35510
35649
  return "The required automatic capability or safety precondition is not available in the current runtime. Your current settings are preserved.";
@@ -35853,7 +35992,7 @@ var init_guided = __esm({
35853
35992
  "codex-native-policy-shadowed": "A project or profile overrides this Codex setting. That setting belongs to you and will not be replaced.",
35854
35993
  "no-providers-registered": "No optimization provider was selected for this operation.",
35855
35994
  "prompt-routing-target-unavailable": "Token Harness could not locate a supported user-level prompt-hook settings file for this agent.",
35856
- "prompt-routing-version-unverified": "Automatic routing is not available for this agent version until its prompt-hook format has been verified.",
35995
+ "prompt-routing-version-unverified": "Update Token Harness in Health and updates, then retry routing. This agent version is not supported by this copy.",
35857
35996
  "prompt-routing-runtime-unavailable": "The Token Harness hook command could not run from this dashboard environment. Make Token Harness available on PATH, then review routing again.",
35858
35997
  "prompt-routing-target-not-file": "A non-file occupies the agent hook settings path, so Token Harness left it unchanged.",
35859
35998
  "prompt-routing-settings-unmergeable": "The current hook settings cannot be merged safely. Repair the JSON or review the hook manually.",
@@ -35947,6 +36086,8 @@ var init_guided = __esm({
35947
36086
  loading = null;
35948
36087
  readSequence = 0;
35949
36088
  busy = false;
36089
+ restartVersion = null;
36090
+ restartApplication;
35950
36091
  lastApplied = null;
35951
36092
  reading = null;
35952
36093
  cached = null;
@@ -35959,12 +36100,13 @@ var init_guided = __esm({
35959
36100
  random;
35960
36101
  observeGuidance;
35961
36102
  observeRouting;
35962
- constructor(call, now, random, observeGuidance = null, observeRouting = null) {
36103
+ constructor(call, now, random, observeGuidance = null, observeRouting = null, restartApplication = null) {
35963
36104
  this.call = call;
35964
36105
  this.now = now;
35965
36106
  this.random = random;
35966
36107
  this.observeGuidance = observeGuidance;
35967
36108
  this.observeRouting = observeRouting;
36109
+ this.restartApplication = restartApplication;
35968
36110
  }
35969
36111
  status() {
35970
36112
  return {
@@ -36604,21 +36746,40 @@ var init_guided = __esm({
36604
36746
  }
36605
36747
  this.lastApplied = null;
36606
36748
  this.invalidateObservedState();
36749
+ this.record("Re-checking health after the update.", "working");
36750
+ let health;
36751
+ try {
36752
+ health = await this.verifyIntegrations();
36753
+ } catch {
36754
+ health = {
36755
+ ok: false,
36756
+ title: "Health check needs attention",
36757
+ messages: ["Update installed; automatic health check could not finish."],
36758
+ appliedPlans: 0
36759
+ };
36760
+ }
36761
+ if (applicationTarget !== void 0)
36762
+ this.restartVersion = applicationTarget.version;
36607
36763
  const versions = approvedUpdates.map((target) => `${guideUpdateTargetName(target)} ${target.version}`).join(", ");
36608
36764
  const messages2 = [
36609
36765
  appliedCount > 0 ? `Installed and verified the approved update${approvedUpdates.length === 1 ? "" : "s"}: ${versions}.` : `The approved update${approvedUpdates.length === 1 ? " was" : "s were"} already at the target version: ${versions}.`,
36610
- ...applicationTarget === void 0 ? [] : ["Token Harness is updated on disk. Restart this app to load the new version."],
36766
+ ...applicationTarget === void 0 ? [] : [
36767
+ "Token Harness is updated. Choose Restart and re-check to load it and discover new capabilities."
36768
+ ],
36611
36769
  ...providerTargets.length === 0 ? [] : [
36612
36770
  "The active optimizer runtimes were re-read after the operation and match the approved targets.",
36613
36771
  "Reopen a coding agent if an updated optimizer requires it."
36614
36772
  ]
36615
36773
  ];
36774
+ messages2.push(health.ok ? "Health re-check completed automatically." : "Update installed; health needs attention.", ...health.messages);
36616
36775
  this.record(appliedCount > 0 ? "Approved updates installed and verified." : "Approved updates are already at their target versions.", "success");
36617
36776
  return {
36618
36777
  ok: true,
36619
36778
  title: applicationTarget !== void 0 ? "Token Harness updated" : appliedCount > 0 ? "Optimizers updated" : "Approved versions already active",
36620
36779
  messages: messages2,
36621
- appliedPlans: appliedCount
36780
+ appliedPlans: appliedCount,
36781
+ ...health.stack === void 0 ? {} : { stack: health.stack },
36782
+ restartRequired: applicationTarget !== void 0
36622
36783
  };
36623
36784
  }
36624
36785
  if (approval.operation === "candidate-apply" || approval.operation === "candidate-uninstall") {
@@ -36774,6 +36935,34 @@ var init_guided = __esm({
36774
36935
  };
36775
36936
  });
36776
36937
  }
36938
+ async routing() {
36939
+ if (this.observeRouting === null)
36940
+ return { agents: [] };
36941
+ const agents = await Promise.all(["claude", "codex"].map(async (id) => ({
36942
+ id,
36943
+ promptRouting: await this.observeRouting(id)
36944
+ })));
36945
+ if (this.cached !== null) {
36946
+ for (const agent of this.cached.value.agents) {
36947
+ const live = agents.find((item) => item.id === agent.id);
36948
+ if (live !== void 0)
36949
+ agent.promptRouting = live.promptRouting;
36950
+ }
36951
+ }
36952
+ return { agents };
36953
+ }
36954
+ async restart() {
36955
+ return this.exclusive(async () => {
36956
+ if (this.restartVersion === null || this.restartApplication === null)
36957
+ throw new GuideError(409, "Restart is available after a verified Token Harness update.");
36958
+ const installed2 = await this.call(["update"]);
36959
+ if (!sameGuideVersion(installed2.data?.application?.installed ?? null, this.restartVersion))
36960
+ throw new GuideError(409, "The installation changed. Check updates again before restarting.");
36961
+ const url = await this.restartApplication();
36962
+ this.restartVersion = null;
36963
+ return { url };
36964
+ });
36965
+ }
36777
36966
  async checkUpdates() {
36778
36967
  return this.exclusive(async () => {
36779
36968
  this.approval = null;
@@ -36892,89 +37081,90 @@ var init_guided = __esm({
36892
37081
  });
36893
37082
  }
36894
37083
  async verify() {
36895
- return this.exclusive(async () => {
36896
- this.record("Checking the configured integrations without changing them.", "working");
36897
- const messages = [];
36898
- const results = [];
36899
- let ok = true;
36900
- let healthyAtDeclaredTier = true;
36901
- const inventory = await this.call(["doctor"]);
36902
- const present = (inventory.data?.harnesses ?? []).filter((item) => item.state !== "absent" && ["claude", "codex"].includes(item.harnessId));
36903
- if (inventory.data === null) {
37084
+ return this.exclusive(() => this.verifyIntegrations());
37085
+ }
37086
+ async verifyIntegrations() {
37087
+ this.record("Checking the configured integrations without changing them.", "working");
37088
+ const messages = [];
37089
+ const results = [];
37090
+ let ok = true;
37091
+ let healthyAtDeclaredTier = true;
37092
+ const inventory = await this.call(["doctor"]);
37093
+ const present = (inventory.data?.harnesses ?? []).filter((item) => item.state !== "absent" && ["claude", "codex"].includes(item.harnessId));
37094
+ if (inventory.data === null) {
37095
+ ok = false;
37096
+ healthyAtDeclaredTier = false;
37097
+ messages.push("The installed-agent inventory could not be read. Refresh and check the local installation.");
37098
+ }
37099
+ if (present.length === 0) {
37100
+ ok = false;
37101
+ healthyAtDeclaredTier = false;
37102
+ messages.push("No supported installed agent was detected, so no integration was checked.");
37103
+ }
37104
+ for (const agent of present) {
37105
+ const harness = agent.harnessId;
37106
+ this.record(`Checking ${name(harness)} configuration and available execution evidence. No settings changed.`, "working");
37107
+ const result6 = await this.call(["verify", "--harness", harness]);
37108
+ const healthy = result6.data?.healthyAtDeclaredTier === true;
37109
+ const versionWarnings = result6.diagnostics.filter((entry) => entry.severity === "warning" && (entry.code === "harness-version-unknown-newer" || entry.code === "provider-version-unknown-newer"));
37110
+ const failed = result6.data === null || result6.exitCode !== 0 || result6.diagnostics.some((entry) => entry.severity === "error" || entry.severity === "warning" && !versionWarnings.includes(entry)) || result6.data.results.some((entry) => entry.status === "degraded" || entry.status === "failed");
37111
+ if (failed)
36904
37112
  ok = false;
37113
+ if (!healthy)
36905
37114
  healthyAtDeclaredTier = false;
36906
- messages.push("The installed-agent inventory could not be read. Refresh and check the local installation.");
37115
+ if (result6.data !== null)
37116
+ results.push(...result6.data.results);
37117
+ const prefix = `${name(harness)}: `;
37118
+ if (result6.data === null) {
37119
+ messages.push(prefix + "the verification report could not be read. Refresh and check the local installation.");
37120
+ } else if (healthy) {
37121
+ messages.push(prefix + "the available integration checks passed. This is not proof that every command was reduced.");
37122
+ } else if (failed) {
37123
+ messages.push(prefix + "a known integration check failed. Review the specific check before changing setup.");
37124
+ } else if (result6.data.results.length === 0) {
37125
+ messages.push(prefix + "the agent is detected, but no managed optimizer connection is present to verify. Review setup only if you want to connect one.");
37126
+ } else {
37127
+ const pendingProviders = [
37128
+ ...new Set(result6.data.results.filter((entry) => entry.status === "not-applicable").map((entry) => name(entry.providerId)))
37129
+ ];
37130
+ const subject = pendingProviders.length > 0 ? pendingProviders.join(" and ") : "Some integrations";
37131
+ messages.push(`${prefix}${subject} have not produced enough attributable runtime evidence for ${name(harness)} yet. This is an evidence gap, not a finding that the setup is broken. If you do not use this agent on this machine, no action is required.`);
36907
37132
  }
36908
- if (present.length === 0) {
36909
- ok = false;
36910
- healthyAtDeclaredTier = false;
36911
- messages.push("No supported installed agent was detected, so no integration was checked.");
37133
+ if (versionWarnings.length > 0) {
37134
+ messages.push(prefix + "the installed version is newer than Token Harness\u2019s recorded compatibility sample; read-only checks can continue, but review the version before changing its integration.");
36912
37135
  }
36913
- for (const agent of present) {
36914
- const harness = agent.harnessId;
36915
- this.record(`Checking ${name(harness)} configuration and available execution evidence. No settings changed.`, "working");
36916
- const result6 = await this.call(["verify", "--harness", harness]);
36917
- const healthy = result6.data?.healthyAtDeclaredTier === true;
36918
- const versionWarnings = result6.diagnostics.filter((entry) => entry.severity === "warning" && (entry.code === "harness-version-unknown-newer" || entry.code === "provider-version-unknown-newer"));
36919
- const failed = result6.data === null || result6.exitCode !== 0 || result6.diagnostics.some((entry) => entry.severity === "error" || entry.severity === "warning" && !versionWarnings.includes(entry)) || result6.data.results.some((entry) => entry.status === "degraded" || entry.status === "failed");
36920
- if (failed)
36921
- ok = false;
36922
- if (!healthy)
36923
- healthyAtDeclaredTier = false;
36924
- if (result6.data !== null)
36925
- results.push(...result6.data.results);
36926
- const prefix = `${name(harness)}: `;
36927
- if (result6.data === null) {
36928
- messages.push(prefix + "the verification report could not be read. Refresh and check the local installation.");
36929
- } else if (healthy) {
36930
- messages.push(prefix + "the available integration checks passed. This is not proof that every command was reduced.");
36931
- } else if (failed) {
36932
- messages.push(prefix + "a known integration check failed. Review the specific check before changing setup.");
36933
- } else if (result6.data.results.length === 0) {
36934
- messages.push(prefix + "the agent is detected, but no managed optimizer connection is present to verify. Review setup only if you want to connect one.");
36935
- } else {
36936
- const pendingProviders = [
36937
- ...new Set(result6.data.results.filter((entry) => entry.status === "not-applicable").map((entry) => name(entry.providerId)))
36938
- ];
36939
- const subject = pendingProviders.length > 0 ? pendingProviders.join(" and ") : "Some integrations";
36940
- messages.push(`${prefix}${subject} have not produced enough attributable runtime evidence for ${name(harness)} yet. This is an evidence gap, not a finding that the setup is broken. If you do not use this agent on this machine, no action is required.`);
36941
- }
36942
- if (versionWarnings.length > 0) {
36943
- messages.push(prefix + "the installed version is newer than Token Harness\u2019s recorded compatibility sample; read-only checks can continue, but review the version before changing its integration.");
37136
+ }
37137
+ if (inventory.data !== null) {
37138
+ const fingerprint = stackFingerprint(inventory.data);
37139
+ this.verification = {
37140
+ fingerprint,
37141
+ report: {
37142
+ receiptId: null,
37143
+ appliedAt: null,
37144
+ results,
37145
+ healthyAtDeclaredTier: healthyAtDeclaredTier && present.length > 0
36944
37146
  }
36945
- }
36946
- if (inventory.data !== null) {
36947
- const fingerprint = stackFingerprint(inventory.data);
36948
- this.verification = {
36949
- fingerprint,
36950
- report: {
36951
- receiptId: null,
36952
- appliedAt: null,
36953
- results,
36954
- healthyAtDeclaredTier: healthyAtDeclaredTier && present.length > 0
36955
- }
36956
- };
36957
- this.stackBase = {
36958
- detections: [...inventory.data.providers],
36959
- metrics: this.stackBase?.metrics ?? null,
36960
- drift: this.stackBase?.drift ?? [],
36961
- fingerprint
36962
- };
36963
- } else {
36964
- this.verification = null;
36965
- }
36966
- const stack = this.stackSnapshot();
36967
- if (this.cached !== null)
36968
- this.cached.value = { ...this.cached.value, stack };
36969
- this.record("Integration checks completed. No settings changed.", ok ? "success" : "attention");
36970
- return {
36971
- ok,
36972
- title: ok ? healthyAtDeclaredTier ? "Integration checks passed" : "Configuration checks complete; runtime evidence pending" : "Integration checks need attention",
36973
- messages,
36974
- appliedPlans: 0,
36975
- stack
36976
37147
  };
36977
- });
37148
+ this.stackBase = {
37149
+ detections: [...inventory.data.providers],
37150
+ metrics: this.stackBase?.metrics ?? null,
37151
+ drift: this.stackBase?.drift ?? [],
37152
+ fingerprint
37153
+ };
37154
+ } else {
37155
+ this.verification = null;
37156
+ }
37157
+ const stack = this.stackSnapshot();
37158
+ if (this.cached !== null)
37159
+ this.cached.value = { ...this.cached.value, stack };
37160
+ this.record("Integration checks completed. No settings changed.", ok ? "success" : "attention");
37161
+ return {
37162
+ ok,
37163
+ title: ok ? healthyAtDeclaredTier ? "Integration checks passed" : "Configuration checks complete; runtime evidence pending" : "Integration checks need attention",
37164
+ messages,
37165
+ appliedPlans: 0,
37166
+ stack
37167
+ };
36978
37168
  }
36979
37169
  };
36980
37170
  }
@@ -38565,7 +38755,6 @@ var init_guided_capabilities_client = __esm({
38565
38755
  return element;
38566
38756
  };
38567
38757
  const originalFetch = window.fetch.bind(window);
38568
- const managedProviders = new Set(['rtk', 'harnesstrim']);
38569
38758
  const HELP = {
38570
38759
  'claude-effort': ['Change reasoning in Claude', 'Inside Claude Code, use /effort. Token Harness keeps difficult work above its quality floor.', '/effort'],
38571
38760
  'codex-effort': ['Change reasoning in Codex', 'Inside Codex, use /model to review model and reasoning settings.', '/model'],
@@ -38848,44 +39037,16 @@ var init_guided_capabilities_client = __esm({
38848
39037
  if (!root.children.length) root.append(node('p', 'Agent details appear after a supported coding agent is detected.', 'empty'));
38849
39038
  }
38850
39039
 
38851
- function renderRemovalControls(data) {
38852
- const root = $('managed-removal-actions');
38853
- if (!root) return;
38854
- root.replaceChildren();
38855
- const removable = (data.stack?.components || []).filter(component =>
38856
- managedProviders.has(component.providerId) && (component.managedByTokenHarness || component.configured),
38857
- );
38858
- if (!removable.length) {
38859
- root.append(node('p', 'No managed configuration is currently eligible for removal.', 'caption'));
38860
- return;
38861
- }
38862
- for (const component of removable) {
38863
- const row = node('div', undefined, 'maintenance-row');
38864
- const text = node('div');
38865
- const name = component.displayName || (component.providerId === 'rtk' ? 'RTK' : 'HarnessTrim');
38866
- text.append(
38867
- node('strong', name),
38868
- node('p', component.managedByTokenHarness
38869
- ? 'Review removal of Token Harness-owned integration changes.'
38870
- : 'Check whether Token Harness owns any removable changes. The provider installation remains user-owned.', 'caption'),
38871
- );
38872
- row.append(
38873
- text,
38874
- actionButton('Review removal', () => preview(
38875
- { action: 'remove', provider: component.providerId },
38876
- 'Review removal for ' + name,
38877
- 'Remove managed integration',
38878
- 'Integration removed',
38879
- ), 'secondary'),
38880
- );
38881
- root.append(row);
38882
- }
38883
- }
39040
+ window.tokenHarnessReviewRemoval = (provider, name) => preview(
39041
+ { action: 'remove', provider },
39042
+ 'Review removal for ' + name,
39043
+ 'Remove managed setup',
39044
+ 'Managed setup removed',
39045
+ );
38884
39046
 
38885
39047
  function consumeOverview(data) {
38886
39048
  if (!data || !Array.isArray(data.agents)) return;
38887
39049
  renderAgentCapabilities(data);
38888
- renderRemovalControls(data);
38889
39050
  }
38890
39051
 
38891
39052
  window.fetch = async (...args) => {
@@ -38965,7 +39126,7 @@ var init_guided_product_client = __esm({
38965
39126
  const date = value => value ? new Date(value).toLocaleString() : 'not recorded';
38966
39127
  const VIEWS = {
38967
39128
  dashboard: ['Overview', 'Your coding agents, optimization stack, health and measured results in one place.'],
38968
- results: ['Results', 'A dashboard of optimizer results, coding-app links, quality information, and recent activity.'],
39129
+ results: ['Results', 'Measured evidence by optimizer, routing and coding app.'],
38969
39130
  };
38970
39131
  const TOOL_INFO = {
38971
39132
  rtk: {
@@ -39014,6 +39175,8 @@ var init_guided_product_client = __esm({
39014
39175
  let selectedView = 'dashboard';
39015
39176
  let modalRun = 0;
39016
39177
  let pendingTicket = null;
39178
+ let updateCheckStarted = false;
39179
+ let latestUpdateCheck = null;
39017
39180
  const periodCache = new Map();
39018
39181
 
39019
39182
  async function request(path, body) {
@@ -39046,7 +39209,7 @@ var init_guided_product_client = __esm({
39046
39209
 
39047
39210
  function setBusy(value, applying = false) {
39048
39211
  busy = value;
39049
- document.querySelectorAll('[data-action],#refresh,#period').forEach(element => {
39212
+ document.querySelectorAll('[data-action],#refresh,#period,#evidence-filter,#evidence-type,#evidence-sort').forEach(element => {
39050
39213
  element.disabled = value;
39051
39214
  });
39052
39215
  $('live-status').textContent = value
@@ -39182,7 +39345,7 @@ var init_guided_product_client = __esm({
39182
39345
 
39183
39346
  function optimizerIds() {
39184
39347
  const ids = (current?.stack?.components || []).map(component => component.providerId).filter(Boolean);
39185
- return ids.length ? [...new Set(ids)] : Object.keys(TOOL_INFO);
39348
+ return [...new Set([...Object.keys(TOOL_INFO), ...ids])];
39186
39349
  }
39187
39350
 
39188
39351
  function configuredProviders() {
@@ -39310,6 +39473,16 @@ var init_guided_product_client = __esm({
39310
39473
  detail: 'A paired benchmark favored the baseline. Token Harness is not crediting the affected savings.',
39311
39474
  action: 'results',
39312
39475
  };
39476
+ const routingAttention = agents.filter(agent => agent.promptRouting?.needsRepair ||
39477
+ (agent.promptRouting?.configured === true && ['untrusted', 'disabled', 'unknown'].includes(agent.promptRouting.enablement)));
39478
+ if (routingAttention.length)
39479
+ return {
39480
+ label: 'Routing action required',
39481
+ cls: 'warn',
39482
+ title: 'Automatic routing needs attention',
39483
+ detail: routingAttention.map(agent => agent.name + ': ' + agent.promptRouting.detail).join(' '),
39484
+ action: 'routing',
39485
+ };
39313
39486
  if (stack?.state === 'attention')
39314
39487
  return {
39315
39488
  label: 'Needs attention',
@@ -39369,6 +39542,8 @@ var init_guided_product_client = __esm({
39369
39542
  const actions = node('div', undefined, 'inline-actions');
39370
39543
  if (assessment.action === 'verify') {
39371
39544
  actions.append(actionButton('Re-check health', () => readOnlyOperation('verify')));
39545
+ } else if (assessment.action === 'routing') {
39546
+ actions.append(actionButton('Review routing', () => $('coding-agents').scrollIntoView({ block: 'start', behavior: 'smooth' })));
39372
39547
  } else if (assessment.action === 'results') {
39373
39548
  actions.append(navigateButton('View detailed results', 'results'));
39374
39549
  }
@@ -39476,27 +39651,40 @@ var init_guided_product_client = __esm({
39476
39651
  ),
39477
39652
  );
39478
39653
  const routing = agent.promptRouting;
39654
+ const routingConfigured = routing?.configured === true || routing?.enablement === 'enabled' || routing?.enablement === 'untrusted' || (!routing?.enablement && routing?.state === 'managed');
39655
+ const routingObserved = routing?.verificationTier === 'runtime-observed';
39656
+ const routingLabel = routingObserved ? 'Active · callback seen' : routing?.needsRepair ? 'Repair required' : routing?.enablement === 'untrusted' ? 'Trust required' : routing?.enablement === 'disabled' ? 'Hooks disabled' : routing?.configured !== false && routing?.enablement === 'unknown' ? 'Authorization unknown' : routingConfigured ? 'Enabled · awaiting callback' : routing?.state === 'external' ? 'Managed elsewhere' : 'Not enabled';
39479
39657
  const routingCard = node('div', undefined, 'routing-feature');
39480
39658
  const routingHead = node('div', undefined, 'tool-head');
39481
39659
  routingHead.append(
39482
39660
  node('strong', 'Automatic prompt routing'),
39483
- pill(routing?.label || 'Not verified', routing?.state === 'managed' ? 'good' : routing?.state === 'absent' ? '' : 'warn'),
39661
+ pill(routingLabel, routingObserved ? 'good' : routingConfigured || routing?.needsRepair ? 'warn' : ''),
39484
39662
  );
39485
39663
  routingCard.append(
39486
39664
  routingHead,
39487
39665
  node(
39488
39666
  'p',
39489
- routing?.detail || 'A native hook can inject the routing policy on every submitted prompt. Setup and runtime activity are tracked separately.',
39667
+ routing?.detail || (routing?.enablement === 'untrusted'
39668
+ ? 'Open /hooks in Codex and trust this hook. Then submit a prompt to verify the callback.'
39669
+ : routing?.needsRepair
39670
+ ? routing.detail || 'Review and repair the Token Harness routing hook.'
39671
+ : routing?.enablement === 'unknown'
39672
+ ? routing.detail || 'Token Harness could not determine whether this hook is authorized.'
39673
+ : routingConfigured
39674
+ ? routingObserved ? 'Automatic routing is running on submitted prompts.' : 'Configured; submit a prompt and Token Harness will show the callback when it arrives.'
39675
+ : 'Enable once. The native hook then checks every submitted prompt automatically.'),
39490
39676
  'caption',
39491
39677
  ),
39492
39678
  );
39493
39679
  const routingActions = node('div', undefined, 'inline-actions');
39494
- if (routing?.state === 'absent') {
39495
- routingActions.append(actionButton('Enable routing', () => reviewPromptRouting(agent.id, true), 'secondary'));
39496
- } else if (routing?.state === 'managed') {
39497
- routingActions.append(actionButton('Disable routing', () => reviewPromptRouting(agent.id, false), 'secondary'));
39680
+ if (routing?.needsRepair) {
39681
+ routingActions.append(actionButton('Repair routing', () => reviewPromptRouting(agent.id, true), 'secondary'));
39498
39682
  } else if (routing?.state === 'external') {
39499
39683
  routingActions.append(node('span', 'Managed elsewhere · left untouched', 'caption'));
39684
+ } else if (!routingConfigured) {
39685
+ routingActions.append(actionButton('Enable routing', () => reviewPromptRouting(agent.id, true), 'secondary'));
39686
+ } else if (routingConfigured) {
39687
+ routingActions.append(actionButton('Disable routing', () => reviewPromptRouting(agent.id, false), 'secondary'));
39500
39688
  }
39501
39689
  if (routingActions.children.length) routingCard.append(routingActions);
39502
39690
  card.append(routingCard);
@@ -39622,13 +39810,17 @@ var init_guided_product_client = __esm({
39622
39810
  if (!(data.changes || []).length)
39623
39811
  $('modal-content').append(messageBox('No change proposed', (data.notices || []).join(' ') || 'The current routing state or ownership evidence does not support a safe change.'));
39624
39812
  for (const notice of data.notices || []) $('modal-content').append(node('p', notice, 'notice-row'));
39625
- if (data.ticket) $('modal-content').append(messageBox(
39626
- agentId === 'codex' ? 'Codex trust step' : 'When it takes effect',
39627
- agentId === 'codex'
39628
- ? 'After Apply, review and trust the UserPromptSubmit hook in Codex using /hooks. Until a callback is observed, the dashboard will show it as configured but not runtime verified.'
39629
- : 'After Apply, start a new Claude Code session. The dashboard will show configured state first and runtime activity after the next prompt callback.',
39630
- 'safe',
39631
- ));
39813
+ if (data.ticket) {
39814
+ const observed = activeAgents().find(agent => agent.id === agentId)?.promptRouting;
39815
+ const needsTrust = agentId === 'codex' && observed?.enablement === 'untrusted';
39816
+ $('modal-content').append(messageBox(
39817
+ needsTrust ? 'Trust required' : 'When it takes effect',
39818
+ needsTrust
39819
+ ? 'Open /hooks in Codex and trust this hook. Then send a prompt.'
39820
+ : 'Send a prompt in a new session. Token Harness will show the callback when it arrives.',
39821
+ 'safe',
39822
+ ));
39823
+ }
39632
39824
  $('modal-actions').replaceChildren(modalClose(data.ticket ? 'Cancel' : 'Done'));
39633
39825
  if (data.ticket) $('modal-actions').append(actionButton(enabled ? 'Apply routing hook' : 'Remove owned routing hook', () => applyTicket(data.ticket)));
39634
39826
  })
@@ -39724,6 +39916,12 @@ var init_guided_product_client = __esm({
39724
39916
  await ensureSession();
39725
39917
  const result = await request('/api/apply', { ticket });
39726
39918
  if (run !== modalRun) return;
39919
+ if (result.restartRequired) {
39920
+ $('modal-title').textContent = result.title || 'Token Harness update installed';
39921
+ $('modal-content').replaceChildren(messageBox('Restart to finish', (result.messages || []).join(' ') || 'Token Harness must restart before it can check the updated installation.', 'safe'));
39922
+ $('modal-actions').replaceChildren(modalClose('Later'), actionButton('Restart and re-check', restartAndRecheck));
39923
+ return;
39924
+ }
39727
39925
  $('modal-title').textContent = result.title || (result.ok ? 'Setup completed' : 'Setup needs attention');
39728
39926
  $('modal-content').replaceChildren(
39729
39927
  messageBox(result.ok ? 'Applied' : 'Needs attention', (result.messages || []).join(' '), result.ok ? 'safe' : 'warn'),
@@ -39768,6 +39966,24 @@ var init_guided_product_client = __esm({
39768
39966
  }
39769
39967
  }
39770
39968
 
39969
+ async function restartAndRecheck() {
39970
+ if (busy) return;
39971
+ setBusy(true, true);
39972
+ $('modal-content').replaceChildren(progress('Restarting Token Harness', 'The updated app will run its health check when it opens again.'));
39973
+ $('modal-actions').replaceChildren(modalClose('Restarting…', true));
39974
+ try {
39975
+ await ensureSession();
39976
+ const result = await request('/api/restart', {});
39977
+ if (!result.ok) throw new Error((result.messages || []).join(' ') || 'Restart did not complete.');
39978
+ setTimeout(() => window.location.reload(), 700);
39979
+ } catch (error) {
39980
+ $('modal-error').textContent = error.message;
39981
+ $('modal-error').hidden = false;
39982
+ $('modal-actions').replaceChildren(modalClose('Close'));
39983
+ setBusy(false, false);
39984
+ }
39985
+ }
39986
+
39771
39987
  function connectionPresentation(target) {
39772
39988
  if (!target) return { label: 'Not targeted', cls: '' };
39773
39989
  if (target.state === 'connected') return { label: 'Setup detected', cls: 'good' };
@@ -39776,6 +39992,26 @@ var init_guided_product_client = __esm({
39776
39992
  return { label: 'Not applicable', cls: '' };
39777
39993
  }
39778
39994
 
39995
+ function mcptoonInstallOptions() {
39996
+ modal('Install mcptoon prerequisites');
39997
+ $('modal-content').append(
39998
+ node('p', 'Token Harness can install mcptoon after pipx or uv is available. Install one, then Refresh and choose Install & connect.'),
39999
+ );
40000
+ const links = node('div', undefined, 'inline-actions');
40001
+ for (const [label, href] of [
40002
+ ['pipx installation', 'https://pipx.pypa.io/stable/installation/'],
40003
+ ['uv installation', 'https://docs.astral.sh/uv/getting-started/installation/'],
40004
+ ]) {
40005
+ const link = node('a', label, 'button secondary');
40006
+ link.href = href;
40007
+ link.target = '_blank';
40008
+ link.rel = 'noreferrer noopener';
40009
+ links.append(link);
40010
+ }
40011
+ $('modal-content').append(links);
40012
+ $('modal-actions').append(modalClose('Done'));
40013
+ }
40014
+
39779
40015
  function renderConnectionOverview() {
39780
40016
  const root = $('connection-overview');
39781
40017
  if (!root) return;
@@ -39839,8 +40075,18 @@ var init_guided_product_client = __esm({
39839
40075
  () => reviewSetup(id),
39840
40076
  'secondary',
39841
40077
  ),
39842
- );
39843
- else action.append(node('span', 'No action', 'caption'));
40078
+ );
40079
+ const mcptoonUnavailable = id === 'mcptoon' && agents.some(agent => setupTarget(agent.id, id)?.state === 'unavailable');
40080
+ if (mcptoonUnavailable)
40081
+ action.append(actionButton('Installation options', mcptoonInstallOptions, 'secondary'));
40082
+ if (component?.managedByTokenHarness || component?.configured) {
40083
+ const remove = actionButton('Remove managed setup', () => {
40084
+ window.tokenHarnessReviewRemoval?.(id, info.name);
40085
+ }, 'secondary');
40086
+ remove.disabled = busy || typeof window.tokenHarnessReviewRemoval !== 'function';
40087
+ action.append(remove);
40088
+ }
40089
+ if (!action.children.length) action.append(node('span', 'No action', 'caption'));
39844
40090
  row.append(action);
39845
40091
  table.append(row);
39846
40092
  }
@@ -39963,7 +40209,7 @@ var init_guided_product_client = __esm({
39963
40209
  messageBox('Optional candidate lifecycle', 'This is an explicit evaluation setup, not production-stack setup. Token Harness does not silently install or activate candidates.'),
39964
40210
  );
39965
40211
  if (candidate.id === 'mcptoon')
39966
- $('modal-content').append(messageBox('Prerequisites stay yours', 'An approved setup may install the exact reviewed mcptoon build only through an already-installed pipx. Token Harness does not install Python, pipx or administrator prerequisites.'));
40212
+ $('modal-content').append(messageBox('Prerequisites stay yours', 'An approved setup may install the exact reviewed mcptoon build through an already-installed pipx or uv. Token Harness does not install Python, pipx, uv or administrator prerequisites.'));
39967
40213
  if (candidate.id === 'gitnexus')
39968
40214
  $('modal-content').append(messageBox('Index stays yours', 'GitNexus must already be installed on the exact reviewed row. Token Harness can register only the reviewed Claude MCP entry; it never creates or refreshes the repository index.'));
39969
40215
  const agents = activeAgents().filter(agent => supported.includes(agent.id));
@@ -40243,44 +40489,139 @@ var init_guided_product_client = __esm({
40243
40489
  renderMaintenance();
40244
40490
  }
40245
40491
 
40246
- function renderSavings() {
40247
- const root = $('result-savings');
40248
- root.replaceChildren();
40249
- const rows = current?.savings?.rows || [];
40250
- if (!rows.length) {
40251
- root.append(sectionEmpty('No measured optimizer output has been recorded for this period. Missing data is not zero savings.'));
40252
- return;
40492
+ function addEvidenceRow(body, type, name, scope, summary, amount, details) {
40493
+ const row = node('tr');
40494
+ row.dataset.type = type;
40495
+ row.dataset.name = name.toLocaleLowerCase();
40496
+ row.dataset.search = [type, name, scope, summary].join(' ').toLocaleLowerCase();
40497
+ row.dataset.amount = String(amount || 0);
40498
+ const systemCell = node('th');
40499
+ systemCell.scope = 'row';
40500
+ systemCell.append(node('strong', name), node('span', type[0].toUpperCase() + type.slice(1), 'caption'));
40501
+ row.append(systemCell, node('td', scope), node('td', summary));
40502
+ const detailCell = node('td');
40503
+ const disclosure = node('details');
40504
+ disclosure.append(node('summary', 'Details'));
40505
+ for (const detail of details) disclosure.append(node('p', detail, 'caption'));
40506
+ detailCell.append(disclosure);
40507
+ row.append(detailCell);
40508
+ body.append(row);
40509
+ return row;
40510
+ }
40511
+
40512
+ function optimizerEvidenceDetail(row) {
40513
+ const unit = row.unit ? ' ' + row.unit : '';
40514
+ const change = row.before !== null && row.before !== undefined && row.after !== null && row.after !== undefined
40515
+ ? count(row.before) + ' → ' + count(row.after) + unit
40516
+ : count(row.saved) + unit;
40517
+ return [
40518
+ row.impact?.detail || 'Recorded optimizer evidence.',
40519
+ 'Recorded change: ' + change,
40520
+ count(row.operations) + ' operation(s)' + (row.agents?.length ? ' · ' + row.agents.join(', ') : ' · no harness attribution'),
40521
+ ];
40522
+ }
40523
+
40524
+ function routingDetails(agent) {
40525
+ const routing = agent.promptRouting || {};
40526
+ const lines = [];
40527
+ const tier = routing.verificationTier;
40528
+ if (routing.enablement === 'untrusted') lines.push('Action required: open /hooks in Codex and trust this hook, then submit a prompt.');
40529
+ else if (tier === 'runtime-observed') lines.push('Runtime callback observed. Automatic routing runs on submitted prompts.');
40530
+ else if (routing.configured !== false && routing.enablement === 'unknown') lines.push('Authorization is unknown; check the hook status in the coding app.');
40531
+ else if (routing.enablement === 'disabled') lines.push('Hooks are disabled for this coding app.');
40532
+ else if (routing.enablement === 'enabled' || (!routing.enablement && routing.state === 'managed')) lines.push('Configured; waiting for the first runtime callback after a prompt.');
40533
+ else if (routing.state === 'external') lines.push('Routing is managed elsewhere; Token Harness leaves it unchanged.');
40534
+ else lines.push('Automatic routing is not enabled for this coding app.');
40535
+ if (Number.isFinite(routing.promptSubmissions)) lines.push('Prompt callbacks: ' + count(routing.promptSubmissions));
40536
+ if (Number.isFinite(routing.subagentsStarted)) lines.push('Subagents started: ' + count(routing.subagentsStarted));
40537
+ if (Number.isFinite(routing.subagentsStopped)) lines.push('Subagents stopped: ' + count(routing.subagentsStopped));
40538
+ if (routing.reportedModels?.length) lines.push('Reported models: ' + routing.reportedModels.join(', '));
40539
+ if (routing.lastObservedAt) lines.push('Last callback: ' + date(routing.lastObservedAt));
40540
+ return lines;
40541
+ }
40542
+
40543
+ function renderEvidence() {
40544
+ const body = $('result-evidence');
40545
+ body.replaceChildren();
40546
+ const savings = current?.savings?.rows || [];
40547
+ for (const id of optimizerIds()) {
40548
+ const info = optimizerInfo(id);
40549
+ const component = managedComponent(id);
40550
+ const measured = savings.filter(row => row.providerId === id);
40551
+ const scope = component?.configuredHarnesses?.length
40552
+ ? component.configuredHarnesses.map(agentName).join(', ')
40553
+ : 'No setup detected';
40554
+ const summary = measured.length
40555
+ ? measured.map(row => row.measurement + ' · ' + count(row.saved) + (row.unit ? ' ' + row.unit : '')).join(' · ')
40556
+ : 'No measured evidence';
40557
+ const details = measured.length
40558
+ ? measured.flatMap(optimizerEvidenceDetail)
40559
+ : [component?.configured ? 'Setup is detected, but no result was recorded for this period.' : 'No result was recorded for this optimizer in this period.'];
40560
+ addEvidenceRow(body, 'optimizer', info.name, scope, summary, measured.length, details);
40561
+ }
40562
+
40563
+ const routing = current?.value?.routing;
40564
+ const routingAgents = activeAgents();
40565
+ const routingDetailsList = routingAgents.flatMap(agent => [agent.name + ':', ...routingDetails(agent)]);
40566
+ if (routing?.state === 'measured' || routing?.pairs > 0) {
40567
+ routingDetailsList.push((routing.pairs ? count(routing.pairs) + ' quality-passed routed pair(s).' : ''));
40568
+ if (routing.savedLocalTokens !== null && routing.savedLocalTokens !== undefined)
40569
+ routingDetailsList.push(routing.savedLocalTokens >= 0
40570
+ ? count(routing.savedLocalTokens) + ' local tokens saved · end-to-end local usage'
40571
+ : count(Math.abs(routing.savedLocalTokens)) + ' local tokens added · end-to-end local usage');
40572
+ if (routing.allowance5h?.savedPercent !== null && routing.allowance5h?.savedPercent !== undefined)
40573
+ routingDetailsList.push('5h allowance change: ' + count(routing.allowance5h.savedPercent) + '%');
40574
+ if (routing.allowance7d?.savedPercent !== null && routing.allowance7d?.savedPercent !== undefined)
40575
+ routingDetailsList.push('7d allowance change: ' + count(routing.allowance7d.savedPercent) + '%');
40576
+ }
40577
+ const routingSummary = routing?.state === 'blocked-by-quality'
40578
+ ? 'Not credited · quality gate'
40579
+ : routing?.savedLocalTokens !== null && routing?.savedLocalTokens !== undefined
40580
+ ? count(routing.savedLocalTokens) + ' local tokens · end-to-end paired evidence'
40581
+ : routing?.state === 'measured' ? 'Allowance evidence measured' : 'Not measured yet';
40582
+ addEvidenceRow(body, 'routing', 'Automatic prompt routing', routingAgents.map(agent => agent.name).join(', ') || 'No coding app detected', routingSummary, routing?.pairs || 0, routingDetailsList.length ? routingDetailsList : ['No routing measurement has been recorded.']);
40583
+
40584
+ for (const agent of routingAgents) {
40585
+ const linked = savings.filter(row => row.harnesses?.includes(agent.id));
40586
+ const configured = configuredProviders().filter(component => component.configuredHarnesses?.includes(agent.id)).map(component => optimizerInfo(component.providerId).name);
40587
+ const details = [
40588
+ 'Detected optimizer setup: ' + (configured.join(', ') || 'none'),
40589
+ ...routingDetails(agent),
40590
+ ...(linked.length ? linked.flatMap(optimizerEvidenceDetail) : ['No optimizer measurement is directly linked to this coding app.']),
40591
+ ];
40592
+ addEvidenceRow(body, 'harness', agent.name, agent.version ? 'v' + agent.version : 'Version unavailable', linked.length ? linked.map(row => row.provider + ': ' + row.measurement + ' · ' + count(row.saved) + (row.unit ? ' ' + row.unit : '')).join(' · ') : 'No linked measured evidence', linked.length, details);
40253
40593
  }
40594
+
40595
+ for (const item of current?.value?.candidates || []) {
40596
+ if (!(item.pairs > 0)) continue;
40597
+ const candidate = (current?.optimizationCandidates || []).find(entry => entry.id === item.candidateId);
40598
+ const name = candidate?.name || item.candidateId;
40599
+ addEvidenceRow(body, 'candidate', name, 'Experimental', count(item.pairs) + ' paired result(s)', item.pairs, [
40600
+ count(item.optimizedBetter || 0) + ' optimized better · ' + count(item.baselineBetter || 0) + ' baseline better.',
40601
+ 'Evaluation evidence only; this does not automatically promote or activate the candidate.',
40602
+ ]);
40603
+ }
40604
+ applyEvidenceFilters();
40605
+ }
40606
+
40607
+ function applyEvidenceFilters() {
40608
+ const body = $('result-evidence');
40609
+ if (!body) return;
40610
+ const filter = $('evidence-filter').value.trim().toLocaleLowerCase();
40611
+ const type = $('evidence-type').value;
40612
+ const sort = $('evidence-sort').value;
40613
+ const rows = [...body.querySelectorAll('tr')];
40614
+ rows.sort((a, b) => sort === 'evidence'
40615
+ ? Number(b.dataset.amount) - Number(a.dataset.amount) || a.dataset.name.localeCompare(b.dataset.name)
40616
+ : sort === 'type'
40617
+ ? a.dataset.type.localeCompare(b.dataset.type) || a.dataset.name.localeCompare(b.dataset.name)
40618
+ : a.dataset.name.localeCompare(b.dataset.name));
40254
40619
  for (const row of rows) {
40255
- const card = node('article', undefined, 'evidence-row');
40256
- const head = node('div', undefined, 'evidence-head');
40257
- head.append(node('h3', row.provider), pill(row.measurement));
40258
- card.append(head, node('strong', row.impact?.headline || count(row.saved) + ' ' + row.unit, 'evidence-value'), node('p', row.impact?.detail || 'Recorded optimization output.'));
40259
- const facts = node('dl', undefined, 'evidence-facts');
40260
- const values = [
40261
- ['Recorded change', row.before !== null && row.after !== null ? count(row.before) + ' → ' + count(row.after) + ' ' + row.unit : count(Math.abs(row.saved)) + ' ' + row.unit],
40262
- ['Operations', count(row.operations)],
40263
- ['Coding agent', row.agents?.length ? row.agents.join(', ') : 'Not linked to an agent'],
40264
- ];
40265
- for (const [label, value] of values) {
40266
- const wrap = node('div');
40267
- wrap.append(node('dt', label), node('dd', value));
40268
- facts.append(wrap);
40269
- }
40270
- card.append(facts);
40271
- if (!row.agents?.length) {
40272
- card.append(
40273
- node(
40274
- 'p',
40275
- row.providerId === 'rtk'
40276
- ? 'RTK records these reductions but does not record whether Codex or Claude ran each command. The result is real, but Token Harness cannot assign it to either agent.'
40277
- : 'The source did not include a coding-agent identity, so Token Harness keeps this result unassigned.',
40278
- 'caption',
40279
- ),
40280
- );
40281
- }
40282
- root.append(card);
40620
+ const shown = (type === 'all' || row.dataset.type === type) && (!filter || row.dataset.search.includes(filter));
40621
+ row.hidden = !shown;
40622
+ body.append(row);
40283
40623
  }
40624
+ $('evidence-empty').hidden = rows.some(row => !row.hidden);
40284
40625
  }
40285
40626
 
40286
40627
  function measurementHelp() {
@@ -40295,173 +40636,23 @@ var init_guided_product_client = __esm({
40295
40636
  $('modal-actions').append(modalClose('Done'));
40296
40637
  }
40297
40638
 
40298
- function renderCandidateResults() {
40299
- const root = $('candidate-results');
40300
- root.replaceChildren();
40301
- const evidence = current?.value?.candidates || [];
40302
- if (!evidence.some(item => item.pairs > 0)) {
40303
- root.append(sectionEmpty('No experimental candidate has completed paired evidence yet. Experimental tools are optional and do not affect managed setup.'));
40304
- return;
40305
- }
40306
- for (const item of evidence.filter(entry => entry.pairs > 0)) {
40307
- const candidate = EXPERIMENTAL.find(entry => entry.id === item.candidateId);
40308
- if (!candidate) continue;
40309
- const card = node('article', undefined, 'evidence-row');
40310
- card.append(node('h3', candidate.name), node('strong', count(item.pairs) + ' paired result(s)', 'evidence-value'));
40311
- card.append(node('p', count(item.optimizedBetter || 0) + ' optimized better · ' + count(item.baselineBetter || 0) + ' baseline better. This is evaluation evidence, not automatic promotion.'));
40312
- root.append(card);
40313
- }
40314
- }
40315
-
40316
- function renderResultOptimizers() {
40317
- const root = $('result-optimizers');
40318
- if (!root) return;
40319
- root.replaceChildren();
40320
- const rows = current?.savings?.rows || [];
40321
- for (const id of optimizerIds()) {
40322
- const component = managedComponent(id);
40323
- const info = optimizerInfo(id);
40324
- const state = componentState(id, component);
40325
- const card = node('article', undefined, 'tool-card result-overview-card');
40326
- const head = node('div', undefined, 'tool-head');
40327
- head.append(node('h3', info.name), pill(state.label, state.cls));
40328
- card.append(head, node('p', info.role));
40329
- const facts = node('div', undefined, 'tool-facts');
40330
- facts.append(
40331
- node('span', 'Setup detected for'),
40332
- node('strong', component?.configuredHarnesses?.length ? component.configuredHarnesses.map(agentName).join(', ') : 'No detected agent'),
40333
- );
40334
- const measured = rows.filter(row => row.providerId === id);
40335
- card.append(facts);
40336
- if (!measured.length) {
40337
- card.append(
40338
- node(
40339
- 'p',
40340
- component?.configured
40341
- ? 'Setup is detected, but no result was recorded in the selected period.'
40342
- : 'No result was recorded for this optimizer in the selected period.',
40343
- 'caption',
40344
- ),
40345
- );
40346
- } else {
40347
- for (const row of measured) {
40348
- const evidence = node('div', undefined, 'result-signal');
40349
- evidence.append(
40350
- node('span', row.measurement, 'caption'),
40351
- node('strong', row.impact?.headline || count(row.saved) + ' ' + row.unit),
40352
- node('span', count(row.operations) + ' operation' + (row.operations === 1 ? '' : 's'), 'caption'),
40353
- );
40354
- card.append(evidence);
40355
- }
40356
- }
40357
- root.append(card);
40358
- }
40359
- }
40360
-
40361
- function renderResultAgents() {
40362
- const root = $('result-agents');
40363
- if (!root) return;
40364
- root.replaceChildren();
40365
- const rows = current?.savings?.rows || [];
40366
- if (!activeAgents().length) {
40367
- root.append(sectionEmpty('No supported coding agent is currently detected.'));
40368
- return;
40369
- }
40370
- for (const agent of activeAgents()) {
40371
- const setupDetected = configuredProviders().filter(component =>
40372
- component.configuredHarnesses?.includes(agent.id),
40373
- );
40374
- const measured = rows.filter(row => row.harnesses?.includes(agent.id));
40375
- const rtkUnattributed = rows.some(row =>
40376
- row.providerId === 'rtk' && !row.agents?.length,
40377
- );
40378
- const notes = [];
40379
- if (
40380
- setupDetected.some(component => component.providerId === 'rtk') &&
40381
- !measured.some(row => row.providerId === 'rtk')
40382
- ) {
40383
- notes.push(
40384
- rtkUnattributed
40385
- ? 'RTK has saved command-output data, but its history does not say whether Codex or Claude ran each command. Token Harness keeps those results under RTK instead of guessing.'
40386
- : 'RTK setup is detected, but no RTK result can be linked to this agent in the selected period.',
40387
- );
40388
- }
40389
- if (
40390
- setupDetected.some(component => component.providerId === 'harnesstrim') &&
40391
- !measured.some(row => row.providerId === 'harnesstrim')
40392
- ) {
40393
- notes.push(
40394
- 'HarnessTrim setup is detected, but no HarnessTrim result is linked to this app in the selected period. Setup alone does not mean it was used.',
40395
- );
40396
- }
40397
- if (!setupDetected.length && !measured.length) {
40398
- notes.push('No optimizer setup or agent-linked result was found for this coding app.');
40399
- }
40400
- const card = node('article', undefined, 'tool-card result-overview-card');
40401
- const head = node('div', undefined, 'tool-head');
40402
- head.append(node('h3', agent.name), pill(setupDetected.length ? 'Setup detected' : 'No setup', setupDetected.length ? 'good' : ''));
40403
- card.append(
40404
- head,
40405
- node('p', agent.version ? 'v' + agent.version : 'Version unavailable', 'caption'),
40406
- );
40407
- const facts = node('div', undefined, 'tool-facts');
40408
- facts.append(
40409
- node('span', 'Setup found'),
40410
- node('strong', setupDetected.length ? setupDetected.map(component => optimizerInfo(component.providerId).name).join(', ') : 'None'),
40411
- node('span', 'Results linked to this agent'),
40412
- node('strong', measured.length ? measured.map(row => row.provider).join(', ') : 'None in this period'),
40413
- );
40414
- card.append(facts);
40415
- for (const note of notes) card.append(node('p', note, 'caption'));
40416
- root.append(card);
40417
- }
40418
- }
40419
-
40420
40639
  function renderResults() {
40421
40640
  const allowance = allowanceSummary();
40422
40641
  const quality = qualitySummary();
40423
- const configured = configuredProviders();
40424
- const connectionCount = configured.reduce(
40425
- (total, component) => total + (component.configuredHarnesses?.length || 0),
40426
- 0,
40427
- );
40428
- const measuredProviders = new Set(
40429
- (current?.savings?.rows || []).map(row => row.providerId).filter(Boolean),
40430
- );
40642
+ const savings = current?.savings?.rows || [];
40431
40643
  $('result-summary').replaceChildren(
40432
- metricCard('Configured optimizers', count(configured.length), optimizerIds().length + ' optimizer(s) tracked in the stack.', configured.length ? 'positive' : ''),
40433
- metricCard('Setups detected', count(connectionCount), 'Detected optimizer setup links; this is not proof of measured activity.', connectionCount ? 'positive' : ''),
40434
- metricCard('Optimizers with results', count(measuredProviders.size), 'Providers with recorded measurements in the selected period.'),
40644
+ metricCard('Measured output', savings.length ? count(savings.length) + ' evidence record(s)' : 'No records yet', 'Exact, estimated and other measurement classes remain separate.'),
40435
40645
  metricCard('5h / 7d allowance', allowance.value, allowance.detail, allowance.cls),
40436
40646
  metricCard('Quality', quality.value, quality.detail, quality.cls),
40437
40647
  );
40438
40648
  const routed = current?.value?.routing;
40439
- const quotaParts = [];
40440
- if (routed?.allowance5h?.state === 'measured' && routed.allowance5h.savedPercent !== null)
40441
- quotaParts.push(routed.allowance5h.savedPercent >= 0
40442
- ? '5h saved ' + count(routed.allowance5h.savedPercent) + '%'
40443
- : '5h use +' + count(Math.abs(routed.allowance5h.savedPercent)) + '%');
40444
- if (routed?.allowance7d?.state === 'measured' && routed.allowance7d.savedPercent !== null)
40445
- quotaParts.push(routed.allowance7d.savedPercent >= 0
40446
- ? '7d saved ' + count(routed.allowance7d.savedPercent) + '%'
40447
- : '7d use +' + count(Math.abs(routed.allowance7d.savedPercent)) + '%');
40448
- const routingValue = routed?.state === 'blocked-by-quality'
40649
+ const routeStatus = routed?.state === 'blocked-by-quality'
40449
40650
  ? 'Not credited'
40450
40651
  : routed?.savedLocalTokens !== null && routed?.savedLocalTokens !== undefined
40451
- ? (routed.savedLocalTokens >= 0
40452
- ? count(routed.savedLocalTokens) + ' tokens saved' + (routed.localTokenSavingPercent === null ? '' : ' · ' + count(routed.localTokenSavingPercent) + '%')
40453
- : count(Math.abs(routed.savedLocalTokens)) + ' tokens added' + (routed.localTokenSavingPercent === null ? '' : ' · ' + count(Math.abs(routed.localTokenSavingPercent)) + '%'))
40454
- : quotaParts.length ? 'Allowance measured' : routed?.state === 'measured' ? 'Usage unavailable' : 'Not measured yet';
40455
- const routingDetail = routed?.state === 'blocked-by-quality'
40456
- ? routed.basis
40457
- : (quotaParts.length ? quotaParts.join(' · ') + '. ' : '') +
40458
- (routed?.pairs ? count(routed.pairs) + ' quality-passed routed pair(s). ' : '') +
40459
- 'Local tokens and allowance percentages are separate measurements. Actual child model is not exposed by every harness hook.';
40460
- $('result-summary').append(metricCard('Automatic routing', routingValue, routingDetail, routed?.state === 'measured' ? 'positive' : ''));
40461
- renderResultOptimizers();
40462
- renderResultAgents();
40463
- renderSavings();
40464
- renderCandidateResults();
40652
+ ? count(routed.savedLocalTokens) + ' local tokens'
40653
+ : routed?.state === 'measured' ? 'Allowance measured' : 'Not measured yet';
40654
+ $('result-summary').append(metricCard('Automatic routing', routeStatus, routed?.pairs ? count(routed.pairs) + ' quality-passed pair(s). Allowance and local tokens are separate.' : 'Routing savings need paired, quality-gated evidence.', routed?.state === 'measured' ? 'positive' : ''));
40655
+ renderEvidence();
40465
40656
  $('results-period-note').textContent = current?.savings?.firstRecordedAt
40466
40657
  ? 'Recorded from ' + date(current.savings.firstRecordedAt) + ' through ' + date(current.savings.lastRecordedAt)
40467
40658
  : 'No recorded result dates for this period.';
@@ -40470,16 +40661,18 @@ var init_guided_product_client = __esm({
40470
40661
  function renderActivity() {
40471
40662
  const root = $('activity');
40472
40663
  root.replaceChildren();
40473
- const rows = activityState?.activity || [];
40664
+ const rows = [...(activityState?.activity || [])].sort((a, b) => new Date(b.at).getTime() - new Date(a.at).getTime());
40474
40665
  if (!rows.length) {
40475
40666
  root.append(sectionEmpty('No checks or changes have been recorded in this app session.'));
40476
40667
  return;
40477
40668
  }
40478
- for (const item of rows) {
40669
+ const visible = rows.slice(0, 8);
40670
+ for (const item of visible) {
40479
40671
  const row = node('div', undefined, 'activity-row');
40480
40672
  row.append(pill(item.state === 'success' ? 'Done' : item.state === 'attention' ? 'Attention' : 'Working', item.state === 'success' ? 'good' : item.state === 'attention' ? 'warn' : ''), node('span', item.message), node('time', date(item.at), 'caption'));
40481
40673
  root.append(row);
40482
40674
  }
40675
+ if (rows.length > visible.length) root.prepend(node('p', 'Showing the latest ' + visible.length + ' of ' + rows.length + ' entries.', 'caption'));
40483
40676
  }
40484
40677
 
40485
40678
  async function loadActivity() {
@@ -40498,6 +40691,82 @@ var init_guided_product_client = __esm({
40498
40691
  }
40499
40692
  }
40500
40693
 
40694
+ function reviewUpdate(result) {
40695
+ if (!result?.ticket || busy) return;
40696
+ modal('Review Token Harness update');
40697
+ $('modal-content').append(
40698
+ messageBox('Update available', (result.messages || []).join(' ') || result.title || 'A reviewed Token Harness update is ready.'),
40699
+ messageBox('Health re-check', 'After installation, Token Harness will re-check optimizer health automatically.'),
40700
+ );
40701
+ $('modal-actions').append(modalClose('Cancel'), actionButton('Install updates', () => applyTicket(result.ticket)));
40702
+ }
40703
+
40704
+ async function checkUpdatesOnStartup() {
40705
+ if (updateCheckStarted) return;
40706
+ if ($('modal').open) {
40707
+ $('modal').addEventListener('close', checkUpdatesOnStartup, { once: true });
40708
+ return;
40709
+ }
40710
+ if (busy || reading) {
40711
+ setTimeout(checkUpdatesOnStartup, 1000);
40712
+ return;
40713
+ }
40714
+ updateCheckStarted = true;
40715
+ try {
40716
+ await ensureSession();
40717
+ const result = await request('/api/update-check', { period: $('period').value });
40718
+ if (busy || reading || $('modal').open) {
40719
+ updateCheckStarted = false;
40720
+ if ($('modal').open) $('modal').addEventListener('close', checkUpdatesOnStartup, { once: true });
40721
+ else setTimeout(checkUpdatesOnStartup, 1000);
40722
+ return;
40723
+ }
40724
+ latestUpdateCheck = result;
40725
+ if (result.stack && current) {
40726
+ current = { ...current, stack: result.stack };
40727
+ renderDashboard();
40728
+ renderSetup();
40729
+ renderResults();
40730
+ }
40731
+ const root = $('update-notice');
40732
+ root.replaceChildren();
40733
+ if (!result.ticket) {
40734
+ root.hidden = true;
40735
+ return;
40736
+ }
40737
+ const copy = node('div');
40738
+ copy.append(node('strong', result.title || 'Token Harness update available'), node('p', (result.messages || []).join(' ') || 'Review and install the available update.', 'caption'));
40739
+ root.append(copy, actionButton('Review update', () => reviewUpdate(latestUpdateCheck), 'secondary'));
40740
+ root.hidden = false;
40741
+ } catch {
40742
+ // The startup version check is supplementary; Refresh and Health and updates remain available.
40743
+ }
40744
+ }
40745
+
40746
+ async function pollRouting() {
40747
+ if (document.hidden || busy || reading || $('modal').open || !current) return;
40748
+ try {
40749
+ const result = await request('/api/routing');
40750
+ if (busy || reading || $('modal').open || document.activeElement?.closest('#setup-agents, #result-evidence')) return;
40751
+ if (!Array.isArray(result.agents)) return;
40752
+ const byId = new Map(result.agents.map(agent => [agent.id, agent.promptRouting]));
40753
+ const previous = new Map((current.agents || []).map(agent => [agent.id, agent.promptRouting]));
40754
+ const changed = [...byId].some(([id, routing]) => JSON.stringify(previous.get(id)) !== JSON.stringify(routing));
40755
+ if (!changed) return;
40756
+ current = {
40757
+ ...current,
40758
+ agents: (current.agents || []).map(agent => byId.has(agent.id)
40759
+ ? { ...agent, promptRouting: byId.get(agent.id) }
40760
+ : agent),
40761
+ };
40762
+ renderDashboard();
40763
+ renderAgentSetup();
40764
+ renderResults();
40765
+ } catch {
40766
+ // Runtime receipts are supplementary; the overview remains usable if this read fails.
40767
+ }
40768
+ }
40769
+
40501
40770
  function render() {
40502
40771
  renderNotices();
40503
40772
  renderDashboard();
@@ -40530,6 +40799,7 @@ var init_guided_product_client = __esm({
40530
40799
  clearInterval(progressTimer);
40531
40800
  reading = false;
40532
40801
  $('refresh').disabled = false;
40802
+ if (current && !updateCheckStarted) checkUpdatesOnStartup();
40533
40803
  }
40534
40804
  }
40535
40805
 
@@ -40570,6 +40840,9 @@ var init_guided_product_client = __esm({
40570
40840
  });
40571
40841
  $('refresh').addEventListener('click', () => refresh(true));
40572
40842
  $('period').addEventListener('change', changePeriod);
40843
+ $('evidence-filter').addEventListener('input', applyEvidenceFilters);
40844
+ $('evidence-type').addEventListener('change', applyEvidenceFilters);
40845
+ $('evidence-sort').addEventListener('change', applyEvidenceFilters);
40573
40846
  $('measurement-help').addEventListener('click', measurementHelp);
40574
40847
  $('theme').addEventListener('change', () => {
40575
40848
  const value = $('theme').value;
@@ -40585,6 +40858,8 @@ var init_guided_product_client = __esm({
40585
40858
  selectView('dashboard');
40586
40859
  refresh(false);
40587
40860
  setInterval(() => { if (!document.hidden) loadActivity(); }, 4000);
40861
+ setInterval(pollRouting, 15000);
40862
+ document.addEventListener('visibilitychange', () => { if (!document.hidden) pollRouting(); });
40588
40863
  })();
40589
40864
  `;
40590
40865
  }
@@ -40611,9 +40886,13 @@ var init_guided_product_styles = __esm({
40611
40886
  .explain-box{background:var(--panel-soft);border:1px solid var(--line);border-radius:12px;padding:.8rem;margin:.6rem 0}.explain-box p{margin:.25rem 0;color:var(--muted)}.explain-box.warn{background:var(--warn-soft);border-color:color-mix(in srgb,var(--warn) 35%,var(--line))}.explain-box.safe{background:var(--good-soft);border-color:color-mix(in srgb,var(--good) 30%,var(--line))}.operation-progress{margin:.75rem 0;padding:.8rem;border:1px solid var(--line);border-radius:12px}.operation-progress p{margin:.35rem 0 0}
40612
40887
  .choice-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.6rem;margin:.8rem 0}.choice-button{display:flex;flex-direction:column;align-items:flex-start;text-align:left;gap:.25rem;background:var(--panel);color:var(--text);border:1px solid var(--line);padding:.8rem}.choice-button:hover:not(:disabled){border-color:var(--accent);background:var(--accent-soft)}.choice-button .caption{font-weight:500}
40613
40888
  .result-signal{display:grid;gap:.2rem;border-top:1px solid var(--line);padding:.65rem 0}.result-signal strong{font-size:1rem}.results-header{display:flex;justify-content:space-between;gap:1rem;align-items:end;margin:1rem 0}.results-header h2{margin:0}.results-header p{margin:.2rem 0;color:var(--muted)}
40889
+ .update-notice{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.8rem 1rem;margin:.8rem 0;border:1px solid color-mix(in srgb,var(--accent) 40%,var(--line));border-radius:var(--radius);background:var(--accent-soft)}.update-notice p{margin:.2rem 0 0;color:var(--muted)}
40890
+ .inline-actions a.secondary{display:inline-flex;align-items:center;padding:.68rem 1rem;border-radius:10px;text-decoration:none;font-weight:700}
40891
+ .evidence-panel{padding:0}.evidence-controls{display:flex;align-items:end;gap:.7rem;flex-wrap:wrap;padding:.8rem;border-bottom:1px solid var(--line)}.evidence-controls label{display:grid;gap:.25rem;color:var(--muted);font-size:.82rem}.evidence-controls input,.evidence-controls select{min-width:150px}.evidence-controls input{min-width:min(260px,70vw)}.evidence-table-scroll{overflow-x:auto}.evidence-table{width:100%;border-collapse:collapse;min-width:760px}.evidence-table th,.evidence-table td{padding:.75rem .85rem;text-align:left;vertical-align:top;border-bottom:1px solid var(--line)}.evidence-table thead{background:var(--panel-soft);color:var(--muted);font-size:.8rem}.evidence-table tbody th{min-width:175px;font-weight:600}.evidence-table tbody th span{display:block;margin-top:.2rem}.evidence-table td:nth-child(2){min-width:150px}.evidence-table td:nth-child(3){min-width:240px}.evidence-table td:last-child{min-width:110px}.evidence-table details summary{cursor:pointer;color:var(--accent);font-weight:700}.evidence-table details p{margin:.45rem 0}.evidence-table tr[hidden]{display:none}.activity-scroll{max-height:24rem;overflow-y:auto;overscroll-behavior:contain}.activity-scroll .activity-row{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:.75rem;padding:.65rem 0;border-bottom:1px solid var(--line)}
40614
40892
  #modal{width:min(720px,calc(100vw - 2rem));max-height:calc(100vh - 2rem);overflow:auto}#modal-content h3{margin:1rem 0 .4rem}#modal-actions{display:flex;justify-content:flex-end;gap:.5rem;flex-wrap:wrap;margin-top:1rem}
40615
40893
  @media(max-width:900px){.dashboard-columns{grid-template-columns:1fr}.tool-grid{grid-template-columns:1fr}.setup-intro{grid-template-columns:1fr}}
40616
- @media(max-width:640px){.dashboard-status{flex-direction:column}.choice-grid{grid-template-columns:1fr}.connection-summary{align-items:flex-start;flex-direction:column}.connection-action{justify-content:flex-start}.maintenance-row{align-items:flex-start;flex-direction:column}.results-header{align-items:flex-start;flex-direction:column}}
40894
+ @media(max-width:640px){.dashboard-status{flex-direction:column}.choice-grid{grid-template-columns:1fr}.connection-summary{align-items:flex-start;flex-direction:column}.connection-action{justify-content:flex-start}.maintenance-row{align-items:flex-start;flex-direction:column}.results-header{align-items:flex-start;flex-direction:column}.update-notice{align-items:flex-start;flex-direction:column}.activity-scroll .activity-row{grid-template-columns:auto minmax(0,1fr)}.activity-scroll .activity-row time{grid-column:2}}
40895
+ @media(max-width:800px){.evidence-table{min-width:0}.evidence-table thead{display:none}.evidence-table tbody{display:block}.evidence-table tr{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);padding:.65rem;border-bottom:1px solid var(--line)}.evidence-table tbody th,.evidence-table td:nth-child(n){min-width:0;padding:.3rem;border:0;overflow-wrap:anywhere}.evidence-table td:nth-child(3),.evidence-table td:last-child{grid-column:1/-1}}
40617
40896
  `;
40618
40897
  }
40619
40898
  });
@@ -41273,6 +41552,7 @@ ${GUIDE_CANDIDATE_READINESS_JS}`;
41273
41552
  <div class="page-heading"><div><h1 id="view-title">Overview</h1><p id="view-description">Your coding agents, optimization stack, health and measured results in one place.</p></div></div>
41274
41553
  <div class="status-line"><span class="read-status" role="status"><span id="reading-spinner" class="spinner" aria-hidden="true"></span><span id="updated">Checking your setup\u2026</span></span><span id="live-status" class="caption">Nothing changes without your approval</span></div>
41275
41554
  <div id="stale-state" class="stale-state" hidden></div><div id="error" class="error" role="alert" hidden></div><div id="notices"></div>
41555
+ <div id="update-notice" class="update-notice" role="status" hidden></div>
41276
41556
 
41277
41557
  <section id="view-dashboard" role="tabpanel" aria-labelledby="tab-dashboard" tabindex="0">
41278
41558
  <section id="dashboard-status" class="dashboard-status"><div><span class="eyebrow">CURRENT STATUS</span><h2>Checking your machine\u2026</h2><p>Finding Claude Code, Codex, recommended optimizers and measured results.</p></div><span class="pill">Checking</span></section>
@@ -41300,7 +41580,6 @@ ${GUIDE_CANDIDATE_READINESS_JS}`;
41300
41580
  <section class="setup-step" id="optimizers">
41301
41581
  <div class="section-title"><div><h2>Optimizer setup</h2><p>This matrix shows which optimizer setup Token Harness detected for each coding app. It does not confirm runtime activity; measured results appear separately when evidence is recorded.</p></div></div>
41302
41582
  <div id="connection-overview" class="connection-overview"><p class="empty">Checking optimizer connections\u2026</p></div>
41303
- <details class="disclosure"><summary>Remove Token Harness-managed configuration</summary><p class="caption">Removal is reviewed first. Token Harness removes only configuration it owns; installed provider software and user-owned configuration may remain.</p><div id="managed-removal-actions" class="maintenance-list"><p class="caption">Checking managed ownership\u2026</p></div></details>
41304
41583
  </section>
41305
41584
 
41306
41585
  <section class="setup-step" id="maintenance">
@@ -41310,15 +41589,15 @@ ${GUIDE_CANDIDATE_READINESS_JS}`;
41310
41589
  </section>
41311
41590
 
41312
41591
  <section id="view-results" role="tabpanel" aria-labelledby="tab-results" tabindex="0" hidden>
41313
- <div class="results-header"><div><h2>Results dashboard</h2><p>See which optimizer setups Token Harness found and which results it actually recorded for each coding app.</p></div><div class="filter-row"><label for="period">Period</label><select id="period"><option value="all">All</option><option value="7d">7 days</option><option value="30d">30 days</option></select><button id="measurement-help" class="secondary" type="button">How results are recorded</button></div></div>
41314
- <div id="result-summary" class="impact-grid" aria-label="Results overview"><article class="metric-card"><span class="metric-label">Optimization stack</span><strong class="metric-value">Checking\u2026</strong></article></div>
41315
- <div class="section-title"><div><h2>By optimizer</h2><p>Detected setup and recorded results for every optimizer in the stack.</p></div></div>
41316
- <div id="result-optimizers" class="tool-grid"><article class="tool-card"><h3>Checking optimizer results\u2026</h3></article></div>
41317
- <div class="section-title"><div><h2>By coding agent</h2><p>Which optimizer setups were detected for each app and which measured results can be linked to it.</p></div></div>
41318
- <div id="result-agents" class="tool-grid"><article class="tool-card"><h3>Checking results by coding app\u2026</h3></article></div>
41319
- <div class="section-title"><div><h2>Measurement evidence</h2><p id="results-period-note">Checking recorded dates\u2026</p></div></div><section class="panel"><div id="result-savings" class="evidence-list"><p class="empty">Checking recorded results\u2026</p></div></section>
41320
- <div class="section-title"><div><h2>Experimental benchmark results</h2><p>Candidate evidence is evaluation only; it never promotes a tool automatically.</p></div></div><section class="panel"><div id="candidate-results" class="evidence-list"><p class="empty">Checking candidate evidence\u2026</p></div></section>
41321
- <div class="section-title"><div><h2>Recent activity</h2><p>Checks and changes from this local app session.</p></div></div><section class="panel"><div id="activity"><p class="empty">No activity yet.</p></div></section>
41592
+ <div class="results-header"><div><h2>Results dashboard</h2><p>Measured evidence by optimizer, routing and coding app. Different classes and units stay separate.</p></div><div class="filter-row"><label for="period">Period</label><select id="period"><option value="all">All</option><option value="7d">7 days</option><option value="30d">30 days</option></select><button id="measurement-help" class="secondary" type="button">How results are recorded</button></div></div>
41593
+ <div id="result-summary" class="impact-grid" aria-label="Results overview"><article class="metric-card"><span class="metric-label">Measured evidence</span><strong class="metric-value">Checking\u2026</strong></article></div>
41594
+ <div class="section-title"><div><h2>Evidence</h2><p id="results-period-note">Checking recorded dates\u2026</p></div></div>
41595
+ <section class="panel evidence-panel">
41596
+ <div class="evidence-controls"><label>Filter <input id="evidence-filter" type="search" placeholder="Optimizer, harness, class\u2026" autocomplete="off"></label><label>Type <select id="evidence-type"><option value="all">All</option><option value="optimizer">Optimizers</option><option value="routing">Routing</option><option value="harness">Coding apps</option><option value="candidate">Experiments</option></select></label><label>Sort <select id="evidence-sort"><option value="name">Name</option><option value="evidence">Evidence count</option><option value="type">Type</option></select></label></div>
41597
+ <div class="evidence-table-scroll"><table class="evidence-table"><thead><tr><th scope="col">System</th><th scope="col">Scope</th><th scope="col">Measured evidence</th><th scope="col">Details</th></tr></thead><tbody id="result-evidence"><tr><td colspan="4">Checking recorded results\u2026</td></tr></tbody></table></div>
41598
+ <p id="evidence-empty" class="empty" hidden>No evidence matches these filters.</p>
41599
+ </section>
41600
+ <div class="section-title"><div><h2>Recent activity</h2><p>Latest checks and changes from this app session.</p></div></div><section class="panel"><div id="activity" class="activity-scroll"><p class="empty">No activity yet.</p></div></section>
41322
41601
  </section>
41323
41602
 
41324
41603
  <footer><span>Local data. No account required.</span><span>Full overview refresh runs only when you choose Refresh.</span></footer>
@@ -41506,6 +41785,10 @@ function createGuideHandler(input) {
41506
41785
  send(200, JSON.stringify(input.service.status()));
41507
41786
  return;
41508
41787
  }
41788
+ if (url.pathname === "/api/routing") {
41789
+ send(200, JSON.stringify(await input.service.routing()));
41790
+ return;
41791
+ }
41509
41792
  if (url.pathname === "/api/candidate-campaign") {
41510
41793
  if (input.candidateCampaign === void 0)
41511
41794
  throw new GuideError(404, "Candidate campaign status is unavailable.");
@@ -41563,6 +41846,12 @@ function createGuideHandler(input) {
41563
41846
  send(200, JSON.stringify(result6));
41564
41847
  return;
41565
41848
  }
41849
+ if (url.pathname === "/api/restart") {
41850
+ if (body === null || typeof body !== "object" || Array.isArray(body) || Object.keys(body).length !== 0)
41851
+ throw new GuideError(400, "Restart accepts no commands or paths.");
41852
+ send(200, JSON.stringify(await input.service.restart()));
41853
+ return;
41854
+ }
41566
41855
  if (url.pathname === "/api/update-check") {
41567
41856
  if (body === null || typeof body !== "object" || Array.isArray(body))
41568
41857
  throw new GuideError(400, "Only an optional reporting period is accepted.");
@@ -42106,6 +42395,7 @@ async function runGuidedUi(options, base) {
42106
42395
  }
42107
42396
  return result6;
42108
42397
  };
42398
+ const entryScript = base.adapters === null || base.adapters === void 0 || base.applicationEntryScript === void 0 || base.applicationEntryScript === null ? null : await base.adapters.fs.canonicalPath?.(base.applicationEntryScript) ?? null;
42109
42399
  const service = new GuideService(guideCall, () => Date.now(), () => randomBytes2(32).toString("hex"), async (harness) => {
42110
42400
  if (base.adapters === null || base.adapters === void 0) {
42111
42401
  return {
@@ -42147,8 +42437,23 @@ async function runGuidedUi(options, base) {
42147
42437
  facts: base.platform,
42148
42438
  paths: base.adapters.paths,
42149
42439
  projectRoot: base.cwd,
42150
- projectId: base.adapters.projectIdFor(base.cwd)
42440
+ projectId: null
42441
+ });
42442
+ }, async () => {
42443
+ if (entryScript === null || base.adapters === null || base.adapters === void 0 || base.platform === null)
42444
+ throw new Error("The installed app entry could not be verified.");
42445
+ const current = await base.adapters.fs.canonicalPath?.(base.applicationEntryScript);
42446
+ if (current !== entryScript || (await base.adapters.fs.stat(entryScript))?.kind !== "file")
42447
+ throw new Error("The app entry changed. Check the installation before restarting.");
42448
+ const url2 = await launchGuidedApplication({
42449
+ executable: process5.execPath,
42450
+ entryScript,
42451
+ cwd: base.cwd,
42452
+ facts: base.platform,
42453
+ env: process5.env
42151
42454
  });
42455
+ setTimeout(() => server.close(), 1e3);
42456
+ return url2;
42152
42457
  });
42153
42458
  const token = randomBytes2(32).toString("hex");
42154
42459
  let authority = "";
@@ -42177,6 +42482,8 @@ async function runGuidedUi(options, base) {
42177
42482
  }
42178
42483
  authority = `127.0.0.1:${address.port}`;
42179
42484
  const url = `http://${authority}/`;
42485
+ if (process5.send !== void 0)
42486
+ process5.send({ type: "token-harness-guide-ready", url });
42180
42487
  process5.stdout.write(`Token Harness is ready: ${url}
42181
42488
 
42182
42489
  Use the browser to review setup, see recorded savings and read the active rules.