@factory/droid-sdk 0.1.4 → 0.3.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.
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ var DroidServerMethod = /* @__PURE__ */ ((DroidServerMethod2) => {
3
3
  DroidServerMethod2["INITIALIZE_SESSION"] = "droid.initialize_session";
4
4
  DroidServerMethod2["LOAD_SESSION"] = "droid.load_session";
5
5
  DroidServerMethod2["ADD_USER_MESSAGE"] = "droid.add_user_message";
6
+ DroidServerMethod2["CLOSE_SESSION"] = "droid.close_session";
6
7
  DroidServerMethod2["INTERRUPT_SESSION"] = "droid.interrupt_session";
7
8
  DroidServerMethod2["KILL_WORKER_SESSION"] = "droid.kill_worker_session";
8
9
  DroidServerMethod2["UPDATE_SESSION_SETTINGS"] = "droid.update_session_settings";
@@ -14,11 +15,18 @@ var DroidServerMethod = /* @__PURE__ */ ((DroidServerMethod2) => {
14
15
  DroidServerMethod2["REMOVE_MCP_SERVER"] = "droid.remove_mcp_server";
15
16
  DroidServerMethod2["LIST_MCP_REGISTRY"] = "droid.list_mcp_registry";
16
17
  DroidServerMethod2["LIST_MCP_TOOLS"] = "droid.list_mcp_tools";
18
+ DroidServerMethod2["LIST_TOOLS"] = "droid.list_tools";
17
19
  DroidServerMethod2["LIST_MCP_SERVERS"] = "droid.list_mcp_servers";
18
20
  DroidServerMethod2["TOGGLE_MCP_TOOL"] = "droid.toggle_mcp_tool";
19
21
  DroidServerMethod2["SUBMIT_MCP_AUTH_CODE"] = "droid.submit_mcp_auth_code";
20
22
  DroidServerMethod2["LIST_SKILLS"] = "droid.list_skills";
21
23
  DroidServerMethod2["SUBMIT_BUG_REPORT"] = "droid.submit_bug_report";
24
+ DroidServerMethod2["GET_REWIND_INFO"] = "droid.get_rewind_info";
25
+ DroidServerMethod2["EXECUTE_REWIND"] = "droid.execute_rewind";
26
+ DroidServerMethod2["COMPACT_SESSION"] = "droid.compact_session";
27
+ DroidServerMethod2["FORK_SESSION"] = "droid.fork_session";
28
+ DroidServerMethod2["RENAME_SESSION"] = "droid.rename_session";
29
+ DroidServerMethod2["GET_CONTEXT_STATS"] = "droid.get_context_stats";
22
30
  return DroidServerMethod2;
23
31
  })(DroidServerMethod || {});
24
32
  var DroidClientMethod = /* @__PURE__ */ ((DroidClientMethod2) => {
@@ -38,7 +46,10 @@ var SessionNotificationType = /* @__PURE__ */ ((SessionNotificationType2) => {
38
46
  SessionNotificationType2["SESSION_TITLE_UPDATED"] = "session_title_updated";
39
47
  SessionNotificationType2["MCP_STATUS_CHANGED"] = "mcp_status_changed";
40
48
  SessionNotificationType2["ASSISTANT_TEXT_DELTA"] = "assistant_text_delta";
49
+ SessionNotificationType2["ASSISTANT_TEXT_COMPLETE"] = "assistant_text_complete";
41
50
  SessionNotificationType2["THINKING_TEXT_DELTA"] = "thinking_text_delta";
51
+ SessionNotificationType2["THINKING_TEXT_COMPLETE"] = "thinking_text_complete";
52
+ SessionNotificationType2["TOOL_CALL"] = "tool_call";
42
53
  SessionNotificationType2["SESSION_TOKEN_USAGE_CHANGED"] = "session_token_usage_changed";
43
54
  SessionNotificationType2["MISSION_STATE_CHANGED"] = "mission_state_changed";
44
55
  SessionNotificationType2["MISSION_FEATURES_CHANGED"] = "mission_features_changed";
@@ -48,6 +59,9 @@ var SessionNotificationType = /* @__PURE__ */ ((SessionNotificationType2) => {
48
59
  SessionNotificationType2["MISSION_WORKER_COMPLETED"] = "mission_worker_completed";
49
60
  SessionNotificationType2["MCP_AUTH_REQUIRED"] = "mcp_auth_required";
50
61
  SessionNotificationType2["MCP_AUTH_COMPLETED"] = "mcp_auth_completed";
62
+ SessionNotificationType2["HOOK_EXECUTION_STARTED"] = "hook_execution_started";
63
+ SessionNotificationType2["HOOK_EXECUTION_COMPLETED"] = "hook_execution_completed";
64
+ SessionNotificationType2["STRUCTURED_OUTPUT"] = "structured_output";
51
65
  return SessionNotificationType2;
52
66
  })(SessionNotificationType || {});
53
67
  var ToolConfirmationOutcome = /* @__PURE__ */ ((ToolConfirmationOutcome3) => {
@@ -57,6 +71,10 @@ var ToolConfirmationOutcome = /* @__PURE__ */ ((ToolConfirmationOutcome3) => {
57
71
  ToolConfirmationOutcome3["ProceedAutoRunLow"] = "proceed_auto_run_low";
58
72
  ToolConfirmationOutcome3["ProceedAutoRunMedium"] = "proceed_auto_run_medium";
59
73
  ToolConfirmationOutcome3["ProceedAutoRunHigh"] = "proceed_auto_run_high";
74
+ ToolConfirmationOutcome3["ProceedNewSession"] = "proceed_new_session";
75
+ ToolConfirmationOutcome3["ProceedNewSessionLow"] = "proceed_new_session_low";
76
+ ToolConfirmationOutcome3["ProceedNewSessionMedium"] = "proceed_new_session_medium";
77
+ ToolConfirmationOutcome3["ProceedNewSessionHigh"] = "proceed_new_session_high";
60
78
  ToolConfirmationOutcome3["ProceedEdit"] = "proceed_edit";
61
79
  ToolConfirmationOutcome3["Cancel"] = "cancel";
62
80
  return ToolConfirmationOutcome3;
@@ -81,6 +99,11 @@ var DroidWorkingState = /* @__PURE__ */ ((DroidWorkingState2) => {
81
99
  DroidWorkingState2["CompactingConversation"] = "compacting_conversation";
82
100
  return DroidWorkingState2;
83
101
  })(DroidWorkingState || {});
102
+ var ContextStatsAccuracy = /* @__PURE__ */ ((ContextStatsAccuracy2) => {
103
+ ContextStatsAccuracy2["Exact"] = "exact";
104
+ ContextStatsAccuracy2["Estimated"] = "estimated";
105
+ return ContextStatsAccuracy2;
106
+ })(ContextStatsAccuracy || {});
84
107
  var DroidErrorType = /* @__PURE__ */ ((DroidErrorType2) => {
85
108
  DroidErrorType2["CONNECTION_ERROR"] = "ConnectionError";
86
109
  DroidErrorType2["PROTOCOL_ERROR"] = "ProtocolError";
@@ -252,19 +275,39 @@ var SkillLocation = /* @__PURE__ */ ((SkillLocation2) => {
252
275
  // src/schemas/constants.ts
253
276
  var JSONRPC_VERSION = "2.0";
254
277
  var LEGACY_FACTORY_API_VERSION = "1.0.0";
255
- var FACTORY_PROTOCOL_VERSION = "1.2.0";
278
+ var FACTORY_PROTOCOL_VERSION = "1.3.0";
256
279
  var FACTORY_CLIENT_HEADER = "X-Factory-Client";
257
280
  var FACTORY_CLIENT_VERSION = "X-Client-Version";
258
281
  var DEFAULT_REQUEST_TIMEOUT = 3e4;
259
282
  var SESSION_INIT_TIMEOUT = 6e4;
260
283
  var MCP_AUTH_TIMEOUT = 3e5;
284
+ var COMPACTION_TIMEOUT = 24e4;
285
+ var REWIND_TIMEOUT = 6e4;
261
286
 
262
287
  // src/schemas/shared.ts
263
288
  import { z } from "zod";
289
+ var JsonValueSchema = z.lazy(
290
+ () => z.union([
291
+ z.string(),
292
+ z.number(),
293
+ z.boolean(),
294
+ z.null(),
295
+ z.array(JsonValueSchema),
296
+ z.record(JsonValueSchema)
297
+ ])
298
+ );
299
+ var JsonObjectSchema = z.record(JsonValueSchema);
300
+ var JsonArraySchema = z.array(JsonValueSchema);
264
301
  var TraceContextMetaSchema = z.object({
265
302
  traceparent: z.string().optional(),
266
303
  tracestate: z.string().optional()
267
304
  });
305
+ var ToolSelectionOverridesSchema = z.object({
306
+ enabledToolIds: z.array(z.string()).optional(),
307
+ disabledToolIds: z.array(z.string()).optional()
308
+ });
309
+ var EmptyResultSchema = z.object({}).passthrough();
310
+ var SuccessResultSchema = z.object({ success: z.boolean() }).passthrough();
268
311
  var JsonRpcEnvelopeSchema = z.object({
269
312
  jsonrpc: z.literal(JSONRPC_VERSION),
270
313
  factoryApiVersion: z.literal(LEGACY_FACTORY_API_VERSION),
@@ -274,18 +317,18 @@ var JsonRpcEnvelopeSchema = z.object({
274
317
  var JsonRpcErrorSchema = z.object({
275
318
  code: z.nativeEnum(JsonRpcErrorCode),
276
319
  message: z.string(),
277
- data: z.unknown().optional()
320
+ data: JsonValueSchema.optional()
278
321
  });
279
322
  var BaseRequestSchema = z.object({
280
323
  type: z.literal("request"),
281
324
  id: z.string(),
282
325
  method: z.string(),
283
- params: z.unknown().optional()
326
+ params: JsonValueSchema.optional()
284
327
  });
285
328
  var BaseResponseSuccessSchema = z.object({
286
329
  type: z.literal("response"),
287
330
  id: z.string(),
288
- result: z.unknown()
331
+ result: JsonValueSchema
289
332
  });
290
333
  var BaseResponseFailureSchema = z.object({
291
334
  type: z.literal("response"),
@@ -295,7 +338,7 @@ var BaseResponseFailureSchema = z.object({
295
338
  var BaseNotificationSchema = z.object({
296
339
  type: z.literal("notification"),
297
340
  method: z.string(),
298
- params: z.unknown().optional()
341
+ params: JsonValueSchema.optional()
299
342
  });
300
343
  var JsonRpcRequestSchema = JsonRpcEnvelopeSchema.extend(
301
344
  BaseRequestSchema.shape
@@ -318,61 +361,134 @@ var JsonRpcMessageSchema = z.discriminatedUnion("type", [
318
361
  JsonRpcEnvelopeSchema.extend({
319
362
  type: z.literal("response"),
320
363
  id: z.string().nullable(),
321
- result: z.unknown().optional(),
364
+ result: JsonValueSchema.optional(),
322
365
  error: JsonRpcErrorSchema.optional()
323
366
  }),
324
367
  JsonRpcNotificationSchema
325
368
  ]);
369
+ function createResponseSchema(resultSchema) {
370
+ return z.union([
371
+ JsonRpcResponseSuccessSchema.extend({ result: resultSchema }),
372
+ JsonRpcResponseFailureSchema
373
+ ]);
374
+ }
326
375
 
327
- // src/schemas/messages.ts
376
+ // src/schemas/session-metadata.ts
377
+ import { z as z6 } from "zod";
378
+
379
+ // src/schemas/client.ts
380
+ import { z as z5 } from "zod";
381
+
382
+ // src/schemas/mcp.ts
328
383
  import { z as z2 } from "zod";
329
- var TextBlockSchema = z2.object({
330
- type: z2.literal("text"),
331
- text: z2.string(),
332
- id: z2.string().optional()
333
- }).passthrough();
334
- var Base64ImageSourceSchema = z2.object({
335
- type: z2.literal("base64"),
336
- data: z2.string(),
337
- mediaType: z2.enum(["image/jpeg", "image/png", "image/gif", "image/webp"])
338
- }).passthrough();
339
- var ImageBlockSchema = z2.object({
340
- type: z2.literal("image"),
341
- source: Base64ImageSourceSchema,
342
- id: z2.string().optional()
343
- }).passthrough();
344
- var ThinkingBlockSchema = z2.object({
345
- type: z2.literal("thinking"),
346
- signature: z2.string(),
347
- thinking: z2.string(),
348
- id: z2.string().optional(),
349
- signatureProvider: z2.string().optional()
350
- }).passthrough();
351
- var RedactedThinkingBlockSchema = z2.object({
352
- type: z2.literal("redacted_thinking"),
353
- data: z2.string(),
354
- id: z2.string().optional()
355
- }).passthrough();
356
- var ToolUseBlockSchema = z2.object({
357
- type: z2.literal("tool_use"),
358
- id: z2.string(),
359
- input: z2.record(z2.unknown()),
384
+ var McpStdioServerConfigFieldsSchema = z2.object({
385
+ command: z2.string().optional(),
386
+ args: z2.array(z2.string()).optional()
387
+ });
388
+ var McpHttpServerConfigFieldsSchema = z2.object({
389
+ url: z2.string().optional()
390
+ });
391
+ var McpSseServerConfigFieldsSchema = z2.object({
392
+ url: z2.string(),
393
+ headers: z2.record(z2.string()).optional()
394
+ });
395
+ var McpServerStatusInfoSchema = z2.object({
396
+ name: z2.string(),
397
+ status: z2.nativeEnum(McpServerStatus),
398
+ source: z2.nativeEnum(SettingsLevel),
399
+ isManaged: z2.boolean(),
400
+ error: z2.string().optional(),
401
+ toolCount: z2.number().optional(),
402
+ serverType: z2.nativeEnum(McpServerType).optional(),
403
+ hasAuthTokens: z2.boolean().optional()
404
+ }).passthrough();
405
+ var McpStatusSummarySchema = z2.object({
406
+ total: z2.number(),
407
+ connected: z2.number(),
408
+ connecting: z2.number(),
409
+ failed: z2.number(),
410
+ disabled: z2.number().optional()
411
+ }).passthrough();
412
+ var McpRegistryServerSchema = z2.object({
413
+ name: z2.string(),
414
+ description: z2.string(),
415
+ type: z2.nativeEnum(McpServerType),
416
+ // Stdio config fields
417
+ command: z2.string().optional(),
418
+ args: z2.array(z2.string()).optional(),
419
+ // HTTP config fields
420
+ url: z2.string().optional(),
421
+ // Additional metadata
422
+ note: z2.string().optional(),
423
+ logoUrl: z2.string().optional()
424
+ }).passthrough();
425
+ var McpToolInputSchemaSchema = z2.object({
426
+ type: z2.string().optional(),
427
+ properties: JsonObjectSchema.optional(),
428
+ required: z2.array(z2.string()).optional()
429
+ }).passthrough();
430
+ var McpToolInfoSchema = z2.object({
431
+ serverName: z2.string(),
360
432
  name: z2.string(),
361
- thoughtSignature: z2.string().optional()
433
+ description: z2.string().optional(),
434
+ isEnabled: z2.boolean(),
435
+ isReadOnly: z2.boolean().optional(),
436
+ inputSchema: McpToolInputSchemaSchema.optional()
437
+ }).passthrough();
438
+ var ToolConfirmationListItemSchema = z2.object({
439
+ label: z2.string(),
440
+ value: z2.nativeEnum(ToolConfirmationOutcome)
441
+ }).passthrough();
442
+
443
+ // src/schemas/messages.ts
444
+ import { z as z3 } from "zod";
445
+ var TextBlockSchema = z3.object({
446
+ type: z3.literal("text"),
447
+ text: z3.string(),
448
+ id: z3.string().optional()
449
+ }).passthrough();
450
+ var Base64ImageSourceSchema = z3.object({
451
+ type: z3.literal("base64"),
452
+ data: z3.string(),
453
+ mediaType: z3.enum(["image/jpeg", "image/png", "image/gif", "image/webp"])
454
+ }).passthrough();
455
+ var ImageBlockSchema = z3.object({
456
+ type: z3.literal("image"),
457
+ source: Base64ImageSourceSchema,
458
+ id: z3.string().optional()
362
459
  }).passthrough();
363
- var ToolResultBlockSchema = z2.object({
364
- type: z2.literal("tool_result"),
365
- toolUseId: z2.string(),
366
- content: z2.union([z2.string(), z2.array(z2.unknown())]).optional(),
367
- isError: z2.boolean().optional(),
368
- id: z2.string().optional()
460
+ var ThinkingBlockSchema = z3.object({
461
+ type: z3.literal("thinking"),
462
+ signature: z3.string(),
463
+ thinking: z3.string(),
464
+ id: z3.string().optional(),
465
+ signatureProvider: z3.string().optional()
369
466
  }).passthrough();
370
- var DocumentBlockSchema = z2.object({
371
- type: z2.literal("document"),
372
- source: z2.record(z2.unknown()),
373
- id: z2.string().optional()
467
+ var RedactedThinkingBlockSchema = z3.object({
468
+ type: z3.literal("redacted_thinking"),
469
+ data: z3.string(),
470
+ id: z3.string().optional()
374
471
  }).passthrough();
375
- var ContentBlockSchema = z2.discriminatedUnion("type", [
472
+ var ToolUseBlockSchema = z3.object({
473
+ type: z3.literal("tool_use"),
474
+ id: z3.string(),
475
+ input: JsonObjectSchema,
476
+ name: z3.string(),
477
+ thoughtSignature: z3.string().optional()
478
+ }).passthrough();
479
+ var ToolResultBlockSchema = z3.object({
480
+ type: z3.literal("tool_result"),
481
+ toolUseId: z3.string(),
482
+ content: z3.union([z3.string(), z3.array(JsonValueSchema)]).optional(),
483
+ isError: z3.boolean().optional(),
484
+ id: z3.string().optional()
485
+ }).passthrough();
486
+ var DocumentBlockSchema = z3.object({
487
+ type: z3.literal("document"),
488
+ source: JsonObjectSchema,
489
+ id: z3.string().optional()
490
+ }).passthrough();
491
+ var ContentBlockSchema = z3.discriminatedUnion("type", [
376
492
  TextBlockSchema,
377
493
  ImageBlockSchema,
378
494
  ThinkingBlockSchema,
@@ -381,83 +497,33 @@ var ContentBlockSchema = z2.discriminatedUnion("type", [
381
497
  ToolResultBlockSchema,
382
498
  DocumentBlockSchema
383
499
  ]);
384
- var FactoryDroidMessageSchema = z2.object({
385
- id: z2.string(),
386
- role: z2.enum(["user", "assistant", "tool", "system"]),
387
- content: z2.array(ContentBlockSchema),
388
- createdAt: z2.number(),
389
- updatedAt: z2.number(),
390
- parentId: z2.string().optional(),
391
- visibility: z2.enum(["both", "llm_only", "user_only"]).optional(),
392
- isError: z2.boolean().optional()
393
- }).passthrough();
394
- var DocumentSourceSchema = z2.object({
395
- type: z2.string(),
396
- mediaType: z2.string(),
397
- data: z2.string(),
398
- name: z2.string().optional(),
399
- mime: z2.string().optional()
400
- }).strict();
401
-
402
- // src/schemas/mcp.ts
403
- import { z as z3 } from "zod";
404
- var McpStdioServerConfigFieldsSchema = z3.object({
405
- command: z3.string().optional(),
406
- args: z3.array(z3.string()).optional()
407
- });
408
- var McpHttpServerConfigFieldsSchema = z3.object({
409
- url: z3.string().optional()
410
- });
411
- var McpSseServerConfigFieldsSchema = z3.object({
412
- url: z3.string(),
413
- headers: z3.record(z3.string()).optional()
414
- });
415
- var McpServerStatusInfoSchema = z3.object({
416
- name: z3.string(),
417
- status: z3.nativeEnum(McpServerStatus),
418
- source: z3.nativeEnum(SettingsLevel),
419
- isManaged: z3.boolean(),
420
- error: z3.string().optional(),
421
- toolCount: z3.number().optional(),
422
- serverType: z3.nativeEnum(McpServerType).optional(),
423
- hasAuthTokens: z3.boolean().optional()
424
- }).passthrough();
425
- var McpStatusSummarySchema = z3.object({
426
- total: z3.number(),
427
- connected: z3.number(),
428
- connecting: z3.number(),
429
- failed: z3.number(),
430
- disabled: z3.number().optional()
431
- }).passthrough();
432
- var McpRegistryServerSchema = z3.object({
433
- name: z3.string(),
434
- description: z3.string(),
435
- type: z3.nativeEnum(McpServerType),
436
- // Stdio config fields
437
- command: z3.string().optional(),
438
- args: z3.array(z3.string()).optional(),
439
- // HTTP config fields
440
- url: z3.string().optional(),
441
- // Additional metadata
442
- note: z3.string().optional(),
443
- logoUrl: z3.string().optional()
444
- }).passthrough();
445
- var McpToolInputSchemaSchema = z3.object({
446
- type: z3.string().optional(),
447
- properties: z3.record(z3.unknown()).optional(),
448
- required: z3.array(z3.string()).optional()
449
- }).passthrough();
450
- var McpToolInfoSchema = z3.object({
451
- serverName: z3.string(),
452
- name: z3.string(),
453
- description: z3.string().optional(),
454
- isEnabled: z3.boolean(),
455
- isReadOnly: z3.boolean().optional(),
456
- inputSchema: McpToolInputSchemaSchema.optional()
500
+ var FactoryDroidMessageRole = {
501
+ User: "user",
502
+ Assistant: "assistant",
503
+ Tool: "tool",
504
+ System: "system"
505
+ };
506
+ var FactoryDroidMessageSchema = z3.object({
507
+ id: z3.string(),
508
+ role: z3.enum([
509
+ FactoryDroidMessageRole.User,
510
+ FactoryDroidMessageRole.Assistant,
511
+ FactoryDroidMessageRole.Tool,
512
+ FactoryDroidMessageRole.System
513
+ ]),
514
+ content: z3.array(ContentBlockSchema),
515
+ createdAt: z3.number(),
516
+ updatedAt: z3.number(),
517
+ parentId: z3.string().optional(),
518
+ visibility: z3.enum(["both", "llm_only", "user_only"]).optional(),
519
+ isError: z3.boolean().optional()
457
520
  }).passthrough();
458
- var ToolConfirmationListItemSchema = z3.object({
459
- label: z3.string(),
460
- value: z3.nativeEnum(ToolConfirmationOutcome)
521
+ var DocumentSourceSchema = z3.object({
522
+ type: z3.string(),
523
+ mediaType: z3.string(),
524
+ data: z3.string(),
525
+ name: z3.string().optional(),
526
+ mime: z3.string().optional()
461
527
  }).passthrough();
462
528
 
463
529
  // src/schemas/mission.ts
@@ -608,7 +674,12 @@ var ProgressLogEntrySchema = z4.discriminatedUnion("type", [
608
674
  ]);
609
675
 
610
676
  // src/schemas/client.ts
611
- import { z as z5 } from "zod";
677
+ var SessionModeRequestFieldsShape = {
678
+ modelId: z5.string().optional(),
679
+ autonomyMode: z5.nativeEnum(AutonomyMode).optional(),
680
+ interactionMode: z5.nativeEnum(DroidInteractionMode).optional(),
681
+ autonomyLevel: z5.nativeEnum(AutonomyLevel).optional()
682
+ };
612
683
  var SessionTagSchema = z5.object({
613
684
  name: z5.string(),
614
685
  metadata: z5.record(z5.string()).optional()
@@ -650,7 +721,8 @@ var SessionSettingsSchema = z5.object({
650
721
  interactionMode: z5.nativeEnum(DroidInteractionMode).optional().catch(void 0),
651
722
  autonomyLevel: z5.nativeEnum(AutonomyLevel).optional().catch(void 0),
652
723
  specModeModelId: z5.string().optional(),
653
- specModeReasoningEffort: z5.nativeEnum(ReasoningEffort).optional()
724
+ specModeReasoningEffort: z5.nativeEnum(ReasoningEffort).optional(),
725
+ ...ToolSelectionOverridesSchema.shape
654
726
  }).passthrough();
655
727
  var GitRepoInfoSchema = z5.object({
656
728
  owner: z5.string().optional(),
@@ -670,7 +742,7 @@ var AvailableModelConfigSchema = z5.object({
670
742
  tier: z5.string().optional(),
671
743
  tokenMultiplier: z5.number().optional(),
672
744
  promoLabel: z5.string().optional(),
673
- featureFlag: z5.record(z5.unknown()).optional(),
745
+ featureFlag: JsonObjectSchema.optional(),
674
746
  usesUSBasedInference: z5.boolean().optional()
675
747
  }).passthrough();
676
748
  var TokenUsageSchema = z5.object({
@@ -680,6 +752,13 @@ var TokenUsageSchema = z5.object({
680
752
  cacheReadTokens: z5.number(),
681
753
  thinkingTokens: z5.number()
682
754
  }).passthrough();
755
+ var ContextStatsSchema = z5.object({
756
+ used: z5.number(),
757
+ remaining: z5.number(),
758
+ limit: z5.number(),
759
+ accuracy: z5.nativeEnum(ContextStatsAccuracy),
760
+ updatedAt: z5.string()
761
+ }).passthrough();
683
762
  var WorkerStateInfoSchema = z5.object({
684
763
  startedAt: z5.string(),
685
764
  completedAt: z5.string().optional(),
@@ -707,17 +786,14 @@ var InitializeSessionRequestParamsSchema = z5.object({
707
786
  workspaceId: z5.string().optional(),
708
787
  sessionId: z5.string().optional(),
709
788
  mcpServers: z5.array(McpServerConfigSchema).optional(),
710
- autonomyMode: z5.nativeEnum(AutonomyMode).optional(),
711
- interactionMode: z5.nativeEnum(DroidInteractionMode).optional().catch(void 0),
712
- autonomyLevel: z5.nativeEnum(AutonomyLevel).optional().catch(void 0),
713
- modelId: z5.string().optional(),
789
+ ...SessionModeRequestFieldsShape,
714
790
  reasoningEffort: z5.nativeEnum(ReasoningEffort).optional(),
715
791
  specModeModelId: z5.string().optional(),
716
792
  specModeReasoningEffort: z5.nativeEnum(ReasoningEffort).optional(),
717
793
  decompSessionType: z5.nativeEnum(DecompSessionType).optional(),
718
794
  decompMissionId: z5.string().optional(),
719
795
  skipPermissionsUnsafe: z5.boolean().optional(),
720
- enabledToolIds: z5.array(z5.string()).optional(),
796
+ ...ToolSelectionOverridesSchema.shape,
721
797
  sessionLocation: z5.string().optional(),
722
798
  sessionSource: SessionSourceSchema.optional(),
723
799
  tags: z5.array(SessionTagSchema).optional(),
@@ -728,24 +804,33 @@ var LoadSessionRequestParamsSchema = z5.object({
728
804
  mcpServers: z5.array(McpServerConfigSchema).optional(),
729
805
  mcpOAuthCallbackUri: z5.string().optional()
730
806
  }).strict();
807
+ var OutputFormatType = {
808
+ JsonSchema: "json_schema"
809
+ };
810
+ var OutputFormatSchema = z5.object({
811
+ type: z5.literal(OutputFormatType.JsonSchema),
812
+ schema: JsonObjectSchema
813
+ }).strict();
731
814
  var AddUserMessageRequestParamsSchema = z5.object({
732
815
  messageId: z5.string().optional(),
733
816
  text: z5.string(),
734
817
  images: z5.array(Base64ImageSourceSchema).optional(),
735
- files: z5.array(DocumentSourceSchema).optional()
818
+ files: z5.array(DocumentSourceSchema).optional(),
819
+ outputFormat: OutputFormatSchema.optional()
736
820
  }).strict();
737
821
  var InterruptSessionRequestParamsSchema = z5.object({}).strict();
822
+ var CloseSessionRequestParamsSchema = z5.object({
823
+ reason: z5.enum(["clear", "logout", "prompt_input_exit", "other"]).optional()
824
+ }).strict();
738
825
  var KillWorkerSessionRequestParamsSchema = z5.object({
739
826
  workerSessionId: z5.string()
740
827
  }).strict();
741
828
  var UpdateSessionSettingsRequestParamsSchema = z5.object({
742
- modelId: z5.string().optional(),
829
+ ...SessionModeRequestFieldsShape,
743
830
  reasoningEffort: z5.nativeEnum(ReasoningEffort).optional(),
744
- autonomyMode: z5.nativeEnum(AutonomyMode).optional(),
745
- interactionMode: z5.nativeEnum(DroidInteractionMode).optional().catch(void 0),
746
- autonomyLevel: z5.nativeEnum(AutonomyLevel).optional().catch(void 0),
747
831
  specModeModelId: z5.string().nullable().optional(),
748
- specModeReasoningEffort: z5.nativeEnum(ReasoningEffort).nullable().optional()
832
+ specModeReasoningEffort: z5.nativeEnum(ReasoningEffort).nullable().optional(),
833
+ ...ToolSelectionOverridesSchema.shape
749
834
  }).strict();
750
835
  var ToggleMcpServerRequestParamsSchema = z5.object({
751
836
  serverName: z5.string(),
@@ -781,6 +866,22 @@ var RemoveMcpServerRequestParamsSchema = z5.object({
781
866
  }).strict();
782
867
  var ListMcpRegistryRequestParamsSchema = z5.object({}).strict();
783
868
  var ListMcpToolsRequestParamsSchema = z5.object({}).strict();
869
+ var ExecToolInfoSchema = z5.object({
870
+ id: z5.string(),
871
+ llmId: z5.string(),
872
+ displayName: z5.string(),
873
+ description: z5.string(),
874
+ category: z5.enum(["read", "edit", "execute", "other"]),
875
+ defaultAllowed: z5.boolean(),
876
+ currentlyAllowed: z5.boolean()
877
+ }).passthrough();
878
+ var ListToolsRequestParamsSchema = z5.object({
879
+ ...SessionModeRequestFieldsShape,
880
+ specModeModelId: z5.string().nullable().optional(),
881
+ skipPermissionsUnsafe: z5.boolean().optional(),
882
+ ...ToolSelectionOverridesSchema.shape,
883
+ depth: z5.number().int().min(0).optional()
884
+ }).strict();
784
885
  var ListMcpServersRequestParamsSchema = z5.object({}).strict();
785
886
  var ToggleMcpToolRequestParamsSchema = z5.object({
786
887
  serverName: z5.string(),
@@ -792,6 +893,35 @@ var SubmitBugReportRequestParamsSchema = z5.object({
792
893
  userComment: z5.string(),
793
894
  clientLogs: z5.string().optional()
794
895
  }).strict();
896
+ var RewindFileSnapshotSchema = z5.object({
897
+ filePath: z5.string(),
898
+ contentHash: z5.string(),
899
+ size: z5.number()
900
+ }).passthrough();
901
+ var RewindFileCreationSchema = z5.object({
902
+ filePath: z5.string()
903
+ }).passthrough();
904
+ var RewindEvictedFileSchema = z5.object({
905
+ filePath: z5.string(),
906
+ reason: z5.string()
907
+ }).passthrough();
908
+ var GetRewindInfoRequestParamsSchema = z5.object({
909
+ messageId: z5.string()
910
+ }).passthrough();
911
+ var ExecuteRewindRequestParamsSchema = z5.object({
912
+ messageId: z5.string(),
913
+ filesToRestore: z5.array(RewindFileSnapshotSchema),
914
+ filesToDelete: z5.array(RewindFileCreationSchema),
915
+ forkTitle: z5.string()
916
+ }).passthrough();
917
+ var CompactSessionRequestParamsSchema = z5.object({
918
+ customInstructions: z5.string().optional()
919
+ }).passthrough();
920
+ var RenameSessionRequestParamsSchema = z5.object({
921
+ title: z5.string()
922
+ }).passthrough();
923
+ var ForkSessionRequestParamsSchema = z5.object({}).passthrough();
924
+ var GetContextStatsRequestParamsSchema = z5.object({}).passthrough();
795
925
  var InitializeSessionRequestSchema = JsonRpcRequestSchema.extend({
796
926
  method: z5.literal("droid.initialize_session" /* INITIALIZE_SESSION */),
797
927
  params: InitializeSessionRequestParamsSchema
@@ -808,6 +938,10 @@ var InterruptSessionRequestSchema = JsonRpcRequestSchema.extend({
808
938
  method: z5.literal("droid.interrupt_session" /* INTERRUPT_SESSION */),
809
939
  params: InterruptSessionRequestParamsSchema
810
940
  });
941
+ var CloseSessionRequestSchema = JsonRpcRequestSchema.extend({
942
+ method: z5.literal("droid.close_session" /* CLOSE_SESSION */),
943
+ params: CloseSessionRequestParamsSchema
944
+ });
811
945
  var KillWorkerSessionRequestSchema = JsonRpcRequestSchema.extend({
812
946
  method: z5.literal("droid.kill_worker_session" /* KILL_WORKER_SESSION */),
813
947
  params: KillWorkerSessionRequestParamsSchema
@@ -852,6 +986,10 @@ var ListMcpToolsRequestSchema = JsonRpcRequestSchema.extend({
852
986
  method: z5.literal("droid.list_mcp_tools" /* LIST_MCP_TOOLS */),
853
987
  params: ListMcpToolsRequestParamsSchema
854
988
  });
989
+ var ListToolsRequestSchema = JsonRpcRequestSchema.extend({
990
+ method: z5.literal("droid.list_tools" /* LIST_TOOLS */),
991
+ params: ListToolsRequestParamsSchema
992
+ });
855
993
  var ListMcpServersRequestSchema = JsonRpcRequestSchema.extend({
856
994
  method: z5.literal("droid.list_mcp_servers" /* LIST_MCP_SERVERS */),
857
995
  params: ListMcpServersRequestParamsSchema
@@ -868,10 +1006,35 @@ var SubmitBugReportRequestSchema = JsonRpcRequestSchema.extend({
868
1006
  method: z5.literal("droid.submit_bug_report" /* SUBMIT_BUG_REPORT */),
869
1007
  params: SubmitBugReportRequestParamsSchema
870
1008
  });
1009
+ var GetRewindInfoRequestSchema = JsonRpcRequestSchema.extend({
1010
+ method: z5.literal("droid.get_rewind_info" /* GET_REWIND_INFO */),
1011
+ params: GetRewindInfoRequestParamsSchema
1012
+ });
1013
+ var ExecuteRewindRequestSchema = JsonRpcRequestSchema.extend({
1014
+ method: z5.literal("droid.execute_rewind" /* EXECUTE_REWIND */),
1015
+ params: ExecuteRewindRequestParamsSchema
1016
+ });
1017
+ var CompactSessionRequestSchema = JsonRpcRequestSchema.extend({
1018
+ method: z5.literal("droid.compact_session" /* COMPACT_SESSION */),
1019
+ params: CompactSessionRequestParamsSchema
1020
+ });
1021
+ var ForkSessionRequestSchema = JsonRpcRequestSchema.extend({
1022
+ method: z5.literal("droid.fork_session" /* FORK_SESSION */),
1023
+ params: ForkSessionRequestParamsSchema
1024
+ });
1025
+ var GetContextStatsRequestSchema = JsonRpcRequestSchema.extend({
1026
+ method: z5.literal("droid.get_context_stats" /* GET_CONTEXT_STATS */),
1027
+ params: GetContextStatsRequestParamsSchema
1028
+ });
1029
+ var RenameSessionRequestSchema = JsonRpcRequestSchema.extend({
1030
+ method: z5.literal("droid.rename_session" /* RENAME_SESSION */),
1031
+ params: RenameSessionRequestParamsSchema
1032
+ });
871
1033
  var ClientRequestSchema = z5.discriminatedUnion("method", [
872
1034
  InitializeSessionRequestSchema,
873
1035
  LoadSessionRequestSchema,
874
1036
  AddUserMessageRequestSchema,
1037
+ CloseSessionRequestSchema,
875
1038
  InterruptSessionRequestSchema,
876
1039
  KillWorkerSessionRequestSchema,
877
1040
  UpdateSessionSettingsRequestSchema,
@@ -884,10 +1047,17 @@ var ClientRequestSchema = z5.discriminatedUnion("method", [
884
1047
  RemoveMcpServerRequestSchema,
885
1048
  ListMcpRegistryRequestSchema,
886
1049
  ListMcpToolsRequestSchema,
1050
+ ListToolsRequestSchema,
887
1051
  ListMcpServersRequestSchema,
888
1052
  ToggleMcpToolRequestSchema,
889
1053
  ListSkillsRequestSchema,
890
- SubmitBugReportRequestSchema
1054
+ SubmitBugReportRequestSchema,
1055
+ GetRewindInfoRequestSchema,
1056
+ ExecuteRewindRequestSchema,
1057
+ CompactSessionRequestSchema,
1058
+ ForkSessionRequestSchema,
1059
+ GetContextStatsRequestSchema,
1060
+ RenameSessionRequestSchema
891
1061
  ]);
892
1062
  var MissionSnapshotSchema = z5.object({
893
1063
  state: z5.nativeEnum(MissionState),
@@ -900,20 +1070,20 @@ var MissionSnapshotSchema = z5.object({
900
1070
  }).passthrough();
901
1071
  var InitializeSessionResultSchema = z5.object({
902
1072
  sessionId: z5.string(),
903
- session: z5.record(z5.unknown()),
1073
+ session: JsonObjectSchema,
904
1074
  mcpServers: z5.array(McpServerConfigSchema).optional(),
905
1075
  settings: SessionSettingsSchema,
906
1076
  gitRepo: GitRepoInfoSchema.optional(),
907
1077
  availableModels: z5.array(AvailableModelConfigSchema).optional()
908
1078
  }).passthrough();
909
1079
  var LoadSessionResultSchema = z5.object({
910
- session: z5.record(z5.unknown()),
1080
+ session: JsonObjectSchema,
911
1081
  mcpServers: z5.array(McpServerConfigSchema).optional(),
912
- pendingPermissions: z5.array(z5.record(z5.unknown())).optional(),
913
- pendingAskUserRequests: z5.array(z5.record(z5.unknown())).optional(),
1082
+ pendingPermissions: z5.array(JsonObjectSchema).optional(),
1083
+ pendingAskUserRequests: z5.array(JsonObjectSchema).optional(),
914
1084
  settings: SessionSettingsSchema,
915
1085
  isAgentLoopInProgress: z5.boolean().optional(),
916
- queuedMessages: z5.array(z5.record(z5.unknown())).optional(),
1086
+ queuedMessages: z5.array(JsonObjectSchema).optional(),
917
1087
  gitRepo: GitRepoInfoSchema.optional(),
918
1088
  cwd: z5.string().optional(),
919
1089
  callingSessionId: z5.string().optional(),
@@ -923,258 +1093,386 @@ var LoadSessionResultSchema = z5.object({
923
1093
  mission: MissionSnapshotSchema.optional(),
924
1094
  decompSessionType: z5.nativeEnum(DecompSessionType).optional()
925
1095
  }).passthrough();
926
- var AddUserMessageResultSchema = z5.object({}).passthrough();
927
- var InterruptSessionResultSchema = z5.object({}).passthrough();
928
- var KillWorkerSessionResultSchema = z5.object({}).passthrough();
929
- var UpdateSessionSettingsResultSchema = z5.object({}).passthrough();
930
- var ToggleMcpServerResultSchema = z5.object({ success: z5.boolean() }).passthrough();
931
- var AuthenticateMcpServerResultSchema = z5.object({ success: z5.boolean() }).passthrough();
932
- var CancelMcpAuthResultSchema = z5.object({ success: z5.boolean() }).passthrough();
933
- var ClearMcpAuthResultSchema = z5.object({ success: z5.boolean() }).passthrough();
934
- var SubmitMcpAuthCodeResultSchema = z5.object({ success: z5.boolean() }).passthrough();
935
- var AddMcpServerResultSchema = z5.object({ success: z5.boolean() }).passthrough();
936
- var RemoveMcpServerResultSchema = z5.object({ success: z5.boolean() }).passthrough();
1096
+ var AddUserMessageResultSchema = EmptyResultSchema;
1097
+ var InterruptSessionResultSchema = EmptyResultSchema;
1098
+ var CloseSessionResultSchema = EmptyResultSchema;
1099
+ var KillWorkerSessionResultSchema = EmptyResultSchema;
1100
+ var UpdateSessionSettingsResultSchema = EmptyResultSchema;
1101
+ var ToggleMcpServerResultSchema = SuccessResultSchema;
1102
+ var AuthenticateMcpServerResultSchema = SuccessResultSchema;
1103
+ var CancelMcpAuthResultSchema = SuccessResultSchema;
1104
+ var ClearMcpAuthResultSchema = SuccessResultSchema;
1105
+ var SubmitMcpAuthCodeResultSchema = SuccessResultSchema;
1106
+ var AddMcpServerResultSchema = SuccessResultSchema;
1107
+ var RemoveMcpServerResultSchema = SuccessResultSchema;
937
1108
  var ListMcpRegistryResultSchema = z5.object({ servers: z5.array(McpRegistryServerSchema) }).passthrough();
938
1109
  var ListMcpToolsResultSchema = z5.object({ tools: z5.array(McpToolInfoSchema) }).passthrough();
1110
+ var ListToolsResultSchema = z5.object({ tools: z5.array(ExecToolInfoSchema) }).passthrough();
939
1111
  var ListMcpServersResultSchema = z5.object({
940
1112
  servers: z5.array(McpServerStatusInfoSchema),
941
1113
  summary: McpStatusSummarySchema
942
1114
  }).passthrough();
943
- var ToggleMcpToolResultSchema = z5.object({ success: z5.boolean() }).passthrough();
1115
+ var ToggleMcpToolResultSchema = SuccessResultSchema;
944
1116
  var ListSkillsResultSchema = z5.object({ skills: z5.array(SkillInfoSchema) }).passthrough();
945
1117
  var SubmitBugReportResultSchema = z5.object({ bugReportId: z5.string() }).passthrough();
946
- var InitializeSessionResponseSchema = z5.union([
947
- JsonRpcResponseSuccessSchema.extend({
948
- result: InitializeSessionResultSchema
949
- }),
950
- JsonRpcResponseFailureSchema
951
- ]);
952
- var _LoadSessionResponseSchema = z5.union([
953
- JsonRpcResponseSuccessSchema.extend({ result: LoadSessionResultSchema }),
954
- JsonRpcResponseFailureSchema
955
- ]);
1118
+ var GetRewindInfoResultSchema = z5.object({
1119
+ availableFiles: z5.array(RewindFileSnapshotSchema),
1120
+ createdFiles: z5.array(RewindFileCreationSchema),
1121
+ evictedFiles: z5.array(RewindEvictedFileSchema)
1122
+ }).passthrough();
1123
+ var ExecuteRewindResultSchema = z5.object({
1124
+ newSessionId: z5.string(),
1125
+ restoredCount: z5.number(),
1126
+ deletedCount: z5.number(),
1127
+ failedRestoreCount: z5.number(),
1128
+ failedDeleteCount: z5.number()
1129
+ }).passthrough();
1130
+ var CompactSessionResultSchema = z5.object({
1131
+ newSessionId: z5.string(),
1132
+ removedCount: z5.number()
1133
+ }).passthrough();
1134
+ var ForkSessionResultSchema = z5.object({
1135
+ newSessionId: z5.string()
1136
+ }).passthrough();
1137
+ var GetContextStatsResultSchema = ContextStatsSchema;
1138
+ var RenameSessionResultSchema = SuccessResultSchema;
1139
+ var InitializeSessionResponseSchema = createResponseSchema(
1140
+ InitializeSessionResultSchema
1141
+ );
1142
+ var _LoadSessionResponseSchema = createResponseSchema(
1143
+ LoadSessionResultSchema
1144
+ );
956
1145
  var LoadSessionResponseSchema = _LoadSessionResponseSchema;
957
- var AddUserMessageResponseSchema = z5.union([
958
- JsonRpcResponseSuccessSchema.extend({ result: AddUserMessageResultSchema }),
959
- JsonRpcResponseFailureSchema
960
- ]);
961
- var InterruptSessionResponseSchema = z5.union([
962
- JsonRpcResponseSuccessSchema.extend({
963
- result: InterruptSessionResultSchema
964
- }),
965
- JsonRpcResponseFailureSchema
966
- ]);
967
- var KillWorkerSessionResponseSchema = z5.union([
968
- JsonRpcResponseSuccessSchema.extend({
969
- result: KillWorkerSessionResultSchema
970
- }),
971
- JsonRpcResponseFailureSchema
972
- ]);
973
- var UpdateSessionSettingsResponseSchema = z5.union([
974
- JsonRpcResponseSuccessSchema.extend({
975
- result: UpdateSessionSettingsResultSchema
976
- }),
977
- JsonRpcResponseFailureSchema
978
- ]);
979
- var ToggleMcpServerResponseSchema = z5.union([
980
- JsonRpcResponseSuccessSchema.extend({
981
- result: ToggleMcpServerResultSchema
982
- }),
983
- JsonRpcResponseFailureSchema
984
- ]);
985
- var AuthenticateMcpServerResponseSchema = z5.union([
986
- JsonRpcResponseSuccessSchema.extend({
987
- result: AuthenticateMcpServerResultSchema
988
- }),
989
- JsonRpcResponseFailureSchema
990
- ]);
991
- var CancelMcpAuthResponseSchema = z5.union([
992
- JsonRpcResponseSuccessSchema.extend({ result: CancelMcpAuthResultSchema }),
993
- JsonRpcResponseFailureSchema
994
- ]);
995
- var ClearMcpAuthResponseSchema = z5.union([
996
- JsonRpcResponseSuccessSchema.extend({ result: ClearMcpAuthResultSchema }),
997
- JsonRpcResponseFailureSchema
998
- ]);
999
- var SubmitMcpAuthCodeResponseSchema = z5.union([
1000
- JsonRpcResponseSuccessSchema.extend({
1001
- result: SubmitMcpAuthCodeResultSchema
1002
- }),
1003
- JsonRpcResponseFailureSchema
1004
- ]);
1005
- var AddMcpServerResponseSchema = z5.union([
1006
- JsonRpcResponseSuccessSchema.extend({ result: AddMcpServerResultSchema }),
1007
- JsonRpcResponseFailureSchema
1008
- ]);
1009
- var RemoveMcpServerResponseSchema = z5.union([
1010
- JsonRpcResponseSuccessSchema.extend({ result: RemoveMcpServerResultSchema }),
1011
- JsonRpcResponseFailureSchema
1012
- ]);
1013
- var ListMcpRegistryResponseSchema = z5.union([
1014
- JsonRpcResponseSuccessSchema.extend({
1015
- result: ListMcpRegistryResultSchema
1016
- }),
1017
- JsonRpcResponseFailureSchema
1018
- ]);
1019
- var ListMcpToolsResponseSchema = z5.union([
1020
- JsonRpcResponseSuccessSchema.extend({ result: ListMcpToolsResultSchema }),
1021
- JsonRpcResponseFailureSchema
1022
- ]);
1023
- var ListMcpServersResponseSchema = z5.union([
1024
- JsonRpcResponseSuccessSchema.extend({ result: ListMcpServersResultSchema }),
1025
- JsonRpcResponseFailureSchema
1026
- ]);
1027
- var ToggleMcpToolResponseSchema = z5.union([
1028
- JsonRpcResponseSuccessSchema.extend({ result: ToggleMcpToolResultSchema }),
1029
- JsonRpcResponseFailureSchema
1030
- ]);
1031
- var ListSkillsResponseSchema = z5.union([
1032
- JsonRpcResponseSuccessSchema.extend({ result: ListSkillsResultSchema }),
1033
- JsonRpcResponseFailureSchema
1034
- ]);
1035
- var SubmitBugReportResponseSchema = z5.union([
1036
- JsonRpcResponseSuccessSchema.extend({ result: SubmitBugReportResultSchema }),
1037
- JsonRpcResponseFailureSchema
1146
+ var AddUserMessageResponseSchema = createResponseSchema(
1147
+ AddUserMessageResultSchema
1148
+ );
1149
+ var InterruptSessionResponseSchema = createResponseSchema(
1150
+ InterruptSessionResultSchema
1151
+ );
1152
+ var CloseSessionResponseSchema = createResponseSchema(
1153
+ CloseSessionResultSchema
1154
+ );
1155
+ var KillWorkerSessionResponseSchema = createResponseSchema(
1156
+ KillWorkerSessionResultSchema
1157
+ );
1158
+ var UpdateSessionSettingsResponseSchema = createResponseSchema(
1159
+ UpdateSessionSettingsResultSchema
1160
+ );
1161
+ var ToggleMcpServerResponseSchema = createResponseSchema(
1162
+ ToggleMcpServerResultSchema
1163
+ );
1164
+ var AuthenticateMcpServerResponseSchema = createResponseSchema(
1165
+ AuthenticateMcpServerResultSchema
1166
+ );
1167
+ var CancelMcpAuthResponseSchema = createResponseSchema(
1168
+ CancelMcpAuthResultSchema
1169
+ );
1170
+ var ClearMcpAuthResponseSchema = createResponseSchema(
1171
+ ClearMcpAuthResultSchema
1172
+ );
1173
+ var SubmitMcpAuthCodeResponseSchema = createResponseSchema(
1174
+ SubmitMcpAuthCodeResultSchema
1175
+ );
1176
+ var AddMcpServerResponseSchema = createResponseSchema(
1177
+ AddMcpServerResultSchema
1178
+ );
1179
+ var RemoveMcpServerResponseSchema = createResponseSchema(
1180
+ RemoveMcpServerResultSchema
1181
+ );
1182
+ var ListMcpRegistryResponseSchema = createResponseSchema(
1183
+ ListMcpRegistryResultSchema
1184
+ );
1185
+ var ListMcpToolsResponseSchema = createResponseSchema(
1186
+ ListMcpToolsResultSchema
1187
+ );
1188
+ var ListToolsResponseSchema = createResponseSchema(
1189
+ ListToolsResultSchema
1190
+ );
1191
+ var ListMcpServersResponseSchema = createResponseSchema(
1192
+ ListMcpServersResultSchema
1193
+ );
1194
+ var ToggleMcpToolResponseSchema = createResponseSchema(
1195
+ ToggleMcpToolResultSchema
1196
+ );
1197
+ var ListSkillsResponseSchema = createResponseSchema(
1198
+ ListSkillsResultSchema
1199
+ );
1200
+ var SubmitBugReportResponseSchema = createResponseSchema(
1201
+ SubmitBugReportResultSchema
1202
+ );
1203
+ var GetRewindInfoResponseSchema = createResponseSchema(
1204
+ GetRewindInfoResultSchema
1205
+ );
1206
+ var ExecuteRewindResponseSchema = createResponseSchema(
1207
+ ExecuteRewindResultSchema
1208
+ );
1209
+ var CompactSessionResponseSchema = createResponseSchema(
1210
+ CompactSessionResultSchema
1211
+ );
1212
+ var ForkSessionResponseSchema = createResponseSchema(
1213
+ ForkSessionResultSchema
1214
+ );
1215
+ var GetContextStatsResponseSchema = createResponseSchema(
1216
+ GetContextStatsResultSchema
1217
+ );
1218
+ var RenameSessionResponseSchema = createResponseSchema(
1219
+ RenameSessionResultSchema
1220
+ );
1221
+
1222
+ // src/schemas/session-metadata.ts
1223
+ var SessionMetadataSchema = z6.object({
1224
+ id: z6.string(),
1225
+ title: z6.string(),
1226
+ sessionTitle: z6.string().optional(),
1227
+ owner: z6.string(),
1228
+ messageCount: z6.number(),
1229
+ modifiedTime: z6.date(),
1230
+ createdTime: z6.date(),
1231
+ isFavorite: z6.boolean().optional(),
1232
+ cwd: z6.string().optional(),
1233
+ decompSessionType: z6.nativeEnum(DecompSessionType).optional(),
1234
+ decompMissionId: z6.string().optional()
1235
+ }).passthrough();
1236
+ var SessionStartEventSchema = z6.object({
1237
+ type: z6.literal("session_start"),
1238
+ sessionId: z6.string().optional(),
1239
+ title: z6.string().optional(),
1240
+ sessionTitle: z6.string().optional(),
1241
+ owner: z6.string().optional(),
1242
+ cwd: z6.string().optional(),
1243
+ decompSessionType: z6.nativeEnum(DecompSessionType).optional().catch(void 0),
1244
+ decompMissionId: z6.string().optional()
1245
+ }).passthrough();
1246
+ var SessionSettingsFileSchema = z6.object({
1247
+ archivedAt: z6.string().optional(),
1248
+ tags: z6.array(SessionTagSchema).optional()
1249
+ }).passthrough();
1250
+
1251
+ // src/schemas/hooks.ts
1252
+ import { z as z7 } from "zod";
1253
+ var DroidHookEventSchema = z7.enum([
1254
+ "PreToolUse",
1255
+ "PostToolUse",
1256
+ "Notification",
1257
+ "UserPromptSubmit",
1258
+ "Stop",
1259
+ "SubagentStop",
1260
+ "PreCompact",
1261
+ "SessionStart",
1262
+ "SessionEnd"
1038
1263
  ]);
1264
+ var DroidHookSpecificOutputSchema = z7.object({
1265
+ hookEventName: DroidHookEventSchema.optional(),
1266
+ permissionDecision: z7.enum(["allow", "deny", "ask"]).optional(),
1267
+ permissionDecisionReason: z7.string().optional(),
1268
+ additionalContext: z7.string().optional(),
1269
+ updatedInput: z7.record(z7.unknown()).optional()
1270
+ }).passthrough();
1271
+ var DroidHookOutputSchema = z7.object({
1272
+ continue: z7.boolean().optional(),
1273
+ stopReason: z7.string().optional(),
1274
+ suppressOutput: z7.boolean().optional(),
1275
+ systemMessage: z7.string().optional(),
1276
+ decision: z7.enum(["block", "approve"]).optional(),
1277
+ reason: z7.string().optional(),
1278
+ hookSpecificOutput: DroidHookSpecificOutputSchema.optional()
1279
+ }).passthrough();
1280
+ var DroidHookExecutionResultSchema = DroidHookOutputSchema.extend({
1281
+ exitCode: z7.number(),
1282
+ stdout: z7.string(),
1283
+ stderr: z7.string()
1284
+ });
1039
1285
 
1040
1286
  // src/schemas/server.ts
1041
- import { z as z6 } from "zod";
1042
- var ToolUseSchema = z6.object({
1043
- type: z6.literal("tool_use"),
1044
- id: z6.string(),
1045
- input: z6.record(z6.unknown()),
1046
- name: z6.string(),
1047
- thoughtSignature: z6.string().optional()
1048
- }).passthrough();
1049
- var ErrorDetailSchema = z6.object({
1050
- name: z6.string(),
1051
- message: z6.string()
1052
- }).passthrough();
1053
- var ToolProgressUpdateSchema = z6.object({
1054
- type: z6.enum(["tool_call", "tool_result", "error", "status", "message"]),
1055
- toolName: z6.string().optional(),
1056
- status: z6.string().optional(),
1057
- details: z6.string().optional(),
1058
- text: z6.string().optional(),
1059
- error: z6.string().optional(),
1060
- timestamp: z6.number().optional(),
1061
- parameters: z6.record(z6.unknown()).optional(),
1062
- valueSnippet: z6.string().optional(),
1063
- subagentSessionId: z6.string().optional()
1064
- }).passthrough();
1065
- var SettingsUpdatedPayloadSchema = z6.object({
1066
- autonomyMode: z6.nativeEnum(AutonomyMode).optional(),
1067
- interactionMode: z6.nativeEnum(DroidInteractionMode).optional().catch(void 0),
1068
- autonomyLevel: z6.nativeEnum(AutonomyLevel).optional().catch(void 0),
1069
- modelId: z6.string().optional(),
1070
- reasoningEffort: z6.nativeEnum(ReasoningEffort).optional(),
1071
- specModeModelId: z6.string().optional(),
1072
- specModeReasoningEffort: z6.nativeEnum(ReasoningEffort).optional()
1073
- }).passthrough();
1074
- var ToolResultNotificationSchema = z6.object({
1075
- type: z6.literal("tool_result" /* TOOL_RESULT */),
1076
- messageId: z6.string(),
1077
- toolUseId: z6.string(),
1078
- content: z6.unknown().optional(),
1079
- isError: z6.boolean().optional(),
1080
- id: z6.string().optional()
1081
- }).passthrough();
1082
- var ToolProgressUpdateNotificationSchema = z6.object({
1083
- type: z6.literal("tool_progress_update" /* TOOL_PROGRESS_UPDATE */),
1084
- toolUseId: z6.string(),
1085
- toolName: z6.string(),
1287
+ import { z as z8 } from "zod";
1288
+ var ToolUseBlockSchema2 = ToolUseBlockSchema;
1289
+ var ToolUseSchema = ToolUseBlockSchema2;
1290
+ var ErrorDetailSchema = z8.object({
1291
+ name: z8.string(),
1292
+ message: z8.string()
1293
+ }).passthrough();
1294
+ var ToolProgressUpdateSchema = z8.object({
1295
+ type: z8.enum(["tool_call", "tool_result", "error", "status", "message"]),
1296
+ toolName: z8.string().optional(),
1297
+ status: z8.string().optional(),
1298
+ details: z8.string().optional(),
1299
+ text: z8.string().optional(),
1300
+ error: z8.string().optional(),
1301
+ timestamp: z8.number().optional(),
1302
+ parameters: JsonObjectSchema.optional(),
1303
+ valueSnippet: z8.string().optional(),
1304
+ subagentSessionId: z8.string().optional()
1305
+ }).passthrough();
1306
+ var SettingsUpdatedPayloadSchema = z8.object({
1307
+ autonomyMode: z8.nativeEnum(AutonomyMode).optional(),
1308
+ interactionMode: z8.nativeEnum(DroidInteractionMode).optional().catch(void 0),
1309
+ autonomyLevel: z8.nativeEnum(AutonomyLevel).optional().catch(void 0),
1310
+ modelId: z8.string().optional(),
1311
+ reasoningEffort: z8.nativeEnum(ReasoningEffort).optional(),
1312
+ specModeModelId: z8.string().optional(),
1313
+ specModeReasoningEffort: z8.nativeEnum(ReasoningEffort).optional(),
1314
+ ...ToolSelectionOverridesSchema.shape
1315
+ }).passthrough();
1316
+ var ToolResultNotificationSchema = z8.object({
1317
+ type: z8.literal("tool_result" /* TOOL_RESULT */),
1318
+ messageId: z8.string(),
1319
+ toolUseId: z8.string(),
1320
+ content: JsonValueSchema.optional(),
1321
+ isError: z8.boolean().optional(),
1322
+ id: z8.string().optional()
1323
+ }).passthrough();
1324
+ var ToolProgressUpdateNotificationSchema = z8.object({
1325
+ type: z8.literal("tool_progress_update" /* TOOL_PROGRESS_UPDATE */),
1326
+ toolUseId: z8.string(),
1327
+ toolName: z8.string(),
1086
1328
  update: ToolProgressUpdateSchema
1087
1329
  }).passthrough();
1088
- var CreateMessageNotificationSchema = z6.object({
1089
- type: z6.literal("create_message" /* CREATE_MESSAGE */),
1330
+ var CreateMessageNotificationSchema = z8.object({
1331
+ type: z8.literal("create_message" /* CREATE_MESSAGE */),
1090
1332
  message: FactoryDroidMessageSchema,
1091
- parentId: z6.string().optional(),
1092
- requestId: z6.string().optional()
1093
- }).passthrough();
1094
- var ErrorNotificationSchema = z6.object({
1095
- type: z6.literal("error" /* ERROR */),
1096
- message: z6.string(),
1097
- errorType: z6.nativeEnum(DroidErrorType),
1098
- timestamp: z6.string(),
1333
+ parentId: z8.string().optional(),
1334
+ requestId: z8.string().optional()
1335
+ }).passthrough();
1336
+ var ErrorNotificationSchema = z8.object({
1337
+ type: z8.literal("error" /* ERROR */),
1338
+ message: z8.string(),
1339
+ errorType: z8.nativeEnum(DroidErrorType),
1340
+ timestamp: z8.string(),
1099
1341
  error: ErrorDetailSchema.optional()
1100
1342
  }).passthrough();
1101
- var DroidWorkingStateChangedNotificationSchema = z6.object({
1102
- type: z6.literal("droid_working_state_changed" /* DROID_WORKING_STATE_CHANGED */),
1103
- newState: z6.nativeEnum(DroidWorkingState)
1343
+ var DroidWorkingStateChangedNotificationSchema = z8.object({
1344
+ type: z8.literal("droid_working_state_changed" /* DROID_WORKING_STATE_CHANGED */),
1345
+ newState: z8.nativeEnum(DroidWorkingState)
1104
1346
  }).passthrough();
1105
- var PermissionResolvedNotificationSchema = z6.object({
1106
- type: z6.literal("permission_resolved" /* PERMISSION_RESOLVED */),
1107
- requestId: z6.string(),
1108
- toolUseIds: z6.array(z6.string()),
1109
- selectedOption: z6.nativeEnum(ToolConfirmationOutcome)
1347
+ var PermissionResolvedNotificationSchema = z8.object({
1348
+ type: z8.literal("permission_resolved" /* PERMISSION_RESOLVED */),
1349
+ requestId: z8.string(),
1350
+ toolUseIds: z8.array(z8.string()),
1351
+ selectedOption: z8.nativeEnum(ToolConfirmationOutcome)
1110
1352
  }).passthrough();
1111
- var SettingsUpdatedNotificationSchema = z6.object({
1112
- type: z6.literal("settings_updated" /* SETTINGS_UPDATED */),
1353
+ var SettingsUpdatedNotificationSchema = z8.object({
1354
+ type: z8.literal("settings_updated" /* SETTINGS_UPDATED */),
1113
1355
  settings: SettingsUpdatedPayloadSchema
1114
1356
  }).passthrough();
1115
- var SessionTitleUpdatedNotificationSchema = z6.object({
1116
- type: z6.literal("session_title_updated" /* SESSION_TITLE_UPDATED */),
1117
- title: z6.string()
1357
+ var SessionTitleUpdatedNotificationSchema = z8.object({
1358
+ type: z8.literal("session_title_updated" /* SESSION_TITLE_UPDATED */),
1359
+ title: z8.string()
1118
1360
  }).passthrough();
1119
- var McpStatusChangedNotificationSchema = z6.object({
1120
- type: z6.literal("mcp_status_changed" /* MCP_STATUS_CHANGED */),
1121
- servers: z6.array(McpServerStatusInfoSchema),
1361
+ var McpStatusChangedNotificationSchema = z8.object({
1362
+ type: z8.literal("mcp_status_changed" /* MCP_STATUS_CHANGED */),
1363
+ servers: z8.array(McpServerStatusInfoSchema),
1122
1364
  summary: McpStatusSummarySchema
1123
1365
  }).passthrough();
1124
- var AssistantTextDeltaNotificationSchema = z6.object({
1125
- type: z6.literal("assistant_text_delta" /* ASSISTANT_TEXT_DELTA */),
1126
- messageId: z6.string(),
1127
- blockIndex: z6.number(),
1128
- textDelta: z6.string()
1129
- }).passthrough();
1130
- var ThinkingTextDeltaNotificationSchema = z6.object({
1131
- type: z6.literal("thinking_text_delta" /* THINKING_TEXT_DELTA */),
1132
- messageId: z6.string(),
1133
- blockIndex: z6.number(),
1134
- textDelta: z6.string()
1135
- }).passthrough();
1136
- var SessionTokenUsageChangedNotificationSchema = z6.object({
1137
- type: z6.literal("session_token_usage_changed" /* SESSION_TOKEN_USAGE_CHANGED */),
1138
- sessionId: z6.string(),
1366
+ var AssistantTextDeltaNotificationSchema = z8.object({
1367
+ type: z8.literal("assistant_text_delta" /* ASSISTANT_TEXT_DELTA */),
1368
+ messageId: z8.string(),
1369
+ blockIndex: z8.number(),
1370
+ textDelta: z8.string()
1371
+ }).passthrough();
1372
+ var AssistantTextCompleteNotificationSchema = z8.object({
1373
+ type: z8.literal("assistant_text_complete" /* ASSISTANT_TEXT_COMPLETE */),
1374
+ messageId: z8.string(),
1375
+ blockIndex: z8.number()
1376
+ }).passthrough();
1377
+ var ThinkingTextDeltaNotificationSchema = z8.object({
1378
+ type: z8.literal("thinking_text_delta" /* THINKING_TEXT_DELTA */),
1379
+ messageId: z8.string(),
1380
+ blockIndex: z8.number(),
1381
+ textDelta: z8.string()
1382
+ }).passthrough();
1383
+ var ThinkingTextCompleteNotificationSchema = z8.object({
1384
+ type: z8.literal("thinking_text_complete" /* THINKING_TEXT_COMPLETE */),
1385
+ messageId: z8.string(),
1386
+ blockIndex: z8.number(),
1387
+ durationMs: z8.number().optional()
1388
+ }).passthrough();
1389
+ var ToolCallNotificationSchema = z8.object({
1390
+ type: z8.literal("tool_call" /* TOOL_CALL */),
1391
+ toolUse: ToolUseBlockSchema2
1392
+ }).passthrough();
1393
+ var SessionTokenUsageChangedNotificationSchema = z8.object({
1394
+ type: z8.literal("session_token_usage_changed" /* SESSION_TOKEN_USAGE_CHANGED */),
1395
+ sessionId: z8.string(),
1139
1396
  tokenUsage: TokenUsageSchema
1140
1397
  }).passthrough();
1141
- var MissionStateChangedNotificationSchema = z6.object({
1142
- type: z6.literal("mission_state_changed" /* MISSION_STATE_CHANGED */),
1143
- state: z6.nativeEnum(MissionState)
1398
+ var MissionStateChangedNotificationSchema = z8.object({
1399
+ type: z8.literal("mission_state_changed" /* MISSION_STATE_CHANGED */),
1400
+ state: z8.nativeEnum(MissionState)
1401
+ }).passthrough();
1402
+ var MissionFeaturesChangedNotificationSchema = z8.object({
1403
+ type: z8.literal("mission_features_changed" /* MISSION_FEATURES_CHANGED */),
1404
+ features: z8.array(MissionFeatureSchema)
1405
+ }).passthrough();
1406
+ var MissionProgressEntryNotificationSchema = z8.object({
1407
+ type: z8.literal("mission_progress_entry" /* MISSION_PROGRESS_ENTRY */),
1408
+ progressLog: z8.array(ProgressLogEntrySchema)
1409
+ }).passthrough();
1410
+ var MissionHeartbeatNotificationSchema = z8.object({
1411
+ type: z8.literal("mission_heartbeat" /* MISSION_HEARTBEAT */),
1412
+ timestamp: z8.string()
1144
1413
  }).passthrough();
1145
- var MissionFeaturesChangedNotificationSchema = z6.object({
1146
- type: z6.literal("mission_features_changed" /* MISSION_FEATURES_CHANGED */),
1147
- features: z6.array(MissionFeatureSchema)
1414
+ var MissionWorkerStartedNotificationSchema = z8.object({
1415
+ type: z8.literal("mission_worker_started" /* MISSION_WORKER_STARTED */),
1416
+ workerSessionId: z8.string()
1148
1417
  }).passthrough();
1149
- var MissionProgressEntryNotificationSchema = z6.object({
1150
- type: z6.literal("mission_progress_entry" /* MISSION_PROGRESS_ENTRY */),
1151
- progressLog: z6.array(ProgressLogEntrySchema)
1418
+ var MissionWorkerCompletedNotificationSchema = z8.object({
1419
+ type: z8.literal("mission_worker_completed" /* MISSION_WORKER_COMPLETED */),
1420
+ workerSessionId: z8.string(),
1421
+ exitCode: z8.number()
1152
1422
  }).passthrough();
1153
- var MissionHeartbeatNotificationSchema = z6.object({
1154
- type: z6.literal("mission_heartbeat" /* MISSION_HEARTBEAT */),
1155
- timestamp: z6.string()
1423
+ var McpAuthRequiredNotificationSchema = z8.object({
1424
+ type: z8.literal("mcp_auth_required" /* MCP_AUTH_REQUIRED */),
1425
+ serverName: z8.string(),
1426
+ authUrl: z8.string(),
1427
+ message: z8.string(),
1428
+ state: z8.string()
1156
1429
  }).passthrough();
1157
- var MissionWorkerStartedNotificationSchema = z6.object({
1158
- type: z6.literal("mission_worker_started" /* MISSION_WORKER_STARTED */),
1159
- workerSessionId: z6.string()
1430
+ var McpAuthCompletedNotificationSchema = z8.object({
1431
+ type: z8.literal("mcp_auth_completed" /* MCP_AUTH_COMPLETED */),
1432
+ serverName: z8.string(),
1433
+ outcome: z8.nativeEnum(McpAuthOutcome),
1434
+ message: z8.string()
1160
1435
  }).passthrough();
1161
- var MissionWorkerCompletedNotificationSchema = z6.object({
1162
- type: z6.literal("mission_worker_completed" /* MISSION_WORKER_COMPLETED */),
1163
- workerSessionId: z6.string(),
1164
- exitCode: z6.number()
1436
+ var HookCommandSchema = z8.object({
1437
+ command: z8.string(),
1438
+ timeout: z8.number().optional()
1165
1439
  }).passthrough();
1166
- var McpAuthRequiredNotificationSchema = z6.object({
1167
- type: z6.literal("mcp_auth_required" /* MCP_AUTH_REQUIRED */),
1168
- serverName: z6.string(),
1169
- authUrl: z6.string(),
1170
- message: z6.string(),
1171
- state: z6.string()
1440
+ var HookResultSchema = z8.object({
1441
+ exitCode: z8.number(),
1442
+ stdout: z8.string(),
1443
+ stderr: z8.string(),
1444
+ command: z8.string().optional(),
1445
+ timeout: z8.number().optional()
1172
1446
  }).passthrough();
1173
- var McpAuthCompletedNotificationSchema = z6.object({
1174
- type: z6.literal("mcp_auth_completed" /* MCP_AUTH_COMPLETED */),
1175
- serverName: z6.string(),
1176
- outcome: z6.nativeEnum(McpAuthOutcome),
1177
- message: z6.string()
1447
+ var HookExecutionStartedNotificationSchema = z8.object({
1448
+ type: z8.literal("hook_execution_started" /* HOOK_EXECUTION_STARTED */),
1449
+ hookId: z8.string(),
1450
+ hookEventName: DroidHookEventSchema,
1451
+ hookMatcher: z8.string().optional(),
1452
+ hookCommands: z8.array(HookCommandSchema),
1453
+ hookToolCallId: z8.string().optional(),
1454
+ isParallelExecution: z8.boolean().optional(),
1455
+ parallelGroupId: z8.string().optional()
1456
+ }).passthrough();
1457
+ var HookExecutionCompletedNotificationSchema = z8.object({
1458
+ type: z8.literal("hook_execution_completed" /* HOOK_EXECUTION_COMPLETED */),
1459
+ hookId: z8.string(),
1460
+ hookEventName: DroidHookEventSchema.optional(),
1461
+ hookMatcher: z8.string().optional(),
1462
+ hookToolCallId: z8.string().optional(),
1463
+ hookStatus: z8.enum(["completed", "error"]),
1464
+ hookResults: z8.array(HookResultSchema).optional()
1465
+ }).passthrough();
1466
+ var StructuredOutputErrorSchema = z8.object({
1467
+ code: z8.string(),
1468
+ message: z8.string(),
1469
+ details: z8.unknown().optional()
1470
+ }).passthrough();
1471
+ var StructuredOutputNotificationSchema = z8.object({
1472
+ type: z8.literal("structured_output" /* STRUCTURED_OUTPUT */),
1473
+ messageId: z8.string(),
1474
+ structuredOutput: JsonObjectSchema.nullable(),
1475
+ structuredOutputError: StructuredOutputErrorSchema.nullable()
1178
1476
  }).passthrough();
1179
1477
  var SessionNotificationSchemaList = [
1180
1478
  ToolResultNotificationSchema,
@@ -1187,7 +1485,10 @@ var SessionNotificationSchemaList = [
1187
1485
  SessionTitleUpdatedNotificationSchema,
1188
1486
  McpStatusChangedNotificationSchema,
1189
1487
  AssistantTextDeltaNotificationSchema,
1488
+ AssistantTextCompleteNotificationSchema,
1190
1489
  ThinkingTextDeltaNotificationSchema,
1490
+ ThinkingTextCompleteNotificationSchema,
1491
+ ToolCallNotificationSchema,
1191
1492
  SessionTokenUsageChangedNotificationSchema,
1192
1493
  MissionStateChangedNotificationSchema,
1193
1494
  MissionFeaturesChangedNotificationSchema,
@@ -1196,86 +1497,91 @@ var SessionNotificationSchemaList = [
1196
1497
  MissionWorkerStartedNotificationSchema,
1197
1498
  MissionWorkerCompletedNotificationSchema,
1198
1499
  McpAuthRequiredNotificationSchema,
1199
- McpAuthCompletedNotificationSchema
1500
+ McpAuthCompletedNotificationSchema,
1501
+ HookExecutionStartedNotificationSchema,
1502
+ HookExecutionCompletedNotificationSchema,
1503
+ StructuredOutputNotificationSchema
1200
1504
  ];
1201
- var SessionNotificationPayloadSchema = z6.discriminatedUnion(
1505
+ var SessionNotificationPayloadSchema = z8.discriminatedUnion(
1202
1506
  "type",
1203
1507
  SessionNotificationSchemaList
1204
1508
  );
1205
- var SessionNotificationParamsSchema = z6.object({
1509
+ var _SessionNotificationParamsSchema = z8.object({
1206
1510
  notification: SessionNotificationPayloadSchema
1207
1511
  }).passthrough();
1208
- var SessionNotificationSchema = JsonRpcNotificationSchema.extend({
1209
- method: z6.literal("droid.session_notification" /* SESSION_NOTIFICATION */),
1512
+ var SessionNotificationParamsSchema = _SessionNotificationParamsSchema;
1513
+ var _SessionNotificationSchema = JsonRpcNotificationSchema.extend({
1514
+ method: z8.literal("droid.session_notification" /* SESSION_NOTIFICATION */),
1210
1515
  params: SessionNotificationParamsSchema
1211
1516
  });
1212
- var EditToolConfirmationDetailsSchema = z6.object({
1213
- type: z6.literal("edit" /* Edit */),
1214
- filePath: z6.string(),
1215
- fileName: z6.string(),
1216
- oldContent: z6.string().optional(),
1217
- newContent: z6.string().optional()
1218
- }).passthrough();
1219
- var ExecuteToolConfirmationDetailsSchema = z6.object({
1220
- type: z6.literal("exec" /* Execute */),
1221
- fullCommand: z6.string(),
1222
- command: z6.string(),
1223
- extractedCommands: z6.array(z6.string()).optional(),
1224
- impactLevel: z6.string().optional()
1225
- }).passthrough();
1226
- var CreateToolConfirmationDetailsSchema = z6.object({
1227
- type: z6.literal("create" /* Create */),
1228
- filePath: z6.string(),
1229
- fileName: z6.string(),
1230
- content: z6.string()
1231
- }).passthrough();
1232
- var AskUserQuestionSchema = z6.object({
1233
- index: z6.number(),
1234
- topic: z6.string(),
1235
- question: z6.string(),
1236
- options: z6.array(z6.string())
1237
- }).passthrough();
1238
- var AskUserConfirmationDetailsSchema = z6.object({
1239
- type: z6.literal("ask_user" /* AskUser */),
1240
- questionnaire: z6.string(),
1241
- parsed: z6.object({
1242
- questions: z6.array(AskUserQuestionSchema)
1517
+ var SessionNotificationSchema = _SessionNotificationSchema;
1518
+ var EditToolConfirmationDetailsSchema = z8.object({
1519
+ type: z8.literal("edit" /* Edit */),
1520
+ filePath: z8.string(),
1521
+ fileName: z8.string(),
1522
+ oldContent: z8.string().optional(),
1523
+ newContent: z8.string().optional()
1524
+ }).passthrough();
1525
+ var ExecuteToolConfirmationDetailsSchema = z8.object({
1526
+ type: z8.literal("exec" /* Execute */),
1527
+ fullCommand: z8.string(),
1528
+ command: z8.string(),
1529
+ extractedCommands: z8.array(z8.string()).optional(),
1530
+ impactLevel: z8.string().optional()
1531
+ }).passthrough();
1532
+ var CreateToolConfirmationDetailsSchema = z8.object({
1533
+ type: z8.literal("create" /* Create */),
1534
+ filePath: z8.string(),
1535
+ fileName: z8.string(),
1536
+ content: z8.string()
1537
+ }).passthrough();
1538
+ var AskUserQuestionSchema = z8.object({
1539
+ index: z8.number(),
1540
+ topic: z8.string(),
1541
+ question: z8.string(),
1542
+ options: z8.array(z8.string())
1543
+ }).passthrough();
1544
+ var AskUserConfirmationDetailsSchema = z8.object({
1545
+ type: z8.literal("ask_user" /* AskUser */),
1546
+ questionnaire: z8.string(),
1547
+ parsed: z8.object({
1548
+ questions: z8.array(AskUserQuestionSchema)
1243
1549
  }).optional(),
1244
- parseError: z6.object({
1245
- message: z6.string(),
1246
- line: z6.number().optional()
1550
+ parseError: z8.object({
1551
+ message: z8.string(),
1552
+ line: z8.number().optional()
1247
1553
  }).optional()
1248
1554
  }).passthrough();
1249
- var ExitSpecModeConfirmationDetailsSchema = z6.object({
1250
- type: z6.literal("exit_spec_mode" /* ExitSpecMode */),
1251
- plan: z6.string(),
1252
- title: z6.string().optional(),
1253
- optionNames: z6.array(z6.string()).optional()
1254
- }).passthrough();
1255
- var ProposeMissionConfirmationDetailsSchema = z6.object({
1256
- type: z6.literal("propose_mission" /* ProposeMission */),
1257
- proposal: z6.string(),
1258
- title: z6.string().optional()
1259
- }).passthrough();
1260
- var StartMissionRunConfirmationDetailsSchema = z6.object({
1261
- type: z6.literal("start_mission_run" /* StartMissionRun */),
1262
- runningMissionCount: z6.number(),
1263
- runningMissionSessionIds: z6.array(z6.string())
1264
- }).passthrough();
1265
- var ApplyPatchToolConfirmationDetailsSchema = z6.object({
1266
- type: z6.literal("apply_patch" /* ApplyPatch */),
1267
- filePath: z6.string(),
1268
- fileName: z6.string(),
1269
- patchContent: z6.string(),
1270
- oldContent: z6.string().optional(),
1271
- newContent: z6.string().optional()
1272
- }).passthrough();
1273
- var McpToolConfirmationDetailsSchema = z6.object({
1274
- type: z6.literal("mcp_tool" /* McpTool */),
1275
- toolName: z6.string(),
1276
- impactLevel: z6.string()
1277
- }).passthrough();
1278
- var ToolConfirmationDetailsSchema = z6.discriminatedUnion("type", [
1555
+ var ExitSpecModeConfirmationDetailsSchema = z8.object({
1556
+ type: z8.literal("exit_spec_mode" /* ExitSpecMode */),
1557
+ plan: z8.string(),
1558
+ title: z8.string().optional(),
1559
+ optionNames: z8.array(z8.string()).optional()
1560
+ }).passthrough();
1561
+ var ProposeMissionConfirmationDetailsSchema = z8.object({
1562
+ type: z8.literal("propose_mission" /* ProposeMission */),
1563
+ proposal: z8.string(),
1564
+ title: z8.string().optional()
1565
+ }).passthrough();
1566
+ var StartMissionRunConfirmationDetailsSchema = z8.object({
1567
+ type: z8.literal("start_mission_run" /* StartMissionRun */),
1568
+ runningMissionCount: z8.number(),
1569
+ runningMissionSessionIds: z8.array(z8.string())
1570
+ }).passthrough();
1571
+ var ApplyPatchToolConfirmationDetailsSchema = z8.object({
1572
+ type: z8.literal("apply_patch" /* ApplyPatch */),
1573
+ filePath: z8.string(),
1574
+ fileName: z8.string(),
1575
+ patchContent: z8.string(),
1576
+ oldContent: z8.string().optional(),
1577
+ newContent: z8.string().optional()
1578
+ }).passthrough();
1579
+ var McpToolConfirmationDetailsSchema = z8.object({
1580
+ type: z8.literal("mcp_tool" /* McpTool */),
1581
+ toolName: z8.string(),
1582
+ impactLevel: z8.string()
1583
+ }).passthrough();
1584
+ var ToolConfirmationDetailsSchema = z8.discriminatedUnion("type", [
1279
1585
  EditToolConfirmationDetailsSchema,
1280
1586
  ExecuteToolConfirmationDetailsSchema,
1281
1587
  CreateToolConfirmationDetailsSchema,
@@ -1286,60 +1592,61 @@ var ToolConfirmationDetailsSchema = z6.discriminatedUnion("type", [
1286
1592
  ApplyPatchToolConfirmationDetailsSchema,
1287
1593
  McpToolConfirmationDetailsSchema
1288
1594
  ]);
1289
- var ToolConfirmationInfoSchema = z6.object({
1595
+ var ToolConfirmationInfoSchema = z8.object({
1290
1596
  toolUse: ToolUseSchema,
1291
- confirmationType: z6.nativeEnum(ToolConfirmationType),
1597
+ confirmationType: z8.nativeEnum(ToolConfirmationType),
1292
1598
  details: ToolConfirmationDetailsSchema
1293
1599
  }).passthrough();
1294
- var RequestPermissionRequestParamsSchema = z6.object({
1295
- toolUses: z6.array(ToolConfirmationInfoSchema),
1296
- options: z6.array(ToolConfirmationListItemSchema)
1600
+ var RequestPermissionRequestParamsSchema = z8.object({
1601
+ toolUses: z8.array(ToolConfirmationInfoSchema),
1602
+ options: z8.array(ToolConfirmationListItemSchema)
1297
1603
  }).passthrough();
1298
1604
  var RequestPermissionRequestSchema = JsonRpcRequestSchema.extend({
1299
- method: z6.literal("droid.request_permission" /* REQUEST_PERMISSION */),
1605
+ method: z8.literal("droid.request_permission" /* REQUEST_PERMISSION */),
1300
1606
  params: RequestPermissionRequestParamsSchema
1301
1607
  });
1302
- var RequestPermissionResultSchema = z6.object({
1303
- selectedOption: z6.nativeEnum(ToolConfirmationOutcome)
1608
+ var RequestPermissionResultSchema = z8.object({
1609
+ selectedOption: z8.nativeEnum(ToolConfirmationOutcome),
1610
+ comment: z8.string().optional()
1304
1611
  }).strict();
1305
- var RequestPermissionResponseSchema = z6.union([
1306
- JsonRpcResponseSuccessSchema.extend({
1307
- result: RequestPermissionResultSchema
1308
- }),
1309
- JsonRpcResponseFailureSchema
1310
- ]);
1311
- var AskUserRequestParamsSchema = z6.object({
1312
- toolCallId: z6.string(),
1313
- questions: z6.array(AskUserQuestionSchema)
1612
+ var RequestPermissionResponseSchema = createResponseSchema(
1613
+ RequestPermissionResultSchema
1614
+ );
1615
+ var AskUserRequestParamsSchema = z8.object({
1616
+ toolCallId: z8.string(),
1617
+ questions: z8.array(AskUserQuestionSchema)
1314
1618
  }).passthrough();
1315
1619
  var AskUserRequestSchema = JsonRpcRequestSchema.extend({
1316
- method: z6.literal("droid.ask_user" /* ASK_USER */),
1620
+ method: z8.literal("droid.ask_user" /* ASK_USER */),
1317
1621
  params: AskUserRequestParamsSchema
1318
1622
  });
1319
- var AskUserCollectedAnswerSchema = z6.object({
1320
- index: z6.number(),
1321
- question: z6.string(),
1322
- answer: z6.string()
1623
+ var AskUserCollectedAnswerSchema = z8.object({
1624
+ index: z8.number(),
1625
+ question: z8.string(),
1626
+ answer: z8.string()
1323
1627
  }).strict();
1324
- var AskUserResultSchema = z6.object({
1325
- cancelled: z6.boolean().optional(),
1326
- answers: z6.array(AskUserCollectedAnswerSchema)
1628
+ var AskUserResultSchema = z8.object({
1629
+ cancelled: z8.boolean().optional(),
1630
+ answers: z8.array(AskUserCollectedAnswerSchema)
1327
1631
  }).strict();
1328
- var AskUserResponseSchema = z6.union([
1329
- JsonRpcResponseSuccessSchema.extend({ result: AskUserResultSchema }),
1330
- JsonRpcResponseFailureSchema
1331
- ]);
1332
- var CliRequestOrNotificationSchema = z6.union([
1632
+ var AskUserResponseSchema = createResponseSchema(AskUserResultSchema);
1633
+ var _CliRequestOrNotificationSchema = z8.union([
1333
1634
  SessionNotificationSchema,
1334
1635
  RequestPermissionRequestSchema,
1335
1636
  AskUserRequestSchema
1336
1637
  ]);
1638
+ var CliRequestOrNotificationSchema = _CliRequestOrNotificationSchema;
1639
+
1640
+ // src/constants.ts
1641
+ var SDK_VERSION = "0.3.0";
1642
+ var SDK_TAG = {
1643
+ name: "sdk",
1644
+ metadata: { language: "typescript", version: SDK_VERSION }
1645
+ };
1337
1646
 
1338
1647
  // src/errors.ts
1339
1648
  var ConnectionError = class _ConnectionError extends Error {
1340
- /** The working directory used when spawning the process. */
1341
1649
  cwd;
1342
- /** The executable path used when spawning the process. */
1343
1650
  execPath;
1344
1651
  constructor(message, options) {
1345
1652
  super(message);
@@ -1350,9 +1657,7 @@ var ConnectionError = class _ConnectionError extends Error {
1350
1657
  }
1351
1658
  };
1352
1659
  var ProtocolError = class _ProtocolError extends Error {
1353
- /** The JSON-RPC error code, if available. */
1354
1660
  code;
1355
- /** Additional error data from the JSON-RPC response. */
1356
1661
  data;
1357
1662
  constructor(message, options) {
1358
1663
  super(message);
@@ -1370,7 +1675,6 @@ var SessionError = class _SessionError extends Error {
1370
1675
  }
1371
1676
  };
1372
1677
  var SessionNotFoundError = class _SessionNotFoundError extends SessionError {
1373
- /** The ID of the session that was not found. */
1374
1678
  sessionId;
1375
1679
  constructor(sessionId) {
1376
1680
  super(`Session not found: ${sessionId}`);
@@ -1387,9 +1691,7 @@ var TimeoutError = class _TimeoutError extends Error {
1387
1691
  }
1388
1692
  };
1389
1693
  var ProcessExitError = class _ProcessExitError extends Error {
1390
- /** The exit code of the process, or null if terminated by signal. */
1391
1694
  exitCode;
1392
- /** The signal that terminated the process, or null if exited normally. */
1393
1695
  signal;
1394
1696
  constructor(message, options) {
1395
1697
  super(message);
@@ -1403,6 +1705,13 @@ var ProcessExitError = class _ProcessExitError extends Error {
1403
1705
  // src/transport.ts
1404
1706
  import { spawn } from "child_process";
1405
1707
  import * as readline from "readline";
1708
+
1709
+ // src/utils.ts
1710
+ function isRecord(value) {
1711
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1712
+ }
1713
+
1714
+ // src/transport.ts
1406
1715
  var DEFAULT_EXEC_ARGS = [
1407
1716
  "exec",
1408
1717
  "--input-format",
@@ -1421,12 +1730,9 @@ var ProcessTransport = class {
1421
1730
  readlineInterface = null;
1422
1731
  messageHandler = null;
1423
1732
  errorHandler = null;
1424
- /**
1425
- * Sticky error from a process error or unexpected exit. Once set,
1426
- * all subsequent `send()` calls throw immediately.
1427
- */
1733
+ /** Once set, all subsequent `send()` calls throw immediately. */
1428
1734
  processError = null;
1429
- /** Promise-chain serializer for stdin writes. */
1735
+ /** Serializes stdin writes to prevent interleaving. */
1430
1736
  writeChain = Promise.resolve();
1431
1737
  _isConnected = false;
1432
1738
  isClosing = false;
@@ -1437,9 +1743,6 @@ var ProcessTransport = class {
1437
1743
  this.env = options.env;
1438
1744
  this.gracePeriodMs = (options.gracePeriod ?? DEFAULT_GRACE_PERIOD_MS / 1e3) * 1e3;
1439
1745
  }
1440
- // -----------------------------------------------------------------------
1441
- // DroidClientTransport interface
1442
- // -----------------------------------------------------------------------
1443
1746
  get isConnected() {
1444
1747
  return this._isConnected;
1445
1748
  }
@@ -1491,7 +1794,7 @@ var ProcessTransport = class {
1491
1794
  if (this.processError) {
1492
1795
  throw this.processError;
1493
1796
  }
1494
- await new Promise((resolve, reject) => {
1797
+ await new Promise((resolve2, reject) => {
1495
1798
  if (!this.childProcess || !this.childProcess.stdin) {
1496
1799
  reject(
1497
1800
  new ConnectionError("Process stdin unavailable", {
@@ -1527,7 +1830,7 @@ var ProcessTransport = class {
1527
1830
  );
1528
1831
  }
1529
1832
  } else {
1530
- resolve();
1833
+ resolve2();
1531
1834
  }
1532
1835
  });
1533
1836
  });
@@ -1552,7 +1855,7 @@ var ProcessTransport = class {
1552
1855
  this.readlineInterface = null;
1553
1856
  }
1554
1857
  if (proc && proc.exitCode === null && !proc.killed) {
1555
- await new Promise((resolve) => {
1858
+ await new Promise((resolve2) => {
1556
1859
  const timeout = setTimeout(() => {
1557
1860
  if (proc.exitCode === null && !proc.killed) {
1558
1861
  try {
@@ -1563,7 +1866,7 @@ var ProcessTransport = class {
1563
1866
  }, this.gracePeriodMs);
1564
1867
  proc.once("exit", () => {
1565
1868
  clearTimeout(timeout);
1566
- resolve();
1869
+ resolve2();
1567
1870
  });
1568
1871
  if (proc.stdin) {
1569
1872
  try {
@@ -1575,15 +1878,12 @@ var ProcessTransport = class {
1575
1878
  proc.kill("SIGTERM");
1576
1879
  } catch {
1577
1880
  clearTimeout(timeout);
1578
- resolve();
1881
+ resolve2();
1579
1882
  }
1580
1883
  });
1581
1884
  }
1582
1885
  this.isClosing = false;
1583
1886
  }
1584
- // -----------------------------------------------------------------------
1585
- // Private helpers
1586
- // -----------------------------------------------------------------------
1587
1887
  setupHandlers() {
1588
1888
  const proc = this.childProcess;
1589
1889
  if (!proc || !proc.stdout) {
@@ -1598,10 +1898,10 @@ var ProcessTransport = class {
1598
1898
  if (!trimmed) {
1599
1899
  return;
1600
1900
  }
1601
- if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
1901
+ if (trimmed.startsWith("{")) {
1602
1902
  try {
1603
1903
  const parsed = JSON.parse(trimmed);
1604
- if (this.messageHandler && typeof parsed === "object" && parsed !== null) {
1904
+ if (this.messageHandler && isRecord(parsed)) {
1605
1905
  this.messageHandler(parsed);
1606
1906
  }
1607
1907
  } catch {
@@ -1654,26 +1954,33 @@ var ProcessTransport = class {
1654
1954
 
1655
1955
  // src/protocol.ts
1656
1956
  import { v4 as uuidv4 } from "uuid";
1957
+ function dispatchNotification(notification, listeners) {
1958
+ let notificationType;
1959
+ const parsed = SessionNotificationParamsSchema.safeParse(
1960
+ notification["params"]
1961
+ );
1962
+ if (parsed.success) {
1963
+ notificationType = parsed.data.notification.type;
1964
+ }
1965
+ for (const listener of listeners) {
1966
+ if (listener.filter?.type != null && listener.filter.type !== notificationType) {
1967
+ continue;
1968
+ }
1969
+ try {
1970
+ listener.callback(notification);
1971
+ } catch {
1972
+ }
1973
+ }
1974
+ }
1657
1975
  var ProtocolEngine = class {
1658
1976
  _transport;
1659
1977
  _defaultTimeout;
1660
- /** Pending requests keyed by UUID string. */
1661
1978
  _pendingRequests = /* @__PURE__ */ new Map();
1662
- /** Notification listener registry. */
1663
1979
  _notificationListeners = /* @__PURE__ */ new Set();
1664
- /** Server→client request handlers. */
1665
1980
  _permissionHandler = null;
1666
1981
  _askUserHandler = null;
1667
- /** Sticky transport error — once set, all requests fail immediately. */
1668
1982
  _transportError = null;
1669
- /** Closed flag — once true, new requests are rejected. */
1670
1983
  _closed = false;
1671
- /**
1672
- * Create a new ProtocolEngine.
1673
- *
1674
- * @param options.transport - A connected DroidClientTransport implementation.
1675
- * @param options.defaultTimeout - Default timeout in ms for sendRequest (default 30 000).
1676
- */
1677
1984
  constructor(options) {
1678
1985
  this._transport = options.transport;
1679
1986
  this._defaultTimeout = options.defaultTimeout ?? DEFAULT_REQUEST_TIMEOUT;
@@ -1684,25 +1991,6 @@ var ProtocolEngine = class {
1684
1991
  this._handleTransportError(error);
1685
1992
  });
1686
1993
  }
1687
- // ------------------------------------------------------------------
1688
- // Public API: Sending requests
1689
- // ------------------------------------------------------------------
1690
- /**
1691
- * Send a JSON-RPC request and wait for the response.
1692
- *
1693
- * Constructs the full envelope, registers a pending promise, sends
1694
- * via transport, and returns the parsed response `result` field.
1695
- *
1696
- * @param method - The RPC method name (e.g. `"droid.list_skills"`).
1697
- * @param params - Method parameters object.
1698
- * @param timeout - Timeout in ms. Defaults to `defaultTimeout`.
1699
- * @returns The `result` field from the JSON-RPC success response.
1700
- * @throws {ConnectionError} If the engine is closed.
1701
- * @throws {ConnectionError} If the transport has a sticky error.
1702
- * @throws {TimeoutError} If no response arrives within the timeout.
1703
- * @throws {ProtocolError} If the response contains a protocol error.
1704
- * @throws {SessionNotFoundError} If error code is ENTITY_NOT_FOUND.
1705
- */
1706
1994
  async sendRequest(method, params, timeout) {
1707
1995
  if (this._closed) {
1708
1996
  throw new ConnectionError("Protocol engine is closed");
@@ -1718,12 +2006,12 @@ var ProtocolEngine = class {
1718
2006
  jsonrpc: JSONRPC_VERSION,
1719
2007
  factoryApiVersion: LEGACY_FACTORY_API_VERSION,
1720
2008
  factoryProtocolVersion: FACTORY_PROTOCOL_VERSION,
1721
- type: "request",
2009
+ type: "request" /* Request */,
1722
2010
  id: requestId,
1723
2011
  method,
1724
2012
  params
1725
2013
  };
1726
- return new Promise((resolve, reject) => {
2014
+ return new Promise((resolve2, reject) => {
1727
2015
  const timer = setTimeout(() => {
1728
2016
  this._pendingRequests.delete(requestId);
1729
2017
  reject(
@@ -1736,7 +2024,7 @@ var ProtocolEngine = class {
1736
2024
  method,
1737
2025
  requestId,
1738
2026
  params,
1739
- resolve,
2027
+ resolve: resolve2,
1740
2028
  reject,
1741
2029
  timer
1742
2030
  };
@@ -1756,19 +2044,6 @@ var ProtocolEngine = class {
1756
2044
  }
1757
2045
  });
1758
2046
  }
1759
- // ------------------------------------------------------------------
1760
- // Public API: Notification listeners
1761
- // ------------------------------------------------------------------
1762
- /**
1763
- * Register a callback for incoming notification messages.
1764
- *
1765
- * Multiple listeners can be registered. Each receives the full
1766
- * parsed notification object.
1767
- *
1768
- * @param callback - Invoked with the notification object.
1769
- * @param filter - Optional filter to only receive specific notification types.
1770
- * @returns An unsubscribe function. Calling it again is safe (no-op).
1771
- */
1772
2047
  onNotification(callback, filter) {
1773
2048
  const listener = { callback, filter };
1774
2049
  this._notificationListeners.add(listener);
@@ -1780,23 +2055,9 @@ var ProtocolEngine = class {
1780
2055
  }
1781
2056
  };
1782
2057
  }
1783
- // ------------------------------------------------------------------
1784
- // Public API: Server→client request handlers
1785
- // ------------------------------------------------------------------
1786
- /**
1787
- * Register a handler for server→client permission requests.
1788
- *
1789
- * The handler receives the request params and should return a
1790
- * ToolConfirmationOutcome string value.
1791
- *
1792
- * Replaces any previously registered handler.
1793
- */
1794
2058
  setPermissionHandler(handler) {
1795
2059
  this._permissionHandler = handler;
1796
2060
  }
1797
- /**
1798
- * Remove the permission request handler (restores default Cancel).
1799
- */
1800
2061
  clearPermissionHandler() {
1801
2062
  this._permissionHandler = null;
1802
2063
  }
@@ -1811,31 +2072,12 @@ var ProtocolEngine = class {
1811
2072
  setAskUserHandler(handler) {
1812
2073
  this._askUserHandler = handler;
1813
2074
  }
1814
- /**
1815
- * Remove the ask-user request handler (restores default cancelled=true).
1816
- */
1817
2075
  clearAskUserHandler() {
1818
2076
  this._askUserHandler = null;
1819
2077
  }
1820
- // ------------------------------------------------------------------
1821
- // Public API: Health check
1822
- // ------------------------------------------------------------------
1823
- /**
1824
- * Whether the engine is in a healthy state — not closed and no
1825
- * sticky transport error.
1826
- */
1827
2078
  get isHealthy() {
1828
2079
  return !this._closed && this._transportError === null;
1829
2080
  }
1830
- // ------------------------------------------------------------------
1831
- // Public API: Close
1832
- // ------------------------------------------------------------------
1833
- /**
1834
- * Close the protocol engine.
1835
- *
1836
- * Rejects all pending requests, closes the transport, and prevents
1837
- * new requests. Idempotent — safe to call multiple times.
1838
- */
1839
2081
  async close() {
1840
2082
  if (this._closed) {
1841
2083
  return;
@@ -1850,38 +2092,25 @@ var ProtocolEngine = class {
1850
2092
  this._notificationListeners.clear();
1851
2093
  await this._transport.close();
1852
2094
  }
1853
- // ------------------------------------------------------------------
1854
- // Internal: Message handling
1855
- // ------------------------------------------------------------------
1856
- /**
1857
- * Handle an incoming parsed message from the transport.
1858
- * Dispatches to response handler, notification handler, or
1859
- * server→client request handler based on message type.
1860
- */
1861
- _handleMessage(parsed) {
1862
- const msgType = parsed["type"];
1863
- if (msgType === "response") {
1864
- this._handleResponse(parsed);
1865
- } else if (msgType === "notification") {
1866
- this._handleNotification(parsed);
1867
- } else if (msgType === "request") {
1868
- void this._handleServerRequest(parsed);
1869
- } else {
1870
- if ("result" in parsed || "error" in parsed) {
1871
- this._handleResponse(parsed);
1872
- } else if ("method" in parsed && !("id" in parsed)) {
1873
- this._handleNotification(parsed);
1874
- } else if ("method" in parsed && "id" in parsed) {
1875
- void this._handleServerRequest(parsed);
1876
- }
2095
+ _handleMessage(raw) {
2096
+ const parsed = JsonRpcMessageSchema.safeParse(raw);
2097
+ if (!parsed.success) {
2098
+ return;
2099
+ }
2100
+ const msg = parsed.data;
2101
+ switch (msg.type) {
2102
+ case "response" /* Response */:
2103
+ this._handleResponse(msg.id, msg.result, msg.error);
2104
+ break;
2105
+ case "notification" /* Notification */:
2106
+ this._handleNotification(msg);
2107
+ break;
2108
+ case "request" /* Request */:
2109
+ void this._handleServerRequest(msg.method, msg.id, msg.params);
2110
+ break;
1877
2111
  }
1878
2112
  }
1879
- /**
1880
- * Handle an incoming response message.
1881
- * Matches by ID to resolve the correct pending Promise.
1882
- */
1883
- _handleResponse(response) {
1884
- const responseId = response["id"];
2113
+ _handleResponse(responseId, result, error) {
1885
2114
  if (responseId == null) {
1886
2115
  return;
1887
2116
  }
@@ -1891,68 +2120,50 @@ var ProtocolEngine = class {
1891
2120
  }
1892
2121
  this._pendingRequests.delete(responseId);
1893
2122
  clearTimeout(pending.timer);
1894
- const errorObj = response["error"];
1895
- if (errorObj != null && typeof errorObj === "object") {
1896
- const error = errorObj;
1897
- const code = error["code"];
1898
- const message = error["message"] ?? "Unknown error";
1899
- const data = error["data"];
1900
- if (code === -32004 /* ENTITY_NOT_FOUND */) {
2123
+ if (error != null) {
2124
+ if (error.code === -32004 /* ENTITY_NOT_FOUND */) {
1901
2125
  const sessionId = String(
1902
2126
  pending.params["sessionId"] ?? pending.requestId
1903
2127
  );
1904
2128
  pending.reject(new SessionNotFoundError(sessionId));
1905
2129
  return;
1906
2130
  }
1907
- pending.reject(new ProtocolError(message, { code, data }));
2131
+ pending.reject(
2132
+ new ProtocolError(error.message, { code: error.code, data: error.data })
2133
+ );
1908
2134
  return;
1909
2135
  }
1910
- pending.resolve(response);
2136
+ pending.resolve(result);
1911
2137
  }
1912
- /**
1913
- * Handle an incoming notification message.
1914
- * Dispatches to all registered notification listeners that match.
1915
- */
1916
2138
  _handleNotification(notification) {
1917
- const params = notification["params"];
1918
- const innerNotification = params?.["notification"];
1919
- const notificationType = innerNotification?.["type"];
1920
- for (const listener of this._notificationListeners) {
1921
- if (listener.filter?.type != null && listener.filter.type !== notificationType) {
1922
- continue;
1923
- }
1924
- try {
1925
- listener.callback(notification);
1926
- } catch {
1927
- }
1928
- }
2139
+ dispatchNotification(notification, this._notificationListeners);
1929
2140
  }
1930
- /**
1931
- * Handle an incoming server→client request.
1932
- * Dispatches to the appropriate handler based on the method field.
1933
- */
1934
- async _handleServerRequest(request) {
1935
- const method = request["method"];
1936
- const requestId = request["id"];
1937
- const params = request["params"] ?? {};
2141
+ async _handleServerRequest(method, requestId, params) {
1938
2142
  if (method === "droid.request_permission" /* REQUEST_PERMISSION */) {
1939
2143
  await this._handlePermissionRequest(requestId, params);
1940
2144
  } else if (method === "droid.ask_user" /* ASK_USER */) {
1941
2145
  await this._handleAskUserRequest(requestId, params);
1942
2146
  }
1943
2147
  }
1944
- /**
1945
- * Handle droid.request_permission server→client request.
1946
- */
1947
2148
  async _handlePermissionRequest(requestId, params) {
1948
2149
  const handler = this._permissionHandler;
1949
2150
  if (handler == null) {
1950
- this._sendResponse(requestId, { selectedOption: "cancel" });
2151
+ this._sendResponse(
2152
+ requestId,
2153
+ RequestPermissionResultSchema.parse({
2154
+ selectedOption: "cancel" /* Cancel */
2155
+ })
2156
+ );
1951
2157
  return;
1952
2158
  }
1953
2159
  try {
1954
- const selectedOption = await Promise.resolve(handler(params));
1955
- this._sendResponse(requestId, { selectedOption });
2160
+ const parsedParams = RequestPermissionRequestParamsSchema.parse(params);
2161
+ const selection = await Promise.resolve(handler(parsedParams));
2162
+ const result = typeof selection === "string" ? { selectedOption: selection } : selection;
2163
+ this._sendResponse(
2164
+ requestId,
2165
+ RequestPermissionResultSchema.parse(result)
2166
+ );
1956
2167
  } catch (exc) {
1957
2168
  const errorMessage = exc instanceof Error ? exc.message : String(exc);
1958
2169
  this._sendErrorResponse(
@@ -1963,18 +2174,19 @@ var ProtocolEngine = class {
1963
2174
  );
1964
2175
  }
1965
2176
  }
1966
- /**
1967
- * Handle droid.ask_user server→client request.
1968
- */
1969
2177
  async _handleAskUserRequest(requestId, params) {
1970
2178
  const handler = this._askUserHandler;
1971
2179
  if (handler == null) {
1972
- this._sendResponse(requestId, { cancelled: true, answers: [] });
2180
+ this._sendResponse(
2181
+ requestId,
2182
+ AskUserResultSchema.parse({ cancelled: true, answers: [] })
2183
+ );
1973
2184
  return;
1974
2185
  }
1975
2186
  try {
1976
- const result = await Promise.resolve(handler(params));
1977
- this._sendResponse(requestId, result);
2187
+ const parsedParams = AskUserRequestParamsSchema.parse(params);
2188
+ const result = await Promise.resolve(handler(parsedParams));
2189
+ this._sendResponse(requestId, AskUserResultSchema.parse(result));
1978
2190
  } catch (exc) {
1979
2191
  const errorMessage = exc instanceof Error ? exc.message : String(exc);
1980
2192
  this._sendErrorResponse(
@@ -1985,9 +2197,6 @@ var ProtocolEngine = class {
1985
2197
  );
1986
2198
  }
1987
2199
  }
1988
- // ------------------------------------------------------------------
1989
- // Internal: Transport error handling
1990
- // ------------------------------------------------------------------
1991
2200
  /**
1992
2201
  * Handle a transport error.
1993
2202
  * Sets the sticky transport error and rejects all pending requests.
@@ -2001,29 +2210,17 @@ var ProtocolEngine = class {
2001
2210
  connectionError.cause = error;
2002
2211
  this._rejectAllPending(connectionError);
2003
2212
  }
2004
- // ------------------------------------------------------------------
2005
- // Internal: Response helpers
2006
- // ------------------------------------------------------------------
2007
- /**
2008
- * Send a JSON-RPC success response back to the server.
2009
- */
2010
2213
  _sendResponse(requestId, result) {
2011
2214
  const response = {
2012
2215
  jsonrpc: JSONRPC_VERSION,
2013
2216
  factoryApiVersion: LEGACY_FACTORY_API_VERSION,
2014
2217
  factoryProtocolVersion: FACTORY_PROTOCOL_VERSION,
2015
- type: "response",
2218
+ type: "response" /* Response */,
2016
2219
  id: requestId,
2017
2220
  result
2018
2221
  };
2019
- try {
2020
- this._transport.send(response);
2021
- } catch {
2022
- }
2222
+ this._sendBestEffort(response);
2023
2223
  }
2024
- /**
2025
- * Send a JSON-RPC error response back to the server.
2026
- */
2027
2224
  _sendErrorResponse(requestId, code, message, data) {
2028
2225
  const errorObj = { code, message };
2029
2226
  if (data !== void 0) {
@@ -2033,18 +2230,18 @@ var ProtocolEngine = class {
2033
2230
  jsonrpc: JSONRPC_VERSION,
2034
2231
  factoryApiVersion: LEGACY_FACTORY_API_VERSION,
2035
2232
  factoryProtocolVersion: FACTORY_PROTOCOL_VERSION,
2036
- type: "response",
2233
+ type: "response" /* Response */,
2037
2234
  id: requestId,
2038
2235
  error: errorObj
2039
2236
  };
2237
+ this._sendBestEffort(response);
2238
+ }
2239
+ _sendBestEffort(message) {
2040
2240
  try {
2041
- this._transport.send(response);
2241
+ this._transport.send(message);
2042
2242
  } catch {
2043
2243
  }
2044
2244
  }
2045
- /**
2046
- * Reject all pending requests with the given error.
2047
- */
2048
2245
  _rejectAllPending(error) {
2049
2246
  const pending = new Map(this._pendingRequests);
2050
2247
  this._pendingRequests.clear();
@@ -2060,10 +2257,6 @@ var DroidClient = class {
2060
2257
  _engine;
2061
2258
  _sessionId = null;
2062
2259
  _closed = false;
2063
- /**
2064
- * Client-level notification listeners.
2065
- * Each entry is [callback, optional type filter string].
2066
- */
2067
2260
  _notificationListeners = [];
2068
2261
  /** Client-level permission handler. */
2069
2262
  _permissionHandler = null;
@@ -2084,329 +2277,219 @@ var DroidClient = class {
2084
2277
  (params) => this._dispatchAskUserRequest(params)
2085
2278
  );
2086
2279
  }
2087
- // ------------------------------------------------------------------
2088
- // Properties
2089
- // ------------------------------------------------------------------
2090
- /**
2091
- * Current session ID, or `null` if no session is active.
2092
- */
2280
+ async _rpc(method, params, schema, timeout) {
2281
+ const raw = await this._engine.sendRequest(method, params, timeout);
2282
+ return schema.parse(raw);
2283
+ }
2284
+ async _sessionRpc(method, params, schema, timeout) {
2285
+ this._ensureNotClosed();
2286
+ this._ensureSession();
2287
+ return this._rpc(method, params, schema, timeout);
2288
+ }
2289
+ async _sessionRpcWithoutParams(method, schema, timeout) {
2290
+ return this._sessionRpc(method, {}, schema, timeout);
2291
+ }
2093
2292
  get sessionId() {
2094
2293
  return this._sessionId;
2095
2294
  }
2096
- /**
2097
- * Whether the client is in a healthy state — not closed and no
2098
- * transport errors have occurred. Returns false after transport
2099
- * disconnect/error.
2100
- */
2101
2295
  get isConnected() {
2102
2296
  return !this._closed && this._engine.isHealthy;
2103
2297
  }
2104
- // ------------------------------------------------------------------
2105
- // Session lifecycle methods
2106
- // ------------------------------------------------------------------
2107
- /**
2108
- * Initialize a new session.
2109
- *
2110
- * Sends `droid.initialize_session` with extended timeout. On success,
2111
- * stores the session ID internally and returns the typed result.
2112
- */
2113
2298
  async initializeSession(params) {
2114
2299
  this._ensureNotClosed();
2115
- const response = await this._engine.sendRequest(
2300
+ const result = await this._rpc(
2116
2301
  "droid.initialize_session" /* INITIALIZE_SESSION */,
2117
2302
  params,
2303
+ InitializeSessionResultSchema,
2118
2304
  SESSION_INIT_TIMEOUT
2119
2305
  );
2120
- const result = response["result"];
2121
- if (result) {
2122
- this._sessionId = result.sessionId;
2123
- return result;
2124
- }
2125
- if ("sessionId" in response) {
2126
- this._sessionId = response["sessionId"];
2127
- return response;
2128
- }
2129
- return response;
2306
+ this._sessionId = result.sessionId;
2307
+ return result;
2130
2308
  }
2131
- /**
2132
- * Load an existing session.
2133
- *
2134
- * Sends `droid.load_session`. SessionNotFoundError is thrown for
2135
- * non-existent sessions (mapped from ENTITY_NOT_FOUND by the protocol engine).
2136
- */
2137
2309
  async loadSession(params) {
2138
2310
  this._ensureNotClosed();
2139
- const response = await this._engine.sendRequest(
2311
+ const result = await this._rpc(
2140
2312
  "droid.load_session" /* LOAD_SESSION */,
2141
2313
  params,
2314
+ LoadSessionResultSchema,
2142
2315
  SESSION_INIT_TIMEOUT
2143
2316
  );
2144
- const result = response["result"];
2145
- if (result) {
2146
- this._sessionId = params.sessionId;
2147
- return result;
2148
- }
2149
2317
  this._sessionId = params.sessionId;
2150
- return response;
2318
+ return result;
2151
2319
  }
2152
- /**
2153
- * Add a user message to the active session.
2154
- *
2155
- * Sends `droid.add_user_message` with text and optional images/files.
2156
- */
2157
2320
  async addUserMessage(params) {
2158
- this._ensureNotClosed();
2159
- this._ensureSession();
2160
- const response = await this._engine.sendRequest(
2321
+ return this._sessionRpc(
2161
2322
  "droid.add_user_message" /* ADD_USER_MESSAGE */,
2162
- params
2323
+ params,
2324
+ AddUserMessageResultSchema
2163
2325
  );
2164
- const result = response["result"];
2165
- return result ?? response;
2166
2326
  }
2167
- /**
2168
- * Interrupt the current session.
2169
- *
2170
- * Sends `droid.interrupt_session` with empty params.
2171
- */
2172
2327
  async interruptSession() {
2173
- this._ensureNotClosed();
2174
- this._ensureSession();
2175
- const response = await this._engine.sendRequest(
2328
+ return this._sessionRpcWithoutParams(
2176
2329
  "droid.interrupt_session" /* INTERRUPT_SESSION */,
2177
- {}
2330
+ InterruptSessionResultSchema
2331
+ );
2332
+ }
2333
+ async closeSession(params = {}) {
2334
+ return this._sessionRpc(
2335
+ "droid.close_session" /* CLOSE_SESSION */,
2336
+ params,
2337
+ CloseSessionResultSchema
2178
2338
  );
2179
- const result = response["result"];
2180
- return result ?? response;
2181
2339
  }
2182
- /**
2183
- * Kill a worker session.
2184
- *
2185
- * Sends `droid.kill_worker_session`.
2186
- */
2187
2340
  async killWorkerSession(params) {
2188
- this._ensureNotClosed();
2189
- this._ensureSession();
2190
- const response = await this._engine.sendRequest(
2341
+ return this._sessionRpc(
2191
2342
  "droid.kill_worker_session" /* KILL_WORKER_SESSION */,
2192
- params
2343
+ params,
2344
+ KillWorkerSessionResultSchema
2193
2345
  );
2194
- const result = response["result"];
2195
- return result ?? response;
2196
2346
  }
2197
- /**
2198
- * Update session settings.
2199
- *
2200
- * Sends `droid.update_session_settings` with the provided partial settings.
2201
- */
2202
2347
  async updateSessionSettings(params) {
2203
- this._ensureNotClosed();
2204
- this._ensureSession();
2205
- const response = await this._engine.sendRequest(
2348
+ return this._sessionRpc(
2206
2349
  "droid.update_session_settings" /* UPDATE_SESSION_SETTINGS */,
2207
- params
2350
+ params,
2351
+ UpdateSessionSettingsResultSchema
2208
2352
  );
2209
- const result = response["result"];
2210
- return result ?? response;
2211
2353
  }
2212
- // ------------------------------------------------------------------
2213
- // MCP methods
2214
- // ------------------------------------------------------------------
2215
- /**
2216
- * Toggle an MCP server on or off.
2217
- */
2218
2354
  async toggleMcpServer(params) {
2219
- this._ensureNotClosed();
2220
- this._ensureSession();
2221
- const response = await this._engine.sendRequest(
2355
+ return this._sessionRpc(
2222
2356
  "droid.toggle_mcp_server" /* TOGGLE_MCP_SERVER */,
2223
- params
2357
+ params,
2358
+ ToggleMcpServerResultSchema
2224
2359
  );
2225
- const result = response["result"];
2226
- return result ?? response;
2227
2360
  }
2228
- /**
2229
- * Authenticate an MCP server (OAuth flow).
2230
- * Uses extended timeout (300s) since OAuth requires user interaction.
2231
- */
2232
2361
  async authenticateMcpServer(params) {
2233
- this._ensureNotClosed();
2234
- this._ensureSession();
2235
- const response = await this._engine.sendRequest(
2362
+ return this._sessionRpc(
2236
2363
  "droid.authenticate_mcp_server" /* AUTHENTICATE_MCP_SERVER */,
2237
2364
  params,
2365
+ AuthenticateMcpServerResultSchema,
2238
2366
  MCP_AUTH_TIMEOUT
2239
2367
  );
2240
- const result = response["result"];
2241
- return result ?? response;
2242
2368
  }
2243
- /**
2244
- * Cancel an in-progress MCP authentication.
2245
- */
2246
2369
  async cancelMcpAuth(params) {
2247
- this._ensureNotClosed();
2248
- this._ensureSession();
2249
- const response = await this._engine.sendRequest(
2370
+ return this._sessionRpc(
2250
2371
  "droid.cancel_mcp_auth" /* CANCEL_MCP_AUTH */,
2251
- params
2372
+ params,
2373
+ CancelMcpAuthResultSchema
2252
2374
  );
2253
- const result = response["result"];
2254
- return result ?? response;
2255
2375
  }
2256
- /**
2257
- * Clear stored MCP authentication tokens.
2258
- */
2259
2376
  async clearMcpAuth(params) {
2260
- this._ensureNotClosed();
2261
- this._ensureSession();
2262
- const response = await this._engine.sendRequest(
2377
+ return this._sessionRpc(
2263
2378
  "droid.clear_mcp_auth" /* CLEAR_MCP_AUTH */,
2264
- params
2379
+ params,
2380
+ ClearMcpAuthResultSchema
2265
2381
  );
2266
- const result = response["result"];
2267
- return result ?? response;
2268
2382
  }
2269
- /**
2270
- * Submit an MCP authentication code (OAuth callback).
2271
- */
2272
2383
  async submitMcpAuthCode(params) {
2273
- this._ensureNotClosed();
2274
- this._ensureSession();
2275
- const response = await this._engine.sendRequest(
2384
+ return this._sessionRpc(
2276
2385
  "droid.submit_mcp_auth_code" /* SUBMIT_MCP_AUTH_CODE */,
2277
- params
2386
+ params,
2387
+ SubmitMcpAuthCodeResultSchema
2278
2388
  );
2279
- const result = response["result"];
2280
- return result ?? response;
2281
2389
  }
2282
- /**
2283
- * Add an MCP server.
2284
- */
2285
2390
  async addMcpServer(params) {
2286
- this._ensureNotClosed();
2287
- this._ensureSession();
2288
- const response = await this._engine.sendRequest(
2391
+ return this._sessionRpc(
2289
2392
  "droid.add_mcp_server" /* ADD_MCP_SERVER */,
2290
- params
2393
+ params,
2394
+ AddMcpServerResultSchema
2291
2395
  );
2292
- const result = response["result"];
2293
- return result ?? response;
2294
2396
  }
2295
- /**
2296
- * Remove an MCP server.
2297
- */
2298
2397
  async removeMcpServer(params) {
2299
- this._ensureNotClosed();
2300
- this._ensureSession();
2301
- const response = await this._engine.sendRequest(
2398
+ return this._sessionRpc(
2302
2399
  "droid.remove_mcp_server" /* REMOVE_MCP_SERVER */,
2303
- params
2400
+ params,
2401
+ RemoveMcpServerResultSchema
2304
2402
  );
2305
- const result = response["result"];
2306
- return result ?? response;
2307
2403
  }
2308
- /**
2309
- * List available MCP registry servers.
2310
- */
2311
2404
  async listMcpRegistry() {
2312
- this._ensureNotClosed();
2313
- this._ensureSession();
2314
- const response = await this._engine.sendRequest(
2405
+ return this._sessionRpcWithoutParams(
2315
2406
  "droid.list_mcp_registry" /* LIST_MCP_REGISTRY */,
2316
- {}
2407
+ ListMcpRegistryResultSchema
2317
2408
  );
2318
- const result = response["result"];
2319
- return result ?? response;
2320
2409
  }
2321
- /**
2322
- * List available MCP tools.
2323
- */
2324
2410
  async listMcpTools() {
2325
- this._ensureNotClosed();
2326
- this._ensureSession();
2327
- const response = await this._engine.sendRequest(
2411
+ return this._sessionRpcWithoutParams(
2328
2412
  "droid.list_mcp_tools" /* LIST_MCP_TOOLS */,
2329
- {}
2413
+ ListMcpToolsResultSchema
2414
+ );
2415
+ }
2416
+ async listTools(params = {}) {
2417
+ return this._sessionRpc(
2418
+ "droid.list_tools" /* LIST_TOOLS */,
2419
+ params,
2420
+ ListToolsResultSchema
2330
2421
  );
2331
- const result = response["result"];
2332
- return result ?? response;
2333
2422
  }
2334
- /**
2335
- * List MCP servers with status and summary.
2336
- */
2337
2423
  async listMcpServers() {
2338
- this._ensureNotClosed();
2339
- this._ensureSession();
2340
- const response = await this._engine.sendRequest(
2424
+ return this._sessionRpcWithoutParams(
2341
2425
  "droid.list_mcp_servers" /* LIST_MCP_SERVERS */,
2342
- {}
2426
+ ListMcpServersResultSchema
2343
2427
  );
2344
- const result = response["result"];
2345
- return result ?? response;
2346
2428
  }
2347
- /**
2348
- * Toggle an MCP tool on or off.
2349
- */
2350
2429
  async toggleMcpTool(params) {
2351
- this._ensureNotClosed();
2352
- this._ensureSession();
2353
- const response = await this._engine.sendRequest(
2430
+ return this._sessionRpc(
2354
2431
  "droid.toggle_mcp_tool" /* TOGGLE_MCP_TOOL */,
2355
- params
2432
+ params,
2433
+ ToggleMcpToolResultSchema
2356
2434
  );
2357
- const result = response["result"];
2358
- return result ?? response;
2359
2435
  }
2360
- // ------------------------------------------------------------------
2361
- // Skills and bug report methods
2362
- // ------------------------------------------------------------------
2363
- /**
2364
- * List available skills.
2365
- */
2366
2436
  async listSkills() {
2367
- this._ensureNotClosed();
2368
- this._ensureSession();
2369
- const response = await this._engine.sendRequest(
2437
+ return this._sessionRpcWithoutParams(
2370
2438
  "droid.list_skills" /* LIST_SKILLS */,
2371
- {}
2439
+ ListSkillsResultSchema
2372
2440
  );
2373
- const result = response["result"];
2374
- return result ?? response;
2375
2441
  }
2376
- /**
2377
- * Submit a bug report.
2378
- */
2379
2442
  async submitBugReport(params) {
2380
- this._ensureNotClosed();
2381
- this._ensureSession();
2382
- const response = await this._engine.sendRequest(
2443
+ return this._sessionRpc(
2383
2444
  "droid.submit_bug_report" /* SUBMIT_BUG_REPORT */,
2384
- params
2445
+ params,
2446
+ SubmitBugReportResultSchema
2447
+ );
2448
+ }
2449
+ async getRewindInfo(params) {
2450
+ return this._sessionRpc(
2451
+ "droid.get_rewind_info" /* GET_REWIND_INFO */,
2452
+ params,
2453
+ GetRewindInfoResultSchema
2454
+ );
2455
+ }
2456
+ async executeRewind(params) {
2457
+ return this._sessionRpc(
2458
+ "droid.execute_rewind" /* EXECUTE_REWIND */,
2459
+ params,
2460
+ ExecuteRewindResultSchema,
2461
+ REWIND_TIMEOUT
2462
+ );
2463
+ }
2464
+ async compactSession(params) {
2465
+ return this._sessionRpc(
2466
+ "droid.compact_session" /* COMPACT_SESSION */,
2467
+ params,
2468
+ CompactSessionResultSchema,
2469
+ COMPACTION_TIMEOUT
2470
+ );
2471
+ }
2472
+ async forkSession() {
2473
+ return this._sessionRpcWithoutParams(
2474
+ "droid.fork_session" /* FORK_SESSION */,
2475
+ ForkSessionResultSchema
2476
+ );
2477
+ }
2478
+ async getContextStats() {
2479
+ return this._sessionRpcWithoutParams(
2480
+ "droid.get_context_stats" /* GET_CONTEXT_STATS */,
2481
+ GetContextStatsResultSchema
2482
+ );
2483
+ }
2484
+ async renameSession(params) {
2485
+ return this._sessionRpc(
2486
+ "droid.rename_session" /* RENAME_SESSION */,
2487
+ params,
2488
+ RenameSessionResultSchema
2385
2489
  );
2386
- const result = response["result"];
2387
- return result ?? response;
2388
2490
  }
2389
- // ------------------------------------------------------------------
2390
- // Notification subscription
2391
- // ------------------------------------------------------------------
2392
- /**
2393
- * Register a callback for incoming notification messages.
2394
- *
2395
- * Multiple listeners can be registered. Each receives the full parsed
2396
- * notification object. Optionally filter by notification type.
2397
- *
2398
- * Listener exceptions are isolated — if one raises, others still receive
2399
- * the event and the engine continues.
2400
- *
2401
- * @param callback - Invoked with the notification object.
2402
- * @param filter - Optional filter to only receive specific notification types.
2403
- * @returns An unsubscribe function. Calling it again is safe (no-op).
2404
- */
2405
2491
  onNotification(callback, filter) {
2406
- const entry = {
2407
- callback,
2408
- typeFilter: filter?.type
2409
- };
2492
+ const entry = { callback, filter };
2410
2493
  this._notificationListeners.push(entry);
2411
2494
  let unsubscribed = false;
2412
2495
  return () => {
@@ -2419,54 +2502,18 @@ var DroidClient = class {
2419
2502
  }
2420
2503
  };
2421
2504
  }
2422
- // ------------------------------------------------------------------
2423
- // Permission/ask-user handler registration
2424
- // ------------------------------------------------------------------
2425
- /**
2426
- * Register a handler for server→client permission requests.
2427
- *
2428
- * The handler receives the request params and should return a
2429
- * ToolConfirmationOutcome string value. Async handlers are awaited.
2430
- * Replaces any previously registered handler.
2431
- */
2432
2505
  setPermissionHandler(handler) {
2433
2506
  this._permissionHandler = handler;
2434
2507
  }
2435
- /**
2436
- * Remove the permission request handler.
2437
- * Restores default behavior: return "cancel".
2438
- */
2439
2508
  clearPermissionHandler() {
2440
2509
  this._permissionHandler = null;
2441
2510
  }
2442
- /**
2443
- * Register a handler for server→client ask-user requests.
2444
- *
2445
- * The handler receives the request params and should return a result
2446
- * object with `cancelled` and `answers` keys. Async handlers are awaited.
2447
- * Replaces any previously registered handler.
2448
- */
2449
2511
  setAskUserHandler(handler) {
2450
2512
  this._askUserHandler = handler;
2451
2513
  }
2452
- /**
2453
- * Remove the ask-user request handler.
2454
- * Restores default behavior: return `{ cancelled: true, answers: [] }`.
2455
- */
2456
2514
  clearAskUserHandler() {
2457
2515
  this._askUserHandler = null;
2458
2516
  }
2459
- // ------------------------------------------------------------------
2460
- // Lifecycle
2461
- // ------------------------------------------------------------------
2462
- /**
2463
- * Close the client and release all resources.
2464
- *
2465
- * Rejects pending requests, clears handlers and listeners, and closes
2466
- * the protocol engine. Idempotent — safe to call multiple times.
2467
- *
2468
- * After close, all method calls throw ConnectionError immediately.
2469
- */
2470
2517
  async close() {
2471
2518
  if (this._closed) {
2472
2519
  return;
@@ -2477,48 +2524,16 @@ var DroidClient = class {
2477
2524
  this._askUserHandler = null;
2478
2525
  await this._engine.close();
2479
2526
  }
2480
- // ------------------------------------------------------------------
2481
- // Internal: dispatch methods
2482
- // ------------------------------------------------------------------
2483
- /**
2484
- * Dispatch a notification to all registered client-level listeners.
2485
- * Filters by notification type if a type filter is set.
2486
- * Exception in one listener does not affect others.
2487
- */
2488
2527
  _dispatchNotification(notification) {
2489
- const params = notification["params"];
2490
- const innerNotification = params?.["notification"];
2491
- const notificationType = innerNotification?.["type"];
2492
- const listeners = [...this._notificationListeners];
2493
- for (const listener of listeners) {
2494
- if (listener.typeFilter != null && listener.typeFilter !== notificationType) {
2495
- continue;
2496
- }
2497
- try {
2498
- listener.callback(notification);
2499
- } catch {
2500
- }
2501
- }
2528
+ dispatchNotification(notification, [...this._notificationListeners]);
2502
2529
  }
2503
- /**
2504
- * Dispatch to the client-level permission handler.
2505
- * If no handler is set, returns the default "cancel" outcome.
2506
- * If handler throws, the error propagates to the protocol engine
2507
- * which sends an error response.
2508
- */
2509
2530
  _dispatchPermissionRequest(params) {
2510
2531
  const handler = this._permissionHandler;
2511
2532
  if (handler == null) {
2512
- return "cancel";
2533
+ return "cancel" /* Cancel */;
2513
2534
  }
2514
2535
  return handler(params);
2515
2536
  }
2516
- /**
2517
- * Dispatch to the client-level ask-user handler.
2518
- * If no handler is set, returns the default cancelled response.
2519
- * If handler throws, the error propagates to the protocol engine
2520
- * which sends an error response.
2521
- */
2522
2537
  _dispatchAskUserRequest(params) {
2523
2538
  const handler = this._askUserHandler;
2524
2539
  if (handler == null) {
@@ -2526,12 +2541,6 @@ var DroidClient = class {
2526
2541
  }
2527
2542
  return handler(params);
2528
2543
  }
2529
- // ------------------------------------------------------------------
2530
- // Internal: guards
2531
- // ------------------------------------------------------------------
2532
- /**
2533
- * Throw ConnectionError if the client has been closed.
2534
- */
2535
2544
  _ensureNotClosed() {
2536
2545
  if (this._closed) {
2537
2546
  throw new ConnectionError(
@@ -2539,9 +2548,6 @@ var DroidClient = class {
2539
2548
  );
2540
2549
  }
2541
2550
  }
2542
- /**
2543
- * Throw SessionError if no active session.
2544
- */
2545
2551
  _ensureSession() {
2546
2552
  if (this._sessionId == null) {
2547
2553
  throw new SessionError(
@@ -2552,26 +2558,79 @@ var DroidClient = class {
2552
2558
  };
2553
2559
 
2554
2560
  // src/stream.ts
2555
- function convertNotificationToStreamMessage(notification) {
2561
+ var DroidMessageType = {
2562
+ Assistant: "assistant",
2563
+ User: "user",
2564
+ ToolCall: "tool_call",
2565
+ AssistantTextDelta: "assistant_text_delta",
2566
+ AssistantTextComplete: "assistant_text_complete",
2567
+ ThinkingTextDelta: "thinking_text_delta",
2568
+ ThinkingTextComplete: "thinking_text_complete",
2569
+ ToolCallDelta: "tool_call_delta",
2570
+ ToolResult: "tool_result",
2571
+ ToolProgress: "tool_progress",
2572
+ WorkingStateChanged: "working_state_changed",
2573
+ TokenUsageUpdate: "token_usage_update",
2574
+ PermissionResolved: "permission_resolved",
2575
+ SettingsUpdated: "settings_updated",
2576
+ SessionTitleUpdated: "session_title_updated",
2577
+ McpStatusChanged: "mcp_status_changed",
2578
+ MissionStateChanged: "mission_state_changed",
2579
+ MissionFeaturesChanged: "mission_features_changed",
2580
+ MissionProgressEntry: "mission_progress_entry",
2581
+ MissionHeartbeat: "mission_heartbeat",
2582
+ MissionWorkerStarted: "mission_worker_started",
2583
+ MissionWorkerCompleted: "mission_worker_completed",
2584
+ McpAuthRequired: "mcp_auth_required",
2585
+ McpAuthCompleted: "mcp_auth_completed",
2586
+ Hook: "hook",
2587
+ Error: "error",
2588
+ Result: "result"
2589
+ };
2590
+ function convertNotificationToStreamMessage(raw) {
2591
+ const parsed = SessionNotificationPayloadSchema.safeParse(raw);
2592
+ if (!parsed.success) {
2593
+ return null;
2594
+ }
2595
+ const notification = parsed.data;
2556
2596
  switch (notification.type) {
2557
2597
  case "assistant_text_delta" /* ASSISTANT_TEXT_DELTA */:
2558
2598
  return {
2559
- type: "assistant_text_delta",
2599
+ type: DroidMessageType.AssistantTextDelta,
2560
2600
  messageId: notification.messageId,
2561
2601
  blockIndex: notification.blockIndex,
2562
2602
  text: notification.textDelta
2563
2603
  };
2604
+ case "assistant_text_complete" /* ASSISTANT_TEXT_COMPLETE */:
2605
+ return {
2606
+ type: DroidMessageType.AssistantTextComplete,
2607
+ messageId: notification.messageId,
2608
+ blockIndex: notification.blockIndex
2609
+ };
2564
2610
  case "thinking_text_delta" /* THINKING_TEXT_DELTA */:
2565
2611
  return {
2566
- type: "thinking_text_delta",
2612
+ type: DroidMessageType.ThinkingTextDelta,
2567
2613
  messageId: notification.messageId,
2568
2614
  blockIndex: notification.blockIndex,
2569
2615
  text: notification.textDelta
2570
2616
  };
2617
+ case "thinking_text_complete" /* THINKING_TEXT_COMPLETE */:
2618
+ return {
2619
+ type: DroidMessageType.ThinkingTextComplete,
2620
+ messageId: notification.messageId,
2621
+ blockIndex: notification.blockIndex,
2622
+ durationMs: notification.durationMs
2623
+ };
2624
+ case "tool_call" /* TOOL_CALL */:
2625
+ return {
2626
+ type: DroidMessageType.ToolCallDelta,
2627
+ toolUse: notification.toolUse
2628
+ };
2571
2629
  case "tool_result" /* TOOL_RESULT */:
2572
2630
  return {
2573
- type: "tool_result",
2631
+ type: DroidMessageType.ToolResult,
2574
2632
  toolUseId: notification.toolUseId,
2633
+ toolName: "",
2575
2634
  content: normalizeToolResultContent(notification.content),
2576
2635
  isError: Boolean(notification.isError)
2577
2636
  };
@@ -2579,7 +2638,7 @@ function convertNotificationToStreamMessage(notification) {
2579
2638
  const update = notification.update;
2580
2639
  const text = update?.text ?? update?.status ?? update?.details ?? "";
2581
2640
  return {
2582
- type: "tool_progress",
2641
+ type: DroidMessageType.ToolProgress,
2583
2642
  toolUseId: notification.toolUseId,
2584
2643
  toolName: notification.toolName,
2585
2644
  content: text,
@@ -2588,108 +2647,117 @@ function convertNotificationToStreamMessage(notification) {
2588
2647
  }
2589
2648
  case "droid_working_state_changed" /* DROID_WORKING_STATE_CHANGED */:
2590
2649
  return {
2591
- type: "working_state_changed",
2650
+ type: DroidMessageType.WorkingStateChanged,
2592
2651
  state: notification.newState
2593
2652
  };
2594
2653
  case "session_token_usage_changed" /* SESSION_TOKEN_USAGE_CHANGED */: {
2595
2654
  const tu = notification.tokenUsage;
2596
2655
  return {
2597
- type: "token_usage_update",
2656
+ type: DroidMessageType.TokenUsageUpdate,
2598
2657
  inputTokens: tu.inputTokens,
2599
2658
  outputTokens: tu.outputTokens,
2600
2659
  cacheReadTokens: tu.cacheReadTokens,
2601
- cacheWriteTokens: tu.cacheCreationTokens,
2660
+ cacheCreationTokens: tu.cacheCreationTokens,
2602
2661
  thinkingTokens: tu.thinkingTokens
2603
2662
  };
2604
2663
  }
2605
2664
  case "create_message" /* CREATE_MESSAGE */: {
2606
2665
  const msg = notification.message;
2607
2666
  const messages = [];
2608
- if (msg.content && Array.isArray(msg.content)) {
2609
- for (const block of msg.content) {
2610
- if (block.type === "tool_use") {
2611
- messages.push({
2612
- type: "tool_use",
2613
- toolName: block.name,
2614
- toolInput: block.input ?? {},
2615
- toolUseId: block.id
2616
- });
2617
- }
2667
+ for (const block of msg.content) {
2668
+ if (block.type === "tool_use") {
2669
+ messages.push({
2670
+ type: DroidMessageType.ToolCall,
2671
+ toolUse: block
2672
+ });
2618
2673
  }
2619
2674
  }
2620
- messages.push({
2621
- type: "create_message",
2622
- messageId: msg.id,
2623
- role: msg.role,
2624
- content: msg.content ?? [],
2625
- parentId: notification.parentId
2626
- });
2675
+ if (msg.role === FactoryDroidMessageRole.Assistant) {
2676
+ messages.push({
2677
+ type: DroidMessageType.Assistant,
2678
+ message: msg,
2679
+ text: extractTextFromMessage(msg)
2680
+ });
2681
+ } else if (msg.role === FactoryDroidMessageRole.User) {
2682
+ messages.push({
2683
+ type: DroidMessageType.User,
2684
+ message: msg
2685
+ });
2686
+ } else {
2687
+ messages.push({
2688
+ type: "create_message",
2689
+ messageId: msg.id,
2690
+ role: msg.role,
2691
+ content: msg.content,
2692
+ parentId: notification.parentId
2693
+ });
2694
+ }
2627
2695
  return messages;
2628
2696
  }
2629
2697
  case "error" /* ERROR */:
2630
2698
  return {
2631
- type: "error",
2699
+ type: DroidMessageType.Error,
2632
2700
  message: notification.message,
2633
2701
  errorType: notification.errorType,
2634
2702
  timestamp: notification.timestamp
2635
2703
  };
2636
2704
  case "permission_resolved" /* PERMISSION_RESOLVED */:
2637
2705
  return {
2638
- type: "permission_resolved",
2706
+ type: DroidMessageType.PermissionResolved,
2639
2707
  requestId: notification.requestId,
2640
2708
  toolUseIds: notification.toolUseIds,
2641
2709
  selectedOption: notification.selectedOption
2642
2710
  };
2643
2711
  case "settings_updated" /* SETTINGS_UPDATED */:
2644
2712
  return {
2645
- type: "settings_updated",
2713
+ type: DroidMessageType.SettingsUpdated,
2646
2714
  settings: notification.settings
2647
2715
  };
2648
2716
  case "session_title_updated" /* SESSION_TITLE_UPDATED */:
2649
2717
  return {
2650
- type: "session_title_updated",
2718
+ type: DroidMessageType.SessionTitleUpdated,
2651
2719
  title: notification.title
2652
2720
  };
2653
2721
  case "mcp_status_changed" /* MCP_STATUS_CHANGED */:
2654
2722
  return {
2655
- type: "mcp_status_changed",
2723
+ type: DroidMessageType.McpStatusChanged,
2656
2724
  servers: notification.servers,
2657
2725
  summary: notification.summary
2658
2726
  };
2659
2727
  case "mission_state_changed" /* MISSION_STATE_CHANGED */:
2660
2728
  return {
2661
- type: "mission_state_changed",
2729
+ type: DroidMessageType.MissionStateChanged,
2662
2730
  state: notification.state
2663
2731
  };
2664
2732
  case "mission_features_changed" /* MISSION_FEATURES_CHANGED */:
2665
2733
  return {
2666
- type: "mission_features_changed",
2734
+ type: DroidMessageType.MissionFeaturesChanged,
2667
2735
  features: notification.features
2668
2736
  };
2669
2737
  case "mission_progress_entry" /* MISSION_PROGRESS_ENTRY */:
2670
2738
  return {
2671
- type: "mission_progress_entry",
2739
+ type: DroidMessageType.MissionProgressEntry,
2672
2740
  progressLog: notification.progressLog
2673
2741
  };
2674
2742
  case "mission_heartbeat" /* MISSION_HEARTBEAT */:
2675
2743
  return {
2676
- type: "mission_heartbeat",
2744
+ type: DroidMessageType.MissionHeartbeat,
2677
2745
  timestamp: notification.timestamp
2678
2746
  };
2679
2747
  case "mission_worker_started" /* MISSION_WORKER_STARTED */:
2680
2748
  return {
2681
- type: "mission_worker_started",
2749
+ type: DroidMessageType.MissionWorkerStarted,
2682
2750
  workerSessionId: notification.workerSessionId
2683
2751
  };
2684
2752
  case "mission_worker_completed" /* MISSION_WORKER_COMPLETED */:
2685
2753
  return {
2686
- type: "mission_worker_completed",
2754
+ type: DroidMessageType.MissionWorkerCompleted,
2687
2755
  workerSessionId: notification.workerSessionId,
2688
2756
  exitCode: notification.exitCode
2689
2757
  };
2690
2758
  case "mcp_auth_required" /* MCP_AUTH_REQUIRED */:
2691
2759
  return {
2692
- type: "mcp_auth_required",
2760
+ type: DroidMessageType.McpAuthRequired,
2693
2761
  serverName: notification.serverName,
2694
2762
  authUrl: notification.authUrl,
2695
2763
  message: notification.message,
@@ -2697,56 +2765,210 @@ function convertNotificationToStreamMessage(notification) {
2697
2765
  };
2698
2766
  case "mcp_auth_completed" /* MCP_AUTH_COMPLETED */:
2699
2767
  return {
2700
- type: "mcp_auth_completed",
2768
+ type: DroidMessageType.McpAuthCompleted,
2701
2769
  serverName: notification.serverName,
2702
2770
  outcome: notification.outcome,
2703
2771
  message: notification.message
2704
2772
  };
2773
+ case "hook_execution_started" /* HOOK_EXECUTION_STARTED */:
2774
+ return notification.hookCommands.map((hookCommand) => ({
2775
+ type: DroidMessageType.Hook,
2776
+ hookId: notification.hookId,
2777
+ eventName: notification.hookEventName,
2778
+ matcher: notification.hookMatcher,
2779
+ toolCallId: notification.hookToolCallId,
2780
+ command: hookCommand.command,
2781
+ timeout: hookCommand.timeout,
2782
+ status: "started"
2783
+ }));
2784
+ case "hook_execution_completed" /* HOOK_EXECUTION_COMPLETED */:
2785
+ return (notification.hookResults ?? []).map((hookResult) => ({
2786
+ type: DroidMessageType.Hook,
2787
+ hookId: notification.hookId,
2788
+ eventName: notification.hookEventName,
2789
+ matcher: notification.hookMatcher,
2790
+ toolCallId: notification.hookToolCallId,
2791
+ command: hookResult.command,
2792
+ timeout: hookResult.timeout,
2793
+ status: notification.hookStatus,
2794
+ exitCode: hookResult.exitCode,
2795
+ stdout: hookResult.stdout,
2796
+ stderr: hookResult.stderr
2797
+ }));
2798
+ case "structured_output" /* STRUCTURED_OUTPUT */:
2799
+ return {
2800
+ type: "structured_output",
2801
+ messageId: notification.messageId,
2802
+ structuredOutput: notification.structuredOutput,
2803
+ structuredOutputError: notification.structuredOutputError
2804
+ };
2705
2805
  default:
2706
- console.warn(
2707
- `[droid-sdk] Unknown notification type: ${String(notification.type)}`
2708
- );
2709
2806
  return null;
2710
2807
  }
2711
2808
  }
2712
2809
  var StreamStateTracker = class {
2713
- /** Whether we have ever seen a non-idle state. */
2810
+ constructor(options = {}) {
2811
+ this.options = options;
2812
+ }
2714
2813
  hasBeenNonIdle = false;
2715
- /** Last-seen token usage update (to attach to TurnComplete). */
2716
2814
  lastTokenUsage = null;
2717
- /**
2718
- * Process a DroidMessage and return any additional messages that should be
2719
- * emitted (e.g. TurnComplete sentinel).
2720
- *
2721
- * @param message - The DroidMessage to process.
2722
- * @returns An array of additional messages to emit (may be empty).
2723
- */
2815
+ fullText = "";
2816
+ finalAssistantText = "";
2817
+ structuredOutput = null;
2818
+ structuredOutputError = null;
2819
+ errors = [];
2820
+ numTurns = 0;
2821
+ emittedMessages = [];
2822
+ toolNameMap = /* @__PURE__ */ new Map();
2823
+ getToolName(toolUseId) {
2824
+ return this.toolNameMap.get(toolUseId) ?? "";
2825
+ }
2724
2826
  processMessage(message) {
2725
2827
  const additional = [];
2726
- if (message.type === "token_usage_update") {
2828
+ if (message.type === "tool_use") {
2829
+ this.toolNameMap.set(message.toolUseId, message.toolName);
2830
+ }
2831
+ if (message.type === DroidMessageType.ToolCall) {
2832
+ this.toolNameMap.set(message.toolUse.id, message.toolUse.name);
2833
+ }
2834
+ if (message.type === DroidMessageType.ToolCallDelta) {
2835
+ this.toolNameMap.set(message.toolUse.id, message.toolUse.name);
2836
+ }
2837
+ if (message.type === DroidMessageType.ToolResult) {
2838
+ message = { ...message, toolName: this.getToolName(message.toolUseId) };
2839
+ }
2840
+ if (message.type === DroidMessageType.AssistantTextDelta) {
2841
+ this.fullText += message.text;
2842
+ }
2843
+ if (message.type === DroidMessageType.Assistant) {
2844
+ this.finalAssistantText = message.text;
2845
+ if (this.fullText.length === 0) {
2846
+ this.fullText = message.text;
2847
+ }
2848
+ }
2849
+ if (message.type === DroidMessageType.TokenUsageUpdate) {
2727
2850
  this.lastTokenUsage = message;
2728
2851
  }
2729
- if (message.type === "working_state_changed") {
2852
+ if (message.type === DroidMessageType.Error) {
2853
+ this.errors.push(message);
2854
+ }
2855
+ if (message.type === "structured_output") {
2856
+ this.structuredOutput = message.structuredOutput;
2857
+ this.structuredOutputError = message.structuredOutputError;
2858
+ return { message: null, additional };
2859
+ }
2860
+ if (message.type === DroidMessageType.WorkingStateChanged) {
2730
2861
  if (message.state !== "idle" /* Idle */) {
2731
2862
  this.hasBeenNonIdle = true;
2732
2863
  } else if (this.hasBeenNonIdle) {
2733
- additional.push({
2734
- type: "turn_complete",
2735
- tokenUsage: this.lastTokenUsage
2736
- });
2864
+ this.numTurns++;
2865
+ additional.push(this.createResultMessage());
2737
2866
  this.hasBeenNonIdle = false;
2867
+ this.resetTurnState();
2738
2868
  }
2739
2869
  }
2740
- return additional;
2870
+ if (message.type !== DroidMessageType.WorkingStateChanged) {
2871
+ this.trackEmittedMessage(message);
2872
+ }
2873
+ return { message, additional };
2741
2874
  }
2742
- /**
2743
- * Reset the tracker for a new turn/stream call.
2744
- */
2745
- reset() {
2746
- this.hasBeenNonIdle = false;
2875
+ createResultMessage() {
2876
+ if (this.options.hasOutputFormat && this.structuredOutput === null && this.structuredOutputError === null) {
2877
+ this.structuredOutput = parseJsonObject(this.finalAssistantText || this.fullText) ?? null;
2878
+ }
2879
+ const tokenUsage = this.lastTokenUsage ? stripTokenUsageType(this.lastTokenUsage) : null;
2880
+ const result = this.finalAssistantText || this.fullText;
2881
+ const base = {
2882
+ type: DroidMessageType.Result,
2883
+ sessionId: this.options.sessionId ?? "",
2884
+ durationMs: Date.now() - (this.options.startedAt ?? Date.now()),
2885
+ numTurns: this.numTurns,
2886
+ result,
2887
+ tokenUsage,
2888
+ messages: [...this.emittedMessages],
2889
+ text: result,
2890
+ turnCount: this.numTurns
2891
+ };
2892
+ if (this.structuredOutputError) {
2893
+ return {
2894
+ ...base,
2895
+ subtype: "error_structured_output",
2896
+ isError: true,
2897
+ success: false,
2898
+ errors: [this.structuredOutputError.message],
2899
+ structuredOutput: this.structuredOutput,
2900
+ structuredOutputError: this.structuredOutputError,
2901
+ error: null
2902
+ };
2903
+ }
2904
+ if (this.errors.length > 0) {
2905
+ return {
2906
+ ...base,
2907
+ subtype: "error_during_execution",
2908
+ isError: true,
2909
+ success: false,
2910
+ errors: this.errors.map((error) => error.message),
2911
+ structuredOutput: this.structuredOutput,
2912
+ structuredOutputError: null,
2913
+ error: this.errors[0] ?? null
2914
+ };
2915
+ }
2916
+ return {
2917
+ ...base,
2918
+ subtype: "success",
2919
+ isError: false,
2920
+ success: true,
2921
+ structuredOutput: this.structuredOutput,
2922
+ structuredOutputError: null,
2923
+ error: null
2924
+ };
2925
+ }
2926
+ trackEmittedMessage(message) {
2927
+ if (isDefaultStreamMessage(message)) {
2928
+ this.emittedMessages.push(message);
2929
+ }
2930
+ }
2931
+ resetTurnState() {
2747
2932
  this.lastTokenUsage = null;
2933
+ this.fullText = "";
2934
+ this.finalAssistantText = "";
2935
+ this.structuredOutput = null;
2936
+ this.structuredOutputError = null;
2937
+ this.errors = [];
2938
+ this.emittedMessages = [];
2748
2939
  }
2749
2940
  };
2941
+ function isInternalMessage(message) {
2942
+ return message.type === "structured_output" || message.type === "tool_use" || message.type === "create_message";
2943
+ }
2944
+ function isDefaultStreamMessage(message) {
2945
+ return message.type === DroidMessageType.Assistant || message.type === DroidMessageType.User || message.type === DroidMessageType.ToolCall || message.type === DroidMessageType.ToolResult || message.type === DroidMessageType.Hook || message.type === DroidMessageType.Error || message.type === DroidMessageType.Result;
2946
+ }
2947
+ function stripTokenUsageType(message) {
2948
+ const {
2949
+ inputTokens,
2950
+ outputTokens,
2951
+ cacheCreationTokens,
2952
+ cacheReadTokens,
2953
+ thinkingTokens
2954
+ } = message;
2955
+ return {
2956
+ inputTokens,
2957
+ outputTokens,
2958
+ cacheCreationTokens,
2959
+ cacheReadTokens,
2960
+ thinkingTokens
2961
+ };
2962
+ }
2963
+ function parseJsonObject(text) {
2964
+ try {
2965
+ const parsed = JSON.parse(text);
2966
+ const result = JsonObjectSchema.safeParse(parsed);
2967
+ return result.success ? result.data : null;
2968
+ } catch {
2969
+ return null;
2970
+ }
2971
+ }
2750
2972
  function normalizeToolResultContent(content) {
2751
2973
  if (content == null) {
2752
2974
  return "";
@@ -2759,436 +2981,562 @@ function normalizeToolResultContent(content) {
2759
2981
  }
2760
2982
  return String(content);
2761
2983
  }
2984
+ function extractTextFromMessage(message) {
2985
+ return message.content.filter((block) => block.type === "text").map((block) => block.text).join("");
2986
+ }
2762
2987
 
2763
- // src/query.ts
2764
- function query(options) {
2765
- let transport = null;
2766
- let client = null;
2767
- let sessionId = null;
2768
- let aborted = false;
2769
- const messageQueue = [];
2770
- let resolveWaiting = null;
2771
- let streamDone = false;
2772
- function enqueueMessage(msg) {
2773
- messageQueue.push(msg);
2774
- if (resolveWaiting) {
2775
- const resolve = resolveWaiting;
2776
- resolveWaiting = null;
2777
- resolve();
2778
- }
2779
- }
2780
- function signalDone() {
2781
- streamDone = true;
2782
- if (resolveWaiting) {
2783
- const resolve = resolveWaiting;
2784
- resolveWaiting = null;
2785
- resolve();
2786
- }
2787
- }
2788
- async function* generateMessages() {
2789
- if (options.transport) {
2790
- transport = options.transport;
2791
- } else {
2792
- const transportOptions = {
2793
- execPath: options.execPath,
2794
- execArgs: options.execArgs,
2795
- cwd: options.cwd,
2796
- env: options.env
2797
- };
2798
- const processTransport = new ProcessTransport(transportOptions);
2799
- await processTransport.connect();
2800
- transport = processTransport;
2801
- }
2802
- client = new DroidClient({ transport });
2803
- if (options.permissionHandler) {
2804
- client.setPermissionHandler(options.permissionHandler);
2805
- }
2806
- if (options.askUserHandler) {
2807
- client.setAskUserHandler(options.askUserHandler);
2808
- }
2809
- const stateTracker = new StreamStateTracker();
2810
- client.onNotification((notification) => {
2811
- const params = notification["params"];
2812
- const innerNotification = params?.["notification"];
2813
- if (!innerNotification) {
2814
- return;
2815
- }
2816
- const converted = convertNotificationToStreamMessage(
2817
- innerNotification
2818
- );
2819
- if (converted === null) {
2820
- return;
2821
- }
2822
- const messages = Array.isArray(converted) ? converted : [converted];
2823
- for (const msg of messages) {
2824
- enqueueMessage(msg);
2825
- const additional = stateTracker.processMessage(msg);
2826
- for (const extra of additional) {
2827
- enqueueMessage(extra);
2828
- if (extra.type === "turn_complete") {
2829
- signalDone();
2830
- }
2988
+ // src/helpers.ts
2989
+ function wireAbortSignal(signal, onAbort) {
2990
+ if (!signal) return () => {
2991
+ };
2992
+ if (signal.aborted) {
2993
+ onAbort();
2994
+ return () => {
2995
+ };
2996
+ } else {
2997
+ const listener = () => onAbort();
2998
+ signal.addEventListener("abort", listener, { once: true });
2999
+ return () => signal.removeEventListener("abort", listener);
3000
+ }
3001
+ }
3002
+ function extractInnerNotification(notification) {
3003
+ const parsed = SessionNotificationSchema.safeParse(notification);
3004
+ return parsed.success ? parsed.data.params.notification : null;
3005
+ }
3006
+ var MessageBridge = class {
3007
+ constructor(onDone, _options = {}) {
3008
+ this._options = _options;
3009
+ this._onDone = onDone;
3010
+ this._stateTracker = new StreamStateTracker({
3011
+ sessionId: _options.sessionId,
3012
+ startedAt: _options.startedAt,
3013
+ hasOutputFormat: _options.outputFormat !== void 0
3014
+ });
3015
+ }
3016
+ _queue = [];
3017
+ _onDone;
3018
+ _resolveWaiting = null;
3019
+ _done = false;
3020
+ _stateTracker;
3021
+ notificationHandler = (notification) => {
3022
+ const inner = extractInnerNotification(notification);
3023
+ if (!inner) return;
3024
+ const converted = convertNotificationToStreamMessage(inner);
3025
+ if (converted === null) return;
3026
+ const messages = Array.isArray(converted) ? converted : [converted];
3027
+ for (const msg of messages) {
3028
+ const { message, additional } = this._stateTracker.processMessage(msg);
3029
+ if (message && this._shouldYield(message)) {
3030
+ this._enqueue(message);
3031
+ }
3032
+ for (const extra of additional) {
3033
+ if (this._shouldYield(extra)) {
3034
+ this._enqueue(extra);
3035
+ }
3036
+ if (extra.type === DroidMessageType.Result) {
3037
+ this._signalDone();
2831
3038
  }
2832
3039
  }
2833
- });
2834
- const initParams = {
2835
- machineId: options.machineId ?? "default",
2836
- cwd: options.cwd ?? "."
2837
- };
2838
- if (options.modelId !== void 0) {
2839
- initParams.modelId = options.modelId;
2840
3040
  }
2841
- if (options.autonomyLevel !== void 0) {
2842
- initParams.autonomyLevel = options.autonomyLevel;
3041
+ };
3042
+ signalDone() {
3043
+ this._signalDone();
3044
+ }
3045
+ async *messages() {
3046
+ while (true) {
3047
+ while (this._queue.length > 0) {
3048
+ const msg = this._queue.shift();
3049
+ yield msg;
3050
+ if (msg.type === DroidMessageType.Result) {
3051
+ return;
3052
+ }
3053
+ }
3054
+ if (this._done && this._queue.length === 0) {
3055
+ return;
3056
+ }
3057
+ await new Promise((resolve2) => {
3058
+ this._resolveWaiting = resolve2;
3059
+ });
2843
3060
  }
2844
- if (options.interactionMode !== void 0) {
2845
- initParams.interactionMode = options.interactionMode;
3061
+ }
3062
+ _shouldYield(message) {
3063
+ if (isInternalMessage(message)) {
3064
+ return false;
2846
3065
  }
2847
- if (options.reasoningEffort !== void 0) {
2848
- initParams.reasoningEffort = options.reasoningEffort;
3066
+ return this._options.includePartialMessages ? true : isDefaultStreamMessage(message);
3067
+ }
3068
+ _enqueue(msg) {
3069
+ this._queue.push(msg);
3070
+ if (this._resolveWaiting) {
3071
+ const resolve2 = this._resolveWaiting;
3072
+ this._resolveWaiting = null;
3073
+ resolve2();
2849
3074
  }
2850
- if (options.mcpServers !== void 0) {
2851
- initParams.mcpServers = options.mcpServers;
3075
+ }
3076
+ _signalDone() {
3077
+ const wasDone = this._done;
3078
+ this._done = true;
3079
+ if (!wasDone) {
3080
+ this._onDone?.();
2852
3081
  }
2853
- if (options.enabledToolIds !== void 0) {
2854
- initParams.enabledToolIds = options.enabledToolIds;
3082
+ if (this._resolveWaiting) {
3083
+ const resolve2 = this._resolveWaiting;
3084
+ this._resolveWaiting = null;
3085
+ resolve2();
2855
3086
  }
2856
- const initResult = await client.initializeSession(
2857
- initParams
2858
- );
2859
- sessionId = initResult.sessionId;
2860
- await client.addUserMessage({ text: options.prompt });
2861
- try {
2862
- while (true) {
2863
- if (aborted) {
2864
- return;
2865
- }
2866
- while (messageQueue.length > 0) {
2867
- const msg = messageQueue.shift();
2868
- yield msg;
2869
- if (msg.type === "turn_complete") {
2870
- return;
3087
+ }
3088
+ };
3089
+ async function createTransport(options) {
3090
+ if (options.transport) {
3091
+ return options.transport;
3092
+ }
3093
+ const transportOptions = {
3094
+ execPath: options.execPath,
3095
+ execArgs: options.execArgs,
3096
+ cwd: options.cwd,
3097
+ env: options.env
3098
+ };
3099
+ const processTransport = new ProcessTransport(transportOptions);
3100
+ await processTransport.connect();
3101
+ return processTransport;
3102
+ }
3103
+ function setupClientHandlers(client, options) {
3104
+ if (options.permissionHandler) {
3105
+ client.setPermissionHandler(options.permissionHandler);
3106
+ }
3107
+ if (options.askUserHandler) {
3108
+ client.setAskUserHandler(options.askUserHandler);
3109
+ }
3110
+ }
3111
+ async function createConfiguredClient(options) {
3112
+ const transport = await createTransport(options);
3113
+ const client = new DroidClient({ transport });
3114
+ setupClientHandlers(client, options);
3115
+ return { transport, client };
3116
+ }
3117
+ async function closeQuietly(resource) {
3118
+ if (!resource) {
3119
+ return;
3120
+ }
3121
+ try {
3122
+ await resource.close();
3123
+ } catch {
3124
+ }
3125
+ }
3126
+ function buildInitParams(options) {
3127
+ return {
3128
+ machineId: options.machineId ?? "default",
3129
+ cwd: options.cwd ?? ".",
3130
+ ...options.modelId !== void 0 && { modelId: options.modelId },
3131
+ ...options.autonomyLevel !== void 0 && {
3132
+ autonomyLevel: options.autonomyLevel
3133
+ },
3134
+ ...options.interactionMode !== void 0 && {
3135
+ interactionMode: options.interactionMode
3136
+ },
3137
+ ...options.reasoningEffort !== void 0 && {
3138
+ reasoningEffort: options.reasoningEffort
3139
+ },
3140
+ ...options.specModeModelId !== void 0 && {
3141
+ specModeModelId: options.specModeModelId
3142
+ },
3143
+ ...options.specModeReasoningEffort !== void 0 && {
3144
+ specModeReasoningEffort: options.specModeReasoningEffort
3145
+ },
3146
+ ...options.mcpServers !== void 0 && {
3147
+ mcpServers: options.mcpServers
3148
+ },
3149
+ ...options.enabledToolIds !== void 0 && {
3150
+ enabledToolIds: options.enabledToolIds
3151
+ },
3152
+ ...options.disabledToolIds !== void 0 && {
3153
+ disabledToolIds: options.disabledToolIds
3154
+ },
3155
+ tags: [...options.tags ?? [], SDK_TAG]
3156
+ };
3157
+ }
3158
+
3159
+ // src/mcp.ts
3160
+ import { once } from "events";
3161
+ import http from "http";
3162
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3163
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
3164
+ import { z as z9 } from "zod";
3165
+ function tool(name, description, inputSchemaOrHandler, handler) {
3166
+ if (typeof inputSchemaOrHandler === "function") {
3167
+ const actualHandler = inputSchemaOrHandler;
3168
+ return {
3169
+ name,
3170
+ description,
3171
+ handler: (input) => actualHandler(input)
3172
+ };
3173
+ }
3174
+ if (!handler) {
3175
+ throw new Error(`Missing handler for SDK MCP tool "${name}"`);
3176
+ }
3177
+ const inputObjectSchema = z9.object(inputSchemaOrHandler);
3178
+ return {
3179
+ name,
3180
+ description,
3181
+ inputSchema: inputSchemaOrHandler,
3182
+ handler: (input) => handler(inputObjectSchema.parse(input))
3183
+ };
3184
+ }
3185
+ function isSdkMcpServer(server) {
3186
+ return server instanceof SdkMcpServer;
3187
+ }
3188
+ function toCallToolResult(result) {
3189
+ if (typeof result === "string") {
3190
+ return {
3191
+ content: [{ type: "text", text: result }]
3192
+ };
3193
+ }
3194
+ return result;
3195
+ }
3196
+ async function readJsonBody(req) {
3197
+ const chunks = [];
3198
+ for await (const chunk of req) {
3199
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
3200
+ }
3201
+ if (chunks.length === 0) {
3202
+ return void 0;
3203
+ }
3204
+ return JSON.parse(Buffer.concat(chunks).toString("utf8"));
3205
+ }
3206
+ function writeJsonError(res, statusCode, message) {
3207
+ if (res.headersSent) {
3208
+ return;
3209
+ }
3210
+ res.writeHead(statusCode, { "content-type": "application/json" });
3211
+ res.end(
3212
+ JSON.stringify({
3213
+ jsonrpc: JSONRPC_VERSION,
3214
+ error: { code: -32603 /* INTERNAL_ERROR */, message },
3215
+ id: null
3216
+ })
3217
+ );
3218
+ }
3219
+ var SdkMcpServer = class {
3220
+ name;
3221
+ version;
3222
+ tools;
3223
+ _httpServer = null;
3224
+ _url = null;
3225
+ constructor(options) {
3226
+ this.name = options.name;
3227
+ this.version = options.version ?? "1.0.0";
3228
+ this.tools = options.tools;
3229
+ }
3230
+ get config() {
3231
+ if (!this._url) {
3232
+ return null;
3233
+ }
3234
+ return {
3235
+ type: "http" /* Http */,
3236
+ name: this.name,
3237
+ url: this._url,
3238
+ headers: []
3239
+ };
3240
+ }
3241
+ async start() {
3242
+ if (this.config) {
3243
+ return this.config;
3244
+ }
3245
+ this._httpServer = http.createServer((req, res) => {
3246
+ void this.handleRequest(req, res);
3247
+ });
3248
+ this._httpServer.listen(0, "127.0.0.1");
3249
+ await once(this._httpServer, "listening");
3250
+ const address = this._httpServer.address();
3251
+ if (!address || typeof address === "string") {
3252
+ throw new Error("Unable to determine SDK MCP server address");
3253
+ }
3254
+ this._url = `http://127.0.0.1:${address.port}/mcp`;
3255
+ const config = this.config;
3256
+ if (!config) {
3257
+ throw new Error("Unable to start SDK MCP server");
3258
+ }
3259
+ return config;
3260
+ }
3261
+ async close() {
3262
+ const server = this._httpServer;
3263
+ this._httpServer = null;
3264
+ this._url = null;
3265
+ if (!server) {
3266
+ return;
3267
+ }
3268
+ server.closeAllConnections?.();
3269
+ server.close();
3270
+ await once(server, "close");
3271
+ }
3272
+ createMcpServer() {
3273
+ const server = new McpServer({
3274
+ name: this.name,
3275
+ version: this.version
3276
+ });
3277
+ for (const sdkTool of this.tools) {
3278
+ server.registerTool(
3279
+ sdkTool.name,
3280
+ {
3281
+ description: sdkTool.description,
3282
+ ...sdkTool.inputSchema && {
3283
+ inputSchema: sdkTool.inputSchema
2871
3284
  }
2872
- }
2873
- if (streamDone && messageQueue.length === 0) {
2874
- return;
2875
- }
2876
- await new Promise((resolve) => {
2877
- resolveWaiting = resolve;
2878
- });
2879
- }
2880
- } finally {
3285
+ },
3286
+ async (input) => toCallToolResult(await sdkTool.handler(input))
3287
+ );
2881
3288
  }
3289
+ return server;
2882
3290
  }
2883
- const generator = generateMessages();
2884
- async function* wrappedGenerator() {
3291
+ async handleRequest(req, res) {
3292
+ if (req.url !== "/mcp") {
3293
+ res.writeHead(404).end();
3294
+ return;
3295
+ }
3296
+ if (req.method !== "POST") {
3297
+ res.writeHead(405).end();
3298
+ return;
3299
+ }
3300
+ const server = this.createMcpServer();
3301
+ const transport = new StreamableHTTPServerTransport({
3302
+ sessionIdGenerator: void 0
3303
+ });
3304
+ res.on("close", () => {
3305
+ void transport.close();
3306
+ void server.close();
3307
+ });
2885
3308
  try {
2886
- yield* generator;
2887
- } finally {
2888
- if (client) {
2889
- try {
2890
- await client.close();
2891
- } catch {
2892
- }
2893
- client = null;
2894
- } else if (transport) {
2895
- try {
2896
- await transport.close();
2897
- } catch {
2898
- }
3309
+ const body = await readJsonBody(req);
3310
+ await server.connect(transport);
3311
+ await transport.handleRequest(req, res, body);
3312
+ } catch (error) {
3313
+ writeJsonError(
3314
+ res,
3315
+ 500,
3316
+ error instanceof Error ? error.message : "Internal server error"
3317
+ );
3318
+ await transport.close();
3319
+ await server.close();
3320
+ }
3321
+ }
3322
+ };
3323
+ function createSdkMcpServer(options) {
3324
+ return new SdkMcpServer(options);
3325
+ }
3326
+ async function startSdkMcpServers(servers) {
3327
+ if (!servers) {
3328
+ return { cleanup: async () => {
3329
+ } };
3330
+ }
3331
+ const startedServers = [];
3332
+ const mcpServers = [];
3333
+ try {
3334
+ for (const server of servers) {
3335
+ if (isSdkMcpServer(server)) {
3336
+ mcpServers.push(await server.start());
3337
+ startedServers.push(server);
3338
+ } else {
3339
+ mcpServers.push(server);
2899
3340
  }
2900
- transport = null;
2901
3341
  }
3342
+ } catch (error) {
3343
+ await Promise.all(startedServers.map((server) => server.close()));
3344
+ throw error;
2902
3345
  }
2903
- const wrapped = wrappedGenerator();
2904
- const droidQuery = wrapped;
2905
- Object.defineProperties(droidQuery, {
2906
- interrupt: {
2907
- value: async function interrupt() {
2908
- if (client && !aborted) {
2909
- await client.interruptSession();
2910
- }
2911
- },
2912
- writable: false,
2913
- enumerable: true
2914
- },
2915
- abort: {
2916
- value: function abort() {
2917
- aborted = true;
2918
- signalDone();
2919
- if (client) {
2920
- void client.close().catch(() => {
2921
- });
2922
- client = null;
2923
- } else if (transport) {
2924
- void transport.close().catch(() => {
2925
- });
2926
- }
2927
- transport = null;
2928
- },
2929
- writable: false,
2930
- enumerable: true
2931
- },
2932
- sessionId: {
2933
- get() {
2934
- return sessionId;
2935
- },
2936
- enumerable: true
3346
+ return {
3347
+ mcpServers,
3348
+ cleanup: async () => {
3349
+ await Promise.all(startedServers.map((server) => server.close()));
2937
3350
  }
2938
- });
2939
- return droidQuery;
3351
+ };
2940
3352
  }
2941
3353
 
2942
3354
  // src/session.ts
3355
+ function getAbortError(signal) {
3356
+ if (signal.reason instanceof Error) {
3357
+ return signal.reason;
3358
+ }
3359
+ return new Error(
3360
+ typeof signal.reason === "string" ? signal.reason : "Operation aborted"
3361
+ );
3362
+ }
3363
+ function throwIfAborted(signal) {
3364
+ if (signal?.aborted) {
3365
+ throw getAbortError(signal);
3366
+ }
3367
+ }
2943
3368
  var DroidSession = class {
2944
3369
  _client;
2945
3370
  _sessionId;
2946
3371
  _initResult;
2947
3372
  _closed = false;
3373
+ _cleanupAbortSignal = null;
3374
+ _cleanupCallbacks = [];
3375
+ _activeBridges = /* @__PURE__ */ new Set();
2948
3376
  /** @internal */
2949
3377
  constructor(client, sessionId, initResult) {
2950
3378
  this._client = client;
2951
3379
  this._sessionId = sessionId;
2952
3380
  this._initResult = initResult;
2953
3381
  }
2954
- // ------------------------------------------------------------------
2955
- // Properties
2956
- // ------------------------------------------------------------------
2957
- /** The session ID. */
2958
3382
  get sessionId() {
2959
3383
  return this._sessionId;
2960
3384
  }
2961
- /** The result from session initialization or loading. */
2962
3385
  get initResult() {
2963
3386
  return this._initResult;
2964
3387
  }
2965
- // ------------------------------------------------------------------
2966
- // Messaging
2967
- // ------------------------------------------------------------------
2968
- /**
2969
- * Send a message and return a streaming async generator of DroidMessage events.
2970
- *
2971
- * The generator yields messages until a TurnComplete event is received,
2972
- * signaling the end of the agent's turn.
2973
- *
2974
- * @param text - The user message text.
2975
- * @param options - Optional images/files to include.
2976
- * @returns An async generator yielding DroidMessage events.
2977
- */
2978
- async *stream(text, options) {
3388
+ /** @internal */
3389
+ setAbortSignalCleanup(cleanup) {
3390
+ this._cleanupAbortSignal = cleanup;
3391
+ }
3392
+ /** @internal */
3393
+ addCleanup(cleanup) {
3394
+ this._cleanupCallbacks.push(cleanup);
3395
+ }
3396
+ async *stream(prompt, options) {
2979
3397
  this._ensureNotClosed();
2980
- const messageQueue = [];
2981
- let resolveWaiting = null;
2982
- let streamDone = false;
2983
- function enqueueMessage(msg) {
2984
- messageQueue.push(msg);
2985
- if (resolveWaiting) {
2986
- const resolve = resolveWaiting;
2987
- resolveWaiting = null;
2988
- resolve();
2989
- }
2990
- }
2991
- function signalDone() {
2992
- streamDone = true;
2993
- if (resolveWaiting) {
2994
- const resolve = resolveWaiting;
2995
- resolveWaiting = null;
2996
- resolve();
2997
- }
2998
- }
2999
- const stateTracker = new StreamStateTracker();
3000
- const unsubscribe = this._client.onNotification((notification) => {
3001
- const params = notification["params"];
3002
- const innerNotification = params?.["notification"];
3003
- if (!innerNotification) {
3004
- return;
3005
- }
3006
- const converted = convertNotificationToStreamMessage(
3007
- innerNotification
3008
- );
3009
- if (converted === null) {
3010
- return;
3011
- }
3012
- const messages = Array.isArray(converted) ? converted : [converted];
3013
- for (const msg of messages) {
3014
- enqueueMessage(msg);
3015
- const additional = stateTracker.processMessage(msg);
3016
- for (const extra of additional) {
3017
- enqueueMessage(extra);
3018
- if (extra.type === "turn_complete") {
3019
- signalDone();
3020
- }
3021
- }
3022
- }
3398
+ throwIfAborted(options?.abortSignal);
3399
+ const startedAt = Date.now();
3400
+ let resolveDone = () => {
3401
+ };
3402
+ const donePromise = new Promise((resolve2) => {
3403
+ resolveDone = resolve2;
3023
3404
  });
3024
- try {
3025
- await this._client.addUserMessage({
3026
- text,
3027
- images: options?.images,
3028
- files: options?.files
3405
+ const bridge = new MessageBridge(resolveDone, {
3406
+ includePartialMessages: options?.includePartialMessages,
3407
+ sessionId: this._sessionId,
3408
+ startedAt,
3409
+ outputFormat: options?.outputFormat
3410
+ });
3411
+ this._activeBridges.add(bridge);
3412
+ const unsubscribe = this._client.onNotification(bridge.notificationHandler);
3413
+ let resolveAbort = () => {
3414
+ };
3415
+ const abortPromise = new Promise((resolve2) => {
3416
+ resolveAbort = resolve2;
3417
+ });
3418
+ const cleanupAbortSignal = wireAbortSignal(options?.abortSignal, () => {
3419
+ bridge.signalDone();
3420
+ resolveAbort();
3421
+ void this._client.interruptSession().catch(() => {
3029
3422
  });
3030
- while (true) {
3031
- while (messageQueue.length > 0) {
3032
- const msg = messageQueue.shift();
3033
- yield msg;
3034
- if (msg.type === "turn_complete") {
3035
- return;
3036
- }
3037
- }
3038
- if (streamDone && messageQueue.length === 0) {
3039
- return;
3040
- }
3041
- await new Promise((resolve) => {
3042
- resolveWaiting = resolve;
3043
- });
3423
+ });
3424
+ try {
3425
+ await Promise.race([
3426
+ this._client.addUserMessage({
3427
+ text: prompt,
3428
+ images: options?.images,
3429
+ files: options?.files,
3430
+ outputFormat: options?.outputFormat
3431
+ }),
3432
+ donePromise,
3433
+ abortPromise
3434
+ ]);
3435
+ throwIfAborted(options?.abortSignal);
3436
+ for await (const msg of bridge.messages()) {
3437
+ throwIfAborted(options?.abortSignal);
3438
+ yield msg;
3044
3439
  }
3440
+ throwIfAborted(options?.abortSignal);
3045
3441
  } finally {
3442
+ cleanupAbortSignal();
3046
3443
  unsubscribe();
3444
+ this._activeBridges.delete(bridge);
3047
3445
  }
3048
3446
  }
3049
- /**
3050
- * Send a message and collect the complete response (non-streaming).
3051
- *
3052
- * Internally consumes all stream messages and returns an aggregated
3053
- * {@link DroidResult} with the concatenated text, all messages, and
3054
- * final token usage.
3055
- *
3056
- * @param text - The user message text.
3057
- * @param options - Optional images/files to include.
3058
- * @returns Aggregated result with text, messages, and token usage.
3059
- */
3060
- async send(text, options) {
3061
- this._ensureNotClosed();
3062
- const messages = [];
3063
- let fullText = "";
3064
- let lastTokenUsage = null;
3065
- for await (const msg of this.stream(text, options)) {
3066
- messages.push(msg);
3067
- if (msg.type === "assistant_text_delta") {
3068
- fullText += msg.text;
3069
- }
3070
- if (msg.type === "token_usage_update") {
3071
- lastTokenUsage = msg;
3072
- }
3073
- if (msg.type === "turn_complete" && msg.tokenUsage) {
3074
- lastTokenUsage = msg.tokenUsage;
3075
- }
3076
- }
3077
- return {
3078
- text: fullText,
3079
- messages,
3080
- tokenUsage: lastTokenUsage
3081
- };
3082
- }
3083
- // ------------------------------------------------------------------
3084
- // Session control
3085
- // ------------------------------------------------------------------
3086
- /**
3087
- * Interrupt the current agent turn.
3088
- *
3089
- * Sends an interrupt request. The agent will stop after completing
3090
- * its current operation.
3091
- */
3092
3447
  async interrupt() {
3093
3448
  this._ensureNotClosed();
3094
3449
  await this._client.interruptSession();
3095
3450
  }
3096
- /**
3097
- * Close the session and release all resources.
3098
- *
3099
- * Closes the underlying transport and rejects any pending requests.
3100
- * After close, the session cannot be used.
3101
- */
3102
3451
  async close() {
3103
3452
  if (this._closed) {
3104
3453
  return;
3105
3454
  }
3106
3455
  this._closed = true;
3107
- await this._client.close();
3456
+ this._cleanupAbortSignal?.();
3457
+ this._cleanupAbortSignal = null;
3458
+ for (const bridge of this._activeBridges) {
3459
+ bridge.signalDone();
3460
+ }
3461
+ try {
3462
+ await this._client.closeSession({ reason: "other" }).catch(() => {
3463
+ });
3464
+ await this._client.close();
3465
+ } finally {
3466
+ const cleanups = this._cleanupCallbacks.splice(0);
3467
+ await Promise.all(cleanups.map((cleanup) => cleanup()));
3468
+ }
3108
3469
  }
3109
- // ------------------------------------------------------------------
3110
- // Settings
3111
- // ------------------------------------------------------------------
3112
- /**
3113
- * Update session settings (model, reasoning effort, autonomy, etc.).
3114
- *
3115
- * @param params - Partial settings to update.
3116
- */
3117
3470
  async updateSettings(params) {
3118
3471
  this._ensureNotClosed();
3119
3472
  return this._client.updateSessionSettings(params);
3120
3473
  }
3121
- // ------------------------------------------------------------------
3122
- // MCP methods
3123
- // ------------------------------------------------------------------
3124
- /**
3125
- * Add an MCP server to the session.
3126
- */
3474
+ async enterSpecMode(params = {}) {
3475
+ this._ensureNotClosed();
3476
+ return this._client.updateSessionSettings({
3477
+ interactionMode: "spec" /* Spec */,
3478
+ ...params
3479
+ });
3480
+ }
3127
3481
  async addMcpServer(params) {
3128
3482
  this._ensureNotClosed();
3129
3483
  return this._client.addMcpServer(params);
3130
3484
  }
3131
- /**
3132
- * Remove an MCP server from the session.
3133
- */
3134
3485
  async removeMcpServer(params) {
3135
3486
  this._ensureNotClosed();
3136
3487
  return this._client.removeMcpServer(params);
3137
3488
  }
3138
- /**
3139
- * Toggle an MCP server on or off.
3140
- */
3141
3489
  async toggleMcpServer(params) {
3142
3490
  this._ensureNotClosed();
3143
3491
  return this._client.toggleMcpServer(params);
3144
3492
  }
3145
- /**
3146
- * List MCP servers and their status.
3147
- */
3148
3493
  async listMcpServers() {
3149
3494
  this._ensureNotClosed();
3150
3495
  return this._client.listMcpServers();
3151
3496
  }
3152
- /**
3153
- * List available MCP tools.
3154
- */
3155
3497
  async listMcpTools() {
3156
3498
  this._ensureNotClosed();
3157
3499
  return this._client.listMcpTools();
3158
3500
  }
3159
- /**
3160
- * Authenticate an MCP server (OAuth flow).
3161
- */
3501
+ async listTools(params = {}) {
3502
+ this._ensureNotClosed();
3503
+ return this._client.listTools(params);
3504
+ }
3162
3505
  async authenticateMcpServer(params) {
3163
3506
  this._ensureNotClosed();
3164
3507
  return this._client.authenticateMcpServer(params);
3165
3508
  }
3166
- // ------------------------------------------------------------------
3167
- // Skills
3168
- // ------------------------------------------------------------------
3169
- /**
3170
- * List available skills.
3171
- */
3172
3509
  async listSkills() {
3173
3510
  this._ensureNotClosed();
3174
3511
  return this._client.listSkills();
3175
3512
  }
3176
- // ------------------------------------------------------------------
3177
- // Notification subscription
3178
- // ------------------------------------------------------------------
3179
- /**
3180
- * Register a callback for incoming notification messages.
3181
- *
3182
- * @param callback - Invoked with the notification object.
3183
- * @param filter - Optional filter to only receive specific notification types.
3184
- * @returns An unsubscribe function.
3185
- */
3513
+ async getRewindInfo(params) {
3514
+ this._ensureNotClosed();
3515
+ return this._client.getRewindInfo(params);
3516
+ }
3517
+ async executeRewind(params) {
3518
+ this._ensureNotClosed();
3519
+ return this._client.executeRewind(params);
3520
+ }
3521
+ async compactSession(params) {
3522
+ this._ensureNotClosed();
3523
+ return this._client.compactSession(params ?? {});
3524
+ }
3525
+ async forkSession() {
3526
+ this._ensureNotClosed();
3527
+ return this._client.forkSession();
3528
+ }
3529
+ async getContextStats() {
3530
+ this._ensureNotClosed();
3531
+ return this._client.getContextStats();
3532
+ }
3533
+ async renameSession(params) {
3534
+ this._ensureNotClosed();
3535
+ return this._client.renameSession(params);
3536
+ }
3186
3537
  onNotification(callback, filter) {
3187
3538
  return this._client.onNotification(callback, filter);
3188
3539
  }
3189
- // ------------------------------------------------------------------
3190
- // Internal
3191
- // ------------------------------------------------------------------
3192
3540
  _ensureNotClosed() {
3193
3541
  if (this._closed) {
3194
3542
  throw new ConnectionError(
@@ -3198,98 +3546,298 @@ var DroidSession = class {
3198
3546
  }
3199
3547
  };
3200
3548
  async function createSession(options = {}) {
3201
- let transport;
3202
- if (options.transport) {
3203
- transport = options.transport;
3204
- } else {
3205
- const transportOptions = {
3206
- execPath: options.execPath,
3207
- execArgs: options.execArgs,
3208
- cwd: options.cwd,
3209
- env: options.env
3549
+ const { client } = await createConfiguredClient(options);
3550
+ let cleanupInitAbortSignal = options.abortSignal?.aborted ? () => {
3551
+ } : wireAbortSignal(options.abortSignal, () => {
3552
+ void closeQuietly(client);
3553
+ });
3554
+ let sdkMcpServers;
3555
+ try {
3556
+ sdkMcpServers = await startSdkMcpServers(options.mcpServers);
3557
+ const initParams = buildInitParams({
3558
+ ...options,
3559
+ mcpServers: sdkMcpServers.mcpServers
3560
+ });
3561
+ const initResult = await client.initializeSession(initParams);
3562
+ const session = new DroidSession(client, initResult.sessionId, initResult);
3563
+ session.addCleanup(sdkMcpServers.cleanup);
3564
+ cleanupInitAbortSignal();
3565
+ cleanupInitAbortSignal = () => {
3210
3566
  };
3211
- const processTransport = new ProcessTransport(transportOptions);
3212
- await processTransport.connect();
3213
- transport = processTransport;
3214
- }
3215
- const client = new DroidClient({ transport });
3216
- if (options.permissionHandler) {
3217
- client.setPermissionHandler(options.permissionHandler);
3218
- }
3219
- if (options.askUserHandler) {
3220
- client.setAskUserHandler(options.askUserHandler);
3567
+ session.setAbortSignalCleanup(
3568
+ wireAbortSignal(options.abortSignal, () => void session.close())
3569
+ );
3570
+ return session;
3571
+ } catch (error) {
3572
+ cleanupInitAbortSignal();
3573
+ await sdkMcpServers?.cleanup();
3574
+ await closeQuietly(client);
3575
+ throw error;
3221
3576
  }
3222
- const initParams = {
3223
- machineId: options.machineId ?? "default",
3224
- cwd: options.cwd ?? "."
3225
- };
3226
- if (options.modelId !== void 0) {
3227
- initParams.modelId = options.modelId;
3577
+ }
3578
+ async function resumeSession(sessionId, options = {}) {
3579
+ const { client } = await createConfiguredClient(options);
3580
+ let sdkMcpServers;
3581
+ try {
3582
+ sdkMcpServers = await startSdkMcpServers(options.mcpServers);
3583
+ const loadParams = {
3584
+ sessionId,
3585
+ mcpServers: sdkMcpServers.mcpServers
3586
+ };
3587
+ const loadResult = await client.loadSession(loadParams);
3588
+ const session = new DroidSession(client, sessionId, loadResult);
3589
+ session.addCleanup(sdkMcpServers.cleanup);
3590
+ session.setAbortSignalCleanup(
3591
+ wireAbortSignal(options.abortSignal, () => void session.close())
3592
+ );
3593
+ return session;
3594
+ } catch (error) {
3595
+ await sdkMcpServers?.cleanup();
3596
+ await closeQuietly(client);
3597
+ throw error;
3228
3598
  }
3229
- if (options.autonomyLevel !== void 0) {
3230
- initParams.autonomyLevel = options.autonomyLevel;
3599
+ }
3600
+
3601
+ // src/run.ts
3602
+ async function run(prompt, options = {}) {
3603
+ const session = await createSession(options);
3604
+ try {
3605
+ for await (const msg of session.stream(prompt, {
3606
+ ...options,
3607
+ includePartialMessages: false
3608
+ })) {
3609
+ if (msg.type === DroidMessageType.Result) {
3610
+ return msg;
3611
+ }
3612
+ }
3613
+ throw new Error("Stream completed without a result message");
3614
+ } finally {
3615
+ await session.close();
3231
3616
  }
3232
- if (options.interactionMode !== void 0) {
3233
- initParams.interactionMode = options.interactionMode;
3617
+ }
3618
+
3619
+ // src/session-discovery.ts
3620
+ import * as fs from "fs";
3621
+ import * as os from "os";
3622
+ import * as path from "path";
3623
+ var FAVORITES_FILE = ".favorites";
3624
+ var SESSION_EXTENSION = ".jsonl";
3625
+ var SETTINGS_SUFFIX = ".settings.json";
3626
+ var MISSION_TAG_PREFIX = "mission:";
3627
+ var MISSION_ID_METADATA_KEY = "missionId";
3628
+ var DECOMP_SESSION_TYPE_TAG = "decompSessionType";
3629
+ var DECOMP_SESSION_TYPE_METADATA_KEY = "value";
3630
+ var LF = 10;
3631
+ var CR = 13;
3632
+ var SPACE = 32;
3633
+ var TAB = 9;
3634
+ var PARSE_OVERSAMPLE = 20;
3635
+ function readFileBuffer(filePath) {
3636
+ try {
3637
+ return fs.readFileSync(filePath);
3638
+ } catch {
3639
+ return null;
3234
3640
  }
3235
- if (options.reasoningEffort !== void 0) {
3236
- initParams.reasoningEffort = options.reasoningEffort;
3641
+ }
3642
+ function parseJsonBuffer(buf) {
3643
+ try {
3644
+ return JSON.parse(buf.toString("utf-8"));
3645
+ } catch {
3646
+ return null;
3237
3647
  }
3238
- if (options.mcpServers !== void 0) {
3239
- initParams.mcpServers = options.mcpServers;
3648
+ }
3649
+ function scanBufferForLines(buf) {
3650
+ let nonEmptyLineCount = 0;
3651
+ let firstLineEnd = -1;
3652
+ let currentLineHasContent = false;
3653
+ for (let i = 0; i < buf.length; i++) {
3654
+ const ch = buf[i];
3655
+ if (ch === LF) {
3656
+ if (currentLineHasContent) nonEmptyLineCount++;
3657
+ if (firstLineEnd === -1) firstLineEnd = i;
3658
+ currentLineHasContent = false;
3659
+ } else if (ch !== CR && ch !== SPACE && ch !== TAB) {
3660
+ currentLineHasContent = true;
3661
+ }
3240
3662
  }
3241
- if (options.enabledToolIds !== void 0) {
3242
- initParams.enabledToolIds = options.enabledToolIds;
3663
+ if (currentLineHasContent) nonEmptyLineCount++;
3664
+ const end = firstLineEnd === -1 ? buf.length : firstLineEnd > 0 && buf[firstLineEnd - 1] === CR ? firstLineEnd - 1 : firstLineEnd;
3665
+ return {
3666
+ firstLine: buf.subarray(0, end),
3667
+ nonEmptyLineCount
3668
+ };
3669
+ }
3670
+ function loadFavorites(sessionsDir) {
3671
+ const buf = readFileBuffer(path.join(sessionsDir, FAVORITES_FILE));
3672
+ if (!buf) return /* @__PURE__ */ new Set();
3673
+ const parsed = parseJsonBuffer(buf);
3674
+ if (!Array.isArray(parsed)) return /* @__PURE__ */ new Set();
3675
+ return new Set(parsed.filter((id) => typeof id === "string"));
3676
+ }
3677
+ function loadSettingsFile(directory, sessionId) {
3678
+ const buf = readFileBuffer(
3679
+ path.join(directory, `${sessionId}${SETTINGS_SUFFIX}`)
3680
+ );
3681
+ if (!buf) return null;
3682
+ const parsed = parseJsonBuffer(buf);
3683
+ if (parsed === null) return null;
3684
+ const result = SessionSettingsFileSchema.safeParse(parsed);
3685
+ return result.success ? result.data : null;
3686
+ }
3687
+ function getMissionMetadataFromTags(settings) {
3688
+ if (!settings?.tags) return {};
3689
+ const missionTag = settings.tags.find(
3690
+ (tag) => tag.name.startsWith(MISSION_TAG_PREFIX)
3691
+ );
3692
+ const roleTag = settings.tags.find(
3693
+ (tag) => tag.name === DECOMP_SESSION_TYPE_TAG
3694
+ );
3695
+ return {
3696
+ decompMissionId: missionTag?.metadata?.[MISSION_ID_METADATA_KEY],
3697
+ decompSessionType: roleTag?.metadata?.[DECOMP_SESSION_TYPE_METADATA_KEY]
3698
+ };
3699
+ }
3700
+ function parseSessionFile(candidate, ctx) {
3701
+ const buf = readFileBuffer(candidate.sessionPath);
3702
+ if (!buf) return null;
3703
+ const scanned = scanBufferForLines(buf);
3704
+ const firstParsed = parseJsonBuffer(scanned.firstLine);
3705
+ if (firstParsed === null) return null;
3706
+ const firstResult = SessionStartEventSchema.safeParse(firstParsed);
3707
+ if (!firstResult.success) return null;
3708
+ const summary = firstResult.data;
3709
+ if (ctx.requiredCwd !== void 0 && (summary.cwd === void 0 || path.resolve(summary.cwd) !== ctx.requiredCwd)) {
3710
+ return null;
3243
3711
  }
3712
+ const settingsName = `${candidate.sessionId}${SETTINGS_SUFFIX}`;
3713
+ const settings = candidate.siblingNames.has(settingsName) ? loadSettingsFile(candidate.directory, candidate.sessionId) : null;
3714
+ if (settings?.archivedAt) return null;
3715
+ const tagMeta = getMissionMetadataFromTags(settings);
3716
+ const decompSessionType = summary.decompSessionType ?? SessionStartEventSchema.shape.decompSessionType.safeParse(
3717
+ tagMeta.decompSessionType
3718
+ ).data;
3719
+ const messageCount = Math.max(0, scanned.nonEmptyLineCount - 1);
3720
+ return {
3721
+ id: candidate.sessionId,
3722
+ title: summary.title ?? "",
3723
+ sessionTitle: summary.sessionTitle,
3724
+ owner: summary.owner ?? "",
3725
+ messageCount,
3726
+ modifiedTime: candidate.stats.mtime,
3727
+ createdTime: candidate.stats.birthtime || candidate.stats.ctime,
3728
+ isFavorite: ctx.favorites.has(candidate.sessionId),
3729
+ cwd: summary.cwd,
3730
+ decompSessionType,
3731
+ decompMissionId: tagMeta.decompMissionId ?? summary.decompMissionId
3732
+ };
3733
+ }
3734
+ function readDirEntries(directory) {
3244
3735
  try {
3245
- const initResult = await client.initializeSession(
3246
- initParams
3247
- );
3248
- return new DroidSession(client, initResult.sessionId, initResult);
3249
- } catch (error) {
3736
+ return fs.readdirSync(directory, { withFileTypes: true });
3737
+ } catch {
3738
+ return [];
3739
+ }
3740
+ }
3741
+ function collectCandidates(directory, entries) {
3742
+ const siblingNames = new Set(entries.map((e) => e.name));
3743
+ const candidates = [];
3744
+ for (const entry of entries) {
3745
+ if (entry.isDirectory()) continue;
3746
+ if (!entry.name.endsWith(SESSION_EXTENSION)) continue;
3747
+ const sessionPath = path.join(directory, entry.name);
3748
+ let stats;
3250
3749
  try {
3251
- await client.close();
3750
+ stats = fs.statSync(sessionPath);
3252
3751
  } catch {
3752
+ continue;
3253
3753
  }
3254
- throw error;
3754
+ candidates.push({
3755
+ sessionId: entry.name.slice(0, -SESSION_EXTENSION.length),
3756
+ sessionPath,
3757
+ directory,
3758
+ siblingNames,
3759
+ stats
3760
+ });
3255
3761
  }
3762
+ return candidates;
3256
3763
  }
3257
- async function resumeSession(sessionId, options = {}) {
3258
- let transport;
3259
- if (options.transport) {
3260
- transport = options.transport;
3261
- } else {
3262
- const transportOptions = {
3263
- execPath: options.execPath,
3264
- execArgs: options.execArgs,
3265
- cwd: options.cwd,
3266
- env: options.env
3267
- };
3268
- const processTransport = new ProcessTransport(transportOptions);
3269
- await processTransport.connect();
3270
- transport = processTransport;
3271
- }
3272
- const client = new DroidClient({ transport });
3273
- if (options.permissionHandler) {
3274
- client.setPermissionHandler(options.permissionHandler);
3764
+ function parseUpTo(candidates, ctx, limit) {
3765
+ const out = [];
3766
+ for (const candidate of candidates) {
3767
+ if (limit !== void 0 && out.length >= limit) break;
3768
+ const metadata = parseSessionFile(candidate, ctx);
3769
+ if (metadata) out.push(metadata);
3275
3770
  }
3276
- if (options.askUserHandler) {
3277
- client.setAskUserHandler(options.askUserHandler);
3771
+ return out;
3772
+ }
3773
+ function sanitizePathToDirectoryName(cwd) {
3774
+ let expandedPath = cwd;
3775
+ if (cwd.startsWith("~/") || cwd === "~") {
3776
+ expandedPath = path.join(os.homedir(), cwd.slice(1));
3278
3777
  }
3279
- const loadParams = {
3280
- sessionId,
3281
- mcpServers: options.mcpServers
3282
- };
3778
+ const absolutePath = path.resolve(expandedPath);
3779
+ let canonicalPath = absolutePath;
3283
3780
  try {
3284
- const loadResult = await client.loadSession(loadParams);
3285
- return new DroidSession(client, sessionId, loadResult);
3286
- } catch (error) {
3287
- try {
3288
- await client.close();
3289
- } catch {
3781
+ canonicalPath = fs.realpathSync(absolutePath);
3782
+ } catch {
3783
+ canonicalPath = absolutePath;
3784
+ }
3785
+ const normalized = canonicalPath.replace(/[\\/]+$/, "");
3786
+ if (process.platform === "win32") {
3787
+ return `-${normalized.replace(/^([A-Z]):/i, "$1").replace(/[\\/]+/g, "-")}`;
3788
+ }
3789
+ return `-${normalized.replace(/^\/+/, "").replace(/\/+/g, "-")}`;
3790
+ }
3791
+ function getDefaultSessionsDir() {
3792
+ return path.join(os.homedir(), ".factory", "sessions");
3793
+ }
3794
+ async function listSessions(options = {}) {
3795
+ const sessionsDir = options.sessionsDir ?? getDefaultSessionsDir();
3796
+ const favorites = loadFavorites(sessionsDir);
3797
+ const rootEntries = readDirEntries(sessionsDir);
3798
+ const legacyCandidates = collectCandidates(sessionsDir, rootEntries);
3799
+ const projectCandidates = [];
3800
+ let requiredCwd;
3801
+ if (options.fetchOutsideCWD) {
3802
+ for (const entry of rootEntries) {
3803
+ if (!entry.isDirectory()) continue;
3804
+ if (!entry.name.startsWith("-")) continue;
3805
+ const dir = path.join(sessionsDir, entry.name);
3806
+ projectCandidates.push(...collectCandidates(dir, readDirEntries(dir)));
3290
3807
  }
3291
- throw error;
3808
+ } else {
3809
+ const normalizedCwd = path.resolve(options.cwd ?? process.cwd());
3810
+ requiredCwd = normalizedCwd;
3811
+ const projectDir = path.join(
3812
+ sessionsDir,
3813
+ sanitizePathToDirectoryName(normalizedCwd)
3814
+ );
3815
+ projectCandidates.push(
3816
+ ...collectCandidates(projectDir, readDirEntries(projectDir))
3817
+ );
3818
+ }
3819
+ const byMtimeDesc = (a, b) => b.stats.mtime.getTime() - a.stats.mtime.getTime();
3820
+ projectCandidates.sort(byMtimeDesc);
3821
+ legacyCandidates.sort(byMtimeDesc);
3822
+ const parseLimit = options.numSessions !== void 0 && options.numSessions >= 0 ? options.numSessions + PARSE_OVERSAMPLE : void 0;
3823
+ const ctx = { favorites };
3824
+ const legacyCtx = requiredCwd !== void 0 ? { favorites, requiredCwd } : ctx;
3825
+ const projectSessions = parseUpTo(projectCandidates, ctx, parseLimit);
3826
+ const legacySessions = parseUpTo(legacyCandidates, legacyCtx, parseLimit);
3827
+ const byId = /* @__PURE__ */ new Map();
3828
+ for (const session of [...projectSessions, ...legacySessions]) {
3829
+ const existing = byId.get(session.id);
3830
+ if (!existing || session.modifiedTime.getTime() > existing.modifiedTime.getTime()) {
3831
+ byId.set(session.id, session);
3832
+ }
3833
+ }
3834
+ const sorted = Array.from(byId.values()).sort(
3835
+ (a, b) => b.modifiedTime.getTime() - a.modifiedTime.getTime()
3836
+ );
3837
+ if (options.numSessions !== void 0 && options.numSessions >= 0) {
3838
+ return sorted.slice(0, options.numSessions);
3292
3839
  }
3840
+ return sorted;
3293
3841
  }
3294
3842
  export {
3295
3843
  AddMcpServerRequestParamsSchema,
@@ -3308,6 +3856,7 @@ export {
3308
3856
  AskUserRequestSchema,
3309
3857
  AskUserResponseSchema,
3310
3858
  AskUserResultSchema,
3859
+ AssistantTextCompleteNotificationSchema,
3311
3860
  AssistantTextDeltaNotificationSchema,
3312
3861
  AuthenticateMcpServerRequestParamsSchema,
3313
3862
  AuthenticateMcpServerRequestSchema,
@@ -3321,6 +3870,7 @@ export {
3321
3870
  BaseRequestSchema,
3322
3871
  BaseResponseFailureSchema,
3323
3872
  BaseResponseSuccessSchema,
3873
+ COMPACTION_TIMEOUT,
3324
3874
  CancelMcpAuthRequestParamsSchema,
3325
3875
  CancelMcpAuthRequestSchema,
3326
3876
  CancelMcpAuthResponseSchema,
@@ -3331,8 +3881,18 @@ export {
3331
3881
  ClearMcpAuthResultSchema,
3332
3882
  CliRequestOrNotificationSchema,
3333
3883
  ClientRequestSchema,
3884
+ CloseSessionRequestParamsSchema,
3885
+ CloseSessionRequestSchema,
3886
+ CloseSessionResponseSchema,
3887
+ CloseSessionResultSchema,
3888
+ CompactSessionRequestParamsSchema,
3889
+ CompactSessionRequestSchema,
3890
+ CompactSessionResponseSchema,
3891
+ CompactSessionResultSchema,
3334
3892
  ConnectionError,
3335
3893
  ContentBlockSchema,
3894
+ ContextStatsAccuracy,
3895
+ ContextStatsSchema,
3336
3896
  CreateMessageNotificationSchema,
3337
3897
  CreateToolConfirmationDetailsSchema,
3338
3898
  DEFAULT_REQUEST_TIMEOUT,
@@ -3345,26 +3905,54 @@ export {
3345
3905
  DroidClient,
3346
3906
  DroidClientMethod,
3347
3907
  DroidErrorType,
3908
+ DroidHookEventSchema,
3909
+ DroidHookExecutionResultSchema,
3910
+ DroidHookOutputSchema,
3911
+ DroidHookSpecificOutputSchema,
3348
3912
  DroidInteractionMode,
3913
+ DroidMessageType,
3349
3914
  DroidServerMethod,
3350
3915
  DroidSession,
3351
3916
  DroidWorkingState,
3352
3917
  DroidWorkingStateChangedNotificationSchema,
3353
3918
  EditToolConfirmationDetailsSchema,
3919
+ EmptyResultSchema,
3354
3920
  ErrorDetailSchema,
3355
3921
  ErrorNotificationSchema,
3922
+ ExecToolInfoSchema,
3923
+ ExecuteRewindRequestParamsSchema,
3924
+ ExecuteRewindRequestSchema,
3925
+ ExecuteRewindResponseSchema,
3926
+ ExecuteRewindResultSchema,
3356
3927
  ExecuteToolConfirmationDetailsSchema,
3357
3928
  ExitSpecModeConfirmationDetailsSchema,
3358
3929
  FACTORY_CLIENT_HEADER,
3359
3930
  FACTORY_CLIENT_VERSION,
3360
3931
  FACTORY_PROTOCOL_VERSION,
3932
+ FactoryDroidMessageRole,
3361
3933
  FactoryDroidMessageSchema,
3362
3934
  FeatureStatus,
3363
3935
  FeatureSuccessState,
3364
3936
  FeatureSuccessStateSchema,
3937
+ ForkSessionRequestParamsSchema,
3938
+ ForkSessionRequestSchema,
3939
+ ForkSessionResponseSchema,
3940
+ ForkSessionResultSchema,
3941
+ GetContextStatsRequestParamsSchema,
3942
+ GetContextStatsRequestSchema,
3943
+ GetContextStatsResponseSchema,
3944
+ GetContextStatsResultSchema,
3945
+ GetRewindInfoRequestParamsSchema,
3946
+ GetRewindInfoRequestSchema,
3947
+ GetRewindInfoResponseSchema,
3948
+ GetRewindInfoResultSchema,
3365
3949
  GitRepoInfoSchema,
3366
3950
  HandoffItemsDismissedEntrySchema,
3367
3951
  HandoffSchema,
3952
+ HookCommandSchema,
3953
+ HookExecutionCompletedNotificationSchema,
3954
+ HookExecutionStartedNotificationSchema,
3955
+ HookResultSchema,
3368
3956
  HttpHeaderSchema,
3369
3957
  HttpMcpConfigSchema,
3370
3958
  ImageBlockSchema,
@@ -3379,6 +3967,8 @@ export {
3379
3967
  InterruptSessionResultSchema,
3380
3968
  IssueSeverity,
3381
3969
  JSONRPC_VERSION,
3970
+ JsonArraySchema,
3971
+ JsonObjectSchema,
3382
3972
  JsonRpcEnvelopeSchema,
3383
3973
  JsonRpcErrorCode,
3384
3974
  JsonRpcErrorSchema,
@@ -3389,6 +3979,7 @@ export {
3389
3979
  JsonRpcResponseFailureSchema,
3390
3980
  JsonRpcResponseSchema,
3391
3981
  JsonRpcResponseSuccessSchema,
3982
+ JsonValueSchema,
3392
3983
  KillWorkerSessionRequestParamsSchema,
3393
3984
  KillWorkerSessionRequestSchema,
3394
3985
  KillWorkerSessionResponseSchema,
@@ -3410,6 +4001,10 @@ export {
3410
4001
  ListSkillsRequestSchema,
3411
4002
  ListSkillsResponseSchema,
3412
4003
  ListSkillsResultSchema,
4004
+ ListToolsRequestParamsSchema,
4005
+ ListToolsRequestSchema,
4006
+ ListToolsResponseSchema,
4007
+ ListToolsResultSchema,
3413
4008
  LoadSessionRequestParamsSchema,
3414
4009
  LoadSessionRequestSchema,
3415
4010
  LoadSessionResponseSchema,
@@ -3447,6 +4042,8 @@ export {
3447
4042
  MissionWorkerCompletedNotificationSchema,
3448
4043
  MissionWorkerStartedNotificationSchema,
3449
4044
  ModelProvider,
4045
+ OutputFormatSchema,
4046
+ OutputFormatType,
3450
4047
  PermissionResolvedNotificationSchema,
3451
4048
  ProcessExitError,
3452
4049
  ProcessTransport,
@@ -3455,26 +4052,40 @@ export {
3455
4052
  ProposeMissionConfirmationDetailsSchema,
3456
4053
  ProtocolEngine,
3457
4054
  ProtocolError,
4055
+ REWIND_TIMEOUT,
3458
4056
  ReasoningEffort,
3459
4057
  RedactedThinkingBlockSchema,
3460
4058
  RemoveMcpServerRequestParamsSchema,
3461
4059
  RemoveMcpServerRequestSchema,
3462
4060
  RemoveMcpServerResponseSchema,
3463
4061
  RemoveMcpServerResultSchema,
4062
+ RenameSessionRequestParamsSchema,
4063
+ RenameSessionRequestSchema,
4064
+ RenameSessionResponseSchema,
4065
+ RenameSessionResultSchema,
3464
4066
  RequestPermissionRequestParamsSchema,
3465
4067
  RequestPermissionRequestSchema,
3466
4068
  RequestPermissionResponseSchema,
3467
4069
  RequestPermissionResultSchema,
4070
+ RewindEvictedFileSchema,
4071
+ RewindFileCreationSchema,
4072
+ RewindFileSnapshotSchema,
4073
+ SDK_TAG,
4074
+ SDK_VERSION,
3468
4075
  SESSION_INIT_TIMEOUT,
4076
+ SdkMcpServer,
3469
4077
  SessionError,
4078
+ SessionMetadataSchema,
3470
4079
  SessionNotFoundError,
3471
4080
  SessionNotificationParamsSchema,
3472
4081
  SessionNotificationPayloadSchema,
3473
4082
  SessionNotificationSchema,
3474
4083
  SessionNotificationSchemaList,
3475
4084
  SessionNotificationType,
4085
+ SessionSettingsFileSchema,
3476
4086
  SessionSettingsSchema,
3477
4087
  SessionSourceSchema,
4088
+ SessionStartEventSchema,
3478
4089
  SessionTagSchema,
3479
4090
  SessionTitleUpdatedNotificationSchema,
3480
4091
  SessionTokenUsageChangedNotificationSchema,
@@ -3490,6 +4101,8 @@ export {
3490
4101
  StartMissionRunConfirmationDetailsSchema,
3491
4102
  StdioMcpConfigSchema,
3492
4103
  StreamStateTracker,
4104
+ StructuredOutputErrorSchema,
4105
+ StructuredOutputNotificationSchema,
3493
4106
  SubmitBugReportRequestParamsSchema,
3494
4107
  SubmitBugReportRequestSchema,
3495
4108
  SubmitBugReportResponseSchema,
@@ -3498,11 +4111,13 @@ export {
3498
4111
  SubmitMcpAuthCodeRequestSchema,
3499
4112
  SubmitMcpAuthCodeResponseSchema,
3500
4113
  SubmitMcpAuthCodeResultSchema,
4114
+ SuccessResultSchema,
3501
4115
  TestCaseSchema,
3502
4116
  TestFileSchema,
3503
4117
  TestsSchema,
3504
4118
  TextBlockSchema,
3505
4119
  ThinkingBlockSchema,
4120
+ ThinkingTextCompleteNotificationSchema,
3506
4121
  ThinkingTextDeltaNotificationSchema,
3507
4122
  TimeoutError,
3508
4123
  ToggleMcpServerRequestParamsSchema,
@@ -3514,6 +4129,7 @@ export {
3514
4129
  ToggleMcpToolResponseSchema,
3515
4130
  ToggleMcpToolResultSchema,
3516
4131
  TokenUsageSchema,
4132
+ ToolCallNotificationSchema,
3517
4133
  ToolConfirmationDetailsSchema,
3518
4134
  ToolConfirmationInfoSchema,
3519
4135
  ToolConfirmationListItemSchema,
@@ -3523,6 +4139,7 @@ export {
3523
4139
  ToolProgressUpdateSchema,
3524
4140
  ToolResultBlockSchema,
3525
4141
  ToolResultNotificationSchema,
4142
+ ToolSelectionOverridesSchema,
3526
4143
  ToolUseBlockSchema,
3527
4144
  ToolUseSchema,
3528
4145
  TraceContextMetaSchema,
@@ -3539,8 +4156,13 @@ export {
3539
4156
  WorkerStartedEntrySchema,
3540
4157
  WorkerStateInfoSchema,
3541
4158
  convertNotificationToStreamMessage,
4159
+ createResponseSchema,
4160
+ createSdkMcpServer,
3542
4161
  createSession,
3543
- query,
3544
- resumeSession
4162
+ dispatchNotification,
4163
+ listSessions,
4164
+ resumeSession,
4165
+ run,
4166
+ tool
3545
4167
  };
3546
4168
  //# sourceMappingURL=index.js.map