Stringwork follows a clean architecture layout. Business logic does not depend on storage, transport, or tool handler details.
cmd/mcp-server (main, CLI)
|
+-- internal/tools/collab (MCP tool handlers: parse args, call app, format response)
| |
+-- internal/dashboard (web UI + REST API)
| |
+-------+-- internal/app (use cases: CollabService, WorkerManager, Watchdog, Orchestrator)
|
internal/domain (entities: Message, Task, Plan, AgentInstance, WorkContext, ...)
^
internal/repository/sqlite (implements StateRepository)
internal/policy (config, workspace validation, safety)
internal/worktree (git worktree manager for worker isolation)
| Package | Role |
|---|---|
| cmd/mcp-server | Entrypoint. Loads config, wires dependencies. Supports three modes: daemon (HTTP on TCP + unix socket, no stdio), proxy (thin stdio-to-HTTP bridge), and standalone (legacy stdio + HTTP in one process). CLI subcommands (status, audit, discover, constitution, --version). |
| internal/domain | Core entities and aggregate state. No external dependencies. Message, Task, Plan, PlanItem, AgentInstance, WorkContext, AuditEntry, FileLock, Presence, CollabState. |
| internal/app | Application services and ports. CollabService (all collaboration operations), WorkerManager (spawn/kill workers, heartbeat monitoring, Gemini GEMINI_SYSTEM_MD generation), TaskOrchestrator (auto-assign tasks to workers), Watchdog (progress monitoring, SLA alerts, DLQ failure tracking), SessionRegistry (multi-client tracking). Defines StateRepository, AuditWriter, AuditReader, and Policy interfaces. |
| internal/repository/sqlite | Implements StateRepository and AuditWriter/AuditReader using SQLite (via modernc.org/sqlite, pure Go). Full load/save of CollabState; separate audit_log table for tool call recording. |
| internal/policy | Config loading from YAML, workspace path validation, state file and log file paths, global defaults. Includes AuditConfig for audit logging settings, and the constitution: block (constitution_config.go + constitution_profile.go) that materialises user- and team-level rule sources into constitution.Source instances. |
| internal/constitution | Layered prompt resolver. Defines Source (DirSource for local dirs, GitSource for shallow-cloned remotes), Resolve for ordered concatenation, BuildPreamble for the MCP-response pointer block, and BuildInline for the spawn-time inlined body. Also: TaskKindFromTitle heuristic and ScopeFilter for task-kind / agent-role narrowing. See CONSTITUTION.md. |
| internal/tools/collab | 24 MCP tool handlers. Each handler parses map[string]any args, calls CollabService, and returns mcp.CallToolResult. Also: audit middleware, piggyback notifications, MCP resource providers, dynamic instructions. |
| internal/dashboard | Web dashboard (embedded HTML) and REST API for viewing tasks, workers, messages, and plans. Served at /dashboard in HTTP mode. |
| internal/worktree | Git worktree manager. Creates isolated checkouts per worker, runs setup commands, cleans up on cancel/exit. |
- MCP client sends
tools/callrequest - Audit middleware records the call (agent, tool, args summary, timing)
- Tool handler in
internal/tools/collabparses arguments - Handler calls
svc.Run(func(state) { ... })onCollabService CollabServicedoesrepo.Load(), mutates state,repo.Save()- Handler formats the result as
mcp.CallToolResult - Piggyback middleware appends notification banners (unread messages, pending tasks, STOP signals)
- Audit middleware writes the entry to the
audit_logtable (synchronous)
- Driver creates a task with
assigned_to='any' TaskOrchestratorassigns it to a worker type based on strategy (least_loaded or capability_match)WorkerManagerspawns the worker process with the configured command (includes constraint compliance rules in spawn prompt; for Gemini, auto-generatesGEMINI_SYSTEM_MD)- Worker connects to MCP server, claims the task (constraints surfaced inline), calls
get_work_contextto check constraints, does work Watchdogmonitors heartbeats and progress reports, escalates if silent, auto-cancels unresponsive workers- Worker completes task and sends findings; process exits
WorkerManagercleans up (worktree, process resources)
If a worker is cancelled or crashes mid-task, WorkerManager captures its recent output and stores it in the task's WorkContext.PreviousOutput. When a replacement worker is spawned, this output is injected into its prompt so no information is lost across restarts.
The watchdog uses task-bound worker instances (e.g. claude-code-task-3) as the authoritative liveness signal for each task, preventing false recoveries when idle instances from previous sessions have stale heartbeats.
All state lives in domain.CollabState. The repository loads and saves the full aggregate on every operation. There is no partial update -- this keeps the model simple and consistent.
type StateRepository interface {
Load() (*domain.CollabState, error)
Save(*domain.CollabState) error
}type Policy interface {
MessageRetentionMax() int
MessageRetentionDays() int
PresenceTTLSeconds() int
StateFile() string
WorkspaceRoot() string
IsToolEnabled(name string) bool
ValidatePath(path string) (string, error)
}The server binary (mcp-stringwork) supports three operational modes:
| Mode | Flag | Transport | Use case |
|---|---|---|---|
| Daemon | --daemon |
HTTP on TCP + unix socket | Background process shared by multiple Cursor windows |
| Proxy | (auto) | Stdio ↔ HTTP bridge | Cursor subprocess that connects to the daemon |
| Standalone | --standalone |
Stdio + HTTP in one process | Legacy single-process mode |
With daemon mode enabled in config, the binary auto-detects the mode:
- If
--daemonflag: run as daemon - If
--standaloneflag: run standalone - If a daemon is already running (unix socket responds): connect as proxy
- If daemon config enabled: start a new daemon, then connect as proxy
- Otherwise: run standalone
The daemon tracks connected proxies via unix socket connection counting. When the last proxy disconnects, a configurable grace period starts. If no new proxy connects within the grace period, the daemon shuts down cleanly.
- Domain: Pure types, no dependencies.
- App: Table-driven tests with real SQLite (temp files). Tests cover service methods, watchdog alerts, worker env, progress monitoring, and pruning.
- Repository: Integration tests with temp SQLite databases.
- Tools/collab: Integration tests using a real
CollabServiceand in-memory state. - Dashboard: HTTP handler tests with
httptest. - Worktree: Git worktree creation/cleanup tests.
Run all tests:
go test ./...
go test ./... -race -cover