@jstn-sdk/ma 0.1.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/.agents/plugins/marketplace.json +20 -0
- package/.codex/agents/Architect.toml +4 -0
- package/.codex/agents/Auditor.toml +4 -0
- package/.codex/agents/Builder.toml +4 -0
- package/.codex/agents/Flow.toml +4 -0
- package/.codex/agents/Sage.toml +4 -0
- package/.codex/agents/Vibe.toml +4 -0
- package/.codex/hooks.json +15 -0
- package/.codex/prompts/enforcement.md +59 -0
- package/.codex/prompts/onboarding.md +41 -0
- package/.codex/prompts/release-rules.md +28 -0
- package/.codex/prompts/skill-contract.md +41 -0
- package/LICENSE +21 -0
- package/README.md +532 -0
- package/bin/ma.js +300 -0
- package/bin/meta-architect.js +3 -0
- package/docs/README.md +24 -0
- package/docs/assets/meta-architect-logo.png +0 -0
- package/docs/assets/meta-architect-logo.svg +8 -0
- package/docs/getting-started.md +451 -0
- package/docs/mcp-setup.md +5 -0
- package/docs/onboarding.md +65 -0
- package/docs/qa/release-readiness-0.1.0.md +62 -0
- package/docs/release-spec.md +86 -0
- package/docs/skills-publishing.md +231 -0
- package/docs/skills.md +91 -0
- package/index.js +28 -0
- package/mcp/collections.json +21 -0
- package/mcp/fallback.json +7 -0
- package/mcp/servers.json +55 -0
- package/package.json +84 -0
- package/plugins/meta-architect/.app.json +8 -0
- package/plugins/meta-architect/.codex-plugin/plugin.json +23 -0
- package/plugins/meta-architect/.mcp.json +12 -0
- package/plugins/meta-architect/README.md +121 -0
- 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/meta-architect/SKILL.md +30 -0
- 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 +24 -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 +37 -0
- package/scripts/plugin-sync.js +92 -0
- package/scripts/postinstall.js +19 -0
- package/scripts/release-metadata.js +94 -0
- package/scripts/release-verify.js +153 -0
- package/scripts/setup-npmrc.js +39 -0
- package/scripts/skills-install.js +29 -0
- package/scripts/skills-manifest.js +61 -0
- package/scripts/skills-pack.js +54 -0
- package/scripts/skills-validate.js +118 -0
- 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 +40 -0
- package/skills/meta-architect/SKILL.md +30 -0
- package/skills/meta-architect/agents/openai.yaml +4 -0
- package/skills/meta-architect/references/core-release-rules.md +13 -0
- package/skills/sage/SKILL.md +24 -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 +27 -0
- package/sprint/01-architecture.md +26 -0
- package/sprint/02-oss-evidence.md +26 -0
- package/sprint/03-logic.md +25 -0
- package/sprint/04-security.md +25 -0
- package/sprint/05-dx-ux.md +24 -0
- package/sprint/06-build-plan.md +26 -0
- package/sprint/07-release.md +26 -0
- package/src/build-gate.js +52 -0
- package/src/decision-log.js +40 -0
- package/src/fs-utils.js +25 -0
- package/src/launcher.js +55 -0
- package/src/mcp-config.js +30 -0
- package/src/mcp-live-client.js +186 -0
- package/src/paths.js +26 -0
- package/src/policy.js +23 -0
- package/src/release-state.js +59 -0
- package/src/runtime-artifacts.js +363 -0
- package/src/skill-installer.js +49 -0
- package/src/skills.js +507 -0
- package/src/state-sync.js +15 -0
package/src/skills.js
ADDED
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { appendDecision } from "./decision-log.js";
|
|
4
|
+
import { readJson, writeFileIfMissing, writeJson } from "./fs-utils.js";
|
|
5
|
+
import { validateMcpServers } from "./mcp-config.js";
|
|
6
|
+
import { McpSseClient } from "./mcp-live-client.js";
|
|
7
|
+
import { getRepoRoot, getRuntimeReadPath, getRuntimeWritePath, packageRoot } from "./paths.js";
|
|
8
|
+
import {
|
|
9
|
+
seedRuntimeArtifacts,
|
|
10
|
+
writeArchitectureArtifacts,
|
|
11
|
+
writeEvidenceSpec,
|
|
12
|
+
writeExperienceSpec,
|
|
13
|
+
writeLogicSpec,
|
|
14
|
+
writeProjectContext,
|
|
15
|
+
writeSecuritySpec,
|
|
16
|
+
} from "./runtime-artifacts.js";
|
|
17
|
+
import { syncStatusUpdates } from "./state-sync.js";
|
|
18
|
+
|
|
19
|
+
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
|
+
|
|
34
|
+
export function listSkills() {
|
|
35
|
+
return skillNames;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function readIdeaText() {
|
|
39
|
+
const decisions = await readJson(getRuntimeReadPath("decisions.json"));
|
|
40
|
+
const ideaDecision = [...decisions.decisions].reverse().find((entry) => entry.kind === "idea");
|
|
41
|
+
return ideaDecision?.idea ?? null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function runIdea(idea) {
|
|
45
|
+
const trimmed = idea.trim();
|
|
46
|
+
if (!trimmed) {
|
|
47
|
+
throw new Error("Idea text is required");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
await writeProjectContext(trimmed);
|
|
51
|
+
|
|
52
|
+
await appendDecision({
|
|
53
|
+
kind: "idea",
|
|
54
|
+
idea: trimmed,
|
|
55
|
+
decision: "Captured project idea",
|
|
56
|
+
status: "CLEAR",
|
|
57
|
+
evidence: [{ kind: "user-input", value: trimmed }],
|
|
58
|
+
blockers: [],
|
|
59
|
+
next_allowed_triggers: ["$arch"],
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
await syncStatusUpdates({ idea_status: "CLEAR" });
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function runArch() {
|
|
66
|
+
const idea = await readIdeaText();
|
|
67
|
+
if (!idea) {
|
|
68
|
+
throw new Error("Cannot run $arch before ma idea captures a project brief");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const blueprint = {
|
|
72
|
+
summary: `Blueprint derived from idea: ${idea}`,
|
|
73
|
+
suggestedStack: ["Node.js", "MCP", "GitMCP", "Git worktree"],
|
|
74
|
+
outcome: "Produce a gated architecture and implementation plan",
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
await writeArchitectureArtifacts({ idea, blueprint });
|
|
78
|
+
|
|
79
|
+
await appendDecision({
|
|
80
|
+
kind: "skill",
|
|
81
|
+
skill: "$arch",
|
|
82
|
+
decision: "Generated architecture blueprint",
|
|
83
|
+
status: "APPROVED",
|
|
84
|
+
evidence: [blueprint],
|
|
85
|
+
blockers: [],
|
|
86
|
+
next_allowed_triggers: ["$sage"],
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
await syncStatusUpdates({ architecture_status: "APPROVED" });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export async function runSage() {
|
|
93
|
+
const config = await validateMcpServers();
|
|
94
|
+
const sourceEntries = config.servers.map((server) => ({
|
|
95
|
+
repo: server.repo,
|
|
96
|
+
endpoint: server.endpoint,
|
|
97
|
+
category: server.category,
|
|
98
|
+
}));
|
|
99
|
+
const blockers = [];
|
|
100
|
+
const idea = (await readIdeaText()) ?? "software architecture";
|
|
101
|
+
const disableLiveProbe = process.env.MA_DISABLE_LIVE_MCP === "1";
|
|
102
|
+
const probeCandidates = sourceEntries.slice(0, 1);
|
|
103
|
+
let liveSuccessCount = 0;
|
|
104
|
+
|
|
105
|
+
for (const source of sourceEntries) {
|
|
106
|
+
if (disableLiveProbe) {
|
|
107
|
+
source.liveProbe = {
|
|
108
|
+
skipped: true,
|
|
109
|
+
reason: "MA_DISABLE_LIVE_MCP=1",
|
|
110
|
+
};
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (!probeCandidates.includes(source)) {
|
|
115
|
+
source.liveProbe = {
|
|
116
|
+
skipped: true,
|
|
117
|
+
reason: "Not selected for the live probe set in this run",
|
|
118
|
+
};
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const client = new McpSseClient(source.endpoint);
|
|
123
|
+
try {
|
|
124
|
+
const init = await client.connect();
|
|
125
|
+
const tools = await client.request("tools/list", {});
|
|
126
|
+
const searchTool = tools.tools?.find(
|
|
127
|
+
(tool) => tool.name.includes("search_") && tool.name.endsWith("_documentation"),
|
|
128
|
+
);
|
|
129
|
+
const fetchTool = tools.tools?.find(
|
|
130
|
+
(tool) => tool.name.includes("fetch_") && tool.name.endsWith("_documentation"),
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
let evidence = null;
|
|
134
|
+
if (searchTool) {
|
|
135
|
+
evidence = await client.request("tools/call", {
|
|
136
|
+
name: searchTool.name,
|
|
137
|
+
arguments: { query: idea },
|
|
138
|
+
});
|
|
139
|
+
} else if (fetchTool) {
|
|
140
|
+
evidence = await client.request("tools/call", {
|
|
141
|
+
name: fetchTool.name,
|
|
142
|
+
arguments: {},
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
source.liveProbe = {
|
|
147
|
+
serverName: init.serverInfo?.name ?? "unknown",
|
|
148
|
+
serverVersion: init.serverInfo?.version ?? "unknown",
|
|
149
|
+
toolsCount: tools.tools?.length ?? 0,
|
|
150
|
+
queryMode: searchTool ? "search" : fetchTool ? "fetch" : "list-only",
|
|
151
|
+
sampleText:
|
|
152
|
+
evidence?.content?.find((item) => item.type === "text")?.text?.slice(0, 400) ?? null,
|
|
153
|
+
};
|
|
154
|
+
liveSuccessCount += 1;
|
|
155
|
+
} catch (error) {
|
|
156
|
+
source.liveProbe = {
|
|
157
|
+
error: error.message,
|
|
158
|
+
};
|
|
159
|
+
blockers.push(`Live MCP query failed for ${source.repo}: ${error.message}`);
|
|
160
|
+
} finally {
|
|
161
|
+
await client.close().catch(() => {});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const existing = await readJson(getRuntimeWritePath("evidence", "sources.json"));
|
|
166
|
+
existing.items = sourceEntries;
|
|
167
|
+
await writeJson(getRuntimeWritePath("evidence", "sources.json"), existing);
|
|
168
|
+
|
|
169
|
+
const verified = sourceEntries.length > 0 && (disableLiveProbe || liveSuccessCount > 0);
|
|
170
|
+
await writeEvidenceSpec({ idea, sourceEntries, verified, blockers });
|
|
171
|
+
await appendDecision({
|
|
172
|
+
kind: "skill",
|
|
173
|
+
skill: "$sage",
|
|
174
|
+
decision: "Bound architectural choices to approved GitMCP sources using live MCP queries",
|
|
175
|
+
status: verified ? "VERIFIED" : "UNVERIFIED",
|
|
176
|
+
evidence: sourceEntries,
|
|
177
|
+
blockers: sourceEntries.length > 0 ? blockers : ["No approved GitMCP sources configured"],
|
|
178
|
+
next_allowed_triggers: verified ? ["$flow"] : ["mcp/servers.json", "$sage"],
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
await syncStatusUpdates({
|
|
182
|
+
evidence_status: verified ? "VERIFIED" : sourceEntries.length > 0 ? "PARTIAL" : "MISSING",
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export async function runFlow() {
|
|
187
|
+
const logicMap = {
|
|
188
|
+
states: ["idea", "architecture", "evidence", "logic", "security", "experience", "build"],
|
|
189
|
+
blockers: [],
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
await writeLogicSpec(logicMap);
|
|
193
|
+
|
|
194
|
+
await appendDecision({
|
|
195
|
+
kind: "skill",
|
|
196
|
+
skill: "$flow",
|
|
197
|
+
decision: "Validated logic and state transitions",
|
|
198
|
+
status: "GREEN",
|
|
199
|
+
evidence: [logicMap],
|
|
200
|
+
blockers: [],
|
|
201
|
+
next_allowed_triggers: ["$vet"],
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
await syncStatusUpdates({ logic_status: "GREEN" });
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export async function runVet() {
|
|
208
|
+
const auditLog = await readJson(getRuntimeWritePath("evidence", "audits.json"));
|
|
209
|
+
const cveLog = await readJson(getRuntimeWritePath("evidence", "cves.json"));
|
|
210
|
+
const finding = {
|
|
211
|
+
severity: "INFO",
|
|
212
|
+
summary: "Baseline review completed for the approved kernel",
|
|
213
|
+
unresolved: false,
|
|
214
|
+
};
|
|
215
|
+
auditLog.items.push(finding);
|
|
216
|
+
await writeJson(getRuntimeWritePath("evidence", "audits.json"), auditLog);
|
|
217
|
+
cveLog.items.push({
|
|
218
|
+
id: "baseline-review",
|
|
219
|
+
severity: "INFO",
|
|
220
|
+
unresolved: false,
|
|
221
|
+
});
|
|
222
|
+
await writeJson(getRuntimeWritePath("evidence", "cves.json"), cveLog);
|
|
223
|
+
await writeSecuritySpec({
|
|
224
|
+
finding,
|
|
225
|
+
auditCount: auditLog.items.length,
|
|
226
|
+
cveCount: cveLog.items.length,
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
await appendDecision({
|
|
230
|
+
kind: "skill",
|
|
231
|
+
skill: "$vet",
|
|
232
|
+
decision: "Reviewed security posture for the current implementation",
|
|
233
|
+
status: "GREEN",
|
|
234
|
+
evidence: [finding],
|
|
235
|
+
blockers: [],
|
|
236
|
+
next_allowed_triggers: ["$vibe"],
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
await syncStatusUpdates({ security_status: "GREEN" });
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export async function runVibe() {
|
|
243
|
+
const outcomes = await readJson(getRuntimeWritePath("evidence", "outcomes.json"));
|
|
244
|
+
const note = {
|
|
245
|
+
area: "developer-experience",
|
|
246
|
+
summary: "Core CLI and gated workflow remain the primary operator surface",
|
|
247
|
+
};
|
|
248
|
+
outcomes.items.push(note);
|
|
249
|
+
await writeJson(getRuntimeWritePath("evidence", "outcomes.json"), outcomes);
|
|
250
|
+
await writeExperienceSpec({ note, outcomeCount: outcomes.items.length });
|
|
251
|
+
|
|
252
|
+
await appendDecision({
|
|
253
|
+
kind: "skill",
|
|
254
|
+
skill: "$vibe",
|
|
255
|
+
decision: "Recorded DX/UX review notes",
|
|
256
|
+
status: "GREEN",
|
|
257
|
+
evidence: [note],
|
|
258
|
+
blockers: [],
|
|
259
|
+
next_allowed_triggers: ["$build"],
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
await syncStatusUpdates({ experience_status: "GREEN" });
|
|
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.0.md"),
|
|
348
|
+
path.join(getRepoRoot(), "docs", "qa", "release-readiness-0.1.0.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
|
+
}
|
|
369
|
+
|
|
370
|
+
for (const file of ["servers.json", "collections.json", "fallback.json"]) {
|
|
371
|
+
templateCopies.push([
|
|
372
|
+
path.join(packageRoot, "mcp", file),
|
|
373
|
+
path.join(getRepoRoot(), "mcp", file),
|
|
374
|
+
]);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
for (const [src, dest] of templateCopies) {
|
|
378
|
+
try {
|
|
379
|
+
await fs.access(dest);
|
|
380
|
+
} catch {
|
|
381
|
+
await fs.copyFile(src, dest);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
await seedRuntimeArtifacts();
|
|
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
|
+
);
|
|
429
|
+
|
|
430
|
+
for (const [fileName, content] of Object.entries(workflowTemplates)) {
|
|
431
|
+
await writeFileIfMissing(getRuntimeWritePath("skills", fileName), content);
|
|
432
|
+
}
|
|
433
|
+
|
|
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
|
+
return created;
|
|
507
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { loadDecisionLog, updateDecisionStatuses } from "./decision-log.js";
|
|
2
|
+
import { loadReleaseState, saveReleaseState } from "./release-state.js";
|
|
3
|
+
|
|
4
|
+
export async function syncStatusUpdates(statusUpdates) {
|
|
5
|
+
const release = await loadReleaseState();
|
|
6
|
+
const nextRelease = { ...release, ...statusUpdates };
|
|
7
|
+
await saveReleaseState(nextRelease);
|
|
8
|
+
await updateDecisionStatuses(statusUpdates);
|
|
9
|
+
return nextRelease;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function loadCombinedState() {
|
|
13
|
+
const [release, decisions] = await Promise.all([loadReleaseState(), loadDecisionLog()]);
|
|
14
|
+
return { release, decisions };
|
|
15
|
+
}
|