fabro/lib/crates
Bryan Helmkamp 32970e0a30
fix(graphviz): accept multi-line DOT attribute blocks without commas (#255)
Fixes #179.

## Summary
- `fabro validate`'s DOT parser rejected multi-line node attribute
blocks unless every attribute was comma-separated, forcing long node
definitions onto a single line.
- Per the DOT spec, the separator between attributes is optional —
whitespace (including newlines) alone is sufficient, and `,` or `;` are
both accepted as explicit separators.
- `attr_block` now uses `many0(terminated(attr, opt(',' | ';')))`
instead of `separated_list0(',', attr)`, so all three forms parse
identically.

## Before / after

```dot
// previously rejected — now parses
inspect [
    label="Inspect Code"
    shape=tab
    prompt="@prompts/inspect.md"
    class="heavy"
    reasoning_effort="high"
]
```

## Test plan
- [x] Added regression test `parse_attr_block_multiline_without_commas`
covering the exact form from #179.
- [x] `cargo nextest run -p fabro-graphviz` — 109/109 pass, including
the new test and existing comma-separated multi-line tests.
- [x] `cargo +nightly-2026-04-14 clippy -p fabro-graphviz --all-targets
-- -D warnings` clean.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Nate Aune <118984+natea@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 08:29:09 -04:00
..
build-support fix(build): refresh embedded git sha on branch commits 2026-05-09 14:10:04 -04:00
fabro-acp fix(acp): tolerate clean stdio exit after final response 2026-05-12 09:03:53 -04:00
fabro-agent feat(model): support open provider catalog data (#245) 2026-05-12 15:42:49 -04:00
fabro-api feat(model): support open provider catalog data (#245) 2026-05-12 15:42:49 -04:00
fabro-auth feat(model): support open provider catalog data (#245) 2026-05-12 15:42:49 -04:00
fabro-checkpoint Make git metadata sandbox-native 2026-04-27 21:43:15 -07:00
fabro-cli feat(model): support open provider catalog data (#245) 2026-05-12 15:42:49 -04:00
fabro-client feat(cli): add Fabro MCP server (#236) 2026-05-11 18:20:50 -04:00
fabro-config feat(server): inject settings-backed model catalog (#247) 2026-05-12 17:55:28 -04:00
fabro-core Cancel in-flight agent stages with CancellationToken (#211) 2026-05-05 09:54:22 -04:00
fabro-dev feat(model): support open provider catalog data (#245) 2026-05-12 15:42:49 -04:00
fabro-devcontainer refactor(static): centralize env var names 2026-04-24 12:29:51 -04:00
fabro-dump feat(api): unify public run shape 2026-05-10 20:48:55 -04:00
fabro-github fix(github): refresh installation tokens during workflows 2026-05-06 07:15:18 -04:00
fabro-graphviz fix(graphviz): accept multi-line DOT attribute blocks without commas (#255) 2026-05-13 08:29:09 -04:00
fabro-hooks fix(github): refresh installation tokens during workflows 2026-05-06 07:15:18 -04:00
fabro-http refactor(static): centralize env var names 2026-04-24 12:29:51 -04:00
fabro-install fix(server): default foreground logs to stdout 2026-05-06 12:41:52 -04:00
fabro-interview Wire end-to-end steering for running agents (#209) 2026-05-05 15:34:16 -04:00
fabro-llm feat(model): support open provider catalog data (#245) 2026-05-12 15:42:49 -04:00
fabro-macros refactor(dev): simplify generated docs tooling 2026-04-24 18:41:00 -04:00
fabro-manifest fix(validate): pick up sibling workflow.toml inputs for bare .fabro path (#242) 2026-05-12 12:05:21 -04:00
fabro-mcp feat(cli): add Fabro MCP server (#236) 2026-05-11 18:20:50 -04:00
fabro-mcp-server fix(validate): pick up sibling workflow.toml inputs for bare .fabro path (#242) 2026-05-12 12:05:21 -04:00
fabro-model feat(server): inject settings-backed model catalog (#247) 2026-05-12 17:55:28 -04:00
fabro-oauth fix(error): preserve remaining error context 2026-05-02 10:51:15 -04:00
fabro-options-metadata refactor(dev): simplify generated docs tooling 2026-04-24 18:41:00 -04:00
fabro-proc refactor(static): centralize env var names 2026-04-24 12:29:51 -04:00
fabro-redact refactor(integrations): make chat integrations Slack-only 2026-05-09 11:43:16 -04:00
fabro-sandbox fix(sandbox): resolve bash via PATH instead of /bin/bash (#241) 2026-05-12 10:31:12 -04:00
fabro-server feat(slack): render plan summary + run link in interview messages (re #253, stacked on #252) (#254) 2026-05-13 07:41:54 -04:00
fabro-slack feat(slack): render plan summary + run link in interview messages (re #253, stacked on #252) (#254) 2026-05-13 07:41:54 -04:00
fabro-spa feat(dev): gitignore embedded spa assets 2026-04-26 21:31:11 -04:00
fabro-static fix(server): preserve worker terminal color env 2026-05-06 15:54:00 -04:00
fabro-store Add ACP backend support (#237) 2026-05-11 23:39:43 -04:00
fabro-telemetry refactor(workflow): remove retro stage (#230) 2026-05-09 10:18:20 -04:00
fabro-template fix(validate): pick up sibling workflow.toml inputs for bare .fabro path (#242) 2026-05-12 12:05:21 -04:00
fabro-test feat(cli): add Fabro MCP server (#236) 2026-05-11 18:20:50 -04:00
fabro-tracker fix(github): refresh installation tokens during workflows 2026-05-06 07:15:18 -04:00
fabro-types feat(run): add managed branch controls (#243) 2026-05-12 12:00:30 -04:00
fabro-util refactor(error): drop String error shims and DisplayContains test traits 2026-05-01 19:35:22 -04:00
fabro-validate Add ACP backend support (#237) 2026-05-11 23:39:43 -04:00
fabro-vault refactor(api): unify secret metadata types 2026-04-29 20:26:13 -04:00
fabro-workflow feat(model): support open provider catalog data (#245) 2026-05-12 15:42:49 -04:00