@jstn-sdk/ma 0.1.13 → 0.14.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 (259) 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 +9 -9
  14. package/DEMO.md +15 -6
  15. package/LICENSE +0 -0
  16. package/README.md +127 -784
  17. package/bin/ma.js +591 -105
  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/assets/banner.png +0 -0
  23. package/docs/autonomous-tasks.md +46 -0
  24. package/docs/codex-integration.md +16 -0
  25. package/docs/getting-started.md +32 -8
  26. package/docs/installed-sdk.md +0 -0
  27. package/docs/mcp-setup.md +30 -1
  28. package/docs/qa/{release-issue-gates-0.1.13.json → release-issue-gates-0.14.1.json} +77 -77
  29. package/docs/qa/release-readiness-0.1.5.md +0 -0
  30. package/docs/qa/{release-readiness-0.1.13.md → release-readiness-0.14.1.md} +12 -12
  31. package/docs/quality.md +24 -0
  32. package/docs/reference/native-engineering-patterns.md +0 -0
  33. package/docs/reference/native-security-playbooks.md +0 -0
  34. package/docs/reference/native-source-selection.md +0 -0
  35. package/docs/reference/native-style-and-deslop.md +0 -0
  36. package/docs/release-spec.md +27 -14
  37. package/docs/skills.md +1 -1
  38. package/docs/vendor-plugin-publishing.md +49 -0
  39. package/index.js +73 -0
  40. package/mcp/collections.json +0 -0
  41. package/mcp/fallback.json +0 -0
  42. package/mcp/local/code-intel.js +185 -41
  43. package/mcp/local/context.js +180 -0
  44. package/mcp/local/memory.js +17 -6
  45. package/mcp/local/playbooks.js +0 -0
  46. package/mcp/local/quality.js +39 -0
  47. package/mcp/local/state.js +7 -3
  48. package/mcp/local/team-run.js +8 -3
  49. package/mcp/local/trace.js +0 -0
  50. package/mcp/local-capabilities.json +9 -0
  51. package/mcp/native-playbooks.json +0 -0
  52. package/mcp/servers.json +0 -0
  53. package/package.json +37 -6
  54. package/plugins/meta-architect/.app.json +1 -1
  55. package/plugins/meta-architect/.claude-plugin/plugin.json +12 -0
  56. package/plugins/meta-architect/.codex-plugin/plugin.json +1 -1
  57. package/plugins/meta-architect/.mcp.json +1 -1
  58. package/plugins/meta-architect/README.md +14 -2
  59. package/plugins/meta-architect/obsidian/main.js +137 -4
  60. package/plugins/meta-architect/obsidian/manifest.json +1 -1
  61. package/plugins/meta-architect/obsidian/styles.css +0 -0
  62. package/plugins/meta-architect/skills/align/SKILL.md +0 -0
  63. package/plugins/meta-architect/skills/align/agents/openai.yaml +0 -0
  64. package/plugins/meta-architect/skills/align/references/shared-language.md +0 -0
  65. package/plugins/meta-architect/skills/arch/SKILL.md +0 -0
  66. package/plugins/meta-architect/skills/arch/agents/openai.yaml +0 -0
  67. package/plugins/meta-architect/skills/build/SKILL.md +0 -0
  68. package/plugins/meta-architect/skills/build/agents/openai.yaml +0 -0
  69. package/plugins/meta-architect/skills/cleanup/SKILL.md +0 -0
  70. package/plugins/meta-architect/skills/cleanup/agents/openai.yaml +0 -0
  71. package/plugins/meta-architect/skills/cleanup/references/style-and-deslop.md +0 -0
  72. package/plugins/meta-architect/skills/diagnose/SKILL.md +0 -0
  73. package/plugins/meta-architect/skills/diagnose/agents/openai.yaml +0 -0
  74. package/plugins/meta-architect/skills/flow/SKILL.md +0 -0
  75. package/plugins/meta-architect/skills/flow/agents/openai.yaml +0 -0
  76. package/plugins/meta-architect/skills/maestro/SKILL.md +17 -1
  77. package/plugins/meta-architect/skills/maestro/agents/openai.yaml +0 -0
  78. package/plugins/meta-architect/skills/maestro/references/core-release-rules.md +2 -2
  79. package/plugins/meta-architect/skills/maestro/references/native-ingest-map.md +0 -0
  80. package/plugins/meta-architect/skills/sage/SKILL.md +0 -0
  81. package/plugins/meta-architect/skills/sage/agents/openai.yaml +0 -0
  82. package/plugins/meta-architect/skills/sage/references/source-selection.md +0 -0
  83. package/plugins/meta-architect/skills/tdd/SKILL.md +0 -0
  84. package/plugins/meta-architect/skills/tdd/agents/openai.yaml +0 -0
  85. package/plugins/meta-architect/skills/vet/SKILL.md +0 -0
  86. package/plugins/meta-architect/skills/vet/agents/openai.yaml +0 -0
  87. package/plugins/meta-architect/skills/vet/references/security-playbooks.md +0 -0
  88. package/plugins/meta-architect/skills/vibe/SKILL.md +0 -0
  89. package/plugins/meta-architect/skills/vibe/agents/openai.yaml +0 -0
  90. package/schemas/autonomous-task-queue.schema.json +58 -0
  91. package/schemas/handoff-packet.schema.json +36 -0
  92. package/schemas/setup-receipt.schema.json +28 -0
  93. package/schemas/skill-frontmatter.schema.json +20 -0
  94. package/schemas/support-bundle.schema.json +37 -0
  95. package/schemas/task-contract.schema.json +31 -0
  96. package/scripts/active-autonomy-hook.mjs +141 -11
  97. package/scripts/biome-staged.js +0 -0
  98. package/scripts/build-linux-packages.mjs +7 -3
  99. package/scripts/cleanup-test-fixtures.sh +55 -0
  100. package/scripts/context-hydration-hook.mjs +89 -0
  101. package/scripts/demo-smoke.js +285 -0
  102. package/scripts/doctor.js +10 -8
  103. package/scripts/install.sh +33 -4
  104. package/scripts/install.sh.sha256 +1 -0
  105. package/scripts/linux-package-lib.mjs +0 -0
  106. package/scripts/linux-package-smoke.mjs +2 -2
  107. package/scripts/package-size-check.mjs +26 -0
  108. package/scripts/plugin-build.js +314 -0
  109. package/scripts/plugin-publish.js +77 -0
  110. package/scripts/plugin-sync.js +83 -17
  111. package/scripts/prepack.js +9 -0
  112. package/scripts/ralph/prompt.md +0 -0
  113. package/scripts/release-metadata.js +0 -0
  114. package/scripts/release-sync.js +83 -7
  115. package/scripts/release-verify.js +131 -7
  116. package/scripts/setup-npmrc.js +48 -23
  117. package/scripts/skills-install.js +9 -2
  118. package/scripts/skills-manifest.js +2 -21
  119. package/scripts/skills-pack.js +2 -2
  120. package/scripts/skills-validate.js +5 -55
  121. package/skills/align/SKILL.md +0 -0
  122. package/skills/align/agents/openai.yaml +0 -0
  123. package/skills/align/references/shared-language.md +0 -0
  124. package/skills/arch/SKILL.md +0 -0
  125. package/skills/arch/agents/openai.yaml +0 -0
  126. package/skills/build/SKILL.md +0 -0
  127. package/skills/build/agents/openai.yaml +0 -0
  128. package/skills/cleanup/SKILL.md +0 -0
  129. package/skills/cleanup/agents/openai.yaml +0 -0
  130. package/skills/cleanup/references/style-and-deslop.md +0 -0
  131. package/skills/diagnose/SKILL.md +0 -0
  132. package/skills/diagnose/agents/openai.yaml +0 -0
  133. package/skills/flow/SKILL.md +0 -0
  134. package/skills/flow/agents/openai.yaml +0 -0
  135. package/skills/index.json +0 -0
  136. package/skills/maestro/SKILL.md +17 -1
  137. package/skills/maestro/agents/openai.yaml +0 -0
  138. package/skills/maestro/references/core-release-rules.md +2 -2
  139. package/skills/maestro/references/native-ingest-map.md +0 -0
  140. package/skills/sage/SKILL.md +0 -0
  141. package/skills/sage/agents/openai.yaml +0 -0
  142. package/skills/sage/references/source-selection.md +0 -0
  143. package/skills/tdd/SKILL.md +0 -0
  144. package/skills/tdd/agents/openai.yaml +0 -0
  145. package/skills/vet/SKILL.md +0 -0
  146. package/skills/vet/agents/openai.yaml +0 -0
  147. package/skills/vet/references/security-playbooks.md +0 -0
  148. package/skills/vibe/SKILL.md +0 -0
  149. package/skills/vibe/agents/openai.yaml +0 -0
  150. package/sprint/00-idea.md +0 -0
  151. package/sprint/01-architecture.md +0 -0
  152. package/sprint/02-oss-evidence.md +0 -0
  153. package/sprint/03-logic.md +0 -0
  154. package/sprint/04-security.md +0 -0
  155. package/sprint/05-dx-ux.md +0 -0
  156. package/sprint/06-build-plan.md +0 -0
  157. package/sprint/07-release.md +2 -2
  158. package/src/agents.js +281 -0
  159. package/src/bootstrap.js +272 -65
  160. package/src/build-gate.js +0 -0
  161. package/src/codex-app-server.js +291 -0
  162. package/src/decision-log.js +0 -0
  163. package/src/fs-utils.js +175 -4
  164. package/src/launcher.js +26 -23
  165. package/src/mcp-config.js +9 -1
  166. package/src/mcp-live-client.js +141 -8
  167. package/src/paths.js +6 -1
  168. package/src/policy.js +2 -2
  169. package/src/prelaunch.js +223 -0
  170. package/src/process-utils.js +62 -0
  171. package/src/quality/ai-quality-orchestrator.js +328 -0
  172. package/src/release-issue-gates.js +62 -0
  173. package/src/release-operations.js +72 -0
  174. package/src/release-state.js +0 -0
  175. package/src/runtime/active-autonomy-core.js +0 -0
  176. package/src/runtime/agent-compat.js +31 -0
  177. package/src/runtime/alignment-sentinel.js +0 -0
  178. package/src/runtime/architect-review.js +249 -11
  179. package/src/runtime/autonomous-tasks.js +585 -0
  180. package/src/runtime/build-readiness.js +0 -0
  181. package/src/runtime/code-graph-rehearse.js +0 -0
  182. package/src/runtime/codeburn-core.js +118 -0
  183. package/src/runtime/context-authority.js +40 -0
  184. package/src/runtime/context-economy-core.js +40 -0
  185. package/src/runtime/continuity-graph.js +201 -0
  186. package/src/runtime/continuity-notes.js +71 -26
  187. package/src/runtime/core-source-ingest.js +2 -2
  188. package/src/runtime/detached-provider.js +90 -13
  189. package/src/runtime/doctor-report.js +18 -0
  190. package/src/runtime/environment-awareness-core.js +0 -0
  191. package/src/runtime/exposure-catalog.js +0 -0
  192. package/src/runtime/graphify-core.js +167 -0
  193. package/src/runtime/guidance-stack.js +9 -2
  194. package/src/runtime/handoff-packets.js +92 -0
  195. package/src/runtime/headroom-core.js +104 -0
  196. package/src/runtime/helper-orchestration-core.js +0 -0
  197. package/src/runtime/hook-profiles.js +20 -0
  198. package/src/runtime/learning-loop-core.js +110 -4
  199. package/src/runtime/live-agent-verification.js +122 -0
  200. package/src/runtime/maestro-events.js +0 -0
  201. package/src/runtime/maestro-manager.js +0 -0
  202. package/src/runtime/maestro-output.js +58 -0
  203. package/src/runtime/maestro-state.js +0 -0
  204. package/src/runtime/managed-markdown.js +29 -0
  205. package/src/runtime/mcp-authority.js +147 -0
  206. package/src/runtime/mcp-policy.js +0 -0
  207. package/src/runtime/obsidian-integration-core.js +255 -17
  208. package/src/runtime/obsidian-plugin-bridge.js +344 -38
  209. package/src/runtime/orchestrator.js +0 -0
  210. package/src/runtime/pi-maestro-core.js +89 -0
  211. package/src/runtime/preferences.js +79 -0
  212. package/src/runtime/project-context.js +636 -0
  213. package/src/runtime/prompt-strategy-core.js +0 -0
  214. package/src/runtime/quorum-review.js +0 -0
  215. package/src/runtime/ralph-execution-core.js +0 -0
  216. package/src/runtime/redaction-gateway.js +218 -19
  217. package/src/runtime/runtime-state.js +94 -2
  218. package/src/runtime/schema-migrations.js +162 -0
  219. package/src/runtime/semantic-recording-core.js +0 -0
  220. package/src/runtime/signal-hooks.js +13 -0
  221. package/src/runtime/skills-registry-export.js +96 -8
  222. package/src/runtime/startup-path.js +0 -0
  223. package/src/runtime/task-contracts.js +83 -0
  224. package/src/runtime/universal-plugin-broker-core.js +373 -50
  225. package/src/runtime/workspace-intelligence-runtime.js +0 -0
  226. package/src/runtime/workspace-virtualizer.js +0 -0
  227. package/src/runtime/workspaces.js +0 -0
  228. package/src/runtime-artifacts.js +0 -0
  229. package/src/setup-lifecycle.js +359 -0
  230. package/src/skill-frontmatter.js +78 -0
  231. package/src/skill-installer.js +226 -71
  232. package/src/skills.js +309 -31
  233. package/src/state-sync.js +0 -0
  234. package/src/test-fixtures.js +543 -0
  235. package/src/tui/grid.js +67 -0
  236. package/src/tui/status-grid.js +23 -0
  237. package/support-bundle.json +114 -0
  238. package/templates/AGENTS.md +6 -2
  239. package/templates/catalog-manifest.json +0 -0
  240. package/templates/model-instructions/core.md +0 -0
  241. package/templates/model-instructions/release.md +0 -0
  242. package/templates/model-instructions/security.md +0 -0
  243. package/templates/quality/ai-quality-rules.yml +37 -0
  244. package/docs/assets/image/Screenshot(1).png +0 -0
  245. package/docs/assets/image/Screenshot(2).png +0 -0
  246. package/docs/assets/image/Screenshot(3).png +0 -0
  247. package/docs/assets/image/Screenshot(4).png +0 -0
  248. package/docs/assets/image/Screenshot(5).png +0 -0
  249. package/docs/assets/image/Screenshot(6).png +0 -0
  250. package/docs/assets/image/Screenshot(7).png +0 -0
  251. package/docs/assets/image/Screenshot(8).png +0 -0
  252. package/docs/assets/image/Screenshot(9).png +0 -0
  253. package/docs/assets/meta-architect-logo.png +0 -0
  254. package/docs/assets/meta-architect-logo.svg +0 -8
  255. package/docs/onboarding.md +0 -81
  256. package/docs/prompt-guidance-contract.md +0 -17
  257. package/docs/prompt-guidance-fragments/active-autonomy-core.md +0 -7
  258. package/docs/skills-publishing.md +0 -255
  259. package/scripts/postinstall.js +0 -23
package/bin/ma.js CHANGED
@@ -1,20 +1,43 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ import { spawnSync } from "node:child_process";
4
+ import fs from "node:fs/promises";
5
+ import path from "node:path";
6
+ import { resolveAgentCommand } from "../src/agents.js";
3
7
  import { runBootstrap, runDoctor } from "../src/bootstrap.js";
4
8
  import { appendDecision } from "../src/decision-log.js";
5
- import { runCodex, shouldDelegateToCodex } from "../src/launcher.js";
9
+ import { runAgent, shouldDelegateToCodex } from "../src/launcher.js";
10
+ import { getRepoRoot, packageRoot } from "../src/paths.js";
6
11
  import {
7
12
  canMarkBuildDone,
8
13
  rejectsDirectProdPromotion,
9
14
  validateMergeTarget,
10
15
  validateReleaseOrigin,
11
16
  } from "../src/policy.js";
17
+ import { choosePrelaunchInstall, installPrelaunchSelection } from "../src/prelaunch.js";
18
+ import { executeGitOperation, inspectGitOperation } from "../src/release-operations.js";
12
19
  import { loadReleaseState } from "../src/release-state.js";
20
+ import {
21
+ compileAgentIntegrations,
22
+ detectAgentEnvironments,
23
+ listAgentCompatAdapters,
24
+ validateAgentIntegrations,
25
+ } from "../src/runtime/agent-compat.js";
13
26
  import { runExternalArchitectReview } from "../src/runtime/architect-review.js";
27
+ import {
28
+ cancelAutonomousTask,
29
+ enqueueAutonomousTasks,
30
+ loadTaskQueue,
31
+ parseTaskInput,
32
+ runAutonomousTasks,
33
+ } from "../src/runtime/autonomous-tasks.js";
14
34
  import { evaluateRuntimeBuildReadiness } from "../src/runtime/build-readiness.js";
15
35
  import { ingestCoreSources } from "../src/runtime/core-source-ingest.js";
36
+ import { verifyLiveAgentMatrix } from "../src/runtime/live-agent-verification.js";
37
+ import { createMaestroView, formatMaestroView } from "../src/runtime/maestro-output.js";
16
38
  import {
17
39
  appendObsidianOperationReceipt,
40
+ configureObsidianVault,
18
41
  createObsidianNote,
19
42
  deleteObsidianNote,
20
43
  listObsidianNotes,
@@ -23,7 +46,11 @@ import {
23
46
  writeObsidianVaultIndex,
24
47
  } from "../src/runtime/obsidian-integration-core.js";
25
48
  import { installObsidianPlugin } from "../src/runtime/obsidian-plugin-bridge.js";
49
+ import { refreshProjectIndex } from "../src/runtime/project-context.js";
50
+ import { purgeRedactionVault } from "../src/runtime/redaction-gateway.js";
26
51
  import { createRuntimeSummary, loadRuntimeSnapshot } from "../src/runtime/runtime-state.js";
52
+ import { migrateSchemas } from "../src/runtime/schema-migrations.js";
53
+ import { rollbackSetup } from "../src/setup-lifecycle.js";
27
54
  import {
28
55
  ensureSkillsInstalled,
29
56
  ensureSupportBundleInstalled,
@@ -42,55 +69,286 @@ import {
42
69
  runVibe,
43
70
  } from "../src/skills.js";
44
71
  import { syncStatusUpdates } from "../src/state-sync.js";
72
+ import { renderReleaseGrid } from "../src/tui/status-grid.js";
45
73
 
46
74
  function printUsage() {
47
- console.error("Secondary helper commands:");
48
- console.error(" ma");
49
- console.error(" ma bootstrap [--init-mcp]");
50
- console.error(" ma doctor");
51
- console.error(" ma setup");
52
- console.error(" ma init");
53
- console.error(' ma idea "..."');
54
- console.error(" ma skills");
55
- console.error(" ma core-ingest [--refresh]");
56
- console.error(" ma obsidian-index [vault-path]");
57
- console.error(
75
+ console.log("Meta-Architect CLI");
76
+ console.log("Usage: ma <command> [options]");
77
+ console.log("\nCommands:");
78
+ console.log(" ma");
79
+ console.log(" ma bootstrap [--init-mcp]");
80
+ console.log(" ma doctor [--json]");
81
+ console.log(" ma welcome");
82
+ console.log(" ma context refresh [--full|--json]");
83
+ console.log(" ma migrate [--dry-run|--rollback|--json]");
84
+ console.log(" ma setup [--obsidian-vault <path>]");
85
+ console.log(" first interactive launch: choose project or user scope and detected hosts");
86
+ console.log(" ma setup --rollback");
87
+ console.log(" ma setup --rollback --dry-run");
88
+ console.log(" ma uninstall");
89
+ console.log(" ma init");
90
+ console.log(' ma idea "..."');
91
+ console.log(" ma skills");
92
+ console.log(" ma core-ingest [--refresh]");
93
+ console.log(" ma agent-compat adapters|detect|compile|validate [path]");
94
+ console.log(
95
+ " ma obsidian configure|list|read|create|update|delete|plugin-install [vault-path] [note-path] [content]",
96
+ );
97
+ console.log(" ma obsidian-index [vault-path]");
98
+ console.log(
58
99
  " ma obsidian list|read|create|update|delete|plugin-install <vault-path> [note-path] [content]",
59
100
  );
60
- console.error(" ma sdk-path");
61
- console.error(" ma status [--maestro-view]");
62
- console.error(" ma verify --architect");
63
- console.error(" ma run $maestro|$arch|$sage|$flow|$vet|$vibe|$build [--auto-heal] [--parallel]");
64
- console.error(" ma merge <source-branch> <target-branch>");
65
- console.error(" ma release <origin-branch> <target-branch>");
101
+ console.log(" ma sdk-path");
102
+ console.log(" ma status [--maestro-view]");
103
+ console.log(" ma verify --architect|--agents-live [--json]");
104
+ console.log(" ma run $maestro|$arch|$sage|$flow|$vet|$vibe|$build [--auto-heal] [--parallel]");
105
+ console.log(
106
+ " ma task add <goal> [--priority <level>] [--depends-on <id,...>] [--label <name>] [--deadline <ISO>]",
107
+ );
108
+ console.log(" ma task bulk <file|-> [--format json|yaml]");
109
+ console.log(" ma task list [--json]");
110
+ console.log(" ma task run [--concurrency <n>] [--max-tasks <n>] [--json]");
111
+ console.log(" ma task cancel <id> [reason]");
112
+ console.log(" ma hook active-autonomy|context-hydration");
113
+ console.log(" ma redaction purge [--dry-run]");
114
+ console.log(" ma merge <source-branch> <target-branch> [--dry-run|--execute]");
115
+ console.log(" ma release <origin-branch> <target-branch> [--dry-run|--execute]");
116
+ }
117
+
118
+ async function printVersion() {
119
+ const metadata = JSON.parse(await fs.readFile(path.join(packageRoot, "package.json"), "utf8"));
120
+ console.log(metadata.version);
66
121
  }
67
122
 
68
- async function printStatus(releaseState) {
123
+ function printCommandHelp(command) {
124
+ const help = {
125
+ setup: "ma setup [--json] [--obsidian-vault <path>] [--rollback] [--dry-run]",
126
+ doctor: "ma doctor [--json]",
127
+ status: "ma status [--json] [--maestro-view]",
128
+ context: "ma context refresh [--full] [--json]",
129
+ migrate: "ma migrate [--dry-run|--rollback] [--json]",
130
+ merge: "ma merge <source-branch> <target-branch> [--dry-run|--execute]",
131
+ release: "ma release <origin-branch> <target-branch> [--dry-run|--execute]",
132
+ "agent-compat": "ma agent-compat adapters|detect|compile|validate [path]",
133
+ verify: "ma verify --architect|--agents-live [--json]",
134
+ task: "ma task add|bulk|list|run|cancel ...",
135
+ };
136
+ console.log(help[command] ?? `No command-specific help is available for '${command}'.`);
137
+ }
138
+
139
+ function taskOption(rest, name) {
140
+ const value = getOptionValue(rest, name);
141
+ return value === undefined ? undefined : value;
142
+ }
143
+
144
+ async function runTaskCommand(rest) {
145
+ const action = rest[0] ?? "list";
146
+ if (action === "add") {
147
+ const flags = new Set([
148
+ "--priority",
149
+ "--depends-on",
150
+ "--label",
151
+ "--deadline",
152
+ "--id",
153
+ "--vendor",
154
+ ]);
155
+ const goal = rest
156
+ .slice(1)
157
+ .filter((value, index, values) => {
158
+ if (index > 0 && flags.has(values[index - 1])) return false;
159
+ return !value.startsWith("--") && !flags.has(value);
160
+ })
161
+ .join(" ");
162
+ if (!goal) throw new Error("Usage: ma task add <goal>");
163
+ const task = {
164
+ id: taskOption(rest, "--id"),
165
+ goal,
166
+ priority: taskOption(rest, "--priority"),
167
+ dependencies: taskOption(rest, "--depends-on")?.split(",").filter(Boolean),
168
+ labels: taskOption(rest, "--label")?.split(",").filter(Boolean),
169
+ deadline: taskOption(rest, "--deadline"),
170
+ vendor: taskOption(rest, "--vendor"),
171
+ };
172
+ const [added] = await enqueueAutonomousTasks(task);
173
+ console.log(
174
+ rest.includes("--json")
175
+ ? JSON.stringify(added, null, 2)
176
+ : `Queued ${added.id}: ${added.goal}`,
177
+ );
178
+ return;
179
+ }
180
+ if (action === "bulk") {
181
+ const source = rest[1];
182
+ if (!source) throw new Error("Usage: ma task bulk <file|-> [--format json|yaml]");
183
+ const raw =
184
+ source === "-"
185
+ ? await new Promise((resolve, reject) => {
186
+ const chunks = [];
187
+ process.stdin.on("data", (chunk) => chunks.push(chunk));
188
+ process.stdin.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
189
+ process.stdin.on("error", reject);
190
+ })
191
+ : await fs.readFile(source, "utf8");
192
+ const format =
193
+ taskOption(rest, "--format") ??
194
+ (source.endsWith(".yaml") || source.endsWith(".yml") ? "yaml" : "json");
195
+ const added = await enqueueAutonomousTasks(await parseTaskInput(raw, format));
196
+ console.log(
197
+ rest.includes("--json") ? JSON.stringify(added, null, 2) : `Queued ${added.length} task(s)`,
198
+ );
199
+ return;
200
+ }
201
+ if (action === "list") {
202
+ const queue = await loadTaskQueue();
203
+ console.log(JSON.stringify(queue.tasks, null, 2));
204
+ return;
205
+ }
206
+ if (action === "cancel") {
207
+ if (!rest[1]) throw new Error("Usage: ma task cancel <id> [reason]");
208
+ const task = await cancelAutonomousTask(
209
+ rest[1],
210
+ rest
211
+ .slice(2)
212
+ .filter((value) => !value.startsWith("--"))
213
+ .join(" ") || undefined,
214
+ );
215
+ console.log(rest.includes("--json") ? JSON.stringify(task, null, 2) : `Cancelled ${task.id}`);
216
+ return;
217
+ }
218
+ if (action === "run") {
219
+ const result = await runAutonomousTasks({
220
+ concurrency: Number(taskOption(rest, "--concurrency") ?? 1),
221
+ maxTasks: Number(taskOption(rest, "--max-tasks") ?? Infinity),
222
+ });
223
+ if (rest.includes("--json")) console.log(JSON.stringify(result, null, 2));
224
+ else
225
+ console.log(
226
+ `Autonomous tasks: ${Object.entries(result.summary)
227
+ .map(([key, value]) => `${key}=${value}`)
228
+ .join(" ")}`,
229
+ );
230
+ if (result.summary.failed > 0 || result.summary.blocked > 0) process.exitCode = 1;
231
+ return;
232
+ }
233
+ throw new Error(`Unknown task action: ${action}`);
234
+ }
235
+
236
+ function getOptionValue(args, name) {
237
+ const index = args.indexOf(name);
238
+ return index === -1 ? undefined : args[index + 1];
239
+ }
240
+
241
+ function runHook(name) {
242
+ const scripts = {
243
+ "active-autonomy": "active-autonomy-hook.mjs",
244
+ "context-hydration": "context-hydration-hook.mjs",
245
+ };
246
+ const script = scripts[name];
247
+ if (!script) throw new Error(`Unknown hook: ${name}`);
248
+ const result = spawnSync(process.execPath, [path.join(packageRoot, "scripts", script)], {
249
+ cwd: process.cwd(),
250
+ env: process.env,
251
+ stdio: "inherit",
252
+ });
253
+ if (result.error) throw result.error;
254
+ process.exitCode = result.status ?? 1;
255
+ }
256
+
257
+ async function readObsidianContent(args, fallback) {
258
+ const filePath = getOptionValue(args, "--file");
259
+ if (filePath) return fs.readFile(filePath, "utf8");
260
+ if (args.includes("--stdin")) {
261
+ const chunks = [];
262
+ for await (const chunk of process.stdin) chunks.push(chunk);
263
+ return Buffer.concat(chunks).toString("utf8");
264
+ }
265
+ return fallback;
266
+ }
267
+
268
+ async function runAgentCompatCommand(rest) {
269
+ const [action = "adapters", firstArg, secondArg] = rest;
270
+ if (action === "adapters") {
271
+ console.log(JSON.stringify(listAgentCompatAdapters(), null, 2));
272
+ return;
273
+ }
274
+
275
+ if (action === "detect") {
276
+ console.log(JSON.stringify(await detectAgentEnvironments(firstArg ?? process.cwd()), null, 2));
277
+ return;
278
+ }
279
+
280
+ if (action === "validate") {
281
+ console.log(
282
+ JSON.stringify(await validateAgentIntegrations(firstArg ?? process.cwd()), null, 2),
283
+ );
284
+ return;
285
+ }
286
+
287
+ if (action === "compile") {
288
+ if (!firstArg) {
289
+ throw new Error("Usage: ma agent-compat compile <manifest.json> [output]");
290
+ }
291
+ const manifest = JSON.parse(await fs.readFile(firstArg, "utf8"));
292
+ const result = await compileAgentIntegrations(manifest, {
293
+ output: secondArg ?? process.cwd(),
294
+ });
295
+ console.log(JSON.stringify(result, null, 2));
296
+ if (!result.success) process.exitCode = 1;
297
+ return;
298
+ }
299
+
300
+ throw new Error(`Unknown Agent Compat action: ${action}`);
301
+ }
302
+
303
+ async function printStatus(releaseState, { json = false } = {}) {
304
+ const runtimeSummary = createRuntimeSummary(await loadRuntimeSnapshot());
305
+ const evaluation = evaluateRuntimeBuildReadiness(releaseState, runtimeSummary);
306
+ const payload = {
307
+ schemaVersion: "0.1.0",
308
+ scope: "status",
309
+ release: releaseState,
310
+ runtime: runtimeSummary,
311
+ nextTriggers: evaluation.nextTriggers,
312
+ };
313
+ if (json) {
314
+ console.log(JSON.stringify(payload, null, 2));
315
+ return payload;
316
+ }
69
317
  console.log("Meta-Architect Status");
70
318
  console.log("=====================");
71
- console.log(`Idea: ${releaseState.idea_status}`);
72
- console.log(`Architecture: ${releaseState.architecture_status}`);
73
- console.log(`Evidence: ${releaseState.evidence_status}`);
74
- console.log(`Logic: ${releaseState.logic_status}`);
75
- console.log(`Security: ${releaseState.security_status}`);
76
- console.log(`Experience: ${releaseState.experience_status}`);
77
- console.log(`Build: ${releaseState.build_status}`);
319
+ if (process.stdout.isTTY) {
320
+ console.log(renderReleaseGrid(releaseState, evaluation.nextTriggers));
321
+ }
322
+ if (process.stdout.isTTY) {
323
+ console.log(
324
+ `Core source snapshots: ${runtimeSummary.coreSourceIngestCount} (${runtimeSummary.coreSourceIngestStatus})`,
325
+ );
326
+ console.log(`Obsidian vault notes: ${runtimeSummary.obsidianVaultNoteCount}`);
327
+ console.log(`Obsidian CRUD receipts: ${runtimeSummary.obsidianVaultOperationCount}`);
328
+ }
329
+ if (!process.stdout.isTTY) {
330
+ console.log(`Idea: ${releaseState.idea_status}`);
331
+ console.log(`Architecture: ${releaseState.architecture_status}`);
332
+ console.log(`Evidence: ${releaseState.evidence_status}`);
333
+ console.log(`Logic: ${releaseState.logic_status}`);
334
+ console.log(`Security: ${releaseState.security_status}`);
335
+ console.log(`Experience: ${releaseState.experience_status}`);
336
+ console.log(`Build: ${releaseState.build_status}`);
78
337
 
79
- const runtimeSummary = createRuntimeSummary(await loadRuntimeSnapshot());
80
- console.log(
81
- `Core source snapshots: ${runtimeSummary.coreSourceIngestCount} (${runtimeSummary.coreSourceIngestStatus})`,
82
- );
83
- console.log(`Obsidian vault notes: ${runtimeSummary.obsidianVaultNoteCount}`);
84
- console.log(`Obsidian CRUD receipts: ${runtimeSummary.obsidianVaultOperationCount}`);
338
+ console.log(
339
+ `Core source snapshots: ${runtimeSummary.coreSourceIngestCount} (${runtimeSummary.coreSourceIngestStatus})`,
340
+ );
341
+ console.log(`Obsidian vault notes: ${runtimeSummary.obsidianVaultNoteCount}`);
342
+ console.log(`Obsidian CRUD receipts: ${runtimeSummary.obsidianVaultOperationCount}`);
343
+ }
85
344
  if (
86
345
  releaseState.build_status === "DONE" &&
87
346
  releaseState.merge_status !== "MERGED_TO_DEVELOPMENT"
88
347
  ) {
89
348
  console.log("Next allowed triggers:");
90
- console.log("ma merge <feature/*> development");
349
+ console.log("ma merge <feature/*> dev");
91
350
  return;
92
351
  }
93
- const evaluation = evaluateRuntimeBuildReadiness(releaseState, runtimeSummary);
94
352
  console.log("Next allowed triggers:");
95
353
  const triggers = evaluation.nextTriggers;
96
354
  if (triggers.length === 0) {
@@ -103,41 +361,11 @@ async function printStatus(releaseState) {
103
361
  }
104
362
  }
105
363
 
106
- async function printMaestroView() {
107
- const snapshot = await loadRuntimeSnapshot();
108
- const trackEntries = Object.entries(snapshot.maestroState.runtime_tracks);
109
- console.log("Maestro View");
110
- console.log("============");
111
- console.log(`Global status: ${snapshot.maestroState.global_status}`);
112
- console.log(`Orchestration id: ${snapshot.maestroState.orchestration_id ?? "not started"}`);
113
- console.log("Runtime tracks:");
114
- if (trackEntries.length === 0) {
115
- console.log("- none");
116
- } else {
117
- for (const [trackId, track] of trackEntries) {
118
- console.log(`- ${trackId}: ${track.active_gate} [${track.status}]`);
119
- if (Array.isArray(track.blockers) && track.blockers.length > 0) {
120
- console.log(` blockers: ${track.blockers.join("; ")}`);
121
- }
122
- }
123
- }
124
-
125
- const lockEntries = Object.entries(snapshot.maestroState.downstream_lock_table);
126
- console.log("Downstream locks:");
127
- if (lockEntries.length === 0) {
128
- console.log("- none");
129
- return;
130
- }
131
-
132
- for (const [gate, lock] of lockEntries) {
133
- console.log(`- ${gate}: ${lock.is_locked ? "locked" : "unlocked"}`);
134
- if (Array.isArray(lock.locked_by) && lock.locked_by.length > 0) {
135
- console.log(` locked by: ${lock.locked_by.join(", ")}`);
136
- }
137
- if (lock.unlock_criteria) {
138
- console.log(` unlock criteria: ${lock.unlock_criteria}`);
139
- }
140
- }
364
+ async function printMaestroView({ json = false, snapshot = null } = {}) {
365
+ const currentSnapshot = snapshot ?? (await loadRuntimeSnapshot());
366
+ const view = createMaestroView(currentSnapshot.maestroState);
367
+ if (json) return view;
368
+ process.stdout.write(formatMaestroView(view));
141
369
  }
142
370
 
143
371
  async function runBuild() {
@@ -174,20 +402,39 @@ async function runBuild() {
174
402
  }
175
403
 
176
404
  console.log("Build gate completed the bounded execution substep.");
177
- console.log("Next step: ma merge <feature/*> development");
405
+ console.log("Next step: ma merge <feature/*> dev");
178
406
  }
179
407
 
180
- async function runMerge(sourceBranch, targetBranch) {
408
+ async function runMerge(sourceBranch, targetBranch, mode = "approval") {
181
409
  const releaseState = await loadReleaseState();
182
410
 
183
411
  if (!validateMergeTarget(sourceBranch, targetBranch)) {
184
- throw new Error("Merge policy violation: only feature/* -> development is allowed");
412
+ throw new Error("Merge policy violation: only feature/* -> dev is allowed");
185
413
  }
186
414
 
187
415
  if (!canMarkBuildDone(releaseState)) {
188
416
  throw new Error("Merge is blocked until build status is DONE");
189
417
  }
190
418
 
419
+ const operation = await inspectGitOperation(getRepoRoot(), sourceBranch, targetBranch);
420
+ if (!operation.available || !operation.sourceExists || !operation.clean) {
421
+ throw new Error(`Git preflight failed: ${operation.blockers.join("; ")}`);
422
+ }
423
+ if (mode === "dry-run") {
424
+ console.log(
425
+ `DRY RUN: approval state unchanged; would execute ${operation.display} on ${targetBranch}`,
426
+ );
427
+ return;
428
+ }
429
+ if (mode === "execute") {
430
+ if (operation.currentBranch !== targetBranch) {
431
+ throw new Error(
432
+ `Git execute requires current branch ${targetBranch}; found ${operation.currentBranch || "detached HEAD"}`,
433
+ );
434
+ }
435
+ await executeGitOperation(getRepoRoot(), operation);
436
+ }
437
+
191
438
  await appendDecision({
192
439
  kind: "merge",
193
440
  decision: `Merge approved from ${sourceBranch} to ${targetBranch}`,
@@ -201,26 +448,47 @@ async function runMerge(sourceBranch, targetBranch) {
201
448
  merge_status: "MERGED_TO_DEVELOPMENT",
202
449
  });
203
450
 
204
- console.log(`Merge approved: ${sourceBranch} -> ${targetBranch}`);
451
+ console.log(
452
+ mode === "execute"
453
+ ? `Merge executed and approved: ${sourceBranch} -> ${targetBranch}`
454
+ : `Merge approved only: ${sourceBranch} -> ${targetBranch}; no Git command executed. Run \`${operation.display}\` explicitly or use --execute.`,
455
+ );
205
456
  }
206
457
 
207
- async function runRelease(originBranch, targetBranch) {
458
+ async function runRelease(originBranch, targetBranch, mode = "approval") {
208
459
  const releaseState = await loadReleaseState();
209
460
 
210
- if (targetBranch !== "prod") {
211
- throw new Error("Release policy violation: target branch must be prod");
461
+ if (targetBranch !== "main") {
462
+ throw new Error("Release policy violation: target branch must be main");
212
463
  }
213
464
 
214
465
  if (rejectsDirectProdPromotion(originBranch) || !validateReleaseOrigin(originBranch)) {
215
- throw new Error(
216
- "Release policy violation: only development or approved release/* can promote to prod",
217
- );
466
+ throw new Error("Release policy violation: only dev or approved release/* can promote to main");
218
467
  }
219
468
 
220
469
  if (releaseState.merge_status !== "MERGED_TO_DEVELOPMENT") {
221
470
  throw new Error("Release is blocked until merge_status is MERGED_TO_DEVELOPMENT");
222
471
  }
223
472
 
473
+ const operation = await inspectGitOperation(getRepoRoot(), originBranch, targetBranch);
474
+ if (!operation.available || !operation.sourceExists || !operation.clean) {
475
+ throw new Error(`Git preflight failed: ${operation.blockers.join("; ")}`);
476
+ }
477
+ if (mode === "dry-run") {
478
+ console.log(
479
+ `DRY RUN: approval state unchanged; would execute ${operation.display} on ${targetBranch}`,
480
+ );
481
+ return;
482
+ }
483
+ if (mode === "execute") {
484
+ if (operation.currentBranch !== targetBranch) {
485
+ throw new Error(
486
+ `Git execute requires current branch ${targetBranch}; found ${operation.currentBranch || "detached HEAD"}`,
487
+ );
488
+ }
489
+ await executeGitOperation(getRepoRoot(), operation);
490
+ }
491
+
224
492
  await appendDecision({
225
493
  kind: "release",
226
494
  decision: `Release approved from ${originBranch} to ${targetBranch}`,
@@ -234,7 +502,20 @@ async function runRelease(originBranch, targetBranch) {
234
502
  release_status: "SHIPPED_TO_PROD",
235
503
  });
236
504
 
237
- console.log(`Release approved: ${originBranch} -> ${targetBranch}`);
505
+ console.log(
506
+ mode === "execute"
507
+ ? `Release executed and approved: ${originBranch} -> ${targetBranch}`
508
+ : `Release approved only: ${originBranch} -> ${targetBranch}; no Git command executed. Run \`${operation.display}\` explicitly or use --execute.`,
509
+ );
510
+ }
511
+
512
+ function resolveGitMode(args) {
513
+ const modes = [
514
+ args.includes("--dry-run") && "dry-run",
515
+ args.includes("--execute") && "execute",
516
+ ].filter(Boolean);
517
+ if (modes.length > 1) throw new Error("Choose only one of --dry-run or --execute");
518
+ return modes[0] ?? "approval";
238
519
  }
239
520
 
240
521
  async function main() {
@@ -242,40 +523,179 @@ async function main() {
242
523
  const args = process.argv.slice(2);
243
524
  const arg = rest[0];
244
525
 
526
+ if (args[0] === "--help" || args[0] === "-h" || args[0] === "help") {
527
+ if (args[0] === "help" && args[1]) printCommandHelp(args[1]);
528
+ else printUsage();
529
+ return;
530
+ }
531
+ if (args[0] === "--version" || args[0] === "-v" || args[0] === "version") {
532
+ await printVersion();
533
+ return;
534
+ }
535
+ if (args.includes("--help")) {
536
+ printCommandHelp(command);
537
+ return;
538
+ }
539
+
540
+ if (command === "hook") {
541
+ runHook(arg);
542
+ return;
543
+ }
544
+
545
+ if (command === "task") {
546
+ await runTaskCommand(rest);
547
+ return;
548
+ }
549
+
550
+ if (command === "redaction" && rest[0] === "purge") {
551
+ const result = await purgeRedactionVault({ dryRun: rest.includes("--dry-run") });
552
+ console.log(JSON.stringify(result, null, 2));
553
+ return;
554
+ }
555
+
245
556
  if (shouldDelegateToCodex(args)) {
246
- await Promise.all([ensureSkillsInstalled(), ensureSupportBundleInstalled()]);
247
- process.exitCode = runCodex(args);
557
+ const selection = await choosePrelaunchInstall();
558
+ const agentType = process.env.MA_AGENT || selection?.targets?.[0] || "codex";
559
+ if (selection) {
560
+ await installPrelaunchSelection(selection);
561
+ } else if (process.env.MA_AGENT) {
562
+ await installPrelaunchSelection({
563
+ schemaVersion: "0.1.0",
564
+ scope: "project",
565
+ targets: [agentType],
566
+ });
567
+ } else {
568
+ await Promise.all([ensureSkillsInstalled(), ensureSupportBundleInstalled()]);
569
+ }
570
+ if (!resolveAgentCommand(agentType)) {
571
+ console.log(
572
+ `Installed ${agentType} compatibility files; no executable host command is registered, so delegation was skipped.`,
573
+ );
574
+ return;
575
+ }
576
+ process.exitCode = runAgent(args, agentType);
248
577
  return;
249
578
  }
250
579
 
251
580
  if (command === "setup") {
252
- const created = await runInit();
581
+ const jsonOutput = args.includes("--json");
582
+ if (args.includes("--rollback")) {
583
+ const result = await rollbackSetup(getRepoRoot(), { dryRun: args.includes("--dry-run") });
584
+ if (jsonOutput) console.log(JSON.stringify(result, null, 2));
585
+ else console.log(`${result.status}: ${result.removed.length} artifact(s) removed`);
586
+ return;
587
+ }
588
+ const report = await runInit({
589
+ refresh: args.includes("--refresh"),
590
+ obsidianVault: getOptionValue(args, "--obsidian-vault"),
591
+ });
592
+ if (
593
+ [...report.directories, ...report.files].some(
594
+ (entry) => entry.status === "warning" || entry.status === "warned" || entry.fatal === true,
595
+ )
596
+ ) {
597
+ process.exitCode = 1;
598
+ }
599
+ if (jsonOutput) {
600
+ console.log(JSON.stringify(report, null, 2));
601
+ return;
602
+ }
603
+
253
604
  console.log("meta-architect setup");
254
605
  console.log("====================");
255
- for (const item of created) {
256
- console.log(`ready: ${item}`);
606
+ for (const entry of [...report.directories, ...report.files]) {
607
+ const suffix = entry.warning ? `: ${entry.warning}` : "";
608
+ console.log(`${entry.status}: ${entry.path}${suffix}`);
609
+ }
610
+ for (const integration of report.integrations ?? []) {
611
+ console.log(`${integration.status}: ${integration.vaultPath}/${integration.notePath}`);
612
+ }
613
+ if (report.context) {
614
+ console.log(
615
+ `context: ${report.context.path} (${report.context.status}, ${report.context.completeness})`,
616
+ );
617
+ if (report.context.unknown.length > 0) {
618
+ console.log(`context unknown: ${report.context.unknown.join(", ")}`);
619
+ }
620
+ }
621
+ console.log("next: ma doctor | ma context refresh | ma setup --rollback");
622
+ return;
623
+ }
624
+
625
+ if (command === "welcome") {
626
+ const outcome = await runDoctor();
627
+ console.log("Meta-Architect welcome");
628
+ console.log("=======================");
629
+ console.log("Context: .ma/context/project-index.json");
630
+ console.log(
631
+ "Agents read: .ma/context/agent-brief.md, .ma/context/project-index.json, AGENTS.md",
632
+ );
633
+ console.log("Next: ma doctor | ma context refresh | ma setup --rollback");
634
+ process.exitCode = outcome.result === "BLOCKED" ? 1 : 0;
635
+ return;
636
+ }
637
+
638
+ if (command === "context" && rest[0] === "refresh") {
639
+ const result = await refreshProjectIndex(getRepoRoot(), {
640
+ mode: rest.includes("--full") ? "full" : "incremental",
641
+ });
642
+ const receipt = await fs.readFile(`${getRepoRoot()}/.ma/context/refresh-receipt.json`, "utf8");
643
+ if (rest.includes("--json")) console.log(receipt);
644
+ else {
645
+ console.log(`context refresh: ${result.freshness.status}`);
646
+ console.log(`changed: ${result.freshness.changedFiles.length}`);
647
+ console.log(`affected: ${JSON.parse(receipt).affectedArtifacts.join(", ") || "none"}`);
257
648
  }
258
649
  return;
259
650
  }
260
651
 
652
+ if (command === "uninstall") {
653
+ const result = await rollbackSetup(getRepoRoot());
654
+ console.log(JSON.stringify(result, null, 2));
655
+ return;
656
+ }
657
+
261
658
  if (command === "bootstrap") {
262
- const outcome = await runBootstrap({ initMcp: rest.includes("--init-mcp") });
659
+ const outcome = await runBootstrap({
660
+ initMcp: rest.includes("--init-mcp"),
661
+ json: rest.includes("--json"),
662
+ });
663
+ if (rest.includes("--json")) console.log(JSON.stringify(outcome, null, 2));
263
664
  process.exitCode = outcome.result === "BLOCKED" ? 1 : 0;
264
665
  return;
265
666
  }
266
667
 
267
668
  if (command === "doctor") {
268
- const outcome = await runDoctor();
669
+ const outcome = await runDoctor({ json: rest.includes("--json") });
670
+ if (rest.includes("--json")) console.log(JSON.stringify(outcome, null, 2));
269
671
  process.exitCode = outcome.result === "BLOCKED" ? 1 : 0;
270
672
  return;
271
673
  }
272
674
 
675
+ if (command === "migrate") {
676
+ const result = await migrateSchemas(getRepoRoot(), {
677
+ dryRun: rest.includes("--dry-run"),
678
+ rollback: rest.includes("--rollback"),
679
+ });
680
+ if (rest.includes("--json")) console.log(JSON.stringify(result, null, 2));
681
+ else
682
+ console.log(
683
+ `${result.status}: ${(result.migrated ?? result.restored ?? []).length} artifact(s)`,
684
+ );
685
+ process.exitCode = result.status === "failed" ? 1 : 0;
686
+ return;
687
+ }
688
+
273
689
  if (command === "init") {
274
- const created = await runInit();
690
+ const report = await runInit({
691
+ refresh: args.includes("--refresh"),
692
+ obsidianVault: getOptionValue(args, "--obsidian-vault"),
693
+ });
275
694
  console.log("meta-architect init");
276
695
  console.log("===================");
277
- for (const item of created) {
278
- console.log(`ready: ${item}`);
696
+ for (const entry of [...report.directories, ...report.files]) {
697
+ const suffix = entry.warning ? `: ${entry.warning}` : "";
698
+ console.log(`${entry.status}: ${entry.path}${suffix}`);
279
699
  }
280
700
  return;
281
701
  }
@@ -309,13 +729,14 @@ async function main() {
309
729
  return;
310
730
  }
311
731
 
732
+ if (command === "agent-compat") {
733
+ await runAgentCompatCommand(rest);
734
+ return;
735
+ }
736
+
312
737
  if (command === "obsidian-index") {
313
- const vaultPath = arg ?? process.env.MA_OBSIDIAN_VAULT;
314
- if (!vaultPath) {
315
- throw new Error("Obsidian vault path required: ma obsidian-index <vault-path>");
316
- }
317
738
  await runInit();
318
- const index = await writeObsidianVaultIndex({ vaultPath });
739
+ const index = await writeObsidianVaultIndex({ vaultPath: arg });
319
740
  console.log("Obsidian vault indexed");
320
741
  console.log(`Vault: ${index.vault_path}`);
321
742
  console.log(`Notes: ${index.note_count}`);
@@ -326,12 +747,17 @@ async function main() {
326
747
 
327
748
  if (command === "obsidian") {
328
749
  const [action, vaultPath, notePath, ...contentParts] = rest;
329
- if (!action || !vaultPath) {
750
+ if (!action) {
330
751
  throw new Error(
331
752
  "Usage: ma obsidian list|read|create|update|delete|plugin-install <vault-path> [note-path] [content]",
332
753
  );
333
754
  }
334
755
  await runInit();
756
+ if (action === "configure") {
757
+ const config = await configureObsidianVault(vaultPath);
758
+ console.log(`Obsidian vault configured: ${config.vaultPath}`);
759
+ return;
760
+ }
335
761
  if (action === "plugin-install") {
336
762
  const receipt = await installObsidianPlugin({ vaultPath });
337
763
  await appendObsidianOperationReceipt({
@@ -368,10 +794,21 @@ async function main() {
368
794
  return;
369
795
  }
370
796
  if (action === "create") {
797
+ const content = await readObsidianContent(rest, contentParts.join(" "));
798
+ if (rest.includes("--dry-run")) {
799
+ console.log(
800
+ JSON.stringify(
801
+ { schemaVersion: "0.1.0", status: "would_create", notePath, content },
802
+ null,
803
+ 2,
804
+ ),
805
+ );
806
+ return;
807
+ }
371
808
  const receipt = await createObsidianNote({
372
809
  vaultPath,
373
810
  notePath,
374
- content: contentParts.join(" "),
811
+ content,
375
812
  });
376
813
  await appendObsidianOperationReceipt(receipt);
377
814
  await writeObsidianVaultIndex({ vaultPath });
@@ -379,10 +816,27 @@ async function main() {
379
816
  return;
380
817
  }
381
818
  if (action === "update") {
819
+ const content = await readObsidianContent(rest, contentParts.join(" "));
820
+ if (rest.includes("--dry-run")) {
821
+ const existing = await readObsidianNote({ vaultPath, notePath });
822
+ console.log(
823
+ JSON.stringify(
824
+ {
825
+ schemaVersion: "0.1.0",
826
+ status: existing.content === content ? "unchanged" : "would_update",
827
+ notePath,
828
+ content,
829
+ },
830
+ null,
831
+ 2,
832
+ ),
833
+ );
834
+ return;
835
+ }
382
836
  const receipt = await updateObsidianNote({
383
837
  vaultPath,
384
838
  notePath,
385
- content: contentParts.join(" "),
839
+ content,
386
840
  });
387
841
  await appendObsidianOperationReceipt(receipt);
388
842
  await writeObsidianVaultIndex({ vaultPath });
@@ -406,9 +860,23 @@ async function main() {
406
860
 
407
861
  if (command === "status") {
408
862
  const releaseState = await loadReleaseState();
409
- await printStatus(releaseState);
410
- if (rest.includes("--maestro-view")) {
411
- await printMaestroView();
863
+ const json = rest.includes("--json");
864
+ const snapshot = rest.includes("--maestro-view") ? await loadRuntimeSnapshot() : null;
865
+ if (json && snapshot) {
866
+ const runtime = createRuntimeSummary(snapshot);
867
+ const evaluation = evaluateRuntimeBuildReadiness(releaseState, runtime);
868
+ const status = {
869
+ schemaVersion: "0.1.0",
870
+ scope: "status",
871
+ release: releaseState,
872
+ runtime,
873
+ nextTriggers: evaluation.nextTriggers,
874
+ maestro: createMaestroView(snapshot.maestroState),
875
+ };
876
+ process.stdout.write(`${JSON.stringify(status, null, 2)}\n`);
877
+ } else {
878
+ await printStatus(releaseState, { json });
879
+ if (snapshot) await printMaestroView({ snapshot });
412
880
  }
413
881
  return;
414
882
  }
@@ -425,15 +893,33 @@ async function main() {
425
893
  return;
426
894
  }
427
895
 
896
+ if (command === "verify" && rest.includes("--agents-live")) {
897
+ const report = await verifyLiveAgentMatrix({ cwd: process.cwd() });
898
+ if (rest.includes("--json")) {
899
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
900
+ } else {
901
+ console.log(`Agent live verification: ${report.target_count} targets`);
902
+ console.log(`Runtime verified: ${report.runtime_verified}`);
903
+ console.log(`Distribution only: ${report.distribution_only}`);
904
+ console.log(`Blocked: ${report.blocked}`);
905
+ for (const result of report.results) {
906
+ console.log(
907
+ `- ${result.target}: ${result.status}${result.reason ? ` (${result.reason})` : ""}`,
908
+ );
909
+ }
910
+ }
911
+ return;
912
+ }
913
+
428
914
  if (command === "merge") {
429
- const [sourceBranch, targetBranch] = rest;
430
- await runMerge(sourceBranch, targetBranch);
915
+ const [sourceBranch, targetBranch] = rest.filter((arg) => !arg.startsWith("--"));
916
+ await runMerge(sourceBranch, targetBranch, resolveGitMode(rest));
431
917
  return;
432
918
  }
433
919
 
434
920
  if (command === "release") {
435
- const [originBranch, targetBranch] = rest;
436
- await runRelease(originBranch, targetBranch);
921
+ const [originBranch, targetBranch] = rest.filter((arg) => !arg.startsWith("--"));
922
+ await runRelease(originBranch, targetBranch, resolveGitMode(rest));
437
923
  return;
438
924
  }
439
925