No description
Step 9/12 of docs/superpowers/plans/2026-05-17-files-overlay-rewrite.md.
The inline <dialog id="files-editor-modal"> block in overlay_detail.html
is gone. All editor flows (text edit, binary replace, create new) now
exclusively use the URL-addressable modal swapped into #modal-content.
editor.js is now single-purpose (URL-addressable only). Removed:
* editorDialog reference and the editorEls DOM-ref struct
* The legacy editor state object
* CM6 bridge wrappers + UI helpers (getEditorValue/setEditorValue/
setEditorTitle/updateByteCount/updateRenameHint/updateSaveEnabled/
setQueuedReplacement) — they only ever drove the legacy dialog
* withCollisionSuffix (uploads.js still has its copy for the
upload-conflict path; editor.js no longer needs it since the
URL-addressable conflict path is "alert + keep modal open" rather
than overwrite/keep-both)
* openEditorTextNew and openEditorForFile — both functions were
already unreachable from a user action after Steps 6/8
* inLegacyEditor predicate
* Direct-bound listeners on editorEls.filename / contentBox /
editorDialog (input, keydown for Ctrl+S, close)
* Legacy branches in every delegated handler (dragover, dragleave,
drop, change, click)
* legacySaveClicked and legacyDeleteClicked
What stays:
* Routed state (routedReplacement, isRoutedBinaryMode,
setRoutedReplacement, updateRoutedBinarySaveEnabled)
* Delegated dragover/dragleave/drop/change/click handlers — now
single-path each, no legacy/routed branching
* Filename input delegated listener for routed binary mode (so
rename-only Replace stays reachable)
* modal-container close listener that clears routedReplacement
* routedSaveClicked (text edit + is_new), routedReplaceClicked
(binary, with rename-or-replace fork), routedDeleteClicked
* "new-file" and "edit" registered handlers (the "edit" handler is
no longer split editable/binary — the server picks the template
branch)
routedDeleteClicked gained one capability that was missing in Step 8:
it now reads rel-path from either the textarea (text mode) OR the
.files-editor-binary panel, so deletion works for binary files in the
URL-addressable modal too (previously routed-mode binary delete fell
through to legacy, which is now gone).
Test added: test_overlay_detail_no_longer_renders_legacy_editor_dialog
asserts the legacy dialog markup is absent from /overlays/<id> while
the other inline dialogs are still present (Step 3 didn't move them).
Numbers:
editor.js: 660 → 309 lines (-351). Plan estimated ~200; actual is
~50% larger due to module-header comments + the rename-or-replace
fork in routedReplaceClicked. Pure-routing-only and single-mode
per click, which was the structural goal.
Total across files-overlay/: 1432 → 1191 lines.
pytest: 579 → 580 passed, 1 skipped, 3 deselected.
Verified live on /overlays/2 in Chromium:
* id="files-editor-modal" not in DOM; new-folder/delete/conflict
dialogs still present
* "+ new file" → routed modal, Create button
* Click other.cfg (editable) → routed modal, Save button, content
pre-filled
* Click test.png (binary) → routed modal, Replace button, initially
disabled
* No console errors
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| deploy | ||
| docs | ||
| examples/script-overlays | ||
| l4d2host | ||
| l4d2web | ||
| scripts | ||
| .envrc | ||
| .gitignore | ||
| .python-version | ||
| AGENTS.md | ||
| cvar_list | ||
| pyproject.toml | ||
| README.md | ||
| uv.lock | ||
left4me
left4me is a local L4D2 server management platform with two planned components:
l4d2host+l4d2ctl(host library + CLI)l4d2-web-app(Flask web app for users, blueprints, servers, jobs, and logs)
Status
Implementation plans remain the source of truth for architecture and task sequencing:
docs/superpowers/plans/2026-04-22-l4d2-host-lib-v1.mddocs/superpowers/plans/2026-04-23-l4d2-web-app-v1.md
Locked v1 Decisions
- Naming is strictly
l4d2(notl4d). - Host library and web app are separate components.
- Host CLI write commands are fixed to:
installinitialize <name> -f <spec.yaml>start <name>stop <name>delete <name>
- Host CLI read commands are available for the web/host boundary:
status <name> --jsonlogs <name> --lines <n> --follow/--no-follow
- The web app calls host operations through
l4d2ctl, not directl4d2hostimports. - Deployment uses
/var/lib/left4mefor runtime state,/opt/left4mefor repository contents and the virtualenv,/etc/left4mefor environment files, and global units under/usr/local/lib/systemd/system. - Overlay handling is directory-based; the web app populates each overlay (workshop downloads, managed-global refresh).
- No lock manager, no rollback, no preflight checks in host library.
- CLI propagates subprocess failures via stderr and return code.
deleteon missing instance is no-op success.- Blueprint model (web app):
- user-private in v1
- servers are live-linked to blueprint
- no per-server overrides
- delete blueprint blocked when linked servers exist
- blueprint changes apply on next action
- server can reassign blueprint anytime
Planned Repository Layout
l4d2host/l4d2web/deploy/docs/superpowers/plans/
Deployment
See deploy/README.md for the Linux test deployment contract, including the runtime user, target filesystem layout, systemd units, privileged helpers, sudoers rules, admin bootstrap, and overlay reference rules.
Local development
This repo is a uv workspace (l4d2host + l4d2web as members) with a committed uv.lock and a .python-version pinning Python 3.13 (matching the Debian Trixie production target).
One-time prereq: install uv (macOS: brew install uv; Linux: curl -LsSf https://astral.sh/uv/install.sh | sh — uv is not yet in Debian stable's apt).
direnv allowonce per fresh checkout (and after any.envrcchange)..envrcusesuse uv, which runsuv syncand activates.venv/oncd.- Without direnv:
uv syncat the repo root creates.venv/, installs both workspace members editable, and pulls in dev deps (pytest) from the lockfile. - Tests:
uv run pytest(or justpytestonce the venv is on PATH).
Tech Stack (planned)
- Python 3.13+ (workspace uses uv + hatchling)
- Typer, PyYAML, pytest
- Flask, SQLAlchemy, Alembic
- HTMX (vendored locally), custom CSS, SSE
- systemd units, kernel overlayfs (mounted via the
left4me-overlayprivileged helper), steamcmd
Recommended Implementation Order
- Implement
l4d2hostplan first. - Implement
l4d2webplan second. - Keep tests green task-by-task (TDD flow from plans).
- Keep commits small and aligned with plan tasks.
Contributing Notes
- Follow plan task order unless explicitly re-planned.
- Keep contracts above unchanged unless the user asks to change them.
- Update plan docs when scope or behavior changes.