agileflow 2.96.0 → 2.96.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,7 +21,7 @@ import {
21
21
  CLICommand,
22
22
  IREventHandler,
23
23
  GEMINI_CAPABILITIES,
24
- } from "../protocol/driver";
24
+ } from '../protocol/driver';
25
25
  import {
26
26
  IREnvelope,
27
27
  IRSource,
@@ -34,28 +34,28 @@ import {
34
34
  IRError,
35
35
  IRTask,
36
36
  IRNotification,
37
- } from "../protocol/ir";
37
+ } from '../protocol/ir';
38
38
 
39
39
  // ============================================================================
40
40
  // Tool Name Mapping (Gemini -> IR normalized names)
41
41
  // ============================================================================
42
42
 
43
43
  const GEMINI_TOOL_MAPPING: Record<string, string> = {
44
- "read_file": "file_read",
45
- "write_file": "file_write",
46
- "replace": "file_edit",
47
- "run_shell_command": "shell_exec",
48
- "glob": "file_glob",
49
- "search_file_content": "file_grep",
50
- "google_web_search": "web_search",
51
- "fetch_url": "web_fetch",
52
- "create_checkpoint": "checkpoint_create",
53
- "restore_checkpoint": "checkpoint_restore",
54
- "list_checkpoints": "checkpoint_list",
55
- "conductor_run": "conductor_run",
56
- "task_create": "todo_create",
57
- "task_update": "todo_update",
58
- "task_list": "todo_list",
44
+ read_file: 'file_read',
45
+ write_file: 'file_write',
46
+ replace: 'file_edit',
47
+ run_shell_command: 'shell_exec',
48
+ glob: 'file_glob',
49
+ search_file_content: 'file_grep',
50
+ google_web_search: 'web_search',
51
+ fetch_url: 'web_fetch',
52
+ create_checkpoint: 'checkpoint_create',
53
+ restore_checkpoint: 'checkpoint_restore',
54
+ list_checkpoints: 'checkpoint_list',
55
+ conductor_run: 'conductor_run',
56
+ task_create: 'todo_create',
57
+ task_update: 'todo_update',
58
+ task_list: 'todo_list',
59
59
  };
60
60
 
61
61
  /**
@@ -77,7 +77,7 @@ interface RateLimitState {
77
77
  }
78
78
 
79
79
  const RATE_LIMITS = {
80
- rpm: 60, // Requests per minute
80
+ rpm: 60, // Requests per minute
81
81
  rpd: 1000, // Requests per day
82
82
  };
83
83
 
@@ -86,22 +86,25 @@ const RATE_LIMITS = {
86
86
  // ============================================================================
87
87
 
88
88
  export class GeminiDriver implements Driver {
89
- readonly id: IRSource = "gemini";
90
- readonly name = "Gemini CLI";
89
+ readonly id: IRSource = 'gemini';
90
+ readonly name = 'Gemini CLI';
91
91
 
92
92
  private _status: DriverStatus = {
93
- state: "stopped",
94
- provider: "gemini",
93
+ state: 'stopped',
94
+ provider: 'gemini',
95
95
  };
96
96
 
97
97
  private _capabilities: Capability[] = [...GEMINI_CAPABILITIES];
98
98
  private _eventHandlers: Set<IREventHandler> = new Set();
99
- private _sessions: Map<string, {
100
- config: DriverConfig;
101
- seqCounter: number;
102
- checkpoints: string[];
103
- conductorWorkflow?: string;
104
- }> = new Map();
99
+ private _sessions: Map<
100
+ string,
101
+ {
102
+ config: DriverConfig;
103
+ seqCounter: number;
104
+ checkpoints: string[];
105
+ conductorWorkflow?: string;
106
+ }
107
+ > = new Map();
105
108
 
106
109
  // Rate limiting state
107
110
  private _rateLimit: RateLimitState = {
@@ -131,21 +134,21 @@ export class GeminiDriver implements Driver {
131
134
  });
132
135
 
133
136
  this._status = {
134
- state: "ready",
135
- provider: "gemini",
136
- model: config.model || "gemini-2.0-flash",
137
+ state: 'ready',
138
+ provider: 'gemini',
139
+ model: config.model || 'gemini-2.0-flash',
137
140
  contextMax: config.maxTokens || 1000000, // 1M context
138
141
  };
139
142
 
140
143
  // Emit init event
141
144
  const initPayload: IRInit = {
142
- provider: "gemini",
143
- version: "1.0.0",
145
+ provider: 'gemini',
146
+ version: '1.0.0',
144
147
  capabilities: this._capabilities.filter(c => c.available).map(c => c.name),
145
148
  maxContext: config.maxTokens || 1000000,
146
149
  };
147
150
 
148
- this._emit(createIREnvelope("init", sessionId, "gemini", initPayload));
151
+ this._emit(createIREnvelope('init', sessionId, 'gemini', initPayload));
149
152
  }
150
153
 
151
154
  async stop(sessionId: string): Promise<void> {
@@ -154,7 +157,7 @@ export class GeminiDriver implements Driver {
154
157
  if (this._sessions.size === 0) {
155
158
  this._status = {
156
159
  ...this._status,
157
- state: "stopped",
160
+ state: 'stopped',
158
161
  };
159
162
  }
160
163
  }
@@ -223,26 +226,28 @@ export class GeminiDriver implements Driver {
223
226
  // Check rate limits
224
227
  const rateCheck = this._checkRateLimit();
225
228
  if (!rateCheck.allowed) {
226
- this._emit(createIREnvelope<IRError>("error", sessionId, "gemini", {
227
- code: "RATE_LIMITED",
228
- message: `Rate limit exceeded. Retry after ${Math.ceil((rateCheck.retryAfterMs || 0) / 1000)} seconds.`,
229
- details: {
230
- rpm: this._rateLimit.requestsThisMinute,
231
- rpd: this._rateLimit.requestsToday,
232
- limits: RATE_LIMITS,
233
- },
234
- recoverable: true,
235
- }));
229
+ this._emit(
230
+ createIREnvelope<IRError>('error', sessionId, 'gemini', {
231
+ code: 'RATE_LIMITED',
232
+ message: `Rate limit exceeded. Retry after ${Math.ceil((rateCheck.retryAfterMs || 0) / 1000)} seconds.`,
233
+ details: {
234
+ rpm: this._rateLimit.requestsThisMinute,
235
+ rpd: this._rateLimit.requestsToday,
236
+ limits: RATE_LIMITS,
237
+ },
238
+ recoverable: true,
239
+ })
240
+ );
236
241
  return;
237
242
  }
238
243
 
239
244
  this._recordRequest();
240
- this._status = { ...this._status, state: "busy" };
245
+ this._status = { ...this._status, state: 'busy' };
241
246
 
242
247
  const sessionPayload: IRSession = {
243
- state: "thinking",
248
+ state: 'thinking',
244
249
  };
245
- this._emit(createIREnvelope("session", sessionId, "gemini", sessionPayload));
250
+ this._emit(createIREnvelope('session', sessionId, 'gemini', sessionPayload));
246
251
  }
247
252
 
248
253
  // -------------------------------------------------------------------------
@@ -254,16 +259,18 @@ export class GeminiDriver implements Driver {
254
259
  */
255
260
  async createCheckpoint(sessionId: string, name: string): Promise<string> {
256
261
  const session = this._sessions.get(sessionId);
257
- if (!session) throw new Error("Session not found");
262
+ if (!session) throw new Error('Session not found');
258
263
 
259
264
  const checkpointId = `ckpt_${Date.now()}_${name}`;
260
265
  session.checkpoints.push(checkpointId);
261
266
 
262
- this._emit(createIREnvelope<IRNotification>("notification", sessionId, "gemini", {
263
- level: "info",
264
- title: "Checkpoint Created",
265
- message: `Checkpoint "${name}" created (${checkpointId})`,
266
- }));
267
+ this._emit(
268
+ createIREnvelope<IRNotification>('notification', sessionId, 'gemini', {
269
+ level: 'info',
270
+ title: 'Checkpoint Created',
271
+ message: `Checkpoint "${name}" created (${checkpointId})`,
272
+ })
273
+ );
267
274
 
268
275
  return checkpointId;
269
276
  }
@@ -273,16 +280,18 @@ export class GeminiDriver implements Driver {
273
280
  */
274
281
  async restoreCheckpoint(sessionId: string, checkpointId: string): Promise<void> {
275
282
  const session = this._sessions.get(sessionId);
276
- if (!session) throw new Error("Session not found");
283
+ if (!session) throw new Error('Session not found');
277
284
 
278
285
  if (!session.checkpoints.includes(checkpointId)) {
279
286
  throw new Error(`Checkpoint not found: ${checkpointId}`);
280
287
  }
281
288
 
282
- this._emit(createIREnvelope<IRSession>("session", sessionId, "gemini", {
283
- state: "idle",
284
- message: `Restored checkpoint: ${checkpointId}`,
285
- }));
289
+ this._emit(
290
+ createIREnvelope<IRSession>('session', sessionId, 'gemini', {
291
+ state: 'idle',
292
+ message: `Restored checkpoint: ${checkpointId}`,
293
+ })
294
+ );
286
295
  }
287
296
 
288
297
  /**
@@ -302,15 +311,17 @@ export class GeminiDriver implements Driver {
302
311
  */
303
312
  async startConductor(sessionId: string, workflowName: string): Promise<void> {
304
313
  const session = this._sessions.get(sessionId);
305
- if (!session) throw new Error("Session not found");
314
+ if (!session) throw new Error('Session not found');
306
315
 
307
316
  session.conductorWorkflow = workflowName;
308
317
 
309
- this._emit(createIREnvelope<IRNotification>("notification", sessionId, "gemini", {
310
- level: "info",
311
- title: "Conductor Started",
312
- message: `Starting workflow: ${workflowName}`,
313
- }));
318
+ this._emit(
319
+ createIREnvelope<IRNotification>('notification', sessionId, 'gemini', {
320
+ level: 'info',
321
+ title: 'Conductor Started',
322
+ message: `Starting workflow: ${workflowName}`,
323
+ })
324
+ );
314
325
  }
315
326
 
316
327
  // -------------------------------------------------------------------------
@@ -325,78 +336,80 @@ export class GeminiDriver implements Driver {
325
336
  if (!session) return null;
326
337
 
327
338
  switch (geminiMessage.type) {
328
- case "message":
329
- return createIREnvelope<IRTextDelta>("text_delta", sessionId, "gemini", {
330
- text: geminiMessage.content || "",
339
+ case 'message':
340
+ return createIREnvelope<IRTextDelta>('text_delta', sessionId, 'gemini', {
341
+ text: geminiMessage.content || '',
331
342
  done: !geminiMessage.delta,
332
343
  });
333
344
 
334
- case "tool_use":
335
- return createIREnvelope<IRToolStart>("tool_start", sessionId, "gemini", {
345
+ case 'tool_use':
346
+ return createIREnvelope<IRToolStart>('tool_start', sessionId, 'gemini', {
336
347
  id: geminiMessage.id || `tool_${Date.now()}`,
337
- name: normalizeToolName(geminiMessage.tool || ""),
338
- nativeName: geminiMessage.tool || "",
348
+ name: normalizeToolName(geminiMessage.tool || ''),
349
+ nativeName: geminiMessage.tool || '',
339
350
  input: geminiMessage.input || {},
340
351
  });
341
352
 
342
- case "tool_result":
343
- return createIREnvelope<IRToolResult>("tool_result", sessionId, "gemini", {
344
- id: geminiMessage.id || "",
353
+ case 'tool_result':
354
+ return createIREnvelope<IRToolResult>('tool_result', sessionId, 'gemini', {
355
+ id: geminiMessage.id || '',
345
356
  ok: !geminiMessage.error,
346
357
  output: geminiMessage.output,
347
358
  error: geminiMessage.error,
348
359
  });
349
360
 
350
- case "checkpoint":
361
+ case 'checkpoint':
351
362
  // Checkpoint created/restored
352
- return createIREnvelope<IRNotification>("notification", sessionId, "gemini", {
353
- level: "info",
354
- title: geminiMessage.action === "create" ? "Checkpoint Created" : "Checkpoint Restored",
363
+ return createIREnvelope<IRNotification>('notification', sessionId, 'gemini', {
364
+ level: 'info',
365
+ title: geminiMessage.action === 'create' ? 'Checkpoint Created' : 'Checkpoint Restored',
355
366
  message: `Checkpoint: ${geminiMessage.checkpointId}`,
356
367
  });
357
368
 
358
- case "conductor":
369
+ case 'conductor':
359
370
  // Conductor workflow event
360
- return createIREnvelope<IRNotification>("notification", sessionId, "gemini", {
361
- level: "info",
362
- title: "Conductor",
371
+ return createIREnvelope<IRNotification>('notification', sessionId, 'gemini', {
372
+ level: 'info',
373
+ title: 'Conductor',
363
374
  message: `Workflow ${geminiMessage.workflow}: ${geminiMessage.status}`,
364
375
  });
365
376
 
366
- case "task":
367
- return createIREnvelope<IRTask>("task", sessionId, "gemini", {
368
- action: geminiMessage.action as "create" | "update" | "delete" | "list",
369
- task: geminiMessage.task ? {
370
- id: geminiMessage.task.id,
371
- subject: geminiMessage.task.subject,
372
- description: geminiMessage.task.description,
373
- status: geminiMessage.task.status as "pending" | "in_progress" | "completed",
374
- } : undefined,
375
- tasks: geminiMessage.tasks?.map((t) => ({
377
+ case 'task':
378
+ return createIREnvelope<IRTask>('task', sessionId, 'gemini', {
379
+ action: geminiMessage.action as 'create' | 'update' | 'delete' | 'list',
380
+ task: geminiMessage.task
381
+ ? {
382
+ id: geminiMessage.task.id,
383
+ subject: geminiMessage.task.subject,
384
+ description: geminiMessage.task.description,
385
+ status: geminiMessage.task.status as 'pending' | 'in_progress' | 'completed',
386
+ }
387
+ : undefined,
388
+ tasks: geminiMessage.tasks?.map(t => ({
376
389
  id: t.id,
377
390
  subject: t.subject,
378
- status: t.status as "pending" | "in_progress" | "completed",
391
+ status: t.status as 'pending' | 'in_progress' | 'completed',
379
392
  })),
380
393
  });
381
394
 
382
- case "result":
383
- this._status = { ...this._status, state: "ready" };
384
- return createIREnvelope<IRSession>("session", sessionId, "gemini", {
385
- state: "idle",
395
+ case 'result':
396
+ this._status = { ...this._status, state: 'ready' };
397
+ return createIREnvelope<IRSession>('session', sessionId, 'gemini', {
398
+ state: 'idle',
386
399
  });
387
400
 
388
- case "error":
389
- return createIREnvelope<IRError>("error", sessionId, "gemini", {
390
- code: geminiMessage.code || "UNKNOWN",
391
- message: geminiMessage.message || "Unknown error",
401
+ case 'error':
402
+ return createIREnvelope<IRError>('error', sessionId, 'gemini', {
403
+ code: geminiMessage.code || 'UNKNOWN',
404
+ message: geminiMessage.message || 'Unknown error',
392
405
  details: geminiMessage.details,
393
406
  recoverable: geminiMessage.recoverable ?? true,
394
407
  });
395
408
 
396
- case "rate_limit":
397
- return createIREnvelope<IRError>("error", sessionId, "gemini", {
398
- code: "RATE_LIMITED",
399
- message: geminiMessage.message || "Rate limit exceeded",
409
+ case 'rate_limit':
410
+ return createIREnvelope<IRError>('error', sessionId, 'gemini', {
411
+ code: 'RATE_LIMITED',
412
+ message: geminiMessage.message || 'Rate limit exceeded',
400
413
  details: {
401
414
  retryAfterSeconds: geminiMessage.retryAfter,
402
415
  },
@@ -428,11 +441,11 @@ export class GeminiDriver implements Driver {
428
441
  }
429
442
 
430
443
  private _emit(envelope: IREnvelope): void {
431
- Array.from(this._eventHandlers).forEach((handler) => {
444
+ Array.from(this._eventHandlers).forEach(handler => {
432
445
  try {
433
446
  handler(envelope);
434
447
  } catch (error) {
435
- console.error("[GeminiDriver] Event handler error:", error);
448
+ console.error('[GeminiDriver] Event handler error:', error);
436
449
  }
437
450
  });
438
451
  }
@@ -5,13 +5,13 @@
5
5
  */
6
6
 
7
7
  // Driver Manager
8
- export { DefaultDriverManager, getDriverManager, resetDriverManager } from "./driver-manager";
8
+ export { DefaultDriverManager, getDriverManager, resetDriverManager } from './driver-manager';
9
9
 
10
10
  // Claude Driver
11
- export { ClaudeDriver, createClaudeDriver, type ClaudeNativeMessage } from "./claude-driver";
11
+ export { ClaudeDriver, createClaudeDriver, type ClaudeNativeMessage } from './claude-driver';
12
12
 
13
13
  // Codex Driver
14
- export { CodexDriver, createCodexDriver, type CodexJsonRpcMessage } from "./codex-driver";
14
+ export { CodexDriver, createCodexDriver, type CodexJsonRpcMessage } from './codex-driver';
15
15
 
16
16
  // Gemini Driver
17
- export { GeminiDriver, createGeminiDriver, type GeminiNdjsonMessage } from "./gemini-driver";
17
+ export { GeminiDriver, createGeminiDriver, type GeminiNdjsonMessage } from './gemini-driver';
@@ -61,8 +61,7 @@ function extractClaudeFlags(args) {
61
61
  else if (arg === '--model' && args[i + 1]) {
62
62
  flags.push(`${arg} ${args[i + 1]}`);
63
63
  i++;
64
- }
65
- else if (arg.startsWith('--model=')) {
64
+ } else if (arg.startsWith('--model=')) {
66
65
  flags.push(arg);
67
66
  }
68
67
 
@@ -127,13 +126,15 @@ function isClaudeProcess(args) {
127
126
  if (!args || args.length === 0) return false;
128
127
 
129
128
  // Check if any arg contains 'claude' (handles various ways claude can be invoked)
130
- for (const arg of args.slice(0, 3)) { // Only check first few args
131
- if (arg && (
132
- arg.endsWith('/claude') ||
133
- arg === 'claude' ||
134
- arg.includes('claude-code') ||
135
- arg.includes('@anthropic')
136
- )) {
129
+ for (const arg of args.slice(0, 3)) {
130
+ // Only check first few args
131
+ if (
132
+ arg &&
133
+ (arg.endsWith('/claude') ||
134
+ arg === 'claude' ||
135
+ arg.includes('claude-code') ||
136
+ arg.includes('@anthropic'))
137
+ ) {
137
138
  return true;
138
139
  }
139
140
  }
@@ -732,7 +732,14 @@ function getMergeHistory() {
732
732
  * @param {Function} unregisterSession - Session unregisterer
733
733
  * @returns {Object} Smart merge result
734
734
  */
735
- function smartMerge(sessionId, options = {}, loadRegistry, saveRegistry, removeLock, unregisterSession) {
735
+ function smartMerge(
736
+ sessionId,
737
+ options = {},
738
+ loadRegistry,
739
+ saveRegistry,
740
+ removeLock,
741
+ unregisterSession
742
+ ) {
736
743
  const { c } = require('./colors');
737
744
  const {
738
745
  strategy = 'squash',