Skip to content

Bridge generate ignores --config: round-trip reads use plugin UI settings #279

Description

@nathanacurtis

The CLI resolves a config for specs generate --from-bridge and then never sends it. postGenerateFromSelection({ fileKey, nodeId }) carries only those two fields, so the plugin processes the node under whatever its own UI settings happen to be. The CLI's --config governs only where output is written.

Why it matters

Every render round-trip in the #208 verification loop silently compares a baseline generated under one config against a read performed under another. The differences that produces look exactly like render fidelity loss.

Concretely, from the #266 investigation: the plugin's Include invalid variants setting defaults to off. testWrap's baseline holds 47 variant entries (8 valid + 39 invalid); it read back as 8. The differ compares index-to-index, so {b:2} was compared against {a:2,b:2,c:2} and every subsequent row cascaded.

Turning that one toggle on took four fixtures from 231 differences to 1 — and that last one was a genuine defect that had been buried in the noise the whole time.

Component Config mismatched Config matched
testChildren 14 0
testChildren2 17 0
testWrap 101 0
testWrap2 99 1 (real)

The harness does warn about the mismatch, but a warning next to a 101-row table reads as a footnote.

Where the config would flow

Layer Change Size
cli/src/bridge/client.ts add config?: ResolvedConfig to GenerateFromSelectionRequestBody ~2 lines
cli/src/commands/GenerateCommand.ts pass it — modelConfig is already loaded at line 277 ~1 line
cli/src/bridge/server.ts widen the /generate params, thread through sendGenerateFromSelection, add to the ws message ~4 lines
specs-plugin-2/src/UI/Managers/MessageManager.ts read m.config, pass into this.specs.process(...) ~2 lines
specs-plugin-2/src/SpecsController.ts the actual work — see scope decision

Pending decision — scope

SpecsController.process() reads this._settings at four points, not one:

  • buildPhaseConfiguration(this._settings) (line 119)
  • settingsToModelConfig(this._settings) (line 125)
  • FORMAT_OUTPUT, choosing YAML vs JSON (line 162)
  • new OutputController(this._settings) (line 170)

Two options:

  • Narrow — override settingsToModelConfig only. ~15 lines across all repos. Fixes the entire class of bug above, since include and processing are what shape the spec body. Leaves format.output still stamped from UI state, so that config-mismatch warning persists (benign — the harness writes YAML either way).
  • Complete — make process() take a ResolvedConfig and thread it through all four sites. Forces a decision about buildPhaseConfiguration and OutputController, which are Settings-shaped rather than ResolvedConfig-shaped. Roughly a day, with real regression risk in the plugin's normal interactive path.

Recommendation: narrow, escalating only if it proves insufficient.

Whichever is chosen, a per-request config must not persist into the plugin's stored UI settings — an automated round-trip should not silently reconfigure the user's plugin.

Note on config resolution

generate --from-bridge has no source spec to read a config from — it is creating one. The CLI's existing resolution (--config, else the workspace root) is already correct and already in hand; it simply is not sent. A two-step "config in the spec's source, falling back to the workspace root" applies to render, where a baseline spec exists and carries metadata.config.

Done when

  • A generate --from-bridge run reports metadata.config.include and metadata.config.processing matching the config the CLI resolved, regardless of the plugin's UI settings.
  • A round-trip of testWrap with the plugin toggles deliberately set wrong still reports 0 fidelity differences.
  • The plugin's stored settings are unchanged after such a run.

Metadata

Metadata

Assignees

Labels

clispecs-cli and MCP server

Type

No type

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions