token-harness 0.1.13 → 0.1.15

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "token-harness",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
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:f53f4600-4e02-4fbe-462d-286326adfd0b",
4
+ "serialNumber": "urn:uuid:00b7739e-3dfa-0f35-6b77-d2f92796cd4d",
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.13",
11
+ "version": "0.1.15",
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": "f53f46004e024fbe462d286326adfd0be1a2e5d5c2678346e1e2e7e39bce853b"
23
+ "content": "00b7739e3dfa0f356b77d2f92796cd4d87fa151f04c568e476b4329fcee1eb81"
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.13";
9390
+ TOOL_VERSION = "0.1.15";
9391
9391
  }
9392
9392
  });
9393
9393
 
@@ -31970,6 +31970,93 @@ var init_stack_combination_reviews = __esm({
31970
31970
  });
31971
31971
 
31972
31972
  // apps/cli/dist/src/guided.js
31973
+ function guideSetupTarget(report, harness, provider) {
31974
+ const harnessDetection = report.harnesses.find((item) => item.harnessId === harness);
31975
+ const detection = report.providers.find((item) => item.providerId === provider);
31976
+ const label = name(provider);
31977
+ if (harnessDetection === void 0 || harnessDetection.state === "absent") {
31978
+ return {
31979
+ providerId: provider,
31980
+ provider: label,
31981
+ state: "not-applicable",
31982
+ reason: `${name(harness)} is not currently detected.`
31983
+ };
31984
+ }
31985
+ if (detection === void 0) {
31986
+ return {
31987
+ providerId: provider,
31988
+ provider: label,
31989
+ state: "not-applicable",
31990
+ reason: `${label} is not a managed provider in this build.`
31991
+ };
31992
+ }
31993
+ if (detection.configuredHarnesses.includes(harnessDetection.harnessId)) {
31994
+ return {
31995
+ providerId: provider,
31996
+ provider: label,
31997
+ state: "connected",
31998
+ reason: `${label} is configured for ${name(harness)}.`
31999
+ };
32000
+ }
32001
+ const hasReviewedHarnessSurface = COMPATIBILITY_ROWS.some((row2) => row2.provider === provider && row2.harness === harnessDetection.harnessId);
32002
+ if (!hasReviewedHarnessSurface) {
32003
+ return {
32004
+ providerId: provider,
32005
+ provider: label,
32006
+ state: "not-applicable",
32007
+ reason: `Token Harness does not manage a reviewed ${label} connection for ${name(harness)}.`
32008
+ };
32009
+ }
32010
+ if (detection.state === "absent" || detection.state === "available") {
32011
+ return {
32012
+ providerId: provider,
32013
+ provider: label,
32014
+ state: "unavailable",
32015
+ reason: `${label} is not installed in a state Token Harness can configure automatically.`
32016
+ };
32017
+ }
32018
+ if (detection.state === "broken") {
32019
+ return {
32020
+ providerId: provider,
32021
+ provider: label,
32022
+ state: "unavailable",
32023
+ reason: `${label} is detected but its current integration needs attention before setup can continue.`
32024
+ };
32025
+ }
32026
+ if (!detection.assignableHarnesses.includes(harnessDetection.harnessId)) {
32027
+ return {
32028
+ providerId: provider,
32029
+ provider: label,
32030
+ state: "unavailable",
32031
+ reason: `The installed ${label} build does not expose a reviewed automatic setup for ${name(harness)}.`
32032
+ };
32033
+ }
32034
+ const admission = admitManagedMutation(COMPATIBILITY_ROWS, {
32035
+ provider: detection.providerId,
32036
+ providerVersion: detection.version,
32037
+ harness: harnessDetection.harnessId,
32038
+ harnessVersion: harnessDetection.version,
32039
+ os: report.platform.os,
32040
+ wsl: report.platform.isWsl
32041
+ });
32042
+ if (admission.state !== "admitted") {
32043
+ return {
32044
+ providerId: provider,
32045
+ provider: label,
32046
+ state: "unavailable",
32047
+ reason: `Automatic ${label} setup is not reviewed for the installed ${name(harness)} / ${label} version combination on ${report.platform.os}.`
32048
+ };
32049
+ }
32050
+ return {
32051
+ providerId: provider,
32052
+ provider: label,
32053
+ state: "actionable",
32054
+ reason: `${label} can be configured automatically for ${name(harness)} with the reviewed transaction path.`
32055
+ };
32056
+ }
32057
+ function guideSetupTargets(report, harness) {
32058
+ return GUIDE_MANAGED_PROVIDERS.map((provider) => guideSetupTarget(report, harness, provider));
32059
+ }
31973
32060
  function explainGuideIssue(diagnostics, fallback) {
31974
32061
  const known = diagnostics.find((entry) => ISSUE_COPY[entry.code] !== void 0);
31975
32062
  if (known !== void 0)
@@ -31994,7 +32081,8 @@ function stackFingerprint(report) {
31994
32081
  version: item.version,
31995
32082
  versionVerdict: item.versionVerdict,
31996
32083
  managedByTokenHarness: item.managedByTokenHarness,
31997
- configuredHarnesses: [...item.configuredHarnesses].sort()
32084
+ configuredHarnesses: [...item.configuredHarnesses].sort(),
32085
+ assignableHarnesses: [...item.assignableHarnesses].sort()
31998
32086
  })).sort((left, right) => left.id.localeCompare(right.id));
31999
32087
  return JSON.stringify({ harnesses, providers });
32000
32088
  }
@@ -32212,7 +32300,7 @@ function describeChange(action, harness) {
32212
32300
  files: action.affectedPaths.length
32213
32301
  };
32214
32302
  }
32215
- var GuideError, NAMES, name, TASKS, PERIODS, STACK_COMPONENTS, ISSUE_COPY, EFFORT_LABELS, SAFETY_RULES, TASK_RULES, READ_STAGES, GuideService;
32303
+ var GuideError, NAMES, name, GUIDE_MANAGED_PROVIDERS, RECOMMENDED_SETUP_PROVIDERS, TASKS, PERIODS, STACK_COMPONENTS, ISSUE_COPY, EFFORT_LABELS, SAFETY_RULES, TASK_RULES, READ_STAGES, GuideService;
32216
32304
  var init_guided = __esm({
32217
32305
  "apps/cli/dist/src/guided.js"() {
32218
32306
  "use strict";
@@ -32240,6 +32328,14 @@ var init_guided = __esm({
32240
32328
  headroom: "Headroom"
32241
32329
  };
32242
32330
  name = (id) => NAMES[id] ?? id;
32331
+ GUIDE_MANAGED_PROVIDERS = [
32332
+ "rtk",
32333
+ "harnesstrim",
32334
+ "mcptoon",
32335
+ "gitnexus",
32336
+ "headroom"
32337
+ ];
32338
+ RECOMMENDED_SETUP_PROVIDERS = ["rtk", "harnesstrim"];
32243
32339
  TASKS = /* @__PURE__ */ new Set(["mechanical", "standard", "hard", "critical"]);
32244
32340
  PERIODS = /* @__PURE__ */ new Set(["all", "7d", "30d"]);
32245
32341
  STACK_COMPONENTS = [
@@ -32542,6 +32638,8 @@ var init_guided = __esm({
32542
32638
  const providers = (doctor.data?.providers ?? []).filter((provider) => provider.state === "configured" && provider.configuredHarnesses.includes(agent.harnessId)).map((p) => p.providerId);
32543
32639
  const usage = budget.data?.harnesses.find((item) => item.harnessId === agent.harnessId);
32544
32640
  const observed = context.data?.harnesses.find((item) => item.harnessId === agent.harnessId);
32641
+ const setup = doctor.data === null ? [] : guideSetupTargets(doctor.data, agent.harnessId);
32642
+ const hasActionableSetup = setup.some((target) => target.state === "actionable");
32545
32643
  return {
32546
32644
  pending: [
32547
32645
  ...!complete2.rules ? ["reasoning"] : [],
@@ -32551,8 +32649,9 @@ var init_guided = __esm({
32551
32649
  name: name(agent.harnessId),
32552
32650
  version: agent.version,
32553
32651
  configured: providers.length > 0,
32554
- state: agent.state === "broken" ? "Needs attention" : providers.length > 0 ? "Integration configured" : "Ready to set up",
32652
+ state: agent.state === "broken" ? "Needs attention" : providers.length > 0 ? "Integration configured" : hasActionableSetup ? "Ready to set up" : "No reviewed automatic setup available",
32555
32653
  providers: providers.map(name),
32654
+ setup,
32556
32655
  effort: observed?.nativeEffort?.current ?? observed?.reasoningEffort ?? null,
32557
32656
  reasoning: reasoningView(agent.harnessId, observed),
32558
32657
  ...guidance?.[agent.harnessId] ? { guidance: guidance[agent.harnessId] } : {},
@@ -32753,30 +32852,49 @@ var init_guided = __esm({
32753
32852
  let network = false;
32754
32853
  for (const agent of selected) {
32755
32854
  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
- });
32855
+ const setupProviders = [];
32856
+ if (data["action"] === "setup") {
32857
+ const requested = data["provider"] === void 0 ? RECOMMENDED_SETUP_PROVIDERS : [String(data["provider"])];
32858
+ for (const setupProvider of requested) {
32859
+ const target = inventory.data === null ? null : guideSetupTarget(inventory.data, agent.harnessId, setupProvider);
32860
+ if (target?.state === "actionable") {
32861
+ setupProviders.push(setupProvider);
32862
+ } else if (target?.state === "connected") {
32863
+ notices.push(`${name(agent.harnessId)} \xB7 ${name(setupProvider)}: already connected. No setup change is needed.`);
32864
+ } else if (target !== null) {
32865
+ notices.push(`${name(agent.harnessId)} \xB7 ${name(setupProvider)}: ${target.reason}`);
32866
+ }
32867
+ }
32776
32868
  } else {
32777
- changes.push(...report.actions.map((action2) => describeChange(action2, agent.harnessId)));
32869
+ setupProviders.push(null);
32870
+ }
32871
+ for (const setupProvider of setupProviders) {
32872
+ const args = ["plan", "--harness", agent.harnessId];
32873
+ if (setupProvider !== null)
32874
+ args.push("--provider", setupProvider);
32875
+ if (data["action"] === "skill") {
32876
+ args.push("--provider", "none", "--agent-skill");
32877
+ } else if (data["action"] === "effort")
32878
+ args.push("--provider", "none", "--native-policy", "--task", String(data["task"]), "--profile", data["task"] === "mechanical" ? "economy" : data["task"] === "standard" ? "balanced" : "quality");
32879
+ const result6 = await this.call(args);
32880
+ const report = result6.data;
32881
+ if (report === null || result6.exitCode !== 0 || report.conflicts.length > 0 || report.actions.length === 0 || !report.persisted || report.planId === null) {
32882
+ const subject = setupProvider !== null ? `${name(agent.harnessId)} \xB7 ${name(setupProvider)}` : name(agent.harnessId);
32883
+ 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 for the current provider, agent version and platform.")}`);
32884
+ continue;
32885
+ }
32886
+ plans.push(report.planId);
32887
+ if (data["action"] === "skill") {
32888
+ changes.push({
32889
+ title: `${name(agent.harnessId)}: enable in-session guidance`,
32890
+ 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.",
32891
+ files: 1
32892
+ });
32893
+ } else {
32894
+ changes.push(...report.actions.map((action2) => describeChange(action2, agent.harnessId)));
32895
+ }
32896
+ network ||= report.network.length > 0;
32778
32897
  }
32779
- network ||= report.network.length > 0;
32780
32898
  }
32781
32899
  if (selected.length === 0)
32782
32900
  notices.push("No supported coding agent was found. Install and sign in to Claude Code or Codex, then refresh.");
@@ -34840,9 +34958,20 @@ var init_guided_capabilities_client = __esm({
34840
34958
  return data;
34841
34959
  }
34842
34960
 
34843
- function markStale() {
34844
- $('stale-state').hidden = false;
34845
- $('stale-state').textContent = 'A reviewed change was applied. Displayed status is the previous state until you choose Refresh.';
34961
+ async function waitForAutomaticRefresh() {
34962
+ $('stale-state').hidden = true;
34963
+ $('stale-state').textContent = '';
34964
+ const spinner = $('reading-spinner');
34965
+ const refresh = $('refresh');
34966
+ let observedRefresh = false;
34967
+ refresh.click();
34968
+ const deadline = Date.now() + 120000;
34969
+ while (Date.now() < deadline) {
34970
+ if (!spinner.hidden) observedRefresh = true;
34971
+ if (observedRefresh && spinner.hidden) return;
34972
+ await new Promise(resolve => setTimeout(resolve, 100));
34973
+ }
34974
+ throw new Error('The latest setup state could not be read automatically.');
34846
34975
  }
34847
34976
 
34848
34977
  async function applyTicket(ticket, title) {
@@ -34855,11 +34984,33 @@ var init_guided_capabilities_client = __esm({
34855
34984
  const result = await request('/api/apply', { ticket });
34856
34985
  if (activeRun !== runId) return;
34857
34986
  $('modal-title').textContent = result.ok ? title : 'Change needs attention';
34858
- $('modal-content').replaceChildren(message(result.ok ? 'Completed' : 'Needs attention', (result.messages || []).join(' ') || 'The transaction finished.', result.ok ? 'safe' : 'warn'));
34859
- if (result.ok) markStale();
34987
+ $('modal-content').replaceChildren(
34988
+ message(
34989
+ result.ok ? 'Applied' : 'Needs attention',
34990
+ (result.messages || []).join(' ') || 'The transaction finished.',
34991
+ result.ok ? 'safe' : 'warn',
34992
+ ),
34993
+ progress(
34994
+ 'Refreshing the current setup',
34995
+ 'Please wait while Token Harness re-reads the latest agent and optimizer state.',
34996
+ ),
34997
+ );
34998
+ $('modal-actions').replaceChildren(closeButton('Refreshing…', true));
34999
+ await waitForAutomaticRefresh();
35000
+ if (activeRun !== runId) return;
35001
+ $('modal-content').replaceChildren(
35002
+ message(
35003
+ result.ok ? 'Completed and refreshed' : 'Action finished; status refreshed',
35004
+ (result.messages || []).join(' ') || 'The latest setup state is now displayed.',
35005
+ result.ok ? 'safe' : 'warn',
35006
+ ),
35007
+ );
34860
35008
  $('modal-actions').replaceChildren(closeButton('Done'));
34861
35009
  } catch (error) {
34862
35010
  if (activeRun !== runId) return;
35011
+ $('stale-state').hidden = false;
35012
+ $('stale-state').textContent =
35013
+ 'The action finished, but Token Harness could not automatically refresh the latest setup state.';
34863
35014
  $('modal-error').textContent = error.message;
34864
35015
  $('modal-error').hidden = false;
34865
35016
  $('modal-actions').replaceChildren(closeButton('Close'));
@@ -34881,14 +35032,22 @@ var init_guided_capabilities_client = __esm({
34881
35032
  const data = await request('/api/preview', body);
34882
35033
  if (activeRun !== runId || !$('modal').open) return;
34883
35034
  $('modal-content').replaceChildren();
34884
- if (!(data.changes || []).length)
34885
- $('modal-content').append(message('No managed change proposed', (data.notices || []).join(' ') || 'Nothing needs to be changed.'));
34886
- for (const change of data.changes || []) {
34887
- const item = node('article', undefined, 'preview-change');
34888
- item.append(node('h3', change.title), node('p', change.description));
34889
- $('modal-content').append(item);
34890
- }
34891
- for (const notice of data.notices || []) $('modal-content').append(node('p', notice, 'notice-row'));
35035
+ if (!(data.changes || []).length) {
35036
+ $('modal-content').append(
35037
+ message(
35038
+ 'No managed change proposed',
35039
+ (data.notices || []).join(' ') || 'Nothing needs to be changed.',
35040
+ ),
35041
+ );
35042
+ } else {
35043
+ for (const change of data.changes || []) {
35044
+ const item = node('article', undefined, 'preview-change');
35045
+ item.append(node('h3', change.title), node('p', change.description));
35046
+ $('modal-content').append(item);
35047
+ }
35048
+ for (const notice of data.notices || [])
35049
+ $('modal-content').append(node('p', notice, 'notice-row'));
35050
+ }
34892
35051
  $('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'));
34893
35052
  $('modal-actions').replaceChildren(closeButton(data.ticket ? 'Cancel' : 'Done'));
34894
35053
  if (data.ticket)
@@ -35304,22 +35463,61 @@ var init_guided_product_client = __esm({
35304
35463
  return (current?.stack?.components || []).filter(component => component.configured);
35305
35464
  }
35306
35465
 
35307
- function componentConfiguredFor(id, agentId) {
35308
- const component = managedComponent(id);
35309
- return Boolean(component?.configuredHarnesses?.includes(agentId));
35466
+ function setupTarget(agentId, providerId) {
35467
+ const agent = activeAgents().find(item => item.id === agentId);
35468
+ return agent?.setup?.find(item => item.providerId === providerId) || null;
35310
35469
  }
35311
35470
 
35312
- function baselineReadyFor(agentId) {
35313
- return componentConfiguredFor('rtk', agentId) && componentConfiguredFor('harnesstrim', agentId);
35471
+ function baselineStatusFor(agentId) {
35472
+ const targets = ['rtk', 'harnesstrim']
35473
+ .map(providerId => setupTarget(agentId, providerId))
35474
+ .filter(Boolean);
35475
+ const actionable = targets.filter(target => target.state === 'actionable');
35476
+ const unavailable = targets.filter(target => target.state === 'unavailable');
35477
+ const connected = targets.filter(target => target.state === 'connected');
35478
+ if (actionable.length)
35479
+ return {
35480
+ state: 'incomplete',
35481
+ label: 'Setup incomplete',
35482
+ cls: 'warn',
35483
+ actionable,
35484
+ unavailable,
35485
+ connected,
35486
+ };
35487
+ if (unavailable.length && connected.length === 0)
35488
+ return {
35489
+ state: 'unavailable',
35490
+ label: 'No automatic setup',
35491
+ cls: '',
35492
+ actionable,
35493
+ unavailable,
35494
+ connected,
35495
+ };
35496
+ if (unavailable.length)
35497
+ return {
35498
+ state: 'limited',
35499
+ label: 'Reviewed setup complete',
35500
+ cls: 'good',
35501
+ actionable,
35502
+ unavailable,
35503
+ connected,
35504
+ };
35505
+ return {
35506
+ state: 'ready',
35507
+ label: 'Ready',
35508
+ cls: 'good',
35509
+ actionable,
35510
+ unavailable,
35511
+ connected,
35512
+ };
35314
35513
  }
35315
35514
 
35316
35515
  function baselineIncompleteAgents() {
35317
- return activeAgents().filter(agent => !baselineReadyFor(agent.id));
35516
+ return activeAgents().filter(agent => baselineStatusFor(agent.id).state === 'incomplete');
35318
35517
  }
35319
35518
 
35320
- function providerSupportsAgent(providerId, agentId) {
35321
- if (providerId === 'gitnexus') return agentId === 'claude';
35322
- return agentId === 'claude' || agentId === 'codex';
35519
+ function baselineUnavailableAgents() {
35520
+ return activeAgents().filter(agent => baselineStatusFor(agent.id).state === 'unavailable');
35323
35521
  }
35324
35522
 
35325
35523
  function candidateObservation(id) {
@@ -35400,10 +35598,19 @@ var init_guided_product_client = __esm({
35400
35598
  cls: 'warn',
35401
35599
  title: incomplete.length === 1
35402
35600
  ? 'Finish setup for ' + incomplete[0].name
35403
- : 'Finish the recommended setup for your coding agents',
35404
- 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.',
35601
+ : 'Finish the available recommended setup for your coding agents',
35602
+ detail: 'Every Finish setup action below has at least one reviewed provider change available for that exact agent, version and platform.',
35405
35603
  action: 'configure',
35406
35604
  };
35605
+ const unavailable = baselineUnavailableAgents();
35606
+ if (unavailable.length)
35607
+ return {
35608
+ label: 'No automatic setup',
35609
+ cls: '',
35610
+ title: 'No reviewed automatic setup is currently available',
35611
+ detail: 'Token Harness will not show a setup button that cannot complete. The agent cards below explain which provider/version combination is not currently managed.',
35612
+ action: 'none',
35613
+ };
35407
35614
  if (!(current?.savings?.rows || []).length)
35408
35615
  return {
35409
35616
  label: 'Ready',
@@ -35457,7 +35664,7 @@ var init_guided_product_client = __esm({
35457
35664
  );
35458
35665
  }
35459
35666
 
35460
- function componentState(component) {
35667
+ function componentState(id, component) {
35461
35668
  if (!component || component.detectedState === 'absent') return { label: 'Not installed', cls: '' };
35462
35669
  if (component.health === 'attention') return { label: 'Needs attention', cls: 'warn' };
35463
35670
  if (component.configured)
@@ -35465,14 +35672,19 @@ var init_guided_product_client = __esm({
35465
35672
  label: component.verification === 'verified' ? 'Connected · verified' : 'Connected',
35466
35673
  cls: 'good',
35467
35674
  };
35468
- if (component.installed) return { label: 'Installed · not connected', cls: '' };
35675
+ const targets = activeAgents().map(agent => setupTarget(agent.id, id)).filter(Boolean);
35676
+ if (component.installed && targets.some(target => target.state === 'actionable'))
35677
+ return { label: 'Installed · setup available', cls: 'warn' };
35678
+ if (component.installed && targets.some(target => target.state === 'unavailable'))
35679
+ return { label: 'Installed · no automatic setup', cls: '' };
35680
+ if (component.installed) return { label: 'Installed', cls: '' };
35469
35681
  return { label: 'Not installed', cls: '' };
35470
35682
  }
35471
35683
 
35472
35684
  function renderManagedTool(id) {
35473
35685
  const info = TOOL_INFO[id];
35474
35686
  const component = managedComponent(id);
35475
- const state = componentState(component);
35687
+ const state = componentState(id, component);
35476
35688
  const card = node('article', undefined, 'tool-card');
35477
35689
  const head = node('div', undefined, 'tool-head');
35478
35690
  const title = node('div');
@@ -35485,9 +35697,20 @@ var init_guided_product_client = __esm({
35485
35697
 
35486
35698
  const facts = node('div', undefined, 'tool-facts');
35487
35699
  if (component?.version) facts.append(node('span', 'Installed version'), node('strong', 'v' + component.version));
35700
+ const providerTargets = activeAgents()
35701
+ .map(agent => ({ agent, target: setupTarget(agent.id, id) }))
35702
+ .filter(item => item.target);
35703
+ const actionableFor = providerTargets
35704
+ .filter(item => item.target.state === 'actionable')
35705
+ .map(item => item.agent.name);
35706
+ const unavailableFor = providerTargets.filter(item => item.target.state === 'unavailable');
35488
35707
  const configuredFor = component?.configuredHarnesses?.length
35489
35708
  ? component.configuredHarnesses.map(agentName).join(', ')
35490
- : 'Not connected to a coding agent';
35709
+ : actionableFor.length
35710
+ ? 'Setup available for ' + actionableFor.join(', ')
35711
+ : unavailableFor.length
35712
+ ? 'No reviewed automatic connection is available'
35713
+ : 'Not applicable to the detected coding agents';
35491
35714
  facts.append(node('span', 'Connection'), node('strong', configuredFor));
35492
35715
  if (component?.update === 'available')
35493
35716
  facts.append(
@@ -35498,6 +35721,19 @@ var init_guided_product_client = __esm({
35498
35721
  facts.append(node('span', 'Update'), node('strong', 'Newer version not reviewed yet'));
35499
35722
  card.append(facts);
35500
35723
 
35724
+ if (
35725
+ component?.installed &&
35726
+ !(component?.configuredHarnesses?.length) &&
35727
+ actionableFor.length === 0 &&
35728
+ unavailableFor.length > 0
35729
+ )
35730
+ card.append(
35731
+ messageBox(
35732
+ 'Why there is no Connect button',
35733
+ unavailableFor[0].target.reason,
35734
+ ),
35735
+ );
35736
+
35501
35737
  if (component?.warnings?.length) {
35502
35738
  const attention = component.health === 'attention';
35503
35739
  const prerequisite = !component.installed && component.nextAction?.kind === 'install-configure';
@@ -35512,18 +35748,16 @@ var init_guided_product_client = __esm({
35512
35748
  }
35513
35749
 
35514
35750
  const actions = node('div', undefined, 'inline-actions');
35515
- if (info.optional) {
35516
- for (const agent of activeAgents()) {
35517
- if (!providerSupportsAgent(id, agent.id)) continue;
35518
- if (!component?.configuredHarnesses?.includes(agent.id))
35519
- actions.append(
35520
- actionButton(
35521
- 'Set up for ' + agent.name,
35522
- () => reviewSetup(agent.id, id),
35523
- 'secondary',
35524
- ),
35525
- );
35526
- }
35751
+ for (const agent of activeAgents()) {
35752
+ const target = setupTarget(agent.id, id);
35753
+ if (target?.state !== 'actionable') continue;
35754
+ actions.append(
35755
+ actionButton(
35756
+ component?.installed ? 'Connect to ' + agent.name : 'Set up for ' + agent.name,
35757
+ () => reviewSetup(agent.id, id),
35758
+ 'secondary',
35759
+ ),
35760
+ );
35527
35761
  }
35528
35762
  if (component?.update === 'available')
35529
35763
  actions.append(actionButton('Install update', () => readOnlyOperation('updates'), 'secondary'));
@@ -35550,7 +35784,7 @@ var init_guided_product_client = __esm({
35550
35784
  return;
35551
35785
  }
35552
35786
  for (const agent of activeAgents()) {
35553
- const ready = baselineReadyFor(agent.id);
35787
+ const baseline = baselineStatusFor(agent.id);
35554
35788
  const card = node('article', undefined, 'tool-card compact');
35555
35789
  const head = node('div', undefined, 'tool-head');
35556
35790
  const title = node('div');
@@ -35558,16 +35792,18 @@ var init_guided_product_client = __esm({
35558
35792
  node('h3', agent.name),
35559
35793
  node('span', agent.version ? 'v' + agent.version : 'Version unavailable', 'caption'),
35560
35794
  );
35561
- head.append(title, pill(ready ? 'Ready' : 'Setup incomplete', ready ? 'good' : 'warn'));
35562
- card.append(
35563
- head,
35564
- node(
35565
- 'p',
35566
- ready
35567
- ? 'RTK + HarnessTrim are configured for this coding agent.'
35568
- : 'The agent is detected. Finish the recommended RTK + HarnessTrim setup to complete onboarding.',
35569
- ),
35570
- );
35795
+ head.append(title, pill(baseline.label, baseline.cls));
35796
+ const detail =
35797
+ baseline.state === 'incomplete'
35798
+ ? 'A reviewed automatic setup is available for ' +
35799
+ baseline.actionable.map(target => target.provider).join(' + ') +
35800
+ '. Finish setup to review and apply it.'
35801
+ : baseline.state === 'unavailable'
35802
+ ? 'No reviewed automatic baseline change is available for this exact agent, provider versions and platform. Token Harness will not offer a no-op setup button.'
35803
+ : baseline.state === 'limited'
35804
+ ? 'All currently reviewed automatic baseline actions are complete. Other baseline combinations are not automatically changed on this version/platform.'
35805
+ : 'All reviewed automatic baseline connections available for this coding agent are configured.';
35806
+ card.append(head, node('p', detail));
35571
35807
  if (agent.providers?.length)
35572
35808
  card.append(
35573
35809
  node(
@@ -35576,10 +35812,16 @@ var init_guided_product_client = __esm({
35576
35812
  'caption',
35577
35813
  ),
35578
35814
  );
35579
- if (!ready) {
35815
+ if (baseline.state === 'incomplete') {
35580
35816
  const actions = node('div', undefined, 'inline-actions');
35581
35817
  actions.append(actionButton('Finish setup', () => reviewSetup(agent.id)));
35582
35818
  card.append(actions);
35819
+ } else if (baseline.unavailable.length) {
35820
+ const details = node('details', undefined, 'agent-details');
35821
+ details.append(node('summary', 'Why some automatic connections are unavailable'));
35822
+ for (const target of baseline.unavailable)
35823
+ details.append(node('p', target.provider + ': ' + target.reason, 'caption'));
35824
+ card.append(details);
35583
35825
  }
35584
35826
  root.append(card);
35585
35827
  }
@@ -35601,7 +35843,7 @@ var init_guided_product_client = __esm({
35601
35843
  'Safe preview first',
35602
35844
  provider
35603
35845
  ? 'Token Harness will inspect only ' + provider.name + ' for ' + agent.name + '. If setup is supported, the exact change appears before you confirm it.'
35604
- : 'Token Harness will prepare the recommended RTK + HarnessTrim setup for ' + agent.name + '. The exact files and changes appear before you confirm them.',
35846
+ : 'Token Harness will prepare only the reviewed RTK/HarnessTrim changes that are actually available for ' + agent.name + ' on this version and platform. The exact files and changes appear before you confirm them.',
35605
35847
  ),
35606
35848
  messageBox('Nothing changes yet', 'This first step only prepares the safe plan. You decide whether to apply it after seeing the concrete changes.'),
35607
35849
  progress('Checking ' + agent.name, 'Reading installed optimizer versions and current integration state.'),
@@ -35627,29 +35869,36 @@ var init_guided_product_client = __esm({
35627
35869
  .then(data => {
35628
35870
  if (run !== modalRun || !$('modal').open) return;
35629
35871
  pendingTicket = data.ticket;
35872
+ if (!data.ticket) {
35873
+ refreshOverviewAfterMutation('Refreshing setup availability after the review…').catch(
35874
+ () => undefined,
35875
+ );
35876
+ }
35630
35877
  $('modal-content').replaceChildren();
35631
35878
  $('modal-content').append(
35632
35879
  messageBox(
35633
35880
  provider ? 'This optimizer only' : 'Recommended setup',
35634
35881
  provider
35635
35882
  ? 'This approval changes only ' + provider.name + ' for ' + agent.name + '. Other optimizers are left unchanged.'
35636
- : 'This approval covers only RTK + HarnessTrim for ' + agent.name + '. Optional optimizers stay separate.',
35883
+ : 'This review includes only the currently actionable RTK/HarnessTrim changes for ' + agent.name + '. Unsupported or already-complete baseline providers are left out. Optional optimizers stay separate.',
35637
35884
  ),
35638
35885
  );
35639
- if (!data.changes.length)
35886
+ if (!data.changes.length) {
35640
35887
  $('modal-content').append(
35641
35888
  messageBox(
35642
35889
  'No setup change available',
35643
35890
  (data.notices || []).join(' ') ||
35644
- 'This setup is already complete, or a prerequisite/version prevents Token Harness from changing it safely.',
35891
+ 'No reviewed automatic change is available now. The dashboard is refreshing so an obsolete setup action is not left visible.',
35645
35892
  ),
35646
35893
  );
35647
- for (const change of data.changes) {
35648
- const item = node('article', undefined, 'preview-change');
35649
- item.append(node('h3', change.title), node('p', change.description));
35650
- $('modal-content').append(item);
35894
+ } else {
35895
+ for (const change of data.changes) {
35896
+ const item = node('article', undefined, 'preview-change');
35897
+ item.append(node('h3', change.title), node('p', change.description));
35898
+ $('modal-content').append(item);
35899
+ }
35900
+ for (const notice of data.notices || []) $('modal-content').append(node('p', notice, 'notice-row'));
35651
35901
  }
35652
- for (const notice of data.notices || []) $('modal-content').append(node('p', notice, 'notice-row'));
35653
35902
  $('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'));
35654
35903
  $('modal-actions').replaceChildren(modalClose(data.ticket ? 'Cancel' : 'Done'));
35655
35904
  if (data.ticket)
@@ -35667,6 +35916,18 @@ var init_guided_product_client = __esm({
35667
35916
  });
35668
35917
  }
35669
35918
 
35919
+ async function refreshOverviewAfterMutation(message = 'Refreshing setup after the approved change…') {
35920
+ setStatus(message, true);
35921
+ $('stale-state').hidden = true;
35922
+ $('stale-state').textContent = '';
35923
+ const period = $('period').value;
35924
+ current = await request('/api/overview?period=' + encodeURIComponent(period) + '&refresh=1');
35925
+ periodCache.set(period, current);
35926
+ render();
35927
+ await loadActivity();
35928
+ setStatus('Updated at ' + new Date(current.generatedAt).toLocaleTimeString() + '.', false);
35929
+ }
35930
+
35670
35931
  async function applyTicket(ticket) {
35671
35932
  if (!ticket || busy) return;
35672
35933
  const run = modalRun;
@@ -35678,12 +35939,39 @@ var init_guided_product_client = __esm({
35678
35939
  const result = await request('/api/apply', { ticket });
35679
35940
  if (run !== modalRun) return;
35680
35941
  $('modal-title').textContent = result.title || (result.ok ? 'Setup completed' : 'Setup needs attention');
35681
- $('modal-content').replaceChildren(messageBox(result.ok ? 'Completed' : 'Needs attention', (result.messages || []).join(' '), result.ok ? 'safe' : 'warn'));
35682
- $('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'));
35683
- $('stale-state').hidden = false;
35684
- $('stale-state').textContent = 'A setup change was applied. Displayed status is the previous state until you choose Refresh.';
35942
+ $('modal-content').replaceChildren(
35943
+ messageBox(result.ok ? 'Applied' : 'Needs attention', (result.messages || []).join(' '), result.ok ? 'safe' : 'warn'),
35944
+ progress('Refreshing the current setup', 'Please wait while Token Harness re-reads agents, optimizer connections and health after the change.'),
35945
+ );
35946
+ $('modal-actions').replaceChildren(modalClose('Refreshing…', true));
35947
+ try {
35948
+ await refreshOverviewAfterMutation('Applying the new configuration and refreshing status…');
35949
+ if (run !== modalRun) return;
35950
+ $('modal-content').replaceChildren(
35951
+ messageBox(
35952
+ result.ok ? 'Completed and refreshed' : 'Action finished; status refreshed',
35953
+ (result.messages || []).join(' ') || 'The latest setup state is now shown on the dashboard.',
35954
+ result.ok ? 'safe' : 'warn',
35955
+ ),
35956
+ );
35957
+ } catch (refreshError) {
35958
+ if (run !== modalRun) return;
35959
+ $('stale-state').hidden = false;
35960
+ $('stale-state').textContent = 'The action finished, but Token Harness could not automatically refresh the latest setup state.';
35961
+ $('modal-content').replaceChildren(
35962
+ messageBox(
35963
+ result.ok ? 'Change applied' : 'Action finished',
35964
+ (result.messages || []).join(' ') || 'The action completed.',
35965
+ result.ok ? 'safe' : 'warn',
35966
+ ),
35967
+ messageBox(
35968
+ 'Automatic refresh failed',
35969
+ refreshError.message || 'The latest setup state could not be read automatically. Use Refresh to retry the status check.',
35970
+ 'warn',
35971
+ ),
35972
+ );
35973
+ }
35685
35974
  $('modal-actions').replaceChildren(modalClose('Done'));
35686
- loadActivity();
35687
35975
  } catch (error) {
35688
35976
  if (run !== modalRun) return;
35689
35977
  $('modal-error').textContent = error.message;
@@ -36991,7 +37279,7 @@ ${GUIDE_CANDIDATE_READINESS_JS}`;
36991
37279
  </div>
36992
37280
 
36993
37281
  <section class="setup-step" id="coding-agents">
36994
- <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>
37282
+ <div class="section-title"><div><h2>Coding agents</h2><p>Token Harness shows setup actions only when it has a reviewed automatic change for that exact agent, provider version and platform. Unsupported combinations are shown as unavailable instead of as unfinished work.</p></div></div>
36995
37283
  <div id="setup-agents" class="tool-grid"><article class="tool-card"><h3>Checking agents\u2026</h3></article></div>
36996
37284
  <details class="disclosure advanced-disclosure">
36997
37285
  <summary>Agent details and optional reasoning settings</summary>