@directive-run/cli 1.3.0 → 1.5.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/README.md +69 -0
- package/dist/cli.js +206 -82
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +7 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/package.json +13 -4
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import {existsSync,readFileSync,mkdirSync,writeFileSync,readdirSync}from'fs';import {resolve,join,relative,dirname}from'path';import*as p from'@clack/prompts';import f from'picocolors';import {getAllExamples,getExample,getKnowledge}from'@directive-run/knowledge';var x="directive";var V="<!-- directive:start -->",H="<!-- directive:end -->";var oe=[{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 he(e){let t=[];for(let r of oe)r.signals.some(o=>existsSync(join(e,o)))&&t.push({name:r.name,id:r.id,outputPath:join(e,r.outputPath)});return t}function K(e){let t=oe.find(r=>r.id===e);if(!t)throw new Error(`Unknown tool: ${e}`);return t}function ye(){return oe.map(e=>e.id)}function L(e,t){let r=e.indexOf(V),s=e.indexOf(H),o=`${V}
|
|
3
3
|
${t}
|
|
4
|
-
${
|
|
4
|
+
${H}`;if(r!==-1&&s!==-1&&s>r)return e.slice(0,r)+o+e.slice(s+H.length);let i=e.endsWith(`
|
|
5
5
|
`)?`
|
|
6
6
|
`:`
|
|
7
7
|
|
|
8
8
|
`;return e+i+o+`
|
|
9
|
-
`}function
|
|
9
|
+
`}function G(e){return e.includes(V)&&e.includes(H)}var ot=[{file:"pnpm-workspace.yaml",tool:"pnpm"},{file:"turbo.json",tool:"turbo"}];function be(e){let t=resolve(e);for(;t!==dirname(t);){for(let s of ot)if(existsSync(join(t,s.file)))return {isMonorepo:true,rootDir:t,tool:s.tool};let r=join(t,"package.json");if(existsSync(r))try{if(JSON.parse(readFileSync(r,"utf-8")).workspaces){let o=existsSync(join(t,"yarn.lock"))?"yarn":"npm";return {isMonorepo:!0,rootDir:t,tool:o}}}catch{}t=dirname(t);}return {isMonorepo:false,rootDir:e}}function xe(){let e=getKnowledge("core-patterns"),t=getKnowledge("anti-patterns"),r=getKnowledge("naming"),s=getKnowledge("schema-types");return `# Directive \u2014 Complete AI Coding Rules
|
|
10
10
|
|
|
11
11
|
> Constraint-driven runtime for TypeScript. Declare requirements, let the runtime resolve them.
|
|
12
12
|
> https://directive.run | \`npm install @directive-run/core\`
|
|
@@ -226,7 +226,7 @@ for await (const chunk of streamResult.stream) {
|
|
|
226
226
|
\`\`\`
|
|
227
227
|
|
|
228
228
|
Backpressure: \`"buffer"\` (default), \`"block"\`, \`"drop"\`
|
|
229
|
-
`}function
|
|
229
|
+
`}function Q(){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 z(){return Q()+"\n## Anti-Patterns 11-19\n\n| # | WRONG | CORRECT |\n|---|-------|---------|\n| 11 | Returning data from `resolve` | Resolvers return `void` \u2014 mutate `context.facts` |\n| 12 | Async logic in `init` | `init` is synchronous, facts assignment only |\n| 13 | `await system.start()` without settle | Add `await system.settle()` after start |\n| 14 | Missing `crossModuleDeps` | Declare `crossModuleDeps: { auth: authSchema }` |\n| 15 | `require: \"TYPE\"` string literal | `require: { type: \"TYPE\" }` object form |\n| 16 | Passthrough derivation `(f) => f.count` | Remove \u2014 read fact directly |\n| 17 | `from '@directive-run/core/module'` | `from '@directive-run/core'` (main export) |\n| 18 | `async when()` without `deps` | Add `deps: ['factName']` for async constraints |\n| 19 | No error boundary on resolver | Use try-catch or module error boundary config |\n"+`
|
|
230
230
|
## Multi-Module
|
|
231
231
|
|
|
232
232
|
\`\`\`typescript
|
|
@@ -259,10 +259,119 @@ const result = await orchestrator.run(agent, "analyze this");
|
|
|
259
259
|
- Subpath imports: \`from '@directive-run/ai/anthropic'\` not \`from '@directive-run/ai'\`
|
|
260
260
|
- Token usage normalized: \`{ inputTokens, outputTokens }\` (not provider-specific)
|
|
261
261
|
- \`facts.cache = [...facts.cache, item]\` not \`facts.cache.push(item)\`
|
|
262
|
-
`}function
|
|
263
|
-
Updated ${o} file(s) to latest knowledge version.`));}async function
|
|
264
|
-
${
|
|
265
|
-
All rule files are current.`));}function
|
|
262
|
+
`}function $e(){return z()}function ke(){return z()}var at={cursor:Q,claude:xe,copilot:z,windsurf:ke,cline:$e};function Z(e){let t=at[e];if(!t)throw new Error(`No template for tool: ${e}`);return t()}function ue(e){let t={force:false,merge:false,tools:[],dir:process.cwd()};for(let r=0;r<e.length;r++)switch(e[r]){case "--force":t.force=true;break;case "--merge":t.merge=true;break;case "--tool":{let o=e[++r];o&&t.tools.push(o);break}case "--dir":{let o=e[++r];o&&(t.dir=o);break}}return t}async function Se(e){let t=ue(e);p.intro(f.bgCyan(f.black(" directive ai-rules ")));let r=be(t.dir),s=t.dir;if(r.isMonorepo&&r.rootDir!==t.dir){let n=await p.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)})`}]});p.isCancel(n)&&(p.cancel("Cancelled."),process.exit(0)),n==="root"&&(s=r.rootDir);}let o;if(t.tools.length>0)o=t.tools.map(n=>{let a=K(n);return {name:a.name,id:a.id,outputPath:join(s,a.outputPath)}});else {let n=he(s);if(n.length>0){let a=await p.multiselect({message:`Detected ${n.length} AI tool(s). Which should get Directive rules?`,options:n.map(c=>({value:c.id,label:c.name,hint:relative(s,c.outputPath)})),initialValues:n.map(c=>c.id),required:true});p.isCancel(a)&&(p.cancel("Cancelled."),process.exit(0)),o=a.map(c=>{let m=K(c);return {name:m.name,id:m.id,outputPath:join(s,m.outputPath)}});}else {let a=await p.multiselect({message:"No AI tools detected. Which tools do you use?",options:ye().map(c=>{let m=K(c);return {value:c,label:m.name}}),required:true});p.isCancel(a)&&(p.cancel("Cancelled."),process.exit(0)),o=a.map(c=>{let m=K(c);return {name:m.name,id:m.id,outputPath:join(s,m.outputPath)}});}}o.length===0&&(p.cancel("No tools selected."),process.exit(0));let i=p.spinner();for(let n of o){i.start(`Generating ${n.name} rules...`);let a=Z(n.id),c=n.outputPath,m=existsSync(c);if(i.stop(`Generated ${n.name} rules.`),m&&!t.force){let d=readFileSync(c,"utf-8");if(t.merge){q(c,L(d,a)),p.log.success(`${f.green("Merged")} Directive section into ${f.dim(relative(s,c))}`);continue}if(G(d)){let l=await p.select({message:`${relative(s,c)} already has a Directive section. What should we do?`,options:[{value:"merge",label:"Update Directive section only",hint:"recommended"},{value:"overwrite",label:"Overwrite entire file"},{value:"skip",label:"Skip this file"}]});p.isCancel(l)&&(p.cancel("Cancelled."),process.exit(0)),l==="merge"?(q(c,L(d,a)),p.log.success(`${f.green("Updated")} ${f.dim(relative(s,c))}`)):l==="overwrite"?(q(c,a),p.log.success(`${f.green("Wrote")} ${f.dim(relative(s,c))}`)):p.log.info(`Skipped ${f.dim(relative(s,c))}`);}else {let l=await p.select({message:`${relative(s,c)} already exists. What should we do?`,options:[{value:"append",label:"Append Directive section",hint:"preserves existing content"},{value:"overwrite",label:"Overwrite entire file"},{value:"skip",label:"Skip this file"}]});p.isCancel(l)&&(p.cancel("Cancelled."),process.exit(0)),l==="append"?(q(c,L(d,a)),p.log.success(`${f.green("Appended")} to ${f.dim(relative(s,c))}`)):l==="overwrite"?(q(c,a),p.log.success(`${f.green("Wrote")} ${f.dim(relative(s,c))}`)):p.log.info(`Skipped ${f.dim(relative(s,c))}`);}}else q(c,a),p.log.success(`${f.green("Created")} ${f.dim(relative(s,c))}`);}p.outro(`Done! Run ${f.cyan(`${x} 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 Ce(e){let r=ue(e).dir,s=[{id:"cursor",path:join(r,".cursorrules")},{id:"claude",path:join(r,".claude/CLAUDE.md")},{id:"copilot",path:join(r,".github/copilot-instructions.md")},{id:"windsurf",path:join(r,".windsurfrules")},{id:"cline",path:join(r,".clinerules")}],o=0;for(let i of s){if(!existsSync(i.path))continue;let n=readFileSync(i.path,"utf-8");if(!G(n))continue;let a=Z(i.id),c=L(n,a);q(i.path,c),console.log(`${f.green("Updated")} ${f.dim(relative(r,i.path))}`),o++;}console.log(o===0?f.dim(`No existing rule files found. Run ${f.cyan(`${x} ai-rules init`)} first.`):f.green(`
|
|
263
|
+
Updated ${o} file(s) to latest knowledge version.`));}async function Re(e){let r=ue(e).dir,s=[{id:"cursor",path:join(r,".cursorrules"),name:"Cursor"},{id:"claude",path:join(r,".claude/CLAUDE.md"),name:"Claude Code"},{id:"copilot",path:join(r,".github/copilot-instructions.md"),name:"GitHub Copilot"},{id:"windsurf",path:join(r,".windsurfrules"),name:"Windsurf"},{id:"cline",path:join(r,".clinerules"),name:"Cline"}],o=0,i=0;for(let n of s){if(!existsSync(n.path))continue;let a=readFileSync(n.path,"utf-8");if(!G(a))continue;o++;let c=Z(n.id);L(a,c)!==a?(console.log(`${f.red("\u2717")} ${n.name} rules are ${f.yellow("stale")}`),i++):console.log(`${f.green("\u2713")} ${n.name} rules are ${f.green("current")}`);}if(o===0){console.log(f.dim("No rule files found to check."));return}i>0?(console.log(`
|
|
264
|
+
${f.yellow(`${i} file(s) are stale.`)} Run ${f.cyan(`${x} ai-rules update`)} to refresh.`),process.exit(1)):console.log(f.green(`
|
|
265
|
+
All rule files are current.`));}async function M(e){let t=resolve(e);if(!existsSync(t))throw new Error(`File not found: ${t}`);try{let r=await import(t);if(r.default&&I(r.default))return r.default;if(r.system&&I(r.system))return r.system;for(let s of Object.keys(r))if(I(r[s]))return r[s];throw new Error(`No Directive system found in ${f.dim(e)}
|
|
266
|
+
Export a system as default or named "system":
|
|
267
|
+
|
|
268
|
+
${f.cyan("export default")} createSystem({ module: myModule });
|
|
269
|
+
${f.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 ${f.dim(e)}: ${r instanceof Error?r.message:String(r)}
|
|
270
|
+
|
|
271
|
+
Make sure the file is valid TypeScript and tsx is installed:
|
|
272
|
+
${f.cyan("npm install -D tsx")}`)}}function I(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 Oe(e){let t=resolve(e);if(!existsSync(t))throw new Error(`File not found: ${t}`);let r;try{r=await import(t);}catch(i){throw new Error(`Failed to load ${f.dim(e)}: ${i instanceof Error?i.message:String(i)}
|
|
273
|
+
|
|
274
|
+
Make sure the file is valid TypeScript and tsx is installed:
|
|
275
|
+
${f.cyan("npm install -D tsx")}`)}let s=[["createSystem",r.createSystem],["systemFactory",r.systemFactory],["default",r.default]];for(let[i,n]of s)if(typeof n=="function")return async()=>{let a=await Promise.resolve(n());if(!I(a))throw new Error(`Factory '${i}' from ${f.dim(e)} returned a value that is not a started Directive system.
|
|
276
|
+
Expected an object with inspect/start/stop/facts. The factory must call sys.start() before returning.`);return a};throw I(r.default)||I(r.system)||Object.values(r).some(I)?new Error(`Found a started Directive system in ${f.dim(e)}, but bisect needs a factory.
|
|
277
|
+
Bisect instantiates a fresh system for every midpoint replay (so each attempt is hermetic),
|
|
278
|
+
which means it can't reuse a singleton instance the way ${f.cyan("directive replay")} does.
|
|
279
|
+
|
|
280
|
+
Wrap the existing export in a function:
|
|
281
|
+
|
|
282
|
+
${f.cyan("export function createSystem()")} {
|
|
283
|
+
const sys = createSystem({ module: yourModule });
|
|
284
|
+
sys.start();
|
|
285
|
+
return sys;
|
|
286
|
+
}`):new Error(`No system factory found in ${f.dim(e)}
|
|
287
|
+
Bisect needs to instantiate a fresh system per midpoint replay. Export one of:
|
|
288
|
+
|
|
289
|
+
${f.cyan("export function createSystem()")} { ... return sys; }
|
|
290
|
+
${f.cyan("export const systemFactory")} = () => { ... return sys; };
|
|
291
|
+
${f.cyan("export default")} () => { ... return sys; };
|
|
292
|
+
|
|
293
|
+
The factory MUST call sys.start() and return the started system.
|
|
294
|
+
(Did you forget ${f.cyan("sys.start()")} before returning?)`)}async function _(e=false){try{return await import('@directive-run/timeline')}catch(t){console.error(f.red(`error: @directive-run/timeline not installed in this project.
|
|
295
|
+
Install it: npm install --save-dev @directive-run/timeline`)),e&&console.error(f.dim(t.message)),process.exit(1);}}function ft(e){let t={json:false,noDeterminismCheck:false,verbose:false},r="";for(let s=0;s<e.length;s++){let o=e[s];switch(o){case "--system":case "-s":{let i=e[++s];i&&(t.systemPath=i);break}case "--assert":case "-a":{let i=e[++s];i&&(t.assertExpr=i);break}case "--max-frames":{let i=e[++s],n=i?Number.parseInt(i,10):Number.NaN;Number.isFinite(n)&&n>0&&(t.maxFrames=n);break}case "--no-determinism-check":t.noDeterminismCheck=true;break;case "--json":t.json=true;break;case "--verbose":case "-v":t.verbose=true;break;default:o&&!o.startsWith("-")&&!r&&(r=o);}}return {jsonPath:r,opts:t}}function te(){console.error(`
|
|
296
|
+
Usage: directive bisect <timeline.json> --system <factory.ts> --assert <expr>
|
|
297
|
+
|
|
298
|
+
Binary-search a recorded timeline for the first frame that triggers a
|
|
299
|
+
failing assertion \u2014 git-bisect, but over ObservationEvent frames.
|
|
300
|
+
|
|
301
|
+
Arguments:
|
|
302
|
+
<timeline.json> Path to a timeline produced by serializeTimeline()
|
|
303
|
+
|
|
304
|
+
Options:
|
|
305
|
+
--system, -s <path> TypeScript file exporting a system factory
|
|
306
|
+
(createSystem / systemFactory / default).
|
|
307
|
+
The factory must return a started Directive
|
|
308
|
+
system; bisect calls it once per midpoint.
|
|
309
|
+
--assert, -a <expression> JS expression with 'facts' and 'system' in
|
|
310
|
+
scope. Truthy = good prefix, falsy = bad
|
|
311
|
+
prefix. Bisect finds the smallest bad prefix.
|
|
312
|
+
--max-frames <n> Per-replay frame cap (default 100,000)
|
|
313
|
+
--no-determinism-check Skip the "replay-twice and compare" gate
|
|
314
|
+
before bisecting. Use only on timelines you
|
|
315
|
+
know are deterministic.
|
|
316
|
+
--json Emit BisectResult as JSON
|
|
317
|
+
--verbose, -v Print every midpoint and its verdict
|
|
318
|
+
--help, -h Show this help
|
|
319
|
+
|
|
320
|
+
SECURITY: --assert is evaluated as JavaScript in this process. Only
|
|
321
|
+
pass expressions from sources you trust (your own scripts, your own
|
|
322
|
+
PRs). Don't paste expressions from issues, untrusted Slack messages,
|
|
323
|
+
or third-party sources without reading them first.
|
|
324
|
+
|
|
325
|
+
Examples:
|
|
326
|
+
directive bisect bug-1234.json --system test/bisect-sys.ts \\
|
|
327
|
+
--assert 'facts.count >= 0'
|
|
328
|
+
|
|
329
|
+
directive bisect crash.json -s factory.ts -a 'facts.status !== "error"' --json
|
|
330
|
+
`);}function gt(e){let t;try{t=new Function("facts","system",`"use strict"; return (${e});`);}catch(r){throw new Error(`Failed to compile --assert expression: ${r.message}
|
|
331
|
+
expression: ${e}`)}return r=>{let s=r?.facts;return !!t(s,r)}}async function Ee(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(te(),process.exit(e.length===0?1:0));let{jsonPath:t,opts:r}=ft(e);t||(console.error(f.red("error: missing <timeline.json> argument")),te(),process.exit(1)),r.systemPath||(console.error(f.red("error: --system <path> is required"),f.dim(`
|
|
332
|
+
(bisect needs a factory to instantiate a fresh system per midpoint)`)),te(),process.exit(1)),r.assertExpr||(console.error(f.red("error: --assert <expression> is required"),f.dim(`
|
|
333
|
+
(assertion distinguishes 'good' from 'bad' system state)`)),te(),process.exit(1));let s=resolve(t);existsSync(s)||(console.error(f.red(`error: timeline file not found: ${s}`)),process.exit(1));let o;try{o=readFileSync(s,"utf8");}catch(C){console.error(f.red(`error: failed to read ${s}: ${C.message}`)),process.exit(1);}let i;try{i=JSON.parse(o);}catch(C){console.error(f.red(`error: ${s} is not valid JSON: ${C.message}`)),process.exit(1);}let{deserializeTimeline:n,bisectTimeline:a}=await _(r.verbose),c;try{c=n(i);}catch(C){console.error(f.red(`error: timeline JSON failed validation: ${C.message}`)),process.exit(1);}let m;try{m=gt(r.assertExpr);}catch(C){console.error(f.red(`error: ${C.message}`)),process.exit(1);}let d;try{d=await Oe(r.systemPath);}catch(C){console.error(f.red(`error: failed to load system factory: ${C.message}`)),process.exit(1);}r.verbose&&console.error(f.dim(`bisecting ${c.frames.length} frames with assertion: ${r.assertExpr}`));let l=await a(c,d,m,{maxFrames:r.maxFrames,determinismCheck:!r.noDeterminismCheck});if(r.json){let C={firstFailingFrameIndex:l.firstFailingFrameIndex??null,iterations:l.iterations,noFailureFound:l.noFailureFound,failsOnEmptyReplay:l.failsOnEmptyReplay,nonDeterministic:l.nonDeterministic};console.log(JSON.stringify(C,null,2)),process.exit(0);}l.nonDeterministic&&(console.error(f.red("\u2717 bisect aborted: timeline is non-deterministic")),console.error(f.dim(` Two full-timeline replays produced different oracle verdicts.
|
|
334
|
+
Bisection is unreliable on non-deterministic timelines.
|
|
335
|
+
Either fix the timeline source (deterministic clocks/seeds)
|
|
336
|
+
or re-run with --no-determinism-check if you accept the risk.`)),process.exit(2)),l.noFailureFound&&(console.error(f.yellow("\u26A0 no failure to bisect: assertion passes on the full timeline")),console.error(f.dim(` The recorded timeline does not exhibit the bug your
|
|
337
|
+
--assert expression checks. Verify the assertion or
|
|
338
|
+
try a different bad.json.`)),process.exit(0)),l.failsOnEmptyReplay&&(console.error(f.yellow("\u26A0 assertion fails BEFORE any frame replays \u2014 bug is in initialization")),console.error(f.dim(` The freshly-started system already violates the assertion.
|
|
339
|
+
Bisect cannot narrow further. Inspect the system factory
|
|
340
|
+
or initial fact values.`)),process.exit(0));let h=l.firstFailingFrameIndex??-1,T=l.firstFailingFrame,j=T?.event.type??"<unknown>";console.log(`${f.green("\u2713")} bisect complete: ${f.bold(`first failing frame is #${h}`)} ${f.dim(`(${j})`)}`),console.log(f.dim(` \u2022 iterations: ${l.iterations} | timeline frames: ${c.frames.length}`)),r.verbose&&T&&(console.log(f.dim(" \u2022 frame:")),console.log(f.dim(` ${JSON.stringify(T,null,2).split(`
|
|
341
|
+
`).join(`
|
|
342
|
+
`)}`))),process.exit(2);}function yt(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 vt(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 bt(e){let t=join(e,"package.json");if(!existsSync(t))return {label:"Package version compatibility",passed:true,message:"Skipped (no package.json)"};let r=JSON.parse(readFileSync(t,"utf-8")),s={...r.dependencies,...r.devDependencies},o=Object.keys(s).filter(i=>i.startsWith("@directive-run/"));return o.length<=1?{label:"Package version compatibility",passed:true,message:o.length===0?"No packages found":"Single package"}:{label:"Package version compatibility",passed:true,message:`${o.length} packages: ${o.join(", ")}`}}function wt(e){let t=join(e,"tsconfig.json");if(!existsSync(t))return {label:"TypeScript configuration",passed:false,message:"No tsconfig.json found",fix:"Run `tsc --init` to create a TypeScript configuration"};try{let s=readFileSync(t,"utf-8").replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,""),i=JSON.parse(s).compilerOptions||{},n=[];return i.strict!==!0&&n.push("strict mode not enabled"),i.moduleResolution&&!["bundler","nodenext","node16"].includes(i.moduleResolution.toLowerCase())&&n.push(`moduleResolution is "${i.moduleResolution}"`),n.length>0?{label:"TypeScript configuration",passed:!1,message:n.join(", "),fix:'Set "strict": true and "moduleResolution": "bundler" in tsconfig.json'}:{label:"TypeScript configuration",passed:!0,message:"strict mode, correct module resolution"}}catch{return {label:"TypeScript configuration",passed:true,message:"Found (could not parse for detailed checks)"}}}function xt(e){let t=join(e,"node_modules");if(!existsSync(t))return {label:"No duplicate Directive instances",passed:true,message:"No node_modules found"};let r=[];try{let s=join(t,"@directive-run");if(existsSync(s)){let o=readdirSync(s);for(let i of o){let n=join(s,i,"node_modules","@directive-run","core");existsSync(n)&&r.push(`@directive-run/${i}/node_modules/@directive-run/core`);}}}catch{}return r.length>0?{label:"No duplicate Directive instances",passed:false,message:`Found ${r.length} duplicate(s): ${r.join(", ")}`,fix:"Run `npm dedupe` or check for version mismatches"}:{label:"No duplicate Directive instances",passed:true,message:"No duplicates detected"}}function $t(e){let t=[".cursorrules",".claude/CLAUDE.md",".github/copilot-instructions.md",".windsurfrules",".clinerules"],r=[];for(let s of t){let o=join(e,s);if(existsSync(o)){let i=readFileSync(o,"utf-8");G(i)&&r.push(s);}}return r.length===0?{label:"AI coding rules",passed:true,message:"Not installed (optional)"}:{label:"AI coding rules",passed:true,message:`Installed for: ${r.join(", ")}`}}async function je(e){let t=yt(e);console.log(),console.log(f.bold(f.cyan("Directive Doctor"))),console.log(f.dim("\u2500".repeat(40))),console.log();let r=[vt(t.dir),bt(t.dir),wt(t.dir),xt(t.dir),$t(t.dir)],s=0;for(let o of r){let i=o.passed?f.green("\u2713"):f.red("\u2717");console.log(`${i} ${f.bold(o.label)}`),console.log(` ${f.dim(o.message)}`),!o.passed&&o.fix&&(console.log(` ${f.yellow("Fix:")} ${o.fix}`),s++),console.log();}s>0?(console.log(f.yellow(`${s} issue(s) found. See suggested fixes above.`)),process.exit(1)):console.log(f.green("All checks passed!"));}var qe={"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 At(e){for(let[t,r]of Object.entries(qe))if(r.includes(e))return t;return "Other"}function Tt(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 o=s.match(/^\*\s+(.+?)(?:\s*\*\/)?$/);if(o?.[1]&&!o[1].startsWith("@"))return o[1];if(s.startsWith("//")&&s.length>3)return s.slice(2).trim();if(s!==""&&!s.startsWith("//")&&!s.startsWith("/*")&&!s.startsWith("*"))break}return ""}async function Ie(e){let t;for(let n=0;n<e.length;n++)e[n]==="--filter"&&(t=e[++n]?.toLowerCase());let r=getAllExamples();console.log(),console.log(f.bold(f.cyan("Directive Examples"))),console.log(f.dim("\u2500".repeat(50))),console.log();let s=new Map;for(let[n,a]of r){let c=At(n);t&&!c.toLowerCase().includes(t)&&!n.includes(t)||(s.has(c)||s.set(c,[]),s.get(c).push({name:n,desc:Tt(a)}));}if(s.size===0){console.log(f.dim("No examples match the filter."));return}let o=Object.keys(qe),i=[...s.keys()].sort((n,a)=>(o.indexOf(n)??99)-(o.indexOf(a)??99));for(let n of i){let a=s.get(n);console.log(f.bold(n));for(let c of a){let m=c.desc?f.dim(` \u2014 ${c.desc}`):"";console.log(` ${f.cyan(c.name)}${m}`);}console.log();}console.log(f.dim(`${r.size} examples available. Run ${f.cyan("directive examples copy <name>")} to extract one.`));}async function Ne(e,t){let r=process.cwd();for(let c=0;c<t.length;c++)if(t[c]==="--dest"){let m=t[++c];m&&(r=m);}e||(console.error("Usage: directive examples copy <name> [--dest <dir>]"),process.exit(1));let s=getExample(e);s||(console.error(`Example "${e}" not found.`),console.error(`Run ${f.cyan("directive examples list")} to see available examples.`),process.exit(1));let o=s.replace(/from\s+["']@directive-run\/core\/plugins["']/g,'from "@directive-run/core/plugins"').replace(/from\s+["']@directive-run\/core["']/g,'from "@directive-run/core"').replace(/from\s+["']@directive-run\/ai["']/g,'from "@directive-run/ai"'),i=join(r,`${e}.ts`);existsSync(i)&&(console.error(`File already exists: ${relative(process.cwd(),i)}`),process.exit(1));let n=dirname(i);existsSync(n)||mkdirSync(n,{recursive:true}),writeFileSync(i,o,"utf-8");let a=relative(process.cwd(),i);console.log(`${f.green("Copied")} ${f.cyan(e)} \u2192 ${f.dim(a)}`);}function Ot(e){let t={},r="",s;for(let o=0;o<e.length;o++){let i=e[o];if(i==="--module"){let n=e[++o];n&&(t.module=n);}else i&&!i.startsWith("-")&&(r?s||(s=i):r=i);}return {filePath:r,requirementId:s,opts:t}}async function Ue(e){let{filePath:t,requirementId:r}=Ot(e);t||(console.error("Usage: directive explain <file> [requirement-id]"),process.exit(1));let s=await M(t);s.isRunning||s.start();let o=s.inspect();if(r){let i=s.explain(r);if(!i){if(console.error(`Requirement "${r}" not found.
|
|
344
|
+
|
|
345
|
+
Current requirements:`),o.unmet.length===0)console.log(f.dim(" (no unmet requirements)"));else for(let n of o.unmet)console.log(` ${f.cyan(n.id)} \u2014 ${n.requirement.type} (from ${n.fromConstraint})`);s.stop(),process.exit(1);}console.log(),console.log(f.bold(f.cyan("Requirement Explanation"))),console.log(f.dim("\u2500".repeat(40))),console.log(),console.log(i),console.log();}else if(console.log(),console.log(f.bold(f.cyan("All Requirements"))),console.log(f.dim("\u2500".repeat(40))),console.log(),o.unmet.length===0){console.log(f.green("All requirements are met.")),console.log();let i=Object.entries(o.resolvers);if(i.length>0){console.log(f.bold("Recent Resolver Activity:"));for(let[n,a]of i){let c=Fe(a.state),m=a.duration!==void 0?` (${a.duration}ms)`:"";console.log(` ${f.cyan(n)} ${c}${m}`);}console.log();}}else {console.log(`${f.yellow(String(o.unmet.length))} unmet requirement(s):
|
|
346
|
+
`);for(let i of o.unmet){console.log(`${f.yellow("\u25CF")} ${f.bold(i.requirement.type)} (id: ${f.dim(i.id)})`),console.log(` From constraint: ${f.cyan(i.fromConstraint)}`);let n={...i.requirement};delete n.type,Object.keys(n).length>0&&console.log(` Payload: ${JSON.stringify(n)}`);let c=o.resolvers[i.id];c?console.log(` Resolver: ${Fe(c.state)}${c.error?` \u2014 ${c.error}`:""}`):o.resolverDefs.some(d=>d.requirement===i.requirement.type||d.requirement==="(predicate)")||console.log(` ${f.red("No resolver registered for this type")}`),console.log();}console.log(f.dim(`Run ${f.cyan("directive explain <file> <requirement-id>")} for detailed explanation.`));}s.stop();}function Fe(e){switch(e){case "resolved":return f.green("resolved");case "errored":return f.red("errored");case "inflight":return f.yellow("inflight");case "pending":return f.yellow("pending");case "cancelled":return f.dim("cancelled");default:return f.dim(e)}}function jt(e){let t={ascii:false,open:true},r="";for(let s=0;s<e.length;s++){let o=e[s];switch(o){case "--ascii":t.ascii=true;break;case "--no-open":t.open=false;break;case "--output":{let i=e[++s];i&&(t.output=i);break}default:o&&!o.startsWith("-")&&!r&&(r=o);}}return {filePath:r,opts:t}}function Mt(e){let t=[];t.push(f.bold("Dependency Graph")),t.push(f.dim("\u2550".repeat(50))),t.push("");let r=new Map;for(let a of e.constraints)r.set(a.id,{reqTypes:new Set,active:a.active,priority:a.priority});for(let a of e.unmet){let c=r.get(a.fromConstraint);c&&c.reqTypes.add(a.requirement.type);}let s=new Map;for(let a of e.resolverDefs)s.has(a.requirement)||s.set(a.requirement,[]),s.get(a.requirement).push(a.id);t.push(f.bold("Constraints \u2192 Requirements \u2192 Resolvers")),t.push("");for(let[a,c]of r){let m=c.active?f.green("\u25CF"):f.dim("\u25CB");if(t.push(`${m} ${f.cyan(a)} (priority: ${c.priority})`),c.reqTypes.size>0)for(let d of c.reqTypes){t.push(` \u2514\u2500\u25B6 ${f.yellow(d)}`);let l=s.get(d)||[];if(l.length>0)for(let h of l)t.push(` \u2514\u2500\u25B6 ${f.magenta(h)}`);else t.push(` \u2514\u2500\u25B6 ${f.red("(no resolver)")}`);}else t.push(` \u2514\u2500\u25B6 ${f.dim("(no active requirements)")}`);t.push("");}let o=new Set;for(let a of s.values())for(let c of a)o.add(c);if(e.resolverDefs.map(a=>a.id).filter(a=>!o.has(a)).length>0){t.push(f.bold("Standalone Resolvers:"));for(let a of e.resolverDefs)o.has(a.id)||t.push(` ${f.magenta(a.id)} handles ${f.yellow(a.requirement)}`);}return t.join(`
|
|
347
|
+
`)}function Pt(e,t){let r=[],s=[],c=Object.keys(t);for(let u=0;u<c.length;u++){let R=c[u];r.push({id:`fact-${R}`,label:R,type:"fact",x:40,y:60+u*50,color:"#3b82f6"});}for(let u=0;u<e.constraints.length;u++){let R=e.constraints[u];r.push({id:`constraint-${R.id}`,label:R.id,type:"constraint",x:260,y:60+u*50,color:R.active?"#22c55e":"#6b7280"});}let m=new Set;for(let u of e.unmet)m.add(u.requirement.type);let d=0;for(let u of m)r.push({id:`req-${u}`,label:u,type:"requirement",x:480,y:60+d*50,color:"#eab308"}),d++;for(let u=0;u<e.resolverDefs.length;u++){let R=e.resolverDefs[u];r.push({id:`resolver-${R.id}`,label:R.id,type:"resolver",x:700,y:60+u*50,color:"#a855f7"});}for(let u of e.unmet)s.push({from:`constraint-${u.fromConstraint}`,to:`req-${u.requirement.type}`});for(let u of e.resolverDefs)m.has(u.requirement)&&s.push({from:`req-${u.requirement}`,to:`resolver-${u.id}`});let l=new Map(r.map(u=>[u.id,u])),h=960,T=Math.max(...r.map(u=>u.y))+50+20,j=s.map(u=>{let R=l.get(u.from),ne=l.get(u.to);return !R||!ne?"":`<line x1="${R.x+90}" y1="${R.y+15}" x2="${ne.x}" y2="${ne.y+15}" stroke="#94a3b8" stroke-width="1.5" marker-end="url(#arrow)"/>`}).join(`
|
|
348
|
+
`),C=r.map(u=>`<g>
|
|
349
|
+
<rect x="${u.x}" y="${u.y}" width="180" height="30" rx="6" fill="${u.color}" opacity="0.15" stroke="${u.color}" stroke-width="1.5"/>
|
|
350
|
+
<text x="${u.x+90}" y="${u.y+19}" text-anchor="middle" font-size="12" font-family="monospace" fill="${u.color}">${qt(u.label)}</text>
|
|
351
|
+
</g>`).join(`
|
|
352
|
+
`),tt=["Facts","Constraints","Requirements","Resolvers"].map((u,R)=>`<text x="${40+R*220+90}" y="35" text-anchor="middle" font-size="14" font-weight="bold" font-family="system-ui" fill="#e2e8f0">${u}</text>`).join(`
|
|
353
|
+
`);return `<!DOCTYPE html>
|
|
354
|
+
<html>
|
|
355
|
+
<head>
|
|
356
|
+
<title>Directive System Graph</title>
|
|
357
|
+
<style>
|
|
358
|
+
body { margin: 0; background: #0f172a; display: flex; justify-content: center; padding: 20px; }
|
|
359
|
+
svg { max-width: 100%; }
|
|
360
|
+
</style>
|
|
361
|
+
</head>
|
|
362
|
+
<body>
|
|
363
|
+
<svg width="${h}" height="${T}" xmlns="http://www.w3.org/2000/svg">
|
|
364
|
+
<defs>
|
|
365
|
+
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
|
|
366
|
+
<path d="M 0 0 L 10 5 L 0 10 z" fill="#94a3b8"/>
|
|
367
|
+
</marker>
|
|
368
|
+
</defs>
|
|
369
|
+
${tt}
|
|
370
|
+
${j}
|
|
371
|
+
${C}
|
|
372
|
+
</svg>
|
|
373
|
+
</body>
|
|
374
|
+
</html>`}function qt(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}async function We(e){let{filePath:t,opts:r}=jt(e);t||(console.error("Usage: directive graph <file> [--ascii] [--no-open] [--output <path>]"),process.exit(1));let s=await M(t);s.isRunning||s.start();let o=s.inspect();if(r.ascii){console.log(Mt(o)),s.stop();return}let i={};if(s.facts)for(let c of Object.keys(s.facts))try{i[c]=s.facts[c];}catch{i[c]=null;}let n=Pt(o,i),a=r.output||join(process.cwd(),".directive-graph.html");if(writeFileSync(a,n,"utf-8"),console.log(`${f.green("Generated")} ${f.dim(a)}`),r.open)try{let{execFile:c}=await import('child_process'),m=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";c(m,[a]),console.log(f.dim("Opened in browser."));}catch{console.log(f.dim(`Open ${a} in your browser to view the graph.`));}s.stop();}function Wt(e){let t={dir:process.cwd(),noInteractive:false};for(let r=0;r<e.length;r++)switch(e[r]){case "--template":{let o=e[++r];o&&(t.template=o);break}case "--dir":{let o=e[++r];o&&(t.dir=o);break}case "--no-interactive":t.noInteractive=true;break}return t}function Lt(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 Gt(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 me(e){return {counter:{id:"counter",label:"Counter (minimal)",hint:"schema + init + derive + events \u2014 simplest starting point",files:[{path:`src/${e}.ts`,content:zt(e)},{path:"src/main.ts",content:_t(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:Jt(e)},{path:"src/main.ts",content:Bt(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:Ht(e)},{path:"src/main.ts",content:Kt(e)}],deps:["@directive-run/core","@directive-run/ai"]}}}function zt(e){return `import { type ModuleSchema, createModule, t } from "@directive-run/core";
|
|
266
375
|
|
|
267
376
|
const schema = {
|
|
268
377
|
facts: {
|
|
@@ -281,7 +390,7 @@ const schema = {
|
|
|
281
390
|
},
|
|
282
391
|
} satisfies ModuleSchema;
|
|
283
392
|
|
|
284
|
-
export const ${
|
|
393
|
+
export const ${B(e)} = createModule("${e}", {
|
|
285
394
|
schema,
|
|
286
395
|
|
|
287
396
|
init: (facts) => {
|
|
@@ -309,7 +418,7 @@ export const ${j(e)} = createModule("${e}", {
|
|
|
309
418
|
},
|
|
310
419
|
},
|
|
311
420
|
});
|
|
312
|
-
`}function
|
|
421
|
+
`}function _t(e){let t=B(e);return `import { createSystem } from "@directive-run/core";
|
|
313
422
|
import { ${t} } from "./${e}.js";
|
|
314
423
|
|
|
315
424
|
const system = createSystem({
|
|
@@ -335,7 +444,7 @@ system.events.increment();
|
|
|
335
444
|
system.events.increment();
|
|
336
445
|
|
|
337
446
|
export default system;
|
|
338
|
-
`}function
|
|
447
|
+
`}function Jt(e){return `import { type ModuleSchema, createModule, t } from "@directive-run/core";
|
|
339
448
|
|
|
340
449
|
type AuthStatus = "idle" | "authenticating" | "authenticated" | "expired";
|
|
341
450
|
|
|
@@ -362,7 +471,7 @@ const schema = {
|
|
|
362
471
|
},
|
|
363
472
|
} satisfies ModuleSchema;
|
|
364
473
|
|
|
365
|
-
export const ${
|
|
474
|
+
export const ${B(e)} = createModule("${e}", {
|
|
366
475
|
schema,
|
|
367
476
|
|
|
368
477
|
init: (facts) => {
|
|
@@ -439,7 +548,7 @@ export const ${j(e)} = createModule("${e}", {
|
|
|
439
548
|
},
|
|
440
549
|
},
|
|
441
550
|
});
|
|
442
|
-
`}function
|
|
551
|
+
`}function Bt(e){let t=B(e);return `import { createSystem } from "@directive-run/core";
|
|
443
552
|
import { ${t} } from "./${e}.js";
|
|
444
553
|
|
|
445
554
|
const system = createSystem({
|
|
@@ -460,7 +569,7 @@ console.log("authenticated:", system.read("isAuthenticated"));
|
|
|
460
569
|
console.log("token:", system.facts.token);
|
|
461
570
|
|
|
462
571
|
export default system;
|
|
463
|
-
`}function
|
|
572
|
+
`}function Ht(e){return `import { type ModuleSchema, createModule, t } from "@directive-run/core";
|
|
464
573
|
import {
|
|
465
574
|
createAgentOrchestrator,
|
|
466
575
|
createAgentMemory,
|
|
@@ -494,7 +603,7 @@ const schema = {
|
|
|
494
603
|
},
|
|
495
604
|
} satisfies ModuleSchema;
|
|
496
605
|
|
|
497
|
-
export const ${
|
|
606
|
+
export const ${B(e)} = createModule("${e}", {
|
|
498
607
|
schema,
|
|
499
608
|
|
|
500
609
|
init: (facts) => {
|
|
@@ -568,7 +677,7 @@ export const memory = createAgentMemory({
|
|
|
568
677
|
// maxTokenBudget: 50000,
|
|
569
678
|
// memory,
|
|
570
679
|
// });
|
|
571
|
-
`}function
|
|
680
|
+
`}function Kt(e){let t=B(e);return `import { createSystem } from "@directive-run/core";
|
|
572
681
|
import { ${t} } from "./${e}.js";
|
|
573
682
|
|
|
574
683
|
const system = createSystem({
|
|
@@ -587,10 +696,20 @@ await system.settle();
|
|
|
587
696
|
console.log("output:", system.facts.output);
|
|
588
697
|
|
|
589
698
|
export default system;
|
|
590
|
-
`}function
|
|
591
|
-
${
|
|
592
|
-
${
|
|
593
|
-
${
|
|
699
|
+
`}function B(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function Yt(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}async function Le(e){let t=Wt(e);p.intro(f.bgCyan(f.black(" directive init ")));let r;if(t.noInteractive)r="my-module";else {let l=await p.text({message:"Module name:",placeholder:"my-module",defaultValue:"my-module",validate:h=>{if(!/^[a-z][a-z0-9-]*$/.test(h))return "Must start with a letter, use lowercase letters, numbers, and hyphens"}});p.isCancel(l)&&(p.cancel("Cancelled."),process.exit(0)),r=l;}let s;if(t.template){let l=me(r);t.template in l||(p.log.error(`Unknown template: ${t.template}. Available: ${Object.keys(l).join(", ")}`),process.exit(1)),s=t.template;}else if(t.noInteractive)s="counter";else {let l=me(r),h=await p.select({message:"Project template:",options:Object.values(l).map(T=>({value:T.id,label:T.label,hint:T.hint}))});p.isCancel(h)&&(p.cancel("Cancelled."),process.exit(0)),s=h;}let i=me(r)[s],n=Lt(t.dir);p.log.info(`Package manager: ${f.cyan(n)}`);let a=p.spinner();a.start("Creating project files...");let m=0;for(let l of i.files){let h=join(t.dir,l.path);if(existsSync(h)){m++;continue}Yt(h,l.content);}a.stop("Project files created.");for(let l of i.files){let h=join(t.dir,l.path),T=relative(t.dir,h);existsSync(h)&&p.log.success(`${f.green("Created")} ${f.dim(T)}`);}m>0&&p.log.warn(`Skipped ${m} file(s) that already exist.`);let d=Gt(n,i.deps.join(" "));p.outro(`Next steps:
|
|
700
|
+
${f.cyan(d)}
|
|
701
|
+
${f.cyan(`${x} ai-rules init`)}
|
|
702
|
+
${f.dim("Start building!")}`);}function Xt(e){let t={json:false},r="";for(let s=0;s<e.length;s++){let o=e[s];switch(o){case "--json":t.json=true;break;case "--module":{let i=e[++s];i&&(t.module=i);break}default:o&&!o.startsWith("-")&&!r&&(r=o);}}return {filePath:r,opts:t}}function Vt(e){let t=[];t.push(f.bold("Facts:"));let r=Object.entries(e);if(r.length===0)return t.push(" (none)"),t.join(`
|
|
703
|
+
`);for(let[s,o]of r){let i=sr(o);t.push(` ${f.cyan(s)} = ${i}`);}return t.join(`
|
|
704
|
+
`)}function Qt(e){let t=[];if(t.push(f.bold("Constraints:")),e.length===0)return t.push(" (none)"),t.join(`
|
|
705
|
+
`);for(let r of e){let s=r.disabled?f.dim("disabled"):r.active?f.green("active"):f.dim("inactive"),o=r.hitCount>0?f.yellow(` (${r.hitCount} hits)`):"";t.push(` ${f.cyan(r.id)} ${s} priority=${r.priority}${o}`);}return t.join(`
|
|
706
|
+
`)}function Zt(e,t){let r=[];if(r.push(f.bold("Resolvers:")),e.length===0)return r.push(" (none)"),r.join(`
|
|
707
|
+
`);for(let s of e){let o=t[s.id],i=o?rr(o.state,o.error,o.duration):f.dim("idle");r.push(` ${f.cyan(s.id)} \u2192 ${s.requirement} ${i}`);}return r.join(`
|
|
708
|
+
`)}function er(e){let t=[];if(t.push(f.bold("Unmet Requirements:")),e.length===0)return t.push(` ${f.green("(all requirements met)")}`),t.join(`
|
|
709
|
+
`);for(let r of e)t.push(` ${f.yellow(r.requirement.type)} (id: ${f.dim(r.id)}) from ${f.dim(r.fromConstraint)}`);return t.join(`
|
|
710
|
+
`)}function tr(e){let t=[];if(t.push(f.bold("Inflight:")),e.length===0)return t.push(` ${f.green("(none)")}`),t.join(`
|
|
711
|
+
`);let r=Date.now();for(let s of e){let o=r-s.startedAt;t.push(` ${f.cyan(s.resolverId)} \u2192 req ${f.dim(s.id)} ${f.yellow(`${o}ms`)}`);}return t.join(`
|
|
712
|
+
`)}function rr(e,t,r){let s=r!==void 0?` ${r}ms`:"";switch(e){case "resolved":return f.green(`resolved${s}`);case "errored":return f.red(`errored${s}${t?` \u2014 ${t}`:""}`);case "inflight":return f.yellow("inflight");case "cancelled":return f.dim("cancelled");default:return f.dim(e)}}function sr(e){return e===null?f.dim("null"):e===void 0?f.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 nr(e){let t=[];new Set(e.unmet.map(i=>i.requirement.type));new Set(e.resolverDefs.map(i=>i.requirement));for(let i of e.resolverDefs)i.requirement;for(let i of e.unmet)e.resolverDefs.some(a=>a.requirement===i.requirement.type||a.requirement==="(predicate)")||t.push(`No resolver for requirement type "${i.requirement.type}"`);return t}async function Ge(e){let{filePath:t,opts:r}=Xt(e);t||(console.error("Usage: directive inspect <file> [--json] [--module <name>]"),process.exit(1));let s=await M(t);s.isRunning||s.start();let o=s.inspect();if(r.json){let a={};if(s.facts)for(let c of Object.keys(s.facts))try{a[c]=s.facts[c];}catch{a[c]="(error reading)";}console.log(JSON.stringify({facts:a,...o},null,2)),s.stop();return}console.log(),console.log(f.bold(f.cyan("Directive System Inspection"))),console.log(f.dim("\u2500".repeat(40))),console.log();let i={};if(s.facts)for(let a of Object.keys(s.facts))try{i[a]=s.facts[a];}catch{i[a]="(error reading)";}console.log(Vt(i)),console.log(),console.log(Qt(o.constraints)),console.log(),console.log(Zt(o.resolverDefs,o.resolvers)),console.log(),console.log(er(o.unmet)),console.log(),o.inflight.length>0&&(console.log(tr(o.inflight)),console.log());let n=nr(o);if(n.length>0){console.log(f.bold(f.yellow("Warnings:")));for(let a of n)console.log(` ${f.yellow("\u26A0")} ${a}`);console.log();}s.stop();}function _e(e){let t={with:[],minimal:false,dir:process.cwd()};for(let r=0;r<e.length;r++)switch(e[r]){case "--with":{let o=e[++r];o&&(t.with=o.split(",").map(i=>i.trim()));break}case "--minimal":t.minimal=true;break;case "--dir":{let o=e[++r];o&&(t.dir=o);break}}return t}var ze=["derive","events","constraints","resolvers","effects"];function cr(e,t){let r=Je(e),s=t.includes("constraints"),o=t.includes("resolvers"),n=`import { ${["type ModuleSchema","createModule","t"].join(", ")} } from "@directive-run/core";
|
|
594
713
|
|
|
595
714
|
`;return n+=`const schema = {
|
|
596
715
|
`,n+=` facts: {
|
|
@@ -659,7 +778,7 @@ export default system;
|
|
|
659
778
|
`,n+=` },
|
|
660
779
|
`,n+=` },
|
|
661
780
|
`),n+=`});
|
|
662
|
-
`,n}function
|
|
781
|
+
`,n}function lr(e){let t=Je(e);return `import { type ModuleSchema, createModule, createSystem, t } from "@directive-run/core";
|
|
663
782
|
import {
|
|
664
783
|
createAgentOrchestrator,
|
|
665
784
|
createAgentMemory,
|
|
@@ -790,61 +909,59 @@ export const memory = createAgentMemory({
|
|
|
790
909
|
export const system = createSystem({
|
|
791
910
|
module: ${t},
|
|
792
911
|
});
|
|
793
|
-
`}function
|
|
794
|
-
Must start with a letter, use lowercase letters, numbers, and hyphens.`),process.exit(1));let s;r.minimal?s=[]:r.with.length>0?s=r.with.filter(c=>
|
|
795
|
-
Must start with a letter, use lowercase letters, numbers, and hyphens.`),process.exit(1));let s=
|
|
796
|
-
|
|
912
|
+
`}function Je(e){return e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase())}function Be(e,t){let r=dirname(e);existsSync(r)||mkdirSync(r,{recursive:true}),writeFileSync(e,t,"utf-8");}function He(e){return join(e,"src")}async function Ke(e,t){let r=_e(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(c=>ze.includes(c)):s=ze;let o=He(r.dir),i=join(o,`${e}.ts`);existsSync(i)&&(console.error(`File already exists: ${relative(r.dir,i)}`),process.exit(1));let n=cr(e,s);Be(i,n);let a=relative(r.dir,i);console.log(`${f.green("Created")} ${f.dim(a)}`),s.length===0?console.log(f.dim(" Minimal module (schema + init only)")):console.log(f.dim(` Sections: ${s.join(", ")}`));}async function Ye(e,t){let r=_e(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=He(r.dir),o=join(s,`${e}.ts`);existsSync(o)&&(console.error(`File already exists: ${relative(r.dir,o)}`),process.exit(1));let i=lr(e);Be(o,i);let n=relative(r.dir,o);console.log(`${f.green("Created")} ${f.dim(n)}`),console.log(f.dim(" AI orchestrator with memory, guardrails, and streaming"));}function pr(e){let t={json:false,dispatchableOnly:true,verbose:false},r="";for(let s=0;s<e.length;s++){let o=e[s];switch(o){case "--system":case "-s":{let i=e[++s];i&&(t.systemPath=i);break}case "--max-frames":{let i=e[++s],n=i?Number.parseInt(i,10):Number.NaN;Number.isFinite(n)&&n>0&&(t.maxFrames=n);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:o&&!o.startsWith("-")&&!r&&(r=o);}}return {jsonPath:r,opts:t}}function fe(){console.error(`
|
|
915
|
+
Usage: directive replay <timeline.json> [options]
|
|
797
916
|
|
|
798
|
-
|
|
799
|
-
${d.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 ${d.dim(e)}: ${r instanceof Error?r.message:String(r)}
|
|
917
|
+
Replay a serialized Directive timeline against a fresh system.
|
|
800
918
|
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
${y} \u2014 CLI tools for Directive
|
|
919
|
+
Arguments:
|
|
920
|
+
<timeline.json> Path to a timeline produced by serializeTimeline()
|
|
921
|
+
|
|
922
|
+
Options:
|
|
923
|
+
--system, -s <path> Path to a TypeScript file exporting a Directive
|
|
924
|
+
system (default export or 'system' named export)
|
|
925
|
+
--max-frames <n> Cap on frames replayed (default 100,000)
|
|
926
|
+
--all-frames Walk every frame, not just dispatchable ones
|
|
927
|
+
(diagnostic mode \u2014 most frames will skip silently)
|
|
928
|
+
--json Emit ReplayResult as JSON
|
|
929
|
+
--verbose, -v Print per-frame trace
|
|
930
|
+
--help, -h Show this help
|
|
931
|
+
|
|
932
|
+
Examples:
|
|
933
|
+
directive replay bug-1234.json --system src/app/system.ts
|
|
934
|
+
directive replay error.json --system src/system.ts --json
|
|
935
|
+
directive replay error.json --system src/system.ts --verbose
|
|
936
|
+
`);}async function Xe(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(fe(),process.exit(e.length===0?1:0));let{jsonPath:t,opts:r}=pr(e);t||(console.error(f.red("error: missing <timeline.json> argument")),fe(),process.exit(1)),r.systemPath||(console.error(f.red("error: --system <path> is required"),f.dim(`
|
|
937
|
+
(replay needs a fresh system to dispatch against)`)),fe(),process.exit(1));let s=resolve(t);existsSync(s)||(console.error(f.red(`error: timeline file not found: ${s}`)),process.exit(1));let o;try{o=readFileSync(s,"utf8");}catch(h){console.error(f.red(`error: failed to read ${s}: ${h.message}`)),process.exit(1);}let i;try{i=JSON.parse(o);}catch(h){console.error(f.red(`error: ${s} is not valid JSON: ${h.message}`)),process.exit(1);}let{deserializeTimeline:n,replayTimeline:a}=await _(r.verbose),c;try{c=n(i);}catch(h){console.error(f.red(`error: timeline JSON failed validation: ${h.message}`)),process.exit(1);}let m;try{m=await M(r.systemPath);}catch(h){console.error(f.red(`error: failed to load system file: ${h.message}`)),process.exit(1);}let d=m;if(typeof d.dispatch!="function"&&(console.error(f.red("error: loaded system has no dispatch() method. The --system file must export a started Directive system or a factory.")),process.exit(1)),typeof d.start=="function")try{d.start();}catch{}let l=await a(c,d,{dispatchableOnly:r.dispatchableOnly,maxFrames:r.maxFrames});if(r.json)console.log(JSON.stringify(l,null,2));else {let{dispatched:h,skipped:T,truncated:j}=l,C=h>0;console.log(`${C?f.green("\u2713"):f.yellow("\u26A0")} replay complete:`,f.bold(`${h} dispatched`),f.dim(`/ ${T} skipped`),j>0?f.yellow(`/ ${j} TRUNCATED`):""),h===0&&console.error(f.yellow("warning: 0 frames dispatched. Either the timeline contains only non-dispatchable frames (system lifecycle, derivations, etc.) or the system shape doesn't match what the timeline recorded.")),j>0&&console.error(f.yellow(`warning: ${j} frames truncated by --max-frames cap. Raise it with --max-frames <n> if you need them.`));}process.exit(0);}function yr(e){let t={json:false,verbose:false},r=[];for(let s=0;s<e.length;s++){let o=e[s];switch(o){case "--json":t.json=true;break;case "--verbose":case "-v":t.verbose=true;break;default:o&&!o.startsWith("-")&&r.push(o);}}return {aPath:r[0]??"",bPath:r[1]??"",opts:t}}function Ve(){console.error(`
|
|
938
|
+
Usage: directive timeline diff <a.json> <b.json>
|
|
939
|
+
|
|
940
|
+
Compare two serialized Directive timelines as a structured causal-graph
|
|
941
|
+
diff. Reports frame counts, constraint-fire deltas, mutation deltas,
|
|
942
|
+
resolver runs, and new errors.
|
|
943
|
+
|
|
944
|
+
Arguments:
|
|
945
|
+
<a.json> First timeline (typically the "good" / baseline run)
|
|
946
|
+
<b.json> Second timeline (typically the "bad" / regression run)
|
|
947
|
+
|
|
948
|
+
Options:
|
|
949
|
+
--json Emit TimelineDiff as JSON
|
|
950
|
+
-v, --verbose Include unchanged categories in the human output
|
|
951
|
+
--help, -h Show this help
|
|
952
|
+
|
|
953
|
+
Exit codes:
|
|
954
|
+
0 identical timelines
|
|
955
|
+
1 CLI argument error
|
|
956
|
+
2 diff found differences
|
|
957
|
+
|
|
958
|
+
Examples:
|
|
959
|
+
directive timeline diff baseline.json regression.json
|
|
960
|
+
directive timeline diff a.json b.json --json | jq .constraintFires
|
|
961
|
+
`);}function X(e){return e>0?f.green(`+${e}`):e<0?f.red(`${e}`):f.dim(" 0")}function Qe(e){return e.length===0?[f.dim(" (no differences)")]:e.map(t=>` ${f.bold(t.id.padEnd(28))} ${String(t.aCount).padStart(4)} \u2192 ${String(t.bCount).padStart(4)} (${X(t.delta)})`)}function vr(e){return e.length===0?[f.dim(" (no differences)")]:e.map(t=>` ${f.bold(t.resolver.padEnd(28))} starts ${t.aStarts}\u2192${t.bStarts} (${X(t.bStarts-t.aStarts)}) completes ${t.aCompletes}\u2192${t.bCompletes} (${X(t.bCompletes-t.aCompletes)}) errors ${t.aErrors}\u2192${t.bErrors} (${X(t.bErrors-t.aErrors)})`)}function br(e){return e.length===0?[f.dim(" (no new errors)")]:e.map(t=>{let r=t.side==="a"?f.cyan("a-only"):f.yellow("b-only"),s=(()=>{try{return JSON.stringify(t.error)}catch{return `[${typeof t.error}]`}})();return ` ${r} frame #${t.frameIndex} ${f.bold(t.kind)} '${t.id}' ${f.dim(s)}`})}function Ze(e){let t=resolve(e);existsSync(t)||(console.error(f.red(`error: timeline file not found: ${t}`)),process.exit(1));let r;try{r=readFileSync(t,"utf8");}catch(s){console.error(f.red(`error: failed to read ${t}: ${s.message}`)),process.exit(1);}try{return JSON.parse(r)}catch(s){console.error(f.red(`error: ${t} is not valid JSON: ${s.message}`)),process.exit(1);}}async function et(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(Ve(),process.exit(e.length===0?1:0));let{aPath:t,bPath:r,opts:s}=yr(e);(!t||!r)&&(console.error(f.red("error: both <a.json> and <b.json> are required")),Ve(),process.exit(1));let{deserializeTimeline:o,diffTimelines:i}=await _(s.verbose),n=Ze(t),a=Ze(r),c,m;try{c=o(n),m=o(a);}catch(l){console.error(f.red(`error: timeline JSON failed validation: ${l.message}`)),process.exit(1);}let d=i(c,m);s.json&&(console.log(JSON.stringify(d,null,2)),process.exit(d.identical?0:2)),d.identical&&(console.log(f.green("\u2713 identical:"),`both timelines have ${d.aFrameCount} frames and the same causal shape.`),process.exit(0)),console.log(f.bold("Timeline diff"),f.dim(`(${t} vs ${r})`)),console.log(""),console.log(`Frames: ${d.aFrameCount} \u2192 ${d.bFrameCount} (${X(d.frameCountDelta)})`),console.log(""),console.log(f.bold("Constraint fires:"));for(let l of Qe(d.constraintFires))console.log(l);console.log(""),console.log(f.bold("Mutations:"));for(let l of Qe(d.mutations))console.log(l);console.log(""),console.log(f.bold("Resolver runs:"));for(let l of vr(d.resolverRuns))console.log(l);console.log(""),console.log(f.bold("New errors:"));for(let l of br(d.newErrors))console.log(l);console.log(""),process.exit(2);}var wr=`
|
|
962
|
+
${x} \u2014 CLI tools for Directive
|
|
846
963
|
|
|
847
|
-
Usage: ${
|
|
964
|
+
Usage: ${x} <command> [options]
|
|
848
965
|
|
|
849
966
|
Commands:
|
|
850
967
|
init Project scaffolding wizard
|
|
@@ -859,6 +976,12 @@ Commands:
|
|
|
859
976
|
ai-rules check Validate rules are current (CI)
|
|
860
977
|
examples list Browse available examples
|
|
861
978
|
examples copy <name> Extract example to project
|
|
979
|
+
replay <timeline.json> Replay a serialized Directive timeline
|
|
980
|
+
(paired with @directive-run/timeline)
|
|
981
|
+
bisect <timeline.json> Binary-search a timeline for the first
|
|
982
|
+
frame that triggers a failing assertion
|
|
983
|
+
timeline diff <a> <b> Semantic causal-graph diff between two
|
|
984
|
+
serialized timelines
|
|
862
985
|
|
|
863
986
|
Options:
|
|
864
987
|
--help, -h Show this help message
|
|
@@ -892,13 +1015,14 @@ ai-rules init options:
|
|
|
892
1015
|
examples options:
|
|
893
1016
|
--filter <category> Filter by category or name
|
|
894
1017
|
--dest <dir> Destination directory for copy
|
|
895
|
-
`.trim();async function
|
|
896
|
-
Usage: ${
|
|
897
|
-
${
|
|
898
|
-
Usage: ${
|
|
899
|
-
${
|
|
900
|
-
${
|
|
901
|
-
Usage: ${
|
|
902
|
-
${
|
|
903
|
-
|
|
1018
|
+
`.trim();async function xr(){let e=process.argv.slice(2);if((e.length===0||e.includes("--help")||e.includes("-h"))&&(console.log(wr),process.exit(0)),e.includes("--version")||e.includes("-v")){let{readFileSync:r}=await import('fs'),{fileURLToPath:s}=await import('url'),{dirname:o,join:i}=await import('path'),n=o(s(import.meta.url)),a=JSON.parse(r(i(n,"..","package.json"),"utf-8"));console.log(a.version),process.exit(0);}let t=e[0];switch(t){case "init":{await Le(e.slice(1));break}case "new":{let r=e[1],s=e[2];r==="module"?(s||(console.error("Usage: directive new module <name>"),process.exit(1)),await Ke(s,e.slice(3))):r==="orchestrator"?(s||(console.error("Usage: directive new orchestrator <name>"),process.exit(1)),await Ye(s,e.slice(3))):(console.error(`Unknown subcommand: ${r??"(none)"}
|
|
1019
|
+
Usage: ${x} new module <name>
|
|
1020
|
+
${x} new orchestrator <name>`),process.exit(1));break}case "inspect":{await Ge(e.slice(1));break}case "explain":{await Ue(e.slice(1));break}case "graph":{await We(e.slice(1));break}case "doctor":{await je(e.slice(1));break}case "ai-rules":{let r=e[1];r==="init"?await Se(e.slice(2)):r==="update"?await Ce(e.slice(2)):r==="check"?await Re(e.slice(2)):(console.error(`Unknown subcommand: ${r??"(none)"}
|
|
1021
|
+
Usage: ${x} ai-rules init
|
|
1022
|
+
${x} ai-rules update
|
|
1023
|
+
${x} ai-rules check`),process.exit(1));break}case "examples":{let r=e[1];if(r==="list")await Ie(e.slice(2));else if(r==="copy"){let s=e[2];s||(console.error("Usage: directive examples copy <name>"),process.exit(1)),await Ne(s,e.slice(3));}else console.error(`Unknown subcommand: ${r??"(none)"}
|
|
1024
|
+
Usage: ${x} examples list [--filter <category>]
|
|
1025
|
+
${x} examples copy <name> [--dest <dir>]`),process.exit(1);break}case "replay":{await Xe(e.slice(1));break}case "bisect":{await Ee(e.slice(1));break}case "timeline":{let r=e[1];r==="diff"?await et(e.slice(2)):(console.error(`Unknown subcommand: ${r??"(none)"}
|
|
1026
|
+
Usage: ${x} timeline diff <a.json> <b.json>`),process.exit(1));break}default:console.error(`Unknown command: ${t}
|
|
1027
|
+
Run '${x} --help' for usage.`),process.exit(1);}}xr().catch(e=>{console.error(e.message||e),process.exit(1);});//# sourceMappingURL=cli.js.map
|
|
904
1028
|
//# sourceMappingURL=cli.js.map
|