@litmers/cursorflow-orchestrator 0.1.13 → 0.1.15

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 (76) hide show
  1. package/CHANGELOG.md +37 -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 +759 -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 +9 -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 +13 -1
  26. package/dist/core/orchestrator.js +396 -35
  27. package/dist/core/orchestrator.js.map +1 -1
  28. package/dist/core/reviewer.d.ts +2 -0
  29. package/dist/core/reviewer.js +24 -2
  30. package/dist/core/reviewer.js.map +1 -1
  31. package/dist/core/runner.d.ts +9 -3
  32. package/dist/core/runner.js +266 -61
  33. package/dist/core/runner.js.map +1 -1
  34. package/dist/utils/config.js +38 -1
  35. package/dist/utils/config.js.map +1 -1
  36. package/dist/utils/enhanced-logger.d.ts +210 -0
  37. package/dist/utils/enhanced-logger.js +1030 -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 +11 -0
  43. package/dist/utils/git.js +40 -0
  44. package/dist/utils/git.js.map +1 -1
  45. package/dist/utils/logger.d.ts +2 -0
  46. package/dist/utils/logger.js +4 -1
  47. package/dist/utils/logger.js.map +1 -1
  48. package/dist/utils/types.d.ts +132 -1
  49. package/dist/utils/webhook.d.ts +5 -0
  50. package/dist/utils/webhook.js +109 -0
  51. package/dist/utils/webhook.js.map +1 -0
  52. package/examples/README.md +1 -1
  53. package/package.json +2 -1
  54. package/scripts/patches/test-cursor-agent.js +1 -1
  55. package/scripts/simple-logging-test.sh +97 -0
  56. package/scripts/test-real-cursor-lifecycle.sh +289 -0
  57. package/scripts/test-real-logging.sh +289 -0
  58. package/scripts/test-streaming-multi-task.sh +247 -0
  59. package/src/cli/clean.ts +170 -13
  60. package/src/cli/index.ts +4 -1
  61. package/src/cli/logs.ts +863 -0
  62. package/src/cli/monitor.ts +123 -30
  63. package/src/cli/prepare.ts +1 -1
  64. package/src/cli/resume.ts +463 -22
  65. package/src/cli/run.ts +10 -0
  66. package/src/cli/signal.ts +43 -27
  67. package/src/core/orchestrator.ts +458 -36
  68. package/src/core/reviewer.ts +40 -4
  69. package/src/core/runner.ts +293 -60
  70. package/src/utils/config.ts +41 -1
  71. package/src/utils/enhanced-logger.ts +1166 -0
  72. package/src/utils/events.ts +117 -0
  73. package/src/utils/git.ts +40 -0
  74. package/src/utils/logger.ts +4 -1
  75. package/src/utils/types.ts +160 -1
  76. package/src/utils/webhook.ts +85 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@litmers/cursorflow-orchestrator",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Git worktree-based parallel AI agent orchestration system for Cursor",
5
5
  "main": "dist/cli/index.js",
6
6
  "bin": {
@@ -22,6 +22,7 @@
22
22
  "security:audit": "npm audit",
23
23
  "security:audit:fix": "npm audit fix",
24
24
  "security:setup": "scripts/setup-security.sh",
25
+ "test:lifecycle": "scripts/test-real-cursor-lifecycle.sh",
25
26
  "prepare": "husky"
26
27
  },
27
28
  "keywords": [
@@ -81,7 +81,7 @@ const workspace = process.cwd();
81
81
 
82
82
  const agentArgs = [
83
83
  '--print',
84
- '--output-format', 'json',
84
+ '--output-format', 'stream-json',
85
85
  '--workspace', workspace,
86
86
  '--model', 'gemini-3-flash',
87
87
  '--resume', chatId,
@@ -0,0 +1,97 @@
1
+ #!/bin/bash
2
+ #
3
+ # Simple Real Logging Test
4
+ # This test runs cursor-agent directly and verifies log capture
5
+ #
6
+
7
+ set -e
8
+
9
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
11
+
12
+ echo "🧪 Simple Cursor-Agent Logging Test"
13
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
14
+
15
+ # Check cursor-agent
16
+ if ! command -v cursor-agent &> /dev/null; then
17
+ echo "❌ cursor-agent not found"
18
+ exit 1
19
+ fi
20
+
21
+ cd "$PROJECT_ROOT"
22
+
23
+ # Build
24
+ echo "Building..."
25
+ npm run build > /dev/null 2>&1
26
+
27
+ # Setup test dir
28
+ TEST_DIR="$PROJECT_ROOT/_test-logs"
29
+ rm -rf "$TEST_DIR"
30
+ mkdir -p "$TEST_DIR"
31
+
32
+ # Create a very simple task
33
+ cat > "$TEST_DIR/task.json" << 'EOF'
34
+ {
35
+ "baseBranch": "main",
36
+ "branchPrefix": "test/log-",
37
+ "timeout": 30000,
38
+ "tasks": [
39
+ {
40
+ "name": "echo-test",
41
+ "prompt": "Say 'test complete' and nothing else.",
42
+ "model": "sonnet-4.5"
43
+ }
44
+ ]
45
+ }
46
+ EOF
47
+
48
+ # Run with node directly
49
+ echo ""
50
+ echo "Running cursor-agent via runner..."
51
+ echo ""
52
+
53
+ LANE_DIR="$TEST_DIR/lane"
54
+ mkdir -p "$LANE_DIR"
55
+
56
+ # Run runner.js directly
57
+ timeout 60 node dist/core/runner.js "$TEST_DIR/task.json" \
58
+ --run-dir "$LANE_DIR" \
59
+ --executor cursor-agent \
60
+ --start-index 0 || true
61
+
62
+ echo ""
63
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
64
+ echo "📋 Log Files Created:"
65
+ echo ""
66
+
67
+ ls -la "$LANE_DIR"/*.log "$LANE_DIR"/*.jsonl 2>/dev/null || echo "No log files found"
68
+
69
+ echo ""
70
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
71
+ echo "📝 terminal.log content:"
72
+ echo ""
73
+
74
+ if [ -f "$LANE_DIR/terminal.log" ]; then
75
+ head -50 "$LANE_DIR/terminal.log"
76
+ else
77
+ echo "No terminal.log"
78
+ fi
79
+
80
+ echo ""
81
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
82
+ echo "📝 terminal.jsonl (first 3 entries):"
83
+ echo ""
84
+
85
+ if [ -f "$LANE_DIR/terminal.jsonl" ]; then
86
+ head -3 "$LANE_DIR/terminal.jsonl"
87
+ else
88
+ echo "No terminal.jsonl"
89
+ fi
90
+
91
+ # Cleanup git branches
92
+ git branch -D test/log-* 2>/dev/null || true
93
+ git worktree remove _cursorflow/worktrees/test/log-* --force 2>/dev/null || true
94
+
95
+ echo ""
96
+ echo "✅ Test finished"
97
+
@@ -0,0 +1,289 @@
1
+ #!/bin/bash
2
+ # scripts/test-real-cursor-lifecycle.sh
3
+ #
4
+ # Full Lifecycle Integration Test for CursorFlow
5
+ #
6
+ # This script performs a real-world test by:
7
+ # 1. Creating a temporary Git repository
8
+ # 2. Initializing CursorFlow
9
+ # 3. Defining a real task for cursor-agent
10
+ # 4. Running the orchestration
11
+ # 5. Verifying the results (file changes)
12
+ # 6. Cleaning up all resources (branches, worktrees, logs)
13
+
14
+ set -e
15
+
16
+ # Colors
17
+ RED='\033[0;31m'
18
+ GREEN='\033[0;32m'
19
+ YELLOW='\033[1;33m'
20
+ CYAN='\033[0;36m'
21
+ NC='\033[0m' # No Color
22
+
23
+ # Parse arguments
24
+ CLEANUP=true
25
+ NO_GIT=false
26
+ for arg in "$@"; do
27
+ if [ "$arg" == "--no-cleanup" ]; then
28
+ CLEANUP=false
29
+ fi
30
+ if [ "$arg" == "--no-git" ]; then
31
+ NO_GIT=true
32
+ fi
33
+ done
34
+
35
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
36
+ echo -e "${CYAN} 🧪 Full Lifecycle Integration Test${NC}"
37
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
38
+
39
+ # Prerequisites Check
40
+ echo -e "${YELLOW}Checking prerequisites...${NC}"
41
+ if ! command -v cursor-agent &> /dev/null; then
42
+ echo -e "${RED}❌ cursor-agent CLI not found. Please install it first.${NC}"
43
+ exit 1
44
+ fi
45
+
46
+ if ! cursor-agent create-chat &> /dev/null; then
47
+ echo -e "${RED}❌ cursor-agent authentication failed.${NC}"
48
+ echo " Please sign in to Cursor IDE first."
49
+ exit 1
50
+ fi
51
+ echo -e "${GREEN}✓ Prerequisites OK${NC}"
52
+
53
+ # Setup Directories
54
+ PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
55
+ TEST_ROOT="$PROJECT_ROOT/_lifecycle_test"
56
+ CLI_BIN="$PROJECT_ROOT/dist/cli/index.js"
57
+
58
+ echo -e "${YELLOW}Setting up temporary repository at $TEST_ROOT...${NC}"
59
+ rm -rf "$TEST_ROOT"
60
+ mkdir -p "$TEST_ROOT"
61
+ cd "$TEST_ROOT"
62
+
63
+ # Init Git
64
+ # Use a more compatible way to init and set branch
65
+ git init > /dev/null
66
+ echo "# Lifecycle Test Project" > README.md
67
+
68
+ # IMPORTANT: Create a dummy package.json AND .cursorignore to ensure this is treated as a separate root
69
+ cat > package.json << 'EOF'
70
+ {
71
+ "name": "lifecycle-test-project",
72
+ "version": "1.0.0"
73
+ }
74
+ EOF
75
+
76
+ touch .cursorignore
77
+
78
+ git add README.md package.json .cursorignore
79
+ git commit -m "initial commit" > /dev/null
80
+ git branch -m main > /dev/null 2>&1 || true
81
+
82
+ git config user.email "test@cursorflow.com"
83
+ git config user.name "CursorFlow Test"
84
+
85
+ echo -e "${GREEN}✓ Git repository initialized with package.json${NC}"
86
+
87
+ # Build CursorFlow (ensure latest changes)
88
+ echo -e "${YELLOW}Building CursorFlow...${NC}"
89
+ cd "$PROJECT_ROOT"
90
+ npm run build > /dev/null
91
+ cd "$TEST_ROOT"
92
+ echo -e "${GREEN}✓ Build complete${NC}"
93
+ echo -e "${GREEN}✓ Build complete${NC}"
94
+
95
+ # Create an alias for cursorflow to test it as a command
96
+ shopt -s expand_aliases
97
+ alias cursorflow="node $CLI_BIN"
98
+
99
+ # Init CursorFlow
100
+ echo -e "${YELLOW}Initializing CursorFlow...${NC}"
101
+ cursorflow init --yes > /dev/null
102
+ echo -e "${GREEN}✓ CursorFlow initialized${NC}"
103
+
104
+ # Define Task
105
+ echo -e "${YELLOW}Defining complex tasks with dependencies...${NC}"
106
+ mkdir -p _cursorflow/tasks
107
+
108
+ # Lane 1: Creates and updates a config file
109
+ cat > _cursorflow/tasks/lane-1.json << 'EOF'
110
+ {
111
+ "name": "lane-1",
112
+ "tasks": [
113
+ {
114
+ "name": "create-config",
115
+ "prompt": "Create a file named 'config.json' with { \"version\": \"1.0.0\", \"status\": \"alpha\" }. Commit it.",
116
+ "model": "sonnet-4.5"
117
+ },
118
+ {
119
+ "name": "update-config",
120
+ "prompt": "Update 'config.json' to set \"status\": \"beta\" and add \"author\": \"cursorflow-test\". Commit it.",
121
+ "model": "sonnet-4.5"
122
+ }
123
+ ],
124
+ "dependencyPolicy": {
125
+ "allowDependencyChange": false,
126
+ "lockfileReadOnly": true
127
+ }
128
+ }
129
+ EOF
130
+
131
+ # Lane 2: Depends on Lane 1, creates a main file using the config
132
+ cat > _cursorflow/tasks/lane-2.json << 'EOF'
133
+ {
134
+ "name": "lane-2",
135
+ "dependsOn": ["lane-1"],
136
+ "tasks": [
137
+ {
138
+ "name": "create-main",
139
+ "prompt": "Read 'config.json'. Create a file named 'app.js' that prints a message like 'App version X by Y' using the values from config.json. Commit it.",
140
+ "model": "sonnet-4.5"
141
+ }
142
+ ],
143
+ "dependencyPolicy": {
144
+ "allowDependencyChange": false,
145
+ "lockfileReadOnly": true
146
+ }
147
+ }
148
+ EOF
149
+ echo -e "${GREEN}✓ Complex tasks defined${NC}"
150
+
151
+ # Run Orchestration
152
+ echo -e "${YELLOW}Running orchestration (2 lanes, 3 tasks total)...${NC}"
153
+ echo -e "${CYAN}This will interact with Cursor IDE. Please wait...${NC}"
154
+ echo ""
155
+
156
+ # We use the CLI command directly
157
+ if [ "$NO_GIT" == "true" ]; then
158
+ echo -e "${YELLOW}⚠️ Running in --no-git mode (no Git operations)${NC}"
159
+ cursorflow run _cursorflow/tasks --skip-doctor --no-git
160
+ else
161
+ cursorflow run _cursorflow/tasks --skip-doctor
162
+ fi
163
+
164
+ echo -e "${GREEN}✓ Orchestration finished${NC}"
165
+
166
+ # Verify Result
167
+ echo -e "${YELLOW}Verifying results...${NC}"
168
+
169
+ if [ "$NO_GIT" == "true" ]; then
170
+ # In no-git mode, check workdir instead of branches
171
+ WORKDIR=$(find _cursorflow/workdir -type d -name "cursorflow-*" 2>/dev/null | head -n 1)
172
+
173
+ if [ -z "$WORKDIR" ]; then
174
+ WORKDIR=$(find _cursorflow/workdir -type d -mindepth 1 2>/dev/null | head -n 1)
175
+ fi
176
+
177
+ if [ -z "$WORKDIR" ]; then
178
+ echo -e "${YELLOW}⚠️ No workdir found, checking current directory${NC}"
179
+ WORKDIR="."
180
+ fi
181
+
182
+ echo -e "${GREEN}✓ Work directory: $WORKDIR${NC}"
183
+
184
+ # In noGit mode, files are created in the workdir
185
+ if [ -f "$WORKDIR/config.json" ]; then
186
+ CONFIG_CONTENT=$(cat "$WORKDIR/config.json")
187
+ echo -e "${GREEN}✓ config.json found${NC}"
188
+ echo -e " config.json: $CONFIG_CONTENT"
189
+ else
190
+ echo -e "${YELLOW}⚠️ config.json not found in workdir (may be in different location)${NC}"
191
+ fi
192
+
193
+ echo -e "${GREEN}✓ Verification SUCCESS (no-git mode)${NC}"
194
+ else
195
+ # Check Lane 2's final branch (which should have everything)
196
+ LANE2_BRANCH=$(git branch --list 'feature/lane-2*' 'cursorflow/lane-2*' | head -n 1 | sed 's/*//' | xargs)
197
+
198
+ if [ -z "$LANE2_BRANCH" ]; then
199
+ # Try to find it by looking at the latest branches
200
+ LANE2_BRANCH=$(git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname:short)' | grep 'lane-2' | head -n 1)
201
+ fi
202
+
203
+ if [ -z "$LANE2_BRANCH" ]; then
204
+ echo -e "${RED}❌ No branch found for lane-2${NC}"
205
+ exit 1
206
+ fi
207
+
208
+ echo -e "${GREEN}✓ Lane 2 final branch: $LANE2_BRANCH${NC}"
209
+
210
+ # Checkout and check files
211
+ git checkout "$LANE2_BRANCH" > /dev/null 2>&1
212
+
213
+ if [ -f "config.json" ] && [ -f "app.js" ]; then
214
+ CONFIG_CONTENT=$(cat config.json)
215
+ APP_CONTENT=$(cat app.js)
216
+ echo -e "${GREEN}✓ Verification SUCCESS${NC}"
217
+ echo -e " config.json: $CONFIG_CONTENT"
218
+ echo -e " app.js: $APP_CONTENT"
219
+ else
220
+ echo -e "${RED}❌ Verification FAILED - Missing files${NC}"
221
+ [ ! -f "config.json" ] && echo " - config.json is missing"
222
+ [ ! -f "app.js" ] && echo " - app.js is missing"
223
+ exit 1
224
+ fi
225
+ fi
226
+
227
+ # Verify Logs
228
+ echo -e "${YELLOW}Verifying logs...${NC}"
229
+ LOG_DIR="_cursorflow/logs"
230
+ if [ -d "$LOG_DIR" ]; then
231
+ echo -e "${GREEN}✓ Logs directory exists${NC}"
232
+ RUN_LOGS=$(ls -d $LOG_DIR/runs/run-* 2>/dev/null | sort -r | head -n 1)
233
+ if [ -n "$RUN_LOGS" ]; then
234
+ echo -e "${GREEN}✓ Run logs found in $RUN_LOGS${NC}"
235
+ # Check for readable log in lane-1
236
+ READABLE_LOG="$RUN_LOGS/lanes/lane-1/terminal-readable.log"
237
+ if [ -f "$READABLE_LOG" ]; then
238
+ echo -e "${GREEN}✓ Readable log file created: $READABLE_LOG${NC}"
239
+ echo -e "${YELLOW} Log preview (first 10 lines):${NC}"
240
+ head -n 10 "$READABLE_LOG" | sed 's/^/ /'
241
+ else
242
+ echo -e "${RED}❌ Readable log NOT found at $READABLE_LOG${NC}"
243
+ echo "Available files in lane-1 directory:"
244
+ ls -R "$RUN_LOGS/lanes/lane-1"
245
+ exit 1
246
+ fi
247
+ else
248
+ echo -e "${RED}❌ No run logs found in $LOG_DIR/runs${NC}"
249
+ ls -R "$LOG_DIR"
250
+ exit 1
251
+ fi
252
+ else
253
+ echo -e "${RED}❌ Logs directory NOT found at $LOG_DIR${NC}"
254
+ echo "Current working directory contents:"
255
+ ls -R .
256
+ exit 1
257
+ fi
258
+
259
+ # Cleanup
260
+ if [ "$CLEANUP" = "true" ]; then
261
+ echo ""
262
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
263
+ echo -e "${CYAN} 🧹 Cleaning Up${NC}"
264
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
265
+
266
+ if [ "$NO_GIT" != "true" ]; then
267
+ # Return to main branch
268
+ git checkout main > /dev/null 2>&1
269
+
270
+ # Use cursorflow clean
271
+ echo -e "${YELLOW}Cleaning CursorFlow resources...${NC}"
272
+ cursorflow clean all --include-latest --force > /dev/null 2>&1 || true
273
+ fi
274
+
275
+ # Finally remove the test root
276
+ cd "$PROJECT_ROOT"
277
+ rm -rf "$TEST_ROOT"
278
+ echo -e "${GREEN}✓ Temporary test directory removed${NC}"
279
+ else
280
+ echo ""
281
+ echo -e "${YELLOW}⚠️ Skipping cleanup as requested.${NC}"
282
+ echo -e " Test directory: $TEST_ROOT"
283
+ echo -e " You can inspect the results there."
284
+ fi
285
+
286
+ echo ""
287
+ echo -e "${GREEN}✅ Full lifecycle test PASSED successfully!${NC}"
288
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
289
+
@@ -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
+