@litmers/cursorflow-orchestrator 0.1.12 → 0.1.14

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 (71) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +83 -2
  3. package/commands/cursorflow-clean.md +20 -6
  4. package/commands/cursorflow-prepare.md +1 -1
  5. package/commands/cursorflow-resume.md +127 -6
  6. package/commands/cursorflow-run.md +2 -2
  7. package/commands/cursorflow-signal.md +11 -4
  8. package/dist/cli/clean.js +164 -12
  9. package/dist/cli/clean.js.map +1 -1
  10. package/dist/cli/index.d.ts +1 -0
  11. package/dist/cli/index.js +6 -1
  12. package/dist/cli/index.js.map +1 -1
  13. package/dist/cli/logs.d.ts +8 -0
  14. package/dist/cli/logs.js +746 -0
  15. package/dist/cli/logs.js.map +1 -0
  16. package/dist/cli/monitor.js +113 -30
  17. package/dist/cli/monitor.js.map +1 -1
  18. package/dist/cli/prepare.js +1 -1
  19. package/dist/cli/resume.js +367 -18
  20. package/dist/cli/resume.js.map +1 -1
  21. package/dist/cli/run.js +2 -0
  22. package/dist/cli/run.js.map +1 -1
  23. package/dist/cli/signal.js +34 -20
  24. package/dist/cli/signal.js.map +1 -1
  25. package/dist/core/orchestrator.d.ts +11 -1
  26. package/dist/core/orchestrator.js +257 -35
  27. package/dist/core/orchestrator.js.map +1 -1
  28. package/dist/core/reviewer.js +20 -0
  29. package/dist/core/reviewer.js.map +1 -1
  30. package/dist/core/runner.js +113 -13
  31. package/dist/core/runner.js.map +1 -1
  32. package/dist/utils/config.js +34 -0
  33. package/dist/utils/config.js.map +1 -1
  34. package/dist/utils/doctor.js +9 -2
  35. package/dist/utils/doctor.js.map +1 -1
  36. package/dist/utils/enhanced-logger.d.ts +209 -0
  37. package/dist/utils/enhanced-logger.js +963 -0
  38. package/dist/utils/enhanced-logger.js.map +1 -0
  39. package/dist/utils/events.d.ts +59 -0
  40. package/dist/utils/events.js +37 -0
  41. package/dist/utils/events.js.map +1 -0
  42. package/dist/utils/git.d.ts +5 -0
  43. package/dist/utils/git.js +25 -0
  44. package/dist/utils/git.js.map +1 -1
  45. package/dist/utils/types.d.ts +122 -1
  46. package/dist/utils/webhook.d.ts +5 -0
  47. package/dist/utils/webhook.js +109 -0
  48. package/dist/utils/webhook.js.map +1 -0
  49. package/examples/README.md +1 -1
  50. package/package.json +1 -1
  51. package/scripts/simple-logging-test.sh +97 -0
  52. package/scripts/test-real-logging.sh +289 -0
  53. package/scripts/test-streaming-multi-task.sh +247 -0
  54. package/src/cli/clean.ts +170 -13
  55. package/src/cli/index.ts +4 -1
  56. package/src/cli/logs.ts +848 -0
  57. package/src/cli/monitor.ts +123 -30
  58. package/src/cli/prepare.ts +1 -1
  59. package/src/cli/resume.ts +463 -22
  60. package/src/cli/run.ts +2 -0
  61. package/src/cli/signal.ts +43 -27
  62. package/src/core/orchestrator.ts +303 -37
  63. package/src/core/reviewer.ts +22 -0
  64. package/src/core/runner.ts +128 -12
  65. package/src/utils/config.ts +36 -0
  66. package/src/utils/doctor.ts +12 -2
  67. package/src/utils/enhanced-logger.ts +1097 -0
  68. package/src/utils/events.ts +117 -0
  69. package/src/utils/git.ts +25 -0
  70. package/src/utils/types.ts +150 -1
  71. package/src/utils/webhook.ts +85 -0
@@ -0,0 +1,289 @@
1
+ #!/bin/bash
2
+ #
3
+ # Real Integration Test for Enhanced Logging
4
+ #
5
+ # This script runs an actual cursor-agent task and verifies that:
6
+ # 1. terminal.log is created with clean output
7
+ # 2. terminal-raw.log contains raw output
8
+ # 3. terminal.jsonl has structured entries
9
+ # 4. ANSI codes are properly stripped in clean log
10
+ # 5. Timestamps are added correctly
11
+ #
12
+
13
+ set -e
14
+
15
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
16
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
17
+
18
+ # Colors
19
+ RED='\033[0;31m'
20
+ GREEN='\033[0;32m'
21
+ YELLOW='\033[1;33m'
22
+ CYAN='\033[0;36m'
23
+ NC='\033[0m' # No Color
24
+
25
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
26
+ echo -e "${CYAN} 🧪 Real Integration Test for Enhanced Logging${NC}"
27
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
28
+ echo ""
29
+
30
+ # Check if cursor-agent is available
31
+ if ! command -v cursor-agent &> /dev/null; then
32
+ echo -e "${RED}❌ cursor-agent not found. Please install it first.${NC}"
33
+ echo " npm install -g @anthropic-ai/claude-code"
34
+ exit 1
35
+ fi
36
+
37
+ # Check cursor-agent auth
38
+ echo -e "${YELLOW}Checking cursor-agent authentication...${NC}"
39
+ if ! cursor-agent create-chat &> /dev/null; then
40
+ echo -e "${RED}❌ cursor-agent authentication failed.${NC}"
41
+ echo " Please sign in to Cursor IDE first."
42
+ exit 1
43
+ fi
44
+ echo -e "${GREEN}✓ cursor-agent authenticated${NC}"
45
+
46
+ # Setup test directory
47
+ TEST_DIR="$PROJECT_ROOT/_cursorflow/test-real-logging"
48
+ TASKS_DIR="$TEST_DIR/tasks"
49
+ LOGS_DIR="$TEST_DIR/logs"
50
+
51
+ echo ""
52
+ echo -e "${YELLOW}Setting up test environment...${NC}"
53
+
54
+ # Clean previous test
55
+ rm -rf "$TEST_DIR"
56
+ mkdir -p "$TASKS_DIR"
57
+ mkdir -p "$LOGS_DIR"
58
+
59
+ # Create a simple test task
60
+ # This task should complete quickly (just echo something)
61
+ cat > "$TASKS_DIR/logging-test.json" << 'EOF'
62
+ {
63
+ "baseBranch": "main",
64
+ "branchPrefix": "test/logging-",
65
+ "timeout": 60000,
66
+ "dependencyPolicy": {
67
+ "allowDependencyChange": false,
68
+ "lockfileReadOnly": true
69
+ },
70
+ "tasks": [
71
+ {
72
+ "name": "simple-echo",
73
+ "prompt": "Please just respond with 'Hello from cursor-agent! The logging test is working.' and nothing else. Do not make any file changes.",
74
+ "model": "sonnet-4.5"
75
+ }
76
+ ]
77
+ }
78
+ EOF
79
+
80
+ echo -e "${GREEN}✓ Test task created${NC}"
81
+
82
+ # Build the project
83
+ echo ""
84
+ echo -e "${YELLOW}Building project...${NC}"
85
+ cd "$PROJECT_ROOT"
86
+ npm run build > /dev/null 2>&1
87
+ echo -e "${GREEN}✓ Build complete${NC}"
88
+
89
+ # Run the orchestrator with enhanced logging
90
+ echo ""
91
+ echo -e "${YELLOW}Running orchestration with enhanced logging...${NC}"
92
+ echo -e "${CYAN}This will execute cursor-agent - please wait...${NC}"
93
+ echo ""
94
+
95
+ # Run orchestrator
96
+ RUN_DIR="$LOGS_DIR/runs/run-$(date +%s)"
97
+ mkdir -p "$RUN_DIR/lanes/logging-test"
98
+
99
+ # Use node directly to run with enhanced logging config
100
+ node -e "
101
+ const { spawnLane, waitChild } = require('./dist/core/orchestrator');
102
+ const path = require('path');
103
+ const fs = require('fs');
104
+
105
+ const tasksFile = '$TASKS_DIR/logging-test.json';
106
+ const laneRunDir = '$RUN_DIR/lanes/logging-test';
107
+
108
+ console.log('Starting lane with enhanced logging...');
109
+
110
+ const result = spawnLane({
111
+ laneName: 'logging-test',
112
+ tasksFile: tasksFile,
113
+ laneRunDir: laneRunDir,
114
+ executor: 'cursor-agent',
115
+ startIndex: 0,
116
+ enhancedLogConfig: {
117
+ enabled: true,
118
+ stripAnsi: true,
119
+ addTimestamps: true,
120
+ keepRawLogs: true,
121
+ writeJsonLog: true,
122
+ timestampFormat: 'iso',
123
+ },
124
+ });
125
+
126
+ console.log('Lane spawned, waiting for completion...');
127
+ console.log('PID:', result.child.pid);
128
+
129
+ // Set timeout
130
+ const timeout = setTimeout(() => {
131
+ console.log('Timeout reached, killing process...');
132
+ result.child.kill('SIGTERM');
133
+ }, 120000); // 2 minute timeout
134
+
135
+ waitChild(result.child).then((exitCode) => {
136
+ clearTimeout(timeout);
137
+ console.log('');
138
+ console.log('Lane completed with exit code:', exitCode);
139
+
140
+ // Close log manager
141
+ if (result.logManager) {
142
+ result.logManager.close();
143
+ }
144
+
145
+ process.exit(exitCode === 0 ? 0 : 1);
146
+ }).catch((err) => {
147
+ clearTimeout(timeout);
148
+ console.error('Error:', err);
149
+ process.exit(1);
150
+ });
151
+ "
152
+
153
+ EXIT_CODE=$?
154
+
155
+ echo ""
156
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
157
+ echo -e "${CYAN} 📋 Verifying Log Files${NC}"
158
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
159
+ echo ""
160
+
161
+ LANE_DIR="$RUN_DIR/lanes/logging-test"
162
+ ERRORS=0
163
+
164
+ # Check terminal.log
165
+ if [ -f "$LANE_DIR/terminal.log" ]; then
166
+ SIZE=$(wc -c < "$LANE_DIR/terminal.log")
167
+ echo -e "${GREEN}✓ terminal.log exists (${SIZE} bytes)${NC}"
168
+
169
+ # Check for ANSI codes in clean log (should NOT be there)
170
+ if grep -qP '\x1b\[' "$LANE_DIR/terminal.log" 2>/dev/null; then
171
+ echo -e "${RED} ❌ ANSI codes found in clean log (should be stripped)${NC}"
172
+ ERRORS=$((ERRORS + 1))
173
+ else
174
+ echo -e "${GREEN} ✓ No ANSI codes in clean log${NC}"
175
+ fi
176
+
177
+ # Check for timestamps
178
+ if grep -qE '\[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}' "$LANE_DIR/terminal.log"; then
179
+ echo -e "${GREEN} ✓ Timestamps present${NC}"
180
+ else
181
+ echo -e "${YELLOW} ⚠ No ISO timestamps found${NC}"
182
+ fi
183
+
184
+ # Check for session header
185
+ if grep -q "CursorFlow Session Log" "$LANE_DIR/terminal.log"; then
186
+ echo -e "${GREEN} ✓ Session header present${NC}"
187
+ else
188
+ echo -e "${RED} ❌ Session header missing${NC}"
189
+ ERRORS=$((ERRORS + 1))
190
+ fi
191
+ else
192
+ echo -e "${RED}❌ terminal.log NOT found${NC}"
193
+ ERRORS=$((ERRORS + 1))
194
+ fi
195
+
196
+ # Check terminal-raw.log
197
+ if [ -f "$LANE_DIR/terminal-raw.log" ]; then
198
+ SIZE=$(wc -c < "$LANE_DIR/terminal-raw.log")
199
+ echo -e "${GREEN}✓ terminal-raw.log exists (${SIZE} bytes)${NC}"
200
+ else
201
+ echo -e "${RED}❌ terminal-raw.log NOT found${NC}"
202
+ ERRORS=$((ERRORS + 1))
203
+ fi
204
+
205
+ # Check terminal.jsonl
206
+ if [ -f "$LANE_DIR/terminal.jsonl" ]; then
207
+ SIZE=$(wc -c < "$LANE_DIR/terminal.jsonl")
208
+ ENTRIES=$(wc -l < "$LANE_DIR/terminal.jsonl")
209
+ echo -e "${GREEN}✓ terminal.jsonl exists (${SIZE} bytes, ${ENTRIES} entries)${NC}"
210
+
211
+ # Check JSON validity
212
+ if head -1 "$LANE_DIR/terminal.jsonl" | jq . > /dev/null 2>&1; then
213
+ echo -e "${GREEN} ✓ Valid JSON format${NC}"
214
+ else
215
+ echo -e "${RED} ❌ Invalid JSON format${NC}"
216
+ ERRORS=$((ERRORS + 1))
217
+ fi
218
+
219
+ # Check for required fields
220
+ if head -1 "$LANE_DIR/terminal.jsonl" | jq -e '.timestamp and .level and .message' > /dev/null 2>&1; then
221
+ echo -e "${GREEN} ✓ Required fields present (timestamp, level, message)${NC}"
222
+ else
223
+ echo -e "${RED} ❌ Missing required fields${NC}"
224
+ ERRORS=$((ERRORS + 1))
225
+ fi
226
+ else
227
+ echo -e "${RED}❌ terminal.jsonl NOT found${NC}"
228
+ ERRORS=$((ERRORS + 1))
229
+ fi
230
+
231
+ echo ""
232
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
233
+ echo -e "${CYAN} 📝 Log Content Preview${NC}"
234
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
235
+ echo ""
236
+
237
+ echo -e "${YELLOW}terminal.log (first 30 lines):${NC}"
238
+ echo "─────────────────────────────────────────────────────────"
239
+ if [ -f "$LANE_DIR/terminal.log" ]; then
240
+ head -30 "$LANE_DIR/terminal.log"
241
+ fi
242
+ echo "─────────────────────────────────────────────────────────"
243
+
244
+ echo ""
245
+ echo -e "${YELLOW}terminal.jsonl (first 5 entries):${NC}"
246
+ echo "─────────────────────────────────────────────────────────"
247
+ if [ -f "$LANE_DIR/terminal.jsonl" ]; then
248
+ head -5 "$LANE_DIR/terminal.jsonl" | jq -c '.'
249
+ fi
250
+ echo "─────────────────────────────────────────────────────────"
251
+
252
+ echo ""
253
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
254
+
255
+ # Test the logs CLI command
256
+ echo ""
257
+ echo -e "${YELLOW}Testing 'cursorflow logs' command...${NC}"
258
+ echo ""
259
+
260
+ node dist/cli/index.js logs "$RUN_DIR" 2>&1 || true
261
+
262
+ echo ""
263
+ node dist/cli/index.js logs "$RUN_DIR" --lane logging-test --tail 20 2>&1 || true
264
+
265
+ echo ""
266
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
267
+ echo -e "${CYAN} 📊 Test Summary${NC}"
268
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
269
+ echo ""
270
+
271
+ if [ $ERRORS -eq 0 ] && [ $EXIT_CODE -eq 0 ]; then
272
+ echo -e "${GREEN}✅ All tests passed!${NC}"
273
+ echo ""
274
+ echo "Log files are at: $LANE_DIR"
275
+ exit 0
276
+ elif [ $EXIT_CODE -ne 0 ]; then
277
+ echo -e "${YELLOW}⚠️ cursor-agent execution had issues (exit code: $EXIT_CODE)${NC}"
278
+ echo -e "${YELLOW} This might be expected if auth or network issues occurred.${NC}"
279
+ echo -e "${YELLOW} Check if log files were still created correctly.${NC}"
280
+ echo ""
281
+ echo "Log files are at: $LANE_DIR"
282
+ exit 1
283
+ else
284
+ echo -e "${RED}❌ $ERRORS error(s) found in logging verification${NC}"
285
+ echo ""
286
+ echo "Log files are at: $LANE_DIR"
287
+ exit 1
288
+ fi
289
+
@@ -0,0 +1,247 @@
1
+ #!/bin/bash
2
+ #
3
+ # Comprehensive Streaming Output Test with Multi-Task Dependencies
4
+ #
5
+ # This test verifies:
6
+ # 1. Streaming output from cursor-agent (not just final JSON)
7
+ # 2. Multiple tasks execution in sequence
8
+ # 3. Dependency handling between tasks
9
+ # 4. Raw log capture and parsed log quality
10
+ #
11
+
12
+ set -e
13
+
14
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
15
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
16
+
17
+ # Colors
18
+ RED='\033[0;31m'
19
+ GREEN='\033[0;32m'
20
+ YELLOW='\033[1;33m'
21
+ CYAN='\033[0;36m'
22
+ MAGENTA='\033[0;35m'
23
+ NC='\033[0m'
24
+
25
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
26
+ echo -e "${CYAN} 🧪 Streaming Multi-Task Test${NC}"
27
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
28
+ echo ""
29
+
30
+ # Check cursor-agent
31
+ if ! command -v cursor-agent &> /dev/null; then
32
+ echo -e "${RED}❌ cursor-agent not found${NC}"
33
+ exit 1
34
+ fi
35
+
36
+ # Check auth
37
+ echo -e "${YELLOW}Checking cursor-agent authentication...${NC}"
38
+ if ! cursor-agent create-chat &> /dev/null; then
39
+ echo -e "${RED}❌ cursor-agent authentication failed${NC}"
40
+ exit 1
41
+ fi
42
+ echo -e "${GREEN}✓ cursor-agent authenticated${NC}"
43
+
44
+ cd "$PROJECT_ROOT"
45
+
46
+ # Build
47
+ echo -e "${YELLOW}Building project...${NC}"
48
+ npm run build > /dev/null 2>&1
49
+ echo -e "${GREEN}✓ Build complete${NC}"
50
+
51
+ # Setup test directory
52
+ TEST_DIR="$PROJECT_ROOT/_test-streaming"
53
+ rm -rf "$TEST_DIR"
54
+ mkdir -p "$TEST_DIR/lane"
55
+
56
+ # Create multi-task configuration with dependencies
57
+ cat > "$TEST_DIR/multi-task.json" << 'EOF'
58
+ {
59
+ "baseBranch": "main",
60
+ "branchPrefix": "test/stream-",
61
+ "timeout": 120000,
62
+ "dependencyPolicy": {
63
+ "allowDependencyChange": false,
64
+ "lockfileReadOnly": true
65
+ },
66
+ "tasks": [
67
+ {
68
+ "name": "task-1-analyze",
69
+ "prompt": "Analyze this codebase. List the top 3 most important files and briefly explain what each does. Keep your response under 200 words. Do not make any file changes.",
70
+ "model": "sonnet-4.5"
71
+ },
72
+ {
73
+ "name": "task-2-summary",
74
+ "prompt": "Based on your previous analysis, write a 2-sentence summary of what this project does. Do not make any file changes.",
75
+ "model": "sonnet-4.5"
76
+ }
77
+ ]
78
+ }
79
+ EOF
80
+
81
+ echo -e "${GREEN}✓ Test configuration created (2 tasks)${NC}"
82
+ echo ""
83
+
84
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
85
+ echo -e "${CYAN} Running orchestration with STREAMING enabled...${NC}"
86
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
87
+ echo ""
88
+
89
+ LANE_DIR="$TEST_DIR/lane"
90
+
91
+ # Run spawnLane directly to test streaming
92
+ node -e "
93
+ const { spawnLane, waitChild } = require('./dist/core/orchestrator');
94
+ const fs = require('fs');
95
+ const path = require('path');
96
+
97
+ const tasksFile = path.join('$TEST_DIR', 'multi-task.json');
98
+ const laneRunDir = '$LANE_DIR';
99
+
100
+ console.log('Spawning lane with streaming output enabled...');
101
+ console.log('');
102
+
103
+ const result = spawnLane({
104
+ laneName: 'stream-test',
105
+ tasksFile,
106
+ laneRunDir,
107
+ executor: 'cursor-agent',
108
+ startIndex: 0,
109
+ enhancedLogConfig: {
110
+ enabled: true,
111
+ stripAnsi: true,
112
+ streamOutput: true, // Enable streaming!
113
+ addTimestamps: true,
114
+ keepRawLogs: true,
115
+ writeJsonLog: true,
116
+ timestampFormat: 'iso',
117
+ },
118
+ });
119
+
120
+ console.log('Lane spawned, PID:', result.child.pid);
121
+ console.log('Waiting for completion (may take 2-3 minutes)...');
122
+ console.log('');
123
+
124
+ const timeout = setTimeout(() => {
125
+ console.log('\\nTimeout reached (3 min)');
126
+ result.child.kill('SIGTERM');
127
+ }, 180000);
128
+
129
+ waitChild(result.child).then((code) => {
130
+ clearTimeout(timeout);
131
+ console.log('');
132
+ console.log('Lane completed with exit code:', code);
133
+ result.logManager?.close();
134
+ process.exit(code === 0 ? 0 : 1);
135
+ }).catch(e => {
136
+ clearTimeout(timeout);
137
+ console.error('Error:', e);
138
+ process.exit(1);
139
+ });
140
+ " 2>&1
141
+
142
+ EXIT_CODE=$?
143
+
144
+ echo ""
145
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
146
+ echo -e "${CYAN} 📋 Log File Analysis${NC}"
147
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
148
+ echo ""
149
+
150
+ # Check files
151
+ echo -e "${YELLOW}Log files created:${NC}"
152
+ ls -la "$LANE_DIR"/*.log "$LANE_DIR"/*.jsonl 2>/dev/null || echo "No log files found"
153
+ echo ""
154
+
155
+ # Count streaming entries in JSON log
156
+ if [ -f "$LANE_DIR/terminal.jsonl" ]; then
157
+ TOTAL_ENTRIES=$(wc -l < "$LANE_DIR/terminal.jsonl")
158
+ STDOUT_ENTRIES=$(grep -c '"level":"stdout"' "$LANE_DIR/terminal.jsonl" || echo "0")
159
+ STREAMING_ENTRIES=$(grep -c '"type":' "$LANE_DIR/terminal.jsonl" || echo "0")
160
+
161
+ echo -e "${YELLOW}JSON Log Statistics:${NC}"
162
+ echo " Total entries: $TOTAL_ENTRIES"
163
+ echo " stdout entries: $STDOUT_ENTRIES"
164
+ echo " Entries with streaming 'type': $STREAMING_ENTRIES"
165
+ echo ""
166
+ fi
167
+
168
+ # Check for streaming content markers in raw log
169
+ if [ -f "$LANE_DIR/terminal-raw.log" ]; then
170
+ RAW_SIZE=$(wc -c < "$LANE_DIR/terminal-raw.log")
171
+ RAW_LINES=$(wc -l < "$LANE_DIR/terminal-raw.log")
172
+
173
+ # Look for streaming indicators
174
+ HAS_TYPE_TEXT=$(grep -c '"type":"text"' "$LANE_DIR/terminal-raw.log" 2>/dev/null || echo "0")
175
+ HAS_TYPE_RESULT=$(grep -c '"type":"result"' "$LANE_DIR/terminal-raw.log" 2>/dev/null || echo "0")
176
+ HAS_CONTENT=$(grep -c '"content":' "$LANE_DIR/terminal-raw.log" 2>/dev/null || echo "0")
177
+
178
+ echo -e "${YELLOW}Raw Log Statistics:${NC}"
179
+ echo " Size: $RAW_SIZE bytes"
180
+ echo " Lines: $RAW_LINES"
181
+ echo ""
182
+ echo -e "${YELLOW}Streaming Markers Found:${NC}"
183
+ echo " type:'text' entries: $HAS_TYPE_TEXT"
184
+ echo " type:'result' entries: $HAS_TYPE_RESULT"
185
+ echo " content entries: $HAS_CONTENT"
186
+ echo ""
187
+ fi
188
+
189
+ # Show sample of streaming output
190
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
191
+ echo -e "${CYAN} 📝 Sample Streaming Output (first 30 lines of stdout)${NC}"
192
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
193
+ echo ""
194
+
195
+ if [ -f "$LANE_DIR/terminal.log" ]; then
196
+ # Show lines containing cursor-agent output (streaming JSON)
197
+ echo -e "${MAGENTA}Looking for streaming JSON output...${NC}"
198
+ grep -E '^\[.*\] \{"type":' "$LANE_DIR/terminal.log" | head -20 || echo "No streaming JSON found"
199
+ echo ""
200
+ fi
201
+
202
+ # Test the logs CLI command
203
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
204
+ echo -e "${CYAN} 🔍 Testing cursorflow logs command${NC}"
205
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
206
+ echo ""
207
+
208
+ # Create a fake runs directory structure for the CLI
209
+ FAKE_RUN_DIR="$TEST_DIR/runs/run-test"
210
+ mkdir -p "$FAKE_RUN_DIR/lanes"
211
+ ln -sf "$LANE_DIR" "$FAKE_RUN_DIR/lanes/stream-test"
212
+
213
+ echo -e "${YELLOW}Testing: cursorflow logs --tail 15${NC}"
214
+ node dist/cli/index.js logs "$FAKE_RUN_DIR" --tail 15 2>&1 || true
215
+
216
+ echo ""
217
+ echo -e "${YELLOW}Testing: cursorflow logs --filter 'type.*text'${NC}"
218
+ node dist/cli/index.js logs "$FAKE_RUN_DIR" --filter '"type":"text"' --tail 10 2>&1 || true
219
+
220
+ echo ""
221
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
222
+ echo -e "${CYAN} 📊 Test Summary${NC}"
223
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
224
+ echo ""
225
+
226
+ # Determine if streaming worked
227
+ if [ "$HAS_TYPE_TEXT" -gt "0" ] || [ "$HAS_CONTENT" -gt "10" ]; then
228
+ echo -e "${GREEN}✅ Streaming output captured successfully!${NC}"
229
+ echo " Found $HAS_TYPE_TEXT text stream entries"
230
+ echo " Found $HAS_CONTENT content entries"
231
+ else
232
+ echo -e "${YELLOW}⚠️ Limited streaming content detected${NC}"
233
+ echo " This may indicate:"
234
+ echo " - stream-json format not outputting expected data"
235
+ echo " - Or cursor-agent only provides final results"
236
+ fi
237
+
238
+ echo ""
239
+ echo "Log files saved at: $LANE_DIR"
240
+ echo ""
241
+
242
+ # Cleanup git
243
+ git worktree remove _cursorflow/worktrees/test/stream-* --force 2>/dev/null || true
244
+ git branch -D $(git branch | grep "test/stream-") 2>/dev/null || true
245
+
246
+ exit $EXIT_CODE
247
+