summaryrefslogtreecommitdiffhomepage
path: root/packages/api/src/index.ts
AgeCommit message (Collapse)Author
2026-06-02Fix build scripts and deployment port issueAdam Malczewski
2026-06-02feat(api): fall back to next port (3000→3010) when the port is in useAdam Malczewski
The API server bound a fixed port (3000) and died with EADDRINUSE when it was taken — painful when running multiple dispatch instances (e.g. testing several feature branches at once). Replace the static default export with an explicit Bun.serve retry loop that increments the port by one on EADDRINUSE, from START_PORT (PORT env or 3000) up to MAX_PORT (3010), logging the chosen port and a hint to repoint the frontend's API URL on a bump. Guarded by import.meta.main so importing the module (for `app`) never binds a port. Frontend unchanged — set its API URL manually when a bump occurs.
2026-05-23feat: web_search + youtube_transcribe tools, shell interrupt backgrounding, ↵Adam Malczewski
fixes - Add web_search tool (Firecrawl POST to /v1/search with query, limit, lang, country, scrapeOptions) - Add youtube_transcribe tool (GET to transcriber service, handles completed/queued/failed statuses) - Both tools registered for parent agents (always) and child agents (permission-gated) - Added to summon enum, TOOL_DESCRIPTIONS, and core exports - Shell interrupt: run_shell now races against user queue interrupt - When interrupted, command continues in background with run_shell_<uuid> job ID - BackgroundShellStore holds running processes, auto-cleans 10min after completion - retrieve tool extended to handle both agent IDs and shell job IDs - Tool error detection: results starting with 'Error:' now marked isError in UI - Fix TS error: cast unavailMatch[1] regex capture group to string - Docker: network_mode host for Tailscale/LAN access to external services - Bun.serve idleTimeout set to 60s (was default 10s) - KeyUsage: clearer message when OpenCode usage data unavailable - Firecrawl: only send scrapeOptions when scrape=true (avoid 400 on instances without scrape support)
2026-05-22feat: Arch Linux packaging with Electron frontend, systemd backend service, ↵Adam Malczewski
and Windows exe build - Add Electron wrapper (main.cjs, preload.cjs) for desktop frontend - Add systemd service unit, env config, and sysusers for backend API - Add PKGBUILD and .install for Arch package (makepkg -si) - Add desktop entry, SVG/PNG icon, and wrapper scripts - Add bin/build-pkg, bin/install-pkg, bin/windows-pkg scripts - Make API port configurable via PORT env var (default 3000, prod 18390) - Add electron-builder config for Windows exe cross-compilation - Set vite base to './' for Electron file:// loading
2026-05-22feat: agent builder, CWD support, auto-save, UI polish, unavailable tool ↵Adam Malczewski
handling - Agent Builder: full CRUD with card grid, drag-and-drop model reorder, edit/delete - Auto-save on edit with 600ms debounce, AbortController for concurrency, fieldset disabled until name entered - Agent definitions stored as TOML with cwd field, loaded from global/project dirs - Working directory: per-tab CWD override in Chat Settings, agent default CWD, auto-create on first message - CWD validation: check-dir endpoint with ~ expansion, real-time validity indicator - Subagent CWD validated against parent's effective CWD using path.relative - Unavailable tool calls: caught gracefully, shown as tool call with error badge, model retries - UI: tab bar border radius, sidebar border removed, chat input ghost style, scroll-to-bottom rectangle - Skills dir collapse uses CSS rotation, Model Choice renamed to Chat Settings, System Prompt view removed - Reusable SkillsBrowser/ToolPermissions with external mode for Agent Builder - ModelSelector: Agent/Manual toggle, agent list, Agent Settings link - Page router, skills recursive scanning, bin/up gopass removed, docker volume mounts
2026-05-21feat: tab system with per-tab agents, DB persistence, and DaisyUI tabs-lift UIAdam Malczewski
- Add tabs, messages, and settings tables to SQLite database - Backend: refactor AgentManager to manage per-tab Agent instances via Map<tabId, TabAgent> - Backend: WebSocket events tagged with tabId for multiplexing - Backend: tab CRUD routes (create, list, update, archive, messages) - Backend: persist user and assistant messages to DB during chat - Frontend: new tabStore replaces single chatStore with multi-tab reactive state - Frontend: TabBar component using DaisyUI tabs-lift style with status dots - Frontend: Settings sidebar panel for title generation model selection - Frontend: wire ChatPanel, ChatInput, Header to use tabStore - Fix HMR listener accumulation via wsClient.clearCallbacks() - Delete old single-chat chatStore (chat.svelte.ts)
2026-05-20feat: phase 3 — config, skills, model groups, task list, and sidebar UIAdam Malczewski
- Config system: TOML-based dispatch.toml with hot-reload via chokidar - Model/key resolution: tag-based model selection, key fallback chains - Skills system: directory loader with TOML frontmatter, agent mappings - Task list tool: add/update/list/get operations with WebSocket events - API routes: GET /config, /skills, /skills/:name, /models, /models/resolve - Frontend: sidebar with model status, task list, config viewer, skills browser, permission log - Sliding sidebar animation using CSS transitions (not Svelte transitions)
2026-05-19feat: Phase 2 — shell permissions, tree-sitter analysis, permission UIAdam Malczewski
Permission engine: - Rule-based engine: wildcard matching, last-match-wins, reject cascade - PermissionService with pending/approved state, PermissionChecker interface - dispatch.yaml config loader with per-permission pattern rules Shell tool: - run_shell tool with child_process spawn, timeout, streaming output - Tree-sitter static analysis (web-tree-sitter + tree-sitter-bash WASM) - BashArity command normalization for 'always allow' patterns - FILE_COMMANDS set: rm, cp, mv, mkdir, ls, find, grep, cat, etc. Agent loop refactored: - Removed maxSteps, manual step loop with tool execution - Permission checks on shell commands (external_directory only) - Permission checks on file tools outside workspace boundary - Symlink bypass fix (realpathSync), .. false positive fix - Shell output streaming via Promise.race + setImmediate polling API layer: - PermissionManager wraps PermissionService, broadcasts via WebSocket - WebSocket handles permission-reply messages from frontend - Config loaded from dispatch.yaml, converted to ruleset Frontend: - Permission prompt modal (native dialog, focus trap, ARIA) - Always-allow confirmation flow with pattern preview - Shell output display (live streaming + final parsed result) - Permission log panel (fixed bottom-right overlay) - Exit code badge (green 0, red non-zero) 134 tests, typecheck clean on all 3 packages
2026-05-19Phase 1: single agent + basic UIAdam Malczewski
- Bun monorepo with @dispatch/core, @dispatch/api, @dispatch/frontend - Agent runtime with Vercel AI SDK, streaming via WebSocket - Tools: read_file, write_file, list_files (scoped to working directory) - Hono API server with POST /chat, GET /status, GET /health, WS /ws - Svelte 5 + DaisyUI frontend with chat UI, theme switcher, copy button - OpenCode Go (Zen) as LLM provider, deepseek-v4-flash-free model - Docker setup (dev + prod) with bin/ scripts and gopass secrets - Biome v2 linting/formatting, Vitest tests (44 passing) - Debug info attached to error messages for diagnostics