Implements Task 6 of the setup wizard:
- orchestrator.ts: runMenu() for interactive configuration loop
- orchestrator.ts: runFirstRunWizard() for new user onboarding
- orchestrator.test.ts: test for menu exit behavior
- setup.ts: registerSetupCommand() and runSetup() handler
- Handles both first-run and existing config scenarios
- Saves YAML config to disk
- Optional daemon startup after first-run
All tests pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement setupChannels function with support for Telegram, Discord, Slack, and WhatsApp.
Includes WebChat gateway configuration and channel choice loop.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ConfigBuilder class to accumulate wizard answers into config objects with YAML
serialization, and renderSummary function to display configuration summary. Includes
9 test cases covering provider setup, channel configuration, and feature flags.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Created a Prompter interface and factory function for interactive CLI prompts:
- ask(): text input with optional default values
- confirm(): yes/no confirmation with default
- choose(): numbered menu selection with fallback
- password(): text input (no echo planned in TUI)
- println(): simple output helper
All 9 tests pass (ask, confirm, choose, password scenarios).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
9 tasks with TDD approach: prompt helpers, config builder, provider/channel
flows, menu sections, orchestrator, CLI wiring, integration tests. ~29 new
tests, 13 new files, 0 new dependencies.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Interactive setup wizard with two entry points: auto-trigger on
first run (no config detected) and explicit `flynn setup` command.
Minimal-first flow for quick start, menu-driven for reconfiguration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Clean up the once('close') listener on the readline Interface when
rl.question() resolves normally. Previously, each prompt loop iteration
accumulated a close listener that was never removed, triggering
MaxListenersExceededWarning after 11 prompts.
- Core counters: messages processed, sessions, queue depth, uptime, active requests, errors
- Model performance table: recent calls with latency, tokens/sec, provider, status
- Event stream: scrollable log with color-coded levels (error/warn/info)
- Active requests: in-flight request table with session, channel, duration
- Channels grid: existing channel status cards preserved
- Dual timer refresh: 3s for metrics/events/requests, 10s for health/channels
- Targeted DOM updates via getElementById for flicker-free fast updates
- Track active requests with startRequest/endRequest around lane queue work
- Increment messagesProcessed on successful agent.process completion
- Record errors and error events on agent.send failures
- Record tool failure events with tool name and error details
- Add MetricsCollector class with counters, model call ring buffer, event ring buffer, and active request tracking
- Add system.metrics, system.events, system.activeRequests RPC handlers
- Add GET /health unauthenticated HTTP endpoint for Docker HEALTHCHECK
- Add totalPending() to LaneQueue for queue depth metrics
- Add 20 tests for MetricsCollector
Replace console.debug/log/warn calls in model router, retry, and daemon
startup with a structured logger that respects a configurable log_level.
Default level is 'info', suppressing verbose fallback debug messages in
the TUI while keeping them available via config when needed.
- Add src/logger.ts with debug/info/warn/error/silent levels
- Wire log_level into config schema (default: 'info')
- Initialize log level in both daemon and TUI startup paths
- Convert all console.debug in router.ts and retry.ts to logger.debug
- Convert console.log/warn in daemon/models.ts to logger.info/warn
- Import resolveOverlayPath from shared.ts
- Add checkOverlayExists check (skip when no FLYNN_ENV, pass/fail for overlay file)
- Insert after checkConfigExists in allChecks array
- All 1087 tests pass, typecheck clean
- Add resolveOverlayPath() that maps FLYNN_ENV to {configDir}/{env}.yaml
- Update loadConfigSafe to pass overlay path through to loadConfig
- All CLI commands using loadConfigSafe() automatically get overlay support
- No FLYNN_ENV = exact same behavior as before (backward compatible)
- Full test suite passes (1087 tests, zero regressions)
- Add deepMerge utility for recursive object merging (arrays replace, not concat)
- Extend loadConfig with optional overlayPath parameter
- Merge happens before env var expansion and Zod validation
- Add 6 deepMerge unit tests and 4 overlay integration tests
- Re-export deepMerge from config/index.ts
- All 1087 existing tests still pass
- 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
- 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