@clipboard-health/groundcrew 3.4.1 → 4.0.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 (37) hide show
  1. package/README.md +19 -24
  2. package/clearance-allow-hosts +7 -0
  3. package/crew.config.example.ts +13 -32
  4. package/dist/commands/cleaner.d.ts.map +1 -1
  5. package/dist/commands/cleaner.js +1 -5
  6. package/dist/commands/dispatcher.d.ts.map +1 -1
  7. package/dist/commands/dispatcher.js +5 -5
  8. package/dist/commands/eligibility.d.ts +1 -1
  9. package/dist/commands/eligibility.d.ts.map +1 -1
  10. package/dist/commands/eligibility.js +4 -4
  11. package/dist/commands/init.d.ts.map +1 -1
  12. package/dist/commands/init.js +2 -1
  13. package/dist/commands/setupWorkspace.d.ts.map +1 -1
  14. package/dist/commands/setupWorkspace.js +1 -2
  15. package/dist/commands/ticketDoctor.d.ts.map +1 -1
  16. package/dist/commands/ticketDoctor.js +11 -33
  17. package/dist/index.d.ts +3 -3
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +2 -2
  20. package/dist/lib/adapters/linear/factory.d.ts +10 -14
  21. package/dist/lib/adapters/linear/factory.d.ts.map +1 -1
  22. package/dist/lib/adapters/linear/factory.js +23 -63
  23. package/dist/lib/adapters/linear/schema.d.ts +3 -5
  24. package/dist/lib/adapters/linear/schema.d.ts.map +1 -1
  25. package/dist/lib/adapters/linear/schema.js +3 -5
  26. package/dist/lib/boardSource.d.ts +55 -39
  27. package/dist/lib/boardSource.d.ts.map +1 -1
  28. package/dist/lib/boardSource.js +130 -237
  29. package/dist/lib/config.d.ts +11 -70
  30. package/dist/lib/config.d.ts.map +1 -1
  31. package/dist/lib/config.js +10 -157
  32. package/dist/lib/linearIssueStatus.d.ts +0 -4
  33. package/dist/lib/linearIssueStatus.d.ts.map +1 -1
  34. package/dist/lib/linearIssueStatus.js +0 -0
  35. package/dist/lib/ticketSource.d.ts +5 -7
  36. package/dist/lib/ticketSource.d.ts.map +1 -1
  37. package/package.json +1 -1
package/README.md CHANGED
@@ -39,7 +39,7 @@ Eligibility
39
39
 
40
40
  ## Why
41
41
 
42
- - **Linear-native.** Polls a project, respects `agent-*` labels, honors blockers.
42
+ - **Linear-native.** Polls issues assigned to the API key's viewer with `agent-*` labels, honors blockers.
43
43
  - **One worktree per ticket.** Agents work in parallel without stepping on each other.
44
44
  - **Local-first sandboxing.** Safehouse on macOS, Docker Sandboxes on Linux, or an explicit `none` escape hatch.
45
45
  - **Multi-agent.** Ships with `claude` and `codex`; bring your own CLI by dropping a definition into `crew.config.ts`.
@@ -58,7 +58,7 @@ Installs the `crew` binary. `@clipboard-health/clearance` is pulled in transitiv
58
58
 
59
59
  2. **Pick an isolation runner.** See [Runners](#runners) — `auto` resolves to `safehouse` on macOS and `sdx` on Linux/WSL.
60
60
 
61
- 3. **Create a Linear project to scope your work.** Any team works make a project inside it and drop tickets in. The orchestrator polls by project, not by team.
61
+ 3. **Prepare tickets in Linear.** Assign tickets to yourself and add an `agent-*` label. Groundcrew picks them up across all visible teams and projects.
62
62
 
63
63
  4. **Configure.** Create a `crew.config.ts` you can edit:
64
64
 
@@ -74,7 +74,7 @@ Installs the `crew` binary. `@clipboard-health/clearance` is pulled in transitiv
74
74
 
75
75
  `crew` discovers the config via cosmiconfig project-walk, so dropping it at the root of any repo you run `crew` from works too. Any of `crew.config.{ts,mjs,js,json}`, `.crewrc{,.json,.ts}`, `.config/crew.config.{ts,json}`, or `.config/crewrc{,.json}` are recognized.
76
76
 
77
- Set `linear.projects[].projectSlug` (paste the trailing slug of your Linear project URL, e.g. `ai-strategy-5152195762f3`), `workspace.projectDir`, and `workspace.knownRepositories`. Defaults cover everything else. To watch multiple projects from one `crew` instance, add more entries to `linear.projects`; they all share the same `orchestrator.maximumInProgress` budget.
77
+ Set `workspace.projectDir` and `workspace.knownRepositories`. Defaults cover everything else. There is no `linear` config block groundcrew picks up every Linear issue assigned to your API key's viewer that carries an `agent-*` label, across every project and team you can see, governed by a single `orchestrator.maximumInProgress` budget.
78
78
 
79
79
  Then clone each repo before the first `crew run` — groundcrew creates per-ticket worktrees from these clones, it does not auto-clone:
80
80
 
@@ -164,21 +164,22 @@ Watch `${XDG_CACHE_HOME:-$HOME/.cache}/clearance/clearance.log` for `DENY` lines
164
164
 
165
165
  ## Configuration
166
166
 
167
- Three keys are required; everything else has a default.
167
+ Two keys are required; everything else has a default.
168
168
 
169
- | Key | What |
170
- | ------------------------------- | --------------------------------------------------------------------------------------------------------- |
171
- | `linear.projects[].projectSlug` | Trailing slug of each Linear project URL to watch (e.g. `ai-strategy-5152195762f3`). One or more entries. |
172
- | `workspace.projectDir` | Parent dir for cloned repos and sibling ticket worktrees. |
173
- | `workspace.knownRepositories` | Repos searched for in ticket descriptions to infer where work belongs. |
169
+ | Key | What |
170
+ | ----------------------------- | ---------------------------------------------------------------------- |
171
+ | `workspace.projectDir` | Parent dir for cloned repos and sibling ticket worktrees. |
172
+ | `workspace.knownRepositories` | Repos searched for in ticket descriptions to infer where work belongs. |
173
+
174
+ There is **no** `linear` config block. Groundcrew's built-in Linear adapter picks up every Linear issue assigned to your API key's viewer that carries an `agent-*` label — across every project and team you can see. State classification is driven by Linear's workflow `state.type` (`unstarted` → todo, `started` → in progress, `completed`/`canceled`/`duplicate` → terminal), so renamed status columns Just Work without any per-team configuration.
174
175
 
175
176
  `crew` resolves config as: `GROUNDCREW_CONFIG` if set → project-walk from cwd (cosmiconfig: `crew.config.{ts,mjs,js,json}`, `.crewrc{,.json,.ts}`, `.config/crew.config.{ts,json}`, `.config/crewrc{,.json}`) → `${XDG_CONFIG_HOME:-$HOME/.config}/groundcrew/crew.config.ts` (also accepts legacy `config.ts` for one release). The branch prefix (`<prefix>-<TICKET>`) is derived from `os.userInfo().username` — not configurable.
176
177
 
177
- 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.
178
+ Agent selection uses Linear labels: `agent-claude`, `agent-codex`, `agent-<name>`. `crew run` without `--ticket` only fetches tickets carrying an `agent-*` label AND assigned to the API key's viewer — the GraphQL query filters server-side, so unlabeled or unassigned 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.
178
179
 
179
180
  ### Pluggable ticket sources
180
181
 
181
- `sources` declares extra ticket-system adapters. The current release verifies configured extra sources during `crew run` startup; the dispatch loop still reads Linear through `linear.projects` until the consumer refactor lands. This lets you validate shell/Jira/local-plan integrations without changing existing Linear behavior.
182
+ `sources` declares extra ticket-system adapters. The current release verifies configured extra sources during `crew run` startup; the dispatch loop still reads Linear directly through the built-in Linear adapter until the canonical consumer refactor lands. This lets you validate shell/Jira/local-plan integrations without changing existing Linear behavior.
182
183
 
183
184
  The built-in `shell` adapter runs command templates and reads JSON from stdout:
184
185
 
@@ -247,18 +248,12 @@ This keeps package defaults portable while letting your private config reference
247
248
 
248
249
  | Key | Default | What it does |
249
250
  | --------------------------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
250
- | `linear.projects` | **required** | Non-empty array of Linear projects to watch. One `crew` instance dispatches across every entry under a shared `maximumInProgress` budget. |
251
- | `linear.projects[].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 `crew.config.ts` self-documenting and the lookup survives project renames. |
252
- | `linear.projects[].statuses.todo` | `"Todo"` | Status name picked up for new work in this project. Per-project so multi-team setups with divergent state names can coexist. |
253
- | `linear.projects[].statuses.inProgress` | `"In Progress"` | Status set after a workspace is provisioned; counts toward the shared `maximumInProgress`. |
254
- | `linear.projects[].statuses.done` | `"Done"` | Status that triggers worktree cleanup for this project. |
255
- | `linear.projects[].statuses.terminal` | `["Done"]` | Additional status names treated as terminal for cleanup and blocker checks. The project's `done` status is always included. |
256
- | `sources` | `[]` | Additional pluggable ticket sources. Extra sources are verified at startup; Linear remains the dispatch read path until the consumer refactor. Built-in kinds: `shell`, `linear`. |
251
+ | `sources` | `[]` | Additional pluggable ticket sources. Extra sources are verified at startup; the built-in Linear adapter remains the dispatch read path until the canonical consumer refactor. Built-in kinds: `shell`, `linear`. |
257
252
  | `git.remote` | `"origin"` | Remote used for `fetch` and as the worktree base ref. |
258
253
  | `git.defaultBranch` | `"main"` | Branch fetched from `git.remote` and used as the worktree base. |
259
254
  | `workspace.projectDir` | **required** | Parent dir for cloned repos and sibling ticket worktrees. |
260
255
  | `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. |
261
- | `orchestrator.maximumInProgress` | `4` | Cap on in-progress tickets at once, shared across every project in `linear.projects`. |
256
+ | `orchestrator.maximumInProgress` | `4` | Cap on in-progress tickets at once for this `crew` instance. |
262
257
  | `orchestrator.pollIntervalMilliseconds` | `120_000` | Poll interval in `--watch` mode. |
263
258
  | `orchestrator.sessionLimitPercentage` | `85` | Number in `(0, 100]`. A model whose codexbar session window exceeds this percentage is skipped that tick. |
264
259
  | `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`. |
@@ -494,9 +489,9 @@ When a wrapped agent command fails (e.g. `safehouse-clearance` not found, `npm i
494
489
  </details>
495
490
 
496
491
  <details>
497
- <summary>Status names matter</summary>
492
+ <summary>Status names don't matter</summary>
498
493
 
499
- If your team uses `Started` instead of `In Progress`, set `linear.projects[].statuses.inProgress = "Started"` on that project's entry. Status overrides are per-project so divergent team workflows coexist.
494
+ Groundcrew classifies tickets by Linear's workflow `state.type` (`unstarted`, `started`, `completed`, `canceled`, `duplicate`), not by status name. Teams that rename "Todo" to "To Do" or "Done" to "Shipped" need no configuration the orchestrator still classifies correctly.
500
495
 
501
496
  </details>
502
497
 
@@ -510,14 +505,14 @@ Parent issues with children are ignored — sub-issues are the work items.
510
505
  <details>
511
506
  <summary>Tickets stay in-progress until something else moves them</summary>
512
507
 
513
- Groundcrew sets a ticket to `inProgress` when it provisions a workspace and never advances it. The next transition (typically "in review" when a PR opens) is left to your Linear automation rules.
508
+ Groundcrew sets a ticket to `Started` (the first workflow state with `type === "started"` on that team) when it provisions a workspace and never advances it. The next transition (typically "In Review" when a PR opens) is left to your Linear automation rules.
514
509
 
515
510
  </details>
516
511
 
517
512
  <details>
518
- <summary>Cross-team projects need a consistent `inProgress` name per project</summary>
513
+ <summary>Cross-team boards work out of the box</summary>
519
514
 
520
- Cross-team projects work the orchestrator caches the in-progress state ID per `(team, statusName)` pair but every team in a given project must use the same status name for that project's `statuses.inProgress`. If you watch two projects that share a Linear team but configure different `inProgress` names, each project's lookup is independent.
515
+ Groundcrew picks up tickets across every team your API key's viewer can see. The "mark in progress" writeback looks up each ticket's own team workflow and uses that team's `started` state, so teams with different state names coexist without any per-team configuration.
521
516
 
522
517
  </details>
523
518
 
@@ -67,10 +67,17 @@ api.npmjs.org
67
67
  registry.npmjs.org
68
68
  www.npmjs.com
69
69
 
70
+ # Google APIs
71
+ developers.google.com
72
+ drive.googleapis.com
73
+ forms.googleapis.com
74
+ www.googleapis.com
75
+
70
76
  # Developer tooling
71
77
  app.terraform.io
72
78
  buf.build
73
79
  cdn.playwright.dev
80
+ cloud.nx.app
74
81
  fastdl.mongodb.org
75
82
  formulae.brew.sh
76
83
  hub.docker.com
@@ -2,32 +2,15 @@ import type { Config } from "@clipboard-health/groundcrew";
2
2
  // import { readFileSync } from "node:fs";
3
3
 
4
4
  export default {
5
- linear: {
6
- // One or more Linear projects to watch. A single `crew` process
7
- // dispatches across all configured projects under a shared
8
- // `orchestrator.maximumInProgress` budget.
9
- //
10
- // Each entry's `projectSlug` is the trailing segment of your Linear
11
- // project URL — copy it verbatim, e.g. "ai-strategy-5152195762f3"
12
- // from "https://linear.app/<workspace>/project/ai-strategy-5152195762f3".
13
- // The 12-char hex tail is the canonical ID groundcrew uses, so the
14
- // orchestrator stays resilient across project renames and across
15
- // same-name projects in different teams. The leading name segment
16
- // keeps the file self-documenting at a glance.
17
- //
18
- // `statuses` is per-project so multi-team setups with divergent
19
- // workflow state names (e.g. "Todo" vs "To Do", "Shipped" vs
20
- // "Done") can coexist. Each field falls back to its default when
21
- // omitted: { todo: "Todo", inProgress: "In Progress",
22
- // done: "Done", terminal: ["Done"] }.
23
- projects: [
24
- { projectSlug: "your-project-name-0123456789ab" },
25
- // {
26
- // projectSlug: "platform-aaaaaaaaaaaa",
27
- // statuses: { inProgress: "Doing", done: "Released", terminal: ["Released", "Won't Do"] },
28
- // },
29
- ],
30
- },
5
+ // Groundcrew's built-in Linear adapter is implicit and needs no config:
6
+ // it picks up every Linear issue assigned to your API key's viewer that
7
+ // carries an `agent-*` label. There is no project / view / status
8
+ // block — Linear's workflow `state.type` (`unstarted` → todo,
9
+ // `started` → in progress, `completed`/`canceled`/`duplicate` →
10
+ // terminal) is the single source of truth, so renamed columns Just Work.
11
+ //
12
+ // Opt a ticket in: assign it to yourself and add an `agent-<model>`
13
+ // label (e.g. `agent-claude`, `agent-any`).
31
14
  workspace: {
32
15
  // Parent directory under which groundcrew clones repositories and
33
16
  // creates per-ticket worktrees.
@@ -41,11 +24,10 @@ export default {
41
24
  // and edit to override.
42
25
  //
43
26
  // // Additional pluggable ticket sources beyond the implicit built-in
44
- // // Linear adapter (configured via `linear.projects` above). The most
45
- // // common use is `kind: "shell"`, which wires any external system via
46
- // // command templates that emit/consume JSON. See the shell adapter's
47
- // // ShellIssue schema for the JSON contract `fetch` / `resolveOne` must
48
- // // emit.
27
+ // // Linear adapter. The most common use is `kind: "shell"`, which wires
28
+ // // any external system via command templates that emit/consume JSON.
29
+ // // See the shell adapter's ShellIssue schema for the JSON contract
30
+ // // `fetch` / `resolveOne` must emit.
49
31
  // sources: [
50
32
  // {
51
33
  // kind: "shell",
@@ -63,7 +45,6 @@ export default {
63
45
  // git: { remote: "origin", defaultBranch: "main" },
64
46
  //
65
47
  // orchestrator: {
66
- // // Shared across all watched projects in linear.projects.
67
48
  // maximumInProgress: 4,
68
49
  // pollIntervalMilliseconds: 120_000,
69
50
  // sessionLimitPercentage: 85,
@@ -1 +1 @@
1
- {"version":3,"file":"cleaner.d.ts","sourceRoot":"","sources":["../../src/commands/cleaner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,UAAU,EAA4B,MAAM,uBAAuB,CAAC;AAClF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGvD,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,CAsDxD"}
1
+ {"version":3,"file":"cleaner.d.ts","sourceRoot":"","sources":["../../src/commands/cleaner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,UAAU,EAA4B,MAAM,uBAAuB,CAAC;AAClF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGvD,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,CAkDxD"}
@@ -12,11 +12,7 @@ export function createCleaner(deps) {
12
12
  const { config } = deps;
13
13
  async function runOnce(arguments_) {
14
14
  const { state, worktreeEntries, dryRun, signal } = arguments_;
15
- // Only act on tickets in configured projects — if the dir name happens to
16
- // look like a Linear ticket from another project, leave it alone.
17
- const terminalTickets = new Set(state.issues
18
- .filter((issue) => isTerminalStatusForIssue(issue, config))
19
- .map((issue) => issue.id));
15
+ const terminalTickets = new Set(state.issues.filter((issue) => isTerminalStatusForIssue(issue)).map((issue) => issue.id));
20
16
  if (terminalTickets.size === 0) {
21
17
  return;
22
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/commands/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EACL,KAAK,UAAU,EAIhB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,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,MAAM,EAAE,YAAY,CAAC;CACtB;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,CA4LjE"}
1
+ {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/commands/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EACL,KAAK,UAAU,EAKhB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,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,MAAM,EAAE,YAAY,CAAC;CACtB;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,CAyLjE"}
@@ -6,7 +6,7 @@
6
6
  * Pure verdict logic lives in `eligibility.ts`; this module is responsible
7
7
  * for telemetry, Linear writes, and side-effecting setupWorkspace calls.
8
8
  */
9
- import { isGroundcrewIssue, projectFor, } from "../lib/boardSource.js";
9
+ import { isGroundcrewIssue, isIssueInProgress, isIssueTodo, } from "../lib/boardSource.js";
10
10
  import { createLinearIssueStatusUpdater } from "../lib/linearIssueStatus.js";
11
11
  import { errorMessage, log, logEvent } from "../lib/util.js";
12
12
  import { workspaces } from "../lib/workspaces.js";
@@ -24,7 +24,7 @@ function logSkip(verdict) {
24
24
  }
25
25
  export function createDispatcher(deps) {
26
26
  const { config, client } = deps;
27
- const issueStatusUpdater = createLinearIssueStatusUpdater({ config, client });
27
+ const issueStatusUpdater = createLinearIssueStatusUpdater({ client });
28
28
  function buildExhaustedSet(usage) {
29
29
  const exhausted = new Set();
30
30
  for (const exhaustion of classifyUsageExhaustion(config, usage)) {
@@ -99,11 +99,11 @@ export function createDispatcher(deps) {
99
99
  children: skip.childCount,
100
100
  });
101
101
  }
102
- const activeCount = state.issues.filter((issue) => issue.status === projectFor(issue, config).statuses.inProgress).length;
102
+ const activeCount = state.issues.filter((issue) => isIssueInProgress(issue)).length;
103
103
  const slots = config.orchestrator.maximumInProgress - activeCount;
104
104
  // Narrow Todo to tickets that opted in via an `agent-*` label.
105
105
  // Unlabeled tickets are not groundcrew's concern even when in Todo.
106
- const todo = state.issues.filter((issue) => issue.status === projectFor(issue, config).statuses.todo && isGroundcrewIssue(issue));
106
+ const todo = state.issues.filter((issue) => isIssueTodo(issue) && isGroundcrewIssue(issue));
107
107
  if (slots <= 0) {
108
108
  log(`At capacity (${activeCount}/${config.orchestrator.maximumInProgress}), no new work to start${idleSuffix}`);
109
109
  return;
@@ -114,7 +114,7 @@ export function createDispatcher(deps) {
114
114
  }
115
115
  // Run the blocker pre-pass first so an all-blocked board short-circuits
116
116
  // before the codexbar HTTP call and the cmux/tmux shell-out fire.
117
- const { unblocked, skips: blockerSkips } = classifyBlockers(config, todo);
117
+ const { unblocked, skips: blockerSkips } = classifyBlockers(todo);
118
118
  for (const skip of blockerSkips) {
119
119
  logSkip(skip);
120
120
  }
@@ -88,7 +88,7 @@ export declare function classifyUsageExhaustion(config: ResolvedConfig, usage: U
88
88
  * workspace adapter, so a board where every Todo is blocked short-circuits
89
89
  * without paying for either.
90
90
  */
91
- export declare function classifyBlockers(config: ResolvedConfig, todo: readonly GroundcrewIssue[]): BlockerClassification;
91
+ export declare function classifyBlockers(todo: readonly GroundcrewIssue[]): BlockerClassification;
92
92
  /**
93
93
  * Eligibility verdicts for already-unblocked Todo issues — handles
94
94
  * agent-any resolution, session exhaustion, worktree/workspace recovery,
@@ -1 +1 @@
1
- {"version":3,"file":"eligibility.d.ts","sourceRoot":"","sources":["../../src/commands/eligibility.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOzD,KAAK,UAAU,GACX,SAAS,GACT,oBAAoB,GACpB,oBAAoB,GACpB,iBAAiB,GACjB,4BAA4B,GAC5B,mBAAmB,CAAC;AAExB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,eAAe,CAAC;IACvB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,WAAW,EAAE,UAAU,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,OAAO,GAAG,YAAY,GAAG,WAAW,CAAC;AAE1C,MAAM,MAAM,oBAAoB,GAC5B;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEN,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,cAAc,CAAC;IACvB;;;;;OAKG;IACH,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,cAAc,EAAE,cAAc,CAAC;IAC/B,KAAK,EAAE,YAAY,CAAC;IACpB,oDAAoD;IACpD,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,UAAU,qBAAqB;IAC7B,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAqCD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GACrB,MAAM,GAAG,SAAS,CAepB;AAaD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,YAAY,GAClB,oBAAoB,EAAE,CAmCxB;AA4CD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,SAAS,eAAe,EAAE,GAC/B,qBAAqB,CAYvB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,EAAE,CAgE5E"}
1
+ {"version":3,"file":"eligibility.d.ts","sourceRoot":"","sources":["../../src/commands/eligibility.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOzD,KAAK,UAAU,GACX,SAAS,GACT,oBAAoB,GACpB,oBAAoB,GACpB,iBAAiB,GACjB,4BAA4B,GAC5B,mBAAmB,CAAC;AAExB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,eAAe,CAAC;IACvB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,WAAW,EAAE,UAAU,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,OAAO,GAAG,YAAY,GAAG,WAAW,CAAC;AAE1C,MAAM,MAAM,oBAAoB,GAC5B;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEN,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,cAAc,CAAC;IACvB;;;;;OAKG;IACH,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,cAAc,EAAE,cAAc,CAAC;IAC/B,KAAK,EAAE,YAAY,CAAC;IACpB,oDAAoD;IACpD,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,UAAU,qBAAqB;IAC7B,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAgCD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GACrB,MAAM,GAAG,SAAS,CAepB;AAaD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,YAAY,GAClB,oBAAoB,EAAE,CAmCxB;AA4CD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,eAAe,EAAE,GAAG,qBAAqB,CAYxF;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,EAAE,CAgE5E"}
@@ -15,7 +15,7 @@ const MINUTES_PER_WEEK = DAYS_PER_WEEK * MINUTES_PER_DAY;
15
15
  function blockerSummary(blocker) {
16
16
  return `${blocker.id}:${blocker.status ?? "missing"}`;
17
17
  }
18
- function blockerVerdictFor(issue, config) {
18
+ function blockerVerdictFor(issue) {
19
19
  if (issue.hasMoreBlockers) {
20
20
  const blockers = issue.blockers.map(blockerSummary);
21
21
  return {
@@ -26,7 +26,7 @@ function blockerVerdictFor(issue, config) {
26
26
  blockers,
27
27
  };
28
28
  }
29
- const unresolved = issue.blockers.filter((blocker) => !isTerminalStatusForBlocker(blocker, config));
29
+ const unresolved = issue.blockers.filter((blocker) => !isTerminalStatusForBlocker(blocker));
30
30
  if (unresolved.length === 0) {
31
31
  return undefined;
32
32
  }
@@ -138,11 +138,11 @@ function classifyRecovery(arguments_) {
138
138
  * workspace adapter, so a board where every Todo is blocked short-circuits
139
139
  * without paying for either.
140
140
  */
141
- export function classifyBlockers(config, todo) {
141
+ export function classifyBlockers(todo) {
142
142
  const unblocked = [];
143
143
  const skips = [];
144
144
  for (const issue of todo) {
145
- const verdict = blockerVerdictFor(issue, config);
145
+ const verdict = blockerVerdictFor(issue);
146
146
  if (verdict === undefined) {
147
147
  unblocked.push(issue);
148
148
  }
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,KAAK,eAAe,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1C,UAAU,iBAAiB;IACzB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,yCAAyC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iEAAiE;IACjE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,uEAAuE;IACvE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,KAAK,iBAAiB,GAAG,qBAAqB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEpE,UAAU,gBAAgB;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,iBAAiB,CAAC;CAC5B;AAED,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,gBAAgB,CAoB5E;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBjE"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,KAAK,eAAe,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1C,UAAU,iBAAiB;IACzB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,yCAAyC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iEAAiE;IACjE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,uEAAuE;IACvE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,KAAK,iBAAiB,GAAG,qBAAqB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEpE,UAAU,gBAAgB;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,iBAAiB,CAAC;CAC5B;AAED,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,gBAAgB,CAoB5E;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBjE"}
@@ -39,8 +39,9 @@ export async function initConfigCli(argv) {
39
39
  writeOutput("");
40
40
  writeOutput("Next steps:");
41
41
  writeOutput(` - Edit ${result.destination}`);
42
- writeOutput(" - Set linear.projects[].projectSlug, workspace.projectDir, workspace.knownRepositories");
42
+ writeOutput(" - Set workspace.projectDir, workspace.knownRepositories");
43
43
  writeOutput(" - Export GROUNDCREW_LINEAR_API_KEY (or LINEAR_API_KEY)");
44
+ writeOutput(" - Assign Linear tickets to yourself and add an agent-* label to opt them in");
44
45
  writeOutput(" - Verify with `crew doctor`");
45
46
  }
46
47
  }
@@ -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,CAqBf"}
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"}
@@ -237,10 +237,9 @@ export async function setupWorkspaceCli(ticket, options = {}) {
237
237
  model: resolved.model,
238
238
  details: { title: resolved.title, description: resolved.description },
239
239
  });
240
- await createLinearIssueStatusUpdater({ config, client }).markInProgress({
240
+ await createLinearIssueStatusUpdater({ client }).markInProgress({
241
241
  id: ticket.toLowerCase(),
242
242
  uuid: resolved.uuid,
243
243
  teamId: resolved.teamId,
244
- projectSlugId: resolved.projectSlugId,
245
244
  });
246
245
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ticketDoctor.d.ts","sourceRoot":"","sources":["../../src/commands/ticketDoctor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ticketDoctor.d.ts","sourceRoot":"","sources":["../../src/commands/ticketDoctor.ts"],"names":[],"mappings":"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"}
@@ -16,10 +16,10 @@
16
16
  // are skipped — they describe pre-dispatch state that no longer matters.
17
17
  import { existsSync } from "node:fs";
18
18
  import { join } from "node:path";
19
- import { fetchBlockersForTicket, fetchInProgressIssueCount, fetchRawLinearIssue, resolveModelFor, resolveRepositoryFor, } from "../lib/boardSource.js";
19
+ import { fetchBlockersForTicket, fetchInProgressIssueCount, fetchRawLinearIssue, isTerminalStateType, resolveModelFor, resolveRepositoryFor, } from "../lib/boardSource.js";
20
20
  import { runCommandAsync } from "../lib/commandRunner.js";
21
21
  import { resolveDefaultBranch } from "../lib/defaultBranch.js";
22
- import { AGENT_ANY_MODEL, findProjectBySlugId, loadConfig, } from "../lib/config.js";
22
+ import { AGENT_ANY_MODEL, loadConfig } from "../lib/config.js";
23
23
  import { which } from "../lib/host.js";
24
24
  import { readRunState } from "../lib/runState.js";
25
25
  import { getUsageByModel } from "../lib/usage.js";
@@ -282,14 +282,14 @@ async function runEligibilityChecks(arguments_) {
282
282
  assignee: "",
283
283
  updatedAt: "",
284
284
  teamId: raw.teamId,
285
- /* v8 ignore next @preserve -- probeLinear gates off-config projects upstream so raw.projectSlugId is always defined here */
286
- projectSlugId: raw.projectSlugId ?? "",
285
+ /* v8 ignore next @preserve -- fetchRawLinearIssue always populates stateType (defaults to "") so the ?? guard is belt-and-suspenders */
286
+ stateType: raw.stateType ?? "",
287
287
  repository: resolvedRepository,
288
288
  model: resolvedModel,
289
289
  blockers: [...blockers],
290
290
  hasMoreBlockers: raw.hasMoreBlockers,
291
291
  };
292
- const blockerClassification = classifyBlockers(config, [groundcrewIssue]);
292
+ const blockerClassification = classifyBlockers([groundcrewIssue]);
293
293
  const [firstSkip] = blockerClassification.skips;
294
294
  if (firstSkip !== undefined) {
295
295
  if (firstSkip.eventReason === "blockers_paginated") {
@@ -386,35 +386,13 @@ async function probeLinear(deps, upperTicket) {
386
386
  }
387
387
  try {
388
388
  const raw = await deps.fetchRawIssue({ ticket: upperTicket });
389
- const project = raw.projectSlugId === undefined
390
- ? undefined
391
- : findProjectBySlugId(deps.config, raw.projectSlugId);
392
- if (project === undefined) {
393
- const configured = deps.config.linear.projects.map((entry) => entry.slugId).join(", ");
394
- const detail = raw.projectSlugId === undefined
395
- ? `ticket has no associated Linear project; configure linear.projects (${configured})`
396
- : `project slugId "${raw.projectSlugId}" is not in linear.projects (configured: ${configured})`;
397
- return {
398
- linearStatus: { kind: "unresolvable", reason: detail },
399
- resolution: [
400
- { name: "Ticket exists in Linear", status: "ok", detail: `"${raw.title}"` },
401
- {
402
- name: "Project is configured",
403
- status: "fail",
404
- detail,
405
- failureSummary: detail,
406
- },
407
- ],
408
- title: raw.title,
409
- raw,
410
- };
411
- }
412
- const isTerminal = project.statuses.terminal.includes(raw.stateName);
413
- const todoState = project.statuses.todo;
389
+ /* v8 ignore next @preserve -- fetchRawLinearIssue always populates stateType (defaults to "") so the ?? guard is belt-and-suspenders */
390
+ const stateType = raw.stateType ?? "";
391
+ const isTerminal = isTerminalStateType(stateType);
414
392
  const resolution = [
415
393
  { name: "Ticket exists in Linear", status: "ok", detail: `"${raw.title}"` },
416
394
  ];
417
- if (raw.stateName === todoState) {
395
+ if (stateType === "unstarted") {
418
396
  resolution.push({ name: "Status is Todo", status: "ok" });
419
397
  }
420
398
  else {
@@ -422,7 +400,7 @@ async function probeLinear(deps, upperTicket) {
422
400
  name: "Status is Todo",
423
401
  status: "fail",
424
402
  detail: `current: ${raw.stateName}`,
425
- failureSummary: `status is ${raw.stateName} (need ${todoState})`,
403
+ failureSummary: `status is ${raw.stateName} (state.type=${stateType}, need unstarted)`,
426
404
  });
427
405
  }
428
406
  return {
@@ -986,7 +964,7 @@ export async function runTicketDoctor(parsed) {
986
964
  fetchRawIssue,
987
965
  fetchBlockersFor: async ({ ticket, uuid }) => await fetchBlockersForTicket({ client: linearClient(), ticket, uuid }),
988
966
  fetchUsage: async () => await getUsageByModel(config),
989
- countInProgress: async () => await fetchInProgressIssueCount({ client: linearClient(), config }),
967
+ countInProgress: async () => await fetchInProgressIssueCount({ client: linearClient() }),
990
968
  findWorktree: (ticket) => worktrees.findByTicket(config, ticket)[0],
991
969
  probeWorkspaces: async () => await workspaces.probe(config),
992
970
  workspaceAccessHint: async (name) => await workspaces.accessHint(config, name),
package/dist/index.d.ts CHANGED
@@ -5,10 +5,10 @@ export { interruptWorkspace, type InterruptWorkspaceOptions, } from "./commands/
5
5
  export { orchestrate, type OrchestratorOptions } from "./commands/orchestrator.ts";
6
6
  export { resumeWorkspace, type ResumeWorkspaceOptions } from "./commands/resumeWorkspace.ts";
7
7
  export { setupWorkspace, type SetupWorkspaceOptions } from "./commands/setupWorkspace.ts";
8
- export type { Config, ModelDefinition, ProjectConfig, ResolvedConfig, ResolvedProjectConfig, SourceConfig, } from "./lib/config.ts";
9
- export { findProjectBySlugId, loadConfig, unionTerminalStatuses } from "./lib/config.ts";
8
+ export type { Config, ModelDefinition, ResolvedConfig, SourceConfig } from "./lib/config.ts";
9
+ export { loadConfig } from "./lib/config.ts";
10
10
  export { readRunState, recordRunState, removeRunState, runStateDirectory, runStatePath, updateRunState, type RunLifecycleState, type RunState, } from "./lib/runState.ts";
11
- export { fetchBlockersForTicket, fetchInProgressIssueCount, fetchRawLinearIssue, fetchResolvedIssue, isTerminalStatusForBlocker, isTerminalStatusForIssue, projectFor, resolveModelFor, resolveRepositoryFor, UnknownProjectError, type ModelResolution, type RawLinearIssue, type RepositoryResolution, } from "./lib/boardSource.ts";
11
+ export { fetchBlockersForTicket, fetchInProgressIssueCount, fetchRawLinearIssue, fetchResolvedIssue, isIssueInProgress, isIssueTodo, isTerminalStateType, isTerminalStatusForBlocker, isTerminalStatusForIssue, resolveModelFor, resolveRepositoryFor, type ModelResolution, type RawLinearIssue, type RepositoryResolution, } from "./lib/boardSource.ts";
12
12
  export { getUsageByModel, type UsageByModel } from "./lib/usage.ts";
13
13
  export { type Board, createBoard } from "./lib/board.ts";
14
14
  export { buildSources, buildSourcesWith } from "./lib/buildSources.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAChG,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,GAC/B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC1F,YAAY,EACV,MAAM,EACN,eAAe,EACf,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,YAAY,GACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACzF,OAAO,EACL,YAAY,EACZ,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,QAAQ,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,EAClB,0BAA0B,EAC1B,wBAAwB,EACxB,UAAU,EACV,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,KAAK,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACvE,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EACL,eAAe,EACf,KAAK,aAAa,EAClB,aAAa,EACb,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,oBAAoB,EACpB,KAAK,OAAO,IAAI,gBAAgB,EAChC,KAAK,UAAU,IAAI,mBAAmB,EACtC,KAAK,eAAe,EACpB,KAAK,eAAe,IAAI,wBAAwB,EAChD,KAAK,KAAK,IAAI,cAAc,EAC5B,iBAAiB,IAAI,0BAA0B,EAC/C,KAAK,YAAY,GAClB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EACL,YAAY,EACZ,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAChG,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,GAC/B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC1F,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACL,YAAY,EACZ,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,QAAQ,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,EACX,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACxB,eAAe,EACf,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,KAAK,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACvE,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EACL,eAAe,EACf,KAAK,aAAa,EAClB,aAAa,EACb,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,oBAAoB,EACpB,KAAK,OAAO,IAAI,gBAAgB,EAChC,KAAK,UAAU,IAAI,mBAAmB,EACtC,KAAK,eAAe,EACpB,KAAK,eAAe,IAAI,wBAAwB,EAChD,KAAK,KAAK,IAAI,cAAc,EAC5B,iBAAiB,IAAI,0BAA0B,EAC/C,KAAK,YAAY,GAClB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EACL,YAAY,EACZ,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -5,9 +5,9 @@ export { interruptWorkspace, } from "./commands/interruptWorkspace.js";
5
5
  export { orchestrate } from "./commands/orchestrator.js";
6
6
  export { resumeWorkspace } from "./commands/resumeWorkspace.js";
7
7
  export { setupWorkspace } from "./commands/setupWorkspace.js";
8
- export { findProjectBySlugId, loadConfig, unionTerminalStatuses } from "./lib/config.js";
8
+ export { loadConfig } from "./lib/config.js";
9
9
  export { readRunState, recordRunState, removeRunState, runStateDirectory, runStatePath, updateRunState, } from "./lib/runState.js";
10
- export { fetchBlockersForTicket, fetchInProgressIssueCount, fetchRawLinearIssue, fetchResolvedIssue, isTerminalStatusForBlocker, isTerminalStatusForIssue, projectFor, resolveModelFor, resolveRepositoryFor, UnknownProjectError, } from "./lib/boardSource.js";
10
+ export { fetchBlockersForTicket, fetchInProgressIssueCount, fetchRawLinearIssue, fetchResolvedIssue, isIssueInProgress, isIssueTodo, isTerminalStateType, isTerminalStatusForBlocker, isTerminalStatusForIssue, resolveModelFor, resolveRepositoryFor, } from "./lib/boardSource.js";
11
11
  export { getUsageByModel } from "./lib/usage.js";
12
12
  export { createBoard } from "./lib/board.js";
13
13
  export { buildSources, buildSourcesWith } from "./lib/buildSources.js";
@@ -1,27 +1,23 @@
1
1
  /**
2
2
  * Linear `TicketSource` factory. Wraps the existing boardSource.ts machinery
3
3
  * (createBoardSource, fetchResolvedIssue, createLinearIssueStatusUpdater) and
4
- * converts the legacy Linear-specific `Issue`/`Blocker` shapes into the
5
- * canonical `Issue`/`Blocker` shapes consumers (via `Board`) speak.
4
+ * converts the Linear-native `Issue`/`Blocker` shapes into the canonical
5
+ * `Issue`/`Blocker` shapes consumers (via `Board`) speak.
6
6
  *
7
- * Per-project canonical-status mapping lives here: each `Issue` is mapped
8
- * against its own project's `statuses` block (the multi-project semantics
9
- * shipped in PR #75). Off-config blockers fall back to the union of all
10
- * configured projects' status sets — preserving today's
11
- * `isTerminalStatusForBlocker` behavior.
7
+ * Status mapping is driven entirely by Linear's workflow `state.type`
8
+ * (`unstarted` todo, `started` in-progress,
9
+ * `completed`/`canceled`/`duplicate` done) so renamed columns are classified
10
+ * correctly without any per-team config.
12
11
  *
13
12
  * Description is not populated on `fetch()` Issues (boardSource's snapshot
14
13
  * doesn't include it); `resolveOne()` Issues carry the full description
15
- * because `fetchResolvedIssue` fetches it explicitly. Phase 6 can lift
16
- * description onto the board snapshot when it refactors setupWorkspace.
14
+ * because `fetchResolvedIssue` fetches it explicitly.
17
15
  */
18
16
  import type { AdapterContext } from "../../adapterDefinition.ts";
19
- import { type Blocker as LinearBlocker, type Issue as LinearIssue } from "../../boardSource.ts";
20
- import { type ResolvedProjectConfig } from "../../config.ts";
17
+ import { type Issue as LinearIssue } from "../../boardSource.ts";
21
18
  import type { CanonicalStatus, Issue as CanonicalIssue, TicketSource } from "../../ticketSource.ts";
22
19
  import type { LinearAdapterConfig } from "./schema.ts";
23
- export declare function canonicalStatusForProject(nativeStatus: string, project: ResolvedProjectConfig): CanonicalStatus;
24
- export declare function canonicalBlockerStatus(blocker: LinearBlocker, globalConfig: AdapterContext["globalConfig"]): CanonicalStatus;
25
- export declare function toCanonicalIssue(linearIssue: LinearIssue, globalConfig: AdapterContext["globalConfig"], sourceName: string): CanonicalIssue;
20
+ export declare function canonicalStatusFromStateType(stateType: string | undefined): CanonicalStatus;
21
+ export declare function toCanonicalIssue(linearIssue: LinearIssue, sourceName: string): CanonicalIssue;
26
22
  export declare function createLinearTicketSource(config: LinearAdapterConfig, context: AdapterContext): TicketSource;
27
23
  //# sourceMappingURL=factory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EACL,KAAK,OAAO,IAAI,aAAa,EAG7B,KAAK,KAAK,IAAI,WAAW,EAE1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAuB,KAAK,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAElF,OAAO,KAAK,EAEV,eAAe,EACf,KAAK,IAAI,cAAc,EACvB,YAAY,EACb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAUvD,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,qBAAqB,GAC7B,eAAe,CAcjB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,aAAa,EACtB,YAAY,EAAE,cAAc,CAAC,cAAc,CAAC,GAC3C,eAAe,CAoBjB;AAcD,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,cAAc,CAAC,cAAc,CAAC,EAC5C,UAAU,EAAE,MAAM,GACjB,cAAc,CA8BhB;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,cAAc,GACtB,YAAY,CAwEd"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAIL,KAAK,KAAK,IAAI,WAAW,EAE1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAEV,eAAe,EACf,KAAK,IAAI,cAAc,EACvB,YAAY,EACb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AASvD,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,eAAe,CAW3F;AAUD,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,CAsB7F;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,cAAc,GACtB,YAAY,CA6Dd"}