@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.
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 +100 -46
  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 +37 -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 +318 -186
  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 +1 -1
  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,241 @@
1
+ ---
2
+ name: mastermind-new-agent
3
+ description: Mastermind new-agent — wizard to hire/create a new agent within an org. Configures adapter type, model, role name, reports_to hierarchy, governance policy, skill assignments, and budget. Writes the new role to the org config file.
4
+ type: domain-skill
5
+ default_mode: confirm
6
+ ---
7
+
8
+ # Mastermind New Agent
9
+
10
+ This skill is invoked by `mastermind:new-agent` or directly via `/mastermind:new-agent`.
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 add the agent to (required)
18
+ - `action`: create | preview | list-roles | list-adapters
19
+ - `agent_id`: unique slug for the new agent (required for create; auto-generated if omitted)
20
+ - `title`: display title for the agent (required for create)
21
+ - `adapter_type`: claude-local | gemini-local | codex-local | cursor | opencode | hermes | http | acpx (default: claude-local)
22
+ - `model`: model identifier (e.g. claude-sonnet-4-6, claude-opus-4-7, gemini-2.0-flash)
23
+ - `max_tokens`: max tokens per run (default: 8192)
24
+ - `reports_to`: parent agent id in the hierarchy (null = top-level)
25
+ - `governance`: auto | board | strict (default: inherit from org)
26
+ - `skills`: comma-separated skill names to assign (e.g. mastermind:tasks,mastermind:goals)
27
+ - `budget_tokens`: per-run token budget cap (optional)
28
+ - `heartbeat_enabled`: true | false (default: false)
29
+ - `heartbeat_interval`: heartbeat interval in seconds (default: 900)
30
+ - `system_prompt`: brief system prompt override (optional)
31
+ - `caller`: command | master
32
+
33
+ ---
34
+
35
+ ## Adapter Types
36
+
37
+ | Type | Description | Default Model |
38
+ |------|-------------|---------------|
39
+ | `claude-local` | Claude via Anthropic API | claude-sonnet-4-6 |
40
+ | `gemini-local` | Gemini via Google API | gemini-2.0-flash |
41
+ | `codex-local` | OpenAI Codex | gpt-4o |
42
+ | `cursor` | Cursor IDE agent | cursor-default |
43
+ | `opencode` | OpenCode agent | opencode-default |
44
+ | `hermes` | Hermes local model | hermes-3 |
45
+ | `http` | Custom HTTP adapter | (custom) |
46
+ | `acpx` | ACPX protocol | (custom) |
47
+
48
+ ---
49
+
50
+ ## Step 0 — Brain Load (standalone only)
51
+
52
+ If `caller` is not "command", load brain context following _protocol.md Brain Load Procedure with namespace: `ops`.
53
+
54
+ ---
55
+
56
+ ## Step 1 — Load Org
57
+
58
+ ```bash
59
+ orgFile=".monomind/orgs/${org_name}.json"
60
+ [ ! -f "$orgFile" ] && { echo "ERROR: Org '${org_name}' not found."; exit 1; }
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Step 2 — Execute Action
66
+
67
+ ### list-adapters
68
+
69
+ ```bash
70
+ echo "AVAILABLE ADAPTERS"
71
+ echo "────────────────────────────────────────────────────────"
72
+ cat <<'ADAPTERS'
73
+ claude-local Claude via Anthropic API (recommended)
74
+ Models: claude-sonnet-4-6, claude-opus-4-7, claude-haiku-4-5
75
+ gemini-local Gemini via Google AI
76
+ Models: gemini-2.0-flash, gemini-1.5-pro
77
+ codex-local OpenAI Codex
78
+ Models: gpt-4o, gpt-4o-mini, o3-mini
79
+ cursor Cursor IDE agent
80
+ opencode OpenCode agent
81
+ hermes Hermes local LLM (Ollama)
82
+ http Custom HTTP adapter endpoint
83
+ acpx ACPX protocol adapter
84
+ ADAPTERS
85
+ ```
86
+
87
+ ### list-roles
88
+
89
+ ```bash
90
+ echo "CURRENT ROLES IN ORG: $org_name"
91
+ echo "────────────────────────────────────────────────────────"
92
+ printf "%-22s %-20s %-14s %s\n" "ID" "TITLE" "ADAPTER" "REPORTS TO"
93
+ echo "────────────────────────────────────────────────────────"
94
+ jq -r '.roles[] |
95
+ [.id, (.title // "-"), (.adapter.type // "claude-local"), (.reports_to // "(root)")] | @tsv' \
96
+ "$orgFile" | while IFS=$'\t' read -r id title adapter rt; do
97
+ printf "%-22s %-20s %-14s %s\n" "$id" "$title" "$adapter" "$rt"
98
+ done
99
+ ```
100
+
101
+ ### preview
102
+
103
+ ```bash
104
+ [ -z "$title" ] && { echo "ERROR: --title required for preview."; exit 1; }
105
+
106
+ adapterType="${adapter_type:-claude-local}"
107
+ modelId="${model}"
108
+ # Default model per adapter
109
+ if [ -z "$modelId" ]; then
110
+ case "$adapterType" in
111
+ claude-local) modelId="claude-sonnet-4-6" ;;
112
+ gemini-local) modelId="gemini-2.0-flash" ;;
113
+ codex-local) modelId="gpt-4o" ;;
114
+ cursor) modelId="cursor-default" ;;
115
+ opencode) modelId="opencode-default" ;;
116
+ hermes) modelId="hermes-3" ;;
117
+ *) modelId="(custom)" ;;
118
+ esac
119
+ fi
120
+
121
+ # Generate slug if not set
122
+ agentIdPreview="${agent_id}"
123
+ if [ -z "$agentIdPreview" ]; then
124
+ agentIdPreview=$(echo "$title" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-' | sed 's/^-//;s/-$//')
125
+ fi
126
+
127
+ echo "PREVIEW — new agent to be added to org '$org_name'"
128
+ echo "────────────────────────────────────────────────────────"
129
+ echo " ID: $agentIdPreview"
130
+ echo " Title: $title"
131
+ echo " Adapter: $adapterType / $modelId"
132
+ echo " Max tokens: ${max_tokens:-8192}"
133
+ echo " Reports to: ${reports_to:-(root/top-level)}"
134
+ echo " Governance: ${governance:-inherit}"
135
+ echo " Skills: ${skills:-(none)}"
136
+ echo " Budget: ${budget_tokens:-(unlimited)}"
137
+ echo " Heartbeat: ${heartbeat_enabled:-false} (${heartbeat_interval:-900}s)"
138
+ [ -n "$system_prompt" ] && echo " Prompt: $system_prompt"
139
+ echo ""
140
+ echo "Run with --action create to add this agent to the org."
141
+ ```
142
+
143
+ ### create
144
+
145
+ ```bash
146
+ [ -z "$title" ] && { echo "ERROR: --title required."; exit 1; }
147
+
148
+ adapterType="${adapter_type:-claude-local}"
149
+ modelId="${model}"
150
+ if [ -z "$modelId" ]; then
151
+ case "$adapterType" in
152
+ claude-local) modelId="claude-sonnet-4-6" ;;
153
+ gemini-local) modelId="gemini-2.0-flash" ;;
154
+ codex-local) modelId="gpt-4o" ;;
155
+ cursor) modelId="cursor-default" ;;
156
+ opencode) modelId="opencode-default" ;;
157
+ hermes) modelId="hermes-3" ;;
158
+ *) modelId="(custom)" ;;
159
+ esac
160
+ fi
161
+
162
+ # Generate id from title if not provided
163
+ if [ -z "$agent_id" ]; then
164
+ agent_id=$(echo "$title" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-' | sed 's/^-//;s/-$//')
165
+ fi
166
+
167
+ # Check for duplicate id
168
+ duplicate=$(jq -r --arg id "$agent_id" '[.roles[] | select(.id == $id)] | length' "$orgFile")
169
+ [ "$duplicate" -gt 0 ] && { echo "ERROR: Agent id '$agent_id' already exists in org '$org_name'. Use --agent-id to specify a unique id."; exit 1; }
170
+
171
+ # Validate reports_to if set
172
+ if [ -n "$reports_to" ]; then
173
+ parentExists=$(jq -r --arg pid "$reports_to" '[.roles[] | select(.id == $pid)] | length' "$orgFile")
174
+ [ "$parentExists" -eq 0 ] && echo "WARNING: Parent agent '$reports_to' not found in org. Setting anyway."
175
+ fi
176
+
177
+ # Build skills array
178
+ skillsArray="[]"
179
+ if [ -n "$skills" ]; then
180
+ skillsArray=$(echo "$skills" | tr ',' '\n' | jq -Rsc 'split("\n") | map(select(. != ""))')
181
+ fi
182
+
183
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
184
+
185
+ tmp="${orgFile}.tmp"
186
+ jq --arg id "$agent_id" \
187
+ --arg title "$title" \
188
+ --arg adapter "$adapterType" \
189
+ --arg model "$modelId" \
190
+ --argjson maxTok "${max_tokens:-8192}" \
191
+ --arg rt "${reports_to:-}" \
192
+ --arg gov "${governance:-}" \
193
+ --argjson skills "$skillsArray" \
194
+ --argjson budget "${budget_tokens:-null}" \
195
+ --argjson hbEnabled "${heartbeat_enabled:-false}" \
196
+ --argjson hbInterval "${heartbeat_interval:-900}" \
197
+ --arg prompt "${system_prompt:-}" \
198
+ --arg ts "$ts" \
199
+ '.roles += [{
200
+ "id": $id,
201
+ "title": $title,
202
+ "adapter": {"type": $adapter, "model": $model, "max_tokens": $maxTok},
203
+ "reports_to": (if $rt != "" then $rt else null end),
204
+ "governance": (if $gov != "" then $gov else null end),
205
+ "skills": $skills,
206
+ "budget_tokens": $budget,
207
+ "heartbeat": {"enabled": $hbEnabled, "interval": $hbInterval},
208
+ "system_prompt": (if $prompt != "" then $prompt else null end),
209
+ "created_at": $ts
210
+ }]' \
211
+ "$orgFile" > "$tmp" && mv "$tmp" "$orgFile"
212
+
213
+ echo "Agent created: $agent_id"
214
+ echo " Title: $title"
215
+ echo " Adapter: $adapterType / $modelId"
216
+ echo " Reports: ${reports_to:-(root)}"
217
+ echo " Skills: ${skills:-(none)}"
218
+ echo ""
219
+ echo "Org '${org_name}' now has $(jq '.roles | length' "$orgFile") agent(s)."
220
+ echo "View: /mastermind:agent-detail --org $org_name --agent-id $agent_id"
221
+ ```
222
+
223
+ ---
224
+
225
+ ## Step 3 — Return Output
226
+
227
+ ```yaml
228
+ domain: ops
229
+ status: complete
230
+ action: <action>
231
+ org: <org_name>
232
+ agent_id: <agent_id>
233
+ adapter_type: <type>
234
+ model: <model>
235
+ ```
236
+
237
+ ---
238
+
239
+ ## Step 4 — Brain Write (standalone only)
240
+
241
+ If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.
@@ -0,0 +1,207 @@
1
+ ---
2
+ name: mastermind-org-chart
3
+ description: Mastermind org-chart — generates a text-based ASCII org chart for an org showing the agent hierarchy, adapter types, heartbeat status, and reports-to relationships. Supports tree view, flat list, and JSON export. Mirrors OrgChart.tsx canvas view as a CLI-friendly format.
4
+ type: domain-skill
5
+ default_mode: auto
6
+ ---
7
+
8
+ # Mastermind Org Chart
9
+
10
+ This skill is invoked by `mastermind:org-chart` or directly via `/mastermind:org-chart`.
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 chart (required)
18
+ - `action`: show | flat | export | search
19
+ - `query`: search term to filter agents in the chart (for search)
20
+ - `output_file`: file path for JSON export (for export; default: stdout)
21
+ - `depth`: max depth to render (default: unlimited)
22
+ - `caller`: command | master
23
+
24
+ ---
25
+
26
+ ## Step 0 — Brain Load (standalone only)
27
+
28
+ If `caller` is not "command", load brain context following _protocol.md Brain Load Procedure with namespace: `ops`.
29
+
30
+ ---
31
+
32
+ ## Step 1 — Load Org Roles
33
+
34
+ ```bash
35
+ orgFile=".monomind/orgs/${org_name}.json"
36
+ [ ! -f "$orgFile" ] && { echo "ERROR: Org '${org_name}' not found."; exit 1; }
37
+
38
+ roles=$(jq -r '.roles // []' "$orgFile")
39
+ roleCount=$(echo "$roles" | jq 'length')
40
+
41
+ # Load heartbeat state if available
42
+ stateFile=".monomind/orgs/${org_name}-state.json"
43
+ ```
44
+
45
+ ---
46
+
47
+ ## Step 2 — Execute Action
48
+
49
+ ### show (default)
50
+
51
+ ```bash
52
+ echo "ORG CHART — $org_name"
53
+ echo "════════════════════════════════════════════════════════"
54
+
55
+ [ "$roleCount" -eq 0 ] && {
56
+ echo " No agents in org '$org_name'."
57
+ echo " Add one: /mastermind:new-agent --org $org_name --title 'My Agent'"
58
+ exit 0
59
+ }
60
+
61
+ # Build parent→children map using Python for recursive ASCII tree
62
+ python3 - "$orgFile" "$stateFile" "${depth:-99}" <<'PYEOF'
63
+ import json, sys, os
64
+
65
+ orgFile = sys.argv[1]
66
+ stateFile = sys.argv[2] if len(sys.argv) > 2 else None
67
+ maxDepth = int(sys.argv[3]) if len(sys.argv) > 3 else 99
68
+
69
+ with open(orgFile) as f:
70
+ org = json.load(f)
71
+
72
+ roles = org.get("roles", [])
73
+
74
+ # Load heartbeat state
75
+ hb = {}
76
+ if stateFile and os.path.exists(stateFile):
77
+ try:
78
+ with open(stateFile) as f:
79
+ state = json.load(f)
80
+ for r in state.get("roles", []):
81
+ hb[r.get("id", "")] = r.get("last_heartbeat")
82
+ except Exception:
83
+ pass
84
+
85
+ # Build child map
86
+ children = {}
87
+ for r in roles:
88
+ pid = r.get("reports_to") or "__root__"
89
+ children.setdefault(pid, []).append(r)
90
+
91
+ def render(nodes, prefix="", depth=0):
92
+ if depth > maxDepth:
93
+ return
94
+ for i, r in enumerate(nodes):
95
+ is_last = (i == len(nodes) - 1)
96
+ connector = "└── " if is_last else "├── "
97
+ child_prefix = prefix + (" " if is_last else "│ ")
98
+ rid = r.get("id", "?")
99
+ title = r.get("title", rid)
100
+ adapter = r.get("adapter", {})
101
+ atype = adapter.get("type", "?") if isinstance(adapter, dict) else str(adapter)
102
+ model = adapter.get("model", "") if isinstance(adapter, dict) else ""
103
+ hb_status = "♡" if rid not in hb or not hb[rid] else "♥"
104
+ gov = r.get("governance") or ""
105
+ gov_str = f" [{gov}]" if gov else ""
106
+ model_str = f"/{model}" if model else ""
107
+ print(f"{prefix}{connector}{title} ({atype}{model_str}){gov_str} {hb_status}")
108
+ kids = children.get(rid, [])
109
+ if kids:
110
+ render(kids, child_prefix, depth + 1)
111
+
112
+ roots = children.get("__root__", [])
113
+ # Include agents whose reports_to points to a non-existent id
114
+ all_ids = {r.get("id") for r in roles}
115
+ for r in roles:
116
+ pid = r.get("reports_to")
117
+ if pid and pid not in all_ids and r not in roots:
118
+ roots.append(r)
119
+
120
+ render(roots)
121
+ PYEOF
122
+
123
+ echo ""
124
+ echo " $roleCount agent(s) · ♥ heartbeat active ♡ no heartbeat"
125
+ echo " Add agent: /mastermind:new-agent --org $org_name --title 'Role Name'"
126
+ echo " Agent detail: /mastermind:agent-detail --org $org_name --agent-id <id>"
127
+ ```
128
+
129
+ ### flat
130
+
131
+ ```bash
132
+ echo "AGENTS — $org_name (flat list)"
133
+ echo "────────────────────────────────────────────────────────"
134
+ printf "%-24s %-20s %-16s %-20s %s\n" "ID" "TITLE" "ADAPTER" "MODEL" "REPORTS TO"
135
+ echo "────────────────────────────────────────────────────────"
136
+
137
+ echo "$roles" | jq -r '.[] |
138
+ [.id, (.title // "-"), (.adapter.type // "?"), (.adapter.model // "-"),
139
+ (.reports_to // "(root)")] | @tsv' | \
140
+ while IFS=$'\t' read -r id title adapter model rt; do
141
+ printf "%-24s %-20s %-16s %-20s %s\n" "$id" "$title" "$adapter" "$model" "$rt"
142
+ done
143
+
144
+ echo ""
145
+ echo "Total: $roleCount"
146
+ ```
147
+
148
+ ### search
149
+
150
+ ```bash
151
+ [ -z "$query" ] && { echo "ERROR: --query required."; exit 1; }
152
+
153
+ echo "AGENT SEARCH — $org_name query: '$query'"
154
+ echo "────────────────────────────────────────────────────────"
155
+ printf "%-24s %-20s %-16s %s\n" "ID" "TITLE" "ADAPTER" "REPORTS TO"
156
+ echo "────────────────────────────────────────────────────────"
157
+
158
+ ql=$(echo "$query" | tr '[:upper:]' '[:lower:]')
159
+ echo "$roles" | jq -r --arg q "$ql" '.[] |
160
+ select(
161
+ (.id | ascii_downcase | contains($q)) or
162
+ (.title // "" | ascii_downcase | contains($q)) or
163
+ (.adapter.type // "" | ascii_downcase | contains($q)) or
164
+ (.adapter.model // "" | ascii_downcase | contains($q))
165
+ ) |
166
+ [.id, (.title // "-"), (.adapter.type // "?"), (.reports_to // "(root)")] | @tsv' | \
167
+ while IFS=$'\t' read -r id title adapter rt; do
168
+ printf "%-24s %-20s %-16s %s\n" "$id" "$title" "$adapter" "$rt"
169
+ done
170
+ ```
171
+
172
+ ### export
173
+
174
+ ```bash
175
+ outFile="${output_file:-}"
176
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
177
+
178
+ payload=$(jq --arg org "$org_name" --arg ts "$ts" \
179
+ '{org: $org, exportedAt: $ts, roles: (.roles // [])}' \
180
+ "$orgFile")
181
+
182
+ if [ -n "$outFile" ]; then
183
+ mkdir -p "$(dirname "$outFile")"
184
+ echo "$payload" > "$outFile"
185
+ echo "Org chart exported: $outFile ($roleCount agents)"
186
+ else
187
+ echo "$payload" | jq .
188
+ fi
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Step 3 — Return Output
194
+
195
+ ```yaml
196
+ domain: ops
197
+ status: complete
198
+ action: <action>
199
+ org: <org_name>
200
+ agent_count: <N>
201
+ ```
202
+
203
+ ---
204
+
205
+ ## Step 4 — Brain Write (standalone only)
206
+
207
+ If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.
@@ -0,0 +1,217 @@
1
+ ---
2
+ name: mastermind-org-settings
3
+ description: Mastermind org-settings — edit org configuration (name, goal, topology, governance, budget), export org as portable JSON, and import an org from a previously exported file.
4
+ type: domain-skill
5
+ default_mode: confirm
6
+ ---
7
+
8
+ # Mastermind Org Settings
9
+
10
+ This skill is invoked by `mastermind:org-settings` or directly via `/mastermind:org-settings`.
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 configure (required)
18
+ - `action`: show | edit | export | import
19
+ - `field`: field to edit (name, goal, topology, governance, budget_tokens, alert_threshold, ceo_adapter)
20
+ - `value`: new value for the field
21
+ - `export_path`: path to write exported JSON (default: `.monomind/exports/<org_name>-<timestamp>.json`)
22
+ - `import_path`: path to JSON file to import from
23
+ - `caller`: command | master
24
+
25
+ ---
26
+
27
+ ## Step 0 — Brain Load (standalone only)
28
+
29
+ If `caller` is not "command", load brain context following _protocol.md Brain Load Procedure with namespace: `ops`.
30
+
31
+ ---
32
+
33
+ ## Step 1 — Resolve Org
34
+
35
+ ```bash
36
+ orgFile=".monomind/orgs/${org_name}.json"
37
+ [ ! -f "$orgFile" ] && { echo "ERROR: Org '${org_name}' not found. Run /mastermind:createorg first."; exit 1; }
38
+ ```
39
+
40
+ ---
41
+
42
+ ## Step 2 — Execute Action
43
+
44
+ ### show (default)
45
+
46
+ Display current org config in a readable format:
47
+
48
+ ```bash
49
+ echo "ORG SETTINGS — ${org_name}"
50
+ echo "──────────────────────────────────────────"
51
+ jq -r '
52
+ " Name: \(.name // .org_name // "-")",
53
+ " Goal: \(.goal // "-")",
54
+ " Topology: \(.topology // "hierarchical")",
55
+ " Max Agents: \(.max_agents // 8)",
56
+ " Governance: \(.governance.policy // "auto")",
57
+ " Budget: \(.run_config.budget_tokens // 0) tokens",
58
+ " Alert at: \((.run_config.alert_threshold // 0.8) * 100 | floor)%",
59
+ " CEO Adapter: \(.run_config.ceo_adapter // "claude-sonnet-4-6")",
60
+ " Roles: \(.roles | length) agents"
61
+ ' "$orgFile"
62
+ echo ""
63
+ echo " Run /mastermind:org-settings --org ${org_name} --action edit --field <field> --value <value>"
64
+ echo " Fields: name | goal | topology | governance | budget_tokens | alert_threshold | ceo_adapter"
65
+ ```
66
+
67
+ ### edit
68
+
69
+ Update a single field in the org config:
70
+
71
+ ```bash
72
+ field="${field}"
73
+ value="${value}"
74
+ tmp="${orgFile}.tmp"
75
+
76
+ case "$field" in
77
+ name)
78
+ jq --arg v "$value" '.name = $v' "$orgFile" > "$tmp" && mv "$tmp" "$orgFile"
79
+ echo "Updated: name → $value"
80
+ ;;
81
+ goal)
82
+ jq --arg v "$value" '.goal = $v' "$orgFile" > "$tmp" && mv "$tmp" "$orgFile"
83
+ echo "Updated: goal → $value"
84
+ ;;
85
+ topology)
86
+ case "$value" in hierarchical|mesh|hierarchical-mesh|adaptive|star|ring) : ;; *)
87
+ echo "ERROR: topology must be one of: hierarchical, mesh, hierarchical-mesh, adaptive, star, ring"; exit 1 ;;
88
+ esac
89
+ jq --arg v "$value" '.topology = $v' "$orgFile" > "$tmp" && mv "$tmp" "$orgFile"
90
+ echo "Updated: topology → $value"
91
+ ;;
92
+ governance)
93
+ case "$value" in auto|board|strict) : ;; *)
94
+ echo "ERROR: governance must be one of: auto, board, strict"; exit 1 ;;
95
+ esac
96
+ jq --arg v "$value" '.governance.policy = $v' "$orgFile" > "$tmp" && mv "$tmp" "$orgFile"
97
+ echo "Updated: governance → $value"
98
+ ;;
99
+ budget_tokens)
100
+ [[ "$value" =~ ^[0-9]+$ ]] || { echo "ERROR: budget_tokens must be a positive integer"; exit 1; }
101
+ jq --argjson v "$value" '.run_config.budget_tokens = $v' "$orgFile" > "$tmp" && mv "$tmp" "$orgFile"
102
+ echo "Updated: budget_tokens → $value"
103
+ ;;
104
+ alert_threshold)
105
+ # accept 0.0–1.0 or 0–100
106
+ if [[ "$value" =~ ^[0-9]+$ ]] && [ "$value" -gt 1 ]; then
107
+ value=$(awk "BEGIN{printf \"%.2f\",$value/100}")
108
+ fi
109
+ jq --argjson v "$value" '.run_config.alert_threshold = $v' "$orgFile" > "$tmp" && mv "$tmp" "$orgFile"
110
+ echo "Updated: alert_threshold → $value"
111
+ ;;
112
+ ceo_adapter)
113
+ case "$value" in claude-sonnet-4-6|claude-opus-4-7|claude-haiku-4-5) : ;; *)
114
+ echo "ERROR: ceo_adapter must be one of: claude-sonnet-4-6, claude-opus-4-7, claude-haiku-4-5"; exit 1 ;;
115
+ esac
116
+ jq --arg v "$value" '.run_config.ceo_adapter = $v' "$orgFile" > "$tmp" && mv "$tmp" "$orgFile"
117
+ echo "Updated: ceo_adapter → $value"
118
+ ;;
119
+ *)
120
+ echo "ERROR: Unknown field '$field'. Valid fields: name, goal, topology, governance, budget_tokens, alert_threshold, ceo_adapter"
121
+ exit 1
122
+ ;;
123
+ esac
124
+ ```
125
+
126
+ Emit `org:settings:updated` event:
127
+
128
+ ```bash
129
+ REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
130
+ CTRL_URL=$(jq -r '.url // "http://localhost:4242"' "$REPO_ROOT/.monomind/control.json" 2>/dev/null || echo "http://localhost:4242")
131
+ curl -s -X POST "${CTRL_URL}/api/mastermind/event" \
132
+ -H "Content-Type: application/json" \
133
+ -d "$(jq -cn --arg org "$org_name" --arg field "$field" --arg value "$value" \
134
+ '{type:"org:settings:updated",org:$org,field:$field,value:$value,ts:(now*1000|floor)}')" || true
135
+ ```
136
+
137
+ ### export
138
+
139
+ Export the full org config (minus secrets) to a portable JSON:
140
+
141
+ ```bash
142
+ mkdir -p ".monomind/exports"
143
+ timestamp=$(date +%Y%m%d-%H%M%S)
144
+ outPath="${export_path:-.monomind/exports/${org_name}-${timestamp}.json}"
145
+
146
+ # Merge all org data files into one export bundle
147
+ jq -n \
148
+ --slurpfile config "$orgFile" \
149
+ --slurpfile goals ".monomind/orgs/${org_name}-goals.json" 2>/dev/null \
150
+ --slurpfile routines ".monomind/orgs/${org_name}-routines.json" 2>/dev/null \
151
+ --slurpfile projects ".monomind/orgs/${org_name}-projects.json" 2>/dev/null \
152
+ '{
153
+ exported_at: (now|todate),
154
+ format_version: "1.0",
155
+ config: ($config[0] // {}),
156
+ goals: ($goals[0].goals // []),
157
+ routines: ($routines[0].routines // []),
158
+ projects: ($projects[0].projects // [])
159
+ }' > "$outPath"
160
+
161
+ echo "Exported: $outPath"
162
+ echo "$(wc -c < "$outPath") bytes — share this file to recreate the org on another machine."
163
+ echo "Import with: /mastermind:org-settings --action import --import-path $outPath"
164
+ ```
165
+
166
+ ### import
167
+
168
+ Import an org from a previously exported bundle:
169
+
170
+ ```bash
171
+ [ ! -f "$import_path" ] && { echo "ERROR: Import file not found: $import_path"; exit 1; }
172
+
173
+ # Validate format
174
+ fmt=$(jq -r '.format_version // "unknown"' "$import_path" 2>/dev/null || echo "unknown")
175
+ [ "$fmt" != "1.0" ] && echo "Warning: format_version '$fmt' — attempting import anyway."
176
+
177
+ importedName=$(jq -r '.config.name // .config.org_name // "unnamed"' "$import_path")
178
+ targetOrg="${org_name:-$importedName}"
179
+ mkdir -p ".monomind/orgs"
180
+
181
+ # Write config
182
+ jq '.config' "$import_path" > ".monomind/orgs/${targetOrg}.json"
183
+
184
+ # Write goals if present
185
+ goalsData=$(jq '.goals // []' "$import_path")
186
+ [ "$goalsData" != "[]" ] && echo "{\"goals\":$goalsData}" > ".monomind/orgs/${targetOrg}-goals.json"
187
+
188
+ # Write routines if present
189
+ routinesData=$(jq '.routines // []' "$import_path")
190
+ [ "$routinesData" != "[]" ] && echo "{\"routines\":$routinesData}" > ".monomind/orgs/${targetOrg}-routines.json"
191
+
192
+ # Write projects if present
193
+ projectsData=$(jq '.projects // []' "$import_path")
194
+ [ "$projectsData" != "[]" ] && echo "{\"projects\":$projectsData}" > ".monomind/orgs/${targetOrg}-projects.json"
195
+
196
+ echo "Imported org '${targetOrg}' from ${import_path}"
197
+ echo "Agents: $(jq '.config.roles | length' "$import_path")"
198
+ echo "Run /mastermind:env --org ${targetOrg} --action validate to check provider keys."
199
+ ```
200
+
201
+ ---
202
+
203
+ ## Step 3 — Return Output
204
+
205
+ ```yaml
206
+ domain: ops
207
+ status: complete
208
+ action: <action>
209
+ org: <org_name>
210
+ field: <field if edit>
211
+ ```
212
+
213
+ ---
214
+
215
+ ## Step 4 — Brain Write (standalone only)
216
+
217
+ If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.