cyrus-edge-worker 0.2.0 → 0.2.2

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.
@@ -16,6 +16,7 @@ export declare class AgentSessionManager {
16
16
  private entries;
17
17
  private activeTasksBySession;
18
18
  private toolCallsByToolUseId;
19
+ private activeStatusActivitiesBySession;
19
20
  private procedureRouter?;
20
21
  private sharedApplicationServer?;
21
22
  private getParentSessionId?;
@@ -39,6 +40,21 @@ export declare class AgentSessionManager {
39
40
  * Format TodoWrite tool parameter as a nice checklist
40
41
  */
41
42
  private formatTodoWriteParameter;
43
+ /**
44
+ * Format tool input for display in Linear agent activities
45
+ * Converts raw tool inputs into user-friendly parameter strings
46
+ */
47
+ private formatToolParameter;
48
+ /**
49
+ * Format tool action name with description for Bash tool
50
+ * Puts the description in round brackets after the tool name in the action field
51
+ */
52
+ private formatToolActionName;
53
+ /**
54
+ * Format tool result for display in Linear agent activities
55
+ * Converts raw tool results into formatted Markdown
56
+ */
57
+ private formatToolResult;
42
58
  /**
43
59
  * Complete a session from Claude result message
44
60
  */
@@ -178,5 +194,9 @@ export declare class AgentSessionManager {
178
194
  * Post the procedure selection result as a non-ephemeral thought
179
195
  */
180
196
  postProcedureSelectionThought(linearAgentActivitySessionId: string, procedureName: string, classification: string): Promise<void>;
197
+ /**
198
+ * Handle status messages (compacting, etc.)
199
+ */
200
+ private handleStatusMessage;
181
201
  }
182
202
  //# sourceMappingURL=AgentSessionManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AgentSessionManager.d.ts","sourceRoot":"","sources":["../src/AgentSessionManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAkB,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAGX,YAAY,EAEZ,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAEhB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EACX,iBAAiB,EACjB,sBAAsB,EACtB,YAAY,EACZ,2BAA2B,EAC3B,gCAAgC,EAChC,SAAS,EACT,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAE5E;;;;;;GAMG;AACH,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,QAAQ,CAA6C;IAC7D,OAAO,CAAC,OAAO,CAAoD;IACnE,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,OAAO,CAAC,oBAAoB,CACjB;IACX,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,OAAO,CAAC,uBAAuB,CAAC,CAA0B;IAC1D,OAAO,CAAC,kBAAkB,CAAC,CAAiD;IAC5E,OAAO,CAAC,mBAAmB,CAAC,CAIT;IACnB,OAAO,CAAC,oBAAoB,CAAC,CAEV;gBAGlB,YAAY,EAAE,YAAY,EAC1B,kBAAkB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,EACnE,mBAAmB,CAAC,EAAE,CACrB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,KAClB,OAAO,CAAC,IAAI,CAAC,EAClB,oBAAoB,CAAC,EAAE,CACtB,4BAA4B,EAAE,MAAM,KAChC,OAAO,CAAC,IAAI,CAAC,EAClB,eAAe,CAAC,EAAE,eAAe,EACjC,uBAAuB,CAAC,EAAE,uBAAuB;IAUlD;;;OAGG;IACH,wBAAwB,CACvB,4BAA4B,EAAE,MAAM,EACpC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,SAAS,GAClB,iBAAiB;IAwBpB;;OAEG;IACH,qCAAqC,CACpC,4BAA4B,EAAE,MAAM,EACpC,mBAAmB,EAAE,gBAAgB,GACnC,IAAI;IAmBP;;OAEG;YACW,kBAAkB;IAoChC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA2ChC;;OAEG;IACG,eAAe,CACpB,4BAA4B,EAAE,MAAM,EACpC,aAAa,EAAE,gBAAgB,GAC7B,OAAO,CAAC,IAAI,CAAC;IAqChB;;OAEG;YACW,yBAAyB;IA+KvC;;OAEG;YACW,4BAA4B;IA+C1C;;OAEG;IACG,mBAAmB,CACxB,4BAA4B,EAAE,MAAM,EACpC,OAAO,EAAE,UAAU,GACjB,OAAO,CAAC,IAAI,CAAC;IAgEhB;;OAEG;YACW,mBAAmB;IAkBjC;;OAEG;YACW,cAAc;IAoB5B;;OAEG;IACH,OAAO,CAAC,cAAc;IA8CtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAyBvB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAmB7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAYzB;;OAEG;YACW,iBAAiB;IA8O/B;;OAEG;IACH,UAAU,CACT,4BAA4B,EAAE,MAAM,GAClC,iBAAiB,GAAG,SAAS;IAIhC;;OAEG;IACH,iBAAiB,CAChB,4BAA4B,EAAE,MAAM,GAClC,sBAAsB,EAAE;IAI3B;;OAEG;IACH,iBAAiB,IAAI,iBAAiB,EAAE;IAMxC;;OAEG;IACH,eAAe,CACd,4BAA4B,EAAE,MAAM,EACpC,YAAY,EAAE,YAAY,GACxB,IAAI;IAgBP;;OAEG;IACH,mBAAmB,IAAI,YAAY,EAAE;IAMrC;;OAEG;IACH,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE;IAOzD;;OAEG;IACH,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,EAAE;IAM1D;;OAEG;IACH,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,EAAE;IAQhE;;OAEG;IACH,cAAc,IAAI,iBAAiB,EAAE;IAIrC;;OAEG;IACH,eAAe,CACd,4BAA4B,EAAE,MAAM,GAClC,YAAY,GAAG,SAAS;IAK3B;;OAEG;IACH,eAAe,CAAC,4BAA4B,EAAE,MAAM,GAAG,OAAO;IAK9D;;OAEG;IACG,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoC3E;;OAEG;IACG,oBAAoB,CACzB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IA2ChB;;OAEG;IACG,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoC5E;;OAEG;IACG,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCzE;;OAEG;IACG,yBAAyB,CAC9B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACV,OAAO,CAAC,IAAI,CAAC;IAoChB;;OAEG;IACG,yBAAyB,CAC9B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAwChB;;OAEG;IACH,OAAO,CAAC,WAAW,GAAE,MAA4B,GAAG,IAAI;IAexD;;OAEG;IACH,cAAc,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;QACtD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gCAAgC,EAAE,CAAC,CAAC;KAC5D;IAqBD;;OAEG;IACH,YAAY,CACX,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC,EAC/D,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,gCAAgC,EAAE,CAAC,GACnE,IAAI;IA4BP;;OAEG;YACW,4BAA4B;IA+B1C;;OAEG;IACG,kBAAkB,CACvB,4BAA4B,EAAE,MAAM,GAClC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAiCzB;;OAEG;IACG,6BAA6B,CAClC,4BAA4B,EAAE,MAAM,EACpC,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC;CA4BhB"}
1
+ {"version":3,"file":"AgentSessionManager.d.ts","sourceRoot":"","sources":["../src/AgentSessionManager.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,7 @@ export class AgentSessionManager {
12
12
  entries = new Map(); // Stores a list of session entries per each session by its linearAgentActivitySessionId
13
13
  activeTasksBySession = new Map(); // Maps session ID to active Task tool use ID
14
14
  toolCallsByToolUseId = new Map(); // Track tool calls by their tool_use_id
15
+ activeStatusActivitiesBySession = new Map(); // Maps session ID to active compacting status activity ID
15
16
  procedureRouter;
16
17
  sharedApplicationServer;
17
18
  getParentSessionId;
@@ -132,6 +133,317 @@ export class AgentSessionManager {
132
133
  return jsonContent;
133
134
  }
134
135
  }
136
+ /**
137
+ * Format tool input for display in Linear agent activities
138
+ * Converts raw tool inputs into user-friendly parameter strings
139
+ */
140
+ formatToolParameter(toolName, toolInput) {
141
+ // If input is already a string, return it
142
+ if (typeof toolInput === "string") {
143
+ return toolInput;
144
+ }
145
+ try {
146
+ switch (toolName) {
147
+ case "Bash":
148
+ case "↪ Bash": {
149
+ // Show command only - description goes in action field via formatToolActionName
150
+ return toolInput.command || JSON.stringify(toolInput);
151
+ }
152
+ case "Read":
153
+ case "↪ Read":
154
+ if (toolInput.file_path) {
155
+ let param = toolInput.file_path;
156
+ if (toolInput.offset !== undefined ||
157
+ toolInput.limit !== undefined) {
158
+ const start = toolInput.offset || 0;
159
+ const end = toolInput.limit ? start + toolInput.limit : "end";
160
+ param += ` (lines ${start + 1}-${end})`;
161
+ }
162
+ return param;
163
+ }
164
+ break;
165
+ case "Edit":
166
+ case "↪ Edit":
167
+ if (toolInput.file_path) {
168
+ return toolInput.file_path;
169
+ }
170
+ break;
171
+ case "Write":
172
+ case "↪ Write":
173
+ if (toolInput.file_path) {
174
+ return toolInput.file_path;
175
+ }
176
+ break;
177
+ case "Grep":
178
+ case "↪ Grep":
179
+ if (toolInput.pattern) {
180
+ let param = `Pattern: \`${toolInput.pattern}\``;
181
+ if (toolInput.path) {
182
+ param += ` in ${toolInput.path}`;
183
+ }
184
+ if (toolInput.glob) {
185
+ param += ` (${toolInput.glob})`;
186
+ }
187
+ if (toolInput.type) {
188
+ param += ` [${toolInput.type} files]`;
189
+ }
190
+ return param;
191
+ }
192
+ break;
193
+ case "Glob":
194
+ case "↪ Glob":
195
+ if (toolInput.pattern) {
196
+ let param = `Pattern: \`${toolInput.pattern}\``;
197
+ if (toolInput.path) {
198
+ param += ` in ${toolInput.path}`;
199
+ }
200
+ return param;
201
+ }
202
+ break;
203
+ case "Task":
204
+ case "↪ Task":
205
+ if (toolInput.description) {
206
+ return toolInput.description;
207
+ }
208
+ break;
209
+ case "WebFetch":
210
+ case "↪ WebFetch":
211
+ if (toolInput.url) {
212
+ return toolInput.url;
213
+ }
214
+ break;
215
+ case "WebSearch":
216
+ case "↪ WebSearch":
217
+ if (toolInput.query) {
218
+ return `Query: ${toolInput.query}`;
219
+ }
220
+ break;
221
+ case "NotebookEdit":
222
+ case "↪ NotebookEdit":
223
+ if (toolInput.notebook_path) {
224
+ let param = toolInput.notebook_path;
225
+ if (toolInput.cell_id) {
226
+ param += ` (cell ${toolInput.cell_id})`;
227
+ }
228
+ return param;
229
+ }
230
+ break;
231
+ default:
232
+ // For MCP tools or other unknown tools, try to extract meaningful info
233
+ if (toolName.startsWith("mcp__")) {
234
+ // Extract key fields that are commonly meaningful
235
+ const meaningfulFields = [
236
+ "query",
237
+ "id",
238
+ "issueId",
239
+ "title",
240
+ "name",
241
+ "path",
242
+ "file",
243
+ ];
244
+ for (const field of meaningfulFields) {
245
+ if (toolInput[field]) {
246
+ return `${field}: ${toolInput[field]}`;
247
+ }
248
+ }
249
+ }
250
+ break;
251
+ }
252
+ // Fallback to JSON but make it compact
253
+ return JSON.stringify(toolInput);
254
+ }
255
+ catch (error) {
256
+ console.error("[AgentSessionManager] Failed to format tool parameter:", error);
257
+ return JSON.stringify(toolInput);
258
+ }
259
+ }
260
+ /**
261
+ * Format tool action name with description for Bash tool
262
+ * Puts the description in round brackets after the tool name in the action field
263
+ */
264
+ formatToolActionName(toolName, toolInput, isError) {
265
+ // Handle Bash tool with description
266
+ if (toolName === "Bash" || toolName === "↪ Bash") {
267
+ // Check if toolInput has a description field
268
+ if (toolInput &&
269
+ typeof toolInput === "object" &&
270
+ "description" in toolInput &&
271
+ toolInput.description) {
272
+ const baseName = isError ? `${toolName} (Error)` : toolName;
273
+ return `${baseName} (${toolInput.description})`;
274
+ }
275
+ }
276
+ // Default formatting for other tools or Bash without description
277
+ return isError ? `${toolName} (Error)` : toolName;
278
+ }
279
+ /**
280
+ * Format tool result for display in Linear agent activities
281
+ * Converts raw tool results into formatted Markdown
282
+ */
283
+ formatToolResult(toolName, toolInput, result, isError) {
284
+ // If there's an error, wrap in error formatting
285
+ if (isError) {
286
+ return `\`\`\`\n${result}\n\`\`\``;
287
+ }
288
+ try {
289
+ switch (toolName) {
290
+ case "Bash":
291
+ case "↪ Bash": {
292
+ // Show command first if not already in parameter
293
+ let formatted = "";
294
+ if (toolInput.command && !toolInput.description) {
295
+ formatted += `\`\`\`bash\n${toolInput.command}\n\`\`\`\n\n`;
296
+ }
297
+ // Then show output
298
+ if (result?.trim()) {
299
+ formatted += `\`\`\`\n${result}\n\`\`\``;
300
+ }
301
+ else {
302
+ formatted += "*No output*";
303
+ }
304
+ return formatted;
305
+ }
306
+ case "Read":
307
+ case "↪ Read":
308
+ // For Read, the result is file content - use code block
309
+ if (result?.trim()) {
310
+ // Clean up the result: remove line numbers and system-reminder tags
311
+ let cleanedResult = result;
312
+ // Remove line numbers (format: " 123→")
313
+ cleanedResult = cleanedResult.replace(/^\s*\d+→/gm, "");
314
+ // Remove system-reminder blocks
315
+ cleanedResult = cleanedResult.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, "");
316
+ // Trim any extra whitespace
317
+ cleanedResult = cleanedResult.trim();
318
+ // Try to detect language from file extension
319
+ let lang = "";
320
+ if (toolInput.file_path) {
321
+ const ext = toolInput.file_path.split(".").pop()?.toLowerCase();
322
+ const langMap = {
323
+ ts: "typescript",
324
+ tsx: "typescript",
325
+ js: "javascript",
326
+ jsx: "javascript",
327
+ py: "python",
328
+ rb: "ruby",
329
+ go: "go",
330
+ rs: "rust",
331
+ java: "java",
332
+ c: "c",
333
+ cpp: "cpp",
334
+ cs: "csharp",
335
+ php: "php",
336
+ swift: "swift",
337
+ kt: "kotlin",
338
+ scala: "scala",
339
+ sh: "bash",
340
+ bash: "bash",
341
+ zsh: "bash",
342
+ yml: "yaml",
343
+ yaml: "yaml",
344
+ json: "json",
345
+ xml: "xml",
346
+ html: "html",
347
+ css: "css",
348
+ scss: "scss",
349
+ md: "markdown",
350
+ sql: "sql",
351
+ };
352
+ lang = langMap[ext || ""] || "";
353
+ }
354
+ return `\`\`\`${lang}\n${cleanedResult}\n\`\`\``;
355
+ }
356
+ return "*Empty file*";
357
+ case "Edit":
358
+ case "↪ Edit": {
359
+ // For Edit, show changes as a diff
360
+ // Extract old_string and new_string from toolInput
361
+ if (toolInput.old_string && toolInput.new_string) {
362
+ // Format as a unified diff
363
+ const oldLines = toolInput.old_string.split("\n");
364
+ const newLines = toolInput.new_string.split("\n");
365
+ let diff = "```diff\n";
366
+ // Add context lines before changes (show all old lines with - prefix)
367
+ for (const line of oldLines) {
368
+ diff += `-${line}\n`;
369
+ }
370
+ // Add new lines with + prefix
371
+ for (const line of newLines) {
372
+ diff += `+${line}\n`;
373
+ }
374
+ diff += "```";
375
+ return diff;
376
+ }
377
+ // Fallback to result if old/new strings not available
378
+ if (result?.trim()) {
379
+ return result;
380
+ }
381
+ return "*Edit completed*";
382
+ }
383
+ case "Write":
384
+ case "↪ Write":
385
+ // For Write, just confirm
386
+ if (result?.trim()) {
387
+ return result; // In case there's an error or message
388
+ }
389
+ return "*File written successfully*";
390
+ case "Grep":
391
+ case "↪ Grep": {
392
+ // Format grep results
393
+ if (result?.trim()) {
394
+ const lines = result.split("\n");
395
+ // If it looks like file paths (files_with_matches mode)
396
+ if (lines.length > 0 &&
397
+ lines[0] &&
398
+ !lines[0].includes(":") &&
399
+ lines[0].trim().length > 0) {
400
+ return `Found ${lines.filter((l) => l.trim()).length} matching files:\n\`\`\`\n${result}\n\`\`\``;
401
+ }
402
+ // Otherwise it's content matches
403
+ return `\`\`\`\n${result}\n\`\`\``;
404
+ }
405
+ return "*No matches found*";
406
+ }
407
+ case "Glob":
408
+ case "↪ Glob": {
409
+ if (result?.trim()) {
410
+ const lines = result.split("\n").filter((l) => l.trim());
411
+ return `Found ${lines.length} matching files:\n\`\`\`\n${result}\n\`\`\``;
412
+ }
413
+ return "*No files found*";
414
+ }
415
+ case "Task":
416
+ case "↪ Task":
417
+ // Task results can be complex - keep as is but in code block if multiline
418
+ if (result?.trim()) {
419
+ if (result.includes("\n")) {
420
+ return `\`\`\`\n${result}\n\`\`\``;
421
+ }
422
+ return result;
423
+ }
424
+ return "*Task completed*";
425
+ case "WebFetch":
426
+ case "↪ WebFetch":
427
+ case "WebSearch":
428
+ case "↪ WebSearch":
429
+ // Web results are usually formatted, keep as is
430
+ return result || "*No results*";
431
+ default:
432
+ // For unknown tools, use code block if result has multiple lines
433
+ if (result?.trim()) {
434
+ if (result.includes("\n") && result.length > 100) {
435
+ return `\`\`\`\n${result}\n\`\`\``;
436
+ }
437
+ return result;
438
+ }
439
+ return "*Completed*";
440
+ }
441
+ }
442
+ catch (error) {
443
+ console.error("[AgentSessionManager] Failed to format tool result:", error);
444
+ return result || "";
445
+ }
446
+ }
135
447
  /**
136
448
  * Complete a session from Claude result message
137
449
  */
@@ -296,6 +608,10 @@ export class AgentSessionManager {
296
608
  await this.postModelNotificationThought(linearAgentActivitySessionId, systemMessage.model);
297
609
  }
298
610
  }
611
+ else if (message.subtype === "status") {
612
+ // Handle status updates (compacting, etc.)
613
+ await this.handleStatusMessage(linearAgentActivitySessionId, message);
614
+ }
299
615
  break;
300
616
  case "user": {
301
617
  const userEntry = await this.createSessionEntry(linearAgentActivitySessionId, message);
@@ -486,17 +802,16 @@ export class AgentSessionManager {
486
802
  if (toolName === "TodoWrite" || toolName === "↪ TodoWrite") {
487
803
  return;
488
804
  }
489
- // Format input for display
490
- const formattedInput = typeof toolInput === "string"
491
- ? toolInput
492
- : JSON.stringify(toolInput, null, 2);
493
- // Use tool output directly without collapsible wrapping
494
- const wrappedResult = toolResult.content?.trim() || "";
805
+ // Format parameter and result using our formatters
806
+ const formattedParameter = this.formatToolParameter(toolName, toolInput);
807
+ const formattedResult = this.formatToolResult(toolName, toolInput, toolResult.content?.trim() || "", toolResult.isError);
808
+ // Format the action name (with description for Bash tool)
809
+ const formattedAction = this.formatToolActionName(toolName, toolInput, toolResult.isError);
495
810
  content = {
496
811
  type: "action",
497
- action: toolResult.isError ? `${toolName} (Error)` : toolName,
498
- parameter: formattedInput,
499
- result: wrappedResult,
812
+ action: formattedAction,
813
+ parameter: formattedParameter,
814
+ result: formattedResult,
500
815
  };
501
816
  }
502
817
  else {
@@ -539,7 +854,8 @@ export class AgentSessionManager {
539
854
  }
540
855
  else if (toolName === "Task") {
541
856
  // Special handling for Task tool - add start marker and track active task
542
- const parameter = entry.content;
857
+ const toolInput = entry.metadata.toolInput || entry.content;
858
+ const formattedParameter = this.formatToolParameter(toolName, toolInput);
543
859
  const displayName = toolName;
544
860
  // Track this as the active Task for this session
545
861
  if (entry.metadata?.toolUseId) {
@@ -548,7 +864,7 @@ export class AgentSessionManager {
548
864
  content = {
549
865
  type: "action",
550
866
  action: displayName,
551
- parameter: parameter,
867
+ parameter: formattedParameter,
552
868
  // result will be added later when we get tool result
553
869
  };
554
870
  // Task is not ephemeral
@@ -556,7 +872,7 @@ export class AgentSessionManager {
556
872
  }
557
873
  else {
558
874
  // Other tools - check if they're within an active Task
559
- const parameter = entry.content;
875
+ const toolInput = entry.metadata.toolInput || entry.content;
560
876
  let displayName = toolName;
561
877
  if (entry.metadata?.parentToolUseId) {
562
878
  const activeTaskId = this.activeTasksBySession.get(linearAgentActivitySessionId);
@@ -564,10 +880,11 @@ export class AgentSessionManager {
564
880
  displayName = `↪ ${toolName}`;
565
881
  }
566
882
  }
883
+ const formattedParameter = this.formatToolParameter(displayName, toolInput);
567
884
  content = {
568
885
  type: "action",
569
886
  action: displayName,
570
- parameter: parameter,
887
+ parameter: formattedParameter,
571
888
  // result will be added later when we get tool result
572
889
  };
573
890
  // Standard tool calls are ephemeral
@@ -1031,5 +1348,59 @@ export class AgentSessionManager {
1031
1348
  console.error(`[AgentSessionManager] Error posting procedure selection:`, error);
1032
1349
  }
1033
1350
  }
1351
+ /**
1352
+ * Handle status messages (compacting, etc.)
1353
+ */
1354
+ async handleStatusMessage(linearAgentActivitySessionId, message) {
1355
+ const session = this.sessions.get(linearAgentActivitySessionId);
1356
+ if (!session || !session.linearAgentActivitySessionId) {
1357
+ console.warn(`[AgentSessionManager] No Linear session ID for session ${linearAgentActivitySessionId}`);
1358
+ return;
1359
+ }
1360
+ try {
1361
+ if (message.status === "compacting") {
1362
+ // Create an ephemeral thought for the compacting status
1363
+ const result = await this.linearClient.createAgentActivity({
1364
+ agentSessionId: session.linearAgentActivitySessionId,
1365
+ content: {
1366
+ type: "thought",
1367
+ body: "Compacting conversation history…",
1368
+ },
1369
+ ephemeral: true,
1370
+ });
1371
+ if (result.success && result.agentActivity) {
1372
+ const activity = await result.agentActivity;
1373
+ // Store the activity ID so we can replace it later
1374
+ this.activeStatusActivitiesBySession.set(linearAgentActivitySessionId, activity.id);
1375
+ console.log(`[AgentSessionManager] Posted ephemeral compacting status for session ${linearAgentActivitySessionId}`);
1376
+ }
1377
+ else {
1378
+ console.error(`[AgentSessionManager] Failed to post compacting status:`, result);
1379
+ }
1380
+ }
1381
+ else if (message.status === null) {
1382
+ // Clear the status - post a non-ephemeral thought to replace the ephemeral one
1383
+ const result = await this.linearClient.createAgentActivity({
1384
+ agentSessionId: session.linearAgentActivitySessionId,
1385
+ content: {
1386
+ type: "thought",
1387
+ body: "Conversation history compacted",
1388
+ },
1389
+ ephemeral: false,
1390
+ });
1391
+ if (result.success) {
1392
+ // Clean up the stored activity ID
1393
+ this.activeStatusActivitiesBySession.delete(linearAgentActivitySessionId);
1394
+ console.log(`[AgentSessionManager] Posted non-ephemeral status clear for session ${linearAgentActivitySessionId}`);
1395
+ }
1396
+ else {
1397
+ console.error(`[AgentSessionManager] Failed to post status clear:`, result);
1398
+ }
1399
+ }
1400
+ }
1401
+ catch (error) {
1402
+ console.error(`[AgentSessionManager] Error handling status message:`, error);
1403
+ }
1404
+ }
1034
1405
  }
1035
1406
  //# sourceMappingURL=AgentSessionManager.js.map