{"version":3,"sources":["../src/templates/claude.ts","../src/templates/cursor.ts","../src/templates/copilot.ts","../src/templates/cline.ts","../src/templates/llms-txt.ts","../src/templates/windsurf.ts","../src/templates/index.ts","../src/lib/detect.ts","../src/lib/monorepo.ts","../src/lib/constants.ts","../src/lib/merge.ts","../src/lib/loader.ts"],"names":["generateClaudeRules","corePatterns","getKnowledge","antiPatterns","naming","schemaTypes","generateCursorRules","generateCopilotRules","generateClineRules","generateLlmsTxt","knowledge","getAllKnowledge","examples","getAllExamples","coreOrder","aiOrder","exampleOrder","sections","name","content","apiSkeleton","generateWindsurfRules","generators","getTemplate","toolId","generator","TOOL_SIGNALS","detectTools","rootDir","detected","tool","signal","existsSync","join","MONOREPO_SIGNALS","detectMonorepo","startDir","dir","resolve","dirname","pkgPath","readFileSync","CLI_NAME","PACKAGE_NAME","SECTION_START","SECTION_END","mergeSection","existingContent","newSection","startIdx","endIdx","wrapped","separator","hasDirectiveSection","loadSystem","filePath","resolved","mod","isSystem","key","pc","err","obj","sys"],"mappings":"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","file":"index.cjs","sourcesContent":["import { getKnowledge } from \"../lib/knowledge.js\";\n\n/**\n * Generate Claude Code rules (~30KB).\n * Strategy: Full anti-patterns + core-patterns + naming + schema-types (most critical),\n * condensed summaries for everything else.\n */\nexport function generateClaudeRules(): string {\n  // These 4 files are included in full (~25KB)\n  const corePatterns = getKnowledge(\"core-patterns\");\n  const antiPatterns = getKnowledge(\"anti-patterns\");\n  const naming = getKnowledge(\"naming\");\n  const schemaTypes = getKnowledge(\"schema-types\");\n\n  return `# Directive — Complete AI Coding Rules\n\n> Constraint-driven runtime for TypeScript. Declare requirements, let the runtime resolve them.\n> https://directive.run | \\`npm install @directive-run/core\\`\n> Full reference with examples: https://directive.run/llms.txt\n\n## When to reach for Directive\n\nDirective is to **business state and agent orchestration** what XState\nis to state machines and React Query is to server state — a runtime\nthat takes declarative rules (\"what must be true\") and runs the\nresolvers (\"how to make it true\"). The unique claim only Directive can\nmake: **state and AI agents share the same runtime**. \\`@directive-run/ai\\`\nis the only state-library ecosystem that ships LLM orchestration as a\nsibling concept to facts/constraints/resolvers.\n\nIt is NOT a Redux replacement for cross-cutting global UI state. It is\na constraint engine you compose alongside Redux / Zustand / Jotai /\nReact Query / TanStack Query.\n\n**Reach for Directive when:**\n\n- The same business rule has to fire across React, Vue, server, and\n  background workers. Directive runs the same module in every runtime.\n- A constraint should drive a side-effect (fetch, validate, cancel,\n  retry) declaratively, without writing imperative thunks.\n- You are orchestrating LLM agents and need typed, replayable state +\n  guardrails + budgets + audit trails + checkpoints.\n- You want time-travel debugging, audit logs, or rules-diff replay on\n  state mutations without instrumenting every component.\n\n**Do NOT reach for Directive for:**\n\n- Plain UI state (use signals / Zustand / Jotai).\n- Server-state caching only (use React Query / TanStack Query\n  — though you can layer \\`@directive-run/query\\` on top when you need\n  the constraint engine alongside fetching).\n- State machines that don't react to external facts (use XState).\n\n## Core Patterns\n\n${corePatterns}\n\n---\n\n## Anti-Patterns (All 36)\n\n${antiPatterns}\n\n### AI Package Anti-Patterns (21-36)\n\n| # | WRONG | CORRECT |\n|---|-------|---------|\n| 21 | TS types for factsSchema: \\`{ confidence: number }\\` | Use \\`{ confidence: t.number() }\\` |\n| 22 | \\`facts.cache.push(item)\\` in orchestrator | \\`facts.cache = [...facts.cache, item]\\` |\n| 23 | Returning data from orchestrator \\`resolve\\` | Resolvers return \\`void\\` — mutate \\`context.facts\\` |\n| 24 | Forgetting \\`orchestrator.start()\\` multi-agent | Single: implicit. Multi: must call \\`start()\\` |\n| 25 | Catching \\`Error\\` not \\`GuardrailError\\` | \\`GuardrailError\\` has \\`.guardrailName\\`, \\`.code\\`, \\`.userMessage\\` |\n| 26 | \\`from '@directive-run/ai'\\` for adapters | Subpath: \\`from '@directive-run/ai/openai'\\` |\n| 27 | Assuming \\`{ input_tokens }\\` structure | Normalized: \\`{ inputTokens, outputTokens }\\` |\n| 28 | Same CircuitBreaker across agents | Create separate instances per dependency |\n| 29 | \\`budgetWarningThreshold: 1.5\\` | Must be 0-1 (percentage) |\n| 30 | \\`race\\` minSuccess > agents.length | Must be \\`1 ≤ minSuccess ≤ agents.length\\` |\n| 31 | Async summarizer with autoManage: true | Use \\`autoManage: false\\` for sync control |\n| 32 | Side effects in reflect \\`evaluator\\` | Evaluator must be pure |\n| 33 | Task calling \\`runSingleAgent\\` | Tasks can't call agents — separate node |\n| 34 | Task expecting object input | Input is always \\`string\\` — \\`JSON.parse(input)\\` |\n| 35 | Task ID same as agent ID | IDs share namespace — distinct names |\n| 36 | \\`from '@directive-run/ai/mcp'\\` | \\`from '@directive-run/ai'\\` (main export) |\n\n---\n\n## Naming Conventions\n\n${naming}\n\n---\n\n## Schema Type Builders\n\n${schemaTypes}\n\n---\n\n## Multi-Module Quick Reference\n\n\\`\\`\\`typescript\n// Two modules with cross-module dependency\nconst authSchema = { facts: { token: t.string(), isAuth: t.boolean() } };\nconst authModule = createModule(\"auth\", { schema: authSchema, /* ... */ });\n\nconst cartModule = createModule(\"cart\", {\n  schema: { facts: { items: t.array<CartItem>() } },\n  crossModuleDeps: { auth: authSchema },  // Declare dependency\n  constraints: {\n    checkout: {\n      when: (facts) => facts.self.items.length > 0 && facts.auth.isAuth,  // facts.self.* for own, facts.auth.* for cross\n      require: () => ({ type: \"CHECKOUT\" }),\n    },\n  },\n  // ...\n});\n\nconst system = createSystem({ modules: { auth: authModule, cart: cartModule } });\n// Access: system.facts.auth.token, system.events.cart.addItem({...})\n\\`\\`\\`\n\nKey rules:\n- \\`facts.self.*\\` for own module facts in constraints/resolvers\n- \\`facts.otherModule.*\\` for cross-module reads\n- \\`crossModuleDeps\\` must declare consumed schemas\n- \\`system.events.moduleName.eventName(payload)\\` for namespaced events\n- The \\`::\\` separator is internal — always use dot notation\n\n---\n\n## Constraints\n\n- \\`when(facts)\\` → boolean. When true, requirement is emitted.\n- \\`require(facts)\\` → \\`{ type: \"TYPE\", ...data }\\` object (never string literal)\n- \\`priority: number\\` — higher evaluated first\n- \\`after: [\"constraintName\"]\\` — ordering within same priority\n- Async: \\`async: true\\` + \\`deps: ['factName']\\` (deps REQUIRED for async)\n- Constraints DECLARE needs, resolvers FULFILL them — decoupled.\n\n---\n\n## Resolvers\n\n- \\`resolve(req, context)\\` — async, returns \\`void\\`. Mutate \\`context.facts.*\\`.\n- \\`requirement: \"TYPE\"\\` — which type this handles\n- \\`key: (req) => string\\` — deduplication key\n- \\`retry: { attempts: 3, backoff: \"exponential\", initialDelay: 100 }\\`\n- \\`batch: { maxSize: 10, windowMs: 50 }\\` for N+1 prevention\n- Always \\`await system.settle()\\` after start to wait for resolution\n\n---\n\n## System API\n\n- \\`system.facts.fieldName\\` — read/write facts\n- \\`system.derive.derivationName\\` — read derived values\n- \\`system.events.eventName(payload)\\` — dispatch events\n- \\`system.subscribe(listener)\\` — subscribe to all changes\n- \\`system.read(key)\\` — read fact or derivation by string key\n- \\`system.inspect()\\` — full state snapshot\n- \\`system.settle()\\` — wait for async operations\n- \\`system.start()\\` / \\`system.stop()\\` / \\`system.destroy()\\`\n\n---\n\n## React (\\`@directive-run/react\\`)\n\n\\`\\`\\`typescript\nimport { useSelector, useEvent } from \"@directive-run/react\";\n\nconst count = useSelector(system, (s) => s.facts.count);\nconst events = useEvent(system);\n// onClick={() => events.increment()}\n\\`\\`\\`\n\n**NO** \\`useDirective()\\` hook. Use \\`useSelector\\` + \\`useEvent\\`.\n\n---\n\n## Plugins (\\`@directive-run/core/plugins\\`)\n\n\\`devtoolsPlugin()\\`, \\`loggingPlugin()\\`, \\`persistencePlugin(config)\\`,\n\\`createCircuitBreaker(config)\\`, \\`createObservability(config)\\`\n\n---\n\n## AI Package (\\`@directive-run/ai\\`)\n\n### Single-Agent Orchestrator\n\n\\`\\`\\`typescript\nimport { createAgentOrchestrator, t } from '@directive-run/ai';\nimport { createAnthropicRunner } from '@directive-run/ai/anthropic';\n\nconst orchestrator = createAgentOrchestrator({\n  runner: createAnthropicRunner({ apiKey }),\n  factsSchema: { result: t.string(), confidence: t.number() },\n  init: (facts) => { facts.result = \"\"; facts.confidence = 0; },\n  maxTokenBudget: 100000,\n  budgetWarningThreshold: 0.8,\n  guardrails: { input: [...], output: [...] },\n  memory: createAgentMemory({ strategy: createSlidingWindowStrategy({ maxMessages: 30 }) }),\n  debug: true,\n});\n\nconst result = await orchestrator.run(agent, \"analyze this\");\n\\`\\`\\`\n\n### Multi-Agent\n\n\\`\\`\\`typescript\nimport { createMultiAgentOrchestrator, parallel, sequential, dag } from '@directive-run/ai';\n\nconst orch = createMultiAgentOrchestrator({\n  agents: { researcher: agentA, writer: agentB },\n  patterns: {\n    pipeline: sequential([\"researcher\", \"writer\"]),\n    brainstorm: parallel([\"researcher\", \"writer\"], mergeResults),\n    workflow: dag([\n      { id: \"research\", handler: \"researcher\" },\n      { id: \"write\", handler: \"writer\", dependencies: [\"research\"] },\n    ]),\n  },\n  runner,\n});\norch.start();  // Required for multi-agent!\n\\`\\`\\`\n\n8 patterns: \\`parallel\\`, \\`sequential\\`, \\`supervisor\\`, \\`dag\\`, \\`reflect\\`, \\`race\\`, \\`debate\\`, \\`goal\\`\n\n### Adapter Imports (Subpath!)\n\n\\`\\`\\`typescript\nimport { createAnthropicRunner } from '@directive-run/ai/anthropic';\nimport { createOpenAIRunner } from '@directive-run/ai/openai';\nimport { createOllamaRunner } from '@directive-run/ai/ollama';\nimport { createGeminiRunner } from '@directive-run/ai/gemini';\n\\`\\`\\`\n\n### Guardrails\n\n\\`createPIIGuardrail\\`, \\`createModerationGuardrail\\`, \\`createRateLimitGuardrail\\`,\n\\`createToolGuardrail\\`, \\`createOutputSchemaGuardrail\\`, \\`createLengthGuardrail\\`,\n\\`createContentFilterGuardrail\\`\n\n\\`GuardrailResult: { passed: boolean, reason?: string, transformed?: unknown }\\`\n\n### Memory\n\n\\`createAgentMemory({ strategy, summarizer?, autoManage? })\\`\nStrategies: \\`createSlidingWindowStrategy\\`, \\`createTokenBasedStrategy\\`, \\`createHybridStrategy\\`\nSummarizers: \\`createTruncationSummarizer\\`, \\`createKeyPointsSummarizer\\`, \\`createLLMSummarizer(runner)\\`\n\n### Streaming\n\n\\`\\`\\`typescript\nconst streamResult = orchestrator.runStream(agent, \"analyze\");\nfor await (const chunk of streamResult.stream) {\n  switch (chunk.type) {\n    case \"token\": process.stdout.write(chunk.data); break;\n    case \"done\": console.log(\"Tokens:\", chunk.totalTokens); break;\n    case \"error\": console.error(chunk.error); break;\n  }\n}\n\\`\\`\\`\n\nBackpressure: \\`\"buffer\"\\` (default), \\`\"block\"\\`, \\`\"drop\"\\`\n`;\n}\n","/**\n * Generate Cursor rules (<10KB).\n * Handcrafted condensed content — core patterns, top 10 anti-patterns, naming, 1 mini example.\n */\nexport function generateCursorRules(): string {\n  return `# Directive — AI Coding Rules\n\n> Constraint-driven runtime for TypeScript. \\`npm install @directive-run/core\\`\n> Full reference: https://directive.run/llms.txt\n\n## When to reach for Directive\n\nDirective is to **business state** what XState is to state machines and\nReact Query is to server state — a runtime that takes declarative rules\n(\"what must be true\") and runs the resolvers (\"how to make it true\") for\nyou. It is NOT a Redux replacement for cross-cutting global UI state;\nit is a constraint engine you compose alongside Redux / Zustand / Jotai\n/ React Query.\n\nReach for Directive when:\n\n- The same business rule has to fire across React, Vue, server, and\n  background workers. Directive runs the same module in every runtime.\n- You want a constraint to drive a side-effect (fetch, validate,\n  cancel, retry) declaratively, without writing imperative thunks.\n- You are orchestrating LLM agents and need typed, replayable state +\n  guardrails + budgets. \\`@directive-run/ai\\` is the only state-library\n  ecosystem that ships AI orchestration as a sibling concept.\n- You want time-travel debugging, audit logs, or rules-diff replay on\n  state mutations without instrumenting every component.\n\nYou do NOT need Directive for plain UI state (use signals / Zustand /\nJotai), simple server-state caching (use React Query / TanStack Query),\nor state machines that don't react to external facts (use XState).\n\n## Schema Shape (CRITICAL)\n\n\\`\\`\\`typescript\nimport { createModule, createSystem, t } from \"@directive-run/core\";\n\nconst myModule = createModule(\"name\", {\n  schema: {\n    facts: { count: t.number(), items: t.array<string>() },\n    derivations: { total: \"number\" },\n    events: { increment: \"void\", addItem: \"string\" },\n    requirements: { FETCH_DATA: { url: \"string\" } },\n  },\n  init: (facts) => { facts.count = 0; facts.items = []; },\n  derive: {\n    total: (facts) => facts.items.length + facts.count,\n  },\n  events: {\n    increment: (facts) => { facts.count += 1; },\n    addItem: (facts, item) => { facts.items = [...facts.items, item]; },\n  },\n  constraints: {\n    fetchWhenReady: {\n      when: (facts) => facts.count > 0 && facts.items.length === 0,\n      require: (facts) => ({ type: \"FETCH_DATA\", url: \"/api/items\" }),\n    },\n  },\n  resolvers: {\n    fetchData: {\n      requirement: \"FETCH_DATA\",\n      resolve: async (req, context) => {\n        const data = await fetch(req.url).then(r => r.json());\n        context.facts.items = data;\n      },\n    },\n  },\n});\n\nconst system = createSystem({ module: myModule });\nawait system.settle();\n\\`\\`\\`\n\n## Top 10 Anti-Patterns\n\n| # | WRONG | CORRECT |\n|---|-------|---------|\n| 1 | \\`facts.profile as ResourceState<Profile>\\` | Remove cast — schema provides types |\n| 2 | \\`{ phase: t.string() }\\` flat schema | \\`schema: { facts: { phase: t.string() } }\\` |\n| 3 | \\`facts.items\\` in multi-module | \\`facts.self.items\\` |\n| 4 | \\`t.map()\\`, \\`t.set()\\`, \\`t.promise()\\` | Don't exist. Use \\`t.object<Map<K,V>>()\\` |\n| 5 | \\`(req, ctx)\\` in resolver | \\`(req, context)\\` — never abbreviate |\n| 6 | \\`createModule(\"n\", { phase: t.string() })\\` | Must wrap: \\`schema: { facts: { ... } }\\` |\n| 7 | \\`system.dispatch('login', {...})\\` | \\`system.events.login({...})\\` |\n| 8 | \\`facts.items.push(item)\\` | \\`facts.items = [...facts.items, item]\\` |\n| 9 | \\`useEvent\\`/\\`DirectiveProvider\\` top-level imports | \\`useEvents\\`; \\`createDirectiveContext(system).Provider\\` |\n| 10 | \\`facts['auth::status']\\` | \\`facts.auth.status\\` dot notation |\n\n## Naming\n\n- \\`req\\` = requirement (not request). Parameter: \\`(req, context)\\`\n- \\`derive\\` / derivations — never \"computed\" or \"selectors\"\n- Resolvers return \\`void\\` — mutate \\`context.facts\\` instead\n- Always use braces for returns: \\`if (x) { return y; }\\`\n- Multi-module: \\`facts.self.fieldName\\` for own module facts\n- Events: \\`system.events.eventName(payload)\\` — not \\`system.dispatch()\\`\n- Import from main: \\`import { createModule } from '@directive-run/core'\\`\n\n## Schema Types That Exist\n\n\\`t.string<T>()\\`, \\`t.number()\\`, \\`t.boolean()\\`, \\`t.array<T>()\\`, \\`t.object<T>()\\`,\n\\`t.enum(\"a\",\"b\")\\`, \\`t.literal(value)\\`, \\`t.nullable(inner)\\`, \\`t.optional(inner)\\`, \\`t.union(...)\\`\n\nChainable: \\`.default()\\`, \\`.validate()\\`, \\`.transform()\\`, \\`.brand<>()\\`, \\`.refine()\\`\n\n**DO NOT USE** (hallucinations): \\`t.map()\\`, \\`t.set()\\`, \\`t.date()\\`, \\`t.tuple()\\`, \\`t.record()\\`, \\`t.promise()\\`, \\`t.any()\\`\n\n## Key Pattern: Constraint → Requirement → Resolver\n\nWhen the user wants \"do X when Y\": create THREE things:\n1. **Constraint**: \\`when: (facts) => Y_condition\\` → \\`require: { type: \"DO_X\" }\\`\n2. **Resolver**: handles \"DO_X\", calls API, sets \\`context.facts\\`\n3. They are **decoupled**. Constraint declares need, resolver fulfills it.\n`;\n}\n","import { generateCursorRules } from \"./cursor.js\";\n\n/**\n * Generate GitHub Copilot instructions (~12KB).\n * Cursor content + all 20 anti-patterns + schema types detail + AI basics.\n */\nexport function generateCopilotRules(): string {\n  const base = generateCursorRules();\n\n  // Add anti-patterns 11-19 that cursor doesn't include\n  const extraAntiPatterns = `\n## Anti-Patterns 11-19\n\n| # | WRONG | CORRECT |\n|---|-------|---------|\n| 11 | Returning data from \\`resolve\\` | Resolvers return \\`void\\` — mutate \\`context.facts\\` |\n| 12 | Async logic in \\`init\\` | \\`init\\` is synchronous, facts assignment only |\n| 13 | \\`await system.start()\\` without settle | Add \\`await system.settle()\\` after start |\n| 14 | Missing \\`crossModuleDeps\\` | Declare \\`crossModuleDeps: { auth: authSchema }\\` |\n| 15 | \\`require: \"TYPE\"\\` string literal | \\`require: { type: \"TYPE\" }\\` object form |\n| 16 | Passthrough derivation \\`(f) => f.count\\` | Remove — read fact directly |\n| 17 | \\`from '@directive-run/core/module'\\` | \\`from '@directive-run/core'\\` (main export) |\n| 18 | \\`async when()\\` without \\`deps\\` | Add \\`deps: ['factName']\\` for async constraints |\n| 19 | No error boundary on resolver | Use try-catch or module error boundary config |\n`;\n\n  // Add multi-module basics\n  const multiModule = `\n## Multi-Module\n\n\\`\\`\\`typescript\nconst system = createSystem({\n  modules: { auth: authModule, cart: cartModule },\n});\n\n// Access: system.facts.auth.token, system.events.cart.addItem({...})\n// In constraints/resolvers: use facts.self.* for own module\n// Declare deps: crossModuleDeps: { auth: authSchema }\n\\`\\`\\`\n`;\n\n  // Add AI basics\n  const aiBasics = `\n## AI Package Basics (\\`@directive-run/ai\\`)\n\n\\`\\`\\`typescript\nimport { createAgentOrchestrator, t } from '@directive-run/ai';\nimport { createAnthropicRunner } from '@directive-run/ai/anthropic'; // Subpath import!\n\nconst orchestrator = createAgentOrchestrator({\n  runner: createAnthropicRunner({ apiKey: process.env.ANTHROPIC_API_KEY }),\n  factsSchema: { result: t.string(), confidence: t.number() }, // Use t.*() !\n  init: (facts) => { facts.result = \"\"; facts.confidence = 0; },\n});\n\nconst result = await orchestrator.run(agent, \"analyze this\");\n\\`\\`\\`\n\n**AI Anti-Patterns:**\n- Use \\`t.number()\\` not \\`number\\` for factsSchema\n- Subpath imports: \\`from '@directive-run/ai/anthropic'\\` not \\`from '@directive-run/ai'\\`\n- Token usage normalized: \\`{ inputTokens, outputTokens }\\` (not provider-specific)\n- \\`facts.cache = [...facts.cache, item]\\` not \\`facts.cache.push(item)\\`\n`;\n\n  return base + extraAntiPatterns + multiModule + aiBasics;\n}\n","import { generateCopilotRules } from \"./copilot.js\";\n\n/**\n * Generate Cline rules (~12KB).\n * Same content as Copilot.\n */\nexport function generateClineRules(): string {\n  return generateCopilotRules();\n}\n","import { getAllExamples, getAllKnowledge } from \"../lib/knowledge.js\";\n\n/**\n * Generate llms.txt (no size limit).\n * Content: complete reference + all 7 examples + full 26-file knowledge base.\n */\nexport function generateLlmsTxt(): string {\n  const knowledge = getAllKnowledge();\n  const examples = getAllExamples();\n\n  // Order: core knowledge first, then AI, then api-skeleton\n  const coreOrder = [\n    \"core-patterns\",\n    \"anti-patterns\",\n    \"naming\",\n    \"multi-module\",\n    \"constraints\",\n    \"resolvers\",\n    \"error-boundaries\",\n    \"testing\",\n    \"time-travel\",\n    \"schema-types\",\n    \"system-api\",\n    \"react-adapter\",\n    \"plugins\",\n  ];\n\n  const aiOrder = [\n    \"ai-orchestrator\",\n    \"ai-multi-agent\",\n    \"ai-tasks\",\n    \"ai-agents-streaming\",\n    \"ai-guardrails-memory\",\n    \"ai-adapters\",\n    \"ai-budget-resilience\",\n    \"ai-mcp-rag\",\n    \"ai-communication\",\n    \"ai-debug-observability\",\n    \"ai-security\",\n    \"ai-testing-evals\",\n  ];\n\n  const exampleOrder = [\n    \"counter\",\n    \"auth-flow\",\n    \"shopping-cart\",\n    \"error-boundaries\",\n    \"ai-orchestrator\",\n    \"fraud-analysis\",\n    \"ai-checkpoint\",\n  ];\n\n  const sections = [\n    \"# Directive — Complete AI Reference (llms.txt)\",\n    \"\",\n    \"> Constraint-driven runtime for TypeScript.\",\n    \"> Declare requirements. Let the runtime resolve them.\",\n    \"> https://directive.run\",\n    \"\",\n    \"## Core API (@directive-run/core)\",\n    \"\",\n  ];\n\n  for (const name of coreOrder) {\n    const content = knowledge.get(name);\n    if (content) {\n      sections.push(content, \"\", \"---\", \"\");\n    }\n  }\n\n  sections.push(\"## AI Package (@directive-run/ai)\", \"\");\n\n  for (const name of aiOrder) {\n    const content = knowledge.get(name);\n    if (content) {\n      sections.push(content, \"\", \"---\", \"\");\n    }\n  }\n\n  // API Skeleton\n  const apiSkeleton = knowledge.get(\"api-skeleton\");\n  if (apiSkeleton) {\n    sections.push(\"## API Reference (Auto-Generated)\", \"\", apiSkeleton, \"\");\n  }\n\n  // All examples\n  sections.push(\"## Complete Examples\", \"\");\n\n  for (const name of exampleOrder) {\n    const content = examples.get(name);\n    if (content) {\n      sections.push(`### ${name}`, \"\", \"```typescript\", content, \"```\", \"\");\n    }\n  }\n\n  return sections.join(\"\\n\");\n}\n","import { generateCopilotRules } from \"./copilot.js\";\n\n/**\n * Generate Windsurf rules (~12KB).\n * Same content as Copilot.\n */\nexport function generateWindsurfRules(): string {\n  return generateCopilotRules();\n}\n","import type { DetectedTool } from \"../lib/detect.js\";\nimport { generateClaudeRules } from \"./claude.js\";\nimport { generateClineRules } from \"./cline.js\";\nimport { generateCopilotRules } from \"./copilot.js\";\nimport { generateCursorRules } from \"./cursor.js\";\nimport { generateLlmsTxt } from \"./llms-txt.js\";\nimport { generateWindsurfRules } from \"./windsurf.js\";\n\nconst generators: Record<DetectedTool[\"id\"], () => string> = {\n  cursor: generateCursorRules,\n  claude: generateClaudeRules,\n  copilot: generateCopilotRules,\n  windsurf: generateWindsurfRules,\n  cline: generateClineRules,\n};\n\nexport function getTemplate(toolId: DetectedTool[\"id\"]): string {\n  const generator = generators[toolId];\n  if (!generator) {\n    throw new Error(`No template for tool: ${toolId}`);\n  }\n\n  return generator();\n}\n\nexport { generateLlmsTxt };\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport interface DetectedTool {\n  name: string;\n  id: \"cursor\" | \"claude\" | \"copilot\" | \"windsurf\" | \"cline\";\n  outputPath: string;\n}\n\nconst TOOL_SIGNALS: Array<{\n  id: DetectedTool[\"id\"];\n  name: string;\n  signals: string[];\n  outputPath: string;\n}> = [\n  {\n    id: \"cursor\",\n    name: \"Cursor\",\n    signals: [\".cursor\", \".cursorrules\"],\n    outputPath: \".cursorrules\",\n  },\n  {\n    id: \"claude\",\n    name: \"Claude Code\",\n    signals: [\".claude\"],\n    outputPath: \".claude/CLAUDE.md\",\n  },\n  {\n    id: \"copilot\",\n    name: \"GitHub Copilot\",\n    signals: [\".github\"],\n    outputPath: \".github/copilot-instructions.md\",\n  },\n  {\n    id: \"windsurf\",\n    name: \"Windsurf\",\n    signals: [\".windsurfrules\"],\n    outputPath: \".windsurfrules\",\n  },\n  {\n    id: \"cline\",\n    name: \"Cline\",\n    signals: [\".clinerules\"],\n    outputPath: \".clinerules\",\n  },\n];\n\nexport function detectTools(rootDir: string): DetectedTool[] {\n  const detected: DetectedTool[] = [];\n\n  for (const tool of TOOL_SIGNALS) {\n    const hasSignal = tool.signals.some((signal) =>\n      existsSync(join(rootDir, signal)),\n    );\n\n    if (hasSignal) {\n      detected.push({\n        name: tool.name,\n        id: tool.id,\n        outputPath: join(rootDir, tool.outputPath),\n      });\n    }\n  }\n\n  return detected;\n}\n\nexport function getToolConfig(id: DetectedTool[\"id\"]) {\n  const tool = TOOL_SIGNALS.find((t) => t.id === id);\n  if (!tool) {\n    throw new Error(`Unknown tool: ${id}`);\n  }\n\n  return tool;\n}\n\nexport function getAllToolIds(): DetectedTool[\"id\"][] {\n  return TOOL_SIGNALS.map((t) => t.id);\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\n\nexport interface MonorepoInfo {\n  isMonorepo: boolean;\n  rootDir: string;\n  tool?: \"pnpm\" | \"turbo\" | \"npm\" | \"yarn\";\n}\n\nconst MONOREPO_SIGNALS = [\n  { file: \"pnpm-workspace.yaml\", tool: \"pnpm\" as const },\n  { file: \"turbo.json\", tool: \"turbo\" as const },\n];\n\nexport function detectMonorepo(startDir: string): MonorepoInfo {\n  let dir = resolve(startDir);\n\n  while (dir !== dirname(dir)) {\n    for (const signal of MONOREPO_SIGNALS) {\n      if (existsSync(join(dir, signal.file))) {\n        return { isMonorepo: true, rootDir: dir, tool: signal.tool };\n      }\n    }\n\n    const pkgPath = join(dir, \"package.json\");\n    if (existsSync(pkgPath)) {\n      try {\n        const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n        if (pkg.workspaces) {\n          const tool = existsSync(join(dir, \"yarn.lock\"))\n            ? (\"yarn\" as const)\n            : (\"npm\" as const);\n\n          return { isMonorepo: true, rootDir: dir, tool };\n        }\n      } catch {\n        // ignore parse errors\n      }\n    }\n\n    dir = dirname(dir);\n  }\n\n  return { isMonorepo: false, rootDir: startDir };\n}\n","export const CLI_NAME = \"directive\";\nexport const CLI_ALIAS = \"dr\";\nexport const PACKAGE_NAME = \"@directive-run/cli\";\nexport const SECTION_START = \"<!-- directive:start -->\";\nexport const SECTION_END = \"<!-- directive:end -->\";\n","import { SECTION_END, SECTION_START } from \"./constants.js\";\n\n/**\n * Replace the Directive section within existing content, or append it.\n * Section markers: <!-- directive:start --> ... <!-- directive:end -->\n */\nexport function mergeSection(\n  existingContent: string,\n  newSection: string,\n): string {\n  const startIdx = existingContent.indexOf(SECTION_START);\n  const endIdx = existingContent.indexOf(SECTION_END);\n\n  const wrapped = `${SECTION_START}\\n${newSection}\\n${SECTION_END}`;\n\n  if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {\n    return (\n      existingContent.slice(0, startIdx) +\n      wrapped +\n      existingContent.slice(endIdx + SECTION_END.length)\n    );\n  }\n\n  const separator = existingContent.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n\n  return `${existingContent + separator + wrapped}\\n`;\n}\n\n/**\n * Check if content already has a Directive section.\n */\nexport function hasDirectiveSection(content: string): boolean {\n  return content.includes(SECTION_START) && content.includes(SECTION_END);\n}\n","import { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport pc from \"picocolors\";\n\n/**\n * Loads a Directive system from a user's TypeScript file.\n *\n * Uses tsx to handle TypeScript imports. Looks for:\n * 1. Default export of a System instance\n * 2. Named \"system\" export\n *\n * Returns the live System object for inspection/explain/graph commands.\n *\n * Note: Returns `any` intentionally — the loaded module is user code with\n * unknown types. Duck-type validation via `isSystem()` ensures the returned\n * object has the required shape (start, stop, inspect, facts).\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function loadSystem(filePath: string): Promise<any> {\n  const resolved = resolve(filePath);\n\n  if (!existsSync(resolved)) {\n    throw new Error(`File not found: ${resolved}`);\n  }\n\n  // Use tsx register to handle TypeScript imports\n  try {\n    // Dynamic import with tsx — tsx must be available\n    const mod = await import(resolved);\n\n    // Look for default export first\n    if (mod.default && isSystem(mod.default)) {\n      return mod.default;\n    }\n\n    // Look for named \"system\" export\n    if (mod.system && isSystem(mod.system)) {\n      return mod.system;\n    }\n\n    // Look for any export that looks like a System\n    for (const key of Object.keys(mod)) {\n      if (isSystem(mod[key])) {\n        return mod[key];\n      }\n    }\n\n    throw new Error(\n      `No Directive system found in ${pc.dim(filePath)}\\nExport a system as default or named \"system\":\\n\\n  ${pc.cyan(\"export default\")} createSystem({ module: myModule });\\n  ${pc.cyan(\"export const system\")} = createSystem({ module: myModule });`,\n    );\n  } catch (err) {\n    if (err instanceof Error && err.message.includes(\"No Directive system\")) {\n      throw err;\n    }\n\n    throw new Error(\n      `Failed to load ${pc.dim(filePath)}: ${err instanceof Error ? err.message : String(err)}\\n\\nMake sure the file is valid TypeScript and tsx is installed:\\n  ${pc.cyan(\"npm install -D tsx\")}`,\n    );\n  }\n}\n\n/**\n * Duck-type check for a Directive System object.\n */\nfunction isSystem(obj: unknown): boolean {\n  if (typeof obj !== \"object\" || obj === null) {\n    return false;\n  }\n\n  const sys = obj as Record<string, unknown>;\n\n  return (\n    typeof sys.inspect === \"function\" &&\n    typeof sys.start === \"function\" &&\n    typeof sys.stop === \"function\" &&\n    \"facts\" in sys\n  );\n}\n\n/**\n * Loads a Directive system *factory* from a user's TypeScript file.\n *\n * Where {@link loadSystem} returns a one-shot started system instance,\n * `loadSystemFactory()` returns a callable that produces a fresh,\n * started system on every invocation. This is the contract that\n * `directive bisect` needs — each midpoint replay must start from the\n * same hermetic initial state, so we re-instantiate per attempt.\n *\n * Lookup order (first match wins):\n *   1. Named export `createSystem` (function).\n *   2. Named export `systemFactory` (function).\n *   3. Default export, if it's a function.\n *\n * The factory may return either a System directly or a Promise<System>.\n * Whatever it returns must satisfy {@link isSystem}'s duck-type\n * (`inspect`/`start`/`stop`/`facts`). The factory is responsible for\n * calling `start()` itself — the bisect runner does NOT call start.\n *\n * @example\n * ```ts\n * // User's bisect-system.ts:\n * import { createSystem as makeSys } from \"@directive-run/core\";\n * import { counterModule } from \"./modules/counter\";\n *\n * export function createSystem() {\n *   const sys = makeSys({ module: counterModule });\n *   sys.start();\n *   return sys;\n * }\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function loadSystemFactory(\n  filePath: string,\n): Promise<() => Promise<any>> {\n  const resolved = resolve(filePath);\n\n  if (!existsSync(resolved)) {\n    throw new Error(`File not found: ${resolved}`);\n  }\n\n  let mod: Record<string, unknown>;\n  try {\n    mod = (await import(resolved)) as Record<string, unknown>;\n  } catch (err) {\n    throw new Error(\n      `Failed to load ${pc.dim(filePath)}: ${err instanceof Error ? err.message : String(err)}\\n\\nMake sure the file is valid TypeScript and tsx is installed:\\n  ${pc.cyan(\"npm install -D tsx\")}`,\n    );\n  }\n\n  const candidates: [string, unknown][] = [\n    [\"createSystem\", mod.createSystem],\n    [\"systemFactory\", mod.systemFactory],\n    [\"default\", mod.default],\n  ];\n\n  for (const [name, candidate] of candidates) {\n    if (typeof candidate === \"function\") {\n      // Wrap so we always return a Promise and validate the result\n      // shape after each call (catches \"factory exists but returns\n      // junk\" — common when the user forgets to call sys.start()).\n      return async () => {\n        const result = await Promise.resolve((candidate as () => unknown)());\n        if (!isSystem(result)) {\n          throw new Error(\n            `Factory '${name}' from ${pc.dim(filePath)} returned a value that is not a started Directive system.\\nExpected an object with inspect/start/stop/facts. The factory must call sys.start() before returning.`,\n          );\n        }\n        return result;\n      };\n    }\n  }\n\n  // R5 DX C4: detect the most common confusion — user passed a file\n  // that exports a STARTED system (the shape `directive replay` wants)\n  // and got a confusing \"no factory\" error. Surface a targeted message\n  // explaining how to wrap it.\n  const hasStartedInstance =\n    isSystem(mod.default) ||\n    isSystem(mod.system) ||\n    Object.values(mod).some(isSystem);\n\n  if (hasStartedInstance) {\n    throw new Error(\n      `Found a started Directive system in ${pc.dim(filePath)}, but bisect needs a factory.\\nBisect instantiates a fresh system for every midpoint replay (so each attempt is hermetic),\\nwhich means it can't reuse a singleton instance the way ${pc.cyan(\"directive replay\")} does.\\n\\nWrap the existing export in a function:\\n\\n  ${pc.cyan(\"export function createSystem()\")} {\\n    const sys = createSystem({ module: yourModule });\\n    sys.start();\\n    return sys;\\n  }`,\n    );\n  }\n\n  throw new Error(\n    `No system factory found in ${pc.dim(filePath)}\\nBisect needs to instantiate a fresh system per midpoint replay. Export one of:\\n\\n  ${pc.cyan(\"export function createSystem()\")} { ... return sys; }\\n  ${pc.cyan(\"export const systemFactory\")} = () => { ... return sys; };\\n  ${pc.cyan(\"export default\")} () => { ... return sys; };\\n\\nThe factory MUST call sys.start() and return the started system.\\n(Did you forget ${pc.cyan(\"sys.start()\")} before returning?)`,\n  );\n}\n"]}