@clipboard-health/groundcrew 3.4.1 → 4.0.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.
- package/README.md +252 -298
- package/clearance-allow-hosts +7 -0
- package/crew.config.example.ts +13 -32
- package/dist/commands/cleaner.d.ts.map +1 -1
- package/dist/commands/cleaner.js +1 -5
- package/dist/commands/dispatcher.d.ts.map +1 -1
- package/dist/commands/dispatcher.js +5 -5
- package/dist/commands/eligibility.d.ts +1 -1
- package/dist/commands/eligibility.d.ts.map +1 -1
- package/dist/commands/eligibility.js +4 -4
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +2 -1
- package/dist/commands/setupWorkspace.d.ts.map +1 -1
- package/dist/commands/setupWorkspace.js +1 -2
- package/dist/commands/ticketDoctor.d.ts.map +1 -1
- package/dist/commands/ticketDoctor.js +11 -33
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/lib/adapters/linear/factory.d.ts +10 -14
- package/dist/lib/adapters/linear/factory.d.ts.map +1 -1
- package/dist/lib/adapters/linear/factory.js +23 -63
- package/dist/lib/adapters/linear/schema.d.ts +3 -5
- package/dist/lib/adapters/linear/schema.d.ts.map +1 -1
- package/dist/lib/adapters/linear/schema.js +3 -5
- package/dist/lib/boardSource.d.ts +55 -39
- package/dist/lib/boardSource.d.ts.map +1 -1
- package/dist/lib/boardSource.js +130 -237
- package/dist/lib/config.d.ts +11 -70
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +10 -157
- package/dist/lib/linearIssueStatus.d.ts +0 -4
- package/dist/lib/linearIssueStatus.d.ts.map +1 -1
- package/dist/lib/linearIssueStatus.js +0 -0
- package/dist/lib/ticketSource.d.ts +5 -7
- package/dist/lib/ticketSource.d.ts.map +1 -1
- package/package.json +2 -2
package/clearance-allow-hosts
CHANGED
|
@@ -67,10 +67,17 @@ api.npmjs.org
|
|
|
67
67
|
registry.npmjs.org
|
|
68
68
|
www.npmjs.com
|
|
69
69
|
|
|
70
|
+
# Google APIs
|
|
71
|
+
developers.google.com
|
|
72
|
+
drive.googleapis.com
|
|
73
|
+
forms.googleapis.com
|
|
74
|
+
www.googleapis.com
|
|
75
|
+
|
|
70
76
|
# Developer tooling
|
|
71
77
|
app.terraform.io
|
|
72
78
|
buf.build
|
|
73
79
|
cdn.playwright.dev
|
|
80
|
+
cloud.nx.app
|
|
74
81
|
fastdl.mongodb.org
|
|
75
82
|
formulae.brew.sh
|
|
76
83
|
hub.docker.com
|
package/crew.config.example.ts
CHANGED
|
@@ -2,32 +2,15 @@ import type { Config } from "@clipboard-health/groundcrew";
|
|
|
2
2
|
// import { readFileSync } from "node:fs";
|
|
3
3
|
|
|
4
4
|
export default {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
// orchestrator stays resilient across project renames and across
|
|
15
|
-
// same-name projects in different teams. The leading name segment
|
|
16
|
-
// keeps the file self-documenting at a glance.
|
|
17
|
-
//
|
|
18
|
-
// `statuses` is per-project so multi-team setups with divergent
|
|
19
|
-
// workflow state names (e.g. "Todo" vs "To Do", "Shipped" vs
|
|
20
|
-
// "Done") can coexist. Each field falls back to its default when
|
|
21
|
-
// omitted: { todo: "Todo", inProgress: "In Progress",
|
|
22
|
-
// done: "Done", terminal: ["Done"] }.
|
|
23
|
-
projects: [
|
|
24
|
-
{ projectSlug: "your-project-name-0123456789ab" },
|
|
25
|
-
// {
|
|
26
|
-
// projectSlug: "platform-aaaaaaaaaaaa",
|
|
27
|
-
// statuses: { inProgress: "Doing", done: "Released", terminal: ["Released", "Won't Do"] },
|
|
28
|
-
// },
|
|
29
|
-
],
|
|
30
|
-
},
|
|
5
|
+
// Groundcrew's built-in Linear adapter is implicit and needs no config:
|
|
6
|
+
// it picks up every Linear issue assigned to your API key's viewer that
|
|
7
|
+
// carries an `agent-*` label. There is no project / view / status
|
|
8
|
+
// block — Linear's workflow `state.type` (`unstarted` → todo,
|
|
9
|
+
// `started` → in progress, `completed`/`canceled`/`duplicate` →
|
|
10
|
+
// terminal) is the single source of truth, so renamed columns Just Work.
|
|
11
|
+
//
|
|
12
|
+
// Opt a ticket in: assign it to yourself and add an `agent-<model>`
|
|
13
|
+
// label (e.g. `agent-claude`, `agent-any`).
|
|
31
14
|
workspace: {
|
|
32
15
|
// Parent directory under which groundcrew clones repositories and
|
|
33
16
|
// creates per-ticket worktrees.
|
|
@@ -41,11 +24,10 @@ export default {
|
|
|
41
24
|
// and edit to override.
|
|
42
25
|
//
|
|
43
26
|
// // Additional pluggable ticket sources beyond the implicit built-in
|
|
44
|
-
// // Linear adapter
|
|
45
|
-
// //
|
|
46
|
-
// //
|
|
47
|
-
// //
|
|
48
|
-
// // emit.
|
|
27
|
+
// // Linear adapter. The most common use is `kind: "shell"`, which wires
|
|
28
|
+
// // any external system via command templates that emit/consume JSON.
|
|
29
|
+
// // See the shell adapter's ShellIssue schema for the JSON contract
|
|
30
|
+
// // `fetch` / `resolveOne` must emit.
|
|
49
31
|
// sources: [
|
|
50
32
|
// {
|
|
51
33
|
// kind: "shell",
|
|
@@ -63,7 +45,6 @@ export default {
|
|
|
63
45
|
// git: { remote: "origin", defaultBranch: "main" },
|
|
64
46
|
//
|
|
65
47
|
// orchestrator: {
|
|
66
|
-
// // Shared across all watched projects in linear.projects.
|
|
67
48
|
// maximumInProgress: 4,
|
|
68
49
|
// pollIntervalMilliseconds: 120_000,
|
|
69
50
|
// sessionLimitPercentage: 85,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cleaner.d.ts","sourceRoot":"","sources":["../../src/commands/cleaner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,UAAU,EAA4B,MAAM,uBAAuB,CAAC;AAClF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,KAAK,aAAa,EAAa,MAAM,qBAAqB,CAAC;AAGpE,UAAU,WAAW;IACnB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,CAAC,UAAU,EAAE;QAClB,KAAK,EAAE,UAAU,CAAC;QAClB,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;QAC1C,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"cleaner.d.ts","sourceRoot":"","sources":["../../src/commands/cleaner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,UAAU,EAA4B,MAAM,uBAAuB,CAAC;AAClF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,KAAK,aAAa,EAAa,MAAM,qBAAqB,CAAC;AAGpE,UAAU,WAAW;IACnB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,CAAC,UAAU,EAAE;QAClB,KAAK,EAAE,UAAU,CAAC;QAClB,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;QAC1C,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAkDxD"}
|
package/dist/commands/cleaner.js
CHANGED
|
@@ -12,11 +12,7 @@ export function createCleaner(deps) {
|
|
|
12
12
|
const { config } = deps;
|
|
13
13
|
async function runOnce(arguments_) {
|
|
14
14
|
const { state, worktreeEntries, dryRun, signal } = arguments_;
|
|
15
|
-
|
|
16
|
-
// look like a Linear ticket from another project, leave it alone.
|
|
17
|
-
const terminalTickets = new Set(state.issues
|
|
18
|
-
.filter((issue) => isTerminalStatusForIssue(issue, config))
|
|
19
|
-
.map((issue) => issue.id));
|
|
15
|
+
const terminalTickets = new Set(state.issues.filter((issue) => isTerminalStatusForIssue(issue)).map((issue) => issue.id));
|
|
20
16
|
if (terminalTickets.size === 0) {
|
|
21
17
|
return;
|
|
22
18
|
}
|
|
@@ -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,
|
|
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,EAKhB,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,CAyLjE"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Pure verdict logic lives in `eligibility.ts`; this module is responsible
|
|
7
7
|
* for telemetry, Linear writes, and side-effecting setupWorkspace calls.
|
|
8
8
|
*/
|
|
9
|
-
import { isGroundcrewIssue,
|
|
9
|
+
import { isGroundcrewIssue, isIssueInProgress, isIssueTodo, } from "../lib/boardSource.js";
|
|
10
10
|
import { createLinearIssueStatusUpdater } from "../lib/linearIssueStatus.js";
|
|
11
11
|
import { errorMessage, log, logEvent } from "../lib/util.js";
|
|
12
12
|
import { workspaces } from "../lib/workspaces.js";
|
|
@@ -24,7 +24,7 @@ function logSkip(verdict) {
|
|
|
24
24
|
}
|
|
25
25
|
export function createDispatcher(deps) {
|
|
26
26
|
const { config, client } = deps;
|
|
27
|
-
const issueStatusUpdater = createLinearIssueStatusUpdater({
|
|
27
|
+
const issueStatusUpdater = createLinearIssueStatusUpdater({ client });
|
|
28
28
|
function buildExhaustedSet(usage) {
|
|
29
29
|
const exhausted = new Set();
|
|
30
30
|
for (const exhaustion of classifyUsageExhaustion(config, usage)) {
|
|
@@ -99,11 +99,11 @@ export function createDispatcher(deps) {
|
|
|
99
99
|
children: skip.childCount,
|
|
100
100
|
});
|
|
101
101
|
}
|
|
102
|
-
const activeCount = state.issues.filter((issue) =>
|
|
102
|
+
const activeCount = state.issues.filter((issue) => isIssueInProgress(issue)).length;
|
|
103
103
|
const slots = config.orchestrator.maximumInProgress - activeCount;
|
|
104
104
|
// Narrow Todo to tickets that opted in via an `agent-*` label.
|
|
105
105
|
// Unlabeled tickets are not groundcrew's concern even when in Todo.
|
|
106
|
-
const todo = state.issues.filter((issue) =>
|
|
106
|
+
const todo = state.issues.filter((issue) => isIssueTodo(issue) && isGroundcrewIssue(issue));
|
|
107
107
|
if (slots <= 0) {
|
|
108
108
|
log(`At capacity (${activeCount}/${config.orchestrator.maximumInProgress}), no new work to start${idleSuffix}`);
|
|
109
109
|
return;
|
|
@@ -114,7 +114,7 @@ export function createDispatcher(deps) {
|
|
|
114
114
|
}
|
|
115
115
|
// Run the blocker pre-pass first so an all-blocked board short-circuits
|
|
116
116
|
// before the codexbar HTTP call and the cmux/tmux shell-out fire.
|
|
117
|
-
const { unblocked, skips: blockerSkips } = classifyBlockers(
|
|
117
|
+
const { unblocked, skips: blockerSkips } = classifyBlockers(todo);
|
|
118
118
|
for (const skip of blockerSkips) {
|
|
119
119
|
logSkip(skip);
|
|
120
120
|
}
|
|
@@ -88,7 +88,7 @@ export declare function classifyUsageExhaustion(config: ResolvedConfig, usage: U
|
|
|
88
88
|
* workspace adapter, so a board where every Todo is blocked short-circuits
|
|
89
89
|
* without paying for either.
|
|
90
90
|
*/
|
|
91
|
-
export declare function classifyBlockers(
|
|
91
|
+
export declare function classifyBlockers(todo: readonly GroundcrewIssue[]): BlockerClassification;
|
|
92
92
|
/**
|
|
93
93
|
* Eligibility verdicts for already-unblocked Todo issues — handles
|
|
94
94
|
* agent-any resolution, session exhaustion, worktree/workspace recovery,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eligibility.d.ts","sourceRoot":"","sources":["../../src/commands/eligibility.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOzD,KAAK,UAAU,GACX,SAAS,GACT,oBAAoB,GACpB,oBAAoB,GACpB,iBAAiB,GACjB,4BAA4B,GAC5B,mBAAmB,CAAC;AAExB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,eAAe,CAAC;IACvB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,WAAW,EAAE,UAAU,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,OAAO,GAAG,YAAY,GAAG,WAAW,CAAC;AAE1C,MAAM,MAAM,oBAAoB,GAC5B;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEN,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,cAAc,CAAC;IACvB;;;;;OAKG;IACH,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,cAAc,EAAE,cAAc,CAAC;IAC/B,KAAK,EAAE,YAAY,CAAC;IACpB,oDAAoD;IACpD,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,UAAU,qBAAqB;IAC7B,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"eligibility.d.ts","sourceRoot":"","sources":["../../src/commands/eligibility.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOzD,KAAK,UAAU,GACX,SAAS,GACT,oBAAoB,GACpB,oBAAoB,GACpB,iBAAiB,GACjB,4BAA4B,GAC5B,mBAAmB,CAAC;AAExB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,eAAe,CAAC;IACvB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,WAAW,EAAE,UAAU,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,OAAO,GAAG,YAAY,GAAG,WAAW,CAAC;AAE1C,MAAM,MAAM,oBAAoB,GAC5B;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEN,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,cAAc,CAAC;IACvB;;;;;OAKG;IACH,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,cAAc,EAAE,cAAc,CAAC;IAC/B,KAAK,EAAE,YAAY,CAAC;IACpB,oDAAoD;IACpD,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,UAAU,qBAAqB;IAC7B,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAgCD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GACrB,MAAM,GAAG,SAAS,CAepB;AAaD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,YAAY,GAClB,oBAAoB,EAAE,CAmCxB;AA4CD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,eAAe,EAAE,GAAG,qBAAqB,CAYxF;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,EAAE,CAgE5E"}
|
|
@@ -15,7 +15,7 @@ const MINUTES_PER_WEEK = DAYS_PER_WEEK * MINUTES_PER_DAY;
|
|
|
15
15
|
function blockerSummary(blocker) {
|
|
16
16
|
return `${blocker.id}:${blocker.status ?? "missing"}`;
|
|
17
17
|
}
|
|
18
|
-
function blockerVerdictFor(issue
|
|
18
|
+
function blockerVerdictFor(issue) {
|
|
19
19
|
if (issue.hasMoreBlockers) {
|
|
20
20
|
const blockers = issue.blockers.map(blockerSummary);
|
|
21
21
|
return {
|
|
@@ -26,7 +26,7 @@ function blockerVerdictFor(issue, config) {
|
|
|
26
26
|
blockers,
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
|
-
const unresolved = issue.blockers.filter((blocker) => !isTerminalStatusForBlocker(blocker
|
|
29
|
+
const unresolved = issue.blockers.filter((blocker) => !isTerminalStatusForBlocker(blocker));
|
|
30
30
|
if (unresolved.length === 0) {
|
|
31
31
|
return undefined;
|
|
32
32
|
}
|
|
@@ -138,11 +138,11 @@ function classifyRecovery(arguments_) {
|
|
|
138
138
|
* workspace adapter, so a board where every Todo is blocked short-circuits
|
|
139
139
|
* without paying for either.
|
|
140
140
|
*/
|
|
141
|
-
export function classifyBlockers(
|
|
141
|
+
export function classifyBlockers(todo) {
|
|
142
142
|
const unblocked = [];
|
|
143
143
|
const skips = [];
|
|
144
144
|
for (const issue of todo) {
|
|
145
|
-
const verdict = blockerVerdictFor(issue
|
|
145
|
+
const verdict = blockerVerdictFor(issue);
|
|
146
146
|
if (verdict === undefined) {
|
|
147
147
|
unblocked.push(issue);
|
|
148
148
|
}
|
|
@@ -1 +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,
|
|
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,CAiBjE"}
|
package/dist/commands/init.js
CHANGED
|
@@ -39,8 +39,9 @@ export async function initConfigCli(argv) {
|
|
|
39
39
|
writeOutput("");
|
|
40
40
|
writeOutput("Next steps:");
|
|
41
41
|
writeOutput(` - Edit ${result.destination}`);
|
|
42
|
-
writeOutput(" - Set
|
|
42
|
+
writeOutput(" - Set workspace.projectDir, workspace.knownRepositories");
|
|
43
43
|
writeOutput(" - Export GROUNDCREW_LINEAR_API_KEY (or LINEAR_API_KEY)");
|
|
44
|
+
writeOutput(" - Assign Linear tickets to yourself and add an agent-* label to opt them in");
|
|
44
45
|
writeOutput(" - Verify with `crew doctor`");
|
|
45
46
|
}
|
|
46
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/setupWorkspace.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAenE,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAWD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAqBD,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,qBAAqB,EAC9B,UAAU,GAAE,wBAA6B,GACxC,OAAO,CAAC,IAAI,CAAC,CA6Gf;AAwHD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"setupWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/setupWorkspace.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAenE,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAWD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAqBD,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,qBAAqB,EAC9B,UAAU,GAAE,wBAA6B,GACxC,OAAO,CAAC,IAAI,CAAC,CA6Gf;AAwHD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAAC,IAAI,CAAC,CAoBf"}
|
|
@@ -237,10 +237,9 @@ export async function setupWorkspaceCli(ticket, options = {}) {
|
|
|
237
237
|
model: resolved.model,
|
|
238
238
|
details: { title: resolved.title, description: resolved.description },
|
|
239
239
|
});
|
|
240
|
-
await createLinearIssueStatusUpdater({
|
|
240
|
+
await createLinearIssueStatusUpdater({ client }).markInProgress({
|
|
241
241
|
id: ticket.toLowerCase(),
|
|
242
242
|
uuid: resolved.uuid,
|
|
243
243
|
teamId: resolved.teamId,
|
|
244
|
-
projectSlugId: resolved.projectSlugId,
|
|
245
244
|
});
|
|
246
245
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ticketDoctor.d.ts","sourceRoot":"","sources":["../../src/commands/ticketDoctor.ts"],"names":[],"mappings":"AAoBA,OAAO,
|
|
1
|
+
{"version":3,"file":"ticketDoctor.d.ts","sourceRoot":"","sources":["../../src/commands/ticketDoctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
// are skipped — they describe pre-dispatch state that no longer matters.
|
|
17
17
|
import { existsSync } from "node:fs";
|
|
18
18
|
import { join } from "node:path";
|
|
19
|
-
import { fetchBlockersForTicket, fetchInProgressIssueCount, fetchRawLinearIssue, resolveModelFor, resolveRepositoryFor, } from "../lib/boardSource.js";
|
|
19
|
+
import { fetchBlockersForTicket, fetchInProgressIssueCount, fetchRawLinearIssue, isTerminalStateType, resolveModelFor, resolveRepositoryFor, } from "../lib/boardSource.js";
|
|
20
20
|
import { runCommandAsync } from "../lib/commandRunner.js";
|
|
21
21
|
import { resolveDefaultBranch } from "../lib/defaultBranch.js";
|
|
22
|
-
import { AGENT_ANY_MODEL,
|
|
22
|
+
import { AGENT_ANY_MODEL, loadConfig } from "../lib/config.js";
|
|
23
23
|
import { which } from "../lib/host.js";
|
|
24
24
|
import { readRunState } from "../lib/runState.js";
|
|
25
25
|
import { getUsageByModel } from "../lib/usage.js";
|
|
@@ -282,14 +282,14 @@ async function runEligibilityChecks(arguments_) {
|
|
|
282
282
|
assignee: "",
|
|
283
283
|
updatedAt: "",
|
|
284
284
|
teamId: raw.teamId,
|
|
285
|
-
/* v8 ignore next @preserve --
|
|
286
|
-
|
|
285
|
+
/* v8 ignore next @preserve -- fetchRawLinearIssue always populates stateType (defaults to "") so the ?? guard is belt-and-suspenders */
|
|
286
|
+
stateType: raw.stateType ?? "",
|
|
287
287
|
repository: resolvedRepository,
|
|
288
288
|
model: resolvedModel,
|
|
289
289
|
blockers: [...blockers],
|
|
290
290
|
hasMoreBlockers: raw.hasMoreBlockers,
|
|
291
291
|
};
|
|
292
|
-
const blockerClassification = classifyBlockers(
|
|
292
|
+
const blockerClassification = classifyBlockers([groundcrewIssue]);
|
|
293
293
|
const [firstSkip] = blockerClassification.skips;
|
|
294
294
|
if (firstSkip !== undefined) {
|
|
295
295
|
if (firstSkip.eventReason === "blockers_paginated") {
|
|
@@ -386,35 +386,13 @@ async function probeLinear(deps, upperTicket) {
|
|
|
386
386
|
}
|
|
387
387
|
try {
|
|
388
388
|
const raw = await deps.fetchRawIssue({ ticket: upperTicket });
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
if (project === undefined) {
|
|
393
|
-
const configured = deps.config.linear.projects.map((entry) => entry.slugId).join(", ");
|
|
394
|
-
const detail = raw.projectSlugId === undefined
|
|
395
|
-
? `ticket has no associated Linear project; configure linear.projects (${configured})`
|
|
396
|
-
: `project slugId "${raw.projectSlugId}" is not in linear.projects (configured: ${configured})`;
|
|
397
|
-
return {
|
|
398
|
-
linearStatus: { kind: "unresolvable", reason: detail },
|
|
399
|
-
resolution: [
|
|
400
|
-
{ name: "Ticket exists in Linear", status: "ok", detail: `"${raw.title}"` },
|
|
401
|
-
{
|
|
402
|
-
name: "Project is configured",
|
|
403
|
-
status: "fail",
|
|
404
|
-
detail,
|
|
405
|
-
failureSummary: detail,
|
|
406
|
-
},
|
|
407
|
-
],
|
|
408
|
-
title: raw.title,
|
|
409
|
-
raw,
|
|
410
|
-
};
|
|
411
|
-
}
|
|
412
|
-
const isTerminal = project.statuses.terminal.includes(raw.stateName);
|
|
413
|
-
const todoState = project.statuses.todo;
|
|
389
|
+
/* v8 ignore next @preserve -- fetchRawLinearIssue always populates stateType (defaults to "") so the ?? guard is belt-and-suspenders */
|
|
390
|
+
const stateType = raw.stateType ?? "";
|
|
391
|
+
const isTerminal = isTerminalStateType(stateType);
|
|
414
392
|
const resolution = [
|
|
415
393
|
{ name: "Ticket exists in Linear", status: "ok", detail: `"${raw.title}"` },
|
|
416
394
|
];
|
|
417
|
-
if (
|
|
395
|
+
if (stateType === "unstarted") {
|
|
418
396
|
resolution.push({ name: "Status is Todo", status: "ok" });
|
|
419
397
|
}
|
|
420
398
|
else {
|
|
@@ -422,7 +400,7 @@ async function probeLinear(deps, upperTicket) {
|
|
|
422
400
|
name: "Status is Todo",
|
|
423
401
|
status: "fail",
|
|
424
402
|
detail: `current: ${raw.stateName}`,
|
|
425
|
-
failureSummary: `status is ${raw.stateName} (need
|
|
403
|
+
failureSummary: `status is ${raw.stateName} (state.type=${stateType}, need unstarted)`,
|
|
426
404
|
});
|
|
427
405
|
}
|
|
428
406
|
return {
|
|
@@ -986,7 +964,7 @@ export async function runTicketDoctor(parsed) {
|
|
|
986
964
|
fetchRawIssue,
|
|
987
965
|
fetchBlockersFor: async ({ ticket, uuid }) => await fetchBlockersForTicket({ client: linearClient(), ticket, uuid }),
|
|
988
966
|
fetchUsage: async () => await getUsageByModel(config),
|
|
989
|
-
countInProgress: async () => await fetchInProgressIssueCount({ client: linearClient()
|
|
967
|
+
countInProgress: async () => await fetchInProgressIssueCount({ client: linearClient() }),
|
|
990
968
|
findWorktree: (ticket) => worktrees.findByTicket(config, ticket)[0],
|
|
991
969
|
probeWorkspaces: async () => await workspaces.probe(config),
|
|
992
970
|
workspaceAccessHint: async (name) => await workspaces.accessHint(config, name),
|
package/dist/index.d.ts
CHANGED
|
@@ -5,10 +5,10 @@ export { interruptWorkspace, type InterruptWorkspaceOptions, } from "./commands/
|
|
|
5
5
|
export { orchestrate, type OrchestratorOptions } from "./commands/orchestrator.ts";
|
|
6
6
|
export { resumeWorkspace, type ResumeWorkspaceOptions } from "./commands/resumeWorkspace.ts";
|
|
7
7
|
export { setupWorkspace, type SetupWorkspaceOptions } from "./commands/setupWorkspace.ts";
|
|
8
|
-
export type { Config, ModelDefinition,
|
|
9
|
-
export {
|
|
8
|
+
export type { Config, ModelDefinition, ResolvedConfig, SourceConfig } from "./lib/config.ts";
|
|
9
|
+
export { loadConfig } from "./lib/config.ts";
|
|
10
10
|
export { readRunState, recordRunState, removeRunState, runStateDirectory, runStatePath, updateRunState, type RunLifecycleState, type RunState, } from "./lib/runState.ts";
|
|
11
|
-
export { fetchBlockersForTicket, fetchInProgressIssueCount, fetchRawLinearIssue, fetchResolvedIssue, isTerminalStatusForBlocker, isTerminalStatusForIssue,
|
|
11
|
+
export { fetchBlockersForTicket, fetchInProgressIssueCount, fetchRawLinearIssue, fetchResolvedIssue, isIssueInProgress, isIssueTodo, isTerminalStateType, isTerminalStatusForBlocker, isTerminalStatusForIssue, resolveModelFor, resolveRepositoryFor, type ModelResolution, type RawLinearIssue, type RepositoryResolution, } from "./lib/boardSource.ts";
|
|
12
12
|
export { getUsageByModel, type UsageByModel } from "./lib/usage.ts";
|
|
13
13
|
export { type Board, createBoard } from "./lib/board.ts";
|
|
14
14
|
export { buildSources, buildSourcesWith } from "./lib/buildSources.ts";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAChG,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,GAC/B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC1F,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAChG,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,GAC/B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC1F,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACL,YAAY,EACZ,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,QAAQ,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,EACX,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACxB,eAAe,EACf,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,KAAK,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACvE,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EACL,eAAe,EACf,KAAK,aAAa,EAClB,aAAa,EACb,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,oBAAoB,EACpB,KAAK,OAAO,IAAI,gBAAgB,EAChC,KAAK,UAAU,IAAI,mBAAmB,EACtC,KAAK,eAAe,EACpB,KAAK,eAAe,IAAI,wBAAwB,EAChD,KAAK,KAAK,IAAI,cAAc,EAC5B,iBAAiB,IAAI,0BAA0B,EAC/C,KAAK,YAAY,GAClB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EACL,YAAY,EACZ,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,4BAA4B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,9 +5,9 @@ export { interruptWorkspace, } from "./commands/interruptWorkspace.js";
|
|
|
5
5
|
export { orchestrate } from "./commands/orchestrator.js";
|
|
6
6
|
export { resumeWorkspace } from "./commands/resumeWorkspace.js";
|
|
7
7
|
export { setupWorkspace } from "./commands/setupWorkspace.js";
|
|
8
|
-
export {
|
|
8
|
+
export { loadConfig } from "./lib/config.js";
|
|
9
9
|
export { readRunState, recordRunState, removeRunState, runStateDirectory, runStatePath, updateRunState, } from "./lib/runState.js";
|
|
10
|
-
export { fetchBlockersForTicket, fetchInProgressIssueCount, fetchRawLinearIssue, fetchResolvedIssue, isTerminalStatusForBlocker, isTerminalStatusForIssue,
|
|
10
|
+
export { fetchBlockersForTicket, fetchInProgressIssueCount, fetchRawLinearIssue, fetchResolvedIssue, isIssueInProgress, isIssueTodo, isTerminalStateType, isTerminalStatusForBlocker, isTerminalStatusForIssue, resolveModelFor, resolveRepositoryFor, } from "./lib/boardSource.js";
|
|
11
11
|
export { getUsageByModel } from "./lib/usage.js";
|
|
12
12
|
export { createBoard } from "./lib/board.js";
|
|
13
13
|
export { buildSources, buildSourcesWith } from "./lib/buildSources.js";
|
|
@@ -1,27 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Linear `TicketSource` factory. Wraps the existing boardSource.ts machinery
|
|
3
3
|
* (createBoardSource, fetchResolvedIssue, createLinearIssueStatusUpdater) and
|
|
4
|
-
* converts the
|
|
5
|
-
*
|
|
4
|
+
* converts the Linear-native `Issue`/`Blocker` shapes into the canonical
|
|
5
|
+
* `Issue`/`Blocker` shapes consumers (via `Board`) speak.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* `isTerminalStatusForBlocker` behavior.
|
|
7
|
+
* Status mapping is driven entirely by Linear's workflow `state.type`
|
|
8
|
+
* (`unstarted` → todo, `started` → in-progress,
|
|
9
|
+
* `completed`/`canceled`/`duplicate` → done) so renamed columns are classified
|
|
10
|
+
* correctly without any per-team config.
|
|
12
11
|
*
|
|
13
12
|
* Description is not populated on `fetch()` Issues (boardSource's snapshot
|
|
14
13
|
* doesn't include it); `resolveOne()` Issues carry the full description
|
|
15
|
-
* because `fetchResolvedIssue` fetches it explicitly.
|
|
16
|
-
* description onto the board snapshot when it refactors setupWorkspace.
|
|
14
|
+
* because `fetchResolvedIssue` fetches it explicitly.
|
|
17
15
|
*/
|
|
18
16
|
import type { AdapterContext } from "../../adapterDefinition.ts";
|
|
19
|
-
import { type
|
|
20
|
-
import { type ResolvedProjectConfig } from "../../config.ts";
|
|
17
|
+
import { type Issue as LinearIssue } from "../../boardSource.ts";
|
|
21
18
|
import type { CanonicalStatus, Issue as CanonicalIssue, TicketSource } from "../../ticketSource.ts";
|
|
22
19
|
import type { LinearAdapterConfig } from "./schema.ts";
|
|
23
|
-
export declare function
|
|
24
|
-
export declare function
|
|
25
|
-
export declare function toCanonicalIssue(linearIssue: LinearIssue, globalConfig: AdapterContext["globalConfig"], sourceName: string): CanonicalIssue;
|
|
20
|
+
export declare function canonicalStatusFromStateType(stateType: string | undefined): CanonicalStatus;
|
|
21
|
+
export declare function toCanonicalIssue(linearIssue: LinearIssue, sourceName: string): CanonicalIssue;
|
|
26
22
|
export declare function createLinearTicketSource(config: LinearAdapterConfig, context: AdapterContext): TicketSource;
|
|
27
23
|
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/factory.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAIL,KAAK,KAAK,IAAI,WAAW,EAE1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAEV,eAAe,EACf,KAAK,IAAI,cAAc,EACvB,YAAY,EACb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AASvD,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,eAAe,CAW3F;AAUD,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,CA6Dd"}
|
|
@@ -1,78 +1,45 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Linear `TicketSource` factory. Wraps the existing boardSource.ts machinery
|
|
3
3
|
* (createBoardSource, fetchResolvedIssue, createLinearIssueStatusUpdater) and
|
|
4
|
-
* converts the
|
|
5
|
-
*
|
|
4
|
+
* converts the Linear-native `Issue`/`Blocker` shapes into the canonical
|
|
5
|
+
* `Issue`/`Blocker` shapes consumers (via `Board`) speak.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* `isTerminalStatusForBlocker` behavior.
|
|
7
|
+
* Status mapping is driven entirely by Linear's workflow `state.type`
|
|
8
|
+
* (`unstarted` → todo, `started` → in-progress,
|
|
9
|
+
* `completed`/`canceled`/`duplicate` → done) so renamed columns are classified
|
|
10
|
+
* correctly without any per-team config.
|
|
12
11
|
*
|
|
13
12
|
* Description is not populated on `fetch()` Issues (boardSource's snapshot
|
|
14
13
|
* doesn't include it); `resolveOne()` Issues carry the full description
|
|
15
|
-
* because `fetchResolvedIssue` fetches it explicitly.
|
|
16
|
-
* description onto the board snapshot when it refactors setupWorkspace.
|
|
14
|
+
* because `fetchResolvedIssue` fetches it explicitly.
|
|
17
15
|
*/
|
|
18
|
-
import { createBoardSource, fetchResolvedIssue,
|
|
19
|
-
import { findProjectBySlugId } from "../../config.js";
|
|
16
|
+
import { createBoardSource, fetchResolvedIssue, isTerminalStateType, } from "../../boardSource.js";
|
|
20
17
|
import { createLinearIssueStatusUpdater } from "../../linearIssueStatus.js";
|
|
21
18
|
import { getLinearClient } from "../../util.js";
|
|
22
|
-
export function
|
|
23
|
-
if (
|
|
19
|
+
export function canonicalStatusFromStateType(stateType) {
|
|
20
|
+
if (stateType === "unstarted") {
|
|
24
21
|
return "todo";
|
|
25
22
|
}
|
|
26
|
-
if (
|
|
23
|
+
if (stateType === "started") {
|
|
27
24
|
return "in-progress";
|
|
28
25
|
}
|
|
29
|
-
if (
|
|
30
|
-
return "done";
|
|
31
|
-
}
|
|
32
|
-
if (project.statuses.terminal.includes(nativeStatus)) {
|
|
26
|
+
if (isTerminalStateType(stateType)) {
|
|
33
27
|
return "done";
|
|
34
28
|
}
|
|
35
29
|
return "other";
|
|
36
30
|
}
|
|
37
|
-
|
|
38
|
-
if (blocker.status === undefined) {
|
|
39
|
-
return "other";
|
|
40
|
-
}
|
|
41
|
-
// Terminal first — handles off-config blockers via the union fallback that
|
|
42
|
-
// isTerminalStatusForBlocker already implements.
|
|
43
|
-
if (isTerminalStatusForBlocker(blocker, globalConfig)) {
|
|
44
|
-
return "done";
|
|
45
|
-
}
|
|
46
|
-
// Non-terminal: if the blocker's project is configured, use its statuses to
|
|
47
|
-
// distinguish todo vs in-progress. For off-config blockers we collapse to
|
|
48
|
-
// "other" — eligibility only cares whether the blocker is terminal, so the
|
|
49
|
-
// distinction is informational at most.
|
|
50
|
-
if (blocker.projectSlugId !== undefined) {
|
|
51
|
-
const project = findProjectBySlugId(globalConfig, blocker.projectSlugId);
|
|
52
|
-
if (project !== undefined) {
|
|
53
|
-
return canonicalStatusForProject(blocker.status, project);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return "other";
|
|
57
|
-
}
|
|
58
|
-
function toCanonicalBlocker(blocker, globalConfig, sourceName) {
|
|
31
|
+
function toCanonicalBlocker(blocker, sourceName) {
|
|
59
32
|
return {
|
|
60
33
|
id: `${sourceName}:${blocker.id}`,
|
|
61
34
|
title: blocker.title,
|
|
62
|
-
status:
|
|
35
|
+
status: canonicalStatusFromStateType(blocker.stateType),
|
|
63
36
|
};
|
|
64
37
|
}
|
|
65
|
-
export function toCanonicalIssue(linearIssue,
|
|
66
|
-
const project = findProjectBySlugId(globalConfig, linearIssue.projectSlugId);
|
|
67
|
-
/* v8 ignore next 5 @preserve -- fetchBoard's slugId filter and issueStatusBelongsToOwnProject guarantee project is configured by the time we get here */
|
|
68
|
-
if (project === undefined) {
|
|
69
|
-
throw new Error(`Linear adapter: issue ${linearIssue.id} carries unknown projectSlugId "${linearIssue.projectSlugId}"`);
|
|
70
|
-
}
|
|
38
|
+
export function toCanonicalIssue(linearIssue, sourceName) {
|
|
71
39
|
const sourceRef = {
|
|
72
40
|
uuid: linearIssue.uuid,
|
|
73
41
|
statusId: linearIssue.statusId,
|
|
74
42
|
teamId: linearIssue.teamId,
|
|
75
|
-
projectSlugId: linearIssue.projectSlugId,
|
|
76
43
|
nativeStatus: linearIssue.status,
|
|
77
44
|
};
|
|
78
45
|
return {
|
|
@@ -81,12 +48,12 @@ export function toCanonicalIssue(linearIssue, globalConfig, sourceName) {
|
|
|
81
48
|
title: linearIssue.title,
|
|
82
49
|
// Board snapshot doesn't carry description; resolveOne() populates it.
|
|
83
50
|
description: "",
|
|
84
|
-
status:
|
|
51
|
+
status: canonicalStatusFromStateType(linearIssue.stateType),
|
|
85
52
|
repository: linearIssue.repository,
|
|
86
53
|
model: linearIssue.model,
|
|
87
54
|
assignee: linearIssue.assignee,
|
|
88
55
|
updatedAt: linearIssue.updatedAt,
|
|
89
|
-
blockers: linearIssue.blockers.map((b) => toCanonicalBlocker(b,
|
|
56
|
+
blockers: linearIssue.blockers.map((b) => toCanonicalBlocker(b, sourceName)),
|
|
90
57
|
hasMoreBlockers: linearIssue.hasMoreBlockers,
|
|
91
58
|
sourceRef,
|
|
92
59
|
};
|
|
@@ -96,7 +63,7 @@ export function createLinearTicketSource(config, context) {
|
|
|
96
63
|
const { globalConfig } = context;
|
|
97
64
|
const client = getLinearClient();
|
|
98
65
|
const boardSource = createBoardSource({ config: globalConfig, client });
|
|
99
|
-
const issueStatusUpdater = createLinearIssueStatusUpdater({
|
|
66
|
+
const issueStatusUpdater = createLinearIssueStatusUpdater({ client });
|
|
100
67
|
return {
|
|
101
68
|
name: sourceName,
|
|
102
69
|
async verify() {
|
|
@@ -104,23 +71,18 @@ export function createLinearTicketSource(config, context) {
|
|
|
104
71
|
},
|
|
105
72
|
async fetch() {
|
|
106
73
|
const state = await boardSource.fetch();
|
|
107
|
-
return state.issues.map((linearIssue) => toCanonicalIssue(linearIssue,
|
|
74
|
+
return state.issues.map((linearIssue) => toCanonicalIssue(linearIssue, sourceName));
|
|
108
75
|
},
|
|
109
76
|
async resolveOne(naturalId) {
|
|
110
|
-
// fetchResolvedIssue throws on
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
//
|
|
77
|
+
// fetchResolvedIssue throws on missing repo; we let those propagate.
|
|
78
|
+
// Returning `undefined` is reserved for "ticket genuinely doesn't
|
|
79
|
+
// exist," which fetchResolvedIssue surfaces as an Error too — for now
|
|
80
|
+
// we let any error bubble up rather than swallow.
|
|
114
81
|
const resolved = await fetchResolvedIssue({
|
|
115
82
|
client,
|
|
116
83
|
config: globalConfig,
|
|
117
84
|
ticket: naturalId,
|
|
118
85
|
});
|
|
119
|
-
const project = findProjectBySlugId(globalConfig, resolved.projectSlugId);
|
|
120
|
-
/* v8 ignore next 5 @preserve -- fetchResolvedIssue already throws UnknownProjectError before reaching this guard */
|
|
121
|
-
if (project === undefined) {
|
|
122
|
-
throw new Error(`Linear adapter: resolved issue ${naturalId} carries unknown projectSlugId "${resolved.projectSlugId}"`);
|
|
123
|
-
}
|
|
124
86
|
// fetchResolvedIssue doesn't return the native status name (it's
|
|
125
87
|
// already been resolved through workflow state lookup). We surface
|
|
126
88
|
// "other" until the consumer needs the canonical status, which is fine
|
|
@@ -129,7 +91,6 @@ export function createLinearTicketSource(config, context) {
|
|
|
129
91
|
uuid: resolved.uuid,
|
|
130
92
|
statusId: "",
|
|
131
93
|
teamId: resolved.teamId,
|
|
132
|
-
projectSlugId: resolved.projectSlugId,
|
|
133
94
|
nativeStatus: "",
|
|
134
95
|
};
|
|
135
96
|
return {
|
|
@@ -154,7 +115,6 @@ export function createLinearTicketSource(config, context) {
|
|
|
154
115
|
id: issue.id,
|
|
155
116
|
uuid: ref.uuid,
|
|
156
117
|
teamId: ref.teamId,
|
|
157
|
-
projectSlugId: ref.projectSlugId,
|
|
158
118
|
});
|
|
159
119
|
},
|
|
160
120
|
};
|