@monoes/monomindcli 1.9.17 → 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 +63 -37
- 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 +28 -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 +250 -122
- 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
|
@@ -107,7 +107,12 @@ Adjust for the actual roles in this run. Assign `reports_to` on each role using
|
|
|
107
107
|
|
|
108
108
|
## Step 4 — Build Org Config
|
|
109
109
|
|
|
110
|
-
Produce an org config object using the resolved topology (not hardcoded to `hierarchical`)
|
|
110
|
+
Produce an org config object using the resolved topology (not hardcoded to `hierarchical`).
|
|
111
|
+
|
|
112
|
+
Ask the user (or infer from prompt) for the optional Paperclip-style fields:
|
|
113
|
+
- **Budget**: max token budget for this org run (e.g. 500000 tokens). Use `unlimited` if not specified.
|
|
114
|
+
- **Governance**: approval policy — `auto` (agents act freely) | `board` (sensitive actions require `/mastermind:approve`) | `strict` (all external actions need approval)
|
|
115
|
+
- **Adapter**: which AI model/adapter the CEO agent should use (e.g. `claude-sonnet-4-6`, `claude-opus-4-7`). Default: `claude-sonnet-4-6`.
|
|
111
116
|
|
|
112
117
|
```json
|
|
113
118
|
{
|
|
@@ -122,7 +127,11 @@ Produce an org config object using the resolved topology (not hardcoded to `hier
|
|
|
122
127
|
"title": "<display title>",
|
|
123
128
|
"agent_type": "<subagent_type slug from mapping table>",
|
|
124
129
|
"responsibilities": ["<1-3 bullet responsibilities>"],
|
|
125
|
-
"reports_to": "<role id or null>"
|
|
130
|
+
"reports_to": "<role id or null>",
|
|
131
|
+
"adapter_config": {
|
|
132
|
+
"model": "<claude model id>",
|
|
133
|
+
"max_tokens": 8192
|
|
134
|
+
}
|
|
126
135
|
}
|
|
127
136
|
],
|
|
128
137
|
"communication": [
|
|
@@ -133,6 +142,10 @@ Produce an org config object using the resolved topology (not hardcoded to `hier
|
|
|
133
142
|
"protocol": "direct"
|
|
134
143
|
}
|
|
135
144
|
],
|
|
145
|
+
"governance": {
|
|
146
|
+
"policy": "auto | board | strict",
|
|
147
|
+
"approvals_file": ".monomind/orgs/<org_name>-approvals.json"
|
|
148
|
+
},
|
|
136
149
|
"board_id": "<uuid — filled in Step 6 after board creation>",
|
|
137
150
|
"todo_col_id": "<uuid — filled in Step 6>",
|
|
138
151
|
"doing_col_id": "<uuid — filled in Step 6>",
|
|
@@ -142,7 +155,10 @@ Produce an org config object using the resolved topology (not hardcoded to `hier
|
|
|
142
155
|
"run_config": {
|
|
143
156
|
"checkpoint_interval_min": 30,
|
|
144
157
|
"max_concurrent_agents": 6,
|
|
145
|
-
"memory_namespace": "org:<org_name>"
|
|
158
|
+
"memory_namespace": "org:<org_name>",
|
|
159
|
+
"budget_tokens": "<number or 0 for unlimited>",
|
|
160
|
+
"alert_threshold": 0.8,
|
|
161
|
+
"ceo_adapter": "<model id>"
|
|
146
162
|
}
|
|
147
163
|
}
|
|
148
164
|
```
|
|
@@ -263,12 +279,14 @@ jq --arg board_id "$board_id" \
|
|
|
263
279
|
Read values from the saved JSON file and emit two events: `domain:complete` (for the session stream) and `org:create` (so the dashboard Orgs panel registers the new org immediately):
|
|
264
280
|
|
|
265
281
|
```bash
|
|
282
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
283
|
+
CTRL_URL=$(jq -r '.url // "http://localhost:4242"' "$REPO_ROOT/.monomind/control.json" 2>/dev/null || echo "http://localhost:4242")
|
|
266
284
|
orgName=$(jq -r '.name' "$orgJson")
|
|
267
285
|
goal_val=$(jq -r '.goal' "$orgJson")
|
|
268
286
|
rolesCount=$(jq '.roles | length // 0' "$orgJson")
|
|
269
287
|
|
|
270
288
|
# domain:complete — for session correlation
|
|
271
|
-
curl -s -X POST "
|
|
289
|
+
curl -s -X POST "${CTRL_URL}/api/mastermind/event" \
|
|
272
290
|
-H "Content-Type: application/json" \
|
|
273
291
|
-d "$(jq -cn \
|
|
274
292
|
--arg session "$session_id" \
|
|
@@ -279,7 +297,7 @@ curl -s -X POST "http://localhost:4242/api/mastermind/event" \
|
|
|
279
297
|
org:$orgName,goal:$goal,roles_count:$rolesCount,ts:(now*1000|floor)}')" || true
|
|
280
298
|
|
|
281
299
|
# org:create — so handleOrgEvent routes it to the Orgs panel event log
|
|
282
|
-
curl -s -X POST "
|
|
300
|
+
curl -s -X POST "${CTRL_URL}/api/mastermind/event" \
|
|
283
301
|
-H "Content-Type: application/json" \
|
|
284
302
|
-d "$(jq -cn \
|
|
285
303
|
--arg session "$session_id" \
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mastermind-diagnose
|
|
3
|
+
description: Mastermind diagnose — forensic procedure for investigating why agent work stalled, looped, or went too deep. Surfaces the exact stop-point in the issue tree, frames the fix as a product rule respecting three invariants (productive work continues / only real blockers stop work / no infinite loops), and delivers an approved plan before any code changes. Mirrors diagnose-why-work-stopped Paperclip skill.
|
|
4
|
+
type: domain-skill
|
|
5
|
+
default_mode: confirm
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Mastermind Diagnose
|
|
9
|
+
|
|
10
|
+
This skill is invoked by `mastermind:diagnose` or directly via `/mastermind:diagnose`.
|
|
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 investigate (required)
|
|
18
|
+
- `issue_id`: specific issue or task ID that stalled (optional — omit to scan all stalled work)
|
|
19
|
+
- `agent_id`: scope investigation to a specific agent (optional)
|
|
20
|
+
- `action`: scan | diagnose | report
|
|
21
|
+
- `caller`: command | master
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Three Invariants (MUST be preserved in all analysis and proposed fixes)
|
|
26
|
+
|
|
27
|
+
Every diagnosis and every proposed rule must hold these three invariants together:
|
|
28
|
+
|
|
29
|
+
1. **Productive work continues.** Agents with a clear next action must keep working without needing a human to wake them.
|
|
30
|
+
2. **Only real blockers stop work.** Stops happen when something genuinely cannot proceed (missing approval, missing dependency, human owner). Pseudo-stops must be detected and routed.
|
|
31
|
+
3. **No infinite loops.** Recovery and continuation loops must be bounded and distinguishable from genuinely productive continuation.
|
|
32
|
+
|
|
33
|
+
If a proposed fix violates any invariant, drop it or rework it. State explicitly how each invariant is held.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Step 0 — Brain Load (standalone only)
|
|
38
|
+
|
|
39
|
+
If `caller` is not "command", load brain context following _protocol.md Brain Load Procedure with namespace: `ops`.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Step 1 — Load Org State
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
orgFile=".monomind/orgs/${org_name}.json"
|
|
47
|
+
[ ! -f "$orgFile" ] && { echo "ERROR: Org '${org_name}' not found."; exit 1; }
|
|
48
|
+
|
|
49
|
+
stateFile=".monomind/orgs/${org_name}-state.json"
|
|
50
|
+
activityFile=".monomind/orgs/${org_name}-activity.jsonl"
|
|
51
|
+
issuesFile=".monomind/orgs/${org_name}-issues.json"
|
|
52
|
+
routinesFile=".monomind/orgs/${org_name}-routines.json"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Step 2 — Execute Action
|
|
58
|
+
|
|
59
|
+
### scan (default)
|
|
60
|
+
|
|
61
|
+
Scan for stalled work across the org:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
echo "STALL SCAN — $org_name"
|
|
65
|
+
echo "════════════════════════════════════════════════════════"
|
|
66
|
+
|
|
67
|
+
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
68
|
+
now=$(date +%s)
|
|
69
|
+
|
|
70
|
+
echo ""
|
|
71
|
+
echo "AGENT HEARTBEATS"
|
|
72
|
+
echo "────────────────────────────────────────────────────────"
|
|
73
|
+
|
|
74
|
+
python3 - "$orgFile" "$stateFile" "$now" <<'PYEOF'
|
|
75
|
+
import json, sys, os
|
|
76
|
+
from datetime import datetime, timezone
|
|
77
|
+
|
|
78
|
+
org = json.load(open(sys.argv[1]))
|
|
79
|
+
state_path = sys.argv[2]
|
|
80
|
+
now = int(sys.argv[3])
|
|
81
|
+
|
|
82
|
+
hb = {}
|
|
83
|
+
if os.path.exists(state_path):
|
|
84
|
+
try:
|
|
85
|
+
state = json.load(open(state_path))
|
|
86
|
+
for r in state.get("roles", []):
|
|
87
|
+
hb[r.get("id","")] = r.get("last_heartbeat")
|
|
88
|
+
except:
|
|
89
|
+
pass
|
|
90
|
+
|
|
91
|
+
roles = org.get("roles", [])
|
|
92
|
+
stalled = []
|
|
93
|
+
for r in roles:
|
|
94
|
+
rid = r.get("id","?")
|
|
95
|
+
title = r.get("title",rid)
|
|
96
|
+
last = hb.get(rid)
|
|
97
|
+
if not last:
|
|
98
|
+
age = "never"
|
|
99
|
+
stalled.append((rid, title, "no heartbeat"))
|
|
100
|
+
else:
|
|
101
|
+
try:
|
|
102
|
+
dt = datetime.fromisoformat(last.replace("Z","+00:00"))
|
|
103
|
+
age_s = now - int(dt.timestamp())
|
|
104
|
+
age = f"{age_s//60}m ago"
|
|
105
|
+
if age_s > 3600:
|
|
106
|
+
stalled.append((rid, title, f"stale ({age})"))
|
|
107
|
+
except:
|
|
108
|
+
age = "?"
|
|
109
|
+
print(f" {rid:<28} {title:<24} last: {last or 'never'}")
|
|
110
|
+
|
|
111
|
+
print()
|
|
112
|
+
if stalled:
|
|
113
|
+
print(f" STALLED AGENTS ({len(stalled)}):")
|
|
114
|
+
for rid, title, reason in stalled:
|
|
115
|
+
print(f" ⚠ {rid} {title} — {reason}")
|
|
116
|
+
else:
|
|
117
|
+
print(" All agents have recent heartbeats.")
|
|
118
|
+
PYEOF
|
|
119
|
+
|
|
120
|
+
echo ""
|
|
121
|
+
echo "OPEN ISSUES (stall candidates)"
|
|
122
|
+
echo "────────────────────────────────────────────────────────"
|
|
123
|
+
|
|
124
|
+
if [ -f "$issuesFile" ]; then
|
|
125
|
+
python3 - "$issuesFile" "$now" <<'PYEOF'
|
|
126
|
+
import json, sys
|
|
127
|
+
from datetime import datetime, timezone
|
|
128
|
+
|
|
129
|
+
data = json.load(open(sys.argv[1]))
|
|
130
|
+
now = int(sys.argv[2])
|
|
131
|
+
|
|
132
|
+
issues = [i for i in data.get("issues",[])
|
|
133
|
+
if i.get("status") in ("open","in_progress","in_review")]
|
|
134
|
+
|
|
135
|
+
if not issues:
|
|
136
|
+
print(" (no open/stalled issues)")
|
|
137
|
+
else:
|
|
138
|
+
for iss in issues[:20]:
|
|
139
|
+
iid = iss.get("id","?")[:28]
|
|
140
|
+
title = iss.get("title","-")[:38]
|
|
141
|
+
st = iss.get("status","?")
|
|
142
|
+
upd = iss.get("updatedAt","-")[:10]
|
|
143
|
+
asgn = (iss.get("assigneeId") or "—")[:20]
|
|
144
|
+
print(f" [{st:<11}] {title:<38} assigned={asgn} updated={upd}")
|
|
145
|
+
PYEOF
|
|
146
|
+
else
|
|
147
|
+
echo " (no issues file)"
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
echo ""
|
|
151
|
+
echo " For deep diagnosis: /mastermind:diagnose --org $org_name --action diagnose --issue-id <id>"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### diagnose
|
|
155
|
+
|
|
156
|
+
Forensic deep-dive on a specific issue or agent:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
echo "DEEP DIAGNOSIS — $org_name"
|
|
160
|
+
echo "════════════════════════════════════════════════════════"
|
|
161
|
+
echo ""
|
|
162
|
+
|
|
163
|
+
if [ -n "$issue_id" ]; then
|
|
164
|
+
echo "ISSUE: $issue_id"
|
|
165
|
+
echo "────────────────────────────────────────────────────────"
|
|
166
|
+
if [ -f "$issuesFile" ]; then
|
|
167
|
+
jq --arg id "$issue_id" '.issues[] | select(.id == $id)' "$issuesFile" 2>/dev/null \
|
|
168
|
+
|| echo " Issue not found: $issue_id"
|
|
169
|
+
fi
|
|
170
|
+
fi
|
|
171
|
+
|
|
172
|
+
if [ -n "$agent_id" ]; then
|
|
173
|
+
echo ""
|
|
174
|
+
echo "AGENT ACTIVITY: $agent_id"
|
|
175
|
+
echo "────────────────────────────────────────────────────────"
|
|
176
|
+
if [ -f "$activityFile" ]; then
|
|
177
|
+
grep "$agent_id" "$activityFile" | tail -20 | while read -r line; do
|
|
178
|
+
echo " $line"
|
|
179
|
+
done
|
|
180
|
+
else
|
|
181
|
+
echo " (no activity log found)"
|
|
182
|
+
fi
|
|
183
|
+
fi
|
|
184
|
+
|
|
185
|
+
echo ""
|
|
186
|
+
echo "DIAGNOSIS FRAMEWORK"
|
|
187
|
+
echo "────────────────────────────────────────────────────────"
|
|
188
|
+
echo " Walk the issue tree and find the exact stop-point."
|
|
189
|
+
echo " Common stall shapes:"
|
|
190
|
+
echo " 1. Issue is 'in_review' with no active run or pending interaction"
|
|
191
|
+
echo " 2. Issue is 'in_progress' after a successful run with no next action"
|
|
192
|
+
echo " 3. Blocker chain whose leaf is cancelled or inaccessible"
|
|
193
|
+
echo " 4. Recovery loop waking the same issue repeatedly after successful runs"
|
|
194
|
+
echo " 5. Stranded-work recovery treating its own recovery issues as source work"
|
|
195
|
+
echo ""
|
|
196
|
+
echo " Root cause format:"
|
|
197
|
+
echo " - Stop-point: <issue-id> stuck at status=<status> because <reason>"
|
|
198
|
+
echo " - Evidence: <run ids, timestamps, status transitions>"
|
|
199
|
+
echo " - Proposed rule: <rule that prevents recurrence>"
|
|
200
|
+
echo " - Invariant check: [1] productive work continues? [2] real blockers only? [3] bounded?"
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### report
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
echo "DIAGNOSTIC REPORT — $org_name"
|
|
207
|
+
echo "════════════════════════════════════════════════════════"
|
|
208
|
+
echo "Generated: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
209
|
+
echo ""
|
|
210
|
+
|
|
211
|
+
agentCount=$(jq '.roles | length' "$orgFile")
|
|
212
|
+
echo "Org agents: $agentCount"
|
|
213
|
+
|
|
214
|
+
if [ -f "$issuesFile" ]; then
|
|
215
|
+
openCount=$(jq '[.issues[] | select(.status == "open")] | length' "$issuesFile")
|
|
216
|
+
inpCount=$(jq '[.issues[] | select(.status == "in_progress")] | length' "$issuesFile")
|
|
217
|
+
doneCount=$(jq '[.issues[] | select(.status == "done")] | length' "$issuesFile")
|
|
218
|
+
echo "Issues: open=$openCount in_progress=$inpCount done=$doneCount"
|
|
219
|
+
fi
|
|
220
|
+
|
|
221
|
+
echo ""
|
|
222
|
+
echo "THREE INVARIANT STATUS:"
|
|
223
|
+
echo " 1. Productive work continues: [check heartbeats + open issues]"
|
|
224
|
+
echo " 2. Only real blockers stop: [check stall candidates above]"
|
|
225
|
+
echo " 3. No infinite loops: [check activity log for repeat patterns]"
|
|
226
|
+
echo ""
|
|
227
|
+
echo " Run scan first: /mastermind:diagnose --org $org_name --action scan"
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Step 3 — Return Output
|
|
233
|
+
|
|
234
|
+
```yaml
|
|
235
|
+
domain: ops
|
|
236
|
+
status: complete
|
|
237
|
+
action: <action>
|
|
238
|
+
org_name: <org_name>
|
|
239
|
+
invariants:
|
|
240
|
+
productive_work_continues: check
|
|
241
|
+
only_real_blockers: check
|
|
242
|
+
no_infinite_loops: check
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Step 4 — Brain Write (standalone only)
|
|
248
|
+
|
|
249
|
+
If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mastermind-env
|
|
3
|
+
description: Mastermind env — audit and configure the runtime environment for an org. Shows LLM provider config, memory backend, agent JWT settings, logging, and storage — highlighting missing or misconfigured values.
|
|
4
|
+
type: domain-skill
|
|
5
|
+
default_mode: auto
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Mastermind Env
|
|
9
|
+
|
|
10
|
+
This skill is invoked by `mastermind:env` or directly via `/mastermind:env`.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
- `brain_context`: BRAIN CONTEXT block
|
|
17
|
+
- `org_name`: org to inspect env for
|
|
18
|
+
- `action`: show | set | validate
|
|
19
|
+
- `key`: env var key to set (for set action)
|
|
20
|
+
- `value`: value to set (for set action — use env var reference, not inline secrets)
|
|
21
|
+
- `section`: llm | memory | jwt | logging | storage | all (default: all)
|
|
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 Config
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
orgFile=".monomind/orgs/${org_name}.json"
|
|
36
|
+
[ ! -f "$orgFile" ] && { echo "ERROR: Org '$org_name' not found."; exit 1; }
|
|
37
|
+
|
|
38
|
+
memNs="org:${org_name}"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Step 2 — Execute Action
|
|
44
|
+
|
|
45
|
+
### show (default)
|
|
46
|
+
|
|
47
|
+
Collect and display environment configuration for this org's agents:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
echo "╔══════════════════════════════════════════════════════╗"
|
|
51
|
+
echo "║ ENV AUDIT — org: ${org_name}"
|
|
52
|
+
echo "╚══════════════════════════════════════════════════════╝"
|
|
53
|
+
echo ""
|
|
54
|
+
|
|
55
|
+
# LLM / Adapter config
|
|
56
|
+
echo "LLM PROVIDER"
|
|
57
|
+
echo "────────────"
|
|
58
|
+
ceo_model=$(jq -r '.run_config.ceo_adapter // "claude-sonnet-4-6"' "$orgFile")
|
|
59
|
+
echo " CEO adapter model: $ceo_model"
|
|
60
|
+
jq -r '.roles[] | " \(.id): \(.adapter_config.model // "inherited from CEO")"' "$orgFile" 2>/dev/null
|
|
61
|
+
echo ""
|
|
62
|
+
|
|
63
|
+
# API key availability (check env vars, never print values)
|
|
64
|
+
echo "API KEYS (present/missing)"
|
|
65
|
+
echo "──────────────────────────"
|
|
66
|
+
for key in ANTHROPIC_API_KEY OPENAI_API_KEY GOOGLE_API_KEY; do
|
|
67
|
+
if [ -n "${!key}" ]; then
|
|
68
|
+
echo " $key: ✓ present (${!key:0:6}***)"
|
|
69
|
+
elif [ -f ".monomind/orgs/.secrets/${org_name}/${key}" ]; then
|
|
70
|
+
echo " $key: ✓ in org secrets"
|
|
71
|
+
else
|
|
72
|
+
echo " $key: ✗ MISSING"
|
|
73
|
+
fi
|
|
74
|
+
done
|
|
75
|
+
echo ""
|
|
76
|
+
|
|
77
|
+
# Memory config
|
|
78
|
+
echo "MEMORY"
|
|
79
|
+
echo "──────"
|
|
80
|
+
echo " namespace: org:${org_name}"
|
|
81
|
+
npx monomind@latest memory list --namespace "org:${org_name}" 2>/dev/null | wc -l | xargs echo " stored entries:"
|
|
82
|
+
echo ""
|
|
83
|
+
|
|
84
|
+
# Board config
|
|
85
|
+
echo "TASK BOARD"
|
|
86
|
+
echo "──────────"
|
|
87
|
+
board_id=$(jq -r '.board_id // "NOT CONFIGURED"' "$orgFile")
|
|
88
|
+
echo " board_id: $board_id"
|
|
89
|
+
echo " todo_col: $(jq -r '.todo_col_id // "NOT CONFIGURED"' "$orgFile")"
|
|
90
|
+
echo " doing_col: $(jq -r '.doing_col_id // "NOT CONFIGURED"' "$orgFile")"
|
|
91
|
+
echo " done_col: $(jq -r '.done_col_id // "NOT CONFIGURED"' "$orgFile")"
|
|
92
|
+
echo ""
|
|
93
|
+
|
|
94
|
+
# Run config
|
|
95
|
+
echo "RUN CONFIG"
|
|
96
|
+
echo "──────────"
|
|
97
|
+
jq -r '.run_config | to_entries[] | " \(.key): \(.value)"' "$orgFile" 2>/dev/null
|
|
98
|
+
echo ""
|
|
99
|
+
|
|
100
|
+
# Governance
|
|
101
|
+
echo "GOVERNANCE"
|
|
102
|
+
echo "──────────"
|
|
103
|
+
jq -r '" policy: \(.governance.policy // "auto")"' "$orgFile" 2>/dev/null
|
|
104
|
+
echo ""
|
|
105
|
+
|
|
106
|
+
# Dashboard
|
|
107
|
+
echo "DASHBOARD"
|
|
108
|
+
echo "─────────"
|
|
109
|
+
CTRL_URL=$(jq -r '.url // "http://localhost:4242"' ".monomind/control.json" 2>/dev/null || echo "http://localhost:4242")
|
|
110
|
+
echo " url: $CTRL_URL"
|
|
111
|
+
curl -s "${CTRL_URL}/api/health" >/dev/null 2>&1 && echo " status: ✓ reachable" || echo " status: ✗ not reachable"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### validate
|
|
115
|
+
|
|
116
|
+
Run a preflight check before starting an org run:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
echo "PREFLIGHT CHECK — org: $org_name"
|
|
120
|
+
errors=0
|
|
121
|
+
|
|
122
|
+
# Check all required env vars
|
|
123
|
+
for key in ANTHROPIC_API_KEY; do
|
|
124
|
+
if [ -z "${!key}" ] && [ ! -f ".monomind/orgs/.secrets/${org_name}/${key}" ]; then
|
|
125
|
+
echo " ✗ MISSING: $key"
|
|
126
|
+
errors=$((errors + 1))
|
|
127
|
+
else
|
|
128
|
+
echo " ✓ $key"
|
|
129
|
+
fi
|
|
130
|
+
done
|
|
131
|
+
|
|
132
|
+
# Check board IDs
|
|
133
|
+
board_id=$(jq -r '.board_id // empty' "$orgFile")
|
|
134
|
+
[ -z "$board_id" ] && { echo " ✗ MISSING: board_id — run /mastermind:createorg to rebuild"; errors=$((errors + 1)); } || echo " ✓ board_id"
|
|
135
|
+
|
|
136
|
+
# Check roles
|
|
137
|
+
role_count=$(jq '.roles | length' "$orgFile")
|
|
138
|
+
[ "$role_count" -eq 0 ] && { echo " ✗ MISSING: no roles defined"; errors=$((errors + 1)); } || echo " ✓ $role_count roles"
|
|
139
|
+
|
|
140
|
+
# Summary
|
|
141
|
+
echo ""
|
|
142
|
+
if [ "$errors" -eq 0 ]; then
|
|
143
|
+
echo "✓ All checks passed — org is ready to run."
|
|
144
|
+
else
|
|
145
|
+
echo "✗ $errors issue(s) found — resolve before running."
|
|
146
|
+
fi
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### set
|
|
150
|
+
|
|
151
|
+
Update a run_config key or governance field in the org JSON:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# Only allow safe keys — never set arbitrary JSON to prevent injection
|
|
155
|
+
allowed_keys="checkpoint_interval_min max_concurrent_agents budget_tokens alert_threshold ceo_adapter"
|
|
156
|
+
echo "$allowed_keys" | grep -qw "$key" || { echo "ERROR: Key '$key' not settable via this command. Edit $orgFile directly."; exit 1; }
|
|
157
|
+
|
|
158
|
+
tmp="${orgFile}.tmp"
|
|
159
|
+
jq --arg key "$key" --arg value "$value" \
|
|
160
|
+
'.run_config[$key] = ($value | if test("^[0-9]+$") then tonumber else . end)' \
|
|
161
|
+
"$orgFile" > "$tmp" && mv "$tmp" "$orgFile"
|
|
162
|
+
echo "Set run_config.$key = $value"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Agent Environment Template
|
|
168
|
+
|
|
169
|
+
When spawning agents, include this env block in their prompt:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# CEO/boss agent env block (prepend to all boss prompts):
|
|
173
|
+
echo "ENVIRONMENT:
|
|
174
|
+
Memory namespace: org:${orgName}
|
|
175
|
+
Dashboard: ${CTRL_URL}
|
|
176
|
+
Budget: $(jq -r '.run_config.budget_tokens // "unlimited"' "$orgFile") tokens
|
|
177
|
+
Governance: $(jq -r '.governance.policy // "auto"' "$orgFile")
|
|
178
|
+
ANTHROPIC_API_KEY: $([ -n "$ANTHROPIC_API_KEY" ] && echo "present" || echo "missing — check org secrets")
|
|
179
|
+
"
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Step 3 — Return Output
|
|
185
|
+
|
|
186
|
+
```yaml
|
|
187
|
+
domain: ops
|
|
188
|
+
status: complete
|
|
189
|
+
action: <action>
|
|
190
|
+
org: <org_name>
|
|
191
|
+
validation_errors: <N>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Step 4 — Brain Write (standalone only)
|
|
197
|
+
|
|
198
|
+
If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.
|