@directive-run/cli 1.9.0 → 1.11.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 h from'@clack/prompts';import g from'picocolors';import {getAllExamples,getExample,getKnowledge}from'@directive-run/knowledge';var j="directive";var be="<!-- directive:start -->",ce="<!-- directive:end -->";var qe=[{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 Ze(e){let t=[];for(let r of qe)r.signals.some(n=>existsSync(join(e,n)))&&t.push({name:r.name,id:r.id,outputPath:join(e,r.outputPath)});return t}function ue(e){let t=qe.find(r=>r.id===e);if(!t)throw new Error(`Unknown tool: ${e}`);return t}function et(){return qe.map(e=>e.id)}function re(e,t){let r=e.indexOf(be),s=e.indexOf(ce),n=`${be}
2
+ import {existsSync,readFileSync,mkdirSync,writeFileSync,readdirSync}from'fs';import {resolve,join,relative,dirname}from'path';import*as h from'@clack/prompts';import g from'picocolors';import {getAllExamples,getExample,getKnowledge}from'@directive-run/knowledge';var A="directive";var $e="<!-- directive:start -->",ce="<!-- directive:end -->";var qe=[{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 Ze(e){let t=[];for(let r of qe)r.signals.some(n=>existsSync(join(e,n)))&&t.push({name:r.name,id:r.id,outputPath:join(e,r.outputPath)});return t}function ue(e){let t=qe.find(r=>r.id===e);if(!t)throw new Error(`Unknown tool: ${e}`);return t}function et(){return qe.map(e=>e.id)}function re(e,t){let r=e.indexOf($e),s=e.indexOf(ce),n=`${$e}
3
3
  ${t}
4
- ${ce}`;if(r!==-1&&s!==-1&&s>r)return e.slice(0,r)+n+e.slice(s+ce.length);let o=e.endsWith(`
4
+ ${ce}`;if(r!==-1&&s!==-1&&s>r)return e.slice(0,r)+n+e.slice(s+ce.length);let i=e.endsWith(`
5
5
  `)?`
6
6
  `:`
7
7
 
8
- `;return e+o+n+`
9
- `}function ne(e){return e.includes(be)&&e.includes(ce)}var ar=[{file:"pnpm-workspace.yaml",tool:"pnpm"},{file:"turbo.json",tool:"turbo"}];function rt(e){let t=resolve(e);for(;t!==dirname(t);){for(let s of ar)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 st(){let e=getKnowledge("core-patterns"),t=getKnowledge("anti-patterns"),r=getKnowledge("naming"),s=getKnowledge("schema-types");return `# Directive \u2014 Complete AI Coding Rules
8
+ `;return e+i+n+`
9
+ `}function ne(e){return e.includes($e)&&e.includes(ce)}var ar=[{file:"pnpm-workspace.yaml",tool:"pnpm"},{file:"turbo.json",tool:"turbo"}];function rt(e){let t=resolve(e);for(;t!==dirname(t);){for(let s of ar)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 st(){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 $e(){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 se(){return $e()+"\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 be(){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 se(){return be()+"\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,20 +259,20 @@ 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 ot(){return se()}function it(){return se()}var cr={cursor:$e,claude:st,copilot:se,windsurf:it,cline:ot};function Se(e){let t=cr[e];if(!t)throw new Error(`No template for tool: ${e}`);return t()}function _e(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 at(e){let t=_e(e);h.intro(g.bgCyan(g.black(" directive ai-rules ")));let r=rt(t.dir),s=t.dir;if(r.isMonorepo&&r.rootDir!==t.dir){let i=await h.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)})`}]});h.isCancel(i)&&(h.cancel("Cancelled."),process.exit(0)),i==="root"&&(s=r.rootDir);}let n;if(t.tools.length>0)n=t.tools.map(i=>{let l=ue(i);return {name:l.name,id:l.id,outputPath:join(s,l.outputPath)}});else {let i=Ze(s);if(i.length>0){let l=await h.multiselect({message:`Detected ${i.length} AI tool(s). Which should get Directive rules?`,options:i.map(a=>({value:a.id,label:a.name,hint:relative(s,a.outputPath)})),initialValues:i.map(a=>a.id),required:true});h.isCancel(l)&&(h.cancel("Cancelled."),process.exit(0)),n=l.map(a=>{let c=ue(a);return {name:c.name,id:c.id,outputPath:join(s,c.outputPath)}});}else {let l=await h.multiselect({message:"No AI tools detected. Which tools do you use?",options:et().map(a=>{let c=ue(a);return {value:a,label:c.name}}),required:true});h.isCancel(l)&&(h.cancel("Cancelled."),process.exit(0)),n=l.map(a=>{let c=ue(a);return {name:c.name,id:c.id,outputPath:join(s,c.outputPath)}});}}n.length===0&&(h.cancel("No tools selected."),process.exit(0));let o=h.spinner();for(let i of n){o.start(`Generating ${i.name} rules...`);let l=Se(i.id),a=i.outputPath,c=existsSync(a);if(o.stop(`Generated ${i.name} rules.`),c&&!t.force){let u=readFileSync(a,"utf-8");if(t.merge){V(a,re(u,l)),h.log.success(`${g.green("Merged")} Directive section into ${g.dim(relative(s,a))}`);continue}if(ne(u)){let f=await h.select({message:`${relative(s,a)} 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"}]});h.isCancel(f)&&(h.cancel("Cancelled."),process.exit(0)),f==="merge"?(V(a,re(u,l)),h.log.success(`${g.green("Updated")} ${g.dim(relative(s,a))}`)):f==="overwrite"?(V(a,l),h.log.success(`${g.green("Wrote")} ${g.dim(relative(s,a))}`)):h.log.info(`Skipped ${g.dim(relative(s,a))}`);}else {let f=await h.select({message:`${relative(s,a)} 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"}]});h.isCancel(f)&&(h.cancel("Cancelled."),process.exit(0)),f==="append"?(V(a,re(u,l)),h.log.success(`${g.green("Appended")} to ${g.dim(relative(s,a))}`)):f==="overwrite"?(V(a,l),h.log.success(`${g.green("Wrote")} ${g.dim(relative(s,a))}`)):h.log.info(`Skipped ${g.dim(relative(s,a))}`);}}else V(a,l),h.log.success(`${g.green("Created")} ${g.dim(relative(s,a))}`);}h.outro(`Done! Run ${g.cyan(`${j} ai-rules init --merge`)} anytime to update.`);}function V(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}async function lt(e){let r=_e(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(!ne(i))continue;let l=Se(o.id),a=re(i,l);V(o.path,a),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(`${j} ai-rules init`)} first.`):g.green(`
263
- Updated ${n} file(s) to latest knowledge version.`));}async function ct(e){let r=_e(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 l=readFileSync(i.path,"utf-8");if(!ne(l))continue;n++;let a=Se(i.id);re(l,a)!==l?(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(`${j} ai-rules update`)} to refresh.`),process.exit(1)):console.log(g.green(`
265
- All rule files are current.`));}async function W(e){let t=resolve(e);if(!existsSync(t))throw new Error(`File not found: ${t}`);try{let r=await import(t);if(r.default&&Y(r.default))return r.default;if(r.system&&Y(r.system))return r.system;for(let s of Object.keys(r))if(Y(r[s]))return r[s];throw new Error(`No Directive system found in ${g.dim(e)}
262
+ `}function it(){return se()}function ot(){return se()}var cr={cursor:be,claude:st,copilot:se,windsurf:ot,cline:it};function Se(e){let t=cr[e];if(!t)throw new Error(`No template for tool: ${e}`);return t()}function ze(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 at(e){let t=ze(e);h.intro(g.bgCyan(g.black(" directive ai-rules ")));let r=rt(t.dir),s=t.dir;if(r.isMonorepo&&r.rootDir!==t.dir){let o=await h.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)})`}]});h.isCancel(o)&&(h.cancel("Cancelled."),process.exit(0)),o==="root"&&(s=r.rootDir);}let n;if(t.tools.length>0)n=t.tools.map(o=>{let l=ue(o);return {name:l.name,id:l.id,outputPath:join(s,l.outputPath)}});else {let o=Ze(s);if(o.length>0){let l=await h.multiselect({message:`Detected ${o.length} AI tool(s). Which should get Directive rules?`,options:o.map(a=>({value:a.id,label:a.name,hint:relative(s,a.outputPath)})),initialValues:o.map(a=>a.id),required:true});h.isCancel(l)&&(h.cancel("Cancelled."),process.exit(0)),n=l.map(a=>{let c=ue(a);return {name:c.name,id:c.id,outputPath:join(s,c.outputPath)}});}else {let l=await h.multiselect({message:"No AI tools detected. Which tools do you use?",options:et().map(a=>{let c=ue(a);return {value:a,label:c.name}}),required:true});h.isCancel(l)&&(h.cancel("Cancelled."),process.exit(0)),n=l.map(a=>{let c=ue(a);return {name:c.name,id:c.id,outputPath:join(s,c.outputPath)}});}}n.length===0&&(h.cancel("No tools selected."),process.exit(0));let i=h.spinner();for(let o of n){i.start(`Generating ${o.name} rules...`);let l=Se(o.id),a=o.outputPath,c=existsSync(a);if(i.stop(`Generated ${o.name} rules.`),c&&!t.force){let u=readFileSync(a,"utf-8");if(t.merge){V(a,re(u,l)),h.log.success(`${g.green("Merged")} Directive section into ${g.dim(relative(s,a))}`);continue}if(ne(u)){let f=await h.select({message:`${relative(s,a)} 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"}]});h.isCancel(f)&&(h.cancel("Cancelled."),process.exit(0)),f==="merge"?(V(a,re(u,l)),h.log.success(`${g.green("Updated")} ${g.dim(relative(s,a))}`)):f==="overwrite"?(V(a,l),h.log.success(`${g.green("Wrote")} ${g.dim(relative(s,a))}`)):h.log.info(`Skipped ${g.dim(relative(s,a))}`);}else {let f=await h.select({message:`${relative(s,a)} 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"}]});h.isCancel(f)&&(h.cancel("Cancelled."),process.exit(0)),f==="append"?(V(a,re(u,l)),h.log.success(`${g.green("Appended")} to ${g.dim(relative(s,a))}`)):f==="overwrite"?(V(a,l),h.log.success(`${g.green("Wrote")} ${g.dim(relative(s,a))}`)):h.log.info(`Skipped ${g.dim(relative(s,a))}`);}}else V(a,l),h.log.success(`${g.green("Created")} ${g.dim(relative(s,a))}`);}h.outro(`Done! Run ${g.cyan(`${A} ai-rules init --merge`)} anytime to update.`);}function V(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}async function lt(e){let r=ze(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 i of s){if(!existsSync(i.path))continue;let o=readFileSync(i.path,"utf-8");if(!ne(o))continue;let l=Se(i.id),a=re(o,l);V(i.path,a),console.log(`${g.green("Updated")} ${g.dim(relative(r,i.path))}`),n++;}console.log(n===0?g.dim(`No existing rule files found. Run ${g.cyan(`${A} ai-rules init`)} first.`):g.green(`
263
+ Updated ${n} file(s) to latest knowledge version.`));}async function ct(e){let r=ze(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,i=0;for(let o of s){if(!existsSync(o.path))continue;let l=readFileSync(o.path,"utf-8");if(!ne(l))continue;n++;let a=Se(o.id);re(l,a)!==l?(console.log(`${g.red("\u2717")} ${o.name} rules are ${g.yellow("stale")}`),i++):console.log(`${g.green("\u2713")} ${o.name} rules are ${g.green("current")}`);}if(n===0){console.log(g.dim("No rule files found to check."));return}i>0?(console.log(`
264
+ ${g.yellow(`${i} file(s) are stale.`)} Run ${g.cyan(`${A} 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&&Y(r.default))return r.default;if(r.system&&Y(r.system))return r.system;for(let s of Object.keys(r))if(Y(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 Y(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 dt(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 Y(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 dt(e){let t=resolve(e);if(!existsSync(t))throw new Error(`File not found: ${t}`);let r;try{r=await import(t);}catch(i){throw new Error(`Failed to load ${g.dim(e)}: ${i instanceof Error?i.message:String(i)}
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 l=await Promise.resolve(i());if(!Y(l))throw new Error(`Factory '${o}' from ${g.dim(e)} returned a value that is not a started Directive system.
275
+ ${g.cyan("npm install -D tsx")}`)}let s=[["createSystem",r.createSystem],["systemFactory",r.systemFactory],["default",r.default]];for(let[i,o]of s)if(typeof o=="function")return async()=>{let l=await Promise.resolve(o());if(!Y(l))throw new Error(`Factory '${i}' from ${g.dim(e)} returned a value that is not a started Directive system.
276
276
  Expected an object with inspect/start/stop/facts. The factory must call sys.start() before returning.`);return l};throw Y(r.default)||Y(r.system)||Object.values(r).some(Y)?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.
@@ -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 oe(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 gr(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 xe(){console.error(`
294
+ (Did you forget ${g.cyan("sys.start()")} before returning?)`)}async function ie(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 gr(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 i=e[++s];i&&(t.systemPath=i);break}case "--assert":case "-a":{let i=e[++s];i&&(t.assertExpr=i);break}case "--max-frames":{let i=e[++s],o=i?Number.parseInt(i,10):Number.NaN;Number.isFinite(o)&&o>0&&(t.maxFrames=o);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 ke(){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
@@ -328,9 +328,9 @@ Examples:
328
328
 
329
329
  directive bisect crash.json -s factory.ts -a 'facts.status !== "error"' --json
330
330
  `);}function yr(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 mt(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(xe(),process.exit(e.length===0?1:0));let{jsonPath:t,opts:r}=gr(e);t||(console.error(g.red("error: missing <timeline.json> argument")),xe(),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)`)),xe(),process.exit(1)),r.assertExpr||(console.error(g.red("error: --assert <expression> is required"),g.dim(`
333
- (assertion distinguishes 'good' from 'bad' system state)`)),xe(),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:l}=await oe(r.verbose),a;try{a=i(o);}catch(b){console.error(g.red(`error: timeline JSON failed validation: ${b.message}`)),process.exit(1);}let c;try{c=yr(r.assertExpr);}catch(b){console.error(g.red(`error: ${b.message}`)),process.exit(1);}let u;try{u=await dt(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 ${a.frames.length} frames with assertion: ${r.assertExpr}`));let f=await l(a,u,c,{maxFrames:r.maxFrames,determinismCheck:!r.noDeterminismCheck});if(r.json){let b={firstFailingFrameIndex:f.firstFailingFrameIndex??null,iterations:f.iterations,noFailureFound:f.noFailureFound,failsOnEmptyReplay:f.failsOnEmptyReplay,nonDeterministic:f.nonDeterministic};console.log(JSON.stringify(b,null,2)),process.exit(0);}f.nonDeterministic&&(console.error(g.red("\u2717 bisect aborted: timeline is non-deterministic")),console.error(g.dim(` Two full-timeline replays produced different oracle verdicts.
331
+ expression: ${e}`)}return r=>{let s=r?.facts;return !!t(s,r)}}async function mt(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(ke(),process.exit(e.length===0?1:0));let{jsonPath:t,opts:r}=gr(e);t||(console.error(g.red("error: missing <timeline.json> argument")),ke(),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)`)),ke(),process.exit(1)),r.assertExpr||(console.error(g.red("error: --assert <expression> is required"),g.dim(`
333
+ (assertion distinguishes 'good' from 'bad' system state)`)),ke(),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($){console.error(g.red(`error: failed to read ${s}: ${$.message}`)),process.exit(1);}let i;try{i=JSON.parse(n);}catch($){console.error(g.red(`error: ${s} is not valid JSON: ${$.message}`)),process.exit(1);}let{deserializeTimeline:o,bisectTimeline:l}=await ie(r.verbose),a;try{a=o(i);}catch($){console.error(g.red(`error: timeline JSON failed validation: ${$.message}`)),process.exit(1);}let c;try{c=yr(r.assertExpr);}catch($){console.error(g.red(`error: ${$.message}`)),process.exit(1);}let u;try{u=await dt(r.systemPath);}catch($){console.error(g.red(`error: failed to load system factory: ${$.message}`)),process.exit(1);}r.verbose&&console.error(g.dim(`bisecting ${a.frames.length} frames with assertion: ${r.assertExpr}`));let f=await l(a,u,c,{maxFrames:r.maxFrames,determinismCheck:!r.noDeterminismCheck});if(r.json){let $={firstFailingFrameIndex:f.firstFailingFrameIndex??null,iterations:f.iterations,noFailureFound:f.noFailureFound,failsOnEmptyReplay:f.failsOnEmptyReplay,nonDeterministic:f.nonDeterministic};console.log(JSON.stringify($,null,2)),process.exit(0);}f.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)),f.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
@@ -339,17 +339,17 @@ Examples:
339
339
  Bisect cannot narrow further. Inspect the system factory
340
340
  or initial fact values.`)),process.exit(0));let d=f.firstFailingFrameIndex??-1,m=f.firstFailingFrame,v=m?.event.type??"<unknown>";console.log(`${g.green("\u2713")} bisect complete: ${g.bold(`first failing frame is #${d}`)} ${g.dim(`(${v})`)}`),console.log(g.dim(` \u2022 iterations: ${f.iterations} | timeline frames: ${a.frames.length}`)),r.verbose&&m&&(console.log(g.dim(" \u2022 frame:")),console.log(g.dim(` ${JSON.stringify(m,null,2).split(`
341
341
  `).join(`
342
- `)}`))),process.exit(2);}function wr(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 br(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 $r(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 Sr(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 kr(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 xr(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");ne(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 ht(e){let t=wr(e);console.log(),console.log(g.bold(g.cyan("Directive Doctor"))),console.log(g.dim("\u2500".repeat(40))),console.log();let r=[br(t.dir),$r(t.dir),Sr(t.dir),kr(t.dir),xr(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 vt={"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 Ar(e){for(let[t,r]of Object.entries(vt))if(r.includes(e))return t;return "Other"}function Cr(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 wt(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,l]of r){let a=Ar(i);t&&!a.toLowerCase().includes(t)&&!i.includes(t)||(s.has(a)||s.set(a,[]),s.get(a).push({name:i,desc:Cr(l)}));}if(s.size===0){console.log(g.dim("No examples match the filter."));return}let n=Object.keys(vt),o=[...s.keys()].sort((i,l)=>(n.indexOf(i)??99)-(n.indexOf(l)??99));for(let i of o){let l=s.get(i);console.log(g.bold(i));for(let a of l){let c=a.desc?g.dim(` \u2014 ${a.desc}`):"";console.log(` ${g.cyan(a.name)}${c}`);}console.log();}console.log(g.dim(`${r.size} examples available. Run ${g.cyan("directive examples copy <name>")} to extract one.`));}async function bt(e,t){let r=process.cwd();for(let a=0;a<t.length;a++)if(t[a]==="--dest"){let c=t[++a];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 l=relative(process.cwd(),o);console.log(`${g.green("Copied")} ${g.cyan(e)} \u2192 ${g.dim(l)}`);}function Or(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 St(e){let{filePath:t,requirementId:r}=Or(e);t||(console.error("Usage: directive explain <file> [requirement-id]"),process.exit(1));let s=await W(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.
342
+ `)}`))),process.exit(2);}function wr(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 $r(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 br(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(i=>i.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 Sr(e){let t=join(e,"tsconfig.json");if(!existsSync(t))return {label:"TypeScript configuration",passed:false,message:"No tsconfig.json found",fix:"Run `tsc --init` to create a TypeScript configuration"};try{let s=readFileSync(t,"utf-8").replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,""),i=JSON.parse(s).compilerOptions||{},o=[];return i.strict!==!0&&o.push("strict mode not enabled"),i.moduleResolution&&!["bundler","nodenext","node16"].includes(i.moduleResolution.toLowerCase())&&o.push(`moduleResolution is "${i.moduleResolution}"`),o.length>0?{label:"TypeScript configuration",passed:!1,message:o.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 xr(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 i of n){let o=join(s,i,"node_modules","@directive-run","core");existsSync(o)&&r.push(`@directive-run/${i}/node_modules/@directive-run/core`);}}}catch{}return r.length>0?{label:"No duplicate Directive instances",passed:false,message:`Found ${r.length} duplicate(s): ${r.join(", ")}`,fix:"Run `npm dedupe` or check for version mismatches"}:{label:"No duplicate Directive instances",passed:true,message:"No duplicates detected"}}function kr(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 i=readFileSync(n,"utf-8");ne(i)&&r.push(s);}}return r.length===0?{label:"AI coding rules",passed:true,message:"Not installed (optional)"}:{label:"AI coding rules",passed:true,message:`Installed for: ${r.join(", ")}`}}async function ht(e){let t=wr(e);console.log(),console.log(g.bold(g.cyan("Directive Doctor"))),console.log(g.dim("\u2500".repeat(40))),console.log();let r=[$r(t.dir),br(t.dir),Sr(t.dir),xr(t.dir),kr(t.dir)],s=0;for(let n of r){let i=n.passed?g.green("\u2713"):g.red("\u2717");console.log(`${i} ${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 vt={"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 Rr(e){for(let[t,r]of Object.entries(vt))if(r.includes(e))return t;return "Other"}function Cr(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 wt(e){let t;for(let o=0;o<e.length;o++)e[o]==="--filter"&&(t=e[++o]?.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[o,l]of r){let a=Rr(o);t&&!a.toLowerCase().includes(t)&&!o.includes(t)||(s.has(a)||s.set(a,[]),s.get(a).push({name:o,desc:Cr(l)}));}if(s.size===0){console.log(g.dim("No examples match the filter."));return}let n=Object.keys(vt),i=[...s.keys()].sort((o,l)=>(n.indexOf(o)??99)-(n.indexOf(l)??99));for(let o of i){let l=s.get(o);console.log(g.bold(o));for(let a of l){let c=a.desc?g.dim(` \u2014 ${a.desc}`):"";console.log(` ${g.cyan(a.name)}${c}`);}console.log();}console.log(g.dim(`${r.size} examples available. Run ${g.cyan("directive examples copy <name>")} to extract one.`));}async function $t(e,t){let r=process.cwd();for(let a=0;a<t.length;a++)if(t[a]==="--dest"){let c=t[++a];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"'),i=join(r,`${e}.ts`);existsSync(i)&&(console.error(`File already exists: ${relative(process.cwd(),i)}`),process.exit(1));let o=dirname(i);existsSync(o)||mkdirSync(o,{recursive:true}),writeFileSync(i,n,"utf-8");let l=relative(process.cwd(),i);console.log(`${g.green("Copied")} ${g.cyan(e)} \u2192 ${g.dim(l)}`);}function Or(e){let t={},r="",s;for(let n=0;n<e.length;n++){let i=e[n];if(i==="--module"){let o=e[++n];o&&(t.module=o);}else i&&!i.startsWith("-")&&(r?s||(s=i):r=i);}return {filePath:r,requirementId:s,opts:t}}async function St(e){let{filePath:t,requirementId:r}=Or(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 i=s.explain(r);if(!i){if(console.error(`Requirement "${r}" not found.
344
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,l]of o){let a=$t(l.state),c=l.duration!==void 0?` (${l.duration}ms)`:"";console.log(` ${g.cyan(i)} ${a}${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 a=n.resolvers[o.id];a?console.log(` Resolver: ${$t(a.state)}${a.error?` \u2014 ${a.error}`:""}`):n.resolverDefs.some(u=>u.requirement===o.requirement.type||u.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 $t(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 qr(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 Pr(e){let t=[];t.push(g.bold("Dependency Graph")),t.push(g.dim("\u2550".repeat(50))),t.push("");let r=new Map;for(let l of e.constraints)r.set(l.id,{reqTypes:new Set,active:l.active,priority:l.priority});for(let l of e.unmet){let a=r.get(l.fromConstraint);a&&a.reqTypes.add(l.requirement.type);}let s=new Map;for(let l of e.resolverDefs)s.has(l.requirement)||s.set(l.requirement,[]),s.get(l.requirement).push(l.id);t.push(g.bold("Constraints \u2192 Requirements \u2192 Resolvers")),t.push("");for(let[l,a]of r){let c=a.active?g.green("\u25CF"):g.dim("\u25CB");if(t.push(`${c} ${g.cyan(l)} (priority: ${a.priority})`),a.reqTypes.size>0)for(let u of a.reqTypes){t.push(` \u2514\u2500\u25B6 ${g.yellow(u)}`);let f=s.get(u)||[];if(f.length>0)for(let d of f)t.push(` \u2514\u2500\u25B6 ${g.magenta(d)}`);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 l of s.values())for(let a of l)n.add(a);if(e.resolverDefs.map(l=>l.id).filter(l=>!n.has(l)).length>0){t.push(g.bold("Standalone Resolvers:"));for(let l of e.resolverDefs)n.has(l.id)||t.push(` ${g.magenta(l.id)} handles ${g.yellow(l.requirement)}`);}return t.join(`
347
- `)}function Ir(e,t){let r=[],s=[],a=Object.keys(t);for(let p=0;p<a.length;p++){let y=a[p];r.push({id:`fact-${y}`,label:y,type:"fact",x:40,y:60+p*50,color:"#3b82f6"});}for(let p=0;p<e.constraints.length;p++){let y=e.constraints[p];r.push({id:`constraint-${y.id}`,label:y.id,type:"constraint",x:260,y:60+p*50,color:y.active?"#22c55e":"#6b7280"});}let c=new Set;for(let p of e.unmet)c.add(p.requirement.type);let u=0;for(let p of c)r.push({id:`req-${p}`,label:p,type:"requirement",x:480,y:60+u*50,color:"#eab308"}),u++;for(let p=0;p<e.resolverDefs.length;p++){let y=e.resolverDefs[p];r.push({id:`resolver-${y.id}`,label:y.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 f=new Map(r.map(p=>[p.id,p])),d=960,m=Math.max(...r.map(p=>p.y))+50+20,v=s.map(p=>{let y=f.get(p.from),A=f.get(p.to);return !y||!A?"":`<line x1="${y.x+90}" y1="${y.y+15}" x2="${A.x}" y2="${A.y+15}" stroke="#94a3b8" stroke-width="1.5" marker-end="url(#arrow)"/>`}).join(`
348
- `),b=r.map(p=>`<g>
345
+ Current requirements:`),n.unmet.length===0)console.log(g.dim(" (no unmet requirements)"));else for(let o of n.unmet)console.log(` ${g.cyan(o.id)} \u2014 ${o.requirement.type} (from ${o.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(i),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 i=Object.entries(n.resolvers);if(i.length>0){console.log(g.bold("Recent Resolver Activity:"));for(let[o,l]of i){let a=bt(l.state),c=l.duration!==void 0?` (${l.duration}ms)`:"";console.log(` ${g.cyan(o)} ${a}${c}`);}console.log();}}else {console.log(`${g.yellow(String(n.unmet.length))} unmet requirement(s):
346
+ `);for(let i of n.unmet){console.log(`${g.yellow("\u25CF")} ${g.bold(i.requirement.type)} (id: ${g.dim(i.id)})`),console.log(` From constraint: ${g.cyan(i.fromConstraint)}`);let o={...i.requirement};delete o.type,Object.keys(o).length>0&&console.log(` Payload: ${JSON.stringify(o)}`);let a=n.resolvers[i.id];a?console.log(` Resolver: ${bt(a.state)}${a.error?` \u2014 ${a.error}`:""}`):n.resolverDefs.some(u=>u.requirement===i.requirement.type||u.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 bt(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 qr(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 i=e[++s];i&&(t.output=i);break}default:n&&!n.startsWith("-")&&!r&&(r=n);}}return {filePath:r,opts:t}}function Pr(e){let t=[];t.push(g.bold("Dependency Graph")),t.push(g.dim("\u2550".repeat(50))),t.push("");let r=new Map;for(let l of e.constraints)r.set(l.id,{reqTypes:new Set,active:l.active,priority:l.priority});for(let l of e.unmet){let a=r.get(l.fromConstraint);a&&a.reqTypes.add(l.requirement.type);}let s=new Map;for(let l of e.resolverDefs)s.has(l.requirement)||s.set(l.requirement,[]),s.get(l.requirement).push(l.id);t.push(g.bold("Constraints \u2192 Requirements \u2192 Resolvers")),t.push("");for(let[l,a]of r){let c=a.active?g.green("\u25CF"):g.dim("\u25CB");if(t.push(`${c} ${g.cyan(l)} (priority: ${a.priority})`),a.reqTypes.size>0)for(let u of a.reqTypes){t.push(` \u2514\u2500\u25B6 ${g.yellow(u)}`);let f=s.get(u)||[];if(f.length>0)for(let d of f)t.push(` \u2514\u2500\u25B6 ${g.magenta(d)}`);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 l of s.values())for(let a of l)n.add(a);if(e.resolverDefs.map(l=>l.id).filter(l=>!n.has(l)).length>0){t.push(g.bold("Standalone Resolvers:"));for(let l of e.resolverDefs)n.has(l.id)||t.push(` ${g.magenta(l.id)} handles ${g.yellow(l.requirement)}`);}return t.join(`
347
+ `)}function Ir(e,t){let r=[],s=[],a=Object.keys(t);for(let p=0;p<a.length;p++){let y=a[p];r.push({id:`fact-${y}`,label:y,type:"fact",x:40,y:60+p*50,color:"#3b82f6"});}for(let p=0;p<e.constraints.length;p++){let y=e.constraints[p];r.push({id:`constraint-${y.id}`,label:y.id,type:"constraint",x:260,y:60+p*50,color:y.active?"#22c55e":"#6b7280"});}let c=new Set;for(let p of e.unmet)c.add(p.requirement.type);let u=0;for(let p of c)r.push({id:`req-${p}`,label:p,type:"requirement",x:480,y:60+u*50,color:"#eab308"}),u++;for(let p=0;p<e.resolverDefs.length;p++){let y=e.resolverDefs[p];r.push({id:`resolver-${y.id}`,label:y.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 f=new Map(r.map(p=>[p.id,p])),d=960,m=Math.max(...r.map(p=>p.y))+50+20,v=s.map(p=>{let y=f.get(p.from),R=f.get(p.to);return !y||!R?"":`<line x1="${y.x+90}" y1="${y.y+15}" x2="${R.x}" y2="${R.y+15}" stroke="#94a3b8" stroke-width="1.5" marker-end="url(#arrow)"/>`}).join(`
348
+ `),$=r.map(p=>`<g>
349
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
350
  <text x="${p.x+90}" y="${p.y+19}" text-anchor="middle" font-size="12" font-family="monospace" fill="${p.color}">${Nr(p.label)}</text>
351
351
  </g>`).join(`
352
- `),_=["Facts","Constraints","Requirements","Resolvers"].map((p,y)=>`<text x="${40+y*220+90}" y="35" text-anchor="middle" font-size="14" font-weight="bold" font-family="system-ui" fill="#e2e8f0">${p}</text>`).join(`
352
+ `),z=["Facts","Constraints","Requirements","Resolvers"].map((p,y)=>`<text x="${40+y*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>
@@ -366,12 +366,12 @@ Current requirements:`),n.unmet.length===0)console.log(g.dim(" (no unmet requir
366
366
  <path d="M 0 0 L 10 5 L 0 10 z" fill="#94a3b8"/>
367
367
  </marker>
368
368
  </defs>
369
- ${_}
369
+ ${z}
370
370
  ${v}
371
- ${b}
371
+ ${$}
372
372
  </svg>
373
373
  </body>
374
- </html>`}function Nr(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function kt(e){let{filePath:t,opts:r}=qr(e);t||(console.error("Usage: directive graph <file> [--ascii] [--no-open] [--output <path>]"),process.exit(1));let s=await W(t);s.isRunning||s.start();let n=s.inspect();if(r.ascii){console.log(Pr(n)),s.stop();return}let o={};if(s.facts)for(let a of Object.keys(s.facts))try{o[a]=s.facts[a];}catch{o[a]=null;}let i=Ir(n,o),l=r.output||join(process.cwd(),".directive-graph.html");if(writeFileSync(l,i,"utf-8"),console.log(`${g.green("Generated")} ${g.dim(l)}`),r.open)try{let{execFile:a}=await import('child_process'),c=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";a(c,[l]),console.log(g.dim("Opened in browser."));}catch{console.log(g.dim(`Open ${l} in your browser to view the graph.`));}s.stop();}function Wr(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 Lr(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 Br(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 ze(e){return {counter:{id:"counter",label:"Counter (minimal)",hint:"schema + init + derive + events \u2014 simplest starting point",files:[{path:`src/${e}.ts`,content:Kr(e)},{path:"src/main.ts",content:Jr(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:Gr(e)},{path:"src/main.ts",content:Hr(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:Vr(e)},{path:"src/main.ts",content:Yr(e)}],deps:["@directive-run/core","@directive-run/ai"]}}}function Kr(e){return `import { type ModuleSchema, createModule, t } from "@directive-run/core";
374
+ </html>`}function Nr(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function xt(e){let{filePath:t,opts:r}=qr(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(Pr(n)),s.stop();return}let i={};if(s.facts)for(let a of Object.keys(s.facts))try{i[a]=s.facts[a];}catch{i[a]=null;}let o=Ir(n,i),l=r.output||join(process.cwd(),".directive-graph.html");if(writeFileSync(l,o,"utf-8"),console.log(`${g.green("Generated")} ${g.dim(l)}`),r.open)try{let{execFile:a}=await import('child_process'),c=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";a(c,[l]),console.log(g.dim("Opened in browser."));}catch{console.log(g.dim(`Open ${l} in your browser to view the graph.`));}s.stop();}function Ur(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 Lr(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 Kr(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 _e(e){return {counter:{id:"counter",label:"Counter (minimal)",hint:"schema + init + derive + events \u2014 simplest starting point",files:[{path:`src/${e}.ts`,content:Br(e)},{path:"src/main.ts",content:Jr(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:Gr(e)},{path:"src/main.ts",content:Hr(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:Vr(e)},{path:"src/main.ts",content:Yr(e)}],deps:["@directive-run/core","@directive-run/ai"]}}}function Br(e){return `import { type ModuleSchema, createModule, t } from "@directive-run/core";
375
375
 
376
376
  const schema = {
377
377
  facts: {
@@ -696,89 +696,89 @@ await system.settle();
696
696
  console.log("output:", system.facts.output);
697
697
 
698
698
  export default system;
699
- `}function ae(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function Xr(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}async function xt(e){let t=Wr(e);h.intro(g.bgCyan(g.black(" directive init ")));let r;if(t.noInteractive)r="my-module";else {let f=await h.text({message:"Module name:",placeholder:"my-module",defaultValue:"my-module",validate:d=>{if(!/^[a-z][a-z0-9-]*$/.test(d))return "Must start with a letter, use lowercase letters, numbers, and hyphens"}});h.isCancel(f)&&(h.cancel("Cancelled."),process.exit(0)),r=f;}let s;if(t.template){let f=ze(r);t.template in f||(h.log.error(`Unknown template: ${t.template}. Available: ${Object.keys(f).join(", ")}`),process.exit(1)),s=t.template;}else if(t.noInteractive)s="counter";else {let f=ze(r),d=await h.select({message:"Project template:",options:Object.values(f).map(m=>({value:m.id,label:m.label,hint:m.hint}))});h.isCancel(d)&&(h.cancel("Cancelled."),process.exit(0)),s=d;}let o=ze(r)[s],i=Lr(t.dir);h.log.info(`Package manager: ${g.cyan(i)}`);let l=h.spinner();l.start("Creating project files...");let c=0;for(let f of o.files){let d=join(t.dir,f.path);if(existsSync(d)){c++;continue}Xr(d,f.content);}l.stop("Project files created.");for(let f of o.files){let d=join(t.dir,f.path),m=relative(t.dir,d);existsSync(d)&&h.log.success(`${g.green("Created")} ${g.dim(m)}`);}c>0&&h.log.warn(`Skipped ${c} file(s) that already exist.`);let u=Br(i,o.deps.join(" "));h.outro(`Next steps:
699
+ `}function ae(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function Xr(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}async function kt(e){let t=Ur(e);h.intro(g.bgCyan(g.black(" directive init ")));let r;if(t.noInteractive)r="my-module";else {let f=await h.text({message:"Module name:",placeholder:"my-module",defaultValue:"my-module",validate:d=>{if(!/^[a-z][a-z0-9-]*$/.test(d))return "Must start with a letter, use lowercase letters, numbers, and hyphens"}});h.isCancel(f)&&(h.cancel("Cancelled."),process.exit(0)),r=f;}let s;if(t.template){let f=_e(r);t.template in f||(h.log.error(`Unknown template: ${t.template}. Available: ${Object.keys(f).join(", ")}`),process.exit(1)),s=t.template;}else if(t.noInteractive)s="counter";else {let f=_e(r),d=await h.select({message:"Project template:",options:Object.values(f).map(m=>({value:m.id,label:m.label,hint:m.hint}))});h.isCancel(d)&&(h.cancel("Cancelled."),process.exit(0)),s=d;}let i=_e(r)[s],o=Lr(t.dir);h.log.info(`Package manager: ${g.cyan(o)}`);let l=h.spinner();l.start("Creating project files...");let c=0;for(let f of i.files){let d=join(t.dir,f.path);if(existsSync(d)){c++;continue}Xr(d,f.content);}l.stop("Project files created.");for(let f of i.files){let d=join(t.dir,f.path),m=relative(t.dir,d);existsSync(d)&&h.log.success(`${g.green("Created")} ${g.dim(m)}`);}c>0&&h.log.warn(`Skipped ${c} file(s) that already exist.`);let u=Kr(o,i.deps.join(" "));h.outro(`Next steps:
700
700
  ${g.cyan(u)}
701
- ${g.cyan(`${j} ai-rules init`)}
702
- ${g.dim("Start building!")}`);}function Qr(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 Zr(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=on(n);t.push(` ${g.cyan(s)} = ${o}`);}return t.join(`
701
+ ${g.cyan(`${A} ai-rules init`)}
702
+ ${g.dim("Start building!")}`);}function Qr(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 i=e[++s];i&&(t.module=i);break}default:n&&!n.startsWith("-")&&!r&&(r=n);}}return {filePath:r,opts:t}}function Zr(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 i=on(n);t.push(` ${g.cyan(s)} = ${i}`);}return t.join(`
704
704
  `)}function en(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
706
  `)}function tn(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?sn(n.state,n.error,n.duration):g.dim("idle");r.push(` ${g.cyan(s.id)} \u2192 ${s.requirement} ${o}`);}return r.join(`
707
+ `);for(let s of e){let n=t[s.id],i=n?sn(n.state,n.error,n.duration):g.dim("idle");r.push(` ${g.cyan(s.id)} \u2192 ${s.requirement} ${i}`);}return r.join(`
708
708
  `)}function rn(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
710
  `)}function nn(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 sn(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 on(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 an(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(l=>l.requirement===o.requirement.type||l.requirement==="(predicate)")||t.push(`No resolver for requirement type "${o.requirement.type}"`);return t}async function Et(e){let{filePath:t,opts:r}=Qr(e);t||(console.error("Usage: directive inspect <file> [--json] [--module <name>]"),process.exit(1));let s=await W(t);s.isRunning||s.start();let n=s.inspect();if(r.json){let l={};if(s.facts)for(let a of Object.keys(s.facts))try{l[a]=s.facts[a];}catch{l[a]="(error reading)";}console.log(JSON.stringify({facts:l,...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 l of Object.keys(s.facts))try{o[l]=s.facts[l];}catch{o[l]="(error reading)";}console.log(Zr(o)),console.log(),console.log(en(n.constraints)),console.log(),console.log(tn(n.resolverDefs,n.resolvers)),console.log(),console.log(rn(n.unmet)),console.log(),n.inflight.length>0&&(console.log(nn(n.inflight)),console.log());let i=an(n);if(i.length>0){console.log(g.bold(g.yellow("Warnings:")));for(let l of i)console.log(` ${g.yellow("\u26A0")} ${l}`);console.log();}s.stop();}function Rt(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 Dt=["derive","events","constraints","resolvers","effects"];function fn(e,t){let r=jt(e),s=t.includes("constraints"),n=t.includes("resolvers"),i=`import { ${["type ModuleSchema","createModule","t"].join(", ")} } from "@directive-run/core";
713
-
714
- `;return i+=`const schema = {
715
- `,i+=` facts: {
716
- `,i+=` // Add your facts here
717
- `,i+=` status: t.string(),
718
- `,i+=` },
719
- `,t.includes("derive")&&(i+=` derivations: {
720
- `,i+=` // Add derivation types here
721
- `,i+=` isReady: t.boolean(),
722
- `,i+=` },
723
- `),t.includes("events")&&(i+=` events: {
724
- `,i+=` // Add event shapes here
725
- `,i+=` setStatus: { value: t.string() },
726
- `,i+=` },
727
- `),(s||n)&&(i+=` requirements: {
728
- `,i+=` // Add requirement shapes here
729
- `,i+=` PROCESS: { input: t.string() },
730
- `,i+=` },
731
- `),i+=`} satisfies ModuleSchema;
732
-
733
- `,i+=`export const ${r} = createModule("${e}", {
734
- `,i+=` schema,
735
-
736
- `,i+=` init: (facts) => {
737
- `,i+=` facts.status = "idle";
738
- `,i+=` },
739
- `,t.includes("derive")&&(i+=`
712
+ `)}function sn(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 on(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 an(e){let t=[];new Set(e.unmet.map(i=>i.requirement.type));new Set(e.resolverDefs.map(i=>i.requirement));for(let i of e.resolverDefs)i.requirement;for(let i of e.unmet)e.resolverDefs.some(l=>l.requirement===i.requirement.type||l.requirement==="(predicate)")||t.push(`No resolver for requirement type "${i.requirement.type}"`);return t}async function Dt(e){let{filePath:t,opts:r}=Qr(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 l={};if(s.facts)for(let a of Object.keys(s.facts))try{l[a]=s.facts[a];}catch{l[a]="(error reading)";}console.log(JSON.stringify({facts:l,...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 i={};if(s.facts)for(let l of Object.keys(s.facts))try{i[l]=s.facts[l];}catch{i[l]="(error reading)";}console.log(Zr(i)),console.log(),console.log(en(n.constraints)),console.log(),console.log(tn(n.resolverDefs,n.resolvers)),console.log(),console.log(rn(n.unmet)),console.log(),n.inflight.length>0&&(console.log(nn(n.inflight)),console.log());let o=an(n);if(o.length>0){console.log(g.bold(g.yellow("Warnings:")));for(let l of o)console.log(` ${g.yellow("\u26A0")} ${l}`);console.log();}s.stop();}function jt(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(i=>i.trim()));break}case "--minimal":t.minimal=true;break;case "--dir":{let n=e[++r];n&&(t.dir=n);break}}return t}var Et=["derive","events","constraints","resolvers","effects"];function fn(e,t){let r=At(e),s=t.includes("constraints"),n=t.includes("resolvers"),o=`import { ${["type ModuleSchema","createModule","t"].join(", ")} } from "@directive-run/core";
713
+
714
+ `;return o+=`const schema = {
715
+ `,o+=` facts: {
716
+ `,o+=` // Add your facts here
717
+ `,o+=` status: t.string(),
718
+ `,o+=` },
719
+ `,t.includes("derive")&&(o+=` derivations: {
720
+ `,o+=` // Add derivation types here
721
+ `,o+=` isReady: t.boolean(),
722
+ `,o+=` },
723
+ `),t.includes("events")&&(o+=` events: {
724
+ `,o+=` // Add event shapes here
725
+ `,o+=` setStatus: { value: t.string() },
726
+ `,o+=` },
727
+ `),(s||n)&&(o+=` requirements: {
728
+ `,o+=` // Add requirement shapes here
729
+ `,o+=` PROCESS: { input: t.string() },
730
+ `,o+=` },
731
+ `),o+=`} satisfies ModuleSchema;
732
+
733
+ `,o+=`export const ${r} = createModule("${e}", {
734
+ `,o+=` schema,
735
+
736
+ `,o+=` init: (facts) => {
737
+ `,o+=` facts.status = "idle";
738
+ `,o+=` },
739
+ `,t.includes("derive")&&(o+=`
740
740
  derive: {
741
- `,i+=` isReady: (facts) => facts.status === "ready",
742
- `,i+=` },
743
- `),t.includes("events")&&(i+=`
741
+ `,o+=` isReady: (facts) => facts.status === "ready",
742
+ `,o+=` },
743
+ `),t.includes("events")&&(o+=`
744
744
  events: {
745
- `,i+=` setStatus: (facts, { value }) => {
746
- `,i+=` facts.status = value;
747
- `,i+=` },
748
- `,i+=` },
749
- `),s&&(i+=`
745
+ `,o+=` setStatus: (facts, { value }) => {
746
+ `,o+=` facts.status = value;
747
+ `,o+=` },
748
+ `,o+=` },
749
+ `),s&&(o+=`
750
750
  constraints: {
751
- `,i+=` needsProcessing: {
752
- `,i+=` priority: 100,
753
- `,i+=` when: (facts) => facts.status === "pending",
754
- `,i+=` require: (facts) => ({
755
- `,i+=` type: "PROCESS",
756
- `,i+=` input: facts.status,
757
- `,i+=` }),
758
- `,i+=` },
759
- `,i+=` },
760
- `),n&&(i+=`
751
+ `,o+=` needsProcessing: {
752
+ `,o+=` priority: 100,
753
+ `,o+=` when: (facts) => facts.status === "pending",
754
+ `,o+=` require: (facts) => ({
755
+ `,o+=` type: "PROCESS",
756
+ `,o+=` input: facts.status,
757
+ `,o+=` }),
758
+ `,o+=` },
759
+ `,o+=` },
760
+ `),n&&(o+=`
761
761
  resolvers: {
762
- `,i+=` process: {
763
- `,i+=` requirement: "PROCESS",
764
- `,i+=` resolve: async (req, context) => {
765
- `,i+=` // Implement resolution logic here
766
- `,i+=` context.facts.status = "done";
767
- `,i+=` },
768
- `,i+=` },
769
- `,i+=` },
770
- `),t.includes("effects")&&(i+=`
762
+ `,o+=` process: {
763
+ `,o+=` requirement: "PROCESS",
764
+ `,o+=` resolve: async (req, context) => {
765
+ `,o+=` // Implement resolution logic here
766
+ `,o+=` context.facts.status = "done";
767
+ `,o+=` },
768
+ `,o+=` },
769
+ `,o+=` },
770
+ `),t.includes("effects")&&(o+=`
771
771
  effects: {
772
- `,i+=` logChange: {
773
- `,i+=` deps: ["status"],
774
- `,i+=` run: (facts, prev) => {
775
- `,i+=` if (prev && prev.status !== facts.status) {
776
- `,i+=" console.log(`Status: ${prev.status} \u2192 ${facts.status}`);\n",i+=` }
777
- `,i+=` },
778
- `,i+=` },
779
- `,i+=` },
780
- `),i+=`});
781
- `,i}function dn(e){let t=jt(e);return `import { type ModuleSchema, createModule, createSystem, t } from "@directive-run/core";
772
+ `,o+=` logChange: {
773
+ `,o+=` deps: ["status"],
774
+ `,o+=` run: (facts, prev) => {
775
+ `,o+=` if (prev && prev.status !== facts.status) {
776
+ `,o+=" console.log(`Status: ${prev.status} \u2192 ${facts.status}`);\n",o+=` }
777
+ `,o+=` },
778
+ `,o+=` },
779
+ `,o+=` },
780
+ `),o+=`});
781
+ `,o}function dn(e){let t=At(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 jt(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function At(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}function Ct(e){return join(e,"src")}async function Ot(e,t){let r=Rt(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(a=>Dt.includes(a)):s=Dt;let n=Ct(r.dir),o=join(n,`${e}.ts`);existsSync(o)&&(console.error(`File already exists: ${relative(r.dir,o)}`),process.exit(1));let i=fn(e,s);At(o,i);let l=relative(r.dir,o);console.log(`${g.green("Created")} ${g.dim(l)}`),s.length===0?console.log(g.dim(" Minimal module (schema + init only)")):console.log(g.dim(` Sections: ${s.join(", ")}`));}async function Mt(e,t){let r=Rt(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=Ct(r.dir),n=join(s,`${e}.ts`);existsSync(n)&&(console.error(`File already exists: ${relative(r.dir,n)}`),process.exit(1));let o=dn(e);At(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 Re=typeof process<"u"&&process.env?.NODE_ENV!=="production";Object.freeze(new Set(["__proto__","constructor","prototype"]));function de(e,t=50){let r=new WeakSet;function s(a){if(a===null)return "null";if(a===void 0)return "undefined";let c=typeof a;if(c==="string")return JSON.stringify(a);if(c==="number"||c==="boolean")return String(a);if(c==="function")return '"[function]"';if(c==="symbol")return '"[symbol]"'}function n(a,c){if(r.has(a))return '"[circular]"';r.add(a);let u=c();return r.delete(a),u}function o(a,c){return n(a,()=>`[${a.map(u=>l(u,c+1)).join(",")}]`)}function i(a,c){return n(a,()=>`{${Object.keys(a).sort().map(u=>`${JSON.stringify(u)}:${l(a[u],c+1)}`).join(",")}}`)}function l(a,c){if(c>t)return '"[max depth exceeded]"';if(typeof a=="bigint")return `${a.toString()}n`;let u=s(a);if(u!==void 0)return u;if(a instanceof Date)return `D:${a.toISOString()}`;if(a instanceof RegExp)return `R:${a.source}:${a.flags}`;if(a instanceof Map){let f=[...a.entries()].sort();return `M:${l(f,c+1)}`}if(a instanceof Set){let f=[...a].sort();return `S:${l(f,c+1)}`}return Array.isArray(a)?o(a,c):typeof a=="object"?i(a,c):'"[unknown]"'}return l(e,0)}var B=new Set(["$eq","$ne","$in","$nin","$exists","$gt","$gte","$lt","$lte","$between","$matches","$startsWith","$endsWith","$contains","$changed"]),qt=new Set(["$all","$any","$not"]),K=64;function N(e){return typeof e!="object"||e===null||Array.isArray(e)?false:!(e instanceof Date)&&!(e instanceof RegExp)}function je(e){if(typeof e!="object"||e===null||Array.isArray(e))return false;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function Be(e){if(!N(e))return false;let t=0,r=false;for(let s of Object.keys(e)){if(s.startsWith("$"))r=true,B.has(s)||me(`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 Pt(e){return e===null?false:Array.isArray(e)?e.every(t=>je(t)&&"fact"in t&&"op"in t):je(e)}function pe(e,t,r="",s=new WeakSet,n=0){if(n>K){Re&&console.warn(`[Directive] predicate depth limit (${K}) 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,l)=>{if(!N(i))return;let a=i;if(typeof a.fact=="string"&&typeof a.op=="string"){let c=r?`${r}[${l}]`:`[${l}]`;t.operator?.(r?`${r}.${a.fact}`:a.fact,a.op,a.value,`${c}.value`);}});return}if(!N(e))return;if(s.has(e)){Re&&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 l=i==="$not"?[o.$not]:o[i]??[];for(let a of l)pe(a,t,r,s,n+1);return}for(let i of Object.keys(o)){let l=r?`${r}.${i}`:i;if(i.startsWith("$")){t.strayOperatorKey?.(i,l);continue}let a=o[i];if(Be(a)){let c=a;for(let u of Object.keys(c))t.operator?.(l,u,c[u],`${l}.${u}`);continue}if(je(a)){if(t.nested?.(i)===false)continue;pe(a,t,l,s,n+1);continue}t.literal?.(l,a);}}function It(e,t=""){function r(n,o,i,l){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")&&!(l>K)&&!i.has(n)){if(i.add(n),Array.isArray(n)){n.forEach((a,c)=>{r(a,`${o}[${c}]`,i,l+1);});return}for(let a of Object.keys(n))r(n[a],o?`${o}.${a}`:a,i,l+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((l,a)=>{r(l,`${i}[${a}]`,new WeakSet,1);});else if(je(n))for(let l of Object.keys(n))r(n[l],`${i}.${l}`,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).`);pe(e,{operator(n,o,i,l){s(i,o,t?`${t}.${l}`:l);},literal(n,o){s(o,"",t?`${t}.${n}`:n);}});}function mn(){return {ids:new WeakMap,next:{v:1},pairs:new Set}}function Tt(e,t){let r=e.ids.get(t);return r===void 0&&(r=e.next.v++,e.ids.set(t,r)),r}function I(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??mn(),n=`${Tt(s,e)}:${Tt(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((l,a)=>I(l,t[a],s));if(e instanceof Set||t instanceof Set){if(!(e instanceof Set)||!(t instanceof Set)||e.size!==t.size)return false;let l=[...t];return [...e].every(a=>l.some(c=>I(a,c,s)))}if(e instanceof Map||t instanceof Map){if(!(e instanceof Map)||!(t instanceof Map)||e.size!==t.size)return false;let l=[...t.entries()],a=new Array(l.length).fill(false);for(let[c,u]of e){let f=false;for(let d=0;d<l.length;d++){if(a[d])continue;let[m,v]=l[d];if(I(c,m,s)&&I(u,v,s)){a[d]=true,f=true;break}}if(!f)return false}return true}let o=Object.keys(e),i=Object.keys(t);return o.length!==i.length?false:o.every(l=>Object.hasOwn(t,l)&&I(e[l],t[l],s))}function Ae(e){if(e instanceof Date)return e.getTime();if(typeof e=="number"||typeof e=="bigint"||typeof e=="string")return e}function Le(e,t,r){let s=Ae(t),n=Ae(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 Ce(e,t,r,s){switch(e){case "$eq":return I(t,r);case "$ne":return !I(t,r);case "$in":return Array.isArray(r)&&r.some(n=>I(t,n));case "$nin":return Array.isArray(r)&&!r.some(n=>I(t,n));case "$exists":return r===(t!==void 0);case "$changed":return !I(t,s);case "$gt":case "$gte":case "$lt":case "$lte":return Le(e,t,r);case "$between":{if(!Array.isArray(r)||r.length!==2)return false;let n=Ae(r[0]),o=Ae(r[1]);return n!==void 0&&o!==void 0&&typeof n==typeof o&&n>o?(me("$between: reversed pair \u2014 [min, max] required"),false):Le("$gte",t,r[0])&&Le("$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=>I(n,r)):t instanceof Set?t.has(r):false;default:return false}}function me(e){Re&&console.warn(`[Directive] ${e}`);}function hn(e,t,r,s){if(Be(e)){let n=Object.keys(e);n.length>1&&me(`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(!Ce(o,t,e[o],r))return false;return true}return N(e)?te(e,N(t)?t:Object.create(null),N(r)?r:void 0,s+1):I(t,e)}function te(e,t,r,s=0){if(s>K)return me(`predicate depth limit (${K}) 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(!N(n))return false;let{fact:o,op:i,value:l}=n;return Ce(i,t?.[o],l,r?.[o])});if(!N(e))return !!e;if("$all"in e)return e.$all.every(n=>te(n,t,r,s+1));if("$any"in e)return e.$any.some(n=>te(n,t,r,s+1));if("$not"in e)return !te(e.$not,t,r,s+1);for(let n of Object.keys(e)){if(B.has(n))return me(`predicate: operator "${n}" mixed with fact keys \u2014 wrap operators in a per-fact object`),false;if(!hn(e[n],t?.[n],r?.[n],s))return false}return true}function he(e,t,r,s=""){let n=[];if(Array.isArray(e)){for(let o of e){if(!N(o))continue;let{fact:i,op:l,value:a}=o,c=t?.[i];n.push({path:s+i,op:l,expected:a,actual:c,pass:Ce(l,c,a,r?.[i])});}return n}if(!N(e))return n;for(let o of ["$all","$any","$not"])if(o in e){let i=o==="$not"?[e.$not]:e[o],l=[];for(let u of i)l.push(...he(u,t,r,s));let a=l.filter(u=>u.pass).length,c;return o==="$all"?c=l.length===0||a===l.length:o==="$any"?c=l.length>0&&a>0:c=!l.every(u=>u.pass),n.push({path:s||o,op:o,expected:i.length,actual:a,pass:c,children:l}),n}for(let o of Object.keys(e)){if(B.has(o))continue;let i=e[o],l=t?.[o],a=s+o;if(Be(i))for(let c of Object.keys(i))n.push({path:a,op:c,expected:i[c],actual:l,pass:Ce(c,l,i[c],r?.[o])});else N(i)?n.push(...he(i,N(l)?l:Object.create(null),N(r?.[o])?r?.[o]:void 0,`${a}.`)):n.push({path:a,op:"$eq",expected:i,actual:l,pass:I(l,i)});}return n}var le=1e6;function Nt(e,t){try{It(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(!Pt(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(pe(e,{operator(s,n){r===void 0&&n.startsWith("$")&&!B.has(n)&&(r=n);},strayOperatorKey(s){r===void 0&&!B.has(s)&&!qt.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 ge(e){if(e&&typeof e=="object"&&!Array.isArray(e)&&Array.isArray(e.snapshots))return gn(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>le)throw new Error(`[Directive] toReplayFrames: history has ${t.length} frames, exceeds the MAX_REPLAY_FRAMES limit (${le}) \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 gn(e){let t=typeof e=="string"?JSON.parse(e):e;if(Array.isArray(t))return Ft(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 Ft(r.snapshots)}function Ft(e){if(!Array.isArray(e))throw new Error("[Directive] framesFromSnapshots: expected an array of fact-state snapshots");if(e.length>le)throw new Error(`[Directive] framesFromSnapshots: history has ${e.length} snapshots, exceeds the MAX_REPLAY_FRAMES limit (${le}) \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 ge(e)}function Oe(e){let{frames:t,original:r,proposed:s,entityKey:n}=e,o=e.maxSamples??20,i=o>0?o:0;if(t.length>le)throw new Error(`[Directive] replayUnder: history has ${t.length} frames, exceeds the MAX_REPLAY_FRAMES limit (${le}) \u2014 split or down-sample the history`);Nt(r,"original"),Nt(s,"proposed");let l=0,a=0,c=0,u=0,f=0,d=[],m=[],v=n?new Set:void 0,b=n?new Set:void 0,F;for(let p of t){let y=p.facts,A=te(r,y,F),z=te(s,y,F);A&&(l++,v?.add(y[n])),z&&(a++,b?.add(y[n])),A===z?f++:!A&&z?(c++,d.length<i&&d.push(_t(p,r,s,F))):(u++,m.length<i&&m.push(_t(p,r,s,F))),F=y;}let _={framesEvaluated:t.length,original:{matched:l},proposed:{matched:a},delta:a-l,newMatchCount:c,lostMatchCount:u,unchanged:f,newMatches:d,lostMatches:m};return v&&b&&(_.original.matchedEntities=v.size,_.proposed.matchedEntities=b.size),_}function _t(e,t,r,s){let n=e.facts,o={frameId:e.id,facts:n,originalExplain:he(t,n,s),proposedExplain:he(r,n,s)};return e.timestamp!==void 0&&(o.timestamp=e.timestamp),o}var zt=1e4,Ut=5e7;function yn(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===1&&typeof e.$hole=="string"}function Ke(e,t,r=new Set,s=0){if(s>K)throw new Error(`[Directive] sweepUnder: template exceeds MAX_PREDICATE_DEPTH (${K}) \u2014 flatten the template or split the sweep`);if(yn(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=>Ke(o,t,r,s+1));let n={};for(let[o,i]of Object.entries(e))n[o]=Ke(i,t,r,s+1);return n}finally{r.delete(e);}}function*Lt(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 Lt(s,t))yield {[r]:o,...i};}function vn(e){let t=1;for(let r of Object.values(e))t*=r.length;return t}function Bt(e){let{frames:t,original:r,template:s,sweep:n,objective:o=y=>y.proposed.matched,entityKey:i,maxSamples:l=0}=e,a=Object.keys(n);if(a.length===0)throw new Error("[Directive] sweepUnder: `sweep` must contain at least one hole name");let c=vn(n);if(c>zt)throw new Error(`[Directive] sweepUnder: grid has ${c} points, exceeds the MAX_SWEEP_POINTS limit (${zt}) \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 u=c*t.length;if(u>Ut)throw new Error(`[Directive] sweepUnder: ${c} points \xD7 ${t.length} frames = ${u} per-frame evaluations, exceeds the MAX_SWEEP_EVALUATIONS limit (${Ut}) \u2014 narrow the sweep, down-sample the history, or split the run`);let f=false,d=y=>{let A;try{A=o(y);}catch(z){return f||(f=true,console.warn(`[Directive] sweepUnder: objective threw \u2014 point will not rank (${z.message})`)),Number.NEGATIVE_INFINITY}return typeof A!="number"||!Number.isFinite(A)?(f||(f=true,console.warn(`[Directive] sweepUnder: objective returned a non-finite number (${String(A)}) \u2014 point will not rank`)),Number.NEGATIVE_INFINITY):A},m=Oe({frames:t,original:r,proposed:r,entityKey:i,maxSamples:l}),v={values:{},report:m,score:d(m)},b=[],F=0,_=Number.NEGATIVE_INFINITY;for(let y of Lt(a,n)){let A=Ke(s,y),z=Oe({frames:t,original:r,proposed:A,entityKey:i,maxSamples:l}),Te=d(z);Te>_&&(_=Te,F=b.length),b.push({values:y,report:z,score:Te});}let p=b[F];return {points:b,bestIndex:F,best:p,baseline:v}}function Wt(e){let t=e&&typeof e=="object"&&!Array.isArray(e)&&"constraints"in e?e.constraints:e;if(Array.isArray(t)){let r={};for(let s of t){if(!s||typeof s!="object"||!("id"in s))throw new Error("[Directive] diffRules: array entries must be `{ id, whenSpec }` objects");let n=s;if(typeof n.id!="string")throw new Error("[Directive] diffRules: constraint `id` must be a string");r[n.id]=n.whenSpec;}return r}if(t&&typeof t=="object")return t;throw new Error("[Directive] diffRules: expected a `{ id: whenSpec }` map, an array of `{ id, whenSpec }`, or `{ constraints: ... }`")}var wn=new Set(["$eq","$ne","$in","$nin","$exists","$gt","$gte","$lt","$lte","$between","$matches","$startsWith","$endsWith","$contains","$changed"]),bn=new Set(["$all","$any","$not"]);function Kt(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function $n(e){if(!Kt(e))return false;let t=Object.keys(e);if(t.length===0)return false;let r=false;for(let s of t){if(!s.startsWith("$"))return false;wn.has(s)&&(r=true);}return r}function G(e,t="",r=[]){if(e===null||typeof e!="object")return r;if(Array.isArray(e)){for(let s of e)if(s&&typeof s=="object"&&"fact"in s&&"op"in s){let n=s;r.push({path:t?`${t}.${String(n.fact)}`:String(n.fact),op:String(n.op),value:n.value});}return r}if("$all"in e&&Array.isArray(e.$all))return e.$all.forEach((s,n)=>{G(s,`${t}$all[${n}]`,r);}),r;if("$any"in e&&Array.isArray(e.$any))return e.$any.forEach((s,n)=>{G(s,`${t}$any[${n}]`,r);}),r;if("$not"in e)return G(e.$not,`${t}$not`,r),r;for(let[s,n]of Object.entries(e)){let o=t?`${t}.${s}`:s;if($n(n))for(let[i,l]of Object.entries(n))r.push({path:o,op:i,value:l});else Kt(n)&&!bn.has(s)?G(n,o,r):r.push({path:o,op:"$eq",value:n});}return r}function J(e){return typeof e=="number"&&Number.isFinite(e)}function Sn(e,t,r){switch(e){case "$gte":case "$gt":if(J(t)&&J(r)){if(r<t)return "relaxed";if(r>t)return "tightened"}return null;case "$lte":case "$lt":if(J(t)&&J(r)){if(r>t)return "relaxed";if(r<t)return "tightened"}return null;case "$between":{if(Array.isArray(t)&&Array.isArray(r)&&t.length===2&&r.length===2&&J(t[0])&&J(t[1])&&J(r[0])&&J(r[1])){let s=t[1]-t[0],n=r[1]-r[0];if(n>s)return "relaxed";if(n<s)return "tightened"}return null}case "$in":case "$nin":{if(Array.isArray(t)&&Array.isArray(r))if(e==="$in"){if(r.length>t.length)return "relaxed";if(r.length<t.length)return "tightened"}else {if(r.length>t.length)return "tightened";if(r.length<t.length)return "relaxed"}return null}case "$contains":{if(Array.isArray(t)&&Array.isArray(r)){if(r.length>t.length)return "relaxed";if(r.length<t.length)return "tightened"}return null}default:return null}}function Jt(e){let t=Wt(e.before),r=Wt(e.after),s=[...new Set([...Object.keys(t),...Object.keys(r)])].sort(),n=[],o={added:0,removed:0,changed:0,unchanged:0,totalClauseChanges:0};for(let i of s){let l=t[i],a=r[i],c=i in t,u=i in r;if(c&&!u){let d=G(l),m=d.length===0?[{path:"(function-form predicate)",kind:"removed"}]:d.map(v=>({path:v.path,kind:"removed",before:{op:v.op,value:v.value}}));Je(m),n.push({id:i,status:"removed",changes:m}),o.removed++,o.totalClauseChanges+=m.length;continue}if(!c&&u){let d=G(a),m=d.length===0?[{path:"(function-form predicate)",kind:"added"}]:d.map(v=>({path:v.path,kind:"added",after:{op:v.op,value:v.value}}));Je(m),n.push({id:i,status:"added",changes:m}),o.added++,o.totalClauseChanges+=m.length;continue}let f=kn(l,a);f.length===0?(n.push({id:i,status:"unchanged",changes:[]}),o.unchanged++):(n.push({id:i,status:"changed",changes:f}),o.changed++,o.totalClauseChanges+=f.length);}return {constraints:n,summary:o}}function kn(e,t){if(e!==void 0&&t!==void 0&&(e===null||t===null||typeof e!="object"||typeof t!="object"))return de(e)===de(t)?[]:[{path:"",kind:"changed",before:{op:"$eq",value:e},after:{op:"$eq",value:t}}];let r=e===void 0?[]:G(e),s=t===void 0?[]:G(t),n=c=>`${c.path}::${c.op}`,o=new Map(r.map(c=>[n(c),c])),i=new Map(s.map(c=>[n(c),c])),l=new Set([...o.keys(),...i.keys()]),a=[];for(let c of l){let u=o.get(c),f=i.get(c);if(u&&!f){a.push({path:u.path,kind:"removed",before:{op:u.op,value:u.value}});continue}if(!u&&f){a.push({path:f.path,kind:"added",after:{op:f.op,value:f.value}});continue}if(u&&f){if(de(u.value)===de(f.value))continue;let d=Sn(u.op,u.value,f.value);a.push({path:u.path,kind:d??"changed",before:{op:u.op,value:u.value},after:{op:f.op,value:f.value}});}}return Je(a),a}function Je(e){e.sort((t,r)=>{let s=t.path.localeCompare(r.path);if(s!==0)return s;let n=t.before?.op??t.after?.op??"",o=r.before?.op??r.after?.op??"";return n.localeCompare(o)});}function Rn(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 Me(){console.error(`
912
+ `}function At(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function Rt(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}function Ct(e){return join(e,"src")}async function Ot(e,t){let r=jt(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(a=>Et.includes(a)):s=Et;let n=Ct(r.dir),i=join(n,`${e}.ts`);existsSync(i)&&(console.error(`File already exists: ${relative(r.dir,i)}`),process.exit(1));let o=fn(e,s);Rt(i,o);let l=relative(r.dir,i);console.log(`${g.green("Created")} ${g.dim(l)}`),s.length===0?console.log(g.dim(" Minimal module (schema + init only)")):console.log(g.dim(` Sections: ${s.join(", ")}`));}async function Mt(e,t){let r=jt(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=Ct(r.dir),n=join(s,`${e}.ts`);existsSync(n)&&(console.error(`File already exists: ${relative(r.dir,n)}`),process.exit(1));let i=dn(e);Rt(n,i);let o=relative(r.dir,n);console.log(`${g.green("Created")} ${g.dim(o)}`),console.log(g.dim(" AI orchestrator with memory, guardrails, and streaming"));}function de(e,t=50){let r=new WeakSet;function s(a){if(a===null)return "null";if(a===void 0)return "undefined";let c=typeof a;if(c==="string")return JSON.stringify(a);if(c==="number"||c==="boolean")return String(a);if(c==="function")return '"[function]"';if(c==="symbol")return '"[symbol]"'}function n(a,c){if(r.has(a))return '"[circular]"';r.add(a);let u=c();return r.delete(a),u}function i(a,c){return n(a,()=>`[${a.map(u=>l(u,c+1)).join(",")}]`)}function o(a,c){return n(a,()=>`{${Object.keys(a).sort().map(u=>`${JSON.stringify(u)}:${l(a[u],c+1)}`).join(",")}}`)}function l(a,c){if(c>t)return '"[max depth exceeded]"';if(typeof a=="bigint")return `${a.toString()}n`;let u=s(a);if(u!==void 0)return u;if(a instanceof Date)return `D:${a.toISOString()}`;if(a instanceof RegExp)return `R:${a.source}:${a.flags}`;if(a instanceof Map){let f=[...a.entries()].sort();return `M:${l(f,c+1)}`}if(a instanceof Set){let f=[...a].sort();return `S:${l(f,c+1)}`}return Array.isArray(a)?i(a,c):typeof a=="object"?o(a,c):'"[unknown]"'}return l(e,0)}var je=typeof process<"u"&&process.env?.NODE_ENV!=="production";Object.freeze(new Set(["__proto__","constructor","prototype"]));var K=new Set(["$eq","$ne","$in","$nin","$exists","$gt","$gte","$lt","$lte","$between","$matches","$startsWith","$endsWith","$contains","$changed"]),qt=new Set(["$all","$any","$not"]);var B=64;function N(e){return typeof e!="object"||e===null||Array.isArray(e)?false:!(e instanceof Date)&&!(e instanceof RegExp)}function Ae(e){if(typeof e!="object"||e===null||Array.isArray(e))return false;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function Ke(e){if(!N(e))return false;let t=0,r=false;for(let s of Object.keys(e)){if(s.startsWith("$"))r=true,K.has(s)||me(`predicate: unknown operator "${s}" \u2014 looks like a typo. Known operators: ${[...K].join(", ")}`);else if(r||t===0)return false;t++;}return r?t>0:false}function Pt(e){return e===null?false:Array.isArray(e)?e.every(t=>Ae(t)&&"fact"in t&&"op"in t):Ae(e)}function pe(e,t,r="",s=new WeakSet,n=0){if(n>B){je&&console.warn(`[Directive] predicate depth limit (${B}) 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((o,l)=>{if(!N(o))return;let a=o;if(typeof a.fact=="string"&&typeof a.op=="string"){let c=r?`${r}[${l}]`:`[${l}]`;t.operator?.(r?`${r}.${a.fact}`:a.fact,a.op,a.value,`${c}.value`);}});return}if(!N(e))return;if(s.has(e)){je&&console.warn("[Directive] walkPredicate: cyclic predicate spec"),t.bail?.("cycle");return}s.add(e);let i=e;for(let o of ["$all","$any","$not"])if(o in i){if(t.combinator?.(o)===false)return;let l=o==="$not"?[i.$not]:i[o]??[];for(let a of l)pe(a,t,r,s,n+1);return}for(let o of Object.keys(i)){let l=r?`${r}.${o}`:o;if(o.startsWith("$")){t.strayOperatorKey?.(o,l);continue}let a=i[o];if(Ke(a)){let c=a;for(let u of Object.keys(c))t.operator?.(l,u,c[u],`${l}.${u}`);continue}if(Ae(a)){if(t.nested?.(o)===false)continue;pe(a,t,l,s,n+1);continue}t.literal?.(l,a);}}function It(e,t=""){function r(n,i,o,l){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(n instanceof RegExp)throw new Error(`[Directive] validatePredicate: RegExp operand at "${i}" 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")&&!(l>B)&&!o.has(n)){if(o.add(n),Array.isArray(n)){n.forEach((a,c)=>{r(a,`${i}[${c}]`,o,l+1);});return}for(let a of Object.keys(n))r(n[a],i?`${i}.${a}`:a,o,l+1);}}function s(n,i,o){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(i==="$matches"&&!(n instanceof RegExp))throw new Error(`[Directive] validatePredicate: $matches operand at "${o}" 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((l,a)=>{r(l,`${o}[${a}]`,new WeakSet,1);});else if(Ae(n))for(let l of Object.keys(n))r(n[l],`${o}.${l}`,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).`);pe(e,{operator(n,i,o,l){s(o,i,t?`${t}.${l}`:l);},literal(n,i){s(i,"",t?`${t}.${n}`:n);}});}function mn(){return {ids:new WeakMap,next:{v:1},pairs:new Set}}function Tt(e,t){let r=e.ids.get(t);return r===void 0&&(r=e.next.v++,e.ids.set(t,r)),r}function I(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??mn(),n=`${Tt(s,e)}:${Tt(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((l,a)=>I(l,t[a],s));if(e instanceof Set||t instanceof Set){if(!(e instanceof Set)||!(t instanceof Set)||e.size!==t.size)return false;let l=[...t];return [...e].every(a=>l.some(c=>I(a,c,s)))}if(e instanceof Map||t instanceof Map){if(!(e instanceof Map)||!(t instanceof Map)||e.size!==t.size)return false;let l=[...t.entries()],a=new Array(l.length).fill(false);for(let[c,u]of e){let f=false;for(let d=0;d<l.length;d++){if(a[d])continue;let[m,v]=l[d];if(I(c,m,s)&&I(u,v,s)){a[d]=true,f=true;break}}if(!f)return false}return true}let i=Object.keys(e),o=Object.keys(t);return i.length!==o.length?false:i.every(l=>Object.hasOwn(t,l)&&I(e[l],t[l],s))}function Re(e){if(e instanceof Date)return e.getTime();if(typeof e=="number"||typeof e=="bigint"||typeof e=="string")return e}function Le(e,t,r){let s=Re(t),n=Re(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 Ce(e,t,r,s){switch(e){case "$eq":return I(t,r);case "$ne":return !I(t,r);case "$in":return Array.isArray(r)&&r.some(n=>I(t,n));case "$nin":return Array.isArray(r)&&!r.some(n=>I(t,n));case "$exists":return r===(t!==void 0);case "$changed":return !I(t,s);case "$gt":case "$gte":case "$lt":case "$lte":return Le(e,t,r);case "$between":{if(!Array.isArray(r)||r.length!==2)return false;let n=Re(r[0]),i=Re(r[1]);return n!==void 0&&i!==void 0&&typeof n==typeof i&&n>i?(me("$between: reversed pair \u2014 [min, max] required"),false):Le("$gte",t,r[0])&&Le("$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=>I(n,r)):t instanceof Set?t.has(r):false;default:return false}}function me(e){je&&console.warn(`[Directive] ${e}`);}function hn(e,t,r,s){if(Ke(e)){let n=Object.keys(e);n.length>1&&me(`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 i of n)if(!Ce(i,t,e[i],r))return false;return true}return N(e)?te(e,N(t)?t:Object.create(null),N(r)?r:void 0,s+1):I(t,e)}function te(e,t,r,s=0){if(s>B)return me(`predicate depth limit (${B}) 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(!N(n))return false;let{fact:i,op:o,value:l}=n;return Ce(o,t?.[i],l,r?.[i])});if(!N(e))return !!e;if("$all"in e)return e.$all.every(n=>te(n,t,r,s+1));if("$any"in e)return e.$any.some(n=>te(n,t,r,s+1));if("$not"in e)return !te(e.$not,t,r,s+1);for(let n of Object.keys(e)){if(K.has(n))return me(`predicate: operator "${n}" mixed with fact keys \u2014 wrap operators in a per-fact object`),false;if(!hn(e[n],t?.[n],r?.[n],s))return false}return true}function he(e,t,r,s=""){let n=[];if(Array.isArray(e)){for(let i of e){if(!N(i))continue;let{fact:o,op:l,value:a}=i,c=t?.[o];n.push({path:s+o,op:l,expected:a,actual:c,pass:Ce(l,c,a,r?.[o])});}return n}if(!N(e))return n;for(let i of ["$all","$any","$not"])if(i in e){let o=i==="$not"?[e.$not]:e[i],l=[];for(let u of o)l.push(...he(u,t,r,s));let a=l.filter(u=>u.pass).length,c;return i==="$all"?c=l.length===0||a===l.length:i==="$any"?c=l.length>0&&a>0:c=!l.every(u=>u.pass),n.push({path:s||i,op:i,expected:o.length,actual:a,pass:c,children:l}),n}for(let i of Object.keys(e)){if(K.has(i))continue;let o=e[i],l=t?.[i],a=s+i;if(Ke(o))for(let c of Object.keys(o))n.push({path:a,op:c,expected:o[c],actual:l,pass:Ce(c,l,o[c],r?.[i])});else N(o)?n.push(...he(o,N(l)?l:Object.create(null),N(r?.[i])?r?.[i]:void 0,`${a}.`)):n.push({path:a,op:"$eq",expected:o,actual:l,pass:I(l,o)});}return n}var le=1e6;function Nt(e,t){try{It(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(!Pt(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(pe(e,{operator(s,n){r===void 0&&n.startsWith("$")&&!K.has(n)&&(r=n);},strayOperatorKey(s){r===void 0&&!K.has(s)&&!qt.has(s)&&(r=s);}}),r!==void 0)throw new Error(`[Directive] replayUnder: the ${t} predicate uses an unknown operator "${r}" \u2014 known operators: ${[...K].join(", ")}`)}function ge(e){if(e&&typeof e=="object"&&!Array.isArray(e)&&Array.isArray(e.snapshots))return gn(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>le)throw new Error(`[Directive] toReplayFrames: history has ${t.length} frames, exceeds the MAX_REPLAY_FRAMES limit (${le}) \u2014 split or down-sample the history`);return t.map((r,s)=>{if(r&&typeof r=="object"&&"facts"in r){let n=r,i={id:n.id??`#${s}`,facts:n.facts??{}};return typeof n.timestamp=="number"&&(i.timestamp=n.timestamp),i}return {id:`#${s}`,facts:r??{}}})}function gn(e){let t=typeof e=="string"?JSON.parse(e):e;if(Array.isArray(t))return Ft(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 Ft(r.snapshots)}function Ft(e){if(!Array.isArray(e))throw new Error("[Directive] framesFromSnapshots: expected an array of fact-state snapshots");if(e.length>le)throw new Error(`[Directive] framesFromSnapshots: history has ${e.length} snapshots, exceeds the MAX_REPLAY_FRAMES limit (${le}) \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 ge(e)}function Oe(e){let{frames:t,original:r,proposed:s,entityKey:n}=e,i=e.maxSamples??20,o=i>0?i:0;if(t.length>le)throw new Error(`[Directive] replayUnder: history has ${t.length} frames, exceeds the MAX_REPLAY_FRAMES limit (${le}) \u2014 split or down-sample the history`);Nt(r,"original"),Nt(s,"proposed");let l=0,a=0,c=0,u=0,f=0,d=[],m=[],v=n?new Set:void 0,$=n?new Set:void 0,F;for(let p of t){let y=p.facts,R=te(r,y,F),_=te(s,y,F);R&&(l++,v?.add(y[n])),_&&(a++,$?.add(y[n])),R===_?f++:!R&&_?(c++,d.length<o&&d.push(zt(p,r,s,F))):(u++,m.length<o&&m.push(zt(p,r,s,F))),F=y;}let z={framesEvaluated:t.length,original:{matched:l},proposed:{matched:a},delta:a-l,newMatchCount:c,lostMatchCount:u,unchanged:f,newMatches:d,lostMatches:m};return v&&$&&(z.original.matchedEntities=v.size,z.proposed.matchedEntities=$.size),z}function zt(e,t,r,s){let n=e.facts,i={frameId:e.id,facts:n,originalExplain:he(t,n,s),proposedExplain:he(r,n,s)};return e.timestamp!==void 0&&(i.timestamp=e.timestamp),i}var _t=1e4,Wt=5e7;function yn(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===1&&typeof e.$hole=="string"}function Be(e,t,r=new Set,s=0){if(s>B)throw new Error(`[Directive] sweepUnder: template exceeds MAX_PREDICATE_DEPTH (${B}) \u2014 flatten the template or split the sweep`);if(yn(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(i=>Be(i,t,r,s+1));let n={};for(let[i,o]of Object.entries(e))n[i]=Be(o,t,r,s+1);return n}finally{r.delete(e);}}function*Lt(e,t){if(e.length===0){yield {};return}let r=e[0],s=e.slice(1),n=t[r]??[];for(let i of n)for(let o of Lt(s,t))yield {[r]:i,...o};}function vn(e){let t=1;for(let r of Object.values(e))t*=r.length;return t}function Kt(e){let{frames:t,original:r,template:s,sweep:n,objective:i=y=>y.proposed.matched,entityKey:o,maxSamples:l=0}=e,a=Object.keys(n);if(a.length===0)throw new Error("[Directive] sweepUnder: `sweep` must contain at least one hole name");let c=vn(n);if(c>_t)throw new Error(`[Directive] sweepUnder: grid has ${c} points, exceeds the MAX_SWEEP_POINTS limit (${_t}) \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 u=c*t.length;if(u>Wt)throw new Error(`[Directive] sweepUnder: ${c} points \xD7 ${t.length} frames = ${u} per-frame evaluations, exceeds the MAX_SWEEP_EVALUATIONS limit (${Wt}) \u2014 narrow the sweep, down-sample the history, or split the run`);let f=false,d=y=>{let R;try{R=i(y);}catch(_){return f||(f=true,console.warn(`[Directive] sweepUnder: objective threw \u2014 point will not rank (${_.message})`)),Number.NEGATIVE_INFINITY}return typeof R!="number"||!Number.isFinite(R)?(f||(f=true,console.warn(`[Directive] sweepUnder: objective returned a non-finite number (${String(R)}) \u2014 point will not rank`)),Number.NEGATIVE_INFINITY):R},m=Oe({frames:t,original:r,proposed:r,entityKey:o,maxSamples:l}),v={values:{},report:m,score:d(m)},$=[],F=0,z=Number.NEGATIVE_INFINITY;for(let y of Lt(a,n)){let R=Be(s,y),_=Oe({frames:t,original:r,proposed:R,entityKey:o,maxSamples:l}),Te=d(_);Te>z&&(z=Te,F=$.length),$.push({values:y,report:_,score:Te});}let p=$[F];return {points:$,bestIndex:F,best:p,baseline:v}}function Ut(e){let t=e&&typeof e=="object"&&!Array.isArray(e)&&"constraints"in e?e.constraints:e;if(Array.isArray(t)){let r={};for(let s of t){if(!s||typeof s!="object"||!("id"in s))throw new Error("[Directive] diffRules: array entries must be `{ id, whenSpec }` objects");let n=s;if(typeof n.id!="string")throw new Error("[Directive] diffRules: constraint `id` must be a string");r[n.id]=n.whenSpec;}return r}if(t&&typeof t=="object")return t;throw new Error("[Directive] diffRules: expected a `{ id: whenSpec }` map, an array of `{ id, whenSpec }`, or `{ constraints: ... }`")}var wn=new Set(["$eq","$ne","$in","$nin","$exists","$gt","$gte","$lt","$lte","$between","$matches","$startsWith","$endsWith","$contains","$changed"]),$n=new Set(["$all","$any","$not"]);function Bt(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function bn(e){if(!Bt(e))return false;let t=Object.keys(e);if(t.length===0)return false;let r=false;for(let s of t){if(!s.startsWith("$"))return false;wn.has(s)&&(r=true);}return r}function G(e,t="",r=[]){if(e===null||typeof e!="object")return r;if(Array.isArray(e)){for(let s of e)if(s&&typeof s=="object"&&"fact"in s&&"op"in s){let n=s;r.push({path:t?`${t}.${String(n.fact)}`:String(n.fact),op:String(n.op),value:n.value});}return r}if("$all"in e&&Array.isArray(e.$all))return e.$all.forEach((s,n)=>{G(s,`${t}$all[${n}]`,r);}),r;if("$any"in e&&Array.isArray(e.$any))return e.$any.forEach((s,n)=>{G(s,`${t}$any[${n}]`,r);}),r;if("$not"in e)return G(e.$not,`${t}$not`,r),r;for(let[s,n]of Object.entries(e)){let i=t?`${t}.${s}`:s;if(bn(n))for(let[o,l]of Object.entries(n))r.push({path:i,op:o,value:l});else Bt(n)&&!$n.has(s)?G(n,i,r):r.push({path:i,op:"$eq",value:n});}return r}function J(e){return typeof e=="number"&&Number.isFinite(e)}function Sn(e,t,r){switch(e){case "$gte":case "$gt":if(J(t)&&J(r)){if(r<t)return "relaxed";if(r>t)return "tightened"}return null;case "$lte":case "$lt":if(J(t)&&J(r)){if(r>t)return "relaxed";if(r<t)return "tightened"}return null;case "$between":{if(Array.isArray(t)&&Array.isArray(r)&&t.length===2&&r.length===2&&J(t[0])&&J(t[1])&&J(r[0])&&J(r[1])){let s=t[1]-t[0],n=r[1]-r[0];if(n>s)return "relaxed";if(n<s)return "tightened"}return null}case "$in":case "$nin":{if(Array.isArray(t)&&Array.isArray(r))if(e==="$in"){if(r.length>t.length)return "relaxed";if(r.length<t.length)return "tightened"}else {if(r.length>t.length)return "tightened";if(r.length<t.length)return "relaxed"}return null}case "$contains":{if(Array.isArray(t)&&Array.isArray(r)){if(r.length>t.length)return "relaxed";if(r.length<t.length)return "tightened"}return null}default:return null}}function Jt(e){let t=Ut(e.before),r=Ut(e.after),s=[...new Set([...Object.keys(t),...Object.keys(r)])].sort(),n=[],i={added:0,removed:0,changed:0,unchanged:0,totalClauseChanges:0};for(let o of s){let l=t[o],a=r[o],c=o in t,u=o in r;if(c&&!u){let d=G(l),m=d.length===0?[{path:"(function-form predicate)",kind:"removed"}]:d.map(v=>({path:v.path,kind:"removed",before:{op:v.op,value:v.value}}));Je(m),n.push({id:o,status:"removed",changes:m}),i.removed++,i.totalClauseChanges+=m.length;continue}if(!c&&u){let d=G(a),m=d.length===0?[{path:"(function-form predicate)",kind:"added"}]:d.map(v=>({path:v.path,kind:"added",after:{op:v.op,value:v.value}}));Je(m),n.push({id:o,status:"added",changes:m}),i.added++,i.totalClauseChanges+=m.length;continue}let f=xn(l,a);f.length===0?(n.push({id:o,status:"unchanged",changes:[]}),i.unchanged++):(n.push({id:o,status:"changed",changes:f}),i.changed++,i.totalClauseChanges+=f.length);}return {constraints:n,summary:i}}function xn(e,t){if(e!==void 0&&t!==void 0&&(e===null||t===null||typeof e!="object"||typeof t!="object"))return de(e)===de(t)?[]:[{path:"",kind:"changed",before:{op:"$eq",value:e},after:{op:"$eq",value:t}}];let r=e===void 0?[]:G(e),s=t===void 0?[]:G(t),n=c=>`${c.path}::${c.op}`,i=new Map(r.map(c=>[n(c),c])),o=new Map(s.map(c=>[n(c),c])),l=new Set([...i.keys(),...o.keys()]),a=[];for(let c of l){let u=i.get(c),f=o.get(c);if(u&&!f){a.push({path:u.path,kind:"removed",before:{op:u.op,value:u.value}});continue}if(!u&&f){a.push({path:f.path,kind:"added",after:{op:f.op,value:f.value}});continue}if(u&&f){if(de(u.value)===de(f.value))continue;let d=Sn(u.op,u.value,f.value);a.push({path:u.path,kind:d??"changed",before:{op:u.op,value:u.value},after:{op:f.op,value:f.value}});}}return Je(a),a}function Je(e){e.sort((t,r)=>{let s=t.path.localeCompare(r.path);if(s!==0)return s;let n=t.before?.op??t.after?.op??"",i=r.before?.op??r.after?.op??"";return n.localeCompare(i)});}function jn(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],i=n?Number.parseInt(n,10):Number.NaN;Number.isFinite(i)&&i>=0&&(t.maxSamples=i);break}case "--entity-key":{let n=e[++r];n&&(t.entityKey=n);break}case "--json":t.json=true;break}return t}function Me(){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 Ge(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 jn(e){try{return ge(e)}catch(t){console.error(g.red(`error: ${t.message}`)),process.exit(1);}}function Gt(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===0}function Ht(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 An(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 Ge(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 An(e){try{return ge(e)}catch(t){console.error(g.red(`error: ${t.message}`)),process.exit(1);}}function Gt(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===0}function Ht(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 Rn(e,t){let{original:r,proposed:s,delta:n}=e,i=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
- `),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(`
940
+ `),console.log(` frames evaluated ${e.framesEvaluated}`),console.log(` original spec matched ${r.matched} frames`),console.log(` proposed spec matched ${s.matched} frames (${i})`),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
942
  ${g.green("sample new matches:")}`);for(let a of e.newMatches.slice(0,8))console.log(` frame ${a.frameId} ${g.dim(Ht(a.facts))}`);}if(e.lostMatches.length>0){console.log(`
943
- ${g.red("sample lost matches:")}`);for(let a of e.lostMatches.slice(0,8))console.log(` frame ${a.frameId} ${g.dim(Ht(a.facts))}`);}let i=e.newMatches.length+e.lostMatches.length,l=e.newMatchCount+e.lostMatchCount;i<l&&console.log(g.dim(`
944
- ${i} of ${l} diff frames sampled \u2014 --json for the full report`)),console.log("");}async function Vt(e){(e.includes("--help")||e.length===0)&&(Me(),process.exit(e.length===0?1:0));let t=Rn(e);t.historyPath||(console.error(g.red("error: --history <frames.json> is required")),Me(),process.exit(1)),t.proposedPath||(console.error(g.red("error: --proposed <spec.json> is required")),Me(),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)")),Me(),process.exit(1));let r=jn(Ge(t.historyPath,"--history")),s=Ge(t.originalPath,"--original"),n=Ge(t.proposedPath,"--proposed");Gt(s)&&console.error(g.yellow("warning: --original is an empty predicate {} \u2014 it matches every frame")),Gt(n)&&console.error(g.yellow("warning: --proposed is an empty predicate {} \u2014 it matches every frame"));let o;try{o=Oe({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}An(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 He(){console.error(`
943
+ ${g.red("sample lost matches:")}`);for(let a of e.lostMatches.slice(0,8))console.log(` frame ${a.frameId} ${g.dim(Ht(a.facts))}`);}let o=e.newMatches.length+e.lostMatches.length,l=e.newMatchCount+e.lostMatchCount;o<l&&console.log(g.dim(`
944
+ ${o} of ${l} diff frames sampled \u2014 --json for the full report`)),console.log("");}async function Vt(e){(e.includes("--help")||e.length===0)&&(Me(),process.exit(e.length===0?1:0));let t=jn(e);t.historyPath||(console.error(g.red("error: --history <frames.json> is required")),Me(),process.exit(1)),t.proposedPath||(console.error(g.red("error: --proposed <spec.json> is required")),Me(),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)")),Me(),process.exit(1));let r=An(Ge(t.historyPath,"--history")),s=Ge(t.originalPath,"--original"),n=Ge(t.proposedPath,"--proposed");Gt(s)&&console.error(g.yellow("warning: --original is an empty predicate {} \u2014 it matches every frame")),Gt(n)&&console.error(g.yellow("warning: --proposed is an empty predicate {} \u2014 it matches every frame"));let i;try{i=Oe({frames:r,original:s,proposed:n,maxSamples:t.maxSamples,entityKey:t.entityKey});}catch(o){console.error(g.red(`error: ${o.message}`)),process.exit(1);}if(t.json){console.log(JSON.stringify(i,null,2));return}Rn(i,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 i=e[++s];i&&(t.systemPath=i);break}case "--max-frames":{let i=e[++s],o=i?Number.parseInt(i,10):Number.NaN;Number.isFinite(o)&&o>0&&(t.maxFrames=o);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 He(){console.error(`
945
945
  Usage: directive replay <timeline.json> [options]
946
946
 
947
947
  Replay a serialized Directive timeline against a fresh system.
@@ -964,7 +964,7 @@ Examples:
964
964
  directive replay error.json --system src/system.ts --json
965
965
  directive replay error.json --system src/system.ts --verbose
966
966
  `);}async function Yt(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(He(),process.exit(e.length===0?1:0));let{jsonPath:t,opts:r}=Tn(e);t||(console.error(g.red("error: missing <timeline.json> argument")),He(),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)`)),He(),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(d){console.error(g.red(`error: failed to read ${s}: ${d.message}`)),process.exit(1);}let o;try{o=JSON.parse(n);}catch(d){console.error(g.red(`error: ${s} is not valid JSON: ${d.message}`)),process.exit(1);}let{deserializeTimeline:i,replayTimeline:l}=await oe(r.verbose),a;try{a=i(o);}catch(d){console.error(g.red(`error: timeline JSON failed validation: ${d.message}`)),process.exit(1);}let c;try{c=await W(r.systemPath);}catch(d){console.error(g.red(`error: failed to load system file: ${d.message}`)),process.exit(1);}let u=c;if(typeof u.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 u.start=="function")try{u.start();}catch{}let f=await l(a,u,{dispatchableOnly:r.dispatchableOnly,maxFrames:r.maxFrames});if(r.json)console.log(JSON.stringify(f,null,2));else {let{dispatched:d,skipped:m,truncated:v}=f,b=d>0;console.log(`${b?g.green("\u2713"):g.yellow("\u26A0")} replay complete:`,g.bold(`${d} dispatched`),g.dim(`/ ${m} skipped`),v>0?g.yellow(`/ ${v} TRUNCATED`):""),d===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.")),v>0&&console.error(g.yellow(`warning: ${v} frames truncated by --max-frames cap. Raise it with --max-frames <n> if you need them.`));}process.exit(0);}function Nn(e){let t={json:false,markdown:false};for(let r=0;r<e.length;r++)switch(e[r]){case "--before":case "-b":{let n=e[++r];n&&(t.beforePath=n);break}case "--after":case "-a":{let n=e[++r];n&&(t.afterPath=n);break}case "--json":t.json=true;break;case "--markdown":case "--md":t.markdown=true;break}return t}function Ve(){console.error(`
967
+ (replay needs a fresh system to dispatch against)`)),He(),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(d){console.error(g.red(`error: failed to read ${s}: ${d.message}`)),process.exit(1);}let i;try{i=JSON.parse(n);}catch(d){console.error(g.red(`error: ${s} is not valid JSON: ${d.message}`)),process.exit(1);}let{deserializeTimeline:o,replayTimeline:l}=await ie(r.verbose),a;try{a=o(i);}catch(d){console.error(g.red(`error: timeline JSON failed validation: ${d.message}`)),process.exit(1);}let c;try{c=await U(r.systemPath);}catch(d){console.error(g.red(`error: failed to load system file: ${d.message}`)),process.exit(1);}let u=c;if(typeof u.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 u.start=="function")try{u.start();}catch{}let f=await l(a,u,{dispatchableOnly:r.dispatchableOnly,maxFrames:r.maxFrames});if(r.json)console.log(JSON.stringify(f,null,2));else {let{dispatched:d,skipped:m,truncated:v}=f,$=d>0;console.log(`${$?g.green("\u2713"):g.yellow("\u26A0")} replay complete:`,g.bold(`${d} dispatched`),g.dim(`/ ${m} skipped`),v>0?g.yellow(`/ ${v} TRUNCATED`):""),d===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.")),v>0&&console.error(g.yellow(`warning: ${v} frames truncated by --max-frames cap. Raise it with --max-frames <n> if you need them.`));}process.exit(0);}function Nn(e){let t={json:false,markdown:false};for(let r=0;r<e.length;r++)switch(e[r]){case "--before":case "-b":{let n=e[++r];n&&(t.beforePath=n);break}case "--after":case "-a":{let n=e[++r];n&&(t.afterPath=n);break}case "--json":t.json=true;break;case "--markdown":case "--md":t.markdown=true;break}return t}function Ve(){console.error(`
968
968
  Usage: directive rules-diff --before <a.json> --after <b.json>
969
969
 
970
970
  Structural diff between two snapshots of constraint whenSpec. Reports
@@ -990,10 +990,10 @@ Or pull one from a git ref:
990
990
  git show HEAD~1:path/to/snapshot.json > before.json
991
991
  git show HEAD:path/to/snapshot.json > after.json
992
992
  directive rules-diff --before before.json --after after.json
993
- `);}function Xt(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 Fn(e){switch(e){case "added":return g.green("+");case "removed":return g.red("-");case "relaxed":return g.green("\u25B2");case "tightened":return g.red("\u25BD");default:return g.yellow("~")}}function H(e){return e?e.op==="$eq"?JSON.stringify(e.value):`${e.op} ${JSON.stringify(e.value)}`:"\u2014"}function ye(e){return e.replace(/\|/g,"\\|").replace(/`/g,"'").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function _n(e){let{summary:t,constraints:r}=e;console.log(`
993
+ `);}function Xt(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 Fn(e){switch(e){case "added":return g.green("+");case "removed":return g.red("-");case "relaxed":return g.green("\u25B2");case "tightened":return g.red("\u25BD");default:return g.yellow("~")}}function H(e){return e?e.op==="$eq"?JSON.stringify(e.value):`${e.op} ${JSON.stringify(e.value)}`:"\u2014"}function ye(e){return e.replace(/\|/g,"\\|").replace(/`/g,"'").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function zn(e){let{summary:t,constraints:r}=e;console.log(`
994
994
  ${g.bold("rules-diff")} \u2014 structural predicate diff
995
995
  `),console.log(` ${g.green(`+${t.added}`)} added ${g.red(`-${t.removed}`)} removed ${g.yellow(`~${t.changed}`)} changed ${g.dim(`\xB7${t.unchanged} unchanged`)}`),console.log(` ${t.totalClauseChanges} clause-level change${t.totalClauseChanges===1?"":"s"}
996
- `);for(let s of r){if(s.status==="unchanged")continue;let n=s.status==="added"?g.green("ADDED"):s.status==="removed"?g.red("REMOVED"):g.yellow("CHANGED");console.log(` ${g.bold(s.id)} ${n}`);for(let o of s.changes){let i=g.cyan(o.path||"(predicate)"),l=Fn(o.kind);if(o.kind==="added")console.log(` ${l} ${i} ${H(o.after)}`);else if(o.kind==="removed")console.log(` ${l} ${i} ${H(o.before)}`);else {let a=o.kind==="relaxed"?g.green("relaxed"):o.kind==="tightened"?g.red("tightened"):g.yellow("changed");console.log(` ${l} ${i} ${H(o.before)} ${g.dim("\u2192")} ${H(o.after)} ${g.dim(`[${a}]`)}`);}}console.log("");}}function zn(e){let{summary:t,constraints:r}=e;console.log("## \u{1F4CB} Rules diff"),console.log(""),console.log(`**+${t.added} added \xB7 -${t.removed} removed \xB7 ~${t.changed} changed \xB7 \xB7${t.unchanged} unchanged** \u2014 ${t.totalClauseChanges} clause change${t.totalClauseChanges===1?"":"s"}`),console.log("");for(let s of r){if(s.status==="unchanged")continue;let n=s.status==="added"?"\u{1F195} ADDED":s.status==="removed"?"\u{1F5D1} REMOVED":"\u270F\uFE0F CHANGED";console.log(`### \`${s.id}\` \u2014 ${n}`),console.log(""),console.log("| | path | change |"),console.log("|---|---|---|");for(let o of s.changes){let i=`\`${ye(o.path||"(predicate)")}\``,l;o.kind==="added"?l=`| \u2795 | ${i} | ${ye(H(o.after))} |`:o.kind==="removed"?l=`| \u2796 | ${i} | ${ye(H(o.before))} |`:l=`| ${o.kind==="relaxed"?"\u25B2 relaxed":o.kind==="tightened"?"\u25BD tightened":"\u2194 changed"} | ${i} | ${ye(H(o.before))} \u2192 ${ye(H(o.after))} |`,console.log(l);}console.log("");}}async function Qt(e){(e.includes("--help")||e.length===0)&&(Ve(),process.exit(e.length===0?1:0));let t=Nn(e);t.beforePath||(console.error(g.red("error: --before <a.json> is required")),Ve(),process.exit(1)),t.afterPath||(console.error(g.red("error: --after <b.json> is required")),Ve(),process.exit(1));let r=Xt(t.beforePath,"--before"),s=Xt(t.afterPath,"--after"),n;try{n=Jt({before:r,after:s});}catch(o){console.error(g.red(`error: ${o.message}`)),process.exit(1);}if(t.json){console.log(JSON.stringify(n,null,2));return}if(t.markdown){zn(n);return}_n(n);}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 Zt(){console.error(`
996
+ `);for(let s of r){if(s.status==="unchanged")continue;let n=s.status==="added"?g.green("ADDED"):s.status==="removed"?g.red("REMOVED"):g.yellow("CHANGED");console.log(` ${g.bold(s.id)} ${n}`);for(let i of s.changes){let o=g.cyan(i.path||"(predicate)"),l=Fn(i.kind);if(i.kind==="added")console.log(` ${l} ${o} ${H(i.after)}`);else if(i.kind==="removed")console.log(` ${l} ${o} ${H(i.before)}`);else {let a=i.kind==="relaxed"?g.green("relaxed"):i.kind==="tightened"?g.red("tightened"):g.yellow("changed");console.log(` ${l} ${o} ${H(i.before)} ${g.dim("\u2192")} ${H(i.after)} ${g.dim(`[${a}]`)}`);}}console.log("");}}function _n(e){let{summary:t,constraints:r}=e;console.log("## \u{1F4CB} Rules diff"),console.log(""),console.log(`**+${t.added} added \xB7 -${t.removed} removed \xB7 ~${t.changed} changed \xB7 \xB7${t.unchanged} unchanged** \u2014 ${t.totalClauseChanges} clause change${t.totalClauseChanges===1?"":"s"}`),console.log("");for(let s of r){if(s.status==="unchanged")continue;let n=s.status==="added"?"\u{1F195} ADDED":s.status==="removed"?"\u{1F5D1} REMOVED":"\u270F\uFE0F CHANGED";console.log(`### \`${s.id}\` \u2014 ${n}`),console.log(""),console.log("| | path | change |"),console.log("|---|---|---|");for(let i of s.changes){let o=`\`${ye(i.path||"(predicate)")}\``,l;i.kind==="added"?l=`| \u2795 | ${o} | ${ye(H(i.after))} |`:i.kind==="removed"?l=`| \u2796 | ${o} | ${ye(H(i.before))} |`:l=`| ${i.kind==="relaxed"?"\u25B2 relaxed":i.kind==="tightened"?"\u25BD tightened":"\u2194 changed"} | ${o} | ${ye(H(i.before))} \u2192 ${ye(H(i.after))} |`,console.log(l);}console.log("");}}async function Qt(e){(e.includes("--help")||e.length===0)&&(Ve(),process.exit(e.length===0?1:0));let t=Nn(e);t.beforePath||(console.error(g.red("error: --before <a.json> is required")),Ve(),process.exit(1)),t.afterPath||(console.error(g.red("error: --after <b.json> is required")),Ve(),process.exit(1));let r=Xt(t.beforePath,"--before"),s=Xt(t.afterPath,"--after"),n;try{n=Jt({before:r,after:s});}catch(i){console.error(g.red(`error: ${i.message}`)),process.exit(1);}if(t.json){console.log(JSON.stringify(n,null,2));return}if(t.markdown){_n(n);return}zn(n);}function Kn(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 Zt(){console.error(`
997
997
  Usage: directive timeline diff <a.json> <b.json>
998
998
 
999
999
  Compare two serialized Directive timelines as a structured causal-graph
@@ -1017,7 +1017,7 @@ Exit codes:
1017
1017
  Examples:
1018
1018
  directive timeline diff baseline.json regression.json
1019
1019
  directive timeline diff a.json b.json --json | jq .constraintFires
1020
- `);}function ve(e){return e>0?g.green(`+${e}`):e<0?g.red(`${e}`):g.dim(" 0")}function er(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)} (${ve(t.delta)})`)}function Kn(e){return e.length===0?[g.dim(" (no differences)")]:e.map(t=>` ${g.bold(t.resolver.padEnd(28))} starts ${t.aStarts}\u2192${t.bStarts} (${ve(t.bStarts-t.aStarts)}) completes ${t.aCompletes}\u2192${t.bCompletes} (${ve(t.bCompletes-t.aCompletes)}) errors ${t.aErrors}\u2192${t.bErrors} (${ve(t.bErrors-t.aErrors)})`)}function Jn(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 tr(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 rr(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(Zt(),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")),Zt(),process.exit(1));let{deserializeTimeline:n,diffTimelines:o}=await oe(s.verbose),i=tr(t),l=tr(r),a,c;try{a=n(i),c=n(l);}catch(f){console.error(g.red(`error: timeline JSON failed validation: ${f.message}`)),process.exit(1);}let u=o(a,c);s.json&&(console.log(JSON.stringify(u,null,2)),process.exit(u.identical?0:2)),u.identical&&(console.log(g.green("\u2713 identical:"),`both timelines have ${u.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: ${u.aFrameCount} \u2192 ${u.bFrameCount} (${ve(u.frameCountDelta)})`),console.log(""),console.log(g.bold("Constraint fires:"));for(let f of er(u.constraintFires))console.log(f);console.log(""),console.log(g.bold("Mutations:"));for(let f of er(u.mutations))console.log(f);console.log(""),console.log(g.bold("Resolver runs:"));for(let f of Kn(u.resolverRuns))console.log(f);console.log(""),console.log(g.bold("New errors:"));for(let f of Jn(u.newErrors))console.log(f);console.log(""),process.exit(2);}function Yn(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 we(){console.error(`
1020
+ `);}function ve(e){return e>0?g.green(`+${e}`):e<0?g.red(`${e}`):g.dim(" 0")}function er(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)} (${ve(t.delta)})`)}function Bn(e){return e.length===0?[g.dim(" (no differences)")]:e.map(t=>` ${g.bold(t.resolver.padEnd(28))} starts ${t.aStarts}\u2192${t.bStarts} (${ve(t.bStarts-t.aStarts)}) completes ${t.aCompletes}\u2192${t.bCompletes} (${ve(t.bCompletes-t.aCompletes)}) errors ${t.aErrors}\u2192${t.bErrors} (${ve(t.bErrors-t.aErrors)})`)}function Jn(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 tr(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 rr(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(Zt(),process.exit(e.length===0?1:0));let{aPath:t,bPath:r,opts:s}=Kn(e);(!t||!r)&&(console.error(g.red("error: both <a.json> and <b.json> are required")),Zt(),process.exit(1));let{deserializeTimeline:n,diffTimelines:i}=await ie(s.verbose),o=tr(t),l=tr(r),a,c;try{a=n(o),c=n(l);}catch(f){console.error(g.red(`error: timeline JSON failed validation: ${f.message}`)),process.exit(1);}let u=i(a,c);s.json&&(console.log(JSON.stringify(u,null,2)),process.exit(u.identical?0:2)),u.identical&&(console.log(g.green("\u2713 identical:"),`both timelines have ${u.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: ${u.aFrameCount} \u2192 ${u.bFrameCount} (${ve(u.frameCountDelta)})`),console.log(""),console.log(g.bold("Constraint fires:"));for(let f of er(u.constraintFires))console.log(f);console.log(""),console.log(g.bold("Mutations:"));for(let f of er(u.mutations))console.log(f);console.log(""),console.log(g.bold("Resolver runs:"));for(let f of Bn(u.resolverRuns))console.log(f);console.log(""),console.log(g.bold("New errors:"));for(let f of Jn(u.newErrors))console.log(f);console.log(""),process.exit(2);}function Yn(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 we(){console.error(`
1021
1021
  Usage: directive tune --history <frames.json> --original <orig.json> \\
1022
1022
  --template <tmpl.json> --sweep <key:range>
1023
1023
 
@@ -1040,16 +1040,16 @@ Example:
1040
1040
  directive tune --history sessions.json \\
1041
1041
  --original current.json --template proposed-template.json \\
1042
1042
  --sweep threshold:25..200:25
1043
- `);}function Ye(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 Xn(e){try{return ge(e)}catch(t){console.error(g.red(`error: ${t.message}`)),process.exit(1);}}function Qn(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[,l,a,c]=n,u=Number(l),f=Number(a),d=c?Number(c):1;d<=0&&(console.error(g.red(`error: --sweep ${e}: step must be positive`)),process.exit(1)),f<u&&(console.error(g.red(`error: --sweep ${e}: end (${f}) must be >= start (${u})`)),process.exit(1));let m=[];for(let v=u;v<=f+1e-9;v+=d)m.push(Math.round(v*1e6)/1e6);return [r,m]}let o=s.split(",").map(l=>l.trim()).filter(l=>l.length>0);o.length===0&&(console.error(g.red(`error: --sweep ${e}: no values after ':'`)),process.exit(1));let i=o.map(l=>{let a=Number(l);return Number.isNaN(a)?l:a});return [r,i]}var Xe=["\u2581","\u2582","\u2583","\u2584","\u2585","\u2586","\u2587","\u2588"];function Zn(e,t){let r=e.points;Math.max(...r.map(d=>d.report.proposed.matched));let n=e.baseline.report.original.matched,o=r.map(d=>d.score),i=Math.min(...o),a=Math.max(...o)-i,c=r.map(d=>{let m=a>0?(d.score-i)/a:0;return Xe[Math.min(Xe.length-1,Math.round(m*(Xe.length-1)))]}).join("");console.log(`
1043
+ `);}function Ye(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 Xn(e){try{return ge(e)}catch(t){console.error(g.red(`error: ${t.message}`)),process.exit(1);}}function Qn(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[,l,a,c]=n,u=Number(l),f=Number(a),d=c?Number(c):1;d<=0&&(console.error(g.red(`error: --sweep ${e}: step must be positive`)),process.exit(1)),f<u&&(console.error(g.red(`error: --sweep ${e}: end (${f}) must be >= start (${u})`)),process.exit(1));let m=[];for(let v=u;v<=f+1e-9;v+=d)m.push(Math.round(v*1e6)/1e6);return [r,m]}let i=s.split(",").map(l=>l.trim()).filter(l=>l.length>0);i.length===0&&(console.error(g.red(`error: --sweep ${e}: no values after ':'`)),process.exit(1));let o=i.map(l=>{let a=Number(l);return Number.isNaN(a)?l:a});return [r,o]}var Xe=["\u2581","\u2582","\u2583","\u2584","\u2585","\u2586","\u2587","\u2588"];function Zn(e,t){let r=e.points;Math.max(...r.map(d=>d.report.proposed.matched));let n=e.baseline.report.original.matched,i=r.map(d=>d.score),o=Math.min(...i),a=Math.max(...i)-o,c=r.map(d=>{let m=a>0?(d.score-o)/a:0;return Xe[Math.min(Xe.length-1,Math.round(m*(Xe.length-1)))]}).join("");console.log(`
1044
1044
  ${g.bold("directive tune")} \u2014 parameter sweep`),console.log(`
1045
1045
  frames evaluated ${r[0]?.report.framesEvaluated??0}`),console.log(` baseline (current) matched ${n} frames`),console.log(` points evaluated ${r.length}
1046
1046
  `),console.log(` sparkline ${g.cyan(c)}
1047
- `);let u=Object.keys(r[0]?.values??{}),f=u.map(d=>d.padEnd(12)).join(" ")+" "+"matched".padStart(8)+" "+"delta".padStart(7)+(t?" "+`${t}s`.padStart(8):"")+" bar";console.log(g.dim(" "+f));for(let d of r){let m=u.map(z=>String(d.values[z]??"").padEnd(12)).join(" "),v=d.report.proposed.matched,b=d.report.delta,F=t?String(d.report.proposed.matchedEntities??"").padStart(8):"",_=b>0?g.green(`+${b}`.padStart(7)):b<0?g.red(`${b}`.padStart(7)):g.dim("\xB10".padStart(7)),p=a>0?Math.round((d.score-i)/a*24):0,y=m+" "+String(v).padStart(8)+" "+_+(t?" "+F:"")+" "+"\u2588".repeat(p).padEnd(24),A=d===e.best;console.log(A?g.green(" "+y):" "+y);}console.log(`
1047
+ `);let u=Object.keys(r[0]?.values??{}),f=u.map(d=>d.padEnd(12)).join(" ")+" "+"matched".padStart(8)+" "+"delta".padStart(7)+(t?" "+`${t}s`.padStart(8):"")+" bar";console.log(g.dim(" "+f));for(let d of r){let m=u.map(_=>String(d.values[_]??"").padEnd(12)).join(" "),v=d.report.proposed.matched,$=d.report.delta,F=t?String(d.report.proposed.matchedEntities??"").padStart(8):"",z=$>0?g.green(`+${$}`.padStart(7)):$<0?g.red(`${$}`.padStart(7)):g.dim("\xB10".padStart(7)),p=a>0?Math.round((d.score-o)/a*24):0,y=m+" "+String(v).padStart(8)+" "+z+(t?" "+F:"")+" "+"\u2588".repeat(p).padEnd(24),R=d===e.best;console.log(R?g.green(" "+y):" "+y);}console.log(`
1048
1048
  ${g.bold(g.green("best"))} \u2014 ${u.map(d=>`${d}=${e.best.values[d]}`).join(", ")} \u2192 matched ${e.best.report.proposed.matched} (score ${e.best.score})
1049
- `);}async function nr(e){(e.includes("--help")||e.length===0)&&(we(),process.exit(e.length===0?1:0));let t=Yn(e);t.historyPath||(console.error(g.red("error: --history <frames.json> is required")),we(),process.exit(1)),t.originalPath||(console.error(g.red("error: --original <spec.json> is required")),we(),process.exit(1)),t.templatePath||(console.error(g.red("error: --template <spec.json> is required")),we(),process.exit(1)),t.sweepArgs.length===0&&(console.error(g.red("error: at least one --sweep <key:range> is required")),we(),process.exit(1));let r=Xn(Ye(t.historyPath,"--history")),s=Ye(t.originalPath,"--original"),n=Ye(t.templatePath,"--template"),o={};for(let l of t.sweepArgs){let[a,c]=Qn(l);o[a]=c;}let i;try{i=Bt({frames:r,original:s,template:n,sweep:o,entityKey:t.entityKey});}catch(l){console.error(g.red(`error: ${l.message}`)),process.exit(1);}if(t.json){console.log(JSON.stringify(i,null,2));return}Zn(i,t.entityKey);}var es=`
1050
- ${j} \u2014 CLI tools for Directive
1049
+ `);}async function nr(e){(e.includes("--help")||e.length===0)&&(we(),process.exit(e.length===0?1:0));let t=Yn(e);t.historyPath||(console.error(g.red("error: --history <frames.json> is required")),we(),process.exit(1)),t.originalPath||(console.error(g.red("error: --original <spec.json> is required")),we(),process.exit(1)),t.templatePath||(console.error(g.red("error: --template <spec.json> is required")),we(),process.exit(1)),t.sweepArgs.length===0&&(console.error(g.red("error: at least one --sweep <key:range> is required")),we(),process.exit(1));let r=Xn(Ye(t.historyPath,"--history")),s=Ye(t.originalPath,"--original"),n=Ye(t.templatePath,"--template"),i={};for(let l of t.sweepArgs){let[a,c]=Qn(l);i[a]=c;}let o;try{o=Kt({frames:r,original:s,template:n,sweep:i,entityKey:t.entityKey});}catch(l){console.error(g.red(`error: ${l.message}`)),process.exit(1);}if(t.json){console.log(JSON.stringify(o,null,2));return}Zn(o,t.entityKey);}var es=`
1050
+ ${A} \u2014 CLI tools for Directive
1051
1051
 
1052
- Usage: ${j} <command> [options]
1052
+ Usage: ${A} <command> [options]
1053
1053
 
1054
1054
  Commands:
1055
1055
  init Project scaffolding wizard
@@ -1110,14 +1110,14 @@ ai-rules init options:
1110
1110
  examples options:
1111
1111
  --filter <category> Filter by category or name
1112
1112
  --dest <dir> Destination directory for copy
1113
- `.trim();async function ts(){let e=process.argv.slice(2),t=e[0];if((e.length===0||t==="--help"||t==="-h")&&(console.log(es),process.exit(0)),t==="--version"||t==="-v"){let{readFileSync:n}=await import('fs'),{fileURLToPath:o}=await import('url'),{dirname:i,join:l}=await import('path'),a=i(o(import.meta.url)),c=JSON.parse(n(l(a,"..","package.json"),"utf-8"));console.log(c.version),process.exit(0);}let s=e[0];switch(s){case "init":{await xt(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 Ot(o,e.slice(3))):n==="orchestrator"?(o||(console.error("Usage: directive new orchestrator <name>"),process.exit(1)),await Mt(o,e.slice(3))):(console.error(`Unknown subcommand: ${n??"(none)"}
1114
- Usage: ${j} new module <name>
1115
- ${j} new orchestrator <name>`),process.exit(1));break}case "inspect":{await Et(e.slice(1));break}case "explain":{await St(e.slice(1));break}case "graph":{await kt(e.slice(1));break}case "doctor":{await ht(e.slice(1));break}case "ai-rules":{let n=e[1];n==="init"?await at(e.slice(2)):n==="update"?await lt(e.slice(2)):n==="check"?await ct(e.slice(2)):(console.error(`Unknown subcommand: ${n??"(none)"}
1116
- Usage: ${j} ai-rules init
1117
- ${j} ai-rules update
1118
- ${j} ai-rules check`),process.exit(1));break}case "examples":{let n=e[1];if(n==="list")await wt(e.slice(2));else if(n==="copy"){let o=e[2];o||(console.error("Usage: directive examples copy <name>"),process.exit(1)),await bt(o,e.slice(3));}else console.error(`Unknown subcommand: ${n??"(none)"}
1119
- Usage: ${j} examples list [--filter <category>]
1120
- ${j} examples copy <name> [--dest <dir>]`),process.exit(1);break}case "replay":{await Yt(e.slice(1));break}case "replay-under":{await Vt(e.slice(1));break}case "tune":{await nr(e.slice(1));break}case "rules-diff":{await Qt(e.slice(1));break}case "bisect":{await mt(e.slice(1));break}case "timeline":{let n=e[1];n==="diff"?await rr(e.slice(2)):(console.error(`Unknown subcommand: ${n??"(none)"}
1121
- Usage: ${j} timeline diff <a.json> <b.json>`),process.exit(1));break}default:console.error(`Unknown command: ${s}
1122
- Run '${j} --help' for usage.`),process.exit(1);}}ts().catch(e=>{console.error(e.message||e),process.exit(1);});//# sourceMappingURL=cli.js.map
1113
+ `.trim();async function ts(){let e=process.argv.slice(2),t=e[0];if((e.length===0||t==="--help"||t==="-h")&&(console.log(es),process.exit(0)),t==="--version"||t==="-v"){let{readFileSync:n}=await import('fs'),{fileURLToPath:i}=await import('url'),{dirname:o,join:l}=await import('path'),a=o(i(import.meta.url)),c=JSON.parse(n(l(a,"..","package.json"),"utf-8"));console.log(c.version),process.exit(0);}let s=e[0];switch(s){case "init":{await kt(e.slice(1));break}case "new":{let n=e[1],i=e[2];n==="module"?(i||(console.error("Usage: directive new module <name>"),process.exit(1)),await Ot(i,e.slice(3))):n==="orchestrator"?(i||(console.error("Usage: directive new orchestrator <name>"),process.exit(1)),await Mt(i,e.slice(3))):(console.error(`Unknown subcommand: ${n??"(none)"}
1114
+ Usage: ${A} new module <name>
1115
+ ${A} new orchestrator <name>`),process.exit(1));break}case "inspect":{await Dt(e.slice(1));break}case "explain":{await St(e.slice(1));break}case "graph":{await xt(e.slice(1));break}case "doctor":{await ht(e.slice(1));break}case "ai-rules":{let n=e[1];n==="init"?await at(e.slice(2)):n==="update"?await lt(e.slice(2)):n==="check"?await ct(e.slice(2)):(console.error(`Unknown subcommand: ${n??"(none)"}
1116
+ Usage: ${A} ai-rules init
1117
+ ${A} ai-rules update
1118
+ ${A} ai-rules check`),process.exit(1));break}case "examples":{let n=e[1];if(n==="list")await wt(e.slice(2));else if(n==="copy"){let i=e[2];i||(console.error("Usage: directive examples copy <name>"),process.exit(1)),await $t(i,e.slice(3));}else console.error(`Unknown subcommand: ${n??"(none)"}
1119
+ Usage: ${A} examples list [--filter <category>]
1120
+ ${A} examples copy <name> [--dest <dir>]`),process.exit(1);break}case "replay":{await Yt(e.slice(1));break}case "replay-under":{await Vt(e.slice(1));break}case "tune":{await nr(e.slice(1));break}case "rules-diff":{await Qt(e.slice(1));break}case "bisect":{await mt(e.slice(1));break}case "timeline":{let n=e[1];n==="diff"?await rr(e.slice(2)):(console.error(`Unknown subcommand: ${n??"(none)"}
1121
+ Usage: ${A} timeline diff <a.json> <b.json>`),process.exit(1));break}default:console.error(`Unknown command: ${s}
1122
+ Run '${A} --help' for usage.`),process.exit(1);}}ts().catch(e=>{console.error(e.message||e),process.exit(1);});//# sourceMappingURL=cli.js.map
1123
1123
  //# sourceMappingURL=cli.js.map