8a0dffbcae
feat: add Go server implementation in go-server/ Full Go port of local-mcp with all core features. Copied from local-mcp-go worktree to consolidate into single-branch repo (easier maintenance). Architecture: - internal/config: Environment variable configuration - internal/models: Shared types (Instruction, Settings, AgentActivity, etc.) - internal/db: SQLite init with modernc.org/sqlite (pure Go, no CGo) - internal/store: Database operations + WakeupSignal + AgentTracker - internal/events: SSE broker for browser /api/events endpoint - internal/mcp: get_user_request MCP tool with 5s keepalive progress bars - internal/api: chi HTTP router with Bearer auth middleware - main.go: Entry point with auto port switching and Windows interactive banner Dependencies: - github.com/mark3labs/mcp-go@v0.46.0 - github.com/go-chi/chi/v5@v5.2.5 - modernc.org/sqlite@v1.47.0 (pure Go SQLite) - github.com/google/uuid@v1.6.0 Static assets embedded via //go:embed static Features matching Python: - Same wait strategy: 50s with 5s progress keepalives - Same hardcoded constants (DEFAULT_WAIT_SECONDS, DEFAULT_EMPTY_RESPONSE) - Auto port switching (tries 8000-8009) - Windows interactive mode (formatted banner on double-click launch) Build: cd go-server && go build -o local-mcp.exe . Run: ./local-mcp.exe Binary size: ~18 MB (vs Python ~60+ MB memory footprint) Startup: ~10 ms (vs Python ~1-2s)
Brandon Zhang
2026-03-27 15:45:26 +08:00
4db402f258
feat: hardcode wait time and default response as constants Changes: - Add DEFAULT_WAIT_SECONDS = 50 (replaces config.default_wait_seconds) - Add DEFAULT_EMPTY_RESPONSE = 'call this tool... ' (replaces config.default_empty_response) - Remove wait and empty response fields from WebUI Settings panel (only agent_stale_after_seconds remains configurable) Rationale: These values are fundamental to the 60s timeout mitigation strategy and should not be user-configurable. The 50s wait with 5s keepalives is the optimal balance for staying under the Copilot 60s wall-clock limit while providing responsive progress feedback.
Brandon Zhang
2026-03-27 15:45:06 +08:00
ba91349232
experiment: reduce keepalive to 5s and add progress bar EXPERIMENT (NOT FOR PRODUCTION YET) Changes: - KEEPALIVE_INTERVAL_SECONDS reduced from 20s to 5s - Keepalive messages now show progress bar with dots: ●●●●○○○○○○ - Show elapsed time, total wait, and remaining seconds - Example: ⏳ Waiting for instructions... ●●●●○○○○○○ 20s / 50s (agent=copilot, 30s remaining) Goal: Test if more frequent progress updates provide better UX and prevent perceived freezing during the 50s wait. No functional change - the 60s client timeout limit remains the binding constraint.
Brandon Zhang
2026-03-27 15:44:49 +08:00
204f7c4ff6
docs(agents): add warning about committing compiled binaries Binary executables bloat .git history and cause storage issues on constrained upstream repos. Added recovery procedure: git reset --soft HEAD~N, git reset HEAD <file>, delete, recommit.
Brandon Zhang
2026-03-27 14:49:17 +08:00
fa9d5c61c9
docs(agents): note that git commands require --no-pager to avoid terminal hang git may invoke less as a pager which blocks the terminal waiting for user interaction. Always use 'git --no-pager <command>' or pipe through Out-String/Format-List in PowerShell sessions.
Brandon Zhang
2026-03-27 14:00:12 +08:00
298ad54b5c
fix(ui/theme): replace light theme with clean material design palette The previous light theme used warm/organic off-whites and muted tones that felt muddy. Replaced with a crisp material-inspired palette: Surfaces - bg-void #f0f2f5 (cool-grey base) - bg-base #f5f7fa (very light cool background) - bg-raised #ffffff (pure white cards) - bg-hover #e3e8f0 (clear interactive hover) Typography - text-primary #1a202c (near-black, high contrast) - text-secondary #4a5568 (balanced mid-grey) - text-muted #8896a7 (clear but soft) Accents (Material Design colour values) - cyan #0277bd Blue 700 (replaces washed-out #007fa8) - green #388e3c Green 700 - amber #e65100 Deep Orange 900 (warmer, more material) - red #d32f2f Red 700 Shadows Dual-layer transparent shadows for better depth perception on light backgrounds. Also adds @keyframes fade-in-up used by the shortcuts add form.
Brandon Zhang
2026-03-27 13:55:36 +08:00
93bce1521b
feat(ui): add quick shortcuts panel with add/edit/delete support Adds a compact shortcuts row inside the composer panel for one-click instruction queuing, with full lifecycle management stored in localStorage. Features -------- - Six built-in defaults (Stop, Summarize, Explain error, Undo, Continue, etc.) - Click any chip → instantly POSTs to /api/instructions, no typing required - Cyan border pulse on fire; green glow flash on success - Edit mode (toggle button in header): - Per-chip edit (✏) button → replaces chip with inline input, Enter to save - Per-chip delete (✕) button → removes with vanish animation - '+ Add' chip → inline form appended below rail - All changes persisted to localStorage key 'local-mcp-shortcuts' - Accessible: button elements, aria-labels, keyboard support (Enter/Escape) Files ----- - static/js/shortcuts.js new module (loadShortcuts, renderShortcuts, startInlineEdit, showAddPrompt, initShortcuts) - static/index.html #shortcuts-container inside composer .panel-body - static/js/app.js import + initShortcuts() in bootstrap() - static/css/components.css .shortcuts-container, .shortcut-chip variants, .shortcut-inline-edit, keyframes chip-fire/sent/vanish
Brandon Zhang
2026-03-27 13:55:22 +08:00
056ae70e9a
feat(mcp): add periodic SSE keepalive notifications during queue wait When the tool is waiting for an instruction, send ctx.info() log notifications to the client every KEEPALIVE_INTERVAL_SECONDS (default 20). Purpose ------- These notifications write bytes to the SSE stream, resetting any transport-level HTTP read timeout on the client side (e.g. httpx Timeout(read=N)). This prevents premature connection drops when wait periods exceed the client's inactivity window. Caveat ------ Application-level wall-clock timers (anyio.fail_after / JS SDK equivalents) are NOT affected by SSE events -- they count from request start regardless. This is confirmed by experiments in tests/test_keepalive.py and tests/run_keepalive_experiments.py. Experiment results (summarised in tests/run_keepalive_experiments.py) ---------------------------------------------------------------------- - Exp 1: anyio.fail_after(5s) fires at 5.98s with NO keepalives. - Exp 2: anyio.fail_after(10s) fires at 10.90s WITH keepalives every 2s. Keepalives have ZERO effect on app-level timers. - Exp 3b: httpx read=8s, keepalive=2s -> SUCCESS at 51s. Keepalives DO prevent transport-level read timeouts. The Copilot extension 60s limit is almost certainly application-level (hardcoded wall-clock), so default_wait_seconds=50 remains the correct mitigation (returns before the 60s deadline). The keepalives provide defence-in-depth against any proxy/NAT inactivity drops.
Brandon Zhang
2026-03-27 13:54:52 +08:00
b1fdd98740
fix(script): add Windows .venv/Scripts path fallback in server.sh On Windows the venv Python binary lives at .venv/Scripts/python.exe, not .venv/bin/python. Fall back to the Windows path when the Unix path does not exist so the script works cross-platform.
Brandon Zhang
2026-03-27 13:53:38 +08:00
009fd039a2
feat: optional Bearer-token authentication via API_TOKEN env var Disabled by default (empty API_TOKEN). When set: - All /api/* and /mcp requests require: Authorization: Bearer <token> - Public exemptions: /, /healthz, /static/*, /auth-check - Web UI: pre-flight /auth-check on load; shows token modal if required - Token stored in sessionStorage, sent on every API request - Mid-session 401s re-trigger the token modal - MCP clients must pass the header: Authorization: Bearer <token> Files changed: - app/config.py: api_token field + API_TOKEN env var - app/api/auth.py: Starlette BaseHTTPMiddleware for token enforcement - main.py: register middleware + /auth-check public endpoint - static/js/api.js: token storage, auth header, 401 handler hook - static/js/app.js: auth pre-flight, showTokenModal(), bootstrap() - static/css/components.css: .auth-overlay / .auth-card styles - README.md: API_TOKEN env var docs + MCP client header example
cabbage2026-03-27 04:28:12 +08:00
1cc75afe87
feat: add server.sh bash management script (macOS/Linux) Equivalent to server.ps1 for bash environments: - start / stop / restart / status / logs [N|-f] - Detached background process via nohup - PID file in logs/ with live-process verification - Port-based fallback detection via lsof - Memory reporting (Linux /proc + macOS ps) - Colour output with ANSI codes - stderr error highlighting in status view - Follow mode (-f) for live log tailing
cabbage2026-03-27 04:21:40 +08:00
7de4a03d94
fix: Enter key confirms edit (Shift+Enter for newline) Edit textarea now mirrors composer behavior: - Enter alone → save the edit - Shift+Enter → insert newline - Escape → cancel edit
cabbage2026-03-27 04:17:57 +08:00
589f45ba32
refactor: remove wait_seconds from get_user_request tool Wait time is now fully server-controlled via default_wait_seconds setting. Agents can no longer request a different wait duration - only the user controls this via the web UI. - Remove wait_seconds param from get_user_request signature - Simplify actual_wait to min(cfg.default_wait_seconds, MAX_WAIT) - Update Settings panel label from 'Min Wait' to 'Wait (sec)' - Update hint text to explain server-only control - Update README: input schema, behavior rules, settings description, changelog
cabbage2026-03-27 04:16:33 +08:00
256a445e2f
feat: add Clear History button to delete all consumed instructions - Backend: instruction_service.clear_consumed() bulk-deletes consumed rows - Backend: DELETE /api/instructions/consumed route (preserves pending) - Frontend: Clear button in consumed panel header (hidden when empty) - Frontend: SSE handler for history.cleared event - instant UI update - Frontend: api.clearConsumed() fetch wrapper
cabbage2026-03-27 04:16:24 +08:00