@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.
- package/.codex/agents/Architect.toml +1 -2
- package/.codex/agents/Auditor.toml +1 -2
- package/.codex/agents/Builder.toml +1 -2
- package/.codex/agents/Flow.toml +1 -2
- package/.codex/agents/Sage.toml +1 -2
- package/.codex/agents/Vibe.toml +1 -2
- package/.codex/hooks.json +24 -13
- package/.codex/prompts/enforcement.md +4 -0
- package/.codex/prompts/onboarding.md +6 -1
- package/.codex/prompts/release-rules.md +0 -0
- package/.codex/prompts/skill-contract.md +4 -0
- package/COVERAGE.md +211 -0
- package/DEMO.md +274 -0
- package/LICENSE +0 -0
- package/README.md +132 -656
- package/bin/ma.js +748 -55
- package/data/clone-data.ledger.json +41 -0
- package/data/clone-data.proof.json +50 -0
- package/data/clone-data.rvf +37 -0
- package/docs/README.md +10 -1
- package/docs/autonomous-tasks.md +46 -0
- package/docs/codex-integration.md +16 -0
- package/docs/getting-started.md +62 -22
- package/docs/mcp-setup.md +64 -0
- package/docs/qa/release-issue-gates-0.14.0.json +644 -0
- package/docs/qa/release-readiness-0.1.5.md +1 -1
- package/docs/qa/{release-readiness-0.1.12.md → release-readiness-0.14.0.md} +25 -9
- package/docs/quality.md +24 -0
- package/docs/reference/native-security-playbooks.md +6 -0
- package/docs/reference/native-source-selection.md +6 -0
- package/docs/release-spec.md +39 -10
- package/docs/skills.md +14 -1
- package/index.js +295 -2
- package/mcp/collections.json +23 -6
- package/mcp/fallback.json +0 -0
- package/mcp/local/code-intel.js +179 -41
- package/mcp/local/context.js +180 -0
- package/mcp/local/memory.js +17 -6
- package/mcp/local/quality.js +39 -0
- package/mcp/local/state.js +7 -3
- package/mcp/local/team-run.js +56 -4
- package/mcp/local-capabilities.json +9 -0
- package/mcp/servers.json +24 -0
- package/package.json +29 -4
- package/plugins/meta-architect/.app.json +1 -1
- package/plugins/meta-architect/.codex-plugin/plugin.json +1 -1
- package/plugins/meta-architect/.mcp.json +1 -1
- package/plugins/meta-architect/README.md +8 -1
- package/plugins/meta-architect/obsidian/main.js +534 -0
- package/plugins/meta-architect/obsidian/manifest.json +9 -0
- package/plugins/meta-architect/obsidian/styles.css +7 -0
- package/plugins/meta-architect/skills/arch/SKILL.md +2 -0
- package/plugins/meta-architect/skills/build/SKILL.md +3 -0
- package/plugins/meta-architect/skills/flow/SKILL.md +2 -0
- package/plugins/meta-architect/skills/sage/SKILL.md +2 -0
- package/plugins/meta-architect/skills/sage/references/source-selection.md +8 -0
- package/plugins/meta-architect/skills/vet/SKILL.md +2 -0
- package/plugins/meta-architect/skills/vet/references/security-playbooks.md +7 -0
- package/plugins/meta-architect/skills/vibe/SKILL.md +2 -0
- package/schemas/autonomous-task-queue.schema.json +56 -0
- package/schemas/handoff-packet.schema.json +36 -0
- package/schemas/setup-receipt.schema.json +28 -0
- package/schemas/skill-frontmatter.schema.json +20 -0
- package/schemas/support-bundle.schema.json +37 -0
- package/schemas/task-contract.schema.json +31 -0
- package/scripts/active-autonomy-hook.mjs +226 -0
- package/scripts/build-linux-packages.mjs +7 -3
- package/scripts/cleanup-test-fixtures.sh +55 -0
- package/scripts/context-hydration-hook.mjs +89 -0
- package/scripts/demo-smoke.js +285 -0
- package/scripts/doctor.js +27 -12
- package/scripts/install.sh +57 -0
- package/scripts/install.sh.sha256 +1 -0
- package/scripts/linux-package-smoke.mjs +2 -2
- package/scripts/package-size-check.mjs +26 -0
- package/scripts/plugin-sync.js +83 -17
- package/scripts/postinstall.js +17 -10
- package/scripts/prepack.js +9 -0
- package/scripts/ralph/prompt.md +35 -0
- package/scripts/release-sync.js +72 -7
- package/scripts/release-verify.js +260 -2
- package/scripts/setup-npmrc.js +48 -23
- package/scripts/skills-install.js +9 -2
- package/scripts/skills-manifest.js +2 -21
- package/scripts/skills-pack.js +2 -2
- package/scripts/skills-validate.js +5 -55
- package/skills/arch/SKILL.md +2 -0
- package/skills/build/SKILL.md +3 -0
- package/skills/flow/SKILL.md +2 -0
- package/skills/index.json +0 -0
- package/skills/sage/SKILL.md +2 -0
- package/skills/sage/references/source-selection.md +8 -0
- package/skills/vet/SKILL.md +2 -0
- package/skills/vet/references/security-playbooks.md +7 -0
- package/skills/vibe/SKILL.md +2 -0
- package/sprint/00-idea.md +0 -0
- package/sprint/01-architecture.md +0 -0
- package/sprint/02-oss-evidence.md +0 -0
- package/sprint/03-logic.md +0 -0
- package/sprint/04-security.md +0 -0
- package/sprint/05-dx-ux.md +0 -0
- package/sprint/06-build-plan.md +0 -0
- package/sprint/07-release.md +0 -0
- package/src/agents.js +279 -0
- package/src/bootstrap.js +268 -62
- package/src/build-gate.js +2 -2
- package/src/codex-app-server.js +291 -0
- package/src/decision-log.js +0 -0
- package/src/fs-utils.js +175 -4
- package/src/launcher.js +28 -21
- package/src/mcp-config.js +9 -1
- package/src/mcp-live-client.js +422 -3
- package/src/paths.js +10 -1
- package/src/policy.js +3 -3
- package/src/prelaunch.js +189 -0
- package/src/quality/ai-quality-orchestrator.js +328 -0
- package/src/release-issue-gates.js +252 -0
- package/src/release-operations.js +62 -0
- package/src/release-state.js +0 -0
- package/src/runtime/active-autonomy-core.js +208 -0
- package/src/runtime/agent-compat.js +31 -0
- package/src/runtime/alignment-sentinel.js +165 -0
- package/src/runtime/architect-review.js +326 -0
- package/src/runtime/autonomous-tasks.js +408 -0
- package/src/runtime/build-readiness.js +28 -4
- package/src/runtime/code-graph-rehearse.js +113 -0
- package/src/runtime/codeburn-core.js +112 -0
- package/src/runtime/context-authority.js +40 -0
- package/src/runtime/context-economy-core.js +316 -0
- package/src/runtime/continuity-graph.js +201 -0
- package/src/runtime/continuity-notes.js +71 -26
- package/src/runtime/core-source-ingest.js +379 -0
- package/src/runtime/detached-provider.js +142 -0
- package/src/runtime/doctor-report.js +18 -0
- package/src/runtime/environment-awareness-core.js +460 -0
- package/src/runtime/exposure-catalog.js +276 -0
- package/src/runtime/graphify-core.js +167 -0
- package/src/runtime/guidance-stack.js +9 -2
- package/src/runtime/handoff-packets.js +92 -0
- package/src/runtime/headroom-core.js +104 -0
- package/src/runtime/helper-orchestration-core.js +307 -0
- package/src/runtime/hook-profiles.js +20 -0
- package/src/runtime/learning-loop-core.js +344 -0
- package/src/runtime/live-agent-verification.js +122 -0
- package/src/runtime/maestro-events.js +18 -0
- package/src/runtime/maestro-manager.js +19 -0
- package/src/runtime/maestro-output.js +58 -0
- package/src/runtime/maestro-state.js +125 -0
- package/src/runtime/managed-markdown.js +29 -0
- package/src/runtime/mcp-authority.js +147 -0
- package/src/runtime/mcp-policy.js +192 -0
- package/src/runtime/obsidian-integration-core.js +1089 -0
- package/src/runtime/obsidian-plugin-bridge.js +1045 -0
- package/src/runtime/pi-maestro-core.js +89 -0
- package/src/runtime/preferences.js +79 -0
- package/src/runtime/project-context.js +636 -0
- package/src/runtime/prompt-strategy-core.js +230 -0
- package/src/runtime/quorum-review.js +90 -0
- package/src/runtime/ralph-execution-core.js +217 -0
- package/src/runtime/redaction-gateway.js +373 -0
- package/src/runtime/runtime-state.js +935 -2
- package/src/runtime/schema-migrations.js +162 -0
- package/src/runtime/semantic-recording-core.js +147 -0
- package/src/runtime/signal-hooks.js +28 -0
- package/src/runtime/skills-registry-export.js +754 -0
- package/src/runtime/task-contracts.js +83 -0
- package/src/runtime/universal-plugin-broker-core.js +898 -0
- package/src/runtime/workspace-intelligence-runtime.js +674 -0
- package/src/runtime/workspace-virtualizer.js +102 -0
- package/src/runtime-artifacts.js +225 -62
- package/src/setup-lifecycle.js +359 -0
- package/src/skill-frontmatter.js +78 -0
- package/src/skill-installer.js +226 -71
- package/src/skills.js +1166 -96
- package/src/state-sync.js +0 -0
- package/src/test-fixtures.js +543 -0
- package/src/tui/grid.js +67 -0
- package/src/tui/status-grid.js +23 -0
- package/support-bundle.json +114 -0
- package/templates/AGENTS.md +6 -2
- package/templates/catalog-manifest.json +0 -0
- package/templates/model-instructions/core.md +0 -0
- package/templates/model-instructions/release.md +0 -0
- package/templates/model-instructions/security.md +0 -0
- package/templates/quality/ai-quality-rules.yml +37 -0
- package/docs/assets/image/Screenshot(1).png +0 -0
- package/docs/assets/image/Screenshot(2).png +0 -0
- package/docs/assets/image/Screenshot(3).png +0 -0
- package/docs/assets/image/Screenshot(4).png +0 -0
- package/docs/assets/image/Screenshot(5).png +0 -0
- package/docs/assets/image/Screenshot(6).png +0 -0
- package/docs/assets/image/Screenshot(7).png +0 -0
- package/docs/assets/image/Screenshot(8).png +0 -0
- package/docs/assets/image/Screenshot(9).png +0 -0
- package/docs/assets/meta-architect-logo.png +0 -0
- package/docs/assets/meta-architect-logo.svg +0 -8
- package/docs/onboarding.md +0 -65
- package/docs/skills-publishing.md +0 -255
package/bin/ma.js
CHANGED
|
@@ -1,17 +1,56 @@
|
|
|
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 {
|
|
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";
|
|
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";
|
|
13
34
|
import { evaluateRuntimeBuildReadiness } from "../src/runtime/build-readiness.js";
|
|
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";
|
|
38
|
+
import {
|
|
39
|
+
appendObsidianOperationReceipt,
|
|
40
|
+
configureObsidianVault,
|
|
41
|
+
createObsidianNote,
|
|
42
|
+
deleteObsidianNote,
|
|
43
|
+
listObsidianNotes,
|
|
44
|
+
readObsidianNote,
|
|
45
|
+
updateObsidianNote,
|
|
46
|
+
writeObsidianVaultIndex,
|
|
47
|
+
} from "../src/runtime/obsidian-integration-core.js";
|
|
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";
|
|
14
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";
|
|
15
54
|
import {
|
|
16
55
|
ensureSkillsInstalled,
|
|
17
56
|
ensureSupportBundleInstalled,
|
|
@@ -30,36 +69,286 @@ import {
|
|
|
30
69
|
runVibe,
|
|
31
70
|
} from "../src/skills.js";
|
|
32
71
|
import { syncStatusUpdates } from "../src/state-sync.js";
|
|
72
|
+
import { renderReleaseGrid } from "../src/tui/status-grid.js";
|
|
33
73
|
|
|
34
74
|
function printUsage() {
|
|
35
|
-
console.
|
|
36
|
-
console.
|
|
37
|
-
console.
|
|
38
|
-
console.
|
|
39
|
-
console.
|
|
40
|
-
console.
|
|
41
|
-
console.
|
|
42
|
-
console.
|
|
43
|
-
console.
|
|
44
|
-
console.
|
|
45
|
-
console.
|
|
46
|
-
console.
|
|
47
|
-
console.
|
|
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(
|
|
99
|
+
" ma obsidian list|read|create|update|delete|plugin-install <vault-path> [note-path] [content]",
|
|
100
|
+
);
|
|
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]");
|
|
48
116
|
}
|
|
49
117
|
|
|
50
|
-
async function
|
|
51
|
-
|
|
52
|
-
console.log(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
118
|
+
async function printVersion() {
|
|
119
|
+
const metadata = JSON.parse(await fs.readFile(path.join(packageRoot, "package.json"), "utf8"));
|
|
120
|
+
console.log(metadata.version);
|
|
121
|
+
}
|
|
122
|
+
|
|
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
|
+
}
|
|
60
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 } = {}) {
|
|
61
304
|
const runtimeSummary = createRuntimeSummary(await loadRuntimeSnapshot());
|
|
62
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
|
+
}
|
|
317
|
+
console.log("Meta-Architect Status");
|
|
318
|
+
console.log("=====================");
|
|
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}`);
|
|
337
|
+
|
|
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
|
+
}
|
|
344
|
+
if (
|
|
345
|
+
releaseState.build_status === "DONE" &&
|
|
346
|
+
releaseState.merge_status !== "MERGED_TO_DEVELOPMENT"
|
|
347
|
+
) {
|
|
348
|
+
console.log("Next allowed triggers:");
|
|
349
|
+
console.log("ma merge <feature/*> development");
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
63
352
|
console.log("Next allowed triggers:");
|
|
64
353
|
const triggers = evaluation.nextTriggers;
|
|
65
354
|
if (triggers.length === 0) {
|
|
@@ -72,9 +361,16 @@ async function printStatus(releaseState) {
|
|
|
72
361
|
}
|
|
73
362
|
}
|
|
74
363
|
|
|
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));
|
|
369
|
+
}
|
|
370
|
+
|
|
75
371
|
async function runBuild() {
|
|
76
372
|
const result = await runBuildLane();
|
|
77
|
-
if (result.status
|
|
373
|
+
if (result.status === "BLOCKED") {
|
|
78
374
|
console.error("Build is locked.");
|
|
79
375
|
for (const blocker of result.blockers) {
|
|
80
376
|
console.error(`- ${blocker}`);
|
|
@@ -83,18 +379,33 @@ async function runBuild() {
|
|
|
83
379
|
return;
|
|
84
380
|
}
|
|
85
381
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
382
|
+
if (result.status === "READY") {
|
|
383
|
+
const suggestedBranches = result.suggestedBranches ?? [];
|
|
384
|
+
console.log("Build gate is ready.");
|
|
385
|
+
console.log("Suggested branches:");
|
|
386
|
+
for (const branch of suggestedBranches) {
|
|
387
|
+
console.log(`- ${branch}`);
|
|
388
|
+
}
|
|
389
|
+
console.log("Optional worktree commands:");
|
|
390
|
+
console.log("git worktree add ../implementation feature/implementation");
|
|
391
|
+
console.log("git worktree add ../verification feature/verification");
|
|
392
|
+
console.log("Run `ma run '$build'` again to start the bounded build execution substep.");
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (result.status === "RUNNING") {
|
|
397
|
+
console.log("Build gate is running the bounded execution substep.");
|
|
398
|
+
console.log(
|
|
399
|
+
"Run `ma run '$build'` again to finalize the substep and persist completion evidence.",
|
|
400
|
+
);
|
|
401
|
+
return;
|
|
91
402
|
}
|
|
92
|
-
|
|
93
|
-
console.log("
|
|
94
|
-
console.log("
|
|
403
|
+
|
|
404
|
+
console.log("Build gate completed the bounded execution substep.");
|
|
405
|
+
console.log("Next step: ma merge <feature/*> development");
|
|
95
406
|
}
|
|
96
407
|
|
|
97
|
-
async function runMerge(sourceBranch, targetBranch) {
|
|
408
|
+
async function runMerge(sourceBranch, targetBranch, mode = "approval") {
|
|
98
409
|
const releaseState = await loadReleaseState();
|
|
99
410
|
|
|
100
411
|
if (!validateMergeTarget(sourceBranch, targetBranch)) {
|
|
@@ -102,7 +413,26 @@ async function runMerge(sourceBranch, targetBranch) {
|
|
|
102
413
|
}
|
|
103
414
|
|
|
104
415
|
if (!canMarkBuildDone(releaseState)) {
|
|
105
|
-
throw new Error("Merge is blocked until build status is
|
|
416
|
+
throw new Error("Merge is blocked until build status is DONE");
|
|
417
|
+
}
|
|
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);
|
|
106
436
|
}
|
|
107
437
|
|
|
108
438
|
await appendDecision({
|
|
@@ -115,14 +445,17 @@ async function runMerge(sourceBranch, targetBranch) {
|
|
|
115
445
|
});
|
|
116
446
|
|
|
117
447
|
await syncStatusUpdates({
|
|
118
|
-
build_status: "DONE",
|
|
119
448
|
merge_status: "MERGED_TO_DEVELOPMENT",
|
|
120
449
|
});
|
|
121
450
|
|
|
122
|
-
console.log(
|
|
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
|
+
);
|
|
123
456
|
}
|
|
124
457
|
|
|
125
|
-
async function runRelease(originBranch, targetBranch) {
|
|
458
|
+
async function runRelease(originBranch, targetBranch, mode = "approval") {
|
|
126
459
|
const releaseState = await loadReleaseState();
|
|
127
460
|
|
|
128
461
|
if (targetBranch !== "prod") {
|
|
@@ -139,6 +472,25 @@ async function runRelease(originBranch, targetBranch) {
|
|
|
139
472
|
throw new Error("Release is blocked until merge_status is MERGED_TO_DEVELOPMENT");
|
|
140
473
|
}
|
|
141
474
|
|
|
475
|
+
const operation = await inspectGitOperation(getRepoRoot(), originBranch, targetBranch);
|
|
476
|
+
if (!operation.available || !operation.sourceExists || !operation.clean) {
|
|
477
|
+
throw new Error(`Git preflight failed: ${operation.blockers.join("; ")}`);
|
|
478
|
+
}
|
|
479
|
+
if (mode === "dry-run") {
|
|
480
|
+
console.log(
|
|
481
|
+
`DRY RUN: approval state unchanged; would execute ${operation.display} on ${targetBranch}`,
|
|
482
|
+
);
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
if (mode === "execute") {
|
|
486
|
+
if (operation.currentBranch !== targetBranch) {
|
|
487
|
+
throw new Error(
|
|
488
|
+
`Git execute requires current branch ${targetBranch}; found ${operation.currentBranch || "detached HEAD"}`,
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
await executeGitOperation(getRepoRoot(), operation);
|
|
492
|
+
}
|
|
493
|
+
|
|
142
494
|
await appendDecision({
|
|
143
495
|
kind: "release",
|
|
144
496
|
decision: `Release approved from ${originBranch} to ${targetBranch}`,
|
|
@@ -152,7 +504,20 @@ async function runRelease(originBranch, targetBranch) {
|
|
|
152
504
|
release_status: "SHIPPED_TO_PROD",
|
|
153
505
|
});
|
|
154
506
|
|
|
155
|
-
console.log(
|
|
507
|
+
console.log(
|
|
508
|
+
mode === "execute"
|
|
509
|
+
? `Release executed and approved: ${originBranch} -> ${targetBranch}`
|
|
510
|
+
: `Release approved only: ${originBranch} -> ${targetBranch}; no Git command executed. Run \`${operation.display}\` explicitly or use --execute.`,
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
function resolveGitMode(args) {
|
|
515
|
+
const modes = [
|
|
516
|
+
args.includes("--dry-run") && "dry-run",
|
|
517
|
+
args.includes("--execute") && "execute",
|
|
518
|
+
].filter(Boolean);
|
|
519
|
+
if (modes.length > 1) throw new Error("Choose only one of --dry-run or --execute");
|
|
520
|
+
return modes[0] ?? "approval";
|
|
156
521
|
}
|
|
157
522
|
|
|
158
523
|
async function main() {
|
|
@@ -160,40 +525,179 @@ async function main() {
|
|
|
160
525
|
const args = process.argv.slice(2);
|
|
161
526
|
const arg = rest[0];
|
|
162
527
|
|
|
528
|
+
if (args[0] === "--help" || args[0] === "-h" || args[0] === "help") {
|
|
529
|
+
if (args[0] === "help" && args[1]) printCommandHelp(args[1]);
|
|
530
|
+
else printUsage();
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
if (args[0] === "--version" || args[0] === "-v" || args[0] === "version") {
|
|
534
|
+
await printVersion();
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
if (args.includes("--help")) {
|
|
538
|
+
printCommandHelp(command);
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
if (command === "hook") {
|
|
543
|
+
runHook(arg);
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
if (command === "task") {
|
|
548
|
+
await runTaskCommand(rest);
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
if (command === "redaction" && rest[0] === "purge") {
|
|
553
|
+
const result = await purgeRedactionVault({ dryRun: rest.includes("--dry-run") });
|
|
554
|
+
console.log(JSON.stringify(result, null, 2));
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
|
|
163
558
|
if (shouldDelegateToCodex(args)) {
|
|
164
|
-
await
|
|
165
|
-
process.
|
|
559
|
+
const selection = await choosePrelaunchInstall();
|
|
560
|
+
const agentType = process.env.MA_AGENT || selection?.targets?.[0] || "codex";
|
|
561
|
+
if (selection) {
|
|
562
|
+
await installPrelaunchSelection(selection);
|
|
563
|
+
} else if (process.env.MA_AGENT) {
|
|
564
|
+
await installPrelaunchSelection({
|
|
565
|
+
schemaVersion: "0.1.0",
|
|
566
|
+
scope: "project",
|
|
567
|
+
targets: [agentType],
|
|
568
|
+
});
|
|
569
|
+
} else {
|
|
570
|
+
await Promise.all([ensureSkillsInstalled(), ensureSupportBundleInstalled()]);
|
|
571
|
+
}
|
|
572
|
+
if (!resolveAgentCommand(agentType)) {
|
|
573
|
+
console.log(
|
|
574
|
+
`Installed ${agentType} compatibility files; no executable host command is registered, so delegation was skipped.`,
|
|
575
|
+
);
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
process.exitCode = runAgent(args, agentType);
|
|
166
579
|
return;
|
|
167
580
|
}
|
|
168
581
|
|
|
169
582
|
if (command === "setup") {
|
|
170
|
-
const
|
|
583
|
+
const jsonOutput = args.includes("--json");
|
|
584
|
+
if (args.includes("--rollback")) {
|
|
585
|
+
const result = await rollbackSetup(getRepoRoot(), { dryRun: args.includes("--dry-run") });
|
|
586
|
+
if (jsonOutput) console.log(JSON.stringify(result, null, 2));
|
|
587
|
+
else console.log(`${result.status}: ${result.removed.length} artifact(s) removed`);
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
const report = await runInit({
|
|
591
|
+
refresh: args.includes("--refresh"),
|
|
592
|
+
obsidianVault: getOptionValue(args, "--obsidian-vault"),
|
|
593
|
+
});
|
|
594
|
+
if (
|
|
595
|
+
[...report.directories, ...report.files].some(
|
|
596
|
+
(entry) => entry.status === "warning" || entry.status === "warned" || entry.fatal === true,
|
|
597
|
+
)
|
|
598
|
+
) {
|
|
599
|
+
process.exitCode = 1;
|
|
600
|
+
}
|
|
601
|
+
if (jsonOutput) {
|
|
602
|
+
console.log(JSON.stringify(report, null, 2));
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
|
|
171
606
|
console.log("meta-architect setup");
|
|
172
607
|
console.log("====================");
|
|
173
|
-
for (const
|
|
174
|
-
|
|
608
|
+
for (const entry of [...report.directories, ...report.files]) {
|
|
609
|
+
const suffix = entry.warning ? `: ${entry.warning}` : "";
|
|
610
|
+
console.log(`${entry.status}: ${entry.path}${suffix}`);
|
|
611
|
+
}
|
|
612
|
+
for (const integration of report.integrations ?? []) {
|
|
613
|
+
console.log(`${integration.status}: ${integration.vaultPath}/${integration.notePath}`);
|
|
614
|
+
}
|
|
615
|
+
if (report.context) {
|
|
616
|
+
console.log(
|
|
617
|
+
`context: ${report.context.path} (${report.context.status}, ${report.context.completeness})`,
|
|
618
|
+
);
|
|
619
|
+
if (report.context.unknown.length > 0) {
|
|
620
|
+
console.log(`context unknown: ${report.context.unknown.join(", ")}`);
|
|
621
|
+
}
|
|
175
622
|
}
|
|
623
|
+
console.log("next: ma doctor | ma context refresh | ma setup --rollback");
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
if (command === "welcome") {
|
|
628
|
+
const outcome = await runDoctor();
|
|
629
|
+
console.log("Meta-Architect welcome");
|
|
630
|
+
console.log("=======================");
|
|
631
|
+
console.log("Context: .ma/context/project-index.json");
|
|
632
|
+
console.log(
|
|
633
|
+
"Agents read: .ma/context/agent-brief.md, .ma/context/project-index.json, AGENTS.md",
|
|
634
|
+
);
|
|
635
|
+
console.log("Next: ma doctor | ma context refresh | ma setup --rollback");
|
|
636
|
+
process.exitCode = outcome.result === "BLOCKED" ? 1 : 0;
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
if (command === "context" && rest[0] === "refresh") {
|
|
641
|
+
const result = await refreshProjectIndex(getRepoRoot(), {
|
|
642
|
+
mode: rest.includes("--full") ? "full" : "incremental",
|
|
643
|
+
});
|
|
644
|
+
const receipt = await fs.readFile(`${getRepoRoot()}/.ma/context/refresh-receipt.json`, "utf8");
|
|
645
|
+
if (rest.includes("--json")) console.log(receipt);
|
|
646
|
+
else {
|
|
647
|
+
console.log(`context refresh: ${result.freshness.status}`);
|
|
648
|
+
console.log(`changed: ${result.freshness.changedFiles.length}`);
|
|
649
|
+
console.log(`affected: ${JSON.parse(receipt).affectedArtifacts.join(", ") || "none"}`);
|
|
650
|
+
}
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
if (command === "uninstall") {
|
|
655
|
+
const result = await rollbackSetup(getRepoRoot());
|
|
656
|
+
console.log(JSON.stringify(result, null, 2));
|
|
176
657
|
return;
|
|
177
658
|
}
|
|
178
659
|
|
|
179
660
|
if (command === "bootstrap") {
|
|
180
|
-
const outcome = await runBootstrap({
|
|
661
|
+
const outcome = await runBootstrap({
|
|
662
|
+
initMcp: rest.includes("--init-mcp"),
|
|
663
|
+
json: rest.includes("--json"),
|
|
664
|
+
});
|
|
665
|
+
if (rest.includes("--json")) console.log(JSON.stringify(outcome, null, 2));
|
|
181
666
|
process.exitCode = outcome.result === "BLOCKED" ? 1 : 0;
|
|
182
667
|
return;
|
|
183
668
|
}
|
|
184
669
|
|
|
185
670
|
if (command === "doctor") {
|
|
186
|
-
const outcome = await runDoctor();
|
|
671
|
+
const outcome = await runDoctor({ json: rest.includes("--json") });
|
|
672
|
+
if (rest.includes("--json")) console.log(JSON.stringify(outcome, null, 2));
|
|
187
673
|
process.exitCode = outcome.result === "BLOCKED" ? 1 : 0;
|
|
188
674
|
return;
|
|
189
675
|
}
|
|
190
676
|
|
|
677
|
+
if (command === "migrate") {
|
|
678
|
+
const result = await migrateSchemas(getRepoRoot(), {
|
|
679
|
+
dryRun: rest.includes("--dry-run"),
|
|
680
|
+
rollback: rest.includes("--rollback"),
|
|
681
|
+
});
|
|
682
|
+
if (rest.includes("--json")) console.log(JSON.stringify(result, null, 2));
|
|
683
|
+
else
|
|
684
|
+
console.log(
|
|
685
|
+
`${result.status}: ${(result.migrated ?? result.restored ?? []).length} artifact(s)`,
|
|
686
|
+
);
|
|
687
|
+
process.exitCode = result.status === "failed" ? 1 : 0;
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
|
|
191
691
|
if (command === "init") {
|
|
192
|
-
const
|
|
692
|
+
const report = await runInit({
|
|
693
|
+
refresh: args.includes("--refresh"),
|
|
694
|
+
obsidianVault: getOptionValue(args, "--obsidian-vault"),
|
|
695
|
+
});
|
|
193
696
|
console.log("meta-architect init");
|
|
194
697
|
console.log("===================");
|
|
195
|
-
for (const
|
|
196
|
-
|
|
698
|
+
for (const entry of [...report.directories, ...report.files]) {
|
|
699
|
+
const suffix = entry.warning ? `: ${entry.warning}` : "";
|
|
700
|
+
console.log(`${entry.status}: ${entry.path}${suffix}`);
|
|
197
701
|
}
|
|
198
702
|
return;
|
|
199
703
|
}
|
|
@@ -212,6 +716,145 @@ async function main() {
|
|
|
212
716
|
return;
|
|
213
717
|
}
|
|
214
718
|
|
|
719
|
+
if (command === "core-ingest") {
|
|
720
|
+
await runInit();
|
|
721
|
+
const manifest = await ingestCoreSources({ refresh: rest.includes("--refresh") });
|
|
722
|
+
console.log("Core sources ingested");
|
|
723
|
+
console.log(`Status: ${manifest.status}`);
|
|
724
|
+
console.log(`Runtime fetch required: ${manifest.runtime_fetch_required}`);
|
|
725
|
+
for (const source of manifest.sources) {
|
|
726
|
+
console.log(`${source.id}: ${source.status} ${source.local_path ?? source.repo}`);
|
|
727
|
+
}
|
|
728
|
+
if (manifest.errors?.length > 0) {
|
|
729
|
+
process.exitCode = 1;
|
|
730
|
+
}
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
if (command === "agent-compat") {
|
|
735
|
+
await runAgentCompatCommand(rest);
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
if (command === "obsidian-index") {
|
|
740
|
+
await runInit();
|
|
741
|
+
const index = await writeObsidianVaultIndex({ vaultPath: arg });
|
|
742
|
+
console.log("Obsidian vault indexed");
|
|
743
|
+
console.log(`Vault: ${index.vault_path}`);
|
|
744
|
+
console.log(`Notes: ${index.note_count}`);
|
|
745
|
+
console.log(`Tags: ${index.tags.length}`);
|
|
746
|
+
console.log(`Unresolved links: ${index.unresolved_links.length}`);
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
if (command === "obsidian") {
|
|
751
|
+
const [action, vaultPath, notePath, ...contentParts] = rest;
|
|
752
|
+
if (!action) {
|
|
753
|
+
throw new Error(
|
|
754
|
+
"Usage: ma obsidian list|read|create|update|delete|plugin-install <vault-path> [note-path] [content]",
|
|
755
|
+
);
|
|
756
|
+
}
|
|
757
|
+
await runInit();
|
|
758
|
+
if (action === "configure") {
|
|
759
|
+
const config = await configureObsidianVault(vaultPath);
|
|
760
|
+
console.log(`Obsidian vault configured: ${config.vaultPath}`);
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
if (action === "plugin-install") {
|
|
764
|
+
const receipt = await installObsidianPlugin({ vaultPath });
|
|
765
|
+
await appendObsidianOperationReceipt({
|
|
766
|
+
record_type: "obsidian_vault_operation",
|
|
767
|
+
operation: "plugin_install",
|
|
768
|
+
records_as: "vault_context",
|
|
769
|
+
build_evidence: false,
|
|
770
|
+
authority_boundary: "$maestro_or_owning_lane",
|
|
771
|
+
vault_path: receipt.vault_path,
|
|
772
|
+
relative_path: ".obsidian/plugins/meta-architect",
|
|
773
|
+
content_sha256: "0".repeat(64),
|
|
774
|
+
char_count: receipt.installed_files.join("\n").length,
|
|
775
|
+
performed_at: new Date().toISOString(),
|
|
776
|
+
});
|
|
777
|
+
console.log("Obsidian plugin installed");
|
|
778
|
+
console.log(`Vault: ${receipt.vault_path}`);
|
|
779
|
+
console.log(`Plugin: ${receipt.plugin_path}`);
|
|
780
|
+
console.log(`Enabled: ${receipt.enabled}`);
|
|
781
|
+
console.log(`Files: ${receipt.installed_files.join(", ")}`);
|
|
782
|
+
return;
|
|
783
|
+
}
|
|
784
|
+
if (action === "list") {
|
|
785
|
+
const list = await listObsidianNotes({ vaultPath });
|
|
786
|
+
console.log(`Obsidian notes: ${list.notes.length}`);
|
|
787
|
+
for (const note of list.notes) {
|
|
788
|
+
console.log(note);
|
|
789
|
+
}
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
if (action === "read") {
|
|
793
|
+
const note = await readObsidianNote({ vaultPath, notePath });
|
|
794
|
+
console.log(`Obsidian note: ${note.relative_path}`);
|
|
795
|
+
console.log(note.content);
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
798
|
+
if (action === "create") {
|
|
799
|
+
const content = await readObsidianContent(rest, contentParts.join(" "));
|
|
800
|
+
if (rest.includes("--dry-run")) {
|
|
801
|
+
console.log(
|
|
802
|
+
JSON.stringify(
|
|
803
|
+
{ schemaVersion: "0.1.0", status: "would_create", notePath, content },
|
|
804
|
+
null,
|
|
805
|
+
2,
|
|
806
|
+
),
|
|
807
|
+
);
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
const receipt = await createObsidianNote({
|
|
811
|
+
vaultPath,
|
|
812
|
+
notePath,
|
|
813
|
+
content,
|
|
814
|
+
});
|
|
815
|
+
await appendObsidianOperationReceipt(receipt);
|
|
816
|
+
await writeObsidianVaultIndex({ vaultPath });
|
|
817
|
+
console.log(`Obsidian note created: ${receipt.relative_path}`);
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
if (action === "update") {
|
|
821
|
+
const content = await readObsidianContent(rest, contentParts.join(" "));
|
|
822
|
+
if (rest.includes("--dry-run")) {
|
|
823
|
+
const existing = await readObsidianNote({ vaultPath, notePath });
|
|
824
|
+
console.log(
|
|
825
|
+
JSON.stringify(
|
|
826
|
+
{
|
|
827
|
+
schemaVersion: "0.1.0",
|
|
828
|
+
status: existing.content === content ? "unchanged" : "would_update",
|
|
829
|
+
notePath,
|
|
830
|
+
content,
|
|
831
|
+
},
|
|
832
|
+
null,
|
|
833
|
+
2,
|
|
834
|
+
),
|
|
835
|
+
);
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
const receipt = await updateObsidianNote({
|
|
839
|
+
vaultPath,
|
|
840
|
+
notePath,
|
|
841
|
+
content,
|
|
842
|
+
});
|
|
843
|
+
await appendObsidianOperationReceipt(receipt);
|
|
844
|
+
await writeObsidianVaultIndex({ vaultPath });
|
|
845
|
+
console.log(`Obsidian note updated: ${receipt.relative_path}`);
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
if (action === "delete") {
|
|
849
|
+
const receipt = await deleteObsidianNote({ vaultPath, notePath });
|
|
850
|
+
await appendObsidianOperationReceipt(receipt);
|
|
851
|
+
await writeObsidianVaultIndex({ vaultPath });
|
|
852
|
+
console.log(`Obsidian note deleted: ${receipt.relative_path}`);
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
throw new Error(`Unknown Obsidian action: ${action}`);
|
|
856
|
+
}
|
|
857
|
+
|
|
215
858
|
if (command === "sdk-path") {
|
|
216
859
|
process.stdout.write(`${getSupportBundleRoot()}\n`);
|
|
217
860
|
return;
|
|
@@ -219,24 +862,74 @@ async function main() {
|
|
|
219
862
|
|
|
220
863
|
if (command === "status") {
|
|
221
864
|
const releaseState = await loadReleaseState();
|
|
222
|
-
|
|
865
|
+
const json = rest.includes("--json");
|
|
866
|
+
const snapshot = rest.includes("--maestro-view") ? await loadRuntimeSnapshot() : null;
|
|
867
|
+
if (json && snapshot) {
|
|
868
|
+
const runtime = createRuntimeSummary(snapshot);
|
|
869
|
+
const evaluation = evaluateRuntimeBuildReadiness(releaseState, runtime);
|
|
870
|
+
const status = {
|
|
871
|
+
schemaVersion: "0.1.0",
|
|
872
|
+
scope: "status",
|
|
873
|
+
release: releaseState,
|
|
874
|
+
runtime,
|
|
875
|
+
nextTriggers: evaluation.nextTriggers,
|
|
876
|
+
maestro: createMaestroView(snapshot.maestroState),
|
|
877
|
+
};
|
|
878
|
+
process.stdout.write(`${JSON.stringify(status, null, 2)}\n`);
|
|
879
|
+
} else {
|
|
880
|
+
await printStatus(releaseState, { json });
|
|
881
|
+
if (snapshot) await printMaestroView({ snapshot });
|
|
882
|
+
}
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
if (command === "verify" && rest.includes("--architect")) {
|
|
887
|
+
const review = await runExternalArchitectReview({
|
|
888
|
+
prompt:
|
|
889
|
+
"Review the current Meta-Architect runtime and release-state outputs for architectural soundness.",
|
|
890
|
+
});
|
|
891
|
+
console.log(`Architect verdict: ${review.verdict}`);
|
|
892
|
+
if (review.summary) {
|
|
893
|
+
console.log(review.summary);
|
|
894
|
+
}
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
if (command === "verify" && rest.includes("--agents-live")) {
|
|
899
|
+
const report = await verifyLiveAgentMatrix({ cwd: process.cwd() });
|
|
900
|
+
if (rest.includes("--json")) {
|
|
901
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
902
|
+
} else {
|
|
903
|
+
console.log(`Agent live verification: ${report.target_count} targets`);
|
|
904
|
+
console.log(`Runtime verified: ${report.runtime_verified}`);
|
|
905
|
+
console.log(`Distribution only: ${report.distribution_only}`);
|
|
906
|
+
console.log(`Blocked: ${report.blocked}`);
|
|
907
|
+
for (const result of report.results) {
|
|
908
|
+
console.log(
|
|
909
|
+
`- ${result.target}: ${result.status}${result.reason ? ` (${result.reason})` : ""}`,
|
|
910
|
+
);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
223
913
|
return;
|
|
224
914
|
}
|
|
225
915
|
|
|
226
916
|
if (command === "merge") {
|
|
227
|
-
const [sourceBranch, targetBranch] = rest;
|
|
228
|
-
await runMerge(sourceBranch, targetBranch);
|
|
917
|
+
const [sourceBranch, targetBranch] = rest.filter((arg) => !arg.startsWith("--"));
|
|
918
|
+
await runMerge(sourceBranch, targetBranch, resolveGitMode(rest));
|
|
229
919
|
return;
|
|
230
920
|
}
|
|
231
921
|
|
|
232
922
|
if (command === "release") {
|
|
233
|
-
const [originBranch, targetBranch] = rest;
|
|
234
|
-
await runRelease(originBranch, targetBranch);
|
|
923
|
+
const [originBranch, targetBranch] = rest.filter((arg) => !arg.startsWith("--"));
|
|
924
|
+
await runRelease(originBranch, targetBranch, resolveGitMode(rest));
|
|
235
925
|
return;
|
|
236
926
|
}
|
|
237
927
|
|
|
238
928
|
if (command === "run" && arg === "$maestro") {
|
|
239
|
-
await runMaestro(
|
|
929
|
+
await runMaestro({
|
|
930
|
+
autoHeal: rest.includes("--auto-heal"),
|
|
931
|
+
parallel: rest.includes("--parallel"),
|
|
932
|
+
});
|
|
240
933
|
console.log("$maestro complete");
|
|
241
934
|
return;
|
|
242
935
|
}
|