@contextgraph/agent 0.4.0 → 0.4.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.
@@ -24,7 +24,14 @@
24
24
  "Bash(npm publish:*)",
25
25
  "Bash(cat:*)",
26
26
  "WebSearch",
27
- "Bash(claude:*)"
27
+ "Bash(claude:*)",
28
+ "Bash(find:*)",
29
+ "Bash(grep:*)",
30
+ "Bash(vercel logs:*)",
31
+ "Bash(vercel inspect:*)",
32
+ "Bash(pnpm install:*)",
33
+ "Bash(gh pr view:*)",
34
+ "Bash(gh pr diff:*)"
28
35
  ],
29
36
  "deny": [],
30
37
  "ask": []
package/CHANGELOG.md CHANGED
@@ -16,7 +16,7 @@ All notable changes to this project will be documented in this file.
16
16
  ## [0.1.0] - 2025-11-15
17
17
 
18
18
  ### Added
19
- - Initial release of @context-graph/agent
19
+ - Initial release of @contextgraph/agent
20
20
  - OAuth authentication with contextgraph.dev
21
21
  - CLI commands: auth, whoami, run, prepare, execute
22
22
  - Autonomous agent loop with tree traversal
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @context-graph/agent
1
+ # @contextgraph/agent
2
2
 
3
3
  Autonomous agent for contextgraph action execution.
4
4
 
@@ -7,13 +7,13 @@ Autonomous agent for contextgraph action execution.
7
7
  No installation required! Use npx to run commands directly:
8
8
 
9
9
  ```bash
10
- npx @context-graph/agent <command>
10
+ npx @contextgraph/agent <command>
11
11
  ```
12
12
 
13
13
  Or install globally for convenience:
14
14
 
15
15
  ```bash
16
- npm install -g @context-graph/agent
16
+ npm install -g @contextgraph/agent
17
17
  ```
18
18
 
19
19
  ## Prerequisites
@@ -28,13 +28,13 @@ npm install -g @context-graph/agent
28
28
  1. Authenticate with contextgraph.dev:
29
29
 
30
30
  ```bash
31
- npx @context-graph/agent auth
31
+ npx @contextgraph/agent auth
32
32
  ```
33
33
 
34
34
  2. Run the agent:
35
35
 
36
36
  ```bash
37
- npx @context-graph/agent run
37
+ npx @contextgraph/agent run
38
38
  ```
39
39
 
40
40
  ### Option 2: API Token (CI/CD & Cloud Deployments)
@@ -43,7 +43,7 @@ For automated environments, use an API token:
43
43
 
44
44
  ```bash
45
45
  export CONTEXTGRAPH_API_TOKEN="your-api-token"
46
- npx @context-graph/agent run
46
+ npx @contextgraph/agent run
47
47
  ```
48
48
 
49
49
  Get your API token from https://contextgraph.dev/settings/tokens
@@ -54,7 +54,7 @@ Get your API token from https://contextgraph.dev/settings/tokens
54
54
  Authenticate with contextgraph.dev using OAuth:
55
55
 
56
56
  ```bash
57
- npx @context-graph/agent auth
57
+ npx @contextgraph/agent auth
58
58
  ```
59
59
 
60
60
  Opens your browser to complete authentication. Credentials are securely stored in `~/.contextgraph/`.
@@ -63,7 +63,7 @@ Opens your browser to complete authentication. Credentials are securely stored i
63
63
  Check your current authentication status:
64
64
 
65
65
  ```bash
66
- npx @context-graph/agent whoami
66
+ npx @contextgraph/agent whoami
67
67
  ```
68
68
 
69
69
  Shows your user ID and token expiration.
@@ -72,7 +72,7 @@ Shows your user ID and token expiration.
72
72
  Run the autonomous agent loop:
73
73
 
74
74
  ```bash
75
- npx @context-graph/agent run <action-id>
75
+ npx @contextgraph/agent run <action-id>
76
76
  ```
77
77
 
78
78
  The agent will:
@@ -86,7 +86,7 @@ The agent will:
86
86
  Prepare a single action:
87
87
 
88
88
  ```bash
89
- npx @context-graph/agent prepare <action-id>
89
+ npx @contextgraph/agent prepare <action-id>
90
90
  ```
91
91
 
92
92
  Spawns Claude to assess whether the action should be broken down into child actions or is ready to execute.
@@ -95,7 +95,7 @@ Spawns Claude to assess whether the action should be broken down into child acti
95
95
  Execute a single prepared action:
96
96
 
97
97
  ```bash
98
- npx @context-graph/agent execute <action-id>
98
+ npx @contextgraph/agent execute <action-id>
99
99
  ```
100
100
 
101
101
  Spawns Claude to implement the action and mark it complete.
@@ -133,7 +133,7 @@ The agent integrates with contextgraph.dev's MCP server to:
133
133
  If authentication fails or tokens expire:
134
134
 
135
135
  ```bash
136
- npx @context-graph/agent auth
136
+ npx @contextgraph/agent auth
137
137
  ```
138
138
 
139
139
  This will open a new browser session to re-authenticate.
@@ -143,8 +143,8 @@ This will open a new browser session to re-authenticate.
143
143
  Tokens expire after a period of time. Re-authenticate with:
144
144
 
145
145
  ```bash
146
- npx @context-graph/agent whoami # Check expiration
147
- npx @context-graph/agent auth # Re-authenticate if expired
146
+ npx @contextgraph/agent whoami # Check expiration
147
+ npx @contextgraph/agent auth # Re-authenticate if expired
148
148
  ```
149
149
 
150
150
  ### Network errors
@@ -156,8 +156,8 @@ Ensure you have internet connectivity and can reach:
156
156
  ## Links
157
157
 
158
158
  - [contextgraph.dev](https://contextgraph.dev) - Main platform
159
- - [GitHub Repository](https://github.com/context-graph/agent) - Source code and issues
160
- - [Issue Tracker](https://github.com/context-graph/agent/issues) - Report bugs or request features
159
+ - [GitHub Repository](https://github.com/contextgraph/agent) - Source code and issues
160
+ - [Issue Tracker](https://github.com/contextgraph/agent/issues) - Report bugs or request features
161
161
 
162
162
  ## Configuration
163
163
 
@@ -197,7 +197,7 @@ When no work is available, the worker waits before polling again. The wait time
197
197
  Example:
198
198
  ```bash
199
199
  # Poll more frequently (every 1 second initially, up to 15 seconds max)
200
- WORKER_INITIAL_POLL_INTERVAL=1000 WORKER_MAX_POLL_INTERVAL=15000 npx @context-graph/agent run <action-id>
200
+ WORKER_INITIAL_POLL_INTERVAL=1000 WORKER_MAX_POLL_INTERVAL=15000 npx @contextgraph/agent run <action-id>
201
201
  ```
202
202
 
203
203
  ### Claude Agent SDK
package/dist/index.js CHANGED
@@ -91,44 +91,120 @@ function getSuccessPage() {
91
91
  <head>
92
92
  <meta charset="utf-8">
93
93
  <title>Authentication Successful</title>
94
+ <link rel="preconnect" href="https://fonts.googleapis.com">
95
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
96
+ <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
94
97
  <style>
98
+ :root {
99
+ --bg: hsl(0 0% 8%);
100
+ --tile-bg: hsl(0 0% 12%);
101
+ --cream: hsl(45 30% 85%);
102
+ --orange: hsl(30 95% 55%);
103
+ --subtitle: hsl(0 0% 55%);
104
+ --border: hsl(0 0% 20%);
105
+ }
106
+
107
+ * {
108
+ box-sizing: border-box;
109
+ }
110
+
95
111
  body {
96
- font-family: system-ui, -apple-system, sans-serif;
112
+ font-family: 'JetBrains Mono', 'SF Mono', 'Monaco', 'Inconsolata', monospace;
97
113
  display: flex;
98
114
  align-items: center;
99
115
  justify-content: center;
100
116
  min-height: 100vh;
101
117
  margin: 0;
102
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
118
+ background: var(--bg);
119
+ padding: 1rem;
103
120
  }
121
+
104
122
  .container {
105
- background: white;
123
+ background: var(--tile-bg);
106
124
  padding: 3rem;
107
- border-radius: 1rem;
108
- box-shadow: 0 20px 60px rgba(0,0,0,0.3);
125
+ border-radius: 0.75rem;
126
+ border: 1px solid var(--border);
109
127
  text-align: center;
110
128
  max-width: 400px;
129
+ width: 100%;
130
+ }
131
+
132
+ .icon-container {
133
+ width: 80px;
134
+ height: 80px;
135
+ margin: 0 auto 1.5rem;
136
+ background: hsl(145 50% 12%);
137
+ border-radius: 50%;
138
+ display: flex;
139
+ align-items: center;
140
+ justify-content: center;
141
+ border: 2px solid hsl(145 50% 25%);
111
142
  }
143
+
112
144
  .icon {
113
- font-size: 4rem;
114
- margin-bottom: 1rem;
145
+ width: 40px;
146
+ height: 40px;
147
+ stroke: hsl(145 70% 55%);
148
+ stroke-width: 3;
149
+ fill: none;
115
150
  }
151
+
116
152
  h1 {
117
- color: #667eea;
118
- margin: 0 0 1rem 0;
119
- font-size: 1.5rem;
153
+ color: var(--cream);
154
+ margin: 0 0 0.75rem 0;
155
+ font-size: 1.25rem;
156
+ font-weight: 500;
157
+ letter-spacing: -0.02em;
120
158
  }
159
+
121
160
  p {
122
- color: #666;
161
+ color: var(--subtitle);
123
162
  margin: 0;
163
+ font-size: 0.875rem;
164
+ line-height: 1.6;
165
+ }
166
+
167
+ .brand {
168
+ margin-top: 2rem;
169
+ padding-top: 1.5rem;
170
+ border-top: 1px solid var(--border);
171
+ }
172
+
173
+ .brand-text {
174
+ color: var(--orange);
175
+ font-size: 0.75rem;
176
+ font-weight: 500;
177
+ letter-spacing: 0.05em;
178
+ }
179
+
180
+ @keyframes check-draw {
181
+ 0% {
182
+ stroke-dashoffset: 24;
183
+ }
184
+ 100% {
185
+ stroke-dashoffset: 0;
186
+ }
187
+ }
188
+
189
+ .icon polyline {
190
+ stroke-dasharray: 24;
191
+ stroke-dashoffset: 24;
192
+ animation: check-draw 0.4s ease-out 0.2s forwards;
124
193
  }
125
194
  </style>
126
195
  </head>
127
196
  <body>
128
197
  <div class="container">
129
- <div class="icon">\u2705</div>
130
- <h1>Authentication successful!</h1>
198
+ <div class="icon-container">
199
+ <svg class="icon" viewBox="0 0 24 24">
200
+ <polyline points="4 12 10 18 20 6"></polyline>
201
+ </svg>
202
+ </div>
203
+ <h1>Authentication successful</h1>
131
204
  <p>You can close this window and return to your terminal.</p>
205
+ <div class="brand">
206
+ <span class="brand-text">CONTEXTGRAPH</span>
207
+ </div>
132
208
  </div>
133
209
  </body>
134
210
  </html>
@@ -141,44 +217,131 @@ function getErrorPage(message) {
141
217
  <head>
142
218
  <meta charset="utf-8">
143
219
  <title>Authentication Error</title>
220
+ <link rel="preconnect" href="https://fonts.googleapis.com">
221
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
222
+ <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
144
223
  <style>
224
+ :root {
225
+ --bg: hsl(0 0% 8%);
226
+ --tile-bg: hsl(0 0% 12%);
227
+ --red: hsl(0 80% 60%);
228
+ --red-dim: hsl(0 50% 12%);
229
+ --red-border: hsl(0 50% 25%);
230
+ --cream: hsl(45 30% 85%);
231
+ --orange: hsl(30 95% 55%);
232
+ --subtitle: hsl(0 0% 55%);
233
+ --border: hsl(0 0% 20%);
234
+ }
235
+
236
+ * {
237
+ box-sizing: border-box;
238
+ }
239
+
145
240
  body {
146
- font-family: system-ui, -apple-system, sans-serif;
241
+ font-family: 'JetBrains Mono', 'SF Mono', 'Monaco', 'Inconsolata', monospace;
147
242
  display: flex;
148
243
  align-items: center;
149
244
  justify-content: center;
150
245
  min-height: 100vh;
151
246
  margin: 0;
152
- background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
247
+ background: var(--bg);
248
+ padding: 1rem;
153
249
  }
250
+
154
251
  .container {
155
- background: white;
252
+ background: var(--tile-bg);
156
253
  padding: 3rem;
157
- border-radius: 1rem;
158
- box-shadow: 0 20px 60px rgba(0,0,0,0.3);
254
+ border-radius: 0.75rem;
255
+ border: 1px solid var(--border);
159
256
  text-align: center;
160
257
  max-width: 400px;
258
+ width: 100%;
259
+ }
260
+
261
+ .icon-container {
262
+ width: 80px;
263
+ height: 80px;
264
+ margin: 0 auto 1.5rem;
265
+ background: var(--red-dim);
266
+ border-radius: 50%;
267
+ display: flex;
268
+ align-items: center;
269
+ justify-content: center;
270
+ border: 2px solid var(--red-border);
161
271
  }
272
+
162
273
  .icon {
163
- font-size: 4rem;
164
- margin-bottom: 1rem;
274
+ width: 40px;
275
+ height: 40px;
276
+ stroke: var(--red);
277
+ stroke-width: 3;
278
+ fill: none;
165
279
  }
280
+
166
281
  h1 {
167
- color: #f5576c;
168
- margin: 0 0 1rem 0;
169
- font-size: 1.5rem;
282
+ color: var(--red);
283
+ margin: 0 0 0.75rem 0;
284
+ font-size: 1.25rem;
285
+ font-weight: 500;
286
+ letter-spacing: -0.02em;
170
287
  }
288
+
171
289
  p {
172
- color: #666;
290
+ color: var(--subtitle);
173
291
  margin: 0;
292
+ font-size: 0.875rem;
293
+ line-height: 1.6;
294
+ }
295
+
296
+ .brand {
297
+ margin-top: 2rem;
298
+ padding-top: 1.5rem;
299
+ border-top: 1px solid var(--border);
300
+ }
301
+
302
+ .brand-text {
303
+ color: var(--orange);
304
+ font-size: 0.75rem;
305
+ font-weight: 500;
306
+ letter-spacing: 0.05em;
307
+ }
308
+
309
+ @keyframes x-draw {
310
+ 0% {
311
+ stroke-dashoffset: 34;
312
+ }
313
+ 100% {
314
+ stroke-dashoffset: 0;
315
+ }
316
+ }
317
+
318
+ .icon line {
319
+ stroke-dasharray: 17;
320
+ stroke-dashoffset: 17;
321
+ }
322
+
323
+ .icon line:first-child {
324
+ animation: x-draw 0.3s ease-out 0.2s forwards;
325
+ }
326
+
327
+ .icon line:last-child {
328
+ animation: x-draw 0.3s ease-out 0.35s forwards;
174
329
  }
175
330
  </style>
176
331
  </head>
177
332
  <body>
178
333
  <div class="container">
179
- <div class="icon">\u274C</div>
334
+ <div class="icon-container">
335
+ <svg class="icon" viewBox="0 0 24 24">
336
+ <line x1="6" y1="6" x2="18" y2="18"></line>
337
+ <line x1="18" y1="6" x2="6" y2="18"></line>
338
+ </svg>
339
+ </div>
180
340
  <h1>Authentication error</h1>
181
341
  <p>${message}</p>
342
+ <div class="brand">
343
+ <span class="brand-text">CONTEXTGRAPH</span>
344
+ </div>
182
345
  </div>
183
346
  </body>
184
347
  </html>
@@ -191,33 +354,80 @@ function getNotFoundPage() {
191
354
  <head>
192
355
  <meta charset="utf-8">
193
356
  <title>Not Found</title>
357
+ <link rel="preconnect" href="https://fonts.googleapis.com">
358
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
359
+ <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
194
360
  <style>
361
+ :root {
362
+ --bg: hsl(0 0% 8%);
363
+ --tile-bg: hsl(0 0% 12%);
364
+ --cream: hsl(45 30% 85%);
365
+ --orange: hsl(30 95% 55%);
366
+ --subtitle: hsl(0 0% 55%);
367
+ --border: hsl(0 0% 20%);
368
+ }
369
+
370
+ * {
371
+ box-sizing: border-box;
372
+ }
373
+
195
374
  body {
196
- font-family: system-ui, -apple-system, sans-serif;
375
+ font-family: 'JetBrains Mono', 'SF Mono', 'Monaco', 'Inconsolata', monospace;
197
376
  display: flex;
198
377
  align-items: center;
199
378
  justify-content: center;
200
379
  min-height: 100vh;
201
380
  margin: 0;
202
- background: #f0f0f0;
381
+ background: var(--bg);
382
+ padding: 1rem;
203
383
  }
384
+
204
385
  .container {
205
- background: white;
386
+ background: var(--tile-bg);
206
387
  padding: 3rem;
207
- border-radius: 1rem;
208
- box-shadow: 0 4px 12px rgba(0,0,0,0.1);
388
+ border-radius: 0.75rem;
389
+ border: 1px solid var(--border);
209
390
  text-align: center;
210
391
  max-width: 400px;
392
+ width: 100%;
211
393
  }
394
+
395
+ .code {
396
+ color: var(--orange);
397
+ font-size: 3rem;
398
+ font-weight: 700;
399
+ margin: 0 0 0.5rem 0;
400
+ letter-spacing: -0.02em;
401
+ }
402
+
212
403
  h1 {
213
- color: #666;
404
+ color: var(--cream);
214
405
  margin: 0;
406
+ font-size: 1rem;
407
+ font-weight: 400;
408
+ }
409
+
410
+ .brand {
411
+ margin-top: 2rem;
412
+ padding-top: 1.5rem;
413
+ border-top: 1px solid var(--border);
414
+ }
415
+
416
+ .brand-text {
417
+ color: var(--orange);
418
+ font-size: 0.75rem;
419
+ font-weight: 500;
420
+ letter-spacing: 0.05em;
215
421
  }
216
422
  </style>
217
423
  </head>
218
424
  <body>
219
425
  <div class="container">
220
- <h1>404 Not Found</h1>
426
+ <div class="code">404</div>
427
+ <h1>Not Found</h1>
428
+ <div class="brand">
429
+ <span class="brand-text">CONTEXTGRAPH</span>
430
+ </div>
221
431
  </div>
222
432
  </body>
223
433
  </html>
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/index.ts","../src/callback-server.ts","../src/credentials.ts","../src/auth-flow.ts","../src/workflows/auth.ts","../src/claude-sdk.ts","../src/plugin-setup.ts","../src/sdk-event-transformer.ts","../src/fetch-with-retry.ts","../src/log-transport.ts","../src/log-buffer.ts","../src/heartbeat-manager.ts","../src/workflows/prepare.ts","../src/workflows/execute.ts","../src/workflows/agent.ts","../src/api-client.ts","../src/workspace-prep.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport { runAuth } from '../workflows/auth.js';\nimport { runPrepare } from '../workflows/prepare.js';\nimport { runExecute } from '../workflows/execute.js';\nimport { runLocalAgent } from '../workflows/agent.js';\nimport { loadCredentials, isExpired, isTokenExpired } from '../credentials.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageJson = JSON.parse(\n readFileSync(join(__dirname, '../package.json'), 'utf-8')\n);\n\nconst program = new Command();\n\nprogram\n .name('contextgraph-agent')\n .description('Autonomous agent for contextgraph action execution')\n .version(packageJson.version);\n\nprogram\n .command('run')\n .description('Run continuous worker loop (claims and executes actions until Ctrl+C)')\n .action(async () => {\n try {\n await runLocalAgent();\n } catch (error) {\n if (error instanceof Error) {\n console.error('Error running agent:', error.message || '(no message)');\n if (error.stack) {\n console.error('\\nStack trace:');\n console.error(error.stack);\n }\n } else {\n console.error('Error running agent:', error);\n }\n process.exit(1);\n }\n });\n\nprogram\n .command('auth')\n .description('Authenticate with contextgraph.dev')\n .action(async () => {\n try {\n await runAuth();\n } catch (error) {\n console.error('Error during authentication:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n });\n\nprogram\n .command('prepare')\n .argument('<action-id>', 'Action ID to prepare')\n .description('Prepare a single action')\n .action(async (actionId: string) => {\n try {\n await runPrepare(actionId);\n } catch (error) {\n console.error('Error preparing action:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n });\n\nprogram\n .command('execute')\n .argument('<action-id>', 'Action ID to execute')\n .description('Execute a single action')\n .action(async (actionId: string) => {\n try {\n await runExecute(actionId);\n } catch (error) {\n console.error('Error executing action:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n });\n\nprogram\n .command('whoami')\n .description('Show current authentication status')\n .action(async () => {\n try {\n const credentials = await loadCredentials();\n\n if (!credentials) {\n console.log('Not authenticated. Run `contextgraph-agent auth` to authenticate.');\n process.exit(1);\n }\n\n if (isExpired(credentials) || isTokenExpired(credentials.clerkToken)) {\n console.log('⚠️ Token expired. Run `contextgraph-agent auth` to re-authenticate.');\n console.log(`User ID: ${credentials.userId}`);\n console.log(`Expired at: ${credentials.expiresAt}`);\n process.exit(1);\n }\n\n console.log('✅ Authenticated');\n console.log(`User ID: ${credentials.userId}`);\n console.log(`Expires at: ${credentials.expiresAt}`);\n } catch (error) {\n console.error('Error checking authentication:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n });\n\nprogram.parse();\n","import http from 'http';\nimport { URL } from 'url';\nimport type { CallbackResult } from './types/actions.js';\n\nexport type CallbackServerResult = {\n port: number;\n waitForCallback: () => Promise<CallbackResult>;\n close: () => Promise<void>;\n};\n\nconst MIN_PORT = 3000;\nconst MAX_PORT = 3100;\n\nasync function findFreePort(): Promise<number> {\n for (let port = MIN_PORT; port <= MAX_PORT; port++) {\n const isAvailable = await checkPortAvailable(port);\n if (isAvailable) {\n return port;\n }\n }\n\n throw new Error(`No free ports found between ${MIN_PORT} and ${MAX_PORT}`);\n}\n\nfunction checkPortAvailable(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = http.createServer();\n\n server.once('error', () => {\n resolve(false);\n });\n\n server.once('listening', () => {\n server.close();\n resolve(true);\n });\n\n server.listen(port);\n });\n}\n\nexport async function startCallbackServer(): Promise<CallbackServerResult> {\n const port = await findFreePort();\n\n let callbackResolve: ((result: CallbackResult) => void) | null = null;\n\n const server = http.createServer((req, res) => {\n const url = new URL(req.url || '/', `http://localhost:${port}`);\n\n if (url.pathname === '/callback') {\n const token = url.searchParams.get('token');\n const userId = url.searchParams.get('userId');\n\n if (!token) {\n res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(getErrorPage('Missing token parameter'));\n return;\n }\n\n if (!userId) {\n res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(getErrorPage('Missing userId parameter'));\n return;\n }\n\n if (callbackResolve) {\n callbackResolve({ token, userId });\n }\n\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(getSuccessPage());\n } else {\n res.writeHead(404, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(getNotFoundPage());\n }\n });\n\n await new Promise<void>((resolve) => {\n server.listen(port, resolve);\n });\n\n return {\n port,\n waitForCallback: () => {\n return new Promise((resolve) => {\n callbackResolve = resolve;\n });\n },\n close: () => {\n return new Promise<void>((resolve, reject) => {\n server.close((err) => {\n if (err) {\n reject(err);\n } else {\n resolve();\n }\n });\n });\n },\n };\n}\n\nfunction getSuccessPage(): string {\n return `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>Authentication Successful</title>\n <style>\n body {\n font-family: system-ui, -apple-system, sans-serif;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n }\n .container {\n background: white;\n padding: 3rem;\n border-radius: 1rem;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n text-align: center;\n max-width: 400px;\n }\n .icon {\n font-size: 4rem;\n margin-bottom: 1rem;\n }\n h1 {\n color: #667eea;\n margin: 0 0 1rem 0;\n font-size: 1.5rem;\n }\n p {\n color: #666;\n margin: 0;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"icon\">✅</div>\n <h1>Authentication successful!</h1>\n <p>You can close this window and return to your terminal.</p>\n </div>\n</body>\n</html>\n `.trim();\n}\n\nfunction getErrorPage(message: string): string {\n return `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>Authentication Error</title>\n <style>\n body {\n font-family: system-ui, -apple-system, sans-serif;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n }\n .container {\n background: white;\n padding: 3rem;\n border-radius: 1rem;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n text-align: center;\n max-width: 400px;\n }\n .icon {\n font-size: 4rem;\n margin-bottom: 1rem;\n }\n h1 {\n color: #f5576c;\n margin: 0 0 1rem 0;\n font-size: 1.5rem;\n }\n p {\n color: #666;\n margin: 0;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"icon\">❌</div>\n <h1>Authentication error</h1>\n <p>${message}</p>\n </div>\n</body>\n</html>\n `.trim();\n}\n\nfunction getNotFoundPage(): string {\n return `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>Not Found</title>\n <style>\n body {\n font-family: system-ui, -apple-system, sans-serif;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n background: #f0f0f0;\n }\n .container {\n background: white;\n padding: 3rem;\n border-radius: 1rem;\n box-shadow: 0 4px 12px rgba(0,0,0,0.1);\n text-align: center;\n max-width: 400px;\n }\n h1 {\n color: #666;\n margin: 0;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <h1>404 Not Found</h1>\n </div>\n</body>\n</html>\n `.trim();\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport os from 'os';\nimport type { Credentials } from './types/actions.js';\n\nfunction getCredentialsDir(): string {\n return process.env.CONTEXTGRAPH_CREDENTIALS_DIR || path.join(os.homedir(), '.contextgraph');\n}\n\nfunction getCredentialsPath(): string {\n return path.join(getCredentialsDir(), 'credentials.json');\n}\n\nexport const CREDENTIALS_DIR = getCredentialsDir();\nexport const CREDENTIALS_PATH = getCredentialsPath();\n\nexport async function saveCredentials(credentials: Credentials): Promise<void> {\n const dir = getCredentialsDir();\n const filePath = getCredentialsPath();\n\n await fs.mkdir(dir, { recursive: true, mode: 0o700 });\n\n const content = JSON.stringify(credentials, null, 2);\n await fs.writeFile(filePath, content, { mode: 0o600 });\n}\n\nexport async function loadCredentials(): Promise<Credentials | null> {\n // Check for API token in environment variable first\n const apiToken = process.env.CONTEXTGRAPH_API_TOKEN;\n if (apiToken) {\n // Create credentials from API token\n // API tokens don't expire in the same way, set a far future date\n const farFuture = new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString(); // 1 year\n return {\n clerkToken: apiToken,\n userId: 'api-token-user', // Placeholder - server will resolve actual user\n expiresAt: farFuture,\n createdAt: new Date().toISOString(),\n };\n }\n\n // Fall back to file-based credentials\n const filePath = getCredentialsPath();\n\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(content) as Credentials;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n\n console.error('Error loading credentials:', error);\n return null;\n }\n}\n\nexport async function deleteCredentials(): Promise<void> {\n const filePath = getCredentialsPath();\n\n try {\n await fs.unlink(filePath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw error;\n }\n }\n}\n\nexport function isExpired(credentials: Credentials): boolean {\n return new Date(credentials.expiresAt) <= new Date();\n}\n\nexport function isTokenExpired(token: string): boolean {\n try {\n // API tokens (non-JWT format) don't expire - check with server\n // API tokens typically start with a prefix like \"cg_\" or similar\n const parts = token.split('.');\n if (parts.length !== 3) {\n // Not a JWT - assume it's an API token that doesn't expire\n return false;\n }\n\n // Decode JWT to check actual token expiration\n const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString());\n const now = Math.floor(Date.now() / 1000);\n\n // Token without exp claim is considered expired\n if (!payload.exp) {\n return true;\n }\n\n // Check if token has expired (including exactly now)\n if (payload.exp <= now) {\n return true;\n }\n\n // Check if token is not yet valid\n if (payload.nbf && payload.nbf > now) {\n return true;\n }\n\n return false;\n } catch {\n // If we can't decode it as JWT, assume it's an API token\n return false;\n }\n}\n\nexport function getTokenExpiration(token: string): Date | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) {\n return null;\n }\n\n const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString());\n if (payload.exp) {\n return new Date(payload.exp * 1000);\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get an authenticated fetch function that includes the Clerk token\n *\n * This loads the credentials from disk and returns a fetch function\n * that automatically includes the x-authorization header (workaround for Vercel stripping Authorization).\n *\n * Throws an error if credentials are not found or expired.\n */\nexport async function getAuthenticatedFetch(): Promise<typeof fetch> {\n const credentials = await loadCredentials();\n\n if (!credentials) {\n throw new Error(\n 'No credentials found. Please run authentication first.'\n );\n }\n\n if (isTokenExpired(credentials.clerkToken)) {\n throw new Error(\n 'Your credentials have expired. Please re-authenticate.'\n );\n }\n\n // Return a fetch function that includes the x-authorization header\n // Use x-authorization instead of Authorization because Vercel strips Authorization header\n return async (url: string | URL | Request, init?: RequestInit) => {\n const headers = new Headers(init?.headers);\n headers.set('x-authorization', `Bearer ${credentials.clerkToken}`);\n\n return fetch(url, {\n ...init,\n headers,\n });\n };\n}\n","import { startCallbackServer } from './callback-server.js';\nimport { saveCredentials } from './credentials.js';\n\ntype AuthenticationResult =\n | {\n success: true;\n credentials: {\n token: string;\n userId: string;\n };\n }\n | {\n success: false;\n error: string;\n };\n\ntype AuthenticationOptions = {\n baseUrl?: string;\n timeout?: number;\n openBrowser?: (url: string) => Promise<void>;\n};\n\nconst DEFAULT_TIMEOUT = 5 * 60 * 1000; // 5 minutes\nconst DEFAULT_BASE_URL = 'https://www.contextgraph.dev';\n\nasync function defaultOpenBrowser(url: string): Promise<void> {\n const open = (await import('open')).default;\n await open(url);\n}\n\nexport async function authenticateAgent(\n options: AuthenticationOptions = {}\n): Promise<AuthenticationResult> {\n const {\n baseUrl = DEFAULT_BASE_URL,\n timeout = DEFAULT_TIMEOUT,\n openBrowser = defaultOpenBrowser,\n } = options;\n\n let server;\n\n try {\n server = await startCallbackServer();\n const { port, waitForCallback, close } = server;\n\n const authUrl = `${baseUrl}/auth/cli-callback?port=${port}`;\n\n console.log(`Opening browser to: ${authUrl}`);\n await openBrowser(authUrl);\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error('Authentication timeout')), timeout);\n });\n\n const result = await Promise.race([waitForCallback(), timeoutPromise]);\n\n const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(); // 24 hours\n\n await saveCredentials({\n clerkToken: result.token,\n userId: result.userId,\n expiresAt,\n createdAt: new Date().toISOString(),\n });\n\n await close();\n\n return {\n success: true,\n credentials: {\n token: result.token,\n userId: result.userId,\n },\n };\n } catch (error) {\n if (server) {\n await server.close();\n }\n\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n}\n","import { authenticateAgent } from '../auth-flow.js';\n\nexport async function runAuth(): Promise<void> {\n console.log('Starting authentication flow...\\n');\n\n const result = await authenticateAgent();\n\n if (result.success) {\n console.log('\\n✅ Authentication successful!');\n console.log(`User ID: ${result.credentials.userId}`);\n } else {\n console.error('\\n❌ Authentication failed:', result.error);\n process.exit(1);\n }\n}\n\n","import { query, type SDKMessage, type SDKAssistantMessage, type SDKResultMessage } from '@anthropic-ai/claude-agent-sdk';\nimport type { ClaudeResult, SpawnClaudeOptions } from './types/actions.js';\nimport { ensurePlugin } from './plugin-setup.js';\nimport { transformSDKMessage } from './sdk-event-transformer.js';\nimport type { LogEvent } from './log-transport.js';\n\n// Constants for timeouts and truncation\nconst EXECUTION_TIMEOUT_MS = 20 * 60 * 1000; // 20 minutes\nconst THINKING_TRUNCATE_LENGTH = 100;\nconst COMMAND_TRUNCATE_LENGTH = 60;\n\n// Helper types for SDK message content\ntype ToolInput =\n | { file_path: string; old_string?: string; new_string?: string } // Read, Edit, Write\n | { command: string; description?: string; timeout?: number } // Bash\n | { pattern: string; glob?: string; type?: string; output_mode?: string } // Grep\n | { pattern: string; path?: string } // Glob\n | Record<string, unknown>; // Other tools\n\ntype SDKMessageContent = {\n type: string;\n text?: string;\n name?: string;\n input?: ToolInput;\n thinking?: string;\n};\n\n/**\n * Format tool use for console output\n */\nfunction formatToolUse(content: SDKMessageContent): string {\n if (content.type === 'tool_use') {\n const name = content.name || 'unknown';\n const summary = formatToolInput(name, content.input);\n return ` 🔧 ${name}${summary}`;\n }\n if (content.type === 'thinking' && content.thinking) {\n const truncated = content.thinking.length > THINKING_TRUNCATE_LENGTH\n ? content.thinking.substring(0, THINKING_TRUNCATE_LENGTH) + '...'\n : content.thinking;\n return ` 💭 ${truncated}`;\n }\n return '';\n}\n\n/**\n * Format tool input parameters for display\n */\nfunction formatToolInput(toolName: string, input: any): string {\n if (!input) return '';\n\n switch (toolName) {\n case 'Read':\n return `: ${input.file_path}`;\n case 'Edit':\n case 'Write':\n return `: ${input.file_path}`;\n case 'Bash':\n const cmd = input.command || '';\n const truncated = cmd.length > COMMAND_TRUNCATE_LENGTH\n ? cmd.substring(0, COMMAND_TRUNCATE_LENGTH) + '...'\n : cmd;\n return `: ${truncated}`;\n case 'Grep':\n return `: \"${input.pattern}\"`;\n case 'Glob':\n return `: ${input.pattern}`;\n default:\n return '';\n }\n}\n\n/**\n * Format assistant message content for display\n */\nfunction formatAssistantMessage(content: Array<SDKMessageContent>): string {\n const lines: string[] = [];\n\n for (const item of content) {\n if (item.type === 'text' && item.text) {\n lines.push(` ${item.text}`);\n } else if (item.type === 'tool_use' || item.type === 'thinking') {\n const formatted = formatToolUse(item);\n if (formatted) lines.push(formatted);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Format SDK message for console output\n */\nfunction formatMessage(message: SDKMessage): string | null {\n switch (message.type) {\n case 'system':\n if (message.subtype === 'init') {\n return '🚀 Claude session initialized';\n }\n return null;\n\n case 'assistant':\n const assistantMsg = message as SDKAssistantMessage;\n if (assistantMsg.message?.content && Array.isArray(assistantMsg.message.content)) {\n return formatAssistantMessage(assistantMsg.message.content as Array<SDKMessageContent>);\n }\n return null;\n\n case 'result':\n const resultMsg = message as SDKResultMessage;\n if (resultMsg.subtype === 'success') {\n const duration = resultMsg.duration_ms ? `${(resultMsg.duration_ms / 1000).toFixed(1)}s` : 'unknown';\n return `✅ Completed in ${duration}`;\n } else if (resultMsg.subtype.startsWith('error_')) {\n return '❌ Execution failed';\n }\n return null;\n\n default:\n return null;\n }\n}\n\n/**\n * Extended options for executeClaude with log streaming support\n */\nexport interface ExecuteClaudeOptions extends SpawnClaudeOptions {\n /** Callback for log events - called for each SDK message transformed into a LogEvent */\n onLogEvent?: (event: LogEvent) => void;\n}\n\n/**\n * Execute Claude using the Agent SDK\n *\n * This is a drop-in replacement for spawnClaude() that uses the SDK instead of spawning a CLI process.\n * It matches the same interface (SpawnClaudeOptions) and returns the same result type (ClaudeResult).\n *\n * Optionally accepts onLogEvent callback for real-time log streaming.\n */\nexport async function executeClaude(\n options: ExecuteClaudeOptions\n): Promise<ClaudeResult> {\n let sessionId: string | undefined;\n let totalCost = 0;\n let usage: any;\n\n // Create abort controller for timeout\n const abortController = new AbortController();\n const timeout = setTimeout(() => {\n abortController.abort();\n }, EXECUTION_TIMEOUT_MS);\n\n try {\n // Ensure the contextgraph plugin is available (clones from GitHub if missing)\n const pluginPath = await ensurePlugin();\n console.log('[Agent SDK] Loading plugin from:', pluginPath);\n console.log('[Agent SDK] Auth token available:', !!options.authToken);\n console.log('[Agent SDK] Anthropic API key available:', !!process.env.ANTHROPIC_API_KEY);\n console.log('[Agent SDK] Claude OAuth token available:', !!process.env.CLAUDE_CODE_OAUTH_TOKEN);\n\n // Create the query with SDK using the plugin\n const iterator = query({\n prompt: options.prompt,\n options: {\n cwd: options.cwd,\n abortController,\n permissionMode: 'bypassPermissions', // Allow MCP tools to execute automatically\n maxTurns: 100, // Reasonable limit\n env: {\n ...process.env,\n // Pass auth token through environment for MCP server\n CONTEXTGRAPH_AUTH_TOKEN: options.authToken || '',\n // Pass Anthropic API key for SDK authentication\n ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY || '',\n // Pass Claude OAuth token for SDK authentication (alternative to API key)\n CLAUDE_CODE_OAUTH_TOKEN: process.env.CLAUDE_CODE_OAUTH_TOKEN || '',\n },\n // Load the contextgraph plugin (provides MCP server URL and other config)\n plugins: [\n {\n type: 'local',\n path: pluginPath,\n }\n ]\n // Note: Auth is passed via CONTEXTGRAPH_AUTH_TOKEN environment variable above\n }\n });\n\n // Iterate through messages\n for await (const message of iterator) {\n // Capture session ID from first message\n if (!sessionId && message.session_id) {\n sessionId = message.session_id;\n }\n\n // Format and display the message (preserved console output)\n const formatted = formatMessage(message);\n if (formatted) {\n console.log(formatted);\n }\n\n // Transform and emit log event if callback is provided\n if (options.onLogEvent) {\n try {\n const logEvent = transformSDKMessage(message);\n if (logEvent) {\n options.onLogEvent(logEvent);\n }\n } catch (error) {\n // Log transformation errors but don't block execution\n console.error('[Log Transform]', error instanceof Error ? error.message : String(error));\n }\n }\n\n // Capture result metadata\n if (message.type === 'result') {\n const resultMsg = message as SDKResultMessage;\n totalCost = resultMsg.total_cost_usd || 0;\n usage = resultMsg.usage;\n\n // Check for errors\n if (resultMsg.subtype.startsWith('error_')) {\n clearTimeout(timeout);\n return {\n exitCode: 1,\n sessionId,\n usage,\n cost: totalCost,\n };\n }\n }\n }\n\n clearTimeout(timeout);\n\n // Return successful result\n return {\n exitCode: 0,\n sessionId,\n usage,\n cost: totalCost,\n };\n\n } catch (error) {\n clearTimeout(timeout);\n\n // Handle abort/timeout\n if (abortController.signal.aborted) {\n const timeoutMinutes = EXECUTION_TIMEOUT_MS / (60 * 1000);\n throw new Error(`Claude SDK execution timed out after ${timeoutMinutes} minutes`);\n }\n\n // Handle other errors\n throw new Error(`Failed to execute Claude SDK: ${(error as Error).message}`);\n }\n}\n","import { spawn } from 'child_process';\nimport { access, mkdir } from 'fs/promises';\nimport { join } from 'path';\nimport { homedir } from 'os';\n\nconst PLUGIN_REPO = 'https://github.com/contextgraph/claude-code-plugin.git';\nconst PLUGIN_DIR = join(homedir(), '.contextgraph', 'claude-code-plugin');\nconst PLUGIN_PATH = join(PLUGIN_DIR, 'plugins', 'contextgraph');\n\n/**\n * Get the path to the contextgraph plugin, cloning it if necessary\n */\nexport async function ensurePlugin(): Promise<string> {\n // Check if plugin already exists\n try {\n await access(PLUGIN_PATH);\n console.log(`📦 Using plugin: ${PLUGIN_PATH}`);\n return PLUGIN_PATH;\n } catch {\n // Plugin path doesn't exist, check if repo dir exists\n }\n\n // Check if repo directory exists but plugin path is missing (incomplete clone or wrong structure)\n let repoDirExists = false;\n try {\n await access(PLUGIN_DIR);\n repoDirExists = true;\n } catch {\n // Directory doesn't exist, will need to clone\n }\n\n if (repoDirExists) {\n // Directory exists but plugin path doesn't - try pulling latest\n console.log('📦 Plugin directory exists but incomplete, pulling latest...');\n await runCommand('git', ['pull'], PLUGIN_DIR);\n\n // Check again after pull\n try {\n await access(PLUGIN_PATH);\n console.log(`📦 Plugin ready: ${PLUGIN_PATH}`);\n return PLUGIN_PATH;\n } catch {\n throw new Error(`Plugin not found at ${PLUGIN_PATH} even after git pull. Check repository structure.`);\n }\n }\n\n console.log(`📦 Cloning plugin from ${PLUGIN_REPO}...`);\n\n // Ensure parent directory exists\n const contextgraphDir = join(homedir(), '.contextgraph');\n try {\n await mkdir(contextgraphDir, { recursive: true });\n } catch {\n // Directory might already exist\n }\n\n // Clone the repository\n await runCommand('git', ['clone', PLUGIN_REPO, PLUGIN_DIR]);\n\n // Verify plugin exists after clone\n try {\n await access(PLUGIN_PATH);\n console.log(`📦 Plugin installed: ${PLUGIN_PATH}`);\n return PLUGIN_PATH;\n } catch {\n throw new Error(`Plugin clone succeeded but plugin path not found at ${PLUGIN_PATH}`);\n }\n}\n\n/**\n * Update the plugin to latest version\n */\nexport async function updatePlugin(): Promise<void> {\n try {\n await access(PLUGIN_DIR);\n } catch {\n throw new Error('Plugin not installed. Run the agent first to auto-install.');\n }\n\n console.log('[Plugin Setup] Updating plugin...');\n await runCommand('git', ['pull'], PLUGIN_DIR);\n console.log('[Plugin Setup] Plugin updated');\n}\n\n/**\n * Get the plugin path (without ensuring it exists)\n */\nexport function getPluginPath(): string {\n return PLUGIN_PATH;\n}\n\nfunction runCommand(command: string, args: string[], cwd?: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const proc = spawn(command, args, { cwd, stdio: 'inherit' });\n\n proc.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`${command} ${args[0]} failed with exit code ${code}`));\n }\n });\n\n proc.on('error', (err) => {\n reject(new Error(`Failed to spawn ${command}: ${err.message}`));\n });\n });\n}\n","/**\n * SDK Event Transformer - Transforms Claude SDK messages into agentLog event format\n *\n * This module provides a pure transformation function that converts SDK messages\n * into LogEvent objects for the log streaming infrastructure.\n *\n * IMPORTANT: Events are emitted in the same format as the Vercel sandbox agents\n * to ensure compatibility with the AgentEventMessage component. The full SDK\n * message is preserved in the `data` field without truncation.\n */\n\nimport type { LogEvent } from './log-transport.js';\nimport type { SDKMessage, SDKAssistantMessage, SDKResultMessage } from '@anthropic-ai/claude-agent-sdk';\n\n/**\n * Transform an SDK message into a LogEvent\n *\n * The transformation preserves the full SDK message in the `data` field,\n * matching the Vercel sandbox format for UI compatibility.\n *\n * @param message - The SDK message to transform\n * @returns A LogEvent or null if the message should be skipped\n */\nexport function transformSDKMessage(message: SDKMessage): LogEvent | null {\n const timestamp = new Date().toISOString();\n\n switch (message.type) {\n case 'system':\n return transformSystemMessage(message, timestamp);\n\n case 'assistant':\n return transformAssistantMessage(message as SDKAssistantMessage, timestamp);\n\n case 'result':\n return transformResultMessage(message as SDKResultMessage, timestamp);\n\n case 'user':\n // User messages with tool results\n return transformUserMessage(message, timestamp);\n\n default:\n // Skip unknown message types\n return null;\n }\n}\n\n/**\n * Transform a system message (initialization, etc.)\n */\nfunction transformSystemMessage(\n message: SDKMessage & { subtype?: string; content?: string },\n timestamp: string\n): LogEvent {\n // Emit in the format expected by AgentEventMessage\n return {\n eventType: 'claude_message',\n content: message.content || `System: ${message.subtype || 'initialization'}`,\n data: {\n type: 'system',\n subtype: message.subtype,\n content: message.content,\n session_id: message.session_id,\n },\n timestamp,\n };\n}\n\n/**\n * Transform an assistant message (text, tool use, thinking)\n *\n * Preserves the full SDK message in the data field for UI rendering.\n * This matches the Vercel sandbox format where the entire SDK JSON\n * is stored in event.data.\n */\nfunction transformAssistantMessage(\n message: SDKAssistantMessage,\n timestamp: string\n): LogEvent | null {\n const content = message.message?.content;\n if (!content || !Array.isArray(content)) {\n return null;\n }\n\n // Generate a human-readable summary for the content field\n const contentSummary = generateContentSummary(content);\n\n // Emit the full SDK message structure in data for UI compatibility\n // This matches sandbox-execution.ts line 512-522\n return {\n eventType: 'claude_message',\n content: contentSummary,\n data: {\n type: 'assistant',\n message: message.message,\n session_id: message.session_id,\n parent_tool_use_id: message.parent_tool_use_id,\n },\n timestamp,\n };\n}\n\n/**\n * Transform a result message (completion status)\n *\n * Emits as claude_message with type='result' to match sandbox format.\n */\nfunction transformResultMessage(\n message: SDKResultMessage,\n timestamp: string\n): LogEvent {\n const isSuccess = message.subtype === 'success';\n const durationSec = message.duration_ms\n ? (message.duration_ms / 1000).toFixed(1)\n : 'unknown';\n\n return {\n eventType: 'claude_message',\n content: isSuccess\n ? `Completed successfully in ${durationSec}s`\n : `Execution ${message.subtype}: ${durationSec}s`,\n data: {\n type: 'result',\n subtype: message.subtype,\n duration_ms: message.duration_ms,\n total_cost_usd: message.total_cost_usd,\n num_turns: message.num_turns,\n usage: message.usage,\n session_id: message.session_id,\n },\n timestamp,\n };\n}\n\n/**\n * Transform a user message (typically contains tool results)\n *\n * Preserves full tool result content for UI rendering.\n */\nfunction transformUserMessage(\n message: SDKMessage & { message?: { content?: unknown } },\n timestamp: string\n): LogEvent | null {\n const content = message.message?.content;\n if (!content || !Array.isArray(content)) {\n return null;\n }\n\n // Check if this contains tool results\n const hasToolResults = content.some(\n (block: any) => block.type === 'tool_result'\n );\n\n if (!hasToolResults) {\n return null;\n }\n\n // Generate summary for content field\n const summaries = content\n .filter((block: any) => block.type === 'tool_result')\n .map((block: any) => {\n const prefix = block.is_error ? '❌' : '✓';\n const resultText = extractToolResultText(block.content);\n return `${prefix} ${resultText.substring(0, 100)}${resultText.length > 100 ? '...' : ''}`;\n });\n\n // Emit full message structure in data for UI rendering\n return {\n eventType: 'claude_message',\n content: summaries.join('\\n'),\n data: {\n type: 'user',\n message: message.message,\n session_id: message.session_id,\n },\n timestamp,\n };\n}\n\n/**\n * Generate a human-readable summary from message content blocks\n */\nfunction generateContentSummary(content: unknown[]): string {\n const parts: string[] = [];\n\n for (const block of content as any[]) {\n if (block.type === 'text' && block.text) {\n // Include first 200 chars of text in summary\n const text = block.text.length > 200\n ? block.text.substring(0, 200) + '...'\n : block.text;\n parts.push(text);\n } else if (block.type === 'tool_use') {\n parts.push(`🔧 ${block.name}`);\n } else if (block.type === 'thinking') {\n parts.push('💭 [thinking]');\n }\n }\n\n return parts.join(' | ') || '[no content]';\n}\n\n/**\n * Extract text content from a tool result for summary purposes\n */\nfunction extractToolResultText(\n content: string | Array<{ type: string; text?: string }> | undefined\n): string {\n if (!content) return '';\n\n if (typeof content === 'string') {\n return content;\n }\n\n if (Array.isArray(content)) {\n return content\n .filter(block => block.type === 'text' && block.text)\n .map(block => block.text)\n .join('\\n');\n }\n\n return '';\n}\n\n/**\n * Batch transform multiple SDK messages\n * Useful for processing message arrays from SDK iterations\n *\n * @param messages - Array of SDK messages\n * @returns Array of LogEvents (excluding nulls)\n */\nexport function transformSDKMessages(messages: SDKMessage[]): LogEvent[] {\n return messages\n .map(transformSDKMessage)\n .filter((event): event is LogEvent => event !== null);\n}\n","export interface RetryOptions {\n maxRetries?: number;\n baseDelayMs?: number;\n maxDelayMs?: number;\n /** If true, will log retry attempts */\n verbose?: boolean;\n}\n\nexport async function fetchWithRetry(\n url: string,\n options: RequestInit,\n retryOptions: RetryOptions = {}\n): Promise<Response> {\n const { maxRetries = 3, baseDelayMs = 1000, maxDelayMs = 10000 } = retryOptions;\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, options);\n // Don't retry on client errors (4xx), only on server/network errors\n if (response.ok || (response.status >= 400 && response.status < 500)) {\n return response;\n }\n // Server error (5xx) - will retry\n lastError = new Error(`HTTP ${response.status}`);\n } catch (error) {\n // Network error - will retry\n lastError = error instanceof Error ? error : new Error(String(error));\n }\n\n if (attempt < maxRetries) {\n // Exponential backoff with jitter\n const delay = Math.min(baseDelayMs * Math.pow(2, attempt), maxDelayMs);\n const jitter = delay * 0.1 * Math.random();\n await new Promise((resolve) => setTimeout(resolve, delay + jitter));\n }\n }\n\n throw lastError ?? new Error('Request failed after retries');\n}\n","/**\n * LogTransportService - Handles sending log events to the platform API\n *\n * This service manages:\n * - Creating and updating runs\n * - Sending batches of log events\n * - Retry logic with exponential backoff\n */\n\n/**\n * Log event types supported by the platform\n */\nexport type LogEventType =\n | 'stdout'\n | 'stderr'\n | 'claude_message'\n | 'tool_use'\n | 'tool_result'\n | 'system';\n\n/**\n * A log event to be sent to the platform\n */\nexport interface LogEvent {\n eventType: LogEventType;\n content: string;\n data?: Record<string, unknown>;\n timestamp: string;\n}\n\n/**\n * Response from creating a run\n */\nexport interface CreateRunResponse {\n runId: string;\n}\n\n/**\n * Response from batch send\n */\nexport interface BatchSendResponse {\n success: boolean;\n eventsReceived?: number;\n}\n\n/**\n * Configuration for retry behavior\n */\nexport interface RetryConfig {\n maxRetries: number;\n initialDelayMs: number;\n backoffFactor: number;\n}\n\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 3,\n initialDelayMs: 100,\n backoffFactor: 2,\n};\n\n/**\n * Service for sending log events to the platform API\n */\nexport class LogTransportService {\n private runId: string | null = null;\n private retryConfig: RetryConfig;\n\n constructor(\n private baseUrl: string,\n private authToken: string,\n runId?: string,\n retryConfig?: Partial<RetryConfig>\n ) {\n this.runId = runId ?? null;\n this.retryConfig = { ...DEFAULT_RETRY_CONFIG, ...retryConfig };\n }\n\n /**\n * Get the current run ID\n */\n getRunId(): string | null {\n return this.runId;\n }\n\n /**\n * Create a new run for an action\n * @param actionId - The action ID this run is executing\n * @returns The created run ID\n */\n async createRun(actionId: string): Promise<string> {\n const response = await this.makeRequest('/api/runs', {\n method: 'POST',\n body: JSON.stringify({\n actionId,\n state: 'queued',\n }),\n });\n\n const result = await response.json();\n\n if (!result.success) {\n throw new Error(result.error || 'Failed to create run');\n }\n\n this.runId = result.data.runId;\n return this.runId;\n }\n\n /**\n * Start the run (transition to running state)\n * Called when execution begins\n */\n async startRun(): Promise<void> {\n if (!this.runId) {\n throw new Error('No run ID set. Call createRun() first.');\n }\n\n const response = await this.makeRequest(`/api/runs/${this.runId}/start`, {\n method: 'POST',\n body: JSON.stringify({}),\n });\n\n const result = await response.json();\n\n if (!result.success) {\n throw new Error(result.error || 'Failed to start run');\n }\n }\n\n /**\n * Finish the run with an outcome\n * @param outcome - 'success' | 'error' | 'timeout' | 'incomplete'\n * @param metadata - Optional metadata (exitCode, errorMessage, cost, usage)\n */\n async finishRun(\n outcome: 'success' | 'error' | 'timeout' | 'incomplete',\n metadata?: {\n exitCode?: number;\n errorMessage?: string;\n cost?: number;\n usage?: Record<string, unknown>;\n }\n ): Promise<void> {\n if (!this.runId) {\n throw new Error('No run ID set. Call createRun() first.');\n }\n\n const response = await this.makeRequest(`/api/runs/${this.runId}/finish`, {\n method: 'POST',\n body: JSON.stringify({\n outcome,\n exitCode: metadata?.exitCode?.toString(),\n errorMessage: metadata?.errorMessage,\n }),\n });\n\n const result = await response.json();\n\n if (!result.success) {\n // If the run is already in a finishing state (summarizing, finished),\n // this is not an error - the server is already handling completion\n const error = result.error || 'Failed to finish run';\n if (error.includes('summarizing') || error.includes('finished')) {\n console.log('[LogTransport] Run is already being finished by server, skipping client finish');\n return;\n }\n throw new Error(error);\n }\n }\n\n /**\n * Update the state of the current run\n * @deprecated Use startRun() and finishRun() instead\n * @param state - New state for the run\n * @param metadata - Optional metadata to include with the state update\n */\n async updateRunState(\n state: string,\n metadata?: Record<string, unknown>\n ): Promise<void> {\n if (!this.runId) {\n throw new Error('No run ID set. Call createRun() first.');\n }\n\n // Map state to appropriate endpoint\n if (state === 'executing' || state === 'preparing' || state === 'running') {\n await this.startRun();\n } else if (state === 'completed' || state === 'failed') {\n const outcome = state === 'completed' ? 'success' : 'error';\n await this.finishRun(outcome, {\n exitCode: metadata?.exitCode as number | undefined,\n errorMessage: metadata?.error as string | undefined,\n cost: metadata?.cost as number | undefined,\n usage: metadata?.usage as Record<string, unknown> | undefined,\n });\n } else {\n // For unknown states, just log a warning\n console.warn(`[LogTransport] Unknown state '${state}' - no API call made`);\n }\n }\n\n /**\n * Send a batch of log events to the platform\n * @param events - Array of log events to send\n * @param workerId - Optional worker ID\n * @returns Success status and number of events received\n */\n async sendBatch(\n events: LogEvent[],\n workerId?: string\n ): Promise<BatchSendResponse> {\n if (!this.runId) {\n throw new Error('No run ID set. Call createRun() first.');\n }\n\n if (events.length === 0) {\n return { success: true, eventsReceived: 0 };\n }\n\n const response = await this.makeRequest('/api/agents/log/event', {\n method: 'POST',\n body: JSON.stringify({\n runId: this.runId,\n events,\n ...(workerId && { workerId }),\n }),\n });\n\n const result = await response.json();\n\n if (!result.success) {\n throw new Error(result.error || 'Failed to send log batch');\n }\n\n return {\n success: true,\n eventsReceived: result.data?.eventsReceived ?? events.length,\n };\n }\n\n /**\n * Make an HTTP request with retry logic\n */\n private async makeRequest(\n path: string,\n options: RequestInit\n ): Promise<Response> {\n const url = `${this.baseUrl}${path}`;\n const headers = {\n 'x-authorization': `Bearer ${this.authToken}`,\n 'Content-Type': 'application/json',\n };\n\n let lastError: Error | null = null;\n let delay = this.retryConfig.initialDelayMs;\n\n for (let attempt = 0; attempt <= this.retryConfig.maxRetries; attempt++) {\n try {\n const response = await fetch(url, {\n ...options,\n headers: {\n ...headers,\n ...(options.headers || {}),\n },\n });\n\n // Don't retry on client errors (4xx) - these won't succeed on retry\n if (response.status >= 400 && response.status < 500) {\n return response;\n }\n\n // Retry on server errors (5xx) or network issues\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n return response;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Don't wait after the last attempt\n if (attempt < this.retryConfig.maxRetries) {\n await this.sleep(delay);\n delay *= this.retryConfig.backoffFactor;\n }\n }\n }\n\n throw new Error(\n `Request failed after ${this.retryConfig.maxRetries + 1} attempts: ${lastError?.message}`\n );\n }\n\n /**\n * Sleep for a given number of milliseconds\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","/**\n * LogBuffer - Manages buffered, non-blocking log transmission\n *\n * Collects log events and flushes them periodically to avoid\n * blocking the main Claude execution flow.\n */\n\nimport { LogTransportService, type LogEvent } from './log-transport.js';\n\n// Buffer configuration for log streaming\nconst LOG_BUFFER_FLUSH_INTERVAL_MS = 500;\nconst LOG_BUFFER_MAX_SIZE = 50;\nconst LOG_BUFFER_MAX_QUEUE_SIZE = 1000;\n\nexport class LogBuffer {\n private buffer: LogEvent[] = [];\n private flushIntervalId: ReturnType<typeof setInterval> | null = null;\n private isFlushing = false;\n\n constructor(\n private transport: LogTransportService,\n private flushIntervalMs: number = LOG_BUFFER_FLUSH_INTERVAL_MS,\n private maxBufferSize: number = LOG_BUFFER_MAX_SIZE,\n private maxQueueSize: number = LOG_BUFFER_MAX_QUEUE_SIZE\n ) {}\n\n /**\n * Add an event to the buffer (fire-and-forget)\n * Handles backpressure by dropping oldest events if queue is full.\n */\n push(event: LogEvent): void {\n // Backpressure: drop oldest events if queue is too large\n if (this.buffer.length >= this.maxQueueSize) {\n this.buffer.shift();\n }\n this.buffer.push(event);\n\n // Trigger immediate flush if buffer is at max size\n if (this.buffer.length >= this.maxBufferSize) {\n this.flushAsync();\n }\n }\n\n /**\n * Start periodic flushing\n */\n start(): void {\n if (this.flushIntervalId !== null) return;\n\n this.flushIntervalId = setInterval(() => {\n this.flushAsync();\n }, this.flushIntervalMs);\n }\n\n /**\n * Stop periodic flushing and flush remaining events\n */\n async stop(): Promise<void> {\n if (this.flushIntervalId !== null) {\n clearInterval(this.flushIntervalId);\n this.flushIntervalId = null;\n }\n\n // Final flush of remaining events\n await this.flush();\n }\n\n /**\n * Async flush (fire-and-forget, non-blocking)\n */\n private flushAsync(): void {\n // Don't start a new flush if one is in progress\n if (this.isFlushing || this.buffer.length === 0) return;\n\n // Fire and forget - don't await\n this.flush().catch((error) => {\n console.error('[LogBuffer] Flush error:', error instanceof Error ? error.message : String(error));\n });\n }\n\n /**\n * Flush current buffer contents to transport\n */\n private async flush(): Promise<void> {\n if (this.isFlushing || this.buffer.length === 0) return;\n\n this.isFlushing = true;\n const eventsToSend = [...this.buffer];\n this.buffer = [];\n\n try {\n await this.transport.sendBatch(eventsToSend);\n } catch (error) {\n // Log errors but don't re-queue (to avoid infinite growth)\n console.error('[LogBuffer] Failed to send batch:', error instanceof Error ? error.message : String(error));\n } finally {\n this.isFlushing = false;\n }\n }\n}\n","/**\n * HeartbeatManager - Sends periodic liveness signals during execution\n *\n * This service manages:\n * - Periodic heartbeat signals to the platform\n * - Phase/progress updates without blocking execution\n * - Graceful error handling (log, don't throw)\n */\n\n/**\n * Execution phases for heartbeat reporting\n */\nexport type HeartbeatPhase = 'executing' | 'reading' | 'writing' | 'thinking';\n\n/**\n * Heartbeat payload sent to the platform\n */\nexport interface HeartbeatPayload {\n phase: HeartbeatPhase;\n progress?: number;\n timestamp: string;\n}\n\n/**\n * HeartbeatManager - Self-managing heartbeat service\n *\n * Sends periodic liveness signals to keep the platform informed\n * of worker status without blocking the main execution flow.\n */\nexport class HeartbeatManager {\n private intervalId: ReturnType<typeof setInterval> | null = null;\n private currentPhase: HeartbeatPhase = 'executing';\n private currentProgress: number | undefined = undefined;\n\n constructor(\n private baseUrl: string,\n private authToken: string,\n private runId: string\n ) {}\n\n /**\n * Start sending periodic heartbeats\n * @param intervalMs - Time between heartbeats in milliseconds (default: 30000)\n */\n start(intervalMs: number = 30000): void {\n // Clear any existing interval\n this.stop();\n\n // Send initial heartbeat immediately\n this.sendHeartbeat();\n\n // Set up periodic heartbeats\n this.intervalId = setInterval(() => {\n this.sendHeartbeat();\n }, intervalMs);\n }\n\n /**\n * Stop sending heartbeats\n */\n stop(): void {\n if (this.intervalId !== null) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n }\n\n /**\n * Update the current phase and optional progress\n * @param phase - Current execution phase\n * @param progress - Optional progress percentage (0-100)\n */\n updatePhase(phase: HeartbeatPhase, progress?: number): void {\n this.currentPhase = phase;\n this.currentProgress = progress;\n }\n\n /**\n * Check if heartbeat manager is currently running\n */\n isRunning(): boolean {\n return this.intervalId !== null;\n }\n\n /**\n * Send a heartbeat to the platform (internal method)\n * Errors are logged but not thrown to avoid blocking execution.\n * Includes one retry attempt for transient network failures.\n */\n private async sendHeartbeat(): Promise<void> {\n const payload: HeartbeatPayload = {\n phase: this.currentPhase,\n timestamp: new Date().toISOString(),\n };\n\n if (this.currentProgress !== undefined) {\n payload.progress = this.currentProgress;\n }\n\n const url = `${this.baseUrl}/api/runs/${this.runId}/heartbeat`;\n const requestOptions: RequestInit = {\n method: 'POST',\n headers: {\n 'x-authorization': `Bearer ${this.authToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n };\n\n // Try up to 2 times (initial + 1 retry)\n for (let attempt = 0; attempt < 2; attempt++) {\n try {\n const response = await fetch(url, requestOptions);\n\n if (response.ok) {\n return; // Success\n }\n\n // Don't retry client errors (4xx)\n if (response.status >= 400 && response.status < 500) {\n console.error(\n `Heartbeat failed: HTTP ${response.status} ${response.statusText}`\n );\n return;\n }\n\n // Server error - will retry\n if (attempt === 0) {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n } catch (error) {\n // Network error - retry once\n if (attempt === 0) {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n } else {\n // Log on final failure\n console.error(\n 'Heartbeat error:',\n error instanceof Error ? error.message : String(error)\n );\n }\n }\n }\n }\n}\n","import { loadCredentials, isExpired, isTokenExpired } from '../credentials.js';\nimport { executeClaude } from '../claude-sdk.js';\nimport { fetchWithRetry } from '../fetch-with-retry.js';\nimport { LogTransportService } from '../log-transport.js';\nimport { LogBuffer } from '../log-buffer.js';\nimport { HeartbeatManager } from '../heartbeat-manager.js';\n\nconst API_BASE_URL = 'https://www.contextgraph.dev';\n\nexport interface WorkflowOptions {\n cwd?: string;\n}\n\nexport async function runPrepare(actionId: string, options?: WorkflowOptions): Promise<void> {\n const credentials = await loadCredentials();\n\n if (!credentials) {\n console.error('❌ Not authenticated. Run authentication first.');\n process.exit(1);\n }\n\n if (isExpired(credentials) || isTokenExpired(credentials.clerkToken)) {\n console.error('❌ Token expired. Re-authenticate to continue.');\n process.exit(1);\n }\n\n console.log(`Fetching preparation instructions for action ${actionId}...\\n`);\n\n const response = await fetchWithRetry(\n `${API_BASE_URL}/api/prompts/prepare`,\n {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${credentials.clerkToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ actionId }),\n }\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Failed to fetch prepare prompt: ${response.statusText}\\n${errorText}`);\n }\n\n const { prompt } = await response.json();\n\n // Initialize log streaming infrastructure\n const logTransport = new LogTransportService(API_BASE_URL, credentials.clerkToken);\n let runId: string | undefined;\n let heartbeatManager: HeartbeatManager | undefined;\n let logBuffer: LogBuffer | undefined;\n\n try {\n // Create run for this preparation phase\n console.log('[Log Streaming] Creating run for prepare phase...');\n runId = await logTransport.createRun(actionId);\n console.log(`[Log Streaming] Run created: ${runId}`);\n\n // Update run state to preparing\n await logTransport.updateRunState('preparing');\n\n // Start heartbeat manager\n heartbeatManager = new HeartbeatManager(API_BASE_URL, credentials.clerkToken, runId);\n heartbeatManager.start();\n console.log('[Log Streaming] Heartbeat started');\n\n // Set up log buffer for non-blocking transmission\n logBuffer = new LogBuffer(logTransport);\n logBuffer.start();\n\n console.log('Spawning Claude for preparation...\\n');\n\n const claudeResult = await executeClaude({\n prompt,\n cwd: options?.cwd || process.cwd(),\n authToken: credentials.clerkToken,\n onLogEvent: (event) => {\n logBuffer!.push(event);\n },\n });\n\n // Update run state based on execution result\n if (claudeResult.exitCode === 0) {\n await logTransport.finishRun('success', {\n exitCode: claudeResult.exitCode,\n cost: claudeResult.cost,\n usage: claudeResult.usage,\n });\n console.log('\\n✅ Preparation complete');\n } else {\n await logTransport.finishRun('error', {\n exitCode: claudeResult.exitCode,\n errorMessage: `Claude preparation failed with exit code ${claudeResult.exitCode}`,\n });\n console.error(`\\n❌ Claude preparation failed with exit code ${claudeResult.exitCode}`);\n process.exit(1);\n }\n\n } catch (error) {\n // Update run state to failed if we have a run\n if (runId) {\n try {\n await logTransport.finishRun('error', {\n errorMessage: error instanceof Error ? error.message : String(error),\n });\n } catch (stateError) {\n console.error('[Log Streaming] Failed to update run state:', stateError);\n }\n }\n throw error;\n\n } finally {\n // Cleanup: stop heartbeat and flush remaining logs\n if (heartbeatManager) {\n heartbeatManager.stop();\n console.log('[Log Streaming] Heartbeat stopped');\n }\n\n if (logBuffer) {\n await logBuffer.stop();\n console.log('[Log Streaming] Logs flushed');\n }\n }\n}\n","import { loadCredentials, isExpired, isTokenExpired } from '../credentials.js';\nimport { executeClaude } from '../claude-sdk.js';\nimport { fetchWithRetry } from '../fetch-with-retry.js';\nimport { LogTransportService } from '../log-transport.js';\nimport { LogBuffer } from '../log-buffer.js';\nimport { HeartbeatManager } from '../heartbeat-manager.js';\n\nconst API_BASE_URL = 'https://www.contextgraph.dev';\n\nexport interface WorkflowOptions {\n cwd?: string;\n}\n\nexport async function runExecute(actionId: string, options?: WorkflowOptions): Promise<void> {\n const credentials = await loadCredentials();\n\n if (!credentials) {\n console.error('❌ Not authenticated. Run authentication first.');\n process.exit(1);\n }\n\n if (isExpired(credentials) || isTokenExpired(credentials.clerkToken)) {\n console.error('❌ Token expired. Re-authenticate to continue.');\n process.exit(1);\n }\n\n console.log(`Fetching execution instructions for action ${actionId}...\\n`);\n\n const response = await fetchWithRetry(\n `${API_BASE_URL}/api/prompts/execute`,\n {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${credentials.clerkToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ actionId }),\n }\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Failed to fetch execute prompt: ${response.statusText}\\n${errorText}`);\n }\n\n const { prompt } = await response.json();\n\n // Initialize log streaming infrastructure\n const logTransport = new LogTransportService(API_BASE_URL, credentials.clerkToken);\n let runId: string | undefined;\n let heartbeatManager: HeartbeatManager | undefined;\n let logBuffer: LogBuffer | undefined;\n\n try {\n // Create run for this execution\n console.log('[Log Streaming] Creating run...');\n runId = await logTransport.createRun(actionId);\n console.log(`[Log Streaming] Run created: ${runId}`);\n\n // Update run state to executing\n await logTransport.updateRunState('executing');\n\n // Start heartbeat manager\n heartbeatManager = new HeartbeatManager(API_BASE_URL, credentials.clerkToken, runId);\n heartbeatManager.start();\n console.log('[Log Streaming] Heartbeat started');\n\n // Set up log buffer for non-blocking transmission\n logBuffer = new LogBuffer(logTransport);\n logBuffer.start();\n\n console.log('Spawning Claude for execution...\\n');\n\n const claudeResult = await executeClaude({\n prompt,\n cwd: options?.cwd || process.cwd(),\n authToken: credentials.clerkToken,\n onLogEvent: (event) => {\n logBuffer!.push(event);\n },\n });\n\n // Update run state based on execution result\n if (claudeResult.exitCode === 0) {\n await logTransport.finishRun('success', {\n exitCode: claudeResult.exitCode,\n cost: claudeResult.cost,\n usage: claudeResult.usage,\n });\n console.log('\\n✅ Execution complete');\n } else {\n await logTransport.finishRun('error', {\n exitCode: claudeResult.exitCode,\n errorMessage: `Claude execution failed with exit code ${claudeResult.exitCode}`,\n });\n throw new Error(`Claude execution failed with exit code ${claudeResult.exitCode}`);\n }\n\n } catch (error) {\n // Update run state to failed if we have a run\n if (runId) {\n try {\n await logTransport.finishRun('error', {\n errorMessage: error instanceof Error ? error.message : String(error),\n });\n } catch (stateError) {\n console.error('[Log Streaming] Failed to update run state:', stateError);\n }\n }\n throw error;\n\n } finally {\n // Cleanup: stop heartbeat and flush remaining logs\n if (heartbeatManager) {\n heartbeatManager.stop();\n console.log('[Log Streaming] Heartbeat stopped');\n }\n\n if (logBuffer) {\n await logBuffer.stop();\n console.log('[Log Streaming] Logs flushed');\n }\n }\n}\n","import { randomUUID } from 'crypto';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport { ApiClient } from '../api-client.js';\nimport type { ActionNode, ActionMetadata } from '../types/actions.js';\nimport { findNextLeaf, type FindNextLeafResult } from '../next-action.js';\nimport { runPrepare } from './prepare.js';\nimport { runExecute } from './execute.js';\nimport { prepareWorkspace } from '../workspace-prep.js';\nimport { loadCredentials, isExpired, isTokenExpired } from '../credentials.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n// When built, this file is in dist/, so package.json is one level up\nconst packageJson = JSON.parse(\n readFileSync(join(__dirname, '../package.json'), 'utf-8')\n);\n\n// Polling configuration from environment variables\nconst INITIAL_POLL_INTERVAL = parseInt(process.env.WORKER_INITIAL_POLL_INTERVAL || '2000', 10); // 2 seconds default\nconst MAX_POLL_INTERVAL = parseInt(process.env.WORKER_MAX_POLL_INTERVAL || '5000', 10); // 5 seconds default\nconst BACKOFF_MULTIPLIER = 1.5;\nconst STATUS_INTERVAL_MS = 30000; // Show status every 30 seconds when idle\n\n// Retry configuration for transient API errors\n// For extended outages, we wait indefinitely with a ceiling on delay\nconst MAX_API_RETRIES = Infinity; // Never give up on transient errors\nconst INITIAL_RETRY_DELAY = 1000; // 1 second\nconst MAX_RETRY_DELAY = 60000; // 1 minute ceiling\nconst OUTAGE_WARNING_THRESHOLD = 5; // Warn user after this many retries\n\n// Module-scope state for graceful shutdown\nlet running = true;\nlet currentClaim: { actionId: string; claimId: string; workerId: string } | null = null;\nlet apiClient: ApiClient | null = null;\n\n// Stats tracking\nconst stats = {\n startTime: Date.now(),\n prepared: 0,\n executed: 0,\n errors: 0,\n};\n\nfunction formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n\n if (hours > 0) {\n return `${hours}h ${minutes % 60}m`;\n } else if (minutes > 0) {\n return `${minutes}m ${seconds % 60}s`;\n }\n return `${seconds}s`;\n}\n\nfunction printStatus(): void {\n const uptime = formatDuration(Date.now() - stats.startTime);\n const total = stats.prepared + stats.executed;\n console.log(`Status: ${total} actions (${stats.prepared} prepared, ${stats.executed} executed, ${stats.errors} errors) | Uptime: ${uptime}`);\n}\n\n/**\n * Get the next action to work on, handling tree depth truncation.\n * If the tree is truncated (children exist beyond depth limit), this function\n * will recursively re-fetch the tree starting from the truncated node.\n */\nasync function getNextAction(\n apiClient: ApiClient,\n rootId: string,\n depth: number = 0\n): Promise<ActionNode | null> {\n // Prevent infinite recursion in case of malformed data\n const maxDepth = 20;\n if (depth >= maxDepth) {\n console.error(`❌ Tree traversal exceeded maximum depth (${maxDepth}). Possible cycle or malformed data.`);\n return null;\n }\n\n const tree = await apiClient.fetchTree(rootId, false);\n\n if (tree.done) {\n if (depth === 0) {\n console.log('✅ Root action is already complete');\n }\n return null;\n }\n\n // Use local findNextLeaf to traverse tree and find next action\n const result = findNextLeaf(tree);\n\n // If we found an action, return it\n if (result.action) {\n return result.action;\n }\n\n // If tree was truncated, re-fetch starting from the truncated node\n if (result.truncatedAt) {\n console.log(`📊 Tree depth limit reached at action ${result.truncatedAt}. Fetching deeper...`);\n return getNextAction(apiClient, result.truncatedAt, depth + 1);\n }\n\n // No action found and no truncation - tree is complete or blocked\n return null;\n}\n\n/**\n * Clean up any claimed work and exit gracefully\n */\nasync function cleanupAndExit(): Promise<void> {\n if (currentClaim && apiClient) {\n try {\n console.log(`\\n🧹 Releasing claim on action ${currentClaim.actionId}...`);\n await apiClient.releaseClaim({\n action_id: currentClaim.actionId,\n worker_id: currentClaim.workerId,\n claim_id: currentClaim.claimId,\n });\n console.log('✅ Claim released successfully');\n } catch (error) {\n console.error('⚠️ Failed to release claim:', (error as Error).message);\n }\n }\n console.log('👋 Shutdown complete');\n process.exit(0);\n}\n\n/**\n * Set up signal handlers for graceful shutdown\n */\nfunction setupSignalHandlers(): void {\n process.on('SIGINT', async () => {\n console.log('\\n\\n⚠️ Received SIGINT (Ctrl+C). Shutting down gracefully...');\n running = false;\n await cleanupAndExit();\n });\n\n process.on('SIGTERM', async () => {\n console.log('\\n\\n⚠️ Received SIGTERM. Shutting down gracefully...');\n running = false;\n await cleanupAndExit();\n });\n}\n\n/**\n * Sleep for the specified number of milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Check if an error is likely transient and worth retrying\n */\nfunction isRetryableError(error: Error): boolean {\n const message = error.message.toLowerCase();\n // Retry on server errors (5xx), network errors, and timeouts\n return (\n message.includes('api error 5') ||\n message.includes('500') ||\n message.includes('502') ||\n message.includes('503') ||\n message.includes('504') ||\n message.includes('network') ||\n message.includes('timeout') ||\n message.includes('econnreset') ||\n message.includes('econnrefused') ||\n message.includes('socket hang up') ||\n message.includes('failed query') // Database query failures\n );\n}\n\nexport async function runLocalAgent(): Promise<void> {\n // Initialize module-scope apiClient for signal handlers\n apiClient = new ApiClient();\n\n // Set up graceful shutdown handlers\n setupSignalHandlers();\n\n // Load and validate credentials upfront\n const credentials = await loadCredentials();\n if (!credentials) {\n console.error('❌ Not authenticated.');\n console.error(' Set CONTEXTGRAPH_API_TOKEN environment variable or run `contextgraph-agent auth`');\n process.exit(1);\n }\n if (isExpired(credentials) || isTokenExpired(credentials.clerkToken)) {\n console.error('❌ Token expired. Run `contextgraph-agent auth` to re-authenticate.');\n process.exit(1);\n }\n\n // Show authentication method\n const usingApiToken = !!process.env.CONTEXTGRAPH_API_TOKEN;\n if (usingApiToken) {\n console.log('🔐 Authenticated via CONTEXTGRAPH_API_TOKEN');\n }\n\n // Generate unique worker ID for this session\n const workerId = randomUUID();\n\n console.log(`🤖 ContextGraph Agent v${packageJson.version}`);\n console.log(`👷 Worker ID: ${workerId}`);\n console.log(`🔄 Starting continuous worker loop...\\n`);\n console.log(`💡 Press Ctrl+C to gracefully shutdown and release any claimed work\\n`);\n\n let currentPollInterval = INITIAL_POLL_INTERVAL;\n let lastStatusTime = Date.now();\n let consecutiveApiErrors = 0;\n let apiRetryDelay = INITIAL_RETRY_DELAY;\n\n while (running) {\n\n // Claim next action from worker queue with retry logic\n let actionDetail;\n try {\n actionDetail = await apiClient.claimNextAction(workerId);\n // Reset error tracking on success\n consecutiveApiErrors = 0;\n apiRetryDelay = INITIAL_RETRY_DELAY;\n } catch (error) {\n const err = error as Error;\n\n if (isRetryableError(err)) {\n consecutiveApiErrors++;\n\n // Show extended outage warning once\n if (consecutiveApiErrors === OUTAGE_WARNING_THRESHOLD) {\n console.warn(`\\n⚠️ API appears to be experiencing an outage.`);\n console.warn(` Will continue retrying indefinitely (every ${MAX_RETRY_DELAY / 1000}s max).`);\n console.warn(` Press Ctrl+C to stop.\\n`);\n }\n\n if (consecutiveApiErrors < OUTAGE_WARNING_THRESHOLD) {\n console.warn(`⚠️ API error (attempt ${consecutiveApiErrors}): ${err.message}`);\n } else if (consecutiveApiErrors % 10 === 0) {\n // Only log every 10th retry during extended outage to reduce noise\n console.warn(`⚠️ Still retrying... (attempt ${consecutiveApiErrors}, last error: ${err.message})`);\n }\n\n const delaySeconds = Math.round(apiRetryDelay / 1000);\n if (consecutiveApiErrors < OUTAGE_WARNING_THRESHOLD) {\n console.warn(` Retrying in ${delaySeconds}s...`);\n }\n\n await sleep(apiRetryDelay);\n apiRetryDelay = Math.min(apiRetryDelay * 2, MAX_RETRY_DELAY);\n continue;\n }\n\n // Non-retryable error - re-throw\n throw err;\n }\n\n if (!actionDetail) {\n // Show periodic status while waiting\n if (Date.now() - lastStatusTime >= STATUS_INTERVAL_MS) {\n printStatus();\n lastStatusTime = Date.now();\n }\n await sleep(currentPollInterval);\n currentPollInterval = Math.min(currentPollInterval * BACKOFF_MULTIPLIER, MAX_POLL_INTERVAL);\n continue;\n }\n\n // Reset poll interval on successful claim\n currentPollInterval = INITIAL_POLL_INTERVAL;\n\n console.log(`Working: ${actionDetail.title}`);\n\n // Track current claim for graceful shutdown\n if (actionDetail.claim_id) {\n currentClaim = {\n actionId: actionDetail.id,\n claimId: actionDetail.claim_id,\n workerId,\n };\n }\n\n const isPrepared = actionDetail.prepared !== false;\n\n // Prepare workspace - repository URL is required\n const repoUrl = actionDetail.resolved_repository_url || actionDetail.repository_url;\n const branch = actionDetail.resolved_branch || actionDetail.branch;\n\n if (!repoUrl) {\n console.error(`\\n❌ Action \"${actionDetail.title}\" has no repository_url set.`);\n console.error(` Actions must have a repository_url (directly or inherited from parent).`);\n console.error(` Action ID: ${actionDetail.id}`);\n console.error(` resolved_repository_url: ${actionDetail.resolved_repository_url}`);\n console.error(` repository_url: ${actionDetail.repository_url}`);\n process.exit(1);\n }\n\n let workspacePath: string;\n let cleanup: (() => Promise<void>) | undefined;\n\n try {\n const workspace = await prepareWorkspace(repoUrl, {\n branch: branch || undefined,\n authToken: credentials.clerkToken,\n });\n workspacePath = workspace.path;\n cleanup = workspace.cleanup;\n\n if (!isPrepared) {\n await runPrepare(actionDetail.id, { cwd: workspacePath });\n stats.prepared++;\n\n // Release claim after preparation\n if (currentClaim && apiClient) {\n try {\n await apiClient.releaseClaim({\n action_id: currentClaim.actionId,\n worker_id: currentClaim.workerId,\n claim_id: currentClaim.claimId,\n });\n } catch (releaseError) {\n console.error('⚠️ Failed to release claim after preparation:', (releaseError as Error).message);\n }\n }\n currentClaim = null;\n continue;\n }\n\n try {\n await runExecute(actionDetail.id, { cwd: workspacePath });\n stats.executed++;\n console.log(`Completed: ${actionDetail.title}`);\n } catch (executeError) {\n stats.errors++;\n console.error(`Error: ${(executeError as Error).message}. Continuing...`);\n } finally {\n // Release claim after execution completes (success or failure)\n if (currentClaim && apiClient) {\n try {\n await apiClient.releaseClaim({\n action_id: currentClaim.actionId,\n worker_id: currentClaim.workerId,\n claim_id: currentClaim.claimId,\n });\n } catch (releaseError) {\n console.error('⚠️ Failed to release claim:', (releaseError as Error).message);\n }\n }\n currentClaim = null;\n }\n } catch (workspaceError) {\n // Handle workspace preparation or other errors\n stats.errors++;\n console.error(`Error preparing workspace: ${(workspaceError as Error).message}. Continuing...`);\n\n // Release claim on workspace/preparation failure\n if (currentClaim && apiClient) {\n try {\n console.log(`🧹 Releasing claim due to workspace error...`);\n await apiClient.releaseClaim({\n action_id: currentClaim.actionId,\n worker_id: currentClaim.workerId,\n claim_id: currentClaim.claimId,\n });\n console.log('✅ Claim released');\n } catch (releaseError) {\n console.error('⚠️ Failed to release claim:', (releaseError as Error).message);\n }\n }\n currentClaim = null;\n } finally {\n if (cleanup) {\n await cleanup();\n }\n }\n }\n\n}\n\n","import { loadCredentials, isExpired, isTokenExpired } from './credentials.js';\nimport { fetchWithRetry } from './fetch-with-retry.js';\nimport type { ActionDetailResource, ActionNode } from './types/actions.js';\n\nexport class ApiClient {\n constructor(\n private baseUrl: string = 'https://www.contextgraph.dev'\n ) {}\n\n private async getAuthToken(): Promise<string> {\n const credentials = await loadCredentials();\n\n if (!credentials) {\n throw new Error('Not authenticated. Run authentication first.');\n }\n\n // Check both the stored metadata and the actual JWT expiration\n if (isExpired(credentials) || isTokenExpired(credentials.clerkToken)) {\n throw new Error('Token expired. Re-authenticate to continue.');\n }\n\n return credentials.clerkToken;\n }\n\n async getActionDetail(actionId: string): Promise<ActionDetailResource> {\n const token = await this.getAuthToken();\n\n // Use both x-authorization header and query param for Vercel compatibility\n const response = await fetchWithRetry(\n `${this.baseUrl}/api/actions/${actionId}?token=${encodeURIComponent(token)}`,\n {\n headers: {\n 'x-authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n }\n );\n\n if (!response.ok) {\n throw new Error(`API error: ${response.status}`);\n }\n\n const result = await response.json();\n\n if (!result.success) {\n throw new Error(result.error);\n }\n\n return result.data;\n }\n\n async fetchTree(rootActionId: string, includeCompleted: boolean = false): Promise<ActionNode> {\n const token = await this.getAuthToken();\n\n // Use both x-authorization header and query param for Vercel compatibility\n const response = await fetchWithRetry(\n `${this.baseUrl}/api/tree/${rootActionId}?includeCompleted=${includeCompleted}&token=${encodeURIComponent(token)}`,\n {\n headers: {\n 'x-authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n }\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Failed to fetch tree: ${response.status} ${errorText}`);\n }\n\n const result = await response.json();\n if (!result.success) {\n throw new Error('Failed to fetch tree: API returned unsuccessful response');\n }\n\n // If no root actions, the tree is complete (all actions done)\n if (!result.data.rootActions?.[0]) {\n return { id: rootActionId, title: '', done: true, dependencies: [], children: [] };\n }\n\n return result.data.rootActions[0];\n }\n\n async claimNextAction(workerId: string): Promise<ActionDetailResource | null> {\n const token = await this.getAuthToken();\n\n const response = await fetchWithRetry(\n `${this.baseUrl}/api/worker/next?token=${encodeURIComponent(token)}`,\n {\n method: 'POST',\n headers: {\n 'x-authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ worker_id: workerId }),\n }\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`API error ${response.status}: ${errorText}`);\n }\n\n const result = await response.json();\n\n if (!result.success) {\n throw new Error(result.error || 'API returned unsuccessful response');\n }\n\n // API returns null when no work is available\n return result.data;\n }\n\n async releaseClaim(params: { action_id: string; worker_id: string; claim_id: string }): Promise<void> {\n const token = await this.getAuthToken();\n\n const response = await fetchWithRetry(\n `${this.baseUrl}/api/worker/release?token=${encodeURIComponent(token)}`,\n {\n method: 'POST',\n headers: {\n 'x-authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(params),\n }\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`API error ${response.status}: ${errorText}`);\n }\n\n const result = await response.json();\n\n if (!result.success) {\n throw new Error(result.error || 'API returned unsuccessful response');\n }\n }\n}\n","import { spawn } from 'child_process';\nimport { mkdtemp, rm } from 'fs/promises';\nimport { tmpdir } from 'os';\nimport { join } from 'path';\nimport { fetchWithRetry } from './fetch-with-retry.js';\nimport type { GitHubCredentials } from './types/actions.js';\n\nconst API_BASE_URL = 'https://www.contextgraph.dev';\n\nexport interface WorkspaceResult {\n path: string;\n cleanup: () => Promise<void>;\n}\n\nexport interface PrepareWorkspaceOptions {\n branch?: string;\n authToken: string;\n}\n\nasync function fetchGitHubCredentials(authToken: string): Promise<GitHubCredentials> {\n const response = await fetchWithRetry(`${API_BASE_URL}/api/cli/credentials`, {\n headers: {\n 'x-authorization': `Bearer ${authToken}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (response.status === 401) {\n throw new Error('Authentication failed. Please re-authenticate.');\n }\n\n if (response.status === 404) {\n throw new Error(\n 'GitHub not connected. Please connect your GitHub account at https://contextgraph.dev/settings.'\n );\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Failed to fetch GitHub credentials: ${response.statusText}\\n${errorText}`);\n }\n\n return response.json() as Promise<GitHubCredentials>;\n}\n\nfunction runGitCommand(args: string[], cwd?: string): Promise<{ stdout: string; stderr: string }> {\n return new Promise((resolve, reject) => {\n const proc = spawn('git', args, { cwd });\n let stdout = '';\n let stderr = '';\n\n proc.stdout.on('data', (data) => {\n stdout += data.toString();\n });\n\n proc.stderr.on('data', (data) => {\n stderr += data.toString();\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n resolve({ stdout, stderr });\n } else {\n reject(new Error(`git ${args[0]} failed (exit ${code}): ${stderr || stdout}`));\n }\n });\n\n proc.on('error', (err) => {\n reject(new Error(`Failed to spawn git: ${err.message}`));\n });\n });\n}\n\nfunction buildAuthenticatedUrl(repoUrl: string, token: string): string {\n // Handle https://github.com/... URLs\n if (repoUrl.startsWith('https://github.com/')) {\n return repoUrl.replace('https://github.com/', `https://${token}@github.com/`);\n }\n\n // Handle https://github.com URLs without trailing slash\n if (repoUrl.startsWith('https://github.com')) {\n return repoUrl.replace('https://github.com', `https://${token}@github.com`);\n }\n\n // For other URLs, return as-is (might be SSH or other provider)\n return repoUrl;\n}\n\nexport async function prepareWorkspace(\n repoUrl: string,\n options: PrepareWorkspaceOptions\n): Promise<WorkspaceResult> {\n const { branch, authToken } = options;\n\n // Fetch GitHub credentials\n const credentials = await fetchGitHubCredentials(authToken);\n\n // Create temp directory\n const workspacePath = await mkdtemp(join(tmpdir(), 'cg-workspace-'));\n\n const cleanup = async () => {\n try {\n await rm(workspacePath, { recursive: true, force: true });\n } catch (error) {\n console.error(`Warning: Failed to cleanup workspace at ${workspacePath}:`, error);\n }\n };\n\n try {\n // Build authenticated clone URL\n const cloneUrl = buildAuthenticatedUrl(repoUrl, credentials.githubToken);\n\n // Clone the repository\n console.log(`📂 Cloning ${repoUrl}`);\n console.log(` → ${workspacePath}`);\n await runGitCommand(['clone', cloneUrl, workspacePath]);\n console.log(`✅ Repository cloned`);\n\n // Configure git identity if we have the info\n if (credentials.githubUsername) {\n await runGitCommand(['config', 'user.name', credentials.githubUsername], workspacePath);\n }\n if (credentials.githubEmail) {\n await runGitCommand(['config', 'user.email', credentials.githubEmail], workspacePath);\n }\n\n // Handle branch checkout if specified\n if (branch) {\n // Check if branch exists remotely\n const { stdout } = await runGitCommand(\n ['ls-remote', '--heads', 'origin', branch],\n workspacePath\n );\n\n const branchExists = stdout.trim().length > 0;\n\n if (branchExists) {\n // Checkout existing branch\n console.log(`🌿 Checking out branch: ${branch}`);\n await runGitCommand(['checkout', branch], workspacePath);\n } else {\n // Create new branch\n console.log(`🌱 Creating new branch: ${branch}`);\n await runGitCommand(['checkout', '-b', branch], workspacePath);\n }\n }\n\n return { path: workspacePath, cleanup };\n } catch (error) {\n // Cleanup on failure\n await cleanup();\n throw error;\n }\n}\n"],"mappings":"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","names":["readFileSync","fileURLToPath","dirname","join","path","API_BASE_URL","join","spawn","join","API_BASE_URL","spawn","join","__filename","__dirname","join","__filename","fileURLToPath","__dirname","dirname","packageJson","readFileSync","join"]}
1
+ {"version":3,"sources":["../src/cli/index.ts","../src/callback-server.ts","../src/credentials.ts","../src/auth-flow.ts","../src/workflows/auth.ts","../src/claude-sdk.ts","../src/plugin-setup.ts","../src/sdk-event-transformer.ts","../src/fetch-with-retry.ts","../src/log-transport.ts","../src/log-buffer.ts","../src/heartbeat-manager.ts","../src/workflows/prepare.ts","../src/workflows/execute.ts","../src/workflows/agent.ts","../src/api-client.ts","../src/workspace-prep.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport { runAuth } from '../workflows/auth.js';\nimport { runPrepare } from '../workflows/prepare.js';\nimport { runExecute } from '../workflows/execute.js';\nimport { runLocalAgent } from '../workflows/agent.js';\nimport { loadCredentials, isExpired, isTokenExpired } from '../credentials.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageJson = JSON.parse(\n readFileSync(join(__dirname, '../package.json'), 'utf-8')\n);\n\nconst program = new Command();\n\nprogram\n .name('contextgraph-agent')\n .description('Autonomous agent for contextgraph action execution')\n .version(packageJson.version);\n\nprogram\n .command('run')\n .description('Run continuous worker loop (claims and executes actions until Ctrl+C)')\n .action(async () => {\n try {\n await runLocalAgent();\n } catch (error) {\n if (error instanceof Error) {\n console.error('Error running agent:', error.message || '(no message)');\n if (error.stack) {\n console.error('\\nStack trace:');\n console.error(error.stack);\n }\n } else {\n console.error('Error running agent:', error);\n }\n process.exit(1);\n }\n });\n\nprogram\n .command('auth')\n .description('Authenticate with contextgraph.dev')\n .action(async () => {\n try {\n await runAuth();\n } catch (error) {\n console.error('Error during authentication:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n });\n\nprogram\n .command('prepare')\n .argument('<action-id>', 'Action ID to prepare')\n .description('Prepare a single action')\n .action(async (actionId: string) => {\n try {\n await runPrepare(actionId);\n } catch (error) {\n console.error('Error preparing action:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n });\n\nprogram\n .command('execute')\n .argument('<action-id>', 'Action ID to execute')\n .description('Execute a single action')\n .action(async (actionId: string) => {\n try {\n await runExecute(actionId);\n } catch (error) {\n console.error('Error executing action:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n });\n\nprogram\n .command('whoami')\n .description('Show current authentication status')\n .action(async () => {\n try {\n const credentials = await loadCredentials();\n\n if (!credentials) {\n console.log('Not authenticated. Run `contextgraph-agent auth` to authenticate.');\n process.exit(1);\n }\n\n if (isExpired(credentials) || isTokenExpired(credentials.clerkToken)) {\n console.log('⚠️ Token expired. Run `contextgraph-agent auth` to re-authenticate.');\n console.log(`User ID: ${credentials.userId}`);\n console.log(`Expired at: ${credentials.expiresAt}`);\n process.exit(1);\n }\n\n console.log('✅ Authenticated');\n console.log(`User ID: ${credentials.userId}`);\n console.log(`Expires at: ${credentials.expiresAt}`);\n } catch (error) {\n console.error('Error checking authentication:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n });\n\nprogram.parse();\n","import http from 'http';\nimport { URL } from 'url';\nimport type { CallbackResult } from './types/actions.js';\n\nexport type CallbackServerResult = {\n port: number;\n waitForCallback: () => Promise<CallbackResult>;\n close: () => Promise<void>;\n};\n\nconst MIN_PORT = 3000;\nconst MAX_PORT = 3100;\n\nasync function findFreePort(): Promise<number> {\n for (let port = MIN_PORT; port <= MAX_PORT; port++) {\n const isAvailable = await checkPortAvailable(port);\n if (isAvailable) {\n return port;\n }\n }\n\n throw new Error(`No free ports found between ${MIN_PORT} and ${MAX_PORT}`);\n}\n\nfunction checkPortAvailable(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = http.createServer();\n\n server.once('error', () => {\n resolve(false);\n });\n\n server.once('listening', () => {\n server.close();\n resolve(true);\n });\n\n server.listen(port);\n });\n}\n\nexport async function startCallbackServer(): Promise<CallbackServerResult> {\n const port = await findFreePort();\n\n let callbackResolve: ((result: CallbackResult) => void) | null = null;\n\n const server = http.createServer((req, res) => {\n const url = new URL(req.url || '/', `http://localhost:${port}`);\n\n if (url.pathname === '/callback') {\n const token = url.searchParams.get('token');\n const userId = url.searchParams.get('userId');\n\n if (!token) {\n res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(getErrorPage('Missing token parameter'));\n return;\n }\n\n if (!userId) {\n res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(getErrorPage('Missing userId parameter'));\n return;\n }\n\n if (callbackResolve) {\n callbackResolve({ token, userId });\n }\n\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(getSuccessPage());\n } else {\n res.writeHead(404, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(getNotFoundPage());\n }\n });\n\n await new Promise<void>((resolve) => {\n server.listen(port, resolve);\n });\n\n return {\n port,\n waitForCallback: () => {\n return new Promise((resolve) => {\n callbackResolve = resolve;\n });\n },\n close: () => {\n return new Promise<void>((resolve, reject) => {\n server.close((err) => {\n if (err) {\n reject(err);\n } else {\n resolve();\n }\n });\n });\n },\n };\n}\n\nfunction getSuccessPage(): string {\n return `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>Authentication Successful</title>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n <link href=\"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap\" rel=\"stylesheet\">\n <style>\n :root {\n --bg: hsl(0 0% 8%);\n --tile-bg: hsl(0 0% 12%);\n --cream: hsl(45 30% 85%);\n --orange: hsl(30 95% 55%);\n --subtitle: hsl(0 0% 55%);\n --border: hsl(0 0% 20%);\n }\n\n * {\n box-sizing: border-box;\n }\n\n body {\n font-family: 'JetBrains Mono', 'SF Mono', 'Monaco', 'Inconsolata', monospace;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n background: var(--bg);\n padding: 1rem;\n }\n\n .container {\n background: var(--tile-bg);\n padding: 3rem;\n border-radius: 0.75rem;\n border: 1px solid var(--border);\n text-align: center;\n max-width: 400px;\n width: 100%;\n }\n\n .icon-container {\n width: 80px;\n height: 80px;\n margin: 0 auto 1.5rem;\n background: hsl(145 50% 12%);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 2px solid hsl(145 50% 25%);\n }\n\n .icon {\n width: 40px;\n height: 40px;\n stroke: hsl(145 70% 55%);\n stroke-width: 3;\n fill: none;\n }\n\n h1 {\n color: var(--cream);\n margin: 0 0 0.75rem 0;\n font-size: 1.25rem;\n font-weight: 500;\n letter-spacing: -0.02em;\n }\n\n p {\n color: var(--subtitle);\n margin: 0;\n font-size: 0.875rem;\n line-height: 1.6;\n }\n\n .brand {\n margin-top: 2rem;\n padding-top: 1.5rem;\n border-top: 1px solid var(--border);\n }\n\n .brand-text {\n color: var(--orange);\n font-size: 0.75rem;\n font-weight: 500;\n letter-spacing: 0.05em;\n }\n\n @keyframes check-draw {\n 0% {\n stroke-dashoffset: 24;\n }\n 100% {\n stroke-dashoffset: 0;\n }\n }\n\n .icon polyline {\n stroke-dasharray: 24;\n stroke-dashoffset: 24;\n animation: check-draw 0.4s ease-out 0.2s forwards;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"icon-container\">\n <svg class=\"icon\" viewBox=\"0 0 24 24\">\n <polyline points=\"4 12 10 18 20 6\"></polyline>\n </svg>\n </div>\n <h1>Authentication successful</h1>\n <p>You can close this window and return to your terminal.</p>\n <div class=\"brand\">\n <span class=\"brand-text\">CONTEXTGRAPH</span>\n </div>\n </div>\n</body>\n</html>\n `.trim();\n}\n\nfunction getErrorPage(message: string): string {\n return `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>Authentication Error</title>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n <link href=\"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap\" rel=\"stylesheet\">\n <style>\n :root {\n --bg: hsl(0 0% 8%);\n --tile-bg: hsl(0 0% 12%);\n --red: hsl(0 80% 60%);\n --red-dim: hsl(0 50% 12%);\n --red-border: hsl(0 50% 25%);\n --cream: hsl(45 30% 85%);\n --orange: hsl(30 95% 55%);\n --subtitle: hsl(0 0% 55%);\n --border: hsl(0 0% 20%);\n }\n\n * {\n box-sizing: border-box;\n }\n\n body {\n font-family: 'JetBrains Mono', 'SF Mono', 'Monaco', 'Inconsolata', monospace;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n background: var(--bg);\n padding: 1rem;\n }\n\n .container {\n background: var(--tile-bg);\n padding: 3rem;\n border-radius: 0.75rem;\n border: 1px solid var(--border);\n text-align: center;\n max-width: 400px;\n width: 100%;\n }\n\n .icon-container {\n width: 80px;\n height: 80px;\n margin: 0 auto 1.5rem;\n background: var(--red-dim);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 2px solid var(--red-border);\n }\n\n .icon {\n width: 40px;\n height: 40px;\n stroke: var(--red);\n stroke-width: 3;\n fill: none;\n }\n\n h1 {\n color: var(--red);\n margin: 0 0 0.75rem 0;\n font-size: 1.25rem;\n font-weight: 500;\n letter-spacing: -0.02em;\n }\n\n p {\n color: var(--subtitle);\n margin: 0;\n font-size: 0.875rem;\n line-height: 1.6;\n }\n\n .brand {\n margin-top: 2rem;\n padding-top: 1.5rem;\n border-top: 1px solid var(--border);\n }\n\n .brand-text {\n color: var(--orange);\n font-size: 0.75rem;\n font-weight: 500;\n letter-spacing: 0.05em;\n }\n\n @keyframes x-draw {\n 0% {\n stroke-dashoffset: 34;\n }\n 100% {\n stroke-dashoffset: 0;\n }\n }\n\n .icon line {\n stroke-dasharray: 17;\n stroke-dashoffset: 17;\n }\n\n .icon line:first-child {\n animation: x-draw 0.3s ease-out 0.2s forwards;\n }\n\n .icon line:last-child {\n animation: x-draw 0.3s ease-out 0.35s forwards;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"icon-container\">\n <svg class=\"icon\" viewBox=\"0 0 24 24\">\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n </svg>\n </div>\n <h1>Authentication error</h1>\n <p>${message}</p>\n <div class=\"brand\">\n <span class=\"brand-text\">CONTEXTGRAPH</span>\n </div>\n </div>\n</body>\n</html>\n `.trim();\n}\n\nfunction getNotFoundPage(): string {\n return `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>Not Found</title>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n <link href=\"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap\" rel=\"stylesheet\">\n <style>\n :root {\n --bg: hsl(0 0% 8%);\n --tile-bg: hsl(0 0% 12%);\n --cream: hsl(45 30% 85%);\n --orange: hsl(30 95% 55%);\n --subtitle: hsl(0 0% 55%);\n --border: hsl(0 0% 20%);\n }\n\n * {\n box-sizing: border-box;\n }\n\n body {\n font-family: 'JetBrains Mono', 'SF Mono', 'Monaco', 'Inconsolata', monospace;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n background: var(--bg);\n padding: 1rem;\n }\n\n .container {\n background: var(--tile-bg);\n padding: 3rem;\n border-radius: 0.75rem;\n border: 1px solid var(--border);\n text-align: center;\n max-width: 400px;\n width: 100%;\n }\n\n .code {\n color: var(--orange);\n font-size: 3rem;\n font-weight: 700;\n margin: 0 0 0.5rem 0;\n letter-spacing: -0.02em;\n }\n\n h1 {\n color: var(--cream);\n margin: 0;\n font-size: 1rem;\n font-weight: 400;\n }\n\n .brand {\n margin-top: 2rem;\n padding-top: 1.5rem;\n border-top: 1px solid var(--border);\n }\n\n .brand-text {\n color: var(--orange);\n font-size: 0.75rem;\n font-weight: 500;\n letter-spacing: 0.05em;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"code\">404</div>\n <h1>Not Found</h1>\n <div class=\"brand\">\n <span class=\"brand-text\">CONTEXTGRAPH</span>\n </div>\n </div>\n</body>\n</html>\n `.trim();\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport os from 'os';\nimport type { Credentials } from './types/actions.js';\n\nfunction getCredentialsDir(): string {\n return process.env.CONTEXTGRAPH_CREDENTIALS_DIR || path.join(os.homedir(), '.contextgraph');\n}\n\nfunction getCredentialsPath(): string {\n return path.join(getCredentialsDir(), 'credentials.json');\n}\n\nexport const CREDENTIALS_DIR = getCredentialsDir();\nexport const CREDENTIALS_PATH = getCredentialsPath();\n\nexport async function saveCredentials(credentials: Credentials): Promise<void> {\n const dir = getCredentialsDir();\n const filePath = getCredentialsPath();\n\n await fs.mkdir(dir, { recursive: true, mode: 0o700 });\n\n const content = JSON.stringify(credentials, null, 2);\n await fs.writeFile(filePath, content, { mode: 0o600 });\n}\n\nexport async function loadCredentials(): Promise<Credentials | null> {\n // Check for API token in environment variable first\n const apiToken = process.env.CONTEXTGRAPH_API_TOKEN;\n if (apiToken) {\n // Create credentials from API token\n // API tokens don't expire in the same way, set a far future date\n const farFuture = new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString(); // 1 year\n return {\n clerkToken: apiToken,\n userId: 'api-token-user', // Placeholder - server will resolve actual user\n expiresAt: farFuture,\n createdAt: new Date().toISOString(),\n };\n }\n\n // Fall back to file-based credentials\n const filePath = getCredentialsPath();\n\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(content) as Credentials;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n\n console.error('Error loading credentials:', error);\n return null;\n }\n}\n\nexport async function deleteCredentials(): Promise<void> {\n const filePath = getCredentialsPath();\n\n try {\n await fs.unlink(filePath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw error;\n }\n }\n}\n\nexport function isExpired(credentials: Credentials): boolean {\n return new Date(credentials.expiresAt) <= new Date();\n}\n\nexport function isTokenExpired(token: string): boolean {\n try {\n // API tokens (non-JWT format) don't expire - check with server\n // API tokens typically start with a prefix like \"cg_\" or similar\n const parts = token.split('.');\n if (parts.length !== 3) {\n // Not a JWT - assume it's an API token that doesn't expire\n return false;\n }\n\n // Decode JWT to check actual token expiration\n const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString());\n const now = Math.floor(Date.now() / 1000);\n\n // Token without exp claim is considered expired\n if (!payload.exp) {\n return true;\n }\n\n // Check if token has expired (including exactly now)\n if (payload.exp <= now) {\n return true;\n }\n\n // Check if token is not yet valid\n if (payload.nbf && payload.nbf > now) {\n return true;\n }\n\n return false;\n } catch {\n // If we can't decode it as JWT, assume it's an API token\n return false;\n }\n}\n\nexport function getTokenExpiration(token: string): Date | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) {\n return null;\n }\n\n const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString());\n if (payload.exp) {\n return new Date(payload.exp * 1000);\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get an authenticated fetch function that includes the Clerk token\n *\n * This loads the credentials from disk and returns a fetch function\n * that automatically includes the x-authorization header (workaround for Vercel stripping Authorization).\n *\n * Throws an error if credentials are not found or expired.\n */\nexport async function getAuthenticatedFetch(): Promise<typeof fetch> {\n const credentials = await loadCredentials();\n\n if (!credentials) {\n throw new Error(\n 'No credentials found. Please run authentication first.'\n );\n }\n\n if (isTokenExpired(credentials.clerkToken)) {\n throw new Error(\n 'Your credentials have expired. Please re-authenticate.'\n );\n }\n\n // Return a fetch function that includes the x-authorization header\n // Use x-authorization instead of Authorization because Vercel strips Authorization header\n return async (url: string | URL | Request, init?: RequestInit) => {\n const headers = new Headers(init?.headers);\n headers.set('x-authorization', `Bearer ${credentials.clerkToken}`);\n\n return fetch(url, {\n ...init,\n headers,\n });\n };\n}\n","import { startCallbackServer } from './callback-server.js';\nimport { saveCredentials } from './credentials.js';\n\ntype AuthenticationResult =\n | {\n success: true;\n credentials: {\n token: string;\n userId: string;\n };\n }\n | {\n success: false;\n error: string;\n };\n\ntype AuthenticationOptions = {\n baseUrl?: string;\n timeout?: number;\n openBrowser?: (url: string) => Promise<void>;\n};\n\nconst DEFAULT_TIMEOUT = 5 * 60 * 1000; // 5 minutes\nconst DEFAULT_BASE_URL = 'https://www.contextgraph.dev';\n\nasync function defaultOpenBrowser(url: string): Promise<void> {\n const open = (await import('open')).default;\n await open(url);\n}\n\nexport async function authenticateAgent(\n options: AuthenticationOptions = {}\n): Promise<AuthenticationResult> {\n const {\n baseUrl = DEFAULT_BASE_URL,\n timeout = DEFAULT_TIMEOUT,\n openBrowser = defaultOpenBrowser,\n } = options;\n\n let server;\n\n try {\n server = await startCallbackServer();\n const { port, waitForCallback, close } = server;\n\n const authUrl = `${baseUrl}/auth/cli-callback?port=${port}`;\n\n console.log(`Opening browser to: ${authUrl}`);\n await openBrowser(authUrl);\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error('Authentication timeout')), timeout);\n });\n\n const result = await Promise.race([waitForCallback(), timeoutPromise]);\n\n const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(); // 24 hours\n\n await saveCredentials({\n clerkToken: result.token,\n userId: result.userId,\n expiresAt,\n createdAt: new Date().toISOString(),\n });\n\n await close();\n\n return {\n success: true,\n credentials: {\n token: result.token,\n userId: result.userId,\n },\n };\n } catch (error) {\n if (server) {\n await server.close();\n }\n\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n}\n","import { authenticateAgent } from '../auth-flow.js';\n\nexport async function runAuth(): Promise<void> {\n console.log('Starting authentication flow...\\n');\n\n const result = await authenticateAgent();\n\n if (result.success) {\n console.log('\\n✅ Authentication successful!');\n console.log(`User ID: ${result.credentials.userId}`);\n } else {\n console.error('\\n❌ Authentication failed:', result.error);\n process.exit(1);\n }\n}\n\n","import { query, type SDKMessage, type SDKAssistantMessage, type SDKResultMessage } from '@anthropic-ai/claude-agent-sdk';\nimport type { ClaudeResult, SpawnClaudeOptions } from './types/actions.js';\nimport { ensurePlugin } from './plugin-setup.js';\nimport { transformSDKMessage } from './sdk-event-transformer.js';\nimport type { LogEvent } from './log-transport.js';\n\n// Constants for timeouts and truncation\nconst EXECUTION_TIMEOUT_MS = 20 * 60 * 1000; // 20 minutes\nconst THINKING_TRUNCATE_LENGTH = 100;\nconst COMMAND_TRUNCATE_LENGTH = 60;\n\n// Helper types for SDK message content\ntype ToolInput =\n | { file_path: string; old_string?: string; new_string?: string } // Read, Edit, Write\n | { command: string; description?: string; timeout?: number } // Bash\n | { pattern: string; glob?: string; type?: string; output_mode?: string } // Grep\n | { pattern: string; path?: string } // Glob\n | Record<string, unknown>; // Other tools\n\ntype SDKMessageContent = {\n type: string;\n text?: string;\n name?: string;\n input?: ToolInput;\n thinking?: string;\n};\n\n/**\n * Format tool use for console output\n */\nfunction formatToolUse(content: SDKMessageContent): string {\n if (content.type === 'tool_use') {\n const name = content.name || 'unknown';\n const summary = formatToolInput(name, content.input);\n return ` 🔧 ${name}${summary}`;\n }\n if (content.type === 'thinking' && content.thinking) {\n const truncated = content.thinking.length > THINKING_TRUNCATE_LENGTH\n ? content.thinking.substring(0, THINKING_TRUNCATE_LENGTH) + '...'\n : content.thinking;\n return ` 💭 ${truncated}`;\n }\n return '';\n}\n\n/**\n * Format tool input parameters for display\n */\nfunction formatToolInput(toolName: string, input: any): string {\n if (!input) return '';\n\n switch (toolName) {\n case 'Read':\n return `: ${input.file_path}`;\n case 'Edit':\n case 'Write':\n return `: ${input.file_path}`;\n case 'Bash':\n const cmd = input.command || '';\n const truncated = cmd.length > COMMAND_TRUNCATE_LENGTH\n ? cmd.substring(0, COMMAND_TRUNCATE_LENGTH) + '...'\n : cmd;\n return `: ${truncated}`;\n case 'Grep':\n return `: \"${input.pattern}\"`;\n case 'Glob':\n return `: ${input.pattern}`;\n default:\n return '';\n }\n}\n\n/**\n * Format assistant message content for display\n */\nfunction formatAssistantMessage(content: Array<SDKMessageContent>): string {\n const lines: string[] = [];\n\n for (const item of content) {\n if (item.type === 'text' && item.text) {\n lines.push(` ${item.text}`);\n } else if (item.type === 'tool_use' || item.type === 'thinking') {\n const formatted = formatToolUse(item);\n if (formatted) lines.push(formatted);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Format SDK message for console output\n */\nfunction formatMessage(message: SDKMessage): string | null {\n switch (message.type) {\n case 'system':\n if (message.subtype === 'init') {\n return '🚀 Claude session initialized';\n }\n return null;\n\n case 'assistant':\n const assistantMsg = message as SDKAssistantMessage;\n if (assistantMsg.message?.content && Array.isArray(assistantMsg.message.content)) {\n return formatAssistantMessage(assistantMsg.message.content as Array<SDKMessageContent>);\n }\n return null;\n\n case 'result':\n const resultMsg = message as SDKResultMessage;\n if (resultMsg.subtype === 'success') {\n const duration = resultMsg.duration_ms ? `${(resultMsg.duration_ms / 1000).toFixed(1)}s` : 'unknown';\n return `✅ Completed in ${duration}`;\n } else if (resultMsg.subtype.startsWith('error_')) {\n return '❌ Execution failed';\n }\n return null;\n\n default:\n return null;\n }\n}\n\n/**\n * Extended options for executeClaude with log streaming support\n */\nexport interface ExecuteClaudeOptions extends SpawnClaudeOptions {\n /** Callback for log events - called for each SDK message transformed into a LogEvent */\n onLogEvent?: (event: LogEvent) => void;\n}\n\n/**\n * Execute Claude using the Agent SDK\n *\n * This is a drop-in replacement for spawnClaude() that uses the SDK instead of spawning a CLI process.\n * It matches the same interface (SpawnClaudeOptions) and returns the same result type (ClaudeResult).\n *\n * Optionally accepts onLogEvent callback for real-time log streaming.\n */\nexport async function executeClaude(\n options: ExecuteClaudeOptions\n): Promise<ClaudeResult> {\n let sessionId: string | undefined;\n let totalCost = 0;\n let usage: any;\n\n // Create abort controller for timeout\n const abortController = new AbortController();\n const timeout = setTimeout(() => {\n abortController.abort();\n }, EXECUTION_TIMEOUT_MS);\n\n try {\n // Ensure the contextgraph plugin is available (clones from GitHub if missing)\n const pluginPath = await ensurePlugin();\n console.log('[Agent SDK] Loading plugin from:', pluginPath);\n console.log('[Agent SDK] Auth token available:', !!options.authToken);\n console.log('[Agent SDK] Anthropic API key available:', !!process.env.ANTHROPIC_API_KEY);\n console.log('[Agent SDK] Claude OAuth token available:', !!process.env.CLAUDE_CODE_OAUTH_TOKEN);\n\n // Create the query with SDK using the plugin\n const iterator = query({\n prompt: options.prompt,\n options: {\n cwd: options.cwd,\n abortController,\n permissionMode: 'bypassPermissions', // Allow MCP tools to execute automatically\n maxTurns: 100, // Reasonable limit\n env: {\n ...process.env,\n // Pass auth token through environment for MCP server\n CONTEXTGRAPH_AUTH_TOKEN: options.authToken || '',\n // Pass Anthropic API key for SDK authentication\n ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY || '',\n // Pass Claude OAuth token for SDK authentication (alternative to API key)\n CLAUDE_CODE_OAUTH_TOKEN: process.env.CLAUDE_CODE_OAUTH_TOKEN || '',\n },\n // Load the contextgraph plugin (provides MCP server URL and other config)\n plugins: [\n {\n type: 'local',\n path: pluginPath,\n }\n ]\n // Note: Auth is passed via CONTEXTGRAPH_AUTH_TOKEN environment variable above\n }\n });\n\n // Iterate through messages\n for await (const message of iterator) {\n // Capture session ID from first message\n if (!sessionId && message.session_id) {\n sessionId = message.session_id;\n }\n\n // Format and display the message (preserved console output)\n const formatted = formatMessage(message);\n if (formatted) {\n console.log(formatted);\n }\n\n // Transform and emit log event if callback is provided\n if (options.onLogEvent) {\n try {\n const logEvent = transformSDKMessage(message);\n if (logEvent) {\n options.onLogEvent(logEvent);\n }\n } catch (error) {\n // Log transformation errors but don't block execution\n console.error('[Log Transform]', error instanceof Error ? error.message : String(error));\n }\n }\n\n // Capture result metadata\n if (message.type === 'result') {\n const resultMsg = message as SDKResultMessage;\n totalCost = resultMsg.total_cost_usd || 0;\n usage = resultMsg.usage;\n\n // Check for errors\n if (resultMsg.subtype.startsWith('error_')) {\n clearTimeout(timeout);\n return {\n exitCode: 1,\n sessionId,\n usage,\n cost: totalCost,\n };\n }\n }\n }\n\n clearTimeout(timeout);\n\n // Return successful result\n return {\n exitCode: 0,\n sessionId,\n usage,\n cost: totalCost,\n };\n\n } catch (error) {\n clearTimeout(timeout);\n\n // Handle abort/timeout\n if (abortController.signal.aborted) {\n const timeoutMinutes = EXECUTION_TIMEOUT_MS / (60 * 1000);\n throw new Error(`Claude SDK execution timed out after ${timeoutMinutes} minutes`);\n }\n\n // Handle other errors\n throw new Error(`Failed to execute Claude SDK: ${(error as Error).message}`);\n }\n}\n","import { spawn } from 'child_process';\nimport { access, mkdir } from 'fs/promises';\nimport { join } from 'path';\nimport { homedir } from 'os';\n\nconst PLUGIN_REPO = 'https://github.com/contextgraph/claude-code-plugin.git';\nconst PLUGIN_DIR = join(homedir(), '.contextgraph', 'claude-code-plugin');\nconst PLUGIN_PATH = join(PLUGIN_DIR, 'plugins', 'contextgraph');\n\n/**\n * Get the path to the contextgraph plugin, cloning it if necessary\n */\nexport async function ensurePlugin(): Promise<string> {\n // Check if plugin already exists\n try {\n await access(PLUGIN_PATH);\n console.log(`📦 Using plugin: ${PLUGIN_PATH}`);\n return PLUGIN_PATH;\n } catch {\n // Plugin path doesn't exist, check if repo dir exists\n }\n\n // Check if repo directory exists but plugin path is missing (incomplete clone or wrong structure)\n let repoDirExists = false;\n try {\n await access(PLUGIN_DIR);\n repoDirExists = true;\n } catch {\n // Directory doesn't exist, will need to clone\n }\n\n if (repoDirExists) {\n // Directory exists but plugin path doesn't - try pulling latest\n console.log('📦 Plugin directory exists but incomplete, pulling latest...');\n await runCommand('git', ['pull'], PLUGIN_DIR);\n\n // Check again after pull\n try {\n await access(PLUGIN_PATH);\n console.log(`📦 Plugin ready: ${PLUGIN_PATH}`);\n return PLUGIN_PATH;\n } catch {\n throw new Error(`Plugin not found at ${PLUGIN_PATH} even after git pull. Check repository structure.`);\n }\n }\n\n console.log(`📦 Cloning plugin from ${PLUGIN_REPO}...`);\n\n // Ensure parent directory exists\n const contextgraphDir = join(homedir(), '.contextgraph');\n try {\n await mkdir(contextgraphDir, { recursive: true });\n } catch {\n // Directory might already exist\n }\n\n // Clone the repository\n await runCommand('git', ['clone', PLUGIN_REPO, PLUGIN_DIR]);\n\n // Verify plugin exists after clone\n try {\n await access(PLUGIN_PATH);\n console.log(`📦 Plugin installed: ${PLUGIN_PATH}`);\n return PLUGIN_PATH;\n } catch {\n throw new Error(`Plugin clone succeeded but plugin path not found at ${PLUGIN_PATH}`);\n }\n}\n\n/**\n * Update the plugin to latest version\n */\nexport async function updatePlugin(): Promise<void> {\n try {\n await access(PLUGIN_DIR);\n } catch {\n throw new Error('Plugin not installed. Run the agent first to auto-install.');\n }\n\n console.log('[Plugin Setup] Updating plugin...');\n await runCommand('git', ['pull'], PLUGIN_DIR);\n console.log('[Plugin Setup] Plugin updated');\n}\n\n/**\n * Get the plugin path (without ensuring it exists)\n */\nexport function getPluginPath(): string {\n return PLUGIN_PATH;\n}\n\nfunction runCommand(command: string, args: string[], cwd?: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const proc = spawn(command, args, { cwd, stdio: 'inherit' });\n\n proc.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`${command} ${args[0]} failed with exit code ${code}`));\n }\n });\n\n proc.on('error', (err) => {\n reject(new Error(`Failed to spawn ${command}: ${err.message}`));\n });\n });\n}\n","/**\n * SDK Event Transformer - Transforms Claude SDK messages into agentLog event format\n *\n * This module provides a pure transformation function that converts SDK messages\n * into LogEvent objects for the log streaming infrastructure.\n *\n * IMPORTANT: Events are emitted in the same format as the Vercel sandbox agents\n * to ensure compatibility with the AgentEventMessage component. The full SDK\n * message is preserved in the `data` field without truncation.\n */\n\nimport type { LogEvent } from './log-transport.js';\nimport type { SDKMessage, SDKAssistantMessage, SDKResultMessage } from '@anthropic-ai/claude-agent-sdk';\n\n/**\n * Transform an SDK message into a LogEvent\n *\n * The transformation preserves the full SDK message in the `data` field,\n * matching the Vercel sandbox format for UI compatibility.\n *\n * @param message - The SDK message to transform\n * @returns A LogEvent or null if the message should be skipped\n */\nexport function transformSDKMessage(message: SDKMessage): LogEvent | null {\n const timestamp = new Date().toISOString();\n\n switch (message.type) {\n case 'system':\n return transformSystemMessage(message, timestamp);\n\n case 'assistant':\n return transformAssistantMessage(message as SDKAssistantMessage, timestamp);\n\n case 'result':\n return transformResultMessage(message as SDKResultMessage, timestamp);\n\n case 'user':\n // User messages with tool results\n return transformUserMessage(message, timestamp);\n\n default:\n // Skip unknown message types\n return null;\n }\n}\n\n/**\n * Transform a system message (initialization, etc.)\n */\nfunction transformSystemMessage(\n message: SDKMessage & { subtype?: string; content?: string },\n timestamp: string\n): LogEvent {\n // Emit in the format expected by AgentEventMessage\n return {\n eventType: 'claude_message',\n content: message.content || `System: ${message.subtype || 'initialization'}`,\n data: {\n type: 'system',\n subtype: message.subtype,\n content: message.content,\n session_id: message.session_id,\n },\n timestamp,\n };\n}\n\n/**\n * Transform an assistant message (text, tool use, thinking)\n *\n * Preserves the full SDK message in the data field for UI rendering.\n * This matches the Vercel sandbox format where the entire SDK JSON\n * is stored in event.data.\n */\nfunction transformAssistantMessage(\n message: SDKAssistantMessage,\n timestamp: string\n): LogEvent | null {\n const content = message.message?.content;\n if (!content || !Array.isArray(content)) {\n return null;\n }\n\n // Generate a human-readable summary for the content field\n const contentSummary = generateContentSummary(content);\n\n // Emit the full SDK message structure in data for UI compatibility\n // This matches sandbox-execution.ts line 512-522\n return {\n eventType: 'claude_message',\n content: contentSummary,\n data: {\n type: 'assistant',\n message: message.message,\n session_id: message.session_id,\n parent_tool_use_id: message.parent_tool_use_id,\n },\n timestamp,\n };\n}\n\n/**\n * Transform a result message (completion status)\n *\n * Emits as claude_message with type='result' to match sandbox format.\n */\nfunction transformResultMessage(\n message: SDKResultMessage,\n timestamp: string\n): LogEvent {\n const isSuccess = message.subtype === 'success';\n const durationSec = message.duration_ms\n ? (message.duration_ms / 1000).toFixed(1)\n : 'unknown';\n\n return {\n eventType: 'claude_message',\n content: isSuccess\n ? `Completed successfully in ${durationSec}s`\n : `Execution ${message.subtype}: ${durationSec}s`,\n data: {\n type: 'result',\n subtype: message.subtype,\n duration_ms: message.duration_ms,\n total_cost_usd: message.total_cost_usd,\n num_turns: message.num_turns,\n usage: message.usage,\n session_id: message.session_id,\n },\n timestamp,\n };\n}\n\n/**\n * Transform a user message (typically contains tool results)\n *\n * Preserves full tool result content for UI rendering.\n */\nfunction transformUserMessage(\n message: SDKMessage & { message?: { content?: unknown } },\n timestamp: string\n): LogEvent | null {\n const content = message.message?.content;\n if (!content || !Array.isArray(content)) {\n return null;\n }\n\n // Check if this contains tool results\n const hasToolResults = content.some(\n (block: any) => block.type === 'tool_result'\n );\n\n if (!hasToolResults) {\n return null;\n }\n\n // Generate summary for content field\n const summaries = content\n .filter((block: any) => block.type === 'tool_result')\n .map((block: any) => {\n const prefix = block.is_error ? '❌' : '✓';\n const resultText = extractToolResultText(block.content);\n return `${prefix} ${resultText.substring(0, 100)}${resultText.length > 100 ? '...' : ''}`;\n });\n\n // Emit full message structure in data for UI rendering\n return {\n eventType: 'claude_message',\n content: summaries.join('\\n'),\n data: {\n type: 'user',\n message: message.message,\n session_id: message.session_id,\n },\n timestamp,\n };\n}\n\n/**\n * Generate a human-readable summary from message content blocks\n */\nfunction generateContentSummary(content: unknown[]): string {\n const parts: string[] = [];\n\n for (const block of content as any[]) {\n if (block.type === 'text' && block.text) {\n // Include first 200 chars of text in summary\n const text = block.text.length > 200\n ? block.text.substring(0, 200) + '...'\n : block.text;\n parts.push(text);\n } else if (block.type === 'tool_use') {\n parts.push(`🔧 ${block.name}`);\n } else if (block.type === 'thinking') {\n parts.push('💭 [thinking]');\n }\n }\n\n return parts.join(' | ') || '[no content]';\n}\n\n/**\n * Extract text content from a tool result for summary purposes\n */\nfunction extractToolResultText(\n content: string | Array<{ type: string; text?: string }> | undefined\n): string {\n if (!content) return '';\n\n if (typeof content === 'string') {\n return content;\n }\n\n if (Array.isArray(content)) {\n return content\n .filter(block => block.type === 'text' && block.text)\n .map(block => block.text)\n .join('\\n');\n }\n\n return '';\n}\n\n/**\n * Batch transform multiple SDK messages\n * Useful for processing message arrays from SDK iterations\n *\n * @param messages - Array of SDK messages\n * @returns Array of LogEvents (excluding nulls)\n */\nexport function transformSDKMessages(messages: SDKMessage[]): LogEvent[] {\n return messages\n .map(transformSDKMessage)\n .filter((event): event is LogEvent => event !== null);\n}\n","export interface RetryOptions {\n maxRetries?: number;\n baseDelayMs?: number;\n maxDelayMs?: number;\n /** If true, will log retry attempts */\n verbose?: boolean;\n}\n\nexport async function fetchWithRetry(\n url: string,\n options: RequestInit,\n retryOptions: RetryOptions = {}\n): Promise<Response> {\n const { maxRetries = 3, baseDelayMs = 1000, maxDelayMs = 10000 } = retryOptions;\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, options);\n // Don't retry on client errors (4xx), only on server/network errors\n if (response.ok || (response.status >= 400 && response.status < 500)) {\n return response;\n }\n // Server error (5xx) - will retry\n lastError = new Error(`HTTP ${response.status}`);\n } catch (error) {\n // Network error - will retry\n lastError = error instanceof Error ? error : new Error(String(error));\n }\n\n if (attempt < maxRetries) {\n // Exponential backoff with jitter\n const delay = Math.min(baseDelayMs * Math.pow(2, attempt), maxDelayMs);\n const jitter = delay * 0.1 * Math.random();\n await new Promise((resolve) => setTimeout(resolve, delay + jitter));\n }\n }\n\n throw lastError ?? new Error('Request failed after retries');\n}\n","/**\n * LogTransportService - Handles sending log events to the platform API\n *\n * This service manages:\n * - Creating and updating runs\n * - Sending batches of log events\n * - Retry logic with exponential backoff\n */\n\n/**\n * Log event types supported by the platform\n */\nexport type LogEventType =\n | 'stdout'\n | 'stderr'\n | 'claude_message'\n | 'tool_use'\n | 'tool_result'\n | 'system';\n\n/**\n * A log event to be sent to the platform\n */\nexport interface LogEvent {\n eventType: LogEventType;\n content: string;\n data?: Record<string, unknown>;\n timestamp: string;\n}\n\n/**\n * Response from creating a run\n */\nexport interface CreateRunResponse {\n runId: string;\n}\n\n/**\n * Response from batch send\n */\nexport interface BatchSendResponse {\n success: boolean;\n eventsReceived?: number;\n}\n\n/**\n * Configuration for retry behavior\n */\nexport interface RetryConfig {\n maxRetries: number;\n initialDelayMs: number;\n backoffFactor: number;\n}\n\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 3,\n initialDelayMs: 100,\n backoffFactor: 2,\n};\n\n/**\n * Service for sending log events to the platform API\n */\nexport class LogTransportService {\n private runId: string | null = null;\n private retryConfig: RetryConfig;\n\n constructor(\n private baseUrl: string,\n private authToken: string,\n runId?: string,\n retryConfig?: Partial<RetryConfig>\n ) {\n this.runId = runId ?? null;\n this.retryConfig = { ...DEFAULT_RETRY_CONFIG, ...retryConfig };\n }\n\n /**\n * Get the current run ID\n */\n getRunId(): string | null {\n return this.runId;\n }\n\n /**\n * Create a new run for an action\n * @param actionId - The action ID this run is executing\n * @returns The created run ID\n */\n async createRun(actionId: string): Promise<string> {\n const response = await this.makeRequest('/api/runs', {\n method: 'POST',\n body: JSON.stringify({\n actionId,\n state: 'queued',\n }),\n });\n\n const result = await response.json();\n\n if (!result.success) {\n throw new Error(result.error || 'Failed to create run');\n }\n\n this.runId = result.data.runId;\n return this.runId;\n }\n\n /**\n * Start the run (transition to running state)\n * Called when execution begins\n */\n async startRun(): Promise<void> {\n if (!this.runId) {\n throw new Error('No run ID set. Call createRun() first.');\n }\n\n const response = await this.makeRequest(`/api/runs/${this.runId}/start`, {\n method: 'POST',\n body: JSON.stringify({}),\n });\n\n const result = await response.json();\n\n if (!result.success) {\n throw new Error(result.error || 'Failed to start run');\n }\n }\n\n /**\n * Finish the run with an outcome\n * @param outcome - 'success' | 'error' | 'timeout' | 'incomplete'\n * @param metadata - Optional metadata (exitCode, errorMessage, cost, usage)\n */\n async finishRun(\n outcome: 'success' | 'error' | 'timeout' | 'incomplete',\n metadata?: {\n exitCode?: number;\n errorMessage?: string;\n cost?: number;\n usage?: Record<string, unknown>;\n }\n ): Promise<void> {\n if (!this.runId) {\n throw new Error('No run ID set. Call createRun() first.');\n }\n\n const response = await this.makeRequest(`/api/runs/${this.runId}/finish`, {\n method: 'POST',\n body: JSON.stringify({\n outcome,\n exitCode: metadata?.exitCode?.toString(),\n errorMessage: metadata?.errorMessage,\n }),\n });\n\n const result = await response.json();\n\n if (!result.success) {\n // If the run is already in a finishing state (summarizing, finished),\n // this is not an error - the server is already handling completion\n const error = result.error || 'Failed to finish run';\n if (error.includes('summarizing') || error.includes('finished')) {\n console.log('[LogTransport] Run is already being finished by server, skipping client finish');\n return;\n }\n throw new Error(error);\n }\n }\n\n /**\n * Update the state of the current run\n * @deprecated Use startRun() and finishRun() instead\n * @param state - New state for the run\n * @param metadata - Optional metadata to include with the state update\n */\n async updateRunState(\n state: string,\n metadata?: Record<string, unknown>\n ): Promise<void> {\n if (!this.runId) {\n throw new Error('No run ID set. Call createRun() first.');\n }\n\n // Map state to appropriate endpoint\n if (state === 'executing' || state === 'preparing' || state === 'running') {\n await this.startRun();\n } else if (state === 'completed' || state === 'failed') {\n const outcome = state === 'completed' ? 'success' : 'error';\n await this.finishRun(outcome, {\n exitCode: metadata?.exitCode as number | undefined,\n errorMessage: metadata?.error as string | undefined,\n cost: metadata?.cost as number | undefined,\n usage: metadata?.usage as Record<string, unknown> | undefined,\n });\n } else {\n // For unknown states, just log a warning\n console.warn(`[LogTransport] Unknown state '${state}' - no API call made`);\n }\n }\n\n /**\n * Send a batch of log events to the platform\n * @param events - Array of log events to send\n * @param workerId - Optional worker ID\n * @returns Success status and number of events received\n */\n async sendBatch(\n events: LogEvent[],\n workerId?: string\n ): Promise<BatchSendResponse> {\n if (!this.runId) {\n throw new Error('No run ID set. Call createRun() first.');\n }\n\n if (events.length === 0) {\n return { success: true, eventsReceived: 0 };\n }\n\n const response = await this.makeRequest('/api/agents/log/event', {\n method: 'POST',\n body: JSON.stringify({\n runId: this.runId,\n events,\n ...(workerId && { workerId }),\n }),\n });\n\n const result = await response.json();\n\n if (!result.success) {\n throw new Error(result.error || 'Failed to send log batch');\n }\n\n return {\n success: true,\n eventsReceived: result.data?.eventsReceived ?? events.length,\n };\n }\n\n /**\n * Make an HTTP request with retry logic\n */\n private async makeRequest(\n path: string,\n options: RequestInit\n ): Promise<Response> {\n const url = `${this.baseUrl}${path}`;\n const headers = {\n 'x-authorization': `Bearer ${this.authToken}`,\n 'Content-Type': 'application/json',\n };\n\n let lastError: Error | null = null;\n let delay = this.retryConfig.initialDelayMs;\n\n for (let attempt = 0; attempt <= this.retryConfig.maxRetries; attempt++) {\n try {\n const response = await fetch(url, {\n ...options,\n headers: {\n ...headers,\n ...(options.headers || {}),\n },\n });\n\n // Don't retry on client errors (4xx) - these won't succeed on retry\n if (response.status >= 400 && response.status < 500) {\n return response;\n }\n\n // Retry on server errors (5xx) or network issues\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n return response;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Don't wait after the last attempt\n if (attempt < this.retryConfig.maxRetries) {\n await this.sleep(delay);\n delay *= this.retryConfig.backoffFactor;\n }\n }\n }\n\n throw new Error(\n `Request failed after ${this.retryConfig.maxRetries + 1} attempts: ${lastError?.message}`\n );\n }\n\n /**\n * Sleep for a given number of milliseconds\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","/**\n * LogBuffer - Manages buffered, non-blocking log transmission\n *\n * Collects log events and flushes them periodically to avoid\n * blocking the main Claude execution flow.\n */\n\nimport { LogTransportService, type LogEvent } from './log-transport.js';\n\n// Buffer configuration for log streaming\nconst LOG_BUFFER_FLUSH_INTERVAL_MS = 500;\nconst LOG_BUFFER_MAX_SIZE = 50;\nconst LOG_BUFFER_MAX_QUEUE_SIZE = 1000;\n\nexport class LogBuffer {\n private buffer: LogEvent[] = [];\n private flushIntervalId: ReturnType<typeof setInterval> | null = null;\n private isFlushing = false;\n\n constructor(\n private transport: LogTransportService,\n private flushIntervalMs: number = LOG_BUFFER_FLUSH_INTERVAL_MS,\n private maxBufferSize: number = LOG_BUFFER_MAX_SIZE,\n private maxQueueSize: number = LOG_BUFFER_MAX_QUEUE_SIZE\n ) {}\n\n /**\n * Add an event to the buffer (fire-and-forget)\n * Handles backpressure by dropping oldest events if queue is full.\n */\n push(event: LogEvent): void {\n // Backpressure: drop oldest events if queue is too large\n if (this.buffer.length >= this.maxQueueSize) {\n this.buffer.shift();\n }\n this.buffer.push(event);\n\n // Trigger immediate flush if buffer is at max size\n if (this.buffer.length >= this.maxBufferSize) {\n this.flushAsync();\n }\n }\n\n /**\n * Start periodic flushing\n */\n start(): void {\n if (this.flushIntervalId !== null) return;\n\n this.flushIntervalId = setInterval(() => {\n this.flushAsync();\n }, this.flushIntervalMs);\n }\n\n /**\n * Stop periodic flushing and flush remaining events\n */\n async stop(): Promise<void> {\n if (this.flushIntervalId !== null) {\n clearInterval(this.flushIntervalId);\n this.flushIntervalId = null;\n }\n\n // Final flush of remaining events\n await this.flush();\n }\n\n /**\n * Async flush (fire-and-forget, non-blocking)\n */\n private flushAsync(): void {\n // Don't start a new flush if one is in progress\n if (this.isFlushing || this.buffer.length === 0) return;\n\n // Fire and forget - don't await\n this.flush().catch((error) => {\n console.error('[LogBuffer] Flush error:', error instanceof Error ? error.message : String(error));\n });\n }\n\n /**\n * Flush current buffer contents to transport\n */\n private async flush(): Promise<void> {\n if (this.isFlushing || this.buffer.length === 0) return;\n\n this.isFlushing = true;\n const eventsToSend = [...this.buffer];\n this.buffer = [];\n\n try {\n await this.transport.sendBatch(eventsToSend);\n } catch (error) {\n // Log errors but don't re-queue (to avoid infinite growth)\n console.error('[LogBuffer] Failed to send batch:', error instanceof Error ? error.message : String(error));\n } finally {\n this.isFlushing = false;\n }\n }\n}\n","/**\n * HeartbeatManager - Sends periodic liveness signals during execution\n *\n * This service manages:\n * - Periodic heartbeat signals to the platform\n * - Phase/progress updates without blocking execution\n * - Graceful error handling (log, don't throw)\n */\n\n/**\n * Execution phases for heartbeat reporting\n */\nexport type HeartbeatPhase = 'executing' | 'reading' | 'writing' | 'thinking';\n\n/**\n * Heartbeat payload sent to the platform\n */\nexport interface HeartbeatPayload {\n phase: HeartbeatPhase;\n progress?: number;\n timestamp: string;\n}\n\n/**\n * HeartbeatManager - Self-managing heartbeat service\n *\n * Sends periodic liveness signals to keep the platform informed\n * of worker status without blocking the main execution flow.\n */\nexport class HeartbeatManager {\n private intervalId: ReturnType<typeof setInterval> | null = null;\n private currentPhase: HeartbeatPhase = 'executing';\n private currentProgress: number | undefined = undefined;\n\n constructor(\n private baseUrl: string,\n private authToken: string,\n private runId: string\n ) {}\n\n /**\n * Start sending periodic heartbeats\n * @param intervalMs - Time between heartbeats in milliseconds (default: 30000)\n */\n start(intervalMs: number = 30000): void {\n // Clear any existing interval\n this.stop();\n\n // Send initial heartbeat immediately\n this.sendHeartbeat();\n\n // Set up periodic heartbeats\n this.intervalId = setInterval(() => {\n this.sendHeartbeat();\n }, intervalMs);\n }\n\n /**\n * Stop sending heartbeats\n */\n stop(): void {\n if (this.intervalId !== null) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n }\n\n /**\n * Update the current phase and optional progress\n * @param phase - Current execution phase\n * @param progress - Optional progress percentage (0-100)\n */\n updatePhase(phase: HeartbeatPhase, progress?: number): void {\n this.currentPhase = phase;\n this.currentProgress = progress;\n }\n\n /**\n * Check if heartbeat manager is currently running\n */\n isRunning(): boolean {\n return this.intervalId !== null;\n }\n\n /**\n * Send a heartbeat to the platform (internal method)\n * Errors are logged but not thrown to avoid blocking execution.\n * Includes one retry attempt for transient network failures.\n */\n private async sendHeartbeat(): Promise<void> {\n const payload: HeartbeatPayload = {\n phase: this.currentPhase,\n timestamp: new Date().toISOString(),\n };\n\n if (this.currentProgress !== undefined) {\n payload.progress = this.currentProgress;\n }\n\n const url = `${this.baseUrl}/api/runs/${this.runId}/heartbeat`;\n const requestOptions: RequestInit = {\n method: 'POST',\n headers: {\n 'x-authorization': `Bearer ${this.authToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n };\n\n // Try up to 2 times (initial + 1 retry)\n for (let attempt = 0; attempt < 2; attempt++) {\n try {\n const response = await fetch(url, requestOptions);\n\n if (response.ok) {\n return; // Success\n }\n\n // Don't retry client errors (4xx)\n if (response.status >= 400 && response.status < 500) {\n console.error(\n `Heartbeat failed: HTTP ${response.status} ${response.statusText}`\n );\n return;\n }\n\n // Server error - will retry\n if (attempt === 0) {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n } catch (error) {\n // Network error - retry once\n if (attempt === 0) {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n } else {\n // Log on final failure\n console.error(\n 'Heartbeat error:',\n error instanceof Error ? error.message : String(error)\n );\n }\n }\n }\n }\n}\n","import { loadCredentials, isExpired, isTokenExpired } from '../credentials.js';\nimport { executeClaude } from '../claude-sdk.js';\nimport { fetchWithRetry } from '../fetch-with-retry.js';\nimport { LogTransportService } from '../log-transport.js';\nimport { LogBuffer } from '../log-buffer.js';\nimport { HeartbeatManager } from '../heartbeat-manager.js';\n\nconst API_BASE_URL = 'https://www.contextgraph.dev';\n\nexport interface WorkflowOptions {\n cwd?: string;\n}\n\nexport async function runPrepare(actionId: string, options?: WorkflowOptions): Promise<void> {\n const credentials = await loadCredentials();\n\n if (!credentials) {\n console.error('❌ Not authenticated. Run authentication first.');\n process.exit(1);\n }\n\n if (isExpired(credentials) || isTokenExpired(credentials.clerkToken)) {\n console.error('❌ Token expired. Re-authenticate to continue.');\n process.exit(1);\n }\n\n console.log(`Fetching preparation instructions for action ${actionId}...\\n`);\n\n const response = await fetchWithRetry(\n `${API_BASE_URL}/api/prompts/prepare`,\n {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${credentials.clerkToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ actionId }),\n }\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Failed to fetch prepare prompt: ${response.statusText}\\n${errorText}`);\n }\n\n const { prompt } = await response.json();\n\n // Initialize log streaming infrastructure\n const logTransport = new LogTransportService(API_BASE_URL, credentials.clerkToken);\n let runId: string | undefined;\n let heartbeatManager: HeartbeatManager | undefined;\n let logBuffer: LogBuffer | undefined;\n\n try {\n // Create run for this preparation phase\n console.log('[Log Streaming] Creating run for prepare phase...');\n runId = await logTransport.createRun(actionId);\n console.log(`[Log Streaming] Run created: ${runId}`);\n\n // Update run state to preparing\n await logTransport.updateRunState('preparing');\n\n // Start heartbeat manager\n heartbeatManager = new HeartbeatManager(API_BASE_URL, credentials.clerkToken, runId);\n heartbeatManager.start();\n console.log('[Log Streaming] Heartbeat started');\n\n // Set up log buffer for non-blocking transmission\n logBuffer = new LogBuffer(logTransport);\n logBuffer.start();\n\n console.log('Spawning Claude for preparation...\\n');\n\n const claudeResult = await executeClaude({\n prompt,\n cwd: options?.cwd || process.cwd(),\n authToken: credentials.clerkToken,\n onLogEvent: (event) => {\n logBuffer!.push(event);\n },\n });\n\n // Update run state based on execution result\n if (claudeResult.exitCode === 0) {\n await logTransport.finishRun('success', {\n exitCode: claudeResult.exitCode,\n cost: claudeResult.cost,\n usage: claudeResult.usage,\n });\n console.log('\\n✅ Preparation complete');\n } else {\n await logTransport.finishRun('error', {\n exitCode: claudeResult.exitCode,\n errorMessage: `Claude preparation failed with exit code ${claudeResult.exitCode}`,\n });\n console.error(`\\n❌ Claude preparation failed with exit code ${claudeResult.exitCode}`);\n process.exit(1);\n }\n\n } catch (error) {\n // Update run state to failed if we have a run\n if (runId) {\n try {\n await logTransport.finishRun('error', {\n errorMessage: error instanceof Error ? error.message : String(error),\n });\n } catch (stateError) {\n console.error('[Log Streaming] Failed to update run state:', stateError);\n }\n }\n throw error;\n\n } finally {\n // Cleanup: stop heartbeat and flush remaining logs\n if (heartbeatManager) {\n heartbeatManager.stop();\n console.log('[Log Streaming] Heartbeat stopped');\n }\n\n if (logBuffer) {\n await logBuffer.stop();\n console.log('[Log Streaming] Logs flushed');\n }\n }\n}\n","import { loadCredentials, isExpired, isTokenExpired } from '../credentials.js';\nimport { executeClaude } from '../claude-sdk.js';\nimport { fetchWithRetry } from '../fetch-with-retry.js';\nimport { LogTransportService } from '../log-transport.js';\nimport { LogBuffer } from '../log-buffer.js';\nimport { HeartbeatManager } from '../heartbeat-manager.js';\n\nconst API_BASE_URL = 'https://www.contextgraph.dev';\n\nexport interface WorkflowOptions {\n cwd?: string;\n}\n\nexport async function runExecute(actionId: string, options?: WorkflowOptions): Promise<void> {\n const credentials = await loadCredentials();\n\n if (!credentials) {\n console.error('❌ Not authenticated. Run authentication first.');\n process.exit(1);\n }\n\n if (isExpired(credentials) || isTokenExpired(credentials.clerkToken)) {\n console.error('❌ Token expired. Re-authenticate to continue.');\n process.exit(1);\n }\n\n console.log(`Fetching execution instructions for action ${actionId}...\\n`);\n\n const response = await fetchWithRetry(\n `${API_BASE_URL}/api/prompts/execute`,\n {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${credentials.clerkToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ actionId }),\n }\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Failed to fetch execute prompt: ${response.statusText}\\n${errorText}`);\n }\n\n const { prompt } = await response.json();\n\n // Initialize log streaming infrastructure\n const logTransport = new LogTransportService(API_BASE_URL, credentials.clerkToken);\n let runId: string | undefined;\n let heartbeatManager: HeartbeatManager | undefined;\n let logBuffer: LogBuffer | undefined;\n\n try {\n // Create run for this execution\n console.log('[Log Streaming] Creating run...');\n runId = await logTransport.createRun(actionId);\n console.log(`[Log Streaming] Run created: ${runId}`);\n\n // Update run state to executing\n await logTransport.updateRunState('executing');\n\n // Start heartbeat manager\n heartbeatManager = new HeartbeatManager(API_BASE_URL, credentials.clerkToken, runId);\n heartbeatManager.start();\n console.log('[Log Streaming] Heartbeat started');\n\n // Set up log buffer for non-blocking transmission\n logBuffer = new LogBuffer(logTransport);\n logBuffer.start();\n\n console.log('Spawning Claude for execution...\\n');\n\n const claudeResult = await executeClaude({\n prompt,\n cwd: options?.cwd || process.cwd(),\n authToken: credentials.clerkToken,\n onLogEvent: (event) => {\n logBuffer!.push(event);\n },\n });\n\n // Update run state based on execution result\n if (claudeResult.exitCode === 0) {\n await logTransport.finishRun('success', {\n exitCode: claudeResult.exitCode,\n cost: claudeResult.cost,\n usage: claudeResult.usage,\n });\n console.log('\\n✅ Execution complete');\n } else {\n await logTransport.finishRun('error', {\n exitCode: claudeResult.exitCode,\n errorMessage: `Claude execution failed with exit code ${claudeResult.exitCode}`,\n });\n throw new Error(`Claude execution failed with exit code ${claudeResult.exitCode}`);\n }\n\n } catch (error) {\n // Update run state to failed if we have a run\n if (runId) {\n try {\n await logTransport.finishRun('error', {\n errorMessage: error instanceof Error ? error.message : String(error),\n });\n } catch (stateError) {\n console.error('[Log Streaming] Failed to update run state:', stateError);\n }\n }\n throw error;\n\n } finally {\n // Cleanup: stop heartbeat and flush remaining logs\n if (heartbeatManager) {\n heartbeatManager.stop();\n console.log('[Log Streaming] Heartbeat stopped');\n }\n\n if (logBuffer) {\n await logBuffer.stop();\n console.log('[Log Streaming] Logs flushed');\n }\n }\n}\n","import { randomUUID } from 'crypto';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport { ApiClient } from '../api-client.js';\nimport type { ActionNode, ActionMetadata } from '../types/actions.js';\nimport { findNextLeaf, type FindNextLeafResult } from '../next-action.js';\nimport { runPrepare } from './prepare.js';\nimport { runExecute } from './execute.js';\nimport { prepareWorkspace } from '../workspace-prep.js';\nimport { loadCredentials, isExpired, isTokenExpired } from '../credentials.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n// When built, this file is in dist/, so package.json is one level up\nconst packageJson = JSON.parse(\n readFileSync(join(__dirname, '../package.json'), 'utf-8')\n);\n\n// Polling configuration from environment variables\nconst INITIAL_POLL_INTERVAL = parseInt(process.env.WORKER_INITIAL_POLL_INTERVAL || '2000', 10); // 2 seconds default\nconst MAX_POLL_INTERVAL = parseInt(process.env.WORKER_MAX_POLL_INTERVAL || '5000', 10); // 5 seconds default\nconst BACKOFF_MULTIPLIER = 1.5;\nconst STATUS_INTERVAL_MS = 30000; // Show status every 30 seconds when idle\n\n// Retry configuration for transient API errors\n// For extended outages, we wait indefinitely with a ceiling on delay\nconst MAX_API_RETRIES = Infinity; // Never give up on transient errors\nconst INITIAL_RETRY_DELAY = 1000; // 1 second\nconst MAX_RETRY_DELAY = 60000; // 1 minute ceiling\nconst OUTAGE_WARNING_THRESHOLD = 5; // Warn user after this many retries\n\n// Module-scope state for graceful shutdown\nlet running = true;\nlet currentClaim: { actionId: string; claimId: string; workerId: string } | null = null;\nlet apiClient: ApiClient | null = null;\n\n// Stats tracking\nconst stats = {\n startTime: Date.now(),\n prepared: 0,\n executed: 0,\n errors: 0,\n};\n\nfunction formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n\n if (hours > 0) {\n return `${hours}h ${minutes % 60}m`;\n } else if (minutes > 0) {\n return `${minutes}m ${seconds % 60}s`;\n }\n return `${seconds}s`;\n}\n\nfunction printStatus(): void {\n const uptime = formatDuration(Date.now() - stats.startTime);\n const total = stats.prepared + stats.executed;\n console.log(`Status: ${total} actions (${stats.prepared} prepared, ${stats.executed} executed, ${stats.errors} errors) | Uptime: ${uptime}`);\n}\n\n/**\n * Get the next action to work on, handling tree depth truncation.\n * If the tree is truncated (children exist beyond depth limit), this function\n * will recursively re-fetch the tree starting from the truncated node.\n */\nasync function getNextAction(\n apiClient: ApiClient,\n rootId: string,\n depth: number = 0\n): Promise<ActionNode | null> {\n // Prevent infinite recursion in case of malformed data\n const maxDepth = 20;\n if (depth >= maxDepth) {\n console.error(`❌ Tree traversal exceeded maximum depth (${maxDepth}). Possible cycle or malformed data.`);\n return null;\n }\n\n const tree = await apiClient.fetchTree(rootId, false);\n\n if (tree.done) {\n if (depth === 0) {\n console.log('✅ Root action is already complete');\n }\n return null;\n }\n\n // Use local findNextLeaf to traverse tree and find next action\n const result = findNextLeaf(tree);\n\n // If we found an action, return it\n if (result.action) {\n return result.action;\n }\n\n // If tree was truncated, re-fetch starting from the truncated node\n if (result.truncatedAt) {\n console.log(`📊 Tree depth limit reached at action ${result.truncatedAt}. Fetching deeper...`);\n return getNextAction(apiClient, result.truncatedAt, depth + 1);\n }\n\n // No action found and no truncation - tree is complete or blocked\n return null;\n}\n\n/**\n * Clean up any claimed work and exit gracefully\n */\nasync function cleanupAndExit(): Promise<void> {\n if (currentClaim && apiClient) {\n try {\n console.log(`\\n🧹 Releasing claim on action ${currentClaim.actionId}...`);\n await apiClient.releaseClaim({\n action_id: currentClaim.actionId,\n worker_id: currentClaim.workerId,\n claim_id: currentClaim.claimId,\n });\n console.log('✅ Claim released successfully');\n } catch (error) {\n console.error('⚠️ Failed to release claim:', (error as Error).message);\n }\n }\n console.log('👋 Shutdown complete');\n process.exit(0);\n}\n\n/**\n * Set up signal handlers for graceful shutdown\n */\nfunction setupSignalHandlers(): void {\n process.on('SIGINT', async () => {\n console.log('\\n\\n⚠️ Received SIGINT (Ctrl+C). Shutting down gracefully...');\n running = false;\n await cleanupAndExit();\n });\n\n process.on('SIGTERM', async () => {\n console.log('\\n\\n⚠️ Received SIGTERM. Shutting down gracefully...');\n running = false;\n await cleanupAndExit();\n });\n}\n\n/**\n * Sleep for the specified number of milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Check if an error is likely transient and worth retrying\n */\nfunction isRetryableError(error: Error): boolean {\n const message = error.message.toLowerCase();\n // Retry on server errors (5xx), network errors, and timeouts\n return (\n message.includes('api error 5') ||\n message.includes('500') ||\n message.includes('502') ||\n message.includes('503') ||\n message.includes('504') ||\n message.includes('network') ||\n message.includes('timeout') ||\n message.includes('econnreset') ||\n message.includes('econnrefused') ||\n message.includes('socket hang up') ||\n message.includes('failed query') // Database query failures\n );\n}\n\nexport async function runLocalAgent(): Promise<void> {\n // Initialize module-scope apiClient for signal handlers\n apiClient = new ApiClient();\n\n // Set up graceful shutdown handlers\n setupSignalHandlers();\n\n // Load and validate credentials upfront\n const credentials = await loadCredentials();\n if (!credentials) {\n console.error('❌ Not authenticated.');\n console.error(' Set CONTEXTGRAPH_API_TOKEN environment variable or run `contextgraph-agent auth`');\n process.exit(1);\n }\n if (isExpired(credentials) || isTokenExpired(credentials.clerkToken)) {\n console.error('❌ Token expired. Run `contextgraph-agent auth` to re-authenticate.');\n process.exit(1);\n }\n\n // Show authentication method\n const usingApiToken = !!process.env.CONTEXTGRAPH_API_TOKEN;\n if (usingApiToken) {\n console.log('🔐 Authenticated via CONTEXTGRAPH_API_TOKEN');\n }\n\n // Generate unique worker ID for this session\n const workerId = randomUUID();\n\n console.log(`🤖 ContextGraph Agent v${packageJson.version}`);\n console.log(`👷 Worker ID: ${workerId}`);\n console.log(`🔄 Starting continuous worker loop...\\n`);\n console.log(`💡 Press Ctrl+C to gracefully shutdown and release any claimed work\\n`);\n\n let currentPollInterval = INITIAL_POLL_INTERVAL;\n let lastStatusTime = Date.now();\n let consecutiveApiErrors = 0;\n let apiRetryDelay = INITIAL_RETRY_DELAY;\n\n while (running) {\n\n // Claim next action from worker queue with retry logic\n let actionDetail;\n try {\n actionDetail = await apiClient.claimNextAction(workerId);\n // Reset error tracking on success\n consecutiveApiErrors = 0;\n apiRetryDelay = INITIAL_RETRY_DELAY;\n } catch (error) {\n const err = error as Error;\n\n if (isRetryableError(err)) {\n consecutiveApiErrors++;\n\n // Show extended outage warning once\n if (consecutiveApiErrors === OUTAGE_WARNING_THRESHOLD) {\n console.warn(`\\n⚠️ API appears to be experiencing an outage.`);\n console.warn(` Will continue retrying indefinitely (every ${MAX_RETRY_DELAY / 1000}s max).`);\n console.warn(` Press Ctrl+C to stop.\\n`);\n }\n\n if (consecutiveApiErrors < OUTAGE_WARNING_THRESHOLD) {\n console.warn(`⚠️ API error (attempt ${consecutiveApiErrors}): ${err.message}`);\n } else if (consecutiveApiErrors % 10 === 0) {\n // Only log every 10th retry during extended outage to reduce noise\n console.warn(`⚠️ Still retrying... (attempt ${consecutiveApiErrors}, last error: ${err.message})`);\n }\n\n const delaySeconds = Math.round(apiRetryDelay / 1000);\n if (consecutiveApiErrors < OUTAGE_WARNING_THRESHOLD) {\n console.warn(` Retrying in ${delaySeconds}s...`);\n }\n\n await sleep(apiRetryDelay);\n apiRetryDelay = Math.min(apiRetryDelay * 2, MAX_RETRY_DELAY);\n continue;\n }\n\n // Non-retryable error - re-throw\n throw err;\n }\n\n if (!actionDetail) {\n // Show periodic status while waiting\n if (Date.now() - lastStatusTime >= STATUS_INTERVAL_MS) {\n printStatus();\n lastStatusTime = Date.now();\n }\n await sleep(currentPollInterval);\n currentPollInterval = Math.min(currentPollInterval * BACKOFF_MULTIPLIER, MAX_POLL_INTERVAL);\n continue;\n }\n\n // Reset poll interval on successful claim\n currentPollInterval = INITIAL_POLL_INTERVAL;\n\n console.log(`Working: ${actionDetail.title}`);\n\n // Track current claim for graceful shutdown\n if (actionDetail.claim_id) {\n currentClaim = {\n actionId: actionDetail.id,\n claimId: actionDetail.claim_id,\n workerId,\n };\n }\n\n const isPrepared = actionDetail.prepared !== false;\n\n // Prepare workspace - repository URL is required\n const repoUrl = actionDetail.resolved_repository_url || actionDetail.repository_url;\n const branch = actionDetail.resolved_branch || actionDetail.branch;\n\n if (!repoUrl) {\n console.error(`\\n❌ Action \"${actionDetail.title}\" has no repository_url set.`);\n console.error(` Actions must have a repository_url (directly or inherited from parent).`);\n console.error(` Action ID: ${actionDetail.id}`);\n console.error(` resolved_repository_url: ${actionDetail.resolved_repository_url}`);\n console.error(` repository_url: ${actionDetail.repository_url}`);\n process.exit(1);\n }\n\n let workspacePath: string;\n let cleanup: (() => Promise<void>) | undefined;\n\n try {\n const workspace = await prepareWorkspace(repoUrl, {\n branch: branch || undefined,\n authToken: credentials.clerkToken,\n });\n workspacePath = workspace.path;\n cleanup = workspace.cleanup;\n\n if (!isPrepared) {\n await runPrepare(actionDetail.id, { cwd: workspacePath });\n stats.prepared++;\n\n // Release claim after preparation\n if (currentClaim && apiClient) {\n try {\n await apiClient.releaseClaim({\n action_id: currentClaim.actionId,\n worker_id: currentClaim.workerId,\n claim_id: currentClaim.claimId,\n });\n } catch (releaseError) {\n console.error('⚠️ Failed to release claim after preparation:', (releaseError as Error).message);\n }\n }\n currentClaim = null;\n continue;\n }\n\n try {\n await runExecute(actionDetail.id, { cwd: workspacePath });\n stats.executed++;\n console.log(`Completed: ${actionDetail.title}`);\n } catch (executeError) {\n stats.errors++;\n console.error(`Error: ${(executeError as Error).message}. Continuing...`);\n } finally {\n // Release claim after execution completes (success or failure)\n if (currentClaim && apiClient) {\n try {\n await apiClient.releaseClaim({\n action_id: currentClaim.actionId,\n worker_id: currentClaim.workerId,\n claim_id: currentClaim.claimId,\n });\n } catch (releaseError) {\n console.error('⚠️ Failed to release claim:', (releaseError as Error).message);\n }\n }\n currentClaim = null;\n }\n } catch (workspaceError) {\n // Handle workspace preparation or other errors\n stats.errors++;\n console.error(`Error preparing workspace: ${(workspaceError as Error).message}. Continuing...`);\n\n // Release claim on workspace/preparation failure\n if (currentClaim && apiClient) {\n try {\n console.log(`🧹 Releasing claim due to workspace error...`);\n await apiClient.releaseClaim({\n action_id: currentClaim.actionId,\n worker_id: currentClaim.workerId,\n claim_id: currentClaim.claimId,\n });\n console.log('✅ Claim released');\n } catch (releaseError) {\n console.error('⚠️ Failed to release claim:', (releaseError as Error).message);\n }\n }\n currentClaim = null;\n } finally {\n if (cleanup) {\n await cleanup();\n }\n }\n }\n\n}\n\n","import { loadCredentials, isExpired, isTokenExpired } from './credentials.js';\nimport { fetchWithRetry } from './fetch-with-retry.js';\nimport type { ActionDetailResource, ActionNode } from './types/actions.js';\n\nexport class ApiClient {\n constructor(\n private baseUrl: string = 'https://www.contextgraph.dev'\n ) {}\n\n private async getAuthToken(): Promise<string> {\n const credentials = await loadCredentials();\n\n if (!credentials) {\n throw new Error('Not authenticated. Run authentication first.');\n }\n\n // Check both the stored metadata and the actual JWT expiration\n if (isExpired(credentials) || isTokenExpired(credentials.clerkToken)) {\n throw new Error('Token expired. Re-authenticate to continue.');\n }\n\n return credentials.clerkToken;\n }\n\n async getActionDetail(actionId: string): Promise<ActionDetailResource> {\n const token = await this.getAuthToken();\n\n // Use both x-authorization header and query param for Vercel compatibility\n const response = await fetchWithRetry(\n `${this.baseUrl}/api/actions/${actionId}?token=${encodeURIComponent(token)}`,\n {\n headers: {\n 'x-authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n }\n );\n\n if (!response.ok) {\n throw new Error(`API error: ${response.status}`);\n }\n\n const result = await response.json();\n\n if (!result.success) {\n throw new Error(result.error);\n }\n\n return result.data;\n }\n\n async fetchTree(rootActionId: string, includeCompleted: boolean = false): Promise<ActionNode> {\n const token = await this.getAuthToken();\n\n // Use both x-authorization header and query param for Vercel compatibility\n const response = await fetchWithRetry(\n `${this.baseUrl}/api/tree/${rootActionId}?includeCompleted=${includeCompleted}&token=${encodeURIComponent(token)}`,\n {\n headers: {\n 'x-authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n }\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Failed to fetch tree: ${response.status} ${errorText}`);\n }\n\n const result = await response.json();\n if (!result.success) {\n throw new Error('Failed to fetch tree: API returned unsuccessful response');\n }\n\n // If no root actions, the tree is complete (all actions done)\n if (!result.data.rootActions?.[0]) {\n return { id: rootActionId, title: '', done: true, dependencies: [], children: [] };\n }\n\n return result.data.rootActions[0];\n }\n\n async claimNextAction(workerId: string): Promise<ActionDetailResource | null> {\n const token = await this.getAuthToken();\n\n const response = await fetchWithRetry(\n `${this.baseUrl}/api/worker/next?token=${encodeURIComponent(token)}`,\n {\n method: 'POST',\n headers: {\n 'x-authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ worker_id: workerId }),\n }\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`API error ${response.status}: ${errorText}`);\n }\n\n const result = await response.json();\n\n if (!result.success) {\n throw new Error(result.error || 'API returned unsuccessful response');\n }\n\n // API returns null when no work is available\n return result.data;\n }\n\n async releaseClaim(params: { action_id: string; worker_id: string; claim_id: string }): Promise<void> {\n const token = await this.getAuthToken();\n\n const response = await fetchWithRetry(\n `${this.baseUrl}/api/worker/release?token=${encodeURIComponent(token)}`,\n {\n method: 'POST',\n headers: {\n 'x-authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(params),\n }\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`API error ${response.status}: ${errorText}`);\n }\n\n const result = await response.json();\n\n if (!result.success) {\n throw new Error(result.error || 'API returned unsuccessful response');\n }\n }\n}\n","import { spawn } from 'child_process';\nimport { mkdtemp, rm } from 'fs/promises';\nimport { tmpdir } from 'os';\nimport { join } from 'path';\nimport { fetchWithRetry } from './fetch-with-retry.js';\nimport type { GitHubCredentials } from './types/actions.js';\n\nconst API_BASE_URL = 'https://www.contextgraph.dev';\n\nexport interface WorkspaceResult {\n path: string;\n cleanup: () => Promise<void>;\n}\n\nexport interface PrepareWorkspaceOptions {\n branch?: string;\n authToken: string;\n}\n\nasync function fetchGitHubCredentials(authToken: string): Promise<GitHubCredentials> {\n const response = await fetchWithRetry(`${API_BASE_URL}/api/cli/credentials`, {\n headers: {\n 'x-authorization': `Bearer ${authToken}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (response.status === 401) {\n throw new Error('Authentication failed. Please re-authenticate.');\n }\n\n if (response.status === 404) {\n throw new Error(\n 'GitHub not connected. Please connect your GitHub account at https://contextgraph.dev/settings.'\n );\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Failed to fetch GitHub credentials: ${response.statusText}\\n${errorText}`);\n }\n\n return response.json() as Promise<GitHubCredentials>;\n}\n\nfunction runGitCommand(args: string[], cwd?: string): Promise<{ stdout: string; stderr: string }> {\n return new Promise((resolve, reject) => {\n const proc = spawn('git', args, { cwd });\n let stdout = '';\n let stderr = '';\n\n proc.stdout.on('data', (data) => {\n stdout += data.toString();\n });\n\n proc.stderr.on('data', (data) => {\n stderr += data.toString();\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n resolve({ stdout, stderr });\n } else {\n reject(new Error(`git ${args[0]} failed (exit ${code}): ${stderr || stdout}`));\n }\n });\n\n proc.on('error', (err) => {\n reject(new Error(`Failed to spawn git: ${err.message}`));\n });\n });\n}\n\nfunction buildAuthenticatedUrl(repoUrl: string, token: string): string {\n // Handle https://github.com/... URLs\n if (repoUrl.startsWith('https://github.com/')) {\n return repoUrl.replace('https://github.com/', `https://${token}@github.com/`);\n }\n\n // Handle https://github.com URLs without trailing slash\n if (repoUrl.startsWith('https://github.com')) {\n return repoUrl.replace('https://github.com', `https://${token}@github.com`);\n }\n\n // For other URLs, return as-is (might be SSH or other provider)\n return repoUrl;\n}\n\nexport async function prepareWorkspace(\n repoUrl: string,\n options: PrepareWorkspaceOptions\n): Promise<WorkspaceResult> {\n const { branch, authToken } = options;\n\n // Fetch GitHub credentials\n const credentials = await fetchGitHubCredentials(authToken);\n\n // Create temp directory\n const workspacePath = await mkdtemp(join(tmpdir(), 'cg-workspace-'));\n\n const cleanup = async () => {\n try {\n await rm(workspacePath, { recursive: true, force: true });\n } catch (error) {\n console.error(`Warning: Failed to cleanup workspace at ${workspacePath}:`, error);\n }\n };\n\n try {\n // Build authenticated clone URL\n const cloneUrl = buildAuthenticatedUrl(repoUrl, credentials.githubToken);\n\n // Clone the repository\n console.log(`📂 Cloning ${repoUrl}`);\n console.log(` → ${workspacePath}`);\n await runGitCommand(['clone', cloneUrl, workspacePath]);\n console.log(`✅ Repository cloned`);\n\n // Configure git identity if we have the info\n if (credentials.githubUsername) {\n await runGitCommand(['config', 'user.name', credentials.githubUsername], workspacePath);\n }\n if (credentials.githubEmail) {\n await runGitCommand(['config', 'user.email', credentials.githubEmail], workspacePath);\n }\n\n // Handle branch checkout if specified\n if (branch) {\n // Check if branch exists remotely\n const { stdout } = await runGitCommand(\n ['ls-remote', '--heads', 'origin', branch],\n workspacePath\n );\n\n const branchExists = stdout.trim().length > 0;\n\n if (branchExists) {\n // Checkout existing branch\n console.log(`🌿 Checking out branch: ${branch}`);\n await runGitCommand(['checkout', branch], workspacePath);\n } else {\n // Create new branch\n console.log(`🌱 Creating new branch: ${branch}`);\n await runGitCommand(['checkout', '-b', branch], workspacePath);\n }\n }\n\n return { path: workspacePath, cleanup };\n } catch (error) {\n // Cleanup on failure\n await cleanup();\n throw error;\n }\n}\n"],"mappings":"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","names":["readFileSync","fileURLToPath","dirname","join","path","API_BASE_URL","join","spawn","join","API_BASE_URL","spawn","join","__filename","__dirname","join","__filename","fileURLToPath","__dirname","dirname","packageJson","readFileSync","join"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contextgraph/agent",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Autonomous agent for contextgraph action execution",
5
5
  "type": "module",
6
6
  "bin": {