opencode-swarm 7.152.1 → 7.153.1
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/.opencode/skills/swarm-pr-review/SKILL.md +10 -10
- package/dist/background/pending-delegations.d.ts +7 -0
- package/dist/cli/{capability-probe-va4kk8vg.js → capability-probe-5wa7mcp6.js} +3 -2
- package/dist/cli/{config-doctor-bbqmye7a.js → config-doctor-ze21qs6b.js} +3 -3
- package/dist/cli/{core-fh4e6ex0.js → core-qdmhh1kx.js} +2 -2
- package/dist/cli/{curation-policy-nem98yc9.js → curation-policy-twa6agf8.js} +7 -7
- package/dist/cli/{curator-909s9dvs.js → curator-hxb3wsxr.js} +32 -33
- package/dist/cli/curator-llm-factory-s8atmc2n.js +64 -0
- package/dist/cli/{evidence-summary-service-kqw4y0yr.js → evidence-summary-service-wzzym9r7.js} +15 -15
- package/dist/cli/{gate-evidence-ycts62pj.js → gate-evidence-f71dn9vv.js} +8 -8
- package/dist/cli/guardrail-explain-5kzeem4m.js +65 -0
- package/dist/cli/{guardrail-log-e1tmdxxa.js → guardrail-log-38jnajpa.js} +6 -6
- package/dist/cli/{guardrail-reset-gdnaxxvb.js → guardrail-reset-wzvtmpn2.js} +32 -33
- package/dist/cli/{hive-promoter-d0xydg6r.js → hive-promoter-55qcqgfx.js} +32 -33
- package/dist/cli/{index-x6803sxh.js → index-0tyc8kdg.js} +2 -2
- package/dist/cli/{index-z8s2asdk.js → index-0tzv5zg2.js} +22 -150
- package/dist/cli/{index-3djxegsc.js → index-1akn19mp.js} +1 -1
- package/dist/cli/{index-q77e475x.js → index-1dtshrzg.js} +5 -5
- package/dist/cli/{index-73pmnsjg.js → index-1gzdnjg9.js} +2 -2
- package/dist/cli/{index-4tvvh7pn.js → index-23rneydq.js} +36 -35
- package/dist/cli/{index-z4bg1hv8.js → index-2mqmvxac.js} +9 -2
- package/dist/cli/index-3cegckkq.js +239 -0
- package/dist/cli/{index-pvrap7xg.js → index-3ttktt56.js} +1 -1
- package/dist/cli/{index-85gkedsf.js → index-4fwbbad3.js} +521 -15
- package/dist/cli/{index-qqrdmaxq.js → index-4g0g3dqz.js} +2 -2
- package/dist/cli/{index-44xdtqz8.js → index-4pjkdcgc.js} +1 -1
- package/dist/cli/{index-29vd7v3e.js → index-6vgb5fyb.js} +1 -1
- package/dist/cli/{index-sg2sx2q7.js → index-6ybjrqf7.js} +13095 -9360
- package/dist/cli/{index-txbd25bc.js → index-891g7hbf.js} +1 -1
- package/dist/cli/{index-02ajc6d1.js → index-8v9sj4aq.js} +2 -2
- package/dist/cli/{index-z9fyd0d6.js → index-9v8d3c0k.js} +450 -48
- package/dist/cli/{index-26vyr198.js → index-af0cqe6n.js} +16 -16
- package/dist/cli/{index-ryecg2st.js → index-ajkxx2k6.js} +3 -3
- package/dist/cli/{index-k3d919yf.js → index-gn26q90p.js} +85 -24
- package/dist/cli/{index-0tfgn5x0.js → index-k10qtq71.js} +9 -9
- package/dist/cli/{index-xyfdmrv7.js → index-mb7b1gye.js} +3 -3
- package/dist/cli/{index-0q2mjxp2.js → index-meg33yyv.js} +1 -1
- package/dist/cli/{index-cpg98bh1.js → index-myt57pht.js} +1 -1
- package/dist/cli/{index-2e1294d1.js → index-n5pxkera.js} +16 -10
- package/dist/cli/{index-n0vc5b5t.js → index-n823qsae.js} +16 -7
- package/dist/cli/{index-6zkm4p7p.js → index-pk1gbqmq.js} +1 -1
- package/dist/cli/{index-nd8tkb3g.js → index-smqsp8hs.js} +5 -5
- package/dist/cli/{index-7fh82sm1.js → index-td0jz8xe.js} +6 -6
- package/dist/cli/{index-dn6yt0xg.js → index-tdzbm974.js} +7 -7
- package/dist/cli/{index-rq6aetkv.js → index-v689bmr2.js} +4 -4
- package/dist/cli/{index-79g6edht.js → index-x3y6zhgj.js} +1 -1
- package/dist/cli/{index-aw492hpn.js → index-x8vw6ap1.js} +58 -41
- package/dist/cli/{index-96m8ckpq.js → index-xkjrg9k4.js} +4 -4
- package/dist/cli/{index-mken64yj.js → index-zppxpc3y.js} +2 -2
- package/dist/cli/index.js +32 -33
- package/dist/cli/{knowledge-escalator-4egcr928.js → knowledge-escalator-w05ztgvk.js} +13 -13
- package/dist/cli/{knowledge-events-kdyv4jzn.js → knowledge-events-pwm9jc0m.js} +11 -11
- package/dist/cli/{knowledge-link-h8cwj7af.js → knowledge-link-ge0rddxw.js} +6 -6
- package/dist/cli/{knowledge-store-dq3cvg53.js → knowledge-store-4xv65tj2.js} +7 -7
- package/dist/cli/{knowledge-validator-4bhtden9.js → knowledge-validator-0ttfsca7.js} +9 -9
- package/dist/cli/{model-preflight-7ea00h34.js → model-preflight-b95w8wxy.js} +1 -1
- package/dist/cli/{pending-delegations-a2nmssr1.js → pending-delegations-nk78wx7h.js} +4 -4
- package/dist/cli/{pr-subscriptions-7879nq5k.js → pr-subscriptions-dq1f61ye.js} +4 -4
- package/dist/cli/{runner-w81n9js3.js → runner-n50w1y4w.js} +7 -7
- package/dist/cli/{scan-cursor-2eezv81a.js → scan-cursor-b6n15w8d.js} +8 -8
- package/dist/cli/{schema-v4qcqhek.js → schema-jkbfwqr2.js} +2 -2
- package/dist/cli/{scope-persistence-y2r227r0.js → scope-persistence-5xt2m5ep.js} +10 -10
- package/dist/cli/{skill-generator-hhzxvb3h.js → skill-generator-3keadpf7.js} +15 -15
- package/dist/cli/{telemetry-52pw5xac.js → telemetry-hh1j99za.js} +1 -1
- package/dist/cli/{worktree-collision-ownership-p31zm5k0.js → worktree-collision-ownership-4drcjymy.js} +15 -10
- package/dist/cli/{worktree-isolation-ve338ez6.js → worktree-isolation-1ymaxn4h.js} +32 -33
- package/dist/commands/approve-write.d.ts +1 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/lanes.d.ts +25 -0
- package/dist/commands/registry.d.ts +7 -0
- package/dist/config/schema.d.ts +39 -4
- package/dist/consensus/contracts.d.ts +14 -0
- package/dist/consensus/corpus.d.ts +16 -0
- package/dist/hooks/delegation-gate/worktree-isolation.d.ts +50 -3
- package/dist/hooks/delegation-gate/worktree-provisioning-owner.d.ts +40 -2
- package/dist/hooks/delegation-gate/worktree-recovery-authority.d.ts +201 -0
- package/dist/hooks/full-auto-permission.d.ts +7 -0
- package/dist/hooks/guardrails/index.d.ts +2 -1
- package/dist/hooks/guardrails/tool-before.d.ts +4 -0
- package/dist/hooks/init-orphan-recovery.d.ts +5 -1
- package/dist/hooks/pr-workflow-gate.d.ts +12 -0
- package/dist/hooks/scope-guard.d.ts +1 -3
- package/dist/hooks/trajectory-logger.d.ts +22 -6
- package/dist/hooks/trajectory-step-state.d.ts +43 -2
- package/dist/index.js +645 -622
- package/dist/learning/provenance.d.ts +9 -0
- package/dist/observability/catalog.d.ts +6 -4
- package/dist/prm/index.d.ts +3 -3
- package/dist/prm/replay.d.ts +29 -2
- package/dist/prm/trajectory-store.d.ts +210 -20
- package/dist/sandbox/capability-probe.d.ts +40 -1
- package/dist/sandbox/executor.d.ts +26 -1
- package/dist/sandbox/linux/bubblewrap-executor.d.ts +3 -1
- package/dist/sandbox/macos/sandbox-exec-executor.d.ts +3 -1
- package/dist/sandbox/skip-state.d.ts +24 -0
- package/dist/sandbox/win32/native-sandbox-executor.d.ts +5 -1
- package/dist/security/command-classifier.d.ts +22 -0
- package/dist/security/protected-input-integrity.d.ts +19 -0
- package/dist/security/protected-path-policy.d.ts +9 -0
- package/dist/security/write-authority.d.ts +46 -0
- package/dist/services/diagnose-service.d.ts +1 -1
- package/dist/services/skill-generator.d.ts +2 -0
- package/dist/services/skill-improver.d.ts +69 -0
- package/dist/telemetry.d.ts +21 -1
- package/dist/tools/dispatch-lanes.d.ts +47 -0
- package/dist/tools/repo-graph/query.d.ts +2 -1
- package/dist/tools/repo-graph/types.d.ts +64 -0
- package/dist/tools/repo-graph.d.ts +1 -1
- package/dist/tools/skill-improve.d.ts +7 -0
- package/dist/utils/atomic-write.d.ts +2 -0
- package/dist/utils/canonical-root.d.ts +31 -0
- package/dist/workflow/coder-settlement.d.ts +2 -0
- package/dist/worktree/index.d.ts +2 -2
- package/dist/worktree/merge.d.ts +47 -0
- package/package.json +2 -1
- package/dist/cli/curator-llm-factory-462rysph.js +0 -65
- package/dist/cli/guardrail-explain-7620hasq.js +0 -66
- package/dist/cli/index-3g0xk6tk.js +0 -219
- package/dist/cli/index-fxvgaeq4.js +0 -125
- package/dist/cli/worktree-provisioning-owner-cve95q4f.js +0 -22
- package/dist/cli/{curator-drift-2h1d2fnq.js → curator-drift-h57z6tm3.js} +1 -1
|
@@ -169,7 +169,7 @@ class MacOSSandboxExecutor {
|
|
|
169
169
|
this._available = false;
|
|
170
170
|
warn(`Sandbox disabled: ${reason}. Falling through to tool-layer enforcement.`);
|
|
171
171
|
}
|
|
172
|
-
wrapCommand(command, scopePaths, tempDir, envOverrides) {
|
|
172
|
+
wrapCommand(command, scopePaths, tempDir, envOverrides, _policy) {
|
|
173
173
|
if (!this._available) {
|
|
174
174
|
throw new SandboxError("Sandbox not available", "SANDBOX_UNAVAILABLE");
|
|
175
175
|
}
|
|
@@ -878,16 +878,16 @@ class NativeWindowsSandboxExecutor {
|
|
|
878
878
|
this._disabledReason = reason;
|
|
879
879
|
warn(`Sandbox disabled: ${reason}. Falling through to tool-layer enforcement.`);
|
|
880
880
|
}
|
|
881
|
-
wrapCommand(command, scopePaths, tempDir, envOverrides) {
|
|
881
|
+
wrapCommand(command, scopePaths, tempDir, envOverrides, policy) {
|
|
882
882
|
if (!this.isAvailable()) {
|
|
883
883
|
throw new SandboxError("Sandbox not available", "SANDBOX_UNAVAILABLE");
|
|
884
884
|
}
|
|
885
885
|
if (this._strength === "strong") {
|
|
886
|
-
return this._wrapWithRunner(command, scopePaths, tempDir, envOverrides);
|
|
886
|
+
return this._wrapWithRunner(command, scopePaths, tempDir, envOverrides, policy);
|
|
887
887
|
}
|
|
888
888
|
return this._fallbackExecutor.wrapCommand(command, scopePaths, tempDir, envOverrides);
|
|
889
889
|
}
|
|
890
|
-
_wrapWithRunner(command, scopePaths, tempDir, _envOverrides) {
|
|
890
|
+
_wrapWithRunner(command, scopePaths, tempDir, _envOverrides, policyOverride) {
|
|
891
891
|
const binary = _internals3.findRunnerBinary();
|
|
892
892
|
if (!binary) {
|
|
893
893
|
throw new SandboxError("Runner binary not found", "RUNNER_NOT_FOUND");
|
|
@@ -899,7 +899,8 @@ class NativeWindowsSandboxExecutor {
|
|
|
899
899
|
policy.temp_root = tempDir;
|
|
900
900
|
}
|
|
901
901
|
policy.workspace_roots = scopePaths.length > 0 ? scopePaths : [workspaceRoot];
|
|
902
|
-
policy.writable_roots = policy.workspace_roots;
|
|
902
|
+
policy.writable_roots = policyOverride?.writable_roots && policyOverride.writable_roots.length > 0 ? [...policyOverride.writable_roots] : policy.workspace_roots;
|
|
903
|
+
policy.network_mode = policyOverride?.network_mode ?? policy.network_mode;
|
|
903
904
|
if (_envOverrides) {
|
|
904
905
|
for (const [key, value] of Object.entries(_envOverrides)) {
|
|
905
906
|
if (!isValidEnvKey(key))
|
|
@@ -1006,8 +1007,8 @@ async function _createExecutor() {
|
|
|
1006
1007
|
return null;
|
|
1007
1008
|
}
|
|
1008
1009
|
async function _createLinuxExecutor() {
|
|
1009
|
-
const { SandboxCapabilityProbe, isBubblewrapAvailable } = await import("./capability-probe-
|
|
1010
|
-
await new
|
|
1010
|
+
const { SandboxCapabilityProbe: SandboxCapabilityProbe2, isBubblewrapAvailable } = await import("./capability-probe-5wa7mcp6.js");
|
|
1011
|
+
await new SandboxCapabilityProbe2().detect();
|
|
1011
1012
|
if (!isBubblewrapAvailable()) {
|
|
1012
1013
|
return null;
|
|
1013
1014
|
}
|
|
@@ -1026,8 +1027,8 @@ async function _createMacOSExecutor() {
|
|
|
1026
1027
|
}
|
|
1027
1028
|
return null;
|
|
1028
1029
|
}
|
|
1029
|
-
const { SandboxCapabilityProbe, isSandboxExecAvailable } = await import("./capability-probe-
|
|
1030
|
-
await new
|
|
1030
|
+
const { SandboxCapabilityProbe: SandboxCapabilityProbe2, isSandboxExecAvailable } = await import("./capability-probe-5wa7mcp6.js");
|
|
1031
|
+
await new SandboxCapabilityProbe2().detect();
|
|
1031
1032
|
if (!isSandboxExecAvailable()) {
|
|
1032
1033
|
return null;
|
|
1033
1034
|
}
|
|
@@ -1039,8 +1040,8 @@ async function _createMacOSExecutor() {
|
|
|
1039
1040
|
}
|
|
1040
1041
|
}
|
|
1041
1042
|
async function _createWindowsExecutor() {
|
|
1042
|
-
const { SandboxCapabilityProbe, isWindowsSandboxAvailable } = await import("./capability-probe-
|
|
1043
|
-
await new
|
|
1043
|
+
const { SandboxCapabilityProbe: SandboxCapabilityProbe2, isWindowsSandboxAvailable } = await import("./capability-probe-5wa7mcp6.js");
|
|
1044
|
+
await new SandboxCapabilityProbe2().detect();
|
|
1044
1045
|
if (!isWindowsSandboxAvailable()) {
|
|
1045
1046
|
return null;
|
|
1046
1047
|
}
|
|
@@ -1051,9 +1052,10 @@ async function _createWindowsExecutor() {
|
|
|
1051
1052
|
return null;
|
|
1052
1053
|
}
|
|
1053
1054
|
}
|
|
1054
|
-
var SandboxError, UNTRUSTED_ENV_KEY_PREFIXES, _cachedExecutorPromise, _macosSandboxEnabled = false, _hasWarnedMacOSSandboxDisabledByConfig = false;
|
|
1055
|
+
var SandboxError, UNTRUSTED_ENV_KEY_PREFIXES, _cachedExecutorPromise, _sandboxAssessmentCache, _macosSandboxEnabled = false, _hasWarnedMacOSSandboxDisabledByConfig = false;
|
|
1055
1056
|
var init_executor = __esm(() => {
|
|
1056
1057
|
init_logger();
|
|
1058
|
+
init_capability_probe();
|
|
1057
1059
|
SandboxError = class SandboxError extends Error {
|
|
1058
1060
|
code;
|
|
1059
1061
|
constructor(message, code) {
|
|
@@ -1063,6 +1065,7 @@ var init_executor = __esm(() => {
|
|
|
1063
1065
|
}
|
|
1064
1066
|
};
|
|
1065
1067
|
UNTRUSTED_ENV_KEY_PREFIXES = ["GIT_", "LD_", "DYLD_"];
|
|
1068
|
+
_sandboxAssessmentCache = new Map;
|
|
1066
1069
|
});
|
|
1067
1070
|
|
|
1068
1071
|
// src/sandbox/linux/bubblewrap-executor.ts
|
|
@@ -1138,7 +1141,7 @@ class BubblewrapSandboxExecutor {
|
|
|
1138
1141
|
this._disabledReason = reason;
|
|
1139
1142
|
warn(`Sandbox disabled: ${reason}. Falling through to tool-layer enforcement.`);
|
|
1140
1143
|
}
|
|
1141
|
-
wrapCommand(command, scopePaths, tempDir, envOverrides) {
|
|
1144
|
+
wrapCommand(command, scopePaths, tempDir, envOverrides, policy) {
|
|
1142
1145
|
if (!this._available) {
|
|
1143
1146
|
throw new SandboxError("Sandbox not available", "SANDBOX_UNAVAILABLE");
|
|
1144
1147
|
}
|
|
@@ -1164,7 +1167,6 @@ class BubblewrapSandboxExecutor {
|
|
|
1164
1167
|
}
|
|
1165
1168
|
const args = [
|
|
1166
1169
|
"--unshare-user",
|
|
1167
|
-
"--unshare-net",
|
|
1168
1170
|
"--unshare-ipc",
|
|
1169
1171
|
"--die-with-parent",
|
|
1170
1172
|
"--new-session",
|
|
@@ -1198,6 +1200,9 @@ class BubblewrapSandboxExecutor {
|
|
|
1198
1200
|
"-c",
|
|
1199
1201
|
`'${shellEscape2(command)}'`
|
|
1200
1202
|
];
|
|
1203
|
+
if ((policy?.network_mode ?? "off") === "off") {
|
|
1204
|
+
args.splice(1, 0, "--unshare-net");
|
|
1205
|
+
}
|
|
1201
1206
|
const binary = _internals4.resolveBwrapBinary();
|
|
1202
1207
|
return `${binary} ${args.join(" ")}`;
|
|
1203
1208
|
}
|
|
@@ -1216,4 +1221,505 @@ var init_bubblewrap_executor = __esm(() => {
|
|
|
1216
1221
|
};
|
|
1217
1222
|
});
|
|
1218
1223
|
|
|
1219
|
-
|
|
1224
|
+
// src/sandbox/capability-probe.ts
|
|
1225
|
+
import { execFile, spawnSync as spawnSync5 } from "child_process";
|
|
1226
|
+
import * as fs3 from "fs";
|
|
1227
|
+
import * as os5 from "os";
|
|
1228
|
+
import * as path5 from "path";
|
|
1229
|
+
function assessSandboxRequirements(capability, requirements) {
|
|
1230
|
+
if (!requirements || requirements.mode !== "required") {
|
|
1231
|
+
return { satisfied: true, missing: [] };
|
|
1232
|
+
}
|
|
1233
|
+
const missing = [];
|
|
1234
|
+
if (requirements.require_filesystem && capability.filesystem !== "real") {
|
|
1235
|
+
missing.push("filesystem");
|
|
1236
|
+
}
|
|
1237
|
+
if (requirements.require_network && capability.network !== "real") {
|
|
1238
|
+
missing.push("network");
|
|
1239
|
+
}
|
|
1240
|
+
if (requirements.require_process && capability.process !== "real") {
|
|
1241
|
+
missing.push("process");
|
|
1242
|
+
}
|
|
1243
|
+
return { satisfied: missing.length === 0, missing };
|
|
1244
|
+
}
|
|
1245
|
+
function fileIdentity(input) {
|
|
1246
|
+
if (!input)
|
|
1247
|
+
return "missing";
|
|
1248
|
+
const candidate = path5.normalize(input);
|
|
1249
|
+
try {
|
|
1250
|
+
const link = fs3.lstatSync(candidate, { bigint: true });
|
|
1251
|
+
const stat = fs3.statSync(candidate, { bigint: true });
|
|
1252
|
+
return [
|
|
1253
|
+
candidate,
|
|
1254
|
+
`l=${link.dev}:${link.ino}:${link.size}:${link.mtimeNs}`,
|
|
1255
|
+
`s=${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeNs}`
|
|
1256
|
+
].join(":");
|
|
1257
|
+
} catch {
|
|
1258
|
+
return `${candidate}:missing`;
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
function currentProbeSourceIdentity(platform) {
|
|
1262
|
+
if (platform === "linux") {
|
|
1263
|
+
return `linux:${fileIdentity(_internals4.resolveBwrapBinary())}`;
|
|
1264
|
+
}
|
|
1265
|
+
if (platform === "darwin") {
|
|
1266
|
+
return `darwin:${fileIdentity(_internals.resolveSandboxExecBinary())}:${fileIdentity(_internals.resolveProbeTargetBinary())}`;
|
|
1267
|
+
}
|
|
1268
|
+
if (platform === "win32") {
|
|
1269
|
+
const cmdBinary = resolveWindowsCommandProcessorBinary();
|
|
1270
|
+
try {
|
|
1271
|
+
const {
|
|
1272
|
+
_internals: runnerClientInternals
|
|
1273
|
+
} = (init_runner_client(), __toCommonJS(exports_runner_client));
|
|
1274
|
+
return `win32:${fileIdentity(runnerClientInternals.findRunnerBinary?.())}:${fileIdentity(cmdBinary)}`;
|
|
1275
|
+
} catch {
|
|
1276
|
+
return `win32:${fileIdentity(cmdBinary)}`;
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
return `unknown:${platform}`;
|
|
1280
|
+
}
|
|
1281
|
+
function resolveWindowsCommandProcessorBinary() {
|
|
1282
|
+
const candidates = [];
|
|
1283
|
+
const comSpec = process.env.ComSpec?.trim();
|
|
1284
|
+
if (comSpec) {
|
|
1285
|
+
candidates.push(comSpec);
|
|
1286
|
+
}
|
|
1287
|
+
const pathEnv = process.env.Path ?? process.env.PATH ?? "";
|
|
1288
|
+
for (const entry of pathEnv.split(path5.delimiter)) {
|
|
1289
|
+
const trimmed = entry.trim();
|
|
1290
|
+
if (!trimmed)
|
|
1291
|
+
continue;
|
|
1292
|
+
candidates.push(path5.join(trimmed, "cmd.exe"));
|
|
1293
|
+
}
|
|
1294
|
+
for (const candidate of candidates) {
|
|
1295
|
+
try {
|
|
1296
|
+
if (fs3.statSync(candidate).isFile()) {
|
|
1297
|
+
return candidate;
|
|
1298
|
+
}
|
|
1299
|
+
} catch {}
|
|
1300
|
+
}
|
|
1301
|
+
return comSpec || "cmd";
|
|
1302
|
+
}
|
|
1303
|
+
function cleanupProbeTempRoot(tempRoot, mechanism, reasons) {
|
|
1304
|
+
try {
|
|
1305
|
+
_internals5.removeProbeTempRoot(tempRoot);
|
|
1306
|
+
} catch (error) {
|
|
1307
|
+
const code = typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" ? error.code ?? "unknown" : "unknown";
|
|
1308
|
+
reasons.push(`${mechanism} probe temp cleanup failed (${code})`);
|
|
1309
|
+
warn(`[sandbox] ${mechanism} probe temp cleanup failed (${code}); continuing with bounded probe result`);
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
function weakest(...dimensions) {
|
|
1313
|
+
return dimensions.includes("none") ? "none" : dimensions.includes("weak") ? "weak" : "real";
|
|
1314
|
+
}
|
|
1315
|
+
function upgradeCapability(capability, evidence) {
|
|
1316
|
+
let filesystem = "none";
|
|
1317
|
+
let network = "none";
|
|
1318
|
+
let process2 = "none";
|
|
1319
|
+
const reasons = [...evidence.reasons];
|
|
1320
|
+
if (capability.status === "enabled" && capability.platform === "linux") {
|
|
1321
|
+
filesystem = evidence.filesystem;
|
|
1322
|
+
network = evidence.network;
|
|
1323
|
+
process2 = evidence.process;
|
|
1324
|
+
if (reasons.length === 0) {
|
|
1325
|
+
reasons.push("bubblewrap availability is evidenced, but denial behavior is not independently exercised here", "seccomp unsupported: no filter is installed");
|
|
1326
|
+
}
|
|
1327
|
+
} else if (capability.status === "enabled" && capability.platform === "darwin") {
|
|
1328
|
+
filesystem = evidence.filesystem;
|
|
1329
|
+
network = evidence.network;
|
|
1330
|
+
process2 = evidence.process;
|
|
1331
|
+
if (reasons.length === 0) {
|
|
1332
|
+
reasons.push("Seatbelt availability is evidenced, but denial behavior is not independently exercised here", "(allow default) leaves network, IPC, and process-spawn behavior outside the boundary");
|
|
1333
|
+
}
|
|
1334
|
+
} else if (capability.status === "enabled" && capability.platform === "win32") {
|
|
1335
|
+
const mechanism = capability.mechanism.toLowerCase();
|
|
1336
|
+
const appContainer = mechanism.includes("app-container");
|
|
1337
|
+
const restrictedToken = mechanism.includes("restricted-token");
|
|
1338
|
+
filesystem = evidence.filesystem || (appContainer || restrictedToken ? "weak" : "none");
|
|
1339
|
+
network = evidence.network || (appContainer ? "weak" : "none");
|
|
1340
|
+
process2 = evidence.process || (appContainer || restrictedToken ? "weak" : "none");
|
|
1341
|
+
reasons.push(appContainer ? "native AppContainer runner probe succeeded, but end-to-end denial behavior is not independently verified from this host" : restrictedToken ? "restricted-token runner probe succeeded, but it remains a conservative weak boundary until independently verified" : "PowerShell fallback is defense in depth, not containment");
|
|
1342
|
+
} else {
|
|
1343
|
+
reasons.push(capability.error ?? "sandbox mechanism unavailable");
|
|
1344
|
+
}
|
|
1345
|
+
return {
|
|
1346
|
+
...capability,
|
|
1347
|
+
v: 1,
|
|
1348
|
+
filesystem,
|
|
1349
|
+
network,
|
|
1350
|
+
process: process2,
|
|
1351
|
+
effective: weakest(filesystem, network, process2),
|
|
1352
|
+
reasons,
|
|
1353
|
+
identity: `${capability.platform}:${capability.mechanism.toLowerCase()}:${capability.status}:${capability.strength ?? "none"}:fs=${filesystem}:net=${network}:proc=${process2}`
|
|
1354
|
+
};
|
|
1355
|
+
}
|
|
1356
|
+
function withProbeIdentity(capability, probeSourceIdentity) {
|
|
1357
|
+
return {
|
|
1358
|
+
...capability,
|
|
1359
|
+
identity: `${capability.identity}:probe=${probeSourceIdentity}`
|
|
1360
|
+
};
|
|
1361
|
+
}
|
|
1362
|
+
function runBoundedSync(cmd, args, input) {
|
|
1363
|
+
return _internals5.spawnSync(cmd, args, {
|
|
1364
|
+
windowsHide: true,
|
|
1365
|
+
encoding: "utf-8",
|
|
1366
|
+
timeout: 2000,
|
|
1367
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
1368
|
+
input,
|
|
1369
|
+
cwd: os5.tmpdir()
|
|
1370
|
+
});
|
|
1371
|
+
}
|
|
1372
|
+
function probeLinuxBehavior() {
|
|
1373
|
+
const binary = _internals4.resolveBwrapBinary();
|
|
1374
|
+
const tempRoot = fs3.mkdtempSync(path5.join(os5.tmpdir(), "swarm-bwrap-probe-"));
|
|
1375
|
+
const allowedRoot = path5.join(tempRoot, "allowed");
|
|
1376
|
+
const inScopeFile = path5.join(allowedRoot, "inside.txt");
|
|
1377
|
+
const outOfScopeFile = path5.join(tempRoot, "outside.txt");
|
|
1378
|
+
fs3.mkdirSync(allowedRoot, { recursive: true });
|
|
1379
|
+
const reasons = [];
|
|
1380
|
+
let filesystem = "weak";
|
|
1381
|
+
let network = "weak";
|
|
1382
|
+
try {
|
|
1383
|
+
const baseArgs = [
|
|
1384
|
+
"--unshare-user",
|
|
1385
|
+
"--unshare-net",
|
|
1386
|
+
"--unshare-ipc",
|
|
1387
|
+
"--die-with-parent",
|
|
1388
|
+
"--new-session",
|
|
1389
|
+
"--cap-drop",
|
|
1390
|
+
"ALL",
|
|
1391
|
+
"--bind",
|
|
1392
|
+
allowedRoot,
|
|
1393
|
+
allowedRoot,
|
|
1394
|
+
"--dev",
|
|
1395
|
+
"/dev",
|
|
1396
|
+
"--ro-bind",
|
|
1397
|
+
"/etc",
|
|
1398
|
+
"/etc",
|
|
1399
|
+
"--ro-bind",
|
|
1400
|
+
"/usr",
|
|
1401
|
+
"/usr",
|
|
1402
|
+
"--ro-bind",
|
|
1403
|
+
"/lib",
|
|
1404
|
+
"/lib",
|
|
1405
|
+
"--ro-bind",
|
|
1406
|
+
"/lib64",
|
|
1407
|
+
"/lib64",
|
|
1408
|
+
"--proc",
|
|
1409
|
+
"/proc",
|
|
1410
|
+
"--unshare-pid"
|
|
1411
|
+
];
|
|
1412
|
+
const inScope = runBoundedSync(binary, [...baseArgs, "--", "/usr/bin/tee", inScopeFile], "ok");
|
|
1413
|
+
const outOfScope = runBoundedSync(binary, [...baseArgs, "--", "/usr/bin/tee", outOfScopeFile], "blocked");
|
|
1414
|
+
if (inScope.status === 0 && fs3.existsSync(inScopeFile) && outOfScope.status !== 0 && !fs3.existsSync(outOfScopeFile)) {
|
|
1415
|
+
filesystem = "real";
|
|
1416
|
+
reasons.push("bubblewrap allowed in-scope writes and blocked out-of-scope writes in a bounded probe");
|
|
1417
|
+
} else {
|
|
1418
|
+
reasons.push("bubblewrap denial behavior was not independently verified in a bounded probe");
|
|
1419
|
+
}
|
|
1420
|
+
try {
|
|
1421
|
+
const hostNetNs = fs3.readlinkSync("/proc/self/ns/net");
|
|
1422
|
+
const childNetNs = runBoundedSync(binary, [
|
|
1423
|
+
...baseArgs,
|
|
1424
|
+
"--",
|
|
1425
|
+
"/usr/bin/readlink",
|
|
1426
|
+
"/proc/self/ns/net"
|
|
1427
|
+
]);
|
|
1428
|
+
if (childNetNs.status === 0 && childNetNs.stdout.trim() !== "" && childNetNs.stdout.trim() !== hostNetNs.trim()) {
|
|
1429
|
+
network = "real";
|
|
1430
|
+
reasons.push("bubblewrap produced a distinct network namespace in a bounded probe");
|
|
1431
|
+
} else {
|
|
1432
|
+
reasons.push("bubblewrap network namespace isolation was not independently verified");
|
|
1433
|
+
}
|
|
1434
|
+
} catch {
|
|
1435
|
+
reasons.push("bubblewrap network namespace isolation was not independently verified");
|
|
1436
|
+
}
|
|
1437
|
+
} finally {
|
|
1438
|
+
cleanupProbeTempRoot(tempRoot, "bubblewrap", reasons);
|
|
1439
|
+
}
|
|
1440
|
+
return {
|
|
1441
|
+
filesystem,
|
|
1442
|
+
network,
|
|
1443
|
+
process: "none",
|
|
1444
|
+
reasons
|
|
1445
|
+
};
|
|
1446
|
+
}
|
|
1447
|
+
function probeMacOSBehavior() {
|
|
1448
|
+
const binary = _internals.resolveSandboxExecBinary();
|
|
1449
|
+
const tempRoot = fs3.mkdtempSync(path5.join(os5.tmpdir(), "swarm-seatbelt-probe-"));
|
|
1450
|
+
const allowedRoot = path5.join(tempRoot, "allowed");
|
|
1451
|
+
const sandboxTemp = path5.join(tempRoot, "sandbox-tmp");
|
|
1452
|
+
const inScopeFile = path5.join(allowedRoot, "inside.txt");
|
|
1453
|
+
const outOfScopeFile = path5.join(tempRoot, "outside.txt");
|
|
1454
|
+
fs3.mkdirSync(allowedRoot, { recursive: true });
|
|
1455
|
+
fs3.mkdirSync(sandboxTemp, { recursive: true });
|
|
1456
|
+
const profile = _internals.buildSandboxProfile([allowedRoot], sandboxTemp);
|
|
1457
|
+
const reasons = [];
|
|
1458
|
+
let filesystem = "weak";
|
|
1459
|
+
try {
|
|
1460
|
+
const inScope = runBoundedSync(binary, ["-p", profile, "/usr/bin/tee", inScopeFile], "ok");
|
|
1461
|
+
const outOfScope = runBoundedSync(binary, ["-p", profile, "/usr/bin/tee", outOfScopeFile], "blocked");
|
|
1462
|
+
if (inScope.status === 0 && fs3.existsSync(inScopeFile) && outOfScope.status !== 0 && !fs3.existsSync(outOfScopeFile)) {
|
|
1463
|
+
filesystem = "real";
|
|
1464
|
+
reasons.push("sandbox-exec allowed in-scope writes and blocked out-of-scope writes in a bounded probe");
|
|
1465
|
+
} else {
|
|
1466
|
+
reasons.push("sandbox-exec denial behavior was not independently verified in a bounded probe");
|
|
1467
|
+
}
|
|
1468
|
+
} finally {
|
|
1469
|
+
cleanupProbeTempRoot(tempRoot, "sandbox-exec", reasons);
|
|
1470
|
+
}
|
|
1471
|
+
reasons.push("(allow default) leaves network, IPC, and process-spawn behavior outside the boundary");
|
|
1472
|
+
return {
|
|
1473
|
+
filesystem,
|
|
1474
|
+
network: "none",
|
|
1475
|
+
process: "none",
|
|
1476
|
+
reasons
|
|
1477
|
+
};
|
|
1478
|
+
}
|
|
1479
|
+
function detectBehavioralEvidence(capability) {
|
|
1480
|
+
if (capability.status !== "enabled") {
|
|
1481
|
+
return {
|
|
1482
|
+
filesystem: "none",
|
|
1483
|
+
network: "none",
|
|
1484
|
+
process: "none",
|
|
1485
|
+
reasons: [capability.error ?? "sandbox mechanism unavailable"]
|
|
1486
|
+
};
|
|
1487
|
+
}
|
|
1488
|
+
if (capability.platform === "linux") {
|
|
1489
|
+
return probeLinuxBehavior();
|
|
1490
|
+
}
|
|
1491
|
+
if (capability.platform === "darwin") {
|
|
1492
|
+
return probeMacOSBehavior();
|
|
1493
|
+
}
|
|
1494
|
+
if (capability.platform === "win32") {
|
|
1495
|
+
const mechanism = capability.mechanism.toLowerCase();
|
|
1496
|
+
const appContainer = mechanism.includes("app-container");
|
|
1497
|
+
const restrictedToken = mechanism.includes("restricted-token");
|
|
1498
|
+
return {
|
|
1499
|
+
filesystem: appContainer || restrictedToken ? "weak" : "none",
|
|
1500
|
+
network: appContainer ? "weak" : "none",
|
|
1501
|
+
process: appContainer || restrictedToken ? "weak" : "none",
|
|
1502
|
+
reasons: []
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1505
|
+
return {
|
|
1506
|
+
filesystem: "none",
|
|
1507
|
+
network: "none",
|
|
1508
|
+
process: "none",
|
|
1509
|
+
reasons: [capability.error ?? "sandbox mechanism unavailable"]
|
|
1510
|
+
};
|
|
1511
|
+
}
|
|
1512
|
+
function _resetCapabilityCache() {
|
|
1513
|
+
_cached = undefined;
|
|
1514
|
+
_cachedProbeSourceIdentity = undefined;
|
|
1515
|
+
}
|
|
1516
|
+
function withProbeTimeout(cmd, args, ms) {
|
|
1517
|
+
return new Promise((resolve2, reject) => {
|
|
1518
|
+
const controller = new AbortController;
|
|
1519
|
+
const timer = setTimeout(() => {
|
|
1520
|
+
controller.abort();
|
|
1521
|
+
proc?.kill();
|
|
1522
|
+
}, ms);
|
|
1523
|
+
const unref = timer.unref;
|
|
1524
|
+
if (typeof unref === "function") {
|
|
1525
|
+
unref.call(timer);
|
|
1526
|
+
}
|
|
1527
|
+
let proc;
|
|
1528
|
+
try {
|
|
1529
|
+
proc = execFile(cmd, args, {
|
|
1530
|
+
signal: controller.signal,
|
|
1531
|
+
timeout: ms,
|
|
1532
|
+
windowsHide: true,
|
|
1533
|
+
cwd: os5.tmpdir()
|
|
1534
|
+
}, (error, stdout, _stderr) => {
|
|
1535
|
+
clearTimeout(timer);
|
|
1536
|
+
if (error) {
|
|
1537
|
+
const exc = error;
|
|
1538
|
+
if (exc.code === "ENOENT" || exc.code === "ENOTFOUND") {
|
|
1539
|
+
reject(new Error("binary not found"));
|
|
1540
|
+
} else {
|
|
1541
|
+
reject(error);
|
|
1542
|
+
}
|
|
1543
|
+
return;
|
|
1544
|
+
}
|
|
1545
|
+
resolve2(stdout?.trim() ?? "");
|
|
1546
|
+
});
|
|
1547
|
+
} catch (spawnError) {
|
|
1548
|
+
clearTimeout(timer);
|
|
1549
|
+
reject(spawnError);
|
|
1550
|
+
}
|
|
1551
|
+
});
|
|
1552
|
+
}
|
|
1553
|
+
async function probeLinux() {
|
|
1554
|
+
try {
|
|
1555
|
+
const binary = _internals4.resolveBwrapBinary();
|
|
1556
|
+
const output = await _internals5.withProbeTimeout(binary, ["--version"], 2000);
|
|
1557
|
+
if (output.length > 0) {
|
|
1558
|
+
return {
|
|
1559
|
+
status: "enabled",
|
|
1560
|
+
strength: "strong",
|
|
1561
|
+
mechanism: "Bubblewrap",
|
|
1562
|
+
platform: "linux"
|
|
1563
|
+
};
|
|
1564
|
+
}
|
|
1565
|
+
return {
|
|
1566
|
+
status: "disabled",
|
|
1567
|
+
mechanism: "Bubblewrap",
|
|
1568
|
+
platform: "linux",
|
|
1569
|
+
error: "binary returned empty version"
|
|
1570
|
+
};
|
|
1571
|
+
} catch (err) {
|
|
1572
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1573
|
+
if (msg === "binary not found") {
|
|
1574
|
+
return {
|
|
1575
|
+
status: "unsupported",
|
|
1576
|
+
mechanism: "Bubblewrap",
|
|
1577
|
+
platform: "linux",
|
|
1578
|
+
error: msg
|
|
1579
|
+
};
|
|
1580
|
+
}
|
|
1581
|
+
return {
|
|
1582
|
+
status: "disabled",
|
|
1583
|
+
mechanism: "Bubblewrap",
|
|
1584
|
+
platform: "linux",
|
|
1585
|
+
error: msg
|
|
1586
|
+
};
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
async function probeMacOS() {
|
|
1590
|
+
try {
|
|
1591
|
+
const binary = _internals.resolveSandboxExecBinary();
|
|
1592
|
+
const target = _internals.resolveProbeTargetBinary();
|
|
1593
|
+
const profile = _internals.buildProbeProfile(os5.tmpdir());
|
|
1594
|
+
await _internals5.withProbeTimeout(binary, ["-p", profile, target], 2000);
|
|
1595
|
+
return {
|
|
1596
|
+
status: "enabled",
|
|
1597
|
+
strength: "strong",
|
|
1598
|
+
mechanism: "sandbox-exec",
|
|
1599
|
+
platform: "darwin"
|
|
1600
|
+
};
|
|
1601
|
+
} catch (err) {
|
|
1602
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1603
|
+
if (msg === "binary not found") {
|
|
1604
|
+
return {
|
|
1605
|
+
status: "unsupported",
|
|
1606
|
+
mechanism: "sandbox-exec",
|
|
1607
|
+
platform: "darwin",
|
|
1608
|
+
error: msg
|
|
1609
|
+
};
|
|
1610
|
+
}
|
|
1611
|
+
return {
|
|
1612
|
+
status: "disabled",
|
|
1613
|
+
mechanism: "sandbox-exec",
|
|
1614
|
+
platform: "darwin",
|
|
1615
|
+
error: msg
|
|
1616
|
+
};
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
function probeWindows() {
|
|
1620
|
+
try {
|
|
1621
|
+
const { probe: runnerProbe } = (init_runner_client(), __toCommonJS(exports_runner_client));
|
|
1622
|
+
const result = runnerProbe();
|
|
1623
|
+
if (result.available) {
|
|
1624
|
+
return {
|
|
1625
|
+
status: "enabled",
|
|
1626
|
+
strength: "strong",
|
|
1627
|
+
platform: "win32",
|
|
1628
|
+
mechanism: `native-runner/${result.mode}`
|
|
1629
|
+
};
|
|
1630
|
+
}
|
|
1631
|
+
} catch {}
|
|
1632
|
+
try {
|
|
1633
|
+
const cmdBinary = resolveWindowsCommandProcessorBinary();
|
|
1634
|
+
const result = _internals5.spawnSync(cmdBinary, ["/c", "echo", "ok"], {
|
|
1635
|
+
windowsHide: true,
|
|
1636
|
+
encoding: "utf-8",
|
|
1637
|
+
timeout: 5000,
|
|
1638
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1639
|
+
});
|
|
1640
|
+
if (result.error) {
|
|
1641
|
+
return {
|
|
1642
|
+
status: "disabled",
|
|
1643
|
+
platform: "win32",
|
|
1644
|
+
mechanism: "PowerShell wrapper",
|
|
1645
|
+
error: `cmd.exe probe failed: ${result.error.code}`
|
|
1646
|
+
};
|
|
1647
|
+
}
|
|
1648
|
+
return result.status === 0 ? {
|
|
1649
|
+
status: "enabled",
|
|
1650
|
+
strength: "advisory",
|
|
1651
|
+
platform: "win32",
|
|
1652
|
+
mechanism: "PowerShell wrapper"
|
|
1653
|
+
} : {
|
|
1654
|
+
status: "disabled",
|
|
1655
|
+
platform: "win32",
|
|
1656
|
+
mechanism: "PowerShell wrapper",
|
|
1657
|
+
error: "cmd.exe probe returned non-zero"
|
|
1658
|
+
};
|
|
1659
|
+
} catch (err) {
|
|
1660
|
+
return {
|
|
1661
|
+
status: "disabled",
|
|
1662
|
+
platform: "win32",
|
|
1663
|
+
mechanism: "PowerShell wrapper",
|
|
1664
|
+
error: String(err)
|
|
1665
|
+
};
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
function isBubblewrapAvailable() {
|
|
1669
|
+
return _cached?.status === "enabled" && _cached?.platform === "linux";
|
|
1670
|
+
}
|
|
1671
|
+
function isSandboxExecAvailable() {
|
|
1672
|
+
return _cached?.status === "enabled" && _cached?.platform === "darwin";
|
|
1673
|
+
}
|
|
1674
|
+
function isWindowsSandboxAvailable() {
|
|
1675
|
+
return _cached?.status === "enabled" && _cached?.platform === "win32";
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
class SandboxCapabilityProbe {
|
|
1679
|
+
async detect() {
|
|
1680
|
+
const platform = process.platform;
|
|
1681
|
+
const probeSourceIdentity = currentProbeSourceIdentity(platform);
|
|
1682
|
+
if (_cached !== undefined && _cachedProbeSourceIdentity === probeSourceIdentity) {
|
|
1683
|
+
return _cached;
|
|
1684
|
+
}
|
|
1685
|
+
let detected;
|
|
1686
|
+
switch (platform) {
|
|
1687
|
+
case "linux":
|
|
1688
|
+
detected = await probeLinux();
|
|
1689
|
+
break;
|
|
1690
|
+
case "darwin":
|
|
1691
|
+
detected = await probeMacOS();
|
|
1692
|
+
break;
|
|
1693
|
+
case "win32":
|
|
1694
|
+
detected = probeWindows();
|
|
1695
|
+
break;
|
|
1696
|
+
default: {
|
|
1697
|
+
detected = {
|
|
1698
|
+
status: "unsupported",
|
|
1699
|
+
mechanism: "unknown",
|
|
1700
|
+
platform,
|
|
1701
|
+
error: `unsupported platform: ${platform}`
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
_cached = withProbeIdentity(upgradeCapability(detected, _internals5.detectBehavioralEvidence(detected)), probeSourceIdentity);
|
|
1706
|
+
_cachedProbeSourceIdentity = probeSourceIdentity;
|
|
1707
|
+
return _cached;
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
var _cached, _cachedProbeSourceIdentity, _internals5;
|
|
1711
|
+
var init_capability_probe = __esm(() => {
|
|
1712
|
+
init_logger();
|
|
1713
|
+
init_bubblewrap_executor();
|
|
1714
|
+
init_sandbox_exec_executor();
|
|
1715
|
+
_internals5 = {
|
|
1716
|
+
withProbeTimeout,
|
|
1717
|
+
spawnSync: spawnSync5,
|
|
1718
|
+
detectBehavioralEvidence,
|
|
1719
|
+
resolveWindowsCommandProcessorBinary,
|
|
1720
|
+
currentProbeSourceIdentity,
|
|
1721
|
+
removeProbeTempRoot: fs3.rmSync
|
|
1722
|
+
};
|
|
1723
|
+
});
|
|
1724
|
+
|
|
1725
|
+
export { assessSandboxRequirements, _resetCapabilityCache, _internals5 as _internals, isBubblewrapAvailable, isSandboxExecAvailable, isWindowsSandboxAvailable, SandboxCapabilityProbe, init_capability_probe, isValidEnvKey, isUntrustedEnvKey, getExecutor, init_executor };
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
SWARM_WORKTREE_DIR_NAME,
|
|
7
7
|
init_constants
|
|
8
|
-
} from "./index-
|
|
8
|
+
} from "./index-myt57pht.js";
|
|
9
9
|
import {
|
|
10
10
|
init_git_executable,
|
|
11
11
|
resolveGitExecutable
|
|
@@ -92,7 +92,7 @@ var _internals = {
|
|
|
92
92
|
symlinkSync: fs.symlinkSync
|
|
93
93
|
},
|
|
94
94
|
writeScopeToDisk: async (directory, taskId, files) => {
|
|
95
|
-
const { writeScopeToDisk: realWrite } = await import("./scope-persistence-
|
|
95
|
+
const { writeScopeToDisk: realWrite } = await import("./scope-persistence-5xt2m5ep.js");
|
|
96
96
|
return realWrite(directory, taskId, files);
|
|
97
97
|
},
|
|
98
98
|
writeLaneProfileToDisk: async (_worktreePath, _laneIndex, _envOverrides) => {
|