@tablation/crew 0.126.12 → 0.127.0
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/cli.js +24 -6
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -10821,7 +10821,8 @@ var SandboxRunner = class {
|
|
|
10821
10821
|
}
|
|
10822
10822
|
const create2 = ["sandbox", "create", "--name", name, "--detach"];
|
|
10823
10823
|
if (policyFile) create2.push("--policy", policyFile);
|
|
10824
|
-
|
|
10824
|
+
const image = cfg.image ?? plan.sandboxImage;
|
|
10825
|
+
if (image) create2.push("--from", image);
|
|
10825
10826
|
if (cfg.cacheVolume) {
|
|
10826
10827
|
create2.push("--driver-config-json", JSON.stringify({
|
|
10827
10828
|
docker: { mounts: [{ type: "volume", source: cfg.cacheVolume, target: cfg.mirrorDir, read_only: true }] }
|
|
@@ -11041,6 +11042,15 @@ function sandboxLspPluginFor(route2, repo) {
|
|
|
11041
11042
|
return void 0;
|
|
11042
11043
|
}
|
|
11043
11044
|
}
|
|
11045
|
+
function sandboxImageOf(route2, repo, stateDir) {
|
|
11046
|
+
let declares = false;
|
|
11047
|
+
try {
|
|
11048
|
+
const dir = reposOf(route2).find((r) => r.name === repo)?.dir ?? route2.dir;
|
|
11049
|
+
declares = Boolean(loadRepoConfig(dir)?.sandbox);
|
|
11050
|
+
} catch {
|
|
11051
|
+
}
|
|
11052
|
+
return sandboxImageForRun(readSandboxState(stateDir), repo, declares) ?? void 0;
|
|
11053
|
+
}
|
|
11044
11054
|
var AgentSpawnError = class extends AgentError {
|
|
11045
11055
|
};
|
|
11046
11056
|
var WorkspaceAuthRefused = class extends AgentSpawnError {
|
|
@@ -11181,6 +11191,7 @@ function planAgentRun(o) {
|
|
|
11181
11191
|
const code = codeBridgeFor(o, adapter.harness);
|
|
11182
11192
|
const sandboxLsp = o.ship.runner === "sandbox" && adapter.harness === "claude" ? sandboxLspPluginFor(o.route, o.repo) : void 0;
|
|
11183
11193
|
const sandboxOrigin = o.ship.runner === "sandbox" ? sandboxOriginFor(o.route, o.repo) : void 0;
|
|
11194
|
+
const sandboxImage = o.ship.runner === "sandbox" ? sandboxImageOf(o.route, o.repo, o.stateDir) : void 0;
|
|
11184
11195
|
const sandboxFiles = [...code?.files ?? [], ...sandboxLsp?.files ?? []];
|
|
11185
11196
|
const invocation = adapter.invocation(toolchain, {
|
|
11186
11197
|
code,
|
|
@@ -11234,6 +11245,7 @@ function planAgentRun(o) {
|
|
|
11234
11245
|
runner: "sandbox",
|
|
11235
11246
|
...o.ship.sandbox ? { sandboxConfig: o.ship.sandbox } : {},
|
|
11236
11247
|
...sandboxOrigin ? { sandboxOrigin } : {},
|
|
11248
|
+
...sandboxImage ? { sandboxImage } : {},
|
|
11237
11249
|
sandboxPolicy: sandboxPolicyInputFor(o.route, toolchain, { harnessBin: invocation.bin, repo: o.repo, sandbox: o.ship.sandbox }),
|
|
11238
11250
|
...sandboxFiles.length ? { sandboxFiles } : {}
|
|
11239
11251
|
} : {},
|
|
@@ -13104,6 +13116,8 @@ function planSandbox(repo, decl, warm = {}, bridge) {
|
|
|
13104
13116
|
const layer = repoLayer(repo, decl, crew, warm);
|
|
13105
13117
|
return { repo, tag: layer.tag, claude: SANDBOX_CLAUDE_VERSION, layers: [base, crew, layer] };
|
|
13106
13118
|
}
|
|
13119
|
+
var SHIP_SANDBOX_KEY = "@ship";
|
|
13120
|
+
var shipSandboxRef = () => ({ name: SHIP_SANDBOX_KEY, decl: { packages: [], setup: [] } });
|
|
13107
13121
|
var sandboxStatePath = (stateDir) => join32(stateDir, "sandbox-images.json");
|
|
13108
13122
|
function readSandboxState(stateDir) {
|
|
13109
13123
|
try {
|
|
@@ -13123,6 +13137,9 @@ function writeSandboxState(stateDir, state) {
|
|
|
13123
13137
|
function sandboxImageFor(state, repo) {
|
|
13124
13138
|
return state[repo]?.tags[0]?.tag ?? null;
|
|
13125
13139
|
}
|
|
13140
|
+
function sandboxImageForRun(state, repo, declares) {
|
|
13141
|
+
return (declares && repo ? sandboxImageFor(state, repo) : null) ?? sandboxImageFor(state, SHIP_SANDBOX_KEY);
|
|
13142
|
+
}
|
|
13126
13143
|
function sandboxImageStatus(state, plan) {
|
|
13127
13144
|
const s = state[plan.repo];
|
|
13128
13145
|
const current = s?.tags[0];
|
|
@@ -25924,6 +25941,7 @@ ${changed2.map((c) => ` - ${c}
|
|
|
25924
25941
|
}
|
|
25925
25942
|
return [...out.values()];
|
|
25926
25943
|
}
|
|
25944
|
+
const withShipSandbox = (declared) => cfg.ship.runner === "sandbox" ? [shipSandboxRef(), ...declared] : declared;
|
|
25927
25945
|
async function resolveOneRepo(c, t) {
|
|
25928
25946
|
{
|
|
25929
25947
|
const id = repoIdForName(c, t.name);
|
|
@@ -27192,7 +27210,7 @@ ${cu.tail.trimEnd()}
|
|
|
27192
27210
|
onPass: (result) => {
|
|
27193
27211
|
if (!sandboxBuilding) {
|
|
27194
27212
|
sandboxBuilding = true;
|
|
27195
|
-
void sandboxReposOf(cfg.routes.filter((r) => r.enabled)).then((repos) => repos.length ? sandboxBuildTick(repos, sandboxTickDeps(emit, route2)) : null).catch((err3) => emit.warn(`sandbox image build tick failed: ${err3 instanceof Error ? err3.message : String(err3)}`)).finally(() => {
|
|
27213
|
+
void sandboxReposOf(cfg.routes.filter((r) => r.enabled)).then(withShipSandbox).then((repos) => repos.length ? sandboxBuildTick(repos, sandboxTickDeps(emit, route2)) : null).catch((err3) => emit.warn(`sandbox image build tick failed: ${err3 instanceof Error ? err3.message : String(err3)}`)).finally(() => {
|
|
27196
27214
|
sandboxBuilding = false;
|
|
27197
27215
|
});
|
|
27198
27216
|
}
|
|
@@ -28726,7 +28744,7 @@ Signed in as ${result.identity.email} \u2014 minted an API key in workspace "${r
|
|
|
28726
28744
|
}
|
|
28727
28745
|
throw e;
|
|
28728
28746
|
}
|
|
28729
|
-
const declared = await sandboxReposOf(routesS);
|
|
28747
|
+
const declared = withShipSandbox(await sandboxReposOf(routesS));
|
|
28730
28748
|
if (subS === "images") {
|
|
28731
28749
|
const stateS = readSandboxState(cfg.ship.stateDir);
|
|
28732
28750
|
const rows = declared.map((r) => {
|
|
@@ -28753,8 +28771,8 @@ Signed in as ${result.identity.email} \u2014 minted an API key in workspace "${r
|
|
|
28753
28771
|
const only = positional[2];
|
|
28754
28772
|
const targets = only ? declared.filter((r) => r.name === only) : declared;
|
|
28755
28773
|
if (targets.length === 0) {
|
|
28756
|
-
process.stderr.write(only ? `crew: no repository "${only}" declares a sandbox: section
|
|
28757
|
-
` : "crew: no repository declares a sandbox: section in its .crew.yaml\n");
|
|
28774
|
+
process.stderr.write(only ? `crew: no repository "${only}" declares a sandbox: section (${SHIP_SANDBOX_KEY} is the ship's crew layer, built only on a ship.runner: sandbox ship)
|
|
28775
|
+
` : "crew: this ship is not a sandbox ship and no repository declares a sandbox: section in its .crew.yaml\n");
|
|
28758
28776
|
process.exit(2);
|
|
28759
28777
|
}
|
|
28760
28778
|
const emitS = new Emitter({ route: routesS[0].route, eventFile: eventFileFor(cfg.ship.stateDir), rotateBytes: cfg.ship.eventsRotateBytes, logFile: cfg.ship.logFile, console: (l) => process.stderr.write(`${l}
|
|
@@ -30853,7 +30871,7 @@ ${foreign.join("\n")}
|
|
|
30853
30871
|
}
|
|
30854
30872
|
}
|
|
30855
30873
|
{
|
|
30856
|
-
const declaredS = await sandboxReposOf(cfg.routes.filter((r) => r.enabled));
|
|
30874
|
+
const declaredS = withShipSandbox(await sandboxReposOf(cfg.routes.filter((r) => r.enabled)));
|
|
30857
30875
|
const stateS = readSandboxState(cfg.ship.stateDir);
|
|
30858
30876
|
for (const r of declaredS) {
|
|
30859
30877
|
const st = sandboxImageStatus(stateS, planSandbox(r.name, r.decl, r.warm, r.bridge));
|
package/package.json
CHANGED