agileflow 2.99.0 → 2.99.1
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/CHANGELOG.md +5 -0
- package/README.md +3 -3
- package/lib/dashboard-protocol.js +38 -0
- package/lib/dashboard-server.js +189 -7
- package/lib/feedback.js +35 -9
- package/lib/git-operations.js +4 -1
- package/lib/merge-operations.js +16 -0
- package/lib/progress.js +7 -6
- package/lib/session-operations.js +601 -0
- package/lib/session-switching.js +186 -0
- package/lib/template-loader.js +4 -2
- package/lib/worktree-operations.js +5 -25
- package/package.json +1 -1
- package/scripts/agileflow-configure.js +12 -0
- package/scripts/batch-pmap-loop.js +11 -4
- package/scripts/claude-tmux.sh +186 -103
- package/scripts/lib/configure-features.js +6 -4
- package/scripts/lib/configure-repair.js +11 -2
- package/scripts/lib/process-cleanup.js +9 -5
- package/scripts/obtain-context.js +5 -0
- package/scripts/session-manager.js +144 -993
- package/scripts/spawn-parallel.js +15 -11
- package/src/core/commands/configure.md +55 -0
- package/src/core/commands/serve.md +127 -0
- package/src/core/commands/session/end.md +83 -22
- package/src/core/commands/session/new.md +197 -83
|
@@ -31,6 +31,7 @@ const { c, success, warning, error, dim, bold } = require('../lib/colors');
|
|
|
31
31
|
const { getProjectRoot, getStatusPath } = require('../lib/paths');
|
|
32
32
|
const { safeReadJSON } = require('../lib/errors');
|
|
33
33
|
const { getInheritedFlags, detectParentSessionFlags } = require('../lib/flag-detection');
|
|
34
|
+
const { feedback } = require('../lib/feedback');
|
|
34
35
|
|
|
35
36
|
// Import session manager functions
|
|
36
37
|
const sessionManager = require('./session-manager');
|
|
@@ -319,15 +320,19 @@ async function spawn(args) {
|
|
|
319
320
|
console.log('');
|
|
320
321
|
}
|
|
321
322
|
|
|
323
|
+
const task = feedback.task('Creating parallel sessions', sessionsToCreate.length);
|
|
322
324
|
const createdSessions = [];
|
|
323
325
|
for (const sessionSpec of sessionsToCreate) {
|
|
326
|
+
const spinner = feedback.spinner(`Creating session: ${sessionSpec.nickname}`);
|
|
327
|
+
spinner.start();
|
|
328
|
+
|
|
324
329
|
const result = await sessionManager.createSession({
|
|
325
330
|
nickname: sessionSpec.nickname,
|
|
326
331
|
branch: sessionSpec.branch,
|
|
327
332
|
});
|
|
328
333
|
|
|
329
334
|
if (!result.success) {
|
|
330
|
-
|
|
335
|
+
spinner.fail(`Failed: ${sessionSpec.nickname} - ${result.error}`);
|
|
331
336
|
continue;
|
|
332
337
|
}
|
|
333
338
|
|
|
@@ -343,8 +348,10 @@ async function spawn(args) {
|
|
|
343
348
|
// Show what was copied
|
|
344
349
|
const copied = [...(result.envFilesCopied || []), ...(result.foldersCopied || [])];
|
|
345
350
|
const copyInfo = copied.length ? dim(` (copied: ${copied.join(', ')})`) : '';
|
|
346
|
-
|
|
351
|
+
spinner.succeed(`Session ${result.sessionId}: ${sessionSpec.nickname}${copyInfo}`);
|
|
352
|
+
task.step(`${sessionSpec.nickname}`);
|
|
347
353
|
}
|
|
354
|
+
task.complete(`Created ${createdSessions.length} sessions`);
|
|
348
355
|
|
|
349
356
|
if (createdSessions.length === 0) {
|
|
350
357
|
console.error(error('\nNo sessions were created.'));
|
|
@@ -520,17 +527,14 @@ async function addWindow(args) {
|
|
|
520
527
|
// Get window number
|
|
521
528
|
let windowIndex;
|
|
522
529
|
try {
|
|
523
|
-
windowIndex =
|
|
524
|
-
'tmux',
|
|
525
|
-
['list-windows', '-t', currentSession, '-F', '#I:#W'],
|
|
526
|
-
{
|
|
530
|
+
windowIndex =
|
|
531
|
+
execFileSync('tmux', ['list-windows', '-t', currentSession, '-F', '#I:#W'], {
|
|
527
532
|
encoding: 'utf8',
|
|
528
533
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
?.split(':')[0] || '?';
|
|
534
|
+
})
|
|
535
|
+
.split('\n')
|
|
536
|
+
.find(line => line.endsWith(`:${windowName}`))
|
|
537
|
+
?.split(':')[0] || '?';
|
|
534
538
|
} catch {
|
|
535
539
|
windowIndex = '?';
|
|
536
540
|
}
|
|
@@ -443,6 +443,61 @@ When creating new sessions with /agileflow:session:new, this will be the
|
|
|
443
443
|
recommended option. You can still choose a different mode per-session.
|
|
444
444
|
```
|
|
445
445
|
|
|
446
|
+
**If user selected "Skip permissions" or "Accept edits only"**, offer Claude settings integration:
|
|
447
|
+
|
|
448
|
+
```xml
|
|
449
|
+
<invoke name="AskUserQuestion">
|
|
450
|
+
<parameter name="questions">[{
|
|
451
|
+
"question": "Also configure Claude to default to this mode?",
|
|
452
|
+
"header": "Claude settings",
|
|
453
|
+
"multiSelect": false,
|
|
454
|
+
"options": [
|
|
455
|
+
{"label": "af wrapper only (Recommended)", "description": "The 'af' command already uses this setting. No other changes needed."},
|
|
456
|
+
{"label": "Also add shell alias", "description": "Add alias to your shell profile so 'claude' also uses this mode"},
|
|
457
|
+
{"label": "No thanks", "description": "Keep current setup"}
|
|
458
|
+
]
|
|
459
|
+
}]</parameter>
|
|
460
|
+
</invoke>
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
**If "Also add shell alias" selected:**
|
|
464
|
+
|
|
465
|
+
Determine the flag based on the selected mode:
|
|
466
|
+
- `skip-permissions` → `--dangerously-skip-permissions`
|
|
467
|
+
- `accept-edits` → `--permission-mode acceptEdits`
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
# Detect shell config file
|
|
471
|
+
SHELL_RC="$HOME/.bashrc"
|
|
472
|
+
[ -f "$HOME/.zshrc" ] && SHELL_RC="$HOME/.zshrc"
|
|
473
|
+
|
|
474
|
+
# Check if alias already exists
|
|
475
|
+
grep -q 'alias claude=' "$SHELL_RC" 2>/dev/null
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
If alias doesn't exist, add it using the Edit tool on the shell RC file:
|
|
479
|
+
```bash
|
|
480
|
+
# Append alias (idempotent - only if not already present)
|
|
481
|
+
# For skip-permissions:
|
|
482
|
+
echo 'alias claude="claude --dangerously-skip-permissions"' >> "$SHELL_RC"
|
|
483
|
+
# For accept-edits:
|
|
484
|
+
echo 'alias claude="claude --permission-mode acceptEdits"' >> "$SHELL_RC"
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
Display:
|
|
488
|
+
```
|
|
489
|
+
✅ Shell alias added to {SHELL_RC}
|
|
490
|
+
Run `source {SHELL_RC}` or open a new terminal for the alias to take effect.
|
|
491
|
+
|
|
492
|
+
To remove later: edit {SHELL_RC} and remove the 'alias claude=' line.
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
**If "af wrapper only" or "No thanks" selected:**
|
|
496
|
+
```
|
|
497
|
+
The 'af' command already reads the configured startup mode automatically.
|
|
498
|
+
No additional changes needed.
|
|
499
|
+
```
|
|
500
|
+
|
|
446
501
|
---
|
|
447
502
|
|
|
448
503
|
### If "Infrastructure" selected
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Start Dashboard WebSocket server for real-time UI communication
|
|
3
|
+
argument-hint: "[OPTIONS: --port 8765 --api-key KEY --tunnel]"
|
|
4
|
+
compact_context:
|
|
5
|
+
priority: medium
|
|
6
|
+
preserve_rules:
|
|
7
|
+
- "ACTIVE COMMAND: /agileflow:serve - Dashboard WebSocket server"
|
|
8
|
+
- "Server provides real-time communication for Cloud Dashboard"
|
|
9
|
+
- "Default port: 8765, binds to 0.0.0.0"
|
|
10
|
+
state_fields:
|
|
11
|
+
- server_running
|
|
12
|
+
- server_port
|
|
13
|
+
- tunnel_url
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# serve
|
|
17
|
+
|
|
18
|
+
Start the AgileFlow Dashboard WebSocket server for real-time communication with the Cloud Dashboard UI.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Overview
|
|
23
|
+
|
|
24
|
+
The serve command starts a WebSocket server that the AgileFlow Dashboard connects to for real-time features: chat streaming, git operations, terminal access, and automation management.
|
|
25
|
+
|
|
26
|
+
**Key Features**:
|
|
27
|
+
- **WebSocket protocol**: Real-time bidirectional communication with dashboard
|
|
28
|
+
- **Claude CLI bridge**: Streaming text deltas and tool call forwarding
|
|
29
|
+
- **Git integration**: Status, diff, commit, branch operations via WebSocket
|
|
30
|
+
- **Terminal channels**: Remote terminal sessions scoped to project directory
|
|
31
|
+
- **Automation runner**: Trigger and monitor automations from the dashboard
|
|
32
|
+
- **Auth support**: Optional API key authentication for secure connections
|
|
33
|
+
- **Tunnel support**: ngrok integration for remote access
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
### Start with Default Settings
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
/agileflow:serve
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Starts the WebSocket server on port 8765, binding to 0.0.0.0.
|
|
46
|
+
|
|
47
|
+
### Start with Custom Port and Auth
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
/agileflow:serve --port 9000 --api-key agf_secret123
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Start with Tunnel for Remote Access
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
/agileflow:serve --tunnel
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Starts ngrok tunnel for remote dashboard connections (requires ngrok installed).
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Options
|
|
64
|
+
|
|
65
|
+
| Option | Short | Default | Description |
|
|
66
|
+
|--------|-------|---------|-------------|
|
|
67
|
+
| `--port` | `-p` | `8765` | Port to listen on |
|
|
68
|
+
| `--host` | `-h` | `0.0.0.0` | Host to bind to |
|
|
69
|
+
| `--api-key` | `-k` | none | API key for authentication |
|
|
70
|
+
| `--require-auth` | | `false` | Require API key for connections |
|
|
71
|
+
| `--tunnel` | `-t` | `false` | Start ngrok tunnel |
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Prompt
|
|
76
|
+
|
|
77
|
+
ROLE: Dashboard Server Manager
|
|
78
|
+
|
|
79
|
+
Run the dashboard WebSocket server using the installed script:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
node .agileflow/scripts/dashboard-serve.js [OPTIONS]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Pass through any user-provided options** (--port, --api-key, --tunnel, etc.) directly to the script.
|
|
86
|
+
|
|
87
|
+
WORKFLOW:
|
|
88
|
+
|
|
89
|
+
1. **Start the server**:
|
|
90
|
+
```bash
|
|
91
|
+
node .agileflow/scripts/dashboard-serve.js --port 8765
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
2. **Report the connection URL** to the user:
|
|
95
|
+
- Local: `ws://localhost:<port>`
|
|
96
|
+
- If tunnel enabled: the ngrok URL
|
|
97
|
+
|
|
98
|
+
3. **Keep the server running** - it runs in the foreground. The user can stop it with Ctrl+C.
|
|
99
|
+
|
|
100
|
+
4. If the user specifies `--api-key`, pass it through:
|
|
101
|
+
```bash
|
|
102
|
+
node .agileflow/scripts/dashboard-serve.js --port 8765 --api-key agf_secret123
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
5. If the user specifies `--tunnel`, pass it through:
|
|
106
|
+
```bash
|
|
107
|
+
node .agileflow/scripts/dashboard-serve.js --tunnel
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Dashboard Connection
|
|
113
|
+
|
|
114
|
+
Once the server is running, the Cloud Dashboard connects via WebSocket:
|
|
115
|
+
|
|
116
|
+
1. Open the AgileFlow Dashboard
|
|
117
|
+
2. Enter the connection URL: `ws://localhost:8765` (or tunnel URL)
|
|
118
|
+
3. If auth is enabled, provide the API key
|
|
119
|
+
4. Dashboard receives real-time updates for chat, git, terminal, and automations
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Related Commands
|
|
124
|
+
|
|
125
|
+
- `/agileflow:api` - REST API server (read-only state exposure)
|
|
126
|
+
- `/agileflow:session:status` - View current session state
|
|
127
|
+
- `/agileflow:board` - Visual kanban board
|
|
@@ -224,22 +224,33 @@ Continue to **Merge Step 2**.
|
|
|
224
224
|
|
|
225
225
|
#### If "Commit with custom message" selected:
|
|
226
226
|
|
|
227
|
-
First,
|
|
227
|
+
First, analyze changes to suggest a meaningful commit message:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# Get changed files summary for commit message suggestion
|
|
231
|
+
git diff --stat HEAD
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Based on the files changed, generate 2-3 contextual commit message suggestions:
|
|
235
|
+
- Examine which directories/files changed to determine the type (feat/fix/chore/docs)
|
|
236
|
+
- Read the diff summary to understand what was modified
|
|
237
|
+
- Suggest messages that describe the "why" not just the "what"
|
|
238
|
+
|
|
228
239
|
```
|
|
229
240
|
AskUserQuestion:
|
|
230
|
-
question: "
|
|
241
|
+
question: "Choose or customize your commit message:"
|
|
231
242
|
header: "Commit message"
|
|
232
243
|
multiSelect: false
|
|
233
244
|
options:
|
|
234
|
-
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
245
|
+
# 2-3 suggestions based on git diff analysis. Examples:
|
|
246
|
+
# - label: "feat: add OAuth support for session auth"
|
|
247
|
+
# description: "Based on changes to auth/ files"
|
|
248
|
+
# - label: "fix: resolve merge conflict in config"
|
|
249
|
+
# description: "Based on config file changes"
|
|
250
|
+
# Always include at least one option. User can select "Other" for custom.
|
|
240
251
|
```
|
|
241
252
|
|
|
242
|
-
The user will select "Other" to enter a custom message. Then:
|
|
253
|
+
The user will select a suggestion or "Other" to enter a custom message. Then:
|
|
243
254
|
|
|
244
255
|
```bash
|
|
245
256
|
node .agileflow/scripts/session-manager.js commit-changes {session_id} --message="{user_message}"
|
|
@@ -342,26 +353,42 @@ From the `check-merge` response, check `hasConflicts`:
|
|
|
342
353
|
|
|
343
354
|
If `hasConflicts: true`:
|
|
344
355
|
|
|
356
|
+
First, get detailed conflict info:
|
|
357
|
+
```bash
|
|
358
|
+
# Get list of files that conflict (without actually merging)
|
|
359
|
+
git merge --no-commit --no-ff {branchName} 2>&1 || true
|
|
360
|
+
git diff --name-only --diff-filter=U
|
|
361
|
+
git merge --abort
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Display specific files with context:
|
|
345
365
|
```
|
|
346
|
-
⚠️ Merge conflicts detected
|
|
366
|
+
⚠️ Merge conflicts detected in {N} file(s):
|
|
347
367
|
|
|
348
|
-
|
|
368
|
+
{file1} - Both branches modified
|
|
369
|
+
{file2} - Conflicting changes
|
|
370
|
+
{file3} - Both added content (likely auto-resolvable)
|
|
349
371
|
```
|
|
350
372
|
|
|
351
|
-
|
|
373
|
+
Analyze the conflicting files to make a smart recommendation:
|
|
374
|
+
- If ALL conflicts are in docs/config files → recommend "Auto-resolve"
|
|
375
|
+
- If conflicts include source code → recommend "Review first, then auto-resolve"
|
|
376
|
+
- Count files by category (docs, tests, config, source) for the description
|
|
377
|
+
|
|
378
|
+
Then present AI-recommended options:
|
|
352
379
|
|
|
353
380
|
```
|
|
354
381
|
AskUserQuestion:
|
|
355
|
-
question: "How
|
|
356
|
-
header: "
|
|
382
|
+
question: "How to handle {N} conflicting file(s)?"
|
|
383
|
+
header: "Conflicts"
|
|
357
384
|
multiSelect: false
|
|
358
385
|
options:
|
|
359
|
-
- label: "
|
|
360
|
-
description: "
|
|
361
|
-
- label: "
|
|
362
|
-
description: "
|
|
363
|
-
- label: "
|
|
364
|
-
description: "
|
|
386
|
+
- label: "{AI recommended option} (Recommended)"
|
|
387
|
+
description: "{reason based on conflict analysis - e.g., 'All conflicts are in docs/config - safe to auto-resolve'}"
|
|
388
|
+
- label: "Auto-resolve all"
|
|
389
|
+
description: "Smart merge resolves by file type (docs=accept_both, source=theirs, config=ours)"
|
|
390
|
+
- label: "Keep session, resolve manually"
|
|
391
|
+
description: "Stay in session and fix conflicts yourself"
|
|
365
392
|
- label: "Cancel"
|
|
366
393
|
description: "Keep session as-is"
|
|
367
394
|
```
|
|
@@ -490,6 +517,29 @@ Summary:
|
|
|
490
517
|
💡 To push your changes: git push
|
|
491
518
|
```
|
|
492
519
|
|
|
520
|
+
### Post-Merge: Notify Other Sessions
|
|
521
|
+
|
|
522
|
+
After successful merge, check if in tmux and send notification:
|
|
523
|
+
|
|
524
|
+
```bash
|
|
525
|
+
# Check if in tmux
|
|
526
|
+
echo $TMUX
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
If in tmux:
|
|
530
|
+
```bash
|
|
531
|
+
# Send visible notification to all windows
|
|
532
|
+
tmux display-message -d 5000 "Session {id} merged to {mainBranch} - changes are live"
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
Display to user:
|
|
536
|
+
```
|
|
537
|
+
The main branch working directory ({mainPath}) now has your merged changes.
|
|
538
|
+
If you have a Claude session on main, its files are already updated.
|
|
539
|
+
|
|
540
|
+
To push to remote: git push
|
|
541
|
+
```
|
|
542
|
+
|
|
493
543
|
Then proceed to **Step 4: Offer to Close Tab**.
|
|
494
544
|
|
|
495
545
|
If failed:
|
|
@@ -613,7 +663,7 @@ If `reason: "uncommitted_changes"` → Show inline options (5 choices):
|
|
|
613
663
|
|
|
614
664
|
**Step 1a: Handle uncommitted choice**
|
|
615
665
|
- "Commit all": `node .agileflow/scripts/session-manager.js commit-changes {id}` → continue
|
|
616
|
-
- "Commit custom":
|
|
666
|
+
- "Commit custom": Analyze `git diff --stat`, suggest 2-3 contextual messages → `commit-changes {id} --message="..."` → continue
|
|
617
667
|
- "Stash": `node .agileflow/scripts/session-manager.js stash {id}` → continue (unstash after merge)
|
|
618
668
|
- "Discard": `node .agileflow/scripts/session-manager.js discard-changes {id}` → continue
|
|
619
669
|
- "Cancel": EXIT
|
|
@@ -625,7 +675,11 @@ node .agileflow/scripts/session-manager.js merge-preview {session_id}
|
|
|
625
675
|
Display commits and files to be merged.
|
|
626
676
|
|
|
627
677
|
**Step 3: Check conflicts**
|
|
628
|
-
If `hasConflicts: true
|
|
678
|
+
If `hasConflicts: true`:
|
|
679
|
+
- Get detailed file list: `git merge --no-commit --no-ff {branch}`, `git diff --name-only --diff-filter=U`, `git merge --abort`
|
|
680
|
+
- Display per-file conflict details
|
|
681
|
+
- Analyze file types to recommend best option (docs/config → auto-resolve, source → review)
|
|
682
|
+
- Show conflict options with AI recommendation first (auto-resolve/manual/cancel)
|
|
629
683
|
|
|
630
684
|
**Step 3a: If auto-resolve selected**
|
|
631
685
|
```bash
|
|
@@ -681,6 +735,12 @@ node .agileflow/scripts/session-manager.js integrate {id} --strategy={squash|mer
|
|
|
681
735
|
💡 To push: git push
|
|
682
736
|
```
|
|
683
737
|
|
|
738
|
+
**Step 7a: Notify other sessions (if in tmux)**
|
|
739
|
+
```bash
|
|
740
|
+
tmux display-message -d 5000 "Session {id} merged to {mainBranch} - changes are live"
|
|
741
|
+
```
|
|
742
|
+
Display: "Main branch working directory now has your merged changes."
|
|
743
|
+
|
|
684
744
|
---
|
|
685
745
|
|
|
686
746
|
### 🚨 RULE #4: HANDLE OTHER OPTIONS
|
|
@@ -761,6 +821,7 @@ tmux kill-window
|
|
|
761
821
|
g. Execute integrate
|
|
762
822
|
h. If stash was used → unstash on main
|
|
763
823
|
i. Show success with cd command
|
|
824
|
+
j. If in tmux → notify other sessions via tmux display-message
|
|
764
825
|
5. If end/delete → Execute and show result
|
|
765
826
|
6. If in tmux → Offer to close tab
|
|
766
827
|
```
|