arcane-cli 0.16.1 → 0.16.3

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/modules/copier.ts","../src/modules/manifest.ts","../src/config/profiles.ts","../src/modules/registry.ts","../src/modules/banner.ts","../src/modules/agents.ts","../src/config/agent-roles.ts","../src/config/agent-profiles.ts","../src/modules/naming.ts","../src/modules/agent-loader.ts","../src/modules/agent-schema.ts","../src/modules/agent-generator.ts","../src/modules/merger.ts","../src/modules/git.ts","../src/commands/add.ts","../src/commands/update.ts","../src/modules/hub.ts","../src/modules/version-check.ts","../src/commands/status.ts","../src/commands/uninstall.ts","../src/commands/doctor.ts","../src/config/incidents.ts","../src/modules/incident-gate.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { createRequire } from \"node:module\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\nimport { runInit } from \"./commands/init.js\";\nimport { runAdd } from \"./commands/add.js\";\nimport { runUpdate } from \"./commands/update.js\";\nimport { runStatus } from \"./commands/status.js\";\nimport { runUninstall } from \"./commands/uninstall.js\";\nimport { runDoctor } from \"./commands/doctor.js\";\nimport { runAgentsInit, runAgentsList, runAgentsSync } from \"./modules/agents.js\";\nimport { printWelcome } from \"./modules/banner.js\";\nimport type { Profile, AgentInitOptions, AgentProfileId, NamingStrategy, AgentSyncOptions } from \"./types.js\";\n\nconst require = createRequire(import.meta.url);\nconst pkg = require(\"../package.json\") as { version: string };\n\n/**\n * Resolved path to the bundled assets directory.\n * Points to src/assets/ during tests (vitest runs source directly) and\n * dist/assets/ in the published package (tsup bundles to dist/index.js).\n * Can be overridden via ARCANE_ASSETS_DIR env var for testing the built binary.\n */\nexport const ASSETS_DIR =\n process.env[\"ARCANE_ASSETS_DIR\"] ??\n join(dirname(fileURLToPath(import.meta.url)), \"assets\");\n\nconst program = new Command();\n\nprogram\n .name(\"spell\")\n .description(\"Arcane framework CLI — scaffold and manage governance files\")\n .version(pkg.version)\n .action(async () => {\n // Bare `spell` with no subcommand — show the welcome (banner + real repo\n // state + Spell Loop), then the command reference.\n await printWelcome(pkg.version, process.cwd());\n program.outputHelp();\n });\n\nprogram\n .command(\"init\")\n .description(\"Scaffold Arcane framework files into the current repository\")\n .option(\"--profile <profile>\", \"Profile: full | lite | methodology | governance-only\")\n .option(\"--force\", \"Overwrite existing files without error\")\n .option(\"--dry-run\", \"Preview what would be installed without making changes\")\n .action(\n async (opts: { profile?: string; force?: boolean; dryRun?: boolean }) => {\n await runInit(\n {\n profile: opts.profile as Profile | undefined,\n force: opts.force,\n dryRun: opts.dryRun,\n },\n process.cwd(),\n ASSETS_DIR,\n pkg.version,\n );\n },\n );\n\nprogram\n .command(\"add <component>\")\n .description(\"Add a component to an existing Arcane installation\")\n .option(\"--force\", \"Overwrite existing files without error\")\n .option(\"--dry-run\", \"Preview what would be added without making changes\")\n .action(\n async (\n component: string,\n opts: { force?: boolean; dryRun?: boolean },\n ) => {\n await runAdd(\n component,\n { force: opts.force, dryRun: opts.dryRun },\n process.cwd(),\n ASSETS_DIR,\n pkg.version,\n );\n },\n );\n\nprogram\n .command(\"update\")\n .description(\"Update installed components to the current package version\")\n .option(\"--dry-run\", \"Preview what would be updated without making changes\")\n .action(async (opts: { dryRun?: boolean }) => {\n await runUpdate(\n { dryRun: opts.dryRun },\n process.cwd(),\n ASSETS_DIR,\n pkg.version,\n );\n });\n\nprogram\n .command(\"status\")\n .description(\"Show installed components and check for updates\")\n .action(async () => {\n await runStatus(process.cwd(), pkg.version);\n });\n\nprogram\n .command(\"uninstall\")\n .description(\"Remove all installed Arcane framework files\")\n .option(\"--yes\", \"Skip confirmation prompt\")\n .option(\"--dry-run\", \"Preview what would be removed without deleting files\")\n .action(async (opts: { yes?: boolean; dryRun?: boolean }) => {\n await runUninstall({ yes: opts.yes, dryRun: opts.dryRun }, process.cwd());\n });\n\nprogram\n .command(\"doctor\")\n .description(\"Check your environment for Arcane prerequisites\")\n .option(\"--fix\", \"Automatically create missing session continuity files\")\n .action(async (opts: { fix?: boolean }) => {\n await runDoctor(process.cwd(), { fix: opts.fix }, ASSETS_DIR);\n });\n\n// ─── spell agents ─────────────────────────────────────────────────────────────\n\nconst agentsCommand = program\n .command(\"agents\")\n .description(\"Manage the portable agent system (init, sync, list)\");\n\nagentsCommand\n .command(\"init\")\n .description(\n \"Interactive agent roster setup — choose profile, naming strategy, and install definitions\",\n )\n .option(\n \"--profile <profile>\",\n \"Agent profile: base | full | custom\",\n )\n .option(\n \"--naming <strategy>\",\n \"Naming strategy: arcanos | generic | random | custom\",\n )\n .option(\"--force\", \"Reinitialize even if roster already exists\")\n .option(\"--dry-run\", \"Preview what would be created without writing files\")\n .action(\n async (opts: {\n profile?: string;\n naming?: string;\n force?: boolean;\n dryRun?: boolean;\n }) => {\n await runAgentsInit(\n {\n profile: opts.profile as AgentProfileId | undefined,\n naming: opts.naming as NamingStrategy | undefined,\n force: opts.force,\n dryRun: opts.dryRun,\n } satisfies AgentInitOptions,\n process.cwd(),\n ASSETS_DIR,\n );\n },\n );\n\nagentsCommand\n .command(\"sync\")\n .description(\n \"Regenerate all client instruction files from canonical agent definitions\",\n )\n .option(\"--dry-run\", \"Preview what would be generated without writing files\")\n .option(\"--no-openclaw\", \"Skip OpenClaw workspace output\")\n .option(\"--no-copilot\", \"Skip Copilot output\")\n .option(\"--no-claude\", \"Skip Claude output\")\n .option(\"--no-codex\", \"Skip Codex output\")\n .action(\n async (opts: {\n dryRun?: boolean;\n openclaw?: boolean;\n copilot?: boolean;\n claude?: boolean;\n codex?: boolean;\n }) => {\n await runAgentsSync(\n {\n dryRun: opts.dryRun,\n openclaw: opts.openclaw,\n copilot: opts.copilot,\n claude: opts.claude,\n codex: opts.codex,\n } satisfies AgentSyncOptions,\n process.cwd(),\n ASSETS_DIR,\n );\n },\n );\n\nagentsCommand\n .command(\"list\")\n .description(\"Show the current agent roster with assigned names and roles\")\n .action(async () => {\n await runAgentsList(process.cwd());\n });\n\n// Only parse argv when executed directly — not when imported in tests.\n// Use realpathSync to resolve symlinks (e.g. npm global bin → dist/index.js).\nimport { realpathSync } from \"node:fs\";\nif (realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)) {\n await program.parseAsync(process.argv);\n}\n\nexport { program };\n","import { select, confirm } from \"@inquirer/prompts\";\nimport { join } from \"node:path\";\nimport chalk from \"chalk\";\nimport { copyFile, copyDirectory } from \"../modules/copier.js\";\nimport {\n readManifest,\n writeManifest,\n ManifestNotFoundError,\n} from \"../modules/manifest.js\";\nimport { getProfile, listProfiles } from \"../modules/registry.js\";\nimport {\n printDryRun,\n printStep,\n printSuccess,\n printSection,\n printInfo,\n printNextStep,\n printWarning,\n} from \"../modules/banner.js\";\nimport { runAgentsInit } from \"../modules/agents.js\";\nimport { countUncommittedChanges } from \"../modules/git.js\";\nimport type {\n ArcaneManifest,\n HubRole,\n InstalledComponent,\n Profile,\n RegistryComponent,\n SpellInitOptions,\n} from \"../types.js\";\n\nconst VALID_PROFILES: Profile[] = [\"full\", \"lite\", \"governance-only\", \"methodology\"];\n\n// ─── Category labels for preview ─────────────────────────────────────────────\n\ninterface ComponentGroup {\n icon: string;\n label: string;\n count: number;\n}\n\nfunction categorizeComponents(components: RegistryComponent[]): ComponentGroup[] {\n const groups: ComponentGroup[] = [];\n\n const prompts = components.find((c) => c.name === \"spell-prompts\");\n if (prompts) {\n groups.push({\n icon: \"✨\",\n label: \"Copilot Spells\",\n count: prompts.files.length,\n });\n }\n\n const claude = components.find((c) => c.name === \"claude-commands\");\n if (claude) {\n groups.push({\n icon: \"⚡\",\n label: \"Claude Spells\",\n count: claude.files.length,\n });\n }\n\n const governance = components.filter(\n (c) =>\n c.name !== \"spell-prompts\" &&\n c.name !== \"claude-commands\" &&\n c.name !== \"venture-template\" &&\n c.name !== \"agent-definitions\" &&\n c.files.some((f) => f.startsWith(\".arcane/governance/\")),\n );\n if (governance.length > 0) {\n groups.push({\n icon: \"📋\",\n label: \"Governance Docs\",\n count: governance.reduce((n, c) => n + c.files.length, 0),\n });\n }\n\n const agentDef = components.find((c) => c.name === \"agent-definitions\");\n if (agentDef) {\n groups.push({\n icon: \"🛡️\",\n label: \"Agent Policies\",\n count: agentDef.files.length,\n });\n }\n\n const templates = components.find((c) => c.name === \"venture-template\");\n if (templates) {\n groups.push({\n icon: \"📄\",\n label: \"Templates\",\n count: templates.files.length,\n });\n }\n\n return groups;\n}\n\n/**\n * Builds a hover description string for the profile selection menu.\n * Shows the category breakdown so users know what they're getting.\n */\nfunction buildProfileDescription(components: RegistryComponent[], profile: Profile): string {\n const groups = categorizeComponents(components);\n const parts = groups.map((g) => `${g.icon} ${g.count} ${g.label}`);\n if (profile === \"full\" || profile === \"lite\") {\n // Insert agent roles before governance docs (spells + agents first, then the rest)\n const govIndex = groups.findIndex((g) => g.label === \"Governance Docs\");\n parts.splice(govIndex >= 0 ? govIndex : parts.length, 0, \"🤖 12 Agent Roles\");\n }\n return \"\\n\" + parts.join(\"\\n\");\n}\n\n// ─── Main ─────────────────────────────────────────────────────────────────────\n\n/**\n * Runs the `spell init` command.\n *\n * @param options CLI flags (profile, force, dryRun)\n * @param targetDir Directory to initialize (defaults to cwd in CLI)\n * @param assetsDir Path to the bundled assets root (dist/assets/ in prod, src/assets/ in tests)\n * @param packageVersion Current package version string (passed from CLI entry to avoid require path issues)\n */\nexport async function runInit(\n options: SpellInitOptions,\n targetDir: string,\n assetsDir: string,\n packageVersion: string,\n): Promise<void> {\n // Validate profile option if provided\n if (options.profile && !VALID_PROFILES.includes(options.profile)) {\n throw new Error(\n `Invalid profile \"${options.profile}\". Valid options: ${VALID_PROFILES.join(\", \")}`,\n );\n }\n\n // Check if already initialized\n try {\n await readManifest(targetDir);\n console.log(chalk.hex(\"#a855f7\")(`\\n ✦ Arcane v${packageVersion}\\n`));\n console.log('Already initialized. Run \"spell update\" to update existing files.');\n return;\n } catch (err) {\n if (!(err instanceof ManifestNotFoundError)) throw err;\n // ManifestNotFoundError = not initialized — proceed\n }\n\n console.log(chalk.hex(\"#a855f7\")(`\\n ✦ Arcane v${packageVersion}\\n`));\n\n // ── Safety check: warn about uncommitted changes ───────────────────────\n if (!options.dryRun) {\n const dirtyCount = await countUncommittedChanges(targetDir);\n if (dirtyCount > 0) {\n printWarning(`This repo has ${dirtyCount} uncommitted change${dirtyCount === 1 ? \"\" : \"s\"}.`);\n printInfo(\"Running spell init will add new files to your working tree.\");\n console.log();\n const continueAnyway = await confirm({\n message: \"Continue anyway?\",\n default: true,\n });\n if (!continueAnyway) {\n console.log(\"\\nCancelled. Commit or stash your changes first.\");\n return;\n }\n console.log();\n }\n }\n\n // ── Step 1: Resolve profile (prompt if not provided) ───────────────────\n let profile: Profile = options.profile as Profile;\n if (!profile) {\n const profiles = listProfiles();\n profile = (await select({\n message: \"Select an installation profile:\\n\",\n choices: profiles.map((p) => {\n const profileComponents = getProfile(p.id);\n return {\n value: p.id,\n name: `${p.id === \"full\" ? \"🧙\" : p.id === \"lite\" ? \"⚡\" : \"📋\"} ${p.displayName} — ${p.description}`,\n description: buildProfileDescription(profileComponents, p.id),\n };\n }),\n })) as Profile;\n }\n\n // ── Step 2: Resolve components ─────────────────────────────────────────\n const components = getProfile(profile);\n\n // ── Step 3: Preview what will be installed ─────────────────────────────\n const groups = categorizeComponents(components);\n\n console.log();\n printSection(`📦 Profile: ${profile}`);\n console.log();\n\n // Show agent setup as upcoming interactive step\n const hasAgents = profile === \"full\" || profile === \"lite\";\n\n // Build summary parts (same style as hover description)\n const previewParts = groups.map((g) => `${g.icon} ${g.count} ${g.label}`);\n if (hasAgents) {\n // Insert agent roles before governance docs\n const govIndex = groups.findIndex((g) => g.label === \"Governance Docs\");\n previewParts.splice(govIndex >= 0 ? govIndex : previewParts.length, 0, \"🤖 12 Agent Roles\");\n }\n console.log(` ${previewParts.join(\" · \")}`);\n\n console.log();\n\n // ── Step 4: Confirm (skip in non-interactive mode) ─────────────────────\n if (!options.dryRun && !options.profile) {\n const proceed = await confirm({\n message: \"Proceed with installation?\",\n default: true,\n });\n if (!proceed) {\n console.log(\"\\nCancelled.\");\n return;\n }\n }\n\n // ── Step 5: Copy files ─────────────────────────────────────────────────\n const installedComponents: InstalledComponent[] = [];\n let fileCount = 0;\n\n for (const component of components) {\n const installedFiles: string[] = [];\n\n for (const file of component.files) {\n const srcPath = join(assetsDir, file);\n if (options.dryRun) {\n printDryRun(`Would copy: ${file}`);\n } else {\n try {\n await copyFile(srcPath, targetDir, file, { force: options.force });\n } catch (err) {\n // skipExisting components silently skip files that already exist\n if (component.skipExisting && err instanceof Error && err.message.includes(\"already exists\")) {\n continue;\n }\n throw err;\n }\n }\n installedFiles.push(file);\n fileCount++;\n }\n\n for (const dir of component.directories ?? []) {\n const srcDirPath = join(assetsDir, dir);\n if (options.dryRun) {\n printDryRun(`Would copy directory: ${dir}/`);\n } else {\n const copied = await copyDirectory(srcDirPath, targetDir, dir, { force: options.force });\n installedFiles.push(...copied);\n fileCount += copied.length;\n }\n }\n\n if (!options.dryRun) {\n installedComponents.push({\n name: component.name,\n files: installedFiles,\n installedVersion: packageVersion,\n });\n }\n }\n\n // Show compact category summary (not 60 individual file paths)\n if (!options.dryRun) {\n for (const group of groups) {\n printStep(`${group.icon} ${group.count} ${group.label}`);\n }\n }\n\n if (options.dryRun) {\n // Show what agent setup would install\n if (hasAgents) {\n const agentFiles = await import(\"node:fs\").then((fsModule) =>\n fsModule.promises.readdir(join(assetsDir, \"agents\")),\n );\n const yamlFiles = agentFiles.filter((f) => f.endsWith(\".yaml\")).sort();\n printDryRun(\"Would run agent setup (interactive):\");\n printDryRun(\"Would write: .arcane/agents.yaml\");\n for (const f of yamlFiles) {\n printDryRun(`Would copy: .arcane/agents/${f}`);\n }\n }\n printDryRun(`Would initialize with profile \"${profile}\" — ${fileCount} files`);\n return;\n }\n\n // ── Step 5a: Hub question ───────────────────────────────────────────────\n // Explicit opt-in only -- never inferred from repo content (a `ventures/`\n // directory can legitimately exist in a consumer repo too, e.g. one this\n // very init run just created via a governance-only profile). Written\n // explicitly either way so a future `spell update` retrofit wizard can\n // tell \"asked and declined\" apart from \"predates this feature\".\n let role: HubRole | undefined;\n if (!options.profile) {\n console.log();\n const isHub = await confirm({\n message: \"Will this repo manage other ventures as a hub? (idea books, spell-manifest promotion, venture registry)\",\n default: false,\n });\n role = isHub ? \"hub\" : \"consumer\";\n }\n\n // ── Step 6: Write manifest ─────────────────────────────────────────────\n const manifest: ArcaneManifest = {\n version: packageVersion,\n profile,\n installedAt: new Date().toISOString(),\n components: installedComponents,\n ...(role ? { role } : {}),\n };\n await writeManifest(targetDir, manifest);\n\n printSuccess(`Initialized with profile \"${profile}\" — ${fileCount} files installed`);\n\n // ── Step 7: Offer agent setup (for full and lite profiles) ─────────────\n let agentsConfigured = false;\n if (hasAgents && !options.profile) {\n console.log();\n const setupAgents = await confirm({\n message: \"🤖 Set up your agent team? (names, roles, AI tool configs)\",\n default: true,\n });\n\n if (setupAgents) {\n await runAgentsInit({}, targetDir, assetsDir);\n agentsConfigured = true;\n }\n }\n\n // ── Step 8: Print next steps ───────────────────────────────────────────\n console.log();\n printSection(\"🚀 Next steps\");\n console.log();\n let step = 1;\n\n if (!agentsConfigured && profile !== \"governance-only\") {\n printNextStep(step++, \"Run `spell agents init` to set up your agent team\");\n }\n if (agentsConfigured) {\n printNextStep(\n step++,\n \"Edit .arcane/agents.yaml to customize roles → `spell agents sync` to regenerate AI tool configs\",\n );\n }\n if (profile !== \"governance-only\") {\n printNextStep(\n step++,\n \"Review .arcane/governance/ docs and customize for your project\",\n );\n }\n printNextStep(\n step++,\n \"Commit the new files: git add .arcane .github .claude AGENTS.md CLAUDE.md .arcane.json\",\n );\n console.log();\n}\n","import {\n mkdir,\n copyFile as fsCopyFile,\n access,\n readdir,\n} from \"node:fs/promises\";\nimport path from \"node:path\";\n\n/**\n * Validates that relativePath stays within targetDir.\n * Throws if the resolved path escapes the target directory boundary.\n */\nexport function validateTargetPath(\n targetDir: string,\n relativePath: string,\n): void {\n const resolvedBase = path.resolve(targetDir);\n const resolvedFull = path.resolve(targetDir, relativePath);\n\n if (\n resolvedFull !== resolvedBase &&\n !resolvedFull.startsWith(resolvedBase + path.sep)\n ) {\n throw new Error(\n `Path traversal detected: \"${relativePath}\" escapes target directory \"${targetDir}\"`,\n );\n }\n}\n\n/**\n * Creates a directory and all parent directories if they don't exist.\n */\nexport async function ensureDir(dirPath: string): Promise<void> {\n await mkdir(dirPath, { recursive: true });\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Copies srcPath into targetDir at relativePath.\n * Validates path traversal before any I/O.\n * Throws if the destination already exists and opts.force is not set.\n */\nexport async function copyFile(\n srcPath: string,\n targetDir: string,\n relativePath: string,\n opts: { force?: boolean } = {},\n): Promise<void> {\n validateTargetPath(targetDir, relativePath);\n\n const destPath = path.resolve(targetDir, relativePath);\n await ensureDir(path.dirname(destPath));\n\n if (!opts.force && (await fileExists(destPath))) {\n throw new Error(\n `Destination already exists: \"${relativePath}\". Use --force to overwrite.`,\n );\n }\n\n await fsCopyFile(srcPath, destPath);\n}\n\n/**\n * Recursively copies a directory from srcDir to targetDir/relativeDir.\n * Validates the target path to prevent traversal attacks.\n * Returns the list of relative file paths that were copied (for manifest tracking).\n */\nexport async function copyDirectory(\n srcDir: string,\n targetDir: string,\n relativeDir: string,\n opts: { force?: boolean } = {},\n): Promise<string[]> {\n validateTargetPath(targetDir, relativeDir);\n\n const copiedFiles: string[] = [];\n const entries = await readdir(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcEntryPath = path.join(srcDir, entry.name);\n const relEntryPath = `${relativeDir}/${entry.name}`;\n\n if (entry.isDirectory()) {\n const subFiles = await copyDirectory(srcEntryPath, targetDir, relEntryPath, opts);\n copiedFiles.push(...subFiles);\n } else {\n await copyFile(srcEntryPath, targetDir, relEntryPath, opts);\n copiedFiles.push(relEntryPath);\n }\n }\n\n return copiedFiles;\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type {\n ArcaneManifest,\n InstalledComponent,\n Profile,\n} from \"../types.js\";\n\nexport class ManifestNotFoundError extends Error {\n constructor(manifestPath: string) {\n super(`Manifest not found at \"${manifestPath}\". Run \"spell init\" first.`);\n this.name = \"ManifestNotFoundError\";\n }\n}\n\nexport class ManifestCorruptError extends Error {\n constructor(manifestPath: string) {\n super(\n `Manifest at \"${manifestPath}\" contains invalid JSON. It may be corrupted.`,\n );\n this.name = \"ManifestCorruptError\";\n }\n}\n\nconst MANIFEST_FILE = \".arcane.json\";\n\nfunction manifestPath(targetDir: string): string {\n return path.join(targetDir, MANIFEST_FILE);\n}\n\n/**\n * Reads .arcane.json from targetDir.\n * Throws ManifestNotFoundError if the file is missing.\n * Throws ManifestCorruptError if the file contains invalid JSON.\n */\nexport async function readManifest(targetDir: string): Promise<ArcaneManifest> {\n const filePath = manifestPath(targetDir);\n let content: string;\n\n try {\n content = await readFile(filePath, \"utf-8\");\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new ManifestNotFoundError(filePath);\n }\n throw err;\n }\n\n try {\n return JSON.parse(content) as ArcaneManifest;\n } catch {\n throw new ManifestCorruptError(filePath);\n }\n}\n\n/**\n * Writes the manifest to .arcane.json in targetDir with 2-space indentation.\n */\nexport async function writeManifest(\n targetDir: string,\n manifest: ArcaneManifest,\n): Promise<void> {\n const filePath = manifestPath(targetDir);\n await writeFile(filePath, JSON.stringify(manifest, null, 2), \"utf-8\");\n}\n\n/**\n * Creates a new .arcane.json in targetDir with an empty components array.\n * Returns the created manifest.\n */\nexport async function createManifest(\n targetDir: string,\n profile: Profile,\n version: string,\n): Promise<ArcaneManifest> {\n const manifest: ArcaneManifest = {\n version,\n profile,\n installedAt: new Date().toISOString(),\n components: [],\n };\n await writeManifest(targetDir, manifest);\n return manifest;\n}\n\n/**\n * Pure function — returns a new manifest with the component appended.\n * Does not write to disk.\n */\nexport function addComponent(\n manifest: ArcaneManifest,\n component: InstalledComponent,\n): ArcaneManifest {\n return {\n ...manifest,\n components: [...manifest.components, component],\n };\n}\n\n/**\n * Pure function — returns a new manifest with the named component removed.\n * Does not write to disk.\n */\nexport function removeComponent(\n manifest: ArcaneManifest,\n name: string,\n): ArcaneManifest {\n return {\n ...manifest,\n components: manifest.components.filter((c) => c.name !== name),\n };\n}\n\n/**\n * Returns true if a component with the given name exists in the manifest.\n */\nexport function hasComponent(manifest: ArcaneManifest, name: string): boolean {\n return manifest.components.some((c) => c.name === name);\n}\n","/**\n * Profile configuration — the canonical source of truth for Arcane profiles.\n *\n * A profile bundles a curated set of components for a common use case.\n * Adding or changing profiles requires only editing this file — no changes to\n * the registry or CLI command logic are needed.\n *\n * The special value \"*\" for `components` means \"all registered components\"\n * and is expanded by the registry at runtime.\n */\n\nimport type { Profile } from \"../types.js\";\n\nexport interface ProfileConfig {\n id: Profile;\n displayName: string;\n description: string;\n /**\n * Component names included in this profile.\n * Use the special value \"*\" to mean \"all registered components\" (full install).\n */\n components: string[] | \"*\";\n}\n\nexport const PROFILE_CONFIGS: ProfileConfig[] = [\n {\n id: \"full\",\n displayName: \"Full Suite\",\n description: \"All components — spells, governance, agents, templates\",\n components: \"*\",\n },\n {\n id: \"lite\",\n displayName: \"Essentials\",\n description: \"Spells + core governance — fast start\",\n components: [\"spell-prompts\", \"claude-commands\", \"agent-output-instructions\", \"git-conventions\", \"testing-standards\", \"framework-decisions\", \"session-continuity\"],\n },\n {\n id: \"methodology\",\n displayName: \"Methodology Suite\",\n description: \"Spells + governance — full methodology without security/infra docs\",\n components: [\n \"spell-prompts\",\n \"claude-commands\",\n \"agent-output-instructions\",\n \"git-conventions\",\n \"testing-standards\",\n \"framework-decisions\",\n \"session-continuity\",\n \"decision-documentation-standard\",\n \"agent-work-queue-model\",\n \"development-methodology\",\n \"spell-authoring-standards\",\n ],\n },\n {\n id: \"governance-only\",\n displayName: \"Governance Only\",\n description: \"Standards docs only — no spells or agents\",\n components: [\n \"agent-output-instructions\",\n \"git-conventions\",\n \"testing-standards\",\n \"framework-decisions\",\n \"decision-documentation-standard\",\n \"agent-work-queue-model\",\n \"naming-conventions\",\n \"agent-policies\",\n \"threat-model\",\n \"hardening-checklist\",\n \"authentication-strategy\",\n \"new-business-setup\",\n \"agent-approved-paths\",\n \"portable-bootstrap\",\n \"development-methodology\",\n \"cicd-standards\",\n \"poc-management-pattern\",\n \"product-excellence-standards\",\n \"rca-process-standard\",\n \"universal-agent-rules\",\n \"spell-authoring-standards\",\n ],\n },\n];\n","import type { Profile, RegistryComponent, ProfileDefinition } from \"../types.js\";\nimport { PROFILE_CONFIGS } from \"../config/profiles.js\";\n\nexport class ComponentNotFoundError extends Error {\n constructor(name: string, available: string[]) {\n super(\n `Component \"${name}\" not found. Available components: ${available.join(\", \")}`,\n );\n this.name = \"ComponentNotFoundError\";\n }\n}\n\n// ─── Component definitions ───────────────────────────────────────────────────\n// File paths are relative to src/assets/ (source) / dist/assets/ (published).\n\nconst COMPONENTS: RegistryComponent[] = [\n // Governance\n {\n name: \"git-conventions\",\n description: \"Git branching, commit message, and PR conventions\",\n files: [\".arcane/governance/git-conventions.md\"],\n },\n {\n name: \"testing-standards\",\n description: \"Testing framework selection, coverage thresholds, and CI gates\",\n files: [\".arcane/governance/testing-standards.md\"],\n },\n {\n name: \"framework-decisions\",\n description: \"Offline reference for legacy framework ADR citations\",\n files: [\".arcane/governance/framework-decisions.md\"],\n },\n {\n name: \"decision-documentation-standard\",\n description: \"ADR format and decision-logging conventions\",\n files: [\".arcane/governance/decision-documentation-standard.md\"],\n },\n {\n name: \"agent-work-queue-model\",\n description: \"Work queue model for AI agent task assignment and tracking\",\n files: [\".arcane/governance/agent-work-queue-model.md\"],\n },\n {\n name: \"naming-conventions\",\n description: \"Machine, agent, and service naming rules (three-tier model)\",\n files: [\".arcane/governance/naming-conventions.md\"],\n },\n {\n name: \"agent-policies\",\n description: \"Agent autonomy levels, power levels, and operational constraints\",\n files: [\".arcane/governance/agent-policies.md\"],\n },\n {\n name: \"threat-model\",\n description: \"Security threat model covering STRIDE categories and mitigations\",\n files: [\".arcane/governance/threat-model.md\"],\n },\n {\n name: \"hardening-checklist\",\n description: \"Production hardening checklist for infrastructure and agents\",\n files: [\".arcane/governance/hardening-checklist.md\"],\n },\n {\n name: \"authentication-strategy\",\n description: \"Authentication patterns, token management, and identity strategy\",\n files: [\".arcane/governance/authentication-strategy.md\"],\n },\n {\n name: \"new-business-setup\",\n description: \"Step-by-step playbook for bootstrapping a new business unit\",\n files: [\".arcane/governance/new-business-setup.md\"],\n },\n {\n name: \"agent-approved-paths\",\n description: \"Approved repository paths and access boundaries for agents\",\n files: [\".arcane/governance/agent-approved-paths.md\"],\n },\n {\n name: \"portable-bootstrap\",\n description: \"Portable AI context bootstrap for onboarding new AI clients\",\n files: [\".arcane/governance/portable-bootstrap.md\"],\n },\n // Governance — methodology\n {\n name: \"development-methodology\",\n description: \"Spell Loop development methodology\",\n files: [\".arcane/governance/development-methodology.md\"],\n },\n {\n name: \"cicd-standards\",\n description: \"CI/CD pipeline standards and quality gates\",\n files: [\".arcane/governance/cicd-standards.md\"],\n },\n {\n name: \"poc-management-pattern\",\n description: \"POC lifecycle management pattern\",\n files: [\".arcane/governance/poc-management-pattern.md\"],\n },\n {\n name: \"product-excellence-standards\",\n description: \"Product quality gate standards and spell-enchant requirements\",\n files: [\".arcane/governance/product-excellence-standards.md\"],\n },\n {\n name: \"spell-authoring-standards\",\n description: \"Spell Quality Rubric — the authoring bar for spell prompts (8 dimensions)\",\n files: [\".arcane/governance/spell-authoring-standards.md\"],\n },\n {\n name: \"rca-process-standard\",\n description: \"Root cause analysis process standard\",\n files: [\".arcane/governance/rca-process-standard.md\"],\n },\n {\n name: \"universal-agent-rules\",\n description: \"Universal rules for all AI agents operating in any Arcane-managed repo\",\n files: [\".arcane/governance/universal-agent-rules.md\"],\n },\n // VS Code Copilot instructions — installed to .github/instructions/\n {\n name: \"agent-output-instructions\",\n description: \"Copilot enforcement rules: PR link format, merge strategy, and branch naming\",\n files: [\".github/instructions/agent-output.instructions.md\"],\n },\n // Spell prompts — installed to .github/prompts/ (VS Code Copilot convention)\n {\n name: \"spell-prompts\",\n description: \"Full Arcane spell prompt library (34 spells)\",\n files: [\n \".github/prompts/spell-arcane-version.prompt.md\",\n \".github/prompts/spell-architect.prompt.md\",\n \".github/prompts/spell-brainstorm.prompt.md\",\n \".github/prompts/spell-scope.prompt.md\",\n \".github/prompts/spell-summon-venture.prompt.md\",\n \".github/prompts/spell-bug.prompt.md\",\n \".github/prompts/spell-bump.prompt.md\",\n \".github/prompts/spell-check-drift.prompt.md\",\n \".github/prompts/spell-close-session.prompt.md\",\n \".github/prompts/spell-commit-work.prompt.md\",\n \".github/prompts/spell-dotnet-expert.prompt.md\",\n \".github/prompts/spell-enchant.prompt.md\",\n \".github/prompts/spell-explain-concept.prompt.md\",\n \".github/prompts/spell-full-cycle.prompt.md\",\n \".github/prompts/spell-generate-bot-icons.prompt.md\",\n \".github/prompts/spell-implement.prompt.md\",\n \".github/prompts/spell-open-session.prompt.md\",\n \".github/prompts/spell-plan.prompt.md\",\n \".github/prompts/spell-present-arcane.prompt.md\",\n \".github/prompts/spell-product-review.prompt.md\",\n \".github/prompts/spell-review.prompt.md\",\n \".github/prompts/spell-security-review.prompt.md\",\n \".github/prompts/spell-ship.prompt.md\",\n \".github/prompts/spell-suggest-feature.prompt.md\",\n \".github/prompts/spell-test.prompt.md\",\n \".github/prompts/spell-todo.prompt.md\",\n // Workflow spell additions — PR lifecycle, status, capture, feedback\n \".github/prompts/spell-address-review.prompt.md\",\n \".github/prompts/spell-create-pull-request.prompt.md\",\n \".github/prompts/spell-document.prompt.md\",\n \".github/prompts/spell-feedback.prompt.md\",\n \".github/prompts/spell-manifest.prompt.md\",\n \".github/prompts/spell-save-idea.prompt.md\",\n \".github/prompts/spell-status.prompt.md\",\n \".github/prompts/spell-review-batch.prompt.md\",\n ],\n },\n // Templates\n {\n name: \"venture-template\",\n description: \"Starter template for a new business venture folder — overview plus idea/todo books\",\n files: [\n \".arcane/templates/venture-template/overview.md\",\n \".arcane/templates/venture-template/IDEAS.md\",\n \".arcane/templates/venture-template/TODO.md\",\n ],\n },\n // Session continuity — files required for spell-close-session / spell-open-session\n {\n name: \"session-continuity\",\n description: \"Install-once project orientation and session lifecycle files\",\n skipExisting: true,\n files: [\n \"README.md\",\n \"project.md\",\n \"TODO.md\",\n \"DECISIONS.md\",\n \"ai-context/system-prompt-context.md\",\n \"journal/.gitkeep\",\n ],\n },\n // Agent definitions\n // NOTE: the full portable agent system is managed by `spell agents init` / sync / list.\n // This component only installs the policy reference template for governance-only setups.\n {\n name: \"agent-definitions\",\n description: \"Agent policy reference template (for governance-only setups — use `spell agents init` for the full agent system)\",\n files: [\".arcane/agents/agent-policies-template.md\"],\n },\n // NOTE: the static `agent-files` component was retired — `.github/agents/*.agent.md`\n // files are generated per-roster by `spell agents init` / `spell agents sync`, so\n // installing a fixed-name set via `spell init` shipped stale names and collided\n // with the generated output.\n // Claude commands\n {\n name: \"claude-commands\",\n description: \"Claude Code slash command wrappers for all 34 Arcane spells\",\n files: [\n \".claude/commands/spell-arcane-version.md\",\n \".claude/commands/spell-architect.md\",\n \".claude/commands/spell-brainstorm.md\",\n \".claude/commands/spell-scope.md\",\n \".claude/commands/spell-summon-venture.md\",\n \".claude/commands/spell-bug.md\",\n \".claude/commands/spell-bump.md\",\n \".claude/commands/spell-check-drift.md\",\n \".claude/commands/spell-close-session.md\",\n \".claude/commands/spell-commit-work.md\",\n \".claude/commands/spell-dotnet-expert.md\",\n \".claude/commands/spell-enchant.md\",\n \".claude/commands/spell-explain-concept.md\",\n \".claude/commands/spell-full-cycle.md\",\n \".claude/commands/spell-generate-bot-icons.md\",\n \".claude/commands/spell-implement.md\",\n \".claude/commands/spell-open-session.md\",\n \".claude/commands/spell-plan.md\",\n \".claude/commands/spell-present-arcane.md\",\n \".claude/commands/spell-product-review.md\",\n \".claude/commands/spell-review.md\",\n \".claude/commands/spell-security-review.md\",\n \".claude/commands/spell-ship.md\",\n \".claude/commands/spell-suggest-feature.md\",\n \".claude/commands/spell-test.md\",\n \".claude/commands/spell-todo.md\",\n // Workflow spell additions — PR lifecycle, status, capture, feedback\n \".claude/commands/spell-address-review.md\",\n \".claude/commands/spell-create-pull-request.md\",\n \".claude/commands/spell-document.md\",\n \".claude/commands/spell-feedback.md\",\n \".claude/commands/spell-manifest.md\",\n \".claude/commands/spell-save-idea.md\",\n \".claude/commands/spell-status.md\",\n \".claude/commands/spell-review-batch.md\",\n ],\n },\n];\n\n// ─── Profile map (derived from config) ───────────────────────────────────────\n\nfunction buildProfileMap(): Record<Profile, string[]> {\n const allNames = COMPONENTS.map((c) => c.name);\n const map = {} as Record<Profile, string[]>;\n for (const config of PROFILE_CONFIGS) {\n map[config.id] = config.components === \"*\" ? allNames : config.components;\n }\n return map;\n}\n\nconst PROFILE_MAP = buildProfileMap();\n\n// ─── API ──────────────────────────────────────────────────────────────────────\n\nconst componentIndex = new Map(COMPONENTS.map((c) => [c.name, c]));\n\n/**\n * Returns a component by name.\n * Throws ComponentNotFoundError if not found.\n */\nexport function getComponent(name: string): RegistryComponent {\n const component = componentIndex.get(name);\n if (!component) {\n throw new ComponentNotFoundError(name, Array.from(componentIndex.keys()));\n }\n return component;\n}\n\n/**\n * Returns all components for the given profile.\n */\nexport function getProfile(profile: Profile): RegistryComponent[] {\n return PROFILE_MAP[profile].map((name) => getComponent(name));\n}\n\n/**\n * Returns all registered components.\n */\nexport function getAllComponents(): RegistryComponent[] {\n return [...COMPONENTS];\n}\n\n/**\n * Returns all profile definitions with their component lists expanded.\n * Profiles are sourced from src/config/profiles.ts.\n */\nexport function listProfiles(): ProfileDefinition[] {\n const allNames = COMPONENTS.map((c) => c.name);\n return PROFILE_CONFIGS.map((config) => ({\n id: config.id,\n displayName: config.displayName,\n description: config.description,\n components:\n config.components === \"*\" ? [...allNames] : [...config.components],\n }));\n}\n","import chalk from \"chalk\";\nimport gradient from \"gradient-string\";\nimport { readManifest } from \"./manifest.js\";\n\nconst TAGLINE = \"Cast spells to ship software\";\n\n// ─── Brand palette — steel blue (#6F9FD8) ────────────────────────────────────\nconst STEEL = \"#6f9fd8\";\nconst STEEL_DEEP = \"#3a6ea5\";\nconst STEEL_DIM = \"#5d6f93\";\nconst INK_LABEL = \"#c7d2ee\";\nconst FAINT = \"#2c3658\";\n\nconst STOPS = [\"#2a4d7d\", \"#4a7bb5\", \"#6f9fd8\", \"#a9c8ec\"];\nconst arcaneGradient = gradient(STOPS);\n\n// ─── ARCANE wordmark ─────────────────────────────────────────────────────────\nconst WORDMARK = [\n \" █████╗ ██████╗ ██████╗ █████╗ ███╗ ██╗███████╗\",\n \"██╔══██╗██╔══██╗██╔════╝██╔══██╗████╗ ██║██╔════╝\",\n \"███████║██████╔╝██║ ███████║██╔██╗ ██║█████╗\",\n \"██╔══██║██╔══██╗██║ ██╔══██║██║╚██╗██║██╔══╝\",\n \"██║ ██║██║ ██║╚██████╗██║ ██║██║ ╚████║███████╗\",\n \"╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝\",\n];\nconst INDENT = \" \";\nconst LOCKUP_WIDTH = INDENT.length + Math.max(...WORDMARK.map((l) => l.length));\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** True when the terminal can render the fade-in safely. */\nfunction isAnimatable(): boolean {\n return (\n !!process.stdout.isTTY &&\n process.env[\"TERM\"] !== \"dumb\" &&\n process.env[\"CI\"] !== \"true\" &&\n process.env[\"ARCANE_DISABLE_ANIMATION\"] !== \"true\" &&\n (process.stdout.columns ?? 80) >= LOCKUP_WIDTH\n );\n}\n\n/** Scale a hex color toward black by factor f (0..1) — used for the fade-in. */\nfunction scale(hex: string, f: number): string {\n const v = (i: number): number =>\n Math.max(0, Math.min(255, Math.round(parseInt(hex.slice(i, i + 2), 16) * f)));\n return \"#\" + [v(1), v(3), v(5)].map((x) => x.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n/** Build the ARCANE wordmark lines at brightness f (1 = full color). */\nfunction lockupLines(f = 1): string[] {\n const g = f >= 1 ? arcaneGradient : gradient(STOPS.map((c) => scale(c, f)));\n return WORDMARK.map((line) => INDENT + g(line));\n}\n\nfunction printFooter(version: string): void {\n const taglineText = ` ${TAGLINE} · agent-native SDLC · v${version}`;\n const width = Math.max(LOCKUP_WIDTH, taglineText.length);\n const border = chalk.hex(STEEL_DEEP)(\"─\".repeat(width));\n console.log(border);\n console.log(\n chalk.hex(STEEL)(` ${TAGLINE}`),\n chalk.hex(STEEL_DIM)(`· agent-native SDLC · v${version}`),\n );\n console.log(border);\n}\n\n/**\n * Prints the ARCANE wordmark static, with tagline and version.\n * Used by subcommands (init, etc.).\n */\nexport function printBanner(version: string): void {\n console.log();\n for (const line of lockupLines()) console.log(line);\n printFooter(version);\n console.log();\n}\n\n/**\n * Headline counts for the welcome — turns the installed component file list into\n * \"N spells · N agents · N standards\" (the manifest stores registry-relative,\n * forward-slash paths). Returns [] when nothing categorizable is installed, so\n * the caller can fall back to a plain component count.\n */\nfunction installSummary(components: { files: string[] }[]): string[] {\n const files = components.flatMap((c) =>\n c.files.map((f) => f.replace(/\\\\/g, \"/\")),\n );\n const spells = new Set(\n files\n .filter((f) => /\\/(prompts|commands)\\/spell-.+\\.md$/.test(f))\n .map((f) => f.split(\"/\").pop()!.replace(/\\.prompt\\.md$|\\.md$/, \"\")),\n ).size;\n const agents = files.filter((f) => /\\/agents\\/[^/]+\\.agent\\.md$/.test(f)).length;\n const standards = files.filter((f) =>\n /\\/governance\\/[^/]+\\.md$/.test(f),\n ).length;\n const parts: string[] = [];\n if (spells) parts.push(`${spells} spell${spells === 1 ? \"\" : \"s\"}`);\n if (agents) parts.push(`${agents} agent${agents === 1 ? \"\" : \"s\"}`);\n if (standards) parts.push(`${standards} standard${standards === 1 ? \"\" : \"s\"}`);\n return parts;\n}\n\n/**\n * The bare-`spell` welcome screen: a soft fade-in of the lockup followed by a\n * single gentle pulse (strobe-safe — monotonic brightness ramps, no color\n * cycling), then real current state: whether Arcane is installed in this repo\n * (profile, components, version) and the Spell Loop. Falls back to a static\n * lockup on non-TTY / CI / narrow terminals.\n */\nexport async function printWelcome(version: string, cwd: string): Promise<void> {\n console.log();\n if (isAnimatable()) {\n const draw = (lines: string[], redraw: boolean): void => {\n if (redraw) process.stdout.write(`\\x1b[${lines.length}A`);\n for (const line of lines) process.stdout.write(`\\r\\x1b[2K${line}\\n`);\n };\n // 1. Fade in from dark — the mark materializes.\n const fade = [0.1, 0.22, 0.36, 0.52, 0.68, 0.84, 1];\n for (let i = 0; i < fade.length; i++) {\n draw(lockupLines(fade[i]!), i > 0);\n await sleep(90);\n }\n // 2. One gentle settling pulse — a single slow breath of brightness.\n const pulse = [1, 0.9, 0.82, 0.9, 1];\n for (let i = 0; i < pulse.length; i++) {\n draw(lockupLines(pulse[i]!), true);\n await sleep(140);\n }\n } else {\n for (const line of lockupLines()) console.log(line);\n }\n printFooter(version);\n console.log();\n\n const label = (s: string): string => chalk.hex(STEEL_DIM)(s.padEnd(11));\n const dot = chalk.hex(FAINT)(\"·\");\n\n let repoLine: string;\n try {\n const manifest = await readManifest(cwd);\n const parts = installSummary(manifest.components);\n const summary = parts.length\n ? parts\n : [`${manifest.components.length} components`];\n repoLine =\n `${chalk.hex(STEEL)(\"✓\")} Arcane ${chalk.hex(INK_LABEL)(`«${manifest.profile}»`)} ${dot} ` +\n summary.map((p) => chalk.hex(INK_LABEL)(p)).join(` ${dot} `) +\n ` ${dot} ${chalk.hex(STEEL_DIM)(`v${manifest.version}`)}`;\n } catch {\n repoLine =\n `${chalk.hex(STEEL_DIM)(\"○\")} not initialized ${chalk.hex(FAINT)(\"—\")} run ` +\n `${chalk.hex(STEEL).inverse(\" spell init \")} ${chalk.hex(STEEL_DIM)(\"to scaffold\")}`;\n }\n console.log(` ${label(\"This repo\")}${repoLine}`);\n\n const phases = [\"plan\", \"architect\", \"implement\", \"test\", \"review\", \"ship\"].join(\n chalk.hex(STEEL_DEEP)(\" → \"),\n );\n console.log(` ${label(\"Spell Loop\")}${chalk.hex(\"#dbe3f7\")(phases)}`);\n\n // loop-back hint under the implement → test → review cycle\n const flat = [\"plan\", \"architect\", \"implement\", \"test\", \"review\", \"ship\"].join(\" → \");\n const loopStart = 13 + flat.indexOf(\"implement\"); // col under \"implement\"\n const loopEnd = 13 + flat.indexOf(\"review\") + 5; // col under last char of \"review\"\n const inner = loopEnd - loopStart - 1;\n const lp = Math.floor((inner - 19) / 2); // 19 = visible width of \" ↺ until it passes \"\n const rp = inner - 19 - lp;\n const dash = (n: number): string => chalk.hex(STEEL_DEEP)(\"─\".repeat(Math.max(0, n)));\n console.log(\n \" \".repeat(loopStart) +\n chalk.hex(STEEL_DEEP)(\"╰\") +\n dash(lp) +\n chalk.hex(STEEL)(\" ↺ \") +\n chalk.hex(STEEL_DIM)(\"until it passes\") +\n \" \" +\n dash(rp) +\n chalk.hex(STEEL_DEEP)(\"╯\"),\n );\n console.log();\n}\n\nexport function printSuccess(message: string): void {\n console.log(`\\n${chalk.hex(STEEL)(\"✦\")} ${chalk.bold(message)}`);\n}\n\nexport function printStep(message: string): void {\n console.log(` ${chalk.hex(STEEL_DEEP)(\"▸\")} ${message}`);\n}\n\nexport function printDryRun(message: string): void {\n console.log(` ${chalk.yellow(\"◌\")} ${chalk.dim(message)}`);\n}\n\nexport function printSection(title: string): void {\n console.log(`\\n${chalk.hex(STEEL)(\"─\")} ${chalk.bold(title)}`);\n}\n\nexport function printInfo(message: string): void {\n console.log(` ${chalk.dim(message)}`);\n}\n\nexport function printNextStep(step: number, message: string): void {\n console.log(` ${chalk.hex(STEEL_DEEP)(`${step}.`)} ${message}`);\n}\n\nexport function printWarning(message: string): void {\n console.log(` ${chalk.yellow(\"⚠\")} ${chalk.yellow(message)}`);\n}\n","/**\n * `spell agents` subcommand group.\n *\n * Subcommands:\n * spell agents init — Interactive roster setup (naming strategy + role selection)\n * spell agents sync — Regenerate all client instruction files from canonical defs\n * spell agents list — Show current roster with assigned names and roles\n */\n\nimport { select, checkbox, Separator } from \"@inquirer/prompts\";\nimport { mkdir, writeFile, copyFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { stringify } from \"yaml\";\nimport type {\n AgentInitOptions,\n AgentRoster,\n AgentRosterEntry,\n AgentSyncOptions,\n NamingStrategy,\n AgentProfileId,\n} from \"../types.js\";\nimport { AGENT_ROLES } from \"../config/agent-roles.js\";\nimport {\n AGENT_PROFILE_CONFIGS,\n getAgentProfileConfig,\n} from \"../config/agent-profiles.js\";\nimport { applyNamingStrategy } from \"./naming.js\";\nimport {\n loadRoster,\n rosterExists,\n AgentConfigValidationError,\n AgentRosterNotFoundError,\n} from \"./agent-loader.js\";\nimport { syncAgents } from \"./agent-generator.js\";\nimport { printStep, printSuccess } from \"./banner.js\";\n\n// ─── spell agents init ────────────────────────────────────────────────────────\n\n/**\n * Interactive agent roster setup.\n *\n * 1. Prompts for agent profile (base | full | custom)\n * 2. Prompts for naming strategy (generic | random | custom)\n * 3. Applies naming and writes .arcane/agents.yaml + copies definition files\n */\nexport async function runAgentsInit(\n options: AgentInitOptions,\n targetDir: string,\n assetsDir: string,\n): Promise<void> {\n // Check for existing roster\n if (!options.force && (await rosterExists(targetDir))) {\n console.log(\n 'Agent roster already exists at .arcane/agents.yaml. ' +\n 'Run \"spell agents sync\" to regenerate outputs, or use --force to reinitialize.',\n );\n return;\n }\n\n console.log();\n\n // ── Step 1: Agent profile ────────────────────────────────────────────────\n let profileId: AgentProfileId = options.profile ?? \"full\";\n if (!options.profile) {\n const baseRoles = getAgentProfileConfig(\"base\").roles;\n const baseRoleNames = baseRoles.map((id) => {\n const role = AGENT_ROLES.find((r) => r.id === id);\n return role ? role.role : id;\n });\n const allCategories = [...new Set(AGENT_ROLES.map((r) => r.category))];\n\n profileId = (await select({\n message: \"Select an agent profile:\",\n choices: AGENT_PROFILE_CONFIGS.map((p) => ({\n value: p.id,\n name: `${p.id === \"base\" ? \"🎯\" : p.id === \"full\" ? \"🧙\" : \"🎨\"} ${p.displayName}`,\n description:\n p.id === \"base\"\n ? `\\n4 core roles: ${baseRoleNames.join(\", \")}`\n : p.id === \"full\"\n ? `\\nAll 12 roles across ${allCategories.join(\", \")}`\n : \"\\nPick individual roles from the full roster\",\n })),\n })) as AgentProfileId;\n }\n\n // Resolve role IDs for selected profile\n let selectedRoleIds: string[];\n if (profileId === \"custom\") {\n // Group roles by category with separators\n const categories = [...new Set(AGENT_ROLES.map((r) => r.category))];\n const choicesWithSeparators: Array<\n | { value: string; name: string; checked: boolean }\n | Separator\n > = [];\n for (const cat of categories) {\n choicesWithSeparators.push(new Separator(`── ${cat.charAt(0).toUpperCase() + cat.slice(1)} ──`));\n for (const r of AGENT_ROLES.filter((r) => r.category === cat)) {\n choicesWithSeparators.push({\n value: r.id,\n name: `${r.id} — ${r.role}`,\n checked: true,\n });\n }\n }\n\n console.log();\n selectedRoleIds = await checkbox({\n message: \"Select roles to install:\",\n choices: choicesWithSeparators,\n validate: (choices) =>\n choices.length > 0 ? true : \"Select at least one role\",\n });\n } else {\n selectedRoleIds = getAgentProfileConfig(profileId).roles;\n }\n\n // ── Step 2: Naming strategy ──────────────────────────────────────────────\n let namingStrategy: NamingStrategy = options.naming ?? \"arcanos\";\n if (!options.naming) {\n console.log();\n namingStrategy = (await select({\n message: \"Choose a naming strategy for your agents:\",\n choices: [\n {\n value: \"arcanos\" as NamingStrategy,\n name: \"🃏 Arcanos\",\n description: \"\\nPersona names: Kellar, Merlin, Lafayette, Lince, Prospero...\",\n },\n {\n value: \"generic\" as NamingStrategy,\n name: \"🏷️ Generic\",\n description: \"\\nRole-derived labels: Orchestrator, Architect, Developer, QA Lead...\",\n },\n {\n value: \"random\" as NamingStrategy,\n name: \"🎲 Random\",\n description: \"\\nCommon first names shuffled randomly: Blake, Morgan, Casey...\",\n },\n {\n value: \"custom\" as NamingStrategy,\n name: \"✏️ Custom\",\n description: \"\\nType a unique name for each role interactively\",\n },\n ],\n })) as NamingStrategy;\n }\n\n // ── Step 3: Apply naming ─────────────────────────────────────────────────\n printStep(\"Assigning names...\");\n const named = await applyNamingStrategy(namingStrategy, selectedRoleIds);\n\n // ── Step 4: Build roster ─────────────────────────────────────────────────\n const rosterEntries: AgentRosterEntry[] = named.map(({ definition, name }) => {\n // Orchestrator gets the \"main\" OpenClaw ID by convention\n const id = definition === \"orchestrator\" ? \"main\" : name.toLowerCase().replace(/\\s+/g, \"-\");\n return { definition, name, id };\n });\n\n const roster: AgentRoster = {\n schema_version: 2,\n naming_strategy: namingStrategy,\n agent_profile: profileId,\n openclaw: {\n enabled: true,\n workspace_root: \"~/.openclaw\",\n },\n roster: rosterEntries,\n };\n\n // ── Step 5: Write .arcane/agents.yaml ────────────────────────────────────\n const arcaneDir = join(targetDir, \".arcane\", \"agents\");\n if (!options.dryRun) {\n await mkdir(arcaneDir, { recursive: true });\n await writeFile(\n join(targetDir, \".arcane\", \"agents.yaml\"),\n stringify(roster),\n \"utf8\",\n );\n } else {\n console.log(\" [dry-run] Would write: .arcane/agents.yaml\");\n }\n\n // ── Step 6: Copy bundled definition files ─────────────────────────────────\n for (const roleId of selectedRoleIds) {\n const src = join(assetsDir, \"agents\", `${roleId}.yaml`);\n const dest = join(arcaneDir, `${roleId}.yaml`);\n if (!options.dryRun) {\n try {\n await copyFile(src, dest);\n } catch {\n console.warn(` ! Could not copy definition for \"${roleId}\" — skipping`);\n }\n } else {\n console.log(` [dry-run] Would copy: .arcane/agents/${roleId}.yaml`);\n }\n }\n\n if (options.dryRun) {\n console.log(\n `\\n [dry-run] Would initialize roster with ${selectedRoleIds.length} agents`,\n );\n return;\n }\n\n // ── Step 7: Auto-sync all clients ────────────────────────────────────────\n printStep(\"Syncing agent definitions to all clients...\");\n const { synced, skipped } = await syncAgents(\n targetDir,\n assetsDir,\n roster,\n { dryRun: false },\n );\n\n printSuccess(\"Agent roster initialized\");\n console.log(` 📋 Profile: ${profileId} · Naming: ${namingStrategy} · Agents: ${rosterEntries.length}`);\n console.log(` 🔄 Synced: ${synced.length} outputs (Copilot, Claude, Codex, OpenClaw)`);\n if (skipped.length > 0) {\n console.log(` ⚠️ Skipped: ${skipped.length} (${skipped.join(\", \")})`);\n }\n console.log();\n console.log(` 💡 Customize: edit .arcane/agents.yaml → spell agents sync`);\n console.log();\n}\n\n// ─── spell agents sync ────────────────────────────────────────────────────────\n\n/** Regenerates all client instruction files from the current roster + definitions. */\nexport async function runAgentsSync(\n options: AgentSyncOptions,\n targetDir: string,\n assetsDir: string,\n): Promise<void> {\n let roster: AgentRoster;\n try {\n roster = await loadRoster(targetDir);\n } catch (err) {\n if (\n err instanceof AgentRosterNotFoundError\n || err instanceof AgentConfigValidationError\n ) {\n console.error(err.message);\n process.exit(1);\n return;\n }\n throw err;\n }\n\n if (options.dryRun) {\n console.log(\"\\n [dry-run] Would sync agents from roster:\\n\");\n } else {\n console.log(\"\\n Syncing agents...\\n\");\n }\n\n const { synced, skipped } = await syncAgents(\n targetDir,\n assetsDir,\n roster,\n options,\n );\n\n if (options.dryRun) {\n console.log(`\\n [dry-run] ${synced.length} outputs would be generated`);\n return;\n }\n\n console.log(`\\n ✓ Synced ${synced.length} outputs`);\n for (const item of synced) {\n console.log(` + ${item}`);\n }\n if (skipped.length > 0) {\n console.log(`\\n ! Skipped ${skipped.length}:`);\n for (const item of skipped) {\n console.log(` - ${item}`);\n }\n }\n console.log();\n}\n\n// ─── spell agents list ────────────────────────────────────────────────────────\n\n/** Displays the current agent roster in a table. */\nexport async function runAgentsList(targetDir: string): Promise<void> {\n let roster: AgentRoster;\n try {\n roster = await loadRoster(targetDir);\n } catch (err) {\n if (\n err instanceof AgentRosterNotFoundError\n || err instanceof AgentConfigValidationError\n ) {\n console.error(err.message);\n process.exit(1);\n return;\n }\n throw err;\n }\n\n const nameWidth = Math.max(\n \"Name\".length,\n ...roster.roster.map((e) => (e.name ?? e.definition).length),\n );\n const defWidth = Math.max(\n \"Role ID\".length,\n ...roster.roster.map((e) => e.definition.length),\n );\n const idWidth = Math.max(\n \"OpenClaw ID\".length,\n ...roster.roster.map((e) => e.id.length),\n );\n\n const pad = (s: string, n: number) => s.padEnd(n);\n\n console.log(\n `\\n Profile: ${roster.agent_profile} | Naming: ${roster.naming_strategy} | Agents: ${roster.roster.length}\\n`,\n );\n console.log(\n ` ${pad(\"Name\", nameWidth)} ${pad(\"Role ID\", defWidth)} ${pad(\"OpenClaw ID\", idWidth)}`,\n );\n console.log(\n ` ${\"-\".repeat(nameWidth)} ${\"-\".repeat(defWidth)} ${\"-\".repeat(idWidth)}`,\n );\n for (const entry of roster.roster) {\n console.log(\n ` ${pad(entry.name ?? \"(unnamed)\", nameWidth)} ${pad(entry.definition, defWidth)} ${pad(entry.id, idWidth)}`,\n );\n }\n console.log();\n}\n","/**\n * Canonical agent role definitions.\n * Each entry maps to a YAML template file at src/assets/agents/{id}.yaml.\n * These are the 12 standard roles that ship with Arcane.\n */\n\nimport type { AgentCategory } from \"../types.js\";\n\nexport interface AgentRoleConfig {\n id: string;\n role: string;\n category: AgentCategory;\n}\n\nexport const AGENT_ROLES: AgentRoleConfig[] = [\n {\n id: \"orchestrator\",\n role: \"Product Operations Manager\",\n category: \"operations\",\n },\n {\n id: \"architecture-lead\",\n role: \"CTO / Architecture Lead\",\n category: \"engineering\",\n },\n {\n id: \"fullstack-dev\",\n role: \"Full-Stack Developer\",\n category: \"engineering\",\n },\n {\n id: \"qa-lead\",\n role: \"QA Lead\",\n category: \"quality\",\n },\n {\n id: \"devops\",\n role: \"DevOps / CI/CD Engineer\",\n category: \"engineering\",\n },\n {\n id: \"frontend-dev\",\n role: \"Frontend Developer\",\n category: \"engineering\",\n },\n {\n id: \"mobile-dev\",\n role: \"Mobile Developer\",\n category: \"engineering\",\n },\n {\n id: \"research-analyst\",\n role: \"Research & Backlog Analyst\",\n category: \"research\",\n },\n {\n id: \"marketing-strategist\",\n role: \"Marketing Strategist\",\n category: \"operations\",\n },\n {\n id: \"operations-comms\",\n role: \"Operations Communications\",\n category: \"operations\",\n },\n {\n id: \"collaborator\",\n role: \"External Collaboration Lead\",\n category: \"operations\",\n },\n {\n id: \"security-ops\",\n role: \"Security Operations\",\n category: \"quality\",\n },\n];\n\n/** Lookup by role ID. */\nexport function getAgentRole(id: string): AgentRoleConfig | undefined {\n return AGENT_ROLES.find((r) => r.id === id);\n}\n","/**\n * Agent profile configurations.\n * Controls which roles are included when running `spell agents init`.\n * Separate from src/config/profiles.ts (which governs governance/prompts components).\n */\n\nimport type { AgentProfileId } from \"../types.js\";\n\nexport interface AgentProfileConfig {\n id: AgentProfileId;\n displayName: string;\n description: string;\n /** Role IDs included in this profile. Empty means user selects interactively. */\n roles: string[];\n}\n\nexport const AGENT_PROFILE_CONFIGS: AgentProfileConfig[] = [\n {\n id: \"base\",\n displayName: \"Base\",\n description: \"Core team: orchestrator, architecture-lead, fullstack-dev, qa-lead\",\n roles: [\"orchestrator\", \"architecture-lead\", \"fullstack-dev\", \"qa-lead\"],\n },\n {\n id: \"full\",\n displayName: \"Full\",\n description: \"Complete roster — all 12 roles\",\n roles: [\n \"orchestrator\",\n \"architecture-lead\",\n \"fullstack-dev\",\n \"qa-lead\",\n \"devops\",\n \"frontend-dev\",\n \"mobile-dev\",\n \"research-analyst\",\n \"marketing-strategist\",\n \"operations-comms\",\n \"collaborator\",\n \"security-ops\",\n ],\n },\n {\n id: \"custom\",\n displayName: \"Custom\",\n description: \"Select roles interactively\",\n roles: [], // populated at runtime via checkbox prompt\n },\n];\n\n/** Lookup by profile ID. */\nexport function getAgentProfileConfig(id: AgentProfileId): AgentProfileConfig {\n const config = AGENT_PROFILE_CONFIGS.find((p) => p.id === id);\n if (!config) throw new Error(`Unknown agent profile: \"${id}\"`);\n return config;\n}\n","/**\n * Naming strategy logic for agent roster setup.\n *\n * Four strategies:\n * arcanos — the built-in persona roster (default): twelve legendary agents\n * generic — maps each role to a short, memorable generic label\n * random — assigns random common names from a curated pool\n * custom — prompts the user to type a name for each role\n */\n\nimport { input } from \"@inquirer/prompts\";\nimport type { NamingStrategy } from \"../types.js\";\nimport { getAgentRole } from \"../config/agent-roles.js\";\n\n// ─── Generic names ────────────────────────────────────────────────────────────\n\n/** Short, role-derived display names for the generic strategy. */\nconst GENERIC_NAME_MAP: Record<string, string> = {\n \"orchestrator\": \"Orchestrator\",\n \"architecture-lead\": \"Architect\",\n \"fullstack-dev\": \"Developer\",\n \"qa-lead\": \"QA Lead\",\n \"devops\": \"DevOps\",\n \"frontend-dev\": \"Frontend\",\n \"mobile-dev\": \"Mobile\",\n \"research-analyst\": \"Researcher\",\n \"marketing-strategist\": \"Marketer\",\n \"operations-comms\": \"Comms\",\n \"collaborator\": \"Collaborator\",\n \"security-ops\": \"Security\",\n};\n\n// ─── Arcanos preset names ─────────────────────────────────────────────────────\n\n/** Persona names from the Arcanos roster — twelve legendary agents. */\nconst ARCANOS_NAME_MAP: Record<string, string> = {\n \"orchestrator\": \"Kellar\",\n \"architecture-lead\": \"Merlin\",\n \"fullstack-dev\": \"Lafayette\",\n \"qa-lead\": \"Lince\",\n \"devops\": \"Prospero\",\n \"frontend-dev\": \"Adelaide\",\n \"mobile-dev\": \"Mercurio\",\n \"research-analyst\": \"Alexander\",\n \"marketing-strategist\": \"Circe\",\n \"operations-comms\": \"Bess\",\n \"collaborator\": \"Iris\",\n \"security-ops\": \"Custodio\",\n};\n\n// ─── Random name pool ─────────────────────────────────────────────────────────\n\n/**\n * Curated pool of common single-word names.\n * Gender-neutral where possible to avoid unintentional character typecasting.\n */\nconst RANDOM_NAME_POOL: string[] = [\n \"Aiden\", \"Blake\", \"Casey\", \"Dana\", \"Ellis\", \"Finley\", \"Gray\", \"Harper\",\n \"Indigo\", \"Jordan\", \"Kai\", \"Lane\", \"Morgan\", \"Nova\", \"Owen\", \"Parker\",\n \"Quinn\", \"River\", \"Sage\", \"Taylor\", \"Uma\", \"Vale\", \"Wren\", \"Xander\",\n \"Yael\", \"Zara\", \"Avery\", \"Brett\", \"Charlie\", \"Devon\",\n];\n\n// ─── Strategy implementations ────────────────────────────────────────────────\n\nexport interface NamingResult {\n definition: string;\n name: string;\n}\n\n/** Assigns short generic labels derived from each role. */\nexport function applyGenericNames(roleIds: string[]): NamingResult[] {\n return roleIds.map((id) => ({\n definition: id,\n name: GENERIC_NAME_MAP[id] ?? id,\n }));\n}\n\n/** Assigns Arcanos persona names (Kellar, Merlin, Lafayette, etc.). */\nexport function applyArcanosNames(roleIds: string[]): NamingResult[] {\n return roleIds.map((id) => ({\n definition: id,\n name: ARCANOS_NAME_MAP[id] ?? GENERIC_NAME_MAP[id] ?? id,\n }));\n}\n\n/**\n * Assigns random names from the pool, shuffled per call.\n * If more roles than pool entries, wraps around.\n */\nexport function applyRandomNames(roleIds: string[]): NamingResult[] {\n const shuffled = [...RANDOM_NAME_POOL].sort(() => Math.random() - 0.5);\n return roleIds.map((id, i) => ({\n definition: id,\n name: shuffled[i % shuffled.length]!,\n }));\n}\n\n/**\n * Prompts the user to type a name for each role interactively.\n * Defaults to the generic name to speed up entry.\n */\nexport async function promptCustomNames(roleIds: string[]): Promise<NamingResult[]> {\n const results: NamingResult[] = [];\n for (const id of roleIds) {\n const role = getAgentRole(id);\n const defaultName = GENERIC_NAME_MAP[id] ?? id;\n const name = await input({\n message: `Name for ${role?.role ?? id}:`,\n default: defaultName,\n validate: (v) =>\n v.trim().length > 0 ? true : \"Name cannot be empty\",\n });\n results.push({ definition: id, name: name.trim() });\n }\n return results;\n}\n\n/**\n * Applies the selected naming strategy to a list of role IDs.\n * Returns an array of definition→name pairs.\n */\nexport async function applyNamingStrategy(\n strategy: NamingStrategy,\n roleIds: string[],\n): Promise<NamingResult[]> {\n switch (strategy) {\n case \"arcanos\":\n return applyArcanosNames(roleIds);\n case \"generic\":\n return applyGenericNames(roleIds);\n case \"random\":\n return applyRandomNames(roleIds);\n case \"custom\":\n return promptCustomNames(roleIds);\n }\n}\n","/**\n * Agent definition and roster loader.\n *\n * Reads canonical agent YAML files from two locations:\n * - assetsDir/agents/ — bundled templates (used during init/add)\n * - targetDir/.arcane/agents/ — project's installed/customized definitions (used during sync)\n */\n\nimport { readFile, readdir, access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { parse } from \"yaml\";\nimport type { AgentDefinition, AgentRoster } from \"../types.js\";\nimport {\n AgentConfigValidationError,\n validateAgentDefinition,\n validateAgentRoster,\n} from \"./agent-schema.js\";\n\nexport { AgentConfigValidationError } from \"./agent-schema.js\";\n\n// ─── Error types ──────────────────────────────────────────────────────────────\n\nexport class AgentDefinitionNotFoundError extends Error {\n constructor(id: string, searchDir: string) {\n super(\n `Agent definition \"${id}\" not found in \"${searchDir}\". ` +\n `Check that ${id}.yaml exists or run \"spell agents add ${id}\".`,\n );\n this.name = \"AgentDefinitionNotFoundError\";\n }\n}\n\nexport class AgentRosterNotFoundError extends Error {\n constructor() {\n super(\n 'No agent roster found at .arcane/agents.yaml. ' +\n 'Run \"spell agents init\" to create one.',\n );\n this.name = \"AgentRosterNotFoundError\";\n }\n}\n\nfunction parseYaml(content: string, source: string): unknown {\n try {\n return parse(content);\n } catch (err) {\n const detail = err instanceof Error ? err.message : \"unknown YAML parse error\";\n throw new AgentConfigValidationError(source, [`malformed YAML: ${detail}`]);\n }\n}\n\n// ─── Definition loaders ───────────────────────────────────────────────────────\n\n/**\n * Loads a single agent definition from a directory.\n * Used by `spell agents sync` (reads from .arcane/agents/).\n */\nexport async function loadAgentDefinition(\n agentsDir: string,\n id: string,\n): Promise<AgentDefinition> {\n const filePath = join(agentsDir, `${id}.yaml`);\n let content: string;\n try {\n content = await readFile(filePath, \"utf8\");\n } catch {\n throw new AgentDefinitionNotFoundError(id, agentsDir);\n }\n return validateAgentDefinition(parseYaml(content, filePath), filePath);\n}\n\n/**\n * Loads all agent definition files from a directory.\n * Skips non-YAML files and the agents.yaml roster file.\n */\nexport async function loadAllAgentDefinitions(\n agentsDir: string,\n): Promise<AgentDefinition[]> {\n let entries: string[];\n try {\n entries = await readdir(agentsDir);\n } catch {\n return [];\n }\n\n const definitions: AgentDefinition[] = [];\n for (const file of entries) {\n if (!file.endsWith(\".yaml\") || file === \"agents.yaml\") continue;\n const filePath = join(agentsDir, file);\n const content = await readFile(filePath, \"utf8\");\n definitions.push(validateAgentDefinition(parseYaml(content, filePath), filePath));\n }\n return definitions;\n}\n\n// ─── Roster loaders ───────────────────────────────────────────────────────────\n\n/**\n * Loads the agent roster from .arcane/agents.yaml in the target directory.\n * Throws AgentRosterNotFoundError if not initialized.\n */\nexport async function loadRoster(targetDir: string): Promise<AgentRoster> {\n const rosterPath = join(targetDir, \".arcane\", \"agents.yaml\");\n let content: string;\n try {\n content = await readFile(rosterPath, \"utf8\");\n } catch {\n throw new AgentRosterNotFoundError();\n }\n return validateAgentRoster(parseYaml(content, rosterPath), rosterPath);\n}\n\n/**\n * Returns true if a roster file exists in the target directory.\n */\nexport async function rosterExists(targetDir: string): Promise<boolean> {\n try {\n await access(join(targetDir, \".arcane\", \"agents.yaml\"));\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Returns the path to the project's agent definitions directory.\n */\nexport function projectAgentsDir(targetDir: string): string {\n return join(targetDir, \".arcane\", \"agents\");\n}\n","import type { AgentDefinition, AgentRoster } from \"../types.js\";\n\nconst CURRENT_ROSTER_SCHEMA_VERSION = 2;\nconst POWER_LEVELS = new Set([\n \"Spectator\",\n \"Apprentice\",\n \"Wizard\",\n \"Sorcerer\",\n \"Magus\",\n \"Archmage\",\n]);\nconst AGENT_CATEGORIES = new Set([\n \"engineering\",\n \"operations\",\n \"quality\",\n \"research\",\n]);\nconst NAMING_STRATEGIES = new Set([\"arcanos\", \"generic\", \"random\", \"custom\"]);\nconst AGENT_PROFILES = new Set([\"base\", \"full\", \"custom\"]);\n\ntype RecordValue = Record<string, unknown>;\n\nexport class AgentConfigValidationError extends Error {\n constructor(source: string, issues: string[]) {\n super(`Invalid agent configuration in ${source}:\\n- ${issues.join(\"\\n- \")}`);\n this.name = \"AgentConfigValidationError\";\n }\n}\n\nfunction isRecord(value: unknown): value is RecordValue {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction requireRecord(\n value: unknown,\n path: string,\n issues: string[],\n): RecordValue | undefined {\n if (!isRecord(value)) {\n issues.push(`${path} must be an object`);\n return undefined;\n }\n return value;\n}\n\nfunction requireString(value: unknown, path: string, issues: string[]) {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n issues.push(`${path} must be a non-empty string`);\n }\n}\n\nfunction requireBoolean(value: unknown, path: string, issues: string[]) {\n if (typeof value !== \"boolean\") issues.push(`${path} must be a boolean`);\n}\n\nfunction requireStringArray(value: unknown, path: string, issues: string[]) {\n if (!Array.isArray(value) || value.some((entry) => typeof entry !== \"string\")) {\n issues.push(`${path} must be an array of strings`);\n }\n}\n\nfunction requireEnum(\n value: unknown,\n allowed: Set<string>,\n path: string,\n issues: string[],\n) {\n if (typeof value !== \"string\" || !allowed.has(value)) {\n issues.push(`${path} must be one of: ${[...allowed].join(\", \")}`);\n }\n}\n\nfunction validateOptionalClient(\n clients: RecordValue,\n key: string,\n property: string,\n expected: \"string\" | \"boolean\",\n issues: string[],\n) {\n if (clients[key] === undefined) return;\n const client = requireRecord(clients[key], `clients.${key}`, issues);\n if (!client) return;\n if (expected === \"string\") {\n requireString(client[property], `clients.${key}.${property}`, issues);\n } else {\n requireBoolean(client[property], `clients.${key}.${property}`, issues);\n }\n}\n\nexport function validateAgentDefinition(\n value: unknown,\n source: string,\n): AgentDefinition {\n const issues: string[] = [];\n const definition = requireRecord(value, \"definition\", issues);\n if (!definition) throw new AgentConfigValidationError(source, issues);\n\n requireString(definition.id, \"id\", issues);\n requireString(definition.role, \"role\", issues);\n requireEnum(definition.category, AGENT_CATEGORIES, \"category\", issues);\n\n const persona = requireRecord(definition.persona, \"persona\", issues);\n if (persona) {\n requireString(persona.description, \"persona.description\", issues);\n requireStringArray(persona.behavioral_rules, \"persona.behavioral_rules\", issues);\n for (const key of [\"personality\", \"voice\", \"visual_description\"] as const) {\n if (persona[key] !== undefined) requireString(persona[key], `persona.${key}`, issues);\n }\n if (persona.catchphrases !== undefined) {\n requireStringArray(persona.catchphrases, \"persona.catchphrases\", issues);\n }\n }\n\n const model = requireRecord(definition.model, \"model\", issues);\n if (model) {\n requireString(model.primary, \"model.primary\", issues);\n requireStringArray(model.fallback, \"model.fallback\", issues);\n }\n\n const tools = requireRecord(definition.tools, \"tools\", issues);\n if (tools) {\n requireStringArray(tools.allowed, \"tools.allowed\", issues);\n requireStringArray(tools.denied, \"tools.denied\", issues);\n }\n\n const autonomy = requireRecord(definition.autonomy, \"autonomy\", issues);\n if (autonomy) {\n requireEnum(\n autonomy.default_power_level,\n POWER_LEVELS,\n \"autonomy.default_power_level\",\n issues,\n );\n requireBoolean(autonomy.exec_allowed, \"autonomy.exec_allowed\", issues);\n }\n\n const spawn = requireRecord(definition.spawn, \"spawn\", issues);\n if (spawn) {\n requireBoolean(spawn.can_spawn, \"spawn.can_spawn\", issues);\n requireStringArray(spawn.spawnable_by, \"spawn.spawnable_by\", issues);\n }\n\n const clients = requireRecord(definition.clients, \"clients\", issues);\n if (clients) {\n validateOptionalClient(clients, \"openclaw\", \"workspace_prefix\", \"string\", issues);\n validateOptionalClient(clients, \"copilot\", \"agent_file\", \"boolean\", issues);\n validateOptionalClient(clients, \"claude\", \"include_in_instructions\", \"boolean\", issues);\n validateOptionalClient(clients, \"codex\", \"include_in_agents_md\", \"boolean\", issues);\n }\n\n if (issues.length > 0) throw new AgentConfigValidationError(source, issues);\n return definition as unknown as AgentDefinition;\n}\n\nexport function validateAgentRoster(value: unknown, source: string): AgentRoster {\n const issues: string[] = [];\n const parsed = requireRecord(value, \"roster\", issues);\n if (!parsed) throw new AgentConfigValidationError(source, issues);\n\n const version = parsed.schema_version;\n if (!Number.isInteger(version)) {\n throw new AgentConfigValidationError(source, [\n \"schema_version must be an integer; run \\\"spell agents init\\\" with a compatible Arcane CLI\",\n ]);\n }\n if ((version as number) > CURRENT_ROSTER_SCHEMA_VERSION) {\n throw new AgentConfigValidationError(source, [\n `schema_version ${version} is newer than supported version ${CURRENT_ROSTER_SCHEMA_VERSION}; upgrade Arcane before reading this roster`,\n ]);\n }\n if ((version as number) < 1) {\n throw new AgentConfigValidationError(source, [\n `schema_version ${version} is unsupported; supported versions are 1 and ${CURRENT_ROSTER_SCHEMA_VERSION}`,\n ]);\n }\n\n const roster = version === 1\n ? { ...parsed, schema_version: CURRENT_ROSTER_SCHEMA_VERSION }\n : parsed;\n requireEnum(roster.naming_strategy, NAMING_STRATEGIES, \"naming_strategy\", issues);\n requireEnum(roster.agent_profile, AGENT_PROFILES, \"agent_profile\", issues);\n\n const openclaw = requireRecord(roster.openclaw, \"openclaw\", issues);\n if (openclaw) {\n requireBoolean(openclaw.enabled, \"openclaw.enabled\", issues);\n requireString(openclaw.workspace_root, \"openclaw.workspace_root\", issues);\n }\n\n if (!Array.isArray(roster.roster)) {\n issues.push(\"roster must be an array\");\n } else {\n roster.roster.forEach((entry, index) => {\n const item = requireRecord(entry, `roster[${index}]`, issues);\n if (!item) return;\n requireString(item.definition, `roster[${index}].definition`, issues);\n if (item.name !== null) requireString(item.name, `roster[${index}].name`, issues);\n requireString(item.id, `roster[${index}].id`, issues);\n });\n }\n\n if (issues.length > 0) throw new AgentConfigValidationError(source, issues);\n return roster as unknown as AgentRoster;\n}","/**\n * Agent generator — multi-client fan-out engine.\n *\n * Reads canonical agent definitions and an agent roster, then generates\n * client-specific instruction files for each enabled AI client:\n * - OpenClaw: IDENTITY.md, SOUL.md, TOOLS.md per agent workspace\n * - Copilot: .github/agents/{name}.agent.md per agent\n * - Claude: CLAUDE.md ← arcane marker merge\n * - Codex: AGENTS.md ← arcane marker merge\n *\n * Generated outputs also merge an agent roster table into\n * .github/copilot-instructions.md (shared with Copilot merge).\n *\n * NOTE: openclaw.json is NEVER modified directly — a patch file is generated\n * at .arcane/generated/openclaw-roster.json for the user to apply manually.\n */\n\nimport { writeFile, mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type {\n AgentDefinition,\n AgentRoster,\n AgentRosterEntry,\n AgentSyncOptions,\n} from \"../types.js\";\nimport { mergeIntoFile } from \"./merger.js\";\nimport { loadAgentDefinition, projectAgentsDir } from \"./agent-loader.js\";\n\n// ─── Resolved entry (definition + roster entry joined) ───────────────────────\n\ninterface ResolvedEntry {\n entry: AgentRosterEntry;\n def: AgentDefinition;\n displayName: string;\n}\n\n// ─── Content renderers ───────────────────────────────────────────────────────\n\nfunction renderIdentity(def: AgentDefinition, name: string): string {\n const mottosLine =\n def.persona.catchphrases && def.persona.catchphrases.length > 0\n ? `\\n## Mottos\\n\\n${def.persona.catchphrases.map((c) => `- \"${c}\"`).join(\"\\n\")}\\n`\n : \"\";\n return `# ${name} — ${def.role}\n\n## Role\n\n${def.persona.description.trim()}\n\n## Category\n\n${def.category}\n${mottosLine}`;\n}\n\nfunction renderSoul(def: AgentDefinition, name: string): string {\n const rules = def.persona.behavioral_rules.map((r) => `- ${r}`).join(\"\\n\");\n return `# ${name} — Behavioral Directives\n\n## Rules\n\n${rules}\n\n## Autonomy\n\n- **Default Power Level:** ${def.autonomy.default_power_level}\n- **Exec Allowed:** ${def.autonomy.exec_allowed ? \"Yes\" : \"No\"}\n`;\n}\n\nfunction renderTools(def: AgentDefinition, name: string): string {\n const allowed = def.tools.allowed.map((t) => `- \\`${t}\\``).join(\"\\n\");\n const denied = def.tools.denied.map((t) => `- \\`${t}\\``).join(\"\\n\");\n return `# ${name} — Tool Capabilities\n\n## Allowed\n\n${allowed}\n\n## Denied\n\n${denied}\n`;\n}\n\nfunction renderCopilotAgent(def: AgentDefinition, name: string): string {\n const firstLine = def.persona.description.split(\"\\n\")[0]?.trim() ?? def.role;\n const rules = def.persona.behavioral_rules.map((r) => `- ${r}`).join(\"\\n\");\n const personalityBlock = def.persona.personality\n ? `\\n## Personality\\n\\n${def.persona.personality.trim()}\\n`\n : \"\";\n const voiceBlock = def.persona.voice\n ? `\\n## Voice\\n\\n${def.persona.voice.trim()}\\n`\n : \"\";\n const mottosBlock =\n def.persona.catchphrases && def.persona.catchphrases.length > 0\n ? `\\n## Mottos\\n\\n${def.persona.catchphrases.map((c) => `- \"${c}\"`).join(\"\\n\")}\\n`\n : \"\";\n return `---\nname: ${name}\ndescription: ${def.role} — ${firstLine}\n---\n${mottosBlock}\n## Role\n\n${def.persona.description.trim()}\n${personalityBlock}${voiceBlock}\n## Behavioral Rules\n\n${rules}\n\n## Tools\n\n**Allowed:** ${def.tools.allowed.join(\", \")}\n**Denied:** ${def.tools.denied.join(\", \")}\n`;\n}\n\nfunction renderAgentRosterSection(entries: ResolvedEntry[]): string {\n const rows = entries\n .map(({ def, displayName }) =>\n `| **${displayName}** | ${def.role} | ${def.category} |`,\n )\n .join(\"\\n\");\n\n return `## Agent Roster\n\n| Agent | Role | Category |\n|-------|------|----------|\n${rows}\n`;\n}\n\n// ─── Sync result ─────────────────────────────────────────────────────────────\n\nexport interface SyncResult {\n synced: string[];\n skipped: string[];\n}\n\n// ─── Main sync function ───────────────────────────────────────────────────────\n\n/**\n * Generates all client-specific output files from the agent roster and definitions.\n *\n * @param targetDir Root of the consuming repo (where .arcane/ lives)\n * @param assetsDir Path to bundled assets (used as fallback for definitions not yet in project)\n * @param roster Parsed agent roster (from .arcane/agents.yaml)\n * @param options Sync options (dry-run, client filters)\n */\nexport async function syncAgents(\n targetDir: string,\n assetsDir: string,\n roster: AgentRoster,\n options: AgentSyncOptions = {},\n): Promise<SyncResult> {\n const synced: string[] = [];\n const skipped: string[] = [];\n\n // ── Load all definitions ──────────────────────────────────────────────────\n const projectDefs = projectAgentsDir(targetDir);\n const bundledDefs = join(assetsDir, \"agents\");\n\n const resolved: ResolvedEntry[] = [];\n for (const entry of roster.roster) {\n let def: AgentDefinition;\n try {\n // Prefer the project's customized version\n def = await loadAgentDefinition(projectDefs, entry.definition);\n } catch {\n try {\n // Fall back to bundled template\n def = await loadAgentDefinition(bundledDefs, entry.definition);\n } catch {\n skipped.push(`${entry.definition} (definition not found)`);\n continue;\n }\n }\n resolved.push({\n entry,\n def,\n displayName: entry.name ?? entry.definition,\n });\n }\n\n // ── OpenClaw output ──────────────────────────────────────────────────────\n if (roster.openclaw.enabled && options.openclaw !== false) {\n const openclawRoot = roster.openclaw.workspace_root.replace(\n /^~/,\n homedir(),\n );\n\n for (const { entry, def, displayName } of resolved) {\n if (!def.clients.openclaw) continue;\n\n const workspaceName =\n entry.id === \"main\" ? \"workspace\" : `workspace-${entry.id}`;\n const workspaceDir = join(openclawRoot, workspaceName);\n\n try {\n if (!options.dryRun) {\n await mkdir(workspaceDir, { recursive: true });\n await writeFile(\n join(workspaceDir, \"IDENTITY.md\"),\n renderIdentity(def, displayName),\n \"utf8\",\n );\n await writeFile(\n join(workspaceDir, \"SOUL.md\"),\n renderSoul(def, displayName),\n \"utf8\",\n );\n await writeFile(\n join(workspaceDir, \"TOOLS.md\"),\n renderTools(def, displayName),\n \"utf8\",\n );\n } else {\n console.log(` [dry-run] Would write: ${workspaceDir}/IDENTITY.md`);\n console.log(` [dry-run] Would write: ${workspaceDir}/SOUL.md`);\n console.log(` [dry-run] Would write: ${workspaceDir}/TOOLS.md`);\n }\n synced.push(`openclaw:${entry.id}:IDENTITY+SOUL+TOOLS`);\n } catch {\n skipped.push(`openclaw:${entry.id} (workspace not accessible)`);\n }\n }\n\n // Generate openclaw-roster.json patch — never modifies openclaw.json directly\n const patch = {\n $comment:\n \"Apply this to your openclaw.json agents section. \" +\n \"Do not edit manually — regenerated by `spell agents sync`.\",\n agents: resolved.map(({ entry, def }) => ({\n id: entry.id,\n identity: {\n name: entry.name ?? entry.definition,\n role: def.role,\n },\n })),\n };\n\n const generatedDir = join(targetDir, \".arcane\", \"generated\");\n if (!options.dryRun) {\n await mkdir(generatedDir, { recursive: true });\n await writeFile(\n join(generatedDir, \"openclaw-roster.json\"),\n JSON.stringify(patch, null, 2) + \"\\n\",\n \"utf8\",\n );\n } else {\n console.log(\n \" [dry-run] Would write: .arcane/generated/openclaw-roster.json\",\n );\n }\n synced.push(\"openclaw-roster.json\");\n }\n\n // ── Copilot output ───────────────────────────────────────────────────────\n if (options.copilot !== false) {\n const agentsDir = join(targetDir, \".github\", \"agents\");\n\n if (!options.dryRun) {\n await mkdir(agentsDir, { recursive: true });\n }\n\n for (const { def, displayName } of resolved) {\n if (!def.clients.copilot?.agent_file) continue;\n // Slugify: lowercase, spaces → hyphens (e.g. \"QA Lead\" → \"qa-lead.agent.md\")\n const slug = displayName.toLowerCase().replace(/\\s+/g, \"-\");\n const fileName = `${slug}.agent.md`;\n if (!options.dryRun) {\n await writeFile(\n join(agentsDir, fileName),\n renderCopilotAgent(def, displayName),\n \"utf8\",\n );\n } else {\n console.log(` [dry-run] Would write: .github/agents/${fileName}`);\n }\n synced.push(`.github/agents/${fileName}`);\n }\n\n // Merge roster into copilot-instructions.md\n const rosterSection = renderAgentRosterSection(resolved);\n const copilotMerged = await mergeIntoFile(\n targetDir,\n \".github/copilot-instructions.md\",\n rosterSection,\n { force: true, dryRun: options.dryRun },\n );\n if (copilotMerged)\n synced.push(\".github/copilot-instructions.md (agents section)\");\n }\n\n // ── Claude output ────────────────────────────────────────────────────────\n if (options.claude !== false) {\n const rosterSection = renderAgentRosterSection(resolved);\n const claudeMerged = await mergeIntoFile(\n targetDir,\n \"CLAUDE.md\",\n rosterSection,\n { force: true, dryRun: options.dryRun },\n );\n if (claudeMerged) synced.push(\"CLAUDE.md (agents section)\");\n }\n\n // ── Codex output ─────────────────────────────────────────────────────────\n if (options.codex !== false) {\n const rosterSection = renderAgentRosterSection(resolved);\n const codexMerged = await mergeIntoFile(\n targetDir,\n \"AGENTS.md\",\n rosterSection,\n { force: true, dryRun: options.dryRun },\n );\n if (codexMerged) synced.push(\"AGENTS.md (agents section)\");\n }\n\n return { synced, skipped };\n}\n","import { readFile, writeFile, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { validateTargetPath } from \"./copier.js\";\n\nexport const MARKER_START = \"<!-- arcane:start -->\";\nexport const MARKER_END = \"<!-- arcane:end -->\";\n\nexport class MalformedMarkersError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"MalformedMarkersError\";\n }\n}\n\n/**\n * Merges `content` into `targetDir/relativePath` using arcane marker comments.\n *\n * Behaviour:\n * - If both markers exist: replaces everything between them with `content`.\n * - If neither marker exists and `force` is true: appends markers + content.\n * - If neither marker exists and `force` is false: no-op, returns false.\n * - If only one marker is present: throws MalformedMarkersError.\n * - If file doesn't exist and `force` is true: creates the file with markers.\n * - If file doesn't exist and `force` is false: no-op, returns false.\n *\n * @returns true if the file was modified (or would be on dry-run), false if untouched.\n */\nexport async function mergeIntoFile(\n targetDir: string,\n relativePath: string,\n content: string,\n opts: { force?: boolean; dryRun?: boolean } = {},\n): Promise<boolean> {\n validateTargetPath(targetDir, relativePath);\n\n const destPath = path.resolve(targetDir, relativePath);\n\n let existing: string | null;\n try {\n existing = await readFile(destPath, \"utf8\");\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOENT\") {\n existing = null;\n } else {\n throw err;\n }\n }\n\n if (existing === null) {\n // File doesn't exist — create with markers only if --force\n if (!opts.force) return false;\n const newContent = `${MARKER_START}\\n${content}\\n${MARKER_END}\\n`;\n if (!opts.dryRun) {\n await writeFile(destPath, newContent, \"utf8\");\n }\n return true;\n }\n\n const startIdx = existing.indexOf(MARKER_START);\n const endIdx = existing.indexOf(MARKER_END);\n\n const hasStart = startIdx !== -1;\n const hasEnd = endIdx !== -1;\n\n if (hasStart !== hasEnd) {\n throw new MalformedMarkersError(\n `File \"${relativePath}\" has mismatched arcane markers: ` +\n `${hasStart ? \"start found\" : \"start missing\"}, ` +\n `${hasEnd ? \"end found\" : \"end missing\"}.`,\n );\n }\n\n if (hasStart && hasEnd) {\n if (startIdx > endIdx) {\n throw new MalformedMarkersError(\n `File \"${relativePath}\" has arcane markers in wrong order (end before start).`,\n );\n }\n // Replace content between the markers (keeps marker lines themselves intact)\n const beforeMarker = existing.slice(0, startIdx + MARKER_START.length);\n const afterMarker = existing.slice(endIdx);\n const updated = `${beforeMarker}\\n${content}\\n${afterMarker}`;\n if (!opts.dryRun) {\n await writeFile(destPath, updated, \"utf8\");\n }\n return true;\n }\n\n // No markers — append only if --force\n if (!opts.force) return false;\n\n const appended =\n `${existing}${existing.endsWith(\"\\n\") ? \"\" : \"\\n\"}` +\n `${MARKER_START}\\n${content}\\n${MARKER_END}\\n`;\n if (!opts.dryRun) {\n await writeFile(destPath, appended, \"utf8\");\n }\n return true;\n}\n\n/**\n * Removes the `<!-- arcane:start -->…<!-- arcane:end -->` block from a file.\n *\n * - If the file has no markers, returns false (no-op).\n * - If the file is empty (or whitespace-only) after stripping, deletes the file.\n * - Otherwise rewrites the file without the marker block.\n *\n * @returns true if the file was modified or deleted, false if untouched.\n */\nexport async function stripMarkerSection(\n targetDir: string,\n relativePath: string,\n opts: { dryRun?: boolean } = {},\n): Promise<boolean> {\n const destPath = path.resolve(targetDir, relativePath);\n\n let existing: string;\n try {\n existing = await readFile(destPath, \"utf8\");\n } catch {\n return false; // file doesn't exist\n }\n\n const startIdx = existing.indexOf(MARKER_START);\n const endIdx = existing.indexOf(MARKER_END);\n if (startIdx === -1 || endIdx === -1) return false;\n\n const before = existing.slice(0, startIdx);\n const after = existing.slice(endIdx + MARKER_END.length);\n const stripped = (before + after).replace(/\\n{3,}/g, \"\\n\\n\").trim();\n\n if (!opts.dryRun) {\n if (stripped.length === 0) {\n await rm(destPath, { force: true });\n } else {\n await writeFile(destPath, stripped + \"\\n\", \"utf8\");\n }\n }\n return true;\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nexport type GitRepositoryState =\n | { status: \"ready\"; uncommittedChanges: number }\n | { status: \"not-repository\" }\n | { status: \"no-commits\" };\n\n/**\n * Returns the repository state required before a destructive managed update.\n */\nexport async function inspectGitRepository(cwd: string): Promise<GitRepositoryState> {\n try {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"rev-parse\", \"--is-inside-work-tree\"],\n { cwd },\n );\n if (stdout.trim() !== \"true\") {\n return { status: \"not-repository\" };\n }\n } catch {\n return { status: \"not-repository\" };\n }\n\n try {\n await execFileAsync(\"git\", [\"rev-parse\", \"--verify\", \"HEAD\"], { cwd });\n } catch {\n return { status: \"no-commits\" };\n }\n\n const { stdout } = await execFileAsync(\n \"git\",\n [\"status\", \"--porcelain\", \"-uall\"],\n { cwd },\n );\n const lines = stdout.trim();\n return {\n status: \"ready\",\n uncommittedChanges: lines.length === 0 ? 0 : lines.split(\"\\n\").length,\n };\n}\n\n/**\n * Returns the number of uncommitted changes in the working tree, or 0\n * if the directory is not a git repo or git is not installed.\n */\nexport async function countUncommittedChanges(cwd: string): Promise<number> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"status\", \"--porcelain\", \"-uall\"], { cwd });\n const lines = stdout.trim();\n return lines.length === 0 ? 0 : lines.split(\"\\n\").length;\n } catch {\n return 0;\n }\n}\n","import { join } from \"node:path\";\nimport { copyFile, copyDirectory } from \"../modules/copier.js\";\nimport {\n readManifest,\n writeManifest,\n addComponent,\n hasComponent,\n ManifestNotFoundError,\n} from \"../modules/manifest.js\";\nimport { getComponent, ComponentNotFoundError } from \"../modules/registry.js\";\nimport type { InstalledComponent, SpellAddOptions } from \"../types.js\";\n\n/**\n * Runs the `spell add <component>` command.\n *\n * @param name Component name to install\n * @param options CLI flags (force, dryRun)\n * @param targetDir Directory containing the Arcane installation\n * @param assetsDir Path to the bundled assets root\n * @param packageVersion Current package version string\n */\nexport async function runAdd(\n name: string,\n options: SpellAddOptions,\n targetDir: string,\n assetsDir: string,\n packageVersion: string,\n): Promise<void> {\n // Read existing manifest (must be initialized first)\n let manifest;\n try {\n manifest = await readManifest(targetDir);\n } catch (err) {\n if (err instanceof ManifestNotFoundError) {\n console.error(\n 'Not initialized. Run \"spell init\" first before adding components.',\n );\n process.exit(1);\n return; // guard: process.exit is mocked in tests\n }\n throw err;\n }\n\n // Look up the component in the registry\n let component;\n try {\n component = getComponent(name);\n } catch (err) {\n if (err instanceof ComponentNotFoundError) {\n console.error(err.message);\n process.exit(1);\n return; // guard: process.exit is mocked in tests\n }\n throw err;\n }\n\n // Check if already installed\n if (hasComponent(manifest, name)) {\n console.log(\n `Component \"${name}\" is already installed. Use \"spell update\" to update it.`,\n );\n return;\n }\n\n // Copy files and directories\n let fileCount = 0;\n const installedFiles: string[] = [];\n for (const file of component.files) {\n const srcPath = join(assetsDir, file);\n if (options.dryRun) {\n console.log(` [dry-run] Would copy: ${file}`);\n } else {\n await copyFile(srcPath, targetDir, file, { force: options.force });\n }\n installedFiles.push(file);\n fileCount++;\n }\n for (const dir of component.directories ?? []) {\n const srcDirPath = join(assetsDir, dir);\n if (options.dryRun) {\n console.log(` [dry-run] Would copy directory: ${dir}/`);\n } else {\n const copied = await copyDirectory(srcDirPath, targetDir, dir, { force: options.force });\n installedFiles.push(...copied);\n fileCount += copied.length;\n }\n }\n\n if (options.dryRun) {\n console.log(\n `\\n[dry-run] Would add component \"${name}\" \\u2014 ${fileCount} files`,\n );\n return;\n }\n\n // Update manifest\n const newComponent: InstalledComponent = {\n name,\n files: installedFiles,\n installedVersion: packageVersion,\n };\n const updated = addComponent(manifest, newComponent);\n await writeManifest(targetDir, updated);\n\n console.log(\n `\\n\\u2713 Added component \"${name}\" \\u2014 ${fileCount} files copied`,\n );\n}\n","import { join } from \"node:path\";\nimport { copyFile, copyDirectory, fileExists } from \"../modules/copier.js\";\nimport {\n readManifest,\n writeManifest,\n ManifestNotFoundError,\n} from \"../modules/manifest.js\";\nimport { inspectGitRepository } from \"../modules/git.js\";\nimport { getComponent, ComponentNotFoundError } from \"../modules/registry.js\";\nimport { MANIFEST_RETROFITS, runManifestRetrofits, offerRegistryScaffold } from \"../modules/hub.js\";\nimport type { ArcaneManifest, InstalledComponent, SpellUpdateOptions } from \"../types.js\";\n\n/**\n * Runs the `spell update` command.\n *\n * For each installed component, looks up the current registry definition and\n * re-copies files from the current package assets. User-owned files in a\n * skipExisting component are preserved when present and backfilled when absent.\n * The manifest is updated with the new file paths so future updates remain\n * correct even when source paths change between versions.\n *\n * @param options CLI flags (dryRun)\n * @param targetDir Directory containing the Arcane installation\n * @param assetsDir Path to the bundled assets root\n * @param packageVersion Current package version string\n */\nexport async function runUpdate(\n options: SpellUpdateOptions,\n targetDir: string,\n assetsDir: string,\n packageVersion: string,\n): Promise<void> {\n // Read existing manifest\n let manifest;\n try {\n manifest = await readManifest(targetDir);\n } catch (err) {\n if (err instanceof ManifestNotFoundError) {\n console.error(\n 'Not initialized. Run \"spell init\" first before updating.',\n );\n process.exit(1);\n return; // guard: process.exit is mocked in tests\n }\n throw err;\n }\n\n console.warn(\n `WARNING: Arcane v${packageVersion} update safety notice: commit your work before updating.`,\n );\n console.warn(\n \"Updates can replace managed files. A clean committed baseline is required for recovery.\",\n );\n\n const gitState = await inspectGitRepository(targetDir);\n if (gitState.status === \"not-repository\") {\n console.error(\n \"Update refused: this directory is not a Git repository or Git is unavailable.\",\n );\n process.exit(1);\n return;\n }\n if (gitState.status === \"no-commits\") {\n console.error(\n \"Update refused: this repository has no commits. Commit the current baseline before updating.\",\n );\n process.exit(1);\n return;\n }\n if (gitState.uncommittedChanges > 0) {\n console.error(\n `Update refused: this repository has ${gitState.uncommittedChanges} uncommitted change${gitState.uncommittedChanges === 1 ? \"\" : \"s\"}. Commit or otherwise clean the working tree before updating.`,\n );\n process.exit(1);\n return;\n }\n\n // Already up to date\n if (manifest.version === packageVersion && manifest.components.length > 0) {\n console.log(\"Already up to date.\");\n return;\n }\n\n if (manifest.components.length === 0) {\n console.log(\"No components installed. Nothing to update.\");\n return;\n }\n\n let fileCount = 0;\n const updatedComponents: InstalledComponent[] = [];\n\n for (const installed of manifest.components) {\n // Look up the current registry definition (source of truth for file paths)\n let component;\n try {\n component = getComponent(installed.name);\n } catch (err) {\n if (err instanceof ComponentNotFoundError) {\n // Component removed from registry — skip but preserve manifest entry\n console.log(` ! ${installed.name} not in registry — skipping.`);\n updatedComponents.push(installed);\n continue;\n }\n throw err;\n }\n\n // Copy files using current registry paths (handles path changes between versions)\n const updatedFiles: string[] = [];\n for (const file of component.files) {\n const srcPath = join(assetsDir, file);\n const preserveExisting = component.skipExisting\n && await fileExists(join(targetDir, file));\n if (preserveExisting) {\n console.log(` ${options.dryRun ? \"[dry-run] Would preserve\" : \"Preserved\"}: ${file}`);\n } else if (options.dryRun) {\n console.log(` [dry-run] Would update: ${file}`);\n fileCount++;\n } else {\n await copyFile(srcPath, targetDir, file, { force: true });\n fileCount++;\n }\n updatedFiles.push(file);\n }\n // Also copy directories\n for (const dir of component.directories ?? []) {\n const srcDirPath = join(assetsDir, dir);\n if (options.dryRun) {\n console.log(` [dry-run] Would update directory: ${dir}/`);\n } else {\n const copied = await copyDirectory(srcDirPath, targetDir, dir, { force: true });\n updatedFiles.push(...copied);\n fileCount += copied.length;\n }\n }\n\n updatedComponents.push({\n ...installed,\n files: updatedFiles,\n installedVersion: packageVersion,\n });\n }\n\n if (options.dryRun) {\n console.log(\n `\\n[dry-run] Would update ${fileCount} files.`,\n );\n const applicableRetrofits = MANIFEST_RETROFITS.filter((r) => r.needsRetrofit(manifest));\n if (applicableRetrofits.length > 0) {\n console.log(\n `[dry-run] Would ask ${applicableRetrofits.length} manifest retrofit question${applicableRetrofits.length === 1 ? \"\" : \"s\"}: ${applicableRetrofits.map((r) => r.field).join(\", \")}.`,\n );\n }\n return;\n }\n\n // Retrofit wizard: ask about any manifest field this install predates\n // (e.g. `role`), once, before writing the updated manifest.\n const retrofitPatch = await runManifestRetrofits(manifest);\n\n // Update manifest with new version, refreshed component file paths, and\n // any retrofit answers.\n const updated: ArcaneManifest = {\n ...manifest,\n version: packageVersion,\n components: updatedComponents,\n ...retrofitPatch,\n };\n await writeManifest(targetDir, updated);\n\n console.log(\n `\\n\\u2713 Updated ${fileCount} files.`,\n );\n\n // If this update just turned the repo into a hub, offer to scaffold the\n // venture registry from whatever already exists under business_root.\n if (manifest.role !== \"hub\" && updated.role === \"hub\") {\n await offerRegistryScaffold(targetDir, updated.business_root ?? \"ventures\");\n }\n}\n","import { confirm } from \"@inquirer/prompts\";\nimport { readdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { fileExists } from \"./copier.js\";\nimport type { ArcaneManifest, HubRole } from \"../types.js\";\n\n/**\n * A manifest-field retrofit: a schema question `spell update` asks exactly\n * once, for an installed manifest that predates the field. This is a general\n * migration mechanism, not a one-off for `role` -- future manifest fields\n * register a retrofit here instead of leaving older installs permanently\n * unset.\n */\nexport interface ManifestRetrofit {\n /** Field this retrofit introduces on ArcaneManifest, for logging only. */\n field: string;\n /** True if the installed manifest predates this field and should be asked. */\n needsRetrofit(manifest: ArcaneManifest): boolean;\n /** Ask the operator; return the partial patch to merge into the manifest. */\n ask(): Promise<Partial<ArcaneManifest>>;\n}\n\nexport const MANIFEST_RETROFITS: ManifestRetrofit[] = [\n {\n field: \"role\",\n needsRetrofit: (m) => m.role === undefined,\n ask: async () => {\n const isHub = await confirm({\n message:\n \"Will this repo manage other ventures as a hub? (idea books, spell-manifest promotion, venture registry)\",\n default: false,\n });\n return { role: (isHub ? \"hub\" : \"consumer\") as HubRole };\n },\n },\n];\n\n/**\n * Runs every retrofit question the installed manifest predates, in order.\n * Returns the partial patch to merge into the manifest being written.\n * Returns {} immediately (no questions, no console output) if nothing\n * applies -- callers should only invoke this outside dry-run and\n * non-interactive modes.\n */\nexport async function runManifestRetrofits(\n manifest: ArcaneManifest,\n): Promise<Partial<ArcaneManifest>> {\n const applicable = MANIFEST_RETROFITS.filter((r) => r.needsRetrofit(manifest));\n if (applicable.length === 0) return {};\n\n console.log();\n console.log(\n `This install predates ${applicable.length} manifest field${applicable.length === 1 ? \"\" : \"s\"} -- a couple of quick questions:`,\n );\n\n let patch: Partial<ArcaneManifest> = {};\n for (const retrofit of applicable) {\n const answer = await retrofit.ask();\n patch = { ...patch, ...answer };\n }\n return patch;\n}\n\n/**\n * Offers to scaffold `{business_root}/registry.json` from existing venture\n * folders, once `role` has just become \"hub\" (via init or retrofit). Never\n * overwrites an existing registry. No-ops silently (no prompt, no output) if\n * the business root doesn't exist or holds no venture folders -- a brand new\n * hub with nothing under `ventures/` yet has nothing to scaffold.\n */\nexport async function offerRegistryScaffold(\n targetDir: string,\n businessRoot: string,\n): Promise<void> {\n const registryPath = join(targetDir, businessRoot, \"registry.json\");\n if (await fileExists(registryPath)) return;\n\n const businessRootPath = join(targetDir, businessRoot);\n let ventureDirs: string[];\n try {\n const entries = await readdir(businessRootPath, { withFileTypes: true });\n ventureDirs = entries\n .filter((e) => e.isDirectory() && e.name !== \"_template\")\n .map((e) => e.name);\n } catch {\n return;\n }\n if (ventureDirs.length === 0) return;\n\n console.log();\n const scaffold = await confirm({\n message: `Found ${ventureDirs.length} folder${ventureDirs.length === 1 ? \"\" : \"s\"} under ${businessRoot}/ -- scaffold ${businessRoot}/registry.json from them?`,\n default: true,\n });\n if (!scaffold) return;\n\n const ventures: Record<string, unknown> = {};\n for (const slug of ventureDirs) {\n const include = await confirm({ message: ` Include \"${slug}\"?`, default: true });\n if (!include) continue;\n ventures[slug] = {\n name: slug,\n aliases: [],\n status: \"active\",\n visibility: \"private\",\n ownership: \"llc\",\n tracking: \"none\",\n repos: [],\n };\n }\n if (Object.keys(ventures).length === 0) {\n console.log(\" No ventures selected -- registry not created.\");\n return;\n }\n\n const registry = {\n _comment:\n \"Hub-owned venture registry. Private. Never installed or modified by spell update. \" +\n \"Seeded by the retrofit wizard -- review and enrich (aliases, ownership, tracking, \" +\n \"clones) before relying on it.\",\n updated: new Date().toISOString().slice(0, 10),\n ventures,\n };\n await writeFile(registryPath, JSON.stringify(registry, null, 2) + \"\\n\", \"utf-8\");\n console.log(\n ` ✓ Scaffolded ${businessRoot}/registry.json with ${Object.keys(ventures).length} venture(s).`,\n );\n}\n","import { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { createRequire } from \"node:module\";\nimport type { VersionCheckResult } from \"../types.js\";\n\nconst require = createRequire(import.meta.url);\n\ninterface PackageJson {\n publishConfig?: { registry?: string };\n}\n\n/** Read the feed URL from the package's own publishConfig.registry — never hardcoded. */\nexport function getFeedUrl(): string {\n const pkg = require(\"../../package.json\") as PackageJson;\n const url = pkg.publishConfig?.registry;\n if (!url) {\n throw new Error(\n \"publishConfig.registry is not set in package.json. Cannot resolve npm feed URL.\",\n );\n }\n return url;\n}\n\nconst DEFAULT_CACHE_PATH = join(homedir(), \".arcane\", \"version-cache.json\");\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours\n\ninterface CacheEntry {\n latest: string;\n checkedAt: string;\n}\n\n/**\n * Reads the version cache file. Returns null if missing or malformed.\n */\nexport async function readCache(\n cachePath: string,\n): Promise<CacheEntry | null> {\n try {\n const content = await readFile(cachePath, \"utf-8\");\n const parsed = JSON.parse(content) as CacheEntry;\n if (typeof parsed.latest !== \"string\" || typeof parsed.checkedAt !== \"string\") {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n}\n\n/**\n * Writes the version cache file, creating parent directories as needed.\n */\nexport async function writeCache(\n cachePath: string,\n latest: string,\n): Promise<void> {\n await mkdir(dirname(cachePath), { recursive: true });\n const entry: CacheEntry = { latest, checkedAt: new Date().toISOString() };\n await writeFile(cachePath, JSON.stringify(entry, null, 2), \"utf-8\");\n}\n\n/**\n * Fetches the latest published version of arcane-cli from the public npm\n * registry. Returns null (does not throw) on any network failure.\n */\nexport async function getLatestVersion(feedUrl: string): Promise<string | null> {\n const normalizedBase = feedUrl.endsWith(\"/\") ? feedUrl : feedUrl + \"/\";\n const url = `${normalizedBase}arcane-cli`;\n try {\n const response = await fetch(url, {\n headers: { Accept: \"application/json\" },\n signal: AbortSignal.timeout(5000),\n });\n if (!response.ok) return null;\n const body = await response.json() as { \"dist-tags\"?: { latest?: string } };\n return body[\"dist-tags\"]?.latest ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Checks for a newer version of the package, using a 24h file cache.\n * Never throws — errors are captured in VersionCheckResult.error.\n */\nexport async function checkForUpdate(\n currentVersion: string,\n feedUrl: string,\n cachePath: string = DEFAULT_CACHE_PATH,\n): Promise<VersionCheckResult> {\n try {\n let latest: string | null = null;\n\n const cached = await readCache(cachePath);\n if (cached) {\n const age = Date.now() - new Date(cached.checkedAt).getTime();\n if (age < CACHE_TTL_MS) {\n latest = cached.latest;\n }\n }\n\n if (latest === null) {\n latest = await getLatestVersion(feedUrl);\n if (latest !== null) {\n try {\n await writeCache(cachePath, latest);\n } catch {\n // Cache write failure is non-fatal\n }\n }\n }\n\n return {\n current: currentVersion,\n latest,\n updateAvailable: latest !== null && latest !== currentVersion,\n };\n } catch (err) {\n return {\n current: currentVersion,\n latest: null,\n updateAvailable: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n","import {\n readManifest,\n ManifestNotFoundError,\n} from \"../modules/manifest.js\";\nimport {\n checkForUpdate,\n getFeedUrl,\n} from \"../modules/version-check.js\";\n\n/**\n * Runs the `spell status` command.\n *\n * Reads .arcane.json, checks for an available update, then prints\n * a formatted table of installed components + a version footer.\n *\n * @param targetDir Directory containing the Arcane installation\n * @param packageVersion Current package version string\n */\nexport async function runStatus(\n targetDir: string,\n packageVersion: string,\n): Promise<void> {\n // Read existing manifest\n let manifest;\n try {\n manifest = await readManifest(targetDir);\n } catch (err) {\n if (err instanceof ManifestNotFoundError) {\n console.error(\n 'Not initialized. Run \"spell init\" first.',\n );\n process.exit(1);\n return; // guard: process.exit is mocked in tests\n }\n throw err;\n }\n\n if (manifest.components.length === 0) {\n console.log(\"No components installed.\");\n return;\n }\n\n // Check for update (never throws)\n let feedUrl: string;\n try {\n feedUrl = getFeedUrl();\n } catch {\n feedUrl = \"\";\n }\n\n const versionResult = feedUrl\n ? await checkForUpdate(packageVersion, feedUrl)\n : { current: packageVersion, latest: null, updateAvailable: false, error: \"Feed URL unavailable\" };\n\n // ─── Print component table ─────────────────────────────────────────────────\n\n // Compute column widths\n const nameWidth = Math.max(\n \"Component\".length,\n ...manifest.components.map((c) => c.name.length),\n );\n const filesWidth = \"Files\".length;\n const versionWidth = Math.max(\n \"Version\".length,\n ...manifest.components.map((c) => c.installedVersion.length),\n );\n\n const pad = (s: string, n: number) => s.padEnd(n);\n const rpad = (s: string, n: number) => s.padStart(n);\n\n console.log(\n ` ${pad(\"Component\", nameWidth)} ${rpad(\"Files\", filesWidth)} ${pad(\"Version\", versionWidth)}`,\n );\n console.log(\n ` ${\"-\".repeat(nameWidth)} ${\"-\".repeat(filesWidth)} ${\"-\".repeat(versionWidth)}`,\n );\n\n for (const component of manifest.components) {\n const label = component.name;\n const fileCount = component.files.length.toString();\n const displayVersion = component.installedVersion;\n console.log(\n ` ${pad(label, nameWidth)} ${rpad(fileCount, filesWidth)} ${displayVersion}`,\n );\n }\n\n // ─── Version footer ────────────────────────────────────────────────────────\n\n console.log(\"\");\n\n const latestStr = versionResult.error\n ? \"unable to check\"\n : (versionResult.latest ?? manifest.version);\n\n let footer = ` Installed: ${packageVersion} Latest: ${latestStr}`;\n\n if (versionResult.updateAvailable) {\n footer += \" (spell update available)\";\n }\n\n console.log(footer);\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { confirm } from \"@inquirer/prompts\";\nimport {\n readManifest,\n ManifestNotFoundError,\n} from \"../modules/manifest.js\";\nimport { stripMarkerSection } from \"../modules/merger.js\";\n\n/**\n * Runs the `spell uninstall` command.\n *\n * Deletes every file tracked in .arcane.json then removes .arcane.json itself.\n * Prompts for confirmation unless --yes is passed.\n *\n * @param options.yes Skip confirmation prompt\n * @param options.dryRun Preview what would be removed without deleting files\n * @param targetDir Directory containing the Arcane installation\n */\nexport async function runUninstall(\n options: { yes?: boolean; dryRun?: boolean },\n targetDir: string,\n): Promise<void> {\n // Read existing manifest\n let manifest;\n try {\n manifest = await readManifest(targetDir);\n } catch (err) {\n if (err instanceof ManifestNotFoundError) {\n console.error('Not initialized. Run \"spell init\" first.');\n process.exit(1);\n return; // guard: process.exit is mocked in tests\n }\n throw err;\n }\n\n // Count total tracked files\n const allFiles = manifest.components.flatMap((c) => c.files);\n const totalFiles = allFiles.length;\n\n // Dry-run: print what would be removed without deleting\n if (options.dryRun) {\n for (const file of allFiles) {\n console.log(`[dry-run] Would remove: ${file}`);\n }\n console.log(`[dry-run] Would remove: .arcane.json`);\n console.log(`[dry-run] Would remove: .github/agents/ (directory)`);\n console.log(`[dry-run] Would remove: .arcane/agents/ (directory)`);\n console.log(`[dry-run] Would remove: .arcane/generated/ (directory)`);\n console.log(`[dry-run] Would remove: .arcane/agents.yaml`);\n console.log(`[dry-run] Would strip arcane sections from: CLAUDE.md, AGENTS.md, copilot-instructions.md`);\n console.log(`\\n[dry-run] ${totalFiles} file(s) + manifest + agent outputs would be removed.`);\n return;\n }\n\n // Confirmation prompt (skipped with --yes)\n if (!options.yes) {\n const confirmed = await confirm({\n message: `This will remove ${totalFiles} files and .arcane.json. Continue?`,\n default: false,\n });\n\n if (!confirmed) {\n console.log(\"Uninstall cancelled.\");\n return;\n }\n }\n\n // Delete each file tracked in the manifest\n let removed = 0;\n for (const component of manifest.components) {\n for (const file of component.files) {\n const filePath = join(targetDir, file);\n try {\n await rm(filePath, { force: true });\n removed++;\n } catch {\n // Non-existent files are fine (force: true), but other errors propagate\n }\n }\n }\n\n // Delete .arcane.json\n await rm(join(targetDir, \".arcane.json\"), { force: true });\n\n // ── Clean up agent sync outputs (not tracked in manifest) ──────────────\n // Directories created by agent init/sync\n const agentDirs = [\n \".github/agents\",\n \".arcane/agents\",\n \".arcane/generated\",\n ];\n for (const dir of agentDirs) {\n await rm(join(targetDir, dir), { recursive: true, force: true });\n }\n // Roster file\n await rm(join(targetDir, \".arcane/agents.yaml\"), { force: true });\n\n // Strip arcane marker sections from merged files (keeps user content intact)\n const markerFiles = [\n \"CLAUDE.md\",\n \"AGENTS.md\",\n \".github/copilot-instructions.md\",\n ];\n for (const file of markerFiles) {\n await stripMarkerSection(targetDir, file, { dryRun: false });\n }\n\n console.log(`\\n✓ Uninstalled — ${removed} files removed.`);\n}\n","import { access, readFile, mkdir, copyFile as fsCopyFile } from \"node:fs/promises\";\nimport { join, dirname } from \"node:path\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { INCIDENT_QUEUE } from \"../config/incidents.js\";\nimport { evaluateIncidentGate } from \"../modules/incident-gate.js\";\n\nconst execFileAsync = promisify(execFile);\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\ninterface CheckResult {\n name: string;\n passed: boolean;\n message: string;\n /** If false, this is a warning, not a blocker. Defaults to true (blocking). */\n blocking?: boolean;\n}\n\n// ─── Individual checks ────────────────────────────────────────────────────────\n\nasync function checkNodeVersion(): Promise<CheckResult> {\n const name = \"Node.js version\";\n const raw = process.version; // e.g. \"v20.11.0\"\n const major = parseInt(raw.replace(/^v/, \"\").split(\".\")[0] ?? \"0\", 10);\n if (major >= 18) {\n return { name, passed: true, message: `${raw} (>=18 required)` };\n }\n return {\n name,\n passed: false,\n message: `${raw} — Node.js 18 or later is required`,\n };\n}\n\nasync function checkVSCodeExtension(\n id: string,\n label: string,\n): Promise<CheckResult> {\n const name = `VS Code extension: ${label}`;\n // Check extension directories on disk — more reliable than --list-extensions\n // in child process contexts (snap binaries may not output to non-TTY stdout).\n const home = process.env[\"HOME\"] ?? \"\";\n const extDirs = [\n join(home, \".vscode\", \"extensions\"),\n join(home, \".vscode-insiders\", \"extensions\"),\n ];\n\n for (const dir of extDirs) {\n try {\n const { readdir } = await import(\"node:fs/promises\");\n const entries = await readdir(dir);\n const prefix = id.toLowerCase() + \"-\";\n const found = entries.some(\n (e) => e.toLowerCase() === id.toLowerCase() || e.toLowerCase().startsWith(prefix),\n );\n if (found) {\n return { name, passed: true, message: `${id} is installed` };\n }\n } catch {\n // Directory doesn't exist — skip\n }\n }\n\n // Determine install command (prefer code-insiders if present)\n let installBin = \"code\";\n for (const bin of [\"code\", \"code-insiders\"]) {\n try {\n await execFileAsync(bin, [\"--version\"]);\n installBin = bin;\n break;\n } catch {\n // not found\n }\n }\n\n return {\n name,\n passed: false,\n message: `${id} not found. Install via: ${installBin} --install-extension ${id}`,\n blocking: false,\n };\n}\n\nexport async function checkArcaneManifest(targetDir: string): Promise<CheckResult> {\n const name = \"Arcane manifest (.arcane.json)\";\n const manifestPath = join(targetDir, \".arcane.json\");\n try {\n await access(manifestPath);\n } catch {\n const selfHostedManifestPath = join(targetDir, \"src\", \"assets\", \".arcane.json\");\n try {\n const raw = await readFile(selfHostedManifestPath, \"utf8\");\n const manifest = JSON.parse(raw) as {\n selfHosted?: boolean;\n tracking_mode?: string;\n };\n if (manifest.selfHosted === true && manifest.tracking_mode === \"internal\") {\n return {\n name,\n passed: true,\n message: \"self-hosted source tree — committed source manifest is authoritative\",\n };\n }\n } catch {\n // No valid self-hosting marker — report the normal missing-manifest warning.\n }\n return {\n name,\n passed: false,\n message: \"No .arcane.json found. Run `spell init` to initialize Arcane in this project.\",\n blocking: false,\n };\n }\n\n try {\n const raw = await readFile(manifestPath, \"utf8\");\n const manifest = JSON.parse(raw) as { version?: string; components?: unknown[] };\n if (!manifest.version || !Array.isArray(manifest.components)) {\n return {\n name,\n passed: false,\n message: \".arcane.json is present but missing required fields (version, components). Re-run `spell init`.\",\n };\n }\n return {\n name,\n passed: true,\n message: `v${manifest.version} — ${manifest.components.length} component(s) installed`,\n };\n } catch {\n return {\n name,\n passed: false,\n message: \".arcane.json is present but contains invalid JSON. Re-run `spell init`.\",\n };\n }\n}\n\nexport function checkIncidentReleaseGate(): CheckResult {\n const result = evaluateIncidentGate(INCIDENT_QUEUE);\n if (result.blocked) {\n return {\n name: \"Incident release gate (ARC-024)\",\n passed: false,\n message: result.blockers.join(\"; \"),\n };\n }\n const accepted = result.acceptedRisks.length > 0\n ? `; ${result.acceptedRisks.length} explicitly deferred`\n : \"\";\n return {\n name: \"Incident release gate (ARC-024)\",\n passed: true,\n message: `${result.checked} incidents classified${accepted}`,\n };\n}\n\n// ─── Session continuity checks ────────────────────────────────────────────────\n\n/** Files required for spell-close-session / spell-open-session to function. */\nexport const SESSION_CONTINUITY_FILES = [\n \"TODO.md\",\n \"DECISIONS.md\",\n \"ai-context/system-prompt-context.md\",\n \"journal/.gitkeep\",\n];\n\nexport async function checkSessionContinuity(targetDir: string): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n\n for (const file of SESSION_CONTINUITY_FILES) {\n const name = `Session file: ${file}`;\n const filePath = join(targetDir, file);\n try {\n await access(filePath);\n results.push({ name, passed: true, message: \"present\" });\n } catch {\n results.push({\n name,\n passed: false,\n message: `Missing. Required for spell-close-session. Run \\`spell doctor --fix\\` to create it.`,\n blocking: false,\n });\n }\n }\n\n return results;\n}\n\nexport async function fixSessionContinuity(targetDir: string, assetsDir: string): Promise<string[]> {\n const created: string[] = [];\n\n for (const file of SESSION_CONTINUITY_FILES) {\n const destPath = join(targetDir, file);\n try {\n await access(destPath);\n // File exists — skip\n } catch {\n // File missing — create from template\n const srcPath = join(assetsDir, file);\n await mkdir(dirname(destPath), { recursive: true });\n await fsCopyFile(srcPath, destPath);\n created.push(file);\n }\n }\n\n return created;\n}\n\n// ─── Main ─────────────────────────────────────────────────────────────────────\n\nexport interface DoctorOptions {\n fix?: boolean;\n}\n\nexport async function runDoctor(targetDir: string, options: DoctorOptions = {}, assetsDir?: string): Promise<void> {\n console.log(\"\\nspell doctor — checking your Arcane environment\\n\");\n\n const results = await Promise.all([\n checkNodeVersion(),\n checkVSCodeExtension(\"GitHub.copilot-chat\", \"GitHub Copilot (Chat)\"),\n checkArcaneManifest(targetDir),\n Promise.resolve(checkIncidentReleaseGate()),\n ]);\n\n // Add session continuity checks\n const sessionResults = await checkSessionContinuity(targetDir);\n results.push(...sessionResults);\n\n let allPassed = true;\n\n for (const result of results) {\n const icon = result.passed ? \"✓\" : result.blocking === false ? \"⚠\" : \"✗\";\n const label = result.passed\n ? \"pass\"\n : result.blocking === false\n ? \"warn\"\n : \"FAIL\";\n console.log(` ${icon} [${label}] ${result.name}`);\n if (!result.passed) {\n console.log(` ${result.message}`);\n }\n if (!result.passed && result.blocking !== false) {\n allPassed = false;\n }\n }\n\n console.log();\n\n if (allPassed) {\n console.log(\" All checks passed. Your environment is ready.\\n\");\n } else {\n console.log(\" One or more checks failed. Fix the issues above before proceeding.\\n\");\n\n // --fix: remediate missing session continuity files\n const hasMissingSession = sessionResults.some((r) => !r.passed);\n if (options.fix && hasMissingSession && assetsDir) {\n console.log(\" 🔧 Fixing missing session continuity files...\\n\");\n const created = await fixSessionContinuity(targetDir, assetsDir);\n if (created.length > 0) {\n for (const file of created) {\n console.log(` ✓ Created: ${file}`);\n }\n console.log(`\\n ${created.length} file(s) created. Repo is now close-session-ready.\\n`);\n } else {\n console.log(\" No files needed creation (all present).\\n\");\n }\n } else if (hasMissingSession && !options.fix) {\n console.log(\" 💡 Run `spell doctor --fix` to create missing session files.\\n\");\n }\n\n if (!allPassed) {\n process.exitCode = 1;\n }\n }\n}\n","export type IncidentSeverity = \"critical\" | \"high\" | \"medium\" | \"low\";\nexport type IncidentImpact = \"data-integrity\" | \"security\" | \"other\";\nexport type IncidentConfidence = \"confirmed\" | \"research\";\nexport type IncidentState = \"open\" | \"resolved\" | \"deferred\";\n\nexport interface IncidentRecord {\n id: string;\n severity?: IncidentSeverity;\n impact: IncidentImpact;\n confidence: IncidentConfidence;\n state: IncidentState;\n detectedOn: string;\n resolution?: string;\n deferral?: string;\n}\n\nexport const INCIDENT_QUEUE: IncidentRecord[] = [\n { id: \"EF-05\", severity: \"medium\", impact: \"other\", confidence: \"confirmed\", state: \"open\", detectedOn: \"2026-07-31\" },\n { id: \"EF-08\", severity: \"medium\", impact: \"other\", confidence: \"confirmed\", state: \"open\", detectedOn: \"2026-07-31\" },\n { id: \"EF-16\", severity: \"high\", impact: \"other\", confidence: \"confirmed\", state: \"open\", detectedOn: \"2026-07-31\" },\n { id: \"EF-17\", severity: \"high\", impact: \"other\", confidence: \"confirmed\", state: \"open\", detectedOn: \"2026-07-31\" },\n { id: \"EF-20\", severity: \"high\", impact: \"other\", confidence: \"research\", state: \"open\", detectedOn: \"2026-07-31\" },\n { id: \"EF-21\", severity: \"high\", impact: \"other\", confidence: \"confirmed\", state: \"open\", detectedOn: \"2026-07-31\" },\n { id: \"EF-23\", severity: \"medium\", impact: \"other\", confidence: \"confirmed\", state: \"open\", detectedOn: \"2026-07-31\" },\n { id: \"EF-25\", severity: \"high\", impact: \"data-integrity\", confidence: \"confirmed\", state: \"resolved\", detectedOn: \"2026-07-14\", resolution: \"PRs 13 and 14\" },\n { id: \"EF-26\", severity: \"high\", impact: \"security\", confidence: \"confirmed\", state: \"resolved\", detectedOn: \"2026-07-31\", resolution: \"PR 15\" },\n { id: \"EF-27\", severity: \"high\", impact: \"security\", confidence: \"confirmed\", state: \"resolved\", detectedOn: \"2026-07-31\", resolution: \"PR 16\" },\n { id: \"EF-28\", severity: \"high\", impact: \"security\", confidence: \"confirmed\", state: \"resolved\", detectedOn: \"2026-07-31\", resolution: \"PR 17\" },\n { id: \"EF-29\", severity: \"medium\", impact: \"other\", confidence: \"confirmed\", state: \"resolved\", detectedOn: \"2026-07-31\", resolution: \"PR 18\" },\n];","import type { IncidentRecord } from \"../config/incidents.js\";\n\nconst DEFERRAL_PATTERN = /^Deferred \\d{4}-\\d{2}-\\d{2} — known open, accepting the risk\\.$/;\nconst BLOCKING_SEVERITIES = new Set([\"critical\", \"high\"]);\nconst PROTECTED_IMPACTS = new Set([\"data-integrity\", \"security\"]);\n\nexport interface IncidentGateResult {\n blocked: boolean;\n blockers: string[];\n acceptedRisks: string[];\n checked: number;\n}\n\nexport function evaluateIncidentGate(records: IncidentRecord[]): IncidentGateResult {\n const blockers: string[] = [];\n const acceptedRisks: string[] = [];\n const seen = new Set<string>();\n\n for (const record of records) {\n if (seen.has(record.id)) {\n blockers.push(`${record.id}: duplicate incident record`);\n continue;\n }\n seen.add(record.id);\n\n if (record.confidence === \"research\") continue;\n if (!PROTECTED_IMPACTS.has(record.impact)) continue;\n\n if (!record.severity) {\n blockers.push(`${record.id}: confirmed ${record.impact} incident is missing severity`);\n continue;\n }\n if (!BLOCKING_SEVERITIES.has(record.severity)) continue;\n\n if (record.state === \"resolved\") {\n if (!record.resolution?.trim()) {\n blockers.push(`${record.id}: resolved incident is missing resolution evidence`);\n }\n continue;\n }\n\n if (record.state === \"deferred\") {\n if (!record.deferral || !DEFERRAL_PATTERN.test(record.deferral)) {\n blockers.push(\n `${record.id}: deferral must be exactly \"Deferred <date> — known open, accepting the risk.\"`,\n );\n } else {\n acceptedRisks.push(`${record.id}: ${record.deferral}`);\n }\n continue;\n }\n\n blockers.push(\n `${record.id}: unresolved ${record.severity} ${record.impact} incident blocks release`,\n );\n }\n\n return {\n blocked: blockers.length > 0,\n blockers,\n acceptedRisks,\n checked: records.length,\n };\n}"],"mappings":"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","names":["createRequire","dirname","join","select","join","chalk","path","manifestPath","mkdir","writeFile","copyFile","join","readFile","readdir","access","path","readFile","readFile","access","writeFile","mkdir","join","readFile","writeFile","path","path","readFile","writeFile","join","mkdir","writeFile","r","join","mkdir","writeFile","copyFile","stdout","chalk","select","join","join","join","join","confirm","readdir","writeFile","join","confirm","join","readdir","writeFile","join","readFile","writeFile","mkdir","join","homedir","require","pkg","rm","join","confirm","confirm","join","rm","access","readFile","mkdir","fsCopyFile","join","dirname","execFile","promisify","execFileAsync","promisify","execFile","join","readdir","manifestPath","access","readFile","mkdir","dirname","fsCopyFile","require","createRequire","join","dirname"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/modules/copier.ts","../src/modules/manifest.ts","../src/config/profiles.ts","../src/modules/registry.ts","../src/modules/banner.ts","../src/modules/agents.ts","../src/config/agent-roles.ts","../src/config/agent-profiles.ts","../src/modules/naming.ts","../src/modules/agent-loader.ts","../src/modules/agent-schema.ts","../src/modules/agent-generator.ts","../src/modules/merger.ts","../src/modules/git.ts","../src/commands/add.ts","../src/commands/update.ts","../src/modules/hub.ts","../src/modules/version-check.ts","../src/commands/status.ts","../src/commands/uninstall.ts","../src/commands/doctor.ts","../src/config/incidents.ts","../src/modules/incident-gate.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { createRequire } from \"node:module\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\nimport { runInit } from \"./commands/init.js\";\nimport { runAdd } from \"./commands/add.js\";\nimport { runUpdate } from \"./commands/update.js\";\nimport { runStatus } from \"./commands/status.js\";\nimport { runUninstall } from \"./commands/uninstall.js\";\nimport { runDoctor } from \"./commands/doctor.js\";\nimport { runAgentsInit, runAgentsList, runAgentsSync } from \"./modules/agents.js\";\nimport { printWelcome } from \"./modules/banner.js\";\nimport type { Profile, AgentInitOptions, AgentProfileId, NamingStrategy, AgentSyncOptions } from \"./types.js\";\n\nconst require = createRequire(import.meta.url);\nconst pkg = require(\"../package.json\") as { version: string };\n\n/**\n * Resolved path to the bundled assets directory.\n * Points to src/assets/ during tests (vitest runs source directly) and\n * dist/assets/ in the published package (tsup bundles to dist/index.js).\n * Can be overridden via ARCANE_ASSETS_DIR env var for testing the built binary.\n */\nexport const ASSETS_DIR =\n process.env[\"ARCANE_ASSETS_DIR\"] ??\n join(dirname(fileURLToPath(import.meta.url)), \"assets\");\n\nconst program = new Command();\n\nprogram\n .name(\"spell\")\n .description(\"Arcane framework CLI — scaffold and manage governance files\")\n .version(pkg.version)\n .action(async () => {\n // Bare `spell` with no subcommand — show the welcome (banner + real repo\n // state + Spell Loop), then the command reference.\n await printWelcome(pkg.version, process.cwd());\n program.outputHelp();\n });\n\nprogram\n .command(\"init\")\n .description(\"Scaffold Arcane framework files into the current repository\")\n .option(\"--profile <profile>\", \"Profile: full | lite | methodology | governance-only\")\n .option(\"--force\", \"Overwrite existing files without error\")\n .option(\"--dry-run\", \"Preview what would be installed without making changes\")\n .action(\n async (opts: { profile?: string; force?: boolean; dryRun?: boolean }) => {\n await runInit(\n {\n profile: opts.profile as Profile | undefined,\n force: opts.force,\n dryRun: opts.dryRun,\n },\n process.cwd(),\n ASSETS_DIR,\n pkg.version,\n );\n },\n );\n\nprogram\n .command(\"add <component>\")\n .description(\"Add a component to an existing Arcane installation\")\n .option(\"--force\", \"Overwrite existing files without error\")\n .option(\"--dry-run\", \"Preview what would be added without making changes\")\n .action(\n async (\n component: string,\n opts: { force?: boolean; dryRun?: boolean },\n ) => {\n await runAdd(\n component,\n { force: opts.force, dryRun: opts.dryRun },\n process.cwd(),\n ASSETS_DIR,\n pkg.version,\n );\n },\n );\n\nprogram\n .command(\"update\")\n .description(\"Update installed components to the current package version\")\n .option(\"--dry-run\", \"Preview what would be updated without making changes\")\n .action(async (opts: { dryRun?: boolean }) => {\n await runUpdate(\n { dryRun: opts.dryRun },\n process.cwd(),\n ASSETS_DIR,\n pkg.version,\n );\n });\n\nprogram\n .command(\"status\")\n .description(\"Show installed components and check for updates\")\n .action(async () => {\n await runStatus(process.cwd(), pkg.version);\n });\n\nprogram\n .command(\"uninstall\")\n .description(\"Remove all installed Arcane framework files\")\n .option(\"--yes\", \"Skip confirmation prompt\")\n .option(\"--dry-run\", \"Preview what would be removed without deleting files\")\n .action(async (opts: { yes?: boolean; dryRun?: boolean }) => {\n await runUninstall({ yes: opts.yes, dryRun: opts.dryRun }, process.cwd());\n });\n\nprogram\n .command(\"doctor\")\n .description(\"Check your environment for Arcane prerequisites\")\n .option(\"--fix\", \"Automatically create missing session continuity files\")\n .action(async (opts: { fix?: boolean }) => {\n await runDoctor(process.cwd(), { fix: opts.fix }, ASSETS_DIR);\n });\n\n// ─── spell agents ─────────────────────────────────────────────────────────────\n\nconst agentsCommand = program\n .command(\"agents\")\n .description(\"Manage the portable agent system (init, sync, list)\");\n\nagentsCommand\n .command(\"init\")\n .description(\n \"Interactive agent roster setup — choose profile, naming strategy, and install definitions\",\n )\n .option(\n \"--profile <profile>\",\n \"Agent profile: base | full | custom\",\n )\n .option(\n \"--naming <strategy>\",\n \"Naming strategy: arcanos | generic | random | custom\",\n )\n .option(\"--force\", \"Reinitialize even if roster already exists\")\n .option(\"--dry-run\", \"Preview what would be created without writing files\")\n .action(\n async (opts: {\n profile?: string;\n naming?: string;\n force?: boolean;\n dryRun?: boolean;\n }) => {\n await runAgentsInit(\n {\n profile: opts.profile as AgentProfileId | undefined,\n naming: opts.naming as NamingStrategy | undefined,\n force: opts.force,\n dryRun: opts.dryRun,\n } satisfies AgentInitOptions,\n process.cwd(),\n ASSETS_DIR,\n );\n },\n );\n\nagentsCommand\n .command(\"sync\")\n .description(\n \"Regenerate all client instruction files from canonical agent definitions\",\n )\n .option(\"--dry-run\", \"Preview what would be generated without writing files\")\n .option(\"--no-openclaw\", \"Skip OpenClaw workspace output\")\n .option(\"--no-copilot\", \"Skip Copilot output\")\n .option(\"--no-claude\", \"Skip Claude output\")\n .option(\"--no-codex\", \"Skip Codex output\")\n .action(\n async (opts: {\n dryRun?: boolean;\n openclaw?: boolean;\n copilot?: boolean;\n claude?: boolean;\n codex?: boolean;\n }) => {\n await runAgentsSync(\n {\n dryRun: opts.dryRun,\n openclaw: opts.openclaw,\n copilot: opts.copilot,\n claude: opts.claude,\n codex: opts.codex,\n } satisfies AgentSyncOptions,\n process.cwd(),\n ASSETS_DIR,\n );\n },\n );\n\nagentsCommand\n .command(\"list\")\n .description(\"Show the current agent roster with assigned names and roles\")\n .action(async () => {\n await runAgentsList(process.cwd());\n });\n\n// Only parse argv when executed directly — not when imported in tests.\n// Use realpathSync to resolve symlinks (e.g. npm global bin → dist/index.js).\nimport { realpathSync } from \"node:fs\";\nif (realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)) {\n await program.parseAsync(process.argv);\n}\n\nexport { program };\n","import { select, confirm } from \"@inquirer/prompts\";\nimport { join } from \"node:path\";\nimport chalk from \"chalk\";\nimport { copyFile, copyDirectory } from \"../modules/copier.js\";\nimport {\n readManifest,\n writeManifest,\n ManifestNotFoundError,\n} from \"../modules/manifest.js\";\nimport { getProfile, listProfiles } from \"../modules/registry.js\";\nimport {\n printDryRun,\n printStep,\n printSuccess,\n printSection,\n printInfo,\n printNextStep,\n printWarning,\n} from \"../modules/banner.js\";\nimport { runAgentsInit } from \"../modules/agents.js\";\nimport {\n correctUnbornMasterDefault,\n ensureLocalPullRebase,\n inspectGitRepository,\n} from \"../modules/git.js\";\nimport type {\n ArcaneManifest,\n HubRole,\n InstalledComponent,\n Profile,\n RegistryComponent,\n SpellInitOptions,\n} from \"../types.js\";\n\nconst VALID_PROFILES: Profile[] = [\"full\", \"lite\", \"governance-only\", \"methodology\"];\n\n// ─── Category labels for preview ─────────────────────────────────────────────\n\ninterface ComponentGroup {\n icon: string;\n label: string;\n count: number;\n}\n\nfunction categorizeComponents(components: RegistryComponent[]): ComponentGroup[] {\n const groups: ComponentGroup[] = [];\n\n const prompts = components.find((c) => c.name === \"spell-prompts\");\n if (prompts) {\n groups.push({\n icon: \"✨\",\n label: \"Copilot Spells\",\n count: prompts.files.length,\n });\n }\n\n const claude = components.find((c) => c.name === \"claude-commands\");\n if (claude) {\n groups.push({\n icon: \"⚡\",\n label: \"Claude Spells\",\n count: claude.files.length,\n });\n }\n\n const governance = components.filter(\n (c) =>\n c.name !== \"spell-prompts\" &&\n c.name !== \"claude-commands\" &&\n c.name !== \"venture-template\" &&\n c.name !== \"agent-definitions\" &&\n c.files.some((f) => f.startsWith(\".arcane/governance/\")),\n );\n if (governance.length > 0) {\n groups.push({\n icon: \"📋\",\n label: \"Governance Docs\",\n count: governance.reduce((n, c) => n + c.files.length, 0),\n });\n }\n\n const agentDef = components.find((c) => c.name === \"agent-definitions\");\n if (agentDef) {\n groups.push({\n icon: \"🛡️\",\n label: \"Agent Policies\",\n count: agentDef.files.length,\n });\n }\n\n const templates = components.find((c) => c.name === \"venture-template\");\n if (templates) {\n groups.push({\n icon: \"📄\",\n label: \"Templates\",\n count: templates.files.length,\n });\n }\n\n return groups;\n}\n\n/**\n * Builds a hover description string for the profile selection menu.\n * Shows the category breakdown so users know what they're getting.\n */\nfunction buildProfileDescription(components: RegistryComponent[], profile: Profile): string {\n const groups = categorizeComponents(components);\n const parts = groups.map((g) => `${g.icon} ${g.count} ${g.label}`);\n if (profile === \"full\" || profile === \"lite\") {\n // Insert agent roles before governance docs (spells + agents first, then the rest)\n const govIndex = groups.findIndex((g) => g.label === \"Governance Docs\");\n parts.splice(govIndex >= 0 ? govIndex : parts.length, 0, \"🤖 12 Agent Roles\");\n }\n return \"\\n\" + parts.join(\"\\n\");\n}\n\n// ─── Main ─────────────────────────────────────────────────────────────────────\n\n/**\n * Runs the `spell init` command.\n *\n * @param options CLI flags (profile, force, dryRun)\n * @param targetDir Directory to initialize (defaults to cwd in CLI)\n * @param assetsDir Path to the bundled assets root (dist/assets/ in prod, src/assets/ in tests)\n * @param packageVersion Current package version string (passed from CLI entry to avoid require path issues)\n */\nexport async function runInit(\n options: SpellInitOptions,\n targetDir: string,\n assetsDir: string,\n packageVersion: string,\n): Promise<void> {\n // Validate profile option if provided\n if (options.profile && !VALID_PROFILES.includes(options.profile)) {\n throw new Error(\n `Invalid profile \"${options.profile}\". Valid options: ${VALID_PROFILES.join(\", \")}`,\n );\n }\n\n // Check if already initialized\n try {\n await readManifest(targetDir);\n console.log(chalk.hex(\"#a855f7\")(`\\n ✦ Arcane v${packageVersion}\\n`));\n console.log('Already initialized. Run \"spell update\" to update existing files.');\n return;\n } catch (err) {\n if (!(err instanceof ManifestNotFoundError)) throw err;\n // ManifestNotFoundError = not initialized — proceed\n }\n\n console.log(chalk.hex(\"#a855f7\")(`\\n ✦ Arcane v${packageVersion}\\n`));\n\n // ── Git-state checks (EF-05, EF-32) ─────────────────────────────────────\n // Never runs `git init` or creates a commit -- see\n // features/init-git-state-contract/PRD.md's \"Design decision\" section for\n // why that's declined rather than deferred. Only acts where it's provably\n // safe (an unborn repo has no commits to conflict with) or where the\n // operator already explicitly confirmed continuing (uncommitted changes).\n let repoNotFound = false;\n if (!options.dryRun) {\n const gitState = await inspectGitRepository(targetDir);\n\n if (gitState.status === \"not-repository\") {\n repoNotFound = true;\n } else {\n if (gitState.status === \"no-commits\") {\n const correction = await correctUnbornMasterDefault(targetDir);\n if (correction.corrected) {\n printInfo(\n `Repointed the unborn branch from \"${correction.from}\" to \"${correction.to}\" (avoids the Git for Windows default-branch trap).`,\n );\n }\n }\n\n if (gitState.status === \"ready\" && gitState.uncommittedChanges > 0) {\n printWarning(\n `This repo has ${gitState.uncommittedChanges} uncommitted change${gitState.uncommittedChanges === 1 ? \"\" : \"s\"}.`,\n );\n printInfo(\"Running spell init will add new files to your working tree.\");\n console.log();\n const continueAnyway = await confirm({\n message: \"Continue anyway?\",\n default: true,\n });\n if (!continueAnyway) {\n console.log(\"\\nCancelled. Commit or stash your changes first.\");\n return;\n }\n console.log();\n }\n\n const rebaseResult = await ensureLocalPullRebase(targetDir);\n if (rebaseResult.action === \"explicit-false-preserved\") {\n printWarning(\n \"This repo's pull.rebase is explicitly set to false, but Arcane's governance mandates rebase-and-fast-forward (see .arcane/governance/git-conventions.md). Left as-is since you set it explicitly.\",\n );\n }\n }\n }\n\n // ── Step 1: Resolve profile (prompt if not provided) ───────────────────\n let profile: Profile = options.profile as Profile;\n if (!profile) {\n const profiles = listProfiles();\n profile = (await select({\n message: \"Select an installation profile:\\n\",\n choices: profiles.map((p) => {\n const profileComponents = getProfile(p.id);\n return {\n value: p.id,\n name: `${p.id === \"full\" ? \"🧙\" : p.id === \"lite\" ? \"⚡\" : \"📋\"} ${p.displayName} — ${p.description}`,\n description: buildProfileDescription(profileComponents, p.id),\n };\n }),\n })) as Profile;\n }\n\n // ── Step 2: Resolve components ─────────────────────────────────────────\n const components = getProfile(profile);\n\n // ── Step 3: Preview what will be installed ─────────────────────────────\n const groups = categorizeComponents(components);\n\n console.log();\n printSection(`📦 Profile: ${profile}`);\n console.log();\n\n // Show agent setup as upcoming interactive step\n const hasAgents = profile === \"full\" || profile === \"lite\";\n\n // Build summary parts (same style as hover description)\n const previewParts = groups.map((g) => `${g.icon} ${g.count} ${g.label}`);\n if (hasAgents) {\n // Insert agent roles before governance docs\n const govIndex = groups.findIndex((g) => g.label === \"Governance Docs\");\n previewParts.splice(govIndex >= 0 ? govIndex : previewParts.length, 0, \"🤖 12 Agent Roles\");\n }\n console.log(` ${previewParts.join(\" · \")}`);\n\n console.log();\n\n // ── Step 4: Confirm (skip in non-interactive mode) ─────────────────────\n if (!options.dryRun && !options.profile) {\n const proceed = await confirm({\n message: \"Proceed with installation?\",\n default: true,\n });\n if (!proceed) {\n console.log(\"\\nCancelled.\");\n return;\n }\n }\n\n // ── Step 5: Copy files ─────────────────────────────────────────────────\n const installedComponents: InstalledComponent[] = [];\n let fileCount = 0;\n\n for (const component of components) {\n const installedFiles: string[] = [];\n\n for (const file of component.files) {\n const srcPath = join(assetsDir, file);\n if (options.dryRun) {\n printDryRun(`Would copy: ${file}`);\n } else {\n try {\n await copyFile(srcPath, targetDir, file, { force: options.force });\n } catch (err) {\n // skipExisting components silently skip files that already exist\n if (component.skipExisting && err instanceof Error && err.message.includes(\"already exists\")) {\n continue;\n }\n throw err;\n }\n }\n installedFiles.push(file);\n fileCount++;\n }\n\n for (const dir of component.directories ?? []) {\n const srcDirPath = join(assetsDir, dir);\n if (options.dryRun) {\n printDryRun(`Would copy directory: ${dir}/`);\n } else {\n const copied = await copyDirectory(srcDirPath, targetDir, dir, { force: options.force });\n installedFiles.push(...copied);\n fileCount += copied.length;\n }\n }\n\n if (!options.dryRun) {\n installedComponents.push({\n name: component.name,\n files: installedFiles,\n installedVersion: packageVersion,\n });\n }\n }\n\n // Show compact category summary (not 60 individual file paths)\n if (!options.dryRun) {\n for (const group of groups) {\n printStep(`${group.icon} ${group.count} ${group.label}`);\n }\n }\n\n if (options.dryRun) {\n // Show what agent setup would install\n if (hasAgents) {\n const agentFiles = await import(\"node:fs\").then((fsModule) =>\n fsModule.promises.readdir(join(assetsDir, \"agents\")),\n );\n const yamlFiles = agentFiles.filter((f) => f.endsWith(\".yaml\")).sort();\n printDryRun(\"Would run agent setup (interactive):\");\n printDryRun(\"Would write: .arcane/agents.yaml\");\n for (const f of yamlFiles) {\n printDryRun(`Would copy: .arcane/agents/${f}`);\n }\n }\n printDryRun(`Would initialize with profile \"${profile}\" — ${fileCount} files`);\n return;\n }\n\n // ── Step 5a: Hub question ───────────────────────────────────────────────\n // Explicit opt-in only -- never inferred from repo content (a `ventures/`\n // directory can legitimately exist in a consumer repo too, e.g. one this\n // very init run just created via a governance-only profile). Written\n // explicitly either way so a future `spell update` retrofit wizard can\n // tell \"asked and declined\" apart from \"predates this feature\".\n let role: HubRole | undefined;\n if (!options.profile) {\n console.log();\n const isHub = await confirm({\n message: \"Will this repo manage other ventures as a hub? (idea books, spell-manifest promotion, venture registry)\",\n default: false,\n });\n role = isHub ? \"hub\" : \"consumer\";\n }\n\n // ── Step 6: Write manifest ─────────────────────────────────────────────\n const manifest: ArcaneManifest = {\n version: packageVersion,\n profile,\n installedAt: new Date().toISOString(),\n components: installedComponents,\n ...(role ? { role } : {}),\n };\n await writeManifest(targetDir, manifest);\n\n printSuccess(`Initialized with profile \"${profile}\" — ${fileCount} files installed`);\n\n // ── Step 7: Offer agent setup (for full and lite profiles) ─────────────\n let agentsConfigured = false;\n if (hasAgents && !options.profile) {\n console.log();\n const setupAgents = await confirm({\n message: \"🤖 Set up your agent team? (names, roles, AI tool configs)\",\n default: true,\n });\n\n if (setupAgents) {\n await runAgentsInit({}, targetDir, assetsDir);\n agentsConfigured = true;\n }\n }\n\n // ── Step 8: Print next steps ───────────────────────────────────────────\n console.log();\n printSection(\"🚀 Next steps\");\n console.log();\n let step = 1;\n\n if (!agentsConfigured && profile !== \"governance-only\") {\n printNextStep(step++, \"Run `spell agents init` to set up your agent team\");\n }\n if (agentsConfigured) {\n printNextStep(\n step++,\n \"Edit .arcane/agents.yaml to customize roles → `spell agents sync` to regenerate AI tool configs\",\n );\n }\n if (profile !== \"governance-only\") {\n printNextStep(\n step++,\n \"Review .arcane/governance/ docs and customize for your project\",\n );\n }\n if (repoNotFound) {\n printNextStep(\n step++,\n 'Initialize Git for this project: `git init -b main` (avoids defaulting to \"master\" on systems where that\\'s the system default)',\n );\n }\n printNextStep(\n step++,\n \"Commit the new files: git add .arcane .github .claude AGENTS.md CLAUDE.md .arcane.json\",\n );\n console.log();\n}\n","import {\n mkdir,\n copyFile as fsCopyFile,\n access,\n readdir,\n} from \"node:fs/promises\";\nimport path from \"node:path\";\n\n/**\n * Validates that relativePath stays within targetDir.\n * Throws if the resolved path escapes the target directory boundary.\n */\nexport function validateTargetPath(\n targetDir: string,\n relativePath: string,\n): void {\n const resolvedBase = path.resolve(targetDir);\n const resolvedFull = path.resolve(targetDir, relativePath);\n\n if (\n resolvedFull !== resolvedBase &&\n !resolvedFull.startsWith(resolvedBase + path.sep)\n ) {\n throw new Error(\n `Path traversal detected: \"${relativePath}\" escapes target directory \"${targetDir}\"`,\n );\n }\n}\n\n/**\n * Creates a directory and all parent directories if they don't exist.\n */\nexport async function ensureDir(dirPath: string): Promise<void> {\n await mkdir(dirPath, { recursive: true });\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Copies srcPath into targetDir at relativePath.\n * Validates path traversal before any I/O.\n * Throws if the destination already exists and opts.force is not set.\n */\nexport async function copyFile(\n srcPath: string,\n targetDir: string,\n relativePath: string,\n opts: { force?: boolean } = {},\n): Promise<void> {\n validateTargetPath(targetDir, relativePath);\n\n const destPath = path.resolve(targetDir, relativePath);\n await ensureDir(path.dirname(destPath));\n\n if (!opts.force && (await fileExists(destPath))) {\n throw new Error(\n `Destination already exists: \"${relativePath}\". Use --force to overwrite.`,\n );\n }\n\n await fsCopyFile(srcPath, destPath);\n}\n\n/**\n * Recursively copies a directory from srcDir to targetDir/relativeDir.\n * Validates the target path to prevent traversal attacks.\n * Returns the list of relative file paths that were copied (for manifest tracking).\n */\nexport async function copyDirectory(\n srcDir: string,\n targetDir: string,\n relativeDir: string,\n opts: { force?: boolean } = {},\n): Promise<string[]> {\n validateTargetPath(targetDir, relativeDir);\n\n const copiedFiles: string[] = [];\n const entries = await readdir(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcEntryPath = path.join(srcDir, entry.name);\n const relEntryPath = `${relativeDir}/${entry.name}`;\n\n if (entry.isDirectory()) {\n const subFiles = await copyDirectory(srcEntryPath, targetDir, relEntryPath, opts);\n copiedFiles.push(...subFiles);\n } else {\n await copyFile(srcEntryPath, targetDir, relEntryPath, opts);\n copiedFiles.push(relEntryPath);\n }\n }\n\n return copiedFiles;\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type {\n ArcaneManifest,\n InstalledComponent,\n Profile,\n} from \"../types.js\";\n\nexport class ManifestNotFoundError extends Error {\n constructor(manifestPath: string) {\n super(`Manifest not found at \"${manifestPath}\". Run \"spell init\" first.`);\n this.name = \"ManifestNotFoundError\";\n }\n}\n\nexport class ManifestCorruptError extends Error {\n constructor(manifestPath: string) {\n super(\n `Manifest at \"${manifestPath}\" contains invalid JSON. It may be corrupted.`,\n );\n this.name = \"ManifestCorruptError\";\n }\n}\n\nconst MANIFEST_FILE = \".arcane.json\";\n\nfunction manifestPath(targetDir: string): string {\n return path.join(targetDir, MANIFEST_FILE);\n}\n\n/**\n * Reads .arcane.json from targetDir.\n * Throws ManifestNotFoundError if the file is missing.\n * Throws ManifestCorruptError if the file contains invalid JSON.\n */\nexport async function readManifest(targetDir: string): Promise<ArcaneManifest> {\n const filePath = manifestPath(targetDir);\n let content: string;\n\n try {\n content = await readFile(filePath, \"utf-8\");\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new ManifestNotFoundError(filePath);\n }\n throw err;\n }\n\n try {\n return JSON.parse(content) as ArcaneManifest;\n } catch {\n throw new ManifestCorruptError(filePath);\n }\n}\n\n/**\n * Writes the manifest to .arcane.json in targetDir with 2-space indentation.\n */\nexport async function writeManifest(\n targetDir: string,\n manifest: ArcaneManifest,\n): Promise<void> {\n const filePath = manifestPath(targetDir);\n await writeFile(filePath, JSON.stringify(manifest, null, 2), \"utf-8\");\n}\n\n/**\n * Creates a new .arcane.json in targetDir with an empty components array.\n * Returns the created manifest.\n */\nexport async function createManifest(\n targetDir: string,\n profile: Profile,\n version: string,\n): Promise<ArcaneManifest> {\n const manifest: ArcaneManifest = {\n version,\n profile,\n installedAt: new Date().toISOString(),\n components: [],\n };\n await writeManifest(targetDir, manifest);\n return manifest;\n}\n\n/**\n * Pure function — returns a new manifest with the component appended.\n * Does not write to disk.\n */\nexport function addComponent(\n manifest: ArcaneManifest,\n component: InstalledComponent,\n): ArcaneManifest {\n return {\n ...manifest,\n components: [...manifest.components, component],\n };\n}\n\n/**\n * Pure function — returns a new manifest with the named component removed.\n * Does not write to disk.\n */\nexport function removeComponent(\n manifest: ArcaneManifest,\n name: string,\n): ArcaneManifest {\n return {\n ...manifest,\n components: manifest.components.filter((c) => c.name !== name),\n };\n}\n\n/**\n * Returns true if a component with the given name exists in the manifest.\n */\nexport function hasComponent(manifest: ArcaneManifest, name: string): boolean {\n return manifest.components.some((c) => c.name === name);\n}\n","/**\n * Profile configuration — the canonical source of truth for Arcane profiles.\n *\n * A profile bundles a curated set of components for a common use case.\n * Adding or changing profiles requires only editing this file — no changes to\n * the registry or CLI command logic are needed.\n *\n * The special value \"*\" for `components` means \"all registered components\"\n * and is expanded by the registry at runtime.\n */\n\nimport type { Profile } from \"../types.js\";\n\nexport interface ProfileConfig {\n id: Profile;\n displayName: string;\n description: string;\n /**\n * Component names included in this profile.\n * Use the special value \"*\" to mean \"all registered components\" (full install).\n */\n components: string[] | \"*\";\n}\n\nexport const PROFILE_CONFIGS: ProfileConfig[] = [\n {\n id: \"full\",\n displayName: \"Full Suite\",\n description: \"All components — spells, governance, agents, templates\",\n components: \"*\",\n },\n {\n id: \"lite\",\n displayName: \"Essentials\",\n description: \"Spells + core governance — fast start\",\n components: [\"spell-prompts\", \"claude-commands\", \"agent-output-instructions\", \"git-conventions\", \"testing-standards\", \"framework-decisions\", \"session-continuity\"],\n },\n {\n id: \"methodology\",\n displayName: \"Methodology Suite\",\n description: \"Spells + governance — full methodology without security/infra docs\",\n components: [\n \"spell-prompts\",\n \"claude-commands\",\n \"agent-output-instructions\",\n \"git-conventions\",\n \"testing-standards\",\n \"framework-decisions\",\n \"session-continuity\",\n \"decision-documentation-standard\",\n \"agent-work-queue-model\",\n \"development-methodology\",\n \"spell-authoring-standards\",\n ],\n },\n {\n id: \"governance-only\",\n displayName: \"Governance Only\",\n description: \"Standards docs only — no spells or agents\",\n components: [\n \"agent-output-instructions\",\n \"git-conventions\",\n \"testing-standards\",\n \"framework-decisions\",\n \"decision-documentation-standard\",\n \"agent-work-queue-model\",\n \"naming-conventions\",\n \"agent-policies\",\n \"threat-model\",\n \"hardening-checklist\",\n \"authentication-strategy\",\n \"new-business-setup\",\n \"agent-approved-paths\",\n \"portable-bootstrap\",\n \"development-methodology\",\n \"cicd-standards\",\n \"poc-management-pattern\",\n \"product-excellence-standards\",\n \"rca-process-standard\",\n \"universal-agent-rules\",\n \"spell-authoring-standards\",\n ],\n },\n];\n","import type { Profile, RegistryComponent, ProfileDefinition } from \"../types.js\";\nimport { PROFILE_CONFIGS } from \"../config/profiles.js\";\n\nexport class ComponentNotFoundError extends Error {\n constructor(name: string, available: string[]) {\n super(\n `Component \"${name}\" not found. Available components: ${available.join(\", \")}`,\n );\n this.name = \"ComponentNotFoundError\";\n }\n}\n\n// ─── Component definitions ───────────────────────────────────────────────────\n// File paths are relative to src/assets/ (source) / dist/assets/ (published).\n\nconst COMPONENTS: RegistryComponent[] = [\n // Governance\n {\n name: \"git-conventions\",\n description: \"Git branching, commit message, and PR conventions\",\n files: [\".arcane/governance/git-conventions.md\"],\n },\n {\n name: \"testing-standards\",\n description: \"Testing framework selection, coverage thresholds, and CI gates\",\n files: [\".arcane/governance/testing-standards.md\"],\n },\n {\n name: \"framework-decisions\",\n description: \"Offline reference for legacy framework ADR citations\",\n files: [\".arcane/governance/framework-decisions.md\"],\n },\n {\n name: \"decision-documentation-standard\",\n description: \"ADR format and decision-logging conventions\",\n files: [\".arcane/governance/decision-documentation-standard.md\"],\n },\n {\n name: \"agent-work-queue-model\",\n description: \"Work queue model for AI agent task assignment and tracking\",\n files: [\".arcane/governance/agent-work-queue-model.md\"],\n },\n {\n name: \"naming-conventions\",\n description: \"Machine, agent, and service naming rules (three-tier model)\",\n files: [\".arcane/governance/naming-conventions.md\"],\n },\n {\n name: \"agent-policies\",\n description: \"Agent autonomy levels, power levels, and operational constraints\",\n files: [\".arcane/governance/agent-policies.md\"],\n },\n {\n name: \"threat-model\",\n description: \"Security threat model covering STRIDE categories and mitigations\",\n files: [\".arcane/governance/threat-model.md\"],\n },\n {\n name: \"hardening-checklist\",\n description: \"Production hardening checklist for infrastructure and agents\",\n files: [\".arcane/governance/hardening-checklist.md\"],\n },\n {\n name: \"authentication-strategy\",\n description: \"Authentication patterns, token management, and identity strategy\",\n files: [\".arcane/governance/authentication-strategy.md\"],\n },\n {\n name: \"new-business-setup\",\n description: \"Step-by-step playbook for bootstrapping a new business unit\",\n files: [\".arcane/governance/new-business-setup.md\"],\n },\n {\n name: \"agent-approved-paths\",\n description: \"Approved repository paths and access boundaries for agents\",\n files: [\".arcane/governance/agent-approved-paths.md\"],\n },\n {\n name: \"portable-bootstrap\",\n description: \"Portable AI context bootstrap for onboarding new AI clients\",\n files: [\".arcane/governance/portable-bootstrap.md\"],\n },\n // Governance — methodology\n {\n name: \"development-methodology\",\n description: \"Spell Loop development methodology\",\n files: [\".arcane/governance/development-methodology.md\"],\n },\n {\n name: \"cicd-standards\",\n description: \"CI/CD pipeline standards and quality gates\",\n files: [\".arcane/governance/cicd-standards.md\"],\n },\n {\n name: \"poc-management-pattern\",\n description: \"POC lifecycle management pattern\",\n files: [\".arcane/governance/poc-management-pattern.md\"],\n },\n {\n name: \"product-excellence-standards\",\n description: \"Product quality gate standards and spell-enchant requirements\",\n files: [\".arcane/governance/product-excellence-standards.md\"],\n },\n {\n name: \"spell-authoring-standards\",\n description: \"Spell Quality Rubric — the authoring bar for spell prompts (8 dimensions)\",\n files: [\".arcane/governance/spell-authoring-standards.md\"],\n },\n {\n name: \"rca-process-standard\",\n description: \"Root cause analysis process standard\",\n files: [\".arcane/governance/rca-process-standard.md\"],\n },\n {\n name: \"universal-agent-rules\",\n description: \"Universal rules for all AI agents operating in any Arcane-managed repo\",\n files: [\".arcane/governance/universal-agent-rules.md\"],\n },\n // VS Code Copilot instructions — installed to .github/instructions/\n {\n name: \"agent-output-instructions\",\n description: \"Copilot enforcement rules: PR link format, merge strategy, and branch naming\",\n files: [\".github/instructions/agent-output.instructions.md\"],\n },\n // Spell prompts — installed to .github/prompts/ (VS Code Copilot convention)\n {\n name: \"spell-prompts\",\n description: \"Full Arcane spell prompt library (34 spells)\",\n files: [\n \".github/prompts/spell-arcane-version.prompt.md\",\n \".github/prompts/spell-architect.prompt.md\",\n \".github/prompts/spell-brainstorm.prompt.md\",\n \".github/prompts/spell-scope.prompt.md\",\n \".github/prompts/spell-summon-venture.prompt.md\",\n \".github/prompts/spell-bug.prompt.md\",\n \".github/prompts/spell-bump.prompt.md\",\n \".github/prompts/spell-check-drift.prompt.md\",\n \".github/prompts/spell-close-session.prompt.md\",\n \".github/prompts/spell-commit-work.prompt.md\",\n \".github/prompts/spell-dotnet-expert.prompt.md\",\n \".github/prompts/spell-enchant.prompt.md\",\n \".github/prompts/spell-explain-concept.prompt.md\",\n \".github/prompts/spell-full-cycle.prompt.md\",\n \".github/prompts/spell-generate-bot-icons.prompt.md\",\n \".github/prompts/spell-implement.prompt.md\",\n \".github/prompts/spell-open-session.prompt.md\",\n \".github/prompts/spell-plan.prompt.md\",\n \".github/prompts/spell-present-arcane.prompt.md\",\n \".github/prompts/spell-product-review.prompt.md\",\n \".github/prompts/spell-review.prompt.md\",\n \".github/prompts/spell-security-review.prompt.md\",\n \".github/prompts/spell-ship.prompt.md\",\n \".github/prompts/spell-suggest-feature.prompt.md\",\n \".github/prompts/spell-test.prompt.md\",\n \".github/prompts/spell-todo.prompt.md\",\n // Workflow spell additions — PR lifecycle, status, capture, feedback\n \".github/prompts/spell-address-review.prompt.md\",\n \".github/prompts/spell-create-pull-request.prompt.md\",\n \".github/prompts/spell-document.prompt.md\",\n \".github/prompts/spell-feedback.prompt.md\",\n \".github/prompts/spell-manifest.prompt.md\",\n \".github/prompts/spell-save-idea.prompt.md\",\n \".github/prompts/spell-status.prompt.md\",\n \".github/prompts/spell-review-batch.prompt.md\",\n ],\n },\n // Templates\n {\n name: \"venture-template\",\n description: \"Starter template for a new business venture folder — overview plus idea/todo books\",\n files: [\n \".arcane/templates/venture-template/overview.md\",\n \".arcane/templates/venture-template/IDEAS.md\",\n \".arcane/templates/venture-template/TODO.md\",\n ],\n },\n // Session continuity — files required for spell-close-session / spell-open-session\n {\n name: \"session-continuity\",\n description: \"Install-once project orientation and session lifecycle files\",\n skipExisting: true,\n files: [\n \"README.md\",\n \"project.md\",\n \"TODO.md\",\n \"DECISIONS.md\",\n \"ai-context/system-prompt-context.md\",\n \"journal/.gitkeep\",\n ],\n },\n // Agent definitions\n // NOTE: the full portable agent system is managed by `spell agents init` / sync / list.\n // This component only installs the policy reference template for governance-only setups.\n {\n name: \"agent-definitions\",\n description: \"Agent policy reference template (for governance-only setups — use `spell agents init` for the full agent system)\",\n files: [\".arcane/agents/agent-policies-template.md\"],\n },\n // NOTE: the static `agent-files` component was retired — `.github/agents/*.agent.md`\n // files are generated per-roster by `spell agents init` / `spell agents sync`, so\n // installing a fixed-name set via `spell init` shipped stale names and collided\n // with the generated output.\n // Claude commands\n {\n name: \"claude-commands\",\n description: \"Claude Code slash command wrappers for all 34 Arcane spells\",\n files: [\n \".claude/commands/spell-arcane-version.md\",\n \".claude/commands/spell-architect.md\",\n \".claude/commands/spell-brainstorm.md\",\n \".claude/commands/spell-scope.md\",\n \".claude/commands/spell-summon-venture.md\",\n \".claude/commands/spell-bug.md\",\n \".claude/commands/spell-bump.md\",\n \".claude/commands/spell-check-drift.md\",\n \".claude/commands/spell-close-session.md\",\n \".claude/commands/spell-commit-work.md\",\n \".claude/commands/spell-dotnet-expert.md\",\n \".claude/commands/spell-enchant.md\",\n \".claude/commands/spell-explain-concept.md\",\n \".claude/commands/spell-full-cycle.md\",\n \".claude/commands/spell-generate-bot-icons.md\",\n \".claude/commands/spell-implement.md\",\n \".claude/commands/spell-open-session.md\",\n \".claude/commands/spell-plan.md\",\n \".claude/commands/spell-present-arcane.md\",\n \".claude/commands/spell-product-review.md\",\n \".claude/commands/spell-review.md\",\n \".claude/commands/spell-security-review.md\",\n \".claude/commands/spell-ship.md\",\n \".claude/commands/spell-suggest-feature.md\",\n \".claude/commands/spell-test.md\",\n \".claude/commands/spell-todo.md\",\n // Workflow spell additions — PR lifecycle, status, capture, feedback\n \".claude/commands/spell-address-review.md\",\n \".claude/commands/spell-create-pull-request.md\",\n \".claude/commands/spell-document.md\",\n \".claude/commands/spell-feedback.md\",\n \".claude/commands/spell-manifest.md\",\n \".claude/commands/spell-save-idea.md\",\n \".claude/commands/spell-status.md\",\n \".claude/commands/spell-review-batch.md\",\n ],\n },\n];\n\n// ─── Profile map (derived from config) ───────────────────────────────────────\n\nfunction buildProfileMap(): Record<Profile, string[]> {\n const allNames = COMPONENTS.map((c) => c.name);\n const map = {} as Record<Profile, string[]>;\n for (const config of PROFILE_CONFIGS) {\n map[config.id] = config.components === \"*\" ? allNames : config.components;\n }\n return map;\n}\n\nconst PROFILE_MAP = buildProfileMap();\n\n// ─── API ──────────────────────────────────────────────────────────────────────\n\nconst componentIndex = new Map(COMPONENTS.map((c) => [c.name, c]));\n\n/**\n * Returns a component by name.\n * Throws ComponentNotFoundError if not found.\n */\nexport function getComponent(name: string): RegistryComponent {\n const component = componentIndex.get(name);\n if (!component) {\n throw new ComponentNotFoundError(name, Array.from(componentIndex.keys()));\n }\n return component;\n}\n\n/**\n * Returns all components for the given profile.\n */\nexport function getProfile(profile: Profile): RegistryComponent[] {\n return PROFILE_MAP[profile].map((name) => getComponent(name));\n}\n\n/**\n * Returns all registered components.\n */\nexport function getAllComponents(): RegistryComponent[] {\n return [...COMPONENTS];\n}\n\n/**\n * Returns all profile definitions with their component lists expanded.\n * Profiles are sourced from src/config/profiles.ts.\n */\nexport function listProfiles(): ProfileDefinition[] {\n const allNames = COMPONENTS.map((c) => c.name);\n return PROFILE_CONFIGS.map((config) => ({\n id: config.id,\n displayName: config.displayName,\n description: config.description,\n components:\n config.components === \"*\" ? [...allNames] : [...config.components],\n }));\n}\n","import chalk from \"chalk\";\nimport gradient from \"gradient-string\";\nimport { readManifest } from \"./manifest.js\";\n\nconst TAGLINE = \"Cast spells to ship software\";\n\n// ─── Brand palette — steel blue (#6F9FD8) ────────────────────────────────────\nconst STEEL = \"#6f9fd8\";\nconst STEEL_DEEP = \"#3a6ea5\";\nconst STEEL_DIM = \"#5d6f93\";\nconst INK_LABEL = \"#c7d2ee\";\nconst FAINT = \"#2c3658\";\n\nconst STOPS = [\"#2a4d7d\", \"#4a7bb5\", \"#6f9fd8\", \"#a9c8ec\"];\nconst arcaneGradient = gradient(STOPS);\n\n// ─── ARCANE wordmark ─────────────────────────────────────────────────────────\nconst WORDMARK = [\n \" █████╗ ██████╗ ██████╗ █████╗ ███╗ ██╗███████╗\",\n \"██╔══██╗██╔══██╗██╔════╝██╔══██╗████╗ ██║██╔════╝\",\n \"███████║██████╔╝██║ ███████║██╔██╗ ██║█████╗\",\n \"██╔══██║██╔══██╗██║ ██╔══██║██║╚██╗██║██╔══╝\",\n \"██║ ██║██║ ██║╚██████╗██║ ██║██║ ╚████║███████╗\",\n \"╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝\",\n];\nconst INDENT = \" \";\nconst LOCKUP_WIDTH = INDENT.length + Math.max(...WORDMARK.map((l) => l.length));\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** True when the terminal can render the fade-in safely. */\nfunction isAnimatable(): boolean {\n return (\n !!process.stdout.isTTY &&\n process.env[\"TERM\"] !== \"dumb\" &&\n process.env[\"CI\"] !== \"true\" &&\n process.env[\"ARCANE_DISABLE_ANIMATION\"] !== \"true\" &&\n (process.stdout.columns ?? 80) >= LOCKUP_WIDTH\n );\n}\n\n/** Scale a hex color toward black by factor f (0..1) — used for the fade-in. */\nfunction scale(hex: string, f: number): string {\n const v = (i: number): number =>\n Math.max(0, Math.min(255, Math.round(parseInt(hex.slice(i, i + 2), 16) * f)));\n return \"#\" + [v(1), v(3), v(5)].map((x) => x.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n/** Build the ARCANE wordmark lines at brightness f (1 = full color). */\nfunction lockupLines(f = 1): string[] {\n const g = f >= 1 ? arcaneGradient : gradient(STOPS.map((c) => scale(c, f)));\n return WORDMARK.map((line) => INDENT + g(line));\n}\n\nfunction printFooter(version: string): void {\n const taglineText = ` ${TAGLINE} · agent-native SDLC · v${version}`;\n const width = Math.max(LOCKUP_WIDTH, taglineText.length);\n const border = chalk.hex(STEEL_DEEP)(\"─\".repeat(width));\n console.log(border);\n console.log(\n chalk.hex(STEEL)(` ${TAGLINE}`),\n chalk.hex(STEEL_DIM)(`· agent-native SDLC · v${version}`),\n );\n console.log(border);\n}\n\n/**\n * Prints the ARCANE wordmark static, with tagline and version.\n * Used by subcommands (init, etc.).\n */\nexport function printBanner(version: string): void {\n console.log();\n for (const line of lockupLines()) console.log(line);\n printFooter(version);\n console.log();\n}\n\n/**\n * Headline counts for the welcome — turns the installed component file list into\n * \"N spells · N agents · N standards\" (the manifest stores registry-relative,\n * forward-slash paths). Returns [] when nothing categorizable is installed, so\n * the caller can fall back to a plain component count.\n */\nfunction installSummary(components: { files: string[] }[]): string[] {\n const files = components.flatMap((c) =>\n c.files.map((f) => f.replace(/\\\\/g, \"/\")),\n );\n const spells = new Set(\n files\n .filter((f) => /\\/(prompts|commands)\\/spell-.+\\.md$/.test(f))\n .map((f) => f.split(\"/\").pop()!.replace(/\\.prompt\\.md$|\\.md$/, \"\")),\n ).size;\n const agents = files.filter((f) => /\\/agents\\/[^/]+\\.agent\\.md$/.test(f)).length;\n const standards = files.filter((f) =>\n /\\/governance\\/[^/]+\\.md$/.test(f),\n ).length;\n const parts: string[] = [];\n if (spells) parts.push(`${spells} spell${spells === 1 ? \"\" : \"s\"}`);\n if (agents) parts.push(`${agents} agent${agents === 1 ? \"\" : \"s\"}`);\n if (standards) parts.push(`${standards} standard${standards === 1 ? \"\" : \"s\"}`);\n return parts;\n}\n\n/**\n * The bare-`spell` welcome screen: a soft fade-in of the lockup followed by a\n * single gentle pulse (strobe-safe — monotonic brightness ramps, no color\n * cycling), then real current state: whether Arcane is installed in this repo\n * (profile, components, version) and the Spell Loop. Falls back to a static\n * lockup on non-TTY / CI / narrow terminals.\n */\nexport async function printWelcome(version: string, cwd: string): Promise<void> {\n console.log();\n if (isAnimatable()) {\n const draw = (lines: string[], redraw: boolean): void => {\n if (redraw) process.stdout.write(`\\x1b[${lines.length}A`);\n for (const line of lines) process.stdout.write(`\\r\\x1b[2K${line}\\n`);\n };\n // 1. Fade in from dark — the mark materializes.\n const fade = [0.1, 0.22, 0.36, 0.52, 0.68, 0.84, 1];\n for (let i = 0; i < fade.length; i++) {\n draw(lockupLines(fade[i]!), i > 0);\n await sleep(90);\n }\n // 2. One gentle settling pulse — a single slow breath of brightness.\n const pulse = [1, 0.9, 0.82, 0.9, 1];\n for (let i = 0; i < pulse.length; i++) {\n draw(lockupLines(pulse[i]!), true);\n await sleep(140);\n }\n } else {\n for (const line of lockupLines()) console.log(line);\n }\n printFooter(version);\n console.log();\n\n const label = (s: string): string => chalk.hex(STEEL_DIM)(s.padEnd(11));\n const dot = chalk.hex(FAINT)(\"·\");\n\n let repoLine: string;\n try {\n const manifest = await readManifest(cwd);\n const parts = installSummary(manifest.components);\n const summary = parts.length\n ? parts\n : [`${manifest.components.length} components`];\n repoLine =\n `${chalk.hex(STEEL)(\"✓\")} Arcane ${chalk.hex(INK_LABEL)(`«${manifest.profile}»`)} ${dot} ` +\n summary.map((p) => chalk.hex(INK_LABEL)(p)).join(` ${dot} `) +\n ` ${dot} ${chalk.hex(STEEL_DIM)(`v${manifest.version}`)}`;\n } catch {\n repoLine =\n `${chalk.hex(STEEL_DIM)(\"○\")} not initialized ${chalk.hex(FAINT)(\"—\")} run ` +\n `${chalk.hex(STEEL).inverse(\" spell init \")} ${chalk.hex(STEEL_DIM)(\"to scaffold\")}`;\n }\n console.log(` ${label(\"This repo\")}${repoLine}`);\n\n const phases = [\"plan\", \"architect\", \"implement\", \"test\", \"review\", \"ship\"].join(\n chalk.hex(STEEL_DEEP)(\" → \"),\n );\n console.log(` ${label(\"Spell Loop\")}${chalk.hex(\"#dbe3f7\")(phases)}`);\n\n // loop-back hint under the implement → test → review cycle\n const flat = [\"plan\", \"architect\", \"implement\", \"test\", \"review\", \"ship\"].join(\" → \");\n const loopStart = 13 + flat.indexOf(\"implement\"); // col under \"implement\"\n const loopEnd = 13 + flat.indexOf(\"review\") + 5; // col under last char of \"review\"\n const inner = loopEnd - loopStart - 1;\n const lp = Math.floor((inner - 19) / 2); // 19 = visible width of \" ↺ until it passes \"\n const rp = inner - 19 - lp;\n const dash = (n: number): string => chalk.hex(STEEL_DEEP)(\"─\".repeat(Math.max(0, n)));\n console.log(\n \" \".repeat(loopStart) +\n chalk.hex(STEEL_DEEP)(\"╰\") +\n dash(lp) +\n chalk.hex(STEEL)(\" ↺ \") +\n chalk.hex(STEEL_DIM)(\"until it passes\") +\n \" \" +\n dash(rp) +\n chalk.hex(STEEL_DEEP)(\"╯\"),\n );\n console.log();\n}\n\nexport function printSuccess(message: string): void {\n console.log(`\\n${chalk.hex(STEEL)(\"✦\")} ${chalk.bold(message)}`);\n}\n\nexport function printStep(message: string): void {\n console.log(` ${chalk.hex(STEEL_DEEP)(\"▸\")} ${message}`);\n}\n\nexport function printDryRun(message: string): void {\n console.log(` ${chalk.yellow(\"◌\")} ${chalk.dim(message)}`);\n}\n\nexport function printSection(title: string): void {\n console.log(`\\n${chalk.hex(STEEL)(\"─\")} ${chalk.bold(title)}`);\n}\n\nexport function printInfo(message: string): void {\n console.log(` ${chalk.dim(message)}`);\n}\n\nexport function printNextStep(step: number, message: string): void {\n console.log(` ${chalk.hex(STEEL_DEEP)(`${step}.`)} ${message}`);\n}\n\nexport function printWarning(message: string): void {\n console.log(` ${chalk.yellow(\"⚠\")} ${chalk.yellow(message)}`);\n}\n","/**\n * `spell agents` subcommand group.\n *\n * Subcommands:\n * spell agents init — Interactive roster setup (naming strategy + role selection)\n * spell agents sync — Regenerate all client instruction files from canonical defs\n * spell agents list — Show current roster with assigned names and roles\n */\n\nimport { select, checkbox, Separator } from \"@inquirer/prompts\";\nimport { mkdir, writeFile, copyFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { stringify } from \"yaml\";\nimport type {\n AgentInitOptions,\n AgentRoster,\n AgentRosterEntry,\n AgentSyncOptions,\n NamingStrategy,\n AgentProfileId,\n} from \"../types.js\";\nimport { AGENT_ROLES } from \"../config/agent-roles.js\";\nimport {\n AGENT_PROFILE_CONFIGS,\n getAgentProfileConfig,\n} from \"../config/agent-profiles.js\";\nimport { applyNamingStrategy } from \"./naming.js\";\nimport {\n loadRoster,\n rosterExists,\n AgentConfigValidationError,\n AgentRosterNotFoundError,\n} from \"./agent-loader.js\";\nimport { syncAgents } from \"./agent-generator.js\";\nimport { printStep, printSuccess } from \"./banner.js\";\n\n// ─── spell agents init ────────────────────────────────────────────────────────\n\n/**\n * Interactive agent roster setup.\n *\n * 1. Prompts for agent profile (base | full | custom)\n * 2. Prompts for naming strategy (generic | random | custom)\n * 3. Applies naming and writes .arcane/agents.yaml + copies definition files\n */\nexport async function runAgentsInit(\n options: AgentInitOptions,\n targetDir: string,\n assetsDir: string,\n): Promise<void> {\n // Check for existing roster\n if (!options.force && (await rosterExists(targetDir))) {\n console.log(\n 'Agent roster already exists at .arcane/agents.yaml. ' +\n 'Run \"spell agents sync\" to regenerate outputs, or use --force to reinitialize.',\n );\n return;\n }\n\n console.log();\n\n // ── Step 1: Agent profile ────────────────────────────────────────────────\n let profileId: AgentProfileId = options.profile ?? \"full\";\n if (!options.profile) {\n const baseRoles = getAgentProfileConfig(\"base\").roles;\n const baseRoleNames = baseRoles.map((id) => {\n const role = AGENT_ROLES.find((r) => r.id === id);\n return role ? role.role : id;\n });\n const allCategories = [...new Set(AGENT_ROLES.map((r) => r.category))];\n\n profileId = (await select({\n message: \"Select an agent profile:\",\n choices: AGENT_PROFILE_CONFIGS.map((p) => ({\n value: p.id,\n name: `${p.id === \"base\" ? \"🎯\" : p.id === \"full\" ? \"🧙\" : \"🎨\"} ${p.displayName}`,\n description:\n p.id === \"base\"\n ? `\\n4 core roles: ${baseRoleNames.join(\", \")}`\n : p.id === \"full\"\n ? `\\nAll 12 roles across ${allCategories.join(\", \")}`\n : \"\\nPick individual roles from the full roster\",\n })),\n })) as AgentProfileId;\n }\n\n // Resolve role IDs for selected profile\n let selectedRoleIds: string[];\n if (profileId === \"custom\") {\n // Group roles by category with separators\n const categories = [...new Set(AGENT_ROLES.map((r) => r.category))];\n const choicesWithSeparators: Array<\n | { value: string; name: string; checked: boolean }\n | Separator\n > = [];\n for (const cat of categories) {\n choicesWithSeparators.push(new Separator(`── ${cat.charAt(0).toUpperCase() + cat.slice(1)} ──`));\n for (const r of AGENT_ROLES.filter((r) => r.category === cat)) {\n choicesWithSeparators.push({\n value: r.id,\n name: `${r.id} — ${r.role}`,\n checked: true,\n });\n }\n }\n\n console.log();\n selectedRoleIds = await checkbox({\n message: \"Select roles to install:\",\n choices: choicesWithSeparators,\n validate: (choices) =>\n choices.length > 0 ? true : \"Select at least one role\",\n });\n } else {\n selectedRoleIds = getAgentProfileConfig(profileId).roles;\n }\n\n // ── Step 2: Naming strategy ──────────────────────────────────────────────\n let namingStrategy: NamingStrategy = options.naming ?? \"arcanos\";\n if (!options.naming) {\n console.log();\n namingStrategy = (await select({\n message: \"Choose a naming strategy for your agents:\",\n choices: [\n {\n value: \"arcanos\" as NamingStrategy,\n name: \"🃏 Arcanos\",\n description: \"\\nPersona names: Kellar, Merlin, Lafayette, Lince, Prospero...\",\n },\n {\n value: \"generic\" as NamingStrategy,\n name: \"🏷️ Generic\",\n description: \"\\nRole-derived labels: Orchestrator, Architect, Developer, QA Lead...\",\n },\n {\n value: \"random\" as NamingStrategy,\n name: \"🎲 Random\",\n description: \"\\nCommon first names shuffled randomly: Blake, Morgan, Casey...\",\n },\n {\n value: \"custom\" as NamingStrategy,\n name: \"✏️ Custom\",\n description: \"\\nType a unique name for each role interactively\",\n },\n ],\n })) as NamingStrategy;\n }\n\n // ── Step 3: Apply naming ─────────────────────────────────────────────────\n printStep(\"Assigning names...\");\n const named = await applyNamingStrategy(namingStrategy, selectedRoleIds);\n\n // ── Step 4: Build roster ─────────────────────────────────────────────────\n const rosterEntries: AgentRosterEntry[] = named.map(({ definition, name }) => {\n // Orchestrator gets the \"main\" OpenClaw ID by convention\n const id = definition === \"orchestrator\" ? \"main\" : name.toLowerCase().replace(/\\s+/g, \"-\");\n return { definition, name, id };\n });\n\n const roster: AgentRoster = {\n schema_version: 2,\n naming_strategy: namingStrategy,\n agent_profile: profileId,\n openclaw: {\n enabled: true,\n workspace_root: \"~/.openclaw\",\n },\n roster: rosterEntries,\n };\n\n // ── Step 5: Write .arcane/agents.yaml ────────────────────────────────────\n const arcaneDir = join(targetDir, \".arcane\", \"agents\");\n if (!options.dryRun) {\n await mkdir(arcaneDir, { recursive: true });\n await writeFile(\n join(targetDir, \".arcane\", \"agents.yaml\"),\n stringify(roster),\n \"utf8\",\n );\n } else {\n console.log(\" [dry-run] Would write: .arcane/agents.yaml\");\n }\n\n // ── Step 6: Copy bundled definition files ─────────────────────────────────\n for (const roleId of selectedRoleIds) {\n const src = join(assetsDir, \"agents\", `${roleId}.yaml`);\n const dest = join(arcaneDir, `${roleId}.yaml`);\n if (!options.dryRun) {\n try {\n await copyFile(src, dest);\n } catch {\n console.warn(` ! Could not copy definition for \"${roleId}\" — skipping`);\n }\n } else {\n console.log(` [dry-run] Would copy: .arcane/agents/${roleId}.yaml`);\n }\n }\n\n if (options.dryRun) {\n console.log(\n `\\n [dry-run] Would initialize roster with ${selectedRoleIds.length} agents`,\n );\n return;\n }\n\n // ── Step 7: Auto-sync all clients ────────────────────────────────────────\n printStep(\"Syncing agent definitions to all clients...\");\n const { synced, skipped } = await syncAgents(\n targetDir,\n assetsDir,\n roster,\n { dryRun: false },\n );\n\n printSuccess(\"Agent roster initialized\");\n console.log(` 📋 Profile: ${profileId} · Naming: ${namingStrategy} · Agents: ${rosterEntries.length}`);\n console.log(` 🔄 Synced: ${synced.length} outputs (Copilot, Claude, Codex, OpenClaw)`);\n if (skipped.length > 0) {\n console.log(` ⚠️ Skipped: ${skipped.length} (${skipped.join(\", \")})`);\n }\n console.log();\n console.log(` 💡 Customize: edit .arcane/agents.yaml → spell agents sync`);\n console.log();\n}\n\n// ─── spell agents sync ────────────────────────────────────────────────────────\n\n/** Regenerates all client instruction files from the current roster + definitions. */\nexport async function runAgentsSync(\n options: AgentSyncOptions,\n targetDir: string,\n assetsDir: string,\n): Promise<void> {\n let roster: AgentRoster;\n try {\n roster = await loadRoster(targetDir);\n } catch (err) {\n if (\n err instanceof AgentRosterNotFoundError\n || err instanceof AgentConfigValidationError\n ) {\n console.error(err.message);\n process.exit(1);\n return;\n }\n throw err;\n }\n\n if (options.dryRun) {\n console.log(\"\\n [dry-run] Would sync agents from roster:\\n\");\n } else {\n console.log(\"\\n Syncing agents...\\n\");\n }\n\n const { synced, skipped } = await syncAgents(\n targetDir,\n assetsDir,\n roster,\n options,\n );\n\n if (options.dryRun) {\n console.log(`\\n [dry-run] ${synced.length} outputs would be generated`);\n return;\n }\n\n console.log(`\\n ✓ Synced ${synced.length} outputs`);\n for (const item of synced) {\n console.log(` + ${item}`);\n }\n if (skipped.length > 0) {\n console.log(`\\n ! Skipped ${skipped.length}:`);\n for (const item of skipped) {\n console.log(` - ${item}`);\n }\n }\n console.log();\n}\n\n// ─── spell agents list ────────────────────────────────────────────────────────\n\n/** Displays the current agent roster in a table. */\nexport async function runAgentsList(targetDir: string): Promise<void> {\n let roster: AgentRoster;\n try {\n roster = await loadRoster(targetDir);\n } catch (err) {\n if (\n err instanceof AgentRosterNotFoundError\n || err instanceof AgentConfigValidationError\n ) {\n console.error(err.message);\n process.exit(1);\n return;\n }\n throw err;\n }\n\n const nameWidth = Math.max(\n \"Name\".length,\n ...roster.roster.map((e) => (e.name ?? e.definition).length),\n );\n const defWidth = Math.max(\n \"Role ID\".length,\n ...roster.roster.map((e) => e.definition.length),\n );\n const idWidth = Math.max(\n \"OpenClaw ID\".length,\n ...roster.roster.map((e) => e.id.length),\n );\n\n const pad = (s: string, n: number) => s.padEnd(n);\n\n console.log(\n `\\n Profile: ${roster.agent_profile} | Naming: ${roster.naming_strategy} | Agents: ${roster.roster.length}\\n`,\n );\n console.log(\n ` ${pad(\"Name\", nameWidth)} ${pad(\"Role ID\", defWidth)} ${pad(\"OpenClaw ID\", idWidth)}`,\n );\n console.log(\n ` ${\"-\".repeat(nameWidth)} ${\"-\".repeat(defWidth)} ${\"-\".repeat(idWidth)}`,\n );\n for (const entry of roster.roster) {\n console.log(\n ` ${pad(entry.name ?? \"(unnamed)\", nameWidth)} ${pad(entry.definition, defWidth)} ${pad(entry.id, idWidth)}`,\n );\n }\n console.log();\n}\n","/**\n * Canonical agent role definitions.\n * Each entry maps to a YAML template file at src/assets/agents/{id}.yaml.\n * These are the 12 standard roles that ship with Arcane.\n */\n\nimport type { AgentCategory } from \"../types.js\";\n\nexport interface AgentRoleConfig {\n id: string;\n role: string;\n category: AgentCategory;\n}\n\nexport const AGENT_ROLES: AgentRoleConfig[] = [\n {\n id: \"orchestrator\",\n role: \"Product Operations Manager\",\n category: \"operations\",\n },\n {\n id: \"architecture-lead\",\n role: \"CTO / Architecture Lead\",\n category: \"engineering\",\n },\n {\n id: \"fullstack-dev\",\n role: \"Full-Stack Developer\",\n category: \"engineering\",\n },\n {\n id: \"qa-lead\",\n role: \"QA Lead\",\n category: \"quality\",\n },\n {\n id: \"devops\",\n role: \"DevOps / CI/CD Engineer\",\n category: \"engineering\",\n },\n {\n id: \"frontend-dev\",\n role: \"Frontend Developer\",\n category: \"engineering\",\n },\n {\n id: \"mobile-dev\",\n role: \"Mobile Developer\",\n category: \"engineering\",\n },\n {\n id: \"research-analyst\",\n role: \"Research & Backlog Analyst\",\n category: \"research\",\n },\n {\n id: \"marketing-strategist\",\n role: \"Marketing Strategist\",\n category: \"operations\",\n },\n {\n id: \"operations-comms\",\n role: \"Operations Communications\",\n category: \"operations\",\n },\n {\n id: \"collaborator\",\n role: \"External Collaboration Lead\",\n category: \"operations\",\n },\n {\n id: \"security-ops\",\n role: \"Security Operations\",\n category: \"quality\",\n },\n];\n\n/** Lookup by role ID. */\nexport function getAgentRole(id: string): AgentRoleConfig | undefined {\n return AGENT_ROLES.find((r) => r.id === id);\n}\n","/**\n * Agent profile configurations.\n * Controls which roles are included when running `spell agents init`.\n * Separate from src/config/profiles.ts (which governs governance/prompts components).\n */\n\nimport type { AgentProfileId } from \"../types.js\";\n\nexport interface AgentProfileConfig {\n id: AgentProfileId;\n displayName: string;\n description: string;\n /** Role IDs included in this profile. Empty means user selects interactively. */\n roles: string[];\n}\n\nexport const AGENT_PROFILE_CONFIGS: AgentProfileConfig[] = [\n {\n id: \"base\",\n displayName: \"Base\",\n description: \"Core team: orchestrator, architecture-lead, fullstack-dev, qa-lead\",\n roles: [\"orchestrator\", \"architecture-lead\", \"fullstack-dev\", \"qa-lead\"],\n },\n {\n id: \"full\",\n displayName: \"Full\",\n description: \"Complete roster — all 12 roles\",\n roles: [\n \"orchestrator\",\n \"architecture-lead\",\n \"fullstack-dev\",\n \"qa-lead\",\n \"devops\",\n \"frontend-dev\",\n \"mobile-dev\",\n \"research-analyst\",\n \"marketing-strategist\",\n \"operations-comms\",\n \"collaborator\",\n \"security-ops\",\n ],\n },\n {\n id: \"custom\",\n displayName: \"Custom\",\n description: \"Select roles interactively\",\n roles: [], // populated at runtime via checkbox prompt\n },\n];\n\n/** Lookup by profile ID. */\nexport function getAgentProfileConfig(id: AgentProfileId): AgentProfileConfig {\n const config = AGENT_PROFILE_CONFIGS.find((p) => p.id === id);\n if (!config) throw new Error(`Unknown agent profile: \"${id}\"`);\n return config;\n}\n","/**\n * Naming strategy logic for agent roster setup.\n *\n * Four strategies:\n * arcanos — the built-in persona roster (default): twelve legendary agents\n * generic — maps each role to a short, memorable generic label\n * random — assigns random common names from a curated pool\n * custom — prompts the user to type a name for each role\n */\n\nimport { input } from \"@inquirer/prompts\";\nimport type { NamingStrategy } from \"../types.js\";\nimport { getAgentRole } from \"../config/agent-roles.js\";\n\n// ─── Generic names ────────────────────────────────────────────────────────────\n\n/** Short, role-derived display names for the generic strategy. */\nconst GENERIC_NAME_MAP: Record<string, string> = {\n \"orchestrator\": \"Orchestrator\",\n \"architecture-lead\": \"Architect\",\n \"fullstack-dev\": \"Developer\",\n \"qa-lead\": \"QA Lead\",\n \"devops\": \"DevOps\",\n \"frontend-dev\": \"Frontend\",\n \"mobile-dev\": \"Mobile\",\n \"research-analyst\": \"Researcher\",\n \"marketing-strategist\": \"Marketer\",\n \"operations-comms\": \"Comms\",\n \"collaborator\": \"Collaborator\",\n \"security-ops\": \"Security\",\n};\n\n// ─── Arcanos preset names ─────────────────────────────────────────────────────\n\n/** Persona names from the Arcanos roster — twelve legendary agents. */\nconst ARCANOS_NAME_MAP: Record<string, string> = {\n \"orchestrator\": \"Kellar\",\n \"architecture-lead\": \"Merlin\",\n \"fullstack-dev\": \"Lafayette\",\n \"qa-lead\": \"Lince\",\n \"devops\": \"Prospero\",\n \"frontend-dev\": \"Adelaide\",\n \"mobile-dev\": \"Mercurio\",\n \"research-analyst\": \"Alexander\",\n \"marketing-strategist\": \"Circe\",\n \"operations-comms\": \"Bess\",\n \"collaborator\": \"Iris\",\n \"security-ops\": \"Custodio\",\n};\n\n// ─── Random name pool ─────────────────────────────────────────────────────────\n\n/**\n * Curated pool of common single-word names.\n * Gender-neutral where possible to avoid unintentional character typecasting.\n */\nconst RANDOM_NAME_POOL: string[] = [\n \"Aiden\", \"Blake\", \"Casey\", \"Dana\", \"Ellis\", \"Finley\", \"Gray\", \"Harper\",\n \"Indigo\", \"Jordan\", \"Kai\", \"Lane\", \"Morgan\", \"Nova\", \"Owen\", \"Parker\",\n \"Quinn\", \"River\", \"Sage\", \"Taylor\", \"Uma\", \"Vale\", \"Wren\", \"Xander\",\n \"Yael\", \"Zara\", \"Avery\", \"Brett\", \"Charlie\", \"Devon\",\n];\n\n// ─── Strategy implementations ────────────────────────────────────────────────\n\nexport interface NamingResult {\n definition: string;\n name: string;\n}\n\n/** Assigns short generic labels derived from each role. */\nexport function applyGenericNames(roleIds: string[]): NamingResult[] {\n return roleIds.map((id) => ({\n definition: id,\n name: GENERIC_NAME_MAP[id] ?? id,\n }));\n}\n\n/** Assigns Arcanos persona names (Kellar, Merlin, Lafayette, etc.). */\nexport function applyArcanosNames(roleIds: string[]): NamingResult[] {\n return roleIds.map((id) => ({\n definition: id,\n name: ARCANOS_NAME_MAP[id] ?? GENERIC_NAME_MAP[id] ?? id,\n }));\n}\n\n/**\n * Assigns random names from the pool, shuffled per call.\n * If more roles than pool entries, wraps around.\n */\nexport function applyRandomNames(roleIds: string[]): NamingResult[] {\n const shuffled = [...RANDOM_NAME_POOL].sort(() => Math.random() - 0.5);\n return roleIds.map((id, i) => ({\n definition: id,\n name: shuffled[i % shuffled.length]!,\n }));\n}\n\n/**\n * Prompts the user to type a name for each role interactively.\n * Defaults to the generic name to speed up entry.\n */\nexport async function promptCustomNames(roleIds: string[]): Promise<NamingResult[]> {\n const results: NamingResult[] = [];\n for (const id of roleIds) {\n const role = getAgentRole(id);\n const defaultName = GENERIC_NAME_MAP[id] ?? id;\n const name = await input({\n message: `Name for ${role?.role ?? id}:`,\n default: defaultName,\n validate: (v) =>\n v.trim().length > 0 ? true : \"Name cannot be empty\",\n });\n results.push({ definition: id, name: name.trim() });\n }\n return results;\n}\n\n/**\n * Applies the selected naming strategy to a list of role IDs.\n * Returns an array of definition→name pairs.\n */\nexport async function applyNamingStrategy(\n strategy: NamingStrategy,\n roleIds: string[],\n): Promise<NamingResult[]> {\n switch (strategy) {\n case \"arcanos\":\n return applyArcanosNames(roleIds);\n case \"generic\":\n return applyGenericNames(roleIds);\n case \"random\":\n return applyRandomNames(roleIds);\n case \"custom\":\n return promptCustomNames(roleIds);\n }\n}\n","/**\n * Agent definition and roster loader.\n *\n * Reads canonical agent YAML files from two locations:\n * - assetsDir/agents/ — bundled templates (used during init/add)\n * - targetDir/.arcane/agents/ — project's installed/customized definitions (used during sync)\n */\n\nimport { readFile, readdir, access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { parse } from \"yaml\";\nimport type { AgentDefinition, AgentRoster } from \"../types.js\";\nimport {\n AgentConfigValidationError,\n validateAgentDefinition,\n validateAgentRoster,\n} from \"./agent-schema.js\";\n\nexport { AgentConfigValidationError } from \"./agent-schema.js\";\n\n// ─── Error types ──────────────────────────────────────────────────────────────\n\nexport class AgentDefinitionNotFoundError extends Error {\n constructor(id: string, searchDir: string) {\n super(\n `Agent definition \"${id}\" not found in \"${searchDir}\". ` +\n `Check that ${id}.yaml exists or run \"spell agents add ${id}\".`,\n );\n this.name = \"AgentDefinitionNotFoundError\";\n }\n}\n\nexport class AgentRosterNotFoundError extends Error {\n constructor() {\n super(\n 'No agent roster found at .arcane/agents.yaml. ' +\n 'Run \"spell agents init\" to create one.',\n );\n this.name = \"AgentRosterNotFoundError\";\n }\n}\n\nfunction parseYaml(content: string, source: string): unknown {\n try {\n return parse(content);\n } catch (err) {\n const detail = err instanceof Error ? err.message : \"unknown YAML parse error\";\n throw new AgentConfigValidationError(source, [`malformed YAML: ${detail}`]);\n }\n}\n\n// ─── Definition loaders ───────────────────────────────────────────────────────\n\n/**\n * Loads a single agent definition from a directory.\n * Used by `spell agents sync` (reads from .arcane/agents/).\n */\nexport async function loadAgentDefinition(\n agentsDir: string,\n id: string,\n): Promise<AgentDefinition> {\n const filePath = join(agentsDir, `${id}.yaml`);\n let content: string;\n try {\n content = await readFile(filePath, \"utf8\");\n } catch {\n throw new AgentDefinitionNotFoundError(id, agentsDir);\n }\n return validateAgentDefinition(parseYaml(content, filePath), filePath);\n}\n\n/**\n * Loads all agent definition files from a directory.\n * Skips non-YAML files and the agents.yaml roster file.\n */\nexport async function loadAllAgentDefinitions(\n agentsDir: string,\n): Promise<AgentDefinition[]> {\n let entries: string[];\n try {\n entries = await readdir(agentsDir);\n } catch {\n return [];\n }\n\n const definitions: AgentDefinition[] = [];\n for (const file of entries) {\n if (!file.endsWith(\".yaml\") || file === \"agents.yaml\") continue;\n const filePath = join(agentsDir, file);\n const content = await readFile(filePath, \"utf8\");\n definitions.push(validateAgentDefinition(parseYaml(content, filePath), filePath));\n }\n return definitions;\n}\n\n// ─── Roster loaders ───────────────────────────────────────────────────────────\n\n/**\n * Loads the agent roster from .arcane/agents.yaml in the target directory.\n * Throws AgentRosterNotFoundError if not initialized.\n */\nexport async function loadRoster(targetDir: string): Promise<AgentRoster> {\n const rosterPath = join(targetDir, \".arcane\", \"agents.yaml\");\n let content: string;\n try {\n content = await readFile(rosterPath, \"utf8\");\n } catch {\n throw new AgentRosterNotFoundError();\n }\n return validateAgentRoster(parseYaml(content, rosterPath), rosterPath);\n}\n\n/**\n * Returns true if a roster file exists in the target directory.\n */\nexport async function rosterExists(targetDir: string): Promise<boolean> {\n try {\n await access(join(targetDir, \".arcane\", \"agents.yaml\"));\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Returns the path to the project's agent definitions directory.\n */\nexport function projectAgentsDir(targetDir: string): string {\n return join(targetDir, \".arcane\", \"agents\");\n}\n","import type { AgentDefinition, AgentRoster } from \"../types.js\";\n\nconst CURRENT_ROSTER_SCHEMA_VERSION = 2;\nconst POWER_LEVELS = new Set([\n \"Spectator\",\n \"Apprentice\",\n \"Wizard\",\n \"Sorcerer\",\n \"Magus\",\n \"Archmage\",\n]);\nconst AGENT_CATEGORIES = new Set([\n \"engineering\",\n \"operations\",\n \"quality\",\n \"research\",\n]);\nconst NAMING_STRATEGIES = new Set([\"arcanos\", \"generic\", \"random\", \"custom\"]);\nconst AGENT_PROFILES = new Set([\"base\", \"full\", \"custom\"]);\n\ntype RecordValue = Record<string, unknown>;\n\nexport class AgentConfigValidationError extends Error {\n constructor(source: string, issues: string[]) {\n super(`Invalid agent configuration in ${source}:\\n- ${issues.join(\"\\n- \")}`);\n this.name = \"AgentConfigValidationError\";\n }\n}\n\nfunction isRecord(value: unknown): value is RecordValue {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction requireRecord(\n value: unknown,\n path: string,\n issues: string[],\n): RecordValue | undefined {\n if (!isRecord(value)) {\n issues.push(`${path} must be an object`);\n return undefined;\n }\n return value;\n}\n\nfunction requireString(value: unknown, path: string, issues: string[]) {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n issues.push(`${path} must be a non-empty string`);\n }\n}\n\nfunction requireBoolean(value: unknown, path: string, issues: string[]) {\n if (typeof value !== \"boolean\") issues.push(`${path} must be a boolean`);\n}\n\nfunction requireStringArray(value: unknown, path: string, issues: string[]) {\n if (!Array.isArray(value) || value.some((entry) => typeof entry !== \"string\")) {\n issues.push(`${path} must be an array of strings`);\n }\n}\n\nfunction requireEnum(\n value: unknown,\n allowed: Set<string>,\n path: string,\n issues: string[],\n) {\n if (typeof value !== \"string\" || !allowed.has(value)) {\n issues.push(`${path} must be one of: ${[...allowed].join(\", \")}`);\n }\n}\n\nfunction validateOptionalClient(\n clients: RecordValue,\n key: string,\n property: string,\n expected: \"string\" | \"boolean\",\n issues: string[],\n) {\n if (clients[key] === undefined) return;\n const client = requireRecord(clients[key], `clients.${key}`, issues);\n if (!client) return;\n if (expected === \"string\") {\n requireString(client[property], `clients.${key}.${property}`, issues);\n } else {\n requireBoolean(client[property], `clients.${key}.${property}`, issues);\n }\n}\n\nexport function validateAgentDefinition(\n value: unknown,\n source: string,\n): AgentDefinition {\n const issues: string[] = [];\n const definition = requireRecord(value, \"definition\", issues);\n if (!definition) throw new AgentConfigValidationError(source, issues);\n\n requireString(definition.id, \"id\", issues);\n requireString(definition.role, \"role\", issues);\n requireEnum(definition.category, AGENT_CATEGORIES, \"category\", issues);\n\n const persona = requireRecord(definition.persona, \"persona\", issues);\n if (persona) {\n requireString(persona.description, \"persona.description\", issues);\n requireStringArray(persona.behavioral_rules, \"persona.behavioral_rules\", issues);\n for (const key of [\"personality\", \"voice\", \"visual_description\"] as const) {\n if (persona[key] !== undefined) requireString(persona[key], `persona.${key}`, issues);\n }\n if (persona.catchphrases !== undefined) {\n requireStringArray(persona.catchphrases, \"persona.catchphrases\", issues);\n }\n }\n\n const model = requireRecord(definition.model, \"model\", issues);\n if (model) {\n requireString(model.primary, \"model.primary\", issues);\n requireStringArray(model.fallback, \"model.fallback\", issues);\n }\n\n const tools = requireRecord(definition.tools, \"tools\", issues);\n if (tools) {\n requireStringArray(tools.allowed, \"tools.allowed\", issues);\n requireStringArray(tools.denied, \"tools.denied\", issues);\n }\n\n const autonomy = requireRecord(definition.autonomy, \"autonomy\", issues);\n if (autonomy) {\n requireEnum(\n autonomy.default_power_level,\n POWER_LEVELS,\n \"autonomy.default_power_level\",\n issues,\n );\n requireBoolean(autonomy.exec_allowed, \"autonomy.exec_allowed\", issues);\n }\n\n const spawn = requireRecord(definition.spawn, \"spawn\", issues);\n if (spawn) {\n requireBoolean(spawn.can_spawn, \"spawn.can_spawn\", issues);\n requireStringArray(spawn.spawnable_by, \"spawn.spawnable_by\", issues);\n }\n\n const clients = requireRecord(definition.clients, \"clients\", issues);\n if (clients) {\n validateOptionalClient(clients, \"openclaw\", \"workspace_prefix\", \"string\", issues);\n validateOptionalClient(clients, \"copilot\", \"agent_file\", \"boolean\", issues);\n validateOptionalClient(clients, \"claude\", \"include_in_instructions\", \"boolean\", issues);\n validateOptionalClient(clients, \"codex\", \"include_in_agents_md\", \"boolean\", issues);\n }\n\n if (issues.length > 0) throw new AgentConfigValidationError(source, issues);\n return definition as unknown as AgentDefinition;\n}\n\nexport function validateAgentRoster(value: unknown, source: string): AgentRoster {\n const issues: string[] = [];\n const parsed = requireRecord(value, \"roster\", issues);\n if (!parsed) throw new AgentConfigValidationError(source, issues);\n\n const version = parsed.schema_version;\n if (!Number.isInteger(version)) {\n throw new AgentConfigValidationError(source, [\n \"schema_version must be an integer; run \\\"spell agents init\\\" with a compatible Arcane CLI\",\n ]);\n }\n if ((version as number) > CURRENT_ROSTER_SCHEMA_VERSION) {\n throw new AgentConfigValidationError(source, [\n `schema_version ${version} is newer than supported version ${CURRENT_ROSTER_SCHEMA_VERSION}; upgrade Arcane before reading this roster`,\n ]);\n }\n if ((version as number) < 1) {\n throw new AgentConfigValidationError(source, [\n `schema_version ${version} is unsupported; supported versions are 1 and ${CURRENT_ROSTER_SCHEMA_VERSION}`,\n ]);\n }\n\n const roster = version === 1\n ? { ...parsed, schema_version: CURRENT_ROSTER_SCHEMA_VERSION }\n : parsed;\n requireEnum(roster.naming_strategy, NAMING_STRATEGIES, \"naming_strategy\", issues);\n requireEnum(roster.agent_profile, AGENT_PROFILES, \"agent_profile\", issues);\n\n const openclaw = requireRecord(roster.openclaw, \"openclaw\", issues);\n if (openclaw) {\n requireBoolean(openclaw.enabled, \"openclaw.enabled\", issues);\n requireString(openclaw.workspace_root, \"openclaw.workspace_root\", issues);\n }\n\n if (!Array.isArray(roster.roster)) {\n issues.push(\"roster must be an array\");\n } else {\n roster.roster.forEach((entry, index) => {\n const item = requireRecord(entry, `roster[${index}]`, issues);\n if (!item) return;\n requireString(item.definition, `roster[${index}].definition`, issues);\n if (item.name !== null) requireString(item.name, `roster[${index}].name`, issues);\n requireString(item.id, `roster[${index}].id`, issues);\n });\n }\n\n if (issues.length > 0) throw new AgentConfigValidationError(source, issues);\n return roster as unknown as AgentRoster;\n}","/**\n * Agent generator — multi-client fan-out engine.\n *\n * Reads canonical agent definitions and an agent roster, then generates\n * client-specific instruction files for each enabled AI client:\n * - OpenClaw: IDENTITY.md, SOUL.md, TOOLS.md per agent workspace\n * - Copilot: .github/agents/{name}.agent.md per agent\n * - Claude: CLAUDE.md ← arcane marker merge\n * - Codex: AGENTS.md ← arcane marker merge\n *\n * Generated outputs also merge an agent roster table into\n * .github/copilot-instructions.md (shared with Copilot merge).\n *\n * NOTE: openclaw.json is NEVER modified directly — a patch file is generated\n * at .arcane/generated/openclaw-roster.json for the user to apply manually.\n */\n\nimport { writeFile, mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type {\n AgentDefinition,\n AgentRoster,\n AgentRosterEntry,\n AgentSyncOptions,\n} from \"../types.js\";\nimport { mergeIntoFile } from \"./merger.js\";\nimport { loadAgentDefinition, projectAgentsDir } from \"./agent-loader.js\";\n\n// ─── Resolved entry (definition + roster entry joined) ───────────────────────\n\ninterface ResolvedEntry {\n entry: AgentRosterEntry;\n def: AgentDefinition;\n displayName: string;\n}\n\n// ─── Content renderers ───────────────────────────────────────────────────────\n\nfunction renderIdentity(def: AgentDefinition, name: string): string {\n const mottosLine =\n def.persona.catchphrases && def.persona.catchphrases.length > 0\n ? `\\n## Mottos\\n\\n${def.persona.catchphrases.map((c) => `- \"${c}\"`).join(\"\\n\")}\\n`\n : \"\";\n return `# ${name} — ${def.role}\n\n## Role\n\n${def.persona.description.trim()}\n\n## Category\n\n${def.category}\n${mottosLine}`;\n}\n\nfunction renderSoul(def: AgentDefinition, name: string): string {\n const rules = def.persona.behavioral_rules.map((r) => `- ${r}`).join(\"\\n\");\n return `# ${name} — Behavioral Directives\n\n## Rules\n\n${rules}\n\n## Autonomy\n\n- **Default Power Level:** ${def.autonomy.default_power_level}\n- **Exec Allowed:** ${def.autonomy.exec_allowed ? \"Yes\" : \"No\"}\n`;\n}\n\nfunction renderTools(def: AgentDefinition, name: string): string {\n const allowed = def.tools.allowed.map((t) => `- \\`${t}\\``).join(\"\\n\");\n const denied = def.tools.denied.map((t) => `- \\`${t}\\``).join(\"\\n\");\n return `# ${name} — Tool Capabilities\n\n## Allowed\n\n${allowed}\n\n## Denied\n\n${denied}\n`;\n}\n\nfunction renderCopilotAgent(def: AgentDefinition, name: string): string {\n const firstLine = def.persona.description.split(\"\\n\")[0]?.trim() ?? def.role;\n const rules = def.persona.behavioral_rules.map((r) => `- ${r}`).join(\"\\n\");\n const personalityBlock = def.persona.personality\n ? `\\n## Personality\\n\\n${def.persona.personality.trim()}\\n`\n : \"\";\n const voiceBlock = def.persona.voice\n ? `\\n## Voice\\n\\n${def.persona.voice.trim()}\\n`\n : \"\";\n const mottosBlock =\n def.persona.catchphrases && def.persona.catchphrases.length > 0\n ? `\\n## Mottos\\n\\n${def.persona.catchphrases.map((c) => `- \"${c}\"`).join(\"\\n\")}\\n`\n : \"\";\n return `---\nname: ${name}\ndescription: ${def.role} — ${firstLine}\n---\n${mottosBlock}\n## Role\n\n${def.persona.description.trim()}\n${personalityBlock}${voiceBlock}\n## Behavioral Rules\n\n${rules}\n\n## Tools\n\n**Allowed:** ${def.tools.allowed.join(\", \")}\n**Denied:** ${def.tools.denied.join(\", \")}\n`;\n}\n\nfunction renderAgentRosterSection(entries: ResolvedEntry[]): string {\n const rows = entries\n .map(({ def, displayName }) =>\n `| **${displayName}** | ${def.role} | ${def.category} |`,\n )\n .join(\"\\n\");\n\n return `## Agent Roster\n\n| Agent | Role | Category |\n|-------|------|----------|\n${rows}\n`;\n}\n\n// ─── Sync result ─────────────────────────────────────────────────────────────\n\nexport interface SyncResult {\n synced: string[];\n skipped: string[];\n}\n\n// ─── Main sync function ───────────────────────────────────────────────────────\n\n/**\n * Generates all client-specific output files from the agent roster and definitions.\n *\n * @param targetDir Root of the consuming repo (where .arcane/ lives)\n * @param assetsDir Path to bundled assets (used as fallback for definitions not yet in project)\n * @param roster Parsed agent roster (from .arcane/agents.yaml)\n * @param options Sync options (dry-run, client filters)\n */\nexport async function syncAgents(\n targetDir: string,\n assetsDir: string,\n roster: AgentRoster,\n options: AgentSyncOptions = {},\n): Promise<SyncResult> {\n const synced: string[] = [];\n const skipped: string[] = [];\n\n // ── Load all definitions ──────────────────────────────────────────────────\n const projectDefs = projectAgentsDir(targetDir);\n const bundledDefs = join(assetsDir, \"agents\");\n\n const resolved: ResolvedEntry[] = [];\n for (const entry of roster.roster) {\n let def: AgentDefinition;\n try {\n // Prefer the project's customized version\n def = await loadAgentDefinition(projectDefs, entry.definition);\n } catch {\n try {\n // Fall back to bundled template\n def = await loadAgentDefinition(bundledDefs, entry.definition);\n } catch {\n skipped.push(`${entry.definition} (definition not found)`);\n continue;\n }\n }\n resolved.push({\n entry,\n def,\n displayName: entry.name ?? entry.definition,\n });\n }\n\n // ── OpenClaw output ──────────────────────────────────────────────────────\n if (roster.openclaw.enabled && options.openclaw !== false) {\n const openclawRoot = roster.openclaw.workspace_root.replace(\n /^~/,\n homedir(),\n );\n\n for (const { entry, def, displayName } of resolved) {\n if (!def.clients.openclaw) continue;\n\n const workspaceName =\n entry.id === \"main\" ? \"workspace\" : `workspace-${entry.id}`;\n const workspaceDir = join(openclawRoot, workspaceName);\n\n try {\n if (!options.dryRun) {\n await mkdir(workspaceDir, { recursive: true });\n await writeFile(\n join(workspaceDir, \"IDENTITY.md\"),\n renderIdentity(def, displayName),\n \"utf8\",\n );\n await writeFile(\n join(workspaceDir, \"SOUL.md\"),\n renderSoul(def, displayName),\n \"utf8\",\n );\n await writeFile(\n join(workspaceDir, \"TOOLS.md\"),\n renderTools(def, displayName),\n \"utf8\",\n );\n } else {\n console.log(` [dry-run] Would write: ${workspaceDir}/IDENTITY.md`);\n console.log(` [dry-run] Would write: ${workspaceDir}/SOUL.md`);\n console.log(` [dry-run] Would write: ${workspaceDir}/TOOLS.md`);\n }\n synced.push(`openclaw:${entry.id}:IDENTITY+SOUL+TOOLS`);\n } catch {\n skipped.push(`openclaw:${entry.id} (workspace not accessible)`);\n }\n }\n\n // Generate openclaw-roster.json patch — never modifies openclaw.json directly\n const patch = {\n $comment:\n \"Apply this to your openclaw.json agents section. \" +\n \"Do not edit manually — regenerated by `spell agents sync`.\",\n agents: resolved.map(({ entry, def }) => ({\n id: entry.id,\n identity: {\n name: entry.name ?? entry.definition,\n role: def.role,\n },\n })),\n };\n\n const generatedDir = join(targetDir, \".arcane\", \"generated\");\n if (!options.dryRun) {\n await mkdir(generatedDir, { recursive: true });\n await writeFile(\n join(generatedDir, \"openclaw-roster.json\"),\n JSON.stringify(patch, null, 2) + \"\\n\",\n \"utf8\",\n );\n } else {\n console.log(\n \" [dry-run] Would write: .arcane/generated/openclaw-roster.json\",\n );\n }\n synced.push(\"openclaw-roster.json\");\n }\n\n // ── Copilot output ───────────────────────────────────────────────────────\n if (options.copilot !== false) {\n const agentsDir = join(targetDir, \".github\", \"agents\");\n\n if (!options.dryRun) {\n await mkdir(agentsDir, { recursive: true });\n }\n\n for (const { def, displayName } of resolved) {\n if (!def.clients.copilot?.agent_file) continue;\n // Slugify: lowercase, spaces → hyphens (e.g. \"QA Lead\" → \"qa-lead.agent.md\")\n const slug = displayName.toLowerCase().replace(/\\s+/g, \"-\");\n const fileName = `${slug}.agent.md`;\n if (!options.dryRun) {\n await writeFile(\n join(agentsDir, fileName),\n renderCopilotAgent(def, displayName),\n \"utf8\",\n );\n } else {\n console.log(` [dry-run] Would write: .github/agents/${fileName}`);\n }\n synced.push(`.github/agents/${fileName}`);\n }\n\n // Merge roster into copilot-instructions.md\n const rosterSection = renderAgentRosterSection(resolved);\n const copilotMerged = await mergeIntoFile(\n targetDir,\n \".github/copilot-instructions.md\",\n rosterSection,\n { force: true, dryRun: options.dryRun },\n );\n if (copilotMerged)\n synced.push(\".github/copilot-instructions.md (agents section)\");\n }\n\n // ── Claude output ────────────────────────────────────────────────────────\n if (options.claude !== false) {\n const rosterSection = renderAgentRosterSection(resolved);\n const claudeMerged = await mergeIntoFile(\n targetDir,\n \"CLAUDE.md\",\n rosterSection,\n { force: true, dryRun: options.dryRun },\n );\n if (claudeMerged) synced.push(\"CLAUDE.md (agents section)\");\n }\n\n // ── Codex output ─────────────────────────────────────────────────────────\n if (options.codex !== false) {\n const rosterSection = renderAgentRosterSection(resolved);\n const codexMerged = await mergeIntoFile(\n targetDir,\n \"AGENTS.md\",\n rosterSection,\n { force: true, dryRun: options.dryRun },\n );\n if (codexMerged) synced.push(\"AGENTS.md (agents section)\");\n }\n\n return { synced, skipped };\n}\n","import { readFile, writeFile, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { validateTargetPath } from \"./copier.js\";\n\nexport const MARKER_START = \"<!-- arcane:start -->\";\nexport const MARKER_END = \"<!-- arcane:end -->\";\n\nexport class MalformedMarkersError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"MalformedMarkersError\";\n }\n}\n\n/**\n * Merges `content` into `targetDir/relativePath` using arcane marker comments.\n *\n * Behaviour:\n * - If both markers exist: replaces everything between them with `content`.\n * - If neither marker exists and `force` is true: appends markers + content.\n * - If neither marker exists and `force` is false: no-op, returns false.\n * - If only one marker is present: throws MalformedMarkersError.\n * - If file doesn't exist and `force` is true: creates the file with markers.\n * - If file doesn't exist and `force` is false: no-op, returns false.\n *\n * @returns true if the file was modified (or would be on dry-run), false if untouched.\n */\nexport async function mergeIntoFile(\n targetDir: string,\n relativePath: string,\n content: string,\n opts: { force?: boolean; dryRun?: boolean } = {},\n): Promise<boolean> {\n validateTargetPath(targetDir, relativePath);\n\n const destPath = path.resolve(targetDir, relativePath);\n\n let existing: string | null;\n try {\n existing = await readFile(destPath, \"utf8\");\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOENT\") {\n existing = null;\n } else {\n throw err;\n }\n }\n\n if (existing === null) {\n // File doesn't exist — create with markers only if --force\n if (!opts.force) return false;\n const newContent = `${MARKER_START}\\n${content}\\n${MARKER_END}\\n`;\n if (!opts.dryRun) {\n await writeFile(destPath, newContent, \"utf8\");\n }\n return true;\n }\n\n const startIdx = existing.indexOf(MARKER_START);\n const endIdx = existing.indexOf(MARKER_END);\n\n const hasStart = startIdx !== -1;\n const hasEnd = endIdx !== -1;\n\n if (hasStart !== hasEnd) {\n throw new MalformedMarkersError(\n `File \"${relativePath}\" has mismatched arcane markers: ` +\n `${hasStart ? \"start found\" : \"start missing\"}, ` +\n `${hasEnd ? \"end found\" : \"end missing\"}.`,\n );\n }\n\n if (hasStart && hasEnd) {\n if (startIdx > endIdx) {\n throw new MalformedMarkersError(\n `File \"${relativePath}\" has arcane markers in wrong order (end before start).`,\n );\n }\n // Replace content between the markers (keeps marker lines themselves intact)\n const beforeMarker = existing.slice(0, startIdx + MARKER_START.length);\n const afterMarker = existing.slice(endIdx);\n const updated = `${beforeMarker}\\n${content}\\n${afterMarker}`;\n if (!opts.dryRun) {\n await writeFile(destPath, updated, \"utf8\");\n }\n return true;\n }\n\n // No markers — append only if --force\n if (!opts.force) return false;\n\n const appended =\n `${existing}${existing.endsWith(\"\\n\") ? \"\" : \"\\n\"}` +\n `${MARKER_START}\\n${content}\\n${MARKER_END}\\n`;\n if (!opts.dryRun) {\n await writeFile(destPath, appended, \"utf8\");\n }\n return true;\n}\n\n/**\n * Removes the `<!-- arcane:start -->…<!-- arcane:end -->` block from a file.\n *\n * - If the file has no markers, returns false (no-op).\n * - If the file is empty (or whitespace-only) after stripping, deletes the file.\n * - Otherwise rewrites the file without the marker block.\n *\n * @returns true if the file was modified or deleted, false if untouched.\n */\nexport async function stripMarkerSection(\n targetDir: string,\n relativePath: string,\n opts: { dryRun?: boolean } = {},\n): Promise<boolean> {\n const destPath = path.resolve(targetDir, relativePath);\n\n let existing: string;\n try {\n existing = await readFile(destPath, \"utf8\");\n } catch {\n return false; // file doesn't exist\n }\n\n const startIdx = existing.indexOf(MARKER_START);\n const endIdx = existing.indexOf(MARKER_END);\n if (startIdx === -1 || endIdx === -1) return false;\n\n const before = existing.slice(0, startIdx);\n const after = existing.slice(endIdx + MARKER_END.length);\n const stripped = (before + after).replace(/\\n{3,}/g, \"\\n\\n\").trim();\n\n if (!opts.dryRun) {\n if (stripped.length === 0) {\n await rm(destPath, { force: true });\n } else {\n await writeFile(destPath, stripped + \"\\n\", \"utf8\");\n }\n }\n return true;\n}\n","import { execFile } from \"node:child_process\";\n\nexport type GitRepositoryState =\n | { status: \"ready\"; uncommittedChanges: number }\n | { status: \"not-repository\" }\n | { status: \"no-commits\" };\n\nexport type GitCommandClass = \"read\" | \"write\" | \"network\";\n\nexport interface RunGitOptions {\n /** Override auto-classification from the subcommand. */\n commandClass?: GitCommandClass;\n /** Override the command class's default timeout, in milliseconds. */\n timeoutMs?: number;\n}\n\nexport interface GitResult {\n stdout: string;\n stderr: string;\n}\n\n/**\n * EF-20: thrown when a `git` subprocess exceeds its runGit-assigned timeout\n * and Node reports the resulting kill via `error.killed`. Note this reflects\n * \"the child was killed by a signal Node sent it,\" which today only ever\n * happens through runGit's own timeout, since no caller retains the\n * underlying ChildProcess to kill it independently -- if a future caller\n * gains that ability, `error.killed` alone would no longer distinguish\n * runGit's timeout from an external kill of the same handle.\n */\nexport class GitTimeoutError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = \"GitTimeoutError\";\n }\n}\n\nconst NETWORK_SUBCOMMANDS = new Set([\"fetch\", \"pull\", \"push\", \"clone\", \"ls-remote\", \"send-email\"]);\n\nconst WRITE_SUBCOMMANDS = new Set([\n \"init\",\n \"commit\",\n \"add\",\n \"checkout\",\n \"switch\",\n \"merge\",\n \"rebase\",\n \"reset\",\n \"tag\",\n \"mv\",\n \"rm\",\n \"cherry-pick\",\n \"revert\",\n \"stash\",\n \"apply\",\n \"am\",\n \"restore\",\n \"submodule\",\n \"sparse-checkout\",\n \"maintenance\",\n \"notes\",\n]);\n\n// These subcommands can be read-only (`branch --list`, `config --get`) or\n// mutating (`branch -m`, `config user.name x`) depending on flags. Classified\n// as \"write\" -- the safer over-estimate: a read given write's longer timeout\n// just waits a little longer, while a write given read's shorter timeout\n// risks being killed mid-operation.\nconst AMBIGUOUS_AS_WRITE = new Set([\"branch\", \"config\", \"remote\", \"worktree\"]);\n\n// Known read-only subcommands get the fast 15s budget explicitly. Anything\n// NOT in this list, NOT in WRITE_SUBCOMMANDS/AMBIGUOUS_AS_WRITE, and NOT in\n// NETWORK_SUBCOMMANDS is a subcommand this module doesn't recognize at all --\n// that case defaults to \"write\" (see classifyGitCommand), the safer\n// over-estimate for a genuinely unknown operation.\nconst READ_SUBCOMMANDS = new Set([\n \"status\",\n \"rev-parse\",\n \"log\",\n \"diff\",\n \"show\",\n \"describe\",\n \"cat-file\",\n \"ls-files\",\n \"ls-tree\",\n \"symbolic-ref\",\n \"merge-base\",\n \"blame\",\n \"shortlog\",\n \"grep\",\n \"reflog\",\n \"diff-tree\",\n \"rev-list\",\n \"name-rev\",\n \"count-objects\",\n \"verify-commit\",\n \"verify-tag\",\n \"help\",\n \"version\",\n]);\n\n// Global options that take their value as a SEPARATE following token (not\n// `--opt=value`). Without skipping the value too, `args.find(a =>\n// !a.startsWith(\"-\"))` would grab the value itself (e.g. \"user.name=x\" from\n// `-c user.name=x commit`) and misclassify the real subcommand that follows.\nconst GLOBAL_FLAGS_WITH_SEPARATE_VALUE = new Set([\"-c\", \"-C\"]);\n\nconst DEFAULT_TIMEOUTS_MS: Record<GitCommandClass, number> = {\n read: 15_000,\n write: 30_000,\n network: 120_000,\n};\n\n/**\n * Classify a git invocation by its first real subcommand token, skipping any\n * leading global flags (and, for `-c`/`-C`, their separate-token values) to\n * find it. Exported for tests.\n */\nexport function classifyGitCommand(args: string[]): GitCommandClass {\n let subcommand: string | undefined;\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (GLOBAL_FLAGS_WITH_SEPARATE_VALUE.has(arg)) {\n i++; // skip this flag's value token too\n continue;\n }\n if (arg.startsWith(\"-\")) continue;\n subcommand = arg;\n break;\n }\n if (!subcommand) return \"read\";\n if (NETWORK_SUBCOMMANDS.has(subcommand)) return \"network\";\n if (WRITE_SUBCOMMANDS.has(subcommand) || AMBIGUOUS_AS_WRITE.has(subcommand)) return \"write\";\n if (READ_SUBCOMMANDS.has(subcommand)) return \"read\";\n // A subcommand this module doesn't recognize at all: default to \"write\"\n // (the safer over-estimate) rather than \"read\" -- see READ_SUBCOMMANDS.\n return \"write\";\n}\n\n/**\n * EF-20/EF-13: the non-interactive execution environment applied to every\n * git invocation. GIT_TERMINAL_PROMPT and GCM_INTERACTIVE suppress credential\n * and terminal prompts; GIT_OPTIONAL_LOCKS disables git's speculative index\n * lock during `status` (git-config(1): \"core.optionalLocks\" affects only\n * status/update-index, so this is safe to apply blanket rather than per\n * command class) -- the mitigation for EF-13's stranded-lock report on\n * filesystems that reject unlink. Exported for tests.\n */\nexport function buildGitEnv(): NodeJS.ProcessEnv {\n return {\n ...process.env,\n GIT_TERMINAL_PROMPT: \"0\",\n GCM_INTERACTIVE: \"Never\",\n GIT_OPTIONAL_LOCKS: \"0\",\n };\n}\n\n/**\n * Single chokepoint for every production `git` invocation. Closes stdin\n * immediately (EF-20: an interactive prompt reading from stdin gets instant\n * EOF instead of hanging on an open, unwritten pipe) and enforces a\n * command-class-scoped timeout (EF-20: no git operation can block an\n * autonomous session indefinitely with no completion signal).\n */\nexport function runGit(cwd: string, args: string[], options: RunGitOptions = {}): Promise<GitResult> {\n const commandClass = options.commandClass ?? classifyGitCommand(args);\n // Falls back to the \"write\" budget if commandClass ever reaches here as\n // something outside the GitCommandClass union (only reachable from an\n // untyped caller) -- an undefined timeoutMs would mean NO timeout at all,\n // silently defeating the one guarantee this module exists to provide.\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUTS_MS[commandClass] ?? DEFAULT_TIMEOUTS_MS.write;\n\n return new Promise((resolve, reject) => {\n const child = execFile(\n \"git\",\n args,\n {\n cwd,\n env: buildGitEnv(),\n timeout: timeoutMs,\n // SIGTERM (Node's default) rather than SIGKILL: gives git a chance\n // to run its own cleanup on POSIX, relevant to EF-20's own concern\n // about a killed operation leaving refs/locks in an uncertain state.\n // Moot on Windows -- Node docs: both map to an abrupt TerminateProcess\n // there -- but this module isn't Windows-gated.\n killSignal: \"SIGTERM\",\n windowsHide: true,\n encoding: \"utf8\",\n },\n (error, stdout, stderr) => {\n if (error) {\n if (error.killed) {\n reject(\n new GitTimeoutError(\n // NOTE: embeds the raw args, including any secrets a future\n // network-class caller might pass (e.g. a credentialed\n // clone URL). No current caller does; redact before one does.\n `git ${args.join(\" \")} timed out after ${timeoutMs}ms (class: ${commandClass})`,\n { cause: error },\n ),\n );\n return;\n }\n reject(error);\n return;\n }\n resolve({ stdout, stderr });\n },\n );\n // EF-20: never leave stdin as an open, unread pipe -- see module doc.\n child.stdin?.end();\n });\n}\n\n/**\n * Returns the repository state required before a destructive managed update.\n */\nexport async function inspectGitRepository(cwd: string): Promise<GitRepositoryState> {\n try {\n const { stdout } = await runGit(cwd, [\"rev-parse\", \"--is-inside-work-tree\"]);\n if (stdout.trim() !== \"true\") {\n return { status: \"not-repository\" };\n }\n } catch {\n return { status: \"not-repository\" };\n }\n\n try {\n await runGit(cwd, [\"rev-parse\", \"--verify\", \"HEAD\"]);\n } catch {\n return { status: \"no-commits\" };\n }\n\n const { stdout } = await runGit(cwd, [\"status\", \"--porcelain\", \"-uall\"]);\n const lines = stdout.trim();\n return {\n status: \"ready\",\n uncommittedChanges: lines.length === 0 ? 0 : lines.split(\"\\n\").length,\n };\n}\n\n/**\n * Returns the number of uncommitted changes in the working tree, or 0\n * if the directory is not a git repo or git is not installed.\n */\nexport async function countUncommittedChanges(cwd: string): Promise<number> {\n try {\n const { stdout } = await runGit(cwd, [\"status\", \"--porcelain\", \"-uall\"]);\n const lines = stdout.trim();\n return lines.length === 0 ? 0 : lines.split(\"\\n\").length;\n } catch {\n return 0;\n }\n}\n\nexport interface UnbornBranchCorrection {\n corrected: boolean;\n from?: string;\n to: \"main\";\n}\n\n/**\n * EF-05: on an unborn repository (git init has run, no commit yet) whose\n * HEAD currently targets exactly \"master\" -- the reported Git for Windows\n * system-default leak (init.defaultBranch=master at the system config\n * level) -- repoint it to \"main\" via `symbolic-ref`. Safe because no commit\n * objects exist yet to conflict with; equivalent to what `git init -b main`\n * does internally. Any OTHER branch name, including one an operator\n * deliberately chose, is left untouched -- this corrects the specific\n * reported default-leak, not a general \"Arcane requires main\" policy.\n * No-op (not corrected) if `cwd` isn't an unborn repo at all.\n */\nexport async function correctUnbornMasterDefault(cwd: string): Promise<UnbornBranchCorrection> {\n let current: string;\n try {\n const { stdout } = await runGit(cwd, [\"symbolic-ref\", \"--short\", \"HEAD\"]);\n current = stdout.trim();\n } catch {\n return { corrected: false, to: \"main\" };\n }\n\n if (current !== \"master\") {\n return { corrected: false, to: \"main\" };\n }\n\n // Verify unborn-ness internally rather than trusting the caller: on a\n // BORN repo already on \"master\", `symbolic-ref HEAD refs/heads/main`\n // would detach HEAD's branch pointer from its commit history without\n // moving any commits -- `main` would exist as an empty ref while every\n // real commit stays reachable only via the abandoned `master` ref. This\n // check is the same one `inspectGitRepository` uses to distinguish\n // \"no-commits\" from \"ready\".\n try {\n await runGit(cwd, [\"rev-parse\", \"--verify\", \"HEAD\"]);\n return { corrected: false, to: \"main\" }; // HEAD resolves -- repo is born, don't touch it\n } catch {\n // rev-parse --verify HEAD failing IS the unborn signal -- proceed.\n }\n\n // Also verify the TARGET doesn't already exist with real history.\n // Confirming the source is unborn is not sufficient: if `refs/heads/main`\n // already resolves (e.g. created earlier in this repo, or shared across\n // git worktrees -- refs/heads/* is shared while HEAD is per-worktree, so\n // an unborn \"master\" HEAD in one worktree can coexist with a fully born\n // \"main\" from another), repointing HEAD onto it would silently attach\n // whatever's currently staged/uncommitted on the unborn HEAD to main's\n // real commit history -- a history splice, not a safe unborn-HEAD\n // repoint, and the next `git commit` an operator runs would commit it.\n try {\n await runGit(cwd, [\"rev-parse\", \"--verify\", \"refs/heads/main\"]);\n return { corrected: false, to: \"main\" }; // main already exists -- don't touch it\n } catch {\n // refs/heads/main doesn't exist -- safe to make it HEAD's target.\n }\n\n await runGit(cwd, [\"symbolic-ref\", \"HEAD\", \"refs/heads/main\"]);\n return { corrected: true, from: current, to: \"main\" };\n}\n\nexport type PullRebaseResult =\n | { action: \"set\" }\n | { action: \"already-set\" }\n | { action: \"explicit-false-preserved\" };\n\n/**\n * EF-32: ensure `pull.rebase` is set at the repository-LOCAL level so the\n * mandated rebase-and-fast-forward workflow (git-conventions.md) doesn't\n * silently depend on the operator's machine-wide default (Git for Windows\n * ships pull.rebase=false at the system level). Distinguishes \"unset\n * locally\" (safe to set -- it was only ever inheriting a machine default)\n * from \"explicitly set locally, even to false\" (never silently overridden\n * -- the caller is expected to surface this as a warning instead).\n */\nexport async function ensureLocalPullRebase(cwd: string): Promise<PullRebaseResult> {\n let rawLocalValue: string | undefined;\n try {\n const { stdout } = await runGit(cwd, [\"config\", \"--local\", \"--get\", \"pull.rebase\"]);\n rawLocalValue = stdout.trim();\n } catch {\n rawLocalValue = undefined; // nothing set locally at all (may be inherited from global/system)\n }\n\n if (rawLocalValue === undefined) {\n await runGit(cwd, [\"config\", \"--local\", \"pull.rebase\", \"true\"]);\n return { action: \"set\" };\n }\n\n // Something IS set locally. Determine whether it's a falsy boolean via\n // git's own boolean parser (`--type=bool` normalizes any of git's valid\n // spellings -- true/yes/on/1 and false/no/off/0 -- to canonical\n // \"true\"/\"false\"), rather than hand-matching the literal string \"false\"\n // and missing every other valid spelling. A value `--type=bool` can't\n // coerce (e.g. \"merges\" or \"interactive\" -- both valid, deliberate\n // pull.rebase settings) means the operator explicitly chose something\n // else entirely; that's still an explicit local choice and must never be\n // overwritten, so it's treated the same as \"already-set\".\n try {\n const { stdout } = await runGit(cwd, [\"config\", \"--local\", \"--type=bool\", \"--get\", \"pull.rebase\"]);\n if (stdout.trim() === \"false\") {\n return { action: \"explicit-false-preserved\" };\n }\n return { action: \"already-set\" };\n } catch {\n return { action: \"already-set\" };\n }\n}\n","import { join } from \"node:path\";\nimport { copyFile, copyDirectory } from \"../modules/copier.js\";\nimport {\n readManifest,\n writeManifest,\n addComponent,\n hasComponent,\n ManifestNotFoundError,\n} from \"../modules/manifest.js\";\nimport { getComponent, ComponentNotFoundError } from \"../modules/registry.js\";\nimport type { InstalledComponent, SpellAddOptions } from \"../types.js\";\n\n/**\n * Runs the `spell add <component>` command.\n *\n * @param name Component name to install\n * @param options CLI flags (force, dryRun)\n * @param targetDir Directory containing the Arcane installation\n * @param assetsDir Path to the bundled assets root\n * @param packageVersion Current package version string\n */\nexport async function runAdd(\n name: string,\n options: SpellAddOptions,\n targetDir: string,\n assetsDir: string,\n packageVersion: string,\n): Promise<void> {\n // Read existing manifest (must be initialized first)\n let manifest;\n try {\n manifest = await readManifest(targetDir);\n } catch (err) {\n if (err instanceof ManifestNotFoundError) {\n console.error(\n 'Not initialized. Run \"spell init\" first before adding components.',\n );\n process.exit(1);\n return; // guard: process.exit is mocked in tests\n }\n throw err;\n }\n\n // Look up the component in the registry\n let component;\n try {\n component = getComponent(name);\n } catch (err) {\n if (err instanceof ComponentNotFoundError) {\n console.error(err.message);\n process.exit(1);\n return; // guard: process.exit is mocked in tests\n }\n throw err;\n }\n\n // Check if already installed\n if (hasComponent(manifest, name)) {\n console.log(\n `Component \"${name}\" is already installed. Use \"spell update\" to update it.`,\n );\n return;\n }\n\n // Copy files and directories\n let fileCount = 0;\n const installedFiles: string[] = [];\n for (const file of component.files) {\n const srcPath = join(assetsDir, file);\n if (options.dryRun) {\n console.log(` [dry-run] Would copy: ${file}`);\n } else {\n await copyFile(srcPath, targetDir, file, { force: options.force });\n }\n installedFiles.push(file);\n fileCount++;\n }\n for (const dir of component.directories ?? []) {\n const srcDirPath = join(assetsDir, dir);\n if (options.dryRun) {\n console.log(` [dry-run] Would copy directory: ${dir}/`);\n } else {\n const copied = await copyDirectory(srcDirPath, targetDir, dir, { force: options.force });\n installedFiles.push(...copied);\n fileCount += copied.length;\n }\n }\n\n if (options.dryRun) {\n console.log(\n `\\n[dry-run] Would add component \"${name}\" \\u2014 ${fileCount} files`,\n );\n return;\n }\n\n // Update manifest\n const newComponent: InstalledComponent = {\n name,\n files: installedFiles,\n installedVersion: packageVersion,\n };\n const updated = addComponent(manifest, newComponent);\n await writeManifest(targetDir, updated);\n\n console.log(\n `\\n\\u2713 Added component \"${name}\" \\u2014 ${fileCount} files copied`,\n );\n}\n","import { join } from \"node:path\";\nimport { copyFile, copyDirectory, fileExists } from \"../modules/copier.js\";\nimport {\n readManifest,\n writeManifest,\n ManifestNotFoundError,\n} from \"../modules/manifest.js\";\nimport { inspectGitRepository } from \"../modules/git.js\";\nimport { getComponent, ComponentNotFoundError } from \"../modules/registry.js\";\nimport { MANIFEST_RETROFITS, runManifestRetrofits, offerRegistryScaffold } from \"../modules/hub.js\";\nimport type { ArcaneManifest, InstalledComponent, SpellUpdateOptions } from \"../types.js\";\n\n/**\n * Runs the `spell update` command.\n *\n * For each installed component, looks up the current registry definition and\n * re-copies files from the current package assets. User-owned files in a\n * skipExisting component are preserved when present and backfilled when absent.\n * The manifest is updated with the new file paths so future updates remain\n * correct even when source paths change between versions.\n *\n * @param options CLI flags (dryRun)\n * @param targetDir Directory containing the Arcane installation\n * @param assetsDir Path to the bundled assets root\n * @param packageVersion Current package version string\n */\nexport async function runUpdate(\n options: SpellUpdateOptions,\n targetDir: string,\n assetsDir: string,\n packageVersion: string,\n): Promise<void> {\n // Read existing manifest\n let manifest;\n try {\n manifest = await readManifest(targetDir);\n } catch (err) {\n if (err instanceof ManifestNotFoundError) {\n console.error(\n 'Not initialized. Run \"spell init\" first before updating.',\n );\n process.exit(1);\n return; // guard: process.exit is mocked in tests\n }\n throw err;\n }\n\n console.warn(\n `WARNING: Arcane v${packageVersion} update safety notice: commit your work before updating.`,\n );\n console.warn(\n \"Updates can replace managed files. A clean committed baseline is required for recovery.\",\n );\n\n const gitState = await inspectGitRepository(targetDir);\n if (gitState.status === \"not-repository\") {\n console.error(\n \"Update refused: this directory is not a Git repository or Git is unavailable.\",\n );\n process.exit(1);\n return;\n }\n if (gitState.status === \"no-commits\") {\n console.error(\n \"Update refused: this repository has no commits. Commit the current baseline before updating.\",\n );\n process.exit(1);\n return;\n }\n if (gitState.uncommittedChanges > 0) {\n console.error(\n `Update refused: this repository has ${gitState.uncommittedChanges} uncommitted change${gitState.uncommittedChanges === 1 ? \"\" : \"s\"}. Commit or otherwise clean the working tree before updating.`,\n );\n process.exit(1);\n return;\n }\n\n // Already up to date\n if (manifest.version === packageVersion && manifest.components.length > 0) {\n console.log(\"Already up to date.\");\n return;\n }\n\n if (manifest.components.length === 0) {\n console.log(\"No components installed. Nothing to update.\");\n return;\n }\n\n let fileCount = 0;\n const updatedComponents: InstalledComponent[] = [];\n\n for (const installed of manifest.components) {\n // Look up the current registry definition (source of truth for file paths)\n let component;\n try {\n component = getComponent(installed.name);\n } catch (err) {\n if (err instanceof ComponentNotFoundError) {\n // Component removed from registry — skip but preserve manifest entry\n console.log(` ! ${installed.name} not in registry — skipping.`);\n updatedComponents.push(installed);\n continue;\n }\n throw err;\n }\n\n // Copy files using current registry paths (handles path changes between versions)\n const updatedFiles: string[] = [];\n for (const file of component.files) {\n const srcPath = join(assetsDir, file);\n const preserveExisting = component.skipExisting\n && await fileExists(join(targetDir, file));\n if (preserveExisting) {\n console.log(` ${options.dryRun ? \"[dry-run] Would preserve\" : \"Preserved\"}: ${file}`);\n } else if (options.dryRun) {\n console.log(` [dry-run] Would update: ${file}`);\n fileCount++;\n } else {\n await copyFile(srcPath, targetDir, file, { force: true });\n fileCount++;\n }\n updatedFiles.push(file);\n }\n // Also copy directories\n for (const dir of component.directories ?? []) {\n const srcDirPath = join(assetsDir, dir);\n if (options.dryRun) {\n console.log(` [dry-run] Would update directory: ${dir}/`);\n } else {\n const copied = await copyDirectory(srcDirPath, targetDir, dir, { force: true });\n updatedFiles.push(...copied);\n fileCount += copied.length;\n }\n }\n\n updatedComponents.push({\n ...installed,\n files: updatedFiles,\n installedVersion: packageVersion,\n });\n }\n\n if (options.dryRun) {\n console.log(\n `\\n[dry-run] Would update ${fileCount} files.`,\n );\n const applicableRetrofits = MANIFEST_RETROFITS.filter((r) => r.needsRetrofit(manifest));\n if (applicableRetrofits.length > 0) {\n console.log(\n `[dry-run] Would ask ${applicableRetrofits.length} manifest retrofit question${applicableRetrofits.length === 1 ? \"\" : \"s\"}: ${applicableRetrofits.map((r) => r.field).join(\", \")}.`,\n );\n }\n return;\n }\n\n // Retrofit wizard: ask about any manifest field this install predates\n // (e.g. `role`), once, before writing the updated manifest.\n const retrofitPatch = await runManifestRetrofits(manifest);\n\n // Update manifest with new version, refreshed component file paths, and\n // any retrofit answers.\n const updated: ArcaneManifest = {\n ...manifest,\n version: packageVersion,\n components: updatedComponents,\n ...retrofitPatch,\n };\n await writeManifest(targetDir, updated);\n\n console.log(\n `\\n\\u2713 Updated ${fileCount} files.`,\n );\n\n // If this update just turned the repo into a hub, offer to scaffold the\n // venture registry from whatever already exists under business_root.\n if (manifest.role !== \"hub\" && updated.role === \"hub\") {\n await offerRegistryScaffold(targetDir, updated.business_root ?? \"ventures\");\n }\n}\n","import { confirm } from \"@inquirer/prompts\";\nimport { readdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { fileExists } from \"./copier.js\";\nimport type { ArcaneManifest, HubRole } from \"../types.js\";\n\n/**\n * A manifest-field retrofit: a schema question `spell update` asks exactly\n * once, for an installed manifest that predates the field. This is a general\n * migration mechanism, not a one-off for `role` -- future manifest fields\n * register a retrofit here instead of leaving older installs permanently\n * unset.\n */\nexport interface ManifestRetrofit {\n /** Field this retrofit introduces on ArcaneManifest, for logging only. */\n field: string;\n /** True if the installed manifest predates this field and should be asked. */\n needsRetrofit(manifest: ArcaneManifest): boolean;\n /** Ask the operator; return the partial patch to merge into the manifest. */\n ask(): Promise<Partial<ArcaneManifest>>;\n}\n\nexport const MANIFEST_RETROFITS: ManifestRetrofit[] = [\n {\n field: \"role\",\n needsRetrofit: (m) => m.role === undefined,\n ask: async () => {\n const isHub = await confirm({\n message:\n \"Will this repo manage other ventures as a hub? (idea books, spell-manifest promotion, venture registry)\",\n default: false,\n });\n return { role: (isHub ? \"hub\" : \"consumer\") as HubRole };\n },\n },\n];\n\n/**\n * Runs every retrofit question the installed manifest predates, in order.\n * Returns the partial patch to merge into the manifest being written.\n * Returns {} immediately (no questions, no console output) if nothing\n * applies -- callers should only invoke this outside dry-run and\n * non-interactive modes.\n */\nexport async function runManifestRetrofits(\n manifest: ArcaneManifest,\n): Promise<Partial<ArcaneManifest>> {\n const applicable = MANIFEST_RETROFITS.filter((r) => r.needsRetrofit(manifest));\n if (applicable.length === 0) return {};\n\n console.log();\n console.log(\n `This install predates ${applicable.length} manifest field${applicable.length === 1 ? \"\" : \"s\"} -- a couple of quick questions:`,\n );\n\n let patch: Partial<ArcaneManifest> = {};\n for (const retrofit of applicable) {\n const answer = await retrofit.ask();\n patch = { ...patch, ...answer };\n }\n return patch;\n}\n\n/**\n * Offers to scaffold `{business_root}/registry.json` from existing venture\n * folders, once `role` has just become \"hub\" (via init or retrofit). Never\n * overwrites an existing registry. No-ops silently (no prompt, no output) if\n * the business root doesn't exist or holds no venture folders -- a brand new\n * hub with nothing under `ventures/` yet has nothing to scaffold.\n */\nexport async function offerRegistryScaffold(\n targetDir: string,\n businessRoot: string,\n): Promise<void> {\n const registryPath = join(targetDir, businessRoot, \"registry.json\");\n if (await fileExists(registryPath)) return;\n\n const businessRootPath = join(targetDir, businessRoot);\n let ventureDirs: string[];\n try {\n const entries = await readdir(businessRootPath, { withFileTypes: true });\n ventureDirs = entries\n .filter((e) => e.isDirectory() && e.name !== \"_template\")\n .map((e) => e.name);\n } catch {\n return;\n }\n if (ventureDirs.length === 0) return;\n\n console.log();\n const scaffold = await confirm({\n message: `Found ${ventureDirs.length} folder${ventureDirs.length === 1 ? \"\" : \"s\"} under ${businessRoot}/ -- scaffold ${businessRoot}/registry.json from them?`,\n default: true,\n });\n if (!scaffold) return;\n\n const ventures: Record<string, unknown> = {};\n for (const slug of ventureDirs) {\n const include = await confirm({ message: ` Include \"${slug}\"?`, default: true });\n if (!include) continue;\n ventures[slug] = {\n name: slug,\n aliases: [],\n status: \"active\",\n visibility: \"private\",\n ownership: \"llc\",\n tracking: \"none\",\n repos: [],\n };\n }\n if (Object.keys(ventures).length === 0) {\n console.log(\" No ventures selected -- registry not created.\");\n return;\n }\n\n const registry = {\n _comment:\n \"Hub-owned venture registry. Private. Never installed or modified by spell update. \" +\n \"Seeded by the retrofit wizard -- review and enrich (aliases, ownership, tracking, \" +\n \"clones) before relying on it.\",\n updated: new Date().toISOString().slice(0, 10),\n ventures,\n };\n await writeFile(registryPath, JSON.stringify(registry, null, 2) + \"\\n\", \"utf-8\");\n console.log(\n ` ✓ Scaffolded ${businessRoot}/registry.json with ${Object.keys(ventures).length} venture(s).`,\n );\n}\n","import { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { createRequire } from \"node:module\";\nimport type { VersionCheckResult } from \"../types.js\";\n\nconst require = createRequire(import.meta.url);\n\ninterface PackageJson {\n publishConfig?: { registry?: string };\n}\n\n/** Read the feed URL from the package's own publishConfig.registry — never hardcoded. */\nexport function getFeedUrl(): string {\n const pkg = require(\"../../package.json\") as PackageJson;\n const url = pkg.publishConfig?.registry;\n if (!url) {\n throw new Error(\n \"publishConfig.registry is not set in package.json. Cannot resolve npm feed URL.\",\n );\n }\n return url;\n}\n\nconst DEFAULT_CACHE_PATH = join(homedir(), \".arcane\", \"version-cache.json\");\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours\n\ninterface CacheEntry {\n latest: string;\n checkedAt: string;\n}\n\n/**\n * Reads the version cache file. Returns null if missing or malformed.\n */\nexport async function readCache(\n cachePath: string,\n): Promise<CacheEntry | null> {\n try {\n const content = await readFile(cachePath, \"utf-8\");\n const parsed = JSON.parse(content) as CacheEntry;\n if (typeof parsed.latest !== \"string\" || typeof parsed.checkedAt !== \"string\") {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n}\n\n/**\n * Writes the version cache file, creating parent directories as needed.\n */\nexport async function writeCache(\n cachePath: string,\n latest: string,\n): Promise<void> {\n await mkdir(dirname(cachePath), { recursive: true });\n const entry: CacheEntry = { latest, checkedAt: new Date().toISOString() };\n await writeFile(cachePath, JSON.stringify(entry, null, 2), \"utf-8\");\n}\n\n/**\n * Fetches the latest published version of arcane-cli from the public npm\n * registry. Returns null (does not throw) on any network failure.\n */\nexport async function getLatestVersion(feedUrl: string): Promise<string | null> {\n const normalizedBase = feedUrl.endsWith(\"/\") ? feedUrl : feedUrl + \"/\";\n const url = `${normalizedBase}arcane-cli`;\n try {\n const response = await fetch(url, {\n headers: { Accept: \"application/json\" },\n signal: AbortSignal.timeout(5000),\n });\n if (!response.ok) return null;\n const body = await response.json() as { \"dist-tags\"?: { latest?: string } };\n return body[\"dist-tags\"]?.latest ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Checks for a newer version of the package, using a 24h file cache.\n * Never throws — errors are captured in VersionCheckResult.error.\n */\nexport async function checkForUpdate(\n currentVersion: string,\n feedUrl: string,\n cachePath: string = DEFAULT_CACHE_PATH,\n): Promise<VersionCheckResult> {\n try {\n let latest: string | null = null;\n\n const cached = await readCache(cachePath);\n if (cached) {\n const age = Date.now() - new Date(cached.checkedAt).getTime();\n if (age < CACHE_TTL_MS) {\n latest = cached.latest;\n }\n }\n\n if (latest === null) {\n latest = await getLatestVersion(feedUrl);\n if (latest !== null) {\n try {\n await writeCache(cachePath, latest);\n } catch {\n // Cache write failure is non-fatal\n }\n }\n }\n\n return {\n current: currentVersion,\n latest,\n updateAvailable: latest !== null && latest !== currentVersion,\n };\n } catch (err) {\n return {\n current: currentVersion,\n latest: null,\n updateAvailable: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n","import {\n readManifest,\n ManifestNotFoundError,\n} from \"../modules/manifest.js\";\nimport {\n checkForUpdate,\n getFeedUrl,\n} from \"../modules/version-check.js\";\n\n/**\n * Runs the `spell status` command.\n *\n * Reads .arcane.json, checks for an available update, then prints\n * a formatted table of installed components + a version footer.\n *\n * @param targetDir Directory containing the Arcane installation\n * @param packageVersion Current package version string\n */\nexport async function runStatus(\n targetDir: string,\n packageVersion: string,\n): Promise<void> {\n // Read existing manifest\n let manifest;\n try {\n manifest = await readManifest(targetDir);\n } catch (err) {\n if (err instanceof ManifestNotFoundError) {\n console.error(\n 'Not initialized. Run \"spell init\" first.',\n );\n process.exit(1);\n return; // guard: process.exit is mocked in tests\n }\n throw err;\n }\n\n if (manifest.components.length === 0) {\n console.log(\"No components installed.\");\n return;\n }\n\n // Check for update (never throws)\n let feedUrl: string;\n try {\n feedUrl = getFeedUrl();\n } catch {\n feedUrl = \"\";\n }\n\n const versionResult = feedUrl\n ? await checkForUpdate(packageVersion, feedUrl)\n : { current: packageVersion, latest: null, updateAvailable: false, error: \"Feed URL unavailable\" };\n\n // ─── Print component table ─────────────────────────────────────────────────\n\n // Compute column widths\n const nameWidth = Math.max(\n \"Component\".length,\n ...manifest.components.map((c) => c.name.length),\n );\n const filesWidth = \"Files\".length;\n const versionWidth = Math.max(\n \"Version\".length,\n ...manifest.components.map((c) => c.installedVersion.length),\n );\n\n const pad = (s: string, n: number) => s.padEnd(n);\n const rpad = (s: string, n: number) => s.padStart(n);\n\n console.log(\n ` ${pad(\"Component\", nameWidth)} ${rpad(\"Files\", filesWidth)} ${pad(\"Version\", versionWidth)}`,\n );\n console.log(\n ` ${\"-\".repeat(nameWidth)} ${\"-\".repeat(filesWidth)} ${\"-\".repeat(versionWidth)}`,\n );\n\n for (const component of manifest.components) {\n const label = component.name;\n const fileCount = component.files.length.toString();\n const displayVersion = component.installedVersion;\n console.log(\n ` ${pad(label, nameWidth)} ${rpad(fileCount, filesWidth)} ${displayVersion}`,\n );\n }\n\n // ─── Version footer ────────────────────────────────────────────────────────\n\n console.log(\"\");\n\n const latestStr = versionResult.error\n ? \"unable to check\"\n : (versionResult.latest ?? manifest.version);\n\n let footer = ` Installed: ${packageVersion} Latest: ${latestStr}`;\n\n if (versionResult.updateAvailable) {\n footer += \" (spell update available)\";\n }\n\n console.log(footer);\n}\n","import { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { confirm } from \"@inquirer/prompts\";\nimport {\n readManifest,\n ManifestNotFoundError,\n} from \"../modules/manifest.js\";\nimport { stripMarkerSection } from \"../modules/merger.js\";\n\n/**\n * Runs the `spell uninstall` command.\n *\n * Deletes every file tracked in .arcane.json then removes .arcane.json itself.\n * Prompts for confirmation unless --yes is passed.\n *\n * @param options.yes Skip confirmation prompt\n * @param options.dryRun Preview what would be removed without deleting files\n * @param targetDir Directory containing the Arcane installation\n */\nexport async function runUninstall(\n options: { yes?: boolean; dryRun?: boolean },\n targetDir: string,\n): Promise<void> {\n // Read existing manifest\n let manifest;\n try {\n manifest = await readManifest(targetDir);\n } catch (err) {\n if (err instanceof ManifestNotFoundError) {\n console.error('Not initialized. Run \"spell init\" first.');\n process.exit(1);\n return; // guard: process.exit is mocked in tests\n }\n throw err;\n }\n\n // Count total tracked files\n const allFiles = manifest.components.flatMap((c) => c.files);\n const totalFiles = allFiles.length;\n\n // Dry-run: print what would be removed without deleting\n if (options.dryRun) {\n for (const file of allFiles) {\n console.log(`[dry-run] Would remove: ${file}`);\n }\n console.log(`[dry-run] Would remove: .arcane.json`);\n console.log(`[dry-run] Would remove: .github/agents/ (directory)`);\n console.log(`[dry-run] Would remove: .arcane/agents/ (directory)`);\n console.log(`[dry-run] Would remove: .arcane/generated/ (directory)`);\n console.log(`[dry-run] Would remove: .arcane/agents.yaml`);\n console.log(`[dry-run] Would strip arcane sections from: CLAUDE.md, AGENTS.md, copilot-instructions.md`);\n console.log(`\\n[dry-run] ${totalFiles} file(s) + manifest + agent outputs would be removed.`);\n return;\n }\n\n // Confirmation prompt (skipped with --yes)\n if (!options.yes) {\n const confirmed = await confirm({\n message: `This will remove ${totalFiles} files and .arcane.json. Continue?`,\n default: false,\n });\n\n if (!confirmed) {\n console.log(\"Uninstall cancelled.\");\n return;\n }\n }\n\n // Delete each file tracked in the manifest\n let removed = 0;\n for (const component of manifest.components) {\n for (const file of component.files) {\n const filePath = join(targetDir, file);\n try {\n await rm(filePath, { force: true });\n removed++;\n } catch {\n // Non-existent files are fine (force: true), but other errors propagate\n }\n }\n }\n\n // Delete .arcane.json\n await rm(join(targetDir, \".arcane.json\"), { force: true });\n\n // ── Clean up agent sync outputs (not tracked in manifest) ──────────────\n // Directories created by agent init/sync\n const agentDirs = [\n \".github/agents\",\n \".arcane/agents\",\n \".arcane/generated\",\n ];\n for (const dir of agentDirs) {\n await rm(join(targetDir, dir), { recursive: true, force: true });\n }\n // Roster file\n await rm(join(targetDir, \".arcane/agents.yaml\"), { force: true });\n\n // Strip arcane marker sections from merged files (keeps user content intact)\n const markerFiles = [\n \"CLAUDE.md\",\n \"AGENTS.md\",\n \".github/copilot-instructions.md\",\n ];\n for (const file of markerFiles) {\n await stripMarkerSection(targetDir, file, { dryRun: false });\n }\n\n console.log(`\\n✓ Uninstalled — ${removed} files removed.`);\n}\n","import { access, readFile, mkdir, copyFile as fsCopyFile } from \"node:fs/promises\";\nimport { join, dirname } from \"node:path\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { INCIDENT_QUEUE } from \"../config/incidents.js\";\nimport { evaluateIncidentGate } from \"../modules/incident-gate.js\";\nimport { runGit } from \"../modules/git.js\";\n\nconst execFileAsync = promisify(execFile);\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\ninterface CheckResult {\n name: string;\n passed: boolean;\n message: string;\n /** If false, this is a warning, not a blocker. Defaults to true (blocking). */\n blocking?: boolean;\n}\n\n// ─── Individual checks ────────────────────────────────────────────────────────\n\nasync function checkNodeVersion(): Promise<CheckResult> {\n const name = \"Node.js version\";\n const raw = process.version; // e.g. \"v20.11.0\"\n const major = parseInt(raw.replace(/^v/, \"\").split(\".\")[0] ?? \"0\", 10);\n if (major >= 18) {\n return { name, passed: true, message: `${raw} (>=18 required)` };\n }\n return {\n name,\n passed: false,\n message: `${raw} — Node.js 18 or later is required`,\n };\n}\n\nasync function checkVSCodeExtension(\n id: string,\n label: string,\n): Promise<CheckResult> {\n const name = `VS Code extension: ${label}`;\n // Check extension directories on disk — more reliable than --list-extensions\n // in child process contexts (snap binaries may not output to non-TTY stdout).\n const home = process.env[\"HOME\"] ?? \"\";\n const extDirs = [\n join(home, \".vscode\", \"extensions\"),\n join(home, \".vscode-insiders\", \"extensions\"),\n ];\n\n for (const dir of extDirs) {\n try {\n const { readdir } = await import(\"node:fs/promises\");\n const entries = await readdir(dir);\n const prefix = id.toLowerCase() + \"-\";\n const found = entries.some(\n (e) => e.toLowerCase() === id.toLowerCase() || e.toLowerCase().startsWith(prefix),\n );\n if (found) {\n return { name, passed: true, message: `${id} is installed` };\n }\n } catch {\n // Directory doesn't exist — skip\n }\n }\n\n // Determine install command (prefer code-insiders if present)\n let installBin = \"code\";\n for (const bin of [\"code\", \"code-insiders\"]) {\n try {\n await execFileAsync(bin, [\"--version\"]);\n installBin = bin;\n break;\n } catch {\n // not found\n }\n }\n\n return {\n name,\n passed: false,\n message: `${id} not found. Install via: ${installBin} --install-extension ${id}`,\n blocking: false,\n };\n}\n\nexport async function checkArcaneManifest(targetDir: string): Promise<CheckResult> {\n const name = \"Arcane manifest (.arcane.json)\";\n const manifestPath = join(targetDir, \".arcane.json\");\n try {\n await access(manifestPath);\n } catch {\n const selfHostedManifestPath = join(targetDir, \"src\", \"assets\", \".arcane.json\");\n try {\n const raw = await readFile(selfHostedManifestPath, \"utf8\");\n const manifest = JSON.parse(raw) as {\n selfHosted?: boolean;\n tracking_mode?: string;\n };\n if (manifest.selfHosted === true && manifest.tracking_mode === \"internal\") {\n return {\n name,\n passed: true,\n message: \"self-hosted source tree — committed source manifest is authoritative\",\n };\n }\n } catch {\n // No valid self-hosting marker — report the normal missing-manifest warning.\n }\n return {\n name,\n passed: false,\n message: \"No .arcane.json found. Run `spell init` to initialize Arcane in this project.\",\n blocking: false,\n };\n }\n\n try {\n const raw = await readFile(manifestPath, \"utf8\");\n const manifest = JSON.parse(raw) as { version?: string; components?: unknown[] };\n if (!manifest.version || !Array.isArray(manifest.components)) {\n return {\n name,\n passed: false,\n message: \".arcane.json is present but missing required fields (version, components). Re-run `spell init`.\",\n };\n }\n return {\n name,\n passed: true,\n message: `v${manifest.version} — ${manifest.components.length} component(s) installed`,\n };\n } catch {\n return {\n name,\n passed: false,\n message: \".arcane.json is present but contains invalid JSON. Re-run `spell init`.\",\n };\n }\n}\n\n/**\n * EF-32: independently verify the EFFECTIVE (not just repository-local)\n * pull.rebase resolves to \"true\", catching drift regardless of source --\n * an install that predates `spell init`'s own fix, a value unset again\n * later, or any other path that bypassed init's one-time correction.\n * Non-blocking: this repo has no CI job running inside the operator's own\n * working copy, so a doctor warning is the only enforcement mode available\n * here (see ARC-023's inline-enforcement-contract requirement).\n */\nexport async function checkPullRebase(targetDir: string): Promise<CheckResult> {\n const name = \"Git pull.rebase (rebase-and-fast-forward mandate)\";\n try {\n // --type=bool normalizes any of git's valid boolean spellings\n // (true/yes/on/1, false/no/off/0) to canonical \"true\"/\"false\" -- a raw\n // string comparison against \"true\" alone would false-positive-warn on\n // a fully compliant \"yes\"/\"on\"/\"1\".\n const { stdout } = await runGit(targetDir, [\"config\", \"--type=bool\", \"--get\", \"pull.rebase\"]);\n const value = stdout.trim();\n if (value === \"true\") {\n return { name, passed: true, message: \"pull.rebase=true\" };\n }\n return {\n name,\n passed: false,\n message: `pull.rebase resolves to \"${value}\", not \"true\" -- a bare \\`git pull\\` will create merge commits, contradicting git-conventions.md's rebase-and-fast-forward mandate. Run: git config --local pull.rebase true`,\n blocking: false,\n };\n } catch {\n // Two cases collapse here: unset entirely, or set to a non-boolean\n // value (e.g. \"merges\") --type=bool can't coerce -- both mean\n // \"not affirmatively true\", which is what this check cares about.\n return {\n name,\n passed: false,\n message: \"pull.rebase is unset, not a recognized boolean, or this isn't a Git repository -- effective behavior may not be rebase-and-fast-forward, and Git for Windows defaults this to false when unset. Run: git config --local pull.rebase true\",\n blocking: false,\n };\n }\n}\n\nexport function checkIncidentReleaseGate(): CheckResult {\n const result = evaluateIncidentGate(INCIDENT_QUEUE);\n if (result.blocked) {\n return {\n name: \"Incident release gate (ARC-024)\",\n passed: false,\n message: result.blockers.join(\"; \"),\n };\n }\n const accepted = result.acceptedRisks.length > 0\n ? `; ${result.acceptedRisks.length} explicitly deferred`\n : \"\";\n return {\n name: \"Incident release gate (ARC-024)\",\n passed: true,\n message: `${result.checked} incidents classified${accepted}`,\n };\n}\n\n// ─── Session continuity checks ────────────────────────────────────────────────\n\n/** Files required for spell-close-session / spell-open-session to function. */\nexport const SESSION_CONTINUITY_FILES = [\n \"TODO.md\",\n \"DECISIONS.md\",\n \"ai-context/system-prompt-context.md\",\n \"journal/.gitkeep\",\n];\n\nexport async function checkSessionContinuity(targetDir: string): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n\n for (const file of SESSION_CONTINUITY_FILES) {\n const name = `Session file: ${file}`;\n const filePath = join(targetDir, file);\n try {\n await access(filePath);\n results.push({ name, passed: true, message: \"present\" });\n } catch {\n results.push({\n name,\n passed: false,\n message: `Missing. Required for spell-close-session. Run \\`spell doctor --fix\\` to create it.`,\n blocking: false,\n });\n }\n }\n\n return results;\n}\n\nexport async function fixSessionContinuity(targetDir: string, assetsDir: string): Promise<string[]> {\n const created: string[] = [];\n\n for (const file of SESSION_CONTINUITY_FILES) {\n const destPath = join(targetDir, file);\n try {\n await access(destPath);\n // File exists — skip\n } catch {\n // File missing — create from template\n const srcPath = join(assetsDir, file);\n await mkdir(dirname(destPath), { recursive: true });\n await fsCopyFile(srcPath, destPath);\n created.push(file);\n }\n }\n\n return created;\n}\n\n// ─── Main ─────────────────────────────────────────────────────────────────────\n\nexport interface DoctorOptions {\n fix?: boolean;\n}\n\nexport async function runDoctor(targetDir: string, options: DoctorOptions = {}, assetsDir?: string): Promise<void> {\n console.log(\"\\nspell doctor — checking your Arcane environment\\n\");\n\n const results = await Promise.all([\n checkNodeVersion(),\n checkVSCodeExtension(\"GitHub.copilot-chat\", \"GitHub Copilot (Chat)\"),\n checkArcaneManifest(targetDir),\n Promise.resolve(checkIncidentReleaseGate()),\n checkPullRebase(targetDir),\n ]);\n\n // Add session continuity checks\n const sessionResults = await checkSessionContinuity(targetDir);\n results.push(...sessionResults);\n\n let allPassed = true;\n\n for (const result of results) {\n const icon = result.passed ? \"✓\" : result.blocking === false ? \"⚠\" : \"✗\";\n const label = result.passed\n ? \"pass\"\n : result.blocking === false\n ? \"warn\"\n : \"FAIL\";\n console.log(` ${icon} [${label}] ${result.name}`);\n if (!result.passed) {\n console.log(` ${result.message}`);\n }\n if (!result.passed && result.blocking !== false) {\n allPassed = false;\n }\n }\n\n console.log();\n\n if (allPassed) {\n console.log(\" All checks passed. Your environment is ready.\\n\");\n } else {\n console.log(\" One or more checks failed. Fix the issues above before proceeding.\\n\");\n\n // --fix: remediate missing session continuity files\n const hasMissingSession = sessionResults.some((r) => !r.passed);\n if (options.fix && hasMissingSession && assetsDir) {\n console.log(\" 🔧 Fixing missing session continuity files...\\n\");\n const created = await fixSessionContinuity(targetDir, assetsDir);\n if (created.length > 0) {\n for (const file of created) {\n console.log(` ✓ Created: ${file}`);\n }\n console.log(`\\n ${created.length} file(s) created. Repo is now close-session-ready.\\n`);\n } else {\n console.log(\" No files needed creation (all present).\\n\");\n }\n } else if (hasMissingSession && !options.fix) {\n console.log(\" 💡 Run `spell doctor --fix` to create missing session files.\\n\");\n }\n\n if (!allPassed) {\n process.exitCode = 1;\n }\n }\n}\n","export type IncidentSeverity = \"critical\" | \"high\" | \"medium\" | \"low\";\nexport type IncidentImpact = \"data-integrity\" | \"security\" | \"other\";\nexport type IncidentConfidence = \"confirmed\" | \"research\";\nexport type IncidentState = \"open\" | \"resolved\" | \"deferred\";\n\nexport interface IncidentRecord {\n id: string;\n severity?: IncidentSeverity;\n impact: IncidentImpact;\n confidence: IncidentConfidence;\n state: IncidentState;\n detectedOn: string;\n resolution?: string;\n deferral?: string;\n}\n\nexport const INCIDENT_QUEUE: IncidentRecord[] = [\n { id: \"EF-05\", severity: \"medium\", impact: \"other\", confidence: \"confirmed\", state: \"open\", detectedOn: \"2026-07-31\" },\n { id: \"EF-08\", severity: \"medium\", impact: \"other\", confidence: \"confirmed\", state: \"open\", detectedOn: \"2026-07-31\" },\n { id: \"EF-16\", severity: \"high\", impact: \"other\", confidence: \"confirmed\", state: \"open\", detectedOn: \"2026-07-31\" },\n { id: \"EF-17\", severity: \"high\", impact: \"other\", confidence: \"confirmed\", state: \"open\", detectedOn: \"2026-07-31\" },\n { id: \"EF-20\", severity: \"high\", impact: \"other\", confidence: \"research\", state: \"open\", detectedOn: \"2026-07-31\" },\n { id: \"EF-21\", severity: \"high\", impact: \"other\", confidence: \"confirmed\", state: \"open\", detectedOn: \"2026-07-31\" },\n { id: \"EF-23\", severity: \"medium\", impact: \"other\", confidence: \"confirmed\", state: \"open\", detectedOn: \"2026-07-31\" },\n { id: \"EF-25\", severity: \"high\", impact: \"data-integrity\", confidence: \"confirmed\", state: \"resolved\", detectedOn: \"2026-07-14\", resolution: \"PRs 13 and 14\" },\n { id: \"EF-26\", severity: \"high\", impact: \"security\", confidence: \"confirmed\", state: \"resolved\", detectedOn: \"2026-07-31\", resolution: \"PR 15\" },\n { id: \"EF-27\", severity: \"high\", impact: \"security\", confidence: \"confirmed\", state: \"resolved\", detectedOn: \"2026-07-31\", resolution: \"PR 16\" },\n { id: \"EF-28\", severity: \"high\", impact: \"security\", confidence: \"confirmed\", state: \"resolved\", detectedOn: \"2026-07-31\", resolution: \"PR 17\" },\n { id: \"EF-29\", severity: \"medium\", impact: \"other\", confidence: \"confirmed\", state: \"resolved\", detectedOn: \"2026-07-31\", resolution: \"PR 18\" },\n];","import type { IncidentRecord } from \"../config/incidents.js\";\n\nconst DEFERRAL_PATTERN = /^Deferred \\d{4}-\\d{2}-\\d{2} — known open, accepting the risk\\.$/;\nconst BLOCKING_SEVERITIES = new Set([\"critical\", \"high\"]);\nconst PROTECTED_IMPACTS = new Set([\"data-integrity\", \"security\"]);\n\nexport interface IncidentGateResult {\n blocked: boolean;\n blockers: string[];\n acceptedRisks: string[];\n checked: number;\n}\n\nexport function evaluateIncidentGate(records: IncidentRecord[]): IncidentGateResult {\n const blockers: string[] = [];\n const acceptedRisks: string[] = [];\n const seen = new Set<string>();\n\n for (const record of records) {\n if (seen.has(record.id)) {\n blockers.push(`${record.id}: duplicate incident record`);\n continue;\n }\n seen.add(record.id);\n\n if (record.confidence === \"research\") continue;\n if (!PROTECTED_IMPACTS.has(record.impact)) continue;\n\n if (!record.severity) {\n blockers.push(`${record.id}: confirmed ${record.impact} incident is missing severity`);\n continue;\n }\n if (!BLOCKING_SEVERITIES.has(record.severity)) continue;\n\n if (record.state === \"resolved\") {\n if (!record.resolution?.trim()) {\n blockers.push(`${record.id}: resolved incident is missing resolution evidence`);\n }\n continue;\n }\n\n if (record.state === \"deferred\") {\n if (!record.deferral || !DEFERRAL_PATTERN.test(record.deferral)) {\n blockers.push(\n `${record.id}: deferral must be exactly \"Deferred <date> — known open, accepting the risk.\"`,\n );\n } else {\n acceptedRisks.push(`${record.id}: ${record.deferral}`);\n }\n continue;\n }\n\n blockers.push(\n `${record.id}: unresolved ${record.severity} ${record.impact} incident blocks release`,\n );\n }\n\n return {\n blocked: blockers.length > 0,\n blockers,\n acceptedRisks,\n checked: records.length,\n };\n}"],"mappings":";;;;;AAAA,SAAS,eAAe;AACxB,SAAS,iBAAAA,sBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,WAAAC,UAAS,QAAAC,cAAY;;;ACH9B,SAAS,UAAAC,SAAQ,eAAe;AAChC,SAAS,QAAAC,aAAY;AACrB,OAAOC,YAAW;;;ACFlB;AAAA,EACE;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,OACK;AACP,OAAO,UAAU;AAMV,SAAS,mBACd,WACA,cACM;AACN,QAAM,eAAe,KAAK,QAAQ,SAAS;AAC3C,QAAM,eAAe,KAAK,QAAQ,WAAW,YAAY;AAEzD,MACE,iBAAiB,gBACjB,CAAC,aAAa,WAAW,eAAe,KAAK,GAAG,GAChD;AACA,UAAM,IAAI;AAAA,MACR,6BAA6B,YAAY,+BAA+B,SAAS;AAAA,IACnF;AAAA,EACF;AACF;AAKA,eAAsB,UAAU,SAAgC;AAC9D,QAAM,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;AAC1C;AAEA,eAAsB,WAAW,UAAoC;AACnE,MAAI;AACF,UAAM,OAAO,QAAQ;AACrB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAOA,eAAsB,SACpB,SACA,WACA,cACA,OAA4B,CAAC,GACd;AACf,qBAAmB,WAAW,YAAY;AAE1C,QAAM,WAAW,KAAK,QAAQ,WAAW,YAAY;AACrD,QAAM,UAAU,KAAK,QAAQ,QAAQ,CAAC;AAEtC,MAAI,CAAC,KAAK,SAAU,MAAM,WAAW,QAAQ,GAAI;AAC/C,UAAM,IAAI;AAAA,MACR,gCAAgC,YAAY;AAAA,IAC9C;AAAA,EACF;AAEA,QAAM,WAAW,SAAS,QAAQ;AACpC;AAOA,eAAsB,cACpB,QACA,WACA,aACA,OAA4B,CAAC,GACV;AACnB,qBAAmB,WAAW,WAAW;AAEzC,QAAM,cAAwB,CAAC;AAC/B,QAAM,UAAU,MAAM,QAAQ,QAAQ,EAAE,eAAe,KAAK,CAAC;AAE7D,aAAW,SAAS,SAAS;AAC3B,UAAM,eAAe,KAAK,KAAK,QAAQ,MAAM,IAAI;AACjD,UAAM,eAAe,GAAG,WAAW,IAAI,MAAM,IAAI;AAEjD,QAAI,MAAM,YAAY,GAAG;AACvB,YAAM,WAAW,MAAM,cAAc,cAAc,WAAW,cAAc,IAAI;AAChF,kBAAY,KAAK,GAAG,QAAQ;AAAA,IAC9B,OAAO;AACL,YAAM,SAAS,cAAc,WAAW,cAAc,IAAI;AAC1D,kBAAY,KAAK,YAAY;AAAA,IAC/B;AAAA,EACF;AAEA,SAAO;AACT;;;ACpGA,SAAS,UAAU,iBAAiB;AACpC,OAAOC,WAAU;AAOV,IAAM,wBAAN,cAAoC,MAAM;AAAA,EAC/C,YAAYC,eAAsB;AAChC,UAAM,0BAA0BA,aAAY,4BAA4B;AACxE,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAC9C,YAAYA,eAAsB;AAChC;AAAA,MACE,gBAAgBA,aAAY;AAAA,IAC9B;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEA,IAAM,gBAAgB;AAEtB,SAAS,aAAa,WAA2B;AAC/C,SAAOD,MAAK,KAAK,WAAW,aAAa;AAC3C;AAOA,eAAsB,aAAa,WAA4C;AAC7E,QAAM,WAAW,aAAa,SAAS;AACvC,MAAI;AAEJ,MAAI;AACF,cAAU,MAAM,SAAS,UAAU,OAAO;AAAA,EAC5C,SAAS,KAAK;AACZ,QAAK,IAA8B,SAAS,UAAU;AACpD,YAAM,IAAI,sBAAsB,QAAQ;AAAA,IAC1C;AACA,UAAM;AAAA,EACR;AAEA,MAAI;AACF,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,UAAM,IAAI,qBAAqB,QAAQ;AAAA,EACzC;AACF;AAKA,eAAsB,cACpB,WACA,UACe;AACf,QAAM,WAAW,aAAa,SAAS;AACvC,QAAM,UAAU,UAAU,KAAK,UAAU,UAAU,MAAM,CAAC,GAAG,OAAO;AACtE;AAyBO,SAAS,aACd,UACA,WACgB;AAChB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,YAAY,CAAC,GAAG,SAAS,YAAY,SAAS;AAAA,EAChD;AACF;AAmBO,SAAS,aAAa,UAA0B,MAAuB;AAC5E,SAAO,SAAS,WAAW,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACxD;;;AC9FO,IAAM,kBAAmC;AAAA,EAC9C;AAAA,IACE,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,YAAY;AAAA,EACd;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,YAAY,CAAC,iBAAiB,mBAAmB,6BAA6B,mBAAmB,qBAAqB,uBAAuB,oBAAoB;AAAA,EACnK;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,YAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,YAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;AChFO,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAChD,YAAY,MAAc,WAAqB;AAC7C;AAAA,MACE,cAAc,IAAI,sCAAsC,UAAU,KAAK,IAAI,CAAC;AAAA,IAC9E;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAKA,IAAM,aAAkC;AAAA;AAAA,EAEtC;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,uCAAuC;AAAA,EACjD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,yCAAyC;AAAA,EACnD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,2CAA2C;AAAA,EACrD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,uDAAuD;AAAA,EACjE;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,8CAA8C;AAAA,EACxD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,0CAA0C;AAAA,EACpD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,sCAAsC;AAAA,EAChD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,oCAAoC;AAAA,EAC9C;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,2CAA2C;AAAA,EACrD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,+CAA+C;AAAA,EACzD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,0CAA0C;AAAA,EACpD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,4CAA4C;AAAA,EACtD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,0CAA0C;AAAA,EACpD;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,+CAA+C;AAAA,EACzD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,sCAAsC;AAAA,EAChD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,8CAA8C;AAAA,EACxD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,oDAAoD;AAAA,EAC9D;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,iDAAiD;AAAA,EAC3D;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,4CAA4C;AAAA,EACtD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,6CAA6C;AAAA,EACvD;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,mDAAmD;AAAA,EAC7D;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,cAAc;AAAA,IACd,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAIA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,CAAC,2CAA2C;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAAS,kBAA6C;AACpD,QAAM,WAAW,WAAW,IAAI,CAAC,MAAM,EAAE,IAAI;AAC7C,QAAM,MAAM,CAAC;AACb,aAAW,UAAU,iBAAiB;AACpC,QAAI,OAAO,EAAE,IAAI,OAAO,eAAe,MAAM,WAAW,OAAO;AAAA,EACjE;AACA,SAAO;AACT;AAEA,IAAM,cAAc,gBAAgB;AAIpC,IAAM,iBAAiB,IAAI,IAAI,WAAW,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAM1D,SAAS,aAAa,MAAiC;AAC5D,QAAM,YAAY,eAAe,IAAI,IAAI;AACzC,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,uBAAuB,MAAM,MAAM,KAAK,eAAe,KAAK,CAAC,CAAC;AAAA,EAC1E;AACA,SAAO;AACT;AAKO,SAAS,WAAW,SAAuC;AAChE,SAAO,YAAY,OAAO,EAAE,IAAI,CAAC,SAAS,aAAa,IAAI,CAAC;AAC9D;AAaO,SAAS,eAAoC;AAClD,QAAM,WAAW,WAAW,IAAI,CAAC,MAAM,EAAE,IAAI;AAC7C,SAAO,gBAAgB,IAAI,CAAC,YAAY;AAAA,IACtC,IAAI,OAAO;AAAA,IACX,aAAa,OAAO;AAAA,IACpB,aAAa,OAAO;AAAA,IACpB,YACE,OAAO,eAAe,MAAM,CAAC,GAAG,QAAQ,IAAI,CAAC,GAAG,OAAO,UAAU;AAAA,EACrE,EAAE;AACJ;;;AC9SA,OAAO,WAAW;AAClB,OAAO,cAAc;AAGrB,IAAM,UAAU;AAGhB,IAAM,QAAQ;AACd,IAAM,aAAa;AACnB,IAAM,YAAY;AAClB,IAAM,YAAY;AAClB,IAAM,QAAQ;AAEd,IAAM,QAAQ,CAAC,WAAW,WAAW,WAAW,SAAS;AACzD,IAAM,iBAAiB,SAAS,KAAK;AAGrC,IAAM,WAAW;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,IAAM,SAAS;AACf,IAAM,eAAe,OAAO,SAAS,KAAK,IAAI,GAAG,SAAS,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;AAE9E,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAGA,SAAS,eAAwB;AAC/B,SACE,CAAC,CAAC,QAAQ,OAAO,SACjB,QAAQ,IAAI,MAAM,MAAM,UACxB,QAAQ,IAAI,IAAI,MAAM,UACtB,QAAQ,IAAI,0BAA0B,MAAM,WAC3C,QAAQ,OAAO,WAAW,OAAO;AAEtC;AAGA,SAAS,MAAM,KAAa,GAAmB;AAC7C,QAAM,IAAI,CAAC,MACT,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,SAAS,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;AAC9E,SAAO,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AACrF;AAGA,SAAS,YAAY,IAAI,GAAa;AACpC,QAAM,IAAI,KAAK,IAAI,iBAAiB,SAAS,MAAM,IAAI,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC;AAC1E,SAAO,SAAS,IAAI,CAAC,SAAS,SAAS,EAAE,IAAI,CAAC;AAChD;AAEA,SAAS,YAAY,SAAuB;AAC1C,QAAM,cAAc,KAAK,OAAO,iCAA2B,OAAO;AAClE,QAAM,QAAQ,KAAK,IAAI,cAAc,YAAY,MAAM;AACvD,QAAM,SAAS,MAAM,IAAI,UAAU,EAAE,SAAI,OAAO,KAAK,CAAC;AACtD,UAAQ,IAAI,MAAM;AAClB,UAAQ;AAAA,IACN,MAAM,IAAI,KAAK,EAAE,KAAK,OAAO,EAAE;AAAA,IAC/B,MAAM,IAAI,SAAS,EAAE,gCAA0B,OAAO,EAAE;AAAA,EAC1D;AACA,UAAQ,IAAI,MAAM;AACpB;AAmBA,SAAS,eAAe,YAA6C;AACnE,QAAM,QAAQ,WAAW;AAAA,IAAQ,CAAC,MAChC,EAAE,MAAM,IAAI,CAAC,MAAM,EAAE,QAAQ,OAAO,GAAG,CAAC;AAAA,EAC1C;AACA,QAAM,SAAS,IAAI;AAAA,IACjB,MACG,OAAO,CAAC,MAAM,sCAAsC,KAAK,CAAC,CAAC,EAC3D,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,EAAE,IAAI,EAAG,QAAQ,uBAAuB,EAAE,CAAC;AAAA,EACtE,EAAE;AACF,QAAM,SAAS,MAAM,OAAO,CAAC,MAAM,8BAA8B,KAAK,CAAC,CAAC,EAAE;AAC1E,QAAM,YAAY,MAAM;AAAA,IAAO,CAAC,MAC9B,2BAA2B,KAAK,CAAC;AAAA,EACnC,EAAE;AACF,QAAM,QAAkB,CAAC;AACzB,MAAI,OAAQ,OAAM,KAAK,GAAG,MAAM,SAAS,WAAW,IAAI,KAAK,GAAG,EAAE;AAClE,MAAI,OAAQ,OAAM,KAAK,GAAG,MAAM,SAAS,WAAW,IAAI,KAAK,GAAG,EAAE;AAClE,MAAI,UAAW,OAAM,KAAK,GAAG,SAAS,YAAY,cAAc,IAAI,KAAK,GAAG,EAAE;AAC9E,SAAO;AACT;AASA,eAAsB,aAAa,SAAiB,KAA4B;AAC9E,UAAQ,IAAI;AACZ,MAAI,aAAa,GAAG;AAClB,UAAM,OAAO,CAAC,OAAiB,WAA0B;AACvD,UAAI,OAAQ,SAAQ,OAAO,MAAM,QAAQ,MAAM,MAAM,GAAG;AACxD,iBAAW,QAAQ,MAAO,SAAQ,OAAO,MAAM,YAAY,IAAI;AAAA,CAAI;AAAA,IACrE;AAEA,UAAM,OAAO,CAAC,KAAK,MAAM,MAAM,MAAM,MAAM,MAAM,CAAC;AAClD,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,WAAK,YAAY,KAAK,CAAC,CAAE,GAAG,IAAI,CAAC;AACjC,YAAM,MAAM,EAAE;AAAA,IAChB;AAEA,UAAM,QAAQ,CAAC,GAAG,KAAK,MAAM,KAAK,CAAC;AACnC,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,WAAK,YAAY,MAAM,CAAC,CAAE,GAAG,IAAI;AACjC,YAAM,MAAM,GAAG;AAAA,IACjB;AAAA,EACF,OAAO;AACL,eAAW,QAAQ,YAAY,EAAG,SAAQ,IAAI,IAAI;AAAA,EACpD;AACA,cAAY,OAAO;AACnB,UAAQ,IAAI;AAEZ,QAAM,QAAQ,CAAC,MAAsB,MAAM,IAAI,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC;AACtE,QAAM,MAAM,MAAM,IAAI,KAAK,EAAE,MAAG;AAEhC,MAAI;AACJ,MAAI;AACF,UAAM,WAAW,MAAM,aAAa,GAAG;AACvC,UAAM,QAAQ,eAAe,SAAS,UAAU;AAChD,UAAM,UAAU,MAAM,SAClB,QACA,CAAC,GAAG,SAAS,WAAW,MAAM,aAAa;AAC/C,eACE,GAAG,MAAM,IAAI,KAAK,EAAE,QAAG,CAAC,WAAW,MAAM,IAAI,SAAS,EAAE,OAAI,SAAS,OAAO,MAAG,CAAC,IAAI,GAAG,MACvF,QAAQ,IAAI,CAAC,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC,CAAC,EAAE,KAAK,IAAI,GAAG,GAAG,IAC3D,IAAI,GAAG,IAAI,MAAM,IAAI,SAAS,EAAE,IAAI,SAAS,OAAO,EAAE,CAAC;AAAA,EAC3D,QAAQ;AACN,eACE,GAAG,MAAM,IAAI,SAAS,EAAE,QAAG,CAAC,oBAAoB,MAAM,IAAI,KAAK,EAAE,QAAG,CAAC,QAClE,MAAM,IAAI,KAAK,EAAE,QAAQ,cAAc,CAAC,IAAI,MAAM,IAAI,SAAS,EAAE,aAAa,CAAC;AAAA,EACtF;AACA,UAAQ,IAAI,KAAK,MAAM,WAAW,CAAC,GAAG,QAAQ,EAAE;AAEhD,QAAM,SAAS,CAAC,QAAQ,aAAa,aAAa,QAAQ,UAAU,MAAM,EAAE;AAAA,IAC1E,MAAM,IAAI,UAAU,EAAE,UAAK;AAAA,EAC7B;AACA,UAAQ,IAAI,KAAK,MAAM,YAAY,CAAC,GAAG,MAAM,IAAI,SAAS,EAAE,MAAM,CAAC,EAAE;AAGrE,QAAM,OAAO,CAAC,QAAQ,aAAa,aAAa,QAAQ,UAAU,MAAM,EAAE,KAAK,UAAK;AACpF,QAAM,YAAY,KAAK,KAAK,QAAQ,WAAW;AAC/C,QAAM,UAAU,KAAK,KAAK,QAAQ,QAAQ,IAAI;AAC9C,QAAM,QAAQ,UAAU,YAAY;AACpC,QAAM,KAAK,KAAK,OAAO,QAAQ,MAAM,CAAC;AACtC,QAAM,KAAK,QAAQ,KAAK;AACxB,QAAM,OAAO,CAAC,MAAsB,MAAM,IAAI,UAAU,EAAE,SAAI,OAAO,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC;AACpF,UAAQ;AAAA,IACN,IAAI,OAAO,SAAS,IAClB,MAAM,IAAI,UAAU,EAAE,QAAG,IACzB,KAAK,EAAE,IACP,MAAM,IAAI,KAAK,EAAE,UAAK,IACtB,MAAM,IAAI,SAAS,EAAE,iBAAiB,IACtC,MACA,KAAK,EAAE,IACP,MAAM,IAAI,UAAU,EAAE,QAAG;AAAA,EAC7B;AACA,UAAQ,IAAI;AACd;AAEO,SAAS,aAAa,SAAuB;AAClD,UAAQ,IAAI;AAAA,EAAK,MAAM,IAAI,KAAK,EAAE,QAAG,CAAC,IAAI,MAAM,KAAK,OAAO,CAAC,EAAE;AACjE;AAEO,SAAS,UAAU,SAAuB;AAC/C,UAAQ,IAAI,KAAK,MAAM,IAAI,UAAU,EAAE,QAAG,CAAC,IAAI,OAAO,EAAE;AAC1D;AAEO,SAAS,YAAY,SAAuB;AACjD,UAAQ,IAAI,KAAK,MAAM,OAAO,QAAG,CAAC,IAAI,MAAM,IAAI,OAAO,CAAC,EAAE;AAC5D;AAEO,SAAS,aAAa,OAAqB;AAChD,UAAQ,IAAI;AAAA,EAAK,MAAM,IAAI,KAAK,EAAE,QAAG,CAAC,IAAI,MAAM,KAAK,KAAK,CAAC,EAAE;AAC/D;AAEO,SAAS,UAAU,SAAuB;AAC/C,UAAQ,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,EAAE;AACvC;AAEO,SAAS,cAAc,MAAc,SAAuB;AACjE,UAAQ,IAAI,KAAK,MAAM,IAAI,UAAU,EAAE,GAAG,IAAI,GAAG,CAAC,IAAI,OAAO,EAAE;AACjE;AAEO,SAAS,aAAa,SAAuB;AAClD,UAAQ,IAAI,KAAK,MAAM,OAAO,QAAG,CAAC,KAAK,MAAM,OAAO,OAAO,CAAC,EAAE;AAChE;;;ACzMA,SAAS,QAAQ,UAAU,iBAAiB;AAC5C,SAAS,SAAAE,QAAO,aAAAC,YAAW,YAAAC,iBAAgB;AAC3C,SAAS,QAAAC,aAAY;AACrB,SAAS,iBAAiB;;;ACEnB,IAAM,cAAiC;AAAA,EAC5C;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AACF;AAGO,SAAS,aAAa,IAAyC;AACpE,SAAO,YAAY,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAC5C;;;AChEO,IAAM,wBAA8C;AAAA,EACzD;AAAA,IACE,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,OAAO,CAAC,gBAAgB,qBAAqB,iBAAiB,SAAS;AAAA,EACzE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,OAAO,CAAC;AAAA;AAAA,EACV;AACF;AAGO,SAAS,sBAAsB,IAAwC;AAC5E,QAAM,SAAS,sBAAsB,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAC5D,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,2BAA2B,EAAE,GAAG;AAC7D,SAAO;AACT;;;AC7CA,SAAS,aAAa;AAOtB,IAAM,mBAA2C;AAAA,EAC/C,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,gBAAgB;AAClB;AAKA,IAAM,mBAA2C;AAAA,EAC/C,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,gBAAgB;AAClB;AAQA,IAAM,mBAA6B;AAAA,EACjC;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAU;AAAA,EAAQ;AAAA,EAC9D;AAAA,EAAU;AAAA,EAAU;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAC7D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAC3D;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAS;AAAA,EAAW;AAC/C;AAUO,SAAS,kBAAkB,SAAmC;AACnE,SAAO,QAAQ,IAAI,CAAC,QAAQ;AAAA,IAC1B,YAAY;AAAA,IACZ,MAAM,iBAAiB,EAAE,KAAK;AAAA,EAChC,EAAE;AACJ;AAGO,SAAS,kBAAkB,SAAmC;AACnE,SAAO,QAAQ,IAAI,CAAC,QAAQ;AAAA,IAC1B,YAAY;AAAA,IACZ,MAAM,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,KAAK;AAAA,EACxD,EAAE;AACJ;AAMO,SAAS,iBAAiB,SAAmC;AAClE,QAAM,WAAW,CAAC,GAAG,gBAAgB,EAAE,KAAK,MAAM,KAAK,OAAO,IAAI,GAAG;AACrE,SAAO,QAAQ,IAAI,CAAC,IAAI,OAAO;AAAA,IAC7B,YAAY;AAAA,IACZ,MAAM,SAAS,IAAI,SAAS,MAAM;AAAA,EACpC,EAAE;AACJ;AAMA,eAAsB,kBAAkB,SAA4C;AAClF,QAAM,UAA0B,CAAC;AACjC,aAAW,MAAM,SAAS;AACxB,UAAM,OAAO,aAAa,EAAE;AAC5B,UAAM,cAAc,iBAAiB,EAAE,KAAK;AAC5C,UAAM,OAAO,MAAM,MAAM;AAAA,MACvB,SAAS,YAAY,MAAM,QAAQ,EAAE;AAAA,MACrC,SAAS;AAAA,MACT,UAAU,CAAC,MACT,EAAE,KAAK,EAAE,SAAS,IAAI,OAAO;AAAA,IACjC,CAAC;AACD,YAAQ,KAAK,EAAE,YAAY,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;AAAA,EACpD;AACA,SAAO;AACT;AAMA,eAAsB,oBACpB,UACA,SACyB;AACzB,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO,kBAAkB,OAAO;AAAA,IAClC,KAAK;AACH,aAAO,kBAAkB,OAAO;AAAA,IAClC,KAAK;AACH,aAAO,iBAAiB,OAAO;AAAA,IACjC,KAAK;AACH,aAAO,kBAAkB,OAAO;AAAA,EACpC;AACF;;;AChIA,SAAS,YAAAC,WAAU,WAAAC,UAAS,UAAAC,eAAc;AAC1C,SAAS,YAAY;AACrB,SAAS,aAAa;;;ACRtB,IAAM,gCAAgC;AACtC,IAAM,eAAe,oBAAI,IAAI;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,mBAAmB,oBAAI,IAAI;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,oBAAoB,oBAAI,IAAI,CAAC,WAAW,WAAW,UAAU,QAAQ,CAAC;AAC5E,IAAM,iBAAiB,oBAAI,IAAI,CAAC,QAAQ,QAAQ,QAAQ,CAAC;AAIlD,IAAM,6BAAN,cAAyC,MAAM;AAAA,EACpD,YAAY,QAAgB,QAAkB;AAC5C,UAAM,kCAAkC,MAAM;AAAA,IAAQ,OAAO,KAAK,MAAM,CAAC,EAAE;AAC3E,SAAK,OAAO;AAAA,EACd;AACF;AAEA,SAAS,SAAS,OAAsC;AACtD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,cACP,OACAC,OACA,QACyB;AACzB,MAAI,CAAC,SAAS,KAAK,GAAG;AACpB,WAAO,KAAK,GAAGA,KAAI,oBAAoB;AACvC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,cAAc,OAAgBA,OAAc,QAAkB;AACrE,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,WAAW,GAAG;AAC1D,WAAO,KAAK,GAAGA,KAAI,6BAA6B;AAAA,EAClD;AACF;AAEA,SAAS,eAAe,OAAgBA,OAAc,QAAkB;AACtE,MAAI,OAAO,UAAU,UAAW,QAAO,KAAK,GAAGA,KAAI,oBAAoB;AACzE;AAEA,SAAS,mBAAmB,OAAgBA,OAAc,QAAkB;AAC1E,MAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,KAAK,CAAC,UAAU,OAAO,UAAU,QAAQ,GAAG;AAC7E,WAAO,KAAK,GAAGA,KAAI,8BAA8B;AAAA,EACnD;AACF;AAEA,SAAS,YACP,OACA,SACAA,OACA,QACA;AACA,MAAI,OAAO,UAAU,YAAY,CAAC,QAAQ,IAAI,KAAK,GAAG;AACpD,WAAO,KAAK,GAAGA,KAAI,oBAAoB,CAAC,GAAG,OAAO,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAClE;AACF;AAEA,SAAS,uBACP,SACA,KACA,UACA,UACA,QACA;AACA,MAAI,QAAQ,GAAG,MAAM,OAAW;AAChC,QAAM,SAAS,cAAc,QAAQ,GAAG,GAAG,WAAW,GAAG,IAAI,MAAM;AACnE,MAAI,CAAC,OAAQ;AACb,MAAI,aAAa,UAAU;AACzB,kBAAc,OAAO,QAAQ,GAAG,WAAW,GAAG,IAAI,QAAQ,IAAI,MAAM;AAAA,EACtE,OAAO;AACL,mBAAe,OAAO,QAAQ,GAAG,WAAW,GAAG,IAAI,QAAQ,IAAI,MAAM;AAAA,EACvE;AACF;AAEO,SAAS,wBACd,OACA,QACiB;AACjB,QAAM,SAAmB,CAAC;AAC1B,QAAM,aAAa,cAAc,OAAO,cAAc,MAAM;AAC5D,MAAI,CAAC,WAAY,OAAM,IAAI,2BAA2B,QAAQ,MAAM;AAEpE,gBAAc,WAAW,IAAI,MAAM,MAAM;AACzC,gBAAc,WAAW,MAAM,QAAQ,MAAM;AAC7C,cAAY,WAAW,UAAU,kBAAkB,YAAY,MAAM;AAErE,QAAM,UAAU,cAAc,WAAW,SAAS,WAAW,MAAM;AACnE,MAAI,SAAS;AACX,kBAAc,QAAQ,aAAa,uBAAuB,MAAM;AAChE,uBAAmB,QAAQ,kBAAkB,4BAA4B,MAAM;AAC/E,eAAW,OAAO,CAAC,eAAe,SAAS,oBAAoB,GAAY;AACzE,UAAI,QAAQ,GAAG,MAAM,OAAW,eAAc,QAAQ,GAAG,GAAG,WAAW,GAAG,IAAI,MAAM;AAAA,IACtF;AACA,QAAI,QAAQ,iBAAiB,QAAW;AACtC,yBAAmB,QAAQ,cAAc,wBAAwB,MAAM;AAAA,IACzE;AAAA,EACF;AAEA,QAAM,QAAQ,cAAc,WAAW,OAAO,SAAS,MAAM;AAC7D,MAAI,OAAO;AACT,kBAAc,MAAM,SAAS,iBAAiB,MAAM;AACpD,uBAAmB,MAAM,UAAU,kBAAkB,MAAM;AAAA,EAC7D;AAEA,QAAM,QAAQ,cAAc,WAAW,OAAO,SAAS,MAAM;AAC7D,MAAI,OAAO;AACT,uBAAmB,MAAM,SAAS,iBAAiB,MAAM;AACzD,uBAAmB,MAAM,QAAQ,gBAAgB,MAAM;AAAA,EACzD;AAEA,QAAM,WAAW,cAAc,WAAW,UAAU,YAAY,MAAM;AACtE,MAAI,UAAU;AACZ;AAAA,MACE,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,mBAAe,SAAS,cAAc,yBAAyB,MAAM;AAAA,EACvE;AAEA,QAAM,QAAQ,cAAc,WAAW,OAAO,SAAS,MAAM;AAC7D,MAAI,OAAO;AACT,mBAAe,MAAM,WAAW,mBAAmB,MAAM;AACzD,uBAAmB,MAAM,cAAc,sBAAsB,MAAM;AAAA,EACrE;AAEA,QAAM,UAAU,cAAc,WAAW,SAAS,WAAW,MAAM;AACnE,MAAI,SAAS;AACX,2BAAuB,SAAS,YAAY,oBAAoB,UAAU,MAAM;AAChF,2BAAuB,SAAS,WAAW,cAAc,WAAW,MAAM;AAC1E,2BAAuB,SAAS,UAAU,2BAA2B,WAAW,MAAM;AACtF,2BAAuB,SAAS,SAAS,wBAAwB,WAAW,MAAM;AAAA,EACpF;AAEA,MAAI,OAAO,SAAS,EAAG,OAAM,IAAI,2BAA2B,QAAQ,MAAM;AAC1E,SAAO;AACT;AAEO,SAAS,oBAAoB,OAAgB,QAA6B;AAC/E,QAAM,SAAmB,CAAC;AAC1B,QAAM,SAAS,cAAc,OAAO,UAAU,MAAM;AACpD,MAAI,CAAC,OAAQ,OAAM,IAAI,2BAA2B,QAAQ,MAAM;AAEhE,QAAM,UAAU,OAAO;AACvB,MAAI,CAAC,OAAO,UAAU,OAAO,GAAG;AAC9B,UAAM,IAAI,2BAA2B,QAAQ;AAAA,MAC3C;AAAA,IACF,CAAC;AAAA,EACH;AACA,MAAK,UAAqB,+BAA+B;AACvD,UAAM,IAAI,2BAA2B,QAAQ;AAAA,MAC3C,kBAAkB,OAAO,oCAAoC,6BAA6B;AAAA,IAC5F,CAAC;AAAA,EACH;AACA,MAAK,UAAqB,GAAG;AAC3B,UAAM,IAAI,2BAA2B,QAAQ;AAAA,MAC3C,kBAAkB,OAAO,iDAAiD,6BAA6B;AAAA,IACzG,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,YAAY,IACvB,EAAE,GAAG,QAAQ,gBAAgB,8BAA8B,IAC3D;AACJ,cAAY,OAAO,iBAAiB,mBAAmB,mBAAmB,MAAM;AAChF,cAAY,OAAO,eAAe,gBAAgB,iBAAiB,MAAM;AAEzE,QAAM,WAAW,cAAc,OAAO,UAAU,YAAY,MAAM;AAClE,MAAI,UAAU;AACZ,mBAAe,SAAS,SAAS,oBAAoB,MAAM;AAC3D,kBAAc,SAAS,gBAAgB,2BAA2B,MAAM;AAAA,EAC1E;AAEA,MAAI,CAAC,MAAM,QAAQ,OAAO,MAAM,GAAG;AACjC,WAAO,KAAK,yBAAyB;AAAA,EACvC,OAAO;AACL,WAAO,OAAO,QAAQ,CAAC,OAAO,UAAU;AACtC,YAAM,OAAO,cAAc,OAAO,UAAU,KAAK,KAAK,MAAM;AAC5D,UAAI,CAAC,KAAM;AACX,oBAAc,KAAK,YAAY,UAAU,KAAK,gBAAgB,MAAM;AACpE,UAAI,KAAK,SAAS,KAAM,eAAc,KAAK,MAAM,UAAU,KAAK,UAAU,MAAM;AAChF,oBAAc,KAAK,IAAI,UAAU,KAAK,QAAQ,MAAM;AAAA,IACtD,CAAC;AAAA,EACH;AAEA,MAAI,OAAO,SAAS,EAAG,OAAM,IAAI,2BAA2B,QAAQ,MAAM;AAC1E,SAAO;AACT;;;ADpLO,IAAM,+BAAN,cAA2C,MAAM;AAAA,EACtD,YAAY,IAAY,WAAmB;AACzC;AAAA,MACE,qBAAqB,EAAE,mBAAmB,SAAS,iBACrC,EAAE,yCAAyC,EAAE;AAAA,IAC7D;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,2BAAN,cAAuC,MAAM;AAAA,EAClD,cAAc;AACZ;AAAA,MACE;AAAA,IAEF;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEA,SAAS,UAAU,SAAiB,QAAyB;AAC3D,MAAI;AACF,WAAO,MAAM,OAAO;AAAA,EACtB,SAAS,KAAK;AACZ,UAAM,SAAS,eAAe,QAAQ,IAAI,UAAU;AACpD,UAAM,IAAI,2BAA2B,QAAQ,CAAC,mBAAmB,MAAM,EAAE,CAAC;AAAA,EAC5E;AACF;AAQA,eAAsB,oBACpB,WACA,IAC0B;AAC1B,QAAM,WAAW,KAAK,WAAW,GAAG,EAAE,OAAO;AAC7C,MAAI;AACJ,MAAI;AACF,cAAU,MAAMC,UAAS,UAAU,MAAM;AAAA,EAC3C,QAAQ;AACN,UAAM,IAAI,6BAA6B,IAAI,SAAS;AAAA,EACtD;AACA,SAAO,wBAAwB,UAAU,SAAS,QAAQ,GAAG,QAAQ;AACvE;AAgCA,eAAsB,WAAW,WAAyC;AACxE,QAAM,aAAa,KAAK,WAAW,WAAW,aAAa;AAC3D,MAAI;AACJ,MAAI;AACF,cAAU,MAAMC,UAAS,YAAY,MAAM;AAAA,EAC7C,QAAQ;AACN,UAAM,IAAI,yBAAyB;AAAA,EACrC;AACA,SAAO,oBAAoB,UAAU,SAAS,UAAU,GAAG,UAAU;AACvE;AAKA,eAAsB,aAAa,WAAqC;AACtE,MAAI;AACF,UAAMC,QAAO,KAAK,WAAW,WAAW,aAAa,CAAC;AACtD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAAS,iBAAiB,WAA2B;AAC1D,SAAO,KAAK,WAAW,WAAW,QAAQ;AAC5C;;;AEhHA,SAAS,aAAAC,YAAW,SAAAC,cAAa;AACjC,SAAS,QAAAC,aAAY;AACrB,SAAS,eAAe;;;ACnBxB,SAAS,YAAAC,WAAU,aAAAC,YAAW,UAAU;AACxC,OAAOC,WAAU;AAGV,IAAM,eAAe;AACrB,IAAM,aAAa;AAEnB,IAAM,wBAAN,cAAoC,MAAM;AAAA,EAC/C,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAeA,eAAsB,cACpB,WACA,cACA,SACA,OAA8C,CAAC,GAC7B;AAClB,qBAAmB,WAAW,YAAY;AAE1C,QAAM,WAAWC,MAAK,QAAQ,WAAW,YAAY;AAErD,MAAI;AACJ,MAAI;AACF,eAAW,MAAMC,UAAS,UAAU,MAAM;AAAA,EAC5C,SAAS,KAAK;AACZ,UAAM,IAAI;AACV,QAAI,EAAE,SAAS,UAAU;AACvB,iBAAW;AAAA,IACb,OAAO;AACL,YAAM;AAAA,IACR;AAAA,EACF;AAEA,MAAI,aAAa,MAAM;AAErB,QAAI,CAAC,KAAK,MAAO,QAAO;AACxB,UAAM,aAAa,GAAG,YAAY;AAAA,EAAK,OAAO;AAAA,EAAK,UAAU;AAAA;AAC7D,QAAI,CAAC,KAAK,QAAQ;AAChB,YAAMC,WAAU,UAAU,YAAY,MAAM;AAAA,IAC9C;AACA,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,SAAS,QAAQ,YAAY;AAC9C,QAAM,SAAS,SAAS,QAAQ,UAAU;AAE1C,QAAM,WAAW,aAAa;AAC9B,QAAM,SAAS,WAAW;AAE1B,MAAI,aAAa,QAAQ;AACvB,UAAM,IAAI;AAAA,MACR,SAAS,YAAY,oCAChB,WAAW,gBAAgB,eAAe,KAC1C,SAAS,cAAc,aAAa;AAAA,IAC3C;AAAA,EACF;AAEA,MAAI,YAAY,QAAQ;AACtB,QAAI,WAAW,QAAQ;AACrB,YAAM,IAAI;AAAA,QACR,SAAS,YAAY;AAAA,MACvB;AAAA,IACF;AAEA,UAAM,eAAe,SAAS,MAAM,GAAG,WAAW,aAAa,MAAM;AACrE,UAAM,cAAc,SAAS,MAAM,MAAM;AACzC,UAAM,UAAU,GAAG,YAAY;AAAA,EAAK,OAAO;AAAA,EAAK,WAAW;AAC3D,QAAI,CAAC,KAAK,QAAQ;AAChB,YAAMA,WAAU,UAAU,SAAS,MAAM;AAAA,IAC3C;AACA,WAAO;AAAA,EACT;AAGA,MAAI,CAAC,KAAK,MAAO,QAAO;AAExB,QAAM,WACJ,GAAG,QAAQ,GAAG,SAAS,SAAS,IAAI,IAAI,KAAK,IAAI,GAC9C,YAAY;AAAA,EAAK,OAAO;AAAA,EAAK,UAAU;AAAA;AAC5C,MAAI,CAAC,KAAK,QAAQ;AAChB,UAAMA,WAAU,UAAU,UAAU,MAAM;AAAA,EAC5C;AACA,SAAO;AACT;AAWA,eAAsB,mBACpB,WACA,cACA,OAA6B,CAAC,GACZ;AAClB,QAAM,WAAWF,MAAK,QAAQ,WAAW,YAAY;AAErD,MAAI;AACJ,MAAI;AACF,eAAW,MAAMC,UAAS,UAAU,MAAM;AAAA,EAC5C,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,SAAS,QAAQ,YAAY;AAC9C,QAAM,SAAS,SAAS,QAAQ,UAAU;AAC1C,MAAI,aAAa,MAAM,WAAW,GAAI,QAAO;AAE7C,QAAM,SAAS,SAAS,MAAM,GAAG,QAAQ;AACzC,QAAM,QAAQ,SAAS,MAAM,SAAS,WAAW,MAAM;AACvD,QAAM,YAAY,SAAS,OAAO,QAAQ,WAAW,MAAM,EAAE,KAAK;AAElE,MAAI,CAAC,KAAK,QAAQ;AAChB,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,GAAG,UAAU,EAAE,OAAO,KAAK,CAAC;AAAA,IACpC,OAAO;AACL,YAAMC,WAAU,UAAU,WAAW,MAAM,MAAM;AAAA,IACnD;AAAA,EACF;AACA,SAAO;AACT;;;ADrGA,SAAS,eAAe,KAAsB,MAAsB;AAClE,QAAM,aACJ,IAAI,QAAQ,gBAAgB,IAAI,QAAQ,aAAa,SAAS,IAC1D;AAAA;AAAA;AAAA,EAAkB,IAAI,QAAQ,aAAa,IAAI,CAAC,MAAM,MAAM,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,IAC5E;AACN,SAAO,KAAK,IAAI,WAAM,IAAI,IAAI;AAAA;AAAA;AAAA;AAAA,EAI9B,IAAI,QAAQ,YAAY,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA,EAI9B,IAAI,QAAQ;AAAA,EACZ,UAAU;AACZ;AAEA,SAAS,WAAW,KAAsB,MAAsB;AAC9D,QAAM,QAAQ,IAAI,QAAQ,iBAAiB,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI;AACzE,SAAO,KAAK,IAAI;AAAA;AAAA;AAAA;AAAA,EAIhB,KAAK;AAAA;AAAA;AAAA;AAAA,6BAIsB,IAAI,SAAS,mBAAmB;AAAA,sBACvC,IAAI,SAAS,eAAe,QAAQ,IAAI;AAAA;AAE9D;AAEA,SAAS,YAAY,KAAsB,MAAsB;AAC/D,QAAM,UAAU,IAAI,MAAM,QAAQ,IAAI,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,KAAK,IAAI;AACpE,QAAM,SAAS,IAAI,MAAM,OAAO,IAAI,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,KAAK,IAAI;AAClE,SAAO,KAAK,IAAI;AAAA;AAAA;AAAA;AAAA,EAIhB,OAAO;AAAA;AAAA;AAAA;AAAA,EAIP,MAAM;AAAA;AAER;AAEA,SAAS,mBAAmB,KAAsB,MAAsB;AACtE,QAAM,YAAY,IAAI,QAAQ,YAAY,MAAM,IAAI,EAAE,CAAC,GAAG,KAAK,KAAK,IAAI;AACxE,QAAM,QAAQ,IAAI,QAAQ,iBAAiB,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI;AACzE,QAAM,mBAAmB,IAAI,QAAQ,cACjC;AAAA;AAAA;AAAA,EAAuB,IAAI,QAAQ,YAAY,KAAK,CAAC;AAAA,IACrD;AACJ,QAAM,aAAa,IAAI,QAAQ,QAC3B;AAAA;AAAA;AAAA,EAAiB,IAAI,QAAQ,MAAM,KAAK,CAAC;AAAA,IACzC;AACJ,QAAM,cACJ,IAAI,QAAQ,gBAAgB,IAAI,QAAQ,aAAa,SAAS,IAC1D;AAAA;AAAA;AAAA,EAAkB,IAAI,QAAQ,aAAa,IAAI,CAAC,MAAM,MAAM,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,IAC5E;AACN,SAAO;AAAA,QACD,IAAI;AAAA,eACG,IAAI,IAAI,WAAM,SAAS;AAAA;AAAA,EAEpC,WAAW;AAAA;AAAA;AAAA,EAGX,IAAI,QAAQ,YAAY,KAAK,CAAC;AAAA,EAC9B,gBAAgB,GAAG,UAAU;AAAA;AAAA;AAAA,EAG7B,KAAK;AAAA;AAAA;AAAA;AAAA,eAIQ,IAAI,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,cAC7B,IAAI,MAAM,OAAO,KAAK,IAAI,CAAC;AAAA;AAEzC;AAEA,SAAS,yBAAyB,SAAkC;AAClE,QAAM,OAAO,QACV;AAAA,IAAI,CAAC,EAAE,KAAK,YAAY,MACvB,OAAO,WAAW,QAAQ,IAAI,IAAI,MAAM,IAAI,QAAQ;AAAA,EACtD,EACC,KAAK,IAAI;AAEZ,SAAO;AAAA;AAAA;AAAA;AAAA,EAIP,IAAI;AAAA;AAEN;AAmBA,eAAsB,WACpB,WACA,WACA,QACA,UAA4B,CAAC,GACR;AACrB,QAAM,SAAmB,CAAC;AAC1B,QAAM,UAAoB,CAAC;AAG3B,QAAM,cAAc,iBAAiB,SAAS;AAC9C,QAAM,cAAcC,MAAK,WAAW,QAAQ;AAE5C,QAAM,WAA4B,CAAC;AACnC,aAAW,SAAS,OAAO,QAAQ;AACjC,QAAI;AACJ,QAAI;AAEF,YAAM,MAAM,oBAAoB,aAAa,MAAM,UAAU;AAAA,IAC/D,QAAQ;AACN,UAAI;AAEF,cAAM,MAAM,oBAAoB,aAAa,MAAM,UAAU;AAAA,MAC/D,QAAQ;AACN,gBAAQ,KAAK,GAAG,MAAM,UAAU,yBAAyB;AACzD;AAAA,MACF;AAAA,IACF;AACA,aAAS,KAAK;AAAA,MACZ;AAAA,MACA;AAAA,MACA,aAAa,MAAM,QAAQ,MAAM;AAAA,IACnC,CAAC;AAAA,EACH;AAGA,MAAI,OAAO,SAAS,WAAW,QAAQ,aAAa,OAAO;AACzD,UAAM,eAAe,OAAO,SAAS,eAAe;AAAA,MAClD;AAAA,MACA,QAAQ;AAAA,IACV;AAEA,eAAW,EAAE,OAAO,KAAK,YAAY,KAAK,UAAU;AAClD,UAAI,CAAC,IAAI,QAAQ,SAAU;AAE3B,YAAM,gBACJ,MAAM,OAAO,SAAS,cAAc,aAAa,MAAM,EAAE;AAC3D,YAAM,eAAeA,MAAK,cAAc,aAAa;AAErD,UAAI;AACF,YAAI,CAAC,QAAQ,QAAQ;AACnB,gBAAMC,OAAM,cAAc,EAAE,WAAW,KAAK,CAAC;AAC7C,gBAAMC;AAAA,YACJF,MAAK,cAAc,aAAa;AAAA,YAChC,eAAe,KAAK,WAAW;AAAA,YAC/B;AAAA,UACF;AACA,gBAAME;AAAA,YACJF,MAAK,cAAc,SAAS;AAAA,YAC5B,WAAW,KAAK,WAAW;AAAA,YAC3B;AAAA,UACF;AACA,gBAAME;AAAA,YACJF,MAAK,cAAc,UAAU;AAAA,YAC7B,YAAY,KAAK,WAAW;AAAA,YAC5B;AAAA,UACF;AAAA,QACF,OAAO;AACL,kBAAQ,IAAI,4BAA4B,YAAY,cAAc;AAClE,kBAAQ,IAAI,4BAA4B,YAAY,UAAU;AAC9D,kBAAQ,IAAI,4BAA4B,YAAY,WAAW;AAAA,QACjE;AACA,eAAO,KAAK,YAAY,MAAM,EAAE,sBAAsB;AAAA,MACxD,QAAQ;AACN,gBAAQ,KAAK,YAAY,MAAM,EAAE,6BAA6B;AAAA,MAChE;AAAA,IACF;AAGA,UAAM,QAAQ;AAAA,MACZ,UACE;AAAA,MAEF,QAAQ,SAAS,IAAI,CAAC,EAAE,OAAO,IAAI,OAAO;AAAA,QACxC,IAAI,MAAM;AAAA,QACV,UAAU;AAAA,UACR,MAAM,MAAM,QAAQ,MAAM;AAAA,UAC1B,MAAM,IAAI;AAAA,QACZ;AAAA,MACF,EAAE;AAAA,IACJ;AAEA,UAAM,eAAeA,MAAK,WAAW,WAAW,WAAW;AAC3D,QAAI,CAAC,QAAQ,QAAQ;AACnB,YAAMC,OAAM,cAAc,EAAE,WAAW,KAAK,CAAC;AAC7C,YAAMC;AAAA,QACJF,MAAK,cAAc,sBAAsB;AAAA,QACzC,KAAK,UAAU,OAAO,MAAM,CAAC,IAAI;AAAA,QACjC;AAAA,MACF;AAAA,IACF,OAAO;AACL,cAAQ;AAAA,QACN;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK,sBAAsB;AAAA,EACpC;AAGA,MAAI,QAAQ,YAAY,OAAO;AAC7B,UAAM,YAAYA,MAAK,WAAW,WAAW,QAAQ;AAErD,QAAI,CAAC,QAAQ,QAAQ;AACnB,YAAMC,OAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,IAC5C;AAEA,eAAW,EAAE,KAAK,YAAY,KAAK,UAAU;AAC3C,UAAI,CAAC,IAAI,QAAQ,SAAS,WAAY;AAEtC,YAAM,OAAO,YAAY,YAAY,EAAE,QAAQ,QAAQ,GAAG;AAC1D,YAAM,WAAW,GAAG,IAAI;AACxB,UAAI,CAAC,QAAQ,QAAQ;AACnB,cAAMC;AAAA,UACJF,MAAK,WAAW,QAAQ;AAAA,UACxB,mBAAmB,KAAK,WAAW;AAAA,UACnC;AAAA,QACF;AAAA,MACF,OAAO;AACL,gBAAQ,IAAI,2CAA2C,QAAQ,EAAE;AAAA,MACnE;AACA,aAAO,KAAK,kBAAkB,QAAQ,EAAE;AAAA,IAC1C;AAGA,UAAM,gBAAgB,yBAAyB,QAAQ;AACvD,UAAM,gBAAgB,MAAM;AAAA,MAC1B;AAAA,MACA;AAAA,MACA;AAAA,MACA,EAAE,OAAO,MAAM,QAAQ,QAAQ,OAAO;AAAA,IACxC;AACA,QAAI;AACF,aAAO,KAAK,kDAAkD;AAAA,EAClE;AAGA,MAAI,QAAQ,WAAW,OAAO;AAC5B,UAAM,gBAAgB,yBAAyB,QAAQ;AACvD,UAAM,eAAe,MAAM;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,MACA,EAAE,OAAO,MAAM,QAAQ,QAAQ,OAAO;AAAA,IACxC;AACA,QAAI,aAAc,QAAO,KAAK,4BAA4B;AAAA,EAC5D;AAGA,MAAI,QAAQ,UAAU,OAAO;AAC3B,UAAM,gBAAgB,yBAAyB,QAAQ;AACvD,UAAM,cAAc,MAAM;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA,EAAE,OAAO,MAAM,QAAQ,QAAQ,OAAO;AAAA,IACxC;AACA,QAAI,YAAa,QAAO,KAAK,4BAA4B;AAAA,EAC3D;AAEA,SAAO,EAAE,QAAQ,QAAQ;AAC3B;;;ANpRA,eAAsB,cACpB,SACA,WACA,WACe;AAEf,MAAI,CAAC,QAAQ,SAAU,MAAM,aAAa,SAAS,GAAI;AACrD,YAAQ;AAAA,MACN;AAAA,IAEF;AACA;AAAA,EACF;AAEA,UAAQ,IAAI;AAGZ,MAAI,YAA4B,QAAQ,WAAW;AACnD,MAAI,CAAC,QAAQ,SAAS;AACpB,UAAM,YAAY,sBAAsB,MAAM,EAAE;AAChD,UAAM,gBAAgB,UAAU,IAAI,CAAC,OAAO;AAC1C,YAAM,OAAO,YAAY,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAChD,aAAO,OAAO,KAAK,OAAO;AAAA,IAC5B,CAAC;AACD,UAAM,gBAAgB,CAAC,GAAG,IAAI,IAAI,YAAY,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAErE,gBAAa,MAAM,OAAO;AAAA,MACxB,SAAS;AAAA,MACT,SAAS,sBAAsB,IAAI,CAAC,OAAO;AAAA,QACzC,OAAO,EAAE;AAAA,QACT,MAAM,GAAG,EAAE,OAAO,SAAS,cAAO,EAAE,OAAO,SAAS,cAAO,WAAI,KAAK,EAAE,WAAW;AAAA,QACjF,aACE,EAAE,OAAO,SACL;AAAA,gBAAmB,cAAc,KAAK,IAAI,CAAC,KAC3C,EAAE,OAAO,SACP;AAAA,sBAAyB,cAAc,KAAK,IAAI,CAAC,KACjD;AAAA,MACV,EAAE;AAAA,IACJ,CAAC;AAAA,EACH;AAGA,MAAI;AACJ,MAAI,cAAc,UAAU;AAE1B,UAAM,aAAa,CAAC,GAAG,IAAI,IAAI,YAAY,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAClE,UAAM,wBAGF,CAAC;AACL,eAAW,OAAO,YAAY;AAC5B,4BAAsB,KAAK,IAAI,UAAU,gBAAM,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC,CAAC,eAAK,CAAC;AAC/F,iBAAW,KAAK,YAAY,OAAO,CAACG,OAAMA,GAAE,aAAa,GAAG,GAAG;AAC7D,8BAAsB,KAAK;AAAA,UACzB,OAAO,EAAE;AAAA,UACT,MAAM,GAAG,EAAE,EAAE,WAAM,EAAE,IAAI;AAAA,UACzB,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAEA,YAAQ,IAAI;AACZ,sBAAkB,MAAM,SAAS;AAAA,MAC/B,SAAS;AAAA,MACT,SAAS;AAAA,MACT,UAAU,CAAC,YACT,QAAQ,SAAS,IAAI,OAAO;AAAA,IAChC,CAAC;AAAA,EACH,OAAO;AACL,sBAAkB,sBAAsB,SAAS,EAAE;AAAA,EACrD;AAGA,MAAI,iBAAiC,QAAQ,UAAU;AACvD,MAAI,CAAC,QAAQ,QAAQ;AACnB,YAAQ,IAAI;AACZ,qBAAkB,MAAM,OAAO;AAAA,MAC7B,SAAS;AAAA,MACT,SAAS;AAAA,QACP;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAGA,YAAU,oBAAoB;AAC9B,QAAM,QAAQ,MAAM,oBAAoB,gBAAgB,eAAe;AAGvE,QAAM,gBAAoC,MAAM,IAAI,CAAC,EAAE,YAAY,KAAK,MAAM;AAE5E,UAAM,KAAK,eAAe,iBAAiB,SAAS,KAAK,YAAY,EAAE,QAAQ,QAAQ,GAAG;AAC1F,WAAO,EAAE,YAAY,MAAM,GAAG;AAAA,EAChC,CAAC;AAED,QAAM,SAAsB;AAAA,IAC1B,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,UAAU;AAAA,MACR,SAAS;AAAA,MACT,gBAAgB;AAAA,IAClB;AAAA,IACA,QAAQ;AAAA,EACV;AAGA,QAAM,YAAYC,MAAK,WAAW,WAAW,QAAQ;AACrD,MAAI,CAAC,QAAQ,QAAQ;AACnB,UAAMC,OAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAC1C,UAAMC;AAAA,MACJF,MAAK,WAAW,WAAW,aAAa;AAAA,MACxC,UAAU,MAAM;AAAA,MAChB;AAAA,IACF;AAAA,EACF,OAAO;AACL,YAAQ,IAAI,8CAA8C;AAAA,EAC5D;AAGA,aAAW,UAAU,iBAAiB;AACpC,UAAM,MAAMA,MAAK,WAAW,UAAU,GAAG,MAAM,OAAO;AACtD,UAAM,OAAOA,MAAK,WAAW,GAAG,MAAM,OAAO;AAC7C,QAAI,CAAC,QAAQ,QAAQ;AACnB,UAAI;AACF,cAAMG,UAAS,KAAK,IAAI;AAAA,MAC1B,QAAQ;AACN,gBAAQ,KAAK,sCAAsC,MAAM,mBAAc;AAAA,MACzE;AAAA,IACF,OAAO;AACL,cAAQ,IAAI,0CAA0C,MAAM,OAAO;AAAA,IACrE;AAAA,EACF;AAEA,MAAI,QAAQ,QAAQ;AAClB,YAAQ;AAAA,MACN;AAAA,2CAA8C,gBAAgB,MAAM;AAAA,IACtE;AACA;AAAA,EACF;AAGA,YAAU,6CAA6C;AACvD,QAAM,EAAE,QAAQ,QAAQ,IAAI,MAAM;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA,EAAE,QAAQ,MAAM;AAAA,EAClB;AAEA,eAAa,0BAA0B;AACvC,UAAQ,IAAI,0BAAmB,SAAS,iBAAc,cAAc,iBAAc,cAAc,MAAM,EAAE;AACxG,UAAQ,IAAI,yBAAkB,OAAO,MAAM,6CAA6C;AACxF,MAAI,QAAQ,SAAS,GAAG;AACtB,YAAQ,IAAI,8BAAoB,QAAQ,MAAM,KAAK,QAAQ,KAAK,IAAI,CAAC,GAAG;AAAA,EAC1E;AACA,UAAQ,IAAI;AACZ,UAAQ,IAAI,4EAAgE;AAC5E,UAAQ,IAAI;AACd;AAKA,eAAsB,cACpB,SACA,WACA,WACe;AACf,MAAI;AACJ,MAAI;AACF,aAAS,MAAM,WAAW,SAAS;AAAA,EACrC,SAAS,KAAK;AACZ,QACE,eAAe,4BACZ,eAAe,4BAClB;AACA,cAAQ,MAAM,IAAI,OAAO;AACzB,cAAQ,KAAK,CAAC;AACd;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAEA,MAAI,QAAQ,QAAQ;AAClB,YAAQ,IAAI,gDAAgD;AAAA,EAC9D,OAAO;AACL,YAAQ,IAAI,yBAAyB;AAAA,EACvC;AAEA,QAAM,EAAE,QAAQ,QAAQ,IAAI,MAAM;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,QAAQ,QAAQ;AAClB,YAAQ,IAAI;AAAA,cAAiB,OAAO,MAAM,6BAA6B;AACvE;AAAA,EACF;AAEA,UAAQ,IAAI;AAAA,kBAAgB,OAAO,MAAM,UAAU;AACnD,aAAW,QAAQ,QAAQ;AACzB,YAAQ,IAAI,SAAS,IAAI,EAAE;AAAA,EAC7B;AACA,MAAI,QAAQ,SAAS,GAAG;AACtB,YAAQ,IAAI;AAAA,cAAiB,QAAQ,MAAM,GAAG;AAC9C,eAAW,QAAQ,SAAS;AAC1B,cAAQ,IAAI,SAAS,IAAI,EAAE;AAAA,IAC7B;AAAA,EACF;AACA,UAAQ,IAAI;AACd;AAKA,eAAsB,cAAc,WAAkC;AACpE,MAAI;AACJ,MAAI;AACF,aAAS,MAAM,WAAW,SAAS;AAAA,EACrC,SAAS,KAAK;AACZ,QACE,eAAe,4BACZ,eAAe,4BAClB;AACA,cAAQ,MAAM,IAAI,OAAO;AACzB,cAAQ,KAAK,CAAC;AACd;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAEA,QAAM,YAAY,KAAK;AAAA,IACrB,OAAO;AAAA,IACP,GAAG,OAAO,OAAO,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,MAAM;AAAA,EAC7D;AACA,QAAM,WAAW,KAAK;AAAA,IACpB,UAAU;AAAA,IACV,GAAG,OAAO,OAAO,IAAI,CAAC,MAAM,EAAE,WAAW,MAAM;AAAA,EACjD;AACA,QAAM,UAAU,KAAK;AAAA,IACnB,cAAc;AAAA,IACd,GAAG,OAAO,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM;AAAA,EACzC;AAEA,QAAM,MAAM,CAAC,GAAW,MAAc,EAAE,OAAO,CAAC;AAEhD,UAAQ;AAAA,IACN;AAAA,aAAgB,OAAO,aAAa,gBAAgB,OAAO,eAAe,gBAAgB,OAAO,OAAO,MAAM;AAAA;AAAA,EAChH;AACA,UAAQ;AAAA,IACN,KAAK,IAAI,QAAQ,SAAS,CAAC,KAAK,IAAI,WAAW,QAAQ,CAAC,KAAK,IAAI,eAAe,OAAO,CAAC;AAAA,EAC1F;AACA,UAAQ;AAAA,IACN,KAAK,IAAI,OAAO,SAAS,CAAC,KAAK,IAAI,OAAO,QAAQ,CAAC,KAAK,IAAI,OAAO,OAAO,CAAC;AAAA,EAC7E;AACA,aAAW,SAAS,OAAO,QAAQ;AACjC,YAAQ;AAAA,MACN,KAAK,IAAI,MAAM,QAAQ,aAAa,SAAS,CAAC,KAAK,IAAI,MAAM,YAAY,QAAQ,CAAC,KAAK,IAAI,MAAM,IAAI,OAAO,CAAC;AAAA,IAC/G;AAAA,EACF;AACA,UAAQ,IAAI;AACd;;;AQxUA,SAAS,gBAAgB;AA8BlB,IAAM,kBAAN,cAA8B,MAAM;AAAA,EACzC,YAAY,SAAiB,SAA+B;AAC1D,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AAAA,EACd;AACF;AAEA,IAAM,sBAAsB,oBAAI,IAAI,CAAC,SAAS,QAAQ,QAAQ,SAAS,aAAa,YAAY,CAAC;AAEjG,IAAM,oBAAoB,oBAAI,IAAI;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAOD,IAAM,qBAAqB,oBAAI,IAAI,CAAC,UAAU,UAAU,UAAU,UAAU,CAAC;AAO7E,IAAM,mBAAmB,oBAAI,IAAI;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAMD,IAAM,mCAAmC,oBAAI,IAAI,CAAC,MAAM,IAAI,CAAC;AAE7D,IAAM,sBAAuD;AAAA,EAC3D,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AACX;AAOO,SAAS,mBAAmB,MAAiC;AAClE,MAAI;AACJ,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,MAAM,KAAK,CAAC;AAClB,QAAI,iCAAiC,IAAI,GAAG,GAAG;AAC7C;AACA;AAAA,IACF;AACA,QAAI,IAAI,WAAW,GAAG,EAAG;AACzB,iBAAa;AACb;AAAA,EACF;AACA,MAAI,CAAC,WAAY,QAAO;AACxB,MAAI,oBAAoB,IAAI,UAAU,EAAG,QAAO;AAChD,MAAI,kBAAkB,IAAI,UAAU,KAAK,mBAAmB,IAAI,UAAU,EAAG,QAAO;AACpF,MAAI,iBAAiB,IAAI,UAAU,EAAG,QAAO;AAG7C,SAAO;AACT;AAWO,SAAS,cAAiC;AAC/C,SAAO;AAAA,IACL,GAAG,QAAQ;AAAA,IACX,qBAAqB;AAAA,IACrB,iBAAiB;AAAA,IACjB,oBAAoB;AAAA,EACtB;AACF;AASO,SAAS,OAAO,KAAa,MAAgB,UAAyB,CAAC,GAAuB;AACnG,QAAM,eAAe,QAAQ,gBAAgB,mBAAmB,IAAI;AAKpE,QAAM,YAAY,QAAQ,aAAa,oBAAoB,YAAY,KAAK,oBAAoB;AAEhG,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,QACE;AAAA,QACA,KAAK,YAAY;AAAA,QACjB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMT,YAAY;AAAA,QACZ,aAAa;AAAA,QACb,UAAU;AAAA,MACZ;AAAA,MACA,CAAC,OAAO,QAAQ,WAAW;AACzB,YAAI,OAAO;AACT,cAAI,MAAM,QAAQ;AAChB;AAAA,cACE,IAAI;AAAA;AAAA;AAAA;AAAA,gBAIF,OAAO,KAAK,KAAK,GAAG,CAAC,oBAAoB,SAAS,cAAc,YAAY;AAAA,gBAC5E,EAAE,OAAO,MAAM;AAAA,cACjB;AAAA,YACF;AACA;AAAA,UACF;AACA,iBAAO,KAAK;AACZ;AAAA,QACF;AACA,gBAAQ,EAAE,QAAQ,OAAO,CAAC;AAAA,MAC5B;AAAA,IACF;AAEA,UAAM,OAAO,IAAI;AAAA,EACnB,CAAC;AACH;AAKA,eAAsB,qBAAqB,KAA0C;AACnF,MAAI;AACF,UAAM,EAAE,QAAAC,QAAO,IAAI,MAAM,OAAO,KAAK,CAAC,aAAa,uBAAuB,CAAC;AAC3E,QAAIA,QAAO,KAAK,MAAM,QAAQ;AAC5B,aAAO,EAAE,QAAQ,iBAAiB;AAAA,IACpC;AAAA,EACF,QAAQ;AACN,WAAO,EAAE,QAAQ,iBAAiB;AAAA,EACpC;AAEA,MAAI;AACF,UAAM,OAAO,KAAK,CAAC,aAAa,YAAY,MAAM,CAAC;AAAA,EACrD,QAAQ;AACN,WAAO,EAAE,QAAQ,aAAa;AAAA,EAChC;AAEA,QAAM,EAAE,OAAO,IAAI,MAAM,OAAO,KAAK,CAAC,UAAU,eAAe,OAAO,CAAC;AACvE,QAAM,QAAQ,OAAO,KAAK;AAC1B,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,oBAAoB,MAAM,WAAW,IAAI,IAAI,MAAM,MAAM,IAAI,EAAE;AAAA,EACjE;AACF;AAiCA,eAAsB,2BAA2B,KAA8C;AAC7F,MAAI;AACJ,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM,OAAO,KAAK,CAAC,gBAAgB,WAAW,MAAM,CAAC;AACxE,cAAU,OAAO,KAAK;AAAA,EACxB,QAAQ;AACN,WAAO,EAAE,WAAW,OAAO,IAAI,OAAO;AAAA,EACxC;AAEA,MAAI,YAAY,UAAU;AACxB,WAAO,EAAE,WAAW,OAAO,IAAI,OAAO;AAAA,EACxC;AASA,MAAI;AACF,UAAM,OAAO,KAAK,CAAC,aAAa,YAAY,MAAM,CAAC;AACnD,WAAO,EAAE,WAAW,OAAO,IAAI,OAAO;AAAA,EACxC,QAAQ;AAAA,EAER;AAWA,MAAI;AACF,UAAM,OAAO,KAAK,CAAC,aAAa,YAAY,iBAAiB,CAAC;AAC9D,WAAO,EAAE,WAAW,OAAO,IAAI,OAAO;AAAA,EACxC,QAAQ;AAAA,EAER;AAEA,QAAM,OAAO,KAAK,CAAC,gBAAgB,QAAQ,iBAAiB,CAAC;AAC7D,SAAO,EAAE,WAAW,MAAM,MAAM,SAAS,IAAI,OAAO;AACtD;AAgBA,eAAsB,sBAAsB,KAAwC;AAClF,MAAI;AACJ,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM,OAAO,KAAK,CAAC,UAAU,WAAW,SAAS,aAAa,CAAC;AAClF,oBAAgB,OAAO,KAAK;AAAA,EAC9B,QAAQ;AACN,oBAAgB;AAAA,EAClB;AAEA,MAAI,kBAAkB,QAAW;AAC/B,UAAM,OAAO,KAAK,CAAC,UAAU,WAAW,eAAe,MAAM,CAAC;AAC9D,WAAO,EAAE,QAAQ,MAAM;AAAA,EACzB;AAWA,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM,OAAO,KAAK,CAAC,UAAU,WAAW,eAAe,SAAS,aAAa,CAAC;AACjG,QAAI,OAAO,KAAK,MAAM,SAAS;AAC7B,aAAO,EAAE,QAAQ,2BAA2B;AAAA,IAC9C;AACA,WAAO,EAAE,QAAQ,cAAc;AAAA,EACjC,QAAQ;AACN,WAAO,EAAE,QAAQ,cAAc;AAAA,EACjC;AACF;;;Ad3UA,IAAM,iBAA4B,CAAC,QAAQ,QAAQ,mBAAmB,aAAa;AAUnF,SAAS,qBAAqB,YAAmD;AAC/E,QAAM,SAA2B,CAAC;AAElC,QAAM,UAAU,WAAW,KAAK,CAAC,MAAM,EAAE,SAAS,eAAe;AACjE,MAAI,SAAS;AACX,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO,QAAQ,MAAM;AAAA,IACvB,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,WAAW,KAAK,CAAC,MAAM,EAAE,SAAS,iBAAiB;AAClE,MAAI,QAAQ;AACV,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO,OAAO,MAAM;AAAA,IACtB,CAAC;AAAA,EACH;AAEA,QAAM,aAAa,WAAW;AAAA,IAC5B,CAAC,MACC,EAAE,SAAS,mBACX,EAAE,SAAS,qBACX,EAAE,SAAS,sBACX,EAAE,SAAS,uBACX,EAAE,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,qBAAqB,CAAC;AAAA,EAC3D;AACA,MAAI,WAAW,SAAS,GAAG;AACzB,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO,WAAW,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,MAAM,QAAQ,CAAC;AAAA,IAC1D,CAAC;AAAA,EACH;AAEA,QAAM,WAAW,WAAW,KAAK,CAAC,MAAM,EAAE,SAAS,mBAAmB;AACtE,MAAI,UAAU;AACZ,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO,SAAS,MAAM;AAAA,IACxB,CAAC;AAAA,EACH;AAEA,QAAM,YAAY,WAAW,KAAK,CAAC,MAAM,EAAE,SAAS,kBAAkB;AACtE,MAAI,WAAW;AACb,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO,UAAU,MAAM;AAAA,IACzB,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAMA,SAAS,wBAAwB,YAAiC,SAA0B;AAC1F,QAAM,SAAS,qBAAqB,UAAU;AAC9C,QAAM,QAAQ,OAAO,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,IAAI,EAAE,KAAK,IAAI,EAAE,KAAK,EAAE;AACjE,MAAI,YAAY,UAAU,YAAY,QAAQ;AAE5C,UAAM,WAAW,OAAO,UAAU,CAAC,MAAM,EAAE,UAAU,iBAAiB;AACtE,UAAM,OAAO,YAAY,IAAI,WAAW,MAAM,QAAQ,GAAG,0BAAmB;AAAA,EAC9E;AACA,SAAO,OAAO,MAAM,KAAK,IAAI;AAC/B;AAYA,eAAsB,QACpB,SACA,WACA,WACA,gBACe;AAEf,MAAI,QAAQ,WAAW,CAAC,eAAe,SAAS,QAAQ,OAAO,GAAG;AAChE,UAAM,IAAI;AAAA,MACR,oBAAoB,QAAQ,OAAO,qBAAqB,eAAe,KAAK,IAAI,CAAC;AAAA,IACnF;AAAA,EACF;AAGA,MAAI;AACF,UAAM,aAAa,SAAS;AAC5B,YAAQ,IAAIC,OAAM,IAAI,SAAS,EAAE;AAAA,mBAAiB,cAAc;AAAA,CAAI,CAAC;AACrE,YAAQ,IAAI,mEAAmE;AAC/E;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,EAAE,eAAe,uBAAwB,OAAM;AAAA,EAErD;AAEA,UAAQ,IAAIA,OAAM,IAAI,SAAS,EAAE;AAAA,mBAAiB,cAAc;AAAA,CAAI,CAAC;AAQrE,MAAI,eAAe;AACnB,MAAI,CAAC,QAAQ,QAAQ;AACnB,UAAM,WAAW,MAAM,qBAAqB,SAAS;AAErD,QAAI,SAAS,WAAW,kBAAkB;AACxC,qBAAe;AAAA,IACjB,OAAO;AACL,UAAI,SAAS,WAAW,cAAc;AACpC,cAAM,aAAa,MAAM,2BAA2B,SAAS;AAC7D,YAAI,WAAW,WAAW;AACxB;AAAA,YACE,qCAAqC,WAAW,IAAI,SAAS,WAAW,EAAE;AAAA,UAC5E;AAAA,QACF;AAAA,MACF;AAEA,UAAI,SAAS,WAAW,WAAW,SAAS,qBAAqB,GAAG;AAClE;AAAA,UACE,iBAAiB,SAAS,kBAAkB,sBAAsB,SAAS,uBAAuB,IAAI,KAAK,GAAG;AAAA,QAChH;AACA,kBAAU,6DAA6D;AACvE,gBAAQ,IAAI;AACZ,cAAM,iBAAiB,MAAM,QAAQ;AAAA,UACnC,SAAS;AAAA,UACT,SAAS;AAAA,QACX,CAAC;AACD,YAAI,CAAC,gBAAgB;AACnB,kBAAQ,IAAI,kDAAkD;AAC9D;AAAA,QACF;AACA,gBAAQ,IAAI;AAAA,MACd;AAEA,YAAM,eAAe,MAAM,sBAAsB,SAAS;AAC1D,UAAI,aAAa,WAAW,4BAA4B;AACtD;AAAA,UACE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,UAAmB,QAAQ;AAC/B,MAAI,CAAC,SAAS;AACZ,UAAM,WAAW,aAAa;AAC9B,cAAW,MAAMC,QAAO;AAAA,MACtB,SAAS;AAAA,MACT,SAAS,SAAS,IAAI,CAAC,MAAM;AAC3B,cAAM,oBAAoB,WAAW,EAAE,EAAE;AACzC,eAAO;AAAA,UACL,OAAO,EAAE;AAAA,UACT,MAAM,GAAG,EAAE,OAAO,SAAS,cAAO,EAAE,OAAO,SAAS,WAAM,WAAI,KAAK,EAAE,WAAW,WAAM,EAAE,WAAW;AAAA,UACnG,aAAa,wBAAwB,mBAAmB,EAAE,EAAE;AAAA,QAC9D;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAGA,QAAM,aAAa,WAAW,OAAO;AAGrC,QAAM,SAAS,qBAAqB,UAAU;AAE9C,UAAQ,IAAI;AACZ,eAAa,sBAAe,OAAO,EAAE;AACrC,UAAQ,IAAI;AAGZ,QAAM,YAAY,YAAY,UAAU,YAAY;AAGpD,QAAM,eAAe,OAAO,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,IAAI,EAAE,KAAK,IAAI,EAAE,KAAK,EAAE;AACxE,MAAI,WAAW;AAEb,UAAM,WAAW,OAAO,UAAU,CAAC,MAAM,EAAE,UAAU,iBAAiB;AACtE,iBAAa,OAAO,YAAY,IAAI,WAAW,aAAa,QAAQ,GAAG,0BAAmB;AAAA,EAC5F;AACA,UAAQ,IAAI,KAAK,aAAa,KAAK,QAAK,CAAC,EAAE;AAE3C,UAAQ,IAAI;AAGZ,MAAI,CAAC,QAAQ,UAAU,CAAC,QAAQ,SAAS;AACvC,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AACD,QAAI,CAAC,SAAS;AACZ,cAAQ,IAAI,cAAc;AAC1B;AAAA,IACF;AAAA,EACF;AAGA,QAAM,sBAA4C,CAAC;AACnD,MAAI,YAAY;AAEhB,aAAW,aAAa,YAAY;AAClC,UAAM,iBAA2B,CAAC;AAElC,eAAW,QAAQ,UAAU,OAAO;AAClC,YAAM,UAAUC,MAAK,WAAW,IAAI;AACpC,UAAI,QAAQ,QAAQ;AAClB,oBAAY,eAAe,IAAI,EAAE;AAAA,MACnC,OAAO;AACL,YAAI;AACF,gBAAM,SAAS,SAAS,WAAW,MAAM,EAAE,OAAO,QAAQ,MAAM,CAAC;AAAA,QACnE,SAAS,KAAK;AAEZ,cAAI,UAAU,gBAAgB,eAAe,SAAS,IAAI,QAAQ,SAAS,gBAAgB,GAAG;AAC5F;AAAA,UACF;AACA,gBAAM;AAAA,QACR;AAAA,MACF;AACA,qBAAe,KAAK,IAAI;AACxB;AAAA,IACF;AAEA,eAAW,OAAO,UAAU,eAAe,CAAC,GAAG;AAC7C,YAAM,aAAaA,MAAK,WAAW,GAAG;AACtC,UAAI,QAAQ,QAAQ;AAClB,oBAAY,yBAAyB,GAAG,GAAG;AAAA,MAC7C,OAAO;AACL,cAAM,SAAS,MAAM,cAAc,YAAY,WAAW,KAAK,EAAE,OAAO,QAAQ,MAAM,CAAC;AACvF,uBAAe,KAAK,GAAG,MAAM;AAC7B,qBAAa,OAAO;AAAA,MACtB;AAAA,IACF;AAEA,QAAI,CAAC,QAAQ,QAAQ;AACnB,0BAAoB,KAAK;AAAA,QACvB,MAAM,UAAU;AAAA,QAChB,OAAO;AAAA,QACP,kBAAkB;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,EACF;AAGA,MAAI,CAAC,QAAQ,QAAQ;AACnB,eAAW,SAAS,QAAQ;AAC1B,gBAAU,GAAG,MAAM,IAAI,IAAI,MAAM,KAAK,IAAI,MAAM,KAAK,EAAE;AAAA,IACzD;AAAA,EACF;AAEA,MAAI,QAAQ,QAAQ;AAElB,QAAI,WAAW;AACb,YAAM,aAAa,MAAM,OAAO,IAAS,EAAE;AAAA,QAAK,CAAC,aAC/C,SAAS,SAAS,QAAQA,MAAK,WAAW,QAAQ,CAAC;AAAA,MACrD;AACA,YAAM,YAAY,WAAW,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO,CAAC,EAAE,KAAK;AACrE,kBAAY,sCAAsC;AAClD,kBAAY,kCAAkC;AAC9C,iBAAW,KAAK,WAAW;AACzB,oBAAY,8BAA8B,CAAC,EAAE;AAAA,MAC/C;AAAA,IACF;AACA,gBAAY,kCAAkC,OAAO,YAAO,SAAS,QAAQ;AAC7E;AAAA,EACF;AAQA,MAAI;AACJ,MAAI,CAAC,QAAQ,SAAS;AACpB,YAAQ,IAAI;AACZ,UAAM,QAAQ,MAAM,QAAQ;AAAA,MAC1B,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AACD,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAGA,QAAM,WAA2B;AAAA,IAC/B,SAAS;AAAA,IACT;AAAA,IACA,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,YAAY;AAAA,IACZ,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,EACzB;AACA,QAAM,cAAc,WAAW,QAAQ;AAEvC,eAAa,6BAA6B,OAAO,YAAO,SAAS,kBAAkB;AAGnF,MAAI,mBAAmB;AACvB,MAAI,aAAa,CAAC,QAAQ,SAAS;AACjC,YAAQ,IAAI;AACZ,UAAM,cAAc,MAAM,QAAQ;AAAA,MAChC,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AAED,QAAI,aAAa;AACf,YAAM,cAAc,CAAC,GAAG,WAAW,SAAS;AAC5C,yBAAmB;AAAA,IACrB;AAAA,EACF;AAGA,UAAQ,IAAI;AACZ,eAAa,sBAAe;AAC5B,UAAQ,IAAI;AACZ,MAAI,OAAO;AAEX,MAAI,CAAC,oBAAoB,YAAY,mBAAmB;AACtD,kBAAc,QAAQ,mDAAmD;AAAA,EAC3E;AACA,MAAI,kBAAkB;AACpB;AAAA,MACE;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,YAAY,mBAAmB;AACjC;AAAA,MACE;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,cAAc;AAChB;AAAA,MACE;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,EACF;AACA,UAAQ,IAAI;AACd;;;Ae/YA,SAAS,QAAAC,aAAY;AAqBrB,eAAsB,OACpB,MACA,SACA,WACA,WACA,gBACe;AAEf,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,aAAa,SAAS;AAAA,EACzC,SAAS,KAAK;AACZ,QAAI,eAAe,uBAAuB;AACxC,cAAQ;AAAA,QACN;AAAA,MACF;AACA,cAAQ,KAAK,CAAC;AACd;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAGA,MAAI;AACJ,MAAI;AACF,gBAAY,aAAa,IAAI;AAAA,EAC/B,SAAS,KAAK;AACZ,QAAI,eAAe,wBAAwB;AACzC,cAAQ,MAAM,IAAI,OAAO;AACzB,cAAQ,KAAK,CAAC;AACd;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAGA,MAAI,aAAa,UAAU,IAAI,GAAG;AAChC,YAAQ;AAAA,MACN,cAAc,IAAI;AAAA,IACpB;AACA;AAAA,EACF;AAGA,MAAI,YAAY;AAChB,QAAM,iBAA2B,CAAC;AAClC,aAAW,QAAQ,UAAU,OAAO;AAClC,UAAM,UAAUC,MAAK,WAAW,IAAI;AACpC,QAAI,QAAQ,QAAQ;AAClB,cAAQ,IAAI,2BAA2B,IAAI,EAAE;AAAA,IAC/C,OAAO;AACL,YAAM,SAAS,SAAS,WAAW,MAAM,EAAE,OAAO,QAAQ,MAAM,CAAC;AAAA,IACnE;AACA,mBAAe,KAAK,IAAI;AACxB;AAAA,EACF;AACA,aAAW,OAAO,UAAU,eAAe,CAAC,GAAG;AAC7C,UAAM,aAAaA,MAAK,WAAW,GAAG;AACtC,QAAI,QAAQ,QAAQ;AAClB,cAAQ,IAAI,qCAAqC,GAAG,GAAG;AAAA,IACzD,OAAO;AACL,YAAM,SAAS,MAAM,cAAc,YAAY,WAAW,KAAK,EAAE,OAAO,QAAQ,MAAM,CAAC;AACvF,qBAAe,KAAK,GAAG,MAAM;AAC7B,mBAAa,OAAO;AAAA,IACtB;AAAA,EACF;AAEA,MAAI,QAAQ,QAAQ;AAClB,YAAQ;AAAA,MACN;AAAA,iCAAoC,IAAI,YAAY,SAAS;AAAA,IAC/D;AACA;AAAA,EACF;AAGA,QAAM,eAAmC;AAAA,IACvC;AAAA,IACA,OAAO;AAAA,IACP,kBAAkB;AAAA,EACpB;AACA,QAAM,UAAU,aAAa,UAAU,YAAY;AACnD,QAAM,cAAc,WAAW,OAAO;AAEtC,UAAQ;AAAA,IACN;AAAA,0BAA6B,IAAI,YAAY,SAAS;AAAA,EACxD;AACF;;;AC3GA,SAAS,QAAAC,aAAY;;;ACArB,SAAS,WAAAC,gBAAe;AACxB,SAAS,WAAAC,UAAS,aAAAC,kBAAiB;AACnC,SAAS,QAAAC,aAAY;AAoBd,IAAM,qBAAyC;AAAA,EACpD;AAAA,IACE,OAAO;AAAA,IACP,eAAe,CAAC,MAAM,EAAE,SAAS;AAAA,IACjC,KAAK,YAAY;AACf,YAAM,QAAQ,MAAMC,SAAQ;AAAA,QAC1B,SACE;AAAA,QACF,SAAS;AAAA,MACX,CAAC;AACD,aAAO,EAAE,MAAO,QAAQ,QAAQ,WAAuB;AAAA,IACzD;AAAA,EACF;AACF;AASA,eAAsB,qBACpB,UACkC;AAClC,QAAM,aAAa,mBAAmB,OAAO,CAAC,MAAM,EAAE,cAAc,QAAQ,CAAC;AAC7E,MAAI,WAAW,WAAW,EAAG,QAAO,CAAC;AAErC,UAAQ,IAAI;AACZ,UAAQ;AAAA,IACN,yBAAyB,WAAW,MAAM,kBAAkB,WAAW,WAAW,IAAI,KAAK,GAAG;AAAA,EAChG;AAEA,MAAI,QAAiC,CAAC;AACtC,aAAW,YAAY,YAAY;AACjC,UAAM,SAAS,MAAM,SAAS,IAAI;AAClC,YAAQ,EAAE,GAAG,OAAO,GAAG,OAAO;AAAA,EAChC;AACA,SAAO;AACT;AASA,eAAsB,sBACpB,WACA,cACe;AACf,QAAM,eAAeC,MAAK,WAAW,cAAc,eAAe;AAClE,MAAI,MAAM,WAAW,YAAY,EAAG;AAEpC,QAAM,mBAAmBA,MAAK,WAAW,YAAY;AACrD,MAAI;AACJ,MAAI;AACF,UAAM,UAAU,MAAMC,SAAQ,kBAAkB,EAAE,eAAe,KAAK,CAAC;AACvE,kBAAc,QACX,OAAO,CAAC,MAAM,EAAE,YAAY,KAAK,EAAE,SAAS,WAAW,EACvD,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,EACtB,QAAQ;AACN;AAAA,EACF;AACA,MAAI,YAAY,WAAW,EAAG;AAE9B,UAAQ,IAAI;AACZ,QAAM,WAAW,MAAMF,SAAQ;AAAA,IAC7B,SAAS,SAAS,YAAY,MAAM,UAAU,YAAY,WAAW,IAAI,KAAK,GAAG,UAAU,YAAY,iBAAiB,YAAY;AAAA,IACpI,SAAS;AAAA,EACX,CAAC;AACD,MAAI,CAAC,SAAU;AAEf,QAAM,WAAoC,CAAC;AAC3C,aAAW,QAAQ,aAAa;AAC9B,UAAM,UAAU,MAAMA,SAAQ,EAAE,SAAS,cAAc,IAAI,MAAM,SAAS,KAAK,CAAC;AAChF,QAAI,CAAC,QAAS;AACd,aAAS,IAAI,IAAI;AAAA,MACf,MAAM;AAAA,MACN,SAAS,CAAC;AAAA,MACV,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,UAAU;AAAA,MACV,OAAO,CAAC;AAAA,IACV;AAAA,EACF;AACA,MAAI,OAAO,KAAK,QAAQ,EAAE,WAAW,GAAG;AACtC,YAAQ,IAAI,iDAAiD;AAC7D;AAAA,EACF;AAEA,QAAM,WAAW;AAAA,IACf,UACE;AAAA,IAGF,UAAS,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAAA,IAC7C;AAAA,EACF;AACA,QAAMG,WAAU,cAAc,KAAK,UAAU,UAAU,MAAM,CAAC,IAAI,MAAM,OAAO;AAC/E,UAAQ;AAAA,IACN,uBAAkB,YAAY,uBAAuB,OAAO,KAAK,QAAQ,EAAE,MAAM;AAAA,EACnF;AACF;;;ADrGA,eAAsB,UACpB,SACA,WACA,WACA,gBACe;AAEf,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,aAAa,SAAS;AAAA,EACzC,SAAS,KAAK;AACZ,QAAI,eAAe,uBAAuB;AACxC,cAAQ;AAAA,QACN;AAAA,MACF;AACA,cAAQ,KAAK,CAAC;AACd;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAEA,UAAQ;AAAA,IACN,oBAAoB,cAAc;AAAA,EACpC;AACA,UAAQ;AAAA,IACN;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,qBAAqB,SAAS;AACrD,MAAI,SAAS,WAAW,kBAAkB;AACxC,YAAQ;AAAA,MACN;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AACd;AAAA,EACF;AACA,MAAI,SAAS,WAAW,cAAc;AACpC,YAAQ;AAAA,MACN;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AACd;AAAA,EACF;AACA,MAAI,SAAS,qBAAqB,GAAG;AACnC,YAAQ;AAAA,MACN,uCAAuC,SAAS,kBAAkB,sBAAsB,SAAS,uBAAuB,IAAI,KAAK,GAAG;AAAA,IACtI;AACA,YAAQ,KAAK,CAAC;AACd;AAAA,EACF;AAGA,MAAI,SAAS,YAAY,kBAAkB,SAAS,WAAW,SAAS,GAAG;AACzE,YAAQ,IAAI,qBAAqB;AACjC;AAAA,EACF;AAEA,MAAI,SAAS,WAAW,WAAW,GAAG;AACpC,YAAQ,IAAI,6CAA6C;AACzD;AAAA,EACF;AAEA,MAAI,YAAY;AAChB,QAAM,oBAA0C,CAAC;AAEjD,aAAW,aAAa,SAAS,YAAY;AAE3C,QAAI;AACJ,QAAI;AACF,kBAAY,aAAa,UAAU,IAAI;AAAA,IACzC,SAAS,KAAK;AACZ,UAAI,eAAe,wBAAwB;AAEzC,gBAAQ,IAAI,OAAO,UAAU,IAAI,mCAA8B;AAC/D,0BAAkB,KAAK,SAAS;AAChC;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAGA,UAAM,eAAyB,CAAC;AAChC,eAAW,QAAQ,UAAU,OAAO;AAClC,YAAM,UAAUC,MAAK,WAAW,IAAI;AACpC,YAAM,mBAAmB,UAAU,gBAC9B,MAAM,WAAWA,MAAK,WAAW,IAAI,CAAC;AAC3C,UAAI,kBAAkB;AACpB,gBAAQ,IAAI,KAAK,QAAQ,SAAS,6BAA6B,WAAW,KAAK,IAAI,EAAE;AAAA,MACvF,WAAW,QAAQ,QAAQ;AACzB,gBAAQ,IAAI,6BAA6B,IAAI,EAAE;AAC/C;AAAA,MACF,OAAO;AACL,cAAM,SAAS,SAAS,WAAW,MAAM,EAAE,OAAO,KAAK,CAAC;AACxD;AAAA,MACF;AACA,mBAAa,KAAK,IAAI;AAAA,IACxB;AAEA,eAAW,OAAO,UAAU,eAAe,CAAC,GAAG;AAC7C,YAAM,aAAaA,MAAK,WAAW,GAAG;AACtC,UAAI,QAAQ,QAAQ;AAClB,gBAAQ,IAAI,uCAAuC,GAAG,GAAG;AAAA,MAC3D,OAAO;AACL,cAAM,SAAS,MAAM,cAAc,YAAY,WAAW,KAAK,EAAE,OAAO,KAAK,CAAC;AAC9E,qBAAa,KAAK,GAAG,MAAM;AAC3B,qBAAa,OAAO;AAAA,MACtB;AAAA,IACF;AAEA,sBAAkB,KAAK;AAAA,MACrB,GAAG;AAAA,MACH,OAAO;AAAA,MACP,kBAAkB;AAAA,IACpB,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,QAAQ;AAClB,YAAQ;AAAA,MACN;AAAA,yBAA4B,SAAS;AAAA,IACvC;AACA,UAAM,sBAAsB,mBAAmB,OAAO,CAAC,MAAM,EAAE,cAAc,QAAQ,CAAC;AACtF,QAAI,oBAAoB,SAAS,GAAG;AAClC,cAAQ;AAAA,QACN,uBAAuB,oBAAoB,MAAM,8BAA8B,oBAAoB,WAAW,IAAI,KAAK,GAAG,KAAK,oBAAoB,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;AAAA,MACnL;AAAA,IACF;AACA;AAAA,EACF;AAIA,QAAM,gBAAgB,MAAM,qBAAqB,QAAQ;AAIzD,QAAM,UAA0B;AAAA,IAC9B,GAAG;AAAA,IACH,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,GAAG;AAAA,EACL;AACA,QAAM,cAAc,WAAW,OAAO;AAEtC,UAAQ;AAAA,IACN;AAAA,iBAAoB,SAAS;AAAA,EAC/B;AAIA,MAAI,SAAS,SAAS,SAAS,QAAQ,SAAS,OAAO;AACrD,UAAM,sBAAsB,WAAW,QAAQ,iBAAiB,UAAU;AAAA,EAC5E;AACF;;;AElLA,SAAS,YAAAC,WAAU,aAAAC,YAAW,SAAAC,cAAa;AAC3C,SAAS,SAAS,QAAAC,aAAY;AAC9B,SAAS,WAAAC,gBAAe;AACxB,SAAS,qBAAqB;AAG9B,IAAMC,WAAU,cAAc,YAAY,GAAG;AAOtC,SAAS,aAAqB;AACnC,QAAMC,OAAMD,SAAQ,oBAAoB;AACxC,QAAM,MAAMC,KAAI,eAAe;AAC/B,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,qBAAqBH,MAAKC,SAAQ,GAAG,WAAW,oBAAoB;AAC1E,IAAM,eAAe,KAAK,KAAK,KAAK;AAUpC,eAAsB,UACpB,WAC4B;AAC5B,MAAI;AACF,UAAM,UAAU,MAAMJ,UAAS,WAAW,OAAO;AACjD,UAAM,SAAS,KAAK,MAAM,OAAO;AACjC,QAAI,OAAO,OAAO,WAAW,YAAY,OAAO,OAAO,cAAc,UAAU;AAC7E,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,WACpB,WACA,QACe;AACf,QAAME,OAAM,QAAQ,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC;AACnD,QAAM,QAAoB,EAAE,QAAQ,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE;AACxE,QAAMD,WAAU,WAAW,KAAK,UAAU,OAAO,MAAM,CAAC,GAAG,OAAO;AACpE;AAMA,eAAsB,iBAAiB,SAAyC;AAC9E,QAAM,iBAAiB,QAAQ,SAAS,GAAG,IAAI,UAAU,UAAU;AACnE,QAAM,MAAM,GAAG,cAAc;AAC7B,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,SAAS,EAAE,QAAQ,mBAAmB;AAAA,MACtC,QAAQ,YAAY,QAAQ,GAAI;AAAA,IAClC,CAAC;AACD,QAAI,CAAC,SAAS,GAAI,QAAO;AACzB,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,WAAO,KAAK,WAAW,GAAG,UAAU;AAAA,EACtC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMA,eAAsB,eACpB,gBACA,SACA,YAAoB,oBACS;AAC7B,MAAI;AACF,QAAI,SAAwB;AAE5B,UAAM,SAAS,MAAM,UAAU,SAAS;AACxC,QAAI,QAAQ;AACV,YAAM,MAAM,KAAK,IAAI,IAAI,IAAI,KAAK,OAAO,SAAS,EAAE,QAAQ;AAC5D,UAAI,MAAM,cAAc;AACtB,iBAAS,OAAO;AAAA,MAClB;AAAA,IACF;AAEA,QAAI,WAAW,MAAM;AACnB,eAAS,MAAM,iBAAiB,OAAO;AACvC,UAAI,WAAW,MAAM;AACnB,YAAI;AACF,gBAAM,WAAW,WAAW,MAAM;AAAA,QACpC,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA,iBAAiB,WAAW,QAAQ,WAAW;AAAA,IACjD;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,iBAAiB;AAAA,MACjB,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,IACxD;AAAA,EACF;AACF;;;AC5GA,eAAsB,UACpB,WACA,gBACe;AAEf,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,aAAa,SAAS;AAAA,EACzC,SAAS,KAAK;AACZ,QAAI,eAAe,uBAAuB;AACxC,cAAQ;AAAA,QACN;AAAA,MACF;AACA,cAAQ,KAAK,CAAC;AACd;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAEA,MAAI,SAAS,WAAW,WAAW,GAAG;AACpC,YAAQ,IAAI,0BAA0B;AACtC;AAAA,EACF;AAGA,MAAI;AACJ,MAAI;AACF,cAAU,WAAW;AAAA,EACvB,QAAQ;AACN,cAAU;AAAA,EACZ;AAEA,QAAM,gBAAgB,UAClB,MAAM,eAAe,gBAAgB,OAAO,IAC5C,EAAE,SAAS,gBAAgB,QAAQ,MAAM,iBAAiB,OAAO,OAAO,uBAAuB;AAKnG,QAAM,YAAY,KAAK;AAAA,IACrB,YAAY;AAAA,IACZ,GAAG,SAAS,WAAW,IAAI,CAAC,MAAM,EAAE,KAAK,MAAM;AAAA,EACjD;AACA,QAAM,aAAa,QAAQ;AAC3B,QAAM,eAAe,KAAK;AAAA,IACxB,UAAU;AAAA,IACV,GAAG,SAAS,WAAW,IAAI,CAAC,MAAM,EAAE,iBAAiB,MAAM;AAAA,EAC7D;AAEA,QAAM,MAAM,CAAC,GAAW,MAAc,EAAE,OAAO,CAAC;AAChD,QAAM,OAAO,CAAC,GAAW,MAAc,EAAE,SAAS,CAAC;AAEnD,UAAQ;AAAA,IACN,KAAK,IAAI,aAAa,SAAS,CAAC,KAAK,KAAK,SAAS,UAAU,CAAC,KAAK,IAAI,WAAW,YAAY,CAAC;AAAA,EACjG;AACA,UAAQ;AAAA,IACN,KAAK,IAAI,OAAO,SAAS,CAAC,KAAK,IAAI,OAAO,UAAU,CAAC,KAAK,IAAI,OAAO,YAAY,CAAC;AAAA,EACpF;AAEA,aAAW,aAAa,SAAS,YAAY;AAC3C,UAAM,QAAQ,UAAU;AACxB,UAAM,YAAY,UAAU,MAAM,OAAO,SAAS;AAClD,UAAM,iBAAiB,UAAU;AACjC,YAAQ;AAAA,MACN,KAAK,IAAI,OAAO,SAAS,CAAC,KAAK,KAAK,WAAW,UAAU,CAAC,KAAK,cAAc;AAAA,IAC/E;AAAA,EACF;AAIA,UAAQ,IAAI,EAAE;AAEd,QAAM,YAAY,cAAc,QAC5B,oBACC,cAAc,UAAU,SAAS;AAEtC,MAAI,SAAS,gBAAgB,cAAc,aAAa,SAAS;AAEjE,MAAI,cAAc,iBAAiB;AACjC,cAAU;AAAA,EACZ;AAEA,UAAQ,IAAI,MAAM;AACpB;;;ACrGA,SAAS,MAAAM,WAAU;AACnB,SAAS,QAAAC,aAAY;AACrB,SAAS,WAAAC,gBAAe;AAiBxB,eAAsB,aACpB,SACA,WACe;AAEf,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,aAAa,SAAS;AAAA,EACzC,SAAS,KAAK;AACZ,QAAI,eAAe,uBAAuB;AACxC,cAAQ,MAAM,0CAA0C;AACxD,cAAQ,KAAK,CAAC;AACd;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAGA,QAAM,WAAW,SAAS,WAAW,QAAQ,CAAC,MAAM,EAAE,KAAK;AAC3D,QAAM,aAAa,SAAS;AAG5B,MAAI,QAAQ,QAAQ;AAClB,eAAW,QAAQ,UAAU;AAC3B,cAAQ,IAAI,2BAA2B,IAAI,EAAE;AAAA,IAC/C;AACA,YAAQ,IAAI,sCAAsC;AAClD,YAAQ,IAAI,qDAAqD;AACjE,YAAQ,IAAI,qDAAqD;AACjE,YAAQ,IAAI,wDAAwD;AACpE,YAAQ,IAAI,6CAA6C;AACzD,YAAQ,IAAI,2FAA2F;AACvG,YAAQ,IAAI;AAAA,YAAe,UAAU,uDAAuD;AAC5F;AAAA,EACF;AAGA,MAAI,CAAC,QAAQ,KAAK;AAChB,UAAM,YAAY,MAAMC,SAAQ;AAAA,MAC9B,SAAS,oBAAoB,UAAU;AAAA,MACvC,SAAS;AAAA,IACX,CAAC;AAED,QAAI,CAAC,WAAW;AACd,cAAQ,IAAI,sBAAsB;AAClC;AAAA,IACF;AAAA,EACF;AAGA,MAAI,UAAU;AACd,aAAW,aAAa,SAAS,YAAY;AAC3C,eAAW,QAAQ,UAAU,OAAO;AAClC,YAAM,WAAWC,MAAK,WAAW,IAAI;AACrC,UAAI;AACF,cAAMC,IAAG,UAAU,EAAE,OAAO,KAAK,CAAC;AAClC;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAGA,QAAMA,IAAGD,MAAK,WAAW,cAAc,GAAG,EAAE,OAAO,KAAK,CAAC;AAIzD,QAAM,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,aAAW,OAAO,WAAW;AAC3B,UAAMC,IAAGD,MAAK,WAAW,GAAG,GAAG,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACjE;AAEA,QAAMC,IAAGD,MAAK,WAAW,qBAAqB,GAAG,EAAE,OAAO,KAAK,CAAC;AAGhE,QAAM,cAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,aAAW,QAAQ,aAAa;AAC9B,UAAM,mBAAmB,WAAW,MAAM,EAAE,QAAQ,MAAM,CAAC;AAAA,EAC7D;AAEA,UAAQ,IAAI;AAAA,4BAAqB,OAAO,iBAAiB;AAC3D;;;AC7GA,SAAS,UAAAE,SAAQ,YAAAC,WAAU,SAAAC,QAAO,YAAYC,mBAAkB;AAChE,SAAS,QAAAC,QAAM,WAAAC,gBAAe;AAC9B,SAAS,YAAAC,iBAAgB;AACzB,SAAS,iBAAiB;;;ACanB,IAAM,iBAAmC;AAAA,EAC9C,EAAE,IAAI,SAAS,UAAU,UAAU,QAAQ,SAAS,YAAY,aAAa,OAAO,QAAQ,YAAY,aAAa;AAAA,EACrH,EAAE,IAAI,SAAS,UAAU,UAAU,QAAQ,SAAS,YAAY,aAAa,OAAO,QAAQ,YAAY,aAAa;AAAA,EACrH,EAAE,IAAI,SAAS,UAAU,QAAQ,QAAQ,SAAS,YAAY,aAAa,OAAO,QAAQ,YAAY,aAAa;AAAA,EACnH,EAAE,IAAI,SAAS,UAAU,QAAQ,QAAQ,SAAS,YAAY,aAAa,OAAO,QAAQ,YAAY,aAAa;AAAA,EACnH,EAAE,IAAI,SAAS,UAAU,QAAQ,QAAQ,SAAS,YAAY,YAAY,OAAO,QAAQ,YAAY,aAAa;AAAA,EAClH,EAAE,IAAI,SAAS,UAAU,QAAQ,QAAQ,SAAS,YAAY,aAAa,OAAO,QAAQ,YAAY,aAAa;AAAA,EACnH,EAAE,IAAI,SAAS,UAAU,UAAU,QAAQ,SAAS,YAAY,aAAa,OAAO,QAAQ,YAAY,aAAa;AAAA,EACrH,EAAE,IAAI,SAAS,UAAU,QAAQ,QAAQ,kBAAkB,YAAY,aAAa,OAAO,YAAY,YAAY,cAAc,YAAY,gBAAgB;AAAA,EAC7J,EAAE,IAAI,SAAS,UAAU,QAAQ,QAAQ,YAAY,YAAY,aAAa,OAAO,YAAY,YAAY,cAAc,YAAY,QAAQ;AAAA,EAC/I,EAAE,IAAI,SAAS,UAAU,QAAQ,QAAQ,YAAY,YAAY,aAAa,OAAO,YAAY,YAAY,cAAc,YAAY,QAAQ;AAAA,EAC/I,EAAE,IAAI,SAAS,UAAU,QAAQ,QAAQ,YAAY,YAAY,aAAa,OAAO,YAAY,YAAY,cAAc,YAAY,QAAQ;AAAA,EAC/I,EAAE,IAAI,SAAS,UAAU,UAAU,QAAQ,SAAS,YAAY,aAAa,OAAO,YAAY,YAAY,cAAc,YAAY,QAAQ;AAChJ;;;AC3BA,IAAM,mBAAmB;AACzB,IAAM,sBAAsB,oBAAI,IAAI,CAAC,YAAY,MAAM,CAAC;AACxD,IAAM,oBAAoB,oBAAI,IAAI,CAAC,kBAAkB,UAAU,CAAC;AASzD,SAAS,qBAAqB,SAA+C;AAClF,QAAM,WAAqB,CAAC;AAC5B,QAAM,gBAA0B,CAAC;AACjC,QAAM,OAAO,oBAAI,IAAY;AAE7B,aAAW,UAAU,SAAS;AAC5B,QAAI,KAAK,IAAI,OAAO,EAAE,GAAG;AACvB,eAAS,KAAK,GAAG,OAAO,EAAE,6BAA6B;AACvD;AAAA,IACF;AACA,SAAK,IAAI,OAAO,EAAE;AAElB,QAAI,OAAO,eAAe,WAAY;AACtC,QAAI,CAAC,kBAAkB,IAAI,OAAO,MAAM,EAAG;AAE3C,QAAI,CAAC,OAAO,UAAU;AACpB,eAAS,KAAK,GAAG,OAAO,EAAE,eAAe,OAAO,MAAM,+BAA+B;AACrF;AAAA,IACF;AACA,QAAI,CAAC,oBAAoB,IAAI,OAAO,QAAQ,EAAG;AAE/C,QAAI,OAAO,UAAU,YAAY;AAC/B,UAAI,CAAC,OAAO,YAAY,KAAK,GAAG;AAC9B,iBAAS,KAAK,GAAG,OAAO,EAAE,oDAAoD;AAAA,MAChF;AACA;AAAA,IACF;AAEA,QAAI,OAAO,UAAU,YAAY;AAC/B,UAAI,CAAC,OAAO,YAAY,CAAC,iBAAiB,KAAK,OAAO,QAAQ,GAAG;AAC/D,iBAAS;AAAA,UACP,GAAG,OAAO,EAAE;AAAA,QACd;AAAA,MACF,OAAO;AACL,sBAAc,KAAK,GAAG,OAAO,EAAE,KAAK,OAAO,QAAQ,EAAE;AAAA,MACvD;AACA;AAAA,IACF;AAEA,aAAS;AAAA,MACP,GAAG,OAAO,EAAE,gBAAgB,OAAO,QAAQ,IAAI,OAAO,MAAM;AAAA,IAC9D;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS,SAAS,SAAS;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,SAAS,QAAQ;AAAA,EACnB;AACF;;;AFvDA,IAAM,gBAAgB,UAAUC,SAAQ;AAcxC,eAAe,mBAAyC;AACtD,QAAM,OAAO;AACb,QAAM,MAAM,QAAQ;AACpB,QAAM,QAAQ,SAAS,IAAI,QAAQ,MAAM,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE;AACrE,MAAI,SAAS,IAAI;AACf,WAAO,EAAE,MAAM,QAAQ,MAAM,SAAS,GAAG,GAAG,mBAAmB;AAAA,EACjE;AACA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,IACR,SAAS,GAAG,GAAG;AAAA,EACjB;AACF;AAEA,eAAe,qBACb,IACA,OACsB;AACtB,QAAM,OAAO,sBAAsB,KAAK;AAGxC,QAAM,OAAO,QAAQ,IAAI,MAAM,KAAK;AACpC,QAAM,UAAU;AAAA,IACdC,OAAK,MAAM,WAAW,YAAY;AAAA,IAClCA,OAAK,MAAM,oBAAoB,YAAY;AAAA,EAC7C;AAEA,aAAW,OAAO,SAAS;AACzB,QAAI;AACF,YAAM,EAAE,SAAAC,SAAQ,IAAI,MAAM,OAAO,aAAkB;AACnD,YAAM,UAAU,MAAMA,SAAQ,GAAG;AACjC,YAAM,SAAS,GAAG,YAAY,IAAI;AAClC,YAAM,QAAQ,QAAQ;AAAA,QACpB,CAAC,MAAM,EAAE,YAAY,MAAM,GAAG,YAAY,KAAK,EAAE,YAAY,EAAE,WAAW,MAAM;AAAA,MAClF;AACA,UAAI,OAAO;AACT,eAAO,EAAE,MAAM,QAAQ,MAAM,SAAS,GAAG,EAAE,gBAAgB;AAAA,MAC7D;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAGA,MAAI,aAAa;AACjB,aAAW,OAAO,CAAC,QAAQ,eAAe,GAAG;AAC3C,QAAI;AACF,YAAM,cAAc,KAAK,CAAC,WAAW,CAAC;AACtC,mBAAa;AACb;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,IACR,SAAS,GAAG,EAAE,4BAA4B,UAAU,wBAAwB,EAAE;AAAA,IAC9E,UAAU;AAAA,EACZ;AACF;AAEA,eAAsB,oBAAoB,WAAyC;AACjF,QAAM,OAAO;AACb,QAAMC,gBAAeF,OAAK,WAAW,cAAc;AACnD,MAAI;AACF,UAAMG,QAAOD,aAAY;AAAA,EAC3B,QAAQ;AACN,UAAM,yBAAyBF,OAAK,WAAW,OAAO,UAAU,cAAc;AAC9E,QAAI;AACF,YAAM,MAAM,MAAMI,UAAS,wBAAwB,MAAM;AACzD,YAAM,WAAW,KAAK,MAAM,GAAG;AAI/B,UAAI,SAAS,eAAe,QAAQ,SAAS,kBAAkB,YAAY;AACzE,eAAO;AAAA,UACL;AAAA,UACA,QAAQ;AAAA,UACR,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AACA,WAAO;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,MAAI;AACF,UAAM,MAAM,MAAMA,UAASF,eAAc,MAAM;AAC/C,UAAM,WAAW,KAAK,MAAM,GAAG;AAC/B,QAAI,CAAC,SAAS,WAAW,CAAC,MAAM,QAAQ,SAAS,UAAU,GAAG;AAC5D,aAAO;AAAA,QACL;AAAA,QACA,QAAQ;AAAA,QACR,SAAS;AAAA,MACX;AAAA,IACF;AACA,WAAO;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,MACR,SAAS,IAAI,SAAS,OAAO,WAAM,SAAS,WAAW,MAAM;AAAA,IAC/D;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAWA,eAAsB,gBAAgB,WAAyC;AAC7E,QAAM,OAAO;AACb,MAAI;AAKF,UAAM,EAAE,OAAO,IAAI,MAAM,OAAO,WAAW,CAAC,UAAU,eAAe,SAAS,aAAa,CAAC;AAC5F,UAAM,QAAQ,OAAO,KAAK;AAC1B,QAAI,UAAU,QAAQ;AACpB,aAAO,EAAE,MAAM,QAAQ,MAAM,SAAS,mBAAmB;AAAA,IAC3D;AACA,WAAO;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,MACR,SAAS,4BAA4B,KAAK;AAAA,MAC1C,UAAU;AAAA,IACZ;AAAA,EACF,QAAQ;AAIN,WAAO;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,UAAU;AAAA,IACZ;AAAA,EACF;AACF;AAEO,SAAS,2BAAwC;AACtD,QAAM,SAAS,qBAAqB,cAAc;AAClD,MAAI,OAAO,SAAS;AAClB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,OAAO,SAAS,KAAK,IAAI;AAAA,IACpC;AAAA,EACF;AACA,QAAM,WAAW,OAAO,cAAc,SAAS,IAC3C,KAAK,OAAO,cAAc,MAAM,yBAChC;AACJ,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS,GAAG,OAAO,OAAO,wBAAwB,QAAQ;AAAA,EAC5D;AACF;AAKO,IAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,eAAsB,uBAAuB,WAA2C;AACtF,QAAM,UAAyB,CAAC;AAEhC,aAAW,QAAQ,0BAA0B;AAC3C,UAAM,OAAO,iBAAiB,IAAI;AAClC,UAAM,WAAWF,OAAK,WAAW,IAAI;AACrC,QAAI;AACF,YAAMG,QAAO,QAAQ;AACrB,cAAQ,KAAK,EAAE,MAAM,QAAQ,MAAM,SAAS,UAAU,CAAC;AAAA,IACzD,QAAQ;AACN,cAAQ,KAAK;AAAA,QACX;AAAA,QACA,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAsB,qBAAqB,WAAmB,WAAsC;AAClG,QAAM,UAAoB,CAAC;AAE3B,aAAW,QAAQ,0BAA0B;AAC3C,UAAM,WAAWH,OAAK,WAAW,IAAI;AACrC,QAAI;AACF,YAAMG,QAAO,QAAQ;AAAA,IAEvB,QAAQ;AAEN,YAAM,UAAUH,OAAK,WAAW,IAAI;AACpC,YAAMK,OAAMC,SAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAClD,YAAMC,YAAW,SAAS,QAAQ;AAClC,cAAQ,KAAK,IAAI;AAAA,IACnB;AAAA,EACF;AAEA,SAAO;AACT;AAQA,eAAsB,UAAU,WAAmB,UAAyB,CAAC,GAAG,WAAmC;AACjH,UAAQ,IAAI,0DAAqD;AAEjE,QAAM,UAAU,MAAM,QAAQ,IAAI;AAAA,IAChC,iBAAiB;AAAA,IACjB,qBAAqB,uBAAuB,uBAAuB;AAAA,IACnE,oBAAoB,SAAS;AAAA,IAC7B,QAAQ,QAAQ,yBAAyB,CAAC;AAAA,IAC1C,gBAAgB,SAAS;AAAA,EAC3B,CAAC;AAGD,QAAM,iBAAiB,MAAM,uBAAuB,SAAS;AAC7D,UAAQ,KAAK,GAAG,cAAc;AAE9B,MAAI,YAAY;AAEhB,aAAW,UAAU,SAAS;AAC5B,UAAM,OAAO,OAAO,SAAS,WAAM,OAAO,aAAa,QAAQ,WAAM;AACrE,UAAM,QAAQ,OAAO,SACjB,SACA,OAAO,aAAa,QAClB,SACA;AACN,YAAQ,IAAI,KAAK,IAAI,KAAK,KAAK,KAAK,OAAO,IAAI,EAAE;AACjD,QAAI,CAAC,OAAO,QAAQ;AAClB,cAAQ,IAAI,YAAY,OAAO,OAAO,EAAE;AAAA,IAC1C;AACA,QAAI,CAAC,OAAO,UAAU,OAAO,aAAa,OAAO;AAC/C,kBAAY;AAAA,IACd;AAAA,EACF;AAEA,UAAQ,IAAI;AAEZ,MAAI,WAAW;AACb,YAAQ,IAAI,mDAAmD;AAAA,EACjE,OAAO;AACL,YAAQ,IAAI,wEAAwE;AAGpF,UAAM,oBAAoB,eAAe,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM;AAC9D,QAAI,QAAQ,OAAO,qBAAqB,WAAW;AACjD,cAAQ,IAAI,0DAAmD;AAC/D,YAAM,UAAU,MAAM,qBAAqB,WAAW,SAAS;AAC/D,UAAI,QAAQ,SAAS,GAAG;AACtB,mBAAW,QAAQ,SAAS;AAC1B,kBAAQ,IAAI,uBAAkB,IAAI,EAAE;AAAA,QACtC;AACA,gBAAQ,IAAI;AAAA,IAAO,QAAQ,MAAM;AAAA,CAAsD;AAAA,MACzF,OAAO;AACL,gBAAQ,IAAI,+CAA+C;AAAA,MAC7D;AAAA,IACF,WAAW,qBAAqB,CAAC,QAAQ,KAAK;AAC5C,cAAQ,IAAI,yEAAkE;AAAA,IAChF;AAEA,QAAI,CAAC,WAAW;AACd,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF;AACF;;;AtBtHA,SAAS,oBAAoB;AA1L7B,IAAMC,WAAUC,eAAc,YAAY,GAAG;AAC7C,IAAM,MAAMD,SAAQ,iBAAiB;AAQ9B,IAAM,aACX,QAAQ,IAAI,mBAAmB,KAC/BE,OAAKC,SAAQ,cAAc,YAAY,GAAG,CAAC,GAAG,QAAQ;AAExD,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,OAAO,EACZ,YAAY,kEAA6D,EACzE,QAAQ,IAAI,OAAO,EACnB,OAAO,YAAY;AAGlB,QAAM,aAAa,IAAI,SAAS,QAAQ,IAAI,CAAC;AAC7C,UAAQ,WAAW;AACrB,CAAC;AAEH,QACG,QAAQ,MAAM,EACd,YAAY,6DAA6D,EACzE,OAAO,uBAAuB,sDAAsD,EACpF,OAAO,WAAW,wCAAwC,EAC1D,OAAO,aAAa,wDAAwD,EAC5E;AAAA,EACC,OAAO,SAAkE;AACvE,UAAM;AAAA,MACJ;AAAA,QACE,SAAS,KAAK;AAAA,QACd,OAAO,KAAK;AAAA,QACZ,QAAQ,KAAK;AAAA,MACf;AAAA,MACA,QAAQ,IAAI;AAAA,MACZ;AAAA,MACA,IAAI;AAAA,IACN;AAAA,EACF;AACF;AAEF,QACG,QAAQ,iBAAiB,EACzB,YAAY,oDAAoD,EAChE,OAAO,WAAW,wCAAwC,EAC1D,OAAO,aAAa,oDAAoD,EACxE;AAAA,EACC,OACE,WACA,SACG;AACH,UAAM;AAAA,MACJ;AAAA,MACA,EAAE,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAO;AAAA,MACzC,QAAQ,IAAI;AAAA,MACZ;AAAA,MACA,IAAI;AAAA,IACN;AAAA,EACF;AACF;AAEF,QACG,QAAQ,QAAQ,EAChB,YAAY,4DAA4D,EACxE,OAAO,aAAa,sDAAsD,EAC1E,OAAO,OAAO,SAA+B;AAC5C,QAAM;AAAA,IACJ,EAAE,QAAQ,KAAK,OAAO;AAAA,IACtB,QAAQ,IAAI;AAAA,IACZ;AAAA,IACA,IAAI;AAAA,EACN;AACF,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,iDAAiD,EAC7D,OAAO,YAAY;AAClB,QAAM,UAAU,QAAQ,IAAI,GAAG,IAAI,OAAO;AAC5C,CAAC;AAEH,QACG,QAAQ,WAAW,EACnB,YAAY,6CAA6C,EACzD,OAAO,SAAS,0BAA0B,EAC1C,OAAO,aAAa,sDAAsD,EAC1E,OAAO,OAAO,SAA8C;AAC3D,QAAM,aAAa,EAAE,KAAK,KAAK,KAAK,QAAQ,KAAK,OAAO,GAAG,QAAQ,IAAI,CAAC;AAC1E,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,iDAAiD,EAC7D,OAAO,SAAS,uDAAuD,EACvE,OAAO,OAAO,SAA4B;AACzC,QAAM,UAAU,QAAQ,IAAI,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,UAAU;AAC9D,CAAC;AAIH,IAAM,gBAAgB,QACnB,QAAQ,QAAQ,EAChB,YAAY,qDAAqD;AAEpE,cACG,QAAQ,MAAM,EACd;AAAA,EACC;AACF,EACC;AAAA,EACC;AAAA,EACA;AACF,EACC;AAAA,EACC;AAAA,EACA;AACF,EACC,OAAO,WAAW,4CAA4C,EAC9D,OAAO,aAAa,qDAAqD,EACzE;AAAA,EACC,OAAO,SAKD;AACJ,UAAM;AAAA,MACJ;AAAA,QACE,SAAS,KAAK;AAAA,QACd,QAAQ,KAAK;AAAA,QACb,OAAO,KAAK;AAAA,QACZ,QAAQ,KAAK;AAAA,MACf;AAAA,MACA,QAAQ,IAAI;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;AAEF,cACG,QAAQ,MAAM,EACd;AAAA,EACC;AACF,EACC,OAAO,aAAa,uDAAuD,EAC3E,OAAO,iBAAiB,gCAAgC,EACxD,OAAO,gBAAgB,qBAAqB,EAC5C,OAAO,eAAe,oBAAoB,EAC1C,OAAO,cAAc,mBAAmB,EACxC;AAAA,EACC,OAAO,SAMD;AACJ,UAAM;AAAA,MACJ;AAAA,QACE,QAAQ,KAAK;AAAA,QACb,UAAU,KAAK;AAAA,QACf,SAAS,KAAK;AAAA,QACd,QAAQ,KAAK;AAAA,QACb,OAAO,KAAK;AAAA,MACd;AAAA,MACA,QAAQ,IAAI;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;AAEF,cACG,QAAQ,MAAM,EACd,YAAY,6DAA6D,EACzE,OAAO,YAAY;AAClB,QAAM,cAAc,QAAQ,IAAI,CAAC;AACnC,CAAC;AAKH,IAAI,aAAa,QAAQ,KAAK,CAAC,CAAC,MAAM,cAAc,YAAY,GAAG,GAAG;AACpE,QAAM,QAAQ,WAAW,QAAQ,IAAI;AACvC;","names":["createRequire","dirname","join","select","join","chalk","path","manifestPath","mkdir","writeFile","copyFile","join","readFile","readdir","access","path","readFile","readFile","access","writeFile","mkdir","join","readFile","writeFile","path","path","readFile","writeFile","join","mkdir","writeFile","r","join","mkdir","writeFile","copyFile","stdout","chalk","select","join","join","join","join","confirm","readdir","writeFile","join","confirm","join","readdir","writeFile","join","readFile","writeFile","mkdir","join","homedir","require","pkg","rm","join","confirm","confirm","join","rm","access","readFile","mkdir","fsCopyFile","join","dirname","execFile","execFile","join","readdir","manifestPath","access","readFile","mkdir","dirname","fsCopyFile","require","createRequire","join","dirname"]}