@tablation/crew 0.127.6 → 0.127.8

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.
Files changed (2) hide show
  1. package/dist/cli.js +23 -6
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -11563,10 +11563,7 @@ var SandboxRunner = class {
11563
11563
  }
11564
11564
  }
11565
11565
  };
11566
- function describeExecError(e) {
11567
- const err3 = e;
11568
- return (err3.stderr?.trim() || err3.message || String(e)).split("\n").slice(-3).join(" / ");
11569
- }
11566
+ var describeExecError = describe;
11570
11567
  function gitOrigin(cwd) {
11571
11568
  try {
11572
11569
  return execFileSync6("git", ["-C", cwd, "remote", "get-url", "origin"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
@@ -12795,9 +12792,10 @@ var realExec = (bin, args, o) => execFileP2(bin, args, { env: o?.env ?? process.
12795
12792
  var OPENSHELL_ATTACHABLE_LABEL = "openshell.ai/sandbox-attachable=true";
12796
12793
  var OPENSHELL_WORKSPACE_LABEL = "openshell.ai/sandbox-attachable-workspace";
12797
12794
  var VOLUME_ROOT = "/cache";
12795
+ var SANDBOX_WORKSPACE = "default";
12798
12796
  var DEFAULT_CACHE_SETTINGS = {
12799
12797
  engine: "docker",
12800
- workspace: "crew",
12798
+ workspace: SANDBOX_WORKSPACE,
12801
12799
  helperImage: "alpine/git:latest",
12802
12800
  depsLockfile: "pnpm-lock.yaml"
12803
12801
  };
@@ -12821,6 +12819,10 @@ function cloneScript(o) {
12821
12819
  const mirror = `${o.mirrorDir}/${mirrorRelPath(o.repo)}`;
12822
12820
  const depsRoot = `${o.mirrorDir}/${depsRelDir(o.repo)}`;
12823
12821
  return [
12822
+ // The mirror is written by the helper container as root and mounted read-only,
12823
+ // so git sees it as owned by someone else and refuses it. Global (not `-c`) so
12824
+ // it holds for every later git call in the run that reads through the alternates.
12825
+ `git config --global --add safe.directory '*'`,
12824
12826
  `git clone --quiet --shared ${q(mirror)} ${q(o.workDir)}`,
12825
12827
  `cd ${q(o.workDir)}`,
12826
12828
  `git remote set-url origin ${q(o.origin)}`,
@@ -12949,6 +12951,16 @@ var SandboxCache = class {
12949
12951
  ]);
12950
12952
  return true;
12951
12953
  }
12954
+ /** The workspace label the existing volume carries, or null when the volume is absent or unlabeled. A volume's labels cannot be changed in place. */
12955
+ async volumeWorkspace() {
12956
+ try {
12957
+ const { stdout } = await this.engine(["volume", "inspect", "--format", `{{index .Labels "${OPENSHELL_WORKSPACE_LABEL}"}}`, this.s.volume]);
12958
+ const v = stdout.trim();
12959
+ return v && v !== "<no value>" ? v : null;
12960
+ } catch {
12961
+ return null;
12962
+ }
12963
+ }
12952
12964
  helper(image, script, args, env = {}, extra = []) {
12953
12965
  const flags = Object.keys(env).flatMap((k) => ["-e", k]);
12954
12966
  return this.engine(["run", "--rm", "--label", DOCKER_LABEL_OWNER, "-v", `${this.s.volume}:${VOLUME_ROOT}`, ...extra, ...flags, "--entrypoint", "sh", image, "-c", script, "sh", ...args], { ...process.env, ...env });
@@ -13055,7 +13067,10 @@ var SandboxCache = class {
13055
13067
  };
13056
13068
  function describe(e) {
13057
13069
  const err3 = e;
13058
- return (err3.stderr?.trim() || err3.message || String(e)).split("\n").slice(-3).join(" / ");
13070
+ const lines2 = (err3.stderr?.trim() || err3.message || String(e)).split("\n");
13071
+ const tail3 = lines2.slice(-3);
13072
+ const first = lines2.find((l) => /^(fatal|error):/.test(l.trim()));
13073
+ return (first && !tail3.includes(first) ? [first, ...tail3] : tail3).join(" / ");
13059
13074
  }
13060
13075
  function cacheSettingsOf(cfg) {
13061
13076
  if (!cfg?.cacheVolume) return null;
@@ -30738,6 +30753,8 @@ watermark: ${state.watermark()}
30738
30753
  try {
30739
30754
  const missing = unmirroredRepos(sandboxCacheRepos(route2, cfg.ship), await new SandboxCache(cacheSettings).list());
30740
30755
  for (const r of missing) problems.push({ severity: "attention", kind: "sandbox_cache_unmirrored", route: route2.route, message: `${r} has no mirror in the cache volume ${cacheSettings.volume}, so sandboxed runs cannot clone it`, remedy: "see `crew sandbox cache` for the last refresh failure" });
30756
+ const labeled = await new SandboxCache(cacheSettings).volumeWorkspace();
30757
+ if (labeled !== null && labeled !== cacheSettings.workspace) problems.push({ severity: "blocker", kind: "sandbox_cache_workspace_mismatch", route: route2.route, message: `the cache volume ${cacheSettings.volume} is labeled for OpenShell workspace "${labeled}" but sandboxes are created in "${cacheSettings.workspace}", so the gateway refuses to mount it`, remedy: "run `crew sandbox cache --reset` to recreate the volume with the right label" });
30741
30758
  } catch {
30742
30759
  }
30743
30760
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tablation/crew",
3
- "version": "0.127.6",
3
+ "version": "0.127.8",
4
4
  "description": "A standing team of headless agents that picks work off a Tablation board, does it on a machine you control, and reports back.",
5
5
  "type": "module",
6
6
  "license": "MIT",