@jstn-sdk/ma 0.1.13 → 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 (253) hide show
  1. package/.agents/plugins/marketplace.json +0 -0
  2. package/.codex/agents/Architect.toml +1 -0
  3. package/.codex/agents/Auditor.toml +1 -0
  4. package/.codex/agents/Builder.toml +1 -0
  5. package/.codex/agents/Flow.toml +1 -0
  6. package/.codex/agents/Sage.toml +1 -0
  7. package/.codex/agents/Vibe.toml +1 -0
  8. package/.codex/hooks.json +12 -2
  9. package/.codex/prompts/enforcement.md +0 -0
  10. package/.codex/prompts/onboarding.md +6 -1
  11. package/.codex/prompts/release-rules.md +0 -0
  12. package/.codex/prompts/skill-contract.md +0 -0
  13. package/COVERAGE.md +7 -7
  14. package/DEMO.md +15 -6
  15. package/LICENSE +0 -0
  16. package/README.md +126 -793
  17. package/bin/ma.js +585 -97
  18. package/data/clone-data.ledger.json +0 -0
  19. package/data/clone-data.proof.json +0 -0
  20. package/data/clone-data.rvf +0 -0
  21. package/docs/README.md +8 -2
  22. package/docs/autonomous-tasks.md +46 -0
  23. package/docs/codex-integration.md +16 -0
  24. package/docs/getting-started.md +28 -4
  25. package/docs/installed-sdk.md +0 -0
  26. package/docs/mcp-setup.md +30 -1
  27. package/docs/qa/{release-issue-gates-0.1.13.json → release-issue-gates-0.14.0.json} +77 -77
  28. package/docs/qa/release-readiness-0.1.5.md +0 -0
  29. package/docs/qa/{release-readiness-0.1.13.md → release-readiness-0.14.0.md} +12 -12
  30. package/docs/quality.md +24 -0
  31. package/docs/reference/native-engineering-patterns.md +0 -0
  32. package/docs/reference/native-security-playbooks.md +0 -0
  33. package/docs/reference/native-source-selection.md +0 -0
  34. package/docs/reference/native-style-and-deslop.md +0 -0
  35. package/docs/release-spec.md +27 -14
  36. package/docs/skills.md +1 -1
  37. package/index.js +73 -0
  38. package/mcp/collections.json +0 -0
  39. package/mcp/fallback.json +0 -0
  40. package/mcp/local/code-intel.js +179 -41
  41. package/mcp/local/context.js +180 -0
  42. package/mcp/local/memory.js +17 -6
  43. package/mcp/local/playbooks.js +0 -0
  44. package/mcp/local/quality.js +39 -0
  45. package/mcp/local/state.js +7 -3
  46. package/mcp/local/team-run.js +8 -3
  47. package/mcp/local/trace.js +0 -0
  48. package/mcp/local-capabilities.json +9 -0
  49. package/mcp/native-playbooks.json +0 -0
  50. package/mcp/servers.json +0 -0
  51. package/package.json +26 -4
  52. package/plugins/meta-architect/.app.json +1 -1
  53. package/plugins/meta-architect/.codex-plugin/plugin.json +1 -1
  54. package/plugins/meta-architect/.mcp.json +1 -1
  55. package/plugins/meta-architect/README.md +2 -2
  56. package/plugins/meta-architect/obsidian/main.js +137 -4
  57. package/plugins/meta-architect/obsidian/manifest.json +1 -1
  58. package/plugins/meta-architect/obsidian/styles.css +0 -0
  59. package/plugins/meta-architect/skills/align/SKILL.md +0 -0
  60. package/plugins/meta-architect/skills/align/agents/openai.yaml +0 -0
  61. package/plugins/meta-architect/skills/align/references/shared-language.md +0 -0
  62. package/plugins/meta-architect/skills/arch/SKILL.md +0 -0
  63. package/plugins/meta-architect/skills/arch/agents/openai.yaml +0 -0
  64. package/plugins/meta-architect/skills/build/SKILL.md +0 -0
  65. package/plugins/meta-architect/skills/build/agents/openai.yaml +0 -0
  66. package/plugins/meta-architect/skills/cleanup/SKILL.md +0 -0
  67. package/plugins/meta-architect/skills/cleanup/agents/openai.yaml +0 -0
  68. package/plugins/meta-architect/skills/cleanup/references/style-and-deslop.md +0 -0
  69. package/plugins/meta-architect/skills/diagnose/SKILL.md +0 -0
  70. package/plugins/meta-architect/skills/diagnose/agents/openai.yaml +0 -0
  71. package/plugins/meta-architect/skills/flow/SKILL.md +0 -0
  72. package/plugins/meta-architect/skills/flow/agents/openai.yaml +0 -0
  73. package/plugins/meta-architect/skills/maestro/SKILL.md +0 -0
  74. package/plugins/meta-architect/skills/maestro/agents/openai.yaml +0 -0
  75. package/plugins/meta-architect/skills/maestro/references/core-release-rules.md +0 -0
  76. package/plugins/meta-architect/skills/maestro/references/native-ingest-map.md +0 -0
  77. package/plugins/meta-architect/skills/sage/SKILL.md +0 -0
  78. package/plugins/meta-architect/skills/sage/agents/openai.yaml +0 -0
  79. package/plugins/meta-architect/skills/sage/references/source-selection.md +0 -0
  80. package/plugins/meta-architect/skills/tdd/SKILL.md +0 -0
  81. package/plugins/meta-architect/skills/tdd/agents/openai.yaml +0 -0
  82. package/plugins/meta-architect/skills/vet/SKILL.md +0 -0
  83. package/plugins/meta-architect/skills/vet/agents/openai.yaml +0 -0
  84. package/plugins/meta-architect/skills/vet/references/security-playbooks.md +0 -0
  85. package/plugins/meta-architect/skills/vibe/SKILL.md +0 -0
  86. package/plugins/meta-architect/skills/vibe/agents/openai.yaml +0 -0
  87. package/schemas/autonomous-task-queue.schema.json +56 -0
  88. package/schemas/handoff-packet.schema.json +36 -0
  89. package/schemas/setup-receipt.schema.json +28 -0
  90. package/schemas/skill-frontmatter.schema.json +20 -0
  91. package/schemas/support-bundle.schema.json +37 -0
  92. package/schemas/task-contract.schema.json +31 -0
  93. package/scripts/active-autonomy-hook.mjs +141 -11
  94. package/scripts/biome-staged.js +0 -0
  95. package/scripts/build-linux-packages.mjs +7 -3
  96. package/scripts/cleanup-test-fixtures.sh +55 -0
  97. package/scripts/context-hydration-hook.mjs +89 -0
  98. package/scripts/demo-smoke.js +285 -0
  99. package/scripts/doctor.js +10 -8
  100. package/scripts/install.sh +33 -4
  101. package/scripts/install.sh.sha256 +1 -0
  102. package/scripts/linux-package-lib.mjs +0 -0
  103. package/scripts/linux-package-smoke.mjs +2 -2
  104. package/scripts/package-size-check.mjs +26 -0
  105. package/scripts/plugin-sync.js +83 -17
  106. package/scripts/postinstall.js +17 -10
  107. package/scripts/prepack.js +9 -0
  108. package/scripts/ralph/prompt.md +0 -0
  109. package/scripts/release-metadata.js +0 -0
  110. package/scripts/release-sync.js +72 -7
  111. package/scripts/release-verify.js +100 -7
  112. package/scripts/setup-npmrc.js +48 -23
  113. package/scripts/skills-install.js +9 -2
  114. package/scripts/skills-manifest.js +2 -21
  115. package/scripts/skills-pack.js +2 -2
  116. package/scripts/skills-validate.js +5 -55
  117. package/skills/align/SKILL.md +0 -0
  118. package/skills/align/agents/openai.yaml +0 -0
  119. package/skills/align/references/shared-language.md +0 -0
  120. package/skills/arch/SKILL.md +0 -0
  121. package/skills/arch/agents/openai.yaml +0 -0
  122. package/skills/build/SKILL.md +0 -0
  123. package/skills/build/agents/openai.yaml +0 -0
  124. package/skills/cleanup/SKILL.md +0 -0
  125. package/skills/cleanup/agents/openai.yaml +0 -0
  126. package/skills/cleanup/references/style-and-deslop.md +0 -0
  127. package/skills/diagnose/SKILL.md +0 -0
  128. package/skills/diagnose/agents/openai.yaml +0 -0
  129. package/skills/flow/SKILL.md +0 -0
  130. package/skills/flow/agents/openai.yaml +0 -0
  131. package/skills/index.json +0 -0
  132. package/skills/maestro/SKILL.md +0 -0
  133. package/skills/maestro/agents/openai.yaml +0 -0
  134. package/skills/maestro/references/core-release-rules.md +0 -0
  135. package/skills/maestro/references/native-ingest-map.md +0 -0
  136. package/skills/sage/SKILL.md +0 -0
  137. package/skills/sage/agents/openai.yaml +0 -0
  138. package/skills/sage/references/source-selection.md +0 -0
  139. package/skills/tdd/SKILL.md +0 -0
  140. package/skills/tdd/agents/openai.yaml +0 -0
  141. package/skills/vet/SKILL.md +0 -0
  142. package/skills/vet/agents/openai.yaml +0 -0
  143. package/skills/vet/references/security-playbooks.md +0 -0
  144. package/skills/vibe/SKILL.md +0 -0
  145. package/skills/vibe/agents/openai.yaml +0 -0
  146. package/sprint/00-idea.md +0 -0
  147. package/sprint/01-architecture.md +0 -0
  148. package/sprint/02-oss-evidence.md +0 -0
  149. package/sprint/03-logic.md +0 -0
  150. package/sprint/04-security.md +0 -0
  151. package/sprint/05-dx-ux.md +0 -0
  152. package/sprint/06-build-plan.md +0 -0
  153. package/sprint/07-release.md +0 -0
  154. package/src/agents.js +279 -0
  155. package/src/bootstrap.js +252 -63
  156. package/src/build-gate.js +0 -0
  157. package/src/codex-app-server.js +291 -0
  158. package/src/decision-log.js +0 -0
  159. package/src/fs-utils.js +175 -4
  160. package/src/launcher.js +24 -21
  161. package/src/mcp-config.js +9 -1
  162. package/src/mcp-live-client.js +140 -7
  163. package/src/paths.js +6 -1
  164. package/src/policy.js +2 -2
  165. package/src/prelaunch.js +189 -0
  166. package/src/quality/ai-quality-orchestrator.js +328 -0
  167. package/src/release-issue-gates.js +62 -0
  168. package/src/release-operations.js +62 -0
  169. package/src/release-state.js +0 -0
  170. package/src/runtime/active-autonomy-core.js +0 -0
  171. package/src/runtime/agent-compat.js +31 -0
  172. package/src/runtime/alignment-sentinel.js +0 -0
  173. package/src/runtime/architect-review.js +248 -10
  174. package/src/runtime/autonomous-tasks.js +408 -0
  175. package/src/runtime/build-readiness.js +0 -0
  176. package/src/runtime/code-graph-rehearse.js +0 -0
  177. package/src/runtime/codeburn-core.js +112 -0
  178. package/src/runtime/context-authority.js +40 -0
  179. package/src/runtime/context-economy-core.js +40 -0
  180. package/src/runtime/continuity-graph.js +201 -0
  181. package/src/runtime/continuity-notes.js +71 -26
  182. package/src/runtime/core-source-ingest.js +0 -0
  183. package/src/runtime/detached-provider.js +82 -14
  184. package/src/runtime/doctor-report.js +18 -0
  185. package/src/runtime/environment-awareness-core.js +0 -0
  186. package/src/runtime/exposure-catalog.js +0 -0
  187. package/src/runtime/graphify-core.js +167 -0
  188. package/src/runtime/guidance-stack.js +9 -2
  189. package/src/runtime/handoff-packets.js +92 -0
  190. package/src/runtime/headroom-core.js +104 -0
  191. package/src/runtime/helper-orchestration-core.js +0 -0
  192. package/src/runtime/hook-profiles.js +20 -0
  193. package/src/runtime/learning-loop-core.js +110 -4
  194. package/src/runtime/live-agent-verification.js +122 -0
  195. package/src/runtime/maestro-events.js +0 -0
  196. package/src/runtime/maestro-manager.js +0 -0
  197. package/src/runtime/maestro-output.js +58 -0
  198. package/src/runtime/maestro-state.js +0 -0
  199. package/src/runtime/managed-markdown.js +29 -0
  200. package/src/runtime/mcp-authority.js +147 -0
  201. package/src/runtime/mcp-policy.js +0 -0
  202. package/src/runtime/obsidian-integration-core.js +255 -17
  203. package/src/runtime/obsidian-plugin-bridge.js +344 -38
  204. package/src/runtime/orchestrator.js +0 -0
  205. package/src/runtime/pi-maestro-core.js +89 -0
  206. package/src/runtime/preferences.js +79 -0
  207. package/src/runtime/project-context.js +636 -0
  208. package/src/runtime/prompt-strategy-core.js +0 -0
  209. package/src/runtime/quorum-review.js +0 -0
  210. package/src/runtime/ralph-execution-core.js +0 -0
  211. package/src/runtime/redaction-gateway.js +218 -19
  212. package/src/runtime/runtime-state.js +94 -2
  213. package/src/runtime/schema-migrations.js +162 -0
  214. package/src/runtime/semantic-recording-core.js +0 -0
  215. package/src/runtime/signal-hooks.js +13 -0
  216. package/src/runtime/skills-registry-export.js +92 -8
  217. package/src/runtime/startup-path.js +0 -0
  218. package/src/runtime/task-contracts.js +83 -0
  219. package/src/runtime/universal-plugin-broker-core.js +373 -50
  220. package/src/runtime/workspace-intelligence-runtime.js +0 -0
  221. package/src/runtime/workspace-virtualizer.js +0 -0
  222. package/src/runtime/workspaces.js +0 -0
  223. package/src/runtime-artifacts.js +0 -0
  224. package/src/setup-lifecycle.js +359 -0
  225. package/src/skill-frontmatter.js +78 -0
  226. package/src/skill-installer.js +226 -71
  227. package/src/skills.js +297 -19
  228. package/src/state-sync.js +0 -0
  229. package/src/test-fixtures.js +543 -0
  230. package/src/tui/grid.js +67 -0
  231. package/src/tui/status-grid.js +23 -0
  232. package/support-bundle.json +114 -0
  233. package/templates/AGENTS.md +6 -2
  234. package/templates/catalog-manifest.json +0 -0
  235. package/templates/model-instructions/core.md +0 -0
  236. package/templates/model-instructions/release.md +0 -0
  237. package/templates/model-instructions/security.md +0 -0
  238. package/templates/quality/ai-quality-rules.yml +37 -0
  239. package/docs/assets/image/Screenshot(1).png +0 -0
  240. package/docs/assets/image/Screenshot(2).png +0 -0
  241. package/docs/assets/image/Screenshot(3).png +0 -0
  242. package/docs/assets/image/Screenshot(4).png +0 -0
  243. package/docs/assets/image/Screenshot(5).png +0 -0
  244. package/docs/assets/image/Screenshot(6).png +0 -0
  245. package/docs/assets/image/Screenshot(7).png +0 -0
  246. package/docs/assets/image/Screenshot(8).png +0 -0
  247. package/docs/assets/image/Screenshot(9).png +0 -0
  248. package/docs/assets/meta-architect-logo.png +0 -0
  249. package/docs/assets/meta-architect-logo.svg +0 -8
  250. package/docs/onboarding.md +0 -81
  251. package/docs/prompt-guidance-contract.md +0 -17
  252. package/docs/prompt-guidance-fragments/active-autonomy-core.md +0 -7
  253. 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
 
@@ -157,6 +335,7 @@ async function inspectLocalScaffold() {
157
335
  getRuntimeWritePath("context", "code-graph-rehearse.json"),
158
336
  getRuntimeWritePath("context", "core-source-ingest.json"),
159
337
  getRuntimeWritePath("context", "learning-loop-core.json"),
338
+ getRuntimeWritePath("context", "project-index.json"),
160
339
  getRuntimeWritePath("context", "obsidian-bridge.json"),
161
340
  getRuntimeWritePath("context", "obsidian-vault-index.json"),
162
341
  getRuntimeWritePath("context", "obsidian-vault-operations.json"),
@@ -177,7 +356,8 @@ async function inspectLocalScaffold() {
177
356
  getRuntimeWritePath("state", "manager-runs.json"),
178
357
  getRuntimeWritePath("state", "maestro-state.json"),
179
358
  getRuntimeWritePath("evidence", "semantic-receipts.json"),
180
- path.join(getRepoRoot(), "docs", "qa", "release-issue-gates-0.1.13.json"),
359
+ resolveReleaseIssueGates(getRepoRoot())?.path ??
360
+ path.join(getRepoRoot(), "docs", "qa", "release-issue-gates-missing.json"),
181
361
  path.join(getMcpRootPath(), "servers.json"),
182
362
  path.join(getMcpRootPath(), "local-capabilities.json"),
183
363
  ];
@@ -319,48 +499,59 @@ async function inspectLocalCapabilityState({ fix }) {
319
499
  }
320
500
 
321
501
  async function runEnvironmentFlow({ fix, initMcp }) {
322
- const statuses = [];
502
+ const statuses = [makeStatus("OK", "MCP client version", mcpClientVersion)];
503
+ statuses.push(inspectMcpBridge());
504
+ statuses.push(inspectArchitectReview());
323
505
 
324
- 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;
325
509
  if (codexResolution) {
326
510
  statuses.push(codexResolution);
327
511
  }
328
512
 
329
- const codex = inspectCodex();
330
- if (codex.ok) {
331
- 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));
332
516
  } else {
333
517
  statuses.push(
334
518
  makeStatus(
335
519
  "BLOCKED",
336
- "codex command is not usable",
337
- "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.",
338
522
  ),
339
523
  );
340
524
  }
341
525
 
342
- const skillInstallRoot = getSkillInstallRoot();
526
+ const skillInstallRoot = getSkillInstallRoot(agent.id);
343
527
  if (fix) {
344
528
  const result = await ensureSkillsInstalled();
345
529
  statuses.push(
346
530
  makeStatus(
347
531
  result.installed.length > 0 ? "FIXED" : "OK",
348
- "Codex skills are installed",
532
+ `${agent.displayName} skills are installed`,
349
533
  skillInstallRoot,
350
534
  ),
351
535
  );
352
536
  } else {
537
+ const receipt = await readInstallReceipt(skillInstallRoot, "skills");
353
538
  statuses.push(
354
539
  makeStatus(
355
540
  (await areSkillsInstalled()) ? "OK" : "WARN",
356
- "Codex skills install state",
357
- skillInstallRoot,
541
+ `${agent.displayName} skills install state`,
542
+ receipt
543
+ ? `${skillInstallRoot} (v${receipt.packageVersion}, receipt present)`
544
+ : `${skillInstallRoot} (receipt missing)`,
358
545
  ),
359
546
  );
360
547
  }
361
548
 
362
549
  const supportBundleRoot = getSupportBundleRoot();
363
- 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) {
364
555
  const result = await ensureSupportBundleInstalled();
365
556
  statuses.push(
366
557
  makeStatus(
@@ -370,11 +561,14 @@ async function runEnvironmentFlow({ fix, initMcp }) {
370
561
  ),
371
562
  );
372
563
  } else {
564
+ const receipt = await readInstallReceipt(supportBundleRoot, "support");
373
565
  statuses.push(
374
566
  makeStatus(
375
567
  (await isSupportBundleInstalled()) ? "OK" : "WARN",
376
568
  "support bundle install state",
377
- supportBundleRoot,
569
+ receipt
570
+ ? `${supportBundleRoot} (v${receipt.bundleVersion}, receipt present)`
571
+ : `${supportBundleRoot} (receipt missing)`,
378
572
  ),
379
573
  );
380
574
  }
@@ -403,35 +597,26 @@ async function runEnvironmentFlow({ fix, initMcp }) {
403
597
 
404
598
  statuses.push(await inspectGitMcpState({ fix, initMcp }));
405
599
  statuses.push(await inspectLocalCapabilityState({ fix }));
600
+ statuses.push(...(await inspectContextHealth()));
601
+ statuses.push(await inspectPluginInjectionState());
406
602
  return statuses;
407
603
  }
408
604
 
409
- function summarizeStatuses(statuses) {
410
- const hasBlocked = statuses.some((status) => status.kind === "BLOCKED");
411
- const hasWarn = statuses.some((status) => status.kind === "WARN");
412
- if (hasBlocked) {
413
- return "BLOCKED";
414
- }
415
- if (hasWarn) {
416
- return "READY_WITH_WARNINGS";
417
- }
418
- return "READY";
419
- }
420
-
421
605
  function printStatuses(title, statuses) {
422
- console.log(title);
423
- console.log("=".repeat(title.length));
424
- for (const status of statuses) {
425
- const label = status.kind.padEnd(7, " ");
426
- if (status.detail) {
427
- console.log(`${label} ${status.label}: ${status.detail}`);
428
- } else {
429
- console.log(`${label} ${status.label}`);
430
- }
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;
431
618
  }
432
- const result = summarizeStatuses(statuses);
433
- console.log();
434
- console.log(`Result: ${result}`);
619
+ const result = printDoctorStatuses(title, statuses);
435
620
  if (result === "BLOCKED") {
436
621
  console.log("Next: install or repair blocked prerequisites, then rerun `ma bootstrap`.");
437
622
  } else if (result === "READY_WITH_WARNINGS") {
@@ -442,16 +627,20 @@ function printStatuses(title, statuses) {
442
627
  return result;
443
628
  }
444
629
 
445
- export async function runDoctor() {
630
+ export async function runDoctor({ json = false } = {}) {
446
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 };
447
634
  return {
448
635
  statuses,
449
636
  result: printStatuses("Meta-Architect Doctor", statuses),
450
637
  };
451
638
  }
452
639
 
453
- export async function runBootstrap({ initMcp = false } = {}) {
640
+ export async function runBootstrap({ initMcp = false, json = false } = {}) {
454
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 };
455
644
  return {
456
645
  statuses,
457
646
  result: printStatuses("Meta-Architect Bootstrap", statuses),
package/src/build-gate.js CHANGED
File without changes