@workbench-ai/workbench 0.0.74 → 0.0.75
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/dev-open/client.css +0 -6
- package/dist/dev-open/client.js +113 -113
- package/dist/fanout.js +35 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -75
- package/package.json +6 -6
package/dist/fanout.js
CHANGED
|
@@ -34,7 +34,7 @@ export async function fanOutSkill(name, options) {
|
|
|
34
34
|
"--global",
|
|
35
35
|
"--yes",
|
|
36
36
|
];
|
|
37
|
-
const child = await runNode(args,
|
|
37
|
+
const child = await runNode(args, minimalChildEnv(process.env), FANOUT_TIMEOUT_MS);
|
|
38
38
|
const { linkedAgents, additionalAgents } = parseFanOutAgents(`${child.stdout}\n${child.stderr}`);
|
|
39
39
|
if (child.timedOut) {
|
|
40
40
|
return {
|
|
@@ -143,29 +143,40 @@ function runNode(args, env, timeoutMs) {
|
|
|
143
143
|
});
|
|
144
144
|
});
|
|
145
145
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
"
|
|
154
|
-
"
|
|
155
|
-
"
|
|
156
|
-
"
|
|
157
|
-
"
|
|
158
|
-
"
|
|
159
|
-
"
|
|
160
|
-
"
|
|
161
|
-
"
|
|
162
|
-
"
|
|
163
|
-
"
|
|
164
|
-
"
|
|
165
|
-
"
|
|
166
|
-
"
|
|
167
|
-
|
|
168
|
-
|
|
146
|
+
// The skills CLI changes behavior when it detects it is running inside an
|
|
147
|
+
// agent (via @vercel/detect-agent reading agent-specific environment
|
|
148
|
+
// variables). Fan-out must always run in machine mode, so the child gets a
|
|
149
|
+
// minimal allowlisted environment instead of a hand-maintained blacklist of
|
|
150
|
+
// every agent's marker variables.
|
|
151
|
+
function minimalChildEnv(env) {
|
|
152
|
+
const allowed = [
|
|
153
|
+
"PATH",
|
|
154
|
+
"HOME",
|
|
155
|
+
"USER",
|
|
156
|
+
"SHELL",
|
|
157
|
+
"TMPDIR",
|
|
158
|
+
"TMP",
|
|
159
|
+
"TEMP",
|
|
160
|
+
"LANG",
|
|
161
|
+
"NODE_EXTRA_CA_CERTS",
|
|
162
|
+
"HTTP_PROXY",
|
|
163
|
+
"HTTPS_PROXY",
|
|
164
|
+
"NO_PROXY",
|
|
165
|
+
"http_proxy",
|
|
166
|
+
"https_proxy",
|
|
167
|
+
"no_proxy",
|
|
168
|
+
"SYSTEMROOT",
|
|
169
|
+
"SystemRoot",
|
|
170
|
+
"COMSPEC",
|
|
171
|
+
"APPDATA",
|
|
172
|
+
"LOCALAPPDATA",
|
|
173
|
+
"USERPROFILE",
|
|
174
|
+
];
|
|
175
|
+
const next = {};
|
|
176
|
+
for (const key of Object.keys(env)) {
|
|
177
|
+
if (allowed.includes(key) || key.startsWith("XDG_") || key.startsWith("LC_")) {
|
|
178
|
+
next[key] = env[key];
|
|
179
|
+
}
|
|
169
180
|
}
|
|
170
181
|
return next;
|
|
171
182
|
}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAgEA,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,CAoMlB"}
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { createRequire } from "node:module";
|
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { gzipSync } from "node:zlib";
|
|
7
|
-
import { addWorkbenchRemote, addWorkbenchAgent, compareWorkbench, createWorkbenchInspectionSnapshot, createWorkbenchAdapterAuthBundle, createWorkbenchReadOnlyInspectionSnapshot, diffWorkbenchVersions, evalWorkbenchSkill, improveWorkbenchSkill, initWorkbenchSkill, listWorkbenchAgents, listWorkbenchVersions, localWorkbenchAdapterAuthStore, parseWorkbenchAdapterAuthTarget, prepareWorkbenchCloudEvalRequest, prepareWorkbenchCloudImproveRequest, publishWorkbenchVersion, removeWorkbenchAgent, showWorkbenchRef, switchWorkbenchVersion, syncWorkbenchRemote, workbenchJobEvidenceForSnapshot,
|
|
7
|
+
import { addWorkbenchRemote, addWorkbenchAgent, compareWorkbench, createWorkbenchInspectionSnapshot, createWorkbenchAdapterAuthBundle, createWorkbenchReadOnlyInspectionSnapshot, diffWorkbenchVersions, evalWorkbenchSkill, improveWorkbenchSkill, initWorkbenchSkill, listWorkbenchAgents, listWorkbenchVersions, localWorkbenchAdapterAuthStore, parseWorkbenchAdapterAuthTarget, prepareWorkbenchCloudEvalRequest, prepareWorkbenchCloudImproveRequest, publishWorkbenchVersion, removeWorkbenchAgent, showWorkbenchRef, switchWorkbenchVersion, syncWorkbenchRemote, workbenchJobEvidenceForSnapshot, workbenchStatusSnapshot, WorkbenchCodedError, WorkbenchUserError, } from "@workbench-ai/workbench-core";
|
|
8
8
|
import { normalizeWorkbenchSkillName } from "@workbench-ai/workbench-contract";
|
|
9
9
|
import { emitError, emitResult } from "./output.js";
|
|
10
10
|
import { fanOutSkill, manualFanOutCommand } from "./fanout.js";
|
|
@@ -375,12 +375,10 @@ export async function runCli(argv, io = {
|
|
|
375
375
|
if (parsed.flags.cloud === true) {
|
|
376
376
|
return await handleCloudImprove(parsed, io);
|
|
377
377
|
}
|
|
378
|
-
const improverAgent = await resolveLocalImproverAgent(parsed, core);
|
|
379
378
|
const result = await improveWorkbenchSkill({
|
|
380
379
|
...core,
|
|
381
380
|
skill: stringFlag(parsed, "skills"),
|
|
382
381
|
agent: stringFlag(parsed, "agents"),
|
|
383
|
-
...(improverAgent ? { improverAgent } : {}),
|
|
384
382
|
budget: intFlag(parsed, "budget"),
|
|
385
383
|
samples: intFlag(parsed, "samples"),
|
|
386
384
|
});
|
|
@@ -1110,15 +1108,9 @@ async function startCloudExecution(command, parsed, io) {
|
|
|
1110
1108
|
exitCode: 1,
|
|
1111
1109
|
});
|
|
1112
1110
|
}
|
|
1111
|
+
const syncAfterSchedule = await syncWorkbenchRemote({ ...core, remote: remote.name });
|
|
1113
1112
|
const initialRunIds = runs.map((run) => run.id);
|
|
1114
1113
|
writeCloudProgress(io, `workbench cloud: scheduled hosted ${command} on ${remote.url} (${formatCloudRunStatuses(runs)}).`, showProgress);
|
|
1115
|
-
let initialSyncAfter = syncBefore;
|
|
1116
|
-
try {
|
|
1117
|
-
initialSyncAfter = await syncWorkbenchRemote({ ...core, remote: remote.name });
|
|
1118
|
-
}
|
|
1119
|
-
catch (error) {
|
|
1120
|
-
writeCloudProgress(io, `workbench cloud: sync while waiting failed; retrying (${oneLineExcerpt(errorMessage(error)) ?? "unknown error"}).`, showProgress);
|
|
1121
|
-
}
|
|
1122
1114
|
writeCloudProgress(io, `workbench cloud: waiting for terminal status; press Ctrl-C to detach and resume with workbench show ${displayRef(initialRunIds[0] ?? "run")}.`, showProgress);
|
|
1123
1115
|
const completed = await waitForCloudRuns({
|
|
1124
1116
|
command,
|
|
@@ -1127,7 +1119,9 @@ async function startCloudExecution(command, parsed, io) {
|
|
|
1127
1119
|
progress: showProgress,
|
|
1128
1120
|
remote,
|
|
1129
1121
|
runs,
|
|
1130
|
-
|
|
1122
|
+
source,
|
|
1123
|
+
skillId,
|
|
1124
|
+
initialSync: syncAfterSchedule,
|
|
1131
1125
|
});
|
|
1132
1126
|
return {
|
|
1133
1127
|
core,
|
|
@@ -1163,7 +1157,6 @@ async function waitForCloudRuns(input) {
|
|
|
1163
1157
|
let interrupted = false;
|
|
1164
1158
|
const startedAtMs = Date.now();
|
|
1165
1159
|
let lastProgressAtMs = startedAtMs;
|
|
1166
|
-
let lastSyncErrorMessage;
|
|
1167
1160
|
const onSigint = () => {
|
|
1168
1161
|
interrupted = true;
|
|
1169
1162
|
writeCloudProgress(input.io, `workbench cloud: detaching from hosted ${input.command} (${runIds.map(displayRef).join(", ")}).`, input.progress);
|
|
@@ -1172,14 +1165,7 @@ async function waitForCloudRuns(input) {
|
|
|
1172
1165
|
const seenStatuses = new Map();
|
|
1173
1166
|
try {
|
|
1174
1167
|
while (true) {
|
|
1175
|
-
|
|
1176
|
-
const snapshotRuns = runIds
|
|
1177
|
-
.map((id) => snapshot.runs.find((entry) => entry.id === id))
|
|
1178
|
-
.filter((run) => Boolean(run));
|
|
1179
|
-
if (snapshotRuns.length > 0) {
|
|
1180
|
-
runs = runIds.map((id) => snapshotRuns.find((entry) => entry.id === id) ?? runs.find((entry) => entry.id === id))
|
|
1181
|
-
.filter((run) => Boolean(run));
|
|
1182
|
-
}
|
|
1168
|
+
runs = await fetchCloudRuns(input.source.baseUrl, input.skillId, runIds, runs);
|
|
1183
1169
|
let wroteProgress = false;
|
|
1184
1170
|
const nowMs = Date.now();
|
|
1185
1171
|
for (const run of runs) {
|
|
@@ -1191,6 +1177,7 @@ async function waitForCloudRuns(input) {
|
|
|
1191
1177
|
}
|
|
1192
1178
|
}
|
|
1193
1179
|
if (runs.length === runIds.length && runs.every(isTerminalRun)) {
|
|
1180
|
+
sync = await syncWorkbenchRemote({ ...input.core, remote: input.remote.name });
|
|
1194
1181
|
return { runs, sync };
|
|
1195
1182
|
}
|
|
1196
1183
|
if (wroteProgress) {
|
|
@@ -1218,26 +1205,18 @@ async function waitForCloudRuns(input) {
|
|
|
1218
1205
|
if (interrupted) {
|
|
1219
1206
|
return { runs, sync, detached: true };
|
|
1220
1207
|
}
|
|
1221
|
-
try {
|
|
1222
|
-
sync = await syncWorkbenchRemote({ ...input.core, remote: input.remote.name });
|
|
1223
|
-
if (lastSyncErrorMessage) {
|
|
1224
|
-
writeCloudProgress(input.io, "workbench cloud: sync while waiting recovered.", input.progress);
|
|
1225
|
-
lastSyncErrorMessage = undefined;
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1228
|
-
catch (error) {
|
|
1229
|
-
const message = oneLineExcerpt(errorMessage(error)) ?? "unknown error";
|
|
1230
|
-
if (message !== lastSyncErrorMessage) {
|
|
1231
|
-
writeCloudProgress(input.io, `workbench cloud: sync while waiting failed; retrying (${message}).`, input.progress);
|
|
1232
|
-
lastSyncErrorMessage = message;
|
|
1233
|
-
}
|
|
1234
|
-
}
|
|
1235
1208
|
}
|
|
1236
1209
|
}
|
|
1237
1210
|
finally {
|
|
1238
1211
|
process.off("SIGINT", onSigint);
|
|
1239
1212
|
}
|
|
1240
1213
|
}
|
|
1214
|
+
async function fetchCloudRuns(baseUrl, skillId, runIds, fallback) {
|
|
1215
|
+
const responses = await Promise.all(runIds.map((runId) => apiRequest(`/api/workbench/skills/${encodeURIComponent(skillId)}/runs/${encodeURIComponent(runId)}`, {}, baseUrl)));
|
|
1216
|
+
return runIds
|
|
1217
|
+
.map((runId, index) => responses[index]?.run ?? fallback.find((run) => run.id === runId))
|
|
1218
|
+
.filter((run) => Boolean(run));
|
|
1219
|
+
}
|
|
1241
1220
|
function isTerminalRun(run) {
|
|
1242
1221
|
return run.status === "succeeded" || run.status === "failed" || run.status === "canceled";
|
|
1243
1222
|
}
|
|
@@ -1353,15 +1332,11 @@ async function resolveCloudSkillId(source) {
|
|
|
1353
1332
|
function cloudExecutionRequestBody(command, request) {
|
|
1354
1333
|
return {
|
|
1355
1334
|
versionId: request.versionId,
|
|
1356
|
-
evalHash: request.evalHash,
|
|
1357
1335
|
skill: request.skill,
|
|
1358
|
-
skillBundleHash: request.skillBundleHash,
|
|
1359
1336
|
agent: request.agent,
|
|
1360
|
-
agentHash: request.agentHash,
|
|
1361
1337
|
samples: request.samples,
|
|
1362
1338
|
...(command === "improve" ? {
|
|
1363
1339
|
budget: request.budget,
|
|
1364
|
-
evidenceTraceIds: request.evidenceTraceIds,
|
|
1365
1340
|
} : {}),
|
|
1366
1341
|
};
|
|
1367
1342
|
}
|
|
@@ -2701,10 +2676,10 @@ async function workbenchMachineStatus(auth) {
|
|
|
2701
2676
|
};
|
|
2702
2677
|
}
|
|
2703
2678
|
function scoredRunValue(run) {
|
|
2704
|
-
return
|
|
2679
|
+
return typeof run.score === "number" ? run.score : undefined;
|
|
2705
2680
|
}
|
|
2706
2681
|
function scoredJobValue(job) {
|
|
2707
|
-
return
|
|
2682
|
+
return typeof job.score === "number" ? job.score : undefined;
|
|
2708
2683
|
}
|
|
2709
2684
|
function snapshotHasWorkflowCase(snapshot) {
|
|
2710
2685
|
const currentVersion = snapshotVersionByRef(snapshot, snapshot.status.currentVersionId ?? snapshot.refs.current ?? "");
|
|
@@ -2981,41 +2956,6 @@ function manifestOnly(value) {
|
|
|
2981
2956
|
}
|
|
2982
2957
|
return out;
|
|
2983
2958
|
}
|
|
2984
|
-
async function resolveLocalImproverAgent(parsed, core) {
|
|
2985
|
-
if (stringFlag(parsed, "agents")) {
|
|
2986
|
-
return undefined;
|
|
2987
|
-
}
|
|
2988
|
-
const agents = await listWorkbenchAgents(core).catch(() => []);
|
|
2989
|
-
const status = await workbenchStatusSnapshot(core).catch(() => undefined);
|
|
2990
|
-
const defaultAgentName = status?.project.defaultAgent ?? agents[0]?.name;
|
|
2991
|
-
const defaultAgent = agents.find((agent) => agent.name === defaultAgentName);
|
|
2992
|
-
if (defaultAgent && workbenchSkillImproveCanUseQueuedAdapter(defaultAgent)) {
|
|
2993
|
-
return undefined;
|
|
2994
|
-
}
|
|
2995
|
-
const connected = await localWorkbenchAdapterAuthStore(adapterAuthStoreRoot()).listStatus().catch(() => []);
|
|
2996
|
-
const candidates = connected
|
|
2997
|
-
.filter((entry) => entry.status === "connected" &&
|
|
2998
|
-
(entry.adapterId === "claude" || entry.adapterId === "codex"))
|
|
2999
|
-
.sort((left, right) => {
|
|
3000
|
-
const adapterRank = (adapter) => adapter === "claude" ? 0 : adapter === "codex" ? 1 : 2;
|
|
3001
|
-
return adapterRank(left.adapterId) - adapterRank(right.adapterId) ||
|
|
3002
|
-
(Date.parse(right.updatedAt ?? "") || 0) - (Date.parse(left.updatedAt ?? "") || 0);
|
|
3003
|
-
});
|
|
3004
|
-
const selected = candidates[0];
|
|
3005
|
-
if (!selected) {
|
|
3006
|
-
throw new WorkbenchCodedError("auth_required", "workbench improve needs a connected improver.", {
|
|
3007
|
-
remediation: "Run workbench login claude (or codex) to connect an improver.",
|
|
3008
|
-
exitCode: 1,
|
|
3009
|
-
});
|
|
3010
|
-
}
|
|
3011
|
-
return {
|
|
3012
|
-
name: selected.adapterId,
|
|
3013
|
-
adapter: selected.adapterId,
|
|
3014
|
-
config: {
|
|
3015
|
-
auth: selected.slot ? { [selected.slot]: selected.profile } : selected.profile,
|
|
3016
|
-
},
|
|
3017
|
-
};
|
|
3018
|
-
}
|
|
3019
2959
|
function formatLogEntry(entry) {
|
|
3020
2960
|
if (entry.kind === "version") {
|
|
3021
2961
|
return `${entry.createdAt}\tversion\t${displayRef(entry.id)}\tfiles=${entry.fileCount}\t${entry.message}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workbench-ai/workbench",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.75",
|
|
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.
|
|
26
|
-
"@workbench-ai/workbench-contract": "0.0.
|
|
27
|
-
"@workbench-ai/workbench-
|
|
28
|
-
"@workbench-ai/workbench-
|
|
25
|
+
"@workbench-ai/workbench-built-in-adapters": "0.0.75",
|
|
26
|
+
"@workbench-ai/workbench-contract": "0.0.75",
|
|
27
|
+
"@workbench-ai/workbench-core": "0.0.75",
|
|
28
|
+
"@workbench-ai/workbench-protocol": "0.0.75"
|
|
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.75"
|
|
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",
|