You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
CodeAssembly needs to install eventHooks entries into Rovo Dev's ~/.rovodev/config.yml, but the file is user-curated YAML carrying comments and foreign eventHooks entries written by other tools. Because multiple tools register commands on the same events (which Rovo Dev runs in parallel), CodeAssembly's commands are scattered across several event arrays, interleaved with foreign commands. No utility exists to add, verify, or remove CodeAssembly-owned entries without disturbing foreign content.
Context
Foreign comments and unrelated config keys must survive every operation. Comments inside CodeAssembly-owned entries need not be preserved, since an owned entry is CodeAssembly's to replace or rebuild as a unit.
Ownership is per-entry, marked by a sentinel embedded in each entry and matched wherever the entry sits — across multiple event arrays, interleaved with foreign entries. The sentinel encoding (a token in the hook command, or a metadata field if Rovo Dev verifiably ignores unknown keys) is the consumer's (Emit session-lifecycle events via harness hooks #1005) to fix once it observes real Rovo Dev behavior; this utility takes the sentinel matcher as an injected argument and stays agnostic about what it marks. Comment-fence / contiguous-region sentinels are ruled out: owned entries are scattered and interleaved, so no fence can delimit ownership.
eventHooks.events items are {name, commands[]}. Whether Rovo Dev tolerates duplicate name items or requires merging into an existing item's commands list is the consumer's concern; the sentinel rides the entry either way.
Functions operate on a parsed yamlDocument; the caller owns file IO. This matches the pure-transform split of the existing prompts-yml-region.ts.
A library module packages/agents/src/lib/rovo-config-hooks.ts exposing three operations over a Document plus caller-supplied entries and a sentinel matcher:
ensure — idempotent insert-or-replace, creating missing structure (including a missing eventHooks section); a drifted sentinel-matching entry is replaced in place, not duplicated.
check — reports present / drifted / absent per supplied entry (drifted = a sentinel-matching entry whose content differs).
remove — deletes only sentinel-matching entries and prunes structure the removal emptied.
Mutation is via the comment-preserving yaml Document API (surgical: foreign entries, foreign comments, and unrelated keys are untouched). Whole-entry rebuild is a sanctioned fallback where an edit can't be expressed surgically.
Acceptance criteria
Must have
Ensure is idempotent: an immediate re-run is a no-op, and a drifted sentinel-matching entry is replaced rather than duplicated.
Foreign eventHooks entries, foreign comments, and unrelated config keys survive every operation unchanged.
Owned entries scattered across multiple event arrays and interleaved with foreign entries are each matched and mutated correctly.
Remove deletes only sentinel-matching entries and prunes structure emptied by the removal.
A Document carrying parse errors is never treated as writable; the module surfaces the parse failure to the caller rather than emitting a corrupted result.
Problem
CodeAssembly needs to install
eventHooksentries into Rovo Dev's~/.rovodev/config.yml, but the file is user-curated YAML carrying comments and foreigneventHooksentries written by other tools. Because multiple tools register commands on the same events (which Rovo Dev runs in parallel), CodeAssembly's commands are scattered across several event arrays, interleaved with foreign commands. No utility exists to add, verify, or remove CodeAssembly-owned entries without disturbing foreign content.Context
eventHooks.eventsitems are{name, commands[]}. Whether Rovo Dev tolerates duplicatenameitems or requires merging into an existing item'scommandslist is the consumer's concern; the sentinel rides the entry either way.yamlDocument; the caller owns file IO. This matches the pure-transform split of the existingprompts-yml-region.ts.rovo-config-hooks.ts; a genericconfig.ymlsection-mutation layer is extracted only when a second consumer needs it.Proposed solution
A library module
packages/agents/src/lib/rovo-config-hooks.tsexposing three operations over aDocumentplus caller-supplied entries and a sentinel matcher:eventHookssection); a drifted sentinel-matching entry is replaced in place, not duplicated.Mutation is via the comment-preserving
yamlDocument API (surgical: foreign entries, foreign comments, and unrelated keys are untouched). Whole-entry rebuild is a sanctioned fallback where an edit can't be expressed surgically.Acceptance criteria
Must have
eventHooksentries, foreign comments, and unrelated config keys survive every operation unchanged.Documentcarrying parse errors is never treated as writable; the module surfaces the parse failure to the caller rather than emitting a corrupted result.