@clipboard-health/groundcrew 4.2.4 → 4.3.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 (36) hide show
  1. package/README.md +21 -36
  2. package/dist/commands/dispatcher.d.ts.map +1 -1
  3. package/dist/commands/dispatcher.js +5 -1
  4. package/dist/commands/setupWorkspace.d.ts +2 -0
  5. package/dist/commands/setupWorkspace.d.ts.map +1 -1
  6. package/dist/commands/setupWorkspace.js +11 -1
  7. package/dist/commands/status.d.ts.map +1 -1
  8. package/dist/commands/status.js +332 -52
  9. package/dist/commands/upgrade.d.ts +1 -0
  10. package/dist/commands/upgrade.d.ts.map +1 -1
  11. package/dist/commands/upgrade.js +57 -8
  12. package/dist/lib/adapters/linear/factory.d.ts.map +1 -1
  13. package/dist/lib/adapters/linear/factory.js +2 -0
  14. package/dist/lib/adapters/linear/fetch.d.ts +5 -0
  15. package/dist/lib/adapters/linear/fetch.d.ts.map +1 -1
  16. package/dist/lib/adapters/linear/fetch.js +6 -0
  17. package/dist/lib/adapters/shell/factory.d.ts.map +1 -1
  18. package/dist/lib/adapters/shell/factory.js +1 -0
  19. package/dist/lib/adapters/shell/schema.d.ts +2 -0
  20. package/dist/lib/adapters/shell/schema.d.ts.map +1 -1
  21. package/dist/lib/adapters/shell/schema.js +5 -0
  22. package/dist/lib/npmGlobal.d.ts +3 -2
  23. package/dist/lib/npmGlobal.d.ts.map +1 -1
  24. package/dist/lib/npmGlobal.js +9 -8
  25. package/dist/lib/pullRequests.d.ts +23 -0
  26. package/dist/lib/pullRequests.d.ts.map +1 -0
  27. package/dist/lib/pullRequests.js +74 -0
  28. package/dist/lib/runState.d.ts +15 -0
  29. package/dist/lib/runState.d.ts.map +1 -1
  30. package/dist/lib/runState.js +11 -0
  31. package/dist/lib/ticketSource.d.ts +7 -0
  32. package/dist/lib/ticketSource.d.ts.map +1 -1
  33. package/dist/lib/workspaces.d.ts +2 -1
  34. package/dist/lib/workspaces.d.ts.map +1 -1
  35. package/dist/lib/workspaces.js +5 -4
  36. package/package.json +2 -2
@@ -1,3 +1,5 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { join } from "node:path";
1
3
  import { runCommand } from "../lib/commandRunner.js";
2
4
  import { which } from "../lib/host.js";
3
5
  import { classifyInstall, createDefaultNpmSpawner, detectInstallPath, detectIsSymlink, detectNpmRootGlobal, runNpmInstallGlobal, } from "../lib/npmGlobal.js";
@@ -54,13 +56,13 @@ export async function upgradeCli(argv, optionsInput) {
54
56
  return;
55
57
  }
56
58
  const options = await resolveOptions(optionsInput);
57
- const npmBin = await resolveGlobalNpmBin(options);
58
- if (npmBin === undefined) {
59
+ const install = await resolveGlobalInstall(options);
60
+ if (install === undefined) {
59
61
  return;
60
62
  }
61
- await runInstallAndReport(options, npmBin, parsed.version);
63
+ await runInstallAndReport(options, install, parsed.version);
62
64
  }
63
- async function resolveGlobalNpmBin(options) {
65
+ async function resolveGlobalInstall(options) {
64
66
  const install = await options.resolveInstall();
65
67
  if (install.installKind !== "global") {
66
68
  writeError(refusalMessage(install.installKind, install.installPath, options.packageName));
@@ -72,22 +74,45 @@ async function resolveGlobalNpmBin(options) {
72
74
  process.exitCode = 1;
73
75
  return undefined;
74
76
  }
75
- return install.npmBin;
77
+ return { installPath: install.installPath, npmBin: install.npmBin };
76
78
  }
77
- async function runInstallAndReport(options, npmBin, version) {
79
+ async function runInstallAndReport(options, install, version) {
80
+ const fromVersion = options.readInstalledVersion(install.installPath);
81
+ writeOutput("Upgrading crew…");
78
82
  const result = await options.runInstall({
79
83
  packageName: options.packageName,
80
84
  version,
81
- npmBin,
85
+ npmBin: install.npmBin,
82
86
  });
83
87
  if (result.exitCode === 0) {
88
+ const toVersion = options.readInstalledVersion(install.installPath);
89
+ writeOutput(formatUpgradeSuccess({ fromVersion, toVersion }));
84
90
  return;
85
91
  }
92
+ if (result.outputText.length > 0) {
93
+ process.stderr.write(result.outputText);
94
+ if (!result.outputText.endsWith("\n")) {
95
+ process.stderr.write("\n");
96
+ }
97
+ }
86
98
  if (result.sawEacces) {
87
99
  writeError("crew upgrade: install failed with EACCES (permission denied). Your global npm prefix may require elevated permissions - see https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally");
88
100
  }
89
101
  process.exitCode = result.exitCode;
90
102
  }
103
+ function formatUpgradeSuccess(versions) {
104
+ const { fromVersion, toVersion } = versions;
105
+ if (toVersion === undefined) {
106
+ return "crew upgrade complete";
107
+ }
108
+ if (fromVersion === undefined) {
109
+ return `crew is now on version ${toVersion}`;
110
+ }
111
+ if (fromVersion === toVersion) {
112
+ return `crew is already on version ${toVersion}`;
113
+ }
114
+ return `Upgraded crew from ${fromVersion} to ${toVersion}`;
115
+ }
91
116
  export async function createDefaultUpgradeCliOptions(args) {
92
117
  return {
93
118
  packageName: args.packageName,
@@ -104,7 +129,31 @@ export async function createDefaultUpgradeCliOptions(args) {
104
129
  },
105
130
  runInstall: async (options) => await runNpmInstallGlobal({
106
131
  ...options,
107
- spawner: createDefaultNpmSpawner(process.stderr),
132
+ spawner: createDefaultNpmSpawner(),
108
133
  }),
134
+ readInstalledVersion: readInstalledVersionFromDisk,
109
135
  };
110
136
  }
137
+ function readInstalledVersionFromDisk(installPath) {
138
+ let raw;
139
+ try {
140
+ raw = readFileSync(join(installPath, "package.json"), "utf8");
141
+ }
142
+ catch {
143
+ return undefined;
144
+ }
145
+ let parsed;
146
+ try {
147
+ parsed = JSON.parse(raw);
148
+ }
149
+ catch {
150
+ return undefined;
151
+ }
152
+ if (typeof parsed === "object" &&
153
+ parsed !== null &&
154
+ "version" in parsed &&
155
+ typeof parsed.version === "string") {
156
+ return parsed.version;
157
+ }
158
+ return undefined;
159
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAIL,KAAK,KAAK,IAAI,cAAc,EAE5B,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,OAAO,EAKL,KAAK,KAAK,IAAI,WAAW,EAE1B,MAAM,YAAY,CAAC;AAGpB;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,iGAAiG;IACjG,YAAY,EAAE,MAAM,CAAC;CACtB;AAkFD,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,CA+Ed"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAIL,KAAK,KAAK,IAAI,cAAc,EAE5B,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,OAAO,EAKL,KAAK,KAAK,IAAI,WAAW,EAE1B,MAAM,YAAY,CAAC;AAGpB;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,iGAAiG;IACjG,YAAY,EAAE,MAAM,CAAC;CACtB;AAkFD,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,CAuB7F;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,cAAc,GACtB,YAAY,CAgFd"}
@@ -107,6 +107,7 @@ export function toCanonicalIssue(linearIssue, sourceName) {
107
107
  updatedAt: linearIssue.updatedAt,
108
108
  blockers: linearIssue.blockers.map((b) => toCanonicalBlocker(b, sourceName)),
109
109
  hasMoreBlockers: linearIssue.hasMoreBlockers,
110
+ url: linearIssue.url,
110
111
  sourceRef,
111
112
  };
112
113
  }
@@ -172,6 +173,7 @@ export function createLinearTicketSource(config, context) {
172
173
  updatedAt: new Date().toISOString(),
173
174
  blockers: [],
174
175
  hasMoreBlockers: false,
176
+ url: resolved.url,
175
177
  sourceRef,
176
178
  };
177
179
  },
@@ -46,6 +46,8 @@ export interface Issue {
46
46
  teamId: string;
47
47
  blockers: Blocker[];
48
48
  hasMoreBlockers: boolean;
49
+ /** Linear `Issue.url` — direct web link to the ticket. */
50
+ url: string;
49
51
  }
50
52
  /**
51
53
  * `Issue` narrowed to "this ticket is for groundcrew". Consumers operate on
@@ -113,6 +115,7 @@ interface ResolvedIssue {
113
115
  stateType: string;
114
116
  status: string;
115
117
  statusId: string;
118
+ url: string;
116
119
  }
117
120
  export interface RawLinearIssue {
118
121
  uuid: string;
@@ -135,6 +138,8 @@ export interface RawLinearIssue {
135
138
  * reporting "would dispatch."
136
139
  */
137
140
  hasChildren: boolean;
141
+ /** Linear `Issue.url` — direct web link to the ticket. */
142
+ url: string;
138
143
  }
139
144
  export declare function fetchBlockersForTicket(arguments_: {
140
145
  client: LinearClient;
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/fetch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/fetch.ts"],"names":[],"mappings":"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"}
@@ -84,6 +84,7 @@ async function fetchBoard(client, config) {
84
84
  title
85
85
  description
86
86
  updatedAt
87
+ url
87
88
  state { id name type }
88
89
  team { id key }
89
90
  assignee { name }
@@ -177,6 +178,7 @@ function buildLinearIssue(input) {
177
178
  repository: input.repository,
178
179
  model: input.model,
179
180
  teamId: input.teamId,
181
+ url: input.url,
180
182
  blockers: blockersFromRelations(input.inverseRelations?.nodes ?? []),
181
183
  hasMoreBlockers: input.inverseRelations?.pageInfo.hasNextPage ?? false,
182
184
  };
@@ -209,6 +211,7 @@ function issueFromNode(node, config) {
209
211
  repository,
210
212
  model,
211
213
  teamId: node.team?.id ?? "",
214
+ url: node.url,
212
215
  inverseRelations: node.inverseRelations,
213
216
  });
214
217
  }
@@ -255,6 +258,7 @@ export async function fetchRawLinearIssue(arguments_) {
255
258
  id
256
259
  title
257
260
  description
261
+ url
258
262
  team { id }
259
263
  state { id name type }
260
264
  children { nodes { id } }
@@ -295,6 +299,7 @@ export async function fetchRawLinearIssue(arguments_) {
295
299
  blockers: blockersFromRelations(issue.inverseRelations?.nodes ?? []),
296
300
  hasMoreBlockers: issue.inverseRelations?.pageInfo.hasNextPage ?? false,
297
301
  hasChildren: (issue.children?.nodes.length ?? 0) > 0,
302
+ url: issue.url,
298
303
  };
299
304
  }
300
305
  export async function fetchInProgressIssueCount(arguments_) {
@@ -371,6 +376,7 @@ export async function fetchResolvedIssue(arguments_) {
371
376
  stateType: raw.stateType,
372
377
  status: raw.stateName,
373
378
  statusId: raw.stateId,
379
+ url: raw.url,
374
380
  };
375
381
  }
376
382
  export function warnIfDisabledFallback(ticket, modelResolution, config) {
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/shell/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAGL,KAAK,KAAK,IAAI,cAAc,EAC5B,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,KAAK,kBAAkB,EAEvB,KAAK,UAAU,EAEhB,MAAM,aAAa,CAAC;AAyBrB,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,CAsB3F;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,cAAc,GACvB,YAAY,CAgFd"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/shell/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAGL,KAAK,KAAK,IAAI,cAAc,EAC5B,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,KAAK,kBAAkB,EAEvB,KAAK,UAAU,EAEhB,MAAM,aAAa,CAAC;AAyBrB,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,CAuB3F;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,cAAc,GACvB,YAAY,CAgFd"}
@@ -50,6 +50,7 @@ export function toCanonicalIssue(shellIssue, sourceName) {
50
50
  updatedAt: shellIssue.updatedAt,
51
51
  blockers,
52
52
  hasMoreBlockers: shellIssue.hasMoreBlockers,
53
+ ...(shellIssue.url === undefined ? {} : { url: shellIssue.url }),
53
54
  sourceRef: shellIssue.sourceRef,
54
55
  };
55
56
  }
@@ -41,6 +41,7 @@ export declare const shellIssueSchema: z.ZodObject<{
41
41
  nativeStatus: z.ZodOptional<z.ZodString>;
42
42
  }, z.core.$strip>>;
43
43
  hasMoreBlockers: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
44
+ url: z.ZodOptional<z.ZodURL>;
44
45
  sourceRef: z.ZodUnknown;
45
46
  }, z.core.$strip>;
46
47
  export type ShellIssue = z.infer<typeof shellIssueSchema>;
@@ -76,6 +77,7 @@ export declare const shellFetchOutputSchema: z.ZodArray<z.ZodObject<{
76
77
  nativeStatus: z.ZodOptional<z.ZodString>;
77
78
  }, z.core.$strip>>;
78
79
  hasMoreBlockers: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
80
+ url: z.ZodOptional<z.ZodURL>;
79
81
  sourceRef: z.ZodUnknown;
80
82
  }, z.core.$strip>>;
81
83
  export declare const shellAdapterConfigSchema: z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/shell/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAY3B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAA4B,CAAC;AAEhE,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;iBAwBnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/shell/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiB3B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAA4B,CAAC;AAEhE,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;iBAwBnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
@@ -28,6 +28,11 @@ export const shellIssueSchema = z.object({
28
28
  updatedAt: z.string(),
29
29
  blockers: z.array(shellBlockerSchema),
30
30
  hasMoreBlockers: z.boolean().optional().default(false),
31
+ /**
32
+ * Direct web URL for the ticket. Optional so scripts can omit it without
33
+ * breaking; `crew status` falls back to displaying just the id.
34
+ */
35
+ url: z.url().optional(),
31
36
  sourceRef: z.unknown(),
32
37
  });
33
38
  export const shellFetchOutputSchema = z.array(shellIssueSchema);
@@ -7,12 +7,13 @@ export interface ClassifyInstallOptions {
7
7
  export declare function classifyInstall(options: ClassifyInstallOptions): InstallKind;
8
8
  export interface NpmSpawnerResult {
9
9
  exitCode: number;
10
- stderrText: string;
10
+ outputText: string;
11
11
  }
12
12
  export type NpmSpawner = (command: string, args: readonly string[]) => Promise<NpmSpawnerResult>;
13
13
  export interface NpmRunResult {
14
14
  exitCode: number;
15
15
  sawEacces: boolean;
16
+ outputText: string;
16
17
  }
17
18
  export interface RunNpmInstallOptions {
18
19
  packageName: string;
@@ -25,5 +26,5 @@ export declare function detectInstallPath(cliMetaUrl: string): string;
25
26
  export type NpmRootRunner = (command: string, args: readonly string[]) => string;
26
27
  export declare function detectNpmRootGlobal(npmBin: string, runner: NpmRootRunner): string | undefined;
27
28
  export declare function detectIsSymlink(path: string): boolean;
28
- export declare function createDefaultNpmSpawner(passthroughStderr: NodeJS.WritableStream): NpmSpawner;
29
+ export declare function createDefaultNpmSpawner(): NpmSpawner;
29
30
  //# sourceMappingURL=npmGlobal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"npmGlobal.d.ts","sourceRoot":"","sources":["../../src/lib/npmGlobal.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,CAAC;AAE9E,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CACtC;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,WAAW,CAY5E;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAEjG,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,UAAU,CAAC;CACrB;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CAO9F;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC;AAEjF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAM7F;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMrD;AAED,wBAAgB,uBAAuB,CAAC,iBAAiB,EAAE,MAAM,CAAC,cAAc,GAAG,UAAU,CAmB5F"}
1
+ {"version":3,"file":"npmGlobal.d.ts","sourceRoot":"","sources":["../../src/lib/npmGlobal.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,CAAC;AAE9E,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CACtC;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,WAAW,CAY5E;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAEjG,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,UAAU,CAAC;CACrB;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CAQ9F;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC;AAEjF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAM7F;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMrD;AAED,wBAAgB,uBAAuB,IAAI,UAAU,CAmBpD"}
@@ -20,7 +20,8 @@ export async function runNpmInstallGlobal(options) {
20
20
  const result = await options.spawner(options.npmBin, args);
21
21
  return {
22
22
  exitCode: result.exitCode,
23
- sawEacces: result.stderrText.includes("EACCES"),
23
+ sawEacces: result.outputText.includes("EACCES"),
24
+ outputText: result.outputText,
24
25
  };
25
26
  }
26
27
  export function detectInstallPath(cliMetaUrl) {
@@ -42,20 +43,20 @@ export function detectIsSymlink(path) {
42
43
  return false;
43
44
  }
44
45
  }
45
- export function createDefaultNpmSpawner(passthroughStderr) {
46
+ export function createDefaultNpmSpawner() {
46
47
  return async (command, args) => await new Promise((resolve, reject) => {
47
- const child = spawn(command, [...args], { stdio: ["inherit", "inherit", "pipe"] });
48
- const { stderr } = child;
48
+ const child = spawn(command, [...args], { stdio: ["inherit", "pipe", "pipe"] });
49
49
  const chunks = [];
50
- stderr.on("data", (chunk) => {
50
+ const collect = (chunk) => {
51
51
  chunks.push(chunk);
52
- passthroughStderr.write(chunk);
53
- });
52
+ };
53
+ child.stdout.on("data", collect);
54
+ child.stderr.on("data", collect);
54
55
  child.on("error", reject);
55
56
  child.on("close", (code) => {
56
57
  resolve({
57
58
  exitCode: code ?? 1,
58
- stderrText: Buffer.concat(chunks).toString("utf8"),
59
+ outputText: Buffer.concat(chunks).toString("utf8"),
59
60
  });
60
61
  });
61
62
  });
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Best-effort lookup of GitHub pull requests for a worktree branch via the
3
+ * `gh` CLI. `crew status` uses this to surface PR links inline; failures
4
+ * (gh not on PATH, not authenticated, non-GitHub remote) are silent — the
5
+ * caller falls back to omitting the row.
6
+ */
7
+ export interface PullRequestSummary {
8
+ url: string;
9
+ number: number;
10
+ /** Lowercased lifecycle: "open" | "merged" | "closed". */
11
+ state: string;
12
+ title: string;
13
+ }
14
+ interface LookupArgs {
15
+ /** GitHub `owner/repo` slug. */
16
+ repository: string;
17
+ /** Branch name to filter PRs by. */
18
+ branchName: string;
19
+ signal?: AbortSignal;
20
+ }
21
+ export declare function findPullRequestsForBranch(arguments_: LookupArgs): Promise<readonly PullRequestSummary[]>;
22
+ export {};
23
+ //# sourceMappingURL=pullRequests.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Best-effort lookup of GitHub pull requests for a worktree branch via the
3
+ * `gh` CLI. `crew status` uses this to surface PR links inline; failures
4
+ * (gh not on PATH, not authenticated, non-GitHub remote) are silent — the
5
+ * caller falls back to omitting the row.
6
+ */
7
+ import { runCommandAsync } from "./commandRunner.js";
8
+ const GH_PR_LIST_LIMIT = 5;
9
+ const STATE_MAP = {
10
+ OPEN: "open",
11
+ MERGED: "merged",
12
+ CLOSED: "closed",
13
+ };
14
+ function parsePullRequests(output) {
15
+ let parsed;
16
+ try {
17
+ parsed = JSON.parse(output);
18
+ }
19
+ catch {
20
+ return [];
21
+ }
22
+ if (!Array.isArray(parsed)) {
23
+ return [];
24
+ }
25
+ const summaries = [];
26
+ for (const entry of parsed) {
27
+ if (!isRawPullRequest(entry)) {
28
+ continue;
29
+ }
30
+ summaries.push({
31
+ url: entry.url,
32
+ number: entry.number,
33
+ state: STATE_MAP[entry.state] ?? entry.state.toLowerCase(),
34
+ title: entry.title,
35
+ });
36
+ }
37
+ return summaries;
38
+ }
39
+ function isRawPullRequest(value) {
40
+ if (typeof value !== "object" || value === null) {
41
+ return false;
42
+ }
43
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- narrowing untyped JSON.parse output to a record so we can probe its keys
44
+ const record = value;
45
+ return (typeof record["url"] === "string" &&
46
+ typeof record["number"] === "number" &&
47
+ typeof record["state"] === "string" &&
48
+ typeof record["title"] === "string");
49
+ }
50
+ export async function findPullRequestsForBranch(arguments_) {
51
+ const { repository, branchName, signal } = arguments_;
52
+ try {
53
+ const output = await runCommandAsync("gh", [
54
+ "pr",
55
+ "list",
56
+ "--repo",
57
+ repository,
58
+ "--head",
59
+ branchName,
60
+ "--state",
61
+ "all",
62
+ "--limit",
63
+ String(GH_PR_LIST_LIMIT),
64
+ "--json",
65
+ "url,number,state,title",
66
+ ], signal === undefined ? {} : { signal });
67
+ return parsePullRequests(output);
68
+ }
69
+ catch {
70
+ // gh not installed / not authenticated / non-GitHub remote / network
71
+ // error / etc. All resolve to "no PR info available" for display.
72
+ return [];
73
+ }
74
+ }
@@ -13,6 +13,19 @@ export interface RunState {
13
13
  resumeCount: number;
14
14
  reason?: string;
15
15
  detail?: string;
16
+ /**
17
+ * Ticket title at dispatch time. Cached so `crew status` can render it
18
+ * without re-hitting the ticket source; lifecycle transitions
19
+ * (resume/interrupt) that omit the field preserve the on-disk value.
20
+ */
21
+ title?: string;
22
+ /**
23
+ * Direct ticket URL at dispatch time. Same caching rationale as `title`;
24
+ * the source adapter populates it when it can (e.g., Linear), otherwise
25
+ * the field stays undefined and `crew status` falls back to displaying
26
+ * just the ticket id.
27
+ */
28
+ url?: string;
16
29
  }
17
30
  export interface RunStateDraft {
18
31
  ticket: string;
@@ -25,6 +38,8 @@ export interface RunStateDraft {
25
38
  reason?: string;
26
39
  detail?: string;
27
40
  resumeCount?: number;
41
+ title?: string;
42
+ url?: string;
28
43
  }
29
44
  export interface RecordRunStateInput {
30
45
  config: ResolvedConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"runState.d.ts","sourceRoot":"","sources":["../../src/lib/runState.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,GAAG,kBAAkB,CAAC;AAE3F,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,iBAAiB,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,iBAAiB,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,aAAa,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,GAAG,QAAQ,CAAC,CAAC,GAAG;QACvD,KAAK,EAAE,iBAAiB,CAAC;KAC1B,CAAC;CACH;AAaD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,GAAG,MAAM,CAEjF;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE5F;AA+ED,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAYzF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,QAAQ,CAmBnE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,QAAQ,GAAG,SAAS,CAc/E;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAE3E"}
1
+ {"version":3,"file":"runState.d.ts","sourceRoot":"","sources":["../../src/lib/runState.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,GAAG,kBAAkB,CAAC;AAE3F,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,iBAAiB,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,iBAAiB,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,aAAa,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,GAAG,QAAQ,CAAC,CAAC,GAAG;QACvD,KAAK,EAAE,iBAAiB,CAAC;KAC1B,CAAC;CACH;AAaD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,GAAG,MAAM,CAEjF;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE5F;AAmFD,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAYzF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,QAAQ,CA0BnE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,QAAQ,GAAG,SAAS,CAc/E;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAE3E"}
@@ -46,6 +46,8 @@ function parseRunState(value) {
46
46
  const updatedAt = stringField(value, "updatedAt");
47
47
  const reason = stringField(value, "reason");
48
48
  const detail = stringField(value, "detail");
49
+ const title = stringField(value, "title");
50
+ const url = stringField(value, "url");
49
51
  if (ticket === undefined ||
50
52
  repository === undefined ||
51
53
  model === undefined ||
@@ -73,6 +75,8 @@ function parseRunState(value) {
73
75
  resumeCount,
74
76
  ...(reason === undefined ? {} : { reason }),
75
77
  ...(detail === undefined ? {} : { detail }),
78
+ ...(title === undefined ? {} : { title }),
79
+ ...(url === undefined ? {} : { url }),
76
80
  };
77
81
  }
78
82
  function writeState(config, state) {
@@ -100,6 +104,11 @@ export function readRunState(config, ticket) {
100
104
  export function recordRunState(input) {
101
105
  const existing = readRunState(input.config, input.state.ticket);
102
106
  const timestamp = nowIso();
107
+ // Resume/interrupt callers don't know the title or url, so they omit
108
+ // them. Fall back to the on-disk value so cached display fields survive
109
+ // transitions.
110
+ const title = input.state.title ?? existing?.title;
111
+ const url = input.state.url ?? existing?.url;
103
112
  const state = {
104
113
  ticket: ticketKey(input.state.ticket),
105
114
  repository: input.state.repository,
@@ -113,6 +122,8 @@ export function recordRunState(input) {
113
122
  resumeCount: input.state.resumeCount ?? existing?.resumeCount ?? 0,
114
123
  ...(input.state.reason === undefined ? {} : { reason: input.state.reason }),
115
124
  ...(input.state.detail === undefined ? {} : { detail: input.state.detail }),
125
+ ...(title === undefined ? {} : { title }),
126
+ ...(url === undefined ? {} : { url }),
116
127
  };
117
128
  writeState(input.config, state);
118
129
  return state;
@@ -67,6 +67,13 @@ export interface Issue {
67
67
  updatedAt: string;
68
68
  blockers: Blocker[];
69
69
  hasMoreBlockers: boolean;
70
+ /**
71
+ * Direct web URL for the ticket on the source system, when the adapter
72
+ * knows one. `undefined` when the source can't produce a public URL (e.g.,
73
+ * a shell script that omits the `url` field). Display-only — never
74
+ * branched on.
75
+ */
76
+ url?: string;
70
77
  /** Adapter-private. Consumers MUST NOT inspect; only the producing adapter reads it. */
71
78
  sourceRef: unknown;
72
79
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ticketSource.d.ts","sourceRoot":"","sources":["../../src/lib/ticketSource.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ticketSource.d.ts","sourceRoot":"","sources":["../../src/lib/ticketSource.ts"],"names":[],"mappings":"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"}
@@ -22,12 +22,13 @@ interface ResolveArguments {
22
22
  }
23
23
  export declare function resolveWorkspaceKind(arguments_: ResolveArguments): WorkspaceResolution;
24
24
  declare function probeWorkspaces(config: ResolvedConfig, signal?: AbortSignal): Promise<WorkspaceProbe>;
25
+ declare function accessHintForWorkspace(config: ResolvedConfig, name: string, signal?: AbortSignal): Promise<WorkspaceAccessHint | undefined>;
25
26
  declare function interruptWorkspace(config: ResolvedConfig, name: string, signal?: AbortSignal): Promise<WorkspaceInterruptResult>;
26
27
  export declare const workspaces: {
27
28
  open(config: ResolvedConfig, spec: OpenSpec, signal?: AbortSignal): Promise<void>;
28
29
  probe: typeof probeWorkspaces;
29
30
  close(config: ResolvedConfig, name: string, signal?: AbortSignal): Promise<WorkspaceCloseResult>;
30
31
  interrupt: typeof interruptWorkspace;
31
- accessHint(config: ResolvedConfig, name: string, signal?: AbortSignal): Promise<WorkspaceAccessHint | undefined>;
32
+ accessHint: typeof accessHintForWorkspace;
32
33
  };
33
34
  //# sourceMappingURL=workspaces.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../../src/lib/workspaces.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAA0B,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE1E,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,QAAQ,EACR,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,aAAa,EACb,cAAc,EACd,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,oBAAoB,CAAC;IAChC,QAAQ,EAAE,aAAa,CAAC;IACxB,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,gBAAgB;IACxB,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,gBAAgB,CAAC;CACxB;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,gBAAgB,GAAG,mBAAmB,CAUtF;AAsDD,iBAAe,eAAe,CAC5B,MAAM,EAAE,cAAc,EACtB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,CAAC,CAezB;AAED,iBAAe,kBAAkB,CAC/B,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,wBAAwB,CAAC,CAenC;AAED,eAAO,MAAM,UAAU;IACf,IAAI,SAAS,cAAc,QAAQ,QAAQ,WAAW,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvF,KAAK;IACC,KAAK,SACD,cAAc,QAChB,MAAM,WACH,WAAW,GACnB,OAAO,CAAC,oBAAoB,CAAC;IAIhC,SAAS;IACH,UAAU,SACN,cAAc,QAChB,MAAM,WACH,WAAW,GACnB,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;CAI5C,CAAC"}
1
+ {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../../src/lib/workspaces.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAA0B,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE1E,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,QAAQ,EACR,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,aAAa,EACb,cAAc,EACd,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,oBAAoB,CAAC;IAChC,QAAQ,EAAE,aAAa,CAAC;IACxB,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,gBAAgB;IACxB,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,gBAAgB,CAAC;CACxB;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,gBAAgB,GAAG,mBAAmB,CAUtF;AAsDD,iBAAe,eAAe,CAC5B,MAAM,EAAE,cAAc,EACtB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,CAAC,CAezB;AAED,iBAAe,sBAAsB,CACnC,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAG1C;AAED,iBAAe,kBAAkB,CAC/B,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,wBAAwB,CAAC,CAenC;AAED,eAAO,MAAM,UAAU;IACf,IAAI,SAAS,cAAc,QAAQ,QAAQ,WAAW,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvF,KAAK;IACC,KAAK,SACD,cAAc,QAChB,MAAM,WACH,WAAW,GACnB,OAAO,CAAC,oBAAoB,CAAC;IAIhC,SAAS;IACT,UAAU;CACX,CAAC"}
@@ -76,6 +76,10 @@ async function probeWorkspaces(config, signal) {
76
76
  }
77
77
  return { kind: "ok", names: new Set(raw.map((ws) => ws.name)) };
78
78
  }
79
+ async function accessHintForWorkspace(config, name, signal) {
80
+ const adapter = await adapterFor(config, signal);
81
+ return adapter.accessHint(name);
82
+ }
79
83
  async function interruptWorkspace(config, name, signal) {
80
84
  const probe = await probeWorkspaces(config, signal);
81
85
  if (probe.kind === "unavailable") {
@@ -103,8 +107,5 @@ export const workspaces = {
103
107
  return await adapter.close(name, signal);
104
108
  },
105
109
  interrupt: interruptWorkspace,
106
- async accessHint(config, name, signal) {
107
- const adapter = await adapterFor(config, signal);
108
- return adapter.accessHint(name);
109
- },
110
+ accessHint: accessHintForWorkspace,
110
111
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clipboard-health/groundcrew",
3
- "version": "4.2.4",
3
+ "version": "4.3.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",
@@ -74,7 +74,7 @@
74
74
  "zod": "4.4.3"
75
75
  },
76
76
  "devDependencies": {
77
- "@clipboard-health/ai-rules": "2.18.7",
77
+ "@clipboard-health/ai-rules": "2.21.0",
78
78
  "@clipboard-health/oxlint-config": "1.9.4",
79
79
  "@nx/js": "22.7.2",
80
80
  "@tsconfig/node24": "24.0.4",