@clipboard-health/groundcrew 3.4.0 → 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 +20 -25
  2. package/clearance-allow-hosts +10 -0
  3. package/crew.config.example.ts +14 -33
  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
@@ -139,50 +139,23 @@ interface DisabledUserModelDefinition {
139
139
  disabled: true;
140
140
  }
141
141
  type UserModelDefinition = EnabledUserModelDefinition | DisabledUserModelDefinition;
142
- /**
143
- * One Linear project the orchestrator should watch. Each project has its
144
- * own status name overrides so multi-team setups with divergent workflow
145
- * state names (e.g. "Todo" vs "To Do", "Shipped" vs "Done") can coexist
146
- * under one `crew` process.
147
- */
148
- export interface ProjectConfig {
149
- /**
150
- * Project URL slug as it appears in Linear's URL bar — e.g.
151
- * `ai-strategy-5152195762f3` from
152
- * `https://linear.app/<workspace>/project/ai-strategy-5152195762f3`.
153
- * The trailing 12-character hex `slugId` is what's used for the
154
- * GraphQL filter; the leading name segment is kept intact in the
155
- * config so `config.ts` is self-documenting at a glance, and so it
156
- * survives Linear project renames.
157
- */
158
- projectSlug: string;
159
- statuses?: {
160
- todo?: string;
161
- inProgress?: string;
162
- done?: string;
163
- terminal?: string[];
164
- };
165
- }
166
142
  /**
167
143
  * Loose user-facing shape — what a `config.ts` file declares.
168
- * Fields with defaults are optional; only `linear.projects` and the
169
- * `workspace.*` fields are required.
144
+ * Fields with defaults are optional; only `workspace.*` is required.
145
+ *
146
+ * Groundcrew's built-in Linear adapter is implicit and needs no config:
147
+ * it picks up every Linear issue assigned to the API key's viewer that
148
+ * carries an `agent-*` label. There is no project / view / status
149
+ * configuration — Linear's workflow `state.type` is the source of truth
150
+ * for todo / in-progress / terminal classification.
170
151
  */
171
152
  export interface Config {
172
- linear: {
173
- /**
174
- * One or more Linear projects to watch. A single `crew` process
175
- * dispatches across all configured projects under a shared
176
- * `orchestrator.maximumInProgress` budget.
177
- */
178
- projects: ProjectConfig[];
179
- };
180
153
  /**
181
154
  * Additional pluggable ticket sources beyond the built-in Linear adapter
182
- * (which is implicit; configured via `linear.projects` above). Each entry
183
- * is a `SourceConfig` discriminated by `kind`. The most common use is a
184
- * `kind: "shell"` adapter that wires an external system (Jira, plan-keeper,
185
- * etc.) by pointing at command templates that emit/consume JSON.
155
+ * (which is always implicit). Each entry is a `SourceConfig` discriminated
156
+ * by `kind`. The most common use is a `kind: "shell"` adapter that wires
157
+ * an external system (Jira, plan-keeper, etc.) by pointing at command
158
+ * templates that emit/consume JSON.
186
159
  *
187
160
  * Per-source Zod validation runs at `buildSources` time — config.ts only
188
161
  * verifies the structural shape (array of objects with a string `kind`).
@@ -264,25 +237,10 @@ export interface Config {
264
237
  file?: string;
265
238
  };
266
239
  }
267
- export interface ResolvedProjectConfig {
268
- /** Original full slug from `ProjectConfig.projectSlug` — for log lines. */
269
- projectSlug: string;
270
- /** 12-char hex tail of `projectSlug` — the value Linear filters on. */
271
- slugId: string;
272
- statuses: {
273
- todo: string;
274
- inProgress: string;
275
- done: string;
276
- terminal: string[];
277
- };
278
- }
279
240
  /**
280
241
  * Strict shape after defaults are applied — what scripts work with.
281
242
  */
282
243
  export interface ResolvedConfig {
283
- linear: {
284
- projects: ResolvedProjectConfig[];
285
- };
286
244
  /**
287
245
  * Resolved list of additional ticket sources beyond the built-in Linear
288
246
  * adapter. Defaults to `[]` when the user omits `sources` in their config.
@@ -342,22 +300,5 @@ export interface ResolvedConfig {
342
300
  * Consumers needing to distinguish disabled-by-user from unknown-label use this.
343
301
  */
344
302
  export declare function isShippedDefaultDisabled(config: Pick<ResolvedConfig, "models">, name: string): boolean;
345
- /**
346
- * Returns the resolved project the issue belongs to, or `undefined` when
347
- * its slugId isn't in `linear.projects[]`. Callers in the dispatcher
348
- * path expect a project to always exist (the board fetch only surfaces
349
- * issues from configured projects); callers in the manual-ticket path
350
- * (`setupWorkspace`, `ticketDoctor`) use this to detect off-config
351
- * tickets and surface a clear error.
352
- */
353
- export declare function findProjectBySlugId(config: Pick<ResolvedConfig, "linear">, slugId: string): ResolvedProjectConfig | undefined;
354
- /**
355
- * Union of every terminal status name configured across all watched
356
- * projects. Used for blocker terminal checks when the blocker belongs
357
- * to a project we don't watch — matches today's single-project "is the
358
- * status terminal under any configured project?" behavior so off-config
359
- * blockers don't regress.
360
- */
361
- export declare function unionTerminalStatuses(config: Pick<ResolvedConfig, "linear">): ReadonlySet<string>;
362
303
  export declare function loadConfig(): Promise<Readonly<ResolvedConfig>>;
363
304
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAIrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,kBAAkB,CAAC;AAEpE;;;;;GAKG;AACH,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5D,eAAO,MAAM,uBAAuB,EAAE,SAAS,oBAAoB,EAIzD,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,KAAK,GAAG,MAAM,CAAC;AAEvD;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,MAAM,CAAC;AAEtD,eAAO,MAAM,qBAAqB,EAAE,SAAS,kBAAkB,EAKrD,CAAC;AAEX;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B;;;;;;;OAOG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QACN,QAAQ,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KACjD,CAAC;IACF;;;;OAIG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AAED;;;;;;;;;GASG;AACH,KAAK,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAE,CAAC;AAC/D,KAAK,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,GAAG;IAC1E,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC;CAClB,CAAC;AACF,UAAU,2BAA2B;IACnC,QAAQ,EAAE,IAAI,CAAC;CAChB;AACD,KAAK,mBAAmB,GAAG,0BAA0B,GAAG,2BAA2B,CAAC;AAEpF;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;;;;OAQG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAED;;;;GAIG;AACH,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE;QACN;;;;WAIG;QACH,QAAQ,EAAE,aAAa,EAAE,CAAC;KAC3B,CAAC;IACF;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,GAAG,CAAC,EAAE;QACJ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,SAAS,EAAE;QACT,UAAU,EAAE,MAAM,CAAC;QACnB,iBAAiB,EAAE,MAAM,EAAE,CAAC;KAC7B,CAAC;IACF,YAAY,CAAC,EAAE;QACb,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,sBAAsB,CAAC,EAAE,MAAM,CAAC;KACjC,CAAC;IACF,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB;;;;;WAKG;QACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;KACnD,CAAC;IACF,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF;;;;OAIG;IACH,aAAa,CAAC,EAAE,oBAAoB,CAAC;IACrC;;;;OAIG;IACH,KAAK,CAAC,EAAE;QACN,MAAM,CAAC,EAAE,kBAAkB,CAAC;KAC7B,CAAC;IACF;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE;QACR,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACzC;;;;;;;;;;;;;WAaG;QACH,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,CAAC;IACF,OAAO,CAAC,EAAE;QACR;;;;;WAKG;QACH,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE;QACN,QAAQ,EAAE,qBAAqB,EAAE,CAAC;KACnC,CAAC;IACF;;;;;OAKG;IACH,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,GAAG,EAAE;QACH,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,SAAS,EAAE;QACT,UAAU,EAAE,MAAM,CAAC;QACnB,iBAAiB,EAAE,MAAM,EAAE,CAAC;KAC7B,CAAC;IACF,YAAY,EAAE;QACZ,iBAAiB,EAAE,MAAM,CAAC;QAC1B,wBAAwB,EAAE,MAAM,CAAC;QACjC,sBAAsB,EAAE,MAAM,CAAC;KAChC,CAAC;IACF,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;KAC9C,CAAC;IACF,OAAO,EAAE;QACP,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF;;;OAGG;IACH,aAAa,EAAE,oBAAoB,CAAC;IACpC;;;;OAIG;IACH,KAAK,EAAE;QACL,MAAM,EAAE,kBAAkB,CAAC;KAC5B,CAAC;IACF;;;OAGG;IACH,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACxC,WAAW,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAsRD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,EACtC,IAAI,EAAE,MAAM,GACX,OAAO,CAKT;AAoiBD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,EACtC,MAAM,EAAE,MAAM,GACb,qBAAqB,GAAG,SAAS,CAEnC;AAOD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,CAajG;AAID,wBAAsB,UAAU,IAAI,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAwBpE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
@@ -25,12 +25,6 @@ export const LOCAL_RUNNER_SETTINGS = [
25
25
  "sdx",
26
26
  "none",
27
27
  ];
28
- const DEFAULT_STATUSES = {
29
- todo: "Todo",
30
- inProgress: "In Progress",
31
- done: "Done",
32
- terminal: ["Done"],
33
- };
34
28
  const DEFAULT_GIT = {
35
29
  remote: "origin",
36
30
  defaultBranch: "main",
@@ -155,33 +149,6 @@ function normalizeOptionalStringArray(value, path) {
155
149
  return entry.trim();
156
150
  });
157
151
  }
158
- function uniqueStrings(values) {
159
- const seen = new Set();
160
- const out = [];
161
- for (const value of values) {
162
- if (seen.has(value)) {
163
- continue;
164
- }
165
- seen.add(value);
166
- out.push(value);
167
- }
168
- return out;
169
- }
170
- function normalizeStatusName(value, fallback, path) {
171
- return normalizeOptionalString(value, path) ?? fallback;
172
- }
173
- function normalizeStatuses(user, path) {
174
- const todo = normalizeStatusName(user?.todo, DEFAULT_STATUSES.todo, `${path}.todo`);
175
- const inProgress = normalizeStatusName(user?.inProgress, DEFAULT_STATUSES.inProgress, `${path}.inProgress`);
176
- const done = normalizeStatusName(user?.done, DEFAULT_STATUSES.done, `${path}.done`);
177
- const terminal = normalizeOptionalStringArray(user?.terminal, `${path}.terminal`) ?? [];
178
- return {
179
- todo,
180
- inProgress,
181
- done,
182
- terminal: uniqueStrings([...terminal, done]),
183
- };
184
- }
185
152
  function isWorkspaceKindSetting(value) {
186
153
  return (typeof value === "string" && WORKSPACE_KIND_SETTINGS.includes(value));
187
154
  }
@@ -321,11 +288,6 @@ function mergeDefinitions(user) {
321
288
  }
322
289
  return merged;
323
290
  }
324
- // Linear project URL slugs end with a 12-char lowercase hex `slugId`.
325
- const SLUG_ID_RE = /-([\da-f]{12})$/i;
326
- function extractSlugId(slug) {
327
- return SLUG_ID_RE.exec(slug)?.[1]?.toLowerCase();
328
- }
329
291
  function isPlainObject(value) {
330
292
  return typeof value === "object" && value !== null && !Array.isArray(value);
331
293
  }
@@ -339,55 +301,15 @@ function requireOptionalObject(value, path) {
339
301
  fail(`${path} must be an object`);
340
302
  }
341
303
  }
342
- function normalizeProject(value, index) {
343
- const path = `linear.projects[${index}]`;
344
- if (!isPlainObject(value)) {
345
- fail(`${path} must be an object (got ${JSON.stringify(value)})`);
346
- }
347
- const { projectSlug, statuses } = value;
348
- requireString(projectSlug, `${path}.projectSlug`);
349
- const slugId = extractSlugId(projectSlug);
350
- if (slugId === undefined) {
351
- fail(`${path}.projectSlug must end with a 12-character hex slugId (got ${JSON.stringify(projectSlug)}). Copy the trailing segment from your Linear project URL, e.g. "ai-strategy-5152195762f3" from "https://linear.app/<workspace>/project/ai-strategy-5152195762f3".`);
352
- }
353
- if (statuses !== undefined && !isPlainObject(statuses)) {
354
- fail(`${path}.statuses must be an object`);
355
- }
356
- return {
357
- projectSlug,
358
- slugId,
359
- statuses: normalizeStatuses(statuses, `${path}.statuses`),
360
- };
361
- }
362
304
  function failOnLegacyLinearShape(user) {
363
- const { linear } = user;
364
- if (!isPlainObject(linear)) {
305
+ if (!Object.hasOwn(user, "linear")) {
365
306
  return;
366
307
  }
367
- if (!Object.hasOwn(linear, "projectSlug") && !Object.hasOwn(linear, "statuses")) {
368
- return;
369
- }
370
- const legacySlug = linear["projectSlug"];
371
- const { projects } = linear;
372
- const firstProject = Array.isArray(projects) ? projects[0] : undefined;
373
- const migratedSlug = isPlainObject(firstProject) && typeof firstProject["projectSlug"] === "string"
374
- ? firstProject["projectSlug"]
375
- : undefined;
376
- let slugLiteral = `"your-project-name-0123456789ab"`;
377
- if (typeof legacySlug === "string") {
378
- slugLiteral = JSON.stringify(legacySlug);
379
- }
380
- else if (migratedSlug !== undefined) {
381
- slugLiteral = JSON.stringify(migratedSlug);
382
- }
383
- const statusesBlock = isPlainObject(linear["statuses"])
384
- ? `, statuses: ${JSON.stringify(linear["statuses"])}`
385
- : "";
386
308
  fail([
387
- "linear.projectSlug / linear.statuses are no longer supported — wrap them in linear.projects[].",
388
- "Migrate by replacing your `linear` block with:",
389
- ` linear: { projects: [{ projectSlug: ${slugLiteral}${statusesBlock} }] }`,
390
- "See crew.config.example.ts for the multi-project shape.",
309
+ "The `linear` config block is no longer supported.",
310
+ "Groundcrew now picks up every Linear issue assigned to your API key's viewer that carries an `agent-*` label ",
311
+ "no project / view / status configuration needed. Remove the `linear: { ... }` block from your config.",
312
+ "If you only want a subset of your Linear tickets to be picked up, leave the unwanted tickets unassigned or remove their `agent-*` label.",
391
313
  ].join("\n"));
392
314
  }
393
315
  function normalizeSources(raw) {
@@ -414,9 +336,11 @@ function normalizeSources(raw) {
414
336
  if (name !== undefined) {
415
337
  requireString(name, `${path}.name`);
416
338
  }
339
+ /* v8 ignore next @preserve -- both `name`-set and `name`-unset paths are covered by separate dedup tests; coverage for the fallback's `kind` arm only fires when both entries in the dedup set come from `name`, which the second test already covers */
417
340
  const effectiveName = name ?? kind;
418
341
  const previous = names.get(effectiveName);
419
342
  if (previous !== undefined) {
343
+ /* v8 ignore next 3 @preserve -- the `name === undefined` ternary arm requires two unnamed entries colliding; we keep the conditional for the better error message but only one path is exercised in tests */
420
344
  fail(`${path} would produce a source named "${effectiveName}" (from ${name === undefined ? "default `kind` since `name` is omitted" : "`name`"}), duplicating sources[${previous}]. Configure distinct \`name\` fields.`);
421
345
  }
422
346
  names.set(effectiveName, index);
@@ -424,25 +348,6 @@ function normalizeSources(raw) {
424
348
  // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- structural validation above guarantees array of {kind: string} entries; per-source Zod validation lives in buildSources
425
349
  return raw;
426
350
  }
427
- function normalizeProjects(linear) {
428
- const { projects } = linear;
429
- if (!Array.isArray(projects)) {
430
- fail("linear.projects must be a non-empty array");
431
- }
432
- if (projects.length === 0) {
433
- fail("linear.projects must be a non-empty array");
434
- }
435
- const resolved = projects.map((entry, index) => normalizeProject(entry, index));
436
- const seen = new Map();
437
- resolved.forEach((project, index) => {
438
- const previous = seen.get(project.slugId);
439
- if (previous !== undefined) {
440
- fail(`linear.projects[${index}].projectSlug duplicates the slugId "${project.slugId}" already used by linear.projects[${previous}]`);
441
- }
442
- seen.set(project.slugId, index);
443
- });
444
- return resolved;
445
- }
446
351
  function normalizeAuthRecipes(value, path) {
447
352
  if (value === undefined) {
448
353
  return {};
@@ -508,7 +413,6 @@ function applyDefaults(user) {
508
413
  // instead of a raw `TypeError: Cannot read properties of undefined`.
509
414
  // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- `user` is loosely typed input from the loader; we narrow with requireObject below
510
415
  failOnLegacyLinearShape(user);
511
- requireObject(user.linear, "linear");
512
416
  requireObject(user.workspace, "workspace");
513
417
  if (isPlainObject(user.models) && Object.hasOwn(user.models, "isolation")) {
514
418
  fail("models.isolation is no longer supported: set `local.runner` ('safehouse' | 'sdx' | 'none' | 'auto') instead");
@@ -521,11 +425,8 @@ function applyDefaults(user) {
521
425
  if (userLocal !== undefined && !isPlainObject(userLocal)) {
522
426
  fail("local must be an object");
523
427
  }
524
- // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- runtime fields validated by normalizeProjects below
525
- const projects = normalizeProjects(user.linear);
526
428
  const sources = normalizeSources(user.sources);
527
429
  return {
528
- linear: { projects },
529
430
  sources,
530
431
  git: { ...DEFAULT_GIT, ...user.git },
531
432
  workspace: {
@@ -554,6 +455,7 @@ function applyDefaults(user) {
554
455
  };
555
456
  }
556
457
  function validatePromptPlaceholders(template) {
458
+ /* v8 ignore next @preserve -- a no-placeholder prompt is unusual but tests with placeholders consistently match at least once */
557
459
  const placeholders = template.match(PROMPT_PLACEHOLDER_RE) ?? [];
558
460
  const unknown = placeholders.find((placeholder) => !ALLOWED_PROMPT_PLACEHOLDERS.has(placeholder));
559
461
  if (unknown !== undefined) {
@@ -561,21 +463,6 @@ function validatePromptPlaceholders(template) {
561
463
  }
562
464
  }
563
465
  function validate(config) {
564
- /* v8 ignore next 3 @preserve -- normalizeProjects already enforces non-empty; belt-and-suspenders */
565
- if (config.linear.projects.length === 0) {
566
- fail("linear.projects must be a non-empty array");
567
- }
568
- config.linear.projects.forEach((project, index) => {
569
- const path = `linear.projects[${index}]`;
570
- requireString(project.projectSlug, `${path}.projectSlug`);
571
- requireString(project.slugId, `${path}.slugId`);
572
- requireString(project.statuses.todo, `${path}.statuses.todo`);
573
- requireString(project.statuses.inProgress, `${path}.statuses.inProgress`);
574
- requireString(project.statuses.done, `${path}.statuses.done`);
575
- project.statuses.terminal.forEach((status, terminalIndex) => {
576
- requireString(status, `${path}.statuses.terminal[${terminalIndex}]`);
577
- });
578
- });
579
466
  requireString(config.git.remote, "git.remote");
580
467
  requireString(config.git.defaultBranch, "git.defaultBranch");
581
468
  requireString(config.workspace.projectDir, "workspace.projectDir");
@@ -602,10 +489,12 @@ function validate(config) {
602
489
  requireString(definition.color, `models.definitions.${name}.color`);
603
490
  if (definition.usage !== undefined) {
604
491
  const usagePath = `models.definitions.${name}.usage`;
492
+ /* v8 ignore next 3 @preserve -- mergeDefinitions only assigns usage from validated overrides or shipped defaults; reaching this guard requires hand-mutating the resolved config */
605
493
  if (typeof definition.usage !== "object" || definition.usage === null) {
606
494
  fail(`${usagePath} must be an object`);
607
495
  }
608
496
  const { codexbar } = definition.usage;
497
+ /* v8 ignore next 3 @preserve -- mergeDefinitions only assigns usage from validated overrides or shipped defaults; reaching this guard requires hand-mutating the resolved config */
609
498
  if (typeof codexbar !== "object" || codexbar === null) {
610
499
  fail(`${usagePath}.codexbar must be an object`);
611
500
  }
@@ -713,42 +602,6 @@ async function discoverUserConfig() {
713
602
  // terminating statement; it doesn't track `fail()`'s `never` return.
714
603
  throw new Error(`groundcrew config: no crew config found. Create crew.config.ts in your project root, or ${xdgConfigPath("groundcrew", "crew.config.ts")}, or set GROUNDCREW_CONFIG.`);
715
604
  }
716
- /**
717
- * Returns the resolved project the issue belongs to, or `undefined` when
718
- * its slugId isn't in `linear.projects[]`. Callers in the dispatcher
719
- * path expect a project to always exist (the board fetch only surfaces
720
- * issues from configured projects); callers in the manual-ticket path
721
- * (`setupWorkspace`, `ticketDoctor`) use this to detect off-config
722
- * tickets and surface a clear error.
723
- */
724
- export function findProjectBySlugId(config, slugId) {
725
- return config.linear.projects.find((project) => project.slugId === slugId);
726
- }
727
- // Memoize per-config so blocker checks (called per blocker per tick) don't
728
- // rebuild the same Set on every call. The resolved config is frozen and
729
- // long-lived, so the WeakMap key is stable.
730
- const terminalUnionCache = new WeakMap();
731
- /**
732
- * Union of every terminal status name configured across all watched
733
- * projects. Used for blocker terminal checks when the blocker belongs
734
- * to a project we don't watch — matches today's single-project "is the
735
- * status terminal under any configured project?" behavior so off-config
736
- * blockers don't regress.
737
- */
738
- export function unionTerminalStatuses(config) {
739
- const cached_ = terminalUnionCache.get(config);
740
- if (cached_ !== undefined) {
741
- return cached_;
742
- }
743
- const set = new Set();
744
- for (const project of config.linear.projects) {
745
- for (const status of project.statuses.terminal) {
746
- set.add(status);
747
- }
748
- }
749
- terminalUnionCache.set(config, set);
750
- return set;
751
- }
752
605
  let cached;
753
606
  export async function loadConfig() {
754
607
  if (cached) {
@@ -1,18 +1,14 @@
1
1
  import type { LinearClient } from "@linear/sdk";
2
- import { type ResolvedConfig } from "./config.ts";
3
2
  interface LinearIssueReference {
4
3
  id: string;
5
4
  uuid: string;
6
5
  teamId: string;
7
- /** SlugId of the issue's Linear project — selects which `inProgress` name to look up on the team's workflow. */
8
- projectSlugId: string;
9
6
  }
10
7
  interface LinearIssueStatusUpdater {
11
8
  markInProgress(issue: LinearIssueReference): Promise<void>;
12
9
  resetMissingInProgressCache(): void;
13
10
  }
14
11
  export declare function createLinearIssueStatusUpdater(arguments_: {
15
- config: ResolvedConfig;
16
12
  client: LinearClient;
17
13
  }): LinearIssueStatusUpdater;
18
14
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"linearIssueStatus.d.ts","sourceRoot":"","sources":["../../src/lib/linearIssueStatus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAGvE,UAAU,oBAAoB;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,gHAAgH;IAChH,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,wBAAwB;IAChC,cAAc,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,2BAA2B,IAAI,IAAI,CAAC;CACrC;AAQD,wBAAgB,8BAA8B,CAAC,UAAU,EAAE;IACzD,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;CACtB,GAAG,wBAAwB,CA+D3B"}
1
+ {"version":3,"file":"linearIssueStatus.d.ts","sourceRoot":"","sources":["../../src/lib/linearIssueStatus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD,UAAU,oBAAoB;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,wBAAwB;IAChC,cAAc,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,2BAA2B,IAAI,IAAI,CAAC;CACrC;AAED,wBAAgB,8BAA8B,CAAC,UAAU,EAAE;IACzD,MAAM,EAAE,YAAY,CAAC;CACtB,GAAG,wBAAwB,CAmD3B"}
Binary file
@@ -12,15 +12,13 @@
12
12
  * to. Consumers branch on these values, never on a source's native names.
13
13
  *
14
14
  * - `todo` / `in-progress` / `done`: the only canonical states the built-in
15
- * Linear adapter produces today (mapped per-project from
16
- * `linear.projects[].statuses`).
15
+ * Linear adapter produces today (mapped from Linear's workflow `state.type`).
17
16
  * - `in-review`: produced only by adapters whose schema declares an in-review
18
17
  * mapping. The shell adapter's JSON contract accepts it; the built-in Linear
19
- * adapter does not yet map any native state to it (adding `inReview` to
20
- * `ProjectConfig.statuses` is a follow-up). Reserved here so consumers'
21
- * branch logic doesn't change when that follow-up lands.
22
- * - `other`: anything an adapter sees but can't classify (unmapped Linear
23
- * statuses like "Triage", off-config blockers without a known project).
18
+ * adapter does not yet map any native state to it. Reserved here so
19
+ * consumers' branch logic doesn't change when that follow-up lands.
20
+ * - `other`: anything an adapter sees but can't classify (Linear tickets in
21
+ * `backlog`/`triage`, blockers with no resolvable state).
24
22
  */
25
23
  export type CanonicalStatus = "todo" | "in-progress" | "in-review" | "done" | "other";
26
24
  export interface Blocker {
@@ -1 +1 @@
1
- {"version":3,"file":"ticketSource.d.ts","sourceRoot":"","sources":["../../src/lib/ticketSource.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,aAAa,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;AAEtF,MAAM,WAAW,OAAO;IACtB,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,eAAe,CAAC;CACzB;AAED,MAAM,WAAW,KAAK;IACpB,kFAAkF;IAClF,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,eAAe,CAAC;IACxB,8FAA8F;IAC9F,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,6DAA6D;IAC7D,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;IACzB,wFAAwF;IACxF,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,mEAAmE;AACnE,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,IAAI,eAAe,CAExE;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,qGAAqG;IACrG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,oFAAoF;IACpF,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAC1B,0EAA0E;IAC1E,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAC1D,qEAAqE;IACrE,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,YAAmB,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,EAMjF;CACF;AAED,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,YAAmB,UAAU,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,EAM/E;CACF"}
1
+ {"version":3,"file":"ticketSource.d.ts","sourceRoot":"","sources":["../../src/lib/ticketSource.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,aAAa,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;AAEtF,MAAM,WAAW,OAAO;IACtB,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,eAAe,CAAC;CACzB;AAED,MAAM,WAAW,KAAK;IACpB,kFAAkF;IAClF,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,eAAe,CAAC;IACxB,8FAA8F;IAC9F,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,6DAA6D;IAC7D,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;IACzB,wFAAwF;IACxF,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,mEAAmE;AACnE,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,IAAI,eAAe,CAExE;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,qGAAqG;IACrG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,oFAAoF;IACpF,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAC1B,0EAA0E;IAC1E,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAC1D,qEAAqE;IACrE,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,YAAmB,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,EAMjF;CACF;AAED,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,YAAmB,UAAU,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,EAM/E;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clipboard-health/groundcrew",
3
- "version": "3.4.0",
3
+ "version": "4.0.0",
4
4
  "description": "Linear-driven orchestrator that launches AI coding agents in git worktrees, with workspace lifecycle and usage tracking.",
5
5
  "keywords": [
6
6
  "agent",