Skip to content

Add core TeleCoder implementation: CLI, session engine, and web UI#7

Open
jxucoder wants to merge 7 commits intomainfrom
claude/create-execute-sprints-2jOnA
Open

Add core TeleCoder implementation: CLI, session engine, and web UI#7
jxucoder wants to merge 7 commits intomainfrom
claude/create-execute-sprints-2jOnA

Conversation

@jxucoder
Copy link
Copy Markdown
Owner

@jxucoder jxucoder commented Mar 7, 2026

Summary

This PR implements the complete v1 foundation of TeleCoder, a system for running Claude Code as a remote coding agent on a VPS. It includes the CLI interface, session management engine, git workspace handling, runtime adapter, and a basic web UI.

Key Changes

Core Infrastructure

  • Added config.py: TOML-based configuration system with sensible defaults for service, runtime, storage, git, and verification settings
  • Added db.py: SQLite schema and initialization for session metadata and run history
  • Added __init__.py: Package metadata with version tracking

Session Management

  • Added session.py: SessionEngine class for creating, listing, running, stopping, and resuming sessions with full state persistence
  • Sessions track repo URLs/paths, workspace directories, git branches, test/lint commands, and execution results
  • Support for multiple runs per session with prompt history

Runtime & Process Management

  • Added runtime.py: Adapter for launching Claude Code CLI as subprocess, capturing stdout/stderr to log files, and managing process lifecycle
  • Handles process detection, graceful shutdown, and environment variable injection
  • Supports configurable binary paths and runtime types

Git Integration

  • Added git_workspace.py: Workspace setup from remote repos or local paths, branch creation/switching, and diff/status inspection
  • Preserves workspaces between runs for incremental work
  • Provides changed file listing and diff summaries for inspection

Verification Layer

  • Added verify.py: Test and lint command execution with timeout handling and result capture
  • Formats pass/fail summaries for display and storage

CLI Interface

  • Added cli.py: Complete Click-based CLI with commands for:
    • init: First-time setup with directory and config creation
    • session create/list/inspect/run/stop/resume/logs: Full session lifecycle management
    • config view/set: Credential and setting management
    • service start/stop: Service control
  • Includes help text, status badges, and formatted output tables

Web UI

  • Added web/app.py: FastAPI application serving session list and detail pages
  • Added templates (base.html, index.html, session.html): GitHub-dark-themed responsive UI for viewing sessions, logs, and git changes
  • Real-time status refresh and log streaming support

Installation & Deployment

  • Added install.sh: Automated setup script that creates telecoder user, directories, installs package, and registers systemd service
  • Added telecoder.service: Systemd unit file for service management
  • Added config.example.toml: Example configuration with all available options

Documentation

  • Added docs/quickstart.md: 5-minute getting started guide
  • Added docs/vps-setup.md: VPS provisioning and dependency installation
  • Added docs/runtime-setup.md: Claude Code CLI setup and verification
  • Added docs/git-credentials.md: SSH key and token configuration for git access
  • Added docs/troubleshooting.md: Common issues and debugging steps
  • Added sprints.md: Development roadmap and tech stack documentation

Project Configuration

  • Added pyproject.toml: Package metadata, dependencies (click, fastapi, uvicorn, jinja2), and CLI entrypoint
  • Updated .gitignore: Added Python artifacts, venv, and database files

Implementation Details

  • Database: SQLite with WAL mode and foreign key constraints for reliability
  • Process Management: Processes launched in new session groups to survive terminal disconnects
  • Configuration: Hierarchical loading from /etc/telecoder/config.toml, ~/.config/telecoder/config.toml, or local config.toml
  • Logging: Per-session stdout/stderr capture to separate log files in logs/ directory
  • State Persistence: All session state stored in SQLite; workspaces preserved on disk for incremental work
  • Error Handling: Graceful degradation with informative error messages and troubleshooting guides

This implementation provides a complete, production-ready foundation for running Claude Code as a remote agent with full CLI and web interfaces.

https://claude.ai/code/session_01HWLSjJJU2C1Q2GbDtb4wbW

Build the complete v1 of TeleCoder across 6 sprints:

Sprint 1 - Bootstrap: project structure, pyproject.toml, config (TOML),
SQLite schema, systemd unit template

Sprint 2 - Runtime & Sessions: Claude Code runtime adapter with
process management, session engine with create/run/stop/resume/list,
SQLite persistence, log capture

Sprint 3 - Git & Verification: git workspace handling (clone, branch,
diff), verification layer for test/lint commands with result capture

Sprint 4 - CLI: full Click-based CLI covering init, session create/
list/inspect/run/stop/resume/logs/verify/delete, service start

Sprint 5 - Web UI & Install: FastAPI web viewer with session list and
detail pages, dark theme, API endpoints, install.sh script

Sprint 6 - Documentation: quickstart, VPS setup, runtime setup,
git credentials, and troubleshooting guides

https://claude.ai/code/session_01HWLSjJJU2C1Q2GbDtb4wbW
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 23d177cff0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/telecoder/runtime.py Outdated
Comment on lines +89 to +90
os.kill(pid, 0)
return True
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Treat zombie child processes as not running

is_running uses os.kill(pid, 0), which returns success even when the runtime process has exited but remains as a zombie under the long-lived web service parent; in that state SessionEngine.refresh_status will never transition the session from running to completed, so finished runs can appear permanently active until the service restarts.

Useful? React with 👍 / 👎.

Comment thread src/telecoder/web/app.py Outdated
body = await request.json()
prompt = body.get("prompt", "")
if not prompt:
return {"error": "prompt is required"}, 400
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Return an actual 400 response for missing prompt

The Flask-style tuple ({"error": ...}, 400) is not how FastAPI sets status codes, so this branch can return a 200 response with a serialized tuple-like payload instead of an HTTP 400; clients calling /api/session/{session_id}/run may treat invalid requests as successful.

Useful? React with 👍 / 👎.

Comment thread install.sh Outdated
Comment on lines +21 to +23
if ! command -v python3 &>/dev/null; then
echo "Python 3 not found. Installing..."
apt-get update -qq && apt-get install -y -qq python3 python3-pip python3-venv git
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Install pip3 even when Python is already present

The installer only runs apt-get install ... python3-pip when python3 is missing, but many base images have Python without pip3; in that case the later pip3 install step fails and aborts installation, so the dependency check should validate pip3 separately.

Useful? React with 👍 / 👎.

claude added 6 commits March 7, 2026 21:01
Remove the entire Python package (src/, pyproject.toml, FastAPI web UI,
systemd service) and replace with a thin bash CLI that composes existing
CLI tools directly:

- bin/telecoder: main CLI dispatcher with all commands
- lib/db.sh: sqlite3 CLI wrappers for session state
- lib/session.sh: session management via tmux + sqlite3
- lib/verify.sh: test/lint runner

Sessions run in tmux — close your terminal, they keep going.
State lives in sqlite3. The agent is claude CLI, called directly.
No Python, no pip, no virtualenv. Just bash, git, tmux, sqlite3.

Updated install.sh, config format (shell-sourceable), and all docs
to match the new approach.

https://claude.ai/code/session_01HWLSjJJU2C1Q2GbDtb4wbW
Write prompt to a file and read it back at runtime instead of
interpolating into shell strings. Use a generated runner script per
session so tmux never sees the raw prompt text. Use parameterized
sqlite3 queries for inserts/updates containing user input.

"don't forget to fix the tests" now works.

https://claude.ai/code/session_01HWLSjJJU2C1Q2GbDtb4wbW
No intent parsing or command mapping. Your Telegram message goes
straight to Claude Code as the prompt. The AI decides what to do.

- bot/main.py: Telegram polling bot with /new, /status, /logs, /stop
- bot/telecoder.py: thin wrapper that shells out to telecoder CLI
- Auto-creates a session if none exists
- Optional user allowlist via TELECODER_TG_ALLOWED_USERS

https://claude.ai/code/session_01HWLSjJJU2C1Q2GbDtb4wbW
Sprints are the new atomic unit of work. You prompt, it runs.
No intermediate planning, no confirmation, no approval gate.
The AI gets maximum freedom: goal → execute → verify → done.

- Add sprints table to DB schema
- Add lib/sprint.sh with create, status, list functions
- Add CLI commands: sprint, sprint-status, sprint-list
- Update Telegram bot: plain messages become sprints
- Auto-verify on completion when test/lint commands configured
- Auto-push when TELECODER_AUTO_PUSH=true

https://claude.ai/code/session_01HWLSjJJU2C1Q2GbDtb4wbW
Claude Code already handles the complexity. The session is the
unit of work. Adding a sprint layer on top was unnecessary
indirection. You prompt, it runs. That's what sessions already do.

https://claude.ai/code/session_01HWLSjJJU2C1Q2GbDtb4wbW
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants