@jstn-sdk/ma 0.1.13 → 0.14.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 (253) hide show
  1. package/.agents/plugins/marketplace.json +0 -0
  2. package/.codex/agents/Architect.toml +1 -0
  3. package/.codex/agents/Auditor.toml +1 -0
  4. package/.codex/agents/Builder.toml +1 -0
  5. package/.codex/agents/Flow.toml +1 -0
  6. package/.codex/agents/Sage.toml +1 -0
  7. package/.codex/agents/Vibe.toml +1 -0
  8. package/.codex/hooks.json +12 -2
  9. package/.codex/prompts/enforcement.md +0 -0
  10. package/.codex/prompts/onboarding.md +6 -1
  11. package/.codex/prompts/release-rules.md +0 -0
  12. package/.codex/prompts/skill-contract.md +0 -0
  13. package/COVERAGE.md +7 -7
  14. package/DEMO.md +15 -6
  15. package/LICENSE +0 -0
  16. package/README.md +126 -793
  17. package/bin/ma.js +585 -97
  18. package/data/clone-data.ledger.json +0 -0
  19. package/data/clone-data.proof.json +0 -0
  20. package/data/clone-data.rvf +0 -0
  21. package/docs/README.md +8 -2
  22. package/docs/autonomous-tasks.md +46 -0
  23. package/docs/codex-integration.md +16 -0
  24. package/docs/getting-started.md +28 -4
  25. package/docs/installed-sdk.md +0 -0
  26. package/docs/mcp-setup.md +30 -1
  27. package/docs/qa/{release-issue-gates-0.1.13.json → release-issue-gates-0.14.0.json} +77 -77
  28. package/docs/qa/release-readiness-0.1.5.md +0 -0
  29. package/docs/qa/{release-readiness-0.1.13.md → release-readiness-0.14.0.md} +12 -12
  30. package/docs/quality.md +24 -0
  31. package/docs/reference/native-engineering-patterns.md +0 -0
  32. package/docs/reference/native-security-playbooks.md +0 -0
  33. package/docs/reference/native-source-selection.md +0 -0
  34. package/docs/reference/native-style-and-deslop.md +0 -0
  35. package/docs/release-spec.md +27 -14
  36. package/docs/skills.md +1 -1
  37. package/index.js +73 -0
  38. package/mcp/collections.json +0 -0
  39. package/mcp/fallback.json +0 -0
  40. package/mcp/local/code-intel.js +179 -41
  41. package/mcp/local/context.js +180 -0
  42. package/mcp/local/memory.js +17 -6
  43. package/mcp/local/playbooks.js +0 -0
  44. package/mcp/local/quality.js +39 -0
  45. package/mcp/local/state.js +7 -3
  46. package/mcp/local/team-run.js +8 -3
  47. package/mcp/local/trace.js +0 -0
  48. package/mcp/local-capabilities.json +9 -0
  49. package/mcp/native-playbooks.json +0 -0
  50. package/mcp/servers.json +0 -0
  51. package/package.json +26 -4
  52. package/plugins/meta-architect/.app.json +1 -1
  53. package/plugins/meta-architect/.codex-plugin/plugin.json +1 -1
  54. package/plugins/meta-architect/.mcp.json +1 -1
  55. package/plugins/meta-architect/README.md +2 -2
  56. package/plugins/meta-architect/obsidian/main.js +137 -4
  57. package/plugins/meta-architect/obsidian/manifest.json +1 -1
  58. package/plugins/meta-architect/obsidian/styles.css +0 -0
  59. package/plugins/meta-architect/skills/align/SKILL.md +0 -0
  60. package/plugins/meta-architect/skills/align/agents/openai.yaml +0 -0
  61. package/plugins/meta-architect/skills/align/references/shared-language.md +0 -0
  62. package/plugins/meta-architect/skills/arch/SKILL.md +0 -0
  63. package/plugins/meta-architect/skills/arch/agents/openai.yaml +0 -0
  64. package/plugins/meta-architect/skills/build/SKILL.md +0 -0
  65. package/plugins/meta-architect/skills/build/agents/openai.yaml +0 -0
  66. package/plugins/meta-architect/skills/cleanup/SKILL.md +0 -0
  67. package/plugins/meta-architect/skills/cleanup/agents/openai.yaml +0 -0
  68. package/plugins/meta-architect/skills/cleanup/references/style-and-deslop.md +0 -0
  69. package/plugins/meta-architect/skills/diagnose/SKILL.md +0 -0
  70. package/plugins/meta-architect/skills/diagnose/agents/openai.yaml +0 -0
  71. package/plugins/meta-architect/skills/flow/SKILL.md +0 -0
  72. package/plugins/meta-architect/skills/flow/agents/openai.yaml +0 -0
  73. package/plugins/meta-architect/skills/maestro/SKILL.md +0 -0
  74. package/plugins/meta-architect/skills/maestro/agents/openai.yaml +0 -0
  75. package/plugins/meta-architect/skills/maestro/references/core-release-rules.md +0 -0
  76. package/plugins/meta-architect/skills/maestro/references/native-ingest-map.md +0 -0
  77. package/plugins/meta-architect/skills/sage/SKILL.md +0 -0
  78. package/plugins/meta-architect/skills/sage/agents/openai.yaml +0 -0
  79. package/plugins/meta-architect/skills/sage/references/source-selection.md +0 -0
  80. package/plugins/meta-architect/skills/tdd/SKILL.md +0 -0
  81. package/plugins/meta-architect/skills/tdd/agents/openai.yaml +0 -0
  82. package/plugins/meta-architect/skills/vet/SKILL.md +0 -0
  83. package/plugins/meta-architect/skills/vet/agents/openai.yaml +0 -0
  84. package/plugins/meta-architect/skills/vet/references/security-playbooks.md +0 -0
  85. package/plugins/meta-architect/skills/vibe/SKILL.md +0 -0
  86. package/plugins/meta-architect/skills/vibe/agents/openai.yaml +0 -0
  87. package/schemas/autonomous-task-queue.schema.json +56 -0
  88. package/schemas/handoff-packet.schema.json +36 -0
  89. package/schemas/setup-receipt.schema.json +28 -0
  90. package/schemas/skill-frontmatter.schema.json +20 -0
  91. package/schemas/support-bundle.schema.json +37 -0
  92. package/schemas/task-contract.schema.json +31 -0
  93. package/scripts/active-autonomy-hook.mjs +141 -11
  94. package/scripts/biome-staged.js +0 -0
  95. package/scripts/build-linux-packages.mjs +7 -3
  96. package/scripts/cleanup-test-fixtures.sh +55 -0
  97. package/scripts/context-hydration-hook.mjs +89 -0
  98. package/scripts/demo-smoke.js +285 -0
  99. package/scripts/doctor.js +10 -8
  100. package/scripts/install.sh +33 -4
  101. package/scripts/install.sh.sha256 +1 -0
  102. package/scripts/linux-package-lib.mjs +0 -0
  103. package/scripts/linux-package-smoke.mjs +2 -2
  104. package/scripts/package-size-check.mjs +26 -0
  105. package/scripts/plugin-sync.js +83 -17
  106. package/scripts/postinstall.js +17 -10
  107. package/scripts/prepack.js +9 -0
  108. package/scripts/ralph/prompt.md +0 -0
  109. package/scripts/release-metadata.js +0 -0
  110. package/scripts/release-sync.js +72 -7
  111. package/scripts/release-verify.js +100 -7
  112. package/scripts/setup-npmrc.js +48 -23
  113. package/scripts/skills-install.js +9 -2
  114. package/scripts/skills-manifest.js +2 -21
  115. package/scripts/skills-pack.js +2 -2
  116. package/scripts/skills-validate.js +5 -55
  117. package/skills/align/SKILL.md +0 -0
  118. package/skills/align/agents/openai.yaml +0 -0
  119. package/skills/align/references/shared-language.md +0 -0
  120. package/skills/arch/SKILL.md +0 -0
  121. package/skills/arch/agents/openai.yaml +0 -0
  122. package/skills/build/SKILL.md +0 -0
  123. package/skills/build/agents/openai.yaml +0 -0
  124. package/skills/cleanup/SKILL.md +0 -0
  125. package/skills/cleanup/agents/openai.yaml +0 -0
  126. package/skills/cleanup/references/style-and-deslop.md +0 -0
  127. package/skills/diagnose/SKILL.md +0 -0
  128. package/skills/diagnose/agents/openai.yaml +0 -0
  129. package/skills/flow/SKILL.md +0 -0
  130. package/skills/flow/agents/openai.yaml +0 -0
  131. package/skills/index.json +0 -0
  132. package/skills/maestro/SKILL.md +0 -0
  133. package/skills/maestro/agents/openai.yaml +0 -0
  134. package/skills/maestro/references/core-release-rules.md +0 -0
  135. package/skills/maestro/references/native-ingest-map.md +0 -0
  136. package/skills/sage/SKILL.md +0 -0
  137. package/skills/sage/agents/openai.yaml +0 -0
  138. package/skills/sage/references/source-selection.md +0 -0
  139. package/skills/tdd/SKILL.md +0 -0
  140. package/skills/tdd/agents/openai.yaml +0 -0
  141. package/skills/vet/SKILL.md +0 -0
  142. package/skills/vet/agents/openai.yaml +0 -0
  143. package/skills/vet/references/security-playbooks.md +0 -0
  144. package/skills/vibe/SKILL.md +0 -0
  145. package/skills/vibe/agents/openai.yaml +0 -0
  146. package/sprint/00-idea.md +0 -0
  147. package/sprint/01-architecture.md +0 -0
  148. package/sprint/02-oss-evidence.md +0 -0
  149. package/sprint/03-logic.md +0 -0
  150. package/sprint/04-security.md +0 -0
  151. package/sprint/05-dx-ux.md +0 -0
  152. package/sprint/06-build-plan.md +0 -0
  153. package/sprint/07-release.md +0 -0
  154. package/src/agents.js +279 -0
  155. package/src/bootstrap.js +252 -63
  156. package/src/build-gate.js +0 -0
  157. package/src/codex-app-server.js +291 -0
  158. package/src/decision-log.js +0 -0
  159. package/src/fs-utils.js +175 -4
  160. package/src/launcher.js +24 -21
  161. package/src/mcp-config.js +9 -1
  162. package/src/mcp-live-client.js +140 -7
  163. package/src/paths.js +6 -1
  164. package/src/policy.js +2 -2
  165. package/src/prelaunch.js +189 -0
  166. package/src/quality/ai-quality-orchestrator.js +328 -0
  167. package/src/release-issue-gates.js +62 -0
  168. package/src/release-operations.js +62 -0
  169. package/src/release-state.js +0 -0
  170. package/src/runtime/active-autonomy-core.js +0 -0
  171. package/src/runtime/agent-compat.js +31 -0
  172. package/src/runtime/alignment-sentinel.js +0 -0
  173. package/src/runtime/architect-review.js +248 -10
  174. package/src/runtime/autonomous-tasks.js +408 -0
  175. package/src/runtime/build-readiness.js +0 -0
  176. package/src/runtime/code-graph-rehearse.js +0 -0
  177. package/src/runtime/codeburn-core.js +112 -0
  178. package/src/runtime/context-authority.js +40 -0
  179. package/src/runtime/context-economy-core.js +40 -0
  180. package/src/runtime/continuity-graph.js +201 -0
  181. package/src/runtime/continuity-notes.js +71 -26
  182. package/src/runtime/core-source-ingest.js +0 -0
  183. package/src/runtime/detached-provider.js +82 -14
  184. package/src/runtime/doctor-report.js +18 -0
  185. package/src/runtime/environment-awareness-core.js +0 -0
  186. package/src/runtime/exposure-catalog.js +0 -0
  187. package/src/runtime/graphify-core.js +167 -0
  188. package/src/runtime/guidance-stack.js +9 -2
  189. package/src/runtime/handoff-packets.js +92 -0
  190. package/src/runtime/headroom-core.js +104 -0
  191. package/src/runtime/helper-orchestration-core.js +0 -0
  192. package/src/runtime/hook-profiles.js +20 -0
  193. package/src/runtime/learning-loop-core.js +110 -4
  194. package/src/runtime/live-agent-verification.js +122 -0
  195. package/src/runtime/maestro-events.js +0 -0
  196. package/src/runtime/maestro-manager.js +0 -0
  197. package/src/runtime/maestro-output.js +58 -0
  198. package/src/runtime/maestro-state.js +0 -0
  199. package/src/runtime/managed-markdown.js +29 -0
  200. package/src/runtime/mcp-authority.js +147 -0
  201. package/src/runtime/mcp-policy.js +0 -0
  202. package/src/runtime/obsidian-integration-core.js +255 -17
  203. package/src/runtime/obsidian-plugin-bridge.js +344 -38
  204. package/src/runtime/orchestrator.js +0 -0
  205. package/src/runtime/pi-maestro-core.js +89 -0
  206. package/src/runtime/preferences.js +79 -0
  207. package/src/runtime/project-context.js +636 -0
  208. package/src/runtime/prompt-strategy-core.js +0 -0
  209. package/src/runtime/quorum-review.js +0 -0
  210. package/src/runtime/ralph-execution-core.js +0 -0
  211. package/src/runtime/redaction-gateway.js +218 -19
  212. package/src/runtime/runtime-state.js +94 -2
  213. package/src/runtime/schema-migrations.js +162 -0
  214. package/src/runtime/semantic-recording-core.js +0 -0
  215. package/src/runtime/signal-hooks.js +13 -0
  216. package/src/runtime/skills-registry-export.js +92 -8
  217. package/src/runtime/startup-path.js +0 -0
  218. package/src/runtime/task-contracts.js +83 -0
  219. package/src/runtime/universal-plugin-broker-core.js +373 -50
  220. package/src/runtime/workspace-intelligence-runtime.js +0 -0
  221. package/src/runtime/workspace-virtualizer.js +0 -0
  222. package/src/runtime/workspaces.js +0 -0
  223. package/src/runtime-artifacts.js +0 -0
  224. package/src/setup-lifecycle.js +359 -0
  225. package/src/skill-frontmatter.js +78 -0
  226. package/src/skill-installer.js +226 -71
  227. package/src/skills.js +297 -19
  228. package/src/state-sync.js +0 -0
  229. package/src/test-fixtures.js +543 -0
  230. package/src/tui/grid.js +67 -0
  231. package/src/tui/status-grid.js +23 -0
  232. package/support-bundle.json +114 -0
  233. package/templates/AGENTS.md +6 -2
  234. package/templates/catalog-manifest.json +0 -0
  235. package/templates/model-instructions/core.md +0 -0
  236. package/templates/model-instructions/release.md +0 -0
  237. package/templates/model-instructions/security.md +0 -0
  238. package/templates/quality/ai-quality-rules.yml +37 -0
  239. package/docs/assets/image/Screenshot(1).png +0 -0
  240. package/docs/assets/image/Screenshot(2).png +0 -0
  241. package/docs/assets/image/Screenshot(3).png +0 -0
  242. package/docs/assets/image/Screenshot(4).png +0 -0
  243. package/docs/assets/image/Screenshot(5).png +0 -0
  244. package/docs/assets/image/Screenshot(6).png +0 -0
  245. package/docs/assets/image/Screenshot(7).png +0 -0
  246. package/docs/assets/image/Screenshot(8).png +0 -0
  247. package/docs/assets/image/Screenshot(9).png +0 -0
  248. package/docs/assets/meta-architect-logo.png +0 -0
  249. package/docs/assets/meta-architect-logo.svg +0 -8
  250. package/docs/onboarding.md +0 -81
  251. package/docs/prompt-guidance-contract.md +0 -17
  252. package/docs/prompt-guidance-fragments/active-autonomy-core.md +0 -7
  253. package/docs/skills-publishing.md +0 -255
@@ -1,39 +1,64 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ import { randomUUID } from "node:crypto";
3
4
  import fs from "node:fs/promises";
5
+ import os from "node:os";
4
6
  import path from "node:path";
5
7
  import process from "node:process";
8
+ import { fileURLToPath } from "node:url";
6
9
 
7
- function normalizeRegistry(registryUrl) {
8
- return registryUrl.endsWith("/") ? registryUrl : `${registryUrl}/`;
10
+ export async function createTemporaryNpmConfig({
11
+ token,
12
+ registry = "https://registry.npmjs.org/",
13
+ scope = "",
14
+ tempRoot = process.env.RUNNER_TEMP || os.tmpdir(),
15
+ } = {}) {
16
+ if (!token) return null;
17
+ const normalizedRegistry = registry.endsWith("/") ? registry : `${registry}/`;
18
+ const host = new URL(normalizedRegistry).host;
19
+ const configPath = path.join(tempRoot, `meta-architect-npmrc-${randomUUID()}`);
20
+ const content = [
21
+ `registry=${normalizedRegistry}`,
22
+ ...(scope ? [`${scope}:registry=${normalizedRegistry}`] : []),
23
+ `//${host}/:_authToken=${token}`,
24
+ "",
25
+ ].join("\n");
26
+
27
+ await fs.writeFile(configPath, content, { encoding: "utf8", mode: 0o600 });
28
+ await fs.chmod(configPath, 0o600);
29
+ return configPath;
30
+ }
31
+
32
+ export async function cleanupTemporaryNpmConfig(configPath) {
33
+ if (!configPath) return false;
34
+ await fs.rm(configPath, { force: true });
35
+ return true;
9
36
  }
10
37
 
11
38
  async function main() {
12
39
  const token = process.env.NPM_TOKEN || process.env.NODE_AUTH_TOKEN;
13
40
  if (!token) {
14
- console.log("No npm token detected. Skipping .npmrc generation.");
41
+ console.log("No npm token detected. Skipping temporary npm auth config.");
15
42
  return;
16
43
  }
17
44
 
18
- const registry = normalizeRegistry(process.env.NPM_REGISTRY_URL || "https://registry.npmjs.org/");
19
- const scope = process.env.NPM_SCOPE || "";
20
- const host = new URL(registry).host;
21
- const npmrcPath = path.join(process.cwd(), ".npmrc");
22
-
23
- const content = [
24
- `registry=${registry}`,
25
- ...(scope ? [`${scope}:registry=${registry}`] : []),
26
- `//${host}/:_authToken=${token}`,
27
- "",
28
- ].join("\n");
29
-
30
- await fs.writeFile(npmrcPath, content, "utf8");
31
- console.log(
32
- `Wrote CI .npmrc for ${scope ? `scope ${scope}` : "the canonical unscoped package"}.`,
33
- );
45
+ const configPath = await createTemporaryNpmConfig({
46
+ token,
47
+ registry: process.env.NPM_REGISTRY_URL || "https://registry.npmjs.org/",
48
+ scope: process.env.NPM_SCOPE || "",
49
+ });
50
+ if (process.env.GITHUB_ENV) {
51
+ await fs.appendFile(process.env.GITHUB_ENV, `NPM_CONFIG_USERCONFIG=${configPath}\n`);
52
+ }
53
+ console.log("Created temporary npm auth config outside the workspace.");
54
+ if (!process.env.GITHUB_ENV) {
55
+ console.log(`Use NPM_CONFIG_USERCONFIG=${configPath} for the current command.`);
56
+ }
34
57
  }
35
58
 
36
- main().catch((error) => {
37
- console.error(error.message);
38
- process.exitCode = 1;
39
- });
59
+ if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
60
+ main().catch((error) => {
61
+ console.error(error.message);
62
+ process.exitCode = 1;
63
+ });
64
+ }
@@ -1,22 +1,29 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import process from "node:process";
4
- import { installSkills } from "../src/skill-installer.js";
4
+ import { installSkills, rollbackInstalledAssets } from "../src/skill-installer.js";
5
5
 
6
6
  function parseArgs(argv) {
7
- const args = { path: null };
7
+ const args = { path: null, rollback: false };
8
8
  for (let index = 0; index < argv.length; index += 1) {
9
9
  const token = argv[index];
10
10
  if (token === "--path") {
11
11
  args.path = argv[index + 1];
12
12
  index += 1;
13
13
  }
14
+ if (token === "--rollback") args.rollback = true;
14
15
  }
15
16
  return args;
16
17
  }
17
18
 
18
19
  async function main() {
19
20
  const args = parseArgs(process.argv.slice(2));
21
+ if (args.rollback) {
22
+ console.log(
23
+ JSON.stringify(await rollbackInstalledAssets({ targetRoot: args.path ?? undefined })),
24
+ );
25
+ return;
26
+ }
20
27
  const { installed } = await installSkills({ targetRoot: args.path ?? undefined });
21
28
  for (const skill of installed) {
22
29
  console.log(`installed ${skill.name} -> ${skill.dest}`);
@@ -3,31 +3,12 @@
3
3
  import fs from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import process from "node:process";
6
+ import { parseSkillFrontmatter, validateSkillFrontmatter } from "../src/skill-frontmatter.js";
6
7
 
7
8
  const repoRoot = process.cwd();
8
9
  const skillsRoot = path.join(repoRoot, "skills");
9
10
  const manifestPath = path.join(skillsRoot, "index.json");
10
11
 
11
- function parseFrontmatterNameAndDescription(content) {
12
- const match = content.match(/^---\n([\s\S]*?)\n---/);
13
- if (!match) {
14
- throw new Error("Missing SKILL.md frontmatter");
15
- }
16
-
17
- const lines = match[1].split("\n");
18
- let name = "";
19
- let description = "";
20
- for (const line of lines) {
21
- if (line.startsWith("name:")) {
22
- name = line.slice("name:".length).trim();
23
- }
24
- if (line.startsWith("description:")) {
25
- description = line.slice("description:".length).trim().replace(/^"|"$/g, "");
26
- }
27
- }
28
- return { name, description };
29
- }
30
-
31
12
  async function main() {
32
13
  const entries = await fs.readdir(skillsRoot, { withFileTypes: true });
33
14
  const skills = [];
@@ -39,7 +20,7 @@ async function main() {
39
20
 
40
21
  const skillPath = path.join(skillsRoot, entry.name, "SKILL.md");
41
22
  const content = await fs.readFile(skillPath, "utf8");
42
- const meta = parseFrontmatterNameAndDescription(content);
23
+ const meta = validateSkillFrontmatter(parseSkillFrontmatter(content), entry.name);
43
24
  skills.push({
44
25
  name: meta.name,
45
26
  path: `skills/${entry.name}`,
@@ -2,9 +2,9 @@
2
2
 
3
3
  import { spawnSync } from "node:child_process";
4
4
  import fs from "node:fs/promises";
5
- import os from "node:os";
6
5
  import path from "node:path";
7
6
  import process from "node:process";
7
+ import { createTestNamespace } from "../src/test-fixtures.js";
8
8
 
9
9
  const repoRoot = process.cwd();
10
10
  const distRoot = path.join(repoRoot, "dist");
@@ -28,7 +28,7 @@ async function copyDir(src, dest) {
28
28
  async function main() {
29
29
  await fs.mkdir(distRoot, { recursive: true });
30
30
  await fs.rm(bundlePath, { force: true });
31
- const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "meta-architect-skills-"));
31
+ const tempRoot = createTestNamespace("meta-architect-skills");
32
32
  const frozenSkillsRoot = path.join(tempRoot, "skills");
33
33
  await copyDir(skillsRoot, frozenSkillsRoot);
34
34
 
@@ -3,6 +3,7 @@
3
3
  import fs from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import process from "node:process";
6
+ import { parseSkillFrontmatter, validateSkillFrontmatter } from "../src/skill-frontmatter.js";
6
7
 
7
8
  const repoRoot = process.cwd();
8
9
  const skillsRoot = path.join(repoRoot, "skills");
@@ -12,42 +13,6 @@ function fail(message) {
12
13
  process.exitCode = 1;
13
14
  }
14
15
 
15
- function extractFrontmatter(content) {
16
- const match = content.match(/^---\n([\s\S]*?)\n---\n?/);
17
- if (!match) {
18
- return null;
19
- }
20
-
21
- const yaml = match[1];
22
- const result = {};
23
-
24
- for (const rawLine of yaml.split("\n")) {
25
- const line = rawLine.trim();
26
- if (!line || line.startsWith("#")) {
27
- continue;
28
- }
29
-
30
- const separator = line.indexOf(":");
31
- if (separator === -1) {
32
- continue;
33
- }
34
-
35
- const key = line.slice(0, separator).trim();
36
- let value = line.slice(separator + 1).trim();
37
-
38
- if (
39
- (value.startsWith('"') && value.endsWith('"')) ||
40
- (value.startsWith("'") && value.endsWith("'"))
41
- ) {
42
- value = value.slice(1, -1);
43
- }
44
-
45
- result[key] = value;
46
- }
47
-
48
- return result;
49
- }
50
-
51
16
  async function validateSkillDir(skillDir) {
52
17
  const skillName = path.basename(skillDir);
53
18
  const skillPath = path.join(skillDir, "SKILL.md");
@@ -58,25 +23,10 @@ async function validateSkillDir(skillDir) {
58
23
  throw new Error(`${skillName}: missing SKILL.md`);
59
24
  }
60
25
 
61
- const frontmatter = extractFrontmatter(skillContent);
62
- if (!frontmatter) {
63
- throw new Error(`${skillName}: SKILL.md missing frontmatter`);
64
- }
65
-
66
- if (!frontmatter.name) {
67
- throw new Error(`${skillName}: frontmatter missing name`);
68
- }
69
-
70
- if (frontmatter.name !== skillName) {
71
- throw new Error(`${skillName}: frontmatter name must match directory name`);
72
- }
73
-
74
- if (!/^[a-z0-9-]+$/.test(frontmatter.name)) {
75
- throw new Error(`${skillName}: frontmatter name must be lowercase kebab-case`);
76
- }
77
-
78
- if (!frontmatter.description || frontmatter.description.length < 10) {
79
- throw new Error(`${skillName}: frontmatter description is missing or too short`);
26
+ try {
27
+ validateSkillFrontmatter(parseSkillFrontmatter(skillContent), skillName);
28
+ } catch (error) {
29
+ throw new Error(`${skillName}: ${error.message}`);
80
30
  }
81
31
 
82
32
  const agentContent = await fs.readFile(agentPath, "utf8").catch(() => null);
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/skills/index.json CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/sprint/00-idea.md CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/src/agents.js ADDED
@@ -0,0 +1,279 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import path from "node:path";
3
+
4
+ const definitions = {
5
+ codex: {
6
+ id: "codex",
7
+ displayName: "Codex CLI",
8
+ skillsDir: ".agents/skills",
9
+ globalSkillsDir: "~/.agents/skills",
10
+ isUniversal: true,
11
+ command: "codex",
12
+ surface: "cli",
13
+ vendor: "openai",
14
+ probeable: true,
15
+ },
16
+ "claude-code": {
17
+ id: "claude-code",
18
+ displayName: "Claude Code",
19
+ skillsDir: ".claude/skills",
20
+ globalSkillsDir: "~/.claude/skills",
21
+ isUniversal: false,
22
+ command: "claude",
23
+ surface: "cli",
24
+ vendor: "anthropic",
25
+ probeable: true,
26
+ },
27
+ cursor: {
28
+ id: "cursor",
29
+ displayName: "Cursor",
30
+ skillsDir: ".agents/skills",
31
+ globalSkillsDir: "~/.agents/skills",
32
+ isUniversal: true,
33
+ command: "cursor",
34
+ surface: "ide",
35
+ vendor: "cursor",
36
+ probeable: true,
37
+ },
38
+ opencode: {
39
+ id: "opencode",
40
+ displayName: "OpenCode",
41
+ skillsDir: ".agents/skills",
42
+ globalSkillsDir: "~/.config/opencode/skills",
43
+ isUniversal: true,
44
+ command: "opencode",
45
+ surface: "cli",
46
+ vendor: "sst",
47
+ probeable: true,
48
+ },
49
+ "gemini-cli": {
50
+ id: "gemini-cli",
51
+ displayName: "Gemini CLI",
52
+ skillsDir: ".agents/skills",
53
+ globalSkillsDir: "~/.gemini/skills",
54
+ isUniversal: true,
55
+ command: "gemini",
56
+ surface: "cli",
57
+ vendor: "google",
58
+ probeable: true,
59
+ },
60
+ amp: {
61
+ id: "amp",
62
+ displayName: "Amp",
63
+ skillsDir: ".agents/skills",
64
+ globalSkillsDir: "~/.config/agents/skills",
65
+ isUniversal: true,
66
+ command: "amp",
67
+ surface: "cli",
68
+ vendor: "sourcegraph",
69
+ probeable: true,
70
+ },
71
+ goose: {
72
+ id: "goose",
73
+ displayName: "Goose",
74
+ skillsDir: ".goose/skills",
75
+ globalSkillsDir: "~/.config/goose/skills",
76
+ isUniversal: false,
77
+ command: "goose",
78
+ surface: "cli",
79
+ vendor: "block",
80
+ probeable: true,
81
+ },
82
+ "hermes-agent": {
83
+ id: "hermes-agent",
84
+ displayName: "Hermes Agent",
85
+ skillsDir: ".hermes/skills",
86
+ globalSkillsDir: "~/.hermes/skills",
87
+ isUniversal: false,
88
+ command: "hermes",
89
+ surface: "cli",
90
+ vendor: "nous-research",
91
+ probeable: true,
92
+ },
93
+ pi: {
94
+ id: "pi",
95
+ displayName: "Pi Coding Agent",
96
+ skillsDir: ".pi/skills",
97
+ globalSkillsDir: "~/.pi/agent/skills",
98
+ isUniversal: false,
99
+ command: "pi",
100
+ surface: "cli",
101
+ vendor: "pi",
102
+ probeable: true,
103
+ },
104
+ windsurf: {
105
+ id: "windsurf",
106
+ displayName: "Windsurf",
107
+ skillsDir: ".windsurf/skills",
108
+ globalSkillsDir: "~/.codeium/windsurf/skills",
109
+ isUniversal: false,
110
+ command: null,
111
+ surface: "ide",
112
+ vendor: "windsurf",
113
+ probeable: false,
114
+ },
115
+ cline: {
116
+ id: "cline",
117
+ displayName: "Cline",
118
+ skillsDir: ".agents/skills",
119
+ globalSkillsDir: "~/.agents/skills",
120
+ isUniversal: true,
121
+ command: null,
122
+ surface: "ide",
123
+ vendor: "cline",
124
+ probeable: false,
125
+ },
126
+ continue: {
127
+ id: "continue",
128
+ displayName: "Continue",
129
+ skillsDir: ".continue/skills",
130
+ globalSkillsDir: "~/.continue/skills",
131
+ isUniversal: false,
132
+ command: "continue",
133
+ surface: "ide",
134
+ vendor: "continue",
135
+ probeable: true,
136
+ },
137
+ roo: {
138
+ id: "roo",
139
+ displayName: "Roo Code",
140
+ skillsDir: ".roo/skills",
141
+ globalSkillsDir: "~/.roo/skills",
142
+ isUniversal: false,
143
+ command: null,
144
+ surface: "ide",
145
+ vendor: "roo-code",
146
+ probeable: false,
147
+ },
148
+ "kiro-cli": {
149
+ id: "kiro-cli",
150
+ displayName: "Kiro CLI",
151
+ skillsDir: ".kiro/skills",
152
+ globalSkillsDir: "~/.kiro/skills",
153
+ isUniversal: false,
154
+ command: "kiro",
155
+ surface: "ide",
156
+ vendor: "amazon",
157
+ probeable: true,
158
+ },
159
+ junie: {
160
+ id: "junie",
161
+ displayName: "Junie",
162
+ skillsDir: ".junie/skills",
163
+ globalSkillsDir: "~/.junie/skills",
164
+ isUniversal: false,
165
+ command: null,
166
+ surface: "ide",
167
+ vendor: "jetbrains",
168
+ probeable: false,
169
+ },
170
+ "github-copilot": {
171
+ id: "github-copilot",
172
+ displayName: "GitHub Copilot",
173
+ skillsDir: ".agents/skills",
174
+ globalSkillsDir: "~/.copilot/skills",
175
+ isUniversal: true,
176
+ command: null,
177
+ surface: "ide",
178
+ vendor: "github",
179
+ probeable: false,
180
+ },
181
+ antigravity: {
182
+ id: "antigravity",
183
+ displayName: "Antigravity",
184
+ skillsDir: ".agents/skills",
185
+ globalSkillsDir: "~/.gemini/antigravity/skills",
186
+ isUniversal: true,
187
+ command: null,
188
+ surface: "ide",
189
+ vendor: "google",
190
+ probeable: false,
191
+ },
192
+ universal: {
193
+ id: "universal",
194
+ displayName: "Universal Agent Skills",
195
+ skillsDir: ".agents/skills",
196
+ globalSkillsDir: "~/.agents/skills",
197
+ isUniversal: true,
198
+ command: null,
199
+ surface: "generic",
200
+ vendor: "universal",
201
+ probeable: false,
202
+ },
203
+ };
204
+
205
+ export const agentRegistry = Object.freeze(
206
+ Object.fromEntries(
207
+ Object.entries(definitions).map(([id, definition]) => [id, Object.freeze(definition)]),
208
+ ),
209
+ );
210
+
211
+ export function getAgent(type = process.env.MA_AGENT || "codex") {
212
+ return agentRegistry[type] ?? agentRegistry.codex;
213
+ }
214
+
215
+ export function getNonUniversalAgents() {
216
+ return Object.values(agentRegistry).filter((agent) => !agent.isUniversal);
217
+ }
218
+
219
+ export function isUniversalAgent(type) {
220
+ return getAgent(type).isUniversal;
221
+ }
222
+
223
+ export function resolveAgentCommand(type = process.env.MA_AGENT || "codex") {
224
+ const agent = getAgent(type);
225
+ if (!agent.command) return null;
226
+ const envKey = `MA_${agent.id.replaceAll("-", "_").toUpperCase()}_BIN`;
227
+ return process.env[envKey]?.trim() || agent.command;
228
+ }
229
+
230
+ export function detectInstalled(type = process.env.MA_AGENT || "codex") {
231
+ const agent = getAgent(type);
232
+ const command = resolveAgentCommand(agent.id);
233
+ if (!command || !agent.probeable) {
234
+ return {
235
+ ...agent,
236
+ installed: false,
237
+ command: command ?? null,
238
+ version: "",
239
+ probe: "unsupported",
240
+ };
241
+ }
242
+ const script = [".js", ".mjs", ".cjs"].includes(path.extname(command));
243
+ const result = spawnSync(
244
+ script ? process.execPath : command,
245
+ script ? [command, "--version"] : ["--version"],
246
+ {
247
+ encoding: "utf8",
248
+ },
249
+ );
250
+ return {
251
+ ...agent,
252
+ command,
253
+ installed: result.status === 0,
254
+ version: result.status === 0 ? result.stdout.trim() : "",
255
+ error: result.error?.message || result.stderr?.trim() || "",
256
+ };
257
+ }
258
+
259
+ export function listAgents() {
260
+ return Object.values(agentRegistry);
261
+ }
262
+
263
+ const slashInvocationAgents = new Set([
264
+ "cursor",
265
+ "windsurf",
266
+ "cline",
267
+ "continue",
268
+ "roo",
269
+ "kiro-cli",
270
+ "junie",
271
+ "github-copilot",
272
+ "antigravity",
273
+ ]);
274
+
275
+ export function getAgentInvocation(type, command = "maestro") {
276
+ if (type === "codex") return `$${command}`;
277
+ if (slashInvocationAgents.has(type)) return `/${command}`;
278
+ return command;
279
+ }