@clipboard-health/groundcrew 4.35.0 → 4.35.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.
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAyLH,wBAAsB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,CAmF/C"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAuQH,wBAAsB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,CAmF/C"}
@@ -3,12 +3,12 @@
3
3
  * Returns true if every required check passes; false otherwise.
4
4
  */
5
5
  import { existsSync, statSync } from "node:fs";
6
- import { createBoard } from "../lib/board.js";
7
6
  import { buildSources, sourcesFromConfig } from "../lib/buildSources.js";
8
7
  import { loadConfigWithSource, worktreeBaseDir, } from "../lib/config.js";
9
8
  import { detectHostCapabilities, which } from "../lib/host.js";
10
9
  import { isEnvironmentAssignment } from "../lib/launchCommand.js";
11
10
  import { resolveLocalRunner } from "../lib/localRunner.js";
11
+ import { naturalIdFromCanonical } from "../lib/taskSource.js";
12
12
  import { gatedAgents } from "../lib/usage.js";
13
13
  import { errorMessage, writeOutput } from "../lib/util.js";
14
14
  import { resolveWorkspaceKind } from "../lib/workspaces.js";
@@ -34,27 +34,97 @@ async function checkCmd(cmd, required, hint) {
34
34
  }
35
35
  return result;
36
36
  }
37
+ function isRecord(value) {
38
+ return typeof value === "object" && value !== null;
39
+ }
37
40
  /**
38
- * Source-agnostic reachability check: build every configured task source
39
- * and run the Board's `verify()` fan-out. Replaces the old Linear-only
40
- * "api key + reachability" probe so a misconfigured shell (or future Jira)
41
- * source surfaces here too. A missing Linear API key still fails verify with
42
- * its own user-facing message, so the prior behavior is preserved.
41
+ * True when a raw source config entry declares `kind: "shell"`. Gates the
42
+ * shell-only read probe.
43
43
  */
44
- async function checkSourceProbe(config) {
44
+ function isShellSource(raw) {
45
+ if (!isRecord(raw)) {
46
+ return false;
47
+ }
48
+ const { kind } = raw;
49
+ return kind === "shell";
50
+ }
51
+ function hasExplicitGetTaskCommand(raw) {
52
+ const { commands } = raw;
53
+ if (!isRecord(commands)) {
54
+ return false;
55
+ }
56
+ const { getTask, resolveOne } = commands;
57
+ return typeof getTask === "string" || typeof resolveOne === "string";
58
+ }
59
+ function shellReadProbeFor(raw) {
60
+ if (!isShellSource(raw)) {
61
+ return "none";
62
+ }
63
+ return hasExplicitGetTaskCommand(raw) ? "listTasksAndGetTask" : "listTasks";
64
+ }
65
+ /**
66
+ * Probe each configured task source independently and emit one `Check` per
67
+ * source (named `source: <name>`), so a single broken source is attributable
68
+ * instead of hidden behind an aggregate "N source(s) verified" line.
69
+ *
70
+ * Every source runs its `verify()`. Shell sources are additionally deep-probed
71
+ * via `listTasks()`: their `verify` command can discard stdout (e.g.
72
+ * `... fetch >/dev/null`), so a malformed task payload sails through verify and
73
+ * only blows up later in `crew run`. Running listTasks here surfaces a
74
+ * wrong-shape payload (a `TaskSourceOutputError` with a readable message) at
75
+ * doctor time. Non-shell sources (Linear) are left to `verify()` alone — their
76
+ * fetch is an expensive network call that verify already exercises.
77
+ */
78
+ async function checkSourceProbes(config) {
79
+ const rawSources = sourcesFromConfig(config);
80
+ let sources;
45
81
  try {
46
- const sources = await buildSources(sourcesFromConfig(config), { globalConfig: config });
47
- const board = createBoard(sources);
48
- await board.verify();
49
- return {
50
- name: "source probe",
51
- ok: true,
52
- required: true,
53
- hint: `${sources.length} source(s) verified`,
54
- };
82
+ sources = await buildSources(rawSources, { globalConfig: config });
83
+ }
84
+ catch (error) {
85
+ // Building sources failed before any individual probe (bad config / unknown
86
+ // kind). Surface it as a single failed check rather than per-source.
87
+ return [{ name: "sources", ok: false, required: true, hint: errorMessage(error) }];
88
+ }
89
+ if (sources.length === 0) {
90
+ return [{ name: "sources", ok: false, required: true, hint: "no task sources configured" }];
91
+ }
92
+ const checks = [];
93
+ for (const [index, source] of sources.entries()) {
94
+ const shellReadProbe = shellReadProbeFor(rawSources[index]);
95
+ // oxlint-disable-next-line no-await-in-loop -- sequential keeps each verdict attributable to one source
96
+ checks.push(await probeSource(source, shellReadProbe));
97
+ }
98
+ return checks;
99
+ }
100
+ async function probeSource(source, shellReadProbe) {
101
+ const name = `source: ${source.name}`;
102
+ try {
103
+ await source.verify();
104
+ if (shellReadProbe === "none") {
105
+ return { name, ok: true, required: true, hint: "verified" };
106
+ }
107
+ const tasks = await source.listTasks();
108
+ const parts = [`fetched ${tasks.length} task(s)`];
109
+ // Read-path symmetry: an id listTasks emitted must resolve via getTask.
110
+ // Skipped when getTask is only the adapter's listTasks fallback, since that
111
+ // would just re-run listTasks and can race changing source output.
112
+ const [first] = tasks;
113
+ if (first !== undefined && shellReadProbe === "listTasksAndGetTask") {
114
+ const naturalId = naturalIdFromCanonical(first.id);
115
+ const resolved = await source.getTask(naturalId);
116
+ if (resolved === null) {
117
+ throw new Error(`getTask("${naturalId}") returned nothing, but listTasks emitted it`);
118
+ }
119
+ if (resolved.id !== first.id) {
120
+ throw new Error(`getTask("${naturalId}") resolved "${resolved.id}", but listTasks emitted "${first.id}"`);
121
+ }
122
+ parts.push("getTask round-trips");
123
+ }
124
+ return { name, ok: true, required: true, hint: `verified; ${parts.join("; ")}` };
55
125
  }
56
126
  catch (error) {
57
- return { name: "source probe", ok: false, required: true, hint: errorMessage(error) };
127
+ return { name, ok: false, required: true, hint: errorMessage(error) };
58
128
  }
59
129
  }
60
130
  function checkDir(path, label) {
@@ -190,7 +260,7 @@ export async function doctor() {
190
260
  const workspaceOutcome = resolveWorkspaceOutcome(config, host);
191
261
  reportWorkspaceKind(config, workspaceOutcome);
192
262
  const checks = [
193
- await checkSourceProbe(config),
263
+ ...(await checkSourceProbes(config)),
194
264
  await checkCmd("git", true, "https://git-scm.com/"),
195
265
  ...(await workspaceChecks(workspaceOutcome)),
196
266
  checkDir(config.workspace.projectDir, "workspace.projectDir"),
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/commands/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA2DH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;CACjB;AAiBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgE7E"}
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/commands/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoEH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;CACjB;AAiBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgE7E"}
@@ -8,7 +8,7 @@ import { createBoard } from "../lib/board.js";
8
8
  import { buildSources, sourcesFromConfig } from "../lib/buildSources.js";
9
9
  import { loadConfigWithSource } from "../lib/config.js";
10
10
  import { findPullRequestsForBranch } from "../lib/pullRequests.js";
11
- import { RepositoryResolutionError } from "../lib/taskSource.js";
11
+ import { RepositoryResolutionError, TaskSourceOutputError, } from "../lib/taskSource.js";
12
12
  import { getUsageByAgent } from "../lib/usage.js";
13
13
  import { errorMessage, log, sleep, writeOutput } from "../lib/util.js";
14
14
  import { worktrees } from "../lib/worktrees.js";
@@ -30,6 +30,11 @@ async function withRetry(function_, signal, maxRetries = RETRY_MAX_ATTEMPTS, bas
30
30
  if (error instanceof RepositoryResolutionError) {
31
31
  throw error;
32
32
  }
33
+ // A source returned unparseable output — deterministic, so retrying just
34
+ // delays a guaranteed failure behind confusing "Retrying in Ns" lines.
35
+ if (error instanceof TaskSourceOutputError) {
36
+ throw error;
37
+ }
33
38
  if (attempt === maxRetries) {
34
39
  throw error;
35
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/shell/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAIL,KAAK,KAAK,IAAI,cAAc,EAG5B,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EACL,KAAK,kBAAkB,EAEvB,KAAK,UAAU,EAGhB,MAAM,aAAa,CAAC;AAyErB,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,CAuB3F;AA8BD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,cAAc,GACvB,UAAU,CA6LZ"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/shell/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAIL,KAAK,KAAK,IAAI,cAAc,EAG5B,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EACL,KAAK,kBAAkB,EAEvB,KAAK,UAAU,EAGhB,MAAM,aAAa,CAAC;AAyErB,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,CAuB3F;AA8BD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,cAAc,GACvB,UAAU,CAsMZ"}
@@ -22,6 +22,7 @@
22
22
  import { toCanonicalId, } from "../../taskSource.js";
23
23
  import { errorMessage, writeError } from "../../util.js";
24
24
  import { invokeShellCommand } from "./invoke.js";
25
+ import { parseShellJson } from "./parseOutput.js";
25
26
  import { shellFetchOutputSchema, shellIssueSchema, shellValidateOutputSchema, } from "./schema.js";
26
27
  const DEFAULT_TIMEOUTS = {
27
28
  verify: 10_000,
@@ -134,7 +135,10 @@ export function createShellTaskSource(config, _context) {
134
135
  env: config.env,
135
136
  sourceName,
136
137
  });
137
- const parsed = shellFetchOutputSchema.parse(JSON.parse(stdout));
138
+ const parsed = parseShellJson(shellFetchOutputSchema, stdout, {
139
+ sourceName,
140
+ command: "listTasks",
141
+ });
138
142
  return parsed.map((si) => toCanonicalIssue(si, sourceName));
139
143
  }
140
144
  async function getTask(naturalId) {
@@ -158,7 +162,10 @@ export function createShellTaskSource(config, _context) {
158
162
  if (result.exitCode === 3 || result.stdout.trim().length === 0) {
159
163
  return null;
160
164
  }
161
- const parsed = shellIssueSchema.parse(JSON.parse(result.stdout));
165
+ const parsed = parseShellJson(shellIssueSchema, result.stdout, {
166
+ sourceName,
167
+ command: "getTask",
168
+ });
162
169
  return toCanonicalIssue(parsed, sourceName);
163
170
  }
164
171
  // Shared by markInProgress / markInReview: both pipe the canonical issue's
@@ -259,7 +266,10 @@ export function createShellTaskSource(config, _context) {
259
266
  if (trimmed.length === 0) {
260
267
  throw new Error(`shell source "${sourceName}" createTask command produced no output (expected one ShellIssue JSON)`);
261
268
  }
262
- const parsed = shellIssueSchema.parse(JSON.parse(trimmed));
269
+ const parsed = parseShellJson(shellIssueSchema, trimmed, {
270
+ sourceName,
271
+ command: "createTask",
272
+ });
263
273
  return toCanonicalIssue(parsed, sourceName);
264
274
  };
265
275
  }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Friendly stdout parsing for the shell adapter. A shell source emits JSON on
3
+ * stdout; both `JSON.parse` and the Zod schema can reject it. A raw `ZodError`
4
+ * stringifies to a JSON array of issues — cryptic, unattributed, and (for a
5
+ * fetch array) repeated once per task. This module collapses that into a
6
+ * single user-facing `TaskSourceOutputError` that names the source, the
7
+ * command, and the offending field(s), with a targeted hint for the common
8
+ * "missing `agent`" mistake.
9
+ */
10
+ import type { z } from "zod";
11
+ export interface ShellParseContext {
12
+ /** The source's configured `name`, surfaced so the user knows which source broke. */
13
+ sourceName: string;
14
+ /** The contract method that produced the output, e.g. `"listTasks"` or `"getTask"`. */
15
+ command: string;
16
+ }
17
+ /**
18
+ * Parse `stdout` as JSON and validate it against `schema`. On any failure,
19
+ * throws a `TaskSourceOutputError` with a readable, source-attributed message
20
+ * instead of a raw `SyntaxError` / `ZodError`.
21
+ */
22
+ export declare function parseShellJson<T>(schema: z.ZodType<T>, stdout: string, context: ShellParseContext): T;
23
+ //# sourceMappingURL=parseOutput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseOutput.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/shell/parseOutput.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAK7B,MAAM,WAAW,iBAAiB;IAChC,qFAAqF;IACrF,UAAU,EAAE,MAAM,CAAC;IACnB,uFAAuF;IACvF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EACpB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,iBAAiB,GACzB,CAAC,CAcH"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Friendly stdout parsing for the shell adapter. A shell source emits JSON on
3
+ * stdout; both `JSON.parse` and the Zod schema can reject it. A raw `ZodError`
4
+ * stringifies to a JSON array of issues — cryptic, unattributed, and (for a
5
+ * fetch array) repeated once per task. This module collapses that into a
6
+ * single user-facing `TaskSourceOutputError` that names the source, the
7
+ * command, and the offending field(s), with a targeted hint for the common
8
+ * "missing `agent`" mistake.
9
+ */
10
+ import { TaskSourceOutputError } from "../../taskSource.js";
11
+ import { errorMessage } from "../../util.js";
12
+ /**
13
+ * Parse `stdout` as JSON and validate it against `schema`. On any failure,
14
+ * throws a `TaskSourceOutputError` with a readable, source-attributed message
15
+ * instead of a raw `SyntaxError` / `ZodError`.
16
+ */
17
+ export function parseShellJson(schema, stdout, context) {
18
+ let json;
19
+ try {
20
+ json = JSON.parse(stdout);
21
+ }
22
+ catch (error) {
23
+ throw new TaskSourceOutputError(`source "${context.sourceName}": the ${context.command} command did not return valid JSON (${errorMessage(error)}).`);
24
+ }
25
+ const result = schema.safeParse(json);
26
+ if (result.success) {
27
+ return result.data;
28
+ }
29
+ throw new TaskSourceOutputError(formatSchemaError(result.error, context));
30
+ }
31
+ /** The last string segment of an issue path — the field name, ignoring array indices. */
32
+ function fieldName(path) {
33
+ for (let index = path.length - 1; index >= 0; index -= 1) {
34
+ const segment = path[index];
35
+ if (typeof segment === "string") {
36
+ return segment;
37
+ }
38
+ }
39
+ return undefined;
40
+ }
41
+ /** One human-readable phrase describing what's wrong with a single issue. */
42
+ function describeIssue(issue) {
43
+ const field = fieldName(issue.path);
44
+ const label = field === undefined ? "field" : `"${field}"`;
45
+ // Zod v4 reports a missing required key as an `invalid_type` whose message
46
+ // ends in "received undefined"; there is no separate `received` property to
47
+ // branch on, so we match the message.
48
+ if (issue.code === "invalid_type" && issue.message.includes("received undefined")) {
49
+ return `are missing the required ${label} field`;
50
+ }
51
+ return `have an invalid ${label} field: ${issue.message}`;
52
+ }
53
+ function formatSchemaError(error, context) {
54
+ // A fetch array yields one issue per task (48 tasks missing `agent` → 48
55
+ // identical issues). Collapse identical phrasings into a single counted line,
56
+ // preserving first-seen order via the Map's insertion order.
57
+ const counts = new Map();
58
+ for (const issue of error.issues) {
59
+ const description = describeIssue(issue);
60
+ counts.set(description, (counts.get(description) ?? 0) + 1);
61
+ }
62
+ const lines = [...counts].map(([description, count]) => ` • ${count} issue(s) ${description}`);
63
+ return [
64
+ `source "${context.sourceName}": the ${context.command} command returned task JSON that doesn't match the expected shape:`,
65
+ ...lines,
66
+ ].join("\n");
67
+ }
@@ -210,6 +210,19 @@ export declare class RepositoryResolutionError extends Error {
210
210
  repositories: readonly string[];
211
211
  });
212
212
  }
213
+ /**
214
+ * A task source returned output that groundcrew could not parse — non-JSON
215
+ * stdout, or JSON that doesn't match the source's contract (e.g. a shell
216
+ * script's `listTasks` payload missing the required `agent` field). Carries a
217
+ * user-facing message that names the source and what was wrong.
218
+ *
219
+ * Marked deterministic: re-running the same command yields the same bad
220
+ * output, so the orchestrator's `withRetry` must NOT retry it (retrying only
221
+ * delays a guaranteed failure behind confusing "Retrying in Ns" lines).
222
+ */
223
+ export declare class TaskSourceOutputError extends Error {
224
+ constructor(message: string);
225
+ }
213
226
  export declare class AmbiguousTaskError extends Error {
214
227
  constructor(arguments_: {
215
228
  naturalId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"taskSource.d.ts","sourceRoot":"","sources":["../../src/lib/taskSource.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"taskSource.d.ts","sourceRoot":"","sources":["../../src/lib/taskSource.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,22 @@ export class RepositoryResolutionError extends Error {
17
17
  this.name = "RepositoryResolutionError";
18
18
  }
19
19
  }
20
+ /**
21
+ * A task source returned output that groundcrew could not parse — non-JSON
22
+ * stdout, or JSON that doesn't match the source's contract (e.g. a shell
23
+ * script's `listTasks` payload missing the required `agent` field). Carries a
24
+ * user-facing message that names the source and what was wrong.
25
+ *
26
+ * Marked deterministic: re-running the same command yields the same bad
27
+ * output, so the orchestrator's `withRetry` must NOT retry it (retrying only
28
+ * delays a guaranteed failure behind confusing "Retrying in Ns" lines).
29
+ */
30
+ export class TaskSourceOutputError extends Error {
31
+ constructor(message) {
32
+ super(message);
33
+ this.name = "TaskSourceOutputError";
34
+ }
35
+ }
20
36
  export class AmbiguousTaskError extends Error {
21
37
  constructor(arguments_) {
22
38
  const { naturalId, matches } = arguments_;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clipboard-health/groundcrew",
3
- "version": "4.35.0",
3
+ "version": "4.35.1",
4
4
  "description": "Linear-driven orchestrator that launches AI coding agents in git worktrees, with workspace lifecycle and usage tracking.",
5
5
  "keywords": [
6
6
  "agent",
@@ -82,7 +82,7 @@
82
82
  "@tsconfig/node24": "24.0.4",
83
83
  "@tsconfig/strictest": "2.0.8",
84
84
  "@types/node": "25.9.2",
85
- "@typescript/native-preview": "7.0.0-dev.20260606.1",
85
+ "@typescript/native-preview": "7.0.0-dev.20260608.1",
86
86
  "@vitest/coverage-v8": "4.1.8",
87
87
  "cspell": "10.0.1",
88
88
  "dependency-cruiser": "17.4.3",