@jstn-sdk/ma 0.1.12 → 0.14.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 (198) hide show
  1. package/.codex/agents/Architect.toml +1 -2
  2. package/.codex/agents/Auditor.toml +1 -2
  3. package/.codex/agents/Builder.toml +1 -2
  4. package/.codex/agents/Flow.toml +1 -2
  5. package/.codex/agents/Sage.toml +1 -2
  6. package/.codex/agents/Vibe.toml +1 -2
  7. package/.codex/hooks.json +24 -13
  8. package/.codex/prompts/enforcement.md +4 -0
  9. package/.codex/prompts/onboarding.md +6 -1
  10. package/.codex/prompts/release-rules.md +0 -0
  11. package/.codex/prompts/skill-contract.md +4 -0
  12. package/COVERAGE.md +211 -0
  13. package/DEMO.md +274 -0
  14. package/LICENSE +0 -0
  15. package/README.md +132 -656
  16. package/bin/ma.js +748 -55
  17. package/data/clone-data.ledger.json +41 -0
  18. package/data/clone-data.proof.json +50 -0
  19. package/data/clone-data.rvf +37 -0
  20. package/docs/README.md +10 -1
  21. package/docs/autonomous-tasks.md +46 -0
  22. package/docs/codex-integration.md +16 -0
  23. package/docs/getting-started.md +62 -22
  24. package/docs/mcp-setup.md +64 -0
  25. package/docs/qa/release-issue-gates-0.14.0.json +644 -0
  26. package/docs/qa/release-readiness-0.1.5.md +1 -1
  27. package/docs/qa/{release-readiness-0.1.12.md → release-readiness-0.14.0.md} +25 -9
  28. package/docs/quality.md +24 -0
  29. package/docs/reference/native-security-playbooks.md +6 -0
  30. package/docs/reference/native-source-selection.md +6 -0
  31. package/docs/release-spec.md +39 -10
  32. package/docs/skills.md +14 -1
  33. package/index.js +295 -2
  34. package/mcp/collections.json +23 -6
  35. package/mcp/fallback.json +0 -0
  36. package/mcp/local/code-intel.js +179 -41
  37. package/mcp/local/context.js +180 -0
  38. package/mcp/local/memory.js +17 -6
  39. package/mcp/local/quality.js +39 -0
  40. package/mcp/local/state.js +7 -3
  41. package/mcp/local/team-run.js +56 -4
  42. package/mcp/local-capabilities.json +9 -0
  43. package/mcp/servers.json +24 -0
  44. package/package.json +29 -4
  45. package/plugins/meta-architect/.app.json +1 -1
  46. package/plugins/meta-architect/.codex-plugin/plugin.json +1 -1
  47. package/plugins/meta-architect/.mcp.json +1 -1
  48. package/plugins/meta-architect/README.md +8 -1
  49. package/plugins/meta-architect/obsidian/main.js +534 -0
  50. package/plugins/meta-architect/obsidian/manifest.json +9 -0
  51. package/plugins/meta-architect/obsidian/styles.css +7 -0
  52. package/plugins/meta-architect/skills/arch/SKILL.md +2 -0
  53. package/plugins/meta-architect/skills/build/SKILL.md +3 -0
  54. package/plugins/meta-architect/skills/flow/SKILL.md +2 -0
  55. package/plugins/meta-architect/skills/sage/SKILL.md +2 -0
  56. package/plugins/meta-architect/skills/sage/references/source-selection.md +8 -0
  57. package/plugins/meta-architect/skills/vet/SKILL.md +2 -0
  58. package/plugins/meta-architect/skills/vet/references/security-playbooks.md +7 -0
  59. package/plugins/meta-architect/skills/vibe/SKILL.md +2 -0
  60. package/schemas/autonomous-task-queue.schema.json +56 -0
  61. package/schemas/handoff-packet.schema.json +36 -0
  62. package/schemas/setup-receipt.schema.json +28 -0
  63. package/schemas/skill-frontmatter.schema.json +20 -0
  64. package/schemas/support-bundle.schema.json +37 -0
  65. package/schemas/task-contract.schema.json +31 -0
  66. package/scripts/active-autonomy-hook.mjs +226 -0
  67. package/scripts/build-linux-packages.mjs +7 -3
  68. package/scripts/cleanup-test-fixtures.sh +55 -0
  69. package/scripts/context-hydration-hook.mjs +89 -0
  70. package/scripts/demo-smoke.js +285 -0
  71. package/scripts/doctor.js +27 -12
  72. package/scripts/install.sh +57 -0
  73. package/scripts/install.sh.sha256 +1 -0
  74. package/scripts/linux-package-smoke.mjs +2 -2
  75. package/scripts/package-size-check.mjs +26 -0
  76. package/scripts/plugin-sync.js +83 -17
  77. package/scripts/postinstall.js +17 -10
  78. package/scripts/prepack.js +9 -0
  79. package/scripts/ralph/prompt.md +35 -0
  80. package/scripts/release-sync.js +72 -7
  81. package/scripts/release-verify.js +260 -2
  82. package/scripts/setup-npmrc.js +48 -23
  83. package/scripts/skills-install.js +9 -2
  84. package/scripts/skills-manifest.js +2 -21
  85. package/scripts/skills-pack.js +2 -2
  86. package/scripts/skills-validate.js +5 -55
  87. package/skills/arch/SKILL.md +2 -0
  88. package/skills/build/SKILL.md +3 -0
  89. package/skills/flow/SKILL.md +2 -0
  90. package/skills/index.json +0 -0
  91. package/skills/sage/SKILL.md +2 -0
  92. package/skills/sage/references/source-selection.md +8 -0
  93. package/skills/vet/SKILL.md +2 -0
  94. package/skills/vet/references/security-playbooks.md +7 -0
  95. package/skills/vibe/SKILL.md +2 -0
  96. package/sprint/00-idea.md +0 -0
  97. package/sprint/01-architecture.md +0 -0
  98. package/sprint/02-oss-evidence.md +0 -0
  99. package/sprint/03-logic.md +0 -0
  100. package/sprint/04-security.md +0 -0
  101. package/sprint/05-dx-ux.md +0 -0
  102. package/sprint/06-build-plan.md +0 -0
  103. package/sprint/07-release.md +0 -0
  104. package/src/agents.js +279 -0
  105. package/src/bootstrap.js +268 -62
  106. package/src/build-gate.js +2 -2
  107. package/src/codex-app-server.js +291 -0
  108. package/src/decision-log.js +0 -0
  109. package/src/fs-utils.js +175 -4
  110. package/src/launcher.js +28 -21
  111. package/src/mcp-config.js +9 -1
  112. package/src/mcp-live-client.js +422 -3
  113. package/src/paths.js +10 -1
  114. package/src/policy.js +3 -3
  115. package/src/prelaunch.js +189 -0
  116. package/src/quality/ai-quality-orchestrator.js +328 -0
  117. package/src/release-issue-gates.js +252 -0
  118. package/src/release-operations.js +62 -0
  119. package/src/release-state.js +0 -0
  120. package/src/runtime/active-autonomy-core.js +208 -0
  121. package/src/runtime/agent-compat.js +31 -0
  122. package/src/runtime/alignment-sentinel.js +165 -0
  123. package/src/runtime/architect-review.js +326 -0
  124. package/src/runtime/autonomous-tasks.js +408 -0
  125. package/src/runtime/build-readiness.js +28 -4
  126. package/src/runtime/code-graph-rehearse.js +113 -0
  127. package/src/runtime/codeburn-core.js +112 -0
  128. package/src/runtime/context-authority.js +40 -0
  129. package/src/runtime/context-economy-core.js +316 -0
  130. package/src/runtime/continuity-graph.js +201 -0
  131. package/src/runtime/continuity-notes.js +71 -26
  132. package/src/runtime/core-source-ingest.js +379 -0
  133. package/src/runtime/detached-provider.js +142 -0
  134. package/src/runtime/doctor-report.js +18 -0
  135. package/src/runtime/environment-awareness-core.js +460 -0
  136. package/src/runtime/exposure-catalog.js +276 -0
  137. package/src/runtime/graphify-core.js +167 -0
  138. package/src/runtime/guidance-stack.js +9 -2
  139. package/src/runtime/handoff-packets.js +92 -0
  140. package/src/runtime/headroom-core.js +104 -0
  141. package/src/runtime/helper-orchestration-core.js +307 -0
  142. package/src/runtime/hook-profiles.js +20 -0
  143. package/src/runtime/learning-loop-core.js +344 -0
  144. package/src/runtime/live-agent-verification.js +122 -0
  145. package/src/runtime/maestro-events.js +18 -0
  146. package/src/runtime/maestro-manager.js +19 -0
  147. package/src/runtime/maestro-output.js +58 -0
  148. package/src/runtime/maestro-state.js +125 -0
  149. package/src/runtime/managed-markdown.js +29 -0
  150. package/src/runtime/mcp-authority.js +147 -0
  151. package/src/runtime/mcp-policy.js +192 -0
  152. package/src/runtime/obsidian-integration-core.js +1089 -0
  153. package/src/runtime/obsidian-plugin-bridge.js +1045 -0
  154. package/src/runtime/pi-maestro-core.js +89 -0
  155. package/src/runtime/preferences.js +79 -0
  156. package/src/runtime/project-context.js +636 -0
  157. package/src/runtime/prompt-strategy-core.js +230 -0
  158. package/src/runtime/quorum-review.js +90 -0
  159. package/src/runtime/ralph-execution-core.js +217 -0
  160. package/src/runtime/redaction-gateway.js +373 -0
  161. package/src/runtime/runtime-state.js +935 -2
  162. package/src/runtime/schema-migrations.js +162 -0
  163. package/src/runtime/semantic-recording-core.js +147 -0
  164. package/src/runtime/signal-hooks.js +28 -0
  165. package/src/runtime/skills-registry-export.js +754 -0
  166. package/src/runtime/task-contracts.js +83 -0
  167. package/src/runtime/universal-plugin-broker-core.js +898 -0
  168. package/src/runtime/workspace-intelligence-runtime.js +674 -0
  169. package/src/runtime/workspace-virtualizer.js +102 -0
  170. package/src/runtime-artifacts.js +225 -62
  171. package/src/setup-lifecycle.js +359 -0
  172. package/src/skill-frontmatter.js +78 -0
  173. package/src/skill-installer.js +226 -71
  174. package/src/skills.js +1166 -96
  175. package/src/state-sync.js +0 -0
  176. package/src/test-fixtures.js +543 -0
  177. package/src/tui/grid.js +67 -0
  178. package/src/tui/status-grid.js +23 -0
  179. package/support-bundle.json +114 -0
  180. package/templates/AGENTS.md +6 -2
  181. package/templates/catalog-manifest.json +0 -0
  182. package/templates/model-instructions/core.md +0 -0
  183. package/templates/model-instructions/release.md +0 -0
  184. package/templates/model-instructions/security.md +0 -0
  185. package/templates/quality/ai-quality-rules.yml +37 -0
  186. package/docs/assets/image/Screenshot(1).png +0 -0
  187. package/docs/assets/image/Screenshot(2).png +0 -0
  188. package/docs/assets/image/Screenshot(3).png +0 -0
  189. package/docs/assets/image/Screenshot(4).png +0 -0
  190. package/docs/assets/image/Screenshot(5).png +0 -0
  191. package/docs/assets/image/Screenshot(6).png +0 -0
  192. package/docs/assets/image/Screenshot(7).png +0 -0
  193. package/docs/assets/image/Screenshot(8).png +0 -0
  194. package/docs/assets/image/Screenshot(9).png +0 -0
  195. package/docs/assets/meta-architect-logo.png +0 -0
  196. package/docs/assets/meta-architect-logo.svg +0 -8
  197. package/docs/onboarding.md +0 -65
  198. package/docs/skills-publishing.md +0 -255
package/src/bootstrap.js CHANGED
@@ -2,15 +2,26 @@ import { spawnSync } from "node:child_process";
2
2
  import fs from "node:fs/promises";
3
3
  import os from "node:os";
4
4
  import path from "node:path";
5
+ import { detectInstalled, getAgent } from "./agents.js";
5
6
  import { loadDecisionLog } from "./decision-log.js";
7
+ import { inspectRuntimeStateHealth } from "./fs-utils.js";
6
8
  import {
7
9
  runLocalCapabilityReadinessChecks,
8
10
  validateLocalCapabilities,
9
11
  validateMcpServers,
10
12
  } from "./mcp-config.js";
13
+ import { getMcpBridgeConfiguration, mcpClientVersion } from "./mcp-live-client.js";
11
14
  import { getMcpRootPath, getRepoRoot, getRuntimeWritePath, packageRoot } from "./paths.js";
15
+ import { resolveReleaseIssueGates } from "./release-issue-gates.js";
12
16
  import { loadReleaseState } from "./release-state.js";
17
+ import { getArchitectReviewConfiguration } from "./runtime/architect-review.js";
18
+ import { printDoctorStatuses, summarizeDoctorStatuses } from "./runtime/doctor-report.js";
19
+ import { mcpWriteCapabilityStatus } from "./runtime/mcp-authority.js";
20
+ import { loadObsidianVaultConfig } from "./runtime/obsidian-integration-core.js";
21
+ import { inspectRedactionVault } from "./runtime/redaction-gateway.js";
13
22
  import { loadLeaderAuthority, loadRuntimeSnapshot } from "./runtime/runtime-state.js";
23
+ import { findOutdatedSchemas } from "./runtime/schema-migrations.js";
24
+ import { inspectSetupDrift } from "./setup-lifecycle.js";
14
25
  import {
15
26
  areSkillsInstalled,
16
27
  ensureSkillsInstalled,
@@ -18,44 +29,211 @@ import {
18
29
  getSkillInstallRoot,
19
30
  getSupportBundleRoot,
20
31
  isSupportBundleInstalled,
32
+ readInstallReceipt,
21
33
  } from "./skill-installer.js";
22
34
  import { runInit } from "./skills.js";
35
+ import { renderCheckGrid } from "./tui/status-grid.js";
23
36
 
24
37
  function makeStatus(kind, label, detail = "") {
25
38
  return { kind, label, detail };
26
39
  }
27
40
 
28
- function resolveCodexCommand() {
29
- return process.env.MA_CODEX_BIN ?? "codex";
41
+ function inspectMcpBridge() {
42
+ const template = process.env.MA_MCP_REMOTE_BRIDGE_CMD?.trim();
43
+ if (!template) return makeStatus("OK", "MCP remote bridge", "not configured");
44
+ const command = template.split(/\s+/, 1)[0].replace(/^['"]|['"]$/g, "");
45
+ const policy = getMcpBridgeConfiguration();
46
+ const allowed = policy.allowedCommands.some(
47
+ (entry) => entry === command || path.basename(entry) === path.basename(command),
48
+ );
49
+ return makeStatus(
50
+ allowed ? "OK" : "WARN",
51
+ "MCP remote bridge",
52
+ allowed
53
+ ? `${command} is explicitly allowlisted (${policy.source})`
54
+ : `${command} is not allowlisted; configure MA_MCP_REMOTE_BRIDGE_ALLOWLIST or mcp/bridge.json`,
55
+ );
30
56
  }
31
57
 
32
- function runCommand(command, args) {
33
- const isNodeScript = [".js", ".mjs", ".cjs"].includes(path.extname(command));
34
- const finalCommand = isNodeScript ? process.execPath : command;
35
- const finalArgs = isNodeScript ? [command, ...args] : args;
36
- return spawnSync(finalCommand, finalArgs, { encoding: "utf8" });
58
+ function inspectArchitectReview() {
59
+ const template = process.env.MA_ARCHITECT_REVIEW_CMD?.trim();
60
+ if (!template) return makeStatus("OK", "external architect review", "not configured");
61
+ const command = template.split(/\s+/, 1)[0].replace(/^['"]|['"]$/g, "");
62
+ const policy = getArchitectReviewConfiguration();
63
+ const allowed = policy.allowedCommands.some(
64
+ (entry) => entry === command || path.basename(entry) === path.basename(command),
65
+ );
66
+ return makeStatus(
67
+ allowed ? "OK" : "WARN",
68
+ "external architect review",
69
+ allowed
70
+ ? `${command} is explicitly allowlisted (${policy.source})`
71
+ : `${command} is not allowlisted; configure MA_ARCHITECT_REVIEW_ALLOWLIST or .ma/architect-review-policy.json`,
72
+ );
37
73
  }
38
74
 
39
- function inspectCodex() {
40
- const command = resolveCodexCommand();
41
- const result = runCommand(command, ["--version"]);
42
- const version = result.stdout.trim();
43
- if (result.status === 0) {
44
- return {
45
- ok: true,
46
- command,
47
- detail: result.error?.message ?? "",
48
- version,
75
+ export async function inspectWorkspaceNpmrc() {
76
+ const npmrcPath = path.join(getRepoRoot(), ".npmrc");
77
+ try {
78
+ const content = await fs.readFile(npmrcPath, "utf8");
79
+ const hasAuthMaterial = /(?:_authToken|_auth|_password|username)\s*=|token\s*=/i.test(content);
80
+ return makeStatus(
81
+ hasAuthMaterial ? "WARN" : "OK",
82
+ "workspace npm auth",
83
+ hasAuthMaterial
84
+ ? "token-bearing .npmrc detected; use NODE_AUTH_TOKEN or a temporary config outside the workspace"
85
+ : "no token-bearing .npmrc detected",
86
+ );
87
+ } catch (error) {
88
+ if (error?.code === "ENOENT")
89
+ return makeStatus("OK", "workspace npm auth", "no workspace .npmrc");
90
+ return makeStatus("WARN", "workspace npm auth", `unable to inspect .npmrc: ${error.message}`);
91
+ }
92
+ }
93
+
94
+ async function inspectPluginInjectionState() {
95
+ const root = path.join(os.homedir(), ".ma", "backups", "plugins");
96
+ try {
97
+ const plugins = await fs.readdir(root, { withFileTypes: true });
98
+ const receipts = [];
99
+ for (const plugin of plugins) {
100
+ if (!plugin.isDirectory()) continue;
101
+ const runs = await fs.readdir(path.join(root, plugin.name), { withFileTypes: true });
102
+ for (const run of runs.filter((entry) => entry.isDirectory())) {
103
+ const receiptPath = path.join(root, plugin.name, run.name, "receipt.json");
104
+ try {
105
+ receipts.push(JSON.parse(await fs.readFile(receiptPath, "utf8")));
106
+ } catch {
107
+ // Ignore incomplete backup directories.
108
+ }
109
+ }
110
+ }
111
+ const latest = receipts.sort((a, b) => `${b.backupRoot}`.localeCompare(`${a.backupRoot}`))[0];
112
+ const hosts = latest?.vendorInjection?.configured_hosts ?? [];
113
+ return makeStatus(
114
+ "OK",
115
+ "plugin MCP injection state",
116
+ hosts.length > 0 ? `configured hosts: ${hosts.join(", ")}` : "no recorded vendor mutations",
117
+ );
118
+ } catch {
119
+ return makeStatus("OK", "plugin MCP injection state", "no recorded vendor mutations");
120
+ }
121
+ }
122
+
123
+ async function inspectContextHealth() {
124
+ const contextPath = getRuntimeWritePath("context", "project-index.json");
125
+ const briefPath = getRuntimeWritePath("context", "agent-brief.md");
126
+ const hookPath = path.join(getRepoRoot(), ".codex", "hooks.json");
127
+ try {
128
+ const project = JSON.parse(await fs.readFile(contextPath, "utf8"));
129
+ const brief = await fs.readFile(briefPath, "utf8");
130
+ const hooks = JSON.parse(await fs.readFile(hookPath, "utf8"));
131
+ const hookText = JSON.stringify(hooks);
132
+ const hydrated =
133
+ hookText.includes("context-hydration-hook.mjs") ||
134
+ hookText.includes("ma hook context-hydration");
135
+ const hookFiles = [];
136
+ const collectHookCommands = (value) => {
137
+ if (Array.isArray(value)) return value.forEach(collectHookCommands);
138
+ if (!value || typeof value !== "object") return;
139
+ if (typeof value.command === "string") hookFiles.push(value.command);
140
+ Object.values(value).forEach(collectHookCommands);
49
141
  };
142
+ collectHookCommands(hooks);
143
+ const brokenHookCommands = [];
144
+ for (const command of hookFiles) {
145
+ const relative = command.match(/^node\s+([^\s]+)/)?.[1];
146
+ if (!relative) continue;
147
+ try {
148
+ await fs.access(path.resolve(getRepoRoot(), relative));
149
+ } catch {
150
+ brokenHookCommands.push(relative);
151
+ }
152
+ }
153
+ const freshness = project.freshness?.status ?? "unknown";
154
+ const outdated = await findOutdatedSchemas(getRepoRoot());
155
+ const runtimeFindings = await inspectRuntimeStateHealth(getRepoRoot());
156
+ const setupDrift = await inspectSetupDrift(getRepoRoot());
157
+ const mcpWriteStatus = mcpWriteCapabilityStatus();
158
+ return [
159
+ makeStatus(
160
+ setupDrift.length ? "WARN" : "OK",
161
+ "seeded artifact drift",
162
+ setupDrift.length
163
+ ? setupDrift.map((entry) => `${entry.status}: ${entry.path}`).join(", ")
164
+ : "no managed template drift",
165
+ ),
166
+ makeStatus(
167
+ runtimeFindings.length ? "WARN" : "OK",
168
+ "runtime state integrity",
169
+ runtimeFindings.length
170
+ ? runtimeFindings.map((finding) => `${finding.type}: ${finding.path}`).join(", ")
171
+ : "atomic writes and locks healthy",
172
+ ),
173
+ makeStatus(
174
+ freshness === "stale" ? "WARN" : "OK",
175
+ "project context freshness",
176
+ `${freshness}; ${project.quality?.confidence ?? "unknown"} confidence`,
177
+ ),
178
+ makeStatus(brief.trim() ? "OK" : "WARN", "agent context brief", briefPath),
179
+ makeStatus(
180
+ hydrated ? "OK" : "WARN",
181
+ "startup/prompt context hydration",
182
+ hydrated ? hookPath : "run `ma setup`",
183
+ ),
184
+ makeStatus(
185
+ brokenHookCommands.length ? "WARN" : "OK",
186
+ "hook command portability",
187
+ brokenHookCommands.length
188
+ ? `missing: ${brokenHookCommands.join(", ")}`
189
+ : "all local hook scripts are present",
190
+ ),
191
+ makeStatus(
192
+ "OK",
193
+ "Obsidian integration",
194
+ (await loadObsidianVaultConfig())?.vaultPath || process.env.MA_OBSIDIAN_VAULT
195
+ ? "configured"
196
+ : "not configured (explicitly disabled)",
197
+ ),
198
+ await inspectRedactionVault().then((vault) =>
199
+ makeStatus(
200
+ vault.status === "warning" ? "WARN" : "OK",
201
+ "redaction vault policy",
202
+ vault.issues.length > 0
203
+ ? vault.issues.join(", ")
204
+ : `${vault.policy.retentionDays}d retention, ${vault.policy.maxEntries} max entries`,
205
+ ),
206
+ ),
207
+ await inspectWorkspaceNpmrc(),
208
+ makeStatus("OK", "MCP context resources", "local read-only context capability available"),
209
+ makeStatus(
210
+ mcpWriteStatus.readOnly ? "WARN" : "OK",
211
+ "MCP write authority",
212
+ mcpWriteStatus.detail,
213
+ ),
214
+ makeStatus(
215
+ outdated.length ? "WARN" : "OK",
216
+ "runtime schema versions",
217
+ outdated.length ? `${outdated.length} outdated artifact(s); run ma migrate` : "current",
218
+ ),
219
+ ];
220
+ } catch (_error) {
221
+ return [
222
+ makeStatus(
223
+ "WARN",
224
+ "project context health",
225
+ "Run `ma setup` to generate bounded context artifacts",
226
+ ),
227
+ ];
50
228
  }
229
+ }
51
230
 
231
+ function inspectAgent(type = process.env.MA_AGENT || "codex") {
232
+ const result = detectInstalled(type);
52
233
  return {
53
- ok: false,
54
- command,
55
- detail:
56
- (result.error?.message ?? result.stderr.trim() ?? result.stdout.trim()) ||
57
- "Codex command failed",
58
- version: "",
234
+ ok: result.installed,
235
+ detail: result.error || `${getAgent(type).displayName} command failed`,
236
+ version: result.version,
59
237
  };
60
238
  }
61
239
 
@@ -152,6 +330,21 @@ async function inspectLocalScaffold() {
152
330
  getRuntimeWritePath("release.json"),
153
331
  getRuntimeWritePath("guidance", "merged.json"),
154
332
  getRuntimeWritePath("guidance", "include-graph.json"),
333
+ getRuntimeWritePath("context", "active-autonomy-core.json"),
334
+ getRuntimeWritePath("context", "capability-composition.json"),
335
+ getRuntimeWritePath("context", "code-graph-rehearse.json"),
336
+ getRuntimeWritePath("context", "core-source-ingest.json"),
337
+ getRuntimeWritePath("context", "learning-loop-core.json"),
338
+ getRuntimeWritePath("context", "project-index.json"),
339
+ getRuntimeWritePath("context", "obsidian-bridge.json"),
340
+ getRuntimeWritePath("context", "obsidian-vault-index.json"),
341
+ getRuntimeWritePath("context", "obsidian-vault-operations.json"),
342
+ getRuntimeWritePath("context", "prompt-strategy-core.json"),
343
+ getRuntimeWritePath("context", "recording-core.json"),
344
+ getRuntimeWritePath("context", "skills-registry-export.json"),
345
+ getRuntimeWritePath("context", "workspace-virtualizer.json"),
346
+ getRuntimeWritePath("context", "workspace-context-pack.json"),
347
+ getRuntimeWritePath("context", "workspace-effectiveness.json"),
155
348
  getRuntimeWritePath("memory", "notes.md"),
156
349
  getRuntimeWritePath("memory", "index.json"),
157
350
  getRuntimeWritePath("hooks", "config.json"),
@@ -161,6 +354,10 @@ async function inspectLocalScaffold() {
161
354
  getRuntimeWritePath("tasks", "locks"),
162
355
  getRuntimeWritePath("workspaces", "index.json"),
163
356
  getRuntimeWritePath("state", "manager-runs.json"),
357
+ getRuntimeWritePath("state", "maestro-state.json"),
358
+ getRuntimeWritePath("evidence", "semantic-receipts.json"),
359
+ resolveReleaseIssueGates(getRepoRoot())?.path ??
360
+ path.join(getRepoRoot(), "docs", "qa", "release-issue-gates-missing.json"),
164
361
  path.join(getMcpRootPath(), "servers.json"),
165
362
  path.join(getMcpRootPath(), "local-capabilities.json"),
166
363
  ];
@@ -302,48 +499,59 @@ async function inspectLocalCapabilityState({ fix }) {
302
499
  }
303
500
 
304
501
  async function runEnvironmentFlow({ fix, initMcp }) {
305
- const statuses = [];
502
+ const statuses = [makeStatus("OK", "MCP client version", mcpClientVersion)];
503
+ statuses.push(inspectMcpBridge());
504
+ statuses.push(inspectArchitectReview());
306
505
 
307
- const codexResolution = await inspectCodexResolution({ fix });
506
+ const agentType = process.env.MA_AGENT?.trim() || "codex";
507
+ const agent = getAgent(agentType);
508
+ const codexResolution = agentType === "codex" ? await inspectCodexResolution({ fix }) : null;
308
509
  if (codexResolution) {
309
510
  statuses.push(codexResolution);
310
511
  }
311
512
 
312
- const codex = inspectCodex();
313
- if (codex.ok) {
314
- statuses.push(makeStatus("OK", "codex command is available", codex.version));
513
+ const installed = inspectAgent(agentType);
514
+ if (installed.ok) {
515
+ statuses.push(makeStatus("OK", `${agent.displayName} command is available`, installed.version));
315
516
  } else {
316
517
  statuses.push(
317
518
  makeStatus(
318
519
  "BLOCKED",
319
- "codex command is not usable",
320
- "Install or repair Codex with: npm install -g @openai/codex@latest",
520
+ `${agent.displayName} command is not usable`,
521
+ installed.detail || "Install or repair the selected agent command.",
321
522
  ),
322
523
  );
323
524
  }
324
525
 
325
- const skillInstallRoot = getSkillInstallRoot();
526
+ const skillInstallRoot = getSkillInstallRoot(agent.id);
326
527
  if (fix) {
327
528
  const result = await ensureSkillsInstalled();
328
529
  statuses.push(
329
530
  makeStatus(
330
531
  result.installed.length > 0 ? "FIXED" : "OK",
331
- "Codex skills are installed",
532
+ `${agent.displayName} skills are installed`,
332
533
  skillInstallRoot,
333
534
  ),
334
535
  );
335
536
  } else {
537
+ const receipt = await readInstallReceipt(skillInstallRoot, "skills");
336
538
  statuses.push(
337
539
  makeStatus(
338
540
  (await areSkillsInstalled()) ? "OK" : "WARN",
339
- "Codex skills install state",
340
- skillInstallRoot,
541
+ `${agent.displayName} skills install state`,
542
+ receipt
543
+ ? `${skillInstallRoot} (v${receipt.packageVersion}, receipt present)`
544
+ : `${skillInstallRoot} (receipt missing)`,
341
545
  ),
342
546
  );
343
547
  }
344
548
 
345
549
  const supportBundleRoot = getSupportBundleRoot();
346
- if (fix) {
550
+ if (agent.id !== "codex") {
551
+ statuses.push(
552
+ makeStatus("OK", "Codex support bundle", "not applicable to the selected agent surface"),
553
+ );
554
+ } else if (fix) {
347
555
  const result = await ensureSupportBundleInstalled();
348
556
  statuses.push(
349
557
  makeStatus(
@@ -353,11 +561,14 @@ async function runEnvironmentFlow({ fix, initMcp }) {
353
561
  ),
354
562
  );
355
563
  } else {
564
+ const receipt = await readInstallReceipt(supportBundleRoot, "support");
356
565
  statuses.push(
357
566
  makeStatus(
358
567
  (await isSupportBundleInstalled()) ? "OK" : "WARN",
359
568
  "support bundle install state",
360
- supportBundleRoot,
569
+ receipt
570
+ ? `${supportBundleRoot} (v${receipt.bundleVersion}, receipt present)`
571
+ : `${supportBundleRoot} (receipt missing)`,
361
572
  ),
362
573
  );
363
574
  }
@@ -386,35 +597,26 @@ async function runEnvironmentFlow({ fix, initMcp }) {
386
597
 
387
598
  statuses.push(await inspectGitMcpState({ fix, initMcp }));
388
599
  statuses.push(await inspectLocalCapabilityState({ fix }));
600
+ statuses.push(...(await inspectContextHealth()));
601
+ statuses.push(await inspectPluginInjectionState());
389
602
  return statuses;
390
603
  }
391
604
 
392
- function summarizeStatuses(statuses) {
393
- const hasBlocked = statuses.some((status) => status.kind === "BLOCKED");
394
- const hasWarn = statuses.some((status) => status.kind === "WARN");
395
- if (hasBlocked) {
396
- return "BLOCKED";
397
- }
398
- if (hasWarn) {
399
- return "READY_WITH_WARNINGS";
400
- }
401
- return "READY";
402
- }
403
-
404
605
  function printStatuses(title, statuses) {
405
- console.log(title);
406
- console.log("=".repeat(title.length));
407
- for (const status of statuses) {
408
- const label = status.kind.padEnd(7, " ");
409
- if (status.detail) {
410
- console.log(`${label} ${status.label}: ${status.detail}`);
411
- } else {
412
- console.log(`${label} ${status.label}`);
413
- }
606
+ if (process.stdout.isTTY) {
607
+ const result = summarizeDoctorStatuses(statuses);
608
+ console.log(title);
609
+ console.log("=".repeat(title.length));
610
+ console.log(renderCheckGrid(statuses));
611
+ console.log(`\nResult: ${result}`);
612
+ console.log(
613
+ result === "BLOCKED"
614
+ ? "Next: install or repair blocked prerequisites, then rerun `ma bootstrap`."
615
+ : "Next: start Codex or run `ma run '$maestro'`.",
616
+ );
617
+ return result;
414
618
  }
415
- const result = summarizeStatuses(statuses);
416
- console.log();
417
- console.log(`Result: ${result}`);
619
+ const result = printDoctorStatuses(title, statuses);
418
620
  if (result === "BLOCKED") {
419
621
  console.log("Next: install or repair blocked prerequisites, then rerun `ma bootstrap`.");
420
622
  } else if (result === "READY_WITH_WARNINGS") {
@@ -425,16 +627,20 @@ function printStatuses(title, statuses) {
425
627
  return result;
426
628
  }
427
629
 
428
- export async function runDoctor() {
630
+ export async function runDoctor({ json = false } = {}) {
429
631
  const statuses = await runEnvironmentFlow({ fix: false, initMcp: false });
632
+ const result = summarizeDoctorStatuses(statuses);
633
+ if (json) return { schemaVersion: "0.1.0", scope: "environment", result, statuses };
430
634
  return {
431
635
  statuses,
432
636
  result: printStatuses("Meta-Architect Doctor", statuses),
433
637
  };
434
638
  }
435
639
 
436
- export async function runBootstrap({ initMcp = false } = {}) {
640
+ export async function runBootstrap({ initMcp = false, json = false } = {}) {
437
641
  const statuses = await runEnvironmentFlow({ fix: true, initMcp });
642
+ const result = summarizeDoctorStatuses(statuses);
643
+ if (json) return { schemaVersion: "0.1.0", scope: "bootstrap", result, statuses };
438
644
  return {
439
645
  statuses,
440
646
  result: printStatuses("Meta-Architect Bootstrap", statuses),
package/src/build-gate.js CHANGED
@@ -26,10 +26,10 @@ export function evaluateBuildGate(releaseState) {
26
26
  });
27
27
  }
28
28
 
29
- if (!["LOCKED", "READY"].includes(releaseState.build_status)) {
29
+ if (!["LOCKED", "READY", "RUNNING"].includes(releaseState.build_status)) {
30
30
  blockers.push({
31
31
  field: "build_status",
32
- expected: "LOCKED or READY",
32
+ expected: "LOCKED, READY, or RUNNING",
33
33
  actual: releaseState.build_status,
34
34
  trigger: "$build",
35
35
  });