@jstn-sdk/ma 0.1.13 → 0.14.1
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 +0 -0
- package/.codex/agents/Architect.toml +1 -0
- package/.codex/agents/Auditor.toml +1 -0
- package/.codex/agents/Builder.toml +1 -0
- package/.codex/agents/Flow.toml +1 -0
- package/.codex/agents/Sage.toml +1 -0
- package/.codex/agents/Vibe.toml +1 -0
- package/.codex/hooks.json +12 -2
- package/.codex/prompts/enforcement.md +0 -0
- package/.codex/prompts/onboarding.md +6 -1
- package/.codex/prompts/release-rules.md +0 -0
- package/.codex/prompts/skill-contract.md +0 -0
- package/COVERAGE.md +9 -9
- package/DEMO.md +15 -6
- package/LICENSE +0 -0
- package/README.md +127 -784
- package/bin/ma.js +591 -105
- package/data/clone-data.ledger.json +0 -0
- package/data/clone-data.proof.json +0 -0
- package/data/clone-data.rvf +0 -0
- package/docs/README.md +8 -2
- package/docs/assets/banner.png +0 -0
- package/docs/autonomous-tasks.md +46 -0
- package/docs/codex-integration.md +16 -0
- package/docs/getting-started.md +32 -8
- package/docs/installed-sdk.md +0 -0
- package/docs/mcp-setup.md +30 -1
- package/docs/qa/{release-issue-gates-0.1.13.json → release-issue-gates-0.14.1.json} +77 -77
- package/docs/qa/release-readiness-0.1.5.md +0 -0
- package/docs/qa/{release-readiness-0.1.13.md → release-readiness-0.14.1.md} +12 -12
- package/docs/quality.md +24 -0
- package/docs/reference/native-engineering-patterns.md +0 -0
- package/docs/reference/native-security-playbooks.md +0 -0
- package/docs/reference/native-source-selection.md +0 -0
- package/docs/reference/native-style-and-deslop.md +0 -0
- package/docs/release-spec.md +27 -14
- package/docs/skills.md +1 -1
- package/docs/vendor-plugin-publishing.md +49 -0
- package/index.js +73 -0
- package/mcp/collections.json +0 -0
- package/mcp/fallback.json +0 -0
- package/mcp/local/code-intel.js +185 -41
- package/mcp/local/context.js +180 -0
- package/mcp/local/memory.js +17 -6
- package/mcp/local/playbooks.js +0 -0
- package/mcp/local/quality.js +39 -0
- package/mcp/local/state.js +7 -3
- package/mcp/local/team-run.js +8 -3
- package/mcp/local/trace.js +0 -0
- package/mcp/local-capabilities.json +9 -0
- package/mcp/native-playbooks.json +0 -0
- package/mcp/servers.json +0 -0
- package/package.json +37 -6
- package/plugins/meta-architect/.app.json +1 -1
- package/plugins/meta-architect/.claude-plugin/plugin.json +12 -0
- package/plugins/meta-architect/.codex-plugin/plugin.json +1 -1
- package/plugins/meta-architect/.mcp.json +1 -1
- package/plugins/meta-architect/README.md +14 -2
- package/plugins/meta-architect/obsidian/main.js +137 -4
- package/plugins/meta-architect/obsidian/manifest.json +1 -1
- package/plugins/meta-architect/obsidian/styles.css +0 -0
- package/plugins/meta-architect/skills/align/SKILL.md +0 -0
- package/plugins/meta-architect/skills/align/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/align/references/shared-language.md +0 -0
- package/plugins/meta-architect/skills/arch/SKILL.md +0 -0
- package/plugins/meta-architect/skills/arch/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/build/SKILL.md +0 -0
- package/plugins/meta-architect/skills/build/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/cleanup/SKILL.md +0 -0
- package/plugins/meta-architect/skills/cleanup/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/cleanup/references/style-and-deslop.md +0 -0
- package/plugins/meta-architect/skills/diagnose/SKILL.md +0 -0
- package/plugins/meta-architect/skills/diagnose/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/flow/SKILL.md +0 -0
- package/plugins/meta-architect/skills/flow/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/maestro/SKILL.md +17 -1
- package/plugins/meta-architect/skills/maestro/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/maestro/references/core-release-rules.md +2 -2
- package/plugins/meta-architect/skills/maestro/references/native-ingest-map.md +0 -0
- package/plugins/meta-architect/skills/sage/SKILL.md +0 -0
- package/plugins/meta-architect/skills/sage/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/sage/references/source-selection.md +0 -0
- package/plugins/meta-architect/skills/tdd/SKILL.md +0 -0
- package/plugins/meta-architect/skills/tdd/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/vet/SKILL.md +0 -0
- package/plugins/meta-architect/skills/vet/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/vet/references/security-playbooks.md +0 -0
- package/plugins/meta-architect/skills/vibe/SKILL.md +0 -0
- package/plugins/meta-architect/skills/vibe/agents/openai.yaml +0 -0
- package/schemas/autonomous-task-queue.schema.json +58 -0
- package/schemas/handoff-packet.schema.json +36 -0
- package/schemas/setup-receipt.schema.json +28 -0
- package/schemas/skill-frontmatter.schema.json +20 -0
- package/schemas/support-bundle.schema.json +37 -0
- package/schemas/task-contract.schema.json +31 -0
- package/scripts/active-autonomy-hook.mjs +141 -11
- package/scripts/biome-staged.js +0 -0
- package/scripts/build-linux-packages.mjs +7 -3
- package/scripts/cleanup-test-fixtures.sh +55 -0
- package/scripts/context-hydration-hook.mjs +89 -0
- package/scripts/demo-smoke.js +285 -0
- package/scripts/doctor.js +10 -8
- package/scripts/install.sh +33 -4
- package/scripts/install.sh.sha256 +1 -0
- package/scripts/linux-package-lib.mjs +0 -0
- package/scripts/linux-package-smoke.mjs +2 -2
- package/scripts/package-size-check.mjs +26 -0
- package/scripts/plugin-build.js +314 -0
- package/scripts/plugin-publish.js +77 -0
- package/scripts/plugin-sync.js +83 -17
- package/scripts/prepack.js +9 -0
- package/scripts/ralph/prompt.md +0 -0
- package/scripts/release-metadata.js +0 -0
- package/scripts/release-sync.js +83 -7
- package/scripts/release-verify.js +131 -7
- package/scripts/setup-npmrc.js +48 -23
- package/scripts/skills-install.js +9 -2
- package/scripts/skills-manifest.js +2 -21
- package/scripts/skills-pack.js +2 -2
- package/scripts/skills-validate.js +5 -55
- package/skills/align/SKILL.md +0 -0
- package/skills/align/agents/openai.yaml +0 -0
- package/skills/align/references/shared-language.md +0 -0
- package/skills/arch/SKILL.md +0 -0
- package/skills/arch/agents/openai.yaml +0 -0
- package/skills/build/SKILL.md +0 -0
- package/skills/build/agents/openai.yaml +0 -0
- package/skills/cleanup/SKILL.md +0 -0
- package/skills/cleanup/agents/openai.yaml +0 -0
- package/skills/cleanup/references/style-and-deslop.md +0 -0
- package/skills/diagnose/SKILL.md +0 -0
- package/skills/diagnose/agents/openai.yaml +0 -0
- package/skills/flow/SKILL.md +0 -0
- package/skills/flow/agents/openai.yaml +0 -0
- package/skills/index.json +0 -0
- package/skills/maestro/SKILL.md +17 -1
- package/skills/maestro/agents/openai.yaml +0 -0
- package/skills/maestro/references/core-release-rules.md +2 -2
- package/skills/maestro/references/native-ingest-map.md +0 -0
- package/skills/sage/SKILL.md +0 -0
- package/skills/sage/agents/openai.yaml +0 -0
- package/skills/sage/references/source-selection.md +0 -0
- package/skills/tdd/SKILL.md +0 -0
- package/skills/tdd/agents/openai.yaml +0 -0
- package/skills/vet/SKILL.md +0 -0
- package/skills/vet/agents/openai.yaml +0 -0
- package/skills/vet/references/security-playbooks.md +0 -0
- package/skills/vibe/SKILL.md +0 -0
- package/skills/vibe/agents/openai.yaml +0 -0
- package/sprint/00-idea.md +0 -0
- package/sprint/01-architecture.md +0 -0
- package/sprint/02-oss-evidence.md +0 -0
- package/sprint/03-logic.md +0 -0
- package/sprint/04-security.md +0 -0
- package/sprint/05-dx-ux.md +0 -0
- package/sprint/06-build-plan.md +0 -0
- package/sprint/07-release.md +2 -2
- package/src/agents.js +281 -0
- package/src/bootstrap.js +272 -65
- package/src/build-gate.js +0 -0
- package/src/codex-app-server.js +291 -0
- package/src/decision-log.js +0 -0
- package/src/fs-utils.js +175 -4
- package/src/launcher.js +26 -23
- package/src/mcp-config.js +9 -1
- package/src/mcp-live-client.js +141 -8
- package/src/paths.js +6 -1
- package/src/policy.js +2 -2
- package/src/prelaunch.js +223 -0
- package/src/process-utils.js +62 -0
- package/src/quality/ai-quality-orchestrator.js +328 -0
- package/src/release-issue-gates.js +62 -0
- package/src/release-operations.js +72 -0
- package/src/release-state.js +0 -0
- package/src/runtime/active-autonomy-core.js +0 -0
- package/src/runtime/agent-compat.js +31 -0
- package/src/runtime/alignment-sentinel.js +0 -0
- package/src/runtime/architect-review.js +249 -11
- package/src/runtime/autonomous-tasks.js +585 -0
- package/src/runtime/build-readiness.js +0 -0
- package/src/runtime/code-graph-rehearse.js +0 -0
- package/src/runtime/codeburn-core.js +118 -0
- package/src/runtime/context-authority.js +40 -0
- package/src/runtime/context-economy-core.js +40 -0
- package/src/runtime/continuity-graph.js +201 -0
- package/src/runtime/continuity-notes.js +71 -26
- package/src/runtime/core-source-ingest.js +2 -2
- package/src/runtime/detached-provider.js +90 -13
- package/src/runtime/doctor-report.js +18 -0
- package/src/runtime/environment-awareness-core.js +0 -0
- package/src/runtime/exposure-catalog.js +0 -0
- package/src/runtime/graphify-core.js +167 -0
- package/src/runtime/guidance-stack.js +9 -2
- package/src/runtime/handoff-packets.js +92 -0
- package/src/runtime/headroom-core.js +104 -0
- package/src/runtime/helper-orchestration-core.js +0 -0
- package/src/runtime/hook-profiles.js +20 -0
- package/src/runtime/learning-loop-core.js +110 -4
- package/src/runtime/live-agent-verification.js +122 -0
- package/src/runtime/maestro-events.js +0 -0
- package/src/runtime/maestro-manager.js +0 -0
- package/src/runtime/maestro-output.js +58 -0
- package/src/runtime/maestro-state.js +0 -0
- package/src/runtime/managed-markdown.js +29 -0
- package/src/runtime/mcp-authority.js +147 -0
- package/src/runtime/mcp-policy.js +0 -0
- package/src/runtime/obsidian-integration-core.js +255 -17
- package/src/runtime/obsidian-plugin-bridge.js +344 -38
- package/src/runtime/orchestrator.js +0 -0
- package/src/runtime/pi-maestro-core.js +89 -0
- package/src/runtime/preferences.js +79 -0
- package/src/runtime/project-context.js +636 -0
- package/src/runtime/prompt-strategy-core.js +0 -0
- package/src/runtime/quorum-review.js +0 -0
- package/src/runtime/ralph-execution-core.js +0 -0
- package/src/runtime/redaction-gateway.js +218 -19
- package/src/runtime/runtime-state.js +94 -2
- package/src/runtime/schema-migrations.js +162 -0
- package/src/runtime/semantic-recording-core.js +0 -0
- package/src/runtime/signal-hooks.js +13 -0
- package/src/runtime/skills-registry-export.js +96 -8
- package/src/runtime/startup-path.js +0 -0
- package/src/runtime/task-contracts.js +83 -0
- package/src/runtime/universal-plugin-broker-core.js +373 -50
- package/src/runtime/workspace-intelligence-runtime.js +0 -0
- package/src/runtime/workspace-virtualizer.js +0 -0
- package/src/runtime/workspaces.js +0 -0
- package/src/runtime-artifacts.js +0 -0
- package/src/setup-lifecycle.js +359 -0
- package/src/skill-frontmatter.js +78 -0
- package/src/skill-installer.js +226 -71
- package/src/skills.js +309 -31
- package/src/state-sync.js +0 -0
- package/src/test-fixtures.js +543 -0
- package/src/tui/grid.js +67 -0
- package/src/tui/status-grid.js +23 -0
- package/support-bundle.json +114 -0
- package/templates/AGENTS.md +6 -2
- package/templates/catalog-manifest.json +0 -0
- package/templates/model-instructions/core.md +0 -0
- package/templates/model-instructions/release.md +0 -0
- package/templates/model-instructions/security.md +0 -0
- package/templates/quality/ai-quality-rules.yml +37 -0
- package/docs/assets/image/Screenshot(1).png +0 -0
- package/docs/assets/image/Screenshot(2).png +0 -0
- package/docs/assets/image/Screenshot(3).png +0 -0
- package/docs/assets/image/Screenshot(4).png +0 -0
- package/docs/assets/image/Screenshot(5).png +0 -0
- package/docs/assets/image/Screenshot(6).png +0 -0
- package/docs/assets/image/Screenshot(7).png +0 -0
- package/docs/assets/image/Screenshot(8).png +0 -0
- package/docs/assets/image/Screenshot(9).png +0 -0
- package/docs/assets/meta-architect-logo.png +0 -0
- package/docs/assets/meta-architect-logo.svg +0 -8
- package/docs/onboarding.md +0 -81
- package/docs/prompt-guidance-contract.md +0 -17
- package/docs/prompt-guidance-fragments/active-autonomy-core.md +0 -7
- package/docs/skills-publishing.md +0 -255
- package/scripts/postinstall.js +0 -23
package/scripts/release-sync.js
CHANGED
|
@@ -31,6 +31,8 @@ const WATCHED_FILES = new Set([
|
|
|
31
31
|
function parseArgs(argv) {
|
|
32
32
|
const args = {
|
|
33
33
|
bump: "",
|
|
34
|
+
version: "",
|
|
35
|
+
refreshFrom: "",
|
|
34
36
|
fromRef: "",
|
|
35
37
|
toRef: "",
|
|
36
38
|
githubOutput: "",
|
|
@@ -44,6 +46,16 @@ function parseArgs(argv) {
|
|
|
44
46
|
index += 1;
|
|
45
47
|
continue;
|
|
46
48
|
}
|
|
49
|
+
if (token === "--version") {
|
|
50
|
+
args.version = argv[index + 1] ?? "";
|
|
51
|
+
index += 1;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (token === "--refresh-from") {
|
|
55
|
+
args.refreshFrom = argv[index + 1] ?? "";
|
|
56
|
+
index += 1;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
47
59
|
if (token === "--from-ref") {
|
|
48
60
|
args.fromRef = argv[index + 1] ?? "";
|
|
49
61
|
index += 1;
|
|
@@ -184,6 +196,12 @@ function updateCurrentSurfaceFile(file, oldVersion, nextVersion) {
|
|
|
184
196
|
writeText(file, content);
|
|
185
197
|
}
|
|
186
198
|
|
|
199
|
+
function syncReadmeReleaseSurface(_nextVersion) {
|
|
200
|
+
const readmePath = "README.md";
|
|
201
|
+
// The README uses a dynamic GitHub release badge; no version replacement is needed.
|
|
202
|
+
writeText(readmePath, readText(readmePath));
|
|
203
|
+
}
|
|
204
|
+
|
|
187
205
|
function syncPackageVersion(nextVersion) {
|
|
188
206
|
const pkg = readJson("package.json");
|
|
189
207
|
const lock = readJson("package-lock.json");
|
|
@@ -196,10 +214,19 @@ function syncPackageVersion(nextVersion) {
|
|
|
196
214
|
writeJson("package-lock.json", lock);
|
|
197
215
|
}
|
|
198
216
|
|
|
217
|
+
function syncSupportBundleVersion(nextVersion) {
|
|
218
|
+
const manifestPath = "support-bundle.json";
|
|
219
|
+
if (!fs.existsSync(manifestPath)) return;
|
|
220
|
+
const manifest = readJson(manifestPath);
|
|
221
|
+
manifest.bundleVersion = nextVersion;
|
|
222
|
+
writeJson(manifestPath, manifest);
|
|
223
|
+
}
|
|
224
|
+
|
|
199
225
|
function syncPluginVersions(nextVersion) {
|
|
200
226
|
for (const file of [
|
|
201
227
|
path.join("plugins", "meta-architect", ".app.json"),
|
|
202
228
|
path.join("plugins", "meta-architect", ".mcp.json"),
|
|
229
|
+
path.join("plugins", "meta-architect", "obsidian", "manifest.json"),
|
|
203
230
|
]) {
|
|
204
231
|
const value = readJson(file);
|
|
205
232
|
value.version = nextVersion;
|
|
@@ -210,14 +237,28 @@ function syncPluginVersions(nextVersion) {
|
|
|
210
237
|
const pluginManifest = readJson(pluginManifestFile);
|
|
211
238
|
pluginManifest.version = nextVersion;
|
|
212
239
|
writePluginManifestJson(pluginManifestFile, pluginManifest);
|
|
240
|
+
|
|
241
|
+
const claudePluginFile = path.join("plugins", "meta-architect", ".claude-plugin", "plugin.json");
|
|
242
|
+
const claudePlugin = readJson(claudePluginFile);
|
|
243
|
+
claudePlugin.version = nextVersion;
|
|
244
|
+
writeJson(claudePluginFile, claudePlugin);
|
|
245
|
+
|
|
246
|
+
const claudeMarketplaceFile = path.join(".claude-plugin", "marketplace.json");
|
|
247
|
+
const claudeMarketplace = readJson(claudeMarketplaceFile);
|
|
248
|
+
claudeMarketplace.metadata.version = nextVersion;
|
|
249
|
+
writeJson(claudeMarketplaceFile, claudeMarketplace);
|
|
213
250
|
}
|
|
214
251
|
|
|
215
252
|
function syncCurrentReleaseFiles(oldVersion, nextVersion) {
|
|
216
253
|
for (const file of [
|
|
217
254
|
"README.md",
|
|
255
|
+
"DEMO.md",
|
|
256
|
+
"COVERAGE.md",
|
|
218
257
|
"RELEASE.md",
|
|
219
258
|
path.join("docs", "README.md"),
|
|
220
259
|
path.join("docs", "getting-started.md"),
|
|
260
|
+
path.join("docs", "onboarding.md"),
|
|
261
|
+
path.join("docs", "skills.md"),
|
|
221
262
|
path.join("docs", "release-spec.md"),
|
|
222
263
|
path.join("plugins", "meta-architect", "README.md"),
|
|
223
264
|
]) {
|
|
@@ -228,16 +269,17 @@ function syncCurrentReleaseFiles(oldVersion, nextVersion) {
|
|
|
228
269
|
const nextQa = path.join("docs", "qa", `release-readiness-${nextVersion}.md`);
|
|
229
270
|
fs.renameSync(oldQa, nextQa);
|
|
230
271
|
updateCurrentSurfaceFile(nextQa, oldVersion, nextVersion);
|
|
272
|
+
|
|
273
|
+
const oldIssueGates = path.join("docs", "qa", `release-issue-gates-${oldVersion}.json`);
|
|
274
|
+
const nextIssueGates = path.join("docs", "qa", `release-issue-gates-${nextVersion}.json`);
|
|
275
|
+
if (fs.existsSync(oldIssueGates)) {
|
|
276
|
+
fs.renameSync(oldIssueGates, nextIssueGates);
|
|
277
|
+
updateCurrentSurfaceFile(nextIssueGates, oldVersion, nextVersion);
|
|
278
|
+
}
|
|
231
279
|
}
|
|
232
280
|
|
|
233
281
|
function syncSupportingCode(oldVersion, nextVersion) {
|
|
234
282
|
const replacements = [
|
|
235
|
-
{
|
|
236
|
-
file: path.join("src", "skills.js"),
|
|
237
|
-
search: `release-readiness-${oldVersion}.md`,
|
|
238
|
-
replacement: `release-readiness-${nextVersion}.md`,
|
|
239
|
-
label: "skills QA path",
|
|
240
|
-
},
|
|
241
283
|
{
|
|
242
284
|
file: path.join("test", "package-install-smoke.test.js"),
|
|
243
285
|
search: `jstn-sdk-ma-${oldVersion}.tgz`,
|
|
@@ -259,6 +301,9 @@ function syncSupportingCode(oldVersion, nextVersion) {
|
|
|
259
301
|
|
|
260
302
|
const mcpLiveClientFile = path.join("src", "mcp-live-client.js");
|
|
261
303
|
const mcpLiveClient = readText(mcpLiveClientFile);
|
|
304
|
+
if (/resolveMcpClientVersion\(packageMetadata\)/.test(mcpLiveClient)) {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
262
307
|
if (!/version: "[0-9]+\.[0-9]+\.[0-9]+(?:-dev)?"/.test(mcpLiveClient)) {
|
|
263
308
|
throw new Error("Expected to find mcp live client version declaration");
|
|
264
309
|
}
|
|
@@ -271,6 +316,27 @@ function syncSupportingCode(oldVersion, nextVersion) {
|
|
|
271
316
|
);
|
|
272
317
|
}
|
|
273
318
|
|
|
319
|
+
function refreshCurrentReleaseFiles(oldVersion, currentVersion) {
|
|
320
|
+
for (const file of [
|
|
321
|
+
"README.md",
|
|
322
|
+
"DEMO.md",
|
|
323
|
+
"COVERAGE.md",
|
|
324
|
+
"RELEASE.md",
|
|
325
|
+
path.join("docs", "README.md"),
|
|
326
|
+
path.join("docs", "getting-started.md"),
|
|
327
|
+
path.join("docs", "onboarding.md"),
|
|
328
|
+
path.join("docs", "skills.md"),
|
|
329
|
+
path.join("docs", "release-spec.md"),
|
|
330
|
+
path.join("plugins", "meta-architect", "README.md"),
|
|
331
|
+
path.join("docs", "qa", `release-readiness-${currentVersion}.md`),
|
|
332
|
+
path.join("docs", "qa", `release-issue-gates-${currentVersion}.json`),
|
|
333
|
+
path.join("scripts", "install.sh"),
|
|
334
|
+
path.join("plugins", "meta-architect", "obsidian", "manifest.json"),
|
|
335
|
+
]) {
|
|
336
|
+
if (fs.existsSync(file)) updateCurrentSurfaceFile(file, oldVersion, currentVersion);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
274
340
|
function rewriteReleaseState(nextVersion, previousVersion) {
|
|
275
341
|
const releasePath = "RELEASE.md";
|
|
276
342
|
const qaPath = path.join("docs", "qa", `release-readiness-${nextVersion}.md`);
|
|
@@ -319,6 +385,13 @@ function main() {
|
|
|
319
385
|
const args = parseArgs(process.argv.slice(2));
|
|
320
386
|
const pkg = readJson("package.json");
|
|
321
387
|
const currentVersion = pkg.version;
|
|
388
|
+
if (args.refreshFrom) {
|
|
389
|
+
refreshCurrentReleaseFiles(args.refreshFrom, currentVersion);
|
|
390
|
+
console.log(
|
|
391
|
+
JSON.stringify({ updated: true, refreshed: true, version: currentVersion }, null, 2),
|
|
392
|
+
);
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
322
395
|
const changedFiles = getChangedFiles(args);
|
|
323
396
|
const relevantChanges = args.force ? ["<forced>"] : changedFiles.filter(isWatchedPath);
|
|
324
397
|
|
|
@@ -342,12 +415,15 @@ function main() {
|
|
|
342
415
|
}
|
|
343
416
|
|
|
344
417
|
const bumpKind = args.bump || "patch";
|
|
345
|
-
const nextVersion = bumpVersion(currentVersion, bumpKind);
|
|
418
|
+
const nextVersion = args.version || bumpVersion(currentVersion, bumpKind);
|
|
419
|
+
parseVersion(nextVersion);
|
|
346
420
|
|
|
347
421
|
syncPackageVersion(nextVersion);
|
|
422
|
+
syncSupportBundleVersion(nextVersion);
|
|
348
423
|
syncPluginVersions(nextVersion);
|
|
349
424
|
prependChangelog(nextVersion);
|
|
350
425
|
syncCurrentReleaseFiles(currentVersion, nextVersion);
|
|
426
|
+
syncReadmeReleaseSurface(nextVersion);
|
|
351
427
|
syncSupportingCode(currentVersion, nextVersion);
|
|
352
428
|
rewriteReleaseState(nextVersion, currentVersion);
|
|
353
429
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
4
|
+
import crypto from "node:crypto";
|
|
3
5
|
import fs from "node:fs";
|
|
4
6
|
import path from "node:path";
|
|
5
7
|
import process from "node:process";
|
|
@@ -7,8 +9,6 @@ import { validateReleaseIssueGates } from "../src/release-issue-gates.js";
|
|
|
7
9
|
|
|
8
10
|
const CANONICAL_PACKAGE = "@jstn-sdk/ma";
|
|
9
11
|
const CANONICAL_INSTALL = "npm i -g @openai/codex@latest @jstn-sdk/ma@latest";
|
|
10
|
-
const CDN_INSTALL =
|
|
11
|
-
"curl -fsSL https://cdn.jsdelivr.net/gh/JustineDevs/meta-architect@main/scripts/install.sh | sh";
|
|
12
12
|
const CANONICAL_LAUNCH = "ma --madmax --high";
|
|
13
13
|
const UNINSTALL_MA = "npm uninstall -g @jstn-sdk/ma";
|
|
14
14
|
const UNINSTALL_BOTH = "npm uninstall -g @jstn-sdk/ma @openai/codex";
|
|
@@ -41,13 +41,29 @@ function parseVersion(version) {
|
|
|
41
41
|
return match.groups;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
function latestCdnInstall() {
|
|
45
|
+
return "curl -fsSLo install.sh https://cdn.jsdelivr.net/gh/JustineDevs/meta-architect@latest/scripts/install.sh && curl -fsSLo install.sh.sha256 https://cdn.jsdelivr.net/gh/JustineDevs/meta-architect@latest/scripts/install.sh.sha256 && sed 's#scripts/install.sh#install.sh#' install.sh.sha256 | sha256sum -c - && sh install.sh";
|
|
46
|
+
}
|
|
47
|
+
|
|
44
48
|
function verifyInstallBlock(file) {
|
|
45
49
|
const content = readText(file);
|
|
46
|
-
|
|
50
|
+
const cdnInstall = latestCdnInstall();
|
|
51
|
+
const htmlCdnInstall = cdnInstall.replaceAll("&&", "&&");
|
|
52
|
+
const normalizedContent = content.replaceAll("\\|", "|");
|
|
53
|
+
const splitCdnInstall = [
|
|
54
|
+
"curl -fsSLo install.sh https://cdn.jsdelivr.net/gh/JustineDevs/meta-architect@latest/scripts/install.sh",
|
|
55
|
+
"curl -fsSLo install.sh.sha256 https://cdn.jsdelivr.net/gh/JustineDevs/meta-architect@latest/scripts/install.sh.sha256",
|
|
56
|
+
"sed 's#scripts/install.sh#install.sh#' install.sh.sha256 | sha256sum -c -",
|
|
57
|
+
"sh install.sh",
|
|
58
|
+
].every((command) => normalizedContent.includes(command));
|
|
59
|
+
if (!content.includes(CANONICAL_INSTALL) && !content.includes(cdnInstall) && !splitCdnInstall) {
|
|
47
60
|
return;
|
|
48
61
|
}
|
|
49
62
|
|
|
50
|
-
assert(
|
|
63
|
+
assert(
|
|
64
|
+
content.includes(cdnInstall) || content.includes(htmlCdnInstall) || splitCdnInstall,
|
|
65
|
+
`${file}: missing jsDelivr POSIX installer command`,
|
|
66
|
+
);
|
|
51
67
|
assert(content.includes(CANONICAL_INSTALL), `${file}: missing canonical npm install command`);
|
|
52
68
|
assert(content.includes(CANONICAL_LAUNCH), `${file}: missing canonical launch command`);
|
|
53
69
|
assert(content.includes(UNINSTALL_MA), `${file}: missing uninstall Meta-Architect command`);
|
|
@@ -77,12 +93,29 @@ function verifyNpmIgnore() {
|
|
|
77
93
|
}
|
|
78
94
|
}
|
|
79
95
|
|
|
96
|
+
function verifyDistPolicy() {
|
|
97
|
+
const tracked = execFileSync("git", ["ls-files", "dist/"], { encoding: "utf8" }).trim();
|
|
98
|
+
assert(!tracked, `dist/: generated release artifacts must not be tracked:\n${tracked}`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function verifyInstallerIntegrity() {
|
|
102
|
+
const installer = readText("scripts/install.sh");
|
|
103
|
+
const checksum = readText("scripts/install.sh.sha256").trim().split(/\s+/)[0];
|
|
104
|
+
const actual = crypto.createHash("sha256").update(installer).digest("hex");
|
|
105
|
+
assert(checksum === actual, "scripts/install.sh.sha256: checksum does not match installer");
|
|
106
|
+
assert(
|
|
107
|
+
!installer.includes("raw.githubusercontent.com") && !installer.includes("jsdelivr"),
|
|
108
|
+
"scripts/install.sh: must not fetch mutable installer sources at runtime",
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
80
112
|
function verifyDemoDoc({ version, gitTag }) {
|
|
113
|
+
const cdnInstall = latestCdnInstall();
|
|
81
114
|
assert(fs.existsSync("DEMO.md"), "DEMO.md: missing demo guide");
|
|
82
115
|
const content = readText("DEMO.md");
|
|
83
116
|
assert(content.includes(`Release line: \`${gitTag}\``), "DEMO.md: wrong release line");
|
|
84
117
|
assert(content.includes("Package: `@jstn-sdk/ma`"), "DEMO.md: missing package name");
|
|
85
|
-
assert(content.includes(
|
|
118
|
+
assert(content.includes(cdnInstall), "DEMO.md: missing versioned installer");
|
|
86
119
|
assert(content.includes(CANONICAL_INSTALL), "DEMO.md: missing canonical npm install");
|
|
87
120
|
assert(content.includes(CANONICAL_LAUNCH), "DEMO.md: missing canonical launch");
|
|
88
121
|
assert(content.includes(UNINSTALL_MA), "DEMO.md: missing MA uninstall command");
|
|
@@ -131,6 +164,77 @@ function verifyCoverageDoc({ version, gitTag }) {
|
|
|
131
164
|
assert(!content.includes("v0.1.0 release bar"), "COVERAGE.md: stale release bar");
|
|
132
165
|
}
|
|
133
166
|
|
|
167
|
+
function verifyReadmeReleaseSurface({ gitTag }) {
|
|
168
|
+
const content = readText("README.md");
|
|
169
|
+
const demoImage = `<img src="https://raw.githubusercontent.com/JustineDevs/meta-architect/${gitTag}/docs/assets/DEMO_VIDEO.gif" alt="Meta-Architect demo video" width="800">`;
|
|
170
|
+
const bannerImage = `<img src="./docs/assets/banner.png" alt="Meta-Architect: quality gates and evidence verification for AI coding agents" width="1000">`;
|
|
171
|
+
assert(content.includes("> [!NOTE]"), "README.md: missing product-positioning note admonition");
|
|
172
|
+
assert(
|
|
173
|
+
content.includes(
|
|
174
|
+
"> Meta-Architect is a workflow layer for teams that want architecture, evidence, review, and release discipline before build execution.",
|
|
175
|
+
),
|
|
176
|
+
"README.md: missing workflow-layer positioning note",
|
|
177
|
+
);
|
|
178
|
+
assert(
|
|
179
|
+
content.includes("> Meta-Architect does not replace your coding runtime."),
|
|
180
|
+
"README.md: missing runtime-wrapper boundary note",
|
|
181
|
+
);
|
|
182
|
+
assert(
|
|
183
|
+
content.includes(
|
|
184
|
+
"> It wraps that runtime with architecture, evidence, gate enforcement, and release-sensitive workflow control.",
|
|
185
|
+
),
|
|
186
|
+
"README.md: missing runtime-wrapper behavior note",
|
|
187
|
+
);
|
|
188
|
+
assert(content.includes(demoImage), "README.md: missing requested 800px demo GIF");
|
|
189
|
+
assert(
|
|
190
|
+
content.includes("<summary><strong>🔌 All 33 plugins & features</strong></summary>"),
|
|
191
|
+
"README.md: missing all 33 plugins/features toggle",
|
|
192
|
+
);
|
|
193
|
+
assert(
|
|
194
|
+
content.includes(
|
|
195
|
+
"https://img.shields.io/github/v/release/JustineDevs/meta-architect?display_name=tag&sort=semver",
|
|
196
|
+
),
|
|
197
|
+
"README.md: missing GitHub release badge",
|
|
198
|
+
);
|
|
199
|
+
assert(
|
|
200
|
+
fs.existsSync(path.join("docs", "assets", "banner.png")),
|
|
201
|
+
"docs/assets/banner.png: missing",
|
|
202
|
+
);
|
|
203
|
+
assert(content.includes(bannerImage), "README.md: banner image missing");
|
|
204
|
+
assert(
|
|
205
|
+
!content.includes("raw.githubusercontent.com/JustineDevs/meta-architect/main/"),
|
|
206
|
+
"README.md: stable docs must not reference mutable main",
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function verifyRealDemoKit() {
|
|
211
|
+
const runbook = readText(path.join("docs", "demo", "REAL_DEMO_RUNBOOK.md"));
|
|
212
|
+
const story = readText(path.join("docs", "demo", "DEMO_STORY.md"));
|
|
213
|
+
const checklist = readText(path.join("docs", "demo", "PROSPECT_CHECKLIST.md"));
|
|
214
|
+
assert(fs.existsSync(path.join("scripts", "demo-smoke.js")), "scripts/demo-smoke.js: missing");
|
|
215
|
+
assert(
|
|
216
|
+
runbook.includes("npm run demo:smoke"),
|
|
217
|
+
"REAL_DEMO_RUNBOOK.md: missing demo smoke command",
|
|
218
|
+
);
|
|
219
|
+
assert(runbook.includes("$maestro"), "REAL_DEMO_RUNBOOK.md: missing maestro scenario");
|
|
220
|
+
assert(
|
|
221
|
+
runbook.includes("vault_context"),
|
|
222
|
+
"REAL_DEMO_RUNBOOK.md: missing Obsidian context boundary",
|
|
223
|
+
);
|
|
224
|
+
assert(story.includes("Northstar Logistics"), "DEMO_STORY.md: missing realistic buyer story");
|
|
225
|
+
assert(story.includes("npm run release:verify"), "DEMO_STORY.md: missing release proof close");
|
|
226
|
+
assert(
|
|
227
|
+
checklist.includes("Remove `Demo Account`, `Test Company`, `Sample Co`"),
|
|
228
|
+
"PROSPECT_CHECKLIST.md: missing no-test-branding check",
|
|
229
|
+
);
|
|
230
|
+
for (const forbidden of ["Demo Account", "Test Company", "Sample Co"]) {
|
|
231
|
+
assert(
|
|
232
|
+
!runbook.includes(forbidden) && !story.includes(forbidden),
|
|
233
|
+
`demo docs: forbidden visible demo branding ${forbidden}`,
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
134
238
|
function verifyCanonicalSemanticSurfaces({ version, gitTag }) {
|
|
135
239
|
const usageWorkflow = readText(path.join("example", "usage-workflow.md"));
|
|
136
240
|
assert(
|
|
@@ -178,7 +282,7 @@ function verifyCanonicalSemanticSurfaces({ version, gitTag }) {
|
|
|
178
282
|
|
|
179
283
|
const currentQa = readText(path.join("docs", "qa", `release-readiness-${version}.md`));
|
|
180
284
|
assert(
|
|
181
|
-
currentQa.includes(
|
|
285
|
+
currentQa.includes(`Harden Meta-Architect ${gitTag} semantic core`),
|
|
182
286
|
`docs/qa/release-readiness-${version}.md: missing realistic semantic smoke idea`,
|
|
183
287
|
);
|
|
184
288
|
assert(
|
|
@@ -217,8 +321,12 @@ function main() {
|
|
|
217
321
|
assert(pkg.files?.includes("COVERAGE.md"), "package.json: files must include COVERAGE.md");
|
|
218
322
|
|
|
219
323
|
verifyNpmIgnore();
|
|
324
|
+
verifyDistPolicy();
|
|
325
|
+
verifyInstallerIntegrity();
|
|
220
326
|
verifyDemoDoc({ version, gitTag });
|
|
221
327
|
verifyCoverageDoc({ version, gitTag });
|
|
328
|
+
verifyReadmeReleaseSurface({ gitTag });
|
|
329
|
+
verifyRealDemoKit();
|
|
222
330
|
verifyCanonicalSemanticSurfaces({ version, gitTag });
|
|
223
331
|
|
|
224
332
|
const changelog = readText("CHANGELOG.md");
|
|
@@ -263,12 +371,28 @@ function main() {
|
|
|
263
371
|
const pluginManifest = readJson(
|
|
264
372
|
path.join("plugins", "meta-architect", ".codex-plugin", "plugin.json"),
|
|
265
373
|
);
|
|
374
|
+
const claudeMarketplace = readJson(path.join(".claude-plugin", "marketplace.json"));
|
|
375
|
+
const claudePlugin = readJson(
|
|
376
|
+
path.join("plugins", "meta-architect", ".claude-plugin", "plugin.json"),
|
|
377
|
+
);
|
|
266
378
|
assert(pluginApp.version === version, "plugins/meta-architect/.app.json: version drift");
|
|
267
379
|
assert(pluginMcp.version === version, "plugins/meta-architect/.mcp.json: version drift");
|
|
268
380
|
assert(
|
|
269
381
|
pluginManifest.version === version,
|
|
270
382
|
"plugins/meta-architect/.codex-plugin/plugin.json: version drift",
|
|
271
383
|
);
|
|
384
|
+
assert(
|
|
385
|
+
claudeMarketplace.metadata?.version === version,
|
|
386
|
+
".claude-plugin/marketplace.json: version drift",
|
|
387
|
+
);
|
|
388
|
+
assert(
|
|
389
|
+
claudeMarketplace.plugins?.some((plugin) => plugin.source === "./plugins/meta-architect"),
|
|
390
|
+
".claude-plugin/marketplace.json: missing Meta-Architect plugin source",
|
|
391
|
+
);
|
|
392
|
+
assert(
|
|
393
|
+
claudePlugin.version === version,
|
|
394
|
+
"plugins/meta-architect/.claude-plugin/plugin.json: version drift",
|
|
395
|
+
);
|
|
272
396
|
|
|
273
397
|
for (const file of [
|
|
274
398
|
"README.md",
|
|
@@ -279,7 +403,7 @@ function main() {
|
|
|
279
403
|
path.join("docs", "skills.md"),
|
|
280
404
|
path.join("plugins", "meta-architect", "README.md"),
|
|
281
405
|
]) {
|
|
282
|
-
verifyInstallBlock(file);
|
|
406
|
+
verifyInstallBlock(file, gitTag);
|
|
283
407
|
}
|
|
284
408
|
|
|
285
409
|
const envTag =
|
package/scripts/setup-npmrc.js
CHANGED
|
@@ -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
|
|
8
|
-
|
|
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
|
|
41
|
+
console.log("No npm token detected. Skipping temporary npm auth config.");
|
|
15
42
|
return;
|
|
16
43
|
}
|
|
17
44
|
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
`
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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 =
|
|
23
|
+
const meta = validateSkillFrontmatter(parseSkillFrontmatter(content), entry.name);
|
|
43
24
|
skills.push({
|
|
44
25
|
name: meta.name,
|
|
45
26
|
path: `skills/${entry.name}`,
|
package/scripts/skills-pack.js
CHANGED
|
@@ -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 =
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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);
|
package/skills/align/SKILL.md
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/skills/arch/SKILL.md
CHANGED
|
File without changes
|
|
File without changes
|
package/skills/build/SKILL.md
CHANGED
|
File without changes
|
|
File without changes
|
package/skills/cleanup/SKILL.md
CHANGED
|
File without changes
|