@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.
Files changed (97) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/.codex/agents/Architect.toml +4 -0
  3. package/.codex/agents/Auditor.toml +4 -0
  4. package/.codex/agents/Builder.toml +4 -0
  5. package/.codex/agents/Flow.toml +4 -0
  6. package/.codex/agents/Sage.toml +4 -0
  7. package/.codex/agents/Vibe.toml +4 -0
  8. package/.codex/hooks.json +15 -0
  9. package/.codex/prompts/enforcement.md +59 -0
  10. package/.codex/prompts/onboarding.md +41 -0
  11. package/.codex/prompts/release-rules.md +28 -0
  12. package/.codex/prompts/skill-contract.md +41 -0
  13. package/LICENSE +21 -0
  14. package/README.md +532 -0
  15. package/bin/ma.js +300 -0
  16. package/bin/meta-architect.js +3 -0
  17. package/docs/README.md +24 -0
  18. package/docs/assets/meta-architect-logo.png +0 -0
  19. package/docs/assets/meta-architect-logo.svg +8 -0
  20. package/docs/getting-started.md +451 -0
  21. package/docs/mcp-setup.md +5 -0
  22. package/docs/onboarding.md +65 -0
  23. package/docs/qa/release-readiness-0.1.0.md +62 -0
  24. package/docs/release-spec.md +86 -0
  25. package/docs/skills-publishing.md +231 -0
  26. package/docs/skills.md +91 -0
  27. package/index.js +28 -0
  28. package/mcp/collections.json +21 -0
  29. package/mcp/fallback.json +7 -0
  30. package/mcp/servers.json +55 -0
  31. package/package.json +84 -0
  32. package/plugins/meta-architect/.app.json +8 -0
  33. package/plugins/meta-architect/.codex-plugin/plugin.json +23 -0
  34. package/plugins/meta-architect/.mcp.json +12 -0
  35. package/plugins/meta-architect/README.md +121 -0
  36. package/plugins/meta-architect/skills/arch/SKILL.md +27 -0
  37. package/plugins/meta-architect/skills/arch/agents/openai.yaml +4 -0
  38. package/plugins/meta-architect/skills/build/SKILL.md +24 -0
  39. package/plugins/meta-architect/skills/build/agents/openai.yaml +4 -0
  40. package/plugins/meta-architect/skills/flow/SKILL.md +24 -0
  41. package/plugins/meta-architect/skills/flow/agents/openai.yaml +4 -0
  42. package/plugins/meta-architect/skills/meta-architect/SKILL.md +30 -0
  43. package/plugins/meta-architect/skills/meta-architect/agents/openai.yaml +4 -0
  44. package/plugins/meta-architect/skills/meta-architect/references/core-release-rules.md +13 -0
  45. package/plugins/meta-architect/skills/sage/SKILL.md +24 -0
  46. package/plugins/meta-architect/skills/sage/agents/openai.yaml +4 -0
  47. package/plugins/meta-architect/skills/vet/SKILL.md +25 -0
  48. package/plugins/meta-architect/skills/vet/agents/openai.yaml +4 -0
  49. package/plugins/meta-architect/skills/vibe/SKILL.md +24 -0
  50. package/plugins/meta-architect/skills/vibe/agents/openai.yaml +4 -0
  51. package/scripts/doctor.js +37 -0
  52. package/scripts/plugin-sync.js +92 -0
  53. package/scripts/postinstall.js +19 -0
  54. package/scripts/release-metadata.js +94 -0
  55. package/scripts/release-verify.js +153 -0
  56. package/scripts/setup-npmrc.js +39 -0
  57. package/scripts/skills-install.js +29 -0
  58. package/scripts/skills-manifest.js +61 -0
  59. package/scripts/skills-pack.js +54 -0
  60. package/scripts/skills-validate.js +118 -0
  61. package/skills/arch/SKILL.md +27 -0
  62. package/skills/arch/agents/openai.yaml +4 -0
  63. package/skills/build/SKILL.md +24 -0
  64. package/skills/build/agents/openai.yaml +4 -0
  65. package/skills/flow/SKILL.md +24 -0
  66. package/skills/flow/agents/openai.yaml +4 -0
  67. package/skills/index.json +40 -0
  68. package/skills/meta-architect/SKILL.md +30 -0
  69. package/skills/meta-architect/agents/openai.yaml +4 -0
  70. package/skills/meta-architect/references/core-release-rules.md +13 -0
  71. package/skills/sage/SKILL.md +24 -0
  72. package/skills/sage/agents/openai.yaml +4 -0
  73. package/skills/vet/SKILL.md +25 -0
  74. package/skills/vet/agents/openai.yaml +4 -0
  75. package/skills/vibe/SKILL.md +24 -0
  76. package/skills/vibe/agents/openai.yaml +4 -0
  77. package/sprint/00-idea.md +27 -0
  78. package/sprint/01-architecture.md +26 -0
  79. package/sprint/02-oss-evidence.md +26 -0
  80. package/sprint/03-logic.md +25 -0
  81. package/sprint/04-security.md +25 -0
  82. package/sprint/05-dx-ux.md +24 -0
  83. package/sprint/06-build-plan.md +26 -0
  84. package/sprint/07-release.md +26 -0
  85. package/src/build-gate.js +52 -0
  86. package/src/decision-log.js +40 -0
  87. package/src/fs-utils.js +25 -0
  88. package/src/launcher.js +55 -0
  89. package/src/mcp-config.js +30 -0
  90. package/src/mcp-live-client.js +186 -0
  91. package/src/paths.js +26 -0
  92. package/src/policy.js +23 -0
  93. package/src/release-state.js +59 -0
  94. package/src/runtime-artifacts.js +363 -0
  95. package/src/skill-installer.js +49 -0
  96. package/src/skills.js +507 -0
  97. package/src/state-sync.js +15 -0
@@ -0,0 +1,363 @@
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 operator 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 renderBuildPlan({ allowed, blockers, nextTriggers, suggestedBranches = [] }) {
200
+ const lines = [
201
+ "# Build Plan",
202
+ "",
203
+ `Updated: ${new Date().toISOString()}`,
204
+ "",
205
+ "## Gate State",
206
+ "",
207
+ allowed ? "READY" : "LOCKED",
208
+ "",
209
+ "## Blockers",
210
+ "",
211
+ ];
212
+
213
+ if (blockers.length === 0) {
214
+ lines.push("None.", "");
215
+ } else {
216
+ lines.push(...blockers.map((blocker) => `- ${blocker}`), "");
217
+ }
218
+
219
+ lines.push("## Next Allowed Triggers", "");
220
+ lines.push(
221
+ ...(nextTriggers.length === 0 ? ["- $build"] : nextTriggers.map((item) => `- ${item}`)),
222
+ "",
223
+ );
224
+
225
+ if (suggestedBranches.length > 0) {
226
+ lines.push(
227
+ "## Suggested Branches",
228
+ "",
229
+ ...suggestedBranches.map((branch) => `- ${branch}`),
230
+ "",
231
+ );
232
+ }
233
+
234
+ return lines.join("\n");
235
+ }
236
+
237
+ function renderRunbook() {
238
+ return [
239
+ "# Meta-Architect Runbook",
240
+ "",
241
+ "## Purpose",
242
+ "",
243
+ "This runbook defines the local helper-path workflow for Meta-Architect.",
244
+ "",
245
+ "## Canonical Sequence",
246
+ "",
247
+ "1. `ma setup`",
248
+ '2. `ma idea "..."`',
249
+ "3. `ma run '$arch'`",
250
+ "4. `ma run '$sage'`",
251
+ "5. `ma run '$flow'`",
252
+ "6. `ma run '$vet'`",
253
+ "7. `ma run '$vibe'`",
254
+ "8. `ma status`",
255
+ "9. `ma run '$build'`",
256
+ "",
257
+ "## Runtime Artifacts",
258
+ "",
259
+ "- `.ma/context/project.md`",
260
+ "- `.ma/specs/architecture.md`",
261
+ "- `.ma/specs/evidence.md`",
262
+ "- `.ma/specs/logic.md`",
263
+ "- `.ma/specs/security.md`",
264
+ "- `.ma/specs/experience.md`",
265
+ "- `.ma/plans/implementation.md`",
266
+ "- `.ma/plans/build.md`",
267
+ "- `.ma/decisions.json`",
268
+ "- `.ma/release.json`",
269
+ "",
270
+ "## Guardrails",
271
+ "",
272
+ "- Do not edit gate status files manually.",
273
+ "- Treat GitHub release state and npm registry state as separate facts.",
274
+ "- Do not claim a publish channel succeeded without evidence from that channel.",
275
+ "",
276
+ ].join("\n");
277
+ }
278
+
279
+ async function writeArtifact(relativePath, content) {
280
+ const target = getRuntimeWritePath(...relativePath.split("/"));
281
+ await ensureDir(path.dirname(target));
282
+ await fs.writeFile(target, `${content.trimEnd()}\n`);
283
+ }
284
+
285
+ export async function seedRuntimeArtifacts() {
286
+ for (const dir of runtimeDirs) {
287
+ await ensureDir(getRuntimeWritePath(dir));
288
+ }
289
+
290
+ await writeFileIfMissing(
291
+ getRuntimeWritePath("context", "project.md"),
292
+ `${renderProjectContext({})}\n`,
293
+ );
294
+ await writeFileIfMissing(
295
+ getRuntimeWritePath("specs", "architecture.md"),
296
+ "# Architecture Spec\n\nNo architecture captured yet.\n",
297
+ );
298
+ await writeFileIfMissing(
299
+ getRuntimeWritePath("specs", "evidence.md"),
300
+ "# Evidence Spec\n\nNo evidence captured yet.\n",
301
+ );
302
+ await writeFileIfMissing(
303
+ getRuntimeWritePath("specs", "logic.md"),
304
+ "# Logic Spec\n\nNo logic review captured yet.\n",
305
+ );
306
+ await writeFileIfMissing(
307
+ getRuntimeWritePath("specs", "security.md"),
308
+ "# Security Spec\n\nNo security review captured yet.\n",
309
+ );
310
+ await writeFileIfMissing(
311
+ getRuntimeWritePath("specs", "experience.md"),
312
+ "# Experience Spec\n\nNo experience review captured yet.\n",
313
+ );
314
+ await writeFileIfMissing(
315
+ getRuntimeWritePath("plans", "implementation.md"),
316
+ "# Implementation Plan\n\nNo implementation plan captured yet.\n",
317
+ );
318
+ await writeFileIfMissing(
319
+ getRuntimeWritePath("plans", "build.md"),
320
+ "# Build Plan\n\nBuild is still locked.\n",
321
+ );
322
+ await writeFileIfMissing(getRuntimeWritePath("runbook.md"), `${renderRunbook()}\n`);
323
+ }
324
+
325
+ export async function writeProjectContext(idea) {
326
+ await writeArtifact("context/project.md", renderProjectContext({ idea }));
327
+ }
328
+
329
+ export async function writeArchitectureArtifacts({ idea, blueprint }) {
330
+ await writeArtifact("specs/architecture.md", renderArchitectureSpec({ idea, blueprint }));
331
+ await writeArtifact("plans/implementation.md", renderImplementationPlan({ idea, blueprint }));
332
+ }
333
+
334
+ export async function writeEvidenceSpec({ idea, sourceEntries, verified, blockers }) {
335
+ await writeArtifact(
336
+ "specs/evidence.md",
337
+ renderEvidenceSpec({ idea, sourceEntries, verified, blockers }),
338
+ );
339
+ }
340
+
341
+ export async function writeLogicSpec(logicMap) {
342
+ await writeArtifact("specs/logic.md", renderLogicSpec(logicMap));
343
+ }
344
+
345
+ export async function writeSecuritySpec({ finding, auditCount, cveCount }) {
346
+ await writeArtifact("specs/security.md", renderSecuritySpec({ finding, auditCount, cveCount }));
347
+ }
348
+
349
+ export async function writeExperienceSpec({ note, outcomeCount }) {
350
+ await writeArtifact("specs/experience.md", renderExperienceSpec({ note, outcomeCount }));
351
+ }
352
+
353
+ export async function writeBuildPlanArtifact({
354
+ allowed,
355
+ blockers,
356
+ nextTriggers,
357
+ suggestedBranches = [],
358
+ }) {
359
+ await writeArtifact(
360
+ "plans/build.md",
361
+ renderBuildPlan({ allowed, blockers, nextTriggers, suggestedBranches }),
362
+ );
363
+ }
@@ -0,0 +1,49 @@
1
+ import fs from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { packageRoot } from "./paths.js";
5
+
6
+ function resolveSkillInstallRoot() {
7
+ const codexHome = process.env.CODEX_HOME ?? path.join(os.homedir(), ".codex");
8
+ return path.join(codexHome, "skills");
9
+ }
10
+
11
+ async function copyDir(src, dest) {
12
+ await fs.mkdir(dest, { recursive: true });
13
+ const entries = await fs.readdir(src, { withFileTypes: true });
14
+ for (const entry of entries) {
15
+ const srcPath = path.join(src, entry.name);
16
+ const destPath = path.join(dest, entry.name);
17
+ if (entry.isDirectory()) {
18
+ await copyDir(srcPath, destPath);
19
+ } else {
20
+ await fs.copyFile(srcPath, destPath);
21
+ }
22
+ }
23
+ }
24
+
25
+ export function getSkillInstallRoot() {
26
+ return resolveSkillInstallRoot();
27
+ }
28
+
29
+ export async function loadSkillManifest() {
30
+ const manifestPath = path.join(packageRoot, "skills", "index.json");
31
+ const manifest = JSON.parse(await fs.readFile(manifestPath, "utf8"));
32
+ return manifest.skills ?? [];
33
+ }
34
+
35
+ export async function installSkills({ targetRoot = getSkillInstallRoot() } = {}) {
36
+ const skills = await loadSkillManifest();
37
+ await fs.mkdir(targetRoot, { recursive: true });
38
+
39
+ const installed = [];
40
+ for (const skill of skills) {
41
+ const src = path.join(packageRoot, skill.path);
42
+ const dest = path.join(targetRoot, path.basename(skill.path));
43
+ await fs.rm(dest, { recursive: true, force: true });
44
+ await copyDir(src, dest);
45
+ installed.push({ name: skill.name, dest });
46
+ }
47
+
48
+ return { targetRoot, installed };
49
+ }