@jiggai/recipes 0.3.1 → 0.3.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 CHANGED
@@ -6,7 +6,9 @@
6
6
 
7
7
  ClawRecipes is an OpenClaw plugin that provides **CLI-first recipes** for scaffolding specialist agents and teams from Markdown.
8
8
 
9
- If you like durable workflows: ClawRecipes is built around a **file-first team workspace** (inbox/backlog/in-progress/testing/done) that plays nicely with git.
9
+ If you like durable workflows, ClawRecipes is built around a **file-first team workspace** (inbox/backlog/in-progress/testing/done) that plays nicely with git.
10
+
11
+ For those who prefer a beautiful user interface, install **[ClawKitchen](https://github.com/JIGGAI/ClawKitchen)** — our latest plugin where you can add, remove, update, and fully manage your teams in one place. It includes an agile workflow board, a goal tracker, and cron management for convenience.
10
12
 
11
13
  ## Quickstart
12
14
  ### 1) Install
@@ -54,16 +56,6 @@ openclaw recipes dispatch \
54
56
  --owner lead
55
57
  ```
56
58
 
57
- ## License
58
-
59
- ClawRecipes is licensed under **Apache-2.0**.
60
-
61
- Attribution requirement (practical): if you redistribute ClawRecipes (or a derivative work), you must retain the license and attribution notices (see `LICENSE` and `NOTICE`).
62
-
63
- Branding note: the license does not grant permission to use JIGGAI trademarks except as required for reasonable and customary attribution. See `TRADEMARK.md`.
64
-
65
- Contributions: we welcome PRs. By contributing, you agree that your contributions are licensed under the project’s Apache-2.0 license.
66
-
67
59
  ## Commands (high level)
68
60
  - `openclaw recipes list|show|status`
69
61
  - `openclaw recipes scaffold` (agent → `workspace-<agentId>` + writes workspace recipe `~/.openclaw/workspace/recipes/<agentId>.md` by default)
@@ -118,7 +110,9 @@ Run:
118
110
  - `npm run test:smoke` (or `npm run scaffold:smoke`)
119
111
 
120
112
  Notes:
121
- - Creates a temporary `workspace-smoke-<timestamp>-team` under `~/.openclaw/` and then deletes it.
113
+ - Creates a temporary `workspace-smoke-<timestamp>-team` under `~/.openclaw/`.
114
+ - If it does not delete cleanly (crash/interrupt), run cleanup:
115
+ - `openclaw recipes cleanup-workspaces --prefix smoke- --yes`
122
116
  - Exits non-zero on mismatch.
123
117
  - Requires OpenClaw and workspace config.
124
118
 
@@ -180,9 +174,20 @@ Most users should focus on:
180
174
  - running the file-first workflow (dispatch → backlog → in-progress → testing → done)
181
175
 
182
176
  ## Goals
183
- - Release Clawmarket, https://github.com/JIGGAI/ClawMarket, public url https://clawkitchen.ai
184
- - Release ClawKitchen, https://github.com/JIGGAI/ClawKitchen
185
- - Merge at least 1 community pull request
177
+ - ~~Release Clawmarket, https://github.com/JIGGAI/ClawMarket, public url https://clawkitchen.ai~~
178
+ - ~~Release ClawKitchen, https://github.com/JIGGAI/ClawKitchen~~
179
+ - ~~Merge at least 1 community pull request~~
186
180
  - Daily shipping/pull requests of ClawRecipes features
187
181
  - Improve recipes with more detailed agent files
188
- - Add ability to install skills for agents through ClawKitchen
182
+ - Add ability to install skills for agents through ClawKitchen
183
+ - Integrate ClawKitchen with ClawMarket to pull new recipes
184
+
185
+ ## License
186
+
187
+ ClawRecipes is licensed under **Apache-2.0**.
188
+
189
+ Attribution requirement (practical): if you redistribute ClawRecipes (or a derivative work), you must retain the license and attribution notices (see `LICENSE` and `NOTICE`).
190
+
191
+ Branding note: the license does not grant permission to use JIGGAI trademarks except as required for reasonable and customary attribution. See `TRADEMARK.md`.
192
+
193
+ Contributions: we welcome PRs. By contributing, you agree that your contributions are licensed under the project’s Apache-2.0 license.
@@ -59,6 +59,15 @@ openclaw cron list
59
59
  openclaw cron run <jobId>
60
60
  ```
61
61
 
62
+ ## Cleanup (important)
63
+ These verification commands create temporary `workspace-<teamId>` directories.
64
+
65
+ After you finish (or between runs), clean up test workspaces so they don’t accumulate:
66
+
67
+ ```bash
68
+ openclaw recipes cleanup-workspaces --prefix smoke- --prefix qa- --prefix tmp- --prefix test- --yes
69
+ ```
70
+
62
71
  ## What to record
63
72
  - Any recipe that fails to scaffold
64
73
  - Any cron job install/update errors
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jiggai/recipes",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "ClawRecipes plugin for OpenClaw (markdown recipes -> scaffold agents/teams)",
5
5
  "main": "index.ts",
6
6
  "type": "commonjs",
@@ -1,40 +1,23 @@
1
1
  ---
2
2
  id: development-team
3
3
  name: Development Team
4
- version: 0.2.1
4
+ version: 0.2.0
5
5
  description: A small engineering team with a shared workspace (lead, dev, devops, test) using file-first tickets.
6
6
  kind: team
7
7
  cronJobs:
8
8
  - id: lead-triage-loop
9
9
  name: "Lead triage loop"
10
- schedule: "*/30 8-23 * * 1-5"
11
- agentId: "{{teamId}}-lead"
12
- channel: "last"
13
- message: "Lead triage loop (automated). Goal: keep tickets moving. Steps: run ticket hygiene; inspect board; pull next actionable work into in-progress; assign owners; write updates to tickets (## Comments) and notes/status.md. If lowest-numbered in-progress is hard-blocked, advance the next unblocked ticket (or pull from backlog)."
14
- enabledByDefault: false
10
+ schedule: "*/30 7-23 * * 1-5"
11
+ timezone: "America/New_York"
12
+ message: "Automated lead triage loop: triage inbox/tickets, assign work, and update notes/status.md. Anti-stuck: if lowest in-progress is HARD BLOCKED, advance the next unblocked ticket (or pull from backlog). If in-progress is stale (>12h no dated update), comment or move it back."
13
+ enabledByDefault: true
15
14
  - id: execution-loop
16
15
  name: "Execution loop"
17
- schedule: "*/30 8-23 * * 1-5"
18
- agentId: "{{teamId}}-lead"
19
- channel: "last"
20
- message: "Execution loop (automated). Goal: make concrete progress on the lowest-numbered in-progress ticket. Run ticket hygiene; perform repo lint/build checks (avoid noisy tests unless defined); update ticket + notes/status.md. Send a message only when there is a material change."
21
- enabledByDefault: false
22
- - id: pr-watcher
23
- name: "PR watcher"
24
- schedule: "*/30 8-23 * * 1-5"
25
- agentId: "{{teamId}}-lead"
26
- channel: "last"
27
- message: "PR watcher (automated). Goal: watch ticket-linked PR URLs; summarize failing checks; if merged, move tickets to done with a short completion report. Requires GitHub access/auth on the controller."
28
- enabledByDefault: false
29
-
30
- - id: testing-lane-loop
31
- name: "Testing lane loop"
32
- schedule: "*/30 0-1,7-23 * * *"
16
+ schedule: "*/30 7-23 * * 1-5"
33
17
  timezone: "America/New_York"
34
- agentId: "{{teamId}}-test"
35
- channel: "last"
36
- message: "Testing lane loop (automated). Goal: drain work/testing reliably. For each ticket in work/testing: follow the ticket's '## Verification steps'; record results under ## Comments; if it passes, complete the ticket; if it fails, write a clear repro + fix request and hand back to dev; if blocked on an unmerged PR/deploy, note and skip. Also keep notes/status.md current (3–5 bullets)."
18
+ message: "Automated execution loop: make progress on in-progress tickets, keep changes small/safe, and update notes/status.md."
37
19
  enabledByDefault: false
20
+ # pr-watcher omitted (enable only when a real PR integration exists)
38
21
  requiredSkills: []
39
22
  team:
40
23
  teamId: development-team
@@ -81,7 +64,6 @@ templates:
81
64
 
82
65
  Team: {{teamId}}
83
66
  Shared workspace: {{teamDir}}
84
- Role: lead
85
67
 
86
68
  ## Guardrails (read → act → write)
87
69
 
@@ -90,26 +72,24 @@ templates:
90
72
  - `notes/plan.md`
91
73
  - `notes/status.md`
92
74
  - `shared-context/priorities.md`
93
- - the current ticket
94
-
95
- During work (every loop):
96
- 1) Run hygiene:
97
- - `./scripts/ticket-hygiene.sh`
75
+ - the relevant ticket(s)
98
76
 
99
77
  After you act:
100
78
  1) Write back:
101
- - Update the ticket with decisions/assignments and a dated entry under `## Comments`.
102
- - Keep `notes/status.md` current (add 3–5 bullets per active ticket).
103
- - Append detailed logs/output to `shared-context/agent-outputs/` (append-only).
79
+ - Update tickets with decisions/assignments.
80
+ - Keep `notes/status.md` current (3–5 bullets per active ticket).
104
81
 
105
82
  ## Curator model
106
83
 
107
- You curate:
84
+ You are the curator of:
108
85
  - `notes/plan.md`
109
86
  - `shared-context/priorities.md`
110
87
 
111
- Other agents should not edit curated files; they append to:
88
+ Everyone else should append to:
112
89
  - `shared-context/agent-outputs/` (append-only)
90
+ - `shared-context/feedback/`
91
+
92
+ Your job is to periodically distill those inputs into the curated files.
113
93
 
114
94
  ## File-first workflow (tickets)
115
95
 
@@ -121,9 +101,29 @@ templates:
121
101
  - `work/in-progress/` — tickets currently being executed
122
102
  - `work/testing/` — tickets awaiting QA verification
123
103
  - `work/done/` — completed tickets + completion notes
124
-
125
- Handoff to QA (keeps assignment stubs consistent):
126
- - `openclaw recipes handoff --team-id {{teamId}} --ticket <NNNN> --yes`
104
+ - `notes/plan.md` — current plan / priorities (curated)
105
+ - `notes/status.md` current status snapshot
106
+ - `shared-context/` shared context + append-only outputs
107
+
108
+ ### Ticket numbering (critical)
109
+ - Backlog tickets MUST be named `0001-...md`, `0002-...md`, etc.
110
+ - The developer pulls the lowest-numbered ticket assigned to them.
111
+
112
+ ### Ticket format
113
+ See `TICKETS.md` in the team root. Every ticket should include:
114
+ - Context
115
+ - Requirements
116
+ - Acceptance criteria
117
+ - Owner (dev/devops)
118
+ - Status
119
+
120
+ ### Your responsibilities
121
+ - For every new request in `inbox/`, create a normalized ticket in `work/backlog/`.
122
+ - Curate `notes/plan.md` and `shared-context/priorities.md`.
123
+ - Keep `notes/status.md` updated.
124
+ - When work is ready for QA, move the ticket to `work/testing/` and assign it to the tester.
125
+ - Only after QA verification, move the ticket to `work/done/` (or use `openclaw recipes complete`).
126
+ - When a completion appears in `work/done/`, write a short summary into `outbox/`.
127
127
 
128
128
  dev.soul: |
129
129
  # SOUL.md
@@ -134,32 +134,48 @@ templates:
134
134
  dev.agents: |
135
135
  # AGENTS.md
136
136
 
137
- Team: {{teamId}}
138
137
  Shared workspace: {{teamDir}}
139
- Role: dev
140
138
 
141
139
  ## Guardrails (read → act → write)
142
140
 
143
- Before you change anything, read:
144
- - `notes/plan.md`
145
- - `notes/status.md`
146
- - `shared-context/priorities.md`
147
- - the current ticket
141
+ Before you change anything:
142
+ 1) Read:
143
+ - `notes/plan.md`
144
+ - `notes/status.md`
145
+ - `shared-context/priorities.md`
146
+ - the current ticket you’re working on
147
+
148
+ While working:
149
+ - Keep changes small and safe.
150
+ - Prefer file-first coordination over chat.
151
+
152
+ After you finish a work session (even if not done):
153
+ 1) Write back:
154
+ - Update the ticket with what you did and what’s next.
155
+ - Add **3–5 bullets** to `notes/status.md` (what changed / what’s blocked).
156
+ - Append detailed output to `shared-context/agent-outputs/` (append-only).
157
+
158
+ Curator model:
159
+ - Lead curates `notes/plan.md` and `shared-context/priorities.md`.
160
+ - You should NOT edit curated files; propose changes via `agent-outputs/`.
161
+
162
+ ## How you work (pull system)
163
+
164
+ 1) Look in `work/in-progress/` for any ticket already assigned to you.
165
+ - If present: continue it.
148
166
 
149
- Quick hygiene around stage moves:
150
- - `./scripts/ticket-hygiene-dev.sh`
167
+ 2) Otherwise, pick the next ticket from `work/backlog/`:
168
+ - Choose the lowest-numbered `0001-...md` ticket assigned to `dev`.
151
169
 
152
- After you act, write back:
153
- - Update the ticket with what you did + verification steps.
154
- - Check/respond in the ticket’s `## Comments` section (especially if you were pinged).
155
- - Add 3–5 bullets to `notes/status.md`.
156
- - Append detailed logs/output to `shared-context/agent-outputs/` (append-only).
170
+ 3) Move the ticket file from `work/backlog/` → `work/in-progress/`.
157
171
 
158
- ## Pull system
172
+ 4) Do the work.
173
+
174
+ 5) Write a completion report into `work/done/` with:
175
+ - What changed
176
+ - How to test
177
+ - Any follow-ups
159
178
 
160
- - Continue any ticket already assigned to you in `work/in-progress/`.
161
- - Otherwise pull the lowest-numbered assigned ticket from `work/backlog/` and move it to `work/in-progress/`.
162
- - Keep changes small and reversible.
163
179
  devops.soul: |
164
180
  # SOUL.md
165
181
 
@@ -169,26 +185,44 @@ templates:
169
185
  devops.agents: |
170
186
  # AGENTS.md
171
187
 
172
- Team: {teamId}
173
- Shared workspace: {teamDir}
174
- Role: devops
188
+ Shared workspace: {{teamDir}}
175
189
 
176
190
  ## Guardrails (read → act → write)
177
- Before you act:
191
+
192
+ Before you change anything:
178
193
  1) Read:
179
194
  - `notes/plan.md`
180
195
  - `notes/status.md`
181
- - relevant ticket(s) in `work/in-progress/`
182
- - any relevant shared context under `shared-context/`
196
+ - `shared-context/priorities.md`
197
+ - the current ticket you’re working on
183
198
 
184
- After you act:
199
+ After you finish a work session:
185
200
  1) Write back:
186
- - Put outputs in the agreed folder (usually `outbox/` or a ticket file).
187
- - Update the ticket with what you did and where the artifact is.
201
+ - Update the ticket with what you did + verification steps.
202
+ - Add **3–5 bullets** to `notes/status.md`.
203
+ - Append detailed output/logs to `shared-context/agent-outputs/` (append-only).
204
+
205
+ Curator model:
206
+ - Lead curates `notes/plan.md` and `shared-context/priorities.md`.
207
+ - You should NOT edit curated files; propose changes via `agent-outputs/`.
208
+
209
+ ## How you work (pull system)
210
+
211
+ 1) Look in `work/in-progress/` for any ticket already assigned to you.
212
+ - If present: continue it.
213
+
214
+ 2) Otherwise, pick the next ticket from `work/backlog/`:
215
+ - Choose the lowest-numbered `0001-...md` ticket assigned to `devops`.
216
+
217
+ 3) Move the ticket file from `work/backlog/` → `work/in-progress/`.
218
+
219
+ 4) Do the work.
220
+
221
+ 5) Write a completion report into `work/done/` with:
222
+ - What changed
223
+ - How to verify
224
+ - Rollback notes (if applicable)
188
225
 
189
- ## Workflow
190
- - Prefer a pull model: wait for a clear task from the lead, or propose a scoped task.
191
- - Keep work small and reversible.
192
226
  lead.tools: |
193
227
  # TOOLS.md
194
228
 
@@ -247,30 +281,68 @@ templates:
247
281
  test.agents: |
248
282
  # AGENTS.md
249
283
 
250
- Team: {{teamId}}
251
284
  Shared workspace: {{teamDir}}
252
- Role: test
253
285
 
254
286
  ## Guardrails (read → act → write)
255
287
 
256
- Before you verify anything, read:
257
- - `notes/plan.md`
258
- - `notes/status.md`
259
- - `shared-context/priorities.md`
260
- - the ticket in `work/testing/`
288
+ Before verifying:
289
+ 1) Read:
290
+ - `notes/plan.md`
291
+ - `notes/status.md`
292
+ - `shared-context/priorities.md`
293
+ - the ticket under test
261
294
 
262
- After you verify, write back:
263
- - Record QA verification (preferred): create `work/testing/<ticket>.testing-verified.md`.
264
- - Alternative: add a clear `## QA verification` section in the ticket.
265
- - If failing: write a concise bug note, then move the ticket back to `work/in-progress/` and assign to the right owner.
266
- - Check/respond in the ticket’s `## Comments` section.
267
- - Add 3–5 bullets to `notes/status.md`.
268
- - Append detailed logs/output to `shared-context/agent-outputs/` (append-only).
295
+ After each verification pass:
296
+ 1) Write back:
297
+ - Add a short verification note to the ticket (pass/fail + evidence).
298
+ - Add **3–5 bullets** to `notes/status.md` (what’s verified / what’s blocked).
299
+ - Append detailed findings to `shared-context/feedback/` or `shared-context/agent-outputs/`.
269
300
 
270
- ## Testing lane workflow
301
+ Curator model:
302
+ - Lead curates `notes/plan.md` and `shared-context/priorities.md`.
303
+ - You should NOT edit curated files; propose changes via feedback/outputs.
304
+
305
+ ## How you work
306
+
307
+ 1) Look in `work/testing/` for tickets assigned to you.
308
+
309
+ 2) For each ticket:
310
+ - Follow the ticket's "How to test" steps (if present)
311
+ - Validate acceptance criteria
312
+ - Write a short verification note (or failures) into the ticket itself or a sibling note.
313
+
314
+ 3) If it passes:
315
+ - Move the ticket to `work/done/` (or ask the lead to do it).
316
+
317
+ 4) If it fails:
318
+ - Move the ticket back to `work/in-progress/` and assign to the right owner.
319
+
320
+ ## Cleanup after testing
321
+
322
+ If your test involved creating temporary resources (e.g., scaffolding test teams, creating test workspaces), **clean them up** after verification:
323
+
324
+ 1) Remove test workspaces:
325
+ ```bash
326
+ rm -rf ~/.openclaw/workspace-<test-team-id>
327
+ ```
328
+
329
+ 2) Remove test agents from config (agents whose id starts with the test team id):
330
+ - Edit `~/.openclaw/openclaw.json` and remove entries from `agents.list[]`
331
+ - Or wait for `openclaw recipes remove-team` (once available)
332
+
333
+ 3) Remove any cron jobs created for the test team:
334
+ ```bash
335
+ openclaw cron list --all --json | grep "<test-team-id>"
336
+ openclaw cron remove <jobId>
337
+ ```
338
+
339
+ 4) Restart the gateway if you modified config:
340
+ ```bash
341
+ openclaw gateway restart
342
+ ```
343
+
344
+ **Naming convention:** When scaffolding test teams, use a prefix like `qa-<ticketNum>-` (e.g., `qa-0017-social-team`) so cleanup is easier.
271
345
 
272
- - Work from `work/testing/`.
273
- - Follow the ticket’s “How to test” steps and validate acceptance criteria.
274
346
  test.tools: |
275
347
  # TOOLS.md
276
348
 
@@ -328,4 +400,3 @@ Scaffolds a shared team workspace and four namespaced agents (lead/dev/devops/te
328
400
  - allow groups: group:automation, group:fs, group:runtime, group:web
329
401
  - deny: (none)
330
402
  - Safety note: most bundled teams default to denying `exec` unless a role explicitly needs it.
331
-
@@ -2,292 +2,334 @@
2
2
  id: stock-trader-team
3
3
  name: Stock Trader Team
4
4
  version: 0.1.0
5
- description: A trading support team (research, signals, risk, journaling, ops) coordinated via a shared workspace.
5
+ description: A trading support team (research, signals, risk, journaling, ops) coordinated
6
+ via a shared workspace.
6
7
  kind: team
7
8
  cronJobs:
8
- - id: lead-triage-loop
9
- name: "Lead triage loop"
10
- schedule: "*/30 7-23 * * 1-5"
11
- timezone: "America/New_York"
12
- message: "Automated lead triage loop (Stock Trader): triage research/tickets, assign work, and update notes/status.md."
13
- enabledByDefault: false
14
- - id: execution-loop
15
- name: "Execution loop"
16
- schedule: "*/30 7-23 * * 1-5"
17
- timezone: "America/New_York"
18
- message: "Automated execution loop (Stock Trader): make progress on in-progress tickets and update notes/status.md."
19
- enabledByDefault: false
9
+ - id: lead-triage-loop
10
+ name: Lead triage loop
11
+ schedule: '*/30 7-23 * * 1-5'
12
+ timezone: America/New_York
13
+ message: 'Automated lead triage loop (Stock Trader): triage research/tickets, assign
14
+ work, and update notes/status.md.'
15
+ enabledByDefault: false
16
+ - id: execution-loop
17
+ name: Execution loop
18
+ schedule: '*/30 7-23 * * 1-5'
19
+ timezone: America/New_York
20
+ message: 'Automated execution loop (Stock Trader): make progress on in-progress
21
+ tickets and update notes/status.md.'
22
+ enabledByDefault: false
20
23
  requiredSkills: []
21
24
  team:
22
25
  teamId: stock-trader-team
23
26
  agents:
24
- - role: lead
25
- name: Head Trader / Lead
26
- tools:
27
- profile: "coding"
28
- allow: ["group:fs", "group:web", "group:runtime"]
29
- deny: ["exec"]
30
- - role: researcher
31
- name: Market Researcher
32
- tools:
33
- profile: "coding"
34
- allow: ["group:fs", "group:web"]
35
- deny: ["exec"]
36
- - role: signals
37
- name: Signals & Watchlists
38
- tools:
39
- profile: "coding"
40
- allow: ["group:fs", "group:web"]
41
- deny: ["exec"]
42
- - role: risk
43
- name: Risk Manager
44
- tools:
45
- profile: "coding"
46
- allow: ["group:fs", "group:web"]
47
- deny: ["exec"]
48
- - role: journal
49
- name: Trade Journaler
50
- tools:
51
- profile: "coding"
52
- allow: ["group:fs"]
53
- deny: ["exec"]
54
- - role: ops
55
- name: Trading Ops
56
- tools:
57
- profile: "coding"
58
- allow: ["group:fs", "group:web"]
59
- deny: ["exec"]
60
-
27
+ - role: lead
28
+ name: Head Trader / Lead
29
+ tools:
30
+ profile: coding
31
+ allow:
32
+ - group:fs
33
+ - group:web
34
+ - group:runtime
35
+ deny:
36
+ - exec
37
+ - role: researcher
38
+ name: Market Researcher
39
+ tools:
40
+ profile: coding
41
+ allow:
42
+ - group:fs
43
+ - group:web
44
+ deny:
45
+ - exec
46
+ - role: signals
47
+ name: Signals & Watchlists
48
+ tools:
49
+ profile: coding
50
+ allow:
51
+ - group:fs
52
+ - group:web
53
+ deny:
54
+ - exec
55
+ - role: risk
56
+ name: Risk Manager
57
+ tools:
58
+ profile: coding
59
+ allow:
60
+ - group:fs
61
+ - group:web
62
+ deny:
63
+ - exec
64
+ - role: journal
65
+ name: Trade Journaler
66
+ tools:
67
+ profile: coding
68
+ allow:
69
+ - group:fs
70
+ deny:
71
+ - exec
72
+ - role: ops
73
+ name: Trading Ops
74
+ tools:
75
+ profile: coding
76
+ allow:
77
+ - group:fs
78
+ - group:web
79
+ deny:
80
+ - exec
61
81
  templates:
62
- lead.soul: |
63
- # SOUL.md
82
+ lead.soul: '# SOUL.md
83
+
84
+
85
+ You are the Team Lead / Dispatcher for {{{teamId}}}.
64
86
 
65
- You are the Team Lead / Dispatcher for {{teamId}}.
66
87
 
67
88
  Core job:
89
+
68
90
  - Convert new requests into scoped tickets.
91
+
69
92
  - Assign work to Dev or DevOps.
93
+
70
94
  - Monitor progress and unblock.
95
+
71
96
  - Report completions.
72
- lead.agents: |
73
- # AGENTS.md
74
-
75
- Team: {{teamId}}
76
- Shared workspace: {{teamDir}}
77
-
78
- ## Guardrails (read → act → write)
79
-
80
- Before you act:
81
- 1) Read:
82
- - `notes/plan.md`
83
- - `notes/status.md`
84
- - `shared-context/priorities.md`
85
- - the relevant ticket(s)
86
-
87
- After you act:
88
- 1) Write back:
89
- - Update tickets with decisions/assignments.
90
- - Keep `notes/status.md` current (3–5 bullets per active ticket).
91
-
92
- ## Curator model
93
-
94
- You are the curator of:
95
- - `notes/plan.md`
96
- - `shared-context/priorities.md`
97
-
98
- Everyone else should append to:
99
- - `shared-context/agent-outputs/` (append-only)
100
- - `shared-context/feedback/`
101
-
102
- Your job is to periodically distill those inputs into the curated files.
103
-
104
- ## File-first workflow (tickets)
105
-
106
- Source of truth is the shared team workspace.
107
-
108
- Folders:
109
- - `inbox/` — raw incoming requests (append-only)
110
- - `work/backlog/` — normalized tickets, filename-ordered (`0001-...md`)
111
- - `work/in-progress/` — tickets currently being executed
112
- - `work/testing/` — tickets awaiting QA verification
113
- - `work/done/` — completed tickets + completion notes
114
- - `notes/plan.md` — current plan / priorities (curated)
115
- - `notes/status.md` — current status snapshot
116
- - `shared-context/` — shared context + append-only outputs
117
-
118
- ### Ticket numbering (critical)
119
- - Backlog tickets MUST be named `0001-...md`, `0002-...md`, etc.
120
- - The developer pulls the lowest-numbered ticket assigned to them.
121
-
122
- ### Ticket format
123
- See `TICKETS.md` in the team root. Every ticket should include:
124
- - Context
125
- - Requirements
126
- - Acceptance criteria
127
- - Owner (dev/devops)
128
- - Status
129
-
130
- ### Your responsibilities
131
- - For every new request in `inbox/`, create a normalized ticket in `work/backlog/`.
132
- - Curate `notes/plan.md` and `shared-context/priorities.md`.
133
- - Keep `notes/status.md` updated.
134
- - When work is ready for QA, move the ticket to `work/testing/` and assign it to the tester.
135
- - Only after QA verification, move the ticket to `work/done/` (or use `openclaw recipes complete`).
136
- - When a completion appears in `work/done/`, write a short summary into `outbox/`.
137
- researcher.soul: |
138
- # SOUL.md
139
-
140
- You are the Market Researcher on {{teamId}}.
141
97
 
142
- You track macro/sector themes and summarize what matters.
98
+ '
99
+ lead.agents: "# AGENTS.md\n\nTeam: {{{teamId}}}\nShared workspace: {{{teamDir}}}\n\
100
+ \n## Guardrails (read \u2192 act \u2192 write)\n\nBefore you act:\n1) Read:\n\
101
+ \ - `notes/plan.md`\n - `notes/status.md`\n - `shared-context/priorities.md`\n\
102
+ \ - the relevant ticket(s)\n\nAfter you act:\n1) Write back:\n - Update tickets\
103
+ \ with decisions/assignments.\n - Keep `notes/status.md` current (3\u20135 bullets\
104
+ \ per active ticket).\n\n## Curator model\n\nYou are the curator of:\n- `notes/plan.md`\n\
105
+ - `shared-context/priorities.md`\n\nEveryone else should append to:\n- `shared-context/agent-outputs/`\
106
+ \ (append-only)\n- `shared-context/feedback/`\n\nYour job is to periodically distill\
107
+ \ those inputs into the curated files.\n\n## File-first workflow (tickets)\n\n\
108
+ Source of truth is the shared team workspace.\n\nFolders:\n- `inbox/` \u2014 raw\
109
+ \ incoming requests (append-only)\n- `work/backlog/` \u2014 normalized tickets,\
110
+ \ filename-ordered (`0001-...md`)\n- `work/in-progress/` \u2014 tickets currently\
111
+ \ being executed\n- `work/testing/` \u2014 tickets awaiting QA verification\n\
112
+ - `work/done/` \u2014 completed tickets + completion notes\n- `notes/plan.md`\
113
+ \ \u2014 current plan / priorities (curated)\n- `notes/status.md` \u2014 current\
114
+ \ status snapshot\n- `shared-context/` \u2014 shared context + append-only outputs\n\
115
+ \n### Ticket numbering (critical)\n- Backlog tickets MUST be named `0001-...md`,\
116
+ \ `0002-...md`, etc.\n- The developer pulls the lowest-numbered ticket assigned\
117
+ \ to them.\n\n### Ticket format\nSee `TICKETS.md` in the team root. Every ticket\
118
+ \ should include:\n- Context\n- Requirements\n- Acceptance criteria\n- Owner (dev/devops)\n\
119
+ - Status\n\n### Your responsibilities\n- For every new request in `inbox/`, create\
120
+ \ a normalized ticket in `work/backlog/`.\n- Curate `notes/plan.md` and `shared-context/priorities.md`.\n\
121
+ - Keep `notes/status.md` updated.\n- When work is ready for QA, move the ticket\
122
+ \ to `work/testing/` and assign it to the tester.\n- Only after QA verification,\
123
+ \ move the ticket to `work/done/` (or use `openclaw recipes complete`).\n- When\
124
+ \ a completion appears in `work/done/`, write a short summary into `outbox/`.\n"
125
+ researcher.soul: '# SOUL.md
126
+
127
+
128
+ You are the Market Researcher on {{{teamId}}}.
143
129
 
144
- researcher.agents: |
145
- # AGENTS.md
146
130
 
147
- Team: {teamId}
148
- Shared workspace: {teamDir}
149
- Role: researcher
131
+ You track macro/sector themes and summarize what matters.
150
132
 
151
- ## Guardrails (read → act → write)
152
- Before you act:
153
- 1) Read:
154
- - `notes/plan.md`
155
- - `notes/status.md`
156
- - relevant ticket(s) in `work/in-progress/`
157
- - any relevant shared context under `shared-context/`
133
+ '
134
+ researcher.agents: "# AGENTS.md\n\nTeam: {{teamId}}\nShared workspace: {{teamDir}}\n\
135
+ Role: researcher\n\n## Guardrails (read \u2192 act \u2192 write)\nBefore you act:\n\
136
+ 1) Read:\n - `notes/plan.md`\n - `notes/status.md`\n - relevant ticket(s)\
137
+ \ in `work/in-progress/`\n - any relevant shared context under `shared-context/`\n\
138
+ \nAfter you act:\n1) Write back:\n - Put outputs in the agreed folder (usually\
139
+ \ `outbox/` or a ticket file).\n - Update the ticket with what you did and where\
140
+ \ the artifact is.\n\n## Workflow\n- Prefer a pull model: wait for a clear task\
141
+ \ from the lead, or propose a scoped task.\n- Keep work small and reversible.\n"
142
+ signals.soul: '# SOUL.md
158
143
 
159
- After you act:
160
- 1) Write back:
161
- - Put outputs in the agreed folder (usually `outbox/` or a ticket file).
162
- - Update the ticket with what you did and where the artifact is.
163
144
 
164
- ## Workflow
165
- - Prefer a pull model: wait for a clear task from the lead, or propose a scoped task.
166
- - Keep work small and reversible.
167
- signals.soul: |
168
- # SOUL.md
145
+ You maintain signals, screeners, and watchlists for {{{teamId}}}.
169
146
 
170
- You maintain signals, screeners, and watchlists for {{teamId}}.
171
147
 
172
148
  You produce concise entries: ticker, setup, catalyst, invalidation.
173
149
 
174
- signals.agents: |
175
- # AGENTS.md
150
+ '
151
+ signals.agents: "# AGENTS.md\n\nTeam: {{teamId}}\nShared workspace: {{teamDir}}\n\
152
+ Role: signals\n\n## Guardrails (read \u2192 act \u2192 write)\nBefore you act:\n\
153
+ 1) Read:\n - `notes/plan.md`\n - `notes/status.md`\n - relevant ticket(s)\
154
+ \ in `work/in-progress/`\n - any relevant shared context under `shared-context/`\n\
155
+ \nAfter you act:\n1) Write back:\n - Put outputs in the agreed folder (usually\
156
+ \ `outbox/` or a ticket file).\n - Update the ticket with what you did and where\
157
+ \ the artifact is.\n\n## Workflow\n- Prefer a pull model: wait for a clear task\
158
+ \ from the lead, or propose a scoped task.\n- Keep work small and reversible.\n"
159
+ risk.soul: '# SOUL.md
176
160
 
177
- Team: {teamId}
178
- Shared workspace: {teamDir}
179
- Role: signals
180
161
 
181
- ## Guardrails (read act write)
182
- Before you act:
183
- 1) Read:
184
- - `notes/plan.md`
185
- - `notes/status.md`
186
- - relevant ticket(s) in `work/in-progress/`
187
- - any relevant shared context under `shared-context/`
162
+ You are the Risk Manager on {{{teamId}}}.
188
163
 
189
- After you act:
190
- 1) Write back:
191
- - Put outputs in the agreed folder (usually `outbox/` or a ticket file).
192
- - Update the ticket with what you did and where the artifact is.
193
164
 
194
- ## Workflow
195
- - Prefer a pull model: wait for a clear task from the lead, or propose a scoped task.
196
- - Keep work small and reversible.
197
- risk.soul: |
198
- # SOUL.md
165
+ You enforce position sizing, stop rules, and drawdown controls.
199
166
 
200
- You are the Risk Manager on {{teamId}}.
167
+ '
168
+ risk.agents: "# AGENTS.md\n\nTeam: {{teamId}}\nShared workspace: {{teamDir}}\nRole:\
169
+ \ risk\n\n## Guardrails (read \u2192 act \u2192 write)\nBefore you act:\n1) Read:\n\
170
+ \ - `notes/plan.md`\n - `notes/status.md`\n - relevant ticket(s) in `work/in-progress/`\n\
171
+ \ - any relevant shared context under `shared-context/`\n\nAfter you act:\n\
172
+ 1) Write back:\n - Put outputs in the agreed folder (usually `outbox/` or a\
173
+ \ ticket file).\n - Update the ticket with what you did and where the artifact\
174
+ \ is.\n\n## Workflow\n- Prefer a pull model: wait for a clear task from the lead,\
175
+ \ or propose a scoped task.\n- Keep work small and reversible.\n"
176
+ journal.soul: '# SOUL.md
201
177
 
202
- You enforce position sizing, stop rules, and drawdown controls.
203
178
 
204
- risk.agents: |
205
- # AGENTS.md
179
+ You are the Trade Journaler on {{{teamId}}}.
206
180
 
207
- Team: {teamId}
208
- Shared workspace: {teamDir}
209
- Role: risk
210
181
 
211
- ## Guardrails (read act write)
212
- Before you act:
213
- 1) Read:
214
- - `notes/plan.md`
215
- - `notes/status.md`
216
- - relevant ticket(s) in `work/in-progress/`
217
- - any relevant shared context under `shared-context/`
182
+ You keep a clean daily log and capture lessons learned.
218
183
 
219
- After you act:
220
- 1) Write back:
221
- - Put outputs in the agreed folder (usually `outbox/` or a ticket file).
222
- - Update the ticket with what you did and where the artifact is.
184
+ '
185
+ journal.agents: "# AGENTS.md\n\nTeam: {{teamId}}\nShared workspace: {{teamDir}}\n\
186
+ Role: journal\n\n## Guardrails (read \u2192 act \u2192 write)\nBefore you act:\n\
187
+ 1) Read:\n - `notes/plan.md`\n - `notes/status.md`\n - relevant ticket(s)\
188
+ \ in `work/in-progress/`\n - any relevant shared context under `shared-context/`\n\
189
+ \nAfter you act:\n1) Write back:\n - Put outputs in the agreed folder (usually\
190
+ \ `outbox/` or a ticket file).\n - Update the ticket with what you did and where\
191
+ \ the artifact is.\n\n## Workflow\n- Prefer a pull model: wait for a clear task\
192
+ \ from the lead, or propose a scoped task.\n- Keep work small and reversible.\n"
193
+ ops.soul: '# SOUL.md
223
194
 
224
- ## Workflow
225
- - Prefer a pull model: wait for a clear task from the lead, or propose a scoped task.
226
- - Keep work small and reversible.
227
- journal.soul: |
228
- # SOUL.md
229
195
 
230
- You are the Trade Journaler on {{teamId}}.
196
+ You run trading ops for {{{teamId}}}.
231
197
 
232
- You keep a clean daily log and capture lessons learned.
233
198
 
234
- journal.agents: |
235
- # AGENTS.md
199
+ You keep calendars, checklists, and tooling notes tidy.
236
200
 
237
- Team: {teamId}
238
- Shared workspace: {teamDir}
239
- Role: journal
201
+ '
202
+ ops.agents: "# AGENTS.md\n\nOutput:\n- Calendar/cadence checklists \u2192 work/playbook/cadence.md\n\
203
+ - Tooling notes \u2192 shared-context/tooling/\n"
204
+ lead.tools: '# TOOLS.md
240
205
 
241
- ## Guardrails (read → act → write)
242
- Before you act:
243
- 1) Read:
244
- - `notes/plan.md`
245
- - `notes/status.md`
246
- - relevant ticket(s) in `work/in-progress/`
247
- - any relevant shared context under `shared-context/`
248
206
 
249
- After you act:
250
- 1) Write back:
251
- - Put outputs in the agreed folder (usually `outbox/` or a ticket file).
252
- - Update the ticket with what you did and where the artifact is.
207
+ # Agent-local notes for lead (paths, conventions, env quirks).
253
208
 
254
- ## Workflow
255
- - Prefer a pull model: wait for a clear task from the lead, or propose a scoped task.
256
- - Keep work small and reversible.
257
- ops.soul: |
258
- # SOUL.md
209
+ '
210
+ lead.status: '# STATUS.md
259
211
 
260
- You run trading ops for {{teamId}}.
261
212
 
262
- You keep calendars, checklists, and tooling notes tidy.
213
+ - (empty)
263
214
 
264
- ops.agents: |
265
- # AGENTS.md
215
+ '
216
+ lead.notes: '# NOTES.md
266
217
 
267
- Output:
268
- - Calendar/cadence checklists → work/playbook/cadence.md
269
- - Tooling notes → shared-context/tooling/
270
218
 
271
- files:
272
- - path: SOUL.md
273
- template: soul
274
- mode: createOnly
275
- - path: AGENTS.md
276
- template: agents
277
- mode: createOnly
278
- - path: TOOLS.md
279
- template: tools
280
- mode: createOnly
281
- - path: STATUS.md
282
- template: status
283
- mode: createOnly
284
- - path: NOTES.md
285
- template: notes
286
- mode: createOnly
219
+ - (empty)
220
+
221
+ '
222
+ researcher.tools: '# TOOLS.md
223
+
224
+
225
+ # Agent-local notes for researcher (paths, conventions, env quirks).
226
+
227
+ '
228
+ researcher.status: '# STATUS.md
229
+
230
+
231
+ - (empty)
232
+
233
+ '
234
+ researcher.notes: '# NOTES.md
235
+
236
+
237
+ - (empty)
238
+
239
+ '
240
+ signals.tools: '# TOOLS.md
241
+
242
+
243
+ # Agent-local notes for signals (paths, conventions, env quirks).
244
+
245
+ '
246
+ signals.status: '# STATUS.md
247
+
248
+
249
+ - (empty)
287
250
 
251
+ '
252
+ signals.notes: '# NOTES.md
253
+
254
+
255
+ - (empty)
256
+
257
+ '
258
+ risk.tools: '# TOOLS.md
259
+
260
+
261
+ # Agent-local notes for risk (paths, conventions, env quirks).
262
+
263
+ '
264
+ risk.status: '# STATUS.md
265
+
266
+
267
+ - (empty)
268
+
269
+ '
270
+ risk.notes: '# NOTES.md
271
+
272
+
273
+ - (empty)
274
+
275
+ '
276
+ journal.tools: '# TOOLS.md
277
+
278
+
279
+ # Agent-local notes for journal (paths, conventions, env quirks).
280
+
281
+ '
282
+ journal.status: '# STATUS.md
283
+
284
+
285
+ - (empty)
286
+
287
+ '
288
+ journal.notes: '# NOTES.md
289
+
290
+
291
+ - (empty)
292
+
293
+ '
294
+ ops.tools: '# TOOLS.md
295
+
296
+
297
+ # Agent-local notes for ops (paths, conventions, env quirks).
298
+
299
+ '
300
+ ops.status: '# STATUS.md
301
+
302
+
303
+ - (empty)
304
+
305
+ '
306
+ ops.notes: '# NOTES.md
307
+
308
+
309
+ - (empty)
310
+
311
+ '
312
+ files:
313
+ - path: SOUL.md
314
+ template: soul
315
+ mode: createOnly
316
+ - path: AGENTS.md
317
+ template: agents
318
+ mode: createOnly
319
+ - path: TOOLS.md
320
+ template: tools
321
+ mode: createOnly
322
+ - path: STATUS.md
323
+ template: status
324
+ mode: createOnly
325
+ - path: NOTES.md
326
+ template: notes
327
+ mode: createOnly
288
328
  tools:
289
- profile: "messaging"
290
- allow: ["group:fs", "group:web"]
329
+ profile: messaging
330
+ allow:
331
+ - group:fs
332
+ - group:web
291
333
  deny: []
292
334
  ---
293
335
 
@@ -308,4 +350,3 @@ Bundled team recipe.
308
350
  - deny: exec
309
351
  - Safety note: most bundled teams default to denying `exec` unless a role explicitly needs it.
310
352
 
311
-
@@ -39,15 +39,16 @@ async function ensureTeamDirectoryStructure(
39
39
  ]);
40
40
  }
41
41
 
42
- async function writeTeamBootstrapFiles(
43
- teamId: string,
44
- teamDir: string,
45
- sharedContextDir: string,
46
- notesDir: string,
47
- goalsDir: string,
48
- overwrite: boolean,
49
- opts?: { qaChecklist?: boolean }
50
- ) {
42
+ async function writeTeamBootstrapFiles(opts: {
43
+ teamId: string;
44
+ teamDir: string;
45
+ sharedContextDir: string;
46
+ notesDir: string;
47
+ goalsDir: string;
48
+ overwrite: boolean;
49
+ qaChecklist?: boolean;
50
+ }) {
51
+ const { teamId, teamDir, sharedContextDir, notesDir, goalsDir, overwrite, qaChecklist } = opts;
51
52
  const mode = overwrite ? "overwrite" : "createOnly";
52
53
  await ensureDir(goalsDir);
53
54
  await writeFileSafely(
@@ -68,7 +69,7 @@ async function writeTeamBootstrapFiles(
68
69
  mode
69
70
  );
70
71
 
71
- if (opts?.qaChecklist) {
72
+ if (qaChecklist) {
72
73
  await writeFileSafely(
73
74
  path.join(notesDir, "QA_CHECKLIST.md"),
74
75
  `# QA Checklist — ${teamId}\n\nUse this when verifying a ticket before moving it from work/testing/ → work/done/.\n\n## Checklist\n- [ ] Repro steps verified\n- [ ] Acceptance criteria met\n- [ ] No regressions in adjacent flows\n- [ ] Notes/screenshots attached (if relevant)\n\n## Verified by\n- QA: (name)\n- Date: (YYYY-MM-DD)\n\n## Links\n- Ticket: (path or URL)\n- PR/Commit: (optional)\n`,
@@ -184,7 +185,6 @@ export async function handleScaffoldTeam(
184
185
  await ensureDir(recipesDir);
185
186
  const overwriteRecipe = !!options.overwriteRecipe;
186
187
  const autoIncrement = !!options.autoIncrement;
187
-
188
188
  const explicitRecipeId = typeof options.recipeIdExplicit === "string" ? String(options.recipeIdExplicit).trim() : "";
189
189
  const baseRecipeId = explicitRecipeId || teamId;
190
190
  const workspaceRecipeId = await pickRecipeId({
@@ -201,7 +201,6 @@ export async function handleScaffoldTeam(
201
201
  `Workspace recipe already exists: recipes/${id}.md. Choose --recipe-id (e.g. ${suggestions.join(", ")}) or --auto-increment or --overwrite-recipe.`,
202
202
  });
203
203
  await writeWorkspaceRecipeFile(loaded, recipesDir, workspaceRecipeId, overwriteRecipe);
204
-
205
204
  const rolesDir = path.join(teamDir, "roles");
206
205
  const notesDir = path.join(teamDir, "notes");
207
206
  const workDir = path.join(teamDir, "work");
@@ -209,12 +208,17 @@ export async function handleScaffoldTeam(
209
208
  const sharedContextDir = path.join(teamDir, "shared-context");
210
209
  const goalsDir = path.join(notesDir, "goals");
211
210
 
212
- const hasTestRole = (recipe.agents ?? []).some((a) => String(a.role ?? '').toLowerCase() === 'test');
213
- const qaChecklist = Boolean(recipe.qaChecklist ?? false) || hasTestRole;
214
-
211
+ const qaChecklist = Boolean(recipe.qaChecklist ?? false) || (recipe.agents ?? []).some((a) => String(a.role ?? "").toLowerCase() === "test");
215
212
  await ensureTeamDirectoryStructure(teamDir, sharedContextDir, notesDir, workDir);
216
- await writeTeamBootstrapFiles(teamId, teamDir, sharedContextDir, notesDir, goalsDir, overwrite, { qaChecklist });
217
-
213
+ await writeTeamBootstrapFiles({
214
+ teamId,
215
+ teamDir,
216
+ sharedContextDir,
217
+ notesDir,
218
+ goalsDir,
219
+ overwrite,
220
+ qaChecklist,
221
+ });
218
222
  const results = await scaffoldTeamAgents(api, recipe, teamId, teamDir, rolesDir, overwrite);
219
223
  await writeTeamMetadataAndConfig({ api, teamId, teamDir, recipe, results, applyConfig: !!options.applyConfig, overwrite });
220
224
 
@@ -16,7 +16,17 @@ export function upsertAgentInConfig(cfgObj: AgentsConfigMutable, snippet: AgentC
16
16
  const list = cfgObj.agents.list;
17
17
  const idx = list.findIndex((a) => a?.id === snippet.id);
18
18
  const prev = idx >= 0 ? list[idx] : {};
19
- const prevTools = (prev as any)?.tools as undefined | { profile?: string; allow?: string[]; deny?: string[] };
19
+
20
+ const prevTools = (() => {
21
+ const v = (prev as { tools?: unknown } | null | undefined)?.tools;
22
+ if (!v || typeof v !== "object") return undefined;
23
+ const t = v as { profile?: unknown; allow?: unknown; deny?: unknown };
24
+ return {
25
+ profile: typeof t.profile === "string" ? t.profile : undefined,
26
+ allow: Array.isArray(t.allow) ? (t.allow as string[]) : undefined,
27
+ deny: Array.isArray(t.deny) ? (t.deny as string[]) : undefined,
28
+ } as { profile?: string; allow?: string[]; deny?: string[] };
29
+ })();
20
30
  const nextTools =
21
31
  snippet.tools === undefined
22
32
  ? prevTools
@@ -1,12 +1,25 @@
1
+ import os from "node:os";
1
2
  import path from "node:path";
2
3
  import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
3
4
  import { ensureDir } from "./fs-utils";
4
5
  import { ticketStageDir } from "./lanes";
5
6
 
7
+ /**
8
+ * Resolve the OpenClaw workspace root.
9
+ *
10
+ * Priority:
11
+ * 1) config: agents.defaults.workspace
12
+ * 2) env: OPENCLAW_WORKSPACE
13
+ * 3) default: ~/.openclaw/workspace
14
+ */
6
15
  export function resolveWorkspaceRoot(api: OpenClawPluginApi): string {
7
16
  const root = api.config.agents?.defaults?.workspace;
8
- if (!root) throw new Error("agents.defaults.workspace is not set in config");
9
- return root;
17
+ if (root) return root;
18
+
19
+ const envRoot = process.env.OPENCLAW_WORKSPACE;
20
+ if (envRoot) return envRoot;
21
+
22
+ return path.join(os.homedir(), ".openclaw", "workspace");
10
23
  }
11
24
 
12
25
  export function resolveTeamDir(api: OpenClawPluginApi, teamId: string): string {