token-harness 0.1.12 → 0.1.14

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/README.md CHANGED
@@ -29,90 +29,67 @@ of CLI commands to memorize.
29
29
 
30
30
  ### First run
31
31
 
32
- 1. Open **Dashboard** and let Token Harness inspect the current setup.
33
- 2. If setup is incomplete, choose **Open setup**.
34
- 3. In **Setup**, work from top to bottom:
35
- - Coding agents
36
- - Managed optimizers
37
- - Optional agent tuning
38
- - Checks and maintenance
39
- 4. For Claude Code or Codex, choose **Review baseline** when the RTK + HarnessTrim setup is available.
40
- 5. Read the exact proposed changes. **Apply reviewed setup** appears only when there is a concrete
41
- safe plan to apply.
42
- 6. Keep using Claude Code or Codex normally.
43
- 7. Open **Results** when you want to see what Token Harness can actually prove.
32
+ The first screen is **Overview**. There is no separate Setup page to learn.
44
33
 
45
- Opening the app does not change your configuration. Read-only checks stay read-only, and a managed
46
- write requires an explicit review and approval.
34
+ 1. Token Harness detects Claude Code and Codex.
35
+ 2. Each detected coding agent says either **Ready** or **Setup incomplete**.
36
+ 3. If setup is incomplete, choose **Finish setup** on that agent. Token Harness prepares the
37
+ recommended **RTK + HarnessTrim** baseline and shows the exact safe plan before anything changes.
38
+ 4. The **Optimizers** section keeps the recommended baseline separate from optional tools
39
+ (mcptoon, GitNexus and Headroom). When a tool needs an action, that action appears on the same
40
+ card as the status it refers to.
41
+ 5. **Health and updates** is maintenance, not another onboarding checklist. Normal setup performs its
42
+ own safety checks. Use **Re-check health** for troubleshooting and **Check for updates** when you
43
+ want to inspect provider versions. If a reviewed update is available, the same dialog offers
44
+ **Install updates** after showing the versions.
45
+ 6. Keep using Claude Code or Codex normally. Open **Results** when you want detailed evidence.
47
46
 
48
- ## The three views
47
+ Opening the app does not change your configuration. A configuration or software change is always
48
+ previewed first and requires an explicit review and approval.
49
49
 
50
- ### Dashboard
50
+ ## The two views
51
51
 
52
- Dashboard answers the questions that matter first:
52
+ ### Overview
53
53
 
54
- - is my setup ready;
55
- - which coding agents and managed optimizers are active;
56
- - what should I do next;
57
- - what value has actually been measured;
58
- - whether quality or an integration needs attention.
54
+ Overview is both the first-run screen and the normal status screen. It keeps the two product entities
55
+ separate:
59
56
 
60
- The headline cards deliberately distinguish measured evidence from unknown values. Missing evidence
61
- is never shown as zero savings.
57
+ - **Coding agents** — currently Claude Code and Codex. Detection only means Token Harness can see the
58
+ agent; first-run setup is complete for that agent only when both RTK and HarnessTrim are connected.
59
+ - **Optimizers** — RTK and HarnessTrim are the recommended baseline. mcptoon, GitNexus and Headroom
60
+ are optional reviewed integrations with narrower prerequisites and compatibility boundaries.
62
61
 
63
- ### Setup
62
+ The status at the top always answers what to do next. States such as **Setup incomplete**,
63
+ **Installed · not connected**, **Needs attention**, or **Update available** have their action beside
64
+ the affected agent or optimizer instead of in a separate action list.
64
65
 
65
- Setup is one ordered workflow instead of a collection of unrelated actions.
66
+ Overview also contains a compact **Measured impact** summary. Missing evidence is shown as unknown,
67
+ never as zero savings.
66
68
 
67
- **1. Coding agents**
69
+ Advanced agent details and reasoning preferences are collapsed because they are not required for
70
+ first-run optimizer setup.
68
71
 
69
- Token Harness currently supports guided setup for Claude Code and Codex. Agent details also show
70
- useful read-only allowance and connected-tool observations when available.
72
+ ### Optimizer lifecycle and evidence
71
73
 
72
- **2. Managed optimizers**
74
+ The recommended baseline remains **RTK + HarnessTrim** on individually reviewed combinations.
75
+ Token Harness also exposes **mcptoon**, **GitNexus** and **Headroom** as optional managed integrations
76
+ on exact reviewed lifecycle rows. Enabling an optional optimizer does not make it part of the
77
+ production baseline and does not create a savings claim.
73
78
 
74
- The production baseline remains **RTK + HarnessTrim** on individually reviewed combinations.
75
- Token Harness also exposes **mcptoon**, **GitNexus** and **Headroom** as optional managed integrations on their exact
76
- reviewed lifecycle rows; enabling any of them does not make it part of the production baseline or create a
77
- savings claim. Token Harness tracks the exact combined provider set separately: if no combined-stack
78
- review is recorded, Setup says so and keeps the stack incomplete rather than inferring compatibility
79
- from healthy individual checks. Token Harness can prepare their integration transactionally, show the
80
- exact plan, apply it only after approval, verify it, and remove only configuration it owns.
79
+ Token Harness can prepare supported integration changes transactionally, show the exact plan, apply
80
+ it only after approval, verify what the declared tier can verify, and remove only configuration it
81
+ owns. GitNexus is never auto-indexed and its noncommercial license boundary stays visible. Headroom
82
+ remains config-only managed on its reviewed row; Token Harness does not bootstrap uv/Python or start
83
+ wrapper/proxy/deploy flows.
81
84
 
82
- For maintainers validating the combined stack, `token-harness stack-review --json` captures the exact
83
- configured provider versions and managed harness sets and reuses the existing passive `verify`
84
- evidence for exact provider/harness pairs. Runtime evidence is credited only when it can be
85
- attributed to that harness: HarnessTrim uses its native event harness field, while provider-wide
86
- telemetry can be attributed by exclusion only when one harness is wired. With multiple harnesses, an
87
- unattributable receipt stays **Unavailable** instead of being copied across rows. A `not-exercised`
88
- result does not promise that ordinary agent use will create a receipt: the provider must record a
89
- qualifying operation, and for reducers that means a real reduction. `stack-review` does not run an
90
- active canary or spend a model call, and it never makes the compatibility decision itself. The
91
- shipped combined-review registry stays empty until the captured configuration has enough real
92
- verification evidence, has been benchmarked together, and has been deliberately reviewed; see
93
- `docs/combined-stack-reviews.md`.
85
+ For maintainers, `token-harness stack-review --json` captures the exact configured provider versions
86
+ and managed harness sets for combined-stack review. Runtime evidence is credited only when it can be
87
+ attributed to the relevant harness; missing attribution remains unavailable rather than being copied
88
+ across rows.
94
89
 
95
- **3. Evaluation evidence (maintainers)**
96
-
97
- Selection campaigns and historical candidate evidence remain available for maintainers, but they are
98
- not a separate novice setup product. Once a tool has a reviewed managed lifecycle, Setup presents it in
99
- the same **Optimization Stack** with its exact state, version, prerequisites, harness scope and safe
100
- Apply/Remove controls. Evaluation evidence never turns into a savings or compatibility claim by itself.
101
-
102
- Headroom is config-only managed on its exact reviewed 0.37.0 row. Token Harness can own the narrow
103
- Claude Code or Codex MCP registration after the pinned CLI is present; it deliberately does not
104
- bootstrap `uv`/Python, start wrappers/proxies, or claim runtime compression savings. GitNexus likewise
105
- does not auto-index repositories, and its noncommercial license boundary stays visible.
106
-
107
- **4. Optional agent tuning**
108
-
109
- Reasoning preferences are separate from optimizer installation. They are persistent agent settings,
110
- not hidden per-task switches, and are changed only through the normal preview/apply flow.
111
-
112
- **5. Checks and maintenance**
113
-
114
- Read-only integration checks, update checks and safe removal/undo controls live here. An update
115
- outside reviewed compatibility is not forced.
90
+ Evaluation campaigns are an advanced maintainer workflow, not a novice setup step. Normal managed
91
+ setup stays in the unified **Optimization Stack** and historical candidate evidence never turns into
92
+ a savings, compatibility or promotion claim by itself.
116
93
 
117
94
  ### Results
118
95
 
@@ -384,8 +361,9 @@ Update Token Harness itself:
384
361
  npm install --global token-harness@latest
385
362
  ```
386
363
 
387
- Provider checks and reviewed updates are in **Setup -> Checks and maintenance**. From the advanced
388
- CLI, first preview and then explicitly apply the provider-package updates:
364
+ Provider checks and reviewed updates are in **Overview -> Health and updates**. The browser first
365
+ checks reviewed channels and, when an installable update exists, offers **Install updates** in the
366
+ same dialog. From the advanced CLI, the preview prints the exact confirmation command:
389
367
 
390
368
  ```sh
391
369
  token-harness update
@@ -442,7 +420,7 @@ Node must be at least 22.13. Reopen the terminal after installation if needed.
442
420
 
443
421
  ### Setup or verification needs attention
444
422
 
445
- Use the action shown in Dashboard or Setup. For technical evidence:
423
+ Use the action shown beside the affected agent or optimizer in Overview. For technical evidence:
446
424
 
447
425
  ```sh
448
426
  token-harness doctor --verbose
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "token-harness",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "description": "Quota-aware efficiency layer for Claude Code and Codex subscription limits.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
package/sbom.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "bomFormat": "CycloneDX",
3
3
  "specVersion": "1.5",
4
- "serialNumber": "urn:uuid:584dee19-a861-2f17-f82a-93efadc2de0b",
4
+ "serialNumber": "urn:uuid:8840bbd7-fcea-b78f-b033-a40bef562512",
5
5
  "version": 1,
6
6
  "metadata": {
7
7
  "component": {
8
8
  "type": "application",
9
9
  "bom-ref": "token-harness",
10
10
  "name": "token-harness",
11
- "version": "0.1.12",
11
+ "version": "0.1.14",
12
12
  "description": "Quota-aware efficiency layer for Claude Code and Codex subscription limits.",
13
13
  "licenses": [
14
14
  {
@@ -20,7 +20,7 @@
20
20
  "hashes": [
21
21
  {
22
22
  "alg": "SHA-256",
23
- "content": "584dee19a8612f17f82a93efadc2de0b6c8b28fc96bd7a7d44b9e5af2dbb09bc"
23
+ "content": "8840bbd7fceab78fb033a40bef5625123772648c48cb4fea73b39020b714e9cf"
24
24
  }
25
25
  ]
26
26
  },
package/token-harness.mjs CHANGED
@@ -9387,7 +9387,7 @@ var TOOL_VERSION;
9387
9387
  var init_version2 = __esm({
9388
9388
  "apps/cli/dist/src/version.js"() {
9389
9389
  "use strict";
9390
- TOOL_VERSION = "0.1.12";
9390
+ TOOL_VERSION = "0.1.14";
9391
9391
  }
9392
9392
  });
9393
9393
 
@@ -28522,7 +28522,7 @@ async function runUpdate(context) {
28522
28522
  receiptId: null
28523
28523
  }
28524
28524
  };
28525
- return result5(EXIT_CODES["confirmation-required"], null, [
28525
+ return result5(EXIT_CODES["confirmation-required"], report2, [
28526
28526
  ...preparedDiagnostics,
28527
28527
  adoptionConfirmationDiagnostic(plan6),
28528
28528
  confirmationDiagnostic(report2)
@@ -32753,30 +32753,43 @@ var init_guided = __esm({
32753
32753
  let network = false;
32754
32754
  for (const agent of selected) {
32755
32755
  this.record(`Preparing supported changes for ${name(agent.harnessId)}. No settings changed.`, "working");
32756
- const args = ["plan", "--harness", agent.harnessId];
32757
- if (data["action"] === "setup" && data["provider"] !== void 0)
32758
- args.push("--provider", String(data["provider"]));
32759
- if (data["action"] === "skill") {
32760
- args.push("--provider", "none", "--agent-skill");
32761
- } else if (data["action"] === "effort")
32762
- args.push("--provider", "none", "--native-policy", "--task", String(data["task"]), "--profile", data["task"] === "mechanical" ? "economy" : data["task"] === "standard" ? "balanced" : "quality");
32763
- const result6 = await this.call(args);
32764
- const report = result6.data;
32765
- if (report === null || result6.exitCode !== 0 || report.conflicts.length > 0 || report.actions.length === 0 || !report.persisted || report.planId === null) {
32766
- notices.push(`${name(agent.harnessId)}: ${explainGuideIssue(result6.diagnostics, data["action"] === "effort" ? "No supported preference change is needed or available. Your current preference is kept." : data["action"] === "skill" ? "In-session guidance is already present, or an existing user-owned skill location was left untouched." : "No safe setup change is available. The integration may already be configured, or a required provider is not installed.")}`);
32767
- continue;
32768
- }
32769
- plans.push(report.planId);
32770
- if (data["action"] === "skill") {
32771
- changes.push({
32772
- title: `${name(agent.harnessId)}: enable in-session guidance`,
32773
- description: "Installs one reviewed Token Harness Agent Skill in the standard user skill directory. It does not change model, login, billing, hooks, trust, or the current conversation.",
32774
- files: 1
32775
- });
32756
+ const setupProviders = [];
32757
+ if (data["action"] === "setup" && data["harness"] !== void 0) {
32758
+ if (data["provider"] === void 0) {
32759
+ setupProviders.push("rtk", "harnesstrim");
32760
+ } else {
32761
+ setupProviders.push(String(data["provider"]));
32762
+ }
32776
32763
  } else {
32777
- changes.push(...report.actions.map((action2) => describeChange(action2, agent.harnessId)));
32764
+ setupProviders.push(null);
32765
+ }
32766
+ for (const setupProvider of setupProviders) {
32767
+ const args = ["plan", "--harness", agent.harnessId];
32768
+ if (setupProvider !== null)
32769
+ args.push("--provider", setupProvider);
32770
+ if (data["action"] === "skill") {
32771
+ args.push("--provider", "none", "--agent-skill");
32772
+ } else if (data["action"] === "effort")
32773
+ args.push("--provider", "none", "--native-policy", "--task", String(data["task"]), "--profile", data["task"] === "mechanical" ? "economy" : data["task"] === "standard" ? "balanced" : "quality");
32774
+ const result6 = await this.call(args);
32775
+ const report = result6.data;
32776
+ if (report === null || result6.exitCode !== 0 || report.conflicts.length > 0 || report.actions.length === 0 || !report.persisted || report.planId === null) {
32777
+ const subject = setupProvider !== null ? `${name(agent.harnessId)} \xB7 ${name(setupProvider)}` : name(agent.harnessId);
32778
+ notices.push(`${subject}: ${explainGuideIssue(result6.diagnostics, data["action"] === "effort" ? "No supported preference change is needed or available. Your current preference is kept." : data["action"] === "skill" ? "In-session guidance is already present, or an existing user-owned skill location was left untouched." : "No safe setup change is available. The integration may already be configured, or a required provider is not installed.")}`);
32779
+ continue;
32780
+ }
32781
+ plans.push(report.planId);
32782
+ if (data["action"] === "skill") {
32783
+ changes.push({
32784
+ title: `${name(agent.harnessId)}: enable in-session guidance`,
32785
+ description: "Installs one reviewed Token Harness Agent Skill in the standard user skill directory. It does not change model, login, billing, hooks, trust, or the current conversation.",
32786
+ files: 1
32787
+ });
32788
+ } else {
32789
+ changes.push(...report.actions.map((action2) => describeChange(action2, agent.harnessId)));
32790
+ }
32791
+ network ||= report.network.length > 0;
32778
32792
  }
32779
- network ||= report.network.length > 0;
32780
32793
  }
32781
32794
  if (selected.length === 0)
32782
32795
  notices.push("No supported coding agent was found. Install and sign in to Claude Code or Codex, then refresh.");
@@ -32816,6 +32829,52 @@ var init_guided = __esm({
32816
32829
  if (approval === null || approval.id !== data["ticket"] || this.now() >= approval.expires)
32817
32830
  throw new GuideError(409, "This preview expired or was already used. Review a fresh preview.");
32818
32831
  this.approval = null;
32832
+ if (approval.operation === "update") {
32833
+ this.record("Installing only the reviewed provider updates you approved.", "working");
32834
+ let result6;
32835
+ try {
32836
+ result6 = await this.call(["update", "--yes"]);
32837
+ } catch {
32838
+ this.invalidateObservedState();
32839
+ const message = "The update stopped before its final result could be read. No automatic retry was made. Refresh and inspect the installed optimizer versions before retrying.";
32840
+ this.record(message, "attention");
32841
+ return {
32842
+ ok: false,
32843
+ title: "Update result needs checking",
32844
+ messages: [message],
32845
+ appliedPlans: 0
32846
+ };
32847
+ }
32848
+ if (result6.exitCode !== 0 || result6.data === null) {
32849
+ const message = explainGuideIssue(result6.diagnostics, "The reviewed optimizer update was not applied. The installed version, update channel or compatibility evidence changed after the preview, so nothing was forced.");
32850
+ this.invalidateObservedState();
32851
+ this.record(message, "attention");
32852
+ return {
32853
+ ok: false,
32854
+ title: "Optimizer update was not applied",
32855
+ messages: [message],
32856
+ appliedPlans: 0
32857
+ };
32858
+ }
32859
+ const applied = result6.data.execution?.results.filter((row2) => row2.status === "applied") ?? [];
32860
+ this.lastApplied = null;
32861
+ this.invalidateObservedState();
32862
+ const messages2 = applied.length > 0 ? [
32863
+ "The reviewed optimizer update completed successfully.",
32864
+ "Token Harness re-ran the update transaction safety checks before changing software.",
32865
+ "Choose Refresh to read the installed versions again. Reopen a coding agent if the updated optimizer requires it."
32866
+ ] : [
32867
+ "No optimizer needed an update by the time the approved action ran.",
32868
+ "Nothing was forced. Choose Refresh to read the current versions."
32869
+ ];
32870
+ this.record(applied.length > 0 ? "Reviewed optimizer update installed." : "Optimizer update no longer needed.", "success");
32871
+ return {
32872
+ ok: true,
32873
+ title: applied.length > 0 ? "Optimizer updated" : "Already up to date",
32874
+ messages: messages2,
32875
+ appliedPlans: applied.length
32876
+ };
32877
+ }
32819
32878
  if (approval.operation === "candidate-apply" || approval.operation === "candidate-uninstall") {
32820
32879
  if (approval.candidate === void 0 || approval.candidateHarness === void 0)
32821
32880
  throw new GuideError(409, "This experimental preview is incomplete. Review it again.");
@@ -32971,6 +33030,7 @@ var init_guided = __esm({
32971
33030
  }
32972
33031
  async checkUpdates() {
32973
33032
  return this.exclusive(async () => {
33033
+ this.approval = null;
32974
33034
  this.record("Checking provider update channels without changing software.", "working");
32975
33035
  const updateResult = await this.call(["update"]);
32976
33036
  const inventory = await this.call(["doctor"]);
@@ -32982,7 +33042,8 @@ var init_guided = __esm({
32982
33042
  ok: false,
32983
33043
  title: "Update check needs attention",
32984
33044
  messages: [message],
32985
- appliedPlans: 0
33045
+ appliedPlans: 0,
33046
+ ticket: null
32986
33047
  };
32987
33048
  }
32988
33049
  const fingerprint = stackFingerprint(inventory.data);
@@ -33004,7 +33065,8 @@ var init_guided = __esm({
33004
33065
  title: "Update check needs attention",
33005
33066
  messages: [message],
33006
33067
  appliedPlans: 0,
33007
- stack: stack2
33068
+ stack: stack2,
33069
+ ticket: null
33008
33070
  };
33009
33071
  }
33010
33072
  this.updates = { fingerprint, report: updateResult.data };
@@ -33012,19 +33074,43 @@ var init_guided = __esm({
33012
33074
  const blocked = updateResult.data.providers.filter((row2) => row2.verdict === "blocked-unreviewed");
33013
33075
  const messages = [];
33014
33076
  if (available.length > 0) {
33015
- messages.push(...available.map((row2) => `${name(row2.providerId)}: ${row2.installed ?? "installed version"} \u2192 ${row2.available ?? "new version"} is available. Run token-harness update to review the dry-run; applying still requires explicit approval.`));
33077
+ messages.push(...available.map((row2) => `${name(row2.providerId)}: ${row2.installed ?? "installed version"} \u2192 ${row2.available ?? "new version"} is reviewed and ready to install.`));
33016
33078
  }
33017
33079
  if (blocked.length > 0) {
33018
- messages.push(...blocked.map((row2) => `${name(row2.providerId)}: ${row2.available ?? "a newer version"} exists, but Token Harness is keeping ${row2.installed ?? "the installed version"} until that combination has reviewed compatibility evidence.`));
33080
+ messages.push(...blocked.map((row2) => `${name(row2.providerId)}: ${row2.available ?? "a newer version"} exists, but Token Harness is keeping ${row2.installed ?? "the installed version"} because that newer combination is not reviewed yet.`));
33019
33081
  }
33020
33082
  if (available.length === 0 && blocked.length === 0)
33021
- messages.push("No reviewed provider update is currently available. Pins and unavailable channels remain visible in the stack.");
33022
- messages.push("This was a read-only channel check. No provider was installed, updated, downgraded or enabled.");
33083
+ messages.push("Your managed optimizers are up to date on their reviewed channels.");
33084
+ let ticket = null;
33085
+ if (available.length > 0) {
33086
+ ticket = this.random();
33087
+ const expires = this.now() + 10 * 6e4;
33088
+ this.approval = {
33089
+ id: ticket,
33090
+ expires,
33091
+ plans: [],
33092
+ transactionId: null,
33093
+ provider: null,
33094
+ description: "Optimizer updates",
33095
+ operation: "update",
33096
+ network: updateResult.data.network.length > 0
33097
+ };
33098
+ messages.push("Review the versions above, then choose Install updates. Token Harness will re-check the update channels and transaction safety rules before changing software.");
33099
+ } else {
33100
+ messages.push("No software was changed.");
33101
+ }
33023
33102
  const stack = this.stackSnapshot();
33024
33103
  if (this.cached !== null)
33025
33104
  this.cached.value = { ...this.cached.value, stack };
33026
- this.record("Provider update check completed. No software changed.", "success");
33027
- return { ok: true, title: "Optimizer update check", messages, appliedPlans: 0, stack };
33105
+ this.record(available.length > 0 ? "Reviewed optimizer update available. Waiting for your approval." : "Provider update check completed. No reviewed update is pending.", "success");
33106
+ return {
33107
+ ok: true,
33108
+ title: available.length > 0 ? "Updates available" : "Optimizers up to date",
33109
+ messages,
33110
+ appliedPlans: 0,
33111
+ stack,
33112
+ ticket
33113
+ };
33028
33114
  });
33029
33115
  }
33030
33116
  async verify() {
@@ -34767,9 +34853,20 @@ var init_guided_capabilities_client = __esm({
34767
34853
  return data;
34768
34854
  }
34769
34855
 
34770
- function markStale() {
34771
- $('stale-state').hidden = false;
34772
- $('stale-state').textContent = 'A reviewed change was applied. Displayed status is the previous state until you choose Refresh.';
34856
+ async function waitForAutomaticRefresh() {
34857
+ $('stale-state').hidden = true;
34858
+ $('stale-state').textContent = '';
34859
+ const spinner = $('reading-spinner');
34860
+ const refresh = $('refresh');
34861
+ let observedRefresh = false;
34862
+ refresh.click();
34863
+ const deadline = Date.now() + 120000;
34864
+ while (Date.now() < deadline) {
34865
+ if (!spinner.hidden) observedRefresh = true;
34866
+ if (observedRefresh && spinner.hidden) return;
34867
+ await new Promise(resolve => setTimeout(resolve, 100));
34868
+ }
34869
+ throw new Error('The latest setup state could not be read automatically.');
34773
34870
  }
34774
34871
 
34775
34872
  async function applyTicket(ticket, title) {
@@ -34782,11 +34879,33 @@ var init_guided_capabilities_client = __esm({
34782
34879
  const result = await request('/api/apply', { ticket });
34783
34880
  if (activeRun !== runId) return;
34784
34881
  $('modal-title').textContent = result.ok ? title : 'Change needs attention';
34785
- $('modal-content').replaceChildren(message(result.ok ? 'Completed' : 'Needs attention', (result.messages || []).join(' ') || 'The transaction finished.', result.ok ? 'safe' : 'warn'));
34786
- if (result.ok) markStale();
34882
+ $('modal-content').replaceChildren(
34883
+ message(
34884
+ result.ok ? 'Applied' : 'Needs attention',
34885
+ (result.messages || []).join(' ') || 'The transaction finished.',
34886
+ result.ok ? 'safe' : 'warn',
34887
+ ),
34888
+ progress(
34889
+ 'Refreshing the current setup',
34890
+ 'Please wait while Token Harness re-reads the latest agent and optimizer state.',
34891
+ ),
34892
+ );
34893
+ $('modal-actions').replaceChildren(closeButton('Refreshing…', true));
34894
+ await waitForAutomaticRefresh();
34895
+ if (activeRun !== runId) return;
34896
+ $('modal-content').replaceChildren(
34897
+ message(
34898
+ result.ok ? 'Completed and refreshed' : 'Action finished; status refreshed',
34899
+ (result.messages || []).join(' ') || 'The latest setup state is now displayed.',
34900
+ result.ok ? 'safe' : 'warn',
34901
+ ),
34902
+ );
34787
34903
  $('modal-actions').replaceChildren(closeButton('Done'));
34788
34904
  } catch (error) {
34789
34905
  if (activeRun !== runId) return;
34906
+ $('stale-state').hidden = false;
34907
+ $('stale-state').textContent =
34908
+ 'The action finished, but Token Harness could not automatically refresh the latest setup state.';
34790
34909
  $('modal-error').textContent = error.message;
34791
34910
  $('modal-error').hidden = false;
34792
34911
  $('modal-actions').replaceChildren(closeButton('Close'));
@@ -34808,14 +34927,22 @@ var init_guided_capabilities_client = __esm({
34808
34927
  const data = await request('/api/preview', body);
34809
34928
  if (activeRun !== runId || !$('modal').open) return;
34810
34929
  $('modal-content').replaceChildren();
34811
- if (!(data.changes || []).length)
34812
- $('modal-content').append(message('No managed change proposed', (data.notices || []).join(' ') || 'Nothing needs to be changed.'));
34813
- for (const change of data.changes || []) {
34814
- const item = node('article', undefined, 'preview-change');
34815
- item.append(node('h3', change.title), node('p', change.description));
34816
- $('modal-content').append(item);
34817
- }
34818
- for (const notice of data.notices || []) $('modal-content').append(node('p', notice, 'notice-row'));
34930
+ if (!(data.changes || []).length) {
34931
+ $('modal-content').append(
34932
+ message(
34933
+ 'No managed change proposed',
34934
+ (data.notices || []).join(' ') || 'Nothing needs to be changed.',
34935
+ ),
34936
+ );
34937
+ } else {
34938
+ for (const change of data.changes || []) {
34939
+ const item = node('article', undefined, 'preview-change');
34940
+ item.append(node('h3', change.title), node('p', change.description));
34941
+ $('modal-content').append(item);
34942
+ }
34943
+ for (const notice of data.notices || [])
34944
+ $('modal-content').append(node('p', notice, 'notice-row'));
34945
+ }
34819
34946
  $('modal-content').append(message('Safety', 'Only Token Harness-owned changes can be applied or removed. User-owned provider installations and unrelated configuration are left untouched.', 'safe'));
34820
34947
  $('modal-actions').replaceChildren(closeButton(data.ticket ? 'Cancel' : 'Done'));
34821
34948
  if (data.ticket)
@@ -35024,9 +35151,8 @@ var init_guided_product_client = __esm({
35024
35151
  const count = value => new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(value);
35025
35152
  const date = value => value ? new Date(value).toLocaleString() : 'not recorded';
35026
35153
  const VIEWS = {
35027
- dashboard: ['Dashboard', 'Your coding setup, what is active, and what to do next.'],
35028
- setup: ['Setup', 'Install and configure optimization tools in a clear order.'],
35029
- results: ['Results', 'Measured savings, quality evidence, and recent activity.'],
35154
+ dashboard: ['Overview', 'Your coding agents, optimizer setup, health and measured results in one place.'],
35155
+ results: ['Results', 'Detailed measured savings, quality evidence, and recent activity.'],
35030
35156
  };
35031
35157
  const TOOL_INFO = {
35032
35158
  rtk: {
@@ -35232,6 +35358,24 @@ var init_guided_product_client = __esm({
35232
35358
  return (current?.stack?.components || []).filter(component => component.configured);
35233
35359
  }
35234
35360
 
35361
+ function componentConfiguredFor(id, agentId) {
35362
+ const component = managedComponent(id);
35363
+ return Boolean(component?.configuredHarnesses?.includes(agentId));
35364
+ }
35365
+
35366
+ function baselineReadyFor(agentId) {
35367
+ return componentConfiguredFor('rtk', agentId) && componentConfiguredFor('harnesstrim', agentId);
35368
+ }
35369
+
35370
+ function baselineIncompleteAgents() {
35371
+ return activeAgents().filter(agent => !baselineReadyFor(agent.id));
35372
+ }
35373
+
35374
+ function providerSupportsAgent(providerId, agentId) {
35375
+ if (providerId === 'gitnexus') return agentId === 'claude';
35376
+ return agentId === 'claude' || agentId === 'codex';
35377
+ }
35378
+
35235
35379
  function candidateObservation(id) {
35236
35380
  return (current?.optimizationCandidates || []).find(item => item.id === id) || null;
35237
35381
  }
@@ -35278,21 +35422,21 @@ var init_guided_product_client = __esm({
35278
35422
 
35279
35423
  function setupAssessment() {
35280
35424
  const agents = activeAgents();
35281
- const configured = configuredProviders();
35425
+ const incomplete = baselineIncompleteAgents();
35282
35426
  const stack = current?.stack;
35283
35427
  if (!agents.length)
35284
35428
  return {
35285
35429
  label: 'Agent needed',
35286
35430
  cls: 'warn',
35287
- title: 'Connect a supported coding agent first',
35288
- detail: 'Token Harness could not find Claude Code or Codex in the environment that started this app.',
35289
- action: 'setup',
35431
+ title: 'Install or expose Claude Code or Codex first',
35432
+ detail: 'Token Harness could not find a supported coding agent in the environment that started this app.',
35433
+ action: 'none',
35290
35434
  };
35291
35435
  if (current?.value?.quality?.state === 'regressed')
35292
35436
  return {
35293
35437
  label: 'Needs attention',
35294
35438
  cls: 'warn',
35295
- title: 'Review the quality regression before increasing optimization',
35439
+ title: 'Measured quality needs attention',
35296
35440
  detail: 'A paired benchmark favored the baseline. Token Harness is not crediting the affected savings.',
35297
35441
  action: 'results',
35298
35442
  };
@@ -35300,31 +35444,33 @@ var init_guided_product_client = __esm({
35300
35444
  return {
35301
35445
  label: 'Needs attention',
35302
35446
  cls: 'warn',
35303
- title: 'One integration needs attention',
35304
- detail: 'Open Setup to see the affected tool and run the read-only integration check.',
35305
- action: 'setup',
35447
+ title: 'One configured optimizer needs attention',
35448
+ detail: 'Use Re-check health below to see whether the configured integration still matches its reviewed state.',
35449
+ action: 'verify',
35306
35450
  };
35307
- if (!configured.length)
35451
+ if (incomplete.length)
35308
35452
  return {
35309
35453
  label: 'Setup incomplete',
35310
35454
  cls: 'warn',
35311
- title: 'Your coding agent is ready; add the managed optimization stack',
35312
- detail: 'Start with RTK and HarnessTrim. You will review every proposed configuration change before it is applied.',
35313
- action: 'setup',
35455
+ title: incomplete.length === 1
35456
+ ? 'Finish setup for ' + incomplete[0].name
35457
+ : 'Finish the recommended setup for your coding agents',
35458
+ detail: 'The recommended baseline is RTK + HarnessTrim. Finish setup on each incomplete coding-agent card below; you will see the exact safe plan before anything changes.',
35459
+ action: 'configure',
35314
35460
  };
35315
35461
  if (!(current?.savings?.rows || []).length)
35316
35462
  return {
35317
35463
  label: 'Ready',
35318
35464
  cls: 'good',
35319
- title: 'Setup is ready; use your coding agent normally',
35320
- detail: 'Token Harness has no measured result yet. Keep working normally and results will appear after evidence is recorded.',
35465
+ title: 'Recommended setup is complete',
35466
+ detail: 'Use your coding agents normally. Measured results will appear when Token Harness has evidence to report.',
35321
35467
  action: 'results',
35322
35468
  };
35323
35469
  return {
35324
35470
  label: 'Ready',
35325
35471
  cls: 'good',
35326
- title: 'Your managed setup is active',
35327
- detail: 'No urgent action is required. Review measured results or manage optional optimizers when you want to.',
35472
+ title: 'Your recommended setup is active',
35473
+ detail: 'No setup action is required. The summary below shows what Token Harness can actually measure.',
35328
35474
  action: 'results',
35329
35475
  };
35330
35476
  }
@@ -35342,15 +35488,14 @@ var init_guided_product_client = __esm({
35342
35488
  const assessment = setupAssessment();
35343
35489
  $('dashboard-status').replaceChildren();
35344
35490
  const main = node('div');
35345
- main.append(node('span', 'SETUP STATUS', 'eyebrow'), node('h2', assessment.title), node('p', assessment.detail));
35491
+ main.append(node('span', 'CURRENT STATUS', 'eyebrow'), node('h2', assessment.title), node('p', assessment.detail));
35346
35492
  const actions = node('div', undefined, 'inline-actions');
35347
- actions.append(
35348
- assessment.action === 'setup'
35349
- ? navigateButton('Open setup', 'setup')
35350
- : navigateButton('View results', 'results'),
35351
- );
35352
- if (assessment.action !== 'setup') actions.append(navigateButton('Manage setup', 'setup', 'secondary'));
35353
- main.append(actions);
35493
+ if (assessment.action === 'verify') {
35494
+ actions.append(actionButton('Re-check health', () => readOnlyOperation('verify')));
35495
+ } else if (assessment.action === 'results') {
35496
+ actions.append(navigateButton('View detailed results', 'results'));
35497
+ }
35498
+ if (actions.children.length) main.append(actions);
35354
35499
  $('dashboard-status').append(main, pill(assessment.label, assessment.cls));
35355
35500
 
35356
35501
  const reduction = bestReduction();
@@ -35364,46 +35509,18 @@ var init_guided_product_client = __esm({
35364
35509
  metricCard('API cost', 'Not measured yet', 'Requires billed-token evidence and a verified price basis.'),
35365
35510
  metricCard('Quality', quality.value, quality.detail, quality.cls),
35366
35511
  );
35367
-
35368
- const active = $('dashboard-active');
35369
- active.replaceChildren();
35370
- for (const agent of activeAgents()) {
35371
- const row = node('div', undefined, 'status-row');
35372
- row.append(node('div', agent.name + (agent.version ? ' · v' + agent.version : '')), pill(agent.state, agent.configured ? 'good' : ''));
35373
- active.append(row);
35374
- }
35375
- for (const component of configuredProviders()) {
35376
- const row = node('div', undefined, 'status-row');
35377
- const name = TOOL_INFO[component.providerId]?.name || component.displayName || component.providerId;
35378
- const configuredFor = (component.configuredHarnesses || []).map(agentName).join(', ');
35379
- row.append(node('div', name + (configuredFor ? ' · ' + configuredFor : '')), pill(component.health === 'healthy' ? 'Verified' : 'Configured', component.health === 'attention' ? 'warn' : 'good'));
35380
- active.append(row);
35381
- }
35382
- if (!active.children.length) active.append(sectionEmpty('No managed optimization is active yet. Open Setup to start.'));
35383
-
35384
- const checklist = $('dashboard-checklist');
35385
- checklist.replaceChildren();
35386
- const agentReady = activeAgents().length > 0;
35387
- const managedReady = configuredProviders().length > 0;
35388
- const evidenceReady = (current?.savings?.rows || []).length > 0;
35389
- for (const item of [
35390
- [agentReady, 'Coding agent detected', agentReady ? activeAgents().map(agent => agent.name).join(', ') : 'Claude Code or Codex must be visible to this process.'],
35391
- [managedReady, 'Managed optimizer configured', managedReady ? configuredProviders().map(item => TOOL_INFO[item.providerId]?.name || item.providerId).join(', ') : 'RTK/HarnessTrim setup has not been completed yet.'],
35392
- [evidenceReady, 'Measured result available', evidenceReady ? 'Recorded optimization evidence is available.' : 'Use your configured coding agent normally to build evidence.'],
35393
- ]) {
35394
- const row = node('div', undefined, 'check-row');
35395
- row.append(node('span', item[0] ? '✓' : '○', 'check-icon ' + (item[0] ? 'done' : '')), node('div'));
35396
- row.lastChild.append(node('strong', item[1]), node('p', item[2], 'caption'));
35397
- checklist.append(row);
35398
- }
35399
35512
  }
35400
35513
 
35401
35514
  function componentState(component) {
35402
- if (!component) return { label: 'Not detected', cls: '' };
35515
+ if (!component || component.detectedState === 'absent') return { label: 'Not installed', cls: '' };
35403
35516
  if (component.health === 'attention') return { label: 'Needs attention', cls: 'warn' };
35404
- if (component.configured) return { label: component.verification === 'verified' ? 'Configured + verified' : 'Configured', cls: 'good' };
35405
- if (component.installed) return { label: 'Installed · setup needed', cls: '' };
35406
- return { label: 'Not installed/configured', cls: '' };
35517
+ if (component.configured)
35518
+ return {
35519
+ label: component.verification === 'verified' ? 'Connected · verified' : 'Connected',
35520
+ cls: 'good',
35521
+ };
35522
+ if (component.installed) return { label: 'Installed · not connected', cls: '' };
35523
+ return { label: 'Not installed', cls: '' };
35407
35524
  }
35408
35525
 
35409
35526
  function renderManagedTool(id) {
@@ -35415,29 +35532,69 @@ var init_guided_product_client = __esm({
35415
35532
  const title = node('div');
35416
35533
  title.append(
35417
35534
  node('h3', info.name),
35418
- node('span', info.optional ? 'Optional managed integration' : 'Production baseline', 'caption'),
35535
+ node('span', info.optional ? 'Optional optimizer' : 'Recommended baseline', 'caption'),
35419
35536
  );
35420
35537
  head.append(title, pill(state.label, state.cls));
35421
35538
  card.append(head, node('p', info.role));
35539
+
35422
35540
  const facts = node('div', undefined, 'tool-facts');
35541
+ if (component?.version) facts.append(node('span', 'Installed version'), node('strong', 'v' + component.version));
35423
35542
  const configuredFor = component?.configuredHarnesses?.length
35424
35543
  ? component.configuredHarnesses.map(agentName).join(', ')
35425
- : 'No agent yet';
35426
- facts.append(node('span', 'Configured for'), node('strong', configuredFor));
35427
- if (component?.version) facts.append(node('span', 'Version'), node('strong', 'v' + component.version));
35544
+ : 'Not connected to a coding agent';
35545
+ facts.append(node('span', 'Connection'), node('strong', configuredFor));
35546
+ if (component?.update === 'available')
35547
+ facts.append(
35548
+ node('span', 'Update'),
35549
+ node('strong', 'v' + (component.updateAvailableVersion || 'new version') + ' available'),
35550
+ );
35551
+ else if (component?.update === 'blocked')
35552
+ facts.append(node('span', 'Update'), node('strong', 'Newer version not reviewed yet'));
35428
35553
  card.append(facts);
35554
+
35429
35555
  if (component?.warnings?.length) {
35430
35556
  const attention = component.health === 'attention';
35431
35557
  const prerequisite = !component.installed && component.nextAction?.kind === 'install-configure';
35432
35558
  if (attention || prerequisite)
35433
35559
  card.append(
35434
35560
  messageBox(
35435
- attention ? 'Needs attention' : 'Prerequisite needed',
35561
+ attention ? 'Needs attention' : 'Setup requirement',
35436
35562
  component.warnings[0].message,
35437
35563
  attention ? 'warn' : '',
35438
35564
  ),
35439
35565
  );
35440
35566
  }
35567
+
35568
+ const actions = node('div', undefined, 'inline-actions');
35569
+ for (const agent of activeAgents()) {
35570
+ if (!providerSupportsAgent(id, agent.id)) continue;
35571
+ if (component?.configuredHarnesses?.includes(agent.id)) continue;
35572
+ if (info.optional) {
35573
+ actions.append(
35574
+ actionButton(
35575
+ 'Set up for ' + agent.name,
35576
+ () => reviewSetup(agent.id, id),
35577
+ 'secondary',
35578
+ ),
35579
+ );
35580
+ } else {
35581
+ actions.append(
35582
+ actionButton(
35583
+ component?.installed ? 'Connect to ' + agent.name : 'Set up for ' + agent.name,
35584
+ () => reviewSetup(agent.id, id),
35585
+ 'secondary',
35586
+ ),
35587
+ );
35588
+ }
35589
+ }
35590
+ if (component?.update === 'available')
35591
+ actions.append(actionButton('Install update', () => readOnlyOperation('updates'), 'secondary'));
35592
+ if (
35593
+ component?.configured &&
35594
+ (component.health === 'attention' || component.verification === 'degraded')
35595
+ )
35596
+ actions.append(actionButton('Re-check health', () => readOnlyOperation('verify'), 'secondary'));
35597
+ if (actions.children.length) card.append(actions);
35441
35598
  return card;
35442
35599
  }
35443
35600
 
@@ -35445,16 +35602,47 @@ var init_guided_product_client = __esm({
35445
35602
  const root = $('setup-agents');
35446
35603
  root.replaceChildren();
35447
35604
  if (!activeAgents().length) {
35448
- root.append(messageBox('No supported agent detected', 'Start Token Harness from a terminal where Claude Code or Codex is installed and available on PATH, then choose Refresh.', 'warn'));
35605
+ root.append(
35606
+ messageBox(
35607
+ 'No supported coding agent detected',
35608
+ 'Start Token Harness from a terminal where Claude Code or Codex is installed and available on PATH, then choose Refresh.',
35609
+ 'warn',
35610
+ ),
35611
+ );
35449
35612
  return;
35450
35613
  }
35451
35614
  for (const agent of activeAgents()) {
35615
+ const ready = baselineReadyFor(agent.id);
35452
35616
  const card = node('article', undefined, 'tool-card compact');
35453
35617
  const head = node('div', undefined, 'tool-head');
35454
35618
  const title = node('div');
35455
- title.append(node('h3', agent.name), node('span', agent.version ? 'v' + agent.version : 'Version unavailable', 'caption'));
35456
- head.append(title, pill('Detected', 'good'));
35457
- card.append(head, node('p', agent.configured ? 'At least one managed optimizer is configured for this agent.' : 'The agent is available, but managed optimizer setup is not complete.'));
35619
+ title.append(
35620
+ node('h3', agent.name),
35621
+ node('span', agent.version ? 'v' + agent.version : 'Version unavailable', 'caption'),
35622
+ );
35623
+ head.append(title, pill(ready ? 'Ready' : 'Setup incomplete', ready ? 'good' : 'warn'));
35624
+ card.append(
35625
+ head,
35626
+ node(
35627
+ 'p',
35628
+ ready
35629
+ ? 'RTK + HarnessTrim are configured for this coding agent.'
35630
+ : 'The agent is detected. Finish the recommended RTK + HarnessTrim setup to complete onboarding.',
35631
+ ),
35632
+ );
35633
+ if (agent.providers?.length)
35634
+ card.append(
35635
+ node(
35636
+ 'p',
35637
+ 'Connected optimizers: ' + agent.providers.join(', '),
35638
+ 'caption',
35639
+ ),
35640
+ );
35641
+ if (!ready) {
35642
+ const actions = node('div', undefined, 'inline-actions');
35643
+ actions.append(actionButton('Finish setup', () => reviewSetup(agent.id)));
35644
+ card.append(actions);
35645
+ }
35458
35646
  root.append(card);
35459
35647
  }
35460
35648
  }
@@ -35466,16 +35654,18 @@ var init_guided_product_client = __esm({
35466
35654
  const provider = providerId ? TOOL_INFO[providerId] : null;
35467
35655
  if (providerId && !provider) return;
35468
35656
  const run = modal(
35469
- provider ? 'Review ' + provider.name + ' for ' + agent.name : 'Review managed setup for ' + agent.name,
35657
+ provider
35658
+ ? 'Set up ' + provider.name + ' for ' + agent.name
35659
+ : 'Set up recommended optimizers for ' + agent.name,
35470
35660
  );
35471
35661
  $('modal-content').append(
35472
35662
  messageBox(
35473
- 'What this checks',
35663
+ 'Safe preview first',
35474
35664
  provider
35475
- ? 'Token Harness will inspect only ' + provider.name + ' for ' + agent.name + ' and propose a change only on an exact reviewed compatibility row.'
35476
- : 'RTK and HarnessTrim are the production baseline. Token Harness will inspect both for ' + agent.name + ' and propose only compatible changes.',
35665
+ ? 'Token Harness will inspect only ' + provider.name + ' for ' + agent.name + '. If setup is supported, the exact change appears before you confirm it.'
35666
+ : 'Token Harness will prepare the recommended RTK + HarnessTrim setup for ' + agent.name + '. The exact files and changes appear before you confirm them.',
35477
35667
  ),
35478
- messageBox('Nothing changes yet', 'This step is read-only. If a change is available, you will see exactly what it writes before an Apply button appears.'),
35668
+ messageBox('Nothing changes yet', 'This first step only prepares the safe plan. You decide whether to apply it after seeing the concrete changes.'),
35479
35669
  progress('Checking ' + agent.name, 'Reading installed optimizer versions and current integration state.'),
35480
35670
  );
35481
35671
  if (providerId === 'gitnexus')
@@ -35502,22 +35692,34 @@ var init_guided_product_client = __esm({
35502
35692
  $('modal-content').replaceChildren();
35503
35693
  $('modal-content').append(
35504
35694
  messageBox(
35505
- 'Managed scope',
35695
+ provider ? 'This optimizer only' : 'Recommended setup',
35506
35696
  provider
35507
- ? provider.name + ' is reviewed separately from the RTK + HarnessTrim production baseline. This approval changes only the provider-scoped plan shown below.'
35508
- : 'This review covers the RTK + HarnessTrim production baseline only. Optional managed integrations are reviewed separately.',
35697
+ ? 'This approval changes only ' + provider.name + ' for ' + agent.name + '. Other optimizers are left unchanged.'
35698
+ : 'This approval covers only RTK + HarnessTrim for ' + agent.name + '. Optional optimizers stay separate.',
35509
35699
  ),
35510
35700
  );
35511
- if (!data.changes.length) $('modal-content').append(messageBox('No managed change proposed', (data.notices || []).join(' ') || 'This agent already has the supported setup, or no safe managed change is available.'));
35512
- for (const change of data.changes) {
35513
- const item = node('article', undefined, 'preview-change');
35514
- item.append(node('h3', change.title), node('p', change.description));
35515
- $('modal-content').append(item);
35701
+ if (!data.changes.length) {
35702
+ $('modal-content').append(
35703
+ messageBox(
35704
+ 'No setup change available',
35705
+ (data.notices || []).join(' ') ||
35706
+ 'This setup is already complete, or a prerequisite/version prevents Token Harness from changing it safely.',
35707
+ ),
35708
+ );
35709
+ } else {
35710
+ for (const change of data.changes) {
35711
+ const item = node('article', undefined, 'preview-change');
35712
+ item.append(node('h3', change.title), node('p', change.description));
35713
+ $('modal-content').append(item);
35714
+ }
35715
+ for (const notice of data.notices || []) $('modal-content').append(node('p', notice, 'notice-row'));
35516
35716
  }
35517
- for (const notice of data.notices || []) $('modal-content').append(node('p', notice, 'notice-row'));
35518
35717
  $('modal-content').append(messageBox('Safety', 'Apply uses the existing transactional engine with backups, compatibility checks, ownership checks and rollback. Unsupported versions are not forced.', 'safe'));
35519
35718
  $('modal-actions').replaceChildren(modalClose(data.ticket ? 'Cancel' : 'Done'));
35520
- if (data.ticket) $('modal-actions').append(actionButton('Apply reviewed setup', () => applyTicket(data.ticket), ''));
35719
+ if (data.ticket)
35720
+ $('modal-actions').append(
35721
+ actionButton(provider ? 'Set up ' + provider.name : 'Apply recommended setup', () => applyTicket(data.ticket), ''),
35722
+ );
35521
35723
  })
35522
35724
  .catch(error => {
35523
35725
  if (run !== modalRun) return;
@@ -35529,6 +35731,18 @@ var init_guided_product_client = __esm({
35529
35731
  });
35530
35732
  }
35531
35733
 
35734
+ async function refreshOverviewAfterMutation(message = 'Refreshing setup after the approved change…') {
35735
+ setStatus(message, true);
35736
+ $('stale-state').hidden = true;
35737
+ $('stale-state').textContent = '';
35738
+ const period = $('period').value;
35739
+ current = await request('/api/overview?period=' + encodeURIComponent(period) + '&refresh=1');
35740
+ periodCache.set(period, current);
35741
+ render();
35742
+ await loadActivity();
35743
+ setStatus('Updated at ' + new Date(current.generatedAt).toLocaleTimeString() + '.', false);
35744
+ }
35745
+
35532
35746
  async function applyTicket(ticket) {
35533
35747
  if (!ticket || busy) return;
35534
35748
  const run = modalRun;
@@ -35540,12 +35754,39 @@ var init_guided_product_client = __esm({
35540
35754
  const result = await request('/api/apply', { ticket });
35541
35755
  if (run !== modalRun) return;
35542
35756
  $('modal-title').textContent = result.title || (result.ok ? 'Setup completed' : 'Setup needs attention');
35543
- $('modal-content').replaceChildren(messageBox(result.ok ? 'Completed' : 'Needs attention', (result.messages || []).join(' '), result.ok ? 'safe' : 'warn'));
35544
- $('modal-content').append(node('p', 'The dashboard is now marked as previous state. Choose Refresh when you want to re-read the complete setup.', 'caption'));
35545
- $('stale-state').hidden = false;
35546
- $('stale-state').textContent = 'A setup change was applied. Displayed status is the previous state until you choose Refresh.';
35757
+ $('modal-content').replaceChildren(
35758
+ messageBox(result.ok ? 'Applied' : 'Needs attention', (result.messages || []).join(' '), result.ok ? 'safe' : 'warn'),
35759
+ progress('Refreshing the current setup', 'Please wait while Token Harness re-reads agents, optimizer connections and health after the change.'),
35760
+ );
35761
+ $('modal-actions').replaceChildren(modalClose('Refreshing…', true));
35762
+ try {
35763
+ await refreshOverviewAfterMutation('Applying the new configuration and refreshing status…');
35764
+ if (run !== modalRun) return;
35765
+ $('modal-content').replaceChildren(
35766
+ messageBox(
35767
+ result.ok ? 'Completed and refreshed' : 'Action finished; status refreshed',
35768
+ (result.messages || []).join(' ') || 'The latest setup state is now shown on the dashboard.',
35769
+ result.ok ? 'safe' : 'warn',
35770
+ ),
35771
+ );
35772
+ } catch (refreshError) {
35773
+ if (run !== modalRun) return;
35774
+ $('stale-state').hidden = false;
35775
+ $('stale-state').textContent = 'The action finished, but Token Harness could not automatically refresh the latest setup state.';
35776
+ $('modal-content').replaceChildren(
35777
+ messageBox(
35778
+ result.ok ? 'Change applied' : 'Action finished',
35779
+ (result.messages || []).join(' ') || 'The action completed.',
35780
+ result.ok ? 'safe' : 'warn',
35781
+ ),
35782
+ messageBox(
35783
+ 'Automatic refresh failed',
35784
+ refreshError.message || 'The latest setup state could not be read automatically. Use Refresh to retry the status check.',
35785
+ 'warn',
35786
+ ),
35787
+ );
35788
+ }
35547
35789
  $('modal-actions').replaceChildren(modalClose('Done'));
35548
- loadActivity();
35549
35790
  } catch (error) {
35550
35791
  if (run !== modalRun) return;
35551
35792
  $('modal-error').textContent = error.message;
@@ -35560,45 +35801,15 @@ var init_guided_product_client = __esm({
35560
35801
  $('managed-tools').replaceChildren(
35561
35802
  renderManagedTool('rtk'),
35562
35803
  renderManagedTool('harnesstrim'),
35563
- renderManagedTool('mcptoon'),
35564
- renderManagedTool('gitnexus'),
35565
- renderManagedTool('headroom'),
35566
35804
  );
35567
- const actions = $('managed-setup-actions');
35568
- actions.replaceChildren();
35569
- if (!activeAgents().length) {
35570
- actions.append(sectionEmpty('A supported coding agent must be detected before managed setup can be reviewed.'));
35571
- return;
35572
- }
35573
- actions.append(node('p', 'Choose the agent you want to configure. Review setup is read-only; Apply appears only after a concrete safe plan is shown.', 'caption'));
35574
- const buttons = node('div', undefined, 'inline-actions');
35575
- for (const agent of activeAgents())
35576
- buttons.append(actionButton('Review baseline for ' + agent.name, () => reviewSetup(agent.id)));
35577
- actions.append(buttons);
35578
-
35579
- const optional = node('div', undefined, 'managed-optional');
35580
- optional.append(
35581
- node(
35582
- 'p',
35583
- 'Optional managed integrations are reviewed one at a time. Enabling one does not create a savings claim or make it part of the RTK + HarnessTrim production baseline.',
35584
- 'caption',
35585
- ),
35586
- );
35587
- const optionalButtons = node('div', undefined, 'inline-actions');
35588
- for (const agent of activeAgents()) {
35589
- optionalButtons.append(
35590
- actionButton('Review mcptoon for ' + agent.name, () => reviewSetup(agent.id, 'mcptoon'), 'secondary'),
35591
- );
35592
- if (agent.id === 'claude')
35593
- optionalButtons.append(
35594
- actionButton('Review GitNexus for ' + agent.name, () => reviewSetup(agent.id, 'gitnexus'), 'secondary'),
35595
- );
35596
- optionalButtons.append(
35597
- actionButton('Review Headroom for ' + agent.name, () => reviewSetup(agent.id, 'headroom'), 'secondary'),
35805
+ const optionalRoot = $('optional-tools');
35806
+ if (optionalRoot)
35807
+ optionalRoot.replaceChildren(
35808
+ renderManagedTool('mcptoon'),
35809
+ renderManagedTool('gitnexus'),
35810
+ renderManagedTool('headroom'),
35598
35811
  );
35599
- }
35600
- optional.append(optionalButtons);
35601
- actions.append(optional);
35812
+
35602
35813
  }
35603
35814
 
35604
35815
  function candidateState(observation) {
@@ -35844,19 +36055,44 @@ var init_guided_product_client = __esm({
35844
36055
  function readOnlyOperation(kind) {
35845
36056
  if (busy) return;
35846
36057
  const isVerify = kind === 'verify';
35847
- const run = modal(isVerify ? 'Check integrations' : 'Check optimizer updates');
36058
+ const run = modal(isVerify ? 'Re-check optimizer health' : 'Check for optimizer updates');
35848
36059
  $('modal-content').append(
35849
- messageBox('Read-only check', isVerify ? 'Verifies the currently configured managed integrations. It does not repair or change configuration.' : 'Checks update channels for installed managed optimizers. It does not download or upgrade anything.'),
35850
- progress(isVerify ? 'Checking integrations' : 'Checking update channels', 'Nothing will be changed.'),
36060
+ messageBox(
36061
+ isVerify ? 'Troubleshooting check' : 'Update preview',
36062
+ isVerify
36063
+ ? 'Re-checks the configured optimizer integrations without repairing or changing them. Normal setup already performs its own safety checks.'
36064
+ : 'Checks reviewed update channels first. If an installable update exists, you can approve it from this window.',
36065
+ ),
36066
+ progress(
36067
+ isVerify ? 'Checking configured optimizers' : 'Checking update channels',
36068
+ 'Nothing changes during this check.',
36069
+ ),
35851
36070
  );
35852
36071
  $('modal-actions').append(modalClose('Cancel'));
35853
36072
  setBusy(true, false);
35854
36073
  ensureSession()
35855
- .then(() => request(isVerify ? '/api/verify' : '/api/update-check', { period: $('period').value }))
36074
+ .then(() =>
36075
+ request(isVerify ? '/api/verify' : '/api/update-check', { period: $('period').value }),
36076
+ )
35856
36077
  .then(result => {
35857
36078
  if (run !== modalRun || !$('modal').open) return;
35858
- $('modal-content').replaceChildren(messageBox(result.ok ? 'Completed' : 'Needs attention', (result.messages || []).join(' ') || 'Check completed.', result.ok ? 'safe' : 'warn'));
35859
- $('modal-actions').replaceChildren(modalClose('Done'));
36079
+ if (result.stack && current) {
36080
+ current = { ...current, stack: result.stack };
36081
+ renderDashboard();
36082
+ renderSetup();
36083
+ }
36084
+ $('modal-content').replaceChildren(
36085
+ messageBox(
36086
+ result.title || (result.ok ? 'Completed' : 'Needs attention'),
36087
+ (result.messages || []).join(' ') || 'Check completed.',
36088
+ result.ok ? 'safe' : 'warn',
36089
+ ),
36090
+ );
36091
+ $('modal-actions').replaceChildren(modalClose(result.ticket ? 'Cancel' : 'Done'));
36092
+ if (result.ticket)
36093
+ $('modal-actions').append(
36094
+ actionButton('Install updates', () => applyTicket(result.ticket), ''),
36095
+ );
35860
36096
  })
35861
36097
  .catch(error => {
35862
36098
  if (run !== modalRun) return;
@@ -35902,19 +36138,57 @@ var init_guided_product_client = __esm({
35902
36138
  function renderMaintenance() {
35903
36139
  const root = $('maintenance-actions');
35904
36140
  root.replaceChildren();
35905
- const verify = node('article', undefined, 'maintenance-row');
35906
- const verifyText = node('div');
35907
- verifyText.append(node('strong', 'Check integrations'), node('p', 'Read-only verification of configured managed tools.', 'caption'));
35908
- verify.append(verifyText, actionButton('Check', () => readOnlyOperation('verify'), 'secondary'));
36141
+
36142
+ if (configuredProviders().length) {
36143
+ const verify = node('article', undefined, 'maintenance-row');
36144
+ const verifyText = node('div');
36145
+ verifyText.append(
36146
+ node('strong', 'Optimizer health'),
36147
+ node(
36148
+ 'p',
36149
+ current?.stack?.state === 'attention'
36150
+ ? 'Something changed or could not be verified. Re-check the configured integrations for details.'
36151
+ : 'Setup is already complete. Re-check only when troubleshooting or after external changes.',
36152
+ 'caption',
36153
+ ),
36154
+ );
36155
+ verify.append(
36156
+ verifyText,
36157
+ actionButton(
36158
+ current?.stack?.state === 'attention' ? 'Check now' : 'Re-check health',
36159
+ () => readOnlyOperation('verify'),
36160
+ 'secondary',
36161
+ ),
36162
+ );
36163
+ root.append(verify);
36164
+ }
36165
+
35909
36166
  const updates = node('article', undefined, 'maintenance-row');
35910
36167
  const updateText = node('div');
35911
- updateText.append(node('strong', 'Check optimizer updates'), node('p', 'Read-only version check. Nothing is upgraded automatically.', 'caption'));
35912
- updates.append(updateText, actionButton('Check updates', () => readOnlyOperation('updates'), 'secondary'));
35913
- root.append(verify, updates);
36168
+ const available = (current?.stack?.components || []).filter(component => component.update === 'available');
36169
+ updateText.append(
36170
+ node('strong', 'Optimizer updates'),
36171
+ node(
36172
+ 'p',
36173
+ available.length
36174
+ ? available.map(component => (TOOL_INFO[component.providerId]?.name || component.providerId) + ' has an update ready.').join(' ')
36175
+ : 'Check installed optimizer versions. If a reviewed update is available, you can install it from the same dialog.',
36176
+ 'caption',
36177
+ ),
36178
+ );
36179
+ updates.append(
36180
+ updateText,
36181
+ actionButton(available.length ? 'Review updates' : 'Check for updates', () => readOnlyOperation('updates'), available.length ? '' : 'secondary'),
36182
+ );
36183
+ root.append(updates);
36184
+
35914
36185
  if (activityState?.canUndo) {
35915
36186
  const undo = node('article', undefined, 'maintenance-row');
35916
36187
  const undoText = node('div');
35917
- undoText.append(node('strong', 'Undo last dashboard change'), node('p', 'Review and restore the exact last transaction from this app session.', 'caption'));
36188
+ undoText.append(
36189
+ node('strong', 'Undo last change'),
36190
+ node('p', 'Review and restore the exact last configuration transaction from this app session.', 'caption'),
36191
+ );
35918
36192
  undo.append(undoText, actionButton('Review undo', undoLastChange, 'secondary'));
35919
36193
  root.append(undo);
35920
36194
  }
@@ -36798,42 +37072,57 @@ ${GUIDE_CANDIDATE_READINESS_JS}`;
36798
37072
  <header class="app-header"><div class="header-inner">
36799
37073
  <div class="brand"><span class="brand-mark" aria-hidden="true">TH</span><span>Token Harness<small>Use less. Know what changed.</small></span></div>
36800
37074
  <nav class="view-tabs" role="tablist" aria-label="Token Harness">
36801
- <button id="tab-dashboard" role="tab" aria-selected="true" aria-controls="view-dashboard" data-view="dashboard" type="button">Dashboard</button>
36802
- <button id="tab-setup" role="tab" aria-selected="false" aria-controls="view-setup" data-view="setup" tabindex="-1" type="button">Setup</button>
37075
+ <button id="tab-dashboard" role="tab" aria-selected="true" aria-controls="view-dashboard" data-view="dashboard" type="button">Overview</button>
36803
37076
  <button id="tab-results" role="tab" aria-selected="false" aria-controls="view-results" data-view="results" tabindex="-1" type="button">Results</button>
36804
37077
  </nav>
36805
37078
  <div class="header-tools"><label><span class="sr-only">Appearance</span><select id="theme" aria-label="Appearance"><option value="system">System</option><option value="light">Light</option><option value="dark">Dark</option></select></label><button id="refresh" class="secondary" type="button">Refresh</button></div>
36806
37079
  </div></header>
36807
37080
  <main id="main">
36808
- <div class="page-heading"><div><h1 id="view-title">Dashboard</h1><p id="view-description">Your coding setup, what is active, and what to do next.</p></div></div>
37081
+ <div class="page-heading"><div><h1 id="view-title">Overview</h1><p id="view-description">Your coding agents, optimizer setup, health and measured results in one place.</p></div></div>
36809
37082
  <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>
36810
37083
  <div id="stale-state" class="stale-state" hidden></div><div id="error" class="error" role="alert" hidden></div><div id="notices"></div>
36811
37084
 
36812
37085
  <section id="view-dashboard" role="tabpanel" aria-labelledby="tab-dashboard" tabindex="0">
36813
- <section id="dashboard-status" class="dashboard-status"><div><span class="eyebrow">SETUP STATUS</span><h2>Checking your machine\u2026</h2><p>Finding Claude Code, Codex, managed optimizers and measured results.</p></div><span class="pill">Checking</span></section>
36814
- <div class="section-title"><div><h2>What Token Harness is doing for you</h2><p>Only measured results or explicitly unknown values are shown.</p></div></div>
37086
+ <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>
37087
+
37088
+ <div class="section-title"><div><h2>Measured impact</h2><p>A summary of what Token Harness can actually prove. Open Results for the detailed evidence.</p></div></div>
36815
37089
  <div id="dashboard-metrics" class="impact-grid" aria-label="Efficiency summary">
36816
37090
  <article class="metric-card"><span class="metric-label">Measured output</span><strong class="metric-value">Checking\u2026</strong><p class="metric-help">Recorded optimizer output.</p></article>
36817
37091
  <article class="metric-card"><span class="metric-label">5h / 7d allowance</span><strong class="metric-value">Checking\u2026</strong><p class="metric-help">Shown only when measured.</p></article>
36818
37092
  <article class="metric-card"><span class="metric-label">API cost</span><strong class="metric-value">Checking\u2026</strong><p class="metric-help">Shown only from billing evidence.</p></article>
36819
37093
  <article class="metric-card"><span class="metric-label">Quality</span><strong class="metric-value">Checking\u2026</strong><p class="metric-help">Measured separately from savings.</p></article>
36820
37094
  </div>
36821
- <div class="dashboard-columns">
36822
- <section class="panel"><h2>Active today</h2><p class="caption">Coding agents and managed optimization that Token Harness can actually see.</p><div id="dashboard-active" class="status-list"><p class="empty">Checking\u2026</p></div></section>
36823
- <section class="panel"><h2>Getting started</h2><p class="caption">The shortest path from installation to useful measured results.</p><div id="dashboard-checklist" class="checklist"><p class="empty">Checking\u2026</p></div></section>
36824
- </div>
36825
- </section>
36826
37095
 
36827
- <section id="view-setup" role="tabpanel" aria-labelledby="tab-setup" tabindex="0" hidden>
36828
- <div class="setup-intro"><div><h2>Set up Token Harness in order</h2><p>Start with your coding agent and the RTK + HarnessTrim production baseline. Optional managed integrations are reviewed separately; unmanaged experiments stay outside the active stack.</p></div><span class="pill good">Safe previews before changes</span></div>
37096
+ <section class="setup-step" id="coding-agents">
37097
+ <div class="section-title"><div><h2>Coding agents</h2><p>These are the harnesses Token Harness can configure today. A detected agent is not considered fully set up until the recommended RTK + HarnessTrim baseline is connected to it.</p></div></div>
37098
+ <div id="setup-agents" class="tool-grid"><article class="tool-card"><h3>Checking agents\u2026</h3></article></div>
37099
+ <details class="disclosure advanced-disclosure">
37100
+ <summary>Agent details and optional reasoning settings</summary>
37101
+ <p class="caption">Allowance, connected-tool observations and reasoning preferences are advanced information. They are not required to finish optimizer setup.</p>
37102
+ <div id="agent-capabilities" class="tool-grid"><article class="tool-card"><h3>Checking agent details\u2026</h3></article></div>
37103
+ <div class="subsection-heading"><h3>Optional reasoning settings</h3><p class="caption">Persistent agent preferences are separate from optimizer setup.</p></div>
37104
+ <div id="agent-tuning" class="tool-grid"><article class="tool-card"><h3>Checking reasoning controls\u2026</h3></article></div>
37105
+ </details>
37106
+ </section>
36829
37107
 
36830
- <section class="setup-step"><div class="step-heading"><span class="step-number">1</span><div><h2>Coding agents</h2><p>Token Harness currently supports guided setup for Claude Code and Codex. The app must be started from an environment where the agent is detectable.</p></div></div><div id="setup-agents" class="tool-grid"><article class="tool-card"><h3>Checking agents\u2026</h3></article></div><div class="subsection-heading"><h3>Agent details</h3><p class="caption">In-session guidance, plan allowance and useful connected-tool checks.</p></div><div id="agent-capabilities" class="tool-grid"><article class="tool-card"><h3>Checking agent details\u2026</h3></article></div></section>
37108
+ <section class="setup-step" id="optimizers">
37109
+ <div class="section-title"><div><h2>Optimizers</h2><p>Recommended and optional tools are kept separate. Every button sits next to the tool or agent it affects, and every configuration change is previewed before approval.</p></div></div>
37110
+ <div class="subsection-heading"><h3>Recommended baseline</h3><p class="caption">RTK + HarnessTrim are configured together from the coding-agent card above, so first-run setup stays one action per agent.</p></div>
37111
+ <div id="managed-tools" class="tool-grid"><article class="tool-card"><h3>Checking recommended optimizers\u2026</h3></article></div>
36831
37112
 
36832
- <section class="setup-step"><div class="step-heading"><span class="step-number">2</span><div><h2>Managed optimizers</h2><p>RTK and HarnessTrim are the production baseline. mcptoon, GitNexus and Headroom also expose narrow optional managed integrations on exact reviewed rows. Every setup is reviewed before anything is written.</p></div></div><div id="managed-tools" class="tool-grid"><article class="tool-card"><h3>Checking managed optimizers\u2026</h3></article></div><div id="managed-setup-actions" class="managed-action-box"><p>Checking available agents\u2026</p></div><details class="disclosure"><summary>Remove managed changes</summary><p class="caption">Removal is reviewed first. Token Harness removes only configuration changes it owns; an installed provider CLI may remain.</p><div id="managed-removal-actions" class="maintenance-list"><p class="caption">Checking managed ownership\u2026</p></div></details></section>
37113
+ <details class="disclosure optional-disclosure">
37114
+ <summary>Optional optimizers</summary>
37115
+ <p class="caption">Add these only when you want their specific capability. They are not required to complete first-run setup and are never counted as savings merely because they are configured.</p>
37116
+ <div id="optional-tools" class="tool-grid"><article class="tool-card"><h3>Checking optional optimizers\u2026</h3></article></div>
37117
+ </details>
36833
37118
 
36834
- <section class="setup-step"><div class="step-heading"><span class="step-number">3</span><div><h2>Optional agent tuning</h2><p>Reasoning preferences are separate from optimizer installation. Change them only when you intentionally want a persistent agent preference.</p></div></div><div id="agent-tuning" class="tool-grid"><article class="tool-card"><h3>Checking reasoning controls\u2026</h3></article></div></section>
37119
+ <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>
37120
+ </section>
36835
37121
 
36836
- <section class="setup-step"><div class="step-heading"><span class="step-number">4</span><div><h2>Checks and maintenance</h2><p>Read-only verification and update checks live here. Undo is shown only when this dashboard has an exact transaction it can safely restore.</p></div></div><div id="maintenance-actions" class="maintenance-list"><p class="empty">Checking\u2026</p></div></section>
37122
+ <section class="setup-step" id="maintenance">
37123
+ <div class="section-title"><div><h2>Health and updates</h2><p>These are maintenance actions, not onboarding steps. Setup already performs its own safety checks.</p></div></div>
37124
+ <div id="maintenance-actions" class="maintenance-list"><p class="empty">Checking\u2026</p></div>
37125
+ </section>
36837
37126
  </section>
36838
37127
 
36839
37128
  <section id="view-results" role="tabpanel" aria-labelledby="tab-results" tabindex="0" hidden>
@@ -36844,7 +37133,7 @@ ${GUIDE_CANDIDATE_READINESS_JS}`;
36844
37133
  <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>
36845
37134
  </section>
36846
37135
 
36847
- <footer><span>Local data. No account required.</span><span>Full setup refresh runs only when you choose Refresh.</span></footer>
37136
+ <footer><span>Local data. No account required.</span><span>Full overview refresh runs only when you choose Refresh.</span></footer>
36848
37137
  </main>
36849
37138
  <dialog id="modal" aria-labelledby="modal-title"><div class="dialog-body"><div class="dialog-heading"><h2 id="modal-title">Review</h2></div><div id="modal-content"></div><div id="modal-error" class="error" role="alert" hidden></div><div id="modal-actions" class="dialog-actions"></div></div></dialog>
36850
37139
  <script src="/guide.js" defer></script></body></html>`;