workon 1.3.0 → 2.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.
@@ -0,0 +1,396 @@
1
+ # ADR-002: Positional Command Arguments
2
+
3
+ **Status:** Proposed
4
+ **Date:** 2025-08-06
5
+ **Deciders:** Israel Roldan
6
+ **Related:** ADR-001 (Command-Centric Architecture)
7
+
8
+ ## Context
9
+
10
+ Currently, the workon CLI operates with a "all-or-nothing" approach where running `workon my-project` executes all configured events for that project. However, there are scenarios where users want to execute only specific commands for a project.
11
+
12
+ ### Current Behavior
13
+ ```bash
14
+ workon my-project # Executes ALL configured events (cwd, ide, claude, npm, etc.)
15
+ ```
16
+
17
+ ### Desired Behavior
18
+ ```bash
19
+ workon my-project # Executes all configured events (current behavior)
20
+ workon my-project cwd # Only changes to project directory
21
+ workon my-project claude # Only opens Claude in project directory
22
+ workon my-project npm # Only runs npm command
23
+ workon my-project cwd claude # Runs cwd + claude (split terminal)
24
+ ```
25
+
26
+ ## Problems with Current Approach
27
+
28
+ 1. **Inflexibility**: Can't run individual commands without modifying project configuration
29
+ 2. **Performance**: Sometimes you don't want to start dev server, just open Claude
30
+ 3. **Workflow Mismatch**: Different workflows need different command combinations
31
+ 4. **Resource Usage**: Starting all services when you only need one is wasteful
32
+
33
+ ### Common Use Cases
34
+
35
+ - **Quick directory change**: `workon my-project cwd`
36
+ - **AI assistance only**: `workon my-project claude`
37
+ - **Development startup**: `workon my-project cwd claude npm`
38
+ - **IDE-only launch**: `workon my-project ide`
39
+ - **Terminal + build**: `workon my-project cwd npm`
40
+
41
+ ## Decision
42
+
43
+ Implement **positional command arguments** that allow users to specify which commands to execute for a project, while maintaining backward compatibility with the current "execute all" behavior.
44
+
45
+ ## Proposed Implementation
46
+
47
+ ### 1. CLI Argument Structure
48
+
49
+ ```bash
50
+ workon <project> [command1] [command2] [...commandN] [options]
51
+ ```
52
+
53
+ **Examples:**
54
+ ```bash
55
+ workon my-project # All configured events
56
+ workon my-project cwd # Just directory change
57
+ workon my-project claude # Just Claude
58
+ workon my-project cwd claude # Directory + Claude
59
+ workon my-project cwd claude npm # Full development setup
60
+ workon my-project ide --shell # IDE with shell output
61
+ ```
62
+
63
+ ### 2. Argument Parsing Logic
64
+
65
+ ```javascript
66
+ // Enhanced argument parsing
67
+ class ProjectArgumentParser {
68
+ static parse(args) {
69
+ const projectName = args[0];
70
+ const commands = args.slice(1).filter(arg => !arg.startsWith('--'));
71
+ const flags = args.slice(1).filter(arg => arg.startsWith('--'));
72
+
73
+ return {
74
+ projectName,
75
+ commands: commands.length > 0 ? commands : null, // null means "all configured"
76
+ flags
77
+ };
78
+ }
79
+
80
+ static validate(projectName, commands, projectConfig) {
81
+ // Validate that requested commands are configured for the project
82
+ const configuredEvents = Object.keys(projectConfig.events || {});
83
+ const invalidCommands = commands.filter(cmd => !configuredEvents.includes(cmd));
84
+
85
+ if (invalidCommands.length > 0) {
86
+ throw new Error(`Commands not configured for project '${projectName}': ${invalidCommands.join(', ')}`);
87
+ }
88
+ }
89
+ }
90
+ ```
91
+
92
+ ### 3. Execution Logic
93
+
94
+ ```javascript
95
+ // cli/open.js - Enhanced execution
96
+ class open extends command {
97
+ async processProject(project, requestedCommands = null) {
98
+ const projectConfig = this.getProjectConfig(project);
99
+ const configuredEvents = Object.keys(projectConfig.events || {});
100
+
101
+ // Determine which events to execute
102
+ let eventsToExecute;
103
+ if (requestedCommands) {
104
+ // Validate requested commands are configured
105
+ this.validateRequestedCommands(requestedCommands, configuredEvents, project);
106
+ eventsToExecute = requestedCommands;
107
+ } else {
108
+ // Execute all configured events (current behavior)
109
+ eventsToExecute = configuredEvents.filter(e => projectConfig.events[e]);
110
+ }
111
+
112
+ await this.executeEvents(projectConfig, eventsToExecute);
113
+ }
114
+
115
+ validateRequestedCommands(requested, configured, projectName) {
116
+ const invalid = requested.filter(cmd => !configured.includes(cmd));
117
+ if (invalid.length > 0) {
118
+ throw new Error(
119
+ `Commands not configured for project '${projectName}': ${invalid.join(', ')}\n` +
120
+ `Available commands: ${configured.join(', ')}`
121
+ );
122
+ }
123
+ }
124
+ }
125
+ ```
126
+
127
+ ### 4. Smart Layout Detection
128
+
129
+ The intelligent layout detection from ADR-001 would work with positional arguments:
130
+
131
+ ```javascript
132
+ // Layout detection based on actual commands being executed
133
+ const layoutDetection = {
134
+ determineLayout(executedCommands, projectConfig) {
135
+ const hasCwd = executedCommands.includes('cwd');
136
+ const hasClaude = executedCommands.includes('claude');
137
+ const hasNpm = executedCommands.includes('npm');
138
+
139
+ if (hasCwd && hasClaude && hasNpm) {
140
+ return 'three-pane'; // Claude + Terminal + NPM
141
+ } else if (hasCwd && hasNpm) {
142
+ return 'two-pane-npm'; // Terminal + NPM
143
+ } else if (hasCwd && hasClaude) {
144
+ return 'two-pane-claude'; // Claude + Terminal
145
+ } else {
146
+ return 'individual'; // Execute commands individually
147
+ }
148
+ }
149
+ };
150
+ ```
151
+
152
+ ### 5. Help and Discovery
153
+
154
+ Enhanced help system that shows available commands per project:
155
+
156
+ ```bash
157
+ workon my-project --help
158
+ # Output:
159
+ # Available commands for 'my-project':
160
+ # cwd - Change to project directory
161
+ # claude - Open Claude Code with --resume flag
162
+ # npm - Run 'npm run dev'
163
+ # ide - Open in VS Code
164
+ #
165
+ # Usage:
166
+ # workon my-project [command1] [command2] ...
167
+ #
168
+ # Examples:
169
+ # workon my-project cwd claude # Split terminal with Claude
170
+ # workon my-project npm # Just start dev server
171
+ ```
172
+
173
+ ## Integration with ADR-001
174
+
175
+ This feature complements the Command-Centric Architecture:
176
+
177
+ ### Command Interface Extension
178
+ ```javascript
179
+ class NPMCommand {
180
+ static metadata = {
181
+ name: 'npm',
182
+ displayName: 'Run NPM command',
183
+ canRunIndividually: true, // Can be executed alone
184
+ requiresProject: true, // Needs project context
185
+ dependencies: ['npm']
186
+ }
187
+
188
+ static help = {
189
+ shortDescription: 'Run npm scripts',
190
+ individualUsage: 'workon <project> npm',
191
+ examples: [
192
+ 'workon my-app npm # Run configured npm script',
193
+ 'workon my-app cwd npm # Terminal + npm in split'
194
+ ]
195
+ }
196
+ }
197
+ ```
198
+
199
+ ### Enhanced Command Registry
200
+ ```javascript
201
+ class CommandRegistry {
202
+ static getAvailableCommandsForProject(projectConfig) {
203
+ const configuredEvents = Object.keys(projectConfig.events || {});
204
+ return configuredEvents.map(eventName => {
205
+ const command = this.getCommandByName(eventName);
206
+ return {
207
+ name: eventName,
208
+ description: command.metadata.displayName,
209
+ canRunIndividually: command.metadata.canRunIndividually
210
+ };
211
+ });
212
+ }
213
+ }
214
+ ```
215
+
216
+ ## Implementation Challenges
217
+
218
+ ### 1. Argument Parsing Complexity
219
+ **Challenge**: Distinguishing between project names and commands
220
+ ```bash
221
+ workon claude my-project # Project named 'claude' or command 'claude' on 'my-project'?
222
+ ```
223
+
224
+ **Solution**: Commands are always positional after project name:
225
+ ```bash
226
+ workon my-project claude # ✅ Clear: project 'my-project', command 'claude'
227
+ workon claude # ✅ Clear: project 'claude', no specific commands
228
+ ```
229
+
230
+ ### 2. Command Validation
231
+ **Challenge**: What if user requests a command that's not configured?
232
+
233
+ **Options:**
234
+ - **Strict**: Error if command not configured
235
+ - **Permissive**: Execute if command exists, ignore configuration
236
+ - **Hybrid**: Warn but execute if possible
237
+
238
+ **Recommendation**: Start strict, add permissive mode with flag later.
239
+
240
+ ### 3. Backward Compatibility
241
+ **Challenge**: Ensure existing usage patterns continue to work
242
+
243
+ **Solution**: No commands specified = execute all (current behavior)
244
+ ```bash
245
+ workon my-project # Still works as before
246
+ workon my-project --shell # Still works as before
247
+ ```
248
+
249
+ ### 4. Complex Command Interactions
250
+ **Challenge**: Some commands have dependencies or conflicts
251
+
252
+ **Examples:**
253
+ - `claude` without `cwd` - should we auto-add `cwd`?
254
+ - `npm` without `cwd` - doesn't make sense
255
+
256
+ **Solution**: Command dependency resolution:
257
+ ```javascript
258
+ class CommandDependencyResolver {
259
+ static resolve(requestedCommands, projectConfig) {
260
+ const resolved = [...requestedCommands];
261
+
262
+ // Auto-add dependencies
263
+ if (requestedCommands.includes('npm') && !requestedCommands.includes('cwd')) {
264
+ resolved.unshift('cwd'); // npm needs cwd
265
+ }
266
+
267
+ if (requestedCommands.includes('claude') && !requestedCommands.includes('cwd')) {
268
+ resolved.unshift('cwd'); // claude needs cwd
269
+ }
270
+
271
+ return resolved;
272
+ }
273
+ }
274
+ ```
275
+
276
+ ## User Experience Design
277
+
278
+ ### 1. Intuitive Command Discovery
279
+ ```bash
280
+ workon my-project help # Show available commands for this project
281
+ workon help commands # Show all available command types
282
+ workon --list-projects # Show all projects with their commands
283
+ ```
284
+
285
+ ### 2. Smart Defaults
286
+ ```bash
287
+ workon my-project claude # Automatically includes 'cwd' dependency
288
+ workon my-project npm # Automatically includes 'cwd' dependency
289
+ ```
290
+
291
+ ### 3. Error Messages
292
+ ```bash
293
+ workon my-project invalid-cmd
294
+ # Error: Command 'invalid-cmd' not configured for project 'my-project'
295
+ # Available commands: cwd, claude, npm, ide
296
+ #
297
+ # Tip: Run 'workon my-project help' for more details
298
+ ```
299
+
300
+ ## Implementation Plan
301
+
302
+ ### Phase 1: Argument Parsing Foundation
303
+ 1. Implement `ProjectArgumentParser` class
304
+ 2. Update CLI entry point to handle positional arguments
305
+ 3. Add backward compatibility tests
306
+ 4. Basic command validation
307
+
308
+ ### Phase 2: Command Execution Logic
309
+ 1. Update `open.js` to handle selective command execution
310
+ 2. Implement dependency resolution system
311
+ 3. Add error handling and user-friendly messages
312
+ 4. Update help system
313
+
314
+ ### Phase 3: Layout Integration
315
+ 1. Update smart layout detection for positional commands
316
+ 2. Ensure tmux layouts work with partial command sets
317
+ 3. Add fallback behavior for unsupported combinations
318
+
319
+ ### Phase 4: Enhanced UX
320
+ 1. Add command discovery helpers
321
+ 2. Implement auto-completion support
322
+ 3. Add command validation with helpful suggestions
323
+ 4. Enhanced help and documentation
324
+
325
+ ## Success Criteria
326
+
327
+ 1. **Backward Compatibility**: `workon my-project` works exactly as before
328
+ 2. **Individual Commands**: `workon my-project cwd` only changes directory
329
+ 3. **Command Combinations**: `workon my-project cwd claude` creates split terminal
330
+ 4. **Error Handling**: Clear messages for invalid command combinations
331
+ 5. **Help System**: Users can discover available commands per project
332
+ 6. **Performance**: Single commands execute faster than full project setup
333
+
334
+ ## Examples
335
+
336
+ ### Basic Usage
337
+ ```bash
338
+ # Current behavior preserved
339
+ workon my-app # All configured events
340
+
341
+ # New individual command usage
342
+ workon my-app cwd # Just cd to directory
343
+ workon my-app claude # Just open Claude (with auto cwd)
344
+ workon my-app ide # Just open IDE
345
+ workon my-app npm # Just run npm script (with auto cwd)
346
+ ```
347
+
348
+ ### Advanced Combinations
349
+ ```bash
350
+ # Custom combinations
351
+ workon my-app cwd claude # Split terminal: Claude + shell
352
+ workon my-app cwd npm # Split terminal: shell + npm
353
+ workon my-app cwd claude npm # Three-pane: Claude + shell + npm
354
+ workon my-app ide claude # IDE + Claude (no terminal)
355
+ ```
356
+
357
+ ### Shell Mode
358
+ ```bash
359
+ # Shell mode with positional args
360
+ workon my-app cwd --shell # Just outputs: cd "/path/to/project"
361
+ workon my-app cwd claude --shell # Outputs tmux split commands
362
+ ```
363
+
364
+ ## Benefits
365
+
366
+ ### For Users
367
+ - **Flexibility**: Run only what you need
368
+ - **Performance**: Faster startup for individual commands
369
+ - **Workflow Optimization**: Match commands to specific use cases
370
+ - **Resource Efficiency**: Don't start unnecessary services
371
+
372
+ ### For Development
373
+ - **Testing**: Easier to test individual commands
374
+ - **Debugging**: Isolate issues to specific commands
375
+ - **Modularity**: Commands become more independent
376
+
377
+ ### For Future Features
378
+ - **Command Aliases**: `workon my-app dev` → `workon my-app cwd claude npm`
379
+ - **Profiles**: Save common command combinations
380
+ - **Conditional Logic**: Run commands based on project state
381
+
382
+ ## Risks and Mitigations
383
+
384
+ ### Risk: User Confusion
385
+ **Mitigation**: Clear documentation, intuitive defaults, helpful error messages
386
+
387
+ ### Risk: Complex Dependency Resolution
388
+ **Mitigation**: Start simple, add complexity incrementally, clear logging
389
+
390
+ ### Risk: Breaking Changes
391
+ **Mitigation**: Maintain backward compatibility, opt-in behavior
392
+
393
+ ### Risk: Command Conflicts
394
+ **Mitigation**: Define clear command interaction rules, validation system
395
+
396
+ This ADR provides a comprehensive plan for adding positional command arguments while maintaining the project's usability and setting the foundation for even more flexible workflow management.
package/docs/ideas.md CHANGED
@@ -2,86 +2,92 @@
2
2
 
3
3
  This document contains ideas for future enhancements to the workon project.
4
4
 
5
- ## Interactive Project Management
5
+ ## NPM Command Integration
6
6
 
7
- ### Project Configuration Editor
8
- Create an interactive mode for editing project configurations through guided prompts instead of manual file editing.
7
+ ### Three-Pane Development Layout
8
+ When `cwd`, `claude`, and `npm` events are enabled, create a three-pane tmux layout:
9
+ - **Left pane**: Claude Code running in project directory (full height)
10
+ - **Top-right pane**: Shell terminal in project directory
11
+ - **Bottom-right pane**: NPM command running (e.g., `npm run dev`, `npm test`)
9
12
 
10
- **Features:**
11
- - Interactive project creation wizard with step-by-step guidance
12
- - Edit existing project properties (name, path, IDE, events) through prompts
13
- - Validate project paths and IDE commands during configuration
14
- - Preview configuration changes before saving
15
- - Bulk operations for managing multiple projects
16
-
17
- **Implementation considerations:**
18
- - Extend existing inquirer-based interactive system
19
- - Add new command like `workon config` or `workon manage --interactive`
20
- - Provide different flows for:
21
- - Creating new projects
22
- - Editing existing projects
23
- - Bulk project management
24
- - Include validation for:
25
- - Directory paths existence
26
- - IDE command availability
27
- - Event configuration correctness
28
-
29
- **Benefits:**
30
- - Lower barrier to entry for new users
31
- - Reduced configuration errors through validation
32
- - More discoverable project management features
33
- - Better UX compared to manual JSON editing
34
-
35
- ## Enhanced Events
13
+ **Implementation approach:**
14
+ - Extend current split terminal to support three panes
15
+ - Create initial vertical split (Claude | Terminal)
16
+ - Split the right terminal pane horizontally (Terminal | npm)
17
+ - Use tmux: `split-window -v` on the right pane
18
+ - Auto-run specified npm command in bottom-right pane
36
19
 
37
- ### Advanced claude Event Options ✅ IMPLEMENTED
38
- The claude event now supports advanced configuration options:
20
+ **Configuration:**
39
21
  ```json
40
- "claude": {
41
- "flags": ["--resume", "--debug"]
22
+ {
23
+ "events": {
24
+ "cwd": "true",
25
+ "claude": {
26
+ "flags": ["--resume"],
27
+ "split_terminal": true
28
+ },
29
+ "npm": "dev"
30
+ }
42
31
  }
43
32
  ```
44
33
 
45
- **Available through:** `workon manage` → Configure advanced Claude options
46
-
47
- ### Split Terminal with Claude + CWD
48
- When both `claude` and `cwd` events are enabled, automatically create a split terminal layout:
49
- - **Left pane**: Claude Code running in project directory
50
- - **Right pane**: Shell terminal in project directory
51
-
52
- **Implementation approach:**
53
- - Use tmux to create split session
54
- - Detect when both events are present
55
- - Create session: `tmux new-session -d -s "workon-{project}"`
56
- - Split horizontally: `tmux split-window -h`
57
- - Run claude in left pane, shell in right pane
58
- - Attach to session
59
-
60
- **Configuration:**
34
+ **Alternative configuration:**
61
35
  ```json
62
- "claude": {
63
- "flags": ["--resume"],
64
- "split_terminal": true
36
+ {
37
+ "events": {
38
+ "cwd": "true",
39
+ "claude": "true",
40
+ "npm": {
41
+ "command": "dev",
42
+ "watch": true,
43
+ "auto_restart": false
44
+ }
45
+ }
65
46
  }
66
47
  ```
67
48
 
68
49
  **Benefits:**
69
- - Claude and terminal side-by-side for optimal workflow
70
- - Easy switching between AI assistance and command execution
71
- - Persistent session that can be reattached
50
+ - Complete development environment in one tmux session
51
+ - Claude AI + Terminal + Development server all visible
52
+ - Perfect for web development workflows
53
+ - Automatic npm script execution
72
54
 
73
- ### Future claude Event Enhancements
74
- Additional options that could be implemented:
75
- ```json
76
- "claude": {
77
- "flags": ["--resume"],
78
- "mode": "interactive",
79
- "project_context": true,
80
- "working_directory": "src/",
81
- "tmux_layout": "even-horizontal"
82
- }
55
+ **Tmux Layout:**
56
+ ```
57
+ ┌──────────────┬──────────────┐
58
+ │ │ Terminal │
59
+ │ Claude ├──────────────┤
60
+ │ (full │ npm run dev │
61
+ │ height) │ │
62
+ └──────────────┴──────────────┘
63
+ ```
64
+
65
+ ### Two-Pane Terminal + NPM Layout
66
+ When `cwd` and `npm` events are enabled (without Claude), create a two-pane tmux layout:
67
+ - **Left pane**: Shell terminal in project directory
68
+ - **Right pane**: NPM command running (e.g., `npm run dev`, `npm test`)
69
+
70
+ **Tmux Layout:**
71
+ ```
72
+ ┌──────────────┬──────────────┐
73
+ │ │ │
74
+ │ Terminal │ npm run dev │
75
+ │ │ │
76
+ │ │ │
77
+ └──────────────┴──────────────┘
83
78
  ```
84
79
 
80
+ **Use cases:**
81
+ - Traditional development workflow without AI assistance
82
+ - Monitoring build output while running commands
83
+ - Side-by-side terminal and dev server
84
+
85
85
  ## Future Ideas
86
86
 
87
+ ### Auto-enable Split Terminal
88
+ When both `cwd` and `claude` events are enabled, automatically enable split terminal mode without requiring explicit configuration.
89
+
90
+ ### Project Templates
91
+ Pre-configured project templates for common development stacks (React, Node.js, Python, etc.) with appropriate events and npm commands.
92
+
87
93
  *Add more ideas here as they come up...*
package/lib/tmux.js CHANGED
@@ -62,6 +62,53 @@ class TmuxManager {
62
62
  return sessionName;
63
63
  }
64
64
 
65
+ async createThreePaneSession(projectName, projectPath, claudeArgs = [], npmCommand = 'npm run dev') {
66
+ const sessionName = this.getSessionName(projectName);
67
+
68
+ // Kill existing session if it exists
69
+ if (await this.sessionExists(sessionName)) {
70
+ await this.killSession(sessionName);
71
+ }
72
+
73
+ const claudeCommand = claudeArgs.length > 0
74
+ ? `claude ${claudeArgs.join(' ')}`
75
+ : 'claude';
76
+
77
+ // Create new tmux session with claude in the first pane (left side)
78
+ await exec(`tmux new-session -d -s "${sessionName}" -c "${projectPath}" '${claudeCommand}'`);
79
+
80
+ // Split window vertically - creates right side
81
+ await exec(`tmux split-window -h -t "${sessionName}" -c "${projectPath}"`);
82
+
83
+ // Split the right pane horizontally - creates top-right and bottom-right
84
+ await exec(`tmux split-window -v -t "${sessionName}:0.1" -c "${projectPath}" '${npmCommand}'`);
85
+
86
+ // Set focus on claude pane (left pane)
87
+ await exec(`tmux select-pane -t "${sessionName}:0.0"`);
88
+
89
+ return sessionName;
90
+ }
91
+
92
+ async createTwoPaneNpmSession(projectName, projectPath, npmCommand = 'npm run dev') {
93
+ const sessionName = this.getSessionName(projectName);
94
+
95
+ // Kill existing session if it exists
96
+ if (await this.sessionExists(sessionName)) {
97
+ await this.killSession(sessionName);
98
+ }
99
+
100
+ // Create new tmux session with shell in the first pane (left side)
101
+ await exec(`tmux new-session -d -s "${sessionName}" -c "${projectPath}"`);
102
+
103
+ // Split window vertically and run npm command in right pane
104
+ await exec(`tmux split-window -h -t "${sessionName}" -c "${projectPath}" '${npmCommand}'`);
105
+
106
+ // Set focus on terminal pane (left pane)
107
+ await exec(`tmux select-pane -t "${sessionName}:0.0"`);
108
+
109
+ return sessionName;
110
+ }
111
+
65
112
  async attachToSession(sessionName) {
66
113
  // Check if we're already in a tmux session
67
114
  if (process.env.TMUX) {
@@ -93,6 +140,40 @@ class TmuxManager {
93
140
  ];
94
141
  }
95
142
 
143
+ buildThreePaneShellCommands(projectName, projectPath, claudeArgs = [], npmCommand = 'npm run dev') {
144
+ const sessionName = this.getSessionName(projectName);
145
+ const claudeCommand = claudeArgs.length > 0
146
+ ? `claude ${claudeArgs.join(' ')}`
147
+ : 'claude';
148
+
149
+ return [
150
+ `# Create tmux three-pane session for ${projectName}`,
151
+ `tmux has-session -t "${sessionName}" 2>/dev/null && tmux kill-session -t "${sessionName}"`,
152
+ `tmux new-session -d -s "${sessionName}" -c "${projectPath}" '${claudeCommand}'`,
153
+ `tmux split-window -h -t "${sessionName}" -c "${projectPath}"`,
154
+ `tmux split-window -v -t "${sessionName}:0.1" -c "${projectPath}" '${npmCommand}'`,
155
+ `tmux select-pane -t "${sessionName}:0.0"`,
156
+ process.env.TMUX
157
+ ? `tmux switch-client -t "${sessionName}"`
158
+ : `tmux attach-session -t "${sessionName}"`
159
+ ];
160
+ }
161
+
162
+ buildTwoPaneNpmShellCommands(projectName, projectPath, npmCommand = 'npm run dev') {
163
+ const sessionName = this.getSessionName(projectName);
164
+
165
+ return [
166
+ `# Create tmux two-pane session with npm for ${projectName}`,
167
+ `tmux has-session -t "${sessionName}" 2>/dev/null && tmux kill-session -t "${sessionName}"`,
168
+ `tmux new-session -d -s "${sessionName}" -c "${projectPath}"`,
169
+ `tmux split-window -h -t "${sessionName}" -c "${projectPath}" '${npmCommand}'`,
170
+ `tmux select-pane -t "${sessionName}:0.0"`,
171
+ process.env.TMUX
172
+ ? `tmux switch-client -t "${sessionName}"`
173
+ : `tmux attach-session -t "${sessionName}"`
174
+ ];
175
+ }
176
+
96
177
  async listWorkonSessions() {
97
178
  try {
98
179
  const { stdout } = await exec('tmux list-sessions -F "#{session_name}"');