fellow-agents 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,76 +1,132 @@
1
1
  # fellow-agents
2
2
 
3
- Multiple Claude Code agents collaborating via messaging.
3
+ **Run a team of Claude Code agents that talk to each other.**
4
4
 
5
- ## Quick Start
5
+ One command gives you a coordinator, a coder, and a reviewer — each in their own terminal, communicating through async messaging, managed from a single browser UI.
6
6
 
7
7
  ```bash
8
8
  npm install -g fellow-agents
9
- fellow-agents start
9
+ mkdir my-team && cd my-team
10
+ fellow-agents
10
11
  ```
11
12
 
12
- Downloads binaries on first run, starts services, opens browser. No git clone needed.
13
+ That's it. Creates a workspace, downloads what it needs, opens your browser three agents ready to collaborate.
13
14
 
14
- ### Options
15
+ ---
15
16
 
16
- ```bash
17
- fellow-agents start --port 3700 --emcom-port 8800 # custom ports
18
- fellow-agents start --no-browser # headless
19
- fellow-agents start --update # force re-download binaries
20
- fellow-agents stop # stop all services
17
+ ## What happens when you run it
18
+
19
+ 1. Downloads platform binaries (first run only, ~30 seconds)
20
+ 2. Starts the messaging server (emcom)
21
+ 3. Registers three agents: **coordinator**, **coder**, **reviewer**
22
+ 4. Launches the browser UI (pty-win) on `http://localhost:3700`
23
+
24
+ Each agent is a Claude Code session with its own workspace, personality, and tools. They message each other through emcom — no shared context window, no token limits, real async collaboration.
25
+
26
+ ## Try it
27
+
28
+ 1. Click **coordinator** in the browser UI (hit play)
29
+ 2. Tell it: *"Have the coder write a fibonacci function and the reviewer check it for edge cases."*
30
+ 3. Watch the agents coordinate — messages flow in the feed panel on the right
31
+
32
+ The coordinator breaks down the task, sends it to the coder via emcom, the coder writes the code and sends it to the reviewer, the reviewer sends feedback back. All visible in real time.
33
+
34
+ ## How it works
35
+
36
+ ```
37
+ fellow-agents start
38
+ |
39
+ v
40
+ +-----------+ emcom messages +-----------+
41
+ | coordinator| <------------------> | coder |
42
+ +-----------+ +-----------+
43
+ ^ |
44
+ | emcom messages |
45
+ +---------------------------------- +
46
+ | v
47
+ +-----------+ +-----------+
48
+ | pty-win | browser UI on :3700 | reviewer |
49
+ +-----------+ +-----------+
50
+ |
51
+ emcom-server on :8800
21
52
  ```
22
53
 
54
+ **pty-win** is the browser-based terminal multiplexer — every agent session in one tab. **emcom** is the messaging layer — agents send, receive, and reply to each other asynchronously. Each agent has a `CLAUDE.md` defining its role and an `identity.json` for messaging.
55
+
23
56
  ## Prerequisites
24
57
 
25
- - [Node.js](https://nodejs.org/) 18+
26
- - [Claude Code](https://claude.ai/code) (optional for setup, required to run agents)
58
+ - **Node.js 18+** — [nodejs.org](https://nodejs.org/)
59
+ - **Claude Code** — [claude.ai/code](https://claude.ai/code) (needed to run agent sessions)
27
60
 
28
- ## Alternative: Git Clone
61
+ ## Options
29
62
 
30
63
  ```bash
31
- git clone https://github.com/rajan-chari/fellow-agents.git
32
- cd fellow-agents
33
- ./setup.sh # Mac/Linux
34
- pwsh ./setup.ps1 # Windows (requires PowerShell 7+)
64
+ fellow-agents # start (default command)
65
+ fellow-agents --port 4000 # custom pty-win port
66
+ fellow-agents --emcom-port 9000 # custom messaging port
67
+ fellow-agents --no-browser # headless (server/CI)
68
+ fellow-agents --update # force re-download binaries
69
+ fellow-agents stop # stop all services
35
70
  ```
36
71
 
37
- ## Try It
72
+ ## Add your own agent
38
73
 
39
- 1. Open **coordinator** in pty-win (click play)
40
- 2. Say: *"Have the coder write a fibonacci script and the reviewer check it."*
41
- 3. Watch agents message each other in the emcom feed (right panel)
74
+ ```bash
75
+ mkdir workspaces/designer
76
+ ```
77
+
78
+ Create `CLAUDE.md` (the agent's system prompt) and `identity.json` (name + description for messaging):
79
+
80
+ ```json
81
+ {
82
+ "name": "designer",
83
+ "description": "UI/UX designer — creates interfaces and reviews layouts",
84
+ "server": "http://127.0.0.1:8800"
85
+ }
86
+ ```
42
87
 
43
- ## What's Included
88
+ ```bash
89
+ emcom --identity workspaces/designer/identity.json register
90
+ ```
44
91
 
45
- | Component | Purpose |
46
- |-----------|---------|
47
- | **pty-win** | Browser terminal multiplexer — manage all agent sessions |
48
- | **emcom** | Async messaging between agents |
49
- | **templates/** | 3 starter agents: coordinator, coder, reviewer |
92
+ Restart pty-win and the new agent appears in the UI.
50
93
 
51
- ## Add an Agent
94
+ ## Alternative install: git clone
52
95
 
53
96
  ```bash
54
- mkdir workspaces/myagent
55
- # Copy CLAUDE.md + identity.json from an existing agent, customize
56
- emcom --identity workspaces/myagent/identity.json register
97
+ git clone https://github.com/rajan-chari/fellow-agents.git
98
+ cd fellow-agents
99
+ ./setup.sh # Mac/Linux
100
+ pwsh ./setup.ps1 # Windows (PowerShell 7+)
57
101
  ```
58
102
 
59
- ## Architecture
103
+ Same result, more control. Useful for development or Docker.
104
+
105
+ ## File layout
60
106
 
61
107
  ```
62
- ~/.fellow-agents/ # Data directory (auto-created)
63
- bin/{platform}/ # emcom, tracker, emcom-server binaries
64
- pty-win/ # Terminal multiplexer
65
- pid/ # PID files for running services
66
- logs/ # Service logs
67
-
68
- ./workspaces/ # Agent workspaces (scaffolded from templates)
69
- coordinator/ # Task coordinator
70
- coder/ # Code writer
71
- reviewer/ # Code reviewer
108
+ ~/.fellow-agents/ # Auto-created data directory
109
+ bin/{platform}/ # emcom, tracker, emcom-server
110
+ pty-win/ # Terminal multiplexer
111
+ logs/ # Service logs (check here if something fails)
112
+ pid/ # PID files
113
+
114
+ ./workspaces/ # Scaffolded from templates on first run
115
+ coordinator/CLAUDE.md # "Break tasks down, delegate to coder/reviewer"
116
+ coder/CLAUDE.md # "Write code, send to reviewer for feedback"
117
+ reviewer/CLAUDE.md # "Review code, report issues back"
72
118
  ```
73
119
 
74
- ## Stop
120
+ ## Troubleshooting
121
+
122
+ **Services won't start?** Check `~/.fellow-agents/logs/emcom-server.log` and `pty-win.log`.
123
+
124
+ **Port already in use?** Use `--port` and `--emcom-port` to pick different ports.
125
+
126
+ **Browser didn't open?** Navigate to `http://localhost:3700` manually.
127
+
128
+ **Want to start fresh?** `rm -rf ~/.fellow-agents` and run `fellow-agents start` again.
129
+
130
+ ## License
75
131
 
76
- `fellow-agents stop` or `Ctrl+C` in the start terminal.
132
+ MIT
package/dist/cli.js CHANGED
@@ -1,6 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  const args = process.argv.slice(2);
3
- const command = args[0] || "start";
3
+ // Default to "start" if no command given or first arg is a flag
4
+ const command = args[0] === "stop" ? "stop"
5
+ : (args[0] === "--help" || args[0] === "-h") ? "help"
6
+ : "start";
4
7
  function getFlag(name, fallback) {
5
8
  const idx = args.indexOf(name);
6
9
  return idx !== -1 && args[idx + 1] ? args[idx + 1] : fallback;
@@ -22,14 +25,14 @@ else if (command === "stop") {
22
25
  const { stop } = await import("./commands/stop.js");
23
26
  stop();
24
27
  }
25
- else if (command === "--help" || command === "-h") {
28
+ else {
26
29
  console.log(`fellow-agents — multi-agent system for Claude Code
27
30
 
28
31
  Usage:
29
- fellow-agents start [options] Start services (download binaries on first run)
30
- fellow-agents stop Stop all running services
32
+ fellow-agents [options] Start services (default)
33
+ fellow-agents stop Stop all running services
31
34
 
32
- Options (start):
35
+ Options:
33
36
  --port <number> pty-win port (default: 3700)
34
37
  --emcom-port <number> emcom-server port (default: 8800)
35
38
  --dir <path> Working directory (default: current)
@@ -38,8 +41,4 @@ Options (start):
38
41
 
39
42
  -h, --help Show this help`);
40
43
  }
41
- else {
42
- console.error(`Unknown command: ${command}. Run 'fellow-agents --help' for usage.`);
43
- process.exit(1);
44
- }
45
44
  export {};
@@ -12,7 +12,14 @@ export async function start(opts) {
12
12
  console.log(" fellow-agents");
13
13
  console.log(" =============");
14
14
  console.log("");
15
- const workDir = resolve(opts.dir);
15
+ // Auto-create fellow-agents/ subdirectory if CWD doesn't already have workspaces/
16
+ let workDir = resolve(opts.dir);
17
+ if (!existsSync(join(workDir, "workspaces"))) {
18
+ workDir = join(workDir, "fellow-agents");
19
+ const { mkdirSync } = await import("fs");
20
+ mkdirSync(workDir, { recursive: true });
21
+ console.log(` Working directory: ${workDir}`);
22
+ }
16
23
  const workspacesDir = join(workDir, "workspaces");
17
24
  const emcomUrl = `http://127.0.0.1:${opts.emcomPort}`;
18
25
  // 1. Prerequisites
@@ -1,5 +1,5 @@
1
1
  import { get } from "https";
2
- import { createWriteStream, mkdirSync, readFileSync, writeFileSync, existsSync, rmSync } from "fs";
2
+ import { createWriteStream, mkdirSync, readFileSync, writeFileSync, existsSync, rmSync, chmodSync, readdirSync } from "fs";
3
3
  import { join, dirname } from "path";
4
4
  import { execSync } from "child_process";
5
5
  import { dataDir, binDir, ptyWinDir, versionFile } from "./paths.js";
@@ -57,6 +57,15 @@ export async function downloadBinaries(force = false) {
57
57
  mkdirSync(binDir, { recursive: true });
58
58
  extractZip(dest, dataDir);
59
59
  rmSync(dest);
60
+ // chmod +x on Linux/Mac
61
+ if (process.platform !== "win32") {
62
+ for (const f of readdirSync(binDir)) {
63
+ try {
64
+ chmodSync(join(binDir, f), 0o755);
65
+ }
66
+ catch { }
67
+ }
68
+ }
60
69
  }
61
70
  else if (asset.name.includes("pty-win")) {
62
71
  console.log(` Downloading ${asset.name}...`);
@@ -39,15 +39,32 @@ function isRunning(pid) {
39
39
  }
40
40
  export function startEmcomServer(emcomPort, env) {
41
41
  const bin = join(binDir, `emcom-server${binarySuffix()}`);
42
+ if (!existsSync(bin)) {
43
+ console.error(` emcom-server not found at ${bin}`);
44
+ return -1;
45
+ }
42
46
  const log = openLog("emcom-server");
43
- const proc = spawn(bin, ["--port", String(emcomPort)], {
44
- env: { ...env, EMCOM_PORT: String(emcomPort) },
45
- detached: true,
46
- stdio: ["ignore", log, log],
47
- });
48
- proc.unref();
49
- writePid("emcom-server", proc.pid);
50
- return proc.pid;
47
+ try {
48
+ const proc = spawn(bin, ["--port", String(emcomPort)], {
49
+ env: { ...env, EMCOM_PORT: String(emcomPort) },
50
+ detached: true,
51
+ stdio: ["ignore", log, log],
52
+ });
53
+ proc.on("error", (err) => {
54
+ if (err.code === "EACCES") {
55
+ console.error(` Permission denied: ${bin}`);
56
+ console.error(` Fix: chmod +x "${bin}"`);
57
+ }
58
+ });
59
+ proc.unref();
60
+ writePid("emcom-server", proc.pid);
61
+ return proc.pid;
62
+ }
63
+ catch (err) {
64
+ console.error(` Failed to start emcom-server: ${err.message}`);
65
+ console.error(` Check permissions on ${binDir}`);
66
+ return -1;
67
+ }
51
68
  }
52
69
  export function startPtyWin(port, workspacesDir, emcomUrl, env) {
53
70
  const main = join(ptyWinDir, "dist", "index.js");
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import { runBinary } from "./run-binary.js";
3
+ runBinary("emcom-server");
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import { runBinary } from "./run-binary.js";
3
+ runBinary("emcom");
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { execFileSync } from "child_process";
3
+ import { join } from "path";
4
+ import { existsSync } from "fs";
5
+ // pty-cld lives alongside pty-win in the data directory
6
+ import { dataDir } from "../lib/paths.js";
7
+ const ptyCldDir = join(dataDir, "pty-cld");
8
+ const main = join(ptyCldDir, "dist", "index.js");
9
+ if (!existsSync(main)) {
10
+ console.error("pty-cld not found. Run 'fellow-agents' first to download binaries.");
11
+ process.exit(1);
12
+ }
13
+ try {
14
+ execFileSync("node", [main, ...process.argv.slice(2)], { stdio: "inherit" });
15
+ }
16
+ catch (err) {
17
+ process.exit(err.status ?? 1);
18
+ }
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import { execFileSync } from "child_process";
3
+ import { join } from "path";
4
+ import { existsSync } from "fs";
5
+ import { ptyWinDir } from "../lib/paths.js";
6
+ const main = join(ptyWinDir, "dist", "index.js");
7
+ if (!existsSync(main)) {
8
+ console.error("pty-win not found. Run 'fellow-agents' first to download binaries.");
9
+ process.exit(1);
10
+ }
11
+ try {
12
+ execFileSync("node", [main, ...process.argv.slice(2)], { stdio: "inherit" });
13
+ }
14
+ catch (err) {
15
+ process.exit(err.status ?? 1);
16
+ }
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ import { execFileSync } from "child_process";
3
+ import { join } from "path";
4
+ import { existsSync } from "fs";
5
+ import { binDir } from "../lib/paths.js";
6
+ import { binarySuffix } from "../lib/platform.js";
7
+ export function runBinary(name) {
8
+ const bin = join(binDir, `${name}${binarySuffix()}`);
9
+ if (!existsSync(bin)) {
10
+ console.error(`${name} not found. Run 'fellow-agents' first to download binaries.`);
11
+ process.exit(1);
12
+ }
13
+ try {
14
+ execFileSync(bin, process.argv.slice(2), { stdio: "inherit" });
15
+ }
16
+ catch (err) {
17
+ process.exit(err.status ?? 1);
18
+ }
19
+ }
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import { runBinary } from "./run-binary.js";
3
+ runBinary("tracker");
package/package.json CHANGED
@@ -1,10 +1,15 @@
1
1
  {
2
2
  "name": "fellow-agents",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "Multi-agent system — multiple Claude Code instances collaborating via messaging",
5
5
  "type": "module",
6
6
  "bin": {
7
- "fellow-agents": "dist/cli.js"
7
+ "fellow-agents": "dist/cli.js",
8
+ "emcom": "dist/shims/emcom.js",
9
+ "emcom-server": "dist/shims/emcom-server.js",
10
+ "tracker": "dist/shims/tracker.js",
11
+ "pty-win": "dist/shims/pty-win.js",
12
+ "pty-cld": "dist/shims/pty-cld.js"
8
13
  },
9
14
  "files": [
10
15
  "dist/",