token-harness 0.1.7 → 0.1.8
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 +89 -22
- package/package.json +1 -1
- package/sbom.json +3 -3
- package/token-harness.mjs +280 -135
package/README.md
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
**Make Claude Code and Codex easier to understand and use efficiently.**
|
|
4
4
|
|
|
5
5
|
Token Harness checks your coding agents, shows subscription allowance when it can be
|
|
6
|
-
observed reliably, reduces avoidable context overhead, and recommends
|
|
7
|
-
|
|
6
|
+
observed reliably, reduces avoidable context overhead, and recommends useful actions.
|
|
7
|
+
It runs locally and never presents local token estimates as subscription quota.
|
|
8
8
|
|
|
9
9
|
## The easy path
|
|
10
10
|
|
|
11
11
|
You need [Node.js 22.13 or newer](https://nodejs.org/) and at least one signed-in coding
|
|
12
|
-
agent
|
|
12
|
+
agent such as Claude Code or Codex.
|
|
13
13
|
|
|
14
14
|
Open a terminal and paste:
|
|
15
15
|
|
|
@@ -21,7 +21,7 @@ token-harness setup
|
|
|
21
21
|
That is the whole first-time check. `setup` tells you:
|
|
22
22
|
|
|
23
23
|
- which coding agents it found;
|
|
24
|
-
-
|
|
24
|
+
- which optimizers are already active;
|
|
25
25
|
- whether the current setup works;
|
|
26
26
|
- what it changed, if anything;
|
|
27
27
|
- exactly one next step.
|
|
@@ -44,16 +44,60 @@ After setup, run:
|
|
|
44
44
|
token-harness ui
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
The dashboard opens in your browser and
|
|
48
|
-
allowance windows, the main recommendation, and the next action. It is a small local
|
|
49
|
-
web page served only on `127.0.0.1`: no Electron app, account, or cloud service.
|
|
47
|
+
The dashboard opens in your browser and answers three questions in this order:
|
|
50
48
|
|
|
51
|
-
|
|
49
|
+
1. **Can I work normally right now?**
|
|
50
|
+
2. **What is actually active and useful?**
|
|
51
|
+
3. **Is there one action worth taking?**
|
|
52
|
+
|
|
53
|
+
It shows active/relevant coding agents first, their optimization providers, observable
|
|
54
|
+
allowance windows, and task guidance. Tools that are absent do not get large cards;
|
|
55
|
+
secondary detected tools are kept out of the main path.
|
|
56
|
+
|
|
57
|
+
The page is served only on `127.0.0.1`: no Electron app, account, or cloud service.
|
|
58
|
+
|
|
59
|
+
### What happens after the dashboard?
|
|
60
|
+
|
|
61
|
+
Usually: **nothing else. You are done.**
|
|
62
|
+
|
|
63
|
+
Token Harness is not a launcher and it does not need to stay between you and your coding
|
|
64
|
+
agent. Continue exactly as you normally would:
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
claude
|
|
68
|
+
codex
|
|
69
|
+
opencode
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Use whichever of those you already use. RTK, HarnessTrim, or another configured provider
|
|
73
|
+
runs automatically through that coding agent's integration. You do **not** need a special
|
|
74
|
+
`token-harness run` command.
|
|
75
|
+
|
|
76
|
+
You can close the dashboard whenever you want. Use `Ctrl+C` in the terminal to stop its
|
|
77
|
+
local web server. Closing it does not disable configured optimizers.
|
|
78
|
+
|
|
79
|
+
Open it again later with `token-harness ui` when you want a status check. If you do not
|
|
80
|
+
want it to open a browser:
|
|
52
81
|
|
|
53
82
|
```sh
|
|
54
83
|
token-harness ui --no-open
|
|
55
84
|
```
|
|
56
85
|
|
|
86
|
+
## Daily use
|
|
87
|
+
|
|
88
|
+
There is no mandatory command loop. These are tools you use when they answer a question:
|
|
89
|
+
|
|
90
|
+
| When you want to know... | Run |
|
|
91
|
+
| --- | --- |
|
|
92
|
+
| Is everything still connected? | `token-harness ui` |
|
|
93
|
+
| What should I do before a demanding task? | `token-harness optimize --task hard --profile quality` |
|
|
94
|
+
| Is an integration actually working? | `token-harness verify` |
|
|
95
|
+
| How much reducer saving has been measured? | `token-harness metrics --since 7d` |
|
|
96
|
+
| Are safer provider updates available? | `token-harness update` |
|
|
97
|
+
|
|
98
|
+
If a command finishes with **no action required**, stop there and use your coding agent
|
|
99
|
+
normally. Token Harness should not send you around a `ui → optimize → ui` loop.
|
|
100
|
+
|
|
57
101
|
## Ask your AI to install Token Harness
|
|
58
102
|
|
|
59
103
|
You can give this prompt to Claude Code or Codex:
|
|
@@ -67,8 +111,10 @@ Explain the setup result in plain language: what was detected, what already work
|
|
|
67
111
|
what would change, and the single next step. Do not expose credentials, cookies,
|
|
68
112
|
tokens, raw home paths, or private project contents. If setup proposes a supported
|
|
69
113
|
configuration change, show me the short plan and ask before running
|
|
70
|
-
`token-harness setup --yes`. After an approved change, verify it and
|
|
71
|
-
`token-harness ui
|
|
114
|
+
`token-harness setup --yes`. After an approved change, verify it and open
|
|
115
|
+
`token-harness ui` once. Then tell me clearly that setup is complete and that I should
|
|
116
|
+
continue using my normal coding-agent command. Do not invent additional Token Harness
|
|
117
|
+
steps when no action is required.
|
|
72
118
|
```
|
|
73
119
|
|
|
74
120
|
The AI should ask before the `--yes` step because that is the point where coding-agent
|
|
@@ -76,25 +122,37 @@ configuration may change.
|
|
|
76
122
|
|
|
77
123
|
## What normal output looks like
|
|
78
124
|
|
|
79
|
-
|
|
125
|
+
A healthy final check is intentionally short:
|
|
80
126
|
|
|
81
127
|
```text
|
|
82
128
|
TOKEN HARNESS - READY
|
|
83
129
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
harnesstrim: active on Codex
|
|
130
|
+
WHAT WORKS
|
|
131
|
+
Codex: configured (0.146.0)
|
|
132
|
+
HarnessTrim: active on Codex
|
|
88
133
|
|
|
89
134
|
CHANGES
|
|
90
135
|
Nothing changed.
|
|
91
136
|
|
|
92
137
|
NEXT STEP
|
|
93
|
-
|
|
94
|
-
|
|
138
|
+
Use your coding agent normally; configured optimizers run automatically.
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
A newer-than-tested combination is not presented as if the whole setup were broken:
|
|
142
|
+
|
|
143
|
+
```text
|
|
144
|
+
TOKEN HARNESS - READY WITH LIMITATIONS
|
|
145
|
+
|
|
146
|
+
WHAT WORKS
|
|
147
|
+
Claude Code: configured
|
|
148
|
+
RTK: active on Claude Code
|
|
149
|
+
|
|
150
|
+
NEXT STEP
|
|
151
|
+
token-harness verify
|
|
152
|
+
You can keep working; verify the active integrations when convenient.
|
|
95
153
|
```
|
|
96
154
|
|
|
97
|
-
Need the evidence behind
|
|
155
|
+
Need the evidence behind a summary? Add `--verbose`:
|
|
98
156
|
|
|
99
157
|
```sh
|
|
100
158
|
token-harness doctor --verbose
|
|
@@ -120,7 +178,7 @@ token-harness optimize
|
|
|
120
178
|
| Command | Answer |
|
|
121
179
|
| --- | --- |
|
|
122
180
|
| `setup` | Is Token Harness ready, and what is my one next step? |
|
|
123
|
-
| `ui` | What is active, how much allowance is visible, and
|
|
181
|
+
| `ui` | What is active, how much allowance is visible, and do I need to do anything? |
|
|
124
182
|
| `optimize` | What is the best evidence-based action for the task I am starting? |
|
|
125
183
|
|
|
126
184
|
For example:
|
|
@@ -141,13 +199,15 @@ Token Harness is conservative by design:
|
|
|
141
199
|
- existing files are backed up before a managed write;
|
|
142
200
|
- only exact Token Harness-owned entries are removed by `uninstall`;
|
|
143
201
|
- newer or untested combinations are reported, not guessed;
|
|
202
|
+
- an available provider update outside reviewed compatibility is kept out rather than
|
|
203
|
+
forced, and the installed working version stays in place;
|
|
144
204
|
- the dashboard binds only to the local loopback address and provides no mutation API;
|
|
145
205
|
- source code, prompts, command contents, credentials, and cookies are not sent to a
|
|
146
206
|
Token Harness service.
|
|
147
207
|
|
|
148
208
|
Plans, receipts, metrics, and backups stay in the local Token Harness state directory.
|
|
149
|
-
See [RFC 0004](docs/rfcs/0004-
|
|
150
|
-
|
|
209
|
+
See [RFC 0004](docs/rfcs/0004-safety-and-installation.md) for the execution model and
|
|
210
|
+
[RFC 0006](docs/rfcs/0006-cli-contract.md) for CLI/JSON guarantees.
|
|
151
211
|
|
|
152
212
|
## Supported optimizations
|
|
153
213
|
|
|
@@ -183,7 +243,7 @@ Most people do not need this section. Run `token-harness <command> --help` for d
|
|
|
183
243
|
| `verify` | Check the declared integration tier | No |
|
|
184
244
|
| `metrics` | Report attributable reducer savings | No |
|
|
185
245
|
| `status` | Report pipelines, drift, and importer modes | No |
|
|
186
|
-
| `update` | Check/update installed providers | Yes, only with `--yes` |
|
|
246
|
+
| `update` | Check/update installed providers; unreviewed targets stay installed | Yes, only with `--yes` |
|
|
187
247
|
| `rollback` | Restore the latest transaction snapshot | Yes, only with `--yes` |
|
|
188
248
|
| `uninstall` | Remove owned integration entries | Yes, only with `--yes` |
|
|
189
249
|
| `schedule` | Compare Claude Code and Codex using available evidence | No |
|
|
@@ -214,6 +274,13 @@ token-harness doctor --verbose
|
|
|
214
274
|
Do not force an unsupported plan. Open an issue with the redacted `--json` result if
|
|
215
275
|
you believe the combination should be supported.
|
|
216
276
|
|
|
277
|
+
### `update` finds a newer version but keeps the installed one
|
|
278
|
+
|
|
279
|
+
That is normally a safety decision, not a failed installation. Token Harness found a
|
|
280
|
+
newer provider release but does not yet have reviewed compatibility evidence for the
|
|
281
|
+
active provider × harness × platform combination. Keep using the installed version; no
|
|
282
|
+
manual upgrade is required.
|
|
283
|
+
|
|
217
284
|
### Verification says `not-exercised`
|
|
218
285
|
|
|
219
286
|
Restart the coding agent, use it for one normal command, and run:
|
package/package.json
CHANGED
package/sbom.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"bomFormat": "CycloneDX",
|
|
3
3
|
"specVersion": "1.5",
|
|
4
|
-
"serialNumber": "urn:uuid:
|
|
4
|
+
"serialNumber": "urn:uuid:dfdf5e8b-aba7-10dd-1c9d-dd9a38f31fb3",
|
|
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.
|
|
11
|
+
"version": "0.1.8",
|
|
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": "
|
|
23
|
+
"content": "dfdf5e8baba710dd1c9ddd9a38f31fb3aded525ea28f8b15a0fc5cff743444c6"
|
|
24
24
|
}
|
|
25
25
|
]
|
|
26
26
|
},
|
package/token-harness.mjs
CHANGED
|
@@ -6867,7 +6867,7 @@ var TOOL_VERSION;
|
|
|
6867
6867
|
var init_version2 = __esm({
|
|
6868
6868
|
"apps/cli/dist/src/version.js"() {
|
|
6869
6869
|
"use strict";
|
|
6870
|
-
TOOL_VERSION = "0.1.
|
|
6870
|
+
TOOL_VERSION = "0.1.8";
|
|
6871
6871
|
}
|
|
6872
6872
|
});
|
|
6873
6873
|
|
|
@@ -15074,7 +15074,7 @@ function contextEvidence(context, harness) {
|
|
|
15074
15074
|
const hasUnknownTools = harness.mcpServers.some((server) => server.toolCount === null);
|
|
15075
15075
|
const evidence2 = [];
|
|
15076
15076
|
let score = 0;
|
|
15077
|
-
if (harness.projectDocMaxBytes !== null && harness.projectDocMaxBytes > 0) {
|
|
15077
|
+
if (harness.projectDocMaxBytes !== null && harness.projectDocMaxBytes > 0 && instructionBytes > 0) {
|
|
15078
15078
|
const ratio = instructionBytes / harness.projectDocMaxBytes;
|
|
15079
15079
|
if (ratio >= 0.75)
|
|
15080
15080
|
score = Math.max(score, 2);
|
|
@@ -17636,7 +17636,9 @@ async function runSetup(context, operations = DEFAULT_OPERATIONS) {
|
|
|
17636
17636
|
diagnostics: doctor.diagnostics
|
|
17637
17637
|
});
|
|
17638
17638
|
}
|
|
17639
|
-
|
|
17639
|
+
const setupHarnessIds = new Set(detectedHarnesses.map((harness) => harness.harnessId));
|
|
17640
|
+
const hasBrokenSetupIntegration = detectedHarnesses.some((harness) => harness.state === "broken") || baseDoctor.providers.some((provider) => provider.state === "broken" && provider.configuredHarnesses.some((harness) => setupHarnessIds.has(harness)));
|
|
17641
|
+
if (hasBrokenSetupIntegration) {
|
|
17640
17642
|
return commandResult({
|
|
17641
17643
|
command: "setup",
|
|
17642
17644
|
exitCode: EXIT_CODES["problems-found"],
|
|
@@ -17650,7 +17652,7 @@ async function runSetup(context, operations = DEFAULT_OPERATIONS) {
|
|
|
17650
17652
|
budget: null,
|
|
17651
17653
|
nextStep: {
|
|
17652
17654
|
command: "token-harness doctor --verbose",
|
|
17653
|
-
description: "Review the
|
|
17655
|
+
description: "Review the broken active integration before changing configuration."
|
|
17654
17656
|
}
|
|
17655
17657
|
},
|
|
17656
17658
|
diagnostics: doctor.diagnostics
|
|
@@ -17679,7 +17681,7 @@ async function runSetup(context, operations = DEFAULT_OPERATIONS) {
|
|
|
17679
17681
|
budget: budget2.data,
|
|
17680
17682
|
nextStep: healthy2 ? {
|
|
17681
17683
|
command: "token-harness ui",
|
|
17682
|
-
description: "Open the dashboard to
|
|
17684
|
+
description: "Open the dashboard once to review status; then use your coding agent normally."
|
|
17683
17685
|
} : {
|
|
17684
17686
|
command: "token-harness verify --verbose",
|
|
17685
17687
|
description: "Review the failed integration check."
|
|
@@ -17775,7 +17777,7 @@ async function runSetup(context, operations = DEFAULT_OPERATIONS) {
|
|
|
17775
17777
|
budget: budget.data,
|
|
17776
17778
|
nextStep: healthy ? {
|
|
17777
17779
|
command: "token-harness ui",
|
|
17778
|
-
description: "Open the dashboard to
|
|
17780
|
+
description: "Open the dashboard once to review status; then use your coding agent normally."
|
|
17779
17781
|
} : {
|
|
17780
17782
|
command: "token-harness verify --verbose",
|
|
17781
17783
|
description: "Review the failed integration check."
|
|
@@ -17862,8 +17864,6 @@ function upgradeAction(input) {
|
|
|
17862
17864
|
return {
|
|
17863
17865
|
kind: "package-manager-install",
|
|
17864
17866
|
id: digest.slice(digest.indexOf(":") + 1, digest.indexOf(":") + 9),
|
|
17865
|
-
// The same class the install action uses, for the same reason: an installed package is not
|
|
17866
|
-
// reversed by restoring a file.
|
|
17867
17867
|
riskClass: "delegated",
|
|
17868
17868
|
requiresNetwork: input.requiresNetwork,
|
|
17869
17869
|
requiresElevation: input.requiresElevation,
|
|
@@ -17874,21 +17874,10 @@ function upgradeAction(input) {
|
|
|
17874
17874
|
`${input.packageName} is installed at ${input.installed}`
|
|
17875
17875
|
],
|
|
17876
17876
|
postconditions: [`${input.packageName} reports ${input.target}`],
|
|
17877
|
-
/**
|
|
17878
|
-
* `package-inventory` where the channel can report what is installed, `none` otherwise.
|
|
17879
|
-
*
|
|
17880
|
-
* An update replaces a binary. Rolling the transaction back restores files and leaves the new
|
|
17881
|
-
* version in place, so the executor's receipt is not boilerplate here — it is the difference
|
|
17882
|
-
* between the machine being restored and the *configuration* being restored. With an
|
|
17883
|
-
* inventory-capturing channel the rollback also reinstalls the previous version, and the
|
|
17884
|
-
* receipt says per package whether that reinstall took.
|
|
17885
|
-
*/
|
|
17886
17877
|
rollbackData: channelCanReportInventory(input.channel) ? "package-inventory" : "none",
|
|
17887
17878
|
explanation: `Update ${input.packageName} from ${input.installed} to ${input.target} through ${input.channel}`,
|
|
17888
17879
|
packageManager: input.channel,
|
|
17889
17880
|
packageName: input.packageName,
|
|
17890
|
-
// Pinned to the exact version the channel reported, not left open. An unpinned upgrade would
|
|
17891
|
-
// install whatever is newest at execution time, which is not the version the dry run showed.
|
|
17892
17881
|
version: input.target
|
|
17893
17882
|
};
|
|
17894
17883
|
}
|
|
@@ -17898,8 +17887,6 @@ async function runUpdate(context) {
|
|
|
17898
17887
|
const finish3 = (exitCode, data) => commandResult({
|
|
17899
17888
|
command: "update",
|
|
17900
17889
|
exitCode,
|
|
17901
|
-
// RFC 0006: `data` is null when the status is `error`, and the human renderer must read the
|
|
17902
|
-
// same object it serializes — the defect `apply` already had to fix.
|
|
17903
17890
|
data: statusForExitCode(exitCode) === "error" ? null : data,
|
|
17904
17891
|
diagnostics
|
|
17905
17892
|
});
|
|
@@ -17916,23 +17903,27 @@ async function runUpdate(context) {
|
|
|
17916
17903
|
const providerAdapters = listProviderAdapters().filter((adapter) => context.provider === null || adapter.manifest.id === context.provider);
|
|
17917
17904
|
const managedState = await managedIntegrations(context);
|
|
17918
17905
|
const managed = managedState.integrations;
|
|
17906
|
+
const harnessAdapters = listHarnessAdapters();
|
|
17919
17907
|
const managedHarnessIds = new Set(managed.map((entry) => entry.harnessId));
|
|
17908
|
+
if (managedState.legacyOwnershipUnknown) {
|
|
17909
|
+
for (const harness of harnessAdapters)
|
|
17910
|
+
managedHarnessIds.add(harness.manifest.id);
|
|
17911
|
+
}
|
|
17912
|
+
const harnessContext = {
|
|
17913
|
+
fs: adapters.fs,
|
|
17914
|
+
runner: adapters.runner,
|
|
17915
|
+
facts: context.platform,
|
|
17916
|
+
paths: adapters.paths,
|
|
17917
|
+
projectRoot: context.projectRoot
|
|
17918
|
+
};
|
|
17920
17919
|
const harnessVersions = /* @__PURE__ */ new Map();
|
|
17921
|
-
|
|
17922
|
-
|
|
17923
|
-
|
|
17924
|
-
|
|
17925
|
-
|
|
17926
|
-
paths: adapters.paths,
|
|
17927
|
-
projectRoot: context.projectRoot
|
|
17928
|
-
};
|
|
17929
|
-
for (const harness of listHarnessAdapters()) {
|
|
17930
|
-
if (!managedHarnessIds.has(harness.manifest.id))
|
|
17931
|
-
continue;
|
|
17932
|
-
const detection = await harness.detect(harnessContext);
|
|
17933
|
-
harnessVersions.set(harness.manifest.id, detection.version);
|
|
17934
|
-
}
|
|
17920
|
+
for (const harness of harnessAdapters) {
|
|
17921
|
+
if (!managedHarnessIds.has(harness.manifest.id))
|
|
17922
|
+
continue;
|
|
17923
|
+
const detection = await harness.detect(harnessContext);
|
|
17924
|
+
harnessVersions.set(harness.manifest.id, detection.version);
|
|
17935
17925
|
}
|
|
17926
|
+
const recoveryHarnessConfigs = managedState.legacyOwnershipUnknown ? (await Promise.all(harnessAdapters.map(async (harness) => (await harness.inspect(harnessContext)).summaries))).flat() : [];
|
|
17936
17927
|
const pins = context.stateRoot === null ? { pins: /* @__PURE__ */ new Map(), unhonoredProjectPinPath: null, diagnostics: [] } : await readPins({
|
|
17937
17928
|
fs: adapters.fs,
|
|
17938
17929
|
stateRoot: context.stateRoot,
|
|
@@ -17945,7 +17936,7 @@ async function runUpdate(context) {
|
|
|
17945
17936
|
facts: context.platform,
|
|
17946
17937
|
paths: adapters.paths,
|
|
17947
17938
|
projectRoot: context.projectRoot,
|
|
17948
|
-
harnessConfigs:
|
|
17939
|
+
harnessConfigs: recoveryHarnessConfigs,
|
|
17949
17940
|
now: context.now,
|
|
17950
17941
|
localDatabase: adapters.localDatabase,
|
|
17951
17942
|
projectIdFor: adapters.projectIdFor
|
|
@@ -18008,22 +17999,18 @@ async function runUpdate(context) {
|
|
|
18008
17999
|
report.providers.push(row2);
|
|
18009
18000
|
continue;
|
|
18010
18001
|
}
|
|
18011
|
-
const
|
|
18012
|
-
let updateAdmitted = !managedState.legacyOwnershipUnknown;
|
|
18002
|
+
const compatibilityHarnessIds = new Set(managed.filter((entry) => entry.providerId === adapter.manifest.id).map((entry) => entry.harnessId));
|
|
18013
18003
|
if (managedState.legacyOwnershipUnknown) {
|
|
18014
|
-
|
|
18015
|
-
|
|
18016
|
-
target: query.version,
|
|
18017
|
-
harnessId: "legacy-owned-state",
|
|
18018
|
-
missing: "a committed pre-attribution journal owns configuration but does not identify its provider and harness"
|
|
18019
|
-
});
|
|
18004
|
+
for (const harnessId2 of detection.configuredHarnesses)
|
|
18005
|
+
compatibilityHarnessIds.add(harnessId2);
|
|
18020
18006
|
}
|
|
18021
|
-
|
|
18007
|
+
let updateAdmitted = true;
|
|
18008
|
+
for (const harnessId2 of compatibilityHarnessIds) {
|
|
18022
18009
|
const admission = admitManagedMutation(context.compatibilityRows ?? COMPATIBILITY_ROWS, {
|
|
18023
18010
|
provider: adapter.manifest.id,
|
|
18024
18011
|
providerVersion: query.version,
|
|
18025
|
-
harness:
|
|
18026
|
-
harnessVersion: harnessVersions.get(
|
|
18012
|
+
harness: harnessId2,
|
|
18013
|
+
harnessVersion: harnessVersions.get(harnessId2) ?? null,
|
|
18027
18014
|
os: context.platform.os,
|
|
18028
18015
|
wsl: context.platform.isWsl
|
|
18029
18016
|
});
|
|
@@ -18032,8 +18019,9 @@ async function runUpdate(context) {
|
|
|
18032
18019
|
updateAdmitted = false;
|
|
18033
18020
|
blockedUpdates.push({
|
|
18034
18021
|
providerId: adapter.manifest.id,
|
|
18022
|
+
installed: detection.version,
|
|
18035
18023
|
target: query.version,
|
|
18036
|
-
harnessId:
|
|
18024
|
+
harnessId: harnessId2,
|
|
18037
18025
|
missing: admission.missing
|
|
18038
18026
|
});
|
|
18039
18027
|
}
|
|
@@ -18055,20 +18043,25 @@ async function runUpdate(context) {
|
|
|
18055
18043
|
}));
|
|
18056
18044
|
}
|
|
18057
18045
|
report.network = [...destinations].sort();
|
|
18058
|
-
const blockedIsOutcome = blockedUpdates.length > 0 && actions.length === 0;
|
|
18059
18046
|
for (const blocked of blockedUpdates) {
|
|
18060
18047
|
diagnostics.push(diagnostic({
|
|
18061
|
-
severity:
|
|
18048
|
+
severity: "info",
|
|
18062
18049
|
code: "managed-update-blocked",
|
|
18063
|
-
message:
|
|
18064
|
-
remediation: "
|
|
18050
|
+
message: `${blocked.providerId} ${blocked.target} is available but is not validated for ${blocked.harnessId}; keeping ${blocked.installed ?? "the installed version"}`,
|
|
18051
|
+
remediation: "No action is required; Token Harness will allow the update after this combination has reviewed compatibility evidence"
|
|
18052
|
+
}));
|
|
18053
|
+
diagnostics.push(diagnostic({
|
|
18054
|
+
severity: "info",
|
|
18055
|
+
code: "managed-update-blocked-detail",
|
|
18056
|
+
message: `${blocked.providerId} ${blocked.target} compatibility evidence is missing: ${blocked.missing}`,
|
|
18057
|
+
remediation: null
|
|
18065
18058
|
}));
|
|
18066
18059
|
}
|
|
18067
18060
|
if (pins.unhonoredProjectPinPath !== null) {
|
|
18068
18061
|
}
|
|
18069
18062
|
if (actions.length === 0 && blockedUpdates.length > 0) {
|
|
18070
|
-
report.execution = emptyExecution("
|
|
18071
|
-
return finish3(EXIT_CODES
|
|
18063
|
+
report.execution = emptyExecution("nothing-to-do");
|
|
18064
|
+
return finish3(EXIT_CODES.ok, report);
|
|
18072
18065
|
}
|
|
18073
18066
|
if (actions.length === 0) {
|
|
18074
18067
|
report.execution = emptyExecution("nothing-to-do");
|
|
@@ -18085,7 +18078,6 @@ async function runUpdate(context) {
|
|
|
18085
18078
|
diagnostics.push(diagnostic({
|
|
18086
18079
|
severity: "error",
|
|
18087
18080
|
code: "confirmation-required",
|
|
18088
|
-
// In the message and not only in `data`: exit 8 is an `error` status, so `data` is null.
|
|
18089
18081
|
message: `Would update ${summary}`,
|
|
18090
18082
|
remediation: "Re-run with `--yes` to apply it"
|
|
18091
18083
|
}));
|
|
@@ -18136,8 +18128,6 @@ async function runUpdate(context) {
|
|
|
18136
18128
|
planId: null,
|
|
18137
18129
|
transactionId,
|
|
18138
18130
|
fromStoredPlan: false,
|
|
18139
|
-
// Mapped the way `apply` maps it: `in-progress` is not a terminal outcome a report may
|
|
18140
|
-
// carry, and anything that is not one of the three known ends is a rejection.
|
|
18141
18131
|
outcome: transaction.journal.outcome === "committed" ? "committed" : transaction.journal.outcome === "rolled-back" ? "rolled-back" : transaction.journal.outcome === "dirty" ? "dirty" : "rejected",
|
|
18142
18132
|
results: transaction.journal.entries.map((entry) => ({
|
|
18143
18133
|
actionId: entry.actionId,
|
|
@@ -19421,32 +19411,53 @@ function harnessName(id) {
|
|
|
19421
19411
|
return "Codex";
|
|
19422
19412
|
if (id === "opencode")
|
|
19423
19413
|
return "OpenCode";
|
|
19414
|
+
if (id === "pi")
|
|
19415
|
+
return "Pi";
|
|
19416
|
+
if (id === "hermes")
|
|
19417
|
+
return "Hermes";
|
|
19418
|
+
return id;
|
|
19419
|
+
}
|
|
19420
|
+
function providerName(id) {
|
|
19421
|
+
if (id === "rtk")
|
|
19422
|
+
return "RTK";
|
|
19423
|
+
if (id === "harnesstrim")
|
|
19424
|
+
return "HarnessTrim";
|
|
19424
19425
|
return id;
|
|
19425
19426
|
}
|
|
19427
|
+
function normalWork() {
|
|
19428
|
+
return "Use your coding agent normally; configured optimizers run automatically.";
|
|
19429
|
+
}
|
|
19430
|
+
function usefulEvidence(evidence2) {
|
|
19431
|
+
const useful = evidence2.find((item) => !/^0B known loaded of /i.test(item.summary) && !/^0 MCP servers/i.test(item.summary) && !/^0B of instruction candidates/i.test(item.summary));
|
|
19432
|
+
return useful?.summary ?? evidence2[0]?.summary ?? null;
|
|
19433
|
+
}
|
|
19426
19434
|
function renderSimpleDoctor(report) {
|
|
19427
19435
|
const present = report.harnesses.filter((item) => item.state !== "absent");
|
|
19428
19436
|
const active = report.providers.filter((item) => item.state === "configured" && item.configuredHarnesses.length > 0);
|
|
19429
|
-
const
|
|
19437
|
+
const broken = present.some((item) => item.state === "broken") || report.providers.some((item) => item.state === "broken");
|
|
19438
|
+
const newerThanTested = [...present, ...report.providers].some((item) => item.versionVerdict === "unknown-newer");
|
|
19439
|
+
const state = broken ? "attention needed" : newerThanTested ? "ready with limitations" : present.length > 0 ? "ready" : "setup needed";
|
|
19430
19440
|
const lines = [...title(state), "WHAT WORKS"];
|
|
19431
19441
|
if (present.length === 0)
|
|
19432
19442
|
lines.push(" No supported coding harness was found.");
|
|
19433
|
-
for (const item of
|
|
19434
|
-
|
|
19435
|
-
lines.push(` ${harnessName(item.harnessId)}: ${stateText}${item.version ? ` (${item.version})` : ""}`);
|
|
19443
|
+
for (const item of present) {
|
|
19444
|
+
lines.push(` ${harnessName(item.harnessId)}: ${item.state}${item.version ? ` (${item.version})` : ""}`);
|
|
19436
19445
|
}
|
|
19437
|
-
if (
|
|
19438
|
-
lines.push("
|
|
19439
|
-
for (const item of
|
|
19446
|
+
if (active.length === 0)
|
|
19447
|
+
lines.push(" Optimization provider: none active");
|
|
19448
|
+
for (const item of active) {
|
|
19440
19449
|
const connected = item.configuredHarnesses.map(harnessName).join(", ");
|
|
19441
|
-
lines.push(truncate(` ${item.providerId}:
|
|
19450
|
+
lines.push(truncate(` ${providerName(item.providerId)}: active on ${connected}`, MAX_WIDTH));
|
|
19442
19451
|
}
|
|
19443
19452
|
lines.push(...changeLine(false));
|
|
19444
|
-
if (
|
|
19445
|
-
lines.push(...next("token-harness doctor --verbose", "Review the
|
|
19453
|
+
if (broken) {
|
|
19454
|
+
lines.push(...next("token-harness doctor --verbose", "Review the integration that needs attention."));
|
|
19446
19455
|
} else if (present.length === 0 || active.length === 0) {
|
|
19447
19456
|
lines.push(...next("token-harness setup", "Finish the guided setup."));
|
|
19457
|
+
} else if (newerThanTested) {
|
|
19458
|
+
lines.push(...next("token-harness verify", "You can keep working; verify the active integrations when convenient."));
|
|
19448
19459
|
} else {
|
|
19449
|
-
lines.push(...next(
|
|
19460
|
+
lines.push(...next(null, normalWork()));
|
|
19450
19461
|
}
|
|
19451
19462
|
return document(lines);
|
|
19452
19463
|
}
|
|
@@ -19463,7 +19474,7 @@ function renderSimpleSetup(report, context) {
|
|
|
19463
19474
|
if (active.length === 0)
|
|
19464
19475
|
lines.push(" Optimization provider: not active");
|
|
19465
19476
|
for (const provider of active) {
|
|
19466
|
-
lines.push(truncate(` ${provider.providerId}: active on ${provider.configuredHarnesses.map(harnessName).join(", ")}`, MAX_WIDTH));
|
|
19477
|
+
lines.push(truncate(` ${providerName(provider.providerId)}: active on ${provider.configuredHarnesses.map(harnessName).join(", ")}`, MAX_WIDTH));
|
|
19467
19478
|
}
|
|
19468
19479
|
if (report.plan !== null && report.apply === null && report.plan.actions.length > 0) {
|
|
19469
19480
|
lines.push("", "SAFE PLAN");
|
|
@@ -19473,7 +19484,7 @@ function renderSimpleSetup(report, context) {
|
|
|
19473
19484
|
}
|
|
19474
19485
|
}
|
|
19475
19486
|
lines.push(...changeLine(report.changed, report.apply?.results.some((item) => item.status === "applied") ? "Safe configuration applied and checked." : void 0));
|
|
19476
|
-
lines.push(...next(report.nextStep.command, report.nextStep.description));
|
|
19487
|
+
lines.push(...next(report.nextStep.command, report.stage === "ready" && report.nextStep.command === "token-harness ui" ? "Open the dashboard once to review status; after that use your coding agent normally." : report.nextStep.description));
|
|
19477
19488
|
return document(lines);
|
|
19478
19489
|
}
|
|
19479
19490
|
function renderVerboseSetup(report, context) {
|
|
@@ -19546,7 +19557,7 @@ function renderSimpleBudget(report) {
|
|
|
19546
19557
|
}
|
|
19547
19558
|
}
|
|
19548
19559
|
lines.push(...changeLine(false));
|
|
19549
|
-
lines.push(...next(observed.length > 0 ? "token-harness optimize" : "token-harness setup", observed.length > 0 ? "
|
|
19560
|
+
lines.push(...next(observed.length > 0 ? "token-harness optimize" : "token-harness setup", observed.length > 0 ? "Get advice for the task you are about to start." : "Check the local installation and connections."));
|
|
19550
19561
|
return document(lines);
|
|
19551
19562
|
}
|
|
19552
19563
|
function renderSimpleContext(report) {
|
|
@@ -19567,7 +19578,7 @@ function renderSimpleMcp(report) {
|
|
|
19567
19578
|
lines.push(` ${harnessName(harness.harnessId)}: ${harness.servers.length} servers, ${harness.knownToolCount} known tools`);
|
|
19568
19579
|
}
|
|
19569
19580
|
lines.push(...changeLine(false));
|
|
19570
|
-
lines.push(...next(attention ? "token-harness mcp --verbose" : "token-harness optimize", attention ? "Review the server that needs attention." : "See whether context can be simplified."));
|
|
19581
|
+
lines.push(...next(attention ? "token-harness mcp --verbose" : "token-harness optimize", attention ? "Review the server that needs attention." : "See whether context can be simplified for the next task."));
|
|
19571
19582
|
return document(lines);
|
|
19572
19583
|
}
|
|
19573
19584
|
function renderSimpleOptimize(report) {
|
|
@@ -19579,15 +19590,15 @@ function renderSimpleOptimize(report) {
|
|
|
19579
19590
|
if (advice.length === 0)
|
|
19580
19591
|
lines.push(" No supported harness could be assessed.");
|
|
19581
19592
|
for (const harness of advice) {
|
|
19582
|
-
const recommendation = harness.recommendations.find((item) => item.priority === "first") ?? harness.recommendations
|
|
19593
|
+
const recommendation = harness.recommendations.find((item) => item.priority === "first") ?? harness.recommendations.find((item) => item.priority === "next");
|
|
19583
19594
|
lines.push(truncate(` ${harnessName(harness.harnessId)}: ${recommendation?.action ?? "No change recommended."}`, MAX_WIDTH));
|
|
19584
|
-
const evidence2 = recommendation
|
|
19595
|
+
const evidence2 = recommendation === void 0 ? null : usefulEvidence(recommendation.evidence);
|
|
19585
19596
|
if (evidence2)
|
|
19586
19597
|
lines.push(truncate(` Why: ${evidence2}`, MAX_WIDTH));
|
|
19587
19598
|
}
|
|
19588
19599
|
lines.push(...changeLine(false));
|
|
19589
19600
|
const canPlan = advice.some((item) => item.recommendedEffort !== item.currentEffort || item.recommendedVerbosity !== item.currentVerbosity);
|
|
19590
|
-
lines.push(...next(canPlan ? "token-harness plan --native-policy" :
|
|
19601
|
+
lines.push(...next(canPlan ? "token-harness plan --native-policy" : null, canPlan ? "Review the reversible recommended policy change." : "No change is required now. " + normalWork()));
|
|
19591
19602
|
return document(lines);
|
|
19592
19603
|
}
|
|
19593
19604
|
function renderSimplePlan(report, context) {
|
|
@@ -19616,9 +19627,9 @@ function renderSimplePlan(report, context) {
|
|
|
19616
19627
|
else if (report.actions.length > 0 && report.persisted && report.planId !== null)
|
|
19617
19628
|
lines.push(...next(`token-harness apply --plan ${report.planId} --yes`, "Apply exactly this stored plan."));
|
|
19618
19629
|
else if (report.actions.length === 0)
|
|
19619
|
-
lines.push(...next("token-harness setup", "Check detection and finish guided setup."));
|
|
19630
|
+
lines.push(...report.pipelineId === null ? next("token-harness setup", "Check detection and finish guided setup.") : next(null, normalWork()));
|
|
19620
19631
|
else
|
|
19621
|
-
lines.push(...next("token-harness ui", "Open the dashboard."));
|
|
19632
|
+
lines.push(...next("token-harness ui", "Open the dashboard to review the current state."));
|
|
19622
19633
|
return document(lines);
|
|
19623
19634
|
}
|
|
19624
19635
|
function renderSimpleApply(report, command) {
|
|
@@ -19633,7 +19644,7 @@ function renderSimpleApply(report, command) {
|
|
|
19633
19644
|
lines.push(` Transaction: ${report.transactionId ?? "none"}`);
|
|
19634
19645
|
lines.push(...changeLine(changed, command === "uninstall" ? "Owned configuration removed." : command === "rollback" ? "Previous configuration restored." : "Configuration applied and committed."));
|
|
19635
19646
|
const confirmationCommand = command === "apply" && report.planId !== null ? `token-harness apply --plan ${report.planId} --yes` : `token-harness ${command} --yes`;
|
|
19636
|
-
lines.push(...next(okay ? "token-harness verify" : report.outcome === "confirmation-required" ? confirmationCommand : `token-harness ${command} --verbose`, okay ? "Check that the integration works." : report.outcome === "confirmation-required" ? "Apply the reviewed change." : "Review the technical result."));
|
|
19647
|
+
lines.push(...next(okay ? "token-harness verify" : report.outcome === "confirmation-required" ? confirmationCommand : `token-harness ${command} --verbose`, okay ? "Check that the integration works; a successful verify is the end of setup." : report.outcome === "confirmation-required" ? "Apply the reviewed change." : "Review the technical result."));
|
|
19637
19648
|
return document(lines);
|
|
19638
19649
|
}
|
|
19639
19650
|
function renderSimpleVerify(report) {
|
|
@@ -19644,9 +19655,9 @@ function renderSimpleVerify(report) {
|
|
|
19644
19655
|
if (report.results.length === 0)
|
|
19645
19656
|
lines.push(" Nothing is configured to verify yet.");
|
|
19646
19657
|
for (const item of report.results)
|
|
19647
|
-
lines.push(truncate(` ${item.providerId} on ${harnessName(item.harnessId)}: ${item.status}`, MAX_WIDTH));
|
|
19658
|
+
lines.push(truncate(` ${providerName(item.providerId)} on ${harnessName(item.harnessId)}: ${item.status}`, MAX_WIDTH));
|
|
19648
19659
|
lines.push(...changeLine(false));
|
|
19649
|
-
lines.push(...next(report.healthyAtDeclaredTier ?
|
|
19660
|
+
lines.push(...next(report.healthyAtDeclaredTier ? null : "token-harness verify --verbose", report.healthyAtDeclaredTier ? normalWork() : "Review the failed check and suggested fix."));
|
|
19650
19661
|
return document(lines);
|
|
19651
19662
|
}
|
|
19652
19663
|
function renderSimpleStatus(report) {
|
|
@@ -19655,11 +19666,11 @@ function renderSimpleStatus(report) {
|
|
|
19655
19666
|
lines.push(" No Token Harness pipeline is active.");
|
|
19656
19667
|
for (const pipeline of report.pipelines) {
|
|
19657
19668
|
const providers = [...new Set(pipeline.owners.map((owner) => owner.owner))];
|
|
19658
|
-
lines.push(truncate(` ${harnessName(pipeline.harness)}: ${providers.join(" -> ") || "no provider"}`, MAX_WIDTH));
|
|
19669
|
+
lines.push(truncate(` ${harnessName(pipeline.harness)}: ${providers.map(providerName).join(" -> ") || "no provider"}`, MAX_WIDTH));
|
|
19659
19670
|
}
|
|
19660
19671
|
lines.push(` Drift: ${report.drift.length === 0 ? "none" : report.drift.length}`);
|
|
19661
19672
|
lines.push(...changeLine(false));
|
|
19662
|
-
lines.push(...next(report.problemCount === 0 ? report.pipelines.length === 0 ? "token-harness setup" :
|
|
19673
|
+
lines.push(...next(report.problemCount === 0 ? report.pipelines.length === 0 ? "token-harness setup" : null : "token-harness status --verbose", report.problemCount === 0 ? report.pipelines.length === 0 ? "Finish the guided setup." : normalWork() : "Review the drift before making changes."));
|
|
19663
19674
|
return document(lines);
|
|
19664
19675
|
}
|
|
19665
19676
|
function renderSimpleMetrics(report) {
|
|
@@ -19671,7 +19682,7 @@ function renderSimpleMetrics(report) {
|
|
|
19671
19682
|
lines.push(` ${item.class}: ${formatCount(item.saved ?? 0)} ${item.unit ?? ""} saved`);
|
|
19672
19683
|
lines.push(` Errors: ${report.errors}`);
|
|
19673
19684
|
lines.push(...changeLine(false));
|
|
19674
|
-
lines.push(...next("
|
|
19685
|
+
lines.push(...next(null, "Measurement is complete. Use optimize before a task only when you want fresh advice."));
|
|
19675
19686
|
return document(lines);
|
|
19676
19687
|
}
|
|
19677
19688
|
function renderSimpleHistory(report) {
|
|
@@ -19681,9 +19692,26 @@ function renderSimpleHistory(report) {
|
|
|
19681
19692
|
for (const item of report.harnesses)
|
|
19682
19693
|
lines.push(` ${harnessName(item.harnessId)}: ${formatCount(item.totalTokens)} tokens, trend ${item.burnTrend.state}`);
|
|
19683
19694
|
lines.push(...changeLine(false));
|
|
19684
|
-
lines.push(...next("token-harness optimize
|
|
19695
|
+
lines.push(...next(null, "History is informational. Run token-harness optimize when you want task-specific advice."));
|
|
19685
19696
|
return document(lines);
|
|
19686
19697
|
}
|
|
19698
|
+
function updateStatus(item) {
|
|
19699
|
+
if (item.verdict === "current")
|
|
19700
|
+
return `${item.installed ?? "installed"} is current`;
|
|
19701
|
+
if (item.verdict === "pinned")
|
|
19702
|
+
return `kept at ${item.pin ?? item.installed ?? "installed"} (pinned)`;
|
|
19703
|
+
if (item.verdict === "blocked-unreviewed")
|
|
19704
|
+
return `${item.available ?? "newer version"} available; keeping ${item.installed ?? "installed"} until validated`;
|
|
19705
|
+
if (item.verdict === "upgradable")
|
|
19706
|
+
return `${item.installed ?? "installed"} -> ${item.available ?? "newer version"} ready`;
|
|
19707
|
+
if (item.verdict === "not-installed")
|
|
19708
|
+
return "not installed";
|
|
19709
|
+
if (item.verdict === "no-channel")
|
|
19710
|
+
return "installed; no supported update channel";
|
|
19711
|
+
if (item.verdict === "unavailable")
|
|
19712
|
+
return "installed; update check unavailable";
|
|
19713
|
+
return "installed; update status unknown";
|
|
19714
|
+
}
|
|
19687
19715
|
function renderSimpleUpdate(report) {
|
|
19688
19716
|
const execution = report.execution;
|
|
19689
19717
|
const changed = execution?.outcome === "committed" && execution.results.some((item) => item.status === "applied");
|
|
@@ -19691,10 +19719,11 @@ function renderSimpleUpdate(report) {
|
|
|
19691
19719
|
if (report.providers.length === 0)
|
|
19692
19720
|
lines.push(" No provider was detected.");
|
|
19693
19721
|
for (const item of report.providers)
|
|
19694
|
-
lines.push(truncate(` ${item.providerId}: ${item
|
|
19722
|
+
lines.push(truncate(` ${providerName(item.providerId)}: ${updateStatus(item)}`, MAX_WIDTH));
|
|
19695
19723
|
lines.push(...changeLine(changed, "Provider update applied."));
|
|
19696
19724
|
const pending = report.providers.some((item) => item.verdict === "upgradable");
|
|
19697
|
-
|
|
19725
|
+
const deferred = report.providers.some((item) => item.verdict === "blocked-unreviewed");
|
|
19726
|
+
lines.push(...next(pending && execution?.outcome === "confirmation-required" ? "token-harness update --yes" : changed ? "token-harness verify" : null, pending && execution?.outcome === "confirmation-required" ? "Apply the reviewed provider update." : changed ? "Check that the updated integrations still work." : deferred ? "No action required. The installed versions stay active until newer ones are validated." : normalWork()));
|
|
19698
19727
|
return document(lines);
|
|
19699
19728
|
}
|
|
19700
19729
|
var init_simple = __esm({
|
|
@@ -20463,59 +20492,129 @@ function nameOf(id) {
|
|
|
20463
20492
|
return "Codex";
|
|
20464
20493
|
if (id === "opencode")
|
|
20465
20494
|
return "OpenCode";
|
|
20495
|
+
if (id === "pi")
|
|
20496
|
+
return "Pi";
|
|
20497
|
+
if (id === "hermes")
|
|
20498
|
+
return "Hermes";
|
|
20499
|
+
return id;
|
|
20500
|
+
}
|
|
20501
|
+
function providerName2(id) {
|
|
20502
|
+
if (id === "harnesstrim")
|
|
20503
|
+
return "HarnessTrim";
|
|
20504
|
+
if (id === "rtk")
|
|
20505
|
+
return "RTK";
|
|
20466
20506
|
return id;
|
|
20467
20507
|
}
|
|
20508
|
+
function usefulReason(evidence2) {
|
|
20509
|
+
const useful = evidence2.find((item) => !/^0B known loaded of /i.test(item.summary) && !/^0 MCP servers/i.test(item.summary) && !/^0B of instruction candidates/i.test(item.summary));
|
|
20510
|
+
return useful?.summary ?? evidence2[0]?.summary ?? null;
|
|
20511
|
+
}
|
|
20468
20512
|
function buildDashboardModel(input) {
|
|
20469
20513
|
const present = input.doctor.harnesses.filter((item) => item.state !== "absent");
|
|
20470
|
-
const
|
|
20471
|
-
const
|
|
20472
|
-
const
|
|
20473
|
-
const
|
|
20514
|
+
const connectedProviders = input.doctor.providers.filter((item) => item.configuredHarnesses.length > 0);
|
|
20515
|
+
const configuredProviders = connectedProviders.filter((item) => item.state === "configured");
|
|
20516
|
+
const relevantHarnessIds = /* @__PURE__ */ new Set();
|
|
20517
|
+
for (const provider of connectedProviders) {
|
|
20518
|
+
for (const harness of provider.configuredHarnesses)
|
|
20519
|
+
relevantHarnessIds.add(harness);
|
|
20520
|
+
}
|
|
20521
|
+
for (const item of input.budget.harnesses) {
|
|
20522
|
+
if (item.windows.length > 0)
|
|
20523
|
+
relevantHarnessIds.add(item.harnessId);
|
|
20524
|
+
}
|
|
20525
|
+
for (const pipeline of input.status.pipelines)
|
|
20526
|
+
relevantHarnessIds.add(pipeline.harness);
|
|
20527
|
+
const relevantHarnesses = present.filter((harness) => relevantHarnessIds.has(harness.harnessId));
|
|
20528
|
+
const broken = relevantHarnesses.some((item) => item.state === "broken") || connectedProviders.some((item) => item.state === "broken");
|
|
20529
|
+
const newerThanTested = relevantHarnesses.some((item) => item.versionVerdict === "unknown-newer") || connectedProviders.some((item) => item.versionVerdict === "unknown-newer");
|
|
20530
|
+
const state = present.length === 0 ? "setup-needed" : broken || input.status.problemCount > 0 ? "action-needed" : configuredProviders.length === 0 ? "setup-needed" : newerThanTested ? "limited" : "ready";
|
|
20531
|
+
const rankedRecommendations = input.optimize.harnesses.filter((harness) => harness.state !== "absent" && relevantHarnessIds.has(harness.harnessId)).flatMap((harness) => harness.recommendations.map((item) => ({
|
|
20474
20532
|
harness: harness.harnessId,
|
|
20475
20533
|
priority: item.priority,
|
|
20476
20534
|
action: item.action,
|
|
20477
|
-
reason: item.evidence
|
|
20535
|
+
reason: usefulReason(item.evidence)
|
|
20478
20536
|
}))).sort((left, right) => {
|
|
20479
20537
|
const rank = { first: 0, next: 1, optional: 2 };
|
|
20480
20538
|
return rank[left.priority] - rank[right.priority];
|
|
20481
|
-
})
|
|
20482
|
-
const
|
|
20483
|
-
|
|
20484
|
-
|
|
20539
|
+
});
|
|
20540
|
+
const recommendation = rankedRecommendations.find((item) => item.priority !== "optional");
|
|
20541
|
+
const harnesses = relevantHarnesses.map((harness) => {
|
|
20542
|
+
const providerIds = configuredProviders.filter((provider) => provider.configuredHarnesses.includes(harness.harnessId)).map((provider) => provider.providerId);
|
|
20543
|
+
const budget = input.budget.harnesses.find((item) => item.harnessId === harness.harnessId);
|
|
20544
|
+
const health = harness.state === "broken" ? "attention" : harness.versionVerdict === "unknown-newer" ? "limited" : "active";
|
|
20545
|
+
const statusLabel = health === "attention" ? "Needs attention" : health === "limited" ? "Works \xB7 newer than tested" : providerIds.length > 0 ? "Optimized" : "Available";
|
|
20546
|
+
return {
|
|
20547
|
+
id: harness.harnessId,
|
|
20548
|
+
name: nameOf(harness.harnessId),
|
|
20549
|
+
health,
|
|
20550
|
+
statusLabel,
|
|
20551
|
+
version: harness.version,
|
|
20552
|
+
providers: providerIds.map(providerName2),
|
|
20553
|
+
allowance: (budget?.windows ?? []).map((window) => ({
|
|
20554
|
+
label: window.bucketName ?? window.scope,
|
|
20555
|
+
remainingPercent: window.remainingPercent,
|
|
20556
|
+
resetsAt: window.resetsAt,
|
|
20557
|
+
confidence: window.confidence
|
|
20558
|
+
}))
|
|
20559
|
+
};
|
|
20560
|
+
});
|
|
20561
|
+
const otherHarnesses = present.filter((harness) => !relevantHarnessIds.has(harness.harnessId)).map((harness) => ({ name: nameOf(harness.harnessId), version: harness.version }));
|
|
20562
|
+
const providers = configuredProviders.map((provider) => ({
|
|
20563
|
+
id: provider.providerId,
|
|
20564
|
+
name: providerName2(provider.providerId),
|
|
20565
|
+
harnesses: provider.configuredHarnesses.map(nameOf)
|
|
20566
|
+
}));
|
|
20567
|
+
const copy = state === "ready" ? {
|
|
20568
|
+
statusLabel: "READY",
|
|
20569
|
+
headline: "Everything important is connected.",
|
|
20570
|
+
summary: "Token Harness is already active through your configured integrations. This dashboard is for status and guidance; it is not a launcher.",
|
|
20571
|
+
nextStep: {
|
|
20572
|
+
command: null,
|
|
20573
|
+
title: "Use your coding agent normally",
|
|
20574
|
+
description: "Open Claude Code, Codex, or OpenCode exactly as you normally do. RTK and HarnessTrim run automatically where they are configured."
|
|
20575
|
+
}
|
|
20576
|
+
} : state === "limited" ? {
|
|
20577
|
+
statusLabel: "READY WITH LIMITATIONS",
|
|
20578
|
+
headline: "You can keep working.",
|
|
20579
|
+
summary: "An active integration uses a version newer than the tested range. Token Harness will keep working read-only and stay conservative about changes.",
|
|
20580
|
+
nextStep: {
|
|
20581
|
+
command: "token-harness verify",
|
|
20582
|
+
title: "Verify the active integrations",
|
|
20583
|
+
description: "Keep using your coding agents normally. Run this check when you want evidence that the configured interception still works."
|
|
20584
|
+
}
|
|
20585
|
+
} : state === "action-needed" ? {
|
|
20586
|
+
statusLabel: "ACTION NEEDED",
|
|
20587
|
+
headline: "One active integration needs attention.",
|
|
20588
|
+
summary: "Do not change providers yet. Review the live pipeline or configuration issue first; your other working integrations can remain untouched.",
|
|
20589
|
+
nextStep: {
|
|
20590
|
+
command: input.status.problemCount > 0 ? "token-harness status --verbose" : "token-harness doctor --verbose",
|
|
20591
|
+
title: "Review the specific problem",
|
|
20592
|
+
description: "The detailed command is only for the integration that needs attention. It is not part of the normal daily workflow."
|
|
20593
|
+
}
|
|
20485
20594
|
} : {
|
|
20486
|
-
|
|
20487
|
-
|
|
20595
|
+
statusLabel: "SETUP NEEDED",
|
|
20596
|
+
headline: "Finish the one-time setup.",
|
|
20597
|
+
summary: "A supported coding agent was not found with an active optimization provider yet.",
|
|
20598
|
+
nextStep: {
|
|
20599
|
+
command: "token-harness setup",
|
|
20600
|
+
title: "Continue guided setup",
|
|
20601
|
+
description: "Token Harness will detect what is available and propose only supported changes."
|
|
20602
|
+
}
|
|
20488
20603
|
};
|
|
20489
20604
|
return {
|
|
20490
20605
|
generatedAt: input.generatedAt,
|
|
20491
20606
|
state,
|
|
20492
|
-
|
|
20493
|
-
|
|
20494
|
-
|
|
20495
|
-
|
|
20496
|
-
|
|
20497
|
-
|
|
20498
|
-
state: harness.state,
|
|
20499
|
-
version: harness.version,
|
|
20500
|
-
providers: input.doctor.providers.filter((provider) => provider.configuredHarnesses.includes(harness.harnessId)).map((provider) => provider.providerId),
|
|
20501
|
-
allowance: (budget?.windows ?? []).map((window) => ({
|
|
20502
|
-
label: window.bucketName ?? window.scope,
|
|
20503
|
-
remainingPercent: window.remainingPercent,
|
|
20504
|
-
resetsAt: window.resetsAt,
|
|
20505
|
-
confidence: window.confidence
|
|
20506
|
-
}))
|
|
20507
|
-
};
|
|
20508
|
-
}),
|
|
20509
|
-
providers: input.doctor.providers.map((provider) => ({
|
|
20510
|
-
id: provider.providerId,
|
|
20511
|
-
state: provider.state,
|
|
20512
|
-
harnesses: provider.configuredHarnesses.map(nameOf)
|
|
20513
|
-
})),
|
|
20607
|
+
statusLabel: copy.statusLabel,
|
|
20608
|
+
headline: copy.headline,
|
|
20609
|
+
summary: copy.summary,
|
|
20610
|
+
harnesses,
|
|
20611
|
+
otherHarnesses,
|
|
20612
|
+
providers,
|
|
20514
20613
|
recommendation: recommendation === void 0 ? null : {
|
|
20515
20614
|
action: `${nameOf(recommendation.harness)}: ${recommendation.action}`,
|
|
20516
20615
|
reason: recommendation.reason
|
|
20517
20616
|
},
|
|
20518
|
-
nextStep
|
|
20617
|
+
nextStep: copy.nextStep
|
|
20519
20618
|
};
|
|
20520
20619
|
}
|
|
20521
20620
|
function uiAsset(path, model) {
|
|
@@ -20537,40 +20636,86 @@ var UI_USAGE, DASHBOARD_HTML, DASHBOARD_CSS, DASHBOARD_JS;
|
|
|
20537
20636
|
var init_ui = __esm({
|
|
20538
20637
|
"apps/cli/dist/src/ui.js"() {
|
|
20539
20638
|
"use strict";
|
|
20540
|
-
UI_USAGE = `token-harness ui \u2014 open
|
|
20639
|
+
UI_USAGE = `token-harness ui \u2014 open the local status and guidance dashboard
|
|
20541
20640
|
|
|
20542
20641
|
Usage
|
|
20543
20642
|
token-harness ui [--no-open] [--port <number>] [--json]
|
|
20544
20643
|
|
|
20545
|
-
The dashboard listens only on 127.0.0.1 and
|
|
20546
|
-
It does not send data anywhere and cannot change configuration.
|
|
20547
|
-
|
|
20644
|
+
The dashboard listens only on 127.0.0.1 and is read-only.
|
|
20645
|
+
It does not send data anywhere and cannot change configuration.
|
|
20646
|
+
It shows what is active, what needs attention, and what to do next. When the setup is ready,
|
|
20647
|
+
keep using Claude Code, Codex, or OpenCode normally \u2014 Token Harness does not replace their
|
|
20648
|
+
launch commands. Close the local dashboard server with Ctrl+C.`;
|
|
20548
20649
|
DASHBOARD_HTML = `<!doctype html>
|
|
20549
20650
|
<html lang="en">
|
|
20550
20651
|
<head>
|
|
20551
20652
|
<meta charset="utf-8">
|
|
20552
20653
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
20553
|
-
<meta name="color-scheme" content="dark">
|
|
20654
|
+
<meta name="color-scheme" content="light dark">
|
|
20554
20655
|
<title>Token Harness</title>
|
|
20555
20656
|
<link rel="stylesheet" href="/app.css">
|
|
20556
20657
|
</head>
|
|
20557
20658
|
<body>
|
|
20558
20659
|
<a class="skip" href="#main">Skip to dashboard</a>
|
|
20559
|
-
<header
|
|
20660
|
+
<header class="topbar">
|
|
20661
|
+
<div class="brand"><span class="mark" aria-hidden="true">TH</span><span>Token Harness</span></div>
|
|
20662
|
+
<button id="refresh" class="secondary-button" type="button">Refresh</button>
|
|
20663
|
+
</header>
|
|
20560
20664
|
<main id="main">
|
|
20561
|
-
<section class="hero" aria-labelledby="headline"
|
|
20562
|
-
|
|
20563
|
-
|
|
20564
|
-
|
|
20565
|
-
|
|
20665
|
+
<section class="hero" aria-labelledby="headline">
|
|
20666
|
+
<div id="status" class="status-chip">CHECKING</div>
|
|
20667
|
+
<h1 id="headline">Checking your setup...</h1>
|
|
20668
|
+
<p id="summary" class="hero-copy">Reading local status and guidance.</p>
|
|
20669
|
+
<p id="updated" class="timestamp" aria-live="polite"></p>
|
|
20670
|
+
</section>
|
|
20671
|
+
|
|
20672
|
+
<section class="action-card" aria-labelledby="next-title">
|
|
20673
|
+
<div class="action-copy">
|
|
20674
|
+
<p class="eyebrow">WHAT TO DO NOW</p>
|
|
20675
|
+
<h2 id="next-title">Checking the next step...</h2>
|
|
20676
|
+
<p id="description" class="supporting"></p>
|
|
20677
|
+
</div>
|
|
20678
|
+
<div id="command-row" class="command-row" hidden>
|
|
20679
|
+
<code id="command"></code>
|
|
20680
|
+
<button id="copy" class="primary-button" type="button">Copy command</button>
|
|
20681
|
+
</div>
|
|
20682
|
+
</section>
|
|
20683
|
+
|
|
20684
|
+
<section class="section" aria-labelledby="active-title">
|
|
20685
|
+
<div class="section-heading">
|
|
20686
|
+
<div><p class="eyebrow">ACTIVE SETUP</p><h2 id="active-title">What is working</h2></div>
|
|
20687
|
+
<p class="section-note">Only active or relevant tools are shown here.</p>
|
|
20688
|
+
</div>
|
|
20689
|
+
<div id="harnesses" class="harness-grid" aria-live="polite"></div>
|
|
20690
|
+
</section>
|
|
20691
|
+
|
|
20692
|
+
<section id="recommendation-panel" class="recommendation-card" aria-labelledby="recommendation-title" hidden>
|
|
20693
|
+
<p class="eyebrow">USEFUL NOW</p>
|
|
20694
|
+
<h2 id="recommendation-title">Recommendation</h2>
|
|
20695
|
+
<p id="recommendation" class="recommendation-action"></p>
|
|
20696
|
+
<p id="reason" class="supporting"></p>
|
|
20697
|
+
</section>
|
|
20698
|
+
|
|
20699
|
+
<section id="providers-panel" class="compact-panel" aria-labelledby="providers-title" hidden>
|
|
20700
|
+
<div><p class="eyebrow">ACTIVE OPTIMIZERS</p><h2 id="providers-title">Providers</h2></div>
|
|
20701
|
+
<ul id="providers" class="provider-list"></ul>
|
|
20702
|
+
</section>
|
|
20703
|
+
|
|
20704
|
+
<details id="other-panel" class="details-panel" hidden>
|
|
20705
|
+
<summary id="other-summary">Other detected tools</summary>
|
|
20706
|
+
<ul id="other-harnesses" class="secondary-list"></ul>
|
|
20707
|
+
</details>
|
|
20708
|
+
|
|
20566
20709
|
<p id="error" class="error" role="alert"></p>
|
|
20567
20710
|
</main>
|
|
20568
|
-
<footer>
|
|
20711
|
+
<footer>
|
|
20712
|
+
<strong>Local and read-only.</strong> You can close this page whenever you want. Configured optimizers keep working through their normal harness integrations.
|
|
20713
|
+
</footer>
|
|
20569
20714
|
<script src="/app.js" defer></script>
|
|
20570
20715
|
</body>
|
|
20571
20716
|
</html>`;
|
|
20572
|
-
DASHBOARD_CSS = `:root{font-family:Inter,ui-sans-serif,system-ui,-apple-system,sans-serif;
|
|
20573
|
-
DASHBOARD_JS = `const byId=(id)=>document.getElementById(id);const
|
|
20717
|
+
DASHBOARD_CSS = `:root{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;font-synthesis:none;--bg:#f6f8fb;--surface:#ffffff;--surface-2:#f1f5f9;--text:#111827;--muted:#5b6472;--subtle:#7b8492;--border:#dce2ea;--accent:#0f766e;--accent-strong:#115e59;--accent-soft:#ccfbf1;--warning:#92400e;--warning-soft:#fef3c7;--danger:#b42318;--danger-soft:#fee4e2;--shadow:0 14px 34px rgba(15,23,42,.08);--focus:#2563eb}*{box-sizing:border-box}html{background:var(--bg)}body{margin:0;min-height:100vh;background:linear-gradient(180deg,rgba(15,118,110,.045),transparent 240px),var(--bg);color:var(--text);font-size:16px;line-height:1.5}button{font:inherit}button:focus-visible,a:focus-visible,summary:focus-visible{outline:3px solid var(--focus);outline-offset:3px}.skip{position:absolute;left:-999px;top:1rem;z-index:10;background:var(--text);color:var(--surface);padding:.6rem .8rem;border-radius:8px}.skip:focus{left:1rem}.topbar,main,footer{width:min(1040px,calc(100% - 32px));margin-inline:auto}.topbar{height:68px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--border)}.brand{display:flex;align-items:center;gap:.7rem;font-weight:800;letter-spacing:-.01em}.mark{display:grid;place-items:center;width:36px;height:36px;border-radius:10px;background:var(--accent);color:#fff;font:800 13px ui-monospace,SFMono-Regular,Consolas,monospace}.secondary-button,.primary-button{min-height:44px;border-radius:10px;padding:0 1rem;font-weight:750;cursor:pointer}.secondary-button{border:1px solid var(--border);background:var(--surface);color:var(--text)}.secondary-button:hover{background:var(--surface-2)}.primary-button{border:1px solid var(--accent-strong);background:var(--accent);color:#fff}.primary-button:hover{background:var(--accent-strong)}button:disabled{cursor:wait;opacity:.62}.hero{padding:54px 0 28px;max-width:780px}.status-chip{display:inline-flex;align-items:center;min-height:28px;padding:0 .65rem;border-radius:999px;background:var(--accent-soft);color:var(--accent-strong);font-size:.76rem;font-weight:850;letter-spacing:.08em}.status-chip.limited{background:var(--warning-soft);color:var(--warning)}.status-chip.action-needed{background:var(--danger-soft);color:var(--danger)}.status-chip.setup-needed{background:var(--surface-2);color:var(--muted)}.hero h1{margin:14px 0 10px;font-size:clamp(2.05rem,5vw,3.65rem);line-height:1.04;letter-spacing:-.045em}.hero-copy{margin:0;max-width:720px;color:var(--muted);font-size:1.08rem}.timestamp{margin:12px 0 0;color:var(--subtle);font-size:.82rem}.action-card{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:24px;align-items:center;padding:24px;border:1px solid color-mix(in srgb,var(--accent) 28%,var(--border));border-radius:18px;background:var(--surface);box-shadow:var(--shadow)}.eyebrow{margin:0 0 6px;color:var(--accent-strong);font-size:.72rem;font-weight:850;letter-spacing:.11em}.action-card h2,.section h2,.recommendation-card h2,.compact-panel h2{margin:0;font-size:1.18rem;letter-spacing:-.015em}.supporting{margin:7px 0 0;color:var(--muted)}.command-row{display:flex;align-items:center;gap:10px;max-width:100%}.command-row code{display:block;max-width:440px;padding:12px 14px;border:1px solid var(--border);border-radius:10px;background:var(--surface-2);color:var(--text);font:650 .88rem ui-monospace,SFMono-Regular,Consolas,monospace;overflow-wrap:anywhere}.section{padding-top:34px}.section-heading{display:flex;align-items:end;justify-content:space-between;gap:24px;margin-bottom:14px}.section-note{margin:0;color:var(--subtle);font-size:.86rem}.harness-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr));gap:12px}.harness-card{min-width:0;padding:18px;border:1px solid var(--border);border-radius:16px;background:var(--surface)}.harness-top{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.harness-card h3{margin:0;font-size:1.06rem}.health{display:inline-flex;align-items:center;gap:7px;flex:0 0 auto;color:var(--accent-strong);font-size:.76rem;font-weight:800}.health::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--accent)}.health.limited{color:var(--warning)}.health.limited::before{background:var(--warning)}.health.attention{color:var(--danger)}.health.attention::before{background:var(--danger)}.harness-meta{margin:5px 0 0;color:var(--muted);font-size:.86rem}.provider-line{margin:13px 0 0;font-size:.9rem}.provider-line strong{font-weight:800}.allowance{margin-top:16px;padding-top:14px;border-top:1px solid var(--border)}.quota{margin-top:12px}.quota:first-child{margin-top:0}.quota-row{display:flex;justify-content:space-between;gap:16px;margin-bottom:6px;font-size:.88rem}.quota-row strong{font-variant-numeric:tabular-nums}.track{height:7px;border-radius:999px;background:var(--surface-2);overflow:hidden}.fill{height:100%;border-radius:inherit;background:var(--accent)}.quota-meta{margin:5px 0 0;color:var(--subtle);font-size:.76rem}.no-allowance{margin:14px 0 0;color:var(--subtle);font-size:.82rem}.recommendation-card,.compact-panel,.details-panel{margin-top:14px;border:1px solid var(--border);border-radius:16px;background:var(--surface)}.recommendation-card{padding:20px}.recommendation-action{margin:9px 0 0;font-weight:760}.compact-panel{display:flex;align-items:center;justify-content:space-between;gap:20px;padding:16px 18px}.provider-list,.secondary-list{margin:0;padding:0;list-style:none}.provider-list{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px}.provider-list li{padding:7px 9px;border:1px solid var(--border);border-radius:9px;background:var(--surface-2);font-size:.82rem}.details-panel{padding:0 16px}.details-panel summary{min-height:48px;display:flex;align-items:center;cursor:pointer;color:var(--muted);font-weight:750}.secondary-list{padding:0 0 14px}.secondary-list li{padding:7px 0;border-top:1px solid var(--border);color:var(--muted);font-size:.86rem}.error{color:var(--danger);font-weight:700}footer{padding:28px 0 42px;color:var(--subtle);font-size:.82rem}footer strong{color:var(--muted)}[hidden]{display:none!important}@media(prefers-color-scheme:dark){:root{--bg:#0b1118;--surface:#111923;--surface-2:#17212d;--text:#f3f6fa;--muted:#b2bdc9;--subtle:#8996a4;--border:#273443;--accent:#2dd4bf;--accent-strong:#99f6e4;--accent-soft:#123d39;--warning:#fbbf24;--warning-soft:#422f12;--danger:#ff8a80;--danger-soft:#44201f;--shadow:0 16px 38px rgba(0,0,0,.22);--focus:#60a5fa}.primary-button{color:#062a27}.mark{color:#062a27}.action-card{border-color:#28514d}}@media(max-width:760px){.topbar,main,footer{width:min(100% - 24px,1040px)}.hero{padding:38px 0 22px}.action-card{grid-template-columns:1fr;gap:16px;padding:19px}.command-row{align-items:stretch;flex-direction:column}.command-row code{max-width:none}.command-row .primary-button{width:100%}.section{padding-top:28px}.section-heading{align-items:flex-start;flex-direction:column;gap:3px}.compact-panel{align-items:flex-start;flex-direction:column}.provider-list{justify-content:flex-start}.topbar{height:62px}}@media(max-width:390px){.hero h1{font-size:2rem}.harness-card{padding:15px}.harness-top{align-items:flex-start;flex-direction:column;gap:6px}}@media(prefers-reduced-motion:reduce){*{scroll-behavior:auto!important;transition:none!important;animation:none!important}}`;
|
|
20718
|
+
DASHBOARD_JS = `const byId=(id)=>document.getElementById(id);const setText=(id,value)=>{const node=byId(id);if(node)node.textContent=value};function formatReset(value){return value?'Resets '+new Date(value).toLocaleString():'Reset time unavailable'}function renderHarness(item){const card=document.createElement('article');card.className='harness-card';const top=document.createElement('div');top.className='harness-top';const title=document.createElement('h3');title.textContent=item.name;const health=document.createElement('span');health.className='health '+item.health;health.textContent=item.statusLabel;top.append(title,health);card.append(top);const meta=document.createElement('p');meta.className='harness-meta';meta.textContent=item.version?'Version '+item.version:'Version unavailable';card.append(meta);if(item.providers.length){const provider=document.createElement('p');provider.className='provider-line';const strong=document.createElement('strong');strong.textContent=item.providers.join(', ');provider.append(strong,document.createTextNode(' active automatically'));card.append(provider)}if(item.allowance.length){const allowance=document.createElement('div');allowance.className='allowance';for(const quota of item.allowance){const box=document.createElement('div');box.className='quota';const row=document.createElement('div');row.className='quota-row';const label=document.createElement('span');label.textContent=quota.label;const value=document.createElement('strong');value.textContent=quota.remainingPercent===null?'Unknown':quota.remainingPercent+'% left';row.append(label,value);const track=document.createElement('div');track.className='track';track.setAttribute('role','progressbar');track.setAttribute('aria-label',item.name+' '+quota.label);track.setAttribute('aria-valuemin','0');track.setAttribute('aria-valuemax','100');if(quota.remainingPercent!==null){track.setAttribute('aria-valuenow',String(quota.remainingPercent));track.setAttribute('aria-valuetext',quota.remainingPercent+'% remaining')}const fill=document.createElement('div');fill.className='fill';fill.style.width=(quota.remainingPercent===null?0:Math.max(0,Math.min(100,quota.remainingPercent)))+'%';track.append(fill);const detail=document.createElement('p');detail.className='quota-meta';detail.textContent=formatReset(quota.resetsAt)+(quota.confidence==='authoritative'?' \xB7 verified allowance':' \xB7 '+quota.confidence);box.append(row,track,detail);allowance.append(box)}card.append(allowance)}else{const empty=document.createElement('p');empty.className='no-allowance';empty.textContent='Allowance data is not available for this harness.';card.append(empty)}return card}function render(model){document.body.dataset.state=model.state;const status=byId('status');status.textContent=model.statusLabel;status.className='status-chip '+model.state;setText('headline',model.headline);setText('summary',model.summary);setText('updated','Updated '+new Date(model.generatedAt).toLocaleString());setText('next-title',model.nextStep.title);setText('description',model.nextStep.description);const commandRow=byId('command-row');if(model.nextStep.command){setText('command',model.nextStep.command);commandRow.hidden=false}else{setText('command','');commandRow.hidden=true}const harnesses=byId('harnesses');harnesses.replaceChildren();if(model.harnesses.length===0){const empty=document.createElement('p');empty.className='supporting';empty.textContent='No active optimized harness is available yet.';harnesses.append(empty)}for(const item of model.harnesses)harnesses.append(renderHarness(item));const recommendationPanel=byId('recommendation-panel');if(model.recommendation){setText('recommendation',model.recommendation.action);setText('reason',model.recommendation.reason||'This recommendation is based on the currently observable local signals.');recommendationPanel.hidden=false}else{recommendationPanel.hidden=true}const providersPanel=byId('providers-panel');const providers=byId('providers');providers.replaceChildren();if(model.providers.length){for(const item of model.providers){const node=document.createElement('li');node.textContent=item.name+' \xB7 '+item.harnesses.join(', ');providers.append(node)}providersPanel.hidden=false}else{providersPanel.hidden=true}const otherPanel=byId('other-panel');const other=byId('other-harnesses');other.replaceChildren();if(model.otherHarnesses.length){setText('other-summary','Other detected tools ('+model.otherHarnesses.length+')');for(const item of model.otherHarnesses){const node=document.createElement('li');node.textContent=item.name+(item.version?' \xB7 '+item.version:'')+' \xB7 detected, not active in the optimized setup';other.append(node)}otherPanel.hidden=false}else{otherPanel.hidden=true}setText('error','')}async function load(){const refresh=byId('refresh');refresh.disabled=true;refresh.textContent='Refreshing\u2026';try{const response=await fetch('/api/status',{cache:'no-store'});if(!response.ok)throw new Error('Dashboard data is unavailable');render(await response.json())}catch(error){setText('error',error instanceof Error?error.message:String(error))}finally{refresh.disabled=false;refresh.textContent='Refresh'}}byId('refresh').addEventListener('click',load);byId('copy').addEventListener('click',async()=>{const command=byId('command').textContent||'';try{await navigator.clipboard.writeText(command);setText('updated','Command copied')}catch{setText('updated','Copy unavailable \u2014 select the command manually')}});load();setInterval(()=>{if(!document.hidden)load()},30000);`;
|
|
20574
20719
|
}
|
|
20575
20720
|
});
|
|
20576
20721
|
|
|
@@ -20761,7 +20906,7 @@ async function runUi(options, baseOptions) {
|
|
|
20761
20906
|
return EXIT_CODES["unsupported-environment"];
|
|
20762
20907
|
}
|
|
20763
20908
|
if (options.json) {
|
|
20764
|
-
const exitCode = initial.state === "
|
|
20909
|
+
const exitCode = initial.state === "action-needed" ? EXIT_CODES["problems-found"] : EXIT_CODES.ok;
|
|
20765
20910
|
process5.stdout.write(serializeEnvelope(toEnvelope(commandResult({ command: "ui", exitCode, data: initial }), TOOL_VERSION)));
|
|
20766
20911
|
return exitCode;
|
|
20767
20912
|
}
|