left4me/AGENTS.md
mwiegand 49992b3a26
refactor(repo): uv workspace + hatchling + layout restructure
Migrate from pip-install-e + setuptools to a uv workspace with a
committed uv.lock for deterministic deps. Switch both members to
hatchling, and move package sources into nested standard layout
(l4d2host/l4d2host/, l4d2web/l4d2web/) so builds work from a
read-only source tree — setuptools wrote egg-info to source under
the old layout, which broke uv sync on the root-owned /opt/left4me/src.

Local dev install: `pip install -e ./l4d2host -e ./l4d2web` -> `uv sync`.
.envrc switches from `layout python python3.13` to `use uv`. Python
pinned to 3.13 via .python-version.

l4d2web now declares its cross-dep on l4d2host explicitly via
[tool.uv.sources] (workspace = true). l4d2web/alembic.ini and
l4d2web/alembic/ stay at the project root (standard alembic layout).

Test fixes:
- tests/__init__.py added to both test dirs so pytest doesn't shadow
  l4d2host as a namespace package via outer-dir walk.
- 3 CWD-relative paths in tests (l4d2web/static/css/{tokens,layout}.css
  and js/sse.js) anchored to Path(__file__) so they survive layout
  changes.
- Two test_install.py tests now monkeypatch HOME to tmp_path so they
  stop silently mutating ~/.steam/sdk32 on every run.

628 tests pass under sandboxed `uv run pytest`.

Per docs/superpowers/plans/2026-05-15-uv-workspace-execution.md;
prereq for the ckn-bw bundle's uv-sync action (queued).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 22:04:29 +02:00

3.9 KiB

AGENTS.md

Guidance for coding agents working in this repository.

Mission

Build left4me according to the two implementation plans:

  • docs/superpowers/plans/2026-04-22-l4d2-host-lib-v1.md
  • docs/superpowers/plans/2026-04-23-l4d2-web-app-v1.md

Do not invent architecture outside these plans unless explicitly requested.

Current Project State

  • l4d2host/ and l4d2web/ implementation directories exist.
  • Implementation plans remain the source of truth for contract changes and task sequencing.

Non-Negotiable Constraints

Workspace and tools

  • Do not use git worktrees.
  • Repo is a uv workspace; Python is pinned to 3.13 via .python-version. After fresh checkout: install uv (brew install uv / curl -LsSf https://astral.sh/uv/install.sh | sh), then direnv allow (or uv sync directly). See README Local development for details.

Planning artifacts

  • Design specs live in docs/superpowers/specs/ as YYYY-MM-DD-<topic>-design.md.
  • Implementation plans live in docs/superpowers/plans/ as YYYY-MM-DD-<topic>.md (suffix the topic with -v1/-v2/etc. if a plan is versioned).
  • Commit both to git as soon as the user approves them.
  • Do not leave specs or plans outside this repo. The ~/.claude/plans/<slug>.md plan-mode scratch file is acceptable while plan mode is open; the persisted artifact must end up under docs/superpowers/ and be committed.

Naming and boundaries

  • Use l4d2 naming consistently.
  • Keep host library and web app as separate components.
  • Do not collapse them into one package.

Host library (l4d2host / l4d2ctl)

  • Exposed CLI write command set is fixed:
    • install
    • initialize <name> -f <spec.yaml>
    • start <name>
    • stop <name>
    • delete <name>
  • CLI read commands are allowed for web/host boundary consistency:
    • status <name> --json
    • logs <name> --lines <n> --follow/--no-follow
  • Runtime paths are rooted at LEFT4ME_ROOT, defaulting to /var/lib/left4me.
  • Deployment/config management owns global units under /usr/local/lib/systemd/system and privileged helpers under /usr/local/libexec/left4me.
  • Overlay directories are populated by the web app (workshop downloads, managed-global refresh). The host library only mounts them.
  • Fail-fast subprocess behavior; pass raw stderr; propagate return code.
  • No lock manager, no rollback, no preflight runtime checks.
  • Delete missing instance/runtime dirs must succeed (no-op).
  • Read APIs required for web app integration:
    • get_instance_status(name)
    • stream_instance_logs(name, lines=200, follow=True)

Web app (l4d2-web-app)

  • Flask + server-rendered templates + vendored HTMX.
  • No external frontend framework/dependencies.
  • Custom CSS with tokenized, consistent link and accent colors.
  • Local username/password auth and admin flag.
  • Persist command logs in job_logs table (retain indefinitely).
  • Desired vs actual server state model.
  • Live logs in UI for both jobs and servers.
  • Web app host operations go through l4d2ctl via a host command client, not direct l4d2host imports.
  • Blueprint semantics (locked):
    • private per user in v1
    • live-linked to servers
    • no server-level overrides
    • deleting in-use blueprint is blocked
    • updates apply on next action
    • servers can reassign blueprint anytime

Delivery Workflow

  1. Read both plan files fully before coding.
  2. Execute plan tasks in order.
  3. Keep changes scoped to one task at a time.
  4. Run task-level tests before moving forward.
  5. Do not claim completion without command evidence.
  6. Keep docs updated when behavior/contracts change.

Verification Expectations

Before claiming success on any step, run the relevant command and report actual output status.

Typical commands (once components exist):

  • pytest l4d2host/tests -q
  • pytest l4d2web/tests -q

Change Control

  • If a requested change conflicts with this file, follow explicit user instruction.
  • If plans and code diverge, update plans or flag the mismatch clearly.