@clipboard-health/groundcrew 3.1.8 → 3.2.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.
package/README.md CHANGED
@@ -60,16 +60,19 @@ Installs the `crew` binary. `@clipboard-health/clearance` is pulled in transitiv
60
60
 
61
61
  3. **Create a Linear project to scope your work.** Any team works — make a project inside it and drop tickets in. The orchestrator polls by project, not by team.
62
62
 
63
- 4. **Configure.** Copy the shipped example into XDG config and edit:
63
+ 4. **Configure.** Create a `crew.config.ts` you can edit:
64
64
 
65
65
  ```bash
66
- mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/groundcrew"
67
- cp "$(npm root -g)/@clipboard-health/groundcrew/crew.config.example.ts" \
68
- "${XDG_CONFIG_HOME:-$HOME/.config}/groundcrew/crew.config.ts"
69
- $EDITOR "${XDG_CONFIG_HOME:-$HOME/.config}/groundcrew/crew.config.ts"
66
+ # Write into the current folder:
67
+ crew init && $EDITOR crew.config.ts
68
+
69
+ # ...or into the XDG config dir:
70
+ crew init --global && $EDITOR "${XDG_CONFIG_HOME:-$HOME/.config}/groundcrew/crew.config.ts"
70
71
  ```
71
72
 
72
- Or drop `crew.config.ts` at the root of any repo you run `crew` from `crew` discovers it via cosmiconfig project-walk. Any of `crew.config.{ts,mjs,js,json}`, `.crewrc{,.json,.ts}`, `.config/crew.config.{ts,json}`, or `.config/crewrc{,.json}` work.
73
+ `crew init` refuses to overwrite an existing config; pass `--force` to replace it, or `--dry-run` to preview the destination path.
74
+
75
+ `crew` discovers the config via cosmiconfig project-walk, so dropping it at the root of any repo you run `crew` from works too. Any of `crew.config.{ts,mjs,js,json}`, `.crewrc{,.json,.ts}`, `.config/crew.config.{ts,json}`, or `.config/crewrc{,.json}` are recognized.
73
76
 
74
77
  Set `linear.projects[].projectSlug` (paste the trailing slug of your Linear project URL, e.g. `ai-strategy-5152195762f3`), `workspace.projectDir`, and `workspace.knownRepositories`. Defaults cover everything else. To watch multiple projects from one `crew` instance, add more entries to `linear.projects`; they all share the same `orchestrator.maximumInProgress` budget.
75
78
 
@@ -359,6 +362,7 @@ To have a coding agent (Claude Code, Cursor, etc.) scaffold `.groundcrew/setup.s
359
362
  ## Commands
360
363
 
361
364
  ```bash
365
+ crew init [--global | --local] [--force] [--dry-run] # create a crew.config.ts (cwd by default)
362
366
  crew doctor # full setup check
363
367
  crew doctor --ticket <TICKET> [--no-linear] [--no-fetch] # full ticket lifecycle (dispatch + recovery)
364
368
  crew run # one-shot dispatch
@@ -29,6 +29,7 @@ slack.com
29
29
  api.datadoghq.com
30
30
  app.datadoghq.com
31
31
  datadoghq.com
32
+ docs.datadoghq.com
32
33
 
33
34
  # GitHub + GHA artifact storage (Azure blobs)
34
35
  api.github.com
@@ -68,6 +69,7 @@ www.npmjs.com
68
69
  app.terraform.io
69
70
  buf.build
70
71
  cdn.playwright.dev
72
+ fastdl.mongodb.org
71
73
  formulae.brew.sh
72
74
  hub.docker.com
73
75
  index.docker.io
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AA6JA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BvD"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAmKA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BvD"}
package/dist/cli.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createRequire } from "node:module";
2
2
  import { cleanupWorkspaceCli } from "./commands/cleanupWorkspace.js";
3
3
  import { doctor } from "./commands/doctor.js";
4
+ import { initConfigCli } from "./commands/init.js";
4
5
  import { interruptWorkspaceCli } from "./commands/interruptWorkspace.js";
5
6
  import { orchestrate } from "./commands/orchestrator.js";
6
7
  import { resumeWorkspaceCli } from "./commands/resumeWorkspace.js";
@@ -77,6 +78,11 @@ async function doctorCli(argv) {
77
78
  process.exitCode = ok ? process.exitCode : 1;
78
79
  }
79
80
  const SUBCOMMANDS = {
81
+ init: {
82
+ summary: "Create a crew.config.ts in the cwd (or --global into the XDG config dir)",
83
+ usage: "[--global | --local] [--force] [--dry-run]",
84
+ invoke: initConfigCli,
85
+ },
80
86
  run: {
81
87
  summary: "Run the orchestrator (one-shot by default), or provision one ticket with --ticket",
82
88
  usage: "[--watch] [--dry-run] [--ticket <ticket>]",
@@ -1 +1 @@
1
- {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/commands/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EACL,KAAK,UAAU,EAIhB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAWzD,UAAU,cAAc;IACtB,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,UAAU,EAAE;QAClB,KAAK,EAAE,UAAU,CAAC;QAClB,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;QAC1C,+FAA+F;QAC/F,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;QACvD,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB;;;;WAIG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,CAuMjE"}
1
+ {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/commands/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EACL,KAAK,UAAU,EAIhB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAWzD,UAAU,cAAc;IACtB,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,UAAU,EAAE;QAClB,KAAK,EAAE,UAAU,CAAC;QAClB,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;QAC1C,+FAA+F;QAC/F,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;QACvD,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB;;;;WAIG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB;AAaD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,CA4LjE"}
@@ -12,6 +12,16 @@ import { errorMessage, log, logEvent } from "../lib/util.js";
12
12
  import { workspaces } from "../lib/workspaces.js";
13
13
  import { classifyBlockers, classifyEligibility, classifyUsageExhaustion, } from "./eligibility.js";
14
14
  import { setupWorkspace } from "./setupWorkspace.js";
15
+ function logSkip(verdict) {
16
+ log(verdict.message);
17
+ logEvent("dispatch", {
18
+ outcome: "skipped",
19
+ reason: verdict.eventReason,
20
+ ticket: verdict.issue.id,
21
+ blockers: verdict.blockers,
22
+ model: verdict.model,
23
+ });
24
+ }
15
25
  export function createDispatcher(deps) {
16
26
  const { config, client } = deps;
17
27
  const issueStatusUpdater = createLinearIssueStatusUpdater({ config, client });
@@ -23,16 +33,6 @@ export function createDispatcher(deps) {
23
33
  }
24
34
  return exhausted;
25
35
  }
26
- function logSkip(verdict) {
27
- log(verdict.message);
28
- logEvent("dispatch", {
29
- outcome: "skipped",
30
- reason: verdict.eventReason,
31
- ticket: verdict.issue.id,
32
- blockers: verdict.blockers,
33
- model: verdict.model,
34
- });
35
- }
36
36
  async function startEligibleIssue(start, dryRun, signal) {
37
37
  const { issue, recovery } = start;
38
38
  if (start.resolvedFromAny) {
@@ -0,0 +1,26 @@
1
+ /**
2
+ * `crew init` — create a `crew.config.ts` in the current working directory or,
3
+ * with `--global`, in the XDG groundcrew config dir. The contents come from
4
+ * the shipped `crew.config.example.ts` so a fresh install skips the manual
5
+ * `cp` dance documented in the README.
6
+ */
7
+ type InitConfigScope = "global" | "local";
8
+ interface InitConfigOptions {
9
+ /** Where to write the config. Defaults to "local" (cwd). */
10
+ scope?: InitConfigScope;
11
+ /** Overwrite an existing destination. */
12
+ force?: boolean;
13
+ /** Report the planned action without touching the filesystem. */
14
+ dryRun?: boolean;
15
+ /** Override for the working directory; defaults to `process.cwd()`. */
16
+ cwd?: string;
17
+ }
18
+ type InitConfigOutcome = "dry-run-would-write" | "exists" | "wrote";
19
+ interface InitConfigResult {
20
+ destination: string;
21
+ outcome: InitConfigOutcome;
22
+ }
23
+ export declare function initConfig(options?: InitConfigOptions): InitConfigResult;
24
+ export declare function initConfigCli(argv: string[]): Promise<void>;
25
+ export {};
26
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,KAAK,eAAe,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1C,UAAU,iBAAiB;IACzB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,yCAAyC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iEAAiE;IACjE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,uEAAuE;IACvE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,KAAK,iBAAiB,GAAG,qBAAqB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEpE,UAAU,gBAAgB;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,iBAAiB,CAAC;CAC5B;AAED,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,gBAAgB,CAoB5E;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBjE"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * `crew init` — create a `crew.config.ts` in the current working directory or,
3
+ * with `--global`, in the XDG groundcrew config dir. The contents come from
4
+ * the shipped `crew.config.example.ts` so a fresh install skips the manual
5
+ * `cp` dance documented in the README.
6
+ */
7
+ import { copyFileSync, existsSync, mkdirSync } from "node:fs";
8
+ import { dirname, resolve } from "node:path";
9
+ import { log, writeOutput } from "../lib/util.js";
10
+ import { xdgConfigPath } from "../lib/xdg.js";
11
+ const CONFIG_FILE_NAME = "crew.config.ts";
12
+ const EXAMPLE_FILE_NAME = "crew.config.example.ts";
13
+ export function initConfig(options = {}) {
14
+ const scope = options.scope ?? "local";
15
+ const cwd = options.cwd ?? process.cwd();
16
+ const source = resolveExamplePath();
17
+ const destination = destinationFor({ scope, cwd });
18
+ if (existsSync(destination) && options.force !== true) {
19
+ log(`[exists] ${destination} — pass --force to overwrite`);
20
+ return { destination, outcome: "exists" };
21
+ }
22
+ if (options.dryRun === true) {
23
+ log(`[dry-run] would write ${destination}`);
24
+ return { destination, outcome: "dry-run-would-write" };
25
+ }
26
+ mkdirSync(dirname(destination), { recursive: true });
27
+ copyFileSync(source, destination);
28
+ log(`[wrote] ${destination}`);
29
+ return { destination, outcome: "wrote" };
30
+ }
31
+ export async function initConfigCli(argv) {
32
+ const options = parseArguments(argv);
33
+ const result = initConfig(options);
34
+ if (result.outcome === "exists") {
35
+ process.exitCode = 1;
36
+ return;
37
+ }
38
+ if (result.outcome === "wrote") {
39
+ writeOutput("");
40
+ writeOutput("Next steps:");
41
+ writeOutput(` - Edit ${result.destination}`);
42
+ writeOutput(" - Set linear.projects[].projectSlug, workspace.projectDir, workspace.knownRepositories");
43
+ writeOutput(" - Export GROUNDCREW_LINEAR_API_KEY (or LINEAR_API_KEY)");
44
+ writeOutput(" - Verify with `crew doctor`");
45
+ }
46
+ }
47
+ function parseArguments(argv) {
48
+ let scope;
49
+ let force = false;
50
+ let dryRun = false;
51
+ for (const argument of argv) {
52
+ if (argument === "--global" || argument === "--local") {
53
+ const next = argument === "--global" ? "global" : "local";
54
+ if (scope !== undefined && scope !== next) {
55
+ throw new Error("crew init: --global and --local are mutually exclusive.\nUsage: crew init [--global | --local] [--force] [--dry-run]");
56
+ }
57
+ scope = next;
58
+ continue;
59
+ }
60
+ if (argument === "--force") {
61
+ force = true;
62
+ continue;
63
+ }
64
+ if (argument === "--dry-run") {
65
+ dryRun = true;
66
+ continue;
67
+ }
68
+ throw new Error(`Unknown option: ${argument}\nUsage: crew init [--global | --local] [--force] [--dry-run]`);
69
+ }
70
+ return { scope: scope ?? "local", force, dryRun };
71
+ }
72
+ function destinationFor(args) {
73
+ if (args.scope === "global") {
74
+ return xdgConfigPath("groundcrew", CONFIG_FILE_NAME);
75
+ }
76
+ return resolve(args.cwd, CONFIG_FILE_NAME);
77
+ }
78
+ function resolveExamplePath() {
79
+ // `init.ts` lives at src/commands/init.ts in source and dist/commands/init.js
80
+ // after build; the example ships at the package root in both cases.
81
+ return resolve(import.meta.dirname, "..", "..", EXAMPLE_FILE_NAME);
82
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
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,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,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,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AA4QD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,EACtC,IAAI,EAAE,MAAM,GACX,OAAO,CAKT;AA4dD;;;;;;;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"}
@@ -5,6 +5,7 @@ import { resolve } from "node:path";
5
5
  import { pathToFileURL } from "node:url";
6
6
  import { cosmiconfig } from "cosmiconfig";
7
7
  import { log, readEnvironmentVariable, setLogFile } from "./util.js";
8
+ import { xdgConfigPath, xdgStatePath } from "./xdg.js";
8
9
  export { BUILD_SECRET_NAMES } from "./buildSecrets.js";
9
10
  /**
10
11
  * Reserved model name. A ticket labeled `agent-any` resolves at runtime
@@ -83,19 +84,6 @@ const ALLOWED_PROMPT_PLACEHOLDERS = new Set([
83
84
  const PROMPT_PLACEHOLDER_RE = /{{[^{}]*}}/g;
84
85
  const PERCENT_MIN_EXCLUSIVE = 0;
85
86
  const PERCENT_MAX = 100;
86
- function xdgBase(envName, fallbackSegments) {
87
- const override = readEnvironmentVariable(envName);
88
- if (override !== undefined && override.length > 0) {
89
- return override;
90
- }
91
- return resolve(homedir(), ...fallbackSegments);
92
- }
93
- function xdgConfigPath(...segments) {
94
- return resolve(xdgBase("XDG_CONFIG_HOME", [".config"]), ...segments);
95
- }
96
- function xdgStatePath(...segments) {
97
- return resolve(xdgBase("XDG_STATE_HOME", [".local", "state"]), ...segments);
98
- }
99
87
  function defaultLogFile() {
100
88
  return xdgStatePath("groundcrew", "groundcrew.log");
101
89
  }
@@ -0,0 +1,3 @@
1
+ export declare function xdgConfigPath(...segments: string[]): string;
2
+ export declare function xdgStatePath(...segments: string[]): string;
3
+ //# sourceMappingURL=xdg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xdg.d.ts","sourceRoot":"","sources":["../../src/lib/xdg.ts"],"names":[],"mappings":"AAgBA,wBAAgB,aAAa,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAE3D;AAED,wBAAgB,YAAY,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAE1D"}
@@ -0,0 +1,19 @@
1
+ import { homedir } from "node:os";
2
+ import { isAbsolute, resolve } from "node:path";
3
+ import { readEnvironmentVariable } from "./util.js";
4
+ // Per the XDG Base Directory spec, relative override paths are invalid and
5
+ // must be ignored — without this guard, a relative override would anchor to
6
+ // the cwd via `resolve` instead of falling back to $HOME.
7
+ function xdgBase(envName, fallbackSegments) {
8
+ const override = readEnvironmentVariable(envName);
9
+ if (override !== undefined && override.length > 0 && isAbsolute(override)) {
10
+ return override;
11
+ }
12
+ return resolve(homedir(), ...fallbackSegments);
13
+ }
14
+ export function xdgConfigPath(...segments) {
15
+ return resolve(xdgBase("XDG_CONFIG_HOME", [".config"]), ...segments);
16
+ }
17
+ export function xdgStatePath(...segments) {
18
+ return resolve(xdgBase("XDG_STATE_HOME", [".local", "state"]), ...segments);
19
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clipboard-health/groundcrew",
3
- "version": "3.1.8",
3
+ "version": "3.2.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",
@@ -68,34 +68,34 @@
68
68
  },
69
69
  "dependencies": {
70
70
  "@clipboard-health/clearance": "1.0.8",
71
- "@linear/sdk": "84.0.0",
71
+ "@linear/sdk": "85.0.0",
72
72
  "cosmiconfig": "9.0.1",
73
73
  "tslib": "2.8.1",
74
74
  "zod": "4.4.3"
75
75
  },
76
76
  "devDependencies": {
77
- "@clipboard-health/ai-rules": "2.18.4",
77
+ "@clipboard-health/ai-rules": "2.18.7",
78
78
  "@clipboard-health/oxlint-config": "1.9.4",
79
- "@nx/js": "22.7.1",
79
+ "@nx/js": "22.7.2",
80
80
  "@tsconfig/node24": "24.0.4",
81
81
  "@tsconfig/strictest": "2.0.8",
82
- "@types/node": "24.12.2",
83
- "@typescript/native-preview": "7.0.0-dev.20260430.1",
84
- "@vitest/coverage-v8": "4.1.5",
82
+ "@types/node": "24.12.4",
83
+ "@typescript/native-preview": "7.0.0-dev.20260522.1",
84
+ "@vitest/coverage-v8": "4.1.6",
85
85
  "cspell": "10.0.0",
86
86
  "dependency-cruiser": "17.4.0",
87
87
  "husky": "9.1.7",
88
- "jscpd": "4.0.9",
89
- "knip": "6.9.0",
90
- "lint-staged": "17.0.4",
88
+ "jscpd": "4.2.3",
89
+ "knip": "6.14.1",
90
+ "lint-staged": "17.0.5",
91
91
  "markdownlint-cli2": "0.22.1",
92
- "nx": "22.7.1",
93
- "oxfmt": "0.47.0",
94
- "oxlint": "1.64.0",
95
- "oxlint-tsgolint": "0.22.1",
96
- "syncpack": "15.0.0",
97
- "vite": "8.0.10",
98
- "vitest": "4.1.5"
92
+ "nx": "22.7.2",
93
+ "oxfmt": "0.50.0",
94
+ "oxlint": "1.65.0",
95
+ "oxlint-tsgolint": "0.23.0",
96
+ "syncpack": "15.2.0",
97
+ "vite": "8.0.14",
98
+ "vitest": "4.1.6"
99
99
  },
100
100
  "engines": {
101
101
  "node": "24.14.1",