Commit Graph

543 Commits

Author SHA1 Message Date
William Valentin d72a04ef99 docs(phase-01): complete phase execution — verification passed 2026-02-09 20:32:24 -08:00
William Valentin 24688d1a16 docs(01-03): complete daemon composition root plan — Phase 1 done
- Created 01-03-SUMMARY.md with self-check passed
- Updated STATE.md: Phase 1 complete, 3/3 plans done
- Updated ROADMAP.md: Phase 1 marked complete
- daemon/index.ts: 1087 → 140 lines (87% reduction)
- All 1077 tests pass, zero type errors
2026-02-09 20:25:39 -08:00
William Valentin 701fcfcaed refactor(01-03): extract services/skills/gateway/mcp into services.ts, reduce index.ts to 140 lines
- Extract initSkills(), initMcp(), loadSystemPrompt(), initPairingManager(), createGateway(), startServices() into services.ts
- daemon/index.ts reduced from 386 to 140 lines (64% reduction, 87% from 1087 baseline)
- Organize imports with section comments (External, Config, Daemon Modules, Infrastructure)
- Add section dividers in startDaemon() (Data & Sessions, Core Services, Model & Prompt, Gateway & Channels, Tier 1 Tools, Lifecycle)
- Convert unused value imports to type-only imports
- DaemonContext interface and re-exports unchanged
2026-02-09 20:22:34 -08:00
William Valentin 688f7a5154 docs(01-02): complete channel/agent/routing extraction plan
- Add 01-02-SUMMARY.md with task commits, deviations, decisions
- Update STATE.md: 2/3 plans complete, daemon/index.ts at 385 lines (-65%)
2026-02-09 20:15:54 -08:00
William Valentin 37901e3c20 docs(01-01): complete extract-models-memory-tools plan
- SUMMARY.md documenting 3 tasks, 3 commits, 9min duration
- STATE.md updated: plan 1/3 complete, metrics, decisions, technical notes
2026-02-09 20:15:17 -08:00
William Valentin 35a0061de9 feat(01-02): extract channel adapter registration into src/daemon/channels.ts
- Move Telegram, Discord, Slack, WhatsApp, WebChat adapter setup to channels.ts
- Move CronScheduler, WebhookHandler, GmailWatcher registration to channels.ts
- Clean up index.ts imports (remove unused adapter value imports)
- index.ts calls registerChannels() and receives cronScheduler for tool wiring
2026-02-09 20:14:23 -08:00
William Valentin fb1199a1da refactor(01-01): extract tool registration into src/daemon/tools.ts
- Create initTools() factory encapsulating ToolRegistry, allBuiltinTools, web search tools, ProcessManager, BrowserManager, ToolExecutor, and ToolPolicy
- Replace ~70 lines of inline tool setup in startDaemon() with single initTools() call
- Clean up tool-specific imports from daemon/index.ts (ToolPolicy, allBuiltinTools, createWebSearchTools, createProcessTools, ProcessManager, createBrowserTools)
- Tier 1 agent tools (session, agents list, message send, cron) remain in daemon/index.ts as intended
- daemon/index.ts reduced to 457 lines (from 1088 baseline)
2026-02-09 20:12:46 -08:00
William Valentin efceb38cb6 feat(01-02): extract agent config and sandbox setup into src/daemon/agents.ts
- Create initAgents() function encapsulating AgentConfigRegistry, AgentRouter, SandboxManager init
- Replace ~26 lines in startDaemon() with single initAgents() call
- Lifecycle shutdown handler for sandbox cleanup included in agents.ts
- Zero type errors, routing tests pass
2026-02-09 20:11:32 -08:00
William Valentin 00f8f74aac refactor(01-01): extract memory initialization into src/daemon/memory.ts
- Create initMemory() factory encapsulating MemoryStore, VectorStore, HybridSearch, background indexer, and memory tools registration
- Replace ~65 lines of inline memory init in startDaemon() with single initMemory() call
- Clean up memory-specific imports from daemon/index.ts (MemoryStore, VectorStore, HybridSearch, createEmbeddingProvider, chunkText, contentHash, createMemoryTools)
2026-02-09 20:10:49 -08:00
William Valentin 08f5b6b8e7 feat(01-02): extract message routing into src/daemon/routing.ts
- Move createMessageRouter function (~220 lines) to dedicated routing module
- Add import from ./routing.js in daemon/index.ts
- routing.test.ts passes without modification
- Zero type errors
2026-02-09 20:09:28 -08:00
William Valentin 86cda91f6b refactor(01-01): extract model client logic into src/daemon/models.ts
- Move createClientFromConfig, anthropicToGitHubModel, createAutoFallbackClient, createModelRouter to dedicated module
- Add re-exports from daemon/index.ts for backward compatibility
- clientFactory.test.ts passes without modification
- Reduces daemon/index.ts by ~248 lines
2026-02-09 20:06:27 -08:00
William Valentin c0baf3e45e docs(state): update state after phase 1 planning 2026-02-09 20:01:33 -08:00
William Valentin fcbf5866f3 docs(01-daemon-decomposition): create phase plans — 3 plans in 2 waves 2026-02-09 20:01:12 -08:00
William Valentin 0973b4610f docs: create roadmap (3 phases) 2026-02-09 19:53:01 -08:00
William Valentin 1910d1d833 docs: define v1 requirements for DX milestone 2026-02-09 19:50:11 -08:00
William Valentin 8eb0980b71 chore: add project config 2026-02-09 19:43:49 -08:00
William Valentin b19be89510 docs: initialize project 2026-02-09 19:42:39 -08:00
William Valentin d2d64f3361 docs: map existing codebase 2026-02-09 19:31:05 -08:00
William Valentin 85b1401440 docs: update README, CHANGELOG, CLAUDE.md, AGENTS.md for Tier 3-4 features (xAI, Voyage AI, gateway lock, shell completion, tailscale serve, DM pairing, lane queue, credential redaction, usage dashboard) 2026-02-09 18:40:40 -08:00
William Valentin e86653fc14 docs: update state.json and gap analysis scorecard for Tier 4 completion (77% match rate) 2026-02-09 18:30:42 -08:00
William Valentin 1e29da4da2 feat: complete DM pairing codes with channel adapters, gateway handlers, and TUI command (Tier 4 feature 4) 2026-02-09 18:28:10 -08:00
William Valentin 9d4d440ecf feat: add PairingManager and gateway lock tests (Tier 4 feature 4 foundation) 2026-02-09 13:32:59 -08:00
William Valentin 4413c4dc7c feat: add gateway lock, shell completion, and tailscale serve (Tier 4 features 1-3) 2026-02-09 13:29:59 -08:00
William Valentin 9be8f76bc7 feat: implement Tier 3 features — lane queue, credential redaction, token dashboard, xAI, Voyage AI
- Lane Queue: per-session FIFO queue in gateway replacing reject-when-busy (9 tests)
- Credential Redaction: redactConfig() expanded to cover 18+ secret fields (16 tests)
- Web UI Token Dashboard: system.tokenUsage endpoint + Usage page with summary cards
- xAI (Grok) Provider: OpenAI-compatible client with model pricing
- Voyage AI Embeddings: new embedding provider with configurable dimensions (5 tests)
- Update gap analysis: 90→95 match (70%→74%), Tier 3 section marked DONE
- Update state.json: test count 1001→1034, add tier3_completion entry

Total: 1034 tests passing across 85 files, typecheck clean
2026-02-09 10:32:57 -08:00
William Valentin 1d126cddfb feat: add Zhipu AI (GLM) model provider support
Adds zhipuai as a new provider using the OpenAI-compatible API at
api.z.ai. Supports api_key config or ZHIPUAI_API_KEY env var, with
optional endpoint override.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 09:55:13 -08:00
William Valentin ffa63a435e docs: update test count to 1001 2026-02-07 17:45:03 -08:00
William Valentin 6ed8a4a8bf fix: gracefully handle Ollama models without tool support
Check model capabilities via /api/show before sending tools.
Models without 'tools' capability get requests without tools
(they can still answer, just without tool use). Result is cached
per client instance. Defense-in-depth: 'does not support' added
to retry nonRetryablePatterns to avoid wasting retries on
permanent errors.
2026-02-07 17:44:47 -08:00
William Valentin a0f5584220 docs: update CHANGELOG, state.json, and default config for local model tool calling 2026-02-07 17:27:27 -08:00
William Valentin fb20acfbcd feat: add tool calling support to Ollama and llama.cpp clients
- Ollama: pass tools to API, parse tool_calls responses, handle thinking field from reasoning models (deepseek-r1, glm-4.7-flash)
- llama.cpp: pass tools via OpenAI-compatible endpoint, parse tool_calls, accumulate streaming tool call deltas
- Both clients now set stopReason to 'tool_use' when tool calls are present
- Tests: 12 new tests (8 Ollama + 5 llama.cpp, total 983→995)
2026-02-07 17:20:27 -08:00
William Valentin fcbab1e1ee docs: document system.info tool and runtime context in README, CHANGELOG, and gap analysis 2026-02-07 16:27:16 -08:00
William Valentin 8bf88049bf feat: add runtime context awareness — system.info tool + date/time in system prompt
- assembleSystemPrompt() now injects '# Runtime Context' with current date/time
- New system.info tool: date, time, hostname, platform, arch, uptime, memory, Node.js version
- Tool available in all profiles (minimal/messaging/coding/full)
- 983 tests passing (+7 new)
2026-02-07 16:22:17 -08:00
William Valentin 33f6f142bc docs: add file.patch and Gmail Pub/Sub watcher documentation
- README: features list, Gmail config section with field reference and
  template variables, hook examples, architecture tree, CLI description
- CHANGELOG: new Added entries for both features
- SOUL.md: file.patch in capabilities list
- config/default.yaml: file.patch in confirm hooks, commented-out
  automation section with cron, webhooks, gmail, heartbeat examples
2026-02-07 15:45:41 -08:00
William Valentin be3363fdc8 docs: update state.json and gap analysis — file.patch + Gmail (87/116 = 75%) 2026-02-07 15:40:45 -08:00
William Valentin 06438bb44f feat: add Gmail Pub/Sub watcher for inbound email automation
New ChannelAdapter that monitors Gmail via Google Cloud Pub/Sub push
notifications with polling fallback. Supports OAuth2 auth, configurable
watch labels, template rendering with email metadata placeholders
(from, to, subject, snippet, date, id, labels).

Wired into daemon lifecycle and gateway (POST /gmail/push endpoint).
Includes 16 tests covering auth, templates, push notifications, and
channel routing.
2026-02-07 15:39:24 -08:00
William Valentin 131d23989c feat: add file.patch tool for multi-hunk structured patches
Implements apply_patch equivalent: a single tool call can make multiple
line-based edits (replacements, insertions, deletions) across one or more
files. Hunks are applied bottom-up to preserve line numbers.

Includes 10 tests covering replacement, multi-hunk, insertion, deletion,
multi-file, overlapping hunks error, OOB error, and edge cases.
2026-02-07 15:39:15 -08:00
William Valentin c1e2f1e86c Add documentation for agent model delegation fix
Document the solution to OpenCode/Claude Code issue where LLMs
cannot properly delegate to specific model tiers when using subagents.
2026-02-07 15:06:48 -08:00
William Valentin c062f687d2 docs: add state.json update rule to AGENTS.md 2026-02-07 14:55:25 -08:00
William Valentin 308e7f228e docs: update state.json with tier 2 completion stats 2026-02-07 14:53:50 -08:00
William Valentin d0ebbff608 docs: add documentation for Tier 2 features
- README: webhooks, heartbeat, vector memory, Docker sections with config examples
- README: updated features list, architecture tree, environment variables
- CHANGELOG: entries for all 4 Tier 2 features
2026-02-07 14:52:02 -08:00
William Valentin 93c0d64e8d docs: update gap analysis — mark Tier 2 as complete (85/116 = 73%) 2026-02-07 14:46:23 -08:00
William Valentin 88731a50e3 feat: add heartbeat monitor and vector memory search (Tier 2)
Heartbeat:
- HeartbeatMonitor with 5 checks: gateway, model, channels, memory, disk
- Configurable interval, failure threshold, notification channel
- Recovery notifications when health restores
- 25 new tests

Vector Memory Search:
- EmbeddingProvider interface with OpenAI, Gemini, Ollama, LlamaCpp backends
- SQLite-backed VectorStore with cosine similarity search
- Text chunker with paragraph-aware splitting and overlap
- HybridSearch merging keyword + vector results with configurable weight
- Background indexer with dirty-namespace tracking
- Graceful fallback to keyword search when embeddings unavailable
- 51 new tests

Config: automation.heartbeat + memory.embedding schema sections
Total: 950 tests passing, all types clean
2026-02-07 14:45:11 -08:00
William Valentin b50c140d25 feat: add Docker support and inbound webhooks (Tier 2)
- Dockerfile: multi-stage build (node:22-alpine), better-sqlite3 native deps handled
- .dockerignore + docker-compose.yml for deployment
- FLYNN_DATA_DIR env var support in daemon, CLI, and TUI
- WebhookHandler: ChannelAdapter for HTTP POST /webhooks/:name
- Per-webhook HMAC auth, template rendering ({{body}}, {{json.field}})
- Config schema: automation.webhooks array with name/secret/message/output
- Gateway routes webhook requests before static files (bypasses gateway auth)
- 23 new tests for webhook functionality, 874 total tests passing
2026-02-07 14:36:05 -08:00
William Valentin b322e8f29c fix: GitHub Copilot fallback — remove stale API version header and fix model name mapping
Two issues prevented the GitHub Models fallback from working:

1. The X-GitHub-Api-Version: 2022-11-28 header caused '400 invalid
   apiVersion' errors. The Copilot chat completions endpoint does not
   use this header — removed from both constructor and rebuildClient.

2. The anthropicToGitHubModel mapping was incomplete: it only knew
   three models and the generic date-stripping fallback produced wrong
   names (e.g. 'claude-sonnet-4-5' instead of 'claude-sonnet-4.5').
   GitHub Copilot uses dots for sub-versions, not hyphens.

   Updated with explicit mappings for all current models (sonnet 4,
   4.5; opus 4, 4.5, 4.6; haiku 4.5) and a smarter generic fallback
   that converts digit-hyphen-digit to digit.digit at the end.

3. createClientFromConfig now auto-maps Anthropic-style model names
   when the provider is 'github', so users can copy model names from
   their Anthropic config into fallback blocks without manual renaming.
2026-02-07 14:04:54 -08:00
William Valentin e12eb3a0be fix: TUI now uses shared model router with auto-fallback support
The TUI was building its own ModelRouter with a duplicated client factory
that lacked auto same-model fallback, local_providers resolution, retry
config, and per-tier fallback logic. When Anthropic failed, it skipped
GitHub Models and fell straight to the local Ollama model.

Replace the duplicated ~50-line createClient + router setup in tui.ts
with a single call to the daemon's createModelRouter(), which already
handles all of these correctly. This removes ~50 lines of duplicated
code and ensures TUI and daemon have identical fallback behavior.
2026-02-07 13:58:34 -08:00
William Valentin f43d6edfe0 docs: document fallback patterns in default.yaml
Add comments explaining:
- Auto same-model fallback via GitHub Models for Anthropic tiers
- Inline per-tier fallback blocks
- The full fallback order (primary → auto → inline → global chain)
- local_providers map for named providers in fallback_chain
- Usage examples for both patterns
2026-02-07 13:55:38 -08:00
William Valentin 4876bad9ab feat: register web search and process tools in TUI mode
Previously these tools were only available in daemon mode. Now TUI mode
also registers web search tools (when credentials are configured) and
process management tools with proper cleanup on exit.
2026-02-07 13:54:17 -08:00
William Valentin 5984c42bfd feat: auto same-model fallback via GitHub Models when primary Anthropic provider fails
When a tier uses the Anthropic provider and has no user-configured inline
fallback, automatically insert a GitHub Models client for the equivalent
model as a tier fallback. This ensures the same model is tried via an
alternative provider before degrading to the global fallback chain (which
may be a much weaker local model).

Mapping: claude-sonnet-4-20250514 → claude-sonnet-4, etc.
2026-02-07 13:52:53 -08:00
William Valentin d5694649bf docs: update gap analysis for tier 1 implementation (65% → 69%)
Mark 5 features as MATCH: tool groups, session pruning, /think,
/verbose, typing indicators. Update scorecard (80/116 features),
remove completed Tier 1 section from remaining gaps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 13:36:22 -08:00
William Valentin 1c2f54fae3 feat: implement tier 1 quick wins (tool groups, typing, pruning, verbose, think)
Five additive features with no breaking changes:

- Tool groups: group:fs, group:runtime, group:web, group:memory syntactic
  sugar for allow/deny lists in tool policy config
- Typing indicators: Discord sendTyping() and WhatsApp sendStateTyping()
  on message receipt for better UX feedback
- Session pruning: TTL-based auto-cleanup via sessions.ttl config with
  hourly daemon timer and SQLite GROUP BY pruning
- /verbose command: TUI command parser toggle for raw streaming display
- !!think prefix: per-message extended thinking mode wired through
  Anthropic (budget_tokens), OpenAI/GitHub (reasoning_effort), and
  Gemini (thinkingConfig) providers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 13:35:00 -08:00
William Valentin 6bb424cddc feat: add agent tools and sanitize tool names for Anthropic API
Add 8 new agent-callable tools (sessions.list/history/create/delete,
agents.list, message.send, cron.list/trigger) and sanitize tool names
at the API boundary (dots → underscores) to comply with Anthropic's
`^[a-zA-Z0-9_-]{1,128}` requirement. Reverse-maps sanitized names
back to internal names for hook callbacks and tool execution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:23:09 -08:00