@directive-run/cli 1.1.2 → 1.4.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 CHANGED
@@ -152,6 +152,75 @@ directive examples copy counter
152
152
  directive examples copy auth-flow --dest ./src/examples
153
153
  ```
154
154
 
155
+ ### `directive replay <timeline.json>`
156
+
157
+ Re-dispatch a serialized [`@directive-run/timeline`](../timeline) JSON dump against a fresh system. Designed for the prod-error-to-local-repro flow: production captures the last N seconds of timeline frames via `serializeTimeline()`, ships the JSON to your bug tracker, and an engineer pastes the path into `replay`.
158
+
159
+ ```bash
160
+ directive replay bug-1234.json --system src/app/system.ts
161
+ # ✓ replay complete: 47 dispatched / 18 skipped
162
+
163
+ directive replay bug-1234.json --system src/system.ts --json
164
+ # {"dispatched": 47, "skipped": 18, "truncated": 0}
165
+
166
+ directive replay bug-1234.json --system src/system.ts --max-frames 10000
167
+ ```
168
+
169
+ The `--system <path>` file must export a started Directive system as either a default export or a named `system` export. Same shape as `inspect` / `graph` / `explain`.
170
+
171
+ **Requires `@directive-run/timeline` as a peer dep:** install it with `npm install --save-dev @directive-run/timeline`.
172
+
173
+ ### `directive bisect <timeline.json>`
174
+
175
+ Binary-search a recorded timeline for the first frame whose inclusion flips a user-supplied assertion from passing to failing — git-bisect, but over `ObservationEvent` frames.
176
+
177
+ ```bash
178
+ directive bisect bug-1234.json \
179
+ --system test/bisect-system.ts \
180
+ --assert 'facts.count >= 0'
181
+ # ✓ bisect complete: first failing frame is #47 (fact.change)
182
+ ```
183
+
184
+ The `--system <path>` file must export a **factory** (not a started instance — bisect calls the factory once per midpoint to keep each replay hermetic). Looks for `createSystem` / `systemFactory` / `default` exports, in that order. The factory must return a started system:
185
+
186
+ ```ts
187
+ // test/bisect-system.ts
188
+ export function createSystem() {
189
+ const sys = makeSys({ module: counterModule });
190
+ sys.start();
191
+ return sys;
192
+ }
193
+ ```
194
+
195
+ The `--assert <expression>` is evaluated as JS with `facts` and `system` in scope. Truthy = good prefix; falsy = bad prefix. Bisect locates the smallest bad prefix.
196
+
197
+ **SECURITY:** `--assert` runs as JavaScript in the CLI process. Only pass expressions from sources you trust. Don't paste expressions from untrusted issues / Slack / third parties.
198
+
199
+ Options: `--max-frames <n>` (default 100,000), `--no-determinism-check` (skip the replay-twice gate), `--json`, `--verbose`.
200
+
201
+ Exit codes: `0` (no failure to bisect / fails-on-empty), `2` (bisect found a frame OR refused due to non-determinism), `1` (CLI error).
202
+
203
+ ### `directive timeline diff <a.json> <b.json>`
204
+
205
+ Semantic causal-graph diff between two serialized timelines. Not a textual JSON diff — per-category deltas (frame counts, constraint fires, mutation kinds, resolver runs, new errors).
206
+
207
+ ```bash
208
+ directive timeline diff baseline.json regression.json
209
+ # Frames: 23 → 31 (+8)
210
+ # Constraint fires:
211
+ # loadOnLoading 1 → 4 (+3)
212
+ # Mutations:
213
+ # submit 2 → 3 (+1)
214
+ # Resolver runs:
215
+ # loader starts 1→2 (+1) completes 1→1 ( 0) errors 0→1 (+1)
216
+ # New errors:
217
+ # b-only frame #15 resolver.error 'loader' "timeout"
218
+
219
+ directive timeline diff a.json b.json --json | jq .constraintFires
220
+ ```
221
+
222
+ Exit codes: `0` (identical), `2` (differences found, CI-gate friendly), `1` (CLI error).
223
+
155
224
  ## Supported AI Tools
156
225
 
157
226
  | Tool | Output File |