@directive-run/cli 1.14.0 → 1.15.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,17 +1,50 @@
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 O="directive";var be="<!-- directive:start -->",ue="<!-- directive:end -->";var Ne=[{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 Ne)r.signals.some(n=>existsSync(join(e,n)))&&t.push({name:r.name,id:r.id,outputPath:join(e,r.outputPath)});return t}function fe(e){let t=Ne.find(r=>r.id===e);if(!t)throw new Error(`Unknown tool: ${e}`);return t}function et(){return Ne.map(e=>e.id)}function re(e,t){let r=e.indexOf(be),s=e.indexOf(ue),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 O="directive";var be="<!-- directive:start -->",ue="<!-- directive:end -->";var Ne=[{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 Ne)r.signals.some(n=>existsSync(join(e,n)))&&t.push({name:r.name,id:r.id,outputPath:join(e,r.outputPath)});return t}function de(e){let t=Ne.find(r=>r.id===e);if(!t)throw new Error(`Unknown tool: ${e}`);return t}function et(){return Ne.map(e=>e.id)}function re(e,t){let r=e.indexOf(be),s=e.indexOf(ue),n=`${be}
3
3
  ${t}
4
4
  ${ue}`;if(r!==-1&&s!==-1&&s>r)return e.slice(0,r)+n+e.slice(s+ue.length);let o=e.endsWith(`
5
5
  `)?`
6
6
  `:`
7
7
 
8
- `;return e+o+n+`
8
+ `;return `${e+o+n}
9
9
  `}function ne(e){return e.includes(be)&&e.includes(ue)}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\`
13
13
  > Full reference with examples: https://directive.run/llms.txt
14
14
 
15
+ ## When to reach for Directive
16
+
17
+ Directive is to **business state and agent orchestration** what XState
18
+ is to state machines and React Query is to server state \u2014 a runtime
19
+ that takes declarative rules ("what must be true") and runs the
20
+ resolvers ("how to make it true"). The unique claim only Directive can
21
+ make: **state and AI agents share the same runtime**. \`@directive-run/ai\`
22
+ is the only state-library ecosystem that ships LLM orchestration as a
23
+ sibling concept to facts/constraints/resolvers.
24
+
25
+ It is NOT a Redux replacement for cross-cutting global UI state. It is
26
+ a constraint engine you compose alongside Redux / Zustand / Jotai /
27
+ React Query / TanStack Query.
28
+
29
+ **Reach for Directive when:**
30
+
31
+ - The same business rule has to fire across React, Vue, server, and
32
+ background workers. Directive runs the same module in every runtime.
33
+ - A constraint should drive a side-effect (fetch, validate, cancel,
34
+ retry) declaratively, without writing imperative thunks.
35
+ - You are orchestrating LLM agents and need typed, replayable state +
36
+ guardrails + budgets + audit trails + checkpoints.
37
+ - You want time-travel debugging, audit logs, or rules-diff replay on
38
+ state mutations without instrumenting every component.
39
+
40
+ **Do NOT reach for Directive for:**
41
+
42
+ - Plain UI state (use signals / Zustand / Jotai).
43
+ - Server-state caching only (use React Query / TanStack Query
44
+ \u2014 though you can layer \`@directive-run/query\` on top when you need
45
+ the constraint engine alongside fetching).
46
+ - State machines that don't react to external facts (use XState).
47
+
15
48
  ## Core Patterns
16
49
 
17
50
  ${e}
@@ -30,7 +63,7 @@ ${t}
30
63
  | 22 | \`facts.cache.push(item)\` in orchestrator | \`facts.cache = [...facts.cache, item]\` |
31
64
  | 23 | Returning data from orchestrator \`resolve\` | Resolvers return \`void\` \u2014 mutate \`context.facts\` |
32
65
  | 24 | Forgetting \`orchestrator.start()\` multi-agent | Single: implicit. Multi: must call \`start()\` |
33
- | 25 | Catching \`Error\` not \`GuardrailError\` | \`GuardrailError\` has \`.guardrailName\`, \`.errorCode\` |
66
+ | 25 | Catching \`Error\` not \`GuardrailError\` | \`GuardrailError\` has \`.guardrailName\`, \`.code\`, \`.userMessage\` |
34
67
  | 26 | \`from '@directive-run/ai'\` for adapters | Subpath: \`from '@directive-run/ai/openai'\` |
35
68
  | 27 | Assuming \`{ input_tokens }\` structure | Normalized: \`{ inputTokens, outputTokens }\` |
36
69
  | 28 | Same CircuitBreaker across agents | Create separate instances per dependency |
@@ -226,7 +259,7 @@ for await (const chunk of streamResult.stream) {
226
259
  \`\`\`
227
260
 
228
261
  Backpressure: \`"buffer"\` (default), \`"block"\`, \`"drop"\`
229
- `}function xe(){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 xe()+"\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"+`
262
+ `}function ke(){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## When to reach for Directive\n\nDirective is to **business state** what XState is to state machines and\nReact Query is to server state \u2014 a runtime that takes declarative rules\n("what must be true") and runs the resolvers ("how to make it true") for\nyou. It is NOT a Redux replacement for cross-cutting global UI state;\nit is a constraint engine you compose alongside Redux / Zustand / Jotai\n/ React Query.\n\nReach for Directive when:\n\n- The same business rule has to fire across React, Vue, server, and\n background workers. Directive runs the same module in every runtime.\n- You want a constraint to drive a side-effect (fetch, validate,\n cancel, retry) declaratively, without writing imperative thunks.\n- You are orchestrating LLM agents and need typed, replayable state +\n guardrails + budgets. `@directive-run/ai` is the only state-library\n ecosystem that ships AI orchestration as a sibling concept.\n- You want time-travel debugging, audit logs, or rules-diff replay on\n state mutations without instrumenting every component.\n\nYou do NOT need Directive for plain UI state (use signals / Zustand /\nJotai), simple server-state caching (use React Query / TanStack Query),\nor state machines that don\'t react to external facts (use XState).\n\n## Schema Shape (CRITICAL)\n\n```typescript\nimport { createModule, createSystem, t } from "@directive-run/core";\n\nconst myModule = createModule("name", {\n schema: {\n facts: { count: t.number(), items: t.array<string>() },\n derivations: { total: "number" },\n events: { increment: "void", addItem: "string" },\n requirements: { FETCH_DATA: { url: "string" } },\n },\n init: (facts) => { facts.count = 0; facts.items = []; },\n derive: {\n total: (facts) => facts.items.length + facts.count,\n },\n events: {\n increment: (facts) => { facts.count += 1; },\n addItem: (facts, item) => { facts.items = [...facts.items, item]; },\n },\n constraints: {\n fetchWhenReady: {\n when: (facts) => facts.count > 0 && facts.items.length === 0,\n require: (facts) => ({ type: "FETCH_DATA", url: "/api/items" }),\n },\n },\n resolvers: {\n fetchData: {\n requirement: "FETCH_DATA",\n resolve: async (req, context) => {\n const data = await fetch(req.url).then(r => r.json());\n context.facts.items = data;\n },\n },\n },\n});\n\nconst system = createSystem({ module: myModule });\nawait system.settle();\n```\n\n## Top 10 Anti-Patterns\n\n| # | WRONG | CORRECT |\n|---|-------|---------|\n| 1 | `facts.profile as ResourceState<Profile>` | Remove cast \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 | `useEvent`/`DirectiveProvider` top-level imports | `useEvents`; `createDirectiveContext(system).Provider` |\n| 10 | `facts[\'auth::status\']` | `facts.auth.status` dot notation |\n\n## Naming\n\n- `req` = requirement (not request). Parameter: `(req, context)`\n- `derive` / derivations \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 ke()+"\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
263
  ## Multi-Module
231
264
 
232
265
  \`\`\`typescript
@@ -259,17 +292,17 @@ const result = await orchestrator.run(agent, "analyze this");
259
292
  - Subpath imports: \`from '@directive-run/ai/anthropic'\` not \`from '@directive-run/ai'\`
260
293
  - Token usage normalized: \`{ inputTokens, outputTokens }\` (not provider-specific)
261
294
  - \`facts.cache = [...facts.cache, item]\` not \`facts.cache.push(item)\`
262
- `}function ot(){return se()}function it(){return se()}var lr={cursor:xe,claude:st,copilot:se,windsurf:it,cline:ot};function ke(e){let t=lr[e];if(!t)throw new Error(`No template for tool: ${e}`);return t()}function We(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=We(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 c=fe(i);return {name:c.name,id:c.id,outputPath:join(s,c.outputPath)}});else {let i=Ze(s);if(i.length>0){let c=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(c)&&(h.cancel("Cancelled."),process.exit(0)),n=c.map(a=>{let l=fe(a);return {name:l.name,id:l.id,outputPath:join(s,l.outputPath)}});}else {let c=await h.multiselect({message:"No AI tools detected. Which tools do you use?",options:et().map(a=>{let l=fe(a);return {value:a,label:l.name}}),required:true});h.isCancel(c)&&(h.cancel("Cancelled."),process.exit(0)),n=c.map(a=>{let l=fe(a);return {name:l.name,id:l.id,outputPath:join(s,l.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 c=ke(i.id),a=i.outputPath,l=existsSync(a);if(o.stop(`Generated ${i.name} rules.`),l&&!t.force){let u=readFileSync(a,"utf-8");if(t.merge){Q(a,re(u,c)),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"?(Q(a,re(u,c)),h.log.success(`${g.green("Updated")} ${g.dim(relative(s,a))}`)):f==="overwrite"?(Q(a,c),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"?(Q(a,re(u,c)),h.log.success(`${g.green("Appended")} to ${g.dim(relative(s,a))}`)):f==="overwrite"?(Q(a,c),h.log.success(`${g.green("Wrote")} ${g.dim(relative(s,a))}`)):h.log.info(`Skipped ${g.dim(relative(s,a))}`);}}else Q(a,c),h.log.success(`${g.green("Created")} ${g.dim(relative(s,a))}`);}h.outro(`Done! Run ${g.cyan(`${O} ai-rules init --merge`)} anytime to update.`);}function Q(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}async function ct(e){let r=We(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 c=ke(o.id),a=re(i,c);Q(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(`${O} ai-rules init`)} first.`):g.green(`
263
- Updated ${n} file(s) to latest knowledge version.`));}async function lt(e){let r=We(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 c=readFileSync(i.path,"utf-8");if(!ne(c))continue;n++;let a=ke(i.id);re(c,a)!==c?(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(`
295
+ `}function ot(){return se()}function it(){return se()}var lr={cursor:ke,claude:st,copilot:se,windsurf:it,cline:ot};function xe(e){let t=lr[e];if(!t)throw new Error(`No template for tool: ${e}`);return t()}function We(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=We(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 c=de(i);return {name:c.name,id:c.id,outputPath:join(s,c.outputPath)}});else {let i=Ze(s);if(i.length>0){let c=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(c)&&(h.cancel("Cancelled."),process.exit(0)),n=c.map(a=>{let l=de(a);return {name:l.name,id:l.id,outputPath:join(s,l.outputPath)}});}else {let c=await h.multiselect({message:"No AI tools detected. Which tools do you use?",options:et().map(a=>{let l=de(a);return {value:a,label:l.name}}),required:true});h.isCancel(c)&&(h.cancel("Cancelled."),process.exit(0)),n=c.map(a=>{let l=de(a);return {name:l.name,id:l.id,outputPath:join(s,l.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 c=xe(i.id),a=i.outputPath,l=existsSync(a);if(o.stop(`Generated ${i.name} rules.`),l&&!t.force){let u=readFileSync(a,"utf-8");if(t.merge){Q(a,re(u,c)),h.log.success(`${g.green("Merged")} Directive section into ${g.dim(relative(s,a))}`);continue}if(ne(u)){let d=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(d)&&(h.cancel("Cancelled."),process.exit(0)),d==="merge"?(Q(a,re(u,c)),h.log.success(`${g.green("Updated")} ${g.dim(relative(s,a))}`)):d==="overwrite"?(Q(a,c),h.log.success(`${g.green("Wrote")} ${g.dim(relative(s,a))}`)):h.log.info(`Skipped ${g.dim(relative(s,a))}`);}else {let d=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(d)&&(h.cancel("Cancelled."),process.exit(0)),d==="append"?(Q(a,re(u,c)),h.log.success(`${g.green("Appended")} to ${g.dim(relative(s,a))}`)):d==="overwrite"?(Q(a,c),h.log.success(`${g.green("Wrote")} ${g.dim(relative(s,a))}`)):h.log.info(`Skipped ${g.dim(relative(s,a))}`);}}else Q(a,c),h.log.success(`${g.green("Created")} ${g.dim(relative(s,a))}`);}h.outro(`Done! Run ${g.cyan(`${O} ai-rules init --merge`)} anytime to update.`);}function Q(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}async function ct(e){let r=We(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 c=xe(o.id),a=re(i,c);Q(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(`${O} ai-rules init`)} first.`):g.green(`
296
+ Updated ${n} file(s) to latest knowledge version.`));}async function lt(e){let r=We(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 c=readFileSync(i.path,"utf-8");if(!ne(c))continue;n++;let a=xe(i.id);re(c,a)!==c?(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
297
  ${g.yellow(`${o} file(s) are stale.`)} Run ${g.cyan(`${O} 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)}
298
+ All rule files are current.`));}async function z(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
299
  Export a system as default or named "system":
267
300
 
268
301
  ${g.cyan("export default")} createSystem({ module: myModule });
269
302
  ${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
303
 
271
304
  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)}
305
+ ${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 ft(e){let t=resolve(e);if(!existsSync(t))throw new Error(`File not found: ${t}`);let r;try{r=await import(t);}catch(o){throw new Error(`Failed to load ${g.dim(e)}: ${o instanceof Error?o.message:String(o)}
273
306
 
274
307
  Make sure the file is valid TypeScript and tsx is installed:
275
308
  ${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 c=await Promise.resolve(i());if(!Y(c))throw new Error(`Factory '${o}' from ${g.dim(e)} returned a value that is not a started Directive system.
@@ -330,21 +363,21 @@ Examples:
330
363
  `);}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
364
  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)&&(Ae(),process.exit(e.length===0?1:0));let{jsonPath:t,opts:r}=gr(e);t||(console.error(g.red("error: missing <timeline.json> argument")),Ae(),process.exit(1)),r.systemPath||(console.error(g.red("error: --system <path> is required"),g.dim(`
332
365
  (bisect needs a factory to instantiate a fresh system per midpoint)`)),Ae(),process.exit(1)),r.assertExpr||(console.error(g.red("error: --assert <expression> is required"),g.dim(`
333
- (assertion distinguishes 'good' from 'bad' system state)`)),Ae(),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(w){console.error(g.red(`error: failed to read ${s}: ${w.message}`)),process.exit(1);}let o;try{o=JSON.parse(n);}catch(w){console.error(g.red(`error: ${s} is not valid JSON: ${w.message}`)),process.exit(1);}let{deserializeTimeline:i,bisectTimeline:c}=await oe(r.verbose),a;try{a=i(o);}catch(w){console.error(g.red(`error: timeline JSON failed validation: ${w.message}`)),process.exit(1);}let l;try{l=yr(r.assertExpr);}catch(w){console.error(g.red(`error: ${w.message}`)),process.exit(1);}let u;try{u=await dt(r.systemPath);}catch(w){console.error(g.red(`error: failed to load system factory: ${w.message}`)),process.exit(1);}r.verbose&&console.error(g.dim(`bisecting ${a.frames.length} frames with assertion: ${r.assertExpr}`));let f=await c(a,u,l,{maxFrames:r.maxFrames,determinismCheck:!r.noDeterminismCheck});if(r.json){let w={firstFailingFrameIndex:f.firstFailingFrameIndex??null,iterations:f.iterations,noFailureFound:f.noFailureFound,failsOnEmptyReplay:f.failsOnEmptyReplay,nonDeterministic:f.nonDeterministic};console.log(JSON.stringify(w,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.
366
+ (assertion distinguishes 'good' from 'bad' system state)`)),Ae(),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(w){console.error(g.red(`error: failed to read ${s}: ${w.message}`)),process.exit(1);}let o;try{o=JSON.parse(n);}catch(w){console.error(g.red(`error: ${s} is not valid JSON: ${w.message}`)),process.exit(1);}let{deserializeTimeline:i,bisectTimeline:c}=await oe(r.verbose),a;try{a=i(o);}catch(w){console.error(g.red(`error: timeline JSON failed validation: ${w.message}`)),process.exit(1);}let l;try{l=yr(r.assertExpr);}catch(w){console.error(g.red(`error: ${w.message}`)),process.exit(1);}let u;try{u=await ft(r.systemPath);}catch(w){console.error(g.red(`error: failed to load system factory: ${w.message}`)),process.exit(1);}r.verbose&&console.error(g.dim(`bisecting ${a.frames.length} frames with assertion: ${r.assertExpr}`));let d=await c(a,u,l,{maxFrames:r.maxFrames,determinismCheck:!r.noDeterminismCheck});if(r.json){let w={firstFailingFrameIndex:d.firstFailingFrameIndex??null,iterations:d.iterations,noFailureFound:d.noFailureFound,failsOnEmptyReplay:d.failsOnEmptyReplay,nonDeterministic:d.nonDeterministic};console.log(JSON.stringify(w,null,2)),process.exit(0);}d.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
367
  Bisection is unreliable on non-deterministic timelines.
335
368
  Either fix the timeline source (deterministic clocks/seeds)
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
369
+ or re-run with --no-determinism-check if you accept the risk.`)),process.exit(2)),d.noFailureFound&&(console.error(g.yellow("\u26A0 no failure to bisect: assertion passes on the full timeline")),console.error(g.dim(` The recorded timeline does not exhibit the bug your
337
370
  --assert expression checks. Verify the assertion or
338
- try a different bad.json.`)),process.exit(0)),f.failsOnEmptyReplay&&(console.error(g.yellow("\u26A0 assertion fails BEFORE any frame replays \u2014 bug is in initialization")),console.error(g.dim(` The freshly-started system already violates the assertion.
371
+ try a different bad.json.`)),process.exit(0)),d.failsOnEmptyReplay&&(console.error(g.yellow("\u26A0 assertion fails BEFORE any frame replays \u2014 bug is in initialization")),console.error(g.dim(` The freshly-started system already violates the assertion.
339
372
  Bisect cannot narrow further. Inspect the system factory
340
- or initial fact values.`)),process.exit(0));let d=f.firstFailingFrameIndex??-1,m=f.firstFailingFrame,$=m?.event.type??"<unknown>";console.log(`${g.green("\u2713")} bisect complete: ${g.bold(`first failing frame is #${d}`)} ${g.dim(`(${$})`)}`),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(`
373
+ or initial fact values.`)),process.exit(0));let f=d.firstFailingFrameIndex??-1,m=d.firstFailingFrame,$=m?.event.type??"<unknown>";console.log(`${g.green("\u2713")} bisect complete: ${g.bold(`first failing frame is #${f}`)} ${g.dim(`(${$})`)}`),console.log(g.dim(` \u2022 iterations: ${d.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
374
  `).join(`
342
- `)}`))),process.exit(2);}function vr(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 wr(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(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 xr(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 Sr(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=vr(e);console.log(),console.log(g.bold(g.cyan("Directive Doctor"))),console.log(g.dim("\u2500".repeat(40))),console.log();let r=[wr(t.dir),br(t.dir),xr(t.dir),kr(t.dir),Sr(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 $t={"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 Dr(e){for(let[t,r]of Object.entries($t))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 vt(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,c]of r){let a=Dr(i);t&&!a.toLowerCase().includes(t)&&!i.includes(t)||(s.has(a)||s.set(a,[]),s.get(a).push({name:i,desc:Cr(c)}));}if(s.size===0){console.log(g.dim("No examples match the filter."));return}let n=Object.keys($t),o=[...s.keys()].sort((i,c)=>(n.indexOf(i)??99)-(n.indexOf(c)??99));for(let i of o){let c=s.get(i);console.log(g.bold(i));for(let a of c){let l=a.desc?g.dim(` \u2014 ${a.desc}`):"";console.log(` ${g.cyan(a.name)}${l}`);}console.log();}console.log(g.dim(`${r.size} examples available. Run ${g.cyan("directive examples copy <name>")} to extract one.`));}async function wt(e,t){let r=process.cwd();for(let a=0;a<t.length;a++)if(t[a]==="--dest"){let l=t[++a];l&&(r=l);}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 c=relative(process.cwd(),o);console.log(`${g.green("Copied")} ${g.cyan(e)} \u2192 ${g.dim(c)}`);}function Rr(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 xt(e){let{filePath:t,requirementId:r}=Rr(e);t||(console.error("Usage: directive explain <file> [requirement-id]"),process.exit(1));let s=await U(t);s.isRunning||s.start();let n=s.inspect();if(r){let o=s.explain(r);if(!o){if(console.error(`Requirement "${r}" not found.
375
+ `)}`))),process.exit(2);}function vr(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 wr(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(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 kr(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 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 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 Sr(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=vr(e);console.log(),console.log(g.bold(g.cyan("Directive Doctor"))),console.log(g.dim("\u2500".repeat(40))),console.log();let r=[wr(t.dir),br(t.dir),kr(t.dir),xr(t.dir),Sr(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 $t={"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 Dr(e){for(let[t,r]of Object.entries($t))if(r.includes(e))return t;return "Other"}function Rr(e){let t=e.split(`
376
+ `);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 vt(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,c]of r){let a=Dr(i);t&&!a.toLowerCase().includes(t)&&!i.includes(t)||(s.has(a)||s.set(a,[]),s.get(a).push({name:i,desc:Rr(c)}));}if(s.size===0){console.log(g.dim("No examples match the filter."));return}let n=Object.keys($t),o=[...s.keys()].sort((i,c)=>(n.indexOf(i)??99)-(n.indexOf(c)??99));for(let i of o){let c=s.get(i);console.log(g.bold(i));for(let a of c){let l=a.desc?g.dim(` \u2014 ${a.desc}`):"";console.log(` ${g.cyan(a.name)}${l}`);}console.log();}console.log(g.dim(`${r.size} examples available. Run ${g.cyan("directive examples copy <name>")} to extract one.`));}async function wt(e,t){let r=process.cwd();for(let a=0;a<t.length;a++)if(t[a]==="--dest"){let l=t[++a];l&&(r=l);}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 c=relative(process.cwd(),o);console.log(`${g.green("Copied")} ${g.cyan(e)} \u2192 ${g.dim(c)}`);}function Tr(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 kt(e){let{filePath:t,requirementId:r}=Tr(e);t||(console.error("Usage: directive explain <file> [requirement-id]"),process.exit(1));let s=await z(t);s.isRunning||s.start();let n=s.inspect();if(r){let o=s.explain(r);if(!o){if(console.error(`Requirement "${r}" not found.
344
377
 
345
378
  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,c]of o){let a=bt(c.state),l=c.duration!==void 0?` (${c.duration}ms)`:"";console.log(` ${g.cyan(i)} ${a}${l}`);}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: ${bt(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 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 Nr(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 c of e.constraints)r.set(c.id,{reqTypes:new Set,active:c.active,priority:c.priority});for(let c of e.unmet){let a=r.get(c.fromConstraint);a&&a.reqTypes.add(c.requirement.type);}let s=new Map;for(let c of e.resolverDefs)s.has(c.requirement)||s.set(c.requirement,[]),s.get(c.requirement).push(c.id);t.push(g.bold("Constraints \u2192 Requirements \u2192 Resolvers")),t.push("");for(let[c,a]of r){let l=a.active?g.green("\u25CF"):g.dim("\u25CB");if(t.push(`${l} ${g.cyan(c)} (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 c of s.values())for(let a of c)n.add(a);if(e.resolverDefs.map(c=>c.id).filter(c=>!n.has(c)).length>0){t.push(g.bold("Standalone Resolvers:"));for(let c of e.resolverDefs)n.has(c.id)||t.push(` ${g.magenta(c.id)} handles ${g.yellow(c.requirement)}`);}return t.join(`
347
- `)}function qr(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 l=new Set;for(let p of e.unmet)l.add(p.requirement.type);let u=0;for(let p of l)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)l.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,$=s.map(p=>{let y=f.get(p.from),D=f.get(p.to);return !y||!D?"":`<line x1="${y.x+90}" y1="${y.y+15}" x2="${D.x}" y2="${D.y+15}" stroke="#94a3b8" stroke-width="1.5" marker-end="url(#arrow)"/>`}).join(`
379
+ `);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: ${bt(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 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 Nr(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 c of e.constraints)r.set(c.id,{reqTypes:new Set,active:c.active,priority:c.priority});for(let c of e.unmet){let a=r.get(c.fromConstraint);a&&a.reqTypes.add(c.requirement.type);}let s=new Map;for(let c of e.resolverDefs)s.has(c.requirement)||s.set(c.requirement,[]),s.get(c.requirement).push(c.id);t.push(g.bold("Constraints \u2192 Requirements \u2192 Resolvers")),t.push("");for(let[c,a]of r){let l=a.active?g.green("\u25CF"):g.dim("\u25CB");if(t.push(`${l} ${g.cyan(c)} (priority: ${a.priority})`),a.reqTypes.size>0)for(let u of a.reqTypes){t.push(` \u2514\u2500\u25B6 ${g.yellow(u)}`);let d=s.get(u)||[];if(d.length>0)for(let f of d)t.push(` \u2514\u2500\u25B6 ${g.magenta(f)}`);else t.push(` \u2514\u2500\u25B6 ${g.red("(no resolver)")}`);}else t.push(` \u2514\u2500\u25B6 ${g.dim("(no active requirements)")}`);t.push("");}let n=new Set;for(let c of s.values())for(let a of c)n.add(a);if(e.resolverDefs.map(c=>c.id).filter(c=>!n.has(c)).length>0){t.push(g.bold("Standalone Resolvers:"));for(let c of e.resolverDefs)n.has(c.id)||t.push(` ${g.magenta(c.id)} handles ${g.yellow(c.requirement)}`);}return t.join(`
380
+ `)}function qr(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 l=new Set;for(let p of e.unmet)l.add(p.requirement.type);let u=0;for(let p of l)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)l.has(p.requirement)&&s.push({from:`req-${p.requirement}`,to:`resolver-${p.id}`});let d=new Map(r.map(p=>[p.id,p])),f=960,m=Math.max(...r.map(p=>p.y))+50+20,$=s.map(p=>{let y=d.get(p.from),D=d.get(p.to);return !y||!D?"":`<line x1="${y.x+90}" y1="${y.y+15}" x2="${D.x}" y2="${D.y+15}" stroke="#94a3b8" stroke-width="1.5" marker-end="url(#arrow)"/>`}).join(`
348
381
  `),w=r.map(p=>`<g>
349
382
  <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
383
  <text x="${p.x+90}" y="${p.y+19}" text-anchor="middle" font-size="12" font-family="monospace" fill="${p.color}">${Ir(p.label)}</text>
@@ -360,7 +393,7 @@ Current requirements:`),n.unmet.length===0)console.log(g.dim(" (no unmet requir
360
393
  </style>
361
394
  </head>
362
395
  <body>
363
- <svg width="${d}" height="${m}" xmlns="http://www.w3.org/2000/svg">
396
+ <svg width="${f}" height="${m}" xmlns="http://www.w3.org/2000/svg">
364
397
  <defs>
365
398
  <marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
366
399
  <path d="M 0 0 L 10 5 L 0 10 z" fill="#94a3b8"/>
@@ -371,7 +404,7 @@ Current requirements:`),n.unmet.length===0)console.log(g.dim(" (no unmet requir
371
404
  ${w}
372
405
  </svg>
373
406
  </body>
374
- </html>`}function Ir(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function kt(e){let{filePath:t,opts:r}=Nr(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 o={};if(s.facts)for(let a of Object.keys(s.facts))try{o[a]=s.facts[a];}catch{o[a]=null;}let i=qr(n,o),c=r.output||join(process.cwd(),".directive-graph.html");if(writeFileSync(c,i,"utf-8"),console.log(`${g.green("Generated")} ${g.dim(c)}`),r.open)try{let{execFile:a}=await import('child_process'),l=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";a(l,[c]),console.log(g.dim("Opened in browser."));}catch{console.log(g.dim(`Open ${c} 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 Jr(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:Kr(e)},{path:"src/main.ts",content:Gr(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:Br(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:Qr(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";
407
+ </html>`}function Ir(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function xt(e){let{filePath:t,opts:r}=Nr(e);t||(console.error("Usage: directive graph <file> [--ascii] [--no-open] [--output <path>]"),process.exit(1));let s=await z(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=qr(n,o),c=r.output||join(process.cwd(),".directive-graph.html");if(writeFileSync(c,i,"utf-8"),console.log(`${g.green("Generated")} ${g.dim(c)}`),r.open)try{let{execFile:a}=await import('child_process'),l=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";a(l,[c]),console.log(g.dim("Opened in browser."));}catch{console.log(g.dim(`Open ${c} in your browser to view the graph.`));}s.stop();}function zr(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 Jr(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:Kr(e)},{path:"src/main.ts",content:Gr(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:Br(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:Qr(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";
375
408
 
376
409
  const schema = {
377
410
  facts: {
@@ -696,10 +729,10 @@ await system.settle();
696
729
  console.log("output:", system.facts.output);
697
730
 
698
731
  export default system;
699
- `}function ae(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function Vr(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}async function St(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 o=_e(r)[s],i=Lr(t.dir);h.log.info(`Package manager: ${g.cyan(i)}`);let c=h.spinner();c.start("Creating project files...");let l=0;for(let f of o.files){let d=join(t.dir,f.path);if(existsSync(d)){l++;continue}Vr(d,f.content);}c.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)}`);}l>0&&h.log.warn(`Skipped ${l} file(s) that already exist.`);let u=Jr(i,o.deps.join(" "));h.outro(`Next steps:
732
+ `}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 St(e){let t=zr(e);h.intro(g.bgCyan(g.black(" directive init ")));let r;if(t.noInteractive)r="my-module";else {let d=await h.text({message:"Module name:",placeholder:"my-module",defaultValue:"my-module",validate:f=>{if(!/^[a-z][a-z0-9-]*$/.test(f))return "Must start with a letter, use lowercase letters, numbers, and hyphens"}});h.isCancel(d)&&(h.cancel("Cancelled."),process.exit(0)),r=d;}let s;if(t.template){let d=_e(r);t.template in d||(h.log.error(`Unknown template: ${t.template}. Available: ${Object.keys(d).join(", ")}`),process.exit(1)),s=t.template;}else if(t.noInteractive)s="counter";else {let d=_e(r),f=await h.select({message:"Project template:",options:Object.values(d).map(m=>({value:m.id,label:m.label,hint:m.hint}))});h.isCancel(f)&&(h.cancel("Cancelled."),process.exit(0)),s=f;}let o=_e(r)[s],i=Lr(t.dir);h.log.info(`Package manager: ${g.cyan(i)}`);let c=h.spinner();c.start("Creating project files...");let l=0;for(let d of o.files){let f=join(t.dir,d.path);if(existsSync(f)){l++;continue}Xr(f,d.content);}c.stop("Project files created.");for(let d of o.files){let f=join(t.dir,d.path),m=relative(t.dir,f);existsSync(f)&&h.log.success(`${g.green("Created")} ${g.dim(m)}`);}l>0&&h.log.warn(`Skipped ${l} file(s) that already exist.`);let u=Jr(i,o.deps.join(" "));h.outro(`Next steps:
700
733
  ${g.cyan(u)}
701
734
  ${g.cyan(`${O} ai-rules init`)}
702
- ${g.dim("Start building!")}`);}function Xr(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(`
735
+ ${g.dim("Start building!")}`);}function Vr(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
736
  `);for(let[s,n]of r){let o=on(n);t.push(` ${g.cyan(s)} = ${o}`);}return t.join(`
704
737
  `)}function en(e){let t=[];if(t.push(g.bold("Constraints:")),e.length===0)return t.push(" (none)"),t.join(`
705
738
  `);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(`
@@ -709,7 +742,7 @@ export default system;
709
742
  `);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
743
  `)}function nn(e){let t=[];if(t.push(g.bold("Inflight:")),e.length===0)return t.push(` ${g.green("(none)")}`),t.join(`
711
744
  `);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(c=>c.requirement===o.requirement.type||c.requirement==="(predicate)")||t.push(`No resolver for requirement type "${o.requirement.type}"`);return t}async function At(e){let{filePath:t,opts:r}=Xr(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 c={};if(s.facts)for(let a of Object.keys(s.facts))try{c[a]=s.facts[a];}catch{c[a]="(error reading)";}console.log(JSON.stringify({facts:c,...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 c of Object.keys(s.facts))try{o[c]=s.facts[c];}catch{o[c]="(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 c of i)console.log(` ${g.yellow("\u26A0")} ${c}`);console.log();}s.stop();}function Et(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 jt=["derive","events","constraints","resolvers","effects"];function fn(e,t){let r=Ot(e),s=t.includes("constraints"),n=t.includes("resolvers"),i=`import { ${["type ModuleSchema","createModule","t"].join(", ")} } from "@directive-run/core";
745
+ `)}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(c=>c.requirement===o.requirement.type||c.requirement==="(predicate)")||t.push(`No resolver for requirement type "${o.requirement.type}"`);return t}async function At(e){let{filePath:t,opts:r}=Vr(e);t||(console.error("Usage: directive inspect <file> [--json] [--module <name>]"),process.exit(1));let s=await z(t);s.isRunning||s.start();let n=s.inspect();if(r.json){let c={};if(s.facts)for(let a of Object.keys(s.facts))try{c[a]=s.facts[a];}catch{c[a]="(error reading)";}console.log(JSON.stringify({facts:c,...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 c of Object.keys(s.facts))try{o[c]=s.facts[c];}catch{o[c]="(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 c of i)console.log(` ${g.yellow("\u26A0")} ${c}`);console.log();}s.stop();}function Et(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 jt=["derive","events","constraints","resolvers","effects"];function dn(e,t){let r=Ot(e),s=t.includes("constraints"),n=t.includes("resolvers"),i=`import { ${["type ModuleSchema","createModule","t"].join(", ")} } from "@directive-run/core";
713
746
 
714
747
  `;return i+=`const schema = {
715
748
  `,i+=` facts: {
@@ -778,7 +811,7 @@ export default system;
778
811
  `,i+=` },
779
812
  `,i+=` },
780
813
  `),i+=`});
781
- `,i}function dn(e){let t=Ot(e);return `import { type ModuleSchema, createModule, createSystem, t } from "@directive-run/core";
814
+ `,i}function fn(e){let t=Ot(e);return `import { type ModuleSchema, createModule, createSystem, t } from "@directive-run/core";
782
815
  import {
783
816
  createAgentOrchestrator,
784
817
  createAgentMemory,
@@ -909,9 +942,9 @@ export const memory = createAgentMemory({
909
942
  export const system = createSystem({
910
943
  module: ${t},
911
944
  });
912
- `}function Ot(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function Dt(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 Rt(e,t){let r=Et(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=>jt.includes(a)):s=jt;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);Dt(o,i);let c=relative(r.dir,o);console.log(`${g.green("Created")} ${g.dim(c)}`),s.length===0?console.log(g.dim(" Minimal module (schema + init only)")):console.log(g.dim(` Sections: ${s.join(", ")}`));}async function Tt(e,t){let r=Et(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);Dt(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 pe=typeof process<"u"&&process.env?.NODE_ENV!=="production";function ce(e,t=50){let r=new WeakSet;function s(a){if(a===null)return "null";if(a===void 0)return "undefined";let l=typeof a;if(l==="string")return JSON.stringify(a);if(l==="number"||l==="boolean")return String(a);if(l==="function")return '"[function]"';if(l==="symbol")return '"[symbol]"'}function n(a,l){if(r.has(a))return '"[circular]"';r.add(a);let u=l();return r.delete(a),u}function o(a,l){return n(a,()=>`[${a.map(u=>c(u,l+1)).join(",")}]`)}function i(a,l){return n(a,()=>`{${Object.keys(a).sort().map(u=>`${JSON.stringify(u)}:${c(a[u],l+1)}`).join(",")}}`)}function c(a,l){if(l>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:${c(f,l+1)}`}if(a instanceof Set){let f=[...a].sort();return `S:${c(f,l+1)}`}return Array.isArray(a)?o(a,l):typeof a=="object"?i(a,l):'"[unknown]"'}return c(e,0)}var J=new Set(["$eq","$ne","$in","$nin","$exists","$gt","$gte","$lt","$lte","$between","$matches","$startsWith","$endsWith","$contains","$changed"]),Nt=new Set(["$all","$any","$not"]);var K=64;function I(e){return typeof e!="object"||e===null||Array.isArray(e)?false:!(e instanceof Date)&&!(e instanceof RegExp)}function Oe(e){if(typeof e!="object"||e===null||Array.isArray(e))return false;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function Je(e){if(!I(e))return false;let t=0,r=false;for(let s of Object.keys(e)){if(s.startsWith("$"))r=true,J.has(s)||he(`predicate: unknown operator "${s}" \u2014 looks like a typo. Known operators: ${[...J].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=>Oe(t)&&"fact"in t&&"op"in t):Oe(e)}function me(e,t,r="",s=new WeakSet,n=0){if(n>K){pe&&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,c)=>{if(!I(i))return;let a=i;if(typeof a.fact=="string"&&typeof a.op=="string"){let l=r?`${r}[${c}]`:`[${c}]`;t.operator?.(r?`${r}.${a.fact}`:a.fact,a.op,a.value,`${l}.value`);}});return}if(!I(e))return;if(s.has(e)){pe&&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 c=i==="$not"?[o.$not]:o[i]??[];for(let a of c)me(a,t,r,s,n+1);return}for(let i of Object.keys(o)){let c=r?`${r}.${i}`:i;if(i.startsWith("$")){t.strayOperatorKey?.(i,c);continue}let a=o[i];if(Je(a)){let l=a;for(let u of Object.keys(l))t.operator?.(c,u,l[u],`${c}.${u}`);continue}if(Oe(a)){if(t.nested?.(i)===false)continue;me(a,t,c,s,n+1);continue}t.literal?.(c,a);}}function qt(e,t=""){function r(n,o,i,c){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")&&!(c>K)&&!i.has(n)){if(i.add(n),Array.isArray(n)){n.forEach((a,l)=>{r(a,`${o}[${l}]`,i,c+1);});return}for(let a of Object.keys(n))r(n[a],o?`${o}.${a}`:a,i,c+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((c,a)=>{r(c,`${i}[${a}]`,new WeakSet,1);});else if(Oe(n))for(let c of Object.keys(n))r(n[c],`${i}.${c}`,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).`);me(e,{operator(n,o,i,c){s(i,o,t?`${t}.${c}`:c);},literal(n,o){s(o,"",t?`${t}.${n}`:n);}});}function pn(){return {ids:new WeakMap,next:{v:1},pairs:new Set}}function Mt(e,t){let r=e.ids.get(t);return r===void 0&&(r=e.next.v++,e.ids.set(t,r)),r}function q(e,t,r){if(Object.is(e,t))return true;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(typeof e!="object"||typeof t!="object"||e===null||t===null)return false;let s=r??pn(),n=`${Mt(s,e)}:${Mt(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((c,a)=>q(c,t[a],s));if(e instanceof Set||t instanceof Set){if(!(e instanceof Set)||!(t instanceof Set)||e.size!==t.size)return false;let c=[...t];return [...e].every(a=>c.some(l=>q(a,l,s)))}if(e instanceof Map||t instanceof Map){if(!(e instanceof Map)||!(t instanceof Map)||e.size!==t.size)return false;let c=[...t.entries()],a=new Array(c.length).fill(false);for(let[l,u]of e){let f=false;for(let d=0;d<c.length;d++){if(a[d])continue;let[m,$]=c[d];if(q(l,m,s)&&q(u,$,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(c=>Object.hasOwn(t,c)&&q(e[c],t[c],s))}function De(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=De(t),n=De(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 q(t,r);case "$ne":return !q(t,r);case "$in":return Array.isArray(r)&&r.some(n=>q(t,n));case "$nin":return Array.isArray(r)&&!r.some(n=>q(t,n));case "$exists":return r===(t!==void 0);case "$changed":return !q(t,s);case "$gt":case "$gte":case "$lt":case "$lte":return Le(e,t,r);case "$between":{if(!Array.isArray(r)||r.length!==2)return false;let n=De(r[0]),o=De(r[1]);return n!==void 0&&o!==void 0&&typeof n==typeof o&&n>o?(he("$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=>q(n,r)):t instanceof Set?t.has(r):false;default:return false}}function he(e){pe&&console.warn(`[Directive] ${e}`);}function mn(e,t,r,s){if(Je(e)){let n=Object.keys(e);n.length>1&&he(`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 I(e)?te(e,I(t)?t:Object.create(null),I(r)?r:void 0,s+1):q(t,e)}function te(e,t,r,s=0){if(s>K)return he(`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(!I(n))return false;let{fact:o,op:i,value:c}=n;return Ce(i,t?.[o],c,r?.[o])});if(!I(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(J.has(n))return he(`predicate: operator "${n}" mixed with fact keys \u2014 wrap operators in a per-fact object`),false;if(!mn(e[n],t?.[n],r?.[n],s))return false}return true}function ge(e,t,r,s=""){let n=[];if(Array.isArray(e)){for(let o of e){if(!I(o))continue;let{fact:i,op:c,value:a}=o,l=t?.[i];n.push({path:s+i,op:c,expected:a,actual:l,pass:Ce(c,l,a,r?.[i])});}return n}if(!I(e))return n;for(let o of ["$all","$any","$not"])if(o in e){let i=o==="$not"?[e.$not]:e[o],c=[];for(let u of i)c.push(...ge(u,t,r,s));let a=c.filter(u=>u.pass).length,l;return o==="$all"?l=c.length===0||a===c.length:o==="$any"?l=c.length>0&&a>0:l=!c.every(u=>u.pass),n.push({path:s||o,op:o,expected:i.length,actual:a,pass:l,children:c}),n}for(let o of Object.keys(e)){if(J.has(o))continue;let i=e[o],c=t?.[o],a=s+o;if(Je(i))for(let l of Object.keys(i))n.push({path:a,op:l,expected:i[l],actual:c,pass:Ce(l,c,i[l],r?.[o])});else I(i)?n.push(...ge(i,I(c)?c:Object.create(null),I(r?.[o])?r?.[o]:void 0,`${a}.`)):n.push({path:a,op:"$eq",expected:i,actual:c,pass:q(c,i)});}return n}var le=1e6;function It(e,t){try{qt(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(me(e,{operator(s,n){r===void 0&&n.startsWith("$")&&!J.has(n)&&(r=n);},strayOperatorKey(s){r===void 0&&!J.has(s)&&!Nt.has(s)&&(r=s);}}),r!==void 0)throw new Error(`[Directive] replayUnder: the ${t} predicate uses an unknown operator "${r}" \u2014 known operators: ${[...J].join(", ")}`)}function ye(e){if(e&&typeof e=="object"&&!Array.isArray(e)&&Array.isArray(e.snapshots))return hn(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 hn(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 ye(e)}function Re(e){let{frames:t,original:r,proposed:s,entityKey:n}=e,o=e.maxSamples??20,i=o>0?o:0;if(t.length>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`);It(r,"original"),It(s,"proposed");let c=0,a=0,l=0,u=0,f=0,d=[],m=[],$=n?new Set:void 0,w=n?new Set:void 0,F;for(let p of t){let y=p.facts,D=te(r,y,F),_=te(s,y,F);D&&(c++,$?.add(y[n])),_&&(a++,w?.add(y[n])),D===_?f++:!D&&_?(l++,d.length<i&&d.push(Wt(p,r,s,F))):(u++,m.length<i&&m.push(Wt(p,r,s,F))),F=y;}let W={framesEvaluated:t.length,original:{matched:c},proposed:{matched:a},delta:a-c,newMatchCount:l,lostMatchCount:u,unchanged:f,newMatches:d,lostMatches:m};return $&&w&&(W.original.matchedEntities=$.size,W.proposed.matchedEntities=w.size),W}function Wt(e,t,r,s){let n=e.facts,o={frameId:e.id,facts:n,originalExplain:ge(t,n,s),proposedExplain:ge(r,n,s)};return e.timestamp!==void 0&&(o.timestamp=e.timestamp),o}var _t=1e4,zt=5e7;function gn(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(gn(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 yn(e){let t=1;for(let r of Object.values(e))t*=r.length;return t}function Jt(e){let{frames:t,original:r,template:s,sweep:n,objective:o=y=>y.proposed.matched,entityKey:i,maxSamples:c=0}=e,a=Object.keys(n);if(a.length===0)throw new Error("[Directive] sweepUnder: `sweep` must contain at least one hole name");let l=yn(n);if(l>_t)throw new Error(`[Directive] sweepUnder: grid has ${l} points, exceeds the MAX_SWEEP_POINTS limit (${_t}) \u2014 narrow the sweep ranges or split the run`);if(l===0)throw new Error("[Directive] sweepUnder: at least one hole has zero candidate values");let u=l*t.length;if(u>zt)throw new Error(`[Directive] sweepUnder: ${l} points \xD7 ${t.length} frames = ${u} per-frame evaluations, exceeds the MAX_SWEEP_EVALUATIONS limit (${zt}) \u2014 narrow the sweep, down-sample the history, or split the run`);let f=false,d=y=>{let D;try{D=o(y);}catch(_){return f||(f=true,console.warn(`[Directive] sweepUnder: objective threw \u2014 point will not rank (${_.message})`)),Number.NEGATIVE_INFINITY}return typeof D!="number"||!Number.isFinite(D)?(f||(f=true,console.warn(`[Directive] sweepUnder: objective returned a non-finite number (${String(D)}) \u2014 point will not rank`)),Number.NEGATIVE_INFINITY):D},m=Re({frames:t,original:r,proposed:r,entityKey:i,maxSamples:c}),$={values:{},report:m,score:d(m)},w=[],F=0,W=Number.NEGATIVE_INFINITY;for(let y of Lt(a,n)){let D=Ke(s,y),_=Re({frames:t,original:r,proposed:D,entityKey:i,maxSamples:c}),Me=d(_);Me>W&&(W=Me,F=w.length),w.push({values:y,report:_,score:Me});}let p=w[F];return {points:w,bestIndex:F,best:p,baseline:$}}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 $n=new Set(["$eq","$ne","$in","$nin","$exists","$gt","$gte","$lt","$lte","$between","$matches","$startsWith","$endsWith","$contains","$changed"]),vn=new Set(["$all","$any","$not"]);function Kt(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function wn(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;$n.has(s)&&(r=true);}return r}function B(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)=>{B(s,`${t}$all[${n}]`,r);}),r;if("$any"in e&&Array.isArray(e.$any))return e.$any.forEach((s,n)=>{B(s,`${t}$any[${n}]`,r);}),r;if("$not"in e)return B(e.$not,`${t}$not`,r),r;for(let[s,n]of Object.entries(e)){let o=t?`${t}.${s}`:s;if(wn(n))for(let[i,c]of Object.entries(n))r.push({path:o,op:i,value:c});else Kt(n)&&!vn.has(s)?B(n,o,r):r.push({path:o,op:"$eq",value:n});}return r}function G(e){return typeof e=="number"&&Number.isFinite(e)}function bn(e,t,r){switch(e){case "$gte":case "$gt":if(G(t)&&G(r)){if(r<t)return "relaxed";if(r>t)return "tightened"}return null;case "$lte":case "$lt":if(G(t)&&G(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&&G(t[0])&&G(t[1])&&G(r[0])&&G(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 Gt(e){let t=Ut(e.before),r=Ut(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 c=t[i],a=r[i],l=i in t,u=i in r;if(l&&!u){let d=B(c),m=d.length===0?[{path:"(function-form predicate)",kind:"removed"}]:d.map($=>({path:$.path,kind:"removed",before:{op:$.op,value:$.value}}));Ge(m),n.push({id:i,status:"removed",changes:m}),o.removed++,o.totalClauseChanges+=m.length;continue}if(!l&&u){let d=B(a),m=d.length===0?[{path:"(function-form predicate)",kind:"added"}]:d.map($=>({path:$.path,kind:"added",after:{op:$.op,value:$.value}}));Ge(m),n.push({id:i,status:"added",changes:m}),o.added++,o.totalClauseChanges+=m.length;continue}let f=xn(c,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 xn(e,t){if(e!==void 0&&t!==void 0&&(e===null||t===null||typeof e!="object"||typeof t!="object"))return ce(e)===ce(t)?[]:[{path:"",kind:"changed",before:{op:"$eq",value:e},after:{op:"$eq",value:t}}];let r=e===void 0?[]:B(e),s=t===void 0?[]:B(t),n=l=>`${l.path}::${l.op}`,o=new Map(r.map(l=>[n(l),l])),i=new Map(s.map(l=>[n(l),l])),c=new Set([...o.keys(),...i.keys()]),a=[];for(let l of c){let u=o.get(l),f=i.get(l);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(ce(u.value)===ce(f.value))continue;let d=bn(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 Ge(a),a}function Ge(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 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],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 Te(){console.error(`
945
+ `}function Ot(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function Dt(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}function Rt(e){return join(e,"src")}async function Tt(e,t){let r=Et(t);(!e||!/^[a-z][a-z0-9-]*$/.test(e))&&(console.error(`Invalid module name: ${e||"(none)"}
946
+ 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=>jt.includes(a)):s=jt;let n=Rt(r.dir),o=join(n,`${e}.ts`);existsSync(o)&&(console.error(`File already exists: ${relative(r.dir,o)}`),process.exit(1));let i=dn(e,s);Dt(o,i);let c=relative(r.dir,o);console.log(`${g.green("Created")} ${g.dim(c)}`),s.length===0?console.log(g.dim(" Minimal module (schema + init only)")):console.log(g.dim(` Sections: ${s.join(", ")}`));}async function Ct(e,t){let r=Et(t);(!e||!/^[a-z][a-z0-9-]*$/.test(e))&&(console.error(`Invalid orchestrator name: ${e||"(none)"}
947
+ Must start with a letter, use lowercase letters, numbers, and hyphens.`),process.exit(1));let s=Rt(r.dir),n=join(s,`${e}.ts`);existsSync(n)&&(console.error(`File already exists: ${relative(r.dir,n)}`),process.exit(1));let o=fn(e);Dt(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 pe=typeof process<"u"&&process.env?.NODE_ENV!=="production";function ce(e,t=50){let r=new WeakSet;function s(a){if(a===null)return "null";if(a===void 0)return "undefined";let l=typeof a;if(l==="string")return JSON.stringify(a);if(l==="number"||l==="boolean")return String(a);if(l==="function")return '"[function]"';if(l==="symbol")return '"[symbol]"'}function n(a,l){if(r.has(a))return '"[circular]"';r.add(a);let u=l();return r.delete(a),u}function o(a,l){return n(a,()=>`[${a.map(u=>c(u,l+1)).join(",")}]`)}function i(a,l){return n(a,()=>`{${Object.keys(a).sort().map(u=>`${JSON.stringify(u)}:${c(a[u],l+1)}`).join(",")}}`)}function c(a,l){if(l>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 d=[...a.entries()].sort();return `M:${c(d,l+1)}`}if(a instanceof Set){let d=[...a].sort();return `S:${c(d,l+1)}`}return Array.isArray(a)?o(a,l):typeof a=="object"?i(a,l):'"[unknown]"'}return c(e,0)}var J=new Set(["$eq","$ne","$in","$nin","$exists","$gt","$gte","$lt","$lte","$between","$matches","$startsWith","$endsWith","$contains","$changed"]),Nt=new Set(["$all","$any","$not"]);var K=64;function I(e){return typeof e!="object"||e===null||Array.isArray(e)?false:!(e instanceof Date)&&!(e instanceof RegExp)}function Oe(e){if(typeof e!="object"||e===null||Array.isArray(e))return false;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function Je(e){if(!I(e))return false;let t=0,r=false;for(let s of Object.keys(e)){if(s.startsWith("$"))r=true,J.has(s)||he(`predicate: unknown operator "${s}" \u2014 looks like a typo. Known operators: ${[...J].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=>Oe(t)&&"fact"in t&&"op"in t):Oe(e)}function me(e,t,r="",s=new WeakSet,n=0){if(n>K){pe&&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,c)=>{if(!I(i))return;let a=i;if(typeof a.fact=="string"&&typeof a.op=="string"){let l=r?`${r}[${c}]`:`[${c}]`;t.operator?.(r?`${r}.${a.fact}`:a.fact,a.op,a.value,`${l}.value`);}});return}if(!I(e))return;if(s.has(e)){pe&&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 c=i==="$not"?[o.$not]:o[i]??[];for(let a of c)me(a,t,r,s,n+1);return}for(let i of Object.keys(o)){let c=r?`${r}.${i}`:i;if(i.startsWith("$")){t.strayOperatorKey?.(i,c);continue}let a=o[i];if(Je(a)){let l=a;for(let u of Object.keys(l))t.operator?.(c,u,l[u],`${c}.${u}`);continue}if(Oe(a)){if(t.nested?.(i)===false)continue;me(a,t,c,s,n+1);continue}t.literal?.(c,a);}}function qt(e,t=""){function r(n,o,i,c){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")&&!(c>K)&&!i.has(n)){if(i.add(n),Array.isArray(n)){n.forEach((a,l)=>{r(a,`${o}[${l}]`,i,c+1);});return}for(let a of Object.keys(n))r(n[a],o?`${o}.${a}`:a,i,c+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((c,a)=>{r(c,`${i}[${a}]`,new WeakSet,1);});else if(Oe(n))for(let c of Object.keys(n))r(n[c],`${i}.${c}`,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).`);me(e,{operator(n,o,i,c){s(i,o,t?`${t}.${c}`:c);},literal(n,o){s(o,"",t?`${t}.${n}`:n);}});}function pn(){return {ids:new WeakMap,next:{v:1},pairs:new Set}}function Mt(e,t){let r=e.ids.get(t);return r===void 0&&(r=e.next.v++,e.ids.set(t,r)),r}function q(e,t,r){if(Object.is(e,t))return true;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(typeof e!="object"||typeof t!="object"||e===null||t===null)return false;let s=r??pn(),n=`${Mt(s,e)}:${Mt(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((c,a)=>q(c,t[a],s));if(e instanceof Set||t instanceof Set){if(!(e instanceof Set)||!(t instanceof Set)||e.size!==t.size)return false;let c=[...t];return [...e].every(a=>c.some(l=>q(a,l,s)))}if(e instanceof Map||t instanceof Map){if(!(e instanceof Map)||!(t instanceof Map)||e.size!==t.size)return false;let c=[...t.entries()],a=new Array(c.length).fill(false);for(let[l,u]of e){let d=false;for(let f=0;f<c.length;f++){if(a[f])continue;let[m,$]=c[f];if(q(l,m,s)&&q(u,$,s)){a[f]=true,d=true;break}}if(!d)return false}return true}let o=Object.keys(e),i=Object.keys(t);return o.length!==i.length?false:o.every(c=>Object.hasOwn(t,c)&&q(e[c],t[c],s))}function De(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=De(t),n=De(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 Re(e,t,r,s){switch(e){case "$eq":return q(t,r);case "$ne":return !q(t,r);case "$in":return Array.isArray(r)&&r.some(n=>q(t,n));case "$nin":return Array.isArray(r)&&!r.some(n=>q(t,n));case "$exists":return r===(t!==void 0);case "$changed":return !q(t,s);case "$gt":case "$gte":case "$lt":case "$lte":return Le(e,t,r);case "$between":{if(!Array.isArray(r)||r.length!==2)return false;let n=De(r[0]),o=De(r[1]);return n!==void 0&&o!==void 0&&typeof n==typeof o&&n>o?(he("$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=>q(n,r)):t instanceof Set?t.has(r):false;default:return false}}function he(e){pe&&console.warn(`[Directive] ${e}`);}function mn(e,t,r,s){if(Je(e)){let n=Object.keys(e);n.length>1&&he(`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(!Re(o,t,e[o],r))return false;return true}return I(e)?te(e,I(t)?t:Object.create(null),I(r)?r:void 0,s+1):q(t,e)}function te(e,t,r,s=0){if(s>K)return he(`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(!I(n))return false;let{fact:o,op:i,value:c}=n;return Re(i,t?.[o],c,r?.[o])});if(!I(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(J.has(n))return he(`predicate: operator "${n}" mixed with fact keys \u2014 wrap operators in a per-fact object`),false;if(!mn(e[n],t?.[n],r?.[n],s))return false}return true}function ge(e,t,r,s=""){let n=[];if(Array.isArray(e)){for(let o of e){if(!I(o))continue;let{fact:i,op:c,value:a}=o,l=t?.[i];n.push({path:s+i,op:c,expected:a,actual:l,pass:Re(c,l,a,r?.[i])});}return n}if(!I(e))return n;for(let o of ["$all","$any","$not"])if(o in e){let i=o==="$not"?[e.$not]:e[o],c=[];for(let u of i)c.push(...ge(u,t,r,s));let a=c.filter(u=>u.pass).length,l;return o==="$all"?l=c.length===0||a===c.length:o==="$any"?l=c.length>0&&a>0:l=!c.every(u=>u.pass),n.push({path:s||o,op:o,expected:i.length,actual:a,pass:l,children:c}),n}for(let o of Object.keys(e)){if(J.has(o))continue;let i=e[o],c=t?.[o],a=s+o;if(Je(i))for(let l of Object.keys(i))n.push({path:a,op:l,expected:i[l],actual:c,pass:Re(l,c,i[l],r?.[o])});else I(i)?n.push(...ge(i,I(c)?c:Object.create(null),I(r?.[o])?r?.[o]:void 0,`${a}.`)):n.push({path:a,op:"$eq",expected:i,actual:c,pass:q(c,i)});}return n}var le=1e6;function It(e,t){try{qt(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(me(e,{operator(s,n){r===void 0&&n.startsWith("$")&&!J.has(n)&&(r=n);},strayOperatorKey(s){r===void 0&&!J.has(s)&&!Nt.has(s)&&(r=s);}}),r!==void 0)throw new Error(`[Directive] replayUnder: the ${t} predicate uses an unknown operator "${r}" \u2014 known operators: ${[...J].join(", ")}`)}function ye(e){if(e&&typeof e=="object"&&!Array.isArray(e)&&Array.isArray(e.snapshots))return hn(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 hn(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 ye(e)}function Te(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`);It(r,"original"),It(s,"proposed");let c=0,a=0,l=0,u=0,d=0,f=[],m=[],$=n?new Set:void 0,w=n?new Set:void 0,F;for(let p of t){let y=p.facts,D=te(r,y,F),_=te(s,y,F);D&&(c++,$?.add(y[n])),_&&(a++,w?.add(y[n])),D===_?d++:!D&&_?(l++,f.length<i&&f.push(Wt(p,r,s,F))):(u++,m.length<i&&m.push(Wt(p,r,s,F))),F=y;}let W={framesEvaluated:t.length,original:{matched:c},proposed:{matched:a},delta:a-c,newMatchCount:l,lostMatchCount:u,unchanged:d,newMatches:f,lostMatches:m};return $&&w&&(W.original.matchedEntities=$.size,W.proposed.matchedEntities=w.size),W}function Wt(e,t,r,s){let n=e.facts,o={frameId:e.id,facts:n,originalExplain:ge(t,n,s),proposedExplain:ge(r,n,s)};return e.timestamp!==void 0&&(o.timestamp=e.timestamp),o}var _t=1e4,Ut=5e7;function gn(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(gn(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 yn(e){let t=1;for(let r of Object.values(e))t*=r.length;return t}function Jt(e){let{frames:t,original:r,template:s,sweep:n,objective:o=y=>y.proposed.matched,entityKey:i,maxSamples:c=0}=e,a=Object.keys(n);if(a.length===0)throw new Error("[Directive] sweepUnder: `sweep` must contain at least one hole name");let l=yn(n);if(l>_t)throw new Error(`[Directive] sweepUnder: grid has ${l} points, exceeds the MAX_SWEEP_POINTS limit (${_t}) \u2014 narrow the sweep ranges or split the run`);if(l===0)throw new Error("[Directive] sweepUnder: at least one hole has zero candidate values");let u=l*t.length;if(u>Ut)throw new Error(`[Directive] sweepUnder: ${l} 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 d=false,f=y=>{let D;try{D=o(y);}catch(_){return d||(d=true,console.warn(`[Directive] sweepUnder: objective threw \u2014 point will not rank (${_.message})`)),Number.NEGATIVE_INFINITY}return typeof D!="number"||!Number.isFinite(D)?(d||(d=true,console.warn(`[Directive] sweepUnder: objective returned a non-finite number (${String(D)}) \u2014 point will not rank`)),Number.NEGATIVE_INFINITY):D},m=Te({frames:t,original:r,proposed:r,entityKey:i,maxSamples:c}),$={values:{},report:m,score:f(m)},w=[],F=0,W=Number.NEGATIVE_INFINITY;for(let y of Lt(a,n)){let D=Ke(s,y),_=Te({frames:t,original:r,proposed:D,entityKey:i,maxSamples:c}),Me=f(_);Me>W&&(W=Me,F=w.length),w.push({values:y,report:_,score:Me});}let p=w[F];return {points:w,bestIndex:F,best:p,baseline:$}}function zt(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 $n=new Set(["$eq","$ne","$in","$nin","$exists","$gt","$gte","$lt","$lte","$between","$matches","$startsWith","$endsWith","$contains","$changed"]),vn=new Set(["$all","$any","$not"]);function Kt(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function wn(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;$n.has(s)&&(r=true);}return r}function B(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)=>{B(s,`${t}$all[${n}]`,r);}),r;if("$any"in e&&Array.isArray(e.$any))return e.$any.forEach((s,n)=>{B(s,`${t}$any[${n}]`,r);}),r;if("$not"in e)return B(e.$not,`${t}$not`,r),r;for(let[s,n]of Object.entries(e)){let o=t?`${t}.${s}`:s;if(wn(n))for(let[i,c]of Object.entries(n))r.push({path:o,op:i,value:c});else Kt(n)&&!vn.has(s)?B(n,o,r):r.push({path:o,op:"$eq",value:n});}return r}function G(e){return typeof e=="number"&&Number.isFinite(e)}function bn(e,t,r){switch(e){case "$gte":case "$gt":if(G(t)&&G(r)){if(r<t)return "relaxed";if(r>t)return "tightened"}return null;case "$lte":case "$lt":if(G(t)&&G(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&&G(t[0])&&G(t[1])&&G(r[0])&&G(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 Gt(e){let t=zt(e.before),r=zt(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 c=t[i],a=r[i],l=i in t,u=i in r;if(l&&!u){let f=B(c),m=f.length===0?[{path:"(function-form predicate)",kind:"removed"}]:f.map($=>({path:$.path,kind:"removed",before:{op:$.op,value:$.value}}));Ge(m),n.push({id:i,status:"removed",changes:m}),o.removed++,o.totalClauseChanges+=m.length;continue}if(!l&&u){let f=B(a),m=f.length===0?[{path:"(function-form predicate)",kind:"added"}]:f.map($=>({path:$.path,kind:"added",after:{op:$.op,value:$.value}}));Ge(m),n.push({id:i,status:"added",changes:m}),o.added++,o.totalClauseChanges+=m.length;continue}let d=kn(c,a);d.length===0?(n.push({id:i,status:"unchanged",changes:[]}),o.unchanged++):(n.push({id:i,status:"changed",changes:d}),o.changed++,o.totalClauseChanges+=d.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 ce(e)===ce(t)?[]:[{path:"",kind:"changed",before:{op:"$eq",value:e},after:{op:"$eq",value:t}}];let r=e===void 0?[]:B(e),s=t===void 0?[]:B(t),n=l=>`${l.path}::${l.op}`,o=new Map(r.map(l=>[n(l),l])),i=new Map(s.map(l=>[n(l),l])),c=new Set([...o.keys(),...i.keys()]),a=[];for(let l of c){let u=o.get(l),d=i.get(l);if(u&&!d){a.push({path:u.path,kind:"removed",before:{op:u.op,value:u.value}});continue}if(!u&&d){a.push({path:d.path,kind:"added",after:{op:d.op,value:d.value}});continue}if(u&&d){if(ce(u.value)===ce(d.value))continue;let f=bn(u.op,u.value,d.value);a.push({path:u.path,kind:f??"changed",before:{op:u.op,value:u.value},after:{op:d.op,value:d.value}});}}return Ge(a),a}function Ge(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 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],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 Ce(){console.error(`
915
948
  Usage: directive replay-under --history <frames.json> --proposed <spec.json>
916
949
 
917
950
  Replay a recorded fact-frame history through a proposed constraint
@@ -941,7 +974,7 @@ ${g.bold("replay-under")} \u2014 predicate backtest
941
974
  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
975
  ${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
976
  ${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,c=e.newMatchCount+e.lostMatchCount;i<c&&console.log(g.dim(`
944
- ${i} of ${c} diff frames sampled \u2014 --json for the full report`)),console.log("");}async function Qt(e){(e.includes("--help")||e.length===0)&&(Te(),process.exit(e.length===0?1:0));let t=jn(e);t.historyPath||(console.error(g.red("error: --history <frames.json> is required")),Te(),process.exit(1)),t.proposedPath||(console.error(g.red("error: --proposed <spec.json> is required")),Te(),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)")),Te(),process.exit(1));let r=En(Be(t.historyPath,"--history")),s=Be(t.originalPath,"--original"),n=Be(t.proposedPath,"--proposed");Bt(s)&&console.error(g.yellow("warning: --original is an empty predicate {} \u2014 it matches every frame")),Bt(n)&&console.error(g.yellow("warning: --proposed is an empty predicate {} \u2014 it matches every frame"));let o;try{o=Re({frames:r,original:s,proposed:n,maxSamples:t.maxSamples,entityKey:t.entityKey});}catch(i){console.error(g.red(`error: ${i.message}`)),process.exit(1);}if(t.json){console.log(JSON.stringify(o,null,2));return}On(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(`
977
+ ${i} of ${c} diff frames sampled \u2014 --json for the full report`)),console.log("");}async function Qt(e){(e.includes("--help")||e.length===0)&&(Ce(),process.exit(e.length===0?1:0));let t=jn(e);t.historyPath||(console.error(g.red("error: --history <frames.json> is required")),Ce(),process.exit(1)),t.proposedPath||(console.error(g.red("error: --proposed <spec.json> is required")),Ce(),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)")),Ce(),process.exit(1));let r=En(Be(t.historyPath,"--history")),s=Be(t.originalPath,"--original"),n=Be(t.proposedPath,"--proposed");Bt(s)&&console.error(g.yellow("warning: --original is an empty predicate {} \u2014 it matches every frame")),Bt(n)&&console.error(g.yellow("warning: --proposed is an empty predicate {} \u2014 it matches every frame"));let o;try{o=Te({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}On(o,t.entityKey);}function Cn(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(`
945
978
  Usage: directive replay <timeline.json> [options]
946
979
 
947
980
  Replay a serialized Directive timeline against a fresh system.
@@ -963,8 +996,8 @@ Examples:
963
996
  directive replay bug-1234.json --system src/app/system.ts
964
997
  directive replay error.json --system src/system.ts --json
965
998
  directive replay error.json --system src/system.ts --verbose
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:c}=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 l;try{l=await U(r.systemPath);}catch(d){console.error(g.red(`error: failed to load system file: ${d.message}`)),process.exit(1);}let u=l;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 c(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:$}=f,w=d>0;console.log(`${w?g.green("\u2713"):g.yellow("\u26A0")} replay complete:`,g.bold(`${d} dispatched`),g.dim(`/ ${m} skipped`),$>0?g.yellow(`/ ${$} 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.")),$>0&&console.error(g.yellow(`warning: ${$} frames truncated by --max-frames cap. Raise it with --max-frames <n> if you need them.`));}process.exit(0);}function qn(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 Qe(){console.error(`
999
+ `);}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}=Cn(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(`
1000
+ (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(f){console.error(g.red(`error: failed to read ${s}: ${f.message}`)),process.exit(1);}let o;try{o=JSON.parse(n);}catch(f){console.error(g.red(`error: ${s} is not valid JSON: ${f.message}`)),process.exit(1);}let{deserializeTimeline:i,replayTimeline:c}=await oe(r.verbose),a;try{a=i(o);}catch(f){console.error(g.red(`error: timeline JSON failed validation: ${f.message}`)),process.exit(1);}let l;try{l=await z(r.systemPath);}catch(f){console.error(g.red(`error: failed to load system file: ${f.message}`)),process.exit(1);}let u=l;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 d=await c(a,u,{dispatchableOnly:r.dispatchableOnly,maxFrames:r.maxFrames});if(r.json)console.log(JSON.stringify(d,null,2));else {let{dispatched:f,skipped:m,truncated:$}=d,w=f>0;console.log(`${w?g.green("\u2713"):g.yellow("\u26A0")} replay complete:`,g.bold(`${f} dispatched`),g.dim(`/ ${m} skipped`),$>0?g.yellow(`/ ${$} TRUNCATED`):""),f===0&&console.error(g.yellow("warning: 0 frames dispatched. Either the timeline contains only non-dispatchable frames (system lifecycle, derivations, etc.) or the system shape doesn't match what the timeline recorded.")),$>0&&console.error(g.yellow(`warning: ${$} frames truncated by --max-frames cap. Raise it with --max-frames <n> if you need them.`));}process.exit(0);}function qn(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 Qe(){console.error(`
968
1001
  Usage: directive rules-diff --before <a.json> --after <b.json>
969
1002
 
970
1003
  Structural diff between two snapshots of constraint whenSpec. Reports
@@ -990,10 +1023,10 @@ Or pull one from a git ref:
990
1023
  git show HEAD~1:path/to/snapshot.json > before.json
991
1024
  git show HEAD:path/to/snapshot.json > after.json
992
1025
  directive rules-diff --before before.json --after after.json
993
- `);}function Vt(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 In(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 $e(e){return e.replace(/\|/g,"\\|").replace(/`/g,"'").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Fn(e){let{summary:t,constraints:r}=e;console.log(`
1026
+ `);}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 In(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 $e(e){return e.replace(/\|/g,"\\|").replace(/`/g,"'").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Fn(e){let{summary:t,constraints:r}=e;console.log(`
994
1027
  ${g.bold("rules-diff")} \u2014 structural predicate diff
995
1028
  `),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)"),c=In(o.kind);if(o.kind==="added")console.log(` ${c} ${i} ${H(o.after)}`);else if(o.kind==="removed")console.log(` ${c} ${i} ${H(o.before)}`);else {let a=o.kind==="relaxed"?g.green("relaxed"):o.kind==="tightened"?g.red("tightened"):g.yellow("changed");console.log(` ${c} ${i} ${H(o.before)} ${g.dim("\u2192")} ${H(o.after)} ${g.dim(`[${a}]`)}`);}}console.log("");}}function Wn(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=`\`${$e(o.path||"(predicate)")}\``,c;o.kind==="added"?c=`| \u2795 | ${i} | ${$e(H(o.after))} |`:o.kind==="removed"?c=`| \u2796 | ${i} | ${$e(H(o.before))} |`:c=`| ${o.kind==="relaxed"?"\u25B2 relaxed":o.kind==="tightened"?"\u25BD tightened":"\u2194 changed"} | ${i} | ${$e(H(o.before))} \u2192 ${$e(H(o.after))} |`,console.log(c);}console.log("");}}async function Xt(e){(e.includes("--help")||e.length===0)&&(Qe(),process.exit(e.length===0?1:0));let t=qn(e);t.beforePath||(console.error(g.red("error: --before <a.json> is required")),Qe(),process.exit(1)),t.afterPath||(console.error(g.red("error: --after <b.json> is required")),Qe(),process.exit(1));let r=Vt(t.beforePath,"--before"),s=Vt(t.afterPath,"--after"),n;try{n=Gt({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){Wn(n);return}Fn(n);}function Ln(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(`
1029
+ `);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)"),c=In(o.kind);if(o.kind==="added")console.log(` ${c} ${i} ${H(o.after)}`);else if(o.kind==="removed")console.log(` ${c} ${i} ${H(o.before)}`);else {let a=o.kind==="relaxed"?g.green("relaxed"):o.kind==="tightened"?g.red("tightened"):g.yellow("changed");console.log(` ${c} ${i} ${H(o.before)} ${g.dim("\u2192")} ${H(o.after)} ${g.dim(`[${a}]`)}`);}}console.log("");}}function Wn(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=`\`${$e(o.path||"(predicate)")}\``,c;o.kind==="added"?c=`| \u2795 | ${i} | ${$e(H(o.after))} |`:o.kind==="removed"?c=`| \u2796 | ${i} | ${$e(H(o.before))} |`:c=`| ${o.kind==="relaxed"?"\u25B2 relaxed":o.kind==="tightened"?"\u25BD tightened":"\u2194 changed"} | ${i} | ${$e(H(o.before))} \u2192 ${$e(H(o.after))} |`,console.log(c);}console.log("");}}async function Vt(e){(e.includes("--help")||e.length===0)&&(Qe(),process.exit(e.length===0?1:0));let t=qn(e);t.beforePath||(console.error(g.red("error: --before <a.json> is required")),Qe(),process.exit(1)),t.afterPath||(console.error(g.red("error: --after <b.json> is required")),Qe(),process.exit(1));let r=Xt(t.beforePath,"--before"),s=Xt(t.afterPath,"--after"),n;try{n=Gt({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){Wn(n);return}Fn(n);}function Ln(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
1030
  Usage: directive timeline diff <a.json> <b.json>
998
1031
 
999
1032
  Compare two serialized Directive timelines as a structured causal-graph
@@ -1017,7 +1050,7 @@ Exit codes:
1017
1050
  Examples:
1018
1051
  directive timeline diff baseline.json regression.json
1019
1052
  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 Jn(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 Kn(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}=Ln(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),c=tr(r),a,l;try{a=n(i),l=n(c);}catch(f){console.error(g.red(`error: timeline JSON failed validation: ${f.message}`)),process.exit(1);}let u=o(a,l);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 Jn(u.resolverRuns))console.log(f);console.log(""),console.log(g.bold("New errors:"));for(let f of Kn(u.newErrors))console.log(f);console.log(""),process.exit(2);}function Qn(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(`
1053
+ `);}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 Jn(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 Kn(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}=Ln(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),c=tr(r),a,l;try{a=n(i),l=n(c);}catch(d){console.error(g.red(`error: timeline JSON failed validation: ${d.message}`)),process.exit(1);}let u=o(a,l);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 d of er(u.constraintFires))console.log(d);console.log(""),console.log(g.bold("Mutations:"));for(let d of er(u.mutations))console.log(d);console.log(""),console.log(g.bold("Resolver runs:"));for(let d of Jn(u.resolverRuns))console.log(d);console.log(""),console.log(g.bold("New errors:"));for(let d of Kn(u.newErrors))console.log(d);console.log(""),process.exit(2);}function Qn(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
1054
  Usage: directive tune --history <frames.json> --original <orig.json> \\
1022
1055
  --template <tmpl.json> --sweep <key:range>
1023
1056
 
@@ -1040,13 +1073,13 @@ Example:
1040
1073
  directive tune --history sessions.json \\
1041
1074
  --original current.json --template proposed-template.json \\
1042
1075
  --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 Yn(e){try{return ye(e)}catch(t){console.error(g.red(`error: ${t.message}`)),process.exit(1);}}function Vn(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[,c,a,l]=n,u=Number(c),f=Number(a),d=l?Number(l):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 $=u;$<=f+1e-9;$+=d)m.push(Math.round($*1e6)/1e6);return [r,m]}let o=s.split(",").map(c=>c.trim()).filter(c=>c.length>0);o.length===0&&(console.error(g.red(`error: --sweep ${e}: no values after ':'`)),process.exit(1));let i=o.map(c=>{let a=Number(c);return Number.isNaN(a)?c:a});return [r,i]}var Ve=["\u2581","\u2582","\u2583","\u2584","\u2585","\u2586","\u2587","\u2588"];function Xn(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,l=r.map(d=>{let m=a>0?(d.score-i)/a:0;return Ve[Math.min(Ve.length-1,Math.round(m*(Ve.length-1)))]}).join("");console.log(`
1076
+ `);}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 Yn(e){try{return ye(e)}catch(t){console.error(g.red(`error: ${t.message}`)),process.exit(1);}}function Xn(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[,c,a,l]=n,u=Number(c),d=Number(a),f=l?Number(l):1;f<=0&&(console.error(g.red(`error: --sweep ${e}: step must be positive`)),process.exit(1)),d<u&&(console.error(g.red(`error: --sweep ${e}: end (${d}) must be >= start (${u})`)),process.exit(1));let m=[];for(let $=u;$<=d+1e-9;$+=f)m.push(Math.round($*1e6)/1e6);return [r,m]}let o=s.split(",").map(c=>c.trim()).filter(c=>c.length>0);o.length===0&&(console.error(g.red(`error: --sweep ${e}: no values after ':'`)),process.exit(1));let i=o.map(c=>{let a=Number(c);return Number.isNaN(a)?c:a});return [r,i]}var Xe=["\u2581","\u2582","\u2583","\u2584","\u2585","\u2586","\u2587","\u2588"];function Vn(e,t){let r=e.points;Math.max(...r.map(f=>f.report.proposed.matched));let n=e.baseline.report.original.matched,o=r.map(f=>f.score),i=Math.min(...o),a=Math.max(...o)-i,l=r.map(f=>{let m=a>0?(f.score-i)/a:0;return Xe[Math.min(Xe.length-1,Math.round(m*(Xe.length-1)))]}).join("");console.log(`
1044
1077
  ${g.bold("directive tune")} \u2014 parameter sweep`),console.log(`
1045
1078
  frames evaluated ${r[0]?.report.framesEvaluated??0}`),console.log(` baseline (current) matched ${n} frames`),console.log(` points evaluated ${r.length}
1046
1079
  `),console.log(` sparkline ${g.cyan(l)}
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(" "),$=d.report.proposed.matched,w=d.report.delta,F=t?String(d.report.proposed.matchedEntities??"").padStart(8):"",W=w>0?g.green(`+${w}`.padStart(7)):w<0?g.red(`${w}`.padStart(7)):g.dim("\xB10".padStart(7)),p=a>0?Math.round((d.score-i)/a*24):0,y=m+" "+String($).padStart(8)+" "+W+(t?" "+F:"")+" "+"\u2588".repeat(p).padEnd(24),D=d===e.best;console.log(D?g.green(" "+y):" "+y);}console.log(`
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=Qn(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=Yn(Ye(t.historyPath,"--history")),s=Ye(t.originalPath,"--original"),n=Ye(t.templatePath,"--template"),o={};for(let c of t.sweepArgs){let[a,l]=Vn(c);o[a]=l;}let i;try{i=Jt({frames:r,original:s,template:n,sweep:o,entityKey:t.entityKey});}catch(c){console.error(g.red(`error: ${c.message}`)),process.exit(1);}if(t.json){console.log(JSON.stringify(i,null,2));return}Xn(i,t.entityKey);}var Zn=`
1080
+ `);let u=Object.keys(r[0]?.values??{}),d=`${u.map(f=>f.padEnd(12)).join(" ")} ${"matched".padStart(8)} ${"delta".padStart(7)}${t?` ${`${t}s`.padStart(8)}`:""} bar`;console.log(g.dim(` ${d}`));for(let f of r){let m=u.map(_=>String(f.values[_]??"").padEnd(12)).join(" "),$=f.report.proposed.matched,w=f.report.delta,F=t?String(f.report.proposed.matchedEntities??"").padStart(8):"",W=w>0?g.green(`+${w}`.padStart(7)):w<0?g.red(`${w}`.padStart(7)):g.dim("\xB10".padStart(7)),p=a>0?Math.round((f.score-i)/a*24):0,y=`${m} ${String($).padStart(8)} ${W}${t?` ${F}`:""} ${"\u2588".repeat(p).padEnd(24)}`,D=f===e.best;console.log(D?g.green(` ${y}`):` ${y}`);}console.log(`
1081
+ ${g.bold(g.green("best"))} \u2014 ${u.map(f=>`${f}=${e.best.values[f]}`).join(", ")} \u2192 matched ${e.best.report.proposed.matched} (score ${e.best.score})
1082
+ `);}async function nr(e){(e.includes("--help")||e.length===0)&&(we(),process.exit(e.length===0?1:0));let t=Qn(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=Yn(Ye(t.historyPath,"--history")),s=Ye(t.originalPath,"--original"),n=Ye(t.templatePath,"--template"),o={};for(let c of t.sweepArgs){let[a,l]=Xn(c);o[a]=l;}let i;try{i=Jt({frames:r,original:s,template:n,sweep:o,entityKey:t.entityKey});}catch(c){console.error(g.red(`error: ${c.message}`)),process.exit(1);}if(t.json){console.log(JSON.stringify(i,null,2));return}Vn(i,t.entityKey);}var Zn=`
1050
1083
  ${O} \u2014 CLI tools for Directive
1051
1084
 
1052
1085
  Usage: ${O} <command> [options]
@@ -1110,14 +1143,14 @@ ai-rules init options:
1110
1143
  examples options:
1111
1144
  --filter <category> Filter by category or name
1112
1145
  --dest <dir> Destination directory for copy
1113
- `.trim();async function es(){let e=process.argv.slice(2),t=e[0];if((e.length===0||t==="--help"||t==="-h")&&(console.log(Zn),process.exit(0)),t==="--version"||t==="-v"){let{readFileSync:n}=await import('fs'),{fileURLToPath:o}=await import('url'),{dirname:i,join:c}=await import('path'),a=i(o(import.meta.url)),l=JSON.parse(n(c(a,"..","package.json"),"utf-8"));console.log(l.version),process.exit(0);}let s=e[0];switch(s){case "init":{await St(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 Rt(o,e.slice(3))):n==="orchestrator"?(o||(console.error("Usage: directive new orchestrator <name>"),process.exit(1)),await Tt(o,e.slice(3))):(console.error(`Unknown subcommand: ${n??"(none)"}
1146
+ `.trim();async function es(){let e=process.argv.slice(2),t=e[0];if((e.length===0||t==="--help"||t==="-h")&&(console.log(Zn),process.exit(0)),t==="--version"||t==="-v"){let{readFileSync:n}=await import('fs'),{fileURLToPath:o}=await import('url'),{dirname:i,join:c}=await import('path'),a=i(o(import.meta.url)),l=JSON.parse(n(c(a,"..","package.json"),"utf-8"));console.log(l.version),process.exit(0);}let s=e[0];switch(s){case "init":{await St(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 Tt(o,e.slice(3))):n==="orchestrator"?(o||(console.error("Usage: directive new orchestrator <name>"),process.exit(1)),await Ct(o,e.slice(3))):(console.error(`Unknown subcommand: ${n??"(none)"}
1114
1147
  Usage: ${O} new module <name>
1115
- ${O} new orchestrator <name>`),process.exit(1));break}case "inspect":{await At(e.slice(1));break}case "explain":{await xt(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 ct(e.slice(2)):n==="check"?await lt(e.slice(2)):(console.error(`Unknown subcommand: ${n??"(none)"}
1148
+ ${O} new orchestrator <name>`),process.exit(1));break}case "inspect":{await At(e.slice(1));break}case "explain":{await kt(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 ct(e.slice(2)):n==="check"?await lt(e.slice(2)):(console.error(`Unknown subcommand: ${n??"(none)"}
1116
1149
  Usage: ${O} ai-rules init
1117
1150
  ${O} ai-rules update
1118
1151
  ${O} ai-rules check`),process.exit(1));break}case "examples":{let n=e[1];if(n==="list")await vt(e.slice(2));else if(n==="copy"){let o=e[2];o||(console.error("Usage: directive examples copy <name>"),process.exit(1)),await wt(o,e.slice(3));}else console.error(`Unknown subcommand: ${n??"(none)"}
1119
1152
  Usage: ${O} examples list [--filter <category>]
1120
- ${O} examples copy <name> [--dest <dir>]`),process.exit(1);break}case "replay":{await Yt(e.slice(1));break}case "replay-under":{await Qt(e.slice(1));break}case "tune":{await nr(e.slice(1));break}case "rules-diff":{await Xt(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)"}
1153
+ ${O} examples copy <name> [--dest <dir>]`),process.exit(1);break}case "replay":{await Yt(e.slice(1));break}case "replay-under":{await Qt(e.slice(1));break}case "tune":{await nr(e.slice(1));break}case "rules-diff":{await Vt(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
1154
  Usage: ${O} timeline diff <a.json> <b.json>`),process.exit(1));break}default:console.error(`Unknown command: ${s}
1122
1155
  Run '${O} --help' for usage.`),process.exit(1);}}es().catch(e=>{console.error(e.message||e),process.exit(1);});//# sourceMappingURL=cli.js.map
1123
1156
  //# sourceMappingURL=cli.js.map