@jstn-sdk/ma 0.1.3 → 0.1.5
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/config.toml +2 -0
- package/.codex/hooks.json +1 -1
- package/.codex/prompts/enforcement.md +3 -3
- package/.codex/prompts/onboarding.md +14 -29
- package/README.md +129 -466
- package/bin/ma.js +103 -54
- package/docs/README.md +1 -2
- package/docs/getting-started.md +37 -402
- package/docs/mcp-setup.md +134 -3
- package/docs/onboarding.md +11 -41
- package/docs/qa/release-readiness-0.1.5.md +77 -0
- package/docs/release-spec.md +103 -74
- package/docs/skills-publishing.md +54 -187
- package/docs/skills.md +141 -78
- package/mcp/collections.json +1 -1
- package/mcp/fallback.json +1 -1
- package/mcp/servers.json +1 -1
- package/package.json +14 -16
- package/plugins/meta-architect/.app.json +1 -1
- package/plugins/meta-architect/.mcp.json +1 -1
- package/plugins/meta-architect/README.md +10 -23
- package/plugins/meta-architect/skills/meta-architect/SKILL.md +23 -17
- package/plugins/meta-architect/skills/meta-architect-arch/SKILL.md +24 -0
- package/plugins/meta-architect/skills/meta-architect-build/SKILL.md +25 -0
- package/plugins/meta-architect/skills/meta-architect-flow/SKILL.md +23 -0
- package/plugins/meta-architect/skills/meta-architect-sage/SKILL.md +23 -0
- package/plugins/meta-architect/skills/meta-architect-vet/SKILL.md +23 -0
- package/plugins/meta-architect/skills/meta-architect-vibe/SKILL.md +24 -0
- package/prompts/architect.md +216 -0
- package/prompts/builder.md +10 -0
- package/prompts/flow.md +9 -0
- package/prompts/release-manager.md +10 -0
- package/prompts/sage.md +10 -0
- package/prompts/security-reviewer.md +10 -0
- package/prompts/verifier.md +10 -0
- package/prompts/vibe.md +10 -0
- package/scripts/doctor.js +0 -8
- package/scripts/skills-install.js +36 -4
- package/scripts/skills-manifest.js +1 -1
- package/scripts/skills-validate.js +40 -78
- package/skills/index.json +22 -22
- package/skills/meta-architect/SKILL.md +23 -17
- package/skills/meta-architect/agents/openai.yaml +3 -3
- package/skills/meta-architect/references/core-release-rules.md +2 -2
- package/skills/meta-architect-arch/SKILL.md +24 -0
- package/skills/meta-architect-arch/agents/openai.yaml +4 -0
- package/skills/meta-architect-build/SKILL.md +25 -0
- package/skills/meta-architect-build/agents/openai.yaml +4 -0
- package/skills/meta-architect-flow/SKILL.md +23 -0
- package/skills/meta-architect-flow/agents/openai.yaml +4 -0
- package/skills/meta-architect-sage/SKILL.md +23 -0
- package/skills/meta-architect-sage/agents/openai.yaml +4 -0
- package/skills/meta-architect-vet/SKILL.md +23 -0
- package/skills/meta-architect-vet/agents/openai.yaml +4 -0
- package/skills/meta-architect-vibe/SKILL.md +24 -0
- package/skills/meta-architect-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/doctor.js +30 -0
- package/src/launcher.js +17 -21
- package/src/mcp-live-client.js +1 -1
- package/src/paths.js +32 -8
- package/src/release-state.js +3 -3
- package/src/setup.js +375 -0
- package/src/skills.js +166 -309
- package/templates/AGENTS.md +6 -6
- package/templates/model-instructions/core.md +1 -1
- package/.agents/plugins/marketplace.json +0 -20
- package/docs/assets/meta-architect-logo.png +0 -0
- package/docs/assets/meta-architect-logo.svg +0 -8
- package/docs/installed-sdk.md +0 -60
- package/docs/qa/release-readiness-0.1.3.md +0 -79
- package/plugins/meta-architect/.codex-plugin/plugin.json +0 -23
- package/plugins/meta-architect/skills/arch/SKILL.md +0 -27
- package/plugins/meta-architect/skills/arch/agents/openai.yaml +0 -4
- package/plugins/meta-architect/skills/build/SKILL.md +0 -24
- package/plugins/meta-architect/skills/build/agents/openai.yaml +0 -4
- package/plugins/meta-architect/skills/flow/SKILL.md +0 -24
- package/plugins/meta-architect/skills/flow/agents/openai.yaml +0 -4
- package/plugins/meta-architect/skills/meta-architect/agents/openai.yaml +0 -4
- package/plugins/meta-architect/skills/meta-architect/references/core-release-rules.md +0 -13
- package/plugins/meta-architect/skills/sage/SKILL.md +0 -24
- package/plugins/meta-architect/skills/sage/agents/openai.yaml +0 -4
- package/plugins/meta-architect/skills/vet/SKILL.md +0 -25
- package/plugins/meta-architect/skills/vet/agents/openai.yaml +0 -4
- package/plugins/meta-architect/skills/vibe/SKILL.md +0 -24
- package/plugins/meta-architect/skills/vibe/agents/openai.yaml +0 -4
- package/scripts/plugin-sync.js +0 -92
- package/scripts/postinstall.js +0 -23
- package/scripts/release-metadata.js +0 -94
- package/scripts/release-sync.js +0 -348
- package/scripts/release-verify.js +0 -153
- package/scripts/setup-npmrc.js +0 -39
- package/skills/arch/SKILL.md +0 -27
- package/skills/arch/agents/openai.yaml +0 -4
- package/skills/build/SKILL.md +0 -24
- package/skills/build/agents/openai.yaml +0 -4
- package/skills/flow/SKILL.md +0 -24
- package/skills/flow/agents/openai.yaml +0 -4
- package/skills/sage/SKILL.md +0 -24
- package/skills/sage/agents/openai.yaml +0 -4
- package/skills/vet/SKILL.md +0 -25
- package/skills/vet/agents/openai.yaml +0 -4
- package/skills/vibe/SKILL.md +0 -24
- package/skills/vibe/agents/openai.yaml +0 -4
- package/src/runtime-artifacts.js +0 -363
- package/src/skill-installer.js +0 -198
package/src/skills.js
CHANGED
|
@@ -1,54 +1,46 @@
|
|
|
1
|
-
import fs from "node:fs/promises";
|
|
2
1
|
import path from "node:path";
|
|
3
2
|
import { appendDecision } from "./decision-log.js";
|
|
4
|
-
import { readJson,
|
|
3
|
+
import { readJson, writeJson } from "./fs-utils.js";
|
|
5
4
|
import { validateMcpServers } from "./mcp-config.js";
|
|
6
5
|
import { McpSseClient } from "./mcp-live-client.js";
|
|
7
|
-
import { getRepoRoot, getRuntimeReadPath, getRuntimeWritePath, packageRoot } from "./paths.js";
|
|
8
6
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
} from "./
|
|
7
|
+
getAuditsPath,
|
|
8
|
+
getCvesPath,
|
|
9
|
+
getOutcomesPath,
|
|
10
|
+
getRepoRoot,
|
|
11
|
+
getSourcesPath,
|
|
12
|
+
} from "./paths.js";
|
|
13
|
+
import { loadReleaseState, saveReleaseState } from "./release-state.js";
|
|
14
|
+
import { runSetupScaffold } from "./setup.js";
|
|
17
15
|
import { syncStatusUpdates } from "./state-sync.js";
|
|
18
16
|
|
|
19
17
|
const skillNames = ["$arch", "$sage", "$flow", "$vet", "$vibe", "$build"];
|
|
20
|
-
const workflowTemplates = {
|
|
21
|
-
"arch.skill.md":
|
|
22
|
-
"# `$arch`\n\nProduces blueprint architecture, stack rationale, subsystem design, and tradeoffs.\n",
|
|
23
|
-
"sage.skill.md":
|
|
24
|
-
"# `$sage`\n\nMaps architectural choices to approved OSS candidates from GitMCP-backed collections.\n",
|
|
25
|
-
"vet.skill.md": "# `$vet`\n\nAudits security posture, CVE signals, and safer alternatives.\n",
|
|
26
|
-
"flow.skill.md": "# `$flow`\n\nValidates logic, state transitions, and unresolved blockers.\n",
|
|
27
|
-
"vibe.skill.md":
|
|
28
|
-
"# `$vibe`\n\nReviews developer and user experience risks before build execution.\n",
|
|
29
|
-
"build.skill.md": "# `$build`\n\nChecks gates and plans bounded build execution.\n",
|
|
30
|
-
"sync.skill.md":
|
|
31
|
-
"# `$sync`\n\nReserved for refreshing mapped MCP sources and availability records.\n",
|
|
32
|
-
};
|
|
33
18
|
|
|
34
19
|
export function listSkills() {
|
|
35
20
|
return skillNames;
|
|
36
21
|
}
|
|
37
22
|
|
|
38
23
|
async function readIdeaText() {
|
|
39
|
-
const decisions = await readJson(
|
|
24
|
+
const decisions = await readJson(path.join(getRepoRoot(), ".omx", "decisions.json"));
|
|
40
25
|
const ideaDecision = [...decisions.decisions].reverse().find((entry) => entry.kind === "idea");
|
|
41
26
|
return ideaDecision?.idea ?? null;
|
|
42
27
|
}
|
|
43
28
|
|
|
29
|
+
async function readLatestArchitectureSummary() {
|
|
30
|
+
const decisions = await readJson(path.join(getRepoRoot(), ".omx", "decisions.json"));
|
|
31
|
+
const architectureDecision = [...decisions.decisions]
|
|
32
|
+
.reverse()
|
|
33
|
+
.find((entry) => entry.kind === "skill" && entry.skill === "$arch");
|
|
34
|
+
|
|
35
|
+
return architectureDecision?.evidence?.[0]?.summary ?? null;
|
|
36
|
+
}
|
|
37
|
+
|
|
44
38
|
export async function runIdea(idea) {
|
|
45
39
|
const trimmed = idea.trim();
|
|
46
40
|
if (!trimmed) {
|
|
47
41
|
throw new Error("Idea text is required");
|
|
48
42
|
}
|
|
49
43
|
|
|
50
|
-
await writeProjectContext(trimmed);
|
|
51
|
-
|
|
52
44
|
await appendDecision({
|
|
53
45
|
kind: "idea",
|
|
54
46
|
idea: trimmed,
|
|
@@ -69,13 +61,36 @@ export async function runArch() {
|
|
|
69
61
|
}
|
|
70
62
|
|
|
71
63
|
const blueprint = {
|
|
72
|
-
summary: `
|
|
64
|
+
summary: `Architecture blueprint derived from idea: ${idea}`,
|
|
65
|
+
targetArchitecture: {
|
|
66
|
+
orchestration: "Codex-compatible CLI orchestrator",
|
|
67
|
+
evidence: "GitMCP-backed MCP sources with explicit endpoint allowlist",
|
|
68
|
+
releaseModel: "Gated build, merge, and release states stored locally",
|
|
69
|
+
},
|
|
70
|
+
components: [
|
|
71
|
+
"CLI entrypoint",
|
|
72
|
+
"state and decision storage",
|
|
73
|
+
"MCP configuration",
|
|
74
|
+
"publishable skills bundle",
|
|
75
|
+
"release and packaging surfaces",
|
|
76
|
+
],
|
|
73
77
|
suggestedStack: ["Node.js", "MCP", "GitMCP", "Git worktree"],
|
|
74
|
-
|
|
78
|
+
tradeoffs: [
|
|
79
|
+
"Favor explicit file contracts over hidden runtime magic",
|
|
80
|
+
"Favor bounded build planning over unconstrained generation",
|
|
81
|
+
"Favor evidence-backed recommendation over convenience-only defaults",
|
|
82
|
+
],
|
|
83
|
+
evidenceRequirements: [
|
|
84
|
+
"Major package and framework choices must be backed by configured GitMCP sources",
|
|
85
|
+
],
|
|
86
|
+
downstreamHandoff: {
|
|
87
|
+
sage: "Verify stack choices against approved sources",
|
|
88
|
+
flow: "Model state transitions and blockers",
|
|
89
|
+
vet: "Check security risks and dependency posture",
|
|
90
|
+
build: "Stay locked until evidence, logic, security, and experience are green",
|
|
91
|
+
},
|
|
75
92
|
};
|
|
76
93
|
|
|
77
|
-
await writeArchitectureArtifacts({ idea, blueprint });
|
|
78
|
-
|
|
79
94
|
await appendDecision({
|
|
80
95
|
kind: "skill",
|
|
81
96
|
skill: "$arch",
|
|
@@ -90,6 +105,21 @@ export async function runArch() {
|
|
|
90
105
|
}
|
|
91
106
|
|
|
92
107
|
export async function runSage() {
|
|
108
|
+
const releaseState = await loadReleaseState();
|
|
109
|
+
if (releaseState.architecture_status !== "APPROVED") {
|
|
110
|
+
await appendDecision({
|
|
111
|
+
kind: "skill",
|
|
112
|
+
skill: "$sage",
|
|
113
|
+
decision: "Blocked evidence binding because architecture is not approved",
|
|
114
|
+
status: "UNVERIFIED",
|
|
115
|
+
evidence: [],
|
|
116
|
+
blockers: ["architecture_status must be APPROVED before $sage runs"],
|
|
117
|
+
next_allowed_triggers: ["$arch"],
|
|
118
|
+
});
|
|
119
|
+
await syncStatusUpdates({ evidence_status: "MISSING" });
|
|
120
|
+
throw new Error("Cannot run $sage before architecture is approved");
|
|
121
|
+
}
|
|
122
|
+
|
|
93
123
|
const config = await validateMcpServers();
|
|
94
124
|
const sourceEntries = config.servers.map((server) => ({
|
|
95
125
|
repo: server.repo,
|
|
@@ -98,6 +128,7 @@ export async function runSage() {
|
|
|
98
128
|
}));
|
|
99
129
|
const blockers = [];
|
|
100
130
|
const idea = (await readIdeaText()) ?? "software architecture";
|
|
131
|
+
const architectureSummary = (await readLatestArchitectureSummary()) ?? idea;
|
|
101
132
|
const disableLiveProbe = process.env.MA_DISABLE_LIVE_MCP === "1";
|
|
102
133
|
const probeCandidates = sourceEntries.slice(0, 1);
|
|
103
134
|
let liveSuccessCount = 0;
|
|
@@ -134,7 +165,7 @@ export async function runSage() {
|
|
|
134
165
|
if (searchTool) {
|
|
135
166
|
evidence = await client.request("tools/call", {
|
|
136
167
|
name: searchTool.name,
|
|
137
|
-
arguments: { query:
|
|
168
|
+
arguments: { query: architectureSummary },
|
|
138
169
|
});
|
|
139
170
|
} else if (fetchTool) {
|
|
140
171
|
evidence = await client.request("tools/call", {
|
|
@@ -151,7 +182,11 @@ export async function runSage() {
|
|
|
151
182
|
sampleText:
|
|
152
183
|
evidence?.content?.find((item) => item.type === "text")?.text?.slice(0, 400) ?? null,
|
|
153
184
|
};
|
|
154
|
-
|
|
185
|
+
if (source.liveProbe.sampleText) {
|
|
186
|
+
liveSuccessCount += 1;
|
|
187
|
+
} else {
|
|
188
|
+
blockers.push(`Live MCP query for ${source.repo} did not return usable evidence content`);
|
|
189
|
+
}
|
|
155
190
|
} catch (error) {
|
|
156
191
|
source.liveProbe = {
|
|
157
192
|
error: error.message,
|
|
@@ -162,346 +197,168 @@ export async function runSage() {
|
|
|
162
197
|
}
|
|
163
198
|
}
|
|
164
199
|
|
|
165
|
-
const existing = await readJson(
|
|
200
|
+
const existing = await readJson(getSourcesPath());
|
|
166
201
|
existing.items = sourceEntries;
|
|
167
|
-
await writeJson(
|
|
202
|
+
await writeJson(getSourcesPath(), existing);
|
|
168
203
|
|
|
169
|
-
const verified = sourceEntries.length > 0 &&
|
|
170
|
-
|
|
204
|
+
const verified = sourceEntries.length > 0 && liveSuccessCount > 0;
|
|
205
|
+
const partial = sourceEntries.length > 0 && !verified;
|
|
171
206
|
await appendDecision({
|
|
172
207
|
kind: "skill",
|
|
173
208
|
skill: "$sage",
|
|
174
209
|
decision: "Bound architectural choices to approved GitMCP sources using live MCP queries",
|
|
175
|
-
status: verified ? "VERIFIED" : "UNVERIFIED",
|
|
210
|
+
status: verified ? "VERIFIED" : partial ? "PARTIAL" : "UNVERIFIED",
|
|
176
211
|
evidence: sourceEntries,
|
|
177
212
|
blockers: sourceEntries.length > 0 ? blockers : ["No approved GitMCP sources configured"],
|
|
178
213
|
next_allowed_triggers: verified ? ["$flow"] : ["mcp/servers.json", "$sage"],
|
|
179
214
|
});
|
|
180
215
|
|
|
181
216
|
await syncStatusUpdates({
|
|
182
|
-
evidence_status: verified ? "VERIFIED" :
|
|
217
|
+
evidence_status: verified ? "VERIFIED" : partial ? "PARTIAL" : "MISSING",
|
|
183
218
|
});
|
|
184
219
|
}
|
|
185
220
|
|
|
186
221
|
export async function runFlow() {
|
|
222
|
+
const releaseState = await loadReleaseState();
|
|
223
|
+
const blockers = [];
|
|
224
|
+
if (releaseState.architecture_status !== "APPROVED") {
|
|
225
|
+
blockers.push("architecture_status must be APPROVED before $flow runs");
|
|
226
|
+
}
|
|
227
|
+
if (!["VERIFIED", "PARTIAL"].includes(releaseState.evidence_status)) {
|
|
228
|
+
blockers.push("evidence_status must be VERIFIED or PARTIAL before $flow runs");
|
|
229
|
+
}
|
|
230
|
+
|
|
187
231
|
const logicMap = {
|
|
188
232
|
states: ["idea", "architecture", "evidence", "logic", "security", "experience", "build"],
|
|
189
|
-
blockers
|
|
233
|
+
blockers,
|
|
190
234
|
};
|
|
191
235
|
|
|
192
|
-
await writeLogicSpec(logicMap);
|
|
193
|
-
|
|
194
236
|
await appendDecision({
|
|
195
237
|
kind: "skill",
|
|
196
238
|
skill: "$flow",
|
|
197
|
-
decision:
|
|
198
|
-
|
|
239
|
+
decision:
|
|
240
|
+
blockers.length === 0
|
|
241
|
+
? "Validated logic and state transitions"
|
|
242
|
+
: "Blocked logic validation because prerequisite gates are not ready",
|
|
243
|
+
status: blockers.length === 0 ? "GREEN" : "RED",
|
|
199
244
|
evidence: [logicMap],
|
|
200
|
-
blockers
|
|
201
|
-
next_allowed_triggers: ["$vet"],
|
|
245
|
+
blockers,
|
|
246
|
+
next_allowed_triggers: blockers.length === 0 ? ["$vet"] : ["$sage", "$flow"],
|
|
202
247
|
});
|
|
203
248
|
|
|
204
|
-
await syncStatusUpdates({ logic_status: "GREEN" });
|
|
249
|
+
await syncStatusUpdates({ logic_status: blockers.length === 0 ? "GREEN" : "RED" });
|
|
250
|
+
|
|
251
|
+
if (blockers.length > 0) {
|
|
252
|
+
throw new Error(blockers.join(" "));
|
|
253
|
+
}
|
|
205
254
|
}
|
|
206
255
|
|
|
207
256
|
export async function runVet() {
|
|
208
|
-
const
|
|
209
|
-
const
|
|
257
|
+
const releaseState = await loadReleaseState();
|
|
258
|
+
const blockers = [];
|
|
259
|
+
if (releaseState.logic_status !== "GREEN") {
|
|
260
|
+
blockers.push("logic_status must be GREEN before $vet runs");
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const auditLog = await readJson(getAuditsPath());
|
|
264
|
+
const cveLog = await readJson(getCvesPath());
|
|
210
265
|
const finding = {
|
|
211
|
-
severity: "INFO",
|
|
212
|
-
summary:
|
|
213
|
-
|
|
266
|
+
severity: blockers.length === 0 ? "INFO" : "HIGH",
|
|
267
|
+
summary:
|
|
268
|
+
blockers.length === 0
|
|
269
|
+
? "Baseline review completed for the approved kernel"
|
|
270
|
+
: "Security review blocked because logic prerequisites are incomplete",
|
|
271
|
+
unresolved: blockers.length > 0,
|
|
214
272
|
};
|
|
215
273
|
auditLog.items.push(finding);
|
|
216
|
-
await writeJson(
|
|
274
|
+
await writeJson(getAuditsPath(), auditLog);
|
|
217
275
|
cveLog.items.push({
|
|
218
276
|
id: "baseline-review",
|
|
219
277
|
severity: "INFO",
|
|
220
278
|
unresolved: false,
|
|
221
279
|
});
|
|
222
|
-
await writeJson(
|
|
223
|
-
await writeSecuritySpec({
|
|
224
|
-
finding,
|
|
225
|
-
auditCount: auditLog.items.length,
|
|
226
|
-
cveCount: cveLog.items.length,
|
|
227
|
-
});
|
|
280
|
+
await writeJson(getCvesPath(), cveLog);
|
|
228
281
|
|
|
229
282
|
await appendDecision({
|
|
230
283
|
kind: "skill",
|
|
231
284
|
skill: "$vet",
|
|
232
|
-
decision:
|
|
233
|
-
|
|
285
|
+
decision:
|
|
286
|
+
blockers.length === 0
|
|
287
|
+
? "Reviewed security posture for the current implementation"
|
|
288
|
+
: "Blocked security review because logic is not green",
|
|
289
|
+
status: blockers.length === 0 ? "GREEN" : "RED",
|
|
234
290
|
evidence: [finding],
|
|
235
|
-
blockers
|
|
236
|
-
next_allowed_triggers: ["$vibe"],
|
|
291
|
+
blockers,
|
|
292
|
+
next_allowed_triggers: blockers.length === 0 ? ["$vibe"] : ["$flow", "$vet"],
|
|
237
293
|
});
|
|
238
294
|
|
|
239
|
-
await syncStatusUpdates({ security_status: "GREEN" });
|
|
295
|
+
await syncStatusUpdates({ security_status: blockers.length === 0 ? "GREEN" : "RED" });
|
|
296
|
+
|
|
297
|
+
if (blockers.length > 0) {
|
|
298
|
+
throw new Error(blockers.join(" "));
|
|
299
|
+
}
|
|
240
300
|
}
|
|
241
301
|
|
|
242
|
-
export async function runVibe() {
|
|
243
|
-
const
|
|
302
|
+
export async function runVibe(options = {}) {
|
|
303
|
+
const releaseState = await loadReleaseState();
|
|
304
|
+
const blockers = [];
|
|
305
|
+
if (releaseState.security_status !== "GREEN") {
|
|
306
|
+
blockers.push("security_status must be GREEN before $vibe runs");
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const outcomes = await readJson(getOutcomesPath());
|
|
244
310
|
const note = {
|
|
245
311
|
area: "developer-experience",
|
|
246
|
-
summary:
|
|
312
|
+
summary:
|
|
313
|
+
blockers.length === 0
|
|
314
|
+
? "Core CLI and gated workflow remain the primary operator surface"
|
|
315
|
+
: "Experience review blocked because security is not green",
|
|
247
316
|
};
|
|
248
317
|
outcomes.items.push(note);
|
|
249
|
-
await writeJson(
|
|
250
|
-
await writeExperienceSpec({ note, outcomeCount: outcomes.items.length });
|
|
318
|
+
await writeJson(getOutcomesPath(), outcomes);
|
|
251
319
|
|
|
252
320
|
await appendDecision({
|
|
253
321
|
kind: "skill",
|
|
254
322
|
skill: "$vibe",
|
|
255
|
-
decision:
|
|
256
|
-
|
|
323
|
+
decision:
|
|
324
|
+
blockers.length === 0
|
|
325
|
+
? options.waive
|
|
326
|
+
? "Recorded DX/UX waiver decision"
|
|
327
|
+
: "Recorded DX/UX review notes"
|
|
328
|
+
: "Blocked experience review because security is not green",
|
|
329
|
+
status: blockers.length === 0 ? (options.waive ? "WAIVED" : "GREEN") : "RED",
|
|
257
330
|
evidence: [note],
|
|
258
|
-
blockers
|
|
259
|
-
next_allowed_triggers: ["$build"],
|
|
331
|
+
blockers,
|
|
332
|
+
next_allowed_triggers: blockers.length === 0 ? ["$build"] : ["$vet", "$vibe"],
|
|
260
333
|
});
|
|
261
334
|
|
|
262
|
-
await syncStatusUpdates({
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
export async function runInit() {
|
|
266
|
-
const created = [];
|
|
267
|
-
const targets = [
|
|
268
|
-
".codex/agents",
|
|
269
|
-
".codex/prompts",
|
|
270
|
-
".ma/skills",
|
|
271
|
-
".ma/evidence",
|
|
272
|
-
".ma/context",
|
|
273
|
-
".ma/specs",
|
|
274
|
-
".ma/plans",
|
|
275
|
-
"mcp",
|
|
276
|
-
"docs",
|
|
277
|
-
"docs/qa",
|
|
278
|
-
"sprint",
|
|
279
|
-
];
|
|
280
|
-
|
|
281
|
-
for (const relative of targets) {
|
|
282
|
-
const target = path.join(getRepoRoot(), relative);
|
|
283
|
-
await fs.mkdir(target, { recursive: true });
|
|
284
|
-
created.push(relative);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const templateCopies = [
|
|
288
|
-
[
|
|
289
|
-
path.join(packageRoot, ".codex", "agents", "Architect.toml"),
|
|
290
|
-
path.join(getRepoRoot(), ".codex", "agents", "Architect.toml"),
|
|
291
|
-
],
|
|
292
|
-
[
|
|
293
|
-
path.join(packageRoot, ".codex", "agents", "Sage.toml"),
|
|
294
|
-
path.join(getRepoRoot(), ".codex", "agents", "Sage.toml"),
|
|
295
|
-
],
|
|
296
|
-
[
|
|
297
|
-
path.join(packageRoot, ".codex", "agents", "Auditor.toml"),
|
|
298
|
-
path.join(getRepoRoot(), ".codex", "agents", "Auditor.toml"),
|
|
299
|
-
],
|
|
300
|
-
[
|
|
301
|
-
path.join(packageRoot, ".codex", "agents", "Flow.toml"),
|
|
302
|
-
path.join(getRepoRoot(), ".codex", "agents", "Flow.toml"),
|
|
303
|
-
],
|
|
304
|
-
[
|
|
305
|
-
path.join(packageRoot, ".codex", "agents", "Vibe.toml"),
|
|
306
|
-
path.join(getRepoRoot(), ".codex", "agents", "Vibe.toml"),
|
|
307
|
-
],
|
|
308
|
-
[
|
|
309
|
-
path.join(packageRoot, ".codex", "agents", "Builder.toml"),
|
|
310
|
-
path.join(getRepoRoot(), ".codex", "agents", "Builder.toml"),
|
|
311
|
-
],
|
|
312
|
-
[
|
|
313
|
-
path.join(packageRoot, ".codex", "hooks.json"),
|
|
314
|
-
path.join(getRepoRoot(), ".codex", "hooks.json"),
|
|
315
|
-
],
|
|
316
|
-
[
|
|
317
|
-
path.join(packageRoot, ".codex", "prompts", "enforcement.md"),
|
|
318
|
-
path.join(getRepoRoot(), ".codex", "prompts", "enforcement.md"),
|
|
319
|
-
],
|
|
320
|
-
[
|
|
321
|
-
path.join(packageRoot, ".codex", "prompts", "release-rules.md"),
|
|
322
|
-
path.join(getRepoRoot(), ".codex", "prompts", "release-rules.md"),
|
|
323
|
-
],
|
|
324
|
-
[
|
|
325
|
-
path.join(packageRoot, ".codex", "prompts", "skill-contract.md"),
|
|
326
|
-
path.join(getRepoRoot(), ".codex", "prompts", "skill-contract.md"),
|
|
327
|
-
],
|
|
328
|
-
[
|
|
329
|
-
path.join(packageRoot, ".codex", "prompts", "onboarding.md"),
|
|
330
|
-
path.join(getRepoRoot(), ".codex", "prompts", "onboarding.md"),
|
|
331
|
-
],
|
|
332
|
-
[path.join(packageRoot, "docs", "README.md"), path.join(getRepoRoot(), "docs", "README.md")],
|
|
333
|
-
[
|
|
334
|
-
path.join(packageRoot, "docs", "getting-started.md"),
|
|
335
|
-
path.join(getRepoRoot(), "docs", "getting-started.md"),
|
|
336
|
-
],
|
|
337
|
-
[path.join(packageRoot, "docs", "skills.md"), path.join(getRepoRoot(), "docs", "skills.md")],
|
|
338
|
-
[
|
|
339
|
-
path.join(packageRoot, "docs", "mcp-setup.md"),
|
|
340
|
-
path.join(getRepoRoot(), "docs", "mcp-setup.md"),
|
|
341
|
-
],
|
|
342
|
-
[
|
|
343
|
-
path.join(packageRoot, "docs", "release-spec.md"),
|
|
344
|
-
path.join(getRepoRoot(), "docs", "release-spec.md"),
|
|
345
|
-
],
|
|
346
|
-
[
|
|
347
|
-
path.join(packageRoot, "docs", "qa", "release-readiness-0.1.3.md"),
|
|
348
|
-
path.join(getRepoRoot(), "docs", "qa", "release-readiness-0.1.3.md"),
|
|
349
|
-
],
|
|
350
|
-
];
|
|
351
|
-
|
|
352
|
-
const sprintFiles = [
|
|
353
|
-
"00-idea.md",
|
|
354
|
-
"01-architecture.md",
|
|
355
|
-
"02-oss-evidence.md",
|
|
356
|
-
"03-logic.md",
|
|
357
|
-
"04-security.md",
|
|
358
|
-
"05-dx-ux.md",
|
|
359
|
-
"06-build-plan.md",
|
|
360
|
-
"07-release.md",
|
|
361
|
-
];
|
|
362
|
-
|
|
363
|
-
for (const file of sprintFiles) {
|
|
364
|
-
templateCopies.push([
|
|
365
|
-
path.join(packageRoot, "sprint", file),
|
|
366
|
-
path.join(getRepoRoot(), "sprint", file),
|
|
367
|
-
]);
|
|
368
|
-
}
|
|
335
|
+
await syncStatusUpdates({
|
|
336
|
+
experience_status: blockers.length === 0 ? (options.waive ? "WAIVED" : "GREEN") : "RED",
|
|
337
|
+
});
|
|
369
338
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
339
|
+
if (blockers.length === 0 && options.waive) {
|
|
340
|
+
const nextRelease = {
|
|
341
|
+
...(await loadReleaseState()),
|
|
342
|
+
waiver: {
|
|
343
|
+
reason: options.reason ?? "DX/UX waiver approved for the current build",
|
|
344
|
+
actor: "ma run $vibe --waive",
|
|
345
|
+
timestamp: new Date().toISOString(),
|
|
346
|
+
},
|
|
347
|
+
};
|
|
348
|
+
await saveReleaseState(nextRelease);
|
|
375
349
|
}
|
|
376
350
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
await fs.access(dest);
|
|
380
|
-
} catch {
|
|
381
|
-
await fs.copyFile(src, dest);
|
|
382
|
-
}
|
|
351
|
+
if (blockers.length > 0) {
|
|
352
|
+
throw new Error(blockers.join(" "));
|
|
383
353
|
}
|
|
354
|
+
}
|
|
384
355
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
await writeFileIfMissing(
|
|
388
|
-
getRuntimeWritePath("decisions.json"),
|
|
389
|
-
`${JSON.stringify(
|
|
390
|
-
{
|
|
391
|
-
schemaVersion: "0.1.0",
|
|
392
|
-
idea_status: "DRAFT",
|
|
393
|
-
architecture_status: "DRAFT",
|
|
394
|
-
evidence_status: "MISSING",
|
|
395
|
-
logic_status: "PENDING",
|
|
396
|
-
security_status: "PENDING",
|
|
397
|
-
experience_status: "PENDING",
|
|
398
|
-
build_status: "LOCKED",
|
|
399
|
-
merge_status: "LOCKED",
|
|
400
|
-
release_status: "LOCKED",
|
|
401
|
-
decisions: [],
|
|
402
|
-
},
|
|
403
|
-
null,
|
|
404
|
-
2,
|
|
405
|
-
)}\n`,
|
|
406
|
-
);
|
|
407
|
-
|
|
408
|
-
await writeFileIfMissing(
|
|
409
|
-
getRuntimeWritePath("release.json"),
|
|
410
|
-
`${JSON.stringify(
|
|
411
|
-
{
|
|
412
|
-
schemaVersion: "0.1.0",
|
|
413
|
-
idea_status: "DRAFT",
|
|
414
|
-
architecture_status: "DRAFT",
|
|
415
|
-
evidence_status: "MISSING",
|
|
416
|
-
logic_status: "PENDING",
|
|
417
|
-
security_status: "PENDING",
|
|
418
|
-
experience_status: "PENDING",
|
|
419
|
-
build_status: "LOCKED",
|
|
420
|
-
merge_status: "LOCKED",
|
|
421
|
-
release_status: "LOCKED",
|
|
422
|
-
waiver: null,
|
|
423
|
-
updatedAt: new Date().toISOString(),
|
|
424
|
-
},
|
|
425
|
-
null,
|
|
426
|
-
2,
|
|
427
|
-
)}\n`,
|
|
428
|
-
);
|
|
356
|
+
export async function runInit() {
|
|
357
|
+
const { created, warnings } = await runSetupScaffold();
|
|
429
358
|
|
|
430
|
-
for (const
|
|
431
|
-
|
|
359
|
+
for (const warning of warnings) {
|
|
360
|
+
console.warn(`[ma setup] ${warning}`);
|
|
432
361
|
}
|
|
433
362
|
|
|
434
|
-
await writeFileIfMissing(
|
|
435
|
-
path.join(getRepoRoot(), "mcp", "servers.json"),
|
|
436
|
-
`${JSON.stringify({ schemaVersion: "0.1.0", servers: [] }, null, 2)}\n`,
|
|
437
|
-
);
|
|
438
|
-
await writeFileIfMissing(
|
|
439
|
-
path.join(getRepoRoot(), "mcp", "collections.json"),
|
|
440
|
-
`${JSON.stringify({ schemaVersion: "0.1.0", collections: {} }, null, 2)}\n`,
|
|
441
|
-
);
|
|
442
|
-
await writeFileIfMissing(
|
|
443
|
-
path.join(getRepoRoot(), "mcp", "fallback.json"),
|
|
444
|
-
`${JSON.stringify(
|
|
445
|
-
{
|
|
446
|
-
schemaVersion: "0.1.0",
|
|
447
|
-
fallback: {
|
|
448
|
-
endpoint: "https://gitmcp.io/docs",
|
|
449
|
-
policy: "Use only when no approved exact endpoint exists.",
|
|
450
|
-
},
|
|
451
|
-
},
|
|
452
|
-
null,
|
|
453
|
-
2,
|
|
454
|
-
)}\n`,
|
|
455
|
-
);
|
|
456
|
-
await writeFileIfMissing(
|
|
457
|
-
getRuntimeWritePath("evidence", "sources.json"),
|
|
458
|
-
`${JSON.stringify(
|
|
459
|
-
{
|
|
460
|
-
schemaVersion: "0.1.0",
|
|
461
|
-
items: [],
|
|
462
|
-
},
|
|
463
|
-
null,
|
|
464
|
-
2,
|
|
465
|
-
)}\n`,
|
|
466
|
-
);
|
|
467
|
-
await writeFileIfMissing(
|
|
468
|
-
getRuntimeWritePath("evidence", "audits.json"),
|
|
469
|
-
`${JSON.stringify(
|
|
470
|
-
{
|
|
471
|
-
schemaVersion: "0.1.0",
|
|
472
|
-
items: [],
|
|
473
|
-
},
|
|
474
|
-
null,
|
|
475
|
-
2,
|
|
476
|
-
)}\n`,
|
|
477
|
-
);
|
|
478
|
-
await writeFileIfMissing(
|
|
479
|
-
getRuntimeWritePath("evidence", "outcomes.json"),
|
|
480
|
-
`${JSON.stringify(
|
|
481
|
-
{
|
|
482
|
-
schemaVersion: "0.1.0",
|
|
483
|
-
items: [],
|
|
484
|
-
},
|
|
485
|
-
null,
|
|
486
|
-
2,
|
|
487
|
-
)}\n`,
|
|
488
|
-
);
|
|
489
|
-
await writeFileIfMissing(
|
|
490
|
-
getRuntimeWritePath("evidence", "cves.json"),
|
|
491
|
-
`${JSON.stringify(
|
|
492
|
-
{
|
|
493
|
-
schemaVersion: "0.1.0",
|
|
494
|
-
items: [],
|
|
495
|
-
},
|
|
496
|
-
null,
|
|
497
|
-
2,
|
|
498
|
-
)}\n`,
|
|
499
|
-
);
|
|
500
|
-
|
|
501
|
-
await writeFileIfMissing(
|
|
502
|
-
path.join(getRepoRoot(), "docs", "onboarding.md"),
|
|
503
|
-
"# Onboarding\n\nMeta-Architect initializes the core scaffold, MCP config, and canonical .ma runtime files.\n",
|
|
504
|
-
);
|
|
505
|
-
|
|
506
363
|
return created;
|
|
507
364
|
}
|
package/templates/AGENTS.md
CHANGED
|
@@ -80,11 +80,11 @@ Major technology recommendations must be supported by evidence from configured M
|
|
|
80
80
|
|
|
81
81
|
Architecture decisions, evidence, audits, and release-relevant outcomes should be written to repository-visible local files where applicable, especially:
|
|
82
82
|
|
|
83
|
-
- `.
|
|
84
|
-
- `.
|
|
85
|
-
- `.
|
|
86
|
-
- `.
|
|
87
|
-
- `.
|
|
83
|
+
- `.omx/decisions.json`
|
|
84
|
+
- `.omx/release.json`
|
|
85
|
+
- `.omx/evidence/sources.json`
|
|
86
|
+
- `.omx/evidence/audits.json`
|
|
87
|
+
- `.omx/evidence/cves.json`
|
|
88
88
|
|
|
89
89
|
## Skill routing
|
|
90
90
|
|
|
@@ -104,7 +104,7 @@ When working in this repository:
|
|
|
104
104
|
- prefer explicit reasoning and explicit file changes
|
|
105
105
|
- do not skip validation steps silently
|
|
106
106
|
- do not weaken hooks or gates for convenience
|
|
107
|
-
- do not commit runtime `.
|
|
107
|
+
- do not commit runtime `.omx` state
|
|
108
108
|
- do not treat release-sensitive changes as trivial edits
|
|
109
109
|
|
|
110
110
|
## Contributor expectation
|
|
@@ -6,7 +6,7 @@ Use these instructions when generating or applying repository content to the Met
|
|
|
6
6
|
|
|
7
7
|
- Keep Meta-Architect skills, gates, evidence, and release behavior explicit.
|
|
8
8
|
- Prefer inspectable files over hidden side effects.
|
|
9
|
-
- Do not bypass the `.
|
|
9
|
+
- Do not bypass the `.omx` gate model.
|
|
10
10
|
- Treat CLI, skill contracts, plugin surfaces, and docs as one coherent product system.
|
|
11
11
|
|
|
12
12
|
## Kernel rule
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "meta-architect-local",
|
|
3
|
-
"interface": {
|
|
4
|
-
"displayName": "Meta-Architect Local Plugins"
|
|
5
|
-
},
|
|
6
|
-
"plugins": [
|
|
7
|
-
{
|
|
8
|
-
"name": "meta-architect",
|
|
9
|
-
"source": {
|
|
10
|
-
"source": "local",
|
|
11
|
-
"path": "./plugins/meta-architect"
|
|
12
|
-
},
|
|
13
|
-
"policy": {
|
|
14
|
-
"installation": "AVAILABLE",
|
|
15
|
-
"authentication": "ON_INSTALL"
|
|
16
|
-
},
|
|
17
|
-
"category": "Developer Tools"
|
|
18
|
-
}
|
|
19
|
-
]
|
|
20
|
-
}
|
|
Binary file
|