@monoes/monomindcli 1.9.16 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/mastermind/_repeat.md +182 -39
- package/.claude/commands/mastermind/architect.md +17 -11
- package/.claude/commands/mastermind/brain.md +4 -0
- package/.claude/commands/mastermind/build.md +4 -0
- package/.claude/commands/mastermind/content.md +4 -0
- package/.claude/commands/mastermind/createorg.md +5 -3
- package/.claude/commands/mastermind/finance.md +4 -0
- package/.claude/commands/mastermind/idea.md +4 -0
- package/.claude/commands/mastermind/marketing.md +4 -0
- package/.claude/commands/mastermind/master.md +100 -46
- package/.claude/commands/mastermind/ops.md +4 -0
- package/.claude/commands/mastermind/release.md +4 -0
- package/.claude/commands/mastermind/research.md +4 -0
- package/.claude/commands/mastermind/review.md +4 -0
- package/.claude/commands/mastermind/runorg.md +5 -3
- package/.claude/commands/mastermind/sales.md +4 -0
- package/.claude/commands/mastermind/techport.md +9 -0
- package/.claude/commands/monomind/do.md +5 -1
- package/.claude/commands/monomind/idea.md +5 -1
- package/.claude/commands/monomind/improve.md +5 -1
- package/.claude/commands/monomind/repeat.md +85 -29
- package/.claude/commands/monomind/review.md +6 -2
- package/.claude/commands/monomind/understand.md +10 -8
- package/.claude/helpers/extras-registry.json +235 -235
- package/.claude/helpers/graphify-freshen.cjs +13 -1
- package/.claude/helpers/hook-handler.cjs +1 -1
- package/.claude/helpers/router.cjs +4 -1
- package/.claude/skills/mastermind/_protocol.md +37 -21
- package/.claude/skills/mastermind/access.md +236 -0
- package/.claude/skills/mastermind/activity.md +191 -0
- package/.claude/skills/mastermind/adapter-manager.md +259 -0
- package/.claude/skills/mastermind/adapters.md +204 -0
- package/.claude/skills/mastermind/agent-detail.md +242 -0
- package/.claude/skills/mastermind/agents.md +178 -0
- package/.claude/skills/mastermind/approval-detail.md +259 -0
- package/.claude/skills/mastermind/approve.md +181 -0
- package/.claude/skills/mastermind/architect.md +24 -8
- package/.claude/skills/mastermind/backup.md +197 -0
- package/.claude/skills/mastermind/bootstrap.md +190 -0
- package/.claude/skills/mastermind/budgets.md +237 -0
- package/.claude/skills/mastermind/companies.md +256 -0
- package/.claude/skills/mastermind/costs.md +151 -0
- package/.claude/skills/mastermind/createorg.md +23 -5
- package/.claude/skills/mastermind/diagnose.md +249 -0
- package/.claude/skills/mastermind/env.md +198 -0
- package/.claude/skills/mastermind/environments.md +250 -0
- package/.claude/skills/mastermind/export.md +324 -0
- package/.claude/skills/mastermind/goal-detail.md +255 -0
- package/.claude/skills/mastermind/goals.md +149 -0
- package/.claude/skills/mastermind/heartbeat.md +164 -0
- package/.claude/skills/mastermind/idea.md +318 -186
- package/.claude/skills/mastermind/import.md +281 -0
- package/.claude/skills/mastermind/inbox.md +214 -0
- package/.claude/skills/mastermind/instance-settings.md +315 -0
- package/.claude/skills/mastermind/instance.md +231 -0
- package/.claude/skills/mastermind/invite-landing.md +227 -0
- package/.claude/skills/mastermind/invites.md +254 -0
- package/.claude/skills/mastermind/issue-detail.md +291 -0
- package/.claude/skills/mastermind/issues.md +235 -0
- package/.claude/skills/mastermind/join-queue.md +170 -0
- package/.claude/skills/mastermind/liveness.md +392 -0
- package/.claude/skills/mastermind/memory.md +321 -0
- package/.claude/skills/mastermind/my-issues.md +146 -0
- package/.claude/skills/mastermind/new-agent.md +241 -0
- package/.claude/skills/mastermind/org-chart.md +207 -0
- package/.claude/skills/mastermind/org-settings.md +217 -0
- package/.claude/skills/mastermind/plan-to-tasks.md +136 -0
- package/.claude/skills/mastermind/plugin-manager.md +241 -0
- package/.claude/skills/mastermind/plugin-settings.md +273 -0
- package/.claude/skills/mastermind/plugins.md +190 -0
- package/.claude/skills/mastermind/profile.md +187 -0
- package/.claude/skills/mastermind/project-detail.md +249 -0
- package/.claude/skills/mastermind/project-workspace.md +244 -0
- package/.claude/skills/mastermind/projects.md +164 -0
- package/.claude/skills/mastermind/routine-detail.md +253 -0
- package/.claude/skills/mastermind/routines.md +202 -0
- package/.claude/skills/mastermind/runorg.md +74 -9
- package/.claude/skills/mastermind/search.md +186 -0
- package/.claude/skills/mastermind/secrets.md +199 -0
- package/.claude/skills/mastermind/skills.md +156 -0
- package/.claude/skills/mastermind/tasks.md +149 -0
- package/.claude/skills/mastermind/techport.md +5 -5
- package/.claude/skills/mastermind/threads.md +259 -0
- package/.claude/skills/mastermind/tree-control.md +250 -0
- package/.claude/skills/mastermind/wiki.md +314 -0
- package/.claude/skills/mastermind/workspace-detail.md +317 -0
- package/.claude/skills/mastermind/workspaces.md +261 -0
- package/.claude/skills/mastermind/worktree.md +187 -0
- package/dist/src/init/executor.js +8 -8
- package/dist/src/init/executor.js.map +1 -1
- package/dist/src/init/statusline-generator.d.ts.map +1 -1
- package/dist/src/init/statusline-generator.js +12 -0
- package/dist/src/init/statusline-generator.js.map +1 -1
- package/dist/src/ui/.monomind/data/ranked-context.json +1 -1
- package/dist/src/ui/.monomind/loops/mastermind-review-1778664132789.json +16 -0
- package/dist/src/ui/.monomind/sessions/current.json +5 -5
- package/dist/src/ui/.monomind/sessions/session-1776778451399.json +15 -0
- package/dist/src/ui/dashboard.html +3030 -181
- package/dist/src/ui/data/mastermind-events.jsonl +8 -0
- package/dist/src/ui/data/mastermind-sessions.json +1 -0
- package/dist/src/ui/server.mjs +738 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/.claude/skills/.monomind/data/ranked-context.json +0 -5
- package/.claude/skills/.monomind/sessions/current.json +0 -13
- package/.claude/skills/.monomind/sessions/session-1777829336455.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777831614725.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777832095857.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777839814183.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777841847131.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777843309463.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777880867159.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777881884593.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777884090471.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777884808221.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777885672155.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777886852818.json +0 -15
- package/.claude/skills/.monomind/sessions/session-1777896532690.json +0 -15
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mastermind-agent-detail
|
|
3
|
+
description: Mastermind agent-detail — deep per-agent inspection: show config, run history, budget usage, heartbeat status, assigned skills, and reset/reconfigure a single agent within an org.
|
|
4
|
+
type: domain-skill
|
|
5
|
+
default_mode: auto
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Mastermind Agent Detail
|
|
9
|
+
|
|
10
|
+
This skill is invoked by `mastermind:agent-detail` or directly via `/mastermind:agent-detail`.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
- `brain_context`: BRAIN CONTEXT block (injected by command, or loaded below if standalone)
|
|
17
|
+
- `org_name`: org the agent belongs to (required)
|
|
18
|
+
- `agent_id`: agent slug/id (required)
|
|
19
|
+
- `action`: show | runs | config | budget | heartbeat | skills | reset
|
|
20
|
+
- `days`: lookback window for run history (default 7)
|
|
21
|
+
- `caller`: command | master
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Step 0 — Brain Load (standalone only)
|
|
26
|
+
|
|
27
|
+
If `caller` is not "command", load brain context following _protocol.md Brain Load Procedure with namespace: `ops`.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Step 1 — Load Agent Data
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
orgFile=".monomind/orgs/${org_name}.json"
|
|
35
|
+
[ ! -f "$orgFile" ] && { echo "ERROR: Org '${org_name}' not found."; exit 1; }
|
|
36
|
+
|
|
37
|
+
agentDef=$(jq -r --arg id "$agent_id" '.roles[] | select(.id == $id)' "$orgFile")
|
|
38
|
+
[ -z "$agentDef" ] && { echo "ERROR: Agent '$agent_id' not found in org '$org_name'."; exit 1; }
|
|
39
|
+
|
|
40
|
+
stateFile=".monomind/orgs/${org_name}-state.json"
|
|
41
|
+
agentState="{}"
|
|
42
|
+
[ -f "$stateFile" ] && agentState=$(jq -r --arg id "$agent_id" '.agents[$id] // {}' "$stateFile")
|
|
43
|
+
|
|
44
|
+
activityFile=".monomind/orgs/${org_name}-activity.jsonl"
|
|
45
|
+
days=${days:-7}
|
|
46
|
+
cutoff=$(date -u -v-${days}d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "${days} days ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || echo "")
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Step 2 — Execute Action
|
|
52
|
+
|
|
53
|
+
### show (default)
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
echo "AGENT DETAIL — $agent_id @ $org_name"
|
|
57
|
+
echo "────────────────────────────────────────────────────────"
|
|
58
|
+
|
|
59
|
+
echo "$agentDef" | jq -r '
|
|
60
|
+
" ID: \(.id)",
|
|
61
|
+
" Title: \(.title // "-")",
|
|
62
|
+
" Reports to: \(.reports_to // "(top)")",
|
|
63
|
+
" Governance: \(.governance // "inherit")",
|
|
64
|
+
" Model: \(.adapter.model // "default")",
|
|
65
|
+
" Max tokens: \((.adapter.max_tokens // 8192) | tostring)",
|
|
66
|
+
" Heartbeat: \(if (.heartbeat.enabled // false) then "enabled (" + ((.heartbeat.interval // 900) | tostring) + "s)" else "disabled" end)"
|
|
67
|
+
'
|
|
68
|
+
|
|
69
|
+
status=$(echo "$agentState" | jq -r '.status // "unknown"')
|
|
70
|
+
lastRun=$(echo "$agentState" | jq -r '.last_run // "-"')
|
|
71
|
+
totalRuns=$(echo "$agentState" | jq -r '.total_runs // 0')
|
|
72
|
+
tokenUsed=$(echo "$agentState" | jq -r '.tokens_used // 0')
|
|
73
|
+
|
|
74
|
+
echo ""
|
|
75
|
+
echo " Status: $status"
|
|
76
|
+
echo " Last run: $lastRun"
|
|
77
|
+
echo " Total runs: $totalRuns"
|
|
78
|
+
echo " Tokens used: $tokenUsed"
|
|
79
|
+
|
|
80
|
+
# Skills
|
|
81
|
+
skillCount=$(echo "$agentDef" | jq -r '(.skills // []) | length')
|
|
82
|
+
echo ""
|
|
83
|
+
echo " Skills: $skillCount assigned"
|
|
84
|
+
echo "$agentDef" | jq -r '(.skills // [])[] | " · \(.)"'
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### runs
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
echo "RUN HISTORY — $agent_id (last ${days} days)"
|
|
91
|
+
echo "────────────────────────────────────────────────────────"
|
|
92
|
+
printf "%-26s %-10s %-8s %-12s %s\n" "TIMESTAMP" "STATUS" "TOKENS" "DURATION" "TASK"
|
|
93
|
+
echo "────────────────────────────────────────────────────────"
|
|
94
|
+
|
|
95
|
+
found=0
|
|
96
|
+
if [ -f "$activityFile" ]; then
|
|
97
|
+
while IFS= read -r line; do
|
|
98
|
+
agId=$(echo "$line" | jq -r '.agent // ""')
|
|
99
|
+
[ "$agId" != "$agent_id" ] && continue
|
|
100
|
+
ts=$(echo "$line" | jq -r '.ts // ""')
|
|
101
|
+
[ -n "$cutoff" ] && [ "$ts" \< "$cutoff" ] && continue
|
|
102
|
+
st=$(echo "$line" | jq -r '.status // "-"')
|
|
103
|
+
tok=$(echo "$line" | jq -r '.tokens // "-"')
|
|
104
|
+
dur=$(echo "$line" | jq -r '.duration_ms // "-"')
|
|
105
|
+
task=$(echo "$line" | jq -r '.task // "-"' | cut -c1-40)
|
|
106
|
+
printf "%-26s %-10s %-8s %-12s %s\n" "$ts" "$st" "$tok" "${dur}ms" "$task"
|
|
107
|
+
found=$((found + 1))
|
|
108
|
+
done < "$activityFile"
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
[ "$found" -eq 0 ] && echo " No runs in the last $days days."
|
|
112
|
+
|
|
113
|
+
# 7-day summary bar
|
|
114
|
+
echo ""
|
|
115
|
+
echo "ACTIVITY SUMMARY (last 7 days)"
|
|
116
|
+
for d in 6 5 4 3 2 1 0; do
|
|
117
|
+
dayLabel=$(date -u -v-${d}d +%Y-%m-%d 2>/dev/null || date -u -d "${d} days ago" +%Y-%m-%d 2>/dev/null || echo "?")
|
|
118
|
+
count=0
|
|
119
|
+
if [ -f "$activityFile" ]; then
|
|
120
|
+
count=$(grep "\"agent\":\"${agent_id}\"" "$activityFile" | grep "\"$dayLabel" | wc -l | tr -d ' ')
|
|
121
|
+
fi
|
|
122
|
+
bar=$(printf '%0.s█' $(seq 1 $((count > 10 ? 10 : count))))
|
|
123
|
+
printf " %s %-10s %s\n" "$dayLabel" "$bar" "($count)"
|
|
124
|
+
done
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### config
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
echo "ADAPTER CONFIG — $agent_id"
|
|
131
|
+
echo "────────────────────────────────────────────────────────"
|
|
132
|
+
echo "$agentDef" | jq '.adapter // {"model":"default","max_tokens":8192}'
|
|
133
|
+
echo ""
|
|
134
|
+
echo "RUNTIME CONFIG"
|
|
135
|
+
echo "$agentDef" | jq '.runtimeConfig // {}'
|
|
136
|
+
echo ""
|
|
137
|
+
echo "HEARTBEAT CONFIG"
|
|
138
|
+
echo "$agentDef" | jq '.heartbeat // {"enabled":false}'
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### budget
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
echo "BUDGET — $agent_id @ $org_name"
|
|
145
|
+
echo "────────────────────────────────────────────────────────"
|
|
146
|
+
|
|
147
|
+
orgBudget=$(jq -r '.budget_tokens // 0' "$orgFile")
|
|
148
|
+
agentBudget=$(echo "$agentDef" | jq -r '.budget_tokens // null')
|
|
149
|
+
tokensUsed=$(echo "$agentState" | jq -r '.tokens_used // 0')
|
|
150
|
+
|
|
151
|
+
echo " Org budget: $orgBudget tokens/day"
|
|
152
|
+
[ "$agentBudget" != "null" ] && echo " Agent cap: $agentBudget tokens" || echo " Agent cap: (inherits org)"
|
|
153
|
+
echo " Used today: $tokensUsed tokens"
|
|
154
|
+
|
|
155
|
+
if [ "$orgBudget" -gt 0 ] && [ "$tokensUsed" -gt 0 ]; then
|
|
156
|
+
pct=$((tokensUsed * 100 / orgBudget))
|
|
157
|
+
echo " Utilization: ${pct}%"
|
|
158
|
+
[ "$pct" -ge 80 ] && echo " WARNING: Agent has used ${pct}% of org daily budget."
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
# Per-day breakdown from activity
|
|
162
|
+
echo ""
|
|
163
|
+
echo "DAILY USAGE (last 7 days)"
|
|
164
|
+
for d in 6 5 4 3 2 1 0; do
|
|
165
|
+
dayLabel=$(date -u -v-${d}d +%Y-%m-%d 2>/dev/null || date -u -d "${d} days ago" +%Y-%m-%d 2>/dev/null || echo "?")
|
|
166
|
+
dayTok=0
|
|
167
|
+
if [ -f "$activityFile" ]; then
|
|
168
|
+
dayTok=$(grep "\"agent\":\"${agent_id}\"" "$activityFile" | grep "\"$dayLabel" | \
|
|
169
|
+
jq -rs '[.[].tokens // 0] | add // 0' 2>/dev/null || echo 0)
|
|
170
|
+
fi
|
|
171
|
+
printf " %s %s tokens\n" "$dayLabel" "$dayTok"
|
|
172
|
+
done
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### heartbeat
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
echo "HEARTBEAT CONFIG — $agent_id"
|
|
179
|
+
echo "────────────────────────────────────────────────────────"
|
|
180
|
+
enabled=$(echo "$agentDef" | jq -r '.heartbeat.enabled // false')
|
|
181
|
+
interval=$(echo "$agentDef" | jq -r '.heartbeat.interval // 900')
|
|
182
|
+
lastHb=$(echo "$agentState" | jq -r '.last_heartbeat // "-"')
|
|
183
|
+
|
|
184
|
+
echo " Enabled: $enabled"
|
|
185
|
+
echo " Interval: ${interval}s"
|
|
186
|
+
echo " Last beat: $lastHb"
|
|
187
|
+
echo ""
|
|
188
|
+
echo "To toggle: /mastermind:instance --action toggle-heartbeat --org $org_name --agent-id $agent_id"
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### skills
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
echo "SKILLS — $agent_id"
|
|
195
|
+
echo "────────────────────────────────────────────────────────"
|
|
196
|
+
skillList=$(echo "$agentDef" | jq -r '(.skills // [])[]' 2>/dev/null)
|
|
197
|
+
|
|
198
|
+
if [ -z "$skillList" ]; then
|
|
199
|
+
echo " No skills assigned. Use /mastermind:skills to map skills to this agent."
|
|
200
|
+
else
|
|
201
|
+
while IFS= read -r sk; do
|
|
202
|
+
skillFile=".claude/skills/${sk//:///}.md"
|
|
203
|
+
[ -f "$skillFile" ] && desc=$(head -5 "$skillFile" | grep 'description:' | sed 's/description: //') || desc="(skill file not found)"
|
|
204
|
+
printf " %-30s %s\n" "$sk" "$desc"
|
|
205
|
+
done <<< "$skillList"
|
|
206
|
+
fi
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### reset
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
echo "Resetting agent state for '$agent_id'…"
|
|
213
|
+
|
|
214
|
+
tmp="${stateFile}.tmp"
|
|
215
|
+
if [ -f "$stateFile" ]; then
|
|
216
|
+
jq --arg id "$agent_id" \
|
|
217
|
+
'.agents[$id] = {"status":"idle","total_runs":0,"tokens_used":0,"last_run":null,"last_heartbeat":null}' \
|
|
218
|
+
"$stateFile" > "$tmp" && mv "$tmp" "$stateFile"
|
|
219
|
+
fi
|
|
220
|
+
|
|
221
|
+
echo "Agent '$agent_id' state reset. Run history is preserved in activity log."
|
|
222
|
+
echo "To reconfigure adapter: edit the role in /mastermind:org --action show (then edit org config)."
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Step 3 — Return Output
|
|
228
|
+
|
|
229
|
+
```yaml
|
|
230
|
+
domain: ops
|
|
231
|
+
status: complete
|
|
232
|
+
action: <action>
|
|
233
|
+
org: <org_name>
|
|
234
|
+
agent_id: <agent_id>
|
|
235
|
+
agent_status: <status>
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Step 4 — Brain Write (standalone only)
|
|
241
|
+
|
|
242
|
+
If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mastermind-agents
|
|
3
|
+
description: Mastermind agents — list, inspect, hire, pause, and remove agents in a running org. Shows status, last heartbeat, adapter config, and burn rate per agent.
|
|
4
|
+
type: domain-skill
|
|
5
|
+
default_mode: confirm
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Mastermind Agents
|
|
9
|
+
|
|
10
|
+
This skill is invoked by `mastermind:agents` or directly via `/mastermind:agents`.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
- `brain_context`: BRAIN CONTEXT block (injected by command, or loaded below if standalone)
|
|
17
|
+
- `org_name`: org to inspect (optional — lists all orgs if omitted)
|
|
18
|
+
- `action`: list | hire | pause | resume | remove | inspect
|
|
19
|
+
- `agent_id`: role id or agent slug (required for inspect/pause/resume/remove)
|
|
20
|
+
- `caller`: command | master
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Step 0 — Brain Load (standalone only)
|
|
25
|
+
|
|
26
|
+
If `caller` is not "command", load brain context following _protocol.md Brain Load Procedure with namespace: `ops`.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Step 1 — Resolve Org
|
|
31
|
+
|
|
32
|
+
If `org_name` is provided, load `.monomind/orgs/<org_name>.json`. Otherwise list all orgs:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
ls .monomind/orgs/*.json 2>/dev/null | xargs -I{} basename {} .json
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
If no orgs exist, print: "No orgs found. Run /mastermind:createorg to define one."
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Step 2 — Execute Action
|
|
43
|
+
|
|
44
|
+
### list (default)
|
|
45
|
+
|
|
46
|
+
Display all agents in the org with status from state file:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
orgFile=".monomind/orgs/${org_name}.json"
|
|
50
|
+
stateFile=".monomind/orgs/${org_name}-state.json"
|
|
51
|
+
|
|
52
|
+
jq -r '.roles[] | "• [\(.id)] \(.title) agent=\(.agent_type) reports_to=\(.reports_to // "none")"' "$orgFile"
|
|
53
|
+
|
|
54
|
+
# Overlay runtime status from state file if present
|
|
55
|
+
if [ -f "$stateFile" ]; then
|
|
56
|
+
echo ""
|
|
57
|
+
echo "RUNTIME STATUS:"
|
|
58
|
+
jq -r '.agents // {} | to_entries[] | " \(.key): \(.value.status // "unknown") last_beat=\(.value.last_heartbeat // "never")"' "$stateFile" 2>/dev/null || true
|
|
59
|
+
fi
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Render as table:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
AGENTS — org: <org_name>
|
|
66
|
+
──────────────────────────────────────────────────────
|
|
67
|
+
ID TITLE AGENT TYPE STATUS LAST HEARTBEAT
|
|
68
|
+
boss CEO / Boss coordinator running 2 min ago
|
|
69
|
+
content-writer Content Writer Content Creator idle 8 min ago
|
|
70
|
+
reviewer Content Reviewer reviewer waiting 8 min ago
|
|
71
|
+
...
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### inspect
|
|
75
|
+
|
|
76
|
+
Show full config + responsibilities + communication edges for a single agent:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
jq --arg id "$agent_id" '.roles[] | select(.id == $id)' "$orgFile"
|
|
80
|
+
jq --arg id "$agent_id" '.communication[] | select(.from == $id or .to == $id)' "$orgFile"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### hire
|
|
84
|
+
|
|
85
|
+
Add a new role to the org. Prompt the user for:
|
|
86
|
+
- `id` (slug, e.g. `seo-lead`), `title` (display name), `agent_type` (from mapping table in createorg.md), `responsibilities` (comma-separated), `reports_to` (role id or null)
|
|
87
|
+
|
|
88
|
+
**Adapter/model selection** — present this picker:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
ADAPTER / MODEL
|
|
92
|
+
───────────────
|
|
93
|
+
Available Claude models:
|
|
94
|
+
1. claude-sonnet-4-6 → balanced capability + speed (Recommended)
|
|
95
|
+
2. claude-opus-4-7 → highest capability, slower
|
|
96
|
+
3. claude-haiku-4-5 → fastest, lowest cost
|
|
97
|
+
|
|
98
|
+
Enter choice [1]:
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Set `adapter_config.model` from selection. Default: `claude-sonnet-4-6`.
|
|
102
|
+
|
|
103
|
+
Append to `.monomind/orgs/<org_name>.json` roles array using jq:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# model from adapter picker (default: claude-sonnet-4-6)
|
|
107
|
+
adapter_model="${selected_model:-claude-sonnet-4-6}"
|
|
108
|
+
|
|
109
|
+
tmp="${orgFile}.tmp"
|
|
110
|
+
jq --arg id "$agent_id" \
|
|
111
|
+
--arg title "$title" \
|
|
112
|
+
--arg agent_type "$agent_type" \
|
|
113
|
+
--arg reports_to "${reports_to:-}" \
|
|
114
|
+
--arg model "$adapter_model" \
|
|
115
|
+
--argjson resp "$(echo "$responsibilities" | jq -R 'split(",") | map(ltrimstr(" "))')" \
|
|
116
|
+
'.roles += [{"id":$id,"title":$title,"agent_type":$agent_type,
|
|
117
|
+
"responsibilities":$resp,
|
|
118
|
+
"reports_to":($reports_to|if .=="" then null else . end),
|
|
119
|
+
"adapter_config":{"model":$model,"max_tokens":8192}}]' \
|
|
120
|
+
"$orgFile" > "$tmp" && mv "$tmp" "$orgFile"
|
|
121
|
+
echo "Hired: $title ($agent_type) → adapter: $adapter_model"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Then emit `org:agent:hired` event to dashboard:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
128
|
+
CTRL_URL=$(jq -r '.url // "http://localhost:4242"' "$REPO_ROOT/.monomind/control.json" 2>/dev/null || echo "http://localhost:4242")
|
|
129
|
+
curl -s -X POST "${CTRL_URL}/api/mastermind/event" \
|
|
130
|
+
-H "Content-Type: application/json" \
|
|
131
|
+
-d "$(jq -cn --arg org "$org_name" --arg role "$agent_id" --arg title "$title" \
|
|
132
|
+
'{type:"org:agent:hired",org:$org,role:$role,title:$title,ts:(now*1000|floor)}')" || true
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### pause / resume
|
|
136
|
+
|
|
137
|
+
Update state file:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
stateFile=".monomind/orgs/${org_name}-state.json"
|
|
141
|
+
[ ! -f "$stateFile" ] && echo '{"agents":{}}' > "$stateFile"
|
|
142
|
+
tmp="${stateFile}.tmp"
|
|
143
|
+
jq --arg id "$agent_id" --arg status "paused" \
|
|
144
|
+
'.agents[$id].status = $status | .agents[$id].updated_at = (now|todate)' \
|
|
145
|
+
"$stateFile" > "$tmp" && mv "$tmp" "$stateFile"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Emit `org:agent:paused` / `org:agent:resumed` event.
|
|
149
|
+
|
|
150
|
+
### remove
|
|
151
|
+
|
|
152
|
+
Confirm with user, then remove role from org config:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
tmp="${orgFile}.tmp"
|
|
156
|
+
jq --arg id "$agent_id" '.roles = [.roles[] | select(.id != $id)] | .communication = [.communication[] | select(.from != $id and .to != $id)]' \
|
|
157
|
+
"$orgFile" > "$tmp" && mv "$tmp" "$orgFile"
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Step 3 — Return Output
|
|
163
|
+
|
|
164
|
+
```yaml
|
|
165
|
+
domain: ops
|
|
166
|
+
status: complete
|
|
167
|
+
action: <action>
|
|
168
|
+
org: <org_name>
|
|
169
|
+
agents_count: <N>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Print summary and any suggested next actions (e.g. "Run /mastermind:heartbeat to trigger a manual heartbeat for this agent").
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Step 4 — Brain Write (standalone only)
|
|
177
|
+
|
|
178
|
+
If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mastermind-approval-detail
|
|
3
|
+
description: Mastermind approval-detail — deep inspection and action on a single approval request. View approval metadata, payload, comments, linked issues, and perform approve/reject/revision/resubmit actions. Mirrors ApprovalDetail.tsx.
|
|
4
|
+
type: domain-skill
|
|
5
|
+
default_mode: confirm
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Mastermind Approval Detail
|
|
9
|
+
|
|
10
|
+
This skill is invoked by `mastermind:approval-detail` or directly via `/mastermind:approval-detail`.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
- `brain_context`: BRAIN CONTEXT block (injected by command, or loaded below if standalone)
|
|
17
|
+
- `org_name`: org the approval belongs to (required)
|
|
18
|
+
- `approval_id`: approval id or short prefix (required)
|
|
19
|
+
- `action`: show | comments | linked-issues | comment | approve | reject | request-revision | resubmit
|
|
20
|
+
- `comment_body`: comment text (for comment action)
|
|
21
|
+
- `caller`: command | master
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Approval Statuses
|
|
26
|
+
|
|
27
|
+
| Status | Meaning |
|
|
28
|
+
|--------|---------|
|
|
29
|
+
| `pending` | Awaiting review — actionable |
|
|
30
|
+
| `approved` | Approved and resolved |
|
|
31
|
+
| `rejected` | Rejected and resolved |
|
|
32
|
+
| `revision_requested` | Agent asked to revise — still actionable |
|
|
33
|
+
| `resubmitted` | Agent resubmitted after revision |
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Approval Types
|
|
38
|
+
|
|
39
|
+
| Type | Description |
|
|
40
|
+
|------|-------------|
|
|
41
|
+
| `budget_override_required` | Agent needs to exceed budget cap |
|
|
42
|
+
| `agent_hire` | Agent is requesting to hire another agent |
|
|
43
|
+
| `tool_grant` | Agent requests a new tool permission |
|
|
44
|
+
| `action_confirm` | Agent requests confirmation before a destructive action |
|
|
45
|
+
| `custom` | Plugin-defined approval type |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Step 0 — Brain Load (standalone only)
|
|
50
|
+
|
|
51
|
+
If `caller` is not "command", load brain context following _protocol.md Brain Load Procedure with namespace: `ops`.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Step 1 — Load Approval
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
orgFile=".monomind/orgs/${org_name}.json"
|
|
59
|
+
[ ! -f "$orgFile" ] && { echo "ERROR: Org '${org_name}' not found."; exit 1; }
|
|
60
|
+
|
|
61
|
+
approvalsFile=".monomind/orgs/${org_name}-approvals.json"
|
|
62
|
+
[ ! -f "$approvalsFile" ] && { echo "ERROR: No approvals file for org '${org_name}'."; exit 1; }
|
|
63
|
+
|
|
64
|
+
# Find approval by full id or prefix
|
|
65
|
+
approvalDef=$(jq -r --arg id "$approval_id" \
|
|
66
|
+
'.approvals[] | select(.id == $id or (.id | startswith($id)))' \
|
|
67
|
+
"$approvalsFile" | head -1)
|
|
68
|
+
[ -z "$approvalDef" ] && { echo "ERROR: Approval '${approval_id}' not found."; exit 1; }
|
|
69
|
+
|
|
70
|
+
approvalId=$(echo "$approvalDef" | jq -r '.id')
|
|
71
|
+
commentsFile=".monomind/orgs/${org_name}-approval-comments.jsonl"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Step 2 — Execute Action
|
|
77
|
+
|
|
78
|
+
### show (default)
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
echo "APPROVAL — ${approvalId}"
|
|
82
|
+
echo "────────────────────────────────────────────────────────"
|
|
83
|
+
|
|
84
|
+
echo "$approvalDef" | jq -r '
|
|
85
|
+
" ID: \(.id)",
|
|
86
|
+
" Type: \(.type // "unknown")",
|
|
87
|
+
" Status: \(.status // "pending")",
|
|
88
|
+
" Agent: \(.agentId // "(unknown)")",
|
|
89
|
+
" Created: \(.createdAt // "-")",
|
|
90
|
+
" Resolved: \(.resolvedAt // "-")"
|
|
91
|
+
'
|
|
92
|
+
|
|
93
|
+
echo ""
|
|
94
|
+
echo "PAYLOAD"
|
|
95
|
+
echo "────────────────────────────────────────────────────────"
|
|
96
|
+
echo "$approvalDef" | jq -r '.payload // {}' | jq .
|
|
97
|
+
|
|
98
|
+
status=$(echo "$approvalDef" | jq -r '.status // "pending"')
|
|
99
|
+
if [ "$status" = "pending" ] || [ "$status" = "revision_requested" ]; then
|
|
100
|
+
echo ""
|
|
101
|
+
echo "ACTIONS AVAILABLE"
|
|
102
|
+
echo " approve: --action approve"
|
|
103
|
+
echo " reject: --action reject"
|
|
104
|
+
echo " request revision: --action request-revision"
|
|
105
|
+
echo " add comment: --action comment --comment-body 'your notes'"
|
|
106
|
+
fi
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### comments
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
echo "COMMENTS — ${approvalId}"
|
|
113
|
+
echo "────────────────────────────────────────────────────────"
|
|
114
|
+
|
|
115
|
+
if [ ! -f "$commentsFile" ]; then
|
|
116
|
+
echo " No comments."
|
|
117
|
+
else
|
|
118
|
+
count=$(grep -c "\"approvalId\":\"${approvalId}\"" "$commentsFile" 2>/dev/null || echo 0)
|
|
119
|
+
echo " Total: $count"
|
|
120
|
+
echo ""
|
|
121
|
+
grep "\"approvalId\":\"${approvalId}\"" "$commentsFile" 2>/dev/null | while IFS= read -r line; do
|
|
122
|
+
author=$(echo "$line" | jq -r '.authorType // "user"')
|
|
123
|
+
body=$(echo "$line" | jq -r '.body // ""')
|
|
124
|
+
ts=$(echo "$line" | jq -r '.createdAt // "-"')
|
|
125
|
+
echo " [$ts] ($author)"
|
|
126
|
+
echo " $body"
|
|
127
|
+
echo ""
|
|
128
|
+
done
|
|
129
|
+
fi
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### linked-issues
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
issuesFile=".monomind/orgs/${org_name}-issues.json"
|
|
136
|
+
echo "LINKED ISSUES — ${approvalId}"
|
|
137
|
+
echo "────────────────────────────────────────────────────────"
|
|
138
|
+
printf "%-24s %-12s %s\n" "ID" "STATUS" "TITLE"
|
|
139
|
+
echo "────────────────────────────────────────────────────────"
|
|
140
|
+
|
|
141
|
+
linkedIds=$(echo "$approvalDef" | jq -r '(.linkedIssueIds // [])[]')
|
|
142
|
+
if [ -z "$linkedIds" ]; then
|
|
143
|
+
echo " No linked issues."
|
|
144
|
+
else
|
|
145
|
+
if [ -f "$issuesFile" ]; then
|
|
146
|
+
echo "$linkedIds" | while read -r iid; do
|
|
147
|
+
row=$(jq -r --arg id "$iid" '.issues[] | select(.id == $id) | [.id, (.status // "open"), (.title // "(no title)")] | @tsv' "$issuesFile")
|
|
148
|
+
[ -n "$row" ] && echo "$row" | while IFS=$'\t' read -r id st title; do
|
|
149
|
+
printf "%-24s %-12s %s\n" "$id" "$st" "$title"
|
|
150
|
+
done || printf "%-24s %-12s %s\n" "$iid" "(unknown)" "(not found)"
|
|
151
|
+
done
|
|
152
|
+
fi
|
|
153
|
+
fi
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### comment
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
[ -z "$comment_body" ] && { echo "ERROR: --comment-body required."; exit 1; }
|
|
160
|
+
|
|
161
|
+
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
162
|
+
entry=$(jq -n \
|
|
163
|
+
--arg aid "$approvalId" \
|
|
164
|
+
--arg org "$org_name" \
|
|
165
|
+
--arg body "$comment_body" \
|
|
166
|
+
--arg ts "$ts" \
|
|
167
|
+
'{"approvalId":$aid,"org":$org,"authorType":"operator","body":$body,"createdAt":$ts}')
|
|
168
|
+
|
|
169
|
+
echo "$entry" >> "$commentsFile"
|
|
170
|
+
|
|
171
|
+
echo "Comment added to approval ${approvalId}."
|
|
172
|
+
echo " Body: $comment_body"
|
|
173
|
+
echo " At: $ts"
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### approve
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
status=$(echo "$approvalDef" | jq -r '.status // "pending"')
|
|
180
|
+
if [ "$status" != "pending" ] && [ "$status" != "revision_requested" ]; then
|
|
181
|
+
echo "ERROR: Approval is in status '$status' — cannot approve."
|
|
182
|
+
exit 1
|
|
183
|
+
fi
|
|
184
|
+
|
|
185
|
+
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
186
|
+
tmp="${approvalsFile}.tmp"
|
|
187
|
+
jq --arg id "$approvalId" --arg ts "$ts" \
|
|
188
|
+
'.approvals = [.approvals[] | if .id == $id then
|
|
189
|
+
.status = "approved" | .resolvedAt = $ts | .resolvedBy = "operator"
|
|
190
|
+
else . end]' \
|
|
191
|
+
"$approvalsFile" > "$tmp" && mv "$tmp" "$approvalsFile"
|
|
192
|
+
|
|
193
|
+
echo "Approval '${approvalId}' APPROVED."
|
|
194
|
+
echo " Resolved at: $ts"
|
|
195
|
+
echo " Agent will be notified to proceed."
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### reject
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
202
|
+
tmp="${approvalsFile}.tmp"
|
|
203
|
+
jq --arg id "$approvalId" --arg ts "$ts" \
|
|
204
|
+
'.approvals = [.approvals[] | if .id == $id then
|
|
205
|
+
.status = "rejected" | .resolvedAt = $ts | .resolvedBy = "operator"
|
|
206
|
+
else . end]' \
|
|
207
|
+
"$approvalsFile" > "$tmp" && mv "$tmp" "$approvalsFile"
|
|
208
|
+
|
|
209
|
+
echo "Approval '${approvalId}' REJECTED."
|
|
210
|
+
echo " Resolved at: $ts"
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### request-revision
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
217
|
+
tmp="${approvalsFile}.tmp"
|
|
218
|
+
jq --arg id "$approvalId" --arg ts "$ts" \
|
|
219
|
+
'.approvals = [.approvals[] | if .id == $id then
|
|
220
|
+
.status = "revision_requested" | .revisionRequestedAt = $ts
|
|
221
|
+
else . end]' \
|
|
222
|
+
"$approvalsFile" > "$tmp" && mv "$tmp" "$approvalsFile"
|
|
223
|
+
|
|
224
|
+
echo "Revision requested for approval '${approvalId}'."
|
|
225
|
+
echo " Agent will be notified to revise and resubmit."
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### resubmit
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
232
|
+
tmp="${approvalsFile}.tmp"
|
|
233
|
+
jq --arg id "$approvalId" --arg ts "$ts" \
|
|
234
|
+
'.approvals = [.approvals[] | if .id == $id then
|
|
235
|
+
.status = "pending" | .resubmittedAt = $ts
|
|
236
|
+
else . end]' \
|
|
237
|
+
"$approvalsFile" > "$tmp" && mv "$tmp" "$approvalsFile"
|
|
238
|
+
|
|
239
|
+
echo "Approval '${approvalId}' resubmitted (status reset to pending)."
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Step 3 — Return Output
|
|
245
|
+
|
|
246
|
+
```yaml
|
|
247
|
+
domain: ops
|
|
248
|
+
status: complete
|
|
249
|
+
action: <action>
|
|
250
|
+
org: <org_name>
|
|
251
|
+
approval_id: <approval_id>
|
|
252
|
+
approval_status: <status>
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Step 4 — Brain Write (standalone only)
|
|
258
|
+
|
|
259
|
+
If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.
|