cyrus-edge-worker 0.0.19 → 0.0.20

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.
@@ -1,6 +1,6 @@
1
- import { LinearClient } from '@linear/sdk';
2
- import type { SDKMessage, SDKSystemMessage, SDKResultMessage, ClaudeRunner } from 'cyrus-claude-runner';
3
- import type { CyrusAgentSession, CyrusAgentSessionEntry, IssueMinimal, SerializedCyrusAgentSession, SerializedCyrusAgentSessionEntry, Workspace } from 'cyrus-core';
1
+ import { type LinearClient } from "@linear/sdk";
2
+ import type { ClaudeRunner, SDKMessage, SDKResultMessage, SDKSystemMessage } from "cyrus-claude-runner";
3
+ import type { CyrusAgentSession, CyrusAgentSessionEntry, IssueMinimal, SerializedCyrusAgentSession, SerializedCyrusAgentSessionEntry, Workspace } from "cyrus-core";
4
4
  /**
5
5
  * Manages Linear Agent Sessions integration with Claude Code SDK
6
6
  * Transforms Claude streaming messages into Agent Session format
@@ -1 +1 @@
1
- {"version":3,"file":"AgentSessionManager.d.ts","sourceRoot":"","sources":["../src/AgentSessionManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AgentSessionManager.d.ts","sourceRoot":"","sources":["../src/AgentSessionManager.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { LinearDocument } from '@linear/sdk';
1
+ import { LinearDocument } from "@linear/sdk";
2
2
  /**
3
3
  * Manages Linear Agent Sessions integration with Claude Code SDK
4
4
  * Transforms Claude streaming messages into Agent Session format
@@ -29,7 +29,7 @@ export class AgentSessionManager {
29
29
  updatedAt: Date.now(),
30
30
  issueId,
31
31
  issue: issueMinimal,
32
- workspace: workspace
32
+ workspace: workspace,
33
33
  };
34
34
  // Store locally
35
35
  this.sessions.set(linearAgentActivitySessionId, agentSession);
@@ -59,9 +59,9 @@ export class AgentSessionManager {
59
59
  */
60
60
  async createSessionEntry(_linearAgentActivitySessionId, sdkMessage) {
61
61
  // Extract tool info if this is an assistant message
62
- const toolInfo = sdkMessage.type === 'assistant' ? this.extractToolInfo(sdkMessage) : null;
62
+ const toolInfo = sdkMessage.type === "assistant" ? this.extractToolInfo(sdkMessage) : null;
63
63
  // Extract tool_use_id if this is a user message with tool_result
64
- const toolResultId = sdkMessage.type === 'user' ? this.extractToolResultId(sdkMessage) : null;
64
+ const toolResultId = sdkMessage.type === "user" ? this.extractToolResultId(sdkMessage) : null;
65
65
  const sessionEntry = {
66
66
  claudeSessionId: sdkMessage.session_id,
67
67
  type: sdkMessage.type,
@@ -72,12 +72,12 @@ export class AgentSessionManager {
72
72
  ...(toolInfo && {
73
73
  toolUseId: toolInfo.id,
74
74
  toolName: toolInfo.name,
75
- toolInput: toolInfo.input
75
+ toolInput: toolInfo.input,
76
76
  }),
77
77
  ...(toolResultId && {
78
- toolUseId: toolResultId
79
- })
80
- }
78
+ toolUseId: toolResultId,
79
+ }),
80
+ },
81
81
  };
82
82
  // DON'T store locally yet - wait until we actually post to Linear
83
83
  return sessionEntry;
@@ -93,27 +93,27 @@ export class AgentSessionManager {
93
93
  }
94
94
  const todos = data.todos;
95
95
  // Keep original order but add status indicators
96
- let formatted = '\n';
96
+ let formatted = "\n";
97
97
  todos.forEach((todo, index) => {
98
- let statusEmoji = '';
99
- if (todo.status === 'completed') {
100
- statusEmoji = '';
98
+ let statusEmoji = "";
99
+ if (todo.status === "completed") {
100
+ statusEmoji = "";
101
101
  }
102
- else if (todo.status === 'in_progress') {
103
- statusEmoji = '🔄 ';
102
+ else if (todo.status === "in_progress") {
103
+ statusEmoji = "🔄 ";
104
104
  }
105
- else if (todo.status === 'pending') {
106
- statusEmoji = '';
105
+ else if (todo.status === "pending") {
106
+ statusEmoji = "";
107
107
  }
108
108
  formatted += `${statusEmoji}${todo.content}`;
109
109
  if (index < todos.length - 1) {
110
- formatted += '\n';
110
+ formatted += "\n";
111
111
  }
112
112
  });
113
113
  return formatted;
114
114
  }
115
115
  catch (error) {
116
- console.error('[AgentSessionManager] Failed to format TodoWrite parameter:', error);
116
+ console.error("[AgentSessionManager] Failed to format TodoWrite parameter:", error);
117
117
  return jsonContent;
118
118
  }
119
119
  }
@@ -128,16 +128,16 @@ export class AgentSessionManager {
128
128
  }
129
129
  // Clear any active Task when session completes
130
130
  this.activeTasksBySession.delete(linearAgentActivitySessionId);
131
- const status = resultMessage.subtype === 'success'
131
+ const status = resultMessage.subtype === "success"
132
132
  ? LinearDocument.AgentSessionStatus.Complete
133
133
  : LinearDocument.AgentSessionStatus.Error;
134
134
  // Update session status and metadata
135
135
  await this.updateSessionStatus(linearAgentActivitySessionId, status, {
136
136
  totalCostUsd: resultMessage.total_cost_usd,
137
- usage: resultMessage.usage
137
+ usage: resultMessage.usage,
138
138
  });
139
139
  // Add result entry if present
140
- if ('result' in resultMessage && resultMessage.result) {
140
+ if ("result" in resultMessage && resultMessage.result) {
141
141
  await this.addResultEntry(linearAgentActivitySessionId, resultMessage);
142
142
  }
143
143
  }
@@ -147,8 +147,8 @@ export class AgentSessionManager {
147
147
  async handleClaudeMessage(linearAgentActivitySessionId, message) {
148
148
  try {
149
149
  switch (message.type) {
150
- case 'system':
151
- if (message.subtype === 'init') {
150
+ case "system":
151
+ if (message.subtype === "init") {
152
152
  this.updateAgentSessionWithClaudeSessionId(linearAgentActivitySessionId, message);
153
153
  // Post model notification thought
154
154
  const systemMessage = message;
@@ -157,15 +157,17 @@ export class AgentSessionManager {
157
157
  }
158
158
  }
159
159
  break;
160
- case 'user':
160
+ case "user": {
161
161
  const userEntry = await this.createSessionEntry(linearAgentActivitySessionId, message);
162
162
  await this.syncEntryToLinear(userEntry, linearAgentActivitySessionId);
163
163
  break;
164
- case 'assistant':
164
+ }
165
+ case "assistant": {
165
166
  const assistantEntry = await this.createSessionEntry(linearAgentActivitySessionId, message);
166
167
  await this.syncEntryToLinear(assistantEntry, linearAgentActivitySessionId);
167
168
  break;
168
- case 'result':
169
+ }
170
+ case "result":
169
171
  await this.completeSession(linearAgentActivitySessionId, message);
170
172
  break;
171
173
  default:
@@ -198,12 +200,12 @@ export class AgentSessionManager {
198
200
  async addResultEntry(linearAgentActivitySessionId, resultMessage) {
199
201
  const resultEntry = {
200
202
  claudeSessionId: resultMessage.session_id,
201
- type: 'result',
202
- content: 'result' in resultMessage ? resultMessage.result : '',
203
+ type: "result",
204
+ content: "result" in resultMessage ? resultMessage.result : "",
203
205
  metadata: {
204
206
  timestamp: Date.now(),
205
207
  durationMs: resultMessage.duration_ms,
206
- isError: resultMessage.is_error
208
+ isError: resultMessage.is_error,
207
209
  },
208
210
  };
209
211
  // DON'T store locally - syncEntryToLinear will do it
@@ -214,38 +216,38 @@ export class AgentSessionManager {
214
216
  * Extract content from Claude message
215
217
  */
216
218
  extractContent(sdkMessage) {
217
- const message = sdkMessage.type === 'user'
219
+ const message = sdkMessage.type === "user"
218
220
  ? sdkMessage.message
219
221
  : sdkMessage.message;
220
- if (typeof message.content === 'string') {
222
+ if (typeof message.content === "string") {
221
223
  return message.content;
222
224
  }
223
225
  if (Array.isArray(message.content)) {
224
226
  return message.content
225
227
  .map((block) => {
226
- if (block.type === 'text') {
228
+ if (block.type === "text") {
227
229
  return block.text;
228
230
  }
229
- else if (block.type === 'tool_use') {
231
+ else if (block.type === "tool_use") {
230
232
  // For tool use blocks, return the input as JSON string
231
233
  return JSON.stringify(block.input, null, 2);
232
234
  }
233
- else if (block.type === 'tool_result') {
235
+ else if (block.type === "tool_result") {
234
236
  // For tool_result blocks, extract just the text content
235
237
  if (Array.isArray(block.content)) {
236
238
  return block.content
237
- .filter((contentBlock) => contentBlock.type === 'text')
239
+ .filter((contentBlock) => contentBlock.type === "text")
238
240
  .map((contentBlock) => contentBlock.text)
239
- .join('\n');
241
+ .join("\n");
240
242
  }
241
- return '';
243
+ return "";
242
244
  }
243
- return '';
245
+ return "";
244
246
  })
245
247
  .filter(Boolean)
246
- .join('\n');
248
+ .join("\n");
247
249
  }
248
- return '';
250
+ return "";
249
251
  }
250
252
  /**
251
253
  * Extract tool information from Claude assistant message
@@ -253,12 +255,15 @@ export class AgentSessionManager {
253
255
  extractToolInfo(sdkMessage) {
254
256
  const message = sdkMessage.message;
255
257
  if (Array.isArray(message.content)) {
256
- const toolUse = message.content.find((block) => block.type === 'tool_use');
257
- if (toolUse && 'id' in toolUse && 'name' in toolUse && 'input' in toolUse) {
258
+ const toolUse = message.content.find((block) => block.type === "tool_use");
259
+ if (toolUse &&
260
+ "id" in toolUse &&
261
+ "name" in toolUse &&
262
+ "input" in toolUse) {
258
263
  return {
259
264
  id: toolUse.id,
260
265
  name: toolUse.name,
261
- input: toolUse.input
266
+ input: toolUse.input,
262
267
  };
263
268
  }
264
269
  }
@@ -270,8 +275,8 @@ export class AgentSessionManager {
270
275
  extractToolResultId(sdkMessage) {
271
276
  const message = sdkMessage.message;
272
277
  if (Array.isArray(message.content)) {
273
- const toolResult = message.content.find((block) => block.type === 'tool_result');
274
- if (toolResult && 'tool_use_id' in toolResult) {
278
+ const toolResult = message.content.find((block) => block.type === "tool_result");
279
+ if (toolResult && "tool_use_id" in toolResult) {
275
280
  return toolResult.tool_use_id;
276
281
  }
277
282
  }
@@ -294,12 +299,12 @@ export class AgentSessionManager {
294
299
  // Build activity content based on entry type
295
300
  let content;
296
301
  switch (entry.type) {
297
- case 'user':
302
+ case "user": {
298
303
  const activeTaskId = this.activeTasksBySession.get(linearAgentActivitySessionId);
299
304
  if (activeTaskId && activeTaskId === entry.metadata?.toolUseId) {
300
305
  content = {
301
- type: 'thought',
302
- body: `✅ Task Completed\n\n\n\n${entry.content}\n\n---\n\n`
306
+ type: "thought",
307
+ body: `✅ Task Completed\n\n\n\n${entry.content}\n\n---\n\n`,
303
308
  };
304
309
  this.activeTasksBySession.delete(linearAgentActivitySessionId);
305
310
  }
@@ -309,28 +314,29 @@ export class AgentSessionManager {
309
314
  return;
310
315
  }
311
316
  break;
312
- case 'assistant':
317
+ }
318
+ case "assistant":
313
319
  // Assistant messages can be thoughts or responses
314
320
  if (entry.metadata?.toolUseId) {
315
- const toolName = entry.metadata.toolName || 'Tool';
321
+ const toolName = entry.metadata.toolName || "Tool";
316
322
  // Special handling for TodoWrite tool - treat as thought instead of action
317
- if (toolName === 'TodoWrite') {
323
+ if (toolName === "TodoWrite") {
318
324
  const formattedTodos = this.formatTodoWriteParameter(entry.content);
319
325
  content = {
320
- type: 'thought',
321
- body: formattedTodos
326
+ type: "thought",
327
+ body: formattedTodos,
322
328
  };
323
329
  }
324
- else if (toolName === 'Task') {
330
+ else if (toolName === "Task") {
325
331
  // Special handling for Task tool - add start marker and track active task
326
- let parameter = entry.content;
327
- let displayName = toolName;
332
+ const parameter = entry.content;
333
+ const displayName = toolName;
328
334
  // Track this as the active Task for this session
329
335
  if (entry.metadata?.toolUseId) {
330
336
  this.activeTasksBySession.set(linearAgentActivitySessionId, entry.metadata.toolUseId);
331
337
  }
332
338
  content = {
333
- type: 'action',
339
+ type: "action",
334
340
  action: displayName,
335
341
  parameter: parameter,
336
342
  // result will be added later when we get tool result
@@ -338,7 +344,7 @@ export class AgentSessionManager {
338
344
  }
339
345
  else {
340
346
  // Other tools - check if they're within an active Task
341
- let parameter = entry.content;
347
+ const parameter = entry.content;
342
348
  let displayName = toolName;
343
349
  if (entry.metadata?.parentToolUseId) {
344
350
  const activeTaskId = this.activeTasksBySession.get(linearAgentActivitySessionId);
@@ -347,7 +353,7 @@ export class AgentSessionManager {
347
353
  }
348
354
  }
349
355
  content = {
350
- type: 'action',
356
+ type: "action",
351
357
  action: displayName,
352
358
  parameter: parameter,
353
359
  // result will be added later when we get tool result
@@ -357,50 +363,52 @@ export class AgentSessionManager {
357
363
  else {
358
364
  // Regular assistant message - create a thought
359
365
  // Check if this message contains the last message marker
360
- if (entry.content.includes('___LAST_MESSAGE_MARKER___')) {
366
+ if (entry.content.includes("___LAST_MESSAGE_MARKER___")) {
361
367
  console.log(`[AgentSessionManager] Skipping assistant message with last message marker - will be posted as response later`);
362
368
  return; // Skip posting this as a thought
363
369
  }
364
370
  content = {
365
- type: 'thought',
366
- body: entry.content
371
+ type: "thought",
372
+ body: entry.content,
367
373
  };
368
374
  }
369
375
  break;
370
- case 'system':
376
+ case "system":
371
377
  // System messages are thoughts
372
378
  content = {
373
- type: 'thought',
374
- body: entry.content
379
+ type: "thought",
380
+ body: entry.content,
375
381
  };
376
382
  break;
377
- case 'result':
383
+ case "result":
378
384
  // Result messages can be responses or errors
379
385
  if (entry.metadata?.isError) {
380
386
  content = {
381
- type: 'error',
382
- body: entry.content
387
+ type: "error",
388
+ body: entry.content,
383
389
  };
384
390
  }
385
391
  else {
386
392
  // Strip the last message marker from the response
387
- const cleanedContent = entry.content.replace(/___LAST_MESSAGE_MARKER___/g, '').trim();
393
+ const cleanedContent = entry.content
394
+ .replace(/___LAST_MESSAGE_MARKER___/g, "")
395
+ .trim();
388
396
  content = {
389
- type: 'response',
390
- body: cleanedContent
397
+ type: "response",
398
+ body: cleanedContent,
391
399
  };
392
400
  }
393
401
  break;
394
402
  default:
395
403
  // Default to thought
396
404
  content = {
397
- type: 'thought',
398
- body: entry.content
405
+ type: "thought",
406
+ body: entry.content,
399
407
  };
400
408
  }
401
409
  const activityInput = {
402
410
  agentSessionId: session.linearAgentActivitySessionId, // Use the Linear session ID
403
- content
411
+ content,
404
412
  };
405
413
  const result = await this.linearClient.createAgentActivity(activityInput);
406
414
  if (result.success && result.agentActivity) {
@@ -432,7 +440,7 @@ export class AgentSessionManager {
432
440
  * Get all active sessions
433
441
  */
434
442
  getActiveSessions() {
435
- return Array.from(this.sessions.values()).filter(session => session.status === LinearDocument.AgentSessionStatus.Active);
443
+ return Array.from(this.sessions.values()).filter((session) => session.status === LinearDocument.AgentSessionStatus.Active);
436
444
  }
437
445
  /**
438
446
  * Add or update ClaudeRunner for a session
@@ -452,7 +460,7 @@ export class AgentSessionManager {
452
460
  */
453
461
  getAllClaudeRunners() {
454
462
  return Array.from(this.sessions.values())
455
- .map(session => session.claudeRunner)
463
+ .map((session) => session.claudeRunner)
456
464
  .filter((runner) => runner !== undefined);
457
465
  }
458
466
  /**
@@ -460,21 +468,22 @@ export class AgentSessionManager {
460
468
  */
461
469
  getClaudeRunnersForIssue(issueId) {
462
470
  return Array.from(this.sessions.values())
463
- .filter(session => session.issueId === issueId)
464
- .map(session => session.claudeRunner)
471
+ .filter((session) => session.issueId === issueId)
472
+ .map((session) => session.claudeRunner)
465
473
  .filter((runner) => runner !== undefined);
466
474
  }
467
475
  /**
468
476
  * Get sessions by issue ID
469
477
  */
470
478
  getSessionsByIssueId(issueId) {
471
- return Array.from(this.sessions.values()).filter(session => session.issueId === issueId);
479
+ return Array.from(this.sessions.values()).filter((session) => session.issueId === issueId);
472
480
  }
473
481
  /**
474
482
  * Get active sessions by issue ID
475
483
  */
476
484
  getActiveSessionsByIssueId(issueId) {
477
- return Array.from(this.sessions.values()).filter(session => session.issueId === issueId && session.status === LinearDocument.AgentSessionStatus.Active);
485
+ return Array.from(this.sessions.values()).filter((session) => session.issueId === issueId &&
486
+ session.status === LinearDocument.AgentSessionStatus.Active);
478
487
  }
479
488
  /**
480
489
  * Get all sessions
@@ -495,9 +504,9 @@ export class AgentSessionManager {
495
504
  const result = await this.linearClient.createAgentActivity({
496
505
  agentSessionId: session.linearAgentActivitySessionId,
497
506
  content: {
498
- type: 'thought',
499
- body
500
- }
507
+ type: "thought",
508
+ body,
509
+ },
501
510
  });
502
511
  if (result.success) {
503
512
  console.log(`[AgentSessionManager] Created thought activity for session ${sessionId}`);
@@ -521,16 +530,16 @@ export class AgentSessionManager {
521
530
  }
522
531
  try {
523
532
  const content = {
524
- type: 'action',
533
+ type: "action",
525
534
  action,
526
- parameter
535
+ parameter,
527
536
  };
528
537
  if (result !== undefined) {
529
538
  content.result = result;
530
539
  }
531
540
  const response = await this.linearClient.createAgentActivity({
532
541
  agentSessionId: session.linearAgentActivitySessionId,
533
- content
542
+ content,
534
543
  });
535
544
  if (response.success) {
536
545
  console.log(`[AgentSessionManager] Created action activity for session ${sessionId}`);
@@ -556,9 +565,9 @@ export class AgentSessionManager {
556
565
  const result = await this.linearClient.createAgentActivity({
557
566
  agentSessionId: session.linearAgentActivitySessionId,
558
567
  content: {
559
- type: 'response',
560
- body
561
- }
568
+ type: "response",
569
+ body,
570
+ },
562
571
  });
563
572
  if (result.success) {
564
573
  console.log(`[AgentSessionManager] Created response activity for session ${sessionId}`);
@@ -584,9 +593,9 @@ export class AgentSessionManager {
584
593
  const result = await this.linearClient.createAgentActivity({
585
594
  agentSessionId: session.linearAgentActivitySessionId,
586
595
  content: {
587
- type: 'error',
588
- body
589
- }
596
+ type: "error",
597
+ body,
598
+ },
590
599
  });
591
600
  if (result.success) {
592
601
  console.log(`[AgentSessionManager] Created error activity for session ${sessionId}`);
@@ -612,9 +621,9 @@ export class AgentSessionManager {
612
621
  const result = await this.linearClient.createAgentActivity({
613
622
  agentSessionId: session.linearAgentActivitySessionId,
614
623
  content: {
615
- type: 'elicitation',
616
- body
617
- }
624
+ type: "elicitation",
625
+ body,
626
+ },
618
627
  });
619
628
  if (result.success) {
620
629
  console.log(`[AgentSessionManager] Created elicitation activity for session ${sessionId}`);
@@ -633,7 +642,7 @@ export class AgentSessionManager {
633
642
  cleanup(olderThanMs = 24 * 60 * 60 * 1000) {
634
643
  const cutoff = Date.now() - olderThanMs;
635
644
  for (const [sessionId, session] of this.sessions.entries()) {
636
- if ((session.status === 'complete' || session.status === 'error') &&
645
+ if ((session.status === "complete" || session.status === "error") &&
637
646
  session.updatedAt < cutoff) {
638
647
  this.sessions.delete(sessionId);
639
648
  this.entries.delete(sessionId);
@@ -650,12 +659,12 @@ export class AgentSessionManager {
650
659
  // Serialize sessions
651
660
  for (const [sessionId, session] of this.sessions.entries()) {
652
661
  // Exclude claudeRunner from serialization as it's not serializable
653
- const { claudeRunner, ...serializableSession } = session;
662
+ const { claudeRunner: _claudeRunner, ...serializableSession } = session;
654
663
  sessions[sessionId] = serializableSession;
655
664
  }
656
665
  // Serialize entries
657
666
  for (const [sessionId, sessionEntries] of this.entries.entries()) {
658
- entries[sessionId] = sessionEntries.map(entry => ({
667
+ entries[sessionId] = sessionEntries.map((entry) => ({
659
668
  ...entry,
660
669
  }));
661
670
  }
@@ -677,7 +686,7 @@ export class AgentSessionManager {
677
686
  }
678
687
  // Restore entries
679
688
  for (const [sessionId, entriesData] of Object.entries(serializedEntries)) {
680
- const sessionEntries = entriesData.map(entryData => ({
689
+ const sessionEntries = entriesData.map((entryData) => ({
681
690
  ...entryData,
682
691
  }));
683
692
  this.entries.set(sessionId, sessionEntries);
@@ -692,9 +701,9 @@ export class AgentSessionManager {
692
701
  const result = await this.linearClient.createAgentActivity({
693
702
  agentSessionId: linearAgentActivitySessionId,
694
703
  content: {
695
- type: 'thought',
696
- body: `Using model: ${model}`
697
- }
704
+ type: "thought",
705
+ body: `Using model: ${model}`,
706
+ },
698
707
  });
699
708
  if (result.success) {
700
709
  console.log(`[AgentSessionManager] Posted model notification for session ${linearAgentActivitySessionId} (model: ${model})`);