@bluewombat/runtime 0.1.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 +473 -0
- package/SPECS.md +303 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +172 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/defaults.d.ts +17 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +17 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/find-config.d.ts +9 -0
- package/dist/config/find-config.d.ts.map +1 -0
- package/dist/config/find-config.js +25 -0
- package/dist/config/find-config.js.map +1 -0
- package/dist/config/home.d.ts +17 -0
- package/dist/config/home.d.ts.map +1 -0
- package/dist/config/home.js +23 -0
- package/dist/config/home.js.map +1 -0
- package/dist/config/load-config.d.ts +13 -0
- package/dist/config/load-config.d.ts.map +1 -0
- package/dist/config/load-config.js +537 -0
- package/dist/config/load-config.js.map +1 -0
- package/dist/config/parse-args.d.ts +25 -0
- package/dist/config/parse-args.d.ts.map +1 -0
- package/dist/config/parse-args.js +478 -0
- package/dist/config/parse-args.js.map +1 -0
- package/dist/config/types.d.ts +144 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/loop/authority.d.ts +51 -0
- package/dist/loop/authority.d.ts.map +1 -0
- package/dist/loop/authority.js +166 -0
- package/dist/loop/authority.js.map +1 -0
- package/dist/loop/context.d.ts +44 -0
- package/dist/loop/context.d.ts.map +1 -0
- package/dist/loop/context.js +2 -0
- package/dist/loop/context.js.map +1 -0
- package/dist/loop/cursor.d.ts +4 -0
- package/dist/loop/cursor.d.ts.map +1 -0
- package/dist/loop/cursor.js +20 -0
- package/dist/loop/cursor.js.map +1 -0
- package/dist/loop/deliveries.d.ts +22 -0
- package/dist/loop/deliveries.d.ts.map +1 -0
- package/dist/loop/deliveries.js +240 -0
- package/dist/loop/deliveries.js.map +1 -0
- package/dist/loop/describe.d.ts +40 -0
- package/dist/loop/describe.d.ts.map +1 -0
- package/dist/loop/describe.js +48 -0
- package/dist/loop/describe.js.map +1 -0
- package/dist/loop/drive.d.ts +15 -0
- package/dist/loop/drive.d.ts.map +1 -0
- package/dist/loop/drive.js +42 -0
- package/dist/loop/drive.js.map +1 -0
- package/dist/loop/journal.d.ts +22 -0
- package/dist/loop/journal.d.ts.map +1 -0
- package/dist/loop/journal.js +49 -0
- package/dist/loop/journal.js.map +1 -0
- package/dist/loop/lock.d.ts +11 -0
- package/dist/loop/lock.d.ts.map +1 -0
- package/dist/loop/lock.js +60 -0
- package/dist/loop/lock.js.map +1 -0
- package/dist/loop/message.d.ts +34 -0
- package/dist/loop/message.d.ts.map +1 -0
- package/dist/loop/message.js +48 -0
- package/dist/loop/message.js.map +1 -0
- package/dist/loop/open-host.d.ts +13 -0
- package/dist/loop/open-host.d.ts.map +1 -0
- package/dist/loop/open-host.js +180 -0
- package/dist/loop/open-host.js.map +1 -0
- package/dist/loop/probe.d.ts +9 -0
- package/dist/loop/probe.d.ts.map +1 -0
- package/dist/loop/probe.js +57 -0
- package/dist/loop/probe.js.map +1 -0
- package/dist/loop/report.d.ts +26 -0
- package/dist/loop/report.d.ts.map +1 -0
- package/dist/loop/report.js +328 -0
- package/dist/loop/report.js.map +1 -0
- package/dist/loop/tick.d.ts +24 -0
- package/dist/loop/tick.d.ts.map +1 -0
- package/dist/loop/tick.js +169 -0
- package/dist/loop/tick.js.map +1 -0
- package/dist/loop/trace.d.ts +16 -0
- package/dist/loop/trace.d.ts.map +1 -0
- package/dist/loop/trace.js +49 -0
- package/dist/loop/trace.js.map +1 -0
- package/dist/loop/transformers.d.ts +27 -0
- package/dist/loop/transformers.d.ts.map +1 -0
- package/dist/loop/transformers.js +229 -0
- package/dist/loop/transformers.js.map +1 -0
- package/dist/loop/work-line.d.ts +73 -0
- package/dist/loop/work-line.d.ts.map +1 -0
- package/dist/loop/work-line.js +109 -0
- package/dist/loop/work-line.js.map +1 -0
- package/dist/operator/board.d.ts +31 -0
- package/dist/operator/board.d.ts.map +1 -0
- package/dist/operator/board.js +67 -0
- package/dist/operator/board.js.map +1 -0
- package/dist/operator/cancel.d.ts +19 -0
- package/dist/operator/cancel.d.ts.map +1 -0
- package/dist/operator/cancel.js +70 -0
- package/dist/operator/cancel.js.map +1 -0
- package/dist/operator/doctor.d.ts +15 -0
- package/dist/operator/doctor.d.ts.map +1 -0
- package/dist/operator/doctor.js +416 -0
- package/dist/operator/doctor.js.map +1 -0
- package/dist/operator/git-remote.d.ts +39 -0
- package/dist/operator/git-remote.d.ts.map +1 -0
- package/dist/operator/git-remote.js +78 -0
- package/dist/operator/git-remote.js.map +1 -0
- package/dist/operator/init.d.ts +28 -0
- package/dist/operator/init.d.ts.map +1 -0
- package/dist/operator/init.js +522 -0
- package/dist/operator/init.js.map +1 -0
- package/dist/operator/live.d.ts +19 -0
- package/dist/operator/live.d.ts.map +1 -0
- package/dist/operator/live.js +149 -0
- package/dist/operator/live.js.map +1 -0
- package/dist/operator/prompt.d.ts +35 -0
- package/dist/operator/prompt.d.ts.map +1 -0
- package/dist/operator/prompt.js +125 -0
- package/dist/operator/prompt.js.map +1 -0
- package/dist/operator/setup.d.ts +18 -0
- package/dist/operator/setup.d.ts.map +1 -0
- package/dist/operator/setup.js +62 -0
- package/dist/operator/setup.js.map +1 -0
- package/dist/plugins/discover.d.ts +13 -0
- package/dist/plugins/discover.d.ts.map +1 -0
- package/dist/plugins/discover.js +81 -0
- package/dist/plugins/discover.js.map +1 -0
- package/dist/plugins/isolation.d.ts +78 -0
- package/dist/plugins/isolation.d.ts.map +1 -0
- package/dist/plugins/isolation.js +64 -0
- package/dist/plugins/isolation.js.map +1 -0
- package/dist/plugins/load.d.ts +35 -0
- package/dist/plugins/load.d.ts.map +1 -0
- package/dist/plugins/load.js +109 -0
- package/dist/plugins/load.js.map +1 -0
- package/dist/plugins/manager.d.ts +43 -0
- package/dist/plugins/manager.d.ts.map +1 -0
- package/dist/plugins/manager.js +47 -0
- package/dist/plugins/manager.js.map +1 -0
- package/dist/plugins/persist.d.ts +33 -0
- package/dist/plugins/persist.d.ts.map +1 -0
- package/dist/plugins/persist.js +26 -0
- package/dist/plugins/persist.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { refreshWorkLine } from "./authority.js";
|
|
2
|
+
import { loadCursor, saveCursor } from "./cursor.js";
|
|
3
|
+
import { handleDelivery } from "./deliveries.js";
|
|
4
|
+
import { driveProject } from "./drive.js";
|
|
5
|
+
import { abandonGone } from "./probe.js";
|
|
6
|
+
import { reportMoment } from "./report.js";
|
|
7
|
+
/**
|
|
8
|
+
* States the sweep will try to drive. `escalated` is frozen for a human;
|
|
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
|
+
]);
|
|
18
|
+
export async function runOnce(input) {
|
|
19
|
+
const { options, workLine, ledger, manager, journal, trace, authority } = input;
|
|
20
|
+
const interruptFlag = options.interruptFlag ?? { interrupted: false };
|
|
21
|
+
const reported = [];
|
|
22
|
+
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
|
+
const since = await loadCursor(options.ledgerRoot);
|
|
27
|
+
const listenInput = {};
|
|
28
|
+
if (since !== undefined) {
|
|
29
|
+
listenInput.since = since;
|
|
30
|
+
}
|
|
31
|
+
const listened = await manager.listen(listenInput);
|
|
32
|
+
journal.append({
|
|
33
|
+
event: "listen",
|
|
34
|
+
outcome: listened.outcome,
|
|
35
|
+
deliveries: listened.deliveries.length,
|
|
36
|
+
});
|
|
37
|
+
if (listened.deliveries.length > 0) {
|
|
38
|
+
trace(`listen ${listened.deliveries.length} to look at`);
|
|
39
|
+
}
|
|
40
|
+
const deliveryInput = { ...input, reported };
|
|
41
|
+
const probed = await abandonGone(deliveryInput, listened.outcome);
|
|
42
|
+
if (probed === "stop") {
|
|
43
|
+
return { listenerOutcome: listened.outcome, reported };
|
|
44
|
+
}
|
|
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 = 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
|
+
// What Conductor says mid-pass is reported as it happens, not after the pass:
|
|
73
|
+
// a plan, a Subtask landed, a Submission — each is something a person waits for.
|
|
74
|
+
input.watcher.current = (moment) => reportMoment(deliveryInput, moment);
|
|
75
|
+
let cursor = since;
|
|
76
|
+
for (const delivery of listened.deliveries) {
|
|
77
|
+
if (interruptFlag.interrupted) {
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
const handled = await handleDelivery({
|
|
81
|
+
...deliveryInput,
|
|
82
|
+
payload: delivery.payload,
|
|
83
|
+
});
|
|
84
|
+
if (!handled.advance) {
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
if (handled.run !== undefined) {
|
|
88
|
+
lastRun = handled.run;
|
|
89
|
+
}
|
|
90
|
+
if (handled.project !== undefined) {
|
|
91
|
+
driven.add(handled.project);
|
|
92
|
+
}
|
|
93
|
+
cursor = delivery.cursor;
|
|
94
|
+
await saveCursor(options.ledgerRoot, delivery.cursor);
|
|
95
|
+
}
|
|
96
|
+
// A Project with work in flight, or a Feature still `received` behind one,
|
|
97
|
+
// moves on whether or not the tracker mentioned it again. Nothing else
|
|
98
|
+
// claims a queue, so a restart with only `received` work would otherwise
|
|
99
|
+
// sit idle until a delivery that has no reason to come.
|
|
100
|
+
const pending = await pendingWork(ledger);
|
|
101
|
+
if (pending.length > 0) {
|
|
102
|
+
journal.append({
|
|
103
|
+
event: "sweep",
|
|
104
|
+
keys: pending.map((summary) => summary.key),
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
for (const summary of pending) {
|
|
108
|
+
if (interruptFlag.interrupted || driven.has(summary.project)) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
driven.add(summary.project);
|
|
112
|
+
const run = await driveProject(deliveryInput, summary.project, summary.key);
|
|
113
|
+
if (run !== undefined) {
|
|
114
|
+
lastRun = run;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (listened.deliveries.length === 0 && pending.length === 0) {
|
|
118
|
+
journal.append({ event: "idle" });
|
|
119
|
+
}
|
|
120
|
+
const result = {
|
|
121
|
+
listenerOutcome: listened.outcome,
|
|
122
|
+
reported,
|
|
123
|
+
};
|
|
124
|
+
if (lastRun !== undefined) {
|
|
125
|
+
result.lastRun = lastRun;
|
|
126
|
+
}
|
|
127
|
+
if (cursor !== undefined) {
|
|
128
|
+
result.cursor = cursor;
|
|
129
|
+
}
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
export async function run(input) {
|
|
133
|
+
const { options, conductor, journal } = input;
|
|
134
|
+
const interruptFlag = options.interruptFlag ?? { interrupted: false };
|
|
135
|
+
let last = {
|
|
136
|
+
listenerOutcome: "completed",
|
|
137
|
+
reported: [],
|
|
138
|
+
};
|
|
139
|
+
for (;;) {
|
|
140
|
+
if (interruptFlag.interrupted) {
|
|
141
|
+
journal.append({ event: "paused" });
|
|
142
|
+
conductor.pause();
|
|
143
|
+
return last;
|
|
144
|
+
}
|
|
145
|
+
last = await runOnce(input);
|
|
146
|
+
if (options.pollIntervalMs === undefined) {
|
|
147
|
+
return last;
|
|
148
|
+
}
|
|
149
|
+
await sleep(options.pollIntervalMs, interruptFlag);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async function pendingWork(ledger) {
|
|
153
|
+
const summaries = await ledger.list();
|
|
154
|
+
return summaries.filter((summary) => SWEEP_STATES.has(summary.state));
|
|
155
|
+
}
|
|
156
|
+
function sleep(ms, interruptFlag) {
|
|
157
|
+
return new Promise((resolve) => {
|
|
158
|
+
const started = Date.now();
|
|
159
|
+
const tick = () => {
|
|
160
|
+
if (interruptFlag.interrupted || Date.now() - started >= ms) {
|
|
161
|
+
resolve();
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
setTimeout(tick, Math.min(50, ms));
|
|
165
|
+
};
|
|
166
|
+
tick();
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=tick.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tick.js","sourceRoot":"","sources":["../../src/loop/tick.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FeatureAggregate } from "@bluewombat/work-ledger";
|
|
2
|
+
/**
|
|
3
|
+
* What the run says about itself while it works.
|
|
4
|
+
*
|
|
5
|
+
* A run can wait minutes on an Attempt and longer on a verdict. With nothing on
|
|
6
|
+
* stdout there is no way to tell working from wedged, and no way to see which
|
|
7
|
+
* stage a feature is at without reading the WorkLedger by hand.
|
|
8
|
+
*
|
|
9
|
+
* One line per thing that happened, and one per pass over a feature that is
|
|
10
|
+
* waiting — a repeated line is how a reader knows the loop is still turning.
|
|
11
|
+
*/
|
|
12
|
+
export type Trace = (line: string) => void;
|
|
13
|
+
export declare function openTrace(write: (text: string) => void): Trace;
|
|
14
|
+
/** Where this feature stands, in one line. */
|
|
15
|
+
export declare function describeFeature(aggregate: FeatureAggregate): string;
|
|
16
|
+
//# sourceMappingURL=trace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../src/loop/trace.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE;;;;;;;;;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,8CAA8C;AAC9C,wBAAgB,eAAe,CAAC,SAAS,EAAE,gBAAgB,GAAG,MAAM,CAInE"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export function openTrace(write) {
|
|
2
|
+
return (line) => {
|
|
3
|
+
write(`${stamp()} ${line}\n`);
|
|
4
|
+
};
|
|
5
|
+
}
|
|
6
|
+
/** Where this feature stands, in one line. */
|
|
7
|
+
export function describeFeature(aggregate) {
|
|
8
|
+
const key = aggregate.intention.key;
|
|
9
|
+
const state = aggregate.state;
|
|
10
|
+
return `${key} ${state.padEnd(11)} ${detailOf(aggregate)}`.trimEnd();
|
|
11
|
+
}
|
|
12
|
+
function detailOf(aggregate) {
|
|
13
|
+
switch (aggregate.state) {
|
|
14
|
+
case "submitted":
|
|
15
|
+
return aggregate.submission === undefined
|
|
16
|
+
? ""
|
|
17
|
+
: `${aggregate.submission.reference}${aggregate.submission.refusals > 0
|
|
18
|
+
? ` (sent back ${aggregate.submission.refusals}x)`
|
|
19
|
+
: ""}`;
|
|
20
|
+
case "done":
|
|
21
|
+
return aggregate.submission?.reference ?? "";
|
|
22
|
+
case "escalated":
|
|
23
|
+
return `${aggregate.escalation?.kind ?? "?"} — waiting for a human`;
|
|
24
|
+
case "running":
|
|
25
|
+
return runningDetail(aggregate);
|
|
26
|
+
case "planning":
|
|
27
|
+
return "";
|
|
28
|
+
case "integrating":
|
|
29
|
+
return `${countIntegrated(aggregate)} subtask(s) folded`;
|
|
30
|
+
case "invalid":
|
|
31
|
+
return aggregate.invalid?.reason ?? "";
|
|
32
|
+
default:
|
|
33
|
+
return "";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function runningDetail(aggregate) {
|
|
37
|
+
const subtasks = aggregate.plan?.subtasks ?? [];
|
|
38
|
+
const current = subtasks.find((subtask) => subtask.state === "running");
|
|
39
|
+
const at = current === undefined ? "" : `subtask ${current.id}, `;
|
|
40
|
+
return `${at}${countIntegrated(aggregate)}/${subtasks.length} folded, attempt ${aggregate.attempts_used}`;
|
|
41
|
+
}
|
|
42
|
+
function countIntegrated(aggregate) {
|
|
43
|
+
return (aggregate.plan?.subtasks ?? []).filter((subtask) => subtask.state === "integrated")
|
|
44
|
+
.length;
|
|
45
|
+
}
|
|
46
|
+
function stamp() {
|
|
47
|
+
return new Date().toISOString().slice(11, 19);
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=trace.js.map
|
|
@@ -0,0 +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,8CAA8C;AAC9C,MAAM,UAAU,eAAe,CAAC,SAA2B;IACzD,MAAM,GAAG,GAAG,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC;IACpC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;IAC9B,OAAO,GAAG,GAAG,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC;AACxE,CAAC;AAED,SAAS,QAAQ,CAAC,SAA2B;IAC3C,QAAQ,SAAS,CAAC,KAAK,EAAE,CAAC;QACxB,KAAK,WAAW;YACd,OAAO,SAAS,CAAC,UAAU,KAAK,SAAS;gBACvC,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,SAAS,GAC/B,SAAS,CAAC,UAAU,CAAC,QAAQ,GAAG,CAAC;oBAC/B,CAAC,CAAC,eAAe,SAAS,CAAC,UAAU,CAAC,QAAQ,IAAI;oBAClD,CAAC,CAAC,EACN,EAAE,CAAC;QACT,KAAK,MAAM;YACT,OAAO,SAAS,CAAC,UAAU,EAAE,SAAS,IAAI,EAAE,CAAC;QAC/C,KAAK,WAAW;YACd,OAAO,GAAG,SAAS,CAAC,UAAU,EAAE,IAAI,IAAI,GAAG,wBAAwB,CAAC;QACtE,KAAK,SAAS;YACZ,OAAO,aAAa,CAAC,SAAS,CAAC,CAAC;QAClC,KAAK,UAAU;YACb,OAAO,EAAE,CAAC;QACZ,KAAK,aAAa;YAChB,OAAO,GAAG,eAAe,CAAC,SAAS,CAAC,oBAAoB,CAAC;QAC3D,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC,OAAO,EAAE,MAAM,IAAI,EAAE,CAAC;QACzC;YACE,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,SAA2B;IAChD,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC;IAChD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IACxE,MAAM,EAAE,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,OAAO,CAAC,EAAE,IAAI,CAAC;IAClE,OAAO,GAAG,EAAE,GAAG,eAAe,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC,MAAM,oBAAoB,SAAS,CAAC,aAAa,EAAE,CAAC;AAC5G,CAAC;AAED,SAAS,eAAe,CAAC,SAA2B;IAClD,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,KAAK,YAAY,CAAC;SACxF,MAAM,CAAC;AACZ,CAAC;AAED,SAAS,KAAK;IACZ,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { TransformerPort } from "@bluewombat/conductor";
|
|
2
|
+
import { type FoldBackend } from "@bluewombat/integrator";
|
|
3
|
+
import { type IsolationBackend } from "@bluewombat/isolator";
|
|
4
|
+
import type { AssemblySpec, PassSpec, StageSpec } from "../config/types.js";
|
|
5
|
+
import type { Journal } from "./journal.js";
|
|
6
|
+
import type { Trace } from "./trace.js";
|
|
7
|
+
export type TransformerSlots = {
|
|
8
|
+
/** Where the Transformers say what they are doing. Absent: nowhere. */
|
|
9
|
+
trace?: Trace;
|
|
10
|
+
/** Film of every progress line, including ones the Trace drops. Absent: nowhere. */
|
|
11
|
+
journal?: Journal;
|
|
12
|
+
planner: PassSpec;
|
|
13
|
+
/** Making a Subtask, and the Gates judging what came out of it. */
|
|
14
|
+
builder: StageSpec;
|
|
15
|
+
/** Judging the assembled feature, and the command that fixes a refusal. */
|
|
16
|
+
assembly: AssemblySpec;
|
|
17
|
+
/** How Isolator produces the Child. Host chooses; Isolator does not sniff. */
|
|
18
|
+
isolation: IsolationBackend;
|
|
19
|
+
/** How Integrator folds. Must match `isolation`. */
|
|
20
|
+
fold: FoldBackend;
|
|
21
|
+
/** How long any one child outside a Task may run: manager, isolations. */
|
|
22
|
+
timeoutMs: number;
|
|
23
|
+
maxUnits: number;
|
|
24
|
+
maxFeatureBytes: number;
|
|
25
|
+
};
|
|
26
|
+
export declare function createTransformers(slots: TransformerSlots): TransformerPort;
|
|
27
|
+
//# sourceMappingURL=transformers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformers.d.ts","sourceRoot":"","sources":["../../src/loop/transformers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoC,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAO/F,OAAO,EAAE,KAAK,WAAW,EAAiB,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,KAAK,gBAAgB,EAAe,MAAM,sBAAsB,CAAC;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,uEAAuE;IACvE,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,oFAAoF;IACpF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,QAAQ,CAAC;IAClB,mEAAmE;IACnE,OAAO,EAAE,SAAS,CAAC;IACnB,2EAA2E;IAC3E,QAAQ,EAAE,YAAY,CAAC;IACvB,8EAA8E;IAC9E,SAAS,EAAE,gBAAgB,CAAC;IAC5B,oDAAoD;IACpD,IAAI,EAAE,WAAW,CAAC;IAClB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AA8IF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,GAAG,eAAe,CA8G3E"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { runBreakdown } from "@bluewombat/feature-breakdown";
|
|
2
|
+
import { runImplementer, } from "@bluewombat/implementer";
|
|
3
|
+
import { runIntegrator } from "@bluewombat/integrator";
|
|
4
|
+
import { runIsolator } from "@bluewombat/isolator";
|
|
5
|
+
const DEFAULT_MAX_ATTEMPTS = 3;
|
|
6
|
+
const silent = () => { };
|
|
7
|
+
/**
|
|
8
|
+
* A Transformer's progress, as a line a person reads.
|
|
9
|
+
*
|
|
10
|
+
* Each of them already says what it is doing on its own writer; Host used to
|
|
11
|
+
* drop all of it, which is why a run of several minutes said nothing at all.
|
|
12
|
+
* Only the lines that name a phase or an outcome are kept — the rest is
|
|
13
|
+
* bookkeeping nobody watches.
|
|
14
|
+
*/
|
|
15
|
+
function progressTrace(trace) {
|
|
16
|
+
if (trace === undefined) {
|
|
17
|
+
return silent;
|
|
18
|
+
}
|
|
19
|
+
return (line) => {
|
|
20
|
+
// Only the phase labels. Each Transformer also writes a closing line with
|
|
21
|
+
// the outcome, and that outcome is already the last phase it announced.
|
|
22
|
+
if (typeof line.label !== "string") {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const id = typeof line.id === "string" ? line.id : String(line.task_id ?? "");
|
|
26
|
+
const label = id.length > 0 ? line.label.replace(`:${id}`, "") : line.label;
|
|
27
|
+
trace(id.length > 0 ? ` ${id} ${label}` : ` ${label}`);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The journal keeps every progress line; the Trace keeps the ones a person reads.
|
|
32
|
+
*/
|
|
33
|
+
function progressWriter(slots) {
|
|
34
|
+
const toTrace = progressTrace(slots.trace);
|
|
35
|
+
const journal = slots.journal;
|
|
36
|
+
return (line) => {
|
|
37
|
+
journal?.append({ ...line });
|
|
38
|
+
toTrace(line);
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Wire the four execution Transformers into Conductor's Transformer Port.
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
45
|
+
* Why an Attempt ended, when it did not end well.
|
|
46
|
+
*
|
|
47
|
+
* The first Gate that did not pass is the one that stopped the sequence, so its
|
|
48
|
+
* report is the reason. With no such Gate, the producer is what failed, and the
|
|
49
|
+
* detail it left is the reason.
|
|
50
|
+
*/
|
|
51
|
+
/**
|
|
52
|
+
* What ended this Attempt, and what said so.
|
|
53
|
+
*
|
|
54
|
+
* The name matters as much as the words: a report handed on unattributed
|
|
55
|
+
* reaches the next producer as "something refused this", and the Gate that
|
|
56
|
+
* looked at the work is exactly what tells it where to look.
|
|
57
|
+
*/
|
|
58
|
+
function reasonOf(trace) {
|
|
59
|
+
const refused = trace.gates.find((gate) => gate.verdict !== "pass");
|
|
60
|
+
if (refused !== undefined && refused.report.trim().length > 0) {
|
|
61
|
+
return { report: refused.report, from: refused.id };
|
|
62
|
+
}
|
|
63
|
+
const detail = trace.builder.result.detail;
|
|
64
|
+
return detail !== undefined && detail.trim().length > 0 ? { report: detail } : undefined;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Which sequence judges this Task.
|
|
68
|
+
*
|
|
69
|
+
* `assembly.gates` judge what was published, so they belong to the pass that
|
|
70
|
+
* judges — not to the one that makes, whose Gates would still be looking at what
|
|
71
|
+
* was there before it published anything.
|
|
72
|
+
*
|
|
73
|
+
* A making pass is judged like any other making pass, by the Project's own
|
|
74
|
+
* sequence. Leaving it ungated lets a producer that made nothing pass, republish
|
|
75
|
+
* the same thing, and be refused again until the budget is gone.
|
|
76
|
+
*/
|
|
77
|
+
function gatesFor(input, slots) {
|
|
78
|
+
return input.stage === "assembly" && input.produce === false
|
|
79
|
+
? slots.assembly.gates
|
|
80
|
+
: slots.builder.gates;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* How long the agent of this pass may run.
|
|
84
|
+
*
|
|
85
|
+
* A Subtask names its producer. An assembly names a fix, and only when something
|
|
86
|
+
* already refused the whole.
|
|
87
|
+
*/
|
|
88
|
+
function commandTimeoutMs(input, slots) {
|
|
89
|
+
if (input.stage === "assembly") {
|
|
90
|
+
return slots.assembly.fix?.timeoutMs ?? slots.timeoutMs;
|
|
91
|
+
}
|
|
92
|
+
return slots.builder.producer.timeoutMs;
|
|
93
|
+
}
|
|
94
|
+
function attemptBudget(input, slots) {
|
|
95
|
+
if (input.produce === false) {
|
|
96
|
+
return 1;
|
|
97
|
+
}
|
|
98
|
+
const stage = input.stage === "assembly" ? slots.assembly : slots.builder;
|
|
99
|
+
return stage.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
|
|
100
|
+
}
|
|
101
|
+
function producersFor(input, slots) {
|
|
102
|
+
if (input.produce === false) {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
if (input.stage === "assembly") {
|
|
106
|
+
const fix = slots.assembly.fix;
|
|
107
|
+
if (fix === undefined) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
// Implementer picks repairArgv only when a report is present, and Conductor
|
|
111
|
+
// never produces at assembly without one. The fix command is the producer.
|
|
112
|
+
return { builderArgv: fix.cmd };
|
|
113
|
+
}
|
|
114
|
+
const { producer, repair } = slots.builder;
|
|
115
|
+
return {
|
|
116
|
+
builderArgv: producer.cmd,
|
|
117
|
+
repairArgv: repair.cmd,
|
|
118
|
+
repairTimeoutMs: repair.timeoutMs,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
export function createTransformers(slots) {
|
|
122
|
+
const write = progressWriter(slots);
|
|
123
|
+
return {
|
|
124
|
+
async isolate(input) {
|
|
125
|
+
const result = await runIsolator({
|
|
126
|
+
invocation: {
|
|
127
|
+
id: input.id,
|
|
128
|
+
parent: input.parent,
|
|
129
|
+
child: input.child,
|
|
130
|
+
durationMs: input.durationMs,
|
|
131
|
+
},
|
|
132
|
+
backend: slots.isolation,
|
|
133
|
+
write,
|
|
134
|
+
});
|
|
135
|
+
return { outcome: result.outcome };
|
|
136
|
+
},
|
|
137
|
+
async breakDown(input) {
|
|
138
|
+
const result = await runBreakdown({
|
|
139
|
+
invocation: {
|
|
140
|
+
maxFeatureBytes: slots.maxFeatureBytes,
|
|
141
|
+
maxUnits: slots.maxUnits,
|
|
142
|
+
plannerArgv: slots.planner.cmd,
|
|
143
|
+
plannerDurationMs: slots.planner.timeoutMs,
|
|
144
|
+
},
|
|
145
|
+
featureJson: input.featureJson,
|
|
146
|
+
write,
|
|
147
|
+
});
|
|
148
|
+
if (result.outcome === "planned" && result.plan !== undefined) {
|
|
149
|
+
return {
|
|
150
|
+
outcome: "planned",
|
|
151
|
+
plannedAt: result.plan.planned_at,
|
|
152
|
+
subtasks: result.plan.subtasks.map((st) => ({
|
|
153
|
+
id: st.id,
|
|
154
|
+
intention: st.intention,
|
|
155
|
+
definition_of_done: st.definition_of_done,
|
|
156
|
+
depends_on: [...st.depends_on],
|
|
157
|
+
})),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
if (result.outcome === "refused") {
|
|
161
|
+
return {
|
|
162
|
+
outcome: "refused",
|
|
163
|
+
code: result.code ?? "not-specifiable",
|
|
164
|
+
reason: result.reason ?? "FeatureBreakdown refused the Plan.",
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
if (result.outcome === "unavailable" || result.outcome === "interrupted") {
|
|
168
|
+
return { outcome: result.outcome };
|
|
169
|
+
}
|
|
170
|
+
return { outcome: "invalid-invocation" };
|
|
171
|
+
},
|
|
172
|
+
async implement(input) {
|
|
173
|
+
const producers = producersFor(input, slots);
|
|
174
|
+
const result = await runImplementer({
|
|
175
|
+
invocation: {
|
|
176
|
+
id: input.id,
|
|
177
|
+
intention: input.intention,
|
|
178
|
+
// Implementer always carries the flag and never reads it; an assembly
|
|
179
|
+
// has nothing to put in it, and the roles drop an empty one whole.
|
|
180
|
+
definitionOfDone: input.definitionOfDone ?? "",
|
|
181
|
+
workspace: input.workspace,
|
|
182
|
+
// Without this the report an outside judge sent back never reaches
|
|
183
|
+
// the producer, and the Attempt repeats blind.
|
|
184
|
+
...(input.report === undefined ? {} : { report: input.report }),
|
|
185
|
+
...(input.reportFrom === undefined ? {} : { reportFrom: input.reportFrom }),
|
|
186
|
+
...(input.context === undefined ? {} : { context: input.context }),
|
|
187
|
+
...(input.stage === undefined ? {} : { stage: input.stage }),
|
|
188
|
+
...(producers === undefined ? {} : producers),
|
|
189
|
+
gates: gatesFor(input, slots),
|
|
190
|
+
// A pass that makes nothing cannot make a different result on a second
|
|
191
|
+
// try: whoever asked for the judgement owns the retrying.
|
|
192
|
+
maxAttempts: attemptBudget(input, slots),
|
|
193
|
+
builderTimeoutMs: commandTimeoutMs(input, slots),
|
|
194
|
+
},
|
|
195
|
+
write,
|
|
196
|
+
});
|
|
197
|
+
return {
|
|
198
|
+
outcome: result.outcome,
|
|
199
|
+
traces: result.traces.map((trace) => {
|
|
200
|
+
const reason = reasonOf(trace);
|
|
201
|
+
if (reason === undefined) {
|
|
202
|
+
return { ended: trace.ended };
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
ended: trace.ended,
|
|
206
|
+
report: reason.report,
|
|
207
|
+
...(reason.from === undefined ? {} : { refusedBy: reason.from }),
|
|
208
|
+
};
|
|
209
|
+
}),
|
|
210
|
+
};
|
|
211
|
+
},
|
|
212
|
+
async integrate(input) {
|
|
213
|
+
const result = await runIntegrator({
|
|
214
|
+
invocation: {
|
|
215
|
+
id: input.id,
|
|
216
|
+
parent: input.parent,
|
|
217
|
+
child: input.child,
|
|
218
|
+
durationMs: input.durationMs,
|
|
219
|
+
...(input.subject === undefined ? {} : { subject: input.subject }),
|
|
220
|
+
...(input.mergeSubject === undefined ? {} : { mergeSubject: input.mergeSubject }),
|
|
221
|
+
},
|
|
222
|
+
backend: slots.fold,
|
|
223
|
+
write,
|
|
224
|
+
});
|
|
225
|
+
return { outcome: result.outcome };
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=transformers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformers.js","sourceRoot":"","sources":["../../src/loop/transformers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { IsolationStrategy, ParsedReference, ReferenceCopyState } from "../plugins/isolation.js";
|
|
2
|
+
export type WorkLineState = {
|
|
3
|
+
kind: "missing";
|
|
4
|
+
} | {
|
|
5
|
+
kind: "not-a-directory";
|
|
6
|
+
} | {
|
|
7
|
+
kind: "plain";
|
|
8
|
+
} | {
|
|
9
|
+
kind: "git";
|
|
10
|
+
branch: string;
|
|
11
|
+
};
|
|
12
|
+
/** What is at that path today. Integrator folds by merge only on a git tree. */
|
|
13
|
+
export declare function inspectWorkLine(path: string): WorkLineState;
|
|
14
|
+
export type WorkLineInput = {
|
|
15
|
+
/** Host's own directory; the copy of a reference lives there unless `stable` says otherwise. */
|
|
16
|
+
home: string;
|
|
17
|
+
/** `workLine.stable`, when the operator set it. */
|
|
18
|
+
stable: string | undefined;
|
|
19
|
+
/** `workLine.branch`, when the operator set it. */
|
|
20
|
+
branch: string | undefined;
|
|
21
|
+
/** The manager's name, for the messages. */
|
|
22
|
+
manager: string;
|
|
23
|
+
/** `authority.enabled`. Without one, the work line is the operator's whatever the manager names. */
|
|
24
|
+
wantsAuthority: boolean;
|
|
25
|
+
/** What `referenceManager` returned, unread. */
|
|
26
|
+
reference: Record<string, unknown> | undefined;
|
|
27
|
+
strategy: IsolationStrategy;
|
|
28
|
+
strategyName: string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Which directory is the work line, and whose it is.
|
|
32
|
+
*
|
|
33
|
+
* - `operators`: no reference is named, so `workLine.stable` is a work line
|
|
34
|
+
* the operator maintains — the fold lands there and that is final.
|
|
35
|
+
* - `unchecked`: a reference is named but this strategy cannot read one, so an
|
|
36
|
+
* explicit `workLine.stable` is taken on trust, as before any of this.
|
|
37
|
+
* - `copy`: a reference is named and read. The directory is Host's copy of it,
|
|
38
|
+
* whether the operator chose the path or the default did.
|
|
39
|
+
* - `invalid`: something disagrees, and the run must not start.
|
|
40
|
+
*/
|
|
41
|
+
export type WorkLineResolution = {
|
|
42
|
+
kind: "operators";
|
|
43
|
+
stable: string;
|
|
44
|
+
} | {
|
|
45
|
+
kind: "unchecked";
|
|
46
|
+
stable: string;
|
|
47
|
+
reason: string;
|
|
48
|
+
} | {
|
|
49
|
+
kind: "copy";
|
|
50
|
+
stable: string;
|
|
51
|
+
target: string;
|
|
52
|
+
reference: ParsedReference;
|
|
53
|
+
state: ReferenceCopyState;
|
|
54
|
+
} | {
|
|
55
|
+
kind: "invalid";
|
|
56
|
+
reason: string;
|
|
57
|
+
};
|
|
58
|
+
/** Offline. Everything here reads; `materializeWorkLine` is the one write. */
|
|
59
|
+
export declare function resolveWorkLine(input: WorkLineInput): WorkLineResolution;
|
|
60
|
+
/**
|
|
61
|
+
* Bring a `copy` resolution to a directory a run can use: fetch a missing one,
|
|
62
|
+
* refuse a directory that is not a copy of the reference. Network.
|
|
63
|
+
*/
|
|
64
|
+
export declare function materializeWorkLine(resolution: Extract<WorkLineResolution, {
|
|
65
|
+
kind: "copy";
|
|
66
|
+
}>): Promise<{
|
|
67
|
+
ok: true;
|
|
68
|
+
fetched: boolean;
|
|
69
|
+
} | {
|
|
70
|
+
ok: false;
|
|
71
|
+
reason: string;
|
|
72
|
+
}>;
|
|
73
|
+
//# sourceMappingURL=work-line.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work-line.d.ts","sourceRoot":"","sources":["../../src/loop/work-line.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EACnB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpC,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAW3D;AAgBD,MAAM,MAAM,aAAa,GAAG;IAC1B,gGAAgG;IAChG,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,mDAAmD;IACnD,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,oGAAoG;IACpG,cAAc,EAAE,OAAO,CAAC;IACxB,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC/C,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,eAAe,CAAC;IAC3B,KAAK,EAAE,kBAAkB,CAAC;CAC3B,GACD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,kBAAkB,CAgDxE;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,OAAO,CAAC,kBAAkB,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GACxD,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAkBzE"}
|