@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,255 @@
1
+ ---
2
+ name: mastermind-goal-detail
3
+ description: Mastermind goal-detail — deep per-goal inspection and management. Show sub-goal tree, linked projects, edit title/status/description/priority, add child goals, and close or reopen a single goal within an org.
4
+ type: domain-skill
5
+ default_mode: auto
6
+ ---
7
+
8
+ # Mastermind Goal Detail
9
+
10
+ This skill is invoked by `mastermind:goal-detail` or directly via `/mastermind:goal-detail`.
11
+
12
+ ---
13
+
14
+ ## Inputs
15
+
16
+ - `brain_context`: BRAIN CONTEXT block (injected by command, or loaded below if standalone)
17
+ - `org_name`: org the goal belongs to (required)
18
+ - `goal_id`: goal id/slug (required)
19
+ - `action`: show | tree | projects | edit | add-child | close | reopen
20
+ - `field`: field to edit (title | description | status | priority | parent_id)
21
+ - `value`: new field value (required for edit)
22
+ - `child_title`: title for the new child goal (required for add-child)
23
+ - `child_description`: description for the new child goal (optional)
24
+ - `caller`: command | master
25
+
26
+ ---
27
+
28
+ ## Goal Status Flow
29
+
30
+ ```
31
+ open → in_progress → done
32
+ └──────────────────┘ (can reopen)
33
+ ```
34
+
35
+ ## Priority Levels
36
+
37
+ `critical` | `high` | `medium` | `low`
38
+
39
+ ---
40
+
41
+ ## Step 0 — Brain Load (standalone only)
42
+
43
+ If `caller` is not "command", load brain context following _protocol.md Brain Load Procedure with namespace: `ops`.
44
+
45
+ ---
46
+
47
+ ## Step 1 — Load Goal Data
48
+
49
+ ```bash
50
+ orgFile=".monomind/orgs/${org_name}.json"
51
+ [ ! -f "$orgFile" ] && { echo "ERROR: Org '${org_name}' not found."; exit 1; }
52
+
53
+ goalsFile=".monomind/orgs/${org_name}-goals.json"
54
+ [ ! -f "$goalsFile" ] && { echo "ERROR: No goals file for org '$org_name'. Create goals via /mastermind:goals."; exit 1; }
55
+
56
+ goalDef=$(jq -r --arg id "$goal_id" '.goals[] | select(.id == $id or .slug == $id)' "$goalsFile")
57
+ [ -z "$goalDef" ] && { echo "ERROR: Goal '$goal_id' not found in org '$org_name'."; exit 1; }
58
+
59
+ resolvedId=$(echo "$goalDef" | jq -r '.id')
60
+ projectsFile=".monomind/orgs/${org_name}-projects.json"
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Step 2 — Execute Action
66
+
67
+ ### show (default)
68
+
69
+ ```bash
70
+ echo "GOAL DETAIL — $goal_id @ $org_name"
71
+ echo "────────────────────────────────────────────────────────"
72
+
73
+ echo "$goalDef" | jq -r '
74
+ " ID: \(.id)",
75
+ " Title: \(.title // "(no title)")",
76
+ " Status: \(.status // "open")",
77
+ " Priority: \(.priority // "medium")",
78
+ " Parent: \(.parent_id // "(root goal)")",
79
+ " Created: \(.created_at // "-")",
80
+ " Updated: \(.updated_at // "-")"
81
+ '
82
+
83
+ # Sub-goals count
84
+ subCount=$(jq --arg pid "$resolvedId" '[.goals[] | select(.parent_id == $pid)] | length' "$goalsFile" 2>/dev/null || echo 0)
85
+ doneCount=$(jq --arg pid "$resolvedId" '[.goals[] | select(.parent_id == $pid and .status == "done")] | length' "$goalsFile" 2>/dev/null || echo 0)
86
+ echo " Sub-goals: $subCount total, $doneCount done"
87
+
88
+ # Linked projects
89
+ projCount=$(echo "$goalDef" | jq -r '(.linked_projects // []) | length')
90
+ echo " Projects: $projCount linked"
91
+
92
+ # Description
93
+ desc=$(echo "$goalDef" | jq -r '.description // ""')
94
+ if [ -n "$desc" ]; then
95
+ echo ""
96
+ echo "DESCRIPTION"
97
+ echo "────────────────────────────────────────────────────────"
98
+ echo "$desc"
99
+ fi
100
+ ```
101
+
102
+ ### tree
103
+
104
+ ```bash
105
+ echo "SUB-GOAL TREE — $goal_id"
106
+ echo "────────────────────────────────────────────────────────"
107
+
108
+ function print_tree() {
109
+ local pid="$1"
110
+ local indent="$2"
111
+ local children
112
+ children=$(jq -r --arg pid "$pid" '.goals[] | select(.parent_id == $pid) |
113
+ [.id, (.status // "open"), (.title // "(no title)")] | @tsv' "$goalsFile" 2>/dev/null)
114
+ while IFS=$'\t' read -r cid cst ctitle; do
115
+ [ -z "$cid" ] && continue
116
+ echo "${indent}[${cst}] ${ctitle} (${cid})"
117
+ print_tree "$cid" " ${indent}"
118
+ done <<< "$children"
119
+ }
120
+
121
+ # Print root goal
122
+ rootTitle=$(echo "$goalDef" | jq -r '.title // "(no title)"')
123
+ rootStatus=$(echo "$goalDef" | jq -r '.status // "open"')
124
+ echo "[${rootStatus}] ${rootTitle} (${resolvedId})"
125
+ print_tree "$resolvedId" " "
126
+ ```
127
+
128
+ ### projects
129
+
130
+ ```bash
131
+ echo "LINKED PROJECTS — $goal_id"
132
+ echo "────────────────────────────────────────────────────────"
133
+
134
+ linkedIds=$(echo "$goalDef" | jq -r '(.linked_projects // [])[]')
135
+ if [ -z "$linkedIds" ]; then
136
+ echo " No linked projects."
137
+ else
138
+ while IFS= read -r pid; do
139
+ [ -z "$pid" ] && continue
140
+ if [ -f "$projectsFile" ]; then
141
+ projInfo=$(jq -r --arg id "$pid" '.projects[] | select(.id == $id) |
142
+ " [\(.status // "active")] \(.name // $id) — \(.description // "")"' "$projectsFile" 2>/dev/null)
143
+ [ -n "$projInfo" ] && echo "$projInfo" || echo " [$pid] (project not found in projects file)"
144
+ else
145
+ echo " $pid"
146
+ fi
147
+ done <<< "$linkedIds"
148
+ fi
149
+
150
+ echo ""
151
+ echo "Issues referencing this goal:"
152
+ issuesFile=".monomind/orgs/${org_name}-issues.json"
153
+ if [ -f "$issuesFile" ]; then
154
+ count=$(jq --arg gid "$resolvedId" '[.issues[] | select(.goal_id == $gid)] | length' "$issuesFile" 2>/dev/null || echo 0)
155
+ echo " $count issue(s) linked to this goal."
156
+ fi
157
+ ```
158
+
159
+ ### edit
160
+
161
+ ```bash
162
+ [ -z "$field" ] && { echo "ERROR: --field required (title|description|status|priority|parent_id)."; exit 1; }
163
+ [ -z "$value" ] && { echo "ERROR: --value required."; exit 1; }
164
+
165
+ validFields="title description status priority parent_id"
166
+ echo "$validFields" | tr ' ' '\n' | grep -qx "$field" || {
167
+ echo "ERROR: Unknown field '$field'. Valid: $validFields"; exit 1
168
+ }
169
+
170
+ if [ "$field" = "status" ]; then
171
+ case "$value" in open|in_progress|done|cancelled) : ;; *)
172
+ echo "ERROR: status must be one of: open, in_progress, done, cancelled"; exit 1 ;;
173
+ esac
174
+ fi
175
+ if [ "$field" = "priority" ]; then
176
+ case "$value" in critical|high|medium|low) : ;; *)
177
+ echo "ERROR: priority must be one of: critical, high, medium, low"; exit 1 ;;
178
+ esac
179
+ fi
180
+
181
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
182
+ tmp="${goalsFile}.tmp"
183
+ jq --arg id "$resolvedId" --arg field "$field" --arg val "$value" --arg ts "$ts" \
184
+ '.goals = [.goals[] | if .id == $id then .[$field] = $val | .updated_at = $ts else . end]' \
185
+ "$goalsFile" > "$tmp" && mv "$tmp" "$goalsFile"
186
+
187
+ echo "Goal '$goal_id' updated: $field = $value"
188
+ ```
189
+
190
+ ### add-child
191
+
192
+ ```bash
193
+ [ -z "$child_title" ] && { echo "ERROR: --child-title required."; exit 1; }
194
+
195
+ childId="goal-$(openssl rand -hex 4 2>/dev/null || python3 -c 'import secrets; print(secrets.token_hex(4))')"
196
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
197
+
198
+ tmp="${goalsFile}.tmp"
199
+ jq --arg id "$childId" \
200
+ --arg title "$child_title" \
201
+ --arg desc "${child_description:-}" \
202
+ --arg pid "$resolvedId" \
203
+ --arg ts "$ts" \
204
+ '.goals += [{"id":$id,"title":$title,
205
+ "description":(if $desc != "" then $desc else null end),
206
+ "parent_id":$pid,"status":"open","priority":"medium",
207
+ "linked_projects":[],"created_at":$ts,"updated_at":$ts}]' \
208
+ "$goalsFile" > "$tmp" && mv "$tmp" "$goalsFile"
209
+
210
+ echo "Sub-goal created: $childId"
211
+ echo " Title: $child_title"
212
+ echo " Parent: $goal_id"
213
+ ```
214
+
215
+ ### close
216
+
217
+ ```bash
218
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
219
+ tmp="${goalsFile}.tmp"
220
+ jq --arg id "$resolvedId" --arg ts "$ts" \
221
+ '.goals = [.goals[] | if .id == $id then .status = "done" | .updated_at = $ts | .closed_at = $ts else . end]' \
222
+ "$goalsFile" > "$tmp" && mv "$tmp" "$goalsFile"
223
+ echo "Goal '$goal_id' → done."
224
+ ```
225
+
226
+ ### reopen
227
+
228
+ ```bash
229
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
230
+ tmp="${goalsFile}.tmp"
231
+ jq --arg id "$resolvedId" --arg ts "$ts" \
232
+ '.goals = [.goals[] | if .id == $id then .status = "open" | .updated_at = $ts | .closed_at = null else . end]' \
233
+ "$goalsFile" > "$tmp" && mv "$tmp" "$goalsFile"
234
+ echo "Goal '$goal_id' → reopened."
235
+ ```
236
+
237
+ ---
238
+
239
+ ## Step 3 — Return Output
240
+
241
+ ```yaml
242
+ domain: ops
243
+ status: complete
244
+ action: <action>
245
+ org: <org_name>
246
+ goal_id: <goal_id>
247
+ goal_status: <status>
248
+ sub_goals: <N>
249
+ ```
250
+
251
+ ---
252
+
253
+ ## Step 4 — Brain Write (standalone only)
254
+
255
+ If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.
@@ -0,0 +1,149 @@
1
+ ---
2
+ name: mastermind-goals
3
+ description: Mastermind goals — define, track, and visualize hierarchical goals for an org. Goals link to tasks, have progress metrics, and form a goal tree.
4
+ type: domain-skill
5
+ default_mode: confirm
6
+ ---
7
+
8
+ # Mastermind Goals
9
+
10
+ This skill is invoked by `mastermind:goals` or directly via `/mastermind:goals`.
11
+
12
+ ---
13
+
14
+ ## Inputs
15
+
16
+ - `brain_context`: BRAIN CONTEXT block
17
+ - `org_name`: org whose goals to manage
18
+ - `action`: list | add | update | link | close
19
+ - `goal_title`: title for add
20
+ - `goal_id`: slug for update/link/close
21
+ - `parent_goal`: parent goal slug (for hierarchy)
22
+ - `status`: active | achieved | paused | cancelled
23
+ - `metric`: success metric description (e.g. "100 blog posts published")
24
+ - `caller`: command | master
25
+
26
+ ---
27
+
28
+ ## Step 0 — Brain Load (standalone only)
29
+
30
+ If `caller` is not "command", load brain context following _protocol.md Brain Load Procedure with namespace: `ops`.
31
+
32
+ ---
33
+
34
+ ## Step 1 — Load Goals State
35
+
36
+ Goals are stored in `.monomind/orgs/<org_name>-goals.json`. Create if missing:
37
+
38
+ ```bash
39
+ goalsFile=".monomind/orgs/${org_name}-goals.json"
40
+ [ ! -f "$goalsFile" ] && echo '{"goals":[]}' > "$goalsFile"
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Step 2 — Execute Action
46
+
47
+ ### list (default)
48
+
49
+ Render goal tree with progress metrics. Goals without a `parent` are root goals; child goals are indented:
50
+
51
+ ```bash
52
+ jq -r '
53
+ def tree(gs; pid):
54
+ gs | map(select(.parent == pid)) | .[] |
55
+ (" " * (.depth // 0)) + "[\(.id)] \(.title) [\(.status // "active")] \(.metric // "")" ,
56
+ tree(gs; .id);
57
+ .goals | tree(.; null)
58
+ ' "$goalsFile" 2>/dev/null || jq -r '.goals[] | "[\(.id)] \(.title) [\(.status // "active")]"' "$goalsFile"
59
+ ```
60
+
61
+ Render as:
62
+ ```
63
+ GOALS — org: <org_name>
64
+ ──────────────────────────────────────
65
+ [grow-audience] Grow audience to 10k followers [active]
66
+ [content-output] Publish 3 posts/week [active] metric: 3 posts/week
67
+ [blog-drafts] 5 draft articles in pipeline [active]
68
+ [improve-seo] Rank top 10 for target keywords [active]
69
+ ```
70
+
71
+ ### add
72
+
73
+ ```bash
74
+ goal_slug=$(echo "$goal_title" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | tr -s '-')
75
+ tmp="${goalsFile}.tmp"
76
+ jq --arg id "$goal_slug" \
77
+ --arg title "$goal_title" \
78
+ --arg parent "${parent_goal:-}" \
79
+ --arg status "active" \
80
+ --arg metric "${metric:-}" \
81
+ --arg created_at "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
82
+ '.goals += [{"id":$id,"title":$title,"parent":($parent|if .=="" then null else . end),"status":$status,"metric":$metric,"created_at":$created_at,"tasks":[]}]' \
83
+ "$goalsFile" > "$tmp" && mv "$tmp" "$goalsFile"
84
+ echo "Goal added: $goal_slug"
85
+ ```
86
+
87
+ Emit `org:goal:created` event to dashboard.
88
+
89
+ ### update
90
+
91
+ Update goal status or metric:
92
+
93
+ ```bash
94
+ tmp="${goalsFile}.tmp"
95
+ jq --arg id "$goal_id" \
96
+ --arg status "${status:-}" \
97
+ --arg metric "${metric:-}" \
98
+ '.goals = [.goals[] | if .id == $id then
99
+ (if $status != "" then .status = $status else . end) |
100
+ (if $metric != "" then .metric = $metric else . end) |
101
+ (.updated_at = (now|todate))
102
+ else . end]' \
103
+ "$goalsFile" > "$tmp" && mv "$tmp" "$goalsFile"
104
+ ```
105
+
106
+ ### link
107
+
108
+ Link a task id to a goal (append to goal's tasks array):
109
+
110
+ ```bash
111
+ tmp="${goalsFile}.tmp"
112
+ jq --arg id "$goal_id" --arg task "$task_id" \
113
+ '.goals = [.goals[] | if .id == $id then .tasks += [$task] else . end]' \
114
+ "$goalsFile" > "$tmp" && mv "$tmp" "$goalsFile"
115
+ ```
116
+
117
+ ### close
118
+
119
+ Mark goal as achieved and timestamp:
120
+
121
+ ```bash
122
+ tmp="${goalsFile}.tmp"
123
+ jq --arg id "$goal_id" \
124
+ '.goals = [.goals[] | if .id == $id then .status = "achieved" | .achieved_at = (now|todate) else . end]' \
125
+ "$goalsFile" > "$tmp" && mv "$tmp" "$goalsFile"
126
+ ```
127
+
128
+ Emit `org:goal:achieved` event.
129
+
130
+ ---
131
+
132
+ ## Step 3 — Return Output
133
+
134
+ ```yaml
135
+ domain: ops
136
+ status: complete
137
+ action: <action>
138
+ org: <org_name>
139
+ goal_id: <goal_id if applicable>
140
+ goals_file: .monomind/orgs/<org_name>-goals.json
141
+ ```
142
+
143
+ Suggest next: "Link tasks to this goal with /mastermind:tasks link or /mastermind:goals link --goal-id <id> --task-id <card_id>"
144
+
145
+ ---
146
+
147
+ ## Step 4 — Brain Write (standalone only)
148
+
149
+ If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.
@@ -0,0 +1,164 @@
1
+ ---
2
+ name: mastermind-heartbeat
3
+ description: Mastermind heartbeat — trigger a manual heartbeat for a specific agent in a running org. The agent wakes, checks its task queue, executes pending work, and reports back.
4
+ type: domain-skill
5
+ default_mode: auto
6
+ ---
7
+
8
+ # Mastermind Heartbeat
9
+
10
+ This skill is invoked by `mastermind:heartbeat` or directly via `/mastermind:heartbeat`.
11
+
12
+ ---
13
+
14
+ ## Inputs
15
+
16
+ - `brain_context`: BRAIN CONTEXT block
17
+ - `org_name`: org the agent belongs to
18
+ - `agent_id`: role id of the agent to wake (e.g. `content-writer`)
19
+ - `context`: optional additional context/instructions to pass to the agent during this heartbeat
20
+ - `source`: timer | on_demand | assignment | automation (default: on_demand)
21
+ - `timeout_min`: minutes to wait for completion (default: 10)
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
+ stateFile=".monomind/orgs/${org_name}-state.json"
37
+
38
+ [ ! -f "$orgFile" ] && { echo "ERROR: Org '${org_name}' not found. Run /mastermind:createorg first."; exit 1; }
39
+
40
+ board_id=$(jq -r '.board_id // empty' "$orgFile")
41
+ todo_col=$(jq -r '.todo_col_id // empty' "$orgFile")
42
+ doing_col=$(jq -r '.doing_col_id // empty' "$orgFile")
43
+ done_col=$(jq -r '.done_col_id // empty' "$orgFile")
44
+ memNs="org:${org_name}"
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Step 2 — Validate Agent
50
+
51
+ ```bash
52
+ agentConfig=$(jq --arg id "$agent_id" '.roles[] | select(.id == $id)' "$orgFile")
53
+ [ -z "$agentConfig" ] && { echo "ERROR: Agent '$agent_id' not found in org '$org_name'."; exit 1; }
54
+
55
+ agentTitle=$(echo "$agentConfig" | jq -r '.title')
56
+ agentType=$(echo "$agentConfig" | jq -r '.agent_type')
57
+ agentResp=$(echo "$agentConfig" | jq -r '.responsibilities | join("; ")')
58
+ reportsTo=$(echo "$agentConfig" | jq -r '.reports_to // "none"')
59
+ ```
60
+
61
+ ---
62
+
63
+ ## Step 3 — Update State and Emit heartbeat:start
64
+
65
+ ```bash
66
+ [ ! -f "$stateFile" ] && echo '{"agents":{}}' > "$stateFile"
67
+ tmp="${stateFile}.tmp"
68
+ jq --arg id "$agent_id" --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg source "${source:-on_demand}" \
69
+ '.agents[$id].last_heartbeat = $ts | .agents[$id].status = "running" | .agents[$id].heartbeat_source = $source' \
70
+ "$stateFile" > "$tmp" && mv "$tmp" "$stateFile"
71
+
72
+ REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
73
+ CTRL_URL=$(jq -r '.url // "http://localhost:4242"' "$REPO_ROOT/.monomind/control.json" 2>/dev/null || echo "http://localhost:4242")
74
+ curl -s -X POST "${CTRL_URL}/api/mastermind/event" \
75
+ -H "Content-Type: application/json" \
76
+ -d "$(jq -cn \
77
+ --arg org "$org_name" \
78
+ --arg role "$agent_id" \
79
+ --arg title "$agentTitle" \
80
+ --arg source "${source:-on_demand}" \
81
+ '{type:"org:heartbeat:start",org:$org,role:$role,title:$title,source:$source,ts:(now*1000|floor)}')" || true
82
+ ```
83
+
84
+ ---
85
+
86
+ ## Step 4 — Spawn Agent for One Heartbeat Cycle
87
+
88
+ ```javascript
89
+ Task({
90
+ subagent_type: agentType,
91
+ description: `Heartbeat for ${agentTitle} in org "${org_name}"`,
92
+ run_in_background: false,
93
+ prompt: `You are ${agentTitle} in the autonomous organization "${org_name}".
94
+
95
+ This is a HEARTBEAT CYCLE — a single work session triggered ${source || "on_demand"}.
96
+
97
+ YOUR ROLE: ${agentTitle}
98
+ YOUR RESPONSIBILITIES: ${agentResp}
99
+ REPORTS TO: ${reportsTo}
100
+ MEMORY NAMESPACE: ${memNs}
101
+
102
+ ${context ? `CONTEXT / INSTRUCTIONS FOR THIS HEARTBEAT:\n${context}\n\n` : ""}
103
+
104
+ TASK BOARD:
105
+ - board_id: ${board_id}
106
+ - Todo column: ${todo_col}
107
+ - Doing column: ${doing_col}
108
+ - Done column: ${done_col}
109
+
110
+ HEARTBEAT PROCEDURE:
111
+ 1. Check your task queue — unclaimed cards with "role:${agent_id}" label in Todo:
112
+ monotask card list ${board_id} --col ${todo_col} --json | jq '[.[] | select((.labels // []) | index("role:${agent_id}")) | select((.labels // []) | index("claimed") | not)]'
113
+
114
+ 2. For each unclaimed task:
115
+ a. Move to Doing: monotask card move ${board_id} $CARD_ID ${doing_col}
116
+ b. Add "claimed" label: monotask card label add ${board_id} $CARD_ID "claimed"
117
+ c. Execute the work described in the task title
118
+ d. Store output: npx monomind@latest memory store --key "${memNs}:output:${agent_id}:$CARD_ID" --namespace "${memNs}" --value "<your output>"
119
+ e. Move to Done: monotask card move ${board_id} $CARD_ID ${done_col}
120
+
121
+ 3. If no tasks, check memory for any pending instructions:
122
+ npx monomind@latest memory search --query "instruction ${agent_id}" --namespace "${memNs}"
123
+
124
+ 4. Report completion — emit heartbeat:complete event:
125
+ CTRL_URL=$(jq -r '.url // "http://localhost:4242"' "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.monomind/control.json" 2>/dev/null || echo "http://localhost:4242")
126
+ curl -s -X POST "${CTRL_URL}/api/mastermind/event" -H "Content-Type: application/json" \
127
+ -d "$(jq -cn --arg org "${org_name}" --arg role "${agent_id}" --arg title "${agentTitle}" \
128
+ '{type:"org:heartbeat:complete",org:$org,role:$role,title:$title,ts:(now*1000|floor)}')" || true
129
+
130
+ Complete your tasks then exit. This is a single heartbeat cycle, not a persistent loop.`
131
+ })
132
+ ```
133
+
134
+ ---
135
+
136
+ ## Step 5 — Update State After Completion
137
+
138
+ ```bash
139
+ tmp="${stateFile}.tmp"
140
+ jq --arg id "$agent_id" --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
141
+ '.agents[$id].status = "idle" | .agents[$id].last_heartbeat_complete = $ts' \
142
+ "$stateFile" > "$tmp" && mv "$tmp" "$stateFile"
143
+ ```
144
+
145
+ ---
146
+
147
+ ## Step 6 — Return Output
148
+
149
+ ```yaml
150
+ domain: ops
151
+ status: complete
152
+ org: <org_name>
153
+ agent_id: <agent_id>
154
+ agent_title: <agentTitle>
155
+ heartbeat_source: <source>
156
+ ```
157
+
158
+ Print: "Heartbeat complete for <agentTitle>. Check outputs with: npx monomind@latest memory search --namespace org:<org_name>"
159
+
160
+ ---
161
+
162
+ ## Step 7 — Brain Write (standalone only)
163
+
164
+ If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.