@monoes/monomindcli 1.11.7 → 1.11.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/github/issue-tracker.md +5 -5
- package/.claude/agents/github/pr-manager.md +5 -5
- package/.claude/agents/github/release-manager.md +3 -3
- package/.claude/agents/github/repo-architect.md +3 -3
- package/.claude/agents/github/swarm-issue.md +1 -1
- package/.claude/agents/github/sync-coordinator.md +1 -1
- package/.claude/agents/github/workflow-automation.md +1 -1
- package/.claude/commands/github/repo-architect.md +1 -1
- package/.claude/commands/github/sync-coordinator.md +1 -1
- package/.claude/commands/mastermind/createorg.md +4 -1
- package/.claude/commands/mastermind/help.md +2 -2
- package/.claude/commands/mastermind/orgs.md +21 -0
- package/.claude/commands/mastermind/orgstatus.md +59 -0
- package/.claude/commands/mastermind/runorg.md +4 -2
- package/.claude/commands/mastermind/stoporg.md +78 -0
- package/.claude/commands/mastermind/swarm.md +1 -1
- package/.claude/helpers/handlers/gates-handler.cjs +135 -0
- package/.claude/helpers/handlers/task-handler.cjs +7 -3
- package/.claude/helpers/hook-handler.cjs +11 -2
- package/.claude/helpers/intelligence.cjs +87 -0
- package/.claude/helpers/learning-service.mjs +60 -0
- package/.claude/helpers/memory.cjs +69 -0
- package/.claude/helpers/router.cjs +68 -0
- package/.claude/helpers/session.cjs +63 -0
- package/.claude/helpers/utils/monograph.cjs +4 -2
- package/.claude/helpers/utils/telemetry.cjs +3 -2
- package/.claude/skills/agentic-jujutsu/SKILL.md +1 -1
- package/.claude/skills/hive-mind-advanced/SKILL.md +4 -4
- package/.claude/skills/mastermind/_agent-select.md +2 -2
- package/.claude/skills/mastermind/access.md +11 -11
- package/.claude/skills/mastermind/adapter-manager.md +13 -13
- package/.claude/skills/mastermind/adapters.md +7 -7
- package/.claude/skills/mastermind/agent-detail.md +1 -1
- package/.claude/skills/mastermind/agents.md +5 -5
- package/.claude/skills/mastermind/approval-detail.md +6 -6
- package/.claude/skills/mastermind/approve.md +9 -10
- package/.claude/skills/mastermind/backup.md +2 -2
- package/.claude/skills/mastermind/bootstrap.md +2 -2
- package/.claude/skills/mastermind/companies.md +7 -7
- package/.claude/skills/mastermind/createorg.md +213 -8
- package/.claude/skills/mastermind/diagnose.md +4 -4
- package/.claude/skills/mastermind/env.md +1 -1
- package/.claude/skills/mastermind/environments.md +8 -8
- package/.claude/skills/mastermind/export.md +12 -3
- package/.claude/skills/mastermind/goal-detail.md +9 -9
- package/.claude/skills/mastermind/goals.md +4 -4
- package/.claude/skills/mastermind/heartbeat.md +1 -1
- package/.claude/skills/mastermind/idea.md +4 -4
- package/.claude/skills/mastermind/import.md +8 -8
- package/.claude/skills/mastermind/inbox.md +4 -4
- package/.claude/skills/mastermind/instance-settings.md +9 -9
- package/.claude/skills/mastermind/instance.md +9 -7
- package/.claude/skills/mastermind/invite-landing.md +5 -5
- package/.claude/skills/mastermind/invites.md +12 -12
- package/.claude/skills/mastermind/issue-detail.md +8 -8
- package/.claude/skills/mastermind/monitor.md +11 -11
- package/.claude/skills/mastermind/my-issues.md +6 -6
- package/.claude/skills/mastermind/new-agent.md +4 -4
- package/.claude/skills/mastermind/org-chart.md +8 -6
- package/.claude/skills/mastermind/org-settings.md +58 -21
- package/.claude/skills/mastermind/orgs.md +98 -0
- package/.claude/skills/mastermind/orgstatus.md +194 -0
- package/.claude/skills/mastermind/plan-to-tasks.md +1 -1
- package/.claude/skills/mastermind/plugin-manager.md +12 -12
- package/.claude/skills/mastermind/plugin-settings.md +5 -5
- package/.claude/skills/mastermind/plugins.md +5 -5
- package/.claude/skills/mastermind/profile.md +2 -2
- package/.claude/skills/mastermind/project-detail.md +12 -12
- package/.claude/skills/mastermind/project-workspace.md +4 -4
- package/.claude/skills/mastermind/projects.md +4 -4
- package/.claude/skills/mastermind/review.md +50 -0
- package/.claude/skills/mastermind/routine-detail.md +3 -3
- package/.claude/skills/mastermind/routines.md +7 -6
- package/.claude/skills/mastermind/runorg.md +178 -8
- package/.claude/skills/mastermind/search.md +6 -6
- package/.claude/skills/mastermind/secrets.md +6 -6
- package/.claude/skills/mastermind/skills.md +4 -4
- package/.claude/skills/mastermind/stoporg.md +138 -0
- package/.claude/skills/mastermind/workspace-detail.md +5 -5
- package/.claude/skills/mastermind/workspaces.md +9 -9
- package/.claude/skills/performance-analysis/SKILL.md +3 -3
- package/.claude/skills/sparc-methodology/SKILL.md +2 -2
- package/.claude/skills/swarm-advanced/SKILL.md +4 -4
- package/README.md +129 -376
- package/dist/src/agents/registry-builder.d.ts +27 -1
- package/dist/src/agents/registry-builder.d.ts.map +1 -1
- package/dist/src/agents/registry-builder.js +2 -2
- package/dist/src/agents/registry-builder.js.map +1 -1
- package/dist/src/commands/agent.d.ts.map +1 -1
- package/dist/src/commands/agent.js +4 -9
- package/dist/src/commands/agent.js.map +1 -1
- package/dist/src/commands/analyze.d.ts +1 -1
- package/dist/src/commands/analyze.js +1 -1
- package/dist/src/commands/claims.d.ts +1 -1
- package/dist/src/commands/claims.js +2 -2
- package/dist/src/commands/claims.js.map +1 -1
- package/dist/src/commands/cleanup.d.ts +1 -1
- package/dist/src/commands/cleanup.js +1 -1
- package/dist/src/commands/completions.d.ts +1 -1
- package/dist/src/commands/completions.js +1 -1
- package/dist/src/commands/deployment.d.ts +1 -1
- package/dist/src/commands/deployment.js +2 -2
- package/dist/src/commands/deployment.js.map +1 -1
- package/dist/src/commands/doctor.d.ts +1 -1
- package/dist/src/commands/doctor.d.ts.map +1 -1
- package/dist/src/commands/doctor.js +69 -4
- package/dist/src/commands/doctor.js.map +1 -1
- package/dist/src/commands/guidance.d.ts.map +1 -1
- package/dist/src/commands/guidance.js +129 -0
- package/dist/src/commands/guidance.js.map +1 -1
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +4 -0
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/init.js +18 -0
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/monovector/import.d.ts +1 -1
- package/dist/src/commands/monovector/import.js +1 -1
- package/dist/src/commands/monovector/index.d.ts +1 -1
- package/dist/src/commands/monovector/index.js +1 -1
- package/dist/src/commands/monovector/setup.d.ts +1 -1
- package/dist/src/commands/monovector/setup.js +2 -2
- package/dist/src/commands/neural.d.ts +1 -1
- package/dist/src/commands/neural.js +2 -2
- package/dist/src/commands/neural.js.map +1 -1
- package/dist/src/commands/performance.d.ts +1 -1
- package/dist/src/commands/performance.js +2 -2
- package/dist/src/commands/performance.js.map +1 -1
- package/dist/src/commands/platforms.d.ts +1 -1
- package/dist/src/commands/platforms.js +1 -1
- package/dist/src/commands/plugins.d.ts +1 -1
- package/dist/src/commands/plugins.d.ts.map +1 -1
- package/dist/src/commands/plugins.js +2 -4
- package/dist/src/commands/plugins.js.map +1 -1
- package/dist/src/commands/providers.d.ts +1 -1
- package/dist/src/commands/providers.js +2 -2
- package/dist/src/commands/providers.js.map +1 -1
- package/dist/src/commands/route.d.ts +1 -1
- package/dist/src/commands/route.d.ts.map +1 -1
- package/dist/src/commands/route.js +5 -11
- package/dist/src/commands/route.js.map +1 -1
- package/dist/src/commands/security.d.ts +1 -1
- package/dist/src/commands/security.d.ts.map +1 -1
- package/dist/src/commands/security.js +140 -91
- package/dist/src/commands/security.js.map +1 -1
- package/dist/src/dlq/dlq-replayer.d.ts +7 -1
- package/dist/src/dlq/dlq-replayer.d.ts.map +1 -1
- package/dist/src/dlq/dlq-replayer.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +10 -26
- package/dist/src/index.js.map +1 -1
- package/dist/src/init/claudemd-generator.js +2 -2
- package/dist/src/init/claudemd-generator.js.map +1 -1
- package/dist/src/init/executor.js +3 -3
- package/dist/src/init/settings-generator.js +2 -2
- package/dist/src/init/settings-generator.js.map +1 -1
- package/dist/src/mcp-client.d.ts +5 -0
- package/dist/src/mcp-client.d.ts.map +1 -1
- package/dist/src/mcp-client.js +7 -0
- package/dist/src/mcp-client.js.map +1 -1
- package/dist/src/mcp-server.d.ts.map +1 -1
- package/dist/src/mcp-server.js +17 -1
- package/dist/src/mcp-server.js.map +1 -1
- package/dist/src/mcp-tools/a2a-tools.js +6 -6
- package/dist/src/mcp-tools/a2a-tools.js.map +1 -1
- package/dist/src/mcp-tools/auto-install.d.ts +2 -2
- package/dist/src/mcp-tools/auto-install.js +1 -1
- package/dist/src/mcp-tools/auto-install.js.map +1 -1
- package/dist/src/mcp-tools/hive-mind-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/hive-mind-tools.js +1 -52
- package/dist/src/mcp-tools/hive-mind-tools.js.map +1 -1
- package/dist/src/mcp-tools/index.d.ts +4 -0
- package/dist/src/mcp-tools/index.d.ts.map +1 -1
- package/dist/src/mcp-tools/index.js +4 -0
- package/dist/src/mcp-tools/index.js.map +1 -1
- package/dist/src/mcp-tools/monograph-compat.d.ts.map +1 -1
- package/dist/src/mcp-tools/monograph-compat.js +1 -2
- package/dist/src/mcp-tools/monograph-compat.js.map +1 -1
- package/dist/src/mcp-tools/monograph-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/monograph-tools.js +107 -5
- package/dist/src/mcp-tools/monograph-tools.js.map +1 -1
- package/dist/src/mcp-tools/security-tools.d.ts +6 -6
- package/dist/src/mcp-tools/security-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/security-tools.js +48 -61
- package/dist/src/mcp-tools/security-tools.js.map +1 -1
- package/dist/src/memory/memory-bridge.d.ts +0 -1
- package/dist/src/memory/memory-bridge.d.ts.map +1 -1
- package/dist/src/memory/memory-bridge.js +232 -57
- package/dist/src/memory/memory-bridge.js.map +1 -1
- package/dist/src/memory/memory-initializer.d.ts.map +1 -1
- package/dist/src/memory/memory-initializer.js +3 -32
- package/dist/src/memory/memory-initializer.js.map +1 -1
- package/dist/src/plugins/store/discovery.d.ts.map +1 -1
- package/dist/src/plugins/store/discovery.js +0 -69
- package/dist/src/plugins/store/discovery.js.map +1 -1
- package/dist/src/routing/embed-worker.d.ts +2 -0
- package/dist/src/routing/embed-worker.d.ts.map +1 -0
- package/dist/src/routing/embed-worker.js +55 -0
- package/dist/src/routing/embed-worker.js.map +1 -0
- package/dist/src/routing/embedder.d.ts +31 -0
- package/dist/src/routing/embedder.d.ts.map +1 -0
- package/dist/src/routing/embedder.js +0 -0
- package/dist/src/routing/embedder.js.map +1 -0
- package/dist/src/routing/llm-caller.d.ts +1 -1
- package/dist/src/routing/llm-caller.d.ts.map +1 -1
- package/dist/src/routing/llm-caller.js +18 -3
- package/dist/src/routing/llm-caller.js.map +1 -1
- package/dist/src/routing/route-layer-factory.d.ts +9 -0
- package/dist/src/routing/route-layer-factory.d.ts.map +1 -0
- package/dist/src/routing/route-layer-factory.js +151 -0
- package/dist/src/routing/route-layer-factory.js.map +1 -0
- package/dist/src/services/worker-daemon.d.ts.map +1 -1
- package/dist/src/services/worker-daemon.js +0 -1
- package/dist/src/services/worker-daemon.js.map +1 -1
- package/dist/src/suggest.d.ts +1 -1
- package/dist/src/suggest.js +1 -1
- package/dist/src/ui/server.mjs +5 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -10
- package/scripts/publish-registry.ts +0 -2
- package/scripts/understand-analyze.mjs +1 -1
|
@@ -65,9 +65,9 @@ echo "INVITES — org: $org_name"
|
|
|
65
65
|
echo "────────────────────────────────────────────────────────"
|
|
66
66
|
|
|
67
67
|
# Active invites (pending in join_requests with type=invite)
|
|
68
|
-
activeInvites=$(jq '[.join_requests[] | select(.type == "invite" and .status == "pending")] | length' "$membersFile")
|
|
68
|
+
activeInvites=$(jq '[(.join_requests // [])[] | select(.type == "invite" and .status == "pending")] | length' "$membersFile")
|
|
69
69
|
totalMembers=$(jq '.members | length' "$membersFile")
|
|
70
|
-
pendingJoins=$(jq '[.join_requests[] | select(.type != "invite" and .status == "pending_approval")] | length' "$membersFile")
|
|
70
|
+
pendingJoins=$(jq '[(.join_requests // [])[] | select(.type != "invite" and .status == "pending_approval")] | length' "$membersFile")
|
|
71
71
|
|
|
72
72
|
echo " Members: $totalMembers"
|
|
73
73
|
echo " Pending invites: $activeInvites"
|
|
@@ -78,7 +78,7 @@ if [ "$activeInvites" -gt 0 ]; then
|
|
|
78
78
|
echo "ACTIVE INVITES"
|
|
79
79
|
printf " %-28s %-10s %-20s %s\n" "TOKEN" "ROLE" "CREATED" "URL"
|
|
80
80
|
echo " ────────────────────────────────────────────────────────"
|
|
81
|
-
jq -r '.join_requests[] | select(.type == "invite" and .status == "pending") |
|
|
81
|
+
jq -r '(.join_requests // [])[] | select(.type == "invite" and .status == "pending") |
|
|
82
82
|
[.token, (.role // "operator"), (.createdAt // "-"), (.inviteUrl // "-")] | @tsv' \
|
|
83
83
|
"$membersFile" | while IFS=$'\t' read -r tok role ts url; do
|
|
84
84
|
printf " %-28s %-10s %-20s %s\n" "${tok:0:24}…" "$role" "$ts" "${url:0:40}…"
|
|
@@ -126,14 +126,14 @@ echo "To copy URL hint: --action copy-url --invite-id $token"
|
|
|
126
126
|
|
|
127
127
|
# Find the invite
|
|
128
128
|
inviteExists=$(jq -r --arg id "$invite_id" \
|
|
129
|
-
'[.join_requests[] | select((.id == $id or .token == $id) and .type == "invite")] | length' \
|
|
129
|
+
'[(.join_requests // [])[] | select((.id == $id or .token == $id) and .type == "invite")] | length' \
|
|
130
130
|
"$membersFile")
|
|
131
131
|
[ "$inviteExists" -eq 0 ] && { echo "ERROR: Invite '$invite_id' not found or already resolved."; exit 1; }
|
|
132
132
|
|
|
133
133
|
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
134
134
|
tmp="${membersFile}.tmp"
|
|
135
135
|
jq --arg id "$invite_id" --arg ts "$ts" \
|
|
136
|
-
'.join_requests = [.join_requests[] | if (.id == $id or .token == $id) then
|
|
136
|
+
'.join_requests = [(.join_requests // [])[] | if (.id == $id or .token == $id) then
|
|
137
137
|
.status = "revoked" | .resolvedAt = $ts
|
|
138
138
|
else . end]' \
|
|
139
139
|
"$membersFile" > "$tmp" && mv "$tmp" "$membersFile"
|
|
@@ -148,7 +148,7 @@ echo " Revoked at: $ts"
|
|
|
148
148
|
[ -z "$invite_id" ] && { echo "ERROR: --invite-id required."; exit 1; }
|
|
149
149
|
|
|
150
150
|
inviteUrl=$(jq -r --arg id "$invite_id" \
|
|
151
|
-
'.join_requests[] | select(.id == $id or .token == $id) | .inviteUrl // ""' \
|
|
151
|
+
'(.join_requests // [])[] | select(.id == $id or .token == $id) | .inviteUrl // ""' \
|
|
152
152
|
"$membersFile")
|
|
153
153
|
[ -z "$inviteUrl" ] && { echo "ERROR: Invite '$invite_id' not found."; exit 1; }
|
|
154
154
|
|
|
@@ -172,7 +172,7 @@ echo " Filter: status=$statusFilter type=$typeFilter"
|
|
|
172
172
|
echo "────────────────────────────────────────────────────────"
|
|
173
173
|
|
|
174
174
|
jq -r --arg st "$statusFilter" --arg type "$typeFilter" '
|
|
175
|
-
.join_requests[] |
|
|
175
|
+
(.join_requests // [])[] |
|
|
176
176
|
select(
|
|
177
177
|
(.status == $st) and
|
|
178
178
|
(.type != "invite") and
|
|
@@ -190,7 +190,7 @@ jq -r --arg st "$statusFilter" --arg type "$typeFilter" '
|
|
|
190
190
|
echo " → reject: --action reject-join --request-id $id"
|
|
191
191
|
done
|
|
192
192
|
|
|
193
|
-
total=$(jq --arg st "$statusFilter" '[.join_requests[] | select(.status == $st and .type != "invite")] | length' "$membersFile")
|
|
193
|
+
total=$(jq --arg st "$statusFilter" '[(.join_requests // [])[] | select(.status == $st and .type != "invite")] | length' "$membersFile")
|
|
194
194
|
[ "$total" -eq 0 ] && echo " No join requests with status='$statusFilter'."
|
|
195
195
|
echo ""
|
|
196
196
|
echo "Total ($statusFilter): $total"
|
|
@@ -202,13 +202,13 @@ echo "Total ($statusFilter): $total"
|
|
|
202
202
|
[ -z "$request_id" ] && { echo "ERROR: --request-id required."; exit 1; }
|
|
203
203
|
|
|
204
204
|
reqRole=$(jq -r --arg id "$request_id" \
|
|
205
|
-
'.join_requests[] | select(.id == $id) | .role // "viewer"' "$membersFile")
|
|
205
|
+
'(.join_requests // [])[] | select(.id == $id) | .role // "viewer"' "$membersFile")
|
|
206
206
|
[ -z "$reqRole" ] && { echo "ERROR: Request '$request_id' not found."; exit 1; }
|
|
207
207
|
|
|
208
208
|
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
209
209
|
tmp="${membersFile}.tmp"
|
|
210
210
|
jq --arg id "$request_id" --arg role "$reqRole" --arg ts "$ts" \
|
|
211
|
-
'.join_requests = [.join_requests[] | if .id == $id then .status = "approved" | .resolvedAt = $ts else . end] |
|
|
211
|
+
'.join_requests = [(.join_requests // [])[] | if .id == $id then .status = "approved" | .resolvedAt = $ts else . end] |
|
|
212
212
|
.members += [{"id":$id,"role":$role,"status":"active","grants":[],"joinedAt":$ts}]' \
|
|
213
213
|
"$membersFile" > "$tmp" && mv "$tmp" "$membersFile"
|
|
214
214
|
|
|
@@ -222,13 +222,13 @@ echo " Member added. View members: /mastermind:access --org $org_name --action
|
|
|
222
222
|
```bash
|
|
223
223
|
[ -z "$request_id" ] && { echo "ERROR: --request-id required."; exit 1; }
|
|
224
224
|
|
|
225
|
-
exists=$(jq -r --arg id "$request_id" '[.join_requests[] | select(.id == $id)] | length' "$membersFile")
|
|
225
|
+
exists=$(jq -r --arg id "$request_id" '[(.join_requests // [])[] | select(.id == $id)] | length' "$membersFile")
|
|
226
226
|
[ "$exists" -eq 0 ] && { echo "ERROR: Request '$request_id' not found."; exit 1; }
|
|
227
227
|
|
|
228
228
|
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
229
229
|
tmp="${membersFile}.tmp"
|
|
230
230
|
jq --arg id "$request_id" --arg ts "$ts" \
|
|
231
|
-
'.join_requests = [.join_requests[] | if .id == $id then .status = "rejected" | .resolvedAt = $ts else . end]' \
|
|
231
|
+
'.join_requests = [(.join_requests // [])[] | if .id == $id then .status = "rejected" | .resolvedAt = $ts else . end]' \
|
|
232
232
|
"$membersFile" > "$tmp" && mv "$tmp" "$membersFile"
|
|
233
233
|
|
|
234
234
|
echo "Join request '$request_id' rejected."
|
|
@@ -54,7 +54,7 @@ orgFile=".monomind/orgs/${org_name}.json"
|
|
|
54
54
|
issuesFile=".monomind/orgs/${org_name}-issues.json"
|
|
55
55
|
[ ! -f "$issuesFile" ] && { echo "ERROR: No issues file for org '$org_name'. Create tasks via /mastermind:tasks."; exit 1; }
|
|
56
56
|
|
|
57
|
-
issueDef=$(jq -r --arg id "$issue_id" '.issues[] | select(.id == $id or .slug == $id)' "$issuesFile")
|
|
57
|
+
issueDef=$(jq -r --arg id "$issue_id" '(.issues // [])[] | select(.id == $id or .slug == $id)' "$issuesFile")
|
|
58
58
|
[ -z "$issueDef" ] && { echo "ERROR: Issue '$issue_id' not found in org '$org_name'."; exit 1; }
|
|
59
59
|
|
|
60
60
|
resolvedId=$(echo "$issueDef" | jq -r '.id')
|
|
@@ -86,7 +86,7 @@ echo "$issueDef" | jq -r '
|
|
|
86
86
|
'
|
|
87
87
|
|
|
88
88
|
# Sub-issues
|
|
89
|
-
subCount=$(jq --arg pid "$resolvedId" '[.issues[] | select(.parent_id == $pid)] | length' "$issuesFile" 2>/dev/null || echo 0)
|
|
89
|
+
subCount=$(jq --arg pid "$resolvedId" '[(.issues // [])[] | select(.parent_id == $pid)] | length' "$issuesFile" 2>/dev/null || echo 0)
|
|
90
90
|
echo " Sub-issues: $subCount"
|
|
91
91
|
|
|
92
92
|
# Attachments
|
|
@@ -169,7 +169,7 @@ printf "%-24s %-12s %-10s %s\n" "ID" "STATUS" "PRIORITY" "TITLE"
|
|
|
169
169
|
echo "────────────────────────────────────────────────────────"
|
|
170
170
|
|
|
171
171
|
count=0
|
|
172
|
-
jq -r --arg pid "$resolvedId" '.issues[] | select(.parent_id == $pid) |
|
|
172
|
+
jq -r --arg pid "$resolvedId" '(.issues // [])[] | select(.parent_id == $pid) |
|
|
173
173
|
[.id, (.status // "open"), (.priority // "medium"), (.title // "(no title)")] | @tsv' \
|
|
174
174
|
"$issuesFile" 2>/dev/null | while IFS=$'\t' read -r id st pri title; do
|
|
175
175
|
printf "%-24s %-12s %-10s %s\n" "$id" "$st" "$pri" "$title"
|
|
@@ -215,13 +215,13 @@ echo " Time: $ts"
|
|
|
215
215
|
[ -z "$assignee_id" ] && { echo "ERROR: --assignee-id required."; exit 1; }
|
|
216
216
|
|
|
217
217
|
# Validate agent exists in org
|
|
218
|
-
exists=$(jq --arg id "$assignee_id" '[.roles[] | select(.id == $id)] | length' "$orgFile")
|
|
218
|
+
exists=$(jq --arg id "$assignee_id" '[(.roles // [])[] | select(.id == $id)] | length' "$orgFile")
|
|
219
219
|
[ "$exists" -eq 0 ] && echo "WARNING: Agent '$assignee_id' not found in org '$org_name'. Assigning anyway."
|
|
220
220
|
|
|
221
221
|
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
222
222
|
tmp="${issuesFile}.tmp"
|
|
223
223
|
jq --arg id "$resolvedId" --arg ag "$assignee_id" --arg ts "$ts" \
|
|
224
|
-
'.issues = [.issues[] | if .id == $id then .assignee_id = $ag | .updated_at = $ts else . end]' \
|
|
224
|
+
'.issues = [(.issues // [])[] | if .id == $id then .assignee_id = $ag | .updated_at = $ts else . end]' \
|
|
225
225
|
"$issuesFile" > "$tmp" && mv "$tmp" "$issuesFile"
|
|
226
226
|
|
|
227
227
|
echo "Issue '$issue_id' assigned to '$assignee_id'."
|
|
@@ -233,7 +233,7 @@ echo "Issue '$issue_id' assigned to '$assignee_id'."
|
|
|
233
233
|
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
234
234
|
tmp="${issuesFile}.tmp"
|
|
235
235
|
jq --arg id "$resolvedId" --arg ts "$ts" \
|
|
236
|
-
'.issues = [.issues[] | if .id == $id then .status = "done" | .updated_at = $ts | .closed_at = $ts else . end]' \
|
|
236
|
+
'.issues = [(.issues // [])[] | if .id == $id then .status = "done" | .updated_at = $ts | .closed_at = $ts else . end]' \
|
|
237
237
|
"$issuesFile" > "$tmp" && mv "$tmp" "$issuesFile"
|
|
238
238
|
echo "Issue '$issue_id' → done (closed at $ts)."
|
|
239
239
|
```
|
|
@@ -244,7 +244,7 @@ echo "Issue '$issue_id' → done (closed at $ts)."
|
|
|
244
244
|
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
245
245
|
tmp="${issuesFile}.tmp"
|
|
246
246
|
jq --arg id "$resolvedId" --arg ts "$ts" \
|
|
247
|
-
'.issues = [.issues[] | if .id == $id then .status = "open" | .updated_at = $ts | .closed_at = null else . end]' \
|
|
247
|
+
'.issues = [(.issues // [])[] | if .id == $id then .status = "open" | .updated_at = $ts | .closed_at = null else . end]' \
|
|
248
248
|
"$issuesFile" > "$tmp" && mv "$tmp" "$issuesFile"
|
|
249
249
|
echo "Issue '$issue_id' → reopened."
|
|
250
250
|
```
|
|
@@ -262,7 +262,7 @@ newStatus=$([ "$recovery_action" = "accept" ] && echo "in_progress" || echo "can
|
|
|
262
262
|
|
|
263
263
|
tmp="${issuesFile}.tmp"
|
|
264
264
|
jq --arg id "$resolvedId" --arg st "$newStatus" --arg ts "$ts" --arg ra "$recovery_action" \
|
|
265
|
-
'.issues = [.issues[] | if .id == $id then
|
|
265
|
+
'.issues = [(.issues // [])[] | if .id == $id then
|
|
266
266
|
.status = $st | .recovery_status = $ra | .updated_at = $ts
|
|
267
267
|
else . end]' \
|
|
268
268
|
"$issuesFile" > "$tmp" && mv "$tmp" "$issuesFile"
|
|
@@ -59,7 +59,7 @@ for f in "$MONITOR_DIR"/*.json; do
|
|
|
59
59
|
[ -f "$f" ] || continue
|
|
60
60
|
jq -r '
|
|
61
61
|
"[\(.name)] status=\(.status // "active") interval=\(.poll_interval)s agent=\(.agent_type)
|
|
62
|
-
sources: \([.sources[].type] | join(", "))
|
|
62
|
+
sources: \([(.sources // [])[].type] | join(", "))
|
|
63
63
|
last_tick: \(.last_tick // "never") tasks_done: \(.stats.done // 0) tasks_failed: \(.stats.failed // 0)"
|
|
64
64
|
' "$f"
|
|
65
65
|
echo ""
|
|
@@ -162,7 +162,7 @@ jq -r '
|
|
|
162
162
|
"Sources (\(.sources | length)):"
|
|
163
163
|
' "$cfg"
|
|
164
164
|
|
|
165
|
-
jq -r '.sources[] | " [\(.type)] \(.filter | to_entries | map("\(.key)=\(.value)") | join(" "))"' "$cfg"
|
|
165
|
+
jq -r '(.sources // [])[] | " [\(.type)] \(.filter | to_entries | map("\(.key)=\(.value)") | join(" "))"' "$cfg"
|
|
166
166
|
|
|
167
167
|
if [ -f "$state_file" ]; then
|
|
168
168
|
in_flight=$(jq '.in_flight // [] | length' "$state_file" 2>/dev/null || echo 0)
|
|
@@ -320,7 +320,7 @@ state_file="$MONITOR_DIR/${name}-state.json"
|
|
|
320
320
|
# Load config
|
|
321
321
|
[ ! -f "$cfg" ] && echo "Monitor '$name' not found — loop terminated." && exit 0
|
|
322
322
|
|
|
323
|
-
monitor_status=$(jq -r '.status' "$cfg")
|
|
323
|
+
monitor_status=$(jq -r '.status // "active"' "$cfg")
|
|
324
324
|
[ "$monitor_status" = "stopped" ] && echo "Monitor '$name' stopped — loop terminated." && exit 0
|
|
325
325
|
[ "$monitor_status" = "paused" ] && echo "Monitor '$name' paused — will not reschedule." && exit 0
|
|
326
326
|
|
|
@@ -353,7 +353,7 @@ If a previous task failed but has retry_count < 3, it remains in `in_flight` wit
|
|
|
353
353
|
|
|
354
354
|
```bash
|
|
355
355
|
retry_task=$(jq -c '
|
|
356
|
-
.in_flight[] as $t |
|
|
356
|
+
(.in_flight // [])[] as $t |
|
|
357
357
|
(.processed_ids[($t.source_type + ":" + $t.external_id)].status // "") |
|
|
358
358
|
if . == "retry_pending" then $t else empty end' "$state_file" | head -1)
|
|
359
359
|
```
|
|
@@ -405,7 +405,7 @@ if [ -z "$retry_task" ]; then
|
|
|
405
405
|
# === Linear adapter (below) ===
|
|
406
406
|
```
|
|
407
407
|
|
|
408
|
-
> The `case` block continues through all adapters. After the Filesystem adapter closes its inner loop and `fi`, add `esac` → `done < <(jq -c '.sources[]' "$cfg")` → `fi` (closing the `if [ -z "$retry_task" ]` guard). After the outer `fi`, check `$task_claimed` to decide whether to run the "After claim" section.
|
|
408
|
+
> The `case` block continues through all adapters. After the Filesystem adapter closes its inner loop and `fi`, add `esac` → `done < <(jq -c '(.sources // [])[]' "$cfg")` → `fi` (closing the `if [ -z "$retry_task" ]` guard). After the outer `fi`, check `$task_claimed` to decide whether to run the "After claim" section.
|
|
409
409
|
|
|
410
410
|
---
|
|
411
411
|
|
|
@@ -733,7 +733,7 @@ done <<< "$tasks" # close per-file while loop (reached only if no file was cla
|
|
|
733
733
|
fi # close 'if [ ! -d "$folder" ]' else block
|
|
734
734
|
;; # end filesystem case branch
|
|
735
735
|
esac
|
|
736
|
-
done < <(jq -c '.sources[]' "$cfg")
|
|
736
|
+
done < <(jq -c '(.sources // [])[]' "$cfg")
|
|
737
737
|
fi # close 'if [ -z "$retry_task" ]' guard
|
|
738
738
|
# After: if $task_claimed=true, proceed to "After claim"; otherwise skip to Step 5
|
|
739
739
|
```
|
|
@@ -950,7 +950,7 @@ jq --arg key "${task_source_type}:${task_external_id}" \
|
|
|
950
950
|
--arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
951
951
|
'(.processed_ids[$key].status = "done") |
|
|
952
952
|
(.processed_ids[$key].done_at = $ts) |
|
|
953
|
-
(.in_flight = [.in_flight[] | select(.external_id != $eid or .source_type != $stype)])' \
|
|
953
|
+
(.in_flight = [(.in_flight // [])[] | select(.external_id != $eid or .source_type != $stype)])' \
|
|
954
954
|
"$state_file" > "$tmp" && mv "$tmp" "$state_file"
|
|
955
955
|
|
|
956
956
|
tmp="${cfg}.tmp"
|
|
@@ -991,7 +991,7 @@ if [ "$retry_count" -lt 3 ]; then
|
|
|
991
991
|
'(.processed_ids[$key].retry_count = $r) |
|
|
992
992
|
(.processed_ids[$key].last_failure = $ts) |
|
|
993
993
|
(.processed_ids[$key].status = "retry_pending") |
|
|
994
|
-
(.in_flight = [.in_flight[] |
|
|
994
|
+
(.in_flight = [(.in_flight // [])[] |
|
|
995
995
|
if (.external_id == $eid and .source_type == $stype)
|
|
996
996
|
then .retry_count = $r | .last_failure = $ts
|
|
997
997
|
else . end])' \
|
|
@@ -1064,7 +1064,7 @@ Last attempt: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
|
1064
1064
|
--arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
1065
1065
|
'(.processed_ids[$key].status = "failed") |
|
|
1066
1066
|
(.processed_ids[$key].failed_at = $ts) |
|
|
1067
|
-
(.in_flight = [.in_flight[] | select(.external_id != $eid or .source_type != $stype)])' \
|
|
1067
|
+
(.in_flight = [(.in_flight // [])[] | select(.external_id != $eid or .source_type != $stype)])' \
|
|
1068
1068
|
"$state_file" > "$tmp" && mv "$tmp" "$state_file"
|
|
1069
1069
|
|
|
1070
1070
|
tmp="${cfg}.tmp"
|
|
@@ -1137,7 +1137,7 @@ If `caller` is not "command", follow `_protocol.md` Brain Write Procedure for do
|
|
|
1137
1137
|
{
|
|
1138
1138
|
"type": "github",
|
|
1139
1139
|
"filter": {
|
|
1140
|
-
"repo": "
|
|
1140
|
+
"repo": "monoes/monomind",
|
|
1141
1141
|
"assignee": "nokhodian",
|
|
1142
1142
|
"labels": ["ai-agent"],
|
|
1143
1143
|
"state": "open",
|
|
@@ -1214,7 +1214,7 @@ If `caller` is not "command", follow `_protocol.md` Brain Write Procedure for do
|
|
|
1214
1214
|
```bash
|
|
1215
1215
|
# Create a monitor watching GitHub issues assigned to you
|
|
1216
1216
|
/mastermind:monitor --action start --name dev-watcher \
|
|
1217
|
-
--source github --project
|
|
1217
|
+
--source github --project monoes/monomind --user nokhodian \
|
|
1218
1218
|
--label ai-agent --agent coder --interval 120
|
|
1219
1219
|
|
|
1220
1220
|
# Add a Linear source to an existing monitor
|
|
@@ -55,7 +55,7 @@ printf "%-24s %-12s %-10s %s\n" "ID" "STATUS" "PRIORITY" "TITLE"
|
|
|
55
55
|
echo "────────────────────────────────────────────────────────"
|
|
56
56
|
|
|
57
57
|
jq -r --arg uid "$assigneeFilter" --arg sf "$statusFilter" '
|
|
58
|
-
.issues[] |
|
|
58
|
+
(.issues // [])[] |
|
|
59
59
|
select(
|
|
60
60
|
(.assigneeId == $uid or .assigned_to == $uid) and
|
|
61
61
|
(if $sf == "active" then (.status == "open" or .status == "in_progress")
|
|
@@ -69,7 +69,7 @@ jq -r --arg uid "$assigneeFilter" --arg sf "$statusFilter" '
|
|
|
69
69
|
done
|
|
70
70
|
|
|
71
71
|
total=$(jq -r --arg uid "$assigneeFilter" \
|
|
72
|
-
'[.issues[] | select(.assigneeId == $uid or .assigned_to == $uid)] | length' \
|
|
72
|
+
'[(.issues // [])[] | select(.assigneeId == $uid or .assigned_to == $uid)] | length' \
|
|
73
73
|
"$issuesFile")
|
|
74
74
|
echo ""
|
|
75
75
|
echo "Total assigned: $total"
|
|
@@ -81,13 +81,13 @@ echo "Total assigned: $total"
|
|
|
81
81
|
```bash
|
|
82
82
|
[ -z "$issue_id" ] && { echo "ERROR: --issue-id required."; exit 1; }
|
|
83
83
|
|
|
84
|
-
exists=$(jq -r --arg id "$issue_id" '[.issues[] | select(.id == $id)] | length' "$issuesFile")
|
|
84
|
+
exists=$(jq -r --arg id "$issue_id" '[(.issues // [])[] | select(.id == $id)] | length' "$issuesFile")
|
|
85
85
|
[ "$exists" -eq 0 ] && { echo "ERROR: Issue '$issue_id' not found."; exit 1; }
|
|
86
86
|
|
|
87
87
|
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
88
88
|
tmp="${issuesFile}.tmp"
|
|
89
89
|
jq --arg id "$issue_id" --arg uid "$assigneeFilter" --arg ts "$ts" \
|
|
90
|
-
'.issues = [.issues[] | if .id == $id then
|
|
90
|
+
'.issues = [(.issues // [])[] | if .id == $id then
|
|
91
91
|
.assigneeId = $uid | .lastActivityAt = $ts
|
|
92
92
|
else . end]' \
|
|
93
93
|
"$issuesFile" > "$tmp" && mv "$tmp" "$issuesFile"
|
|
@@ -103,7 +103,7 @@ echo "Issue '$issue_id' assigned to '$assigneeFilter'."
|
|
|
103
103
|
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
104
104
|
tmp="${issuesFile}.tmp"
|
|
105
105
|
jq --arg id "$issue_id" --arg ts "$ts" \
|
|
106
|
-
'.issues = [.issues[] | if .id == $id then
|
|
106
|
+
'.issues = [(.issues // [])[] | if .id == $id then
|
|
107
107
|
.assigneeId = null | .lastActivityAt = $ts
|
|
108
108
|
else . end]' \
|
|
109
109
|
"$issuesFile" > "$tmp" && mv "$tmp" "$issuesFile"
|
|
@@ -119,7 +119,7 @@ echo "Issue '$issue_id' unassigned."
|
|
|
119
119
|
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
120
120
|
tmp="${issuesFile}.tmp"
|
|
121
121
|
jq --arg id "$issue_id" --arg ts "$ts" \
|
|
122
|
-
'.issues = [.issues[] | if .id == $id then
|
|
122
|
+
'.issues = [(.issues // [])[] | if .id == $id then
|
|
123
123
|
.status = "done" | .closedAt = $ts | .lastActivityAt = $ts
|
|
124
124
|
else . end]' \
|
|
125
125
|
"$issuesFile" > "$tmp" && mv "$tmp" "$issuesFile"
|
|
@@ -91,7 +91,7 @@ echo "CURRENT ROLES IN ORG: $org_name"
|
|
|
91
91
|
echo "────────────────────────────────────────────────────────"
|
|
92
92
|
printf "%-22s %-20s %-14s %s\n" "ID" "TITLE" "ADAPTER" "REPORTS TO"
|
|
93
93
|
echo "────────────────────────────────────────────────────────"
|
|
94
|
-
jq -r '.roles[] |
|
|
94
|
+
jq -r '(.roles // [])[] |
|
|
95
95
|
[.id, (.title // "-"), (.adapter.type // "claude-local"), (.reports_to // "(root)")] | @tsv' \
|
|
96
96
|
"$orgFile" | while IFS=$'\t' read -r id title adapter rt; do
|
|
97
97
|
printf "%-22s %-20s %-14s %s\n" "$id" "$title" "$adapter" "$rt"
|
|
@@ -165,13 +165,13 @@ if [ -z "$agent_id" ]; then
|
|
|
165
165
|
fi
|
|
166
166
|
|
|
167
167
|
# Check for duplicate id
|
|
168
|
-
duplicate=$(jq -r --arg id "$agent_id" '[.roles[] | select(.id == $id)] | length' "$orgFile")
|
|
168
|
+
duplicate=$(jq -r --arg id "$agent_id" '[(.roles // [])[] | select(.id == $id)] | length' "$orgFile")
|
|
169
169
|
[ "$duplicate" -gt 0 ] && { echo "ERROR: Agent id '$agent_id' already exists in org '$org_name'. Use --agent-id to specify a unique id."; exit 1; }
|
|
170
170
|
|
|
171
171
|
# Validate reports_to if set
|
|
172
172
|
if [ -n "$reports_to" ]; then
|
|
173
|
-
parentExists=$(jq -r --arg pid "$reports_to" '[.roles[] | select(.id == $pid)] | length' "$orgFile")
|
|
174
|
-
[ "$parentExists" -eq 0 ] && echo "
|
|
173
|
+
parentExists=$(jq -r --arg pid "$reports_to" '[(.roles // [])[] | select(.id == $pid)] | length' "$orgFile")
|
|
174
|
+
[ "$parentExists" -eq 0 ] && { echo "ERROR: Parent agent '$reports_to' not found in org '${org_name}'. Check the agent ID with /mastermind:org-chart --org ${org_name}."; exit 1; }
|
|
175
175
|
fi
|
|
176
176
|
|
|
177
177
|
# Build skills array
|
|
@@ -97,9 +97,9 @@ def render(nodes, prefix="", depth=0):
|
|
|
97
97
|
child_prefix = prefix + (" " if is_last else "│ ")
|
|
98
98
|
rid = r.get("id", "?")
|
|
99
99
|
title = r.get("title", rid)
|
|
100
|
-
adapter = r.get("adapter", {})
|
|
101
|
-
atype = adapter.get("type", "?") if isinstance(adapter, dict) else str(adapter)
|
|
100
|
+
adapter = r.get("adapter_config", r.get("adapter", {}))
|
|
102
101
|
model = adapter.get("model", "") if isinstance(adapter, dict) else ""
|
|
102
|
+
atype = model.split("-")[0] if model else "?"
|
|
103
103
|
hb_status = "♡" if rid not in hb or not hb[rid] else "♥"
|
|
104
104
|
gov = r.get("governance") or ""
|
|
105
105
|
gov_str = f" [{gov}]" if gov else ""
|
|
@@ -135,7 +135,8 @@ printf "%-24s %-20s %-16s %-20s %s\n" "ID" "TITLE" "ADAPTER" "MODEL" "REPORTS TO
|
|
|
135
135
|
echo "────────────────────────────────────────────────────────"
|
|
136
136
|
|
|
137
137
|
echo "$roles" | jq -r '.[] |
|
|
138
|
-
|
|
138
|
+
(((.adapter_config.model // .adapter.model) // "") | split("-") | .[0] | if . == "" then "?" else . end) as $atype |
|
|
139
|
+
[.id, (.title // "-"), $atype, ((.adapter_config.model // .adapter.model) // "-"),
|
|
139
140
|
(.reports_to // "(root)")] | @tsv' | \
|
|
140
141
|
while IFS=$'\t' read -r id title adapter model rt; do
|
|
141
142
|
printf "%-24s %-20s %-16s %-20s %s\n" "$id" "$title" "$adapter" "$model" "$rt"
|
|
@@ -157,13 +158,14 @@ echo "────────────────────────
|
|
|
157
158
|
|
|
158
159
|
ql=$(echo "$query" | tr '[:upper:]' '[:lower:]')
|
|
159
160
|
echo "$roles" | jq -r --arg q "$ql" '.[] |
|
|
161
|
+
(((.adapter_config.model // .adapter.model) // "") | split("-") | .[0] | if . == "" then "?" else . end) as $atype |
|
|
160
162
|
select(
|
|
161
163
|
(.id | ascii_downcase | contains($q)) or
|
|
162
164
|
(.title // "" | ascii_downcase | contains($q)) or
|
|
163
|
-
(.adapter.
|
|
164
|
-
(.
|
|
165
|
+
((.adapter_config.model // .adapter.model) // "" | ascii_downcase | contains($q)) or
|
|
166
|
+
(.agent_type // "" | ascii_downcase | contains($q))
|
|
165
167
|
) |
|
|
166
|
-
[.id, (.title // "-"),
|
|
168
|
+
[.id, (.title // "-"), $atype, (.reports_to // "(root)")] | @tsv' | \
|
|
167
169
|
while IFS=$'\t' read -r id title adapter rt; do
|
|
168
170
|
printf "%-24s %-20s %-16s %s\n" "$id" "$title" "$adapter" "$rt"
|
|
169
171
|
done
|
|
@@ -75,8 +75,30 @@ tmp="${orgFile}.tmp"
|
|
|
75
75
|
|
|
76
76
|
case "$field" in
|
|
77
77
|
name)
|
|
78
|
+
# Validate new name slug
|
|
79
|
+
echo "$value" | grep -qE '^[a-z0-9][a-z0-9-]{0,63}$' || { echo "ERROR: name must match ^[a-z0-9][a-z0-9-]{0,63}$"; exit 1; }
|
|
80
|
+
newOrgFile=".monomind/orgs/${value}.json"
|
|
81
|
+
[ -f "$newOrgFile" ] && { echo "ERROR: An org named '${value}' already exists."; exit 1; }
|
|
82
|
+
# Update the name field inside the JSON
|
|
78
83
|
jq --arg v "$value" '.name = $v' "$orgFile" > "$tmp" && mv "$tmp" "$orgFile"
|
|
79
|
-
|
|
84
|
+
# Rename the main config file
|
|
85
|
+
mv "$orgFile" "$newOrgFile"
|
|
86
|
+
# Rename all side-car data files
|
|
87
|
+
for suffix in -state -goals -routines -approvals -activity -issues -members -projects -workspaces -worktrees -environments -plugins -adapters -threads -budgets -project-workspaces -approval-comments -bootstrap -secrets; do
|
|
88
|
+
old_file=".monomind/orgs/${org_name}${suffix}.json"
|
|
89
|
+
[ -f "$old_file" ] && mv "$old_file" ".monomind/orgs/${value}${suffix}.json" || true
|
|
90
|
+
old_jsonl=".monomind/orgs/${org_name}${suffix}.jsonl"
|
|
91
|
+
[ -f "$old_jsonl" ] && mv "$old_jsonl" ".monomind/orgs/${value}${suffix}.jsonl" || true
|
|
92
|
+
done
|
|
93
|
+
# Rename loop prompt file if present (scheduled orgs)
|
|
94
|
+
old_loop=".monomind/loops/${org_name}.md"
|
|
95
|
+
[ -f "$old_loop" ] && mv "$old_loop" ".monomind/loops/${value}.md" || true
|
|
96
|
+
# Rename stop file if present
|
|
97
|
+
old_stop=".monomind/orgs/.stops/${org_name}.stop"
|
|
98
|
+
[ -f "$old_stop" ] && mv "$old_stop" ".monomind/orgs/.stops/${value}.stop" || true
|
|
99
|
+
echo "Renamed org '${org_name}' → '${value}'"
|
|
100
|
+
org_name="$value"
|
|
101
|
+
orgFile="$newOrgFile"
|
|
80
102
|
;;
|
|
81
103
|
goal)
|
|
82
104
|
jq --arg v "$value" '.goal = $v' "$orgFile" > "$tmp" && mv "$tmp" "$orgFile"
|
|
@@ -143,19 +165,24 @@ mkdir -p ".monomind/exports"
|
|
|
143
165
|
timestamp=$(date +%Y%m%d-%H%M%S)
|
|
144
166
|
outPath="${export_path:-.monomind/exports/${org_name}-${timestamp}.json}"
|
|
145
167
|
|
|
168
|
+
# Pre-read optional side-car files (--slurpfile aborts jq when the file is missing)
|
|
169
|
+
goals_json=$([ -f ".monomind/orgs/${org_name}-goals.json" ] && jq -c '.' ".monomind/orgs/${org_name}-goals.json" || echo 'null')
|
|
170
|
+
routines_json=$([ -f ".monomind/orgs/${org_name}-routines.json" ] && jq -c '.' ".monomind/orgs/${org_name}-routines.json" || echo 'null')
|
|
171
|
+
projects_json=$([ -f ".monomind/orgs/${org_name}-projects.json" ] && jq -c '.' ".monomind/orgs/${org_name}-projects.json" || echo 'null')
|
|
172
|
+
|
|
146
173
|
# Merge all org data files into one export bundle
|
|
147
174
|
jq -n \
|
|
148
175
|
--slurpfile config "$orgFile" \
|
|
149
|
-
--
|
|
150
|
-
--
|
|
151
|
-
--
|
|
176
|
+
--argjson goals "$goals_json" \
|
|
177
|
+
--argjson routines "$routines_json" \
|
|
178
|
+
--argjson projects "$projects_json" \
|
|
152
179
|
'{
|
|
153
180
|
exported_at: (now|todate),
|
|
154
181
|
format_version: "1.0",
|
|
155
182
|
config: ($config[0] // {}),
|
|
156
|
-
goals: ($goals
|
|
157
|
-
routines: ($routines
|
|
158
|
-
projects: ($projects
|
|
183
|
+
goals: ($goals.goals // []),
|
|
184
|
+
routines: ($routines.routines // []),
|
|
185
|
+
projects: ($projects.projects // [])
|
|
159
186
|
}' > "$outPath"
|
|
160
187
|
|
|
161
188
|
echo "Exported: $outPath"
|
|
@@ -178,20 +205,30 @@ importedName=$(jq -r '.config.name // .config.org_name // "unnamed"' "$import_pa
|
|
|
178
205
|
targetOrg="${org_name:-$importedName}"
|
|
179
206
|
mkdir -p ".monomind/orgs"
|
|
180
207
|
|
|
181
|
-
# Write config
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
# Write
|
|
193
|
-
|
|
194
|
-
[ "$
|
|
208
|
+
# Write config — update the name field to match targetOrg (in case file was exported under a different name)
|
|
209
|
+
tmpConfig=".monomind/orgs/${targetOrg}.json.tmp"
|
|
210
|
+
jq --arg n "$targetOrg" '.config | .name = $n' "$import_path" > "$tmpConfig" && mv "$tmpConfig" ".monomind/orgs/${targetOrg}.json" || { rm -f "$tmpConfig"; echo "ERROR: Failed to write org config from import."; exit 1; }
|
|
211
|
+
|
|
212
|
+
# Write goals if present (atomic write)
|
|
213
|
+
goalsData=$(jq -c '.goals // []' "$import_path" 2>/dev/null || echo '[]')
|
|
214
|
+
if [ "$goalsData" != "[]" ]; then
|
|
215
|
+
tmp=".monomind/orgs/${targetOrg}-goals.json.tmp"
|
|
216
|
+
jq -n --argjson data "$goalsData" '{"goals":$data}' > "$tmp" && mv "$tmp" ".monomind/orgs/${targetOrg}-goals.json" || rm -f "$tmp"
|
|
217
|
+
fi
|
|
218
|
+
|
|
219
|
+
# Write routines if present (atomic write)
|
|
220
|
+
routinesData=$(jq -c '.routines // []' "$import_path" 2>/dev/null || echo '[]')
|
|
221
|
+
if [ "$routinesData" != "[]" ]; then
|
|
222
|
+
tmp=".monomind/orgs/${targetOrg}-routines.json.tmp"
|
|
223
|
+
jq -n --argjson data "$routinesData" '{"routines":$data}' > "$tmp" && mv "$tmp" ".monomind/orgs/${targetOrg}-routines.json" || rm -f "$tmp"
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
# Write projects if present (atomic write)
|
|
227
|
+
projectsData=$(jq -c '.projects // []' "$import_path" 2>/dev/null || echo '[]')
|
|
228
|
+
if [ "$projectsData" != "[]" ]; then
|
|
229
|
+
tmp=".monomind/orgs/${targetOrg}-projects.json.tmp"
|
|
230
|
+
jq -n --argjson data "$projectsData" '{"projects":$data}' > "$tmp" && mv "$tmp" ".monomind/orgs/${targetOrg}-projects.json" || rm -f "$tmp"
|
|
231
|
+
fi
|
|
195
232
|
|
|
196
233
|
echo "Imported org '${targetOrg}' from ${import_path}"
|
|
197
234
|
echo "Agents: $(jq '.config.roles | length' "$import_path")"
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mastermind-orgs
|
|
3
|
+
description: Mastermind orgs — list all saved orgs with their status, schedule, and last/next run times. Shows stopped/active/paused state for scheduled orgs.
|
|
4
|
+
type: domain-skill
|
|
5
|
+
default_mode: auto
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Mastermind Orgs
|
|
9
|
+
|
|
10
|
+
This skill is invoked by `mastermind:orgs` or directly via `/mastermind:orgs`.
|
|
11
|
+
|
|
12
|
+
Lists all saved orgs from `.monomind/orgs/*.json`.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Inputs
|
|
17
|
+
|
|
18
|
+
- `caller`: command | master (controls whether brain load runs here)
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Step 0 — Brain Load (standalone only)
|
|
23
|
+
|
|
24
|
+
If `caller` is not "command", load brain context following _protocol.md Brain Load Procedure with namespace: `ops`.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Step 1 — List Orgs
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
orgsDir=".monomind/orgs"
|
|
32
|
+
orgFiles=$(ls "$orgsDir"/*.json 2>/dev/null | grep -vE -- '-approvals|-state|-activity|-goals|-routines|-projects|-members|-issues|-workspaces|-worktrees|-environments|-plugins|-adapters|-bootstrap|-threads|-budgets|-project-workspaces|-approval-comments')
|
|
33
|
+
|
|
34
|
+
if [ -z "$orgFiles" ]; then
|
|
35
|
+
echo "No saved orgs found."
|
|
36
|
+
echo "Create one: /mastermind:createorg <goal>"
|
|
37
|
+
exit 0
|
|
38
|
+
fi
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Step 2 — Render Org Table
|
|
44
|
+
|
|
45
|
+
For each org file (skip state/approvals files), extract and display:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
echo ""
|
|
49
|
+
printf "%-28s %-10s %-12s %-22s %-22s\n" "ORG" "STATUS" "SCHEDULE" "LAST RUN" "NEXT RUN"
|
|
50
|
+
printf "%-28s %-10s %-12s %-22s %-22s\n" "---" "------" "--------" "--------" "--------"
|
|
51
|
+
|
|
52
|
+
for f in $orgFiles; do
|
|
53
|
+
name=$(jq -r '.name // "(unnamed)"' "$f" 2>/dev/null)
|
|
54
|
+
goal=$(jq -r '.goal // ""' "$f" 2>/dev/null | cut -c1-55)
|
|
55
|
+
status=$(jq -r '.status // "—"' "$f" 2>/dev/null)
|
|
56
|
+
interval=$(jq -r 'if .loop.poll_interval_minutes then "\(.loop.poll_interval_minutes)m" else "manual" end' "$f" 2>/dev/null)
|
|
57
|
+
last_run=$(jq -r '.loop.last_run // "—"' "$f" 2>/dev/null | sed 's/T/ /;s/Z//')
|
|
58
|
+
next_run=$(jq -r '.loop.next_run // "—"' "$f" 2>/dev/null | sed 's/T/ /;s/Z//')
|
|
59
|
+
|
|
60
|
+
# Status indicator — distinguish non-scheduled (manual) from scheduled loop states
|
|
61
|
+
if [ "$interval" = "manual" ]; then
|
|
62
|
+
indicator="■ persistent"
|
|
63
|
+
else
|
|
64
|
+
case "$status" in
|
|
65
|
+
active) indicator="● active" ;;
|
|
66
|
+
stopped) indicator="○ stopped" ;;
|
|
67
|
+
paused) indicator="⏸ paused" ;;
|
|
68
|
+
*) indicator="— unknown" ;;
|
|
69
|
+
esac
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
printf "%-28s %-10s %-12s %-22s %-22s\n" "$name" "$indicator" "$interval" "$last_run" "$next_run"
|
|
73
|
+
echo " └ $goal"
|
|
74
|
+
echo ""
|
|
75
|
+
done
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Step 3 — Show Summary and Commands
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
COMMANDS
|
|
84
|
+
────────
|
|
85
|
+
/mastermind:orgstatus --org <name> Detailed status, last runs, activity
|
|
86
|
+
/mastermind:runorg --org <name> Start (or restart) a scheduled org
|
|
87
|
+
/mastermind:stoporg --org <name> Stop a running scheduled org
|
|
88
|
+
/mastermind:createorg <goal> Create a new org
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Step 4 — Return Output
|
|
94
|
+
|
|
95
|
+
```yaml
|
|
96
|
+
domain: ops
|
|
97
|
+
status: complete
|
|
98
|
+
```
|