@rallycry/conveyor-agent 6.4.2 → 7.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,303 +1,272 @@
1
1
  import * as _project_shared from '@project/shared';
2
- import { AgentRunnerStatus, MultimodalBlock, ProjectEnvironmentStatus, ChatMessageResponse, TaskFileResponse, TaskContext, AgentEvent, AgentQuestion, IncomingMessagePayload, SetModePayload, AgentMode, SubtaskCreatePayload, SubtaskUpdateFields, SubtaskResponse, StartChildCloudBuildResponse, TaskLookupResponse, UpdateTaskPropertiesPayload, IconListItem, GenerateIconResponse, TaskPropertiesResponse, TriggerIdentificationResponse, ModeTransitionPayload, DebugSessionState, DebugSessionSummary, IncidentDTO, TaskIncidentDTO, ResourceTierName, ScaleUpResponse, TaskDependencySummary, QueryGcpLogsResponse, TagAuditRunnerRequest, TagAuditRunnerResponse, TagAuditProgressActivity, DebugTelemetryEvent } from '@project/shared';
3
- export { AgentEvent, ChatMessage, DebugBreakpointHit, DebugModeEvent, TaskContext, TaskFileContext } from '@project/shared';
2
+ import { AgentSessionServiceMethods, AgentMode, AgentQuestion, AgentRunnerStatus, DebugTelemetryEvent, DebugSessionSummary } from '@project/shared';
3
+ export * from '@project/shared';
4
4
  import { ChildProcess } from 'node:child_process';
5
5
 
6
- /**
7
- * Harness-neutral types for agent query execution.
8
- *
9
- * These types abstract the underlying agent SDK so that the runner,
10
- * execution, and tool layers never reference SDK-specific imports
11
- * directly. The only place that should import from
12
- * `@anthropic-ai/claude-agent-sdk` is `harness/claude-code/`.
13
- */
14
-
15
- interface HarnessUserMessage {
16
- type: "user";
17
- session_id: string;
18
- message: {
19
- role: "user";
20
- content: string | unknown[];
21
- };
22
- parent_tool_use_id: null;
6
+ interface ModelUsageEntry {
7
+ model: string;
8
+ inputTokens: number;
9
+ outputTokens: number;
10
+ cacheReadInputTokens: number;
11
+ cacheCreationInputTokens: number;
12
+ costUSD: number;
23
13
  }
24
14
 
25
- interface AgentRunnerConfig {
26
- conveyorApiUrl: string;
15
+ interface AgentConnectionConfig {
16
+ apiUrl: string;
27
17
  taskToken: string;
28
- taskId: string;
29
- model: string;
30
- instructions: string;
31
- workspaceDir: string;
32
- mode?: _project_shared.RunnerMode;
33
- isAuto?: boolean;
34
- agentSettings?: _project_shared.AgentSettings;
18
+ sessionId: string;
19
+ runnerMode?: "task" | "pm" | "code-review";
35
20
  }
36
- interface AgentRunnerCallbacks {
37
- onEvent: (event: _project_shared.AgentEvent) => void | Promise<void>;
38
- onStatusChange: (status: _project_shared.AgentRunnerStatus) => void | Promise<void>;
21
+ interface IncomingMessage {
22
+ content: string;
23
+ userId: string;
24
+ files?: Array<{
25
+ name: string;
26
+ content: string;
27
+ mimeType?: string;
28
+ }>;
39
29
  }
40
-
41
- declare class AgentRunner {
42
- private config;
43
- private connection;
44
- private callbacks;
45
- private _state;
46
- private stopped;
47
- private interrupted;
48
- private inputResolver;
49
- private pendingMessages;
50
- private setupLog;
51
- private heartbeatTimer;
52
- private taskContext;
53
- private planSync;
54
- private costTracker;
55
- private worktreeActive;
56
- private agentMode;
57
- private hasExitedPlanMode;
58
- private pendingModeRestart;
59
- private pendingModeAutoStart;
60
- private sessionIds;
61
- private lastQueryModeRestart;
62
- private startCommandStarted;
63
- private prNudgeCount;
64
- private idleTimer;
65
- private idleCheckInterval;
66
- private conveyorConfig;
67
- private _queryHost;
68
- private tunnelClient;
69
- private harness;
70
- constructor(config: AgentRunnerConfig, callbacks: AgentRunnerCallbacks);
71
- get state(): AgentRunnerStatus;
72
- private get effectiveAgentMode();
73
- private setState;
74
- private startHeartbeat;
75
- private stopHeartbeat;
76
- private clearIdleTimers;
77
- start(): Promise<void>;
78
- private tryInitWorktree;
79
- private fetchAndInitContext;
80
- /**
81
- * For auto-mode tasks, bypass planning if the task is already past Planning
82
- * or if it's still in Planning but has all required properties set (e.g. from
83
- * a prior PM discovery session).
84
- */
85
- private tryAutoModeBypass;
86
- private transitionToBuilding;
87
- private tryPostContextWorktree;
88
- private startPreviewTunnel;
89
- private activateWorktree;
90
- private checkoutWorktreeBranch;
91
- private needsPRNudge;
92
- private maybeSendPRNudge;
93
- private sendPRNudgeQuery;
94
- private executeInitialMode;
95
- private runQuerySafe;
96
- private handleModeRestartCycle;
97
- private runCoreLoop;
98
- private handleRunStartCommand;
99
- private logEffectiveSettings;
100
- private injectHumanMessage;
101
- private waitForMessage;
102
- private waitForUserContent;
103
- createInputStream(initialPrompt: string | MultimodalBlock[]): AsyncGenerator<HarnessUserMessage, void, unknown>;
104
- private asQueryHost;
105
- private lastAnnouncedMode;
106
- private handleModeChange;
107
- private updateExitedPlanModeFlag;
108
- softStop(): void;
109
- stop(): void;
30
+ interface SetModeData {
31
+ agentMode: AgentMode;
110
32
  }
111
-
112
- interface ProjectRunnerConfig {
113
- conveyorApiUrl: string;
114
- projectToken: string;
115
- projectId: string;
116
- projectDir: string;
33
+ interface ApiKeyUpdateData {
34
+ apiKey: string;
35
+ isSubscription?: boolean;
117
36
  }
118
- declare class ProjectRunner {
119
- private connection;
120
- private projectDir;
121
- private activeAgents;
122
- private heartbeatTimer;
123
- private stopping;
124
- private resolveLifecycle;
125
- private chatSessionIds;
126
- private startCommandChild;
127
- private startCommandRunning;
128
- private setupComplete;
129
- private branchSwitchCommand;
130
- private commitWatcher;
131
- constructor(config: ProjectRunnerConfig);
132
- private checkoutWorkspaceBranch;
133
- private executeSetupCommand;
134
- private executeStartCommand;
135
- killStartCommand(): Promise<void>;
136
- restartStartCommand(): Promise<void>;
137
- getEnvironmentStatus(): ProjectEnvironmentStatus;
138
- private getCurrentBranch;
139
- private smartSync;
140
- private handleSwitchBranch;
141
- private handleSyncEnvironment;
142
- private handleGetEnvStatus;
143
- start(): Promise<void>;
144
- private setupSignalHandlers;
145
- private handleAssignment;
146
- private handleStopTask;
147
- stop(): Promise<void>;
148
- }
149
-
150
- declare class ConveyorConnection {
37
+ declare class AgentConnection {
151
38
  private socket;
152
- private config;
39
+ private readonly config;
153
40
  private eventBuffer;
154
41
  private flushTimer;
155
42
  private lastEmittedStatus;
156
- private static readonly EVENT_BATCH_MS;
157
43
  private earlyMessages;
158
44
  private earlyStop;
159
45
  private earlySoftStop;
160
46
  private earlyModeChanges;
161
- private chatMessageCallback;
47
+ private messageCallback;
162
48
  private stopCallback;
163
49
  private softStopCallback;
164
50
  private modeChangeCallback;
165
- private runStartCommandCallback;
166
- private pendingQuestionResolvers;
167
- constructor(config: AgentRunnerConfig);
51
+ private wakeCallback;
52
+ private apiKeyUpdateCallback;
53
+ constructor(config: AgentConnectionConfig);
54
+ get sessionId(): string;
55
+ get connected(): boolean;
56
+ call<M extends keyof AgentSessionServiceMethods>(method: M, payload: AgentSessionServiceMethods[M]["payload"]): Promise<AgentSessionServiceMethods[M]["response"]>;
168
57
  connect(): Promise<void>;
169
- fetchChatMessages(limit?: number, taskId?: string): Promise<ChatMessageResponse[]>;
170
- fetchTaskFiles(): Promise<TaskFileResponse[]>;
171
- fetchTaskFile(fileId: string): Promise<TaskFileResponse>;
172
- fetchTaskContext(): Promise<TaskContext>;
173
- sendEvent(event: AgentEvent): void;
174
- flushEvents(): void;
175
- updateStatus(status: string): void;
58
+ disconnect(): void;
59
+ onMessage(callback: (msg: IncomingMessage) => void): void;
60
+ onStop(callback: () => void): void;
61
+ onSoftStop(callback: () => void): void;
62
+ onModeChange(callback: (data: SetModeData) => void): void;
63
+ onWake(callback: () => void): void;
64
+ onApiKeyUpdate(callback: (data: ApiKeyUpdateData) => void): void;
65
+ emitStatus(status: string): void;
176
66
  postChatMessage(content: string): void;
177
- createPR(params: {
178
- title: string;
179
- body: string;
180
- baseBranch?: string;
181
- branch?: string;
182
- }): Promise<{
183
- url: string;
184
- number: number;
185
- }>;
186
- askUserQuestion(requestId: string, questions: AgentQuestion[]): Promise<Record<string, string>>;
187
- cancelPendingQuestions(): void;
188
- storeSessionId(sessionId: string): void;
67
+ sendHeartbeat(): void;
68
+ emitModeChanged(agentMode?: AgentMode | null): void;
189
69
  updateTaskFields(fields: {
190
70
  plan?: string;
191
71
  description?: string;
192
72
  }): void;
193
- onChatMessage(callback: (message: IncomingMessagePayload) => void): void;
194
- onStopRequested(callback: () => void): void;
195
- onSoftStopRequested(callback: () => void): void;
196
- onModeChange(callback: (data: SetModePayload) => void): void;
197
- onRunStartCommand(callback: () => void): void;
198
- private handleRunAuthTokenCommand;
199
- emitModeChanged(agentMode?: AgentMode | null): void;
73
+ storeSessionId(sdkSessionId: string): void;
74
+ sendTypingStart(): void;
75
+ sendTypingStop(): void;
200
76
  trackSpending(params: {
201
77
  agentId: string;
202
78
  sessionId: string;
203
79
  totalCostUsd: number;
204
80
  onSubscription: boolean;
205
- modelUsage?: {
206
- model: string;
207
- inputTokens: number;
208
- outputTokens: number;
209
- cacheReadInputTokens: number;
210
- cacheCreationInputTokens: number;
211
- costUSD: number;
212
- }[];
81
+ modelUsage?: ModelUsageEntry[];
213
82
  }): void;
214
- emitStatus(status: string): void;
215
83
  emitRateLimitPause(resetsAt: string): void;
216
- sendHeartbeat(): void;
217
- sendTypingStart(): void;
218
- sendTypingStop(): void;
219
- createSubtask(data: SubtaskCreatePayload): Promise<{
220
- id: string;
221
- }>;
222
- updateSubtask(subtaskId: string, fields: SubtaskUpdateFields): void;
223
- deleteSubtask(subtaskId: string): void;
224
- listSubtasks(): Promise<SubtaskResponse[]>;
225
- fetchCliHistory(taskId?: string, limit?: number, source?: string): Promise<{
226
- event: AgentEvent;
227
- time: string;
228
- }[]>;
229
- startChildCloudBuild(childTaskId: string): Promise<StartChildCloudBuildResponse>;
230
- approveAndMergePR(childTaskId: string): Promise<{
231
- merged: boolean;
232
- queued?: boolean;
233
- childTaskId: string;
234
- prNumber: number;
235
- }>;
236
- postChildChatMessage(childTaskId: string, content: string): Promise<void>;
237
- updateChildStatus(childTaskId: string, status: string): Promise<void>;
238
- stopChildBuild(childTaskId: string): Promise<void>;
239
- fetchTask(slugOrId: string): Promise<TaskLookupResponse>;
240
- updateTaskProperties(data: UpdateTaskPropertiesPayload): void;
241
- listIcons(): Promise<IconListItem[]>;
242
- generateTaskIcon(prompt: string, aspectRatio?: "auto" | "portrait" | "landscape" | "square"): Promise<GenerateIconResponse>;
243
- getTaskProperties(): Promise<TaskPropertiesResponse>;
244
- triggerIdentification(): Promise<TriggerIdentificationResponse>;
245
- refreshAuthToken(): Promise<boolean>;
246
- emitModeTransition(payload: ModeTransitionPayload): void;
247
- emitDebugStateChanged(state: DebugSessionState): void;
248
- emitDebugSessionComplete(summary: DebugSessionSummary): void;
249
- emitDebugReproduceRequested(hypothesis?: string): void;
84
+ updateStatus(status: string): void;
250
85
  emitCodeReviewResult(content: string, approved: boolean): void;
251
- searchIncidents(status?: string, source?: string): Promise<IncidentDTO[]>;
252
- getTaskIncidents(taskId?: string): Promise<TaskIncidentDTO[]>;
253
- requestScaleUp(tier: ResourceTierName, reason?: string): Promise<ScaleUpResponse>;
254
- addDependency(dependsOnSlugOrId: string): Promise<void>;
255
- removeDependency(dependsOnSlugOrId: string): Promise<void>;
256
- getDependencies(): Promise<TaskDependencySummary[]>;
257
- createFollowUpTask(data: {
258
- title: string;
259
- description?: string;
86
+ askUserQuestion(questions: AgentQuestion[]): Promise<Record<string, string>>;
87
+ getTaskProperties(): Promise<{
260
88
  plan?: string;
261
- storyPointValue?: number;
262
- }): Promise<{
263
- id: string;
264
- slug: string;
89
+ storyPointId?: string;
90
+ title?: string;
265
91
  }>;
266
- queryGcpLogs(params: {
267
- filter?: string;
268
- startTime?: string;
269
- endTime?: string;
270
- severity?: string;
271
- pageSize?: number;
272
- }): Promise<QueryGcpLogsResponse>;
273
- createSuggestion(title: string, description?: string, tagNames?: string[]): Promise<{
274
- id: string;
275
- merged: boolean;
276
- mergedIntoId?: string;
92
+ triggerIdentification(): Promise<{
93
+ identified: boolean;
277
94
  }>;
278
- voteSuggestion(suggestionId: string, value: 1 | -1): Promise<{
279
- score: number;
95
+ requestScaleUp(tier: string, reason?: string): Promise<{
96
+ scaled: boolean;
280
97
  }>;
281
- getSuggestions(status?: string, limit?: number): Promise<Array<{
282
- id: string;
283
- title: string;
284
- description: string | null;
285
- score: number;
286
- status: string;
287
- tags: string[];
288
- }>>;
289
- disconnect(): void;
98
+ refreshAuthToken(): Promise<boolean>;
99
+ sendEvent(event: Record<string, unknown>): void;
100
+ flushEvents(): void;
101
+ }
102
+
103
+ type ModeAction = {
104
+ type: "noop";
105
+ } | {
106
+ type: "restart_query";
107
+ newMode: AgentMode;
108
+ } | {
109
+ type: "soft_stop";
110
+ } | {
111
+ type: "start_auto";
112
+ };
113
+ interface ModeTaskContext {
114
+ status: string;
115
+ plan: string | null;
116
+ storyPointId: string | null;
117
+ isParentTask?: boolean;
118
+ model: string;
119
+ builderModel?: string | null;
120
+ githubPRUrl?: string | null;
121
+ }
122
+ declare class ModeController {
123
+ private _mode;
124
+ private _hasExitedPlanMode;
125
+ private _pendingModeRestart;
126
+ private _runnerMode;
127
+ private _isAuto;
128
+ constructor(initialMode: AgentMode, runnerMode?: "task" | "pm" | "code-review", isAuto?: boolean);
129
+ get mode(): AgentMode;
130
+ get hasExitedPlanMode(): boolean;
131
+ set hasExitedPlanMode(val: boolean);
132
+ get pendingModeRestart(): boolean;
133
+ set pendingModeRestart(val: boolean);
134
+ /** Effective mode accounting for PM/task defaults */
135
+ get effectiveMode(): AgentMode;
136
+ get isReadOnly(): boolean;
137
+ get isAutoPlanning(): boolean;
138
+ get isBuildCapable(): boolean;
139
+ /** Resolve the initial mode based on task context */
140
+ resolveInitialMode(context: ModeTaskContext): AgentMode;
141
+ /** Check if auto-mode can bypass planning (task already has plan + properties) */
142
+ canBypassPlanning(context: ModeTaskContext): boolean;
143
+ /** Handle mode change from server */
144
+ handleModeChange(newMode: AgentMode): ModeAction;
145
+ /** Handle ExitPlanMode call from the agent */
146
+ handleExitPlanMode(context: ModeTaskContext): ModeAction;
147
+ /** Check if pack runner behavior should be used */
148
+ isPackRunner(context: ModeTaskContext): boolean;
149
+ private transitionToBuilding;
150
+ private updateExitedPlanModeFlag;
151
+ }
152
+
153
+ interface LifecycleConfig {
154
+ /** Idle timeout before entering sleep mode (default: 30 min) */
155
+ idleTimeoutMs: number;
156
+ /** Grace period after sleep announcement before shutdown (default: 5s) */
157
+ sleepGracePeriodMs: number;
158
+ /** Heartbeat interval (default: 30s) */
159
+ heartbeatIntervalMs: number;
160
+ }
161
+ interface LifecycleCallbacks {
162
+ onHeartbeat: () => void;
163
+ onIdleTimeout: () => void;
164
+ onSleep: () => void;
165
+ onSleepGraceExpired: () => void;
166
+ onWake: () => void;
167
+ }
168
+ /** 30 min idle, 5s sleep grace, 30s heartbeat */
169
+ declare const DEFAULT_LIFECYCLE_CONFIG: LifecycleConfig;
170
+ declare class Lifecycle {
171
+ private readonly config;
172
+ private readonly callbacks;
173
+ private heartbeatTimer;
174
+ private idleTimer;
175
+ private idleCheckInterval;
176
+ private sleepShutdownTimer;
177
+ private _isSleeping;
178
+ constructor(config: LifecycleConfig, callbacks: LifecycleCallbacks);
179
+ get isSleeping(): boolean;
180
+ startHeartbeat(): void;
181
+ stopHeartbeat(): void;
182
+ startIdleTimer(): void;
183
+ cancelIdleTimer(): void;
184
+ private enterSleepMode;
185
+ /** Wake from sleep — cancels shutdown timer, resets idle */
186
+ wake(): void;
187
+ /** Cancel the sleep shutdown timer (e.g. when a message arrives) */
188
+ cancelSleepShutdown(): void;
189
+ destroy(): void;
190
+ private clearIdleTimers;
191
+ }
192
+
193
+ interface SessionRunnerConfig {
194
+ connection: AgentConnectionConfig;
195
+ agentMode?: AgentMode;
196
+ runnerMode?: "task" | "pm" | "code-review";
197
+ isAuto?: boolean;
198
+ workspaceDir: string;
199
+ model?: string;
200
+ lifecycle?: Partial<LifecycleConfig>;
201
+ }
202
+ interface SessionRunnerCallbacks {
203
+ onStatusChange: (status: AgentRunnerStatus) => void | Promise<void>;
204
+ onEvent: (event: Record<string, unknown>) => void | Promise<void>;
205
+ }
206
+ declare class SessionRunner {
207
+ readonly connection: AgentConnection;
208
+ readonly mode: ModeController;
209
+ readonly lifecycle: Lifecycle;
210
+ private readonly config;
211
+ private readonly callbacks;
212
+ private _state;
213
+ private stopped;
214
+ private interrupted;
215
+ private taskContext;
216
+ private fullContext;
217
+ private queryBridge;
218
+ private inputResolver;
219
+ private pendingMessages;
220
+ private prNudgeCount;
221
+ constructor(config: SessionRunnerConfig, callbacks: SessionRunnerCallbacks);
222
+ get state(): AgentRunnerStatus;
223
+ get sessionId(): string;
224
+ get isStopped(): boolean;
225
+ start(): Promise<void>;
226
+ private coreLoop;
227
+ private executeInitialMode;
228
+ private waitForMessage;
229
+ /** Inject a message (from connection callback or external source) */
230
+ injectMessage(msg: IncomingMessage): void;
231
+ stop(): void;
232
+ softStop(): void;
233
+ private static readonly MAX_PR_NUDGES;
234
+ private needsPRNudge;
235
+ private refreshTaskContext;
236
+ private maybeSendPRNudge;
237
+ private buildFullContext;
238
+ private createQueryBridge;
239
+ private wireConnectionCallbacks;
240
+ private setState;
241
+ private shutdown;
242
+ private logInitialization;
243
+ }
244
+
245
+ interface AgentRunnerConfig {
246
+ conveyorApiUrl: string;
247
+ taskToken: string;
248
+ taskId: string;
249
+ model: string;
250
+ instructions: string;
251
+ workspaceDir: string;
252
+ mode?: _project_shared.RunnerMode;
253
+ isAuto?: boolean;
254
+ agentSettings?: _project_shared.AgentSettings;
255
+ }
256
+ interface AgentRunnerCallbacks {
257
+ onEvent: (event: Record<string, unknown>) => void | Promise<void>;
258
+ onStatusChange: (status: string) => void | Promise<void>;
290
259
  }
291
260
 
292
261
  interface ProjectConnectionConfig {
293
262
  apiUrl: string;
294
263
  projectToken: string;
295
264
  projectId: string;
296
- projectDir?: string;
297
265
  }
298
266
  interface TaskAssignment {
299
267
  taskId: string;
300
268
  taskToken: string;
269
+ sessionId?: string;
301
270
  apiUrl: string;
302
271
  mode: string;
303
272
  branch: string;
@@ -311,151 +280,106 @@ interface IncomingChatMessage {
311
280
  content: string;
312
281
  userId: string;
313
282
  chatId?: string;
314
- files?: {
315
- id: string;
316
- fileName: string;
317
- mimeType: string;
318
- downloadUrl: string;
319
- content?: string;
320
- contentEncoding?: "base64" | "utf-8";
321
- }[];
322
- }
323
- interface ChatHistoryMessage {
324
- role: string;
325
- content: string;
326
- userId: string | null;
327
- userName?: string;
328
- createdAt: string;
329
- }
330
- interface AgentContext {
331
- projectName: string;
332
- projectDescription: string | null;
333
- agentId: string | null;
334
- agentName: string | null;
335
- agentInstructions: string;
336
- model: string;
337
- agentSettings: Record<string, unknown> | null;
338
- branchSwitchCommand?: string;
339
- }
340
- type SwitchBranchCallback = (res: {
341
- ok: boolean;
342
- data?: _project_shared.ProjectEnvironmentStatus;
343
- error?: string;
344
- }) => void;
345
- type SyncEnvironmentCallback = (res: {
346
- ok: boolean;
347
- data?: _project_shared.ProjectEnvironmentStatus;
348
- error?: string;
349
- }) => void;
350
- type GetEnvStatusCallback = (res: {
351
- ok: boolean;
352
- data?: _project_shared.ProjectEnvironmentStatus;
353
- }) => void;
283
+ projectId: string;
284
+ timestamp: string;
285
+ }
286
+ interface SwitchBranchRequest {
287
+ branch: string;
288
+ syncAfter?: boolean;
289
+ }
354
290
  declare class ProjectConnection {
355
291
  private socket;
356
- private config;
357
- private taskAssignmentCallback;
358
- private stopTaskCallback;
359
- private shutdownCallback;
360
- private chatMessageCallback;
361
- private earlyChatMessages;
362
- private auditRequestCallback;
363
- onSwitchBranch: ((data: {
364
- branch: string;
365
- syncAfter?: boolean;
366
- }, cb: SwitchBranchCallback) => void) | null;
367
- onSyncEnvironment: ((cb: SyncEnvironmentCallback) => void) | null;
368
- onGetEnvStatus: ((cb: GetEnvStatusCallback) => void) | null;
369
- onRestartStartCommand: ((cb: (res: {
370
- ok: boolean;
371
- error?: string;
372
- }) => void) => void) | null;
292
+ private readonly config;
293
+ private eventBuffer;
294
+ private flushTimer;
295
+ private reconnectCallbacks;
373
296
  constructor(config: ProjectConnectionConfig);
297
+ get projectId(): string;
298
+ get connected(): boolean;
299
+ call<M extends keyof AgentSessionServiceMethods>(method: M, payload: AgentSessionServiceMethods[M]["payload"]): Promise<AgentSessionServiceMethods[M]["response"]>;
374
300
  connect(): Promise<void>;
301
+ disconnect(): void;
302
+ onReconnect(callback: () => void): void;
375
303
  onTaskAssignment(callback: (assignment: TaskAssignment) => void): void;
376
304
  onStopTask(callback: (data: {
377
305
  taskId: string;
378
306
  }) => void): void;
379
307
  onShutdown(callback: () => void): void;
380
308
  onChatMessage(callback: (msg: IncomingChatMessage) => void): void;
381
- onAuditRequest(callback: (request: TagAuditRunnerRequest) => void): void;
382
- emitAuditResult(data: TagAuditRunnerResponse): void;
383
- emitAuditProgress(data: {
384
- requestId: string;
385
- activity: TagAuditProgressActivity;
386
- }): void;
309
+ onSwitchBranch(callback: (data: SwitchBranchRequest, cb: (res: {
310
+ ok: boolean;
311
+ error?: string;
312
+ }) => void) => void): void;
313
+ onSyncEnvironment(callback: (cb: (res: {
314
+ ok: boolean;
315
+ error?: string;
316
+ }) => void) => void): void;
317
+ onRestartStartCommand(callback: (cb: (res: {
318
+ ok: boolean;
319
+ error?: string;
320
+ }) => void) => void): void;
387
321
  sendHeartbeat(): void;
322
+ sendEvent(event: Record<string, unknown>): void;
323
+ emitStatus(status: "busy" | "idle"): void;
388
324
  emitTaskStarted(taskId: string): void;
389
325
  emitTaskStopped(taskId: string, reason: string): void;
390
- emitEvent(event: Record<string, unknown>): void;
391
- emitChatMessage(content: string): Promise<void>;
392
- emitAgentStatus(status: string): void;
393
- fetchAgentContext(): Promise<AgentContext | null>;
394
- fetchChatHistory(limit?: number, chatId?: string): Promise<ChatHistoryMessage[]>;
395
- requestListTasks(params: {
396
- status?: string;
397
- assigneeId?: string;
398
- limit?: number;
399
- }): Promise<unknown[]>;
400
- requestGetTask(taskId: string): Promise<unknown>;
401
- requestCreateTask(params: {
402
- title: string;
403
- description?: string;
404
- plan?: string;
405
- status?: string;
406
- isBug?: boolean;
407
- }): Promise<{
408
- id: string;
409
- slug: string;
410
- }>;
411
- requestUpdateTask(params: {
412
- taskId: string;
413
- title?: string;
414
- description?: string;
415
- plan?: string;
416
- status?: string;
417
- assignedUserId?: string | null;
418
- }): Promise<unknown>;
419
- requestSearchTasks(params: {
420
- tagNames?: string[];
421
- searchQuery?: string;
422
- statusFilters?: string[];
423
- limit?: number;
424
- }): Promise<unknown[]>;
425
- requestListTags(): Promise<unknown[]>;
426
- requestGetProjectSummary(): Promise<unknown>;
427
- private requestWithCallback;
428
- emitNewCommitsDetected(data: {
429
- branch: string;
430
- commitCount: number;
431
- latestCommit: {
432
- sha: string;
433
- message: string;
434
- author: string;
435
- };
436
- autoSyncing: boolean;
437
- }): void;
438
- emitEnvironmentReady(data: {
439
- branch: string;
440
- commitsSynced: number;
441
- syncDurationMs: number;
442
- stepsRun: string[];
443
- }): void;
444
- emitEnvSwitchProgress(data: {
445
- step: string;
446
- status: "running" | "success" | "error";
447
- message?: string;
448
- }): void;
449
- private handleRunAuthTokenCommand;
450
- disconnect(): void;
326
+ private flushEvents;
327
+ private requireSocket;
451
328
  }
452
329
 
453
- declare function ensureWorktree(projectDir: string, taskId: string, branch?: string): string;
454
- /**
455
- * Force-remove is intentional: this runs after task completion or explicit stop.
456
- * Any uncommitted changes at this point are scratch artifacts, not valuable work.
457
- */
458
- declare function removeWorktree(projectDir: string, taskId: string): void;
330
+ interface ProjectRunnerConfig {
331
+ conveyorApiUrl: string;
332
+ projectToken: string;
333
+ projectId: string;
334
+ projectDir: string;
335
+ }
336
+ declare class ProjectRunner {
337
+ private connection;
338
+ private projectDir;
339
+ private activeAgents;
340
+ private heartbeatTimer;
341
+ private stopping;
342
+ private resolveLifecycle;
343
+ private chatSessionIds;
344
+ private startCommandChild;
345
+ private startCommandRunning;
346
+ private setupComplete;
347
+ private branchSwitchCommand;
348
+ private commitWatcher;
349
+ constructor(config: ProjectRunnerConfig);
350
+ start(): Promise<void>;
351
+ stop(): Promise<void>;
352
+ private wireEventHandlers;
353
+ private handleReconnect;
354
+ private handleAssignment;
355
+ private handleStopTask;
356
+ private checkoutWorkspaceBranch;
357
+ private executeSetupCommand;
358
+ private executeStartCommand;
359
+ private killStartCommand;
360
+ private restartStartCommand;
361
+ private getCurrentBranch;
362
+ private handleSwitchBranch;
363
+ private handleSyncEnvironment;
364
+ private handleNewCommits;
365
+ private smartSync;
366
+ private syncDependencies;
367
+ private runIndividualSyncSteps;
368
+ private getChangedFiles;
369
+ }
370
+
371
+ declare class PlanSync {
372
+ private planFileSnapshot;
373
+ private lockedPlanFile;
374
+ private workspaceDir;
375
+ private connection;
376
+ constructor(workspaceDir: string, connection: AgentConnection);
377
+ updateWorkspaceDir(workspaceDir: string): void;
378
+ private getPlanDirs;
379
+ snapshotPlanFiles(): void;
380
+ private findNewestPlanFile;
381
+ syncPlanFile(): void;
382
+ }
459
383
 
460
384
  interface CacheEntry {
461
385
  content: Buffer;
@@ -481,18 +405,63 @@ declare class FileCache {
481
405
  };
482
406
  }
483
407
 
484
- interface ConveyorConfig {
485
- setupCommand?: string;
486
- startCommand?: string;
487
- previewPort?: number;
408
+ interface CommitWatcherConfig {
409
+ projectDir: string;
410
+ pollIntervalMs: number;
411
+ debounceMs: number;
412
+ }
413
+ interface NewCommitsData {
414
+ branch: string;
415
+ previousSha: string;
416
+ newCommitSha: string;
417
+ commitCount: number;
418
+ latestMessage: string;
419
+ latestAuthor: string;
488
420
  }
421
+ interface CommitWatcherCallbacks {
422
+ onNewCommits: (data: NewCommitsData) => Promise<void>;
423
+ }
424
+ declare class CommitWatcher {
425
+ private config;
426
+ private callbacks;
427
+ private interval;
428
+ private lastKnownRemoteSha;
429
+ private branch;
430
+ private debounceTimer;
431
+ private isSyncing;
432
+ constructor(config: CommitWatcherConfig, callbacks: CommitWatcherCallbacks);
433
+ start(branch: string): void;
434
+ stop(): void;
435
+ private getLocalHeadSha;
436
+ private poll;
437
+ private handleNewCommits;
438
+ }
439
+
440
+ /** Returns true if the working tree has uncommitted changes (staged or unstaged). */
441
+ declare function hasUncommittedChanges(cwd: string): boolean;
442
+ /** Returns the current branch name, or null if on detached HEAD. */
443
+ declare function getCurrentBranch(cwd: string): string | null;
444
+ /** Returns true if there are committed changes that haven't been pushed to origin. */
445
+ declare function hasUnpushedCommits(cwd: string): boolean;
446
+ /** Stage all changes and create a commit. Returns the commit hash if successful. */
447
+ declare function stageAndCommit(cwd: string, message: string): string | null;
448
+ /** Update the git remote URL with a fresh token. */
449
+ declare function updateRemoteToken(cwd: string, token: string): void;
450
+ /** Push current branch to origin. On auth failure, refreshes the GitHub token and retries. */
451
+ declare function pushToOrigin(cwd: string, refreshToken?: () => Promise<string | undefined>): Promise<boolean>;
452
+
453
+ declare function ensureWorktree(projectDir: string, taskId: string, branch?: string): string;
489
454
  /**
490
- * Load config from env vars (project-level settings injected via bootstrap).
455
+ * Detach any task worktree that has `branch` checked out, releasing the branch lock
456
+ * so the main project directory can check it out. Only touches worktrees inside
457
+ * `.worktrees/` — never the main project directory.
491
458
  */
492
- declare function loadConveyorConfig(_workspaceDir?: string): ConveyorConfig | null;
493
-
494
- declare function runSetupCommand(cmd: string, cwd: string, onOutput: (stream: "stdout" | "stderr", data: string) => void): Promise<void>;
495
- declare function runStartCommand(cmd: string, cwd: string, onOutput: (stream: "stdout" | "stderr", data: string) => void): ChildProcess;
459
+ declare function detachWorktreeBranch(projectDir: string, branch: string): void;
460
+ /**
461
+ * Force-remove is intentional: this runs after task completion or explicit stop.
462
+ * Any uncommitted changes at this point are scratch artifacts, not valuable work.
463
+ */
464
+ declare function removeWorktree(projectDir: string, taskId: string): void;
496
465
 
497
466
  interface BreakpointInfo {
498
467
  breakpointId: string;
@@ -671,6 +640,7 @@ declare class PlaywrightDebugClient {
671
640
  private clearInactivityTimer;
672
641
  }
673
642
 
643
+ type InspectorRuntime = "node" | "bun" | "unknown";
674
644
  interface DebugEventHandler {
675
645
  onDebugModeEntered: () => void;
676
646
  onDebugModeExited: () => void;
@@ -710,11 +680,13 @@ declare class DebugManager {
710
680
  private ensurePlaywrightInstalled;
711
681
  private startWithInspector;
712
682
  }
683
+ declare function detectRuntime(startCommand: string): InspectorRuntime;
684
+ declare function injectBunInspectFlag(command: string): string;
713
685
 
714
686
  /**
715
687
  * Orchestrates the debug session lifecycle, tracks state for the web UI,
716
688
  * and generates session summaries. Wraps DebugManager events and forwards
717
- * state changes to the API via ConveyorConnection.
689
+ * state changes to the API via AgentConnection.
718
690
  */
719
691
  declare class DebugLifecycleManager {
720
692
  private connection;
@@ -726,7 +698,7 @@ declare class DebugLifecycleManager {
726
698
  private reproduceRequested;
727
699
  private keyFindings;
728
700
  private _isActive;
729
- constructor(connection: ConveyorConnection);
701
+ constructor(connection: AgentConnection);
730
702
  get isActive(): boolean;
731
703
  setDebugManager(manager: DebugManager): void;
732
704
  /**
@@ -750,4 +722,71 @@ declare class DebugLifecycleManager {
750
722
  private broadcastState;
751
723
  }
752
724
 
753
- export { type AgentContext, AgentRunner, type AgentRunnerCallbacks, type AgentRunnerConfig, type BreakpointInfo, type CallFrameInfo, CdpDebugClient, type ChatHistoryMessage, type ConveyorConfig, ConveyorConnection, type DebugEventHandler, DebugLifecycleManager, DebugManager, FileCache, type IncomingChatMessage, type PausedState, ProjectConnection, type ProjectConnectionConfig, ProjectRunner, type ProjectRunnerConfig, type ScopeVariable, type TaskAssignment, ensureWorktree, loadConveyorConfig, removeWorktree, runSetupCommand, runStartCommand };
725
+ interface Observation {
726
+ description: string;
727
+ confirmsHypothesis: boolean;
728
+ iteration: number;
729
+ timestamp: number;
730
+ }
731
+ interface HypothesisState {
732
+ hypothesis: string | null;
733
+ iteration: number;
734
+ observations: Observation[];
735
+ active: boolean;
736
+ conclusion: string | null;
737
+ }
738
+ declare class HypothesisTracker {
739
+ private hypothesis;
740
+ private iteration;
741
+ private observations;
742
+ private _active;
743
+ private conclusion;
744
+ /**
745
+ * Start or update the current debugging hypothesis.
746
+ * Increments the iteration count if a hypothesis was already set.
747
+ */
748
+ setHypothesis(text: string): {
749
+ accepted: boolean;
750
+ message: string;
751
+ };
752
+ /**
753
+ * Record an observation from debug data (breakpoint hit, telemetry, etc.).
754
+ */
755
+ recordObservation(description: string, confirmsHypothesis: boolean): void;
756
+ /**
757
+ * End the debug session with a conclusion.
758
+ */
759
+ concludeSession(conclusion: string): string;
760
+ /**
761
+ * Get formatted debug context for injection into the agent's system prompt.
762
+ * Returns empty string if no active session.
763
+ */
764
+ getDebugContext(): string;
765
+ /**
766
+ * Get the full state (for serialization/testing).
767
+ */
768
+ getState(): HypothesisState;
769
+ isActive(): boolean;
770
+ getIteration(): number;
771
+ getMaxIterations(): number;
772
+ private getSessionSummary;
773
+ private reset;
774
+ }
775
+
776
+ interface ConveyorConfig {
777
+ setupCommand?: string;
778
+ startCommand?: string;
779
+ previewPort?: number;
780
+ }
781
+ declare function loadForwardPorts(workspaceDir: string): Promise<number[]>;
782
+ /** Load config from env vars (project-level settings injected via bootstrap). */
783
+ declare function loadConveyorConfig(): ConveyorConfig | null;
784
+
785
+ declare function runSetupCommand(cmd: string, cwd: string, onOutput: (stream: "stdout" | "stderr", data: string) => void): Promise<void>;
786
+ declare function runAuthTokenCommand(cmd: string, userEmail: string, cwd: string): string | null;
787
+ declare function runStartCommand(cmd: string, cwd: string, onOutput: (stream: "stdout" | "stderr", data: string) => void): ChildProcess;
788
+
789
+ /** Fetch full git history if the repo was cloned with --depth=1. */
790
+ declare function unshallowRepo(workspaceDir: string): void;
791
+
792
+ export { AgentConnection, type AgentConnectionConfig, type AgentRunnerCallbacks, type AgentRunnerConfig, type ApiKeyUpdateData, CommitWatcher, type ConveyorConfig, DEFAULT_LIFECYCLE_CONFIG, type DebugEventHandler, DebugLifecycleManager, DebugManager, type DebugModeOptions, FileCache, HypothesisTracker, type IncomingMessage, type InspectorRuntime, Lifecycle, type LifecycleCallbacks, type LifecycleConfig, type ModeAction, ModeController, type ModeTaskContext, PlanSync, ProjectConnection, ProjectRunner, SessionRunner, type SessionRunnerCallbacks, type SessionRunnerConfig, type SetModeData, detachWorktreeBranch, detectRuntime, ensureWorktree, getCurrentBranch, hasUncommittedChanges, hasUnpushedCommits, injectBunInspectFlag, loadConveyorConfig, loadForwardPorts, pushToOrigin, removeWorktree, runAuthTokenCommand, runSetupCommand, runStartCommand, stageAndCommit, unshallowRepo, updateRemoteToken };