@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.
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 +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,136 @@
1
+ ---
2
+ name: mastermind-plan-to-tasks
3
+ description: Mastermind plan-to-tasks — converts a written plan (prose, outline, or structured doc) into assigned org issues with correct specialties, dependency wiring, and parallelization. Mirrors Paperclip's plan-to-tasks skill. Use when breaking down a project plan into executable issue trees.
4
+ type: domain-skill
5
+ default_mode: confirm
6
+ ---
7
+
8
+ # Mastermind Plan to Tasks
9
+
10
+ This skill is invoked by `mastermind:plan-to-tasks` or directly via `/mastermind:plan-to-tasks`.
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 create issues in (required)
18
+ - `plan`: the plan text (required — paste inline or pipe in)
19
+ - `project_id`: assign all issues to this project (optional)
20
+ - `workspace_id`: assign all issues to this workspace (optional)
21
+ - `dry_run`: true | false (default: false — if true, print plan without creating issues)
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 — Validate Inputs
33
+
34
+ ```bash
35
+ [ -z "$org_name" ] && { echo "ERROR: --org required."; exit 1; }
36
+ [ -z "$plan" ] && { echo "ERROR: --plan required (the plan text to decompose)."; exit 1; }
37
+
38
+ orgFile=".monomind/orgs/${org_name}.json"
39
+ [ ! -f "$orgFile" ] && { echo "ERROR: Org '${org_name}' not found."; exit 1; }
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Step 2 — Load Agents for Specialty Matching
45
+
46
+ ```bash
47
+ echo "PLAN-TO-TASKS — $org_name"
48
+ echo "────────────────────────────────────────────────────────"
49
+ echo ""
50
+ echo "AGENTS IN ORG:"
51
+ jq -r '.roles[] | " \(.id) \(.title // "-") [\(.adapter.type // "?")]"' "$orgFile"
52
+ echo ""
53
+ ```
54
+
55
+ ---
56
+
57
+ ## Step 3 — Decompose Plan into Issues
58
+
59
+ Read the plan carefully and apply these rules:
60
+
61
+ **Planning principles (from Paperclip plan-to-tasks):**
62
+
63
+ 1. **Plan deeply.** Capture real detail: goals, constraints, unknowns, success criteria, risks. A shallow plan becomes rework.
64
+ 2. **Know your team.** Read the org's agents and their specialties (titles, roles, adapters) before assigning anything.
65
+ 3. **Assign for specialty.** Hand each piece of work to the most relevant agent. If no agent fits, flag the gap.
66
+ 4. **Take responsibility.** When you (the AI) are best-suited for a piece, assign it to yourself instead of delegating.
67
+ 5. **Use the dependency tree.** Express every concrete deliverable as an issue. Wire real blockers via `blockedByIssueIds`. When done, dependents auto-wake.
68
+ 6. **Order, then parallelize.** Sequence by real dependencies. Independent branches start in parallel.
69
+ 7. **Enough is enough.** Plans unblock execution. Don't re-plan already clear work.
70
+
71
+ **Decomposition output:**
72
+
73
+ For each issue extracted from the plan, produce:
74
+ ```
75
+ ISSUE: <title>
76
+ assignee: <agent-id or UNASSIGNED>
77
+ priority: low | medium | high | urgent
78
+ blockedBy: <issue-title> (or none)
79
+ description: <1-2 sentence summary of the deliverable>
80
+ ```
81
+
82
+ **Quality checklist before creating:**
83
+ - [ ] Enough detail that assignees can act without re-asking
84
+ - [ ] Every concrete deliverable is an issue
85
+ - [ ] Each issue has a deliberate, specialty-matched assignee
86
+ - [ ] Each issue's real blockers are declared
87
+ - [ ] Independent branches can start in parallel
88
+ - [ ] Gaps (missing skills, decisions, external inputs) are surfaced, not hidden
89
+
90
+ ---
91
+
92
+ ## Step 4 — Create Issues (unless dry_run=true)
93
+
94
+ ```bash
95
+ issuesFile=".monomind/orgs/${org_name}-issues.json"
96
+ [ ! -f "$issuesFile" ] && echo '{"issues":[]}' > "$issuesFile"
97
+
98
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
99
+
100
+ # Issues are created from the decomposition above
101
+ # Each issue gets:
102
+ # id: issue-<timestamp>-<N>
103
+ # title, description, priority, status: open
104
+ # assigneeId (from matched agent)
105
+ # projectId, workspaceId (if provided)
106
+ # blockedByIssueIds (resolved after all issues are created)
107
+ # createdAt, updatedAt
108
+
109
+ echo ""
110
+ if [ "${dry_run:-false}" = "true" ]; then
111
+ echo "DRY RUN — no issues were created."
112
+ echo "Remove --dry-run to create these issues."
113
+ else
114
+ echo "CREATED ISSUES:"
115
+ # (issue creation happens inline above as each issue is decomposed)
116
+ fi
117
+ ```
118
+
119
+ ---
120
+
121
+ ## Step 5 — Return Output
122
+
123
+ ```yaml
124
+ domain: ops
125
+ status: complete
126
+ action: plan-to-tasks
127
+ org_name: <org_name>
128
+ issues_created: <N>
129
+ dry_run: <true|false>
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Step 6 — Brain Write (standalone only)
135
+
136
+ If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.
@@ -0,0 +1,241 @@
1
+ ---
2
+ name: mastermind-plugin-manager
3
+ description: Mastermind plugin-manager — install plugins from npm, uninstall with two-step confirmation, enable/disable installed plugins. Extends mastermind:plugins (listing) and mastermind:plugin-settings (per-plugin config) with the install/uninstall lifecycle. Mirrors PluginManager.tsx.
4
+ type: domain-skill
5
+ default_mode: confirm
6
+ ---
7
+
8
+ # Mastermind Plugin Manager
9
+
10
+ This skill is invoked by `mastermind:plugin-manager` or directly via `/mastermind:plugin-manager`.
11
+
12
+ ---
13
+
14
+ ## Inputs
15
+
16
+ - `brain_context`: BRAIN CONTEXT block (injected by command, or loaded below if standalone)
17
+ - `action`: list | install | uninstall | enable | disable | check-updates
18
+ - `package_name`: npm package name to install (for install; e.g. `@monomind/plugin-github`)
19
+ - `plugin_id`: plugin id slug (required for uninstall/enable/disable)
20
+ - `confirm`: yes (required second step for uninstall — prevents accidental removal)
21
+ - `caller`: command | master
22
+
23
+ ---
24
+
25
+ ## Plugin Record Schema
26
+
27
+ ```json
28
+ {
29
+ "id": "plugin-slug",
30
+ "packageName": "@monomind/plugin-name",
31
+ "status": "installed",
32
+ "version": "1.2.0",
33
+ "category": "monitoring",
34
+ "description": "One-line plugin description",
35
+ "installedAt": "2026-01-01T00:00:00Z",
36
+ "config": {},
37
+ "grants": [],
38
+ "health": {"status": "ok", "lastCheck": null}
39
+ }
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Step 0 — Brain Load (standalone only)
45
+
46
+ If `caller` is not "command", load brain context following _protocol.md Brain Load Procedure with namespace: `ops`.
47
+
48
+ ---
49
+
50
+ ## Step 1 — Load Plugin Registry
51
+
52
+ ```bash
53
+ registryFile=".monomind/plugins/registry.json"
54
+ mkdir -p ".monomind/plugins"
55
+ [ ! -f "$registryFile" ] && echo '{"plugins":[]}' > "$registryFile"
56
+ ```
57
+
58
+ ---
59
+
60
+ ## Step 2 — Execute Action
61
+
62
+ ### list (default)
63
+
64
+ ```bash
65
+ echo "INSTALLED PLUGINS"
66
+ echo "────────────────────────────────────────────────────────"
67
+ printf "%-24s %-10s %-10s %-14s %s\n" "ID" "STATUS" "VERSION" "CATEGORY" "PACKAGE"
68
+ echo "────────────────────────────────────────────────────────"
69
+
70
+ count=$(jq '.plugins | length' "$registryFile")
71
+ if [ "$count" -eq 0 ]; then
72
+ echo " No plugins installed."
73
+ echo " Install one: --action install --package-name @monomind/plugin-github"
74
+ else
75
+ jq -r '.plugins[] |
76
+ [.id, (.status // "installed"), (.version // "-"), (.category // "general"),
77
+ (.packageName // "-")] | @tsv' \
78
+ "$registryFile" | while IFS=$'\t' read -r id st ver cat pkg; do
79
+ printf "%-24s %-10s %-10s %-14s %s\n" "$id" "$st" "$ver" "$cat" "$pkg"
80
+ done
81
+
82
+ errCount=$(jq '[.plugins[] | select(.status == "error")] | length' "$registryFile")
83
+ [ "$errCount" -gt 0 ] && echo "" && echo " WARNING: $errCount plugin(s) in error state. Run: --action list to inspect."
84
+ fi
85
+
86
+ echo ""
87
+ echo " Install: --action install --package-name <npm-package>"
88
+ echo " Uninstall: --action uninstall --plugin-id <id>"
89
+ echo " Settings: /mastermind:plugin-settings --plugin-id <id>"
90
+ ```
91
+
92
+ ### install
93
+
94
+ ```bash
95
+ [ -z "$package_name" ] && { echo "ERROR: --package-name required (e.g. @monomind/plugin-github)."; exit 1; }
96
+
97
+ echo "INSTALLING PLUGIN — $package_name"
98
+ echo "────────────────────────────────────────────────────────"
99
+ echo " Running: npm install $package_name"
100
+
101
+ # Check if already installed
102
+ alreadyId=$(jq -r --arg pkg "$package_name" '.plugins[] | select(.packageName == $pkg) | .id' "$registryFile" | head -1)
103
+ [ -n "$alreadyId" ] && {
104
+ echo " Plugin already installed as '$alreadyId'. Use --action enable/disable or reinstall via npm."
105
+ exit 0
106
+ }
107
+
108
+ if npm install "$package_name" 2>&1 | tail -5; then
109
+ # Derive plugin metadata from npm package
110
+ pkgVer=$(node -e "try{console.log(require('${package_name}/package.json').version)}catch(e){console.log('0.0.0')}" 2>/dev/null || echo "0.0.0")
111
+ pkgDesc=$(node -e "try{console.log(require('${package_name}/package.json').description||'')}catch(e){console.log('')}" 2>/dev/null || echo "")
112
+ pluginId=$(echo "$package_name" | sed 's|@[^/]*/||' | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-' | sed 's/^-//;s/-$//')
113
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
114
+
115
+ tmp="${registryFile}.tmp"
116
+ jq --arg id "$pluginId" \
117
+ --arg pkg "$package_name" \
118
+ --arg ver "$pkgVer" \
119
+ --arg desc "$pkgDesc" \
120
+ --arg ts "$ts" \
121
+ '.plugins += [{"id":$id,"packageName":$pkg,"status":"installed","version":$ver,
122
+ "description":$desc,"category":"general","config":{},"grants":[],
123
+ "health":{"status":"ok","lastCheck":null},"installedAt":$ts}]' \
124
+ "$registryFile" > "$tmp" && mv "$tmp" "$registryFile"
125
+
126
+ echo ""
127
+ echo "Plugin installed: $pluginId @ $pkgVer"
128
+ echo " Configure: /mastermind:plugin-settings --plugin-id $pluginId"
129
+ else
130
+ echo " ERROR: npm install failed. Check the package name and network connectivity."
131
+ exit 1
132
+ fi
133
+ ```
134
+
135
+ ### uninstall
136
+
137
+ ```bash
138
+ [ -z "$plugin_id" ] && { echo "ERROR: --plugin-id required."; exit 1; }
139
+
140
+ exists=$(jq -r --arg id "$plugin_id" '[.plugins[] | select(.id == $id)] | length' "$registryFile")
141
+ [ "$exists" -eq 0 ] && { echo "ERROR: Plugin '$plugin_id' not found."; exit 1; }
142
+
143
+ # Two-step confirmation
144
+ if [ "${confirm:-}" != "yes" ]; then
145
+ pkg=$(jq -r --arg id "$plugin_id" '.plugins[] | select(.id == $id) | .packageName // $id' "$registryFile")
146
+ echo "UNINSTALL CONFIRMATION REQUIRED"
147
+ echo "────────────────────────────────────────────────────────"
148
+ echo " Plugin: $plugin_id ($pkg)"
149
+ echo " This will remove the plugin and all its configuration."
150
+ echo ""
151
+ echo " To confirm: --action uninstall --plugin-id $plugin_id --confirm yes"
152
+ exit 0
153
+ fi
154
+
155
+ pkg=$(jq -r --arg id "$plugin_id" '.plugins[] | select(.id == $id) | .packageName // ""' "$registryFile")
156
+
157
+ # Remove from registry
158
+ tmp="${registryFile}.tmp"
159
+ jq --arg id "$plugin_id" \
160
+ '.plugins = [.plugins[] | select(.id != $id)]' \
161
+ "$registryFile" > "$tmp" && mv "$tmp" "$registryFile"
162
+
163
+ echo "Plugin '$plugin_id' removed from registry."
164
+
165
+ # Attempt npm uninstall if packageName known
166
+ if [ -n "$pkg" ]; then
167
+ echo " Running: npm uninstall $pkg"
168
+ npm uninstall "$pkg" 2>&1 | tail -3 || echo " WARNING: npm uninstall had errors — registry entry removed anyway."
169
+ fi
170
+ ```
171
+
172
+ ### enable
173
+
174
+ ```bash
175
+ [ -z "$plugin_id" ] && { echo "ERROR: --plugin-id required."; exit 1; }
176
+
177
+ exists=$(jq -r --arg id "$plugin_id" '[.plugins[] | select(.id == $id)] | length' "$registryFile")
178
+ [ "$exists" -eq 0 ] && { echo "ERROR: Plugin '$plugin_id' not found."; exit 1; }
179
+
180
+ tmp="${registryFile}.tmp"
181
+ jq --arg id "$plugin_id" \
182
+ '.plugins = [.plugins[] | if .id == $id then .status = "installed" | .disabledAt = null else . end]' \
183
+ "$registryFile" > "$tmp" && mv "$tmp" "$registryFile"
184
+
185
+ echo "Plugin '$plugin_id' ENABLED."
186
+ ```
187
+
188
+ ### disable
189
+
190
+ ```bash
191
+ [ -z "$plugin_id" ] && { echo "ERROR: --plugin-id required."; exit 1; }
192
+
193
+ exists=$(jq -r --arg id "$plugin_id" '[.plugins[] | select(.id == $id)] | length' "$registryFile")
194
+ [ "$exists" -eq 0 ] && { echo "ERROR: Plugin '$plugin_id' not found."; exit 1; }
195
+
196
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
197
+ tmp="${registryFile}.tmp"
198
+ jq --arg id "$plugin_id" --arg ts "$ts" \
199
+ '.plugins = [.plugins[] | if .id == $id then .status = "disabled" | .disabledAt = $ts else . end]' \
200
+ "$registryFile" > "$tmp" && mv "$tmp" "$registryFile"
201
+
202
+ echo "Plugin '$plugin_id' DISABLED — will not load on next startup."
203
+ ```
204
+
205
+ ### check-updates
206
+
207
+ ```bash
208
+ echo "CHECKING PLUGIN UPDATES"
209
+ echo "────────────────────────────────────────────────────────"
210
+
211
+ count=$(jq '.plugins | length' "$registryFile")
212
+ [ "$count" -eq 0 ] && { echo " No plugins installed."; exit 0; }
213
+
214
+ jq -r '.plugins[] | select(.packageName != null) |
215
+ [.id, .packageName, (.version // "unknown")] | @tsv' \
216
+ "$registryFile" | while IFS=$'\t' read -r id pkg ver; do
217
+ latest=$(curl -sf "https://registry.npmjs.org/${pkg}/latest" 2>/dev/null | jq -r '.version // "?"' 2>/dev/null || echo "?")
218
+ if [ "$latest" != "?" ] && [ "$latest" != "$ver" ]; then
219
+ echo " [$id] $ver → $latest — run: npm install $pkg"
220
+ else
221
+ echo " [$id] $ver (up to date)"
222
+ fi
223
+ done
224
+ ```
225
+
226
+ ---
227
+
228
+ ## Step 3 — Return Output
229
+
230
+ ```yaml
231
+ domain: ops
232
+ status: complete
233
+ action: <action>
234
+ plugin_id: <plugin_id>
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,273 @@
1
+ ---
2
+ name: mastermind-plugin-settings
3
+ description: Mastermind plugin-settings — inspect and configure a single installed plugin. View configuration fields, manage file system access grants (read/write paths), check runtime health/status, and update plugin settings. Mirrors Paperclip's PluginSettings page with configuration and status tabs.
4
+ type: domain-skill
5
+ default_mode: confirm
6
+ ---
7
+
8
+ # Mastermind Plugin Settings
9
+
10
+ This skill is invoked by `mastermind:plugin-settings` or directly via `/mastermind:plugin-settings`.
11
+
12
+ ---
13
+
14
+ ## Inputs
15
+
16
+ - `brain_context`: BRAIN CONTEXT block (injected by command, or loaded below if standalone)
17
+ - `plugin_id`: plugin id to manage (required)
18
+ - `org_name`: org scope (optional — uses global registry if omitted)
19
+ - `action`: show | config | status | grants | set-config | add-grant | remove-grant
20
+ - `config_key`: config key to set (for set-config)
21
+ - `config_value`: config value (for set-config)
22
+ - `grant_path`: filesystem path to grant access to (for add-grant/remove-grant)
23
+ - `grant_access`: read | write | readwrite (for add-grant, default: read)
24
+ - `caller`: command | master
25
+
26
+ ---
27
+
28
+ ## Plugin Configuration Model
29
+
30
+ ```json
31
+ {
32
+ "id": "plugin-slug",
33
+ "packageName": "@monomind/plugin-name",
34
+ "status": "installed",
35
+ "version": "1.2.0",
36
+ "category": "monitoring",
37
+ "config": {
38
+ "apiKey": "***",
39
+ "webhookUrl": "https://...",
40
+ "customField": "value"
41
+ },
42
+ "grants": [
43
+ { "path": "/tmp/plugin-data", "access": "readwrite" },
44
+ { "path": "/project/logs", "access": "read" }
45
+ ],
46
+ "health": {
47
+ "status": "ok",
48
+ "lastCheck": "2026-01-01T00:00:00Z",
49
+ "message": null
50
+ }
51
+ }
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Step 0 — Brain Load (standalone only)
57
+
58
+ If `caller` is not "command", load brain context following _protocol.md Brain Load Procedure with namespace: `ops`.
59
+
60
+ ---
61
+
62
+ ## Step 1 — Load Plugin Registry
63
+
64
+ ```bash
65
+ registryFile=".monomind/plugins/registry.json"
66
+ [ ! -f "$registryFile" ] && { echo "ERROR: No plugin registry found. Install plugins via /mastermind:plugins."; exit 1; }
67
+
68
+ pluginDef=$(jq -r --arg id "$plugin_id" '.plugins[] | select(.id == $id)' "$registryFile")
69
+ [ -z "$pluginDef" ] && { echo "ERROR: Plugin '$plugin_id' not found. List plugins via /mastermind:plugins --action list."; exit 1; }
70
+
71
+ # Load org-level overrides if org_name specified
72
+ orgPluginsFile=""
73
+ if [ -n "$org_name" ]; then
74
+ orgPluginsFile=".monomind/orgs/${org_name}-plugins.json"
75
+ orgOverride=$([ -f "$orgPluginsFile" ] && jq -r --arg id "$plugin_id" '.plugins[] | select(.id == $id)' "$orgPluginsFile" || echo "")
76
+ fi
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Step 2 — Execute Action
82
+
83
+ ### show (default)
84
+
85
+ ```bash
86
+ echo "PLUGIN — $plugin_id"
87
+ echo "────────────────────────────────────────────────────────"
88
+
89
+ echo "$pluginDef" | jq -r '
90
+ " ID: \(.id)",
91
+ " Package: \(.packageName // "-")",
92
+ " Version: \(.version // "-")",
93
+ " Status: \(.status // "unknown")",
94
+ " Category: \(.category // "general")",
95
+ " Local path: \(if .isLocalPath then "yes" else "no" end)",
96
+ " Installed: \(.installedAt // "-")"
97
+ '
98
+
99
+ if [ -n "$orgOverride" ] && [ "$orgOverride" != "null" ]; then
100
+ echo ""
101
+ echo " ORG OVERRIDE ($org_name):"
102
+ echo "$orgOverride" | jq -r '" Status: \(.status // "inherited")"'
103
+ fi
104
+
105
+ # Config summary
106
+ configCount=$(echo "$pluginDef" | jq -r '(.config // {}) | length')
107
+ echo ""
108
+ echo " Config fields: $configCount"
109
+ echo " Grants: $(echo "$pluginDef" | jq -r '(.grants // []) | length')"
110
+
111
+ # Health
112
+ healthStatus=$(echo "$pluginDef" | jq -r '.health.status // "unknown"')
113
+ healthMsg=$(echo "$pluginDef" | jq -r '.health.message // ""')
114
+ echo " Health: $healthStatus${healthMsg:+ — $healthMsg}"
115
+
116
+ # Last error
117
+ lastErr=$(echo "$pluginDef" | jq -r '.lastError // ""')
118
+ [ -n "$lastErr" ] && echo "" && echo " LAST ERROR: $lastErr"
119
+ ```
120
+
121
+ ### config
122
+
123
+ ```bash
124
+ echo "CONFIG — $plugin_id"
125
+ echo "────────────────────────────────────────────────────────"
126
+
127
+ config=$(echo "$pluginDef" | jq -r '.config // {}')
128
+ count=$(echo "$config" | jq 'length')
129
+
130
+ if [ "$count" -eq 0 ]; then
131
+ echo " No configuration fields."
132
+ echo " Set a field: --action set-config --config-key <key> --config-value <value>"
133
+ else
134
+ echo "$config" | jq -r 'to_entries[] |
135
+ if (.value | type) == "string" and (.key | test("key|token|secret|password|api"; "i")) then
136
+ " \(.key) = ***"
137
+ else
138
+ " \(.key) = \(.value)"
139
+ end'
140
+ fi
141
+ ```
142
+
143
+ ### status
144
+
145
+ ```bash
146
+ echo "PLUGIN STATUS — $plugin_id"
147
+ echo "────────────────────────────────────────────────────────"
148
+
149
+ echo "$pluginDef" | jq -r '
150
+ " Status: \(.status // "unknown")",
151
+ " Version: \(.version // "-")",
152
+ " Installed: \(.installedAt // "-")"
153
+ '
154
+
155
+ health=$(echo "$pluginDef" | jq -r '.health // {}')
156
+ healthStatus=$(echo "$health" | jq -r '.status // "unknown"')
157
+ lastCheck=$(echo "$health" | jq -r '.lastCheck // "-"')
158
+ healthMsg=$(echo "$health" | jq -r '.message // ""')
159
+
160
+ echo ""
161
+ echo "HEALTH CHECK"
162
+ echo " Status: $healthStatus"
163
+ echo " Last: $lastCheck"
164
+ [ -n "$healthMsg" ] && echo " Message: $healthMsg"
165
+
166
+ # Error
167
+ lastErr=$(echo "$pluginDef" | jq -r '.lastError // ""')
168
+ if [ -n "$lastErr" ]; then
169
+ echo ""
170
+ echo "LAST ERROR"
171
+ echo " $lastErr"
172
+ fi
173
+
174
+ # Suggest reload
175
+ [ "$healthStatus" = "error" ] && echo "" && echo " Run: /mastermind:plugins --action reload --plugin-id $plugin_id"
176
+ ```
177
+
178
+ ### grants
179
+
180
+ ```bash
181
+ echo "FILE SYSTEM GRANTS — $plugin_id"
182
+ echo "────────────────────────────────────────────────────────"
183
+ printf "%-6s %s\n" "ACCESS" "PATH"
184
+ echo "────────────────────────────────────────────────────────"
185
+
186
+ grants=$(echo "$pluginDef" | jq -r '(.grants // [])[]' 2>/dev/null)
187
+ if [ -z "$grants" ]; then
188
+ echo " No file system grants."
189
+ echo " Add a grant: --action add-grant --grant-path /path/to/dir --grant-access read"
190
+ else
191
+ echo "$pluginDef" | jq -r '(.grants // [])[] |
192
+ " \(.access // "read")\t\(.path)"' | while IFS=$'\t' read -r acc path; do
193
+ printf " %-10s %s\n" "$acc" "$path"
194
+ done
195
+ fi
196
+ ```
197
+
198
+ ### set-config
199
+
200
+ ```bash
201
+ [ -z "$config_key" ] && { echo "ERROR: --config-key required."; exit 1; }
202
+ [ -z "$config_value" ] && { echo "ERROR: --config-value required."; exit 1; }
203
+
204
+ tmp="${registryFile}.tmp"
205
+ jq --arg id "$plugin_id" --arg k "$config_key" --arg v "$config_value" \
206
+ '.plugins = [.plugins[] | if .id == $id then
207
+ if .config == null then .config = {} else . end |
208
+ .config[$k] = $v
209
+ else . end]' \
210
+ "$registryFile" > "$tmp" && mv "$tmp" "$registryFile"
211
+
212
+ # Mask value in output if sensitive key
213
+ if echo "$config_key" | grep -qiE "key|token|secret|password|api"; then
214
+ echo "Config set: $config_key = ***"
215
+ else
216
+ echo "Config set: $config_key = $config_value"
217
+ fi
218
+ echo "NOTE: Restart agents or reload the plugin for changes to take effect."
219
+ ```
220
+
221
+ ### add-grant
222
+
223
+ ```bash
224
+ [ -z "$grant_path" ] && { echo "ERROR: --grant-path required."; exit 1; }
225
+ access="${grant_access:-read}"
226
+ case "$access" in read|write|readwrite) : ;; *)
227
+ echo "ERROR: --grant-access must be read, write, or readwrite"; exit 1 ;;
228
+ esac
229
+
230
+ tmp="${registryFile}.tmp"
231
+ jq --arg id "$plugin_id" --arg path "$grant_path" --arg access "$access" \
232
+ '.plugins = [.plugins[] | if .id == $id then
233
+ .grants = ((.grants // []) | map(select(.path != $path))) +
234
+ [{"path":$path,"access":$access}]
235
+ else . end]' \
236
+ "$registryFile" > "$tmp" && mv "$tmp" "$registryFile"
237
+
238
+ echo "Grant added: $access → $grant_path"
239
+ ```
240
+
241
+ ### remove-grant
242
+
243
+ ```bash
244
+ [ -z "$grant_path" ] && { echo "ERROR: --grant-path required."; exit 1; }
245
+
246
+ tmp="${registryFile}.tmp"
247
+ jq --arg id "$plugin_id" --arg path "$grant_path" \
248
+ '.plugins = [.plugins[] | if .id == $id then
249
+ .grants = [(.grants // [])[] | select(.path != $path)]
250
+ else . end]' \
251
+ "$registryFile" > "$tmp" && mv "$tmp" "$registryFile"
252
+
253
+ echo "Grant removed: $grant_path"
254
+ ```
255
+
256
+ ---
257
+
258
+ ## Step 3 — Return Output
259
+
260
+ ```yaml
261
+ domain: ops
262
+ status: complete
263
+ action: <action>
264
+ plugin_id: <plugin_id>
265
+ plugin_status: <status>
266
+ health_status: <health>
267
+ ```
268
+
269
+ ---
270
+
271
+ ## Step 4 — Brain Write (standalone only)
272
+
273
+ If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.