@jstn-sdk/ma 0.1.5 → 0.1.7
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 +20 -0
- package/.codex/hooks.json +1 -1
- package/.codex/prompts/enforcement.md +13 -3
- package/.codex/prompts/onboarding.md +29 -14
- package/README.md +536 -129
- package/bin/ma.js +61 -103
- package/docs/README.md +2 -1
- 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 +8 -0
- package/docs/getting-started.md +434 -37
- package/docs/installed-sdk.md +60 -0
- package/docs/mcp-setup.md +46 -134
- package/docs/onboarding.md +41 -11
- package/docs/qa/release-readiness-0.1.5.md +46 -44
- package/docs/qa/release-readiness-0.1.7.md +79 -0
- package/docs/release-spec.md +81 -103
- package/docs/skills-publishing.md +187 -54
- package/docs/skills.md +82 -141
- package/mcp/collections.json +1 -1
- package/mcp/fallback.json +1 -1
- package/mcp/servers.json +1 -1
- package/package.json +17 -14
- package/plugins/meta-architect/.app.json +1 -1
- package/plugins/meta-architect/.codex-plugin/plugin.json +23 -0
- package/plugins/meta-architect/.mcp.json +1 -1
- package/plugins/meta-architect/README.md +23 -10
- package/plugins/meta-architect/skills/arch/SKILL.md +27 -0
- package/plugins/meta-architect/skills/arch/agents/openai.yaml +4 -0
- package/plugins/meta-architect/skills/build/SKILL.md +24 -0
- package/plugins/meta-architect/skills/build/agents/openai.yaml +4 -0
- package/plugins/meta-architect/skills/flow/SKILL.md +24 -0
- package/plugins/meta-architect/skills/flow/agents/openai.yaml +4 -0
- package/plugins/meta-architect/skills/maestro/SKILL.md +25 -0
- package/plugins/meta-architect/skills/maestro/agents/openai.yaml +4 -0
- package/plugins/meta-architect/skills/meta-architect/SKILL.md +19 -23
- package/plugins/meta-architect/skills/meta-architect/agents/openai.yaml +4 -0
- package/plugins/meta-architect/skills/meta-architect/references/core-release-rules.md +13 -0
- package/plugins/meta-architect/skills/sage/SKILL.md +37 -0
- package/plugins/meta-architect/skills/sage/agents/openai.yaml +4 -0
- package/plugins/meta-architect/skills/vet/SKILL.md +25 -0
- package/plugins/meta-architect/skills/vet/agents/openai.yaml +4 -0
- package/plugins/meta-architect/skills/vibe/SKILL.md +24 -0
- package/plugins/meta-architect/skills/vibe/agents/openai.yaml +4 -0
- package/scripts/doctor.js +8 -0
- package/scripts/plugin-sync.js +93 -0
- package/scripts/postinstall.js +23 -0
- package/scripts/release-metadata.js +94 -0
- package/scripts/release-sync.js +359 -0
- package/scripts/release-verify.js +153 -0
- package/scripts/setup-npmrc.js +39 -0
- package/scripts/skills-install.js +4 -36
- package/scripts/skills-manifest.js +1 -1
- package/scripts/skills-validate.js +78 -40
- package/skills/arch/SKILL.md +27 -0
- package/skills/arch/agents/openai.yaml +4 -0
- package/skills/build/SKILL.md +24 -0
- package/skills/build/agents/openai.yaml +4 -0
- package/skills/flow/SKILL.md +24 -0
- package/skills/flow/agents/openai.yaml +4 -0
- package/skills/index.json +27 -22
- package/skills/maestro/SKILL.md +25 -0
- package/skills/maestro/agents/openai.yaml +4 -0
- package/skills/meta-architect/SKILL.md +19 -23
- package/skills/meta-architect/agents/openai.yaml +3 -3
- package/skills/meta-architect/references/core-release-rules.md +2 -2
- package/skills/sage/SKILL.md +37 -0
- package/skills/sage/agents/openai.yaml +4 -0
- package/skills/vet/SKILL.md +25 -0
- package/skills/vet/agents/openai.yaml +4 -0
- package/skills/vibe/SKILL.md +24 -0
- package/skills/vibe/agents/openai.yaml +4 -0
- package/sprint/00-idea.md +1 -1
- package/sprint/01-architecture.md +1 -1
- package/sprint/02-oss-evidence.md +1 -1
- package/sprint/03-logic.md +1 -1
- package/sprint/04-security.md +2 -2
- package/sprint/05-dx-ux.md +1 -1
- package/src/decision-log.js +4 -4
- package/src/launcher.js +21 -17
- package/src/mcp-live-client.js +1 -1
- package/src/paths.js +8 -32
- package/src/release-state.js +3 -3
- package/src/runtime-artifacts.js +411 -0
- package/src/skill-installer.js +198 -0
- package/src/skills.js +473 -166
- package/templates/AGENTS.md +23 -6
- package/templates/model-instructions/core.md +1 -1
- package/.codex/config.toml +0 -2
- package/plugins/meta-architect/skills/meta-architect-arch/SKILL.md +0 -24
- package/plugins/meta-architect/skills/meta-architect-build/SKILL.md +0 -25
- package/plugins/meta-architect/skills/meta-architect-flow/SKILL.md +0 -23
- package/plugins/meta-architect/skills/meta-architect-sage/SKILL.md +0 -23
- package/plugins/meta-architect/skills/meta-architect-vet/SKILL.md +0 -23
- package/plugins/meta-architect/skills/meta-architect-vibe/SKILL.md +0 -24
- package/prompts/architect.md +0 -216
- package/prompts/builder.md +0 -10
- package/prompts/flow.md +0 -9
- package/prompts/release-manager.md +0 -10
- package/prompts/sage.md +0 -10
- package/prompts/security-reviewer.md +0 -10
- package/prompts/verifier.md +0 -10
- package/prompts/vibe.md +0 -10
- package/skills/meta-architect-arch/SKILL.md +0 -24
- package/skills/meta-architect-arch/agents/openai.yaml +0 -4
- package/skills/meta-architect-build/SKILL.md +0 -25
- package/skills/meta-architect-build/agents/openai.yaml +0 -4
- package/skills/meta-architect-flow/SKILL.md +0 -23
- package/skills/meta-architect-flow/agents/openai.yaml +0 -4
- package/skills/meta-architect-sage/SKILL.md +0 -23
- package/skills/meta-architect-sage/agents/openai.yaml +0 -4
- package/skills/meta-architect-vet/SKILL.md +0 -23
- package/skills/meta-architect-vet/agents/openai.yaml +0 -4
- package/skills/meta-architect-vibe/SKILL.md +0 -24
- package/skills/meta-architect-vibe/agents/openai.yaml +0 -4
- package/src/doctor.js +0 -30
- package/src/setup.js +0 -375
package/src/launcher.js
CHANGED
|
@@ -1,52 +1,56 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const nativeCommands = new Set([
|
|
5
5
|
"setup",
|
|
6
6
|
"init",
|
|
7
|
-
"doctor",
|
|
8
7
|
"idea",
|
|
9
8
|
"skills",
|
|
9
|
+
"sdk-path",
|
|
10
10
|
"status",
|
|
11
|
-
"run",
|
|
12
11
|
"merge",
|
|
13
12
|
"release",
|
|
13
|
+
"run",
|
|
14
14
|
]);
|
|
15
15
|
|
|
16
16
|
export function shouldDelegateToCodex(args) {
|
|
17
17
|
if (args.length === 0) {
|
|
18
|
-
return
|
|
18
|
+
return true;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
return first.startsWith("-") || !maintenanceCommands.has(first);
|
|
21
|
+
return !nativeCommands.has(args[0]);
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
function normalizeCodexArgs(args) {
|
|
26
25
|
return args.filter((arg) => arg !== "--madmax" && arg !== "--high");
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
function resolveCodexCommand() {
|
|
30
|
-
|
|
29
|
+
if (process.env.MA_CODEX_BIN) {
|
|
30
|
+
return process.env.MA_CODEX_BIN;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return "codex";
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
export function runCodex(args) {
|
|
34
37
|
const codexCommand = resolveCodexCommand();
|
|
35
38
|
const codexArgs = normalizeCodexArgs(args);
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
const commandArgs =
|
|
40
|
+
path.extname(codexCommand) === ".js" || path.extname(codexCommand) === ".mjs"
|
|
41
|
+
? [codexCommand, ...codexArgs]
|
|
42
|
+
: codexArgs;
|
|
43
|
+
const command = commandArgs[0] === codexCommand ? process.execPath : codexCommand;
|
|
44
|
+
const finalArgs = command === process.execPath ? commandArgs : codexArgs;
|
|
45
|
+
const result = spawnSync(command, finalArgs, { stdio: "inherit" });
|
|
42
46
|
|
|
43
47
|
if (result.error) {
|
|
44
48
|
if (result.error.code === "ENOENT") {
|
|
45
|
-
throw new Error("Codex
|
|
49
|
+
throw new Error("Codex not found. Install it with: npm install -g @openai/codex");
|
|
46
50
|
}
|
|
47
51
|
|
|
48
|
-
throw new Error(`Failed to start Codex
|
|
52
|
+
throw new Error(`Failed to start Codex: ${result.error.message}`);
|
|
49
53
|
}
|
|
50
54
|
|
|
51
|
-
return result.status
|
|
55
|
+
return typeof result.status === "number" ? result.status : 1;
|
|
52
56
|
}
|
package/src/mcp-live-client.js
CHANGED
package/src/paths.js
CHANGED
|
@@ -5,46 +5,22 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
5
5
|
const __dirname = path.dirname(__filename);
|
|
6
6
|
|
|
7
7
|
export const packageRoot = path.resolve(__dirname, "..");
|
|
8
|
-
export function getPackageRoot() {
|
|
9
|
-
return packageRoot;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
8
|
export function getRepoRoot() {
|
|
13
|
-
return path.resolve(process.env.MA_ROOT
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function resolveRepoPath(...parts) {
|
|
17
|
-
return path.join(getRepoRoot(), ...parts);
|
|
9
|
+
return process.env.MA_ROOT ? path.resolve(process.env.MA_ROOT) : process.cwd();
|
|
18
10
|
}
|
|
19
11
|
|
|
20
|
-
export function
|
|
21
|
-
return
|
|
12
|
+
export function getRuntimeRoot() {
|
|
13
|
+
return path.join(getRepoRoot(), ".ma");
|
|
22
14
|
}
|
|
23
15
|
|
|
24
|
-
export function
|
|
25
|
-
return path.join(
|
|
16
|
+
export function getRuntimeWritePath(...parts) {
|
|
17
|
+
return path.join(getRuntimeRoot(), ...parts);
|
|
26
18
|
}
|
|
27
19
|
|
|
28
|
-
export function
|
|
29
|
-
return path.join(
|
|
20
|
+
export function getRuntimeReadPath(...parts) {
|
|
21
|
+
return path.join(getRuntimeRoot(), ...parts);
|
|
30
22
|
}
|
|
31
23
|
|
|
32
24
|
export function getMcpServersPath() {
|
|
33
|
-
return
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function getSourcesPath() {
|
|
37
|
-
return path.join(getOmxRoot(), "evidence", "sources.json");
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export function getAuditsPath() {
|
|
41
|
-
return path.join(getOmxRoot(), "evidence", "audits.json");
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function getOutcomesPath() {
|
|
45
|
-
return path.join(getOmxRoot(), "evidence", "outcomes.json");
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function getCvesPath() {
|
|
49
|
-
return path.join(getOmxRoot(), "evidence", "cves.json");
|
|
25
|
+
return path.join(getRepoRoot(), "mcp", "servers.json");
|
|
50
26
|
}
|
package/src/release-state.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import { writeJson } from "./fs-utils.js";
|
|
3
|
-
import {
|
|
3
|
+
import { getRuntimeReadPath, getRuntimeWritePath } from "./paths.js";
|
|
4
4
|
|
|
5
5
|
const allowedStatuses = {
|
|
6
6
|
idea_status: ["DRAFT", "CLEAR", "BLOCKED"],
|
|
@@ -43,7 +43,7 @@ export function validateReleaseState(state) {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
export async function loadReleaseState() {
|
|
46
|
-
const raw = await fs.readFile(
|
|
46
|
+
const raw = await fs.readFile(getRuntimeReadPath("release.json"), "utf8");
|
|
47
47
|
const parsed = JSON.parse(raw);
|
|
48
48
|
return validateReleaseState(parsed);
|
|
49
49
|
}
|
|
@@ -54,6 +54,6 @@ export async function saveReleaseState(state) {
|
|
|
54
54
|
...state,
|
|
55
55
|
updatedAt: new Date().toISOString(),
|
|
56
56
|
};
|
|
57
|
-
await writeJson(
|
|
57
|
+
await writeJson(getRuntimeWritePath("release.json"), next);
|
|
58
58
|
return next;
|
|
59
59
|
}
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { ensureDir, writeFileIfMissing } from "./fs-utils.js";
|
|
4
|
+
import { getRuntimeWritePath } from "./paths.js";
|
|
5
|
+
|
|
6
|
+
const runtimeDirs = ["context", "specs", "plans"];
|
|
7
|
+
|
|
8
|
+
function renderProjectContext({ idea = null }) {
|
|
9
|
+
return [
|
|
10
|
+
"# Project Context",
|
|
11
|
+
"",
|
|
12
|
+
`Updated: ${new Date().toISOString()}`,
|
|
13
|
+
"",
|
|
14
|
+
"## Current Brief",
|
|
15
|
+
"",
|
|
16
|
+
idea ?? 'No project brief captured yet. Run `ma idea "..."` first.',
|
|
17
|
+
"",
|
|
18
|
+
"## Source Of Truth",
|
|
19
|
+
"",
|
|
20
|
+
"- `.ma/decisions.json` tracks gate and decision history",
|
|
21
|
+
"- `.ma/release.json` tracks release-state fields",
|
|
22
|
+
"- `.ma/runbook.md` defines the local helper workflow",
|
|
23
|
+
"",
|
|
24
|
+
"## Next Recommended Trigger",
|
|
25
|
+
"",
|
|
26
|
+
idea ? "`$arch`" : "`ma idea`",
|
|
27
|
+
"",
|
|
28
|
+
].join("\n");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function renderArchitectureSpec({ idea, blueprint }) {
|
|
32
|
+
return [
|
|
33
|
+
"# Architecture Spec",
|
|
34
|
+
"",
|
|
35
|
+
`Updated: ${new Date().toISOString()}`,
|
|
36
|
+
"",
|
|
37
|
+
"## Problem Statement",
|
|
38
|
+
"",
|
|
39
|
+
idea,
|
|
40
|
+
"",
|
|
41
|
+
"## Blueprint Summary",
|
|
42
|
+
"",
|
|
43
|
+
blueprint.summary,
|
|
44
|
+
"",
|
|
45
|
+
"## Suggested Stack",
|
|
46
|
+
"",
|
|
47
|
+
...blueprint.suggestedStack.map((item) => `- ${item}`),
|
|
48
|
+
"",
|
|
49
|
+
"## Intended Outcome",
|
|
50
|
+
"",
|
|
51
|
+
blueprint.outcome,
|
|
52
|
+
"",
|
|
53
|
+
"## Next Recommended Trigger",
|
|
54
|
+
"",
|
|
55
|
+
"`$sage`",
|
|
56
|
+
"",
|
|
57
|
+
].join("\n");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function renderEvidenceSpec({ idea, sourceEntries, verified, blockers }) {
|
|
61
|
+
const status = verified ? "VERIFIED" : sourceEntries.length > 0 ? "PARTIAL" : "MISSING";
|
|
62
|
+
const lines = [
|
|
63
|
+
"# Evidence Spec",
|
|
64
|
+
"",
|
|
65
|
+
`Updated: ${new Date().toISOString()}`,
|
|
66
|
+
"",
|
|
67
|
+
"## Probe Basis",
|
|
68
|
+
"",
|
|
69
|
+
idea,
|
|
70
|
+
"",
|
|
71
|
+
"## Evidence Status",
|
|
72
|
+
"",
|
|
73
|
+
status,
|
|
74
|
+
"",
|
|
75
|
+
"## Sources",
|
|
76
|
+
"",
|
|
77
|
+
];
|
|
78
|
+
|
|
79
|
+
if (sourceEntries.length === 0) {
|
|
80
|
+
lines.push("No approved GitMCP sources configured.", "");
|
|
81
|
+
} else {
|
|
82
|
+
for (const source of sourceEntries) {
|
|
83
|
+
lines.push(`- ${source.repo} (${source.category})`);
|
|
84
|
+
lines.push(` - endpoint: ${source.endpoint}`);
|
|
85
|
+
if (source.liveProbe?.sampleText) {
|
|
86
|
+
lines.push(` - live probe: ${source.liveProbe.sampleText}`);
|
|
87
|
+
} else if (source.liveProbe?.reason) {
|
|
88
|
+
lines.push(` - live probe: ${source.liveProbe.reason}`);
|
|
89
|
+
} else if (source.liveProbe?.error) {
|
|
90
|
+
lines.push(` - live probe error: ${source.liveProbe.error}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
lines.push("");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
lines.push("## Blockers", "");
|
|
97
|
+
if (blockers.length === 0) {
|
|
98
|
+
lines.push("None.", "");
|
|
99
|
+
} else {
|
|
100
|
+
lines.push(...blockers.map((blocker) => `- ${blocker}`), "");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
lines.push("## Next Recommended Trigger", "", verified ? "`$flow`" : "`$sage`", "");
|
|
104
|
+
return lines.join("\n");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function renderLogicSpec(logicMap) {
|
|
108
|
+
return [
|
|
109
|
+
"# Logic Spec",
|
|
110
|
+
"",
|
|
111
|
+
`Updated: ${new Date().toISOString()}`,
|
|
112
|
+
"",
|
|
113
|
+
"## States",
|
|
114
|
+
"",
|
|
115
|
+
...logicMap.states.map((state) => `- ${state}`),
|
|
116
|
+
"",
|
|
117
|
+
"## Blockers",
|
|
118
|
+
"",
|
|
119
|
+
...(logicMap.blockers.length === 0 ? ["None."] : logicMap.blockers.map((item) => `- ${item}`)),
|
|
120
|
+
"",
|
|
121
|
+
"## Next Recommended Trigger",
|
|
122
|
+
"",
|
|
123
|
+
"`$vet`",
|
|
124
|
+
"",
|
|
125
|
+
].join("\n");
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function renderSecuritySpec({ finding, auditCount, cveCount }) {
|
|
129
|
+
return [
|
|
130
|
+
"# Security Spec",
|
|
131
|
+
"",
|
|
132
|
+
`Updated: ${new Date().toISOString()}`,
|
|
133
|
+
"",
|
|
134
|
+
"## Latest Finding",
|
|
135
|
+
"",
|
|
136
|
+
`- severity: ${finding.severity}`,
|
|
137
|
+
`- summary: ${finding.summary}`,
|
|
138
|
+
`- unresolved: ${finding.unresolved}`,
|
|
139
|
+
"",
|
|
140
|
+
"## Evidence Files",
|
|
141
|
+
"",
|
|
142
|
+
`- audits logged: ${auditCount}`,
|
|
143
|
+
`- cve entries logged: ${cveCount}`,
|
|
144
|
+
"",
|
|
145
|
+
"## Next Recommended Trigger",
|
|
146
|
+
"",
|
|
147
|
+
"`$vibe`",
|
|
148
|
+
"",
|
|
149
|
+
].join("\n");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function renderExperienceSpec({ note, outcomeCount }) {
|
|
153
|
+
return [
|
|
154
|
+
"# Experience Spec",
|
|
155
|
+
"",
|
|
156
|
+
`Updated: ${new Date().toISOString()}`,
|
|
157
|
+
"",
|
|
158
|
+
"## Latest Outcome",
|
|
159
|
+
"",
|
|
160
|
+
`- area: ${note.area}`,
|
|
161
|
+
`- summary: ${note.summary}`,
|
|
162
|
+
"",
|
|
163
|
+
"## Evidence Files",
|
|
164
|
+
"",
|
|
165
|
+
`- outcomes logged: ${outcomeCount}`,
|
|
166
|
+
"",
|
|
167
|
+
"## Next Recommended Trigger",
|
|
168
|
+
"",
|
|
169
|
+
"`$build`",
|
|
170
|
+
"",
|
|
171
|
+
].join("\n");
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function renderImplementationPlan({ idea, blueprint }) {
|
|
175
|
+
return [
|
|
176
|
+
"# Implementation Plan",
|
|
177
|
+
"",
|
|
178
|
+
`Updated: ${new Date().toISOString()}`,
|
|
179
|
+
"",
|
|
180
|
+
"## Goal",
|
|
181
|
+
"",
|
|
182
|
+
idea,
|
|
183
|
+
"",
|
|
184
|
+
"## Planned Phases",
|
|
185
|
+
"",
|
|
186
|
+
"- Capture the approved architecture baseline",
|
|
187
|
+
"- Validate evidence through approved GitMCP sources",
|
|
188
|
+
"- Validate logic and state transitions",
|
|
189
|
+
"- Review security and experience gates",
|
|
190
|
+
"- Unlock bounded build execution",
|
|
191
|
+
"",
|
|
192
|
+
"## Architecture Anchor",
|
|
193
|
+
"",
|
|
194
|
+
blueprint.summary,
|
|
195
|
+
"",
|
|
196
|
+
].join("\n");
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function renderMaestroPlan({ releaseState, recommendation }) {
|
|
200
|
+
return [
|
|
201
|
+
"# Maestro Plan",
|
|
202
|
+
"",
|
|
203
|
+
`Updated: ${new Date().toISOString()}`,
|
|
204
|
+
"",
|
|
205
|
+
"## Current Gate State",
|
|
206
|
+
"",
|
|
207
|
+
`- idea: ${releaseState.idea_status}`,
|
|
208
|
+
`- architecture: ${releaseState.architecture_status}`,
|
|
209
|
+
`- evidence: ${releaseState.evidence_status}`,
|
|
210
|
+
`- logic: ${releaseState.logic_status}`,
|
|
211
|
+
`- security: ${releaseState.security_status}`,
|
|
212
|
+
`- experience: ${releaseState.experience_status}`,
|
|
213
|
+
`- build: ${releaseState.build_status}`,
|
|
214
|
+
"",
|
|
215
|
+
"## Best Next Step",
|
|
216
|
+
"",
|
|
217
|
+
recommendation.nextStep,
|
|
218
|
+
"",
|
|
219
|
+
"## Why This Is Next",
|
|
220
|
+
"",
|
|
221
|
+
recommendation.why,
|
|
222
|
+
"",
|
|
223
|
+
"## Recommended Lane",
|
|
224
|
+
"",
|
|
225
|
+
`- primary: ${recommendation.primaryLane}`,
|
|
226
|
+
`- support: ${recommendation.supportLane}`,
|
|
227
|
+
"",
|
|
228
|
+
"## Suggested Assignment",
|
|
229
|
+
"",
|
|
230
|
+
...recommendation.assignments.map((item) => `- ${item}`),
|
|
231
|
+
"",
|
|
232
|
+
"## Avoid For Now",
|
|
233
|
+
"",
|
|
234
|
+
...recommendation.avoid.map((item) => `- ${item}`),
|
|
235
|
+
"",
|
|
236
|
+
"## Exact Next Trigger",
|
|
237
|
+
"",
|
|
238
|
+
recommendation.nextTrigger,
|
|
239
|
+
"",
|
|
240
|
+
].join("\n");
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function renderBuildPlan({ allowed, blockers, nextTriggers, suggestedBranches = [] }) {
|
|
244
|
+
const lines = [
|
|
245
|
+
"# Build Plan",
|
|
246
|
+
"",
|
|
247
|
+
`Updated: ${new Date().toISOString()}`,
|
|
248
|
+
"",
|
|
249
|
+
"## Gate State",
|
|
250
|
+
"",
|
|
251
|
+
allowed ? "READY" : "LOCKED",
|
|
252
|
+
"",
|
|
253
|
+
"## Blockers",
|
|
254
|
+
"",
|
|
255
|
+
];
|
|
256
|
+
|
|
257
|
+
if (blockers.length === 0) {
|
|
258
|
+
lines.push("None.", "");
|
|
259
|
+
} else {
|
|
260
|
+
lines.push(...blockers.map((blocker) => `- ${blocker}`), "");
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
lines.push("## Next Allowed Triggers", "");
|
|
264
|
+
lines.push(
|
|
265
|
+
...(nextTriggers.length === 0 ? ["- $build"] : nextTriggers.map((item) => `- ${item}`)),
|
|
266
|
+
"",
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
if (suggestedBranches.length > 0) {
|
|
270
|
+
lines.push(
|
|
271
|
+
"## Suggested Branches",
|
|
272
|
+
"",
|
|
273
|
+
...suggestedBranches.map((branch) => `- ${branch}`),
|
|
274
|
+
"",
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return lines.join("\n");
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function renderRunbook() {
|
|
282
|
+
return [
|
|
283
|
+
"# Meta-Architect Runbook",
|
|
284
|
+
"",
|
|
285
|
+
"## Purpose",
|
|
286
|
+
"",
|
|
287
|
+
"This runbook defines the local helper-path workflow that supports the primary in-session skill flow.",
|
|
288
|
+
"",
|
|
289
|
+
"## Canonical Sequence",
|
|
290
|
+
"",
|
|
291
|
+
"1. `ma setup`",
|
|
292
|
+
'2. `ma idea "..."`',
|
|
293
|
+
"3. `ma run '$arch'`",
|
|
294
|
+
"4. `ma run '$sage'`",
|
|
295
|
+
"5. `ma run '$flow'`",
|
|
296
|
+
"6. `ma run '$vet'`",
|
|
297
|
+
"7. `ma run '$vibe'`",
|
|
298
|
+
"8. `ma status`",
|
|
299
|
+
"9. `ma run '$build'`",
|
|
300
|
+
"",
|
|
301
|
+
"## Runtime Artifacts",
|
|
302
|
+
"",
|
|
303
|
+
"- `.ma/context/project.md`",
|
|
304
|
+
"- `.ma/specs/architecture.md`",
|
|
305
|
+
"- `.ma/specs/evidence.md`",
|
|
306
|
+
"- `.ma/specs/logic.md`",
|
|
307
|
+
"- `.ma/specs/security.md`",
|
|
308
|
+
"- `.ma/specs/experience.md`",
|
|
309
|
+
"- `.ma/plans/implementation.md`",
|
|
310
|
+
"- `.ma/plans/build.md`",
|
|
311
|
+
"- `.ma/decisions.json`",
|
|
312
|
+
"- `.ma/release.json`",
|
|
313
|
+
"",
|
|
314
|
+
"## Guardrails",
|
|
315
|
+
"",
|
|
316
|
+
"- Do not edit gate status files manually.",
|
|
317
|
+
"- Treat GitHub release state and npm registry state as separate facts.",
|
|
318
|
+
"- Do not claim a publish channel succeeded without evidence from that channel.",
|
|
319
|
+
"",
|
|
320
|
+
].join("\n");
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
async function writeArtifact(relativePath, content) {
|
|
324
|
+
const target = getRuntimeWritePath(...relativePath.split("/"));
|
|
325
|
+
await ensureDir(path.dirname(target));
|
|
326
|
+
await fs.writeFile(target, `${content.trimEnd()}\n`);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
export async function seedRuntimeArtifacts() {
|
|
330
|
+
for (const dir of runtimeDirs) {
|
|
331
|
+
await ensureDir(getRuntimeWritePath(dir));
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
await writeFileIfMissing(
|
|
335
|
+
getRuntimeWritePath("context", "project.md"),
|
|
336
|
+
`${renderProjectContext({})}\n`,
|
|
337
|
+
);
|
|
338
|
+
await writeFileIfMissing(
|
|
339
|
+
getRuntimeWritePath("specs", "architecture.md"),
|
|
340
|
+
"# Architecture Spec\n\nNo architecture captured yet.\n",
|
|
341
|
+
);
|
|
342
|
+
await writeFileIfMissing(
|
|
343
|
+
getRuntimeWritePath("specs", "evidence.md"),
|
|
344
|
+
"# Evidence Spec\n\nNo evidence captured yet.\n",
|
|
345
|
+
);
|
|
346
|
+
await writeFileIfMissing(
|
|
347
|
+
getRuntimeWritePath("specs", "logic.md"),
|
|
348
|
+
"# Logic Spec\n\nNo logic review captured yet.\n",
|
|
349
|
+
);
|
|
350
|
+
await writeFileIfMissing(
|
|
351
|
+
getRuntimeWritePath("specs", "security.md"),
|
|
352
|
+
"# Security Spec\n\nNo security review captured yet.\n",
|
|
353
|
+
);
|
|
354
|
+
await writeFileIfMissing(
|
|
355
|
+
getRuntimeWritePath("specs", "experience.md"),
|
|
356
|
+
"# Experience Spec\n\nNo experience review captured yet.\n",
|
|
357
|
+
);
|
|
358
|
+
await writeFileIfMissing(
|
|
359
|
+
getRuntimeWritePath("plans", "implementation.md"),
|
|
360
|
+
"# Implementation Plan\n\nNo implementation plan captured yet.\n",
|
|
361
|
+
);
|
|
362
|
+
await writeFileIfMissing(
|
|
363
|
+
getRuntimeWritePath("plans", "build.md"),
|
|
364
|
+
"# Build Plan\n\nBuild is still locked.\n",
|
|
365
|
+
);
|
|
366
|
+
await writeFileIfMissing(getRuntimeWritePath("runbook.md"), `${renderRunbook()}\n`);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
export async function writeProjectContext(idea) {
|
|
370
|
+
await writeArtifact("context/project.md", renderProjectContext({ idea }));
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export async function writeArchitectureArtifacts({ idea, blueprint }) {
|
|
374
|
+
await writeArtifact("specs/architecture.md", renderArchitectureSpec({ idea, blueprint }));
|
|
375
|
+
await writeArtifact("plans/implementation.md", renderImplementationPlan({ idea, blueprint }));
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
export async function writeEvidenceSpec({ idea, sourceEntries, verified, blockers }) {
|
|
379
|
+
await writeArtifact(
|
|
380
|
+
"specs/evidence.md",
|
|
381
|
+
renderEvidenceSpec({ idea, sourceEntries, verified, blockers }),
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export async function writeLogicSpec(logicMap) {
|
|
386
|
+
await writeArtifact("specs/logic.md", renderLogicSpec(logicMap));
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export async function writeSecuritySpec({ finding, auditCount, cveCount }) {
|
|
390
|
+
await writeArtifact("specs/security.md", renderSecuritySpec({ finding, auditCount, cveCount }));
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
export async function writeExperienceSpec({ note, outcomeCount }) {
|
|
394
|
+
await writeArtifact("specs/experience.md", renderExperienceSpec({ note, outcomeCount }));
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
export async function writeBuildPlanArtifact({
|
|
398
|
+
allowed,
|
|
399
|
+
blockers,
|
|
400
|
+
nextTriggers,
|
|
401
|
+
suggestedBranches = [],
|
|
402
|
+
}) {
|
|
403
|
+
await writeArtifact(
|
|
404
|
+
"plans/build.md",
|
|
405
|
+
renderBuildPlan({ allowed, blockers, nextTriggers, suggestedBranches }),
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export async function writeMaestroPlan({ releaseState, recommendation }) {
|
|
410
|
+
await writeArtifact("plans/maestro.md", renderMaestroPlan({ releaseState, recommendation }));
|
|
411
|
+
}
|