@workbench-ai/workbench-core 0.0.68 → 0.0.69
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/coded-errors.d.ts +27 -0
- package/dist/coded-errors.d.ts.map +1 -0
- package/dist/coded-errors.js +52 -0
- package/dist/execution-events.d.ts +5 -1
- package/dist/execution-events.d.ts.map +1 -1
- package/dist/execution-events.js +13 -3
- package/dist/execution-scheduler.d.ts +5 -3
- package/dist/execution-scheduler.d.ts.map +1 -1
- package/dist/execution-scheduler.js +29 -8
- package/dist/generic-spec.d.ts +1 -55
- package/dist/generic-spec.d.ts.map +1 -1
- package/dist/generic-spec.js +0 -681
- package/dist/index.d.ts +71 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3512 -1322
- package/dist/remote-model.d.ts +17 -0
- package/dist/remote-model.d.ts.map +1 -0
- package/dist/remote-model.js +86 -0
- package/dist/runtime-utils.d.ts +1 -1
- package/dist/runtime-utils.d.ts.map +1 -1
- package/dist/runtime-utils.js +3 -3
- package/dist/sandbox-backends/docker.d.ts.map +1 -1
- package/dist/sandbox-backends/docker.js +32 -16
- package/package.json +3 -3
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type WorkbenchRemoteKind } from "@workbench-ai/workbench-contract";
|
|
2
|
+
export type { WorkbenchRemoteKind };
|
|
3
|
+
export interface ParsedWorkbenchCloudRemoteUrl {
|
|
4
|
+
kind: "workbench-cloud";
|
|
5
|
+
url: string;
|
|
6
|
+
baseUrl: string;
|
|
7
|
+
owner: string;
|
|
8
|
+
skill: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ParsedWorkbenchFileRemoteUrl {
|
|
11
|
+
kind: "file";
|
|
12
|
+
url: string;
|
|
13
|
+
path: string;
|
|
14
|
+
}
|
|
15
|
+
export type ParsedWorkbenchRemoteUrl = ParsedWorkbenchCloudRemoteUrl | ParsedWorkbenchFileRemoteUrl;
|
|
16
|
+
export declare function parseWorkbenchRemoteUrl(rawUrl: string): ParsedWorkbenchRemoteUrl;
|
|
17
|
+
//# sourceMappingURL=remote-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-model.d.ts","sourceRoot":"","sources":["../src/remote-model.ts"],"names":[],"mappings":"AAEA,OAAO,EAA+B,KAAK,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAIzG,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,iBAAiB,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,wBAAwB,GAAG,6BAA6B,GAAG,4BAA4B,CAAC;AAEpG,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,wBAAwB,CAoEhF"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
import { normalizeWorkbenchSkillName } from "@workbench-ai/workbench-contract";
|
|
3
|
+
import { WorkbenchCodedError } from "./coded-errors.js";
|
|
4
|
+
export function parseWorkbenchRemoteUrl(rawUrl) {
|
|
5
|
+
const trimmed = rawUrl.trim();
|
|
6
|
+
if (!trimmed) {
|
|
7
|
+
throw new WorkbenchCodedError("remote_invalid_url", "Workbench remote URL must be non-empty.", {
|
|
8
|
+
remediation: "Run workbench remote add --name NAME --url file:///absolute/path or workbench remote add --name NAME --url https://HOST/skills/OWNER/SKILL.",
|
|
9
|
+
exitCode: 2,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
let url;
|
|
13
|
+
try {
|
|
14
|
+
url = new URL(trimmed);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
throw new WorkbenchCodedError("remote_invalid_url", `Invalid Workbench remote URL: ${trimmed}`, {
|
|
18
|
+
remediation: "Use file:///absolute/path for local remotes or https://HOST/skills/OWNER/SKILL for Workbench Cloud remotes.",
|
|
19
|
+
subject: { url: trimmed },
|
|
20
|
+
exitCode: 2,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
if (url.protocol === "file:") {
|
|
24
|
+
let filePath;
|
|
25
|
+
try {
|
|
26
|
+
filePath = fileURLToPath(url);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
throw new WorkbenchCodedError("remote_invalid_url", `Invalid file Workbench remote URL: ${trimmed}`, {
|
|
30
|
+
remediation: "Use an absolute file URL such as file:///tmp/workbench-remote.",
|
|
31
|
+
subject: { url: trimmed },
|
|
32
|
+
exitCode: 2,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
if (!filePath.startsWith("/")) {
|
|
36
|
+
throw new WorkbenchCodedError("remote_invalid_url", `File Workbench remote must use an absolute path: ${trimmed}`, {
|
|
37
|
+
remediation: "Use file:///absolute/path for local Workbench remotes.",
|
|
38
|
+
subject: { url: trimmed },
|
|
39
|
+
exitCode: 2,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return { kind: "file", url: url.toString(), path: filePath };
|
|
43
|
+
}
|
|
44
|
+
if (url.protocol !== "https:" && !(url.protocol === "http:" && isLoopbackHost(url.hostname))) {
|
|
45
|
+
throw new WorkbenchCodedError("remote_unsupported_scheme", `Unsupported Workbench remote scheme: ${url.protocol.replace(/:$/u, "")}`, {
|
|
46
|
+
remediation: "Use file:///absolute/path for local remotes or https://HOST/skills/OWNER/SKILL for Workbench Cloud remotes.",
|
|
47
|
+
subject: { url: trimmed, scheme: url.protocol.replace(/:$/u, "") },
|
|
48
|
+
exitCode: 2,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
const segments = url.pathname.split("/").filter(Boolean).map((segment) => decodeURIComponent(segment));
|
|
52
|
+
if (segments.length !== 3 || segments[0] !== "skills") {
|
|
53
|
+
throw new WorkbenchCodedError("remote_invalid_skill_slug", `Workbench Cloud remote must use /skills/OWNER/SKILL: ${trimmed}`, {
|
|
54
|
+
remediation: "Run workbench remote add --name NAME --url https://HOST/skills/OWNER/SKILL.",
|
|
55
|
+
subject: { url: trimmed },
|
|
56
|
+
exitCode: 2,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
const owner = validateRemoteSlug(segments[1], "owner", trimmed);
|
|
60
|
+
const skill = validateRemoteSlug(segments[2], "skill", trimmed);
|
|
61
|
+
url.hash = "";
|
|
62
|
+
url.search = "";
|
|
63
|
+
url.pathname = `/skills/${encodeURIComponent(owner)}/${encodeURIComponent(skill)}`;
|
|
64
|
+
return {
|
|
65
|
+
kind: "workbench-cloud",
|
|
66
|
+
url: url.toString().replace(/\/$/u, ""),
|
|
67
|
+
baseUrl: url.origin,
|
|
68
|
+
owner,
|
|
69
|
+
skill,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function validateRemoteSlug(value, label, displayUrl) {
|
|
73
|
+
const normalized = normalizeWorkbenchSkillName(value);
|
|
74
|
+
if (!normalized || normalized !== value) {
|
|
75
|
+
throw new WorkbenchCodedError("remote_invalid_skill_slug", `Workbench Cloud remote ${label} must be a URL-safe slug: ${value}`, {
|
|
76
|
+
remediation: "Use lowercase letters, numbers, and single hyphens in Workbench Cloud remote URLs.",
|
|
77
|
+
subject: { url: displayUrl, segment: label, value },
|
|
78
|
+
exitCode: 2,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return normalized;
|
|
82
|
+
}
|
|
83
|
+
function isLoopbackHost(hostname) {
|
|
84
|
+
const normalized = hostname.toLowerCase().replace(/^\[(.*)\]$/u, "$1");
|
|
85
|
+
return normalized === "localhost" || normalized === "127.0.0.1" || normalized === "::1";
|
|
86
|
+
}
|
package/dist/runtime-utils.d.ts
CHANGED
|
@@ -18,6 +18,6 @@ export declare function resolveDockerRuntimeImageRef(imageRef: string, options:
|
|
|
18
18
|
}): string;
|
|
19
19
|
export declare function normalizeRuntimeRegistry(value: string): string;
|
|
20
20
|
export declare function normalizeWorkbenchWorkerId(value: unknown): string | undefined;
|
|
21
|
-
export declare function resolveWorkbenchWorkerId(
|
|
21
|
+
export declare function resolveWorkbenchWorkerId(candidates: readonly unknown[], fallback: string): string;
|
|
22
22
|
export declare function quoteShellArg(value: string): string;
|
|
23
23
|
//# sourceMappingURL=runtime-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-utils.d.ts","sourceRoot":"","sources":["../src/runtime-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EACJ,mBAAmB,EACpB,MAAM,kCAAkC,CAAC;AAE1C,wBAAsB,gBAAgB,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAEvE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAIvE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAI/D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE9D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE9D;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAU9D;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,mBAAmB,EAAE,GACpC,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAA;CAAO,GACvD,OAAO,CAAC,mBAAmB,EAAE,CAAC,CA+ChC;AAwBD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,kCAAkC,EAAE,IAAI,CAWtG;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAE,GAChF,MAAM,CASR;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9D;AAeD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAS7E;AAED,wBAAgB,wBAAwB,CAAC,
|
|
1
|
+
{"version":3,"file":"runtime-utils.d.ts","sourceRoot":"","sources":["../src/runtime-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EACJ,mBAAmB,EACpB,MAAM,kCAAkC,CAAC;AAE1C,wBAAsB,gBAAgB,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAEvE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAIvE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAI/D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE9D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE9D;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAU9D;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,mBAAmB,EAAE,GACpC,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAA;CAAO,GACvD,OAAO,CAAC,mBAAmB,EAAE,CAAC,CA+ChC;AAwBD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,kCAAkC,EAAE,IAAI,CAWtG;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAE,GAChF,MAAM,CASR;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9D;AAeD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAS7E;AAED,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,SAAS,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CASjG;AAoBD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKnD"}
|
package/dist/runtime-utils.js
CHANGED
|
@@ -167,9 +167,9 @@ export function normalizeWorkbenchWorkerId(value) {
|
|
|
167
167
|
}
|
|
168
168
|
return NON_IDENTIFYING_WORKER_IDS.has(normalized.toLowerCase()) ? undefined : normalized;
|
|
169
169
|
}
|
|
170
|
-
export function resolveWorkbenchWorkerId(
|
|
171
|
-
for (const
|
|
172
|
-
const normalized = normalizeWorkbenchWorkerId(
|
|
170
|
+
export function resolveWorkbenchWorkerId(candidates, fallback) {
|
|
171
|
+
for (const candidate of candidates) {
|
|
172
|
+
const normalized = normalizeWorkbenchWorkerId(candidate);
|
|
173
173
|
if (normalized) {
|
|
174
174
|
return normalized;
|
|
175
175
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/sandbox-backends/docker.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EACV,8BAA8B,EAC/B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,KAAK,wBAAwB,EAE7B,KAAK,yBAAyB,EAE9B,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/sandbox-backends/docker.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EACV,8BAA8B,EAC/B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,KAAK,wBAAwB,EAE7B,KAAK,yBAAyB,EAE9B,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AA8C7B,wBAAgB,oCAAoC,IACjD,wBAAwB,CAY1B;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,8BAA8B,EACpC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,yBAAyB,GACnC,YAAY,CAmDd"}
|
|
@@ -17,6 +17,7 @@ const BUILT_IN_ENVIRONMENT_IMAGES = {
|
|
|
17
17
|
};
|
|
18
18
|
const DOCKER_RUNTIME_MOUNT = "/workbench-runtime";
|
|
19
19
|
const DOCKER_DEFAULT_WORKSPACE = "/workspace";
|
|
20
|
+
const mutableDockerTemplateImageBuilds = new Map();
|
|
20
21
|
export function createDockerSandboxBackendDescriptor() {
|
|
21
22
|
return {
|
|
22
23
|
name: DOCKER_SANDBOX_BACKEND,
|
|
@@ -98,18 +99,33 @@ async function prepareDockerTemplateImage(execution, args, execFileAsync) {
|
|
|
98
99
|
]);
|
|
99
100
|
const sourceHash = args.environmentVersion?.sourceHash?.trim() || createHash("sha256").update(dockerfile).digest("hex");
|
|
100
101
|
const image = `workbench/sandbox-${safeDockerImageSegment(args.environmentVersion?.id ?? "env")}:${sourceHash.slice(0, 16)}`;
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
const pending = mutableDockerTemplateImageBuilds.get(image);
|
|
103
|
+
if (pending) {
|
|
104
|
+
return await pending;
|
|
105
|
+
}
|
|
106
|
+
const build = (async () => {
|
|
107
|
+
const imageExists = await execFileAsync("docker", ["image", "inspect", image], { maxBuffer: 1024 * 1024 })
|
|
108
|
+
.then(() => true, () => false);
|
|
109
|
+
if (imageExists) {
|
|
110
|
+
return image;
|
|
111
|
+
}
|
|
112
|
+
const contextRoot = path.join(args.workdir ?? os.tmpdir(), "workbench-docker-environments", sourceHash.slice(0, 32));
|
|
113
|
+
const dockerfilePath = path.join(contextRoot, "Dockerfile");
|
|
114
|
+
await fs.rm(contextRoot, { recursive: true, force: true }).catch(() => undefined);
|
|
115
|
+
await fs.mkdir(contextRoot, { recursive: true });
|
|
116
|
+
await fs.writeFile(dockerfilePath, `${dockerfile}\n`, { mode: 0o600 });
|
|
117
|
+
await execFileAsync("docker", ["build", "-t", image, "-f", dockerfilePath, contextRoot], { maxBuffer: 20 * 1024 * 1024 });
|
|
104
118
|
return image;
|
|
119
|
+
})();
|
|
120
|
+
mutableDockerTemplateImageBuilds.set(image, build);
|
|
121
|
+
try {
|
|
122
|
+
return await build;
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
if (mutableDockerTemplateImageBuilds.get(image) === build) {
|
|
126
|
+
mutableDockerTemplateImageBuilds.delete(image);
|
|
127
|
+
}
|
|
105
128
|
}
|
|
106
|
-
const contextRoot = path.join(args.workdir ?? os.tmpdir(), "workbench-docker-environments", sourceHash.slice(0, 32));
|
|
107
|
-
const dockerfilePath = path.join(contextRoot, "Dockerfile");
|
|
108
|
-
await fs.rm(contextRoot, { recursive: true, force: true }).catch(() => undefined);
|
|
109
|
-
await fs.mkdir(contextRoot, { recursive: true });
|
|
110
|
-
await fs.writeFile(dockerfilePath, `${dockerfile}\n`, { mode: 0o600 });
|
|
111
|
-
await execFileAsync("docker", ["build", "-t", image, "-f", dockerfilePath, contextRoot], { maxBuffer: 20 * 1024 * 1024 });
|
|
112
|
-
return image;
|
|
113
129
|
}
|
|
114
130
|
async function prepareDockerSandboxWorkspace(args, request, startedAt) {
|
|
115
131
|
const [{ execFile }, fs, os, path, { promisify }] = await Promise.all([
|
|
@@ -168,7 +184,7 @@ async function runDockerSandboxExecution(args, sandbox, execution) {
|
|
|
168
184
|
const runtimeImport = readRequiredMetadataString(metadata, "runtimeImport", DOCKER_SANDBOX_BACKEND);
|
|
169
185
|
const sandboxUid = readRequiredMetadataNumber(metadata, "sandboxUid", DOCKER_SANDBOX_BACKEND);
|
|
170
186
|
const sandboxGid = readRequiredMetadataNumber(metadata, "sandboxGid", DOCKER_SANDBOX_BACKEND);
|
|
171
|
-
const progressTarget = readOptionalProgressTarget(metadata.progressTarget);
|
|
187
|
+
const progressTarget = args.progress ?? readOptionalProgressTarget(metadata.progressTarget);
|
|
172
188
|
const network = asRuntimeRecord(metadata.network);
|
|
173
189
|
const resources = execution.policy.resources;
|
|
174
190
|
const tmpfsSize = dockerSize(resources.diskGb);
|
|
@@ -566,17 +582,17 @@ function findDockerSourceRoot() {
|
|
|
566
582
|
}
|
|
567
583
|
const cwd = process.cwd();
|
|
568
584
|
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
|
|
569
|
-
const
|
|
585
|
+
const roots = [
|
|
570
586
|
cwd,
|
|
571
587
|
path.resolve(cwd, ".."),
|
|
572
588
|
path.resolve(cwd, "../.."),
|
|
573
589
|
path.resolve(cwd, "../../.."),
|
|
574
590
|
path.resolve(moduleDir, "../../../../../.."),
|
|
575
591
|
];
|
|
576
|
-
for (const
|
|
577
|
-
if (existsSync(path.join(
|
|
578
|
-
existsSync(path.join(
|
|
579
|
-
return
|
|
592
|
+
for (const root of roots) {
|
|
593
|
+
if (existsSync(path.join(root, "products/workbench/packages/core/worker/sandbox-adapter-runner.cjs")) &&
|
|
594
|
+
existsSync(path.join(root, "products/workbench/packages/core/src/index.ts"))) {
|
|
595
|
+
return root;
|
|
580
596
|
}
|
|
581
597
|
}
|
|
582
598
|
return null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workbench-ai/workbench-core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.69",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/workbench-ai/workbench.git",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"yaml": "^2.8.2",
|
|
25
|
-
"@workbench-ai/workbench-contract": "0.0.
|
|
26
|
-
"@workbench-ai/workbench-protocol": "0.0.
|
|
25
|
+
"@workbench-ai/workbench-contract": "0.0.69",
|
|
26
|
+
"@workbench-ai/workbench-protocol": "0.0.69"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "^24.3.1",
|