@directive-run/cli 1.6.1 → 1.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/dist/cli.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import {existsSync,readFileSync,mkdirSync,writeFileSync,readdirSync}from'fs';import {resolve,join,relative,dirname}from'path';import*as m from'@clack/prompts';import g from'picocolors';import {getAllExamples,getExample,getKnowledge}from'@directive-run/knowledge';var R="directive";var ue="<!-- directive:start -->",re="<!-- directive:end -->";var ke=[{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 Fe(e){let t=[];for(let r of ke)r.signals.some(n=>existsSync(join(e,n)))&&t.push({name:r.name,id:r.id,outputPath:join(e,r.outputPath)});return t}function ne(e){let t=ke.find(r=>r.id===e);if(!t)throw new Error(`Unknown tool: ${e}`);return t}function ze(){return ke.map(e=>e.id)}function H(e,t){let r=e.indexOf(ue),s=e.indexOf(re),n=`${ue}
2
+ import {existsSync,readFileSync,mkdirSync,writeFileSync,readdirSync}from'fs';import {resolve,join,relative,dirname}from'path';import*as m from'@clack/prompts';import g from'picocolors';import {getAllExamples,getExample,getKnowledge}from'@directive-run/knowledge';var C="directive";var me="<!-- directive:start -->",ie="<!-- directive:end -->";var De=[{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 Ke(e){let t=[];for(let r of De)r.signals.some(n=>existsSync(join(e,n)))&&t.push({name:r.name,id:r.id,outputPath:join(e,r.outputPath)});return t}function oe(e){let t=De.find(r=>r.id===e);if(!t)throw new Error(`Unknown tool: ${e}`);return t}function Je(){return De.map(e=>e.id)}function Z(e,t){let r=e.indexOf(me),s=e.indexOf(ie),n=`${me}
3
3
  ${t}
4
- ${re}`;if(r!==-1&&s!==-1&&s>r)return e.slice(0,r)+n+e.slice(s+re.length);let o=e.endsWith(`
4
+ ${ie}`;if(r!==-1&&s!==-1&&s>r)return e.slice(0,r)+n+e.slice(s+ie.length);let o=e.endsWith(`
5
5
  `)?`
6
6
  `:`
7
7
 
8
8
  `;return e+o+n+`
9
- `}function V(e){return e.includes(ue)&&e.includes(re)}var Nt=[{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 Nt)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 n=existsSync(join(t,"yarn.lock"))?"yarn":"npm";return {isMonorepo:!0,rootDir:t,tool:n}}}catch{}t=dirname(t);}return {isMonorepo:false,rootDir:e}}function Be(){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 Q(e){return e.includes(me)&&e.includes(ie)}var Ht=[{file:"pnpm-workspace.yaml",tool:"pnpm"},{file:"turbo.json",tool:"turbo"}];function He(e){let t=resolve(e);for(;t!==dirname(t);){for(let s of Ht)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 n=existsSync(join(t,"yarn.lock"))?"yarn":"npm";return {isMonorepo:!0,rootDir:t,tool:n}}}catch{}t=dirname(t);}return {isMonorepo:false,rootDir:e}}function Ye(){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 fe(){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 Y(){return fe()+"\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"+`
229
+ `}function ge(){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 ee(){return ge()+"\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,21 +259,21 @@ 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 Le(){return Y()}function Ke(){return Y()}var zt={cursor:fe,claude:Be,copilot:Y,windsurf:Ke,cline:Le};function de(e){let t=zt[e];if(!t)throw new Error(`No template for tool: ${e}`);return t()}function De(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 n=e[++r];n&&t.tools.push(n);break}case "--dir":{let n=e[++r];n&&(t.dir=n);break}}return t}async function Je(e){let t=De(e);m.intro(g.bgCyan(g.black(" directive ai-rules ")));let r=Ue(t.dir),s=t.dir;if(r.isMonorepo&&r.rootDir!==t.dir){let i=await m.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)})`}]});m.isCancel(i)&&(m.cancel("Cancelled."),process.exit(0)),i==="root"&&(s=r.rootDir);}let n;if(t.tools.length>0)n=t.tools.map(i=>{let a=ne(i);return {name:a.name,id:a.id,outputPath:join(s,a.outputPath)}});else {let i=Fe(s);if(i.length>0){let a=await m.multiselect({message:`Detected ${i.length} AI tool(s). Which should get Directive rules?`,options:i.map(l=>({value:l.id,label:l.name,hint:relative(s,l.outputPath)})),initialValues:i.map(l=>l.id),required:true});m.isCancel(a)&&(m.cancel("Cancelled."),process.exit(0)),n=a.map(l=>{let c=ne(l);return {name:c.name,id:c.id,outputPath:join(s,c.outputPath)}});}else {let a=await m.multiselect({message:"No AI tools detected. Which tools do you use?",options:ze().map(l=>{let c=ne(l);return {value:l,label:c.name}}),required:true});m.isCancel(a)&&(m.cancel("Cancelled."),process.exit(0)),n=a.map(l=>{let c=ne(l);return {name:c.name,id:c.id,outputPath:join(s,c.outputPath)}});}}n.length===0&&(m.cancel("No tools selected."),process.exit(0));let o=m.spinner();for(let i of n){o.start(`Generating ${i.name} rules...`);let a=de(i.id),l=i.outputPath,c=existsSync(l);if(o.stop(`Generated ${i.name} rules.`),c&&!t.force){let f=readFileSync(l,"utf-8");if(t.merge){_(l,H(f,a)),m.log.success(`${g.green("Merged")} Directive section into ${g.dim(relative(s,l))}`);continue}if(V(f)){let u=await m.select({message:`${relative(s,l)} 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"}]});m.isCancel(u)&&(m.cancel("Cancelled."),process.exit(0)),u==="merge"?(_(l,H(f,a)),m.log.success(`${g.green("Updated")} ${g.dim(relative(s,l))}`)):u==="overwrite"?(_(l,a),m.log.success(`${g.green("Wrote")} ${g.dim(relative(s,l))}`)):m.log.info(`Skipped ${g.dim(relative(s,l))}`);}else {let u=await m.select({message:`${relative(s,l)} 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"}]});m.isCancel(u)&&(m.cancel("Cancelled."),process.exit(0)),u==="append"?(_(l,H(f,a)),m.log.success(`${g.green("Appended")} to ${g.dim(relative(s,l))}`)):u==="overwrite"?(_(l,a),m.log.success(`${g.green("Wrote")} ${g.dim(relative(s,l))}`)):m.log.info(`Skipped ${g.dim(relative(s,l))}`);}}else _(l,a),m.log.success(`${g.green("Created")} ${g.dim(relative(s,l))}`);}m.outro(`Done! Run ${g.cyan(`${R} ai-rules init --merge`)} anytime to update.`);}function _(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}async function Ge(e){let r=De(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")}],n=0;for(let o of s){if(!existsSync(o.path))continue;let i=readFileSync(o.path,"utf-8");if(!V(i))continue;let a=de(o.id),l=H(i,a);_(o.path,l),console.log(`${g.green("Updated")} ${g.dim(relative(r,o.path))}`),n++;}console.log(n===0?g.dim(`No existing rule files found. Run ${g.cyan(`${R} ai-rules init`)} first.`):g.green(`
263
- Updated ${n} file(s) to latest knowledge version.`));}async function He(e){let r=De(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"}],n=0,o=0;for(let i of s){if(!existsSync(i.path))continue;let a=readFileSync(i.path,"utf-8");if(!V(a))continue;n++;let l=de(i.id);H(a,l)!==a?(console.log(`${g.red("\u2717")} ${i.name} rules are ${g.yellow("stale")}`),o++):console.log(`${g.green("\u2713")} ${i.name} rules are ${g.green("current")}`);}if(n===0){console.log(g.dim("No rule files found to check."));return}o>0?(console.log(`
264
- ${g.yellow(`${o} file(s) are stale.`)} Run ${g.cyan(`${R} ai-rules update`)} to refresh.`),process.exit(1)):console.log(g.green(`
265
- All rule files are current.`));}async function P(e){let t=resolve(e);if(!existsSync(t))throw new Error(`File not found: ${t}`);try{let r=await import(t);if(r.default&&U(r.default))return r.default;if(r.system&&U(r.system))return r.system;for(let s of Object.keys(r))if(U(r[s]))return r[s];throw new Error(`No Directive system found in ${g.dim(e)}
262
+ `}function Xe(){return ee()}function Ze(){return ee()}var Yt={cursor:ge,claude:Ye,copilot:ee,windsurf:Ze,cline:Xe};function he(e){let t=Yt[e];if(!t)throw new Error(`No template for tool: ${e}`);return t()}function qe(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 n=e[++r];n&&t.tools.push(n);break}case "--dir":{let n=e[++r];n&&(t.dir=n);break}}return t}async function Qe(e){let t=qe(e);m.intro(g.bgCyan(g.black(" directive ai-rules ")));let r=He(t.dir),s=t.dir;if(r.isMonorepo&&r.rootDir!==t.dir){let i=await m.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)})`}]});m.isCancel(i)&&(m.cancel("Cancelled."),process.exit(0)),i==="root"&&(s=r.rootDir);}let n;if(t.tools.length>0)n=t.tools.map(i=>{let a=oe(i);return {name:a.name,id:a.id,outputPath:join(s,a.outputPath)}});else {let i=Ke(s);if(i.length>0){let a=await m.multiselect({message:`Detected ${i.length} AI tool(s). Which should get Directive rules?`,options:i.map(l=>({value:l.id,label:l.name,hint:relative(s,l.outputPath)})),initialValues:i.map(l=>l.id),required:true});m.isCancel(a)&&(m.cancel("Cancelled."),process.exit(0)),n=a.map(l=>{let c=oe(l);return {name:c.name,id:c.id,outputPath:join(s,c.outputPath)}});}else {let a=await m.multiselect({message:"No AI tools detected. Which tools do you use?",options:Je().map(l=>{let c=oe(l);return {value:l,label:c.name}}),required:true});m.isCancel(a)&&(m.cancel("Cancelled."),process.exit(0)),n=a.map(l=>{let c=oe(l);return {name:c.name,id:c.id,outputPath:join(s,c.outputPath)}});}}n.length===0&&(m.cancel("No tools selected."),process.exit(0));let o=m.spinner();for(let i of n){o.start(`Generating ${i.name} rules...`);let a=he(i.id),l=i.outputPath,c=existsSync(l);if(o.stop(`Generated ${i.name} rules.`),c&&!t.force){let d=readFileSync(l,"utf-8");if(t.merge){K(l,Z(d,a)),m.log.success(`${g.green("Merged")} Directive section into ${g.dim(relative(s,l))}`);continue}if(Q(d)){let u=await m.select({message:`${relative(s,l)} 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"}]});m.isCancel(u)&&(m.cancel("Cancelled."),process.exit(0)),u==="merge"?(K(l,Z(d,a)),m.log.success(`${g.green("Updated")} ${g.dim(relative(s,l))}`)):u==="overwrite"?(K(l,a),m.log.success(`${g.green("Wrote")} ${g.dim(relative(s,l))}`)):m.log.info(`Skipped ${g.dim(relative(s,l))}`);}else {let u=await m.select({message:`${relative(s,l)} 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"}]});m.isCancel(u)&&(m.cancel("Cancelled."),process.exit(0)),u==="append"?(K(l,Z(d,a)),m.log.success(`${g.green("Appended")} to ${g.dim(relative(s,l))}`)):u==="overwrite"?(K(l,a),m.log.success(`${g.green("Wrote")} ${g.dim(relative(s,l))}`)):m.log.info(`Skipped ${g.dim(relative(s,l))}`);}}else K(l,a),m.log.success(`${g.green("Created")} ${g.dim(relative(s,l))}`);}m.outro(`Done! Run ${g.cyan(`${C} ai-rules init --merge`)} anytime to update.`);}function K(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}async function et(e){let r=qe(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")}],n=0;for(let o of s){if(!existsSync(o.path))continue;let i=readFileSync(o.path,"utf-8");if(!Q(i))continue;let a=he(o.id),l=Z(i,a);K(o.path,l),console.log(`${g.green("Updated")} ${g.dim(relative(r,o.path))}`),n++;}console.log(n===0?g.dim(`No existing rule files found. Run ${g.cyan(`${C} ai-rules init`)} first.`):g.green(`
263
+ Updated ${n} file(s) to latest knowledge version.`));}async function tt(e){let r=qe(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"}],n=0,o=0;for(let i of s){if(!existsSync(i.path))continue;let a=readFileSync(i.path,"utf-8");if(!Q(a))continue;n++;let l=he(i.id);Z(a,l)!==a?(console.log(`${g.red("\u2717")} ${i.name} rules are ${g.yellow("stale")}`),o++):console.log(`${g.green("\u2713")} ${i.name} rules are ${g.green("current")}`);}if(n===0){console.log(g.dim("No rule files found to check."));return}o>0?(console.log(`
264
+ ${g.yellow(`${o} file(s) are stale.`)} Run ${g.cyan(`${C} ai-rules update`)} to refresh.`),process.exit(1)):console.log(g.green(`
265
+ All rule files are current.`));}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&&J(r.default))return r.default;if(r.system&&J(r.system))return r.system;for(let s of Object.keys(r))if(J(r[s]))return r[s];throw new Error(`No Directive system found in ${g.dim(e)}
266
266
  Export a system as default or named "system":
267
267
 
268
268
  ${g.cyan("export default")} createSystem({ module: myModule });
269
269
  ${g.cyan("export const system")} = createSystem({ module: myModule });`)}catch(r){throw r instanceof Error&&r.message.includes("No Directive system")?r:new Error(`Failed to load ${g.dim(e)}: ${r instanceof Error?r.message:String(r)}
270
270
 
271
271
  Make sure the file is valid TypeScript and tsx is installed:
272
- ${g.cyan("npm install -D tsx")}`)}}function U(e){if(typeof e!="object"||e===null)return false;let t=e;return typeof t.inspect=="function"&&typeof t.start=="function"&&typeof t.stop=="function"&&"facts"in t}async function Xe(e){let t=resolve(e);if(!existsSync(t))throw new Error(`File not found: ${t}`);let r;try{r=await import(t);}catch(o){throw new Error(`Failed to load ${g.dim(e)}: ${o instanceof Error?o.message:String(o)}
272
+ ${g.cyan("npm install -D tsx")}`)}}function J(e){if(typeof e!="object"||e===null)return false;let t=e;return typeof t.inspect=="function"&&typeof t.start=="function"&&typeof t.stop=="function"&&"facts"in t}async function st(e){let t=resolve(e);if(!existsSync(t))throw new Error(`File not found: ${t}`);let r;try{r=await import(t);}catch(o){throw new Error(`Failed to load ${g.dim(e)}: ${o instanceof Error?o.message:String(o)}
273
273
 
274
274
  Make sure the file is valid TypeScript and tsx is installed:
275
- ${g.cyan("npm install -D tsx")}`)}let s=[["createSystem",r.createSystem],["systemFactory",r.systemFactory],["default",r.default]];for(let[o,i]of s)if(typeof i=="function")return async()=>{let a=await Promise.resolve(i());if(!U(a))throw new Error(`Factory '${o}' from ${g.dim(e)} returned a value that is not a started Directive system.
276
- Expected an object with inspect/start/stop/facts. The factory must call sys.start() before returning.`);return a};throw U(r.default)||U(r.system)||Object.values(r).some(U)?new Error(`Found a started Directive system in ${g.dim(e)}, but bisect needs a factory.
275
+ ${g.cyan("npm install -D tsx")}`)}let s=[["createSystem",r.createSystem],["systemFactory",r.systemFactory],["default",r.default]];for(let[o,i]of s)if(typeof i=="function")return async()=>{let a=await Promise.resolve(i());if(!J(a))throw new Error(`Factory '${o}' from ${g.dim(e)} returned a value that is not a started Directive system.
276
+ Expected an object with inspect/start/stop/facts. The factory must call sys.start() before returning.`);return a};throw J(r.default)||J(r.system)||Object.values(r).some(J)?new Error(`Found a started Directive system in ${g.dim(e)}, but bisect needs a factory.
277
277
  Bisect instantiates a fresh system for every midpoint replay (so each attempt is hermetic),
278
278
  which means it can't reuse a singleton instance the way ${g.cyan("directive replay")} does.
279
279
 
@@ -291,8 +291,8 @@ Bisect needs to instantiate a fresh system per midpoint replay. Export one of:
291
291
  ${g.cyan("export default")} () => { ... return sys; };
292
292
 
293
293
  The factory MUST call sys.start() and return the started system.
294
- (Did you forget ${g.cyan("sys.start()")} before returning?)`)}async function X(e=false){try{return await import('@directive-run/timeline')}catch(t){console.error(g.red(`error: @directive-run/timeline not installed in this project.
295
- Install it: npm install --save-dev @directive-run/timeline`)),e&&console.error(g.dim(t.message)),process.exit(1);}}function Jt(e){let t={json:false,noDeterminismCheck:false,verbose:false},r="";for(let s=0;s<e.length;s++){let n=e[s];switch(n){case "--system":case "-s":{let o=e[++s];o&&(t.systemPath=o);break}case "--assert":case "-a":{let o=e[++s];o&&(t.assertExpr=o);break}case "--max-frames":{let o=e[++s],i=o?Number.parseInt(o,10):Number.NaN;Number.isFinite(i)&&i>0&&(t.maxFrames=i);break}case "--no-determinism-check":t.noDeterminismCheck=true;break;case "--json":t.json=true;break;case "--verbose":case "-v":t.verbose=true;break;default:n&&!n.startsWith("-")&&!r&&(r=n);}}return {jsonPath:r,opts:t}}function me(){console.error(`
294
+ (Did you forget ${g.cyan("sys.start()")} before returning?)`)}async function te(e=false){try{return await import('@directive-run/timeline')}catch(t){console.error(g.red(`error: @directive-run/timeline not installed in this project.
295
+ Install it: npm install --save-dev @directive-run/timeline`)),e&&console.error(g.dim(t.message)),process.exit(1);}}function nr(e){let t={json:false,noDeterminismCheck:false,verbose:false},r="";for(let s=0;s<e.length;s++){let n=e[s];switch(n){case "--system":case "-s":{let o=e[++s];o&&(t.systemPath=o);break}case "--assert":case "-a":{let o=e[++s];o&&(t.assertExpr=o);break}case "--max-frames":{let o=e[++s],i=o?Number.parseInt(o,10):Number.NaN;Number.isFinite(i)&&i>0&&(t.maxFrames=i);break}case "--no-determinism-check":t.noDeterminismCheck=true;break;case "--json":t.json=true;break;case "--verbose":case "-v":t.verbose=true;break;default:n&&!n.startsWith("-")&&!r&&(r=n);}}return {jsonPath:r,opts:t}}function ve(){console.error(`
296
296
  Usage: directive bisect <timeline.json> --system <factory.ts> --assert <expr>
297
297
 
298
298
  Binary-search a recorded timeline for the first frame that triggers a
@@ -327,29 +327,29 @@ Examples:
327
327
  --assert 'facts.count >= 0'
328
328
 
329
329
  directive bisect crash.json -s factory.ts -a 'facts.status !== "error"' --json
330
- `);}function Gt(e){let t;try{t=new Function("facts","system",`"use strict"; return (${e});`);}catch(r){throw new Error(`Failed to compile --assert expression: ${r.message}
331
- expression: ${e}`)}return r=>{let s=r?.facts;return !!t(s,r)}}async function Qe(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(me(),process.exit(e.length===0?1:0));let{jsonPath:t,opts:r}=Jt(e);t||(console.error(g.red("error: missing <timeline.json> argument")),me(),process.exit(1)),r.systemPath||(console.error(g.red("error: --system <path> is required"),g.dim(`
332
- (bisect needs a factory to instantiate a fresh system per midpoint)`)),me(),process.exit(1)),r.assertExpr||(console.error(g.red("error: --assert <expression> is required"),g.dim(`
333
- (assertion distinguishes 'good' from 'bad' system state)`)),me(),process.exit(1));let s=resolve(t);existsSync(s)||(console.error(g.red(`error: timeline file not found: ${s}`)),process.exit(1));let n;try{n=readFileSync(s,"utf8");}catch(x){console.error(g.red(`error: failed to read ${s}: ${x.message}`)),process.exit(1);}let o;try{o=JSON.parse(n);}catch(x){console.error(g.red(`error: ${s} is not valid JSON: ${x.message}`)),process.exit(1);}let{deserializeTimeline:i,bisectTimeline:a}=await X(r.verbose),l;try{l=i(o);}catch(x){console.error(g.red(`error: timeline JSON failed validation: ${x.message}`)),process.exit(1);}let c;try{c=Gt(r.assertExpr);}catch(x){console.error(g.red(`error: ${x.message}`)),process.exit(1);}let f;try{f=await Xe(r.systemPath);}catch(x){console.error(g.red(`error: failed to load system factory: ${x.message}`)),process.exit(1);}r.verbose&&console.error(g.dim(`bisecting ${l.frames.length} frames with assertion: ${r.assertExpr}`));let u=await a(l,f,c,{maxFrames:r.maxFrames,determinismCheck:!r.noDeterminismCheck});if(r.json){let x={firstFailingFrameIndex:u.firstFailingFrameIndex??null,iterations:u.iterations,noFailureFound:u.noFailureFound,failsOnEmptyReplay:u.failsOnEmptyReplay,nonDeterministic:u.nonDeterministic};console.log(JSON.stringify(x,null,2)),process.exit(0);}u.nonDeterministic&&(console.error(g.red("\u2717 bisect aborted: timeline is non-deterministic")),console.error(g.dim(` Two full-timeline replays produced different oracle verdicts.
330
+ `);}function sr(e){let t;try{t=new Function("facts","system",`"use strict"; return (${e});`);}catch(r){throw new Error(`Failed to compile --assert expression: ${r.message}
331
+ expression: ${e}`)}return r=>{let s=r?.facts;return !!t(s,r)}}async function ot(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(ve(),process.exit(e.length===0?1:0));let{jsonPath:t,opts:r}=nr(e);t||(console.error(g.red("error: missing <timeline.json> argument")),ve(),process.exit(1)),r.systemPath||(console.error(g.red("error: --system <path> is required"),g.dim(`
332
+ (bisect needs a factory to instantiate a fresh system per midpoint)`)),ve(),process.exit(1)),r.assertExpr||(console.error(g.red("error: --assert <expression> is required"),g.dim(`
333
+ (assertion distinguishes 'good' from 'bad' system state)`)),ve(),process.exit(1));let s=resolve(t);existsSync(s)||(console.error(g.red(`error: timeline file not found: ${s}`)),process.exit(1));let n;try{n=readFileSync(s,"utf8");}catch(b){console.error(g.red(`error: failed to read ${s}: ${b.message}`)),process.exit(1);}let o;try{o=JSON.parse(n);}catch(b){console.error(g.red(`error: ${s} is not valid JSON: ${b.message}`)),process.exit(1);}let{deserializeTimeline:i,bisectTimeline:a}=await te(r.verbose),l;try{l=i(o);}catch(b){console.error(g.red(`error: timeline JSON failed validation: ${b.message}`)),process.exit(1);}let c;try{c=sr(r.assertExpr);}catch(b){console.error(g.red(`error: ${b.message}`)),process.exit(1);}let d;try{d=await st(r.systemPath);}catch(b){console.error(g.red(`error: failed to load system factory: ${b.message}`)),process.exit(1);}r.verbose&&console.error(g.dim(`bisecting ${l.frames.length} frames with assertion: ${r.assertExpr}`));let u=await a(l,d,c,{maxFrames:r.maxFrames,determinismCheck:!r.noDeterminismCheck});if(r.json){let b={firstFailingFrameIndex:u.firstFailingFrameIndex??null,iterations:u.iterations,noFailureFound:u.noFailureFound,failsOnEmptyReplay:u.failsOnEmptyReplay,nonDeterministic:u.nonDeterministic};console.log(JSON.stringify(b,null,2)),process.exit(0);}u.nonDeterministic&&(console.error(g.red("\u2717 bisect aborted: timeline is non-deterministic")),console.error(g.dim(` Two full-timeline replays produced different oracle verdicts.
334
334
  Bisection is unreliable on non-deterministic timelines.
335
335
  Either fix the timeline source (deterministic clocks/seeds)
336
336
  or re-run with --no-determinism-check if you accept the risk.`)),process.exit(2)),u.noFailureFound&&(console.error(g.yellow("\u26A0 no failure to bisect: assertion passes on the full timeline")),console.error(g.dim(` The recorded timeline does not exhibit the bug your
337
337
  --assert expression checks. Verify the assertion or
338
338
  try a different bad.json.`)),process.exit(0)),u.failsOnEmptyReplay&&(console.error(g.yellow("\u26A0 assertion fails BEFORE any frame replays \u2014 bug is in initialization")),console.error(g.dim(` The freshly-started system already violates the assertion.
339
339
  Bisect cannot narrow further. Inspect the system factory
340
- or initial fact values.`)),process.exit(0));let p=u.firstFailingFrameIndex??-1,k=u.firstFailingFrame,j=k?.event.type??"<unknown>";console.log(`${g.green("\u2713")} bisect complete: ${g.bold(`first failing frame is #${p}`)} ${g.dim(`(${j})`)}`),console.log(g.dim(` \u2022 iterations: ${u.iterations} | timeline frames: ${l.frames.length}`)),r.verbose&&k&&(console.log(g.dim(" \u2022 frame:")),console.log(g.dim(` ${JSON.stringify(k,null,2).split(`
340
+ or initial fact values.`)),process.exit(0));let f=u.firstFailingFrameIndex??-1,v=u.firstFailingFrame,x=v?.event.type??"<unknown>";console.log(`${g.green("\u2713")} bisect complete: ${g.bold(`first failing frame is #${f}`)} ${g.dim(`(${x})`)}`),console.log(g.dim(` \u2022 iterations: ${u.iterations} | timeline frames: ${l.frames.length}`)),r.verbose&&v&&(console.log(g.dim(" \u2022 frame:")),console.log(g.dim(` ${JSON.stringify(v,null,2).split(`
341
341
  `).join(`
342
- `)}`))),process.exit(2);}function Vt(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 Yt(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 Xt(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},n=Object.keys(s).filter(o=>o.startsWith("@directive-run/"));return n.length<=1?{label:"Package version compatibility",passed:true,message:n.length===0?"No packages found":"Single package"}:{label:"Package version compatibility",passed:true,message:`${n.length} packages: ${n.join(", ")}`}}function Zt(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,""),o=JSON.parse(s).compilerOptions||{},i=[];return o.strict!==!0&&i.push("strict mode not enabled"),o.moduleResolution&&!["bundler","nodenext","node16"].includes(o.moduleResolution.toLowerCase())&&i.push(`moduleResolution is "${o.moduleResolution}"`),i.length>0?{label:"TypeScript configuration",passed:!1,message:i.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 Qt(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 n=readdirSync(s);for(let o of n){let i=join(s,o,"node_modules","@directive-run","core");existsSync(i)&&r.push(`@directive-run/${o}/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 er(e){let t=[".cursorrules",".claude/CLAUDE.md",".github/copilot-instructions.md",".windsurfrules",".clinerules"],r=[];for(let s of t){let n=join(e,s);if(existsSync(n)){let o=readFileSync(n,"utf-8");V(o)&&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 et(e){let t=Vt(e);console.log(),console.log(g.bold(g.cyan("Directive Doctor"))),console.log(g.dim("\u2500".repeat(40))),console.log();let r=[Yt(t.dir),Xt(t.dir),Zt(t.dir),Qt(t.dir),er(t.dir)],s=0;for(let n of r){let o=n.passed?g.green("\u2713"):g.red("\u2717");console.log(`${o} ${g.bold(n.label)}`),console.log(` ${g.dim(n.message)}`),!n.passed&&n.fix&&(console.log(` ${g.yellow("Fix:")} ${n.fix}`),s++),console.log();}s>0?(console.log(g.yellow(`${s} issue(s) found. See suggested fixes above.`)),process.exit(1)):console.log(g.green("All checks passed!"));}var nt={"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 ir(e){for(let[t,r]of Object.entries(nt))if(r.includes(e))return t;return "Other"}function or(e){let t=e.split(`
343
- `);for(let r of t){let s=r.trim();if(s.startsWith("// Example:")||s.startsWith("// Source:")||s.startsWith("// Extracted"))continue;let n=s.match(/^\*\s+(.+?)(?:\s*\*\/)?$/);if(n?.[1]&&!n[1].startsWith("@"))return n[1];if(s.startsWith("//")&&s.length>3)return s.slice(2).trim();if(s!==""&&!s.startsWith("//")&&!s.startsWith("/*")&&!s.startsWith("*"))break}return ""}async function st(e){let t;for(let i=0;i<e.length;i++)e[i]==="--filter"&&(t=e[++i]?.toLowerCase());let r=getAllExamples();console.log(),console.log(g.bold(g.cyan("Directive Examples"))),console.log(g.dim("\u2500".repeat(50))),console.log();let s=new Map;for(let[i,a]of r){let l=ir(i);t&&!l.toLowerCase().includes(t)&&!i.includes(t)||(s.has(l)||s.set(l,[]),s.get(l).push({name:i,desc:or(a)}));}if(s.size===0){console.log(g.dim("No examples match the filter."));return}let n=Object.keys(nt),o=[...s.keys()].sort((i,a)=>(n.indexOf(i)??99)-(n.indexOf(a)??99));for(let i of o){let a=s.get(i);console.log(g.bold(i));for(let l of a){let c=l.desc?g.dim(` \u2014 ${l.desc}`):"";console.log(` ${g.cyan(l.name)}${c}`);}console.log();}console.log(g.dim(`${r.size} examples available. Run ${g.cyan("directive examples copy <name>")} to extract one.`));}async function it(e,t){let r=process.cwd();for(let l=0;l<t.length;l++)if(t[l]==="--dest"){let c=t[++l];c&&(r=c);}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 ${g.cyan("directive examples list")} to see available examples.`),process.exit(1));let n=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"'),o=join(r,`${e}.ts`);existsSync(o)&&(console.error(`File already exists: ${relative(process.cwd(),o)}`),process.exit(1));let i=dirname(o);existsSync(i)||mkdirSync(i,{recursive:true}),writeFileSync(o,n,"utf-8");let a=relative(process.cwd(),o);console.log(`${g.green("Copied")} ${g.cyan(e)} \u2192 ${g.dim(a)}`);}function ar(e){let t={},r="",s;for(let n=0;n<e.length;n++){let o=e[n];if(o==="--module"){let i=e[++n];i&&(t.module=i);}else o&&!o.startsWith("-")&&(r?s||(s=o):r=o);}return {filePath:r,requirementId:s,opts:t}}async function at(e){let{filePath:t,requirementId:r}=ar(e);t||(console.error("Usage: directive explain <file> [requirement-id]"),process.exit(1));let s=await P(t);s.isRunning||s.start();let n=s.inspect();if(r){let o=s.explain(r);if(!o){if(console.error(`Requirement "${r}" not found.
344
-
345
- Current requirements:`),n.unmet.length===0)console.log(g.dim(" (no unmet requirements)"));else for(let i of n.unmet)console.log(` ${g.cyan(i.id)} \u2014 ${i.requirement.type} (from ${i.fromConstraint})`);s.stop(),process.exit(1);}console.log(),console.log(g.bold(g.cyan("Requirement Explanation"))),console.log(g.dim("\u2500".repeat(40))),console.log(),console.log(o),console.log();}else if(console.log(),console.log(g.bold(g.cyan("All Requirements"))),console.log(g.dim("\u2500".repeat(40))),console.log(),n.unmet.length===0){console.log(g.green("All requirements are met.")),console.log();let o=Object.entries(n.resolvers);if(o.length>0){console.log(g.bold("Recent Resolver Activity:"));for(let[i,a]of o){let l=ot(a.state),c=a.duration!==void 0?` (${a.duration}ms)`:"";console.log(` ${g.cyan(i)} ${l}${c}`);}console.log();}}else {console.log(`${g.yellow(String(n.unmet.length))} unmet requirement(s):
346
- `);for(let o of n.unmet){console.log(`${g.yellow("\u25CF")} ${g.bold(o.requirement.type)} (id: ${g.dim(o.id)})`),console.log(` From constraint: ${g.cyan(o.fromConstraint)}`);let i={...o.requirement};delete i.type,Object.keys(i).length>0&&console.log(` Payload: ${JSON.stringify(i)}`);let l=n.resolvers[o.id];l?console.log(` Resolver: ${ot(l.state)}${l.error?` \u2014 ${l.error}`:""}`):n.resolverDefs.some(f=>f.requirement===o.requirement.type||f.requirement==="(predicate)")||console.log(` ${g.red("No resolver registered for this type")}`),console.log();}console.log(g.dim(`Run ${g.cyan("directive explain <file> <requirement-id>")} for detailed explanation.`));}s.stop();}function ot(e){switch(e){case "resolved":return g.green("resolved");case "errored":return g.red("errored");case "inflight":return g.yellow("inflight");case "pending":return g.yellow("pending");case "cancelled":return g.dim("cancelled");default:return g.dim(e)}}function ur(e){let t={ascii:false,open:true},r="";for(let s=0;s<e.length;s++){let n=e[s];switch(n){case "--ascii":t.ascii=true;break;case "--no-open":t.open=false;break;case "--output":{let o=e[++s];o&&(t.output=o);break}default:n&&!n.startsWith("-")&&!r&&(r=n);}}return {filePath:r,opts:t}}function fr(e){let t=[];t.push(g.bold("Dependency Graph")),t.push(g.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 l=r.get(a.fromConstraint);l&&l.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(g.bold("Constraints \u2192 Requirements \u2192 Resolvers")),t.push("");for(let[a,l]of r){let c=l.active?g.green("\u25CF"):g.dim("\u25CB");if(t.push(`${c} ${g.cyan(a)} (priority: ${l.priority})`),l.reqTypes.size>0)for(let f of l.reqTypes){t.push(` \u2514\u2500\u25B6 ${g.yellow(f)}`);let u=s.get(f)||[];if(u.length>0)for(let p of u)t.push(` \u2514\u2500\u25B6 ${g.magenta(p)}`);else t.push(` \u2514\u2500\u25B6 ${g.red("(no resolver)")}`);}else t.push(` \u2514\u2500\u25B6 ${g.dim("(no active requirements)")}`);t.push("");}let n=new Set;for(let a of s.values())for(let l of a)n.add(l);if(e.resolverDefs.map(a=>a.id).filter(a=>!n.has(a)).length>0){t.push(g.bold("Standalone Resolvers:"));for(let a of e.resolverDefs)n.has(a.id)||t.push(` ${g.magenta(a.id)} handles ${g.yellow(a.requirement)}`);}return t.join(`
347
- `)}function dr(e,t){let r=[],s=[],l=Object.keys(t);for(let d=0;d<l.length;d++){let $=l[d];r.push({id:`fact-${$}`,label:$,type:"fact",x:40,y:60+d*50,color:"#3b82f6"});}for(let d=0;d<e.constraints.length;d++){let $=e.constraints[d];r.push({id:`constraint-${$.id}`,label:$.id,type:"constraint",x:260,y:60+d*50,color:$.active?"#22c55e":"#6b7280"});}let c=new Set;for(let d of e.unmet)c.add(d.requirement.type);let f=0;for(let d of c)r.push({id:`req-${d}`,label:d,type:"requirement",x:480,y:60+f*50,color:"#eab308"}),f++;for(let d=0;d<e.resolverDefs.length;d++){let $=e.resolverDefs[d];r.push({id:`resolver-${$.id}`,label:$.id,type:"resolver",x:700,y:60+d*50,color:"#a855f7"});}for(let d of e.unmet)s.push({from:`constraint-${d.fromConstraint}`,to:`req-${d.requirement.type}`});for(let d of e.resolverDefs)c.has(d.requirement)&&s.push({from:`req-${d.requirement}`,to:`resolver-${d.id}`});let u=new Map(r.map(d=>[d.id,d])),p=960,k=Math.max(...r.map(d=>d.y))+50+20,j=s.map(d=>{let $=u.get(d.from),z=u.get(d.to);return !$||!z?"":`<line x1="${$.x+90}" y1="${$.y+15}" x2="${z.x}" y2="${z.y+15}" stroke="#94a3b8" stroke-width="1.5" marker-end="url(#arrow)"/>`}).join(`
348
- `),x=r.map(d=>`<g>
349
- <rect x="${d.x}" y="${d.y}" width="180" height="30" rx="6" fill="${d.color}" opacity="0.15" stroke="${d.color}" stroke-width="1.5"/>
350
- <text x="${d.x+90}" y="${d.y+19}" text-anchor="middle" font-size="12" font-family="monospace" fill="${d.color}">${pr(d.label)}</text>
342
+ `)}`))),process.exit(2);}function or(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 ar(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 lr(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},n=Object.keys(s).filter(o=>o.startsWith("@directive-run/"));return n.length<=1?{label:"Package version compatibility",passed:true,message:n.length===0?"No packages found":"Single package"}:{label:"Package version compatibility",passed:true,message:`${n.length} packages: ${n.join(", ")}`}}function cr(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,""),o=JSON.parse(s).compilerOptions||{},i=[];return o.strict!==!0&&i.push("strict mode not enabled"),o.moduleResolution&&!["bundler","nodenext","node16"].includes(o.moduleResolution.toLowerCase())&&i.push(`moduleResolution is "${o.moduleResolution}"`),i.length>0?{label:"TypeScript configuration",passed:!1,message:i.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 ur(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 n=readdirSync(s);for(let o of n){let i=join(s,o,"node_modules","@directive-run","core");existsSync(i)&&r.push(`@directive-run/${o}/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 fr(e){let t=[".cursorrules",".claude/CLAUDE.md",".github/copilot-instructions.md",".windsurfrules",".clinerules"],r=[];for(let s of t){let n=join(e,s);if(existsSync(n)){let o=readFileSync(n,"utf-8");Q(o)&&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 at(e){let t=or(e);console.log(),console.log(g.bold(g.cyan("Directive Doctor"))),console.log(g.dim("\u2500".repeat(40))),console.log();let r=[ar(t.dir),lr(t.dir),cr(t.dir),ur(t.dir),fr(t.dir)],s=0;for(let n of r){let o=n.passed?g.green("\u2713"):g.red("\u2717");console.log(`${o} ${g.bold(n.label)}`),console.log(` ${g.dim(n.message)}`),!n.passed&&n.fix&&(console.log(` ${g.yellow("Fix:")} ${n.fix}`),s++),console.log();}s>0?(console.log(g.yellow(`${s} issue(s) found. See suggested fixes above.`)),process.exit(1)):console.log(g.green("All checks passed!"));}var ut={"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 hr(e){for(let[t,r]of Object.entries(ut))if(r.includes(e))return t;return "Other"}function yr(e){let t=e.split(`
343
+ `);for(let r of t){let s=r.trim();if(s.startsWith("// Example:")||s.startsWith("// Source:")||s.startsWith("// Extracted"))continue;let n=s.match(/^\*\s+(.+?)(?:\s*\*\/)?$/);if(n?.[1]&&!n[1].startsWith("@"))return n[1];if(s.startsWith("//")&&s.length>3)return s.slice(2).trim();if(s!==""&&!s.startsWith("//")&&!s.startsWith("/*")&&!s.startsWith("*"))break}return ""}async function ft(e){let t;for(let i=0;i<e.length;i++)e[i]==="--filter"&&(t=e[++i]?.toLowerCase());let r=getAllExamples();console.log(),console.log(g.bold(g.cyan("Directive Examples"))),console.log(g.dim("\u2500".repeat(50))),console.log();let s=new Map;for(let[i,a]of r){let l=hr(i);t&&!l.toLowerCase().includes(t)&&!i.includes(t)||(s.has(l)||s.set(l,[]),s.get(l).push({name:i,desc:yr(a)}));}if(s.size===0){console.log(g.dim("No examples match the filter."));return}let n=Object.keys(ut),o=[...s.keys()].sort((i,a)=>(n.indexOf(i)??99)-(n.indexOf(a)??99));for(let i of o){let a=s.get(i);console.log(g.bold(i));for(let l of a){let c=l.desc?g.dim(` \u2014 ${l.desc}`):"";console.log(` ${g.cyan(l.name)}${c}`);}console.log();}console.log(g.dim(`${r.size} examples available. Run ${g.cyan("directive examples copy <name>")} to extract one.`));}async function dt(e,t){let r=process.cwd();for(let l=0;l<t.length;l++)if(t[l]==="--dest"){let c=t[++l];c&&(r=c);}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 ${g.cyan("directive examples list")} to see available examples.`),process.exit(1));let n=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"'),o=join(r,`${e}.ts`);existsSync(o)&&(console.error(`File already exists: ${relative(process.cwd(),o)}`),process.exit(1));let i=dirname(o);existsSync(i)||mkdirSync(i,{recursive:true}),writeFileSync(o,n,"utf-8");let a=relative(process.cwd(),o);console.log(`${g.green("Copied")} ${g.cyan(e)} \u2192 ${g.dim(a)}`);}function vr(e){let t={},r="",s;for(let n=0;n<e.length;n++){let o=e[n];if(o==="--module"){let i=e[++n];i&&(t.module=i);}else o&&!o.startsWith("-")&&(r?s||(s=o):r=o);}return {filePath:r,requirementId:s,opts:t}}async function mt(e){let{filePath:t,requirementId:r}=vr(e);t||(console.error("Usage: directive explain <file> [requirement-id]"),process.exit(1));let s=await U(t);s.isRunning||s.start();let n=s.inspect();if(r){let o=s.explain(r);if(!o){if(console.error(`Requirement "${r}" not found.
344
+
345
+ Current requirements:`),n.unmet.length===0)console.log(g.dim(" (no unmet requirements)"));else for(let i of n.unmet)console.log(` ${g.cyan(i.id)} \u2014 ${i.requirement.type} (from ${i.fromConstraint})`);s.stop(),process.exit(1);}console.log(),console.log(g.bold(g.cyan("Requirement Explanation"))),console.log(g.dim("\u2500".repeat(40))),console.log(),console.log(o),console.log();}else if(console.log(),console.log(g.bold(g.cyan("All Requirements"))),console.log(g.dim("\u2500".repeat(40))),console.log(),n.unmet.length===0){console.log(g.green("All requirements are met.")),console.log();let o=Object.entries(n.resolvers);if(o.length>0){console.log(g.bold("Recent Resolver Activity:"));for(let[i,a]of o){let l=pt(a.state),c=a.duration!==void 0?` (${a.duration}ms)`:"";console.log(` ${g.cyan(i)} ${l}${c}`);}console.log();}}else {console.log(`${g.yellow(String(n.unmet.length))} unmet requirement(s):
346
+ `);for(let o of n.unmet){console.log(`${g.yellow("\u25CF")} ${g.bold(o.requirement.type)} (id: ${g.dim(o.id)})`),console.log(` From constraint: ${g.cyan(o.fromConstraint)}`);let i={...o.requirement};delete i.type,Object.keys(i).length>0&&console.log(` Payload: ${JSON.stringify(i)}`);let l=n.resolvers[o.id];l?console.log(` Resolver: ${pt(l.state)}${l.error?` \u2014 ${l.error}`:""}`):n.resolverDefs.some(d=>d.requirement===o.requirement.type||d.requirement==="(predicate)")||console.log(` ${g.red("No resolver registered for this type")}`),console.log();}console.log(g.dim(`Run ${g.cyan("directive explain <file> <requirement-id>")} for detailed explanation.`));}s.stop();}function pt(e){switch(e){case "resolved":return g.green("resolved");case "errored":return g.red("errored");case "inflight":return g.yellow("inflight");case "pending":return g.yellow("pending");case "cancelled":return g.dim("cancelled");default:return g.dim(e)}}function $r(e){let t={ascii:false,open:true},r="";for(let s=0;s<e.length;s++){let n=e[s];switch(n){case "--ascii":t.ascii=true;break;case "--no-open":t.open=false;break;case "--output":{let o=e[++s];o&&(t.output=o);break}default:n&&!n.startsWith("-")&&!r&&(r=n);}}return {filePath:r,opts:t}}function Sr(e){let t=[];t.push(g.bold("Dependency Graph")),t.push(g.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 l=r.get(a.fromConstraint);l&&l.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(g.bold("Constraints \u2192 Requirements \u2192 Resolvers")),t.push("");for(let[a,l]of r){let c=l.active?g.green("\u25CF"):g.dim("\u25CB");if(t.push(`${c} ${g.cyan(a)} (priority: ${l.priority})`),l.reqTypes.size>0)for(let d of l.reqTypes){t.push(` \u2514\u2500\u25B6 ${g.yellow(d)}`);let u=s.get(d)||[];if(u.length>0)for(let f of u)t.push(` \u2514\u2500\u25B6 ${g.magenta(f)}`);else t.push(` \u2514\u2500\u25B6 ${g.red("(no resolver)")}`);}else t.push(` \u2514\u2500\u25B6 ${g.dim("(no active requirements)")}`);t.push("");}let n=new Set;for(let a of s.values())for(let l of a)n.add(l);if(e.resolverDefs.map(a=>a.id).filter(a=>!n.has(a)).length>0){t.push(g.bold("Standalone Resolvers:"));for(let a of e.resolverDefs)n.has(a.id)||t.push(` ${g.magenta(a.id)} handles ${g.yellow(a.requirement)}`);}return t.join(`
347
+ `)}function kr(e,t){let r=[],s=[],l=Object.keys(t);for(let p=0;p<l.length;p++){let h=l[p];r.push({id:`fact-${h}`,label:h,type:"fact",x:40,y:60+p*50,color:"#3b82f6"});}for(let p=0;p<e.constraints.length;p++){let h=e.constraints[p];r.push({id:`constraint-${h.id}`,label:h.id,type:"constraint",x:260,y:60+p*50,color:h.active?"#22c55e":"#6b7280"});}let c=new Set;for(let p of e.unmet)c.add(p.requirement.type);let d=0;for(let p of c)r.push({id:`req-${p}`,label:p,type:"requirement",x:480,y:60+d*50,color:"#eab308"}),d++;for(let p=0;p<e.resolverDefs.length;p++){let h=e.resolverDefs[p];r.push({id:`resolver-${h.id}`,label:h.id,type:"resolver",x:700,y:60+p*50,color:"#a855f7"});}for(let p of e.unmet)s.push({from:`constraint-${p.fromConstraint}`,to:`req-${p.requirement.type}`});for(let p of e.resolverDefs)c.has(p.requirement)&&s.push({from:`req-${p.requirement}`,to:`resolver-${p.id}`});let u=new Map(r.map(p=>[p.id,p])),f=960,v=Math.max(...r.map(p=>p.y))+50+20,x=s.map(p=>{let h=u.get(p.from),D=u.get(p.to);return !h||!D?"":`<line x1="${h.x+90}" y1="${h.y+15}" x2="${D.x}" y2="${D.y+15}" stroke="#94a3b8" stroke-width="1.5" marker-end="url(#arrow)"/>`}).join(`
348
+ `),b=r.map(p=>`<g>
349
+ <rect x="${p.x}" y="${p.y}" width="180" height="30" rx="6" fill="${p.color}" opacity="0.15" stroke="${p.color}" stroke-width="1.5"/>
350
+ <text x="${p.x+90}" y="${p.y+19}" text-anchor="middle" font-size="12" font-family="monospace" fill="${p.color}">${xr(p.label)}</text>
351
351
  </g>`).join(`
352
- `),te=["Facts","Constraints","Requirements","Resolvers"].map((d,$)=>`<text x="${40+$*220+90}" y="35" text-anchor="middle" font-size="14" font-weight="bold" font-family="system-ui" fill="#e2e8f0">${d}</text>`).join(`
352
+ `),F=["Facts","Constraints","Requirements","Resolvers"].map((p,h)=>`<text x="${40+h*220+90}" y="35" text-anchor="middle" font-size="14" font-weight="bold" font-family="system-ui" fill="#e2e8f0">${p}</text>`).join(`
353
353
  `);return `<!DOCTYPE html>
354
354
  <html>
355
355
  <head>
@@ -360,18 +360,18 @@ Current requirements:`),n.unmet.length===0)console.log(g.dim(" (no unmet requir
360
360
  </style>
361
361
  </head>
362
362
  <body>
363
- <svg width="${p}" height="${k}" xmlns="http://www.w3.org/2000/svg">
363
+ <svg width="${f}" height="${v}" xmlns="http://www.w3.org/2000/svg">
364
364
  <defs>
365
365
  <marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
366
366
  <path d="M 0 0 L 10 5 L 0 10 z" fill="#94a3b8"/>
367
367
  </marker>
368
368
  </defs>
369
- ${te}
370
- ${j}
369
+ ${F}
371
370
  ${x}
371
+ ${b}
372
372
  </svg>
373
373
  </body>
374
- </html>`}function pr(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function lt(e){let{filePath:t,opts:r}=ur(e);t||(console.error("Usage: directive graph <file> [--ascii] [--no-open] [--output <path>]"),process.exit(1));let s=await P(t);s.isRunning||s.start();let n=s.inspect();if(r.ascii){console.log(fr(n)),s.stop();return}let o={};if(s.facts)for(let l of Object.keys(s.facts))try{o[l]=s.facts[l];}catch{o[l]=null;}let i=dr(n,o),a=r.output||join(process.cwd(),".directive-graph.html");if(writeFileSync(a,i,"utf-8"),console.log(`${g.green("Generated")} ${g.dim(a)}`),r.open)try{let{execFile:l}=await import('child_process'),c=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";l(c,[a]),console.log(g.dim("Opened in browser."));}catch{console.log(g.dim(`Open ${a} in your browser to view the graph.`));}s.stop();}function vr(e){let t={dir:process.cwd(),noInteractive:false};for(let r=0;r<e.length;r++)switch(e[r]){case "--template":{let n=e[++r];n&&(t.template=n);break}case "--dir":{let n=e[++r];n&&(t.dir=n);break}case "--no-interactive":t.noInteractive=true;break}return t}function br(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 wr(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 je(e){return {counter:{id:"counter",label:"Counter (minimal)",hint:"schema + init + derive + events \u2014 simplest starting point",files:[{path:`src/${e}.ts`,content:$r(e)},{path:"src/main.ts",content:Sr(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:kr(e)},{path:"src/main.ts",content:xr(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:Rr(e)},{path:"src/main.ts",content:Cr(e)}],deps:["@directive-run/core","@directive-run/ai"]}}}function $r(e){return `import { type ModuleSchema, createModule, t } from "@directive-run/core";
374
+ </html>`}function xr(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function gt(e){let{filePath:t,opts:r}=$r(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 n=s.inspect();if(r.ascii){console.log(Sr(n)),s.stop();return}let o={};if(s.facts)for(let l of Object.keys(s.facts))try{o[l]=s.facts[l];}catch{o[l]=null;}let i=kr(n,o),a=r.output||join(process.cwd(),".directive-graph.html");if(writeFileSync(a,i,"utf-8"),console.log(`${g.green("Generated")} ${g.dim(a)}`),r.open)try{let{execFile:l}=await import('child_process'),c=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";l(c,[a]),console.log(g.dim("Opened in browser."));}catch{console.log(g.dim(`Open ${a} in your browser to view the graph.`));}s.stop();}function jr(e){let t={dir:process.cwd(),noInteractive:false};for(let r=0;r<e.length;r++)switch(e[r]){case "--template":{let n=e[++r];n&&(t.template=n);break}case "--dir":{let n=e[++r];n&&(t.dir=n);break}case "--no-interactive":t.noInteractive=true;break}return t}function Or(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 Ar(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 Ie(e){return {counter:{id:"counter",label:"Counter (minimal)",hint:"schema + init + derive + events \u2014 simplest starting point",files:[{path:`src/${e}.ts`,content:Mr(e)},{path:"src/main.ts",content:qr(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:Ir(e)},{path:"src/main.ts",content:Pr(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:Tr(e)},{path:"src/main.ts",content:Nr(e)}],deps:["@directive-run/core","@directive-run/ai"]}}}function Mr(e){return `import { type ModuleSchema, createModule, t } from "@directive-run/core";
375
375
 
376
376
  const schema = {
377
377
  facts: {
@@ -390,7 +390,7 @@ const schema = {
390
390
  },
391
391
  } satisfies ModuleSchema;
392
392
 
393
- export const ${Q(e)} = createModule("${e}", {
393
+ export const ${ne(e)} = createModule("${e}", {
394
394
  schema,
395
395
 
396
396
  init: (facts) => {
@@ -418,7 +418,7 @@ export const ${Q(e)} = createModule("${e}", {
418
418
  },
419
419
  },
420
420
  });
421
- `}function Sr(e){let t=Q(e);return `import { createSystem } from "@directive-run/core";
421
+ `}function qr(e){let t=ne(e);return `import { createSystem } from "@directive-run/core";
422
422
  import { ${t} } from "./${e}.js";
423
423
 
424
424
  const system = createSystem({
@@ -444,7 +444,7 @@ system.events.increment();
444
444
  system.events.increment();
445
445
 
446
446
  export default system;
447
- `}function kr(e){return `import { type ModuleSchema, createModule, t } from "@directive-run/core";
447
+ `}function Ir(e){return `import { type ModuleSchema, createModule, t } from "@directive-run/core";
448
448
 
449
449
  type AuthStatus = "idle" | "authenticating" | "authenticated" | "expired";
450
450
 
@@ -471,7 +471,7 @@ const schema = {
471
471
  },
472
472
  } satisfies ModuleSchema;
473
473
 
474
- export const ${Q(e)} = createModule("${e}", {
474
+ export const ${ne(e)} = createModule("${e}", {
475
475
  schema,
476
476
 
477
477
  init: (facts) => {
@@ -548,7 +548,7 @@ export const ${Q(e)} = createModule("${e}", {
548
548
  },
549
549
  },
550
550
  });
551
- `}function xr(e){let t=Q(e);return `import { createSystem } from "@directive-run/core";
551
+ `}function Pr(e){let t=ne(e);return `import { createSystem } from "@directive-run/core";
552
552
  import { ${t} } from "./${e}.js";
553
553
 
554
554
  const system = createSystem({
@@ -569,7 +569,7 @@ console.log("authenticated:", system.read("isAuthenticated"));
569
569
  console.log("token:", system.facts.token);
570
570
 
571
571
  export default system;
572
- `}function Rr(e){return `import { type ModuleSchema, createModule, t } from "@directive-run/core";
572
+ `}function Tr(e){return `import { type ModuleSchema, createModule, t } from "@directive-run/core";
573
573
  import {
574
574
  createAgentOrchestrator,
575
575
  createAgentMemory,
@@ -603,7 +603,7 @@ const schema = {
603
603
  },
604
604
  } satisfies ModuleSchema;
605
605
 
606
- export const ${Q(e)} = createModule("${e}", {
606
+ export const ${ne(e)} = createModule("${e}", {
607
607
  schema,
608
608
 
609
609
  init: (facts) => {
@@ -677,7 +677,7 @@ export const memory = createAgentMemory({
677
677
  // maxTokenBudget: 50000,
678
678
  // memory,
679
679
  // });
680
- `}function Cr(e){let t=Q(e);return `import { createSystem } from "@directive-run/core";
680
+ `}function Nr(e){let t=ne(e);return `import { createSystem } from "@directive-run/core";
681
681
  import { ${t} } from "./${e}.js";
682
682
 
683
683
  const system = createSystem({
@@ -696,20 +696,20 @@ await system.settle();
696
696
  console.log("output:", system.facts.output);
697
697
 
698
698
  export default system;
699
- `}function Q(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function Er(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}async function ct(e){let t=vr(e);m.intro(g.bgCyan(g.black(" directive init ")));let r;if(t.noInteractive)r="my-module";else {let u=await m.text({message:"Module name:",placeholder:"my-module",defaultValue:"my-module",validate:p=>{if(!/^[a-z][a-z0-9-]*$/.test(p))return "Must start with a letter, use lowercase letters, numbers, and hyphens"}});m.isCancel(u)&&(m.cancel("Cancelled."),process.exit(0)),r=u;}let s;if(t.template){let u=je(r);t.template in u||(m.log.error(`Unknown template: ${t.template}. Available: ${Object.keys(u).join(", ")}`),process.exit(1)),s=t.template;}else if(t.noInteractive)s="counter";else {let u=je(r),p=await m.select({message:"Project template:",options:Object.values(u).map(k=>({value:k.id,label:k.label,hint:k.hint}))});m.isCancel(p)&&(m.cancel("Cancelled."),process.exit(0)),s=p;}let o=je(r)[s],i=br(t.dir);m.log.info(`Package manager: ${g.cyan(i)}`);let a=m.spinner();a.start("Creating project files...");let c=0;for(let u of o.files){let p=join(t.dir,u.path);if(existsSync(p)){c++;continue}Er(p,u.content);}a.stop("Project files created.");for(let u of o.files){let p=join(t.dir,u.path),k=relative(t.dir,p);existsSync(p)&&m.log.success(`${g.green("Created")} ${g.dim(k)}`);}c>0&&m.log.warn(`Skipped ${c} file(s) that already exist.`);let f=wr(i,o.deps.join(" "));m.outro(`Next steps:
700
- ${g.cyan(f)}
701
- ${g.cyan(`${R} ai-rules init`)}
702
- ${g.dim("Start building!")}`);}function Dr(e){let t={json:false},r="";for(let s=0;s<e.length;s++){let n=e[s];switch(n){case "--json":t.json=true;break;case "--module":{let o=e[++s];o&&(t.module=o);break}default:n&&!n.startsWith("-")&&!r&&(r=n);}}return {filePath:r,opts:t}}function jr(e){let t=[];t.push(g.bold("Facts:"));let r=Object.entries(e);if(r.length===0)return t.push(" (none)"),t.join(`
703
- `);for(let[s,n]of r){let o=Tr(n);t.push(` ${g.cyan(s)} = ${o}`);}return t.join(`
704
- `)}function Or(e){let t=[];if(t.push(g.bold("Constraints:")),e.length===0)return t.push(" (none)"),t.join(`
699
+ `}function ne(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function Fr(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}async function ht(e){let t=jr(e);m.intro(g.bgCyan(g.black(" directive init ")));let r;if(t.noInteractive)r="my-module";else {let u=await m.text({message:"Module name:",placeholder:"my-module",defaultValue:"my-module",validate:f=>{if(!/^[a-z][a-z0-9-]*$/.test(f))return "Must start with a letter, use lowercase letters, numbers, and hyphens"}});m.isCancel(u)&&(m.cancel("Cancelled."),process.exit(0)),r=u;}let s;if(t.template){let u=Ie(r);t.template in u||(m.log.error(`Unknown template: ${t.template}. Available: ${Object.keys(u).join(", ")}`),process.exit(1)),s=t.template;}else if(t.noInteractive)s="counter";else {let u=Ie(r),f=await m.select({message:"Project template:",options:Object.values(u).map(v=>({value:v.id,label:v.label,hint:v.hint}))});m.isCancel(f)&&(m.cancel("Cancelled."),process.exit(0)),s=f;}let o=Ie(r)[s],i=Or(t.dir);m.log.info(`Package manager: ${g.cyan(i)}`);let a=m.spinner();a.start("Creating project files...");let c=0;for(let u of o.files){let f=join(t.dir,u.path);if(existsSync(f)){c++;continue}Fr(f,u.content);}a.stop("Project files created.");for(let u of o.files){let f=join(t.dir,u.path),v=relative(t.dir,f);existsSync(f)&&m.log.success(`${g.green("Created")} ${g.dim(v)}`);}c>0&&m.log.warn(`Skipped ${c} file(s) that already exist.`);let d=Ar(i,o.deps.join(" "));m.outro(`Next steps:
700
+ ${g.cyan(d)}
701
+ ${g.cyan(`${C} ai-rules init`)}
702
+ ${g.dim("Start building!")}`);}function zr(e){let t={json:false},r="";for(let s=0;s<e.length;s++){let n=e[s];switch(n){case "--json":t.json=true;break;case "--module":{let o=e[++s];o&&(t.module=o);break}default:n&&!n.startsWith("-")&&!r&&(r=n);}}return {filePath:r,opts:t}}function _r(e){let t=[];t.push(g.bold("Facts:"));let r=Object.entries(e);if(r.length===0)return t.push(" (none)"),t.join(`
703
+ `);for(let[s,n]of r){let o=Jr(n);t.push(` ${g.cyan(s)} = ${o}`);}return t.join(`
704
+ `)}function Ur(e){let t=[];if(t.push(g.bold("Constraints:")),e.length===0)return t.push(" (none)"),t.join(`
705
705
  `);for(let r of e){let s=r.disabled?g.dim("disabled"):r.active?g.green("active"):g.dim("inactive"),n=r.hitCount>0?g.yellow(` (${r.hitCount} hits)`):"";t.push(` ${g.cyan(r.id)} ${s} priority=${r.priority}${n}`);}return t.join(`
706
- `)}function Ar(e,t){let r=[];if(r.push(g.bold("Resolvers:")),e.length===0)return r.push(" (none)"),r.join(`
707
- `);for(let s of e){let n=t[s.id],o=n?Ir(n.state,n.error,n.duration):g.dim("idle");r.push(` ${g.cyan(s.id)} \u2192 ${s.requirement} ${o}`);}return r.join(`
708
- `)}function Mr(e){let t=[];if(t.push(g.bold("Unmet Requirements:")),e.length===0)return t.push(` ${g.green("(all requirements met)")}`),t.join(`
706
+ `)}function Wr(e,t){let r=[];if(r.push(g.bold("Resolvers:")),e.length===0)return r.push(" (none)"),r.join(`
707
+ `);for(let s of e){let n=t[s.id],o=n?Kr(n.state,n.error,n.duration):g.dim("idle");r.push(` ${g.cyan(s.id)} \u2192 ${s.requirement} ${o}`);}return r.join(`
708
+ `)}function Br(e){let t=[];if(t.push(g.bold("Unmet Requirements:")),e.length===0)return t.push(` ${g.green("(all requirements met)")}`),t.join(`
709
709
  `);for(let r of e)t.push(` ${g.yellow(r.requirement.type)} (id: ${g.dim(r.id)}) from ${g.dim(r.fromConstraint)}`);return t.join(`
710
- `)}function qr(e){let t=[];if(t.push(g.bold("Inflight:")),e.length===0)return t.push(` ${g.green("(none)")}`),t.join(`
710
+ `)}function Lr(e){let t=[];if(t.push(g.bold("Inflight:")),e.length===0)return t.push(` ${g.green("(none)")}`),t.join(`
711
711
  `);let r=Date.now();for(let s of e){let n=r-s.startedAt;t.push(` ${g.cyan(s.resolverId)} \u2192 req ${g.dim(s.id)} ${g.yellow(`${n}ms`)}`);}return t.join(`
712
- `)}function Ir(e,t,r){let s=r!==void 0?` ${r}ms`:"";switch(e){case "resolved":return g.green(`resolved${s}`);case "errored":return g.red(`errored${s}${t?` \u2014 ${t}`:""}`);case "inflight":return g.yellow("inflight");case "cancelled":return g.dim("cancelled");default:return g.dim(e)}}function Tr(e){return e===null?g.dim("null"):e===void 0?g.dim("undefined"):typeof e=="string"?e.length>60?`"${e.slice(0,57)}..."`:`"${e}"`:typeof e=="number"||typeof e=="boolean"?String(e):Array.isArray(e)?`[${e.length} items]`:JSON.stringify(e).slice(0,60)}function Pr(e){let t=[];new Set(e.unmet.map(o=>o.requirement.type));new Set(e.resolverDefs.map(o=>o.requirement));for(let o of e.resolverDefs)o.requirement;for(let o of e.unmet)e.resolverDefs.some(a=>a.requirement===o.requirement.type||a.requirement==="(predicate)")||t.push(`No resolver for requirement type "${o.requirement.type}"`);return t}async function ut(e){let{filePath:t,opts:r}=Dr(e);t||(console.error("Usage: directive inspect <file> [--json] [--module <name>]"),process.exit(1));let s=await P(t);s.isRunning||s.start();let n=s.inspect();if(r.json){let a={};if(s.facts)for(let l of Object.keys(s.facts))try{a[l]=s.facts[l];}catch{a[l]="(error reading)";}console.log(JSON.stringify({facts:a,...n},null,2)),s.stop();return}console.log(),console.log(g.bold(g.cyan("Directive System Inspection"))),console.log(g.dim("\u2500".repeat(40))),console.log();let o={};if(s.facts)for(let a of Object.keys(s.facts))try{o[a]=s.facts[a];}catch{o[a]="(error reading)";}console.log(jr(o)),console.log(),console.log(Or(n.constraints)),console.log(),console.log(Ar(n.resolverDefs,n.resolvers)),console.log(),console.log(Mr(n.unmet)),console.log(),n.inflight.length>0&&(console.log(qr(n.inflight)),console.log());let i=Pr(n);if(i.length>0){console.log(g.bold(g.yellow("Warnings:")));for(let a of i)console.log(` ${g.yellow("\u26A0")} ${a}`);console.log();}s.stop();}function dt(e){let t={with:[],minimal:false,dir:process.cwd()};for(let r=0;r<e.length;r++)switch(e[r]){case "--with":{let n=e[++r];n&&(t.with=n.split(",").map(o=>o.trim()));break}case "--minimal":t.minimal=true;break;case "--dir":{let n=e[++r];n&&(t.dir=n);break}}return t}var ft=["derive","events","constraints","resolvers","effects"];function _r(e,t){let r=pt(e),s=t.includes("constraints"),n=t.includes("resolvers"),i=`import { ${["type ModuleSchema","createModule","t"].join(", ")} } from "@directive-run/core";
712
+ `)}function Kr(e,t,r){let s=r!==void 0?` ${r}ms`:"";switch(e){case "resolved":return g.green(`resolved${s}`);case "errored":return g.red(`errored${s}${t?` \u2014 ${t}`:""}`);case "inflight":return g.yellow("inflight");case "cancelled":return g.dim("cancelled");default:return g.dim(e)}}function Jr(e){return e===null?g.dim("null"):e===void 0?g.dim("undefined"):typeof e=="string"?e.length>60?`"${e.slice(0,57)}..."`:`"${e}"`:typeof e=="number"||typeof e=="boolean"?String(e):Array.isArray(e)?`[${e.length} items]`:JSON.stringify(e).slice(0,60)}function Gr(e){let t=[];new Set(e.unmet.map(o=>o.requirement.type));new Set(e.resolverDefs.map(o=>o.requirement));for(let o of e.resolverDefs)o.requirement;for(let o of e.unmet)e.resolverDefs.some(a=>a.requirement===o.requirement.type||a.requirement==="(predicate)")||t.push(`No resolver for requirement type "${o.requirement.type}"`);return t}async function yt(e){let{filePath:t,opts:r}=zr(e);t||(console.error("Usage: directive inspect <file> [--json] [--module <name>]"),process.exit(1));let s=await U(t);s.isRunning||s.start();let n=s.inspect();if(r.json){let a={};if(s.facts)for(let l of Object.keys(s.facts))try{a[l]=s.facts[l];}catch{a[l]="(error reading)";}console.log(JSON.stringify({facts:a,...n},null,2)),s.stop();return}console.log(),console.log(g.bold(g.cyan("Directive System Inspection"))),console.log(g.dim("\u2500".repeat(40))),console.log();let o={};if(s.facts)for(let a of Object.keys(s.facts))try{o[a]=s.facts[a];}catch{o[a]="(error reading)";}console.log(_r(o)),console.log(),console.log(Ur(n.constraints)),console.log(),console.log(Wr(n.resolverDefs,n.resolvers)),console.log(),console.log(Br(n.unmet)),console.log(),n.inflight.length>0&&(console.log(Lr(n.inflight)),console.log());let i=Gr(n);if(i.length>0){console.log(g.bold(g.yellow("Warnings:")));for(let a of i)console.log(` ${g.yellow("\u26A0")} ${a}`);console.log();}s.stop();}function bt(e){let t={with:[],minimal:false,dir:process.cwd()};for(let r=0;r<e.length;r++)switch(e[r]){case "--with":{let n=e[++r];n&&(t.with=n.split(",").map(o=>o.trim()));break}case "--minimal":t.minimal=true;break;case "--dir":{let n=e[++r];n&&(t.dir=n);break}}return t}var vt=["derive","events","constraints","resolvers","effects"];function Xr(e,t){let r=wt(e),s=t.includes("constraints"),n=t.includes("resolvers"),i=`import { ${["type ModuleSchema","createModule","t"].join(", ")} } from "@directive-run/core";
713
713
 
714
714
  `;return i+=`const schema = {
715
715
  `,i+=` facts: {
@@ -778,7 +778,7 @@ export default system;
778
778
  `,i+=` },
779
779
  `,i+=` },
780
780
  `),i+=`});
781
- `,i}function Ur(e){let t=pt(e);return `import { type ModuleSchema, createModule, createSystem, t } from "@directive-run/core";
781
+ `,i}function Zr(e){let t=wt(e);return `import { type ModuleSchema, createModule, createSystem, t } from "@directive-run/core";
782
782
  import {
783
783
  createAgentOrchestrator,
784
784
  createAgentMemory,
@@ -909,9 +909,9 @@ export const memory = createAgentMemory({
909
909
  export const system = createSystem({
910
910
  module: ${t},
911
911
  });
912
- `}function pt(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function mt(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}function gt(e){return join(e,"src")}async function ht(e,t){let r=dt(t);(!e||!/^[a-z][a-z0-9-]*$/.test(e))&&(console.error(`Invalid module name: ${e||"(none)"}
913
- 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(l=>ft.includes(l)):s=ft;let n=gt(r.dir),o=join(n,`${e}.ts`);existsSync(o)&&(console.error(`File already exists: ${relative(r.dir,o)}`),process.exit(1));let i=_r(e,s);mt(o,i);let a=relative(r.dir,o);console.log(`${g.green("Created")} ${g.dim(a)}`),s.length===0?console.log(g.dim(" Minimal module (schema + init only)")):console.log(g.dim(` Sections: ${s.join(", ")}`));}async function yt(e,t){let r=dt(t);(!e||!/^[a-z][a-z0-9-]*$/.test(e))&&(console.error(`Invalid orchestrator name: ${e||"(none)"}
914
- Must start with a letter, use lowercase letters, numbers, and hyphens.`),process.exit(1));let s=gt(r.dir),n=join(s,`${e}.ts`);existsSync(n)&&(console.error(`File already exists: ${relative(r.dir,n)}`),process.exit(1));let o=Ur(e);mt(n,o);let i=relative(r.dir,n);console.log(`${g.green("Created")} ${g.dim(i)}`),console.log(g.dim(" AI orchestrator with memory, guardrails, and streaming"));}var ye=typeof process<"u"&&process.env?.NODE_ENV!=="production";Object.freeze(new Set(["__proto__","constructor","prototype"]));var F=new Set(["$eq","$ne","$in","$nin","$exists","$gt","$gte","$lt","$lte","$between","$matches","$startsWith","$endsWith","$contains","$changed"]),bt=new Set(["$all","$any","$not"]),ie=64;function I(e){return typeof e!="object"||e===null||Array.isArray(e)?false:!(e instanceof Date)&&!(e instanceof RegExp)}function ve(e){if(typeof e!="object"||e===null||Array.isArray(e))return false;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function qe(e){if(!I(e))return false;let t=0,r=false;for(let s of Object.keys(e)){if(s.startsWith("$"))r=true,F.has(s)||ae(`predicate: unknown operator "${s}" \u2014 looks like a typo. Known operators: ${[...F].join(", ")}`);else if(r||t===0)return false;t++;}return r?t>0:false}function wt(e){return e===null?false:Array.isArray(e)?e.every(t=>ve(t)&&"fact"in t&&"op"in t):ve(e)}function oe(e,t,r="",s=new WeakSet,n=0){if(n>ie){ye&&console.warn(`[Directive] predicate depth limit (${ie}) exceeded \u2014 flatten the predicate or split it into multiple constraints. If this is unexpected, check for a cyclic spec object.`),t.bail?.("depth");return}if(Array.isArray(e)){e.forEach((i,a)=>{if(!I(i))return;let l=i;if(typeof l.fact=="string"&&typeof l.op=="string"){let c=r?`${r}[${a}]`:`[${a}]`;t.operator?.(r?`${r}.${l.fact}`:l.fact,l.op,l.value,`${c}.value`);}});return}if(!I(e))return;if(s.has(e)){ye&&console.warn("[Directive] walkPredicate: cyclic predicate spec"),t.bail?.("cycle");return}s.add(e);let o=e;for(let i of ["$all","$any","$not"])if(i in o){if(t.combinator?.(i)===false)return;let a=i==="$not"?[o.$not]:o[i]??[];for(let l of a)oe(l,t,r,s,n+1);return}for(let i of Object.keys(o)){let a=r?`${r}.${i}`:i;if(i.startsWith("$")){t.strayOperatorKey?.(i,a);continue}let l=o[i];if(qe(l)){let c=l;for(let f of Object.keys(c))t.operator?.(a,f,c[f],`${a}.${f}`);continue}if(ve(l)){if(t.nested?.(i)===false)continue;oe(l,t,a,s,n+1);continue}t.literal?.(a,l);}}function $t(e,t=""){function r(n,o,i,a){if(typeof n=="bigint")throw new Error(`[Directive] validatePredicate: bigint operand at "${o}" is not JSON-serializable (JSON.stringify throws on bigint).`);if(n instanceof Set)throw new Error(`[Directive] validatePredicate: Set operand at "${o}" is not JSON-serializable (serializes to {} and loses all members).`);if(n instanceof Map)throw new Error(`[Directive] validatePredicate: Map operand at "${o}" is not JSON-serializable (serializes to {} and loses all entries).`);if(n instanceof RegExp)throw new Error(`[Directive] validatePredicate: RegExp operand at "${o}" is not JSON-serializable (a regex lost to JSON.parse becomes {}). Only a direct $matches operand may be a RegExp.`);if(!(n===null||typeof n!="object")&&!(a>ie)&&!i.has(n)){if(i.add(n),Array.isArray(n)){n.forEach((l,c)=>{r(l,`${o}[${c}]`,i,a+1);});return}for(let l of Object.keys(n))r(n[l],o?`${o}.${l}`:l,i,a+1);}}function s(n,o,i){if(typeof n=="bigint")throw new Error(`[Directive] validatePredicate: bigint operand at "${i}" is not JSON-serializable (JSON.stringify throws on bigint).`);if(n instanceof Set)throw new Error(`[Directive] validatePredicate: Set operand at "${i}" is not JSON-serializable (serializes to {} and loses all members).`);if(n instanceof Map)throw new Error(`[Directive] validatePredicate: Map operand at "${i}" is not JSON-serializable (serializes to {} and loses all entries).`);if(o==="$matches"&&!(n instanceof RegExp))throw new Error(`[Directive] validatePredicate: $matches operand at "${i}" must be a RegExp; got ${n===null?"null":typeof n}. A regex lost to JSON.parse becomes {} \u2014 reify with new RegExp(pattern, flags) before installing.`);if(Array.isArray(n))n.forEach((a,l)=>{r(a,`${i}[${l}]`,new WeakSet,1);});else if(ve(n))for(let a of Object.keys(n))r(n[a],`${i}.${a}`,new WeakSet,1);}if(e instanceof Set)throw new Error(`[Directive] validatePredicate: Set operand${t?` at "${t}"`:""} is not JSON-serializable (serializes to {} and loses all members).`);if(e instanceof Map)throw new Error(`[Directive] validatePredicate: Map operand${t?` at "${t}"`:""} is not JSON-serializable (serializes to {} and loses all entries).`);oe(e,{operator(n,o,i,a){s(i,o,t?`${t}.${a}`:a);},literal(n,o){s(o,"",t?`${t}.${n}`:n);}});}function Br(){return {ids:new WeakMap,next:{v:1},pairs:new Set}}function vt(e,t){let r=e.ids.get(t);return r===void 0&&(r=e.next.v++,e.ids.set(t,r)),r}function q(e,t,r){if(Object.is(e,t))return true;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(typeof e!="object"||typeof t!="object"||e===null||t===null)return false;let s=r??Br(),n=`${vt(s,e)}:${vt(s,t)}`;if(s.pairs.has(n))return true;if(s.pairs.add(n),Array.isArray(e)||Array.isArray(t))return !Array.isArray(e)||!Array.isArray(t)||e.length!==t.length?false:e.every((a,l)=>q(a,t[l],s));if(e instanceof Set||t instanceof Set){if(!(e instanceof Set)||!(t instanceof Set)||e.size!==t.size)return false;let a=[...t];return [...e].every(l=>a.some(c=>q(l,c,s)))}if(e instanceof Map||t instanceof Map){if(!(e instanceof Map)||!(t instanceof Map)||e.size!==t.size)return false;let a=[...t.entries()],l=new Array(a.length).fill(false);for(let[c,f]of e){let u=false;for(let p=0;p<a.length;p++){if(l[p])continue;let[k,j]=a[p];if(q(c,k,s)&&q(f,j,s)){l[p]=true,u=true;break}}if(!u)return false}return true}let o=Object.keys(e),i=Object.keys(t);return o.length!==i.length?false:o.every(a=>Object.hasOwn(t,a)&&q(e[a],t[a],s))}function be(e){if(e instanceof Date)return e.getTime();if(typeof e=="number"||typeof e=="bigint"||typeof e=="string")return e}function Me(e,t,r){let s=be(t),n=be(r);if(s===void 0||n===void 0||typeof s!=typeof n)return false;switch(e){case "$gt":return s>n;case "$gte":return s>=n;case "$lt":return s<n;case "$lte":return s<=n;default:return false}}function we(e,t,r,s){switch(e){case "$eq":return q(t,r);case "$ne":return !q(t,r);case "$in":return Array.isArray(r)&&r.some(n=>q(t,n));case "$nin":return Array.isArray(r)&&!r.some(n=>q(t,n));case "$exists":return r===(t!==void 0);case "$changed":return !q(t,s);case "$gt":case "$gte":case "$lt":case "$lte":return Me(e,t,r);case "$between":{if(!Array.isArray(r)||r.length!==2)return false;let n=be(r[0]),o=be(r[1]);return n!==void 0&&o!==void 0&&typeof n==typeof o&&n>o?(ae("$between: reversed pair \u2014 [min, max] required"),false):Me("$gte",t,r[0])&&Me("$lte",t,r[1])}case "$matches":{if(!(r instanceof RegExp))throw new Error("[Directive] $matches: operand must be a RegExp (string operands are no longer accepted; pass /pattern/flags directly).");return typeof t!="string"?false:r.test(t)}case "$startsWith":return typeof t!="string"?false:t.startsWith(String(r));case "$endsWith":return typeof t!="string"?false:t.endsWith(String(r));case "$contains":return typeof t=="string"?t.includes(String(r)):Array.isArray(t)?t.some(n=>q(n,r)):t instanceof Set?t.has(r):false;default:return false}}function ae(e){ye&&console.warn(`[Directive] ${e}`);}function Lr(e,t,r,s){if(qe(e)){let n=Object.keys(e);n.length>1&&ae(`predicate: operator object has ${n.length} operators (${n.join(", ")}) \u2014 write the array form or $all instead. The runtime ANDs them as a best-effort fallback.`);for(let o of n)if(!we(o,t,e[o],r))return false;return true}return I(e)?J(e,I(t)?t:Object.create(null),I(r)?r:void 0,s+1):q(t,e)}function J(e,t,r,s=0){if(s>ie)return ae(`predicate depth limit (${ie}) exceeded \u2014 flatten the predicate or split it into multiple constraints. If this is unexpected, check for a cyclic spec object.`),false;if(Array.isArray(e))return e.every(n=>{if(!I(n))return false;let{fact:o,op:i,value:a}=n;return we(i,t?.[o],a,r?.[o])});if(!I(e))return !!e;if("$all"in e)return e.$all.every(n=>J(n,t,r,s+1));if("$any"in e)return e.$any.some(n=>J(n,t,r,s+1));if("$not"in e)return !J(e.$not,t,r,s+1);for(let n of Object.keys(e)){if(F.has(n))return ae(`predicate: operator "${n}" mixed with fact keys \u2014 wrap operators in a per-fact object`),false;if(!Lr(e[n],t?.[n],r?.[n],s))return false}return true}function le(e,t,r,s=""){let n=[];if(Array.isArray(e)){for(let o of e){if(!I(o))continue;let{fact:i,op:a,value:l}=o,c=t?.[i];n.push({path:s+i,op:a,expected:l,actual:c,pass:we(a,c,l,r?.[i])});}return n}if(!I(e))return n;for(let o of ["$all","$any","$not"])if(o in e){let i=o==="$not"?[e.$not]:e[o],a=[];for(let f of i)a.push(...le(f,t,r,s));let l=a.filter(f=>f.pass).length,c;return o==="$all"?c=a.length===0||l===a.length:o==="$any"?c=a.length>0&&l>0:c=!a.every(f=>f.pass),n.push({path:s||o,op:o,expected:i.length,actual:l,pass:c,children:a}),n}for(let o of Object.keys(e)){if(F.has(o))continue;let i=e[o],a=t?.[o],l=s+o;if(qe(i))for(let c of Object.keys(i))n.push({path:l,op:c,expected:i[c],actual:a,pass:we(c,a,i[c],r?.[o])});else I(i)?n.push(...le(i,I(a)?a:Object.create(null),I(r?.[o])?r?.[o]:void 0,`${l}.`)):n.push({path:l,op:"$eq",expected:i,actual:a,pass:q(a,i)});}return n}var ee=1e6;function St(e,t){try{$t(e);}catch(s){let n=s instanceof Error?s.message:String(s);throw new Error(`[Directive] replayUnder: the ${t} predicate is invalid \u2014 ${n}`)}if(!wt(e)){let s=e===null||typeof e!="object"?`${typeof e} \u2014 ${JSON.stringify(e)}`:JSON.stringify(e).slice(0,80);throw new Error(`[Directive] replayUnder: the ${t} predicate is not a valid FactPredicate (got ${s})`)}let r;if(oe(e,{operator(s,n){r===void 0&&n.startsWith("$")&&!F.has(n)&&(r=n);},strayOperatorKey(s){r===void 0&&!F.has(s)&&!bt.has(s)&&(r=s);}}),r!==void 0)throw new Error(`[Directive] replayUnder: the ${t} predicate uses an unknown operator "${r}" \u2014 known operators: ${[...F].join(", ")}`)}function Ie(e){if(e&&typeof e=="object"&&!Array.isArray(e)&&Array.isArray(e.snapshots))return Kr(e);let t=Array.isArray(e)?e:e&&typeof e=="object"&&Array.isArray(e.frames)?e.frames:null;if(!t)throw new Error("[Directive] toReplayFrames: history must be a JSON array of frames, an object with a `frames` array, or a history export with a `snapshots` array");if(t.length>ee)throw new Error(`[Directive] toReplayFrames: history has ${t.length} frames, exceeds the MAX_REPLAY_FRAMES limit (${ee}) \u2014 split or down-sample the history`);return t.map((r,s)=>{if(r&&typeof r=="object"&&"facts"in r){let n=r,o={id:n.id??`#${s}`,facts:n.facts??{}};return typeof n.timestamp=="number"&&(o.timestamp=n.timestamp),o}return {id:`#${s}`,facts:r??{}}})}function Kr(e){let t=typeof e=="string"?JSON.parse(e):e;if(Array.isArray(t))return kt(t);if(!t||typeof t!="object")throw new Error("[Directive] framesFromHistory: expected a history export object with a `snapshots` array (from system.history.export())");let r=t;if(r.version!==void 0&&r.version!==1)throw new Error(`[Directive] framesFromHistory: unsupported history export version ${JSON.stringify(r.version)} \u2014 expected 1`);if(!Array.isArray(r.snapshots))throw new Error("[Directive] framesFromHistory: expected a history export object with a `snapshots` array (from system.history.export())");return kt(r.snapshots)}function kt(e){if(!Array.isArray(e))throw new Error("[Directive] framesFromSnapshots: expected an array of fact-state snapshots");if(e.length>ee)throw new Error(`[Directive] framesFromSnapshots: history has ${e.length} snapshots, exceeds the MAX_REPLAY_FRAMES limit (${ee}) \u2014 split or down-sample the history`);for(let t=0;t<e.length;t++){let r=e[t];if(!r||typeof r!="object"||!("facts"in r))throw new Error(`[Directive] framesFromSnapshots: snapshot at index ${t} is not a { facts, ... } object`)}return Ie(e)}function Rt(e){let{frames:t,original:r,proposed:s,entityKey:n}=e,o=e.maxSamples??20,i=o>0?o:0;if(t.length>ee)throw new Error(`[Directive] replayUnder: history has ${t.length} frames, exceeds the MAX_REPLAY_FRAMES limit (${ee}) \u2014 split or down-sample the history`);St(r,"original"),St(s,"proposed");let a=0,l=0,c=0,f=0,u=0,p=[],k=[],j=n?new Set:void 0,x=n?new Set:void 0,G;for(let d of t){let $=d.facts,z=J(r,$,G),Se=J(s,$,G);z&&(a++,j?.add($[n])),Se&&(l++,x?.add($[n])),z===Se?u++:!z&&Se?(c++,p.length<i&&p.push(xt(d,r,s,G))):(f++,k.length<i&&k.push(xt(d,r,s,G))),G=$;}let te={framesEvaluated:t.length,original:{matched:a},proposed:{matched:l},delta:l-a,newMatchCount:c,lostMatchCount:f,unchanged:u,newMatches:p,lostMatches:k};return j&&x&&(te.original.matchedEntities=j.size,te.proposed.matchedEntities=x.size),te}function xt(e,t,r,s){let n=e.facts,o={frameId:e.id,facts:n,originalExplain:le(t,n,s),proposedExplain:le(r,n,s)};return e.timestamp!==void 0&&(o.timestamp=e.timestamp),o}function Vr(e){let t={maxSamples:20,json:false};for(let r=0;r<e.length;r++)switch(e[r]){case "--history":{let n=e[++r];n&&(t.historyPath=n);break}case "--proposed":case "-p":{let n=e[++r];n&&(t.proposedPath=n);break}case "--original":case "-o":{let n=e[++r];n&&(t.originalPath=n);break}case "--max-samples":{let n=e[++r],o=n?Number.parseInt(n,10):Number.NaN;Number.isFinite(o)&&o>=0&&(t.maxSamples=o);break}case "--entity-key":{let n=e[++r];n&&(t.entityKey=n);break}case "--json":t.json=true;break}return t}function $e(){console.error(`
912
+ `}function wt(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function $t(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}function St(e){return join(e,"src")}async function kt(e,t){let r=bt(t);(!e||!/^[a-z][a-z0-9-]*$/.test(e))&&(console.error(`Invalid module name: ${e||"(none)"}
913
+ 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(l=>vt.includes(l)):s=vt;let n=St(r.dir),o=join(n,`${e}.ts`);existsSync(o)&&(console.error(`File already exists: ${relative(r.dir,o)}`),process.exit(1));let i=Xr(e,s);$t(o,i);let a=relative(r.dir,o);console.log(`${g.green("Created")} ${g.dim(a)}`),s.length===0?console.log(g.dim(" Minimal module (schema + init only)")):console.log(g.dim(` Sections: ${s.join(", ")}`));}async function xt(e,t){let r=bt(t);(!e||!/^[a-z][a-z0-9-]*$/.test(e))&&(console.error(`Invalid orchestrator name: ${e||"(none)"}
914
+ Must start with a letter, use lowercase letters, numbers, and hyphens.`),process.exit(1));let s=St(r.dir),n=join(s,`${e}.ts`);existsSync(n)&&(console.error(`File already exists: ${relative(r.dir,n)}`),process.exit(1));let o=Zr(e);$t(n,o);let i=relative(r.dir,n);console.log(`${g.green("Created")} ${g.dim(i)}`),console.log(g.dim(" AI orchestrator with memory, guardrails, and streaming"));}var $e=typeof process<"u"&&process.env?.NODE_ENV!=="production";Object.freeze(new Set(["__proto__","constructor","prototype"]));var B=new Set(["$eq","$ne","$in","$nin","$exists","$gt","$gte","$lt","$lte","$between","$matches","$startsWith","$endsWith","$contains","$changed"]),Et=new Set(["$all","$any","$not"]),L=64;function T(e){return typeof e!="object"||e===null||Array.isArray(e)?false:!(e instanceof Date)&&!(e instanceof RegExp)}function Se(e){if(typeof e!="object"||e===null||Array.isArray(e))return false;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function Fe(e){if(!T(e))return false;let t=0,r=false;for(let s of Object.keys(e)){if(s.startsWith("$"))r=true,B.has(s)||ce(`predicate: unknown operator "${s}" \u2014 looks like a typo. Known operators: ${[...B].join(", ")}`);else if(r||t===0)return false;t++;}return r?t>0:false}function Ct(e){return e===null?false:Array.isArray(e)?e.every(t=>Se(t)&&"fact"in t&&"op"in t):Se(e)}function le(e,t,r="",s=new WeakSet,n=0){if(n>L){$e&&console.warn(`[Directive] predicate depth limit (${L}) exceeded \u2014 flatten the predicate or split it into multiple constraints. If this is unexpected, check for a cyclic spec object.`),t.bail?.("depth");return}if(Array.isArray(e)){e.forEach((i,a)=>{if(!T(i))return;let l=i;if(typeof l.fact=="string"&&typeof l.op=="string"){let c=r?`${r}[${a}]`:`[${a}]`;t.operator?.(r?`${r}.${l.fact}`:l.fact,l.op,l.value,`${c}.value`);}});return}if(!T(e))return;if(s.has(e)){$e&&console.warn("[Directive] walkPredicate: cyclic predicate spec"),t.bail?.("cycle");return}s.add(e);let o=e;for(let i of ["$all","$any","$not"])if(i in o){if(t.combinator?.(i)===false)return;let a=i==="$not"?[o.$not]:o[i]??[];for(let l of a)le(l,t,r,s,n+1);return}for(let i of Object.keys(o)){let a=r?`${r}.${i}`:i;if(i.startsWith("$")){t.strayOperatorKey?.(i,a);continue}let l=o[i];if(Fe(l)){let c=l;for(let d of Object.keys(c))t.operator?.(a,d,c[d],`${a}.${d}`);continue}if(Se(l)){if(t.nested?.(i)===false)continue;le(l,t,a,s,n+1);continue}t.literal?.(a,l);}}function Dt(e,t=""){function r(n,o,i,a){if(typeof n=="bigint")throw new Error(`[Directive] validatePredicate: bigint operand at "${o}" is not JSON-serializable (JSON.stringify throws on bigint).`);if(n instanceof Set)throw new Error(`[Directive] validatePredicate: Set operand at "${o}" is not JSON-serializable (serializes to {} and loses all members).`);if(n instanceof Map)throw new Error(`[Directive] validatePredicate: Map operand at "${o}" is not JSON-serializable (serializes to {} and loses all entries).`);if(n instanceof RegExp)throw new Error(`[Directive] validatePredicate: RegExp operand at "${o}" is not JSON-serializable (a regex lost to JSON.parse becomes {}). Only a direct $matches operand may be a RegExp.`);if(!(n===null||typeof n!="object")&&!(a>L)&&!i.has(n)){if(i.add(n),Array.isArray(n)){n.forEach((l,c)=>{r(l,`${o}[${c}]`,i,a+1);});return}for(let l of Object.keys(n))r(n[l],o?`${o}.${l}`:l,i,a+1);}}function s(n,o,i){if(typeof n=="bigint")throw new Error(`[Directive] validatePredicate: bigint operand at "${i}" is not JSON-serializable (JSON.stringify throws on bigint).`);if(n instanceof Set)throw new Error(`[Directive] validatePredicate: Set operand at "${i}" is not JSON-serializable (serializes to {} and loses all members).`);if(n instanceof Map)throw new Error(`[Directive] validatePredicate: Map operand at "${i}" is not JSON-serializable (serializes to {} and loses all entries).`);if(o==="$matches"&&!(n instanceof RegExp))throw new Error(`[Directive] validatePredicate: $matches operand at "${i}" must be a RegExp; got ${n===null?"null":typeof n}. A regex lost to JSON.parse becomes {} \u2014 reify with new RegExp(pattern, flags) before installing.`);if(Array.isArray(n))n.forEach((a,l)=>{r(a,`${i}[${l}]`,new WeakSet,1);});else if(Se(n))for(let a of Object.keys(n))r(n[a],`${i}.${a}`,new WeakSet,1);}if(e instanceof Set)throw new Error(`[Directive] validatePredicate: Set operand${t?` at "${t}"`:""} is not JSON-serializable (serializes to {} and loses all members).`);if(e instanceof Map)throw new Error(`[Directive] validatePredicate: Map operand${t?` at "${t}"`:""} is not JSON-serializable (serializes to {} and loses all entries).`);le(e,{operator(n,o,i,a){s(i,o,t?`${t}.${a}`:a);},literal(n,o){s(o,"",t?`${t}.${n}`:n);}});}function en(){return {ids:new WeakMap,next:{v:1},pairs:new Set}}function Rt(e,t){let r=e.ids.get(t);return r===void 0&&(r=e.next.v++,e.ids.set(t,r)),r}function P(e,t,r){if(Object.is(e,t))return true;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(typeof e!="object"||typeof t!="object"||e===null||t===null)return false;let s=r??en(),n=`${Rt(s,e)}:${Rt(s,t)}`;if(s.pairs.has(n))return true;if(s.pairs.add(n),Array.isArray(e)||Array.isArray(t))return !Array.isArray(e)||!Array.isArray(t)||e.length!==t.length?false:e.every((a,l)=>P(a,t[l],s));if(e instanceof Set||t instanceof Set){if(!(e instanceof Set)||!(t instanceof Set)||e.size!==t.size)return false;let a=[...t];return [...e].every(l=>a.some(c=>P(l,c,s)))}if(e instanceof Map||t instanceof Map){if(!(e instanceof Map)||!(t instanceof Map)||e.size!==t.size)return false;let a=[...t.entries()],l=new Array(a.length).fill(false);for(let[c,d]of e){let u=false;for(let f=0;f<a.length;f++){if(l[f])continue;let[v,x]=a[f];if(P(c,v,s)&&P(d,x,s)){l[f]=true,u=true;break}}if(!u)return false}return true}let o=Object.keys(e),i=Object.keys(t);return o.length!==i.length?false:o.every(a=>Object.hasOwn(t,a)&&P(e[a],t[a],s))}function ke(e){if(e instanceof Date)return e.getTime();if(typeof e=="number"||typeof e=="bigint"||typeof e=="string")return e}function Ne(e,t,r){let s=ke(t),n=ke(r);if(s===void 0||n===void 0||typeof s!=typeof n)return false;switch(e){case "$gt":return s>n;case "$gte":return s>=n;case "$lt":return s<n;case "$lte":return s<=n;default:return false}}function xe(e,t,r,s){switch(e){case "$eq":return P(t,r);case "$ne":return !P(t,r);case "$in":return Array.isArray(r)&&r.some(n=>P(t,n));case "$nin":return Array.isArray(r)&&!r.some(n=>P(t,n));case "$exists":return r===(t!==void 0);case "$changed":return !P(t,s);case "$gt":case "$gte":case "$lt":case "$lte":return Ne(e,t,r);case "$between":{if(!Array.isArray(r)||r.length!==2)return false;let n=ke(r[0]),o=ke(r[1]);return n!==void 0&&o!==void 0&&typeof n==typeof o&&n>o?(ce("$between: reversed pair \u2014 [min, max] required"),false):Ne("$gte",t,r[0])&&Ne("$lte",t,r[1])}case "$matches":{if(!(r instanceof RegExp))throw new Error("[Directive] $matches: operand must be a RegExp (string operands are no longer accepted; pass /pattern/flags directly).");return typeof t!="string"?false:r.test(t)}case "$startsWith":return typeof t!="string"?false:t.startsWith(String(r));case "$endsWith":return typeof t!="string"?false:t.endsWith(String(r));case "$contains":return typeof t=="string"?t.includes(String(r)):Array.isArray(t)?t.some(n=>P(n,r)):t instanceof Set?t.has(r):false;default:return false}}function ce(e){$e&&console.warn(`[Directive] ${e}`);}function tn(e,t,r,s){if(Fe(e)){let n=Object.keys(e);n.length>1&&ce(`predicate: operator object has ${n.length} operators (${n.join(", ")}) \u2014 write the array form or $all instead. The runtime ANDs them as a best-effort fallback.`);for(let o of n)if(!xe(o,t,e[o],r))return false;return true}return T(e)?X(e,T(t)?t:Object.create(null),T(r)?r:void 0,s+1):P(t,e)}function X(e,t,r,s=0){if(s>L)return ce(`predicate depth limit (${L}) exceeded \u2014 flatten the predicate or split it into multiple constraints. If this is unexpected, check for a cyclic spec object.`),false;if(Array.isArray(e))return e.every(n=>{if(!T(n))return false;let{fact:o,op:i,value:a}=n;return xe(i,t?.[o],a,r?.[o])});if(!T(e))return !!e;if("$all"in e)return e.$all.every(n=>X(n,t,r,s+1));if("$any"in e)return e.$any.some(n=>X(n,t,r,s+1));if("$not"in e)return !X(e.$not,t,r,s+1);for(let n of Object.keys(e)){if(B.has(n))return ce(`predicate: operator "${n}" mixed with fact keys \u2014 wrap operators in a per-fact object`),false;if(!tn(e[n],t?.[n],r?.[n],s))return false}return true}function ue(e,t,r,s=""){let n=[];if(Array.isArray(e)){for(let o of e){if(!T(o))continue;let{fact:i,op:a,value:l}=o,c=t?.[i];n.push({path:s+i,op:a,expected:l,actual:c,pass:xe(a,c,l,r?.[i])});}return n}if(!T(e))return n;for(let o of ["$all","$any","$not"])if(o in e){let i=o==="$not"?[e.$not]:e[o],a=[];for(let d of i)a.push(...ue(d,t,r,s));let l=a.filter(d=>d.pass).length,c;return o==="$all"?c=a.length===0||l===a.length:o==="$any"?c=a.length>0&&l>0:c=!a.every(d=>d.pass),n.push({path:s||o,op:o,expected:i.length,actual:l,pass:c,children:a}),n}for(let o of Object.keys(e)){if(B.has(o))continue;let i=e[o],a=t?.[o],l=s+o;if(Fe(i))for(let c of Object.keys(i))n.push({path:l,op:c,expected:i[c],actual:a,pass:xe(c,a,i[c],r?.[o])});else T(i)?n.push(...ue(i,T(a)?a:Object.create(null),T(r?.[o])?r?.[o]:void 0,`${l}.`)):n.push({path:l,op:"$eq",expected:i,actual:a,pass:P(a,i)});}return n}var se=1e6;function jt(e,t){try{Dt(e);}catch(s){let n=s instanceof Error?s.message:String(s);throw new Error(`[Directive] replayUnder: the ${t} predicate is invalid \u2014 ${n}`)}if(!Ct(e)){let s=e===null||typeof e!="object"?`${typeof e} \u2014 ${JSON.stringify(e)}`:JSON.stringify(e).slice(0,80);throw new Error(`[Directive] replayUnder: the ${t} predicate is not a valid FactPredicate (got ${s})`)}let r;if(le(e,{operator(s,n){r===void 0&&n.startsWith("$")&&!B.has(n)&&(r=n);},strayOperatorKey(s){r===void 0&&!B.has(s)&&!Et.has(s)&&(r=s);}}),r!==void 0)throw new Error(`[Directive] replayUnder: the ${t} predicate uses an unknown operator "${r}" \u2014 known operators: ${[...B].join(", ")}`)}function fe(e){if(e&&typeof e=="object"&&!Array.isArray(e)&&Array.isArray(e.snapshots))return rn(e);let t=Array.isArray(e)?e:e&&typeof e=="object"&&Array.isArray(e.frames)?e.frames:null;if(!t)throw new Error("[Directive] toReplayFrames: history must be a JSON array of frames, an object with a `frames` array, or a history export with a `snapshots` array");if(t.length>se)throw new Error(`[Directive] toReplayFrames: history has ${t.length} frames, exceeds the MAX_REPLAY_FRAMES limit (${se}) \u2014 split or down-sample the history`);return t.map((r,s)=>{if(r&&typeof r=="object"&&"facts"in r){let n=r,o={id:n.id??`#${s}`,facts:n.facts??{}};return typeof n.timestamp=="number"&&(o.timestamp=n.timestamp),o}return {id:`#${s}`,facts:r??{}}})}function rn(e){let t=typeof e=="string"?JSON.parse(e):e;if(Array.isArray(t))return Ot(t);if(!t||typeof t!="object")throw new Error("[Directive] framesFromHistory: expected a history export object with a `snapshots` array (from system.history.export())");let r=t;if(r.version!==void 0&&r.version!==1)throw new Error(`[Directive] framesFromHistory: unsupported history export version ${JSON.stringify(r.version)} \u2014 expected 1`);if(!Array.isArray(r.snapshots))throw new Error("[Directive] framesFromHistory: expected a history export object with a `snapshots` array (from system.history.export())");return Ot(r.snapshots)}function Ot(e){if(!Array.isArray(e))throw new Error("[Directive] framesFromSnapshots: expected an array of fact-state snapshots");if(e.length>se)throw new Error(`[Directive] framesFromSnapshots: history has ${e.length} snapshots, exceeds the MAX_REPLAY_FRAMES limit (${se}) \u2014 split or down-sample the history`);for(let t=0;t<e.length;t++){let r=e[t];if(!r||typeof r!="object"||!("facts"in r))throw new Error(`[Directive] framesFromSnapshots: snapshot at index ${t} is not a { facts, ... } object`)}return fe(e)}function Re(e){let{frames:t,original:r,proposed:s,entityKey:n}=e,o=e.maxSamples??20,i=o>0?o:0;if(t.length>se)throw new Error(`[Directive] replayUnder: history has ${t.length} frames, exceeds the MAX_REPLAY_FRAMES limit (${se}) \u2014 split or down-sample the history`);jt(r,"original"),jt(s,"proposed");let a=0,l=0,c=0,d=0,u=0,f=[],v=[],x=n?new Set:void 0,b=n?new Set:void 0,N;for(let p of t){let h=p.facts,D=X(r,h,N),z=X(s,h,N);D&&(a++,x?.add(h[n])),z&&(l++,b?.add(h[n])),D===z?u++:!D&&z?(c++,f.length<i&&f.push(At(p,r,s,N))):(d++,v.length<i&&v.push(At(p,r,s,N))),N=h;}let F={framesEvaluated:t.length,original:{matched:a},proposed:{matched:l},delta:l-a,newMatchCount:c,lostMatchCount:d,unchanged:u,newMatches:f,lostMatches:v};return x&&b&&(F.original.matchedEntities=x.size,F.proposed.matchedEntities=b.size),F}function At(e,t,r,s){let n=e.facts,o={frameId:e.id,facts:n,originalExplain:ue(t,n,s),proposedExplain:ue(r,n,s)};return e.timestamp!==void 0&&(o.timestamp=e.timestamp),o}var Mt=1e4,qt=5e7;function nn(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===1&&typeof e.$hole=="string"}function ze(e,t,r=new Set,s=0){if(s>L)throw new Error(`[Directive] sweepUnder: template exceeds MAX_PREDICATE_DEPTH (${L}) \u2014 flatten the template or split the sweep`);if(nn(e)){let n=e.$hole;if(!(n in t))throw new Error(`[Directive] sweepUnder: template references hole "${n}" but sweep has no values for it`);return t[n]}if(e===null||typeof e!="object")return e;if(r.has(e))throw new Error("[Directive] sweepUnder: template contains a cycle \u2014 predicate templates must be a tree");r.add(e);try{if(Array.isArray(e))return e.map(o=>ze(o,t,r,s+1));let n={};for(let[o,i]of Object.entries(e))n[o]=ze(i,t,r,s+1);return n}finally{r.delete(e);}}function*It(e,t){if(e.length===0){yield {};return}let r=e[0],s=e.slice(1),n=t[r]??[];for(let o of n)for(let i of It(s,t))yield {[r]:o,...i};}function sn(e){let t=1;for(let r of Object.values(e))t*=r.length;return t}function Pt(e){let{frames:t,original:r,template:s,sweep:n,objective:o=h=>h.proposed.matched,entityKey:i,maxSamples:a=0}=e,l=Object.keys(n);if(l.length===0)throw new Error("[Directive] sweepUnder: `sweep` must contain at least one hole name");let c=sn(n);if(c>Mt)throw new Error(`[Directive] sweepUnder: grid has ${c} points, exceeds the MAX_SWEEP_POINTS limit (${Mt}) \u2014 narrow the sweep ranges or split the run`);if(c===0)throw new Error("[Directive] sweepUnder: at least one hole has zero candidate values");let d=c*t.length;if(d>qt)throw new Error(`[Directive] sweepUnder: ${c} points \xD7 ${t.length} frames = ${d} per-frame evaluations, exceeds the MAX_SWEEP_EVALUATIONS limit (${qt}) \u2014 narrow the sweep, down-sample the history, or split the run`);let u=false,f=h=>{let D;try{D=o(h);}catch(z){return u||(u=true,console.warn(`[Directive] sweepUnder: objective threw \u2014 point will not rank (${z.message})`)),Number.NEGATIVE_INFINITY}return typeof D!="number"||!Number.isFinite(D)?(u||(u=true,console.warn(`[Directive] sweepUnder: objective returned a non-finite number (${String(D)}) \u2014 point will not rank`)),Number.NEGATIVE_INFINITY):D},v=Re({frames:t,original:r,proposed:r,entityKey:i,maxSamples:a}),x={values:{},report:v,score:f(v)},b=[],N=0,F=Number.NEGATIVE_INFINITY;for(let h of It(l,n)){let D=ze(s,h),z=Re({frames:t,original:r,proposed:D,entityKey:i,maxSamples:a}),Ce=f(z);Ce>F&&(F=Ce,N=b.length),b.push({values:h,report:z,score:Ce});}let p=b[N];return {points:b,bestIndex:N,best:p,baseline:x}}function cn(e){let t={maxSamples:20,json:false};for(let r=0;r<e.length;r++)switch(e[r]){case "--history":{let n=e[++r];n&&(t.historyPath=n);break}case "--proposed":case "-p":{let n=e[++r];n&&(t.proposedPath=n);break}case "--original":case "-o":{let n=e[++r];n&&(t.originalPath=n);break}case "--max-samples":{let n=e[++r],o=n?Number.parseInt(n,10):Number.NaN;Number.isFinite(o)&&o>=0&&(t.maxSamples=o);break}case "--entity-key":{let n=e[++r];n&&(t.entityKey=n);break}case "--json":t.json=true;break}return t}function Ee(){console.error(`
915
915
  Usage: directive replay-under --history <frames.json> --proposed <spec.json>
916
916
 
917
917
  Replay a recorded fact-frame history through a proposed constraint
@@ -935,13 +935,13 @@ Examples:
935
935
  --original current-rule.json --proposed tightened-rule.json
936
936
  directive replay-under --history sessions.json \\
937
937
  --original a.json --proposed b.json --entity-key userId --json
938
- `);}function Te(e,t){let r=resolve(e);existsSync(r)||(console.error(g.red(`error: ${t} file not found: ${r}`)),process.exit(1));try{return JSON.parse(readFileSync(r,"utf8"))}catch(s){console.error(g.red(`error: failed to parse ${t} (${r}): `)+s.message),process.exit(1);}}function Yr(e){try{return Ie(e)}catch(t){console.error(g.red(`error: ${t.message}`)),process.exit(1);}}function Ct(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===0}function Et(e){let t=Object.entries(e).slice(0,6).map(([s,n])=>`${s}=${JSON.stringify(n)}`),r=Object.keys(e).length-t.length;return t.join(" ")+(r>0?g.dim(` +${r} more`):"")}function Xr(e,t){let{original:r,proposed:s,delta:n}=e,o=n>0?g.green(`+${n}`):n<0?g.red(`${n}`):g.dim("\xB10");if(console.log(`
938
+ `);}function _e(e,t){let r=resolve(e);existsSync(r)||(console.error(g.red(`error: ${t} file not found: ${r}`)),process.exit(1));try{return JSON.parse(readFileSync(r,"utf8"))}catch(s){console.error(g.red(`error: failed to parse ${t} (${r}): `)+s.message),process.exit(1);}}function un(e){try{return fe(e)}catch(t){console.error(g.red(`error: ${t.message}`)),process.exit(1);}}function Tt(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===0}function Nt(e){let t=Object.entries(e).slice(0,6).map(([s,n])=>`${s}=${JSON.stringify(n)}`),r=Object.keys(e).length-t.length;return t.join(" ")+(r>0?g.dim(` +${r} more`):"")}function fn(e,t){let{original:r,proposed:s,delta:n}=e,o=n>0?g.green(`+${n}`):n<0?g.red(`${n}`):g.dim("\xB10");if(console.log(`
939
939
  ${g.bold("replay-under")} \u2014 predicate backtest
940
940
  `),console.log(` frames evaluated ${e.framesEvaluated}`),console.log(` original spec matched ${r.matched} frames`),console.log(` proposed spec matched ${s.matched} frames (${o})`),t&&r.matchedEntities!==void 0&&s.matchedEntities!==void 0&&(console.log(`
941
941
  original spec matched across ${r.matchedEntities} ${t}s`),console.log(` proposed spec matched across ${s.matchedEntities} ${t}s`)),console.log(""),console.log(` ${g.green(`+${e.newMatchCount}`)} new matches ${g.dim("frames that now match the rule")}`),console.log(` ${g.red(`-${e.lostMatchCount}`)} lost matches ${g.dim("frames that no longer match")}`),e.newMatches.length>0){console.log(`
942
- ${g.green("sample new matches:")}`);for(let l of e.newMatches.slice(0,8))console.log(` frame ${l.frameId} ${g.dim(Et(l.facts))}`);}if(e.lostMatches.length>0){console.log(`
943
- ${g.red("sample lost matches:")}`);for(let l of e.lostMatches.slice(0,8))console.log(` frame ${l.frameId} ${g.dim(Et(l.facts))}`);}let i=e.newMatches.length+e.lostMatches.length,a=e.newMatchCount+e.lostMatchCount;i<a&&console.log(g.dim(`
944
- ${i} of ${a} diff frames sampled \u2014 --json for the full report`)),console.log("");}async function Dt(e){(e.includes("--help")||e.length===0)&&($e(),process.exit(e.length===0?1:0));let t=Vr(e);t.historyPath||(console.error(g.red("error: --history <frames.json> is required")),$e(),process.exit(1)),t.proposedPath||(console.error(g.red("error: --proposed <spec.json> is required")),$e(),process.exit(1)),t.originalPath||(console.error(g.red("error: --original <spec.json> is required")+g.dim("\n (v1 cannot recover the constraint's current `when` from a live system)")),$e(),process.exit(1));let r=Yr(Te(t.historyPath,"--history")),s=Te(t.originalPath,"--original"),n=Te(t.proposedPath,"--proposed");Ct(s)&&console.error(g.yellow("warning: --original is an empty predicate {} \u2014 it matches every frame")),Ct(n)&&console.error(g.yellow("warning: --proposed is an empty predicate {} \u2014 it matches every frame"));let o;try{o=Rt({frames:r,original:s,proposed:n,maxSamples:t.maxSamples,entityKey:t.entityKey});}catch(i){console.error(g.red(`error: ${i.message}`)),process.exit(1);}if(t.json){console.log(JSON.stringify(o,null,2));return}Xr(o,t.entityKey);}function tn(e){let t={json:false,dispatchableOnly:true,verbose:false},r="";for(let s=0;s<e.length;s++){let n=e[s];switch(n){case "--system":case "-s":{let o=e[++s];o&&(t.systemPath=o);break}case "--max-frames":{let o=e[++s],i=o?Number.parseInt(o,10):Number.NaN;Number.isFinite(i)&&i>0&&(t.maxFrames=i);break}case "--all-frames":case "--no-dispatchable-only":t.dispatchableOnly=false;break;case "--json":t.json=true;break;case "--verbose":case "-v":t.verbose=true;break;default:n&&!n.startsWith("-")&&!r&&(r=n);}}return {jsonPath:r,opts:t}}function Pe(){console.error(`
942
+ ${g.green("sample new matches:")}`);for(let l of e.newMatches.slice(0,8))console.log(` frame ${l.frameId} ${g.dim(Nt(l.facts))}`);}if(e.lostMatches.length>0){console.log(`
943
+ ${g.red("sample lost matches:")}`);for(let l of e.lostMatches.slice(0,8))console.log(` frame ${l.frameId} ${g.dim(Nt(l.facts))}`);}let i=e.newMatches.length+e.lostMatches.length,a=e.newMatchCount+e.lostMatchCount;i<a&&console.log(g.dim(`
944
+ ${i} of ${a} diff frames sampled \u2014 --json for the full report`)),console.log("");}async function Ft(e){(e.includes("--help")||e.length===0)&&(Ee(),process.exit(e.length===0?1:0));let t=cn(e);t.historyPath||(console.error(g.red("error: --history <frames.json> is required")),Ee(),process.exit(1)),t.proposedPath||(console.error(g.red("error: --proposed <spec.json> is required")),Ee(),process.exit(1)),t.originalPath||(console.error(g.red("error: --original <spec.json> is required")+g.dim("\n (v1 cannot recover the constraint's current `when` from a live system)")),Ee(),process.exit(1));let r=un(_e(t.historyPath,"--history")),s=_e(t.originalPath,"--original"),n=_e(t.proposedPath,"--proposed");Tt(s)&&console.error(g.yellow("warning: --original is an empty predicate {} \u2014 it matches every frame")),Tt(n)&&console.error(g.yellow("warning: --proposed is an empty predicate {} \u2014 it matches every frame"));let o;try{o=Re({frames:r,original:s,proposed:n,maxSamples:t.maxSamples,entityKey:t.entityKey});}catch(i){console.error(g.red(`error: ${i.message}`)),process.exit(1);}if(t.json){console.log(JSON.stringify(o,null,2));return}fn(o,t.entityKey);}function gn(e){let t={json:false,dispatchableOnly:true,verbose:false},r="";for(let s=0;s<e.length;s++){let n=e[s];switch(n){case "--system":case "-s":{let o=e[++s];o&&(t.systemPath=o);break}case "--max-frames":{let o=e[++s],i=o?Number.parseInt(o,10):Number.NaN;Number.isFinite(i)&&i>0&&(t.maxFrames=i);break}case "--all-frames":case "--no-dispatchable-only":t.dispatchableOnly=false;break;case "--json":t.json=true;break;case "--verbose":case "-v":t.verbose=true;break;default:n&&!n.startsWith("-")&&!r&&(r=n);}}return {jsonPath:r,opts:t}}function Ue(){console.error(`
945
945
  Usage: directive replay <timeline.json> [options]
946
946
 
947
947
  Replay a serialized Directive timeline against a fresh system.
@@ -963,8 +963,8 @@ Examples:
963
963
  directive replay bug-1234.json --system src/app/system.ts
964
964
  directive replay error.json --system src/system.ts --json
965
965
  directive replay error.json --system src/system.ts --verbose
966
- `);}async function jt(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(Pe(),process.exit(e.length===0?1:0));let{jsonPath:t,opts:r}=tn(e);t||(console.error(g.red("error: missing <timeline.json> argument")),Pe(),process.exit(1)),r.systemPath||(console.error(g.red("error: --system <path> is required"),g.dim(`
967
- (replay needs a fresh system to dispatch against)`)),Pe(),process.exit(1));let s=resolve(t);existsSync(s)||(console.error(g.red(`error: timeline file not found: ${s}`)),process.exit(1));let n;try{n=readFileSync(s,"utf8");}catch(p){console.error(g.red(`error: failed to read ${s}: ${p.message}`)),process.exit(1);}let o;try{o=JSON.parse(n);}catch(p){console.error(g.red(`error: ${s} is not valid JSON: ${p.message}`)),process.exit(1);}let{deserializeTimeline:i,replayTimeline:a}=await X(r.verbose),l;try{l=i(o);}catch(p){console.error(g.red(`error: timeline JSON failed validation: ${p.message}`)),process.exit(1);}let c;try{c=await P(r.systemPath);}catch(p){console.error(g.red(`error: failed to load system file: ${p.message}`)),process.exit(1);}let f=c;if(typeof f.dispatch!="function"&&(console.error(g.red("error: loaded system has no dispatch() method. The --system file must export a started Directive system or a factory.")),process.exit(1)),typeof f.start=="function")try{f.start();}catch{}let u=await a(l,f,{dispatchableOnly:r.dispatchableOnly,maxFrames:r.maxFrames});if(r.json)console.log(JSON.stringify(u,null,2));else {let{dispatched:p,skipped:k,truncated:j}=u,x=p>0;console.log(`${x?g.green("\u2713"):g.yellow("\u26A0")} replay complete:`,g.bold(`${p} dispatched`),g.dim(`/ ${k} skipped`),j>0?g.yellow(`/ ${j} TRUNCATED`):""),p===0&&console.error(g.yellow("warning: 0 frames dispatched. Either the timeline contains only non-dispatchable frames (system lifecycle, derivations, etc.) or the system shape doesn't match what the timeline recorded.")),j>0&&console.error(g.yellow(`warning: ${j} frames truncated by --max-frames cap. Raise it with --max-frames <n> if you need them.`));}process.exit(0);}function on(e){let t={json:false,verbose:false},r=[];for(let s=0;s<e.length;s++){let n=e[s];switch(n){case "--json":t.json=true;break;case "--verbose":case "-v":t.verbose=true;break;default:n&&!n.startsWith("-")&&r.push(n);}}return {aPath:r[0]??"",bPath:r[1]??"",opts:t}}function Ot(){console.error(`
966
+ `);}async function zt(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(Ue(),process.exit(e.length===0?1:0));let{jsonPath:t,opts:r}=gn(e);t||(console.error(g.red("error: missing <timeline.json> argument")),Ue(),process.exit(1)),r.systemPath||(console.error(g.red("error: --system <path> is required"),g.dim(`
967
+ (replay needs a fresh system to dispatch against)`)),Ue(),process.exit(1));let s=resolve(t);existsSync(s)||(console.error(g.red(`error: timeline file not found: ${s}`)),process.exit(1));let n;try{n=readFileSync(s,"utf8");}catch(f){console.error(g.red(`error: failed to read ${s}: ${f.message}`)),process.exit(1);}let o;try{o=JSON.parse(n);}catch(f){console.error(g.red(`error: ${s} is not valid JSON: ${f.message}`)),process.exit(1);}let{deserializeTimeline:i,replayTimeline:a}=await te(r.verbose),l;try{l=i(o);}catch(f){console.error(g.red(`error: timeline JSON failed validation: ${f.message}`)),process.exit(1);}let c;try{c=await U(r.systemPath);}catch(f){console.error(g.red(`error: failed to load system file: ${f.message}`)),process.exit(1);}let d=c;if(typeof d.dispatch!="function"&&(console.error(g.red("error: loaded system has no dispatch() method. The --system file must export a started Directive system or a factory.")),process.exit(1)),typeof d.start=="function")try{d.start();}catch{}let u=await a(l,d,{dispatchableOnly:r.dispatchableOnly,maxFrames:r.maxFrames});if(r.json)console.log(JSON.stringify(u,null,2));else {let{dispatched:f,skipped:v,truncated:x}=u,b=f>0;console.log(`${b?g.green("\u2713"):g.yellow("\u26A0")} replay complete:`,g.bold(`${f} dispatched`),g.dim(`/ ${v} skipped`),x>0?g.yellow(`/ ${x} TRUNCATED`):""),f===0&&console.error(g.yellow("warning: 0 frames dispatched. Either the timeline contains only non-dispatchable frames (system lifecycle, derivations, etc.) or the system shape doesn't match what the timeline recorded.")),x>0&&console.error(g.yellow(`warning: ${x} frames truncated by --max-frames cap. Raise it with --max-frames <n> if you need them.`));}process.exit(0);}function bn(e){let t={json:false,verbose:false},r=[];for(let s=0;s<e.length;s++){let n=e[s];switch(n){case "--json":t.json=true;break;case "--verbose":case "-v":t.verbose=true;break;default:n&&!n.startsWith("-")&&r.push(n);}}return {aPath:r[0]??"",bPath:r[1]??"",opts:t}}function _t(){console.error(`
968
968
  Usage: directive timeline diff <a.json> <b.json>
969
969
 
970
970
  Compare two serialized Directive timelines as a structured causal-graph
@@ -988,10 +988,39 @@ Exit codes:
988
988
  Examples:
989
989
  directive timeline diff baseline.json regression.json
990
990
  directive timeline diff a.json b.json --json | jq .constraintFires
991
- `);}function ce(e){return e>0?g.green(`+${e}`):e<0?g.red(`${e}`):g.dim(" 0")}function At(e){return e.length===0?[g.dim(" (no differences)")]:e.map(t=>` ${g.bold(t.id.padEnd(28))} ${String(t.aCount).padStart(4)} \u2192 ${String(t.bCount).padStart(4)} (${ce(t.delta)})`)}function an(e){return e.length===0?[g.dim(" (no differences)")]:e.map(t=>` ${g.bold(t.resolver.padEnd(28))} starts ${t.aStarts}\u2192${t.bStarts} (${ce(t.bStarts-t.aStarts)}) completes ${t.aCompletes}\u2192${t.bCompletes} (${ce(t.bCompletes-t.aCompletes)}) errors ${t.aErrors}\u2192${t.bErrors} (${ce(t.bErrors-t.aErrors)})`)}function ln(e){return e.length===0?[g.dim(" (no new errors)")]:e.map(t=>{let r=t.side==="a"?g.cyan("a-only"):g.yellow("b-only"),s=(()=>{try{return JSON.stringify(t.error)}catch{return `[${typeof t.error}]`}})();return ` ${r} frame #${t.frameIndex} ${g.bold(t.kind)} '${t.id}' ${g.dim(s)}`})}function Mt(e){let t=resolve(e);existsSync(t)||(console.error(g.red(`error: timeline file not found: ${t}`)),process.exit(1));let r;try{r=readFileSync(t,"utf8");}catch(s){console.error(g.red(`error: failed to read ${t}: ${s.message}`)),process.exit(1);}try{return JSON.parse(r)}catch(s){console.error(g.red(`error: ${t} is not valid JSON: ${s.message}`)),process.exit(1);}}async function qt(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(Ot(),process.exit(e.length===0?1:0));let{aPath:t,bPath:r,opts:s}=on(e);(!t||!r)&&(console.error(g.red("error: both <a.json> and <b.json> are required")),Ot(),process.exit(1));let{deserializeTimeline:n,diffTimelines:o}=await X(s.verbose),i=Mt(t),a=Mt(r),l,c;try{l=n(i),c=n(a);}catch(u){console.error(g.red(`error: timeline JSON failed validation: ${u.message}`)),process.exit(1);}let f=o(l,c);s.json&&(console.log(JSON.stringify(f,null,2)),process.exit(f.identical?0:2)),f.identical&&(console.log(g.green("\u2713 identical:"),`both timelines have ${f.aFrameCount} frames and the same causal shape.`),process.exit(0)),console.log(g.bold("Timeline diff"),g.dim(`(${t} vs ${r})`)),console.log(""),console.log(`Frames: ${f.aFrameCount} \u2192 ${f.bFrameCount} (${ce(f.frameCountDelta)})`),console.log(""),console.log(g.bold("Constraint fires:"));for(let u of At(f.constraintFires))console.log(u);console.log(""),console.log(g.bold("Mutations:"));for(let u of At(f.mutations))console.log(u);console.log(""),console.log(g.bold("Resolver runs:"));for(let u of an(f.resolverRuns))console.log(u);console.log(""),console.log(g.bold("New errors:"));for(let u of ln(f.newErrors))console.log(u);console.log(""),process.exit(2);}var cn=`
992
- ${R} \u2014 CLI tools for Directive
991
+ `);}function de(e){return e>0?g.green(`+${e}`):e<0?g.red(`${e}`):g.dim(" 0")}function Ut(e){return e.length===0?[g.dim(" (no differences)")]:e.map(t=>` ${g.bold(t.id.padEnd(28))} ${String(t.aCount).padStart(4)} \u2192 ${String(t.bCount).padStart(4)} (${de(t.delta)})`)}function wn(e){return e.length===0?[g.dim(" (no differences)")]:e.map(t=>` ${g.bold(t.resolver.padEnd(28))} starts ${t.aStarts}\u2192${t.bStarts} (${de(t.bStarts-t.aStarts)}) completes ${t.aCompletes}\u2192${t.bCompletes} (${de(t.bCompletes-t.aCompletes)}) errors ${t.aErrors}\u2192${t.bErrors} (${de(t.bErrors-t.aErrors)})`)}function $n(e){return e.length===0?[g.dim(" (no new errors)")]:e.map(t=>{let r=t.side==="a"?g.cyan("a-only"):g.yellow("b-only"),s=(()=>{try{return JSON.stringify(t.error)}catch{return `[${typeof t.error}]`}})();return ` ${r} frame #${t.frameIndex} ${g.bold(t.kind)} '${t.id}' ${g.dim(s)}`})}function Wt(e){let t=resolve(e);existsSync(t)||(console.error(g.red(`error: timeline file not found: ${t}`)),process.exit(1));let r;try{r=readFileSync(t,"utf8");}catch(s){console.error(g.red(`error: failed to read ${t}: ${s.message}`)),process.exit(1);}try{return JSON.parse(r)}catch(s){console.error(g.red(`error: ${t} is not valid JSON: ${s.message}`)),process.exit(1);}}async function Bt(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(_t(),process.exit(e.length===0?1:0));let{aPath:t,bPath:r,opts:s}=bn(e);(!t||!r)&&(console.error(g.red("error: both <a.json> and <b.json> are required")),_t(),process.exit(1));let{deserializeTimeline:n,diffTimelines:o}=await te(s.verbose),i=Wt(t),a=Wt(r),l,c;try{l=n(i),c=n(a);}catch(u){console.error(g.red(`error: timeline JSON failed validation: ${u.message}`)),process.exit(1);}let d=o(l,c);s.json&&(console.log(JSON.stringify(d,null,2)),process.exit(d.identical?0:2)),d.identical&&(console.log(g.green("\u2713 identical:"),`both timelines have ${d.aFrameCount} frames and the same causal shape.`),process.exit(0)),console.log(g.bold("Timeline diff"),g.dim(`(${t} vs ${r})`)),console.log(""),console.log(`Frames: ${d.aFrameCount} \u2192 ${d.bFrameCount} (${de(d.frameCountDelta)})`),console.log(""),console.log(g.bold("Constraint fires:"));for(let u of Ut(d.constraintFires))console.log(u);console.log(""),console.log(g.bold("Mutations:"));for(let u of Ut(d.mutations))console.log(u);console.log(""),console.log(g.bold("Resolver runs:"));for(let u of wn(d.resolverRuns))console.log(u);console.log(""),console.log(g.bold("New errors:"));for(let u of $n(d.newErrors))console.log(u);console.log(""),process.exit(2);}function Rn(e){let t={sweepArgs:[],json:false};for(let r=0;r<e.length;r++)switch(e[r]){case "--history":{let n=e[++r];n&&(t.historyPath=n);break}case "--original":case "-o":{let n=e[++r];n&&(t.originalPath=n);break}case "--template":case "-t":{let n=e[++r];n&&(t.templatePath=n);break}case "--sweep":case "-s":{let n=e[++r];n&&t.sweepArgs.push(n);break}case "--entity-key":{let n=e[++r];n&&(t.entityKey=n);break}case "--json":t.json=true;break}return t}function pe(){console.error(`
992
+ Usage: directive tune --history <frames.json> --original <orig.json> \\
993
+ --template <tmpl.json> --sweep <key:range>
993
994
 
994
- Usage: ${R} <command> [options]
995
+ Grid-search one or more parameters in a predicate template against a
996
+ recorded fact history and print the response curve.
997
+
998
+ Options:
999
+ --history <path> Recorded frames JSON (required)
1000
+ --original <path> Original predicate JSON \u2014 the baseline (required)
1001
+ --template <path> Predicate template with { "$hole": "name" } markers (required)
1002
+ --sweep <key:range> Repeatable. Range syntax:
1003
+ * numeric: key:25..200:25 (start..end:step)
1004
+ * discrete: key:val1,val2,val3
1005
+ --entity-key <fact> Fact key identifying an entity \u2014 also reports
1006
+ distinct-entity counts (e.g. userId)
1007
+ --json Emit the full SweepReport as JSON
1008
+ --help Show this help
1009
+
1010
+ Example:
1011
+ directive tune --history sessions.json \\
1012
+ --original current.json --template proposed-template.json \\
1013
+ --sweep threshold:25..200:25
1014
+ `);}function We(e,t){let r=resolve(e);existsSync(r)||(console.error(g.red(`error: ${t} file not found: ${r}`)),process.exit(1));try{return JSON.parse(readFileSync(r,"utf8"))}catch(s){console.error(g.red(`error: failed to parse ${t} (${r}): `)+s.message),process.exit(1);}}function En(e){try{return fe(e)}catch(t){console.error(g.red(`error: ${t.message}`)),process.exit(1);}}function Cn(e){let t=e.indexOf(":");t<1&&(console.error(g.red(`error: --sweep ${e}: missing ':' between hole name and values`)),process.exit(1));let r=e.slice(0,t),s=e.slice(t+1),n=s.match(/^(-?\d+(?:\.\d+)?)\.\.(-?\d+(?:\.\d+)?)(?::(-?\d+(?:\.\d+)?))?$/);if(n){let[,a,l,c]=n,d=Number(a),u=Number(l),f=c?Number(c):1;f<=0&&(console.error(g.red(`error: --sweep ${e}: step must be positive`)),process.exit(1)),u<d&&(console.error(g.red(`error: --sweep ${e}: end (${u}) must be >= start (${d})`)),process.exit(1));let v=[];for(let x=d;x<=u+1e-9;x+=f)v.push(Math.round(x*1e6)/1e6);return [r,v]}let o=s.split(",").map(a=>a.trim()).filter(a=>a.length>0);o.length===0&&(console.error(g.red(`error: --sweep ${e}: no values after ':'`)),process.exit(1));let i=o.map(a=>{let l=Number(a);return Number.isNaN(l)?a:l});return [r,i]}var Be=["\u2581","\u2582","\u2583","\u2584","\u2585","\u2586","\u2587","\u2588"];function Dn(e,t){let r=e.points;Math.max(...r.map(f=>f.report.proposed.matched));let n=e.baseline.report.original.matched,o=r.map(f=>f.score),i=Math.min(...o),l=Math.max(...o)-i,c=r.map(f=>{let v=l>0?(f.score-i)/l:0;return Be[Math.min(Be.length-1,Math.round(v*(Be.length-1)))]}).join("");console.log(`
1015
+ ${g.bold("directive tune")} \u2014 parameter sweep`),console.log(`
1016
+ frames evaluated ${r[0]?.report.framesEvaluated??0}`),console.log(` baseline (current) matched ${n} frames`),console.log(` points evaluated ${r.length}
1017
+ `),console.log(` sparkline ${g.cyan(c)}
1018
+ `);let d=Object.keys(r[0]?.values??{}),u=d.map(f=>f.padEnd(12)).join(" ")+" "+"matched".padStart(8)+" "+"delta".padStart(7)+(t?" "+`${t}s`.padStart(8):"")+" bar";console.log(g.dim(" "+u));for(let f of r){let v=d.map(z=>String(f.values[z]??"").padEnd(12)).join(" "),x=f.report.proposed.matched,b=f.report.delta,N=t?String(f.report.proposed.matchedEntities??"").padStart(8):"",F=b>0?g.green(`+${b}`.padStart(7)):b<0?g.red(`${b}`.padStart(7)):g.dim("\xB10".padStart(7)),p=l>0?Math.round((f.score-i)/l*24):0,h=v+" "+String(x).padStart(8)+" "+F+(t?" "+N:"")+" "+"\u2588".repeat(p).padEnd(24),D=f===e.best;console.log(D?g.green(" "+h):" "+h);}console.log(`
1019
+ ${g.bold(g.green("best"))} \u2014 ${d.map(f=>`${f}=${e.best.values[f]}`).join(", ")} \u2192 matched ${e.best.report.proposed.matched} (score ${e.best.score})
1020
+ `);}async function Lt(e){(e.includes("--help")||e.length===0)&&(pe(),process.exit(e.length===0?1:0));let t=Rn(e);t.historyPath||(console.error(g.red("error: --history <frames.json> is required")),pe(),process.exit(1)),t.originalPath||(console.error(g.red("error: --original <spec.json> is required")),pe(),process.exit(1)),t.templatePath||(console.error(g.red("error: --template <spec.json> is required")),pe(),process.exit(1)),t.sweepArgs.length===0&&(console.error(g.red("error: at least one --sweep <key:range> is required")),pe(),process.exit(1));let r=En(We(t.historyPath,"--history")),s=We(t.originalPath,"--original"),n=We(t.templatePath,"--template"),o={};for(let a of t.sweepArgs){let[l,c]=Cn(a);o[l]=c;}let i;try{i=Pt({frames:r,original:s,template:n,sweep:o,entityKey:t.entityKey});}catch(a){console.error(g.red(`error: ${a.message}`)),process.exit(1);}if(t.json){console.log(JSON.stringify(i,null,2));return}Dn(i,t.entityKey);}var jn=`
1021
+ ${C} \u2014 CLI tools for Directive
1022
+
1023
+ Usage: ${C} <command> [options]
995
1024
 
996
1025
  Commands:
997
1026
  init Project scaffolding wizard
@@ -1008,6 +1037,8 @@ Commands:
1008
1037
  examples copy <name> Extract example to project
1009
1038
  replay <timeline.json> Replay a serialized Directive timeline
1010
1039
  (paired with @directive-run/timeline)
1040
+ tune --history ... Grid-search a predicate template's $hole
1041
+ parameters against recorded history
1011
1042
  replay-under --history ... Predicate backtest \u2014 diff a proposed
1012
1043
  predicate against recorded history
1013
1044
  bisect <timeline.json> Binary-search a timeline for the first
@@ -1047,14 +1078,14 @@ ai-rules init options:
1047
1078
  examples options:
1048
1079
  --filter <category> Filter by category or name
1049
1080
  --dest <dir> Destination directory for copy
1050
- `.trim();async function un(){let e=process.argv.slice(2),t=e[0];if((e.length===0||t==="--help"||t==="-h")&&(console.log(cn),process.exit(0)),t==="--version"||t==="-v"){let{readFileSync:n}=await import('fs'),{fileURLToPath:o}=await import('url'),{dirname:i,join:a}=await import('path'),l=i(o(import.meta.url)),c=JSON.parse(n(a(l,"..","package.json"),"utf-8"));console.log(c.version),process.exit(0);}let s=e[0];switch(s){case "init":{await ct(e.slice(1));break}case "new":{let n=e[1],o=e[2];n==="module"?(o||(console.error("Usage: directive new module <name>"),process.exit(1)),await ht(o,e.slice(3))):n==="orchestrator"?(o||(console.error("Usage: directive new orchestrator <name>"),process.exit(1)),await yt(o,e.slice(3))):(console.error(`Unknown subcommand: ${n??"(none)"}
1051
- Usage: ${R} new module <name>
1052
- ${R} new orchestrator <name>`),process.exit(1));break}case "inspect":{await ut(e.slice(1));break}case "explain":{await at(e.slice(1));break}case "graph":{await lt(e.slice(1));break}case "doctor":{await et(e.slice(1));break}case "ai-rules":{let n=e[1];n==="init"?await Je(e.slice(2)):n==="update"?await Ge(e.slice(2)):n==="check"?await He(e.slice(2)):(console.error(`Unknown subcommand: ${n??"(none)"}
1053
- Usage: ${R} ai-rules init
1054
- ${R} ai-rules update
1055
- ${R} ai-rules check`),process.exit(1));break}case "examples":{let n=e[1];if(n==="list")await st(e.slice(2));else if(n==="copy"){let o=e[2];o||(console.error("Usage: directive examples copy <name>"),process.exit(1)),await it(o,e.slice(3));}else console.error(`Unknown subcommand: ${n??"(none)"}
1056
- Usage: ${R} examples list [--filter <category>]
1057
- ${R} examples copy <name> [--dest <dir>]`),process.exit(1);break}case "replay":{await jt(e.slice(1));break}case "replay-under":{await Dt(e.slice(1));break}case "bisect":{await Qe(e.slice(1));break}case "timeline":{let n=e[1];n==="diff"?await qt(e.slice(2)):(console.error(`Unknown subcommand: ${n??"(none)"}
1058
- Usage: ${R} timeline diff <a.json> <b.json>`),process.exit(1));break}default:console.error(`Unknown command: ${s}
1059
- Run '${R} --help' for usage.`),process.exit(1);}}un().catch(e=>{console.error(e.message||e),process.exit(1);});//# sourceMappingURL=cli.js.map
1081
+ `.trim();async function On(){let e=process.argv.slice(2),t=e[0];if((e.length===0||t==="--help"||t==="-h")&&(console.log(jn),process.exit(0)),t==="--version"||t==="-v"){let{readFileSync:n}=await import('fs'),{fileURLToPath:o}=await import('url'),{dirname:i,join:a}=await import('path'),l=i(o(import.meta.url)),c=JSON.parse(n(a(l,"..","package.json"),"utf-8"));console.log(c.version),process.exit(0);}let s=e[0];switch(s){case "init":{await ht(e.slice(1));break}case "new":{let n=e[1],o=e[2];n==="module"?(o||(console.error("Usage: directive new module <name>"),process.exit(1)),await kt(o,e.slice(3))):n==="orchestrator"?(o||(console.error("Usage: directive new orchestrator <name>"),process.exit(1)),await xt(o,e.slice(3))):(console.error(`Unknown subcommand: ${n??"(none)"}
1082
+ Usage: ${C} new module <name>
1083
+ ${C} new orchestrator <name>`),process.exit(1));break}case "inspect":{await yt(e.slice(1));break}case "explain":{await mt(e.slice(1));break}case "graph":{await gt(e.slice(1));break}case "doctor":{await at(e.slice(1));break}case "ai-rules":{let n=e[1];n==="init"?await Qe(e.slice(2)):n==="update"?await et(e.slice(2)):n==="check"?await tt(e.slice(2)):(console.error(`Unknown subcommand: ${n??"(none)"}
1084
+ Usage: ${C} ai-rules init
1085
+ ${C} ai-rules update
1086
+ ${C} ai-rules check`),process.exit(1));break}case "examples":{let n=e[1];if(n==="list")await ft(e.slice(2));else if(n==="copy"){let o=e[2];o||(console.error("Usage: directive examples copy <name>"),process.exit(1)),await dt(o,e.slice(3));}else console.error(`Unknown subcommand: ${n??"(none)"}
1087
+ Usage: ${C} examples list [--filter <category>]
1088
+ ${C} examples copy <name> [--dest <dir>]`),process.exit(1);break}case "replay":{await zt(e.slice(1));break}case "replay-under":{await Ft(e.slice(1));break}case "tune":{await Lt(e.slice(1));break}case "bisect":{await ot(e.slice(1));break}case "timeline":{let n=e[1];n==="diff"?await Bt(e.slice(2)):(console.error(`Unknown subcommand: ${n??"(none)"}
1089
+ Usage: ${C} timeline diff <a.json> <b.json>`),process.exit(1));break}default:console.error(`Unknown command: ${s}
1090
+ Run '${C} --help' for usage.`),process.exit(1);}}On().catch(e=>{console.error(e.message||e),process.exit(1);});//# sourceMappingURL=cli.js.map
1060
1091
  //# sourceMappingURL=cli.js.map