Skip to content

Latest commit

 

History

History
283 lines (262 loc) · 16 KB

File metadata and controls

283 lines (262 loc) · 16 KB

Centaurx Backlog

Checklist-style backlog organized for small, reviewable steps.

  • P0: Observability + failure transparency (must-do, iterate until DONE)

    • Runner logging regression + output forwarding: centaurx serve must emit server-side logs for every runner command/exec (Info/Debug/Trace), include stdout+stderr forwarding, default runner LOG_MODE=json, and add regression tests + log reader that assert logs across the server↔runner flow.
    • COMPREHENSIVE LOGGING EVERYWHERE: add Warn/Info/Debug/Trace coverage across the codebase (HTTP, SSH, runner, service, repo, persistence, shipohoy, UI).
    • Surface runner failures to user buffers (system output) with clear, actionable messages (e.g. codex auth missing/401, runner exit, container start failure).
    • Make /new and prompt submission emit user-facing status lines while work is in-flight (starting runner, creating repo, cloning, git init, etc.).
    • Ensure runner errors are logged server-side with root cause (gRPC status, exit codes, stderr, container logs).
    • Expand tests to assert failure paths are surfaced (e.g. codex 401, runner not starting) and that user-visible output/logs appear.
    • Add tests that prove codex auth failure yields explicit errors (not silent blank output).
    • Runner lifecycle hygiene: runner containers must not linger after server exit/crash.
      • Implement server-side shutdown cleanup (close all runner tabs on Stop).
      • Add runner keepalive (ping every 10s; exit after 3 missed) so orphaned runners self-terminate.
      • Add tests that verify runners stop on server shutdown and auto-remove cleans them up.
    • Context plumbing fix: eliminate detached context.Background() usage that prevents cancellation; plumb request/session context through runner commands and codex exec so shutdown/timeout cancels correctly (SSH + HTTP + runner).
      • Replace background contexts in internal/command/handler.go and core/service.go with caller contexts or derived timeouts.
      • Add regression tests that ensure cancellation propagates (e.g. HTTP request cancel does not orphan runner; service shutdown stops in-flight operations).
    • Regression tests for runner repo root mapping: add unit tests that fail if runner.repo_root is set to a host path (e.g. equals runner.host_repo_root), and ensure runnercontainer.NewProvider refuses host paths when HostRepoRoot is set.
  • P0: TUI/Web theming + formatting (outrun default, future palettes)

    • SSH TUI tab bar redesign (approach A):
      • Render a full-width colored tab bar (solid background across entire top line) so output cannot overdraw it.
      • Active tab is indicated by background color change (no [] brackets).
      • Introduce an ANSI-aware tab renderer that trims by visible width without cutting escape codes.
      • Sanitize output lines for SSH TUI rendering (strip ANSI/control sequences like \x1b[ and bare \r) to prevent top-bar corruption.
      • Add regression tests for: tab bar always renders on line 1; active tab background color changes; ANSI/control sequences in output cannot hide the bar.
    • Theme registry:
      • Default theme name outrun (formerly outrun-electric).
      • Additional palettes registered: gruvbox, tokyo-midnight (selectable but not necessarily wired to config yet).
      • /theme <name> command supported in SSH TUI and HTTP UI.
    • Stream formatting tweaks:
      • Remove stderr: prefix; instead render stderr lines in a high-contrast pink (outrun palette) with bold styling in SSH TUI.
      • Ensure error lines remain red across both SSH and web UI.
    • Markdown rendering (SSH TUI + web UI) per MESSAGES.md:
      • item.type: command_execution stays plain (no markdown), but add /togglefullcommandoutput (default terse: max 5 lines of command + output) with mode toggle persisted per user/session.
      • item.type: reasoning render markdown; default italic; bold is bold-italic; apply distinct outrun blue/pink color (not same as agent text).
      • item.type: agent_message render markdown; bold/italic styles; inline code in accent color.
      • Decide whether to adopt a markdown renderer or a minimal internal parser (document the choice + tests).
    • Worked-for separator line before final item.completed agent_message:
      • Add a full-width divider (e.g. ─ Worked for 19s ─────) in SSH TUI.
      • Add the same in web UI (CSS-driven full-width rule).
      • Compute duration from prompt start to final item completion; show s/m/h as appropriate.
    • Web UI TAB key behavior:
      • TAB should only cycle between tabs (not move focus between input/terminal/etc).
      • Add chromedp regression test asserting TAB cycles to the next tab.
    • Web UI multiline input scrollbar should be themed (match current palette; no default white scrollbar).
  • P0: SSH auth hardening + pubkey management

    • Require SSH pubkey authentication and TOTP (prompt after successful pubkey auth).
    • SSH TOTP prompt must be exactly Verification code: (no echo).
    • Do not auto-generate SSH login pubkeys on user creation; new users have zero login pubkeys.
    • Add admin CLI pubkey management (add/list/remove) for users.
    • Add user commands:
      • /addloginpubkey <pubkey>
      • /listloginpubkeys
      • /rmloginpubkey <id> (1-based in insertion order)
      • /pubkey (print git SSH public key for use in GitHub, etc.)
    • Tests: SSH auth flow requires pubkey + TOTP; prompt text and no-echo behavior asserted.
    • Tests: anonymous users rejected; wrong pubkey rejected; missing/wrong TOTP rejected; any valid pubkey for a user succeeds.
    • Tests: only pubkeys associated with the username are accepted (no cross-user auth).
  • P0: Terminal UX regression (copy/paste)

    • Fix SSH TUI selection so mouse drag selection persists and can be copied (avoid redundant redraws that clear selection).
    • Add regression test that ensures SSH TUI does not redraw when state is unchanged (prevents selection loss).
  • P1: Session UX + tab isolation

    • /renew command: renew the current tab by starting a fresh codex session (new session ID) without changing repo/tab name.
    • Tab switching is session-scoped: active tab changes in one SSH session do not affect other SSH sessions or the web UI (and vice versa).
  • Phase 0: Repo hygiene and scaffolding

    • Add doc.go to each new package (Go package docs).
    • Create .golangci.yml in repo root if missing (per AGENTS.md).
    • Establish module layout:
      • cmd/centaurx (CLI)
      • centaurx (root compositor)
      • core (service API + implementation)
      • schema (domain data types)
      • httpapi (HTTP API + UI)
      • sshserver (SSH server)
      • internal/... for implementation details
    • Refactor package layout to avoid import cycles (core/schema split + root compositor)
  • Phase 1: Core domain model (transport-agnostic)

    • Define core types:
      • Tab, TabID, TabName, SessionID, RepoRef
      • Buffer (scrollback) with cursor and scroll position
      • Event types for parsed codex JSONL
      • Renderer interface for SSH/HTTP formatting
      • Command / SlashCommand routing
    • Implement tab manager:
      • Create, close, switch, list
      • Per-user tab registry
      • Scrollback persistence per tab
    • Implement repo manager:
      • Repo prefix config
      • /new creates repo dir + git init
      • /repo validates repo/.git
      • /listrepos enumerates repo dirs
  • Phase 2: Codex exec runner + JSONL parsing

    • Implement codex exec runner:
      • Start new session (codex exec --json <prompt>)
      • Resume existing session (codex exec resume <id> --json <prompt>)
      • Thread ID capture from thread.started
      • Per-tab model selection
      • Support prompt via stdin using -
    • JSONL parser:
      • Discriminated union on type
      • Tolerant to unknown fields/types
      • Parse item.* types (agent_message, reasoning, command_execution, etc.)
    • Output formatter:
      • Convert parsed events into lines for terminal buffer
      • Separate SSH vs HTTP formatting (no ANSI in HTTP)
    • Mock codex exec CLI:
      • centaurx codex-mock subcommand with exec and exec resume <id>
      • Support prompt via args or stdin (-)
      • Emit deterministic JSONL with varied event shapes
      • Support optional --seed, --scenario, --delay-ms, --linger-ms
      • Handle SIGHUP/SIGTERM gracefully (emit error event, exit)
  • Phase 3: Slash commands

    • /new <repo_name>:
      • Open existing repo in a new tab if it already exists
      • Create repo dir and git init
      • Switch to centaurx branch on creation
      • New tab named after repo (truncate to 10 chars; if longer, use first 9 chars + $)
    • /repo removed (use /new for create/open)
    • /listrepos
    • /rm <number_or_name>
    • Command semantics update:
      • Add /close to close the current tab (no args).
      • /quit, /exit, /logout should exit the SSH session (no tab close).
      • Ensure /quit no longer aliases /rm anywhere (SSH/HTTP/UI/handler).
    • /model <model> per-tab model selection
      • Normalize/validate to [A-Za-z0-9._-]
      • If missing argument, return syntax error and include seeded model list
    • /stop or /z:
      • SIGTERM, wait 10s
      • SIGKILL if still running
      • Emit status messages
    • /git commit [message]:
      • git add -A
      • If message missing, call codex exec resume with gpt-5.1-codex-mini
      • Use returned single-line message for git commit -m
  • Phase 3b: State persistence

    • Persist per-user tabs, buffers, scroll offsets, and session ids to disk
    • Load persisted state on startup
  • Phase 4: Runner split + IPC (gRPC over UDS)

    • Define gRPC proto for runner (see docs/runner-grpc.md):
      • Start new codex session (exec)
      • Resume codex session (exec resume)
      • Run shell command (for ! and /git)
      • Signal session (stop/z)
      • Server-streamed events for output
    • Add proto/runner/v1/runner.proto (spec only; no codegen yet)
    • Add top-level generate.go using protoc (no codegen run yet)
    • Add internal/runnerpb package placeholder with doc.go
    • Add centaurx runner gRPC server (wraps codex exec + shell commands)
    • Add gRPC client in centaurx server and replace local runner usage
    • Use Unix domain sockets only (no TCP); add configurable socket path
    • Bump config version to enforce runner socket path
    • Ensure runner supports stdin prompts and preserves thread_id semantics
  • Phase 4b: Per-user repo isolation

    • Per-user repo roots: $HOME/.centaurx/repos/<user>/...
    • Enforce username validation [a-z0-9._-] in users CLI (no normalization)
    • Update repo manager to scope list/open/create to the authenticated user
  • Phase 4c: Per-user SSH credentials (Option B)

    • Store per-user SSH private keys encrypted at rest (kryptograf)
    • Extend centaurx users:
      • Generate SSH key on users add (ed25519 default)
      • Support --ssh-key-type (ed25519 | rsa) and --ssh-key-bits
      • Output public key for user onboarding (GitHub, etc.)
      • Add users rotate-ssh-key
    • Implement per-user SSH agent in server (x/crypto/ssh/agent)
    • Expose per-user agent socket to runner (shared volume)
  • Phase 4d: Extended commands and repo flows (post-runner split)

    • /help slash command with concise usage for all supported commands
    • ! <cmd> run arbitrary shell commands in the tab's repo directory (via runner)
    • /new accepts SSH git URLs (e.g. github.com/org/repo) and clones:
      • Use SSH by default (convert to git@host:org/repo.git where needed)
      • Tab name = repo basename (truncate to 10 chars; if longer, use first 9 chars + $)
      • If repo already exists locally, open it in a new tab (no clone)
      • Only local repo creation switches to centaurx branch (do not switch on clones)
  • Phase 5: SSH server (TUI)

    • SSH server:
      • gliderlabs/ssh session handling
      • PTY allocation via gliderlabs/ssh
      • Window resize handling
      • Auto-generate host key if missing
    • TUI renderer:
      • Top row tab bar
      • Scrollback viewport + prompt
      • TAB to switch tabs
      • PageUp/PageDown to scroll
      • Typing cancels scrollback
    • Prompt editing:
      • Custom line editor (ctrl+w, alt+f/b, ctrl+a/e)
      • Screen renderer + cursor positioning
    • Spinner prompt when codex is running:
      • Rotate |/-\ every ~250ms
      • Allow input while running; queue prompts until current run completes
      • Allow slash commands and ! while spinner active
  • Phase 6: HTTP API + UI

    • Auth:
      • JSON file at ~/.centaurx/users.json
      • bcrypt password hashing
      • TOTP via pquerna/otp
      • Session cookie (long-lived) + logout endpoint
    • API:
      • List tabs, create tab, close tab
      • Send prompt to tab
      • Stream output via SSE (EventSource)
      • Switch tabs and query scrollback buffer
    • UI:
      • Single-page app (minimal JS + SSE)
      • Monospace terminal-lookalike
      • Tab bar + scrollback + prompt per tab
      • No ANSI rendering; plain text
      • Mobile-friendly (Chrome/Duck)
      • Keyboard tab cycling (TAB) for HTTP view
      • Preserve per-tab scroll position + auto-scroll toggle
  • Phase 7: Config and CLI

    • Viper config file:
      • Repo prefix (default $HOME/.centaurx/repos)
      • Default model
      • Allowed models list
      • HTTP auth users (seeded)
      • SSH/HTTP ports
      • Codex exec path/flags if needed
      • Runner socket path (UDS)
      • Per-user repo roots under repo_root/<user>
      • SSH key storage paths (key store + key dir + agent dir)
      • Config version bump to 4 for breaking changes
    • Cobra CLI:
      • centaurx serve (start SSH + HTTP)
      • centaurx bootstrap (dump default config)
      • centaurx version
      • centaurx users (list/add/delete/chpasswd/rotate-totp)
  • Phase 8: Quality gates and tests

    • Add tests for:
      • JSONL parsing and session id capture
      • Repo manager behavior (/new, /listrepos)
      • Slash command routing
      • Buffer scroll/viewport logic
      • State persistence load/save (integration coverage)
      • HTTP API + SSE integration tests
      • SSH session integration tests
      • Web UI smoke test (chromedp)
      • gRPC runner integration tests (start/run/stop/stream)
      • ! command and queued prompt behavior tests
      • Ensure integration tests run without containers (local binaries + UDS)
    • Run required checks:
      • go test ./...
      • go vet ./...
      • golint ./...
      • golangci-lint run ./...
  • Phase 9: Containerization (nerdctl compose)

    • Ensure centaurx runs as PID1 via pkt.systems/psi before containerizing
    • Add Containerfile for centaurx (server container)
    • Add Containerfile for cxrunner (runner container)
    • Add docker-compose.yaml:
      • Build both images
      • Expose HTTP 27480 and SSH 27422
      • Shared volume for repos and runner socket
      • Mount per-user SSH agent sockets into runner
      • Run both containers with host UID/GID (rootless)
      • Mount host containerd socket at /run/user/<uid>/containerd/containerd.sock into centaurx and set XDG_RUNTIME_DIR=/run/user/<uid>
  • Open questions (remaining)

    • Confirm session model for HTTP (per-user scope vs multi-user sharing).
    • Define master key source and rotation strategy for encrypted SSH keys.