@enderfga/claw-orchestrator 3.7.1 → 4.0.3
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 +45 -3
- package/configs/autoloop-coder-prompt.md +65 -28
- package/configs/autoloop-planner-prompt.md +103 -42
- package/configs/autoloop-reviewer-prompt.md +58 -30
- package/dist/bin/cli.js +30 -7
- package/dist/bin/cli.js.map +1 -1
- package/dist/src/autoloop/dispatcher.js +16 -2
- package/dist/src/autoloop/dispatcher.js.map +1 -1
- package/dist/src/autoloop/messages.d.ts +0 -2
- package/dist/src/autoloop/messages.js +0 -2
- package/dist/src/autoloop/messages.js.map +1 -1
- package/dist/src/autoloop/planner-tools.d.ts +11 -6
- package/dist/src/autoloop/planner-tools.js +24 -7
- package/dist/src/autoloop/planner-tools.js.map +1 -1
- package/dist/src/autoloop/runner.d.ts +1 -2
- package/dist/src/autoloop/runner.js +1 -2
- package/dist/src/autoloop/runner.js.map +1 -1
- package/dist/src/autoloop/types.d.ts +0 -2
- package/dist/src/autoloop/types.js +0 -2
- package/dist/src/autoloop/types.js.map +1 -1
- package/dist/src/council.js +1 -0
- package/dist/src/council.js.map +1 -1
- package/dist/src/dashboard/index.html +1066 -12
- package/dist/src/embedded-server.d.ts +7 -0
- package/dist/src/embedded-server.js +359 -17
- package/dist/src/embedded-server.js.map +1 -1
- package/dist/src/index.js +222 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/session-manager.d.ts +98 -1
- package/dist/src/session-manager.js +340 -5
- package/dist/src/session-manager.js.map +1 -1
- package/dist/src/ultraapp/build-events.d.ts +46 -0
- package/dist/src/ultraapp/build-events.js +6 -0
- package/dist/src/ultraapp/build-events.js.map +1 -0
- package/dist/src/ultraapp/build.d.ts +39 -0
- package/dist/src/ultraapp/build.js +111 -0
- package/dist/src/ultraapp/build.js.map +1 -0
- package/dist/src/ultraapp/conventions.d.ts +8 -0
- package/dist/src/ultraapp/conventions.js +248 -0
- package/dist/src/ultraapp/conventions.js.map +1 -0
- package/dist/src/ultraapp/council-adapter.d.ts +49 -0
- package/dist/src/ultraapp/council-adapter.js +152 -0
- package/dist/src/ultraapp/council-adapter.js.map +1 -0
- package/dist/src/ultraapp/deploy.d.ts +45 -0
- package/dist/src/ultraapp/deploy.js +82 -0
- package/dist/src/ultraapp/deploy.js.map +1 -0
- package/dist/src/ultraapp/diff-apply.d.ts +15 -0
- package/dist/src/ultraapp/diff-apply.js +48 -0
- package/dist/src/ultraapp/diff-apply.js.map +1 -0
- package/dist/src/ultraapp/docker.d.ts +57 -0
- package/dist/src/ultraapp/docker.js +83 -0
- package/dist/src/ultraapp/docker.js.map +1 -0
- package/dist/src/ultraapp/feedback-classifier.d.ts +24 -0
- package/dist/src/ultraapp/feedback-classifier.js +85 -0
- package/dist/src/ultraapp/feedback-classifier.js.map +1 -0
- package/dist/src/ultraapp/files.d.ts +24 -0
- package/dist/src/ultraapp/files.js +79 -0
- package/dist/src/ultraapp/files.js.map +1 -0
- package/dist/src/ultraapp/fix-on-failure-session.d.ts +23 -0
- package/dist/src/ultraapp/fix-on-failure-session.js +48 -0
- package/dist/src/ultraapp/fix-on-failure-session.js.map +1 -0
- package/dist/src/ultraapp/fix-on-failure.d.ts +39 -0
- package/dist/src/ultraapp/fix-on-failure.js +69 -0
- package/dist/src/ultraapp/fix-on-failure.js.map +1 -0
- package/dist/src/ultraapp/host-strategy.d.ts +57 -0
- package/dist/src/ultraapp/host-strategy.js +205 -0
- package/dist/src/ultraapp/host-strategy.js.map +1 -0
- package/dist/src/ultraapp/interview-parser.d.ts +41 -0
- package/dist/src/ultraapp/interview-parser.js +83 -0
- package/dist/src/ultraapp/interview-parser.js.map +1 -0
- package/dist/src/ultraapp/interview-tools.d.ts +16 -0
- package/dist/src/ultraapp/interview-tools.js +36 -0
- package/dist/src/ultraapp/interview-tools.js.map +1 -0
- package/dist/src/ultraapp/json-patch.d.ts +6 -0
- package/dist/src/ultraapp/json-patch.js +78 -0
- package/dist/src/ultraapp/json-patch.js.map +1 -0
- package/dist/src/ultraapp/lifecycle.d.ts +38 -0
- package/dist/src/ultraapp/lifecycle.js +31 -0
- package/dist/src/ultraapp/lifecycle.js.map +1 -0
- package/dist/src/ultraapp/manager.d.ts +150 -0
- package/dist/src/ultraapp/manager.js +684 -0
- package/dist/src/ultraapp/manager.js.map +1 -0
- package/dist/src/ultraapp/narrator-prompt.d.ts +10 -0
- package/dist/src/ultraapp/narrator-prompt.js +54 -0
- package/dist/src/ultraapp/narrator-prompt.js.map +1 -0
- package/dist/src/ultraapp/narrator.d.ts +49 -0
- package/dist/src/ultraapp/narrator.js +83 -0
- package/dist/src/ultraapp/narrator.js.map +1 -0
- package/dist/src/ultraapp/patcher.d.ts +35 -0
- package/dist/src/ultraapp/patcher.js +159 -0
- package/dist/src/ultraapp/patcher.js.map +1 -0
- package/dist/src/ultraapp/router.d.ts +39 -0
- package/dist/src/ultraapp/router.js +139 -0
- package/dist/src/ultraapp/router.js.map +1 -0
- package/dist/src/ultraapp/spec-delta.d.ts +18 -0
- package/dist/src/ultraapp/spec-delta.js +35 -0
- package/dist/src/ultraapp/spec-delta.js.map +1 -0
- package/dist/src/ultraapp/spec.d.ts +82 -0
- package/dist/src/ultraapp/spec.js +125 -0
- package/dist/src/ultraapp/spec.js.map +1 -0
- package/dist/src/ultraapp/store.d.ts +67 -0
- package/dist/src/ultraapp/store.js +177 -0
- package/dist/src/ultraapp/store.js.map +1 -0
- package/dist/src/ultraapp/versions.d.ts +50 -0
- package/dist/src/ultraapp/versions.js +65 -0
- package/dist/src/ultraapp/versions.js.map +1 -0
- package/openclaw.plugin.json +15 -1
- package/package.json +3 -1
- package/skills/SKILL.md +2 -2
- package/skills/references/autoloop.md +7 -4
- package/skills/references/dashboard.md +153 -0
- package/skills/references/mcp.md +2 -2
- package/skills/references/tools.md +183 -0
- package/skills/references/ultraapp.md +203 -0
- package/skills/ultraapp/SKILL.md +112 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"versions.js","sourceRoot":"","sources":["../../../src/ultraapp/versions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAiBlC,MAAM,UAAU,YAAY,CAAC,WAAmB;IAC9C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3C,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,eAAe,CAAC,EAAE,MAAM,CAAC,CAGvF,CAAC;YACF,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,2BAA2B;QAC7B,CAAC;IACH,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAClF,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAe;IACzC,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,WAAmB,EAAE,IAA8C;IACjG,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IACzC,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,EAC/B,IAAI,CAAC,SAAS,CACZ;QACE,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACjC,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,EACD,IAAI,EACJ,CAAC,CACF,CACF,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC;AAYD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAc;IAC9C,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,WAAW,CAAC,CAAC;IAClE,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9D,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC;QAChB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,IAAI,CAAC,SAAS,qBAAqB,EAAE,CAAC;IACrF,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;QACjB,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YAC7D,iBAAiB;QACnB,CAAC,CAAC,CAAC;IACL,CAAC;IACD,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAC7D,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC"}
|
package/openclaw.plugin.json
CHANGED
|
@@ -98,7 +98,21 @@
|
|
|
98
98
|
"ultraplan_start",
|
|
99
99
|
"ultraplan_status",
|
|
100
100
|
"ultrareview_start",
|
|
101
|
-
"ultrareview_status"
|
|
101
|
+
"ultrareview_status",
|
|
102
|
+
"ultraapp_list",
|
|
103
|
+
"ultraapp_get",
|
|
104
|
+
"ultraapp_status",
|
|
105
|
+
"ultraapp_new",
|
|
106
|
+
"ultraapp_answer",
|
|
107
|
+
"ultraapp_add_file",
|
|
108
|
+
"ultraapp_spec_edit",
|
|
109
|
+
"ultraapp_build_start",
|
|
110
|
+
"ultraapp_build_cancel",
|
|
111
|
+
"ultraapp_feedback",
|
|
112
|
+
"ultraapp_promote_version",
|
|
113
|
+
"ultraapp_start_container",
|
|
114
|
+
"ultraapp_stop_container",
|
|
115
|
+
"ultraapp_delete"
|
|
102
116
|
]
|
|
103
117
|
},
|
|
104
118
|
"skills": ["skills/SKILL.md"]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enderfga/claw-orchestrator",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.3",
|
|
4
4
|
"description": "Claw Orchestrator — run Claude Code, Codex, Gemini, Cursor Agent, OpenCode and custom coding CLIs as one unified runtime. Drop into Hermes Agent, Claude Desktop, Cursor, Cline, Continue, Zed, Windsurf, Goose or any Model Context Protocol (MCP) host, install as an OpenClaw plugin, or run standalone. Persistent sessions, multi-agent council, ultraplan, ultrareview, autoloop, tool orchestration.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/src/index.js",
|
|
@@ -92,6 +92,7 @@
|
|
|
92
92
|
"dependencies": {
|
|
93
93
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
94
94
|
"commander": "^12.1.0",
|
|
95
|
+
"diff": "^9.0.0",
|
|
95
96
|
"re2": "^1.24.0"
|
|
96
97
|
},
|
|
97
98
|
"peerDependencies": {
|
|
@@ -99,6 +100,7 @@
|
|
|
99
100
|
},
|
|
100
101
|
"devDependencies": {
|
|
101
102
|
"@eslint/js": "^9.15.0",
|
|
103
|
+
"@types/diff": "^7.0.2",
|
|
102
104
|
"@types/node": "^22.10.0",
|
|
103
105
|
"@vitest/coverage-v8": "^3.1.0",
|
|
104
106
|
"eslint": "^9.15.0",
|
package/skills/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: claw-orchestrator
|
|
3
|
-
description: Manage persistent coding sessions across Claude Code, Codex, Gemini, Cursor, and OpenCode engines. Use when orchestrating multi-engine coding agents, starting/sending/stopping sessions, running multi-agent council collaborations, cross-session messaging, ultraplan deep planning, ultrareview parallel code review, autoloop autonomous workspace iteration, switching models/tools at runtime, or exposing the orchestrator's
|
|
3
|
+
description: Manage persistent coding sessions across Claude Code, Codex, Gemini, Cursor, and OpenCode engines. Use when orchestrating multi-engine coding agents, starting/sending/stopping sessions, running multi-agent council collaborations, cross-session messaging, ultraplan deep planning, ultrareview parallel code review, autoloop autonomous workspace iteration, ultraapp building deployable web apps from a structured Q&A interview, switching models/tools at runtime, or exposing the orchestrator's 55 tools as an MCP server to Hermes Agent / Claude Desktop / Cursor / Cline / Continue / Zed / Windsurf / Goose. Triggers on "start a session", "send to session", "run council", "ultraplan", "ultrareview", "autoloop", "ultraapp", "Forge tab", "build a web app", "one-click app", "AppSpec", "autonomous iteration", "iterate until goal", "deep paper review", "auto research", "switch model", "multi-agent", "coding session", "session inbox", "cursor agent", "opencode", "mcp server", "clawo-mcp", "hermes mcp", "model context protocol".
|
|
4
4
|
metadata:
|
|
5
5
|
{
|
|
6
6
|
"openclaw":
|
|
@@ -43,7 +43,7 @@ metadata:
|
|
|
43
43
|
|
|
44
44
|
# Claw Orchestrator Skill
|
|
45
45
|
|
|
46
|
-
Claw Orchestrator — persistent multi-engine coding session manager for claw-style agent systems. Runs as a standalone CLI/server, with first-class OpenClaw plugin support. Wraps Claude Code, Codex, Gemini, Cursor Agent, OpenCode, and custom CLIs into headless agentic engines with
|
|
46
|
+
Claw Orchestrator — persistent multi-engine coding session manager for claw-style agent systems. Runs as a standalone CLI/server, with first-class OpenClaw plugin support. Wraps Claude Code, Codex, Gemini, Cursor Agent, OpenCode, and custom CLIs into headless agentic engines with 55 tools.
|
|
47
47
|
|
|
48
48
|
## Engine Quick Reference
|
|
49
49
|
|
|
@@ -5,7 +5,7 @@ the **Planner** to design a plan; on your approval, the Planner spawns the
|
|
|
5
5
|
**Coder** + **Reviewer** subloop, monitors it, and pushes you (wechat →
|
|
6
6
|
whatsapp → email fallback chain) only when something needs your attention.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
This page is the operator reference.
|
|
9
9
|
|
|
10
10
|
## When to use
|
|
11
11
|
|
|
@@ -100,8 +100,8 @@ never see the JSON — only the Planner's narrative.
|
|
|
100
100
|
| `resume_loop` | — | Resume after pause. |
|
|
101
101
|
| `terminate` | `reason` | End run. |
|
|
102
102
|
| `update_push_policy` | partial PushPolicy | Mutate notification rules (e.g. when you say "tell me every iter"). |
|
|
103
|
-
| `
|
|
104
|
-
| `
|
|
103
|
+
| `write_plan` | `content` (full plan.md body), `commit_message?` | Write `plan.md` to the workspace and git-commit. The **only** way the Planner can author plan.md — Write/Edit are stripped from the Planner session as a hard role boundary. Re-running replaces the whole file. |
|
|
104
|
+
| `write_goal` | `content` (full goal.json body), `commit_message?` | Same, for `goal.json`. Content is JSON-validated before write; malformed content errors back to the Planner. |
|
|
105
105
|
|
|
106
106
|
## Default push policy
|
|
107
107
|
|
|
@@ -211,9 +211,12 @@ Every JSON artifact in the ledger carries a `schema_version` field (currently
|
|
|
211
211
|
| Endpoint | Returns |
|
|
212
212
|
|---|---|
|
|
213
213
|
| `GET /autoloop/list` | `{ ok, runs: AutoloopState[] }` |
|
|
214
|
+
| `POST /autoloop/new` | `{ ok, run_id, planner_session }` — body `{ workspace, run_id?, planner_model?, send_timeout_ms? }` |
|
|
214
215
|
| `GET /autoloop/<id>/state` | `{ ok, state: AutoloopState }` |
|
|
215
216
|
| `GET /autoloop/<id>/push_log` | `{ ok, entries: PushLogEntry[] }` |
|
|
216
|
-
| `GET /autoloop/<id>/events` | SSE: `snapshot` / `message` / `state` / `push` / `iter_done` / `planner_reply` / `coder_reply` / `reviewer_reply` / `terminated` |
|
|
217
|
+
| `GET /autoloop/<id>/events` | SSE: `snapshot` / `message` / `state` / `push` / `iter_done` / `planner_reply` / `planner_error` / `coder_reply` / `reviewer_reply` / `terminated` |
|
|
218
|
+
| `POST /autoloop/<id>/chat` | **202** `{ ok, queued: true }` — body `{ text }`. Fire-and-forget: the Planner's reply streams back via the `/events` SSE channel as a `planner_reply` event (or `planner_error` on failure); the HTTP response intentionally does NOT wait for it, because first-contact replies routinely exceed reverse-proxy idle limits (e.g. Cloudflare Tunnel cuts at ~100s → 524). 400 on empty text, 404 when the run is not in this process's memory. The MCP `autoloop_chat` tool path keeps the synchronous await-and-return-reply semantics (it runs in-process). |
|
|
219
|
+
| `POST /autoloop/<id>/delete` | `{ ok }` — stops the runner if still alive, scrubs the row from `~/.claw-orchestrator/autoloop-registry.jsonl`. The ledger directory under `<workspace>/tasks/<run_id>/` is kept on disk. 404 if the run was not present in either memory or the registry. |
|
|
217
220
|
|
|
218
221
|
The 3-pane UI consumes these endpoints:
|
|
219
222
|
- **Left**: Planner chat (subscribes to `planner_reply`)
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Dashboard
|
|
2
|
+
|
|
3
|
+
The dashboard is a single-page HTML app served by the orchestrator's embedded
|
|
4
|
+
HTTP server. It lets you **launch and observe** Council sessions, Autoloop
|
|
5
|
+
runs, and Forge (Ultraapp) builds from a browser — no CLI, no webchat, no
|
|
6
|
+
plugin tool calls needed.
|
|
7
|
+
|
|
8
|
+
URL: `http://127.0.0.1:18796/dash` (local) or whatever public hostname you
|
|
9
|
+
front the embedded server with (the recommended setup uses a path-based
|
|
10
|
+
reverse proxy, e.g. `https://<your-host>/dash`).
|
|
11
|
+
|
|
12
|
+
## Tabs
|
|
13
|
+
|
|
14
|
+
| Tab | Backed by | Launch endpoint |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| Autoloop | `SessionManager.autoloopStart()` | `POST /autoloop/new` |
|
|
17
|
+
| Council | `SessionManager.councilStart()` | `POST /council/new` |
|
|
18
|
+
| Forge | `UltraappManager.createRun()` | `POST /ultraapp/new` |
|
|
19
|
+
|
|
20
|
+
Each tab has a `+ New` button in the sidebar. Council and Autoloop open a
|
|
21
|
+
modal form (because they need workspace/task input); Forge POSTs an empty
|
|
22
|
+
body and drops you into an interview (the spec is built conversationally).
|
|
23
|
+
|
|
24
|
+
## Standalone deployment
|
|
25
|
+
|
|
26
|
+
The recommended way to run the dashboard 24/7 is a separate `clawo serve`
|
|
27
|
+
process under launchd — completely decoupled from the OpenClaw gateway. The
|
|
28
|
+
gateway's plugin-side embedded server still works (lazy init on first tool
|
|
29
|
+
call); when both processes try to bind the default port, the loser gracefully
|
|
30
|
+
skips, so the two coexist without conflict.
|
|
31
|
+
|
|
32
|
+
Example `~/Library/LaunchAgents/com.clawo.serve.plist`:
|
|
33
|
+
|
|
34
|
+
```xml
|
|
35
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
36
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
37
|
+
<plist version="1.0">
|
|
38
|
+
<dict>
|
|
39
|
+
<key>Label</key><string>com.clawo.serve</string>
|
|
40
|
+
<key>RunAtLoad</key><true/>
|
|
41
|
+
<key>KeepAlive</key><true/>
|
|
42
|
+
<key>ThrottleInterval</key><integer>5</integer>
|
|
43
|
+
<key>ProgramArguments</key>
|
|
44
|
+
<array>
|
|
45
|
+
<string>/opt/homebrew/bin/node</string>
|
|
46
|
+
<string>/opt/homebrew/bin/clawo</string>
|
|
47
|
+
<string>serve</string>
|
|
48
|
+
<string>--port</string><string>18796</string>
|
|
49
|
+
<string>--host</string><string>127.0.0.1</string>
|
|
50
|
+
</array>
|
|
51
|
+
<key>StandardOutPath</key>
|
|
52
|
+
<string>/Users/USER/.openclaw/logs/clawo-serve.log</string>
|
|
53
|
+
<key>StandardErrorPath</key>
|
|
54
|
+
<string>/Users/USER/.openclaw/logs/clawo-serve.log</string>
|
|
55
|
+
</dict>
|
|
56
|
+
</plist>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Bootstrap:
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
launchctl bootstrap "gui/$(id -u)" ~/Library/LaunchAgents/com.clawo.serve.plist
|
|
63
|
+
launchctl print "gui/$(id -u)/com.clawo.serve" | grep state
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Auth
|
|
67
|
+
|
|
68
|
+
The embedded server self-generates a 32-byte token at startup and writes it
|
|
69
|
+
to `~/.openclaw/server-token` (mode 0600). Same-user processes on the box
|
|
70
|
+
read it and present it as `Authorization: Bearer <token>` (or
|
|
71
|
+
`?token=<v>` query / `clawo_auth` cookie).
|
|
72
|
+
|
|
73
|
+
### Local access
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
http://127.0.0.1:18796/dash?token=$(cat ~/.openclaw/server-token)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The server sets a `clawo_auth` cookie on the first query-token request, so
|
|
80
|
+
the bookmark `/dash` works on subsequent visits.
|
|
81
|
+
|
|
82
|
+
### Hosted access via reverse proxy (recommended)
|
|
83
|
+
|
|
84
|
+
Don't expose the token to the public internet. Instead, gate the public
|
|
85
|
+
hostname with whatever auth layer you already trust (CF Access passkey,
|
|
86
|
+
Tailscale, mTLS, etc.) and have the reverse proxy **inject the Bearer
|
|
87
|
+
token on behalf of the user** when forwarding to port 18796. The browser
|
|
88
|
+
authenticates only against your edge auth; the dashboard's own token stays
|
|
89
|
+
inside the box.
|
|
90
|
+
|
|
91
|
+
Example sasha-doctor pattern (matches the user-side setup):
|
|
92
|
+
```js
|
|
93
|
+
// after the edge auth check passes:
|
|
94
|
+
if (!req.headers.authorization) {
|
|
95
|
+
req.headers.authorization =
|
|
96
|
+
"Bearer " + fs.readFileSync("~/.openclaw/server-token", "utf-8").trim();
|
|
97
|
+
}
|
|
98
|
+
proxyHTTP(req, res, 18796);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The `/login?token=...&redirect=/dash` endpoint exists as a fallback for
|
|
102
|
+
quick one-shot setups (works locally and through proxies that DON'T inject
|
|
103
|
+
the Bearer for you), but the proxy-injects-Bearer pattern is preferred
|
|
104
|
+
because users never see or paste the token.
|
|
105
|
+
|
|
106
|
+
Token-file write is deferred to the `listen()`-success callback so a second
|
|
107
|
+
process that loses the EADDRINUSE race does NOT clobber the winner's token.
|
|
108
|
+
|
|
109
|
+
## Cross-process visibility
|
|
110
|
+
|
|
111
|
+
When the dashboard runs in a different process from where you spawn runs
|
|
112
|
+
(e.g. you started a council via the OpenClaw plugin tool from webchat, but
|
|
113
|
+
the dashboard is in `clawo serve`), the run state is invisible across
|
|
114
|
+
in-memory boundaries. The dashboard fixes this by unioning in-memory state
|
|
115
|
+
with on-disk records on every list call:
|
|
116
|
+
|
|
117
|
+
- **Councils**: `~/.openclaw/council-logs/council-*.md` — parsed for
|
|
118
|
+
`- **ID**:`, `- **Time**:`, `- **Task**:`, `- **Status**:` headers.
|
|
119
|
+
Legacy transcripts (pre-v4.0) fall back to a filename-derived id.
|
|
120
|
+
- **Autoloops**: `~/.claw-orchestrator/autoloop-registry.jsonl` — an
|
|
121
|
+
append-only JSONL index written by `autoloopStart()`. Stale entries
|
|
122
|
+
whose ledger directory no longer exists are filtered out at read time.
|
|
123
|
+
- **Forge**: `UltraappStore.listRuns()` already reads from disk
|
|
124
|
+
(`~/.claw-orchestrator/ultraapps/`).
|
|
125
|
+
|
|
126
|
+
Result: any run you've ever started — from any process — shows up in the
|
|
127
|
+
sidebar, sorted newest-first, until the underlying files are deleted.
|
|
128
|
+
|
|
129
|
+
## Reverse-proxy integration
|
|
130
|
+
|
|
131
|
+
If you front the embedded server with sasha-doctor (or another reverse
|
|
132
|
+
proxy), route these paths to `127.0.0.1:18796`:
|
|
133
|
+
|
|
134
|
+
- `/dashboard`, `/dash`, `/login`
|
|
135
|
+
- `/autoloop/*`, `/council/*`, `/ultraapp/*`
|
|
136
|
+
|
|
137
|
+
The dashboard's relative `fetch()` calls expect the proxy to preserve the
|
|
138
|
+
path verbatim — no prefix stripping. `/v1/openclaw/*` should keep routing
|
|
139
|
+
to the OpenClaw gateway, not the embedded server.
|
|
140
|
+
|
|
141
|
+
## Reset
|
|
142
|
+
|
|
143
|
+
To wipe dashboard state without touching real run data:
|
|
144
|
+
|
|
145
|
+
```sh
|
|
146
|
+
# Forget all known autoloops (council/forge unchanged).
|
|
147
|
+
rm ~/.claw-orchestrator/autoloop-registry.jsonl
|
|
148
|
+
|
|
149
|
+
# Force the standalone server to mint a fresh auth token.
|
|
150
|
+
launchctl kickstart -k "gui/$(id -u)/com.clawo.serve"
|
|
151
|
+
# Then visit /login?token=$(cat ~/.openclaw/server-token)&redirect=/dash once
|
|
152
|
+
# to refresh the cookie.
|
|
153
|
+
```
|
package/skills/references/mcp.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# MCP integration
|
|
2
2
|
|
|
3
|
-
Claw Orchestrator ships a Model Context Protocol (MCP) server (`clawo-mcp`) so any MCP-compatible host can drive its
|
|
3
|
+
Claw Orchestrator ships a Model Context Protocol (MCP) server (`clawo-mcp`) so any MCP-compatible host can drive its 55 tools.
|
|
4
4
|
|
|
5
5
|
This document covers:
|
|
6
6
|
|
|
@@ -229,7 +229,7 @@ The engines themselves (`claude`, `codex`, `gemini`, `agent`, `opencode`) must a
|
|
|
229
229
|
|
|
230
230
|
## Tool filtering
|
|
231
231
|
|
|
232
|
-
|
|
232
|
+
55 tools is a lot for a small context window. Reduce noise either at the host level (most hosts have an `include` / `exclude` filter — see Hermes example above) or at the server level via `CLAWO_MCP_TOOLS`:
|
|
233
233
|
|
|
234
234
|
```bash
|
|
235
235
|
CLAWO_MCP_TOOLS="session_start,session_send,session_stop,council_start,council_status" clawo-mcp
|
|
@@ -414,3 +414,186 @@ Get status and findings when completed.
|
|
|
414
414
|
| Parameter | Type | Required |
|
|
415
415
|
|-----------|------|----------|
|
|
416
416
|
| `id` | string | yes |
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## Autoloop (6)
|
|
421
|
+
|
|
422
|
+
Three-agent autonomous iteration loop (Planner / Coder / Reviewer) over a git workspace. See [`autoloop.md`](./autoloop.md) for the operator reference (push policy, ledger layout, smoke test).
|
|
423
|
+
|
|
424
|
+
### `autoloop_start`
|
|
425
|
+
|
|
426
|
+
Start an autoloop run. Planner is created persistent; Coder + Reviewer are spawned by the Planner once `plan.md` is ready.
|
|
427
|
+
|
|
428
|
+
| Parameter | Type | Required | Description |
|
|
429
|
+
|-----------|------|----------|-------------|
|
|
430
|
+
| `cwd` | string | yes | Workspace (must be a git repo) |
|
|
431
|
+
| `goal` | string | yes | High-level user goal in natural language |
|
|
432
|
+
| `model` | string | | Planner model (default Opus) |
|
|
433
|
+
| `coderModel` | string | | Coder subagent model |
|
|
434
|
+
| `reviewerModel` | string | | Reviewer subagent model |
|
|
435
|
+
| `maxIters` | number | | Cap on Coder/Reviewer rounds (default 50) |
|
|
436
|
+
| `pushChannels` | string[] | | Notification channels (`wechat`, `whatsapp`, `email`) |
|
|
437
|
+
|
|
438
|
+
### `autoloop_chat`
|
|
439
|
+
|
|
440
|
+
Send a message into the Planner conversation (e.g. answer a clarifying question, refine the plan, kick off the subloop).
|
|
441
|
+
|
|
442
|
+
| Parameter | Type | Required |
|
|
443
|
+
|-----------|------|----------|
|
|
444
|
+
| `id` | string | yes |
|
|
445
|
+
| `message` | string | yes |
|
|
446
|
+
|
|
447
|
+
### `autoloop_status`
|
|
448
|
+
|
|
449
|
+
Get current state, phase, recent inbox messages, and ledger summary.
|
|
450
|
+
|
|
451
|
+
| Parameter | Type | Required |
|
|
452
|
+
|-----------|------|----------|
|
|
453
|
+
| `id` | string | yes |
|
|
454
|
+
|
|
455
|
+
### `autoloop_list`
|
|
456
|
+
|
|
457
|
+
List active and recent autoloop runs (in-memory + on-disk registry, deduped by run_id).
|
|
458
|
+
|
|
459
|
+
(no params)
|
|
460
|
+
|
|
461
|
+
### `autoloop_reset_agent`
|
|
462
|
+
|
|
463
|
+
Reset one of the subagent sessions (Coder or Reviewer) without losing Planner state — useful when a subagent loops on a stale belief.
|
|
464
|
+
|
|
465
|
+
| Parameter | Type | Required | Description |
|
|
466
|
+
|-----------|------|----------|-------------|
|
|
467
|
+
| `id` | string | yes | Run id |
|
|
468
|
+
| `agent` | `'coder'` \| `'reviewer'` | yes | Which subagent to reset |
|
|
469
|
+
|
|
470
|
+
### `autoloop_stop`
|
|
471
|
+
|
|
472
|
+
Terminate the run. All sessions are stopped and ledger state is finalised.
|
|
473
|
+
|
|
474
|
+
| Parameter | Type | Required |
|
|
475
|
+
|-----------|------|----------|
|
|
476
|
+
| `id` | string | yes |
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
## Ultraapp (14)
|
|
481
|
+
|
|
482
|
+
Forge tab — turn a structured Q&A interview into a deployed web app reachable at `localhost:19000/forge/<slug>/`. See [`ultraapp.md`](./ultraapp.md) for the operator reference (lifecycle, conventions §1–§7, runtime modes, file layout, HTTP routes).
|
|
483
|
+
|
|
484
|
+
### `ultraapp_list`
|
|
485
|
+
|
|
486
|
+
List all ultraapp runs.
|
|
487
|
+
|
|
488
|
+
(no params)
|
|
489
|
+
|
|
490
|
+
### `ultraapp_get`
|
|
491
|
+
|
|
492
|
+
Full snapshot of a run: spec + chat + state.
|
|
493
|
+
|
|
494
|
+
| Parameter | Type | Required |
|
|
495
|
+
|-----------|------|----------|
|
|
496
|
+
| `id` | string | yes |
|
|
497
|
+
|
|
498
|
+
### `ultraapp_status`
|
|
499
|
+
|
|
500
|
+
Lightweight status (mode + timestamps).
|
|
501
|
+
|
|
502
|
+
| Parameter | Type | Required |
|
|
503
|
+
|-----------|------|----------|
|
|
504
|
+
| `id` | string | yes |
|
|
505
|
+
|
|
506
|
+
### `ultraapp_new`
|
|
507
|
+
|
|
508
|
+
Create a fresh run. Optionally seeds the interview with the user's first message.
|
|
509
|
+
|
|
510
|
+
| Parameter | Type | Required | Description |
|
|
511
|
+
|-----------|------|----------|-------------|
|
|
512
|
+
| `firstMessage` | string | | Free-form opening line; the interview Opus reads it before its first question |
|
|
513
|
+
|
|
514
|
+
### `ultraapp_answer`
|
|
515
|
+
|
|
516
|
+
Submit an answer to the current interview question.
|
|
517
|
+
|
|
518
|
+
| Parameter | Type | Required | Description |
|
|
519
|
+
|-----------|------|----------|-------------|
|
|
520
|
+
| `id` | string | yes | Run id |
|
|
521
|
+
| `value` | string | yes | One of the question's `options[].value`, or `''` when using freeform |
|
|
522
|
+
| `freeform` | string | | Free-form text when none of the options fit |
|
|
523
|
+
|
|
524
|
+
### `ultraapp_add_file`
|
|
525
|
+
|
|
526
|
+
Upload a sample file to `examples/` (the interview engine will `extract_metadata` it).
|
|
527
|
+
|
|
528
|
+
| Parameter | Type | Required |
|
|
529
|
+
|-----------|------|----------|
|
|
530
|
+
| `id` | string | yes |
|
|
531
|
+
| `path` | string | yes |
|
|
532
|
+
| `content` | string \| Buffer | yes |
|
|
533
|
+
|
|
534
|
+
### `ultraapp_spec_edit`
|
|
535
|
+
|
|
536
|
+
Apply RFC 6902 JSON Patch ops to the AppSpec mid-interview.
|
|
537
|
+
|
|
538
|
+
| Parameter | Type | Required |
|
|
539
|
+
|-----------|------|----------|
|
|
540
|
+
| `id` | string | yes |
|
|
541
|
+
| `patch` | object[] | yes |
|
|
542
|
+
|
|
543
|
+
### `ultraapp_build_start`
|
|
544
|
+
|
|
545
|
+
Validate the spec strictly (shape + cross-refs + DAG) and enqueue the build. Council picks it up FIFO.
|
|
546
|
+
|
|
547
|
+
| Parameter | Type | Required |
|
|
548
|
+
|-----------|------|----------|
|
|
549
|
+
| `id` | string | yes |
|
|
550
|
+
|
|
551
|
+
### `ultraapp_build_cancel`
|
|
552
|
+
|
|
553
|
+
Abort an active build. Council sessions are stopped and the worktrees are left as-is for inspection.
|
|
554
|
+
|
|
555
|
+
| Parameter | Type | Required |
|
|
556
|
+
|-----------|------|----------|
|
|
557
|
+
| `id` | string | yes |
|
|
558
|
+
|
|
559
|
+
### `ultraapp_feedback`
|
|
560
|
+
|
|
561
|
+
Done-mode feedback. Haiku classifier routes into `cosmetic` (Opus patcher), `spec-delta` (focused interview + auto-rerun), or `structural` (suggest fresh run).
|
|
562
|
+
|
|
563
|
+
| Parameter | Type | Required | Description |
|
|
564
|
+
|-----------|------|----------|-------------|
|
|
565
|
+
| `id` | string | yes | Run id |
|
|
566
|
+
| `text` | string | yes | The feedback (1+ chars) |
|
|
567
|
+
|
|
568
|
+
### `ultraapp_promote_version`
|
|
569
|
+
|
|
570
|
+
Atomically swap the deployed version. Stops the current container/process, starts the target's, updates the router map.
|
|
571
|
+
|
|
572
|
+
| Parameter | Type | Required | Description |
|
|
573
|
+
|-----------|------|----------|-------------|
|
|
574
|
+
| `id` | string | yes | Run id |
|
|
575
|
+
| `version` | string | yes | Target version label (`v1`, `v2`, …) |
|
|
576
|
+
|
|
577
|
+
### `ultraapp_start_container`
|
|
578
|
+
|
|
579
|
+
Start the container/process for the active version (no-op if already running).
|
|
580
|
+
|
|
581
|
+
| Parameter | Type | Required |
|
|
582
|
+
|-----------|------|----------|
|
|
583
|
+
| `id` | string | yes |
|
|
584
|
+
|
|
585
|
+
### `ultraapp_stop_container`
|
|
586
|
+
|
|
587
|
+
Stop the container/process without deleting any state.
|
|
588
|
+
|
|
589
|
+
| Parameter | Type | Required |
|
|
590
|
+
|-----------|------|----------|
|
|
591
|
+
| `id` | string | yes |
|
|
592
|
+
|
|
593
|
+
### `ultraapp_delete`
|
|
594
|
+
|
|
595
|
+
Stop + remove the run completely (sessions, container, on-disk state, router entry).
|
|
596
|
+
|
|
597
|
+
| Parameter | Type | Required |
|
|
598
|
+
|-----------|------|----------|
|
|
599
|
+
| `id` | string | yes |
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# ultraapp — Reference
|
|
2
|
+
|
|
3
|
+
Turn a structured Q&A interview into a deployed web app reachable at
|
|
4
|
+
`localhost:19000/forge/<slug>/`. The dashboard's **Forge** tab and a
|
|
5
|
+
14-tool MCP surface drive the end-to-end loop: interview → 3-agent
|
|
6
|
+
council → fix-on-failure → deploy → done-mode feedback.
|
|
7
|
+
|
|
8
|
+
This page is the operator reference. The interview behavioural contract
|
|
9
|
+
lives in [`skills/ultraapp/SKILL.md`](../ultraapp/SKILL.md). The
|
|
10
|
+
council architectural conventions every generated app must satisfy live
|
|
11
|
+
in [`src/ultraapp/conventions.ts`](../../src/ultraapp/conventions.ts).
|
|
12
|
+
|
|
13
|
+
## When to use
|
|
14
|
+
|
|
15
|
+
- You have a workflow in your head (or a sample input file) and want a
|
|
16
|
+
shareable web app for it without writing code.
|
|
17
|
+
- You want to iterate cosmetically on a deployed app via chat ("make
|
|
18
|
+
the button green", "shrink the hero h1") without touching the
|
|
19
|
+
codebase yourself.
|
|
20
|
+
- You want to evolve the AppSpec ("also output a thumbnail") and
|
|
21
|
+
rebuild without restarting the interview.
|
|
22
|
+
|
|
23
|
+
## Lifecycle
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
interview ─► queued ─► building ─► build-complete ─► deploying ─► done
|
|
27
|
+
│
|
|
28
|
+
▼
|
|
29
|
+
done-mode chat
|
|
30
|
+
(cosmetic /
|
|
31
|
+
spec-delta /
|
|
32
|
+
structural)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
| Mode | Meaning |
|
|
36
|
+
|------|---------|
|
|
37
|
+
| `interview` | AppSpec being filled by Q&A. Chat input goes to the interview Opus. |
|
|
38
|
+
| `queued` | Build accepted, waiting for a slot in the FIFO build queue. |
|
|
39
|
+
| `building` | Council writing code, fix-on-failure driving install/build/test. |
|
|
40
|
+
| `build-complete` | Codebase ready, awaiting `deploy` step. |
|
|
41
|
+
| `deploying` | Container/process being started, router map being updated. |
|
|
42
|
+
| `done` | App live at `/forge/<slug>/`. Chat input now goes to the done-mode classifier. |
|
|
43
|
+
| `failed` | Council didn't reach consensus, or fix-on-failure couldn't get the build green. |
|
|
44
|
+
|
|
45
|
+
## Architectural conventions (§1–§7)
|
|
46
|
+
|
|
47
|
+
Every generated app MUST satisfy these. They're embedded in the council
|
|
48
|
+
super-task prompt verbatim from `src/ultraapp/conventions.ts`.
|
|
49
|
+
|
|
50
|
+
| § | Topic | Headline rule |
|
|
51
|
+
|---|-------|---------------|
|
|
52
|
+
| 1 | Path-based deploy | Mount at `BASE_PATH=/forge/<slug>/`; in-app links MUST be relative. |
|
|
53
|
+
| 2 | Async file-queue runtime | Exact endpoints: `GET /`, `POST /run`, `GET /status/:jobId`, `GET /result/:jobId`, `GET /health`. File-based job queue under `$DATA_DIR/jobs/<jobId>/`. NO database. Data path from `process.env.DATA_DIR ?? '/data'`. |
|
|
54
|
+
| 3 | BYOK | If `runtime.needsLLM`, API keys live in browser localStorage and are sent direct to the provider. The server MUST NEVER receive the key (enforced by `eslint-plugin-no-server-keys`). |
|
|
55
|
+
| 4 | Dockerfile + smoke test | Single multi-stage Dockerfile, `npm run smoke` drives one full job in < 90s using `examples[0].ref`. |
|
|
56
|
+
| 5 | Council voting protocol | 3 agents in git worktrees, all-YES vote required, max 8 rounds. |
|
|
57
|
+
| 6 | Tech stack | Modern TypeScript / JavaScript framework (Next.js, Vite + Hono, SvelteKit). NO Python, NO pure SSGs. |
|
|
58
|
+
| 7 | **Frontend quality** | **Real styling system + real type hierarchy + four-state coverage on every async surface + drag-and-drop forms + appropriate result presentation + one deliberate theme.** §7g requires every agent to capture Chrome-headless screenshots at 1440×900 AND 375×812 and visually inspect the PNGs before voting YES — source-code review is explicitly insufficient evidence. |
|
|
59
|
+
|
|
60
|
+
## Runtime modes
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
clawo serve --ultraapp-runtime host # default
|
|
64
|
+
clawo serve --ultraapp-runtime docker # opt-in
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
| Mode | Build | Run | Pros | Cons |
|
|
68
|
+
|------|-------|-----|------|------|
|
|
69
|
+
| `host` | `npm install && npm run build` | `npm start` (detached, `setsid`-equivalent) | Zero extra deps; works anywhere Node works; faster start. | No process isolation; deps installed under the user. |
|
|
70
|
+
| `docker` | `docker build .` | `docker run -d --restart unless-stopped` | Per-app isolation, restart policy, image is the artefact. | Requires a running Docker daemon. |
|
|
71
|
+
|
|
72
|
+
Both modes allocate a backend port in `[19100, 19999]`. The reverse-
|
|
73
|
+
proxy router runs at port `19000` (auto-fallback up to `19099` if
|
|
74
|
+
taken) and maps `/forge/<slug>/*` to the right backend. Slug→port map
|
|
75
|
+
persists to `~/.claw-orchestrator/_router.json`. Host-mode pid metadata
|
|
76
|
+
persists to `~/.claw-orchestrator/host-procs.json`.
|
|
77
|
+
|
|
78
|
+
## File layout (per run)
|
|
79
|
+
|
|
80
|
+
```text
|
|
81
|
+
~/.claw-orchestrator/ultraapps/<runId>/
|
|
82
|
+
├── spec.json # current AppSpec (latest)
|
|
83
|
+
├── spec.history.jsonl # every accepted update_spec patch
|
|
84
|
+
├── chat.jsonl # all chat turns (interview + done-mode)
|
|
85
|
+
├── state.json # { runId, mode, createdAt, updatedAt }
|
|
86
|
+
├── examples/ # uploaded sample files
|
|
87
|
+
├── data/ # passed to host-mode app as DATA_DIR
|
|
88
|
+
├── council-project/ # fresh git repo the council collaborates in
|
|
89
|
+
│ ├── .worktrees/{agent-A,agent-B,agent-C}/
|
|
90
|
+
│ └── (council code, merged to main on consensus)
|
|
91
|
+
└── versions/
|
|
92
|
+
├── v1/
|
|
93
|
+
│ ├── codebase/ # snapshot of council main HEAD
|
|
94
|
+
│ └── artifact.json # { worktreePath, builtAt, deploy: { url, port, … } }
|
|
95
|
+
└── v2/ # patcher / spec-delta produces v2, v3, …
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## HTTP routes (drive headlessly)
|
|
99
|
+
|
|
100
|
+
All routes are served by the embedded server (default `:18796`), under
|
|
101
|
+
`Authorization: Bearer <token>` from `~/.openclaw/server-token`.
|
|
102
|
+
|
|
103
|
+
| Method + path | Purpose |
|
|
104
|
+
|----|----|
|
|
105
|
+
| `GET /ultraapp/list` | All runs with mode + createdAt. |
|
|
106
|
+
| `POST /ultraapp/new` | Body: `{ firstMessage?: string }`. Returns `{ runId }`. |
|
|
107
|
+
| `GET /ultraapp/<id>` | Full snapshot: spec + chat + state. |
|
|
108
|
+
| `POST /ultraapp/<id>/answer` | Body: `{ value, freeform? }`. Submit interview answer. |
|
|
109
|
+
| `POST /ultraapp/<id>/spec-edit` | Body: RFC 6902 patch ops. Edit the spec mid-interview. |
|
|
110
|
+
| `POST /ultraapp/<id>/files` | Multipart upload to `examples/`. |
|
|
111
|
+
| `GET /ultraapp/<id>/events` | SSE stream of build/chat events (mode pill, narrator, council activity). |
|
|
112
|
+
| `POST /ultraapp/<id>/build` | Validate spec strictly + enqueue. |
|
|
113
|
+
| `POST /ultraapp/<id>/build/cancel` | Abort the active build. |
|
|
114
|
+
| `GET /ultraapp/<id>/artifacts` | List `versions/vN/`. |
|
|
115
|
+
| `POST /ultraapp/<id>/start` | Start the deployed container/process for the active version. |
|
|
116
|
+
| `POST /ultraapp/<id>/stop` | Stop without deleting. |
|
|
117
|
+
| `POST /ultraapp/<id>/delete` | Stop + remove all per-run state. |
|
|
118
|
+
| `POST /ultraapp/<id>/feedback` | Body: `{ text }`. Done-mode classifier routes cosmetic / spec-delta / structural. |
|
|
119
|
+
| `POST /ultraapp/<id>/promote-version` | Body: `{ version: "vN" }`. Atomically swap deployed version. |
|
|
120
|
+
|
|
121
|
+
## MCP tools (14)
|
|
122
|
+
|
|
123
|
+
Same surface as HTTP, callable from any Model Context Protocol host
|
|
124
|
+
(Claude Desktop, Hermes Agent, Cursor, Cline, Continue, Zed,
|
|
125
|
+
Windsurf, Goose). Param schemas in [`tools.md`](./tools.md#ultraapp).
|
|
126
|
+
|
|
127
|
+
```text
|
|
128
|
+
ultraapp_list ultraapp_get ultraapp_status
|
|
129
|
+
ultraapp_new ultraapp_answer ultraapp_add_file
|
|
130
|
+
ultraapp_spec_edit ultraapp_build_start ultraapp_build_cancel
|
|
131
|
+
ultraapp_feedback ultraapp_promote_version
|
|
132
|
+
ultraapp_start_container ultraapp_stop_container ultraapp_delete
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Done-mode feedback classification
|
|
136
|
+
|
|
137
|
+
After the run reaches `done`, chat input goes to a per-run Haiku
|
|
138
|
+
classifier. Three classes:
|
|
139
|
+
|
|
140
|
+
| Class | Routes to | Behaviour |
|
|
141
|
+
|-------|-----------|-----------|
|
|
142
|
+
| `cosmetic` | Patcher | Opus generates a unified diff against the deployed worktree → `applyUnifiedDiff` → validate via fix-on-failure → on success snapshot to `versions/vN+1/`, on any failure restore the snapshot atomically and post the reason to chat. |
|
|
143
|
+
| `spec-delta` | Focused interview | Flips mode back to `interview` with a bootstrap message that names the field(s) being changed. Completion auto-triggers a fresh `startBuild`. |
|
|
144
|
+
| `structural` | Suggestion only | Posts a narrator note: "this sounds like a different app — click + New". |
|
|
145
|
+
|
|
146
|
+
To swap which version is live, use `promote-version` (HTTP) or
|
|
147
|
+
`ultraapp_promote_version` (MCP) — the router map and host-procs map
|
|
148
|
+
update atomically.
|
|
149
|
+
|
|
150
|
+
## Reference traces + replay
|
|
151
|
+
|
|
152
|
+
5 captured JSONL traces of real interviews ground-truth the interview
|
|
153
|
+
engine against drift:
|
|
154
|
+
|
|
155
|
+
```text
|
|
156
|
+
src/__tests__/fixtures/ultraapp-traces/
|
|
157
|
+
├── text-summariser.jsonl (synthetic, simple text in/out)
|
|
158
|
+
├── image-batch-resize.jsonl (batch upload + Pillow + zip)
|
|
159
|
+
├── vlog-cut.jsonl (ffmpeg + whisper + branching DAG)
|
|
160
|
+
├── llm-agent-pipeline.jsonl (BYOK, multi-step LLM)
|
|
161
|
+
├── branching-dag.jsonl (parallel paths converging)
|
|
162
|
+
├── _format.md (trace JSONL schema)
|
|
163
|
+
└── expected/<name>.appspec.json (frozen target)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
tsx scripts/test-ultraapp-integration.ts --trace=image-batch-resize
|
|
168
|
+
tsx scripts/test-ultraapp-integration.ts --trace=all
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
The `spec-extraction-quality.test.ts` test replays each trace through
|
|
172
|
+
the interview engine and asserts the resulting `AppSpec` matches the
|
|
173
|
+
frozen snapshot — any future engine or skill drift fails this test.
|
|
174
|
+
|
|
175
|
+
## Operator quick start
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# 1. Boot
|
|
179
|
+
clawo serve # dashboard at :18796, ultraapp router at :19000
|
|
180
|
+
open "http://127.0.0.1:18796/dashboard?token=$(cat ~/.openclaw/server-token)"
|
|
181
|
+
|
|
182
|
+
# 2. Forge tab → + New → walk through the interview
|
|
183
|
+
|
|
184
|
+
# 3. After [Start Build] (or POST /ultraapp/<id>/build), watch:
|
|
185
|
+
# mode pill: queued → building → done
|
|
186
|
+
# narrator: short conversational chat updates
|
|
187
|
+
# Versions panel: v1, v2, … with Promote per row
|
|
188
|
+
|
|
189
|
+
# 4. Live URL appears in the share card. The deployed app is reachable at:
|
|
190
|
+
curl http://127.0.0.1:19000/forge/<slug>/health
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Known limitations (v4.0.0)
|
|
194
|
+
|
|
195
|
+
- The done-mode patcher loop occasionally hangs between
|
|
196
|
+
feedback-classification and the patcher Opus session creation;
|
|
197
|
+
cosmetic changes can be applied manually until the underlying race
|
|
198
|
+
is fixed.
|
|
199
|
+
- The §7g frontend gate currently relies on per-agent honesty about
|
|
200
|
+
running the screenshot capture; agents that skip the inspection can
|
|
201
|
+
still pass the smoke gate. A follow-up will plumb a server-side
|
|
202
|
+
screenshot validator into the council verifier so the gate becomes
|
|
203
|
+
structurally enforced rather than persona-enforced.
|