@supaku/agentfactory 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/dist/src/deployment/deployment-checker.d.ts +110 -0
  3. package/dist/src/deployment/deployment-checker.d.ts.map +1 -0
  4. package/dist/src/deployment/deployment-checker.js +242 -0
  5. package/dist/src/deployment/index.d.ts +3 -0
  6. package/dist/src/deployment/index.d.ts.map +1 -0
  7. package/dist/src/deployment/index.js +2 -0
  8. package/dist/src/index.d.ts +5 -0
  9. package/dist/src/index.d.ts.map +1 -0
  10. package/dist/src/index.js +4 -0
  11. package/dist/src/logger.d.ts +117 -0
  12. package/dist/src/logger.d.ts.map +1 -0
  13. package/dist/src/logger.js +430 -0
  14. package/dist/src/orchestrator/activity-emitter.d.ts +128 -0
  15. package/dist/src/orchestrator/activity-emitter.d.ts.map +1 -0
  16. package/dist/src/orchestrator/activity-emitter.js +406 -0
  17. package/dist/src/orchestrator/api-activity-emitter.d.ts +167 -0
  18. package/dist/src/orchestrator/api-activity-emitter.d.ts.map +1 -0
  19. package/dist/src/orchestrator/api-activity-emitter.js +469 -0
  20. package/dist/src/orchestrator/heartbeat-writer.d.ts +57 -0
  21. package/dist/src/orchestrator/heartbeat-writer.d.ts.map +1 -0
  22. package/dist/src/orchestrator/heartbeat-writer.js +137 -0
  23. package/dist/src/orchestrator/index.d.ts +20 -0
  24. package/dist/src/orchestrator/index.d.ts.map +1 -0
  25. package/dist/src/orchestrator/index.js +22 -0
  26. package/dist/src/orchestrator/log-analyzer.d.ts +160 -0
  27. package/dist/src/orchestrator/log-analyzer.d.ts.map +1 -0
  28. package/dist/src/orchestrator/log-analyzer.js +572 -0
  29. package/dist/src/orchestrator/log-config.d.ts +39 -0
  30. package/dist/src/orchestrator/log-config.d.ts.map +1 -0
  31. package/dist/src/orchestrator/log-config.js +45 -0
  32. package/dist/src/orchestrator/orchestrator.d.ts +246 -0
  33. package/dist/src/orchestrator/orchestrator.d.ts.map +1 -0
  34. package/dist/src/orchestrator/orchestrator.js +2525 -0
  35. package/dist/src/orchestrator/parse-work-result.d.ts +16 -0
  36. package/dist/src/orchestrator/parse-work-result.d.ts.map +1 -0
  37. package/dist/src/orchestrator/parse-work-result.js +73 -0
  38. package/dist/src/orchestrator/progress-logger.d.ts +72 -0
  39. package/dist/src/orchestrator/progress-logger.d.ts.map +1 -0
  40. package/dist/src/orchestrator/progress-logger.js +135 -0
  41. package/dist/src/orchestrator/session-logger.d.ts +159 -0
  42. package/dist/src/orchestrator/session-logger.d.ts.map +1 -0
  43. package/dist/src/orchestrator/session-logger.js +275 -0
  44. package/dist/src/orchestrator/state-recovery.d.ts +96 -0
  45. package/dist/src/orchestrator/state-recovery.d.ts.map +1 -0
  46. package/dist/src/orchestrator/state-recovery.js +301 -0
  47. package/dist/src/orchestrator/state-types.d.ts +165 -0
  48. package/dist/src/orchestrator/state-types.d.ts.map +1 -0
  49. package/dist/src/orchestrator/state-types.js +7 -0
  50. package/dist/src/orchestrator/stream-parser.d.ts +145 -0
  51. package/dist/src/orchestrator/stream-parser.d.ts.map +1 -0
  52. package/dist/src/orchestrator/stream-parser.js +131 -0
  53. package/dist/src/orchestrator/types.d.ts +205 -0
  54. package/dist/src/orchestrator/types.d.ts.map +1 -0
  55. package/dist/src/orchestrator/types.js +4 -0
  56. package/dist/src/providers/amp-provider.d.ts +20 -0
  57. package/dist/src/providers/amp-provider.d.ts.map +1 -0
  58. package/dist/src/providers/amp-provider.js +24 -0
  59. package/dist/src/providers/claude-provider.d.ts +18 -0
  60. package/dist/src/providers/claude-provider.d.ts.map +1 -0
  61. package/dist/src/providers/claude-provider.js +267 -0
  62. package/dist/src/providers/codex-provider.d.ts +21 -0
  63. package/dist/src/providers/codex-provider.d.ts.map +1 -0
  64. package/dist/src/providers/codex-provider.js +25 -0
  65. package/dist/src/providers/index.d.ts +42 -0
  66. package/dist/src/providers/index.d.ts.map +1 -0
  67. package/dist/src/providers/index.js +77 -0
  68. package/dist/src/providers/types.d.ts +147 -0
  69. package/dist/src/providers/types.d.ts.map +1 -0
  70. package/dist/src/providers/types.js +13 -0
  71. package/package.json +63 -0
@@ -0,0 +1,406 @@
1
+ /**
2
+ * Linear Activity Emitter
3
+ *
4
+ * Emits Claude stream events to Linear as agent activities.
5
+ * Handles rate limiting by batching rapid activities and
6
+ * truncating long outputs.
7
+ *
8
+ * Mapping:
9
+ * - assistant message → response (persisted, user-directed communication)
10
+ * - tool_use → action (ephemeral)
11
+ * - tool_result → action (ephemeral)
12
+ * - result → response (persisted)
13
+ * - error → error (persisted)
14
+ */
15
+ import { ENVIRONMENT_ISSUE_TYPES } from '@supaku/agentfactory-linear';
16
+ const DEFAULT_MIN_INTERVAL = 500;
17
+ const DEFAULT_MAX_OUTPUT_LENGTH = 2000;
18
+ /**
19
+ * Map Claude todo status to Linear plan item state
20
+ */
21
+ function mapTodoStatusToLinearState(status) {
22
+ switch (status) {
23
+ case 'pending':
24
+ return 'pending';
25
+ case 'in_progress':
26
+ return 'inProgress';
27
+ case 'completed':
28
+ return 'completed';
29
+ default:
30
+ return 'pending';
31
+ }
32
+ }
33
+ /**
34
+ * Activity Emitter
35
+ *
36
+ * Handles rate-limited emission of Claude events to Linear activities.
37
+ */
38
+ export class ActivityEmitter {
39
+ session;
40
+ minInterval;
41
+ maxOutputLength;
42
+ includeTimestamps;
43
+ onActivityEmitted;
44
+ onActivityThrottled;
45
+ lastEmitTime = 0;
46
+ queue = [];
47
+ flushTimer = null;
48
+ isProcessing = false;
49
+ // Track reported tool error signatures for deduplication
50
+ reportedToolErrors = new Set();
51
+ constructor(config) {
52
+ this.session = config.session;
53
+ this.minInterval = config.minInterval ?? DEFAULT_MIN_INTERVAL;
54
+ this.maxOutputLength = config.maxOutputLength ?? DEFAULT_MAX_OUTPUT_LENGTH;
55
+ this.includeTimestamps = config.includeTimestamps ?? false;
56
+ this.onActivityEmitted = config.onActivityEmitted;
57
+ this.onActivityThrottled = config.onActivityThrottled;
58
+ }
59
+ /**
60
+ * Emit a thought activity (persistent by default for visibility in Linear)
61
+ */
62
+ async emitThought(content, ephemeral = false) {
63
+ await this.queueActivity({
64
+ type: 'thought',
65
+ content,
66
+ ephemeral,
67
+ });
68
+ }
69
+ /**
70
+ * Emit a tool use activity (ephemeral by default)
71
+ */
72
+ async emitToolUse(tool, input, ephemeral = true) {
73
+ const inputSummary = this.summarizeToolInput(tool, input);
74
+ await this.queueActivity({
75
+ type: 'action',
76
+ content: `${tool}: ${inputSummary}`,
77
+ ephemeral,
78
+ toolName: tool,
79
+ toolInput: input,
80
+ });
81
+ }
82
+ /**
83
+ * Emit a response activity (persisted)
84
+ */
85
+ async emitResponse(content) {
86
+ await this.queueActivity({
87
+ type: 'response',
88
+ content,
89
+ ephemeral: false,
90
+ });
91
+ }
92
+ /**
93
+ * Emit an error activity (persisted)
94
+ */
95
+ async emitError(error) {
96
+ const message = error instanceof Error ? error.message : error;
97
+ await this.queueActivity({
98
+ type: 'error',
99
+ content: message,
100
+ ephemeral: false,
101
+ });
102
+ }
103
+ /**
104
+ * Report a tool error as a Linear issue for tracking and improvement.
105
+ * Creates a bug in the Agent project backlog.
106
+ *
107
+ * @param toolName - Name of the tool that errored
108
+ * @param errorMessage - The error message
109
+ * @param context - Additional context about the error
110
+ * @returns The created issue, or null if creation failed or was deduplicated
111
+ */
112
+ async reportToolError(toolName, errorMessage, context) {
113
+ // Deduplicate using tool name + first 100 chars of error
114
+ const signature = `${toolName}:${errorMessage.substring(0, 100)}`;
115
+ if (this.reportedToolErrors.has(signature)) {
116
+ return null;
117
+ }
118
+ this.reportedToolErrors.add(signature);
119
+ try {
120
+ return await this.session.reportEnvironmentIssue(`Tool error: ${toolName}`, `The agent encountered an error while using the **${toolName}** tool.\n\n**Error:**\n\`\`\`\n${errorMessage}\n\`\`\``, {
121
+ issueType: ENVIRONMENT_ISSUE_TYPES.TOOL,
122
+ sourceIssueId: context?.issueIdentifier,
123
+ additionalContext: {
124
+ toolName,
125
+ ...context?.additionalContext,
126
+ },
127
+ });
128
+ }
129
+ catch (error) {
130
+ console.error('[ActivityEmitter] Failed to report tool error:', error);
131
+ return null;
132
+ }
133
+ }
134
+ /**
135
+ * Get Claude stream handlers that emit to Linear
136
+ */
137
+ getStreamHandlers() {
138
+ return {
139
+ onAssistant: async (event) => {
140
+ // Skip partial messages (streaming updates)
141
+ if (event.partial)
142
+ return;
143
+ // Assistant messages are user-directed communication, emit as response (persisted)
144
+ await this.queueActivity({
145
+ type: 'response',
146
+ content: event.message,
147
+ ephemeral: false,
148
+ });
149
+ },
150
+ onToolUse: async (event) => {
151
+ const inputSummary = this.summarizeToolInput(event.tool, event.input);
152
+ await this.queueActivity({
153
+ type: 'action',
154
+ content: `${event.tool}: ${inputSummary}`,
155
+ ephemeral: true,
156
+ toolName: event.tool,
157
+ toolInput: event.input,
158
+ });
159
+ },
160
+ onToolResult: async (event) => {
161
+ const output = this.truncateOutput(event.output);
162
+ const prefix = event.is_error ? 'Error' : 'Result';
163
+ await this.queueActivity({
164
+ type: 'action',
165
+ content: `${event.tool} ${prefix}: ${output}`,
166
+ ephemeral: true,
167
+ toolName: event.tool,
168
+ toolOutput: output,
169
+ });
170
+ },
171
+ onResult: async (event) => {
172
+ // Final result - persisted as response
173
+ const content = this.formatResultContent(event);
174
+ await this.queueActivity({
175
+ type: 'response',
176
+ content,
177
+ ephemeral: false,
178
+ });
179
+ },
180
+ onError: async (event) => {
181
+ // Errors are persisted
182
+ await this.queueActivity({
183
+ type: 'error',
184
+ content: event.error.message,
185
+ ephemeral: false,
186
+ });
187
+ },
188
+ onTodo: async (newTodos) => {
189
+ // Map Claude todos to Linear plan items
190
+ const planItems = newTodos.map((todo) => ({
191
+ title: todo.content,
192
+ state: mapTodoStatusToLinearState(todo.status),
193
+ details: todo.activeForm,
194
+ }));
195
+ // Update the plan via session
196
+ try {
197
+ await this.session.updatePlan(planItems);
198
+ }
199
+ catch (error) {
200
+ console.error('Failed to update plan:', error);
201
+ }
202
+ },
203
+ };
204
+ }
205
+ /**
206
+ * Queue an activity for emission with rate limiting
207
+ */
208
+ async queueActivity(activity) {
209
+ this.queue.push(activity);
210
+ // Schedule flush if not already scheduled
211
+ if (!this.flushTimer && !this.isProcessing) {
212
+ const timeSinceLastEmit = Date.now() - this.lastEmitTime;
213
+ const delay = Math.max(0, this.minInterval - timeSinceLastEmit);
214
+ this.flushTimer = setTimeout(() => {
215
+ this.flushTimer = null;
216
+ this.processQueue();
217
+ }, delay);
218
+ }
219
+ }
220
+ /**
221
+ * Process queued activities
222
+ */
223
+ async processQueue() {
224
+ if (this.isProcessing || this.queue.length === 0)
225
+ return;
226
+ this.isProcessing = true;
227
+ try {
228
+ // Merge similar consecutive activities to reduce API calls
229
+ const merged = this.mergeQueuedActivities();
230
+ for (const activity of merged) {
231
+ await this.emitActivity(activity);
232
+ this.lastEmitTime = Date.now();
233
+ // Small delay between emissions to avoid rate limits
234
+ if (merged.length > 1) {
235
+ await this.delay(100);
236
+ }
237
+ }
238
+ }
239
+ finally {
240
+ this.isProcessing = false;
241
+ // If more activities were queued during processing, schedule another flush
242
+ if (this.queue.length > 0 && !this.flushTimer) {
243
+ this.flushTimer = setTimeout(() => {
244
+ this.flushTimer = null;
245
+ this.processQueue();
246
+ }, this.minInterval);
247
+ }
248
+ }
249
+ }
250
+ /**
251
+ * Merge consecutive similar activities in the queue
252
+ */
253
+ mergeQueuedActivities() {
254
+ const activities = [...this.queue];
255
+ this.queue = [];
256
+ if (activities.length <= 1)
257
+ return activities;
258
+ const merged = [];
259
+ let current = activities[0];
260
+ for (let i = 1; i < activities.length; i++) {
261
+ const next = activities[i];
262
+ // Merge consecutive thoughts
263
+ if (current.type === 'thought' &&
264
+ next.type === 'thought' &&
265
+ current.ephemeral === next.ephemeral) {
266
+ current = {
267
+ ...current,
268
+ content: `${current.content}\n\n${next.content}`,
269
+ };
270
+ this.onActivityThrottled?.('thought', next.content);
271
+ continue;
272
+ }
273
+ // Merge consecutive tool results for same tool
274
+ if (current.type === 'action' &&
275
+ next.type === 'action' &&
276
+ current.toolName === next.toolName &&
277
+ current.ephemeral === next.ephemeral) {
278
+ current = {
279
+ ...current,
280
+ content: `${current.content}\n${next.content}`,
281
+ };
282
+ this.onActivityThrottled?.('action', next.content);
283
+ continue;
284
+ }
285
+ merged.push(current);
286
+ current = next;
287
+ }
288
+ merged.push(current);
289
+ return merged;
290
+ }
291
+ /**
292
+ * Emit a single activity to Linear
293
+ */
294
+ async emitActivity(activity) {
295
+ try {
296
+ const content = this.includeTimestamps
297
+ ? `[${new Date().toISOString()}] ${activity.content}`
298
+ : activity.content;
299
+ switch (activity.type) {
300
+ case 'thought':
301
+ await this.session.emitThought(content, activity.ephemeral);
302
+ break;
303
+ case 'action':
304
+ if (activity.toolName && activity.toolInput) {
305
+ await this.session.emitAction(activity.toolName, activity.toolInput, activity.ephemeral);
306
+ }
307
+ else if (activity.toolName && activity.toolOutput) {
308
+ await this.session.emitToolResult(activity.toolName, activity.toolOutput, activity.ephemeral);
309
+ }
310
+ else {
311
+ // Generic action - emit as thought
312
+ await this.session.emitThought(content, activity.ephemeral);
313
+ }
314
+ break;
315
+ case 'response':
316
+ await this.session.emitResponse(content);
317
+ break;
318
+ case 'error':
319
+ await this.session.emitError(new Error(content));
320
+ break;
321
+ }
322
+ this.onActivityEmitted?.(activity.type, content);
323
+ }
324
+ catch (error) {
325
+ console.error(`Failed to emit ${activity.type} activity:`, error);
326
+ }
327
+ }
328
+ /**
329
+ * Summarize tool input for display
330
+ */
331
+ summarizeToolInput(tool, input) {
332
+ // Tool-specific summaries
333
+ switch (tool) {
334
+ case 'Read':
335
+ return String(input.file_path || input.path || 'file');
336
+ case 'Write':
337
+ return String(input.file_path || input.path || 'file');
338
+ case 'Edit':
339
+ return String(input.file_path || input.path || 'file');
340
+ case 'Grep':
341
+ return `"${input.pattern}" in ${input.path || '.'}`;
342
+ case 'Glob':
343
+ return String(input.pattern || '*');
344
+ case 'Bash':
345
+ const cmd = String(input.command || '');
346
+ return cmd.length > 50 ? cmd.substring(0, 47) + '...' : cmd;
347
+ case 'Task':
348
+ return String(input.description || input.prompt || 'task');
349
+ default:
350
+ // Generic: show first string value or truncated JSON
351
+ const firstStringValue = Object.values(input).find((v) => typeof v === 'string');
352
+ if (firstStringValue) {
353
+ return firstStringValue.length > 50
354
+ ? firstStringValue.substring(0, 47) + '...'
355
+ : firstStringValue;
356
+ }
357
+ const json = JSON.stringify(input);
358
+ return json.length > 50 ? json.substring(0, 47) + '...' : json;
359
+ }
360
+ }
361
+ /**
362
+ * Truncate long output strings
363
+ */
364
+ truncateOutput(output) {
365
+ if (output.length <= this.maxOutputLength)
366
+ return output;
367
+ return (output.substring(0, this.maxOutputLength) +
368
+ `\n\n... (truncated ${output.length - this.maxOutputLength} chars)`);
369
+ }
370
+ /**
371
+ * Format the final result content
372
+ */
373
+ formatResultContent(event) {
374
+ let content = event.result;
375
+ if (event.cost) {
376
+ content += `\n\n---\n*Tokens: ${event.cost.input_tokens} in / ${event.cost.output_tokens} out*`;
377
+ }
378
+ if (event.duration_ms) {
379
+ const seconds = (event.duration_ms / 1000).toFixed(1);
380
+ content += event.cost ? ` | *Duration: ${seconds}s*` : `\n\n---\n*Duration: ${seconds}s*`;
381
+ }
382
+ return content;
383
+ }
384
+ /**
385
+ * Flush all pending activities immediately
386
+ */
387
+ async flush() {
388
+ if (this.flushTimer) {
389
+ clearTimeout(this.flushTimer);
390
+ this.flushTimer = null;
391
+ }
392
+ await this.processQueue();
393
+ }
394
+ /**
395
+ * Helper delay function
396
+ */
397
+ delay(ms) {
398
+ return new Promise((resolve) => setTimeout(resolve, ms));
399
+ }
400
+ }
401
+ /**
402
+ * Create an activity emitter instance
403
+ */
404
+ export function createActivityEmitter(config) {
405
+ return new ActivityEmitter(config);
406
+ }
@@ -0,0 +1,167 @@
1
+ /**
2
+ * API-based Activity Emitter
3
+ *
4
+ * Emits Claude stream events to Linear via the agent app's API endpoint.
5
+ * This is used when the orchestrator runs remotely (as a worker) and needs
6
+ * to proxy activities through the Vercel app which has OAuth tokens.
7
+ *
8
+ * The agent app API endpoint (/api/sessions/[id]/activity) retrieves the
9
+ * OAuth token from Redis using the session's organizationId and forwards
10
+ * the activity to Linear's Agent API.
11
+ *
12
+ * Mapping:
13
+ * - assistant message → response (persisted, user-directed communication)
14
+ * - tool_use → action (ephemeral)
15
+ * - tool_result → action (ephemeral)
16
+ * - result → response (persisted)
17
+ * - error → error (persisted)
18
+ */
19
+ import type { ClaudeStreamHandlers } from './stream-parser';
20
+ /** Configuration for the API activity emitter */
21
+ export interface ApiActivityEmitterConfig {
22
+ /** Linear session ID */
23
+ sessionId: string;
24
+ /** Worker ID for authentication */
25
+ workerId: string;
26
+ /** API base URL (e.g., https://agent.supaku.dev) */
27
+ apiBaseUrl: string;
28
+ /** API authentication key */
29
+ apiKey: string;
30
+ /** Minimum interval between activities in ms (default: 500ms) */
31
+ minInterval?: number;
32
+ /** Maximum length for tool outputs before truncation (default: 2000) */
33
+ maxOutputLength?: number;
34
+ /** Whether to include timestamps in activities (default: false) */
35
+ includeTimestamps?: boolean;
36
+ /** Optional callback when an activity is emitted */
37
+ onActivityEmitted?: (type: string, content: string) => void;
38
+ /** Optional callback when an activity is throttled */
39
+ onActivityThrottled?: (type: string, content: string) => void;
40
+ /** Optional callback when API call fails */
41
+ onActivityError?: (type: string, error: Error) => void;
42
+ /** Optional callback when a progress update is posted */
43
+ onProgressPosted?: (milestone: string, message: string) => void;
44
+ }
45
+ /** Progress milestone types */
46
+ export type ProgressMilestone = 'claimed' | 'worktree' | 'started' | 'running' | 'tests' | 'pr' | 'completed' | 'failed' | 'stopped' | 'resumed';
47
+ /**
48
+ * API Activity Emitter
49
+ *
50
+ * Handles rate-limited emission of Claude events to Linear via API proxy.
51
+ */
52
+ export declare class ApiActivityEmitter {
53
+ private readonly sessionId;
54
+ private workerId;
55
+ private readonly apiBaseUrl;
56
+ private readonly apiKey;
57
+ private readonly minInterval;
58
+ private readonly maxOutputLength;
59
+ private readonly includeTimestamps;
60
+ private readonly onActivityEmitted?;
61
+ private readonly onActivityThrottled?;
62
+ private readonly onActivityError?;
63
+ private readonly onProgressPosted?;
64
+ private lastEmitTime;
65
+ private queue;
66
+ private flushTimer;
67
+ private isProcessing;
68
+ private readonly reportedToolErrors;
69
+ constructor(config: ApiActivityEmitterConfig);
70
+ /**
71
+ * Update the worker ID used for API requests.
72
+ * Called after worker re-registration to ensure activities are attributed
73
+ * to the new worker ID and pass ownership checks.
74
+ */
75
+ updateWorkerId(newWorkerId: string): void;
76
+ /**
77
+ * Get the current worker ID
78
+ */
79
+ getWorkerId(): string;
80
+ /**
81
+ * Emit a thought activity (persistent by default for visibility in Linear)
82
+ */
83
+ emitThought(content: string, ephemeral?: boolean): Promise<void>;
84
+ /**
85
+ * Emit a tool use activity (ephemeral by default)
86
+ */
87
+ emitToolUse(tool: string, input: Record<string, unknown>, ephemeral?: boolean): Promise<void>;
88
+ /**
89
+ * Emit a response activity (persisted)
90
+ */
91
+ emitResponse(content: string): Promise<void>;
92
+ /**
93
+ * Emit an error activity (persisted)
94
+ */
95
+ emitError(error: Error | string): Promise<void>;
96
+ /**
97
+ * Post a progress update comment to the Linear issue thread.
98
+ * Unlike activities which are ephemeral, progress updates are
99
+ * persisted as comments and visible in the issue thread.
100
+ *
101
+ * @param milestone - The type of progress milestone (e.g., 'started', 'completed')
102
+ * @param message - The progress message to post
103
+ */
104
+ postProgress(milestone: ProgressMilestone, message: string): Promise<boolean>;
105
+ /**
106
+ * Report a tool error as a Linear issue for tracking and improvement.
107
+ * Creates a bug in the Agent project backlog via API.
108
+ *
109
+ * @param toolName - Name of the tool that errored
110
+ * @param errorMessage - The error message
111
+ * @param context - Additional context about the error
112
+ * @returns The created issue, or null if creation failed or was deduplicated
113
+ */
114
+ reportToolError(toolName: string, errorMessage: string, context?: {
115
+ issueIdentifier?: string;
116
+ additionalContext?: Record<string, unknown>;
117
+ }): Promise<{
118
+ id: string;
119
+ identifier: string;
120
+ url: string;
121
+ } | null>;
122
+ /**
123
+ * Get Claude stream handlers that emit to Linear via API
124
+ */
125
+ getStreamHandlers(): ClaudeStreamHandlers;
126
+ /**
127
+ * Queue an activity for emission with rate limiting
128
+ */
129
+ private queueActivity;
130
+ /**
131
+ * Process queued activities
132
+ */
133
+ private processQueue;
134
+ /**
135
+ * Merge consecutive similar activities in the queue
136
+ */
137
+ private mergeQueuedActivities;
138
+ /**
139
+ * Emit a single activity to Linear via API
140
+ */
141
+ private emitActivity;
142
+ /**
143
+ * Summarize tool input for display
144
+ */
145
+ private summarizeToolInput;
146
+ /**
147
+ * Truncate long output strings
148
+ */
149
+ private truncateOutput;
150
+ /**
151
+ * Format the final result content
152
+ */
153
+ private formatResultContent;
154
+ /**
155
+ * Flush all pending activities immediately
156
+ */
157
+ flush(): Promise<void>;
158
+ /**
159
+ * Helper delay function
160
+ */
161
+ private delay;
162
+ }
163
+ /**
164
+ * Create an API activity emitter instance
165
+ */
166
+ export declare function createApiActivityEmitter(config: ApiActivityEmitterConfig): ApiActivityEmitter;
167
+ //# sourceMappingURL=api-activity-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-activity-emitter.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/api-activity-emitter.ts"],"names":[],"mappings":"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"}