@workbench-ai/workbench 0.0.94 → 0.0.96

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiEA,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;CAC/B;AAuTD,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,GAAE,KAGzD,GAAG,OAAO,CAAC,MAAM,CAAC,CAmNlB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiEA,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;CAC/B;AAuTD,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,GAAE,KAGzD,GAAG,OAAO,CAAC,MAAM,CAAC,CA0NlB"}
package/dist/index.js CHANGED
@@ -102,7 +102,7 @@ const COMMAND_HELP = {
102
102
  "Installs published source into the canonical machine skill store, or lists installed skills when no source is given.",
103
103
  "",
104
104
  "Example:",
105
- " workbench install acme/earnings-prep",
105
+ " workbench install test/workbench-smoke",
106
106
  ].join("\n"),
107
107
  status: [
108
108
  "Usage:",
@@ -195,7 +195,7 @@ const COMMAND_HELP = {
195
195
  "Publishes installable skill source to Workbench Cloud. --as sets the linked OWNER/SKILL handle.",
196
196
  "",
197
197
  "Example:",
198
- " workbench publish --as acme/earnings-prep --dry-run",
198
+ " workbench publish --as OWNER/SKILL --dry-run",
199
199
  ].join("\n"),
200
200
  login: [
201
201
  "Usage:",
@@ -418,6 +418,9 @@ export async function runCli(argv, io = {
418
418
  const beforeRuns = parsed.flags["dry-run"] === true
419
419
  ? undefined
420
420
  : await runEvidenceFingerprints(core).catch(() => undefined);
421
+ if (parsed.flags["dry-run"] !== true) {
422
+ writeCliProgress(io, `workbench sync: syncing ${optionalPositional(parsed, 1) ?? "default remote"}.`);
423
+ }
421
424
  const result = await syncWorkbenchRemote({
422
425
  ...core,
423
426
  remote: optionalPositional(parsed, 1),
@@ -443,23 +446,26 @@ export async function runCli(argv, io = {
443
446
  ? await previewPublishWithDerivedRemote(parsed)
444
447
  : undefined;
445
448
  if (preview) {
449
+ const audience = publishAudience(preview.visibility);
446
450
  return emitResult("workbench.cli.publish.v1", {
447
451
  remote: preview.remote,
448
452
  version: versionSummary(preview.version),
449
- visibility: preview.visibility,
453
+ visibility: audience,
450
454
  installHandle: preview.installHandle,
451
455
  installUrl: preview.installUrl,
452
456
  pinnedInstallUrl: preview.pinnedInstallUrl,
453
457
  dryRun: true,
454
458
  }, parsed, io, () => [
455
- `Would publish ${displayRef(preview.version.id)} as ${preview.installHandle} (${preview.visibility}).`,
459
+ `Would publish ${displayRef(preview.version.id)} as ${preview.installHandle} (${audience}).`,
456
460
  `next: workbench install ${preview.installHandle}`,
457
461
  ].join("\n"));
458
462
  }
459
463
  let remote;
460
464
  let result;
461
465
  try {
466
+ writeCliProgress(io, "workbench publish: preparing Cloud skill.");
462
467
  remote = await ensurePublishRemote(parsed);
468
+ writeCliProgress(io, `workbench publish: publishing ${optionalPositional(parsed, 1) ?? "current"} source.`);
463
469
  result = await publishWorkbenchVersion({
464
470
  ...core,
465
471
  version: optionalPositional(parsed, 1),
@@ -471,16 +477,17 @@ export async function runCli(argv, io = {
471
477
  catch (error) {
472
478
  throw await publishErrorWithCliContext(error, parsed, remote);
473
479
  }
480
+ const audience = publishAudience(result.visibility);
474
481
  return emitResult("workbench.cli.publish.v1", {
475
482
  remote: result.remote,
476
483
  version: versionSummary(result.version),
477
- visibility: result.visibility,
484
+ visibility: audience,
478
485
  installHandle: result.installHandle,
479
486
  installUrl: result.installUrl,
480
487
  pinnedInstallUrl: result.pinnedInstallUrl,
481
488
  ...(result.dryRun ? { dryRun: true } : {}),
482
489
  }, parsed, io, () => [
483
- `${result.dryRun ? "Would publish" : "Published"} ${displayRef(result.version.id)} as ${result.installHandle} (${result.visibility}).`,
490
+ `${result.dryRun ? "Would publish" : "Published"} ${displayRef(result.version.id)} as ${result.installHandle} (${audience}).`,
484
491
  `next: workbench install ${result.installHandle}`,
485
492
  ].join("\n"));
486
493
  }
@@ -872,7 +879,7 @@ async function handleLogout(parsed, io) {
872
879
  revoke = "failed";
873
880
  }
874
881
  }
875
- const configRemoved = tokenPresent;
882
+ const tokenRemoved = tokenPresent;
876
883
  if (tokenPresent) {
877
884
  await writeConfig({ schema: CONFIG_SCHEMA, ...(baseUrl ? { baseUrl } : {}) });
878
885
  }
@@ -880,11 +887,11 @@ async function handleLogout(parsed, io) {
880
887
  ...(baseUrl ? { baseUrl } : {}),
881
888
  tokenPresent,
882
889
  revoke,
883
- configRemoved,
890
+ tokenRemoved,
884
891
  adapterAuth: "unchanged",
885
892
  }, parsed, io, () => [
886
893
  `Logged out of Workbench${baseUrl ? ` (${baseUrl})` : ""}.`,
887
- `Token: ${tokenPresent ? "present" : "absent"}; revoke ${revoke}; config ${configRemoved ? "removed" : "unchanged"}.`,
894
+ `Token: ${tokenPresent ? "present" : "absent"}; revoke ${revoke}; token ${tokenRemoved ? "removed" : "unchanged"}.`,
888
895
  "Local adapter auth unchanged; run workbench logout PROVIDER to remove provider credentials.",
889
896
  ].join("\n"));
890
897
  }
@@ -1005,7 +1012,7 @@ async function handleCloudImprove(parsed, io) {
1005
1012
  if (failedRuns.length > 0) {
1006
1013
  const first = failedRuns[0];
1007
1014
  throw new WorkbenchCodedError("improve_failed", "Hosted improve failed; evidence was saved.", {
1008
- remediation: `Run workbench show ${first.id}.`,
1015
+ remediation: `workbench show ${first.id}`,
1009
1016
  subject: {
1010
1017
  runIds: failedRuns.map((run) => run.id),
1011
1018
  statuses: Object.fromEntries(failedRuns.map((run) => [run.id, run.status])),
@@ -1136,7 +1143,7 @@ async function startCloudExecution(command, parsed, io) {
1136
1143
  if (runs.length === 0) {
1137
1144
  throw new WorkbenchCodedError("cloud_run_missing", `Workbench Cloud did not return a run for ${command}.`, {
1138
1145
  retryable: true,
1139
- remediation: "Run workbench log --runs.",
1146
+ remediation: "workbench log --runs",
1140
1147
  subject: { remote: remote.name, skillId },
1141
1148
  exitCode: 1,
1142
1149
  });
@@ -1221,7 +1228,7 @@ async function cloudPreScheduleStep(command, interrupt, step) {
1221
1228
  }
1222
1229
  function cloudCanceledBeforeRunIdError(command) {
1223
1230
  return new WorkbenchCodedError("cloud_canceled", `Hosted ${command} was canceled before Workbench Cloud returned a run id.`, {
1224
- remediation: `Run workbench ${command} --cloud.`,
1231
+ remediation: `workbench ${command} --cloud`,
1225
1232
  exitCode: 130,
1226
1233
  });
1227
1234
  }
@@ -1308,7 +1315,7 @@ async function waitForCloudRuns(input) {
1308
1315
  if (runIds.length === 0 || runIds.length !== input.runs.length) {
1309
1316
  throw new WorkbenchCodedError("cloud_run_missing", "Workbench Cloud did not return a run id.", {
1310
1317
  retryable: true,
1311
- remediation: "Run workbench log --runs.",
1318
+ remediation: "workbench log --runs",
1312
1319
  exitCode: 1,
1313
1320
  });
1314
1321
  }
@@ -1349,7 +1356,7 @@ async function waitForCloudRuns(input) {
1349
1356
  if (Date.now() >= deadline) {
1350
1357
  throw new WorkbenchCodedError("cloud_run_pending", "Hosted Workbench run is still running.", {
1351
1358
  retryable: true,
1352
- remediation: runIds[0] ? `Run workbench show ${runIds[0]}.` : "Run workbench log --runs.",
1359
+ remediation: runIds[0] ? `workbench show ${runIds[0]}` : "workbench log --runs",
1353
1360
  subject: {
1354
1361
  runIds,
1355
1362
  statuses: Object.fromEntries(runs.map((run) => [run.id, run.status])),
@@ -1592,6 +1599,9 @@ function writeCloudProgress(io, message, enabled = true) {
1592
1599
  }
1593
1600
  io.stderr.write(`${message}\n`);
1594
1601
  }
1602
+ function writeCliProgress(io, message) {
1603
+ io.stderr.write(`${message}\n`);
1604
+ }
1595
1605
  function formatCloudRunStatuses(runs) {
1596
1606
  return runs.length > 0
1597
1607
  ? runs.map((run) => `${displayRef(run.id)}:${run.status}`).join(", ")
@@ -2199,10 +2209,10 @@ function authMethod(parsed, adapterId) {
2199
2209
  return explicit;
2200
2210
  }
2201
2211
  if (adapterId === "codex") {
2202
- return process.env.OPENAI_API_KEY ? "api-key" : "oauth";
2212
+ return "oauth";
2203
2213
  }
2204
2214
  if (adapterId === "claude") {
2205
- return process.env.ANTHROPIC_API_KEY ? "api-key" : "oauth";
2215
+ return "oauth";
2206
2216
  }
2207
2217
  return "env";
2208
2218
  }
@@ -2220,7 +2230,10 @@ async function collectAdapterAuthBundle(args) {
2220
2230
  return createWorkbenchAdapterAuthBundle({
2221
2231
  target: args.target,
2222
2232
  method: args.method,
2223
- files: [await requiredAuthFile(args.profileRoot, ".codex/auth.json")],
2233
+ files: [await requiredAuthFile(args.profileRoot, ".codex/auth.json", {
2234
+ provider: "Codex",
2235
+ remediation: "codex login --device-auth && workbench login codex --method oauth",
2236
+ })],
2224
2237
  });
2225
2238
  }
2226
2239
  }
@@ -2233,16 +2246,21 @@ async function collectAdapterAuthBundle(args) {
2233
2246
  });
2234
2247
  }
2235
2248
  if (args.method === "oauth") {
2249
+ const profile = await requiredAuthFile(args.profileRoot, ".claude.json", {
2250
+ provider: "Claude auth",
2251
+ remediation: "claude setup-token && workbench login claude --method oauth",
2252
+ });
2253
+ const portableToken = await requiredAnyAuthFile(args.profileRoot, [
2254
+ ".claude/oauth-token",
2255
+ ".claude/.credentials.json",
2256
+ ], {
2257
+ provider: "Claude portable OAuth token",
2258
+ remediation: "claude setup-token && workbench login claude --method oauth",
2259
+ });
2236
2260
  return createWorkbenchAdapterAuthBundle({
2237
2261
  target: args.target,
2238
2262
  method: args.method,
2239
- files: [
2240
- await requiredAuthFile(args.profileRoot, ".claude.json"),
2241
- ...await optionalAuthFiles(args.profileRoot, [
2242
- ".claude/oauth-token",
2243
- ".claude/.credentials.json",
2244
- ]),
2245
- ],
2263
+ files: [profile, portableToken],
2246
2264
  });
2247
2265
  }
2248
2266
  if (args.method === "bedrock") {
@@ -2277,13 +2295,32 @@ function requiredEnvVars(required, optional = [], remediation) {
2277
2295
  return value ? [[name, value]] : [];
2278
2296
  }));
2279
2297
  }
2280
- async function requiredAuthFile(root, relativePath) {
2298
+ async function requiredAuthFile(root, relativePath, guidance) {
2281
2299
  const file = await readAuthFile(root, relativePath);
2282
2300
  if (!file) {
2283
- throw new WorkbenchUserError(`Missing auth file: ${path.join(root, relativePath)}`);
2301
+ const absolute = path.join(root, relativePath);
2302
+ throw new WorkbenchCodedError("provider_oauth_missing", guidance
2303
+ ? `Missing ${guidance.provider} OAuth token file: ${absolute}`
2304
+ : `Missing auth file: ${absolute}`, {
2305
+ ...(guidance ? { remediation: guidance.remediation } : {}),
2306
+ subject: { path: absolute, relativePath },
2307
+ exitCode: 2,
2308
+ });
2284
2309
  }
2285
2310
  return file;
2286
2311
  }
2312
+ async function requiredAnyAuthFile(root, paths, guidance) {
2313
+ const files = await optionalAuthFiles(root, paths);
2314
+ const [file] = files;
2315
+ if (file) {
2316
+ return file;
2317
+ }
2318
+ throw new WorkbenchCodedError("provider_oauth_missing", `Missing ${guidance.provider} file: ${paths.map((entry) => path.join(root, entry)).join(" or ")}`, {
2319
+ remediation: guidance.remediation,
2320
+ subject: { paths: paths.map((entry) => path.join(root, entry)), relativePaths: [...paths] },
2321
+ exitCode: 2,
2322
+ });
2323
+ }
2287
2324
  async function optionalAuthFiles(root, paths) {
2288
2325
  const files = await Promise.all(paths.map((entry) => readAuthFile(root, entry)));
2289
2326
  return files.filter((entry) => Boolean(entry));
@@ -2671,6 +2708,9 @@ async function previewPublishWithDerivedRemote(parsed) {
2671
2708
  function normalizePublishVisibility(value) {
2672
2709
  return value === "private" || value === "internal" || value === "public" ? value : undefined;
2673
2710
  }
2711
+ function publishAudience(visibility) {
2712
+ return visibility === "internal" ? "team" : visibility;
2713
+ }
2674
2714
  async function ensurePublishRemote(parsed) {
2675
2715
  const core = await coreOptions(parsed);
2676
2716
  const root = path.resolve(dirFlag(parsed) ?? process.cwd());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workbench-ai/workbench",
3
- "version": "0.0.94",
3
+ "version": "0.0.96",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/workbench-ai/workbench.git",
@@ -21,10 +21,10 @@
21
21
  ],
22
22
  "dependencies": {
23
23
  "yaml": "^2.8.2",
24
- "@workbench-ai/workbench-built-in-adapters": "0.0.94",
25
- "@workbench-ai/workbench-core": "0.0.94",
26
- "@workbench-ai/workbench-protocol": "0.0.94",
27
- "@workbench-ai/workbench-contract": "0.0.94"
24
+ "@workbench-ai/workbench-built-in-adapters": "0.0.96",
25
+ "@workbench-ai/workbench-protocol": "0.0.96",
26
+ "@workbench-ai/workbench-core": "0.0.96",
27
+ "@workbench-ai/workbench-contract": "0.0.96"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@tailwindcss/postcss": "^4.2.2",
@@ -35,7 +35,7 @@
35
35
  "react-dom": "^19.2.0",
36
36
  "typescript": "^5.9.2",
37
37
  "vitest": "^3.2.4",
38
- "@workbench-ai/workbench-ui": "0.0.94"
38
+ "@workbench-ai/workbench-ui": "0.0.96"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "rm -rf dist && tsc -p tsconfig.json && chmod 755 dist/workbench.js && node ./scripts/build-dev-open-assets.mjs",