@clipboard-health/groundcrew 4.0.3 → 4.2.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.
Files changed (64) hide show
  1. package/README.md +37 -13
  2. package/crew.config.example.ts +5 -18
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +27 -49
  5. package/dist/commands/resumeWorkspace.d.ts.map +1 -1
  6. package/dist/commands/resumeWorkspace.js +1 -2
  7. package/dist/commands/setupWorkspace.d.ts.map +1 -1
  8. package/dist/commands/setupWorkspace.js +1 -7
  9. package/dist/commands/upgrade.d.ts +0 -11
  10. package/dist/commands/upgrade.d.ts.map +1 -1
  11. package/dist/commands/upgrade.js +14 -100
  12. package/dist/lib/agentLaunch.d.ts +0 -6
  13. package/dist/lib/agentLaunch.d.ts.map +1 -1
  14. package/dist/lib/agentLaunch.js +1 -12
  15. package/dist/lib/cmuxAdapter.d.ts +8 -0
  16. package/dist/lib/cmuxAdapter.d.ts.map +1 -0
  17. package/dist/lib/cmuxAdapter.js +163 -0
  18. package/dist/lib/config.d.ts +2 -76
  19. package/dist/lib/config.d.ts.map +1 -1
  20. package/dist/lib/config.js +29 -102
  21. package/dist/lib/launchCommand.d.ts +3 -3
  22. package/dist/lib/sandboxName.d.ts +9 -0
  23. package/dist/lib/sandboxName.d.ts.map +1 -0
  24. package/dist/lib/sandboxName.js +12 -0
  25. package/dist/lib/tmuxAdapter.d.ts +9 -0
  26. package/dist/lib/tmuxAdapter.d.ts.map +1 -0
  27. package/dist/lib/tmuxAdapter.js +156 -0
  28. package/dist/lib/workspaceAdapter.d.ts +79 -0
  29. package/dist/lib/workspaceAdapter.d.ts.map +1 -0
  30. package/dist/lib/workspaceAdapter.js +17 -0
  31. package/dist/lib/workspaces.d.ts +7 -55
  32. package/dist/lib/workspaces.d.ts.map +1 -1
  33. package/dist/lib/workspaces.js +8 -404
  34. package/package.json +1 -2
  35. package/dist/commands/sandbox/auth.d.ts +0 -3
  36. package/dist/commands/sandbox/auth.d.ts.map +0 -1
  37. package/dist/commands/sandbox/auth.js +0 -227
  38. package/dist/commands/sandbox/index.d.ts +0 -2
  39. package/dist/commands/sandbox/index.d.ts.map +0 -1
  40. package/dist/commands/sandbox/index.js +0 -47
  41. package/dist/commands/sandbox/inspect.d.ts +0 -2
  42. package/dist/commands/sandbox/inspect.d.ts.map +0 -1
  43. package/dist/commands/sandbox/inspect.js +0 -18
  44. package/dist/commands/sandbox/lifecycle.d.ts +0 -7
  45. package/dist/commands/sandbox/lifecycle.d.ts.map +0 -1
  46. package/dist/commands/sandbox/lifecycle.js +0 -68
  47. package/dist/commands/sandbox/model.d.ts +0 -10
  48. package/dist/commands/sandbox/model.d.ts.map +0 -1
  49. package/dist/commands/sandbox/model.js +0 -37
  50. package/dist/commands/sandbox/picker.d.ts +0 -20
  51. package/dist/commands/sandbox/picker.d.ts.map +0 -1
  52. package/dist/commands/sandbox/picker.js +0 -23
  53. package/dist/commands/setupRepos.d.ts +0 -44
  54. package/dist/commands/setupRepos.d.ts.map +0 -1
  55. package/dist/commands/setupRepos.js +0 -212
  56. package/dist/lib/dockerSandbox.d.ts +0 -43
  57. package/dist/lib/dockerSandbox.d.ts.map +0 -1
  58. package/dist/lib/dockerSandbox.js +0 -69
  59. package/dist/lib/sandboxGitDefaults.d.ts +0 -10
  60. package/dist/lib/sandboxGitDefaults.d.ts.map +0 -1
  61. package/dist/lib/sandboxGitDefaults.js +0 -31
  62. package/dist/lib/upgrade.d.ts +0 -66
  63. package/dist/lib/upgrade.d.ts.map +0 -1
  64. package/dist/lib/upgrade.js +0 -178
package/README.md CHANGED
@@ -63,7 +63,9 @@ npm install -g @clipboard-health/groundcrew
63
63
  crew init && $EDITOR crew.config.ts
64
64
 
65
65
  # 4. Clone the repos referenced in your config
66
- crew setup repos
66
+ PROJECT_DIR="$HOME/dev/c"
67
+ mkdir -p "$PROJECT_DIR/OWNER"
68
+ git clone git@github.com:OWNER/REPO.git "$PROJECT_DIR/OWNER/REPO"
67
69
 
68
70
  # 5. Export your Linear API key
69
71
  export GROUNDCREW_LINEAR_API_KEY="lin_api_..."
@@ -86,14 +88,35 @@ crew status [<TICKET>] # inspect current state
86
88
  crew run # one-shot orchestration
87
89
  crew run --watch # poll forever
88
90
  crew start <TICKET> # provision + launch one ticket now
89
- crew setup repos [<repo>...] [--dry-run] # clone known repos via gh
90
91
  crew stop <TICKET> [--reason <text>] # stop workspace, keep worktree
91
92
  crew resume <TICKET> # reopen a paused ticket
92
93
  crew cleanup <TICKET> # tear down every worktree for a ticket
94
+ crew upgrade [<version>] # reinstall crew globally through npm
93
95
  ```
94
96
 
95
97
  Deprecated aliases still work but print a warning and will be removed in the next major version: `crew interrupt` → `crew stop`, `crew run --ticket <TICKET>` → `crew start <TICKET>`, `crew doctor --ticket <TICKET>` → `crew status <TICKET>`.
96
98
 
99
+ ## Manual Repository Bootstrap
100
+
101
+ Groundcrew no longer clones repositories for you. For each `workspace.knownRepositories` entry,
102
+ clone the repository into `workspace.projectDir` using the same relative path that appears in the
103
+ config. For an `OWNER/REPO` entry:
104
+
105
+ ```bash
106
+ PROJECT_DIR="$HOME/dev/c"
107
+ mkdir -p "$PROJECT_DIR/OWNER"
108
+ git clone git@github.com:OWNER/REPO.git "$PROJECT_DIR/OWNER/REPO"
109
+ ```
110
+
111
+ HTTPS works the same way if you do not use SSH:
112
+
113
+ ```bash
114
+ git clone https://github.com/OWNER/REPO.git "$PROJECT_DIR/OWNER/REPO"
115
+ ```
116
+
117
+ Bare-name entries do not include an owner, so choose the correct remote URL yourself and clone it to
118
+ `$PROJECT_DIR/<name>`. `crew setup repos` now exits non-zero and points back to this section.
119
+
97
120
  ## Configuration
98
121
 
99
122
  Two keys are required; everything else has a default.
@@ -143,7 +166,7 @@ Resolution order: `GROUNDCREW_CONFIG` → cosmiconfig project-walk from cwd (any
143
166
  | `models.definitions.<name>.cmd` | — | Shell command launched for the model. Runs in the worktree through the resolved `local.runner`. `{{worktree}}` is replaced before launch; `{{sandbox}}` expands to the sbx sandbox name under the sdx runner and an empty string otherwise. |
144
167
  | `models.definitions.<name>.color` | — | Color for the workspace status pill (cmux only; tmux silently drops it). |
145
168
  | `models.definitions.<name>.usage` | optional | If set, codexbar usage is fetched for this model and gated by `sessionLimitPercentage`. Falls back to default when unset, with gating enabled for known models. When `usage.codexbar.source` is omitted, groundcrew uses `oauth` for Codex/Claude on macOS, `auto` for other macOS providers, and `cli` elsewhere. Set to `{ disabled: true }` to disable usage gating. |
146
- | `models.definitions.<name>.sandbox` | optional | Docker Sandboxes binding for the model. Required at launch when `local.runner` resolves to `sdx`. Fields: `agent` (required sbx agent name), `template`, `kits`, `setupCommand` (override for the inside-sandbox setup script). |
169
+ | `models.definitions.<name>.sandbox` | optional | Docker Sandboxes binding for the model. Required at launch when `local.runner` resolves to `sdx`. Fields: `agent` (required sbx agent name) and `setupCommand` (override for the inside-sandbox setup script). Groundcrew assumes the `groundcrew-<agent>` sandbox already exists. |
147
170
  | `models.definitions.<name>.disabled` | optional | When set to exactly `true`, drops the named shipped default (`claude` or `codex`). Doctor skips probing it; `agent-<name>` labels fall back to `models.default` with a warning. |
148
171
  | `prompts.initial` | unattended template | First message sent to the agent. Placeholders: `{{ticket}}`, `{{worktree}}`, `{{title}}`, `{{description}}`. Override this from `crew.config.ts` for team-specific statuses, tools, plugins, or review loops. |
149
172
  | `workspaceKind` | `"auto"` | Terminal session manager. `"auto"` picks `cmux` when on PATH, else `tmux`. Set to `"cmux"` or `"tmux"` to fail loudly when the chosen backend is missing. |
@@ -188,9 +211,17 @@ Watch `${XDG_CACHE_HOME:-$HOME/.cache}/clearance/clearance.log` for `DENY` lines
188
211
  <details>
189
212
  <summary>Docker Sandboxes (sdx) setup</summary>
190
213
 
191
- Each model that runs under `sdx` needs a `sandbox: { agent: "<sbx-agent>" }` block in `crew.config.ts`. Groundcrew names sandboxes `groundcrew-<agent>` (e.g. `groundcrew-claude`) and reuses one sandbox per agent across repos and tickets. First-time agent auth happens inside the sandbox the first time it launches. To bootstrap manually instead, run `sbx create --name groundcrew-<agent> <agent> <projectDir>` once.
214
+ Each model that runs under `sdx` needs a `sandbox: { agent: "<sbx-agent>" }` block in `crew.config.ts`. Groundcrew addresses the sandbox as `groundcrew-<agent>` (e.g. `groundcrew-claude`) and reuses one existing sandbox per agent across repos and tickets.
192
215
 
193
- Groundcrew auto-creates sandboxes when missing but never deletes them — they persist across tickets and `crew cleanup`. Auth state lives inside the sandbox, so deleting it forces a re-login. Manage with `sbx ls` / `sbx rm`.
216
+ First-time setup is manual:
217
+
218
+ ```bash
219
+ sbx create --name groundcrew-claude claude <projectDir>
220
+ sbx exec -it groundcrew-claude claude auth login
221
+ sbx exec -it groundcrew-claude gh auth login
222
+ ```
223
+
224
+ Replace `claude` with the sbx agent for the model and `<projectDir>` with `workspace.projectDir` from `crew.config.ts`. Manage lifecycle and auth with `sbx` directly (`sbx ls`, `sbx exec`, `sbx rm`). Groundcrew does not create, authenticate, regenerate, list, or remove sandboxes.
194
225
 
195
226
  </details>
196
227
 
@@ -238,7 +269,7 @@ In Progress (state.type=started) — Multi-event extractor: year inference can p
238
269
 
239
270
  ### `crew start <TICKET>`
240
271
 
241
- Provisions and launches one ticket immediately, bypassing orchestrator eligibility. Use it to dispatch a specific ticket on demand — including unlabeled tickets that `crew run` ignores. (Replaces the deprecated `crew run --ticket <TICKET>`.)
272
+ Launches one ticket immediately, bypassing orchestrator eligibility. Use it to dispatch a specific ticket on demand — including unlabeled tickets that `crew run` ignores. (Replaces the deprecated `crew run --ticket <TICKET>`.)
242
273
 
243
274
  ```bash
244
275
  crew start HRD-442
@@ -500,13 +531,6 @@ The handoff is `<your cmd> "<prompt>"`. `claude`, `codex`, and `cursor-agent` al
500
531
 
501
532
  </details>
502
533
 
503
- <details>
504
- <summary><code>crew setup repos</code> only auto-clones <code>owner/repo</code> entries</summary>
505
-
506
- Bare-name entries in `workspace.knownRepositories` (e.g. `"api"` rather than `"clipboardhealth/api"`) are skipped with a hint to clone manually — the command refuses to guess the owner. After a partial setup, the exit code is non-zero so CI gates notice; rerun is idempotent once you clone the bare ones into `<projectDir>/<name>` yourself.
507
-
508
- </details>
509
-
510
534
  ## Development
511
535
 
512
536
  Clone the repo and the `crew` / `crew:op` scripts execute straight from TypeScript source — no build step needed.
@@ -73,24 +73,11 @@ export default {
73
73
  // // macOS when you need an agent to use Docker safely.
74
74
  // local: { runner: "auto" },
75
75
  //
76
- // // Additional auth recipes for `crew sandbox auth <model> <tool>`. The
77
- // // shipped recipes (claude/codex/cursor agents + github tool) are merged
78
- // // with whatever you declare here; your recipe wins on key collision.
79
- // // Describe each tool's in-sandbox login + status commands and a regex
80
- // // that matches its logged-in output. Omit `kind` for cross-cutting
81
- // // tools that should appear in every sandbox's picker; set
82
- // // `kind: "agent"` to scope a recipe to a single sbx agent.
83
- // sandbox: {
84
- // authRecipes: {
85
- // gcloud: {
86
- // displayName: "gcloud",
87
- // binary: "gcloud",
88
- // loginArgs: ["auth", "login", "--no-launch-browser"],
89
- // statusArgs: ["auth", "list", "--filter=status:ACTIVE", "--format=value(account)"],
90
- // authenticatedPattern: /@/,
91
- // },
92
- // },
93
- // },
76
+ // // Groundcrew does not create or authenticate sdx sandboxes. For an sdx
77
+ // // model, create the matching sandbox yourself before first launch:
78
+ // // sbx create --name groundcrew-claude claude ~/dev/groundcrew
79
+ // // sbx exec -it groundcrew-claude claude auth login
80
+ // // sbx exec -it groundcrew-claude gh auth login
94
81
  //
95
82
  // prompts: {
96
83
  // // Keep personal workflow instructions next to this config, for example
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAwQA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCvD"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAmPA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCvD"}
package/dist/cli.js CHANGED
@@ -5,16 +5,21 @@ import { initConfigCli } from "./commands/init.js";
5
5
  import { interruptWorkspaceCli } from "./commands/interruptWorkspace.js";
6
6
  import { orchestrate } from "./commands/orchestrator.js";
7
7
  import { resumeWorkspaceCli } from "./commands/resumeWorkspace.js";
8
- import { sandboxCli } from "./commands/sandbox/index.js";
9
- import { setupReposCli } from "./commands/setupRepos.js";
10
8
  import { setupWorkspaceCli } from "./commands/setupWorkspace.js";
11
9
  import { statusCli } from "./commands/status.js";
12
10
  import { createDefaultUpgradeCliOptions, upgradeCli } from "./commands/upgrade.js";
13
- import { computeUpgradeNudge, defaultUpgradeCheckCachePath, fetchLatestVersion, } from "./lib/upgrade.js";
14
- import { errorMessage, parseDryRunPositionals, readEnvironmentVariable, readTicketArgument, writeError, writeOutput, } from "./lib/util.js";
15
- const NUDGE_TTL_MS = 6 * 60 * 60 * 1000;
16
- const NUDGE_FETCH_TIMEOUT_MS = 1000;
11
+ import { errorMessage, parseDryRunPositionals, readTicketArgument, writeError, writeOutput, } from "./lib/util.js";
12
+ const REMOVED_SANDBOX_COMMAND_MESSAGE = [
13
+ "`crew sandbox` is no longer supported.",
14
+ "Groundcrew now launches agents inside existing sbx sandboxes but does not list, create, regenerate, authenticate, or remove them.",
15
+ "Use the manual `sbx` workflow in README.md#docker-sandboxes-sdx-setup, then keep `models.definitions.<model>.sandbox.agent` in crew.config.ts so launches can address the existing sandbox.",
16
+ ].join("\n");
17
17
  const requireFromCli = createRequire(import.meta.url);
18
+ const SETUP_REPOS_REMOVED_MESSAGE = [
19
+ "crew setup repos was removed.",
20
+ "Clone repositories manually with git clone into workspace.projectDir.",
21
+ "See README.md#manual-repository-bootstrap for the replacement workflow.",
22
+ ].join(" ");
18
23
  /**
19
24
  * Prints a deprecation warning to stderr naming the canonical command and that
20
25
  * the old form is removed in the next major, then lets the caller proceed.
@@ -23,13 +28,12 @@ function warnDeprecated(forms) {
23
28
  writeError(`crew ${forms.oldForm} is deprecated and will be removed in the next major version; use crew ${forms.newForm} instead.`);
24
29
  }
25
30
  function setupUsage() {
26
- return "Usage: crew setup repos [--dry-run] [<repo>...]";
31
+ return `Usage: crew setup repos\n\n${SETUP_REPOS_REMOVED_MESSAGE}`;
27
32
  }
28
33
  async function setupCli(argv) {
29
- const [verb, ...rest] = argv;
34
+ const [verb] = argv;
30
35
  if (verb === "repos") {
31
- await setupReposCli(rest);
32
- return;
36
+ throw new Error(SETUP_REPOS_REMOVED_MESSAGE);
33
37
  }
34
38
  throw new Error(setupUsage());
35
39
  }
@@ -76,27 +80,10 @@ async function startCli(argv) {
76
80
  async function upgradeCliInvoke(argv) {
77
81
  const metadata = packageMetadata();
78
82
  await upgradeCli(argv, async () => await createDefaultUpgradeCliOptions({
79
- currentVersion: metadata.version,
80
83
  packageName: metadata.name,
81
84
  cliMetaUrl: import.meta.url,
82
85
  }));
83
86
  }
84
- async function maybeRunUpgradeNudge(metadata) {
85
- const message = await computeUpgradeNudge({
86
- currentVersion: metadata.version,
87
- packageName: metadata.name,
88
- cachePath: defaultUpgradeCheckCachePath(),
89
- ttlMs: NUDGE_TTL_MS,
90
- fetchTimeoutMs: NUDGE_FETCH_TIMEOUT_MS,
91
- registry: readEnvironmentVariable("npm_config_registry"),
92
- noUpgradeCheck: readEnvironmentVariable("GROUNDCREW_NO_UPGRADE_CHECK") === "1",
93
- now: Date.now,
94
- fetcher: fetchLatestVersion,
95
- });
96
- if (message !== undefined) {
97
- writeError(message);
98
- }
99
- }
100
87
  function doctorTicketAlias(argv) {
101
88
  if (argv[0] !== "--ticket") {
102
89
  return undefined;
@@ -132,7 +119,7 @@ const SUBCOMMANDS = {
132
119
  invoke: runCli,
133
120
  },
134
121
  start: {
135
- summary: "Provision and launch one ticket immediately, bypassing eligibility",
122
+ summary: "Launch one ticket immediately, bypassing eligibility",
136
123
  usage: "<ticket> [--dry-run]",
137
124
  invoke: startCli,
138
125
  },
@@ -170,34 +157,28 @@ const SUBCOMMANDS = {
170
157
  usage: "<ticket>",
171
158
  invoke: resumeWorkspaceCli,
172
159
  },
173
- sandbox: {
174
- summary: "Manage Docker Sandboxes (sbx) for configured models",
175
- usage: "<list|ensure|regenerate|auth|rm> [...args]",
176
- invoke: sandboxCli,
177
- },
178
160
  setup: {
179
- summary: "Project-level setup commands (currently: repos)",
180
- usage: "repos [--dry-run] [<repo>...]",
161
+ summary: "Removed repository bootstrap command",
162
+ usage: "repos",
163
+ hidden: true,
181
164
  invoke: setupCli,
182
165
  },
183
166
  upgrade: {
184
167
  summary: "Install the latest version of crew (or pin to a specific version)",
185
- usage: "[<version>] [--check]",
168
+ usage: "[<version>]",
186
169
  invoke: upgradeCliInvoke,
187
170
  },
188
171
  };
189
172
  function printHelp() {
190
- const width = Math.max(...Object.keys(SUBCOMMANDS).map((key) => key.length));
173
+ const visibleCommands = Object.entries(SUBCOMMANDS).filter(([, command]) => command.hidden !== true && command.deprecated !== true);
174
+ const width = Math.max(...visibleCommands.map(([key]) => key.length));
191
175
  writeOutput("Usage: crew <command> [...args]\n");
192
176
  writeOutput("Options:");
193
177
  writeOutput(" -h, --help Show help");
194
178
  writeOutput(" -v, --version Print version");
195
179
  writeOutput("");
196
180
  writeOutput("Commands:");
197
- for (const [name, command] of Object.entries(SUBCOMMANDS)) {
198
- if (command.deprecated === true) {
199
- continue;
200
- }
181
+ for (const [name, command] of visibleCommands) {
201
182
  writeOutput(` ${name.padEnd(width)} ${command.summary}`);
202
183
  writeOutput(` ${" ".repeat(width)} → crew ${name} ${command.usage}`);
203
184
  }
@@ -224,6 +205,11 @@ export async function run(argv) {
224
205
  writeOutput(packageVersion());
225
206
  return;
226
207
  }
208
+ if (subcommand === "sandbox") {
209
+ writeError(REMOVED_SANDBOX_COMMAND_MESSAGE);
210
+ process.exitCode = 1;
211
+ return;
212
+ }
227
213
  const command = SUBCOMMANDS[subcommand];
228
214
  if (!command) {
229
215
  writeError(`Unknown command: ${subcommand}\n`);
@@ -231,14 +217,6 @@ export async function run(argv) {
231
217
  process.exitCode = 1;
232
218
  return;
233
219
  }
234
- if (subcommand !== "upgrade") {
235
- try {
236
- await maybeRunUpgradeNudge(packageMetadata());
237
- }
238
- catch {
239
- // Passive nudge is never load-bearing; never block the user's command.
240
- }
241
- }
242
220
  try {
243
221
  await command.invoke(rest);
244
222
  }
@@ -1 +1 @@
1
- {"version":3,"file":"resumeWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/resumeWorkspace.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAcnE,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;CAChB;AA6HD,wBAAsB,eAAe,CACnC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA6Df;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAGtE"}
1
+ {"version":3,"file":"resumeWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/resumeWorkspace.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAcnE,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;CAChB;AA6HD,wBAAsB,eAAe,CACnC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA4Df;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAGtE"}
@@ -1,6 +1,6 @@
1
1
  import { fetchResolvedIssue } from "../lib/boardSource.js";
2
2
  import { loadConfig } from "../lib/config.js";
3
- import { ensureAgentSandbox, openAgentWorkspace, prepareAgentLaunch } from "../lib/agentLaunch.js";
3
+ import { openAgentWorkspace, prepareAgentLaunch } from "../lib/agentLaunch.js";
4
4
  import { buildLaunchCommand } from "../lib/launchCommand.js";
5
5
  import { readRunState, recordRunState } from "../lib/runState.js";
6
6
  import { removeStagedPrompt, stageBuildSecrets, stagePromptText, stageWorkspaceLaunchCommand, } from "../lib/stagedLaunch.js";
@@ -117,7 +117,6 @@ export async function resumeWorkspace(config, options) {
117
117
  text: renderResumePrompt(context),
118
118
  });
119
119
  const secretsFile = stageBuildSecrets(stagedPrompt.directory);
120
- await ensureAgentSandbox({ config, definition, sandboxName });
121
120
  const launchCommand = buildLaunchCommand({
122
121
  definition,
123
122
  promptFile: stagedPrompt.file,
@@ -1 +1 @@
1
- {"version":3,"file":"setupWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/setupWorkspace.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAenE,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAWD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAqBD,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,qBAAqB,EAC9B,UAAU,GAAE,wBAA6B,GACxC,OAAO,CAAC,IAAI,CAAC,CA6Gf;AAwHD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAAC,IAAI,CAAC,CAoBf"}
1
+ {"version":3,"file":"setupWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/setupWorkspace.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAenE,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAWD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAqBD,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,qBAAqB,EAC9B,UAAU,GAAE,wBAA6B,GACxC,OAAO,CAAC,IAAI,CAAC,CAsGf;AAwHD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAAC,IAAI,CAAC,CAoBf"}
@@ -1,7 +1,7 @@
1
1
  import { rmSync } from "node:fs";
2
2
  import { fetchResolvedIssue } from "../lib/boardSource.js";
3
3
  import { loadConfig } from "../lib/config.js";
4
- import { ensureAgentSandbox, openAgentWorkspace, prepareAgentLaunch } from "../lib/agentLaunch.js";
4
+ import { openAgentWorkspace, prepareAgentLaunch } from "../lib/agentLaunch.js";
5
5
  import { buildLaunchCommand } from "../lib/launchCommand.js";
6
6
  import { createLinearIssueStatusUpdater } from "../lib/linearIssueStatus.js";
7
7
  import { recordRunState } from "../lib/runState.js";
@@ -80,12 +80,6 @@ export async function setupWorkspace(config, options, runOptions = {}) {
80
80
  const stagedPrompt = stagePrompt({ config, ticket, ticketDetails, worktreeName });
81
81
  promptDir = stagedPrompt.directory;
82
82
  const secretsFile = stageBuildSecrets(promptDir);
83
- await ensureAgentSandbox({
84
- config,
85
- definition,
86
- sandboxName,
87
- ...(signal === undefined ? {} : { signal }),
88
- });
89
83
  const launchCommand = buildLaunchCommand({
90
84
  definition,
91
85
  promptFile: stagedPrompt.file,
@@ -1,22 +1,12 @@
1
1
  import { type InstallKind, type NpmRunResult } from "../lib/npmGlobal.ts";
2
- import { type VersionFetcher } from "../lib/upgrade.ts";
3
2
  export interface UpgradeCliOptions {
4
- currentVersion: string;
5
3
  packageName: string;
6
4
  resolveInstall: () => Promise<UpgradeInstallDetails>;
7
- fetcher: VersionFetcher;
8
5
  runInstall: (options: {
9
6
  packageName: string;
10
7
  version: string;
11
8
  npmBin: string;
12
9
  }) => Promise<NpmRunResult>;
13
- registry?: string | undefined;
14
- fetchTimeoutMs: number;
15
- /** Path of the upgrade-availability cache that the nudge reads. We prime
16
- * it from `--check` and the default install path so the next non-upgrade
17
- * subcommand can render the nudge without paying the network cost. */
18
- cachePath: string;
19
- now: () => number;
20
10
  }
21
11
  export interface UpgradeInstallDetails {
22
12
  installKind: InstallKind;
@@ -26,7 +16,6 @@ export interface UpgradeInstallDetails {
26
16
  export type UpgradeCliOptionsInput = UpgradeCliOptions | (() => Promise<UpgradeCliOptions>);
27
17
  export declare function upgradeCli(argv: string[], optionsInput: UpgradeCliOptionsInput): Promise<void>;
28
18
  export interface CreateUpgradeOptionsArgs {
29
- currentVersion: string;
30
19
  packageName: string;
31
20
  cliMetaUrl: string;
32
21
  }
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,WAAW,EAChB,KAAK,YAAY,EAElB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAK3B,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACrD,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,CAAC,OAAO,EAAE;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB;;0EAEsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAQD,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,GAAG,CAAC,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC;AA0D5F,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EAAE,EACd,YAAY,EAAE,sBAAsB,GACnC,OAAO,CAAC,IAAI,CAAC,CAyCf;AAyFD,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,8BAA8B,CAClD,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,iBAAiB,CAAC,CA2B5B"}
1
+ {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,WAAW,EAChB,KAAK,YAAY,EAElB,MAAM,qBAAqB,CAAC;AAK7B,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACrD,UAAU,EAAE,CAAC,OAAO,EAAE;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAOD,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,GAAG,CAAC,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC;AAiD5F,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EAAE,EACd,YAAY,EAAE,sBAAsB,GACnC,OAAO,CAAC,IAAI,CAAC,CAkBf;AAsCD,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,8BAA8B,CAClD,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,iBAAiB,CAAC,CAqB5B"}
@@ -1,46 +1,36 @@
1
1
  import { runCommand } from "../lib/commandRunner.js";
2
2
  import { which } from "../lib/host.js";
3
3
  import { classifyInstall, createDefaultNpmSpawner, detectInstallPath, detectIsSymlink, detectNpmRootGlobal, runNpmInstallGlobal, } from "../lib/npmGlobal.js";
4
- import { compareVersions, defaultUpgradeCheckCachePath, fetchAndPrimeUpgradeCheckCache, fetchLatestVersion, parseVersion, } from "../lib/upgrade.js";
5
- import { errorMessage, readEnvironmentVariable, writeError, writeOutput } from "../lib/util.js";
6
- const EXPLICIT_FETCH_TIMEOUT_MS = 5000;
4
+ import { writeError, writeOutput } from "../lib/util.js";
5
+ const DEFAULT_UPGRADE_TARGET = "latest";
7
6
  function parseArgs(argv) {
8
- let check = false;
9
- let pinnedVersion;
7
+ let version;
10
8
  for (const arg of argv) {
11
9
  if (arg === "--help" || arg === "-h") {
12
10
  return { kind: "help" };
13
11
  }
14
- if (arg === "--check") {
15
- check = true;
16
- continue;
17
- }
18
12
  if (arg.startsWith("-")) {
19
13
  return { kind: "error", message: `crew upgrade: unknown argument: ${arg}` };
20
14
  }
21
- if (pinnedVersion !== undefined) {
15
+ if (arg.length === 0) {
16
+ return { kind: "error", message: "crew upgrade: version cannot be empty" };
17
+ }
18
+ if (version !== undefined) {
22
19
  return { kind: "error", message: "crew upgrade: too many positional arguments" };
23
20
  }
24
- pinnedVersion = arg;
25
- }
26
- if (check && pinnedVersion !== undefined) {
27
- return { kind: "error", message: "crew upgrade: --check does not accept a version argument" };
28
- }
29
- if (check) {
30
- return { kind: "check" };
21
+ version = arg;
31
22
  }
32
- return { kind: "install", pinnedVersion };
23
+ return { kind: "install", version: version ?? DEFAULT_UPGRADE_TARGET };
33
24
  }
34
25
  function printHelp() {
35
- writeOutput("Usage: crew upgrade [<version>] [--check]");
26
+ writeOutput("Usage: crew upgrade [<version>]");
36
27
  writeOutput("");
37
- writeOutput("Install the latest version of crew.");
28
+ writeOutput("Install crew globally through npm.");
38
29
  writeOutput("");
39
30
  writeOutput("Arguments:");
40
- writeOutput(" <version> Install an exact version (upgrade or downgrade)");
31
+ writeOutput(" <version> Install an exact version or npm tag (default: latest)");
41
32
  writeOutput("");
42
33
  writeOutput("Options:");
43
- writeOutput(" --check Report availability without installing");
44
34
  writeOutput(" -h, --help Show this help");
45
35
  }
46
36
  function refusalMessage(kind, installPath, packageName) {
@@ -64,34 +54,11 @@ export async function upgradeCli(argv, optionsInput) {
64
54
  return;
65
55
  }
66
56
  const options = await resolveOptions(optionsInput);
67
- if (parsed.kind === "check") {
68
- await runCheck(options);
69
- return;
70
- }
71
- let targetVersion;
72
- if (parsed.pinnedVersion === undefined) {
73
- const fetched = await fetchOrFail(options);
74
- if (fetched === undefined) {
75
- return;
76
- }
77
- if (compareVersions(options.currentVersion, fetched) >= 0) {
78
- writeOutput(`crew is up to date (${fetched})`);
79
- return;
80
- }
81
- targetVersion = fetched;
82
- }
83
- else {
84
- const resolved = resolvePinnedVersion(options, parsed.pinnedVersion);
85
- if (resolved === undefined) {
86
- return;
87
- }
88
- targetVersion = resolved;
89
- }
90
57
  const npmBin = await resolveGlobalNpmBin(options);
91
58
  if (npmBin === undefined) {
92
59
  return;
93
60
  }
94
- await runInstallAndReport(options, npmBin, targetVersion);
61
+ await runInstallAndReport(options, npmBin, parsed.version);
95
62
  }
96
63
  async function resolveGlobalNpmBin(options) {
97
64
  const install = await options.resolveInstall();
@@ -107,53 +74,6 @@ async function resolveGlobalNpmBin(options) {
107
74
  }
108
75
  return install.npmBin;
109
76
  }
110
- async function runCheck(options) {
111
- const latest = await fetchOrFail(options);
112
- if (latest === undefined) {
113
- return;
114
- }
115
- if (compareVersions(options.currentVersion, latest) >= 0) {
116
- writeOutput(`crew is up to date (${latest})`);
117
- return;
118
- }
119
- writeOutput(`${latest} available (you are on ${options.currentVersion}); run \`crew upgrade\``);
120
- }
121
- async function fetchOrFail(options) {
122
- try {
123
- return await fetchAndPrimeUpgradeCheckCache({
124
- packageName: options.packageName,
125
- cachePath: options.cachePath,
126
- fetchTimeoutMs: options.fetchTimeoutMs,
127
- registry: options.registry,
128
- now: options.now,
129
- fetcher: options.fetcher,
130
- });
131
- }
132
- catch (error) {
133
- writeError(`crew upgrade: could not reach npm registry: ${errorMessage(error)}`);
134
- process.exitCode = 1;
135
- return undefined;
136
- }
137
- }
138
- function resolvePinnedVersion(options, pinnedVersion) {
139
- try {
140
- parseVersion(pinnedVersion);
141
- }
142
- catch (error) {
143
- writeError(`crew upgrade: ${errorMessage(error)}`);
144
- process.exitCode = 1;
145
- return undefined;
146
- }
147
- if (options.currentVersion === pinnedVersion) {
148
- writeOutput(`crew is already on ${pinnedVersion}`);
149
- return undefined;
150
- }
151
- const cmp = compareVersions(options.currentVersion, pinnedVersion);
152
- if (cmp > 0) {
153
- writeOutput(`downgrading ${options.currentVersion} → ${pinnedVersion}`);
154
- }
155
- return pinnedVersion;
156
- }
157
77
  async function runInstallAndReport(options, npmBin, version) {
158
78
  const result = await options.runInstall({
159
79
  packageName: options.packageName,
@@ -164,13 +84,12 @@ async function runInstallAndReport(options, npmBin, version) {
164
84
  return;
165
85
  }
166
86
  if (result.sawEacces) {
167
- writeError("crew upgrade: install failed with EACCES (permission denied). Your global npm prefix may require elevated permissions see https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally");
87
+ writeError("crew upgrade: install failed with EACCES (permission denied). Your global npm prefix may require elevated permissions - see https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally");
168
88
  }
169
89
  process.exitCode = result.exitCode;
170
90
  }
171
91
  export async function createDefaultUpgradeCliOptions(args) {
172
92
  return {
173
- currentVersion: args.currentVersion,
174
93
  packageName: args.packageName,
175
94
  resolveInstall: async () => {
176
95
  const installPath = detectInstallPath(args.cliMetaUrl);
@@ -183,14 +102,9 @@ export async function createDefaultUpgradeCliOptions(args) {
183
102
  });
184
103
  return { installKind, installPath, npmBin };
185
104
  },
186
- fetcher: fetchLatestVersion,
187
105
  runInstall: async (options) => await runNpmInstallGlobal({
188
106
  ...options,
189
107
  spawner: createDefaultNpmSpawner(process.stderr),
190
108
  }),
191
- fetchTimeoutMs: EXPLICIT_FETCH_TIMEOUT_MS,
192
- registry: readEnvironmentVariable("npm_config_registry"),
193
- cachePath: defaultUpgradeCheckCachePath(),
194
- now: Date.now,
195
109
  };
196
110
  }
@@ -10,12 +10,6 @@ export declare function prepareAgentLaunch(input: {
10
10
  purpose: "runs" | "resumes";
11
11
  signal?: AbortSignal;
12
12
  }): Promise<PreparedAgentLaunch>;
13
- export declare function ensureAgentSandbox(input: {
14
- config: ResolvedConfig;
15
- definition: ModelDefinition;
16
- sandboxName: string | undefined;
17
- signal?: AbortSignal;
18
- }): Promise<void>;
19
13
  export declare function openAgentWorkspace(input: {
20
14
  config: ResolvedConfig;
21
15
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"agentLaunch.d.ts","sourceRoot":"","sources":["../../src/lib/agentLaunch.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAOhF,UAAU,mBAAmB;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE;IAC9C,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,eAAe,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA6B/B;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE;IAC9C,MAAM,EAAE,cAAc,CAAC;IACvB,UAAU,EAAE,eAAe,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhB;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE;IAC9C,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAUhB"}
1
+ {"version":3,"file":"agentLaunch.d.ts","sourceRoot":"","sources":["../../src/lib/agentLaunch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAOhF,UAAU,mBAAmB;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE;IAC9C,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,eAAe,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA6B/B;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE;IAC9C,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAUhB"}
@@ -1,8 +1,7 @@
1
- import { resolve } from "node:path";
2
1
  import { ensureClearance } from "@clipboard-health/clearance";
3
- import { ensureSandbox, sandboxNameFor } from "./dockerSandbox.js";
4
2
  import { detectHostCapabilities } from "./host.js";
5
3
  import { assertLocalRunnerRequirements, resolveLocalRunner } from "./localRunner.js";
4
+ import { sandboxNameFor } from "./sandboxName.js";
6
5
  import { log, sleep } from "./util.js";
7
6
  import { workspaces } from "./workspaces.js";
8
7
  export async function prepareAgentLaunch(input) {
@@ -31,16 +30,6 @@ export async function prepareAgentLaunch(input) {
31
30
  : undefined;
32
31
  return { runner, sandboxName };
33
32
  }
34
- export async function ensureAgentSandbox(input) {
35
- if (input.sandboxName !== undefined && input.definition.sandbox !== undefined) {
36
- await ensureSandbox({
37
- sandboxName: input.sandboxName,
38
- sandbox: input.definition.sandbox,
39
- mountPath: resolve(input.config.workspace.projectDir),
40
- gitDefaults: input.config.sandbox.gitDefaults,
41
- }, input.signal);
42
- }
43
- }
44
33
  export async function openAgentWorkspace(input) {
45
34
  const spec = {
46
35
  name: input.name,
@@ -0,0 +1,8 @@
1
+ /**
2
+ * cmux Workspace backend. cmux is the macOS TUI; workspaces surface in its
3
+ * own app, so `accessHint` has nothing concise to emit. cmux can paint a
4
+ * per-workspace status pill, which `open` applies best-effort.
5
+ */
6
+ import { type Adapter } from "./workspaceAdapter.ts";
7
+ export declare const cmuxAdapter: Adapter;
8
+ //# sourceMappingURL=cmuxAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cmuxAdapter.d.ts","sourceRoot":"","sources":["../../src/lib/cmuxAdapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,KAAK,OAAO,EAIb,MAAM,uBAAuB,CAAC;AAG/B,eAAO,MAAM,WAAW,EAAE,OA6EzB,CAAC"}