Split the monolithic context.py (117 lines) into five purpose-specific
modules following single-responsibility principle:
- config.py: Server-level constants (DATA_DIR, SESSIONS_DIR, PORT,
STALE_EVENT_AGE, _state_lock)
- agents.py: Agent-specific paths and caches (CLAUDE_PROJECTS_DIR,
CODEX_SESSIONS_DIR, discovery caches)
- auth.py: Authentication token generation/validation for spawn endpoint
- spawn_config.py: Spawn feature configuration (PENDING_SPAWNS_DIR,
rate limiting, projects watcher thread)
- zellij.py: Zellij binary resolution and session management constants
This refactoring improves:
- Code navigation: Find relevant constants by domain, not alphabetically
- Testing: Each module can be tested in isolation
- Import clarity: Mixins import only what they need
- Future maintenance: Changes to one domain don't risk breaking others
All mixins updated to import from new module locations. Tests updated
to use new import paths.
Includes PROPOSED_CODE_FILE_REORGANIZATION_PLAN.md documenting the
rationale and mapping from old to new locations.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Position the spawn modal directly under the 'New Agent' button without a
blur overlay. Uses click-outside dismissal and absolute positioning.
Reduces visual disruption for quick agent spawning.
- Add empty-state message in SpawnModal when no projects found
- Spawn button stays disabled when projects list is empty
- Server already handled OSError/missing dir gracefully (returns [])
- Add tests: missing directory, only-hidden-dirs, empty API responses
Closes: bd-3c7
Add routing for spawn-related endpoints to HttpMixin:
- GET /api/projects -> _handle_projects
- GET /api/health -> _handle_health
- POST /api/spawn -> _handle_spawn
- POST /api/projects/refresh -> _handle_projects_refresh
Update CORS preflight (AC-39) to include GET in allowed methods
and Authorization in allowed headers.
Closes bd-2al
Closes bd-3ny. Added mousedown listener that dismisses the dropdown when
clicking outside both the dropdown and textarea. Uses early return to avoid
registering listeners when dropdown is already closed.
Comprehensive test coverage for _get_conversation_mtime() and its
integration with _collect_sessions().
Test cases:
- Claude sessions: file exists, file missing, OSError on stat,
missing project_dir, missing session_id
- Codex sessions: transcript_path exists, transcript_path missing,
discovery fallback, discovery returns None, OSError on stat
- Edge cases: unknown agent type, missing agent key
- Integration: mtime included when file exists, omitted when missing
- Change detection: mtime changes trigger payload hash changes
Uses mock patching to isolate file system interactions and test
error handling paths without requiring actual conversation files.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds comprehensive test coverage for the amc_server package:
- test_context.py: Tests _resolve_zellij_bin preference order (which
first, then fallback to bare name)
- test_control.py: Tests SessionControlMixin including two-step Enter
injection with configurable delay, freeform response handling,
plugin inject with explicit session/pane targeting, and unsafe
fallback behavior
- test_state.py: Tests StateMixin zellij session parsing with the
resolved binary path
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>