token-harness 0.1.0 → 0.1.1
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 +500 -236
- package/package.json +1 -1
- package/sbom.json +5 -5
- package/token-harness.mjs +595 -187
package/token-harness.mjs
CHANGED
|
@@ -155,6 +155,7 @@ function diagnostic(init) {
|
|
|
155
155
|
severity: init.severity,
|
|
156
156
|
code: init.code,
|
|
157
157
|
message: init.message,
|
|
158
|
+
subject: init.subject ?? null,
|
|
158
159
|
path: init.path ?? null,
|
|
159
160
|
remediation: init.remediation ?? null
|
|
160
161
|
};
|
|
@@ -263,6 +264,9 @@ function isStartableExecutable(resolved) {
|
|
|
263
264
|
// packages/core/dist/src/domain/process.js
|
|
264
265
|
var DEFAULT_MAX_OUTPUT_BYTES = 1024 * 1024;
|
|
265
266
|
var DEFAULT_PROCESS_TIMEOUT_MS = 3e4;
|
|
267
|
+
function processSucceeded(outcome2) {
|
|
268
|
+
return outcome2.failure === null && outcome2.exitCode === 0;
|
|
269
|
+
}
|
|
266
270
|
|
|
267
271
|
// packages/core/dist/src/domain/redaction.js
|
|
268
272
|
var REDACTED = "[redacted]";
|
|
@@ -882,12 +886,12 @@ function isUsableSalt(value) {
|
|
|
882
886
|
}
|
|
883
887
|
|
|
884
888
|
// packages/core/dist/src/metrics/local-database.js
|
|
885
|
-
function numberAt(
|
|
886
|
-
const value =
|
|
889
|
+
function numberAt(row2, column2) {
|
|
890
|
+
const value = row2[column2];
|
|
887
891
|
return typeof value === "number" ? value : null;
|
|
888
892
|
}
|
|
889
|
-
function stringAt(
|
|
890
|
-
const value =
|
|
893
|
+
function stringAt(row2, column2) {
|
|
894
|
+
const value = row2[column2];
|
|
891
895
|
return typeof value === "string" ? value : null;
|
|
892
896
|
}
|
|
893
897
|
|
|
@@ -988,7 +992,7 @@ function aggregateEvents(input) {
|
|
|
988
992
|
const managed = new Set(input.managedProviders ?? []);
|
|
989
993
|
const modes = input.adapterModes ?? {};
|
|
990
994
|
const classes = MEASUREMENT_CLASSES.map((measurementClass) => {
|
|
991
|
-
const rows = [...classTotals.values()].filter((
|
|
995
|
+
const rows = [...classTotals.values()].filter((row3) => row3.class === measurementClass);
|
|
992
996
|
if (rows.length > 1) {
|
|
993
997
|
return {
|
|
994
998
|
class: measurementClass,
|
|
@@ -996,11 +1000,11 @@ function aggregateEvents(input) {
|
|
|
996
1000
|
before: null,
|
|
997
1001
|
after: null,
|
|
998
1002
|
saved: null,
|
|
999
|
-
note: `recorded in ${rows.map((
|
|
1003
|
+
note: `recorded in ${rows.map((row3) => row3.unit).join(" and ")}, which are not addable`
|
|
1000
1004
|
};
|
|
1001
1005
|
}
|
|
1002
|
-
const
|
|
1003
|
-
if (
|
|
1006
|
+
const row2 = rows[0];
|
|
1007
|
+
if (row2 === void 0) {
|
|
1004
1008
|
return {
|
|
1005
1009
|
class: measurementClass,
|
|
1006
1010
|
unit: null,
|
|
@@ -1012,22 +1016,22 @@ function aggregateEvents(input) {
|
|
|
1012
1016
|
}
|
|
1013
1017
|
return {
|
|
1014
1018
|
class: measurementClass,
|
|
1015
|
-
unit:
|
|
1016
|
-
before:
|
|
1017
|
-
after:
|
|
1018
|
-
saved:
|
|
1019
|
+
unit: row2.unit,
|
|
1020
|
+
before: row2.before,
|
|
1021
|
+
after: row2.after,
|
|
1022
|
+
saved: row2.before - row2.after,
|
|
1019
1023
|
note: null
|
|
1020
1024
|
};
|
|
1021
1025
|
});
|
|
1022
|
-
const providers = [...providerTotals.values()].sort((left, right) => right.saved - left.saved || left.providerId.localeCompare(right.providerId)).map((
|
|
1023
|
-
providerId:
|
|
1024
|
-
saved:
|
|
1025
|
-
unit:
|
|
1026
|
-
class:
|
|
1027
|
-
operations:
|
|
1028
|
-
harnesses: [...
|
|
1029
|
-
managedByTokenHarness: managed.has(
|
|
1030
|
-
adapterMode: modes[
|
|
1026
|
+
const providers = [...providerTotals.values()].sort((left, right) => right.saved - left.saved || left.providerId.localeCompare(right.providerId)).map((row2) => ({
|
|
1027
|
+
providerId: row2.providerId,
|
|
1028
|
+
saved: row2.saved,
|
|
1029
|
+
unit: row2.unit,
|
|
1030
|
+
class: row2.class,
|
|
1031
|
+
operations: row2.operations,
|
|
1032
|
+
harnesses: [...row2.harnesses].sort(),
|
|
1033
|
+
managedByTokenHarness: managed.has(row2.providerId),
|
|
1034
|
+
adapterMode: modes[row2.providerId] ?? null
|
|
1031
1035
|
}));
|
|
1032
1036
|
const operations = realized + bypassed;
|
|
1033
1037
|
return {
|
|
@@ -2037,6 +2041,139 @@ async function applyRemoveOwnedChange(action, context) {
|
|
|
2037
2041
|
await fs.writeFile(action.target.path, UTF8.encode(removal.text), null);
|
|
2038
2042
|
return outcome(action, "applied", { snapshots: [snapshot] });
|
|
2039
2043
|
}
|
|
2044
|
+
async function scanTree(fs, path, entries = []) {
|
|
2045
|
+
const stat3 = await fs.stat(path);
|
|
2046
|
+
if (stat3 === null)
|
|
2047
|
+
return entries;
|
|
2048
|
+
const digest = stat3.kind === "file" ? digestBytes(await fs.readFile(path)) : null;
|
|
2049
|
+
entries.push({ path, kind: stat3.kind, digest, byteLength: stat3.byteLength });
|
|
2050
|
+
if (stat3.kind === "directory") {
|
|
2051
|
+
for (const child of await fs.readDirectory(path)) {
|
|
2052
|
+
await scanTree(fs, fs.join(path, child), entries);
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
return entries;
|
|
2056
|
+
}
|
|
2057
|
+
function equalTreeEntry(left, right) {
|
|
2058
|
+
return left !== void 0 && right !== void 0 && left.kind === right.kind && left.digest === right.digest;
|
|
2059
|
+
}
|
|
2060
|
+
async function applyDelegatedProviderInstall(action, context) {
|
|
2061
|
+
if (context.runner === null || context.runner === void 0 || context.cwd === void 0) {
|
|
2062
|
+
return refusal(action, "process-runner-unavailable", action.executable, "A delegated provider install requires a process runner and working directory", "Run this command through the Token Harness CLI");
|
|
2063
|
+
}
|
|
2064
|
+
const before = /* @__PURE__ */ new Map();
|
|
2065
|
+
for (const boundary of action.containmentBoundary) {
|
|
2066
|
+
for (const entry of await scanTree(context.fs, boundary))
|
|
2067
|
+
before.set(entry.path, entry);
|
|
2068
|
+
}
|
|
2069
|
+
if (action.expectedArtifacts.every((artifact) => before.get(artifact.path)?.kind === "file" && before.get(artifact.path)?.digest === artifact.digest)) {
|
|
2070
|
+
return outcome(action, "already-satisfied");
|
|
2071
|
+
}
|
|
2072
|
+
const bytes = [...before.values()].reduce((total, entry) => total + entry.byteLength, 0);
|
|
2073
|
+
if (bytes > action.snapshotSizeCapBytes) {
|
|
2074
|
+
return refusal(action, "delegated-install-snapshot-too-large", action.containmentBoundary[0] ?? action.executable, `The delegated install boundary is ${String(bytes)} bytes, above its ${String(action.snapshotSizeCapBytes)} byte snapshot cap`, "Narrow the provider containment boundary before applying this plan");
|
|
2075
|
+
}
|
|
2076
|
+
const snapshots = [];
|
|
2077
|
+
const capturedPaths = /* @__PURE__ */ new Set();
|
|
2078
|
+
for (const boundary of action.containmentBoundary) {
|
|
2079
|
+
const entries = await scanTree(context.fs, boundary);
|
|
2080
|
+
if (entries.length === 0) {
|
|
2081
|
+
snapshots.push(await context.snapshots.capture(boundary));
|
|
2082
|
+
capturedPaths.add(boundary);
|
|
2083
|
+
continue;
|
|
2084
|
+
}
|
|
2085
|
+
for (const entry of entries) {
|
|
2086
|
+
snapshots.push(await context.snapshots.capture(entry.path));
|
|
2087
|
+
capturedPaths.add(entry.path);
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
const result = await context.runner.run({
|
|
2091
|
+
executable: action.executable,
|
|
2092
|
+
args: action.args,
|
|
2093
|
+
cwd: context.cwd,
|
|
2094
|
+
timeoutMs: 3e4
|
|
2095
|
+
});
|
|
2096
|
+
if (!processSucceeded(result)) {
|
|
2097
|
+
return outcome(action, "failed", {
|
|
2098
|
+
snapshots,
|
|
2099
|
+
diagnostics: [
|
|
2100
|
+
diagnostic({
|
|
2101
|
+
severity: "error",
|
|
2102
|
+
code: "delegated-install-failed",
|
|
2103
|
+
message: `${action.executable} did not complete its delegated install successfully`,
|
|
2104
|
+
remediation: "Review the provider output and rerun the plan after correcting the problem"
|
|
2105
|
+
})
|
|
2106
|
+
]
|
|
2107
|
+
});
|
|
2108
|
+
}
|
|
2109
|
+
const after = /* @__PURE__ */ new Map();
|
|
2110
|
+
for (const boundary of action.containmentBoundary) {
|
|
2111
|
+
for (const entry of await scanTree(context.fs, boundary))
|
|
2112
|
+
after.set(entry.path, entry);
|
|
2113
|
+
}
|
|
2114
|
+
for (const entry of after.values()) {
|
|
2115
|
+
if (!before.has(entry.path) && !capturedPaths.has(entry.path)) {
|
|
2116
|
+
snapshots.push(context.snapshots.captureAbsent(entry.path));
|
|
2117
|
+
capturedPaths.add(entry.path);
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
const protectedPath = action.protectedPaths.find((path) => !equalTreeEntry(before.get(path), after.get(path)));
|
|
2121
|
+
if (protectedPath !== void 0) {
|
|
2122
|
+
return outcome(action, "failed", {
|
|
2123
|
+
snapshots,
|
|
2124
|
+
diagnostics: [
|
|
2125
|
+
diagnostic({
|
|
2126
|
+
severity: "error",
|
|
2127
|
+
code: "delegated-install-protected-path-changed",
|
|
2128
|
+
message: `The delegated installer changed the protected path ${protectedPath}`,
|
|
2129
|
+
path: protectedPath,
|
|
2130
|
+
remediation: "Do not apply this provider until its reviewed write set is updated"
|
|
2131
|
+
})
|
|
2132
|
+
]
|
|
2133
|
+
});
|
|
2134
|
+
}
|
|
2135
|
+
const changed = /* @__PURE__ */ new Set([...before.keys(), ...after.keys()]);
|
|
2136
|
+
const undeclared = [...changed].map((path) => after.get(path) ?? before.get(path)).find((entry) => entry !== void 0 && !equalTreeEntry(before.get(entry.path), after.get(entry.path)) && !action.expectedArtifacts.some((artifact) => artifact.path === entry.path || entry.kind === "directory" && context.fs.isInside(artifact.path, entry.path)));
|
|
2137
|
+
if (undeclared !== void 0) {
|
|
2138
|
+
return outcome(action, "failed", {
|
|
2139
|
+
snapshots,
|
|
2140
|
+
diagnostics: [
|
|
2141
|
+
diagnostic({
|
|
2142
|
+
severity: "error",
|
|
2143
|
+
code: "delegated-install-undeclared-write",
|
|
2144
|
+
message: `The delegated installer changed an undeclared path inside its containment boundary: ${undeclared.path}`,
|
|
2145
|
+
path: undeclared.path,
|
|
2146
|
+
remediation: "Do not apply this provider until its reviewed write set is updated"
|
|
2147
|
+
})
|
|
2148
|
+
]
|
|
2149
|
+
});
|
|
2150
|
+
}
|
|
2151
|
+
const missing = action.expectedArtifacts.find((artifact) => after.get(artifact.path)?.kind !== "file" || after.get(artifact.path)?.digest !== artifact.digest);
|
|
2152
|
+
if (missing !== void 0) {
|
|
2153
|
+
return outcome(action, "failed", {
|
|
2154
|
+
snapshots,
|
|
2155
|
+
diagnostics: [
|
|
2156
|
+
diagnostic({
|
|
2157
|
+
severity: "error",
|
|
2158
|
+
code: "delegated-install-artifact-mismatch",
|
|
2159
|
+
message: `The delegated installer did not produce the reviewed artifact ${missing.path}`,
|
|
2160
|
+
path: missing.path,
|
|
2161
|
+
remediation: "Do not apply this provider until its reviewed artifact digests are updated"
|
|
2162
|
+
})
|
|
2163
|
+
]
|
|
2164
|
+
});
|
|
2165
|
+
}
|
|
2166
|
+
const ownership = [];
|
|
2167
|
+
for (const artifact of action.expectedArtifacts) {
|
|
2168
|
+
ownership.push({
|
|
2169
|
+
kind: "owned-file",
|
|
2170
|
+
path: artifact.path,
|
|
2171
|
+
digest: artifact.digest,
|
|
2172
|
+
mode: (await context.fs.stat(artifact.path))?.mode ?? null
|
|
2173
|
+
});
|
|
2174
|
+
}
|
|
2175
|
+
return outcome(action, "applied", { snapshots, ownership });
|
|
2176
|
+
}
|
|
2040
2177
|
function notImplemented(action) {
|
|
2041
2178
|
return outcome(action, "failed", {
|
|
2042
2179
|
diagnostics: [
|
|
@@ -2063,9 +2200,10 @@ async function applyAction(action, context) {
|
|
|
2063
2200
|
return applyMergeJson(action, context);
|
|
2064
2201
|
case "package-manager-install":
|
|
2065
2202
|
return applyPackageManagerInstall(action, context);
|
|
2203
|
+
case "delegated-provider-install":
|
|
2204
|
+
return applyDelegatedProviderInstall(action, context);
|
|
2066
2205
|
case "download-artifact":
|
|
2067
2206
|
case "run-installer-command":
|
|
2068
|
-
case "delegated-provider-install":
|
|
2069
2207
|
case "merge-toml":
|
|
2070
2208
|
case "merge-yaml":
|
|
2071
2209
|
case "register-mcp-server":
|
|
@@ -2559,23 +2697,25 @@ var TransactionSnapshotStore = class _TransactionSnapshotStore {
|
|
|
2559
2697
|
this.taken.push(snapshot);
|
|
2560
2698
|
return snapshot;
|
|
2561
2699
|
}
|
|
2700
|
+
captureAbsent(path) {
|
|
2701
|
+
return this.remember({
|
|
2702
|
+
schemaVersion: 1,
|
|
2703
|
+
path,
|
|
2704
|
+
existed: false,
|
|
2705
|
+
wasDirectory: false,
|
|
2706
|
+
digest: null,
|
|
2707
|
+
mode: null,
|
|
2708
|
+
byteLength: null,
|
|
2709
|
+
contentRef: null,
|
|
2710
|
+
capturedAt: this.input.now()
|
|
2711
|
+
});
|
|
2712
|
+
}
|
|
2562
2713
|
async capture(path) {
|
|
2563
2714
|
const { fs } = this.input;
|
|
2564
2715
|
const stat3 = await fs.stat(path);
|
|
2565
2716
|
const capturedAt = this.input.now();
|
|
2566
|
-
if (stat3 === null)
|
|
2567
|
-
return this.
|
|
2568
|
-
schemaVersion: 1,
|
|
2569
|
-
path,
|
|
2570
|
-
existed: false,
|
|
2571
|
-
wasDirectory: false,
|
|
2572
|
-
digest: null,
|
|
2573
|
-
mode: null,
|
|
2574
|
-
byteLength: null,
|
|
2575
|
-
contentRef: null,
|
|
2576
|
-
capturedAt
|
|
2577
|
-
});
|
|
2578
|
-
}
|
|
2717
|
+
if (stat3 === null)
|
|
2718
|
+
return this.captureAbsent(path);
|
|
2579
2719
|
if (stat3.kind === "directory") {
|
|
2580
2720
|
return this.remember({
|
|
2581
2721
|
schemaVersion: 1,
|
|
@@ -3168,9 +3308,9 @@ async function readLocalDatabase(request) {
|
|
|
3168
3308
|
database = new construct(request.path, { readOnly: true });
|
|
3169
3309
|
const statement = database.prepare(request.sql);
|
|
3170
3310
|
const raw = statement.all(...request.parameters);
|
|
3171
|
-
const rows = raw.map((
|
|
3311
|
+
const rows = raw.map((row2) => {
|
|
3172
3312
|
const mapped = {};
|
|
3173
|
-
for (const [column2, value] of Object.entries(
|
|
3313
|
+
for (const [column2, value] of Object.entries(row2))
|
|
3174
3314
|
mapped[column2] = toValue(value);
|
|
3175
3315
|
return mapped;
|
|
3176
3316
|
});
|
|
@@ -4447,9 +4587,20 @@ async function inspect(context) {
|
|
|
4447
4587
|
diagnostics.push(diagnostic({
|
|
4448
4588
|
severity: "warning",
|
|
4449
4589
|
code: "tool-family-not-covered",
|
|
4450
|
-
|
|
4590
|
+
subject: CLAUDE,
|
|
4591
|
+
/**
|
|
4592
|
+
* Says whose gap it is, and that the tool is working.
|
|
4593
|
+
*
|
|
4594
|
+
* The first wording — "No configured matcher covers the PowerShell tool family" — read like a
|
|
4595
|
+
* defect in Token Harness on a first run. It is not: the hook in the file below matches some
|
|
4596
|
+
* tool families and not others, Claude Code routes shell commands through more than one on
|
|
4597
|
+
* Windows, and the commands going through the uncovered ones never reach the provider at all.
|
|
4598
|
+
*/
|
|
4599
|
+
// Short enough to survive the one-line human rendering without being cut.
|
|
4600
|
+
message: `${uncoveredToolFamilies.join(", ")} has no hook, so those commands are not optimized`,
|
|
4451
4601
|
path: configs.find((config) => config.configuredPoints.length > 0)?.path ?? null,
|
|
4452
|
-
|
|
4602
|
+
// Short on purpose: a remediation nobody finishes reading is not one.
|
|
4603
|
+
remediation: "Optional. Widen the matcher, or accept the gap"
|
|
4453
4604
|
}));
|
|
4454
4605
|
}
|
|
4455
4606
|
return {
|
|
@@ -4743,6 +4894,7 @@ async function inspect2(context) {
|
|
|
4743
4894
|
diagnostic({
|
|
4744
4895
|
severity: "info",
|
|
4745
4896
|
code: "hook-enablement-unobservable",
|
|
4897
|
+
subject: CODEX,
|
|
4746
4898
|
message: "Codex declares this hook, but its persisted enablement and trust state cannot be read outside the TUI",
|
|
4747
4899
|
path: hook.path,
|
|
4748
4900
|
remediation: "Open Codex and confirm the hook is enabled and trusted after any hook edit"
|
|
@@ -5072,6 +5224,15 @@ function listHarnessAdapters() {
|
|
|
5072
5224
|
var HARNESSTRIM2 = providerId("harnesstrim");
|
|
5073
5225
|
var CLAUDE2 = harnessId("claude");
|
|
5074
5226
|
var CODEX2 = harnessId("codex");
|
|
5227
|
+
var CLAUDE_ARTIFACT_DIGESTS = {
|
|
5228
|
+
"compact-handoff/SKILL.md": "sha256:0efbf35581c559359e755b204778b64a289dab4d20dadc1cba3d5b5c995b5f01",
|
|
5229
|
+
"debug-log-slim/SKILL.md": "sha256:17f5ccc34d29d7aba083444e0e4d87fd3d49916ebcb4e6544caf8c89f13f0045",
|
|
5230
|
+
"delegate-bulk/SKILL.md": "sha256:3753de2ad18271c24832e4cda63115d353620515d5d80f40e93bc07d2a7257d7",
|
|
5231
|
+
"delta-response/SKILL.md": "sha256:b6a71f4bdcfcadde3b5242994baa017d0371fe11652dd763f55a2f6d3840cfa8",
|
|
5232
|
+
"delta-response/references/examples.md": "sha256:c67a1f57e63550b396043c3072b7e1a3a0c1522376471f53d6829253339e64e7",
|
|
5233
|
+
"review-delta/SKILL.md": "sha256:4dfbf9d6ec08dff27b4759726536b43928370e288706fa01f5b498648e741388",
|
|
5234
|
+
"scaffold-fast/SKILL.md": "sha256:1a18d52c4d335fbd3f74e2559bc20d6346193a40eef7b85149f51f44f697d182"
|
|
5235
|
+
};
|
|
5075
5236
|
var OPENCODE2 = harnessId("opencode");
|
|
5076
5237
|
var HOOK_COMMAND_PATTERN = /(^|[\\/\s"'])harnesstrim(\.cmd|\.exe)?([\s"']|$)/i;
|
|
5077
5238
|
var MANIFEST4 = {
|
|
@@ -5157,10 +5318,17 @@ var MANIFEST4 = {
|
|
|
5157
5318
|
mode: "legacy",
|
|
5158
5319
|
locations: [".harnesstrim/metrics.jsonl", "~/.hermes/harnesstrim-metrics.jsonl"]
|
|
5159
5320
|
},
|
|
5160
|
-
delegatedInstallReview:
|
|
5321
|
+
delegatedInstallReview: {
|
|
5322
|
+
upstreamVersion: "0.0.7",
|
|
5323
|
+
reviewedWriteSet: [
|
|
5324
|
+
...Object.keys(CLAUDE_ARTIFACT_DIGESTS).map((path) => `.claude/skills/${path}`)
|
|
5325
|
+
],
|
|
5326
|
+
containmentBoundary: [".claude", "CLAUDE.md"],
|
|
5327
|
+
upstreamUninstallAvailable: true
|
|
5328
|
+
}
|
|
5161
5329
|
};
|
|
5162
|
-
var TESTED_UPSTREAM = "0.0.
|
|
5163
|
-
var TESTED_VERSIONS = { minimum:
|
|
5330
|
+
var TESTED_UPSTREAM = "0.0.7";
|
|
5331
|
+
var TESTED_VERSIONS = { minimum: "0.0.5", maximum: TESTED_UPSTREAM };
|
|
5164
5332
|
function identifiesCommand(command) {
|
|
5165
5333
|
return HOOK_COMMAND_PATTERN.test(command);
|
|
5166
5334
|
}
|
|
@@ -5412,7 +5580,7 @@ async function verify4(context) {
|
|
|
5412
5580
|
checks.push({
|
|
5413
5581
|
id: "canary-intercepted",
|
|
5414
5582
|
status: receipt === null ? "not-exercised" : "pass",
|
|
5415
|
-
summary: receipt === null ? "no telemetry file
|
|
5583
|
+
summary: receipt === null ? "no telemetry file yet, so nothing has been observed" : `${String(receipt.operations)} reductions recorded, most recently ${receipt.observedAt}`,
|
|
5416
5584
|
// A recorded reduction is the provider witnessing its own interception, which is what `canary`
|
|
5417
5585
|
// means in RFC 0007's tier table.
|
|
5418
5586
|
achievedTier: receipt === null ? null : "canary",
|
|
@@ -5571,9 +5739,73 @@ async function collectMetrics(context, store) {
|
|
|
5571
5739
|
diagnostics
|
|
5572
5740
|
};
|
|
5573
5741
|
}
|
|
5574
|
-
async function plan(
|
|
5575
|
-
|
|
5576
|
-
|
|
5742
|
+
async function plan(context, request) {
|
|
5743
|
+
const claudeDirectory = context.fs.join(context.projectRoot, ".claude");
|
|
5744
|
+
const skillsDirectory = context.fs.join(claudeDirectory, "skills");
|
|
5745
|
+
const expectedArtifacts = Object.entries(CLAUDE_ARTIFACT_DIGESTS).map(([path, digest]) => ({
|
|
5746
|
+
path: context.fs.join(skillsDirectory, ...path.split("/")),
|
|
5747
|
+
digest
|
|
5748
|
+
}));
|
|
5749
|
+
if (!request.harnesses.some((harness) => harness.id === CLAUDE2)) {
|
|
5750
|
+
return { providerId: HARNESSTRIM2, desiredState: request.desiredState, actions: [] };
|
|
5751
|
+
}
|
|
5752
|
+
if (request.desiredState === "absent") {
|
|
5753
|
+
const actions = expectedArtifacts.map((artifact) => ({
|
|
5754
|
+
kind: "remove-owned-change",
|
|
5755
|
+
id: `harnesstrim-claude-skill-remove-${digestText(artifact.path).slice(7, 15)}`,
|
|
5756
|
+
riskClass: "reversible",
|
|
5757
|
+
requiresNetwork: false,
|
|
5758
|
+
requiresElevation: false,
|
|
5759
|
+
affectedPaths: [artifact.path],
|
|
5760
|
+
affectedProcesses: [],
|
|
5761
|
+
preconditions: ["the HarnessTrim skill still matches the reviewed 0.0.7 artifact"],
|
|
5762
|
+
postconditions: ["the owned HarnessTrim skill is absent"],
|
|
5763
|
+
rollbackData: "file-snapshot",
|
|
5764
|
+
explanation: `Remove the owned HarnessTrim Claude skill ${context.fs.basename(context.fs.dirname(artifact.path))}`,
|
|
5765
|
+
path: artifact.path,
|
|
5766
|
+
reverses: `harnesstrim-claude-skills-${digestText(context.projectRoot).slice(7, 15)}`,
|
|
5767
|
+
target: { kind: "owned-file", path: artifact.path, digest: artifact.digest, mode: null }
|
|
5768
|
+
}));
|
|
5769
|
+
return { providerId: HARNESSTRIM2, desiredState: "absent", actions };
|
|
5770
|
+
}
|
|
5771
|
+
const installed = await probeExecutable(context);
|
|
5772
|
+
if (installed.version !== TESTED_UPSTREAM) {
|
|
5773
|
+
return { providerId: HARNESSTRIM2, desiredState: "configured", actions: [] };
|
|
5774
|
+
}
|
|
5775
|
+
const review = MANIFEST4.delegatedInstallReview;
|
|
5776
|
+
if (review === null)
|
|
5777
|
+
throw new Error("HarnessTrim delegated-install review is missing");
|
|
5778
|
+
const action = {
|
|
5779
|
+
kind: "delegated-provider-install",
|
|
5780
|
+
id: `harnesstrim-claude-skills-${digestText(context.projectRoot).slice(7, 15)}`,
|
|
5781
|
+
riskClass: "delegated",
|
|
5782
|
+
requiresNetwork: false,
|
|
5783
|
+
requiresElevation: false,
|
|
5784
|
+
affectedPaths: expectedArtifacts.map((artifact) => artifact.path),
|
|
5785
|
+
affectedProcesses: ["harnesstrim"],
|
|
5786
|
+
preconditions: [
|
|
5787
|
+
"harnesstrim 0.0.7 is installed and on PATH",
|
|
5788
|
+
"the reviewed installer writes only the declared Claude skill artifacts"
|
|
5789
|
+
],
|
|
5790
|
+
postconditions: [
|
|
5791
|
+
"HarnessTrim Claude skills match the reviewed 0.0.7 artifacts",
|
|
5792
|
+
"no HarnessTrim hook or reduce-pipe instruction was added"
|
|
5793
|
+
],
|
|
5794
|
+
rollbackData: "directory-snapshot",
|
|
5795
|
+
explanation: "Install HarnessTrim Claude skills without a hook or reduce-pipe instruction",
|
|
5796
|
+
executable: "harnesstrim",
|
|
5797
|
+
args: ["install", "claude", context.projectRoot, "--apply", "--no-hook", "--no-instructions"],
|
|
5798
|
+
containmentBoundary: review.containmentBoundary.map((path) => context.fs.join(context.projectRoot, path)),
|
|
5799
|
+
expectedArtifacts,
|
|
5800
|
+
protectedPaths: [
|
|
5801
|
+
context.fs.join(claudeDirectory, "settings.json"),
|
|
5802
|
+
context.fs.join(context.projectRoot, "CLAUDE.md")
|
|
5803
|
+
],
|
|
5804
|
+
rollbackStrategy: "restore-snapshot",
|
|
5805
|
+
snapshotSizeCapBytes: 1048576,
|
|
5806
|
+
upstreamUninstallAvailable: review.upstreamUninstallAvailable
|
|
5807
|
+
};
|
|
5808
|
+
return { providerId: HARNESSTRIM2, desiredState: "configured", actions: [action] };
|
|
5577
5809
|
}
|
|
5578
5810
|
var harnesstrimAdapter = {
|
|
5579
5811
|
manifest: MANIFEST4,
|
|
@@ -5581,7 +5813,8 @@ var harnesstrimAdapter = {
|
|
|
5581
5813
|
identifiesCommand,
|
|
5582
5814
|
verify: verify4,
|
|
5583
5815
|
collectMetrics,
|
|
5584
|
-
plan
|
|
5816
|
+
plan,
|
|
5817
|
+
plansWithoutOwnership: true
|
|
5585
5818
|
};
|
|
5586
5819
|
|
|
5587
5820
|
// packages/adapters/dist/src/providers/rtk-plan.js
|
|
@@ -6138,17 +6371,17 @@ function rtkDatabasePath(context) {
|
|
|
6138
6371
|
function cursorGeneration(low) {
|
|
6139
6372
|
return `rtk-history:low=${String(low ?? 0)}`;
|
|
6140
6373
|
}
|
|
6141
|
-
function toEvent2(
|
|
6142
|
-
const id = numberAt(
|
|
6143
|
-
const timestamp = stringAt(
|
|
6144
|
-
const before = numberAt(
|
|
6145
|
-
const after = numberAt(
|
|
6374
|
+
function toEvent2(row2, context) {
|
|
6375
|
+
const id = numberAt(row2, "id");
|
|
6376
|
+
const timestamp = stringAt(row2, "timestamp");
|
|
6377
|
+
const before = numberAt(row2, "input_tokens");
|
|
6378
|
+
const after = numberAt(row2, "output_tokens");
|
|
6146
6379
|
if (id === null || timestamp === null || before === null || after === null)
|
|
6147
6380
|
return null;
|
|
6148
6381
|
const instant = new Date(timestamp);
|
|
6149
6382
|
if (Number.isNaN(instant.getTime()))
|
|
6150
6383
|
return null;
|
|
6151
|
-
const projectPath = stringAt(
|
|
6384
|
+
const projectPath = stringAt(row2, "project_path");
|
|
6152
6385
|
return {
|
|
6153
6386
|
schemaVersion: OPTIMIZATION_EVENT_SCHEMA_VERSION,
|
|
6154
6387
|
// Native, not synthesized: RFC 0005 prefers the upstream identifier when there is one,
|
|
@@ -6292,11 +6525,11 @@ async function collectMetrics2(context, store) {
|
|
|
6292
6525
|
const events = [];
|
|
6293
6526
|
let skipped = 0;
|
|
6294
6527
|
let highest = from;
|
|
6295
|
-
for (const
|
|
6296
|
-
const id = numberAt(
|
|
6528
|
+
for (const row2 of batch.rows) {
|
|
6529
|
+
const id = numberAt(row2, "id");
|
|
6297
6530
|
if (id !== null && id > highest)
|
|
6298
6531
|
highest = id;
|
|
6299
|
-
const event = toEvent2(
|
|
6532
|
+
const event = toEvent2(row2, context);
|
|
6300
6533
|
if (event === null) {
|
|
6301
6534
|
skipped += 1;
|
|
6302
6535
|
continue;
|
|
@@ -6435,7 +6668,7 @@ async function computePlan(context) {
|
|
|
6435
6668
|
if (providerContext !== null) {
|
|
6436
6669
|
for (const adapter of providerAdapters) {
|
|
6437
6670
|
const owned = resolution.ownership.filter((entry) => entry.owner === adapter.manifest.id);
|
|
6438
|
-
if (owned.length === 0)
|
|
6671
|
+
if (owned.length === 0 && adapter.plansWithoutOwnership !== true)
|
|
6439
6672
|
continue;
|
|
6440
6673
|
const providerPlan = await adapter.plan(providerContext, {
|
|
6441
6674
|
ownership: owned,
|
|
@@ -7288,7 +7521,7 @@ async function runUpdate(context) {
|
|
|
7288
7521
|
for (const adapter of providerAdapters) {
|
|
7289
7522
|
const detection = await adapter.detect(providerContext);
|
|
7290
7523
|
const channel = preferredInstallationChannel(adapter.manifest.installationChannels, context.platform.os);
|
|
7291
|
-
const
|
|
7524
|
+
const row2 = {
|
|
7292
7525
|
providerId: adapter.manifest.id,
|
|
7293
7526
|
installed: detection.version,
|
|
7294
7527
|
available: null,
|
|
@@ -7297,24 +7530,24 @@ async function runUpdate(context) {
|
|
|
7297
7530
|
pin: pins.pins.get(adapter.manifest.id) ?? null
|
|
7298
7531
|
};
|
|
7299
7532
|
if (detection.state === "absent") {
|
|
7300
|
-
|
|
7301
|
-
report.providers.push(
|
|
7533
|
+
row2.verdict = "not-installed";
|
|
7534
|
+
report.providers.push(row2);
|
|
7302
7535
|
continue;
|
|
7303
7536
|
}
|
|
7304
|
-
if (
|
|
7305
|
-
|
|
7306
|
-
report.providers.push(
|
|
7537
|
+
if (row2.pin !== null) {
|
|
7538
|
+
row2.verdict = "pinned";
|
|
7539
|
+
report.providers.push(row2);
|
|
7307
7540
|
diagnostics.push(diagnostic({
|
|
7308
7541
|
severity: "info",
|
|
7309
7542
|
code: "provider-pinned",
|
|
7310
|
-
message: `${adapter.manifest.id} is pinned at ${
|
|
7543
|
+
message: `${adapter.manifest.id} is pinned at ${row2.pin}, so no update was planned for it`,
|
|
7311
7544
|
remediation: `Remove it from the pin file to allow updates`
|
|
7312
7545
|
}));
|
|
7313
7546
|
continue;
|
|
7314
7547
|
}
|
|
7315
7548
|
if (channel === null) {
|
|
7316
|
-
|
|
7317
|
-
report.providers.push(
|
|
7549
|
+
row2.verdict = "no-channel";
|
|
7550
|
+
report.providers.push(row2);
|
|
7318
7551
|
continue;
|
|
7319
7552
|
}
|
|
7320
7553
|
const packageName = channel.packageId ?? adapter.manifest.id;
|
|
@@ -7327,21 +7560,21 @@ async function runUpdate(context) {
|
|
|
7327
7560
|
diagnostics.push(...query.diagnostics);
|
|
7328
7561
|
if (query.destination !== null)
|
|
7329
7562
|
destinations.add(query.destination);
|
|
7330
|
-
|
|
7563
|
+
row2.available = query.version;
|
|
7331
7564
|
if (query.status !== "found" || query.version === null) {
|
|
7332
|
-
|
|
7333
|
-
report.providers.push(
|
|
7565
|
+
row2.verdict = query.status === "unknown" ? "unknown" : "unavailable";
|
|
7566
|
+
report.providers.push(row2);
|
|
7334
7567
|
continue;
|
|
7335
7568
|
}
|
|
7336
7569
|
const installed = detection.version === null ? null : parseSemanticVersion(detection.version);
|
|
7337
7570
|
const offered = parseSemanticVersion(query.version);
|
|
7338
7571
|
if (installed === null || offered === null || compareVersions(offered, installed) <= 0) {
|
|
7339
|
-
|
|
7340
|
-
report.providers.push(
|
|
7572
|
+
row2.verdict = "current";
|
|
7573
|
+
report.providers.push(row2);
|
|
7341
7574
|
continue;
|
|
7342
7575
|
}
|
|
7343
|
-
|
|
7344
|
-
report.providers.push(
|
|
7576
|
+
row2.verdict = "upgradable";
|
|
7577
|
+
report.providers.push(row2);
|
|
7345
7578
|
actions.push(upgradeAction({
|
|
7346
7579
|
providerId: adapter.manifest.id,
|
|
7347
7580
|
channel: channel.id,
|
|
@@ -7556,11 +7789,52 @@ function statusFor(achieved, declared) {
|
|
|
7556
7789
|
}
|
|
7557
7790
|
|
|
7558
7791
|
// apps/cli/dist/src/render/layout.js
|
|
7792
|
+
var MAX_WIDTH = 78;
|
|
7793
|
+
function wrap(text, indent, width = MAX_WIDTH) {
|
|
7794
|
+
const limit = Math.max(20, width - indent);
|
|
7795
|
+
const words = text.split(/\s+/).filter((word) => word !== "");
|
|
7796
|
+
if (words.length === 0)
|
|
7797
|
+
return [];
|
|
7798
|
+
const lines = [];
|
|
7799
|
+
let current = "";
|
|
7800
|
+
for (const word of words) {
|
|
7801
|
+
if (current === "") {
|
|
7802
|
+
current = word;
|
|
7803
|
+
continue;
|
|
7804
|
+
}
|
|
7805
|
+
if (`${current} ${word}`.length <= limit) {
|
|
7806
|
+
current = `${current} ${word}`;
|
|
7807
|
+
continue;
|
|
7808
|
+
}
|
|
7809
|
+
lines.push(current);
|
|
7810
|
+
current = word;
|
|
7811
|
+
}
|
|
7812
|
+
lines.push(current);
|
|
7813
|
+
const pad = " ".repeat(indent);
|
|
7814
|
+
return lines.map((line, index) => index === 0 ? pad + line : pad + line);
|
|
7815
|
+
}
|
|
7559
7816
|
function column(value, width, minimumGutter = 2) {
|
|
7560
7817
|
if (value.length >= width)
|
|
7561
7818
|
return value + " ".repeat(minimumGutter);
|
|
7562
7819
|
return value.padEnd(width, " ");
|
|
7563
7820
|
}
|
|
7821
|
+
function truncate(value, width) {
|
|
7822
|
+
const characters = [...value];
|
|
7823
|
+
if (characters.length <= width)
|
|
7824
|
+
return value;
|
|
7825
|
+
return `${characters.slice(0, Math.max(1, width - 1)).join("").trimEnd()}\u2026`;
|
|
7826
|
+
}
|
|
7827
|
+
var COLUMN_SEPARATOR = " - ";
|
|
7828
|
+
function row(cells) {
|
|
7829
|
+
const rendered = cells.map(([value, width], index) => index === cells.length - 1 ? value : column(value, width, 0));
|
|
7830
|
+
return rendered.join(COLUMN_SEPARATOR);
|
|
7831
|
+
}
|
|
7832
|
+
function truncatePath(value, width) {
|
|
7833
|
+
const characters = [...value];
|
|
7834
|
+
if (characters.length <= width)
|
|
7835
|
+
return value;
|
|
7836
|
+
return `\u2026${characters.slice(characters.length - (width - 1)).join("")}`;
|
|
7837
|
+
}
|
|
7564
7838
|
function rightAlign(value, width) {
|
|
7565
7839
|
return value.padStart(width, " ");
|
|
7566
7840
|
}
|
|
@@ -7639,7 +7913,7 @@ var HEADERS = {
|
|
|
7639
7913
|
rollback: "Rollback",
|
|
7640
7914
|
uninstall: "Uninstall"
|
|
7641
7915
|
};
|
|
7642
|
-
function renderApplyReport(report,
|
|
7916
|
+
function renderApplyReport(report, context, command = "apply") {
|
|
7643
7917
|
const lines = [];
|
|
7644
7918
|
const header = [HEADERS[command] ?? "Apply"];
|
|
7645
7919
|
header.push(report.planId === null ? "no plan" : `plan ${report.planId}`);
|
|
@@ -7652,14 +7926,20 @@ function renderApplyReport(report, _context, command = "apply") {
|
|
|
7652
7926
|
if (report.results.length > 0) {
|
|
7653
7927
|
lines.push("Actions");
|
|
7654
7928
|
for (const [index, result] of report.results.entries()) {
|
|
7655
|
-
lines.push(` ${String(index + 1)}. ${
|
|
7929
|
+
lines.push(` ${String(index + 1)}. ${row([
|
|
7930
|
+
[result.kind, KIND_WIDTH],
|
|
7931
|
+
[result.status, STATUS_WIDTH],
|
|
7932
|
+
// Abbreviated: an absolute Windows path under a long account name ran past 140
|
|
7933
|
+
// characters, and `~/` is both shorter and what every other command shows.
|
|
7934
|
+
[result.path === null ? "" : displayPath(result.path, context.home), 0]
|
|
7935
|
+
])}`);
|
|
7656
7936
|
}
|
|
7657
7937
|
lines.push("");
|
|
7658
7938
|
}
|
|
7659
7939
|
if (report.unrestored.length > 0) {
|
|
7660
7940
|
lines.push("Not restored");
|
|
7661
7941
|
for (const path of report.unrestored)
|
|
7662
|
-
lines.push(` ${path}`);
|
|
7942
|
+
lines.push(` ${displayPath(path, context.home)}`);
|
|
7663
7943
|
lines.push("");
|
|
7664
7944
|
}
|
|
7665
7945
|
lines.push((OUTCOME_LINES[command] ?? OUTCOME_LINES["apply"])?.[report.outcome] ?? "");
|
|
@@ -7667,57 +7947,133 @@ function renderApplyReport(report, _context, command = "apply") {
|
|
|
7667
7947
|
}
|
|
7668
7948
|
|
|
7669
7949
|
// apps/cli/dist/src/render/doctor.js
|
|
7670
|
-
var
|
|
7671
|
-
var
|
|
7672
|
-
var
|
|
7673
|
-
var
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
if (detection.
|
|
7688
|
-
|
|
7689
|
-
|
|
7950
|
+
var NAME_WIDTH = 15;
|
|
7951
|
+
var STATE_WIDTH = 12;
|
|
7952
|
+
var VERSION_WIDTH = 10;
|
|
7953
|
+
var WIRED_WIDTH = 14;
|
|
7954
|
+
function harnessState(detection) {
|
|
7955
|
+
switch (detection.state) {
|
|
7956
|
+
case "absent":
|
|
7957
|
+
return "not found";
|
|
7958
|
+
case "detected":
|
|
7959
|
+
return "no hooks";
|
|
7960
|
+
case "configured":
|
|
7961
|
+
return "hooks";
|
|
7962
|
+
case "broken":
|
|
7963
|
+
return "unreadable";
|
|
7964
|
+
}
|
|
7965
|
+
}
|
|
7966
|
+
function wiredTo(detection) {
|
|
7967
|
+
if (detection.state === "broken")
|
|
7968
|
+
return "cannot run";
|
|
7969
|
+
if (detection.state === "absent")
|
|
7970
|
+
return "not installed";
|
|
7971
|
+
if (detection.configuredHarnesses.length === 0)
|
|
7972
|
+
return "nothing yet";
|
|
7973
|
+
return detection.configuredHarnesses.join(", ");
|
|
7974
|
+
}
|
|
7975
|
+
function setUpBy(detection) {
|
|
7976
|
+
if (detection.state === "absent" || detection.configuredHarnesses.length === 0)
|
|
7977
|
+
return "\u2014";
|
|
7978
|
+
return detection.managedByTokenHarness ? "this tool" : "you";
|
|
7979
|
+
}
|
|
7980
|
+
function notes(report) {
|
|
7981
|
+
const lines = [];
|
|
7982
|
+
for (const harness of report.harnesses) {
|
|
7983
|
+
if (harness.state === "broken") {
|
|
7984
|
+
lines.push(` ${row([
|
|
7985
|
+
[harness.harnessId, NAME_WIDTH - 2],
|
|
7986
|
+
["configuration could not be read", 0]
|
|
7987
|
+
])}`);
|
|
7988
|
+
}
|
|
7989
|
+
if (harness.versionVerdict === "unknown-newer") {
|
|
7990
|
+
lines.push(` ${row([
|
|
7991
|
+
[harness.harnessId, NAME_WIDTH - 2],
|
|
7992
|
+
[`${harness.version ?? ""} is newer than any tested version`, 0]
|
|
7993
|
+
])}`);
|
|
7994
|
+
}
|
|
7995
|
+
}
|
|
7996
|
+
for (const provider of report.providers) {
|
|
7997
|
+
if (provider.state === "broken") {
|
|
7998
|
+
lines.push(` ${row([
|
|
7999
|
+
[provider.providerId, NAME_WIDTH - 2],
|
|
8000
|
+
["installed but could not be run", 0]
|
|
8001
|
+
])}`);
|
|
8002
|
+
}
|
|
8003
|
+
if (provider.versionVerdict === "unknown-newer") {
|
|
8004
|
+
lines.push(` ${row([
|
|
8005
|
+
[provider.providerId, NAME_WIDTH - 2],
|
|
8006
|
+
[`${provider.version ?? ""} is newer than any tested version`, 0]
|
|
8007
|
+
])}`);
|
|
8008
|
+
}
|
|
7690
8009
|
}
|
|
7691
|
-
|
|
7692
|
-
const adopted = detection.managedByTokenHarness ? "" : " (adopted, not managed)";
|
|
7693
|
-
return `configured for ${list}${adopted}`;
|
|
8010
|
+
return lines;
|
|
7694
8011
|
}
|
|
7695
8012
|
function renderDoctorReport(report, context) {
|
|
7696
8013
|
const lines = [];
|
|
7697
8014
|
lines.push(`Token Harness ${context.toolVersion} \u2014 ${renderPlatformSummary(report.platform)}, Node ${report.platform.nodeVersion}`);
|
|
7698
8015
|
lines.push("");
|
|
7699
|
-
lines.push(
|
|
8016
|
+
lines.push(` ${row([
|
|
8017
|
+
["HARNESSES", NAME_WIDTH - 2],
|
|
8018
|
+
["STATE", STATE_WIDTH],
|
|
8019
|
+
["CONFIG FILE", 0]
|
|
8020
|
+
])}`);
|
|
7700
8021
|
if (report.harnesses.length === 0) {
|
|
7701
|
-
lines.push("
|
|
8022
|
+
lines.push(" none registered");
|
|
7702
8023
|
} else {
|
|
7703
8024
|
for (const harness of report.harnesses) {
|
|
7704
|
-
lines.push(` ${
|
|
8025
|
+
lines.push(` ${row([
|
|
8026
|
+
[harness.harnessId, NAME_WIDTH - 2],
|
|
8027
|
+
[harnessState(harness), STATE_WIDTH],
|
|
8028
|
+
[
|
|
8029
|
+
harness.configPath === null ? "" : (
|
|
8030
|
+
// The columns before this one, plus their separators, consume a fixed prefix; the
|
|
8031
|
+
// path gets what is left and is cut from the left so the file name survives.
|
|
8032
|
+
truncatePath(displayPath(harness.configPath, context.home), MAX_WIDTH - (2 + NAME_WIDTH - 2 + 3 + STATE_WIDTH + 3))
|
|
8033
|
+
),
|
|
8034
|
+
0
|
|
8035
|
+
]
|
|
8036
|
+
])}`);
|
|
7705
8037
|
}
|
|
7706
8038
|
}
|
|
7707
8039
|
lines.push("");
|
|
7708
|
-
lines.push(
|
|
8040
|
+
lines.push(` ${row([
|
|
8041
|
+
["PROVIDERS", NAME_WIDTH - 2],
|
|
8042
|
+
["VERSION", VERSION_WIDTH],
|
|
8043
|
+
["WIRED TO", WIRED_WIDTH],
|
|
8044
|
+
["SET UP BY", 0]
|
|
8045
|
+
])}`);
|
|
7709
8046
|
if (report.providers.length === 0) {
|
|
7710
|
-
lines.push("
|
|
8047
|
+
lines.push(" none registered");
|
|
7711
8048
|
} else {
|
|
7712
8049
|
for (const provider of report.providers) {
|
|
7713
|
-
lines.push(` ${
|
|
8050
|
+
lines.push(` ${row([
|
|
8051
|
+
[provider.providerId, NAME_WIDTH - 2],
|
|
8052
|
+
[provider.version ?? "-", VERSION_WIDTH],
|
|
8053
|
+
[wiredTo(provider), WIRED_WIDTH],
|
|
8054
|
+
[setUpBy(provider), 0]
|
|
8055
|
+
])}`);
|
|
7714
8056
|
}
|
|
7715
8057
|
}
|
|
8058
|
+
const notable = notes(report);
|
|
8059
|
+
if (notable.length > 0) {
|
|
8060
|
+
lines.push("");
|
|
8061
|
+
lines.push("NOTES");
|
|
8062
|
+
lines.push(...notable);
|
|
8063
|
+
}
|
|
8064
|
+
const unwired = report.providers.filter((provider) => provider.state !== "absent" && provider.configuredHarnesses.length === 0);
|
|
7716
8065
|
lines.push("");
|
|
7717
|
-
|
|
7718
|
-
|
|
7719
|
-
|
|
7720
|
-
|
|
8066
|
+
lines.push("NEXT");
|
|
8067
|
+
const suggestions = report.providers.every((provider) => provider.state === "absent") || unwired.length > 0 ? [["token-harness plan", "see what would change \u2014 writes nothing"]] : [
|
|
8068
|
+
["token-harness verify", "check the pipeline actually intercepts"],
|
|
8069
|
+
["token-harness metrics --since 7d", "see what it saved"]
|
|
8070
|
+
];
|
|
8071
|
+
const commandWidth = Math.max(...suggestions.map(([command]) => command.length));
|
|
8072
|
+
for (const [command, description] of suggestions) {
|
|
8073
|
+
lines.push(` ${row([
|
|
8074
|
+
[command, commandWidth],
|
|
8075
|
+
[description, 0]
|
|
8076
|
+
])}`);
|
|
7721
8077
|
}
|
|
7722
8078
|
return document(lines);
|
|
7723
8079
|
}
|
|
@@ -7725,11 +8081,10 @@ function renderDoctorReport(report, context) {
|
|
|
7725
8081
|
// apps/cli/dist/src/render/metrics.js
|
|
7726
8082
|
var CLASS_LABEL_WIDTH = 23;
|
|
7727
8083
|
var FIGURE_BLOCK_GUTTER = 4;
|
|
7728
|
-
var
|
|
7729
|
-
var PROVIDER_SAVED_WIDTH =
|
|
7730
|
-
var PROVIDER_CLASS_WIDTH =
|
|
7731
|
-
var
|
|
7732
|
-
var PROVIDER_CONTINUATION_INDENT = 2 + PROVIDER_ID_WIDTH2;
|
|
8084
|
+
var PROVIDER_ID_WIDTH = 13;
|
|
8085
|
+
var PROVIDER_SAVED_WIDTH = 21;
|
|
8086
|
+
var PROVIDER_CLASS_WIDTH = 15;
|
|
8087
|
+
var PROVIDER_CONTINUATION_INDENT = 2 + PROVIDER_ID_WIDTH;
|
|
7733
8088
|
var CLASS_LABELS = {
|
|
7734
8089
|
"exact-local": "Exact local",
|
|
7735
8090
|
"estimated-local": "Estimated local",
|
|
@@ -7737,21 +8092,21 @@ var CLASS_LABELS = {
|
|
|
7737
8092
|
"end-to-end-billed": "End-to-end billed"
|
|
7738
8093
|
};
|
|
7739
8094
|
function renderClassRows(report) {
|
|
7740
|
-
const byClass = new Map(report.classes.map((
|
|
7741
|
-
const ordered = MEASUREMENT_CLASSES.map((id) => byClass.get(id)).filter((
|
|
7742
|
-
const withFigures = ordered.filter((
|
|
7743
|
-
const beforeWidth = Math.max(0, ...withFigures.map((
|
|
7744
|
-
const afterWidth = Math.max(0, ...withFigures.map((
|
|
7745
|
-
const blocks = ordered.map((
|
|
7746
|
-
if (
|
|
8095
|
+
const byClass = new Map(report.classes.map((row2) => [row2.class, row2]));
|
|
8096
|
+
const ordered = MEASUREMENT_CLASSES.map((id) => byClass.get(id)).filter((row2) => row2 !== void 0);
|
|
8097
|
+
const withFigures = ordered.filter((row2) => row2.before !== null && row2.after !== null);
|
|
8098
|
+
const beforeWidth = Math.max(0, ...withFigures.map((row2) => formatCount(row2.before).length));
|
|
8099
|
+
const afterWidth = Math.max(0, ...withFigures.map((row2) => formatCount(row2.after).length));
|
|
8100
|
+
const blocks = ordered.map((row2) => {
|
|
8101
|
+
if (row2.before === null || row2.after === null)
|
|
7747
8102
|
return "";
|
|
7748
|
-
return `${rightAlign(formatCount(
|
|
8103
|
+
return `${rightAlign(formatCount(row2.before), beforeWidth)} -> ${rightAlign(formatCount(row2.after), afterWidth)} ${row2.unit ?? ""}`;
|
|
7749
8104
|
});
|
|
7750
8105
|
const blockWidth = Math.max(0, ...blocks.map((block) => block.length)) + FIGURE_BLOCK_GUTTER;
|
|
7751
|
-
return ordered.map((
|
|
7752
|
-
const label = column(CLASS_LABELS[
|
|
8106
|
+
return ordered.map((row2, index) => {
|
|
8107
|
+
const label = column(CLASS_LABELS[row2.class], CLASS_LABEL_WIDTH);
|
|
7753
8108
|
const block = (blocks[index] ?? "").padEnd(blockWidth, " ");
|
|
7754
|
-
const tail =
|
|
8109
|
+
const tail = row2.saved === null ? row2.note ?? "" : `saved ${formatCount(row2.saved)}`;
|
|
7755
8110
|
return `${label}${block}${tail}`;
|
|
7756
8111
|
});
|
|
7757
8112
|
}
|
|
@@ -7769,14 +8124,21 @@ function renderMetricsReport(report, _context) {
|
|
|
7769
8124
|
lines.push(" no provider reported a measurable saving in this window");
|
|
7770
8125
|
} else {
|
|
7771
8126
|
for (const provider of report.providers) {
|
|
7772
|
-
lines.push(` ${
|
|
7773
|
-
|
|
8127
|
+
lines.push(` ${row([
|
|
8128
|
+
[provider.providerId, PROVIDER_ID_WIDTH],
|
|
8129
|
+
[`saved ${formatCount(provider.saved)} ${provider.unit}`, PROVIDER_SAVED_WIDTH],
|
|
8130
|
+
[provider.class, PROVIDER_CLASS_WIDTH],
|
|
8131
|
+
[`${formatCount(provider.operations)} operations`, 0]
|
|
8132
|
+
])}`);
|
|
8133
|
+
const notes2 = [];
|
|
8134
|
+
if (provider.harnesses.length > 0)
|
|
8135
|
+
notes2.push(`on ${provider.harnesses.join(", ")}`);
|
|
7774
8136
|
if (!provider.managedByTokenHarness)
|
|
7775
|
-
|
|
8137
|
+
notes2.push("set up by you");
|
|
7776
8138
|
if (provider.adapterMode !== null)
|
|
7777
|
-
|
|
7778
|
-
if (
|
|
7779
|
-
lines.push(`${" ".repeat(PROVIDER_CONTINUATION_INDENT)}${
|
|
8139
|
+
notes2.push(`mode ${provider.adapterMode}`);
|
|
8140
|
+
if (notes2.length > 0) {
|
|
8141
|
+
lines.push(`${" ".repeat(PROVIDER_CONTINUATION_INDENT)}${notes2.join(" \u2014 ")}`);
|
|
7780
8142
|
}
|
|
7781
8143
|
}
|
|
7782
8144
|
}
|
|
@@ -7808,8 +8170,8 @@ function renderConflicts(report) {
|
|
|
7808
8170
|
lines.push("");
|
|
7809
8171
|
lines.push(` ${column("conflict", CONFLICT_LABEL_WIDTH)}${conflict.code}`);
|
|
7810
8172
|
for (const detail2 of conflict.detail)
|
|
7811
|
-
lines.push(
|
|
7812
|
-
lines.push(`
|
|
8173
|
+
lines.push(...wrap(detail2, 4));
|
|
8174
|
+
lines.push(...wrap(`Fix: ${conflict.remediation}`, 4));
|
|
7813
8175
|
}
|
|
7814
8176
|
lines.push("");
|
|
7815
8177
|
lines.push("No plan was produced.");
|
|
@@ -7852,13 +8214,24 @@ function renderPlanReport(report, context) {
|
|
|
7852
8214
|
if (report.exclusions.length > 0) {
|
|
7853
8215
|
lines.push("");
|
|
7854
8216
|
lines.push("Excluded");
|
|
8217
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
7855
8218
|
for (const exclusion of report.exclusions) {
|
|
7856
|
-
const
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
|
|
8219
|
+
const key = `${exclusion.excluded}\0${exclusion.scope.capability}`;
|
|
8220
|
+
const existing = grouped.get(key);
|
|
8221
|
+
if (existing === void 0) {
|
|
8222
|
+
grouped.set(key, {
|
|
8223
|
+
capability: exclusion.scope.capability,
|
|
8224
|
+
harnesses: [exclusion.scope.harness]
|
|
8225
|
+
});
|
|
8226
|
+
} else if (!existing.harnesses.includes(exclusion.scope.harness)) {
|
|
8227
|
+
existing.harnesses.push(exclusion.scope.harness);
|
|
7860
8228
|
}
|
|
7861
8229
|
}
|
|
8230
|
+
for (const [key, entry] of grouped) {
|
|
8231
|
+
const provider = key.slice(0, key.indexOf("\0"));
|
|
8232
|
+
lines.push(` ${column(provider, EXCLUSION_PROVIDER_WIDTH)}${column(entry.capability, EXCLUSION_CAPABILITY_WIDTH)}${entry.harnesses.join(", ")}`);
|
|
8233
|
+
lines.push(...wrap("its installer cannot produce this in isolation, so it is measured but not given the scope", EXCLUSION_CONTINUATION_INDENT));
|
|
8234
|
+
}
|
|
7862
8235
|
}
|
|
7863
8236
|
lines.push("");
|
|
7864
8237
|
lines.push("Actions");
|
|
@@ -7934,22 +8307,22 @@ var VERDICT_WIDTH = 15;
|
|
|
7934
8307
|
function widthOf(values, floor) {
|
|
7935
8308
|
return Math.max(floor, ...values.map((value) => value.length + 2));
|
|
7936
8309
|
}
|
|
7937
|
-
function detail(
|
|
7938
|
-
switch (
|
|
8310
|
+
function detail(row2) {
|
|
8311
|
+
switch (row2.verdict) {
|
|
7939
8312
|
case "upgradable":
|
|
7940
|
-
return `${String(
|
|
8313
|
+
return `${String(row2.installed)} \u2192 ${String(row2.available)} via ${String(row2.channel)}`;
|
|
7941
8314
|
case "current":
|
|
7942
|
-
return `${String(
|
|
8315
|
+
return `${String(row2.installed)} is the newest ${String(row2.channel)} offers`;
|
|
7943
8316
|
case "pinned":
|
|
7944
|
-
return `held at ${String(
|
|
8317
|
+
return `held at ${String(row2.pin)} by a pin`;
|
|
7945
8318
|
case "not-installed":
|
|
7946
8319
|
return "not installed, so there is nothing to update";
|
|
7947
8320
|
case "no-channel":
|
|
7948
8321
|
return "no installation channel on this platform";
|
|
7949
8322
|
case "unknown":
|
|
7950
|
-
return `${String(
|
|
8323
|
+
return `${String(row2.channel)} answered without a version this build can read`;
|
|
7951
8324
|
case "unavailable":
|
|
7952
|
-
return `${String(
|
|
8325
|
+
return `${String(row2.channel)} could not be asked`;
|
|
7953
8326
|
}
|
|
7954
8327
|
}
|
|
7955
8328
|
function renderUpdateReport(report, _context) {
|
|
@@ -7958,16 +8331,20 @@ function renderUpdateReport(report, _context) {
|
|
|
7958
8331
|
lines.push("No provider was inspected.");
|
|
7959
8332
|
return document(lines);
|
|
7960
8333
|
}
|
|
7961
|
-
const providerWidth = widthOf(report.providers.map((
|
|
7962
|
-
const
|
|
7963
|
-
for (const
|
|
7964
|
-
lines.push(
|
|
8334
|
+
const providerWidth = Math.min(20, widthOf(report.providers.map((entry) => entry.providerId), PROVIDER_WIDTH));
|
|
8335
|
+
const detailStart = providerWidth + 3 + VERDICT_WIDTH + 3;
|
|
8336
|
+
for (const entry of report.providers) {
|
|
8337
|
+
lines.push(truncate(row([
|
|
8338
|
+
[entry.providerId, providerWidth],
|
|
8339
|
+
[entry.verdict, VERDICT_WIDTH],
|
|
8340
|
+
[truncate(detail(entry), MAX_WIDTH - detailStart), 0]
|
|
8341
|
+
]), MAX_WIDTH));
|
|
7965
8342
|
}
|
|
7966
8343
|
if (report.network.length > 0) {
|
|
7967
8344
|
lines.push("");
|
|
7968
8345
|
lines.push(`Network: ${report.network.join(", ")}`);
|
|
7969
8346
|
}
|
|
7970
|
-
const upgradable = report.providers.filter((
|
|
8347
|
+
const upgradable = report.providers.filter((row2) => row2.verdict === "upgradable").length;
|
|
7971
8348
|
const execution = report.execution;
|
|
7972
8349
|
lines.push("");
|
|
7973
8350
|
if (execution === null || execution.outcome === "nothing-to-do") {
|
|
@@ -7983,33 +8360,34 @@ function renderUpdateReport(report, _context) {
|
|
|
7983
8360
|
}
|
|
7984
8361
|
|
|
7985
8362
|
// apps/cli/dist/src/render/verify.js
|
|
7986
|
-
var
|
|
7987
|
-
var
|
|
7988
|
-
function
|
|
7989
|
-
|
|
7990
|
-
return Math.max(CHECK_STATUS_WIDTH, longest + 2);
|
|
8363
|
+
var STATUS_WIDTH2 = 16;
|
|
8364
|
+
var CHECK_WIDTH = 12;
|
|
8365
|
+
function shortCheck(id) {
|
|
8366
|
+
return truncate(id.replace(/-resolves$|-registered$|-intercepted$/, ""), CHECK_WIDTH);
|
|
7991
8367
|
}
|
|
7992
8368
|
function renderVerifyReport(report, _context) {
|
|
7993
8369
|
const lines = [];
|
|
7994
|
-
|
|
7995
|
-
lines.push(report.receiptId === null || report.appliedAt === null ? "No receipt \u2014 verifying the live configuration" : `Receipt ${report.receiptId} \u2014 applied ${report.appliedAt}`);
|
|
7996
|
-
lines.push("");
|
|
8370
|
+
lines.push(report.receiptId === null || report.appliedAt === null ? "No receipt: verifying what is on the machine now" : `Receipt ${report.receiptId} \u2014 applied ${report.appliedAt}`);
|
|
7997
8371
|
for (const result of report.results) {
|
|
7998
|
-
|
|
7999
|
-
|
|
8000
|
-
header.push("adopted, not managed");
|
|
8001
|
-
header.push(`declared tier: ${result.declaredTier}`);
|
|
8002
|
-
lines.push(header.join(" \u2014 "));
|
|
8372
|
+
lines.push("");
|
|
8373
|
+
lines.push(`${result.providerId} on ${result.harnessId} \u2014 set up by ${result.managedByTokenHarness ? "this tool" : "you"}, tier ${result.declaredTier}`);
|
|
8003
8374
|
for (const check of result.checks) {
|
|
8004
|
-
|
|
8375
|
+
const indent = 2 + CHECK_WIDTH + 3 + STATUS_WIDTH2 + 3;
|
|
8376
|
+
const wrapped = wrap(check.summary, indent);
|
|
8377
|
+
lines.push(` ${row([
|
|
8378
|
+
[shortCheck(check.id), CHECK_WIDTH],
|
|
8379
|
+
[check.status, STATUS_WIDTH2],
|
|
8380
|
+
[(wrapped[0] ?? "").trimStart(), 0]
|
|
8381
|
+
])}`);
|
|
8382
|
+
lines.push(...wrapped.slice(1));
|
|
8005
8383
|
}
|
|
8006
8384
|
}
|
|
8007
8385
|
lines.push("");
|
|
8008
8386
|
if (report.healthyAtDeclaredTier) {
|
|
8009
|
-
lines.push("
|
|
8387
|
+
lines.push("Healthy at the declared tier for every provider.");
|
|
8010
8388
|
} else {
|
|
8011
8389
|
const failures = report.results.flatMap((result) => result.checks).filter((check) => check.status === "fail").length;
|
|
8012
|
-
lines.push(`${failures} ${pluralize(failures, "check")} below
|
|
8390
|
+
lines.push(`${String(failures)} ${pluralize(failures, "check")} below tier. Not proven.`);
|
|
8013
8391
|
}
|
|
8014
8392
|
return document(lines);
|
|
8015
8393
|
}
|
|
@@ -8053,27 +8431,37 @@ function renderHuman(result, context) {
|
|
|
8053
8431
|
}
|
|
8054
8432
|
|
|
8055
8433
|
// apps/cli/dist/src/usage.js
|
|
8056
|
-
var ROOT_USAGE = `token-harness \u2014
|
|
8434
|
+
var ROOT_USAGE = `token-harness \u2014 set up and measure token-saving tools for coding agents
|
|
8435
|
+
|
|
8436
|
+
First time here
|
|
8437
|
+
1 token-harness doctor what is on this machine writes nothing
|
|
8438
|
+
2 token-harness plan what would change writes nothing
|
|
8439
|
+
3 token-harness apply --yes make those changes WRITES
|
|
8440
|
+
4 token-harness verify is it actually intercepting writes nothing
|
|
8441
|
+
5 token-harness metrics what it saved writes nothing
|
|
8442
|
+
|
|
8443
|
+
Steps 1 and 2 are safe to run right now. Nothing changes until step 3.
|
|
8057
8444
|
|
|
8058
8445
|
Usage
|
|
8059
8446
|
token-harness <command> [flags]
|
|
8447
|
+
token-harness help <command>
|
|
8060
8448
|
|
|
8061
|
-
Commands
|
|
8062
|
-
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
|
|
8449
|
+
Commands, in the order you would use them
|
|
8450
|
+
doctor What is installed, what is wired up, what is worth knowing
|
|
8451
|
+
plan Compute what would change, file by file. Changes nothing
|
|
8452
|
+
apply Run that plan inside a transaction that can be rolled back
|
|
8453
|
+
verify Check the pipeline actually intercepts, at its declared tier
|
|
8454
|
+
metrics Report what was saved, labelled with how it was measured
|
|
8066
8455
|
status Report applied pipelines, drift, and importer modes
|
|
8067
|
-
|
|
8068
|
-
rollback Restore the files a transaction changed, as they were before
|
|
8069
|
-
uninstall Remove what Token Harness
|
|
8070
|
-
update Update the installed providers to what their channel offers
|
|
8456
|
+
update Update installed providers to what their channel offers
|
|
8457
|
+
rollback Restore the files a transaction changed, as they were before
|
|
8458
|
+
uninstall Remove what Token Harness set up, leaving everything else
|
|
8071
8459
|
|
|
8072
8460
|
Flags
|
|
8073
8461
|
--json Emit one machine-readable envelope on stdout
|
|
8074
8462
|
--harness <id> Restrict the operation to one harness
|
|
8075
8463
|
--provider <id> Restrict the operation to one provider
|
|
8076
|
-
--project <dir>
|
|
8464
|
+
--project <dir> Use that project instead of the current directory
|
|
8077
8465
|
--since <window> Report from this point: a duration like 7d, or a date
|
|
8078
8466
|
--until <window> Report up to this point; defaults to now
|
|
8079
8467
|
--plan <id> Apply a previously computed plan by id
|
|
@@ -8081,8 +8469,8 @@ Flags
|
|
|
8081
8469
|
--version Print the version and exit 0
|
|
8082
8470
|
--help Print usage and exit 0
|
|
8083
8471
|
|
|
8084
|
-
|
|
8085
|
-
|
|
8472
|
+
Only apply, update, rollback and uninstall change anything, and none of
|
|
8473
|
+
them do without --yes. Exit codes and JSON are specified in RFC 0006.`;
|
|
8086
8474
|
var COMMAND_USAGE = {
|
|
8087
8475
|
apply: `token-harness apply \u2014 execute a plan inside a reversible transaction
|
|
8088
8476
|
|
|
@@ -8221,7 +8609,7 @@ function usageText(topic) {
|
|
|
8221
8609
|
}
|
|
8222
8610
|
|
|
8223
8611
|
// apps/cli/dist/src/version.js
|
|
8224
|
-
var TOOL_VERSION = "0.1.
|
|
8612
|
+
var TOOL_VERSION = "0.1.1";
|
|
8225
8613
|
|
|
8226
8614
|
// apps/cli/dist/src/run.js
|
|
8227
8615
|
var DEFAULT_COMMANDS = {
|
|
@@ -8235,12 +8623,31 @@ var DEFAULT_COMMANDS = {
|
|
|
8235
8623
|
update: runUpdate,
|
|
8236
8624
|
verify: runVerify
|
|
8237
8625
|
};
|
|
8238
|
-
|
|
8239
|
-
|
|
8240
|
-
|
|
8241
|
-
|
|
8242
|
-
|
|
8243
|
-
|
|
8626
|
+
var SUBJECT_WIDTH = 12;
|
|
8627
|
+
function diagnosticLine(entry) {
|
|
8628
|
+
const label = entry.subject ?? entry.code;
|
|
8629
|
+
return truncate(` ${row([
|
|
8630
|
+
[label, SUBJECT_WIDTH],
|
|
8631
|
+
[entry.message, 0]
|
|
8632
|
+
])}`, MAX_WIDTH);
|
|
8633
|
+
}
|
|
8634
|
+
function formatDiagnostics(diagnostics) {
|
|
8635
|
+
const errors = diagnostics.filter((entry) => entry.severity === "error");
|
|
8636
|
+
const warnings = diagnostics.filter((entry) => entry.severity === "warning");
|
|
8637
|
+
if (errors.length === 0 && warnings.length === 0)
|
|
8638
|
+
return "";
|
|
8639
|
+
const lines = [];
|
|
8640
|
+
for (const [title, group] of [
|
|
8641
|
+
["ERRORS", errors],
|
|
8642
|
+
["WARNINGS", warnings]
|
|
8643
|
+
]) {
|
|
8644
|
+
if (group.length === 0)
|
|
8645
|
+
continue;
|
|
8646
|
+
lines.push("");
|
|
8647
|
+
lines.push(title);
|
|
8648
|
+
for (const entry of group)
|
|
8649
|
+
lines.push(diagnosticLine(entry));
|
|
8650
|
+
}
|
|
8244
8651
|
return `${lines.join("\n")}
|
|
8245
8652
|
`;
|
|
8246
8653
|
}
|
|
@@ -8282,8 +8689,9 @@ function emit(result, options, renderContext, json) {
|
|
|
8282
8689
|
const rendering = renderHuman(result, renderContext);
|
|
8283
8690
|
if (rendering.report !== "")
|
|
8284
8691
|
options.streams.out(rendering.report);
|
|
8285
|
-
|
|
8286
|
-
|
|
8692
|
+
const diagnostics = formatDiagnostics(rendering.stderrDiagnostics);
|
|
8693
|
+
if (diagnostics !== "")
|
|
8694
|
+
options.streams.err(diagnostics);
|
|
8287
8695
|
return result.exitCode;
|
|
8288
8696
|
}
|
|
8289
8697
|
function emitHelpOrVersion(invocation, options) {
|