import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import assert from "node:assert/strict"; import { afterEach, describe, it } from "vitest"; import { createFeatureManifest, parseArgs, writeFeatureManifest } from "./create-feature-manifest.mjs"; const fixtures = []; function createRoot() { const root = fs.mkdtempSync(path.join(os.tmpdir(), "feature-manifest-")); fixtures.push(root); return root; } afterEach(() => { while (fixtures.length > 0) { fs.rmSync(fixtures.pop(), { recursive: true, force: true }); } }); describe("create-feature-manifest", () => { it("creates an integration-aware manifest scaffold", () => { const manifest = createFeatureManifest({ id: "customer-health", title: "Customer Health", classification: "plugin-candidate", ownership: "admin-managed", lastReviewed: "2026-05-15", }); assert.equal(manifest.schemaVersion, "1.0"); assert.equal(manifest.id, "customer-health"); assert.equal(manifest.pruning.action, "extract-plugin"); assert.equal(manifest.integration.ownership, "admin-managed"); assert.deepEqual(Object.keys(manifest.integration.surfaces), ["adminRoutes", "tenantRoutes", "publicRoutes", "apiRoutes"]); assert.match(manifest.integration.permissions[0], /^app\./); assert.match(manifest.integration.auditEvents[0], /^feature\./); assert.equal(manifest.validation.lastReviewed, "2026-05-15"); }); it("writes without overwriting existing manifests unless forced", () => { const root = createRoot(); const args = { id: "agent-demo", title: "Agent Demo", classification: "core", ownership: "system-only", lastReviewed: "2026-05-15", }; const first = writeFeatureManifest(args, root); assert.equal(path.relative(root, first.target), "docs/feature-manifests/agent-demo.json"); assert.equal(JSON.parse(fs.readFileSync(first.target, "utf8")).pruning.action, "keep"); assert.throws(() => writeFeatureManifest(args, root), /already exists/); assert.doesNotThrow(() => writeFeatureManifest({ ...args, force: true }, root)); }); it("parses CLI flags and rejects invalid values", () => { assert.deepEqual(parseArgs(["--id", "my-feature", "--title", "My Feature", "--force"]), { id: "my-feature", title: "My Feature", force: true, }); assert.throws(() => createFeatureManifest({ id: "Bad_ID", title: "Bad" }), /--id must match/); assert.throws(() => createFeatureManifest({ id: "ok", title: "" }), /--title is required/); assert.throws(() => createFeatureManifest({ id: "ok", title: "OK", classification: "legacy" }), /--classification must be/); }); });