ghostrail 0.18.0 → 0.20.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 +29 -0
- package/dist/agent/claude-code.d.ts +18 -1
- package/dist/agent/claude-code.d.ts.map +1 -1
- package/dist/agent/claude-code.js +36 -4
- package/dist/agent/claude-code.js.map +1 -1
- package/dist/board/page.js +1 -1
- package/dist/cli/commands.d.ts +12 -7
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +261 -43
- package/dist/cli/commands.js.map +1 -1
- package/dist/commands/help.d.ts.map +1 -1
- package/dist/commands/help.js +5 -3
- package/dist/commands/help.js.map +1 -1
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +20 -3
- package/dist/config/load.js.map +1 -1
- package/dist/config/schema.d.ts +57 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +19 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/dashboard/index.d.ts +3 -2
- package/dist/dashboard/index.d.ts.map +1 -1
- package/dist/dashboard/index.js +3 -2
- package/dist/dashboard/index.js.map +1 -1
- package/dist/dashboard/page.d.ts.map +1 -1
- package/dist/dashboard/page.js +39 -3
- package/dist/dashboard/page.js.map +1 -1
- package/dist/dashboard/review-page.d.ts +14 -0
- package/dist/dashboard/review-page.d.ts.map +1 -0
- package/dist/dashboard/review-page.js +256 -0
- package/dist/dashboard/review-page.js.map +1 -0
- package/dist/dashboard/routes.d.ts +18 -0
- package/dist/dashboard/routes.d.ts.map +1 -1
- package/dist/dashboard/routes.js +24 -0
- package/dist/dashboard/routes.js.map +1 -1
- package/dist/dashboard/server.d.ts +19 -0
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +71 -1
- package/dist/dashboard/server.js.map +1 -1
- package/dist/doctor/checks.d.ts +21 -0
- package/dist/doctor/checks.d.ts.map +1 -1
- package/dist/doctor/checks.js +44 -0
- package/dist/doctor/checks.js.map +1 -1
- package/dist/doctor/probes.d.ts +15 -0
- package/dist/doctor/probes.d.ts.map +1 -1
- package/dist/doctor/probes.js +33 -0
- package/dist/doctor/probes.js.map +1 -1
- package/dist/doctor/run.d.ts +2 -1
- package/dist/doctor/run.d.ts.map +1 -1
- package/dist/doctor/run.js +25 -2
- package/dist/doctor/run.js.map +1 -1
- package/dist/factory/build.d.ts +6 -0
- package/dist/factory/build.d.ts.map +1 -1
- package/dist/factory/build.js +17 -5
- package/dist/factory/build.js.map +1 -1
- package/dist/global/tempdir.d.ts +19 -0
- package/dist/global/tempdir.d.ts.map +1 -0
- package/dist/global/tempdir.js +47 -0
- package/dist/global/tempdir.js.map +1 -0
- package/dist/init/greenroom.d.ts +18 -0
- package/dist/init/greenroom.d.ts.map +1 -0
- package/dist/init/greenroom.js +24 -0
- package/dist/init/greenroom.js.map +1 -0
- package/dist/loop/engine.d.ts +9 -0
- package/dist/loop/engine.d.ts.map +1 -1
- package/dist/loop/engine.js +114 -7
- package/dist/loop/engine.js.map +1 -1
- package/dist/loop/index.d.ts +1 -0
- package/dist/loop/index.d.ts.map +1 -1
- package/dist/loop/index.js +1 -0
- package/dist/loop/index.js.map +1 -1
- package/dist/loop/ports.d.ts +7 -0
- package/dist/loop/ports.d.ts.map +1 -1
- package/dist/loop/record.d.ts +6 -1
- package/dist/loop/record.d.ts.map +1 -1
- package/dist/loop/retry.d.ts +50 -0
- package/dist/loop/retry.d.ts.map +1 -0
- package/dist/loop/retry.js +77 -0
- package/dist/loop/retry.js.map +1 -0
- package/dist/loop/schedule.d.ts +33 -0
- package/dist/loop/schedule.d.ts.map +1 -0
- package/dist/loop/schedule.js +28 -0
- package/dist/loop/schedule.js.map +1 -0
- package/dist/respond/authors.d.ts +38 -0
- package/dist/respond/authors.d.ts.map +1 -0
- package/dist/respond/authors.js +50 -0
- package/dist/respond/authors.js.map +1 -0
- package/dist/respond/merge.d.ts.map +1 -1
- package/dist/respond/merge.js +25 -19
- package/dist/respond/merge.js.map +1 -1
- package/dist/respond/respond.d.ts +7 -0
- package/dist/respond/respond.d.ts.map +1 -1
- package/dist/respond/respond.js +36 -16
- package/dist/respond/respond.js.map +1 -1
- package/dist/respond/run-id.d.ts +17 -0
- package/dist/respond/run-id.d.ts.map +1 -0
- package/dist/respond/run-id.js +23 -0
- package/dist/respond/run-id.js.map +1 -0
- package/dist/respond/run-row.d.ts +24 -0
- package/dist/respond/run-row.d.ts.map +1 -0
- package/dist/respond/run-row.js +28 -0
- package/dist/respond/run-row.js.map +1 -0
- package/dist/store/events.d.ts +12 -0
- package/dist/store/events.d.ts.map +1 -1
- package/dist/store/events.js +10 -3
- package/dist/store/events.js.map +1 -1
- package/dist/store/index.d.ts +1 -1
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js.map +1 -1
- package/dist/triage/engine.d.ts +14 -0
- package/dist/triage/engine.d.ts.map +1 -1
- package/dist/triage/engine.js +73 -3
- package/dist/triage/engine.js.map +1 -1
- package/package.json +1 -1
- package/templates/code/ghostrail.toml +4 -0
- package/templates/content/ghostrail.toml +4 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { findRunIdForPr } from "./run-row.js";
|
|
2
|
+
/**
|
|
3
|
+
* The run id of the row a PR already has, or undefined when there is none (or
|
|
4
|
+
* no store to ask). Shared by both respond flows: answering comments and
|
|
5
|
+
* resolving conflicts before a merge are each more work on the item that row
|
|
6
|
+
* is about, not new items (specs/respond-continues-its-run-row.spec.md).
|
|
7
|
+
*
|
|
8
|
+
* Best-effort. A store that cannot be read logs and yields undefined, so the
|
|
9
|
+
* pass records a new row instead of failing over a lookup.
|
|
10
|
+
*/
|
|
11
|
+
export async function findExistingRunId(deps, pr, logger) {
|
|
12
|
+
if (deps.runs === undefined)
|
|
13
|
+
return undefined;
|
|
14
|
+
try {
|
|
15
|
+
return findRunIdForPr(await deps.runs.listRuns(), pr.number);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
19
|
+
logger.warn(`respond #${pr.number}: could not read the run store: ${message}`);
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=run-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-id.js","sourceRoot":"","sources":["../../src/respond/run-id.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9D;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAA0B,EAC1B,EAAsB,EACtB,MAAc;IAEd,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC9C,IAAI,CAAC;QACH,OAAO,cAAc,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IAC/D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,mCAAmC,OAAO,EAAE,CAAC,CAAC;QAC/E,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { RunRow } from "../store/events.js";
|
|
2
|
+
/**
|
|
3
|
+
* Just enough of the run store for respond to find the row a PR already has.
|
|
4
|
+
* A narrow port rather than the whole `RunStore`, so a caller that only reads
|
|
5
|
+
* rows says exactly that.
|
|
6
|
+
*/
|
|
7
|
+
export interface RunLookup {
|
|
8
|
+
listRuns(): Promise<RunRow[]>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The id of the run row that already covers `prNumber`, or undefined when no
|
|
12
|
+
* row does.
|
|
13
|
+
*
|
|
14
|
+
* The fix loop sets `prNumber` on the row when it opens the PR, so this finds
|
|
15
|
+
* the run that produced the pull request. Reusing its id is what makes a
|
|
16
|
+
* respond pass continue that item's row instead of opening a sibling next to
|
|
17
|
+
* it (see specs/respond-continues-its-run-row.spec.md).
|
|
18
|
+
*
|
|
19
|
+
* Several rows can match in a store written before this landed, where each
|
|
20
|
+
* respond pass left a row of its own. The most recently active one wins, and
|
|
21
|
+
* ties fall back to the later position, so the answer is deterministic.
|
|
22
|
+
*/
|
|
23
|
+
export declare function findRunIdForPr(rows: readonly RunRow[], prNumber: number): string | undefined;
|
|
24
|
+
//# sourceMappingURL=run-row.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-row.d.ts","sourceRoot":"","sources":["../../src/respond/run-row.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC/B;AAOD;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAO5F"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** How recently a row was active, for picking between several matches. */
|
|
2
|
+
function lastActivity(row) {
|
|
3
|
+
return row.finishedAt ?? row.startedAt ?? Number.NEGATIVE_INFINITY;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* The id of the run row that already covers `prNumber`, or undefined when no
|
|
7
|
+
* row does.
|
|
8
|
+
*
|
|
9
|
+
* The fix loop sets `prNumber` on the row when it opens the PR, so this finds
|
|
10
|
+
* the run that produced the pull request. Reusing its id is what makes a
|
|
11
|
+
* respond pass continue that item's row instead of opening a sibling next to
|
|
12
|
+
* it (see specs/respond-continues-its-run-row.spec.md).
|
|
13
|
+
*
|
|
14
|
+
* Several rows can match in a store written before this landed, where each
|
|
15
|
+
* respond pass left a row of its own. The most recently active one wins, and
|
|
16
|
+
* ties fall back to the later position, so the answer is deterministic.
|
|
17
|
+
*/
|
|
18
|
+
export function findRunIdForPr(rows, prNumber) {
|
|
19
|
+
let best;
|
|
20
|
+
for (const row of rows) {
|
|
21
|
+
if (row.prNumber !== prNumber)
|
|
22
|
+
continue;
|
|
23
|
+
if (best === undefined || lastActivity(row) >= lastActivity(best))
|
|
24
|
+
best = row;
|
|
25
|
+
}
|
|
26
|
+
return best?.runId;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=run-row.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-row.js","sourceRoot":"","sources":["../../src/respond/run-row.ts"],"names":[],"mappings":"AAWA,0EAA0E;AAC1E,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,SAAS,IAAI,MAAM,CAAC,iBAAiB,CAAC;AACrE,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,IAAuB,EAAE,QAAgB;IACtE,IAAI,IAAwB,CAAC;IAC7B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;YAAE,SAAS;QACxC,IAAI,IAAI,KAAK,SAAS,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC;YAAE,IAAI,GAAG,GAAG,CAAC;IAChF,CAAC;IACD,OAAO,IAAI,EAAE,KAAK,CAAC;AACrB,CAAC"}
|
package/dist/store/events.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a "failed" outcome should be weighed when deciding whether to retry: a
|
|
3
|
+
* `persistent` failure (a red gate, or the agent reporting one) means the
|
|
4
|
+
* agent's own work was wrong and a retry is likely to repeat it; a `transient`
|
|
5
|
+
* one (a provisioning error, a timeout) may just be flakiness and is worth a
|
|
6
|
+
* cheaper allowance. See `loop/retry.ts`.
|
|
7
|
+
*/
|
|
8
|
+
export type FailureKind = "transient" | "persistent";
|
|
1
9
|
/**
|
|
2
10
|
* The append-only event is the source of truth (research Appendix C). A run row
|
|
3
11
|
* is a fold over its events, so a crashed mid-stage run still leaves a trail and
|
|
@@ -53,6 +61,8 @@ export type RunEvent = {
|
|
|
53
61
|
state: string;
|
|
54
62
|
error?: string;
|
|
55
63
|
summary?: string;
|
|
64
|
+
/** Set only when `state` is "failed"; see {@link FailureKind}. */
|
|
65
|
+
failureKind?: FailureKind;
|
|
56
66
|
};
|
|
57
67
|
/** A sink the loop emits run events to. A no-op sink means "don't record". */
|
|
58
68
|
export interface EventSink {
|
|
@@ -100,6 +110,8 @@ export interface RunRow {
|
|
|
100
110
|
error?: string;
|
|
101
111
|
/** The completion comment: blocked questions, a noop's reason, or a done run's summary. */
|
|
102
112
|
summary?: string;
|
|
113
|
+
/** Set only when `state` is "failed"; see {@link FailureKind}. */
|
|
114
|
+
failureKind?: FailureKind;
|
|
103
115
|
artifacts: ArtifactRef[];
|
|
104
116
|
/** Epoch millis of the first and last events seen. */
|
|
105
117
|
startedAt?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/store/events.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAChB;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GACD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACnF;IACE,IAAI,EAAE,gBAAgB,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GACD;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,GACD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjF;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3E;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/store/events.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;AAErD;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAChB;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GACD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACnF;IACE,IAAI,EAAE,gBAAgB,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GACD;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,GACD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjF;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3E;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AAEN,8EAA8E;AAC9E,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAO3F;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,gFAAgF;AAChF,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC,wEAAwE;AACxE,MAAM,WAAW,MAAM;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2FAA2F;IAC3F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,8DAA8D;AAC9D,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAE/C,wFAAwF;AACxF,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAE9D;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,MAAM,CAiD/D;AAED,mDAAmD;AACnD,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,CAE1E"}
|
package/dist/store/events.js
CHANGED
|
@@ -62,12 +62,17 @@ export function applyEvent(row, event) {
|
|
|
62
62
|
next.branch = event.branch;
|
|
63
63
|
break;
|
|
64
64
|
case "agent_finished":
|
|
65
|
+
// Accumulated, not overwritten. A fix-loop or triage run emits exactly
|
|
66
|
+
// one of these, so adding to an absent total yields the same number it
|
|
67
|
+
// always did. A respond pass continuing an item's row (TJ-1665) emits
|
|
68
|
+
// another, and the row should then say what the item has cost in total
|
|
69
|
+
// rather than what its most recent agent run cost.
|
|
65
70
|
if (event.costUsd !== undefined)
|
|
66
|
-
next.costUsd = event.costUsd;
|
|
71
|
+
next.costUsd = (next.costUsd ?? 0) + event.costUsd;
|
|
67
72
|
if (event.tokensIn !== undefined)
|
|
68
|
-
next.tokensIn = event.tokensIn;
|
|
73
|
+
next.tokensIn = (next.tokensIn ?? 0) + event.tokensIn;
|
|
69
74
|
if (event.tokensOut !== undefined)
|
|
70
|
-
next.tokensOut = event.tokensOut;
|
|
75
|
+
next.tokensOut = (next.tokensOut ?? 0) + event.tokensOut;
|
|
71
76
|
break;
|
|
72
77
|
case "gate_step":
|
|
73
78
|
next.gate.push({ name: event.name, exitCode: event.exitCode, durationMs: event.durationMs });
|
|
@@ -85,6 +90,8 @@ export function applyEvent(row, event) {
|
|
|
85
90
|
next.error = event.error;
|
|
86
91
|
if (event.summary !== undefined)
|
|
87
92
|
next.summary = event.summary;
|
|
93
|
+
if (event.failureKind !== undefined)
|
|
94
|
+
next.failureKind = event.failureKind;
|
|
88
95
|
break;
|
|
89
96
|
}
|
|
90
97
|
return next;
|
package/dist/store/events.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/store/events.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/store/events.ts"],"names":[],"mappings":"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"}
|
package/dist/store/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { applyEvent, type ArtifactRef, displayState, emitEvent, emptyRow, type EventSink, foldRun, type GateStepRow, IN_PROGRESS_STATE, ROW_SCHEMA_VERSION, type RunEvent, type RunRow, } from "./events.js";
|
|
1
|
+
export { applyEvent, type ArtifactRef, displayState, emitEvent, emptyRow, type EventSink, type FailureKind, foldRun, type GateStepRow, IN_PROGRESS_STATE, ROW_SCHEMA_VERSION, type RunEvent, type RunRow, } from "./events.js";
|
|
2
2
|
export { FileStore } from "./file-store.js";
|
|
3
3
|
export type { RetentionPolicy, RunFilter, RunStore } from "./port.js";
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,KAAK,WAAW,EAChB,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,KAAK,SAAS,EACd,OAAO,EACP,KAAK,WAAW,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,QAAQ,EACb,KAAK,MAAM,GACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,KAAK,WAAW,EAChB,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,OAAO,EACP,KAAK,WAAW,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,QAAQ,EACb,KAAK,MAAM,GACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/store/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAEV,YAAY,EACZ,SAAS,EACT,QAAQ,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAEV,YAAY,EACZ,SAAS,EACT,QAAQ,EAGR,OAAO,EAEP,iBAAiB,EACjB,kBAAkB,GAGnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/triage/engine.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { Backend } from "../backend/types.js";
|
|
|
2
2
|
import type { GhostrailConfig } from "../config/schema.js";
|
|
3
3
|
import type { GlobalStore } from "../global/store.js";
|
|
4
4
|
import type { Agent, Lock, Logger, TriageSource } from "../loop/ports.js";
|
|
5
|
+
import type { EventSink } from "../store/events.js";
|
|
5
6
|
import { type TriageResult } from "./apply.js";
|
|
6
7
|
/** Path, relative to the workspace root, where the triage agent writes its plan. */
|
|
7
8
|
export declare const TRIAGE_PLAN_PATH = ".ghostrail/triage.json";
|
|
@@ -21,7 +22,20 @@ export interface TriageDeps {
|
|
|
21
22
|
globalStore?: GlobalStore;
|
|
22
23
|
/** Host path to the composed Claude profile, staged into each workspace. */
|
|
23
24
|
claudeProfileDir?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Where run events go, so a triage pass shows up on the board and the
|
|
27
|
+
* dashboard like a fix-loop run does. Absent means "don't record".
|
|
28
|
+
*/
|
|
29
|
+
events?: EventSink;
|
|
24
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* The `kind` a triage row carries, so the board can tell which pass produced
|
|
33
|
+
* it. The fix loop sets no kind, so an absent one keeps meaning "fix loop"
|
|
34
|
+
* and no row already in a store changes meaning.
|
|
35
|
+
*/
|
|
36
|
+
export declare const TRIAGE_RUN_KIND = "triage";
|
|
37
|
+
/** What a finished triage item is worth saying on its row, or undefined for noop. */
|
|
38
|
+
export declare function triageSummary(result: TriageResult): string | undefined;
|
|
25
39
|
/**
|
|
26
40
|
* Run one triage tick: discover issues in the triage queue and, for each (up to
|
|
27
41
|
* the guardrails), claim it, provision a workspace for repo context, run the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/triage/engine.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/triage/engine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,EAAe,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAExE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItD,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAY,MAAM,kBAAkB,CAAC;AACpF,OAAO,KAAK,EAAE,SAAS,EAAY,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,KAAK,YAAY,EAAmB,MAAM,YAAY,CAAC;AAGhE,oFAAoF;AACpF,eAAO,MAAM,gBAAgB,2BAA2B,CAAC;AAKzD,kDAAkD;AAClD,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AA6BD;;;;GAIG;AACH,eAAO,MAAM,eAAe,WAAW,CAAC;AAExC,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAOtE;AAmBD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,gBAAgB,CAAC,CAwB3B"}
|
package/dist/triage/engine.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
1
2
|
import { stageArtifacts } from "../global/stage.js";
|
|
2
3
|
import { branchName } from "../loop/branch.js";
|
|
3
4
|
import { writeCommentThread } from "../loop/comments.js";
|
|
@@ -8,6 +9,45 @@ import { parseTriagePlan } from "./plan.js";
|
|
|
8
9
|
export const TRIAGE_PLAN_PATH = ".ghostrail/triage.json";
|
|
9
10
|
const BRANCH_PREFIX = "triage";
|
|
10
11
|
const nullLogger = { info: () => { }, warn: () => { } };
|
|
12
|
+
/** Emit an event to the sink if present; recording never breaks a pass. */
|
|
13
|
+
async function emitEvent(sink, event) {
|
|
14
|
+
if (sink === undefined)
|
|
15
|
+
return;
|
|
16
|
+
try {
|
|
17
|
+
await sink.emit(event);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// recording is best-effort
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Emit the one `outcome` event that closes out a triage item's row. */
|
|
24
|
+
async function recordOutcome(sink, runId, result) {
|
|
25
|
+
const summary = triageSummary(result);
|
|
26
|
+
await emitEvent(sink, {
|
|
27
|
+
type: "outcome",
|
|
28
|
+
runId,
|
|
29
|
+
ts: Date.now(),
|
|
30
|
+
state: result.state,
|
|
31
|
+
...(result.error === undefined ? {} : { error: result.error }),
|
|
32
|
+
...(summary === undefined ? {} : { summary }),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The `kind` a triage row carries, so the board can tell which pass produced
|
|
37
|
+
* it. The fix loop sets no kind, so an absent one keeps meaning "fix loop"
|
|
38
|
+
* and no row already in a store changes meaning.
|
|
39
|
+
*/
|
|
40
|
+
export const TRIAGE_RUN_KIND = "triage";
|
|
41
|
+
/** What a finished triage item is worth saying on its row, or undefined for noop. */
|
|
42
|
+
export function triageSummary(result) {
|
|
43
|
+
if (result.state !== "split")
|
|
44
|
+
return undefined;
|
|
45
|
+
const created = result.createdIds ?? [];
|
|
46
|
+
const count = `${created.length} sub-issue${created.length === 1 ? "" : "s"}`;
|
|
47
|
+
return created.length === 0
|
|
48
|
+
? `Split into ${count}.`
|
|
49
|
+
: `Split into ${count}: ${created.join(", ")}.`;
|
|
50
|
+
}
|
|
11
51
|
async function readWorkspaceFile(backend, workspace, path) {
|
|
12
52
|
const result = await backend.exec(workspace, ["cat", path]);
|
|
13
53
|
return result.exitCode === 0 ? result.stdout : undefined;
|
|
@@ -51,21 +91,40 @@ export async function triageTick(deps, config) {
|
|
|
51
91
|
}
|
|
52
92
|
async function triageItem(deps, config, prompt, item, logger) {
|
|
53
93
|
let workspace;
|
|
94
|
+
const runId = randomUUID();
|
|
54
95
|
try {
|
|
55
96
|
const claimed = await deps.source.claim(item);
|
|
56
97
|
if (!claimed) {
|
|
98
|
+
// Deliberately before the first event: an item whose claim was lost was
|
|
99
|
+
// never worked, and a row for it would be a run that never happened.
|
|
57
100
|
logger.info(`${item.id}: claim lost, skipping`);
|
|
58
101
|
return { itemId: item.id, state: "noop" };
|
|
59
102
|
}
|
|
103
|
+
await emitEvent(deps.events, {
|
|
104
|
+
type: "claimed",
|
|
105
|
+
runId,
|
|
106
|
+
ts: Date.now(),
|
|
107
|
+
itemId: item.id,
|
|
108
|
+
title: item.title,
|
|
109
|
+
kind: TRIAGE_RUN_KIND,
|
|
110
|
+
});
|
|
60
111
|
const source = config.factory.source;
|
|
112
|
+
const branch = branchName(BRANCH_PREFIX, item.id, item.title);
|
|
61
113
|
workspace = await deps.backend.provision({
|
|
62
114
|
repoPath: source ?? deps.repoPath,
|
|
63
115
|
baseBranch: config.factory.baseBranch,
|
|
64
|
-
branch
|
|
116
|
+
branch,
|
|
65
117
|
...(source === undefined ? {} : { clone: true }),
|
|
66
118
|
...(config.backend.image === undefined ? {} : { image: config.backend.image }),
|
|
67
119
|
...(deps.claudeProfileDir === undefined ? {} : { profileDir: deps.claudeProfileDir }),
|
|
68
120
|
});
|
|
121
|
+
await emitEvent(deps.events, {
|
|
122
|
+
type: "provisioned",
|
|
123
|
+
runId,
|
|
124
|
+
ts: Date.now(),
|
|
125
|
+
backend: config.backend.kind,
|
|
126
|
+
branch,
|
|
127
|
+
});
|
|
69
128
|
if (deps.globalStore !== undefined && config.artifacts.length > 0) {
|
|
70
129
|
await stageArtifacts(deps.backend, workspace, deps.globalStore, config.artifacts, logger);
|
|
71
130
|
}
|
|
@@ -82,13 +141,24 @@ async function triageItem(deps, config, prompt, item, logger) {
|
|
|
82
141
|
agent: agentConfig,
|
|
83
142
|
guardrails: config.guardrails,
|
|
84
143
|
});
|
|
85
|
-
|
|
144
|
+
await emitEvent(deps.events, {
|
|
145
|
+
type: "agent_finished",
|
|
146
|
+
runId,
|
|
147
|
+
ts: Date.now(),
|
|
148
|
+
status: outcome.status,
|
|
149
|
+
...(outcome.costUsd === undefined ? {} : { costUsd: outcome.costUsd }),
|
|
150
|
+
});
|
|
151
|
+
const result = await route(deps, item, workspace, outcome, logger);
|
|
152
|
+
await recordOutcome(deps.events, runId, result);
|
|
153
|
+
return result;
|
|
86
154
|
}
|
|
87
155
|
catch (error) {
|
|
88
156
|
const message = error instanceof Error ? error.message : String(error);
|
|
89
157
|
logger.warn(`${item.id}: triage errored, resetting: ${message}`);
|
|
90
158
|
await ignoreErrors(() => deps.source.reset(item));
|
|
91
|
-
|
|
159
|
+
const result = { itemId: item.id, state: "failed", error: message };
|
|
160
|
+
await recordOutcome(deps.events, runId, result);
|
|
161
|
+
return result;
|
|
92
162
|
}
|
|
93
163
|
finally {
|
|
94
164
|
if (workspace !== undefined) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/triage/engine.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/triage/engine.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -42,6 +42,10 @@ auto_merge = false # a human owns every merge
|
|
|
42
42
|
|
|
43
43
|
[respond] # `ghostrail respond` folds PR + tracker comments back in
|
|
44
44
|
prompt = "prompts/respond.md"
|
|
45
|
+
# Comment authors respond ignores. The Linear integration posts a linkback
|
|
46
|
+
# comment on every PR, and without this it reads as human feedback.
|
|
47
|
+
ignore_authors = ["linear"]
|
|
48
|
+
every = "5m" # how often `watch` runs respond; "off" to exclude
|
|
45
49
|
|
|
46
50
|
[triage] # `ghostrail triage` splits large issues into sub-issues
|
|
47
51
|
prompt = "prompts/triage.md"
|
|
@@ -41,3 +41,7 @@ auto_merge = false
|
|
|
41
41
|
|
|
42
42
|
[respond] # fold PR + tracker feedback back into the draft
|
|
43
43
|
prompt = "prompts/respond.md"
|
|
44
|
+
# Comment authors respond ignores. The Linear integration posts a linkback
|
|
45
|
+
# comment on every PR, and without this it reads as human feedback.
|
|
46
|
+
ignore_authors = ["linear"]
|
|
47
|
+
every = "5m" # how often `watch` runs respond; "off" to exclude
|