@workbench-ai/workbench 0.0.83 → 0.0.85
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/dist/index.js +50 -24
- package/dist/install-targets.d.ts +1 -1
- package/dist/install-targets.d.ts.map +1 -1
- package/dist/install-targets.js +11 -3
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -908,7 +908,7 @@ async function handleInstall(parsed, io) {
|
|
|
908
908
|
},
|
|
909
909
|
});
|
|
910
910
|
const fanout = parsed.flags["dry-run"] === true
|
|
911
|
-
? skippedFanOut(result.directoryName, result.destination)
|
|
911
|
+
? skippedFanOut(result.directoryName, result.destination, result.result === "unchanged" ? "unchanged" : "dry-run")
|
|
912
912
|
: await fanOutSkill(result.directoryName, { skillDir: result.destination });
|
|
913
913
|
const next = installNextCommand(fanout);
|
|
914
914
|
return emitResult("workbench.cli.install.v1", {
|
|
@@ -1008,16 +1008,16 @@ async function handleCloudImprove(parsed, io) {
|
|
|
1008
1008
|
...(next ? [`next: ${next}`] : []),
|
|
1009
1009
|
].filter(Boolean).join("\n"));
|
|
1010
1010
|
}
|
|
1011
|
-
function skippedFanOut(name, destination) {
|
|
1011
|
+
function skippedFanOut(name, destination, reason) {
|
|
1012
1012
|
return {
|
|
1013
1013
|
status: "skipped",
|
|
1014
1014
|
command: manualFanOutCommand(destination, name),
|
|
1015
1015
|
linkedAgents: [],
|
|
1016
|
-
reason
|
|
1016
|
+
reason,
|
|
1017
1017
|
};
|
|
1018
1018
|
}
|
|
1019
1019
|
function installNextCommand(fanout) {
|
|
1020
|
-
return fanout.status === "failed" || (fanout.status === "skipped" && fanout.reason !== "dry-run")
|
|
1020
|
+
return fanout.status === "failed" || (fanout.status === "skipped" && fanout.reason !== "dry-run" && fanout.reason !== "unchanged")
|
|
1021
1021
|
? fanout.command
|
|
1022
1022
|
: null;
|
|
1023
1023
|
}
|
|
@@ -1026,11 +1026,20 @@ function formatInstallOutcome(result, dryRun) {
|
|
|
1026
1026
|
if (result.result === "unchanged") {
|
|
1027
1027
|
return `Already installed ${result.directoryName} at ${result.destination} (unchanged; dry run made no changes).`;
|
|
1028
1028
|
}
|
|
1029
|
+
if (result.previous === "updated") {
|
|
1030
|
+
return `Would update ${result.directoryName} at ${result.destination} (${formatFileCount(result.filesCopied)}).`;
|
|
1031
|
+
}
|
|
1032
|
+
if (result.previous === "overwritten") {
|
|
1033
|
+
return `Would overwrite ${result.directoryName} at ${result.destination} (${formatFileCount(result.filesCopied)}).`;
|
|
1034
|
+
}
|
|
1029
1035
|
return `Would install ${result.directoryName} to ${result.destination} (${formatFileCount(result.filesCopied)}).`;
|
|
1030
1036
|
}
|
|
1031
1037
|
if (result.result === "unchanged") {
|
|
1032
1038
|
return `Already installed ${result.directoryName} at ${result.destination} (unchanged).`;
|
|
1033
1039
|
}
|
|
1040
|
+
if (result.previous === "updated") {
|
|
1041
|
+
return `Updated ${result.directoryName} at ${result.destination} (${formatFileCount(result.filesCopied)}).`;
|
|
1042
|
+
}
|
|
1034
1043
|
const detail = result.previous === "overwritten"
|
|
1035
1044
|
? `overwrote existing copy, ${formatFileCount(result.filesCopied)}`
|
|
1036
1045
|
: formatFileCount(result.filesCopied);
|
|
@@ -1051,9 +1060,13 @@ function fanOutToJson(fanout) {
|
|
|
1051
1060
|
}
|
|
1052
1061
|
function formatFanOut(fanout) {
|
|
1053
1062
|
if (fanout.status === "skipped") {
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1063
|
+
if (fanout.reason === "dry-run") {
|
|
1064
|
+
return "fanout: planned";
|
|
1065
|
+
}
|
|
1066
|
+
if (fanout.reason === "unchanged") {
|
|
1067
|
+
return "fanout: unchanged";
|
|
1068
|
+
}
|
|
1069
|
+
return `fanout skipped: ${fanout.reason ?? "not available"}`;
|
|
1057
1070
|
}
|
|
1058
1071
|
if (fanout.status === "failed") {
|
|
1059
1072
|
return `fanout failed: ${fanout.reason ?? "unknown failure"}`;
|
|
@@ -2990,17 +3003,30 @@ function versionHasAncestor(snapshot, versionId, ancestorId) {
|
|
|
2990
3003
|
return false;
|
|
2991
3004
|
}
|
|
2992
3005
|
function displayRef(id) {
|
|
3006
|
+
return displayRefWithMinLength(id, 8);
|
|
3007
|
+
}
|
|
3008
|
+
function displayRefWithMinLength(id, minLength) {
|
|
2993
3009
|
const version = /^v_([0-9a-f]{8,})$/iu.exec(id);
|
|
2994
3010
|
if (version?.[1]) {
|
|
2995
|
-
return version[1].slice(0,
|
|
3011
|
+
return version[1].slice(0, minLength);
|
|
2996
3012
|
}
|
|
2997
3013
|
const separator = id.indexOf("_");
|
|
2998
3014
|
if (separator > 0 && separator < id.length - 1) {
|
|
2999
3015
|
const prefix = id.slice(0, separator);
|
|
3000
3016
|
const suffix = id.slice(separator + 1);
|
|
3001
|
-
return `${prefix}_${suffix.slice(0,
|
|
3017
|
+
return `${prefix}_${suffix.slice(0, minLength)}`;
|
|
3002
3018
|
}
|
|
3003
|
-
return id.length >
|
|
3019
|
+
return id.length > minLength ? id.slice(0, minLength) : id;
|
|
3020
|
+
}
|
|
3021
|
+
function displayRefsForIds(ids) {
|
|
3022
|
+
const uniqueIds = [...new Set(ids)];
|
|
3023
|
+
for (let length = 8; length <= 32; length += 1) {
|
|
3024
|
+
const refs = uniqueIds.map((id) => displayRefWithMinLength(id, length));
|
|
3025
|
+
if (new Set(refs).size === refs.length) {
|
|
3026
|
+
return new Map(uniqueIds.map((id, index) => [id, refs[index]]));
|
|
3027
|
+
}
|
|
3028
|
+
}
|
|
3029
|
+
return new Map(uniqueIds.map((id) => [id, id]));
|
|
3004
3030
|
}
|
|
3005
3031
|
function shortenCommandRefs(command) {
|
|
3006
3032
|
return command.replace(/\b(?:v_[0-9a-f]{8,}|(?:run|job|trace|artifact)_[a-z0-9_-]+)/giu, (match) => displayRef(match));
|
|
@@ -3167,8 +3193,16 @@ function evidencePathSegment(value) {
|
|
|
3167
3193
|
return value.replace(/[^A-Za-z0-9._-]+/gu, "-") || "_";
|
|
3168
3194
|
}
|
|
3169
3195
|
function formatRunOrJobEvidence(jobs, details, files) {
|
|
3170
|
-
const
|
|
3171
|
-
|
|
3196
|
+
const jobRefs = displayRefsForIds([
|
|
3197
|
+
...jobs.map((job) => job.id),
|
|
3198
|
+
...details.flatMap((detail) => detail.executions.flatMap((execution) => execution.jobIds)),
|
|
3199
|
+
]);
|
|
3200
|
+
const runRefs = displayRefsForIds([
|
|
3201
|
+
...jobs.map((job) => job.runId),
|
|
3202
|
+
...details.map((detail) => detail.runId),
|
|
3203
|
+
]);
|
|
3204
|
+
const jobLines = jobs.length > 0 ? ["Jobs:", ...jobs.map((job) => formatJobEvidenceSummary(job, jobRefs))] : [];
|
|
3205
|
+
const detailLines = details.map((detail) => formatTraceDetail(detail, { jobRefs, runRefs })).filter(Boolean);
|
|
3172
3206
|
const fileLines = files.length > 0 ? ["Files:", ...files.map((file) => file.path)] : [];
|
|
3173
3207
|
return [...jobLines, ...detailLines, ...fileLines].join("\n") || "No evidence.";
|
|
3174
3208
|
}
|
|
@@ -3183,9 +3217,9 @@ function jobEvidenceSummary(job) {
|
|
|
3183
3217
|
...(job.error ? { error: job.error } : {}),
|
|
3184
3218
|
};
|
|
3185
3219
|
}
|
|
3186
|
-
function formatJobEvidenceSummary(job) {
|
|
3220
|
+
function formatJobEvidenceSummary(job, refs = new Map()) {
|
|
3187
3221
|
return [
|
|
3188
|
-
displayRef(job.id),
|
|
3222
|
+
refs.get(job.id) ?? displayRef(job.id),
|
|
3189
3223
|
`case=${job.caseId}`,
|
|
3190
3224
|
`sample=${job.sample}`,
|
|
3191
3225
|
job.status,
|
|
@@ -3304,17 +3338,9 @@ function findShowFile(files, requestedPath, objectRef) {
|
|
|
3304
3338
|
if (candidates.length === 1) {
|
|
3305
3339
|
return candidates[0];
|
|
3306
3340
|
}
|
|
3307
|
-
const equivalentCandidate = singleEquivalentShowFile(candidates);
|
|
3308
|
-
if (equivalentCandidate) {
|
|
3309
|
-
return equivalentCandidate;
|
|
3310
|
-
}
|
|
3311
3341
|
if (candidates.length === 0 && suffixCandidates.length === 1) {
|
|
3312
3342
|
return suffixCandidates[0];
|
|
3313
3343
|
}
|
|
3314
|
-
const equivalentSuffixCandidate = singleEquivalentShowFile(suffixCandidates);
|
|
3315
|
-
if (equivalentSuffixCandidate) {
|
|
3316
|
-
return equivalentSuffixCandidate;
|
|
3317
|
-
}
|
|
3318
3344
|
throw ambiguousShowPath(objectRef, requestedPath, candidates.length > 0 ? candidates : suffixCandidates);
|
|
3319
3345
|
}
|
|
3320
3346
|
function singleEquivalentShowFile(files) {
|
|
@@ -3672,11 +3698,11 @@ function traceSummary(trace) {
|
|
|
3672
3698
|
files: trace.files.map(fileSummary),
|
|
3673
3699
|
};
|
|
3674
3700
|
}
|
|
3675
|
-
function formatTraceDetail(detail) {
|
|
3701
|
+
function formatTraceDetail(detail, refs = {}) {
|
|
3676
3702
|
return detail.executions.map((execution) => {
|
|
3677
3703
|
const sessionLabels = execution.sessions.map((session) => session.label).join(",");
|
|
3678
3704
|
return [
|
|
3679
|
-
`${execution.id}\trun=${displayRef(detail.runId)}\tjobs=${execution.jobIds.map(displayRef).join(",")}\tstatus=${execution.status}`,
|
|
3705
|
+
`${execution.id}\trun=${refs.runRefs?.get(detail.runId) ?? displayRef(detail.runId)}\tjobs=${execution.jobIds.map((id) => refs.jobRefs?.get(id) ?? displayRef(id)).join(",")}\tstatus=${execution.status}`,
|
|
3680
3706
|
`events=${execution.trace.events.length}`,
|
|
3681
3707
|
`spans=${execution.trace.spans.length}`,
|
|
3682
3708
|
`summaries=${execution.trace.summaries.length}`,
|
|
@@ -18,7 +18,7 @@ export interface WorkbenchInstallStoreResult {
|
|
|
18
18
|
store: StoreKind;
|
|
19
19
|
directoryName: string;
|
|
20
20
|
destination: string;
|
|
21
|
-
previous: "none" | "overwritten" | "unchanged";
|
|
21
|
+
previous: "none" | "updated" | "overwritten" | "unchanged";
|
|
22
22
|
filesCopied: number;
|
|
23
23
|
contentHash: string;
|
|
24
24
|
provenancePath: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-targets.d.ts","sourceRoot":"","sources":["../src/install-targets.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiC,KAAK,IAAI,EAAE,KAAK,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAMlH,KAAK,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAErC,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,mBAAmB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gCAAiC,SAAQ,+BAA+B;IACvF,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAOD,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,WAAW,CAAC;IAC9C,KAAK,EAAE,SAAS,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"install-targets.d.ts","sourceRoot":"","sources":["../src/install-targets.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiC,KAAK,IAAI,EAAE,KAAK,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAMlH,KAAK,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAErC,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,mBAAmB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gCAAiC,SAAQ,+BAA+B;IACvF,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAOD,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,WAAW,CAAC;IAC9C,KAAK,EAAE,SAAS,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;IAC3D,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,6BAA6B,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAC;AAE5F,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,SAAS,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,6BAA6B,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAClC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,wBAAgB,sBAAsB,CAAC,SAAS,SAAyB,GAAG,MAAM,CAEjF;AAED,wBAAsB,sBAAsB,CAAC,OAAO,EAAE;IACpD,QAAQ,EAAE,wBAAwB,CAAC;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,+BAA+B,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAgEvC;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,wBAAwB,GAAG,MAAM,CAStF;AAWD,wBAAsB,4BAA4B,CAAC,OAAO,GAAE;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,gCAAgC,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CAC5F,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAe5C;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,2BAA2B,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAuBrG;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAgBrE"}
|
package/dist/install-targets.js
CHANGED
|
@@ -13,12 +13,14 @@ export function provenancePathForStore(storeRoot = canonicalSkillsStore()) {
|
|
|
13
13
|
}
|
|
14
14
|
export async function installSnapshotToStore(options) {
|
|
15
15
|
const skillName = canonicalSkillDirectoryName(options.snapshot);
|
|
16
|
-
const
|
|
16
|
+
const storeRoot = canonicalSkillsStore();
|
|
17
|
+
const destination = path.join(storeRoot, skillName);
|
|
17
18
|
const normalizedFiles = options.snapshot.files.map((file) => ({
|
|
18
19
|
...file,
|
|
19
20
|
path: normalizeInstallSnapshotPath(file.path),
|
|
20
21
|
}));
|
|
21
22
|
const contentHash = contentHashForFiles(normalizedFiles);
|
|
23
|
+
const provenance = await readProvenanceFile(storeRoot);
|
|
22
24
|
const existingHash = await readExistingTreeHash(destination).catch((error) => {
|
|
23
25
|
const code = error.code;
|
|
24
26
|
if (code === "ENOENT") {
|
|
@@ -34,10 +36,16 @@ export async function installSnapshotToStore(options) {
|
|
|
34
36
|
}
|
|
35
37
|
throw error;
|
|
36
38
|
});
|
|
39
|
+
const existingRecord = provenance.skills[skillName];
|
|
40
|
+
const canUpdateExisting = Boolean(existingHash &&
|
|
41
|
+
existingRecord &&
|
|
42
|
+
existingHash === existingRecord.contentHash &&
|
|
43
|
+
existingRecord.handle === options.provenance.handle &&
|
|
44
|
+
existingRecord.baseUrl === options.provenance.baseUrl);
|
|
37
45
|
const previous = existingHash
|
|
38
|
-
? existingHash === contentHash ? "unchanged" : "overwritten"
|
|
46
|
+
? existingHash === contentHash ? "unchanged" : canUpdateExisting ? "updated" : "overwritten"
|
|
39
47
|
: "none";
|
|
40
|
-
if (existingHash && previous
|
|
48
|
+
if (existingHash && previous === "overwritten" && !options.overwrite) {
|
|
41
49
|
throw new WorkbenchCodedError("install_failed", `Canonical skill already exists: ${destination}`, {
|
|
42
50
|
remediation: "Pass --yes to overwrite the existing canonical store skill.",
|
|
43
51
|
subject: { destination },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workbench-ai/workbench",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.85",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/workbench-ai/workbench.git",
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"skills": "1.5.11",
|
|
24
24
|
"yaml": "^2.8.2",
|
|
25
|
-
"@workbench-ai/workbench-
|
|
26
|
-
"@workbench-ai/workbench-
|
|
27
|
-
"@workbench-ai/workbench-
|
|
28
|
-
"@workbench-ai/workbench-contract": "0.0.
|
|
25
|
+
"@workbench-ai/workbench-built-in-adapters": "0.0.85",
|
|
26
|
+
"@workbench-ai/workbench-protocol": "0.0.85",
|
|
27
|
+
"@workbench-ai/workbench-core": "0.0.85",
|
|
28
|
+
"@workbench-ai/workbench-contract": "0.0.85"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@tailwindcss/postcss": "^4.2.2",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"react-dom": "^19.2.0",
|
|
37
37
|
"typescript": "^5.9.2",
|
|
38
38
|
"vitest": "^3.2.4",
|
|
39
|
-
"@workbench-ai/workbench-ui": "0.0.
|
|
39
|
+
"@workbench-ai/workbench-ui": "0.0.85"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build": "rm -rf dist && tsc -p tsconfig.json && chmod 755 dist/workbench.js && node ./scripts/build-dev-open-assets.mjs",
|