kairn-cli 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -524,11 +524,23 @@ async function writeEnvironment(spec, targetDir) {
524
524
  }
525
525
  function summarizeSpec(spec, registry) {
526
526
  const pluginCommands = [];
527
+ const envSetup = [];
527
528
  for (const selected of spec.tools) {
528
529
  const tool = registry.find((t) => t.id === selected.tool_id);
529
- if (tool?.install.plugin_command) {
530
+ if (!tool) continue;
531
+ if (tool.install.plugin_command) {
530
532
  pluginCommands.push(tool.install.plugin_command);
531
533
  }
534
+ if (tool.env_vars) {
535
+ for (const ev of tool.env_vars) {
536
+ envSetup.push({
537
+ toolName: tool.name,
538
+ envVar: ev.name,
539
+ description: ev.description,
540
+ signupUrl: tool.signup_url
541
+ });
542
+ }
543
+ }
532
544
  }
533
545
  return {
534
546
  toolCount: spec.tools.length,
@@ -536,7 +548,8 @@ function summarizeSpec(spec, registry) {
536
548
  ruleCount: Object.keys(spec.harness.rules || {}).length,
537
549
  skillCount: Object.keys(spec.harness.skills || {}).length,
538
550
  agentCount: Object.keys(spec.harness.agents || {}).length,
539
- pluginCommands
551
+ pluginCommands,
552
+ envSetup
540
553
  };
541
554
  }
542
555
 
@@ -629,8 +642,22 @@ var describeCommand = new Command2("describe").description("Describe your workfl
629
642
  for (const file of written) {
630
643
  console.log(chalk2.dim(` ${file}`));
631
644
  }
645
+ if (summary.envSetup.length > 0) {
646
+ console.log(chalk2.yellow("\n API keys needed (set these environment variables):\n"));
647
+ const seen = /* @__PURE__ */ new Set();
648
+ for (const env of summary.envSetup) {
649
+ if (seen.has(env.envVar)) continue;
650
+ seen.add(env.envVar);
651
+ console.log(chalk2.bold(` export ${env.envVar}="your-key-here"`));
652
+ console.log(chalk2.dim(` ${env.description}`));
653
+ if (env.signupUrl) {
654
+ console.log(chalk2.dim(` Get one at: ${env.signupUrl}`));
655
+ }
656
+ console.log("");
657
+ }
658
+ }
632
659
  if (summary.pluginCommands.length > 0) {
633
- console.log(chalk2.yellow("\n Install plugins by running these in Claude Code:"));
660
+ console.log(chalk2.yellow(" Install plugins by running these in Claude Code:"));
634
661
  for (const cmd of summary.pluginCommands) {
635
662
  console.log(chalk2.bold(` ${cmd}`));
636
663
  }
@@ -1188,8 +1215,22 @@ var optimizeCommand = new Command6("optimize").description("Scan an existing pro
1188
1215
  for (const file of written) {
1189
1216
  console.log(chalk6.dim(` ${file}`));
1190
1217
  }
1218
+ if (summary.envSetup.length > 0) {
1219
+ console.log(chalk6.yellow("\n API keys needed (set these environment variables):\n"));
1220
+ const seen = /* @__PURE__ */ new Set();
1221
+ for (const env of summary.envSetup) {
1222
+ if (seen.has(env.envVar)) continue;
1223
+ seen.add(env.envVar);
1224
+ console.log(chalk6.bold(` export ${env.envVar}="your-key-here"`));
1225
+ console.log(chalk6.dim(` ${env.description}`));
1226
+ if (env.signupUrl) {
1227
+ console.log(chalk6.dim(` Get one at: ${env.signupUrl}`));
1228
+ }
1229
+ console.log("");
1230
+ }
1231
+ }
1191
1232
  if (summary.pluginCommands.length > 0) {
1192
- console.log(chalk6.yellow("\n Install plugins by running these in Claude Code:"));
1233
+ console.log(chalk6.yellow(" Install plugins by running these in Claude Code:"));
1193
1234
  for (const cmd of summary.pluginCommands) {
1194
1235
  console.log(chalk6.bold(` ${cmd}`));
1195
1236
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/config.ts","../src/commands/describe.ts","../src/compiler/compile.ts","../src/compiler/prompt.ts","../src/adapter/claude-code.ts","../src/commands/list.ts","../src/commands/activate.ts","../src/commands/update-registry.ts","../src/commands/optimize.ts","../src/scanner/scan.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { describeCommand } from \"./commands/describe.js\";\nimport { listCommand } from \"./commands/list.js\";\nimport { activateCommand } from \"./commands/activate.js\";\nimport { updateRegistryCommand } from \"./commands/update-registry.js\";\nimport { optimizeCommand } from \"./commands/optimize.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"kairn\")\n .description(\n \"Compile natural language intent into optimized Claude Code environments\"\n )\n .version(\"1.0.0\");\n\nprogram.addCommand(initCommand);\nprogram.addCommand(describeCommand);\nprogram.addCommand(optimizeCommand);\nprogram.addCommand(listCommand);\nprogram.addCommand(activateCommand);\nprogram.addCommand(updateRegistryCommand);\n\nprogram.parse();\n","import { Command } from \"commander\";\nimport { password, select } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport Anthropic from \"@anthropic-ai/sdk\";\nimport OpenAI from \"openai\";\nimport { execFileSync } from \"child_process\";\nimport { loadConfig, saveConfig, getConfigPath } from \"../config.js\";\nimport type { KairnConfig, LLMProvider } from \"../types.js\";\n\nconst PROVIDER_MODELS: Record<LLMProvider, { name: string; models: { name: string; value: string }[] }> = {\n anthropic: {\n name: \"Anthropic\",\n models: [\n { name: \"Claude Sonnet 4.6 (recommended — fast, smart)\", value: \"claude-sonnet-4-6\" },\n { name: \"Claude Opus 4.6 (highest quality)\", value: \"claude-opus-4-6\" },\n { name: \"Claude Haiku 4.5 (fastest, cheapest)\", value: \"claude-haiku-4-5-20251001\" },\n ],\n },\n openai: {\n name: \"OpenAI\",\n models: [\n { name: \"GPT-4o (recommended)\", value: \"gpt-4o\" },\n { name: \"GPT-4o mini (faster, cheaper)\", value: \"gpt-4o-mini\" },\n { name: \"o3 (reasoning)\", value: \"o3\" },\n ],\n },\n google: {\n name: \"Google Gemini\",\n models: [\n { name: \"Gemini 2.5 Flash (recommended)\", value: \"gemini-2.5-flash-preview-05-20\" },\n { name: \"Gemini 2.5 Pro (highest quality)\", value: \"gemini-2.5-pro-preview-05-06\" },\n ],\n },\n};\n\nasync function verifyKey(provider: LLMProvider, apiKey: string, model: string): Promise<boolean> {\n try {\n if (provider === \"anthropic\") {\n const client = new Anthropic({ apiKey });\n await client.messages.create({\n model: \"claude-haiku-4-5-20251001\",\n max_tokens: 10,\n messages: [{ role: \"user\", content: \"ping\" }],\n });\n return true;\n } else if (provider === \"openai\") {\n const client = new OpenAI({ apiKey });\n await client.chat.completions.create({\n model: \"gpt-4o-mini\",\n max_tokens: 10,\n messages: [{ role: \"user\", content: \"ping\" }],\n });\n return true;\n } else if (provider === \"google\") {\n // Google uses OpenAI-compatible API\n const client = new OpenAI({\n apiKey,\n baseURL: \"https://generativelanguage.googleapis.com/v1beta/openai/\",\n });\n await client.chat.completions.create({\n model: \"gemini-2.5-flash-preview-05-20\",\n max_tokens: 10,\n messages: [{ role: \"user\", content: \"ping\" }],\n });\n return true;\n }\n return false;\n } catch {\n return false;\n }\n}\n\nfunction detectClaudeCode(): boolean {\n try {\n execFileSync(\"which\", [\"claude\"], { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n}\n\nexport const initCommand = new Command(\"init\")\n .description(\"Set up Kairn with your API key\")\n .action(async () => {\n console.log(chalk.cyan(\"\\n Kairn Setup\\n\"));\n\n const existing = await loadConfig();\n if (existing) {\n console.log(\n chalk.yellow(\" Config already exists at \") +\n chalk.dim(getConfigPath())\n );\n console.log(chalk.yellow(\" Running setup will overwrite it.\\n\"));\n }\n\n const provider = await select<LLMProvider>({\n message: \"LLM provider\",\n choices: [\n { name: \"Anthropic (Claude) — recommended\", value: \"anthropic\" as LLMProvider },\n { name: \"OpenAI (GPT)\", value: \"openai\" as LLMProvider },\n { name: \"Google (Gemini)\", value: \"google\" as LLMProvider },\n ],\n });\n\n const providerInfo = PROVIDER_MODELS[provider];\n\n const model = await select({\n message: \"Compilation model\",\n choices: providerInfo.models,\n });\n\n const apiKey = await password({\n message: `${providerInfo.name} API key`,\n mask: \"*\",\n });\n\n if (!apiKey) {\n console.log(chalk.red(\"\\n No API key provided. Aborting.\"));\n process.exit(1);\n }\n\n console.log(chalk.dim(\"\\n Verifying API key...\"));\n const valid = await verifyKey(provider, apiKey, model);\n\n if (!valid) {\n console.log(\n chalk.red(\" Invalid API key. Check your key and try again.\")\n );\n process.exit(1);\n }\n\n console.log(chalk.green(\" ✓ API key verified\"));\n\n const config: KairnConfig = {\n provider,\n api_key: apiKey,\n model,\n default_runtime: \"claude-code\",\n created_at: new Date().toISOString(),\n };\n\n await saveConfig(config);\n console.log(\n chalk.green(\" ✓ Config saved to \") + chalk.dim(getConfigPath())\n );\n console.log(\n chalk.dim(` ✓ Provider: ${providerInfo.name}, Model: ${model}`)\n );\n\n const hasClaude = detectClaudeCode();\n if (hasClaude) {\n console.log(chalk.green(\" ✓ Claude Code detected\"));\n } else {\n console.log(\n chalk.yellow(\n \" ⚠ Claude Code not found. Install it: npm install -g @anthropic-ai/claude-code\"\n )\n );\n }\n\n console.log(\n chalk.cyan(\"\\n Ready! Run \") +\n chalk.bold(\"kairn describe\") +\n chalk.cyan(\" to create your first environment.\\n\")\n );\n });\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport os from \"os\";\nimport type { KairnConfig } from \"./types.js\";\n\nconst KAIRN_DIR = path.join(os.homedir(), \".kairn\");\nconst CONFIG_PATH = path.join(KAIRN_DIR, \"config.json\");\nconst ENVS_DIR = path.join(KAIRN_DIR, \"envs\");\n\nexport function getKairnDir(): string {\n return KAIRN_DIR;\n}\n\nexport function getConfigPath(): string {\n return CONFIG_PATH;\n}\n\nexport function getEnvsDir(): string {\n return ENVS_DIR;\n}\n\nexport async function ensureDirs(): Promise<void> {\n await fs.mkdir(KAIRN_DIR, { recursive: true });\n await fs.mkdir(ENVS_DIR, { recursive: true });\n}\n\nexport async function loadConfig(): Promise<KairnConfig | null> {\n try {\n const data = await fs.readFile(CONFIG_PATH, \"utf-8\");\n const raw = JSON.parse(data) as Record<string, unknown>;\n\n // Handle old config format (v1.0.0: anthropic_api_key)\n if (raw.anthropic_api_key && !raw.provider) {\n return {\n provider: \"anthropic\",\n api_key: raw.anthropic_api_key as string,\n model: \"claude-sonnet-4-6\",\n default_runtime: \"claude-code\",\n created_at: (raw.created_at as string) || new Date().toISOString(),\n };\n }\n\n return raw as unknown as KairnConfig;\n } catch {\n return null;\n }\n}\n\nexport async function saveConfig(config: KairnConfig): Promise<void> {\n await ensureDirs();\n await fs.writeFile(CONFIG_PATH, JSON.stringify(config, null, 2), \"utf-8\");\n}\n","import { Command } from \"commander\";\nimport { input, confirm } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { loadConfig } from \"../config.js\";\nimport { compile } from \"../compiler/compile.js\";\nimport { writeEnvironment, summarizeSpec } from \"../adapter/claude-code.js\";\nimport { fileURLToPath } from \"url\";\nimport type { RegistryTool } from \"../types.js\";\n\nasync function loadRegistry(): Promise<RegistryTool[]> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidates = [\n path.resolve(__dirname, \"../registry/tools.json\"),\n path.resolve(__dirname, \"../src/registry/tools.json\"),\n path.resolve(__dirname, \"../../src/registry/tools.json\"),\n ];\n for (const candidate of candidates) {\n try {\n const data = await fs.readFile(candidate, \"utf-8\");\n return JSON.parse(data) as RegistryTool[];\n } catch {\n continue;\n }\n }\n throw new Error(\"Could not find tools.json registry\");\n}\n\nexport const describeCommand = new Command(\"describe\")\n .description(\"Describe your workflow and generate a Claude Code environment\")\n .argument(\"[intent]\", \"What you want your agent to do\")\n .option(\"-y, --yes\", \"Skip confirmation prompt\")\n .action(async (intentArg: string | undefined, options: { yes?: boolean }) => {\n // 1. Check config\n const config = await loadConfig();\n if (!config) {\n console.log(\n chalk.red(\"\\n No config found. Run \") +\n chalk.bold(\"kairn init\") +\n chalk.red(\" first.\\n\")\n );\n process.exit(1);\n }\n\n // 2. Get intent\n const intent =\n intentArg ||\n (await input({\n message: \"What do you want your agent to do?\",\n }));\n\n if (!intent.trim()) {\n console.log(chalk.red(\"\\n No description provided. Aborting.\\n\"));\n process.exit(1);\n }\n\n // 3. Compile with progress\n console.log(\"\");\n let spec;\n try {\n spec = await compile(intent, (msg) => {\n process.stdout.write(`\\r ${chalk.dim(msg)} `);\n });\n process.stdout.write(\"\\r \\r\");\n } catch (err) {\n process.stdout.write(\"\\r \\r\");\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(`\\n Compilation failed: ${msg}\\n`));\n process.exit(1);\n }\n\n // 4. Show results\n const registry = await loadRegistry();\n const summary = summarizeSpec(spec, registry);\n\n console.log(chalk.green(\"\\n ✓ Environment compiled\\n\"));\n console.log(chalk.cyan(\" Name: \") + spec.name);\n console.log(chalk.cyan(\" Description: \") + spec.description);\n console.log(chalk.cyan(\" Tools: \") + summary.toolCount);\n console.log(chalk.cyan(\" Commands: \") + summary.commandCount);\n console.log(chalk.cyan(\" Rules: \") + summary.ruleCount);\n console.log(chalk.cyan(\" Skills: \") + summary.skillCount);\n console.log(chalk.cyan(\" Agents: \") + summary.agentCount);\n\n if (spec.tools.length > 0) {\n console.log(chalk.dim(\"\\n Selected tools:\"));\n for (const tool of spec.tools) {\n const regTool = registry.find((t) => t.id === tool.tool_id);\n const name = regTool?.name || tool.tool_id;\n console.log(chalk.dim(` - ${name}: ${tool.reason}`));\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(chalk.yellow(\"\\n Plugins to install manually:\"));\n for (const cmd of summary.pluginCommands) {\n console.log(chalk.yellow(` ${cmd}`));\n }\n }\n\n // 5. Confirm\n console.log(\"\");\n const proceed = options.yes || await confirm({\n message: \"Generate environment in current directory?\",\n default: true,\n });\n\n if (!proceed) {\n console.log(chalk.dim(\"\\n Aborted. Environment saved to ~/.kairn/envs/\\n\"));\n return;\n }\n\n // 6. Write\n const targetDir = process.cwd();\n const written = await writeEnvironment(spec, targetDir);\n\n console.log(chalk.green(\"\\n ✓ Environment written\\n\"));\n for (const file of written) {\n console.log(chalk.dim(` ${file}`));\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(chalk.yellow(\"\\n Install plugins by running these in Claude Code:\"));\n for (const cmd of summary.pluginCommands) {\n console.log(chalk.bold(` ${cmd}`));\n }\n }\n\n console.log(\n chalk.cyan(\"\\n Ready! Run \") +\n chalk.bold(\"claude\") +\n chalk.cyan(\" to start.\\n\")\n );\n });\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport crypto from \"crypto\";\nimport Anthropic from \"@anthropic-ai/sdk\";\nimport OpenAI from \"openai\";\nimport { loadConfig, getEnvsDir, ensureDirs } from \"../config.js\";\nimport { SYSTEM_PROMPT } from \"./prompt.js\";\nimport type { EnvironmentSpec, RegistryTool, KairnConfig } from \"../types.js\";\n\nasync function loadRegistry(): Promise<RegistryTool[]> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidates = [\n path.resolve(__dirname, \"../registry/tools.json\"),\n path.resolve(__dirname, \"../src/registry/tools.json\"),\n path.resolve(__dirname, \"../../src/registry/tools.json\"),\n ];\n for (const candidate of candidates) {\n try {\n const data = await fs.readFile(candidate, \"utf-8\");\n return JSON.parse(data) as RegistryTool[];\n } catch {\n continue;\n }\n }\n throw new Error(\"Could not find tools.json registry\");\n}\n\nfunction buildUserMessage(intent: string, registry: RegistryTool[]): string {\n const registrySummary = registry\n .map(\n (t) =>\n `- ${t.id} (${t.type}, tier ${t.tier}, auth: ${t.auth}): ${t.description} [best_for: ${t.best_for.join(\", \")}]`\n )\n .join(\"\\n\");\n\n return `## User Intent\\n\\n${intent}\\n\\n## Available Tool Registry\\n\\n${registrySummary}\\n\\nGenerate the EnvironmentSpec JSON now.`;\n}\n\nfunction parseSpecResponse(text: string): Omit<EnvironmentSpec, \"id\" | \"intent\" | \"created_at\"> {\n let cleaned = text.trim();\n // Strip markdown code fences\n if (cleaned.startsWith(\"```\")) {\n cleaned = cleaned.replace(/^```(?:json)?\\n?/, \"\").replace(/\\n?```$/, \"\");\n }\n // Try to extract JSON if there's surrounding text\n const jsonMatch = cleaned.match(/\\{[\\s\\S]*\\}/);\n if (!jsonMatch) {\n throw new Error(\n \"LLM response did not contain valid JSON. Try again or use a different model.\"\n );\n }\n try {\n return JSON.parse(jsonMatch[0]);\n } catch (err) {\n throw new Error(\n `Failed to parse LLM response as JSON: ${err instanceof Error ? err.message : String(err)}\\n` +\n `Response started with: ${cleaned.slice(0, 200)}...`\n );\n }\n}\n\nfunction classifyError(err: unknown, provider: string): string {\n const msg = err instanceof Error ? err.message : String(err);\n const status = (err as { status?: number })?.status;\n const code = (err as { code?: string })?.code;\n\n // Network errors\n if (code === \"ECONNREFUSED\" || code === \"ENOTFOUND\" || code === \"ETIMEDOUT\") {\n return `Network error: could not reach ${provider} API. Check your internet connection.`;\n }\n\n // Auth errors\n if (status === 401 || msg.includes(\"invalid\") && msg.includes(\"key\")) {\n return `Invalid API key for ${provider}. Run \\`kairn init\\` to reconfigure.`;\n }\n if (status === 403) {\n return `Access denied by ${provider}. Your API key may lack permissions for this model.`;\n }\n\n // Rate limiting\n if (status === 429 || msg.includes(\"rate limit\") || msg.includes(\"quota\")) {\n return `Rate limited by ${provider}. Wait a moment and try again, or switch to a cheaper model with \\`kairn init\\`.`;\n }\n\n // Model errors\n if (status === 404 || msg.includes(\"not found\") || msg.includes(\"does not exist\")) {\n return `Model not found on ${provider}. Run \\`kairn init\\` to select a valid model.`;\n }\n\n // Overloaded\n if (status === 529 || status === 503 || msg.includes(\"overloaded\")) {\n return `${provider} is temporarily overloaded. Try again in a few seconds.`;\n }\n\n // Token/context limit\n if (msg.includes(\"token\") && (msg.includes(\"limit\") || msg.includes(\"exceed\"))) {\n return `Request too large for the selected model. Try a shorter workflow description.`;\n }\n\n // Billing\n if (msg.includes(\"billing\") || msg.includes(\"payment\") || msg.includes(\"insufficient\")) {\n return `Billing issue with your ${provider} account. Check your account dashboard.`;\n }\n\n // Fallback\n return `${provider} API error: ${msg}`;\n}\n\nasync function callLLM(config: KairnConfig, userMessage: string): Promise<string> {\n if (config.provider === \"anthropic\") {\n const client = new Anthropic({ apiKey: config.api_key });\n try {\n const response = await client.messages.create({\n model: config.model,\n max_tokens: 8192,\n system: SYSTEM_PROMPT,\n messages: [{ role: \"user\", content: userMessage }],\n });\n const textBlock = response.content.find((block) => block.type === \"text\");\n if (!textBlock || textBlock.type !== \"text\") {\n throw new Error(\"No text response from compiler LLM\");\n }\n return textBlock.text;\n } catch (err) {\n throw new Error(classifyError(err, \"Anthropic\"));\n }\n } else if (config.provider === \"openai\" || config.provider === \"google\") {\n const providerName = config.provider === \"google\" ? \"Google\" : \"OpenAI\";\n const clientOptions: { apiKey: string; baseURL?: string } = { apiKey: config.api_key };\n if (config.provider === \"google\") {\n clientOptions.baseURL = \"https://generativelanguage.googleapis.com/v1beta/openai/\";\n }\n const client = new OpenAI(clientOptions);\n try {\n const response = await client.chat.completions.create({\n model: config.model,\n max_tokens: 8192,\n messages: [\n { role: \"system\", content: SYSTEM_PROMPT },\n { role: \"user\", content: userMessage },\n ],\n });\n const text = response.choices[0]?.message?.content;\n if (!text) {\n throw new Error(\"No text response from compiler LLM\");\n }\n return text;\n } catch (err) {\n throw new Error(classifyError(err, providerName));\n }\n }\n throw new Error(`Unsupported provider: ${config.provider}. Run \\`kairn init\\` to reconfigure.`);\n}\n\nexport async function compile(\n intent: string,\n onProgress?: (msg: string) => void\n): Promise<EnvironmentSpec> {\n const config = await loadConfig();\n if (!config) {\n throw new Error(\"No config found. Run `kairn init` first.\");\n }\n\n onProgress?.(\"Loading tool registry...\");\n const registry = await loadRegistry();\n\n onProgress?.(`Compiling with ${config.provider} (${config.model})...`);\n const userMessage = buildUserMessage(intent, registry);\n const responseText = await callLLM(config, userMessage);\n\n onProgress?.(\"Parsing environment spec...\");\n const parsed = parseSpecResponse(responseText);\n\n const spec: EnvironmentSpec = {\n id: `env_${crypto.randomUUID()}`,\n intent,\n created_at: new Date().toISOString(),\n ...parsed,\n };\n\n // Save to ~/.kairn/envs/\n await ensureDirs();\n const envPath = path.join(getEnvsDir(), `${spec.id}.json`);\n await fs.writeFile(envPath, JSON.stringify(spec, null, 2), \"utf-8\");\n\n return spec;\n}\n","export const SYSTEM_PROMPT = `You are the Kairn environment compiler. Your job is to generate a minimal, optimal Claude Code agent environment from a user's natural language description of what they want their agent to do.\n\nYou will receive:\n1. The user's intent (what they want to build/do)\n2. A tool registry (available MCP servers, plugins, and hooks)\n\nYou must output a JSON object matching the EnvironmentSpec schema.\n\n## Core Principles\n\n- **Minimalism over completeness.** Fewer, well-chosen tools beat many generic ones. Each MCP server costs 500-2000 context tokens.\n- **Workflow-specific, not generic.** Every instruction, command, and rule must relate to the user's actual workflow.\n- **Concise CLAUDE.md.** Under 100 lines. No generic text like \"be helpful.\" Include build/test commands, reference docs/ and skills/.\n- **Security by default.** Always include deny rules for destructive commands and secret file access.\n\n## What You Must Always Include\n\n1. A concise, workflow-specific \\`claude_md\\` (the CLAUDE.md content)\n2. A \\`/project:help\\` command that explains the environment\n3. A \\`/project:tasks\\` command for task management via TODO.md\n4. A \\`docs/TODO.md\\` file for continuity\n5. A \\`docs/DECISIONS.md\\` file for architectural decisions\n6. A \\`docs/LEARNINGS.md\\` file for non-obvious discoveries\n7. A \\`rules/continuity.md\\` rule encouraging updates to DECISIONS.md and LEARNINGS.md\n8. A \\`rules/security.md\\` rule with essential security instructions\n9. settings.json with deny rules for \\`rm -rf\\`, \\`curl|sh\\`, reading \\`.env\\` and \\`secrets/\\`\n\n## Tool Selection Rules\n\n- Only select tools directly relevant to the described workflow\n- Prefer free tools (auth: \"none\") when quality is comparable\n- Tier 1 tools (Context7, Sequential Thinking, security-guidance) should be included in most environments\n- For tools requiring API keys (auth: \"api_key\"), use \\${ENV_VAR} syntax — never hardcode keys\n- Maximum 6-8 MCP servers to avoid context bloat\n- Include a \\`reason\\` for each selected tool explaining why it fits this workflow\n\n## For Code Projects, Additionally Include\n\n- \\`/project:plan\\` command (plan before coding)\n- \\`/project:review\\` command (review changes)\n- \\`/project:test\\` command (run and fix tests)\n- \\`/project:commit\\` command (conventional commits)\n- A TDD skill if testing is relevant\n- A reviewer agent (read-only, Sonnet model)\n\n## For Research Projects, Additionally Include\n\n- \\`/project:research\\` command (deep research on a topic)\n- \\`/project:summarize\\` command (summarize findings)\n- A research-synthesis skill\n- A researcher agent\n\n## For Content/Writing Projects, Additionally Include\n\n- \\`/project:draft\\` command (write first draft)\n- \\`/project:edit\\` command (review and improve writing)\n- A writing-workflow skill\n\n## Output Schema\n\nReturn ONLY valid JSON matching this structure:\n\n\\`\\`\\`json\n{\n \"name\": \"short-kebab-case-name\",\n \"description\": \"One-line description of the environment\",\n \"tools\": [\n { \"tool_id\": \"id-from-registry\", \"reason\": \"why this tool fits\" }\n ],\n \"harness\": {\n \"claude_md\": \"The full CLAUDE.md content (under 100 lines)\",\n \"settings\": {\n \"permissions\": {\n \"allow\": [\"Bash(npm run *)\", \"Read\", \"Write\", \"Edit\"],\n \"deny\": [\"Bash(rm -rf *)\", \"Bash(curl * | sh)\", \"Read(./.env)\", \"Read(./secrets/**)\"]\n }\n },\n \"mcp_config\": {\n \"server-name\": { \"command\": \"npx\", \"args\": [\"...\"], \"env\": {} }\n },\n \"commands\": {\n \"help\": \"markdown content for /project:help\",\n \"tasks\": \"markdown content for /project:tasks\"\n },\n \"rules\": {\n \"continuity\": \"markdown content for continuity rule\",\n \"security\": \"markdown content for security rule\"\n },\n \"skills\": {\n \"skill-name/SKILL\": \"markdown content with YAML frontmatter\"\n },\n \"agents\": {\n \"agent-name\": \"markdown content with YAML frontmatter\"\n },\n \"docs\": {\n \"TODO\": \"# TODO\\\\n\\\\n- [ ] First task based on workflow\",\n \"DECISIONS\": \"# Decisions\\\\n\\\\nArchitectural decisions for this project.\",\n \"LEARNINGS\": \"# Learnings\\\\n\\\\nNon-obvious discoveries and gotchas.\"\n }\n }\n}\n\\`\\`\\`\n\nDo not include any text outside the JSON object. Do not wrap in markdown code fences.`;\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport type { EnvironmentSpec, RegistryTool } from \"../types.js\";\n\nasync function writeFile(filePath: string, content: string): Promise<void> {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, content, \"utf-8\");\n}\n\nexport async function writeEnvironment(\n spec: EnvironmentSpec,\n targetDir: string\n): Promise<string[]> {\n const claudeDir = path.join(targetDir, \".claude\");\n const written: string[] = [];\n\n // 1. CLAUDE.md\n if (spec.harness.claude_md) {\n const p = path.join(claudeDir, \"CLAUDE.md\");\n await writeFile(p, spec.harness.claude_md);\n written.push(\".claude/CLAUDE.md\");\n }\n\n // 2. settings.json\n if (spec.harness.settings && Object.keys(spec.harness.settings).length > 0) {\n const p = path.join(claudeDir, \"settings.json\");\n await writeFile(p, JSON.stringify(spec.harness.settings, null, 2));\n written.push(\".claude/settings.json\");\n }\n\n // 3. .mcp.json (project-scoped, goes in project root)\n if (\n spec.harness.mcp_config &&\n Object.keys(spec.harness.mcp_config).length > 0\n ) {\n const p = path.join(targetDir, \".mcp.json\");\n const mcpContent = { mcpServers: spec.harness.mcp_config };\n await writeFile(p, JSON.stringify(mcpContent, null, 2));\n written.push(\".mcp.json\");\n }\n\n // 4. Commands\n if (spec.harness.commands) {\n for (const [name, content] of Object.entries(spec.harness.commands)) {\n const p = path.join(claudeDir, \"commands\", `${name}.md`);\n await writeFile(p, content);\n written.push(`.claude/commands/${name}.md`);\n }\n }\n\n // 5. Rules\n if (spec.harness.rules) {\n for (const [name, content] of Object.entries(spec.harness.rules)) {\n const p = path.join(claudeDir, \"rules\", `${name}.md`);\n await writeFile(p, content);\n written.push(`.claude/rules/${name}.md`);\n }\n }\n\n // 6. Skills\n if (spec.harness.skills) {\n for (const [skillPath, content] of Object.entries(spec.harness.skills)) {\n const p = path.join(claudeDir, \"skills\", `${skillPath}.md`);\n await writeFile(p, content);\n written.push(`.claude/skills/${skillPath}.md`);\n }\n }\n\n // 7. Agents\n if (spec.harness.agents) {\n for (const [name, content] of Object.entries(spec.harness.agents)) {\n const p = path.join(claudeDir, \"agents\", `${name}.md`);\n await writeFile(p, content);\n written.push(`.claude/agents/${name}.md`);\n }\n }\n\n // 8. Docs\n if (spec.harness.docs) {\n for (const [name, content] of Object.entries(spec.harness.docs)) {\n const p = path.join(claudeDir, \"docs\", `${name}.md`);\n await writeFile(p, content);\n written.push(`.claude/docs/${name}.md`);\n }\n }\n\n return written;\n}\n\nexport function summarizeSpec(\n spec: EnvironmentSpec,\n registry: RegistryTool[]\n): {\n toolCount: number;\n commandCount: number;\n ruleCount: number;\n skillCount: number;\n agentCount: number;\n pluginCommands: string[];\n} {\n const pluginCommands: string[] = [];\n for (const selected of spec.tools) {\n const tool = registry.find((t) => t.id === selected.tool_id);\n if (tool?.install.plugin_command) {\n pluginCommands.push(tool.install.plugin_command);\n }\n }\n\n return {\n toolCount: spec.tools.length,\n commandCount: Object.keys(spec.harness.commands || {}).length,\n ruleCount: Object.keys(spec.harness.rules || {}).length,\n skillCount: Object.keys(spec.harness.skills || {}).length,\n agentCount: Object.keys(spec.harness.agents || {}).length,\n pluginCommands,\n };\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { getEnvsDir } from \"../config.js\";\nimport type { EnvironmentSpec } from \"../types.js\";\n\nexport const listCommand = new Command(\"list\")\n .description(\"Show saved environments\")\n .action(async () => {\n const envsDir = getEnvsDir();\n\n let files: string[];\n try {\n files = await fs.readdir(envsDir);\n } catch {\n console.log(chalk.dim(\"\\n No environments yet. Run \") +\n chalk.bold(\"kairn describe\") +\n chalk.dim(\" to create one.\\n\"));\n return;\n }\n\n const jsonFiles = files.filter((f) => f.endsWith(\".json\"));\n\n if (jsonFiles.length === 0) {\n console.log(chalk.dim(\"\\n No environments yet. Run \") +\n chalk.bold(\"kairn describe\") +\n chalk.dim(\" to create one.\\n\"));\n return;\n }\n\n console.log(chalk.cyan(\"\\n Saved Environments\\n\"));\n\n for (const file of jsonFiles) {\n try {\n const data = await fs.readFile(path.join(envsDir, file), \"utf-8\");\n const spec = JSON.parse(data) as EnvironmentSpec;\n const date = new Date(spec.created_at).toLocaleDateString();\n const toolCount = spec.tools?.length ?? 0;\n\n console.log(chalk.bold(` ${spec.name}`));\n console.log(chalk.dim(` ${spec.description}`));\n console.log(\n chalk.dim(` ${date} · ${toolCount} tools · ${spec.id}`)\n );\n console.log(\"\");\n } catch {\n // Skip malformed files\n }\n }\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { getEnvsDir } from \"../config.js\";\nimport { writeEnvironment } from \"../adapter/claude-code.js\";\nimport type { EnvironmentSpec } from \"../types.js\";\n\nexport const activateCommand = new Command(\"activate\")\n .description(\"Re-deploy a saved environment to the current directory\")\n .argument(\"<env_id>\", \"Environment ID (from kairn list)\")\n .action(async (envId: string) => {\n const envsDir = getEnvsDir();\n\n // Find the env file — accept full ID or partial match\n let files: string[];\n try {\n files = await fs.readdir(envsDir);\n } catch {\n console.log(chalk.red(\"\\n No saved environments found.\\n\"));\n process.exit(1);\n }\n\n const match = files.find(\n (f) => f === `${envId}.json` || f.startsWith(envId)\n );\n\n if (!match) {\n console.log(chalk.red(`\\n Environment \"${envId}\" not found.`));\n console.log(chalk.dim(\" Run kairn list to see saved environments.\\n\"));\n process.exit(1);\n }\n\n const data = await fs.readFile(path.join(envsDir, match), \"utf-8\");\n const spec = JSON.parse(data) as EnvironmentSpec;\n\n console.log(chalk.cyan(`\\n Activating: ${spec.name}`));\n console.log(chalk.dim(` ${spec.description}\\n`));\n\n const targetDir = process.cwd();\n const written = await writeEnvironment(spec, targetDir);\n\n console.log(chalk.green(\" ✓ Environment written\\n\"));\n for (const file of written) {\n console.log(chalk.dim(` ${file}`));\n }\n\n console.log(\n chalk.cyan(\"\\n Ready! Run \") +\n chalk.bold(\"claude\") +\n chalk.cyan(\" to start.\\n\")\n );\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\n\nconst REGISTRY_URL =\n \"https://raw.githubusercontent.com/ashtonperlroth/kairn/main/src/registry/tools.json\";\n\nasync function getLocalRegistryPath(): Promise<string> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidates = [\n path.resolve(__dirname, \"../registry/tools.json\"),\n path.resolve(__dirname, \"../src/registry/tools.json\"),\n path.resolve(__dirname, \"../../src/registry/tools.json\"),\n ];\n for (const candidate of candidates) {\n try {\n await fs.access(candidate);\n return candidate;\n } catch {\n continue;\n }\n }\n throw new Error(\"Could not find local tools.json registry\");\n}\n\nexport const updateRegistryCommand = new Command(\"update-registry\")\n .description(\"Fetch the latest tool registry from GitHub\")\n .option(\"--url <url>\", \"Custom registry URL\")\n .action(async (options: { url?: string }) => {\n const url = options.url || REGISTRY_URL;\n\n console.log(chalk.dim(`\\n Fetching registry from ${url}...`));\n\n try {\n const response = await fetch(url);\n\n if (!response.ok) {\n console.log(\n chalk.red(` Failed to fetch registry: ${response.status} ${response.statusText}`)\n );\n console.log(\n chalk.dim(\" The remote registry may not be available yet.\")\n );\n console.log(\n chalk.dim(\" Your local registry is still active.\\n\")\n );\n return;\n }\n\n const text = await response.text();\n\n // Validate it's valid JSON and has the expected structure\n let tools: unknown[];\n try {\n tools = JSON.parse(text);\n if (!Array.isArray(tools)) throw new Error(\"Not an array\");\n if (tools.length === 0) throw new Error(\"Empty registry\");\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(` Invalid registry format: ${msg}\\n`));\n return;\n }\n\n const registryPath = await getLocalRegistryPath();\n\n // Back up existing registry\n const backupPath = registryPath + \".bak\";\n try {\n await fs.copyFile(registryPath, backupPath);\n } catch {\n // No existing file to back up\n }\n\n await fs.writeFile(registryPath, JSON.stringify(tools, null, 2), \"utf-8\");\n\n console.log(chalk.green(` ✓ Registry updated: ${tools.length} tools`));\n console.log(chalk.dim(` Saved to: ${registryPath}`));\n console.log(chalk.dim(` Backup: ${backupPath}\\n`));\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(` Network error: ${msg}`));\n console.log(chalk.dim(\" Your local registry is still active.\\n\"));\n }\n });\n","import { Command } from \"commander\";\nimport { input, confirm, checkbox } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { loadConfig } from \"../config.js\";\nimport { compile } from \"../compiler/compile.js\";\nimport { writeEnvironment, summarizeSpec } from \"../adapter/claude-code.js\";\nimport { scanProject } from \"../scanner/scan.js\";\nimport type { ProjectProfile } from \"../scanner/scan.js\";\nimport type { RegistryTool } from \"../types.js\";\n\nasync function loadRegistry(): Promise<RegistryTool[]> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidates = [\n path.resolve(__dirname, \"../registry/tools.json\"),\n path.resolve(__dirname, \"../src/registry/tools.json\"),\n path.resolve(__dirname, \"../../src/registry/tools.json\"),\n ];\n for (const candidate of candidates) {\n try {\n const data = await fs.readFile(candidate, \"utf-8\");\n return JSON.parse(data) as RegistryTool[];\n } catch {\n continue;\n }\n }\n throw new Error(\"Could not find tools.json registry\");\n}\n\nfunction buildProfileSummary(profile: ProjectProfile): string {\n const lines: string[] = [];\n lines.push(`Project: ${profile.name}`);\n if (profile.description) lines.push(`Description: ${profile.description}`);\n if (profile.language) lines.push(`Language: ${profile.language}`);\n if (profile.framework) lines.push(`Framework: ${profile.framework}`);\n if (profile.dependencies.length > 0) {\n lines.push(`Dependencies: ${profile.dependencies.join(\", \")}`);\n }\n if (profile.testCommand) lines.push(`Test command: ${profile.testCommand}`);\n if (profile.buildCommand) lines.push(`Build command: ${profile.buildCommand}`);\n if (profile.lintCommand) lines.push(`Lint command: ${profile.lintCommand}`);\n if (profile.hasDocker) lines.push(\"Has Docker configuration\");\n if (profile.hasCi) lines.push(\"Has CI/CD (GitHub Actions)\");\n if (profile.envKeys.length > 0) {\n lines.push(`Env keys needed: ${profile.envKeys.join(\", \")}`);\n }\n return lines.join(\"\\n\");\n}\n\nfunction buildAuditSummary(profile: ProjectProfile): string {\n const lines: string[] = [];\n lines.push(`\\nExisting .claude/ harness found:`);\n lines.push(` CLAUDE.md: ${profile.claudeMdLineCount} lines${profile.claudeMdLineCount > 200 ? \" (⚠ over 200 — may degrade adherence)\" : \"\"}`);\n lines.push(` MCP servers: ${profile.mcpServerCount}`);\n lines.push(` Commands: ${profile.existingCommands.length > 0 ? profile.existingCommands.map(c => `/project:${c}`).join(\", \") : \"none\"}`);\n lines.push(` Rules: ${profile.existingRules.length > 0 ? profile.existingRules.join(\", \") : \"none\"}`);\n lines.push(` Skills: ${profile.existingSkills.length > 0 ? profile.existingSkills.join(\", \") : \"none\"}`);\n lines.push(` Agents: ${profile.existingAgents.length > 0 ? profile.existingAgents.join(\", \") : \"none\"}`);\n return lines.join(\"\\n\");\n}\n\nfunction buildOptimizeIntent(profile: ProjectProfile): string {\n const parts: string[] = [];\n\n parts.push(\"## Project Profile (scanned from actual codebase)\\n\");\n parts.push(buildProfileSummary(profile));\n\n if (profile.hasClaudeDir) {\n parts.push(buildAuditSummary(profile));\n\n if (profile.existingClaudeMd) {\n parts.push(`\\n## Existing CLAUDE.md Content\\n\\n${profile.existingClaudeMd}`);\n }\n\n parts.push(`\\n## Task\\n`);\n parts.push(\"Analyze this existing Claude Code environment and generate an OPTIMIZED version.\");\n parts.push(\"Preserve what works. Fix what's wrong. Add what's missing. Remove what's bloat.\");\n parts.push(\"Key optimizations to consider:\");\n parts.push(\"- Is CLAUDE.md under 100 lines? If not, move detail to rules/ or docs/\");\n parts.push(\"- Are the right MCP servers selected for these dependencies?\");\n parts.push(\"- Are there missing slash commands (help, tasks, plan, test, commit)?\");\n parts.push(\"- Are security rules present?\");\n parts.push(\"- Is there a continuity rule for session memory?\");\n parts.push(\"- Are there unnecessary MCP servers adding context bloat?\");\n if (profile.claudeMdLineCount > 200) {\n parts.push(`- CLAUDE.md is ${profile.claudeMdLineCount} lines — needs aggressive trimming`);\n }\n if (!profile.existingCommands.includes(\"help\")) {\n parts.push(\"- Missing /project:help command\");\n }\n if (!profile.existingRules.includes(\"security\")) {\n parts.push(\"- Missing security rules\");\n }\n } else {\n parts.push(`\\n## Task\\n`);\n parts.push(\"Generate an optimal Claude Code environment for this existing project.\");\n parts.push(\"Use the scanned project profile — this is a real codebase, not a description.\");\n parts.push(\"The environment should match the actual tech stack, dependencies, and workflows.\");\n }\n\n return parts.join(\"\\n\");\n}\n\nexport const optimizeCommand = new Command(\"optimize\")\n .description(\"Scan an existing project and generate or optimize its Claude Code environment\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"--audit-only\", \"Only audit the existing harness, don't generate changes\")\n .action(async (options: { yes?: boolean; auditOnly?: boolean }) => {\n const config = await loadConfig();\n if (!config) {\n console.log(\n chalk.red(\"\\n No config found. Run \") +\n chalk.bold(\"kairn init\") +\n chalk.red(\" first.\\n\")\n );\n process.exit(1);\n }\n\n const targetDir = process.cwd();\n\n // 1. Scan\n console.log(chalk.dim(\"\\n Scanning project...\"));\n const profile = await scanProject(targetDir);\n\n // 2. Show profile\n console.log(chalk.cyan(\"\\n Project Profile\\n\"));\n if (profile.language) console.log(chalk.dim(` Language: ${profile.language}`));\n if (profile.framework) console.log(chalk.dim(` Framework: ${profile.framework}`));\n console.log(chalk.dim(` Dependencies: ${profile.dependencies.length}`));\n if (profile.testCommand) console.log(chalk.dim(` Tests: ${profile.testCommand}`));\n if (profile.buildCommand) console.log(chalk.dim(` Build: ${profile.buildCommand}`));\n if (profile.hasDocker) console.log(chalk.dim(\" Docker: yes\"));\n if (profile.hasCi) console.log(chalk.dim(\" CI/CD: yes\"));\n if (profile.envKeys.length > 0) console.log(chalk.dim(` Env keys: ${profile.envKeys.join(\", \")}`));\n\n // 3. Audit existing harness\n if (profile.hasClaudeDir) {\n console.log(chalk.yellow(\"\\n Existing .claude/ harness detected\\n\"));\n console.log(chalk.dim(` CLAUDE.md: ${profile.claudeMdLineCount} lines${profile.claudeMdLineCount > 200 ? chalk.yellow(\" ⚠ bloated\") : chalk.green(\" ✓\")}`));\n console.log(chalk.dim(` MCP servers: ${profile.mcpServerCount}`));\n console.log(chalk.dim(` Commands: ${profile.existingCommands.length > 0 ? profile.existingCommands.map(c => c).join(\", \") : \"none\"}`));\n console.log(chalk.dim(` Rules: ${profile.existingRules.length > 0 ? profile.existingRules.join(\", \") : \"none\"}`));\n console.log(chalk.dim(` Skills: ${profile.existingSkills.length > 0 ? profile.existingSkills.join(\", \") : \"none\"}`));\n console.log(chalk.dim(` Agents: ${profile.existingAgents.length > 0 ? profile.existingAgents.join(\", \") : \"none\"}`));\n\n // Quick audit checks\n const issues: string[] = [];\n if (profile.claudeMdLineCount > 200) issues.push(\"CLAUDE.md over 200 lines — move detail to rules/ or docs/\");\n if (!profile.existingCommands.includes(\"help\")) issues.push(\"Missing /project:help command\");\n if (!profile.existingRules.includes(\"security\")) issues.push(\"Missing security rules\");\n if (!profile.existingRules.includes(\"continuity\")) issues.push(\"Missing continuity rule for session memory\");\n if (profile.mcpServerCount > 8) issues.push(`${profile.mcpServerCount} MCP servers — may cause context bloat`);\n if (profile.mcpServerCount === 0 && profile.dependencies.length > 0) issues.push(\"No MCP servers configured\");\n if (profile.hasTests && !profile.existingCommands.includes(\"test\")) issues.push(\"Has tests but no /project:test command\");\n if (!profile.existingCommands.includes(\"tasks\")) issues.push(\"Missing /project:tasks command\");\n\n if (issues.length > 0) {\n console.log(chalk.yellow(\"\\n Issues Found:\\n\"));\n for (const issue of issues) {\n console.log(chalk.yellow(` ⚠ ${issue}`));\n }\n } else {\n console.log(chalk.green(\"\\n ✓ No obvious issues found\"));\n }\n\n if (options.auditOnly) {\n console.log(chalk.dim(\"\\n Audit complete. Run without --audit-only to generate optimized environment.\\n\"));\n return;\n }\n\n // Ask before overwriting\n if (!options.yes) {\n console.log(\"\");\n const proceed = await confirm({\n message: \"Generate optimized environment? This will overwrite existing .claude/ files.\",\n default: false,\n });\n if (!proceed) {\n console.log(chalk.dim(\"\\n Aborted.\\n\"));\n return;\n }\n }\n } else {\n console.log(chalk.dim(\"\\n No existing .claude/ directory found — generating from scratch.\\n\"));\n\n if (!options.yes) {\n const proceed = await confirm({\n message: \"Generate Claude Code environment for this project?\",\n default: true,\n });\n if (!proceed) {\n console.log(chalk.dim(\"\\n Aborted.\\n\"));\n return;\n }\n }\n }\n\n // 4. Compile with scanned profile\n const intent = buildOptimizeIntent(profile);\n let spec;\n try {\n spec = await compile(intent, (msg) => {\n process.stdout.write(`\\r ${chalk.dim(msg)} `);\n });\n process.stdout.write(\"\\r \\r\");\n } catch (err) {\n process.stdout.write(\"\\r \\r\");\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(`\\n Optimization failed: ${msg}\\n`));\n process.exit(1);\n }\n\n // 5. Show results\n const registry = await loadRegistry();\n const summary = summarizeSpec(spec, registry);\n\n console.log(chalk.green(\" ✓ Environment compiled\\n\"));\n console.log(chalk.cyan(\" Name: \") + spec.name);\n console.log(chalk.cyan(\" Tools: \") + summary.toolCount);\n console.log(chalk.cyan(\" Commands: \") + summary.commandCount);\n console.log(chalk.cyan(\" Rules: \") + summary.ruleCount);\n console.log(chalk.cyan(\" Skills: \") + summary.skillCount);\n console.log(chalk.cyan(\" Agents: \") + summary.agentCount);\n\n if (spec.tools.length > 0) {\n console.log(chalk.dim(\"\\n Selected tools:\"));\n for (const tool of spec.tools) {\n const regTool = registry.find((t) => t.id === tool.tool_id);\n const name = regTool?.name || tool.tool_id;\n console.log(chalk.dim(` - ${name}: ${tool.reason}`));\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(chalk.yellow(\"\\n Plugins to install manually:\"));\n for (const cmd of summary.pluginCommands) {\n console.log(chalk.yellow(` ${cmd}`));\n }\n }\n\n // 6. Write\n const written = await writeEnvironment(spec, targetDir);\n\n console.log(chalk.green(\"\\n ✓ Environment written\\n\"));\n for (const file of written) {\n console.log(chalk.dim(` ${file}`));\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(chalk.yellow(\"\\n Install plugins by running these in Claude Code:\"));\n for (const cmd of summary.pluginCommands) {\n console.log(chalk.bold(` ${cmd}`));\n }\n }\n\n console.log(\n chalk.cyan(\"\\n Ready! Run \") +\n chalk.bold(\"claude\") +\n chalk.cyan(\" to start.\\n\")\n );\n });\n","import fs from \"fs/promises\";\nimport path from \"path\";\n\nexport interface ProjectProfile {\n // Core identity\n name: string;\n description: string;\n directory: string;\n\n // Language & framework\n language: string | null;\n framework: string | null;\n typescript: boolean;\n\n // Dependencies\n dependencies: string[];\n devDependencies: string[];\n\n // Scripts & commands\n scripts: Record<string, string>;\n hasTests: boolean;\n testCommand: string | null;\n buildCommand: string | null;\n lintCommand: string | null;\n\n // Project structure\n hasSrc: boolean;\n hasDocker: boolean;\n hasCi: boolean;\n hasEnvFile: boolean;\n envKeys: string[]; // from .env.example only — never read .env values\n\n // Existing harness\n hasClaudeDir: boolean;\n existingClaudeMd: string | null;\n existingSettings: Record<string, unknown> | null;\n existingMcpConfig: Record<string, unknown> | null;\n existingCommands: string[];\n existingRules: string[];\n existingSkills: string[];\n existingAgents: string[];\n mcpServerCount: number;\n claudeMdLineCount: number;\n\n // Key files found\n keyFiles: string[];\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await fs.access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function readJsonSafe(p: string): Promise<Record<string, unknown> | null> {\n try {\n const data = await fs.readFile(p, \"utf-8\");\n return JSON.parse(data);\n } catch {\n return null;\n }\n}\n\nasync function readFileSafe(p: string): Promise<string | null> {\n try {\n return await fs.readFile(p, \"utf-8\");\n } catch {\n return null;\n }\n}\n\nasync function listDirSafe(p: string): Promise<string[]> {\n try {\n const entries = await fs.readdir(p);\n return entries.filter((e) => !e.startsWith(\".\"));\n } catch {\n return [];\n }\n}\n\nfunction detectFramework(deps: string[]): string | null {\n const frameworks: [string[], string][] = [\n [[\"next\"], \"Next.js\"],\n [[\"nuxt\"], \"Nuxt\"],\n [[\"@remix-run/node\", \"@remix-run/react\"], \"Remix\"],\n [[\"svelte\", \"@sveltejs/kit\"], \"SvelteKit\"],\n [[\"express\"], \"Express\"],\n [[\"fastify\"], \"Fastify\"],\n [[\"hono\"], \"Hono\"],\n [[\"react\", \"react-dom\"], \"React\"],\n [[\"vue\"], \"Vue\"],\n [[\"angular\"], \"Angular\"],\n [[\"django\"], \"Django\"],\n [[\"flask\"], \"Flask\"],\n [[\"fastapi\"], \"FastAPI\"],\n [[\"@supabase/supabase-js\"], \"Supabase\"],\n [[\"prisma\", \"@prisma/client\"], \"Prisma\"],\n [[\"drizzle-orm\"], \"Drizzle\"],\n [[\"tailwindcss\"], \"Tailwind CSS\"],\n ];\n\n const detected: string[] = [];\n for (const [packages, name] of frameworks) {\n if (packages.some((pkg) => deps.includes(pkg))) {\n detected.push(name);\n }\n }\n return detected.length > 0 ? detected.join(\" + \") : null;\n}\n\nfunction detectLanguage(dir: string, keyFiles: string[]): string | null {\n if (keyFiles.some((f) => f === \"tsconfig.json\")) return \"TypeScript\";\n if (keyFiles.some((f) => f === \"package.json\")) return \"JavaScript\";\n if (keyFiles.some((f) => f === \"pyproject.toml\" || f === \"setup.py\" || f === \"requirements.txt\")) return \"Python\";\n if (keyFiles.some((f) => f === \"Cargo.toml\")) return \"Rust\";\n if (keyFiles.some((f) => f === \"go.mod\")) return \"Go\";\n if (keyFiles.some((f) => f === \"Gemfile\")) return \"Ruby\";\n return null;\n}\n\nfunction extractEnvKeys(content: string): string[] {\n const keys: string[] = [];\n for (const line of content.split(\"\\n\")) {\n const match = line.match(/^([A-Z][A-Z0-9_]*)=/);\n if (match) keys.push(match[1]);\n }\n return keys;\n}\n\nexport async function scanProject(dir: string): Promise<ProjectProfile> {\n // Read package.json\n const pkg = await readJsonSafe(path.join(dir, \"package.json\")) as Record<string, unknown> | null;\n const deps = pkg?.dependencies ? Object.keys(pkg.dependencies as Record<string, string>) : [];\n const devDeps = pkg?.devDependencies ? Object.keys(pkg.devDependencies as Record<string, string>) : [];\n const allDeps = [...deps, ...devDeps];\n const scripts = (pkg?.scripts || {}) as Record<string, string>;\n\n // Detect key files\n const rootFiles = await listDirSafe(dir);\n const keyFiles = rootFiles.filter((f) =>\n [\n \"package.json\", \"tsconfig.json\", \"pyproject.toml\", \"setup.py\",\n \"requirements.txt\", \"Cargo.toml\", \"go.mod\", \"Gemfile\",\n \"docker-compose.yml\", \"Dockerfile\", \".env.example\", \".env\",\n \"README.md\", \"CLAUDE.md\",\n ].includes(f)\n );\n\n // Detect language & framework\n const language = detectLanguage(dir, keyFiles);\n const framework = detectFramework(allDeps);\n const typescript = keyFiles.includes(\"tsconfig.json\") || allDeps.includes(\"typescript\");\n\n // Test detection\n const testCommand = scripts.test && scripts.test !== 'echo \"Error: no test specified\" && exit 1'\n ? scripts.test : null;\n const hasTests = testCommand !== null ||\n await fileExists(path.join(dir, \"tests\")) ||\n await fileExists(path.join(dir, \"__tests__\")) ||\n await fileExists(path.join(dir, \"test\"));\n\n // Build & lint\n const buildCommand = scripts.build || null;\n const lintCommand = scripts.lint || null;\n\n // Structure\n const hasSrc = await fileExists(path.join(dir, \"src\"));\n const hasDocker = await fileExists(path.join(dir, \"docker-compose.yml\")) ||\n await fileExists(path.join(dir, \"Dockerfile\"));\n const hasCi = await fileExists(path.join(dir, \".github/workflows\"));\n\n // Env keys (from .env.example only — never read actual .env values)\n const hasEnvFile = await fileExists(path.join(dir, \".env\")) ||\n await fileExists(path.join(dir, \".env.example\"));\n let envKeys: string[] = [];\n const envExample = await readFileSafe(path.join(dir, \".env.example\"));\n if (envExample) {\n envKeys = extractEnvKeys(envExample);\n }\n\n // Existing .claude/ harness\n const claudeDir = path.join(dir, \".claude\");\n const hasClaudeDir = await fileExists(claudeDir);\n let existingClaudeMd: string | null = null;\n let existingSettings: Record<string, unknown> | null = null;\n let existingMcpConfig: Record<string, unknown> | null = null;\n let existingCommands: string[] = [];\n let existingRules: string[] = [];\n let existingSkills: string[] = [];\n let existingAgents: string[] = [];\n let mcpServerCount = 0;\n let claudeMdLineCount = 0;\n\n if (hasClaudeDir) {\n existingClaudeMd = await readFileSafe(path.join(claudeDir, \"CLAUDE.md\"));\n if (existingClaudeMd) {\n claudeMdLineCount = existingClaudeMd.split(\"\\n\").length;\n }\n\n existingSettings = await readJsonSafe(path.join(claudeDir, \"settings.json\"));\n existingMcpConfig = await readJsonSafe(path.join(dir, \".mcp.json\"));\n if (existingMcpConfig?.mcpServers) {\n mcpServerCount = Object.keys(existingMcpConfig.mcpServers as Record<string, unknown>).length;\n }\n\n existingCommands = (await listDirSafe(path.join(claudeDir, \"commands\")))\n .filter((f) => f.endsWith(\".md\"))\n .map((f) => f.replace(\".md\", \"\"));\n existingRules = (await listDirSafe(path.join(claudeDir, \"rules\")))\n .filter((f) => f.endsWith(\".md\"))\n .map((f) => f.replace(\".md\", \"\"));\n existingSkills = await listDirSafe(path.join(claudeDir, \"skills\"));\n existingAgents = (await listDirSafe(path.join(claudeDir, \"agents\")))\n .filter((f) => f.endsWith(\".md\"))\n .map((f) => f.replace(\".md\", \"\"));\n }\n\n // Project name & description\n const name = (pkg?.name as string) || path.basename(dir);\n const description = (pkg?.description as string) || \"\";\n\n return {\n name,\n description,\n directory: dir,\n language,\n framework,\n typescript,\n dependencies: deps,\n devDependencies: devDeps,\n scripts,\n hasTests,\n testCommand,\n buildCommand,\n lintCommand,\n hasSrc,\n hasDocker,\n hasCi,\n hasEnvFile,\n envKeys,\n hasClaudeDir,\n existingClaudeMd,\n existingSettings,\n existingMcpConfig,\n existingCommands,\n existingRules,\n existingSkills,\n existingAgents,\n mcpServerCount,\n claudeMdLineCount,\n keyFiles,\n };\n}\n"],"mappings":"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","names":["Command","Command","chalk","fs","path","fs","path","Anthropic","OpenAI","path","fs","Anthropic","OpenAI","fs","path","fileURLToPath","loadRegistry","path","fs","Command","chalk","Command","chalk","fs","path","Command","fs","chalk","path","Command","chalk","fs","path","Command","fs","chalk","path","Command","chalk","fs","path","fileURLToPath","Command","confirm","chalk","fs","path","fileURLToPath","fs","path","loadRegistry","fileURLToPath","path","fs","Command","chalk","confirm","Command"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/config.ts","../src/commands/describe.ts","../src/compiler/compile.ts","../src/compiler/prompt.ts","../src/adapter/claude-code.ts","../src/commands/list.ts","../src/commands/activate.ts","../src/commands/update-registry.ts","../src/commands/optimize.ts","../src/scanner/scan.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { describeCommand } from \"./commands/describe.js\";\nimport { listCommand } from \"./commands/list.js\";\nimport { activateCommand } from \"./commands/activate.js\";\nimport { updateRegistryCommand } from \"./commands/update-registry.js\";\nimport { optimizeCommand } from \"./commands/optimize.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"kairn\")\n .description(\n \"Compile natural language intent into optimized Claude Code environments\"\n )\n .version(\"1.0.0\");\n\nprogram.addCommand(initCommand);\nprogram.addCommand(describeCommand);\nprogram.addCommand(optimizeCommand);\nprogram.addCommand(listCommand);\nprogram.addCommand(activateCommand);\nprogram.addCommand(updateRegistryCommand);\n\nprogram.parse();\n","import { Command } from \"commander\";\nimport { password, select } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport Anthropic from \"@anthropic-ai/sdk\";\nimport OpenAI from \"openai\";\nimport { execFileSync } from \"child_process\";\nimport { loadConfig, saveConfig, getConfigPath } from \"../config.js\";\nimport type { KairnConfig, LLMProvider } from \"../types.js\";\n\nconst PROVIDER_MODELS: Record<LLMProvider, { name: string; models: { name: string; value: string }[] }> = {\n anthropic: {\n name: \"Anthropic\",\n models: [\n { name: \"Claude Sonnet 4.6 (recommended — fast, smart)\", value: \"claude-sonnet-4-6\" },\n { name: \"Claude Opus 4.6 (highest quality)\", value: \"claude-opus-4-6\" },\n { name: \"Claude Haiku 4.5 (fastest, cheapest)\", value: \"claude-haiku-4-5-20251001\" },\n ],\n },\n openai: {\n name: \"OpenAI\",\n models: [\n { name: \"GPT-4o (recommended)\", value: \"gpt-4o\" },\n { name: \"GPT-4o mini (faster, cheaper)\", value: \"gpt-4o-mini\" },\n { name: \"o3 (reasoning)\", value: \"o3\" },\n ],\n },\n google: {\n name: \"Google Gemini\",\n models: [\n { name: \"Gemini 2.5 Flash (recommended)\", value: \"gemini-2.5-flash-preview-05-20\" },\n { name: \"Gemini 2.5 Pro (highest quality)\", value: \"gemini-2.5-pro-preview-05-06\" },\n ],\n },\n};\n\nasync function verifyKey(provider: LLMProvider, apiKey: string, model: string): Promise<boolean> {\n try {\n if (provider === \"anthropic\") {\n const client = new Anthropic({ apiKey });\n await client.messages.create({\n model: \"claude-haiku-4-5-20251001\",\n max_tokens: 10,\n messages: [{ role: \"user\", content: \"ping\" }],\n });\n return true;\n } else if (provider === \"openai\") {\n const client = new OpenAI({ apiKey });\n await client.chat.completions.create({\n model: \"gpt-4o-mini\",\n max_tokens: 10,\n messages: [{ role: \"user\", content: \"ping\" }],\n });\n return true;\n } else if (provider === \"google\") {\n // Google uses OpenAI-compatible API\n const client = new OpenAI({\n apiKey,\n baseURL: \"https://generativelanguage.googleapis.com/v1beta/openai/\",\n });\n await client.chat.completions.create({\n model: \"gemini-2.5-flash-preview-05-20\",\n max_tokens: 10,\n messages: [{ role: \"user\", content: \"ping\" }],\n });\n return true;\n }\n return false;\n } catch {\n return false;\n }\n}\n\nfunction detectClaudeCode(): boolean {\n try {\n execFileSync(\"which\", [\"claude\"], { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n}\n\nexport const initCommand = new Command(\"init\")\n .description(\"Set up Kairn with your API key\")\n .action(async () => {\n console.log(chalk.cyan(\"\\n Kairn Setup\\n\"));\n\n const existing = await loadConfig();\n if (existing) {\n console.log(\n chalk.yellow(\" Config already exists at \") +\n chalk.dim(getConfigPath())\n );\n console.log(chalk.yellow(\" Running setup will overwrite it.\\n\"));\n }\n\n const provider = await select<LLMProvider>({\n message: \"LLM provider\",\n choices: [\n { name: \"Anthropic (Claude) — recommended\", value: \"anthropic\" as LLMProvider },\n { name: \"OpenAI (GPT)\", value: \"openai\" as LLMProvider },\n { name: \"Google (Gemini)\", value: \"google\" as LLMProvider },\n ],\n });\n\n const providerInfo = PROVIDER_MODELS[provider];\n\n const model = await select({\n message: \"Compilation model\",\n choices: providerInfo.models,\n });\n\n const apiKey = await password({\n message: `${providerInfo.name} API key`,\n mask: \"*\",\n });\n\n if (!apiKey) {\n console.log(chalk.red(\"\\n No API key provided. Aborting.\"));\n process.exit(1);\n }\n\n console.log(chalk.dim(\"\\n Verifying API key...\"));\n const valid = await verifyKey(provider, apiKey, model);\n\n if (!valid) {\n console.log(\n chalk.red(\" Invalid API key. Check your key and try again.\")\n );\n process.exit(1);\n }\n\n console.log(chalk.green(\" ✓ API key verified\"));\n\n const config: KairnConfig = {\n provider,\n api_key: apiKey,\n model,\n default_runtime: \"claude-code\",\n created_at: new Date().toISOString(),\n };\n\n await saveConfig(config);\n console.log(\n chalk.green(\" ✓ Config saved to \") + chalk.dim(getConfigPath())\n );\n console.log(\n chalk.dim(` ✓ Provider: ${providerInfo.name}, Model: ${model}`)\n );\n\n const hasClaude = detectClaudeCode();\n if (hasClaude) {\n console.log(chalk.green(\" ✓ Claude Code detected\"));\n } else {\n console.log(\n chalk.yellow(\n \" ⚠ Claude Code not found. Install it: npm install -g @anthropic-ai/claude-code\"\n )\n );\n }\n\n console.log(\n chalk.cyan(\"\\n Ready! Run \") +\n chalk.bold(\"kairn describe\") +\n chalk.cyan(\" to create your first environment.\\n\")\n );\n });\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport os from \"os\";\nimport type { KairnConfig } from \"./types.js\";\n\nconst KAIRN_DIR = path.join(os.homedir(), \".kairn\");\nconst CONFIG_PATH = path.join(KAIRN_DIR, \"config.json\");\nconst ENVS_DIR = path.join(KAIRN_DIR, \"envs\");\n\nexport function getKairnDir(): string {\n return KAIRN_DIR;\n}\n\nexport function getConfigPath(): string {\n return CONFIG_PATH;\n}\n\nexport function getEnvsDir(): string {\n return ENVS_DIR;\n}\n\nexport async function ensureDirs(): Promise<void> {\n await fs.mkdir(KAIRN_DIR, { recursive: true });\n await fs.mkdir(ENVS_DIR, { recursive: true });\n}\n\nexport async function loadConfig(): Promise<KairnConfig | null> {\n try {\n const data = await fs.readFile(CONFIG_PATH, \"utf-8\");\n const raw = JSON.parse(data) as Record<string, unknown>;\n\n // Handle old config format (v1.0.0: anthropic_api_key)\n if (raw.anthropic_api_key && !raw.provider) {\n return {\n provider: \"anthropic\",\n api_key: raw.anthropic_api_key as string,\n model: \"claude-sonnet-4-6\",\n default_runtime: \"claude-code\",\n created_at: (raw.created_at as string) || new Date().toISOString(),\n };\n }\n\n return raw as unknown as KairnConfig;\n } catch {\n return null;\n }\n}\n\nexport async function saveConfig(config: KairnConfig): Promise<void> {\n await ensureDirs();\n await fs.writeFile(CONFIG_PATH, JSON.stringify(config, null, 2), \"utf-8\");\n}\n","import { Command } from \"commander\";\nimport { input, confirm } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { loadConfig } from \"../config.js\";\nimport { compile } from \"../compiler/compile.js\";\nimport { writeEnvironment, summarizeSpec } from \"../adapter/claude-code.js\";\nimport { fileURLToPath } from \"url\";\nimport type { RegistryTool } from \"../types.js\";\n\nasync function loadRegistry(): Promise<RegistryTool[]> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidates = [\n path.resolve(__dirname, \"../registry/tools.json\"),\n path.resolve(__dirname, \"../src/registry/tools.json\"),\n path.resolve(__dirname, \"../../src/registry/tools.json\"),\n ];\n for (const candidate of candidates) {\n try {\n const data = await fs.readFile(candidate, \"utf-8\");\n return JSON.parse(data) as RegistryTool[];\n } catch {\n continue;\n }\n }\n throw new Error(\"Could not find tools.json registry\");\n}\n\nexport const describeCommand = new Command(\"describe\")\n .description(\"Describe your workflow and generate a Claude Code environment\")\n .argument(\"[intent]\", \"What you want your agent to do\")\n .option(\"-y, --yes\", \"Skip confirmation prompt\")\n .action(async (intentArg: string | undefined, options: { yes?: boolean }) => {\n // 1. Check config\n const config = await loadConfig();\n if (!config) {\n console.log(\n chalk.red(\"\\n No config found. Run \") +\n chalk.bold(\"kairn init\") +\n chalk.red(\" first.\\n\")\n );\n process.exit(1);\n }\n\n // 2. Get intent\n const intent =\n intentArg ||\n (await input({\n message: \"What do you want your agent to do?\",\n }));\n\n if (!intent.trim()) {\n console.log(chalk.red(\"\\n No description provided. Aborting.\\n\"));\n process.exit(1);\n }\n\n // 3. Compile with progress\n console.log(\"\");\n let spec;\n try {\n spec = await compile(intent, (msg) => {\n process.stdout.write(`\\r ${chalk.dim(msg)} `);\n });\n process.stdout.write(\"\\r \\r\");\n } catch (err) {\n process.stdout.write(\"\\r \\r\");\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(`\\n Compilation failed: ${msg}\\n`));\n process.exit(1);\n }\n\n // 4. Show results\n const registry = await loadRegistry();\n const summary = summarizeSpec(spec, registry);\n\n console.log(chalk.green(\"\\n ✓ Environment compiled\\n\"));\n console.log(chalk.cyan(\" Name: \") + spec.name);\n console.log(chalk.cyan(\" Description: \") + spec.description);\n console.log(chalk.cyan(\" Tools: \") + summary.toolCount);\n console.log(chalk.cyan(\" Commands: \") + summary.commandCount);\n console.log(chalk.cyan(\" Rules: \") + summary.ruleCount);\n console.log(chalk.cyan(\" Skills: \") + summary.skillCount);\n console.log(chalk.cyan(\" Agents: \") + summary.agentCount);\n\n if (spec.tools.length > 0) {\n console.log(chalk.dim(\"\\n Selected tools:\"));\n for (const tool of spec.tools) {\n const regTool = registry.find((t) => t.id === tool.tool_id);\n const name = regTool?.name || tool.tool_id;\n console.log(chalk.dim(` - ${name}: ${tool.reason}`));\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(chalk.yellow(\"\\n Plugins to install manually:\"));\n for (const cmd of summary.pluginCommands) {\n console.log(chalk.yellow(` ${cmd}`));\n }\n }\n\n // 5. Confirm\n console.log(\"\");\n const proceed = options.yes || await confirm({\n message: \"Generate environment in current directory?\",\n default: true,\n });\n\n if (!proceed) {\n console.log(chalk.dim(\"\\n Aborted. Environment saved to ~/.kairn/envs/\\n\"));\n return;\n }\n\n // 6. Write\n const targetDir = process.cwd();\n const written = await writeEnvironment(spec, targetDir);\n\n console.log(chalk.green(\"\\n ✓ Environment written\\n\"));\n for (const file of written) {\n console.log(chalk.dim(` ${file}`));\n }\n\n if (summary.envSetup.length > 0) {\n console.log(chalk.yellow(\"\\n API keys needed (set these environment variables):\\n\"));\n const seen = new Set<string>();\n for (const env of summary.envSetup) {\n if (seen.has(env.envVar)) continue;\n seen.add(env.envVar);\n console.log(chalk.bold(` export ${env.envVar}=\"your-key-here\"`));\n console.log(chalk.dim(` ${env.description}`));\n if (env.signupUrl) {\n console.log(chalk.dim(` Get one at: ${env.signupUrl}`));\n }\n console.log(\"\");\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(chalk.yellow(\" Install plugins by running these in Claude Code:\"));\n for (const cmd of summary.pluginCommands) {\n console.log(chalk.bold(` ${cmd}`));\n }\n }\n\n console.log(\n chalk.cyan(\"\\n Ready! Run \") +\n chalk.bold(\"claude\") +\n chalk.cyan(\" to start.\\n\")\n );\n });\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport crypto from \"crypto\";\nimport Anthropic from \"@anthropic-ai/sdk\";\nimport OpenAI from \"openai\";\nimport { loadConfig, getEnvsDir, ensureDirs } from \"../config.js\";\nimport { SYSTEM_PROMPT } from \"./prompt.js\";\nimport type { EnvironmentSpec, RegistryTool, KairnConfig } from \"../types.js\";\n\nasync function loadRegistry(): Promise<RegistryTool[]> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidates = [\n path.resolve(__dirname, \"../registry/tools.json\"),\n path.resolve(__dirname, \"../src/registry/tools.json\"),\n path.resolve(__dirname, \"../../src/registry/tools.json\"),\n ];\n for (const candidate of candidates) {\n try {\n const data = await fs.readFile(candidate, \"utf-8\");\n return JSON.parse(data) as RegistryTool[];\n } catch {\n continue;\n }\n }\n throw new Error(\"Could not find tools.json registry\");\n}\n\nfunction buildUserMessage(intent: string, registry: RegistryTool[]): string {\n const registrySummary = registry\n .map(\n (t) =>\n `- ${t.id} (${t.type}, tier ${t.tier}, auth: ${t.auth}): ${t.description} [best_for: ${t.best_for.join(\", \")}]`\n )\n .join(\"\\n\");\n\n return `## User Intent\\n\\n${intent}\\n\\n## Available Tool Registry\\n\\n${registrySummary}\\n\\nGenerate the EnvironmentSpec JSON now.`;\n}\n\nfunction parseSpecResponse(text: string): Omit<EnvironmentSpec, \"id\" | \"intent\" | \"created_at\"> {\n let cleaned = text.trim();\n // Strip markdown code fences\n if (cleaned.startsWith(\"```\")) {\n cleaned = cleaned.replace(/^```(?:json)?\\n?/, \"\").replace(/\\n?```$/, \"\");\n }\n // Try to extract JSON if there's surrounding text\n const jsonMatch = cleaned.match(/\\{[\\s\\S]*\\}/);\n if (!jsonMatch) {\n throw new Error(\n \"LLM response did not contain valid JSON. Try again or use a different model.\"\n );\n }\n try {\n return JSON.parse(jsonMatch[0]);\n } catch (err) {\n throw new Error(\n `Failed to parse LLM response as JSON: ${err instanceof Error ? err.message : String(err)}\\n` +\n `Response started with: ${cleaned.slice(0, 200)}...`\n );\n }\n}\n\nfunction classifyError(err: unknown, provider: string): string {\n const msg = err instanceof Error ? err.message : String(err);\n const status = (err as { status?: number })?.status;\n const code = (err as { code?: string })?.code;\n\n // Network errors\n if (code === \"ECONNREFUSED\" || code === \"ENOTFOUND\" || code === \"ETIMEDOUT\") {\n return `Network error: could not reach ${provider} API. Check your internet connection.`;\n }\n\n // Auth errors\n if (status === 401 || msg.includes(\"invalid\") && msg.includes(\"key\")) {\n return `Invalid API key for ${provider}. Run \\`kairn init\\` to reconfigure.`;\n }\n if (status === 403) {\n return `Access denied by ${provider}. Your API key may lack permissions for this model.`;\n }\n\n // Rate limiting\n if (status === 429 || msg.includes(\"rate limit\") || msg.includes(\"quota\")) {\n return `Rate limited by ${provider}. Wait a moment and try again, or switch to a cheaper model with \\`kairn init\\`.`;\n }\n\n // Model errors\n if (status === 404 || msg.includes(\"not found\") || msg.includes(\"does not exist\")) {\n return `Model not found on ${provider}. Run \\`kairn init\\` to select a valid model.`;\n }\n\n // Overloaded\n if (status === 529 || status === 503 || msg.includes(\"overloaded\")) {\n return `${provider} is temporarily overloaded. Try again in a few seconds.`;\n }\n\n // Token/context limit\n if (msg.includes(\"token\") && (msg.includes(\"limit\") || msg.includes(\"exceed\"))) {\n return `Request too large for the selected model. Try a shorter workflow description.`;\n }\n\n // Billing\n if (msg.includes(\"billing\") || msg.includes(\"payment\") || msg.includes(\"insufficient\")) {\n return `Billing issue with your ${provider} account. Check your account dashboard.`;\n }\n\n // Fallback\n return `${provider} API error: ${msg}`;\n}\n\nasync function callLLM(config: KairnConfig, userMessage: string): Promise<string> {\n if (config.provider === \"anthropic\") {\n const client = new Anthropic({ apiKey: config.api_key });\n try {\n const response = await client.messages.create({\n model: config.model,\n max_tokens: 8192,\n system: SYSTEM_PROMPT,\n messages: [{ role: \"user\", content: userMessage }],\n });\n const textBlock = response.content.find((block) => block.type === \"text\");\n if (!textBlock || textBlock.type !== \"text\") {\n throw new Error(\"No text response from compiler LLM\");\n }\n return textBlock.text;\n } catch (err) {\n throw new Error(classifyError(err, \"Anthropic\"));\n }\n } else if (config.provider === \"openai\" || config.provider === \"google\") {\n const providerName = config.provider === \"google\" ? \"Google\" : \"OpenAI\";\n const clientOptions: { apiKey: string; baseURL?: string } = { apiKey: config.api_key };\n if (config.provider === \"google\") {\n clientOptions.baseURL = \"https://generativelanguage.googleapis.com/v1beta/openai/\";\n }\n const client = new OpenAI(clientOptions);\n try {\n const response = await client.chat.completions.create({\n model: config.model,\n max_tokens: 8192,\n messages: [\n { role: \"system\", content: SYSTEM_PROMPT },\n { role: \"user\", content: userMessage },\n ],\n });\n const text = response.choices[0]?.message?.content;\n if (!text) {\n throw new Error(\"No text response from compiler LLM\");\n }\n return text;\n } catch (err) {\n throw new Error(classifyError(err, providerName));\n }\n }\n throw new Error(`Unsupported provider: ${config.provider}. Run \\`kairn init\\` to reconfigure.`);\n}\n\nexport async function compile(\n intent: string,\n onProgress?: (msg: string) => void\n): Promise<EnvironmentSpec> {\n const config = await loadConfig();\n if (!config) {\n throw new Error(\"No config found. Run `kairn init` first.\");\n }\n\n onProgress?.(\"Loading tool registry...\");\n const registry = await loadRegistry();\n\n onProgress?.(`Compiling with ${config.provider} (${config.model})...`);\n const userMessage = buildUserMessage(intent, registry);\n const responseText = await callLLM(config, userMessage);\n\n onProgress?.(\"Parsing environment spec...\");\n const parsed = parseSpecResponse(responseText);\n\n const spec: EnvironmentSpec = {\n id: `env_${crypto.randomUUID()}`,\n intent,\n created_at: new Date().toISOString(),\n ...parsed,\n };\n\n // Save to ~/.kairn/envs/\n await ensureDirs();\n const envPath = path.join(getEnvsDir(), `${spec.id}.json`);\n await fs.writeFile(envPath, JSON.stringify(spec, null, 2), \"utf-8\");\n\n return spec;\n}\n","export const SYSTEM_PROMPT = `You are the Kairn environment compiler. Your job is to generate a minimal, optimal Claude Code agent environment from a user's natural language description of what they want their agent to do.\n\nYou will receive:\n1. The user's intent (what they want to build/do)\n2. A tool registry (available MCP servers, plugins, and hooks)\n\nYou must output a JSON object matching the EnvironmentSpec schema.\n\n## Core Principles\n\n- **Minimalism over completeness.** Fewer, well-chosen tools beat many generic ones. Each MCP server costs 500-2000 context tokens.\n- **Workflow-specific, not generic.** Every instruction, command, and rule must relate to the user's actual workflow.\n- **Concise CLAUDE.md.** Under 100 lines. No generic text like \"be helpful.\" Include build/test commands, reference docs/ and skills/.\n- **Security by default.** Always include deny rules for destructive commands and secret file access.\n\n## What You Must Always Include\n\n1. A concise, workflow-specific \\`claude_md\\` (the CLAUDE.md content)\n2. A \\`/project:help\\` command that explains the environment\n3. A \\`/project:tasks\\` command for task management via TODO.md\n4. A \\`docs/TODO.md\\` file for continuity\n5. A \\`docs/DECISIONS.md\\` file for architectural decisions\n6. A \\`docs/LEARNINGS.md\\` file for non-obvious discoveries\n7. A \\`rules/continuity.md\\` rule encouraging updates to DECISIONS.md and LEARNINGS.md\n8. A \\`rules/security.md\\` rule with essential security instructions\n9. settings.json with deny rules for \\`rm -rf\\`, \\`curl|sh\\`, reading \\`.env\\` and \\`secrets/\\`\n\n## Tool Selection Rules\n\n- Only select tools directly relevant to the described workflow\n- Prefer free tools (auth: \"none\") when quality is comparable\n- Tier 1 tools (Context7, Sequential Thinking, security-guidance) should be included in most environments\n- For tools requiring API keys (auth: \"api_key\"), use \\${ENV_VAR} syntax — never hardcode keys\n- Maximum 6-8 MCP servers to avoid context bloat\n- Include a \\`reason\\` for each selected tool explaining why it fits this workflow\n\n## For Code Projects, Additionally Include\n\n- \\`/project:plan\\` command (plan before coding)\n- \\`/project:review\\` command (review changes)\n- \\`/project:test\\` command (run and fix tests)\n- \\`/project:commit\\` command (conventional commits)\n- A TDD skill if testing is relevant\n- A reviewer agent (read-only, Sonnet model)\n\n## For Research Projects, Additionally Include\n\n- \\`/project:research\\` command (deep research on a topic)\n- \\`/project:summarize\\` command (summarize findings)\n- A research-synthesis skill\n- A researcher agent\n\n## For Content/Writing Projects, Additionally Include\n\n- \\`/project:draft\\` command (write first draft)\n- \\`/project:edit\\` command (review and improve writing)\n- A writing-workflow skill\n\n## Output Schema\n\nReturn ONLY valid JSON matching this structure:\n\n\\`\\`\\`json\n{\n \"name\": \"short-kebab-case-name\",\n \"description\": \"One-line description of the environment\",\n \"tools\": [\n { \"tool_id\": \"id-from-registry\", \"reason\": \"why this tool fits\" }\n ],\n \"harness\": {\n \"claude_md\": \"The full CLAUDE.md content (under 100 lines)\",\n \"settings\": {\n \"permissions\": {\n \"allow\": [\"Bash(npm run *)\", \"Read\", \"Write\", \"Edit\"],\n \"deny\": [\"Bash(rm -rf *)\", \"Bash(curl * | sh)\", \"Read(./.env)\", \"Read(./secrets/**)\"]\n }\n },\n \"mcp_config\": {\n \"server-name\": { \"command\": \"npx\", \"args\": [\"...\"], \"env\": {} }\n },\n \"commands\": {\n \"help\": \"markdown content for /project:help\",\n \"tasks\": \"markdown content for /project:tasks\"\n },\n \"rules\": {\n \"continuity\": \"markdown content for continuity rule\",\n \"security\": \"markdown content for security rule\"\n },\n \"skills\": {\n \"skill-name/SKILL\": \"markdown content with YAML frontmatter\"\n },\n \"agents\": {\n \"agent-name\": \"markdown content with YAML frontmatter\"\n },\n \"docs\": {\n \"TODO\": \"# TODO\\\\n\\\\n- [ ] First task based on workflow\",\n \"DECISIONS\": \"# Decisions\\\\n\\\\nArchitectural decisions for this project.\",\n \"LEARNINGS\": \"# Learnings\\\\n\\\\nNon-obvious discoveries and gotchas.\"\n }\n }\n}\n\\`\\`\\`\n\nDo not include any text outside the JSON object. Do not wrap in markdown code fences.`;\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport type { EnvironmentSpec, RegistryTool } from \"../types.js\";\n\nasync function writeFile(filePath: string, content: string): Promise<void> {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, content, \"utf-8\");\n}\n\nexport async function writeEnvironment(\n spec: EnvironmentSpec,\n targetDir: string\n): Promise<string[]> {\n const claudeDir = path.join(targetDir, \".claude\");\n const written: string[] = [];\n\n // 1. CLAUDE.md\n if (spec.harness.claude_md) {\n const p = path.join(claudeDir, \"CLAUDE.md\");\n await writeFile(p, spec.harness.claude_md);\n written.push(\".claude/CLAUDE.md\");\n }\n\n // 2. settings.json\n if (spec.harness.settings && Object.keys(spec.harness.settings).length > 0) {\n const p = path.join(claudeDir, \"settings.json\");\n await writeFile(p, JSON.stringify(spec.harness.settings, null, 2));\n written.push(\".claude/settings.json\");\n }\n\n // 3. .mcp.json (project-scoped, goes in project root)\n if (\n spec.harness.mcp_config &&\n Object.keys(spec.harness.mcp_config).length > 0\n ) {\n const p = path.join(targetDir, \".mcp.json\");\n const mcpContent = { mcpServers: spec.harness.mcp_config };\n await writeFile(p, JSON.stringify(mcpContent, null, 2));\n written.push(\".mcp.json\");\n }\n\n // 4. Commands\n if (spec.harness.commands) {\n for (const [name, content] of Object.entries(spec.harness.commands)) {\n const p = path.join(claudeDir, \"commands\", `${name}.md`);\n await writeFile(p, content);\n written.push(`.claude/commands/${name}.md`);\n }\n }\n\n // 5. Rules\n if (spec.harness.rules) {\n for (const [name, content] of Object.entries(spec.harness.rules)) {\n const p = path.join(claudeDir, \"rules\", `${name}.md`);\n await writeFile(p, content);\n written.push(`.claude/rules/${name}.md`);\n }\n }\n\n // 6. Skills\n if (spec.harness.skills) {\n for (const [skillPath, content] of Object.entries(spec.harness.skills)) {\n const p = path.join(claudeDir, \"skills\", `${skillPath}.md`);\n await writeFile(p, content);\n written.push(`.claude/skills/${skillPath}.md`);\n }\n }\n\n // 7. Agents\n if (spec.harness.agents) {\n for (const [name, content] of Object.entries(spec.harness.agents)) {\n const p = path.join(claudeDir, \"agents\", `${name}.md`);\n await writeFile(p, content);\n written.push(`.claude/agents/${name}.md`);\n }\n }\n\n // 8. Docs\n if (spec.harness.docs) {\n for (const [name, content] of Object.entries(spec.harness.docs)) {\n const p = path.join(claudeDir, \"docs\", `${name}.md`);\n await writeFile(p, content);\n written.push(`.claude/docs/${name}.md`);\n }\n }\n\n return written;\n}\n\nexport interface EnvSetupInfo {\n toolName: string;\n envVar: string;\n description: string;\n signupUrl?: string;\n}\n\nexport function summarizeSpec(\n spec: EnvironmentSpec,\n registry: RegistryTool[]\n): {\n toolCount: number;\n commandCount: number;\n ruleCount: number;\n skillCount: number;\n agentCount: number;\n pluginCommands: string[];\n envSetup: EnvSetupInfo[];\n} {\n const pluginCommands: string[] = [];\n const envSetup: EnvSetupInfo[] = [];\n\n for (const selected of spec.tools) {\n const tool = registry.find((t) => t.id === selected.tool_id);\n if (!tool) continue;\n\n if (tool.install.plugin_command) {\n pluginCommands.push(tool.install.plugin_command);\n }\n\n if (tool.env_vars) {\n for (const ev of tool.env_vars) {\n envSetup.push({\n toolName: tool.name,\n envVar: ev.name,\n description: ev.description,\n signupUrl: tool.signup_url,\n });\n }\n }\n }\n\n return {\n toolCount: spec.tools.length,\n commandCount: Object.keys(spec.harness.commands || {}).length,\n ruleCount: Object.keys(spec.harness.rules || {}).length,\n skillCount: Object.keys(spec.harness.skills || {}).length,\n agentCount: Object.keys(spec.harness.agents || {}).length,\n pluginCommands,\n envSetup,\n };\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { getEnvsDir } from \"../config.js\";\nimport type { EnvironmentSpec } from \"../types.js\";\n\nexport const listCommand = new Command(\"list\")\n .description(\"Show saved environments\")\n .action(async () => {\n const envsDir = getEnvsDir();\n\n let files: string[];\n try {\n files = await fs.readdir(envsDir);\n } catch {\n console.log(chalk.dim(\"\\n No environments yet. Run \") +\n chalk.bold(\"kairn describe\") +\n chalk.dim(\" to create one.\\n\"));\n return;\n }\n\n const jsonFiles = files.filter((f) => f.endsWith(\".json\"));\n\n if (jsonFiles.length === 0) {\n console.log(chalk.dim(\"\\n No environments yet. Run \") +\n chalk.bold(\"kairn describe\") +\n chalk.dim(\" to create one.\\n\"));\n return;\n }\n\n console.log(chalk.cyan(\"\\n Saved Environments\\n\"));\n\n for (const file of jsonFiles) {\n try {\n const data = await fs.readFile(path.join(envsDir, file), \"utf-8\");\n const spec = JSON.parse(data) as EnvironmentSpec;\n const date = new Date(spec.created_at).toLocaleDateString();\n const toolCount = spec.tools?.length ?? 0;\n\n console.log(chalk.bold(` ${spec.name}`));\n console.log(chalk.dim(` ${spec.description}`));\n console.log(\n chalk.dim(` ${date} · ${toolCount} tools · ${spec.id}`)\n );\n console.log(\"\");\n } catch {\n // Skip malformed files\n }\n }\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { getEnvsDir } from \"../config.js\";\nimport { writeEnvironment } from \"../adapter/claude-code.js\";\nimport type { EnvironmentSpec } from \"../types.js\";\n\nexport const activateCommand = new Command(\"activate\")\n .description(\"Re-deploy a saved environment to the current directory\")\n .argument(\"<env_id>\", \"Environment ID (from kairn list)\")\n .action(async (envId: string) => {\n const envsDir = getEnvsDir();\n\n // Find the env file — accept full ID or partial match\n let files: string[];\n try {\n files = await fs.readdir(envsDir);\n } catch {\n console.log(chalk.red(\"\\n No saved environments found.\\n\"));\n process.exit(1);\n }\n\n const match = files.find(\n (f) => f === `${envId}.json` || f.startsWith(envId)\n );\n\n if (!match) {\n console.log(chalk.red(`\\n Environment \"${envId}\" not found.`));\n console.log(chalk.dim(\" Run kairn list to see saved environments.\\n\"));\n process.exit(1);\n }\n\n const data = await fs.readFile(path.join(envsDir, match), \"utf-8\");\n const spec = JSON.parse(data) as EnvironmentSpec;\n\n console.log(chalk.cyan(`\\n Activating: ${spec.name}`));\n console.log(chalk.dim(` ${spec.description}\\n`));\n\n const targetDir = process.cwd();\n const written = await writeEnvironment(spec, targetDir);\n\n console.log(chalk.green(\" ✓ Environment written\\n\"));\n for (const file of written) {\n console.log(chalk.dim(` ${file}`));\n }\n\n console.log(\n chalk.cyan(\"\\n Ready! Run \") +\n chalk.bold(\"claude\") +\n chalk.cyan(\" to start.\\n\")\n );\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\n\nconst REGISTRY_URL =\n \"https://raw.githubusercontent.com/ashtonperlroth/kairn/main/src/registry/tools.json\";\n\nasync function getLocalRegistryPath(): Promise<string> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidates = [\n path.resolve(__dirname, \"../registry/tools.json\"),\n path.resolve(__dirname, \"../src/registry/tools.json\"),\n path.resolve(__dirname, \"../../src/registry/tools.json\"),\n ];\n for (const candidate of candidates) {\n try {\n await fs.access(candidate);\n return candidate;\n } catch {\n continue;\n }\n }\n throw new Error(\"Could not find local tools.json registry\");\n}\n\nexport const updateRegistryCommand = new Command(\"update-registry\")\n .description(\"Fetch the latest tool registry from GitHub\")\n .option(\"--url <url>\", \"Custom registry URL\")\n .action(async (options: { url?: string }) => {\n const url = options.url || REGISTRY_URL;\n\n console.log(chalk.dim(`\\n Fetching registry from ${url}...`));\n\n try {\n const response = await fetch(url);\n\n if (!response.ok) {\n console.log(\n chalk.red(` Failed to fetch registry: ${response.status} ${response.statusText}`)\n );\n console.log(\n chalk.dim(\" The remote registry may not be available yet.\")\n );\n console.log(\n chalk.dim(\" Your local registry is still active.\\n\")\n );\n return;\n }\n\n const text = await response.text();\n\n // Validate it's valid JSON and has the expected structure\n let tools: unknown[];\n try {\n tools = JSON.parse(text);\n if (!Array.isArray(tools)) throw new Error(\"Not an array\");\n if (tools.length === 0) throw new Error(\"Empty registry\");\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(` Invalid registry format: ${msg}\\n`));\n return;\n }\n\n const registryPath = await getLocalRegistryPath();\n\n // Back up existing registry\n const backupPath = registryPath + \".bak\";\n try {\n await fs.copyFile(registryPath, backupPath);\n } catch {\n // No existing file to back up\n }\n\n await fs.writeFile(registryPath, JSON.stringify(tools, null, 2), \"utf-8\");\n\n console.log(chalk.green(` ✓ Registry updated: ${tools.length} tools`));\n console.log(chalk.dim(` Saved to: ${registryPath}`));\n console.log(chalk.dim(` Backup: ${backupPath}\\n`));\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(` Network error: ${msg}`));\n console.log(chalk.dim(\" Your local registry is still active.\\n\"));\n }\n });\n","import { Command } from \"commander\";\nimport { input, confirm, checkbox } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { loadConfig } from \"../config.js\";\nimport { compile } from \"../compiler/compile.js\";\nimport { writeEnvironment, summarizeSpec } from \"../adapter/claude-code.js\";\nimport { scanProject } from \"../scanner/scan.js\";\nimport type { ProjectProfile } from \"../scanner/scan.js\";\nimport type { RegistryTool } from \"../types.js\";\n\nasync function loadRegistry(): Promise<RegistryTool[]> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidates = [\n path.resolve(__dirname, \"../registry/tools.json\"),\n path.resolve(__dirname, \"../src/registry/tools.json\"),\n path.resolve(__dirname, \"../../src/registry/tools.json\"),\n ];\n for (const candidate of candidates) {\n try {\n const data = await fs.readFile(candidate, \"utf-8\");\n return JSON.parse(data) as RegistryTool[];\n } catch {\n continue;\n }\n }\n throw new Error(\"Could not find tools.json registry\");\n}\n\nfunction buildProfileSummary(profile: ProjectProfile): string {\n const lines: string[] = [];\n lines.push(`Project: ${profile.name}`);\n if (profile.description) lines.push(`Description: ${profile.description}`);\n if (profile.language) lines.push(`Language: ${profile.language}`);\n if (profile.framework) lines.push(`Framework: ${profile.framework}`);\n if (profile.dependencies.length > 0) {\n lines.push(`Dependencies: ${profile.dependencies.join(\", \")}`);\n }\n if (profile.testCommand) lines.push(`Test command: ${profile.testCommand}`);\n if (profile.buildCommand) lines.push(`Build command: ${profile.buildCommand}`);\n if (profile.lintCommand) lines.push(`Lint command: ${profile.lintCommand}`);\n if (profile.hasDocker) lines.push(\"Has Docker configuration\");\n if (profile.hasCi) lines.push(\"Has CI/CD (GitHub Actions)\");\n if (profile.envKeys.length > 0) {\n lines.push(`Env keys needed: ${profile.envKeys.join(\", \")}`);\n }\n return lines.join(\"\\n\");\n}\n\nfunction buildAuditSummary(profile: ProjectProfile): string {\n const lines: string[] = [];\n lines.push(`\\nExisting .claude/ harness found:`);\n lines.push(` CLAUDE.md: ${profile.claudeMdLineCount} lines${profile.claudeMdLineCount > 200 ? \" (⚠ over 200 — may degrade adherence)\" : \"\"}`);\n lines.push(` MCP servers: ${profile.mcpServerCount}`);\n lines.push(` Commands: ${profile.existingCommands.length > 0 ? profile.existingCommands.map(c => `/project:${c}`).join(\", \") : \"none\"}`);\n lines.push(` Rules: ${profile.existingRules.length > 0 ? profile.existingRules.join(\", \") : \"none\"}`);\n lines.push(` Skills: ${profile.existingSkills.length > 0 ? profile.existingSkills.join(\", \") : \"none\"}`);\n lines.push(` Agents: ${profile.existingAgents.length > 0 ? profile.existingAgents.join(\", \") : \"none\"}`);\n return lines.join(\"\\n\");\n}\n\nfunction buildOptimizeIntent(profile: ProjectProfile): string {\n const parts: string[] = [];\n\n parts.push(\"## Project Profile (scanned from actual codebase)\\n\");\n parts.push(buildProfileSummary(profile));\n\n if (profile.hasClaudeDir) {\n parts.push(buildAuditSummary(profile));\n\n if (profile.existingClaudeMd) {\n parts.push(`\\n## Existing CLAUDE.md Content\\n\\n${profile.existingClaudeMd}`);\n }\n\n parts.push(`\\n## Task\\n`);\n parts.push(\"Analyze this existing Claude Code environment and generate an OPTIMIZED version.\");\n parts.push(\"Preserve what works. Fix what's wrong. Add what's missing. Remove what's bloat.\");\n parts.push(\"Key optimizations to consider:\");\n parts.push(\"- Is CLAUDE.md under 100 lines? If not, move detail to rules/ or docs/\");\n parts.push(\"- Are the right MCP servers selected for these dependencies?\");\n parts.push(\"- Are there missing slash commands (help, tasks, plan, test, commit)?\");\n parts.push(\"- Are security rules present?\");\n parts.push(\"- Is there a continuity rule for session memory?\");\n parts.push(\"- Are there unnecessary MCP servers adding context bloat?\");\n if (profile.claudeMdLineCount > 200) {\n parts.push(`- CLAUDE.md is ${profile.claudeMdLineCount} lines — needs aggressive trimming`);\n }\n if (!profile.existingCommands.includes(\"help\")) {\n parts.push(\"- Missing /project:help command\");\n }\n if (!profile.existingRules.includes(\"security\")) {\n parts.push(\"- Missing security rules\");\n }\n } else {\n parts.push(`\\n## Task\\n`);\n parts.push(\"Generate an optimal Claude Code environment for this existing project.\");\n parts.push(\"Use the scanned project profile — this is a real codebase, not a description.\");\n parts.push(\"The environment should match the actual tech stack, dependencies, and workflows.\");\n }\n\n return parts.join(\"\\n\");\n}\n\nexport const optimizeCommand = new Command(\"optimize\")\n .description(\"Scan an existing project and generate or optimize its Claude Code environment\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"--audit-only\", \"Only audit the existing harness, don't generate changes\")\n .action(async (options: { yes?: boolean; auditOnly?: boolean }) => {\n const config = await loadConfig();\n if (!config) {\n console.log(\n chalk.red(\"\\n No config found. Run \") +\n chalk.bold(\"kairn init\") +\n chalk.red(\" first.\\n\")\n );\n process.exit(1);\n }\n\n const targetDir = process.cwd();\n\n // 1. Scan\n console.log(chalk.dim(\"\\n Scanning project...\"));\n const profile = await scanProject(targetDir);\n\n // 2. Show profile\n console.log(chalk.cyan(\"\\n Project Profile\\n\"));\n if (profile.language) console.log(chalk.dim(` Language: ${profile.language}`));\n if (profile.framework) console.log(chalk.dim(` Framework: ${profile.framework}`));\n console.log(chalk.dim(` Dependencies: ${profile.dependencies.length}`));\n if (profile.testCommand) console.log(chalk.dim(` Tests: ${profile.testCommand}`));\n if (profile.buildCommand) console.log(chalk.dim(` Build: ${profile.buildCommand}`));\n if (profile.hasDocker) console.log(chalk.dim(\" Docker: yes\"));\n if (profile.hasCi) console.log(chalk.dim(\" CI/CD: yes\"));\n if (profile.envKeys.length > 0) console.log(chalk.dim(` Env keys: ${profile.envKeys.join(\", \")}`));\n\n // 3. Audit existing harness\n if (profile.hasClaudeDir) {\n console.log(chalk.yellow(\"\\n Existing .claude/ harness detected\\n\"));\n console.log(chalk.dim(` CLAUDE.md: ${profile.claudeMdLineCount} lines${profile.claudeMdLineCount > 200 ? chalk.yellow(\" ⚠ bloated\") : chalk.green(\" ✓\")}`));\n console.log(chalk.dim(` MCP servers: ${profile.mcpServerCount}`));\n console.log(chalk.dim(` Commands: ${profile.existingCommands.length > 0 ? profile.existingCommands.map(c => c).join(\", \") : \"none\"}`));\n console.log(chalk.dim(` Rules: ${profile.existingRules.length > 0 ? profile.existingRules.join(\", \") : \"none\"}`));\n console.log(chalk.dim(` Skills: ${profile.existingSkills.length > 0 ? profile.existingSkills.join(\", \") : \"none\"}`));\n console.log(chalk.dim(` Agents: ${profile.existingAgents.length > 0 ? profile.existingAgents.join(\", \") : \"none\"}`));\n\n // Quick audit checks\n const issues: string[] = [];\n if (profile.claudeMdLineCount > 200) issues.push(\"CLAUDE.md over 200 lines — move detail to rules/ or docs/\");\n if (!profile.existingCommands.includes(\"help\")) issues.push(\"Missing /project:help command\");\n if (!profile.existingRules.includes(\"security\")) issues.push(\"Missing security rules\");\n if (!profile.existingRules.includes(\"continuity\")) issues.push(\"Missing continuity rule for session memory\");\n if (profile.mcpServerCount > 8) issues.push(`${profile.mcpServerCount} MCP servers — may cause context bloat`);\n if (profile.mcpServerCount === 0 && profile.dependencies.length > 0) issues.push(\"No MCP servers configured\");\n if (profile.hasTests && !profile.existingCommands.includes(\"test\")) issues.push(\"Has tests but no /project:test command\");\n if (!profile.existingCommands.includes(\"tasks\")) issues.push(\"Missing /project:tasks command\");\n\n if (issues.length > 0) {\n console.log(chalk.yellow(\"\\n Issues Found:\\n\"));\n for (const issue of issues) {\n console.log(chalk.yellow(` ⚠ ${issue}`));\n }\n } else {\n console.log(chalk.green(\"\\n ✓ No obvious issues found\"));\n }\n\n if (options.auditOnly) {\n console.log(chalk.dim(\"\\n Audit complete. Run without --audit-only to generate optimized environment.\\n\"));\n return;\n }\n\n // Ask before overwriting\n if (!options.yes) {\n console.log(\"\");\n const proceed = await confirm({\n message: \"Generate optimized environment? This will overwrite existing .claude/ files.\",\n default: false,\n });\n if (!proceed) {\n console.log(chalk.dim(\"\\n Aborted.\\n\"));\n return;\n }\n }\n } else {\n console.log(chalk.dim(\"\\n No existing .claude/ directory found — generating from scratch.\\n\"));\n\n if (!options.yes) {\n const proceed = await confirm({\n message: \"Generate Claude Code environment for this project?\",\n default: true,\n });\n if (!proceed) {\n console.log(chalk.dim(\"\\n Aborted.\\n\"));\n return;\n }\n }\n }\n\n // 4. Compile with scanned profile\n const intent = buildOptimizeIntent(profile);\n let spec;\n try {\n spec = await compile(intent, (msg) => {\n process.stdout.write(`\\r ${chalk.dim(msg)} `);\n });\n process.stdout.write(\"\\r \\r\");\n } catch (err) {\n process.stdout.write(\"\\r \\r\");\n const msg = err instanceof Error ? err.message : String(err);\n console.log(chalk.red(`\\n Optimization failed: ${msg}\\n`));\n process.exit(1);\n }\n\n // 5. Show results\n const registry = await loadRegistry();\n const summary = summarizeSpec(spec, registry);\n\n console.log(chalk.green(\" ✓ Environment compiled\\n\"));\n console.log(chalk.cyan(\" Name: \") + spec.name);\n console.log(chalk.cyan(\" Tools: \") + summary.toolCount);\n console.log(chalk.cyan(\" Commands: \") + summary.commandCount);\n console.log(chalk.cyan(\" Rules: \") + summary.ruleCount);\n console.log(chalk.cyan(\" Skills: \") + summary.skillCount);\n console.log(chalk.cyan(\" Agents: \") + summary.agentCount);\n\n if (spec.tools.length > 0) {\n console.log(chalk.dim(\"\\n Selected tools:\"));\n for (const tool of spec.tools) {\n const regTool = registry.find((t) => t.id === tool.tool_id);\n const name = regTool?.name || tool.tool_id;\n console.log(chalk.dim(` - ${name}: ${tool.reason}`));\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(chalk.yellow(\"\\n Plugins to install manually:\"));\n for (const cmd of summary.pluginCommands) {\n console.log(chalk.yellow(` ${cmd}`));\n }\n }\n\n // 6. Write\n const written = await writeEnvironment(spec, targetDir);\n\n console.log(chalk.green(\"\\n ✓ Environment written\\n\"));\n for (const file of written) {\n console.log(chalk.dim(` ${file}`));\n }\n\n if (summary.envSetup.length > 0) {\n console.log(chalk.yellow(\"\\n API keys needed (set these environment variables):\\n\"));\n const seen = new Set<string>();\n for (const env of summary.envSetup) {\n if (seen.has(env.envVar)) continue;\n seen.add(env.envVar);\n console.log(chalk.bold(` export ${env.envVar}=\"your-key-here\"`));\n console.log(chalk.dim(` ${env.description}`));\n if (env.signupUrl) {\n console.log(chalk.dim(` Get one at: ${env.signupUrl}`));\n }\n console.log(\"\");\n }\n }\n\n if (summary.pluginCommands.length > 0) {\n console.log(chalk.yellow(\" Install plugins by running these in Claude Code:\"));\n for (const cmd of summary.pluginCommands) {\n console.log(chalk.bold(` ${cmd}`));\n }\n }\n\n console.log(\n chalk.cyan(\"\\n Ready! Run \") +\n chalk.bold(\"claude\") +\n chalk.cyan(\" to start.\\n\")\n );\n });\n","import fs from \"fs/promises\";\nimport path from \"path\";\n\nexport interface ProjectProfile {\n // Core identity\n name: string;\n description: string;\n directory: string;\n\n // Language & framework\n language: string | null;\n framework: string | null;\n typescript: boolean;\n\n // Dependencies\n dependencies: string[];\n devDependencies: string[];\n\n // Scripts & commands\n scripts: Record<string, string>;\n hasTests: boolean;\n testCommand: string | null;\n buildCommand: string | null;\n lintCommand: string | null;\n\n // Project structure\n hasSrc: boolean;\n hasDocker: boolean;\n hasCi: boolean;\n hasEnvFile: boolean;\n envKeys: string[]; // from .env.example only — never read .env values\n\n // Existing harness\n hasClaudeDir: boolean;\n existingClaudeMd: string | null;\n existingSettings: Record<string, unknown> | null;\n existingMcpConfig: Record<string, unknown> | null;\n existingCommands: string[];\n existingRules: string[];\n existingSkills: string[];\n existingAgents: string[];\n mcpServerCount: number;\n claudeMdLineCount: number;\n\n // Key files found\n keyFiles: string[];\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await fs.access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function readJsonSafe(p: string): Promise<Record<string, unknown> | null> {\n try {\n const data = await fs.readFile(p, \"utf-8\");\n return JSON.parse(data);\n } catch {\n return null;\n }\n}\n\nasync function readFileSafe(p: string): Promise<string | null> {\n try {\n return await fs.readFile(p, \"utf-8\");\n } catch {\n return null;\n }\n}\n\nasync function listDirSafe(p: string): Promise<string[]> {\n try {\n const entries = await fs.readdir(p);\n return entries.filter((e) => !e.startsWith(\".\"));\n } catch {\n return [];\n }\n}\n\nfunction detectFramework(deps: string[]): string | null {\n const frameworks: [string[], string][] = [\n [[\"next\"], \"Next.js\"],\n [[\"nuxt\"], \"Nuxt\"],\n [[\"@remix-run/node\", \"@remix-run/react\"], \"Remix\"],\n [[\"svelte\", \"@sveltejs/kit\"], \"SvelteKit\"],\n [[\"express\"], \"Express\"],\n [[\"fastify\"], \"Fastify\"],\n [[\"hono\"], \"Hono\"],\n [[\"react\", \"react-dom\"], \"React\"],\n [[\"vue\"], \"Vue\"],\n [[\"angular\"], \"Angular\"],\n [[\"django\"], \"Django\"],\n [[\"flask\"], \"Flask\"],\n [[\"fastapi\"], \"FastAPI\"],\n [[\"@supabase/supabase-js\"], \"Supabase\"],\n [[\"prisma\", \"@prisma/client\"], \"Prisma\"],\n [[\"drizzle-orm\"], \"Drizzle\"],\n [[\"tailwindcss\"], \"Tailwind CSS\"],\n ];\n\n const detected: string[] = [];\n for (const [packages, name] of frameworks) {\n if (packages.some((pkg) => deps.includes(pkg))) {\n detected.push(name);\n }\n }\n return detected.length > 0 ? detected.join(\" + \") : null;\n}\n\nfunction detectLanguage(dir: string, keyFiles: string[]): string | null {\n if (keyFiles.some((f) => f === \"tsconfig.json\")) return \"TypeScript\";\n if (keyFiles.some((f) => f === \"package.json\")) return \"JavaScript\";\n if (keyFiles.some((f) => f === \"pyproject.toml\" || f === \"setup.py\" || f === \"requirements.txt\")) return \"Python\";\n if (keyFiles.some((f) => f === \"Cargo.toml\")) return \"Rust\";\n if (keyFiles.some((f) => f === \"go.mod\")) return \"Go\";\n if (keyFiles.some((f) => f === \"Gemfile\")) return \"Ruby\";\n return null;\n}\n\nfunction extractEnvKeys(content: string): string[] {\n const keys: string[] = [];\n for (const line of content.split(\"\\n\")) {\n const match = line.match(/^([A-Z][A-Z0-9_]*)=/);\n if (match) keys.push(match[1]);\n }\n return keys;\n}\n\nexport async function scanProject(dir: string): Promise<ProjectProfile> {\n // Read package.json\n const pkg = await readJsonSafe(path.join(dir, \"package.json\")) as Record<string, unknown> | null;\n const deps = pkg?.dependencies ? Object.keys(pkg.dependencies as Record<string, string>) : [];\n const devDeps = pkg?.devDependencies ? Object.keys(pkg.devDependencies as Record<string, string>) : [];\n const allDeps = [...deps, ...devDeps];\n const scripts = (pkg?.scripts || {}) as Record<string, string>;\n\n // Detect key files\n const rootFiles = await listDirSafe(dir);\n const keyFiles = rootFiles.filter((f) =>\n [\n \"package.json\", \"tsconfig.json\", \"pyproject.toml\", \"setup.py\",\n \"requirements.txt\", \"Cargo.toml\", \"go.mod\", \"Gemfile\",\n \"docker-compose.yml\", \"Dockerfile\", \".env.example\", \".env\",\n \"README.md\", \"CLAUDE.md\",\n ].includes(f)\n );\n\n // Detect language & framework\n const language = detectLanguage(dir, keyFiles);\n const framework = detectFramework(allDeps);\n const typescript = keyFiles.includes(\"tsconfig.json\") || allDeps.includes(\"typescript\");\n\n // Test detection\n const testCommand = scripts.test && scripts.test !== 'echo \"Error: no test specified\" && exit 1'\n ? scripts.test : null;\n const hasTests = testCommand !== null ||\n await fileExists(path.join(dir, \"tests\")) ||\n await fileExists(path.join(dir, \"__tests__\")) ||\n await fileExists(path.join(dir, \"test\"));\n\n // Build & lint\n const buildCommand = scripts.build || null;\n const lintCommand = scripts.lint || null;\n\n // Structure\n const hasSrc = await fileExists(path.join(dir, \"src\"));\n const hasDocker = await fileExists(path.join(dir, \"docker-compose.yml\")) ||\n await fileExists(path.join(dir, \"Dockerfile\"));\n const hasCi = await fileExists(path.join(dir, \".github/workflows\"));\n\n // Env keys (from .env.example only — never read actual .env values)\n const hasEnvFile = await fileExists(path.join(dir, \".env\")) ||\n await fileExists(path.join(dir, \".env.example\"));\n let envKeys: string[] = [];\n const envExample = await readFileSafe(path.join(dir, \".env.example\"));\n if (envExample) {\n envKeys = extractEnvKeys(envExample);\n }\n\n // Existing .claude/ harness\n const claudeDir = path.join(dir, \".claude\");\n const hasClaudeDir = await fileExists(claudeDir);\n let existingClaudeMd: string | null = null;\n let existingSettings: Record<string, unknown> | null = null;\n let existingMcpConfig: Record<string, unknown> | null = null;\n let existingCommands: string[] = [];\n let existingRules: string[] = [];\n let existingSkills: string[] = [];\n let existingAgents: string[] = [];\n let mcpServerCount = 0;\n let claudeMdLineCount = 0;\n\n if (hasClaudeDir) {\n existingClaudeMd = await readFileSafe(path.join(claudeDir, \"CLAUDE.md\"));\n if (existingClaudeMd) {\n claudeMdLineCount = existingClaudeMd.split(\"\\n\").length;\n }\n\n existingSettings = await readJsonSafe(path.join(claudeDir, \"settings.json\"));\n existingMcpConfig = await readJsonSafe(path.join(dir, \".mcp.json\"));\n if (existingMcpConfig?.mcpServers) {\n mcpServerCount = Object.keys(existingMcpConfig.mcpServers as Record<string, unknown>).length;\n }\n\n existingCommands = (await listDirSafe(path.join(claudeDir, \"commands\")))\n .filter((f) => f.endsWith(\".md\"))\n .map((f) => f.replace(\".md\", \"\"));\n existingRules = (await listDirSafe(path.join(claudeDir, \"rules\")))\n .filter((f) => f.endsWith(\".md\"))\n .map((f) => f.replace(\".md\", \"\"));\n existingSkills = await listDirSafe(path.join(claudeDir, \"skills\"));\n existingAgents = (await listDirSafe(path.join(claudeDir, \"agents\")))\n .filter((f) => f.endsWith(\".md\"))\n .map((f) => f.replace(\".md\", \"\"));\n }\n\n // Project name & description\n const name = (pkg?.name as string) || path.basename(dir);\n const description = (pkg?.description as string) || \"\";\n\n return {\n name,\n description,\n directory: dir,\n language,\n framework,\n typescript,\n dependencies: deps,\n devDependencies: devDeps,\n scripts,\n hasTests,\n testCommand,\n buildCommand,\n lintCommand,\n hasSrc,\n hasDocker,\n hasCi,\n hasEnvFile,\n envKeys,\n hasClaudeDir,\n existingClaudeMd,\n existingSettings,\n existingMcpConfig,\n existingCommands,\n existingRules,\n existingSkills,\n existingAgents,\n mcpServerCount,\n claudeMdLineCount,\n keyFiles,\n };\n}\n"],"mappings":";AAAA,SAAS,WAAAA,gBAAe;;;ACAxB,SAAS,eAAe;AACxB,SAAS,UAAU,cAAc;AACjC,OAAO,WAAW;AAClB,OAAO,eAAe;AACtB,OAAO,YAAY;AACnB,SAAS,oBAAoB;;;ACL7B,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,OAAO,QAAQ;AAGf,IAAM,YAAY,KAAK,KAAK,GAAG,QAAQ,GAAG,QAAQ;AAClD,IAAM,cAAc,KAAK,KAAK,WAAW,aAAa;AACtD,IAAM,WAAW,KAAK,KAAK,WAAW,MAAM;AAMrC,SAAS,gBAAwB;AACtC,SAAO;AACT;AAEO,SAAS,aAAqB;AACnC,SAAO;AACT;AAEA,eAAsB,aAA4B;AAChD,QAAM,GAAG,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAC7C,QAAM,GAAG,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAC9C;AAEA,eAAsB,aAA0C;AAC9D,MAAI;AACF,UAAM,OAAO,MAAM,GAAG,SAAS,aAAa,OAAO;AACnD,UAAM,MAAM,KAAK,MAAM,IAAI;AAG3B,QAAI,IAAI,qBAAqB,CAAC,IAAI,UAAU;AAC1C,aAAO;AAAA,QACL,UAAU;AAAA,QACV,SAAS,IAAI;AAAA,QACb,OAAO;AAAA,QACP,iBAAiB;AAAA,QACjB,YAAa,IAAI,eAAyB,oBAAI,KAAK,GAAE,YAAY;AAAA,MACnE;AAAA,IACF;AAEA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,WAAW,QAAoC;AACnE,QAAM,WAAW;AACjB,QAAM,GAAG,UAAU,aAAa,KAAK,UAAU,QAAQ,MAAM,CAAC,GAAG,OAAO;AAC1E;;;AD1CA,IAAM,kBAAoG;AAAA,EACxG,WAAW;AAAA,IACT,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,sDAAiD,OAAO,oBAAoB;AAAA,MACpF,EAAE,MAAM,qCAAqC,OAAO,kBAAkB;AAAA,MACtE,EAAE,MAAM,wCAAwC,OAAO,4BAA4B;AAAA,IACrF;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,wBAAwB,OAAO,SAAS;AAAA,MAChD,EAAE,MAAM,iCAAiC,OAAO,cAAc;AAAA,MAC9D,EAAE,MAAM,kBAAkB,OAAO,KAAK;AAAA,IACxC;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,kCAAkC,OAAO,iCAAiC;AAAA,MAClF,EAAE,MAAM,oCAAoC,OAAO,+BAA+B;AAAA,IACpF;AAAA,EACF;AACF;AAEA,eAAe,UAAU,UAAuB,QAAgB,OAAiC;AAC/F,MAAI;AACF,QAAI,aAAa,aAAa;AAC5B,YAAM,SAAS,IAAI,UAAU,EAAE,OAAO,CAAC;AACvC,YAAM,OAAO,SAAS,OAAO;AAAA,QAC3B,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,UAAU,CAAC,EAAE,MAAM,QAAQ,SAAS,OAAO,CAAC;AAAA,MAC9C,CAAC;AACD,aAAO;AAAA,IACT,WAAW,aAAa,UAAU;AAChC,YAAM,SAAS,IAAI,OAAO,EAAE,OAAO,CAAC;AACpC,YAAM,OAAO,KAAK,YAAY,OAAO;AAAA,QACnC,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,UAAU,CAAC,EAAE,MAAM,QAAQ,SAAS,OAAO,CAAC;AAAA,MAC9C,CAAC;AACD,aAAO;AAAA,IACT,WAAW,aAAa,UAAU;AAEhC,YAAM,SAAS,IAAI,OAAO;AAAA,QACxB;AAAA,QACA,SAAS;AAAA,MACX,CAAC;AACD,YAAM,OAAO,KAAK,YAAY,OAAO;AAAA,QACnC,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,UAAU,CAAC,EAAE,MAAM,QAAQ,SAAS,OAAO,CAAC;AAAA,MAC9C,CAAC;AACD,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,mBAA4B;AACnC,MAAI;AACF,iBAAa,SAAS,CAAC,QAAQ,GAAG,EAAE,OAAO,SAAS,CAAC;AACrD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,IAAM,cAAc,IAAI,QAAQ,MAAM,EAC1C,YAAY,gCAAgC,EAC5C,OAAO,YAAY;AAClB,UAAQ,IAAI,MAAM,KAAK,mBAAmB,CAAC;AAE3C,QAAM,WAAW,MAAM,WAAW;AAClC,MAAI,UAAU;AACZ,YAAQ;AAAA,MACN,MAAM,OAAO,6BAA6B,IACxC,MAAM,IAAI,cAAc,CAAC;AAAA,IAC7B;AACA,YAAQ,IAAI,MAAM,OAAO,sCAAsC,CAAC;AAAA,EAClE;AAEA,QAAM,WAAW,MAAM,OAAoB;AAAA,IACzC,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,MAAM,yCAAoC,OAAO,YAA2B;AAAA,MAC9E,EAAE,MAAM,gBAAgB,OAAO,SAAwB;AAAA,MACvD,EAAE,MAAM,mBAAmB,OAAO,SAAwB;AAAA,IAC5D;AAAA,EACF,CAAC;AAED,QAAM,eAAe,gBAAgB,QAAQ;AAE7C,QAAM,QAAQ,MAAM,OAAO;AAAA,IACzB,SAAS;AAAA,IACT,SAAS,aAAa;AAAA,EACxB,CAAC;AAED,QAAM,SAAS,MAAM,SAAS;AAAA,IAC5B,SAAS,GAAG,aAAa,IAAI;AAAA,IAC7B,MAAM;AAAA,EACR,CAAC;AAED,MAAI,CAAC,QAAQ;AACX,YAAQ,IAAI,MAAM,IAAI,oCAAoC,CAAC;AAC3D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,MAAM,IAAI,0BAA0B,CAAC;AACjD,QAAM,QAAQ,MAAM,UAAU,UAAU,QAAQ,KAAK;AAErD,MAAI,CAAC,OAAO;AACV,YAAQ;AAAA,MACN,MAAM,IAAI,kDAAkD;AAAA,IAC9D;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,MAAM,MAAM,2BAAsB,CAAC;AAE/C,QAAM,SAAsB;AAAA,IAC1B;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA,iBAAiB;AAAA,IACjB,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,EACrC;AAEA,QAAM,WAAW,MAAM;AACvB,UAAQ;AAAA,IACN,MAAM,MAAM,2BAAsB,IAAI,MAAM,IAAI,cAAc,CAAC;AAAA,EACjE;AACA,UAAQ;AAAA,IACN,MAAM,IAAI,sBAAiB,aAAa,IAAI,YAAY,KAAK,EAAE;AAAA,EACjE;AAEA,QAAM,YAAY,iBAAiB;AACnC,MAAI,WAAW;AACb,YAAQ,IAAI,MAAM,MAAM,+BAA0B,CAAC;AAAA,EACrD,OAAO;AACL,YAAQ;AAAA,MACN,MAAM;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,UAAQ;AAAA,IACN,MAAM,KAAK,iBAAiB,IAC1B,MAAM,KAAK,gBAAgB,IAC3B,MAAM,KAAK,sCAAsC;AAAA,EACrD;AACF,CAAC;;;AErKH,SAAS,WAAAC,gBAAe;AACxB,SAAS,OAAO,eAAe;AAC/B,OAAOC,YAAW;AAClB,OAAOC,SAAQ;AACf,OAAOC,WAAU;;;ACJjB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,qBAAqB;AAC9B,OAAO,YAAY;AACnB,OAAOC,gBAAe;AACtB,OAAOC,aAAY;;;ACLZ,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ADU7B,eAAe,eAAwC;AACrD,QAAM,aAAa,cAAc,YAAY,GAAG;AAChD,QAAM,YAAYC,MAAK,QAAQ,UAAU;AACzC,QAAM,aAAa;AAAA,IACjBA,MAAK,QAAQ,WAAW,wBAAwB;AAAA,IAChDA,MAAK,QAAQ,WAAW,4BAA4B;AAAA,IACpDA,MAAK,QAAQ,WAAW,+BAA+B;AAAA,EACzD;AACA,aAAW,aAAa,YAAY;AAClC,QAAI;AACF,YAAM,OAAO,MAAMC,IAAG,SAAS,WAAW,OAAO;AACjD,aAAO,KAAK,MAAM,IAAI;AAAA,IACxB,QAAQ;AACN;AAAA,IACF;AAAA,EACF;AACA,QAAM,IAAI,MAAM,oCAAoC;AACtD;AAEA,SAAS,iBAAiB,QAAgB,UAAkC;AAC1E,QAAM,kBAAkB,SACrB;AAAA,IACC,CAAC,MACC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,UAAU,EAAE,IAAI,WAAW,EAAE,IAAI,MAAM,EAAE,WAAW,eAAe,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA,EAChH,EACC,KAAK,IAAI;AAEZ,SAAO;AAAA;AAAA,EAAqB,MAAM;AAAA;AAAA;AAAA;AAAA,EAAqC,eAAe;AAAA;AAAA;AACxF;AAEA,SAAS,kBAAkB,MAAqE;AAC9F,MAAI,UAAU,KAAK,KAAK;AAExB,MAAI,QAAQ,WAAW,KAAK,GAAG;AAC7B,cAAU,QAAQ,QAAQ,oBAAoB,EAAE,EAAE,QAAQ,WAAW,EAAE;AAAA,EACzE;AAEA,QAAM,YAAY,QAAQ,MAAM,aAAa;AAC7C,MAAI,CAAC,WAAW;AACd,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,MAAI;AACF,WAAO,KAAK,MAAM,UAAU,CAAC,CAAC;AAAA,EAChC,SAAS,KAAK;AACZ,UAAM,IAAI;AAAA,MACR,yCAAyC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,yBAC/D,QAAQ,MAAM,GAAG,GAAG,CAAC;AAAA,IACjD;AAAA,EACF;AACF;AAEA,SAAS,cAAc,KAAc,UAA0B;AAC7D,QAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,QAAM,SAAU,KAA6B;AAC7C,QAAM,OAAQ,KAA2B;AAGzC,MAAI,SAAS,kBAAkB,SAAS,eAAe,SAAS,aAAa;AAC3E,WAAO,kCAAkC,QAAQ;AAAA,EACnD;AAGA,MAAI,WAAW,OAAO,IAAI,SAAS,SAAS,KAAK,IAAI,SAAS,KAAK,GAAG;AACpE,WAAO,uBAAuB,QAAQ;AAAA,EACxC;AACA,MAAI,WAAW,KAAK;AAClB,WAAO,oBAAoB,QAAQ;AAAA,EACrC;AAGA,MAAI,WAAW,OAAO,IAAI,SAAS,YAAY,KAAK,IAAI,SAAS,OAAO,GAAG;AACzE,WAAO,mBAAmB,QAAQ;AAAA,EACpC;AAGA,MAAI,WAAW,OAAO,IAAI,SAAS,WAAW,KAAK,IAAI,SAAS,gBAAgB,GAAG;AACjF,WAAO,sBAAsB,QAAQ;AAAA,EACvC;AAGA,MAAI,WAAW,OAAO,WAAW,OAAO,IAAI,SAAS,YAAY,GAAG;AAClE,WAAO,GAAG,QAAQ;AAAA,EACpB;AAGA,MAAI,IAAI,SAAS,OAAO,MAAM,IAAI,SAAS,OAAO,KAAK,IAAI,SAAS,QAAQ,IAAI;AAC9E,WAAO;AAAA,EACT;AAGA,MAAI,IAAI,SAAS,SAAS,KAAK,IAAI,SAAS,SAAS,KAAK,IAAI,SAAS,cAAc,GAAG;AACtF,WAAO,2BAA2B,QAAQ;AAAA,EAC5C;AAGA,SAAO,GAAG,QAAQ,eAAe,GAAG;AACtC;AAEA,eAAe,QAAQ,QAAqB,aAAsC;AAChF,MAAI,OAAO,aAAa,aAAa;AACnC,UAAM,SAAS,IAAIC,WAAU,EAAE,QAAQ,OAAO,QAAQ,CAAC;AACvD,QAAI;AACF,YAAM,WAAW,MAAM,OAAO,SAAS,OAAO;AAAA,QAC5C,OAAO,OAAO;AAAA,QACd,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,UAAU,CAAC,EAAE,MAAM,QAAQ,SAAS,YAAY,CAAC;AAAA,MACnD,CAAC;AACD,YAAM,YAAY,SAAS,QAAQ,KAAK,CAAC,UAAU,MAAM,SAAS,MAAM;AACxE,UAAI,CAAC,aAAa,UAAU,SAAS,QAAQ;AAC3C,cAAM,IAAI,MAAM,oCAAoC;AAAA,MACtD;AACA,aAAO,UAAU;AAAA,IACnB,SAAS,KAAK;AACZ,YAAM,IAAI,MAAM,cAAc,KAAK,WAAW,CAAC;AAAA,IACjD;AAAA,EACF,WAAW,OAAO,aAAa,YAAY,OAAO,aAAa,UAAU;AACvE,UAAM,eAAe,OAAO,aAAa,WAAW,WAAW;AAC/D,UAAM,gBAAsD,EAAE,QAAQ,OAAO,QAAQ;AACrF,QAAI,OAAO,aAAa,UAAU;AAChC,oBAAc,UAAU;AAAA,IAC1B;AACA,UAAM,SAAS,IAAIC,QAAO,aAAa;AACvC,QAAI;AACF,YAAM,WAAW,MAAM,OAAO,KAAK,YAAY,OAAO;AAAA,QACpD,OAAO,OAAO;AAAA,QACd,YAAY;AAAA,QACZ,UAAU;AAAA,UACR,EAAE,MAAM,UAAU,SAAS,cAAc;AAAA,UACzC,EAAE,MAAM,QAAQ,SAAS,YAAY;AAAA,QACvC;AAAA,MACF,CAAC;AACD,YAAM,OAAO,SAAS,QAAQ,CAAC,GAAG,SAAS;AAC3C,UAAI,CAAC,MAAM;AACT,cAAM,IAAI,MAAM,oCAAoC;AAAA,MACtD;AACA,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,YAAM,IAAI,MAAM,cAAc,KAAK,YAAY,CAAC;AAAA,IAClD;AAAA,EACF;AACA,QAAM,IAAI,MAAM,yBAAyB,OAAO,QAAQ,sCAAsC;AAChG;AAEA,eAAsB,QACpB,QACA,YAC0B;AAC1B,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AAEA,eAAa,0BAA0B;AACvC,QAAM,WAAW,MAAM,aAAa;AAEpC,eAAa,kBAAkB,OAAO,QAAQ,KAAK,OAAO,KAAK,MAAM;AACrE,QAAM,cAAc,iBAAiB,QAAQ,QAAQ;AACrD,QAAM,eAAe,MAAM,QAAQ,QAAQ,WAAW;AAEtD,eAAa,6BAA6B;AAC1C,QAAM,SAAS,kBAAkB,YAAY;AAE7C,QAAM,OAAwB;AAAA,IAC5B,IAAI,OAAO,OAAO,WAAW,CAAC;AAAA,IAC9B;AAAA,IACA,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,IACnC,GAAG;AAAA,EACL;AAGA,QAAM,WAAW;AACjB,QAAM,UAAUH,MAAK,KAAK,WAAW,GAAG,GAAG,KAAK,EAAE,OAAO;AACzD,QAAMC,IAAG,UAAU,SAAS,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG,OAAO;AAElE,SAAO;AACT;;;AE5LA,OAAOG,SAAQ;AACf,OAAOC,WAAU;AAGjB,eAAe,UAAU,UAAkB,SAAgC;AACzE,QAAMD,IAAG,MAAMC,MAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAC1D,QAAMD,IAAG,UAAU,UAAU,SAAS,OAAO;AAC/C;AAEA,eAAsB,iBACpB,MACA,WACmB;AACnB,QAAM,YAAYC,MAAK,KAAK,WAAW,SAAS;AAChD,QAAM,UAAoB,CAAC;AAG3B,MAAI,KAAK,QAAQ,WAAW;AAC1B,UAAM,IAAIA,MAAK,KAAK,WAAW,WAAW;AAC1C,UAAM,UAAU,GAAG,KAAK,QAAQ,SAAS;AACzC,YAAQ,KAAK,mBAAmB;AAAA,EAClC;AAGA,MAAI,KAAK,QAAQ,YAAY,OAAO,KAAK,KAAK,QAAQ,QAAQ,EAAE,SAAS,GAAG;AAC1E,UAAM,IAAIA,MAAK,KAAK,WAAW,eAAe;AAC9C,UAAM,UAAU,GAAG,KAAK,UAAU,KAAK,QAAQ,UAAU,MAAM,CAAC,CAAC;AACjE,YAAQ,KAAK,uBAAuB;AAAA,EACtC;AAGA,MACE,KAAK,QAAQ,cACb,OAAO,KAAK,KAAK,QAAQ,UAAU,EAAE,SAAS,GAC9C;AACA,UAAM,IAAIA,MAAK,KAAK,WAAW,WAAW;AAC1C,UAAM,aAAa,EAAE,YAAY,KAAK,QAAQ,WAAW;AACzD,UAAM,UAAU,GAAG,KAAK,UAAU,YAAY,MAAM,CAAC,CAAC;AACtD,YAAQ,KAAK,WAAW;AAAA,EAC1B;AAGA,MAAI,KAAK,QAAQ,UAAU;AACzB,eAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,QAAQ,GAAG;AACnE,YAAM,IAAIA,MAAK,KAAK,WAAW,YAAY,GAAG,IAAI,KAAK;AACvD,YAAM,UAAU,GAAG,OAAO;AAC1B,cAAQ,KAAK,oBAAoB,IAAI,KAAK;AAAA,IAC5C;AAAA,EACF;AAGA,MAAI,KAAK,QAAQ,OAAO;AACtB,eAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,KAAK,GAAG;AAChE,YAAM,IAAIA,MAAK,KAAK,WAAW,SAAS,GAAG,IAAI,KAAK;AACpD,YAAM,UAAU,GAAG,OAAO;AAC1B,cAAQ,KAAK,iBAAiB,IAAI,KAAK;AAAA,IACzC;AAAA,EACF;AAGA,MAAI,KAAK,QAAQ,QAAQ;AACvB,eAAW,CAAC,WAAW,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,MAAM,GAAG;AACtE,YAAM,IAAIA,MAAK,KAAK,WAAW,UAAU,GAAG,SAAS,KAAK;AAC1D,YAAM,UAAU,GAAG,OAAO;AAC1B,cAAQ,KAAK,kBAAkB,SAAS,KAAK;AAAA,IAC/C;AAAA,EACF;AAGA,MAAI,KAAK,QAAQ,QAAQ;AACvB,eAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,MAAM,GAAG;AACjE,YAAM,IAAIA,MAAK,KAAK,WAAW,UAAU,GAAG,IAAI,KAAK;AACrD,YAAM,UAAU,GAAG,OAAO;AAC1B,cAAQ,KAAK,kBAAkB,IAAI,KAAK;AAAA,IAC1C;AAAA,EACF;AAGA,MAAI,KAAK,QAAQ,MAAM;AACrB,eAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,IAAI,GAAG;AAC/D,YAAM,IAAIA,MAAK,KAAK,WAAW,QAAQ,GAAG,IAAI,KAAK;AACnD,YAAM,UAAU,GAAG,OAAO;AAC1B,cAAQ,KAAK,gBAAgB,IAAI,KAAK;AAAA,IACxC;AAAA,EACF;AAEA,SAAO;AACT;AASO,SAAS,cACd,MACA,UASA;AACA,QAAM,iBAA2B,CAAC;AAClC,QAAM,WAA2B,CAAC;AAElC,aAAW,YAAY,KAAK,OAAO;AACjC,UAAM,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,SAAS,OAAO;AAC3D,QAAI,CAAC,KAAM;AAEX,QAAI,KAAK,QAAQ,gBAAgB;AAC/B,qBAAe,KAAK,KAAK,QAAQ,cAAc;AAAA,IACjD;AAEA,QAAI,KAAK,UAAU;AACjB,iBAAW,MAAM,KAAK,UAAU;AAC9B,iBAAS,KAAK;AAAA,UACZ,UAAU,KAAK;AAAA,UACf,QAAQ,GAAG;AAAA,UACX,aAAa,GAAG;AAAA,UAChB,WAAW,KAAK;AAAA,QAClB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,WAAW,KAAK,MAAM;AAAA,IACtB,cAAc,OAAO,KAAK,KAAK,QAAQ,YAAY,CAAC,CAAC,EAAE;AAAA,IACvD,WAAW,OAAO,KAAK,KAAK,QAAQ,SAAS,CAAC,CAAC,EAAE;AAAA,IACjD,YAAY,OAAO,KAAK,KAAK,QAAQ,UAAU,CAAC,CAAC,EAAE;AAAA,IACnD,YAAY,OAAO,KAAK,KAAK,QAAQ,UAAU,CAAC,CAAC,EAAE;AAAA,IACnD;AAAA,IACA;AAAA,EACF;AACF;;;AHpIA,SAAS,iBAAAC,sBAAqB;AAG9B,eAAeC,gBAAwC;AACrD,QAAM,aAAaD,eAAc,YAAY,GAAG;AAChD,QAAM,YAAYE,MAAK,QAAQ,UAAU;AACzC,QAAM,aAAa;AAAA,IACjBA,MAAK,QAAQ,WAAW,wBAAwB;AAAA,IAChDA,MAAK,QAAQ,WAAW,4BAA4B;AAAA,IACpDA,MAAK,QAAQ,WAAW,+BAA+B;AAAA,EACzD;AACA,aAAW,aAAa,YAAY;AAClC,QAAI;AACF,YAAM,OAAO,MAAMC,IAAG,SAAS,WAAW,OAAO;AACjD,aAAO,KAAK,MAAM,IAAI;AAAA,IACxB,QAAQ;AACN;AAAA,IACF;AAAA,EACF;AACA,QAAM,IAAI,MAAM,oCAAoC;AACtD;AAEO,IAAM,kBAAkB,IAAIC,SAAQ,UAAU,EAClD,YAAY,+DAA+D,EAC3E,SAAS,YAAY,gCAAgC,EACrD,OAAO,aAAa,0BAA0B,EAC9C,OAAO,OAAO,WAA+B,YAA+B;AAE3E,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,QAAQ;AACX,YAAQ;AAAA,MACNC,OAAM,IAAI,2BAA2B,IACnCA,OAAM,KAAK,YAAY,IACvBA,OAAM,IAAI,WAAW;AAAA,IACzB;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,SACJ,aACC,MAAM,MAAM;AAAA,IACX,SAAS;AAAA,EACX,CAAC;AAEH,MAAI,CAAC,OAAO,KAAK,GAAG;AAClB,YAAQ,IAAIA,OAAM,IAAI,0CAA0C,CAAC;AACjE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,UAAQ,IAAI,EAAE;AACd,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,QAAQ,QAAQ,CAAC,QAAQ;AACpC,cAAQ,OAAO,MAAM,OAAOA,OAAM,IAAI,GAAG,CAAC,sBAAsB;AAAA,IAClE,CAAC;AACD,YAAQ,OAAO,MAAM,oDAAoD;AAAA,EAC3E,SAAS,KAAK;AACZ,YAAQ,OAAO,MAAM,oDAAoD;AACzE,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,YAAQ,IAAIA,OAAM,IAAI;AAAA,wBAA2B,GAAG;AAAA,CAAI,CAAC;AACzD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,WAAW,MAAMJ,cAAa;AACpC,QAAM,UAAU,cAAc,MAAM,QAAQ;AAE5C,UAAQ,IAAII,OAAM,MAAM,mCAA8B,CAAC;AACvD,UAAQ,IAAIA,OAAM,KAAK,UAAU,IAAI,KAAK,IAAI;AAC9C,UAAQ,IAAIA,OAAM,KAAK,iBAAiB,IAAI,KAAK,WAAW;AAC5D,UAAQ,IAAIA,OAAM,KAAK,WAAW,IAAI,QAAQ,SAAS;AACvD,UAAQ,IAAIA,OAAM,KAAK,cAAc,IAAI,QAAQ,YAAY;AAC7D,UAAQ,IAAIA,OAAM,KAAK,WAAW,IAAI,QAAQ,SAAS;AACvD,UAAQ,IAAIA,OAAM,KAAK,YAAY,IAAI,QAAQ,UAAU;AACzD,UAAQ,IAAIA,OAAM,KAAK,YAAY,IAAI,QAAQ,UAAU;AAEzD,MAAI,KAAK,MAAM,SAAS,GAAG;AACzB,YAAQ,IAAIA,OAAM,IAAI,qBAAqB,CAAC;AAC5C,eAAW,QAAQ,KAAK,OAAO;AAC7B,YAAM,UAAU,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO;AAC1D,YAAM,OAAO,SAAS,QAAQ,KAAK;AACnC,cAAQ,IAAIA,OAAM,IAAI,SAAS,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;AAAA,IACxD;AAAA,EACF;AAEA,MAAI,QAAQ,eAAe,SAAS,GAAG;AACrC,YAAQ,IAAIA,OAAM,OAAO,kCAAkC,CAAC;AAC5D,eAAW,OAAO,QAAQ,gBAAgB;AACxC,cAAQ,IAAIA,OAAM,OAAO,OAAO,GAAG,EAAE,CAAC;AAAA,IACxC;AAAA,EACF;AAGA,UAAQ,IAAI,EAAE;AACd,QAAM,UAAU,QAAQ,OAAO,MAAM,QAAQ;AAAA,IAC3C,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AAED,MAAI,CAAC,SAAS;AACZ,YAAQ,IAAIA,OAAM,IAAI,oDAAoD,CAAC;AAC3E;AAAA,EACF;AAGA,QAAM,YAAY,QAAQ,IAAI;AAC9B,QAAM,UAAU,MAAM,iBAAiB,MAAM,SAAS;AAEtD,UAAQ,IAAIA,OAAM,MAAM,kCAA6B,CAAC;AACtD,aAAW,QAAQ,SAAS;AAC1B,YAAQ,IAAIA,OAAM,IAAI,OAAO,IAAI,EAAE,CAAC;AAAA,EACtC;AAEA,MAAI,QAAQ,SAAS,SAAS,GAAG;AAC/B,YAAQ,IAAIA,OAAM,OAAO,0DAA0D,CAAC;AACpF,UAAM,OAAO,oBAAI,IAAY;AAC7B,eAAW,OAAO,QAAQ,UAAU;AAClC,UAAI,KAAK,IAAI,IAAI,MAAM,EAAG;AAC1B,WAAK,IAAI,IAAI,MAAM;AACnB,cAAQ,IAAIA,OAAM,KAAK,cAAc,IAAI,MAAM,kBAAkB,CAAC;AAClE,cAAQ,IAAIA,OAAM,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;AACjD,UAAI,IAAI,WAAW;AACjB,gBAAQ,IAAIA,OAAM,IAAI,qBAAqB,IAAI,SAAS,EAAE,CAAC;AAAA,MAC7D;AACA,cAAQ,IAAI,EAAE;AAAA,IAChB;AAAA,EACF;AAEA,MAAI,QAAQ,eAAe,SAAS,GAAG;AACrC,YAAQ,IAAIA,OAAM,OAAO,oDAAoD,CAAC;AAC9E,eAAW,OAAO,QAAQ,gBAAgB;AACxC,cAAQ,IAAIA,OAAM,KAAK,OAAO,GAAG,EAAE,CAAC;AAAA,IACtC;AAAA,EACF;AAEA,UAAQ;AAAA,IACNA,OAAM,KAAK,iBAAiB,IAC1BA,OAAM,KAAK,QAAQ,IACnBA,OAAM,KAAK,cAAc;AAAA,EAC7B;AACF,CAAC;;;AItJH,SAAS,WAAAC,gBAAe;AACxB,OAAOC,YAAW;AAClB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAIV,IAAM,cAAc,IAAIC,SAAQ,MAAM,EAC1C,YAAY,yBAAyB,EACrC,OAAO,YAAY;AAClB,QAAM,UAAU,WAAW;AAE3B,MAAI;AACJ,MAAI;AACF,YAAQ,MAAMC,IAAG,QAAQ,OAAO;AAAA,EAClC,QAAQ;AACN,YAAQ,IAAIC,OAAM,IAAI,+BAA+B,IACnDA,OAAM,KAAK,gBAAgB,IAC3BA,OAAM,IAAI,mBAAmB,CAAC;AAChC;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO,CAAC;AAEzD,MAAI,UAAU,WAAW,GAAG;AAC1B,YAAQ,IAAIA,OAAM,IAAI,+BAA+B,IACnDA,OAAM,KAAK,gBAAgB,IAC3BA,OAAM,IAAI,mBAAmB,CAAC;AAChC;AAAA,EACF;AAEA,UAAQ,IAAIA,OAAM,KAAK,0BAA0B,CAAC;AAElD,aAAW,QAAQ,WAAW;AAC5B,QAAI;AACF,YAAM,OAAO,MAAMD,IAAG,SAASE,MAAK,KAAK,SAAS,IAAI,GAAG,OAAO;AAChE,YAAM,OAAO,KAAK,MAAM,IAAI;AAC5B,YAAM,OAAO,IAAI,KAAK,KAAK,UAAU,EAAE,mBAAmB;AAC1D,YAAM,YAAY,KAAK,OAAO,UAAU;AAExC,cAAQ,IAAID,OAAM,KAAK,KAAK,KAAK,IAAI,EAAE,CAAC;AACxC,cAAQ,IAAIA,OAAM,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;AAChD,cAAQ;AAAA,QACNA,OAAM,IAAI,OAAO,IAAI,SAAM,SAAS,eAAY,KAAK,EAAE,EAAE;AAAA,MAC3D;AACA,cAAQ,IAAI,EAAE;AAAA,IAChB,QAAQ;AAAA,IAER;AAAA,EACF;AACF,CAAC;;;AClDH,SAAS,WAAAE,gBAAe;AACxB,OAAOC,YAAW;AAClB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAKV,IAAM,kBAAkB,IAAIC,SAAQ,UAAU,EAClD,YAAY,wDAAwD,EACpE,SAAS,YAAY,kCAAkC,EACvD,OAAO,OAAO,UAAkB;AAC/B,QAAM,UAAU,WAAW;AAG3B,MAAI;AACJ,MAAI;AACF,YAAQ,MAAMC,IAAG,QAAQ,OAAO;AAAA,EAClC,QAAQ;AACN,YAAQ,IAAIC,OAAM,IAAI,oCAAoC,CAAC;AAC3D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,QAAQ,MAAM;AAAA,IAClB,CAAC,MAAM,MAAM,GAAG,KAAK,WAAW,EAAE,WAAW,KAAK;AAAA,EACpD;AAEA,MAAI,CAAC,OAAO;AACV,YAAQ,IAAIA,OAAM,IAAI;AAAA,iBAAoB,KAAK,cAAc,CAAC;AAC9D,YAAQ,IAAIA,OAAM,IAAI,+CAA+C,CAAC;AACtE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,OAAO,MAAMD,IAAG,SAASE,MAAK,KAAK,SAAS,KAAK,GAAG,OAAO;AACjE,QAAM,OAAO,KAAK,MAAM,IAAI;AAE5B,UAAQ,IAAID,OAAM,KAAK;AAAA,gBAAmB,KAAK,IAAI,EAAE,CAAC;AACtD,UAAQ,IAAIA,OAAM,IAAI,KAAK,KAAK,WAAW;AAAA,CAAI,CAAC;AAEhD,QAAM,YAAY,QAAQ,IAAI;AAC9B,QAAM,UAAU,MAAM,iBAAiB,MAAM,SAAS;AAEtD,UAAQ,IAAIA,OAAM,MAAM,gCAA2B,CAAC;AACpD,aAAW,QAAQ,SAAS;AAC1B,YAAQ,IAAIA,OAAM,IAAI,OAAO,IAAI,EAAE,CAAC;AAAA,EACtC;AAEA,UAAQ;AAAA,IACNA,OAAM,KAAK,iBAAiB,IAC1BA,OAAM,KAAK,QAAQ,IACnBA,OAAM,KAAK,cAAc;AAAA,EAC7B;AACF,CAAC;;;ACpDH,SAAS,WAAAE,gBAAe;AACxB,OAAOC,YAAW;AAClB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,iBAAAC,sBAAqB;AAE9B,IAAM,eACJ;AAEF,eAAe,uBAAwC;AACrD,QAAM,aAAaA,eAAc,YAAY,GAAG;AAChD,QAAM,YAAYD,MAAK,QAAQ,UAAU;AACzC,QAAM,aAAa;AAAA,IACjBA,MAAK,QAAQ,WAAW,wBAAwB;AAAA,IAChDA,MAAK,QAAQ,WAAW,4BAA4B;AAAA,IACpDA,MAAK,QAAQ,WAAW,+BAA+B;AAAA,EACzD;AACA,aAAW,aAAa,YAAY;AAClC,QAAI;AACF,YAAMD,IAAG,OAAO,SAAS;AACzB,aAAO;AAAA,IACT,QAAQ;AACN;AAAA,IACF;AAAA,EACF;AACA,QAAM,IAAI,MAAM,0CAA0C;AAC5D;AAEO,IAAM,wBAAwB,IAAIF,SAAQ,iBAAiB,EAC/D,YAAY,4CAA4C,EACxD,OAAO,eAAe,qBAAqB,EAC3C,OAAO,OAAO,YAA8B;AAC3C,QAAM,MAAM,QAAQ,OAAO;AAE3B,UAAQ,IAAIC,OAAM,IAAI;AAAA,2BAA8B,GAAG,KAAK,CAAC;AAE7D,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,GAAG;AAEhC,QAAI,CAAC,SAAS,IAAI;AAChB,cAAQ;AAAA,QACNA,OAAM,IAAI,+BAA+B,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,MACnF;AACA,cAAQ;AAAA,QACNA,OAAM,IAAI,iDAAiD;AAAA,MAC7D;AACA,cAAQ;AAAA,QACNA,OAAM,IAAI,0CAA0C;AAAA,MACtD;AACA;AAAA,IACF;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AAGjC,QAAI;AACJ,QAAI;AACF,cAAQ,KAAK,MAAM,IAAI;AACvB,UAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,OAAM,IAAI,MAAM,cAAc;AACzD,UAAI,MAAM,WAAW,EAAG,OAAM,IAAI,MAAM,gBAAgB;AAAA,IAC1D,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,cAAQ,IAAIA,OAAM,IAAI,8BAA8B,GAAG;AAAA,CAAI,CAAC;AAC5D;AAAA,IACF;AAEA,UAAM,eAAe,MAAM,qBAAqB;AAGhD,UAAM,aAAa,eAAe;AAClC,QAAI;AACF,YAAMC,IAAG,SAAS,cAAc,UAAU;AAAA,IAC5C,QAAQ;AAAA,IAER;AAEA,UAAMA,IAAG,UAAU,cAAc,KAAK,UAAU,OAAO,MAAM,CAAC,GAAG,OAAO;AAExE,YAAQ,IAAID,OAAM,MAAM,8BAAyB,MAAM,MAAM,QAAQ,CAAC;AACtE,YAAQ,IAAIA,OAAM,IAAI,eAAe,YAAY,EAAE,CAAC;AACpD,YAAQ,IAAIA,OAAM,IAAI,aAAa,UAAU;AAAA,CAAI,CAAC;AAAA,EACpD,SAAS,KAAK;AACZ,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,YAAQ,IAAIA,OAAM,IAAI,oBAAoB,GAAG,EAAE,CAAC;AAChD,YAAQ,IAAIA,OAAM,IAAI,0CAA0C,CAAC;AAAA,EACnE;AACF,CAAC;;;ACtFH,SAAS,WAAAI,gBAAe;AACxB,SAAgB,WAAAC,gBAAyB;AACzC,OAAOC,YAAW;AAClB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,iBAAAC,sBAAqB;;;ACL9B,OAAOC,SAAQ;AACf,OAAOC,WAAU;AA+CjB,eAAe,WAAW,GAA6B;AACrD,MAAI;AACF,UAAMD,IAAG,OAAO,CAAC;AACjB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,aAAa,GAAoD;AAC9E,MAAI;AACF,UAAM,OAAO,MAAMA,IAAG,SAAS,GAAG,OAAO;AACzC,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,aAAa,GAAmC;AAC7D,MAAI;AACF,WAAO,MAAMA,IAAG,SAAS,GAAG,OAAO;AAAA,EACrC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,YAAY,GAA8B;AACvD,MAAI;AACF,UAAM,UAAU,MAAMA,IAAG,QAAQ,CAAC;AAClC,WAAO,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC;AAAA,EACjD,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,SAAS,gBAAgB,MAA+B;AACtD,QAAM,aAAmC;AAAA,IACvC,CAAC,CAAC,MAAM,GAAG,SAAS;AAAA,IACpB,CAAC,CAAC,MAAM,GAAG,MAAM;AAAA,IACjB,CAAC,CAAC,mBAAmB,kBAAkB,GAAG,OAAO;AAAA,IACjD,CAAC,CAAC,UAAU,eAAe,GAAG,WAAW;AAAA,IACzC,CAAC,CAAC,SAAS,GAAG,SAAS;AAAA,IACvB,CAAC,CAAC,SAAS,GAAG,SAAS;AAAA,IACvB,CAAC,CAAC,MAAM,GAAG,MAAM;AAAA,IACjB,CAAC,CAAC,SAAS,WAAW,GAAG,OAAO;AAAA,IAChC,CAAC,CAAC,KAAK,GAAG,KAAK;AAAA,IACf,CAAC,CAAC,SAAS,GAAG,SAAS;AAAA,IACvB,CAAC,CAAC,QAAQ,GAAG,QAAQ;AAAA,IACrB,CAAC,CAAC,OAAO,GAAG,OAAO;AAAA,IACnB,CAAC,CAAC,SAAS,GAAG,SAAS;AAAA,IACvB,CAAC,CAAC,uBAAuB,GAAG,UAAU;AAAA,IACtC,CAAC,CAAC,UAAU,gBAAgB,GAAG,QAAQ;AAAA,IACvC,CAAC,CAAC,aAAa,GAAG,SAAS;AAAA,IAC3B,CAAC,CAAC,aAAa,GAAG,cAAc;AAAA,EAClC;AAEA,QAAM,WAAqB,CAAC;AAC5B,aAAW,CAAC,UAAU,IAAI,KAAK,YAAY;AACzC,QAAI,SAAS,KAAK,CAAC,QAAQ,KAAK,SAAS,GAAG,CAAC,GAAG;AAC9C,eAAS,KAAK,IAAI;AAAA,IACpB;AAAA,EACF;AACA,SAAO,SAAS,SAAS,IAAI,SAAS,KAAK,KAAK,IAAI;AACtD;AAEA,SAAS,eAAe,KAAa,UAAmC;AACtE,MAAI,SAAS,KAAK,CAAC,MAAM,MAAM,eAAe,EAAG,QAAO;AACxD,MAAI,SAAS,KAAK,CAAC,MAAM,MAAM,cAAc,EAAG,QAAO;AACvD,MAAI,SAAS,KAAK,CAAC,MAAM,MAAM,oBAAoB,MAAM,cAAc,MAAM,kBAAkB,EAAG,QAAO;AACzG,MAAI,SAAS,KAAK,CAAC,MAAM,MAAM,YAAY,EAAG,QAAO;AACrD,MAAI,SAAS,KAAK,CAAC,MAAM,MAAM,QAAQ,EAAG,QAAO;AACjD,MAAI,SAAS,KAAK,CAAC,MAAM,MAAM,SAAS,EAAG,QAAO;AAClD,SAAO;AACT;AAEA,SAAS,eAAe,SAA2B;AACjD,QAAM,OAAiB,CAAC;AACxB,aAAW,QAAQ,QAAQ,MAAM,IAAI,GAAG;AACtC,UAAM,QAAQ,KAAK,MAAM,qBAAqB;AAC9C,QAAI,MAAO,MAAK,KAAK,MAAM,CAAC,CAAC;AAAA,EAC/B;AACA,SAAO;AACT;AAEA,eAAsB,YAAY,KAAsC;AAEtE,QAAM,MAAM,MAAM,aAAaC,MAAK,KAAK,KAAK,cAAc,CAAC;AAC7D,QAAM,OAAO,KAAK,eAAe,OAAO,KAAK,IAAI,YAAsC,IAAI,CAAC;AAC5F,QAAM,UAAU,KAAK,kBAAkB,OAAO,KAAK,IAAI,eAAyC,IAAI,CAAC;AACrG,QAAM,UAAU,CAAC,GAAG,MAAM,GAAG,OAAO;AACpC,QAAM,UAAW,KAAK,WAAW,CAAC;AAGlC,QAAM,YAAY,MAAM,YAAY,GAAG;AACvC,QAAM,WAAW,UAAU;AAAA,IAAO,CAAC,MACjC;AAAA,MACE;AAAA,MAAgB;AAAA,MAAiB;AAAA,MAAkB;AAAA,MACnD;AAAA,MAAoB;AAAA,MAAc;AAAA,MAAU;AAAA,MAC5C;AAAA,MAAsB;AAAA,MAAc;AAAA,MAAgB;AAAA,MACpD;AAAA,MAAa;AAAA,IACf,EAAE,SAAS,CAAC;AAAA,EACd;AAGA,QAAM,WAAW,eAAe,KAAK,QAAQ;AAC7C,QAAM,YAAY,gBAAgB,OAAO;AACzC,QAAM,aAAa,SAAS,SAAS,eAAe,KAAK,QAAQ,SAAS,YAAY;AAGtF,QAAM,cAAc,QAAQ,QAAQ,QAAQ,SAAS,8CACjD,QAAQ,OAAO;AACnB,QAAM,WAAW,gBAAgB,QAC/B,MAAM,WAAWA,MAAK,KAAK,KAAK,OAAO,CAAC,KACxC,MAAM,WAAWA,MAAK,KAAK,KAAK,WAAW,CAAC,KAC5C,MAAM,WAAWA,MAAK,KAAK,KAAK,MAAM,CAAC;AAGzC,QAAM,eAAe,QAAQ,SAAS;AACtC,QAAM,cAAc,QAAQ,QAAQ;AAGpC,QAAM,SAAS,MAAM,WAAWA,MAAK,KAAK,KAAK,KAAK,CAAC;AACrD,QAAM,YAAY,MAAM,WAAWA,MAAK,KAAK,KAAK,oBAAoB,CAAC,KACrE,MAAM,WAAWA,MAAK,KAAK,KAAK,YAAY,CAAC;AAC/C,QAAM,QAAQ,MAAM,WAAWA,MAAK,KAAK,KAAK,mBAAmB,CAAC;AAGlE,QAAM,aAAa,MAAM,WAAWA,MAAK,KAAK,KAAK,MAAM,CAAC,KACxD,MAAM,WAAWA,MAAK,KAAK,KAAK,cAAc,CAAC;AACjD,MAAI,UAAoB,CAAC;AACzB,QAAM,aAAa,MAAM,aAAaA,MAAK,KAAK,KAAK,cAAc,CAAC;AACpE,MAAI,YAAY;AACd,cAAU,eAAe,UAAU;AAAA,EACrC;AAGA,QAAM,YAAYA,MAAK,KAAK,KAAK,SAAS;AAC1C,QAAM,eAAe,MAAM,WAAW,SAAS;AAC/C,MAAI,mBAAkC;AACtC,MAAI,mBAAmD;AACvD,MAAI,oBAAoD;AACxD,MAAI,mBAA6B,CAAC;AAClC,MAAI,gBAA0B,CAAC;AAC/B,MAAI,iBAA2B,CAAC;AAChC,MAAI,iBAA2B,CAAC;AAChC,MAAI,iBAAiB;AACrB,MAAI,oBAAoB;AAExB,MAAI,cAAc;AAChB,uBAAmB,MAAM,aAAaA,MAAK,KAAK,WAAW,WAAW,CAAC;AACvE,QAAI,kBAAkB;AACpB,0BAAoB,iBAAiB,MAAM,IAAI,EAAE;AAAA,IACnD;AAEA,uBAAmB,MAAM,aAAaA,MAAK,KAAK,WAAW,eAAe,CAAC;AAC3E,wBAAoB,MAAM,aAAaA,MAAK,KAAK,KAAK,WAAW,CAAC;AAClE,QAAI,mBAAmB,YAAY;AACjC,uBAAiB,OAAO,KAAK,kBAAkB,UAAqC,EAAE;AAAA,IACxF;AAEA,wBAAoB,MAAM,YAAYA,MAAK,KAAK,WAAW,UAAU,CAAC,GACnE,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC,EAC/B,IAAI,CAAC,MAAM,EAAE,QAAQ,OAAO,EAAE,CAAC;AAClC,qBAAiB,MAAM,YAAYA,MAAK,KAAK,WAAW,OAAO,CAAC,GAC7D,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC,EAC/B,IAAI,CAAC,MAAM,EAAE,QAAQ,OAAO,EAAE,CAAC;AAClC,qBAAiB,MAAM,YAAYA,MAAK,KAAK,WAAW,QAAQ,CAAC;AACjE,sBAAkB,MAAM,YAAYA,MAAK,KAAK,WAAW,QAAQ,CAAC,GAC/D,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC,EAC/B,IAAI,CAAC,MAAM,EAAE,QAAQ,OAAO,EAAE,CAAC;AAAA,EACpC;AAGA,QAAM,OAAQ,KAAK,QAAmBA,MAAK,SAAS,GAAG;AACvD,QAAM,cAAe,KAAK,eAA0B;AAEpD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ADlPA,eAAeC,gBAAwC;AACrD,QAAM,aAAaC,eAAc,YAAY,GAAG;AAChD,QAAM,YAAYC,MAAK,QAAQ,UAAU;AACzC,QAAM,aAAa;AAAA,IACjBA,MAAK,QAAQ,WAAW,wBAAwB;AAAA,IAChDA,MAAK,QAAQ,WAAW,4BAA4B;AAAA,IACpDA,MAAK,QAAQ,WAAW,+BAA+B;AAAA,EACzD;AACA,aAAW,aAAa,YAAY;AAClC,QAAI;AACF,YAAM,OAAO,MAAMC,IAAG,SAAS,WAAW,OAAO;AACjD,aAAO,KAAK,MAAM,IAAI;AAAA,IACxB,QAAQ;AACN;AAAA,IACF;AAAA,EACF;AACA,QAAM,IAAI,MAAM,oCAAoC;AACtD;AAEA,SAAS,oBAAoB,SAAiC;AAC5D,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,YAAY,QAAQ,IAAI,EAAE;AACrC,MAAI,QAAQ,YAAa,OAAM,KAAK,gBAAgB,QAAQ,WAAW,EAAE;AACzE,MAAI,QAAQ,SAAU,OAAM,KAAK,aAAa,QAAQ,QAAQ,EAAE;AAChE,MAAI,QAAQ,UAAW,OAAM,KAAK,cAAc,QAAQ,SAAS,EAAE;AACnE,MAAI,QAAQ,aAAa,SAAS,GAAG;AACnC,UAAM,KAAK,iBAAiB,QAAQ,aAAa,KAAK,IAAI,CAAC,EAAE;AAAA,EAC/D;AACA,MAAI,QAAQ,YAAa,OAAM,KAAK,iBAAiB,QAAQ,WAAW,EAAE;AAC1E,MAAI,QAAQ,aAAc,OAAM,KAAK,kBAAkB,QAAQ,YAAY,EAAE;AAC7E,MAAI,QAAQ,YAAa,OAAM,KAAK,iBAAiB,QAAQ,WAAW,EAAE;AAC1E,MAAI,QAAQ,UAAW,OAAM,KAAK,0BAA0B;AAC5D,MAAI,QAAQ,MAAO,OAAM,KAAK,4BAA4B;AAC1D,MAAI,QAAQ,QAAQ,SAAS,GAAG;AAC9B,UAAM,KAAK,oBAAoB,QAAQ,QAAQ,KAAK,IAAI,CAAC,EAAE;AAAA,EAC7D;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,kBAAkB,SAAiC;AAC1D,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK;AAAA,iCAAoC;AAC/C,QAAM,KAAK,gBAAgB,QAAQ,iBAAiB,SAAS,QAAQ,oBAAoB,MAAM,oDAA0C,EAAE,EAAE;AAC7I,QAAM,KAAK,kBAAkB,QAAQ,cAAc,EAAE;AACrD,QAAM,KAAK,eAAe,QAAQ,iBAAiB,SAAS,IAAI,QAAQ,iBAAiB,IAAI,OAAK,YAAY,CAAC,EAAE,EAAE,KAAK,IAAI,IAAI,MAAM,EAAE;AACxI,QAAM,KAAK,YAAY,QAAQ,cAAc,SAAS,IAAI,QAAQ,cAAc,KAAK,IAAI,IAAI,MAAM,EAAE;AACrG,QAAM,KAAK,aAAa,QAAQ,eAAe,SAAS,IAAI,QAAQ,eAAe,KAAK,IAAI,IAAI,MAAM,EAAE;AACxG,QAAM,KAAK,aAAa,QAAQ,eAAe,SAAS,IAAI,QAAQ,eAAe,KAAK,IAAI,IAAI,MAAM,EAAE;AACxG,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,oBAAoB,SAAiC;AAC5D,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,qDAAqD;AAChE,QAAM,KAAK,oBAAoB,OAAO,CAAC;AAEvC,MAAI,QAAQ,cAAc;AACxB,UAAM,KAAK,kBAAkB,OAAO,CAAC;AAErC,QAAI,QAAQ,kBAAkB;AAC5B,YAAM,KAAK;AAAA;AAAA;AAAA,EAAsC,QAAQ,gBAAgB,EAAE;AAAA,IAC7E;AAEA,UAAM,KAAK;AAAA;AAAA,CAAa;AACxB,UAAM,KAAK,kFAAkF;AAC7F,UAAM,KAAK,iFAAiF;AAC5F,UAAM,KAAK,gCAAgC;AAC3C,UAAM,KAAK,wEAAwE;AACnF,UAAM,KAAK,8DAA8D;AACzE,UAAM,KAAK,uEAAuE;AAClF,UAAM,KAAK,+BAA+B;AAC1C,UAAM,KAAK,kDAAkD;AAC7D,UAAM,KAAK,2DAA2D;AACtE,QAAI,QAAQ,oBAAoB,KAAK;AACnC,YAAM,KAAK,kBAAkB,QAAQ,iBAAiB,yCAAoC;AAAA,IAC5F;AACA,QAAI,CAAC,QAAQ,iBAAiB,SAAS,MAAM,GAAG;AAC9C,YAAM,KAAK,iCAAiC;AAAA,IAC9C;AACA,QAAI,CAAC,QAAQ,cAAc,SAAS,UAAU,GAAG;AAC/C,YAAM,KAAK,0BAA0B;AAAA,IACvC;AAAA,EACF,OAAO;AACL,UAAM,KAAK;AAAA;AAAA,CAAa;AACxB,UAAM,KAAK,wEAAwE;AACnF,UAAM,KAAK,oFAA+E;AAC1F,UAAM,KAAK,kFAAkF;AAAA,EAC/F;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,IAAM,kBAAkB,IAAIC,SAAQ,UAAU,EAClD,YAAY,+EAA+E,EAC3F,OAAO,aAAa,2BAA2B,EAC/C,OAAO,gBAAgB,yDAAyD,EAChF,OAAO,OAAO,YAAoD;AACjE,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,QAAQ;AACX,YAAQ;AAAA,MACNC,OAAM,IAAI,2BAA2B,IACnCA,OAAM,KAAK,YAAY,IACvBA,OAAM,IAAI,WAAW;AAAA,IACzB;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,YAAY,QAAQ,IAAI;AAG9B,UAAQ,IAAIA,OAAM,IAAI,yBAAyB,CAAC;AAChD,QAAM,UAAU,MAAM,YAAY,SAAS;AAG3C,UAAQ,IAAIA,OAAM,KAAK,uBAAuB,CAAC;AAC/C,MAAI,QAAQ,SAAU,SAAQ,IAAIA,OAAM,IAAI,iBAAiB,QAAQ,QAAQ,EAAE,CAAC;AAChF,MAAI,QAAQ,UAAW,SAAQ,IAAIA,OAAM,IAAI,iBAAiB,QAAQ,SAAS,EAAE,CAAC;AAClF,UAAQ,IAAIA,OAAM,IAAI,mBAAmB,QAAQ,aAAa,MAAM,EAAE,CAAC;AACvE,MAAI,QAAQ,YAAa,SAAQ,IAAIA,OAAM,IAAI,iBAAiB,QAAQ,WAAW,EAAE,CAAC;AACtF,MAAI,QAAQ,aAAc,SAAQ,IAAIA,OAAM,IAAI,iBAAiB,QAAQ,YAAY,EAAE,CAAC;AACxF,MAAI,QAAQ,UAAW,SAAQ,IAAIA,OAAM,IAAI,mBAAmB,CAAC;AACjE,MAAI,QAAQ,MAAO,SAAQ,IAAIA,OAAM,IAAI,mBAAmB,CAAC;AAC7D,MAAI,QAAQ,QAAQ,SAAS,EAAG,SAAQ,IAAIA,OAAM,IAAI,iBAAiB,QAAQ,QAAQ,KAAK,IAAI,CAAC,EAAE,CAAC;AAGpG,MAAI,QAAQ,cAAc;AACxB,YAAQ,IAAIA,OAAM,OAAO,0CAA0C,CAAC;AACpE,YAAQ,IAAIA,OAAM,IAAI,iBAAiB,QAAQ,iBAAiB,SAAS,QAAQ,oBAAoB,MAAMA,OAAM,OAAO,iBAAY,IAAIA,OAAM,MAAM,SAAI,CAAC,EAAE,CAAC;AAC5J,YAAQ,IAAIA,OAAM,IAAI,kBAAkB,QAAQ,cAAc,EAAE,CAAC;AACjE,YAAQ,IAAIA,OAAM,IAAI,iBAAiB,QAAQ,iBAAiB,SAAS,IAAI,QAAQ,iBAAiB,IAAI,OAAK,CAAC,EAAE,KAAK,IAAI,IAAI,MAAM,EAAE,CAAC;AACxI,YAAQ,IAAIA,OAAM,IAAI,iBAAiB,QAAQ,cAAc,SAAS,IAAI,QAAQ,cAAc,KAAK,IAAI,IAAI,MAAM,EAAE,CAAC;AACtH,YAAQ,IAAIA,OAAM,IAAI,iBAAiB,QAAQ,eAAe,SAAS,IAAI,QAAQ,eAAe,KAAK,IAAI,IAAI,MAAM,EAAE,CAAC;AACxH,YAAQ,IAAIA,OAAM,IAAI,iBAAiB,QAAQ,eAAe,SAAS,IAAI,QAAQ,eAAe,KAAK,IAAI,IAAI,MAAM,EAAE,CAAC;AAGxH,UAAM,SAAmB,CAAC;AAC1B,QAAI,QAAQ,oBAAoB,IAAK,QAAO,KAAK,gEAA2D;AAC5G,QAAI,CAAC,QAAQ,iBAAiB,SAAS,MAAM,EAAG,QAAO,KAAK,+BAA+B;AAC3F,QAAI,CAAC,QAAQ,cAAc,SAAS,UAAU,EAAG,QAAO,KAAK,wBAAwB;AACrF,QAAI,CAAC,QAAQ,cAAc,SAAS,YAAY,EAAG,QAAO,KAAK,4CAA4C;AAC3G,QAAI,QAAQ,iBAAiB,EAAG,QAAO,KAAK,GAAG,QAAQ,cAAc,6CAAwC;AAC7G,QAAI,QAAQ,mBAAmB,KAAK,QAAQ,aAAa,SAAS,EAAG,QAAO,KAAK,2BAA2B;AAC5G,QAAI,QAAQ,YAAY,CAAC,QAAQ,iBAAiB,SAAS,MAAM,EAAG,QAAO,KAAK,wCAAwC;AACxH,QAAI,CAAC,QAAQ,iBAAiB,SAAS,OAAO,EAAG,QAAO,KAAK,gCAAgC;AAE7F,QAAI,OAAO,SAAS,GAAG;AACrB,cAAQ,IAAIA,OAAM,OAAO,qBAAqB,CAAC;AAC/C,iBAAW,SAAS,QAAQ;AAC1B,gBAAQ,IAAIA,OAAM,OAAO,cAAS,KAAK,EAAE,CAAC;AAAA,MAC5C;AAAA,IACF,OAAO;AACL,cAAQ,IAAIA,OAAM,MAAM,oCAA+B,CAAC;AAAA,IAC1D;AAEA,QAAI,QAAQ,WAAW;AACrB,cAAQ,IAAIA,OAAM,IAAI,mFAAmF,CAAC;AAC1G;AAAA,IACF;AAGA,QAAI,CAAC,QAAQ,KAAK;AAChB,cAAQ,IAAI,EAAE;AACd,YAAM,UAAU,MAAMC,SAAQ;AAAA,QAC5B,SAAS;AAAA,QACT,SAAS;AAAA,MACX,CAAC;AACD,UAAI,CAAC,SAAS;AACZ,gBAAQ,IAAID,OAAM,IAAI,gBAAgB,CAAC;AACvC;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AACL,YAAQ,IAAIA,OAAM,IAAI,4EAAuE,CAAC;AAE9F,QAAI,CAAC,QAAQ,KAAK;AAChB,YAAM,UAAU,MAAMC,SAAQ;AAAA,QAC5B,SAAS;AAAA,QACT,SAAS;AAAA,MACX,CAAC;AACD,UAAI,CAAC,SAAS;AACZ,gBAAQ,IAAID,OAAM,IAAI,gBAAgB,CAAC;AACvC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,SAAS,oBAAoB,OAAO;AAC1C,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,QAAQ,QAAQ,CAAC,QAAQ;AACpC,cAAQ,OAAO,MAAM,OAAOA,OAAM,IAAI,GAAG,CAAC,sBAAsB;AAAA,IAClE,CAAC;AACD,YAAQ,OAAO,MAAM,oDAAoD;AAAA,EAC3E,SAAS,KAAK;AACZ,YAAQ,OAAO,MAAM,oDAAoD;AACzE,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,YAAQ,IAAIA,OAAM,IAAI;AAAA,yBAA4B,GAAG;AAAA,CAAI,CAAC;AAC1D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,WAAW,MAAML,cAAa;AACpC,QAAM,UAAU,cAAc,MAAM,QAAQ;AAE5C,UAAQ,IAAIK,OAAM,MAAM,iCAA4B,CAAC;AACrD,UAAQ,IAAIA,OAAM,KAAK,UAAU,IAAI,KAAK,IAAI;AAC9C,UAAQ,IAAIA,OAAM,KAAK,WAAW,IAAI,QAAQ,SAAS;AACvD,UAAQ,IAAIA,OAAM,KAAK,cAAc,IAAI,QAAQ,YAAY;AAC7D,UAAQ,IAAIA,OAAM,KAAK,WAAW,IAAI,QAAQ,SAAS;AACvD,UAAQ,IAAIA,OAAM,KAAK,YAAY,IAAI,QAAQ,UAAU;AACzD,UAAQ,IAAIA,OAAM,KAAK,YAAY,IAAI,QAAQ,UAAU;AAEzD,MAAI,KAAK,MAAM,SAAS,GAAG;AACzB,YAAQ,IAAIA,OAAM,IAAI,qBAAqB,CAAC;AAC5C,eAAW,QAAQ,KAAK,OAAO;AAC7B,YAAM,UAAU,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO;AAC1D,YAAM,OAAO,SAAS,QAAQ,KAAK;AACnC,cAAQ,IAAIA,OAAM,IAAI,SAAS,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;AAAA,IACxD;AAAA,EACF;AAEA,MAAI,QAAQ,eAAe,SAAS,GAAG;AACrC,YAAQ,IAAIA,OAAM,OAAO,kCAAkC,CAAC;AAC5D,eAAW,OAAO,QAAQ,gBAAgB;AACxC,cAAQ,IAAIA,OAAM,OAAO,OAAO,GAAG,EAAE,CAAC;AAAA,IACxC;AAAA,EACF;AAGA,QAAM,UAAU,MAAM,iBAAiB,MAAM,SAAS;AAEtD,UAAQ,IAAIA,OAAM,MAAM,kCAA6B,CAAC;AACtD,aAAW,QAAQ,SAAS;AAC1B,YAAQ,IAAIA,OAAM,IAAI,OAAO,IAAI,EAAE,CAAC;AAAA,EACtC;AAEA,MAAI,QAAQ,SAAS,SAAS,GAAG;AAC/B,YAAQ,IAAIA,OAAM,OAAO,0DAA0D,CAAC;AACpF,UAAM,OAAO,oBAAI,IAAY;AAC7B,eAAW,OAAO,QAAQ,UAAU;AAClC,UAAI,KAAK,IAAI,IAAI,MAAM,EAAG;AAC1B,WAAK,IAAI,IAAI,MAAM;AACnB,cAAQ,IAAIA,OAAM,KAAK,cAAc,IAAI,MAAM,kBAAkB,CAAC;AAClE,cAAQ,IAAIA,OAAM,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;AACjD,UAAI,IAAI,WAAW;AACjB,gBAAQ,IAAIA,OAAM,IAAI,qBAAqB,IAAI,SAAS,EAAE,CAAC;AAAA,MAC7D;AACA,cAAQ,IAAI,EAAE;AAAA,IAChB;AAAA,EACF;AAEA,MAAI,QAAQ,eAAe,SAAS,GAAG;AACrC,YAAQ,IAAIA,OAAM,OAAO,oDAAoD,CAAC;AAC9E,eAAW,OAAO,QAAQ,gBAAgB;AACxC,cAAQ,IAAIA,OAAM,KAAK,OAAO,GAAG,EAAE,CAAC;AAAA,IACtC;AAAA,EACF;AAEA,UAAQ;AAAA,IACNA,OAAM,KAAK,iBAAiB,IAC1BA,OAAM,KAAK,QAAQ,IACnBA,OAAM,KAAK,cAAc;AAAA,EAC7B;AACF,CAAC;;;AV9QH,IAAM,UAAU,IAAIE,SAAQ;AAE5B,QACG,KAAK,OAAO,EACZ;AAAA,EACC;AACF,EACC,QAAQ,OAAO;AAElB,QAAQ,WAAW,WAAW;AAC9B,QAAQ,WAAW,eAAe;AAClC,QAAQ,WAAW,eAAe;AAClC,QAAQ,WAAW,WAAW;AAC9B,QAAQ,WAAW,eAAe;AAClC,QAAQ,WAAW,qBAAqB;AAExC,QAAQ,MAAM;","names":["Command","Command","chalk","fs","path","fs","path","Anthropic","OpenAI","path","fs","Anthropic","OpenAI","fs","path","fileURLToPath","loadRegistry","path","fs","Command","chalk","Command","chalk","fs","path","Command","fs","chalk","path","Command","chalk","fs","path","Command","fs","chalk","path","Command","chalk","fs","path","fileURLToPath","Command","confirm","chalk","fs","path","fileURLToPath","fs","path","loadRegistry","fileURLToPath","path","fs","Command","chalk","confirm","Command"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kairn-cli",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Compile natural language intent into optimized Claude Code environments",
5
5
  "author": "Ashton Perlroth",
6
6
  "license": "MIT",
@@ -7,12 +7,20 @@
7
7
  "tier": 1,
8
8
  "type": "mcp_server",
9
9
  "auth": "none",
10
- "best_for": ["coding", "library-usage", "documentation", "any"],
10
+ "best_for": [
11
+ "coding",
12
+ "library-usage",
13
+ "documentation",
14
+ "any"
15
+ ],
11
16
  "install": {
12
17
  "mcp_config": {
13
18
  "context7": {
14
19
  "command": "npx",
15
- "args": ["-y", "@upstash/context7-mcp@latest"]
20
+ "args": [
21
+ "-y",
22
+ "@upstash/context7-mcp@latest"
23
+ ]
16
24
  }
17
25
  }
18
26
  }
@@ -25,12 +33,20 @@
25
33
  "tier": 1,
26
34
  "type": "mcp_server",
27
35
  "auth": "none",
28
- "best_for": ["complex-tasks", "architecture", "debugging", "any"],
36
+ "best_for": [
37
+ "complex-tasks",
38
+ "architecture",
39
+ "debugging",
40
+ "any"
41
+ ],
29
42
  "install": {
30
43
  "mcp_config": {
31
44
  "sequential-thinking": {
32
45
  "command": "npx",
33
- "args": ["-y", "@anthropic/mcp-server-sequential-thinking"]
46
+ "args": [
47
+ "-y",
48
+ "@anthropic/mcp-server-sequential-thinking"
49
+ ]
34
50
  }
35
51
  }
36
52
  }
@@ -43,7 +59,11 @@
43
59
  "tier": 1,
44
60
  "type": "plugin",
45
61
  "auth": "none",
46
- "best_for": ["coding", "security", "any"],
62
+ "best_for": [
63
+ "coding",
64
+ "security",
65
+ "any"
66
+ ],
47
67
  "install": {
48
68
  "plugin_command": "/plugin install security-guidance@claude-plugins-official"
49
69
  }
@@ -56,18 +76,33 @@
56
76
  "tier": 2,
57
77
  "type": "mcp_server",
58
78
  "auth": "oauth",
59
- "best_for": ["coding", "collaboration", "open-source", "github"],
79
+ "best_for": [
80
+ "coding",
81
+ "collaboration",
82
+ "open-source",
83
+ "github"
84
+ ],
60
85
  "install": {
61
86
  "mcp_config": {
62
87
  "github": {
63
88
  "command": "npx",
64
- "args": ["-y", "@anthropic/mcp-server-github"],
89
+ "args": [
90
+ "-y",
91
+ "@anthropic/mcp-server-github"
92
+ ],
65
93
  "env": {
66
94
  "GITHUB_TOKEN": "${GITHUB_TOKEN}"
67
95
  }
68
96
  }
69
97
  }
70
- }
98
+ },
99
+ "env_vars": [
100
+ {
101
+ "name": "GITHUB_TOKEN",
102
+ "description": "Personal access token (Settings > Developer settings > Tokens)"
103
+ }
104
+ ],
105
+ "signup_url": "https://github.com/settings/tokens"
71
106
  },
72
107
  {
73
108
  "id": "playwright",
@@ -77,7 +112,12 @@
77
112
  "tier": 2,
78
113
  "type": "plugin",
79
114
  "auth": "none",
80
- "best_for": ["web-dev", "testing", "frontend", "e2e-testing"],
115
+ "best_for": [
116
+ "web-dev",
117
+ "testing",
118
+ "frontend",
119
+ "e2e-testing"
120
+ ],
81
121
  "install": {
82
122
  "plugin_command": "/plugin install playwright@claude-plugins-official"
83
123
  }
@@ -90,18 +130,32 @@
90
130
  "tier": 2,
91
131
  "type": "mcp_server",
92
132
  "auth": "api_key",
93
- "best_for": ["coding", "security", "code-review"],
133
+ "best_for": [
134
+ "coding",
135
+ "security",
136
+ "code-review"
137
+ ],
94
138
  "install": {
95
139
  "mcp_config": {
96
140
  "semgrep": {
97
141
  "command": "npx",
98
- "args": ["-y", "@semgrep/mcp"],
142
+ "args": [
143
+ "-y",
144
+ "@semgrep/mcp"
145
+ ],
99
146
  "env": {
100
147
  "SEMGREP_APP_TOKEN": "${SEMGREP_APP_TOKEN}"
101
148
  }
102
149
  }
103
150
  }
104
- }
151
+ },
152
+ "env_vars": [
153
+ {
154
+ "name": "SEMGREP_APP_TOKEN",
155
+ "description": "Semgrep app token for static analysis"
156
+ }
157
+ ],
158
+ "signup_url": "https://semgrep.dev/login"
105
159
  },
106
160
  {
107
161
  "id": "exa",
@@ -111,18 +165,32 @@
111
165
  "tier": 3,
112
166
  "type": "mcp_server",
113
167
  "auth": "api_key",
114
- "best_for": ["research", "technical-search", "literature-review"],
168
+ "best_for": [
169
+ "research",
170
+ "technical-search",
171
+ "literature-review"
172
+ ],
115
173
  "install": {
116
174
  "mcp_config": {
117
175
  "exa": {
118
176
  "command": "npx",
119
- "args": ["-y", "exa-mcp-server"],
177
+ "args": [
178
+ "-y",
179
+ "exa-mcp-server"
180
+ ],
120
181
  "env": {
121
182
  "EXA_API_KEY": "${EXA_API_KEY}"
122
183
  }
123
184
  }
124
185
  }
125
- }
186
+ },
187
+ "env_vars": [
188
+ {
189
+ "name": "EXA_API_KEY",
190
+ "description": "Exa API key for semantic search"
191
+ }
192
+ ],
193
+ "signup_url": "https://dashboard.exa.ai/api-keys"
126
194
  },
127
195
  {
128
196
  "id": "brave-search",
@@ -132,18 +200,32 @@
132
200
  "tier": 3,
133
201
  "type": "mcp_server",
134
202
  "auth": "api_key",
135
- "best_for": ["research", "general-search", "web-lookup"],
203
+ "best_for": [
204
+ "research",
205
+ "general-search",
206
+ "web-lookup"
207
+ ],
136
208
  "install": {
137
209
  "mcp_config": {
138
210
  "brave-search": {
139
211
  "command": "npx",
140
- "args": ["-y", "@anthropic/mcp-server-brave"],
212
+ "args": [
213
+ "-y",
214
+ "@anthropic/mcp-server-brave"
215
+ ],
141
216
  "env": {
142
217
  "BRAVE_API_KEY": "${BRAVE_API_KEY}"
143
218
  }
144
219
  }
145
220
  }
146
- }
221
+ },
222
+ "env_vars": [
223
+ {
224
+ "name": "BRAVE_API_KEY",
225
+ "description": "Brave Search API key"
226
+ }
227
+ ],
228
+ "signup_url": "https://brave.com/search/api/"
147
229
  },
148
230
  {
149
231
  "id": "firecrawl",
@@ -153,18 +235,32 @@
153
235
  "tier": 3,
154
236
  "type": "mcp_server",
155
237
  "auth": "api_key",
156
- "best_for": ["research", "web-scraping", "content-extraction"],
238
+ "best_for": [
239
+ "research",
240
+ "web-scraping",
241
+ "content-extraction"
242
+ ],
157
243
  "install": {
158
244
  "mcp_config": {
159
245
  "firecrawl": {
160
246
  "command": "npx",
161
- "args": ["-y", "firecrawl-mcp"],
247
+ "args": [
248
+ "-y",
249
+ "firecrawl-mcp"
250
+ ],
162
251
  "env": {
163
252
  "FIRECRAWL_API_KEY": "${FIRECRAWL_API_KEY}"
164
253
  }
165
254
  }
166
255
  }
167
- }
256
+ },
257
+ "env_vars": [
258
+ {
259
+ "name": "FIRECRAWL_API_KEY",
260
+ "description": "Firecrawl API key for web extraction"
261
+ }
262
+ ],
263
+ "signup_url": "https://firecrawl.dev/app/api-keys"
168
264
  },
169
265
  {
170
266
  "id": "perplexity",
@@ -174,18 +270,32 @@
174
270
  "tier": 3,
175
271
  "type": "mcp_server",
176
272
  "auth": "api_key",
177
- "best_for": ["research", "fact-checking", "deep-research"],
273
+ "best_for": [
274
+ "research",
275
+ "fact-checking",
276
+ "deep-research"
277
+ ],
178
278
  "install": {
179
279
  "mcp_config": {
180
280
  "perplexity": {
181
281
  "command": "npx",
182
- "args": ["-y", "@anthropic/mcp-server-perplexity"],
282
+ "args": [
283
+ "-y",
284
+ "@anthropic/mcp-server-perplexity"
285
+ ],
183
286
  "env": {
184
287
  "PERPLEXITY_API_KEY": "${PERPLEXITY_API_KEY}"
185
288
  }
186
289
  }
187
290
  }
188
- }
291
+ },
292
+ "env_vars": [
293
+ {
294
+ "name": "PERPLEXITY_API_KEY",
295
+ "description": "Perplexity API key for AI-powered research"
296
+ }
297
+ ],
298
+ "signup_url": "https://perplexity.ai/settings/api"
189
299
  },
190
300
  {
191
301
  "id": "postgres",
@@ -195,15 +305,31 @@
195
305
  "tier": 4,
196
306
  "type": "mcp_server",
197
307
  "auth": "connection_string",
198
- "best_for": ["database", "data-analysis", "backend", "sql"],
308
+ "best_for": [
309
+ "database",
310
+ "data-analysis",
311
+ "backend",
312
+ "sql"
313
+ ],
199
314
  "install": {
200
315
  "mcp_config": {
201
316
  "postgres": {
202
317
  "command": "npx",
203
- "args": ["-y", "@bytebase/dbhub", "--dsn", "${DATABASE_URL}"]
318
+ "args": [
319
+ "-y",
320
+ "@bytebase/dbhub",
321
+ "--dsn",
322
+ "${DATABASE_URL}"
323
+ ]
204
324
  }
205
325
  }
206
- }
326
+ },
327
+ "env_vars": [
328
+ {
329
+ "name": "DATABASE_URL",
330
+ "description": "PostgreSQL connection string (postgres://user:pass@host:5432/db)"
331
+ }
332
+ ]
207
333
  },
208
334
  {
209
335
  "id": "supabase",
@@ -213,19 +339,38 @@
213
339
  "tier": 4,
214
340
  "type": "mcp_server",
215
341
  "auth": "api_key",
216
- "best_for": ["backend", "database", "auth", "supabase"],
342
+ "best_for": [
343
+ "backend",
344
+ "database",
345
+ "auth",
346
+ "supabase"
347
+ ],
217
348
  "install": {
218
349
  "mcp_config": {
219
350
  "supabase": {
220
351
  "command": "npx",
221
- "args": ["-y", "@supabase/mcp-server"],
352
+ "args": [
353
+ "-y",
354
+ "@supabase/mcp-server"
355
+ ],
222
356
  "env": {
223
357
  "SUPABASE_URL": "${SUPABASE_URL}",
224
358
  "SUPABASE_SERVICE_ROLE_KEY": "${SUPABASE_SERVICE_ROLE_KEY}"
225
359
  }
226
360
  }
227
361
  }
228
- }
362
+ },
363
+ "env_vars": [
364
+ {
365
+ "name": "SUPABASE_URL",
366
+ "description": "Your Supabase project URL"
367
+ },
368
+ {
369
+ "name": "SUPABASE_SERVICE_ROLE_KEY",
370
+ "description": "Service role key (Settings > API)"
371
+ }
372
+ ],
373
+ "signup_url": "https://supabase.com/dashboard"
229
374
  },
230
375
  {
231
376
  "id": "slack",
@@ -235,18 +380,32 @@
235
380
  "tier": 5,
236
381
  "type": "mcp_server",
237
382
  "auth": "oauth",
238
- "best_for": ["communication", "team-collaboration", "outreach"],
383
+ "best_for": [
384
+ "communication",
385
+ "team-collaboration",
386
+ "outreach"
387
+ ],
239
388
  "install": {
240
389
  "mcp_config": {
241
390
  "slack": {
242
391
  "command": "npx",
243
- "args": ["-y", "@anthropic/mcp-server-slack"],
392
+ "args": [
393
+ "-y",
394
+ "@anthropic/mcp-server-slack"
395
+ ],
244
396
  "env": {
245
397
  "SLACK_BOT_TOKEN": "${SLACK_BOT_TOKEN}"
246
398
  }
247
399
  }
248
400
  }
249
- }
401
+ },
402
+ "env_vars": [
403
+ {
404
+ "name": "SLACK_BOT_TOKEN",
405
+ "description": "Slack bot token (xoxb-...)"
406
+ }
407
+ ],
408
+ "signup_url": "https://api.slack.com/apps"
250
409
  },
251
410
  {
252
411
  "id": "notion",
@@ -256,18 +415,32 @@
256
415
  "tier": 5,
257
416
  "type": "mcp_server",
258
417
  "auth": "oauth",
259
- "best_for": ["documentation", "knowledge-base", "project-management"],
418
+ "best_for": [
419
+ "documentation",
420
+ "knowledge-base",
421
+ "project-management"
422
+ ],
260
423
  "install": {
261
424
  "mcp_config": {
262
425
  "notion": {
263
426
  "command": "npx",
264
- "args": ["-y", "@anthropic/mcp-server-notion"],
427
+ "args": [
428
+ "-y",
429
+ "@anthropic/mcp-server-notion"
430
+ ],
265
431
  "env": {
266
432
  "NOTION_API_KEY": "${NOTION_API_KEY}"
267
433
  }
268
434
  }
269
435
  }
270
- }
436
+ },
437
+ "env_vars": [
438
+ {
439
+ "name": "NOTION_API_KEY",
440
+ "description": "Notion integration token"
441
+ }
442
+ ],
443
+ "signup_url": "https://www.notion.so/my-integrations"
271
444
  },
272
445
  {
273
446
  "id": "linear",
@@ -277,18 +450,32 @@
277
450
  "tier": 5,
278
451
  "type": "mcp_server",
279
452
  "auth": "oauth",
280
- "best_for": ["project-management", "issue-tracking", "agile"],
453
+ "best_for": [
454
+ "project-management",
455
+ "issue-tracking",
456
+ "agile"
457
+ ],
281
458
  "install": {
282
459
  "mcp_config": {
283
460
  "linear": {
284
461
  "command": "npx",
285
- "args": ["-y", "@anthropic/mcp-server-linear"],
462
+ "args": [
463
+ "-y",
464
+ "@anthropic/mcp-server-linear"
465
+ ],
286
466
  "env": {
287
467
  "LINEAR_API_KEY": "${LINEAR_API_KEY}"
288
468
  }
289
469
  }
290
470
  }
291
- }
471
+ },
472
+ "env_vars": [
473
+ {
474
+ "name": "LINEAR_API_KEY",
475
+ "description": "Linear API key"
476
+ }
477
+ ],
478
+ "signup_url": "https://linear.app/settings/api"
292
479
  },
293
480
  {
294
481
  "id": "agentmail",
@@ -298,18 +485,33 @@
298
485
  "tier": 5,
299
486
  "type": "mcp_server",
300
487
  "auth": "api_key",
301
- "best_for": ["email", "outreach", "automation", "communication"],
488
+ "best_for": [
489
+ "email",
490
+ "outreach",
491
+ "automation",
492
+ "communication"
493
+ ],
302
494
  "install": {
303
495
  "mcp_config": {
304
496
  "agentmail": {
305
497
  "command": "npx",
306
- "args": ["-y", "@agentmail/mcp-server"],
498
+ "args": [
499
+ "-y",
500
+ "@agentmail/mcp-server"
501
+ ],
307
502
  "env": {
308
503
  "AGENTMAIL_API_KEY": "${AGENTMAIL_API_KEY}"
309
504
  }
310
505
  }
311
506
  }
312
- }
507
+ },
508
+ "env_vars": [
509
+ {
510
+ "name": "AGENTMAIL_API_KEY",
511
+ "description": "AgentMail API key"
512
+ }
513
+ ],
514
+ "signup_url": "https://agentmail.to"
313
515
  },
314
516
  {
315
517
  "id": "figma",
@@ -319,10 +521,21 @@
319
521
  "tier": 6,
320
522
  "type": "plugin",
321
523
  "auth": "api_key",
322
- "best_for": ["design-to-code", "frontend", "ui-development"],
524
+ "best_for": [
525
+ "design-to-code",
526
+ "frontend",
527
+ "ui-development"
528
+ ],
323
529
  "install": {
324
530
  "plugin_command": "/plugin install figma@claude-plugins-official"
325
- }
531
+ },
532
+ "env_vars": [
533
+ {
534
+ "name": "FIGMA_API_KEY",
535
+ "description": "Figma personal access token"
536
+ }
537
+ ],
538
+ "signup_url": "https://www.figma.com/developers/api#access-tokens"
326
539
  },
327
540
  {
328
541
  "id": "frontend-design",
@@ -332,9 +545,14 @@
332
545
  "tier": 6,
333
546
  "type": "plugin",
334
547
  "auth": "none",
335
- "best_for": ["frontend", "ui-development", "web-dev", "design"],
548
+ "best_for": [
549
+ "frontend",
550
+ "ui-development",
551
+ "web-dev",
552
+ "design"
553
+ ],
336
554
  "install": {
337
555
  "plugin_command": "/plugin install frontend-design@claude-plugins-official"
338
556
  }
339
557
  }
340
- ]
558
+ ]