@clipboard-health/groundcrew 4.50.1 → 4.50.2

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
@@ -14,9 +14,9 @@ import { taskCli } from "./commands/task.js";
14
14
  import { createDefaultUpgradeCliOptions, upgradeCli } from "./commands/upgrade.js";
15
15
  import { errorMessage, parseDryRunPositionals, readEnvironmentVariable, readTaskArgument, setVerbose, writeError, writeOutput, } from "./lib/util.js";
16
16
  const REMOVED_SANDBOX_COMMAND_MESSAGE = [
17
- "`crew sandbox` is no longer supported.",
17
+ "'crew sandbox' is no longer supported.",
18
18
  "Groundcrew now launches agents inside existing sbx sandboxes but does not list, create, regenerate, authenticate, or remove them.",
19
- "Use the manual `sbx` workflow in README.md#docker-sandboxes-sdx-setup, then keep `agents.definitions.<agent>.sandbox.agent` in crew.config.ts so launches can address the existing sandbox.",
19
+ "Use the manual 'sbx' workflow in README.md#docker-sandboxes-sdx-setup, then keep 'agents.definitions.<agent>.sandbox.agent' in crew.config.ts so launches can address the existing sandbox.",
20
20
  ].join("\n");
21
21
  const requireFromCli = createRequire(import.meta.url);
22
22
  const SETUP_REPOS_REMOVED_MESSAGE = [
@@ -158,7 +158,7 @@ const SUBCOMMANDS = {
158
158
  invoke: interruptWorkspaceCli,
159
159
  },
160
160
  interrupt: {
161
- summary: "Deprecated alias for `crew stop`",
161
+ summary: "Deprecated alias for 'crew stop'",
162
162
  usage: "<task> [--reason <text>]",
163
163
  deprecated: true,
164
164
  invoke: async (argv) => {
@@ -354,7 +354,7 @@ function localCapabilityCheck(host, resolved) {
354
354
  required: false,
355
355
  hint: ok
356
356
  ? "ready"
357
- : "safehouse runner requires macOS with `safehouse` on PATH (install from https://agent-safehouse.dev/)",
357
+ : "safehouse runner requires macOS with 'safehouse' on PATH (install from https://agent-safehouse.dev/)",
358
358
  };
359
359
  }
360
360
  if (resolved === "sdx") {
@@ -365,7 +365,7 @@ function localCapabilityCheck(host, resolved) {
365
365
  required: false,
366
366
  hint: ok
367
367
  ? "ready"
368
- : "sdx runner requires `sbx` (Docker Sandboxes) on PATH (install from https://docs.docker.com/ai/sandboxes/)",
368
+ : "sdx runner requires 'sbx' (Docker Sandboxes) on PATH (install from https://docs.docker.com/ai/sandboxes/)",
369
369
  };
370
370
  }
371
371
  // resolved === "none"
@@ -135,7 +135,7 @@ function classifyRecovery(arguments_) {
135
135
  return {
136
136
  kind: "skip",
137
137
  issue,
138
- message: `Skipping ${issue.id}: worktree exists but no live workspace. Run \`crew cleanup ${naturalId}\` to allow re-provisioning.`,
138
+ message: `Skipping ${issue.id}: worktree exists but no live workspace. Run 'crew cleanup ${naturalId}' to allow re-provisioning.`,
139
139
  eventReason: "workspace_missing",
140
140
  };
141
141
  }
@@ -135,7 +135,7 @@ function buildLinearDescription(arguments_) {
135
135
  "## Groundcrew",
136
136
  "",
137
137
  `Repository: ${repository}`,
138
- "Implementation workflow: use the `core:go`/`go` skill when available. If that skill is unavailable, follow this repo's AGENTS.md/CLAUDE.md implementation workflow and run the documented verification.",
138
+ "Implementation workflow: use the `cb-work` skill. Follow this repo's AGENTS.md/CLAUDE.md implementation workflow and run the documented verification.",
139
139
  "",
140
140
  "## Task",
141
141
  "",
@@ -28,7 +28,7 @@ export const cmuxAdapter = {
28
28
  }
29
29
  const workspaceId = extractCmuxOpenId(output);
30
30
  if (workspaceId === undefined) {
31
- log(`cmux new-workspace returned unrecognized output for ${spec.name}; if a workspace was created, run \`cmux close-workspace\` manually.`);
31
+ log(`cmux new-workspace returned unrecognized output for ${spec.name}; if a workspace was created, run 'cmux close-workspace' manually.`);
32
32
  throw new Error(`Unexpected cmux output: ${output}`);
33
33
  }
34
34
  if (spec.url !== undefined) {
@@ -294,7 +294,7 @@ async function closeWorkspaceLeakedByFailedOpen(error, name, signal) {
294
294
  debug(`cmux new-workspace for ${name} exited non-zero but had created ${workspaceId}; closed the leaked workspace.`);
295
295
  }
296
296
  catch (closeError) {
297
- log(`cmux new-workspace for ${name} exited non-zero and left workspace ${workspaceId}; automatic close failed (${errorMessage(closeError)}). Run \`cmux close-workspace --workspace ${workspaceId}\` by hand.`);
297
+ log(`cmux new-workspace for ${name} exited non-zero and left workspace ${workspaceId}; automatic close failed (${errorMessage(closeError)}). Run 'cmux close-workspace --workspace ${workspaceId}' by hand.`);
298
298
  }
299
299
  }
300
300
  /**
@@ -417,7 +417,7 @@ function normalizeSandbox(value, configKey) {
417
417
  }
418
418
  function failRemovedConfigKey(configKey, reason) {
419
419
  fail(`${configKey} is no longer supported: ${reason} ` +
420
- "Provision and manage the sandbox yourself with `sbx` (for example `sbx create --name groundcrew-<agent> <agent> <projectDir>`), then keep only `agents.definitions.<agent>.sandbox.agent` in crew.config.ts.");
420
+ "Provision and manage the sandbox yourself with 'sbx' (for example 'sbx create --name groundcrew-<agent> <agent> <projectDir>'), then keep only 'agents.definitions.<agent>.sandbox.agent' in crew.config.ts.");
421
421
  }
422
422
  function failIfLegacyModelKeys(name, override) {
423
423
  if (!isPlainObject(override)) {
@@ -33,7 +33,7 @@ export function resolveSafehouseClearancePath(baseUrl = import.meta.url) {
33
33
  }
34
34
  catch (error) {
35
35
  throw new Error("@clipboard-health/clearance is required by @clipboard-health/groundcrew but could not be resolved. " +
36
- "Install it alongside groundcrew (for example: `npm install -g @clipboard-health/clearance`).", { cause: error });
36
+ "Install it alongside groundcrew (for example: 'npm install -g @clipboard-health/clearance').", { cause: error });
37
37
  }
38
38
  return path.resolve(path.dirname(clearancePackageJson), "safehouse", "safehouse-clearance");
39
39
  }
@@ -303,10 +303,10 @@ export function buildLaunchCommand(arguments_) {
303
303
  // `runner === "safehouse"` but `cmd` already starts with `safehouse` — the
304
304
  // user owns env forwarding in that case, so there's no wrap flag for us to
305
305
  // inject into. Fail loudly instead of silently dropping the contract.
306
- throw new Error("preLaunchEnv cannot be injected when `cmd` starts with `safehouse` — your cmd owns the wrap, so add the names to its own `--env-pass=` flag, or drop the `safehouse` prefix from `cmd` to let groundcrew compose the flag for you.");
306
+ throw new Error("preLaunchEnv cannot be injected when 'cmd' starts with 'safehouse' — your cmd owns the wrap, so add the names to its own '--env-pass=' flag, or drop the 'safehouse' prefix from 'cmd' to let groundcrew compose the flag for you.");
307
307
  }
308
308
  if (arguments_.workerEnvironment !== undefined && arguments_.runner === "safehouse") {
309
- throw new Error("workerEnvironment cannot be injected when `cmd` starts with `safehouse` — your cmd owns the wrap, so add GROUNDCREW_TASK_ID,GROUNDCREW_COMPLETE to its own `--env-pass=` flag, or drop the `safehouse` prefix from `cmd` to let groundcrew compose the flag for you.");
309
+ throw new Error("workerEnvironment cannot be injected when 'cmd' starts with 'safehouse' — your cmd owns the wrap, so add GROUNDCREW_TASK_ID,GROUNDCREW_COMPLETE to its own '--env-pass=' flag, or drop the 'safehouse' prefix from 'cmd' to let groundcrew compose the flag for you.");
310
310
  }
311
311
  return buildUnwrappedHostLaunchCommand(arguments_);
312
312
  }
@@ -33,7 +33,7 @@ export function assertLocalRunnerRequirements(host, runner) {
33
33
  throw new Error("Local groundcrew runs with the safehouse runner require macOS. On Linux/WSL, set local.runner to 'sdx' (default) or 'auto'.");
34
34
  }
35
35
  if (!host.hasSafehouse) {
36
- throw new Error("Local groundcrew runs require `safehouse` on PATH. Install Safehouse from https://agent-safehouse.dev/ and retry.");
36
+ throw new Error("Local groundcrew runs require 'safehouse' on PATH. Install Safehouse from https://agent-safehouse.dev/ and retry.");
37
37
  }
38
38
  return;
39
39
  }
@@ -42,7 +42,7 @@ export function assertLocalRunnerRequirements(host, runner) {
42
42
  throw new Error("Local groundcrew runs with the sdx runner require macOS or Linux.");
43
43
  }
44
44
  if (!host.hasSbx) {
45
- throw new Error("Local groundcrew runs with the sdx runner require `sbx` (Docker Sandboxes) on PATH. Install from https://docs.docker.com/ai/sandboxes/ and retry.");
45
+ throw new Error("Local groundcrew runs with the sdx runner require 'sbx' (Docker Sandboxes) on PATH. Install from https://docs.docker.com/ai/sandboxes/ and retry.");
46
46
  }
47
47
  return;
48
48
  }
@@ -41,7 +41,7 @@ const TMUX_SESSION_PER_TASK_ENV = "GROUNDCREW_TMUX_SESSION_PER_TASK";
41
41
  const TMUX_SESSION_DEFAULT_WARNING = [
42
42
  "WARNING: tmux window mode is deprecated; tmux session-per-task mode will become the default soon.",
43
43
  `Opt in now with ${TMUX_SESSION_PER_TASK_ENV}=1.`,
44
- "Migration: attach with `tmux attach -t <task>` instead of `tmux attach -t groundcrew:<task>`; each task gets its own tmux session; `crew stop` and `crew cleanup` close that managed session; set GROUNDCREW_KEEP_DEAD_WINDOWS=1 to keep exited scrollback.",
44
+ "Migration: attach with 'tmux attach -t <task>' instead of 'tmux attach -t groundcrew:<task>'; each task gets its own tmux session; 'crew stop' and 'crew cleanup' close that managed session; set GROUNDCREW_KEEP_DEAD_WINDOWS=1 to keep exited scrollback.",
45
45
  ].join("\n");
46
46
  const ADAPTER_LOADER_BY_KIND = {
47
47
  cmux: async () => {
@@ -519,7 +519,7 @@ function describeDirtyWorktree(arguments_) {
519
519
  }
520
520
  const summary = parts.join(" and ");
521
521
  const pronoun = modified + untracked === 1 ? "it" : "them";
522
- return `worktree has ${summary}. Run \`crew cleanup --force ${task}\` to discard ${pronoun}, or commit/stash in ${dir} first.`;
522
+ return `worktree has ${summary}. Run 'crew cleanup --force ${task}' to discard ${pronoun}, or commit/stash in ${dir} first.`;
523
523
  }
524
524
  async function probeWorktreeRegistration(arguments_) {
525
525
  let output;
@@ -542,7 +542,7 @@ async function probeWorktreeRegistration(arguments_) {
542
542
  }
543
543
  function describeOrphanWorktree(arguments_) {
544
544
  const { task, dir } = arguments_;
545
- return `directory exists but is not a registered git worktree. Run \`crew cleanup --force ${task}\` to remove ${dir}, or inspect it first if it may contain valuable files.`;
545
+ return `directory exists but is not a registered git worktree. Run 'crew cleanup --force ${task}' to remove ${dir}, or inspect it first if it may contain valuable files.`;
546
546
  }
547
547
  function expectedHostWorktreeDir(config, entry) {
548
548
  return path.resolve(worktreeBaseDir(config), `${entry.repository}-${entry.task}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clipboard-health/groundcrew",
3
- "version": "4.50.1",
3
+ "version": "4.50.2",
4
4
  "description": "Linear-driven orchestrator that launches AI coding agents in git worktrees, with workspace lifecycle and usage tracking.",
5
5
  "keywords": [
6
6
  "agent",
@@ -72,7 +72,7 @@
72
72
  "@clipboard-health/clearance": "1.6.6",
73
73
  "@linear/sdk": "89.0.0",
74
74
  "agent-trust": "1.0.0",
75
- "cosmiconfig": "9.0.2",
75
+ "cosmiconfig": "10.0.0",
76
76
  "tslib": "2.8.1",
77
77
  "zod": "4.4.3"
78
78
  },
@@ -88,8 +88,8 @@
88
88
  "dependency-cruiser": "18.1.0",
89
89
  "husky": "9.1.7",
90
90
  "jscpd": "5.0.14",
91
- "knip": "6.29.0",
92
- "lint-staged": "17.2.0",
91
+ "knip": "6.31.0",
92
+ "lint-staged": "17.3.0",
93
93
  "markdownlint-cli2": "0.23.2",
94
94
  "nx": "23.1.0",
95
95
  "oxfmt": "0.61.0",