@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.
Files changed (151) hide show
  1. package/README.md +473 -0
  2. package/SPECS.md +303 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +172 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/config/defaults.d.ts +17 -0
  8. package/dist/config/defaults.d.ts.map +1 -0
  9. package/dist/config/defaults.js +17 -0
  10. package/dist/config/defaults.js.map +1 -0
  11. package/dist/config/find-config.d.ts +9 -0
  12. package/dist/config/find-config.d.ts.map +1 -0
  13. package/dist/config/find-config.js +25 -0
  14. package/dist/config/find-config.js.map +1 -0
  15. package/dist/config/home.d.ts +17 -0
  16. package/dist/config/home.d.ts.map +1 -0
  17. package/dist/config/home.js +23 -0
  18. package/dist/config/home.js.map +1 -0
  19. package/dist/config/load-config.d.ts +13 -0
  20. package/dist/config/load-config.d.ts.map +1 -0
  21. package/dist/config/load-config.js +537 -0
  22. package/dist/config/load-config.js.map +1 -0
  23. package/dist/config/parse-args.d.ts +25 -0
  24. package/dist/config/parse-args.d.ts.map +1 -0
  25. package/dist/config/parse-args.js +478 -0
  26. package/dist/config/parse-args.js.map +1 -0
  27. package/dist/config/types.d.ts +144 -0
  28. package/dist/config/types.d.ts.map +1 -0
  29. package/dist/config/types.js +2 -0
  30. package/dist/config/types.js.map +1 -0
  31. package/dist/index.d.ts +30 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +16 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/loop/authority.d.ts +51 -0
  36. package/dist/loop/authority.d.ts.map +1 -0
  37. package/dist/loop/authority.js +166 -0
  38. package/dist/loop/authority.js.map +1 -0
  39. package/dist/loop/context.d.ts +44 -0
  40. package/dist/loop/context.d.ts.map +1 -0
  41. package/dist/loop/context.js +2 -0
  42. package/dist/loop/context.js.map +1 -0
  43. package/dist/loop/cursor.d.ts +4 -0
  44. package/dist/loop/cursor.d.ts.map +1 -0
  45. package/dist/loop/cursor.js +20 -0
  46. package/dist/loop/cursor.js.map +1 -0
  47. package/dist/loop/deliveries.d.ts +22 -0
  48. package/dist/loop/deliveries.d.ts.map +1 -0
  49. package/dist/loop/deliveries.js +240 -0
  50. package/dist/loop/deliveries.js.map +1 -0
  51. package/dist/loop/describe.d.ts +40 -0
  52. package/dist/loop/describe.d.ts.map +1 -0
  53. package/dist/loop/describe.js +48 -0
  54. package/dist/loop/describe.js.map +1 -0
  55. package/dist/loop/drive.d.ts +15 -0
  56. package/dist/loop/drive.d.ts.map +1 -0
  57. package/dist/loop/drive.js +42 -0
  58. package/dist/loop/drive.js.map +1 -0
  59. package/dist/loop/journal.d.ts +22 -0
  60. package/dist/loop/journal.d.ts.map +1 -0
  61. package/dist/loop/journal.js +49 -0
  62. package/dist/loop/journal.js.map +1 -0
  63. package/dist/loop/lock.d.ts +11 -0
  64. package/dist/loop/lock.d.ts.map +1 -0
  65. package/dist/loop/lock.js +60 -0
  66. package/dist/loop/lock.js.map +1 -0
  67. package/dist/loop/message.d.ts +34 -0
  68. package/dist/loop/message.d.ts.map +1 -0
  69. package/dist/loop/message.js +48 -0
  70. package/dist/loop/message.js.map +1 -0
  71. package/dist/loop/open-host.d.ts +13 -0
  72. package/dist/loop/open-host.d.ts.map +1 -0
  73. package/dist/loop/open-host.js +180 -0
  74. package/dist/loop/open-host.js.map +1 -0
  75. package/dist/loop/probe.d.ts +9 -0
  76. package/dist/loop/probe.d.ts.map +1 -0
  77. package/dist/loop/probe.js +57 -0
  78. package/dist/loop/probe.js.map +1 -0
  79. package/dist/loop/report.d.ts +26 -0
  80. package/dist/loop/report.d.ts.map +1 -0
  81. package/dist/loop/report.js +328 -0
  82. package/dist/loop/report.js.map +1 -0
  83. package/dist/loop/tick.d.ts +24 -0
  84. package/dist/loop/tick.d.ts.map +1 -0
  85. package/dist/loop/tick.js +169 -0
  86. package/dist/loop/tick.js.map +1 -0
  87. package/dist/loop/trace.d.ts +16 -0
  88. package/dist/loop/trace.d.ts.map +1 -0
  89. package/dist/loop/trace.js +49 -0
  90. package/dist/loop/trace.js.map +1 -0
  91. package/dist/loop/transformers.d.ts +27 -0
  92. package/dist/loop/transformers.d.ts.map +1 -0
  93. package/dist/loop/transformers.js +229 -0
  94. package/dist/loop/transformers.js.map +1 -0
  95. package/dist/loop/work-line.d.ts +73 -0
  96. package/dist/loop/work-line.d.ts.map +1 -0
  97. package/dist/loop/work-line.js +109 -0
  98. package/dist/loop/work-line.js.map +1 -0
  99. package/dist/operator/board.d.ts +31 -0
  100. package/dist/operator/board.d.ts.map +1 -0
  101. package/dist/operator/board.js +67 -0
  102. package/dist/operator/board.js.map +1 -0
  103. package/dist/operator/cancel.d.ts +19 -0
  104. package/dist/operator/cancel.d.ts.map +1 -0
  105. package/dist/operator/cancel.js +70 -0
  106. package/dist/operator/cancel.js.map +1 -0
  107. package/dist/operator/doctor.d.ts +15 -0
  108. package/dist/operator/doctor.d.ts.map +1 -0
  109. package/dist/operator/doctor.js +416 -0
  110. package/dist/operator/doctor.js.map +1 -0
  111. package/dist/operator/git-remote.d.ts +39 -0
  112. package/dist/operator/git-remote.d.ts.map +1 -0
  113. package/dist/operator/git-remote.js +78 -0
  114. package/dist/operator/git-remote.js.map +1 -0
  115. package/dist/operator/init.d.ts +28 -0
  116. package/dist/operator/init.d.ts.map +1 -0
  117. package/dist/operator/init.js +522 -0
  118. package/dist/operator/init.js.map +1 -0
  119. package/dist/operator/live.d.ts +19 -0
  120. package/dist/operator/live.d.ts.map +1 -0
  121. package/dist/operator/live.js +149 -0
  122. package/dist/operator/live.js.map +1 -0
  123. package/dist/operator/prompt.d.ts +35 -0
  124. package/dist/operator/prompt.d.ts.map +1 -0
  125. package/dist/operator/prompt.js +125 -0
  126. package/dist/operator/prompt.js.map +1 -0
  127. package/dist/operator/setup.d.ts +18 -0
  128. package/dist/operator/setup.d.ts.map +1 -0
  129. package/dist/operator/setup.js +62 -0
  130. package/dist/operator/setup.js.map +1 -0
  131. package/dist/plugins/discover.d.ts +13 -0
  132. package/dist/plugins/discover.d.ts.map +1 -0
  133. package/dist/plugins/discover.js +81 -0
  134. package/dist/plugins/discover.js.map +1 -0
  135. package/dist/plugins/isolation.d.ts +78 -0
  136. package/dist/plugins/isolation.d.ts.map +1 -0
  137. package/dist/plugins/isolation.js +64 -0
  138. package/dist/plugins/isolation.js.map +1 -0
  139. package/dist/plugins/load.d.ts +35 -0
  140. package/dist/plugins/load.d.ts.map +1 -0
  141. package/dist/plugins/load.js +109 -0
  142. package/dist/plugins/load.js.map +1 -0
  143. package/dist/plugins/manager.d.ts +43 -0
  144. package/dist/plugins/manager.d.ts.map +1 -0
  145. package/dist/plugins/manager.js +47 -0
  146. package/dist/plugins/manager.js.map +1 -0
  147. package/dist/plugins/persist.d.ts +33 -0
  148. package/dist/plugins/persist.d.ts.map +1 -0
  149. package/dist/plugins/persist.js +26 -0
  150. package/dist/plugins/persist.js.map +1 -0
  151. package/package.json +66 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deliveries.js","sourceRoot":"","sources":["../../src/loop/deliveries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { PassSpec } from "../config/types.js";
2
+ /**
3
+ * How a delivered feature describes itself is the Project's decision, not
4
+ * Host's: a team has conventions, and an agent can read the change and
5
+ * follow them. The Describer slot is where that lives. Host spawns it once
6
+ * per feature, in the feature workspace where the whole change is, tells it
7
+ * what was asked, and takes one JSON line back: `{ subject, body? }`. What
8
+ * the Authority makes of those words is the manager's business — for GitHub,
9
+ * the fold's message and the pull request's text. A Subtask is never
10
+ * described: its fold is folded again into the feature's, and words spent on
11
+ * it are words wasted.
12
+ *
13
+ * A slot that fails — cannot run, answers nothing readable, subject empty —
14
+ * is not a reason to lose the Submission: the caller keeps the words it had,
15
+ * and the journal says the slot was skipped.
16
+ */
17
+ export type DescribeInput = {
18
+ id: string;
19
+ /** The issue's title, as the human wrote it. */
20
+ title: string;
21
+ /** The issue's body, as the human wrote it. */
22
+ intention: string;
23
+ /** The work line the change will land on, so the slot can diff against it. */
24
+ target: string;
25
+ /** The feature workspace; the slot may read its diff. */
26
+ cwd: string;
27
+ };
28
+ export type Description = {
29
+ subject: string;
30
+ body?: string;
31
+ };
32
+ export type DescribeAnswer = {
33
+ ok: true;
34
+ description: Description;
35
+ } | {
36
+ ok: false;
37
+ detail: string;
38
+ };
39
+ export declare function describe(slot: PassSpec, input: DescribeInput): DescribeAnswer;
40
+ //# sourceMappingURL=describe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe.d.ts","sourceRoot":"","sources":["../../src/loop/describe.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,MAAM,MAAM,cAAc,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpG,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,GAAG,cAAc,CAkC7E"}
@@ -0,0 +1,48 @@
1
+ import { spawnSync } from "node:child_process";
2
+ export function describe(slot, input) {
3
+ const [command, ...rest] = slot.cmd;
4
+ if (command === undefined) {
5
+ return { ok: false, detail: "the Describer has no command" };
6
+ }
7
+ const run = spawnSync(command, [
8
+ ...rest,
9
+ "--id",
10
+ input.id,
11
+ "--title",
12
+ input.title,
13
+ "--intention",
14
+ input.intention,
15
+ "--target",
16
+ input.target,
17
+ ], { cwd: input.cwd, encoding: "utf8", timeout: slot.timeoutMs });
18
+ if (run.error !== undefined) {
19
+ return { ok: false, detail: `Describer could not run: ${run.error.message}` };
20
+ }
21
+ const answer = lastJsonLine(run.stdout ?? "");
22
+ if (answer === undefined) {
23
+ const detail = `${run.stderr ?? ""}`.trim().slice(-500);
24
+ return { ok: false, detail: `Describer stdout is not a JSON object. ${detail}`.trim() };
25
+ }
26
+ const subject = typeof answer.subject === "string" ? answer.subject.trim() : "";
27
+ if (subject.length === 0) {
28
+ return { ok: false, detail: "Describer answered no subject." };
29
+ }
30
+ const body = typeof answer.body === "string" ? answer.body.trim() : "";
31
+ return { ok: true, description: body.length === 0 ? { subject } : { subject, body } };
32
+ }
33
+ function lastJsonLine(stdout) {
34
+ const lines = stdout.split("\n").filter((line) => line.trim().length > 0);
35
+ for (let i = lines.length - 1; i >= 0; i--) {
36
+ try {
37
+ const parsed = JSON.parse(lines[i] ?? "");
38
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
39
+ return parsed;
40
+ }
41
+ }
42
+ catch {
43
+ // not this line
44
+ }
45
+ }
46
+ return undefined;
47
+ }
48
+ //# sourceMappingURL=describe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe.js","sourceRoot":"","sources":["../../src/loop/describe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { ProjectRunResult } from "@bluewombat/conductor";
2
+ import type { HostDeliveryInput } from "./context.js";
3
+ /**
4
+ * Drive one Project and report on the Feature that actually ran.
5
+ *
6
+ * A delivery names a key; `runProject` drives whoever is active on that
7
+ * Project. Attributing the outcome to the delivered key closed the wrong
8
+ * issue, or posted an escalation on one that had only been admitted.
9
+ *
10
+ * An `escalated` Feature is frozen until a human answers: driving it only
11
+ * repeats the verdict. The delivered key is journaled as queued, and a
12
+ * `progress` Event says so once on the tracker.
13
+ */
14
+ export declare function driveProject(input: HostDeliveryInput, project: string, fallbackKey: string): Promise<ProjectRunResult | undefined>;
15
+ //# sourceMappingURL=drive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive.d.ts","sourceRoot":"","sources":["../../src/loop/drive.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAItD;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CA2BvC"}
@@ -0,0 +1,42 @@
1
+ import { journalFeature, pushReport, reportAfterRun } from "./report.js";
2
+ import { describeFeature } from "./trace.js";
3
+ /**
4
+ * Drive one Project and report on the Feature that actually ran.
5
+ *
6
+ * A delivery names a key; `runProject` drives whoever is active on that
7
+ * Project. Attributing the outcome to the delivered key closed the wrong
8
+ * issue, or posted an escalation on one that had only been admitted.
9
+ *
10
+ * An `escalated` Feature is frozen until a human answers: driving it only
11
+ * repeats the verdict. The delivered key is journaled as queued, and a
12
+ * `progress` Event says so once on the tracker.
13
+ */
14
+ export async function driveProject(input, project, fallbackKey) {
15
+ const held = await input.ledger.activeOn(project);
16
+ if (held?.state === "escalated") {
17
+ input.journal.append({ event: "queued", key: fallbackKey, behind: held.key });
18
+ input.trace(`queued ${fallbackKey} behind ${held.key} (escalated)`);
19
+ await pushReport(input, {
20
+ event: "progress",
21
+ key: fallbackKey,
22
+ project,
23
+ eventId: `${fallbackKey}:queued:${held.key}`,
24
+ fields: {
25
+ summary: `Queued behind ${held.key}, which is escalated.`,
26
+ },
27
+ });
28
+ return undefined;
29
+ }
30
+ await input.conductor.reconcile(project);
31
+ const run = await input.conductor.runProject(project);
32
+ // idle / refused name no Feature; the delivered key is the only one we have.
33
+ const key = "key" in run && run.key !== undefined ? run.key : fallbackKey;
34
+ const got = await input.ledger.get(key);
35
+ if (got.ok) {
36
+ input.trace(describeFeature(got.aggregate));
37
+ journalFeature(input.journal, run.outcome, got.aggregate, input.said);
38
+ await reportAfterRun(input, run, got.aggregate);
39
+ }
40
+ return run;
41
+ }
42
+ //# sourceMappingURL=drive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive.js","sourceRoot":"","sources":["../../src/loop/drive.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAwB,EACxB,OAAe,EACf,WAAmB;IAEnB,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAClD,IAAI,IAAI,EAAE,KAAK,KAAK,WAAW,EAAE,CAAC;QAChC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC9E,KAAK,CAAC,KAAK,CAAC,cAAc,WAAW,WAAW,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;QACxE,MAAM,UAAU,CAAC,KAAK,EAAE;YACtB,KAAK,EAAE,UAAU;YACjB,GAAG,EAAE,WAAW;YAChB,OAAO;YACP,OAAO,EAAE,GAAG,WAAW,WAAW,IAAI,CAAC,GAAG,EAAE;YAC5C,MAAM,EAAE;gBACN,OAAO,EAAE,iBAAiB,IAAI,CAAC,GAAG,uBAAuB;aAC1D;SACF,CAAC,CAAC;QACH,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACtD,6EAA6E;IAC7E,MAAM,GAAG,GAAG,KAAK,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;IAC1E,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;QACX,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;QAC5C,cAAc,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACtE,MAAM,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,22 @@
1
+ /** Film of a run, next to `cursor` under the ledger root. Not truth. */
2
+ export declare const JOURNAL_FILENAME = "events.jsonl";
3
+ export type Journal = {
4
+ append(line: Record<string, unknown>): void;
5
+ };
6
+ export declare function journalPath(ledgerRoot: string): string;
7
+ /**
8
+ * Append-only JSON lines. Host stamps `at`; Transformer fields pass through.
9
+ *
10
+ * Sync because a Transformer's ProgressWriter is sync, and the film must land
11
+ * before the next phase starts or a crash cuts the process off.
12
+ */
13
+ export declare function openJournalFile(ledgerRoot: string, now?: () => Date): Journal;
14
+ /**
15
+ * Split a file chunk into complete JSON objects. A truncated last line stays
16
+ * in `remainder` and is not parsed as a Feature.
17
+ */
18
+ export declare function parseJournalChunk(chunk: string, remainder: string): {
19
+ lines: Record<string, unknown>[];
20
+ remainder: string;
21
+ };
22
+ //# sourceMappingURL=journal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../../src/loop/journal.ts"],"names":[],"mappings":"AAGA,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,iBAAiB,CAAC;AAE/C,MAAM,MAAM,OAAO,GAAG;IACpB,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC7C,CAAC;AAEF,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,IAAuB,GAAG,OAAO,CAS/F;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB;IAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAmBzD"}
@@ -0,0 +1,49 @@
1
+ import { appendFileSync, mkdirSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ /** Film of a run, next to `cursor` under the ledger root. Not truth. */
4
+ export const JOURNAL_FILENAME = "events.jsonl";
5
+ export function journalPath(ledgerRoot) {
6
+ return join(ledgerRoot, JOURNAL_FILENAME);
7
+ }
8
+ /**
9
+ * Append-only JSON lines. Host stamps `at`; Transformer fields pass through.
10
+ *
11
+ * Sync because a Transformer's ProgressWriter is sync, and the film must land
12
+ * before the next phase starts or a crash cuts the process off.
13
+ */
14
+ export function openJournalFile(ledgerRoot, now = () => new Date()) {
15
+ mkdirSync(ledgerRoot, { recursive: true });
16
+ const path = journalPath(ledgerRoot);
17
+ return {
18
+ append(line) {
19
+ const stamped = { ...line, at: now().toISOString() };
20
+ appendFileSync(path, `${JSON.stringify(stamped)}\n`);
21
+ },
22
+ };
23
+ }
24
+ /**
25
+ * Split a file chunk into complete JSON objects. A truncated last line stays
26
+ * in `remainder` and is not parsed as a Feature.
27
+ */
28
+ export function parseJournalChunk(chunk, remainder) {
29
+ const text = `${remainder}${chunk}`;
30
+ const parts = text.split("\n");
31
+ const nextRemainder = parts.pop() ?? "";
32
+ const lines = [];
33
+ for (const part of parts) {
34
+ if (part.trim().length === 0) {
35
+ continue;
36
+ }
37
+ try {
38
+ const parsed = JSON.parse(part);
39
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
40
+ lines.push(parsed);
41
+ }
42
+ }
43
+ catch {
44
+ // Garbage or a split object that gained a newline: skip, do not invent a Feature.
45
+ }
46
+ }
47
+ return { lines, remainder: nextRemainder };
48
+ }
49
+ //# sourceMappingURL=journal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal.js","sourceRoot":"","sources":["../../src/loop/journal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,wEAAwE;AACxE,MAAM,CAAC,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAM/C,MAAM,UAAU,WAAW,CAAC,UAAkB;IAC5C,OAAO,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,UAAkB,EAAE,MAAkB,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE;IACpF,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;IACrC,OAAO;QACL,MAAM,CAAC,IAAI;YACT,MAAM,OAAO,GAA4B,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;YAC9E,cAAc,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvD,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAa,EACb,SAAiB;IAEjB,MAAM,IAAI,GAAG,GAAG,SAAS,GAAG,KAAK,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,aAAa,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IACxC,MAAM,KAAK,GAA8B,EAAE,CAAC;IAC5C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,SAAS;QACX,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzC,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5E,KAAK,CAAC,IAAI,CAAC,MAAiC,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,kFAAkF;QACpF,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * One `run` or `cancel` per ledger.
3
+ *
4
+ * Two processes on the same ledger both listen, both drive, and both report: the
5
+ * tracker hears everything twice and the feature is folded by whichever got
6
+ * there first. A lock file names the process that holds the ledger; a second
7
+ * command refuses to start, unless that process is gone.
8
+ */
9
+ export declare function lockPath(ledgerRoot: string): string;
10
+ export declare function acquireLock(ledgerRoot: string): Promise<() => Promise<void>>;
11
+ //# sourceMappingURL=lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/loop/lock.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CA+BlF"}
@@ -0,0 +1,60 @@
1
+ import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { PRODUCT } from "@bluewombat/manager-kit";
4
+ /**
5
+ * One `run` or `cancel` per ledger.
6
+ *
7
+ * Two processes on the same ledger both listen, both drive, and both report: the
8
+ * tracker hears everything twice and the feature is folded by whichever got
9
+ * there first. A lock file names the process that holds the ledger; a second
10
+ * command refuses to start, unless that process is gone.
11
+ */
12
+ export function lockPath(ledgerRoot) {
13
+ return join(ledgerRoot, "lock");
14
+ }
15
+ export async function acquireLock(ledgerRoot) {
16
+ await mkdir(ledgerRoot, { recursive: true });
17
+ const path = lockPath(ledgerRoot);
18
+ const mine = `${process.pid}\n`;
19
+ for (;;) {
20
+ try {
21
+ await writeFile(path, mine, { flag: "wx" });
22
+ break;
23
+ }
24
+ catch (error) {
25
+ if (error.code !== "EEXIST") {
26
+ throw error;
27
+ }
28
+ }
29
+ const holder = Number.parseInt((await readFile(path, "utf8")).trim(), 10);
30
+ if (holder !== process.pid && isAlive(holder)) {
31
+ throw new Error(`Another ${PRODUCT} run (pid ${holder}) holds ${ledgerRoot}. Stop it first, or point --home elsewhere.`);
32
+ }
33
+ // Ours already, or left behind by a process that is gone.
34
+ await rm(path, { force: true });
35
+ }
36
+ return async () => {
37
+ try {
38
+ if ((await readFile(path, "utf8")).trim() === String(process.pid)) {
39
+ await rm(path, { force: true });
40
+ }
41
+ }
42
+ catch {
43
+ // Already gone.
44
+ }
45
+ };
46
+ }
47
+ function isAlive(pid) {
48
+ if (!Number.isInteger(pid) || pid <= 0) {
49
+ return false;
50
+ }
51
+ try {
52
+ process.kill(pid, 0);
53
+ return true;
54
+ }
55
+ catch (error) {
56
+ // EPERM: it exists, and is not ours to signal. Still alive.
57
+ return error.code === "EPERM";
58
+ }
59
+ }
60
+ //# sourceMappingURL=lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/loop/lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAElD;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CAAC,UAAkB;IACzC,OAAO,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,UAAkB;IAClD,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC;IAChC,SAAS,CAAC;QACR,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5C,MAAM;QACR,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1E,IAAI,MAAM,KAAK,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,WAAW,OAAO,aAAa,MAAM,WAAW,UAAU,6CAA6C,CACxG,CAAC;QACJ,CAAC;QACD,0DAA0D;QAC1D,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,KAAK,IAAI,EAAE;QAChB,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB;QAClB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;QACvC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,4DAA4D;QAC5D,OAAQ,KAA+B,CAAC,IAAI,KAAK,OAAO,CAAC;IAC3D,CAAC;AACH,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { PassSpec } from "../config/types.js";
2
+ /**
3
+ * What the feature's commit says — and the pull request with it — is the
4
+ * Project's decision, not Host's: a team has conventions, and an agent can
5
+ * read the diff and follow them. The Message slot is where that lives. Host
6
+ * spawns it once per feature, in the feature workspace where the whole diff
7
+ * is, tells it what was asked, and takes one JSON line back:
8
+ * `{ subject, body? }`. Subtask commits are never asked about: they are
9
+ * squashed away, and words spent on them are words wasted.
10
+ *
11
+ * A slot that fails — cannot run, answers nothing readable, subject empty —
12
+ * is not a reason to lose the fold: the caller keeps the message it would
13
+ * have written anyway, and the journal says the slot was skipped.
14
+ */
15
+ export type MessageInput = {
16
+ id: string;
17
+ /** The issue's title, as the human wrote it. */
18
+ title: string;
19
+ /** The issue's body, as the human wrote it. */
20
+ intention: string;
21
+ /** The work line the change will land on, so the slot can diff against it. */
22
+ target: string;
23
+ /** The feature workspace; the slot may read its diff. */
24
+ cwd: string;
25
+ };
26
+ export type MessageAnswer = {
27
+ ok: true;
28
+ message: string;
29
+ } | {
30
+ ok: false;
31
+ detail: string;
32
+ };
33
+ export declare function askMessage(slot: PassSpec, input: MessageInput): MessageAnswer;
34
+ //# sourceMappingURL=message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/loop/message.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1F,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,GAAG,aAAa,CAkC7E"}
@@ -0,0 +1,48 @@
1
+ import { spawnSync } from "node:child_process";
2
+ export function askMessage(slot, input) {
3
+ const [command, ...rest] = slot.cmd;
4
+ if (command === undefined) {
5
+ return { ok: false, detail: "the Message slot has no command" };
6
+ }
7
+ const run = spawnSync(command, [
8
+ ...rest,
9
+ "--id",
10
+ input.id,
11
+ "--title",
12
+ input.title,
13
+ "--intention",
14
+ input.intention,
15
+ "--target",
16
+ input.target,
17
+ ], { cwd: input.cwd, encoding: "utf8", timeout: slot.timeoutMs });
18
+ if (run.error !== undefined) {
19
+ return { ok: false, detail: `Message slot could not run: ${run.error.message}` };
20
+ }
21
+ const answer = lastJsonLine(run.stdout ?? "");
22
+ if (answer === undefined) {
23
+ const detail = `${run.stderr ?? ""}`.trim().slice(-500);
24
+ return { ok: false, detail: `Message slot stdout is not a JSON object. ${detail}`.trim() };
25
+ }
26
+ const subject = typeof answer.subject === "string" ? answer.subject.trim() : "";
27
+ if (subject.length === 0) {
28
+ return { ok: false, detail: "Message slot answered no subject." };
29
+ }
30
+ const body = typeof answer.body === "string" ? answer.body.trim() : "";
31
+ return { ok: true, message: body.length === 0 ? subject : `${subject}\n\n${body}` };
32
+ }
33
+ function lastJsonLine(stdout) {
34
+ const lines = stdout.split("\n").filter((line) => line.trim().length > 0);
35
+ for (let i = lines.length - 1; i >= 0; i--) {
36
+ try {
37
+ const parsed = JSON.parse(lines[i] ?? "");
38
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
39
+ return parsed;
40
+ }
41
+ }
42
+ catch {
43
+ // not this line
44
+ }
45
+ }
46
+ return undefined;
47
+ }
48
+ //# sourceMappingURL=message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../../src/loop/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AA8B/C,MAAM,UAAU,UAAU,CAAC,IAAc,EAAE,KAAmB;IAC5D,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC;IACpC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iCAAiC,EAAE,CAAC;IAClE,CAAC;IACD,MAAM,GAAG,GAAG,SAAS,CACnB,OAAO,EACP;QACE,GAAG,IAAI;QACP,MAAM;QACN,KAAK,CAAC,EAAE;QACR,SAAS;QACT,KAAK,CAAC,KAAK;QACX,aAAa;QACb,KAAK,CAAC,SAAS;QACf,UAAU;QACV,KAAK,CAAC,MAAM;KACb,EACD,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,CAC9D,CAAC;IACF,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;IACnF,CAAC;IACD,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;IAC9C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;QACxD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,6CAA6C,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;IAC7F,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAChF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mCAAmC,EAAE,CAAC;IACpE,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,OAAO,IAAI,EAAE,EAAE,CAAC;AACtF,CAAC;AAED,SAAS,YAAY,CAAC,MAAc;IAClC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC1E,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,IAAI,CAAC;YACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACnD,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5E,OAAO,MAAiC,CAAC;YAC3C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB;QAClB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { HostOptions } from "../config/types.js";
2
+ import { type Journal } from "./journal.js";
3
+ import { type Host } from "./tick.js";
4
+ export type { HostOptions } from "../config/types.js";
5
+ export type { CancelResult } from "./deliveries.js";
6
+ export type { Host, HostTickResult } from "./tick.js";
7
+ /** What a caller may hand `openHost` that is not configuration: a test's film. */
8
+ export type OpenHostDeps = {
9
+ /** Film next to the ledger. Defaults to `<ledgerRoot>/events.jsonl`. */
10
+ journal?: Journal;
11
+ };
12
+ export declare function openHost(options: HostOptions, deps?: OpenHostDeps): Promise<Host>;
13
+ //# sourceMappingURL=open-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-host.d.ts","sourceRoot":"","sources":["../../src/loop/open-host.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAOtD,OAAO,EAAE,KAAK,OAAO,EAAmB,MAAM,cAAc,CAAC;AAE7D,OAAO,EAAE,KAAK,IAAI,EAAgB,MAAM,WAAW,CAAC;AAKpD,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAKtD,kFAAkF;AAClF,MAAM,MAAM,YAAY,GAAG;IACzB,wEAAwE;IACxE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,wBAAsB,QAAQ,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmL3F"}
@@ -0,0 +1,180 @@
1
+ import { mkdir } from "node:fs/promises";
2
+ import { openConductor } from "@bluewombat/conductor";
3
+ import { openWorkLedger } from "@bluewombat/work-ledger";
4
+ import { DEFAULT_PERSIST } from "../config/defaults.js";
5
+ import { homeOf } from "../config/home.js";
6
+ import { resolveIsolationStrategy } from "../plugins/isolation.js";
7
+ import { contextOf, loadManagerModule } from "../plugins/manager.js";
8
+ import { resolvePersistModule } from "../plugins/persist.js";
9
+ import { openAuthority } from "./authority.js";
10
+ import { cancelFeature } from "./deliveries.js";
11
+ import { openJournalFile } from "./journal.js";
12
+ import { acquireLock } from "./lock.js";
13
+ import { run, runOnce } from "./tick.js";
14
+ import { openTrace } from "./trace.js";
15
+ import { createTransformers } from "./transformers.js";
16
+ import { inspectWorkLine, materializeWorkLine, resolveWorkLine } from "./work-line.js";
17
+ const DEFAULT_MAX_UNITS = 10;
18
+ const DEFAULT_MAX_FEATURE_BYTES = 65_536;
19
+ export async function openHost(options, deps = {}) {
20
+ const configDir = options.configDir ?? process.cwd();
21
+ const home = homeOf(configDir, options.home);
22
+ const interruptFlag = options.interruptFlag ?? { interrupted: false };
23
+ const trace = openTrace(options.write ??
24
+ ((text) => {
25
+ process.stdout.write(text);
26
+ }));
27
+ const resolved = await resolveIsolationStrategy(options.workLineIsolation, configDir, options.workLineIsolationOptions);
28
+ if (!resolved.ok) {
29
+ throw new Error(resolved.reason);
30
+ }
31
+ const persistName = options.persist ?? DEFAULT_PERSIST;
32
+ const backend = await resolvePersistModule(persistName, configDir);
33
+ if (!backend.ok) {
34
+ throw new Error(backend.reason);
35
+ }
36
+ const request = {
37
+ manager: options.manager,
38
+ managerOptions: options.managerOptions ?? {},
39
+ configDir,
40
+ durationMs: options.timeoutMs,
41
+ interruptFlag,
42
+ env: options.env ?? process.env,
43
+ };
44
+ const loaded = await loadManagerModule(request);
45
+ if (!loaded.ok) {
46
+ throw new Error(loaded.reason);
47
+ }
48
+ const managerName = typeof options.manager === "string" ? options.manager : "the manager";
49
+ // Whose directory the work line is, settled before anything is written. A
50
+ // reference the manager names is read by the strategy — strictly, since the
51
+ // two agree on words nothing checks at compile time — and Host's copy of it
52
+ // is fetched here, so a wrong key or an unreachable remote stops the run
53
+ // now rather than in the middle of one.
54
+ const workLine = resolveWorkLine({
55
+ home,
56
+ stable: options.workLineStable,
57
+ branch: options.workLineBranch,
58
+ manager: managerName,
59
+ wantsAuthority: options.authority?.enabled === true,
60
+ reference: loaded.module.referenceManager?.(contextOf(request)),
61
+ strategy: resolved.strategy,
62
+ strategyName: resolved.specifier,
63
+ });
64
+ if (workLine.kind === "invalid") {
65
+ throw new Error(workLine.reason);
66
+ }
67
+ if (workLine.kind === "copy") {
68
+ const made = await materializeWorkLine(workLine);
69
+ if (!made.ok) {
70
+ throw new Error(made.reason);
71
+ }
72
+ if (made.fetched) {
73
+ trace(`work line copied ${workLine.reference.summary} to ${workLine.stable}`);
74
+ }
75
+ }
76
+ const stable = workLine.stable;
77
+ // The reference's git environment: who the system is on the work line. Only
78
+ // the slots that touch the work line get it; nothing else inherits it.
79
+ const workLineEnv = workLine.kind === "copy" ? workLine.reference.env : undefined;
80
+ const target = workLine.kind === "copy" ? workLine.target : options.workLineBranch;
81
+ // Which work line a fold lands on is a decision, not an accident of what was
82
+ // left checked out. Refuse before anything is written rather than fold onto
83
+ // a branch nobody chose. (A copy was already held against its reference.)
84
+ if (workLine.kind !== "copy" && target !== undefined) {
85
+ const state = inspectWorkLine(stable);
86
+ if (state.kind === "git" && state.branch !== target) {
87
+ throw new Error(`WorkLineStable is on "${state.branch}", but the config wants "${target}". Switch it, or change workLine.branch.`);
88
+ }
89
+ }
90
+ await mkdir(options.workspaceRoot, { recursive: true });
91
+ const release = await acquireLock(options.ledgerRoot);
92
+ const persist = await backend.module.openPersist({ ledgerRoot: options.ledgerRoot });
93
+ const ledger = openWorkLedger({ persist });
94
+ const journal = deps.journal ?? openJournalFile(options.ledgerRoot);
95
+ const transformers = createTransformers({
96
+ trace,
97
+ journal,
98
+ planner: options.planner,
99
+ builder: options.builder,
100
+ assembly: options.assembly,
101
+ isolation: resolved.strategy.isolation,
102
+ fold: resolved.strategy.fold,
103
+ timeoutMs: options.timeoutMs,
104
+ maxUnits: DEFAULT_MAX_UNITS,
105
+ maxFeatureBytes: DEFAULT_MAX_FEATURE_BYTES,
106
+ });
107
+ const hostOptions = { ...options, interruptFlag };
108
+ const created = await loaded.module.createManager(contextOf(request));
109
+ if (!created.ok) {
110
+ throw new Error(created.reason);
111
+ }
112
+ const manager = created.manager;
113
+ // Declared, never inferred: a Project has an Authority because it says so,
114
+ // not because a directory happens to look a certain way. Disabled, the
115
+ // assembled feature is folded into WorkLineStable and that fold is final.
116
+ const wantsAuthority = options.authority?.enabled === true;
117
+ if (wantsAuthority && target === undefined) {
118
+ throw new Error('authority.enabled is true, but "workLine.branch" does not say which work line the work is offered to.');
119
+ }
120
+ const authority = wantsAuthority && options.authority !== undefined && target !== undefined
121
+ ? openAuthority({
122
+ manager,
123
+ workLineStable: stable,
124
+ workLineTarget: target,
125
+ publishArgv: options.authority.publishArgv,
126
+ timeoutMs: options.timeoutMs,
127
+ refOf: resolved.strategy.refOf ?? ((id) => id),
128
+ env: workLineEnv,
129
+ describe: options.authority.describeArgv === undefined
130
+ ? undefined
131
+ : { cmd: options.authority.describeArgv, timeoutMs: options.timeoutMs },
132
+ workspaceRoot: options.workspaceRoot,
133
+ journal,
134
+ })
135
+ : undefined;
136
+ // Asking for an Authority from a manager that has none is a configuration
137
+ // mistake, not a reason to quietly fold locally instead.
138
+ if (wantsAuthority && authority === undefined) {
139
+ throw new Error(`${managerName} declares no Submission, so it cannot be an Authority. Set "authority.enabled" to false, or name a manager that submits and folds.`);
140
+ }
141
+ // Conductor says what happens mid-pass; the tick that is running decides what
142
+ // to do with it (report it), so the hook is a slot the tick fills.
143
+ const watcher = {};
144
+ const conductor = openConductor({
145
+ ledger,
146
+ transformers,
147
+ workLineStable: stable,
148
+ workspaceRoot: options.workspaceRoot,
149
+ transformerDurationMs: options.timeoutMs,
150
+ observe: (moment) => watcher.current?.(moment),
151
+ ...(authority === undefined ? {} : { authority }),
152
+ ...(target === undefined ? {} : { workLineTarget: target }),
153
+ ...(options.maxRefusals === undefined ? {} : { maxRefusals: options.maxRefusals }),
154
+ });
155
+ const ctx = {
156
+ options: hostOptions,
157
+ workLine: {
158
+ stable,
159
+ ...(target === undefined ? {} : { target }),
160
+ ...(workLineEnv === undefined ? {} : { env: workLineEnv }),
161
+ },
162
+ ledger,
163
+ conductor,
164
+ manager,
165
+ journal,
166
+ trace,
167
+ watcher,
168
+ said: new Set(),
169
+ ...(authority === undefined ? {} : { authority }),
170
+ };
171
+ return {
172
+ ledger,
173
+ conductor,
174
+ runOnce: () => runOnce(ctx),
175
+ run: () => run(ctx),
176
+ cancel: (key) => cancelFeature(ctx, key),
177
+ close: release,
178
+ };
179
+ }
180
+ //# sourceMappingURL=open-host.js.map