Skip to content

unbug/tday

Repository files navigation

Tday — All-in-One Harness Agent Terminal

One terminal for every coding-agent harness — Claude Code, Codex, Copilot CLI, OpenCode, Pi, and more. Browser-style tabs, unified provider config, auto-detected local inference, long-term memory, cross-agent token analytics, and cross-platform Computer Use (macOS · Windows · Linux).

latest

Tday Demo Video on X

Tday Screenshot 1 Tday Screenshot 2

Tday Screenshot 3 Tday Screenshot 4

Tday Screenshot 5 Tday Screenshot 6


Installation

Download the latest release for your platform from Releases:

Platform Artifact
macOS (arm64 + x64) .dmg
Windows x64 .exe (NSIS installer) or .zip
Linux x64 .AppImage or .tar.gz

macOS — "unverified developer" warning

The distributed build is not code-signed with an Apple Developer certificate. macOS will block the app on first launch. To bypass:

xattr -rd com.apple.quarantine /Applications/Tday.app

Or: right-click the .appOpen → click Open in the dialog.

Or:

Image

Windows — "Windows protected your PC" warning

The build is not code-signed with a Microsoft Authenticode certificate. Windows SmartScreen may show a warning. To bypass:

  1. Click More info in the SmartScreen dialog.
  2. Click Run anyway.

Prerequisites: Tday requires Node.js (LTS, >=20) to install and run AI coding agents. Download it from nodejs.org. After installation, make sure npm is on your PATH by running npm --version in a new terminal — if it works, Tday will also find it.

PATH setup: If you installed agents via npm install -g <package>, their .cmd wrapper scripts live in %APPDATA%\npm. The Tday installer does not modify your system PATH — the app detects this directory automatically at startup. If Tday can't find an agent, run:

npm install -g <agent-package>

then restart Tday.

Linux — AppImage

Make the downloaded .AppImage executable and run it:

chmod +x Tday-*.AppImage
./Tday-*.AppImage

Computer Use on Linux requires xdotool, wmctrl, scrot, and tesseract-ocr:

sudo apt install xdotool wmctrl scrot tesseract-ocr

1. Vision

Today, every coding-agent harness ships with its own CLI, its own provider config, its own memory format, and its own token accounting. Power users juggle Claude Code in one tab, Codex in another, Copilot CLI in a third, OpenCode in a fourth — each a separate terminal, each re-keyed, each forgetful.

Tday is the missing meta-layer:

  • Open agents in tabs the way you open URLs in a browser. Cmd+T for a new agent, drag-to-reorder, persistent sessions.
  • One provider config (DeepSeek, OpenRouter, Anthropic, OpenAI, …) injected into whichever agent you launch.
  • Auto-discover local inference servers (Ollama, LM Studio, llama.cpp, vLLM) on your LAN/loopback and surface them as first-class providers.
  • Unified long-term memory shared across agents (with per-agent scoping when you want it).
  • Cross-agent token analytics — finally know what each harness actually costs.
  • Buttery UX with border-beam accents, native PTY performance, and a Rust core for the hot paths.

2. Key Features

# Feature Description
1 Computer Use (macOS · Windows · Linux) Give any agent hands on your desktop — no vision model required. Uses native Accessibility APIs to read and control any app directly, without screenshots. One-click enable for Claude Code, Codex, Gemini, OpenCode, and Pi. Agents can click UI elements, type, scroll, open apps, control Chrome via CDP, and fall back to OCR when needed. Built-in Computer Operator CoWorker + one-click permission setup. Runs natively on macOS (arm64 + x64), Windows x64, and Linux x64.
2 Multi-tab workspace Open any agent in browser-style tabs, drag to reorder, multi-row wrap, per-tab working directory with cwd commit and last-cwd persistence.
3 10 AI agent adapters Pi, Claude Code, Codex CLI, GitHub Copilot CLI, OpenCode, Gemini CLI, Qwen-Code, Crush, Hermes, DeepSeekTUI — each with auto-detect, one-click install, and per-agent accent color.
4 CoWorker system Reusable role personas injected as system prompts — selected per tab from the CwdBar. 35 built-in presets across 7 categories sourced from CoWorkers.md, or your own custom/online CoWorkers. Community contributions welcome.
5 Cron job scheduler Schedule automated agent tasks with Interval / At Time / Custom cron modes. Human-readable preview, enable/disable, clone, delete, and a live dashboard with next-run countdown and last-status.
6 28-provider settings panel CRUD UI for DeepSeek, OpenAI, Anthropic, Gemini, xAI, Groq, Mistral, Ollama, LM Studio, OpenRouter, and 18 more — supports both OpenAI-compatible and Anthropic-compatible base URLs.
7 Per-agent provider & model binding Each agent tab runs on a different provider and model. Model flags are projected to CLI arguments at spawn time. Shared-config "all agents one provider" toggle also available.
8 Local inference auto-discovery TCP + HTTP fingerprint scan for Ollama, LM Studio, vLLM, llama.cpp, SGLang, LocalAI, Jan. Discovered models appear as chips in the provider UI. Manual base-URL probe available.
9 Cross-agent usage analytics Complete token and cost tracking for every agent and every session. Daily bar chart, by-model and by-agent breakdown tables, 30+ model pricing — all stored locally in SQLite.
10 Unified agent history Every session across all agents is automatically indexed. Browse, search, and restore any past conversation — including working directory and session ID — with one click.
11 Agent-native session resume Claude Code (--resume), Codex (resume <id>), OpenCode (--session), DeepSeekTUI (resume <id>) — session IDs are captured automatically and offered on tab restore.
12 Reliable prompt delivery Task prompts reach the agent at spawn time even when the screen is locked: CLI arg for Codex / Claude Code / Gemini / Qwen-Code / DeepSeekTUI; bracketed-paste PTY write for Pi / Copilot / Crush / Hermes.
13 DeepSeek Anthropic gateway proxy In-process HTTP server translating OpenAI Responses API → Anthropic Messages API: streaming, extended thinking, tool use, multi-turn — no harness patching required.
14 Keep Awake One-click toggle to block system sleep during long agent jobs, without affecting screen dimming.
15 In-app update checker Green dot badge and download link when a new version is available — checked 10 s after launch then every 30 min.
16 Cross-platform macOS (arm64 + x64), Windows, Linux. PATH augmentation for nvm-windows, Volta, fnm. Correct PTY dimensions on all platforms.

3. Architecture

flowchart TB
    subgraph Presentation["🖥  Presentation Layer · React · Vite · TypeScript"]
        direction LR
        TM["Tab Manager\nbrowser-style tabs"]
        TV["Terminal View\nxterm.js + WebGL"]
        UI["Agent Picker · Settings\nUsage Dashboard · Cron"]
        KIT["Tailwind · shadcn/ui\nborder-beam"]
    end

    subgraph Application["⚡  Application Layer · Electron Main · Node.js"]
        direction LR
        SS["Session Service\nnode-pty · one PTY / tab"]
        AA["Agent Adapters\n10 harnesses"]
        PS["Provider Service\nenv-var injection · 28 providers"]
        IB["IPC Bridge\ntyped contextBridge channels"]
        GW["Gateway\nOpenAI Responses API → Anthropic"]
    end

    subgraph Infrastructure["🦀  Infrastructure Layer · Rust"]
        direction LR
        subgraph CORE["tday-core · static binary · JSON-RPC / stdio"]
            direction TB
            SC["Inference Scanner\nOllama · LM Studio · vLLM · llama.cpp · SGLang"]
            TC["Token Counter · Memory Store\ntiktoken-rs · SQLite + sqlite-vec"]
            UL["Usage Logger · Config & Secrets\nper-agent / per-provider · OS keychain"]
        end
        subgraph NC["tday-nativecore · MCP server · Streamable HTTP"]
            direction TB
            AX["AX Tree · OCR · Mouse · Keyboard · Screenshot\nmacOS (Vision) · Windows (WinRT) · Linux (Tesseract)"]
            CDP["CDP · Android ADB · Launcher · System\nprobe_app · cdp_click · adb_tap · execute_command · clipboard"]
        end
    end

    Presentation <-->|"IPC · contextBridge"| Application
    Application -->|"JSON-RPC / stdio"| CORE
    Application -->|"Streamable HTTP / MCP"| NC
Loading

Why this split

Concern Where Why
Window, tabs, UI Electron + React Mature, fast iteration, rich ecosystem.
PTY spawning Electron main (node-pty) Battle-tested, full TTY semantics, integrates cleanly with xterm.js.
Detection / tokenization / memory Rust (tday-core) CPU-bound, must not block UI. Static binary, easy to ship & cross-compile.
Computer Use tools (AX, OCR, mouse, CDP) Rust (tday-nativecore) macOS: Accessibility + Vision + CGEvent. Windows: UIA + SendInput + GDI + WinRT OCR. Linux: X11/XTest + XRandR + scrot + Tesseract. Zero overhead on the Node event loop.
Provider secrets OS keychain via Rust Avoid plaintext in app data; cross-platform.

Gateway — OpenAI Responses API → Anthropic proxy

Some harnesses (e.g. Codex) only speak the OpenAI Responses API. Tday ships a lightweight in-process HTTP gateway that transparently translates those calls to the Anthropic Messages API, enabling DeepSeek and any other Anthropic-compatible provider to be used with every harness without patching the harness.

Harness (Codex)              Main Process
       │  POST /v1/responses      │
       │ ─────────────────────▶  │
       │                   bridge/input   (OpenAI Responses → Anthropic Messages)
       │                   bridge/tools   (tool / tool-choice conversion)
       │                   deepseek/      (thinking-block encode/decode, V4 mutations)
       │                   anthropic/     (HTTP POST + SSE stream from provider)
       │                   bridge/stream  (Anthropic SSE → OpenAI SSE events)
       │  SSE stream              │
       │ ◀─────────────────────  │

Module map (apps/desktop/src/main/gateway/):

Module Responsibility
adapter.ts Express server, request dispatch, error handling
types.ts Shared gateway interfaces (Request, Response, …)
anthropic/types.ts Anthropic Messages API type definitions
anthropic/client.ts HTTP client, SSE tokeniser
openai/types.ts OpenAI Responses API type definitions
bridge/input.ts Convert OpenAI input items → Anthropic messages array
bridge/tools.ts Convert OpenAI tools → Anthropic ATool[], apply DeepSeek mutations
bridge/response.ts Convert Anthropic non-streaming response → OpenAI output
bridge/stream.ts Convert Anthropic SSE events → OpenAI Responses API SSE
deepseek/thinking.ts Encode / decode extended thinking blocks (prefix-based)
deepseek/state.ts Per-session LRU cache for (thinking, signature) pairs

Every harness is a thin adapter:

interface AgentAdapter {
  id: string;                          // "pi" | "claude-code" | "codex" | "opencode"
  displayName: string;
  detect(): Promise<DetectResult>;     // is the binary on PATH? version?
  buildLaunch(ctx: LaunchContext): {   // how to start it in a PTY
    cmd: string;
    args: string[];
    env: Record<string, string>;       // provider keys, base URLs, etc.
    cwd: string;
  };
  parseUsage?(stream: string): UsageDelta | null; // optional: scrape token usage
}

Tab = Session

A Tab owns one Session = one PTY process bound to one agent adapter, one provider profile, and one working directory. Tabs persist across app restarts (process state does not; transcript does).


4. Long-term Roadmap

Version Theme Highlights
v0.1.0 Walk — Pi end-to-end Single-tab MVP. Spawn the pi agent in a PTY tab. Static provider config from a JSON file. Border-beam shell.
v0.2.0 Multi-agent, multi-tab Adapters for Claude Code, Codex, Copilot CLI, OpenCode. Tab manager (open/close/reorder/duplicate). Per-tab cwd picker.
v0.3.0 Providers UI + Gateway Settings panel for 28+ cloud/local providers. DeepSeek Anthropic gateway proxy (OpenAI Responses API → Anthropic). Per-agent model override.
v0.3.x Multi-agent UI overhaul + Tab History 9 agent adapters (Crush, Hermes, Qwen-Code added). Per-agent accent colors. Logo dropdown (History, Keep Awake, Usage, Settings). Closed-tab history with one-click restore. Agent-native session resume (claude-code --resume, codex resume, opencode --session). Conversation history replayed on restore. Windows PATH augmentation (nvm-windows, volta, fnm).
v0.4.x Local-inference + UX Polish Local service discovery (Ollama, LM Studio, vLLM, llama.cpp, SGLang). Usage analytics dashboard (SQLite store, 30+ model pricing, summary cards, daily chart, by-model/agent tables). Settings redesign: History tab, resizable dialog, lazy-mount. Tab title smart clip + hover tooltip, last-active restore on restart. In-app update checker with green-dot badge. claude-code width + double-SIGWINCH fix. Windows menu fix. Electron drag-region fix.
v0.5.x Cron & Automation Settings → Cron tab: job list with enable/clone/delete, ScheduleWidget (Interval / At time / Custom cron with datetime picker), human-readable schedule preview. Cron scheduler in main process (node-cron, persistent JSON store, per-job stats). initialPrompt delivered reliably at spawn time: CLI positional arg for codex / claude-code / opencode / gemini / qwen-code; bracketed-paste PTY write (XTerm ESC[200~) for pi / copilot / hermes / crush — works even when screen is locked. OpenCode run subcommand fix. Job dashboard with next-run countdown, run count, last-status.
v0.6.0 Token usage analytics Dashboard UI: summary cards, daily bar chart, by-model and by-agent breakdown (SQLite store, 30+ model pricing).
v0.6.x CoWorker system Settings → CoWorkers tab: create/edit/delete role personas injected as system prompts. Three source types: built-in (builtin:* from AGENT.md), online (online:* URL-cached from GitHub), custom (inline text / local file / URL). Three curated presets (Karpathy Code Guidelines, Devin-style Planner, Earnings Call Analyst). CoWorker dropdown in CwdBar — select per tab, prompt injected immediately into the running PTY. CoWorker binding in Cron jobs. Settings dialog tabs now top-tab style; backdrop no-drag fix so tabs are always clickable even when TabBar wraps to multiple rows.
v0.7.x CoWorker Registry + Data Freshness CoWorker registry expanded to 35 built-in presets across 7 categories (Mental Models, Startup & Business, Coding & Engineering, Writing & Content, Research & Analysis, Security & Privacy, Productivity). GitHub ★ stars on cards and detail view (24 h TTL cache). Unique ID derivation per entry (deriveRegistrySlug). Online refresh button with spinner + error state. App-level state lifting: agents / coworkers / providers owned by App root, passed as props to Settings — eliminates IPC stutter on every Settings open. requestIdleCallback background refresh after Settings closes (5 s timeout fallback). New-tab provider submenu now includes all preset models alongside discovered & user-added models.
v0.8.x Computer Use Settings → Computer Use tab: one-click enable per agent. tday-nativecore Rust binary injected as MCP server (stdio). 20+ tools: AX tree (take_ax_snapshot, ax_click, ax_set_value, ax_perform_action), OCR (find_text with multi-display CGDirectDisplayID, ocr_screenshot), mouse/keyboard (click, double_click, right_click, type_text, shortcut, scroll, drag), screenshot (take_screenshot), CDP (probe_app, cdp_connect, cdp_find_elements, cdp_click, cdp_fill), Android ADB (adb_tap, adb_key), app launcher (open_app). Decision-tree skill: AX first → visual fallback → CDP last resort. Computer Operator built-in CoWorker preset. Permissions panel (Accessibility + Screen Recording) with always-visible Grant buttons + manual path instructions. macOS arm64 + x64.
v0.9.x Cross-platform Computer Use + Web Tools Windows: UIA (IUIAutomation) AX tree, SendInput mouse/keyboard, BitBlt/GDI screenshots, WinRT OCR. Linux: X11/XTest input, XRandR display, scrot + XGetImage screenshots, Tesseract OCR, wmctrl window management. Same 20+ MCP tools on all 3 platforms. GitHub Actions CI now builds and packages macOS arm64 + Windows x64 + Linux x64 on every tag push.
v0.10.0 MCP Management MCP server registry in Settings (add/edit/remove, stdio & SSE transports). Auto-discover running local MCP processes. Per-agent MCP binding. Bundled quick-add servers: filesystem, memory, fetch, git.
v0.11.0 Skills & Custom Instructions Per-agent, per-project skill files (AGENTS.md, SKILL.md, .instructions.md). Global skills library in Settings. Skill injection at spawn time. Skill marketplace (import from URL / GitHub).
v0.12.0 Channels Management Named I/O channels in Settings: pipe agent stdout to files, webhooks, or other agents. Fan-out (broadcast one agent's output to multiple sinks). Fan-in (merge streams from multiple agents into one tab).
v0.13.0 Custom Agents AgentAdapter public package. Register third-party agents via manifest URL or local path. Agents tab shows community adapters with one-click install. Custom system-prompt per agent.
v0.14.0 Unified long-term memory SQLite + sqlite-vec embedding store. Background embed worker (Rust). MCP server tday-memory (recall / remember / forget). Per-project + global scopes. Memory browser + prune UI.
v0.15.0 Performance & polish xterm WebGL renderer. Lazy-render inactive tabs. Session snapshot/restore. Memory budget warnings. Profiling page (CPU/RSS/handles).
v1.0.0 GA Auto-update (Squirrel), signed & notarised builds for macOS/Windows/Linux, full docs site, telemetry opt-in.

5. Detailed Task Breakdown

v0.1.0 — Pi end-to-end ✅

The acceptance criterion: npm run dev opens a window with one tab running the pi agent in a real PTY; typing works, output streams, resizing works, closing the tab kills the process cleanly.

  • Repo scaffold
    • Decide stack & layout
    • Write this README
  • App skeleton (apps/desktop)
    • Electron main + preload + renderer in TypeScript
    • Vite for renderer dev/build
    • Tailwind + shadcn/ui base
    • border-beam component (magicui-port) on app frame
  • PTY + terminal
    • node-pty integration in main
    • xterm.js in renderer with fit + web-links addons
    • Bidirectional IPC: pty:spawn, pty:write, pty:resize, pty:data, pty:exit
  • Tab shell (multi-tab from the start)
    • Tab and Session data model
    • Cmd+W / close button kills the PTY
  • Pi adapter (packages/adapters/pi)
    • detect()which pi + pi --version
    • buildLaunch() — reads provider profile, sets env, args
    • Configurable binary path
  • Provider profile (static JSON)
    • ~/.tday/providers.json seeded on first launch
    • Loaded at launch, injected via env
  • Rust core stub (crates/tday-core)
    • cargo new --bin, prints version on --version
    • tday-core detect — JSON-RPC stub for v0.4.0
    • Wired into the Electron build so the binary ships next to the app
  • DX
    • pnpm dev launches everything
    • pnpm build produces signed-null .dmg + .zip for arm64 and x64
    • CI: lint + typecheck + cargo check

v0.2.0 — Multi-agent, multi-tab ✅

  • Adapters: pi, claude-code, codex, copilot, opencode (install / update / uninstall via npm i -g)
  • Tab bar with drag-reorder + multi-row wrap
  • Split new-tab button: default agent on click, dropdown chevron picker for any installed harness
  • Configurable default agent in Settings → Agents
  • Per-tab cwd staging + commit (Enter / Apply ↵ / Browse), restart-on-commit, last-cwd persistence
  • Persist open tabs across restart (id, title, agent, cwd)
  • Transcript snapshots (carry scrollback across restart)
  • Cmd+T / Cmd+Shift+T keyboard shortcuts

v0.3.0 — Providers UI + Gateway ✅

  • CRUD UI for provider profiles (sidebar list + "+ Add provider" picker, default-expanded)
  • Built-in templates for 28 vendors (OpenClaw mirror): DeepSeek, OpenAI, Anthropic, Google Gemini, xAI, Groq, Mistral, Moonshot, Cerebras, Together, Fireworks, Z.AI, Qwen, Volcengine, MiniMax, StepFun, OpenRouter, NVIDIA NIM, Hugging Face, Perplexity, Amazon Bedrock, SGLang, vLLM, Ollama, LM Studio, Vercel AI Gateway, LiteLLM, Custom
  • Dual base-URL selector (OpenAI-compatible vs Anthropic-compatible) for every provider
  • Latest-models dropdown per provider (freeform input still allowed)
  • Per-agent provider binding + per-agent model override (CLI flag projection — Codex / Claude / OpenCode honour Tday's model setting)
  • "Use one provider/model for all agents" shared-config toggle
  • DeepSeek Anthropic gateway proxy — in-process HTTP server translating OpenAI Responses API → Anthropic Messages API; supports streaming, extended thinking, tool use, multi-turn (113 unit tests, 12 modules)
  • Secrets via Rust keyring crate (currently plaintext ~/.tday/providers.json)
  • Per-tab provider override + "last-used" memory

v0.4.0 — Local-inference autodetect + UX Polish ✅

  • TypeScript probe system (discovery/probe.ts, specs.ts, index.ts)
    • TCP pre-filter then HTTP fingerprint for each service
    • Ollama: GET /api/tagsmodels[].name
    • LM Studio: GET /v1/modelsdata[].id (port 1234)
    • vLLM: GET /v1/models (port 8000)
    • llama.cpp / LocalAI / Jan: GET /v1/models (port 8080 / 8080 / 1337)
    • SGLang: GET /v1/models (port 30000)
    • LAN host probe: configurable extra hosts + optional /24 subnet sweep
  • probeBaseUrl for manual base-URL scan (tries /models, /v1/models, /api/tags)
  • IPC channel discovery:probe-url wired in main process
  • Settings UI: Scan button + latency badge + discovered-model chips + discoveredModels persistence
  • Usage analytics backend + full dashboard UI
    • usage/store.ts — SQLite-backed append + query
    • usage/pricing.ts — per-model cost table for 30+ providers
    • IPC channels usage:append / usage:query
    • Left sidebar (period filter: today/7d/30d/90d/custom, agent filter, refresh)
    • Right panel: 3-column summary cards, daily bar chart, by-model table, by-agent table
  • Settings redesign
    • History tab: agent sidebar, full-text search, time-based grouping, restore / hide entries
    • Resizable dialog (drag handle)
    • Lazy-mount (first open only) + startTransition for low-priority render
    • Provider list fills remaining height; Add provider pinned at bottom, default expanded
  • Tab UX
    • Tab title CSS-clip (max-w) with full title on hover tooltip
    • Last-active tab persisted and restored on restart; active tab sorted first in DOM
  • Terminal fixes
    • claude-code terminal width: RAF before spawn ensures font metrics; COLUMNS/LINES env vars as fallback
    • Double-SIGWINCH bug fixed: removed duplicate resize from active-tab effect; ResizeObserver guard for hidden containers
  • In-app update checker — GitHub releases API after 10 s then every 30 min; green dot badge on gear button; GitHub + releases links in menu
  • Platform / UX fixes
    • Windows: keep full menu, hide Logo only on win32
    • All dropdowns marked no-drag to prevent Electron drag-region swallowing hover events
    • Menu close delay 500 ms + padding bridge to keep submenus reachable
    • Keep Awake uses prevent-app-suspension only (no screen-dim side-effect)
    • History entries show full year · month · day · HH:MM
    • openExternal IPC (https-only) for in-app browser links
  • Rust scanner (tday-core) — TCP probe + HTTP fingerprint in native binary
  • mDNS/Bonjour discovery for LAN servers
  • Toast notification “Found Ollama with N models — add as provider?”
  • Background watch loop with exponential back-off

v0.5.x — Cron & Automation

  • Settings → Cron tab — job list sidebar with enable toggle, edit, clone, delete
  • ScheduleWidget — three modes: Interval (every N min/hour/day), At time (H:M + Daily/Weekdays/Weekly/Monthly), Custom (datetime-local picker auto-fills expr + raw cron input)
  • Human-readable schedule preview (Every weekday at 09:00 0 9 * * 1-5)
  • cron.ts main-process scheduler — node-cron, persistent JSON store, per-job run stats (lastRunAt, nextRunAt, runCount, lastStatus)
  • Job dashboard — summary cards per job, next-run countdown, last-status badge, manual ▶ Run, Refresh
  • initialPrompt on SpawnRequest — prompt flows renderer → main without any renderer-side setTimeout
    • CLI positional arg for codex / claude-code / opencode run / gemini / qwen-code
    • Bracketed-paste PTY write (ESC[200~…ESC[201~) for pi / copilot / crush / hermes — works even when screen is locked
  • OpenCode run subcommand fix (positional was misinterpreted as project path)
  • Clone cron job (Copy of X, enabled:false, opens in editor)
  • Cron UI theme: datetime-local input uses input-date class (dark color-scheme + fuchsia calendar icon)

v0.6.0 — Token usage analytics ✅

  • Dashboard UI: summary cards, daily chart, by-model and by-agent breakdown
  • Per-tab usage mini-badge (tokens / estimated cost)
  • Adapter parseUsage() hooks scraping token counts from agent output
  • Live cost estimation using pricing table
  • CSV / JSON export
  • Budget alerts (configurable per-agent / global cap)

v0.6.x — CoWorker system

  • CoWorker data model — three kinds: builtin:* (AGENT.md), online:* (URL-cached from GitHub), custom:* (inline / file / URL)
  • Settings → CoWorkers tab — full CRUD: create, edit, delete, preview system prompt
  • Three curated presets (non-deletable, English names):
    • 🧠 Karpathy Code Guidelines (online:karpathy)
    • 🤖 Devin-style Planner (online:devin-planner)
    • 📈 Earnings Call Analyst (online:earnings-analyst)
  • CoWorker dropdown in CwdBar — per-tab single-select; selecting a CoWorker immediately writes its system prompt into the running PTY (window.tday.write)
  • CoWorker binding in Cron jobs — system prompt prepended to task prompt at spawn (buildEffectivePrompt)
  • CoWorker binding at spawncoworkerId on SpawnRequest; main process calls buildEffectivePrompt before PTY launch
  • Settings tab bar: top-tab style (rounded-t) replacing pill-style tabs
  • Settings dialog backdrop: no-drag fix — tabs always clickable even when TabBar wraps to multiple rows
  • Settings dialog: lazy dialogSize init capped to viewport + overflow-y-auto so tabs are never pushed above visible area

v0.7.x — CoWorker Registry + Data Freshness

  • CoWorker registry expanded to 35 built-in presets across 7 categories:
    • 🧠 Mental Models (5 presets)
    • 🚀 Startup & Business (5 presets)
    • 💻 Coding & Engineering (6 presets)
    • ✍️ Writing & Content (5 presets)
    • 🔍 Research & Analysis (5 presets)
    • 🔒 Security & Privacy (4 presets)
    • ⚡ Productivity (5 presets)
  • GitHub ★ stars displayed on CoWorker cards and detail view (24 h TTL cache, refreshGitHubStars)
  • Unique ID derivation (deriveRegistrySlug) — path-based discriminator prevents ID collisions for repos with generic filenames (system.md, index.md)
  • Online registry refresh button with spinner and error display; loadRegistryPresets() prefers the source with more entries (bundled vs cache)
  • CronSection Refresh button moved to sidebar footer — same row as "Add cron job" (icon-only)
  • App-level state lifting — agents / coworkers / providers owned by App root, passed as props to Settings
    • Eliminates slow listAgents() IPC call on every Settings open (subprocess spawns for tool detection)
    • useEffect([open]) in Settings now only fetches fast/time-sensitive data (cron + getAllSettings)
    • Prop → local state sync effects for agentsProp / cfgProp to receive background updates
  • requestIdleCallback background refresh after Settings closes — silently re-fetches agents + coworkers + providers during browser idle time (5 s forced timeout fallback)
  • New-tab provider submenu now includes all preset models (presetForKind(p.kind)?.models) alongside discoveredModels and extraModels

v0.7.0 — MCP Management

MCP (Model Context Protocol) lets agents use tools, access resources, and receive prompts from external servers. Tday becomes the central registry for all MCP connections — configure once, available everywhere.

  • Settings → MCP Servers tab
    • Add / edit / remove MCP server entries (name, transport, command / URL, args, env)
    • Transport types: stdio (local process), SSE (remote HTTP), streamable-http
    • Per-server connection test + status badge
  • Auto-discovery of running local MCP processes (scan well-known ports, inspect mcp.json)
  • Per-agent MCP binding — choose which MCP servers each agent starts with
  • Bundled quick-add server cards in Settings:
    • @modelcontextprotocol/server-filesystem — local file access
    • @modelcontextprotocol/server-memory — persistent key-value memory
    • @modelcontextprotocol/server-fetch — HTTP fetch / web page reader
    • @modelcontextprotocol/server-git — Git log / diff / blame
  • Inject --mcp-config <json> into Claude Code / opencode / gemini at spawn time
  • MCP server log viewer inside the app

v0.7.1 — Channels Management

Named I/O channels let you wire agent outputs to external sinks or other agents — turning Tday into a lightweight multi-agent orchestrator.

  • Settings → Channels tab
    • Create / edit / delete named channel definitions
    • Channel types: file (append to log), webhook (HTTP POST), agent (pipe to another tab)
    • Per-channel filter: regex / glob on stdout lines
    • Channel enable/disable toggle
  • Fan-out — one agent’s output broadcast to multiple sinks simultaneously
  • Fan-in — merge stdout from multiple agents/tabs into a single virtual tab
  • Live channel inspector — real-time stream preview in a side panel
  • Per-tab channel binding (drag-and-drop tab onto channel)
  • Persist channel config to ~/.tday/channels.json

v0.7.2 — Custom Agents

Make AgentAdapter a public package so the community can ship their own agent integrations.

  • Publish @tday/adapter-sdk (TypeScript types + test harness)
  • Agent manifest format (tday-adapter.json): id, displayName, detect, launch, parseUsage
  • Settings → Agents → “Community adapters” section
    • Install from npm package name
    • Install from local path / manifest URL
    • Update / remove installed community adapters
  • Custom system-prompt per agent (injected before every session)
  • Adapter sandbox: run with --no-asar + restricted IPC subset

v0.8.x — Computer Use

  • Settings → Computer Use tab — enable/disable per agent; shows supported agents (Claude Code, Codex, Gemini, OpenCode, Pi)
  • tday-nativecore Rust MCP stdio server injected into agent configs at spawn:
    • claude-code: per-session temp settings file (mcpServers)
    • gemini: ~/.gemini/settings.json (ref-counted, safe concurrent sessions)
    • opencode: opencode.json mcp.servers (ref-counted)
    • codex: ~/.codex/config.json mcpServers (ref-counted)
    • pi: ~/.pi/agent/config.json mcpServers + skill file at ~/.pi/agent/skills/tday-computer-use/SKILL.md
  • AX tools: take_ax_snapshot, ax_click, ax_set_value, ax_select, ax_perform_action
  • OCR tools: find_text (Apple Vision, multi-display via CGDirectDisplayID), ocr_screenshot
  • Mouse/keyboard: click, double_click, right_click, type_text, shortcut, scroll, drag
  • Screenshot: take_screenshot (per display, stable CGDirectDisplayID — fixes external monitor detection)
  • CDP tools: probe_app, cdp_connect, cdp_find_elements, cdp_click, cdp_fill
  • Android ADB: adb_tap, adb_key, adb_screenshot
  • Launcher: open_app
  • COMPUTER_USE_SKILL injected as system prompt: decision tree (AX → visual → CDP), tool descriptions, reliability rules — no take_screenshot as default first step
  • Computer Operator built-in CoWorker preset (builtin:computer-use-operator)
  • Permissions panel — Accessibility + Screen Recording with always-visible Grant buttons, manual path instructions ("System Settings → Privacy & Security → …"), checkPermissions IPC, requestPermission IPC
  • Self-signed cert for CI signing (hardcoded in release.yml) — prevents macOS TCC re-prompting on every update

v0.9.x — Cross-platform Computer Use

Windows and Linux now have full feature parity with macOS Computer Use — same 20+ MCP tools, same API surface.

  • Windows platform (crates/tday-nativecore/src/platform/windows/)
    • uia.rs — IUIAutomation AX tree (take_ax_snapshot), coordinate-based AXRef, ax_click / ax_set_value / ax_perform_action
    • input.rsSendInput mouse/keyboard; Unicode text input; all modifier keys and function keys
    • display.rsEnumDisplayMonitors multi-monitor, DPI-aware coordinate mapping (Per-Monitor V2)
    • screenshot.rs — BitBlt/GDI capture (full screen / region / window), image crate PNG+JPEG encoding
    • ocr.rs — WinRT Windows.Media.Ocr (Windows 10 1903+), word-level bounding boxes
    • window.rsEnumWindows, DWM extended frame bounds, per-window PID
    • app.rsEnumProcesses app list, cmd /c start launcher, TerminateProcess, wmctrl-style SetWindowPos
  • Linux platform (crates/tday-nativecore/src/platform/linux/)
    • input.rs — X11 XTest (XTestFakeButtonEvent, XTestFakeKeyEvent, XTestFakeMotionEvent); xdotool type for Unicode
    • display.rs — XRandR CRTC enumeration; GDK_SCALE fractional scale support
    • screenshot.rsscrot / import / xwd+convert with X11 XGetImage fallback; BGRA→RGBA conversion
    • ocr.rs — Tesseract subprocess, TSV output parsing, word-level bounding boxes
    • window.rswmctrl -l -G window list, /proc/<pid>/comm process name
    • app.rs/proc process enumeration, wmctrl / xdotool activation, kill -TERM/-KILL, xdg-open launcher
    • atspi.rs — coordinate-based AXRef stub; xdotool/xprop for element_at_point and frontmost_pid
  • platform/mod.rs — Windows + Linux cfg blocks + pub use re-exports
  • session/ax_session.rs#[cfg(target_os = "macos")]#[cfg(any(macos, windows, linux))]
  • handlers/probe_app.rs, tracking/hover_tracker.rs, tracking/screen_recorder.rs — same cfg expansion
  • CI.github/workflows/release.yml re-enables windows-2022 and ubuntu-22.04 matrix; Linux apt installs libgtk-3-dev libx11-dev libxrandr-dev libxtst-dev and packaging tools
  • Shared tday-nativecore HTTP MCP server (NativecoreService) — single long-lived process shared across all Computer Use sessions:
    • nativecore-service.ts — ref-counted singleton; lazy 60 s kill after last release; NATIVECORE_PORT:N stdout parsing
    • parent_watch.rs — Rust watchdog: SIGTERM self when parent PID exits (prevents zombie nativecore on crash)
    • singleton.rs — port-file locking prevents duplicate nativecore processes
  • MCP session proxy (startMcpSessionProxy) — per-session Node.js HTTP proxy managing Mcp-Session-Id:
    • Transparent initialize / notifications/initialized handshake with nativecore (rmcp 0.2.1 Streamable HTTP)
    • Auto re-initialize on HTTP 401 (session expired) or 422 (no session context) and replay original request
    • Caches initialize + notifications/initialized bodies for re-init replay
    • Correct content-length header for HTTP keep-alive compatibility
  • Codex namespace-tool proxy fix (startCodexApiProxy):
    • expandNamespaceTools builds shortToFlatMcpName map while expanding type:"namespace" → flat type:"function" tools
    • splitFlatMcpName resolves bare tool names (e.g. list_apps) the model calls from SKILL text back to {namespace, name} for codex router
    • Fixes error=unsupported call: list_apps for all 76 nativecore tools
  • 76-tool nativecore — expanded from 20+ to 76 MCP tools covering CDP (30+ tools), Android ADB (12 tools), App Protocol (WebSocket), hover tracking, screen recording, extended AX (ax_find, ax_focused, click_text, element_at_point), window management (resize_window, quit_app), system tools (sys_process, sys_wait, execute_command, filesystem, clipboard, scrape)

v0.10.x — Web Search & Web Tools

Give every agent instant access to the live web — configure search providers in Settings and inject them as MCP tools per agent.

  • Settings → Web Search sub-panel
    • Provider cards: Brave Search, Tavily, Jina, Perplexity, SearXNG (self-hosted)
    • API key input per provider (stored in OS keychain)
    • Per-agent enable/disable toggle
  • One-click MCP install for each provider’s official MCP server
  • Web page reader / URL fetcher shared tool (via Jina Reader or @modelcontextprotocol/server-fetch)
  • Show active search provider badge on tab header

v0.10.0 — Skills & Custom Instructions

Define reusable instruction files that are automatically injected into agent sessions.

  • Skill file formats supported: AGENTS.md, SKILL.md, .instructions.md, CLAUDE.md, copilot-instructions.md
  • Project-level auto-discovery: scan project root + .github/ on each PTY spawn
  • Global skills library in Settings → Skills
    • Create / edit / delete named skills (Markdown editor)
    • Tag skills (language, framework, style, domain)
    • Enable/disable per agent-kind
  • Skill injection at spawn time (--system-prompt / --instructions / temp context file)
  • Skill marketplace — import from GitHub URL or gist

v0.11.0 — Unified long-term memory

  • sqlite-vec embedding store (Rust)
  • Background embed-on-write worker
  • MCP server tday-memory exposing recall, remember, forget
  • Per-project + global memory scopes
  • Memory browser UI (search, edit, prune, export)

v0.12.0 — Performance & polish

  • xterm WebGL renderer; benchmark vs canvas
  • Lazy-render inactive tabs
  • Session snapshot/restore (carry scrollback across restart)
  • Memory budget per tab; warn on leak
  • Profiling page (CPU/RSS/handles)

v0.13.0+ — see Roadmap table


6. Repository Layout

tday/
├── apps/
│   └── desktop/                  # Electron app (main + preload + renderer)
│       ├── src/main/             # main process
│       ├── src/preload/          # contextBridge
│       ├── src/renderer/         # React app
│       ├── electron.vite.config.ts
│       └── package.json
├── packages/
│   ├── shared/                   # shared types (IPC contracts, AgentAdapter, …)
│   ├── adapters/
│   │   ├── pi/                   # v0.1.0
│   │   ├── claude-code/          # v0.2.0
│   │   ├── codex/                # v0.2.0
│   │   └── opencode/             # v0.2.0
│   └── ui/                       # shared components (border-beam, …)
├── crates/
│   └── tday-core/             # Rust binary (detect, tokens, memory)
├── pnpm-workspace.yaml
├── package.json
└── README.md

7. Quickstart

# prerequisites
node -v        # ≥ 20
pnpm -v        # ≥ 9
rustc --version  # ≥ 1.78

# install + run
pnpm install
pnpm build:core      # builds tday-core (Rust)
pnpm dev             # launches the desktop app

# point Tday at your `pi` binary if it isn't on PATH
echo '{ "agents": { "pi": { "bin": "/absolute/path/to/pi" } } }' \
  > ~/.tday/agents.json

The first window opens with a single tab running pi inside a real PTY.


8. Build and Release

Local build

# typecheck the workspace
pnpm -r typecheck

# build the desktop app
pnpm --filter @tday/desktop build

# create macOS packages locally (.dmg + .zip for x64 and arm64)
pnpm --filter @tday/desktop package:mac

# create Windows and Linux packages locally on their native hosts
pnpm --filter @tday/desktop package:win
pnpm --filter @tday/desktop package:linux

Local packaging writes artifacts to apps/desktop/release/<version>/. Those generated files are ignored by git and are not meant to be committed.

GitHub Actions

The repository ships with .github/workflows/release.yml.

  • Push to main: no build (avoids noise on every commit).
  • Push a tag like v0.9.17: builds macOS arm64, Windows x64, and Linux x64 artifacts in parallel and publishes them to a GitHub Release automatically.
  • Run the workflow manually: builds artifacts on demand; if publish is enabled, it creates a draft GitHub Release.

The CI packaging step uses electron-builder --publish never, so the build pipeline uploads release assets to GitHub Releases only and does not push packaged binaries back to the repository.

Recommended release flow

# 1. commit your code changes
git push origin main

# 2. create a version tag to trigger a GitHub Release
git tag v0.9.17
git push origin v0.9.17

9. Design principles

  1. Native where it matters. PTY, tokenization, memory, scanners — all in Rust or node-pty. Electron is the chrome, never the bottleneck.
  2. Adapter-first. Adding a new harness must be ≤ 100 LOC.
  3. Provider-agnostic. No harness should be locked to a vendor; we own env injection.
  4. Local-first. Everything works offline with Ollama/LM Studio/llama.cpp/vLLM.
  5. Don’t hide the terminal. It’s a terminal. Keystrokes, escape codes, colors, mouse — all forwarded faithfully.

10. Supported Harness Agents

Agent Install Notes
Pi (pi) npm i -g @mariozechner/pi-coding-agent
Claude Code (claude-code) npm i -g @anthropic-ai/claude-code Session resume via --resume <uuid>; conversation history from ~/.claude/projects/ replayed on restore
Codex (codex) npm i -g @openai/codex Session resume via codex resume <uuid>; conversation history from ~/.codex/sessions/ replayed on restore
Copilot CLI (copilot) npm i -g @github/copilot-cli
OpenCode (opencode) npm i -g opencode-ai Session resume via --session <id>; conversation history from SQLite ~/.local/share/opencode/ replayed on restore
Gemini (gemini) npm i -g @google/gemini-cli
Qwen Code (qwen-code) npm i -g qwen-code
Crush (crush) npm i -g crush-cli
Hermes (hermes) install manually, ensure hermes is on PATH

10. Supported Model Providers

Provider API Style Notes
DeepSeek OpenAI · Anthropic DeepSeek V4 Pro / V4 Flash (Apr 2026), DeepSeek V3.2 via in-process Anthropic gateway
OpenAI OpenAI GPT-5.5, GPT-5.5 Pro, GPT-5.4, GPT-5.4-mini, GPT-5.4-nano
Anthropic Anthropic Claude Opus 4.7, Claude Sonnet 4.6, Claude Sonnet 4.5, Claude Haiku 4.5
Google Gemini OpenAI Gemini 2.5 Pro / Flash (stable); Gemini 3.1 Pro / 3 Flash (preview)
xAI (Grok) OpenAI Grok-4.3, Grok-4.20 (reasoning / non-reasoning)
Groq OpenAI Llama 4 Scout / Maverick, Llama 3.3-70B via Groq LPU
Mistral OpenAI Mistral Large 3, Codestral 2501, Mistral Small 3.1
Moonshot (Kimi) OpenAI · Anthropic Kimi k2, Kimi-VL-A3B
Cerebras OpenAI Llama on Cerebras WSE
Together AI OpenAI 200+ open models
Fireworks AI OpenAI Fast open-model inference
Z.AI OpenAI · Anthropic GLM-4 series
Qwen (Alibaba) OpenAI Qwen3.6-Max-Preview, Qwen3.6-Plus, Qwen3-Coder-480B-A35B
Volcengine (Doubao) OpenAI Doubao-1.5-Pro, Doubao-Pro-32K
MiniMax OpenAI MiniMax-Text-01, MiniMax-M1
StepFun OpenAI Step-3, Step-2-16K
OpenRouter OpenAI Unified gateway to 300+ models
NVIDIA NIM OpenAI Llama 4, Qwen3.6, Mistral on NVIDIA NIM
Hugging Face OpenAI Serverless inference API
Perplexity OpenAI Sonar Pro, Sonar Reasoning Pro
Amazon Bedrock Anthropic Claude, Llama, Mistral via Bedrock
SGLang OpenAI Self-hosted high-throughput server
vLLM OpenAI Self-hosted PagedAttention server
Ollama OpenAI Local models (auto-detected on LAN)
LM Studio OpenAI Local GUI inference server (auto-detected)
Vercel AI Gateway OpenAI Vercel-hosted unified gateway
LiteLLM OpenAI Self-hosted proxy for 100+ models
Custom OpenAI · Anthropic Any OpenAI-compatible or Anthropic-compatible endpoint

Local-inference auto-discovery — Tday scans localhost and your LAN for running Ollama, LM Studio, vLLM, llama.cpp, SGLang, and LocalAI instances and surfaces them as providers automatically (Settings → Scan).


11. Renderer Modularity Rules

The renderer follows architectural constraints enforced by ESLint (eslint.config.mjs) — the same philosophy as VS Code: prevent wrong structure from being possible, rather than capping line counts.

Layer rules (enforced)

Rule What it prevents
Orchestrators (Settings.tsx, App.tsx) contain no inline JSX UI logic State + prop wiring only; UI goes in Section/Widget files
*-helpers.ts / hooks/ contain no JSX Pure logic stays pure
Settings/ sub-files import only from @tday/shared, ./types, ./shared, ./cron-helpers, ./history-helpers, or React — never from ../../App No upward coupling
New visually distinct panels get their own *Section.tsxnever added inline to an existing file Forces isolation at creation time
Shared utilities used by 3+ components live in shared.tsx or a dedicated *-helpers.tsnot copy-pasted Single source of truth

ESLint rules: no-restricted-imports (no upward coupling), @typescript-eslint/no-explicit-any (warn), prefer-const. The CI typecheck + test scripts must stay green before merging.

Split triggers

Apply these rules when adding or editing code:

Condition Action
File approaches the line limit Split: extract pure logic into *-helpers.ts, extract hook state into hooks/use*.ts, extract UI into a new *Section.tsx or *Widget.tsx
3+ components share the same utility Move it to shared.tsx or a dedicated *-helpers.ts
A hook exceeds ~100 lines Extract sub-hooks
Business logic lands in an orchestrator (Settings.tsx, App.tsx) Move it down to the owning Section or hook
A new visually distinct panel is added It always gets its own *Section.tsx

Settings module map

src/renderer/src/
  Settings.tsx              ← orchestrator (~200 lines, state + props only)
  Settings/
    types.ts                ← Section / SchedMode / etc. — no JSX
    shared.tsx              ← MiniMarkdown, SectionTab, Field, StatCard, DailyBarChart
    cron-helpers.ts         ← parseCronSchedule, buildCronExpr, describeCronExpr
    history-helpers.ts      ← histTimeGroup, histRelative, etc.
    ProvidersSection.tsx    ← provider profiles, URL probe, model discovery
    AgentsSection.tsx       ← agent list, per-agent config, shared settings
    CronSection.tsx         ← cron job list + editor
    UsageSection.tsx        ← token analytics dashboard
    HistorySection.tsx      ← closed-tab history
    ScheduleWidget.tsx      ← interval / at-time / custom cron picker
    __tests__/
      cron-helpers.test.ts
      history-helpers.test.ts

12. Contributing CoWorkers

The CoWorkers.md file in this repository is the community-curated source of preset Online CoWorkers — GitHub-hosted prompt/skill files that Tday fetches and injects as agent system prompts.

How to contribute

  1. Fork this repository

  2. Add your entry to the appropriate category table in CoWorkers.md:

    Field Description
    Name Short display name, e.g. Feynman.skill
    Description One sentence describing the thinking style or skill
    GitHub Direct link to the repo or the prompt file (GitHub blob URL)
  3. Submit a Pull Request — please verify the URL is publicly accessible and the content is a valid Markdown prompt

New categories are welcome. Keep descriptions concise (one sentence). Point to a specific file blob URL for pinned versions, or a repo root for the latest main.


13. License

MIT License

tday-nativecore (the Computer Use Rust binary) is licensed under the Business Source License 1.1 — see crates/tday-nativecore/LICENSE.

About

All-in-One Harness Agent Terminal

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors