@clipboard-health/groundcrew 3.4.1 → 4.0.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.
Files changed (37) hide show
  1. package/README.md +252 -298
  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 +2 -2
@@ -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"}
@@ -1,78 +1,45 @@
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
- import { createBoardSource, fetchResolvedIssue, isTerminalStatusForBlocker, } from "../../boardSource.js";
19
- import { findProjectBySlugId } from "../../config.js";
16
+ import { createBoardSource, fetchResolvedIssue, isTerminalStateType, } from "../../boardSource.js";
20
17
  import { createLinearIssueStatusUpdater } from "../../linearIssueStatus.js";
21
18
  import { getLinearClient } from "../../util.js";
22
- export function canonicalStatusForProject(nativeStatus, project) {
23
- if (project.statuses.todo === nativeStatus) {
19
+ export function canonicalStatusFromStateType(stateType) {
20
+ if (stateType === "unstarted") {
24
21
  return "todo";
25
22
  }
26
- if (project.statuses.inProgress === nativeStatus) {
23
+ if (stateType === "started") {
27
24
  return "in-progress";
28
25
  }
29
- if (project.statuses.done === nativeStatus) {
30
- return "done";
31
- }
32
- if (project.statuses.terminal.includes(nativeStatus)) {
26
+ if (isTerminalStateType(stateType)) {
33
27
  return "done";
34
28
  }
35
29
  return "other";
36
30
  }
37
- export function canonicalBlockerStatus(blocker, globalConfig) {
38
- if (blocker.status === undefined) {
39
- return "other";
40
- }
41
- // Terminal first — handles off-config blockers via the union fallback that
42
- // isTerminalStatusForBlocker already implements.
43
- if (isTerminalStatusForBlocker(blocker, globalConfig)) {
44
- return "done";
45
- }
46
- // Non-terminal: if the blocker's project is configured, use its statuses to
47
- // distinguish todo vs in-progress. For off-config blockers we collapse to
48
- // "other" — eligibility only cares whether the blocker is terminal, so the
49
- // distinction is informational at most.
50
- if (blocker.projectSlugId !== undefined) {
51
- const project = findProjectBySlugId(globalConfig, blocker.projectSlugId);
52
- if (project !== undefined) {
53
- return canonicalStatusForProject(blocker.status, project);
54
- }
55
- }
56
- return "other";
57
- }
58
- function toCanonicalBlocker(blocker, globalConfig, sourceName) {
31
+ function toCanonicalBlocker(blocker, sourceName) {
59
32
  return {
60
33
  id: `${sourceName}:${blocker.id}`,
61
34
  title: blocker.title,
62
- status: canonicalBlockerStatus(blocker, globalConfig),
35
+ status: canonicalStatusFromStateType(blocker.stateType),
63
36
  };
64
37
  }
65
- export function toCanonicalIssue(linearIssue, globalConfig, sourceName) {
66
- const project = findProjectBySlugId(globalConfig, linearIssue.projectSlugId);
67
- /* v8 ignore next 5 @preserve -- fetchBoard's slugId filter and issueStatusBelongsToOwnProject guarantee project is configured by the time we get here */
68
- if (project === undefined) {
69
- throw new Error(`Linear adapter: issue ${linearIssue.id} carries unknown projectSlugId "${linearIssue.projectSlugId}"`);
70
- }
38
+ export function toCanonicalIssue(linearIssue, sourceName) {
71
39
  const sourceRef = {
72
40
  uuid: linearIssue.uuid,
73
41
  statusId: linearIssue.statusId,
74
42
  teamId: linearIssue.teamId,
75
- projectSlugId: linearIssue.projectSlugId,
76
43
  nativeStatus: linearIssue.status,
77
44
  };
78
45
  return {
@@ -81,12 +48,12 @@ export function toCanonicalIssue(linearIssue, globalConfig, sourceName) {
81
48
  title: linearIssue.title,
82
49
  // Board snapshot doesn't carry description; resolveOne() populates it.
83
50
  description: "",
84
- status: canonicalStatusForProject(linearIssue.status, project),
51
+ status: canonicalStatusFromStateType(linearIssue.stateType),
85
52
  repository: linearIssue.repository,
86
53
  model: linearIssue.model,
87
54
  assignee: linearIssue.assignee,
88
55
  updatedAt: linearIssue.updatedAt,
89
- blockers: linearIssue.blockers.map((b) => toCanonicalBlocker(b, globalConfig, sourceName)),
56
+ blockers: linearIssue.blockers.map((b) => toCanonicalBlocker(b, sourceName)),
90
57
  hasMoreBlockers: linearIssue.hasMoreBlockers,
91
58
  sourceRef,
92
59
  };
@@ -96,7 +63,7 @@ export function createLinearTicketSource(config, context) {
96
63
  const { globalConfig } = context;
97
64
  const client = getLinearClient();
98
65
  const boardSource = createBoardSource({ config: globalConfig, client });
99
- const issueStatusUpdater = createLinearIssueStatusUpdater({ config: globalConfig, client });
66
+ const issueStatusUpdater = createLinearIssueStatusUpdater({ client });
100
67
  return {
101
68
  name: sourceName,
102
69
  async verify() {
@@ -104,23 +71,18 @@ export function createLinearTicketSource(config, context) {
104
71
  },
105
72
  async fetch() {
106
73
  const state = await boardSource.fetch();
107
- return state.issues.map((linearIssue) => toCanonicalIssue(linearIssue, globalConfig, sourceName));
74
+ return state.issues.map((linearIssue) => toCanonicalIssue(linearIssue, sourceName));
108
75
  },
109
76
  async resolveOne(naturalId) {
110
- // fetchResolvedIssue throws on unknown project / missing repo; we let
111
- // those propagate. Returning `undefined` is reserved for "ticket genuinely
112
- // doesn't exist," which fetchResolvedIssue surfaces as an Error too —
113
- // for now we let any error bubble up rather than swallow.
77
+ // fetchResolvedIssue throws on missing repo; we let those propagate.
78
+ // Returning `undefined` is reserved for "ticket genuinely doesn't
79
+ // exist," which fetchResolvedIssue surfaces as an Error too — for now
80
+ // we let any error bubble up rather than swallow.
114
81
  const resolved = await fetchResolvedIssue({
115
82
  client,
116
83
  config: globalConfig,
117
84
  ticket: naturalId,
118
85
  });
119
- const project = findProjectBySlugId(globalConfig, resolved.projectSlugId);
120
- /* v8 ignore next 5 @preserve -- fetchResolvedIssue already throws UnknownProjectError before reaching this guard */
121
- if (project === undefined) {
122
- throw new Error(`Linear adapter: resolved issue ${naturalId} carries unknown projectSlugId "${resolved.projectSlugId}"`);
123
- }
124
86
  // fetchResolvedIssue doesn't return the native status name (it's
125
87
  // already been resolved through workflow state lookup). We surface
126
88
  // "other" until the consumer needs the canonical status, which is fine
@@ -129,7 +91,6 @@ export function createLinearTicketSource(config, context) {
129
91
  uuid: resolved.uuid,
130
92
  statusId: "",
131
93
  teamId: resolved.teamId,
132
- projectSlugId: resolved.projectSlugId,
133
94
  nativeStatus: "",
134
95
  };
135
96
  return {
@@ -154,7 +115,6 @@ export function createLinearTicketSource(config, context) {
154
115
  id: issue.id,
155
116
  uuid: ref.uuid,
156
117
  teamId: ref.teamId,
157
- projectSlugId: ref.projectSlugId,
158
118
  });
159
119
  },
160
120
  };