@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,244 @@
1
+ ---
2
+ name: mastermind-project-workspace
3
+ description: Mastermind project-workspace — configure a project-level workspace (not an execution workspace). Manages source type, visibility, repo URL/ref, branch, cwd, setup/cleanup commands, remote provider, remote workspace ref, runtime config JSON, and shared workspace key. Mirrors ProjectWorkspaceDetail.tsx.
4
+ type: domain-skill
5
+ default_mode: confirm
6
+ ---
7
+
8
+ # Mastermind Project Workspace
9
+
10
+ This skill is invoked by `mastermind:project-workspace` or directly via `/mastermind:project-workspace`.
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 project belongs to (required)
18
+ - `project_id`: project id (required)
19
+ - `workspace_id`: workspace id within the project (required)
20
+ - `action`: show | config | runtime | provision | teardown
21
+ - `name`: display name for workspace (for config)
22
+ - `source_type`: local_path | non_git_path | git_repo | remote_managed (for config)
23
+ - `visibility`: default | advanced (for config)
24
+ - `cwd`: absolute local path (for config; required if source_type is local_path/non_git_path)
25
+ - `repo_url`: remote repository URL (for config)
26
+ - `repo_ref`: git ref/commit (for config)
27
+ - `default_ref`: default branch name (for config)
28
+ - `setup_command`: command to run after workspace creation (for config)
29
+ - `cleanup_command`: command to run before workspace teardown (for config)
30
+ - `remote_provider`: remote provider identifier (for config; use with remote_managed)
31
+ - `remote_workspace_ref`: remote workspace reference ID (for config; use with remote_managed)
32
+ - `shared_workspace_key`: key to share this workspace across agents (for config)
33
+ - `runtime_config`: JSON string with workspaceRuntime config overrides (for runtime)
34
+ - `caller`: command | master
35
+
36
+ ---
37
+
38
+ ## Source Types
39
+
40
+ | Type | Label | Required fields |
41
+ |------|-------|----------------|
42
+ | `local_path` | Local git checkout | `cwd` (absolute path) |
43
+ | `non_git_path` | Local non-git path | `cwd` (absolute path) |
44
+ | `git_repo` | Remote git repo | `repo_url` |
45
+ | `remote_managed` | Remote-managed workspace | `remote_workspace_ref` or `repo_url` |
46
+
47
+ ## Visibility
48
+
49
+ | Value | Description |
50
+ |-------|-------------|
51
+ | `default` | Shown to all agents in the project |
52
+ | `advanced` | Hidden by default; shown only when explicitly selected |
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 Workspace
63
+
64
+ ```bash
65
+ orgFile=".monomind/orgs/${org_name}.json"
66
+ [ ! -f "$orgFile" ] && { echo "ERROR: Org '${org_name}' not found."; exit 1; }
67
+
68
+ projectsFile=".monomind/orgs/${org_name}-projects.json"
69
+ [ ! -f "$projectsFile" ] && { echo "ERROR: No projects file for org '${org_name}'."; exit 1; }
70
+
71
+ # Find project
72
+ projDef=$(jq -r --arg pid "$project_id" '.projects[] | select(.id == $pid or .name == $pid)' "$projectsFile")
73
+ [ -z "$projDef" ] && { echo "ERROR: Project '$project_id' not found."; exit 1; }
74
+
75
+ # Load project workspaces file
76
+ pwsFile=".monomind/orgs/${org_name}-project-workspaces.json"
77
+ [ ! -f "$pwsFile" ] && echo '{"workspaces":[]}' > "$pwsFile"
78
+
79
+ wsDef=$(jq -r --arg wid "$workspace_id" --arg pid "$project_id" \
80
+ '.workspaces[] | select(.id == $wid and (.project_id == $pid or .projectId == $pid))' \
81
+ "$pwsFile")
82
+ ```
83
+
84
+ ---
85
+
86
+ ## Step 2 — Execute Action
87
+
88
+ ### show (default)
89
+
90
+ ```bash
91
+ echo "PROJECT WORKSPACE — $workspace_id @ $project_id ($org_name)"
92
+ echo "────────────────────────────────────────────────────────"
93
+
94
+ if [ -z "$wsDef" ]; then
95
+ echo " Workspace '$workspace_id' not found in project '$project_id'."
96
+ echo " List workspaces: /mastermind:workspaces --org $org_name"
97
+ exit 0
98
+ fi
99
+
100
+ echo "$wsDef" | jq -r '
101
+ " ID: \(.id)",
102
+ " Name: \(.name // "(unnamed)")",
103
+ " Source type: \(.sourceType // .source_type // "local_path")",
104
+ " Visibility: \(.visibility // "default")",
105
+ " CWD: \(.cwd // "(none)")",
106
+ " Repo URL: \(.repoUrl // .repo_url // "(none)")",
107
+ " Repo ref: \(.repoRef // .repo_ref // "(default)")",
108
+ " Default ref: \(.defaultRef // .default_ref // "(default branch)")",
109
+ " Setup command: \(.setupCommand // .setup_command // "(none)")",
110
+ " Cleanup command: \(.cleanupCommand // .cleanup_command // "(none)")",
111
+ " Remote provider: \(.remoteProvider // .remote_provider // "(none)")",
112
+ " Remote ws ref: \(.remoteWorkspaceRef // .remote_workspace_ref // "(none)")",
113
+ " Shared key: \(.sharedWorkspaceKey // .shared_workspace_key // "(none)")"
114
+ '
115
+
116
+ rtConfig=$(echo "$wsDef" | jq -r '.runtimeConfig.workspaceRuntime // null')
117
+ echo ""
118
+ echo "RUNTIME CONFIG: $([ "$rtConfig" = "null" ] && echo '(none)' || echo "$rtConfig" | jq -c .)"
119
+ ```
120
+
121
+ ### config
122
+
123
+ ```bash
124
+ if [ -z "$wsDef" ]; then
125
+ echo "ERROR: Workspace '$workspace_id' not found."
126
+ exit 1
127
+ fi
128
+
129
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
130
+ tmp="${pwsFile}.tmp"
131
+ jq \
132
+ --arg wid "$workspace_id" \
133
+ --arg pid "$project_id" \
134
+ --arg name "${name:-}" \
135
+ --arg st "${source_type:-}" \
136
+ --arg vis "${visibility:-}" \
137
+ --arg cwd_ "${cwd:-}" \
138
+ --arg repoUrl "${repo_url:-}" \
139
+ --arg repoRef "${repo_ref:-}" \
140
+ --arg defaultRef "${default_ref:-}" \
141
+ --arg setupCmd "${setup_command:-}" \
142
+ --arg cleanupCmd "${cleanup_command:-}" \
143
+ --arg remoteProvider "${remote_provider:-}" \
144
+ --arg remoteRef "${remote_workspace_ref:-}" \
145
+ --arg sharedKey "${shared_workspace_key:-}" \
146
+ --arg ts "$ts" \
147
+ '.workspaces = [.workspaces[] | if (.id == $wid and (.project_id == $pid or .projectId == $pid)) then
148
+ (if $name != "" then .name = $name else . end) |
149
+ (if $st != "" then .sourceType = $st else . end) |
150
+ (if $vis != "" then .visibility = $vis else . end) |
151
+ (if $cwd_ != "" then .cwd = $cwd_ else . end) |
152
+ (if $repoUrl != "" then .repoUrl = $repoUrl else . end) |
153
+ (if $repoRef != "" then .repoRef = $repoRef else . end) |
154
+ (if $defaultRef != "" then .defaultRef = $defaultRef else . end) |
155
+ (if $setupCmd != "" then .setupCommand = $setupCmd else . end) |
156
+ (if $cleanupCmd != "" then .cleanupCommand = $cleanupCmd else . end) |
157
+ (if $remoteProvider != "" then .remoteProvider = $remoteProvider else . end) |
158
+ (if $remoteRef != "" then .remoteWorkspaceRef = $remoteRef else . end) |
159
+ (if $sharedKey != "" then .sharedWorkspaceKey = $sharedKey else . end) |
160
+ .updatedAt = $ts
161
+ else . end]' \
162
+ "$pwsFile" > "$tmp" && mv "$tmp" "$pwsFile"
163
+
164
+ echo "Project workspace '$workspace_id' config updated."
165
+ ```
166
+
167
+ ### runtime
168
+
169
+ ```bash
170
+ [ -z "$runtime_config" ] && { echo "ERROR: --runtime-config (JSON string) required."; exit 1; }
171
+
172
+ # Validate JSON
173
+ parsed=$(echo "$runtime_config" | python3 -c "import json,sys; d=json.load(sys.stdin); print(json.dumps(d))" 2>&1) || {
174
+ echo "ERROR: --runtime-config must be valid JSON: $parsed"
175
+ exit 1
176
+ }
177
+
178
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
179
+ tmp="${pwsFile}.tmp"
180
+ jq --arg wid "$workspace_id" --arg pid "$project_id" --argjson rt "$parsed" --arg ts "$ts" \
181
+ '.workspaces = [.workspaces[] | if (.id == $wid and (.project_id == $pid or .projectId == $pid)) then
182
+ .runtimeConfig = {"workspaceRuntime": $rt} | .updatedAt = $ts
183
+ else . end]' \
184
+ "$pwsFile" > "$tmp" && mv "$tmp" "$pwsFile"
185
+
186
+ echo "Runtime config updated for workspace '$workspace_id'."
187
+ echo " Keys: $(echo "$parsed" | python3 -c "import json,sys; d=json.load(sys.stdin); print(', '.join(d.keys()))")"
188
+ ```
189
+
190
+ ### provision
191
+
192
+ ```bash
193
+ setupCmd=$(echo "$wsDef" | jq -r '.setupCommand // .setup_command // ""')
194
+ wsPath=$(echo "$wsDef" | jq -r '.cwd // ""')
195
+
196
+ echo "PROVISION — $workspace_id"
197
+ echo "────────────────────────────────────────────────────────"
198
+ if [ -z "$setupCmd" ]; then
199
+ echo " No setup command configured."
200
+ echo " Set one: --action config --setup-command 'npm install'"
201
+ else
202
+ echo " Command: $setupCmd"
203
+ echo " CWD: ${wsPath:-(none)}"
204
+ if [ -d "$wsPath" ] && [ -n "$setupCmd" ]; then
205
+ echo " Executing…"
206
+ (cd "$wsPath" && eval "$setupCmd") && echo " Provision complete." || echo " Provision command exited with error."
207
+ fi
208
+ fi
209
+ ```
210
+
211
+ ### teardown
212
+
213
+ ```bash
214
+ cleanupCmd=$(echo "$wsDef" | jq -r '.cleanupCommand // .cleanup_command // ""')
215
+ wsPath=$(echo "$wsDef" | jq -r '.cwd // ""')
216
+
217
+ echo "TEARDOWN — $workspace_id"
218
+ echo "────────────────────────────────────────────────────────"
219
+ if [ -z "$cleanupCmd" ]; then
220
+ echo " No cleanup command configured."
221
+ else
222
+ echo " Command: $cleanupCmd"
223
+ [ -d "$wsPath" ] && (cd "$wsPath" && eval "$cleanupCmd") && echo " Teardown complete." || echo " No path or teardown error."
224
+ fi
225
+ ```
226
+
227
+ ---
228
+
229
+ ## Step 3 — Return Output
230
+
231
+ ```yaml
232
+ domain: ops
233
+ status: complete
234
+ action: <action>
235
+ org: <org_name>
236
+ project_id: <project_id>
237
+ workspace_id: <workspace_id>
238
+ ```
239
+
240
+ ---
241
+
242
+ ## Step 4 — Brain Write (standalone only)
243
+
244
+ If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.
@@ -0,0 +1,164 @@
1
+ ---
2
+ name: mastermind-projects
3
+ description: Mastermind projects — create and manage scoped project workspaces within an org. Group tasks under named projects, assign agents to projects, and track project-level status.
4
+ type: domain-skill
5
+ default_mode: confirm
6
+ ---
7
+
8
+ # Mastermind Projects
9
+
10
+ This skill is invoked by `mastermind:projects` or directly via `/mastermind:projects`.
11
+
12
+ ---
13
+
14
+ ## Inputs
15
+
16
+ - `brain_context`: BRAIN CONTEXT block
17
+ - `org_name`: org to manage projects for
18
+ - `action`: list | add | archive | assign | status
19
+ - `project_name`: display name (for add)
20
+ - `project_id`: slug (for archive/assign/status)
21
+ - `agent_id`: role id to assign as project lead
22
+ - `description`: project description
23
+ - `caller`: command | master
24
+
25
+ ---
26
+
27
+ ## Step 0 — Brain Load (standalone only)
28
+
29
+ If `caller` is not "command", load brain context following _protocol.md Brain Load Procedure with namespace: `ops`.
30
+
31
+ ---
32
+
33
+ ## Step 1 — Load Projects State
34
+
35
+ Projects are stored in `.monomind/orgs/<org_name>-projects.json`:
36
+
37
+ ```bash
38
+ projectsFile=".monomind/orgs/${org_name}-projects.json"
39
+ [ ! -f "$projectsFile" ] && echo '{"projects":[]}' > "$projectsFile"
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Step 2 — Execute Action
45
+
46
+ ### list (default)
47
+
48
+ ```bash
49
+ jq -r '
50
+ .projects[] |
51
+ "[\(.id)] \(.name) lead=\(.lead_agent // "unassigned") status=\(.status // "active") tasks=\(.task_count // 0)\n \(.description // "")"
52
+ ' "$projectsFile" 2>/dev/null || echo "No projects yet."
53
+ ```
54
+
55
+ Render as:
56
+ ```
57
+ PROJECTS — org: <org_name>
58
+ ──────────────────────────────────────────────────────
59
+ [homepage-redesign] Homepage Redesign
60
+ Lead: content-writer | Status: active | Tasks: 7
61
+ A full redesign of the company homepage with new copy and visuals.
62
+
63
+ [q2-seo-push] Q2 SEO Push
64
+ Lead: seo-specialist | Status: active | Tasks: 12
65
+ Target 10 high-volume keywords for Q2.
66
+ ```
67
+
68
+ ### add
69
+
70
+ ```bash
71
+ project_id=$(echo "$project_name" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | tr -s '-')
72
+ tmp="${projectsFile}.tmp"
73
+ jq --arg id "$project_id" \
74
+ --arg name "$project_name" \
75
+ --arg desc "${description:-}" \
76
+ --arg lead "${agent_id:-}" \
77
+ '.projects += [{"id":$id,"name":$name,"description":$desc,"lead_agent":($lead|if .=="" then null else . end),
78
+ "status":"active","task_count":0,"created_at":(now|todate)}]' \
79
+ "$projectsFile" > "$tmp" && mv "$tmp" "$projectsFile"
80
+ echo "Project created: $project_id"
81
+ ```
82
+
83
+ Emit `org:project:created` event to dashboard.
84
+
85
+ ### assign
86
+
87
+ Set the lead agent for a project:
88
+
89
+ ```bash
90
+ tmp="${projectsFile}.tmp"
91
+ jq --arg id "$project_id" --arg agent "$agent_id" \
92
+ '.projects = [.projects[] | if .id == $id then .lead_agent = $agent | .updated_at = (now|todate) else . end]' \
93
+ "$projectsFile" > "$tmp" && mv "$tmp" "$projectsFile"
94
+ echo "Assigned $agent_id as lead for project $project_id"
95
+ ```
96
+
97
+ ### archive
98
+
99
+ ```bash
100
+ tmp="${projectsFile}.tmp"
101
+ jq --arg id "$project_id" \
102
+ '.projects = [.projects[] | if .id == $id then .status = "archived" | .archived_at = (now|todate) else . end]' \
103
+ "$projectsFile" > "$tmp" && mv "$tmp" "$projectsFile"
104
+ echo "Project $project_id archived."
105
+ ```
106
+
107
+ ### status
108
+
109
+ Show project summary with linked tasks from the board:
110
+
111
+ ```bash
112
+ project=$(jq --arg id "$project_id" '.projects[] | select(.id == $id)' "$projectsFile")
113
+ echo "$project" | jq .
114
+
115
+ # If board exists, count tasks tagged with this project
116
+ orgFile=".monomind/orgs/${org_name}.json"
117
+ board_id=$(jq -r '.board_id // empty' "$orgFile")
118
+ if [ -n "$board_id" ]; then
119
+ todo_col=$(jq -r '.todo_col_id // empty' "$orgFile")
120
+ doing_col=$(jq -r '.doing_col_id // empty' "$orgFile")
121
+ done_col=$(jq -r '.done_col_id // empty' "$orgFile")
122
+ echo "Tasks on board tagged project:$project_id:"
123
+ for col in "$todo_col" "$doing_col" "$done_col"; do
124
+ monotask card list $board_id --col $col --json 2>/dev/null | \
125
+ jq -r --arg p "project:$project_id" '[.[] | select((.labels // []) | index($p))] | length' 2>/dev/null
126
+ done
127
+ fi
128
+ ```
129
+
130
+ ---
131
+
132
+ ## Using Projects in Task Management
133
+
134
+ When creating tasks with `/mastermind:tasks`, tag them to a project:
135
+
136
+ ```bash
137
+ monotask card label add $board_id $CARD_ID "project:<project_id>"
138
+ ```
139
+
140
+ When running org agents, include the project context in task prompts:
141
+
142
+ ```
143
+ This task belongs to project "<project_name>": <description>
144
+ Report your output tagged with project_id: <project_id>
145
+ ```
146
+
147
+ ---
148
+
149
+ ## Step 3 — Return Output
150
+
151
+ ```yaml
152
+ domain: ops
153
+ status: complete
154
+ action: <action>
155
+ org: <org_name>
156
+ project_id: <project_id if applicable>
157
+ projects_file: .monomind/orgs/<org_name>-projects.json
158
+ ```
159
+
160
+ ---
161
+
162
+ ## Step 4 — Brain Write (standalone only)
163
+
164
+ If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.
@@ -0,0 +1,253 @@
1
+ ---
2
+ name: mastermind-routine-detail
3
+ description: Mastermind routine-detail — deep inspection and management of a single routine: trigger config (schedule/webhook), variables, concurrency/catchup policies, run history, webhook rotation, and revision tracking.
4
+ type: domain-skill
5
+ default_mode: auto
6
+ ---
7
+
8
+ # Mastermind Routine Detail
9
+
10
+ This skill is invoked by `mastermind:routine-detail` or directly via `/mastermind:routine-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 routine belongs to (required)
18
+ - `routine_id`: routine id/slug (required)
19
+ - `action`: show | runs | config | variables | rotate-webhook | revisions
20
+ - `days`: lookback window for run history (default 14)
21
+ - `var_key`: variable key (for variables --set)
22
+ - `var_value`: variable value
23
+ - `caller`: command | master
24
+
25
+ ---
26
+
27
+ ## Trigger Types
28
+
29
+ | Kind | Description |
30
+ |------|-------------|
31
+ | `schedule` | Cron expression — agent fires on schedule |
32
+ | `webhook` | HTTP POST to generated endpoint; signed via signing_mode |
33
+
34
+ ## Signing Modes (webhook only)
35
+
36
+ | Mode | Description |
37
+ |------|-------------|
38
+ | `none` | No signature verification |
39
+ | `bearer` | Authorization: Bearer <token> header |
40
+ | `hmac_sha256` | X-Hub-Signature-256 header (HMAC-SHA256 of body) |
41
+ | `github_hmac` | GitHub-style HMAC — identical to hmac_sha256 + secret stored in mastermind:secrets |
42
+
43
+ ## Concurrency Policies
44
+
45
+ | Policy | Behavior |
46
+ |--------|----------|
47
+ | `coalesce_if_active` | Skip trigger if a run is already active; record as coalesced |
48
+ | `always_enqueue` | Always create a new run regardless of active runs |
49
+ | `skip_if_active` | Silently discard trigger if a run is active |
50
+
51
+ ## Catchup Policies (schedule only)
52
+
53
+ | Policy | Behavior |
54
+ |--------|----------|
55
+ | `skip_missed` | Missed scheduled runs are discarded |
56
+ | `enqueue_missed_with_cap` | Enqueue missed runs up to `catchup_cap` (default 3) |
57
+
58
+ ---
59
+
60
+ ## Step 0 — Brain Load (standalone only)
61
+
62
+ If `caller` is not "command", load brain context following _protocol.md Brain Load Procedure with namespace: `ops`.
63
+
64
+ ---
65
+
66
+ ## Step 1 — Load Routine Data
67
+
68
+ ```bash
69
+ orgFile=".monomind/orgs/${org_name}.json"
70
+ [ ! -f "$orgFile" ] && { echo "ERROR: Org '${org_name}' not found."; exit 1; }
71
+
72
+ routinesFile=".monomind/orgs/${org_name}-routines.json"
73
+ [ ! -f "$routinesFile" ] && { echo "ERROR: No routines file for org '$org_name'. Create routines first via /mastermind:runorg."; exit 1; }
74
+
75
+ routineDef=$(jq -r --arg id "$routine_id" '.routines[] | select(.id == $id)' "$routinesFile")
76
+ [ -z "$routineDef" ] && { echo "ERROR: Routine '$routine_id' not found in org '$org_name'."; exit 1; }
77
+
78
+ stateFile=".monomind/orgs/${org_name}-state.json"
79
+ days=${days:-14}
80
+ cutoff=$(date -u -v-${days}d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "${days} days ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || echo "")
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Step 2 — Execute Action
86
+
87
+ ### show (default)
88
+
89
+ ```bash
90
+ echo "ROUTINE DETAIL — $routine_id @ $org_name"
91
+ echo "────────────────────────────────────────────────────────"
92
+
93
+ echo "$routineDef" | jq -r '
94
+ " ID: \(.id)",
95
+ " Name: \(.name // "-")",
96
+ " Assigned agent: \(.agent_id // "(any)")",
97
+ " Enabled: \(.enabled // false)",
98
+ "",
99
+ "TRIGGER",
100
+ " Kind: \(.trigger.kind // "schedule")",
101
+ (if (.trigger.kind // "schedule") == "schedule" then
102
+ " Cron: \(.trigger.cron // "-")",
103
+ " Catchup policy: \(.catchup_policy // "skip_missed")",
104
+ " Catchup cap: \(.catchup_cap // 3 | tostring)"
105
+ else
106
+ " Endpoint: \(.trigger.endpoint // "(not generated)")",
107
+ " Signing mode: \(.trigger.signing_mode // "none")"
108
+ end),
109
+ "",
110
+ "CONCURRENCY",
111
+ " Policy: \(.concurrency_policy // "coalesce_if_active")",
112
+ "",
113
+ "VARIABLES",
114
+ " Count: \((.variables // {}) | length | tostring)"
115
+ '
116
+
117
+ # Show last run summary from state
118
+ lastRun=$([ -f "$stateFile" ] && jq -r --arg id "$routine_id" '.routines[$id].last_run // "-"' "$stateFile" || echo "-")
119
+ runCount=$([ -f "$stateFile" ] && jq -r --arg id "$routine_id" '.routines[$id].run_count // 0' "$stateFile" || echo "0")
120
+ echo ""
121
+ echo " Last run: $lastRun"
122
+ echo " Run count: $runCount"
123
+ ```
124
+
125
+ ### runs
126
+
127
+ ```bash
128
+ echo "RUN HISTORY — $routine_id (last ${days} days)"
129
+ echo "────────────────────────────────────────────────────────"
130
+ printf "%-26s %-12s %-8s %-14s %s\n" "TIMESTAMP" "STATUS" "TOKENS" "TRIGGER KIND" "COALESCED"
131
+ echo "────────────────────────────────────────────────────────"
132
+
133
+ runsFile=".monomind/orgs/${org_name}-routine-runs.jsonl"
134
+ found=0
135
+
136
+ if [ -f "$runsFile" ]; then
137
+ while IFS= read -r line; do
138
+ rid=$(echo "$line" | jq -r '.routine_id // ""')
139
+ [ "$rid" != "$routine_id" ] && continue
140
+ ts=$(echo "$line" | jq -r '.ts // ""')
141
+ [ -n "$cutoff" ] && [ "$ts" \< "$cutoff" ] && continue
142
+ st=$(echo "$line" | jq -r '.status // "-"')
143
+ tok=$(echo "$line" | jq -r '.tokens // "-"')
144
+ tkind=$(echo "$line" | jq -r '.trigger_kind // "schedule"')
145
+ coal=$(echo "$line" | jq -r 'if .coalesced then "yes" else "-" end')
146
+ printf "%-26s %-12s %-8s %-14s %s\n" "$ts" "$st" "$tok" "$tkind" "$coal"
147
+ found=$((found + 1))
148
+ done < "$runsFile"
149
+ fi
150
+
151
+ [ "$found" -eq 0 ] && echo " No runs in the last $days days."
152
+ ```
153
+
154
+ ### config
155
+
156
+ ```bash
157
+ echo "FULL CONFIG — $routine_id"
158
+ echo "────────────────────────────────────────────────────────"
159
+ echo "$routineDef" | jq 'del(.variables)'
160
+ echo ""
161
+ echo "TRIGGER DETAIL"
162
+ echo "$routineDef" | jq '.trigger'
163
+ ```
164
+
165
+ ### variables
166
+
167
+ ```bash
168
+ echo "VARIABLES — $routine_id"
169
+ echo "────────────────────────────────────────────────────────"
170
+
171
+ vars=$(echo "$routineDef" | jq -r '.variables // {} | to_entries[] | " \(.key) = \(.value)"')
172
+ [ -z "$vars" ] && echo " No variables defined." || echo "$vars"
173
+
174
+ # Set a variable if var_key provided
175
+ if [ -n "$var_key" ]; then
176
+ [ -z "$var_value" ] && { echo "ERROR: --var-value required when setting a variable."; exit 1; }
177
+ tmp="${routinesFile}.tmp"
178
+ jq --arg id "$routine_id" --arg k "$var_key" --arg v "$var_value" \
179
+ '.routines = [.routines[] | if .id == $id then .variables[$k] = $v else . end]' \
180
+ "$routinesFile" > "$tmp" && mv "$tmp" "$routinesFile"
181
+ echo ""
182
+ echo "Set variable: $var_key = $var_value"
183
+ fi
184
+ ```
185
+
186
+ ### rotate-webhook
187
+
188
+ ```bash
189
+ triggerKind=$(echo "$routineDef" | jq -r '.trigger.kind // "schedule"')
190
+ [ "$triggerKind" != "webhook" ] && { echo "ERROR: Routine '$routine_id' is not a webhook-triggered routine."; exit 1; }
191
+
192
+ newToken=$(openssl rand -hex 24 2>/dev/null || python3 -c "import secrets; print(secrets.token_hex(24))")
193
+ newEndpoint="/api/webhook/${org_name}/${routine_id}/${newToken}"
194
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
195
+
196
+ tmp="${routinesFile}.tmp"
197
+ jq --arg id "$routine_id" --arg ep "$newEndpoint" --arg ts "$ts" \
198
+ '.routines = [.routines[] | if .id == $id then
199
+ .trigger.endpoint = $ep | .trigger.rotated_at = $ts
200
+ else . end]' \
201
+ "$routinesFile" > "$tmp" && mv "$tmp" "$routinesFile"
202
+
203
+ echo "Webhook rotated for '$routine_id'"
204
+ echo " New endpoint: $newEndpoint"
205
+ echo " Rotated at: $ts"
206
+ echo ""
207
+ echo "Update your webhook source to use the new endpoint."
208
+ signingMode=$(echo "$routineDef" | jq -r '.trigger.signing_mode // "none"')
209
+ [ "$signingMode" != "none" ] && echo " Signing mode '$signingMode' is unchanged — re-generate the signing secret if required."
210
+ ```
211
+
212
+ ### revisions
213
+
214
+ ```bash
215
+ revisionsFile=".monomind/orgs/${org_name}-routine-revisions.jsonl"
216
+ echo "REVISIONS — $routine_id"
217
+ echo "────────────────────────────────────────────────────────"
218
+
219
+ if [ ! -f "$revisionsFile" ]; then
220
+ echo " No revision history found."
221
+ else
222
+ found=0
223
+ while IFS= read -r line; do
224
+ rid=$(echo "$line" | jq -r '.routine_id // ""')
225
+ [ "$rid" != "$routine_id" ] && continue
226
+ ts=$(echo "$line" | jq -r '.ts // ""')
227
+ who=$(echo "$line" | jq -r '.changed_by // "system"')
228
+ what=$(echo "$line" | jq -r '.change_summary // "-"')
229
+ printf " [%s] by %-16s %s\n" "$ts" "$who" "$what"
230
+ found=$((found + 1))
231
+ done < "$revisionsFile"
232
+ [ "$found" -eq 0 ] && echo " No revisions found for '$routine_id'."
233
+ fi
234
+ ```
235
+
236
+ ---
237
+
238
+ ## Step 3 — Return Output
239
+
240
+ ```yaml
241
+ domain: ops
242
+ status: complete
243
+ action: <action>
244
+ org: <org_name>
245
+ routine_id: <routine_id>
246
+ trigger_kind: <schedule|webhook>
247
+ ```
248
+
249
+ ---
250
+
251
+ ## Step 4 — Brain Write (standalone only)
252
+
253
+ If `caller` is not "command", follow _protocol.md Brain Write Procedure for domain `ops`.