@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,261 @@
1
+ ---
2
+ name: mastermind-workspaces
3
+ description: Mastermind workspaces — manage isolated git worktree workspaces per project. List, attach, detach, stop, and prune workspaces. Grouped by project with running service counts and agent assignments.
4
+ type: domain-skill
5
+ default_mode: confirm
6
+ ---
7
+
8
+ # Mastermind Workspaces
9
+
10
+ This skill is invoked by `mastermind:workspaces` or directly via `/mastermind:workspaces`.
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 manage workspaces for (required)
18
+ - `action`: list | status | attach | detach | stop | prune
19
+ - `workspace_id`: workspace id (required for status/detach/stop)
20
+ - `project_id`: project to filter by (optional for list)
21
+ - `agent_id`: agent to assign to workspace (required for attach)
22
+ - `worktree_path`: filesystem path of the worktree (required for attach)
23
+ - `caller`: command | master
24
+
25
+ ---
26
+
27
+ ## Workspace Model
28
+
29
+ A workspace is a git worktree assigned to a project, optionally running services and assigned to an agent.
30
+
31
+ ```json
32
+ {
33
+ "id": "ws-abc123",
34
+ "project_id": "project-slug",
35
+ "agent_id": "backend-dev",
36
+ "worktree_path": "/tmp/monomind/worktrees/project-slug-abc123",
37
+ "branch": "feat/my-feature",
38
+ "status": "active",
39
+ "services": ["dev-server", "db-watcher"],
40
+ "createdAt": "2026-01-01T00:00:00Z",
41
+ "lastActiveAt": "2026-01-02T00:00:00Z"
42
+ }
43
+ ```
44
+
45
+ ---
46
+
47
+ ## Step 0 — Brain Load (standalone only)
48
+
49
+ If `caller` is not "command", load brain context following _protocol.md Brain Load Procedure with namespace: `ops`.
50
+
51
+ ---
52
+
53
+ ## Step 1 — Load Workspace Data
54
+
55
+ ```bash
56
+ orgFile=".monomind/orgs/${org_name}.json"
57
+ [ ! -f "$orgFile" ] && { echo "ERROR: Org '${org_name}' not found."; exit 1; }
58
+
59
+ wsFile=".monomind/orgs/${org_name}-workspaces.json"
60
+ [ ! -f "$wsFile" ] && echo '{"workspaces":[]}' > "$wsFile"
61
+
62
+ projectsFile=".monomind/orgs/${org_name}-projects.json"
63
+ worktreeRegistry=".monomind/orgs/${org_name}-worktrees.json"
64
+ ```
65
+
66
+ ---
67
+
68
+ ## Step 2 — Execute Action
69
+
70
+ ### list (default)
71
+
72
+ ```bash
73
+ echo "WORKSPACES — org: $org_name"
74
+ [ -n "$project_id" ] && echo "(filtered by project: $project_id)"
75
+ echo "────────────────────────────────────────────────────────"
76
+
77
+ total=$(jq '.workspaces | length' "$wsFile")
78
+
79
+ if [ "$total" -eq 0 ]; then
80
+ echo " No workspaces. Use --action attach to register one."
81
+ else
82
+ # Group by project
83
+ projects=$(jq -r --arg pid "${project_id:-}" '
84
+ .workspaces |
85
+ if $pid != "" then map(select(.project_id == $pid)) else . end |
86
+ [.[].project_id] | unique[]
87
+ ' "$wsFile")
88
+
89
+ while IFS= read -r proj; do
90
+ [ -z "$proj" ] && continue
91
+ projName=$([ -f "$projectsFile" ] && jq -r --arg pid "$proj" '.projects[] | select(.id == $pid) | .name // $pid' "$projectsFile" || echo "$proj")
92
+ echo ""
93
+ echo " PROJECT: $projName"
94
+ echo " ──────────────────────────────────────────────────"
95
+ printf " %-18s %-14s %-18s %-12s %-6s %s\n" "ID" "STATUS" "AGENT" "BRANCH" "SVCS" "PATH"
96
+
97
+ jq -r --arg pid "$proj" '.workspaces[] | select(.project_id == $pid) |
98
+ [.id, (.status // "unknown"), (.agent_id // "(none)"),
99
+ (.branch // "?"), ((.services // []) | length | tostring),
100
+ (.worktree_path // "-")]
101
+ | @tsv' "$wsFile" | while IFS=$'\t' read -r id st ag br svc path; do
102
+ printf " %-18s %-14s %-18s %-12s %-6s %s\n" "$id" "$st" "$ag" "$br" "$svc" "$path"
103
+ done
104
+ done <<< "$projects"
105
+ fi
106
+
107
+ echo ""
108
+ echo "Total: $total workspace(s)"
109
+ ```
110
+
111
+ ### status
112
+
113
+ ```bash
114
+ [ -z "$workspace_id" ] && { echo "ERROR: --workspace-id required."; exit 1; }
115
+ wsDef=$(jq -r --arg id "$workspace_id" '.workspaces[] | select(.id == $id)' "$wsFile")
116
+ [ -z "$wsDef" ] && { echo "ERROR: Workspace '$workspace_id' not found."; exit 1; }
117
+
118
+ echo "WORKSPACE STATUS — $workspace_id"
119
+ echo "────────────────────────────────────────────────────────"
120
+ echo "$wsDef" | jq -r '
121
+ " ID: \(.id)",
122
+ " Project: \(.project_id // "-")",
123
+ " Agent: \(.agent_id // "(unassigned)")",
124
+ " Branch: \(.branch // "?")",
125
+ " Status: \(.status // "unknown")",
126
+ " Created: \(.createdAt // "-")",
127
+ " Last active: \(.lastActiveAt // "-")",
128
+ " Path: \(.worktree_path // "-")"
129
+ '
130
+
131
+ # Check if worktree path exists
132
+ path=$(echo "$wsDef" | jq -r '.worktree_path // ""')
133
+ if [ -n "$path" ]; then
134
+ if [ -d "$path" ]; then
135
+ echo ""
136
+ echo " Worktree: EXISTS at $path"
137
+ branch=$(git -C "$path" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "?")
138
+ echo " Git branch: $branch"
139
+ dirty=$(git -C "$path" status --porcelain 2>/dev/null | wc -l | tr -d ' ')
140
+ [ "$dirty" -gt 0 ] && echo " Uncommitted changes: $dirty file(s)"
141
+ else
142
+ echo " WARNING: Worktree path does not exist: $path"
143
+ fi
144
+ fi
145
+
146
+ echo ""
147
+ echo "Services:"
148
+ echo "$wsDef" | jq -r '(.services // [])[] | " · \(.)"' || echo " (none)"
149
+ ```
150
+
151
+ ### attach
152
+
153
+ ```bash
154
+ [ -z "$project_id" ] && { echo "ERROR: --project-id required."; exit 1; }
155
+ [ -z "$worktree_path" ] && { echo "ERROR: --worktree-path required."; exit 1; }
156
+
157
+ [ ! -d "$worktree_path" ] && { echo "ERROR: Path does not exist: $worktree_path"; exit 1; }
158
+
159
+ wsId="ws-$(openssl rand -hex 4 2>/dev/null || python3 -c 'import secrets; print(secrets.token_hex(4))')"
160
+ branch=$(git -C "$worktree_path" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
161
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
162
+
163
+ tmp="${wsFile}.tmp"
164
+ jq --arg id "$wsId" \
165
+ --arg pid "$project_id" \
166
+ --arg ag "${agent_id:-}" \
167
+ --arg path "$worktree_path" \
168
+ --arg branch "$branch" \
169
+ --arg ts "$ts" \
170
+ '.workspaces += [{"id":$id,"project_id":$pid,
171
+ "agent_id":(if $ag != "" then $ag else null end),
172
+ "worktree_path":$path,"branch":$branch,
173
+ "status":"active","services":[],"createdAt":$ts,"lastActiveAt":$ts}]' \
174
+ "$wsFile" > "$tmp" && mv "$tmp" "$wsFile"
175
+
176
+ echo "Workspace attached: $wsId"
177
+ echo " Project: $project_id"
178
+ echo " Agent: ${agent_id:-(unassigned)}"
179
+ echo " Branch: $branch"
180
+ echo " Path: $worktree_path"
181
+ ```
182
+
183
+ ### detach
184
+
185
+ ```bash
186
+ [ -z "$workspace_id" ] && { echo "ERROR: --workspace-id required."; exit 1; }
187
+ tmp="${wsFile}.tmp"
188
+ jq --arg id "$workspace_id" \
189
+ '.workspaces = [.workspaces[] | if .id == $id then .status = "detached" else . end]' \
190
+ "$wsFile" > "$tmp" && mv "$tmp" "$wsFile"
191
+ echo "Workspace '$workspace_id' → detached. The worktree is preserved on disk."
192
+ ```
193
+
194
+ ### stop
195
+
196
+ ```bash
197
+ [ -z "$workspace_id" ] && { echo "ERROR: --workspace-id required."; exit 1; }
198
+ wsDef=$(jq -r --arg id "$workspace_id" '.workspaces[] | select(.id == $id)' "$wsFile")
199
+ [ -z "$wsDef" ] && { echo "ERROR: Workspace '$workspace_id' not found."; exit 1; }
200
+
201
+ services=$(echo "$wsDef" | jq -r '(.services // [])[]')
202
+ if [ -n "$services" ]; then
203
+ echo "Stopping services for workspace $workspace_id…"
204
+ while IFS= read -r svc; do
205
+ echo " Stopping: $svc"
206
+ done <<< "$services"
207
+ fi
208
+
209
+ tmp="${wsFile}.tmp"
210
+ jq --arg id "$workspace_id" --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
211
+ '.workspaces = [.workspaces[] | if .id == $id then .status = "stopped" | .services = [] | .lastActiveAt = $ts else . end]' \
212
+ "$wsFile" > "$tmp" && mv "$tmp" "$wsFile"
213
+
214
+ echo "Workspace '$workspace_id' stopped."
215
+ ```
216
+
217
+ ### prune
218
+
219
+ ```bash
220
+ echo "Pruning stopped/detached workspaces for org '$org_name'…"
221
+
222
+ before=$(jq '.workspaces | length' "$wsFile")
223
+ removed=0
224
+ orphaned=0
225
+
226
+ tmp="${wsFile}.tmp"
227
+ jq '.workspaces = [.workspaces[] | select(.status != "stopped" and .status != "detached")]' \
228
+ "$wsFile" > "$tmp" && mv "$tmp" "$wsFile"
229
+
230
+ after=$(jq '.workspaces | length' "$wsFile")
231
+ removed=$((before - after))
232
+
233
+ # Find orphaned worktrees (path gone)
234
+ while IFS= read -r path; do
235
+ [ -z "$path" ] || [ "$path" = "null" ] && continue
236
+ [ ! -d "$path" ] && orphaned=$((orphaned + 1))
237
+ done < <(jq -r '.workspaces[].worktree_path // ""' "$wsFile")
238
+
239
+ echo " Removed $removed stopped/detached workspace record(s)."
240
+ [ "$orphaned" -gt 0 ] && echo " WARNING: $orphaned workspace(s) have missing worktree paths. Run --action status to investigate."
241
+ echo "Done. Active workspaces: $(jq '.workspaces | length' "$wsFile")"
242
+ ```
243
+
244
+ ---
245
+
246
+ ## Step 3 — Return Output
247
+
248
+ ```yaml
249
+ domain: ops
250
+ status: complete
251
+ action: <action>
252
+ org: <org_name>
253
+ workspace_id: <id if applicable>
254
+ workspaces_total: <N>
255
+ ```
256
+
257
+ ---
258
+
259
+ ## Step 4 — Brain Write (standalone only)
260
+
261
+ If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.
@@ -0,0 +1,187 @@
1
+ ---
2
+ name: mastermind-worktree
3
+ description: Mastermind worktree — create isolated git worktrees for org agents. Each agent gets its own branch and working directory, preventing conflicts when multiple agents edit code simultaneously.
4
+ type: domain-skill
5
+ default_mode: confirm
6
+ ---
7
+
8
+ # Mastermind Worktree
9
+
10
+ This skill is invoked by `mastermind:worktree` or directly via `/mastermind:worktree`.
11
+
12
+ ---
13
+
14
+ ## Inputs
15
+
16
+ - `brain_context`: BRAIN CONTEXT block
17
+ - `org_name`: org whose agents need worktrees
18
+ - `action`: list | create | assign | merge | cleanup | status
19
+ - `agent_id`: role id of the agent to create a worktree for
20
+ - `base_branch`: branch to create worktree from (default: current HEAD)
21
+ - `branch_name`: explicit branch name (default: `org/<org_name>/<agent_id>/<YYYYMMDD-HHMMSS>`)
22
+ - `worktree_path`: explicit path (default: `.monomind/worktrees/<org_name>/<agent_id>`)
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
+ ## Concept
34
+
35
+ When multiple agents in an org need to edit files concurrently (e.g. a content writer, designer, and developer all working on different parts of a codebase), git worktrees give each agent its own checkout of the repo on a dedicated branch. Changes are isolated until the org's boss (or a human) merges them.
36
+
37
+ Worktree registry is stored in `.monomind/orgs/<org_name>-worktrees.json`.
38
+
39
+ ---
40
+
41
+ ## Step 1 — Load Worktree Registry
42
+
43
+ ```bash
44
+ orgFile=".monomind/orgs/${org_name}.json"
45
+ worktreesFile=".monomind/orgs/${org_name}-worktrees.json"
46
+ [ ! -f "$worktreesFile" ] && echo '{"worktrees":[]}' > "$worktreesFile"
47
+ ```
48
+
49
+ ---
50
+
51
+ ## Step 2 — Execute Action
52
+
53
+ ### list (default)
54
+
55
+ ```bash
56
+ echo "WORKTREES — org: $org_name"
57
+ echo "──────────────────────────────────────────────"
58
+ git worktree list 2>/dev/null | head -20
59
+
60
+ echo ""
61
+ echo "REGISTRY:"
62
+ jq -r '.worktrees[] | "[\(.agent_id)] branch=\(.branch) path=\(.path) created=\(.created_at)"' \
63
+ "$worktreesFile" 2>/dev/null || echo "No registered worktrees."
64
+ ```
65
+
66
+ ### create
67
+
68
+ Create a worktree for a specific agent:
69
+
70
+ ```bash
71
+ agentConfig=$(jq --arg id "$agent_id" '.roles[] | select(.id == $id)' "$orgFile")
72
+ [ -z "$agentConfig" ] && { echo "ERROR: Agent '$agent_id' not found in org."; exit 1; }
73
+
74
+ # Resolve branch name
75
+ timestamp=$(date +%Y%m%d-%H%M%S)
76
+ branch="${branch_name:-org/${org_name}/${agent_id}/${timestamp}}"
77
+ wtPath="${worktree_path:-.monomind/worktrees/${org_name}/${agent_id}}"
78
+
79
+ # Create the worktree
80
+ git worktree add -b "$branch" "$wtPath" "${base_branch:-HEAD}" 2>&1
81
+ if [ $? -ne 0 ]; then
82
+ echo "ERROR: Failed to create worktree. Check that git is initialized and the base branch exists."
83
+ exit 1
84
+ fi
85
+
86
+ echo "Created worktree: $wtPath (branch: $branch)"
87
+
88
+ # Register in worktrees file
89
+ tmp="${worktreesFile}.tmp"
90
+ jq --arg agent "$agent_id" \
91
+ --arg branch "$branch" \
92
+ --arg path "$wtPath" \
93
+ --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
94
+ '.worktrees = [.worktrees[] | select(.agent_id != $agent)] +
95
+ [{"agent_id":$agent,"branch":$branch,"path":$path,"status":"active","created_at":$ts}]' \
96
+ "$worktreesFile" > "$tmp" && mv "$tmp" "$worktreesFile"
97
+ ```
98
+
99
+ Include worktree path in agent prompt when spawning:
100
+
101
+ ```
102
+ WORKTREE: Your isolated working directory is ${wtPath}
103
+ All file edits should happen inside this directory.
104
+ Branch: ${branch}
105
+ To view your changes: git -C "${wtPath}" diff
106
+ ```
107
+
108
+ ### merge
109
+
110
+ Merge a completed agent's worktree branch back to the base:
111
+
112
+ ```bash
113
+ wt=$(jq --arg id "$agent_id" '.worktrees[] | select(.agent_id == $id)' "$worktreesFile")
114
+ branch=$(echo "$wt" | jq -r '.branch')
115
+ wtPath=$(echo "$wt" | jq -r '.path')
116
+
117
+ echo "Merging branch $branch..."
118
+ git merge "$branch" --no-ff -m "org($org_name): merge $agent_id work from $branch"
119
+ if [ $? -eq 0 ]; then
120
+ echo "Merge successful. Removing worktree..."
121
+ git worktree remove "$wtPath" --force 2>/dev/null || true
122
+ git branch -d "$branch" 2>/dev/null || true
123
+ # Update registry
124
+ tmp="${worktreesFile}.tmp"
125
+ jq --arg id "$agent_id" \
126
+ '.worktrees = [.worktrees[] | if .agent_id == $id then .status = "merged" | .merged_at = (now|todate) else . end]' \
127
+ "$worktreesFile" > "$tmp" && mv "$tmp" "$worktreesFile"
128
+ echo "Worktree merged and removed."
129
+ else
130
+ echo "ERROR: Merge conflict on $branch. Resolve manually then run cleanup."
131
+ fi
132
+ ```
133
+
134
+ ### status
135
+
136
+ Show diff summary for all active agent worktrees:
137
+
138
+ ```bash
139
+ jq -r '.worktrees[] | select(.status == "active") | "\(.agent_id) \(.path) \(.branch)"' \
140
+ "$worktreesFile" | while read -r agent path branch; do
141
+ echo "[$agent] branch=$branch"
142
+ git -C "$path" diff --stat 2>/dev/null | tail -3
143
+ echo ""
144
+ done
145
+ ```
146
+
147
+ ### cleanup
148
+
149
+ Remove all merged or abandoned worktrees:
150
+
151
+ ```bash
152
+ git worktree prune 2>/dev/null
153
+ jq -r '.worktrees[] | select(.status != "active") | .path' "$worktreesFile" | while read -r path; do
154
+ [ -d "$path" ] && git worktree remove "$path" --force 2>/dev/null || true
155
+ done
156
+ echo "Pruned stale worktrees."
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Integration with runorg / heartbeat
162
+
163
+ When a boss agent assigns code-editing work to an agent, it should:
164
+
165
+ 1. Call `/mastermind:worktree --action create --agent-id <role_id>`
166
+ 2. Include the worktree path in the agent's task prompt
167
+ 3. When the agent marks the task Done, call `/mastermind:worktree --action merge --agent-id <role_id>`
168
+
169
+ ---
170
+
171
+ ## Step 3 — Return Output
172
+
173
+ ```yaml
174
+ domain: ops
175
+ status: complete
176
+ action: <action>
177
+ org: <org_name>
178
+ agent_id: <agent_id if applicable>
179
+ branch: <branch if applicable>
180
+ worktree_path: <path if applicable>
181
+ ```
182
+
183
+ ---
184
+
185
+ ## Step 4 — Brain Write (standalone only)
186
+
187
+ If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.
@@ -181,7 +181,7 @@ const DIRECTORIES = {
181
181
  * Execute initialization
182
182
  */
183
183
  /**
184
- * Remove legacy ruflo/ruv-swarm configuration from existing project files.
184
+ * Remove legacy ruv-swarm configuration from existing project files.
185
185
  * Safe to call even if no legacy config exists.
186
186
  */
187
187
  function cleanupLegacyTools(targetDir) {
@@ -224,29 +224,29 @@ function cleanupLegacyTools(targetDir) {
224
224
  }
225
225
  catch { /* non-fatal */ }
226
226
  }
227
- // Clean ruflo / ruv-swarm from .claude/settings.json hooks and fix MCP package name
227
+ // Clean ruv-swarm from .claude/settings.json hooks and fix MCP package name
228
228
  const settingsPath = path.join(targetDir, '.claude', 'settings.json');
229
229
  if (fs.existsSync(settingsPath)) {
230
230
  try {
231
231
  const raw = fs.readFileSync(settingsPath, 'utf-8');
232
232
  const settings = JSON.parse(raw);
233
233
  let settingsChanged = false;
234
- if (raw.includes('ruflo') || raw.includes('ruv-swarm')) {
235
- // Remove ruflo-referencing hook entries from all hook arrays
234
+ if (raw.includes('ruv-swarm')) {
235
+ // Remove legacy ruv-swarm hook entries from all hook arrays
236
236
  const hookKeys = ['PreToolUse', 'PostToolUse', 'UserPromptSubmit', 'SessionStart', 'SessionEnd', 'Stop', 'SubagentStart', 'SubagentStop', 'PreCompact'];
237
237
  for (const key of hookKeys) {
238
238
  if (Array.isArray(settings.hooks?.[key])) {
239
239
  const before = settings.hooks[key].length;
240
240
  settings.hooks[key] = settings.hooks[key].filter((entry) => {
241
241
  const str = JSON.stringify(entry);
242
- return !str.includes('ruflo') && !str.includes('ruv-swarm');
242
+ return !str.includes('ruv-swarm');
243
243
  });
244
244
  if (settings.hooks[key].length !== before)
245
245
  settingsChanged = true;
246
246
  }
247
247
  }
248
248
  if (settingsChanged) {
249
- cleaned.push('.claude/settings.json: removed ruflo/ruv-swarm hooks');
249
+ cleaned.push('.claude/settings.json: removed ruv-swarm hooks');
250
250
  }
251
251
  }
252
252
  // Fix wrong MCP package name in mcpServers
@@ -283,7 +283,7 @@ export async function executeInit(options) {
283
283
  };
284
284
  const targetDir = options.targetDir;
285
285
  try {
286
- // Remove legacy ruflo/ruv-swarm configs before writing new ones
286
+ // Remove legacy ruv-swarm configs before writing new ones
287
287
  const legacyCleaned = cleanupLegacyTools(targetDir);
288
288
  for (const msg of legacyCleaned) {
289
289
  result.created.files.push(`[cleaned] ${msg}`);
@@ -620,7 +620,7 @@ export async function executeUpgrade(targetDir, upgradeSettings = false) {
620
620
  settingsUpdated: [],
621
621
  };
622
622
  try {
623
- // Fix legacy ruflo/ruv-swarm configs and old MCP package names
623
+ // Fix legacy ruv-swarm configs and old MCP package names
624
624
  const legacyCleaned = cleanupLegacyTools(targetDir);
625
625
  for (const msg of legacyCleaned) {
626
626
  result.updated.push(`[cleaned] ${msg}`);