@enderfga/claw-orchestrator 5.1.0 → 6.0.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 (147) hide show
  1. package/README.md +26 -26
  2. package/dist/bin/cli.js +107 -1
  3. package/dist/bin/cli.js.map +1 -1
  4. package/dist/src/acp-server.d.ts +5 -5
  5. package/dist/src/acp-server.js +3 -3
  6. package/dist/src/acp-server.js.map +1 -1
  7. package/dist/src/autoloop/dispatcher.d.ts +22 -0
  8. package/dist/src/autoloop/dispatcher.js +71 -13
  9. package/dist/src/autoloop/dispatcher.js.map +1 -1
  10. package/dist/src/autoloop/messages.d.ts +10 -0
  11. package/dist/src/autoloop/messages.js.map +1 -1
  12. package/dist/src/autoloop/runner.js +6 -0
  13. package/dist/src/autoloop/runner.js.map +1 -1
  14. package/dist/src/constants.d.ts +0 -6
  15. package/dist/src/constants.js +0 -6
  16. package/dist/src/constants.js.map +1 -1
  17. package/dist/src/council.d.ts +15 -0
  18. package/dist/src/council.js +48 -35
  19. package/dist/src/council.js.map +1 -1
  20. package/dist/src/dashboard/index.html +191 -6
  21. package/dist/src/embedded-server.js +132 -9
  22. package/dist/src/embedded-server.js.map +1 -1
  23. package/dist/src/fanout.d.ts +30 -1
  24. package/dist/src/fanout.js +32 -3
  25. package/dist/src/fanout.js.map +1 -1
  26. package/dist/src/index.js +359 -4
  27. package/dist/src/index.js.map +1 -1
  28. package/dist/src/kernel/agent-step.d.ts +59 -0
  29. package/dist/src/kernel/agent-step.js +100 -0
  30. package/dist/src/kernel/agent-step.js.map +1 -0
  31. package/dist/src/kernel/conditions.d.ts +11 -0
  32. package/dist/src/kernel/conditions.js +24 -0
  33. package/dist/src/kernel/conditions.js.map +1 -0
  34. package/dist/src/kernel/engine.d.ts +319 -0
  35. package/dist/src/kernel/engine.js +1047 -0
  36. package/dist/src/kernel/engine.js.map +1 -0
  37. package/dist/src/kernel/exec.d.ts +43 -0
  38. package/dist/src/kernel/exec.js +112 -0
  39. package/dist/src/kernel/exec.js.map +1 -0
  40. package/dist/src/kernel/file-lock.d.ts +50 -0
  41. package/dist/src/kernel/file-lock.js +135 -0
  42. package/dist/src/kernel/file-lock.js.map +1 -0
  43. package/dist/src/kernel/nodes/agent.d.ts +4 -0
  44. package/dist/src/kernel/nodes/agent.js +35 -0
  45. package/dist/src/kernel/nodes/agent.js.map +1 -0
  46. package/dist/src/kernel/nodes/autoloop.d.ts +78 -0
  47. package/dist/src/kernel/nodes/autoloop.js +75 -0
  48. package/dist/src/kernel/nodes/autoloop.js.map +1 -0
  49. package/dist/src/kernel/nodes/council.d.ts +12 -0
  50. package/dist/src/kernel/nodes/council.js +88 -0
  51. package/dist/src/kernel/nodes/council.js.map +1 -0
  52. package/dist/src/kernel/nodes/fanout.d.ts +11 -0
  53. package/dist/src/kernel/nodes/fanout.js +63 -0
  54. package/dist/src/kernel/nodes/fanout.js.map +1 -0
  55. package/dist/src/kernel/nodes/human-gate.d.ts +4 -0
  56. package/dist/src/kernel/nodes/human-gate.js +7 -0
  57. package/dist/src/kernel/nodes/human-gate.js.map +1 -0
  58. package/dist/src/kernel/nodes/index.d.ts +12 -0
  59. package/dist/src/kernel/nodes/index.js +21 -0
  60. package/dist/src/kernel/nodes/index.js.map +1 -0
  61. package/dist/src/kernel/nodes/router.d.ts +4 -0
  62. package/dist/src/kernel/nodes/router.js +12 -0
  63. package/dist/src/kernel/nodes/router.js.map +1 -0
  64. package/dist/src/kernel/nodes/subflow.d.ts +13 -0
  65. package/dist/src/kernel/nodes/subflow.js +38 -0
  66. package/dist/src/kernel/nodes/subflow.js.map +1 -0
  67. package/dist/src/kernel/nodes/ultraapp.d.ts +60 -0
  68. package/dist/src/kernel/nodes/ultraapp.js +62 -0
  69. package/dist/src/kernel/nodes/ultraapp.js.map +1 -0
  70. package/dist/src/kernel/nodes/verifier.d.ts +14 -0
  71. package/dist/src/kernel/nodes/verifier.js +84 -0
  72. package/dist/src/kernel/nodes/verifier.js.map +1 -0
  73. package/dist/src/kernel/projections.d.ts +42 -0
  74. package/dist/src/kernel/projections.js +133 -0
  75. package/dist/src/kernel/projections.js.map +1 -0
  76. package/dist/src/kernel/repo.d.ts +13 -0
  77. package/dist/src/kernel/repo.js +64 -0
  78. package/dist/src/kernel/repo.js.map +1 -0
  79. package/dist/src/kernel/secrets.d.ts +25 -0
  80. package/dist/src/kernel/secrets.js +48 -0
  81. package/dist/src/kernel/secrets.js.map +1 -0
  82. package/dist/src/kernel/store.d.ts +225 -0
  83. package/dist/src/kernel/store.js +838 -0
  84. package/dist/src/kernel/store.js.map +1 -0
  85. package/dist/src/kernel/templates/index.d.ts +140 -0
  86. package/dist/src/kernel/templates/index.js +266 -0
  87. package/dist/src/kernel/templates/index.js.map +1 -0
  88. package/dist/src/kernel/types.d.ts +326 -0
  89. package/dist/src/kernel/types.js +19 -0
  90. package/dist/src/kernel/types.js.map +1 -0
  91. package/dist/src/run-ledger.d.ts +57 -3
  92. package/dist/src/run-ledger.js +45 -2
  93. package/dist/src/run-ledger.js.map +1 -1
  94. package/dist/src/session-manager.d.ts +176 -129
  95. package/dist/src/session-manager.js +652 -603
  96. package/dist/src/session-manager.js.map +1 -1
  97. package/dist/src/types.d.ts +33 -3
  98. package/dist/src/ultraapp/build.d.ts +117 -3
  99. package/dist/src/ultraapp/build.js +319 -3
  100. package/dist/src/ultraapp/build.js.map +1 -1
  101. package/dist/src/ultraapp/contract.d.ts +52 -0
  102. package/dist/src/ultraapp/contract.js +83 -0
  103. package/dist/src/ultraapp/contract.js.map +1 -0
  104. package/dist/src/ultraapp/conventions.js +9 -2
  105. package/dist/src/ultraapp/conventions.js.map +1 -1
  106. package/dist/src/ultraapp/fix-on-failure.d.ts +21 -2
  107. package/dist/src/ultraapp/fix-on-failure.js +46 -62
  108. package/dist/src/ultraapp/fix-on-failure.js.map +1 -1
  109. package/dist/src/ultraapp/manager.d.ts +107 -2
  110. package/dist/src/ultraapp/manager.js +305 -86
  111. package/dist/src/ultraapp/manager.js.map +1 -1
  112. package/dist/src/verify/baseline.d.ts +73 -0
  113. package/dist/src/verify/baseline.js +186 -0
  114. package/dist/src/verify/baseline.js.map +1 -0
  115. package/dist/src/verify/contract.d.ts +116 -0
  116. package/dist/src/verify/contract.js +142 -0
  117. package/dist/src/verify/contract.js.map +1 -0
  118. package/dist/src/verify/evidence.d.ts +61 -0
  119. package/dist/src/verify/evidence.js +133 -0
  120. package/dist/src/verify/evidence.js.map +1 -0
  121. package/dist/src/verify/runner.d.ts +63 -0
  122. package/dist/src/verify/runner.js +317 -0
  123. package/dist/src/verify/runner.js.map +1 -0
  124. package/openclaw.plugin.json +8 -0
  125. package/package.json +2 -2
  126. package/skills/SKILL.md +120 -79
  127. package/skills/references/acp.md +17 -17
  128. package/skills/references/autoloop.md +139 -65
  129. package/skills/references/claude-cli-tracking.md +4 -4
  130. package/skills/references/cli.md +101 -59
  131. package/skills/references/council.md +109 -37
  132. package/skills/references/dashboard.md +34 -6
  133. package/skills/references/getting-started.md +13 -13
  134. package/skills/references/inbox.md +4 -4
  135. package/skills/references/mcp.md +39 -34
  136. package/skills/references/multi-engine.md +51 -47
  137. package/skills/references/observability.md +88 -28
  138. package/skills/references/openai-compat.md +39 -39
  139. package/skills/references/sessions.md +43 -25
  140. package/skills/references/tools.md +402 -309
  141. package/skills/references/ultra.md +45 -45
  142. package/skills/references/ultraapp.md +126 -50
  143. package/skills/references/verification.md +187 -0
  144. package/skills/references/workflow.md +362 -0
  145. package/dist/src/ultraapp/fix-on-failure-session.d.ts +0 -23
  146. package/dist/src/ultraapp/fix-on-failure-session.js +0 -51
  147. package/dist/src/ultraapp/fix-on-failure-session.js.map +0 -1
@@ -1,76 +1,60 @@
1
1
  /**
2
- * Purpose-built helper: run the standard verification pipeline in a worktree,
3
- * spawn a Claude session to fix mechanical errors on red, retry up to N rounds.
2
+ * Run the verification pipeline in a worktree, spawn a session to fix mechanical
3
+ * errors on red, retry up to N rounds.
4
+ *
5
+ * As of 6.0.0 this is an adapter over `src/verify/`, not its own runner. The
6
+ * logic it used to own — ordered steps, exit-code gating, byte-capped tails, the
7
+ * fix loop — moved out to become mode-agnostic, and came back with the two
8
+ * things it was missing: a per-step timeout (a wedged `npm test` used to hang
9
+ * the pipeline forever) and an honoured `required` flag (the field was declared
10
+ * here and never read, so every step was fatal).
4
11
  *
5
12
  * Not to be confused with src/autoloop/, which is a planner/coder/reviewer
6
13
  * message-bus orchestrator for a different problem shape.
7
14
  */
8
- import { spawn } from 'node:child_process';
9
- const DEFAULT_STEPS = [
15
+ import path from 'node:path';
16
+ import os from 'node:os';
17
+ import { runContract } from '../verify/runner.js';
18
+ const TEN_MIN = 10 * 60_000;
19
+ export const DEFAULT_STEPS = [
10
20
  { cmd: 'npm', args: ['install'] },
11
21
  { cmd: 'npm', args: ['run', 'build'] },
12
22
  { cmd: 'npm', args: ['test'] },
13
23
  { cmd: 'docker', args: ['build', '-t', 'ultraapp-fix:test', '.'] },
14
24
  ];
15
- const TAIL_LINES = 200;
16
- export async function runFixOnFailure(args) {
17
- const shell = args.shell ?? realShell;
18
- const spawnFixer = args.spawnFixer ?? defaultSpawnFixer;
19
- const steps = args.steps ?? DEFAULT_STEPS;
20
- let rounds = 0;
21
- while (true) {
22
- const failure = await runPipelineOnce(shell, args.worktreePath, steps);
23
- if (failure === null)
24
- return { ok: true, rounds };
25
- if (rounds >= args.maxRounds) {
26
- return {
27
- ok: false,
28
- rounds,
29
- lastError: failure.lastError,
30
- failingCommand: failure.failingCommand,
31
- };
32
- }
33
- rounds++;
34
- await spawnFixer({
35
- worktreePath: args.worktreePath,
36
- failingCommand: failure.failingCommand,
37
- tail: failure.tail,
38
- });
39
- }
25
+ /** Translate the legacy step list into contract checks, `required` included this time. */
26
+ export function stepsToContract(steps, fixOnFailureRounds) {
27
+ const checks = steps.map((s, i) => ({
28
+ id: `${s.cmd}-${i + 1}`,
29
+ spec: { type: 'command', cmd: s.cmd, args: s.args, timeoutMs: s.timeoutMs ?? TEN_MIN },
30
+ required: s.required !== false,
31
+ }));
32
+ return { id: 'fix-on-failure', checks, fixOnFailureRounds };
40
33
  }
41
- async function runPipelineOnce(shell, cwd, steps) {
42
- for (const step of steps) {
43
- const r = await shell(step.cmd, step.args, { cwd });
44
- if (!r.ok) {
45
- const cmdline = `${step.cmd} ${step.args.join(' ')}`;
46
- const tail = lastN(r.stderr || r.stdout, TAIL_LINES);
47
- return { failingCommand: cmdline, lastError: tail.slice(0, 500), tail };
48
- }
49
- }
50
- return null;
51
- }
52
- function lastN(s, n) {
53
- const lines = s.split('\n');
54
- return lines.slice(-n).join('\n');
34
+ export async function runFixOnFailure(args) {
35
+ const contract = args.contract ?? stepsToContract(args.steps ?? DEFAULT_STEPS, args.maxRounds);
36
+ const spawnFixer = args.spawnFixer
37
+ ? ({ cwd, failingCheck, tail }) => args.spawnFixer({ worktreePath: cwd, failingCommand: failingCheck, tail })
38
+ : undefined;
39
+ const { results, passed, rounds } = await runContract({ ...contract, fixOnFailureRounds: args.maxRounds }, {
40
+ cwd: args.worktreePath,
41
+ artifactDir: args.artifactDir ?? path.join(os.tmpdir(), 'clawo-fix-artifacts'),
42
+ exec: args.shell ? shellToExec(args.shell) : undefined,
43
+ }, spawnFixer);
44
+ const failing = results.find((r) => r.required && !r.passed);
45
+ return {
46
+ ok: passed,
47
+ rounds,
48
+ lastError: failing ? (failing.tail ?? failing.detail).slice(0, 500) : undefined,
49
+ failingCommand: failing?.detail,
50
+ results,
51
+ };
55
52
  }
56
- // Only the tail of build output is ever used (see lastN). Cap each stream so a
57
- // runaway build (e.g. a watch loop printing forever) can't OOM the process.
58
- const MAX_CAPTURE_BYTES = 512 * 1024;
59
- function appendCapped(buf, chunk) {
60
- const next = buf + chunk;
61
- return next.length > MAX_CAPTURE_BYTES ? next.slice(next.length - MAX_CAPTURE_BYTES) : next;
53
+ /** Keep the injectable `ShellRunner` seam callers already depend on. */
54
+ function shellToExec(shell) {
55
+ return async (cmd, cmdArgs, opts) => {
56
+ const r = await shell(cmd, cmdArgs, { cwd: opts.cwd ?? process.cwd() });
57
+ return { code: r.ok ? 0 : 1, out: r.stdout, err: r.stderr, timedOut: false, durationMs: 0 };
58
+ };
62
59
  }
63
- const realShell = (cmd, args, opts) => new Promise((resolve) => {
64
- const child = spawn(cmd, args, { cwd: opts.cwd, stdio: ['ignore', 'pipe', 'pipe'] });
65
- let stdout = '';
66
- let stderr = '';
67
- child.stdout.on('data', (d) => (stdout = appendCapped(stdout, d.toString())));
68
- child.stderr.on('data', (d) => (stderr = appendCapped(stderr, d.toString())));
69
- child.on('close', (code) => resolve({ ok: code === 0, stdout, stderr }));
70
- child.on('error', (e) => resolve({ ok: false, stdout, stderr: stderr + e.message }));
71
- });
72
- const defaultSpawnFixer = async (args) => {
73
- const { spawnFixerSession } = await import('./fix-on-failure-session.js');
74
- await spawnFixerSession(args);
75
- };
76
60
  //# sourceMappingURL=fix-on-failure.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fix-on-failure.js","sourceRoot":"","sources":["../../../src/ultraapp/fix-on-failure.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fix-on-failure.js","sourceRoot":"","sources":["../../../src/ultraapp/fix-on-failure.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,11 @@
1
1
  import { type AppSpec } from './spec.js';
2
- import { type UltraappStore, type ChatEntry } from './store.js';
2
+ import { type UltraappStore, type ChatEntry, type RunMode } from './store.js';
3
3
  import { type QuestionEnvelope } from './interview-parser.js';
4
4
  import { type PatchOp } from './json-patch.js';
5
5
  import type { BuildEvent } from './build-events.js';
6
+ import { RunKernel } from '../kernel/engine.js';
7
+ import type { RunRecord } from '../kernel/types.js';
8
+ import { type AcceptanceContract, type CheckResult } from '../verify/contract.js';
6
9
  import { type DeployArgs, type DeployResult } from './deploy.js';
7
10
  import type { UltraappRouter } from './router.js';
8
11
  export type RunEvent = {
@@ -56,23 +59,69 @@ export interface UltraappManagerOptions {
56
59
  `build-complete` (v0.2 behaviour); when present, deploy runs after build
57
60
  and the run reaches `done` with a public-but-local URL. */
58
61
  router?: UltraappRouter;
62
+ /**
63
+ * The run kernel that drives the build pipeline.
64
+ *
65
+ * Supplied by SessionManager in production so UltraApp's runs share the one
66
+ * run store, listing and ownership model as everything else. Left out, a
67
+ * private kernel is wired up — which keeps the class usable on its own, and
68
+ * still means there is only one execution model, not two.
69
+ */
70
+ kernel?: RunKernel;
59
71
  /** Test seam: stub the deploy state machine. */
60
72
  deployFn?: (a: DeployArgs) => Promise<DeployResult>;
73
+ /**
74
+ * Override the build-stage acceptance contract.
75
+ *
76
+ * A caller-supplied contract, never an agent-supplied one — the same rule as
77
+ * everywhere else in the verification plane. It exists because the default
78
+ * really does run `npm install && npm run build && npm test` in the generated
79
+ * codebase, which a unit test has no business doing; tests declare a trivial
80
+ * contract the way they inject `deployFn`.
81
+ */
82
+ buildContract?: AcceptanceContract;
83
+ /**
84
+ * Test seam: stub the deploy-stage acceptance checks. The real one drives a
85
+ * headless browser against the deployed URL, which a stubbed deploy has not
86
+ * got, so tests inject their own the same way they inject `deployFn`.
87
+ */
88
+ runDeployChecksFn?: (contract: AcceptanceContract, cwd: string, artifactDir: string) => Promise<CheckResult[]>;
61
89
  /** Runtime mode for build + deploy. 'host' (default) runs the generated
62
90
  app as a regular Node process — works anywhere Node works, no extra
63
91
  deps. 'docker' uses `docker build` + `docker run` for isolation; only
64
92
  use this when you want shared-host hardening. */
65
93
  runtimeMode?: 'host' | 'docker';
66
94
  }
95
+ /**
96
+ * The kernel run id for an app's current build.
97
+ *
98
+ * Stable rather than per-attempt, so `clawo workflow show ultraapp-<id>` always
99
+ * names the build that matters; a rebuild deletes the previous run and starts a
100
+ * new one under the same id, which the incarnation check makes safe.
101
+ */
102
+ export declare function ultraappKernelRunId(appRunId: string): string;
103
+ /**
104
+ * UltraApp's `RunMode`, derived from the kernel record.
105
+ *
106
+ * The build pipeline no longer has a state machine of its own: this reads the
107
+ * one the kernel keeps. `interview` and `queued` are not here because they are
108
+ * not pipeline states — nothing is running yet, and the interview genuinely is
109
+ * not a workflow.
110
+ */
111
+ export declare function ultraappModeOf(record: RunRecord): RunMode;
67
112
  export declare class UltraappManager {
68
113
  private readonly opts;
69
114
  private readonly runs;
70
115
  private readonly skillContent;
71
116
  private readonly buildQueue;
72
117
  private readonly narrators;
118
+ private readonly kernel;
119
+ /** Per-run serialisation for the mode projection. See {@link projectMode}. */
120
+ private readonly projectChain;
73
121
  private readonly classifierSessions;
74
122
  private readonly inflightWork;
75
123
  constructor(opts: UltraappManagerOptions);
124
+ private ultraappNodeDeps;
76
125
  get store(): UltraappStore;
77
126
  createRun(): Promise<string>;
78
127
  submitAnswer(runId: string, answer: {
@@ -94,8 +143,64 @@ export declare class UltraappManager {
94
143
  startBuild(runId: string): Promise<void>;
95
144
  cancelBuild(runId: string): void;
96
145
  buildPosition(runId: string): number;
146
+ /**
147
+ * Run the build pipeline as a kernel workflow.
148
+ *
149
+ * This used to be a hand-rolled sequence: council, then fix-on-failure, then
150
+ * deploy, with a mode enum written at each step and nothing checkpointed
151
+ * between them. It worked, but it meant UltraApp was a second runtime standing
152
+ * beside the one this release exists to be — its runs were invisible to
153
+ * `workflow_list` and the Runs tab, and a crash halfway through threw away a
154
+ * finished council and started it again from nothing.
155
+ *
156
+ * Now the sequence is a `WorkflowSpec` and the kernel drives it. What is left
157
+ * here is the part that is genuinely UltraApp's: turning kernel events into
158
+ * `BuildEvent`s for the dashboard, and keeping `RunMode` — which the whole
159
+ * UI and every stored run reads — as a projection of the kernel's state
160
+ * rather than as a second source of truth.
161
+ *
162
+ * The interview and the done-mode conversation are deliberately NOT here.
163
+ * They are user-driven and open-ended; expressing them as a workflow would
164
+ * mean a router self-loop fighting the visit bound, or one fake node with a
165
+ * state machine hidden inside it. That would be unification as theatre.
166
+ */
97
167
  private runBuild;
98
- private runDeployStage;
168
+ /** Best-effort narrator startup; its failure must not sink a build. */
169
+ private startNarrator;
170
+ /**
171
+ * Translate the run's kernel events into build events and mode transitions.
172
+ *
173
+ * The mode is recomputed from the record every time rather than stepped
174
+ * forward, so a handler that arrives late cannot write a stale value over a
175
+ * newer one — which it otherwise can, because these handlers are async and the
176
+ * kernel does not wait for them.
177
+ */
178
+ private subscribeKernel;
179
+ private onKernelEvent;
180
+ /**
181
+ * Write UltraApp's mode as it is implied by the kernel record, right now.
182
+ *
183
+ * Serialised per run, and that is the whole mechanism. These are fired from
184
+ * async event handlers, so two of them can read the record at different
185
+ * moments and still write in the opposite order — which showed up as a run
186
+ * that had already failed reverting to `building`. Chaining read-compute-write
187
+ * makes the last write the one computed last, and the kernel record only ever
188
+ * moves forward, so the last computed value is the current one.
189
+ */
190
+ private projectMode;
191
+ private projectModeNow;
192
+ /** Emit the terminal build event and settle the mode from the final record. */
193
+ private settleBuild;
194
+ /**
195
+ * Deploy the built codebase and check the deployed thing.
196
+ *
197
+ * Returns an outcome rather than writing modes: the mode is projected from the
198
+ * kernel now, and a stage that also wrote it would put the two back out of
199
+ * step. The acceptance verdict comes back with the outcome because it is the
200
+ * run's terminal verdict — §7g screenshots are taken against a URL that does
201
+ * not exist until this has run, so the contract cannot sit in the spec.
202
+ */
203
+ private deployStage;
99
204
  startContainer(runId: string): Promise<{
100
205
  ok: boolean;
101
206
  error?: string;