@workbench-ai/workbench 0.0.84 → 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 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: "dry-run",
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
- return fanout.reason === "dry-run"
1055
- ? "fanout: planned"
1056
- : `fanout skipped: ${fanout.reason ?? "not available"}`;
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"}`;
@@ -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":"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"}
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"}
@@ -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 destination = path.join(canonicalSkillsStore(), skillName);
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 !== "unchanged" && !options.overwrite) {
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.84",
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-built-in-adapters": "0.0.84",
26
- "@workbench-ai/workbench-contract": "0.0.84",
27
- "@workbench-ai/workbench-protocol": "0.0.84",
28
- "@workbench-ai/workbench-core": "0.0.84"
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.84"
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",