@clipboard-health/groundcrew 4.49.3 → 4.49.4
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.
|
@@ -89,7 +89,13 @@ function resolveCreateRepository(arguments_) {
|
|
|
89
89
|
description: `Repository: ${input.repository}`,
|
|
90
90
|
config,
|
|
91
91
|
});
|
|
92
|
-
|
|
92
|
+
// `resolveRepositoryFor` reports an unconfigured *declared* repo as
|
|
93
|
+
// { kind: "ok", repository: <asserted name> } (the dispatch path relies on
|
|
94
|
+
// that so the host can WARN+skip it by name). Create is a manual, must-be-
|
|
95
|
+
// valid operation, so reject anything that didn't canonicalize to a known
|
|
96
|
+
// repository rather than routing a task at an unconfigured worktree.
|
|
97
|
+
if (resolution.kind === "missing" ||
|
|
98
|
+
!config.workspace.knownRepositories.includes(resolution.repository)) {
|
|
93
99
|
throw new Error(`linear: repository "${input.repository}" is not in workspace.knownRepositories`);
|
|
94
100
|
}
|
|
95
101
|
return resolution.repository;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parsing.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/parsing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAuC,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC3F,OAAO,EAA6B,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1F,eAAO,MAAM,kBAAkB,WAAW,CAAC;AAG3C,MAAM,MAAM,oBAAoB,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAE5F,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpF,wBAAgB,0BAA0B,CAAC,UAAU,EAAE;IACrD,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjC,GAAG,mBAAmB,GAAG,SAAS,CAIlC;AASD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAUnE;
|
|
1
|
+
{"version":3,"file":"parsing.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/parsing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAuC,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC3F,OAAO,EAA6B,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1F,eAAO,MAAM,kBAAkB,WAAW,CAAC;AAG3C,MAAM,MAAM,oBAAoB,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAE5F,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpF,wBAAgB,0BAA0B,CAAC,UAAU,EAAE;IACrD,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjC,GAAG,mBAAmB,GAAG,SAAS,CAIlC;AASD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAUnE;AA0FD,wBAAgB,oBAAoB,CAAC,UAAU,EAAE;IAC/C,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,cAAc,CAAC;CACxB,GAAG,oBAAoB,CAuBvB;AAED,UAAU,wBAAwB;IAChC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,cAAc,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,wBAAwB,GAAG,MAAM,CA2B5E;AAkDD,wBAAgB,eAAe,CAAC,UAAU,EAAE;IAC1C,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChC,MAAM,EAAE,cAAc,CAAC;CACxB,GAAG,eAAe,CAiBlB"}
|
|
@@ -28,10 +28,56 @@ export function buildRepositoryRegex(config) {
|
|
|
28
28
|
.join("|");
|
|
29
29
|
return new RegExp(String.raw `\b(${alternation})\b`);
|
|
30
30
|
}
|
|
31
|
+
// An explicit `Repository: <owner/repo>` (or bare `<repo>`) line is the
|
|
32
|
+
// author's authoritative target: it is the format `create.ts` emits and the
|
|
33
|
+
// one humans use in hand-written tickets. Case-insensitive (`i`) so
|
|
34
|
+
// `repository:` / `REPOSITORY:` are all honored; anchored to a line start so
|
|
35
|
+
// prose that merely contains the word "repository" can't trip it; optional
|
|
36
|
+
// wrapping backticks are tolerated.
|
|
37
|
+
const DECLARED_REPOSITORY_PATTERN = /^[^\S\n]*Repository:[^\S\n]*`?([^\s`]+)`?/im;
|
|
38
|
+
function extractDeclaredRepository(description) {
|
|
39
|
+
return DECLARED_REPOSITORY_PATTERN.exec(description)?.[1];
|
|
40
|
+
}
|
|
41
|
+
// Resolve one candidate name (full `owner/repo` or bare `repo`) against
|
|
42
|
+
// knownRepositories: a bare name canonicalizes to its full entry, a bare name
|
|
43
|
+
// matching several entries is ambiguous, and anything unconfigured is
|
|
44
|
+
// `unknown` (the caller decides whether that WARN+skips or errors). GitHub
|
|
45
|
+
// owners and repository names are case-insensitive, so the match ignores case
|
|
46
|
+
// (a mis-cased declared repo still resolves) while always returning the
|
|
47
|
+
// configured spelling.
|
|
48
|
+
function canonicalizeKnownRepositoryName(name, knownRepositories) {
|
|
49
|
+
const lowerName = name.toLowerCase();
|
|
50
|
+
const candidates = knownRepositories.filter((repo) => {
|
|
51
|
+
const lowerRepo = repo.toLowerCase();
|
|
52
|
+
return lowerRepo === lowerName || lowerRepo.endsWith(`/${lowerName}`);
|
|
53
|
+
});
|
|
54
|
+
if (candidates.length > 1) {
|
|
55
|
+
return { kind: "ambiguous" };
|
|
56
|
+
}
|
|
57
|
+
if (candidates.length === 1) {
|
|
58
|
+
/* v8 ignore next @preserve -- length-1 guarantees [0] defined */
|
|
59
|
+
// oxlint-disable-next-line typescript/no-non-null-assertion -- length-1 guarantees [0] is defined
|
|
60
|
+
return { kind: "canonical", repository: candidates[0] };
|
|
61
|
+
}
|
|
62
|
+
return { kind: "unknown", repository: name };
|
|
63
|
+
}
|
|
31
64
|
function canonicalizeRepositoryMatch(description, config, repositoryRegex) {
|
|
32
65
|
if (description === undefined || description.length === 0) {
|
|
33
66
|
return { kind: "missing" };
|
|
34
67
|
}
|
|
68
|
+
// An explicit `Repository:` line is authoritative — resolve on it alone and
|
|
69
|
+
// never fall through to the whole-description scan. That fall-through is how
|
|
70
|
+
// a task whose real target repo is unconfigured (so it can't be scanned for)
|
|
71
|
+
// gets hijacked by an incidental known-repo mention elsewhere in the body
|
|
72
|
+
// (e.g. a "contrast with X" note). An unconfigured declared repo returns
|
|
73
|
+
// `unknown` so the dispatcher WARN+skips it by name instead of silently
|
|
74
|
+
// running against the wrong worktree. Resolved before the empty-config guard
|
|
75
|
+
// below because canonicalization needs no regex, so an empty
|
|
76
|
+
// knownRepositories must not discard a name the author stated outright.
|
|
77
|
+
const declared = extractDeclaredRepository(description);
|
|
78
|
+
if (declared !== undefined) {
|
|
79
|
+
return canonicalizeKnownRepositoryName(declared, config.workspace.knownRepositories);
|
|
80
|
+
}
|
|
35
81
|
// Guard against an empty knownRepositories config: buildRepositoryRegex
|
|
36
82
|
// would produce /\b()\b/, which matches the empty string at any word
|
|
37
83
|
// boundary and returns a bogus "" match. Treat that as "no repo could
|
|
@@ -44,16 +90,7 @@ function canonicalizeRepositoryMatch(description, config, repositoryRegex) {
|
|
|
44
90
|
if (matched === undefined) {
|
|
45
91
|
return { kind: "missing" };
|
|
46
92
|
}
|
|
47
|
-
|
|
48
|
-
if (candidates.length > 1) {
|
|
49
|
-
return { kind: "ambiguous" };
|
|
50
|
-
}
|
|
51
|
-
if (candidates.length === 1) {
|
|
52
|
-
/* v8 ignore next @preserve -- length-1 guarantees [0] defined */
|
|
53
|
-
// oxlint-disable-next-line typescript/no-non-null-assertion -- length-1 guarantees [0] is defined
|
|
54
|
-
return { kind: "canonical", repository: candidates[0] };
|
|
55
|
-
}
|
|
56
|
-
return { kind: "unknown", repository: matched };
|
|
93
|
+
return canonicalizeKnownRepositoryName(matched, config.workspace.knownRepositories);
|
|
57
94
|
}
|
|
58
95
|
export function resolveRepositoryFor(arguments_) {
|
|
59
96
|
const { description, config } = arguments_;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clipboard-health/groundcrew",
|
|
3
|
-
"version": "4.49.
|
|
3
|
+
"version": "4.49.4",
|
|
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",
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"oxlint": "1.76.0",
|
|
97
97
|
"oxlint-tsgolint": "7.0.2001",
|
|
98
98
|
"syncpack": "15.3.2",
|
|
99
|
-
"vite": "8.
|
|
99
|
+
"vite": "8.2.0",
|
|
100
100
|
"vitest": "4.1.10"
|
|
101
101
|
},
|
|
102
102
|
"engines": {
|