agentxchain 0.8.0 → 0.8.2

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,6 +1,6 @@
1
1
  # agentxchain
2
2
 
3
- CLI for multi-agent coordination in your IDE. Define a team of AI agents, let them take turns building your project via shared state and lifecycle hooks.
3
+ CLI for multi-agent coordination in your IDE. Define a team of AI agents, let them take turns building your project each in its own IDE window.
4
4
 
5
5
  ## Install
6
6
 
@@ -17,59 +17,92 @@ npx agentxchain init
17
17
  ## Quick start
18
18
 
19
19
  ```bash
20
- agentxchain init # create project with agents + hooks
21
- cd my-project/ && code . # open in VS Code / Cursor
22
- # Select an agent from the Chat dropdown (auto-discovered from .github/agents/)
23
- agentxchain release # release human lock to begin turns
20
+ # 1. Create a project (interactive template selection)
21
+ agentxchain init
22
+
23
+ # 2. Launch agents opens a separate Cursor window per agent
24
+ cd my-project/
25
+ agentxchain start
26
+
27
+ # 3. For each window: paste the prompt (auto-copied to clipboard), select Agent mode, send
28
+ # The CLI walks you through one agent at a time.
29
+
30
+ # 4. Release the human lock — agents start claiming turns
31
+ agentxchain release
24
32
  ```
25
33
 
26
- The `Stop` hook acts as referee: when an agent finishes, it determines the next agent and hands off automatically. No polling process needed.
34
+ Each agent runs in its own Cursor window with a self-polling loop. Agents check `lock.json` every 60 seconds, claim when it's their turn, do their work, release, and go back to waiting. No external referee needed.
27
35
 
28
36
  ## Commands
29
37
 
30
38
  | Command | What it does |
31
39
  |---------|-------------|
32
- | `init` | Create project folder with agents, hooks, protocol files, and templates |
33
- | `generate` | Regenerate VS Code agent files (`.agent.md`, hooks) from `agentxchain.json` |
34
- | `start` | Show agent setup instructions for your IDE |
35
- | `status` | Show lock, phase, agents |
36
- | `claim` | Human takes control |
40
+ | `init` | Create project folder with agents, protocol files, and templates |
41
+ | `start` | Open a Cursor window per agent + copy prompts to clipboard |
42
+ | `generate` | Regenerate agent files from `agentxchain.json` |
43
+ | `status` | Show lock holder, phase, turn number, agents |
44
+ | `claim` | Human takes control (agents stop claiming) |
37
45
  | `release` | Hand lock back to agents |
38
46
  | `stop` | Terminate running Claude Code agent sessions |
39
- | `watch` | Fallback referee for non-IDE environments |
47
+ | `watch` | Optional: TTL safety net + status logging |
40
48
  | `config` | View/edit config, add/remove agents, change rules |
41
49
  | `update` | Self-update CLI from npm |
42
50
 
51
+ ### IDE options
52
+
53
+ ```bash
54
+ agentxchain start # Cursor (default) — one window per agent
55
+ agentxchain start --ide vscode # VS Code — uses .agent.md custom agents + hooks
56
+ agentxchain start --ide claude-code # Claude Code — spawns CLI processes
57
+ ```
58
+
43
59
  ### Additional flags
44
60
 
45
61
  ```bash
62
+ agentxchain start --agent pm # launch only one specific agent
63
+ agentxchain start --dry-run # preview agents without launching
46
64
  agentxchain watch --daemon # run watch in background
47
65
  agentxchain release --force # force-release non-human holder lock
48
66
  ```
49
67
 
50
68
  ## How it works
51
69
 
52
- `agentxchain init` generates native VS Code agent files:
70
+ ### Cursor mode (default)
71
+
72
+ 1. `agentxchain start` opens a **separate Cursor window** for each agent
73
+ 2. Each window gets a unique prompt copied to clipboard
74
+ 3. Agent prompts include a self-polling loop: read `lock.json` → check if it's my turn → claim → work → release → sleep 60s → repeat
75
+ 4. Agents know their rotation order from `agentxchain.json` and only claim when the previous agent released
76
+ 5. Human can `claim` to pause and `release` to resume anytime
77
+
78
+ ### VS Code mode
79
+
80
+ 1. `agentxchain init` generates `.github/agents/*.agent.md` (VS Code custom agents) and `.github/hooks/` (lifecycle hooks)
81
+ 2. VS Code auto-discovers agents in the Chat dropdown
82
+ 3. The `Stop` hook acts as referee — hands off to next agent automatically
53
83
 
54
- - `.github/agents/*.agent.md` — custom agents (auto-discovered by VS Code / Cursor Chat)
55
- - `.github/hooks/agentxchain.json` — lifecycle hooks (Stop = referee, SessionStart = context injection)
56
- - `scripts/agentxchain-*.sh` — hook shell scripts
84
+ ### Turn rotation
57
85
 
58
- When an agent finishes its response, the Stop hook reads `lock.json`, determines the next agent, and hands off automatically.
86
+ Agents follow a round-robin order defined in `agentxchain.json`:
87
+ - PM waits for: lock free + last released by `human`, `null`, or last agent in rotation
88
+ - Dev waits for: lock free + last released by `pm`
89
+ - QA waits for: lock free + last released by `dev`
90
+ - And so on...
59
91
 
60
92
  ## Key features
61
93
 
62
- - **Native VS Code agents** — `.agent.md` files, lifecycle hooks, handoffs
63
- - **Works in any VS Code fork** Cursor, VS Code, Windsurf, etc.
64
- - **Stop hook referee** — deterministic turn coordination via lifecycle hooks
94
+ - **One window per agent** — each agent has its own Cursor window and chat session
95
+ - **Self-polling coordination** agents check `lock.json` every 60s, no external process needed
96
+ - **Works in Cursor, VS Code, Claude Code** — adapters for each IDE
65
97
  - **User-defined teams** — any number of agents, any roles
66
98
  - **No API keys or cloud required** — everything runs locally
67
99
  - **Human-in-the-loop** — claim/release to intervene anytime
68
100
  - **Team templates** — SaaS MVP, Landing Page, Bug Squad, API Builder, Refactor Team
101
+ - **Lock TTL** — `watch` can force-release stale locks as a safety net
69
102
 
70
103
  ## VS Code extension (optional)
71
104
 
72
- For a richer UI experience, install the extension:
105
+ For a richer UI in VS Code:
73
106
 
74
107
  ```bash
75
108
  code --install-extension cli/vscode-extension/agentxchain-0.1.0.vsix
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentxchain",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "CLI for AgentXchain — multi-agent coordination in your IDE",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,5 +1,5 @@
1
1
  import { execSync } from 'child_process';
2
- import { writeFileSync } from 'fs';
2
+ import { writeFileSync, mkdirSync, existsSync, symlinkSync, lstatSync, unlinkSync } from 'fs';
3
3
  import { join } from 'path';
4
4
  import chalk from 'chalk';
5
5
  import inquirer from 'inquirer';
@@ -10,50 +10,83 @@ export async function launchCursorLocal(config, root, opts) {
10
10
  const agentEntries = Object.entries(agents);
11
11
  const total = agentEntries.length;
12
12
 
13
- console.log(chalk.bold(` Opening ${total} Cursor windows for: ${Object.keys(agents).join(', ')}`));
13
+ console.log(chalk.bold(` Setting up ${total} agents: ${Object.keys(agents).join(', ')}`));
14
14
  console.log('');
15
15
 
16
16
  const promptDir = join(root, '.agentxchain-prompts');
17
- try { execSync(`mkdir -p "${promptDir}"`); } catch {}
17
+ mkdirSync(promptDir, { recursive: true });
18
+
19
+ // Save all prompts first
20
+ for (const [id, agent] of agentEntries) {
21
+ const prompt = generatePollingPrompt(id, agent, config);
22
+ writeFileSync(join(promptDir, `${id}.prompt.md`), prompt);
23
+ }
24
+
25
+ // Create per-agent symlinked workspace folders so Cursor opens separate windows
26
+ const workspacesDir = join(root, '.agentxchain-workspaces');
27
+ mkdirSync(workspacesDir, { recursive: true });
18
28
 
19
29
  for (let i = 0; i < agentEntries.length; i++) {
20
30
  const [id, agent] = agentEntries[i];
21
31
  const prompt = generatePollingPrompt(id, agent, config);
22
- const promptFile = join(promptDir, `${id}.prompt.md`);
23
- writeFileSync(promptFile, prompt);
24
32
 
25
- console.log(` ${chalk.cyan(`Window ${i + 1}/${total}:`)} ${chalk.bold(id)} ${agent.name}`);
33
+ // Create symlink: .agentxchain-workspaces/<id> -> project root
34
+ const agentWorkspace = join(workspacesDir, id);
35
+ try {
36
+ if (existsSync(agentWorkspace)) {
37
+ const stat = lstatSync(agentWorkspace);
38
+ if (stat.isSymbolicLink()) unlinkSync(agentWorkspace);
39
+ }
40
+ if (!existsSync(agentWorkspace)) {
41
+ symlinkSync(root, agentWorkspace, 'dir');
42
+ }
43
+ } catch {}
44
+
45
+ console.log(chalk.cyan(` ─── Agent ${i + 1}/${total}: ${chalk.bold(id)} — ${agent.name} ───`));
46
+ console.log('');
26
47
 
27
48
  copyToClipboard(prompt);
28
- console.log(chalk.green(` Prompt copied to clipboard.`));
29
- console.log(chalk.dim(` Also saved to: .agentxchain-prompts/${id}.prompt.md`));
49
+ console.log(chalk.green(`Prompt copied to clipboard.`));
50
+ console.log(chalk.dim(` Saved to: .agentxchain-prompts/${id}.prompt.md`));
51
+
52
+ // Open a separate Cursor window using the symlinked path
53
+ openCursorWindow(agentWorkspace);
54
+ console.log(chalk.dim(` Cursor window opened for ${id}.`));
30
55
 
31
- tryOpenCursor(root);
56
+ console.log('');
57
+ console.log(` ${chalk.bold('In the new Cursor window:')}`);
58
+ console.log(` 1. Open chat (${chalk.bold('Cmd+L')})`);
59
+ console.log(` 2. Paste the prompt (${chalk.bold('Cmd+V')})`);
60
+ console.log(` 3. ${chalk.bold('Select Agent mode')} (not Ask/Edit)`);
61
+ console.log(` 4. Send it (${chalk.bold('Enter')})`);
32
62
 
33
63
  if (i < agentEntries.length - 1) {
34
64
  console.log('');
35
65
  await inquirer.prompt([{
36
66
  type: 'input',
37
67
  name: 'ready',
38
- message: chalk.dim(` Paste prompt in Cursor chat (Cmd+V), send it, then press Enter here for the next agent...`)
68
+ message: ` Done? Press Enter to open next window (${agentEntries[i + 1][0]})...`
39
69
  }]);
70
+ console.log('');
40
71
  } else {
41
72
  console.log('');
42
- console.log(chalk.dim(` Paste this last prompt in Cursor chat (Cmd+V) and send it.`));
73
+ console.log(chalk.dim(` Last agent. Paste and send, then come back here.`));
74
+ console.log('');
43
75
  }
44
76
  }
45
77
 
78
+ console.log(chalk.green(` ✓ All ${total} agents launched in separate Cursor windows.`));
46
79
  console.log('');
47
- console.log(chalk.green(' All agent prompts ready.'));
48
- console.log('');
49
- console.log(` ${chalk.cyan('Next:')}`);
80
+ console.log(` ${chalk.cyan('Now run:')}`);
50
81
  console.log(` ${chalk.bold('agentxchain release')} ${chalk.dim('# release human lock — agents start claiming turns')}`);
51
- console.log(` ${chalk.bold('agentxchain watch')} ${chalk.dim('# optional: TTL safety net + status logging')}`);
82
+ console.log('');
83
+ console.log(` ${chalk.dim('Other commands:')}`);
52
84
  console.log(` ${chalk.bold('agentxchain status')} ${chalk.dim('# check who holds the lock')}`);
53
85
  console.log(` ${chalk.bold('agentxchain claim')} ${chalk.dim('# pause agents and take control')}`);
86
+ console.log(` ${chalk.bold('agentxchain watch')} ${chalk.dim('# optional: TTL safety net')}`);
54
87
  console.log('');
55
88
  console.log(chalk.dim(' Agents self-coordinate via lock.json polling (sleep 60s between checks).'));
56
- console.log(chalk.dim(' Prompts saved in .agentxchain-prompts/ if you need to re-paste.'));
89
+ console.log(chalk.dim(' Re-paste a prompt: cat .agentxchain-prompts/<agent>.prompt.md | pbcopy'));
57
90
  console.log('');
58
91
  }
59
92
 
@@ -82,14 +115,12 @@ function copyToClipboard(text) {
82
115
  return false;
83
116
  }
84
117
 
85
- function tryOpenCursor(root) {
118
+ function openCursorWindow(folderPath) {
86
119
  try {
87
120
  if (process.platform === 'darwin') {
88
- execSync(`open -na "Cursor" --args "${root}"`, { stdio: 'ignore' });
121
+ execSync(`open -na "Cursor" --args "${folderPath}"`, { stdio: 'ignore' });
89
122
  return;
90
123
  }
91
- execSync(`cursor "${root}"`, { stdio: 'ignore' });
92
- } catch {
93
- // Cursor not found or can't open — user will open manually
94
- }
124
+ execSync(`cursor --new-window "${folderPath}"`, { stdio: 'ignore' });
125
+ } catch {}
95
126
  }
@@ -207,7 +207,7 @@ export async function initCommand(opts) {
207
207
  writeFileSync(join(dir, 'log.md'), `# ${project} — Agent Log\n\n## COMPRESSED CONTEXT\n\n(No compressed context yet.)\n\n## MESSAGE LOG\n\n(Agents append messages below this line.)\n`);
208
208
  writeFileSync(join(dir, 'HUMAN_TASKS.md'), '# Human Tasks\n\n(Agents append tasks here when they need human action.)\n');
209
209
  const gitignorePath = join(dir, '.gitignore');
210
- const requiredIgnores = ['.env', '.agentxchain-trigger.json', '.agentxchain-prompts/'];
210
+ const requiredIgnores = ['.env', '.agentxchain-trigger.json', '.agentxchain-prompts/', '.agentxchain-workspaces/'];
211
211
  if (!existsSync(gitignorePath)) {
212
212
  writeFileSync(gitignorePath, requiredIgnores.join('\n') + '\n');
213
213
  } else {
@@ -264,13 +264,7 @@ export async function initCommand(opts) {
264
264
  console.log('');
265
265
  console.log(` ${chalk.cyan('Next:')}`);
266
266
  console.log(` ${chalk.bold(`cd ${folderName}`)}`);
267
- console.log(` ${chalk.bold('cursor .')} ${chalk.dim('# open in Cursor')}`);
268
- console.log(` ${chalk.bold('code .')} ${chalk.dim('# open in VS Code')}`);
269
- console.log(` ${chalk.dim('(If "command not found": open IDE → Cmd+Shift+P → "Shell Command: Install")')}`);
270
- console.log('');
271
- console.log(` ${chalk.dim('In your IDE:')}`);
272
- console.log(` ${chalk.dim(' 1. Open Chat (Cmd+L)')}`);
273
- console.log(` ${chalk.dim(' 2. Select an agent from the dropdown (auto-discovered from .github/agents/)')}`);
274
- console.log(` ${chalk.bold('agentxchain release')} ${chalk.dim('# release human lock to begin turns')}`);
267
+ console.log(` ${chalk.bold('agentxchain start')} ${chalk.dim('# opens Cursor windows + copies agent prompts')}`);
268
+ console.log(` ${chalk.bold('agentxchain release')} ${chalk.dim('# release human lock — agents start working')}`);
275
269
  console.log('');
276
270
  }