@monoes/monomindcli 1.9.1 → 1.9.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/.claude/commands/mastermind/createorg.md +2 -1
- package/.claude/commands/mastermind/master.md +474 -129
- package/.claude/commands/mastermind/runorg.md +2 -1
- package/.claude/skills/mastermind/_agent-select.md +132 -0
- package/.claude/skills/mastermind/_protocol.md +59 -2
- package/.claude/skills/mastermind/build.md +15 -3
- package/.claude/skills/mastermind/content.md +13 -1
- package/.claude/skills/mastermind/createorg.md +14 -6
- package/.claude/skills/mastermind/finance.md +15 -3
- package/.claude/skills/mastermind/idea.md +557 -77
- package/.claude/skills/mastermind/marketing.md +13 -1
- package/.claude/skills/mastermind/ops.md +13 -1
- package/.claude/skills/mastermind/release.md +15 -3
- package/.claude/skills/mastermind/research.md +15 -3
- package/.claude/skills/mastermind/review.md +15 -3
- package/.claude/skills/mastermind/sales.md +15 -3
- package/dist/src/init/settings-generator.d.ts.map +1 -1
- package/dist/src/init/settings-generator.js +34 -16
- package/dist/src/init/settings-generator.js.map +1 -1
- package/dist/src/ui/server.mjs +40 -20
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -52,7 +52,7 @@ Extract from `$ARGUMENTS`:
|
|
|
52
52
|
- `--auto` → mode = auto
|
|
53
53
|
- `--confirm` → mode = confirm
|
|
54
54
|
- `--project <name>` → project_name = <name>
|
|
55
|
-
- `--iterate <N>` → iterate = N (integer ≥ 1;
|
|
55
|
+
- `--iterate <N>` → iterate = N (integer ≥ 1; when flag is absent, no iteration runs)
|
|
56
56
|
- Remaining text = prompt
|
|
57
57
|
|
|
58
58
|
### Step 2 — Brain Load
|
|
@@ -74,21 +74,26 @@ Invoke the intake logic from `_intake.md`:
|
|
|
74
74
|
- If user says "decide yourself": make explicit LLM decision, state it, log it with confidence 0.7
|
|
75
75
|
- Resolve: mode (auto/confirm), project_name, domains_needed
|
|
76
76
|
|
|
77
|
-
**After intake resolves:**
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
77
|
+
**After intake resolves:** Assign shell variables from the intake outputs (these are LLM-resolved values that must be echoed into the bash environment before the curl block runs):
|
|
78
|
+
- `resolved_prompt` = the full cleaned prompt string
|
|
79
|
+
- `mode` = `"auto"` or `"confirm"`
|
|
80
|
+
|
|
81
|
+
Then generate `SESSION_ID` and persist it so iteration cycles can retrieve it across separate Bash calls:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
85
|
+
SESSION_ID="mm-$(date -u +%Y%m%dT%H%M%S)"
|
|
86
|
+
mkdir -p "$REPO_ROOT/.monomind/sessions"
|
|
87
|
+
# Persist SESSION_ID and project context so Step 12 can restore it in a new shell
|
|
88
|
+
jq -n --arg sid "$SESSION_ID" --arg proj "$project_name" --arg prompt "$resolved_prompt" \
|
|
89
|
+
'{sessionId:$sid,project_name:$proj,prompt:$prompt}' \
|
|
90
|
+
> "$REPO_ROOT/.monomind/sessions/current.json.tmp" \
|
|
91
|
+
&& mv "$REPO_ROOT/.monomind/sessions/current.json.tmp" \
|
|
92
|
+
"$REPO_ROOT/.monomind/sessions/current.json"
|
|
93
|
+
curl -s -o /dev/null -X POST "http://localhost:4242/api/mastermind/event" \
|
|
94
|
+
-H "Content-Type: application/json" \
|
|
95
|
+
-d "$(jq -cn --arg sid "$SESSION_ID" --arg prompt "$resolved_prompt" --arg mode "$mode" --arg proj "$(pwd)" \
|
|
96
|
+
'{type:"session:start",session:$sid,prompt:$prompt,mode:$mode,project:$proj,ts:(now*1000|floor)}')" || true
|
|
92
97
|
```
|
|
93
98
|
|
|
94
99
|
### Step 4 — Decompose
|
|
@@ -103,6 +108,32 @@ Complexity threshold for manager agent: any of these is true:
|
|
|
103
108
|
- Has external dependencies (APIs, services)
|
|
104
109
|
- Is estimated to take more than one conversation turn
|
|
105
110
|
|
|
111
|
+
**Per-domain goal extraction:** For each activated domain, extract a one-sentence goal from the prompt describing what that domain must accomplish. Then **run the following Bash block**, substituting `<domain_goals_json>` with a JSON object mapping each domain name to its one-sentence goal (use the full `resolved_prompt` as the value for any domain where no specific goal is extractable):
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
115
|
+
SESSION_STATE="$REPO_ROOT/.monomind/sessions/current.json"
|
|
116
|
+
[ -f "$SESSION_STATE" ] || { echo "ERROR: current.json not found"; exit 1; }
|
|
117
|
+
|
|
118
|
+
# LLM: write the extracted goals JSON object to the temp file below.
|
|
119
|
+
# Use a file (not a shell variable) to avoid quoting issues with apostrophes in goal text.
|
|
120
|
+
# Example content: {"build":"Ship the auth module","marketing":"Draft launch email series"}
|
|
121
|
+
# One JSON object, keys = domain names, values = one-sentence goals.
|
|
122
|
+
SESSION_ID=$(jq -r '.sessionId // empty' "$SESSION_STATE" 2>/dev/null)
|
|
123
|
+
[ -z "$SESSION_ID" ] && { echo "ERROR: SESSION_ID missing in current.json — run Step 3 first"; exit 1; }
|
|
124
|
+
GOALS_FILE="$REPO_ROOT/.monomind/sessions/${SESSION_ID}_goals.json"
|
|
125
|
+
cat > "$GOALS_FILE" << 'GOALS_EOF'
|
|
126
|
+
<domain_goals_json>
|
|
127
|
+
GOALS_EOF
|
|
128
|
+
|
|
129
|
+
# Validate it's real JSON before merging
|
|
130
|
+
jq . "$GOALS_FILE" > /dev/null 2>&1 || { echo "ERROR: domain_goals_json is not valid JSON — check LLM substitution"; exit 1; }
|
|
131
|
+
|
|
132
|
+
jq --slurpfile goals "$GOALS_FILE" '. + {domain_goals:$goals[0]}' \
|
|
133
|
+
"$SESSION_STATE" > "$SESSION_STATE.tmp" && mv "$SESSION_STATE.tmp" "$SESSION_STATE"
|
|
134
|
+
echo "Domain goals written to current.json"
|
|
135
|
+
```
|
|
136
|
+
|
|
106
137
|
### Step 5 — Plan Output
|
|
107
138
|
|
|
108
139
|
Build a plan summary:
|
|
@@ -114,48 +145,249 @@ Prompt: <prompt>
|
|
|
114
145
|
Mode: <auto|confirm>
|
|
115
146
|
|
|
116
147
|
Domains activated:
|
|
117
|
-
✦ build → Development Manager agent → board: <project>/development
|
|
118
|
-
✦ marketing → Marketing Manager agent → board: <project>/marketing
|
|
148
|
+
✦ build → Development Manager agent → board: <project>/development (will be created in Step 6)
|
|
149
|
+
✦ marketing → Marketing Manager agent → board: <project>/marketing (will be created in Step 6)
|
|
119
150
|
|
|
120
151
|
Monotask space: <project_name>
|
|
121
152
|
Brain loaded: <N> principles, <M> domain summaries
|
|
122
153
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
123
154
|
```
|
|
124
155
|
|
|
125
|
-
If mode = confirm: show plan and wait for user
|
|
156
|
+
If mode = confirm: show plan and wait for user response. Valid responses:
|
|
157
|
+
- "go" or "proceed" — continue immediately
|
|
158
|
+
- Any modification (e.g. "add sales domain", "remove marketing") — apply the change, re-show the plan, wait again
|
|
159
|
+
- "cancel" or "stop" — emit `session:complete` with `status: blocked`, reason "cancelled by user", then STOP
|
|
160
|
+
|
|
161
|
+
If mode = auto: proceed immediately.
|
|
126
162
|
|
|
127
163
|
### Step 6 — Monotask Setup
|
|
128
164
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
3
|
|
165
|
+
Follow the Monotask Space+Board Setup Procedure from `_protocol.md`. Resolve the space **once**, then create one board per active domain. Use `project_name` as the space name so all boards across repos and domains share the same space.
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# Require bash 4.3+ for associative arrays and namerefs (local -n introduced in 4.3)
|
|
169
|
+
# macOS ships bash 3.2; install via: brew install bash
|
|
170
|
+
(( BASH_VERSINFO[0] * 100 + BASH_VERSINFO[1] < 403 )) && \
|
|
171
|
+
{ echo "ERROR: bash 4.3+ required for namerefs (current: $BASH_VERSION). Install: brew install bash"; exit 1; }
|
|
172
|
+
|
|
173
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
174
|
+
SESSION_STATE="$REPO_ROOT/.monomind/sessions/current.json"
|
|
175
|
+
|
|
176
|
+
# Reload persisted context (this is a fresh shell; Step 3 wrote these)
|
|
177
|
+
SESSION_ID=$(jq -r '.sessionId // empty' "$SESSION_STATE" 2>/dev/null)
|
|
178
|
+
[ -z "$SESSION_ID" ] && { echo "ERROR: SESSION_ID missing in current.json — run Step 3 first"; exit 1; }
|
|
179
|
+
project_name=$(jq -r '.project_name // ""' "$SESSION_STATE")
|
|
180
|
+
[ -z "$project_name" ] && { echo "ERROR: project_name is empty in current.json — run Step 3 first"; exit 1; }
|
|
181
|
+
resolved_prompt=$(jq -r '.prompt // ""' "$SESSION_STATE")
|
|
182
|
+
|
|
183
|
+
# domains_needed: NOT yet in current.json at this point — must be LLM-substituted inline.
|
|
184
|
+
# LLM: replace DOMAINS_LIST_HERE with space-separated domain names, e.g.: build marketing sales
|
|
185
|
+
# Domain names must be single words (no spaces). Example: "build marketing sales"
|
|
186
|
+
|
|
187
|
+
# Resolve space once for all domains
|
|
188
|
+
# Use awk with literal pipe to avoid BSD awk \| regex fragility
|
|
189
|
+
space_id=$(monotask space list 2>/dev/null | awk -F'|' '{gsub(/^ +| +$/,"",$2); if($2==n) gsub(/^ +| +$/,"",$1); if($2==n) print $1}' n="$project_name" | head -1)
|
|
190
|
+
[ -z "$space_id" ] && space_id=$(monotask space create "$project_name" 2>/dev/null | grep -oE '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')
|
|
191
|
+
[ -z "$space_id" ] && { echo "ERROR: Could not find or create space '$project_name'"; exit 1; }
|
|
192
|
+
|
|
193
|
+
# Associative arrays — no eval, no injection risk
|
|
194
|
+
declare -A board_ids todo_cols doing_cols done_cols domain_goals
|
|
195
|
+
|
|
196
|
+
# Hydrate domain_goals from Step 4's current.json write — prevents Step 4 extraction being clobbered
|
|
197
|
+
# Use NUL-delimited pairs (not @tsv) to safely handle backslashes, tabs, and other special chars in goals
|
|
198
|
+
while IFS= read -r -d '' k && IFS= read -r -d '' v; do
|
|
199
|
+
[[ -n "$k" ]] && domain_goals[$k]="$v"
|
|
200
|
+
done < <(jq -j '.domain_goals // {} | to_entries[] | (.key + "\u0000" + (.value // "") + "\u0000")' "$SESSION_STATE" 2>/dev/null)
|
|
201
|
+
|
|
202
|
+
# Loop over every active domain — LLM: replace DOMAINS_LIST_HERE with the resolved domain list
|
|
203
|
+
domains_needed="DOMAINS_LIST_HERE"
|
|
204
|
+
[ "$domains_needed" = "DOMAINS_LIST_HERE" ] && { echo "ERROR: LLM did not substitute DOMAINS_LIST_HERE with domain names"; exit 1; }
|
|
205
|
+
[ -z "$domains_needed" ] && { echo "ERROR: domains_needed is empty — nothing to do"; exit 1; }
|
|
206
|
+
for domain in $domains_needed; do
|
|
207
|
+
board_id=$(monotask board create "$domain" --json | jq -r '.id // empty')
|
|
208
|
+
[ -z "$board_id" ] && { echo "ERROR: Failed to create $domain board"; exit 1; }
|
|
209
|
+
monotask space boards add "$space_id" "$board_id" >/dev/null 2>&1 \
|
|
210
|
+
|| echo "WARN: could not attach $domain board to space $space_id (non-fatal)"
|
|
211
|
+
todo_col=$(monotask column create "$board_id" "Todo" --json | jq -r '.id // empty')
|
|
212
|
+
[ -z "$todo_col" ] && { echo "ERROR: Failed to create Todo column for $domain"; exit 1; }
|
|
213
|
+
doing_col=$(monotask column create "$board_id" "Doing" --json | jq -r '.id // empty')
|
|
214
|
+
[ -z "$doing_col" ] && { echo "ERROR: Failed to create Doing column for $domain"; exit 1; }
|
|
215
|
+
done_col=$(monotask column create "$board_id" "Done" --json | jq -r '.id // empty')
|
|
216
|
+
[ -z "$done_col" ] && { echo "ERROR: Failed to create Done column for $domain"; exit 1; }
|
|
217
|
+
board_ids[$domain]=$board_id
|
|
218
|
+
todo_cols[$domain]=$todo_col
|
|
219
|
+
doing_cols[$domain]=$doing_col
|
|
220
|
+
done_cols[$domain]=$done_col
|
|
221
|
+
# Fall back to full prompt only for domains not extracted by Step 4
|
|
222
|
+
[ -z "${domain_goals[$domain]}" ] && domain_goals[$domain]="$resolved_prompt"
|
|
223
|
+
done
|
|
224
|
+
|
|
225
|
+
# Persist all session state needed by later shells — board/col IDs, goals, domain list
|
|
226
|
+
# (each Bash tool call is a fresh shell — associative arrays don't survive)
|
|
227
|
+
_to_json_map() {
|
|
228
|
+
local -n _arr=$1
|
|
229
|
+
for k in "${!_arr[@]}"; do
|
|
230
|
+
jq -n --arg k "$k" --arg v "${_arr[$k]}" '{key:$k,value:$v}'
|
|
231
|
+
done | jq -s 'from_entries // {}'
|
|
232
|
+
}
|
|
233
|
+
domains_goals_json=$(_to_json_map domain_goals)
|
|
234
|
+
board_ids_json=$(_to_json_map board_ids)
|
|
235
|
+
todo_cols_json=$(_to_json_map todo_cols)
|
|
236
|
+
doing_cols_json=$(_to_json_map doing_cols)
|
|
237
|
+
done_cols_json=$(_to_json_map done_cols)
|
|
238
|
+
|
|
239
|
+
jq --arg domains "$domains_needed" \
|
|
240
|
+
--argjson goals "$domains_goals_json" \
|
|
241
|
+
--argjson boards "$board_ids_json" \
|
|
242
|
+
--argjson todos "$todo_cols_json" \
|
|
243
|
+
--argjson doings "$doing_cols_json" \
|
|
244
|
+
--argjson dones "$done_cols_json" \
|
|
245
|
+
'. + {domains_needed:($domains | split(" ") | map(select(length>0))),
|
|
246
|
+
domain_goals:$goals, board_ids:$boards,
|
|
247
|
+
todo_cols:$todos, doing_cols:$doings, done_cols:$dones}' \
|
|
248
|
+
"$REPO_ROOT/.monomind/sessions/current.json" > "$REPO_ROOT/.monomind/sessions/current.json.tmp" \
|
|
249
|
+
&& mv "$REPO_ROOT/.monomind/sessions/current.json.tmp" "$REPO_ROOT/.monomind/sessions/current.json"
|
|
250
|
+
```
|
|
133
251
|
|
|
134
252
|
### Step 7 — Spawn Domain Managers
|
|
135
253
|
|
|
136
|
-
**Before spawning
|
|
254
|
+
**Before spawning**, select the best domain manager agent type from the registry for each active domain. Do not hardcode `coordinator` — pick the agent whose expertise best fits the domain goal.
|
|
255
|
+
|
|
256
|
+
**Phase A — Registry selection** (run as one Bash call; must complete before Phase C):
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
# Require bash 4.3+ for associative arrays and namerefs
|
|
260
|
+
(( BASH_VERSINFO[0] * 100 + BASH_VERSINFO[1] < 403 )) && \
|
|
261
|
+
{ echo "ERROR: bash 4.3+ required (current: $BASH_VERSION). Install: brew install bash"; exit 1; }
|
|
262
|
+
|
|
263
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
264
|
+
REGISTRY="$REPO_ROOT/.monomind/registry.json"
|
|
265
|
+
|
|
266
|
+
# Reload state from current.json — this is a new shell; no inherited variables
|
|
267
|
+
SESSION_STATE="$REPO_ROOT/.monomind/sessions/current.json"
|
|
268
|
+
[ -f "$SESSION_STATE" ] || { echo "ERROR: current.json not found — run from Step 3"; exit 1; }
|
|
269
|
+
domains_needed=$(jq -r '.domains_needed[]? // empty' "$SESSION_STATE" | tr '\n' ' ')
|
|
270
|
+
[ -z "$domains_needed" ] && { echo "ERROR: domains_needed is empty in current.json"; exit 1; }
|
|
271
|
+
|
|
272
|
+
# Returns: best agent name from registry for the given domain+goal
|
|
273
|
+
pick_domain_manager() {
|
|
274
|
+
local domain="$1"
|
|
275
|
+
local goal="$2"
|
|
276
|
+
local kw cats result
|
|
277
|
+
kw=$(echo "$goal" | tr '[:upper:]' '[:lower:]' | grep -oE '[a-z]{5,}' | sort -u | tr '\n' ' ')
|
|
278
|
+
case "$domain" in
|
|
279
|
+
build) cats="engineering development architecture" ;;
|
|
280
|
+
marketing) cats="marketing paid-media strategy" ;;
|
|
281
|
+
sales) cats="sales strategy" ;;
|
|
282
|
+
research) cats="academic specialized strategy" ;;
|
|
283
|
+
content) cats="marketing specialized" ;;
|
|
284
|
+
ops) cats="project-management strategy support" ;;
|
|
285
|
+
release) cats="devops github engineering" ;;
|
|
286
|
+
review) cats="engineering testing analysis" ;;
|
|
287
|
+
finance) cats="strategy specialized" ;;
|
|
288
|
+
architect) cats="architecture engineering" ;;
|
|
289
|
+
idea) cats="product strategy marketing" ;;
|
|
290
|
+
*) cats="core strategy" ;;
|
|
291
|
+
esac
|
|
292
|
+
result=$(jq -r \
|
|
293
|
+
--arg cats "$cats" \
|
|
294
|
+
--arg kw "$kw" \
|
|
295
|
+
'[ .agents[] | select(.deprecated != true)
|
|
296
|
+
| select(.category as $c | ($cats | split(" ") | any(. == $c)))
|
|
297
|
+
| {name: .name,
|
|
298
|
+
score: (
|
|
299
|
+
(.name | ascii_downcase) as $n |
|
|
300
|
+
# Score on ANY keyword match, not just the first
|
|
301
|
+
(if ($kw | length) > 0
|
|
302
|
+
then ([$kw | split(" ")[] | select(length > 0) | if ($n | contains(.)) then 1 else 0 end] | add // 0)
|
|
303
|
+
else 0 end) +
|
|
304
|
+
(if $n | test("manager|director|coordinator") then 1 else 0 end)
|
|
305
|
+
)}
|
|
306
|
+
] | sort_by(-.score) | .[0].name // empty' \
|
|
307
|
+
"$REGISTRY" 2>/dev/null)
|
|
308
|
+
if [ -z "$result" ]; then
|
|
309
|
+
echo "WARN: registry lookup failed for domain=$domain, using coordinator fallback" >&2
|
|
310
|
+
echo "coordinator"
|
|
311
|
+
else
|
|
312
|
+
echo "$result"
|
|
313
|
+
fi
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
declare -A domain_managers
|
|
317
|
+
for domain in $domains_needed; do
|
|
318
|
+
goal=$(jq -r --arg d "$domain" '.domain_goals[$d] // empty' "$SESSION_STATE")
|
|
319
|
+
[ -z "$goal" ] && goal=$(jq -r '.prompt // ""' "$SESSION_STATE")
|
|
320
|
+
manager=$(pick_domain_manager "$domain" "$goal")
|
|
321
|
+
domain_managers[$domain]="$manager"
|
|
322
|
+
echo "Domain manager for $domain: $manager"
|
|
323
|
+
done
|
|
324
|
+
|
|
325
|
+
# Persist domain_managers so Phase C can reload them without stdout parsing
|
|
326
|
+
domain_managers_json=$(for k in "${!domain_managers[@]}"; do
|
|
327
|
+
jq -n --arg k "$k" --arg v "${domain_managers[$k]}" '{key:$k,value:$v}'
|
|
328
|
+
done | jq -s 'from_entries // {}')
|
|
329
|
+
[ -z "$domain_managers_json" ] && domain_managers_json="{}"
|
|
330
|
+
jq --argjson mgrs "$domain_managers_json" '. + {domain_managers:$mgrs}' \
|
|
331
|
+
"$SESSION_STATE" > "$SESSION_STATE.tmp" && mv "$SESSION_STATE.tmp" "$SESSION_STATE"
|
|
332
|
+
|
|
333
|
+
# Emit board/column lookup for LLM use in Phase C Task construction:
|
|
334
|
+
echo "--- Phase C board/col IDs (loaded from current.json) ---"
|
|
335
|
+
for domain in $domains_needed; do
|
|
336
|
+
board=$(jq -r --arg d "$domain" '.board_ids[$d] // ""' "$SESSION_STATE")
|
|
337
|
+
todo=$(jq -r --arg d "$domain" '.todo_cols[$d] // ""' "$SESSION_STATE")
|
|
338
|
+
doing=$(jq -r --arg d "$domain" '.doing_cols[$d] // ""' "$SESSION_STATE")
|
|
339
|
+
done_c=$(jq -r --arg d "$domain" '.done_cols[$d] // ""' "$SESSION_STATE")
|
|
340
|
+
mgr=$(jq -r --arg d "$domain" '.domain_managers[$d] // "coordinator"' "$SESSION_STATE")
|
|
341
|
+
echo "DOMAIN=$domain MANAGER=$mgr BOARD=$board TODO=$todo DOING=$doing DONE=$done_c"
|
|
342
|
+
done
|
|
343
|
+
```
|
|
137
344
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
345
|
+
**Phase B — Dashboard dispatch** + **Phase C — Task spawning** (run in one message — B is a Bash call, C is the Task tool calls; they are independent of each other):
|
|
346
|
+
|
|
347
|
+
Phase B:
|
|
348
|
+
```bash
|
|
349
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
350
|
+
SESSION_STATE="$REPO_ROOT/.monomind/sessions/current.json"
|
|
351
|
+
SESSION_ID=$(jq -r '.sessionId // empty' "$SESSION_STATE" 2>/dev/null)
|
|
352
|
+
[ -z "$SESSION_ID" ] && { echo "ERROR: SESSION_ID not found in current.json"; exit 1; }
|
|
353
|
+
domains_needed=$(jq -r '.domains_needed[]? // empty' "$SESSION_STATE" | tr '\n' ' ')
|
|
354
|
+
for domain in $domains_needed; do
|
|
355
|
+
goal=$(jq -r --arg d "$domain" '.domain_goals[$d] // empty' "$SESSION_STATE")
|
|
356
|
+
[ -z "$goal" ] && goal=$(jq -r '.prompt // ""' "$SESSION_STATE")
|
|
357
|
+
curl -s -o /dev/null -X POST "http://localhost:4242/api/mastermind/event" \
|
|
358
|
+
-H "Content-Type: application/json" \
|
|
359
|
+
-d "$(jq -cn --arg sid "$SESSION_ID" --arg d "$domain" --arg cmd "$goal" \
|
|
360
|
+
'{type:"domain:dispatch",session:$sid,domain:$d,cmd:$cmd,ts:(now*1000|floor)}')" || true
|
|
361
|
+
done
|
|
152
362
|
```
|
|
153
363
|
|
|
154
364
|
Spawn ALL domain manager agents in ONE message using the Task tool (parallel execution).
|
|
155
365
|
|
|
366
|
+
**Before constructing the Task calls:** load board/column UUIDs and domain manager names from `current.json` — that is the authoritative source. The Phase A echo lines are a human-readable diagnostic only; do not parse them as the primary data source.
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
370
|
+
SESSION_STATE="$REPO_ROOT/.monomind/sessions/current.json"
|
|
371
|
+
SESSION_ID=$(jq -r '.sessionId // empty' "$SESSION_STATE" 2>/dev/null)
|
|
372
|
+
[ -z "$SESSION_ID" ] && { echo "ERROR: SESSION_ID missing"; exit 1; }
|
|
373
|
+
|
|
374
|
+
# Emit one line per domain for LLM to read before constructing Task calls
|
|
375
|
+
for domain in $(jq -r '.domains_needed[]? // empty' "$SESSION_STATE"); do
|
|
376
|
+
echo "DOMAIN=$domain \
|
|
377
|
+
MANAGER=$(jq -r --arg d "$domain" '.domain_managers[$d] // "coordinator"' "$SESSION_STATE") \
|
|
378
|
+
BOARD=$(jq -r --arg d "$domain" '.board_ids[$d] // ""' "$SESSION_STATE") \
|
|
379
|
+
TODO=$(jq -r --arg d "$domain" '.todo_cols[$d] // ""' "$SESSION_STATE") \
|
|
380
|
+
DOING=$(jq -r --arg d "$domain" '.doing_cols[$d] // ""' "$SESSION_STATE") \
|
|
381
|
+
DONE=$(jq -r --arg d "$domain" '.done_cols[$d] // ""' "$SESSION_STATE") \
|
|
382
|
+
GOAL=$(jq -r --arg d "$domain" '.domain_goals[$d] // .prompt' "$SESSION_STATE" | tr -d '\n')"
|
|
383
|
+
done
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
Use each `MANAGER` value as `subagent_type`, `BOARD`/`TODO`/`DOING`/`DONE` as board and column IDs. Do NOT use placeholder strings.
|
|
387
|
+
|
|
156
388
|
Each Task call must include a complete briefing following the Monotask Task Briefing Standard from `_protocol.md`. Include:
|
|
157
389
|
- The full BRAIN CONTEXT block
|
|
158
|
-
- The board ID
|
|
390
|
+
- The board ID (from `current.json` above)
|
|
159
391
|
- The specific goal for this domain
|
|
160
392
|
- The project name and run context
|
|
161
393
|
- Instruction to create monotask cards directly using `monotask card create $BOARD_ID $COL_TODO_ID "<title>" --json` for all sub-tasks
|
|
@@ -163,95 +395,125 @@ Each Task call must include a complete briefing following the Monotask Task Brie
|
|
|
163
395
|
- Instruction to spawn specialized agents using the domain-appropriate swarm topology
|
|
164
396
|
- Instruction to return the unified output schema when done
|
|
165
397
|
|
|
166
|
-
Example Task call for Development Manager
|
|
398
|
+
Example Task call for Development Manager. Substitute all **pre-known** `<…>` placeholders (project_name, SESSION_ID, board/col IDs, goals, manager name) before calling Task. Placeholders like `<status>`, `<path1>`, `<action1>` are filled at runtime by the spawned agent — do not attempt to substitute them. `subagent_type` is the **string value** of `$domain_manager_build` (e.g. `"Backend Architect"`), not a variable reference.
|
|
399
|
+
|
|
400
|
+
**IMPORTANT — `<SESSION_ID>` appears 6 times in the template below. ALL must be replaced with the resolved value:**
|
|
401
|
+
1. `SESSION ID: <SESSION_ID>` — the header line in the prompt
|
|
402
|
+
2. `--arg sid '<SESSION_ID>'` in the agent:spawn curl call
|
|
403
|
+
3. `--arg sid '<SESSION_ID>'` in the intercom curl call
|
|
404
|
+
4. `mkdir -p "…/sessions/<SESSION_ID>"` — the output directory
|
|
405
|
+
5. `> "…/sessions/<SESSION_ID>/build.json"` — the output file path
|
|
406
|
+
6. `--arg sid '<SESSION_ID>'` in the domain:complete curl call
|
|
407
|
+
|
|
408
|
+
Missing any one causes silent failures (output files written to a literal `<SESSION_ID>` directory that doesn't exist; Step 9 finds nothing and reports `complete` with zero domains).
|
|
409
|
+
|
|
167
410
|
```javascript
|
|
168
411
|
Task({
|
|
169
|
-
subagent_type: "
|
|
170
|
-
description:
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
<paste brain context here
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
next_actions: [...]
|
|
223
|
-
board_url: monotask://<project_name>/development
|
|
224
|
-
run_id: <ISO8601-timestamp>`,
|
|
225
|
-
run_in_background: true
|
|
412
|
+
subagent_type: "<value of domain_manager_build, e.g. Backend Architect>",
|
|
413
|
+
description: "Development Manager for project <project_name>",
|
|
414
|
+
run_in_background: false, // foreground so Step 8 can collect output synchronously
|
|
415
|
+
prompt: "You are the Development Manager for project <project_name>.\n\n" +
|
|
416
|
+
"CONTEXT: Mastermind run <date> | Project: <project_name> | Master spawned you.\n\n" +
|
|
417
|
+
"SESSION ID: <SESSION_ID> — use in all dashboard events below.\n\n" +
|
|
418
|
+
"BRAIN CONTEXT:\n<paste brain context here>\n\n" +
|
|
419
|
+
"YOUR BOARD: <board_build> (monotask://<project_name>/build)\n" +
|
|
420
|
+
"TODO COL: <todo_col_build> | DOING COL: <doing_col_build> | DONE COL: <done_col_build>\n\n" +
|
|
421
|
+
"GOAL: <build_goal>\n\n" +
|
|
422
|
+
"YOUR RESPONSIBILITIES:\n" +
|
|
423
|
+
"1. Break this goal into discrete tasks using:\n" +
|
|
424
|
+
" monotask card create <board_build> <todo_col_build> '<title>' --json\n" +
|
|
425
|
+
" Each card description MUST include: context, goal, scope, constraints, success criteria, agent, dependencies.\n\n" +
|
|
426
|
+
"2. Spawn specialized agents for each task using the Task tool:\n" +
|
|
427
|
+
" - Backend work: subagent_type 'backend-dev'\n" +
|
|
428
|
+
" - Frontend work: subagent_type 'frontend-dev'\n" +
|
|
429
|
+
" - Testing: subagent_type 'tester'\n" +
|
|
430
|
+
" - Code review: subagent_type 'reviewer'\n" +
|
|
431
|
+
" Default swarm: hierarchical 6 agents raft\n\n" +
|
|
432
|
+
"3. BEFORE spawning each agent, emit agent:spawn via curl (NOT WebFetch — use jq for correct ms timestamps):\n" +
|
|
433
|
+
" curl -s -o /dev/null -X POST http://localhost:4242/api/mastermind/event \\\n" +
|
|
434
|
+
" -H 'Content-Type: application/json' \\\n" +
|
|
435
|
+
" -d \"$(jq -cn --arg sid '<SESSION_ID>' --arg agent '<slug>' --arg task '<title>' \\\n" +
|
|
436
|
+
" '{type:\"agent:spawn\",session:$sid,domain:\"build\",agent:$agent,task:$task,ts:(now*1000|floor)}')\" || true\n\n" +
|
|
437
|
+
"4. If handing off artifacts to another domain, emit intercom via curl:\n" +
|
|
438
|
+
" curl -s -o /dev/null -X POST http://localhost:4242/api/mastermind/event \\\n" +
|
|
439
|
+
" -H 'Content-Type: application/json' \\\n" +
|
|
440
|
+
" -d \"$(jq -cn --arg sid '<SESSION_ID>' --arg to '<domain>' --arg msg '<summary>' \\\n" +
|
|
441
|
+
" '{type:\"intercom\",session:$sid,from:\"build\",to:$to,msg:$msg,ts:(now*1000|floor)}')\" || true\n\n" +
|
|
442
|
+
"5. Execute tasks via /monomind:do --board <board_build>\n" +
|
|
443
|
+
"6. Collect all agent outputs\n\n" +
|
|
444
|
+
"7. BEFORE returning, write your output schema to disk AND emit domain:complete:\n" +
|
|
445
|
+
" REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)\n" +
|
|
446
|
+
" mkdir -p \"$REPO_ROOT/.monomind/sessions/<SESSION_ID>\"\n" +
|
|
447
|
+
" jq -n --arg domain 'build' --arg status '<status>' \\\n" +
|
|
448
|
+
" --argjson artifacts '[\"<path1>\",\"<path2>\"]' \\\n" +
|
|
449
|
+
" --argjson next_actions '[\"<action1>\"]' \\\n" +
|
|
450
|
+
" '{domain:$domain,status:$status,artifacts:$artifacts,next_actions:$next_actions}' \\\n" +
|
|
451
|
+
" > \"$REPO_ROOT/.monomind/sessions/<SESSION_ID>/build.json\"\n" +
|
|
452
|
+
" curl -s -o /dev/null -X POST http://localhost:4242/api/mastermind/event \\\n" +
|
|
453
|
+
" -H 'Content-Type: application/json' \\\n" +
|
|
454
|
+
" -d \"$(jq -cn --arg sid '<SESSION_ID>' --arg status '<status>' \\\n" +
|
|
455
|
+
" '{type:\"domain:complete\",session:$sid,domain:\"build\",status:$status,ts:(now*1000|floor)}')\" || true\n\n" +
|
|
456
|
+
"8. Return unified output schema:\n" +
|
|
457
|
+
" domain: build\n" +
|
|
458
|
+
" status: complete|partial|blocked\n" +
|
|
459
|
+
" artifacts: [...]\n" +
|
|
460
|
+
" decisions: [...]\n" +
|
|
461
|
+
" lessons: [...]\n" +
|
|
462
|
+
" next_actions: [...]\n" +
|
|
463
|
+
" board_url: monotask://<project_name>/build\n" +
|
|
464
|
+
" run_id: <ISO8601-timestamp>"
|
|
226
465
|
})
|
|
227
466
|
```
|
|
228
467
|
|
|
229
|
-
### Step 8 —
|
|
468
|
+
### Step 8 — Collect Reports
|
|
230
469
|
|
|
231
|
-
|
|
470
|
+
Domain managers run in foreground (no `run_in_background`), so their unified output schemas are returned synchronously as each Task call completes. Each domain manager writes its canonical output schema to `.monomind/sessions/<SESSION_ID>/<domain>.json` before returning — that file is the source of truth for Step 9 aggregation. The Task tool's text return value is informational only; do not attempt to parse it as JSON. If a manager reports `status: blocked`, record it but continue collecting from all others — do not abort the run.
|
|
232
471
|
|
|
233
472
|
### Step 9 — Synthesize
|
|
234
473
|
|
|
235
|
-
1. Collect all domain output schemas
|
|
236
|
-
2.
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
474
|
+
1. Collect all domain output schemas from Step 8
|
|
475
|
+
2. Compute aggregate status — read from per-domain output files (precedence: blocked > partial > complete):
|
|
476
|
+
|
|
477
|
+
```bash
|
|
478
|
+
# Single bash block: aggregate status + emit dashboard event
|
|
479
|
+
# (variables don't persist between Bash tool calls — keep aggregation and curl together)
|
|
480
|
+
(( BASH_VERSINFO[0] * 100 + BASH_VERSINFO[1] < 400 )) && \
|
|
481
|
+
{ echo "ERROR: bash 4+ required (current: $BASH_VERSION). Install: brew install bash"; exit 1; }
|
|
482
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
483
|
+
SESSION_ID=$(jq -r '.sessionId // empty' "$REPO_ROOT/.monomind/sessions/current.json" 2>/dev/null)
|
|
484
|
+
[ -z "$SESSION_ID" ] && { echo "ERROR: SESSION_ID missing"; exit 1; }
|
|
485
|
+
|
|
486
|
+
overall_status="complete"
|
|
487
|
+
completed_domains=()
|
|
488
|
+
found_domain_files=0
|
|
489
|
+
for domain_file in "$REPO_ROOT/.monomind/sessions/${SESSION_ID}"/*.json; do
|
|
490
|
+
[ -f "$domain_file" ] || continue
|
|
491
|
+
domain=$(jq -r '.domain // ""' "$domain_file")
|
|
492
|
+
[ -z "$domain" ] && continue # skip auxiliary files that aren't domain output schemas
|
|
493
|
+
found_domain_files=$(( found_domain_files + 1 ))
|
|
494
|
+
status=$(jq -r '.status // "blocked"' "$domain_file")
|
|
495
|
+
case "$status" in
|
|
496
|
+
blocked) overall_status="blocked" ;;
|
|
497
|
+
partial) [ "$overall_status" != "blocked" ] && overall_status="partial" ;;
|
|
498
|
+
esac
|
|
499
|
+
[ "$status" = "complete" ] && completed_domains+=("$domain")
|
|
500
|
+
done
|
|
501
|
+
(( found_domain_files == 0 )) && { overall_status="blocked"; echo "WARN: no domain output files found for session $SESSION_ID — all domain managers may have failed"; }
|
|
502
|
+
echo "overall_status=$overall_status completed_domains=${completed_domains[*]}"
|
|
503
|
+
|
|
504
|
+
completed_domains_json=$(jq -n '$ARGS.positional' --args "${completed_domains[@]}")
|
|
505
|
+
|
|
506
|
+
curl -s -o /dev/null -X POST "http://localhost:4242/api/mastermind/event" \
|
|
507
|
+
-H "Content-Type: application/json" \
|
|
508
|
+
-d "$(jq -cn \
|
|
509
|
+
--arg sid "$SESSION_ID" \
|
|
510
|
+
--arg status "$overall_status" \
|
|
511
|
+
--argjson domains "$completed_domains_json" \
|
|
512
|
+
'{type:"session:complete",session:$sid,status:$status,domains:$domains,ts:(now*1000|floor)}')" || true
|
|
253
513
|
```
|
|
254
514
|
|
|
515
|
+
3. Identify any cross-domain artifacts needed (e.g. a release that requires both build and review)
|
|
516
|
+
4. Write cross-domain artifacts to disk if needed
|
|
255
517
|
5. Compose the action summary for the user:
|
|
256
518
|
|
|
257
519
|
```
|
|
@@ -292,6 +554,66 @@ Follow the Brain Write Procedure from `_protocol.md` for each domain that ran:
|
|
|
292
554
|
Show the action summary (Step 9). If any compaction ran during Step 10, append:
|
|
293
555
|
> "Brain updated: compacted <N> entries into <M> summaries."
|
|
294
556
|
|
|
557
|
+
**Persist session state for iteration cycles:** Aggregate artifacts from per-domain output files written by each domain manager, then persist to disk so Step 12 can load it:
|
|
558
|
+
|
|
559
|
+
```bash
|
|
560
|
+
(( BASH_VERSINFO[0] * 100 + BASH_VERSINFO[1] < 400 )) && \
|
|
561
|
+
{ echo "ERROR: bash 4+ required (current: $BASH_VERSION). Install: brew install bash"; exit 1; }
|
|
562
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
563
|
+
SESSION_STATE="$REPO_ROOT/.monomind/sessions/current.json"
|
|
564
|
+
|
|
565
|
+
# Restore variables from current.json (this is a fresh shell)
|
|
566
|
+
SESSION_ID=$(jq -r '.sessionId // empty' "$SESSION_STATE" 2>/dev/null)
|
|
567
|
+
[ -z "$SESSION_ID" ] && { echo "ERROR: SESSION_ID not found"; exit 1; }
|
|
568
|
+
resolved_prompt=$(jq -r '.prompt // ""' "$SESSION_STATE")
|
|
569
|
+
project_name=$(jq -r '.project_name // ""' "$SESSION_STATE")
|
|
570
|
+
|
|
571
|
+
# Aggregate artifacts, next_actions, completed_domains, and overall_status
|
|
572
|
+
# from per-domain output files (single source of truth — Step 9 shell is gone)
|
|
573
|
+
all_artifacts=()
|
|
574
|
+
all_next_actions=()
|
|
575
|
+
completed_domains=()
|
|
576
|
+
overall_status="complete"
|
|
577
|
+
found_domain_files=0
|
|
578
|
+
for domain_file in "$REPO_ROOT/.monomind/sessions/${SESSION_ID}"/*.json; do
|
|
579
|
+
[ -f "$domain_file" ] || continue
|
|
580
|
+
domain=$(jq -r '.domain // ""' "$domain_file")
|
|
581
|
+
[ -z "$domain" ] && continue # skip auxiliary files that aren't domain output schemas
|
|
582
|
+
found_domain_files=$(( found_domain_files + 1 ))
|
|
583
|
+
status=$(jq -r '.status // "blocked"' "$domain_file")
|
|
584
|
+
case "$status" in
|
|
585
|
+
blocked) overall_status="blocked" ;;
|
|
586
|
+
partial) [ "$overall_status" != "blocked" ] && overall_status="partial" ;;
|
|
587
|
+
esac
|
|
588
|
+
[ "$status" = "complete" ] && completed_domains+=("$domain")
|
|
589
|
+
while IFS= read -r art; do all_artifacts+=("$art"); done \
|
|
590
|
+
< <(jq -r '.artifacts[]? // empty' "$domain_file" 2>/dev/null)
|
|
591
|
+
while IFS= read -r act; do all_next_actions+=("$act"); done \
|
|
592
|
+
< <(jq -r '.next_actions[]? // empty' "$domain_file" 2>/dev/null)
|
|
593
|
+
done
|
|
594
|
+
(( found_domain_files == 0 )) && { overall_status="blocked"; echo "WARN: no domain output files found for session $SESSION_ID"; }
|
|
595
|
+
|
|
596
|
+
artifacts_json=$(jq -n '$ARGS.positional' --args "${all_artifacts[@]}")
|
|
597
|
+
next_actions_json=$(jq -n '$ARGS.positional' --args "${all_next_actions[@]}")
|
|
598
|
+
completed_domains_json=$(jq -n '$ARGS.positional' --args "${completed_domains[@]}")
|
|
599
|
+
|
|
600
|
+
jq -n \
|
|
601
|
+
--arg sessionId "$SESSION_ID" \
|
|
602
|
+
--arg prompt "$resolved_prompt" \
|
|
603
|
+
--arg project_name "$project_name" \
|
|
604
|
+
--arg status "$overall_status" \
|
|
605
|
+
--argjson completed_domains "$completed_domains_json" \
|
|
606
|
+
--argjson artifacts "$artifacts_json" \
|
|
607
|
+
--argjson next_actions "$next_actions_json" \
|
|
608
|
+
--arg run_id "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
609
|
+
'{sessionId:$sessionId,prompt:$prompt,project_name:$project_name,status:$status,
|
|
610
|
+
completed_domains:$completed_domains,artifacts:$artifacts,next_actions:$next_actions,
|
|
611
|
+
run_id:$run_id}' \
|
|
612
|
+
> "$REPO_ROOT/.monomind/sessions/${SESSION_ID}.json.tmp" \
|
|
613
|
+
&& mv "$REPO_ROOT/.monomind/sessions/${SESSION_ID}.json.tmp" \
|
|
614
|
+
"$REPO_ROOT/.monomind/sessions/${SESSION_ID}.json"
|
|
615
|
+
```
|
|
616
|
+
|
|
295
617
|
---
|
|
296
618
|
|
|
297
619
|
### Step 12 — Iteration Loop (only if `--iterate <N>` was set and N ≥ 1)
|
|
@@ -302,9 +624,30 @@ After Step 11, run N autonomous improvement cycles. Each cycle is a full self-di
|
|
|
302
624
|
|
|
303
625
|
#### 12a — Assess Current State
|
|
304
626
|
|
|
305
|
-
Load fresh brain context (repeat Brain Load Procedure from `_protocol.md`).
|
|
306
|
-
|
|
307
|
-
|
|
627
|
+
Load fresh brain context (repeat Brain Load Procedure from `_protocol.md`). Load the persisted session state:
|
|
628
|
+
|
|
629
|
+
```bash
|
|
630
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
631
|
+
# Restore SESSION_ID — may be in a new shell context
|
|
632
|
+
SESSION_ID=$(jq -r '.sessionId // empty' "$REPO_ROOT/.monomind/sessions/current.json" 2>/dev/null)
|
|
633
|
+
[ -z "$SESSION_ID" ] && { echo "ERROR: SESSION_ID not found in current.json — cannot continue iteration."; exit 1; }
|
|
634
|
+
|
|
635
|
+
SESSION_FILE="$REPO_ROOT/.monomind/sessions/${SESSION_ID}.json"
|
|
636
|
+
SESSION_STATE="$REPO_ROOT/.monomind/sessions/current.json"
|
|
637
|
+
# Echo to stdout — bash variables don't survive tool call boundaries; only stdout is visible to the LLM
|
|
638
|
+
# Emit run summary (artifacts, next_actions, project_name) from the session file
|
|
639
|
+
jq '{artifacts:.artifacts,next_actions:.next_actions,project_name:.project_name}' "$SESSION_FILE" 2>/dev/null \
|
|
640
|
+
|| echo '{"artifacts":[],"next_actions":[],"project_name":""}'
|
|
641
|
+
|
|
642
|
+
# Emit board_ids from current.json (not carried in SESSION_FILE) so Step 12c can look up board UUIDs
|
|
643
|
+
echo "--- board_ids (from current.json) ---"
|
|
644
|
+
jq '{board_ids:(.board_ids // {})}' "$SESSION_STATE" 2>/dev/null \
|
|
645
|
+
|| echo '{"board_ids":{}}'
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
Then evaluate the project's current state by examining:
|
|
649
|
+
- What was just completed (artifacts from the `artifacts` array printed above)
|
|
650
|
+
- What `next_actions` entries printed above suggest
|
|
308
651
|
- What the `next_actions` from all domain outputs say
|
|
309
652
|
- What the git diff shows (if applicable) — any test failures, TODOs, or incomplete work
|
|
310
653
|
- What gaps exist relative to the original prompt's success criteria
|
|
@@ -333,16 +676,18 @@ Log this as a decision in the cycle's output schema with `confidence` set accord
|
|
|
333
676
|
|
|
334
677
|
Execute the chosen activity by invoking the appropriate domain skill directly (Steps 4–10 of the main flow, condensed):
|
|
335
678
|
|
|
336
|
-
- Test →
|
|
337
|
-
- Debug/Fix →
|
|
338
|
-
- Review →
|
|
339
|
-
- Improve/Refactor →
|
|
340
|
-
- Add feature →
|
|
341
|
-
- Research →
|
|
342
|
-
- Content/Docs →
|
|
343
|
-
- Release →
|
|
679
|
+
- Test → invoke `/mastermind:build` with a testing-focused prompt
|
|
680
|
+
- Debug/Fix → invoke `/mastermind:build` with the specific failing test or error as prompt
|
|
681
|
+
- Review → invoke `/mastermind:review` with scope = artifacts from last run
|
|
682
|
+
- Improve/Refactor → invoke `/mastermind:build` with refactor prompt
|
|
683
|
+
- Add feature → invoke `/mastermind:build` with the next feature from the `next_actions` array printed by the Step 12a output above
|
|
684
|
+
- Research → invoke `/mastermind:research` with the open question as prompt
|
|
685
|
+
- Content/Docs → invoke `/mastermind:content` with scope = new artifacts
|
|
686
|
+
- Release → invoke `/mastermind:release` with project scope
|
|
687
|
+
|
|
688
|
+
Always pass: the current brain_context, project_name (from the `project_name` field above), the relevant board_id (look up `.board_ids[<chosen_domain>]` from the `board_ids` map printed above), and mode = auto (iteration cycles never pause for confirmation).
|
|
344
689
|
|
|
345
|
-
|
|
690
|
+
**Constraint:** Only invoke domains whose board_id already exists in the `board_ids` map. If the chosen activity maps to a domain not in `board_ids` (e.g. `release` was not activated in Step 6), choose the next highest-priority activity whose domain IS in `board_ids`, or invoke `build` as the safe fallback — its board is almost always present.
|
|
346
691
|
|
|
347
692
|
#### 12d — Brain Write
|
|
348
693
|
|