@clipboard-health/groundcrew 3.0.3 → 3.1.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/README.md CHANGED
@@ -171,34 +171,53 @@ Three keys are required; everything else has a default.
171
171
 
172
172
  Agent selection uses Linear labels: `agent-claude`, `agent-codex`, `agent-<name>`. `crew run` without `--ticket` only fetches tickets carrying an `agent-*` label — the GraphQL query filters server-side, so unlabeled tickets are never returned by Linear and do not appear on the board. Use `crew run --ticket <TICKET>` to provision an unlabeled ticket on demand (falls back to `models.default`). `agent-any` routes to the model with the most available session capacity. Todo tickets blocked by non-terminal blockers are skipped until their blockers reach a terminal status.
173
173
 
174
+ ### Prompt customization
175
+
176
+ Groundcrew ships one model-agnostic unattended prompt by default. It tells the agent to make reasonable assumptions, follow repository instructions, run documented verification, review its diff, open a PR when GitHub/`gh` is available, and include a workspace continuation hint when known.
177
+
178
+ For a personal workflow, keep the prompt next to your local config and load it with `readFileSync`:
179
+
180
+ ```ts
181
+ import { readFileSync } from "node:fs";
182
+
183
+ export const config = {
184
+ // ...
185
+ prompts: {
186
+ initial: readFileSync(new URL("./initial-prompt.md", import.meta.url), "utf8"),
187
+ },
188
+ };
189
+ ```
190
+
191
+ This keeps package defaults portable while letting your private config reference team-specific statuses, tools, plugins, or review loops.
192
+
174
193
  <details>
175
194
  <summary>Full reference table</summary>
176
195
 
177
- | Key | Default | What it does |
178
- | --------------------------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
179
- | `linear.projectSlug` | **required** | Linear project URL slug (e.g. `ai-strategy-5152195762f3`). The trailing 12-char hex `slugId` is what's matched against Linear's API; the leading name keeps `config.ts` self-documenting and the lookup survives project renames. |
180
- | `linear.statuses.todo` | `"Todo"` | Status name picked up for new work. |
181
- | `linear.statuses.inProgress` | `"In Progress"` | Status set after a workspace is provisioned; counts toward `maximumInProgress`. |
182
- | `linear.statuses.done` | `"Done"` | Status that triggers worktree cleanup. |
183
- | `linear.statuses.terminal` | `["Done"]` | Additional status names treated as terminal for cleanup, board remaining counts, and blocker checks. The `done` status is always included. |
184
- | `git.remote` | `"origin"` | Remote used for `fetch` and as the worktree base ref. |
185
- | `git.defaultBranch` | `"main"` | Branch fetched from `git.remote` and used as the worktree base. |
186
- | `workspace.projectDir` | **required** | Parent dir for cloned repos and sibling ticket worktrees. |
187
- | `workspace.knownRepositories` | **required** | Repos searched for in ticket descriptions to infer where work belongs. A ticket labeled for groundcrew (`agent-*`) fails fast when no known repo appears; unlabeled tickets are ignored. |
188
- | `orchestrator.maximumInProgress` | `4` | Cap on tickets in `linear.statuses.inProgress` at once. |
189
- | `orchestrator.pollIntervalMilliseconds` | `120_000` | Poll interval in `--watch` mode. |
190
- | `orchestrator.sessionLimitPercentage` | `85` | Number in `(0, 100]`. A model whose codexbar session window exceeds this percentage is skipped that tick. |
191
- | `models.default` | `"claude"` | Tiebreak for `agent-any` resolution and fallback for explicit but unknown `agent-*` labels. Also used by `crew run --ticket <TICKET>` for unlabeled tickets. `crew run` without `--ticket` ignores unlabeled tickets and does not apply this default. Must exist in `models.definitions`. |
192
- | `models.definitions` | `{ claude, codex }` | Agent definitions. Additive merge with shipped defaults. |
193
- | `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. |
194
- | `models.definitions.<name>.color` | — | Color for the workspace status pill (cmux only; tmux silently drops it). |
195
- | `models.definitions.<name>.usage` | optional | If set, codexbar usage is fetched for this model and gated by `sessionLimitPercentage`. Omit to never gate. When `usage.codexbar.source` is omitted, groundcrew uses `oauth` for Codex/Claude on macOS, `auto` for other macOS providers, and `cli` elsewhere. |
196
- | `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). |
197
- | `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. |
198
- | `prompts.initial` | (template) | First message sent to the agent. Placeholders: `{{ticket}}`, `{{worktree}}`, `{{title}}`, `{{description}}`. |
199
- | `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. |
200
- | `local.runner` | `"auto"` | Local isolation backend. `"auto"` → `safehouse` on macOS, `sdx` on Linux/WSL. Explicit: `"safehouse"`, `"sdx"`, `"none"`. `"none"` is never picked implicitly. |
201
- | `logging.file` | XDG state path | Append-mode log file. `log()` / `logEvent()` tee here in addition to stdout. Defaults to `${XDG_STATE_HOME:-$HOME/.local/state}/groundcrew/groundcrew.log`. |
196
+ | Key | Default | What it does |
197
+ | --------------------------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
198
+ | `linear.projectSlug` | **required** | Linear project URL slug (e.g. `ai-strategy-5152195762f3`). The trailing 12-char hex `slugId` is what's matched against Linear's API; the leading name keeps `config.ts` self-documenting and the lookup survives project renames. |
199
+ | `linear.statuses.todo` | `"Todo"` | Status name picked up for new work. |
200
+ | `linear.statuses.inProgress` | `"In Progress"` | Status set after a workspace is provisioned; counts toward `maximumInProgress`. |
201
+ | `linear.statuses.done` | `"Done"` | Status that triggers worktree cleanup. |
202
+ | `linear.statuses.terminal` | `["Done"]` | Additional status names treated as terminal for cleanup, board remaining counts, and blocker checks. The `done` status is always included. |
203
+ | `git.remote` | `"origin"` | Remote used for `fetch` and as the worktree base ref. |
204
+ | `git.defaultBranch` | `"main"` | Branch fetched from `git.remote` and used as the worktree base. |
205
+ | `workspace.projectDir` | **required** | Parent dir for cloned repos and sibling ticket worktrees. |
206
+ | `workspace.knownRepositories` | **required** | Repos searched for in ticket descriptions to infer where work belongs. A ticket labeled for groundcrew (`agent-*`) fails fast when no known repo appears; unlabeled tickets are ignored. |
207
+ | `orchestrator.maximumInProgress` | `4` | Cap on tickets in `linear.statuses.inProgress` at once. |
208
+ | `orchestrator.pollIntervalMilliseconds` | `120_000` | Poll interval in `--watch` mode. |
209
+ | `orchestrator.sessionLimitPercentage` | `85` | Number in `(0, 100]`. A model whose codexbar session window exceeds this percentage is skipped that tick. |
210
+ | `models.default` | `"claude"` | Tiebreak for `agent-any` resolution and fallback for explicit but unknown `agent-*` labels. Also used by `crew run --ticket <TICKET>` for unlabeled tickets. `crew run` without `--ticket` ignores unlabeled tickets and does not apply this default. Must exist in `models.definitions`. |
211
+ | `models.definitions` | `{ claude, codex }` | Agent definitions. Additive merge with shipped defaults. |
212
+ | `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. |
213
+ | `models.definitions.<name>.color` | — | Color for the workspace status pill (cmux only; tmux silently drops it). |
214
+ | `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. |
215
+ | `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). |
216
+ | `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. |
217
+ | `prompts.initial` | unattended template | First message sent to the agent. Placeholders: `{{ticket}}`, `{{worktree}}`, `{{title}}`, `{{description}}`. Override this from `config.ts` for team-specific statuses, tools, plugins, or review loops. |
218
+ | `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. |
219
+ | `local.runner` | `"auto"` | Local isolation backend. `"auto"` → `safehouse` on macOS, `sdx` on Linux/WSL. Explicit: `"safehouse"`, `"sdx"`, `"none"`. `"none"` is never picked implicitly. |
220
+ | `logging.file` | XDG state path | Append-mode log file. `log()` / `logEvent()` tee here in addition to stdout. Defaults to `${XDG_STATE_HOME:-$HOME/.local/state}/groundcrew/groundcrew.log`. |
202
221
 
203
222
  </details>
204
223
 
@@ -33,6 +33,7 @@ datadoghq.com
33
33
  # GitHub + GHA artifact storage (Azure blobs)
34
34
  api.github.com
35
35
  cafe.github.com
36
+ codeload.github.com
36
37
  github.com
37
38
  productionresultssa0.blob.core.windows.net
38
39
  productionresultssa1.blob.core.windows.net
@@ -58,9 +59,10 @@ raw.githubusercontent.com
58
59
  release-assets.githubusercontent.com
59
60
  results-receiver.actions.githubusercontent.com
60
61
 
61
- # npm registry
62
+ # npm registry + package website
62
63
  api.npmjs.org
63
64
  registry.npmjs.org
65
+ www.npmjs.com
64
66
 
65
67
  # Developer tooling
66
68
  buf.build
package/configExample.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { Config } from "./src/lib/config.js";
2
+ // import { readFileSync } from "node:fs";
2
3
 
3
4
  export const config: Config = {
4
5
  linear: {
@@ -57,13 +58,10 @@ export const config: Config = {
57
58
  // local: { runner: "auto" },
58
59
  //
59
60
  // prompts: {
60
- // initial: [
61
- // "Begin work on {{ticket}} ({{title}}) in the {{worktree}} wt subdirectory.",
62
- // "",
63
- // "Ticket description:",
64
- // "",
65
- // "{{description}}",
66
- // ].join("\n"),
61
+ // // Keep personal workflow instructions next to this config, for example
62
+ // // `${XDG_CONFIG_HOME:-$HOME/.config}/groundcrew/initial-prompt.md`.
63
+ // // If you uncomment this, also uncomment the readFileSync import above.
64
+ // initial: readFileSync(new URL("./initial-prompt.md", import.meta.url), "utf8"),
67
65
  // },
68
66
  //
69
67
  // // Terminal session manager. "auto" picks cmux when on PATH, else tmux.
@@ -78,8 +78,16 @@ export interface ModelDefinition {
78
78
  * mirrors the runtime contract: an entry is either a pure overlay
79
79
  * (every concrete field optional, no `disabled` key) or a pure
80
80
  * disable directive (`{ disabled: true }` and nothing else).
81
+ *
82
+ * `usage` accepts an extra `{ disabled: true }` sentinel that strips the
83
+ * usage block from the merged definition — the only way to opt a shipped
84
+ * default out of codexbar gating without disabling the model entirely.
81
85
  */
82
- type EnabledUserModelDefinition = Partial<ModelDefinition> & {
86
+ type UserUsage = ModelDefinition["usage"] | {
87
+ disabled: true;
88
+ };
89
+ type EnabledUserModelDefinition = Partial<Omit<ModelDefinition, "usage">> & {
90
+ usage?: UserUsage;
83
91
  disabled?: never;
84
92
  };
85
93
  interface DisabledUserModelDefinition {
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
@@ -51,11 +51,26 @@ const DEFAULT_MODEL_DEFINITIONS = {
51
51
  },
52
52
  };
53
53
  const DEFAULT_PROMPT_INITIAL = [
54
- "Begin work on {{ticket}} ({{title}}) in the {{worktree}} wt subdirectory.",
54
+ "You are working on Linear ticket {{ticket}} ({{title}}) in the {{worktree}} worktree subdirectory.",
55
55
  "",
56
56
  "Ticket description:",
57
57
  "",
58
58
  "{{description}}",
59
+ "",
60
+ "## Operating mode",
61
+ "",
62
+ "There is no human watching this session. Do not stop to ask clarifying questions. When the ticket is ambiguous or incomplete, choose the simplest reasonable interpretation consistent with the ticket and the codebase, then document that choice in the PR description.",
63
+ "",
64
+ "## Workflow",
65
+ "",
66
+ "1. Inspect the repository instructions and existing patterns before editing.",
67
+ "2. Implement the smallest sensible change that completes the ticket.",
68
+ "3. Run the repository's documented verification command. If no documented verification exists, run the smallest relevant test suite you can find. Fix failures you introduced before continuing.",
69
+ "4. Review your own diff before stopping. Look for bugs, regressions, missing tests, security issues, and convention violations, then fix any issues you find.",
70
+ "5. If this repository uses GitHub and the `gh` CLI is available and authenticated, open a pull request. If you cannot open one, leave the branch ready and record the blocker.",
71
+ "6. Include a short continuation note in the PR body when you know how to reattach to this workspace. For the tmux backend, use `tmux attach -t groundcrew:{{ticket}}`.",
72
+ "",
73
+ "Stop after the branch is ready or the PR is open.",
59
74
  ].join("\n");
60
75
  const ALLOWED_PROMPT_PLACEHOLDERS = new Set([
61
76
  "{{ticket}}",
@@ -259,6 +274,9 @@ export function isShippedDefaultDisabled(config, name) {
259
274
  return (Object.hasOwn(DEFAULT_MODEL_DEFINITIONS, name) &&
260
275
  !Object.hasOwn(config.models.definitions, name));
261
276
  }
277
+ function isUsageDisableSentinel(usage) {
278
+ return isPlainObject(usage) && "disabled" in usage && usage.disabled;
279
+ }
262
280
  function mergeDefinitions(user) {
263
281
  if (user !== undefined && !isPlainObject(user)) {
264
282
  fail("models.definitions must be an object");
@@ -291,7 +309,12 @@ function mergeDefinitions(user) {
291
309
  candidate.color = override.color;
292
310
  }
293
311
  if (override.usage !== undefined) {
294
- candidate.usage = override.usage;
312
+ if (isUsageDisableSentinel(override.usage)) {
313
+ delete candidate.usage;
314
+ }
315
+ else {
316
+ candidate.usage = override.usage;
317
+ }
295
318
  }
296
319
  if (override.sandbox !== undefined) {
297
320
  candidate.sandbox = normalizeSandbox(override.sandbox, `models.definitions.${name}.sandbox`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clipboard-health/groundcrew",
3
- "version": "3.0.3",
3
+ "version": "3.1.1",
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",