@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.
- package/.agents/plugins/marketplace.json +0 -0
- package/.codex/agents/Architect.toml +1 -0
- package/.codex/agents/Auditor.toml +1 -0
- package/.codex/agents/Builder.toml +1 -0
- package/.codex/agents/Flow.toml +1 -0
- package/.codex/agents/Sage.toml +1 -0
- package/.codex/agents/Vibe.toml +1 -0
- package/.codex/hooks.json +12 -2
- package/.codex/prompts/enforcement.md +0 -0
- package/.codex/prompts/onboarding.md +6 -1
- package/.codex/prompts/release-rules.md +0 -0
- package/.codex/prompts/skill-contract.md +0 -0
- package/COVERAGE.md +9 -9
- package/DEMO.md +15 -6
- package/LICENSE +0 -0
- package/README.md +127 -784
- package/bin/ma.js +591 -105
- package/data/clone-data.ledger.json +0 -0
- package/data/clone-data.proof.json +0 -0
- package/data/clone-data.rvf +0 -0
- package/docs/README.md +8 -2
- package/docs/assets/banner.png +0 -0
- package/docs/autonomous-tasks.md +46 -0
- package/docs/codex-integration.md +16 -0
- package/docs/getting-started.md +32 -8
- package/docs/installed-sdk.md +0 -0
- package/docs/mcp-setup.md +30 -1
- package/docs/qa/{release-issue-gates-0.1.13.json → release-issue-gates-0.14.1.json} +77 -77
- package/docs/qa/release-readiness-0.1.5.md +0 -0
- package/docs/qa/{release-readiness-0.1.13.md → release-readiness-0.14.1.md} +12 -12
- package/docs/quality.md +24 -0
- package/docs/reference/native-engineering-patterns.md +0 -0
- package/docs/reference/native-security-playbooks.md +0 -0
- package/docs/reference/native-source-selection.md +0 -0
- package/docs/reference/native-style-and-deslop.md +0 -0
- package/docs/release-spec.md +27 -14
- package/docs/skills.md +1 -1
- package/docs/vendor-plugin-publishing.md +49 -0
- package/index.js +73 -0
- package/mcp/collections.json +0 -0
- package/mcp/fallback.json +0 -0
- package/mcp/local/code-intel.js +185 -41
- package/mcp/local/context.js +180 -0
- package/mcp/local/memory.js +17 -6
- package/mcp/local/playbooks.js +0 -0
- package/mcp/local/quality.js +39 -0
- package/mcp/local/state.js +7 -3
- package/mcp/local/team-run.js +8 -3
- package/mcp/local/trace.js +0 -0
- package/mcp/local-capabilities.json +9 -0
- package/mcp/native-playbooks.json +0 -0
- package/mcp/servers.json +0 -0
- package/package.json +37 -6
- package/plugins/meta-architect/.app.json +1 -1
- package/plugins/meta-architect/.claude-plugin/plugin.json +12 -0
- package/plugins/meta-architect/.codex-plugin/plugin.json +1 -1
- package/plugins/meta-architect/.mcp.json +1 -1
- package/plugins/meta-architect/README.md +14 -2
- package/plugins/meta-architect/obsidian/main.js +137 -4
- package/plugins/meta-architect/obsidian/manifest.json +1 -1
- package/plugins/meta-architect/obsidian/styles.css +0 -0
- package/plugins/meta-architect/skills/align/SKILL.md +0 -0
- package/plugins/meta-architect/skills/align/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/align/references/shared-language.md +0 -0
- package/plugins/meta-architect/skills/arch/SKILL.md +0 -0
- package/plugins/meta-architect/skills/arch/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/build/SKILL.md +0 -0
- package/plugins/meta-architect/skills/build/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/cleanup/SKILL.md +0 -0
- package/plugins/meta-architect/skills/cleanup/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/cleanup/references/style-and-deslop.md +0 -0
- package/plugins/meta-architect/skills/diagnose/SKILL.md +0 -0
- package/plugins/meta-architect/skills/diagnose/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/flow/SKILL.md +0 -0
- package/plugins/meta-architect/skills/flow/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/maestro/SKILL.md +17 -1
- package/plugins/meta-architect/skills/maestro/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/maestro/references/core-release-rules.md +2 -2
- package/plugins/meta-architect/skills/maestro/references/native-ingest-map.md +0 -0
- package/plugins/meta-architect/skills/sage/SKILL.md +0 -0
- package/plugins/meta-architect/skills/sage/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/sage/references/source-selection.md +0 -0
- package/plugins/meta-architect/skills/tdd/SKILL.md +0 -0
- package/plugins/meta-architect/skills/tdd/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/vet/SKILL.md +0 -0
- package/plugins/meta-architect/skills/vet/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/vet/references/security-playbooks.md +0 -0
- package/plugins/meta-architect/skills/vibe/SKILL.md +0 -0
- package/plugins/meta-architect/skills/vibe/agents/openai.yaml +0 -0
- package/schemas/autonomous-task-queue.schema.json +58 -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 +141 -11
- package/scripts/biome-staged.js +0 -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 +10 -8
- package/scripts/install.sh +33 -4
- package/scripts/install.sh.sha256 +1 -0
- package/scripts/linux-package-lib.mjs +0 -0
- package/scripts/linux-package-smoke.mjs +2 -2
- package/scripts/package-size-check.mjs +26 -0
- package/scripts/plugin-build.js +314 -0
- package/scripts/plugin-publish.js +77 -0
- package/scripts/plugin-sync.js +83 -17
- package/scripts/prepack.js +9 -0
- package/scripts/ralph/prompt.md +0 -0
- package/scripts/release-metadata.js +0 -0
- package/scripts/release-sync.js +83 -7
- package/scripts/release-verify.js +131 -7
- 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/align/SKILL.md +0 -0
- package/skills/align/agents/openai.yaml +0 -0
- package/skills/align/references/shared-language.md +0 -0
- package/skills/arch/SKILL.md +0 -0
- package/skills/arch/agents/openai.yaml +0 -0
- package/skills/build/SKILL.md +0 -0
- package/skills/build/agents/openai.yaml +0 -0
- package/skills/cleanup/SKILL.md +0 -0
- package/skills/cleanup/agents/openai.yaml +0 -0
- package/skills/cleanup/references/style-and-deslop.md +0 -0
- package/skills/diagnose/SKILL.md +0 -0
- package/skills/diagnose/agents/openai.yaml +0 -0
- package/skills/flow/SKILL.md +0 -0
- package/skills/flow/agents/openai.yaml +0 -0
- package/skills/index.json +0 -0
- package/skills/maestro/SKILL.md +17 -1
- package/skills/maestro/agents/openai.yaml +0 -0
- package/skills/maestro/references/core-release-rules.md +2 -2
- package/skills/maestro/references/native-ingest-map.md +0 -0
- package/skills/sage/SKILL.md +0 -0
- package/skills/sage/agents/openai.yaml +0 -0
- package/skills/sage/references/source-selection.md +0 -0
- package/skills/tdd/SKILL.md +0 -0
- package/skills/tdd/agents/openai.yaml +0 -0
- package/skills/vet/SKILL.md +0 -0
- package/skills/vet/agents/openai.yaml +0 -0
- package/skills/vet/references/security-playbooks.md +0 -0
- package/skills/vibe/SKILL.md +0 -0
- package/skills/vibe/agents/openai.yaml +0 -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 +2 -2
- package/src/agents.js +281 -0
- package/src/bootstrap.js +272 -65
- package/src/build-gate.js +0 -0
- 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 +26 -23
- package/src/mcp-config.js +9 -1
- package/src/mcp-live-client.js +141 -8
- package/src/paths.js +6 -1
- package/src/policy.js +2 -2
- package/src/prelaunch.js +223 -0
- package/src/process-utils.js +62 -0
- package/src/quality/ai-quality-orchestrator.js +328 -0
- package/src/release-issue-gates.js +62 -0
- package/src/release-operations.js +72 -0
- package/src/release-state.js +0 -0
- package/src/runtime/active-autonomy-core.js +0 -0
- package/src/runtime/agent-compat.js +31 -0
- package/src/runtime/alignment-sentinel.js +0 -0
- package/src/runtime/architect-review.js +249 -11
- package/src/runtime/autonomous-tasks.js +585 -0
- package/src/runtime/build-readiness.js +0 -0
- package/src/runtime/code-graph-rehearse.js +0 -0
- package/src/runtime/codeburn-core.js +118 -0
- package/src/runtime/context-authority.js +40 -0
- package/src/runtime/context-economy-core.js +40 -0
- package/src/runtime/continuity-graph.js +201 -0
- package/src/runtime/continuity-notes.js +71 -26
- package/src/runtime/core-source-ingest.js +2 -2
- package/src/runtime/detached-provider.js +90 -13
- package/src/runtime/doctor-report.js +18 -0
- package/src/runtime/environment-awareness-core.js +0 -0
- package/src/runtime/exposure-catalog.js +0 -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 +0 -0
- package/src/runtime/hook-profiles.js +20 -0
- package/src/runtime/learning-loop-core.js +110 -4
- package/src/runtime/live-agent-verification.js +122 -0
- package/src/runtime/maestro-events.js +0 -0
- package/src/runtime/maestro-manager.js +0 -0
- package/src/runtime/maestro-output.js +58 -0
- package/src/runtime/maestro-state.js +0 -0
- package/src/runtime/managed-markdown.js +29 -0
- package/src/runtime/mcp-authority.js +147 -0
- package/src/runtime/mcp-policy.js +0 -0
- package/src/runtime/obsidian-integration-core.js +255 -17
- package/src/runtime/obsidian-plugin-bridge.js +344 -38
- package/src/runtime/orchestrator.js +0 -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 +0 -0
- package/src/runtime/quorum-review.js +0 -0
- package/src/runtime/ralph-execution-core.js +0 -0
- package/src/runtime/redaction-gateway.js +218 -19
- package/src/runtime/runtime-state.js +94 -2
- package/src/runtime/schema-migrations.js +162 -0
- package/src/runtime/semantic-recording-core.js +0 -0
- package/src/runtime/signal-hooks.js +13 -0
- package/src/runtime/skills-registry-export.js +96 -8
- package/src/runtime/startup-path.js +0 -0
- package/src/runtime/task-contracts.js +83 -0
- package/src/runtime/universal-plugin-broker-core.js +373 -50
- package/src/runtime/workspace-intelligence-runtime.js +0 -0
- package/src/runtime/workspace-virtualizer.js +0 -0
- package/src/runtime/workspaces.js +0 -0
- package/src/runtime-artifacts.js +0 -0
- 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 +309 -31
- 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 -81
- package/docs/prompt-guidance-contract.md +0 -17
- package/docs/prompt-guidance-fragments/active-autonomy-core.md +0 -7
- package/docs/skills-publishing.md +0 -255
- package/scripts/postinstall.js +0 -23
package/src/bootstrap.js
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
|
-
import { spawnSync } from "node:child_process";
|
|
2
1
|
import fs from "node:fs/promises";
|
|
3
2
|
import os from "node:os";
|
|
4
3
|
import path from "node:path";
|
|
4
|
+
import { detectInstalled, getAgent } from "./agents.js";
|
|
5
5
|
import { loadDecisionLog } from "./decision-log.js";
|
|
6
|
+
import { inspectRuntimeStateHealth } from "./fs-utils.js";
|
|
6
7
|
import {
|
|
7
8
|
runLocalCapabilityReadinessChecks,
|
|
8
9
|
validateLocalCapabilities,
|
|
9
10
|
validateMcpServers,
|
|
10
11
|
} from "./mcp-config.js";
|
|
12
|
+
import { getMcpBridgeConfiguration, mcpClientVersion } from "./mcp-live-client.js";
|
|
11
13
|
import { getMcpRootPath, getRepoRoot, getRuntimeWritePath, packageRoot } from "./paths.js";
|
|
14
|
+
import { safeSpawnSync } from "./process-utils.js";
|
|
15
|
+
import { resolveReleaseIssueGates } from "./release-issue-gates.js";
|
|
12
16
|
import { loadReleaseState } from "./release-state.js";
|
|
17
|
+
import { validateAgentIntegrations } from "./runtime/agent-compat.js";
|
|
18
|
+
import { getArchitectReviewConfiguration } from "./runtime/architect-review.js";
|
|
19
|
+
import { printDoctorStatuses, summarizeDoctorStatuses } from "./runtime/doctor-report.js";
|
|
20
|
+
import { mcpWriteCapabilityStatus } from "./runtime/mcp-authority.js";
|
|
21
|
+
import { loadObsidianVaultConfig } from "./runtime/obsidian-integration-core.js";
|
|
22
|
+
import { inspectRedactionVault } from "./runtime/redaction-gateway.js";
|
|
13
23
|
import { loadLeaderAuthority, loadRuntimeSnapshot } from "./runtime/runtime-state.js";
|
|
24
|
+
import { findOutdatedSchemas } from "./runtime/schema-migrations.js";
|
|
25
|
+
import { inspectSetupDrift } from "./setup-lifecycle.js";
|
|
14
26
|
import {
|
|
15
27
|
areSkillsInstalled,
|
|
16
28
|
ensureSkillsInstalled,
|
|
@@ -18,49 +30,216 @@ import {
|
|
|
18
30
|
getSkillInstallRoot,
|
|
19
31
|
getSupportBundleRoot,
|
|
20
32
|
isSupportBundleInstalled,
|
|
33
|
+
readInstallReceipt,
|
|
21
34
|
} from "./skill-installer.js";
|
|
22
35
|
import { runInit } from "./skills.js";
|
|
36
|
+
import { renderCheckGrid } from "./tui/status-grid.js";
|
|
23
37
|
|
|
24
38
|
function makeStatus(kind, label, detail = "") {
|
|
25
39
|
return { kind, label, detail };
|
|
26
40
|
}
|
|
27
41
|
|
|
28
|
-
function
|
|
29
|
-
|
|
42
|
+
function inspectMcpBridge() {
|
|
43
|
+
const template = process.env.MA_MCP_REMOTE_BRIDGE_CMD?.trim();
|
|
44
|
+
if (!template) return makeStatus("OK", "MCP remote bridge", "not configured");
|
|
45
|
+
const command = template.split(/\s+/, 1)[0].replace(/^['"]|['"]$/g, "");
|
|
46
|
+
const policy = getMcpBridgeConfiguration();
|
|
47
|
+
const allowed = policy.allowedCommands.some(
|
|
48
|
+
(entry) => entry === command || path.basename(entry) === path.basename(command),
|
|
49
|
+
);
|
|
50
|
+
return makeStatus(
|
|
51
|
+
allowed ? "OK" : "WARN",
|
|
52
|
+
"MCP remote bridge",
|
|
53
|
+
allowed
|
|
54
|
+
? `${command} is explicitly allowlisted (${policy.source})`
|
|
55
|
+
: `${command} is not allowlisted; configure MA_MCP_REMOTE_BRIDGE_ALLOWLIST or mcp/bridge.json`,
|
|
56
|
+
);
|
|
30
57
|
}
|
|
31
58
|
|
|
32
|
-
function
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
59
|
+
function inspectArchitectReview() {
|
|
60
|
+
const template = process.env.MA_ARCHITECT_REVIEW_CMD?.trim();
|
|
61
|
+
if (!template) return makeStatus("OK", "external architect review", "not configured");
|
|
62
|
+
const command = template.split(/\s+/, 1)[0].replace(/^['"]|['"]$/g, "");
|
|
63
|
+
const policy = getArchitectReviewConfiguration();
|
|
64
|
+
const allowed = policy.allowedCommands.some(
|
|
65
|
+
(entry) => entry === command || path.basename(entry) === path.basename(command),
|
|
66
|
+
);
|
|
67
|
+
return makeStatus(
|
|
68
|
+
allowed ? "OK" : "WARN",
|
|
69
|
+
"external architect review",
|
|
70
|
+
allowed
|
|
71
|
+
? `${command} is explicitly allowlisted (${policy.source})`
|
|
72
|
+
: `${command} is not allowlisted; configure MA_ARCHITECT_REVIEW_ALLOWLIST or .ma/architect-review-policy.json`,
|
|
73
|
+
);
|
|
37
74
|
}
|
|
38
75
|
|
|
39
|
-
function
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
76
|
+
export async function inspectWorkspaceNpmrc() {
|
|
77
|
+
const npmrcPath = path.join(getRepoRoot(), ".npmrc");
|
|
78
|
+
try {
|
|
79
|
+
const content = await fs.readFile(npmrcPath, "utf8");
|
|
80
|
+
const hasAuthMaterial = /(?:_authToken|_auth|_password|username)\s*=|token\s*=/i.test(content);
|
|
81
|
+
return makeStatus(
|
|
82
|
+
hasAuthMaterial ? "WARN" : "OK",
|
|
83
|
+
"workspace npm auth",
|
|
84
|
+
hasAuthMaterial
|
|
85
|
+
? "token-bearing .npmrc detected; use NODE_AUTH_TOKEN or a temporary config outside the workspace"
|
|
86
|
+
: "no token-bearing .npmrc detected",
|
|
87
|
+
);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (error?.code === "ENOENT")
|
|
90
|
+
return makeStatus("OK", "workspace npm auth", "no workspace .npmrc");
|
|
91
|
+
return makeStatus("WARN", "workspace npm auth", `unable to inspect .npmrc: ${error.message}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function inspectPluginInjectionState() {
|
|
96
|
+
const root = path.join(os.homedir(), ".ma", "backups", "plugins");
|
|
97
|
+
try {
|
|
98
|
+
const plugins = await fs.readdir(root, { withFileTypes: true });
|
|
99
|
+
const receipts = [];
|
|
100
|
+
for (const plugin of plugins) {
|
|
101
|
+
if (!plugin.isDirectory()) continue;
|
|
102
|
+
const runs = await fs.readdir(path.join(root, plugin.name), { withFileTypes: true });
|
|
103
|
+
for (const run of runs.filter((entry) => entry.isDirectory())) {
|
|
104
|
+
const receiptPath = path.join(root, plugin.name, run.name, "receipt.json");
|
|
105
|
+
try {
|
|
106
|
+
receipts.push(JSON.parse(await fs.readFile(receiptPath, "utf8")));
|
|
107
|
+
} catch {
|
|
108
|
+
// Ignore incomplete backup directories.
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const latest = receipts.sort((a, b) => `${b.backupRoot}`.localeCompare(`${a.backupRoot}`))[0];
|
|
113
|
+
const hosts = latest?.vendorInjection?.configured_hosts ?? [];
|
|
114
|
+
return makeStatus(
|
|
115
|
+
"OK",
|
|
116
|
+
"plugin MCP injection state",
|
|
117
|
+
hosts.length > 0 ? `configured hosts: ${hosts.join(", ")}` : "no recorded vendor mutations",
|
|
118
|
+
);
|
|
119
|
+
} catch {
|
|
120
|
+
return makeStatus("OK", "plugin MCP injection state", "no recorded vendor mutations");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function inspectContextHealth() {
|
|
125
|
+
const contextPath = getRuntimeWritePath("context", "project-index.json");
|
|
126
|
+
const briefPath = getRuntimeWritePath("context", "agent-brief.md");
|
|
127
|
+
const hookPath = path.join(getRepoRoot(), ".codex", "hooks.json");
|
|
128
|
+
try {
|
|
129
|
+
const project = JSON.parse(await fs.readFile(contextPath, "utf8"));
|
|
130
|
+
const brief = await fs.readFile(briefPath, "utf8");
|
|
131
|
+
const hooks = JSON.parse(await fs.readFile(hookPath, "utf8"));
|
|
132
|
+
const hookText = JSON.stringify(hooks);
|
|
133
|
+
const hydrated =
|
|
134
|
+
hookText.includes("context-hydration-hook.mjs") ||
|
|
135
|
+
hookText.includes("ma hook context-hydration");
|
|
136
|
+
const hookFiles = [];
|
|
137
|
+
const collectHookCommands = (value) => {
|
|
138
|
+
if (Array.isArray(value)) return value.forEach(collectHookCommands);
|
|
139
|
+
if (!value || typeof value !== "object") return;
|
|
140
|
+
if (typeof value.command === "string") hookFiles.push(value.command);
|
|
141
|
+
Object.values(value).forEach(collectHookCommands);
|
|
49
142
|
};
|
|
143
|
+
collectHookCommands(hooks);
|
|
144
|
+
const brokenHookCommands = [];
|
|
145
|
+
for (const command of hookFiles) {
|
|
146
|
+
const relative = command.match(/^node\s+([^\s]+)/)?.[1];
|
|
147
|
+
if (!relative) continue;
|
|
148
|
+
try {
|
|
149
|
+
await fs.access(path.resolve(getRepoRoot(), relative));
|
|
150
|
+
} catch {
|
|
151
|
+
brokenHookCommands.push(relative);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const freshness = project.freshness?.status ?? "unknown";
|
|
155
|
+
const outdated = await findOutdatedSchemas(getRepoRoot());
|
|
156
|
+
const runtimeFindings = await inspectRuntimeStateHealth(getRepoRoot());
|
|
157
|
+
const setupDrift = await inspectSetupDrift(getRepoRoot());
|
|
158
|
+
const mcpWriteStatus = mcpWriteCapabilityStatus();
|
|
159
|
+
return [
|
|
160
|
+
makeStatus(
|
|
161
|
+
setupDrift.length ? "WARN" : "OK",
|
|
162
|
+
"seeded artifact drift",
|
|
163
|
+
setupDrift.length
|
|
164
|
+
? setupDrift.map((entry) => `${entry.status}: ${entry.path}`).join(", ")
|
|
165
|
+
: "no managed template drift",
|
|
166
|
+
),
|
|
167
|
+
makeStatus(
|
|
168
|
+
runtimeFindings.length ? "WARN" : "OK",
|
|
169
|
+
"runtime state integrity",
|
|
170
|
+
runtimeFindings.length
|
|
171
|
+
? runtimeFindings.map((finding) => `${finding.type}: ${finding.path}`).join(", ")
|
|
172
|
+
: "atomic writes and locks healthy",
|
|
173
|
+
),
|
|
174
|
+
makeStatus(
|
|
175
|
+
freshness === "stale" ? "WARN" : "OK",
|
|
176
|
+
"project context freshness",
|
|
177
|
+
`${freshness}; ${project.quality?.confidence ?? "unknown"} confidence`,
|
|
178
|
+
),
|
|
179
|
+
makeStatus(brief.trim() ? "OK" : "WARN", "agent context brief", briefPath),
|
|
180
|
+
makeStatus(
|
|
181
|
+
hydrated ? "OK" : "WARN",
|
|
182
|
+
"startup/prompt context hydration",
|
|
183
|
+
hydrated ? hookPath : "run `ma setup`",
|
|
184
|
+
),
|
|
185
|
+
makeStatus(
|
|
186
|
+
brokenHookCommands.length ? "WARN" : "OK",
|
|
187
|
+
"hook command portability",
|
|
188
|
+
brokenHookCommands.length
|
|
189
|
+
? `missing: ${brokenHookCommands.join(", ")}`
|
|
190
|
+
: "all local hook scripts are present",
|
|
191
|
+
),
|
|
192
|
+
makeStatus(
|
|
193
|
+
"OK",
|
|
194
|
+
"Obsidian integration",
|
|
195
|
+
(await loadObsidianVaultConfig())?.vaultPath || process.env.MA_OBSIDIAN_VAULT
|
|
196
|
+
? "configured"
|
|
197
|
+
: "not configured (explicitly disabled)",
|
|
198
|
+
),
|
|
199
|
+
await inspectRedactionVault().then((vault) =>
|
|
200
|
+
makeStatus(
|
|
201
|
+
vault.status === "warning" ? "WARN" : "OK",
|
|
202
|
+
"redaction vault policy",
|
|
203
|
+
vault.issues.length > 0
|
|
204
|
+
? vault.issues.join(", ")
|
|
205
|
+
: `${vault.policy.retentionDays}d retention, ${vault.policy.maxEntries} max entries`,
|
|
206
|
+
),
|
|
207
|
+
),
|
|
208
|
+
await inspectWorkspaceNpmrc(),
|
|
209
|
+
makeStatus("OK", "MCP context resources", "local read-only context capability available"),
|
|
210
|
+
makeStatus(
|
|
211
|
+
mcpWriteStatus.readOnly ? "WARN" : "OK",
|
|
212
|
+
"MCP write authority",
|
|
213
|
+
mcpWriteStatus.detail,
|
|
214
|
+
),
|
|
215
|
+
makeStatus(
|
|
216
|
+
outdated.length ? "WARN" : "OK",
|
|
217
|
+
"runtime schema versions",
|
|
218
|
+
outdated.length ? `${outdated.length} outdated artifact(s); run ma migrate` : "current",
|
|
219
|
+
),
|
|
220
|
+
];
|
|
221
|
+
} catch (_error) {
|
|
222
|
+
return [
|
|
223
|
+
makeStatus(
|
|
224
|
+
"WARN",
|
|
225
|
+
"project context health",
|
|
226
|
+
"Run `ma setup` to generate bounded context artifacts",
|
|
227
|
+
),
|
|
228
|
+
];
|
|
50
229
|
}
|
|
230
|
+
}
|
|
51
231
|
|
|
232
|
+
function inspectAgent(type = process.env.MA_AGENT || "codex") {
|
|
233
|
+
const result = detectInstalled(type);
|
|
52
234
|
return {
|
|
53
|
-
ok:
|
|
54
|
-
command
|
|
55
|
-
|
|
56
|
-
(result.error?.message ?? result.stderr.trim() ?? result.stdout.trim()) ||
|
|
57
|
-
"Codex command failed",
|
|
58
|
-
version: "",
|
|
235
|
+
ok: result.installed,
|
|
236
|
+
detail: result.error || `${getAgent(type).displayName} command failed`,
|
|
237
|
+
version: result.version,
|
|
59
238
|
};
|
|
60
239
|
}
|
|
61
240
|
|
|
62
241
|
function listCodexPaths() {
|
|
63
|
-
const result =
|
|
242
|
+
const result = safeSpawnSync("which", ["-a", "codex"], { encoding: "utf8" });
|
|
64
243
|
if (result.error || result.status !== 0) {
|
|
65
244
|
return [];
|
|
66
245
|
}
|
|
@@ -157,6 +336,7 @@ async function inspectLocalScaffold() {
|
|
|
157
336
|
getRuntimeWritePath("context", "code-graph-rehearse.json"),
|
|
158
337
|
getRuntimeWritePath("context", "core-source-ingest.json"),
|
|
159
338
|
getRuntimeWritePath("context", "learning-loop-core.json"),
|
|
339
|
+
getRuntimeWritePath("context", "project-index.json"),
|
|
160
340
|
getRuntimeWritePath("context", "obsidian-bridge.json"),
|
|
161
341
|
getRuntimeWritePath("context", "obsidian-vault-index.json"),
|
|
162
342
|
getRuntimeWritePath("context", "obsidian-vault-operations.json"),
|
|
@@ -177,7 +357,8 @@ async function inspectLocalScaffold() {
|
|
|
177
357
|
getRuntimeWritePath("state", "manager-runs.json"),
|
|
178
358
|
getRuntimeWritePath("state", "maestro-state.json"),
|
|
179
359
|
getRuntimeWritePath("evidence", "semantic-receipts.json"),
|
|
180
|
-
|
|
360
|
+
resolveReleaseIssueGates(getRepoRoot())?.path ??
|
|
361
|
+
path.join(getRepoRoot(), "docs", "qa", "release-issue-gates-missing.json"),
|
|
181
362
|
path.join(getMcpRootPath(), "servers.json"),
|
|
182
363
|
path.join(getMcpRootPath(), "local-capabilities.json"),
|
|
183
364
|
];
|
|
@@ -319,48 +500,59 @@ async function inspectLocalCapabilityState({ fix }) {
|
|
|
319
500
|
}
|
|
320
501
|
|
|
321
502
|
async function runEnvironmentFlow({ fix, initMcp }) {
|
|
322
|
-
const statuses = [];
|
|
503
|
+
const statuses = [makeStatus("OK", "MCP client version", mcpClientVersion)];
|
|
504
|
+
statuses.push(inspectMcpBridge());
|
|
505
|
+
statuses.push(inspectArchitectReview());
|
|
323
506
|
|
|
324
|
-
const
|
|
507
|
+
const agentType = process.env.MA_AGENT?.trim() || "codex";
|
|
508
|
+
const agent = getAgent(agentType);
|
|
509
|
+
const codexResolution = agentType === "codex" ? await inspectCodexResolution({ fix }) : null;
|
|
325
510
|
if (codexResolution) {
|
|
326
511
|
statuses.push(codexResolution);
|
|
327
512
|
}
|
|
328
513
|
|
|
329
|
-
const
|
|
330
|
-
if (
|
|
331
|
-
statuses.push(makeStatus("OK",
|
|
514
|
+
const installed = inspectAgent(agentType);
|
|
515
|
+
if (installed.ok) {
|
|
516
|
+
statuses.push(makeStatus("OK", `${agent.displayName} command is available`, installed.version));
|
|
332
517
|
} else {
|
|
333
518
|
statuses.push(
|
|
334
519
|
makeStatus(
|
|
335
520
|
"BLOCKED",
|
|
336
|
-
|
|
337
|
-
"Install or repair
|
|
521
|
+
`${agent.displayName} command is not usable`,
|
|
522
|
+
installed.detail || "Install or repair the selected agent command.",
|
|
338
523
|
),
|
|
339
524
|
);
|
|
340
525
|
}
|
|
341
526
|
|
|
342
|
-
const skillInstallRoot = getSkillInstallRoot();
|
|
527
|
+
const skillInstallRoot = getSkillInstallRoot(agent.id);
|
|
343
528
|
if (fix) {
|
|
344
529
|
const result = await ensureSkillsInstalled();
|
|
345
530
|
statuses.push(
|
|
346
531
|
makeStatus(
|
|
347
532
|
result.installed.length > 0 ? "FIXED" : "OK",
|
|
348
|
-
|
|
533
|
+
`${agent.displayName} skills are installed`,
|
|
349
534
|
skillInstallRoot,
|
|
350
535
|
),
|
|
351
536
|
);
|
|
352
537
|
} else {
|
|
538
|
+
const receipt = await readInstallReceipt(skillInstallRoot, "skills");
|
|
353
539
|
statuses.push(
|
|
354
540
|
makeStatus(
|
|
355
541
|
(await areSkillsInstalled()) ? "OK" : "WARN",
|
|
356
|
-
|
|
357
|
-
|
|
542
|
+
`${agent.displayName} skills install state`,
|
|
543
|
+
receipt
|
|
544
|
+
? `${skillInstallRoot} (v${receipt.packageVersion}, receipt present)`
|
|
545
|
+
: `${skillInstallRoot} (receipt missing)`,
|
|
358
546
|
),
|
|
359
547
|
);
|
|
360
548
|
}
|
|
361
549
|
|
|
362
550
|
const supportBundleRoot = getSupportBundleRoot();
|
|
363
|
-
if (
|
|
551
|
+
if (agent.id !== "codex") {
|
|
552
|
+
statuses.push(
|
|
553
|
+
makeStatus("OK", "Codex support bundle", "not applicable to the selected agent surface"),
|
|
554
|
+
);
|
|
555
|
+
} else if (fix) {
|
|
364
556
|
const result = await ensureSupportBundleInstalled();
|
|
365
557
|
statuses.push(
|
|
366
558
|
makeStatus(
|
|
@@ -370,11 +562,14 @@ async function runEnvironmentFlow({ fix, initMcp }) {
|
|
|
370
562
|
),
|
|
371
563
|
);
|
|
372
564
|
} else {
|
|
565
|
+
const receipt = await readInstallReceipt(supportBundleRoot, "support");
|
|
373
566
|
statuses.push(
|
|
374
567
|
makeStatus(
|
|
375
568
|
(await isSupportBundleInstalled()) ? "OK" : "WARN",
|
|
376
569
|
"support bundle install state",
|
|
377
|
-
|
|
570
|
+
receipt
|
|
571
|
+
? `${supportBundleRoot} (v${receipt.bundleVersion}, receipt present)`
|
|
572
|
+
: `${supportBundleRoot} (receipt missing)`,
|
|
378
573
|
),
|
|
379
574
|
);
|
|
380
575
|
}
|
|
@@ -403,35 +598,43 @@ async function runEnvironmentFlow({ fix, initMcp }) {
|
|
|
403
598
|
|
|
404
599
|
statuses.push(await inspectGitMcpState({ fix, initMcp }));
|
|
405
600
|
statuses.push(await inspectLocalCapabilityState({ fix }));
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
601
|
+
statuses.push(...(await inspectContextHealth()));
|
|
602
|
+
statuses.push(await inspectPluginInjectionState());
|
|
603
|
+
if (agent.id === "cursor") {
|
|
604
|
+
try {
|
|
605
|
+
const validation = await validateAgentIntegrations(getRepoRoot(), { targets: ["cursor"] });
|
|
606
|
+
const cursorResult = validation.results.cursor;
|
|
607
|
+
statuses.push(
|
|
608
|
+
makeStatus(
|
|
609
|
+
cursorResult?.status === "valid" ? "OK" : "WARN",
|
|
610
|
+
"Cursor native project rules",
|
|
611
|
+
cursorResult?.status === "valid"
|
|
612
|
+
? ".cursor/rules/agents.mdc validated"
|
|
613
|
+
: cursorResult?.issues?.map((issue) => issue.message).join(", ") || "run `ma setup`",
|
|
614
|
+
),
|
|
615
|
+
);
|
|
616
|
+
} catch (error) {
|
|
617
|
+
statuses.push(makeStatus("WARN", "Cursor native project rules", error.message));
|
|
618
|
+
}
|
|
417
619
|
}
|
|
418
|
-
return
|
|
620
|
+
return statuses;
|
|
419
621
|
}
|
|
420
622
|
|
|
421
623
|
function printStatuses(title, statuses) {
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
624
|
+
if (process.stdout.isTTY) {
|
|
625
|
+
const result = summarizeDoctorStatuses(statuses);
|
|
626
|
+
console.log(title);
|
|
627
|
+
console.log("=".repeat(title.length));
|
|
628
|
+
console.log(renderCheckGrid(statuses));
|
|
629
|
+
console.log(`\nResult: ${result}`);
|
|
630
|
+
console.log(
|
|
631
|
+
result === "BLOCKED"
|
|
632
|
+
? "Next: install or repair blocked prerequisites, then rerun `ma bootstrap`."
|
|
633
|
+
: "Next: start Codex or run `ma run '$maestro'`.",
|
|
634
|
+
);
|
|
635
|
+
return result;
|
|
431
636
|
}
|
|
432
|
-
const result =
|
|
433
|
-
console.log();
|
|
434
|
-
console.log(`Result: ${result}`);
|
|
637
|
+
const result = printDoctorStatuses(title, statuses);
|
|
435
638
|
if (result === "BLOCKED") {
|
|
436
639
|
console.log("Next: install or repair blocked prerequisites, then rerun `ma bootstrap`.");
|
|
437
640
|
} else if (result === "READY_WITH_WARNINGS") {
|
|
@@ -442,16 +645,20 @@ function printStatuses(title, statuses) {
|
|
|
442
645
|
return result;
|
|
443
646
|
}
|
|
444
647
|
|
|
445
|
-
export async function runDoctor() {
|
|
648
|
+
export async function runDoctor({ json = false } = {}) {
|
|
446
649
|
const statuses = await runEnvironmentFlow({ fix: false, initMcp: false });
|
|
650
|
+
const result = summarizeDoctorStatuses(statuses);
|
|
651
|
+
if (json) return { schemaVersion: "0.1.0", scope: "environment", result, statuses };
|
|
447
652
|
return {
|
|
448
653
|
statuses,
|
|
449
654
|
result: printStatuses("Meta-Architect Doctor", statuses),
|
|
450
655
|
};
|
|
451
656
|
}
|
|
452
657
|
|
|
453
|
-
export async function runBootstrap({ initMcp = false } = {}) {
|
|
658
|
+
export async function runBootstrap({ initMcp = false, json = false } = {}) {
|
|
454
659
|
const statuses = await runEnvironmentFlow({ fix: true, initMcp });
|
|
660
|
+
const result = summarizeDoctorStatuses(statuses);
|
|
661
|
+
if (json) return { schemaVersion: "0.1.0", scope: "bootstrap", result, statuses };
|
|
455
662
|
return {
|
|
456
663
|
statuses,
|
|
457
664
|
result: printStatuses("Meta-Architect Bootstrap", statuses),
|
package/src/build-gate.js
CHANGED
|
File without changes
|