fix: path traversal guard, rollback extension re-registration, lifecycle docs

- remove_tracked_files: validate resolved path stays within project_path
  before unlinking; reject entries with '../' that escape the project root
- Rollback: call _reregister_extension_commands() during rollback (same
  as success path) so extension files are properly restored
- AgentBootstrap: comprehensive lifecycle flow docstring documenting the
  setup → finalize_setup → get_tracked_files → check_modified → teardown
  chain and explaining why tracking all files is safe (hash check)
This commit is contained in:
Manfred Riem
2026-03-23 11:56:50 -05:00
parent 48392ea865
commit 720ac509d2
2 changed files with 29 additions and 5 deletions

View File

@@ -2740,14 +2740,12 @@ def agent_switch(
rollback_resolved = resolve_agent_pack(current_agent, project_path=project_path)
rollback_bs = load_bootstrap(rollback_resolved.path, rollback_resolved.manifest)
rollback_files = rollback_bs.setup(project_path, script_type, options)
# Re-register extension commands (same as the success path)
rollback_ext_files = _reregister_extension_commands(project_path, current_agent)
rollback_bs.finalize_setup(
project_path,
agent_files=rollback_files,
extension_files=list(
(project_path / p).resolve()
for p in old_tracked_ext
if (project_path / p).is_file()
),
extension_files=rollback_ext_files,
)
console.print(f" [green]✓[/green] {current_agent} restored")
except Exception: