@chorus-aidlc/chorus-openclaw-plugin 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +208 -278
- package/dist/commands.d.ts +5 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +147 -0
- package/dist/commands.js.map +1 -0
- package/dist/config.d.ts +38 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +57 -0
- package/dist/config.js.map +1 -0
- package/dist/event-router.d.ts +55 -0
- package/dist/event-router.d.ts.map +1 -0
- package/dist/event-router.js +157 -0
- package/dist/event-router.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +108 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-client.d.ts +37 -0
- package/dist/mcp-client.d.ts.map +1 -0
- package/dist/mcp-client.js +137 -0
- package/dist/mcp-client.js.map +1 -0
- package/dist/mcp-registration.d.ts +25 -0
- package/dist/mcp-registration.d.ts.map +1 -0
- package/dist/mcp-registration.js +93 -0
- package/dist/mcp-registration.js.map +1 -0
- package/dist/sse-listener.d.ts +37 -0
- package/dist/sse-listener.d.ts.map +1 -0
- package/dist/sse-listener.js +152 -0
- package/dist/sse-listener.js.map +1 -0
- package/dist/wake.d.ts +67 -0
- package/dist/wake.d.ts.map +1 -0
- package/dist/wake.js +234 -0
- package/dist/wake.js.map +1 -0
- package/openclaw.plugin.json +13 -12
- package/package.json +23 -5
- package/skills/brainstorm/SKILL.md +163 -0
- package/skills/chorus/SKILL.md +113 -96
- package/skills/develop/SKILL.md +195 -51
- package/skills/idea/SKILL.md +136 -149
- package/skills/openspec-aware/SKILL.md +425 -0
- package/skills/proposal/SKILL.md +155 -157
- package/skills/proposal-reviewer/SKILL.md +117 -0
- package/skills/quick-dev/SKILL.md +31 -7
- package/skills/review/SKILL.md +105 -33
- package/skills/task-reviewer/SKILL.md +113 -0
- package/skills/yolo/SKILL.md +498 -0
- package/src/commands.ts +138 -71
- package/src/config.ts +23 -10
- package/src/event-router.ts +46 -54
- package/src/index.ts +56 -83
- package/src/mcp-client.ts +17 -0
- package/src/mcp-registration.ts +142 -0
- package/src/openclaw-sdk.d.ts +95 -0
- package/src/wake.ts +310 -0
- package/src/tools/admin-tools.ts +0 -126
- package/src/tools/common-tools.ts +0 -575
- package/src/tools/dev-tools.ts +0 -105
- package/src/tools/pm-tools.ts +0 -411
package/README.md
CHANGED
|
@@ -12,90 +12,74 @@
|
|
|
12
12
|
|
|
13
13
|
OpenClaw plugin for [Chorus](https://github.com/Chorus-AIDLC/Chorus) — the AI-DLC (AI-Driven Development Lifecycle) collaboration platform.
|
|
14
14
|
|
|
15
|
-
This plugin
|
|
15
|
+
This plugin lets an OpenClaw agent participate in the full Chorus Idea → Proposal → Task → Execute → Verify workflow. It does two things at activation:
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
1. **Auto-registers the Chorus MCP server** in your OpenClaw config so the agent gains native `chorus__*` tools (no hand-wrapped tools — OpenClaw connects to Chorus over MCP directly).
|
|
18
|
+
2. **Opens a persistent SSE connection** to Chorus and wakes the agent in-process (runs an embedded agent turn via `runEmbeddedAgent`) the moment a task is assigned, you are @mentioned, a proposal is approved/rejected, and more.
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
Chorus Server
|
|
21
|
-
│
|
|
22
|
-
├── SSE (GET /api/events/notifications)
|
|
23
|
-
│ Push real-time events: task_assigned, mentioned,
|
|
24
|
-
│ proposal_rejected, elaboration_answered, etc.
|
|
25
|
-
│ │
|
|
26
|
-
│ ▼
|
|
27
|
-
│ ┌──────────────────────┐
|
|
28
|
-
│ │ SSE Listener │ ── auto-reconnect with
|
|
29
|
-
│ │ (background service)│ exponential backoff
|
|
30
|
-
│ └──────────┬───────────┘
|
|
31
|
-
│ │
|
|
32
|
-
│ ┌──────────▼───────────┐
|
|
33
|
-
│ │ Event Router │ ── filters by project,
|
|
34
|
-
│ │ │ maps event → action
|
|
35
|
-
│ └──────────┬───────────┘
|
|
36
|
-
│ │
|
|
37
|
-
│ ┌──────────▼───────────┐ POST /hooks/wake
|
|
38
|
-
│ │ Agent Trigger │ ──────────────────────► OpenClaw Agent
|
|
39
|
-
│ └──────────────────────┘ (immediate heartbeat)
|
|
40
|
-
│
|
|
41
|
-
├── MCP (POST /api/mcp)
|
|
42
|
-
│ 47 Chorus MCP tools available as native
|
|
43
|
-
│ OpenClaw agent tools via @modelcontextprotocol/sdk
|
|
44
|
-
│
|
|
45
|
-
└─────────────────────────────────────────────────────
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
**Key design decisions:**
|
|
49
|
-
|
|
50
|
-
- **MCP Client, not REST** — Uses `@modelcontextprotocol/sdk` to call Chorus MCP tools directly. Zero Chorus-side code changes needed. 47 tools registered out of the box. When Chorus adds new MCP tools, adding them to the plugin is a one-liner.
|
|
51
|
-
- **SSE for push, MCP for pull** — SSE delivers real-time notifications; MCP handles all tool operations (claim, report, submit, etc.).
|
|
52
|
-
- **Hooks-based agent wake** — Uses OpenClaw's `/hooks/wake` API to inject system events and trigger immediate heartbeats when Chorus events arrive.
|
|
20
|
+
It also ships **11 skills** — 9 workflow skills plus 2 read-only reviewer skills (`/proposal-reviewer`, `/task-reviewer`) that run inside spawned sub-agents.
|
|
53
21
|
|
|
54
|
-
|
|
22
|
+
> **Requires OpenClaw `>=2026.4.27`.** This package uses the OpenClaw Plugin SDK (`definePluginEntry` + native MCP auto-registration + `runEmbeddedAgent` wake + `activation.onStartup`). The binding floor is the newest API it depends on: `activation.onStartup` shipped in **2026.4.27** (`definePluginEntry` ~2026.3.28, `runEmbeddedAgent` 2026.4.10, `mutateConfigFile` 2026.4.26). The floor is enforced by `package.json` → `openclaw.compat.pluginApi` and `openclaw.install.minHostVersion` (both `>=2026.4.27`). On older hosts the SDK entry subpath / `activation.onStartup` are unavailable and the plugin will not load (or won't start its SSE service).
|
|
23
|
+
>
|
|
24
|
+
> **`activation.onStartup` is required.** This plugin has no channel or provider, so it would NOT be activated at gateway cold-boot without `activation: { onStartup: true }` in `openclaw.plugin.json`. That flag is what tells OpenClaw to import the plugin (and start its SSE service) on startup — without it the plugin shows as "enabled" but its background service never runs.
|
|
55
25
|
|
|
56
|
-
|
|
57
|
-
- [Chorus](https://github.com/Chorus-AIDLC/Chorus) server accessible
|
|
58
|
-
- A Chorus API Key (`cho_` prefix) for the agent
|
|
59
|
-
- OpenClaw hooks enabled (`hooks.enabled: true` in `openclaw.json`)
|
|
26
|
+
---
|
|
60
27
|
|
|
61
28
|
## Installation
|
|
62
29
|
|
|
63
|
-
###
|
|
30
|
+
### From npm
|
|
64
31
|
|
|
65
32
|
```bash
|
|
66
|
-
openclaw plugins install
|
|
33
|
+
openclaw plugins install npm:@chorus-aidlc/chorus-openclaw-plugin
|
|
34
|
+
openclaw plugins enable chorus-openclaw-plugin
|
|
67
35
|
```
|
|
68
36
|
|
|
69
|
-
|
|
37
|
+
Restart the OpenClaw gateway if it was already running so it picks up the new plugin and the MCP server entry the plugin writes on first activation.
|
|
70
38
|
|
|
71
|
-
|
|
39
|
+
### Local development (link the repo checkout)
|
|
72
40
|
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
"token": "your-hooks-token"
|
|
78
|
-
}
|
|
79
|
-
}
|
|
41
|
+
```bash
|
|
42
|
+
# from the repo: packages/openclaw-plugin
|
|
43
|
+
openclaw plugins install --link . # link this directory instead of copying
|
|
44
|
+
openclaw plugins enable chorus-openclaw-plugin
|
|
80
45
|
```
|
|
81
46
|
|
|
82
|
-
|
|
47
|
+
A **linked** install does **not** need a build step. OpenClaw treats a linked
|
|
48
|
+
local plugin as a source checkout (`requireBuiltRuntimeEntry: false` — see
|
|
49
|
+
`src/plugins/discovery.ts`) and loads the TypeScript `extensions` entry
|
|
50
|
+
(`src/index.ts`) directly through its bundled `jiti` transpiler. `--link` keeps
|
|
51
|
+
OpenClaw pointed at your working tree, so editing `src/**` and restarting the
|
|
52
|
+
gateway picks up your changes without re-installing or recompiling.
|
|
53
|
+
|
|
54
|
+
> The compiled `dist/` is only required for the **npm-published** install path
|
|
55
|
+
> below — a copied/npm install sets `requireBuiltRuntimeEntry: true`, so OpenClaw
|
|
56
|
+
> demands the compiled runtime entry declared in `openclaw.runtimeExtensions`.
|
|
57
|
+
> Run `npm run build` before publishing (it also runs automatically via
|
|
58
|
+
> `prepublishOnly`). You do not need it for local `--link` development.
|
|
83
59
|
|
|
84
|
-
|
|
60
|
+
> The plugin id is **`chorus-openclaw-plugin`** — that is the argument to `enable` / `disable` / `uninstall`, and the key under `plugins.entries` in your config.
|
|
85
61
|
|
|
86
|
-
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Configuration
|
|
65
|
+
|
|
66
|
+
### Where config lives
|
|
67
|
+
|
|
68
|
+
Plugin config lives in **`~/.openclaw/openclaw.json`** under:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
plugins.entries.chorus-openclaw-plugin.config
|
|
72
|
+
```
|
|
87
73
|
|
|
88
74
|
```json
|
|
89
75
|
{
|
|
90
76
|
"plugins": {
|
|
91
|
-
"enabled": true,
|
|
92
77
|
"entries": {
|
|
93
78
|
"chorus-openclaw-plugin": {
|
|
94
79
|
"enabled": true,
|
|
95
80
|
"config": {
|
|
96
81
|
"chorusUrl": "https://chorus.example.com",
|
|
97
|
-
"apiKey": "cho_your_api_key_here"
|
|
98
|
-
"autoStart": true
|
|
82
|
+
"apiKey": "cho_your_api_key_here"
|
|
99
83
|
}
|
|
100
84
|
}
|
|
101
85
|
}
|
|
@@ -103,277 +87,223 @@ Add the plugin entry to `~/.openclaw/openclaw.json`:
|
|
|
103
87
|
}
|
|
104
88
|
```
|
|
105
89
|
|
|
106
|
-
|
|
90
|
+
### Config keys
|
|
91
|
+
|
|
92
|
+
| Key | Type | Required | Default | What it does |
|
|
93
|
+
|-----|------|----------|---------|--------------|
|
|
94
|
+
| `chorusUrl` | `string` | **Yes** | — | Base URL of your Chorus server. The plugin derives the MCP endpoint (`<chorusUrl>/api/mcp`) and the SSE endpoint from it. |
|
|
95
|
+
| `apiKey` | `string` | **Yes** | — | Chorus API Key (`cho_` prefix). Used as the `Bearer` token for both the MCP server entry and the SSE connection. Marked `sensitive` in the UI hints. |
|
|
107
96
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
97
|
+
If `chorusUrl` or `apiKey` is missing, the plugin logs a warning naming the missing field, skips MCP registration, and disables its features — it does not crash the gateway.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## How tools work now (native MCP)
|
|
102
|
+
|
|
103
|
+
On activation (full registration mode), the plugin **writes an `mcp.servers.chorus` entry** into your OpenClaw config via the host's `runtime.config.mutateConfigFile` API:
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"mcp": {
|
|
108
|
+
"servers": {
|
|
109
|
+
"chorus": {
|
|
110
|
+
"url": "https://chorus.example.com/api/mcp",
|
|
111
|
+
"transport": "streamable-http",
|
|
112
|
+
"headers": { "Authorization": "Bearer cho_your_api_key_here" }
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
OpenClaw then connects to the remote Chorus MCP server and **exposes every Chorus tool to the agent under the `chorus__` prefix** — for example `chorus__chorus_get_task`, `chorus__chorus_claim_task`, `chorus__chorus_submit_for_verify`. The plugin never re-declares those tools itself; they come straight from the MCP server.
|
|
120
|
+
|
|
121
|
+
The write is **idempotent**: if the existing entry already matches (same url + transport + Authorization), the plugin skips the write so it does not trigger a config reload on every activation. If `runtime.config.mutateConfigFile` is unavailable on the host, the failure is logged and swallowed — the SSE service and `/chorus` command still register.
|
|
122
|
+
|
|
123
|
+
### Migration note: bare `chorus_*` tool names are gone
|
|
124
|
+
|
|
125
|
+
Earlier versions of this plugin **hand-wrapped** Chorus tools and exposed them to the agent under their bare names (`chorus_get_task`, `chorus_claim_task`, …). **Those registrations have been removed.** Tools now come from the auto-registered MCP server and are namespaced with the server id, so they appear as **`chorus__<tool>`** (double underscore).
|
|
126
|
+
|
|
127
|
+
If you have macros, prompts, or agent instructions that reference the bare names, update them:
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
chorus_get_task → chorus__chorus_get_task
|
|
131
|
+
chorus_submit_for_verify → chorus__chorus_submit_for_verify
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
(Inside the bundled skills and reviewer-agent prompts the tools are referred to by their logical Chorus names; OpenClaw resolves them through the MCP server.)
|
|
135
|
+
|
|
136
|
+
### bundle-mcp sandbox caveat
|
|
137
|
+
|
|
138
|
+
When OpenClaw runs agents in a sandbox (`tools.sandbox.mode` = `"all"` or `"non-main"`), **MCP tools are owned by the built-in `bundle-mcp` plugin** and are filtered out of the agent's tool list by default. The `chorus__*` tools will be missing until you add either the `bundle-mcp` plugin or the `chorus__` glob to the sandbox allow list:
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"tools": {
|
|
143
|
+
"sandbox": {
|
|
144
|
+
"tools": {
|
|
145
|
+
"alsoAllow": ["chorus__*"]
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
114
151
|
|
|
115
|
-
|
|
152
|
+
You can broaden this to `["bundle-mcp"]` to allow all MCP tools, or keep it scoped to `["chorus__*"]` to allow only Chorus tools. Restart the gateway after editing the sandbox policy. If you are **not** using sandbox mode, no allow-list change is needed.
|
|
116
153
|
|
|
117
|
-
|
|
154
|
+
---
|
|
118
155
|
|
|
119
|
-
-
|
|
120
|
-
- **`hooks.token`** — shared secret for hook authentication (must differ from `gateway.auth.token`)
|
|
121
|
-
- **`gateway.port`** — defaults to `18789`
|
|
156
|
+
## Real-time events (SSE → agent wake)
|
|
122
157
|
|
|
123
|
-
|
|
158
|
+
The plugin runs a background service (`chorus-sse`) that holds an SSE connection to Chorus. When an event arrives it fetches the full notification over MCP and **wakes the main agent in-process** by running an embedded agent turn via the host's `runtime.agent.runEmbeddedAgent(...)`, with the event text as the turn's prompt. The turn runs on the main agent's existing session (so it has conversation context and the full `chorus__*` MCP tool set) and is headless (`disableMessageTool: true`) — the agent acts by calling Chorus MCP tools (e.g. `chorus_get_comments`, `chorus_add_comment`) rather than replying to a chat channel.
|
|
124
159
|
|
|
125
|
-
|
|
160
|
+
> **Why not `enqueueSystemEvent`?** An earlier version pushed the wake text onto the session's system-event queue and triggered a heartbeat. That does **not** work for delivering content: the heartbeat prompt builder only renders exec-completion / cron events into a prompt, so a plain notification's queued text is never injected — the agent just runs the generic `[OpenClaw heartbeat poll]`. `runEmbeddedAgent` delivers the prompt directly.
|
|
126
161
|
|
|
127
|
-
The
|
|
162
|
+
> **The configured model is passed explicitly.** `runEmbeddedAgent` does not auto-resolve the model from config; with no `provider`/`model` it falls back to the built-in default (`gpt-5.5`) and errors with "Unknown model". The plugin reads `agents.defaults.model` (`"provider/model"` or `{ primary: "provider/model" }`) and passes `provider` + `model` to each wake turn.
|
|
128
163
|
|
|
129
164
|
| Event | Behavior |
|
|
130
165
|
|-------|----------|
|
|
131
|
-
| `task_assigned` |
|
|
132
|
-
| `mentioned` | Wake agent with @mention context |
|
|
133
|
-
| `elaboration_requested` | Wake agent to review elaboration questions |
|
|
134
|
-
| `elaboration_answered` | Wake agent to review answers,
|
|
135
|
-
| `proposal_rejected` | Wake agent with rejection
|
|
136
|
-
| `proposal_approved` | Wake agent to
|
|
137
|
-
| `idea_claimed` | Wake agent when an idea is assigned to it
|
|
166
|
+
| `task_assigned` | Wake the agent to review the task and claim it (`chorus_claim_task`) when ready |
|
|
167
|
+
| `mentioned` | Wake the agent with the @mention context and a pointer to the conversation |
|
|
168
|
+
| `elaboration_requested` | Wake the agent to review elaboration questions |
|
|
169
|
+
| `elaboration_answered` | Wake the agent to review answers, then validate or open another round |
|
|
170
|
+
| `proposal_rejected` | Wake the agent with the rejection note to fix and resubmit |
|
|
171
|
+
| `proposal_approved` | Wake the agent to pick up the newly created tasks |
|
|
172
|
+
| `idea_claimed` | Wake the agent when an idea is assigned to it |
|
|
173
|
+
| `task_verified` | Wake the agent to check for newly unblocked tasks |
|
|
174
|
+
| `task_reopened` | Wake the agent with verification feedback to rework |
|
|
175
|
+
|
|
176
|
+
**Resilience.** The SSE listener auto-reconnects with exponential backoff (1s → 2s → … → 30s max). After a reconnect it back-fills unread notifications over MCP so nothing is lost while disconnected. If no main agent session key can be resolved, `runEmbeddedAgent` is unavailable on the host, or a wake turn rejects (e.g. a turn is already in flight), the individual wake is **dropped with a warning** — it never throws and never crashes the SSE service. The next SSE event re-triggers.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Skills (11)
|
|
181
|
+
|
|
182
|
+
Skills are bundled under `skills/` and auto-discovered by OpenClaw. On OpenClaw a skill is invoked as a **bare slash command of its name** — e.g. `/develop`, `/idea` (OpenClaw does **not** use a `chorus:` namespace prefix).
|
|
138
183
|
|
|
139
|
-
|
|
184
|
+
| Skill | Invoke | Description |
|
|
185
|
+
|-------|--------|-------------|
|
|
186
|
+
| `chorus` | `/chorus` | Platform overview, common tools, setup, and routing to the stage-specific skills |
|
|
187
|
+
| `idea` | `/idea` | Claim ideas, run elaboration rounds, and prepare for proposal creation |
|
|
188
|
+
| `brainstorm` | `/brainstorm` | Optional divergent-then-convergent dialogue for fuzzy ideas (prelude to elaboration) |
|
|
189
|
+
| `proposal` | `/proposal` | Create proposals with document + task drafts, manage the dependency DAG, validate and submit |
|
|
190
|
+
| `develop` | `/develop` | Claim tasks, report work, manage sessions, and run wave-based execution |
|
|
191
|
+
| `quick-dev` | `/quick-dev` | Skip Idea→Proposal — create tasks directly, execute, and verify |
|
|
192
|
+
| `review` | `/review` | Approve/reject proposals, verify tasks, and manage project governance |
|
|
193
|
+
| `yolo` | `/yolo` | Full-auto AI-DLC pipeline — from prompt to done |
|
|
194
|
+
| `openspec-aware` | `/openspec-aware` | Opt-in OpenSpec authoring for PM workflows when the local `openspec` CLI is present |
|
|
195
|
+
| `proposal-reviewer` | `/proposal-reviewer` | Read-only adversarial proposal review; ends with a `VERDICT:` comment |
|
|
196
|
+
| `task-reviewer` | `/task-reviewer` | Read-only adversarial task verification (read-only bash for tests); ends with a `VERDICT:` comment |
|
|
140
197
|
|
|
141
|
-
|
|
198
|
+
> Note: `/chorus` (the bare skill) and the `/chorus <subcommand>` command share the same `chorus` prefix. `/chorus status|tasks|ideas|skills` are fast, LLM-free status queries handled by the plugin command (see below); `/chorus` with no recognized subcommand falls through to the command's help/status.
|
|
142
199
|
|
|
143
|
-
|
|
200
|
+
## Reviewer skills (2)
|
|
201
|
+
|
|
202
|
+
`proposal-reviewer` and `task-reviewer` are bundled **as skills** (not agent definitions — OpenClaw has no Claude-Code-style typed agents). Both are **read-only** and end by posting a structured `VERDICT:` comment.
|
|
203
|
+
|
|
204
|
+
They are meant to run inside a **spawned sub-agent**: the orchestrating skill (`/proposal`, `/develop`, `/yolo`, `/review`) uses the OpenClaw `sessions_spawn` tool to spawn a sub-agent and instructs it (in the spawn `task`) to invoke `/proposal-reviewer` or `/task-reviewer` against the entity, then waits for the VERDICT. Spawned sub-agents inherit the plugin's skill snapshot, so the slash-commands are available to them. If `sessions_spawn` is unavailable, the orchestrator runs the same review itself as a read-only pass (the reviewer skills are the authoritative checklists).
|
|
144
205
|
|
|
145
206
|
| Skill | Description |
|
|
146
207
|
|-------|-------------|
|
|
147
|
-
| `
|
|
148
|
-
| `
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
### Registered Tools (47 total)
|
|
157
|
-
|
|
158
|
-
#### PM Workflow (17 tools)
|
|
159
|
-
|
|
160
|
-
| Tool | Description |
|
|
161
|
-
|------|-------------|
|
|
162
|
-
| `chorus_claim_idea` | Claim an open idea for elaboration |
|
|
163
|
-
| `chorus_start_elaboration` | Start elaboration round with structured questions |
|
|
164
|
-
| `chorus_answer_elaboration` | Submit answers for elaboration round |
|
|
165
|
-
| `chorus_validate_elaboration` | Validate answers, resolve or request follow-up |
|
|
166
|
-
| `chorus_create_proposal` | Create proposal with document + task drafts |
|
|
167
|
-
| `chorus_add_document_draft` | Add document draft to proposal |
|
|
168
|
-
| `chorus_add_task_draft` | Add task draft to proposal |
|
|
169
|
-
| `chorus_get_proposal` | View full proposal with all draft UUIDs |
|
|
170
|
-
| `chorus_update_document_draft` | Modify document draft |
|
|
171
|
-
| `chorus_update_task_draft` | Modify task draft (including dependencies) |
|
|
172
|
-
| `chorus_remove_document_draft` | Remove document draft |
|
|
173
|
-
| `chorus_remove_task_draft` | Remove task draft |
|
|
174
|
-
| `chorus_validate_proposal` | Check proposal completeness before submit |
|
|
175
|
-
| `chorus_submit_proposal` | Submit proposal for approval |
|
|
176
|
-
| `chorus_pm_create_idea` | Create a new idea in a project |
|
|
177
|
-
| `chorus_pm_assign_task` | Assign a task to a specific Developer Agent |
|
|
178
|
-
| `chorus_move_idea` | Move an idea to a different project |
|
|
179
|
-
|
|
180
|
-
#### Developer Workflow (4 tools)
|
|
181
|
-
|
|
182
|
-
| Tool | Description |
|
|
183
|
-
|------|-------------|
|
|
184
|
-
| `chorus_claim_task` | Claim an open task |
|
|
185
|
-
| `chorus_update_task` | Update task status or fields (title, description, priority, dependencies) |
|
|
186
|
-
| `chorus_report_work` | Report work progress (writes comment + records activity) |
|
|
187
|
-
| `chorus_submit_for_verify` | Submit completed task for verification |
|
|
188
|
-
| `chorus_report_criteria_self_check` | Self-check acceptance criteria before submitting |
|
|
189
|
-
|
|
190
|
-
#### Common & Exploration (21 tools)
|
|
191
|
-
|
|
192
|
-
| Tool | Description |
|
|
193
|
-
|------|-------------|
|
|
194
|
-
| `chorus_checkin` | Agent check-in (identity, owner info, roles, assignments) |
|
|
195
|
-
| `chorus_get_notifications` | Fetch notifications (default: unread) |
|
|
196
|
-
| `chorus_get_project` | Get project details |
|
|
197
|
-
| `chorus_get_task` | Get task details |
|
|
198
|
-
| `chorus_get_idea` | Get idea details |
|
|
199
|
-
| `chorus_get_available_tasks` | List open tasks in a project |
|
|
200
|
-
| `chorus_get_available_ideas` | List open ideas in a project |
|
|
201
|
-
| `chorus_add_comment` | Comment on idea/proposal/task/document |
|
|
202
|
-
| `chorus_search_mentionables` | Search for @mentionable users and agents |
|
|
203
|
-
| `chorus_list_projects` | List all projects |
|
|
204
|
-
| `chorus_list_tasks` | List tasks in a project (filterable by status/priority) |
|
|
205
|
-
| `chorus_get_ideas` | List ideas in a project (filterable by status) |
|
|
206
|
-
| `chorus_get_proposals` | List proposals in a project |
|
|
207
|
-
| `chorus_get_documents` | List documents in a project |
|
|
208
|
-
| `chorus_get_document` | Get full document content |
|
|
209
|
-
| `chorus_get_unblocked_tasks` | List tasks ready to start (dependencies resolved) |
|
|
210
|
-
| `chorus_get_activity` | Get project activity stream |
|
|
211
|
-
| `chorus_get_comments` | Get comments on an entity |
|
|
212
|
-
| `chorus_get_elaboration` | Get full elaboration state for an idea |
|
|
213
|
-
| `chorus_get_my_assignments` | Get all claimed ideas and tasks |
|
|
214
|
-
| `chorus_get_project_groups` | List all project groups |
|
|
215
|
-
| `chorus_get_project_group` | Get a project group with its projects |
|
|
216
|
-
| `chorus_create_tasks` | Batch create tasks (Quick Task or Proposal-linked) |
|
|
217
|
-
| `chorus_search` | Search across tasks, ideas, proposals, documents, projects |
|
|
218
|
-
|
|
219
|
-
#### Admin (5 tools)
|
|
220
|
-
|
|
221
|
-
| Tool | Description |
|
|
222
|
-
|------|-------------|
|
|
223
|
-
| `chorus_admin_create_project` | Create a new project |
|
|
224
|
-
| `chorus_admin_create_project_group` | Create a new project group |
|
|
225
|
-
| `chorus_admin_approve_proposal` | Approve a proposal (materializes drafts into Documents + Tasks) |
|
|
226
|
-
| `chorus_admin_verify_task` | Verify a task (to_verify → done, unblocks downstream) |
|
|
227
|
-
| `chorus_mark_acceptance_criteria` | Mark acceptance criteria as passed/failed |
|
|
228
|
-
|
|
229
|
-
### Commands
|
|
230
|
-
|
|
231
|
-
Bypass LLM for fast status queries:
|
|
208
|
+
| `/proposal-reviewer` | Reviews submitted proposals — document completeness, task granularity, AC alignment, cross-task dependencies. No Bash. |
|
|
209
|
+
| `/task-reviewer` | Verifies submitted tasks against the AC and proposal documents. Read-only Bash allowed for verification only (tests/build, `cat`/`grep`/`ls`, `git diff`/`log`/`show`). |
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Commands
|
|
214
|
+
|
|
215
|
+
`/chorus` runs fast, LLM-free status queries through the plugin's own slim MCP client:
|
|
232
216
|
|
|
233
217
|
| Command | Description |
|
|
234
218
|
|---------|-------------|
|
|
235
|
-
| `/chorus` or `/chorus status` | Connection status,
|
|
219
|
+
| `/chorus` or `/chorus status` | Connection status, agent identity, assigned-idea count, unread notifications, skill list |
|
|
236
220
|
| `/chorus tasks` | List your assigned tasks |
|
|
237
221
|
| `/chorus ideas` | List your assigned ideas |
|
|
238
|
-
| `/chorus skills` | List
|
|
222
|
+
| `/chorus skills` | List the 9 bundled Chorus skills |
|
|
223
|
+
|
|
224
|
+
---
|
|
239
225
|
|
|
240
226
|
## Architecture
|
|
241
227
|
|
|
242
228
|
```
|
|
243
229
|
packages/openclaw-plugin/
|
|
244
|
-
├── package.json # npm
|
|
245
|
-
├── openclaw.plugin.json #
|
|
246
|
-
├── tsconfig.json
|
|
247
|
-
├──
|
|
248
|
-
|
|
249
|
-
│ ├── idea/SKILL.md # Idea → Elaboration workflow
|
|
250
|
-
│ ├── proposal/SKILL.md # Proposal → DAG → Submit workflow
|
|
251
|
-
│ ├── develop/SKILL.md # Task → Report → Verify workflow
|
|
252
|
-
│ ├── quick-dev/SKILL.md # Quick task creation & execution
|
|
253
|
-
│ └── review/SKILL.md # Admin review & governance
|
|
230
|
+
├── package.json # npm + openclaw block (extensions / runtimeExtensions, install, compat)
|
|
231
|
+
├── openclaw.plugin.json # plugin manifest (id, activation.onStartup, configSchema, skills dir, uiHints)
|
|
232
|
+
├── tsconfig.json # build config; excludes __tests__ from dist
|
|
233
|
+
├── vitest.config.ts # standalone test runner config (package is outside the root workspace)
|
|
234
|
+
├── skills/ # 11 SKILL.md skills (9 workflow + proposal-reviewer + task-reviewer), auto-discovered
|
|
254
235
|
└── src/
|
|
255
|
-
├── index.ts #
|
|
256
|
-
├── config.ts #
|
|
257
|
-
├── mcp-
|
|
258
|
-
├──
|
|
259
|
-
├──
|
|
260
|
-
├──
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
└── admin-tools.ts # 5 Admin tools
|
|
236
|
+
├── index.ts # definePluginEntry — wires everything; gated to "full" registration mode
|
|
237
|
+
├── config.ts # config contract (chorusUrl, apiKey) + location constants
|
|
238
|
+
├── mcp-registration.ts # writes mcp.servers.chorus (idempotent, streamable-http + Bearer)
|
|
239
|
+
├── mcp-client.ts # slim MCP client for the plugin's own calls (checkin, assignments, claim)
|
|
240
|
+
├── sse-listener.ts # SSE connection + exponential-backoff reconnect
|
|
241
|
+
├── event-router.ts # SSE event → wake-message mapping (project-filtered)
|
|
242
|
+
├── wake.ts # resolves main session + model, runs an embedded agent turn (runEmbeddedAgent)
|
|
243
|
+
├── commands.ts # /chorus status|tasks|ideas|skills
|
|
244
|
+
├── openclaw-sdk.d.ts # ambient SDK shim (compile-time only; see below)
|
|
245
|
+
└── __tests__/ # vitest unit tests (config, mcp-registration, wake, event-router, commands, sse-listener)
|
|
266
246
|
```
|
|
267
247
|
|
|
268
|
-
###
|
|
269
|
-
|
|
270
|
-
Wraps `@modelcontextprotocol/sdk` with:
|
|
271
|
-
- **Lazy connection** — connects on first `callTool()`, not at startup
|
|
272
|
-
- **Auto-reconnect** — detects 404 (session expired), reconnects, retries the call
|
|
273
|
-
- **Status tracking** — `connected | disconnected | connecting | reconnecting`
|
|
274
|
-
|
|
275
|
-
### SSE Listener (`sse-listener.ts`)
|
|
276
|
-
|
|
277
|
-
- Native `fetch()` + `ReadableStream` (not browser EventSource — allows `Authorization` header)
|
|
278
|
-
- `Authorization: Bearer cho_xxx` authentication
|
|
279
|
-
- SSE protocol parsing (`data:` lines → JSON, `:` heartbeat lines ignored)
|
|
280
|
-
- Exponential backoff: 1s → 2s → 4s → 8s → 16s → 30s (max)
|
|
281
|
-
- Calls `onReconnect()` after successful reconnect for notification back-fill
|
|
248
|
+
### Note on `openclaw-sdk.d.ts`
|
|
282
249
|
|
|
283
|
-
|
|
250
|
+
The entry imports `definePluginEntry` from `openclaw/plugin-sdk/plugin-entry`, a subpath available in OpenClaw `>=2026.4.27` (the plugin's host floor). When the locally resolvable `openclaw` package is an older build, `tsc` cannot resolve that subpath, so `src/openclaw-sdk.d.ts` declares a minimal ambient module to satisfy the type-checker. It is **compile-time only** — at install/runtime the real host (`>=2026.4.27`) provides the actual SDK. The floor is enforced at install time by `openclaw.compat.pluginApi >=2026.4.27` (and `openclaw.install.minHostVersion`); `peerDependencies.openclaw >=2026.0.0` is npm metadata only and is intentionally looser. Once the workspace resolves a `>=2026.4.27` `openclaw` build, delete the shim and rely on the real types.
|
|
284
251
|
|
|
285
|
-
|
|
286
|
-
- Filters by `projectUuids` config
|
|
287
|
-
- Routes by notification `action` type
|
|
288
|
-
- All handlers catch errors internally — never crashes the gateway
|
|
289
|
-
|
|
290
|
-
## Troubleshooting
|
|
252
|
+
---
|
|
291
253
|
|
|
292
|
-
|
|
254
|
+
## Validation / Release checklist
|
|
293
255
|
|
|
294
|
-
|
|
256
|
+
The maintainer release gate has four parts. The first (type check + test + build) runs anywhere with Node + the dev dependencies. The last two (SDK validators + smoke) require an installed `openclaw` >=2026.4.27 CLI and a running host.
|
|
295
257
|
|
|
296
|
-
|
|
258
|
+
### 1. Type check, test & build (no OpenClaw CLI required)
|
|
297
259
|
|
|
298
|
-
**Verify:**
|
|
299
260
|
```bash
|
|
300
|
-
|
|
301
|
-
#
|
|
302
|
-
|
|
261
|
+
npm run typecheck # tsc --noEmit → exit 0, no diagnostics
|
|
262
|
+
npm run test # vitest run → exit 0, all unit tests pass
|
|
263
|
+
npm run build # tsc → exit 0, writes dist/index.js
|
|
303
264
|
```
|
|
304
265
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
266
|
+
These three also run automatically before publish via the `prepublishOnly`
|
|
267
|
+
script (`clean → typecheck → test → build`), so `npm publish` cannot ship a
|
|
268
|
+
package that fails to type-check, fails its tests, or is missing the compiled
|
|
269
|
+
`dist/`. Publishing the compiled runtime is **mandatory** for the npm install
|
|
270
|
+
path — a copied/npm install rejects a TypeScript-only entry with *"requires
|
|
271
|
+
compiled runtime output"* (see the local-development note above).
|
|
311
272
|
|
|
312
|
-
|
|
313
|
-
```json
|
|
314
|
-
{
|
|
315
|
-
"tools": {
|
|
316
|
-
"sandbox": {
|
|
317
|
-
"tools": {
|
|
318
|
-
"alsoAllow": ["chorus-openclaw-plugin"]
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
```
|
|
273
|
+
`dist/index.js` must exist and its **default export** must be the `definePluginEntry(...)` result — an object with `id: "chorus-openclaw-plugin"` and a `register` function. A direct `import('./dist/index.js')` resolves the `openclaw/plugin-sdk/plugin-entry` peer subpath, so run this on a host where a >=2026.4.27 `openclaw` package is resolvable.
|
|
324
274
|
|
|
325
|
-
|
|
275
|
+
### 2. OpenClaw SDK validators (require `openclaw` >=2026.4.27 CLI)
|
|
326
276
|
|
|
327
|
-
|
|
328
|
-
Ensure `openclaw.plugin.json` `id` and `index.ts` `id` both equal `chorus-openclaw-plugin`.
|
|
277
|
+
Run from the package root after `npm run build`:
|
|
329
278
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
{ "hooks": { "enabled": true, "token": "your-distinct-token" } }
|
|
279
|
+
```bash
|
|
280
|
+
openclaw plugins build --entry ./dist/index.js --check # expect exit 0: "Plugin metadata is up to date."
|
|
281
|
+
openclaw plugins validate --entry ./dist/index.js # expect exit 0: "Plugin chorus-openclaw-plugin is valid."
|
|
334
282
|
```
|
|
335
|
-
The `hooks.token` must be different from `gateway.auth.token`.
|
|
336
283
|
|
|
337
|
-
|
|
338
|
-
|
|
284
|
+
- `plugins build --check` fails (exit 1, "Generated plugin metadata is out of date. Run openclaw plugins build.") if the committed `openclaw.plugin.json` / `package.json` metadata is stale relative to the entry. If it fails, run `openclaw plugins build` (no `--check`) to regenerate, review the diff, and commit.
|
|
285
|
+
- `plugins validate` loads the manifest, checks the entry id matches the manifest id, confirms the `configSchema` is present, and verifies `package.json` `openclaw.extensions` includes the entry. Expected success: `Plugin chorus-openclaw-plugin is valid.`
|
|
339
286
|
|
|
340
|
-
###
|
|
341
|
-
OpenClaw tool `execute` signature is `execute(toolCallId, params)` — the first argument is the call ID, not the params object. If you see this, check that all tools use `execute(_id, { param1, param2 })`.
|
|
287
|
+
### 3. Manual smoke test (require `openclaw` >=2026.4.27 host)
|
|
342
288
|
|
|
343
|
-
|
|
344
|
-
|
|
289
|
+
```bash
|
|
290
|
+
openclaw plugins install --link .
|
|
291
|
+
openclaw plugins enable chorus-openclaw-plugin
|
|
292
|
+
# configure plugins.entries.chorus-openclaw-plugin.config (chorusUrl + apiKey), then restart the gateway
|
|
293
|
+
```
|
|
345
294
|
|
|
346
|
-
|
|
295
|
+
Confirm:
|
|
347
296
|
|
|
348
|
-
|
|
297
|
+
1. **`mcp.servers.chorus` is written** — inspect `~/.openclaw/openclaw.json`; the `mcp.servers.chorus` entry should have `url: <chorusUrl>/api/mcp`, `transport: "streamable-http"`, and a `Bearer` Authorization header.
|
|
298
|
+
2. **`chorus__*` tools appear** — the agent's tool list includes `chorus__chorus_get_task`, `chorus__chorus_checkin`, etc. (in sandbox mode, after adding `chorus__*` to `tools.sandbox.tools.alsoAllow`).
|
|
299
|
+
3. **SSE wake fires** — assign a Chorus task to this agent; the SSE event should wake the agent in-process. Check the gateway log for `[Chorus] Wake enqueued`.
|
|
300
|
+
4. **`/chorus status` works** — running `/chorus` returns connection status + checkin data (agent name, assigned-idea count, unread notifications, skill list).
|
|
349
301
|
|
|
350
|
-
|
|
351
|
-
# No build needed — OpenClaw loads .ts files directly via jiti
|
|
352
|
-
cd /path/to/Chorus/packages/openclaw-plugin
|
|
353
|
-
```
|
|
302
|
+
### Status in this repo's CI environment
|
|
354
303
|
|
|
355
|
-
|
|
304
|
+
In the repository CI/dev environment the `openclaw` CLI is **not installed** (and the resolvable `openclaw` peer is an older `2026.3.x` build, which is exactly why the `openclaw-sdk.d.ts` shim is still required), so steps 2–3 above cannot be executed here. Section 1 (`tsc --noEmit`, `vitest run`, and `tsc` build → `dist/index.js` with a valid default export) **is** run and must pass. A maintainer on a >=2026.4.27 host must run sections 2 and 3 before publishing and confirm the expected exit codes / messages above.
|
|
356
305
|
|
|
357
|
-
|
|
358
|
-
{
|
|
359
|
-
"plugins": {
|
|
360
|
-
"enabled": true,
|
|
361
|
-
"load": {
|
|
362
|
-
"paths": ["/path/to/Chorus/packages/openclaw-plugin"]
|
|
363
|
-
},
|
|
364
|
-
"entries": {
|
|
365
|
-
"chorus-openclaw-plugin": {
|
|
366
|
-
"enabled": true,
|
|
367
|
-
"config": {
|
|
368
|
-
"chorusUrl": "http://localhost:3000",
|
|
369
|
-
"apiKey": "cho_your_dev_key",
|
|
370
|
-
"autoStart": true
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
```
|
|
306
|
+
---
|
|
377
307
|
|
|
378
308
|
## License
|
|
379
309
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AA6KvD,wBAAgB,sBAAsB,CACpC,GAAG,EAAE;IAAE,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,EACpD,SAAS,EAAE,eAAe,EAC1B,SAAS,EAAE,MAAM,MAAM,GACtB,IAAI,CAqDN"}
|