@monoes/monomindcli 1.9.17 → 1.10.1

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.
Files changed (118) hide show
  1. package/.claude/commands/mastermind/_repeat.md +182 -39
  2. package/.claude/commands/mastermind/architect.md +17 -11
  3. package/.claude/commands/mastermind/brain.md +4 -0
  4. package/.claude/commands/mastermind/build.md +4 -0
  5. package/.claude/commands/mastermind/content.md +4 -0
  6. package/.claude/commands/mastermind/createorg.md +5 -3
  7. package/.claude/commands/mastermind/finance.md +4 -0
  8. package/.claude/commands/mastermind/idea.md +4 -0
  9. package/.claude/commands/mastermind/marketing.md +4 -0
  10. package/.claude/commands/mastermind/master.md +63 -37
  11. package/.claude/commands/mastermind/ops.md +4 -0
  12. package/.claude/commands/mastermind/release.md +4 -0
  13. package/.claude/commands/mastermind/research.md +4 -0
  14. package/.claude/commands/mastermind/review.md +4 -0
  15. package/.claude/commands/mastermind/runorg.md +5 -3
  16. package/.claude/commands/mastermind/sales.md +4 -0
  17. package/.claude/commands/mastermind/techport.md +9 -0
  18. package/.claude/commands/monomind/do.md +5 -1
  19. package/.claude/commands/monomind/idea.md +5 -1
  20. package/.claude/commands/monomind/improve.md +5 -1
  21. package/.claude/commands/monomind/repeat.md +85 -29
  22. package/.claude/commands/monomind/review.md +6 -2
  23. package/.claude/commands/monomind/understand.md +10 -8
  24. package/.claude/helpers/extras-registry.json +235 -235
  25. package/.claude/helpers/graphify-freshen.cjs +13 -1
  26. package/.claude/helpers/hook-handler.cjs +1 -1
  27. package/.claude/helpers/router.cjs +4 -1
  28. package/.claude/skills/mastermind/_protocol.md +28 -21
  29. package/.claude/skills/mastermind/access.md +236 -0
  30. package/.claude/skills/mastermind/activity.md +191 -0
  31. package/.claude/skills/mastermind/adapter-manager.md +259 -0
  32. package/.claude/skills/mastermind/adapters.md +204 -0
  33. package/.claude/skills/mastermind/agent-detail.md +242 -0
  34. package/.claude/skills/mastermind/agents.md +178 -0
  35. package/.claude/skills/mastermind/approval-detail.md +259 -0
  36. package/.claude/skills/mastermind/approve.md +181 -0
  37. package/.claude/skills/mastermind/architect.md +24 -8
  38. package/.claude/skills/mastermind/backup.md +197 -0
  39. package/.claude/skills/mastermind/bootstrap.md +190 -0
  40. package/.claude/skills/mastermind/budgets.md +237 -0
  41. package/.claude/skills/mastermind/companies.md +256 -0
  42. package/.claude/skills/mastermind/costs.md +151 -0
  43. package/.claude/skills/mastermind/createorg.md +23 -5
  44. package/.claude/skills/mastermind/diagnose.md +249 -0
  45. package/.claude/skills/mastermind/env.md +198 -0
  46. package/.claude/skills/mastermind/environments.md +250 -0
  47. package/.claude/skills/mastermind/export.md +324 -0
  48. package/.claude/skills/mastermind/goal-detail.md +255 -0
  49. package/.claude/skills/mastermind/goals.md +149 -0
  50. package/.claude/skills/mastermind/heartbeat.md +164 -0
  51. package/.claude/skills/mastermind/idea.md +250 -122
  52. package/.claude/skills/mastermind/import.md +281 -0
  53. package/.claude/skills/mastermind/inbox.md +214 -0
  54. package/.claude/skills/mastermind/instance-settings.md +315 -0
  55. package/.claude/skills/mastermind/instance.md +231 -0
  56. package/.claude/skills/mastermind/invite-landing.md +227 -0
  57. package/.claude/skills/mastermind/invites.md +254 -0
  58. package/.claude/skills/mastermind/issue-detail.md +291 -0
  59. package/.claude/skills/mastermind/issues.md +235 -0
  60. package/.claude/skills/mastermind/join-queue.md +170 -0
  61. package/.claude/skills/mastermind/liveness.md +392 -0
  62. package/.claude/skills/mastermind/memory.md +321 -0
  63. package/.claude/skills/mastermind/my-issues.md +146 -0
  64. package/.claude/skills/mastermind/new-agent.md +241 -0
  65. package/.claude/skills/mastermind/org-chart.md +207 -0
  66. package/.claude/skills/mastermind/org-settings.md +217 -0
  67. package/.claude/skills/mastermind/plan-to-tasks.md +136 -0
  68. package/.claude/skills/mastermind/plugin-manager.md +241 -0
  69. package/.claude/skills/mastermind/plugin-settings.md +273 -0
  70. package/.claude/skills/mastermind/plugins.md +190 -0
  71. package/.claude/skills/mastermind/profile.md +187 -0
  72. package/.claude/skills/mastermind/project-detail.md +249 -0
  73. package/.claude/skills/mastermind/project-workspace.md +244 -0
  74. package/.claude/skills/mastermind/projects.md +164 -0
  75. package/.claude/skills/mastermind/routine-detail.md +253 -0
  76. package/.claude/skills/mastermind/routines.md +202 -0
  77. package/.claude/skills/mastermind/runorg.md +74 -9
  78. package/.claude/skills/mastermind/search.md +186 -0
  79. package/.claude/skills/mastermind/secrets.md +199 -0
  80. package/.claude/skills/mastermind/skills.md +156 -0
  81. package/.claude/skills/mastermind/tasks.md +149 -0
  82. package/.claude/skills/mastermind/techport.md +5 -5
  83. package/.claude/skills/mastermind/threads.md +259 -0
  84. package/.claude/skills/mastermind/tree-control.md +250 -0
  85. package/.claude/skills/mastermind/wiki.md +314 -0
  86. package/.claude/skills/mastermind/workspace-detail.md +317 -0
  87. package/.claude/skills/mastermind/workspaces.md +261 -0
  88. package/.claude/skills/mastermind/worktree.md +187 -0
  89. package/dist/src/init/executor.js +8 -8
  90. package/dist/src/init/executor.js.map +1 -1
  91. package/dist/src/init/statusline-generator.d.ts.map +1 -1
  92. package/dist/src/init/statusline-generator.js +12 -0
  93. package/dist/src/init/statusline-generator.js.map +1 -1
  94. package/dist/src/ui/.monomind/data/ranked-context.json +1 -1
  95. package/dist/src/ui/.monomind/loops/mastermind-review-1778664132789.json +16 -0
  96. package/dist/src/ui/.monomind/sessions/current.json +5 -5
  97. package/dist/src/ui/.monomind/sessions/session-1776778451399.json +15 -0
  98. package/dist/src/ui/dashboard.html +3030 -181
  99. package/dist/src/ui/data/mastermind-events.jsonl +8 -0
  100. package/dist/src/ui/data/mastermind-sessions.json +1 -0
  101. package/dist/src/ui/server.mjs +738 -0
  102. package/dist/tsconfig.tsbuildinfo +1 -1
  103. package/package.json +2 -2
  104. package/.claude/skills/.monomind/data/ranked-context.json +0 -5
  105. package/.claude/skills/.monomind/sessions/current.json +0 -13
  106. package/.claude/skills/.monomind/sessions/session-1777829336455.json +0 -15
  107. package/.claude/skills/.monomind/sessions/session-1777831614725.json +0 -15
  108. package/.claude/skills/.monomind/sessions/session-1777832095857.json +0 -15
  109. package/.claude/skills/.monomind/sessions/session-1777839814183.json +0 -15
  110. package/.claude/skills/.monomind/sessions/session-1777841847131.json +0 -15
  111. package/.claude/skills/.monomind/sessions/session-1777843309463.json +0 -15
  112. package/.claude/skills/.monomind/sessions/session-1777880867159.json +0 -15
  113. package/.claude/skills/.monomind/sessions/session-1777881884593.json +0 -15
  114. package/.claude/skills/.monomind/sessions/session-1777884090471.json +0 -15
  115. package/.claude/skills/.monomind/sessions/session-1777884808221.json +0 -15
  116. package/.claude/skills/.monomind/sessions/session-1777885672155.json +0 -15
  117. package/.claude/skills/.monomind/sessions/session-1777886852818.json +0 -15
  118. package/.claude/skills/.monomind/sessions/session-1777896532690.json +0 -15
@@ -0,0 +1,281 @@
1
+ ---
2
+ name: mastermind-import
3
+ description: Mastermind import — import an org from a portable ZIP archive exported by mastermind:export. Previews the archive contents, shows agent plans (create/update/skip), lets you choose a collision strategy, and applies the import to the local .monomind/orgs/ directory. Mirrors CompanyImport.tsx.
4
+ type: domain-skill
5
+ default_mode: confirm
6
+ ---
7
+
8
+ # Mastermind Import
9
+
10
+ This skill is invoked by `mastermind:import` or directly via `/mastermind:import`.
11
+
12
+ ---
13
+
14
+ ## Inputs
15
+
16
+ - `brain_context`: BRAIN CONTEXT block (injected by command, or loaded below if standalone)
17
+ - `action`: preview | apply | list-archive
18
+ - `archive_path`: absolute or relative path to the ZIP archive file (required)
19
+ - `org_name`: override org name from archive (default: use name in archive)
20
+ - `collision`: skip | merge | overwrite (what to do if org already exists; default: skip)
21
+ - `adapter_override`: optional; adapter type to replace all agents' adapters (e.g. `claude-local`)
22
+ - `caller`: command | master
23
+
24
+ ---
25
+
26
+ ## Collision Strategy Reference
27
+
28
+ | Strategy | Behavior |
29
+ |----------|----------|
30
+ | `skip` | If org already exists, abort. Safe default. |
31
+ | `merge` | Merge: add agents/goals/etc from archive, skip duplicates by id. |
32
+ | `overwrite` | Delete existing org files and replace with archive contents. |
33
+
34
+ ---
35
+
36
+ ## Step 0 — Brain Load (standalone only)
37
+
38
+ If `caller` is not "command", load brain context following _protocol.md Brain Load Procedure with namespace: `ops`.
39
+
40
+ ---
41
+
42
+ ## Step 1 — Validate Archive
43
+
44
+ ```bash
45
+ [ -z "$archive_path" ] && { echo "ERROR: --archive-path required (path to the exported .zip file)."; exit 1; }
46
+ [ ! -f "$archive_path" ] && { echo "ERROR: Archive not found: $archive_path"; exit 1; }
47
+
48
+ # Detect format
49
+ case "$archive_path" in
50
+ *.zip) fmt="zip" ;;
51
+ *.tar.gz|*.tgz) fmt="tgz" ;;
52
+ *.json) fmt="json" ;;
53
+ *) echo "ERROR: Unsupported archive format. Expected .zip, .tar.gz, or .json"; exit 1 ;;
54
+ esac
55
+
56
+ echo "Archive: $archive_path (format: $fmt)"
57
+ ```
58
+
59
+ ---
60
+
61
+ ## Step 2 — Execute Action
62
+
63
+ ### list-archive
64
+
65
+ List files in the archive without extracting:
66
+
67
+ ```bash
68
+ if [ "$fmt" = "zip" ]; then
69
+ unzip -l "$archive_path" 2>/dev/null | grep -v "^Archive\|^--\|files$" | awk '{print $NF}' | grep -v "^$"
70
+ elif [ "$fmt" = "tgz" ]; then
71
+ tar -tzf "$archive_path"
72
+ elif [ "$fmt" = "json" ]; then
73
+ echo "(JSON format — single file, no archive listing needed)"
74
+ fi
75
+ ```
76
+
77
+ ### preview
78
+
79
+ Extract and preview the org configuration without writing:
80
+
81
+ ```bash
82
+ tmpDir=$(mktemp -d /tmp/mastermind-import-XXXXXX)
83
+ trap 'rm -rf "$tmpDir"' EXIT
84
+
85
+ if [ "$fmt" = "zip" ]; then
86
+ unzip -q "$archive_path" -d "$tmpDir" 2>/dev/null
87
+ elif [ "$fmt" = "tgz" ]; then
88
+ tar -xzf "$archive_path" -C "$tmpDir" 2>/dev/null
89
+ elif [ "$fmt" = "json" ]; then
90
+ cp "$archive_path" "$tmpDir/org.json"
91
+ fi
92
+
93
+ # Find the main org config file
94
+ orgConfigFile=$(find "$tmpDir" -name "*.json" | grep -v '\-' | head -1)
95
+ [ -z "$orgConfigFile" ] && orgConfigFile=$(find "$tmpDir" -name "org.json" -o -name "export.json" | head -1)
96
+
97
+ if [ -z "$orgConfigFile" ]; then
98
+ echo "ERROR: Could not find org config file in archive."
99
+ exit 1
100
+ fi
101
+
102
+ importedOrgName="${org_name:-$(jq -r '.name // "unknown"' "$orgConfigFile")}"
103
+ agentCount=$(jq '(.roles // []) | length' "$orgConfigFile")
104
+ createdAt=$(jq -r '.created_at // "-"' "$orgConfigFile")
105
+ gov=$(jq -r '.governance // "-"' "$orgConfigFile")
106
+
107
+ echo "IMPORT PREVIEW"
108
+ echo "────────────────────────────────────────────────────────"
109
+ echo " Archive: $archive_path"
110
+ echo " Org name: $importedOrgName"
111
+ echo " Agents: $agentCount"
112
+ echo " Governance: $gov"
113
+ echo " Created: $createdAt"
114
+ echo ""
115
+
116
+ # Check if org already exists
117
+ targetOrgFile=".monomind/orgs/${importedOrgName}.json"
118
+ if [ -f "$targetOrgFile" ]; then
119
+ existingAgents=$(jq '(.roles // []) | length' "$targetOrgFile")
120
+ echo " WARNING: Org '${importedOrgName}' already exists ($existingAgents agents)."
121
+ echo " Collision strategy: ${collision:-skip}"
122
+ echo ""
123
+ fi
124
+
125
+ # Preview agent plans
126
+ echo "AGENT PLANS"
127
+ echo "────────────────────────────────────────────────────────"
128
+ jq -r --arg target "$targetOrgFile" '.roles[] |
129
+ [.id, (.title // "-"), (.adapter.type // "?"), (.adapter.model // "-")] | @tsv' \
130
+ "$orgConfigFile" | while IFS=$'\t' read -r id title adapter model; do
131
+ if [ -f "$targetOrgFile" ]; then
132
+ exists=$(jq -r --arg id "$id" '[.roles[] | select(.id == $id)] | length' "$targetOrgFile")
133
+ action=$([ "$exists" -gt 0 ] && echo "UPDATE" || echo "CREATE")
134
+ else
135
+ action="CREATE"
136
+ fi
137
+ printf " %-8s %-24s %-20s %-16s %s\n" "$action" "$id" "$title" "$adapter" "$model"
138
+ done
139
+
140
+ echo ""
141
+ echo " To apply: --action apply --archive-path $archive_path --collision ${collision:-skip}"
142
+ ```
143
+
144
+ ### apply
145
+
146
+ Apply the import (write org files):
147
+
148
+ ```bash
149
+ tmpDir=$(mktemp -d /tmp/mastermind-import-XXXXXX)
150
+ trap 'rm -rf "$tmpDir"' EXIT
151
+
152
+ if [ "$fmt" = "zip" ]; then
153
+ unzip -q "$archive_path" -d "$tmpDir" 2>/dev/null
154
+ elif [ "$fmt" = "tgz" ]; then
155
+ tar -xzf "$archive_path" -C "$tmpDir" 2>/dev/null
156
+ elif [ "$fmt" = "json" ]; then
157
+ cp "$archive_path" "$tmpDir/org.json"
158
+ fi
159
+
160
+ orgConfigFile=$(find "$tmpDir" -name "*.json" | grep -v '\-' | head -1)
161
+ [ -z "$orgConfigFile" ] && orgConfigFile=$(find "$tmpDir" -name "org.json" -o -name "export.json" | head -1)
162
+ [ -z "$orgConfigFile" ] && { echo "ERROR: Could not find org config file in archive."; exit 1; }
163
+
164
+ importedOrgName="${org_name:-$(jq -r '.name // "unnamed"' "$orgConfigFile")}"
165
+ targetOrgFile=".monomind/orgs/${importedOrgName}.json"
166
+
167
+ mkdir -p ".monomind/orgs"
168
+
169
+ # Handle collision
170
+ if [ -f "$targetOrgFile" ]; then
171
+ collisionStrategy="${collision:-skip}"
172
+ case "$collisionStrategy" in
173
+ skip)
174
+ echo "ERROR: Org '${importedOrgName}' already exists. Use --collision merge or --collision overwrite to proceed."
175
+ exit 1
176
+ ;;
177
+ overwrite)
178
+ echo " Overwriting existing org '${importedOrgName}'..."
179
+ rm -f ".monomind/orgs/${importedOrgName}"*.json ".monomind/orgs/${importedOrgName}"*.jsonl
180
+ ;;
181
+ merge)
182
+ echo " Merging into existing org '${importedOrgName}'..."
183
+ # Merge will be handled per-file below
184
+ ;;
185
+ esac
186
+ fi
187
+
188
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
189
+
190
+ # Apply adapter override if specified
191
+ if [ -n "$adapter_override" ]; then
192
+ tmp="${orgConfigFile}.ovr"
193
+ jq --arg a "$adapter_override" \
194
+ '.roles = [.roles[] | .adapter.type = $a]' \
195
+ "$orgConfigFile" > "$tmp" && mv "$tmp" "$orgConfigFile"
196
+ echo " Applied adapter override: $adapter_override to all agents"
197
+ fi
198
+
199
+ # Copy main config (or merge if merge strategy)
200
+ if [ -f "$targetOrgFile" ] && [ "${collision:-skip}" = "merge" ]; then
201
+ tmp="$targetOrgFile.tmp"
202
+ python3 - "$targetOrgFile" "$orgConfigFile" > "$tmp" << 'PYEOF'
203
+ import json, sys
204
+ existing = json.load(open(sys.argv[1]))
205
+ incoming = json.load(open(sys.argv[2]))
206
+ existing_ids = {r['id'] for r in existing.get('roles', [])}
207
+ new_roles = [r for r in incoming.get('roles', []) if r['id'] not in existing_ids]
208
+ existing['roles'] = existing.get('roles', []) + new_roles
209
+ print(json.dumps(existing, indent=2))
210
+ PYEOF
211
+ mv "$tmp" "$targetOrgFile"
212
+ mergedCount=$(python3 -c "import json; d=json.load(open('$targetOrgFile')); print(len(d.get('roles',[])))")
213
+ echo " Merged: $mergedCount total agents"
214
+ else
215
+ cp "$orgConfigFile" "$targetOrgFile"
216
+ fi
217
+
218
+ # Copy associated files (goals, routines, issues, etc.) from archive
219
+ for suffix in members issues goals projects routines approvals adapters plugins environments workspaces activity threads budgets; do
220
+ src=$(find "$tmpDir" -name "*-${suffix}.json" | head -1)
221
+ [ -z "$src" ] && src=$(find "$tmpDir" -name "*-${suffix}.jsonl" | head -1)
222
+ if [ -n "$src" ]; then
223
+ ext="${src##*.}"
224
+ dest=".monomind/orgs/${importedOrgName}-${suffix}.${ext}"
225
+ if [ -f "$dest" ] && [ "${collision:-skip}" = "merge" ]; then
226
+ # Merge arrays
227
+ python3 - "$dest" "$src" "$suffix" > "${dest}.tmp" << 'PYEOF'
228
+ import json, sys, os
229
+ dest_path, src_path, suffix = sys.argv[1], sys.argv[2], sys.argv[3]
230
+ try:
231
+ dest_data = json.load(open(dest_path))
232
+ src_data = json.load(open(src_path))
233
+ arr_key = suffix if suffix in dest_data else list(dest_data.keys())[0] if dest_data else suffix
234
+ existing_ids = {item.get('id') for item in dest_data.get(arr_key, []) if 'id' in item}
235
+ new_items = [item for item in src_data.get(arr_key, []) if item.get('id') not in existing_ids]
236
+ dest_data[arr_key] = dest_data.get(arr_key, []) + new_items
237
+ print(json.dumps(dest_data, indent=2))
238
+ except Exception as e:
239
+ print(json.dumps(json.load(open(dest_path))), file=__import__('sys').stdout)
240
+ PYEOF
241
+ mv "${dest}.tmp" "$dest"
242
+ else
243
+ cp "$src" "$dest"
244
+ fi
245
+ echo " Imported: ${importedOrgName}-${suffix}.${ext}"
246
+ fi
247
+ done
248
+
249
+ agentCount=$(jq '(.roles // []) | length' "$targetOrgFile")
250
+
251
+ echo ""
252
+ echo "IMPORT COMPLETE"
253
+ echo "────────────────────────────────────────────────────────"
254
+ echo " Org: $importedOrgName"
255
+ echo " Agents: $agentCount"
256
+ echo " Location: $targetOrgFile"
257
+ echo " Collision: ${collision:-skip}"
258
+ echo " Applied at: $ts"
259
+ echo ""
260
+ echo " Run org: /mastermind:runorg --org $importedOrgName"
261
+ echo " View chart: /mastermind:org-chart --org $importedOrgName"
262
+ ```
263
+
264
+ ---
265
+
266
+ ## Step 3 — Return Output
267
+
268
+ ```yaml
269
+ domain: ops
270
+ status: complete
271
+ action: <action>
272
+ org_name: <importedOrgName>
273
+ agent_count: <N>
274
+ collision: <strategy>
275
+ ```
276
+
277
+ ---
278
+
279
+ ## Step 4 — Brain Write (standalone only)
280
+
281
+ If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.
@@ -0,0 +1,214 @@
1
+ ---
2
+ name: mastermind-inbox
3
+ description: Mastermind inbox — unified view of everything that needs human attention across all orgs: pending approvals, running heartbeats, active task assignments, and budget alerts. The single place to check before starting work.
4
+ type: domain-skill
5
+ default_mode: auto
6
+ ---
7
+
8
+ # Mastermind Inbox
9
+
10
+ This skill is invoked by `mastermind:inbox` or directly via `/mastermind:inbox`.
11
+
12
+ ---
13
+
14
+ ## Inputs
15
+
16
+ - `brain_context`: BRAIN CONTEXT block
17
+ - `org_name`: optional — filter to a single org (default: all orgs)
18
+ - `filter`: all | approvals | heartbeats | tasks | alerts (default: all)
19
+ - `action`: read | mark-done | archive
20
+ - `item_id`: id of item to action
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 — Collect All Orgs
32
+
33
+ ```bash
34
+ if [ -n "$org_name" ]; then
35
+ orgs="$org_name"
36
+ else
37
+ orgs=$(ls .monomind/orgs/*.json 2>/dev/null | grep -v '\-state\|-goals\|-routines\|-approvals\|-projects\|-worktrees\|-secrets' | xargs -I{} basename {} .json | sort)
38
+ fi
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Step 2 — Gather Inbox Items
44
+
45
+ For each org, collect:
46
+
47
+ ```bash
48
+ total_approvals=0
49
+ total_heartbeats=0
50
+ total_alerts=0
51
+
52
+ for org in $orgs; do
53
+ orgFile=".monomind/orgs/${org}.json"
54
+ stateFile=".monomind/orgs/${org}-state.json"
55
+ approvalsFile=".monomind/orgs/${org}-approvals.json"
56
+
57
+ # 1. Pending approvals
58
+ if [ -f "$approvalsFile" ]; then
59
+ pending=$(jq '[.approvals[] | select(.status == "pending")] | length' "$approvalsFile" 2>/dev/null || echo 0)
60
+ total_approvals=$((total_approvals + pending))
61
+ fi
62
+
63
+ # 2. Running agents (active heartbeats)
64
+ if [ -f "$stateFile" ]; then
65
+ running=$(jq '[.agents // {} | to_entries[] | select(.value.status == "running")] | length' "$stateFile" 2>/dev/null || echo 0)
66
+ total_heartbeats=$((total_heartbeats + running))
67
+ fi
68
+
69
+ # 3. Budget alerts
70
+ budget=$(jq -r '.run_config.budget_tokens // 0' "$orgFile" 2>/dev/null || echo 0)
71
+ threshold=$(jq -r '.run_config.alert_threshold // 0.8' "$orgFile" 2>/dev/null || echo 0.8)
72
+ if [ "$budget" -gt 0 ] && [ -f "$stateFile" ]; then
73
+ total_in=$(jq '[.agents // {} | to_entries[] | .value.tokens_in // 0] | add // 0' "$stateFile" 2>/dev/null || echo 0)
74
+ total_out=$(jq '[.agents // {} | to_entries[] | .value.tokens_out // 0] | add // 0' "$stateFile" 2>/dev/null || echo 0)
75
+ total_tok=$((total_in + total_out))
76
+ over=$(awk -v t="$total_tok" -v b="$budget" -v thr="$threshold" \
77
+ 'BEGIN { print (b>0 && t/b >= thr) ? "yes" : "no" }')
78
+ [ "$over" = "yes" ] && total_alerts=$((total_alerts + 1))
79
+ fi
80
+ done
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Step 3 — Render Inbox
86
+
87
+ ```bash
88
+ echo "╔══════════════════════════════════════════════════════╗"
89
+ echo "║ MASTERMIND INBOX ║"
90
+ echo "╚══════════════════════════════════════════════════════╝"
91
+ echo ""
92
+ echo " 🔴 APPROVALS NEEDED: $total_approvals"
93
+ echo " 🟡 AGENTS RUNNING: $total_heartbeats"
94
+ echo " 🟠 BUDGET ALERTS: $total_alerts"
95
+ echo ""
96
+
97
+ for org in $orgs; do
98
+ orgFile=".monomind/orgs/${org}.json"
99
+ stateFile=".monomind/orgs/${org}-state.json"
100
+ approvalsFile=".monomind/orgs/${org}-approvals.json"
101
+
102
+ has_items=0
103
+
104
+ # Pending approvals
105
+ if [ -f "$approvalsFile" ]; then
106
+ pending_approvals=$(jq -r '.approvals[] | select(.status == "pending") | " [APPROVAL] [\(.id)] \(.agent_id): \(.title) risk=\(.risk_level // "low")"' \
107
+ "$approvalsFile" 2>/dev/null)
108
+ [ -n "$pending_approvals" ] && { has_items=1; echo "ORG: $org"; echo "$pending_approvals"; }
109
+ fi
110
+
111
+ # Running agents
112
+ if [ -f "$stateFile" ]; then
113
+ running_agents=$(jq -r '
114
+ .agents // {} | to_entries[] | select(.value.status == "running") |
115
+ " [RUNNING] [\(.key)] since=\(.value.last_heartbeat // "unknown")"
116
+ ' "$stateFile" 2>/dev/null)
117
+ [ -n "$running_agents" ] && { has_items=1; [ $has_items -eq 1 ] || echo "ORG: $org"; echo "$running_agents"; }
118
+ fi
119
+
120
+ [ $has_items -eq 1 ] && echo ""
121
+ done
122
+
123
+ if [ "$total_approvals" -eq 0 ] && [ "$total_heartbeats" -eq 0 ] && [ "$total_alerts" -eq 0 ]; then
124
+ echo " ✓ Inbox is clear. No items need attention."
125
+ fi
126
+ ```
127
+
128
+ ### filter: approvals only
129
+
130
+ ```bash
131
+ for org in $orgs; do
132
+ approvalsFile=".monomind/orgs/${org}-approvals.json"
133
+ [ -f "$approvalsFile" ] || continue
134
+ echo "=== $org ==="
135
+ jq -r '.approvals[] | select(.status == "pending") |
136
+ "[\(.id)] \(.agent_id): \(.title)\n Action: \(.action)\n Risk: \(.risk_level // "low")\n → /mastermind:approve --org '"$org"' --action approve --approval-id \(.id)"
137
+ ' "$approvalsFile" 2>/dev/null || echo " No pending approvals."
138
+ echo ""
139
+ done
140
+ ```
141
+
142
+ ### filter: heartbeats only
143
+
144
+ Show currently running agent heartbeats across all orgs:
145
+
146
+ ```bash
147
+ for org in $orgs; do
148
+ stateFile=".monomind/orgs/${org}-state.json"
149
+ [ -f "$stateFile" ] || continue
150
+ running=$(jq -r '
151
+ .agents // {} | to_entries[] | select(.value.status == "running") |
152
+ " [\(.key)] since=\(.value.last_heartbeat // "?")"
153
+ ' "$stateFile" 2>/dev/null)
154
+ [ -n "$running" ] && { echo "=== $org ==="; echo "$running"; echo ""; }
155
+ done
156
+ ```
157
+
158
+ ### filter: alerts only
159
+
160
+ ```bash
161
+ echo "BUDGET ALERTS:"
162
+ for org in $orgs; do
163
+ orgFile=".monomind/orgs/${org}.json"
164
+ stateFile=".monomind/orgs/${org}-state.json"
165
+ budget=$(jq -r '.run_config.budget_tokens // 0' "$orgFile" 2>/dev/null || echo 0)
166
+ [ "$budget" -le 0 ] && continue
167
+ [ -f "$stateFile" ] || continue
168
+ total_in=$(jq '[.agents // {} | to_entries[] | .value.tokens_in // 0] | add // 0' "$stateFile" 2>/dev/null || echo 0)
169
+ total_out=$(jq '[.agents // {} | to_entries[] | .value.tokens_out // 0] | add // 0' "$stateFile" 2>/dev/null || echo 0)
170
+ total_tok=$((total_in + total_out))
171
+ pct=$(awk -v t="$total_tok" -v b="$budget" 'BEGIN{printf "%.1f", t/b*100}')
172
+ echo " $org: ${pct}% of $budget token budget used"
173
+ done
174
+ ```
175
+
176
+ ---
177
+
178
+ ## Quick Action Shortcuts
179
+
180
+ From the inbox, the user can directly:
181
+
182
+ ```bash
183
+ # Approve a pending request:
184
+ /mastermind:approve --org <org> --action approve --approval-id <id>
185
+
186
+ # Stop a running agent:
187
+ /mastermind:agents --org <org> --action pause --agent-id <id>
188
+
189
+ # Check costs:
190
+ /mastermind:costs --org <org> --action report
191
+
192
+ # Set budget:
193
+ /mastermind:costs --org <org> --action set-budget --budget-tokens 500000
194
+ ```
195
+
196
+ ---
197
+
198
+ ## Step 4 — Return Output
199
+
200
+ ```yaml
201
+ domain: ops
202
+ status: complete
203
+ filter: <filter>
204
+ orgs_checked: <N>
205
+ pending_approvals: <N>
206
+ running_heartbeats: <N>
207
+ budget_alerts: <N>
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Step 5 — Brain Write (standalone only)
213
+
214
+ If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.