@clipboard-health/groundcrew 4.18.1 → 4.19.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 (128) hide show
  1. package/README.md +22 -22
  2. package/crew.config.example.ts +5 -5
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +39 -33
  5. package/dist/commands/cleaner.d.ts +4 -4
  6. package/dist/commands/cleaner.d.ts.map +1 -1
  7. package/dist/commands/cleaner.js +7 -7
  8. package/dist/commands/cleanupWorkspace.d.ts +1 -1
  9. package/dist/commands/cleanupWorkspace.d.ts.map +1 -1
  10. package/dist/commands/cleanupWorkspace.js +14 -14
  11. package/dist/commands/dispatcher.d.ts +4 -4
  12. package/dist/commands/dispatcher.d.ts.map +1 -1
  13. package/dist/commands/dispatcher.js +32 -32
  14. package/dist/commands/doctor.js +1 -1
  15. package/dist/commands/eligibility.d.ts +2 -2
  16. package/dist/commands/eligibility.d.ts.map +1 -1
  17. package/dist/commands/eligibility.js +4 -4
  18. package/dist/commands/init.js +1 -1
  19. package/dist/commands/interruptWorkspace.d.ts +1 -1
  20. package/dist/commands/interruptWorkspace.d.ts.map +1 -1
  21. package/dist/commands/interruptWorkspace.js +18 -18
  22. package/dist/commands/orchestrator.d.ts +1 -1
  23. package/dist/commands/orchestrator.js +2 -2
  24. package/dist/commands/resumeWorkspace.d.ts +1 -1
  25. package/dist/commands/resumeWorkspace.d.ts.map +1 -1
  26. package/dist/commands/resumeWorkspace.js +35 -35
  27. package/dist/commands/reviewer.d.ts +20 -17
  28. package/dist/commands/reviewer.d.ts.map +1 -1
  29. package/dist/commands/reviewer.js +85 -51
  30. package/dist/commands/setupWorkspace.d.ts +5 -5
  31. package/dist/commands/setupWorkspace.d.ts.map +1 -1
  32. package/dist/commands/setupWorkspace.js +39 -39
  33. package/dist/commands/source.d.ts +2 -0
  34. package/dist/commands/source.d.ts.map +1 -0
  35. package/dist/commands/source.js +126 -0
  36. package/dist/commands/status.d.ts +1 -1
  37. package/dist/commands/status.d.ts.map +1 -1
  38. package/dist/commands/status.js +103 -103
  39. package/dist/commands/teardownReporter.js +10 -10
  40. package/dist/index.d.ts +2 -2
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +2 -2
  43. package/dist/lib/adapterDefinition.d.ts +3 -3
  44. package/dist/lib/adapterDefinition.d.ts.map +1 -1
  45. package/dist/lib/adapters/linear/factory.d.ts +3 -3
  46. package/dist/lib/adapters/linear/factory.d.ts.map +1 -1
  47. package/dist/lib/adapters/linear/factory.js +6 -6
  48. package/dist/lib/adapters/linear/fetch.d.ts +18 -18
  49. package/dist/lib/adapters/linear/fetch.d.ts.map +1 -1
  50. package/dist/lib/adapters/linear/fetch.js +20 -20
  51. package/dist/lib/adapters/linear/index.js +2 -2
  52. package/dist/lib/adapters/linear/parsing.d.ts +1 -1
  53. package/dist/lib/adapters/linear/parsing.d.ts.map +1 -1
  54. package/dist/lib/adapters/linear/parsing.js +4 -4
  55. package/dist/lib/adapters/linear/statusNames.d.ts +1 -1
  56. package/dist/lib/adapters/linear/statusNames.d.ts.map +1 -1
  57. package/dist/lib/adapters/linear/writeback.d.ts +3 -3
  58. package/dist/lib/adapters/linear/writeback.d.ts.map +1 -1
  59. package/dist/lib/adapters/linear/writeback.js +1 -1
  60. package/dist/lib/adapters/shell/factory.d.ts +5 -4
  61. package/dist/lib/adapters/shell/factory.d.ts.map +1 -1
  62. package/dist/lib/adapters/shell/factory.js +53 -14
  63. package/dist/lib/adapters/shell/index.js +2 -2
  64. package/dist/lib/adapters/shell/invoke.d.ts +2 -2
  65. package/dist/lib/adapters/shell/invoke.js +3 -3
  66. package/dist/lib/adapters/shell/schema.d.ts +7 -1
  67. package/dist/lib/adapters/shell/schema.d.ts.map +1 -1
  68. package/dist/lib/adapters/shell/schema.js +26 -3
  69. package/dist/lib/agentLaunch.js +1 -1
  70. package/dist/lib/board.d.ts +16 -10
  71. package/dist/lib/board.d.ts.map +1 -1
  72. package/dist/lib/board.js +15 -5
  73. package/dist/lib/buildSources.d.ts +8 -4
  74. package/dist/lib/buildSources.d.ts.map +1 -1
  75. package/dist/lib/buildSources.js +2 -2
  76. package/dist/lib/config.d.ts +6 -6
  77. package/dist/lib/config.js +8 -8
  78. package/dist/lib/launchCommand.js +1 -1
  79. package/dist/lib/pullRequests.d.ts +2 -0
  80. package/dist/lib/pullRequests.d.ts.map +1 -1
  81. package/dist/lib/pullRequests.js +21 -15
  82. package/dist/lib/repositoryValidation.d.ts +2 -2
  83. package/dist/lib/repositoryValidation.d.ts.map +1 -1
  84. package/dist/lib/repositoryValidation.js +1 -1
  85. package/dist/lib/runState.d.ts +11 -11
  86. package/dist/lib/runState.d.ts.map +1 -1
  87. package/dist/lib/runState.js +19 -19
  88. package/dist/lib/runStateCleanup.js +2 -2
  89. package/dist/lib/sourceCapabilities.d.ts +17 -0
  90. package/dist/lib/sourceCapabilities.d.ts.map +1 -0
  91. package/dist/lib/sourceCapabilities.js +51 -0
  92. package/dist/lib/srtLaunch.d.ts +1 -1
  93. package/dist/lib/srtLaunch.d.ts.map +1 -1
  94. package/dist/lib/srtLaunch.js +1 -1
  95. package/dist/lib/srtPolicy.js +1 -1
  96. package/dist/lib/stagedLaunch.d.ts +3 -3
  97. package/dist/lib/stagedLaunch.d.ts.map +1 -1
  98. package/dist/lib/stagedLaunch.js +3 -3
  99. package/dist/lib/{ticketSource.d.ts → taskSource.d.ts} +44 -28
  100. package/dist/lib/taskSource.d.ts.map +1 -0
  101. package/dist/lib/{ticketSource.js → taskSource.js} +9 -9
  102. package/dist/lib/testing/canonicalFixtures.d.ts +1 -1
  103. package/dist/lib/testing/canonicalFixtures.d.ts.map +1 -1
  104. package/dist/lib/testing/canonicalFixtures.js +1 -1
  105. package/dist/lib/tmuxAdapter.d.ts +1 -1
  106. package/dist/lib/tmuxAdapter.js +2 -2
  107. package/dist/lib/util.d.ts +3 -3
  108. package/dist/lib/util.d.ts.map +1 -1
  109. package/dist/lib/util.js +4 -4
  110. package/dist/lib/workspaceAdapter.d.ts +8 -8
  111. package/dist/lib/workspaceAdapter.d.ts.map +1 -1
  112. package/dist/lib/workspaceAdapter.js +2 -2
  113. package/dist/lib/workspaces.d.ts +1 -1
  114. package/dist/lib/workspaces.js +1 -1
  115. package/dist/lib/worktrees.d.ts +11 -11
  116. package/dist/lib/worktrees.d.ts.map +1 -1
  117. package/dist/lib/worktrees.js +47 -47
  118. package/docs/adr/{0002-one-ticket-source-path-linear-is-an-adapter.md → 0002-one-task-source-path-linear-is-an-adapter.md} +3 -3
  119. package/docs/commands.md +10 -10
  120. package/docs/configuration.md +19 -19
  121. package/docs/credentials.md +2 -2
  122. package/docs/runners.md +1 -1
  123. package/docs/setup-hook-agent-prompt.md +2 -2
  124. package/docs/setup-hooks.md +1 -1
  125. package/docs/{ticket-sources.md → task-sources.md} +16 -12
  126. package/docs/troubleshooting.md +5 -5
  127. package/package.json +13 -13
  128. package/dist/lib/ticketSource.d.ts.map +0 -1
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  </p>
7
7
 
8
8
  <p align="center">
9
- Dispatch your ticket backlog to local, interactive AI coding agents. One git worktree per ticket, sandboxed by default.
9
+ Dispatch your task backlog to local, interactive AI coding agents. One git worktree per task, sandboxed by default.
10
10
  </p>
11
11
 
12
12
  <p align="center">
@@ -17,18 +17,18 @@
17
17
  </p>
18
18
 
19
19
  <p align="center">
20
- <a href="./static/demo.tape"><img alt="Groundcrew dispatching tickets into tmux panes with coding agents running in parallel" src="./static/demo.gif" width="800"></a>
20
+ <a href="./static/demo.tape"><img alt="Groundcrew dispatching tasks into tmux panes with coding agents running in parallel" src="./static/demo.gif" width="800"></a>
21
21
  </p>
22
22
 
23
- Groundcrew watches assigned tickets, creates isolated worktrees, launches agent CLIs in dedicated terminals, and leaves each ticket's work on its own PR-ready branch. For the backstory, read _[Tickets to pull requests while you sleep](https://www.clipboardworks.com/resources/blog/tickets-to-pull-requests-while-you-sleep)_.
23
+ Groundcrew watches assigned tasks, creates isolated worktrees, launches agent CLIs in dedicated terminals, and leaves each task's work on its own PR-ready branch. For the backstory, read _[Tasks to pull requests while you sleep](https://www.clipboardworks.com/resources/blog/tasks-to-pull-requests-while-you-sleep)_.
24
24
 
25
25
  ## Why
26
26
 
27
27
  - **Local.** Agents run on your machine with your tools, shell, and credentials. That makes them more steerable than remote agents, and easy to nudge when they drift.
28
- - **Interactive.** Each ticket launches the real `claude` or `codex` CLI in its own terminal pane, not a wrapper that approximates it. Watch any session live and take over when you need to.
29
- - **One worktree per ticket.** Agents work in parallel without stepping on each other.
28
+ - **Interactive.** Each task launches the real `claude` or `codex` CLI in its own terminal pane, not a wrapper that approximates it. Watch any session live and take over when you need to.
29
+ - **One worktree per task.** Agents work in parallel without stepping on each other.
30
30
  - **Sandboxed by default.** Safehouse or Docker Sandboxes isolate each agent on the host; `none` is an explicit escape hatch.
31
- - **Pluggable ticket sources.** Linear by default; Jira and local files via [ticket sources](./docs/ticket-sources.md).
31
+ - **Pluggable task sources.** Linear by default; Jira and local files via [task sources](./docs/task-sources.md).
32
32
  - **Multi-agent routing.** Ships `claude` and `codex` presets; bring your own CLI in config.
33
33
 
34
34
  ## Prerequisites
@@ -56,7 +56,7 @@ crew init --global --project-dir ~/dev --repo OWNER/REPO --model claude
56
56
  # 4. Set the clearance egress proxy allowlist.
57
57
  export CLEARANCE_ALLOW_HOSTS_FILES="$(npm root -g)/@clipboard-health/groundcrew/clearance-allow-hosts"
58
58
 
59
- # 5. Using Linear? Export your API key. (Jira and other trackers: see Ticket Pickup.)
59
+ # 5. Using Linear? Export your API key. (Jira and other trackers: see Task Pickup.)
60
60
  export GROUNDCREW_LINEAR_API_KEY="lin_api_..."
61
61
 
62
62
  # 6. Verify setup, then dispatch.
@@ -66,25 +66,25 @@ crew run --watch
66
66
 
67
67
  `crew init --global` writes config to `${XDG_CONFIG_HOME:-$HOME/.config}/groundcrew/`. Pass `--repo` more than once for multiple repos. `--model claude` or `--model codex` chooses the single built-in model preset to enable in the generated config.
68
68
 
69
- ## Ticket Pickup
69
+ ## Task Pickup
70
70
 
71
- **Not on Linear?** Use Jira or local files via [ticket sources](./docs/ticket-sources.md).
71
+ **Not on Linear?** Use Jira or local files via [task sources](./docs/task-sources.md).
72
72
 
73
- Linear works out of the box: assign tickets to yourself and add an `agent-*` label.
73
+ Linear works out of the box: assign tasks to yourself and add an `agent-*` label.
74
74
 
75
75
  - `agent-claude`, `agent-codex`, or `agent-<name>` routes to that model.
76
76
  - `agent-any` routes to the enabled model with the most session headroom, after skipping models over their session limit or weekly paced budget.
77
- - Tickets without an `agent-*` label are ignored by `crew run`; dispatch one manually with `crew start <TICKET>`.
77
+ - Tasks without an `agent-*` label are ignored by `crew run`; dispatch one manually with `crew start <TASK>`.
78
78
 
79
- Groundcrew scans `workspace.knownRepositories` to infer which repo a ticket belongs to.
79
+ Groundcrew scans `workspace.knownRepositories` to infer which repo a task belongs to.
80
80
 
81
- A ticket blocked by non-terminal blockers is skipped until those blockers are done.
81
+ A task blocked by non-terminal blockers is skipped until those blockers are done.
82
82
 
83
- ### The ticket description is the prompt
83
+ ### The task description is the prompt
84
84
 
85
- Groundcrew sends each agent a generic unattended-execution prompt plus the ticket title and description. The prompt says how to work: read the repo instructions, make the smallest sensible change, verify it, and produce the requested output. The ticket description says what to do.
85
+ Groundcrew sends each agent a generic unattended-execution prompt plus the task title and description. The prompt says how to work: read the repo instructions, make the smallest sensible change, verify it, and produce the requested output. The task description says what to do.
86
86
 
87
- Write tickets as complete agent instructions: the goal, the context and constraints, links to logs or screenshots, how to verify, and the output you want. A vague ticket gets a vague PR.
87
+ Write tasks as complete agent instructions: the goal, the context and constraints, links to logs or screenshots, how to verify, and the output you want. A vague task gets a vague PR.
88
88
 
89
89
  ## Commands
90
90
 
@@ -93,12 +93,12 @@ crew init [--global | --local] [--force] [--dry-run] # create a crew.config.
93
93
  [--project-dir <dir>] [--repo <repo>]...
94
94
  [--runner <auto|safehouse|sdx|none>] [--model <claude|codex>]
95
95
  crew doctor # check setup
96
- crew status [<TICKET>] # inspect current state or one ticket
96
+ crew status [<TASK>] # inspect current state or one task
97
97
  crew run [--watch] # one-shot or --watch forever
98
- crew start <TICKET> # provision + launch one ticket now
99
- crew stop <TICKET> [--reason <text>] # stop workspace, keep worktree
100
- crew resume <TICKET> # reopen a paused ticket
101
- crew cleanup <TICKET> # tear down every worktree for a ticket
98
+ crew start <TASK> # provision + launch one task now
99
+ crew stop <TASK> [--reason <text>] # stop workspace, keep worktree
100
+ crew resume <TASK> # reopen a paused task
101
+ crew cleanup <TASK> # tear down every worktree for a task
102
102
  crew upgrade [<version>] # reinstall crew globally through npm
103
103
  ```
104
104
 
@@ -147,7 +147,7 @@ There is no `linear` config block. Groundcrew reads `GROUNDCREW_LINEAR_API_KEY`
147
147
  - [Runners](./docs/runners.md): Safehouse, Docker Sandboxes, and the `none` escape hatch.
148
148
  - [Credentials](./docs/credentials.md): Linear API keys, 1Password, build secrets, and `preLaunch`.
149
149
  - [Prepare worktree hooks](./docs/setup-hooks.md): `.groundcrew/config.json` `hooks.prepareWorktree` for per-repo dependency setup.
150
- - [Ticket sources](./docs/ticket-sources.md): custom shell/Jira/local-plan adapters.
150
+ - [Task sources](./docs/task-sources.md): custom shell/Jira/local-plan adapters.
151
151
  - [Troubleshooting](./docs/troubleshooting.md): common operational pitfalls and fixes.
152
152
 
153
153
  ## Development
@@ -10,18 +10,18 @@ export default {
10
10
  // `state.type` (`unstarted` → todo, `started` → in progress,
11
11
  // `completed`/`canceled`/`duplicate` → terminal).
12
12
  //
13
- // Opt a ticket in: assign it to yourself and add an `agent-<model>`
13
+ // Opt a task in: assign it to yourself and add an `agent-<model>`
14
14
  // label (e.g. `agent-claude`, `agent-any`).
15
15
  workspace: {
16
16
  // Parent directory under which groundcrew clones repositories and (by
17
- // default) creates per-ticket worktrees.
17
+ // default) creates per-task worktrees.
18
18
  projectDir: "~/dev/groundcrew",
19
19
  // Optional: collect ALL worktrees here instead of beside each repo. Useful
20
20
  // when your repos live in more than one place. Defaults to projectDir.
21
21
  // worktreeDir: "~/dev/worktrees",
22
22
  // Repositories groundcrew is allowed to set up worktrees in. Add
23
23
  // `<owner>/<repo>` or bare `<repo>` strings; the orchestrator scopes
24
- // tickets to these and refuses unknown repos by default. Use the object
24
+ // tasks to these and refuses unknown repos by default. Use the object
25
25
  // form to point a repo at a different parent directory:
26
26
  // { name: "other-org/other-repo", projectDirOverride: "~/work" }
27
27
  knownRepositories: ["your-org/your-repo"],
@@ -30,7 +30,7 @@ export default {
30
30
  default: "claude",
31
31
  // `definitions` is the enabled model set. Built-in keys can use `{}` to
32
32
  // opt into the shipped command/color/usage preset. Add `codex: {}` if you
33
- // want both shipped agents, or add a custom entry and tag tickets with
33
+ // want both shipped agents, or add a custom entry and tag tasks with
34
34
  // `agent-<name>`.
35
35
  definitions: {
36
36
  claude: {},
@@ -53,7 +53,7 @@ export default {
53
53
  // Everything below is optional — defaults shown for reference. Uncomment
54
54
  // and edit to override.
55
55
  //
56
- // // Additional pluggable ticket sources beyond the implicit built-in
56
+ // // Additional pluggable task sources beyond the implicit built-in
57
57
  // // Linear adapter. The most common use is `kind: "shell"`, which wires
58
58
  // // any external system via command templates that emit/consume JSON.
59
59
  // // See the shell adapter's ShellIssue schema for the JSON contract
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAyQA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCvD"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AA+QA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCvD"}
package/dist/cli.js CHANGED
@@ -6,9 +6,10 @@ import { interruptWorkspaceCli } from "./commands/interruptWorkspace.js";
6
6
  import { orchestrate } from "./commands/orchestrator.js";
7
7
  import { resumeWorkspaceCli } from "./commands/resumeWorkspace.js";
8
8
  import { setupWorkspaceCli } from "./commands/setupWorkspace.js";
9
+ import { sourceCli } from "./commands/source.js";
9
10
  import { statusCli } from "./commands/status.js";
10
11
  import { createDefaultUpgradeCliOptions, upgradeCli } from "./commands/upgrade.js";
11
- import { errorMessage, parseDryRunPositionals, readEnvironmentVariable, readTicketArgument, setVerbose, writeError, writeOutput, } from "./lib/util.js";
12
+ import { errorMessage, parseDryRunPositionals, readEnvironmentVariable, readTaskArgument, setVerbose, writeError, writeOutput, } from "./lib/util.js";
12
13
  const REMOVED_SANDBOX_COMMAND_MESSAGE = [
13
14
  "`crew sandbox` is no longer supported.",
14
15
  "Groundcrew now launches agents inside existing sbx sandboxes but does not list, create, regenerate, authenticate, or remove them.",
@@ -40,7 +41,7 @@ async function setupCli(argv) {
40
41
  async function runCli(argv) {
41
42
  let watch = false;
42
43
  let dryRun = false;
43
- let ticket;
44
+ let task;
44
45
  for (let index = 0; index < argv.length; index += 1) {
45
46
  const argument = argv[index];
46
47
  if (argument === "--watch") {
@@ -51,31 +52,31 @@ async function runCli(argv) {
51
52
  dryRun = true;
52
53
  continue;
53
54
  }
54
- if (argument === "--ticket") {
55
- ticket = readTicketArgument(argv, index, "run");
55
+ if (argument === "--task") {
56
+ task = readTaskArgument(argv, index, "run");
56
57
  index += 1;
57
58
  continue;
58
59
  }
59
60
  throw new Error(`crew run: unknown argument: ${argument}`);
60
61
  }
61
- if (ticket !== undefined && watch) {
62
- throw new Error("crew run: --watch and --ticket are mutually exclusive");
62
+ if (task !== undefined && watch) {
63
+ throw new Error("crew run: --watch and --task are mutually exclusive");
63
64
  }
64
- if (ticket === undefined) {
65
+ if (task === undefined) {
65
66
  await orchestrate({ watch, dryRun });
66
67
  return;
67
68
  }
68
- warnDeprecated({ oldForm: "run --ticket", newForm: "start" });
69
- await setupWorkspaceCli(ticket, { dryRun });
69
+ warnDeprecated({ oldForm: "run --task", newForm: "start" });
70
+ await setupWorkspaceCli(task, { dryRun });
70
71
  }
71
- const START_USAGE = "crew start <ticket> [--dry-run]";
72
+ const START_USAGE = "crew start <task> [--dry-run]";
72
73
  async function startCli(argv) {
73
74
  const { dryRun, positionals } = parseDryRunPositionals(argv, START_USAGE);
74
- const [ticket, ...extras] = positionals;
75
- if (ticket === undefined || ticket.length === 0 || extras.length > 0) {
75
+ const [task, ...extras] = positionals;
76
+ if (task === undefined || task.length === 0 || extras.length > 0) {
76
77
  throw new Error(`Usage: ${START_USAGE}`);
77
78
  }
78
- await setupWorkspaceCli(ticket, { dryRun });
79
+ await setupWorkspaceCli(task, { dryRun });
79
80
  }
80
81
  async function upgradeCliInvoke(argv) {
81
82
  const metadata = packageMetadata();
@@ -84,21 +85,21 @@ async function upgradeCliInvoke(argv) {
84
85
  cliMetaUrl: import.meta.url,
85
86
  }));
86
87
  }
87
- function doctorTicketAlias(argv) {
88
- if (argv[0] !== "--ticket") {
88
+ function doctorTaskAlias(argv) {
89
+ if (argv[0] !== "--task") {
89
90
  return undefined;
90
91
  }
91
- const ticket = readTicketArgument(argv, 0, "doctor");
92
+ const task = readTaskArgument(argv, 0, "doctor");
92
93
  if (argv.length > 2) {
93
- throw new Error("Usage: crew status [<ticket>]");
94
+ throw new Error("Usage: crew status [<task>]");
94
95
  }
95
- return ticket;
96
+ return task;
96
97
  }
97
98
  async function doctorCli(argv) {
98
- const aliasTicket = doctorTicketAlias(argv);
99
- if (aliasTicket !== undefined) {
100
- warnDeprecated({ oldForm: "doctor --ticket", newForm: "status" });
101
- await statusCli([aliasTicket]);
99
+ const aliasTask = doctorTaskAlias(argv);
100
+ if (aliasTask !== undefined) {
101
+ warnDeprecated({ oldForm: "doctor --task", newForm: "status" });
102
+ await statusCli([aliasTask]);
102
103
  return;
103
104
  }
104
105
  if (argv.length > 0) {
@@ -114,13 +115,13 @@ const SUBCOMMANDS = {
114
115
  invoke: initConfigCli,
115
116
  },
116
117
  run: {
117
- summary: "Run the orchestrator: poll sources and start eligible tickets (one-shot by default)",
118
+ summary: "Run the orchestrator: poll sources and start eligible tasks (one-shot by default)",
118
119
  usage: "[--watch] [--dry-run]",
119
120
  invoke: runCli,
120
121
  },
121
122
  start: {
122
- summary: "Launch one ticket immediately, bypassing eligibility",
123
- usage: "<ticket> [--dry-run]",
123
+ summary: "Launch one task immediately, bypassing eligibility",
124
+ usage: "<task> [--dry-run]",
124
125
  invoke: startCli,
125
126
  },
126
127
  doctor: {
@@ -128,24 +129,29 @@ const SUBCOMMANDS = {
128
129
  usage: "",
129
130
  invoke: doctorCli,
130
131
  },
132
+ source: {
133
+ summary: "Inspect configured task sources",
134
+ usage: "<list|verify> [...]",
135
+ invoke: sourceCli,
136
+ },
131
137
  status: {
132
- summary: "Print read-only groundcrew state, or one ticket's local/Linear status",
133
- usage: "[<ticket>]",
138
+ summary: "Print read-only groundcrew state, or one task's local/Linear status",
139
+ usage: "[<task>]",
134
140
  invoke: statusCli,
135
141
  },
136
142
  cleanup: {
137
143
  summary: "Tear down a worktree",
138
- usage: "[--force] <ticket>",
144
+ usage: "[--force] <task>",
139
145
  invoke: cleanupWorkspaceCli,
140
146
  },
141
147
  stop: {
142
- summary: "Stop a live ticket workspace while preserving its worktree",
143
- usage: "<ticket> [--reason <text>]",
148
+ summary: "Stop a live task workspace while preserving its worktree",
149
+ usage: "<task> [--reason <text>]",
144
150
  invoke: interruptWorkspaceCli,
145
151
  },
146
152
  interrupt: {
147
153
  summary: "Deprecated alias for `crew stop`",
148
- usage: "<ticket> [--reason <text>]",
154
+ usage: "<task> [--reason <text>]",
149
155
  deprecated: true,
150
156
  invoke: async (argv) => {
151
157
  warnDeprecated({ oldForm: "interrupt", newForm: "stop" });
@@ -153,8 +159,8 @@ const SUBCOMMANDS = {
153
159
  },
154
160
  },
155
161
  resume: {
156
- summary: "Reopen an existing ticket worktree with a continuation prompt",
157
- usage: "<ticket>",
162
+ summary: "Reopen an existing task worktree with a continuation prompt",
163
+ usage: "<task>",
158
164
  invoke: resumeWorkspaceCli,
159
165
  },
160
166
  setup: {
@@ -1,21 +1,21 @@
1
1
  /**
2
2
  * Per-iteration scanner that closes workspaces and removes worktrees for
3
- * tickets that have reached a terminal status. One per `orchestrate()`
3
+ * tasks that have reached a terminal status. One per `orchestrate()`
4
4
  * invocation; stateless across iterations. Mirrors `Dispatcher`.
5
5
  */
6
6
  import type { ResolvedConfig } from "../lib/config.ts";
7
- import { type BoardState } from "../lib/ticketSource.ts";
7
+ import { type BoardState } from "../lib/taskSource.ts";
8
8
  import { type WorktreeEntry } from "../lib/worktrees.ts";
9
9
  interface CleanerDeps {
10
10
  config: ResolvedConfig;
11
11
  }
12
12
  export interface Cleaner {
13
- runOnce(arguments_: {
13
+ runOnce: (arguments_: {
14
14
  state: BoardState;
15
15
  worktreeEntries: readonly WorktreeEntry[];
16
16
  dryRun: boolean;
17
17
  signal?: AbortSignal;
18
- }): Promise<void>;
18
+ }) => Promise<void>;
19
19
  }
20
20
  export declare function createCleaner(deps: CleanerDeps): Cleaner;
21
21
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"cleaner.d.ts","sourceRoot":"","sources":["../../src/commands/cleaner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAA0B,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEjF,OAAO,EAAE,KAAK,aAAa,EAAa,MAAM,qBAAqB,CAAC;AAGpE,UAAU,WAAW;IACnB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,CAAC,UAAU,EAAE;QAClB,KAAK,EAAE,UAAU,CAAC;QAClB,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;QAC1C,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAoDxD"}
1
+ {"version":3,"file":"cleaner.d.ts","sourceRoot":"","sources":["../../src/commands/cleaner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAA0B,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE/E,OAAO,EAAE,KAAK,aAAa,EAAa,MAAM,qBAAqB,CAAC;AAGpE,UAAU,WAAW;IACnB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,CAAC,UAAU,EAAE;QACpB,KAAK,EAAE,UAAU,CAAC;QAClB,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;QAC1C,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAoDxD"}
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Per-iteration scanner that closes workspaces and removes worktrees for
3
- * tickets that have reached a terminal status. One per `orchestrate()`
3
+ * tasks that have reached a terminal status. One per `orchestrate()`
4
4
  * invocation; stateless across iterations. Mirrors `Dispatcher`.
5
5
  */
6
6
  import { recordCleanedUpRuns } from "../lib/runStateCleanup.js";
7
- import { naturalIdFromCanonical } from "../lib/ticketSource.js";
7
+ import { naturalIdFromCanonical } from "../lib/taskSource.js";
8
8
  import { log, logEvent } from "../lib/util.js";
9
9
  import { worktrees } from "../lib/worktrees.js";
10
10
  import { logTeardown, recordTeardownEvents } from "./teardownReporter.js";
@@ -12,24 +12,24 @@ export function createCleaner(deps) {
12
12
  const { config } = deps;
13
13
  async function runOnce(arguments_) {
14
14
  const { state, worktreeEntries, dryRun, signal } = arguments_;
15
- const terminalTickets = new Set(state.issues
15
+ const terminalTasks = new Set(state.issues
16
16
  .filter((issue) => issue.status === "done")
17
17
  .map((issue) => naturalIdFromCanonical(issue.id)));
18
- if (terminalTickets.size === 0) {
18
+ if (terminalTasks.size === 0) {
19
19
  return;
20
20
  }
21
- const stale = worktreeEntries.filter((entry) => terminalTickets.has(entry.ticket));
21
+ const stale = worktreeEntries.filter((entry) => terminalTasks.has(entry.task));
22
22
  if (stale.length === 0) {
23
23
  return;
24
24
  }
25
25
  if (dryRun) {
26
26
  log(`[dry-run] ${stale.length} worktree(s) due for cleanup:`);
27
27
  for (const entry of stale) {
28
- log(` - ${entry.repository}-${entry.ticket} (${entry.kind})`);
28
+ log(` - ${entry.repository}-${entry.task} (${entry.kind})`);
29
29
  logEvent("cleanup", {
30
30
  outcome: "skipped",
31
31
  reason: "dry_run",
32
- ticket: entry.ticket,
32
+ task: entry.task,
33
33
  repository: entry.repository,
34
34
  kind: entry.kind,
35
35
  });
@@ -1,6 +1,6 @@
1
1
  import { type ResolvedConfig } from "../lib/config.ts";
2
2
  export interface CleanupWorkspaceOptions {
3
- ticket: string;
3
+ task: string;
4
4
  /** Default false. The automated cleanup path keeps in-flight uncommitted work. */
5
5
  force?: boolean;
6
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cleanupWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/cleanupWorkspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAQnE,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAwBD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CA+Bf;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvE"}
1
+ {"version":3,"file":"cleanupWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/cleanupWorkspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAQnE,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAwBD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CA6Bf;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvE"}
@@ -14,35 +14,35 @@ function parseArguments(argv) {
14
14
  continue;
15
15
  }
16
16
  if (argument.startsWith("-")) {
17
- throw new Error(`Unknown option: ${argument}\nUsage: crew cleanup [--force] <ticket>\nExample: crew cleanup team-220`);
17
+ throw new Error(`Unknown option: ${argument}\nUsage: crew cleanup [--force] <task>\nExample: crew cleanup team-220`);
18
18
  }
19
19
  positionals.push(argument);
20
20
  }
21
- const [ticket, ...extras] = positionals;
22
- if (ticket === undefined || ticket.length === 0 || extras.length > 0) {
23
- throw new Error("Usage: crew cleanup [--force] <ticket>\nExample: crew cleanup team-220");
21
+ const [task, ...extras] = positionals;
22
+ if (task === undefined || task.length === 0 || extras.length > 0) {
23
+ throw new Error("Usage: crew cleanup [--force] <task>\nExample: crew cleanup team-220");
24
24
  }
25
- return { ticket: ticket.toLowerCase(), force };
25
+ return { task: task.toLowerCase(), force };
26
26
  }
27
27
  export async function cleanupWorkspace(config, options) {
28
- const { ticket, force = false } = options;
29
- const entries = worktrees.findByTicket(config, ticket);
28
+ const { task, force = false } = options;
29
+ const entries = worktrees.findByTask(config, task);
30
30
  if (entries.length === 0) {
31
- if (readRunState(config, ticket) === undefined) {
32
- log(`No worktree found for ${ticket}; nothing to clean up.`);
31
+ if (readRunState(config, task) === undefined) {
32
+ log(`No worktree found for ${task}; nothing to clean up.`);
33
33
  return;
34
34
  }
35
35
  const workspaceProbe = await workspaces.probe(config);
36
36
  if (workspaceProbe.kind === "unavailable") {
37
- log(`No worktree found for ${ticket}; workspace probe unavailable, leaving run-state intact.`);
37
+ log(`No worktree found for ${task}; workspace probe unavailable, leaving run-state intact.`);
38
38
  return;
39
39
  }
40
- if (workspaceProbe.names.has(ticket)) {
41
- log(`No worktree found for ${ticket}; workspace still present; leaving run-state intact.`);
40
+ if (workspaceProbe.names.has(task)) {
41
+ log(`No worktree found for ${task}; workspace still present; leaving run-state intact.`);
42
42
  return;
43
43
  }
44
- removeRunState(config, ticket);
45
- log(`No worktree found for ${ticket}; cleared stale run-state.`);
44
+ removeRunState(config, task);
45
+ log(`No worktree found for ${task}; cleared stale run-state.`);
46
46
  return;
47
47
  }
48
48
  const result = await worktrees.teardown(config, entries, { force });
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Per-iteration decider that picks Todo tickets to start and acts on the
2
+ * Per-iteration decider that picks Todo tasks to start and acts on the
3
3
  * picks. Stateless across iterations. The Board adapter owns its own writeback
4
4
  * caches (e.g., Linear's team-state cache lives in `src/lib/adapters/linear/writeback.ts`).
5
5
  *
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import type { Board } from "../lib/board.ts";
10
10
  import type { ResolvedConfig } from "../lib/config.ts";
11
- import { type BoardState, type Issue } from "../lib/ticketSource.ts";
11
+ import { type BoardState, type Issue } from "../lib/taskSource.ts";
12
12
  import type { UsageByModel } from "../lib/usage.ts";
13
13
  import type { WorktreeEntry } from "../lib/worktrees.ts";
14
14
  interface DispatcherDeps {
@@ -16,7 +16,7 @@ interface DispatcherDeps {
16
16
  board: Board;
17
17
  }
18
18
  export interface Dispatcher {
19
- runOnce(arguments_: {
19
+ runOnce: (arguments_: {
20
20
  state: BoardState;
21
21
  worktreeEntries: readonly WorktreeEntry[];
22
22
  /** Lazy so dispatcher can early-return on idle ticks without paying the codexbar shell-out. */
@@ -29,7 +29,7 @@ export interface Dispatcher {
29
29
  * printing a second line per tick.
30
30
  */
31
31
  idleSuffix?: string;
32
- }): Promise<void>;
32
+ }) => Promise<void>;
33
33
  }
34
34
  export declare function createDispatcher(deps: DispatcherDeps): Dispatcher;
35
35
  export declare function formatActiveSlotList(active: readonly Issue[]): string;
@@ -1 +1 @@
1
- {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/commands/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EACL,KAAK,UAAU,EAGf,KAAK,KAAK,EAEX,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAWzD,UAAU,cAAc;IACtB,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,KAAK,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,UAAU,EAAE;QAClB,KAAK,EAAE,UAAU,CAAC;QAClB,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;QAC1C,+FAA+F;QAC/F,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;QACvD,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB;;;;WAIG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB;AAaD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,CA2NjE;AA2BD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,MAAM,CAQrE"}
1
+ {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/commands/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EACL,KAAK,UAAU,EAGf,KAAK,KAAK,EAEX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAWzD,UAAU,cAAc;IACtB,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,KAAK,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,CAAC,UAAU,EAAE;QACpB,KAAK,EAAE,UAAU,CAAC;QAClB,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;QAC1C,+FAA+F;QAC/F,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;QACvD,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB;;;;WAIG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrB;AAaD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,CAyNjE;AA2BD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,MAAM,CAQrE"}