agileflow 3.4.2 → 3.4.3

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.
Files changed (37) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +2 -2
  3. package/lib/drivers/claude-driver.ts +1 -1
  4. package/lib/lazy-require.js +1 -1
  5. package/package.json +1 -1
  6. package/scripts/agent-loop.js +290 -230
  7. package/scripts/check-sessions.js +116 -0
  8. package/scripts/lib/quality-gates.js +35 -8
  9. package/scripts/lib/signal-detectors.js +0 -13
  10. package/scripts/lib/team-events.js +1 -1
  11. package/scripts/lib/tmux-audit-monitor.js +2 -1
  12. package/src/core/commands/ads/audit.md +19 -3
  13. package/src/core/commands/code/accessibility.md +22 -6
  14. package/src/core/commands/code/api.md +22 -6
  15. package/src/core/commands/code/architecture.md +22 -6
  16. package/src/core/commands/code/completeness.md +22 -6
  17. package/src/core/commands/code/legal.md +22 -6
  18. package/src/core/commands/code/logic.md +22 -6
  19. package/src/core/commands/code/performance.md +22 -6
  20. package/src/core/commands/code/security.md +22 -6
  21. package/src/core/commands/code/test.md +22 -6
  22. package/src/core/commands/ideate/features.md +5 -4
  23. package/src/core/commands/ideate/new.md +8 -7
  24. package/src/core/commands/seo/audit.md +21 -5
  25. package/lib/claude-cli-bridge.js +0 -215
  26. package/lib/dashboard-automations.js +0 -130
  27. package/lib/dashboard-git.js +0 -254
  28. package/lib/dashboard-inbox.js +0 -64
  29. package/lib/dashboard-protocol.js +0 -605
  30. package/lib/dashboard-server.js +0 -1296
  31. package/lib/dashboard-session.js +0 -136
  32. package/lib/dashboard-status.js +0 -72
  33. package/lib/dashboard-terminal.js +0 -354
  34. package/lib/dashboard-websocket.js +0 -88
  35. package/scripts/dashboard-serve.js +0 -336
  36. package/src/core/commands/serve.md +0 -127
  37. package/tools/cli/commands/serve.js +0 -492
@@ -1,336 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * dashboard-serve.js - AgileFlow Dashboard WebSocket Server CLI
5
- *
6
- * Starts a WebSocket server that the AgileFlow Dashboard can connect to
7
- * for real-time communication with Claude Code.
8
- *
9
- * Usage:
10
- * agileflow serve [options]
11
- * node scripts/dashboard-serve.js [options]
12
- *
13
- * Options:
14
- * --port, -p Port to listen on (default: 8765)
15
- * --host, -h Host to bind to (default: 0.0.0.0)
16
- * --api-key, -k API key for authentication
17
- * --require-auth Require API key for connections
18
- * --tunnel, -t Start ngrok tunnel (if installed)
19
- */
20
-
21
- 'use strict';
22
-
23
- const path = require('path');
24
- const {
25
- createDashboardServer,
26
- startDashboardServer,
27
- stopDashboardServer,
28
- } = require('../lib/dashboard-server');
29
- const {
30
- createNotification,
31
- createTextDelta,
32
- createToolStart,
33
- createToolResult,
34
- createAskUserQuestion,
35
- } = require('../lib/dashboard-protocol');
36
- const { createClaudeBridge } = require('../lib/claude-cli-bridge');
37
-
38
- // Parse command line arguments
39
- function parseArgs() {
40
- const args = process.argv.slice(2);
41
- const options = {
42
- port: 8765,
43
- host: '0.0.0.0',
44
- apiKey: null,
45
- requireAuth: false,
46
- tunnel: false,
47
- };
48
-
49
- for (let i = 0; i < args.length; i++) {
50
- const arg = args[i];
51
- const next = args[i + 1];
52
-
53
- switch (arg) {
54
- case '--port':
55
- case '-p':
56
- options.port = parseInt(next, 10);
57
- i++;
58
- break;
59
- case '--host':
60
- case '-h':
61
- options.host = next;
62
- i++;
63
- break;
64
- case '--api-key':
65
- case '-k':
66
- options.apiKey = next;
67
- options.requireAuth = true;
68
- i++;
69
- break;
70
- case '--require-auth':
71
- options.requireAuth = true;
72
- break;
73
- case '--tunnel':
74
- case '-t':
75
- options.tunnel = true;
76
- break;
77
- case '--help':
78
- printHelp();
79
- process.exit(0);
80
- }
81
- }
82
-
83
- return options;
84
- }
85
-
86
- function printHelp() {
87
- console.log(`
88
- AgileFlow Dashboard Server
89
-
90
- Starts a WebSocket server for the AgileFlow Dashboard to connect to.
91
-
92
- Usage:
93
- agileflow serve [options]
94
- node scripts/dashboard-serve.js [options]
95
-
96
- Options:
97
- --port, -p <port> Port to listen on (default: 8765)
98
- --host, -h <host> Host to bind to (default: 0.0.0.0)
99
- --api-key, -k <key> API key for authentication
100
- --require-auth Require API key for connections
101
- --tunnel, -t Start ngrok tunnel (requires ngrok)
102
- --help Show this help message
103
-
104
- Examples:
105
- # Start with default settings
106
- agileflow serve
107
-
108
- # Start on custom port with API key
109
- agileflow serve --port 9000 --api-key agf_secret123
110
-
111
- # Start with ngrok tunnel
112
- agileflow serve --tunnel
113
-
114
- Dashboard Connection:
115
- The dashboard should connect to ws://localhost:<port>
116
- Or use the tunnel URL if --tunnel is enabled.
117
- `);
118
- }
119
-
120
- function printBanner() {
121
- console.log(`
122
- ╔═══════════════════════════════════════════════════════════╗
123
- ║ ║
124
- ║ █████╗ ██████╗ ██╗██╗ ███████╗███████╗██╗ ║
125
- ║ ██╔══██╗██╔════╝ ██║██║ ██╔════╝██╔════╝██║ ║
126
- ║ ███████║██║ ███╗██║██║ █████╗ █████╗ ██║ ║
127
- ║ ██╔══██║██║ ██║██║██║ ██╔══╝ ██╔══╝ ██║ ║
128
- ║ ██║ ██║╚██████╔╝██║███████╗███████╗██║ ███████╗ ║
129
- ║ ╚═╝ ╚═╝ ╚═════╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚══════╝ ║
130
- ║ ║
131
- ║ Dashboard WebSocket Server ║
132
- ║ ║
133
- ╚═══════════════════════════════════════════════════════════╝
134
- `);
135
- }
136
-
137
- async function startTunnel(port) {
138
- try {
139
- const { exec } = require('child_process');
140
-
141
- return new Promise((resolve, reject) => {
142
- // Check if ngrok is installed
143
- exec('which ngrok', error => {
144
- if (error) {
145
- console.log(' Tunnel: ngrok not found. Install with: npm install -g ngrok');
146
- resolve(null);
147
- return;
148
- }
149
-
150
- // Start ngrok tunnel
151
- const ngrok = exec(`ngrok http ${port} --log stdout`, { encoding: 'utf8' });
152
-
153
- ngrok.stdout.on('data', data => {
154
- // Parse ngrok output for public URL
155
- const urlMatch = data.match(/url=(https?:\/\/[^\s]+)/);
156
- if (urlMatch) {
157
- const tunnelUrl = urlMatch[1].replace('https://', 'wss://').replace('http://', 'ws://');
158
- console.log(` Tunnel: ${tunnelUrl}`);
159
- resolve(tunnelUrl);
160
- }
161
- });
162
-
163
- ngrok.stderr.on('data', data => {
164
- console.error(' Tunnel error:', data);
165
- });
166
-
167
- // Give ngrok a moment to start
168
- setTimeout(() => {
169
- if (!ngrok.killed) {
170
- console.log(' Tunnel: Starting... check ngrok dashboard');
171
- resolve(null);
172
- }
173
- }, 5000);
174
- });
175
- });
176
- } catch (error) {
177
- console.log(' Tunnel: Failed to start -', error.message);
178
- return null;
179
- }
180
- }
181
-
182
- async function main() {
183
- const options = parseArgs();
184
-
185
- printBanner();
186
-
187
- console.log('Starting server...\n');
188
-
189
- try {
190
- // Create server
191
- const server = createDashboardServer({
192
- port: options.port,
193
- host: options.host,
194
- apiKey: options.apiKey,
195
- requireAuth: options.requireAuth,
196
- });
197
-
198
- // Set up event handlers
199
- setupEventHandlers(server);
200
-
201
- // Start server
202
- const { wsUrl } = await startDashboardServer(server);
203
-
204
- // Start tunnel if requested
205
- if (options.tunnel) {
206
- await startTunnel(options.port);
207
- }
208
-
209
- console.log('─────────────────────────────────────────────────────────────');
210
- console.log('');
211
- console.log(' Ready! Connect your dashboard to:');
212
- console.log(` ${wsUrl}`);
213
- console.log('');
214
- if (options.apiKey) {
215
- console.log(` API Key: ${options.apiKey.slice(0, 8)}...`);
216
- console.log('');
217
- }
218
- console.log(' Press Ctrl+C to stop.');
219
- console.log('');
220
- console.log('─────────────────────────────────────────────────────────────');
221
- console.log('');
222
-
223
- // Handle shutdown
224
- const shutdown = async () => {
225
- console.log('\nShutting down...');
226
- await stopDashboardServer(server);
227
- process.exit(0);
228
- };
229
-
230
- process.on('SIGINT', shutdown);
231
- process.on('SIGTERM', shutdown);
232
- } catch (error) {
233
- console.error('Failed to start server:', error.message);
234
- process.exit(1);
235
- }
236
- }
237
-
238
- /**
239
- * Set up event handlers for the dashboard server
240
- */
241
- function setupEventHandlers(server) {
242
- // Session events
243
- server.on('session:connected', (sessionId, session) => {
244
- console.log(`[${new Date().toISOString()}] Session connected: ${sessionId}`);
245
- });
246
-
247
- server.on('session:disconnected', sessionId => {
248
- console.log(`[${new Date().toISOString()}] Session disconnected: ${sessionId}`);
249
- });
250
-
251
- // User message handler - use Claude CLI bridge
252
- server.on('user:message', async (session, content) => {
253
- console.log(
254
- `[${new Date().toISOString()}] Message from ${session.id}: ${content.slice(0, 50)}...`
255
- );
256
-
257
- try {
258
- await handleClaudeMessage(session, content, server.projectRoot);
259
- } catch (error) {
260
- console.error(`[${new Date().toISOString()}] Claude error:`, error.message);
261
- session.send(createNotification('error', 'Error', error.message));
262
- session.setState('error');
263
- }
264
- });
265
-
266
- // Cancel handler
267
- server.on('user:cancel', session => {
268
- console.log(`[${new Date().toISOString()}] Cancel from ${session.id}`);
269
- });
270
-
271
- // Refresh handlers
272
- server.on('refresh:tasks', session => {
273
- // Send task list update
274
- console.log(`[${new Date().toISOString()}] Task refresh for ${session.id}`);
275
- });
276
-
277
- server.on('refresh:status', session => {
278
- // Send status update
279
- console.log(`[${new Date().toISOString()}] Status refresh for ${session.id}`);
280
- });
281
- }
282
-
283
- /**
284
- * Handle message by calling Claude CLI
285
- */
286
- async function handleClaudeMessage(session, content, projectRoot) {
287
- let fullResponse = '';
288
-
289
- const bridge = createClaudeBridge({
290
- cwd: projectRoot,
291
- onInit: info => {
292
- console.log(
293
- `[${new Date().toISOString()}] Claude session: ${info.sessionId}, model: ${info.model}`
294
- );
295
- },
296
- onText: (text, done) => {
297
- if (text) {
298
- fullResponse += text;
299
- session.send(createTextDelta(text, done));
300
- }
301
- if (done) {
302
- session.addMessage('assistant', fullResponse);
303
- session.setState('idle');
304
- console.log(`[${new Date().toISOString()}] Response complete`);
305
- }
306
- },
307
- onToolStart: (id, name, input) => {
308
- // Special handling for AskUserQuestion - send to dashboard for UI
309
- if (name === 'AskUserQuestion' && input?.questions) {
310
- session.send(createAskUserQuestion(id, input.questions));
311
- }
312
- session.send(createToolStart(id, name, input));
313
- },
314
- onToolResult: (id, output, isError, toolName) => {
315
- session.send(createToolResult(id, { content: output, error: isError }, toolName));
316
- },
317
- onError: error => {
318
- console.error(`[${new Date().toISOString()}] Claude error:`, error);
319
- session.send(createNotification('error', 'Claude Error', error));
320
- },
321
- onComplete: response => {
322
- // Already handled in onText with done=true
323
- },
324
- });
325
-
326
- try {
327
- await bridge.sendMessage(content);
328
- } catch (error) {
329
- session.send(createNotification('error', 'Error', error.message));
330
- session.setState('error');
331
- throw error;
332
- }
333
- }
334
-
335
- // Run main
336
- main().catch(console.error);
@@ -1,127 +0,0 @@
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