mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
Addresses 1 High + 4 Medium findings from the PR-G1 code review. H1: `_inject_continue_rtk_systemmessage` previously fell through to an unconditional `data["systemMessage"] = RTK_INSTRUCTIONS_BLOCK` when the existing value was non-string (dict / list / number), silently clobbering user data despite a docstring promising otherwise. Extracted a small helper `_apply_rtk_to_systemmessage_field` that returns `(changed, ok)` and refuses loudly on non-string user data with guidance to clear the field before re-running. The injecting helper reports `ok=False` on any refusal so the caller surfaces it as a warning instead of pretending the injection succeeded. Tests cover dict, list, and int values for both top-level and per-model sites. M2: Continue overrides top-level `systemMessage` with per-model `systemMessage` when set, so users with per-model configs were silently getting no RTK guidance. The helper now visits every `models[i]` dict in addition to the top-level field, applying the same idempotency and non- string-clobber rules at each site. Non-dict entries in `models[]` are skipped. M3: The openhands subcommand previously called `_ensure_rtk_binary()` and ignored the result, then proceeded to inject `OPENHANDS_INSTRUCTIONS` even when rtk install had failed. Mirrored the cline/continue/goose pattern — if rtk install fails (and `--no-context-tool` was not passed), exit 1 with a clear error explaining how to install rtk manually or skip rtk. No silent fallback to env-only injection. M4: Wrapped the marker-injection + rtk-setup prelude of all four new subcommands (cline, continue, goose, openhands) in a try/except for KeyboardInterrupt. On Ctrl-C between marker injection and proxy startup, we emit a clear "wrap was interrupted; marker file at <path> is on disk; rerun to retry — it's idempotent" message and exit 130. Pre-compute the marker path so the message can name it even if the interrupt fires before `_inject_rtk_instructions` returns. Introduces a small `_emit_wrap_ interrupted` helper. M1 + M5: Documented the uninstall procedure (hand-remove the `<!-- headroom:rtk-instructions -->` block) and the lean-ctx agent-name caveat in each of the four new subcommand docstrings. We chose docstring guidance over `unwrap cline|continue|goose|openhands` subcommands to keep the PR scoped. Also documented Continue's modern YAML-first config in the `continue` docstring so users on the YAML schema know this command only handles the JSON variant. Tests: +9 new tests across the 4 wrap test files exercising H1 refusal (dict/list/int parametrized × top-level + per-model), M2 per-model injection + idempotency + non-dict-entry skip, M3 rtk install failure abort + `--no-context-tool` bypass, and M4 KeyboardInterrupt-during- prelude flows for all four agents. Cosmetic: Removed the misleading "re-invocation in the same shell session" comment from openhands; the marker guard is for pre-existing env vars. |
||
|---|---|---|
| .. | ||
| test_init_cli.py | ||
| test_install_cli.py | ||
| test_main_help_version.py | ||
| test_mcp.py | ||
| test_unwrap_claude.py | ||
| test_wrap_aider.py | ||
| test_wrap_bridge.py | ||
| test_wrap_cline.py | ||
| test_wrap_codex.py | ||
| test_wrap_continue.py | ||
| test_wrap_copilot.py | ||
| test_wrap_goose.py | ||
| test_wrap_openclaw.py | ||
| test_wrap_openhands.py | ||
| test_wrap_persistent.py | ||