Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .specify/memory/constitution.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ or synchronous interaction.
- Tool outputs MUST be self-describing JSON with enough
context for any consumer to interpret without consulting
the producing tool.
- Inter-agent communication MUST use the swarm mail
- Inter-agent communication MUST use the comms
messaging system, not ad-hoc coordination.

**Rationale**: A swarm of autonomous agents cannot rely on
Expand All @@ -29,8 +29,8 @@ Replicator MUST be independently installable and usable
without any other hero being present. Optional integrations
MUST degrade gracefully.

- The binary MUST deliver core value (hive, swarm mail,
orchestration) when deployed alone with no external
- The binary MUST deliver core value (org, comms,
forge) when deployed alone with no external
services running.
- Dewey integration MUST degrade gracefully: when Dewey
is unavailable, memory tools return structured
Expand Down
Empty file added .uf/replicator/replicator.log
Empty file.
30 changes: 16 additions & 14 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,19 @@ Use in-memory databases for tests (`db.OpenMemory()`).

Tools are registered via the `registry` package and served
over stdio JSON-RPC. Each tool has:
- A name (e.g., `hive_cells`)
- A name (e.g., `org_cells`)
- A description
- A JSON schema for arguments
- An execute function

### Naming Convention: The Hive Metaphor
### Naming Convention

| Concept | Name |
|---------|------|
| Work items | **Hive** |
| Work items | **Org** |
| Individual item | **Cell** |
| Agent coordination | **Swarm** |
| Messaging | **Swarm Mail** |
| Agent coordination | **Forge** |
| Messaging | **Comms** |
| Parallel workers | **Workers** |
| Task orchestrator | **Coordinator** |
| File locks | **Reservations** |
Expand All @@ -55,7 +55,7 @@ core principles:

1. **I. Autonomous Collaboration**: Tools are callable
independently via MCP. Outputs are self-describing JSON.
Inter-agent communication uses swarm mail.
Inter-agent communication uses comms.
2. **II. Composability First**: The binary works standalone.
Dewey integration degrades gracefully. Database schema is
compatible with cyborg-swarm.
Expand Down Expand Up @@ -227,10 +227,10 @@ make install # Install to GOPATH/bin

| Command | Purpose |
|---------|---------|
| `replicator init` | Per-repo setup: creates `.uf/replicator/` with empty `cells.json` |
| `replicator init` | Per-repo setup: creates `.uf/replicator/` with empty `cells.json` + scaffolds agent kit |
| `replicator setup` | Per-machine setup: creates `~/.config/uf/replicator/` + SQLite DB |
| `replicator serve` | Start MCP JSON-RPC server on stdio |
| `replicator cells` | List hive cells (work items) |
| `replicator cells` | List org cells (work items) |
| `replicator doctor` | Check environment health |
| `replicator stats` | Display activity summary |
| `replicator query` | Run preset SQL analytics queries |
Expand All @@ -242,11 +242,12 @@ make install # Install to GOPATH/bin
```
cmd/replicator/ CLI entrypoint (cobra)
internal/
agentkit/ Embedded agent kit (commands, skills, agents)
config/ Configuration
db/ SQLite + migrations (7 tables)
hive/ Cell domain logic (CRUD, epics, sessions, sync)
swarmmail/ Agent messaging + file reservations
swarm/ Orchestration (decompose, spawn, worktree, review, insights)
org/ Cell domain logic (CRUD, epics, sessions, sync)
comms/ Agent messaging + file reservations
forge/ Orchestration (decompose, spawn, worktree, review, insights)
memory/ Dewey proxy + deprecated tool stubs
gitutil/ Git worktree operations (os/exec)
doctor/ Health check engine
Expand All @@ -256,9 +257,9 @@ internal/
ui/ Centralized lipgloss styles + table helpers
tools/
registry/ Tool registration framework
hive/ Hive tool handlers (11 tools)
swarmmail/ Swarm mail tool handlers (10 tools)
swarm/ Swarm tool handlers (24 tools)
org/ Org tool handlers (11 tools)
comms/ Comms tool handlers (10 tools)
forge/ Forge tool handlers (24 tools)
memory/ Memory tool handlers (8 tools)
test/parity/ Shape comparison engine + fixtures
```
Expand All @@ -273,6 +274,7 @@ originally by [Joel Hooks](https://github.com/joelhooks).
- SQLite at `~/.config/uf/replicator/replicator.db` (WAL mode) (001-go-rewrite-phases)
- Go 1.25+ + `charmbracelet/lipgloss v1.1.0`, `charmbracelet/log v1.0.0`, `muesli/termenv v0.16.0`, `charmbracelet/lipgloss/table` (sub-package of lipgloss) (002-charm-ux)
- SQLite via `modernc.org/sqlite` (unchanged) (002-charm-ux)
- Go 1.25+ + cobra (CLI), modernc.org/sqlite (pure Go SQLite), embed (stdlib) (003-rename-terminology)

## Recent Changes
- 001-go-rewrite-phases: Added Go 1.25+ + `cobra` (CLI), `modernc.org/sqlite` (pure Go SQLite), stdlib `encoding/json` (MCP JSON-RPC), stdlib `os/exec` (git operations)
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ Multi-agent coordination for AI coding agents. Single Go binary, zero runtime de
All 5 implementation phases are complete:

- [x] Phase 0: MCP server, SQLite, tool registry
- [x] Phase 1: Hive (11 tools) + Swarm Mail (10 tools)
- [x] Phase 2: Swarm Orchestration (24 tools)
- [x] Phase 1: Org (11 tools) + Comms (10 tools)
- [x] Phase 2: Forge Orchestration (24 tools)
- [x] Phase 3: Memory / Dewey proxy (8 tools)
- [x] Phase 4: CLI (9 commands)
- [x] Phase 5: Parity testing (100% shape match)
Expand Down Expand Up @@ -76,9 +76,9 @@ Replicator exposes 53 tools via the [MCP protocol](https://modelcontextprotocol.

| Category | Tools | Purpose |
|----------|-------|---------|
| **Hive** | 11 | Work item tracking: create, query, update, close, epics, sessions, sync |
| **Swarm Mail** | 10 | Agent messaging: send, inbox, ack, file reservations |
| **Swarm** | 24 | Orchestration: decompose, spawn, worktrees, progress, review, insights |
| **Org** | 11 | Work item tracking: create, query, update, close, epics, sessions, sync |
| **Comms** | 10 | Agent messaging: send, inbox, ack, file reservations |
| **Forge** | 24 | Orchestration: decompose, spawn, worktrees, progress, review, insights |
| **Memory** | 8 | Dewey proxy: store/find learnings, deprecated tool stubs |

See the full [Tool Reference](docs/tools.md) for schemas and examples.
Expand Down Expand Up @@ -127,7 +127,7 @@ flowchart LR
Agent["AI Agent\n(OpenCode, Claude)"]
MCP["MCP Server\n(stdio JSON-RPC)"]
Reg["Tool Registry\n(53 tools)"]
Domain["Domain Logic\n(hive, swarm, mail)"]
Domain["Domain Logic\n(org, forge, comms)"]
DB["SQLite\n(WAL mode)"]
Dewey["Dewey\n(semantic memory)"]
Git["Git\n(worktrees)"]
Expand All @@ -145,11 +145,12 @@ flowchart LR
```
cmd/replicator/ CLI entrypoint (cobra)
internal/
agentkit/ Embedded agent kit (commands, skills, agents)
config/ Configuration (env vars, defaults)
db/ SQLite + migrations (7 tables)
hive/ Cell CRUD, epics, sessions, sync
swarmmail/ Agent messaging, file reservations
swarm/ Decomposition, spawning, worktrees, review, insights
org/ Cell CRUD, epics, sessions, sync
comms/ Agent messaging, file reservations
forge/ Decomposition, spawning, worktrees, review, insights
memory/ Dewey proxy, deprecated tool stubs
gitutil/ Git worktree operations (os/exec)
doctor/ Health check engine
Expand All @@ -159,9 +160,9 @@ internal/
ui/ Centralized lipgloss styles + table helpers
tools/
registry/ Tool registration framework
hive/ Hive tool handlers (11)
swarmmail/ Swarm mail tool handlers (10)
swarm/ Swarm tool handlers (24)
org/ Org tool handlers (11)
comms/ Comms tool handlers (10)
forge/ Forge tool handlers (24)
memory/ Memory tool handlers (8)
test/parity/ Shape comparison engine + fixtures
docs/ Generated tool reference
Expand Down
6 changes: 3 additions & 3 deletions cmd/replicator/cells.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

"github.com/unbound-force/replicator/internal/config"
"github.com/unbound-force/replicator/internal/db"
"github.com/unbound-force/replicator/internal/hive"
"github.com/unbound-force/replicator/internal/org"
)

// jsonOutput controls whether cells are printed as JSON or a styled table.
Expand All @@ -22,7 +22,7 @@ func listCells(cfg *config.Config) error {
}
defer store.Close()

cells, err := hive.QueryCells(store, hive.CellQuery{})
cells, err := org.QueryCells(store, org.CellQuery{})
if err != nil {
return fmt.Errorf("query cells: %w", err)
}
Expand All @@ -36,5 +36,5 @@ func listCells(cfg *config.Config) error {
return nil
}

return hive.FormatCells(cells, os.Stdout)
return org.FormatCells(cells, os.Stdout)
}
20 changes: 10 additions & 10 deletions cmd/replicator/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import (
"github.com/spf13/cobra"
"github.com/unbound-force/replicator/internal/db"
"github.com/unbound-force/replicator/internal/memory"
"github.com/unbound-force/replicator/internal/tools/hive"
commstools "github.com/unbound-force/replicator/internal/tools/comms"
forgetools "github.com/unbound-force/replicator/internal/tools/forge"
memorytools "github.com/unbound-force/replicator/internal/tools/memory"
"github.com/unbound-force/replicator/internal/tools/org"
"github.com/unbound-force/replicator/internal/tools/registry"
swarmtools "github.com/unbound-force/replicator/internal/tools/swarm"
swarmmailtools "github.com/unbound-force/replicator/internal/tools/swarmmail"
)

func docsCmd() *cobra.Command {
Expand All @@ -26,7 +26,7 @@ func docsCmd() *cobra.Command {
Long: `Generates a markdown document listing all registered MCP tools
with their names, descriptions, and argument schemas.

Output is grouped by category: Hive, Swarm Mail, Swarm, Memory.`,
Output is grouped by category: Org, Comms, Forge, Memory.`,
RunE: func(cmd *cobra.Command, args []string) error {
return runDocs(outputFlag)
},
Expand All @@ -45,9 +45,9 @@ func runDocs(outputPath string) error {
defer store.Close()

reg := registry.New()
hive.Register(reg, store)
swarmmailtools.Register(reg, store)
swarmtools.Register(reg, store)
org.Register(reg, store)
commstools.Register(reg, store)
forgetools.Register(reg, store)
memClient := memory.NewClient("http://localhost:3333/mcp/")
memorytools.Register(reg, memClient)

Expand All @@ -69,9 +69,9 @@ var categories = []struct {
prefix string
name string
}{
{"hive_", "Hive"},
{"swarmmail_", "Swarm Mail"},
{"swarm_", "Swarm"},
{"org_", "Org"},
{"comms_", "Comms"},
{"forge_", "Forge"},
{"hivemind_", "Memory"},
}

Expand Down
14 changes: 7 additions & 7 deletions cmd/replicator/docs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import (

"github.com/unbound-force/replicator/internal/db"
"github.com/unbound-force/replicator/internal/memory"
"github.com/unbound-force/replicator/internal/tools/hive"
commstools "github.com/unbound-force/replicator/internal/tools/comms"
forgetools "github.com/unbound-force/replicator/internal/tools/forge"
memorytools "github.com/unbound-force/replicator/internal/tools/memory"
"github.com/unbound-force/replicator/internal/tools/org"
"github.com/unbound-force/replicator/internal/tools/registry"
swarmtools "github.com/unbound-force/replicator/internal/tools/swarm"
swarmmailtools "github.com/unbound-force/replicator/internal/tools/swarmmail"
)

func buildFullRegistry(t *testing.T) *registry.Registry {
Expand All @@ -23,9 +23,9 @@ func buildFullRegistry(t *testing.T) *registry.Registry {
t.Cleanup(func() { store.Close() })

reg := registry.New()
hive.Register(reg, store)
swarmmailtools.Register(reg, store)
swarmtools.Register(reg, store)
org.Register(reg, store)
commstools.Register(reg, store)
forgetools.Register(reg, store)
memClient := memory.NewClient("http://localhost:3333/mcp/")
memorytools.Register(reg, memClient)
return reg
Expand Down Expand Up @@ -56,7 +56,7 @@ func TestWriteDocs_HasCategoryHeaders(t *testing.T) {
writeDocs(&buf, reg)
output := buf.String()

for _, header := range []string{"## Hive", "## Swarm Mail", "## Swarm", "## Memory"} {
for _, header := range []string{"## Org", "## Comms", "## Forge", "## Memory"} {
if !strings.Contains(output, header) {
t.Errorf("missing category header: %q", header)
}
Expand Down
67 changes: 46 additions & 21 deletions cmd/replicator/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,75 @@ import (
"path/filepath"

"github.com/spf13/cobra"
"github.com/unbound-force/replicator/internal/agentkit"
"github.com/unbound-force/replicator/internal/ui"
)

func initCmd() *cobra.Command {
var pathFlag string
var forceFlag bool
cmd := &cobra.Command{
Use: "init",
Short: "Initialize a project directory for swarm operations",
Long: `Creates a .uf/replicator/ directory with an empty cells.json in the target
directory. Idempotent — safe to run multiple times.
Short: "Initialize a project directory for project operations",
Long: `Creates a .uf/replicator/ directory with an empty cells.json and scaffolds
the agent kit into .opencode/ (commands, skills, and agent definitions).

Idempotent — safe to run multiple times. Existing agent kit files are
skipped unless --force is used.

This is the per-repo initialization command. It does not require the
global database (replicator setup) or any external services.`,
RunE: func(cmd *cobra.Command, args []string) error {
return runInit(pathFlag)
return runInit(pathFlag, forceFlag)
},
}
cmd.Flags().StringVar(&pathFlag, "path", ".", "Target directory for .uf/replicator/ initialization")
cmd.Flags().StringVar(&pathFlag, "path", ".", "Target directory for initialization")
cmd.Flags().BoolVar(&forceFlag, "force", false, "Overwrite existing agent kit files")
return cmd
}

// runInit creates the .uf/replicator/ directory and seeds cells.json.
// Uses styled output: green for success, dim for already-initialized.
func runInit(targetDir string) error {
// runInit creates the .uf/replicator/ directory, seeds cells.json, and
// scaffolds the agent kit into .opencode/. Uses styled output: green for
// created, dim for skipped, yellow for overwritten.
func runInit(targetDir string, force bool) error {
styles := ui.NewStyles(os.Stdout)
hiveDir := filepath.Join(targetDir, ".uf", "replicator")
replicatorDir := filepath.Join(targetDir, ".uf", "replicator")

// Create .uf/replicator/ directory (idempotent).
cellsPath := filepath.Join(replicatorDir, "cells.json")
if _, err := os.Stat(cellsPath); err != nil {
// cells.json doesn't exist — create directory and file.
if err := os.MkdirAll(replicatorDir, 0o755); err != nil {
return fmt.Errorf("create .uf/replicator directory: %w", err)
}
if err := os.WriteFile(cellsPath, []byte("[]\n"), 0o644); err != nil {
return fmt.Errorf("write cells.json: %w", err)
}
fmt.Println(styles.Pass.Render("created .uf/replicator/cells.json"))
} else {
fmt.Println(styles.Dim.Render("skipped .uf/replicator/cells.json (exists)"))
}

// Check if already initialized.
if info, err := os.Stat(hiveDir); err == nil && info.IsDir() {
fmt.Println(styles.Dim.Render("already initialized"))
return nil
// Scaffold agent kit into .opencode/.
if force {
fmt.Println(styles.Warn.Render("--force: existing agent kit files will be overwritten"))
}

// Create .uf/replicator/ directory.
if err := os.MkdirAll(hiveDir, 0o755); err != nil {
return fmt.Errorf("create .uf/replicator directory: %w", err)
results, err := agentkit.Scaffold(targetDir, force)
if err != nil {
return fmt.Errorf("scaffold agent kit: %w", err)
}

// Write empty cells.json.
cellsPath := filepath.Join(hiveDir, "cells.json")
if err := os.WriteFile(cellsPath, []byte("[]\n"), 0o644); err != nil {
return fmt.Errorf("write cells.json: %w", err)
for _, r := range results {
switch r.Action {
case "created":
fmt.Println(styles.Pass.Render(fmt.Sprintf("created .opencode/%s", r.Path)))
case "skipped":
fmt.Println(styles.Dim.Render(fmt.Sprintf("skipped .opencode/%s (exists)", r.Path)))
case "overwritten":
fmt.Println(styles.Warn.Render(fmt.Sprintf("overwritten .opencode/%s", r.Path)))
}
}

fmt.Println(styles.Pass.Render("initialized .uf/replicator/"))
return nil
}
Loading
Loading