@northflare/runner 0.0.30 → 0.0.32

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 (119) hide show
  1. package/bin/northflare-runner +1 -1
  2. package/dist/chunk-3QTLJ4CG.js +33622 -0
  3. package/dist/chunk-3QTLJ4CG.js.map +1 -0
  4. package/dist/chunk-7D4SUZUM.js +38 -0
  5. package/dist/chunk-7D4SUZUM.js.map +1 -0
  6. package/dist/dist-W7DZRE4U.js +365 -0
  7. package/dist/dist-W7DZRE4U.js.map +1 -0
  8. package/dist/index.d.ts +764 -5
  9. package/dist/index.js +9872 -202
  10. package/dist/index.js.map +1 -1
  11. package/dist/sdk-query-TRMSGGID-EIENWDKW.js +14 -0
  12. package/dist/sdk-query-TRMSGGID-EIENWDKW.js.map +1 -0
  13. package/package.json +17 -17
  14. package/tsup.config.ts +5 -2
  15. package/dist/components/claude-sdk-manager.d.ts +0 -60
  16. package/dist/components/claude-sdk-manager.d.ts.map +0 -1
  17. package/dist/components/claude-sdk-manager.js +0 -1378
  18. package/dist/components/claude-sdk-manager.js.map +0 -1
  19. package/dist/components/codex-sdk-manager.d.ts +0 -94
  20. package/dist/components/codex-sdk-manager.d.ts.map +0 -1
  21. package/dist/components/codex-sdk-manager.js +0 -1450
  22. package/dist/components/codex-sdk-manager.js.map +0 -1
  23. package/dist/components/enhanced-repository-manager.d.ts +0 -173
  24. package/dist/components/enhanced-repository-manager.d.ts.map +0 -1
  25. package/dist/components/enhanced-repository-manager.js +0 -1097
  26. package/dist/components/enhanced-repository-manager.js.map +0 -1
  27. package/dist/components/message-handler-sse.d.ts +0 -77
  28. package/dist/components/message-handler-sse.d.ts.map +0 -1
  29. package/dist/components/message-handler-sse.js +0 -1224
  30. package/dist/components/message-handler-sse.js.map +0 -1
  31. package/dist/components/northflare-agent-sdk-manager.d.ts +0 -58
  32. package/dist/components/northflare-agent-sdk-manager.d.ts.map +0 -1
  33. package/dist/components/northflare-agent-sdk-manager.js +0 -2032
  34. package/dist/components/northflare-agent-sdk-manager.js.map +0 -1
  35. package/dist/components/repository-manager.d.ts +0 -51
  36. package/dist/components/repository-manager.d.ts.map +0 -1
  37. package/dist/components/repository-manager.js +0 -256
  38. package/dist/components/repository-manager.js.map +0 -1
  39. package/dist/index.d.ts.map +0 -1
  40. package/dist/runner-sse.d.ts +0 -102
  41. package/dist/runner-sse.d.ts.map +0 -1
  42. package/dist/runner-sse.js +0 -877
  43. package/dist/runner-sse.js.map +0 -1
  44. package/dist/services/RunnerAPIClient.d.ts +0 -61
  45. package/dist/services/RunnerAPIClient.d.ts.map +0 -1
  46. package/dist/services/RunnerAPIClient.js +0 -187
  47. package/dist/services/RunnerAPIClient.js.map +0 -1
  48. package/dist/services/SSEClient.d.ts +0 -62
  49. package/dist/services/SSEClient.d.ts.map +0 -1
  50. package/dist/services/SSEClient.js +0 -225
  51. package/dist/services/SSEClient.js.map +0 -1
  52. package/dist/types/claude.d.ts +0 -80
  53. package/dist/types/claude.d.ts.map +0 -1
  54. package/dist/types/claude.js +0 -5
  55. package/dist/types/claude.js.map +0 -1
  56. package/dist/types/index.d.ts +0 -52
  57. package/dist/types/index.d.ts.map +0 -1
  58. package/dist/types/index.js +0 -7
  59. package/dist/types/index.js.map +0 -1
  60. package/dist/types/messages.d.ts +0 -33
  61. package/dist/types/messages.d.ts.map +0 -1
  62. package/dist/types/messages.js +0 -5
  63. package/dist/types/messages.js.map +0 -1
  64. package/dist/types/runner-interface.d.ts +0 -38
  65. package/dist/types/runner-interface.d.ts.map +0 -1
  66. package/dist/types/runner-interface.js +0 -5
  67. package/dist/types/runner-interface.js.map +0 -1
  68. package/dist/utils/StateManager.d.ts +0 -61
  69. package/dist/utils/StateManager.d.ts.map +0 -1
  70. package/dist/utils/StateManager.js +0 -170
  71. package/dist/utils/StateManager.js.map +0 -1
  72. package/dist/utils/config.d.ts +0 -48
  73. package/dist/utils/config.d.ts.map +0 -1
  74. package/dist/utils/config.js +0 -378
  75. package/dist/utils/config.js.map +0 -1
  76. package/dist/utils/console.d.ts +0 -8
  77. package/dist/utils/console.d.ts.map +0 -1
  78. package/dist/utils/console.js +0 -31
  79. package/dist/utils/console.js.map +0 -1
  80. package/dist/utils/debug.d.ts +0 -12
  81. package/dist/utils/debug.d.ts.map +0 -1
  82. package/dist/utils/debug.js +0 -94
  83. package/dist/utils/debug.js.map +0 -1
  84. package/dist/utils/expand-env.d.ts +0 -2
  85. package/dist/utils/expand-env.d.ts.map +0 -1
  86. package/dist/utils/expand-env.js +0 -17
  87. package/dist/utils/expand-env.js.map +0 -1
  88. package/dist/utils/inactivity-timeout.d.ts +0 -19
  89. package/dist/utils/inactivity-timeout.d.ts.map +0 -1
  90. package/dist/utils/inactivity-timeout.js +0 -72
  91. package/dist/utils/inactivity-timeout.js.map +0 -1
  92. package/dist/utils/logger.d.ts +0 -10
  93. package/dist/utils/logger.d.ts.map +0 -1
  94. package/dist/utils/logger.js +0 -129
  95. package/dist/utils/logger.js.map +0 -1
  96. package/dist/utils/message-log.d.ts +0 -23
  97. package/dist/utils/message-log.d.ts.map +0 -1
  98. package/dist/utils/message-log.js +0 -69
  99. package/dist/utils/message-log.js.map +0 -1
  100. package/dist/utils/model.d.ts +0 -8
  101. package/dist/utils/model.d.ts.map +0 -1
  102. package/dist/utils/model.js +0 -37
  103. package/dist/utils/model.js.map +0 -1
  104. package/dist/utils/status-line.d.ts +0 -34
  105. package/dist/utils/status-line.d.ts.map +0 -1
  106. package/dist/utils/status-line.js +0 -131
  107. package/dist/utils/status-line.js.map +0 -1
  108. package/dist/utils/tool-response-sanitizer.d.ts +0 -9
  109. package/dist/utils/tool-response-sanitizer.d.ts.map +0 -1
  110. package/dist/utils/tool-response-sanitizer.js +0 -118
  111. package/dist/utils/tool-response-sanitizer.js.map +0 -1
  112. package/dist/utils/update-coordinator.d.ts +0 -53
  113. package/dist/utils/update-coordinator.d.ts.map +0 -1
  114. package/dist/utils/update-coordinator.js +0 -159
  115. package/dist/utils/update-coordinator.js.map +0 -1
  116. package/dist/utils/version.d.ts +0 -10
  117. package/dist/utils/version.d.ts.map +0 -1
  118. package/dist/utils/version.js +0 -33
  119. package/dist/utils/version.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -1,10 +1,769 @@
1
+ import { Conversation } from '@botanicastudios/claude-code-sdk-ts';
2
+ import { Thread } from '@northflare/codex-sdk';
3
+
4
+ /**
5
+ * JSONRPC message types for communication between runner and orchestrator
6
+ */
7
+ interface JsonRpcMessage {
8
+ jsonrpc: "2.0";
9
+ id?: string | number;
10
+ method?: string;
11
+ params?: any;
12
+ result?: any;
13
+ error?: JsonRpcError;
14
+ }
15
+ interface JsonRpcError {
16
+ code: number;
17
+ message: string;
18
+ data?: any;
19
+ }
20
+ interface RunnerMessage {
21
+ id: string;
22
+ direction: "to_runner" | "to_orchestrator";
23
+ runnerId: string;
24
+ taskId: string | null;
25
+ workspaceId: string | null;
26
+ conversationObjectType?: "Task" | "TaskPlan";
27
+ conversationObjectId?: string;
28
+ conversationId?: string;
29
+ payload: JsonRpcMessage;
30
+ createdAt: string;
31
+ expiresAt: string;
32
+ /** Server's expected runner version. If newer than current, triggers auto-update. */
33
+ expectedRunnerVersion?: string;
34
+ }
35
+ type MethodHandler = (params: any, message: RunnerMessage) => Promise<void>;
36
+
37
+ /**
38
+ * Types related to Claude SDK integration
39
+ */
40
+
41
+ interface AgentConversation {
42
+ send: (payload: {
43
+ type: string;
44
+ text?: string;
45
+ content?: Array<{
46
+ type: string;
47
+ text?: string;
48
+ image?: string;
49
+ }>;
50
+ }) => void;
51
+ end: () => Promise<void> | void;
52
+ }
53
+ interface RepositoryInfo {
54
+ url: string;
55
+ branch: string;
56
+ commit?: string;
57
+ type?: "github" | "local";
58
+ localPath?: string;
59
+ }
60
+ interface ConversationConfig {
61
+ systemPrompt?: string;
62
+ northflareSystemPrompt?: string;
63
+ systemPromptMode?: "append" | "replace";
64
+ accessToken?: string;
65
+ accessKey?: string;
66
+ workspaceId?: string;
67
+ githubToken?: string;
68
+ taskConcurrent?: boolean;
69
+ useWorktrees?: boolean;
70
+ anthropicApiKey?: string;
71
+ apiKey?: string;
72
+ openRouterApiKey?: string;
73
+ groqApiKey?: string;
74
+ providerType?: string;
75
+ agentProviderType?: string;
76
+ mcpServers?: Record<string, any>;
77
+ repository?: RepositoryInfo;
78
+ sessionId?: string;
79
+ runnerRepoPath?: string;
80
+ codexAuth?: CodexAuthConfig;
81
+ agent?: string;
82
+ maxTurns?: number;
83
+ subAgentTypes?: Record<string, any>;
84
+ }
85
+ interface ConversationContext {
86
+ conversationId: string;
87
+ agentSessionId: string;
88
+ conversationObjectType: "Task" | "TaskPlan" | "ProjectStep";
89
+ conversationObjectId: string;
90
+ taskId?: string;
91
+ workspaceId?: string;
92
+ status: "starting" | "active" | "stopping" | "stopped" | "error";
93
+ config: ConversationConfig;
94
+ startedAt: Date;
95
+ lastActivityAt: Date;
96
+ conversation?: Conversation | Thread | AgentConversation;
97
+ provider?: "claude" | "openai" | "openrouter" | "groq" | string;
98
+ metadata?: Record<string, any>;
99
+ summary?: string | null;
100
+ model: string;
101
+ globalInstructions: string;
102
+ workspaceInstructions: string;
103
+ permissionsMode: string;
104
+ }
105
+ interface CodexAuthConfig {
106
+ accessToken: string;
107
+ idToken: string;
108
+ accountId: string;
109
+ lastRefresh?: string | null;
110
+ }
111
+ interface Message {
112
+ content: any;
113
+ role?: "user" | "assistant";
114
+ }
115
+
116
+ /**
117
+ * RepositoryManager - Manages Git repository checkouts and workspace isolation
118
+ *
119
+ * This component handles all Git operations for the runner, including:
120
+ * - Cloning repositories with authentication
121
+ * - Updating repositories to latest state
122
+ * - Workspace isolation via separate directories
123
+ * - Cleanup of old repositories
124
+ * - Error handling for Git operations
125
+ */
126
+
127
+ declare class RepositoryManager {
128
+ private repositories;
129
+ protected repoBasePath: string;
130
+ private runner;
131
+ private git;
132
+ constructor(runner: IRunnerApp);
133
+ checkoutRepository(workspaceId: string, repoUrl: string, branch: string, githubToken?: string): Promise<string>;
134
+ /**
135
+ * Checkout a local repository (bypasses Git operations)
136
+ * Used for local workspaces that point to existing directories on the filesystem
137
+ */
138
+ checkoutLocalRepository(workspaceId: string, localRepoPath: string): Promise<string>;
139
+ getWorkspacePath(workspaceId: string): Promise<string>;
140
+ private updateRepository;
141
+ cleanupRepository(workspaceId: string): Promise<void>;
142
+ cleanupOldRepositories(maxAge?: number): Promise<void>;
143
+ protected executeGit(args: string[], cwd?: string): Promise<void>;
144
+ protected getAuthenticatedUrl(repoUrl: string, githubToken?: string): string;
145
+ protected ensureDirectory(dirPath: string): Promise<void>;
146
+ protected cleanupDirectory(dirPath: string): Promise<void>;
147
+ /**
148
+ * Get statistics about managed repositories
149
+ */
150
+ getRepositoryStats(): {
151
+ total: number;
152
+ workspaceIds: string[];
153
+ oldestAccess: Date | null;
154
+ newestAccess: Date | null;
155
+ };
156
+ /**
157
+ * Check if a workspace has an existing repository
158
+ */
159
+ hasRepository(workspaceId: string): boolean;
160
+ /**
161
+ * Get repository info for a workspace
162
+ */
163
+ getRepository(workspaceId: string): WorkspaceRepository | undefined;
164
+ }
165
+
166
+ /**
167
+ * EnhancedRepositoryManager - Advanced Git repository management with worktree support
168
+ *
169
+ * This enhanced version builds upon the original RepositoryManager to add:
170
+ * - Task-level Git isolation through worktrees
171
+ * - Git operations (stage, commit, push, merge, rebase)
172
+ * - State persistence and recovery
173
+ * - Backward compatibility with workspace-based operations
174
+ *
175
+ * Directory structure:
176
+ * /workspace/repos/<owner>__<repo>/
177
+ * control/ # Primary clone (.git directory owner)
178
+ * .git/
179
+ * worktrees/
180
+ * workspace_<workspaceId>/ # Backward compatibility - workspace default branch
181
+ * task_<taskId>/ # New - isolated task worktrees
182
+ * state.json # Persistent state mapping
183
+ */
184
+
185
+ interface TaskHandle {
186
+ taskId: string;
187
+ worktreePath: string;
188
+ branch: string;
189
+ baseBranch: string;
190
+ }
191
+ interface RemoveOptions {
192
+ preserveBranch?: boolean;
193
+ force?: boolean;
194
+ }
195
+ interface GitAuthor {
196
+ name: string;
197
+ email: string;
198
+ }
199
+ interface RebaseResult {
200
+ success: boolean;
201
+ conflicts?: string[];
202
+ error?: string;
203
+ }
204
+ interface MergeResult {
205
+ success: boolean;
206
+ conflicts?: string[];
207
+ mergedCommit?: string;
208
+ error?: string;
209
+ }
210
+ type MergeMode = "ff-only" | "no-ff" | "squash";
211
+ type TaskIntegrationResult = {
212
+ success: true;
213
+ mergedCommit?: string;
214
+ } | {
215
+ success: false;
216
+ phase: "rebase" | "merge";
217
+ conflicts?: string[];
218
+ error?: string;
219
+ conflictWorkdir: string;
220
+ };
221
+ interface TaskGitState {
222
+ taskId: string;
223
+ workspaceId?: string;
224
+ branch: string;
225
+ baseBranch: string;
226
+ lastCommit?: string;
227
+ commitCount?: number;
228
+ worktreePath: string;
229
+ status: "active" | "conflicted" | "merged" | "abandoned";
230
+ createdAt: Date;
231
+ updatedAt: Date;
232
+ }
233
+ declare class EnhancedRepositoryManager extends RepositoryManager {
234
+ private repoStates;
235
+ private stateFilePath;
236
+ private legacyStateFilePath;
237
+ private repoLocks;
238
+ private taskWorktreesBasePath;
239
+ constructor(runner: IRunnerApp);
240
+ /**
241
+ * Get repository key from owner and repo name
242
+ */
243
+ private getRepoKey;
244
+ private parseRepoKey;
245
+ private findTaskStateEntry;
246
+ private withRepoLock;
247
+ /**
248
+ * Ensure control repository exists
249
+ */
250
+ private ensureControlRepository;
251
+ /**
252
+ * Create a task-specific worktree for local workspaces
253
+ */
254
+ createLocalTaskHandle(taskId: string, localPath: string): Promise<TaskHandle>;
255
+ /**
256
+ * Create a task-specific worktree
257
+ */
258
+ createTaskWorktree(taskId: string, workspaceId: string, repoUrl: string, baseBranch?: string, githubToken?: string): Promise<TaskHandle>;
259
+ private ensureInitialCommitOnBranch;
260
+ /**
261
+ * Remove a task worktree
262
+ */
263
+ removeTaskWorktree(taskId: string, options?: RemoveOptions): Promise<void>;
264
+ /**
265
+ * Stage all changes in a task worktree
266
+ */
267
+ stageAll(taskId: string): Promise<void>;
268
+ /**
269
+ * Commit changes in a task worktree
270
+ */
271
+ commit(taskId: string, message: string, author?: GitAuthor): Promise<string>;
272
+ /**
273
+ * Create a new branch for a task
274
+ */
275
+ createBranch(taskId: string, branchName: string): Promise<void>;
276
+ /**
277
+ * Rebase a task branch onto target branch
278
+ */
279
+ rebaseTask(taskId: string, targetBranch: string): Promise<RebaseResult>;
280
+ /**
281
+ * Merge a task branch into target branch
282
+ */
283
+ mergeTask(taskId: string, targetBranch: string, mode?: MergeMode): Promise<MergeResult>;
284
+ private mergeTaskUnlocked;
285
+ getTaskRepoInfo(taskId: string): Promise<{
286
+ repoKey: string;
287
+ controlPath: string;
288
+ worktreePath: string;
289
+ branch: string;
290
+ baseBranch: string;
291
+ } | null>;
292
+ /**
293
+ * Fast-forward (or hard reset) the shared workspace worktree to a branch tip after a task merge.
294
+ * This keeps the "workspace" checkout in sync with concurrent task integrations.
295
+ *
296
+ * We only update existing workspace worktrees and only when they're clean to avoid
297
+ * clobbering any active non-concurrent task that might be using the workspace checkout.
298
+ */
299
+ syncWorkspaceWorktree(workspaceId: string, repoUrl: string, branch: string): Promise<void>;
300
+ isTaskBranchMerged(taskId: string, targetBranch: string): Promise<boolean>;
301
+ pushBranch(taskId: string, branch: string): Promise<void>;
302
+ integrateTask(taskId: string, targetBranch: string, mode?: MergeMode): Promise<TaskIntegrationResult>;
303
+ /**
304
+ * Get task Git state
305
+ */
306
+ getTaskState(taskId: string): Promise<TaskGitState | null>;
307
+ /**
308
+ * Update task state
309
+ */
310
+ private updateTaskState;
311
+ /**
312
+ * Update task state by task ID
313
+ */
314
+ private updateTaskStateByTaskId;
315
+ /**
316
+ * Persist state to disk
317
+ */
318
+ persistState(): Promise<void>;
319
+ /**
320
+ * Restore state from disk
321
+ */
322
+ restoreState(): Promise<void>;
323
+ private migrateLegacyStateFileIfNeeded;
324
+ /**
325
+ * Override parent's checkoutRepository to use worktrees for backward compatibility
326
+ */
327
+ checkoutRepository(workspaceId: string, repoUrl: string, branch: string, githubToken?: string): Promise<string>;
328
+ }
329
+
330
+ /**
331
+ * ClaudeManager - Manages Claude conversations using SDK-native patterns
332
+ *
333
+ * This component handles stateful conversation lifecycle management, maintaining
334
+ * persistent conversation instances indexed by taskId. Uses the SDK's native
335
+ * capabilities including the builder pattern, native session management, and
336
+ * built-in streaming instead of custom wrappers.
337
+ *
338
+ * Key improvements:
339
+ * - Uses claude() builder pattern for simplified configuration
340
+ * - Native session management with withSessionId()
341
+ * - Direct AsyncGenerator streaming without custom wrappers
342
+ * - SDK's onProcessComplete() for proper cleanup
343
+ * - Simplified error handling while maintaining compatibility
344
+ */
345
+
346
+ declare class ClaudeManager {
347
+ private runner;
348
+ private repositoryManager;
349
+ constructor(runner: IRunnerApp, repositoryManager: EnhancedRepositoryManager);
350
+ private setupInternalMcpServer;
351
+ startConversation(conversationObjectType: "Task" | "TaskPlan" | "ProjectStep", conversationObjectId: string, config: ConversationConfig, initialMessages: Message[], conversationData?: {
352
+ id: string;
353
+ objectType: string;
354
+ objectId: string;
355
+ model: string;
356
+ summary?: string | null;
357
+ globalInstructions: string;
358
+ workspaceInstructions: string;
359
+ permissionsMode: string;
360
+ agentSessionId: string;
361
+ systemPrompt?: string;
362
+ northflareSystemPrompt?: string;
363
+ systemPromptMode?: "append" | "replace";
364
+ }): Promise<ConversationContext>;
365
+ private getInstructionPrefix;
366
+ private _handleRunCompletion;
367
+ private _resumeForGitConflictResolution;
368
+ stopConversation(agentSessionId: string, context: ConversationContext, isRunnerShutdown?: boolean, reason?: string): Promise<void>;
369
+ resumeConversation(conversationObjectType: "Task" | "TaskPlan" | "ProjectStep", conversationObjectId: string, agentSessionId: string, config: ConversationConfig, conversationData?: any, resumeMessage?: string): Promise<string>;
370
+ private _finalizeConversation;
371
+ sendUserMessage(conversationId: string, content: any, config?: ConversationConfig, conversationObjectType?: "Task" | "TaskPlan" | "ProjectStep", conversationObjectId?: string, conversation?: any, _agentSessionIdOverride?: string): Promise<void>;
372
+ private fetchGithubTokens;
373
+ private _handleConversationError;
374
+ private classifyError;
375
+ /**
376
+ * Normalize arbitrary content shapes into a plain string for the CLI
377
+ */
378
+ private normalizeToText;
379
+ /**
380
+ * Normalize arbitrary content shapes into content blocks array for multimodal support.
381
+ * Returns the array of content blocks if the content contains image or document blocks,
382
+ * otherwise returns null to indicate text-only content.
383
+ */
384
+ private normalizeToContentBlocks;
385
+ private handleStreamedMessage;
386
+ }
387
+
388
+ type ConversationDetails = {
389
+ id: string;
390
+ objectType: string;
391
+ objectId: string;
392
+ model: string;
393
+ summary?: string | null;
394
+ globalInstructions: string;
395
+ workspaceInstructions: string;
396
+ permissionsMode: string;
397
+ agentSessionId?: string;
398
+ workspaceId?: string;
399
+ threadId?: string;
400
+ systemPrompt?: string;
401
+ northflareSystemPrompt?: string;
402
+ systemPromptMode?: "append" | "replace";
403
+ };
404
+ declare class CodexManager {
405
+ private runner;
406
+ private repositoryManager;
407
+ private threadStates;
408
+ constructor(runner: IRunnerApp, repositoryManager: EnhancedRepositoryManager);
409
+ startConversation(conversationObjectType: "Task" | "TaskPlan" | "ProjectStep", conversationObjectId: string, config: ConversationConfig, initialMessages: Message[], conversationData?: ConversationDetails, provider?: "openai" | "openrouter" | "groq"): Promise<ConversationContext>;
410
+ stopConversation(_agentSessionId: string, context: ConversationContext, isRunnerShutdown?: boolean, reason?: string): Promise<void>;
411
+ resumeConversation(conversationObjectType: "Task" | "TaskPlan" | "ProjectStep", conversationObjectId: string, agentSessionId: string, config: ConversationConfig, conversationData?: ConversationDetails, resumeMessage?: string, provider?: "openai" | "openrouter" | "groq"): Promise<string>;
412
+ sendUserMessage(conversationId: string, content: any, config?: ConversationConfig, conversationObjectType?: "Task" | "TaskPlan" | "ProjectStep", conversationObjectId?: string, conversation?: any, agentSessionIdOverride?: string, provider?: "openai" | "openrouter" | "groq"): Promise<void>;
413
+ private _handleRunCompletion;
414
+ private _resumeForGitConflictResolution;
415
+ private buildEnvVars;
416
+ private ensureCodexAuthHome;
417
+ private buildPromptForMessage;
418
+ private getInstructionPrefix;
419
+ private formatInitialMessages;
420
+ private buildInitialInput;
421
+ private launchTurn;
422
+ private streamThreadEvents;
423
+ private abortActiveRun;
424
+ private handleThreadEvent;
425
+ private forwardItemEvent;
426
+ private normalizeItemEvent;
427
+ private sendAgentMessage;
428
+ private handleThreadStarted;
429
+ private mapSandboxMode;
430
+ private shouldEnableNetwork;
431
+ private getAdditionalDirectories;
432
+ private buildConfigOverridesFromMcp;
433
+ /**
434
+ * Build Codex config overrides for OpenRouter provider.
435
+ * These correspond to the Codex CLI flags:
436
+ * -c model_provider=openrouter
437
+ * -c model_providers.openrouter.name=openrouter
438
+ * -c model_providers.openrouter.base_url=https://openrouter.ai/api/v1
439
+ * -c model_providers.openrouter.env_key=OPENROUTER_API_KEY
440
+ */
441
+ private buildOpenRouterConfigOverrides;
442
+ private normalizeMcpServersForCodex;
443
+ private buildMcpToolName;
444
+ private logRawThreadEvent;
445
+ private safeStringify;
446
+ private buildToolUseId;
447
+ private stripAuthorizationHeader;
448
+ private flattenOverrideObject;
449
+ private resolveWorkspacePath;
450
+ private fetchGithubTokens;
451
+ private generateToolToken;
452
+ /**
453
+ * Detect whether incoming content contains multimodal blocks (image/document).
454
+ */
455
+ private hasMultimodalContent;
456
+ /**
457
+ * Normalize incoming content into the Codex SDK Input shape.
458
+ * - Text-only -> single string (lets SDK do fast path)
459
+ * - Multimodal -> [{ text }, ...{ local_image }]
460
+ */
461
+ private normalizeToInput;
462
+ /**
463
+ * Download an image (http(s) or data URL) to a temp file and return the path.
464
+ */
465
+ private downloadImageToTemp;
466
+ private writeBufferToTemp;
467
+ private inferExtensionFromUrl;
468
+ private mimeToExtension;
469
+ private normalizeToText;
470
+ private normalizeSessionId;
471
+ private resolveSessionId;
472
+ private isAbortError;
473
+ private _finalizeConversation;
474
+ private _handleConversationError;
475
+ private generateMessageId;
476
+ }
477
+
478
+ /**
479
+ * NorthflareAgentManager - Manages conversations using the @northflare/agent SDK
480
+ *
481
+ * Mirrors the existing Claude integration but targets OpenRouter-style models
482
+ * via the Northflare Agent SDK. Lifecycle, repository handling, and message
483
+ * normalization stay aligned with the existing managers so downstream
484
+ * interfaces remain compatible.
485
+ */
486
+
487
+ declare class NorthflareAgentManager {
488
+ private runner;
489
+ private repositoryManager;
490
+ private submitToolUseIds;
491
+ constructor(runner: IRunnerApp, repositoryManager: EnhancedRepositoryManager);
492
+ private setupInternalMcpServer;
493
+ private buildSubAgentConfig;
494
+ startConversation(conversationObjectType: "Task" | "TaskPlan" | "ProjectStep", conversationObjectId: string, config: ConversationConfig, initialMessages: Message[], conversationData?: {
495
+ id: string;
496
+ objectType: string;
497
+ objectId: string;
498
+ model: string;
499
+ summary?: string | null;
500
+ globalInstructions: string;
501
+ workspaceInstructions: string;
502
+ permissionsMode: string;
503
+ agentSessionId: string;
504
+ systemPrompt?: string;
505
+ northflareSystemPrompt?: string;
506
+ systemPromptMode?: "append" | "replace";
507
+ }, provider?: "openrouter" | "groq"): Promise<ConversationContext>;
508
+ stopConversation(agentSessionId: string, context: ConversationContext, isRunnerShutdown?: boolean, reason?: string): Promise<void>;
509
+ resumeConversation(conversationObjectType: "Task" | "TaskPlan" | "ProjectStep", conversationObjectId: string, agentSessionId: string, config: ConversationConfig, conversationData?: any, resumeMessage?: string, provider?: "openrouter" | "groq"): Promise<string>;
510
+ private _handleRunCompletion;
511
+ private _resumeForGitConflictResolution;
512
+ private _finalizeConversation;
513
+ sendUserMessage(conversationId: string, content: any, config?: ConversationConfig, conversationObjectType?: "Task" | "TaskPlan" | "ProjectStep", conversationObjectId?: string, conversation?: any, _agentSessionIdOverride?: string): Promise<void>;
514
+ private fetchGithubTokens;
515
+ private _handleConversationError;
516
+ private classifyError;
517
+ private normalizeModel;
518
+ /**
519
+ * Check if content contains multimodal blocks (images or documents)
520
+ */
521
+ private hasMultimodalContent;
522
+ /**
523
+ * Normalize content for the SDK, preserving multimodal blocks when present.
524
+ * Returns either a string (text-only) or an array of content blocks (multimodal).
525
+ */
526
+ private normalizeContentForSDK;
527
+ /**
528
+ * Normalize arbitrary content shapes into a plain string for the CLI
529
+ */
530
+ private normalizeToText;
531
+ private handleStreamedMessage;
532
+ }
533
+
534
+ /**
535
+ * Interface for RunnerApp to ensure compatibility between different implementations
536
+ */
537
+
538
+ interface IRunnerApp {
539
+ notify(method: string, params: any): Promise<void>;
540
+ sendToOrchestrator(message: JsonRpcMessage): Promise<any>;
541
+ getConversationContext(conversationId: string): ConversationContext | undefined;
542
+ applyConversationSummary(conversationId: string, summary: string | null): void;
543
+ consumePendingConversationSummary(conversationId: string): string | undefined;
544
+ wasConversationCompleted(conversationId: string): boolean;
545
+ markConversationCompleted(conversationId: string): void;
546
+ get config_(): RunnerConfig;
547
+ get activeConversations_(): Map<string, ConversationContext>;
548
+ get claudeManager_(): ClaudeManager;
549
+ get codexManager_(): CodexManager;
550
+ get northflareAgentManager_(): NorthflareAgentManager;
551
+ get repositoryManager_(): EnhancedRepositoryManager;
552
+ getConfigPath?(): string | undefined;
553
+ getWorkspacePath?(): string | undefined;
554
+ getRunnerId(): string | undefined;
555
+ getRunnerUid(): string | null;
556
+ getLastProcessedAt(): Date | null;
557
+ getIsActiveRunner(): boolean;
558
+ setIsActiveRunner(active: boolean): void;
559
+ setLastProcessedAt(timestamp: Date | null): void;
560
+ getPreHandoffConversations(): Set<string>;
561
+ updateLastProcessedAt?(timestamp: Date | null): Promise<void>;
562
+ replaceRunnerRepos?(repos: RunnerRepo[]): Promise<void>;
563
+ checkForUpdate(serverVersion: string): Promise<void>;
564
+ onConversationEnd(): Promise<void>;
565
+ hasPendingUpdate(): boolean;
566
+ }
567
+
568
+ /**
569
+ * Main type definitions for the runner app
570
+ */
571
+
572
+ type RetryStrategy = "none" | "interval" | "exponential";
573
+ interface RunnerRepo {
574
+ uuid?: string;
575
+ name: string;
576
+ path: string;
577
+ external?: boolean;
578
+ }
579
+ interface RunnerConfig {
580
+ runnerId?: string;
581
+ orchestratorUrl: string;
582
+ dataDir: string;
583
+ workspacePath?: string;
584
+ heartbeatInterval: number;
585
+ retryStrategy: RetryStrategy;
586
+ retryIntervalSecs: number;
587
+ retryDurationSecs: number;
588
+ runnerRepos?: RunnerRepo[];
589
+ inactivityTimeoutMs?: number;
590
+ inactivityTimeoutDisplay?: string;
591
+ }
592
+ interface RunnerConfigFile {
593
+ orchestratorUrl?: string;
594
+ dataDir?: string;
595
+ workspacePath?: string;
596
+ workspaceDir?: string;
597
+ heartbeatInterval?: number;
598
+ retryStrategy?: RetryStrategy;
599
+ retryIntervalSecs?: number;
600
+ retryDurationSecs?: number;
601
+ runnerRepos?: Record<string, RunnerRepo[]>;
602
+ }
603
+ interface WorkspaceRepository {
604
+ workspaceId: string;
605
+ repoUrl: string;
606
+ branch: string;
607
+ localPath: string;
608
+ lastAccessed: Date;
609
+ }
610
+ interface EnvironmentConfig {
611
+ NORTHFLARE_RUNNER_TOKEN: string;
612
+ NORTHFLARE_WORKSPACE_PATH?: string;
613
+ NORTHFLARE_ORCHESTRATOR_URL: string;
614
+ NORTHFLARE_RUNNER_DEBUG?: string;
615
+ DEBUG?: string;
616
+ }
617
+
618
+ /**
619
+ * Main RunnerApp class - entry point and lifecycle manager for the runner app
620
+ * Updated to use SSE for real-time messaging instead of ElectricSQL
621
+ */
622
+
623
+ declare class RunnerApp implements IRunnerApp {
624
+ private messageHandler;
625
+ private claudeManager;
626
+ private codexManager;
627
+ private northflareAgentManager;
628
+ private repositoryManager;
629
+ private stateManager;
630
+ private updateCoordinator;
631
+ private agentConversations;
632
+ private config;
633
+ private configPath?;
634
+ private runnerReposCachePath?;
635
+ private heartbeatInterval?;
636
+ private heartbeatInFlight;
637
+ private isRunning;
638
+ private isRegistered;
639
+ private delayFn;
640
+ private runnerUid;
641
+ private lastProcessedAt;
642
+ private isActiveRunner;
643
+ private preHandoffConversations;
644
+ private completedConversations;
645
+ private static readonly COMPLETED_CONVERSATION_TTL_MS;
646
+ private pendingConversationSummaries;
647
+ constructor(config: RunnerConfig, configPath?: string);
648
+ private fetchRunnerId;
649
+ private initializeComponents;
650
+ start(): Promise<void>;
651
+ stop(): Promise<void>;
652
+ notify(method: string, params: any): Promise<void>;
653
+ sendToOrchestrator(message: JsonRpcMessage): Promise<any>;
654
+ getConversationContext(conversationId: string): ConversationContext | undefined;
655
+ applyConversationSummary(conversationId: string, summary: string | null): void;
656
+ consumePendingConversationSummary(conversationId: string): string | undefined;
657
+ /**
658
+ * Check if a conversation was recently completed (to prevent restart on catch-up)
659
+ */
660
+ wasConversationCompleted(conversationId: string): boolean;
661
+ /**
662
+ * Mark a conversation as completed to prevent restart on catch-up
663
+ */
664
+ markConversationCompleted(conversationId: string): void;
665
+ /**
666
+ * Clean up expired completed conversation entries
667
+ */
668
+ private cleanupCompletedConversations;
669
+ private registerRunner;
670
+ private registerWithRetry;
671
+ private sendToOrchestratorWithRetry;
672
+ private startHeartbeat;
673
+ private stopAllConversations;
674
+ updateLastProcessedAt(timestamp: Date | null): Promise<void>;
675
+ get config_(): RunnerConfig;
676
+ get activeConversations_(): Map<string, ConversationContext>;
677
+ get claudeManager_(): ClaudeManager;
678
+ get codexManager_(): CodexManager;
679
+ get northflareAgentManager_(): NorthflareAgentManager;
680
+ get repositoryManager_(): EnhancedRepositoryManager;
681
+ getConfigPath(): string | undefined;
682
+ getRunnerId(): string | undefined;
683
+ getRunnerUid(): string | null;
684
+ getLastProcessedAt(): Date | null;
685
+ getIsActiveRunner(): boolean;
686
+ setIsActiveRunner(active: boolean): void;
687
+ setLastProcessedAt(timestamp: Date | null): void;
688
+ getPreHandoffConversations(): Set<string>;
689
+ setDelayFunction(fn: (ms: number) => Promise<void>): void;
690
+ getWorkspacePath(): string | undefined;
691
+ /**
692
+ * Check if an update is available and trigger update process if needed.
693
+ * Called by message handler when a message includes expectedRunnerVersion.
694
+ */
695
+ checkForUpdate(serverVersion: string): Promise<void>;
696
+ /**
697
+ * Notify the update coordinator that a conversation has ended.
698
+ * If there's a pending update and this was the last active conversation,
699
+ * the update will be triggered.
700
+ */
701
+ onConversationEnd(): Promise<void>;
702
+ /**
703
+ * Check if there's a pending update waiting for conversations to complete.
704
+ */
705
+ hasPendingUpdate(): boolean;
706
+ replaceRunnerRepos(repos: RunnerRepo[]): Promise<void>;
707
+ private saveRunnerRepoCache;
708
+ private loadRunnerRepoCache;
709
+ private isRepoAllowed;
710
+ private prepareRunnerRepos;
711
+ private refreshRunnerReposFromServer;
712
+ private getManagerForContext;
713
+ }
714
+
715
+ /**
716
+ * Configuration management utilities
717
+ */
718
+
719
+ declare class ConfigManager {
720
+ private static DEFAULT_CONFIG;
721
+ private static resolveDefaultDataDir;
722
+ private static getDefaultConfigPath;
723
+ /**
724
+ * Load configuration without parsing command line arguments
725
+ * Used when arguments have already been parsed by the CLI
726
+ */
727
+ static loadConfig(configPath?: string, options?: {
728
+ promptForWorkspacePath?: boolean;
729
+ }): Promise<RunnerConfig>;
730
+ /**
731
+ * Parse command line arguments and load configuration
732
+ */
733
+ static parseArgsAndLoadConfig(argv: string[]): Promise<RunnerConfig>;
734
+ /**
735
+ * Validate required environment variables
736
+ */
737
+ private static validateEnvironment;
738
+ /**
739
+ * Load configuration from environment variables
740
+ */
741
+ private static loadFromEnvironment;
742
+ /**
743
+ * Load configuration from file
744
+ */
745
+ private static loadConfigFile;
746
+ private static promptForWorkspacePath;
747
+ private static normalizeWorkspacePath;
748
+ private static persistConfigFile;
749
+ /**
750
+ * Validate final configuration
751
+ */
752
+ private static validateConfig;
753
+ /**
754
+ * Get all environment configuration
755
+ */
756
+ static getEnvironmentConfig(): EnvironmentConfig;
757
+ /**
758
+ * Save configuration file with updated data
759
+ */
760
+ static saveConfigFile(configPath: string, config: any): Promise<void>;
761
+ }
762
+
1
763
  /**
2
764
  * Main entry point for the Northflare Runner App
3
765
  */
4
766
  declare let isShuttingDown: boolean;
5
767
  declare function main(): Promise<void>;
6
- export { RunnerApp } from './runner-sse.js';
7
- export { ConfigManager } from './utils/config.js';
8
- export * from './types/index.js';
9
- export { main, isShuttingDown };
10
- //# sourceMappingURL=index.d.ts.map
768
+
769
+ export { type AgentConversation, type CodexAuthConfig, ConfigManager, type ConversationConfig, type ConversationContext, type EnvironmentConfig, type IRunnerApp, type JsonRpcError, type JsonRpcMessage, type Message, type MethodHandler, type RepositoryInfo, type RetryStrategy, RunnerApp, type RunnerConfig, type RunnerConfigFile, type RunnerMessage, type RunnerRepo, type WorkspaceRepository, isShuttingDown, main };