@monoes/monomindcli 1.9.15 → 1.9.17
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.
|
@@ -166,95 +166,111 @@ If mode = auto: proceed immediately.
|
|
|
166
166
|
|
|
167
167
|
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.
|
|
168
168
|
|
|
169
|
-
|
|
170
|
-
# Require bash 4.3+ for associative arrays and namerefs (local -n introduced in 4.3)
|
|
171
|
-
# macOS ships bash 3.2; install via: brew install bash
|
|
172
|
-
(( BASH_VERSINFO[0] * 100 + BASH_VERSINFO[1] < 403 )) && \
|
|
173
|
-
{ echo "ERROR: bash 4.3+ required for namerefs (current: $BASH_VERSION). Install: brew install bash"; exit 1; }
|
|
169
|
+
**Board naming convention:** Every board is named `<project_name>-<domain>` (e.g. `factory-idea`, `factory-build`). This canonical name is stable across runs — mastermind finds the existing board instead of creating a new one every time.
|
|
174
170
|
|
|
171
|
+
```bash
|
|
172
|
+
# Compatible with macOS bash 3.2 — no associative arrays, uses jq accumulation instead
|
|
175
173
|
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
176
174
|
SESSION_STATE="$REPO_ROOT/.monomind/sessions/current.json"
|
|
177
175
|
|
|
178
|
-
# Reload persisted context (this is a fresh shell; Step 3 wrote these)
|
|
179
176
|
SESSION_ID=$(jq -r '.sessionId // empty' "$SESSION_STATE" 2>/dev/null)
|
|
180
177
|
[ -z "$SESSION_ID" ] && { echo "ERROR: SESSION_ID missing in current.json — run Step 3 first"; exit 1; }
|
|
181
178
|
project_name=$(jq -r '.project_name // ""' "$SESSION_STATE")
|
|
182
179
|
[ -z "$project_name" ] && { echo "ERROR: project_name is empty in current.json — run Step 3 first"; exit 1; }
|
|
183
180
|
resolved_prompt=$(jq -r '.prompt // ""' "$SESSION_STATE")
|
|
184
181
|
|
|
185
|
-
# domains_needed: NOT yet in current.json at this point — must be LLM-substituted inline.
|
|
186
182
|
# LLM: replace DOMAINS_LIST_HERE with space-separated domain names, e.g.: build marketing sales
|
|
187
|
-
|
|
183
|
+
domains_needed="DOMAINS_LIST_HERE"
|
|
184
|
+
[ "$domains_needed" = "DOMAINS_LIST_HERE" ] && { echo "ERROR: LLM did not substitute DOMAINS_LIST_HERE"; exit 1; }
|
|
185
|
+
[ -z "$domains_needed" ] && { echo "ERROR: domains_needed is empty — nothing to do"; exit 1; }
|
|
188
186
|
|
|
189
|
-
# Resolve space once
|
|
190
|
-
|
|
191
|
-
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)
|
|
187
|
+
# Resolve space once — find existing by exact name or create
|
|
188
|
+
space_id=$(monotask space list 2>/dev/null | awk -F'|' '{gsub(/^ +| +$/,"",$1);gsub(/^ +| +$/,"",$2);if($2==n)print $1}' n="$project_name" | head -1)
|
|
192
189
|
[ -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}')
|
|
193
190
|
[ -z "$space_id" ] && { echo "ERROR: Could not find or create space '$project_name'"; exit 1; }
|
|
191
|
+
echo "Space: $space_id ($project_name)"
|
|
194
192
|
|
|
195
|
-
#
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
# Hydrate domain_goals from Step 4's current.json write — prevents Step 4 extraction being clobbered
|
|
199
|
-
# Use NUL-delimited pairs (not @tsv) to safely handle backslashes, tabs, and other special chars in goals
|
|
200
|
-
while IFS= read -r -d '' k && IFS= read -r -d '' v; do
|
|
201
|
-
[[ -n "$k" ]] && domain_goals[$k]="$v"
|
|
202
|
-
done < <(jq -j '.domain_goals // {} | to_entries[] | (.key + "\u0000" + (.value // "") + "\u0000")' "$SESSION_STATE" 2>/dev/null)
|
|
193
|
+
# jq accumulation state (replaces bash 4.3+ associative arrays)
|
|
194
|
+
state_patch='{}'
|
|
203
195
|
|
|
204
|
-
# Loop over every active domain — LLM: replace DOMAINS_LIST_HERE with the resolved domain list
|
|
205
|
-
domains_needed="DOMAINS_LIST_HERE"
|
|
206
|
-
[ "$domains_needed" = "DOMAINS_LIST_HERE" ] && { echo "ERROR: LLM did not substitute DOMAINS_LIST_HERE with domain names"; exit 1; }
|
|
207
|
-
[ -z "$domains_needed" ] && { echo "ERROR: domains_needed is empty — nothing to do"; exit 1; }
|
|
208
196
|
for domain in $domains_needed; do
|
|
209
|
-
|
|
210
|
-
[ -z "$board_id" ] && { echo "ERROR: Failed to create $domain board"; exit 1; }
|
|
211
|
-
monotask space boards add "$space_id" "$board_id" >/dev/null 2>&1 \
|
|
212
|
-
|| echo "WARN: could not attach $domain board to space $space_id (non-fatal)"
|
|
213
|
-
todo_col=$(monotask column create "$board_id" "Todo" --json | jq -r '.id // empty')
|
|
214
|
-
[ -z "$todo_col" ] && { echo "ERROR: Failed to create Todo column for $domain"; exit 1; }
|
|
215
|
-
doing_col=$(monotask column create "$board_id" "Doing" --json | jq -r '.id // empty')
|
|
216
|
-
[ -z "$doing_col" ] && { echo "ERROR: Failed to create Doing column for $domain"; exit 1; }
|
|
217
|
-
done_col=$(monotask column create "$board_id" "Done" --json | jq -r '.id // empty')
|
|
218
|
-
[ -z "$done_col" ] && { echo "ERROR: Failed to create Done column for $domain"; exit 1; }
|
|
219
|
-
board_ids[$domain]=$board_id
|
|
220
|
-
todo_cols[$domain]=$todo_col
|
|
221
|
-
doing_cols[$domain]=$doing_col
|
|
222
|
-
done_cols[$domain]=$done_col
|
|
223
|
-
# Fall back to full prompt only for domains not extracted by Step 4
|
|
224
|
-
[ -z "${domain_goals[$domain]}" ] && domain_goals[$domain]="$resolved_prompt"
|
|
225
|
-
done
|
|
197
|
+
canonical="${project_name}-${domain}"
|
|
226
198
|
|
|
227
|
-
#
|
|
228
|
-
|
|
229
|
-
_to_json_map() {
|
|
230
|
-
local -n _arr=$1
|
|
231
|
-
for k in "${!_arr[@]}"; do
|
|
232
|
-
jq -n --arg k "$k" --arg v "${_arr[$k]}" '{key:$k,value:$v}'
|
|
233
|
-
done | jq -s 'from_entries // {}'
|
|
234
|
-
}
|
|
235
|
-
domains_goals_json=$(_to_json_map domain_goals)
|
|
236
|
-
board_ids_json=$(_to_json_map board_ids)
|
|
237
|
-
todo_cols_json=$(_to_json_map todo_cols)
|
|
238
|
-
doing_cols_json=$(_to_json_map doing_cols)
|
|
239
|
-
done_cols_json=$(_to_json_map done_cols)
|
|
199
|
+
# Find existing board by canonical name — reuse across runs
|
|
200
|
+
board_id=$(monotask board list 2>/dev/null | awk -F'|' '{gsub(/^ +| +$/,"",$1);gsub(/^ +| +$/,"",$2);if($2==n)print $1}' n="$canonical" | head -1)
|
|
240
201
|
|
|
202
|
+
# Domain-specific column schema:
|
|
203
|
+
# idea → New | Evaluated | Elaborated | Tasked | Iced | Rejected (intake = "New")
|
|
204
|
+
# all others → Todo | In Progress | Human in Loop | Review | Done | Cancelled (intake = "Todo")
|
|
205
|
+
if [ "$domain" = "idea" ]; then
|
|
206
|
+
intake_col_name="New"
|
|
207
|
+
else
|
|
208
|
+
intake_col_name="Todo"
|
|
209
|
+
fi
|
|
210
|
+
|
|
211
|
+
if [ -n "$board_id" ]; then
|
|
212
|
+
echo "Reusing board: $board_id ($canonical)"
|
|
213
|
+
cols_json=$(monotask column list "$board_id" --json 2>/dev/null || echo '[]')
|
|
214
|
+
todo_col=$(echo "$cols_json" | jq -r --arg n "$intake_col_name" '[.[] | select(.title==$n)] | .[0].id // empty')
|
|
215
|
+
doing_col=$(echo "$cols_json" | jq -r '[.[] | select(.title=="In Progress" or .title=="Doing")] | .[0].id // empty')
|
|
216
|
+
done_col=$(echo "$cols_json" | jq -r '[.[] | select(.title=="Done")] | .[0].id // empty')
|
|
217
|
+
else
|
|
218
|
+
echo "Creating board: $canonical"
|
|
219
|
+
board_id=$(monotask board create --space "$space_id" "$canonical" --json 2>/dev/null | jq -r '.id // empty')
|
|
220
|
+
[ -z "$board_id" ] && { echo "ERROR: Failed to create board '$canonical'"; exit 1; }
|
|
221
|
+
monotask space boards add "$space_id" "$board_id" >/dev/null 2>&1 || true
|
|
222
|
+
if [ "$domain" = "idea" ]; then
|
|
223
|
+
todo_col=$(monotask column create "$board_id" "New" --json | jq -r '.id // empty')
|
|
224
|
+
doing_col=$(monotask column create "$board_id" "Evaluated" --json | jq -r '.id // empty')
|
|
225
|
+
monotask column create "$board_id" "Elaborated" --json >/dev/null
|
|
226
|
+
monotask column create "$board_id" "Tasked" --json >/dev/null
|
|
227
|
+
monotask column create "$board_id" "Iced" --json >/dev/null
|
|
228
|
+
done_col=$(monotask column create "$board_id" "Rejected" --json | jq -r '.id // empty')
|
|
229
|
+
else
|
|
230
|
+
todo_col=$(monotask column create "$board_id" "Todo" --json | jq -r '.id // empty')
|
|
231
|
+
doing_col=$(monotask column create "$board_id" "In Progress" --json | jq -r '.id // empty')
|
|
232
|
+
monotask column create "$board_id" "Human in Loop" --json >/dev/null
|
|
233
|
+
monotask column create "$board_id" "Review" --json >/dev/null
|
|
234
|
+
done_col=$(monotask column create "$board_id" "Done" --json | jq -r '.id // empty')
|
|
235
|
+
monotask column create "$board_id" "Cancelled" --json >/dev/null
|
|
236
|
+
fi
|
|
237
|
+
[ -z "$todo_col" ] && { echo "ERROR: Failed to create intake column for $domain"; exit 1; }
|
|
238
|
+
fi
|
|
239
|
+
|
|
240
|
+
domain_goal=$(jq -r --arg d "$domain" '.domain_goals[$d] // empty' "$SESSION_STATE")
|
|
241
|
+
[ -z "$domain_goal" ] && domain_goal="$resolved_prompt"
|
|
242
|
+
|
|
243
|
+
state_patch=$(echo "$state_patch" | jq \
|
|
244
|
+
--arg d "$domain" --arg b "$board_id" \
|
|
245
|
+
--arg t "$todo_col" --arg g "$doing_col" --arg e "$done_col" \
|
|
246
|
+
--arg goal "$domain_goal" \
|
|
247
|
+
'.board_ids[$d]=$b | .todo_cols[$d]=$t | .doing_cols[$d]=$g | .done_cols[$d]=$e | .domain_goals[$d]=$goal')
|
|
248
|
+
|
|
249
|
+
echo "DOMAIN=$domain BOARD=$board_id TODO=$todo_col DOING=$doing_col DONE=$done_col"
|
|
250
|
+
done
|
|
251
|
+
|
|
252
|
+
# Persist to current.json — one atomic merge
|
|
241
253
|
jq --arg domains "$domains_needed" \
|
|
242
|
-
--argjson
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
--argjson dones "$done_cols_json" \
|
|
247
|
-
'. + {domains_needed:($domains | split(" ") | map(select(length>0))),
|
|
248
|
-
domain_goals:$goals, board_ids:$boards,
|
|
249
|
-
todo_cols:$todos, doing_cols:$doings, done_cols:$dones}' \
|
|
250
|
-
"$REPO_ROOT/.monomind/sessions/current.json" > "$REPO_ROOT/.monomind/sessions/current.json.tmp" \
|
|
251
|
-
&& mv "$REPO_ROOT/.monomind/sessions/current.json.tmp" "$REPO_ROOT/.monomind/sessions/current.json"
|
|
254
|
+
--argjson patch "$state_patch" \
|
|
255
|
+
'. + $patch + {domains_needed:($domains | split(" ") | map(select(length>0)))}' \
|
|
256
|
+
"$SESSION_STATE" > "$SESSION_STATE.tmp" && mv "$SESSION_STATE.tmp" "$SESSION_STATE"
|
|
257
|
+
echo "Session state saved to current.json"
|
|
252
258
|
```
|
|
253
259
|
|
|
254
260
|
### Step 7 — Spawn Domain Managers
|
|
255
261
|
|
|
256
262
|
**BEFORE THIS STEP:** If `idea` is in `domains_needed`, invoke `Skill("mastermind:idea")` directly now (master context has Skill tool access). Pass the resolved prompt, project path, and mode. Write the result to `.monomind/sessions/<SESSION_ID>/idea.json` and mark the `idea` domain as handled. Do NOT include `idea` in the Task spawning below.
|
|
257
263
|
|
|
264
|
+
**IDEA PIPELINE REQUIREMENT:** `mastermind:idea` runs a multi-step pipeline (Steps 3–6 inside idea.md). You MUST follow all of those steps — do NOT shortcut to manually creating cards. The full pipeline is:
|
|
265
|
+
- Step 3: Board setup — find-or-create `<project_name>-idea` board (master's Step 6 already created it with correct columns: New → Evaluated → Elaborated → Tasked → Iced → Rejected). Load column IDs from existing board.
|
|
266
|
+
- Step 4: Spawn Idea Manager agent (coordinator) with specialist sub-agents per angle — generates ideas as cards in the `New` column.
|
|
267
|
+
- Step 5: Spawn PM agent for validation — moves each card to `Evaluated`, `Iced`, or `Rejected`, sets impact/effort.
|
|
268
|
+
- Step 6a: Elaboration agents enrich each `Evaluated` card and move it to `Elaborated`.
|
|
269
|
+
- Step 6b: User gate (skip in auto mode).
|
|
270
|
+
- Step 6c: Task decomposition — creates subtask cards on `<project_name>-tasks-dev` and `<project_name>-tasks-ops` boards, linked as subtasks of their parent idea card. Moves parent idea cards to `Tasked`.
|
|
271
|
+
|
|
272
|
+
Skipping any of these steps produces an incomplete pipeline run — card content is generated but no evaluation, elaboration, or task breakdown occurs.
|
|
273
|
+
|
|
258
274
|
**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.
|
|
259
275
|
|
|
260
276
|
**BASH TOOL REQUIREMENT:** Domain managers must run `monotask` CLI commands. Only use subagent_types that include Bash in their tool list. If the registry returns an agent without Bash (e.g. `Product Manager`, `Backend Architect`), override it with `general-purpose` (which has all tools). Agents without Bash cannot create cards, emit curl events, or write session files — they will silently produce degraded output.
|
|
@@ -247,53 +247,87 @@ curl -s -o /dev/null -X POST "http://localhost:4242/api/mastermind/event" \
|
|
|
247
247
|
|
|
248
248
|
**Always follow this exact order — never create a board without first ensuring a space exists.**
|
|
249
249
|
|
|
250
|
+
**Board naming convention:** Boards are named `<project_name>-<domain>` (e.g. `factory-idea`, `factory-build`). This canonical name is stable across runs — find the existing board first, create only if it does not exist.
|
|
251
|
+
|
|
252
|
+
**Column schemas by domain — use these exact column names, in this order:**
|
|
253
|
+
|
|
254
|
+
| Domain | Columns (left → right) | Intake column |
|
|
255
|
+
|---|---|---|
|
|
256
|
+
| `idea` | New → Evaluated → Elaborated → Tasked → Iced → Rejected | New |
|
|
257
|
+
| `build`, `release`, `architect`, `review` | Todo → In Progress → Human in Loop → Review → Done → Cancelled | Todo |
|
|
258
|
+
| `marketing`, `content`, `sales`, `ops`, `finance`, `research` | Todo → In Progress → Human in Loop → Review → Done → Cancelled | Todo |
|
|
259
|
+
| Task boards (`<proj>-tasks-dev`, `<proj>-tasks-ops`) | Backlog → Todo → In Progress → Human in Loop → Review → Done → Cancelled | Todo |
|
|
260
|
+
|
|
250
261
|
Every mastermind run that needs a task board MUST:
|
|
251
262
|
1. Resolve the space (find existing or create new) — space name = `project_name`
|
|
252
|
-
2.
|
|
253
|
-
3.
|
|
254
|
-
4. Create
|
|
255
|
-
5. Create cards within those columns
|
|
263
|
+
2. Find existing board by canonical name `<project_name>-<domain>` or create it with `--space`
|
|
264
|
+
3. Fetch column IDs from existing board OR create columns for new board
|
|
265
|
+
4. Create cards within those columns
|
|
256
266
|
|
|
257
267
|
If the user is running across multiple repos for the same project, they MUST use the same `project_name` so all boards land in one space.
|
|
258
268
|
|
|
259
269
|
### Canonical bash block (substitute `<domain>` with: build, marketing, ops, content, etc.)
|
|
260
270
|
|
|
261
271
|
```bash
|
|
262
|
-
#
|
|
272
|
+
# Compatible with macOS bash 3.2
|
|
263
273
|
project_name="${project_name:-$(basename "$PWD")}"
|
|
264
|
-
|
|
265
|
-
[ -z "$space_id" ] && space_id=$(monotask space create "$project_name" 2>&1 | grep -oE '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')
|
|
266
|
-
[ -z "$space_id" ] && { echo "ERROR: Could not find or create space '$project_name' — verify monotask is installed (monotask --version)"; exit 1; }
|
|
267
|
-
|
|
268
|
-
# Step 2 — Create board
|
|
269
|
-
board_id=$(monotask board create "<domain>" --json | jq -r '.id // empty')
|
|
270
|
-
[ -z "$board_id" ] && { echo "ERROR: Failed to create board '<domain>'"; exit 1; }
|
|
274
|
+
canonical="${project_name}-<domain>"
|
|
271
275
|
|
|
272
|
-
# Step
|
|
273
|
-
monotask space
|
|
276
|
+
# Step 1 — Resolve space
|
|
277
|
+
space_id=$(monotask space list 2>/dev/null | awk -F'|' '{gsub(/^ +| +$/,"",$1);gsub(/^ +| +$/,"",$2);if($2==n)print $1}' n="$project_name" | head -1)
|
|
278
|
+
[ -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}')
|
|
279
|
+
[ -z "$space_id" ] && { echo "ERROR: Could not find or create space '$project_name' — verify monotask is installed (monotask --version)"; exit 1; }
|
|
274
280
|
|
|
275
|
-
# Step
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
281
|
+
# Step 2 — Find existing board by canonical name or create
|
|
282
|
+
board_id=$(monotask board list 2>/dev/null | awk -F'|' '{gsub(/^ +| +$/,"",$1);gsub(/^ +| +$/,"",$2);if($2==n)print $1}' n="$canonical" | head -1)
|
|
283
|
+
if [ -n "$board_id" ]; then
|
|
284
|
+
# Step 3a — Fetch column IDs from existing board
|
|
285
|
+
cols_json=$(monotask column list "$board_id" --json 2>/dev/null || echo '[]')
|
|
286
|
+
todo_col=$(echo "$cols_json" | jq -r '[.[] | select(.title=="Todo" or .title=="Backlog")] | .[0].id // empty')
|
|
287
|
+
doing_col=$(echo "$cols_json" | jq -r '[.[] | select(.title=="Doing" or .title=="In Progress")] | .[0].id // empty')
|
|
288
|
+
done_col=$(echo "$cols_json" | jq -r '[.[] | select(.title=="Done")] | .[0].id // empty')
|
|
289
|
+
else
|
|
290
|
+
# Step 3b — Create board and columns
|
|
291
|
+
board_id=$(monotask board create --space "$space_id" "$canonical" --json | jq -r '.id // empty')
|
|
292
|
+
[ -z "$board_id" ] && { echo "ERROR: Failed to create board '$canonical'"; exit 1; }
|
|
293
|
+
monotask space boards add "$space_id" "$board_id" >/dev/null 2>&1 || true
|
|
294
|
+
todo_col=$(monotask column create "$board_id" "Todo" --json | jq -r '.id')
|
|
295
|
+
doing_col=$(monotask column create "$board_id" "Doing" --json | jq -r '.id')
|
|
296
|
+
done_col=$(monotask column create "$board_id" "Done" --json | jq -r '.id')
|
|
297
|
+
fi
|
|
279
298
|
```
|
|
280
299
|
|
|
281
|
-
When master.md runs multiple domains, resolve the space **once** before the loop, then repeat steps 2–
|
|
300
|
+
When master.md runs multiple domains, resolve the space **once** before the loop, then repeat steps 2–3 per domain using jq accumulation (no bash 4.3+ needed):
|
|
282
301
|
|
|
283
302
|
```bash
|
|
284
|
-
#
|
|
303
|
+
# Compatible with macOS bash 3.2 — jq accumulation instead of declare -A
|
|
285
304
|
project_name="<resolved project_name>"
|
|
286
|
-
space_id=$(monotask space list 2>/dev/null | awk -F'
|
|
287
|
-
[ -z "$space_id" ] && space_id=$(monotask space create "$project_name" 2
|
|
305
|
+
space_id=$(monotask space list 2>/dev/null | awk -F'|' '{gsub(/^ +| +$/,"",$1);gsub(/^ +| +$/,"",$2);if($2==n)print $1}' n="$project_name" | head -1)
|
|
306
|
+
[ -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}')
|
|
288
307
|
[ -z "$space_id" ] && { echo "ERROR: Could not find or create space '$project_name'"; exit 1; }
|
|
289
308
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
monotask
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
309
|
+
state_patch='{}'
|
|
310
|
+
for domain in build marketing ops; do # substitute actual domain list
|
|
311
|
+
canonical="${project_name}-${domain}"
|
|
312
|
+
board_id=$(monotask board list 2>/dev/null | awk -F'|' '{gsub(/^ +| +$/,"",$1);gsub(/^ +| +$/,"",$2);if($2==n)print $1}' n="$canonical" | head -1)
|
|
313
|
+
if [ -n "$board_id" ]; then
|
|
314
|
+
cols_json=$(monotask column list "$board_id" --json 2>/dev/null || echo '[]')
|
|
315
|
+
todo_col=$(echo "$cols_json" | jq -r '[.[] | select(.title=="Todo" or .title=="Backlog")] | .[0].id // empty')
|
|
316
|
+
doing_col=$(echo "$cols_json" | jq -r '[.[] | select(.title=="Doing" or .title=="In Progress")] | .[0].id // empty')
|
|
317
|
+
done_col=$(echo "$cols_json" | jq -r '[.[] | select(.title=="Done")] | .[0].id // empty')
|
|
318
|
+
else
|
|
319
|
+
board_id=$(monotask board create --space "$space_id" "$canonical" --json | jq -r '.id // empty')
|
|
320
|
+
[ -z "$board_id" ] && { echo "ERROR: Failed to create $canonical board"; exit 1; }
|
|
321
|
+
monotask space boards add "$space_id" "$board_id" >/dev/null 2>&1 || true
|
|
322
|
+
todo_col=$(monotask column create "$board_id" "Todo" --json | jq -r '.id')
|
|
323
|
+
doing_col=$(monotask column create "$board_id" "Doing" --json | jq -r '.id')
|
|
324
|
+
done_col=$(monotask column create "$board_id" "Done" --json | jq -r '.id')
|
|
325
|
+
fi
|
|
326
|
+
state_patch=$(echo "$state_patch" | jq \
|
|
327
|
+
--arg d "$domain" --arg b "$board_id" \
|
|
328
|
+
--arg t "$todo_col" --arg g "$doing_col" --arg e "$done_col" \
|
|
329
|
+
'.board_ids[$d]=$b | .todo_cols[$d]=$t | .doing_cols[$d]=$g | .done_cols[$d]=$e')
|
|
330
|
+
done
|
|
297
331
|
```
|
|
298
332
|
|
|
299
333
|
---
|
|
@@ -69,42 +69,46 @@ For simple prompts (single agent, single output):
|
|
|
69
69
|
Set up the space and ideation board. The ideation board has a dedicated pipeline with six columns (not master's board).
|
|
70
70
|
|
|
71
71
|
```bash
|
|
72
|
+
# Compatible with macOS bash 3.2
|
|
72
73
|
project_name="${project_name:-$(basename "$PWD")}"
|
|
73
74
|
date=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
75
|
+
idea_canonical="${project_name}-idea"
|
|
74
76
|
|
|
75
|
-
# Find or create space
|
|
76
|
-
space_id=$(monotask space list 2>/dev/null | awk -F'
|
|
77
|
-
[ -z "$space_id" ] && space_id=$(monotask space create "$project_name" 2
|
|
77
|
+
# Find or create space (by exact name)
|
|
78
|
+
space_id=$(monotask space list 2>/dev/null | awk -F'|' '{gsub(/^ +| +$/,"",$1);gsub(/^ +| +$/,"",$2);if($2==n)print $1}' n="$project_name" | head -1)
|
|
79
|
+
[ -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}')
|
|
78
80
|
[ -z "$space_id" ] && { echo "ERROR: Could not find or create space '$project_name'"; exit 1; }
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
**Memory-first board lookup:** Check memory for `"mastermind-idea board_id"` in namespace `monomind`. If a board ID is returned, use it as `BOARD_ID` and look up the existing column IDs. Otherwise, create the board:
|
|
82
|
-
|
|
83
|
-
```bash
|
|
84
|
-
BOARD_ID=$(monotask board create "Ideas & Innovation" --json | jq -r '.id // empty')
|
|
85
|
-
[ -z "$BOARD_ID" ] && { echo "ERROR: Failed to create Ideas & Innovation board"; exit 1; }
|
|
86
|
-
monotask space boards add "$space_id" "$BOARD_ID" >/dev/null 2>&1 || true
|
|
87
|
-
npx monomind@latest memory store --key "mastermind-idea board_id" --value "$BOARD_ID" --namespace monomind
|
|
88
|
-
|
|
89
|
-
# Create columns in pipeline order
|
|
90
|
-
COL_NEW=$(monotask column create "$BOARD_ID" "New" --json | jq -r '.id')
|
|
91
|
-
COL_EVALUATED=$(monotask column create "$BOARD_ID" "Evaluated" --json | jq -r '.id')
|
|
92
|
-
COL_ELABORATED=$(monotask column create "$BOARD_ID" "Elaborated" --json | jq -r '.id')
|
|
93
|
-
COL_TASKED=$(monotask column create "$BOARD_ID" "Tasked" --json | jq -r '.id')
|
|
94
|
-
COL_ICED=$(monotask column create "$BOARD_ID" "Iced" --json | jq -r '.id')
|
|
95
|
-
COL_REJECTED=$(monotask column create "$BOARD_ID" "Rejected" --json | jq -r '.id')
|
|
96
|
-
```
|
|
97
81
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
82
|
+
# Find existing idea board by canonical name — reuse across runs (same pattern as master Step 6)
|
|
83
|
+
BOARD_ID=$(monotask board list 2>/dev/null | awk -F'|' '{gsub(/^ +| +$/,"",$1);gsub(/^ +| +$/,"",$2);if($2==n)print $1}' n="$idea_canonical" | head -1)
|
|
84
|
+
|
|
85
|
+
if [ -n "$BOARD_ID" ]; then
|
|
86
|
+
echo "Reusing idea board: $BOARD_ID ($idea_canonical)"
|
|
87
|
+
columns=$(monotask column list "$BOARD_ID" --json)
|
|
88
|
+
COL_NEW=$(echo "$columns" | jq -r '.[] | select(.title == "New") | .id' | head -1)
|
|
89
|
+
COL_EVALUATED=$(echo "$columns" | jq -r '.[] | select(.title == "Evaluated") | .id' | head -1)
|
|
90
|
+
COL_ELABORATED=$(echo "$columns"| jq -r '.[] | select(.title == "Elaborated") | .id' | head -1)
|
|
91
|
+
COL_TASKED=$(echo "$columns" | jq -r '.[] | select(.title == "Tasked") | .id' | head -1)
|
|
92
|
+
COL_ICED=$(echo "$columns" | jq -r '.[] | select(.title == "Iced") | .id' | head -1)
|
|
93
|
+
COL_REJECTED=$(echo "$columns" | jq -r '.[] | select(.title == "Rejected") | .id' | head -1)
|
|
94
|
+
[ -z "$COL_NEW" ] && { echo "ERROR: 'New' column missing on board $BOARD_ID — was board created with wrong schema?"; exit 1; }
|
|
95
|
+
[ -z "$COL_EVALUATED" ] && { echo "ERROR: 'Evaluated' column missing on board $BOARD_ID"; exit 1; }
|
|
96
|
+
[ -z "$COL_ELABORATED" ] && { echo "ERROR: 'Elaborated' column missing on board $BOARD_ID"; exit 1; }
|
|
97
|
+
[ -z "$COL_TASKED" ] && { echo "ERROR: 'Tasked' column missing on board $BOARD_ID"; exit 1; }
|
|
98
|
+
[ -z "$COL_ICED" ] && { echo "ERROR: 'Iced' column missing on board $BOARD_ID"; exit 1; }
|
|
99
|
+
[ -z "$COL_REJECTED" ] && { echo "ERROR: 'Rejected' column missing on board $BOARD_ID"; exit 1; }
|
|
100
|
+
else
|
|
101
|
+
echo "Creating idea board: $idea_canonical"
|
|
102
|
+
BOARD_ID=$(monotask board create --space "$space_id" "$idea_canonical" --json 2>/dev/null | jq -r '.id // empty')
|
|
103
|
+
[ -z "$BOARD_ID" ] && { echo "ERROR: Failed to create idea board '$idea_canonical'"; exit 1; }
|
|
104
|
+
monotask space boards add "$space_id" "$BOARD_ID" >/dev/null 2>&1 || true
|
|
105
|
+
COL_NEW=$(monotask column create "$BOARD_ID" "New" --json | jq -r '.id')
|
|
106
|
+
COL_EVALUATED=$(monotask column create "$BOARD_ID" "Evaluated" --json | jq -r '.id')
|
|
107
|
+
COL_ELABORATED=$(monotask column create "$BOARD_ID" "Elaborated" --json | jq -r '.id')
|
|
108
|
+
COL_TASKED=$(monotask column create "$BOARD_ID" "Tasked" --json | jq -r '.id')
|
|
109
|
+
COL_ICED=$(monotask column create "$BOARD_ID" "Iced" --json | jq -r '.id')
|
|
110
|
+
COL_REJECTED=$(monotask column create "$BOARD_ID" "Rejected" --json | jq -r '.id')
|
|
111
|
+
fi
|
|
108
112
|
```
|
|
109
113
|
|
|
110
114
|
**After either branch above, validate and echo all values.** This is the canonical source for Step 4 Task construction.
|
|
@@ -510,44 +514,81 @@ END_ELABORATION_OUTPUT`
|
|
|
510
514
|
})
|
|
511
515
|
```
|
|
512
516
|
|
|
513
|
-
|
|
517
|
+
Wait for all background agents to complete (do not proceed until all — or two, if only one category — return ELABORATION_OUTPUT blocks). Then build `merged_elaboration_json` by merging agent outputs per `card_id` and injecting `category` from `verdicts_output_json`:
|
|
514
518
|
|
|
515
519
|
```bash
|
|
516
|
-
#
|
|
517
|
-
|
|
518
|
-
|
|
520
|
+
# Assign each agent's ELABORATION_OUTPUT JSON array from its output block:
|
|
521
|
+
dev_researcher_json='<ELABORATION_OUTPUT array from the dev researcher agent>'
|
|
522
|
+
dev_codebase_json='<ELABORATION_OUTPUT array from the dev code-explorer agent>'
|
|
523
|
+
ops_researcher_json='<ELABORATION_OUTPUT array from the ops researcher agent>'
|
|
524
|
+
ops_pm_json='<ELABORATION_OUTPUT array from the ops PM agent>'
|
|
525
|
+
# Use '[]' for any track that had no ideas (e.g. if all ideas were dev, set ops_* to '[]')
|
|
526
|
+
|
|
527
|
+
# Merge dev track: join researcher + codebase findings by card_id, inject category from verdicts
|
|
528
|
+
dev_merged=$(jq -n \
|
|
529
|
+
--argjson r "$dev_researcher_json" \
|
|
530
|
+
--argjson c "$dev_codebase_json" \
|
|
531
|
+
--argjson v "$verdicts_output_json" \
|
|
532
|
+
'[$r[] | {card_id: .card_id, blocking_issue: .blocking_issue,
|
|
533
|
+
researcher_findings: .findings,
|
|
534
|
+
codebase_findings: ([$c[] | select(.card_id == .card_id)] | first | .findings // ""),
|
|
535
|
+
category: ([$v[] | select(.card_id == .card_id)] | first | .category // "feature")}]')
|
|
536
|
+
|
|
537
|
+
# Merge ops track: join researcher + PM findings by card_id, inject category
|
|
538
|
+
ops_merged=$(jq -n \
|
|
539
|
+
--argjson r "$ops_researcher_json" \
|
|
540
|
+
--argjson p "$ops_pm_json" \
|
|
541
|
+
--argjson v "$verdicts_output_json" \
|
|
542
|
+
'[$r[] | {card_id: .card_id, blocking_issue: .blocking_issue,
|
|
543
|
+
researcher_findings: .findings,
|
|
544
|
+
pm_findings: ([$p[] | select(.card_id == .card_id)] | first | .findings // ""),
|
|
545
|
+
category: ([$v[] | select(.card_id == .card_id)] | first | .category // "business-operation")}]')
|
|
546
|
+
|
|
547
|
+
# Combine both tracks
|
|
548
|
+
merged_elaboration_json=$(jq -s 'add' <(echo "$dev_merged") <(echo "$ops_merged"))
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
Use process substitution (not a pipeline) so the while loop runs in the main shell and variables remain in scope after `done`:
|
|
552
|
+
|
|
553
|
+
```bash
|
|
554
|
+
while IFS= read -r idea; do
|
|
555
|
+
CARD_ID=$(echo "$idea" | jq -r '.card_id')
|
|
556
|
+
category=$(echo "$idea" | jq -r '.category')
|
|
557
|
+
blocking_issue=$(echo "$idea" | jq -r '.blocking_issue // empty')
|
|
558
|
+
|
|
559
|
+
if [ "$category" = "business-operation" ]; then
|
|
560
|
+
researcher_findings=$(echo "$idea" | jq -r '.researcher_findings')
|
|
561
|
+
pm_findings=$(echo "$idea" | jq -r '.pm_findings')
|
|
562
|
+
monotask card set-description "$BOARD_ID" "$CARD_ID" "## Elaboration Findings
|
|
519
563
|
|
|
520
564
|
### Industry context & benchmarks:
|
|
521
|
-
|
|
565
|
+
$researcher_findings
|
|
522
566
|
|
|
523
567
|
### Feasibility & stakeholder impact:
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
568
|
+
$pm_findings"
|
|
569
|
+
monotask card comment add "$BOARD_ID" "$CARD_ID" "Industry context & benchmarks: $researcher_findings"
|
|
570
|
+
monotask card comment add "$BOARD_ID" "$CARD_ID" "Feasibility & stakeholder impact: $pm_findings"
|
|
571
|
+
else
|
|
572
|
+
researcher_findings=$(echo "$idea" | jq -r '.researcher_findings')
|
|
573
|
+
codebase_findings=$(echo "$idea" | jq -r '.codebase_findings')
|
|
574
|
+
monotask card set-description "$BOARD_ID" "$CARD_ID" "## Elaboration Findings
|
|
528
575
|
|
|
529
576
|
### Edge cases & prior art:
|
|
530
|
-
|
|
577
|
+
$researcher_findings
|
|
531
578
|
|
|
532
579
|
### Codebase constraints:
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
monotask card
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
monotask card
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
# If neither agent found a blocking issue:
|
|
546
|
-
monotask card move "$BOARD_ID" "$CARD_ID" "$COL_ELABORATED" --json
|
|
547
|
-
|
|
548
|
-
# If either agent found a blocking issue (mutually exclusive with the above):
|
|
549
|
-
monotask card move "$BOARD_ID" "$CARD_ID" "$COL_ICED" --json
|
|
550
|
-
monotask card comment add "$BOARD_ID" "$CARD_ID" "Blocked during elaboration: <issue>"
|
|
580
|
+
$codebase_findings"
|
|
581
|
+
monotask card comment add "$BOARD_ID" "$CARD_ID" "Edge cases & prior art: $researcher_findings"
|
|
582
|
+
monotask card comment add "$BOARD_ID" "$CARD_ID" "Codebase constraints: $codebase_findings"
|
|
583
|
+
fi
|
|
584
|
+
|
|
585
|
+
if [ -n "$blocking_issue" ]; then
|
|
586
|
+
monotask card move "$BOARD_ID" "$CARD_ID" "$COL_ICED" --json
|
|
587
|
+
monotask card comment add "$BOARD_ID" "$CARD_ID" "Blocked during elaboration: $blocking_issue"
|
|
588
|
+
else
|
|
589
|
+
monotask card move "$BOARD_ID" "$CARD_ID" "$COL_ELABORATED" --json
|
|
590
|
+
fi
|
|
591
|
+
done < <(echo "$merged_elaboration_json" | jq -c '.[]')
|
|
551
592
|
```
|
|
552
593
|
|
|
553
594
|
#### 6b. User Confirmation Gate
|
|
@@ -556,6 +597,10 @@ monotask card comment add "$BOARD_ID" "$CARD_ID" "Blocked during elaboration: <i
|
|
|
556
597
|
|
|
557
598
|
**Confirm mode only:** If `mode` is `confirm` (default), present a review table of all elaborated ideas to the user.
|
|
558
599
|
|
|
600
|
+
Build the table from `verdicts_output_json` (filtered to `verdict == "evaluated"`). For each row:
|
|
601
|
+
- **Impact** and **Effort** come from `.impact` and `.effort` fields in `verdicts_output_json`
|
|
602
|
+
- **Track**: `feature` or `technical-baseline` → `dev`; `business-operation` → `ops`
|
|
603
|
+
|
|
559
604
|
Print this exact format:
|
|
560
605
|
|
|
561
606
|
```
|
|
@@ -654,7 +699,7 @@ echo "Dev decomp: $dev_decomp_agent | Ops decomp: $ops_decomp_agent"
|
|
|
654
699
|
```
|
|
655
700
|
|
|
656
701
|
**CRITICAL — Variable substitution required for Step 6c Task calls:**
|
|
657
|
-
Before constructing each Task prompt, replace `${brain_context}`, `${prompt}`, `${project_name}`,
|
|
702
|
+
Before constructing each Task prompt, replace `${brain_context}`, `${prompt}`, `${project_name}`, `${dev_ideas_elaborated}`, and `${ops_ideas_elaborated}` with actual literal text. Also substitute the `subagent_type` values: replace `dev_decomp_agent` and `ops_decomp_agent` with the string values echoed by the registry selection above (e.g. `"Software Architect"`). Build those lists from the VERDICTS_OUTPUT and ELABORATION_OUTPUT results:
|
|
658
703
|
|
|
659
704
|
```bash
|
|
660
705
|
# Build elaborated idea lists including card comments (full context for decomposition agents)
|
|
@@ -755,64 +800,91 @@ END_TASKS_OUTPUT`
|
|
|
755
800
|
|
|
756
801
|
**Dev task board** (`feature` / `technical-baseline` → `Implementation Tasks`):
|
|
757
802
|
|
|
758
|
-
|
|
803
|
+
Canonical board name: `${project_name}-tasks-dev`. Find-or-create:
|
|
759
804
|
|
|
760
805
|
```bash
|
|
761
|
-
|
|
762
|
-
monotask
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
monotask column
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
806
|
+
dev_task_canonical="${project_name}-tasks-dev"
|
|
807
|
+
TASK_BOARD_ID=$(monotask board list 2>/dev/null | awk -F'|' '{gsub(/^ +| +$/,"",$1);gsub(/^ +| +$/,"",$2);if($2==n)print $1}' n="$dev_task_canonical" | head -1)
|
|
808
|
+
if [ -n "$TASK_BOARD_ID" ]; then
|
|
809
|
+
echo "Reusing dev task board: $TASK_BOARD_ID ($dev_task_canonical)"
|
|
810
|
+
task_columns=$(monotask column list "$TASK_BOARD_ID" --json)
|
|
811
|
+
TASK_COL_TODO=$(echo "$task_columns" | jq -r '.[] | select(.title=="Todo") | .id' | head -1)
|
|
812
|
+
TASK_COL_BACKLOG=$(echo "$task_columns" | jq -r '.[] | select(.title=="Backlog") | .id' | head -1)
|
|
813
|
+
else
|
|
814
|
+
echo "Creating dev task board: $dev_task_canonical"
|
|
815
|
+
TASK_BOARD_ID=$(monotask board create --space "$space_id" "$dev_task_canonical" --json 2>/dev/null | jq -r '.id // empty')
|
|
816
|
+
[ -z "$TASK_BOARD_ID" ] && { echo "ERROR: Failed to create dev task board"; exit 1; }
|
|
817
|
+
monotask space boards add "$space_id" "$TASK_BOARD_ID" >/dev/null 2>&1 || true
|
|
818
|
+
TASK_COL_BACKLOG=$(monotask column create "$TASK_BOARD_ID" "Backlog" --json | jq -r '.id')
|
|
819
|
+
TASK_COL_TODO=$(monotask column create "$TASK_BOARD_ID" "Todo" --json | jq -r '.id')
|
|
820
|
+
monotask column create "$TASK_BOARD_ID" "In Progress" --json >/dev/null
|
|
821
|
+
monotask column create "$TASK_BOARD_ID" "Human in Loop" --json >/dev/null
|
|
822
|
+
monotask column create "$TASK_BOARD_ID" "Review" --json >/dev/null
|
|
823
|
+
monotask column create "$TASK_BOARD_ID" "Done" --json >/dev/null
|
|
824
|
+
monotask column create "$TASK_BOARD_ID" "Cancelled" --json >/dev/null
|
|
825
|
+
fi
|
|
826
|
+
[ -z "$TASK_BOARD_ID" ] && { echo "ERROR: TASK_BOARD_ID empty — aborting"; exit 1; }
|
|
827
|
+
[ -z "$TASK_COL_TODO" ] && { echo "ERROR: Could not find Todo column on dev task board"; exit 1; }
|
|
780
828
|
```
|
|
781
829
|
|
|
782
830
|
---
|
|
783
831
|
|
|
784
832
|
**Ops task board** (`business-operation` → `Operations Tasks`):
|
|
785
833
|
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
```bash
|
|
789
|
-
OPS_BOARD_ID=$(monotask board create "Operations Tasks" --json | jq -r '.id // empty')
|
|
790
|
-
monotask space boards add "$space_id" "$OPS_BOARD_ID" >/dev/null 2>&1 || true
|
|
791
|
-
npx monomind@latest memory store --key "operations-tasks board_id" --value "$OPS_BOARD_ID" --namespace monomind
|
|
792
|
-
monotask column create "$OPS_BOARD_ID" "Backlog" --json >/dev/null
|
|
793
|
-
monotask column create "$OPS_BOARD_ID" "Todo" --json >/dev/null
|
|
794
|
-
monotask column create "$OPS_BOARD_ID" "In Progress" --json >/dev/null
|
|
795
|
-
monotask column create "$OPS_BOARD_ID" "Review" --json >/dev/null
|
|
796
|
-
monotask column create "$OPS_BOARD_ID" "Human in Loop" --json >/dev/null
|
|
797
|
-
monotask column create "$OPS_BOARD_ID" "Done" --json >/dev/null
|
|
798
|
-
```
|
|
834
|
+
Canonical board name: `${project_name}-tasks-ops`. Find-or-create:
|
|
799
835
|
|
|
800
|
-
Look up and validate column IDs:
|
|
801
836
|
```bash
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
837
|
+
ops_task_canonical="${project_name}-tasks-ops"
|
|
838
|
+
OPS_BOARD_ID=$(monotask board list 2>/dev/null | awk -F'|' '{gsub(/^ +| +$/,"",$1);gsub(/^ +| +$/,"",$2);if($2==n)print $1}' n="$ops_task_canonical" | head -1)
|
|
839
|
+
if [ -n "$OPS_BOARD_ID" ]; then
|
|
840
|
+
echo "Reusing ops task board: $OPS_BOARD_ID ($ops_task_canonical)"
|
|
841
|
+
ops_columns=$(monotask column list "$OPS_BOARD_ID" --json)
|
|
842
|
+
OPS_COL_TODO=$(echo "$ops_columns" | jq -r '.[] | select(.title=="Todo") | .id' | head -1)
|
|
843
|
+
OPS_COL_BACKLOG=$(echo "$ops_columns" | jq -r '.[] | select(.title=="Backlog") | .id' | head -1)
|
|
844
|
+
else
|
|
845
|
+
echo "Creating ops task board: $ops_task_canonical"
|
|
846
|
+
OPS_BOARD_ID=$(monotask board create --space "$space_id" "$ops_task_canonical" --json 2>/dev/null | jq -r '.id // empty')
|
|
847
|
+
[ -z "$OPS_BOARD_ID" ] && { echo "ERROR: Failed to create ops task board"; exit 1; }
|
|
848
|
+
monotask space boards add "$space_id" "$OPS_BOARD_ID" >/dev/null 2>&1 || true
|
|
849
|
+
OPS_COL_BACKLOG=$(monotask column create "$OPS_BOARD_ID" "Backlog" --json | jq -r '.id')
|
|
850
|
+
OPS_COL_TODO=$(monotask column create "$OPS_BOARD_ID" "Todo" --json | jq -r '.id')
|
|
851
|
+
monotask column create "$OPS_BOARD_ID" "In Progress" --json >/dev/null
|
|
852
|
+
monotask column create "$OPS_BOARD_ID" "Human in Loop" --json >/dev/null
|
|
853
|
+
monotask column create "$OPS_BOARD_ID" "Review" --json >/dev/null
|
|
854
|
+
monotask column create "$OPS_BOARD_ID" "Done" --json >/dev/null
|
|
855
|
+
monotask column create "$OPS_BOARD_ID" "Cancelled" --json >/dev/null
|
|
856
|
+
fi
|
|
857
|
+
[ -z "$OPS_BOARD_ID" ] && { echo "ERROR: OPS_BOARD_ID empty — aborting"; exit 1; }
|
|
858
|
+
[ -z "$OPS_COL_TODO" ] && { echo "ERROR: Could not find Todo column on ops task board"; exit 1; }
|
|
808
859
|
```
|
|
809
860
|
|
|
810
861
|
---
|
|
811
862
|
|
|
812
|
-
**
|
|
863
|
+
**Assign TASKS_OUTPUT from each decomposition agent, then merge and iterate:**
|
|
813
864
|
|
|
814
865
|
```bash
|
|
815
|
-
|
|
866
|
+
# Parse the TASKS_OUTPUT block from the dev decomp agent's response and assign:
|
|
867
|
+
dev_tasks_json='<TASKS_OUTPUT JSON array from dev decomp agent, or [] if no dev ideas>'
|
|
868
|
+
# Parse the TASKS_OUTPUT block from the ops decomp agent's response and assign:
|
|
869
|
+
ops_tasks_json='<TASKS_OUTPUT JSON array from ops decomp agent, or [] if no ops ideas>'
|
|
870
|
+
|
|
871
|
+
merged_tasks_json=$(jq -s 'add' <(echo "$dev_tasks_json") <(echo "$ops_tasks_json"))
|
|
872
|
+
|
|
873
|
+
# Use process substitution (not a pipeline) so variables set inside the loop
|
|
874
|
+
# remain in scope after done — needed for the parent-annotation step below.
|
|
875
|
+
# Also initialise the subtask-accumulator map before the loop.
|
|
876
|
+
declare -A parent_subtask_summaries # parent_card_id -> newline-separated task summary lines
|
|
877
|
+
|
|
878
|
+
while IFS= read -r task; do
|
|
879
|
+
parent_card_id=$(echo "$task" | jq -r '.parent_card_id')
|
|
880
|
+
title=$(echo "$task" | jq -r '.title')
|
|
881
|
+
description=$(echo "$task" | jq -r '.description')
|
|
882
|
+
category=$(echo "$task" | jq -r '.category')
|
|
883
|
+
agent=$(echo "$task" | jq -r '.agent')
|
|
884
|
+
task_effort=$(echo "$task" | jq -r '.effort')
|
|
885
|
+
has_prerequisites=$(echo "$task" | jq -r '.has_prerequisites')
|
|
886
|
+
|
|
887
|
+
if [ "$category" = "business-operation" ]; then
|
|
816
888
|
TARGET_BOARD="$OPS_BOARD_ID"
|
|
817
889
|
COL_TARGET=$([ "$has_prerequisites" = "true" ] && echo "$OPS_COL_BACKLOG" || echo "$OPS_COL_TODO")
|
|
818
890
|
BOARD_LABEL="Operations Tasks"
|
|
@@ -823,8 +895,11 @@ else
|
|
|
823
895
|
fi
|
|
824
896
|
|
|
825
897
|
# Inherit impact and effort from parent idea — look up from verdicts_output_json by parent_card_id
|
|
826
|
-
parent_impact=$(echo "$verdicts_output_json" | jq -r --arg id "$parent_card_id" '.[] | select(.card_id == $id) | .impact')
|
|
827
|
-
parent_effort=$(echo "$verdicts_output_json" | jq -r --arg id "$parent_card_id" '.[] | select(.card_id == $id) | .effort')
|
|
898
|
+
parent_impact=$(echo "$verdicts_output_json" | jq -r --arg id "$parent_card_id" '.[] | select(.card_id == $id) | .impact // 5')
|
|
899
|
+
parent_effort=$(echo "$verdicts_output_json" | jq -r --arg id "$parent_card_id" '.[] | select(.card_id == $id) | .effort // 5')
|
|
900
|
+
# Default to 5 if lookup returned empty (e.g. parent_card_id was "UNKNOWN")
|
|
901
|
+
[ -z "$parent_impact" ] && parent_impact=5
|
|
902
|
+
[ -z "$parent_effort" ] && parent_effort=5
|
|
828
903
|
|
|
829
904
|
# Create task card as a proper subtask of the parent idea card (cross-board link)
|
|
830
905
|
# Signature: subtask add <PARENT_BOARD_ID> <PARENT_CARD_ID> <CHILD_BOARD_ID> <COL_ID> <TITLE>
|
|
@@ -841,14 +916,22 @@ PARENT IDEA IMPACT: <parent_impact>/10 PARENT IDEA EFFORT: <parent_effort>/10
|
|
|
841
916
|
CATEGORY: <category>
|
|
842
917
|
PARENT IDEA: <idea title> (card: <parent_card_id> on ideation board)"
|
|
843
918
|
monotask card label add "$TARGET_BOARD" "$TASK_CARD_ID" "mastermind:idea"
|
|
844
|
-
monotask card label add "$TARGET_BOARD" "$TASK_CARD_ID" "category
|
|
919
|
+
monotask card label add "$TARGET_BOARD" "$TASK_CARD_ID" "category:$category"
|
|
920
|
+
|
|
921
|
+
# Accumulate subtask summary for this parent (used in the post-loop annotation step)
|
|
922
|
+
parent_subtask_summaries[$parent_card_id]+=" - $title (agent: $agent, effort: $task_effort/10, board: $BOARD_LABEL)\n"
|
|
923
|
+
|
|
924
|
+
done < <(echo "$merged_tasks_json" | jq -c '.[]')
|
|
845
925
|
```
|
|
846
926
|
|
|
847
|
-
|
|
927
|
+
After the loop, annotate each parent idea card and move it to `Tasked`:
|
|
848
928
|
```bash
|
|
849
|
-
|
|
850
|
-
"
|
|
851
|
-
monotask card
|
|
929
|
+
for parent_card_id in "${!parent_subtask_summaries[@]}"; do
|
|
930
|
+
subtask_list="${parent_subtask_summaries[$parent_card_id]}"
|
|
931
|
+
monotask card comment add "$BOARD_ID" "$parent_card_id" \
|
|
932
|
+
"Subtasks created:\n${subtask_list}"
|
|
933
|
+
monotask card move "$BOARD_ID" "$parent_card_id" "$COL_TASKED" --json
|
|
934
|
+
done
|
|
852
935
|
```
|
|
853
936
|
|
|
854
937
|
For each entry in FLAGGED, move the idea to `Iced`:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monoes/monomindcli",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.17",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Monomind CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
|
|
6
6
|
"main": "dist/src/index.js",
|