@nforma.ai/nforma 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +1024 -0
  3. package/agents/qgsd-codebase-mapper.md +764 -0
  4. package/agents/qgsd-debugger.md +1201 -0
  5. package/agents/qgsd-executor.md +472 -0
  6. package/agents/qgsd-integration-checker.md +443 -0
  7. package/agents/qgsd-phase-researcher.md +502 -0
  8. package/agents/qgsd-plan-checker.md +643 -0
  9. package/agents/qgsd-planner.md +1182 -0
  10. package/agents/qgsd-project-researcher.md +621 -0
  11. package/agents/qgsd-quorum-orchestrator.md +628 -0
  12. package/agents/qgsd-quorum-slot-worker.md +41 -0
  13. package/agents/qgsd-quorum-synthesizer.md +133 -0
  14. package/agents/qgsd-quorum-test-worker.md +37 -0
  15. package/agents/qgsd-quorum-worker.md +161 -0
  16. package/agents/qgsd-research-synthesizer.md +239 -0
  17. package/agents/qgsd-roadmapper.md +660 -0
  18. package/agents/qgsd-verifier.md +628 -0
  19. package/bin/accept-debug-invariant.cjs +165 -0
  20. package/bin/account-manager.cjs +719 -0
  21. package/bin/aggregate-requirements.cjs +466 -0
  22. package/bin/analyze-assumptions.cjs +757 -0
  23. package/bin/analyze-state-space.cjs +921 -0
  24. package/bin/attribute-trace-divergence.cjs +150 -0
  25. package/bin/auth-drivers/gh-cli.cjs +93 -0
  26. package/bin/auth-drivers/index.cjs +46 -0
  27. package/bin/auth-drivers/pool.cjs +67 -0
  28. package/bin/auth-drivers/simple.cjs +95 -0
  29. package/bin/autoClosePtoF.cjs +110 -0
  30. package/bin/blessed-terminal.cjs +350 -0
  31. package/bin/build-phase-index.cjs +472 -0
  32. package/bin/call-quorum-slot.cjs +541 -0
  33. package/bin/ccr-secure-config.cjs +99 -0
  34. package/bin/ccr-secure-start.cjs +83 -0
  35. package/bin/check-bundled-sdks.cjs +177 -0
  36. package/bin/check-coverage-guard.cjs +112 -0
  37. package/bin/check-liveness-fairness.cjs +95 -0
  38. package/bin/check-mcp-health.cjs +123 -0
  39. package/bin/check-provider-health.cjs +395 -0
  40. package/bin/check-results-exit.cjs +24 -0
  41. package/bin/check-spec-sync.cjs +360 -0
  42. package/bin/check-trace-redaction.cjs +271 -0
  43. package/bin/check-trace-schema-drift.cjs +99 -0
  44. package/bin/compareDrift.cjs +21 -0
  45. package/bin/conformance-schema.cjs +12 -0
  46. package/bin/count-scenarios.cjs +420 -0
  47. package/bin/debt-dedup.cjs +144 -0
  48. package/bin/debt-ledger.cjs +61 -0
  49. package/bin/debt-retention.cjs +76 -0
  50. package/bin/debt-state-machine.cjs +80 -0
  51. package/bin/detect-coverage-gaps.cjs +204 -0
  52. package/bin/detect-project-intent.cjs +362 -0
  53. package/bin/export-prism-constants.cjs +164 -0
  54. package/bin/extract-annotations.cjs +633 -0
  55. package/bin/extractFormalExpected.cjs +104 -0
  56. package/bin/fingerprint-drift.cjs +24 -0
  57. package/bin/fingerprint-issue.cjs +46 -0
  58. package/bin/formal-core.cjs +519 -0
  59. package/bin/formal-ref-linker.cjs +141 -0
  60. package/bin/formal-test-sync.cjs +788 -0
  61. package/bin/generate-formal-specs.cjs +588 -0
  62. package/bin/generate-petri-net.cjs +397 -0
  63. package/bin/generate-phase-spec.cjs +249 -0
  64. package/bin/generate-proposed-changes.cjs +194 -0
  65. package/bin/generate-tla-cfg.cjs +122 -0
  66. package/bin/generate-traceability-matrix.cjs +701 -0
  67. package/bin/generate-triage-bundle.cjs +300 -0
  68. package/bin/gh-account-rotate.cjs +34 -0
  69. package/bin/initialize-model-registry.cjs +105 -0
  70. package/bin/install-formal-tools.cjs +382 -0
  71. package/bin/install.js +2424 -0
  72. package/bin/isNumericThreshold.cjs +34 -0
  73. package/bin/issue-classifier.cjs +151 -0
  74. package/bin/levenshtein.cjs +74 -0
  75. package/bin/lint-formal-models.cjs +580 -0
  76. package/bin/load-baseline-requirements.cjs +275 -0
  77. package/bin/manage-agents-core.cjs +815 -0
  78. package/bin/migrate-formal-dir.cjs +172 -0
  79. package/bin/migrate-planning.cjs +206 -0
  80. package/bin/migrate-to-slots.cjs +255 -0
  81. package/bin/nForma.cjs +2726 -0
  82. package/bin/observe-config.cjs +353 -0
  83. package/bin/observe-debt-writer.cjs +140 -0
  84. package/bin/observe-handler-grafana.cjs +128 -0
  85. package/bin/observe-handler-internal.cjs +301 -0
  86. package/bin/observe-handler-logstash.cjs +153 -0
  87. package/bin/observe-handler-prometheus.cjs +185 -0
  88. package/bin/observe-handlers.cjs +436 -0
  89. package/bin/observe-registry.cjs +131 -0
  90. package/bin/observe-render.cjs +168 -0
  91. package/bin/planning-paths.cjs +167 -0
  92. package/bin/polyrepo.cjs +560 -0
  93. package/bin/prism-priority.cjs +153 -0
  94. package/bin/probe-quorum-slots.cjs +167 -0
  95. package/bin/promote-model.cjs +225 -0
  96. package/bin/propose-debug-invariants.cjs +165 -0
  97. package/bin/providers.json +392 -0
  98. package/bin/pty-proxy.py +129 -0
  99. package/bin/qgsd-solve.cjs +2477 -0
  100. package/bin/quorum-consensus-gate.cjs +238 -0
  101. package/bin/quorum-formal-context.cjs +183 -0
  102. package/bin/quorum-slot-dispatch.cjs +934 -0
  103. package/bin/read-policy.cjs +60 -0
  104. package/bin/requirement-map.cjs +63 -0
  105. package/bin/requirements-core.cjs +247 -0
  106. package/bin/resolve-cli.cjs +101 -0
  107. package/bin/review-mcp-logs.cjs +294 -0
  108. package/bin/run-account-manager-tlc.cjs +188 -0
  109. package/bin/run-account-pool-alloy.cjs +158 -0
  110. package/bin/run-alloy.cjs +153 -0
  111. package/bin/run-audit-alloy.cjs +187 -0
  112. package/bin/run-breaker-tlc.cjs +181 -0
  113. package/bin/run-formal-check.cjs +395 -0
  114. package/bin/run-formal-verify.cjs +701 -0
  115. package/bin/run-installer-alloy.cjs +188 -0
  116. package/bin/run-oauth-rotation-prism.cjs +132 -0
  117. package/bin/run-oscillation-tlc.cjs +202 -0
  118. package/bin/run-phase-tlc.cjs +228 -0
  119. package/bin/run-prism.cjs +446 -0
  120. package/bin/run-protocol-tlc.cjs +201 -0
  121. package/bin/run-quorum-composition-alloy.cjs +155 -0
  122. package/bin/run-sensitivity-sweep.cjs +231 -0
  123. package/bin/run-stop-hook-tlc.cjs +188 -0
  124. package/bin/run-tlc.cjs +467 -0
  125. package/bin/run-transcript-alloy.cjs +173 -0
  126. package/bin/run-uppaal.cjs +264 -0
  127. package/bin/secrets.cjs +134 -0
  128. package/bin/sensitivity-report.cjs +219 -0
  129. package/bin/sensitivity-sweep-feedback.cjs +194 -0
  130. package/bin/set-secret.cjs +29 -0
  131. package/bin/setup-telemetry-cron.sh +36 -0
  132. package/bin/sweepPtoF.cjs +63 -0
  133. package/bin/sync-baseline-requirements.cjs +290 -0
  134. package/bin/task-envelope.cjs +360 -0
  135. package/bin/telemetry-collector.cjs +229 -0
  136. package/bin/unified-mcp-server.mjs +735 -0
  137. package/bin/update-agents.cjs +369 -0
  138. package/bin/update-scoreboard.cjs +1134 -0
  139. package/bin/validate-debt-entry.cjs +207 -0
  140. package/bin/validate-invariant.cjs +419 -0
  141. package/bin/validate-memory.cjs +389 -0
  142. package/bin/validate-requirements-haiku.cjs +435 -0
  143. package/bin/validate-traces.cjs +438 -0
  144. package/bin/verify-formal-results.cjs +124 -0
  145. package/bin/verify-quorum-health.cjs +273 -0
  146. package/bin/write-check-result.cjs +106 -0
  147. package/bin/xstate-to-tla.cjs +483 -0
  148. package/bin/xstate-trace-walker.cjs +205 -0
  149. package/commands/qgsd/add-phase.md +43 -0
  150. package/commands/qgsd/add-requirement.md +24 -0
  151. package/commands/qgsd/add-todo.md +47 -0
  152. package/commands/qgsd/audit-milestone.md +37 -0
  153. package/commands/qgsd/check-todos.md +45 -0
  154. package/commands/qgsd/cleanup.md +18 -0
  155. package/commands/qgsd/close-formal-gaps.md +33 -0
  156. package/commands/qgsd/complete-milestone.md +136 -0
  157. package/commands/qgsd/debug.md +166 -0
  158. package/commands/qgsd/discuss-phase.md +83 -0
  159. package/commands/qgsd/execute-phase.md +117 -0
  160. package/commands/qgsd/fix-tests.md +27 -0
  161. package/commands/qgsd/formal-test-sync.md +32 -0
  162. package/commands/qgsd/health.md +22 -0
  163. package/commands/qgsd/help.md +22 -0
  164. package/commands/qgsd/insert-phase.md +32 -0
  165. package/commands/qgsd/join-discord.md +18 -0
  166. package/commands/qgsd/list-phase-assumptions.md +46 -0
  167. package/commands/qgsd/map-codebase.md +71 -0
  168. package/commands/qgsd/map-requirements.md +20 -0
  169. package/commands/qgsd/mcp-restart.md +176 -0
  170. package/commands/qgsd/mcp-set-model.md +134 -0
  171. package/commands/qgsd/mcp-setup.md +1371 -0
  172. package/commands/qgsd/mcp-status.md +274 -0
  173. package/commands/qgsd/mcp-update.md +238 -0
  174. package/commands/qgsd/new-milestone.md +44 -0
  175. package/commands/qgsd/new-project.md +42 -0
  176. package/commands/qgsd/observe.md +260 -0
  177. package/commands/qgsd/pause-work.md +38 -0
  178. package/commands/qgsd/plan-milestone-gaps.md +34 -0
  179. package/commands/qgsd/plan-phase.md +44 -0
  180. package/commands/qgsd/polyrepo.md +50 -0
  181. package/commands/qgsd/progress.md +24 -0
  182. package/commands/qgsd/queue.md +54 -0
  183. package/commands/qgsd/quick.md +133 -0
  184. package/commands/qgsd/quorum-test.md +275 -0
  185. package/commands/qgsd/quorum.md +707 -0
  186. package/commands/qgsd/reapply-patches.md +110 -0
  187. package/commands/qgsd/remove-phase.md +31 -0
  188. package/commands/qgsd/research-phase.md +189 -0
  189. package/commands/qgsd/resume-work.md +40 -0
  190. package/commands/qgsd/set-profile.md +34 -0
  191. package/commands/qgsd/settings.md +39 -0
  192. package/commands/qgsd/solve.md +565 -0
  193. package/commands/qgsd/sync-baselines.md +119 -0
  194. package/commands/qgsd/triage.md +233 -0
  195. package/commands/qgsd/update.md +37 -0
  196. package/commands/qgsd/verify-work.md +38 -0
  197. package/hooks/dist/config-loader.js +297 -0
  198. package/hooks/dist/conformance-schema.cjs +12 -0
  199. package/hooks/dist/gsd-context-monitor.js +64 -0
  200. package/hooks/dist/qgsd-check-update.js +62 -0
  201. package/hooks/dist/qgsd-circuit-breaker.js +682 -0
  202. package/hooks/dist/qgsd-precompact.js +156 -0
  203. package/hooks/dist/qgsd-prompt.js +653 -0
  204. package/hooks/dist/qgsd-session-start.js +122 -0
  205. package/hooks/dist/qgsd-slot-correlator.js +58 -0
  206. package/hooks/dist/qgsd-spec-regen.js +86 -0
  207. package/hooks/dist/qgsd-statusline.js +91 -0
  208. package/hooks/dist/qgsd-stop.js +553 -0
  209. package/hooks/dist/qgsd-token-collector.js +133 -0
  210. package/hooks/dist/unified-mcp-server.mjs +669 -0
  211. package/package.json +95 -0
  212. package/scripts/build-hooks.js +46 -0
  213. package/scripts/postinstall.js +48 -0
  214. package/scripts/secret-audit.sh +45 -0
  215. package/templates/qgsd.json +49 -0
@@ -0,0 +1,274 @@
1
+ ---
2
+ name: qgsd:mcp-status
3
+ description: Show status of all connected quorum agents — provider, model, health, and latency
4
+ allowed-tools:
5
+ - Read
6
+ - Bash
7
+ - Task
8
+ - mcp__codex-1__identity
9
+ - mcp__gemini-1__identity
10
+ - mcp__opencode-1__identity
11
+ - mcp__copilot-1__identity
12
+ - mcp__claude-1__identity
13
+ - mcp__claude-2__identity
14
+ - mcp__claude-3__identity
15
+ - mcp__claude-4__identity
16
+ - mcp__claude-5__identity
17
+ - mcp__claude-6__identity
18
+ - mcp__claude-1__health_check
19
+ - mcp__claude-2__health_check
20
+ - mcp__claude-3__health_check
21
+ - mcp__claude-4__health_check
22
+ - mcp__claude-5__health_check
23
+ - mcp__claude-6__health_check
24
+ - mcp__codex-1__health_check
25
+ - mcp__gemini-1__health_check
26
+ - mcp__opencode-1__health_check
27
+ - mcp__copilot-1__health_check
28
+ ---
29
+
30
+ <objective>
31
+ Display a clean status table of all connected MCP quorum agents plus the Claude orchestrator. For CLI agents (codex-1, gemini-1, opencode-1, copilot-1): call their identity tool and health_check for real model names and latency. For HTTP agents (claude-1..6): call their identity tool then health_check for real-time endpoint health. Read provider URLs from ~/.claude.json. Show a claude orchestrator row at the top of the table.
32
+
33
+ This command is read-only (observation only). It does NOT invoke quorum and is NOT in quorum_commands.
34
+ </objective>
35
+
36
+ <process>
37
+
38
+ > **IMPORTANT: Run every Bash call in this workflow sequentially (one at a time). Never issue two Bash calls in parallel. A failure in one parallel sibling cancels all other parallel siblings — sequential execution isolates failures. For each numbered step below: run this Bash command alone, wait for its full output, store the result, then proceed to the next step.**
39
+
40
+ ## Step 1: Read scoreboard + provider URLs (run this Bash command first, wait for output before proceeding to Step 2)
41
+
42
+ Run the following Bash command and store the output as INIT_INFO:
43
+
44
+ ```bash
45
+ node << 'EOF'
46
+ const fs=require('fs'), path=require('path'), os=require('os');
47
+
48
+ // Scoreboard
49
+ const sbPath=path.join(process.cwd(),'.planning','quorum-scoreboard.json');
50
+ let totalRounds=0, lastUpdate=null;
51
+ if(fs.existsSync(sbPath)){
52
+ const d=JSON.parse(fs.readFileSync(sbPath,'utf8'));
53
+ totalRounds=(d.rounds||[]).length;
54
+ lastUpdate=d.team?.captured_at||null;
55
+ }
56
+
57
+ // Provider URLs from ~/.claude.json
58
+ const URL_MAP={
59
+ 'https://api.akashml.com/v1': 'AkashML',
60
+ 'https://api.together.xyz/v1': 'Together.xyz',
61
+ 'https://api.fireworks.ai/inference/v1':'Fireworks',
62
+ };
63
+ const cfgPath=path.join(os.homedir(),'.claude.json');
64
+ const providers={};
65
+ if(fs.existsSync(cfgPath)){
66
+ const cfg=JSON.parse(fs.readFileSync(cfgPath,'utf8'));
67
+ for(const [key,val] of Object.entries(cfg.mcpServers||{})){
68
+ const url=(val.env||{}).ANTHROPIC_BASE_URL||null;
69
+ providers[key]=url?URL_MAP[url]||url:null;
70
+ }
71
+ }
72
+
73
+ // Claude orchestrator model from ~/.claude/settings.json
74
+ const claudeSettingsPath=path.join(os.homedir(),'.claude','settings.json');
75
+ let claudeModel='claude-sonnet-4-6'; // default
76
+ if(fs.existsSync(claudeSettingsPath)){
77
+ try {
78
+ const cs=JSON.parse(fs.readFileSync(claudeSettingsPath,'utf8'));
79
+ const raw=(cs.model||'sonnet').toLowerCase();
80
+ if(raw.includes('opus')) claudeModel='claude-opus-4-6';
81
+ else if(raw.includes('haiku')) claudeModel='claude-haiku-4-5-20251001';
82
+ else claudeModel='claude-sonnet-4-6';
83
+ } catch(_){}
84
+ }
85
+
86
+ // Claude orchestrator auth type — oauthAccount present = subscription (sub), absent = API key (api)
87
+ let claudeAuth='api'; // default: API key
88
+ if(fs.existsSync(cfgPath)){
89
+ try {
90
+ const cfg=JSON.parse(fs.readFileSync(cfgPath,'utf8'));
91
+ if(cfg.oauthAccount && typeof cfg.oauthAccount==='object') claudeAuth='sub';
92
+ } catch(_){}
93
+ }
94
+
95
+ console.log(JSON.stringify({totalRounds,lastUpdate,providers,claudeModel,claudeAuth}));
96
+ EOF
97
+ ```
98
+
99
+ Parse `totalRounds`, `lastUpdate`, `providers` (map of slot → provider name or null), `claudeModel`, and `claudeAuth`.
100
+
101
+ **Provider for CLI agents** — prefer `identity.display_provider` when present. If absent, infer from model name:
102
+ - `gpt-*` or `o[0-9]*` → OpenAI
103
+ - `gemini-*` → Google
104
+ - `claude-*` → Anthropic
105
+ - `opencode*` or `grok*` → OpenCode
106
+ - default → —
107
+
108
+ **Auth type** — read from identity response `auth_type` field if present. If absent, infer:
109
+ - CLI agents (codex-1, gemini-1, opencode-1, copilot-1) → `sub` (subscription — flat fee, no per-token cost)
110
+ - HTTP agents (claude-1..6) → `api` (API token — pay per request)
111
+
112
+ Display as `sub` or `api` in the Auth column.
113
+
114
+ ## Step 2: Display banner (run this Bash command second, after Step 1 output is stored; wait for output before proceeding to Step 3)
115
+
116
+ Print:
117
+ ```
118
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
119
+ QGSD ► MCP STATUS
120
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
121
+
122
+ Querying 4 CLI agents + 6 HTTP providers...
123
+ ```
124
+
125
+ ## Step 3: Collect identity + health_check results via sub-agent (run after Step 2 output is stored)
126
+
127
+ Invoke a Task() sub-agent to call all MCP tools. This prevents raw tool-result blocks from appearing in the main conversation.
128
+
129
+ ```
130
+ Task(
131
+ subagent_type: "general-purpose",
132
+ model: "claude-haiku-4-5",
133
+ prompt: """
134
+ You are a data-collection sub-agent. Your only job is to call the MCP tools listed below and return their results as a single JSON object. Do not explain or summarize — return only the JSON object.
135
+
136
+ Call each tool with {} as input. Wrap every call in try/catch — if a tool throws or is unavailable, record null for that field.
137
+
138
+ Tools to call in this order (call them one at a time, sequentially — never parallel):
139
+
140
+ 1. mcp__codex-1__identity — store result as codex_id
141
+ 2. mcp__gemini-1__identity — store result as gemini_id
142
+ 3. mcp__opencode-1__identity — store result as opencode_id
143
+ 4. mcp__copilot-1__identity — store result as copilot_id
144
+ 5. mcp__codex-1__health_check — store result as codex_hc
145
+ 6. mcp__gemini-1__health_check — store result as gemini_hc
146
+ 7. mcp__opencode-1__health_check — store result as opencode_hc
147
+ 8. mcp__copilot-1__health_check — store result as copilot_hc
148
+ 9. mcp__claude-1__identity — store result as claude1_id
149
+ 10. mcp__claude-1__health_check — store result as claude1_hc
150
+ 11. mcp__claude-2__identity — store result as claude2_id
151
+ 12. mcp__claude-2__health_check — store result as claude2_hc
152
+ 13. mcp__claude-3__identity — store result as claude3_id
153
+ 14. mcp__claude-3__health_check — store result as claude3_hc
154
+ 15. mcp__claude-4__identity — store result as claude4_id
155
+ 16. mcp__claude-4__health_check — store result as claude4_hc
156
+ 17. mcp__claude-5__identity — store result as claude5_id
157
+ 18. mcp__claude-5__health_check — store result as claude5_hc
158
+ 19. mcp__claude-6__identity — store result as claude6_id
159
+ 20. mcp__claude-6__health_check — store result as claude6_hc
160
+
161
+ Return ONLY this JSON structure (no markdown, no explanation):
162
+ {
163
+ "codex-1": { "identity": <codex_id or null>, "hc": <codex_hc or null> },
164
+ "gemini-1": { "identity": <gemini_id or null>, "hc": <gemini_hc or null> },
165
+ "opencode-1": { "identity": <opencode_id or null>, "hc": <opencode_hc or null> },
166
+ "copilot-1": { "identity": <copilot_id or null>, "hc": <copilot_hc or null> },
167
+ "claude-1": { "identity": <claude1_id or null>, "hc": <claude1_hc or null> },
168
+ "claude-2": { "identity": <claude2_id or null>, "hc": <claude2_hc or null> },
169
+ "claude-3": { "identity": <claude3_id or null>, "hc": <claude3_hc or null> },
170
+ "claude-4": { "identity": <claude4_id or null>, "hc": <claude4_hc or null> },
171
+ "claude-5": { "identity": <claude5_id or null>, "hc": <claude5_hc or null> },
172
+ "claude-6": { "identity": <claude6_id or null>, "hc": <claude6_hc or null> }
173
+ }
174
+
175
+ Where each identity value is the raw object returned by the tool (with at minimum `version` and `model` fields), and each hc value is the raw object returned by health_check (with `healthy`, `latencyMs`, and optionally `model`, `via` fields).
176
+ """
177
+ )
178
+ ```
179
+
180
+ Store the sub-agent's returned JSON object as AGENT_RESULTS (parse from the sub-agent's text output).
181
+
182
+ For each slot in AGENT_RESULTS:
183
+ - `identity` = the identity result (or null if the sub-agent recorded null)
184
+ - `hc` = the health_check result (or null)
185
+
186
+ Use these values in Step 4 exactly as before — the shape is identical to what the old direct tool calls returned.
187
+
188
+ ## Step 4: Derive health state per agent
189
+
190
+ **For CLI agents — identity + health_check based:**
191
+ - If identity call threw an exception → health = `error`, latency = `—`
192
+ - Else if `hc` is null (health_check threw or timed out) → health = `available`, latency = `—`
193
+ - Else if `!hc.healthy` → health = `unhealthy`, latency = `${hc.latencyMs}ms`
194
+ - Else → health = `available`, latency = `${hc.latencyMs}ms`
195
+
196
+ Model for CLI agents: use `identity.model` if present (real model name from model_detect or static), else `identity.display_provider ?? identity.provider`.
197
+
198
+ **For HTTP agents (claude-1 through claude-6) — live health_check result:**
199
+ - If identity call threw an exception → health = `error`, latency = `—`
200
+ - Else if `hc` is null (health_check threw or timed out) → health = `unreachable`, latency = `—`
201
+ - Else if `hc.healthy === false` → health = `unhealthy`, latency = `${hc.latencyMs}ms`
202
+ - Else if `hc.via === 'fallback'` → health = `fallback`, latency = `${hc.latencyMs}ms`
203
+ - Else → health = `available`, latency = `${hc.latencyMs}ms`
204
+
205
+ When `hc.via === 'fallback'`, the displayed Model should be `hc.model` (the fallback model) rather than the primary model from identity, since that's what actually responded.
206
+
207
+ ## Step 5: Render formatted table
208
+
209
+ Collect all results then render **one table** via a single Bash call (do not print rows one at a time). Pass the collected data as a JSON string into the script.
210
+
211
+ Columns: **Agent | Auth | Provider | Model | Health | Latency**
212
+
213
+ Auto-size each column to the widest value (including header). Use box-drawing characters for borders.
214
+
215
+ Before rendering, prepend a claude orchestrator row at the TOP of the table. This row does NOT come from AGENT_RESULTS — it comes from INIT_INFO:
216
+ - Agent: `claude`
217
+ - Auth: `claudeAuth` (from INIT_INFO — derived from `oauthAccount.billingType` in `~/.claude.json`; `sub` for stripe_subscription/pro, `api` if `ANTHROPIC_API_KEY` is set or billingType indicates API billing)
218
+ - Provider: `Anthropic`
219
+ - Model: `claudeModel` (from INIT_INFO, e.g. `claude-sonnet-4-6`)
220
+ - Health: `orchestrator`
221
+ - Latency: `—`
222
+
223
+ Example output format:
224
+
225
+ ```
226
+ ┌─────────────┬──────┬──────────────┬───────────────────────────────────────────────────┬──────────────┬─────────┐
227
+ │ Agent │ Auth │ Provider │ Model │ Health │ Latency │
228
+ ├─────────────┼──────┼──────────────┼───────────────────────────────────────────────────┼──────────────┼─────────┤
229
+ │ claude │ sub │ Anthropic │ claude-sonnet-4-6 │ orchestrator │ — │
230
+ │ codex-1 │ sub │ OpenAI │ gpt-5.3-codex │ available │ 245ms │
231
+ │ gemini-1 │ sub │ Google │ gemini-2.5-pro │ available │ 312ms │
232
+ │ opencode-1 │ sub │ OpenCode │ xai/grok-3 │ available │ 891ms │
233
+ │ copilot-1 │ sub │ GitHub │ gpt-4.1 │ available │ 1204ms │
234
+ │ claude-1 │ api │ AkashML │ deepseek-ai/DeepSeek-V3.2 │ available │ 524ms │
235
+ │ claude-2 │ api │ AkashML │ MiniMaxAI/MiniMax-M2.5 │ available │ 735ms │
236
+ │ claude-3 │ api │ Together.xyz │ Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8 │ available │ 761ms │
237
+ │ claude-4 │ api │ Fireworks │ accounts/fireworks/models/kimi-k2p5 │ available │ 1828ms │
238
+ │ claude-5 │ api │ Together.xyz │ meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8 │ available │ 20601ms │
239
+ │ claude-6 │ api │ Fireworks │ accounts/fireworks/models/glm-5 │ fallback │ 312ms │
240
+ └─────────────┴──────┴──────────────┴───────────────────────────────────────────────────┴──────────────┴─────────┘
241
+
242
+ Scoreboard: 156 rounds recorded | Last update: 2026-02-23T14:23:52.301Z
243
+ ```
244
+
245
+ If scoreboard file was absent, show instead:
246
+ ```
247
+ Scoreboard: no data yet (run /qgsd:quorum first to populate)
248
+ ```
249
+
250
+ Health legend:
251
+ - `available` — agent responded (identity succeeded; for HTTP: health_check passed)
252
+ - `fallback` — primary endpoint failed; fallback provider (ANTHROPIC_FALLBACK_BASE_URL) responded successfully
253
+ - `unhealthy` — HTTP endpoint returned healthy=false
254
+ - `unreachable` — HTTP health_check call failed (timeout, connection error)
255
+ - `error` — identity call failed (agent not running or crashed)
256
+
257
+ </process>
258
+
259
+ <success_criteria>
260
+ - All 11 rows shown in one clean table (1 orchestrator + 4 CLI + 6 HTTP)
261
+ - Columns: Agent | Auth | Provider | Model | Health | Latency (no UNAVAIL column)
262
+ - `claude` orchestrator row shown at top of table with model read from `~/.claude/settings.json`
263
+ - CLI agents show real model names (gpt-5.3-codex, gemini-2.5-pro, xai/grok-3, gpt-4.1) not binary names
264
+ - CLI agents show real latency in ms from `health_check` --version call
265
+ - CLI agent Provider column uses `identity.display_provider` (OpenAI, Google, OpenCode, GitHub)
266
+ - Provider derived from ~/.claude.json ANTHROPIC_BASE_URL for HTTP agents; identity.display_provider for CLI agents
267
+ - Health for CLI agents reflects identity + health_check result (available/unhealthy/error)
268
+ - Health for claude-1..6 is live from health_check result; `fallback` shown when primary failed but fallback responded
269
+ - Model column shows fallback model name (hc.model) when via=fallback, so it always reflects what actually served the check
270
+ - Latency shows ms for all agents with health_check, — for claude orchestrator row
271
+ - Command handles missing scoreboard gracefully (no crash)
272
+ - Command handles individual agent failures gracefully (no crash)
273
+ - Table rendered in a single Bash call at the end, not printed row-by-row
274
+ </success_criteria>
@@ -0,0 +1,238 @@
1
+ ---
2
+ name: qgsd:mcp-update
3
+ description: Update a quorum agent to its latest version — detects install method from ~/.claude.json and runs the correct update command
4
+ argument-hint: "<agent|all>"
5
+ allowed-tools:
6
+ - Bash
7
+ ---
8
+
9
+ <objective>
10
+ Update a named quorum agent (or all agents) to their latest version. The install method is detected from `~/.claude.json` mcpServers config: `npx`-based agents update via `npm install -g <package>`; `node`-based local repo agents update via `git pull && npm run build` in their repo directory. The running process is NOT killed — run `/qgsd:mcp-restart <agent>` after updating to load the new binary.
11
+ </objective>
12
+
13
+ <process>
14
+
15
+ ## Step 1 — Parse arguments
16
+
17
+ Parse `$ARGUMENTS` as one token: `$TARGET`.
18
+
19
+ If `$TARGET` is missing, print usage and stop:
20
+ ```
21
+ Usage: /qgsd:mcp-update <agent|all>
22
+
23
+ Valid agents:
24
+ codex-cli-1, gemini-cli-1, opencode-1, copilot-1,
25
+ claude-1, claude-2, claude-3, claude-4, claude-5, claude-6
26
+
27
+ Use "all" to update all configured agents sequentially.
28
+ ```
29
+
30
+ ## Step 2 — Validate agent name (single agent mode)
31
+
32
+ If `$TARGET` is not `"all"`:
33
+
34
+ Check `$TARGET` against the known agent list:
35
+ ```
36
+ codex-cli-1, gemini-cli-1, opencode-1, copilot-1,
37
+ claude-1, claude-2, claude-3, claude-4, claude-5, claude-6
38
+ ```
39
+
40
+ If not in the list, print an error and stop:
41
+ ```
42
+ Error: Unknown agent "$TARGET"
43
+
44
+ Valid agents:
45
+ codex-cli-1 gemini-cli-1 opencode-1 copilot-1
46
+ claude-1 claude-2 claude-3 claude-4
47
+ claude-5 claude-6
48
+
49
+ Use "all" to update all configured agents.
50
+ ```
51
+
52
+ ## Step 3 — Read install config from ~/.claude.json
53
+
54
+ Run this inline node script via Bash to read the install configuration:
55
+
56
+ **For single agent:**
57
+ ```bash
58
+ node -e "
59
+ const fs = require('fs');
60
+ const path = require('path');
61
+ const os = require('os');
62
+
63
+ const claudeJsonPath = path.join(os.homedir(), '.claude.json');
64
+ let claudeJson;
65
+ try {
66
+ claudeJson = JSON.parse(fs.readFileSync(claudeJsonPath, 'utf8'));
67
+ } catch (e) {
68
+ console.error('Error: Cannot read ~/.claude.json: ' + e.message);
69
+ process.exit(1);
70
+ }
71
+
72
+ const servers = claudeJson.mcpServers || {};
73
+ const agent = process.env.AGENT;
74
+ const serverConfig = servers[agent];
75
+
76
+ if (!serverConfig) {
77
+ console.error('Error: Agent \"' + agent + '\" is not configured in ~/.claude.json mcpServers');
78
+ process.exit(2);
79
+ }
80
+
81
+ const command = serverConfig.command;
82
+ const args = serverConfig.args || [];
83
+
84
+ let result;
85
+ if (command === 'npx' || command === 'npm') {
86
+ // npm/npx-based: package name is last arg (skip flags like -y)
87
+ const packageName = args[args.length - 1];
88
+ result = { type: 'npm', package: packageName };
89
+ } else if (command === 'node' && args.length > 0) {
90
+ // local node path: args[0] = /path/to/repo/dist/index.js
91
+ const distIndexPath = args[0];
92
+ const repoDir = path.dirname(path.dirname(distIndexPath));
93
+ result = { type: 'local', repoDir };
94
+ } else {
95
+ result = { type: 'unknown', command, args };
96
+ }
97
+
98
+ process.stdout.write(JSON.stringify(result) + '\n');
99
+ " AGENT="$TARGET"
100
+ ```
101
+
102
+ Store output as `$INSTALL_INFO`.
103
+
104
+ If exit code 1 or 2: print the error message and stop.
105
+ If exit code 0: parse `$INSTALL_INFO` JSON.
106
+
107
+ ## Step 4 — Execute update (single agent)
108
+
109
+ Based on the `type` field from `$INSTALL_INFO`:
110
+
111
+ **type = "npm":**
112
+ ```bash
113
+ npm install -g "$PACKAGE"
114
+ ```
115
+ where `$PACKAGE` is `install_info.package`.
116
+
117
+ Capture exit code and output. If exit code ≠ 0: print error output and stop.
118
+
119
+ **type = "local":**
120
+ ```bash
121
+ cd "$REPO_DIR" && git pull && npm run build
122
+ ```
123
+ where `$REPO_DIR` is `install_info.repoDir`.
124
+
125
+ Capture exit code and output. If exit code ≠ 0: print error output and stop.
126
+ **Important:** Do NOT kill the running process if build fails.
127
+
128
+ **type = "unknown":**
129
+ Print:
130
+ ```
131
+ Warning: Cannot determine update method for $TARGET (command: <command>).
132
+ Manual update required. Check ~/.claude.json mcpServers.$TARGET for configuration.
133
+ ```
134
+ Stop.
135
+
136
+ ## Step 5 — Print confirmation (single agent)
137
+
138
+ Display:
139
+ ```
140
+ Updated $TARGET
141
+
142
+ Install method: <npm: npm install -g <pkg>> OR <local repo: git pull + npm run build in <repo_dir>>
143
+ Result: <last line of npm/git output>
144
+
145
+ Note: The running agent process is still using the old version.
146
+ Run: /qgsd:mcp-restart $TARGET to load the new binary.
147
+ ```
148
+
149
+ ## Step 6 — All-agent mode (if $TARGET = "all")
150
+
151
+ If `$TARGET` is `"all"`, skip Steps 2–5 and run this instead:
152
+
153
+ **6a. Build update task list via inline node script:**
154
+
155
+ ```bash
156
+ node -e "
157
+ const fs = require('fs');
158
+ const path = require('path');
159
+ const os = require('os');
160
+
161
+ const KNOWN_AGENTS = [
162
+ 'codex-cli-1', 'gemini-cli-1', 'opencode-1', 'copilot-1',
163
+ 'claude-1', 'claude-2', 'claude-3', 'claude-4', 'claude-5', 'claude-6'
164
+ ];
165
+
166
+ const claudeJsonPath = path.join(os.homedir(), '.claude.json');
167
+ const claudeJson = JSON.parse(fs.readFileSync(claudeJsonPath, 'utf8'));
168
+ const servers = claudeJson.mcpServers || {};
169
+
170
+ const tasks = [];
171
+ const seenKeys = new Set();
172
+
173
+ for (const agent of KNOWN_AGENTS) {
174
+ const cfg = servers[agent];
175
+ if (!cfg) {
176
+ tasks.push({ agent, type: 'not_configured' });
177
+ continue;
178
+ }
179
+ const cmd = cfg.command;
180
+ const args = cfg.args || [];
181
+
182
+ if (cmd === 'npx' || cmd === 'npm') {
183
+ const pkg = args[args.length - 1];
184
+ const key = 'npm:' + pkg;
185
+ if (seenKeys.has(key)) {
186
+ tasks.push({ agent, type: 'npm', package: pkg, deduplicated: true });
187
+ } else {
188
+ seenKeys.add(key);
189
+ tasks.push({ agent, type: 'npm', package: pkg, deduplicated: false });
190
+ }
191
+ } else if (cmd === 'node' && args.length > 0) {
192
+ const repoDir = path.dirname(path.dirname(args[0]));
193
+ const key = 'local:' + repoDir;
194
+ if (seenKeys.has(key)) {
195
+ tasks.push({ agent, type: 'local', repoDir, deduplicated: true });
196
+ } else {
197
+ seenKeys.add(key);
198
+ tasks.push({ agent, type: 'local', repoDir, deduplicated: false });
199
+ }
200
+ } else {
201
+ tasks.push({ agent, type: 'unknown', command: cmd });
202
+ }
203
+ }
204
+
205
+ process.stdout.write(JSON.stringify(tasks) + '\n');
206
+ "
207
+ ```
208
+
209
+ **6b. For each task in the list, sequentially:**
210
+ - If `deduplicated: true`: mark as `SKIPPED (shared repo already updated)` — do not run again
211
+ - If `type: "npm"` and `deduplicated: false`: run `npm install -g <package>`
212
+ - If `type: "local"` and `deduplicated: false`: run `cd <repoDir> && git pull && npm run build`
213
+ - If `type: "not_configured"`: mark as `NOT CONFIGURED`
214
+ - If `type: "unknown"`: mark as `UNKNOWN (manual update required)`
215
+
216
+ **6c. Print per-agent status table:**
217
+ ```
218
+ Update results:
219
+
220
+ codex-cli-1 npm install -g codex-mcp-server ✓ UPDATED
221
+ gemini-cli-1 npm install -g @tuannvm/gemini-... ✓ UPDATED
222
+ opencode-1 git pull + build in /code/opencode ✓ UPDATED
223
+ copilot-1 git pull + build in /code/copilot ✓ UPDATED
224
+ claude-1 git pull + build in /code/claude-m ✓ UPDATED
225
+ claude-2 (shared repo with claude-1) ⚡ SKIPPED
226
+ claude-3 (shared repo) ⚡ SKIPPED
227
+ claude-4 (shared repo) ⚡ SKIPPED
228
+ claude-5 (shared repo) ⚡ SKIPPED
229
+ claude-6 (shared repo) ⚡ SKIPPED
230
+
231
+ To load new binaries, restart updated agents:
232
+ /qgsd:mcp-restart codex-cli-1
233
+ /qgsd:mcp-restart gemini-cli-1
234
+ /qgsd:mcp-restart opencode-1
235
+ (etc. — list only agents that were UPDATED, not SKIPPED)
236
+ ```
237
+
238
+ </process>
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: qgsd:new-milestone
3
+ description: Start a new milestone cycle — update PROJECT.md and route to requirements
4
+ argument-hint: "[milestone name, e.g., 'v1.1 Notifications']"
5
+ allowed-tools:
6
+ - Read
7
+ - Write
8
+ - Bash
9
+ - Task
10
+ - AskUserQuestion
11
+ ---
12
+ <objective>
13
+ Start a new milestone: questioning → research (optional) → requirements → roadmap.
14
+
15
+ Brownfield equivalent of new-project. Project exists, PROJECT.md has history. Gathers "what's next", updates PROJECT.md, then runs requirements → roadmap cycle.
16
+
17
+ **Creates/Updates:**
18
+ - `.planning/PROJECT.md` — updated with new milestone goals
19
+ - `.planning/research/` — domain research (optional, NEW features only)
20
+ - `.planning/REQUIREMENTS.md` — scoped requirements for this milestone
21
+ - `.planning/ROADMAP.md` — phase structure (continues numbering)
22
+ - `.planning/STATE.md` — reset for new milestone
23
+
24
+ **After:** `/qgsd:plan-phase [N]` to start execution.
25
+ </objective>
26
+
27
+ <execution_context>
28
+ @~/.claude/qgsd/workflows/new-milestone.md
29
+ @~/.claude/qgsd/references/questioning.md
30
+ @~/.claude/qgsd/references/ui-brand.md
31
+ @~/.claude/qgsd/templates/project.md
32
+ @~/.claude/qgsd/templates/requirements.md
33
+ </execution_context>
34
+
35
+ <context>
36
+ Milestone name: $ARGUMENTS (optional - will prompt if not provided)
37
+
38
+ Project and milestone context files are resolved inside the workflow (`init new-milestone`) and delegated via `<files_to_read>` blocks where subagents are used.
39
+ </context>
40
+
41
+ <process>
42
+ Execute the new-milestone workflow from @~/.claude/qgsd/workflows/new-milestone.md end-to-end.
43
+ Preserve all workflow gates (validation, questioning, research, requirements, roadmap approval, commits).
44
+ </process>
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: qgsd:new-project
3
+ description: Initialize a new project with deep context gathering and PROJECT.md
4
+ argument-hint: "[--auto]"
5
+ allowed-tools:
6
+ - Read
7
+ - Bash
8
+ - Write
9
+ - Task
10
+ - AskUserQuestion
11
+ ---
12
+ <context>
13
+ **Flags:**
14
+ - `--auto` — Automatic mode. After config questions, runs research → requirements → roadmap without further interaction. Expects idea document via @ reference.
15
+ </context>
16
+
17
+ <objective>
18
+ Initialize a new project through unified flow: questioning → research (optional) → requirements → roadmap.
19
+
20
+ **Creates:**
21
+ - `.planning/PROJECT.md` — project context
22
+ - `.planning/config.json` — workflow preferences
23
+ - `.planning/research/` — domain research (optional)
24
+ - `.planning/REQUIREMENTS.md` — scoped requirements
25
+ - `.planning/ROADMAP.md` — phase structure
26
+ - `.planning/STATE.md` — project memory
27
+
28
+ **After this command:** Run `/qgsd:plan-phase 1` to start execution.
29
+ </objective>
30
+
31
+ <execution_context>
32
+ @~/.claude/qgsd/workflows/new-project.md
33
+ @~/.claude/qgsd/references/questioning.md
34
+ @~/.claude/qgsd/references/ui-brand.md
35
+ @~/.claude/qgsd/templates/project.md
36
+ @~/.claude/qgsd/templates/requirements.md
37
+ </execution_context>
38
+
39
+ <process>
40
+ Execute the new-project workflow from @~/.claude/qgsd/workflows/new-project.md end-to-end.
41
+ Preserve all workflow gates (validation, approvals, commits, routing).
42
+ </process>