@directive-run/cli 0.4.2 → 0.7.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Jason Comes
3
+ Copyright (c) 2026 Sizls LLC
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/dist/cli.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import*as u from'@clack/prompts';import {existsSync,mkdirSync,writeFileSync,readFileSync,readdirSync}from'fs';import {join,relative,dirname,resolve}from'path';import d from'picocolors';import {getAllExamples,getExample,getKnowledge}from'@directive-run/knowledge';var y="directive";var z="<!-- directive:start -->",W="<!-- directive:end -->";var Q=[{id:"cursor",name:"Cursor",signals:[".cursor",".cursorrules"],outputPath:".cursorrules"},{id:"claude",name:"Claude Code",signals:[".claude"],outputPath:".claude/CLAUDE.md"},{id:"copilot",name:"GitHub Copilot",signals:[".github"],outputPath:".github/copilot-instructions.md"},{id:"windsurf",name:"Windsurf",signals:[".windsurfrules"],outputPath:".windsurfrules"},{id:"cline",name:"Cline",signals:[".clinerules"],outputPath:".clinerules"}];function ae(e){let t=[];for(let r of Q)r.signals.some(o=>existsSync(join(e,o)))&&t.push({name:r.name,id:r.id,outputPath:join(e,r.outputPath)});return t}function L(e){let t=Q.find(r=>r.id===e);if(!t)throw new Error(`Unknown tool: ${e}`);return t}function ce(){return Q.map(e=>e.id)}function I(e,t){let r=e.indexOf(z),s=e.indexOf(W),o=`${z}
2
+ import*as u from'@clack/prompts';import {existsSync,mkdirSync,writeFileSync,readFileSync,readdirSync}from'fs';import {join,relative,dirname,resolve}from'path';import d from'picocolors';import {getAllExamples,getExample,getKnowledge}from'@directive-run/knowledge';var y="directive";var _="<!-- directive:start -->",W="<!-- directive:end -->";var J=[{id:"cursor",name:"Cursor",signals:[".cursor",".cursorrules"],outputPath:".cursorrules"},{id:"claude",name:"Claude Code",signals:[".claude"],outputPath:".claude/CLAUDE.md"},{id:"copilot",name:"GitHub Copilot",signals:[".github"],outputPath:".github/copilot-instructions.md"},{id:"windsurf",name:"Windsurf",signals:[".windsurfrules"],outputPath:".windsurfrules"},{id:"cline",name:"Cline",signals:[".clinerules"],outputPath:".clinerules"}];function ae(e){let t=[];for(let r of J)r.signals.some(o=>existsSync(join(e,o)))&&t.push({name:r.name,id:r.id,outputPath:join(e,r.outputPath)});return t}function L(e){let t=J.find(r=>r.id===e);if(!t)throw new Error(`Unknown tool: ${e}`);return t}function ce(){return J.map(e=>e.id)}function I(e,t){let r=e.indexOf(_),s=e.indexOf(W),o=`${_}
3
3
  ${t}
4
4
  ${W}`;if(r!==-1&&s!==-1&&s>r)return e.slice(0,r)+o+e.slice(s+W.length);let i=e.endsWith(`
5
5
  `)?`
6
6
  `:`
7
7
 
8
8
  `;return e+i+o+`
9
- `}function P(e){return e.includes(z)&&e.includes(W)}var Fe=[{file:"pnpm-workspace.yaml",tool:"pnpm"},{file:"turbo.json",tool:"turbo"}];function ue(e){let t=resolve(e);for(;t!==dirname(t);){for(let s of Fe)if(existsSync(join(t,s.file)))return {isMonorepo:true,rootDir:t,tool:s.tool};let r=join(t,"package.json");if(existsSync(r))try{if(JSON.parse(readFileSync(r,"utf-8")).workspaces){let o=existsSync(join(t,"yarn.lock"))?"yarn":"npm";return {isMonorepo:!0,rootDir:t,tool:o}}}catch{}t=dirname(t);}return {isMonorepo:false,rootDir:e}}function me(){let e=getKnowledge("core-patterns"),t=getKnowledge("anti-patterns"),r=getKnowledge("naming"),s=getKnowledge("schema-types");return `# Directive \u2014 Complete AI Coding Rules
9
+ `}function P(e){return e.includes(_)&&e.includes(W)}var Fe=[{file:"pnpm-workspace.yaml",tool:"pnpm"},{file:"turbo.json",tool:"turbo"}];function ue(e){let t=resolve(e);for(;t!==dirname(t);){for(let s of Fe)if(existsSync(join(t,s.file)))return {isMonorepo:true,rootDir:t,tool:s.tool};let r=join(t,"package.json");if(existsSync(r))try{if(JSON.parse(readFileSync(r,"utf-8")).workspaces){let o=existsSync(join(t,"yarn.lock"))?"yarn":"npm";return {isMonorepo:!0,rootDir:t,tool:o}}}catch{}t=dirname(t);}return {isMonorepo:false,rootDir:e}}function me(){let e=getKnowledge("core-patterns"),t=getKnowledge("anti-patterns"),r=getKnowledge("naming"),s=getKnowledge("schema-types");return `# Directive \u2014 Complete AI Coding Rules
10
10
 
11
11
  > Constraint-driven runtime for TypeScript. Declare requirements, let the runtime resolve them.
12
12
  > https://directive.run | \`npm install @directive-run/core\`
@@ -226,7 +226,7 @@ for await (const chunk of streamResult.stream) {
226
226
  \`\`\`
227
227
 
228
228
  Backpressure: \`"buffer"\` (default), \`"block"\`, \`"drop"\`
229
- `}function H(){return '# Directive \u2014 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## 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 \u2014 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)` \u2014 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 | `useDirective(system)` | `useSelector(system, s => s.facts.count)` |\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 \u2014 never "computed" or "selectors"\n- Resolvers return `void` \u2014 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)` \u2014 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 \u2192 Requirement \u2192 Resolver\n\nWhen the user wants "do X when Y": create THREE things:\n1. **Constraint**: `when: (facts) => Y_condition` \u2192 `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'}function E(){return H()+'\n## Anti-Patterns 11-20\n\n| # | WRONG | CORRECT |\n|---|-------|---------|\n| 11 | `module("name").schema({...}).build()` | Prefer `createModule("name", {...})` object syntax |\n| 12 | Returning data from `resolve` | Resolvers return `void` \u2014 mutate `context.facts` |\n| 13 | Async logic in `init` | `init` is synchronous, facts assignment only |\n| 14 | `await system.start()` without settle | Add `await system.settle()` after start |\n| 15 | Missing `crossModuleDeps` | Declare `crossModuleDeps: { auth: authSchema }` |\n| 16 | `require: "TYPE"` string literal | `require: { type: "TYPE" }` object form |\n| 17 | Passthrough derivation `(f) => f.count` | Remove \u2014 read fact directly |\n| 18 | `from \'@directive-run/core/module\'` | `from \'@directive-run/core\'` (main export) |\n| 19 | `async when()` without `deps` | Add `deps: [\'factName\']` for async constraints |\n| 20 | No error boundary on resolver | Use try-catch or module error boundary config |\n'+`
229
+ `}function z(){return '# Directive \u2014 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## 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 \u2014 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)` \u2014 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 | `useDirective(system)` | `useSelector(system, s => s.facts.count)` |\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 \u2014 never "computed" or "selectors"\n- Resolvers return `void` \u2014 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)` \u2014 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 \u2192 Requirement \u2192 Resolver\n\nWhen the user wants "do X when Y": create THREE things:\n1. **Constraint**: `when: (facts) => Y_condition` \u2192 `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'}function E(){return z()+"\n## Anti-Patterns 11-19\n\n| # | WRONG | CORRECT |\n|---|-------|---------|\n| 11 | Returning data from `resolve` | Resolvers return `void` \u2014 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 \u2014 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"+`
230
230
  ## Multi-Module
231
231
 
232
232
  \`\`\`typescript
@@ -259,10 +259,10 @@ const result = await orchestrator.run(agent, "analyze this");
259
259
  - Subpath imports: \`from '@directive-run/ai/anthropic'\` not \`from '@directive-run/ai'\`
260
260
  - Token usage normalized: \`{ inputTokens, outputTokens }\` (not provider-specific)
261
261
  - \`facts.cache = [...facts.cache, item]\` not \`facts.cache.push(item)\`
262
- `}function pe(){return E()}function fe(){return E()}var ze={cursor:H,claude:me,copilot:E,windsurf:fe,cline:pe};function K(e){let t=ze[e];if(!t)throw new Error(`No template for tool: ${e}`);return t()}function se(e){let t={force:false,merge:false,tools:[],dir:process.cwd()};for(let r=0;r<e.length;r++)switch(e[r]){case "--force":t.force=true;break;case "--merge":t.merge=true;break;case "--tool":{let o=e[++r];o&&t.tools.push(o);break}case "--dir":{let o=e[++r];o&&(t.dir=o);break}}return t}async function ge(e){let t=se(e);u.intro(d.bgCyan(d.black(" directive ai-rules ")));let r=ue(t.dir),s=t.dir;if(r.isMonorepo&&r.rootDir!==t.dir){let n=await u.select({message:"Monorepo detected. Where should AI rules be installed?",options:[{value:"root",label:`Monorepo root (${relative(t.dir,r.rootDir)||"."})`,hint:"recommended"},{value:"workspace",label:`Current workspace (${relative(r.rootDir,t.dir)})`}]});u.isCancel(n)&&(u.cancel("Cancelled."),process.exit(0)),n==="root"&&(s=r.rootDir);}let o;if(t.tools.length>0)o=t.tools.map(n=>{let a=L(n);return {name:a.name,id:a.id,outputPath:join(s,a.outputPath)}});else {let n=ae(s);if(n.length>0){let a=await u.multiselect({message:`Detected ${n.length} AI tool(s). Which should get Directive rules?`,options:n.map(c=>({value:c.id,label:c.name,hint:relative(s,c.outputPath)})),initialValues:n.map(c=>c.id),required:true});u.isCancel(a)&&(u.cancel("Cancelled."),process.exit(0)),o=a.map(c=>{let m=L(c);return {name:m.name,id:m.id,outputPath:join(s,m.outputPath)}});}else {let a=await u.multiselect({message:"No AI tools detected. Which tools do you use?",options:ce().map(c=>{let m=L(c);return {value:c,label:m.name}}),required:true});u.isCancel(a)&&(u.cancel("Cancelled."),process.exit(0)),o=a.map(c=>{let m=L(c);return {name:m.name,id:m.id,outputPath:join(s,m.outputPath)}});}}o.length===0&&(u.cancel("No tools selected."),process.exit(0));let i=u.spinner();for(let n of o){i.start(`Generating ${n.name} rules...`);let a=K(n.id),c=n.outputPath,m=existsSync(c);if(i.stop(`Generated ${n.name} rules.`),m&&!t.force){let w=readFileSync(c,"utf-8");if(t.merge){T(c,I(w,a)),u.log.success(`${d.green("Merged")} Directive section into ${d.dim(relative(s,c))}`);continue}if(P(w)){let f=await u.select({message:`${relative(s,c)} already has a Directive section. What should we do?`,options:[{value:"merge",label:"Update Directive section only",hint:"recommended"},{value:"overwrite",label:"Overwrite entire file"},{value:"skip",label:"Skip this file"}]});u.isCancel(f)&&(u.cancel("Cancelled."),process.exit(0)),f==="merge"?(T(c,I(w,a)),u.log.success(`${d.green("Updated")} ${d.dim(relative(s,c))}`)):f==="overwrite"?(T(c,a),u.log.success(`${d.green("Wrote")} ${d.dim(relative(s,c))}`)):u.log.info(`Skipped ${d.dim(relative(s,c))}`);}else {let f=await u.select({message:`${relative(s,c)} already exists. What should we do?`,options:[{value:"append",label:"Append Directive section",hint:"preserves existing content"},{value:"overwrite",label:"Overwrite entire file"},{value:"skip",label:"Skip this file"}]});u.isCancel(f)&&(u.cancel("Cancelled."),process.exit(0)),f==="append"?(T(c,I(w,a)),u.log.success(`${d.green("Appended")} to ${d.dim(relative(s,c))}`)):f==="overwrite"?(T(c,a),u.log.success(`${d.green("Wrote")} ${d.dim(relative(s,c))}`)):u.log.info(`Skipped ${d.dim(relative(s,c))}`);}}else T(c,a),u.log.success(`${d.green("Created")} ${d.dim(relative(s,c))}`);}u.outro(`Done! Run ${d.cyan(`${y} ai-rules init --merge`)} anytime to update.`);}function T(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}async function he(e){let r=se(e).dir,s=[{id:"cursor",path:join(r,".cursorrules")},{id:"claude",path:join(r,".claude/CLAUDE.md")},{id:"copilot",path:join(r,".github/copilot-instructions.md")},{id:"windsurf",path:join(r,".windsurfrules")},{id:"cline",path:join(r,".clinerules")}],o=0;for(let i of s){if(!existsSync(i.path))continue;let n=readFileSync(i.path,"utf-8");if(!P(n))continue;let a=K(i.id),c=I(n,a);T(i.path,c),console.log(`${d.green("Updated")} ${d.dim(relative(r,i.path))}`),o++;}console.log(o===0?d.dim(`No existing rule files found. Run ${d.cyan(`${y} ai-rules init`)} first.`):d.green(`
263
- Updated ${o} file(s) to latest knowledge version.`));}async function ye(e){let r=se(e).dir,s=[{id:"cursor",path:join(r,".cursorrules"),name:"Cursor"},{id:"claude",path:join(r,".claude/CLAUDE.md"),name:"Claude Code"},{id:"copilot",path:join(r,".github/copilot-instructions.md"),name:"GitHub Copilot"},{id:"windsurf",path:join(r,".windsurfrules"),name:"Windsurf"},{id:"cline",path:join(r,".clinerules"),name:"Cline"}],o=0,i=0;for(let n of s){if(!existsSync(n.path))continue;let a=readFileSync(n.path,"utf-8");if(!P(a))continue;o++;let c=K(n.id);I(a,c)!==a?(console.log(`${d.red("\u2717")} ${n.name} rules are ${d.yellow("stale")}`),i++):console.log(`${d.green("\u2713")} ${n.name} rules are ${d.green("current")}`);}if(o===0){console.log(d.dim("No rule files found to check."));return}i>0?(console.log(`
262
+ `}function pe(){return E()}function fe(){return E()}var ze={cursor:z,claude:me,copilot:E,windsurf:fe,cline:pe};function H(e){let t=ze[e];if(!t)throw new Error(`No template for tool: ${e}`);return t()}function te(e){let t={force:false,merge:false,tools:[],dir:process.cwd()};for(let r=0;r<e.length;r++)switch(e[r]){case "--force":t.force=true;break;case "--merge":t.merge=true;break;case "--tool":{let o=e[++r];o&&t.tools.push(o);break}case "--dir":{let o=e[++r];o&&(t.dir=o);break}}return t}async function ge(e){let t=te(e);u.intro(d.bgCyan(d.black(" directive ai-rules ")));let r=ue(t.dir),s=t.dir;if(r.isMonorepo&&r.rootDir!==t.dir){let n=await u.select({message:"Monorepo detected. Where should AI rules be installed?",options:[{value:"root",label:`Monorepo root (${relative(t.dir,r.rootDir)||"."})`,hint:"recommended"},{value:"workspace",label:`Current workspace (${relative(r.rootDir,t.dir)})`}]});u.isCancel(n)&&(u.cancel("Cancelled."),process.exit(0)),n==="root"&&(s=r.rootDir);}let o;if(t.tools.length>0)o=t.tools.map(n=>{let a=L(n);return {name:a.name,id:a.id,outputPath:join(s,a.outputPath)}});else {let n=ae(s);if(n.length>0){let a=await u.multiselect({message:`Detected ${n.length} AI tool(s). Which should get Directive rules?`,options:n.map(c=>({value:c.id,label:c.name,hint:relative(s,c.outputPath)})),initialValues:n.map(c=>c.id),required:true});u.isCancel(a)&&(u.cancel("Cancelled."),process.exit(0)),o=a.map(c=>{let m=L(c);return {name:m.name,id:m.id,outputPath:join(s,m.outputPath)}});}else {let a=await u.multiselect({message:"No AI tools detected. Which tools do you use?",options:ce().map(c=>{let m=L(c);return {value:c,label:m.name}}),required:true});u.isCancel(a)&&(u.cancel("Cancelled."),process.exit(0)),o=a.map(c=>{let m=L(c);return {name:m.name,id:m.id,outputPath:join(s,m.outputPath)}});}}o.length===0&&(u.cancel("No tools selected."),process.exit(0));let i=u.spinner();for(let n of o){i.start(`Generating ${n.name} rules...`);let a=H(n.id),c=n.outputPath,m=existsSync(c);if(i.stop(`Generated ${n.name} rules.`),m&&!t.force){let w=readFileSync(c,"utf-8");if(t.merge){T(c,I(w,a)),u.log.success(`${d.green("Merged")} Directive section into ${d.dim(relative(s,c))}`);continue}if(P(w)){let f=await u.select({message:`${relative(s,c)} already has a Directive section. What should we do?`,options:[{value:"merge",label:"Update Directive section only",hint:"recommended"},{value:"overwrite",label:"Overwrite entire file"},{value:"skip",label:"Skip this file"}]});u.isCancel(f)&&(u.cancel("Cancelled."),process.exit(0)),f==="merge"?(T(c,I(w,a)),u.log.success(`${d.green("Updated")} ${d.dim(relative(s,c))}`)):f==="overwrite"?(T(c,a),u.log.success(`${d.green("Wrote")} ${d.dim(relative(s,c))}`)):u.log.info(`Skipped ${d.dim(relative(s,c))}`);}else {let f=await u.select({message:`${relative(s,c)} already exists. What should we do?`,options:[{value:"append",label:"Append Directive section",hint:"preserves existing content"},{value:"overwrite",label:"Overwrite entire file"},{value:"skip",label:"Skip this file"}]});u.isCancel(f)&&(u.cancel("Cancelled."),process.exit(0)),f==="append"?(T(c,I(w,a)),u.log.success(`${d.green("Appended")} to ${d.dim(relative(s,c))}`)):f==="overwrite"?(T(c,a),u.log.success(`${d.green("Wrote")} ${d.dim(relative(s,c))}`)):u.log.info(`Skipped ${d.dim(relative(s,c))}`);}}else T(c,a),u.log.success(`${d.green("Created")} ${d.dim(relative(s,c))}`);}u.outro(`Done! Run ${d.cyan(`${y} ai-rules init --merge`)} anytime to update.`);}function T(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}async function he(e){let r=te(e).dir,s=[{id:"cursor",path:join(r,".cursorrules")},{id:"claude",path:join(r,".claude/CLAUDE.md")},{id:"copilot",path:join(r,".github/copilot-instructions.md")},{id:"windsurf",path:join(r,".windsurfrules")},{id:"cline",path:join(r,".clinerules")}],o=0;for(let i of s){if(!existsSync(i.path))continue;let n=readFileSync(i.path,"utf-8");if(!P(n))continue;let a=H(i.id),c=I(n,a);T(i.path,c),console.log(`${d.green("Updated")} ${d.dim(relative(r,i.path))}`),o++;}console.log(o===0?d.dim(`No existing rule files found. Run ${d.cyan(`${y} ai-rules init`)} first.`):d.green(`
263
+ Updated ${o} file(s) to latest knowledge version.`));}async function ye(e){let r=te(e).dir,s=[{id:"cursor",path:join(r,".cursorrules"),name:"Cursor"},{id:"claude",path:join(r,".claude/CLAUDE.md"),name:"Claude Code"},{id:"copilot",path:join(r,".github/copilot-instructions.md"),name:"GitHub Copilot"},{id:"windsurf",path:join(r,".windsurfrules"),name:"Windsurf"},{id:"cline",path:join(r,".clinerules"),name:"Cline"}],o=0,i=0;for(let n of s){if(!existsSync(n.path))continue;let a=readFileSync(n.path,"utf-8");if(!P(a))continue;o++;let c=H(n.id);I(a,c)!==a?(console.log(`${d.red("\u2717")} ${n.name} rules are ${d.yellow("stale")}`),i++):console.log(`${d.green("\u2713")} ${n.name} rules are ${d.green("current")}`);}if(o===0){console.log(d.dim("No rule files found to check."));return}i>0?(console.log(`
264
264
  ${d.yellow(`${i} file(s) are stale.`)} Run ${d.cyan(`${y} ai-rules update`)} to refresh.`),process.exit(1)):console.log(d.green(`
265
- All rule files are current.`));}function Qe(e){let t={dir:process.cwd(),noInteractive:false};for(let r=0;r<e.length;r++)switch(e[r]){case "--template":{let o=e[++r];o&&(t.template=o);break}case "--dir":{let o=e[++r];o&&(t.dir=o);break}case "--no-interactive":t.noInteractive=true;break}return t}function Ze(e){return existsSync(join(e,"pnpm-lock.yaml"))?"pnpm":existsSync(join(e,"bun.lockb"))||existsSync(join(e,"bun.lock"))?"bun":existsSync(join(e,"yarn.lock"))?"yarn":"npm"}function et(e,t){switch(e){case "pnpm":return `pnpm add ${t}`;case "yarn":return `yarn add ${t}`;case "bun":return `bun add ${t}`;default:return `npm install ${t}`}}function ne(e){return {counter:{id:"counter",label:"Counter (minimal)",hint:"schema + init + derive + events \u2014 simplest starting point",files:[{path:`src/${e}.ts`,content:tt(e)},{path:"src/main.ts",content:rt(e)}],deps:["@directive-run/core"]},"auth-flow":{id:"auth-flow",label:"Auth flow (constraints + resolvers)",hint:"login flow with constraints, resolvers, retry, and effects",files:[{path:`src/${e}.ts`,content:st(e)},{path:"src/main.ts",content:nt(e)}],deps:["@directive-run/core"]},"ai-orchestrator":{id:"ai-orchestrator",label:"AI orchestrator",hint:"agent orchestrator with guardrails and streaming",files:[{path:`src/${e}.ts`,content:ot(e)},{path:"src/main.ts",content:it(e)}],deps:["@directive-run/core","@directive-run/ai"]}}}function tt(e){return `import { type ModuleSchema, createModule, t } from "@directive-run/core";
265
+ All rule files are current.`));}function Qe(e){let t={dir:process.cwd(),noInteractive:false};for(let r=0;r<e.length;r++)switch(e[r]){case "--template":{let o=e[++r];o&&(t.template=o);break}case "--dir":{let o=e[++r];o&&(t.dir=o);break}case "--no-interactive":t.noInteractive=true;break}return t}function Ze(e){return existsSync(join(e,"pnpm-lock.yaml"))?"pnpm":existsSync(join(e,"bun.lockb"))||existsSync(join(e,"bun.lock"))?"bun":existsSync(join(e,"yarn.lock"))?"yarn":"npm"}function et(e,t){switch(e){case "pnpm":return `pnpm add ${t}`;case "yarn":return `yarn add ${t}`;case "bun":return `bun add ${t}`;default:return `npm install ${t}`}}function re(e){return {counter:{id:"counter",label:"Counter (minimal)",hint:"schema + init + derive + events \u2014 simplest starting point",files:[{path:`src/${e}.ts`,content:tt(e)},{path:"src/main.ts",content:rt(e)}],deps:["@directive-run/core"]},"auth-flow":{id:"auth-flow",label:"Auth flow (constraints + resolvers)",hint:"login flow with constraints, resolvers, retry, and effects",files:[{path:`src/${e}.ts`,content:st(e)},{path:"src/main.ts",content:nt(e)}],deps:["@directive-run/core"]},"ai-orchestrator":{id:"ai-orchestrator",label:"AI orchestrator",hint:"agent orchestrator with guardrails and streaming",files:[{path:`src/${e}.ts`,content:ot(e)},{path:"src/main.ts",content:it(e)}],deps:["@directive-run/core","@directive-run/ai"]}}}function tt(e){return `import { type ModuleSchema, createModule, t } from "@directive-run/core";
266
266
 
267
267
  const schema = {
268
268
  facts: {
@@ -587,7 +587,7 @@ await system.settle();
587
587
  console.log("output:", system.facts.output);
588
588
 
589
589
  export default system;
590
- `}function j(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function at(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}async function ve(e){let t=Qe(e);u.intro(d.bgCyan(d.black(" directive init ")));let r;if(t.noInteractive)r="my-module";else {let f=await u.text({message:"Module name:",placeholder:"my-module",defaultValue:"my-module",validate:x=>{if(!/^[a-z][a-z0-9-]*$/.test(x))return "Must start with a letter, use lowercase letters, numbers, and hyphens"}});u.isCancel(f)&&(u.cancel("Cancelled."),process.exit(0)),r=f;}let s;if(t.template){let f=ne(r);t.template in f||(u.log.error(`Unknown template: ${t.template}. Available: ${Object.keys(f).join(", ")}`),process.exit(1)),s=t.template;}else if(t.noInteractive)s="counter";else {let f=ne(r),x=await u.select({message:"Project template:",options:Object.values(f).map(R=>({value:R.id,label:R.label,hint:R.hint}))});u.isCancel(x)&&(u.cancel("Cancelled."),process.exit(0)),s=x;}let i=ne(r)[s],n=Ze(t.dir);u.log.info(`Package manager: ${d.cyan(n)}`);let a=u.spinner();a.start("Creating project files...");let m=0;for(let f of i.files){let x=join(t.dir,f.path);if(existsSync(x)){m++;continue}at(x,f.content);}a.stop("Project files created.");for(let f of i.files){let x=join(t.dir,f.path),R=relative(t.dir,x);existsSync(x)&&u.log.success(`${d.green("Created")} ${d.dim(R)}`);}m>0&&u.log.warn(`Skipped ${m} file(s) that already exist.`);let w=et(n,i.deps.join(" "));u.outro(`Next steps:
590
+ `}function j(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function at(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}async function ve(e){let t=Qe(e);u.intro(d.bgCyan(d.black(" directive init ")));let r;if(t.noInteractive)r="my-module";else {let f=await u.text({message:"Module name:",placeholder:"my-module",defaultValue:"my-module",validate:x=>{if(!/^[a-z][a-z0-9-]*$/.test(x))return "Must start with a letter, use lowercase letters, numbers, and hyphens"}});u.isCancel(f)&&(u.cancel("Cancelled."),process.exit(0)),r=f;}let s;if(t.template){let f=re(r);t.template in f||(u.log.error(`Unknown template: ${t.template}. Available: ${Object.keys(f).join(", ")}`),process.exit(1)),s=t.template;}else if(t.noInteractive)s="counter";else {let f=re(r),x=await u.select({message:"Project template:",options:Object.values(f).map(R=>({value:R.id,label:R.label,hint:R.hint}))});u.isCancel(x)&&(u.cancel("Cancelled."),process.exit(0)),s=x;}let i=re(r)[s],n=Ze(t.dir);u.log.info(`Package manager: ${d.cyan(n)}`);let a=u.spinner();a.start("Creating project files...");let m=0;for(let f of i.files){let x=join(t.dir,f.path);if(existsSync(x)){m++;continue}at(x,f.content);}a.stop("Project files created.");for(let f of i.files){let x=join(t.dir,f.path),R=relative(t.dir,x);existsSync(x)&&u.log.success(`${d.green("Created")} ${d.dim(R)}`);}m>0&&u.log.warn(`Skipped ${m} file(s) that already exist.`);let w=et(n,i.deps.join(" "));u.outro(`Next steps:
591
591
  ${d.cyan(w)}
592
592
  ${d.cyan(`${y} ai-rules init`)}
593
593
  ${d.dim("Start building!")}`);}function be(e){let t={with:[],minimal:false,dir:process.cwd()};for(let r=0;r<e.length;r++)switch(e[r]){case "--with":{let o=e[++r];o&&(t.with=o.split(",").map(i=>i.trim()));break}case "--minimal":t.minimal=true;break;case "--dir":{let o=e[++r];o&&(t.dir=o);break}}return t}var we=["derive","events","constraints","resolvers","effects"];function dt(e,t){let r=xe(e),s=t.includes("constraints"),o=t.includes("resolvers"),n=`import { ${["type ModuleSchema","createModule","t"].join(", ")} } from "@directive-run/core";
@@ -790,7 +790,7 @@ export const memory = createAgentMemory({
790
790
  export const system = createSystem({
791
791
  module: ${t},
792
792
  });
793
- `}function xe(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function $e(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}function ke(e){return existsSync(join(e,"src"))?join(e,"src"):join(e,"src")}async function Se(e,t){let r=be(t);(!e||!/^[a-z][a-z0-9-]*$/.test(e))&&(console.error(`Invalid module name: ${e||"(none)"}
793
+ `}function xe(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function $e(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}function ke(e){return join(e,"src")}async function Se(e,t){let r=be(t);(!e||!/^[a-z][a-z0-9-]*$/.test(e))&&(console.error(`Invalid module name: ${e||"(none)"}
794
794
  Must start with a letter, use lowercase letters, numbers, and hyphens.`),process.exit(1));let s;r.minimal?s=[]:r.with.length>0?s=r.with.filter(c=>we.includes(c)):s=we;let o=ke(r.dir),i=join(o,`${e}.ts`);existsSync(i)&&(console.error(`File already exists: ${relative(r.dir,i)}`),process.exit(1));let n=dt(e,s);$e(i,n);let a=relative(r.dir,i);console.log(`${d.green("Created")} ${d.dim(a)}`),s.length===0?console.log(d.dim(" Minimal module (schema + init only)")):console.log(d.dim(` Sections: ${s.join(", ")}`));}async function Ce(e,t){let r=be(t);(!e||!/^[a-z][a-z0-9-]*$/.test(e))&&(console.error(`Invalid orchestrator name: ${e||"(none)"}
795
795
  Must start with a letter, use lowercase letters, numbers, and hyphens.`),process.exit(1));let s=ke(r.dir),o=join(s,`${e}.ts`);existsSync(o)&&(console.error(`File already exists: ${relative(r.dir,o)}`),process.exit(1));let i=mt(e);$e(o,i);let n=relative(r.dir,o);console.log(`${d.green("Created")} ${d.dim(n)}`),console.log(d.dim(" AI orchestrator with memory, guardrails, and streaming"));}async function U(e){let t=resolve(e);if(!existsSync(t))throw new Error(`File not found: ${t}`);try{let r=await import(t);if(r.default&&oe(r.default))return r.default;if(r.system&&oe(r.system))return r.system;for(let s of Object.keys(r))if(oe(r[s]))return r[s];throw new Error(`No Directive system found in ${d.dim(e)}
796
796
  Export a system as default or named "system":
@@ -813,7 +813,7 @@ Make sure the file is valid TypeScript and tsx is installed:
813
813
 
814
814
  Current requirements:`),o.unmet.length===0)console.log(d.dim(" (no unmet requirements)"));else for(let n of o.unmet)console.log(` ${d.cyan(n.id)} \u2014 ${n.requirement.type} (from ${n.fromConstraint})`);s.stop(),process.exit(1);}console.log(),console.log(d.bold(d.cyan("Requirement Explanation"))),console.log(d.dim("\u2500".repeat(40))),console.log(),console.log(i),console.log();}else if(console.log(),console.log(d.bold(d.cyan("All Requirements"))),console.log(d.dim("\u2500".repeat(40))),console.log(),o.unmet.length===0){console.log(d.green("All requirements are met.")),console.log();let i=Object.entries(o.resolvers);if(i.length>0){console.log(d.bold("Recent Resolver Activity:"));for(let[n,a]of i){let c=Re(a.state),m=a.duration!==void 0?` (${a.duration}ms)`:"";console.log(` ${d.cyan(n)} ${c}${m}`);}console.log();}}else {console.log(`${d.yellow(String(o.unmet.length))} unmet requirement(s):
815
815
  `);for(let i of o.unmet){console.log(`${d.yellow("\u25CF")} ${d.bold(i.requirement.type)} (id: ${d.dim(i.id)})`),console.log(` From constraint: ${d.cyan(i.fromConstraint)}`);let n={...i.requirement};delete n.type,Object.keys(n).length>0&&console.log(` Payload: ${JSON.stringify(n)}`);let c=o.resolvers[i.id];c?console.log(` Resolver: ${Re(c.state)}${c.error?` \u2014 ${c.error}`:""}`):o.resolverDefs.some(w=>w.requirement===i.requirement.type||w.requirement==="(predicate)")||console.log(` ${d.red("No resolver registered for this type")}`),console.log();}console.log(d.dim(`Run ${d.cyan("directive explain <file> <requirement-id>")} for detailed explanation.`));}s.stop();}function Re(e){switch(e){case "resolved":return d.green("resolved");case "errored":return d.red("errored");case "inflight":return d.yellow("inflight");case "pending":return d.yellow("pending");case "cancelled":return d.dim("cancelled");default:return d.dim(e)}}function Rt(e){let t={ascii:false,open:true},r="";for(let s=0;s<e.length;s++){let o=e[s];switch(o){case "--ascii":t.ascii=true;break;case "--no-open":t.open=false;break;case "--output":{let i=e[++s];i&&(t.output=i);break}default:o&&!o.startsWith("-")&&!r&&(r=o);}}return {filePath:r,opts:t}}function Tt(e){let t=[];t.push(d.bold("Dependency Graph")),t.push(d.dim("\u2550".repeat(50))),t.push("");let r=new Map;for(let a of e.constraints)r.set(a.id,{reqTypes:new Set,active:a.active,priority:a.priority});for(let a of e.unmet){let c=r.get(a.fromConstraint);c&&c.reqTypes.add(a.requirement.type);}let s=new Map;for(let a of e.resolverDefs)s.has(a.requirement)||s.set(a.requirement,[]),s.get(a.requirement).push(a.id);t.push(d.bold("Constraints \u2192 Requirements \u2192 Resolvers")),t.push("");for(let[a,c]of r){let m=c.active?d.green("\u25CF"):d.dim("\u25CB");if(t.push(`${m} ${d.cyan(a)} (priority: ${c.priority})`),c.reqTypes.size>0)for(let w of c.reqTypes){t.push(` \u2514\u2500\u25B6 ${d.yellow(w)}`);let f=s.get(w)||[];if(f.length>0)for(let x of f)t.push(` \u2514\u2500\u25B6 ${d.magenta(x)}`);else t.push(` \u2514\u2500\u25B6 ${d.red("(no resolver)")}`);}else t.push(` \u2514\u2500\u25B6 ${d.dim("(no active requirements)")}`);t.push("");}let o=new Set;for(let a of s.values())for(let c of a)o.add(c);if(e.resolverDefs.map(a=>a.id).filter(a=>!o.has(a)).length>0){t.push(d.bold("Standalone Resolvers:"));for(let a of e.resolverDefs)o.has(a.id)||t.push(` ${d.magenta(a.id)} handles ${d.yellow(a.requirement)}`);}return t.join(`
816
- `)}function Mt(e,t){let r=[],s=[],c=Object.keys(t);for(let l=0;l<c.length;l++){let b=c[l];r.push({id:`fact-${b}`,label:b,type:"fact",x:40,y:60+l*50,color:"#3b82f6"});}for(let l=0;l<e.constraints.length;l++){let b=e.constraints[l];r.push({id:`constraint-${b.id}`,label:b.id,type:"constraint",x:260,y:60+l*50,color:b.active?"#22c55e":"#6b7280"});}let m=new Set;for(let l of e.unmet)m.add(l.requirement.type);let w=0;for(let l of m)r.push({id:`req-${l}`,label:l,type:"requirement",x:480,y:60+w*50,color:"#eab308"}),w++;for(let l=0;l<e.resolverDefs.length;l++){let b=e.resolverDefs[l];r.push({id:`resolver-${b.id}`,label:b.id,type:"resolver",x:700,y:60+l*50,color:"#a855f7"});}for(let l of e.unmet)s.push({from:`constraint-${l.fromConstraint}`,to:`req-${l.requirement.type}`});for(let l of e.resolverDefs)m.has(l.requirement)&&s.push({from:`req-${l.requirement}`,to:`resolver-${l.id}`});let f=new Map(r.map(l=>[l.id,l])),x=960,R=Math.max(...r.map(l=>l.y))+50+20,Ne=s.map(l=>{let b=f.get(l.from),V=f.get(l.to);return !b||!V?"":`<line x1="${b.x+90}" y1="${b.y+15}" x2="${V.x}" y2="${V.y+15}" stroke="#94a3b8" stroke-width="1.5" marker-end="url(#arrow)"/>`}).join(`
816
+ `)}function Mt(e,t){let r=[],s=[],c=Object.keys(t);for(let l=0;l<c.length;l++){let b=c[l];r.push({id:`fact-${b}`,label:b,type:"fact",x:40,y:60+l*50,color:"#3b82f6"});}for(let l=0;l<e.constraints.length;l++){let b=e.constraints[l];r.push({id:`constraint-${b.id}`,label:b.id,type:"constraint",x:260,y:60+l*50,color:b.active?"#22c55e":"#6b7280"});}let m=new Set;for(let l of e.unmet)m.add(l.requirement.type);let w=0;for(let l of m)r.push({id:`req-${l}`,label:l,type:"requirement",x:480,y:60+w*50,color:"#eab308"}),w++;for(let l=0;l<e.resolverDefs.length;l++){let b=e.resolverDefs[l];r.push({id:`resolver-${b.id}`,label:b.id,type:"resolver",x:700,y:60+l*50,color:"#a855f7"});}for(let l of e.unmet)s.push({from:`constraint-${l.fromConstraint}`,to:`req-${l.requirement.type}`});for(let l of e.resolverDefs)m.has(l.requirement)&&s.push({from:`req-${l.requirement}`,to:`resolver-${l.id}`});let f=new Map(r.map(l=>[l.id,l])),x=960,R=Math.max(...r.map(l=>l.y))+50+20,Ne=s.map(l=>{let b=f.get(l.from),X=f.get(l.to);return !b||!X?"":`<line x1="${b.x+90}" y1="${b.y+15}" x2="${X.x}" y2="${X.y+15}" stroke="#94a3b8" stroke-width="1.5" marker-end="url(#arrow)"/>`}).join(`
817
817
  `),je=r.map(l=>`<g>
818
818
  <rect x="${l.x}" y="${l.y}" width="180" height="30" rx="6" fill="${l.color}" opacity="0.15" stroke="${l.color}" stroke-width="1.5"/>
819
819
  <text x="${l.x+90}" y="${l.y+19}" text-anchor="middle" font-size="12" font-family="monospace" fill="${l.color}">${qt(l.label)}</text>
@@ -840,7 +840,7 @@ Current requirements:`),o.unmet.length===0)console.log(d.dim(" (no unmet requir
840
840
  ${je}
841
841
  </svg>
842
842
  </body>
843
- </html>`}function qt(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function Me(e){let{filePath:t,opts:r}=Rt(e);t||(console.error("Usage: directive graph <file> [--ascii] [--no-open] [--output <path>]"),process.exit(1));let s=await U(t);s.isRunning||s.start();let o=s.inspect();if(r.ascii){console.log(Tt(o)),s.stop();return}let i={};if(s.facts)for(let c of Object.keys(s.facts))try{i[c]=s.facts[c];}catch{i[c]=null;}let n=Mt(o,i),a=r.output||join(process.cwd(),".directive-graph.html");if(writeFileSync(a,n,"utf-8"),console.log(`${d.green("Generated")} ${d.dim(a)}`),r.open)try{let{exec:c}=await import('child_process'),m=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";c(`${m} "${a}"`),console.log(d.dim("Opened in browser."));}catch{console.log(d.dim(`Open ${a} in your browser to view the graph.`));}s.stop();}function Dt(e){let t={dir:process.cwd()};for(let r=0;r<e.length;r++)if(e[r]==="--dir"){let s=e[++r];s&&(t.dir=s);}return t}function It(e){let t=join(e,"package.json");if(!existsSync(t))return {label:"@directive-run/core installed",passed:false,message:"No package.json found",fix:"Run `npm init` to create a package.json"};let r=JSON.parse(readFileSync(t,"utf-8")),s={...r.dependencies,...r.devDependencies};return s["@directive-run/core"]?{label:"@directive-run/core installed",passed:true,message:`v${s["@directive-run/core"]}`}:{label:"@directive-run/core installed",passed:false,message:"Not found in dependencies",fix:"Run `npm install @directive-run/core`"}}function Pt(e){let t=join(e,"package.json");if(!existsSync(t))return {label:"Package version compatibility",passed:true,message:"Skipped (no package.json)"};let r=JSON.parse(readFileSync(t,"utf-8")),s={...r.dependencies,...r.devDependencies},o=Object.keys(s).filter(i=>i.startsWith("@directive-run/"));return o.length<=1?{label:"Package version compatibility",passed:true,message:o.length===0?"No packages found":"Single package"}:{label:"Package version compatibility",passed:true,message:`${o.length} packages: ${o.join(", ")}`}}function Et(e){let t=join(e,"tsconfig.json");if(!existsSync(t))return {label:"TypeScript configuration",passed:false,message:"No tsconfig.json found",fix:"Run `tsc --init` to create a TypeScript configuration"};try{let s=readFileSync(t,"utf-8").replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,""),i=JSON.parse(s).compilerOptions||{},n=[];return i.strict!==!0&&n.push("strict mode not enabled"),i.moduleResolution&&!["bundler","nodenext","node16"].includes(i.moduleResolution.toLowerCase())&&n.push(`moduleResolution is "${i.moduleResolution}"`),n.length>0?{label:"TypeScript configuration",passed:!1,message:n.join(", "),fix:'Set "strict": true and "moduleResolution": "bundler" in tsconfig.json'}:{label:"TypeScript configuration",passed:!0,message:"strict mode, correct module resolution"}}catch{return {label:"TypeScript configuration",passed:true,message:"Found (could not parse for detailed checks)"}}}function Nt(e){let t=join(e,"node_modules");if(!existsSync(t))return {label:"No duplicate Directive instances",passed:true,message:"No node_modules found"};let r=[];try{let s=join(t,"@directive-run");if(existsSync(s)){let o=readdirSync(s);for(let i of o){let n=join(s,i,"node_modules","@directive-run","core");existsSync(n)&&r.push(`@directive-run/${i}/node_modules/@directive-run/core`);}}}catch{}return r.length>0?{label:"No duplicate Directive instances",passed:false,message:`Found ${r.length} duplicate(s): ${r.join(", ")}`,fix:"Run `npm dedupe` or check for version mismatches"}:{label:"No duplicate Directive instances",passed:true,message:"No duplicates detected"}}function jt(e){let t=[".cursorrules",".claude/CLAUDE.md",".github/copilot-instructions.md",".windsurfrules",".clinerules"],r=[];for(let s of t){let o=join(e,s);if(existsSync(o)){let i=readFileSync(o,"utf-8");P(i)&&r.push(s);}}return r.length===0?{label:"AI coding rules",passed:true,message:"Not installed (optional)"}:{label:"AI coding rules",passed:true,message:`Installed for: ${r.join(", ")}`}}async function qe(e){let t=Dt(e);console.log(),console.log(d.bold(d.cyan("Directive Doctor"))),console.log(d.dim("\u2500".repeat(40))),console.log();let r=[It(t.dir),Pt(t.dir),Et(t.dir),Nt(t.dir),jt(t.dir)],s=0;for(let o of r){let i=o.passed?d.green("\u2713"):d.red("\u2717");console.log(`${i} ${d.bold(o.label)}`),console.log(` ${d.dim(o.message)}`),!o.passed&&o.fix&&(console.log(` ${d.yellow("Fix:")} ${o.fix}`),s++),console.log();}s>0?(console.log(d.yellow(`${s} issue(s) found. See suggested fixes above.`)),process.exit(1)):console.log(d.green("All checks passed!"));}var Ie={"Getting Started":["counter","contact-form","auth-flow"],"Core Patterns":["async-chains","batch-resolver","debounce-constraints","error-boundaries","feature-flags","multi-module","optimistic-updates","pagination","permissions"],"Real-World":["dashboard-loader","form-wizard","newsletter","notifications","shopping-cart","theme-locale","url-sync","websocket","server"],Games:["checkers","sudoku","goal-heist","ab-testing"],AI:["ai-orchestrator","ai-checkpoint","ai-guardrails","fraud-analysis","provider-routing","topic-guard","dynamic-modules","time-machine"]};function Ft(e){for(let[t,r]of Object.entries(Ie))if(r.includes(e))return t;return "Other"}function _t(e){let t=e.split(`
843
+ </html>`}function qt(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function Me(e){let{filePath:t,opts:r}=Rt(e);t||(console.error("Usage: directive graph <file> [--ascii] [--no-open] [--output <path>]"),process.exit(1));let s=await U(t);s.isRunning||s.start();let o=s.inspect();if(r.ascii){console.log(Tt(o)),s.stop();return}let i={};if(s.facts)for(let c of Object.keys(s.facts))try{i[c]=s.facts[c];}catch{i[c]=null;}let n=Mt(o,i),a=r.output||join(process.cwd(),".directive-graph.html");if(writeFileSync(a,n,"utf-8"),console.log(`${d.green("Generated")} ${d.dim(a)}`),r.open)try{let{execFile:c}=await import('child_process'),m=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";c(m,[a]),console.log(d.dim("Opened in browser."));}catch{console.log(d.dim(`Open ${a} in your browser to view the graph.`));}s.stop();}function Dt(e){let t={dir:process.cwd()};for(let r=0;r<e.length;r++)if(e[r]==="--dir"){let s=e[++r];s&&(t.dir=s);}return t}function It(e){let t=join(e,"package.json");if(!existsSync(t))return {label:"@directive-run/core installed",passed:false,message:"No package.json found",fix:"Run `npm init` to create a package.json"};let r=JSON.parse(readFileSync(t,"utf-8")),s={...r.dependencies,...r.devDependencies};return s["@directive-run/core"]?{label:"@directive-run/core installed",passed:true,message:`v${s["@directive-run/core"]}`}:{label:"@directive-run/core installed",passed:false,message:"Not found in dependencies",fix:"Run `npm install @directive-run/core`"}}function Pt(e){let t=join(e,"package.json");if(!existsSync(t))return {label:"Package version compatibility",passed:true,message:"Skipped (no package.json)"};let r=JSON.parse(readFileSync(t,"utf-8")),s={...r.dependencies,...r.devDependencies},o=Object.keys(s).filter(i=>i.startsWith("@directive-run/"));return o.length<=1?{label:"Package version compatibility",passed:true,message:o.length===0?"No packages found":"Single package"}:{label:"Package version compatibility",passed:true,message:`${o.length} packages: ${o.join(", ")}`}}function Et(e){let t=join(e,"tsconfig.json");if(!existsSync(t))return {label:"TypeScript configuration",passed:false,message:"No tsconfig.json found",fix:"Run `tsc --init` to create a TypeScript configuration"};try{let s=readFileSync(t,"utf-8").replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,""),i=JSON.parse(s).compilerOptions||{},n=[];return i.strict!==!0&&n.push("strict mode not enabled"),i.moduleResolution&&!["bundler","nodenext","node16"].includes(i.moduleResolution.toLowerCase())&&n.push(`moduleResolution is "${i.moduleResolution}"`),n.length>0?{label:"TypeScript configuration",passed:!1,message:n.join(", "),fix:'Set "strict": true and "moduleResolution": "bundler" in tsconfig.json'}:{label:"TypeScript configuration",passed:!0,message:"strict mode, correct module resolution"}}catch{return {label:"TypeScript configuration",passed:true,message:"Found (could not parse for detailed checks)"}}}function Nt(e){let t=join(e,"node_modules");if(!existsSync(t))return {label:"No duplicate Directive instances",passed:true,message:"No node_modules found"};let r=[];try{let s=join(t,"@directive-run");if(existsSync(s)){let o=readdirSync(s);for(let i of o){let n=join(s,i,"node_modules","@directive-run","core");existsSync(n)&&r.push(`@directive-run/${i}/node_modules/@directive-run/core`);}}}catch{}return r.length>0?{label:"No duplicate Directive instances",passed:false,message:`Found ${r.length} duplicate(s): ${r.join(", ")}`,fix:"Run `npm dedupe` or check for version mismatches"}:{label:"No duplicate Directive instances",passed:true,message:"No duplicates detected"}}function jt(e){let t=[".cursorrules",".claude/CLAUDE.md",".github/copilot-instructions.md",".windsurfrules",".clinerules"],r=[];for(let s of t){let o=join(e,s);if(existsSync(o)){let i=readFileSync(o,"utf-8");P(i)&&r.push(s);}}return r.length===0?{label:"AI coding rules",passed:true,message:"Not installed (optional)"}:{label:"AI coding rules",passed:true,message:`Installed for: ${r.join(", ")}`}}async function qe(e){let t=Dt(e);console.log(),console.log(d.bold(d.cyan("Directive Doctor"))),console.log(d.dim("\u2500".repeat(40))),console.log();let r=[It(t.dir),Pt(t.dir),Et(t.dir),Nt(t.dir),jt(t.dir)],s=0;for(let o of r){let i=o.passed?d.green("\u2713"):d.red("\u2717");console.log(`${i} ${d.bold(o.label)}`),console.log(` ${d.dim(o.message)}`),!o.passed&&o.fix&&(console.log(` ${d.yellow("Fix:")} ${o.fix}`),s++),console.log();}s>0?(console.log(d.yellow(`${s} issue(s) found. See suggested fixes above.`)),process.exit(1)):console.log(d.green("All checks passed!"));}var Ie={"Getting Started":["counter","contact-form","auth-flow"],"Core Patterns":["async-chains","batch-resolver","debounce-constraints","error-boundaries","feature-flags","multi-module","optimistic-updates","pagination","permissions"],"Real-World":["dashboard-loader","form-wizard","newsletter","notifications","shopping-cart","theme-locale","url-sync","websocket","server"],Games:["checkers","sudoku","goal-heist","ab-testing"],AI:["ai-orchestrator","ai-checkpoint","ai-guardrails","fraud-analysis","provider-routing","topic-guard","dynamic-modules","time-machine"]};function Ft(e){for(let[t,r]of Object.entries(Ie))if(r.includes(e))return t;return "Other"}function _t(e){let t=e.split(`
844
844
  `);for(let r of t){let s=r.trim();if(s.startsWith("// Example:")||s.startsWith("// Source:")||s.startsWith("// Extracted"))continue;let o=s.match(/^\*\s+(.+?)(?:\s*\*\/)?$/);if(o?.[1]&&!o[1].startsWith("@"))return o[1];if(s.startsWith("//")&&s.length>3)return s.slice(2).trim();if(s!==""&&!s.startsWith("//")&&!s.startsWith("/*")&&!s.startsWith("*"))break}return ""}async function Pe(e){let t;for(let n=0;n<e.length;n++)e[n]==="--filter"&&(t=e[++n]?.toLowerCase());let r=getAllExamples();console.log(),console.log(d.bold(d.cyan("Directive Examples"))),console.log(d.dim("\u2500".repeat(50))),console.log();let s=new Map;for(let[n,a]of r){let c=Ft(n);t&&!c.toLowerCase().includes(t)&&!n.includes(t)||(s.has(c)||s.set(c,[]),s.get(c).push({name:n,desc:_t(a)}));}if(s.size===0){console.log(d.dim("No examples match the filter."));return}let o=Object.keys(Ie),i=[...s.keys()].sort((n,a)=>(o.indexOf(n)??99)-(o.indexOf(a)??99));for(let n of i){let a=s.get(n);console.log(d.bold(n));for(let c of a){let m=c.desc?d.dim(` \u2014 ${c.desc}`):"";console.log(` ${d.cyan(c.name)}${m}`);}console.log();}console.log(d.dim(`${r.size} examples available. Run ${d.cyan("directive examples copy <name>")} to extract one.`));}async function Ee(e,t){let r=process.cwd();for(let c=0;c<t.length;c++)if(t[c]==="--dest"){let m=t[++c];m&&(r=m);}e||(console.error("Usage: directive examples copy <name> [--dest <dir>]"),process.exit(1));let s=getExample(e);s||(console.error(`Example "${e}" not found.`),console.error(`Run ${d.cyan("directive examples list")} to see available examples.`),process.exit(1));let o=s.replace(/from\s+["']@directive-run\/core\/plugins["']/g,'from "@directive-run/core/plugins"').replace(/from\s+["']@directive-run\/core["']/g,'from "@directive-run/core"').replace(/from\s+["']@directive-run\/ai["']/g,'from "@directive-run/ai"'),i=join(r,`${e}.ts`);existsSync(i)&&(console.error(`File already exists: ${relative(process.cwd(),i)}`),process.exit(1));let n=dirname(i);existsSync(n)||mkdirSync(n,{recursive:true}),writeFileSync(i,o,"utf-8");let a=relative(process.cwd(),i);console.log(`${d.green("Copied")} ${d.cyan(e)} \u2192 ${d.dim(a)}`);}var zt=`
845
845
  ${y} \u2014 CLI tools for Directive
846
846