@jiggai/recipes 0.3.1 → 0.3.2
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 +21 -16
- package/docs/verify-built-in-team-recipes.md +9 -0
- package/package.json +1 -1
- package/recipes/default/stock-trader-team.md +279 -238
- package/src/handlers/team.ts +21 -17
- package/src/lib/agent-config.ts +11 -1
- package/src/lib/workspace.ts +15 -2
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
|
|
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
|
|
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
|
@@ -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
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
148
|
-
Shared workspace: {teamDir}
|
|
149
|
-
Role: researcher
|
|
131
|
+
You track macro/sector themes and summarize what matters.
|
|
150
132
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
-
|
|
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
|
-
|
|
175
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
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
|
|
196
|
+
You run trading ops for {{{teamId}}}.
|
|
231
197
|
|
|
232
|
-
You keep a clean daily log and capture lessons learned.
|
|
233
198
|
|
|
234
|
-
|
|
235
|
-
# AGENTS.md
|
|
199
|
+
You keep calendars, checklists, and tooling notes tidy.
|
|
236
200
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
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
|
-
|
|
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
|
-
|
|
255
|
-
|
|
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
|
-
|
|
213
|
+
- (empty)
|
|
263
214
|
|
|
264
|
-
|
|
265
|
-
|
|
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
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
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:
|
|
290
|
-
allow:
|
|
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
|
-
|
package/src/handlers/team.ts
CHANGED
|
@@ -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
|
-
|
|
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 (
|
|
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
|
|
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(
|
|
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
|
|
package/src/lib/agent-config.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
package/src/lib/workspace.ts
CHANGED
|
@@ -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 (
|
|
9
|
-
|
|
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 {
|