Commit Graph

52 Commits

Author SHA1 Message Date
Carlos Florêncio 93251b48ce feat: mcp servers + executors (#60)
* feat: mcp servers

* feat: mcp executors

* feat: mcp per agent profile

* feat: improve side bar

* feat: add reactive executors crud
2026-01-21 01:13:20 +00:00
Carlos Florêncio 7a1bb89fa9 feat: improve repository list setting (#65) 2026-01-21 00:42:49 +00:00
Carlos Florêncio 011009109c feat: custom branch prefix (#58)
* feat: custom branch prefix

* feat: improve ui
2026-01-20 23:15:08 +00:00
Carlos Florêncio 8b8f8ff20b feat: refactor main, add providers (#46)
* feat: add providers

* feat: further refactor internal packages
2026-01-19 21:26:29 +00:00
Carlos Florêncio e25913c697 feat: refactor sqlite usage (#44) 2026-01-19 20:00:20 +00:00
Carlos Florêncio 16b3fb5b92 feat: improve chat UX (#38) 2026-01-18 17:26:41 +00:00
João Salavisa 18f4b4e6fb Cleanup deprecated code and fix session recovery (#37) 2026-01-18 15:58:56 +00:00
João Salavisa 6e98665fd1 fix: improve session terminal and git status handling (#34) 2026-01-18 02:44:30 +00:00
Carlos Florêncio edd093c108 feat: start agents on boot 2026-01-18 00:06:35 +00:00
João Salavisa dd68da4275 refactor: unify permission requests into agent event stream (#31) 2026-01-17 22:21:10 +00:00
Carlos Florêncio fb042e4c59 feat: session refactor (#30) 2026-01-17 19:02:22 +00:00
João Salavisa 2e108b040f refactor: session resumption cleanup and AgentInstance → AgentExecution rename (#23)
* feat: session resumption with ACP session ID support

- Add useSessionResumption hook for automatic session recovery on page reload
- Fix ACPSessionID not being set on AgentInstance in Launch() and createInstance()
- Add task.session.status and task.session.resume WebSocket actions
- Fix shell terminal retry logic for resumed sessions
- Fix taskSessionState reading from Zustand store instead of local state
- Remove dead code: unused stream handling functions in lifecycle/manager.go
- Fix test mock interfaces (CleanupStaleInstanceByTaskID, NewManager signature)
- Add enhanced logging for session resumption debugging
- Simplify page-client.tsx state merging logic

* refactor: remove unused AgentController (dead code)

- Delete agent_controller.go - entirely unused duplicate of Manager methods
- Remove agentController field from Manager struct
- Remove AgentController initialization in NewManager

The AgentController duplicated StartAgentProcess, initializeACPSession, and
PromptAgent from Manager but was never called. All agent control operations
go through Manager's own methods.

* refactor: remove unused MemoryRepository (dead code)

- Delete memory.go - entire MemoryRepository implementation unused
  (replaced by SQLite repository)
- Delete memory_test.go - tests for removed MemoryRepository

Found via 'deadcode' tool analysis.

* refactor: consolidate agentctl packages into server/client structure

Reorganize the confusing dual agentctl packages:
- internal/agentctl/* → internal/agentctl/server/
- internal/agent/agentctl/* → internal/agentctl/client/

Structure is now:
  internal/agentctl/
  ├── client/      - HTTP client for talking to agentctl servers
  │   ├── client.go
  │   ├── standalone.go
  │   ├── acp.go
  │   └── launcher/
  ├── server/      - agentctl server implementation (runs in containers)
  │   ├── api/
  │   ├── adapter/
  │   ├── acp/
  │   ├── config/
  │   ├── instance/
  │   ├── process/
  │   └── shell/
  └── types/       - Shared types used by both client and server

Also consolidated shared types (GitStatusUpdate, FileInfo, etc.) from
process/types.go into the shared types/ package.

* refactor: rename AgentInstance to AgentExecution for clarity

Rename AgentInstance -> AgentExecution across the entire codebase to better
reflect what it represents: an agent actively working on a task, not just
a generic 'instance'.

Changes:
- AgentInstance struct -> AgentExecution
- InstanceStore -> ExecutionStore (new file: execution_store.go)
- RecoveredInstance -> RecoveredExecution
- All method names: GetInstance* -> GetExecution*, ListInstances -> ListExecutions, etc.
- All parameters: instanceID -> executionID
- All local variables: instance -> execution
- DTOs and JSON tags: agent_instance_id -> agent_execution_id
- Database columns: agent_instance_id -> agent_execution_id

Also consolidates duplicate prompt logic:
- Merge sendInitialPrompt and SendPrompt into single SendPrompt method
- Add validateStatus parameter to differentiate initial vs follow-up prompts

Also extracts ACP session management to session.go:
- Move initializeACPSession logic to SessionManager.InitializeAndPrompt
- Move PromptAgent logic to SessionManager.SendPrompt
- Manager now delegates to SessionManager for all prompt operations

Also removes duplicate event publishing:
- Remove 9 duplicate m.publish*() methods from manager.go
- Use existing EventPublisher methods via m.eventPublisher.Publish*()

Also extracts types to dedicated file:
- Move AgentExecution, LaunchRequest, PromptResult, etc. to types.go

Net reduction: ~600 lines removed from manager.go through deduplication
and better separation of concerns.

* fix(backend): Docker runtime now creates instance via ControlServer

The Docker runtime was incorrectly creating an agentctl.Client pointing
directly to port 9999 (the ControlServer port), then trying to call
instance-specific APIs like /api/v1/agent/configure which only exist
on per-instance servers.

Fixed by making Docker runtime follow the same flow as standalone mode:
- LaunchContainer now uses StandaloneCtl to create an instance via the
  control API, then creates Client pointing to the instance port
- RecoverInstances queries the ControlServer to get the instance port
- Added waitForHealth helper to wait for agentctl to be ready

Also improved HTTP error handling in agentctl client:
- All client methods now check HTTP status codes before JSON decoding
- Better error messages include status code and response body

* fix: restore session resumption imports and variables

* fix: add sessionId prop back to TaskLayout
2026-01-16 22:14:19 +00:00
Carlos Florêncio 5085169696 feat: improved chat experience (#22) 2026-01-16 17:42:32 +00:00
Carlos Florêncio 2b38197b31 feat: improve onboarding and task setup (#21) 2026-01-16 15:51:26 +00:00
Carlos Florêncio 41bad65020 feat: task_session_worktrees 2026-01-16 01:59:00 +00:00
Carlos Florêncio 4560901d35 feat: flaky resume sessions 2026-01-15 23:40:20 +00:00
Carlos Florêncio 712610e428 feat: rename agent_sessions to task_sessions 2026-01-15 20:31:39 +00:00
Carlos Florêncio e1bce95bac feat: golang linter 2026-01-15 19:05:16 +00:00
Carlos Florêncio 7d0905b8cb feat: tasks refactor 2026-01-15 18:25:42 +00:00
Carlos Florêncio 004fb20618 feat: chat improved renderer and comments pagination 2026-01-15 02:23:09 +00:00
João Salavisa 7e90883a30 chore: Remove dead code and consolidate agentctl modes (#17) 2026-01-15 00:01:13 +00:00
João Salavisa af7fb84a53 fix: address code review issues (#16) 2026-01-14 23:12:12 +00:00
Carlos Florêncio e965524590 feat: task comments SSR fetch 2026-01-14 20:52:22 +00:00
João Salavisa 85ecf7debb feat(agentctl): protocol adapter abstraction with agent profile support (#15)
* feat(agentctl): implement protocol adapter abstraction

- Add AgentAdapter interface for protocol-agnostic agent communication
- Create ACPAdapter implementation for ACP protocol (JSON-RPC over stdin/stdout)
- Add Protocol field to agent registry (AgentTypeConfig)
- Update process.Manager to use adapters instead of hardcoded ACP
- Update API layer to use adapter interface
- Pass protocol from registry to agentctl via CLI flag and env var
- Support protocol configuration in both Docker and standalone modes

This refactoring allows agentctl to support multiple protocols (ACP, REST, MCP)
via a pluggable adapter pattern. The backend remains protocol-agnostic,
always communicating with agentctl's HTTP API.

* refactor(agentctl): consolidate types and clean up code

- Create shared types package (internal/agentctl/types) for permission types
- Create shared protocol package (pkg/agent) for Protocol type
- Remove duplicate permission types from acp/client.go and adapter.go
- Make adapter the single source of truth for session ID
- Remove unused Command field from adapter.Config
- Remove passthrough wrapper function handleAdapterPermissionRequest
- Clean up extra empty lines in process/manager.go and acp_adapter.go
- Re-export permission types from adapter package for convenience

* fix(agent-session): rename AgentType to AgentProfileID for consistency

- Rename AgentSession.AgentType to AgentProfileID in models
- Update agent_sessions table schema column from agent_type to agent_profile_id
- Update all SQL queries in sqlite.go to use agent_profile_id
- Fix ToAPI() method to return agent_profile_id key
- Remove misleading comments in executor.go

Also adds comprehensive tests for affected areas:
- adapter package unit tests (SessionUpdate, PlanEntry, AgentInfo, Config)
- profile resolver unit tests with mock repository
- AgentSession CRUD tests in sqlite_test.go
2026-01-14 18:16:26 +00:00
João Salavisa 82e8c8905b feat: replace agent_type with agent_profile_id (#14)
* feat: replace agent_type with agent_profile_id

- Replace agent_type field with agent_profile_id across backend and frontend
- Add ProfileResolver interface and StoreProfileResolver implementation
- Update task creation/update to use agent_profile_id
- Change default agent runtime from docker to standalone
- Fix workspace state types to include all required fields
- Fix websocket handlers type mismatches for environments, executors, workspaces
- Update integration tests to use agent_profile_id

* feat: pass model as CLI argument to agents

- Add ModelFlag field to AgentTypeConfig for specifying the CLI flag
- Set ModelFlag to '--model' for all agents (auggie, claude, codex, gemini, opencode, copilot)
- Update launchStandalone to append model flag to agent command
- Update launchDocker/buildContainerConfig to append model flag to container command
- Model is passed when both agent supports ModelFlag and profile has Model configured

* fix: make WebSocket message handling async to prevent blocking

When a long-running handler like orchestrator.prompt was executing,
it blocked the ReadPump loop, preventing other requests (like
workspace.tree.get) from being processed until the handler completed.

Now each message is handled in its own goroutine, allowing concurrent
message handling so file tree requests work while the agent is working.

* feat: show task description as first message in chat

- Add 'Task' label with distinct styling (lighter background, border)
- Pass taskDescription from page to TaskChatPanel component
- Differentiate from regular user messages visually
2026-01-14 12:29:58 +00:00
Carlos Florêncio 9e04b75ddf feat: data fetching refactor ssr -> ws updates 2026-01-14 01:42:12 +00:00
Carlos Florêncio 6c50fef6fa feat: add defaults to workspace: env, executor, agent 2026-01-13 23:37:46 +00:00
Carlos Florêncio aed307d9b8 feat: simplify task creation 2026-01-13 22:41:52 +00:00
Carlos Florêncio aebcf5283f feat: display settings in kanban page 2026-01-13 22:37:36 +00:00
Carlos Florêncio f2aea364af feat: environments and executors 2026-01-13 00:28:25 +00:00
João Salavisa a1013342a3 feat: Real-time Git Status Integration (#8)
* feat: implement real-time git status integration

- Add workspace tracker to monitor git changes every 2 seconds
- Implement WebSocket streaming for git status updates
- Add database persistence for git status in agent session metadata
- Compute diffs backend-side with additions/deletions per file
- Integrate git status into frontend UI (top bar, files panel, changes panel)
- Display real-time ahead/behind commits and line changes
- Show file diffs with syntax highlighting in task view
- Add retry logic for WebSocket connections during reconciliation
- Fix context lifecycle issue in workspace tracker

* refactor: remove debug and unnecessary logging

- Remove debug logs from workspace tracker
- Remove info logs from WebSocket handlers
- Remove verbose git status update logs
- Keep only essential error logs

* fix: compare git diff against remote branch instead of HEAD

- Changed git diff comparison from HEAD to remote tracking branch
- Now shows all changes including committed files that haven't been pushed
- Files committed locally but not pushed will appear in the diff
- Falls back to HEAD if no remote branch is configured

* fix: prevent stale git status when switching tasks

- Clear git status when switching to a new task
- Only accept git.status WebSocket updates for the current task
- Prevents showing git data from previous task when switching

* refactor: remove unused diff stream client code

- Remove diffConn field from agentctl Client struct
- Remove StreamDiff() method (never called)
- Remove CloseDiffStream() method
- Remove DiffUpdate type from client.go
- All diff data is already included in GitStatusUpdate.Files
- Keep server-side diff endpoint in agentctl for potential future use

* refactor: remove unused diff stream server-side code

- Remove /workspace/diff/stream endpoint from agentctl API
- Remove handleDiffStreamWS handler
- Remove DiffUpdate type from workspace_tracker.go
- Remove DiffSubscriber type
- Remove updateDiff() and getDiff() methods
- Remove SubscribeDiff(), UnsubscribeDiff() methods
- Remove notifyDiffSubscribers() method
- Remove GetCurrentDiff() method
- Remove currentDiff field and diffSubscribers map
- All diff data is already included in GitStatusUpdate.Files

* refactor: remove unused output stream code

- Remove /output and /output/stream endpoints from agentctl API
- Remove handleGetOutput and handleOutputStreamWS handlers
- Delete output.go file entirely
- Remove OutputBuffer and related code (buffer.go deleted)
- Remove outputConn field from agentctl Client
- Remove StreamOutput() and CloseOutputStream() methods
- Remove OutputLine type from client.go
- Remove OutputBufferSize config option
- Update readStderr to just log instead of buffering

Output data flows through ACP stream (StreamUpdates) which includes
all session notifications. The separate output stream was never used.
2026-01-12 23:44:29 +00:00
jcfs c2d08271c9 fix: reconnect to agent streams after backend restart
- Add reconnectStreams() to reconnect WebSocket streams for recovered agents
- Reconnect updates stream (for agent responses)
- Reconnect permissions stream (for permission requests)
- Mark recovered agents as READY so they can accept prompts
- Fix worktree cleanup order: clean files before DB cascade deletes records
2026-01-12 17:14:17 +00:00
jcfs 3961afc29e feat: cleanup worktree and branch on task deletion
- Add WorktreeCleanup interface to task service
- Call OnTaskDeleted when a task is deleted to remove worktree dir and branch
- Wire worktree manager to task service in main.go

This ensures that when tasks are deleted, their associated worktrees
and git branches (kandev/{task_id}) are properly cleaned up.
2026-01-12 15:56:09 +00:00
jcfs 19ea7ddc4e feat: expose worktree path and branch in task API and UI
- Add WorktreePath and WorktreeBranch fields to TaskDTO
- Add WorktreeLookup interface to TaskController for enriching task responses
- Add GetWorktreeInfo method to worktree.Manager implementing WorktreeLookup
- Wire worktree manager to task controller in main.go
- Add worktree_path and worktree_branch to frontend Task type
- Display worktree path with copy button in TaskTopBar when worktree exists
- Show worktree branch in tooltip for easy reference
2026-01-12 15:19:11 +00:00
jcfs e012e070a9 fix: recover agent state from Docker on backend restart
- Add Docker reconciliation on lifecycle manager startup to find running containers
- Add container_id field to agent_sessions table for cleanup tracking
- Add GetRecoveredInstances to AgentManagerClient interface
- Sync executor cache with recovered Docker instances on startup
- Add task.execution WebSocket endpoint to check agent running state
- Fix Stop Agent button showing Start Agent after page refresh
- Ensure containers are not leaked when backend restarts
2026-01-12 03:42:54 +00:00
jcfs 7b3e94d6dc feat(backend): add persistent agent session tracking
- Add AgentSession database entity with SQLite persistence
- Implement AgentSession CRUD operations in repository layer
- Update executor to use hybrid cache + database approach
- Add session restoration on startup (LoadActiveSessionsFromDB)
- Link comments to agent sessions via agent_session_id
- Fix SQLite NULL handling for nullable task fields
- Add dev database setup with seed data (make dev, make dev-db-reset)
- Update Makefile with dev targets for development mode

This enables agent sessions to persist across backend restarts,
solving the 'execution not found' error for resumed conversations.
2026-01-12 02:02:47 +00:00
jcfs 0b8cd401c2 refactor: unify WebSocket patterns to Pattern A (handlers + controller + dto)
- Add missing repository action constants to pkg/websocket/actions.go
- Update repository_handlers.go to use action constants instead of string literals
- Refactor orchestrator module: create dto/, controller/, handlers/ packages
- Refactor agent module: create dto/, controller/, handlers/ packages
- Update main.go and integration tests to use new Pattern A wiring
- Remove old wshandlers/ directories from both modules

All modules now follow the same architecture:
  handlers/    → Parse WS messages, validate, call controller
  controller/  → Business logic coordination, convert to/from DTOs
  dto/         → Centralized request/response Data Transfer Objects
  service/     → Core business logic (unchanged)
2026-01-11 22:51:43 +00:00
Carlos Florêncio 4282d67910 fix: go tests 2026-01-11 22:44:10 +00:00
Carlos Florêncio a9047cf823 feat: tasks crud 2026-01-11 22:32:04 +00:00
jcfs 15cf60edb9 merge: resolve conflicts with main
- Keep both RegisterRepositoryRoutes and RegisterCommentRoutes
- Merge permission actions with repository actions in websocket/actions.go
2026-01-11 22:12:16 +00:00
jcfs 195be5e575 feat: enhance comment system and e2e testing
- Add comment handlers for WebSocket API (comment.add, comment.list)
- Update e2e-test.sh to focus on comment system testing
- Test multi-turn conversation flow (3 turns)
- Display comment content and metadata in test output
- Reduce test timeouts for faster execution
- Fix various orchestrator and lifecycle manager issues
- Add CODE_REVIEW_ISSUES.md documenting known issues
2026-01-11 22:08:00 +00:00
Carlos Florêncio 473b336b13 feat: added repositories support 2026-01-11 19:59:28 +00:00
jcfs 0fdf18c37b feat: add bidirectional comment system and agent input request flow
- Add Comment model and CRUD operations (repository, service layers)
- Add WAITING_FOR_INPUT task state for agent input requests
- Add WebSocket actions for comment.add, comment.get, comment.list
- Add ActionCommentAdded and ActionInputRequested notifications
- Update PromptAgent to return PromptResult with stop reason
- Add e2e test for agent input request flow
- Add PR template for the repository

This enables agents to request input from users by returning
stopReason 'needs_input' which transitions the task to
WAITING_FOR_INPUT state and creates an agent comment.
2026-01-11 18:41:52 +00:00
Carlos Florêncio 47a26fcc0e feat: web app support for boards and columns 2026-01-11 18:30:02 +00:00
Carlos Florêncio af6e482c4c feat: web app support for workspaces 2026-01-11 16:28:25 +00:00
Carlos Florêncio 609fd4e16d fix: workspace migration 2026-01-11 14:51:01 +00:00
Carlos Florêncio 8579e8ec91 feat: added workspaces 2026-01-11 14:46:01 +00:00
Carlos Florêncio 6753bfa397 feat: add http handlers to backend 2026-01-11 12:33:10 +00:00
jcfs 6a46eb5a54 feat: implement persistent agent execution logs storage and retrieval
- Add task_agent_execution_logs table schema in SQLite with indexes
- Create SQLiteMessageStore implementing MessageStore interface for persistent ACP message storage
- Add task.logs WebSocket action for retrieving historical logs
- Implement historical log replay on task.subscribe
- Add HistoricalLogsProvider callback to WebSocket Hub

Tests:
- Add comprehensive unit tests for SQLiteMessageStore (29 tests)
- Add integration tests for task.logs and historical replay (3 test suites)
- Enhance e2e-test.sh with historical logs test scenarios (Steps 14-16)

Files:
- apps/backend/internal/orchestrator/acp/sqlite_store.go (new)
- apps/backend/internal/orchestrator/acp/sqlite_store_test.go (new)
- apps/backend/internal/task/repository/sqlite.go (schema)
- apps/backend/internal/gateway/websocket/hub.go (provider)
- apps/backend/internal/gateway/websocket/client.go (replay)
- apps/backend/internal/orchestrator/wshandlers/handlers.go (task.logs)
- apps/backend/cmd/kandev/main.go (wiring)
- scripts/e2e-test.sh (test scenarios)
2026-01-11 01:24:54 +00:00
jcfs 4d0efdc3ed chore: Clean up unused code and placeholder directories
Remove obsolete REST API code and empty placeholder directories:

Removed REST API code:
- apps/backend/internal/agent/api/ (REST handlers)
- apps/backend/internal/orchestrator/api/ (REST handlers)
- apps/backend/internal/orchestrator/streaming/ (REST streaming)
- apps/backend/internal/task/api/ (REST handlers)

Removed obsolete cmd binaries:
- apps/backend/cmd/agent-manager/
- apps/backend/cmd/orchestrator/
- apps/backend/cmd/api-gateway/
- apps/backend/cmd/task-service/
- apps/backend/cmd/agentctl/

Removed empty placeholder directories:
- apps/backend/internal/agent/models/
- apps/backend/internal/agent/monitor/
- apps/backend/internal/common/acp/
- apps/backend/internal/common/auth/
- apps/backend/internal/events/publisher/
- apps/backend/internal/events/subscriber/
- apps/backend/internal/gateway/handlers/
- apps/backend/internal/gateway/middleware/
- apps/backend/internal/gateway/router/
- apps/backend/internal/gateway/streaming/
- apps/backend/pkg/acp/client/
- apps/backend/pkg/acp/server/
- deployments/docker/agents/
- deployments/docker/compose/
- migrations/postgres/
- apps/agentctl/

Fixed:
- Added missing PromptAgent method to mock in scheduler_test.go

All tests pass, build succeeds.
2026-01-10 23:33:38 +00:00