@factory/droid-sdk 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +214 -82
  2. package/dist/index.cjs +2345 -692
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +2570 -232
  5. package/dist/index.d.ts +2570 -232
  6. package/dist/index.js +2298 -697
  7. package/dist/index.js.map +1 -1
  8. package/docs/daemon-usage-guide.md +544 -0
  9. package/docs/sdk-usage-guide.md +748 -0
  10. package/examples/abort-session-stream.ts +23 -56
  11. package/examples/daemon-multi-session.ts +67 -0
  12. package/examples/droid-dev-structured-output.ts +5 -5
  13. package/examples/fork-session.ts +33 -7
  14. package/examples/hook-execution.ts +68 -0
  15. package/examples/init-metadata.ts +14 -66
  16. package/examples/interrupt-session.ts +23 -55
  17. package/examples/list-sessions.ts +9 -55
  18. package/examples/multi-turn-session.ts +27 -54
  19. package/examples/permission-handler.ts +27 -84
  20. package/examples/readme-structured-output.ts +26 -0
  21. package/examples/result-metadata.ts +2 -1
  22. package/examples/run.ts +2 -1
  23. package/examples/sdk-mcp-tool.ts +14 -8
  24. package/examples/session-stream.ts +57 -0
  25. package/examples/spec-mode-new-session.ts +39 -99
  26. package/examples/spec-mode-same-session.ts +50 -111
  27. package/examples/structured-output.ts +17 -10
  28. package/examples/test-compact.ts +9 -4
  29. package/examples/test-rewind.ts +49 -117
  30. package/examples/tool-controls.ts +23 -55
  31. package/package.json +3 -1
  32. package/docs/examples/init-metadata.md +0 -79
  33. package/docs/examples/list-sessions.md +0 -64
  34. package/docs/examples/multi-turn-session.md +0 -77
  35. package/docs/examples/one-shot-query.md +0 -73
  36. package/docs/examples/permission-handler.md +0 -102
  37. package/docs/examples/run.md +0 -52
  38. package/docs/examples/spec-mode.md +0 -101
  39. package/docs/examples/tool-controls.md +0 -90
  40. package/docs/typescript-sdk-reference.md +0 -372
  41. package/examples/simple-query.ts +0 -53
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";
@@ -45,7 +46,10 @@ var SessionNotificationType = /* @__PURE__ */ ((SessionNotificationType2) => {
45
46
  SessionNotificationType2["SESSION_TITLE_UPDATED"] = "session_title_updated";
46
47
  SessionNotificationType2["MCP_STATUS_CHANGED"] = "mcp_status_changed";
47
48
  SessionNotificationType2["ASSISTANT_TEXT_DELTA"] = "assistant_text_delta";
49
+ SessionNotificationType2["ASSISTANT_TEXT_COMPLETE"] = "assistant_text_complete";
48
50
  SessionNotificationType2["THINKING_TEXT_DELTA"] = "thinking_text_delta";
51
+ SessionNotificationType2["THINKING_TEXT_COMPLETE"] = "thinking_text_complete";
52
+ SessionNotificationType2["TOOL_CALL"] = "tool_call";
49
53
  SessionNotificationType2["SESSION_TOKEN_USAGE_CHANGED"] = "session_token_usage_changed";
50
54
  SessionNotificationType2["MISSION_STATE_CHANGED"] = "mission_state_changed";
51
55
  SessionNotificationType2["MISSION_FEATURES_CHANGED"] = "mission_features_changed";
@@ -55,6 +59,9 @@ var SessionNotificationType = /* @__PURE__ */ ((SessionNotificationType2) => {
55
59
  SessionNotificationType2["MISSION_WORKER_COMPLETED"] = "mission_worker_completed";
56
60
  SessionNotificationType2["MCP_AUTH_REQUIRED"] = "mcp_auth_required";
57
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";
58
65
  return SessionNotificationType2;
59
66
  })(SessionNotificationType || {});
60
67
  var ToolConfirmationOutcome = /* @__PURE__ */ ((ToolConfirmationOutcome3) => {
@@ -248,6 +255,11 @@ var JsonRpcMessageType = /* @__PURE__ */ ((JsonRpcMessageType2) => {
248
255
  JsonRpcMessageType2["Notification"] = "notification";
249
256
  return JsonRpcMessageType2;
250
257
  })(JsonRpcMessageType || {});
258
+ var ServerRequestHandlerType = /* @__PURE__ */ ((ServerRequestHandlerType2) => {
259
+ ServerRequestHandlerType2["Permission"] = "permission";
260
+ ServerRequestHandlerType2["AskUser"] = "askUser";
261
+ return ServerRequestHandlerType2;
262
+ })(ServerRequestHandlerType || {});
251
263
  var SettingsLevel = /* @__PURE__ */ ((SettingsLevel2) => {
252
264
  SettingsLevel2["Org"] = "org";
253
265
  SettingsLevel2["Runtime"] = "runtime";
@@ -268,7 +280,7 @@ var SkillLocation = /* @__PURE__ */ ((SkillLocation2) => {
268
280
  // src/schemas/constants.ts
269
281
  var JSONRPC_VERSION = "2.0";
270
282
  var LEGACY_FACTORY_API_VERSION = "1.0.0";
271
- var FACTORY_PROTOCOL_VERSION = "1.3.0";
283
+ var FACTORY_PROTOCOL_VERSION = "1.51.0";
272
284
  var FACTORY_CLIENT_HEADER = "X-Factory-Client";
273
285
  var FACTORY_CLIENT_VERSION = "X-Client-Version";
274
286
  var DEFAULT_REQUEST_TIMEOUT = 3e4;
@@ -359,6 +371,12 @@ var JsonRpcMessageSchema = z.discriminatedUnion("type", [
359
371
  }),
360
372
  JsonRpcNotificationSchema
361
373
  ]);
374
+ function createResponseSchema(resultSchema) {
375
+ return z.union([
376
+ JsonRpcResponseSuccessSchema.extend({ result: resultSchema }),
377
+ JsonRpcResponseFailureSchema
378
+ ]);
379
+ }
362
380
 
363
381
  // src/schemas/session-metadata.ts
364
382
  import { z as z6 } from "zod";
@@ -806,6 +824,9 @@ var AddUserMessageRequestParamsSchema = z5.object({
806
824
  outputFormat: OutputFormatSchema.optional()
807
825
  }).strict();
808
826
  var InterruptSessionRequestParamsSchema = z5.object({}).strict();
827
+ var CloseSessionRequestParamsSchema = z5.object({
828
+ reason: z5.enum(["clear", "logout", "prompt_input_exit", "other"]).optional()
829
+ }).strict();
809
830
  var KillWorkerSessionRequestParamsSchema = z5.object({
810
831
  workerSessionId: z5.string()
811
832
  }).strict();
@@ -922,6 +943,10 @@ var InterruptSessionRequestSchema = JsonRpcRequestSchema.extend({
922
943
  method: z5.literal("droid.interrupt_session" /* INTERRUPT_SESSION */),
923
944
  params: InterruptSessionRequestParamsSchema
924
945
  });
946
+ var CloseSessionRequestSchema = JsonRpcRequestSchema.extend({
947
+ method: z5.literal("droid.close_session" /* CLOSE_SESSION */),
948
+ params: CloseSessionRequestParamsSchema
949
+ });
925
950
  var KillWorkerSessionRequestSchema = JsonRpcRequestSchema.extend({
926
951
  method: z5.literal("droid.kill_worker_session" /* KILL_WORKER_SESSION */),
927
952
  params: KillWorkerSessionRequestParamsSchema
@@ -1014,6 +1039,7 @@ var ClientRequestSchema = z5.discriminatedUnion("method", [
1014
1039
  InitializeSessionRequestSchema,
1015
1040
  LoadSessionRequestSchema,
1016
1041
  AddUserMessageRequestSchema,
1042
+ CloseSessionRequestSchema,
1017
1043
  InterruptSessionRequestSchema,
1018
1044
  KillWorkerSessionRequestSchema,
1019
1045
  UpdateSessionSettingsRequestSchema,
@@ -1074,6 +1100,7 @@ var LoadSessionResultSchema = z5.object({
1074
1100
  }).passthrough();
1075
1101
  var AddUserMessageResultSchema = EmptyResultSchema;
1076
1102
  var InterruptSessionResultSchema = EmptyResultSchema;
1103
+ var CloseSessionResultSchema = EmptyResultSchema;
1077
1104
  var KillWorkerSessionResultSchema = EmptyResultSchema;
1078
1105
  var UpdateSessionSettingsResultSchema = EmptyResultSchema;
1079
1106
  var ToggleMcpServerResultSchema = SuccessResultSchema;
@@ -1113,128 +1140,102 @@ var ForkSessionResultSchema = z5.object({
1113
1140
  newSessionId: z5.string()
1114
1141
  }).passthrough();
1115
1142
  var GetContextStatsResultSchema = ContextStatsSchema;
1143
+ var ContextBreakdownCategorySchema = z5.object({
1144
+ name: z5.string(),
1145
+ tokens: z5.number(),
1146
+ colorKey: z5.string()
1147
+ }).passthrough();
1148
+ var ContextBreakdownResultSchema = z5.object({
1149
+ modelId: z5.string(),
1150
+ modelDisplayName: z5.string(),
1151
+ contextBudget: z5.number(),
1152
+ usedTokens: z5.number(),
1153
+ freeTokens: z5.number(),
1154
+ categories: z5.array(ContextBreakdownCategorySchema)
1155
+ }).passthrough();
1116
1156
  var RenameSessionResultSchema = SuccessResultSchema;
1117
- var InitializeSessionResponseSchema = z5.union([
1118
- JsonRpcResponseSuccessSchema.extend({
1119
- result: InitializeSessionResultSchema
1120
- }),
1121
- JsonRpcResponseFailureSchema
1122
- ]);
1123
- var _LoadSessionResponseSchema = z5.union([
1124
- JsonRpcResponseSuccessSchema.extend({ result: LoadSessionResultSchema }),
1125
- JsonRpcResponseFailureSchema
1126
- ]);
1157
+ var InitializeSessionResponseSchema = createResponseSchema(
1158
+ InitializeSessionResultSchema
1159
+ );
1160
+ var _LoadSessionResponseSchema = createResponseSchema(
1161
+ LoadSessionResultSchema
1162
+ );
1127
1163
  var LoadSessionResponseSchema = _LoadSessionResponseSchema;
1128
- var AddUserMessageResponseSchema = z5.union([
1129
- JsonRpcResponseSuccessSchema.extend({ result: AddUserMessageResultSchema }),
1130
- JsonRpcResponseFailureSchema
1131
- ]);
1132
- var InterruptSessionResponseSchema = z5.union([
1133
- JsonRpcResponseSuccessSchema.extend({
1134
- result: InterruptSessionResultSchema
1135
- }),
1136
- JsonRpcResponseFailureSchema
1137
- ]);
1138
- var KillWorkerSessionResponseSchema = z5.union([
1139
- JsonRpcResponseSuccessSchema.extend({
1140
- result: KillWorkerSessionResultSchema
1141
- }),
1142
- JsonRpcResponseFailureSchema
1143
- ]);
1144
- var UpdateSessionSettingsResponseSchema = z5.union([
1145
- JsonRpcResponseSuccessSchema.extend({
1146
- result: UpdateSessionSettingsResultSchema
1147
- }),
1148
- JsonRpcResponseFailureSchema
1149
- ]);
1150
- var ToggleMcpServerResponseSchema = z5.union([
1151
- JsonRpcResponseSuccessSchema.extend({
1152
- result: ToggleMcpServerResultSchema
1153
- }),
1154
- JsonRpcResponseFailureSchema
1155
- ]);
1156
- var AuthenticateMcpServerResponseSchema = z5.union([
1157
- JsonRpcResponseSuccessSchema.extend({
1158
- result: AuthenticateMcpServerResultSchema
1159
- }),
1160
- JsonRpcResponseFailureSchema
1161
- ]);
1162
- var CancelMcpAuthResponseSchema = z5.union([
1163
- JsonRpcResponseSuccessSchema.extend({ result: CancelMcpAuthResultSchema }),
1164
- JsonRpcResponseFailureSchema
1165
- ]);
1166
- var ClearMcpAuthResponseSchema = z5.union([
1167
- JsonRpcResponseSuccessSchema.extend({ result: ClearMcpAuthResultSchema }),
1168
- JsonRpcResponseFailureSchema
1169
- ]);
1170
- var SubmitMcpAuthCodeResponseSchema = z5.union([
1171
- JsonRpcResponseSuccessSchema.extend({
1172
- result: SubmitMcpAuthCodeResultSchema
1173
- }),
1174
- JsonRpcResponseFailureSchema
1175
- ]);
1176
- var AddMcpServerResponseSchema = z5.union([
1177
- JsonRpcResponseSuccessSchema.extend({ result: AddMcpServerResultSchema }),
1178
- JsonRpcResponseFailureSchema
1179
- ]);
1180
- var RemoveMcpServerResponseSchema = z5.union([
1181
- JsonRpcResponseSuccessSchema.extend({ result: RemoveMcpServerResultSchema }),
1182
- JsonRpcResponseFailureSchema
1183
- ]);
1184
- var ListMcpRegistryResponseSchema = z5.union([
1185
- JsonRpcResponseSuccessSchema.extend({
1186
- result: ListMcpRegistryResultSchema
1187
- }),
1188
- JsonRpcResponseFailureSchema
1189
- ]);
1190
- var ListMcpToolsResponseSchema = z5.union([
1191
- JsonRpcResponseSuccessSchema.extend({ result: ListMcpToolsResultSchema }),
1192
- JsonRpcResponseFailureSchema
1193
- ]);
1194
- var ListToolsResponseSchema = z5.union([
1195
- JsonRpcResponseSuccessSchema.extend({ result: ListToolsResultSchema }),
1196
- JsonRpcResponseFailureSchema
1197
- ]);
1198
- var ListMcpServersResponseSchema = z5.union([
1199
- JsonRpcResponseSuccessSchema.extend({ result: ListMcpServersResultSchema }),
1200
- JsonRpcResponseFailureSchema
1201
- ]);
1202
- var ToggleMcpToolResponseSchema = z5.union([
1203
- JsonRpcResponseSuccessSchema.extend({ result: ToggleMcpToolResultSchema }),
1204
- JsonRpcResponseFailureSchema
1205
- ]);
1206
- var ListSkillsResponseSchema = z5.union([
1207
- JsonRpcResponseSuccessSchema.extend({ result: ListSkillsResultSchema }),
1208
- JsonRpcResponseFailureSchema
1209
- ]);
1210
- var SubmitBugReportResponseSchema = z5.union([
1211
- JsonRpcResponseSuccessSchema.extend({ result: SubmitBugReportResultSchema }),
1212
- JsonRpcResponseFailureSchema
1213
- ]);
1214
- var GetRewindInfoResponseSchema = z5.union([
1215
- JsonRpcResponseSuccessSchema.extend({ result: GetRewindInfoResultSchema }),
1216
- JsonRpcResponseFailureSchema
1217
- ]);
1218
- var ExecuteRewindResponseSchema = z5.union([
1219
- JsonRpcResponseSuccessSchema.extend({ result: ExecuteRewindResultSchema }),
1220
- JsonRpcResponseFailureSchema
1221
- ]);
1222
- var CompactSessionResponseSchema = z5.union([
1223
- JsonRpcResponseSuccessSchema.extend({ result: CompactSessionResultSchema }),
1224
- JsonRpcResponseFailureSchema
1225
- ]);
1226
- var ForkSessionResponseSchema = z5.union([
1227
- JsonRpcResponseSuccessSchema.extend({ result: ForkSessionResultSchema }),
1228
- JsonRpcResponseFailureSchema
1229
- ]);
1230
- var GetContextStatsResponseSchema = z5.union([
1231
- JsonRpcResponseSuccessSchema.extend({ result: GetContextStatsResultSchema }),
1232
- JsonRpcResponseFailureSchema
1233
- ]);
1234
- var RenameSessionResponseSchema = z5.union([
1235
- JsonRpcResponseSuccessSchema.extend({ result: RenameSessionResultSchema }),
1236
- JsonRpcResponseFailureSchema
1237
- ]);
1164
+ var AddUserMessageResponseSchema = createResponseSchema(
1165
+ AddUserMessageResultSchema
1166
+ );
1167
+ var InterruptSessionResponseSchema = createResponseSchema(
1168
+ InterruptSessionResultSchema
1169
+ );
1170
+ var CloseSessionResponseSchema = createResponseSchema(
1171
+ CloseSessionResultSchema
1172
+ );
1173
+ var KillWorkerSessionResponseSchema = createResponseSchema(
1174
+ KillWorkerSessionResultSchema
1175
+ );
1176
+ var UpdateSessionSettingsResponseSchema = createResponseSchema(
1177
+ UpdateSessionSettingsResultSchema
1178
+ );
1179
+ var ToggleMcpServerResponseSchema = createResponseSchema(
1180
+ ToggleMcpServerResultSchema
1181
+ );
1182
+ var AuthenticateMcpServerResponseSchema = createResponseSchema(
1183
+ AuthenticateMcpServerResultSchema
1184
+ );
1185
+ var CancelMcpAuthResponseSchema = createResponseSchema(
1186
+ CancelMcpAuthResultSchema
1187
+ );
1188
+ var ClearMcpAuthResponseSchema = createResponseSchema(
1189
+ ClearMcpAuthResultSchema
1190
+ );
1191
+ var SubmitMcpAuthCodeResponseSchema = createResponseSchema(
1192
+ SubmitMcpAuthCodeResultSchema
1193
+ );
1194
+ var AddMcpServerResponseSchema = createResponseSchema(
1195
+ AddMcpServerResultSchema
1196
+ );
1197
+ var RemoveMcpServerResponseSchema = createResponseSchema(
1198
+ RemoveMcpServerResultSchema
1199
+ );
1200
+ var ListMcpRegistryResponseSchema = createResponseSchema(
1201
+ ListMcpRegistryResultSchema
1202
+ );
1203
+ var ListMcpToolsResponseSchema = createResponseSchema(
1204
+ ListMcpToolsResultSchema
1205
+ );
1206
+ var ListToolsResponseSchema = createResponseSchema(
1207
+ ListToolsResultSchema
1208
+ );
1209
+ var ListMcpServersResponseSchema = createResponseSchema(
1210
+ ListMcpServersResultSchema
1211
+ );
1212
+ var ToggleMcpToolResponseSchema = createResponseSchema(
1213
+ ToggleMcpToolResultSchema
1214
+ );
1215
+ var ListSkillsResponseSchema = createResponseSchema(
1216
+ ListSkillsResultSchema
1217
+ );
1218
+ var SubmitBugReportResponseSchema = createResponseSchema(
1219
+ SubmitBugReportResultSchema
1220
+ );
1221
+ var GetRewindInfoResponseSchema = createResponseSchema(
1222
+ GetRewindInfoResultSchema
1223
+ );
1224
+ var ExecuteRewindResponseSchema = createResponseSchema(
1225
+ ExecuteRewindResultSchema
1226
+ );
1227
+ var CompactSessionResponseSchema = createResponseSchema(
1228
+ CompactSessionResultSchema
1229
+ );
1230
+ var ForkSessionResponseSchema = createResponseSchema(
1231
+ ForkSessionResultSchema
1232
+ );
1233
+ var GetContextStatsResponseSchema = createResponseSchema(
1234
+ GetContextStatsResultSchema
1235
+ );
1236
+ var RenameSessionResponseSchema = createResponseSchema(
1237
+ RenameSessionResultSchema
1238
+ );
1238
1239
 
1239
1240
  // src/schemas/session-metadata.ts
1240
1241
  var SessionMetadataSchema = z6.object({
@@ -1265,140 +1266,231 @@ var SessionSettingsFileSchema = z6.object({
1265
1266
  tags: z6.array(SessionTagSchema).optional()
1266
1267
  }).passthrough();
1267
1268
 
1268
- // src/schemas/server.ts
1269
+ // src/schemas/hooks.ts
1269
1270
  import { z as z7 } from "zod";
1271
+ var DroidHookEventSchema = z7.enum([
1272
+ "PreToolUse",
1273
+ "PostToolUse",
1274
+ "Notification",
1275
+ "UserPromptSubmit",
1276
+ "Stop",
1277
+ "SubagentStop",
1278
+ "PreCompact",
1279
+ "SessionStart",
1280
+ "SessionEnd"
1281
+ ]);
1282
+ var DroidHookSpecificOutputSchema = z7.object({
1283
+ hookEventName: DroidHookEventSchema.optional(),
1284
+ permissionDecision: z7.enum(["allow", "deny", "ask"]).optional(),
1285
+ permissionDecisionReason: z7.string().optional(),
1286
+ additionalContext: z7.string().optional(),
1287
+ updatedInput: z7.record(z7.unknown()).optional()
1288
+ }).passthrough();
1289
+ var DroidHookOutputSchema = z7.object({
1290
+ continue: z7.boolean().optional(),
1291
+ stopReason: z7.string().optional(),
1292
+ suppressOutput: z7.boolean().optional(),
1293
+ systemMessage: z7.string().optional(),
1294
+ decision: z7.enum(["block", "approve"]).optional(),
1295
+ reason: z7.string().optional(),
1296
+ hookSpecificOutput: DroidHookSpecificOutputSchema.optional()
1297
+ }).passthrough();
1298
+ var DroidHookExecutionResultSchema = DroidHookOutputSchema.extend({
1299
+ exitCode: z7.number(),
1300
+ stdout: z7.string(),
1301
+ stderr: z7.string()
1302
+ });
1303
+
1304
+ // src/schemas/server.ts
1305
+ import { z as z8 } from "zod";
1270
1306
  var ToolUseBlockSchema2 = ToolUseBlockSchema;
1271
1307
  var ToolUseSchema = ToolUseBlockSchema2;
1272
- var ErrorDetailSchema = z7.object({
1273
- name: z7.string(),
1274
- message: z7.string()
1275
- }).passthrough();
1276
- var ToolProgressUpdateSchema = z7.object({
1277
- type: z7.enum(["tool_call", "tool_result", "error", "status", "message"]),
1278
- toolName: z7.string().optional(),
1279
- status: z7.string().optional(),
1280
- details: z7.string().optional(),
1281
- text: z7.string().optional(),
1282
- error: z7.string().optional(),
1283
- timestamp: z7.number().optional(),
1308
+ var ErrorDetailSchema = z8.object({
1309
+ name: z8.string(),
1310
+ message: z8.string()
1311
+ }).passthrough();
1312
+ var ToolProgressUpdateSchema = z8.object({
1313
+ type: z8.enum(["tool_call", "tool_result", "error", "status", "message"]),
1314
+ toolName: z8.string().optional(),
1315
+ status: z8.string().optional(),
1316
+ details: z8.string().optional(),
1317
+ text: z8.string().optional(),
1318
+ error: z8.string().optional(),
1319
+ timestamp: z8.number().optional(),
1284
1320
  parameters: JsonObjectSchema.optional(),
1285
- valueSnippet: z7.string().optional(),
1286
- subagentSessionId: z7.string().optional()
1287
- }).passthrough();
1288
- var SettingsUpdatedPayloadSchema = z7.object({
1289
- autonomyMode: z7.nativeEnum(AutonomyMode).optional(),
1290
- interactionMode: z7.nativeEnum(DroidInteractionMode).optional().catch(void 0),
1291
- autonomyLevel: z7.nativeEnum(AutonomyLevel).optional().catch(void 0),
1292
- modelId: z7.string().optional(),
1293
- reasoningEffort: z7.nativeEnum(ReasoningEffort).optional(),
1294
- specModeModelId: z7.string().optional(),
1295
- specModeReasoningEffort: z7.nativeEnum(ReasoningEffort).optional(),
1321
+ valueSnippet: z8.string().optional(),
1322
+ subagentSessionId: z8.string().optional()
1323
+ }).passthrough();
1324
+ var SettingsUpdatedPayloadSchema = z8.object({
1325
+ autonomyMode: z8.nativeEnum(AutonomyMode).optional(),
1326
+ interactionMode: z8.nativeEnum(DroidInteractionMode).optional().catch(void 0),
1327
+ autonomyLevel: z8.nativeEnum(AutonomyLevel).optional().catch(void 0),
1328
+ modelId: z8.string().optional(),
1329
+ reasoningEffort: z8.nativeEnum(ReasoningEffort).optional(),
1330
+ specModeModelId: z8.string().optional(),
1331
+ specModeReasoningEffort: z8.nativeEnum(ReasoningEffort).optional(),
1296
1332
  ...ToolSelectionOverridesSchema.shape
1297
1333
  }).passthrough();
1298
- var ToolResultNotificationSchema = z7.object({
1299
- type: z7.literal("tool_result" /* TOOL_RESULT */),
1300
- messageId: z7.string(),
1301
- toolUseId: z7.string(),
1334
+ var ToolResultNotificationSchema = z8.object({
1335
+ type: z8.literal("tool_result" /* TOOL_RESULT */),
1336
+ messageId: z8.string(),
1337
+ toolUseId: z8.string(),
1302
1338
  content: JsonValueSchema.optional(),
1303
- isError: z7.boolean().optional(),
1304
- id: z7.string().optional()
1339
+ isError: z8.boolean().optional(),
1340
+ id: z8.string().optional()
1305
1341
  }).passthrough();
1306
- var ToolProgressUpdateNotificationSchema = z7.object({
1307
- type: z7.literal("tool_progress_update" /* TOOL_PROGRESS_UPDATE */),
1308
- toolUseId: z7.string(),
1309
- toolName: z7.string(),
1342
+ var ToolProgressUpdateNotificationSchema = z8.object({
1343
+ type: z8.literal("tool_progress_update" /* TOOL_PROGRESS_UPDATE */),
1344
+ toolUseId: z8.string(),
1345
+ toolName: z8.string(),
1310
1346
  update: ToolProgressUpdateSchema
1311
1347
  }).passthrough();
1312
- var CreateMessageNotificationSchema = z7.object({
1313
- type: z7.literal("create_message" /* CREATE_MESSAGE */),
1348
+ var CreateMessageNotificationSchema = z8.object({
1349
+ type: z8.literal("create_message" /* CREATE_MESSAGE */),
1314
1350
  message: FactoryDroidMessageSchema,
1315
- parentId: z7.string().optional(),
1316
- requestId: z7.string().optional()
1317
- }).passthrough();
1318
- var ErrorNotificationSchema = z7.object({
1319
- type: z7.literal("error" /* ERROR */),
1320
- message: z7.string(),
1321
- errorType: z7.nativeEnum(DroidErrorType),
1322
- timestamp: z7.string(),
1351
+ parentId: z8.string().optional(),
1352
+ requestId: z8.string().optional()
1353
+ }).passthrough();
1354
+ var ErrorNotificationSchema = z8.object({
1355
+ type: z8.literal("error" /* ERROR */),
1356
+ message: z8.string(),
1357
+ errorType: z8.nativeEnum(DroidErrorType),
1358
+ timestamp: z8.string(),
1323
1359
  error: ErrorDetailSchema.optional()
1324
1360
  }).passthrough();
1325
- var DroidWorkingStateChangedNotificationSchema = z7.object({
1326
- type: z7.literal("droid_working_state_changed" /* DROID_WORKING_STATE_CHANGED */),
1327
- newState: z7.nativeEnum(DroidWorkingState)
1361
+ var DroidWorkingStateChangedNotificationSchema = z8.object({
1362
+ type: z8.literal("droid_working_state_changed" /* DROID_WORKING_STATE_CHANGED */),
1363
+ newState: z8.nativeEnum(DroidWorkingState)
1328
1364
  }).passthrough();
1329
- var PermissionResolvedNotificationSchema = z7.object({
1330
- type: z7.literal("permission_resolved" /* PERMISSION_RESOLVED */),
1331
- requestId: z7.string(),
1332
- toolUseIds: z7.array(z7.string()),
1333
- selectedOption: z7.nativeEnum(ToolConfirmationOutcome)
1365
+ var PermissionResolvedNotificationSchema = z8.object({
1366
+ type: z8.literal("permission_resolved" /* PERMISSION_RESOLVED */),
1367
+ requestId: z8.string(),
1368
+ toolUseIds: z8.array(z8.string()),
1369
+ selectedOption: z8.nativeEnum(ToolConfirmationOutcome)
1334
1370
  }).passthrough();
1335
- var SettingsUpdatedNotificationSchema = z7.object({
1336
- type: z7.literal("settings_updated" /* SETTINGS_UPDATED */),
1371
+ var SettingsUpdatedNotificationSchema = z8.object({
1372
+ type: z8.literal("settings_updated" /* SETTINGS_UPDATED */),
1337
1373
  settings: SettingsUpdatedPayloadSchema
1338
1374
  }).passthrough();
1339
- var SessionTitleUpdatedNotificationSchema = z7.object({
1340
- type: z7.literal("session_title_updated" /* SESSION_TITLE_UPDATED */),
1341
- title: z7.string()
1375
+ var SessionTitleUpdatedNotificationSchema = z8.object({
1376
+ type: z8.literal("session_title_updated" /* SESSION_TITLE_UPDATED */),
1377
+ title: z8.string()
1342
1378
  }).passthrough();
1343
- var McpStatusChangedNotificationSchema = z7.object({
1344
- type: z7.literal("mcp_status_changed" /* MCP_STATUS_CHANGED */),
1345
- servers: z7.array(McpServerStatusInfoSchema),
1379
+ var McpStatusChangedNotificationSchema = z8.object({
1380
+ type: z8.literal("mcp_status_changed" /* MCP_STATUS_CHANGED */),
1381
+ servers: z8.array(McpServerStatusInfoSchema),
1346
1382
  summary: McpStatusSummarySchema
1347
1383
  }).passthrough();
1348
- var AssistantTextDeltaNotificationSchema = z7.object({
1349
- type: z7.literal("assistant_text_delta" /* ASSISTANT_TEXT_DELTA */),
1350
- messageId: z7.string(),
1351
- blockIndex: z7.number(),
1352
- textDelta: z7.string()
1353
- }).passthrough();
1354
- var ThinkingTextDeltaNotificationSchema = z7.object({
1355
- type: z7.literal("thinking_text_delta" /* THINKING_TEXT_DELTA */),
1356
- messageId: z7.string(),
1357
- blockIndex: z7.number(),
1358
- textDelta: z7.string()
1359
- }).passthrough();
1360
- var SessionTokenUsageChangedNotificationSchema = z7.object({
1361
- type: z7.literal("session_token_usage_changed" /* SESSION_TOKEN_USAGE_CHANGED */),
1362
- sessionId: z7.string(),
1384
+ var AssistantTextDeltaNotificationSchema = z8.object({
1385
+ type: z8.literal("assistant_text_delta" /* ASSISTANT_TEXT_DELTA */),
1386
+ messageId: z8.string(),
1387
+ blockIndex: z8.number(),
1388
+ textDelta: z8.string()
1389
+ }).passthrough();
1390
+ var AssistantTextCompleteNotificationSchema = z8.object({
1391
+ type: z8.literal("assistant_text_complete" /* ASSISTANT_TEXT_COMPLETE */),
1392
+ messageId: z8.string(),
1393
+ blockIndex: z8.number()
1394
+ }).passthrough();
1395
+ var ThinkingTextDeltaNotificationSchema = z8.object({
1396
+ type: z8.literal("thinking_text_delta" /* THINKING_TEXT_DELTA */),
1397
+ messageId: z8.string(),
1398
+ blockIndex: z8.number(),
1399
+ textDelta: z8.string()
1400
+ }).passthrough();
1401
+ var ThinkingTextCompleteNotificationSchema = z8.object({
1402
+ type: z8.literal("thinking_text_complete" /* THINKING_TEXT_COMPLETE */),
1403
+ messageId: z8.string(),
1404
+ blockIndex: z8.number(),
1405
+ durationMs: z8.number().optional()
1406
+ }).passthrough();
1407
+ var ToolCallNotificationSchema = z8.object({
1408
+ type: z8.literal("tool_call" /* TOOL_CALL */),
1409
+ toolUse: ToolUseBlockSchema2
1410
+ }).passthrough();
1411
+ var SessionTokenUsageChangedNotificationSchema = z8.object({
1412
+ type: z8.literal("session_token_usage_changed" /* SESSION_TOKEN_USAGE_CHANGED */),
1413
+ sessionId: z8.string(),
1363
1414
  tokenUsage: TokenUsageSchema
1364
1415
  }).passthrough();
1365
- var MissionStateChangedNotificationSchema = z7.object({
1366
- type: z7.literal("mission_state_changed" /* MISSION_STATE_CHANGED */),
1367
- state: z7.nativeEnum(MissionState)
1416
+ var MissionStateChangedNotificationSchema = z8.object({
1417
+ type: z8.literal("mission_state_changed" /* MISSION_STATE_CHANGED */),
1418
+ state: z8.nativeEnum(MissionState)
1419
+ }).passthrough();
1420
+ var MissionFeaturesChangedNotificationSchema = z8.object({
1421
+ type: z8.literal("mission_features_changed" /* MISSION_FEATURES_CHANGED */),
1422
+ features: z8.array(MissionFeatureSchema)
1423
+ }).passthrough();
1424
+ var MissionProgressEntryNotificationSchema = z8.object({
1425
+ type: z8.literal("mission_progress_entry" /* MISSION_PROGRESS_ENTRY */),
1426
+ progressLog: z8.array(ProgressLogEntrySchema)
1427
+ }).passthrough();
1428
+ var MissionHeartbeatNotificationSchema = z8.object({
1429
+ type: z8.literal("mission_heartbeat" /* MISSION_HEARTBEAT */),
1430
+ timestamp: z8.string()
1431
+ }).passthrough();
1432
+ var MissionWorkerStartedNotificationSchema = z8.object({
1433
+ type: z8.literal("mission_worker_started" /* MISSION_WORKER_STARTED */),
1434
+ workerSessionId: z8.string()
1368
1435
  }).passthrough();
1369
- var MissionFeaturesChangedNotificationSchema = z7.object({
1370
- type: z7.literal("mission_features_changed" /* MISSION_FEATURES_CHANGED */),
1371
- features: z7.array(MissionFeatureSchema)
1436
+ var MissionWorkerCompletedNotificationSchema = z8.object({
1437
+ type: z8.literal("mission_worker_completed" /* MISSION_WORKER_COMPLETED */),
1438
+ workerSessionId: z8.string(),
1439
+ exitCode: z8.number()
1372
1440
  }).passthrough();
1373
- var MissionProgressEntryNotificationSchema = z7.object({
1374
- type: z7.literal("mission_progress_entry" /* MISSION_PROGRESS_ENTRY */),
1375
- progressLog: z7.array(ProgressLogEntrySchema)
1441
+ var McpAuthRequiredNotificationSchema = z8.object({
1442
+ type: z8.literal("mcp_auth_required" /* MCP_AUTH_REQUIRED */),
1443
+ serverName: z8.string(),
1444
+ authUrl: z8.string(),
1445
+ message: z8.string(),
1446
+ state: z8.string()
1376
1447
  }).passthrough();
1377
- var MissionHeartbeatNotificationSchema = z7.object({
1378
- type: z7.literal("mission_heartbeat" /* MISSION_HEARTBEAT */),
1379
- timestamp: z7.string()
1448
+ var McpAuthCompletedNotificationSchema = z8.object({
1449
+ type: z8.literal("mcp_auth_completed" /* MCP_AUTH_COMPLETED */),
1450
+ serverName: z8.string(),
1451
+ outcome: z8.nativeEnum(McpAuthOutcome),
1452
+ message: z8.string()
1380
1453
  }).passthrough();
1381
- var MissionWorkerStartedNotificationSchema = z7.object({
1382
- type: z7.literal("mission_worker_started" /* MISSION_WORKER_STARTED */),
1383
- workerSessionId: z7.string()
1454
+ var HookCommandSchema = z8.object({
1455
+ command: z8.string(),
1456
+ timeout: z8.number().optional()
1384
1457
  }).passthrough();
1385
- var MissionWorkerCompletedNotificationSchema = z7.object({
1386
- type: z7.literal("mission_worker_completed" /* MISSION_WORKER_COMPLETED */),
1387
- workerSessionId: z7.string(),
1388
- exitCode: z7.number()
1458
+ var HookResultSchema = z8.object({
1459
+ exitCode: z8.number(),
1460
+ stdout: z8.string(),
1461
+ stderr: z8.string(),
1462
+ command: z8.string().optional(),
1463
+ timeout: z8.number().optional()
1389
1464
  }).passthrough();
1390
- var McpAuthRequiredNotificationSchema = z7.object({
1391
- type: z7.literal("mcp_auth_required" /* MCP_AUTH_REQUIRED */),
1392
- serverName: z7.string(),
1393
- authUrl: z7.string(),
1394
- message: z7.string(),
1395
- state: z7.string()
1465
+ var HookExecutionStartedNotificationSchema = z8.object({
1466
+ type: z8.literal("hook_execution_started" /* HOOK_EXECUTION_STARTED */),
1467
+ hookId: z8.string(),
1468
+ hookEventName: DroidHookEventSchema,
1469
+ hookMatcher: z8.string().optional(),
1470
+ hookCommands: z8.array(HookCommandSchema),
1471
+ hookToolCallId: z8.string().optional(),
1472
+ isParallelExecution: z8.boolean().optional(),
1473
+ parallelGroupId: z8.string().optional()
1396
1474
  }).passthrough();
1397
- var McpAuthCompletedNotificationSchema = z7.object({
1398
- type: z7.literal("mcp_auth_completed" /* MCP_AUTH_COMPLETED */),
1399
- serverName: z7.string(),
1400
- outcome: z7.nativeEnum(McpAuthOutcome),
1401
- message: z7.string()
1475
+ var HookExecutionCompletedNotificationSchema = z8.object({
1476
+ type: z8.literal("hook_execution_completed" /* HOOK_EXECUTION_COMPLETED */),
1477
+ hookId: z8.string(),
1478
+ hookEventName: DroidHookEventSchema.optional(),
1479
+ hookMatcher: z8.string().optional(),
1480
+ hookToolCallId: z8.string().optional(),
1481
+ hookStatus: z8.enum(["completed", "error"]),
1482
+ hookResults: z8.array(HookResultSchema).optional()
1483
+ }).passthrough();
1484
+ var StructuredOutputErrorSchema = z8.object({
1485
+ code: z8.string(),
1486
+ message: z8.string(),
1487
+ details: z8.unknown().optional()
1488
+ }).passthrough();
1489
+ var StructuredOutputNotificationSchema = z8.object({
1490
+ type: z8.literal("structured_output" /* STRUCTURED_OUTPUT */),
1491
+ messageId: z8.string(),
1492
+ structuredOutput: JsonObjectSchema.nullable(),
1493
+ structuredOutputError: StructuredOutputErrorSchema.nullable()
1402
1494
  }).passthrough();
1403
1495
  var SessionNotificationSchemaList = [
1404
1496
  ToolResultNotificationSchema,
@@ -1411,7 +1503,10 @@ var SessionNotificationSchemaList = [
1411
1503
  SessionTitleUpdatedNotificationSchema,
1412
1504
  McpStatusChangedNotificationSchema,
1413
1505
  AssistantTextDeltaNotificationSchema,
1506
+ AssistantTextCompleteNotificationSchema,
1414
1507
  ThinkingTextDeltaNotificationSchema,
1508
+ ThinkingTextCompleteNotificationSchema,
1509
+ ToolCallNotificationSchema,
1415
1510
  SessionTokenUsageChangedNotificationSchema,
1416
1511
  MissionStateChangedNotificationSchema,
1417
1512
  MissionFeaturesChangedNotificationSchema,
@@ -1420,88 +1515,91 @@ var SessionNotificationSchemaList = [
1420
1515
  MissionWorkerStartedNotificationSchema,
1421
1516
  MissionWorkerCompletedNotificationSchema,
1422
1517
  McpAuthRequiredNotificationSchema,
1423
- McpAuthCompletedNotificationSchema
1518
+ McpAuthCompletedNotificationSchema,
1519
+ HookExecutionStartedNotificationSchema,
1520
+ HookExecutionCompletedNotificationSchema,
1521
+ StructuredOutputNotificationSchema
1424
1522
  ];
1425
- var SessionNotificationPayloadSchema = z7.discriminatedUnion(
1523
+ var SessionNotificationPayloadSchema = z8.discriminatedUnion(
1426
1524
  "type",
1427
1525
  SessionNotificationSchemaList
1428
1526
  );
1429
- var _SessionNotificationParamsSchema = z7.object({
1527
+ var _SessionNotificationParamsSchema = z8.object({
1430
1528
  notification: SessionNotificationPayloadSchema
1431
1529
  }).passthrough();
1432
1530
  var SessionNotificationParamsSchema = _SessionNotificationParamsSchema;
1433
1531
  var _SessionNotificationSchema = JsonRpcNotificationSchema.extend({
1434
- method: z7.literal("droid.session_notification" /* SESSION_NOTIFICATION */),
1532
+ method: z8.literal("droid.session_notification" /* SESSION_NOTIFICATION */),
1435
1533
  params: SessionNotificationParamsSchema
1436
1534
  });
1437
1535
  var SessionNotificationSchema = _SessionNotificationSchema;
1438
- var EditToolConfirmationDetailsSchema = z7.object({
1439
- type: z7.literal("edit" /* Edit */),
1440
- filePath: z7.string(),
1441
- fileName: z7.string(),
1442
- oldContent: z7.string().optional(),
1443
- newContent: z7.string().optional()
1444
- }).passthrough();
1445
- var ExecuteToolConfirmationDetailsSchema = z7.object({
1446
- type: z7.literal("exec" /* Execute */),
1447
- fullCommand: z7.string(),
1448
- command: z7.string(),
1449
- extractedCommands: z7.array(z7.string()).optional(),
1450
- impactLevel: z7.string().optional()
1451
- }).passthrough();
1452
- var CreateToolConfirmationDetailsSchema = z7.object({
1453
- type: z7.literal("create" /* Create */),
1454
- filePath: z7.string(),
1455
- fileName: z7.string(),
1456
- content: z7.string()
1457
- }).passthrough();
1458
- var AskUserQuestionSchema = z7.object({
1459
- index: z7.number(),
1460
- topic: z7.string(),
1461
- question: z7.string(),
1462
- options: z7.array(z7.string())
1463
- }).passthrough();
1464
- var AskUserConfirmationDetailsSchema = z7.object({
1465
- type: z7.literal("ask_user" /* AskUser */),
1466
- questionnaire: z7.string(),
1467
- parsed: z7.object({
1468
- questions: z7.array(AskUserQuestionSchema)
1536
+ var EditToolConfirmationDetailsSchema = z8.object({
1537
+ type: z8.literal("edit" /* Edit */),
1538
+ filePath: z8.string(),
1539
+ fileName: z8.string(),
1540
+ oldContent: z8.string().optional(),
1541
+ newContent: z8.string().optional()
1542
+ }).passthrough();
1543
+ var ExecuteToolConfirmationDetailsSchema = z8.object({
1544
+ type: z8.literal("exec" /* Execute */),
1545
+ fullCommand: z8.string(),
1546
+ command: z8.string(),
1547
+ extractedCommands: z8.array(z8.string()).optional(),
1548
+ impactLevel: z8.string().optional()
1549
+ }).passthrough();
1550
+ var CreateToolConfirmationDetailsSchema = z8.object({
1551
+ type: z8.literal("create" /* Create */),
1552
+ filePath: z8.string(),
1553
+ fileName: z8.string(),
1554
+ content: z8.string()
1555
+ }).passthrough();
1556
+ var AskUserQuestionSchema = z8.object({
1557
+ index: z8.number(),
1558
+ topic: z8.string(),
1559
+ question: z8.string(),
1560
+ options: z8.array(z8.string())
1561
+ }).passthrough();
1562
+ var AskUserConfirmationDetailsSchema = z8.object({
1563
+ type: z8.literal("ask_user" /* AskUser */),
1564
+ questionnaire: z8.string(),
1565
+ parsed: z8.object({
1566
+ questions: z8.array(AskUserQuestionSchema)
1469
1567
  }).optional(),
1470
- parseError: z7.object({
1471
- message: z7.string(),
1472
- line: z7.number().optional()
1568
+ parseError: z8.object({
1569
+ message: z8.string(),
1570
+ line: z8.number().optional()
1473
1571
  }).optional()
1474
1572
  }).passthrough();
1475
- var ExitSpecModeConfirmationDetailsSchema = z7.object({
1476
- type: z7.literal("exit_spec_mode" /* ExitSpecMode */),
1477
- plan: z7.string(),
1478
- title: z7.string().optional(),
1479
- optionNames: z7.array(z7.string()).optional()
1480
- }).passthrough();
1481
- var ProposeMissionConfirmationDetailsSchema = z7.object({
1482
- type: z7.literal("propose_mission" /* ProposeMission */),
1483
- proposal: z7.string(),
1484
- title: z7.string().optional()
1485
- }).passthrough();
1486
- var StartMissionRunConfirmationDetailsSchema = z7.object({
1487
- type: z7.literal("start_mission_run" /* StartMissionRun */),
1488
- runningMissionCount: z7.number(),
1489
- runningMissionSessionIds: z7.array(z7.string())
1490
- }).passthrough();
1491
- var ApplyPatchToolConfirmationDetailsSchema = z7.object({
1492
- type: z7.literal("apply_patch" /* ApplyPatch */),
1493
- filePath: z7.string(),
1494
- fileName: z7.string(),
1495
- patchContent: z7.string(),
1496
- oldContent: z7.string().optional(),
1497
- newContent: z7.string().optional()
1498
- }).passthrough();
1499
- var McpToolConfirmationDetailsSchema = z7.object({
1500
- type: z7.literal("mcp_tool" /* McpTool */),
1501
- toolName: z7.string(),
1502
- impactLevel: z7.string()
1503
- }).passthrough();
1504
- var ToolConfirmationDetailsSchema = z7.discriminatedUnion("type", [
1573
+ var ExitSpecModeConfirmationDetailsSchema = z8.object({
1574
+ type: z8.literal("exit_spec_mode" /* ExitSpecMode */),
1575
+ plan: z8.string(),
1576
+ title: z8.string().optional(),
1577
+ optionNames: z8.array(z8.string()).optional()
1578
+ }).passthrough();
1579
+ var ProposeMissionConfirmationDetailsSchema = z8.object({
1580
+ type: z8.literal("propose_mission" /* ProposeMission */),
1581
+ proposal: z8.string(),
1582
+ title: z8.string().optional()
1583
+ }).passthrough();
1584
+ var StartMissionRunConfirmationDetailsSchema = z8.object({
1585
+ type: z8.literal("start_mission_run" /* StartMissionRun */),
1586
+ runningMissionCount: z8.number(),
1587
+ runningMissionSessionIds: z8.array(z8.string())
1588
+ }).passthrough();
1589
+ var ApplyPatchToolConfirmationDetailsSchema = z8.object({
1590
+ type: z8.literal("apply_patch" /* ApplyPatch */),
1591
+ filePath: z8.string(),
1592
+ fileName: z8.string(),
1593
+ patchContent: z8.string(),
1594
+ oldContent: z8.string().optional(),
1595
+ newContent: z8.string().optional()
1596
+ }).passthrough();
1597
+ var McpToolConfirmationDetailsSchema = z8.object({
1598
+ type: z8.literal("mcp_tool" /* McpTool */),
1599
+ toolName: z8.string(),
1600
+ impactLevel: z8.string()
1601
+ }).passthrough();
1602
+ var ToolConfirmationDetailsSchema = z8.discriminatedUnion("type", [
1505
1603
  EditToolConfirmationDetailsSchema,
1506
1604
  ExecuteToolConfirmationDetailsSchema,
1507
1605
  CreateToolConfirmationDetailsSchema,
@@ -1512,51 +1610,45 @@ var ToolConfirmationDetailsSchema = z7.discriminatedUnion("type", [
1512
1610
  ApplyPatchToolConfirmationDetailsSchema,
1513
1611
  McpToolConfirmationDetailsSchema
1514
1612
  ]);
1515
- var ToolConfirmationInfoSchema = z7.object({
1613
+ var ToolConfirmationInfoSchema = z8.object({
1516
1614
  toolUse: ToolUseSchema,
1517
- confirmationType: z7.nativeEnum(ToolConfirmationType),
1615
+ confirmationType: z8.nativeEnum(ToolConfirmationType),
1518
1616
  details: ToolConfirmationDetailsSchema
1519
1617
  }).passthrough();
1520
- var RequestPermissionRequestParamsSchema = z7.object({
1521
- toolUses: z7.array(ToolConfirmationInfoSchema),
1522
- options: z7.array(ToolConfirmationListItemSchema)
1618
+ var RequestPermissionRequestParamsSchema = z8.object({
1619
+ toolUses: z8.array(ToolConfirmationInfoSchema),
1620
+ options: z8.array(ToolConfirmationListItemSchema)
1523
1621
  }).passthrough();
1524
1622
  var RequestPermissionRequestSchema = JsonRpcRequestSchema.extend({
1525
- method: z7.literal("droid.request_permission" /* REQUEST_PERMISSION */),
1623
+ method: z8.literal("droid.request_permission" /* REQUEST_PERMISSION */),
1526
1624
  params: RequestPermissionRequestParamsSchema
1527
1625
  });
1528
- var RequestPermissionResultSchema = z7.object({
1529
- selectedOption: z7.nativeEnum(ToolConfirmationOutcome),
1530
- comment: z7.string().optional()
1626
+ var RequestPermissionResultSchema = z8.object({
1627
+ selectedOption: z8.nativeEnum(ToolConfirmationOutcome),
1628
+ comment: z8.string().optional()
1531
1629
  }).strict();
1532
- var RequestPermissionResponseSchema = z7.union([
1533
- JsonRpcResponseSuccessSchema.extend({
1534
- result: RequestPermissionResultSchema
1535
- }),
1536
- JsonRpcResponseFailureSchema
1537
- ]);
1538
- var AskUserRequestParamsSchema = z7.object({
1539
- toolCallId: z7.string(),
1540
- questions: z7.array(AskUserQuestionSchema)
1630
+ var RequestPermissionResponseSchema = createResponseSchema(
1631
+ RequestPermissionResultSchema
1632
+ );
1633
+ var AskUserRequestParamsSchema = z8.object({
1634
+ toolCallId: z8.string(),
1635
+ questions: z8.array(AskUserQuestionSchema)
1541
1636
  }).passthrough();
1542
1637
  var AskUserRequestSchema = JsonRpcRequestSchema.extend({
1543
- method: z7.literal("droid.ask_user" /* ASK_USER */),
1638
+ method: z8.literal("droid.ask_user" /* ASK_USER */),
1544
1639
  params: AskUserRequestParamsSchema
1545
1640
  });
1546
- var AskUserCollectedAnswerSchema = z7.object({
1547
- index: z7.number(),
1548
- question: z7.string(),
1549
- answer: z7.string()
1641
+ var AskUserCollectedAnswerSchema = z8.object({
1642
+ index: z8.number(),
1643
+ question: z8.string(),
1644
+ answer: z8.string()
1550
1645
  }).strict();
1551
- var AskUserResultSchema = z7.object({
1552
- cancelled: z7.boolean().optional(),
1553
- answers: z7.array(AskUserCollectedAnswerSchema)
1646
+ var AskUserResultSchema = z8.object({
1647
+ cancelled: z8.boolean().optional(),
1648
+ answers: z8.array(AskUserCollectedAnswerSchema)
1554
1649
  }).strict();
1555
- var AskUserResponseSchema = z7.union([
1556
- JsonRpcResponseSuccessSchema.extend({ result: AskUserResultSchema }),
1557
- JsonRpcResponseFailureSchema
1558
- ]);
1559
- var _CliRequestOrNotificationSchema = z7.union([
1650
+ var AskUserResponseSchema = createResponseSchema(AskUserResultSchema);
1651
+ var _CliRequestOrNotificationSchema = z8.union([
1560
1652
  SessionNotificationSchema,
1561
1653
  RequestPermissionRequestSchema,
1562
1654
  AskUserRequestSchema
@@ -1564,7 +1656,7 @@ var _CliRequestOrNotificationSchema = z7.union([
1564
1656
  var CliRequestOrNotificationSchema = _CliRequestOrNotificationSchema;
1565
1657
 
1566
1658
  // src/constants.ts
1567
- var SDK_VERSION = "0.2.0";
1659
+ var SDK_VERSION = "0.4.0";
1568
1660
  var SDK_TAG = {
1569
1661
  name: "sdk",
1570
1662
  metadata: { language: "typescript", version: SDK_VERSION }
@@ -1880,9 +1972,32 @@ var ProcessTransport = class {
1880
1972
 
1881
1973
  // src/protocol.ts
1882
1974
  import { v4 as uuidv4 } from "uuid";
1975
+ function dispatchNotification(notification, listeners) {
1976
+ let notificationType;
1977
+ const parsed = SessionNotificationParamsSchema.safeParse(
1978
+ notification["params"]
1979
+ );
1980
+ if (parsed.success) {
1981
+ notificationType = parsed.data.notification.type;
1982
+ }
1983
+ for (const listener of listeners) {
1984
+ if (listener.filter?.type != null && listener.filter.type !== notificationType) {
1985
+ continue;
1986
+ }
1987
+ try {
1988
+ listener.callback(notification);
1989
+ } catch {
1990
+ }
1991
+ }
1992
+ }
1993
+ var DEFAULT_SERVER_REQUEST_METHOD_MAP = {
1994
+ ["droid.request_permission" /* REQUEST_PERMISSION */]: "permission" /* Permission */,
1995
+ ["droid.ask_user" /* ASK_USER */]: "askUser" /* AskUser */
1996
+ };
1883
1997
  var ProtocolEngine = class {
1884
1998
  _transport;
1885
1999
  _defaultTimeout;
2000
+ _serverRequestMethodMap;
1886
2001
  _pendingRequests = /* @__PURE__ */ new Map();
1887
2002
  _notificationListeners = /* @__PURE__ */ new Set();
1888
2003
  _permissionHandler = null;
@@ -1892,6 +2007,7 @@ var ProtocolEngine = class {
1892
2007
  constructor(options) {
1893
2008
  this._transport = options.transport;
1894
2009
  this._defaultTimeout = options.defaultTimeout ?? DEFAULT_REQUEST_TIMEOUT;
2010
+ this._serverRequestMethodMap = options.serverRequestMethodMap ?? DEFAULT_SERVER_REQUEST_METHOD_MAP;
1895
2011
  this._transport.onMessage((message) => {
1896
2012
  this._handleMessage(message);
1897
2013
  });
@@ -2044,27 +2160,13 @@ var ProtocolEngine = class {
2044
2160
  pending.resolve(result);
2045
2161
  }
2046
2162
  _handleNotification(notification) {
2047
- let notificationType;
2048
- const parsed = SessionNotificationParamsSchema.safeParse(
2049
- notification["params"]
2050
- );
2051
- if (parsed.success) {
2052
- notificationType = parsed.data.notification.type;
2053
- }
2054
- for (const listener of this._notificationListeners) {
2055
- if (listener.filter?.type != null && listener.filter.type !== notificationType) {
2056
- continue;
2057
- }
2058
- try {
2059
- listener.callback(notification);
2060
- } catch {
2061
- }
2062
- }
2163
+ dispatchNotification(notification, this._notificationListeners);
2063
2164
  }
2064
2165
  async _handleServerRequest(method, requestId, params) {
2065
- if (method === "droid.request_permission" /* REQUEST_PERMISSION */) {
2166
+ const handlerType = this._serverRequestMethodMap[method];
2167
+ if (handlerType === "permission" /* Permission */) {
2066
2168
  await this._handlePermissionRequest(requestId, params);
2067
- } else if (method === "droid.ask_user" /* ASK_USER */) {
2169
+ } else if (handlerType === "askUser" /* AskUser */) {
2068
2170
  await this._handleAskUserRequest(requestId, params);
2069
2171
  }
2070
2172
  }
@@ -2180,10 +2282,6 @@ var DroidClient = class {
2180
2282
  _engine;
2181
2283
  _sessionId = null;
2182
2284
  _closed = false;
2183
- /**
2184
- * Client-level notification listeners.
2185
- * Each entry is [callback, optional notification filter].
2186
- */
2187
2285
  _notificationListeners = [];
2188
2286
  /** Client-level permission handler. */
2189
2287
  _permissionHandler = null;
@@ -2257,6 +2355,13 @@ var DroidClient = class {
2257
2355
  InterruptSessionResultSchema
2258
2356
  );
2259
2357
  }
2358
+ async closeSession(params = {}) {
2359
+ return this._sessionRpc(
2360
+ "droid.close_session" /* CLOSE_SESSION */,
2361
+ params,
2362
+ CloseSessionResultSchema
2363
+ );
2364
+ }
2260
2365
  async killWorkerSession(params) {
2261
2366
  return this._sessionRpc(
2262
2367
  "droid.kill_worker_session" /* KILL_WORKER_SESSION */,
@@ -2445,23 +2550,7 @@ var DroidClient = class {
2445
2550
  await this._engine.close();
2446
2551
  }
2447
2552
  _dispatchNotification(notification) {
2448
- let notificationType;
2449
- const parsed = SessionNotificationParamsSchema.safeParse(
2450
- notification["params"]
2451
- );
2452
- if (parsed.success) {
2453
- notificationType = parsed.data.notification.type;
2454
- }
2455
- const listeners = [...this._notificationListeners];
2456
- for (const listener of listeners) {
2457
- if (listener.filter?.type != null && listener.filter.type !== notificationType) {
2458
- continue;
2459
- }
2460
- try {
2461
- listener.callback(notification);
2462
- } catch {
2463
- }
2464
- }
2553
+ dispatchNotification(notification, [...this._notificationListeners]);
2465
2554
  }
2466
2555
  _dispatchPermissionRequest(params) {
2467
2556
  const handler = this._permissionHandler;
@@ -2495,14 +2584,18 @@ var DroidClient = class {
2495
2584
 
2496
2585
  // src/stream.ts
2497
2586
  var DroidMessageType = {
2587
+ Assistant: "assistant",
2588
+ User: "user",
2589
+ ToolCall: "tool_call",
2498
2590
  AssistantTextDelta: "assistant_text_delta",
2591
+ AssistantTextComplete: "assistant_text_complete",
2499
2592
  ThinkingTextDelta: "thinking_text_delta",
2500
- ToolUse: "tool_use",
2593
+ ThinkingTextComplete: "thinking_text_complete",
2594
+ ToolCallDelta: "tool_call_delta",
2501
2595
  ToolResult: "tool_result",
2502
2596
  ToolProgress: "tool_progress",
2503
2597
  WorkingStateChanged: "working_state_changed",
2504
2598
  TokenUsageUpdate: "token_usage_update",
2505
- CreateMessage: "create_message",
2506
2599
  PermissionResolved: "permission_resolved",
2507
2600
  SettingsUpdated: "settings_updated",
2508
2601
  SessionTitleUpdated: "session_title_updated",
@@ -2515,8 +2608,9 @@ var DroidMessageType = {
2515
2608
  MissionWorkerCompleted: "mission_worker_completed",
2516
2609
  McpAuthRequired: "mcp_auth_required",
2517
2610
  McpAuthCompleted: "mcp_auth_completed",
2611
+ Hook: "hook",
2518
2612
  Error: "error",
2519
- TurnComplete: "turn_complete"
2613
+ Result: "result"
2520
2614
  };
2521
2615
  function convertNotificationToStreamMessage(raw) {
2522
2616
  const parsed = SessionNotificationPayloadSchema.safeParse(raw);
@@ -2532,6 +2626,12 @@ function convertNotificationToStreamMessage(raw) {
2532
2626
  blockIndex: notification.blockIndex,
2533
2627
  text: notification.textDelta
2534
2628
  };
2629
+ case "assistant_text_complete" /* ASSISTANT_TEXT_COMPLETE */:
2630
+ return {
2631
+ type: DroidMessageType.AssistantTextComplete,
2632
+ messageId: notification.messageId,
2633
+ blockIndex: notification.blockIndex
2634
+ };
2535
2635
  case "thinking_text_delta" /* THINKING_TEXT_DELTA */:
2536
2636
  return {
2537
2637
  type: DroidMessageType.ThinkingTextDelta,
@@ -2539,6 +2639,18 @@ function convertNotificationToStreamMessage(raw) {
2539
2639
  blockIndex: notification.blockIndex,
2540
2640
  text: notification.textDelta
2541
2641
  };
2642
+ case "thinking_text_complete" /* THINKING_TEXT_COMPLETE */:
2643
+ return {
2644
+ type: DroidMessageType.ThinkingTextComplete,
2645
+ messageId: notification.messageId,
2646
+ blockIndex: notification.blockIndex,
2647
+ durationMs: notification.durationMs
2648
+ };
2649
+ case "tool_call" /* TOOL_CALL */:
2650
+ return {
2651
+ type: DroidMessageType.ToolCallDelta,
2652
+ toolUse: notification.toolUse
2653
+ };
2542
2654
  case "tool_result" /* TOOL_RESULT */:
2543
2655
  return {
2544
2656
  type: DroidMessageType.ToolResult,
@@ -2578,22 +2690,33 @@ function convertNotificationToStreamMessage(raw) {
2578
2690
  const msg = notification.message;
2579
2691
  const messages = [];
2580
2692
  for (const block of msg.content) {
2581
- if (block.type === DroidMessageType.ToolUse) {
2693
+ if (block.type === "tool_use") {
2582
2694
  messages.push({
2583
- type: DroidMessageType.ToolUse,
2584
- toolName: block.name,
2585
- toolInput: block.input,
2586
- toolUseId: block.id
2695
+ type: DroidMessageType.ToolCall,
2696
+ toolUse: block
2587
2697
  });
2588
2698
  }
2589
2699
  }
2590
- messages.push({
2591
- type: DroidMessageType.CreateMessage,
2592
- messageId: msg.id,
2593
- role: msg.role,
2594
- content: msg.content,
2595
- parentId: notification.parentId
2596
- });
2700
+ if (msg.role === FactoryDroidMessageRole.Assistant) {
2701
+ messages.push({
2702
+ type: DroidMessageType.Assistant,
2703
+ message: msg,
2704
+ text: extractTextFromMessage(msg)
2705
+ });
2706
+ } else if (msg.role === FactoryDroidMessageRole.User) {
2707
+ messages.push({
2708
+ type: DroidMessageType.User,
2709
+ message: msg
2710
+ });
2711
+ } else {
2712
+ messages.push({
2713
+ type: "create_message",
2714
+ messageId: msg.id,
2715
+ role: msg.role,
2716
+ content: msg.content,
2717
+ parentId: notification.parentId
2718
+ });
2719
+ }
2597
2720
  return messages;
2598
2721
  }
2599
2722
  case "error" /* ERROR */:
@@ -2672,42 +2795,205 @@ function convertNotificationToStreamMessage(raw) {
2672
2795
  outcome: notification.outcome,
2673
2796
  message: notification.message
2674
2797
  };
2798
+ case "hook_execution_started" /* HOOK_EXECUTION_STARTED */:
2799
+ return notification.hookCommands.map((hookCommand) => ({
2800
+ type: DroidMessageType.Hook,
2801
+ hookId: notification.hookId,
2802
+ eventName: notification.hookEventName,
2803
+ matcher: notification.hookMatcher,
2804
+ toolCallId: notification.hookToolCallId,
2805
+ command: hookCommand.command,
2806
+ timeout: hookCommand.timeout,
2807
+ status: "started"
2808
+ }));
2809
+ case "hook_execution_completed" /* HOOK_EXECUTION_COMPLETED */:
2810
+ return (notification.hookResults ?? []).map((hookResult) => ({
2811
+ type: DroidMessageType.Hook,
2812
+ hookId: notification.hookId,
2813
+ eventName: notification.hookEventName,
2814
+ matcher: notification.hookMatcher,
2815
+ toolCallId: notification.hookToolCallId,
2816
+ command: hookResult.command,
2817
+ timeout: hookResult.timeout,
2818
+ status: notification.hookStatus,
2819
+ exitCode: hookResult.exitCode,
2820
+ stdout: hookResult.stdout,
2821
+ stderr: hookResult.stderr
2822
+ }));
2823
+ case "structured_output" /* STRUCTURED_OUTPUT */:
2824
+ return {
2825
+ type: "structured_output",
2826
+ messageId: notification.messageId,
2827
+ structuredOutput: notification.structuredOutput,
2828
+ structuredOutputError: notification.structuredOutputError
2829
+ };
2675
2830
  default:
2676
2831
  return null;
2677
2832
  }
2678
2833
  }
2679
2834
  var StreamStateTracker = class {
2835
+ constructor(options = {}) {
2836
+ this.options = options;
2837
+ }
2680
2838
  hasBeenNonIdle = false;
2681
2839
  lastTokenUsage = null;
2840
+ fullText = "";
2841
+ finalAssistantText = "";
2842
+ structuredOutput = null;
2843
+ structuredOutputError = null;
2844
+ errors = [];
2845
+ numTurns = 0;
2846
+ emittedMessages = [];
2682
2847
  toolNameMap = /* @__PURE__ */ new Map();
2683
2848
  getToolName(toolUseId) {
2684
2849
  return this.toolNameMap.get(toolUseId) ?? "";
2685
2850
  }
2686
2851
  processMessage(message) {
2687
2852
  const additional = [];
2688
- if (message.type === DroidMessageType.ToolUse) {
2853
+ if (message.type === "tool_use") {
2689
2854
  this.toolNameMap.set(message.toolUseId, message.toolName);
2690
2855
  }
2856
+ if (message.type === DroidMessageType.ToolCall) {
2857
+ this.toolNameMap.set(message.toolUse.id, message.toolUse.name);
2858
+ }
2859
+ if (message.type === DroidMessageType.ToolCallDelta) {
2860
+ this.toolNameMap.set(message.toolUse.id, message.toolUse.name);
2861
+ }
2691
2862
  if (message.type === DroidMessageType.ToolResult) {
2692
2863
  message = { ...message, toolName: this.getToolName(message.toolUseId) };
2693
2864
  }
2865
+ if (message.type === DroidMessageType.AssistantTextDelta) {
2866
+ this.fullText += message.text;
2867
+ }
2868
+ if (message.type === DroidMessageType.Assistant) {
2869
+ this.finalAssistantText = message.text;
2870
+ if (this.fullText.length === 0) {
2871
+ this.fullText = message.text;
2872
+ }
2873
+ }
2694
2874
  if (message.type === DroidMessageType.TokenUsageUpdate) {
2695
2875
  this.lastTokenUsage = message;
2696
2876
  }
2877
+ if (message.type === DroidMessageType.Error) {
2878
+ this.errors.push(message);
2879
+ }
2880
+ if (message.type === "structured_output") {
2881
+ this.structuredOutput = message.structuredOutput;
2882
+ this.structuredOutputError = message.structuredOutputError;
2883
+ return { message: null, additional };
2884
+ }
2697
2885
  if (message.type === DroidMessageType.WorkingStateChanged) {
2698
2886
  if (message.state !== "idle" /* Idle */) {
2699
2887
  this.hasBeenNonIdle = true;
2700
2888
  } else if (this.hasBeenNonIdle) {
2701
- additional.push({
2702
- type: DroidMessageType.TurnComplete,
2703
- tokenUsage: this.lastTokenUsage
2704
- });
2889
+ this.numTurns++;
2890
+ additional.push(this.createResultMessage());
2705
2891
  this.hasBeenNonIdle = false;
2892
+ this.resetTurnState();
2706
2893
  }
2707
2894
  }
2895
+ if (message.type !== DroidMessageType.WorkingStateChanged) {
2896
+ this.trackEmittedMessage(message);
2897
+ }
2708
2898
  return { message, additional };
2709
2899
  }
2900
+ createResultMessage() {
2901
+ if (this.options.hasOutputFormat && this.structuredOutput === null && this.structuredOutputError === null) {
2902
+ this.structuredOutput = parseJsonObject(this.finalAssistantText || this.fullText) ?? null;
2903
+ }
2904
+ const tokenUsage = this.lastTokenUsage ? stripTokenUsageType(this.lastTokenUsage) : null;
2905
+ const result = this.finalAssistantText || this.fullText;
2906
+ const base = {
2907
+ type: DroidMessageType.Result,
2908
+ sessionId: this.options.sessionId ?? "",
2909
+ durationMs: Date.now() - (this.options.startedAt ?? Date.now()),
2910
+ numTurns: this.numTurns,
2911
+ result,
2912
+ tokenUsage,
2913
+ messages: [...this.emittedMessages],
2914
+ text: result,
2915
+ turnCount: this.numTurns
2916
+ };
2917
+ if (this.structuredOutputError) {
2918
+ return {
2919
+ ...base,
2920
+ subtype: "error_structured_output",
2921
+ isError: true,
2922
+ success: false,
2923
+ errors: [this.structuredOutputError.message],
2924
+ structuredOutput: this.structuredOutput,
2925
+ structuredOutputError: this.structuredOutputError,
2926
+ error: null
2927
+ };
2928
+ }
2929
+ if (this.errors.length > 0) {
2930
+ return {
2931
+ ...base,
2932
+ subtype: "error_during_execution",
2933
+ isError: true,
2934
+ success: false,
2935
+ errors: this.errors.map((error) => error.message),
2936
+ structuredOutput: this.structuredOutput,
2937
+ structuredOutputError: null,
2938
+ error: this.errors[0] ?? null
2939
+ };
2940
+ }
2941
+ return {
2942
+ ...base,
2943
+ subtype: "success",
2944
+ isError: false,
2945
+ success: true,
2946
+ structuredOutput: this.structuredOutput,
2947
+ structuredOutputError: null,
2948
+ error: null
2949
+ };
2950
+ }
2951
+ trackEmittedMessage(message) {
2952
+ if (isDefaultStreamMessage(message)) {
2953
+ this.emittedMessages.push(message);
2954
+ }
2955
+ }
2956
+ resetTurnState() {
2957
+ this.lastTokenUsage = null;
2958
+ this.fullText = "";
2959
+ this.finalAssistantText = "";
2960
+ this.structuredOutput = null;
2961
+ this.structuredOutputError = null;
2962
+ this.errors = [];
2963
+ this.emittedMessages = [];
2964
+ }
2710
2965
  };
2966
+ function isInternalMessage(message) {
2967
+ return message.type === "structured_output" || message.type === "tool_use" || message.type === "create_message";
2968
+ }
2969
+ function isDefaultStreamMessage(message) {
2970
+ 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;
2971
+ }
2972
+ function stripTokenUsageType(message) {
2973
+ const {
2974
+ inputTokens,
2975
+ outputTokens,
2976
+ cacheCreationTokens,
2977
+ cacheReadTokens,
2978
+ thinkingTokens
2979
+ } = message;
2980
+ return {
2981
+ inputTokens,
2982
+ outputTokens,
2983
+ cacheCreationTokens,
2984
+ cacheReadTokens,
2985
+ thinkingTokens
2986
+ };
2987
+ }
2988
+ function parseJsonObject(text) {
2989
+ try {
2990
+ const parsed = JSON.parse(text);
2991
+ const result = JsonObjectSchema.safeParse(parsed);
2992
+ return result.success ? result.data : null;
2993
+ } catch {
2994
+ return null;
2995
+ }
2996
+ }
2711
2997
  function normalizeToolResultContent(content) {
2712
2998
  if (content == null) {
2713
2999
  return "";
@@ -2720,6 +3006,9 @@ function normalizeToolResultContent(content) {
2720
3006
  }
2721
3007
  return String(content);
2722
3008
  }
3009
+ function extractTextFromMessage(message) {
3010
+ return message.content.filter((block) => block.type === "text").map((block) => block.text).join("");
3011
+ }
2723
3012
 
2724
3013
  // src/helpers.ts
2725
3014
  function wireAbortSignal(signal, onAbort) {
@@ -2735,15 +3024,88 @@ function wireAbortSignal(signal, onAbort) {
2735
3024
  return () => signal.removeEventListener("abort", listener);
2736
3025
  }
2737
3026
  }
3027
+ function getAbortError(signal) {
3028
+ if (signal.reason instanceof Error) {
3029
+ return signal.reason;
3030
+ }
3031
+ return new Error(
3032
+ typeof signal.reason === "string" ? signal.reason : "Operation aborted"
3033
+ );
3034
+ }
3035
+ function throwIfAborted(signal) {
3036
+ if (signal?.aborted) {
3037
+ throw getAbortError(signal);
3038
+ }
3039
+ }
3040
+ async function* streamFromClient(client, sessionId, activeBridges, prompt, options) {
3041
+ throwIfAborted(options?.abortSignal);
3042
+ const startedAt = Date.now();
3043
+ let resolveDone = () => {
3044
+ };
3045
+ const donePromise = new Promise((resolve2) => {
3046
+ resolveDone = resolve2;
3047
+ });
3048
+ const bridge = new MessageBridge(resolveDone, {
3049
+ includePartialMessages: options?.includePartialMessages,
3050
+ sessionId,
3051
+ startedAt,
3052
+ outputFormat: options?.outputFormat
3053
+ });
3054
+ activeBridges.add(bridge);
3055
+ const unsubscribe = client.onNotification(bridge.notificationHandler);
3056
+ let resolveAbort = () => {
3057
+ };
3058
+ const abortPromise = new Promise((resolve2) => {
3059
+ resolveAbort = resolve2;
3060
+ });
3061
+ const cleanupAbortSignal = wireAbortSignal(options?.abortSignal, () => {
3062
+ bridge.signalDone();
3063
+ resolveAbort();
3064
+ void client.interruptSession().catch(() => {
3065
+ });
3066
+ });
3067
+ try {
3068
+ await Promise.race([
3069
+ client.addUserMessage({
3070
+ text: prompt,
3071
+ images: options?.images,
3072
+ files: options?.files,
3073
+ outputFormat: options?.outputFormat
3074
+ }),
3075
+ donePromise,
3076
+ abortPromise
3077
+ ]);
3078
+ throwIfAborted(options?.abortSignal);
3079
+ for await (const msg of bridge.messages()) {
3080
+ throwIfAborted(options?.abortSignal);
3081
+ yield msg;
3082
+ }
3083
+ throwIfAborted(options?.abortSignal);
3084
+ } finally {
3085
+ cleanupAbortSignal();
3086
+ unsubscribe();
3087
+ activeBridges.delete(bridge);
3088
+ }
3089
+ }
2738
3090
  function extractInnerNotification(notification) {
2739
3091
  const parsed = SessionNotificationSchema.safeParse(notification);
2740
3092
  return parsed.success ? parsed.data.params.notification : null;
2741
3093
  }
2742
3094
  var MessageBridge = class {
3095
+ constructor(onDone, _options = {}) {
3096
+ this._options = _options;
3097
+ this._onDone = onDone;
3098
+ this._stateTracker = new StreamStateTracker({
3099
+ sessionId: _options.sessionId,
3100
+ startedAt: _options.startedAt,
3101
+ hasOutputFormat: _options.outputFormat !== void 0
3102
+ });
3103
+ }
2743
3104
  _queue = [];
3105
+ _onDone;
2744
3106
  _resolveWaiting = null;
2745
3107
  _done = false;
2746
- _stateTracker = new StreamStateTracker();
3108
+ _stateTracker;
2747
3109
  notificationHandler = (notification) => {
2748
3110
  const inner = extractInnerNotification(notification);
2749
3111
  if (!inner) return;
@@ -2752,10 +3114,14 @@ var MessageBridge = class {
2752
3114
  const messages = Array.isArray(converted) ? converted : [converted];
2753
3115
  for (const msg of messages) {
2754
3116
  const { message, additional } = this._stateTracker.processMessage(msg);
2755
- this._enqueue(message);
3117
+ if (message && this._shouldYield(message)) {
3118
+ this._enqueue(message);
3119
+ }
2756
3120
  for (const extra of additional) {
2757
- this._enqueue(extra);
2758
- if (extra.type === DroidMessageType.TurnComplete) {
3121
+ if (this._shouldYield(extra)) {
3122
+ this._enqueue(extra);
3123
+ }
3124
+ if (extra.type === DroidMessageType.Result) {
2759
3125
  this._signalDone();
2760
3126
  }
2761
3127
  }
@@ -2769,7 +3135,7 @@ var MessageBridge = class {
2769
3135
  while (this._queue.length > 0) {
2770
3136
  const msg = this._queue.shift();
2771
3137
  yield msg;
2772
- if (msg.type === DroidMessageType.TurnComplete) {
3138
+ if (msg.type === DroidMessageType.Result) {
2773
3139
  return;
2774
3140
  }
2775
3141
  }
@@ -2781,6 +3147,12 @@ var MessageBridge = class {
2781
3147
  });
2782
3148
  }
2783
3149
  }
3150
+ _shouldYield(message) {
3151
+ if (isInternalMessage(message)) {
3152
+ return false;
3153
+ }
3154
+ return this._options.includePartialMessages ? true : isDefaultStreamMessage(message);
3155
+ }
2784
3156
  _enqueue(msg) {
2785
3157
  this._queue.push(msg);
2786
3158
  if (this._resolveWaiting) {
@@ -2790,7 +3162,11 @@ var MessageBridge = class {
2790
3162
  }
2791
3163
  }
2792
3164
  _signalDone() {
3165
+ const wasDone = this._done;
2793
3166
  this._done = true;
3167
+ if (!wasDone) {
3168
+ this._onDone?.();
3169
+ }
2794
3170
  if (this._resolveWaiting) {
2795
3171
  const resolve2 = this._resolveWaiting;
2796
3172
  this._resolveWaiting = null;
@@ -2806,7 +3182,7 @@ async function createTransport(options) {
2806
3182
  execPath: options.execPath,
2807
3183
  execArgs: options.execArgs,
2808
3184
  cwd: options.cwd,
2809
- env: options.env
3185
+ env: { ...options.env, FACTORY_API_KEY: options.apiKey }
2810
3186
  };
2811
3187
  const processTransport = new ProcessTransport(transportOptions);
2812
3188
  await processTransport.connect();
@@ -2864,6 +3240,9 @@ function buildInitParams(options) {
2864
3240
  ...options.disabledToolIds !== void 0 && {
2865
3241
  disabledToolIds: options.disabledToolIds
2866
3242
  },
3243
+ ...options.sessionSource !== void 0 && {
3244
+ sessionSource: options.sessionSource
3245
+ },
2867
3246
  tags: [...options.tags ?? [], SDK_TAG]
2868
3247
  };
2869
3248
  }
@@ -2873,7 +3252,7 @@ import { once } from "events";
2873
3252
  import http from "http";
2874
3253
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2875
3254
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
2876
- import { z as z8 } from "zod";
3255
+ import { z as z9 } from "zod";
2877
3256
  function tool(name, description, inputSchemaOrHandler, handler) {
2878
3257
  if (typeof inputSchemaOrHandler === "function") {
2879
3258
  const actualHandler = inputSchemaOrHandler;
@@ -2886,7 +3265,7 @@ function tool(name, description, inputSchemaOrHandler, handler) {
2886
3265
  if (!handler) {
2887
3266
  throw new Error(`Missing handler for SDK MCP tool "${name}"`);
2888
3267
  }
2889
- const inputObjectSchema = z8.object(inputSchemaOrHandler);
3268
+ const inputObjectSchema = z9.object(inputSchemaOrHandler);
2890
3269
  return {
2891
3270
  name,
2892
3271
  description,
@@ -3063,312 +3442,44 @@ async function startSdkMcpServers(servers) {
3063
3442
  };
3064
3443
  }
3065
3444
 
3066
- // src/query.ts
3067
- var DroidQueryImpl = class {
3068
- _generator;
3069
- _getSessionId;
3070
- _getInitResult;
3071
- _getInitialized;
3072
- _interruptFn;
3073
- _abortFn;
3074
- constructor(generator, getSessionId, getInitResult, getInitialized, interruptFn, abortFn) {
3075
- this._generator = generator;
3076
- this._getSessionId = getSessionId;
3077
- this._getInitResult = getInitResult;
3078
- this._getInitialized = getInitialized;
3079
- this._interruptFn = interruptFn;
3080
- this._abortFn = abortFn;
3445
+ // src/session.ts
3446
+ var DroidSession = class {
3447
+ _client;
3448
+ _sessionId;
3449
+ _initResult;
3450
+ _closed = false;
3451
+ _cleanupAbortSignal = null;
3452
+ _cleanupCallbacks = [];
3453
+ _activeBridges = /* @__PURE__ */ new Set();
3454
+ /** @internal */
3455
+ constructor(client, sessionId, initResult) {
3456
+ this._client = client;
3457
+ this._sessionId = sessionId;
3458
+ this._initResult = initResult;
3081
3459
  }
3082
3460
  get sessionId() {
3083
- return this._getSessionId();
3461
+ return this._sessionId;
3084
3462
  }
3085
3463
  get initResult() {
3086
- return this._getInitResult();
3464
+ return this._initResult;
3087
3465
  }
3088
- get initialized() {
3089
- return this._getInitialized();
3466
+ /** @internal */
3467
+ setAbortSignalCleanup(cleanup) {
3468
+ this._cleanupAbortSignal = cleanup;
3090
3469
  }
3091
- async interrupt() {
3092
- return this._interruptFn();
3470
+ /** @internal */
3471
+ addCleanup(cleanup) {
3472
+ this._cleanupCallbacks.push(cleanup);
3093
3473
  }
3094
- abort() {
3095
- this._abortFn();
3096
- }
3097
- next(...args) {
3098
- return this._generator.next(...args);
3099
- }
3100
- return(value) {
3101
- return this._generator.return(value);
3102
- }
3103
- throw(e) {
3104
- return this._generator.throw(e);
3105
- }
3106
- [Symbol.asyncIterator]() {
3107
- return this;
3108
- }
3109
- };
3110
- function query(options) {
3111
- let transport = null;
3112
- let client = null;
3113
- let sessionId = null;
3114
- let initResult = null;
3115
- let aborted = false;
3116
- let initializationPromise = null;
3117
- let promptPromise = null;
3118
- let cleanupAbortSignal = () => {
3119
- };
3120
- let cleanupSdkMcpServers = null;
3121
- const bridge = new MessageBridge();
3122
- const closeActiveResources = async () => {
3123
- const closer = client ?? transport;
3124
- const cleanupMcp = cleanupSdkMcpServers;
3125
- client = null;
3126
- transport = null;
3127
- cleanupSdkMcpServers = null;
3128
- await Promise.all([closeQuietly(closer), cleanupMcp?.()]);
3129
- };
3130
- const ensureInitialized = () => {
3131
- if (initResult) {
3132
- return Promise.resolve(initResult);
3133
- }
3134
- if (initializationPromise) {
3135
- return initializationPromise;
3136
- }
3137
- initializationPromise = (async () => {
3138
- try {
3139
- if (aborted) {
3140
- throw new Error("Query aborted before initialization");
3141
- }
3142
- const configuredClient = await createConfiguredClient(options);
3143
- transport = configuredClient.transport;
3144
- client = configuredClient.client;
3145
- client.onNotification(bridge.notificationHandler);
3146
- if (aborted) {
3147
- throw new Error("Query aborted before initialization");
3148
- }
3149
- const sdkMcpServers = await startSdkMcpServers(options.mcpServers);
3150
- cleanupSdkMcpServers = sdkMcpServers.cleanup;
3151
- const result = await client.initializeSession(
3152
- buildInitParams({
3153
- ...options,
3154
- mcpServers: sdkMcpServers.mcpServers
3155
- })
3156
- );
3157
- sessionId = result.sessionId;
3158
- initResult = result;
3159
- return result;
3160
- } catch (error) {
3161
- await closeActiveResources();
3162
- throw error;
3163
- }
3164
- })();
3165
- return initializationPromise;
3166
- };
3167
- const ensurePromptSent = () => {
3168
- if (promptPromise) {
3169
- return promptPromise;
3170
- }
3171
- promptPromise = (async () => {
3172
- await ensureInitialized();
3173
- if (aborted || client === null) {
3174
- return;
3175
- }
3176
- await client.addUserMessage({ text: options.prompt });
3177
- })();
3178
- return promptPromise;
3179
- };
3180
- async function* generateMessages() {
3181
- if (aborted) return;
3182
- await ensurePromptSent();
3183
- if (aborted) return;
3184
- for await (const msg of bridge.messages()) {
3185
- if (aborted) return;
3186
- yield msg;
3187
- }
3188
- }
3189
- const generator = generateMessages();
3190
- async function* wrappedGenerator() {
3191
- try {
3192
- yield* generator;
3193
- } finally {
3194
- cleanupAbortSignal();
3195
- await closeActiveResources();
3196
- }
3197
- }
3198
- const droidQuery = new DroidQueryImpl(
3199
- wrappedGenerator(),
3200
- () => sessionId,
3201
- () => initResult,
3202
- () => ensureInitialized(),
3203
- async () => {
3204
- if (client && !aborted) {
3205
- await client.interruptSession();
3206
- }
3207
- },
3208
- () => {
3209
- aborted = true;
3210
- bridge.signalDone();
3211
- cleanupAbortSignal();
3212
- void closeActiveResources();
3213
- }
3214
- );
3215
- cleanupAbortSignal = wireAbortSignal(
3216
- options.abortSignal,
3217
- () => droidQuery.abort()
3218
- );
3219
- return droidQuery;
3220
- }
3221
-
3222
- // src/session.ts
3223
- function getAbortError(signal) {
3224
- if (signal.reason instanceof Error) {
3225
- return signal.reason;
3226
- }
3227
- return new Error(
3228
- typeof signal.reason === "string" ? signal.reason : "Operation aborted"
3229
- );
3230
- }
3231
- function throwIfAborted(signal) {
3232
- if (signal?.aborted) {
3233
- throw getAbortError(signal);
3234
- }
3235
- }
3236
- function parseJsonObject(text) {
3237
- try {
3238
- const parsed = JSON.parse(text);
3239
- const result = JsonObjectSchema.safeParse(parsed);
3240
- return result.success ? result.data : null;
3241
- } catch {
3242
- return null;
3243
- }
3244
- }
3245
- function extractAssistantText(message) {
3246
- if (message.type !== DroidMessageType.CreateMessage) {
3247
- return "";
3248
- }
3249
- if (message.role !== FactoryDroidMessageRole.Assistant) {
3250
- return "";
3251
- }
3252
- return message.content.filter((block) => block.type === "text").map((block) => block.text).join("");
3253
- }
3254
- var DroidSession = class {
3255
- _client;
3256
- _sessionId;
3257
- _initResult;
3258
- _closed = false;
3259
- _cleanupAbortSignal = null;
3260
- _cleanupCallbacks = [];
3261
- /** @internal */
3262
- constructor(client, sessionId, initResult) {
3263
- this._client = client;
3264
- this._sessionId = sessionId;
3265
- this._initResult = initResult;
3266
- }
3267
- get sessionId() {
3268
- return this._sessionId;
3269
- }
3270
- get initResult() {
3271
- return this._initResult;
3272
- }
3273
- /** @internal */
3274
- setAbortSignalCleanup(cleanup) {
3275
- this._cleanupAbortSignal = cleanup;
3276
- }
3277
- /** @internal */
3278
- addCleanup(cleanup) {
3279
- this._cleanupCallbacks.push(cleanup);
3280
- }
3281
- /** Yields {@link DroidMessage} events until `turn_complete`. */
3282
- async *stream(text, options) {
3283
- this._ensureNotClosed();
3284
- throwIfAborted(options?.abortSignal);
3285
- const bridge = new MessageBridge();
3286
- const unsubscribe = this._client.onNotification(bridge.notificationHandler);
3287
- let resolveAbort = () => {
3288
- };
3289
- const abortPromise = new Promise((resolve2) => {
3290
- resolveAbort = resolve2;
3291
- });
3292
- const cleanupAbortSignal = wireAbortSignal(options?.abortSignal, () => {
3293
- bridge.signalDone();
3294
- resolveAbort();
3295
- void this._client.interruptSession().catch(() => {
3296
- });
3297
- });
3298
- try {
3299
- await Promise.race([
3300
- this._client.addUserMessage({
3301
- text,
3302
- images: options?.images,
3303
- files: options?.files,
3304
- outputFormat: options?.outputFormat
3305
- }),
3306
- abortPromise
3307
- ]);
3308
- throwIfAborted(options?.abortSignal);
3309
- for await (const msg of bridge.messages()) {
3310
- throwIfAborted(options?.abortSignal);
3311
- yield msg;
3312
- }
3313
- throwIfAborted(options?.abortSignal);
3314
- } finally {
3315
- cleanupAbortSignal();
3316
- unsubscribe();
3317
- }
3318
- }
3319
- /** Consumes the stream and returns an aggregated {@link DroidResult}. */
3320
- async send(text, options) {
3474
+ async *stream(prompt, options) {
3321
3475
  this._ensureNotClosed();
3322
- const messages = [];
3323
- let fullText = "";
3324
- let lastTokenUsage = null;
3325
- let firstError = null;
3326
- let structuredOutput = null;
3327
- let finalAssistantText = "";
3328
- let turnCount = 0;
3329
- const startedAt = Date.now();
3330
- for await (const msg of this.stream(text, options)) {
3331
- messages.push(msg);
3332
- if (msg.type === DroidMessageType.AssistantTextDelta) {
3333
- fullText += msg.text;
3334
- }
3335
- const assistantText = extractAssistantText(msg);
3336
- if (assistantText) {
3337
- finalAssistantText = assistantText;
3338
- if (options?.outputFormat && fullText.length === 0) {
3339
- fullText = assistantText;
3340
- }
3341
- }
3342
- if (msg.type === DroidMessageType.TokenUsageUpdate) {
3343
- lastTokenUsage = msg;
3344
- }
3345
- if (msg.type === DroidMessageType.Error && firstError === null) {
3346
- firstError = msg;
3347
- }
3348
- if (options?.outputFormat && structuredOutput === null) {
3349
- const textToParse = finalAssistantText || fullText;
3350
- if (textToParse) {
3351
- structuredOutput = parseJsonObject(textToParse);
3352
- }
3353
- }
3354
- if (msg.type === DroidMessageType.TurnComplete) {
3355
- turnCount++;
3356
- if (msg.tokenUsage) {
3357
- lastTokenUsage = msg.tokenUsage;
3358
- }
3359
- }
3360
- }
3361
- return {
3362
- sessionId: this._sessionId,
3363
- text: fullText,
3364
- messages,
3365
- tokenUsage: lastTokenUsage,
3366
- durationMs: Date.now() - startedAt,
3367
- turnCount,
3368
- error: firstError,
3369
- structuredOutput,
3370
- success: firstError === null
3371
- };
3476
+ yield* streamFromClient(
3477
+ this._client,
3478
+ this._sessionId,
3479
+ this._activeBridges,
3480
+ prompt,
3481
+ options
3482
+ );
3372
3483
  }
3373
3484
  async interrupt() {
3374
3485
  this._ensureNotClosed();
@@ -3381,7 +3492,12 @@ var DroidSession = class {
3381
3492
  this._closed = true;
3382
3493
  this._cleanupAbortSignal?.();
3383
3494
  this._cleanupAbortSignal = null;
3495
+ for (const bridge of this._activeBridges) {
3496
+ bridge.signalDone();
3497
+ }
3384
3498
  try {
3499
+ await this._client.closeSession({ reason: "other" }).catch(() => {
3500
+ });
3385
3501
  await this._client.close();
3386
3502
  } finally {
3387
3503
  const cleanups = this._cleanupCallbacks.splice(0);
@@ -3466,7 +3582,7 @@ var DroidSession = class {
3466
3582
  }
3467
3583
  }
3468
3584
  };
3469
- async function createSession(options = {}) {
3585
+ async function createSession(options) {
3470
3586
  const { client } = await createConfiguredClient(options);
3471
3587
  let cleanupInitAbortSignal = options.abortSignal?.aborted ? () => {
3472
3588
  } : wireAbortSignal(options.abortSignal, () => {
@@ -3496,7 +3612,7 @@ async function createSession(options = {}) {
3496
3612
  throw error;
3497
3613
  }
3498
3614
  }
3499
- async function resumeSession(sessionId, options = {}) {
3615
+ async function resumeSession(sessionId, options) {
3500
3616
  const { client } = await createConfiguredClient(options);
3501
3617
  let sdkMcpServers;
3502
3618
  try {
@@ -3520,10 +3636,18 @@ async function resumeSession(sessionId, options = {}) {
3520
3636
  }
3521
3637
 
3522
3638
  // src/run.ts
3523
- async function run(text, options = {}) {
3639
+ async function run(prompt, options) {
3524
3640
  const session = await createSession(options);
3525
3641
  try {
3526
- return await session.send(text, options);
3642
+ for await (const msg of session.stream(prompt, {
3643
+ ...options,
3644
+ includePartialMessages: false
3645
+ })) {
3646
+ if (msg.type === DroidMessageType.Result) {
3647
+ return msg;
3648
+ }
3649
+ }
3650
+ throw new Error("Stream completed without a result message");
3527
3651
  } finally {
3528
3652
  await session.close();
3529
3653
  }
@@ -3752,6 +3876,1431 @@ async function listSessions(options = {}) {
3752
3876
  }
3753
3877
  return sorted;
3754
3878
  }
3879
+
3880
+ // src/api-types.ts
3881
+ import { z as z10 } from "zod";
3882
+ var EnvironmentVariableSchema = z10.object({
3883
+ key: z10.string(),
3884
+ value: z10.string()
3885
+ });
3886
+ var MachineTemplateBuildStatusSchema = z10.object({
3887
+ status: z10.enum(["building", "success", "failed"]),
3888
+ failureReason: z10.enum(["setup_script_error", "system_error"]).optional(),
3889
+ buildStartedAt: z10.number().int().optional(),
3890
+ builtAt: z10.number().int().optional(),
3891
+ logs: z10.string().optional()
3892
+ });
3893
+ var MachineTemplateSchema = z10.object({
3894
+ templateId: z10.string(),
3895
+ repoUrl: z10.string(),
3896
+ templateName: z10.string(),
3897
+ defaultBranch: z10.string(),
3898
+ createdBy: z10.string(),
3899
+ createdAt: z10.number().int().optional(),
3900
+ buildStatus: MachineTemplateBuildStatusSchema.optional(),
3901
+ lastUpdatedAt: z10.number().int().nullable().optional(),
3902
+ environmentVariables: z10.array(EnvironmentVariableSchema).optional(),
3903
+ userEnvironmentVariablesByUser: z10.array(EnvironmentVariableSchema).optional(),
3904
+ setupScript: z10.string().optional()
3905
+ });
3906
+ var MachineTemplateListResponseSchema = z10.object({
3907
+ templates: z10.array(MachineTemplateSchema),
3908
+ pagination: z10.object({
3909
+ hasMore: z10.boolean(),
3910
+ nextCursor: z10.string().nullable()
3911
+ })
3912
+ });
3913
+ var ComputerSchema = z10.object({
3914
+ id: z10.string(),
3915
+ name: z10.string(),
3916
+ hostname: z10.string().optional(),
3917
+ providerType: z10.enum(["byom", "e2b"]),
3918
+ status: z10.enum(["provisioning", "active", "error"]).optional(),
3919
+ createdAt: z10.number().int(),
3920
+ relayClientUrl: z10.string().optional(),
3921
+ remoteUser: z10.string().optional()
3922
+ }).passthrough();
3923
+ var ComputerListResponseSchema = z10.object({
3924
+ computers: z10.array(ComputerSchema)
3925
+ });
3926
+ var RefreshComputerResponseSchema = z10.object({
3927
+ configured: z10.number().int()
3928
+ });
3929
+ var ComputerMetricSchema = z10.object({
3930
+ timestamp: z10.string(),
3931
+ cpuUsedPct: z10.number(),
3932
+ cpuCount: z10.number(),
3933
+ memUsed: z10.number(),
3934
+ memTotal: z10.number(),
3935
+ diskUsed: z10.number(),
3936
+ diskTotal: z10.number()
3937
+ });
3938
+ var ComputerMetricsResponseSchema = z10.array(ComputerMetricSchema);
3939
+ var RemoteSessionSchema = z10.object({
3940
+ sessionId: z10.string(),
3941
+ title: z10.string().optional(),
3942
+ status: z10.enum(["idle", "pending", "running"]),
3943
+ messageCount: z10.number().int(),
3944
+ createdAt: z10.number().int(),
3945
+ updatedAt: z10.number().int(),
3946
+ completedAt: z10.number().int().optional(),
3947
+ computerId: z10.string().optional()
3948
+ });
3949
+ var RemoteSessionListResponseSchema = z10.object({
3950
+ sessions: z10.array(RemoteSessionSchema),
3951
+ pagination: z10.object({
3952
+ hasMore: z10.boolean(),
3953
+ nextCursor: z10.string().nullable()
3954
+ })
3955
+ });
3956
+
3957
+ // src/api.ts
3958
+ var DEFAULT_BASE_URL = "https://api.factory.ai";
3959
+ function extractErrorMessage(body, status) {
3960
+ if (isRecord(body) && typeof body["error"] === "string") {
3961
+ return body["error"];
3962
+ }
3963
+ return `Factory API error (status ${status})`;
3964
+ }
3965
+ async function factoryFetch(path3, apiKey, baseUrl, options) {
3966
+ const url = `${baseUrl ?? DEFAULT_BASE_URL}${path3}`;
3967
+ const method = options?.method ?? "GET";
3968
+ const headers = {
3969
+ Authorization: `Bearer ${apiKey}`,
3970
+ Accept: "application/json"
3971
+ };
3972
+ if (options?.body) {
3973
+ headers["Content-Type"] = "application/json";
3974
+ }
3975
+ let response;
3976
+ try {
3977
+ response = await fetch(url, {
3978
+ method,
3979
+ headers,
3980
+ ...options?.body ? { body: JSON.stringify(options.body) } : {}
3981
+ });
3982
+ } catch (error) {
3983
+ throw new ConnectionError(
3984
+ `Failed to reach Factory API: ${error instanceof Error ? error.message : String(error)}`
3985
+ );
3986
+ }
3987
+ if (response.status === 204) {
3988
+ return void 0;
3989
+ }
3990
+ let body;
3991
+ try {
3992
+ body = await response.json();
3993
+ } catch {
3994
+ throw new ProtocolError(
3995
+ `Factory API returned non-JSON response (status ${response.status})`
3996
+ );
3997
+ }
3998
+ if (!response.ok) {
3999
+ const message = extractErrorMessage(body, response.status);
4000
+ if (response.status === 401 || response.status === 403) {
4001
+ throw new ProtocolError(`Invalid or expired API key: ${message}`, {
4002
+ code: response.status
4003
+ });
4004
+ }
4005
+ throw new ProtocolError(message, { code: response.status });
4006
+ }
4007
+ return body;
4008
+ }
4009
+ function parseResponse(body, schema) {
4010
+ const parsed = schema.safeParse(body);
4011
+ if (!parsed.success) {
4012
+ throw new ProtocolError(
4013
+ `Unexpected response format from Factory API: ${parsed.error.message}`
4014
+ );
4015
+ }
4016
+ return parsed.data;
4017
+ }
4018
+ async function listMachineTemplates(options) {
4019
+ const params = new URLSearchParams();
4020
+ if (options.limit != null) {
4021
+ params.set("limit", String(options.limit));
4022
+ }
4023
+ if (options.cursor != null) {
4024
+ params.set("cursor", options.cursor);
4025
+ }
4026
+ const query = params.toString();
4027
+ const path3 = `/api/v0/machines/templates${query ? `?${query}` : ""}`;
4028
+ const body = await factoryFetch(path3, options.apiKey, options.baseUrl);
4029
+ return parseResponse(body, MachineTemplateListResponseSchema);
4030
+ }
4031
+ async function getMachineTemplate(options) {
4032
+ const path3 = `/api/v0/machines/templates/${encodeURIComponent(options.templateId)}`;
4033
+ const body = await factoryFetch(path3, options.apiKey, options.baseUrl);
4034
+ return parseResponse(body, MachineTemplateSchema);
4035
+ }
4036
+ async function listComputers(options) {
4037
+ const path3 = "/api/v0/computers";
4038
+ const body = await factoryFetch(path3, options.apiKey, options.baseUrl);
4039
+ return parseResponse(body, ComputerListResponseSchema);
4040
+ }
4041
+ async function getComputer(options) {
4042
+ const path3 = `/api/v0/computers/${encodeURIComponent(options.computerId)}`;
4043
+ const body = await factoryFetch(path3, options.apiKey, options.baseUrl);
4044
+ return parseResponse(body, ComputerSchema);
4045
+ }
4046
+ async function createComputer(options) {
4047
+ const path3 = "/api/v0/computers";
4048
+ const reqBody = {
4049
+ name: options.name,
4050
+ remoteUser: options.remoteUser
4051
+ };
4052
+ if (options.provider != null) reqBody["provider"] = options.provider;
4053
+ if (options.hostId != null) reqBody["hostId"] = options.hostId;
4054
+ if (options.repos != null) reqBody["repos"] = options.repos;
4055
+ if (options.autoInstallDeps != null)
4056
+ reqBody["autoInstallDeps"] = options.autoInstallDeps;
4057
+ if (options.serviceAccountId != null)
4058
+ reqBody["serviceAccountId"] = options.serviceAccountId;
4059
+ const body = await factoryFetch(path3, options.apiKey, options.baseUrl, {
4060
+ method: "POST",
4061
+ body: reqBody
4062
+ });
4063
+ return parseResponse(body, ComputerSchema);
4064
+ }
4065
+ async function getComputerByName(options) {
4066
+ const path3 = `/api/v0/computers/name/${encodeURIComponent(options.name)}`;
4067
+ const body = await factoryFetch(path3, options.apiKey, options.baseUrl);
4068
+ return parseResponse(body, ComputerSchema);
4069
+ }
4070
+ async function updateComputer(options) {
4071
+ const path3 = `/api/v0/computers/${encodeURIComponent(options.computerId)}`;
4072
+ const reqBody = {};
4073
+ if (options.name != null) reqBody["name"] = options.name;
4074
+ if (options.remoteUser != null) reqBody["remoteUser"] = options.remoteUser;
4075
+ if (options.hostId != null) reqBody["hostId"] = options.hostId;
4076
+ const body = await factoryFetch(path3, options.apiKey, options.baseUrl, {
4077
+ method: "PATCH",
4078
+ body: reqBody
4079
+ });
4080
+ return parseResponse(body, ComputerSchema);
4081
+ }
4082
+ async function deleteComputer(options) {
4083
+ const path3 = `/api/v0/computers/${encodeURIComponent(options.computerId)}`;
4084
+ await factoryFetch(path3, options.apiKey, options.baseUrl, {
4085
+ method: "DELETE"
4086
+ });
4087
+ }
4088
+ async function restartComputer(options) {
4089
+ const path3 = `/api/v0/computers/${encodeURIComponent(options.computerId)}/restart`;
4090
+ await factoryFetch(path3, options.apiKey, options.baseUrl, {
4091
+ method: "POST"
4092
+ });
4093
+ }
4094
+ async function refreshComputer(options) {
4095
+ const path3 = `/api/v0/computers/${encodeURIComponent(options.computerId)}/refresh`;
4096
+ const body = await factoryFetch(path3, options.apiKey, options.baseUrl, {
4097
+ method: "POST"
4098
+ });
4099
+ return parseResponse(body, RefreshComputerResponseSchema);
4100
+ }
4101
+ async function getComputerMetrics(options) {
4102
+ const params = new URLSearchParams();
4103
+ if (options.start != null) {
4104
+ params.set("start", options.start);
4105
+ }
4106
+ const query = params.toString();
4107
+ const path3 = `/api/v0/computers/${encodeURIComponent(options.computerId)}/metrics${query ? `?${query}` : ""}`;
4108
+ const body = await factoryFetch(path3, options.apiKey, options.baseUrl);
4109
+ return parseResponse(body, ComputerMetricsResponseSchema);
4110
+ }
4111
+ async function retryInstallDeps(options) {
4112
+ const path3 = `/api/v0/computers/${encodeURIComponent(options.computerId)}/install-deps`;
4113
+ const body = await factoryFetch(path3, options.apiKey, options.baseUrl, {
4114
+ method: "POST"
4115
+ });
4116
+ return parseResponse(body, ComputerSchema);
4117
+ }
4118
+ async function listRemoteSessions(options) {
4119
+ const params = new URLSearchParams();
4120
+ if (options.computerId != null) {
4121
+ params.set("computerId", options.computerId);
4122
+ }
4123
+ if (options.limit != null) {
4124
+ params.set("limit", String(options.limit));
4125
+ }
4126
+ if (options.cursor != null) {
4127
+ params.set("cursor", options.cursor);
4128
+ }
4129
+ const query = params.toString();
4130
+ const path3 = `/api/v0/sessions${query ? `?${query}` : ""}`;
4131
+ const body = await factoryFetch(path3, options.apiKey, options.baseUrl);
4132
+ return parseResponse(body, RemoteSessionListResponseSchema);
4133
+ }
4134
+
4135
+ // src/daemon/client.ts
4136
+ var DAEMON_SERVER_REQUEST_METHODS = {
4137
+ "daemon.request_permission": "permission" /* Permission */,
4138
+ "daemon.ask_user": "askUser" /* AskUser */
4139
+ };
4140
+ var DaemonClient = class {
4141
+ _engine;
4142
+ _apiKey;
4143
+ _sessionId = null;
4144
+ _closed = false;
4145
+ _notificationListeners = [];
4146
+ _permissionHandler = null;
4147
+ _askUserHandler = null;
4148
+ constructor(options) {
4149
+ this._apiKey = options.apiKey;
4150
+ this._engine = new ProtocolEngine({
4151
+ transport: options.transport,
4152
+ serverRequestMethodMap: DAEMON_SERVER_REQUEST_METHODS
4153
+ });
4154
+ this._engine.onNotification((notification) => {
4155
+ const normalized = notification["method"] === "daemon.session_notification" ? { ...notification, method: "droid.session_notification" } : notification;
4156
+ dispatchNotification(normalized, [...this._notificationListeners]);
4157
+ });
4158
+ this._engine.setPermissionHandler(
4159
+ (params) => this._dispatchPermissionRequest(params)
4160
+ );
4161
+ this._engine.setAskUserHandler(
4162
+ (params) => this._dispatchAskUserRequest(params)
4163
+ );
4164
+ }
4165
+ get sessionId() {
4166
+ return this._sessionId;
4167
+ }
4168
+ get isConnected() {
4169
+ return !this._closed && this._engine.isHealthy;
4170
+ }
4171
+ async initializeSession(params) {
4172
+ this._ensureNotClosed();
4173
+ const result = await this._rpc(
4174
+ "daemon.initialize_session" /* INITIALIZE_SESSION */,
4175
+ { ...params, token: this._apiKey },
4176
+ InitializeSessionResultSchema,
4177
+ SESSION_INIT_TIMEOUT
4178
+ );
4179
+ this._sessionId = result.sessionId;
4180
+ return result;
4181
+ }
4182
+ async loadSession(params) {
4183
+ this._ensureNotClosed();
4184
+ const result = await this._rpc(
4185
+ "daemon.load_session" /* LOAD_SESSION */,
4186
+ { ...params, token: this._apiKey },
4187
+ LoadSessionResultSchema,
4188
+ SESSION_INIT_TIMEOUT
4189
+ );
4190
+ this._sessionId = params.sessionId;
4191
+ return result;
4192
+ }
4193
+ async addUserMessage(params) {
4194
+ return this._sessionRpc(
4195
+ "daemon.add_user_message" /* ADD_USER_MESSAGE */,
4196
+ params,
4197
+ AddUserMessageResultSchema
4198
+ );
4199
+ }
4200
+ async interruptSession() {
4201
+ return this._sessionRpc(
4202
+ "daemon.interrupt_session" /* INTERRUPT_SESSION */,
4203
+ {},
4204
+ InterruptSessionResultSchema
4205
+ );
4206
+ }
4207
+ async closeSession(params = {}) {
4208
+ return this._sessionRpc(
4209
+ "daemon.close_session" /* CLOSE_SESSION */,
4210
+ params,
4211
+ CloseSessionResultSchema
4212
+ );
4213
+ }
4214
+ async updateSessionSettings(params) {
4215
+ return this._sessionRpc(
4216
+ "daemon.update_session_settings" /* UPDATE_SESSION_SETTINGS */,
4217
+ params,
4218
+ UpdateSessionSettingsResultSchema
4219
+ );
4220
+ }
4221
+ async compactSession(params = {}) {
4222
+ return this._sessionRpc(
4223
+ "daemon.compact_session" /* COMPACT_SESSION */,
4224
+ params,
4225
+ CompactSessionResultSchema,
4226
+ COMPACTION_TIMEOUT
4227
+ );
4228
+ }
4229
+ async forkSession() {
4230
+ return this._sessionRpc(
4231
+ "daemon.fork_session" /* FORK_SESSION */,
4232
+ {},
4233
+ ForkSessionResultSchema
4234
+ );
4235
+ }
4236
+ async getContextBreakdown() {
4237
+ return this._sessionRpc(
4238
+ "daemon.get_context_breakdown" /* GET_CONTEXT_STATS */,
4239
+ {},
4240
+ ContextBreakdownResultSchema
4241
+ );
4242
+ }
4243
+ async renameSession(params) {
4244
+ return this._sessionRpc(
4245
+ "daemon.rename_session" /* RENAME_SESSION */,
4246
+ params,
4247
+ RenameSessionResultSchema
4248
+ );
4249
+ }
4250
+ async getRewindInfo(params) {
4251
+ return this._sessionRpc(
4252
+ "daemon.get_rewind_info" /* GET_REWIND_INFO */,
4253
+ params,
4254
+ GetRewindInfoResultSchema,
4255
+ REWIND_TIMEOUT
4256
+ );
4257
+ }
4258
+ async executeRewind(params) {
4259
+ return this._sessionRpc(
4260
+ "daemon.execute_rewind" /* EXECUTE_REWIND */,
4261
+ params,
4262
+ ExecuteRewindResultSchema,
4263
+ REWIND_TIMEOUT
4264
+ );
4265
+ }
4266
+ async addMcpServer(params) {
4267
+ return this._sessionRpc(
4268
+ "daemon.add_mcp_server" /* ADD_MCP_SERVER */,
4269
+ params,
4270
+ AddMcpServerResultSchema
4271
+ );
4272
+ }
4273
+ async removeMcpServer(params) {
4274
+ return this._sessionRpc(
4275
+ "daemon.remove_mcp_server" /* REMOVE_MCP_SERVER */,
4276
+ params,
4277
+ RemoveMcpServerResultSchema
4278
+ );
4279
+ }
4280
+ async toggleMcpServer(params) {
4281
+ return this._sessionRpc(
4282
+ "daemon.toggle_mcp_server" /* TOGGLE_MCP_SERVER */,
4283
+ params,
4284
+ ToggleMcpServerResultSchema
4285
+ );
4286
+ }
4287
+ async listMcpServers() {
4288
+ return this._sessionRpc(
4289
+ "daemon.list_mcp_servers" /* LIST_MCP_SERVERS */,
4290
+ {},
4291
+ ListMcpServersResultSchema
4292
+ );
4293
+ }
4294
+ async listMcpTools() {
4295
+ return this._sessionRpc(
4296
+ "daemon.list_mcp_tools" /* LIST_MCP_TOOLS */,
4297
+ {},
4298
+ ListMcpToolsResultSchema
4299
+ );
4300
+ }
4301
+ async authenticateMcpServer(params) {
4302
+ return this._sessionRpc(
4303
+ "daemon.authenticate_mcp_server" /* AUTHENTICATE_MCP_SERVER */,
4304
+ params,
4305
+ AuthenticateMcpServerResultSchema
4306
+ );
4307
+ }
4308
+ async listSkills() {
4309
+ return this._sessionRpc(
4310
+ "daemon.list_skills" /* LIST_SKILLS */,
4311
+ {},
4312
+ ListSkillsResultSchema
4313
+ );
4314
+ }
4315
+ onNotification(callback, filter) {
4316
+ const entry = { callback, filter };
4317
+ this._notificationListeners.push(entry);
4318
+ let unsubscribed = false;
4319
+ return () => {
4320
+ if (!unsubscribed) {
4321
+ unsubscribed = true;
4322
+ const idx = this._notificationListeners.indexOf(entry);
4323
+ if (idx !== -1) {
4324
+ this._notificationListeners.splice(idx, 1);
4325
+ }
4326
+ }
4327
+ };
4328
+ }
4329
+ setPermissionHandler(handler) {
4330
+ this._permissionHandler = handler;
4331
+ }
4332
+ setAskUserHandler(handler) {
4333
+ this._askUserHandler = handler;
4334
+ }
4335
+ async close() {
4336
+ if (this._closed) {
4337
+ return;
4338
+ }
4339
+ this._closed = true;
4340
+ this._notificationListeners.length = 0;
4341
+ this._permissionHandler = null;
4342
+ this._askUserHandler = null;
4343
+ await this._engine.close();
4344
+ }
4345
+ async _rpc(method, params, schema, timeout) {
4346
+ const raw = await this._engine.sendRequest(method, params, timeout);
4347
+ return schema.parse(raw);
4348
+ }
4349
+ async _sessionRpc(method, params, schema, timeout) {
4350
+ this._ensureNotClosed();
4351
+ this._ensureSession();
4352
+ return this._rpc(
4353
+ method,
4354
+ { sessionId: this._sessionId, ...params },
4355
+ schema,
4356
+ timeout
4357
+ );
4358
+ }
4359
+ _dispatchPermissionRequest(params) {
4360
+ const handler = this._permissionHandler;
4361
+ if (handler == null) {
4362
+ return "cancel" /* Cancel */;
4363
+ }
4364
+ return handler(params);
4365
+ }
4366
+ _dispatchAskUserRequest(params) {
4367
+ const handler = this._askUserHandler;
4368
+ if (handler == null) {
4369
+ return { cancelled: true, answers: [] };
4370
+ }
4371
+ return handler(params);
4372
+ }
4373
+ _ensureNotClosed() {
4374
+ if (this._closed) {
4375
+ throw new ConnectionError(
4376
+ "Daemon client has been closed. Create a new DaemonClient instance."
4377
+ );
4378
+ }
4379
+ }
4380
+ _ensureSession() {
4381
+ if (this._sessionId == null) {
4382
+ throw new SessionError(
4383
+ "No active session. Call initializeSession or loadSession first."
4384
+ );
4385
+ }
4386
+ }
4387
+ };
4388
+
4389
+ // src/daemon/local.ts
4390
+ import { spawn as spawn2 } from "child_process";
4391
+ import * as fs2 from "fs";
4392
+ import * as net from "net";
4393
+ import * as os2 from "os";
4394
+ import * as path2 from "path";
4395
+ var SOCKET_TIMEOUT_MS = 2e3;
4396
+ var STARTUP_POLL_INTERVAL_MS = 250;
4397
+ var STARTUP_TIMEOUT_MS = 3e4;
4398
+ var MAX_STARTUP_ATTEMPTS = 3;
4399
+ var FACTORY_DIR = ".factory";
4400
+ var DEFAULT_PORT = 37643;
4401
+ var DAEMON_PORT_FILE = "daemon.port";
4402
+ var DEFAULT_HOST = "127.0.0.1";
4403
+ var spawnedDaemonProcess = null;
4404
+ var daemonTarget = null;
4405
+ var daemonEnsureInflight = null;
4406
+ function getFactoryHome() {
4407
+ return process.env.FACTORY_HOME_OVERRIDE || os2.homedir();
4408
+ }
4409
+ function getFactoryDirName() {
4410
+ return FACTORY_DIR;
4411
+ }
4412
+ function getFactoryDir() {
4413
+ return path2.join(getFactoryHome(), getFactoryDirName());
4414
+ }
4415
+ function getSdkDir() {
4416
+ return path2.join(getFactoryDir(), "sdk");
4417
+ }
4418
+ function getDefaultDaemonPort() {
4419
+ return DEFAULT_PORT;
4420
+ }
4421
+ function resolveExecPath() {
4422
+ const override = process.env.FACTORY_DROID_BINARY?.trim();
4423
+ if (override && override.length > 0) {
4424
+ if (override.includes("/") || override.includes("\\")) {
4425
+ try {
4426
+ fs2.accessSync(override, fs2.constants.X_OK);
4427
+ return override;
4428
+ } catch {
4429
+ }
4430
+ } else {
4431
+ return override;
4432
+ }
4433
+ }
4434
+ return "droid";
4435
+ }
4436
+ async function allocatePort() {
4437
+ return new Promise((resolve2, reject) => {
4438
+ const server = net.createServer();
4439
+ server.once("error", reject);
4440
+ server.listen(0, DEFAULT_HOST, () => {
4441
+ const address = server.address();
4442
+ if (!address || typeof address === "string") {
4443
+ server.close();
4444
+ reject(new Error("Failed to determine dynamic port"));
4445
+ return;
4446
+ }
4447
+ const port = address.port;
4448
+ server.close((err) => {
4449
+ if (err) reject(err);
4450
+ else resolve2(port);
4451
+ });
4452
+ });
4453
+ });
4454
+ }
4455
+ async function isDaemonReachable(port) {
4456
+ return new Promise((resolve2) => {
4457
+ const socket = net.createConnection({ host: DEFAULT_HOST, port });
4458
+ const cleanup = () => {
4459
+ socket.removeAllListeners();
4460
+ socket.destroy();
4461
+ };
4462
+ const fail = () => {
4463
+ cleanup();
4464
+ resolve2(false);
4465
+ };
4466
+ socket.setTimeout(SOCKET_TIMEOUT_MS, fail);
4467
+ socket.once("error", fail);
4468
+ socket.once("connect", () => {
4469
+ cleanup();
4470
+ resolve2(true);
4471
+ });
4472
+ });
4473
+ }
4474
+ async function waitForDaemonReady(child, port, timeoutMs = STARTUP_TIMEOUT_MS) {
4475
+ return new Promise((resolve2) => {
4476
+ let settled = false;
4477
+ let exited = false;
4478
+ const deadline = Date.now() + timeoutMs;
4479
+ const settle = (result) => {
4480
+ if (settled) return;
4481
+ settled = true;
4482
+ child.removeListener("exit", onExit);
4483
+ child.removeListener("error", onExit);
4484
+ resolve2(result);
4485
+ };
4486
+ const onExit = () => {
4487
+ exited = true;
4488
+ settle("exited");
4489
+ };
4490
+ child.once("exit", onExit);
4491
+ child.once("error", onExit);
4492
+ const poll = async () => {
4493
+ while (!exited && !settled) {
4494
+ if (await isDaemonReachable(port)) {
4495
+ settle("ready");
4496
+ return;
4497
+ }
4498
+ if (Date.now() >= deadline) {
4499
+ settle("timeout");
4500
+ return;
4501
+ }
4502
+ await new Promise((r) => setTimeout(r, STARTUP_POLL_INTERVAL_MS));
4503
+ }
4504
+ };
4505
+ void poll();
4506
+ });
4507
+ }
4508
+ function readPortFile() {
4509
+ try {
4510
+ const portPath = path2.join(getSdkDir(), DAEMON_PORT_FILE);
4511
+ const content = fs2.readFileSync(portPath, "utf-8").trim();
4512
+ const port = parseInt(content, 10);
4513
+ if (Number.isFinite(port) && port > 0 && port < 65536) {
4514
+ return port;
4515
+ }
4516
+ return null;
4517
+ } catch {
4518
+ return null;
4519
+ }
4520
+ }
4521
+ function writePortFile(port) {
4522
+ try {
4523
+ const sdkDir = getSdkDir();
4524
+ fs2.mkdirSync(sdkDir, { recursive: true });
4525
+ fs2.writeFileSync(path2.join(sdkDir, DAEMON_PORT_FILE), String(port), {
4526
+ mode: 384
4527
+ });
4528
+ } catch {
4529
+ }
4530
+ }
4531
+ function cacheTarget(port) {
4532
+ daemonTarget = { host: DEFAULT_HOST, port };
4533
+ return { port };
4534
+ }
4535
+ function clearSpawnedDaemonProcess(child) {
4536
+ if (spawnedDaemonProcess === child) {
4537
+ spawnedDaemonProcess = null;
4538
+ }
4539
+ }
4540
+ async function spawnDaemon(execPath, port) {
4541
+ const args = ["daemon", "--host", DEFAULT_HOST, "--port", String(port)];
4542
+ let stderrFd;
4543
+ try {
4544
+ const logsDir = path2.join(getSdkDir(), "logs");
4545
+ fs2.mkdirSync(logsDir, { recursive: true });
4546
+ stderrFd = fs2.openSync(path2.join(logsDir, "daemon-stderr.log"), "a");
4547
+ } catch {
4548
+ }
4549
+ const child = spawn2(execPath, args, {
4550
+ detached: true,
4551
+ stdio: ["ignore", "ignore", stderrFd ?? "ignore"],
4552
+ cwd: os2.homedir(),
4553
+ env: { ...process.env }
4554
+ });
4555
+ if (stderrFd !== void 0) {
4556
+ try {
4557
+ fs2.closeSync(stderrFd);
4558
+ } catch {
4559
+ }
4560
+ }
4561
+ spawnedDaemonProcess = child;
4562
+ child.unref();
4563
+ child.once("exit", () => {
4564
+ clearSpawnedDaemonProcess(child);
4565
+ });
4566
+ child.on("error", () => {
4567
+ clearSpawnedDaemonProcess(child);
4568
+ });
4569
+ const result = await waitForDaemonReady(child, port);
4570
+ if (result !== "ready") {
4571
+ clearSpawnedDaemonProcess(child);
4572
+ if (result === "timeout") {
4573
+ try {
4574
+ child.kill("SIGTERM");
4575
+ } catch {
4576
+ }
4577
+ }
4578
+ }
4579
+ return result;
4580
+ }
4581
+ async function _ensureLocalDaemon() {
4582
+ const execPath = resolveExecPath();
4583
+ const wellKnownPort = getDefaultDaemonPort();
4584
+ if (await isDaemonReachable(wellKnownPort)) {
4585
+ return cacheTarget(wellKnownPort);
4586
+ }
4587
+ const portFilePort = readPortFile();
4588
+ if (portFilePort !== null && portFilePort !== wellKnownPort) {
4589
+ if (await isDaemonReachable(portFilePort)) {
4590
+ return cacheTarget(portFilePort);
4591
+ }
4592
+ }
4593
+ const firstResult = await spawnDaemon(execPath, wellKnownPort);
4594
+ if (firstResult === "ready") {
4595
+ writePortFile(wellKnownPort);
4596
+ return cacheTarget(wellKnownPort);
4597
+ }
4598
+ for (let attempt = 2; attempt <= MAX_STARTUP_ATTEMPTS; attempt++) {
4599
+ const port = await allocatePort();
4600
+ const result = await spawnDaemon(execPath, port);
4601
+ if (result === "ready") {
4602
+ writePortFile(port);
4603
+ return cacheTarget(port);
4604
+ }
4605
+ }
4606
+ throw new ConnectionError(
4607
+ `Failed to start local droid daemon after ${MAX_STARTUP_ATTEMPTS} attempts. Ensure the \`droid\` CLI is installed and \`droid auth login\` has been run.`
4608
+ );
4609
+ }
4610
+ async function ensureLocalDaemon() {
4611
+ if (daemonTarget) {
4612
+ if (await isDaemonReachable(daemonTarget.port)) {
4613
+ return { port: daemonTarget.port };
4614
+ }
4615
+ daemonTarget = null;
4616
+ }
4617
+ if (!daemonEnsureInflight) {
4618
+ daemonEnsureInflight = _ensureLocalDaemon().finally(() => {
4619
+ daemonEnsureInflight = null;
4620
+ });
4621
+ }
4622
+ return daemonEnsureInflight;
4623
+ }
4624
+
4625
+ // src/daemon/session.ts
4626
+ var DaemonSession = class {
4627
+ _client;
4628
+ _sessionId;
4629
+ _closed = false;
4630
+ _activeBridges = /* @__PURE__ */ new Set();
4631
+ _cleanupCallbacks = [];
4632
+ /** @internal */
4633
+ constructor(client, sessionId) {
4634
+ this._client = client;
4635
+ this._sessionId = sessionId;
4636
+ }
4637
+ /** @internal */
4638
+ addCleanup(cleanup) {
4639
+ this._cleanupCallbacks.push(cleanup);
4640
+ }
4641
+ get sessionId() {
4642
+ return this._sessionId;
4643
+ }
4644
+ async *stream(prompt, options) {
4645
+ this._ensureNotClosed();
4646
+ yield* streamFromClient(
4647
+ this._client,
4648
+ this._sessionId,
4649
+ this._activeBridges,
4650
+ prompt,
4651
+ options
4652
+ );
4653
+ }
4654
+ async send(prompt, options) {
4655
+ this._ensureNotClosed();
4656
+ await this._client.addUserMessage({
4657
+ text: prompt,
4658
+ images: options?.images,
4659
+ files: options?.files,
4660
+ outputFormat: options?.outputFormat
4661
+ });
4662
+ }
4663
+ async interrupt() {
4664
+ this._ensureNotClosed();
4665
+ await this._client.interruptSession();
4666
+ }
4667
+ async close() {
4668
+ if (this._closed) {
4669
+ return;
4670
+ }
4671
+ this._closed = true;
4672
+ for (const bridge of this._activeBridges) {
4673
+ bridge.signalDone();
4674
+ }
4675
+ try {
4676
+ await this._client.closeSession({ reason: "other" }).catch(() => {
4677
+ });
4678
+ } finally {
4679
+ await this._client.close();
4680
+ for (const cleanup of this._cleanupCallbacks) {
4681
+ try {
4682
+ await cleanup();
4683
+ } catch {
4684
+ }
4685
+ }
4686
+ this._cleanupCallbacks.length = 0;
4687
+ }
4688
+ }
4689
+ async updateSettings(params) {
4690
+ this._ensureNotClosed();
4691
+ return this._client.updateSessionSettings(params);
4692
+ }
4693
+ async enterSpecMode(params = {}) {
4694
+ this._ensureNotClosed();
4695
+ return this._client.updateSessionSettings({
4696
+ interactionMode: "spec" /* Spec */,
4697
+ ...params
4698
+ });
4699
+ }
4700
+ async compactSession(params) {
4701
+ this._ensureNotClosed();
4702
+ return this._client.compactSession(params ?? {});
4703
+ }
4704
+ async forkSession() {
4705
+ this._ensureNotClosed();
4706
+ return this._client.forkSession();
4707
+ }
4708
+ async getContextBreakdown() {
4709
+ this._ensureNotClosed();
4710
+ return this._client.getContextBreakdown();
4711
+ }
4712
+ async renameSession(params) {
4713
+ this._ensureNotClosed();
4714
+ return this._client.renameSession(params);
4715
+ }
4716
+ async getRewindInfo(params) {
4717
+ this._ensureNotClosed();
4718
+ return this._client.getRewindInfo(params);
4719
+ }
4720
+ async executeRewind(params) {
4721
+ this._ensureNotClosed();
4722
+ return this._client.executeRewind(params);
4723
+ }
4724
+ async addMcpServer(params) {
4725
+ this._ensureNotClosed();
4726
+ return this._client.addMcpServer(params);
4727
+ }
4728
+ async removeMcpServer(params) {
4729
+ this._ensureNotClosed();
4730
+ return this._client.removeMcpServer(params);
4731
+ }
4732
+ async toggleMcpServer(params) {
4733
+ this._ensureNotClosed();
4734
+ return this._client.toggleMcpServer(params);
4735
+ }
4736
+ async listMcpServers() {
4737
+ this._ensureNotClosed();
4738
+ return this._client.listMcpServers();
4739
+ }
4740
+ async listMcpTools() {
4741
+ this._ensureNotClosed();
4742
+ return this._client.listMcpTools();
4743
+ }
4744
+ async authenticateMcpServer(params) {
4745
+ this._ensureNotClosed();
4746
+ return this._client.authenticateMcpServer(params);
4747
+ }
4748
+ async listSkills() {
4749
+ this._ensureNotClosed();
4750
+ return this._client.listSkills();
4751
+ }
4752
+ onNotification(callback, filter) {
4753
+ return this._client.onNotification(callback, filter);
4754
+ }
4755
+ _ensureNotClosed() {
4756
+ if (this._closed) {
4757
+ throw new ConnectionError(
4758
+ "Daemon session has been closed. Create a new session to continue."
4759
+ );
4760
+ }
4761
+ }
4762
+ };
4763
+
4764
+ // src/daemon/transport.ts
4765
+ import WebSocket from "ws";
4766
+
4767
+ // src/daemon/types.ts
4768
+ var MachineType = /* @__PURE__ */ ((MachineType2) => {
4769
+ MachineType2["Local"] = "local";
4770
+ MachineType2["Computer"] = "computer";
4771
+ return MachineType2;
4772
+ })(MachineType || {});
4773
+ var DEFAULT_DAEMON_PORT = 37643;
4774
+ var DEFAULT_RELAY_BASE_URL = "wss://relay.factory.ai";
4775
+ var DEFAULT_WS_CONFIG = {
4776
+ maxConnectRetries: 5,
4777
+ initialRetryDelayMs: 500,
4778
+ maxRetryDelayMs: 5e3,
4779
+ connectionTimeoutMs: 5e3
4780
+ };
4781
+ var COMPUTER_WS_CONFIG = {
4782
+ connectionTimeoutMs: 45e3,
4783
+ maxConnectRetries: 10,
4784
+ initialRetryDelayMs: 2e3,
4785
+ maxRetryDelayMs: 1e4
4786
+ };
4787
+
4788
+ // src/daemon/transport.ts
4789
+ var WebSocketTransport = class {
4790
+ maxConnectRetries;
4791
+ initialRetryDelayMs;
4792
+ maxRetryDelayMs;
4793
+ connectionTimeoutMs;
4794
+ ws = null;
4795
+ messageHandler = null;
4796
+ errorHandler = null;
4797
+ _isConnected = false;
4798
+ isClosing = false;
4799
+ constructor(options = {}) {
4800
+ this.maxConnectRetries = options.maxConnectRetries ?? DEFAULT_WS_CONFIG.maxConnectRetries;
4801
+ this.initialRetryDelayMs = options.initialRetryDelayMs ?? DEFAULT_WS_CONFIG.initialRetryDelayMs;
4802
+ this.maxRetryDelayMs = options.maxRetryDelayMs ?? DEFAULT_WS_CONFIG.maxRetryDelayMs;
4803
+ this.connectionTimeoutMs = options.connectionTimeoutMs ?? DEFAULT_WS_CONFIG.connectionTimeoutMs;
4804
+ }
4805
+ get isConnected() {
4806
+ return this._isConnected;
4807
+ }
4808
+ async connect(url) {
4809
+ if (!url) {
4810
+ throw new ConnectionError("WebSocket URL is required");
4811
+ }
4812
+ if (this._isConnected) {
4813
+ throw new ConnectionError("Transport already connected");
4814
+ }
4815
+ this.isClosing = false;
4816
+ let lastError;
4817
+ for (let attempt = 0; attempt <= this.maxConnectRetries; attempt++) {
4818
+ try {
4819
+ await this._doConnect(url);
4820
+ return;
4821
+ } catch (error) {
4822
+ lastError = error instanceof Error ? error : new Error(String(error));
4823
+ if (attempt < this.maxConnectRetries) {
4824
+ const delay = Math.min(
4825
+ this.initialRetryDelayMs * 2 ** attempt,
4826
+ this.maxRetryDelayMs
4827
+ );
4828
+ await new Promise((resolve2) => setTimeout(resolve2, delay));
4829
+ }
4830
+ }
4831
+ }
4832
+ throw lastError;
4833
+ }
4834
+ send(message) {
4835
+ if (!this._isConnected || !this.ws) {
4836
+ throw new ConnectionError("WebSocket transport not connected");
4837
+ }
4838
+ try {
4839
+ this.ws.send(JSON.stringify(message));
4840
+ } catch (error) {
4841
+ const msg = error instanceof Error ? error.message : String(error);
4842
+ throw new ConnectionError(`Failed to send WebSocket message: ${msg}`);
4843
+ }
4844
+ }
4845
+ onMessage(callback) {
4846
+ this.messageHandler = callback;
4847
+ }
4848
+ onError(callback) {
4849
+ this.errorHandler = callback;
4850
+ }
4851
+ async close() {
4852
+ if (this.isClosing) {
4853
+ return;
4854
+ }
4855
+ this.isClosing = true;
4856
+ this._isConnected = false;
4857
+ const ws = this.ws;
4858
+ this.ws = null;
4859
+ if (ws && ws.readyState === WebSocket.OPEN) {
4860
+ await new Promise((resolve2) => {
4861
+ ws.once("close", () => resolve2());
4862
+ ws.close(1e3, "Client disconnect");
4863
+ setTimeout(() => resolve2(), 5e3);
4864
+ });
4865
+ }
4866
+ this.isClosing = false;
4867
+ }
4868
+ async _doConnect(url) {
4869
+ return new Promise((resolve2, reject) => {
4870
+ let settled = false;
4871
+ let timeoutId = null;
4872
+ const cleanup = () => {
4873
+ if (timeoutId) {
4874
+ clearTimeout(timeoutId);
4875
+ timeoutId = null;
4876
+ }
4877
+ };
4878
+ const ws = new WebSocket(url);
4879
+ const handleOpen = () => {
4880
+ if (settled) return;
4881
+ settled = true;
4882
+ cleanup();
4883
+ this.ws = ws;
4884
+ this._isConnected = true;
4885
+ this._setupOngoingHandlers(ws);
4886
+ resolve2();
4887
+ };
4888
+ const handleError = (error) => {
4889
+ if (settled) return;
4890
+ settled = true;
4891
+ cleanup();
4892
+ try {
4893
+ ws.close();
4894
+ } catch {
4895
+ }
4896
+ reject(
4897
+ new ConnectionError(`WebSocket connection failed: ${error.message}`)
4898
+ );
4899
+ };
4900
+ const handleClose = (code, reason) => {
4901
+ if (settled) return;
4902
+ settled = true;
4903
+ cleanup();
4904
+ reject(
4905
+ new ConnectionError(
4906
+ `WebSocket closed before opening (code: ${code}, reason: ${reason.toString()})`
4907
+ )
4908
+ );
4909
+ };
4910
+ ws.once("open", handleOpen);
4911
+ ws.once("error", handleError);
4912
+ ws.once("close", handleClose);
4913
+ timeoutId = setTimeout(() => {
4914
+ if (settled) return;
4915
+ settled = true;
4916
+ try {
4917
+ ws.close();
4918
+ } catch {
4919
+ }
4920
+ reject(
4921
+ new ConnectionError(
4922
+ `WebSocket connection timeout after ${this.connectionTimeoutMs}ms: ${url}`
4923
+ )
4924
+ );
4925
+ }, this.connectionTimeoutMs);
4926
+ });
4927
+ }
4928
+ _setupOngoingHandlers(ws) {
4929
+ ws.on("message", (data) => {
4930
+ if (!this.messageHandler) return;
4931
+ const text = typeof data === "string" ? data : data.toString();
4932
+ try {
4933
+ const parsed = JSON.parse(text);
4934
+ if (isRecord(parsed)) {
4935
+ this.messageHandler(parsed);
4936
+ }
4937
+ } catch {
4938
+ }
4939
+ });
4940
+ ws.on("error", (error) => {
4941
+ if (!this.isClosing && this.errorHandler) {
4942
+ this.errorHandler(
4943
+ new ConnectionError(`WebSocket error: ${error.message}`)
4944
+ );
4945
+ }
4946
+ });
4947
+ ws.on("close", (code, reason) => {
4948
+ this._isConnected = false;
4949
+ this.ws = null;
4950
+ if (!this.isClosing && this.errorHandler) {
4951
+ this.errorHandler(
4952
+ new ConnectionError(
4953
+ `WebSocket closed (code: ${code}, reason: ${reason.toString()})`
4954
+ )
4955
+ );
4956
+ }
4957
+ });
4958
+ }
4959
+ };
4960
+
4961
+ // src/daemon/connection.ts
4962
+ var DAEMON_AUTHENTICATE_METHOD = "daemon.authenticate";
4963
+ var DAEMON_AUTHENTICATE_TIMEOUT = 3e4;
4964
+ var SDK_CALLER = "droid-sdk";
4965
+ function resolveWebSocketUrl(options) {
4966
+ if (options.url) {
4967
+ return options.url;
4968
+ }
4969
+ const machine = options.machine;
4970
+ if (!machine || machine.type === "local" /* Local */) {
4971
+ const port = options._localPort ?? options.daemonPort ?? DEFAULT_DAEMON_PORT;
4972
+ return `ws://127.0.0.1:${port}`;
4973
+ }
4974
+ if (machine.type === "computer" /* Computer */) {
4975
+ const relayBase = options.relayBaseUrl ?? DEFAULT_RELAY_BASE_URL;
4976
+ return `${relayBase}/v0/computer/${machine.computerId}/client`;
4977
+ }
4978
+ const _exhaustive = machine;
4979
+ throw new ConnectionError(`Unsupported machine type: ${String(_exhaustive)}`);
4980
+ }
4981
+ function getWebSocketConfig(machine) {
4982
+ if (machine?.type === "computer" /* Computer */) {
4983
+ return { ...DEFAULT_WS_CONFIG, ...COMPUTER_WS_CONFIG };
4984
+ }
4985
+ if (!machine || machine.type === "local" /* Local */) {
4986
+ return { ...DEFAULT_WS_CONFIG, connectionTimeoutMs: 1e4 };
4987
+ }
4988
+ return { ...DEFAULT_WS_CONFIG };
4989
+ }
4990
+ var SharedTransportMultiplexer = class {
4991
+ constructor(_inner) {
4992
+ this._inner = _inner;
4993
+ this._inner.onMessage((message) => {
4994
+ this._routeMessage(message);
4995
+ });
4996
+ this._inner.onError((error) => {
4997
+ for (const view of this._views) {
4998
+ if (view.errorCallback) {
4999
+ try {
5000
+ view.errorCallback(error);
5001
+ } catch {
5002
+ }
5003
+ }
5004
+ }
5005
+ });
5006
+ }
5007
+ _views = /* @__PURE__ */ new Set();
5008
+ createView() {
5009
+ const inner = this._inner;
5010
+ const viewState = {
5011
+ messageCallback: null,
5012
+ errorCallback: null,
5013
+ pendingRequestIds: /* @__PURE__ */ new Set(),
5014
+ sessionId: null
5015
+ };
5016
+ this._views.add(viewState);
5017
+ const view = {
5018
+ send: (message) => {
5019
+ if (message["type"] === "request" && typeof message["id"] === "string") {
5020
+ viewState.pendingRequestIds.add(message["id"]);
5021
+ }
5022
+ inner.send(message);
5023
+ },
5024
+ onMessage: (callback) => {
5025
+ viewState.messageCallback = callback;
5026
+ },
5027
+ onError: (callback) => {
5028
+ viewState.errorCallback = callback;
5029
+ },
5030
+ close: async () => {
5031
+ viewState.messageCallback = null;
5032
+ viewState.errorCallback = null;
5033
+ viewState.pendingRequestIds.clear();
5034
+ this._views.delete(viewState);
5035
+ },
5036
+ get isConnected() {
5037
+ return inner.isConnected;
5038
+ }
5039
+ };
5040
+ return view;
5041
+ }
5042
+ _routeMessage(message) {
5043
+ const messageType = message["type"];
5044
+ const messageId = message["id"];
5045
+ if (messageType === "response" && typeof messageId === "string") {
5046
+ for (const view of this._views) {
5047
+ if (view.pendingRequestIds.has(messageId)) {
5048
+ view.pendingRequestIds.delete(messageId);
5049
+ const result = message["result"];
5050
+ if (isRecord(result) && typeof result["sessionId"] === "string") {
5051
+ view.sessionId = result["sessionId"];
5052
+ }
5053
+ if (view.messageCallback) {
5054
+ try {
5055
+ view.messageCallback(message);
5056
+ } catch {
5057
+ }
5058
+ }
5059
+ return;
5060
+ }
5061
+ }
5062
+ return;
5063
+ }
5064
+ if (messageType === "notification") {
5065
+ const params = message["params"];
5066
+ const sessionId = isRecord(params) && typeof params["sessionId"] === "string" ? params["sessionId"] : null;
5067
+ if (sessionId) {
5068
+ for (const view of this._views) {
5069
+ if (view.sessionId === sessionId && view.messageCallback) {
5070
+ try {
5071
+ view.messageCallback(message);
5072
+ } catch {
5073
+ }
5074
+ return;
5075
+ }
5076
+ }
5077
+ }
5078
+ for (const view of this._views) {
5079
+ if (view.messageCallback) {
5080
+ try {
5081
+ view.messageCallback(message);
5082
+ } catch {
5083
+ }
5084
+ }
5085
+ }
5086
+ return;
5087
+ }
5088
+ if (messageType === "request") {
5089
+ const params = message["params"];
5090
+ const sessionId = isRecord(params) && typeof params["sessionId"] === "string" ? params["sessionId"] : null;
5091
+ if (sessionId) {
5092
+ for (const view of this._views) {
5093
+ if (view.sessionId === sessionId && view.messageCallback) {
5094
+ try {
5095
+ view.messageCallback(message);
5096
+ } catch {
5097
+ }
5098
+ return;
5099
+ }
5100
+ }
5101
+ }
5102
+ for (const view of this._views) {
5103
+ if (view.messageCallback) {
5104
+ try {
5105
+ view.messageCallback(message);
5106
+ } catch {
5107
+ }
5108
+ }
5109
+ }
5110
+ }
5111
+ }
5112
+ };
5113
+ async function authenticate(transport, options) {
5114
+ const requestId = crypto.randomUUID();
5115
+ const envelope = {
5116
+ jsonrpc: JSONRPC_VERSION,
5117
+ factoryApiVersion: LEGACY_FACTORY_API_VERSION,
5118
+ factoryProtocolVersion: FACTORY_PROTOCOL_VERSION,
5119
+ type: "request" /* Request */,
5120
+ id: requestId,
5121
+ method: DAEMON_AUTHENTICATE_METHOD,
5122
+ params: {
5123
+ apiKey: options.apiKey,
5124
+ caller: SDK_CALLER
5125
+ }
5126
+ };
5127
+ return new Promise((resolve2, reject) => {
5128
+ const timer = setTimeout(() => {
5129
+ transport.onMessage(() => {
5130
+ });
5131
+ reject(
5132
+ new ConnectionError(
5133
+ `Daemon authentication timed out after ${DAEMON_AUTHENTICATE_TIMEOUT}ms`
5134
+ )
5135
+ );
5136
+ }, DAEMON_AUTHENTICATE_TIMEOUT);
5137
+ transport.onMessage((message) => {
5138
+ if (message["id"] !== requestId) {
5139
+ return;
5140
+ }
5141
+ clearTimeout(timer);
5142
+ transport.onMessage(() => {
5143
+ });
5144
+ if (message["error"]) {
5145
+ const error = message["error"];
5146
+ const errorMessage = error && typeof error === "object" && "message" in error ? String(error.message) : "unknown error";
5147
+ reject(
5148
+ new ConnectionError(`Daemon authentication failed: ${errorMessage}`)
5149
+ );
5150
+ return;
5151
+ }
5152
+ resolve2();
5153
+ });
5154
+ transport.send(envelope);
5155
+ });
5156
+ }
5157
+ var DaemonConnection = class {
5158
+ _transport;
5159
+ _multiplexer;
5160
+ _apiKey;
5161
+ _closed = false;
5162
+ /** @internal */
5163
+ constructor(transport, apiKey) {
5164
+ this._transport = transport;
5165
+ this._multiplexer = new SharedTransportMultiplexer(transport);
5166
+ this._apiKey = apiKey;
5167
+ }
5168
+ async createSession(options = {}) {
5169
+ this._ensureNotClosed();
5170
+ const view = this._multiplexer.createView();
5171
+ const client = new DaemonClient({
5172
+ transport: view,
5173
+ apiKey: this._apiKey
5174
+ });
5175
+ if (options.permissionHandler) {
5176
+ client.setPermissionHandler(options.permissionHandler);
5177
+ }
5178
+ if (options.askUserHandler) {
5179
+ client.setAskUserHandler(options.askUserHandler);
5180
+ }
5181
+ let sdkMcpServers;
5182
+ try {
5183
+ sdkMcpServers = await startSdkMcpServers(options.mcpServers);
5184
+ const initParams = buildInitParams({
5185
+ ...options,
5186
+ mcpServers: sdkMcpServers.mcpServers
5187
+ });
5188
+ const initResult = await client.initializeSession(initParams);
5189
+ const session = new DaemonSession(client, initResult.sessionId);
5190
+ if (sdkMcpServers) {
5191
+ session.addCleanup(sdkMcpServers.cleanup);
5192
+ }
5193
+ return session;
5194
+ } catch (error) {
5195
+ await sdkMcpServers?.cleanup();
5196
+ await client.close();
5197
+ throw error;
5198
+ }
5199
+ }
5200
+ async resumeSession(sessionId, options = {}) {
5201
+ this._ensureNotClosed();
5202
+ const view = this._multiplexer.createView();
5203
+ const client = new DaemonClient({
5204
+ transport: view,
5205
+ apiKey: this._apiKey
5206
+ });
5207
+ if (options.permissionHandler) {
5208
+ client.setPermissionHandler(options.permissionHandler);
5209
+ }
5210
+ if (options.askUserHandler) {
5211
+ client.setAskUserHandler(options.askUserHandler);
5212
+ }
5213
+ let sdkMcpServers;
5214
+ try {
5215
+ sdkMcpServers = await startSdkMcpServers(options.mcpServers);
5216
+ await client.loadSession({
5217
+ sessionId,
5218
+ mcpServers: sdkMcpServers.mcpServers
5219
+ });
5220
+ const session = new DaemonSession(client, sessionId);
5221
+ if (sdkMcpServers) {
5222
+ session.addCleanup(sdkMcpServers.cleanup);
5223
+ }
5224
+ return session;
5225
+ } catch (error) {
5226
+ await sdkMcpServers?.cleanup();
5227
+ await client.close();
5228
+ throw error;
5229
+ }
5230
+ }
5231
+ async interruptSession(sessionId) {
5232
+ this._ensureNotClosed();
5233
+ const view = this._multiplexer.createView();
5234
+ const client = new DaemonClient({
5235
+ transport: view,
5236
+ apiKey: this._apiKey
5237
+ });
5238
+ try {
5239
+ await client.loadSession({ sessionId });
5240
+ await client.interruptSession();
5241
+ } finally {
5242
+ await client.close();
5243
+ }
5244
+ }
5245
+ async close() {
5246
+ if (this._closed) {
5247
+ return;
5248
+ }
5249
+ this._closed = true;
5250
+ await this._transport.close();
5251
+ }
5252
+ _ensureNotClosed() {
5253
+ if (this._closed) {
5254
+ throw new ConnectionError(
5255
+ "Daemon connection has been closed. Call connectDaemon() to create a new connection."
5256
+ );
5257
+ }
5258
+ }
5259
+ };
5260
+ async function connectDaemon(options) {
5261
+ const isLocal = !options.url && (!options.machine || options.machine.type === "local" /* Local */);
5262
+ let resolvedOptions = options;
5263
+ if (isLocal) {
5264
+ const { port } = await ensureLocalDaemon();
5265
+ resolvedOptions = { ...options, _localPort: port };
5266
+ }
5267
+ const url = resolveWebSocketUrl(resolvedOptions);
5268
+ const wsConfig = getWebSocketConfig(resolvedOptions.machine);
5269
+ const transport = new WebSocketTransport(wsConfig);
5270
+ const apiKey = resolvedOptions.apiKey;
5271
+ const maxRetries = resolvedOptions.maxRetries ?? 0;
5272
+ try {
5273
+ if (maxRetries > 0) {
5274
+ let lastError;
5275
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
5276
+ try {
5277
+ await transport.connect(url);
5278
+ await authenticate(transport, resolvedOptions);
5279
+ return new DaemonConnection(transport, apiKey);
5280
+ } catch (error) {
5281
+ lastError = error instanceof Error ? error : new Error(String(error));
5282
+ try {
5283
+ await transport.close();
5284
+ } catch {
5285
+ }
5286
+ if (attempt < maxRetries) {
5287
+ await new Promise((resolve2) => setTimeout(resolve2, 2e3));
5288
+ }
5289
+ }
5290
+ }
5291
+ throw lastError;
5292
+ }
5293
+ await transport.connect(url);
5294
+ await authenticate(transport, resolvedOptions);
5295
+ return new DaemonConnection(transport, apiKey);
5296
+ } catch (error) {
5297
+ try {
5298
+ await transport.close();
5299
+ } catch {
5300
+ }
5301
+ throw error;
5302
+ }
5303
+ }
3755
5304
  export {
3756
5305
  AddMcpServerRequestParamsSchema,
3757
5306
  AddMcpServerRequestSchema,
@@ -3769,6 +5318,7 @@ export {
3769
5318
  AskUserRequestSchema,
3770
5319
  AskUserResponseSchema,
3771
5320
  AskUserResultSchema,
5321
+ AssistantTextCompleteNotificationSchema,
3772
5322
  AssistantTextDeltaNotificationSchema,
3773
5323
  AuthenticateMcpServerRequestParamsSchema,
3774
5324
  AuthenticateMcpServerRequestSchema,
@@ -3793,17 +5343,30 @@ export {
3793
5343
  ClearMcpAuthResultSchema,
3794
5344
  CliRequestOrNotificationSchema,
3795
5345
  ClientRequestSchema,
5346
+ CloseSessionRequestParamsSchema,
5347
+ CloseSessionRequestSchema,
5348
+ CloseSessionResponseSchema,
5349
+ CloseSessionResultSchema,
3796
5350
  CompactSessionRequestParamsSchema,
3797
5351
  CompactSessionRequestSchema,
3798
5352
  CompactSessionResponseSchema,
3799
5353
  CompactSessionResultSchema,
5354
+ ComputerListResponseSchema,
5355
+ ComputerMetricSchema,
5356
+ ComputerMetricsResponseSchema,
5357
+ ComputerSchema,
3800
5358
  ConnectionError,
3801
5359
  ContentBlockSchema,
5360
+ ContextBreakdownCategorySchema,
5361
+ ContextBreakdownResultSchema,
3802
5362
  ContextStatsAccuracy,
3803
5363
  ContextStatsSchema,
3804
5364
  CreateMessageNotificationSchema,
3805
5365
  CreateToolConfirmationDetailsSchema,
3806
5366
  DEFAULT_REQUEST_TIMEOUT,
5367
+ DaemonClient,
5368
+ DaemonConnection,
5369
+ DaemonSession,
3807
5370
  DecompSessionType,
3808
5371
  DiscoveredIssueSchema,
3809
5372
  DismissalRecordSchema,
@@ -3813,6 +5376,10 @@ export {
3813
5376
  DroidClient,
3814
5377
  DroidClientMethod,
3815
5378
  DroidErrorType,
5379
+ DroidHookEventSchema,
5380
+ DroidHookExecutionResultSchema,
5381
+ DroidHookOutputSchema,
5382
+ DroidHookSpecificOutputSchema,
3816
5383
  DroidInteractionMode,
3817
5384
  DroidMessageType,
3818
5385
  DroidServerMethod,
@@ -3853,6 +5420,10 @@ export {
3853
5420
  GitRepoInfoSchema,
3854
5421
  HandoffItemsDismissedEntrySchema,
3855
5422
  HandoffSchema,
5423
+ HookCommandSchema,
5424
+ HookExecutionCompletedNotificationSchema,
5425
+ HookExecutionStartedNotificationSchema,
5426
+ HookResultSchema,
3856
5427
  HttpHeaderSchema,
3857
5428
  HttpMcpConfigSchema,
3858
5429
  ImageBlockSchema,
@@ -3910,6 +5481,10 @@ export {
3910
5481
  LoadSessionResponseSchema,
3911
5482
  LoadSessionResultSchema,
3912
5483
  MCP_AUTH_TIMEOUT,
5484
+ MachineTemplateBuildStatusSchema,
5485
+ MachineTemplateListResponseSchema,
5486
+ MachineTemplateSchema,
5487
+ MachineType,
3913
5488
  McpAuthCompletedNotificationSchema,
3914
5489
  McpAuthOutcome,
3915
5490
  McpAuthRequiredNotificationSchema,
@@ -3955,6 +5530,9 @@ export {
3955
5530
  REWIND_TIMEOUT,
3956
5531
  ReasoningEffort,
3957
5532
  RedactedThinkingBlockSchema,
5533
+ RefreshComputerResponseSchema,
5534
+ RemoteSessionListResponseSchema,
5535
+ RemoteSessionSchema,
3958
5536
  RemoveMcpServerRequestParamsSchema,
3959
5537
  RemoveMcpServerRequestSchema,
3960
5538
  RemoveMcpServerResponseSchema,
@@ -3974,6 +5552,7 @@ export {
3974
5552
  SDK_VERSION,
3975
5553
  SESSION_INIT_TIMEOUT,
3976
5554
  SdkMcpServer,
5555
+ ServerRequestHandlerType,
3977
5556
  SessionError,
3978
5557
  SessionMetadataSchema,
3979
5558
  SessionNotFoundError,
@@ -4001,6 +5580,8 @@ export {
4001
5580
  StartMissionRunConfirmationDetailsSchema,
4002
5581
  StdioMcpConfigSchema,
4003
5582
  StreamStateTracker,
5583
+ StructuredOutputErrorSchema,
5584
+ StructuredOutputNotificationSchema,
4004
5585
  SubmitBugReportRequestParamsSchema,
4005
5586
  SubmitBugReportRequestSchema,
4006
5587
  SubmitBugReportResponseSchema,
@@ -4015,6 +5596,7 @@ export {
4015
5596
  TestsSchema,
4016
5597
  TextBlockSchema,
4017
5598
  ThinkingBlockSchema,
5599
+ ThinkingTextCompleteNotificationSchema,
4018
5600
  ThinkingTextDeltaNotificationSchema,
4019
5601
  TimeoutError,
4020
5602
  ToggleMcpServerRequestParamsSchema,
@@ -4026,6 +5608,7 @@ export {
4026
5608
  ToggleMcpToolResponseSchema,
4027
5609
  ToggleMcpToolResultSchema,
4028
5610
  TokenUsageSchema,
5611
+ ToolCallNotificationSchema,
4029
5612
  ToolConfirmationDetailsSchema,
4030
5613
  ToolConfirmationInfoSchema,
4031
5614
  ToolConfirmationListItemSchema,
@@ -4045,19 +5628,37 @@ export {
4045
5628
  UpdateSessionSettingsResultSchema,
4046
5629
  VerificationCommandSchema,
4047
5630
  VerificationSchema,
5631
+ WebSocketTransport,
4048
5632
  WorkerCompletedEntrySchema,
4049
5633
  WorkerFailedEntrySchema,
4050
5634
  WorkerPausedEntrySchema,
4051
5635
  WorkerSelectedFeatureEntrySchema,
4052
5636
  WorkerStartedEntrySchema,
4053
5637
  WorkerStateInfoSchema,
5638
+ connectDaemon,
4054
5639
  convertNotificationToStreamMessage,
5640
+ createComputer,
5641
+ createResponseSchema,
4055
5642
  createSdkMcpServer,
4056
5643
  createSession,
5644
+ deleteComputer,
5645
+ dispatchNotification,
5646
+ ensureLocalDaemon,
5647
+ getComputer,
5648
+ getComputerByName,
5649
+ getComputerMetrics,
5650
+ getMachineTemplate,
5651
+ listComputers,
5652
+ listMachineTemplates,
5653
+ listRemoteSessions,
4057
5654
  listSessions,
4058
- query,
5655
+ refreshComputer,
5656
+ resolveWebSocketUrl,
5657
+ restartComputer,
4059
5658
  resumeSession,
5659
+ retryInstallDeps,
4060
5660
  run,
4061
- tool
5661
+ tool,
5662
+ updateComputer
4062
5663
  };
4063
5664
  //# sourceMappingURL=index.js.map