@bluewombat/runtime 0.8.0 → 0.10.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 +236 -142
- package/SPECS.md +138 -97
- package/dist/cli.js +35 -37
- package/dist/cli.js.map +1 -1
- package/dist/config/agent-shorthand.d.ts +24 -4
- package/dist/config/agent-shorthand.d.ts.map +1 -1
- package/dist/config/agent-shorthand.js +65 -28
- package/dist/config/agent-shorthand.js.map +1 -1
- package/dist/config/defaults.d.ts +0 -2
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +0 -2
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/find-config.d.ts +3 -2
- package/dist/config/find-config.d.ts.map +1 -1
- package/dist/config/find-config.js +4 -4
- package/dist/config/find-config.js.map +1 -1
- package/dist/config/home.d.ts +2 -0
- package/dist/config/home.d.ts.map +1 -1
- package/dist/config/home.js +4 -2
- package/dist/config/home.js.map +1 -1
- package/dist/config/load-config.d.ts +2 -2
- package/dist/config/load-config.d.ts.map +1 -1
- package/dist/config/load-config.js +342 -73
- package/dist/config/load-config.js.map +1 -1
- package/dist/config/parse-args.d.ts +1 -1
- package/dist/config/parse-args.d.ts.map +1 -1
- package/dist/config/parse-args.js +132 -103
- package/dist/config/parse-args.js.map +1 -1
- package/dist/config/types.d.ts +142 -38
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +13 -1
- package/dist/config/types.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/loop/authority.d.ts +41 -5
- package/dist/loop/authority.d.ts.map +1 -1
- package/dist/loop/authority.js +68 -24
- package/dist/loop/authority.js.map +1 -1
- package/dist/loop/context.d.ts +23 -3
- package/dist/loop/context.d.ts.map +1 -1
- package/dist/loop/deliveries.d.ts +16 -16
- package/dist/loop/deliveries.d.ts.map +1 -1
- package/dist/loop/deliveries.js +35 -187
- package/dist/loop/deliveries.js.map +1 -1
- package/dist/loop/describe.d.ts +4 -6
- package/dist/loop/describe.d.ts.map +1 -1
- package/dist/loop/describe.js +2 -2
- package/dist/loop/describe.js.map +1 -1
- package/dist/loop/drive.d.ts +11 -7
- package/dist/loop/drive.d.ts.map +1 -1
- package/dist/loop/drive.js +24 -38
- package/dist/loop/drive.js.map +1 -1
- package/dist/loop/features.d.ts +23 -0
- package/dist/loop/features.d.ts.map +1 -0
- package/dist/loop/features.js +834 -0
- package/dist/loop/features.js.map +1 -0
- package/dist/loop/journal.d.ts +1 -1
- package/dist/loop/journal.js +2 -2
- package/dist/loop/journal.js.map +1 -1
- package/dist/loop/lock.d.ts +1 -1
- package/dist/loop/lock.js +1 -1
- package/dist/loop/open-host.d.ts.map +1 -1
- package/dist/loop/open-host.js +132 -31
- package/dist/loop/open-host.js.map +1 -1
- package/dist/loop/probe.d.ts +1 -1
- package/dist/loop/probe.d.ts.map +1 -1
- package/dist/loop/probe.js +51 -22
- package/dist/loop/probe.js.map +1 -1
- package/dist/loop/process-tree.d.ts +1 -1
- package/dist/loop/process-tree.js +1 -1
- package/dist/loop/report.d.ts +9 -7
- package/dist/loop/report.d.ts.map +1 -1
- package/dist/loop/report.js +49 -106
- package/dist/loop/report.js.map +1 -1
- package/dist/loop/streams.d.ts +5 -5
- package/dist/loop/streams.d.ts.map +1 -1
- package/dist/loop/streams.js +3 -3
- package/dist/loop/streams.js.map +1 -1
- package/dist/loop/tick.d.ts +6 -4
- package/dist/loop/tick.d.ts.map +1 -1
- package/dist/loop/tick.js +50 -78
- package/dist/loop/tick.js.map +1 -1
- package/dist/loop/trace.d.ts +5 -5
- package/dist/loop/trace.d.ts.map +1 -1
- package/dist/loop/trace.js +5 -14
- package/dist/loop/trace.js.map +1 -1
- package/dist/loop/transformers.d.ts +18 -14
- package/dist/loop/transformers.d.ts.map +1 -1
- package/dist/loop/transformers.js +139 -74
- package/dist/loop/transformers.js.map +1 -1
- package/dist/loop/warm.d.ts +3 -3
- package/dist/loop/warm.js +4 -4
- package/dist/loop/warm.js.map +1 -1
- package/dist/loop/work-line.d.ts +1 -1
- package/dist/operator/agent-plugins.d.ts +11 -0
- package/dist/operator/agent-plugins.d.ts.map +1 -1
- package/dist/operator/agent-plugins.js +17 -11
- package/dist/operator/agent-plugins.js.map +1 -1
- package/dist/operator/board.d.ts +3 -8
- package/dist/operator/board.d.ts.map +1 -1
- package/dist/operator/board.js +2 -11
- package/dist/operator/board.js.map +1 -1
- package/dist/operator/cancel.d.ts +2 -2
- package/dist/operator/cancel.js +6 -6
- package/dist/operator/cancel.js.map +1 -1
- package/dist/operator/doctor.d.ts +9 -0
- package/dist/operator/doctor.d.ts.map +1 -1
- package/dist/operator/doctor.js +110 -53
- package/dist/operator/doctor.js.map +1 -1
- package/dist/operator/explain.d.ts +76 -0
- package/dist/operator/explain.d.ts.map +1 -0
- package/dist/operator/explain.js +585 -0
- package/dist/operator/explain.js.map +1 -0
- package/dist/operator/film.d.ts +3 -11
- package/dist/operator/film.d.ts.map +1 -1
- package/dist/operator/film.js +8 -93
- package/dist/operator/film.js.map +1 -1
- package/dist/operator/init.d.ts.map +1 -1
- package/dist/operator/init.js +52 -55
- package/dist/operator/init.js.map +1 -1
- package/dist/operator/live.js +1 -1
- package/dist/operator/live.js.map +1 -1
- package/dist/operator/log.js +12 -6
- package/dist/operator/log.js.map +1 -1
- package/dist/operator/release.d.ts +2 -2
- package/dist/operator/release.js +7 -7
- package/dist/operator/release.js.map +1 -1
- package/dist/operator/run.d.ts +25 -0
- package/dist/operator/run.d.ts.map +1 -0
- package/dist/operator/run.js +70 -0
- package/dist/operator/run.js.map +1 -0
- package/dist/operator/setup.d.ts.map +1 -1
- package/dist/operator/setup.js +22 -16
- package/dist/operator/setup.js.map +1 -1
- package/dist/plugins/manager.d.ts +33 -2
- package/dist/plugins/manager.d.ts.map +1 -1
- package/dist/plugins/manager.js +67 -0
- package/dist/plugins/manager.js.map +1 -1
- package/package.json +15 -16
package/dist/loop/tick.js
CHANGED
|
@@ -1,34 +1,20 @@
|
|
|
1
|
-
import { refreshWorkLine } from "./authority.js";
|
|
2
1
|
import { loadCursor, saveCursor } from "./cursor.js";
|
|
3
|
-
import {
|
|
4
|
-
import { driveUntilBlocked } from "./drive.js";
|
|
2
|
+
import { advanceProject, handleFeatureDelivery } from "./features.js";
|
|
5
3
|
import { abandonGone } from "./probe.js";
|
|
6
4
|
import { reportMoment } from "./report.js";
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
* `received` is the queue that nothing else starts once the tracker goes quiet.
|
|
10
|
-
*/
|
|
11
|
-
const SWEEP_STATES = new Set([
|
|
12
|
-
"received",
|
|
13
|
-
"planning",
|
|
14
|
-
"running",
|
|
15
|
-
"integrating",
|
|
16
|
-
"submitted",
|
|
17
|
-
]);
|
|
5
|
+
/** Features that still have something to do: the Projects the sweep moves along. */
|
|
6
|
+
const SWEEP_STATES = new Set(["waiting", "open", "submitted"]);
|
|
18
7
|
export async function runOnce(input) {
|
|
19
|
-
const { options,
|
|
8
|
+
const { options, ledger, features, journal, trace } = input;
|
|
20
9
|
const interruptFlag = options.interruptFlag ?? { interrupted: false };
|
|
21
10
|
const reported = [];
|
|
22
11
|
let lastRun;
|
|
23
|
-
// Projects a delivery already drove this pass. Driving one twice is not
|
|
24
|
-
// wrong, it just does two steps where the caller asked for one.
|
|
25
|
-
const driven = new Set();
|
|
26
12
|
const since = await loadCursor(options.ledgerRoot);
|
|
27
13
|
const listenInput = {};
|
|
28
14
|
if (since !== undefined) {
|
|
29
15
|
listenInput.since = since;
|
|
30
16
|
}
|
|
31
|
-
const listened = await
|
|
17
|
+
const listened = await features.listen(listenInput);
|
|
32
18
|
journal.append({
|
|
33
19
|
event: "listen",
|
|
34
20
|
outcome: listened.outcome,
|
|
@@ -37,84 +23,49 @@ export async function runOnce(input) {
|
|
|
37
23
|
if (listened.deliveries.length > 0) {
|
|
38
24
|
trace(`listen ${listened.deliveries.length} to look at`);
|
|
39
25
|
}
|
|
26
|
+
// A tracker that cannot be read is the one thing a quiet loop must not hide:
|
|
27
|
+
// it is repeated on every poll until it answers again.
|
|
28
|
+
if (listened.outcome === "source-lost" || listened.outcome === "invalid-invocation") {
|
|
29
|
+
trace(`listen ${listened.outcome}: the tracker could not be read`);
|
|
30
|
+
}
|
|
40
31
|
const deliveryInput = { ...input, reported };
|
|
41
32
|
const probed = await abandonGone(deliveryInput, listened.outcome);
|
|
42
33
|
if (probed === "stop") {
|
|
43
34
|
return { listenerOutcome: listened.outcome, reported };
|
|
44
35
|
}
|
|
45
|
-
// The work line copy is brought up to date before anything is driven on it
|
|
46
|
-
// — and only then: a pass with nothing to drive fetches nothing. Starting
|
|
47
|
-
// work on a copy that could not be brought up to date builds on a version
|
|
48
|
-
// that no longer exists, so a failed refresh drives nothing; the next pass
|
|
49
|
-
// tries again, and a human can look at that tree meanwhile.
|
|
50
|
-
const pendingBefore = await pendingWork(ledger);
|
|
51
|
-
const somethingToDrive = listened.deliveries.length > 0 || pendingBefore.length > 0;
|
|
52
|
-
if (somethingToDrive && authority !== undefined && workLine.target !== undefined) {
|
|
53
|
-
const refreshed = await refreshWorkLine({
|
|
54
|
-
workLineStable: workLine.stable,
|
|
55
|
-
workLineTarget: workLine.target,
|
|
56
|
-
refreshArgv: options.authority?.refreshArgv ?? [],
|
|
57
|
-
timeoutMs: options.timeoutMs,
|
|
58
|
-
env: workLine.env,
|
|
59
|
-
});
|
|
60
|
-
if (!refreshed.ok) {
|
|
61
|
-
journal.append({
|
|
62
|
-
event: "refresh",
|
|
63
|
-
outcome: "failed",
|
|
64
|
-
target: workLine.target,
|
|
65
|
-
...(refreshed.detail === undefined ? {} : { detail: refreshed.detail }),
|
|
66
|
-
});
|
|
67
|
-
trace(`work line cannot fast-forward onto ${workLine.target}, so nothing started. ${refreshed.detail ?? ""}`);
|
|
68
|
-
return { listenerOutcome: "skipped", reported };
|
|
69
|
-
}
|
|
70
|
-
journal.append({ event: "refresh", outcome: "ok", target: workLine.target });
|
|
71
|
-
}
|
|
72
36
|
// What Conductor says mid-pass is reported as it happens, not after the pass:
|
|
73
|
-
// a
|
|
37
|
+
// a Submission is something a person waits for.
|
|
74
38
|
input.watcher.current = (moment) => reportMoment(deliveryInput, moment);
|
|
75
39
|
let cursor = since;
|
|
76
40
|
for (const delivery of listened.deliveries) {
|
|
77
41
|
if (interruptFlag.interrupted) {
|
|
78
42
|
break;
|
|
79
43
|
}
|
|
80
|
-
const handled = await
|
|
81
|
-
...deliveryInput,
|
|
82
|
-
payload: delivery.payload,
|
|
83
|
-
});
|
|
44
|
+
const handled = await handleFeatureDelivery(deliveryInput, delivery.payload);
|
|
84
45
|
if (!handled.advance) {
|
|
85
46
|
break;
|
|
86
47
|
}
|
|
87
|
-
if (handled.run !== undefined) {
|
|
88
|
-
lastRun = handled.run;
|
|
89
|
-
}
|
|
90
|
-
if (handled.project !== undefined) {
|
|
91
|
-
driven.add(handled.project);
|
|
92
|
-
}
|
|
93
48
|
cursor = delivery.cursor;
|
|
94
49
|
await saveCursor(options.ledgerRoot, delivery.cursor);
|
|
95
50
|
}
|
|
96
|
-
// A Project with
|
|
97
|
-
//
|
|
98
|
-
//
|
|
99
|
-
//
|
|
100
|
-
const
|
|
101
|
-
if (
|
|
102
|
-
journal.append({
|
|
103
|
-
event: "sweep",
|
|
104
|
-
keys: pending.map((summary) => summary.key),
|
|
105
|
-
});
|
|
51
|
+
// A Project with a Feature to open, make or fold moves on whether or not the
|
|
52
|
+
// tracker mentioned it again: nothing else claims it, so a restart with only
|
|
53
|
+
// waiting work would otherwise sit idle until a delivery that has no reason
|
|
54
|
+
// to come.
|
|
55
|
+
const projects = await projectsToSweep(ledger);
|
|
56
|
+
if (projects.length > 0) {
|
|
57
|
+
journal.append({ event: "sweep", projects });
|
|
106
58
|
}
|
|
107
|
-
for (const
|
|
108
|
-
if (interruptFlag.interrupted
|
|
109
|
-
|
|
59
|
+
for (const project of projects) {
|
|
60
|
+
if (interruptFlag.interrupted) {
|
|
61
|
+
break;
|
|
110
62
|
}
|
|
111
|
-
|
|
112
|
-
const run = await driveUntilBlocked(deliveryInput, summary.project, summary.key);
|
|
63
|
+
const run = await advanceProject(deliveryInput, project);
|
|
113
64
|
if (run !== undefined) {
|
|
114
65
|
lastRun = run;
|
|
115
66
|
}
|
|
116
67
|
}
|
|
117
|
-
if (listened.deliveries.length === 0 &&
|
|
68
|
+
if (listened.deliveries.length === 0 && projects.length === 0) {
|
|
118
69
|
journal.append({ event: "idle" });
|
|
119
70
|
}
|
|
120
71
|
const result = {
|
|
@@ -129,13 +80,17 @@ export async function runOnce(input) {
|
|
|
129
80
|
}
|
|
130
81
|
return result;
|
|
131
82
|
}
|
|
132
|
-
|
|
133
|
-
|
|
83
|
+
/** How long an idle loop goes without saying that it is still turning. */
|
|
84
|
+
export const HEARTBEAT_MS = 60_000;
|
|
85
|
+
export async function run(input, now = Date.now) {
|
|
86
|
+
const { options, conductor, journal, trace } = input;
|
|
134
87
|
const interruptFlag = options.interruptFlag ?? { interrupted: false };
|
|
135
88
|
let last = {
|
|
136
89
|
listenerOutcome: "completed",
|
|
137
90
|
reported: [],
|
|
138
91
|
};
|
|
92
|
+
let idlePasses = 0;
|
|
93
|
+
let lastSaid = now();
|
|
139
94
|
for (;;) {
|
|
140
95
|
if (interruptFlag.interrupted) {
|
|
141
96
|
journal.append({ event: "paused" });
|
|
@@ -146,12 +101,29 @@ export async function run(input) {
|
|
|
146
101
|
if (options.pollIntervalMs === undefined) {
|
|
147
102
|
return last;
|
|
148
103
|
}
|
|
104
|
+
// Nothing printed for a minute looks the same as a hung process, so an idle
|
|
105
|
+
// loop says once a minute that it is polling and found nothing to do.
|
|
106
|
+
if (last.lastRun === undefined && last.reported.length === 0) {
|
|
107
|
+
idlePasses += 1;
|
|
108
|
+
if (now() - lastSaid >= HEARTBEAT_MS) {
|
|
109
|
+
trace(`waiting nothing to do: ${idlePasses} poll(s) in ${Math.round((now() - lastSaid) / 1000)}s`);
|
|
110
|
+
idlePasses = 0;
|
|
111
|
+
lastSaid = now();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
idlePasses = 0;
|
|
116
|
+
lastSaid = now();
|
|
117
|
+
}
|
|
149
118
|
await sleep(options.pollIntervalMs, interruptFlag);
|
|
150
119
|
}
|
|
151
120
|
}
|
|
152
|
-
async function
|
|
153
|
-
const
|
|
154
|
-
|
|
121
|
+
async function projectsToSweep(ledger) {
|
|
122
|
+
const features = await ledger.listFeatures();
|
|
123
|
+
const projects = features
|
|
124
|
+
.filter((summary) => SWEEP_STATES.has(summary.state))
|
|
125
|
+
.map((summary) => summary.project);
|
|
126
|
+
return [...new Set(projects)];
|
|
155
127
|
}
|
|
156
128
|
function sleep(ms, interruptFlag) {
|
|
157
129
|
return new Promise((resolve) => {
|
package/dist/loop/tick.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tick.js","sourceRoot":"","sources":["../../src/loop/tick.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tick.js","sourceRoot":"","sources":["../../src/loop/tick.ts"],"names":[],"mappings":"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"}
|
package/dist/loop/trace.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TicketAggregate } from "@bluewombat/work-ledger";
|
|
2
2
|
/**
|
|
3
3
|
* What the run says about itself while it works.
|
|
4
4
|
*
|
|
5
5
|
* A run can wait minutes on an Attempt and longer on a verdict. With nothing on
|
|
6
6
|
* stdout there is no way to tell working from wedged, and no way to see which
|
|
7
|
-
* stage a
|
|
7
|
+
* stage a ticket is at without reading the WorkLedger by hand.
|
|
8
8
|
*
|
|
9
|
-
* One line per thing that happened, and one per pass over a
|
|
9
|
+
* One line per thing that happened, and one per pass over a ticket that is
|
|
10
10
|
* waiting — a repeated line is how a reader knows the loop is still turning.
|
|
11
11
|
*/
|
|
12
12
|
export type Trace = (line: string) => void;
|
|
13
13
|
export declare function openTrace(write: (text: string) => void): Trace;
|
|
14
|
-
/** Where this
|
|
15
|
-
export declare function
|
|
14
|
+
/** Where this ticket stands, in one line. */
|
|
15
|
+
export declare function describeTicket(aggregate: TicketAggregate): string;
|
|
16
16
|
/**
|
|
17
17
|
* What a failure line adds under its phase label.
|
|
18
18
|
*
|
package/dist/loop/trace.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../src/loop/trace.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../src/loop/trace.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D;;;;;;;;;GASG;AACH,MAAM,MAAM,KAAK,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAE3C,wBAAgB,SAAS,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,KAAK,CAI9D;AAED,6CAA6C;AAC7C,wBAAgB,cAAc,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,CAIjE;AAuCD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAUjE"}
|
package/dist/loop/trace.js
CHANGED
|
@@ -3,8 +3,8 @@ export function openTrace(write) {
|
|
|
3
3
|
write(`${stamp()} ${line}\n`);
|
|
4
4
|
};
|
|
5
5
|
}
|
|
6
|
-
/** Where this
|
|
7
|
-
export function
|
|
6
|
+
/** Where this ticket stands, in one line. */
|
|
7
|
+
export function describeTicket(aggregate) {
|
|
8
8
|
const key = aggregate.intention.key;
|
|
9
9
|
const state = aggregate.state;
|
|
10
10
|
return `${key} ${state.padEnd(11)} ${detailOf(aggregate)}`.trimEnd();
|
|
@@ -23,12 +23,10 @@ function detailOf(aggregate) {
|
|
|
23
23
|
return `${aggregate.escalation?.kind ?? "?"} — waiting for a human`;
|
|
24
24
|
case "running":
|
|
25
25
|
return runningDetail(aggregate);
|
|
26
|
-
case "planning":
|
|
27
|
-
return "";
|
|
28
26
|
case "integrating":
|
|
29
27
|
return aggregate.parked_refusal === undefined
|
|
30
|
-
?
|
|
31
|
-
:
|
|
28
|
+
? "assembling"
|
|
29
|
+
: "ticket.validate sent it back (repair on its way)";
|
|
32
30
|
case "invalid":
|
|
33
31
|
return aggregate.invalid?.reason ?? "";
|
|
34
32
|
default:
|
|
@@ -36,14 +34,7 @@ function detailOf(aggregate) {
|
|
|
36
34
|
}
|
|
37
35
|
}
|
|
38
36
|
function runningDetail(aggregate) {
|
|
39
|
-
|
|
40
|
-
const current = subtasks.find((subtask) => subtask.state === "running");
|
|
41
|
-
const at = current === undefined ? "" : `subtask ${current.id}, `;
|
|
42
|
-
return `${at}${countIntegrated(aggregate)}/${subtasks.length} folded, attempt ${aggregate.attempts_used}`;
|
|
43
|
-
}
|
|
44
|
-
function countIntegrated(aggregate) {
|
|
45
|
-
return (aggregate.plan?.subtasks ?? []).filter((subtask) => subtask.state === "integrated")
|
|
46
|
-
.length;
|
|
37
|
+
return `attempt ${aggregate.attempts_used}`;
|
|
47
38
|
}
|
|
48
39
|
function stamp() {
|
|
49
40
|
return new Date().toISOString().slice(11, 19);
|
package/dist/loop/trace.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../../src/loop/trace.ts"],"names":[],"mappings":"AAcA,MAAM,UAAU,SAAS,CAAC,KAA6B;IACrD,OAAO,CAAC,IAAY,EAAE,EAAE;QACtB,KAAK,CAAC,GAAG,KAAK,EAAE,IAAI,IAAI,IAAI,CAAC,CAAC;IAChC,CAAC,CAAC;AACJ,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../../src/loop/trace.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { TransformerPort } from "@bluewombat/conductor";
|
|
2
2
|
import { type FoldBackend } from "@bluewombat/integrator";
|
|
3
3
|
import { type IsolationBackend } from "@bluewombat/isolator";
|
|
4
|
-
import
|
|
4
|
+
import { type FeatureSpec, type StageSpec, type TicketSpec } from "../config/types.js";
|
|
5
5
|
import type { Journal } from "./journal.js";
|
|
6
6
|
import type { Streams } from "./streams.js";
|
|
7
7
|
import { type Trace } from "./trace.js";
|
|
@@ -15,22 +15,21 @@ export type TransformerSlots = {
|
|
|
15
15
|
* nothing is filmed and a child's output leaves a Transformer as one word.
|
|
16
16
|
*/
|
|
17
17
|
streams?: Streams;
|
|
18
|
-
/**
|
|
19
|
-
planner: GatedPassSpec;
|
|
20
|
-
/** Making a Subtask, and the Gates judging what came out of it. */
|
|
18
|
+
/** Making the unit of work, and the Gates judging what came out of it. */
|
|
21
19
|
builder: StageSpec;
|
|
22
|
-
/** Judging the assembled
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
|
|
26
|
-
* workspace, and not where the Planner agent itself reads from (that stays
|
|
27
|
-
* the Project's own `--read` convention; see feature-breakdown SPECS.md §5a).
|
|
28
|
-
*/
|
|
29
|
-
workLineStable: string;
|
|
20
|
+
/** Judging the assembled ticket, and the command that fixes a refusal. */
|
|
21
|
+
ticket: TicketSpec;
|
|
22
|
+
/** Judging the whole Feature, and its own fix. Present whenever there is an Authority to fold it. */
|
|
23
|
+
feature?: FeatureSpec;
|
|
30
24
|
/** How Isolator produces the Child. Host chooses; Isolator does not sniff. */
|
|
31
25
|
isolation: IsolationBackend;
|
|
32
26
|
/** How Integrator folds. Must match `isolation`. */
|
|
33
27
|
fold: FoldBackend;
|
|
28
|
+
/**
|
|
29
|
+
* What the tracker says of the piece of work a pass is about, read when the pass starts: a
|
|
30
|
+
* label can move while a Feature is made. Absent: nothing is marked.
|
|
31
|
+
*/
|
|
32
|
+
marks?: Marks;
|
|
34
33
|
/** How long any one child outside a Task may run: manager, isolations. */
|
|
35
34
|
timeoutMs: number;
|
|
36
35
|
/**
|
|
@@ -41,8 +40,13 @@ export type TransformerSlots = {
|
|
|
41
40
|
interruptFlag?: {
|
|
42
41
|
interrupted: boolean;
|
|
43
42
|
};
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
};
|
|
44
|
+
/** What a Task's key says of the work behind it, as the tracker last said it. */
|
|
45
|
+
export type Marks = {
|
|
46
|
+
/** The key is a Ticket that holds the e2e acceptance suite of its Feature. */
|
|
47
|
+
ticketIsE2e(key: string): Promise<boolean>;
|
|
48
|
+
/** The key is a Feature that is not put through the e2e acceptance check. */
|
|
49
|
+
featureSkipsE2e(key: string): Promise<boolean>;
|
|
46
50
|
};
|
|
47
51
|
export declare function createTransformers(slots: TransformerSlots): TransformerPort;
|
|
48
52
|
//# sourceMappingURL=transformers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformers.d.ts","sourceRoot":"","sources":["../../src/loop/transformers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"transformers.d.ts","sourceRoot":"","sources":["../../src/loop/transformers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAM9E,OAAO,EAAE,KAAK,WAAW,EAAiB,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,KAAK,gBAAgB,EAAe,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EACL,KAAK,WAAW,EAIhB,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,uEAAuE;IACvE,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,oFAAoF;IACpF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0EAA0E;IAC1E,OAAO,EAAE,SAAS,CAAC;IACnB,0EAA0E;IAC1E,MAAM,EAAE,UAAU,CAAC;IACnB,qGAAqG;IACrG,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,8EAA8E;IAC9E,SAAS,EAAE,gBAAgB,CAAC;IAC5B,oDAAoD;IACpD,IAAI,EAAE,WAAW,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,aAAa,CAAC,EAAE;QAAE,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC;CAC1C,CAAC;AAEF,iFAAiF;AACjF,MAAM,MAAM,KAAK,GAAG;IAClB,8EAA8E;IAC9E,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,6EAA6E;IAC7E,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAChD,CAAC;AA6QF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,GAAG,eAAe,CA6G3E"}
|