@clipboard-health/groundcrew 4.10.1 → 4.10.3

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":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAanE,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAonBD,wBAAsB,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/F;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7D"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAanE,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA6mBD,wBAAsB,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/F;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7D"}
@@ -47,7 +47,7 @@ async function writeTicketWorktrees(config, ticket) {
47
47
  });
48
48
  // oxlint-disable-next-line no-await-in-loop -- one gh lookup per worktree is acceptable; multi-worktree-per-ticket is rare.
49
49
  const prs = await findPullRequestsForBranch({
50
- repository: entry.repository,
50
+ cwd: entry.dir,
51
51
  branchName: entry.branchName,
52
52
  });
53
53
  writeOutput(`- ${entry.repository} ${entry.kind}`);
@@ -326,10 +326,10 @@ async function writeInventoryWorktrees(config, probe) {
326
326
  }
327
327
  const runState = runStates.get(entry.ticket);
328
328
  const accessHint = accessHints.get(entry.ticket);
329
- // `collectPullRequests` guarantees an entry for every (repo, branch)
330
- // pair seen in `entries`; the lookup always returns the array.
329
+ // `collectPullRequests` guarantees an entry for every worktree dir seen
330
+ // in `entries`; the lookup always returns the array.
331
331
  /* v8 ignore next @preserve -- defensive fallback for a Map key that collectPullRequests always populates */
332
- const prs = pullRequests.get(pullRequestKey(entry.repository, entry.branchName)) ?? [];
332
+ const prs = pullRequests.get(entry.dir) ?? [];
333
333
  if (index > 0) {
334
334
  writeOutput();
335
335
  }
@@ -352,9 +352,6 @@ async function writeInventoryWorktrees(config, probe) {
352
352
  }
353
353
  }
354
354
  }
355
- function pullRequestKey(repository, branchName) {
356
- return `${repository} ${branchName}`;
357
- }
358
355
  async function collectAccessHints(config, entries) {
359
356
  const uniqueTickets = [...new Set(entries.map((entry) => entry.ticket))];
360
357
  const results = await Promise.allSettled(uniqueTickets.map(async (ticket) => await workspaces.accessHint(config, ticket)));
@@ -364,23 +361,20 @@ async function collectAccessHints(config, entries) {
364
361
  }));
365
362
  }
366
363
  async function collectPullRequests(entries) {
367
- // Same-(repo, branch) entries collapse to one lookup; later inserts
368
- // overwrite earlier ones with the same identifier, which is fine because
369
- // gh would return the same PR list for both.
370
- const uniqueKeys = new Map();
364
+ // Each worktree dir is unique, so keying by dir collapses nothing in
365
+ // practice; the Map removes duplicates defensively if the same dir
366
+ // appears twice.
367
+ const uniqueByDir = new Map();
371
368
  for (const entry of entries) {
372
- uniqueKeys.set(pullRequestKey(entry.repository, entry.branchName), {
373
- repository: entry.repository,
374
- branchName: entry.branchName,
375
- });
369
+ uniqueByDir.set(entry.dir, { dir: entry.dir, branchName: entry.branchName });
376
370
  }
377
- const results = await Promise.allSettled([...uniqueKeys.entries()].map(async ([key, { repository, branchName }]) => {
378
- const prs = await findPullRequestsForBranch({ repository, branchName });
379
- return [key, prs];
371
+ const results = await Promise.allSettled([...uniqueByDir.entries()].map(async ([dir, { branchName }]) => {
372
+ const prs = await findPullRequestsForBranch({ cwd: dir, branchName });
373
+ return [dir, prs];
380
374
  }));
381
- return new Map([...uniqueKeys.keys()].map((key, index) => {
375
+ return new Map([...uniqueByDir.keys()].map((dir, index) => {
382
376
  const result = results[index];
383
- return [key, result?.status === "fulfilled" ? result.value[1] : []];
377
+ return [dir, result?.status === "fulfilled" ? result.value[1] : []];
384
378
  }));
385
379
  }
386
380
  function writeStraySessions(probe, worktreeTickets) {
@@ -3,6 +3,11 @@
3
3
  * `gh` CLI. `crew status` uses this to surface PR links inline; failures
4
4
  * (gh not on PATH, not authenticated, non-GitHub remote) are silent — the
5
5
  * caller falls back to omitting the row.
6
+ *
7
+ * The lookup runs with `cwd` set to the worktree directory and lets `gh`
8
+ * resolve the GitHub repo from that checkout's own `origin` remote. This
9
+ * handles bare config names, full `owner/repo` slugs, forks, and SSH/HTTPS
10
+ * remotes uniformly — we never reconstruct the slug ourselves.
6
11
  */
7
12
  export interface PullRequestSummary {
8
13
  url: string;
@@ -12,8 +17,8 @@ export interface PullRequestSummary {
12
17
  title: string;
13
18
  }
14
19
  interface LookupArgs {
15
- /** GitHub `owner/repo` slug. */
16
- repository: string;
20
+ /** Worktree directory; `gh` resolves the GitHub repo from its git remote. */
21
+ cwd: string;
17
22
  /** Branch name to filter PRs by. */
18
23
  branchName: string;
19
24
  signal?: AbortSignal;
@@ -1 +1 @@
1
- {"version":3,"file":"pullRequests.d.ts","sourceRoot":"","sources":["../../src/lib/pullRequests.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AASD,UAAU,UAAU;IAClB,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAgDD,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CA2BxC"}
1
+ {"version":3,"file":"pullRequests.d.ts","sourceRoot":"","sources":["../../src/lib/pullRequests.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AASD,UAAU,UAAU;IAClB,6EAA6E;IAC7E,GAAG,EAAE,MAAM,CAAC;IACZ,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAgDD,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAyBxC"}
@@ -3,6 +3,11 @@
3
3
  * `gh` CLI. `crew status` uses this to surface PR links inline; failures
4
4
  * (gh not on PATH, not authenticated, non-GitHub remote) are silent — the
5
5
  * caller falls back to omitting the row.
6
+ *
7
+ * The lookup runs with `cwd` set to the worktree directory and lets `gh`
8
+ * resolve the GitHub repo from that checkout's own `origin` remote. This
9
+ * handles bare config names, full `owner/repo` slugs, forks, and SSH/HTTPS
10
+ * remotes uniformly — we never reconstruct the slug ourselves.
6
11
  */
7
12
  import { runCommandAsync } from "./commandRunner.js";
8
13
  const GH_PR_LIST_LIMIT = 5;
@@ -48,13 +53,11 @@ function isRawPullRequest(value) {
48
53
  typeof record["title"] === "string");
49
54
  }
50
55
  export async function findPullRequestsForBranch(arguments_) {
51
- const { repository, branchName, signal } = arguments_;
56
+ const { cwd, branchName, signal } = arguments_;
52
57
  try {
53
58
  const output = await runCommandAsync("gh", [
54
59
  "pr",
55
60
  "list",
56
- "--repo",
57
- repository,
58
61
  "--head",
59
62
  branchName,
60
63
  "--state",
@@ -63,7 +66,7 @@ export async function findPullRequestsForBranch(arguments_) {
63
66
  String(GH_PR_LIST_LIMIT),
64
67
  "--json",
65
68
  "url,number,state,title",
66
- ], signal === undefined ? {} : { signal });
69
+ ], signal === undefined ? { cwd } : { cwd, signal });
67
70
  return parsePullRequests(output);
68
71
  }
69
72
  catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clipboard-health/groundcrew",
3
- "version": "4.10.1",
3
+ "version": "4.10.3",
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",
@@ -68,14 +68,14 @@
68
68
  "verify": "node scripts/verifyAll.mts"
69
69
  },
70
70
  "dependencies": {
71
- "@clipboard-health/clearance": "1.1.7",
71
+ "@clipboard-health/clearance": "1.1.13",
72
72
  "@linear/sdk": "86.0.0",
73
73
  "cosmiconfig": "9.0.1",
74
74
  "tslib": "2.8.1",
75
75
  "zod": "4.4.3"
76
76
  },
77
77
  "devDependencies": {
78
- "@clipboard-health/ai-rules": "2.21.0",
78
+ "@clipboard-health/ai-rules": "2.21.1",
79
79
  "@clipboard-health/oxlint-config": "1.9.4",
80
80
  "@nx/js": "22.7.3",
81
81
  "@tsconfig/node24": "24.0.4",