Skip to content

TODO

  • Human-in-the-loop channels - job events outbound (proposed, will_run, failed, waiting_approval) plus inbound actions (approve/reject/run/disable) over configurable connectors (webhook first, then email, then Telegram), so a job can reach an operator who is not on the box
  • Global jobs overview across agents - replio jobs list --root <dir> fleet scan, a GET /jobs + POST /jobs/<name>/approve|reject|run|disable operator API on replio serve, then a web Control UI, so one view shows which agents run next and with which task
  • Edge / offline store-and-forward buffering - offline-capable agents with local buffering for unreliable connectivity (enterprise use case)
  • Immutable agent config - replio serve agents must never be able to change their own configuration, permissions, or tool list (control-plane rule from the use-case reference architecture)
  • Hash-chained / tamper-evident audit log - additive on session logs (enterprise.md recommendation), hash-chained append or WORM storage
  • Single-purpose agent fleet with "one agent per process, scoped to a folder" as the headline pattern. README + docs/fleet.md set the niche
  • Fleet and swarm orchestration as the two layers - fleet: supervisor running many scoped replio serve instances (port allocation, health checks, restart policy, per-agent config generation), swarm: /agent types, auditor agents, generate > check > correct
  • Community presence - decide on Discord/X channels and fill the README community link slots
  • Add multiuser capability or queue for API requests (request queue, per-token rate limits)
  • Add ReadTheDocs documentation
  • Citations / source attribution - return URL + snippet with every answer
  • Bookmarks - /bookmark add/remove/list for session pinning
  • Interactive data analysis - CSV querying, SQL execution, code eval in REPL
  • Notebook mode - persistent editable cells with run outputs
  • Hybrid web + local RAG - vector store (FAISS/Weaviate), embeddings, local document search
  • Command palette / fuzzy search - CTRL-P style history search
  • Topic-aware ranking - classifier for query intent to weight search results
  • Naming / positioning decision - "Replio" collides with commercial SaaS products (replio.chat, repliohq.com, replio.eu), kept for now (PyPI + repo claimed), revisit before any promotion push. Candidate free names: pypelio, replcore, replkit
  • Competitor research - validate USPs against actual peers (OpenClaw, Claude Code, opencode, agentic-infra services) rather than the unrelated SaaS "Replio" products. Comparison notes now live in docs/vs/ and feed the feature backlog (Plan/Build modes, Web Control UI, plugin marketplace, telemetry, binary builds, sharing)
  • Self-update - replio update (Pi pi update --self analogue)
  • Standalone binary build - Pi-style release script producing a single executable (contentious for a zero-dep Python package)
  • Opt-in telemetry contracts - vendor-neutral event schema (OpenCode, Pi @earendil-works/pi-telemetry). Decide whether it fits the no-telemetry stance
  • Conversation sharing - web-shareable session links (OpenCode /share) or published sessions (Pi pi-share-hf), building on the planned Markdown export
  • Plugin registry / marketplace - discoverable plugin sharing (OpenClaw ClawHub analogue). PyPI entry-point source is a prerequisite

Open

  • [ ] Persistent member sessions for recurring teams - job-style warm sessions for recurring teams, one-off runs stay fresh sub_ sessions (sequential run loop + briefs + team memory landed with Engine.run_team)
  • [ ] Externalize bundled providers - move opencode/opencode-go (and the vendor providers) out of the core into bundled plugins, keeping BaseProvider/OpenAICompatibleProvider, the PROVIDERS dict + detect_provider, and the plugin register_providers hook as the core mechanisms. Needs a base_url hostname-hint mechanism so plugin providers auto-detect in /connect
  • [ ] Full file_* namespace extension - if file_glob/file_grep prove better with most models, extend the prefix to list_dir/glob/grep (old names stay aliases)
  • [ ] Tool spec polish - rename grep.glob -> include (alias glob), add examples and prefer-web_fetch guidance to tool descriptions
  • [ ] Team kit plugin (movable, private) - templates, recipes, and generator for ad hoc types/skills/teams, kept out of the core. Bundled during development, moved out to its own per-customer repo once documented (docs/teamkit.md)
  • [ ] Template-based team composition - match type/skill templates from the kit library against the request + project description, generate only the deltas, reuse proven artifacts across projects
  • [ ] Team kit library - tag/store proven teams, types, and skills per stack and customer, importable into new projects without publishing internal know-how
  • [ ] Plugin contribution hooks - register_types / register_teams / register_skills plugin entry hooks + TypeRegistry.reload(), so the kit ships templates without forking the core
  • [ ] Mid-run blocking job approval - an ask tool inside a running job pauses the run in place (per-tool-call waiting_approval), notifies via a connector, and resumes the same session when the operator replies. Needs resumable mid-run state, a wait loop inside the run, and the connectors/transport below (deeper than the shipped per-run --require-approval gate)
  • [ ] Job event hooks - the scheduler emits typed transitions (proposed, approved, will_run, executing, verified, failed, timeout, waiting_approval) to registered services. Channel-agnostic core, first consumers are the connectors and the operator API
  • [ ] Job connectors - bundled replio-core-webhook (stdlib JSON POST, zero deps, works with n8n/IFTTT/any URL) first. External email (SMTP + polling) and Telegram (urllib long-poll) plugins later, all driving the jobs operator API so operators can react in time
  • [ ] Jobs operator API - GET /jobs and POST /jobs/<name>/approve|reject|run|disable on replio serve, so clients (web Control UI, connectors, fleet supervisor) can see and act per agent
  • [ ] Fleet jobs overview - replio jobs list --root <dir> scanning agent worktrees (agent, job, status, next run, task table), then the web Control UI on top
  • [ ] Interactive delegation focus - REPL jumps in/out of the active sub-agent (request or automatic on delegate), arrows switch between concurrent delegate_* session logs rendered from their own saved logs (opencode-style sub-agent views)
  • [ ] Agent type directory scan for export/import - read .replio/types/*.md (front-matter types) to import and export types to Markdown, paralleling the sessions Markdown export/import
  • [ ] Delegation progress in the REPL - live status of which sub-agent is working and its progress mid-run. delegate already surfaces the task and the final result (plus a sub footer via delegate_echo). The next step is a progress channel read out of the sub-engine loop, which the single blocking Engine.chat() does not expose today
  • [ ] Auto team selection - the lead agent picks types from the registry for a task and delegates in sequence (team orchestration as a user-facing pattern, e.g. "compare with competitors" -> Researcher > Writer > Referencer > Editor, landing with the team kit composition flow)
  • [ ] Session log full-restructuring (deferred) - restructure messages from flat role-attribute dicts into a typed parts model, borrowing OpenCode's session file structure (.opencode/sessions/ses_*.json). Deferred: the current flat format already reconstructs every conversation element, so this is architectural polish / ecosystem alignment, not a correctness fix. See the detailed spec below. Do NOT migrate existing .replio/sessions/*.json - they are historical and remain readable as-is
  • Reference - OpenCode stores each turn as {role, messageId, timestamp, parts[]} where parts are typed objects:
    • {"type": "text", "text": ...} - assistant/user content
    • {"type": "thinking", "text": ...} - reasoning as its own part (not an attribute of the message)
    • {"type": "tool", "toolName, toolInput, toolOutput, isError} - tool call and result co-located in one object
    • [step-start] / [step-finish] text parts delimit steps within a turn
    • Top-level: {_id, title, startedAt, updatedAt, compactedAt, parentId, subSessions[], turns[], permissions[], errors[]}
  • Recommended target (role-level parts + co-located tool part):
    • Each message becomes {"id": "msg_<hex>", "role": ..., "timestamp": ..., <role meta>, "parts": [...]}
    • Part types: text, thinking, and tool (co-locating id/tool/input/output/is_error/analysis) so a single assistant message holds thinking + answer + each tool step, dropping the separate tool-role messages
    • _provider_messages() reconstructs the OpenAI payload (assistant.tool_calls + tool-role results) from the parts (engine.py _provider_messages/_clean_messages)
  • Optional, larger alternative - full turn-level parts + [step-start]/[step-finish] markers aggregating the multi-round tool loop into one assistant message per user turn (larger agent-loop change)
  • Touch points: sessions/manager.py (part-building helpers, to_dict/from_dict), engine.py (_agent_loop persistence, _execute_tool_calls, _provider_messages, _clean_messages, compact_session, preview_session, _auto_name_session), sessions/render.py, docs/session.md. Server /sessions + /chat are unaffected (names + TurnResult only)
  • [ ] Thinking visibility - /thinking on + reasoning config documented, per-provider reasoning_content check so reasoning shows in the REPL
  • [ ] /spawn command - launch a scoped replio serve agent from the REPL (home -> project path), supervise (health/list/stop) and delegate to it (docs/fleet.md)
  • [ ] Remote channels - command agents from messaging apps (OpenClaw channels parity):
  • [ ] Channel gateway - one adapter surface over the engine/serve API
  • [ ] Telegram adapter - long-polling bot, send + receive
  • [ ] WhatsApp adapter - business-API HTTP channel
  • [ ] More adapters (Discord, Signal, email)
  • [ ] Remote auth + session scoping + headless deny
  • [ ] Plugin test harness - replio plugins test <name> ships. Bundled plugin suites live next to the plugins (plugins/<name>/tests/, discovered by the core suite). Remaining: external plugins are expected to ship a test suite, and replio plugins test is the runner for them
  • [ ] Session recall - full-text search across past sessions (grep/index over .replio/sessions/) so an agent can answer from its own history
  • [ ] Tool dry-run mode - propose tool args/effects without executing (enterprise tool-gateway requirement)
  • [ ] Context-aware cross-plugin tool router - virtual tool names (open, search, ...) dispatch per-argument to the matching plugin handler via register_handler(name, match=...) (e.g. open https://... > replio-core-web, open ../... > replio-core-fs), with merged schemas and args-aware policy accessors
  • [ ] Swarm orchestration - agent cooperation layer (docs/swarm.md): /agent types, auditor agents, generate > check > correct, and team patterns as sub-tasks below
  • [ ] Grep text index - internal bundled plugin (stdlib) that indexes converted text files for local search, bridging toward the vector store
  • [ ] Agent folder watcher - internal bundled plugin (stdlib threading + pathlib polling) that detects new files in an agent's folder and triggers their processing (e.g. convert new PDFs on arrival), scoped capability, no deps
  • [ ] Minimal web Control UI - stdlib http.server page over the existing replio serve JSON API (OpenClaw Control UI analogue). Richer frameworks stay plugin-first
  • [ ] Externalize the bundled plugins (replio-core-web/fs/exec) into separate versioned repositories - the bundled copies stay the shipped defaults. Global/local plugins of the same name already override them
  • [ ] PyPI plugin source - discover installed plugin packages via importlib.metadata entry points (replio.plugins group)
  • [ ] Shared plugin virtualenv - one venv for all plugin dependencies, injected at import
  • [ ] Per-plugin virtualenv isolation - ~/.config/replio/plugins/<name>/.venv. The loader injects its site-packages at import (strongest dependency separation)
  • [ ] Web scraper plugin - full page scraping beyond fetch_page's text extraction (structured content, links), shipped as an external plugin repository
  • [ ] PDF-to-text converter plugin - extract text from local/remote PDFs, shipped as an external plugin repository
  • [ ] Auditor agents - sub-agents that review/check a produced output (tests, code review, fact-check)
  • [ ] Generate > check > correct orchestration - run a main agent, an auditor, and a fix pass in a loop until passing
  • [ ] Custom system prompts per session
  • [ ] code_debug / compile - pdb/gcc/rustc wrappers (test/lint/format landed as code_test/code_lint/code_format)
  • [ ] docs_search - local grep + DuckDuckGo for documentation lookups
  • [ ] Workspace sessions - tools write into a scoped --workspace dir, optional --git sync
  • [ ] Sandboxed exec - namespace/container isolation for run_command (documented, planned for a later version)
  • [ ] /agent types - interactive type selection/run UX (type registry, sub-engine, and delegate landed. The /agent command itself remains)
  • [ ] PM/dev/tester team orchestration as a user-facing pattern (the agent types + delegate primitives landed, and it needs the jobs/team-config layer to be a pattern)
  • [ ] Headless web API plugin-first - stdlib http.server fallback, richer framework (FastAPI) via the dependency plugin
  • [ ] Enterprise plugins (stdlib-first, third-party deps optional):
  • [ ] Data ingestion - read_stream / write_stream (MQTT, OPC-UA, Modbus)
  • [ ] Time-series - anomaly_detect (z-score), forecast
  • [ ] Model inference - model_infer / predict_failure (ONNX)
  • [ ] Optimization - optim_schedule (scheduling / linear programming)
  • [ ] SCADA control - scada_command (OPC-UA registers)
  • [ ] Reporting - report_gen (Markdown/PDF, email/BI push)
  • [ ] Audit logging + metrics (/metrics) for enterprise deployments
  • [ ] Onboarding wizard (replio wizard) for data-source / MES interface setup
  • [ ] RBAC - role-based access control for enterprise deployments
  • [ ] Queue-based scaling - many concurrent sensor/chat feeds without blocking the loop
  • [ ] Session import from Markdown/JSON

Done

  • [x] ask tool - core: human or lead mid-run questions, sub-agent routing
  • [x] Connect any OpenAI-compatible endpoint by URL - named custom provider entries
  • [x] /connect provider rework - name/URL connect, preset defaults, re-enter key
  • [x] Model refs unfold - provider/model refs resolve, gated on approved models
  • [x] models.json - approved-model history (provider, model, timestamps), no keys
  • [x] Provider registry - providers.json, one API key per provider, engine resolves from it
  • [x] Sequential team runs - run_team stage loop, per-run briefs, team memory, /team run
  • [x] persona renamed to agent type - types.py/TypeRegistry, /type, --type, no aliases
  • [x] Bundled web plugin renamed - replio-core-websearch -> replio-core-web
  • [x] GitHub Pages website - mkdocs site + Actions workflow, docs stay in main
  • [x] OpenCode Zen + Go providers - opencode.ai endpoints, model-ref strip, URL detection
  • [x] Tool-use evaluation harness - replio eval + fixture plugin, metrics
  • [x] Project instructions file - per-worktree AGENTS.md in system prompt, capped
  • [x] run_command allowlist - tool_permission.bash_allow, heredocs/multi-line rejected
  • [x] code_test/code_lint/code_format wrappers - dev.*_cmd, bundled replio-core-dev plugin
  • [x] git tool - read-only git + gated git_commit, bundled replio-core-git plugin
  • [x] file_edit tool - search-and-replace with diff preview, bundled replio-core-edit plugin
  • [x] Default tool-result cap - tool_max_result_chars default 100k, list_dir entry cap
  • [x] Default tool names namespaced - web_fetch merges open+fetch_page, old names as aliases
  • [x] Tool schema advertises canonical names only - aliases resolve at call time (20 -> 13 defs)
  • [x] Agent-loop cancellation + tool-dialect hardening - Ctrl-C cancels the turn, unknown-tool hints
  • [x] Skills registry - SkillRegistry, local/global dirs + plugins, type skills in prompts
  • [x] Teams registry - Team/TeamRegistry, 4-layer teams.json merge, /team read/edit
  • [x] Plugin contribution hooks - register_types/teams/skills hooks, TypeRegistry.reload()
  • [x] Fleet orchestration - replio fleet supervisor CLI: ports, health, restart, config gen
  • [x] Per-run job sessions - job_<ts>_<name> files, unified ses_/sub_/job_ naming
  • [x] Job run memory - rolling .memory.md summary injected into each run, seeded
  • [x] Job task definition as linked Markdown - --file templated task files, replio jobs edit
  • [x] Job context management - per-run job_* files, ses_/sub_ naming, 100-run cap
  • [x] Job per-run approval - --require-approval parks a run in waiting_approval
  • [x] Jobs diagnostics - replio jobs status (fired count, last error, uptime)
  • [x] Watchable job runs - replio jobs run --verbose streams the live turn
  • [x] Richer job runs - --type/--system-prompt, recurring-job prompt, tool carve
  • [x] Scheduled / durable jobs - replio jobs: registry, daemon, cron, retries, approval gate
  • [x] Per-agent permission profiles - type tool_permission drives sub-agent policy
  • [x] In-process sub-engine - Engine.run_subagent: type overrides, NullUI, sub_ session
  • [x] delegate tool - core, per-type permission resolver, delegate_echo result display
  • [x] Agent types registry - global+local types.json merge, /type command, docs/types.md
  • [x] Soft tool results surfaced as dimmed info lines - (empty file), (no matches) etc
  • [x] Session audit trail - permission decisions (allow/ask/deny -> granted/declined/denied)
  • [x] Stable message ids - msg_<hex> auto-assigned to every session message
  • [x] Global model registry - /connect appends models + keys, /model list/--online, picker reuse
  • [x] REPL /config --global/--local scope flags + apply() in-memory overrides
  • [x] Scoped config writes - local saves overrides only, replio config CLI
  • [x] Turn recovery - auto-continue on truncation, reasoning-only not flagged empty
  • [x] Thinking captured from reasoning deltas (ollama.com), documented
  • [x] Confirm prompt ? glyph starts at the beginning of the line, aligned with activity glyphs
  • [x] Word-level streaming buffering - buffer REPL output to word boundaries, word_streaming config
  • [x] Multi-line input - detect """/''' blocks, one composed message, framing stripped
  • [x] Config validation (test connection on change) - /connect probe, /provider warn
  • [x] Session export to Markdown - /session export and replio export CLI render logs to Markdown
  • [x] Plan/Build modes - plan (edit+bash denied) vs build, /mode cmd + --mode flag, per-message mode
  • [x] Thinking/reasoning toggle - show_thinking (display) + reasoning (request), /thinking cmd
  • [x] Thinking spinner - animated spinner while thinking when show_thinking false, cleared \r\033[K
  • [x] Activity lines + tool status ephemeral - never persisted to session files
  • [x] MCP via bundled replio-core-mcp plugin - import/expose tools over MCP, dual-era
  • [x] Alias layer - tool/param aliases (read/view, ls, bash/exec, cursor>offset) + open tool
  • [x] Glyph activity lines - dimmed status, glyph_lines config
  • [x] write_file reports resolved abs path (Created|Overwritten|Appended)
  • [x] Tab completion restored (libedit binding) + extended to paths, tool names, and subcommands
  • [x] README terminal screenshot as SVG
  • [x] deploy/ fleet templates - Dockerfile, compose, systemd + launchd units
  • [x] docs/fleet.md - single-purpose scoped-agent fleet pattern
  • [x] README fleet positioning - tagline, Features, fleet section, roadmap
  • [x] Per-turn stats on own line - footer newline when output lacked one
  • [x] One-shot retry for empty/truncated streams before surfacing error
  • [x] write_file status preview ends with dimmed summary (path, lines, chars, action)
  • [x] Thinking announce - + Thinking (or + Thought 12.3s hidden). Headless mirrors
  • [x] Human-readable tool status - [tool: arg] oneliner + dimmed detail lines
  • [x] Built-in web + machine features moved to bundled plugins
  • [x] Discovery precedence bundled < global < local, bundled can't update/uninstall
  • [x] register_services entry hook - powers the web_search: true search-then-answer mode
  • [x] plugins config list replaces plugins.enabled/deny, empty = all
  • [x] tests/test_bundled_plugins.py (10 tests)
  • [x] Plugin system - directory-based external plugins for tools, providers, and commands
  • [x] PluginManager - discovery, manifest compat ranges, single entry import
  • [x] register_tools hook - tools inherit policy, /tool, /help, logging
  • [x] register_providers hook merged into provider registry
  • [x] register_commands(commands) hook, registered after builtins at engine init
  • [x] Plugin manifest + docs - docs/plugins.md (schema, compatibility contract, security)
  • [x] Optional per-plugin deps - requires, lazy import, --deps pip-installs
  • [x] Activation via config - plugins list, enable/disable/install/uninstall maintain it
  • [x] /plugins - list/detail/enable/disable/install/update/uninstall
  • [x] replio plugins CLI - headless list/install/update/uninstall
  • [x] tests/test_plugins.py (30 tests)
  • [x] PyPI proper configuration and documentation
  • [x] Clear screen on REPL start (clear_screen config, default true)
  • [x] /config structured values - JSON parse, -a/-r, reload
  • [x] /compact summarization - append-only, compact_from boundary
  • [x] /session load compaction offer prints the summary, load records a command message
  • [x] /session preview <name> - read-only structural preview without switching sessions
  • [x] Session-name tab completion for /session load/delete
  • [x] Context-size display - dimmed (Ns, N tokens) after each response
  • [x] noise_tools config - noise results replaced by marker in sessions
  • [x] max_tokens optional (0=unset), hitting cap warns + logs error
  • [x] Provider payload from log - command filtered, dangling tool msgs skipped
  • [x] replio run - one-shot CLI (JSON/text) reusing loop + sessions
  • [x] Flags: --prompt, --provider, --model, --output=json, --verbose
  • [x] --session-id - address persistent sessions from headless mode
  • [x] Headless logging (--verbose) instead of visual activity lines
  • [x] replio serve - stdlib http.server HTTP JSON API (POST /chat) over the same agent loop
  • [x] Tests for headless entry points (mock provider, no network)
  • [x] Hardening: agent-loop turn failures always visible in the session log
  • [x] Persist streamed content when the SSE stream ends without a done event
  • [x] Record errors entry for silent failures (EOF, empty/thinking-only done)
  • [x] Non-normal finish_reason (length) logs an errors entry + prints a warning
  • [x] Catch unexpected exceptions escaping the agent loop, log them, keep the REPL alive
  • [x] Tests: token-stream-then-EOF, empty done, streamed exception
  • [x] Sessions are complete logs - every message, tool call + result, reasoning, error persisted
  • [x] Append-only - compaction and load never remove or rewrite entries
  • [x] Session.to_dict() keeps role: tool (full results, noise_tools replaced by a marker)
  • [x] Per-round thinking metadata on assistant messages, excluded from content
  • [x] Session-level errors array
  • [x] created_at / updated_at metadata (bumped on every message)
  • [x] tool_analysis (default false) - model-generated one-line analysis on each tool message
  • [x] session_tool_max_chars (default 0 = unlimited) - caps persisted tool-result content
  • [x] No index.json - session names carry timestamp + first-message slug
  • [x] Flat message list retained (maps 1:1 to provider context)
  • [x] Unified streaming agent loop
  • [x] Single SSE stream, detect tool_calls vs content from the first delta
  • [x] Eliminates double-call cost when no tools are used
  • [x] Unified dispatch
  • [x] Slash commands call the same ToolRegistry as the model
  • [x] Generic query refinement via tool metadata and collapsed _handle_message branches
  • [x] Machine tools (tools/machine.py) - read_file, list_dir, write_file, run_command
  • [x] read_file - numbered lines, offset/limit, truncation, binary/permission errors
  • [x] list_dir - sorted entries, trailing / for subdirs, file sizes
  • [x] write_file - parent-dir creation, w/a modes
  • [x] run_command - subprocess exec with timeout, stdout/stderr capture, exit code, 8k cap
  • [x] category/permission/path_arg/key_arg registration metadata
  • [x] Discovery tools - glob (recursive, noise-dir skip) + grep (regex, file:line)
  • [x] read_file always reports total line count in its header
  • [x] Tool permission model (tools/policy.py + config)
  • [x] tools.allow / tools.deny name-level policies (deny + allow-whitelist take precedence)
  • [x] tool_permission category actions - allow/ask/deny per category
  • [x] Path-scoped confirm - outside-worktree read/write/list escalate to ask
  • [x] bash: ask default - every run_command prompts y/N
  • [x] Confirm prompts - denied tools filtered, cancelled calls feed [cancelled]
  • [x] /tool command routes through the same policy
  • [x] OpenAI / Groq / Anthropic providers
  • [x] Provider auto-detection from base_url
  • [x] Base provider (OpenAI-compatible interface)
  • [x] Ollama cloud provider
  • [x] Session manager (JSON CRUD)
  • [x] /session new and /session load actually switch the active session
  • [x] Session save after file rename - JSON name field matches filename
  • [x] Auto-session naming with first user message as context hint
  • [x] Tool results and assistant tool_calls persisted in session files
  • [x] DuckDuckGo Lite search via html.parser
  • [x] Terminal + AI context formatting
  • [x] /search <query> and /web <query> commands
  • [x] Auto-search mode (web_search: true config)
  • [x] fetch_page - _TextExtractor (HTMLParser) for clean text extraction
  • [x] Search term extraction - query_refine config auto-refines short queries
  • [x] tools/registry.py - decorator-based tool registration
  • [x] tools/builtins.py - web_search and fetch_page tools
  • [x] BaseProvider.chat_nonstreaming() - non-streaming tool decision round
  • [x] Two-phase chat: non-streaming tool decision > stream final content
  • [x] _show_tool_status() - dimmed status during tool execution
  • [x] /search command integration with tool calling
  • [x] Config default: tool_calling: true
  • [x] tool_status_visible config flag (default true)
  • [x] Tool calling integration verified end-to-end
  • [x] Thinking/reasoning token detection and dimmed display
  • [x] SSE streaming survives multi-byte UTF-8 split across read chunks (byte-buffered line decoding)
  • [x] Markdown-aware streaming (disabled by default via markdown_streaming)
  • [x] Error handling improvements (network timeout, auth errors)
  • [x] Edge cases: streaming when tool_calling=true but no tools used
  • [x] Tool-call messages lost on exception - try/finally persists session
  • [x] Final assistant response missing when streaming returns empty - non-streaming fallback
  • [x] Project scaffolding (pyproject.toml, venv, dir structure)
  • [x] Config module (global + local JSON merge)
  • [x] HTTP SSE streaming utility (urllib)
  • [x] REPL loop with readline history + tab completion
  • [x] Command registry + built-in slash commands
  • [x] Streaming token display
  • [x] Documentation (README, AGENTS.md, TODO.md, CHANGELOG.md)