Commit 5469c4c
Yogthos
feat(ui+cli): fuzzy search (bfd) + --output-format stream-json (rmk); audit bash escape (umm = already-done)
Six-feature audit against maki + Claude Code. Findings:
| Feature | Status | Notes |
|---|---|---|
| SSRF on webfetch | ✅ | `validate_url_host_safety` covers loopback, link-local AWS metadata, IPv6, env-gated escape |
| `/btw` chat-isolated query | ✅ | `provider.rs:500 btw_query` |
| Ctrl-F search | ✅ now FUZZY | this commit — port `nucleo-matcher` |
| `! / !! bash escape` | ✅ | `src/shell.rs` + wired at `ui/mod.rs:1706/1737`; initial audit missed it |
| `--print --output-format stream-json` | ✅ | this commit — port maki's `OutputFormat` + Claude-shaped JSON envelopes |
| `/tasks` + Ctrl-X subagent windows + Ctrl-N/P | ❌ | tracked as dirge-ov2; bigger refactor — touches Renderer buffer model + keybindings, will coordinate before starting |
## dirge-bfd: fuzzy Ctrl-F via nucleo-matcher
`update_search` (`ui/mod.rs:4937`) was a `to_lowercase().contains()`
substring filter — failed on typos, partial words, out-of-order
keystrokes. Ported from maki
(`maki-ui/src/components/search_modal.rs:147-185`):
- Add `nucleo-matcher = "0.3"` to Cargo.toml (same dep maki uses)
- `Atom::new(.., AtomKind::Fuzzy, ..)` with `CaseMatching::Smart` +
`Normalization::Smart` — case-insensitive when query is lowercase,
case-sensitive when mixed; Unicode-normalized so `naïve` matches
`naive`
- Collect `(line_idx, score)` pairs, sort by score descending,
tie-break on earlier line for stable ordering
- Empty / whitespace queries clear matches (same as maki)
Regression test added — fuzzy `ctd` query matches `connect to
database` via non-contiguous subsequence, which the prior substring
matcher couldn't find.
## dirge-rmk: --output-format stream-json
Headless `--print` previously emitted plain text only. Ported from
maki's `OutputFormat` enum + Claude Code's NDJSON shape so tooling
written against `claude --print --output-format stream-json` works
against dirge unchanged.
New CLI: `--output-format text | json | stream-json` (gated on
`--print`).
- `Text` (default): unchanged behavior — raw response streamed
inline.
- `Json`: suppresses inline streaming, emits ONE result envelope
on stdout at completion: `{ type: "result", subtype: "success",
is_error, duration_ms, num_turns, result, session_id,
total_cost_usd }`. Same field shape as Claude.
- `StreamJson`: NDJSON. Emits `system/init` event at start
(cwd, session_id, tools, model) + an `assistant` event per turn
+ a final `result` envelope. One JSON object per line.
`run_print` signature gained an `output_format: OutputFormat`
parameter; suppression flag derived from format. Reasoning text
(stderr) is also suppressed under Json/StreamJson so JSON output
stays clean of chain-of-thought.
Added a small UUIDv4 generator (`uuid_v4_simple`) so dirge doesn't
need to pull the `uuid` crate just for the session_id field.
## Test
1222/1223 pass (pre-existing Clojure failure unchanged). Smoke-
tested `dirge --help` confirms `--output-format` shows up with the
right enum values. Binary at ~/bin/dirge.1 parent 0b9f760 commit 5469c4c
8 files changed
Lines changed: 303 additions & 27 deletions
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
76 | 80 | | |
77 | 81 | | |
78 | 82 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
126 | 126 | | |
127 | 127 | | |
128 | 128 | | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
129 | 139 | | |
130 | 140 | | |
131 | 141 | | |
132 | 142 | | |
133 | 143 | | |
| 144 | + | |
134 | 145 | | |
135 | 146 | | |
136 | 147 | | |
137 | 148 | | |
138 | 149 | | |
139 | 150 | | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
140 | 176 | | |
141 | 177 | | |
142 | 178 | | |
| |||
176 | 212 | | |
177 | 213 | | |
178 | 214 | | |
179 | | - | |
180 | | - | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
181 | 219 | | |
182 | 220 | | |
183 | 221 | | |
184 | 222 | | |
185 | 223 | | |
186 | | - | |
187 | | - | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
188 | 233 | | |
189 | 234 | | |
190 | 235 | | |
| |||
222 | 267 | | |
223 | 268 | | |
224 | 269 | | |
225 | | - | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
226 | 317 | | |
227 | 318 | | |
228 | 319 | | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
6 | 26 | | |
7 | 27 | | |
8 | 28 | | |
9 | 29 | | |
10 | 30 | | |
11 | 31 | | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
12 | 44 | | |
13 | 45 | | |
14 | 46 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
636 | 636 | | |
637 | 637 | | |
638 | 638 | | |
639 | | - | |
| 639 | + | |
640 | 640 | | |
641 | 641 | | |
642 | 642 | | |
| |||
832 | 832 | | |
833 | 833 | | |
834 | 834 | | |
835 | | - | |
| 835 | + | |
| 836 | + | |
| 837 | + | |
| 838 | + | |
| 839 | + | |
836 | 840 | | |
837 | 841 | | |
838 | 842 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
569 | 569 | | |
570 | 570 | | |
571 | 571 | | |
572 | | - | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
573 | 578 | | |
| 579 | + | |
574 | 580 | | |
575 | | - | |
576 | | - | |
577 | | - | |
578 | | - | |
579 | | - | |
580 | | - | |
581 | | - | |
582 | | - | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
583 | 589 | | |
584 | 590 | | |
585 | 591 | | |
| |||
0 commit comments