tmux-ide 1.0.0
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/LICENSE +21 -0
- package/README.md +95 -0
- package/bin/cli.js +168 -0
- package/package.json +44 -0
- package/scripts/postinstall.js +13 -0
- package/skill/SKILL.md +238 -0
- package/src/attach.js +22 -0
- package/src/config.js +259 -0
- package/src/detect.js +178 -0
- package/src/detect.test.js +115 -0
- package/src/doctor.js +82 -0
- package/src/init.js +81 -0
- package/src/integration.test.js +94 -0
- package/src/launch.js +238 -0
- package/src/lib/dot-path.js +16 -0
- package/src/lib/dot-path.test.js +67 -0
- package/src/lib/output.js +72 -0
- package/src/lib/sizes.js +36 -0
- package/src/lib/sizes.test.js +74 -0
- package/src/lib/yaml-io.js +26 -0
- package/src/ls.js +42 -0
- package/src/restart.js +23 -0
- package/src/status.js +53 -0
- package/src/stop.js +23 -0
- package/src/validate.js +170 -0
- package/src/validate.test.js +141 -0
- package/templates/agent-team-monorepo.yml +31 -0
- package/templates/agent-team-nextjs.yml +27 -0
- package/templates/agent-team.yml +23 -0
- package/templates/convex.yml +19 -0
- package/templates/default.yml +20 -0
- package/templates/go.yml +15 -0
- package/templates/nextjs.yml +17 -0
- package/templates/python.yml +15 -0
- package/templates/vite.yml +15 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 wavyrai
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# tmux-ide
|
|
2
|
+
|
|
3
|
+
Turn any project into a tmux-powered terminal IDE with a simple `ide.yml` config file.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g tmux-ide
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
tmux-ide init # Scaffold ide.yml (auto-detects your stack)
|
|
15
|
+
tmux-ide # Launch the IDE
|
|
16
|
+
tmux-ide stop # Kill the session
|
|
17
|
+
tmux-ide restart # Stop and relaunch
|
|
18
|
+
tmux-ide attach # Reattach to a running session
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## ide.yml Format
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
name: project-name # tmux session name
|
|
25
|
+
|
|
26
|
+
before: pnpm install # optional pre-launch hook
|
|
27
|
+
|
|
28
|
+
rows:
|
|
29
|
+
- size: 70% # row height percentage
|
|
30
|
+
panes:
|
|
31
|
+
- title: Editor # pane border label
|
|
32
|
+
command: vim # command to run (optional)
|
|
33
|
+
size: 60% # pane width percentage (optional)
|
|
34
|
+
dir: apps/web # per-pane working directory (optional)
|
|
35
|
+
focus: true # initial focus (optional)
|
|
36
|
+
env: # environment variables (optional)
|
|
37
|
+
PORT: 3000
|
|
38
|
+
- title: Shell
|
|
39
|
+
|
|
40
|
+
- panes:
|
|
41
|
+
- title: Dev Server
|
|
42
|
+
command: pnpm dev
|
|
43
|
+
- title: Tests
|
|
44
|
+
command: pnpm test
|
|
45
|
+
|
|
46
|
+
theme: # optional color overrides
|
|
47
|
+
accent: colour75
|
|
48
|
+
border: colour238
|
|
49
|
+
bg: colour235
|
|
50
|
+
fg: colour248
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Commands
|
|
54
|
+
|
|
55
|
+
| Command | Description |
|
|
56
|
+
|---------|-------------|
|
|
57
|
+
| `tmux-ide` | Launch IDE from `ide.yml` |
|
|
58
|
+
| `tmux-ide <path>` | Launch from a specific directory |
|
|
59
|
+
| `tmux-ide init [--template <name>]` | Scaffold a new `ide.yml` |
|
|
60
|
+
| `tmux-ide stop` | Kill the current IDE session |
|
|
61
|
+
| `tmux-ide restart` | Stop and relaunch the IDE session |
|
|
62
|
+
| `tmux-ide attach` | Reattach to a running session |
|
|
63
|
+
| `tmux-ide ls` | List all tmux sessions |
|
|
64
|
+
| `tmux-ide status` | Show session status |
|
|
65
|
+
| `tmux-ide doctor` | Check system requirements |
|
|
66
|
+
| `tmux-ide validate` | Validate `ide.yml` |
|
|
67
|
+
| `tmux-ide detect` | Detect project stack |
|
|
68
|
+
| `tmux-ide detect --write` | Detect and write `ide.yml` |
|
|
69
|
+
| `tmux-ide config` | Dump config as JSON |
|
|
70
|
+
| `tmux-ide config set <path> <value>` | Set a config value |
|
|
71
|
+
| `tmux-ide config add-pane --row <N>` | Add a pane to a row |
|
|
72
|
+
| `tmux-ide config remove-pane --row <N> --pane <M>` | Remove a pane |
|
|
73
|
+
| `tmux-ide config add-row [--size <percent>]` | Add a new row |
|
|
74
|
+
|
|
75
|
+
All commands support `--json` for structured output.
|
|
76
|
+
|
|
77
|
+
## Templates
|
|
78
|
+
|
|
79
|
+
Use `tmux-ide init --template <name>` with one of:
|
|
80
|
+
|
|
81
|
+
- `default` — General-purpose layout
|
|
82
|
+
- `nextjs` — Next.js development
|
|
83
|
+
- `convex` — Convex + Next.js
|
|
84
|
+
- `vite` — Vite project
|
|
85
|
+
- `python` — Python development
|
|
86
|
+
- `go` — Go development
|
|
87
|
+
|
|
88
|
+
## Requirements
|
|
89
|
+
|
|
90
|
+
- **tmux** >= 3.0
|
|
91
|
+
- **Node.js** >= 18
|
|
92
|
+
|
|
93
|
+
## License
|
|
94
|
+
|
|
95
|
+
[MIT](LICENSE)
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { parseArgs } from "node:util";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { launch } from "../src/launch.js";
|
|
5
|
+
import { init } from "../src/init.js";
|
|
6
|
+
import { stop } from "../src/stop.js";
|
|
7
|
+
import { attach } from "../src/attach.js";
|
|
8
|
+
import { ls } from "../src/ls.js";
|
|
9
|
+
import { doctor } from "../src/doctor.js";
|
|
10
|
+
import { status } from "../src/status.js";
|
|
11
|
+
import { validate } from "../src/validate.js";
|
|
12
|
+
import { detect } from "../src/detect.js";
|
|
13
|
+
import { config } from "../src/config.js";
|
|
14
|
+
import { restart } from "../src/restart.js";
|
|
15
|
+
|
|
16
|
+
const { positionals, values } = parseArgs({
|
|
17
|
+
allowPositionals: true,
|
|
18
|
+
strict: false,
|
|
19
|
+
options: {
|
|
20
|
+
json: { type: "boolean" },
|
|
21
|
+
row: { type: "string" },
|
|
22
|
+
pane: { type: "string" },
|
|
23
|
+
title: { type: "string" },
|
|
24
|
+
command: { type: "string" },
|
|
25
|
+
size: { type: "string" },
|
|
26
|
+
write: { type: "boolean" },
|
|
27
|
+
template: { type: "string" },
|
|
28
|
+
name: { type: "string" },
|
|
29
|
+
help: { type: "boolean", short: "h" },
|
|
30
|
+
version: { type: "boolean", short: "v" },
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// --version / -v
|
|
35
|
+
if (values.version) {
|
|
36
|
+
const require = createRequire(import.meta.url);
|
|
37
|
+
const pkg = require("../package.json");
|
|
38
|
+
console.log(`tmux-ide v${pkg.version}`);
|
|
39
|
+
process.exit(0);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const command = positionals[0] ?? "start";
|
|
43
|
+
const json = values.json ?? false;
|
|
44
|
+
|
|
45
|
+
const noColor = "NO_COLOR" in process.env;
|
|
46
|
+
const bold = (s) => (noColor ? s : `\x1b[1m${s}\x1b[22m`);
|
|
47
|
+
const cyan = (s) => (noColor ? s : `\x1b[36m${s}\x1b[39m`);
|
|
48
|
+
const dim = (s) => (noColor ? s : `\x1b[2m${s}\x1b[22m`);
|
|
49
|
+
|
|
50
|
+
function printHelp() {
|
|
51
|
+
console.log(`${bold("tmux-ide")} — Terminal IDE powered by tmux
|
|
52
|
+
|
|
53
|
+
${bold("Usage:")}
|
|
54
|
+
${cyan("tmux-ide")} ${dim("Launch IDE from ide.yml")}
|
|
55
|
+
${cyan("tmux-ide <path>")} ${dim("Launch from a specific directory")}
|
|
56
|
+
${cyan("tmux-ide init")} [--template] ${dim("Scaffold a new ide.yml (auto-detects stack)")}
|
|
57
|
+
${cyan("tmux-ide stop")} ${dim("Kill the current IDE session")}
|
|
58
|
+
${cyan("tmux-ide restart")} ${dim("Stop and relaunch the IDE session")}
|
|
59
|
+
${cyan("tmux-ide attach")} ${dim("Reattach to a running session")}
|
|
60
|
+
${cyan("tmux-ide ls")} ${dim("List all tmux sessions")}
|
|
61
|
+
${cyan("tmux-ide status")} [--json] ${dim("Show session status")}
|
|
62
|
+
${cyan("tmux-ide doctor")} ${dim("Check system requirements")}
|
|
63
|
+
${cyan("tmux-ide validate")} [--json] ${dim("Validate ide.yml")}
|
|
64
|
+
${cyan("tmux-ide detect")} [--json] ${dim("Detect project stack")}
|
|
65
|
+
${cyan("tmux-ide detect --write")} ${dim("Detect and write ide.yml")}
|
|
66
|
+
${cyan("tmux-ide config")} [--json] ${dim("Dump config as JSON")}
|
|
67
|
+
${cyan("tmux-ide config set")} <path> <value>
|
|
68
|
+
${cyan("tmux-ide config add-pane")} --row <N> --title <T> [--command <C>]
|
|
69
|
+
${cyan("tmux-ide config remove-pane")} --row <N> --pane <M>
|
|
70
|
+
${cyan("tmux-ide config add-row")} [--size <percent>]
|
|
71
|
+
${cyan("tmux-ide config enable-team")} [--name <N>] ${dim("Enable agent teams")}
|
|
72
|
+
${cyan("tmux-ide config disable-team")} ${dim("Disable agent teams")}
|
|
73
|
+
|
|
74
|
+
${bold("Flags:")}
|
|
75
|
+
${cyan("--json")} ${dim("Output as JSON (all commands)")}
|
|
76
|
+
${cyan("--template <name>")} ${dim("Use specific template for init")}
|
|
77
|
+
${cyan("--write")} ${dim("Write detected config to ide.yml")}
|
|
78
|
+
${cyan("-v, --version")} ${dim("Show version number")}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
switch (command) {
|
|
82
|
+
case "start":
|
|
83
|
+
await launch(positionals[1]);
|
|
84
|
+
break;
|
|
85
|
+
|
|
86
|
+
case "init":
|
|
87
|
+
await init({ template: values.template, json });
|
|
88
|
+
break;
|
|
89
|
+
|
|
90
|
+
case "stop":
|
|
91
|
+
await stop(positionals[1], { json });
|
|
92
|
+
break;
|
|
93
|
+
|
|
94
|
+
case "attach":
|
|
95
|
+
await attach(positionals[1], { json });
|
|
96
|
+
break;
|
|
97
|
+
|
|
98
|
+
case "restart":
|
|
99
|
+
await restart(positionals[1]);
|
|
100
|
+
break;
|
|
101
|
+
|
|
102
|
+
case "ls":
|
|
103
|
+
await ls({ json });
|
|
104
|
+
break;
|
|
105
|
+
|
|
106
|
+
case "doctor":
|
|
107
|
+
await doctor({ json });
|
|
108
|
+
break;
|
|
109
|
+
|
|
110
|
+
case "status":
|
|
111
|
+
await status(positionals[1], { json });
|
|
112
|
+
break;
|
|
113
|
+
|
|
114
|
+
case "validate":
|
|
115
|
+
await validate(positionals[1], { json });
|
|
116
|
+
break;
|
|
117
|
+
|
|
118
|
+
case "detect":
|
|
119
|
+
await detect(positionals[1], { json, write: values.write });
|
|
120
|
+
break;
|
|
121
|
+
|
|
122
|
+
case "config": {
|
|
123
|
+
const sub = positionals[1]; // set, add-pane, remove-pane, add-row, or undefined (dump)
|
|
124
|
+
let action = "dump";
|
|
125
|
+
let configArgs = [];
|
|
126
|
+
|
|
127
|
+
if (sub === "set") {
|
|
128
|
+
action = "set";
|
|
129
|
+
configArgs = positionals.slice(2);
|
|
130
|
+
} else if (sub === "add-pane") {
|
|
131
|
+
action = "add-pane";
|
|
132
|
+
// Pass named flags as args array
|
|
133
|
+
configArgs = [];
|
|
134
|
+
if (values.row !== undefined) configArgs.push("--row", values.row);
|
|
135
|
+
if (values.title !== undefined) configArgs.push("--title", values.title);
|
|
136
|
+
if (values.command !== undefined) configArgs.push("--command", values.command);
|
|
137
|
+
if (values.size !== undefined) configArgs.push("--size", values.size);
|
|
138
|
+
} else if (sub === "remove-pane") {
|
|
139
|
+
action = "remove-pane";
|
|
140
|
+
configArgs = [];
|
|
141
|
+
if (values.row !== undefined) configArgs.push("--row", values.row);
|
|
142
|
+
if (values.pane !== undefined) configArgs.push("--pane", values.pane);
|
|
143
|
+
} else if (sub === "add-row") {
|
|
144
|
+
action = "add-row";
|
|
145
|
+
configArgs = [];
|
|
146
|
+
if (values.size !== undefined) configArgs.push("--size", values.size);
|
|
147
|
+
} else if (sub === "enable-team") {
|
|
148
|
+
action = "enable-team";
|
|
149
|
+
configArgs = [];
|
|
150
|
+
if (values.name !== undefined) configArgs.push("--name", values.name);
|
|
151
|
+
} else if (sub === "disable-team") {
|
|
152
|
+
action = "disable-team";
|
|
153
|
+
configArgs = [];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
await config(null, { json, action, args: configArgs });
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
case "help":
|
|
161
|
+
printHelp();
|
|
162
|
+
break;
|
|
163
|
+
|
|
164
|
+
default:
|
|
165
|
+
console.error(`Unknown command: ${command}`);
|
|
166
|
+
console.error('Run "tmux-ide help" for usage.');
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tmux-ide",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Turn any project into a tmux-powered terminal IDE with a simple ide.yml",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"tmux-ide": "bin/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"src",
|
|
12
|
+
"scripts",
|
|
13
|
+
"skill",
|
|
14
|
+
"templates"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"dev": "node bin/cli.js",
|
|
18
|
+
"test": "node --test 'src/**/*.test.js'",
|
|
19
|
+
"postinstall": "node scripts/postinstall.js",
|
|
20
|
+
"docs": "cd docs && pnpm dev"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"tmux",
|
|
24
|
+
"ide",
|
|
25
|
+
"terminal",
|
|
26
|
+
"workspace",
|
|
27
|
+
"developer-tools"
|
|
28
|
+
],
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18"
|
|
31
|
+
},
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/wavyrai/tmux-ide.git"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/wavyrai/tmux-ide#readme",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/wavyrai/tmux-ide/issues"
|
|
39
|
+
},
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"js-yaml": "^4.1.0"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, copyFileSync } from "node:fs";
|
|
2
|
+
import { resolve, dirname } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
|
|
5
|
+
const claudeDir = resolve(homedir(), ".claude");
|
|
6
|
+
if (existsSync(claudeDir)) {
|
|
7
|
+
const skillDir = resolve(claudeDir, "skills", "tmux-ide");
|
|
8
|
+
mkdirSync(skillDir, { recursive: true });
|
|
9
|
+
const src = resolve(dirname(import.meta.dirname), "skill", "SKILL.md");
|
|
10
|
+
if (existsSync(src)) {
|
|
11
|
+
copyFileSync(src, resolve(skillDir, "SKILL.md"));
|
|
12
|
+
}
|
|
13
|
+
}
|
package/skill/SKILL.md
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# tmux-ide — Claude Code Skill
|
|
2
|
+
|
|
3
|
+
tmux-ide turns any project into a tmux-powered terminal IDE using a simple `ide.yml` config file.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- User mentions multi-pane, tmux, terminal IDE, or dev environment
|
|
8
|
+
- User wants to set up a development workspace
|
|
9
|
+
- User asks about running multiple terminals/tools side-by-side
|
|
10
|
+
- User wants to coordinate multiple Claude Code instances as a team
|
|
11
|
+
- User mentions agent teams, team lead, or multi-agent workflows
|
|
12
|
+
|
|
13
|
+
## Setup workflow
|
|
14
|
+
|
|
15
|
+
1. Check if `ide.yml` exists: `tmux-ide status --json`
|
|
16
|
+
2. Auto-detect the project: `tmux-ide detect --json`
|
|
17
|
+
3. **Present 2-3 layout options using ASCII diagrams** before writing config. Example:
|
|
18
|
+
|
|
19
|
+
**Option A — Dual Claude + Dev (recommended)**
|
|
20
|
+
```
|
|
21
|
+
┌─────────────────┬─────────────────┐
|
|
22
|
+
│ │ │
|
|
23
|
+
│ Claude 1 │ Claude 2 │ 70%
|
|
24
|
+
│ │ │
|
|
25
|
+
├────────┬────────┴────────┬────────┤
|
|
26
|
+
│Dev Srv │ Tests │ Shell │ │ 30%
|
|
27
|
+
└────────┴─────────┴───────┘────────┘
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Option B — Triple Claude**
|
|
31
|
+
```
|
|
32
|
+
┌───────────┬───────────┬───────────┐
|
|
33
|
+
│ │ │ │
|
|
34
|
+
│ Claude 1 │ Claude 2 │ Claude 3 │ 70%
|
|
35
|
+
│ │ │ │
|
|
36
|
+
├───────────┴─────┬─────┴───────────┤
|
|
37
|
+
│ Dev Server │ Shell │ 30%
|
|
38
|
+
└─────────────────┴─────────────────┘
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Option C — Single Claude + wide dev**
|
|
42
|
+
```
|
|
43
|
+
┌─────────────────────────────────────┐
|
|
44
|
+
│ Claude │ 60%
|
|
45
|
+
├──────────┬──────────┬──────────────┤
|
|
46
|
+
│ Dev Srv │ Tests │ Shell │ 40%
|
|
47
|
+
└──────────┴──────────┴──────────────┘
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Adapt pane names/commands to the detected stack.
|
|
51
|
+
|
|
52
|
+
4. Once the user picks, write the config:
|
|
53
|
+
- Quick: `tmux-ide detect --write` then modify
|
|
54
|
+
- Or build custom with `tmux-ide config` subcommands
|
|
55
|
+
|
|
56
|
+
## Agent Teams workflow
|
|
57
|
+
|
|
58
|
+
Agent teams coordinate multiple Claude Code instances where a lead delegates tasks to teammates. Each gets its own tmux pane.
|
|
59
|
+
|
|
60
|
+
### When to suggest agent teams
|
|
61
|
+
|
|
62
|
+
- User wants coordinated multi-agent development
|
|
63
|
+
- User mentions team lead, teammates, or task delegation
|
|
64
|
+
- User wants parallel work with inter-agent communication
|
|
65
|
+
- User's task benefits from specialized roles (e.g., frontend + backend + review)
|
|
66
|
+
|
|
67
|
+
### Prerequisites
|
|
68
|
+
|
|
69
|
+
Agent teams require `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`. tmux-ide sets this automatically when `team` is configured in `ide.yml`.
|
|
70
|
+
|
|
71
|
+
### Setup from scratch
|
|
72
|
+
|
|
73
|
+
1. **Scaffold with agent team template:**
|
|
74
|
+
```bash
|
|
75
|
+
tmux-ide init --template agent-team
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
2. **Or enable teams on an existing config:**
|
|
79
|
+
```bash
|
|
80
|
+
tmux-ide config enable-team --name "my-team"
|
|
81
|
+
```
|
|
82
|
+
This finds all `command: claude` panes and assigns the first as `lead`, the rest as `teammate`.
|
|
83
|
+
|
|
84
|
+
3. **Assign initial tasks to teammates:**
|
|
85
|
+
```bash
|
|
86
|
+
tmux-ide config set rows.0.panes.1.task "Work on frontend components"
|
|
87
|
+
tmux-ide config set rows.0.panes.2.task "Work on API routes"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
4. **Validate and launch:**
|
|
91
|
+
```bash
|
|
92
|
+
tmux-ide validate --json
|
|
93
|
+
tmux-ide
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Present team layout options
|
|
97
|
+
|
|
98
|
+
When suggesting agent team layouts, show the roles:
|
|
99
|
+
|
|
100
|
+
**Option A — Lead + 2 Teammates**
|
|
101
|
+
```
|
|
102
|
+
┌───────────┬───────────┬───────────┐
|
|
103
|
+
│ │ │ │
|
|
104
|
+
│ Lead │Teammate 1 │Teammate 2 │ 70%
|
|
105
|
+
│ (claude) │ (claude) │ (claude) │
|
|
106
|
+
├───────────┴─────┬─────┴───────────┤
|
|
107
|
+
│ Dev Server │ Shell │ 30%
|
|
108
|
+
└─────────────────┴─────────────────┘
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Option B — Lead + 3 Specialized Teammates**
|
|
112
|
+
```
|
|
113
|
+
┌────────┬────────┬────────┬────────┐
|
|
114
|
+
│ │Frontend│Backend │ Review │
|
|
115
|
+
│ Lead │ Agent │ Agent │ Agent │ 70%
|
|
116
|
+
│ │ │ │ │
|
|
117
|
+
├────────┴────────┴──┬─────┴────────┤
|
|
118
|
+
│ Dev Server │ Shell │ 30%
|
|
119
|
+
└────────────────────┴──────────────┘
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Team lead self-configuration
|
|
123
|
+
|
|
124
|
+
When running as the team lead inside a tmux-ide session, you can reconfigure the team:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Read current config
|
|
128
|
+
tmux-ide config --json
|
|
129
|
+
|
|
130
|
+
# Add a new teammate pane
|
|
131
|
+
tmux-ide config add-pane --row 0 --title "Reviewer" --command "claude"
|
|
132
|
+
tmux-ide config set rows.0.panes.3.role teammate
|
|
133
|
+
tmux-ide config set rows.0.panes.3.task "Review all PRs and check for issues"
|
|
134
|
+
|
|
135
|
+
# Or remove a teammate
|
|
136
|
+
tmux-ide config remove-pane --row 0 --pane 2
|
|
137
|
+
|
|
138
|
+
# Validate and restart to apply
|
|
139
|
+
tmux-ide validate --json
|
|
140
|
+
tmux-ide restart
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Disable teams
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
tmux-ide config disable-team
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Removes the `team` config and all `role`/`task` fields from panes.
|
|
150
|
+
|
|
151
|
+
## Programmatic CLI
|
|
152
|
+
|
|
153
|
+
All commands support `--json` for structured output.
|
|
154
|
+
|
|
155
|
+
### Read commands
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
tmux-ide status --json # Session status
|
|
159
|
+
tmux-ide validate --json # Validate config
|
|
160
|
+
tmux-ide detect --json # Detect project stack
|
|
161
|
+
tmux-ide config --json # Dump config as JSON
|
|
162
|
+
tmux-ide ls --json # List sessions
|
|
163
|
+
tmux-ide doctor --json # System health check
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Write commands
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
tmux-ide detect --write # Detect and write config
|
|
170
|
+
tmux-ide config set name "my-app" # Set config value by dot path
|
|
171
|
+
tmux-ide config set rows.0.size "70%"
|
|
172
|
+
tmux-ide config add-pane --row 0 --title "Claude" --command "claude"
|
|
173
|
+
tmux-ide config remove-pane --row 1 --pane 2
|
|
174
|
+
tmux-ide config add-row --size "30%"
|
|
175
|
+
tmux-ide config enable-team --name "my-team" # Enable agent teams
|
|
176
|
+
tmux-ide config disable-team # Disable agent teams
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Session commands
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
tmux-ide # Launch (or re-launch) IDE
|
|
183
|
+
tmux-ide stop # Kill session
|
|
184
|
+
tmux-ide restart # Stop and relaunch
|
|
185
|
+
tmux-ide attach # Reattach
|
|
186
|
+
tmux-ide init # Scaffold config
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Modification workflow
|
|
190
|
+
|
|
191
|
+
1. Read: `tmux-ide config --json`
|
|
192
|
+
2. Modify: `tmux-ide config set <path> <value>` or `add-pane`/`remove-pane`
|
|
193
|
+
3. Validate: `tmux-ide validate --json`
|
|
194
|
+
|
|
195
|
+
## Best practices
|
|
196
|
+
|
|
197
|
+
- Always use `--json` for programmatic access
|
|
198
|
+
- Always run `validate --json` after config mutations
|
|
199
|
+
- Top row ~70% height for Claude panes
|
|
200
|
+
- 2-3 Claude panes in the top row (or lead + 2 teammates for teams)
|
|
201
|
+
- Dev servers + shell in the bottom row
|
|
202
|
+
- Use `detect --json` first to understand the project stack
|
|
203
|
+
- For agent teams: assign specific tasks to teammates for focused parallel work
|
|
204
|
+
- The team lead should have `focus: true` for easy access
|
|
205
|
+
|
|
206
|
+
## ide.yml format
|
|
207
|
+
|
|
208
|
+
```yaml
|
|
209
|
+
name: project-name
|
|
210
|
+
before: pnpm install # optional pre-launch hook
|
|
211
|
+
team: # optional agent team config
|
|
212
|
+
name: my-team
|
|
213
|
+
rows:
|
|
214
|
+
- size: 70%
|
|
215
|
+
panes:
|
|
216
|
+
- title: Lead
|
|
217
|
+
command: claude
|
|
218
|
+
role: lead # "lead" or "teammate"
|
|
219
|
+
focus: true
|
|
220
|
+
- title: Teammate 1
|
|
221
|
+
command: claude
|
|
222
|
+
role: teammate
|
|
223
|
+
task: "Work on frontend" # initial task for teammate
|
|
224
|
+
- title: Teammate 2
|
|
225
|
+
command: claude
|
|
226
|
+
role: teammate
|
|
227
|
+
task: "Work on backend"
|
|
228
|
+
- panes:
|
|
229
|
+
- title: Dev Server
|
|
230
|
+
command: pnpm dev
|
|
231
|
+
dir: apps/web # per-pane working directory
|
|
232
|
+
env:
|
|
233
|
+
PORT: 3000
|
|
234
|
+
- title: Shell
|
|
235
|
+
theme:
|
|
236
|
+
accent: colour75
|
|
237
|
+
border: colour238
|
|
238
|
+
```
|
package/src/attach.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { execSync } from "node:child_process";
|
|
3
|
+
import { getSessionName } from "./lib/yaml-io.js";
|
|
4
|
+
import { outputError } from "./lib/output.js";
|
|
5
|
+
|
|
6
|
+
export async function attach(targetDir, { json } = {}) {
|
|
7
|
+
const dir = resolve(targetDir ?? ".");
|
|
8
|
+
const session = getSessionName(dir);
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
execSync(`tmux has-session -t "${session}"`, { stdio: "ignore" });
|
|
12
|
+
} catch {
|
|
13
|
+
outputError(
|
|
14
|
+
`Session "${session}" is not running. Start it with: tmux-ide`,
|
|
15
|
+
"NOT_RUNNING",
|
|
16
|
+
{ json }
|
|
17
|
+
);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
execSync(`tmux attach -t "${session}"`, { stdio: "inherit" });
|
|
22
|
+
}
|