claude-code-plus-plus 0.1.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/dist/tmux.js ADDED
@@ -0,0 +1,360 @@
1
+ /**
2
+ * Tmux control utilities
3
+ */
4
+ import { execSync, spawnSync } from 'child_process';
5
+ import { writeFileSync, chmodSync } from 'fs';
6
+ export class Tmux {
7
+ sessionName;
8
+ constructor(sessionName = 'claude-pp') {
9
+ this.sessionName = sessionName;
10
+ }
11
+ /**
12
+ * Check if tmux is installed
13
+ */
14
+ static isAvailable() {
15
+ try {
16
+ execSync('which tmux', { stdio: 'ignore' });
17
+ return true;
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ }
23
+ /**
24
+ * Check if our session already exists
25
+ */
26
+ sessionExists() {
27
+ try {
28
+ execSync(`tmux has-session -t ${this.sessionName} 2>/dev/null`, { stdio: 'ignore' });
29
+ return true;
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ /**
36
+ * Kill existing session if it exists
37
+ */
38
+ killSession() {
39
+ try {
40
+ execSync(`tmux kill-session -t ${this.sessionName} 2>/dev/null`, { stdio: 'ignore' });
41
+ }
42
+ catch {
43
+ // Session didn't exist, that's fine
44
+ }
45
+ }
46
+ /**
47
+ * Create a new tmux session (detached)
48
+ * Returns the initial window/pane ID
49
+ */
50
+ createSession(startDir) {
51
+ // Kill any existing session first
52
+ this.killSession();
53
+ // Create new detached session
54
+ execSync(`tmux new-session -d -s ${this.sessionName} -c "${startDir}"`, { stdio: 'ignore' });
55
+ // Get the pane ID
56
+ const paneId = execSync(`tmux display-message -p -t ${this.sessionName} '#{pane_id}'`)
57
+ .toString()
58
+ .trim();
59
+ return paneId;
60
+ }
61
+ /**
62
+ * Split pane horizontally (left/right)
63
+ * Returns the new pane ID (right pane)
64
+ */
65
+ splitHorizontal(percentage = 50, startDir) {
66
+ const dirArg = startDir ? `-c "${startDir}"` : '';
67
+ execSync(`tmux split-window -h -t ${this.sessionName} -p ${percentage} ${dirArg}`, { stdio: 'ignore' });
68
+ // Get the new pane ID
69
+ const paneId = execSync(`tmux display-message -p -t ${this.sessionName} '#{pane_id}'`)
70
+ .toString()
71
+ .trim();
72
+ return paneId;
73
+ }
74
+ /**
75
+ * Split pane vertically (top/bottom)
76
+ * Returns the new pane ID (bottom pane)
77
+ */
78
+ splitVertical(percentage = 50, startDir) {
79
+ const dirArg = startDir ? `-c "${startDir}"` : '';
80
+ execSync(`tmux split-window -v -t ${this.sessionName} -p ${percentage} ${dirArg}`, { stdio: 'ignore' });
81
+ const paneId = execSync(`tmux display-message -p -t ${this.sessionName} '#{pane_id}'`)
82
+ .toString()
83
+ .trim();
84
+ return paneId;
85
+ }
86
+ /**
87
+ * Send keys to a specific pane
88
+ */
89
+ /**
90
+ * Send literal text to a pane (spaces and special chars preserved)
91
+ */
92
+ sendKeys(paneId, keys, enter = true) {
93
+ // Use -l for literal string to avoid interpretation issues
94
+ // Escape single quotes in the keys
95
+ const escaped = keys.replace(/'/g, "'\\''");
96
+ execSync(`tmux send-keys -t ${paneId} -l '${escaped}'`, { stdio: 'ignore' });
97
+ if (enter) {
98
+ execSync(`tmux send-keys -t ${paneId} Enter`, { stdio: 'ignore' });
99
+ }
100
+ }
101
+ /**
102
+ * Send control/special keys (e.g., C-c for Ctrl+C, Enter, Escape)
103
+ */
104
+ sendControlKey(paneId, key) {
105
+ execSync(`tmux send-keys -t ${paneId} ${key}`, { stdio: 'ignore' });
106
+ }
107
+ /**
108
+ * Run a command in a specific pane
109
+ */
110
+ runInPane(paneId, command) {
111
+ this.sendKeys(paneId, command, true);
112
+ }
113
+ /**
114
+ * Select (focus) a specific pane
115
+ */
116
+ selectPane(paneId) {
117
+ execSync(`tmux select-pane -t ${paneId}`, { stdio: 'ignore' });
118
+ }
119
+ /**
120
+ * Resize a pane
121
+ */
122
+ resizePane(paneId, width, height) {
123
+ if (width !== undefined) {
124
+ execSync(`tmux resize-pane -t ${paneId} -x ${width}`, { stdio: 'ignore' });
125
+ }
126
+ if (height !== undefined) {
127
+ execSync(`tmux resize-pane -t ${paneId} -y ${height}`, { stdio: 'ignore' });
128
+ }
129
+ }
130
+ /**
131
+ * Break a pane out to its own window (keeps it running in background)
132
+ * Returns the new window ID
133
+ */
134
+ breakPane(paneId, windowName) {
135
+ const nameArg = windowName ? `-n "${windowName}"` : '';
136
+ execSync(`tmux break-pane -d -s ${paneId} ${nameArg}`, { stdio: 'ignore' });
137
+ // Get the window ID of the broken-out pane
138
+ const windowId = execSync(`tmux display-message -p -t ${paneId} '#{window_id}'`)
139
+ .toString()
140
+ .trim();
141
+ return windowId;
142
+ }
143
+ /**
144
+ * Join a pane from another window into the current window
145
+ * Returns the new pane ID
146
+ */
147
+ joinPane(sourcePaneId, targetPaneId, horizontal = true) {
148
+ const direction = horizontal ? '-h' : '-v';
149
+ execSync(`tmux join-pane ${direction} -s ${sourcePaneId} -t ${targetPaneId}`, { stdio: 'ignore' });
150
+ // Return the source pane ID (it keeps its ID after joining)
151
+ return sourcePaneId;
152
+ }
153
+ /**
154
+ * Swap two panes
155
+ */
156
+ swapPane(paneId1, paneId2) {
157
+ execSync(`tmux swap-pane -s ${paneId1} -t ${paneId2}`, { stdio: 'ignore' });
158
+ }
159
+ /**
160
+ * Create a new pane by splitting, run a command, then break it to background
161
+ * Returns the pane ID (which persists even after breaking to background window)
162
+ */
163
+ createBackgroundPane(startDir, command) {
164
+ // Split to create new pane
165
+ const paneId = this.splitHorizontal(50, startDir);
166
+ // Run command if provided
167
+ if (command) {
168
+ this.runInPane(paneId, command);
169
+ }
170
+ // Break it to background window (keeps it running)
171
+ this.breakPane(paneId);
172
+ return paneId;
173
+ }
174
+ /**
175
+ * Bring a background pane to the foreground (swap with current right pane)
176
+ */
177
+ showPane(paneId, targetPaneId) {
178
+ this.swapPane(paneId, targetPaneId);
179
+ }
180
+ /**
181
+ * Create a new window (like a tab)
182
+ */
183
+ createWindow(name, startDir) {
184
+ const dirArg = startDir ? `-c "${startDir}"` : '';
185
+ execSync(`tmux new-window -t ${this.sessionName} -n "${name}" ${dirArg}`, { stdio: 'ignore' });
186
+ const windowId = execSync(`tmux display-message -p -t ${this.sessionName} '#{window_id}'`)
187
+ .toString()
188
+ .trim();
189
+ return windowId;
190
+ }
191
+ /**
192
+ * Select a window by index or ID
193
+ */
194
+ selectWindow(windowId) {
195
+ execSync(`tmux select-window -t ${windowId}`, { stdio: 'ignore' });
196
+ }
197
+ /**
198
+ * Rename a window
199
+ */
200
+ renameWindow(windowId, name) {
201
+ execSync(`tmux rename-window -t ${windowId} "${name}"`, { stdio: 'ignore' });
202
+ }
203
+ /**
204
+ * Kill a pane
205
+ */
206
+ killPane(paneId) {
207
+ try {
208
+ execSync(`tmux kill-pane -t ${paneId}`, { stdio: 'ignore' });
209
+ }
210
+ catch {
211
+ // Pane might already be dead
212
+ }
213
+ }
214
+ /**
215
+ * Kill a window
216
+ */
217
+ killWindow(windowId) {
218
+ try {
219
+ execSync(`tmux kill-window -t ${windowId}`, { stdio: 'ignore' });
220
+ }
221
+ catch {
222
+ // Window might already be dead
223
+ }
224
+ }
225
+ /**
226
+ * Detach the current client from the session
227
+ */
228
+ detachClient() {
229
+ try {
230
+ execSync(`tmux detach-client -s ${this.sessionName}`, { stdio: 'ignore' });
231
+ }
232
+ catch {
233
+ // Client might already be detached
234
+ }
235
+ }
236
+ /**
237
+ * Attach to the session (takes over the terminal)
238
+ * This is blocking - returns only after detach/exit
239
+ */
240
+ attach() {
241
+ // Use spawnSync to block until tmux attach exits (user detaches or session ends)
242
+ const result = spawnSync('tmux', ['attach-session', '-t', this.sessionName], {
243
+ stdio: 'inherit',
244
+ });
245
+ return result.status || 0;
246
+ }
247
+ /**
248
+ * Get list of panes in current window
249
+ */
250
+ listPanes() {
251
+ const output = execSync(`tmux list-panes -t ${this.sessionName} -F '#{pane_id},#{pane_width},#{pane_height},#{pane_active}'`).toString();
252
+ return output
253
+ .trim()
254
+ .split('\n')
255
+ .filter(Boolean)
256
+ .map((line) => {
257
+ const [id, width, height, active] = line.split(',');
258
+ return {
259
+ id,
260
+ width: parseInt(width, 10),
261
+ height: parseInt(height, 10),
262
+ active: active === '1',
263
+ };
264
+ });
265
+ }
266
+ /**
267
+ * Get list of windows
268
+ */
269
+ listWindows() {
270
+ const output = execSync(`tmux list-windows -t ${this.sessionName} -F '#{window_id},#{window_name},#{window_active}'`).toString();
271
+ return output
272
+ .trim()
273
+ .split('\n')
274
+ .filter(Boolean)
275
+ .map((line) => {
276
+ const [id, name, active] = line.split(',');
277
+ return {
278
+ id,
279
+ name,
280
+ active: active === '1',
281
+ panes: [], // Could populate with listPanes for each window if needed
282
+ };
283
+ });
284
+ }
285
+ /**
286
+ * Set a tmux option
287
+ */
288
+ setOption(option, value, global = false) {
289
+ const flag = global ? '-g' : '';
290
+ execSync(`tmux set-option ${flag} ${option} ${value}`, { stdio: 'ignore' });
291
+ }
292
+ /**
293
+ * Set a pane-specific option
294
+ */
295
+ setPaneOption(paneId, option, value) {
296
+ execSync(`tmux set-option -p -t ${paneId} ${option} ${value}`, { stdio: 'ignore' });
297
+ }
298
+ /**
299
+ * Bind a key
300
+ */
301
+ bindKey(key, command) {
302
+ execSync(`tmux bind-key ${key} ${command}`, { stdio: 'ignore' });
303
+ }
304
+ /**
305
+ * Unbind a key
306
+ */
307
+ unbindKey(table, key) {
308
+ try {
309
+ execSync(`tmux unbind-key -T ${table} ${key}`, { stdio: 'ignore' });
310
+ }
311
+ catch {
312
+ // Key might not be bound
313
+ }
314
+ }
315
+ /**
316
+ * Bind a conditional key (does different things based on pane)
317
+ */
318
+ bindConditionalKey(table, key, condition, ifTrue, ifFalse) {
319
+ const cmd = ifTrue || '""';
320
+ const elseCmd = ifFalse || '""';
321
+ execSync(`tmux bind-key -T ${table} ${key} if-shell -F "${condition}" ${cmd} ${elseCmd}`, { stdio: 'ignore' });
322
+ }
323
+ /**
324
+ * Set up a key binding to toggle sidebar width
325
+ * Binds to Ctrl+G (no prefix needed, works from any pane)
326
+ */
327
+ bindSidebarToggle(sidebarPaneId, expandedWidth, collapsedWidth) {
328
+ // Write a toggle script using Node.js (avoids shell escaping issues)
329
+ const scriptPath = `/tmp/claude-pp-toggle-${this.sessionName}.sh`;
330
+ const script = `#!/bin/bash
331
+ width=$(tmux display-message -t '${sidebarPaneId}' -p '#{pane_width}')
332
+ if [ "$width" -gt ${collapsedWidth} ]; then
333
+ tmux resize-pane -t '${sidebarPaneId}' -x ${collapsedWidth}
334
+ else
335
+ tmux resize-pane -t '${sidebarPaneId}' -x ${expandedWidth}
336
+ fi
337
+ `;
338
+ writeFileSync(scriptPath, script);
339
+ chmodSync(scriptPath, 0o755);
340
+ // Bind to Ctrl+G in root table
341
+ execSync(`tmux bind-key -T root C-g run-shell -b '${scriptPath}'`, { stdio: 'ignore' });
342
+ }
343
+ /**
344
+ * Disable scroll wheel for a specific pane, keep it for others
345
+ */
346
+ disableScrollForPane(paneId) {
347
+ // Bind wheel events to do nothing if in sidebar pane, otherwise normal behavior
348
+ const condition = `#{==:#{pane_id},${paneId}}`;
349
+ // For WheelUpPane: if sidebar, do nothing; else enter copy-mode and scroll
350
+ execSync(`tmux bind-key -T root WheelUpPane if-shell -F "${condition}" "" "copy-mode -e; send-keys -M"`, { stdio: 'ignore' });
351
+ execSync(`tmux bind-key -T root WheelDownPane if-shell -F "${condition}" "" "copy-mode -e; send-keys -M"`, { stdio: 'ignore' });
352
+ }
353
+ /**
354
+ * Get session name
355
+ */
356
+ getSessionName() {
357
+ return this.sessionName;
358
+ }
359
+ }
360
+ //# sourceMappingURL=tmux.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tmux.js","sourceRoot":"","sources":["../src/tmux.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface Worktree {
2
+ id: string;
3
+ path: string;
4
+ branch: string;
5
+ isMain: boolean;
6
+ sessions: string[];
7
+ }
8
+ export interface AppConfig {
9
+ claudeCodeCommand: string;
10
+ dangerouslySkipPermissions: boolean;
11
+ }
12
+ export declare const DEFAULT_CONFIG: AppConfig;
13
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,0BAA0B,EAAE,OAAO,CAAC;CACrC;AAED,eAAO,MAAM,cAAc,EAAE,SAG5B,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ export const DEFAULT_CONFIG = {
2
+ claudeCodeCommand: 'claude',
3
+ dangerouslySkipPermissions: true,
4
+ };
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,MAAM,cAAc,GAAc;IACvC,iBAAiB,EAAE,QAAQ;IAC3B,0BAA0B,EAAE,IAAI;CACjC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "claude-code-plus-plus",
3
+ "version": "0.1.0",
4
+ "description": "Multi-pane terminal interface for parallel Claude Code agents with git worktree isolation",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "claude++": "./dist/index.js",
9
+ "ccp": "./dist/index.js"
10
+ },
11
+ "scripts": {
12
+ "dev": "tsx src/index.ts",
13
+ "build": "tsc",
14
+ "start": "node dist/index.js",
15
+ "typecheck": "tsc --noEmit",
16
+ "prepublishOnly": "npm run build"
17
+ },
18
+ "files": [
19
+ "dist/**/*",
20
+ "assets/**/*",
21
+ "README.md",
22
+ "LICENSE"
23
+ ],
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/anthropics/claude-code-plus-plus.git"
27
+ },
28
+ "homepage": "https://github.com/anthropics/claude-code-plus-plus#readme",
29
+ "bugs": {
30
+ "url": "https://github.com/anthropics/claude-code-plus-plus/issues"
31
+ },
32
+ "author": "blitzjb",
33
+ "dependencies": {
34
+ "simple-git": "^3.27.0"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^22.10.0",
38
+ "typescript": "^5.6.0",
39
+ "tsx": "^4.19.0"
40
+ },
41
+ "engines": {
42
+ "node": ">=18.0.0"
43
+ },
44
+ "keywords": [
45
+ "claude",
46
+ "claude-code",
47
+ "ai",
48
+ "terminal",
49
+ "tui",
50
+ "tmux",
51
+ "git-worktree",
52
+ "multi-agent",
53
+ "parallel",
54
+ "coding-assistant"
55
+ ],
56
+ "license": "MIT"
57
+ }