66 lines
4.1 KiB
Markdown
66 lines
4.1 KiB
Markdown
# 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`: call `l4d2ctl` through `host_commands` instead of importing `l4d2host` internals.
|
|
- `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
|
|
|
|
- [x] Write failing tests for `l4d2ctl status <name> --json` and `l4d2ctl logs <name> --no-follow`.
|
|
- [x] Run `pytest l4d2host/tests/test_cli.py -q` and confirm the new tests fail because commands do not exist.
|
|
- [x] Add the `status` and `logs` commands to `l4d2host/cli.py` using existing `get_instance_status` and `stream_instance_logs` APIs.
|
|
- [x] Run `pytest l4d2host/tests/test_cli.py -q` and confirm it passes.
|
|
|
|
### Task 2: Add web host command runner
|
|
|
|
- [x] Write failing tests for streaming stdout/stderr callbacks, non-zero exit propagation, and cancellation.
|
|
- [x] Run `pytest l4d2web/tests/test_host_commands.py -q` and confirm failures are for the missing module.
|
|
- [x] Implement `l4d2web/services/host_commands.py` with `run_command`, `HostCommandError`, and `CommandCancelledError`.
|
|
- [x] Run `pytest l4d2web/tests/test_host_commands.py -q` and confirm it passes.
|
|
|
|
### Task 3: Switch web facade to CLI calls
|
|
|
|
- [x] Update facade tests so they monkeypatch `host_commands.run_command` and assert emitted `l4d2ctl` commands.
|
|
- [x] Run `pytest l4d2web/tests/test_l4d2_facade.py -q` and confirm failures show the facade still imports/calls `l4d2host` internals.
|
|
- [x] Replace direct `l4d2host` imports in `l4d2web/services/l4d2_facade.py` with CLI command calls.
|
|
- [x] Run `pytest l4d2web/tests/test_l4d2_facade.py -q` and confirm it passes.
|
|
|
|
### Task 4: Update worker cancellation boundary
|
|
|
|
- [x] Update job worker tests to import `CommandCancelledError` from `l4d2web.services.host_commands`.
|
|
- [x] Run `pytest l4d2web/tests/test_job_worker.py -q` and confirm failures identify the old boundary.
|
|
- [x] Update `l4d2web/services/job_worker.py` to catch the web-side cancellation exception.
|
|
- [x] Run `pytest l4d2web/tests/test_job_worker.py -q` and confirm it passes.
|
|
|
|
### Task 5: Update docs and verify
|
|
|
|
- [x] Update README/plan language from “fixed write commands only” to “fixed write commands plus read commands”.
|
|
- [x] Run `pytest l4d2host/tests -q` and confirm pass.
|
|
- [x] Run `pytest l4d2web/tests -q` and confirm pass.
|
|
- [x] Run `ccc index` if 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 to `l4d2host`.
|