@tablation/crew 0.126.8 → 0.126.10

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 CHANGED
@@ -2747,11 +2747,12 @@ function tablationEndpoint(url) {
2747
2747
  }
2748
2748
  return { host, port };
2749
2749
  }
2750
- var TOOL_BINARIES = ["/usr/bin/curl", "/usr/bin/node", "/usr/local/bin/node", "/usr/bin/npm", "/usr/local/bin/npm", "/usr/local/bin/pnpm", "/usr/bin/corepack", "/usr/local/bin/corepack"];
2750
+ var CREW_BIN = "/opt/crew/bin";
2751
+ var TOOL_BINARIES = ["/usr/bin/curl", `${CREW_BIN}/node`, "/usr/bin/node", "/usr/local/bin/node", "/usr/bin/npm", "/usr/local/bin/npm", "/usr/local/bin/pnpm", "/usr/bin/corepack", "/usr/local/bin/corepack"];
2751
2752
  var GIT_BINARIES = ["/usr/bin/git", "/usr/lib/git-core/git-remote-http", "/usr/lib/git-core/git-remote-https"];
2752
2753
  function policyGroups(input) {
2753
2754
  const harness = `/usr/local/bin/${basename2(input.harnessBin)}`;
2754
- const harnessBins = [.../* @__PURE__ */ new Set([harness, `/usr/bin/${basename2(input.harnessBin)}`, "/usr/bin/node", "/usr/local/bin/node"])];
2755
+ const harnessBins = [.../* @__PURE__ */ new Set([`${CREW_BIN}/${basename2(input.harnessBin)}`, harness, `/usr/bin/${basename2(input.harnessBin)}`, `${CREW_BIN}/node`, "/usr/bin/node", "/usr/local/bin/node"])];
2755
2756
  const groups = [];
2756
2757
  const tablation = tablationEndpoint(input.tablationUrl);
2757
2758
  groups.push({
@@ -10792,8 +10793,10 @@ var SandboxRunner = class {
10792
10793
  return execFileP(this.cfg.bin, args, { env: o.env ?? process.env, maxBuffer: 16 * 1024 * 1024 });
10793
10794
  }
10794
10795
  async start(plan, o) {
10795
- const origin = this.originOf(plan.cwd);
10796
- if (!origin) throw new Error(`cannot find the origin remote of ${plan.cwd}, so there is nothing to clone into the sandbox`);
10796
+ const origin = plan.sandboxOrigin ?? (plan.repo ? null : this.originOf(plan.cwd));
10797
+ if (!origin) {
10798
+ throw new Error(plan.repo ? `cannot place the repository ${plan.repo} of ${plan.ticket ?? "this run"} on route ${plan.route}, so there is nothing to clone into the sandbox` : `cannot find the origin remote of ${plan.cwd}, so there is nothing to clone into the sandbox`);
10799
+ }
10797
10800
  const repo = parseRemote(origin);
10798
10801
  if (!repo) throw new Error(`cannot read a forge host and path from the origin remote ${origin}`);
10799
10802
  const name = sandboxName(plan);
@@ -10975,6 +10978,13 @@ function assemblePrompt(p) {
10975
10978
  }
10976
10979
  var AgentError = class extends Error {
10977
10980
  };
10981
+ function sandboxOriginFor(route2, repo) {
10982
+ if (!repo) return void 0;
10983
+ const repos = reposOf(route2);
10984
+ const target = repos.find((r) => r.name === repo) ?? (repos.length === 1 ? repos[0] : void 0);
10985
+ if (!target) return void 0;
10986
+ return originUrlOf(target.dir, "origin") ?? (target.remote ? cloneUrlFor(target.remote, { host: target.forgeHost }) : void 0);
10987
+ }
10978
10988
  function sandboxPolicyInputFor(route2, toolchain, o) {
10979
10989
  const repos = reposOf(route2);
10980
10990
  const forgeHosts = [...new Set(repos.map((r) => r.forgeHost ?? "github.com"))];
@@ -11152,6 +11162,7 @@ function planAgentRun(o) {
11152
11162
  const adapter = adapterFor(toolchain.harness);
11153
11163
  const code = codeBridgeFor(o, adapter.harness);
11154
11164
  const sandboxLsp = o.ship.runner === "sandbox" && adapter.harness === "claude" ? sandboxLspPluginFor(o.route, o.repo) : void 0;
11165
+ const sandboxOrigin = o.ship.runner === "sandbox" ? sandboxOriginFor(o.route, o.repo) : void 0;
11155
11166
  const sandboxFiles = [...code?.files ?? [], ...sandboxLsp?.files ?? []];
11156
11167
  const invocation = adapter.invocation(toolchain, {
11157
11168
  code,
@@ -11204,6 +11215,7 @@ function planAgentRun(o) {
11204
11215
  ...o.ship.runner === "sandbox" ? {
11205
11216
  runner: "sandbox",
11206
11217
  ...o.ship.sandbox ? { sandboxConfig: o.ship.sandbox } : {},
11218
+ ...sandboxOrigin ? { sandboxOrigin } : {},
11207
11219
  sandboxPolicy: sandboxPolicyInputFor(o.route, toolchain, { harnessBin: invocation.bin, repo: o.repo, sandbox: o.ship.sandbox }),
11208
11220
  ...sandboxFiles.length ? { sandboxFiles } : {}
11209
11221
  } : {},
@@ -14892,6 +14904,20 @@ async function runProvision(o, deps, write, human) {
14892
14904
  emit("route_enabled", `enabled route ${route2}`, { route: route2 });
14893
14905
  }
14894
14906
  }
14907
+ summary.seatKeys = [];
14908
+ for (const route2 of routeNames) {
14909
+ const res = deps.crew(["agents", "sync", route2]);
14910
+ const lines2 = res.stdout.split("\n").map((l) => l.trim());
14911
+ const minted = lines2.flatMap((l) => /^(\w+): agent key minted/.exec(l)?.[1] ?? []);
14912
+ const refused = lines2.filter((l) => /could not mint an agent key|^seat keys: not minted/.test(l));
14913
+ summary.seatKeys.push({ route: route2, minted });
14914
+ if (minted.length > 0) summary.changed = true;
14915
+ emit("seat_keys", `seat keys: ${minted.length} minted${minted.length > 0 ? ` (${minted.join(", ")})` : ""} for ${route2}`, { route: route2, minted });
14916
+ if (res.status >= 2 || refused.length > 0) {
14917
+ const why = refused[0] ?? (res.stderr.trim().split("\n").pop() || `crew agents sync exited ${res.status}`);
14918
+ return fail2(PROVISION_EXIT.failed, `seat keys for ${route2}: ${why}`, { stage: "seat_keys", route: route2 });
14919
+ }
14920
+ }
14895
14921
  const before = deps.installState();
14896
14922
  if (before.unitsStale || !before.running || !before.lingering) {
14897
14923
  const res = deps.crew(["install"]);
@@ -24646,6 +24646,8 @@ function parseEndpoint(raw, defaultPort = 443) {
24646
24646
  if (!IPV4.test(host) && !HOST.test(host)) throw new SandboxPolicyError(`"${raw}" is not a valid host name`);
24647
24647
  return { host, port };
24648
24648
  }
24649
+ var CREW_BIN = "/opt/crew/bin";
24650
+ var TOOL_BINARIES = ["/usr/bin/curl", `${CREW_BIN}/node`, "/usr/bin/node", "/usr/local/bin/node", "/usr/bin/npm", "/usr/local/bin/npm", "/usr/local/bin/pnpm", "/usr/bin/corepack", "/usr/local/bin/corepack"];
24649
24651
  function parseSandboxNetwork(raw, file, fail2) {
24650
24652
  if (raw === void 0 || raw === null) return void 0;
24651
24653
  if (typeof raw !== "object" || Array.isArray(raw)) throw fail2(`${file}: sandbox must be a mapping`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tablation/crew",
3
- "version": "0.126.8",
3
+ "version": "0.126.10",
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",