4.1 KiB
L4D2 CLI Host Client Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Make l4d2web manage the local host through l4d2ctl instead of importing l4d2host internals, so the same execution boundary can later be transported over SSH.
Architecture: l4d2host remains the host-local implementation behind l4d2ctl. l4d2web gains a small local command runner that streams CLI stdout/stderr into jobs, supports cancellation, and parses status JSON. Hosts and overlay sync remain out of this change; the current machine is the implicit local host.
Tech Stack: Python 3.12+, Typer, subprocess, Flask, SQLAlchemy, pytest.
File Map
l4d2host/cli.py: add read commands for status and logs.l4d2host/tests/test_cli.py: cover the expanded CLI contract.l4d2web/services/host_commands.py: new subprocess-based host command runner and cancellation exception.l4d2web/services/l4d2_facade.py: calll4d2ctlthroughhost_commandsinstead of importingl4d2hostinternals.l4d2web/services/job_worker.py: catch the web-side cancellation exception.l4d2web/tests/test_host_commands.py: cover callback streaming, failures, and cancellation.l4d2web/tests/test_l4d2_facade.py: verify facade emits CLI commands and parses status.l4d2web/tests/test_job_worker.py: update cancellation imports.l4d2host/README.md,l4d2web/README.md, existing implementation plans: document the relaxed CLI boundary.
Tasks
Task 1: Add host CLI read commands
- Write failing tests for
l4d2ctl status <name> --jsonandl4d2ctl logs <name> --no-follow. - Run
pytest l4d2host/tests/test_cli.py -qand confirm the new tests fail because commands do not exist. - Add the
statusandlogscommands tol4d2host/cli.pyusing existingget_instance_statusandstream_instance_logsAPIs. - Run
pytest l4d2host/tests/test_cli.py -qand confirm it passes.
Task 2: Add web host command runner
- Write failing tests for streaming stdout/stderr callbacks, non-zero exit propagation, and cancellation.
- Run
pytest l4d2web/tests/test_host_commands.py -qand confirm failures are for the missing module. - Implement
l4d2web/services/host_commands.pywithrun_command,HostCommandError, andCommandCancelledError. - Run
pytest l4d2web/tests/test_host_commands.py -qand confirm it passes.
Task 3: Switch web facade to CLI calls
- Update facade tests so they monkeypatch
host_commands.run_commandand assert emittedl4d2ctlcommands. - Run
pytest l4d2web/tests/test_l4d2_facade.py -qand confirm failures show the facade still imports/callsl4d2hostinternals. - Replace direct
l4d2hostimports inl4d2web/services/l4d2_facade.pywith CLI command calls. - Run
pytest l4d2web/tests/test_l4d2_facade.py -qand confirm it passes.
Task 4: Update worker cancellation boundary
- Update job worker tests to import
CommandCancelledErrorfroml4d2web.services.host_commands. - Run
pytest l4d2web/tests/test_job_worker.py -qand confirm failures identify the old boundary. - Update
l4d2web/services/job_worker.pyto catch the web-side cancellation exception. - Run
pytest l4d2web/tests/test_job_worker.py -qand confirm it passes.
Task 5: Update docs and verify
- Update README/plan language from “fixed write commands only” to “fixed write commands plus read commands”.
- Run
pytest l4d2host/tests -qand confirm pass. - Run
pytest l4d2web/tests -qand confirm pass. - Run
ccc indexif available so the code index reflects the boundary change.
Self-Review
- Spec coverage: covers CLI read commands, web-side CLI execution, status/log parsing, cancellation, docs, and verification.
- Scope: hosts table, SSH transport, and overlay sync are explicitly excluded from this change.
- Type consistency: the web-side cancellation type is
l4d2web.services.host_commands.CommandCancelledError; the host-side process type remains internal tol4d2host.