@robota-sdk/agent-cli 3.0.0-beta.60 → 3.0.0-beta.61

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.
@@ -52,7 +52,6 @@ var import_agent_command_exit = require("@robota-sdk/agent-command-exit");
52
52
  var import_agent_command_help = require("@robota-sdk/agent-command-help");
53
53
  var import_agent_command_language = require("@robota-sdk/agent-command-language");
54
54
  var import_agent_command_memory = require("@robota-sdk/agent-command-memory");
55
- var import_agent_command_mode = require("@robota-sdk/agent-command-mode");
56
55
  var import_agent_command_model = require("@robota-sdk/agent-command-model");
57
56
  var import_agent_command_permissions = require("@robota-sdk/agent-command-permissions");
58
57
  var import_agent_command_plugin = require("@robota-sdk/agent-command-plugin");
@@ -60,8 +59,8 @@ var import_agent_command_reset = require("@robota-sdk/agent-command-reset");
60
59
  var import_agent_command_rewind = require("@robota-sdk/agent-command-rewind");
61
60
  var import_agent_command_statusline = require("@robota-sdk/agent-command-statusline");
62
61
  var import_agent_command_session = require("@robota-sdk/agent-command-session");
63
- var import_agent_sdk14 = require("@robota-sdk/agent-sdk");
64
- var import_agent_sessions = require("@robota-sdk/agent-sessions");
62
+ var import_agent_command_skills = require("@robota-sdk/agent-command-skills");
63
+ var import_agent_sdk15 = require("@robota-sdk/agent-sdk");
65
64
 
66
65
  // src/utils/cli-args.ts
67
66
  var import_node_util = require("util");
@@ -101,6 +100,7 @@ function parseCliArgs() {
101
100
  "output-format": { type: "string" },
102
101
  "system-prompt": { type: "string" },
103
102
  "append-system-prompt": { type: "string" },
103
+ "task-file": { type: "string" },
104
104
  version: { type: "boolean", default: false },
105
105
  reset: { type: "boolean", default: false },
106
106
  bare: { type: "boolean", default: false },
@@ -134,6 +134,7 @@ function parseCliArgs() {
134
134
  outputFormat: values["output-format"],
135
135
  systemPrompt: values["system-prompt"],
136
136
  appendSystemPrompt: values["append-system-prompt"],
137
+ taskFile: values["task-file"],
137
138
  version: values["version"] ?? false,
138
139
  reset: values["reset"] ?? false,
139
140
  bare: values["bare"] ?? false,
@@ -190,6 +191,7 @@ var import_node_path2 = require("path");
190
191
 
191
192
  // src/utils/provider-default-definitions.ts
192
193
  var import_agent_provider_anthropic = require("@robota-sdk/agent-provider-anthropic");
194
+ var import_agent_provider_deepseek = require("@robota-sdk/agent-provider-deepseek");
193
195
  var import_agent_provider_gemma = require("@robota-sdk/agent-provider-gemma");
194
196
  var import_agent_provider_gemini = require("@robota-sdk/agent-provider-gemini");
195
197
  var import_agent_provider_openai = require("@robota-sdk/agent-provider-openai");
@@ -199,7 +201,8 @@ var DEFAULT_PROVIDER_DEFINITIONS = [
199
201
  (0, import_agent_provider_openai.createOpenAIProviderDefinition)(),
200
202
  (0, import_agent_provider_gemini.createGeminiProviderDefinition)(),
201
203
  (0, import_agent_provider_gemma.createGemmaProviderDefinition)(),
202
- (0, import_agent_provider_qwen.createQwenProviderDefinition)()
204
+ (0, import_agent_provider_qwen.createQwenProviderDefinition)(),
205
+ (0, import_agent_provider_deepseek.createDeepSeekProviderDefinition)()
203
206
  ];
204
207
 
205
208
  // src/utils/provider-definition.ts
@@ -335,8 +338,11 @@ function createProviderFromConfig(settings, providerDefinitions) {
335
338
  `Unknown provider: ${settings.name}. Currently supported: ${(0, import_agent_core.formatSupportedProviderTypes)(providerDefinitions)}`
336
339
  );
337
340
  }
338
- if (definition.requiresApiKey === true && !settings.apiKey) {
339
- throw new Error(`Provider ${settings.name} requires apiKey`);
341
+ const credentialRequirement = (0, import_agent_core.getProviderCredentialRequirement)(definition);
342
+ if (credentialRequirement !== void 0 && !hasRequiredProviderCredential(settings, credentialRequirement)) {
343
+ throw new Error(
344
+ `Provider ${settings.name} requires ${formatCredentialRequirement(credentialRequirement)}`
345
+ );
340
346
  }
341
347
  return definition.createProvider(settings);
342
348
  }
@@ -346,6 +352,16 @@ function createProviderFromSettings(cwd, modelOverride, options = {}) {
346
352
  const model = modelOverride ?? settings.model;
347
353
  return createProviderFromConfig({ ...settings, model }, providerDefinitions);
348
354
  }
355
+ function hasRequiredProviderCredential(settings, requirement) {
356
+ return requirement.anyOf.some((field) => hasProviderCredentialValue(settings, field));
357
+ }
358
+ function hasProviderCredentialValue(settings, field) {
359
+ const value = settings[field];
360
+ return value !== void 0 && value.length > 0;
361
+ }
362
+ function formatCredentialRequirement(requirement) {
363
+ return requirement.anyOf.join(" or ");
364
+ }
349
365
  function getProviderDefinitions(options) {
350
366
  return options.providerDefinitions ?? DEFAULT_PROVIDER_DEFINITIONS;
351
367
  }
@@ -372,23 +388,40 @@ function isUsableProviderProfile(type, profile, providerDefinitions) {
372
388
  if (!profile) {
373
389
  return false;
374
390
  }
375
- if ((0, import_agent_sdk.hasUsableSecretReference)(profile.apiKey)) {
376
- return true;
377
- }
378
391
  if (!type) {
379
- return false;
392
+ return (0, import_agent_sdk.hasUsableSecretReference)(profile.apiKey);
380
393
  }
381
394
  const definition = (0, import_agent_core.findProviderDefinition)(providerDefinitions, type);
382
395
  if (definition === void 0) {
383
396
  return false;
384
397
  }
385
- return definition.requiresApiKey !== true || (0, import_agent_sdk.hasUsableSecretReference)(definition.defaults?.apiKey);
398
+ const credentialRequirement = (0, import_agent_core.getProviderCredentialRequirement)(definition);
399
+ if (credentialRequirement === void 0) {
400
+ return true;
401
+ }
402
+ return hasUsableRequiredProviderCredential(profile, definition, credentialRequirement);
403
+ }
404
+ function hasUsableRequiredProviderCredential(profile, definition, requirement) {
405
+ return requirement.anyOf.some(
406
+ (field) => (0, import_agent_sdk.hasUsableSecretReference)(resolveProviderCredentialValue(field, profile, definition))
407
+ );
408
+ }
409
+ function resolveProviderCredentialValue(field, profile, definition) {
410
+ return profile[field] ?? definition.defaults?.[field];
386
411
  }
387
412
 
388
413
  // src/utils/provider-settings.ts
389
414
  var import_agent_sdk2 = require("@robota-sdk/agent-sdk");
390
415
 
391
416
  // src/utils/provider-configuration.ts
417
+ function resolveProviderSettingsWriteTargetPath(cwd, options = {}) {
418
+ const settingsPaths = options.settingsPaths ?? getProviderSettingsPaths(cwd);
419
+ const targetPath = findLastPathWithCurrentProvider(settingsPaths) ?? settingsPaths[0];
420
+ if (targetPath === void 0) {
421
+ throw new Error("No settings path available for provider update");
422
+ }
423
+ return targetPath;
424
+ }
392
425
  function readProviderDocument(settingsPath) {
393
426
  return readSettings(settingsPath);
394
427
  }
@@ -471,6 +504,15 @@ function findLastPathWithLegacyProvider(settingsPaths) {
471
504
  }
472
505
  return void 0;
473
506
  }
507
+ function findLastPathWithCurrentProvider(settingsPaths) {
508
+ for (let index = settingsPaths.length - 1; index >= 0; index -= 1) {
509
+ const settingsPath = settingsPaths[index];
510
+ if (settingsPath === void 0) continue;
511
+ const settings = readProviderDocument(settingsPath);
512
+ if (settings.currentProvider !== void 0) return settingsPath;
513
+ }
514
+ return void 0;
515
+ }
474
516
 
475
517
  // src/utils/provider-setup-flow.ts
476
518
  var import_agent_sdk3 = require("@robota-sdk/agent-sdk");
@@ -496,7 +538,8 @@ function handleProviderConfigurationArgs(cwd, args, providerDefinitions = DEFAUL
496
538
  return !args.printMode && args.positional.length === 0;
497
539
  }
498
540
  if (args.provider && args.setCurrent) {
499
- applyProviderSwitch(settingsPath, args.provider, {
541
+ const switchSettingsPath = args.settingsScope === void 0 ? resolveProviderSettingsWriteTargetPath(cwd) : settingsPath;
542
+ applyProviderSwitch(switchSettingsPath, args.provider, {
500
543
  knownProviders: readMergedProviderSettings(cwd).providers
501
544
  });
502
545
  process.stdout.write(`Current provider set to ${args.provider}
@@ -530,7 +573,9 @@ async function runInteractiveProviderSetup(cwd, args, promptInput2, providerDefi
530
573
  const providerChoice = await promptInput2((0, import_agent_sdk3.formatProviderSetupSelectionPrompt)(providerDefinitions));
531
574
  const type = (0, import_agent_sdk3.resolveProviderSetupSelection)(providerChoice, providerDefinitions);
532
575
  const settingsPath = getSettingsPathForScope(cwd, args.settingsScope);
533
- const input = await (0, import_agent_sdk3.runProviderSetupPromptFlow)(type, promptInput2, providerDefinitions);
576
+ const input = await (0, import_agent_sdk3.runProviderSetupPromptFlow)(type, promptInput2, providerDefinitions, {
577
+ existingProfileNames: Object.keys(readMergedProviderSettings(cwd).providers ?? {})
578
+ });
534
579
  applyProviderConfiguration(settingsPath, input, {
535
580
  providerDefinitions
536
581
  });
@@ -618,6 +663,7 @@ var import_ink22 = require("ink");
618
663
  // src/ui/App.tsx
619
664
  var import_react19 = require("react");
620
665
  var import_ink21 = require("ink");
666
+ var import_agent_sdk9 = require("@robota-sdk/agent-sdk");
621
667
  var import_agent_core11 = require("@robota-sdk/agent-core");
622
668
 
623
669
  // src/ui/hooks/useInteractiveSession.ts
@@ -888,7 +934,6 @@ var TuiStateManager = class {
888
934
 
889
935
  // src/ui/hooks/useSlashRouting.ts
890
936
  var import_react = require("react");
891
- var import_node_crypto = require("crypto");
892
937
  var import_agent_core2 = require("@robota-sdk/agent-core");
893
938
 
894
939
  // src/plugins/plugin-command-source-loader.ts
@@ -917,7 +962,7 @@ function reloadPluginCommandSource(registry) {
917
962
  }
918
963
 
919
964
  // src/ui/hooks/useSlashRouting.ts
920
- function useSlashRouting(interactiveSession, registry, manager) {
965
+ function useSlashRouting(interactiveSession, registry, manager, commandEffectQueue) {
921
966
  return (0, import_react.useCallback)(
922
967
  async (input) => {
923
968
  manager.onUserTurnAccepted();
@@ -931,10 +976,11 @@ function useSlashRouting(interactiveSession, registry, manager) {
931
976
  const args = parts.slice(1).join(" ");
932
977
  const result = await interactiveSession.executeCommand(cmd, args);
933
978
  if (result) {
934
- applySystemCommandResult(result, interactiveSession, registry, manager);
935
- return;
936
- }
937
- if (await routeSkillCommand(input, cmd, registry, interactiveSession, manager)) {
979
+ if (result.effects?.some((effect) => effect.type === "session-execution-started")) {
980
+ manager.setPendingPrompt(interactiveSession.getPendingPrompt());
981
+ return;
982
+ }
983
+ applySystemCommandResult(result, interactiveSession, registry, manager, commandEffectQueue);
938
984
  return;
939
985
  }
940
986
  manager.addEntry(
@@ -943,18 +989,17 @@ function useSlashRouting(interactiveSession, registry, manager) {
943
989
  )
944
990
  );
945
991
  },
946
- [interactiveSession, registry, manager]
992
+ [interactiveSession, registry, manager, commandEffectQueue]
947
993
  );
948
994
  }
949
- function applySystemCommandResult(result, interactiveSession, registry, manager) {
995
+ function applySystemCommandResult(result, interactiveSession, registry, manager, commandEffectQueue) {
950
996
  const pendingEffects = applyImmediateCommandEffects(result.effects, registry, manager);
951
997
  manager.addEntry((0, import_agent_core2.messageToHistoryEntry)((0, import_agent_core2.createSystemMessage)(result.message)));
952
- const effects = getEffects(interactiveSession);
953
998
  if (result.interaction !== void 0) {
954
- effects._pendingCommandInteraction = result.interaction;
999
+ commandEffectQueue.enqueueInteraction(result.interaction);
955
1000
  }
956
1001
  if (pendingEffects.length > 0) {
957
- effects._pendingCommandEffects = pendingEffects;
1002
+ commandEffectQueue.enqueueEffects(pendingEffects);
958
1003
  }
959
1004
  const ctx = interactiveSession.getContextState();
960
1005
  manager.setContextState({
@@ -979,37 +1024,32 @@ function applyImmediateCommandEffects(effects, registry, manager) {
979
1024
  }
980
1025
  return pendingEffects;
981
1026
  }
982
- async function routeSkillCommand(input, cmd, registry, interactiveSession, manager) {
983
- const skillCmd = registry.getCommands().find((c) => c.name === cmd && (c.source === "skill" || c.source === "plugin"));
984
- if (!skillCmd) {
985
- return false;
1027
+
1028
+ // src/ui/hooks/command-effect-queue.ts
1029
+ var CommandEffectQueue = class {
1030
+ queue = [];
1031
+ enqueueInteraction(interaction) {
1032
+ this.queue.push({ type: "interaction", interaction });
986
1033
  }
987
- manager.addEntry({
988
- id: (0, import_node_crypto.randomUUID)(),
989
- timestamp: /* @__PURE__ */ new Date(),
990
- category: "event",
991
- type: "skill-invocation",
992
- data: {
993
- skillName: cmd,
994
- source: skillCmd.source,
995
- message: `Invoking ${skillCmd.source}: ${cmd}`
996
- }
997
- });
998
- const args = input.slice(1 + cmd.length).trimStart();
999
- const qualifiedName = registry.resolveQualifiedName(cmd);
1000
- const hookInput = qualifiedName ? `/${qualifiedName}${input.slice(1 + cmd.length)}` : input;
1001
- await interactiveSession.executeSkillCommand(skillCmd, args, input, hookInput);
1002
- manager.setPendingPrompt(interactiveSession.getPendingPrompt());
1003
- return true;
1004
- }
1005
- function getEffects(interactiveSession) {
1006
- return interactiveSession;
1007
- }
1034
+ enqueueEffects(effects) {
1035
+ if (effects.length === 0) return;
1036
+ this.queue.push({ type: "effects", effects: [...effects] });
1037
+ }
1038
+ drain() {
1039
+ return this.queue.shift();
1040
+ }
1041
+ clear() {
1042
+ this.queue.length = 0;
1043
+ }
1044
+ };
1008
1045
 
1009
1046
  // src/ui/hooks/useInteractiveSession.ts
1010
1047
  function applyCompactEventToManager(interactiveSession, manager) {
1011
1048
  manager.syncHistory(interactiveSession.getFullHistory());
1012
1049
  }
1050
+ function applySkillActivationEventToManager(interactiveSession, manager) {
1051
+ manager.syncHistory(interactiveSession.getFullHistory());
1052
+ }
1013
1053
  function initializeSession(props, permissionHandler) {
1014
1054
  const interactiveSession = new import_agent_sdk5.InteractiveSession({
1015
1055
  cwd: props.cwd,
@@ -1027,14 +1067,13 @@ function initializeSession(props, permissionHandler) {
1027
1067
  commandHostAdapters: props.commandHostAdapters
1028
1068
  });
1029
1069
  const registry = new import_agent_sdk5.CommandRegistry();
1030
- registry.addModule((0, import_agent_sdk5.createBuiltinCommandModule)());
1031
1070
  for (const module2 of props.commandModules ?? []) {
1032
1071
  registry.addModule(module2);
1033
1072
  }
1034
- registry.addSource(new import_agent_sdk5.SkillCommandSource(props.cwd));
1035
1073
  reloadPluginCommandSource(registry);
1036
1074
  const manager = new TuiStateManager();
1037
- return { interactiveSession, registry, manager };
1075
+ const commandEffectQueue = new CommandEffectQueue();
1076
+ return { interactiveSession, registry, manager, commandEffectQueue };
1038
1077
  }
1039
1078
  function useInteractiveSession(props) {
1040
1079
  const [, forceRender] = (0, import_react2.useState)(0);
@@ -1063,8 +1102,8 @@ function useInteractiveSession(props) {
1063
1102
  });
1064
1103
  }, []);
1065
1104
  const permissionHandler = (0, import_react2.useCallback)(
1066
- (toolName, toolArgs) => new Promise((resolve2) => {
1067
- permissionQueueRef.current.push({ toolName, toolArgs, resolve: resolve2 });
1105
+ (toolName, toolArgs) => new Promise((resolve3) => {
1106
+ permissionQueueRef.current.push({ toolName, toolArgs, resolve: resolve3 });
1068
1107
  processNextPermission();
1069
1108
  }),
1070
1109
  [processNextPermission]
@@ -1073,7 +1112,7 @@ function useInteractiveSession(props) {
1073
1112
  if (stateRef.current === null) {
1074
1113
  stateRef.current = initializeSession(props, permissionHandler);
1075
1114
  }
1076
- const { interactiveSession, registry, manager } = stateRef.current;
1115
+ const { interactiveSession, registry, manager, commandEffectQueue } = stateRef.current;
1077
1116
  manager.onChange = () => forceRender((n) => n + 1);
1078
1117
  if (manager.history.length === 0) {
1079
1118
  const restored = interactiveSession.getFullHistory();
@@ -1083,6 +1122,7 @@ function useInteractiveSession(props) {
1083
1122
  }
1084
1123
  (0, import_react2.useEffect)(() => {
1085
1124
  const onCompact = () => applyCompactEventToManager(interactiveSession, manager);
1125
+ const onSkillActivation = () => applySkillActivationEventToManager(interactiveSession, manager);
1086
1126
  interactiveSession.on("text_delta", manager.onTextDelta);
1087
1127
  interactiveSession.on("tool_start", manager.onToolStart);
1088
1128
  interactiveSession.on("tool_end", manager.onToolEnd);
@@ -1092,6 +1132,7 @@ function useInteractiveSession(props) {
1092
1132
  interactiveSession.on("error", manager.onError);
1093
1133
  interactiveSession.on("context_update", manager.onContextUpdate);
1094
1134
  interactiveSession.on("compact", onCompact);
1135
+ interactiveSession.on("skill_activation", onSkillActivation);
1095
1136
  interactiveSession.on("background_task_event", manager.onBackgroundTaskEvent);
1096
1137
  const initCheck = setInterval(() => {
1097
1138
  try {
@@ -1120,6 +1161,7 @@ function useInteractiveSession(props) {
1120
1161
  interactiveSession.off("error", manager.onError);
1121
1162
  interactiveSession.off("context_update", manager.onContextUpdate);
1122
1163
  interactiveSession.off("compact", onCompact);
1164
+ interactiveSession.off("skill_activation", onSkillActivation);
1123
1165
  interactiveSession.off("background_task_event", manager.onBackgroundTaskEvent);
1124
1166
  };
1125
1167
  }, [interactiveSession, manager]);
@@ -1129,7 +1171,7 @@ function useInteractiveSession(props) {
1129
1171
  manager.setPendingPrompt(interactiveSession.getPendingPrompt());
1130
1172
  }
1131
1173
  }, [manager.isThinking, interactiveSession, manager]);
1132
- const handleSubmit = useSlashRouting(interactiveSession, registry, manager);
1174
+ const handleSubmit = useSlashRouting(interactiveSession, registry, manager, commandEffectQueue);
1133
1175
  const handleAbort = (0, import_react2.useCallback)(() => {
1134
1176
  manager.setAborting(true);
1135
1177
  interactiveSession.abort();
@@ -1150,6 +1192,7 @@ function useInteractiveSession(props) {
1150
1192
  return {
1151
1193
  interactiveSession,
1152
1194
  registry,
1195
+ commandEffectQueue,
1153
1196
  history: manager.history,
1154
1197
  addEntry: (entry) => manager.addEntry(entry),
1155
1198
  streamingText: manager.streamingText,
@@ -1433,10 +1476,12 @@ function useSideEffects({
1433
1476
  cwd,
1434
1477
  providerOverride,
1435
1478
  interactiveSession,
1479
+ commandEffectQueue,
1436
1480
  addEntry,
1437
1481
  baseHandleSubmit,
1438
1482
  setSessionName,
1439
- setStatusLineSettings
1483
+ setStatusLineSettings,
1484
+ showSessionPickerOnStart
1440
1485
  }) {
1441
1486
  const { exit } = (0, import_ink.useApp)();
1442
1487
  const [pendingModelId, setPendingModelId] = (0, import_react4.useState)(null);
@@ -1444,7 +1489,7 @@ function useSideEffects({
1444
1489
  const [pendingInteractionPrompt, setPendingInteractionPrompt] = (0, import_react4.useState)(null);
1445
1490
  const commandInteractionRef = (0, import_react4.useRef)(null);
1446
1491
  const [showPluginTUI, setShowPluginTUI] = (0, import_react4.useState)(false);
1447
- const [showSessionPicker, setShowSessionPicker] = (0, import_react4.useState)(false);
1492
+ const [showSessionPicker, setShowSessionPicker] = (0, import_react4.useState)(showSessionPickerOnStart ?? false);
1448
1493
  const requestShutdown = (0, import_react4.useCallback)(
1449
1494
  (reason, message) => {
1450
1495
  addEntry((0, import_agent_core6.messageToHistoryEntry)((0, import_agent_core6.createSystemMessage)("Shutting down...")));
@@ -1485,33 +1530,31 @@ function useSideEffects({
1485
1530
  commandInteractionRef.current = null;
1486
1531
  setPendingInteractionPrompt(null);
1487
1532
  if (result.effects !== void 0 && result.effects.length > 0) {
1488
- applyEffects(result.effects, interactiveSession);
1533
+ applyEffects(result.effects, getHostSideEffects(interactiveSession));
1489
1534
  }
1490
1535
  },
1491
1536
  [addEntry, applyEffects, interactiveSession]
1492
1537
  );
1493
1538
  const applyQueuedCommandState = (0, import_react4.useCallback)(
1494
1539
  (sideEffects) => {
1495
- if (sideEffects._pendingCommandInteraction !== void 0) {
1496
- const interaction = sideEffects._pendingCommandInteraction;
1497
- delete sideEffects._pendingCommandInteraction;
1540
+ const queued = commandEffectQueue.drain();
1541
+ if (queued === void 0) {
1542
+ return false;
1543
+ }
1544
+ if (queued.type === "interaction") {
1545
+ const { interaction } = queued;
1498
1546
  commandInteractionRef.current = interaction;
1499
1547
  setPendingInteractionPrompt(interaction.prompt);
1500
1548
  return true;
1501
1549
  }
1502
- if (sideEffects._pendingCommandEffects !== void 0) {
1503
- const effects = sideEffects._pendingCommandEffects;
1504
- delete sideEffects._pendingCommandEffects;
1505
- return applyEffects(effects, sideEffects);
1506
- }
1507
- return false;
1550
+ return applyEffects(queued.effects, sideEffects);
1508
1551
  },
1509
- [applyEffects]
1552
+ [applyEffects, commandEffectQueue]
1510
1553
  );
1511
1554
  const handleSubmit = (0, import_react4.useCallback)(
1512
1555
  async (input) => {
1513
1556
  await baseHandleSubmit(input);
1514
- const sideEffects = interactiveSession;
1557
+ const sideEffects = getHostSideEffects(interactiveSession);
1515
1558
  if (applyQueuedCommandState(sideEffects)) return;
1516
1559
  if (sideEffects._pendingModelId) {
1517
1560
  const modelId = sideEffects._pendingModelId;
@@ -1622,6 +1665,9 @@ function useSideEffects({
1622
1665
  handleInteractionCancel
1623
1666
  };
1624
1667
  }
1668
+ function getHostSideEffects(interactiveSession) {
1669
+ return interactiveSession;
1670
+ }
1625
1671
 
1626
1672
  // src/ui/hooks/useStatusLineSettings.ts
1627
1673
  var import_react5 = require("react");
@@ -1639,10 +1685,12 @@ var import_agent_core8 = require("@robota-sdk/agent-core");
1639
1685
  // src/ui/render-markdown.ts
1640
1686
  var import_marked = require("marked");
1641
1687
  var import_marked_terminal = __toESM(require("marked-terminal"), 1);
1642
- var ANSI_RED = "\x1B[31m";
1643
- var ANSI_GREEN = "\x1B[32m";
1688
+ var ANSI_LIGHT_RED = "\x1B[38;5;210m";
1689
+ var ANSI_LIGHT_GREEN = "\x1B[38;5;120m";
1644
1690
  var ANSI_CYAN = "\x1B[36m";
1645
1691
  var ANSI_DIM = "\x1B[2m";
1692
+ var ANSI_DARK_RED_BACKGROUND = "\x1B[48;5;52m";
1693
+ var ANSI_DARK_GREEN_BACKGROUND = "\x1B[48;5;22m";
1646
1694
  var ANSI_RESET = "\x1B[0m";
1647
1695
  var CODE_BLOCK_INDENT = " ";
1648
1696
  var ZERO_COLOR = "0";
@@ -1662,36 +1710,59 @@ function shouldUseColor(option) {
1662
1710
  function isDiffLanguage(language) {
1663
1711
  return language?.trim().toLowerCase() === "diff";
1664
1712
  }
1665
- function colorizeDiffLine(line, color) {
1713
+ function styleAddedOrRemovedDiffRow(line, rowWidth, color) {
1714
+ const row = `${CODE_BLOCK_INDENT}${line}`.padEnd(rowWidth);
1666
1715
  if (!color) {
1667
- return line;
1716
+ return row.trimEnd();
1668
1717
  }
1669
1718
  if (line.startsWith("+")) {
1670
- return `${ANSI_GREEN}${line}${ANSI_RESET}`;
1719
+ return `${ANSI_DARK_GREEN_BACKGROUND}${ANSI_LIGHT_GREEN}${row}${ANSI_RESET}`;
1671
1720
  }
1672
1721
  if (line.startsWith("-")) {
1673
- return `${ANSI_RED}${line}${ANSI_RESET}`;
1722
+ return `${ANSI_DARK_RED_BACKGROUND}${ANSI_LIGHT_RED}${row}${ANSI_RESET}`;
1723
+ }
1724
+ return row.trimEnd();
1725
+ }
1726
+ function colorizeDiffLine(line, color, rowWidth) {
1727
+ if (line.startsWith("+") || line.startsWith("-")) {
1728
+ return styleAddedOrRemovedDiffRow(line, rowWidth, color);
1729
+ }
1730
+ const row = `${CODE_BLOCK_INDENT}${line}`;
1731
+ if (!color) {
1732
+ return row;
1674
1733
  }
1675
1734
  if (line.startsWith("@@")) {
1676
- return `${ANSI_CYAN}${line}${ANSI_RESET}`;
1735
+ return `${ANSI_CYAN}${row}${ANSI_RESET}`;
1677
1736
  }
1678
1737
  if (line.startsWith("diff ") || line.startsWith("index ")) {
1679
- return `${ANSI_DIM}${line}${ANSI_RESET}`;
1738
+ return `${ANSI_DIM}${row}${ANSI_RESET}`;
1680
1739
  }
1681
- return line;
1740
+ return row;
1682
1741
  }
1683
- function renderDiffCodeBlock(code, color) {
1684
- const body = code.split("\n").map((line) => `${CODE_BLOCK_INDENT}${colorizeDiffLine(line, color)}`).join("\n");
1742
+ function resolveDiffRowWidth(lines, requestedWidth) {
1743
+ const minimumWidth = lines.reduce(
1744
+ (maxWidth, line) => Math.max(maxWidth, CODE_BLOCK_INDENT.length + line.length),
1745
+ 0
1746
+ );
1747
+ if (requestedWidth === void 0) {
1748
+ return minimumWidth;
1749
+ }
1750
+ return Math.max(minimumWidth, requestedWidth);
1751
+ }
1752
+ function renderDiffCodeBlock(code, color, codeBlockWidth) {
1753
+ const lines = code.split("\n");
1754
+ const rowWidth = resolveDiffRowWidth(lines, codeBlockWidth);
1755
+ const body = lines.map((line) => colorizeDiffLine(line, color, rowWidth)).join("\n");
1685
1756
  return `${body}
1686
1757
 
1687
1758
  `;
1688
1759
  }
1689
- function createTerminalRenderer(color) {
1760
+ function createTerminalRenderer(color, codeBlockWidth) {
1690
1761
  const renderer = new TerminalRendererConstructor(void 0, { ignoreIllegals: true });
1691
1762
  const renderCode = renderer.code.bind(renderer);
1692
1763
  renderer.code = (code, language, escaped) => {
1693
1764
  if (isDiffLanguage(language)) {
1694
- return renderDiffCodeBlock(code, color);
1765
+ return renderDiffCodeBlock(code, color, codeBlockWidth);
1695
1766
  }
1696
1767
  return renderCode(code, language, escaped);
1697
1768
  };
@@ -1699,7 +1770,7 @@ function createTerminalRenderer(color) {
1699
1770
  }
1700
1771
  function renderMarkdown(md, options = {}) {
1701
1772
  const result = import_marked.marked.parse(md, {
1702
- renderer: createTerminalRenderer(shouldUseColor(options.color))
1773
+ renderer: createTerminalRenderer(shouldUseColor(options.color), options.codeBlockWidth)
1703
1774
  });
1704
1775
  return typeof result === "string" ? result.trimEnd() : md;
1705
1776
  }
@@ -2211,11 +2282,7 @@ function StatusActivityText({
2211
2282
  activeBackgroundTaskCount,
2212
2283
  hasPendingPrompt
2213
2284
  });
2214
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
2215
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink6.Text, { color: "cyan", bold: true, children: "Activity:" }),
2216
- " ",
2217
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink6.Text, { color: activity.color, bold: activity.kind !== "idle", children: activity.text })
2218
- ] });
2285
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink6.Text, { color: activity.color, bold: activity.kind !== "idle", children: activity.text });
2219
2286
  }
2220
2287
  function ContextText({
2221
2288
  percentage,
@@ -2239,77 +2306,79 @@ function ModeText({ permissionMode }) {
2239
2306
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink6.Text, { children: permissionMode })
2240
2307
  ] });
2241
2308
  }
2242
- function StatusLeft({
2243
- permissionMode,
2309
+ function shouldShowPermissionMode(permissionMode) {
2310
+ return permissionMode !== "default";
2311
+ }
2312
+ function ProviderText({
2244
2313
  modelName,
2245
- isThinking,
2246
- activeToolCount,
2247
- activeBackgroundTaskCount,
2248
- hasPendingPrompt,
2249
- contextPercentage,
2250
- contextUsedTokens,
2251
- contextMaxTokens,
2252
- sessionName,
2253
- gitBranch,
2254
- showGitBranch
2314
+ providerProfileName,
2315
+ providerType
2255
2316
  }) {
2256
- const shouldShowGitBranch = showGitBranch && gitBranch !== void 0 && gitBranch.length > 0;
2317
+ if (providerProfileName !== void 0 && providerType !== void 0) {
2318
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_ink6.Text, { dimColor: true, children: [
2319
+ providerProfileName,
2320
+ " (",
2321
+ providerType,
2322
+ ") ",
2323
+ modelName
2324
+ ] });
2325
+ }
2326
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink6.Text, { dimColor: true, children: modelName });
2327
+ }
2328
+ function StatusLeft(props) {
2329
+ const shouldShowGitBranch = props.showGitBranch && props.gitBranch !== void 0 && props.gitBranch.length > 0;
2330
+ const showPermissionMode = shouldShowPermissionMode(props.permissionMode);
2257
2331
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_ink6.Text, { children: [
2258
2332
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2259
2333
  StatusActivityText,
2260
2334
  {
2261
- isThinking,
2262
- activeToolCount,
2263
- activeBackgroundTaskCount,
2264
- hasPendingPrompt
2335
+ isThinking: props.isThinking,
2336
+ activeToolCount: props.activeToolCount,
2337
+ activeBackgroundTaskCount: props.activeBackgroundTaskCount,
2338
+ hasPendingPrompt: props.hasPendingPrompt
2265
2339
  }
2266
2340
  ),
2267
- " | ",
2268
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ModeText, { permissionMode }),
2269
- sessionName && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
2341
+ showPermissionMode && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
2342
+ " | ",
2343
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ModeText, { permissionMode: props.permissionMode })
2344
+ ] }),
2345
+ props.sessionName && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
2270
2346
  " | ",
2271
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink6.Text, { color: "magenta", children: sessionName })
2347
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink6.Text, { color: "magenta", children: props.sessionName })
2272
2348
  ] }),
2273
2349
  shouldShowGitBranch && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
2274
2350
  " | ",
2275
2351
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_ink6.Text, { dimColor: true, children: [
2276
2352
  "git: ",
2277
- gitBranch
2353
+ props.gitBranch
2278
2354
  ] })
2279
2355
  ] }),
2280
2356
  " | ",
2281
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink6.Text, { dimColor: true, children: modelName }),
2357
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2358
+ ProviderText,
2359
+ {
2360
+ modelName: props.modelName,
2361
+ providerProfileName: props.providerProfileName,
2362
+ providerType: props.providerType
2363
+ }
2364
+ ),
2282
2365
  " | ",
2283
2366
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2284
2367
  ContextText,
2285
2368
  {
2286
- percentage: contextPercentage,
2287
- usedTokens: contextUsedTokens,
2288
- maxTokens: contextMaxTokens
2369
+ percentage: props.contextPercentage,
2370
+ usedTokens: props.contextUsedTokens,
2371
+ maxTokens: props.contextMaxTokens
2289
2372
  }
2290
2373
  )
2291
2374
  ] });
2292
2375
  }
2293
- function StatusRight({
2294
- isThinking,
2295
- messageCount
2296
- }) {
2297
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_ink6.Text, { children: [
2298
- isThinking && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
2299
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink6.Text, { color: "yellow", children: "thinking..." }),
2300
- " "
2301
- ] }),
2302
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_ink6.Text, { dimColor: true, children: [
2303
- "msgs: ",
2304
- messageCount
2305
- ] })
2306
- ] });
2307
- }
2308
2376
  function StatusBar({
2309
2377
  permissionMode,
2310
2378
  modelName,
2379
+ providerProfileName,
2380
+ providerType,
2311
2381
  sessionId: _sessionId,
2312
- messageCount,
2313
2382
  isThinking,
2314
2383
  activeToolCount = 0,
2315
2384
  activeBackgroundTaskCount = 0,
@@ -2321,7 +2390,7 @@ function StatusBar({
2321
2390
  gitBranch,
2322
2391
  showGitBranch = true
2323
2392
  }) {
2324
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2393
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2325
2394
  import_ink6.Box,
2326
2395
  {
2327
2396
  borderStyle: "single",
@@ -2329,26 +2398,25 @@ function StatusBar({
2329
2398
  paddingLeft: 1,
2330
2399
  paddingRight: 1,
2331
2400
  justifyContent: "space-between",
2332
- children: [
2333
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2334
- StatusLeft,
2335
- {
2336
- permissionMode,
2337
- modelName,
2338
- isThinking,
2339
- activeToolCount,
2340
- activeBackgroundTaskCount,
2341
- hasPendingPrompt,
2342
- contextPercentage,
2343
- contextUsedTokens,
2344
- contextMaxTokens,
2345
- sessionName,
2346
- gitBranch,
2347
- showGitBranch
2348
- }
2349
- ),
2350
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StatusRight, { isThinking, messageCount })
2351
- ]
2401
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2402
+ StatusLeft,
2403
+ {
2404
+ permissionMode,
2405
+ modelName,
2406
+ providerProfileName,
2407
+ providerType,
2408
+ isThinking,
2409
+ activeToolCount,
2410
+ activeBackgroundTaskCount,
2411
+ hasPendingPrompt,
2412
+ contextPercentage,
2413
+ contextUsedTokens,
2414
+ contextMaxTokens,
2415
+ sessionName,
2416
+ gitBranch,
2417
+ showGitBranch
2418
+ }
2419
+ )
2352
2420
  }
2353
2421
  );
2354
2422
  }
@@ -2359,8 +2427,9 @@ function SessionStatusBar({
2359
2427
  cwd,
2360
2428
  permissionMode,
2361
2429
  modelId,
2430
+ providerProfileName,
2431
+ providerType,
2362
2432
  sessionId,
2363
- messageCount,
2364
2433
  isThinking,
2365
2434
  activeToolCount,
2366
2435
  activeBackgroundTaskCount,
@@ -2376,8 +2445,9 @@ function SessionStatusBar({
2376
2445
  {
2377
2446
  permissionMode,
2378
2447
  modelName: modelId ? (0, import_agent_core10.getModelName)(modelId) : "",
2448
+ providerProfileName,
2449
+ providerType,
2379
2450
  sessionId,
2380
- messageCount,
2381
2451
  isThinking,
2382
2452
  activeToolCount,
2383
2453
  activeBackgroundTaskCount,
@@ -3405,6 +3475,7 @@ function submitTextPromptValue(state, options) {
3405
3475
  var import_jsx_runtime13 = require("react/jsx-runtime");
3406
3476
  function TextPrompt({
3407
3477
  title,
3478
+ description,
3408
3479
  placeholder,
3409
3480
  onSubmit,
3410
3481
  onCancel,
@@ -3429,12 +3500,11 @@ function TextPrompt({
3429
3500
  );
3430
3501
  (0, import_ink13.useInput)((input, key) => {
3431
3502
  const action = getTextPromptInputAction(input, key);
3432
- if (action !== void 0) {
3433
- applyAction(action);
3434
- }
3503
+ if (action !== void 0) applyAction(action);
3435
3504
  });
3436
3505
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink13.Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
3437
3506
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink13.Text, { color: "yellow", bold: true, children: title }),
3507
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PromptDescription, { description }),
3438
3508
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink13.Box, { marginTop: 1, children: [
3439
3509
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink13.Text, { color: "cyan", children: "> " }),
3440
3510
  state.value ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink13.Text, { children: masked ? "*".repeat(state.value.length) : state.value }) : placeholder ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink13.Text, { dimColor: true, children: placeholder }) : null,
@@ -3444,6 +3514,12 @@ function TextPrompt({
3444
3514
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink13.Text, { dimColor: true, children: " Enter Submit Esc Cancel" })
3445
3515
  ] });
3446
3516
  }
3517
+ function PromptDescription({ description }) {
3518
+ if (description === void 0 || description.length === 0) {
3519
+ return null;
3520
+ }
3521
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink13.Text, { dimColor: true, children: description });
3522
+ }
3447
3523
 
3448
3524
  // src/ui/InteractivePrompt.tsx
3449
3525
  var import_jsx_runtime14 = require("react/jsx-runtime");
@@ -3457,6 +3533,7 @@ function InteractivePrompt({
3457
3533
  TextPrompt,
3458
3534
  {
3459
3535
  title: prompt.title,
3536
+ description: prompt.description,
3460
3537
  placeholder: prompt.placeholder,
3461
3538
  allowEmpty: prompt.allowEmpty,
3462
3539
  masked: prompt.masked,
@@ -3469,6 +3546,7 @@ function InteractivePrompt({
3469
3546
  }
3470
3547
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_ink14.Box, { flexDirection: "column", children: [
3471
3548
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink14.Text, { bold: true, children: prompt.title }),
3549
+ prompt.description !== void 0 && prompt.description.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink14.Text, { dimColor: true, children: prompt.description }),
3472
3550
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3473
3551
  ListPicker,
3474
3552
  {
@@ -4059,26 +4137,20 @@ function PluginTUI({ callbacks, onClose, addMessage }) {
4059
4137
  var import_ink18 = require("ink");
4060
4138
  var import_jsx_runtime19 = require("react/jsx-runtime");
4061
4139
  var SESSION_ID_DISPLAY_LENGTH = 8;
4140
+ var SESSION_PREVIEW_DISPLAY_LENGTH = 60;
4062
4141
  function SessionPicker({
4063
- sessionStore,
4064
- cwd,
4142
+ sessions,
4065
4143
  onSelect,
4066
4144
  onCancel
4067
4145
  }) {
4068
- const sessions = (sessionStore?.list() ?? []).filter((s) => s.cwd === cwd);
4069
4146
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_ink18.Box, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
4070
4147
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_ink18.Text, { bold: true, color: "cyan", children: "Select a session to resume (ESC to cancel):" }),
4071
4148
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4072
4149
  ListPicker,
4073
4150
  {
4074
- items: sessions,
4151
+ items: [...sessions],
4075
4152
  renderItem: (session, isSelected) => {
4076
- const lastMsg = session.messages.slice().reverse().find((m) => {
4077
- const msg = m;
4078
- return msg.role === "assistant" && msg.content;
4079
- });
4080
- const rawPreview = lastMsg?.content?.replace(/[\n\r]+/g, " ").trim() ?? "";
4081
- const preview = rawPreview ? rawPreview.slice(0, 60) + (rawPreview.length > 60 ? "..." : "") : "";
4153
+ const preview = session.preview ? session.preview.slice(0, SESSION_PREVIEW_DISPLAY_LENGTH) + (session.preview.length > SESSION_PREVIEW_DISPLAY_LENGTH ? "..." : "") : "";
4082
4154
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_ink18.Text, { children: [
4083
4155
  isSelected ? "> " : " ",
4084
4156
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_ink18.Text, { bold: true, children: session.name ?? session.id.slice(0, SESSION_ID_DISPLAY_LENGTH) }),
@@ -4092,7 +4164,7 @@ function SessionPicker({
4092
4164
  " ",
4093
4165
  /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_ink18.Text, { dimColor: true, children: [
4094
4166
  "msgs: ",
4095
- session.messages.length
4167
+ session.messageCount
4096
4168
  ] }),
4097
4169
  preview ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
4098
4170
  "\n ",
@@ -4488,12 +4560,19 @@ function isJsonObject(value) {
4488
4560
  var import_jsx_runtime22 = require("react/jsx-runtime");
4489
4561
  function App(props) {
4490
4562
  const [activeSessionId, setActiveSessionId] = (0, import_react19.useState)(props.resumeSessionId);
4563
+ const [showInitialSessionPicker, setShowInitialSessionPicker] = (0, import_react19.useState)(
4564
+ props.showSessionPickerOnStart ?? false
4565
+ );
4491
4566
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4492
4567
  AppInner,
4493
4568
  {
4494
4569
  ...props,
4570
+ showSessionPickerOnStart: showInitialSessionPicker,
4495
4571
  resumeSessionId: activeSessionId,
4496
- onSessionSwitch: (sessionId) => setActiveSessionId(sessionId)
4572
+ onSessionSwitch: (sessionId) => {
4573
+ setShowInitialSessionPicker(false);
4574
+ setActiveSessionId(sessionId);
4575
+ }
4497
4576
  },
4498
4577
  activeSessionId ?? "__new__"
4499
4578
  );
@@ -4503,6 +4582,7 @@ function AppInner(props) {
4503
4582
  const {
4504
4583
  interactiveSession,
4505
4584
  registry,
4585
+ commandEffectQueue,
4506
4586
  history,
4507
4587
  addEntry,
4508
4588
  streamingText,
@@ -4556,10 +4636,12 @@ function AppInner(props) {
4556
4636
  cwd,
4557
4637
  providerOverride: props.providerOverride,
4558
4638
  interactiveSession,
4639
+ commandEffectQueue,
4559
4640
  addEntry,
4560
4641
  baseHandleSubmit,
4561
4642
  setSessionName,
4562
- setStatusLineSettings
4643
+ setStatusLineSettings,
4644
+ showSessionPickerOnStart: props.showSessionPickerOnStart
4563
4645
  });
4564
4646
  (0, import_react19.useEffect)(() => {
4565
4647
  const name = interactiveSession?.getName?.();
@@ -4665,8 +4747,7 @@ function AppInner(props) {
4665
4747
  showSessionPicker && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4666
4748
  SessionPicker,
4667
4749
  {
4668
- sessionStore: props.sessionStore,
4669
- cwd: props.cwd,
4750
+ sessions: (0, import_agent_sdk9.listResumableSessionSummaries)(props.sessionStore, props.cwd),
4670
4751
  onSelect: (id) => {
4671
4752
  setShowSessionPicker(false);
4672
4753
  props.onSessionSwitch(id);
@@ -4683,8 +4764,9 @@ function AppInner(props) {
4683
4764
  cwd,
4684
4765
  permissionMode,
4685
4766
  modelId: props.modelId,
4767
+ providerProfileName: props.providerProfileName,
4768
+ providerType: props.providerType,
4686
4769
  sessionId,
4687
- messageCount: history.length,
4688
4770
  isThinking,
4689
4771
  activeToolCount: activeTools.length,
4690
4772
  activeBackgroundTaskCount,
@@ -4740,43 +4822,14 @@ function renderApp(options) {
4740
4822
 
4741
4823
  // src/background/managed-shell-process-runner.ts
4742
4824
  var import_node_child_process = require("child_process");
4743
- var import_agent_sdk9 = require("@robota-sdk/agent-sdk");
4825
+ var import_agent_sdk10 = require("@robota-sdk/agent-sdk");
4744
4826
  var DEFAULT_OUTPUT_LIMIT_BYTES = 3e4;
4745
4827
  var DEFAULT_KILL_GRACE_MS = 2e3;
4746
- var LOG_PAGE_SIZE = 200;
4747
- function createCapture(limitBytes) {
4748
- const chunks = [];
4749
- let capturedBytes = 0;
4750
- let truncated = false;
4751
- return {
4752
- appendOutput(text) {
4753
- if (truncated) return;
4754
- const remaining = limitBytes - capturedBytes;
4755
- const buffer = Buffer.from(text, "utf8");
4756
- if (buffer.byteLength <= remaining) {
4757
- chunks.push(text);
4758
- capturedBytes += buffer.byteLength;
4759
- return;
4760
- }
4761
- chunks.push(buffer.subarray(0, Math.max(remaining, 0)).toString("utf8"));
4762
- chunks.push("\n[output truncated]\n");
4763
- truncated = true;
4764
- },
4765
- getOutput() {
4766
- return chunks.join("");
4767
- }
4768
- };
4769
- }
4770
- function appendLog(lines, source, text) {
4771
- for (const line of text.split(/\r?\n/)) {
4772
- if (line.length > 0) lines.push(`[${source}] ${line}`);
4773
- }
4774
- }
4775
4828
  function resolveShell(request) {
4776
4829
  return { command: request.shell ?? "sh", args: ["-c", request.command] };
4777
4830
  }
4778
4831
  function sendInput(child, input) {
4779
- return new Promise((resolve2, reject) => {
4832
+ return new Promise((resolve3, reject) => {
4780
4833
  const onError = (error) => {
4781
4834
  child.stdin.off("error", onError);
4782
4835
  reject(error);
@@ -4784,7 +4837,7 @@ function sendInput(child, input) {
4784
4837
  child.stdin.once("error", onError);
4785
4838
  child.stdin.end(input, () => {
4786
4839
  child.stdin.off("error", onError);
4787
- resolve2();
4840
+ resolve3();
4788
4841
  });
4789
4842
  });
4790
4843
  }
@@ -4794,7 +4847,7 @@ function createManagedShellProcessRunner(options = {}) {
4794
4847
  kind: "process",
4795
4848
  start(task) {
4796
4849
  if (task.request.kind !== "process") {
4797
- throw new import_agent_sdk9.BackgroundTaskError("runner", `Invalid process task kind: ${task.request.kind}`);
4850
+ throw new import_agent_sdk10.BackgroundTaskError("runner", `Invalid process task kind: ${task.request.kind}`);
4798
4851
  }
4799
4852
  return startProcessTask(task.taskId, task.request, killGraceMs);
4800
4853
  }
@@ -4811,7 +4864,9 @@ function startProcessTask(taskId, request, killGraceMs) {
4811
4864
  stdio: ["pipe", "pipe", "pipe"]
4812
4865
  }),
4813
4866
  logs: [],
4814
- capture: createCapture(request.outputLimitBytes ?? DEFAULT_OUTPUT_LIMIT_BYTES),
4867
+ capture: (0, import_agent_sdk10.createLimitedOutputCapture)({
4868
+ limitBytes: request.outputLimitBytes ?? DEFAULT_OUTPUT_LIMIT_BYTES
4869
+ }),
4815
4870
  killGraceMs
4816
4871
  };
4817
4872
  const result = createProcessResult(runtime);
@@ -4819,11 +4874,15 @@ function startProcessTask(taskId, request, killGraceMs) {
4819
4874
  }
4820
4875
  function createProcessResult(runtime) {
4821
4876
  let settled = false;
4822
- return new Promise((resolve2, reject) => {
4877
+ return new Promise((resolve3, reject) => {
4823
4878
  const timeoutTimer = runtime.request.timeoutMs ? setTimeout(() => {
4824
- appendLog(runtime.logs, "system", `timed out after ${runtime.request.timeoutMs}ms`);
4879
+ (0, import_agent_sdk10.appendPrefixedLogLines)(
4880
+ runtime.logs,
4881
+ "system",
4882
+ `timed out after ${runtime.request.timeoutMs}ms`
4883
+ );
4825
4884
  runtime.child.kill("SIGTERM");
4826
- rejectOnceLocal(new import_agent_sdk9.BackgroundTaskError("timeout", "Background process timed out"));
4885
+ rejectOnceLocal(new import_agent_sdk10.BackgroundTaskError("timeout", "Background process timed out"));
4827
4886
  }, runtime.request.timeoutMs) : void 0;
4828
4887
  function clearTimers() {
4829
4888
  if (timeoutTimer) clearTimeout(timeoutTimer);
@@ -4833,7 +4892,7 @@ function createProcessResult(runtime) {
4833
4892
  if (settled) return;
4834
4893
  settled = true;
4835
4894
  clearTimers();
4836
- resolve2({
4895
+ resolve3({
4837
4896
  taskId: runtime.taskId,
4838
4897
  kind: "process",
4839
4898
  output: runtime.capture.getOutput(),
@@ -4849,8 +4908,8 @@ function createProcessResult(runtime) {
4849
4908
  }
4850
4909
  attachOutputListeners(runtime);
4851
4910
  runtime.child.on("error", (error) => {
4852
- appendLog(runtime.logs, "system", error.message);
4853
- rejectOnceLocal(new import_agent_sdk9.BackgroundTaskError("process", error.message));
4911
+ (0, import_agent_sdk10.appendPrefixedLogLines)(runtime.logs, "system", error.message);
4912
+ rejectOnceLocal(new import_agent_sdk10.BackgroundTaskError("process", error.message));
4854
4913
  });
4855
4914
  runtime.child.on("close", (code, signal) => {
4856
4915
  resolveOnce(code ?? void 0, signal ?? void 0);
@@ -4880,40 +4939,37 @@ function attachOutputListeners(runtime) {
4880
4939
  runtime.child.stdout.on("data", (chunk) => {
4881
4940
  const text = chunk.toString("utf8");
4882
4941
  runtime.capture.appendOutput(text);
4883
- appendLog(runtime.logs, "stdout", text);
4942
+ (0, import_agent_sdk10.appendPrefixedLogLines)(runtime.logs, "stdout", text);
4884
4943
  });
4885
4944
  runtime.child.stderr.on("data", (chunk) => {
4886
4945
  const text = chunk.toString("utf8");
4887
4946
  runtime.capture.appendOutput(text);
4888
- appendLog(runtime.logs, "stderr", text);
4947
+ (0, import_agent_sdk10.appendPrefixedLogLines)(runtime.logs, "stderr", text);
4889
4948
  });
4890
4949
  }
4891
4950
  function cancelProcess(runtime, reason) {
4892
- appendLog(runtime.logs, "system", reason ? `cancel requested: ${reason}` : "cancel requested");
4951
+ (0, import_agent_sdk10.appendPrefixedLogLines)(
4952
+ runtime.logs,
4953
+ "system",
4954
+ reason ? `cancel requested: ${reason}` : "cancel requested"
4955
+ );
4893
4956
  if (!runtime.child.killed) runtime.child.kill("SIGTERM");
4894
4957
  runtime.killTimer = setTimeout(() => {
4895
4958
  if (!runtime.child.killed) runtime.child.kill("SIGKILL");
4896
4959
  }, runtime.killGraceMs);
4897
4960
  }
4898
4961
  function readProcessLog(runtime, cursor) {
4899
- const offset = cursor?.offset ?? 0;
4900
- const nextOffset = Math.min(offset + LOG_PAGE_SIZE, runtime.logs.length);
4901
- return {
4902
- taskId: runtime.taskId,
4903
- cursor,
4904
- nextCursor: nextOffset < runtime.logs.length ? { offset: nextOffset } : void 0,
4905
- lines: runtime.logs.slice(offset, nextOffset)
4906
- };
4962
+ return (0, import_agent_sdk10.createBackgroundTaskLogPage)(runtime.taskId, runtime.logs, cursor);
4907
4963
  }
4908
4964
 
4909
4965
  // src/subagents/child-process-subagent-runner.ts
4910
4966
  var import_node_child_process3 = require("child_process");
4911
4967
  var import_node_fs7 = require("fs");
4912
4968
  var import_node_path9 = require("path");
4913
- var import_agent_sdk13 = require("@robota-sdk/agent-sdk");
4969
+ var import_agent_sdk14 = require("@robota-sdk/agent-sdk");
4914
4970
 
4915
4971
  // src/subagents/child-process-subagent-runner-result.ts
4916
- var import_agent_sdk11 = require("@robota-sdk/agent-sdk");
4972
+ var import_agent_sdk12 = require("@robota-sdk/agent-sdk");
4917
4973
 
4918
4974
  // src/subagents/child-process-subagent-ipc.ts
4919
4975
  function isRecord2(value) {
@@ -4945,7 +5001,7 @@ function isSubagentWorkerChildMessage(value) {
4945
5001
  }
4946
5002
 
4947
5003
  // src/subagents/child-process-subagent-transport.ts
4948
- var import_agent_sdk10 = require("@robota-sdk/agent-sdk");
5004
+ var import_agent_sdk11 = require("@robota-sdk/agent-sdk");
4949
5005
  function handleWorkerMessage(message, startWorker, resolveOnce, rejectOnce, emit) {
4950
5006
  switch (message.type) {
4951
5007
  case "ready":
@@ -4955,10 +5011,10 @@ function handleWorkerMessage(message, startWorker, resolveOnce, rejectOnce, emit
4955
5011
  resolveOnce(message.output);
4956
5012
  break;
4957
5013
  case "error":
4958
- rejectOnce(new import_agent_sdk10.BackgroundTaskError("runner", message.message));
5014
+ rejectOnce(new import_agent_sdk11.BackgroundTaskError("runner", message.message));
4959
5015
  break;
4960
5016
  case "cancelled":
4961
- rejectOnce(new import_agent_sdk10.BackgroundTaskError("runner", message.reason ?? "Subagent worker cancelled"));
5017
+ rejectOnce(new import_agent_sdk11.BackgroundTaskError("runner", message.reason ?? "Subagent worker cancelled"));
4962
5018
  break;
4963
5019
  case "text_delta":
4964
5020
  emit?.({ type: "background_task_text_delta", delta: message.delta });
@@ -4978,7 +5034,7 @@ function handleWorkerMessage(message, startWorker, resolveOnce, rejectOnce, emit
4978
5034
  });
4979
5035
  break;
4980
5036
  default:
4981
- rejectOnce(new import_agent_sdk10.BackgroundTaskError("runner", "Unhandled subagent worker message"));
5037
+ rejectOnce(new import_agent_sdk11.BackgroundTaskError("runner", "Unhandled subagent worker message"));
4982
5038
  }
4983
5039
  }
4984
5040
  function extractFirstArg(toolArgs) {
@@ -4988,9 +5044,9 @@ function extractFirstArg(toolArgs) {
4988
5044
  return typeof firstValue === "object" ? JSON.stringify(firstValue) : String(firstValue);
4989
5045
  }
4990
5046
  function sendWorkerMessage(child, message) {
4991
- return new Promise((resolve2, reject) => {
5047
+ return new Promise((resolve3, reject) => {
4992
5048
  if (!child.connected) {
4993
- reject(new import_agent_sdk10.BackgroundTaskError("crash", "Subagent worker IPC channel is closed"));
5049
+ reject(new import_agent_sdk11.BackgroundTaskError("crash", "Subagent worker IPC channel is closed"));
4994
5050
  return;
4995
5051
  }
4996
5052
  child.send(message, (error) => {
@@ -4998,7 +5054,7 @@ function sendWorkerMessage(child, message) {
4998
5054
  reject(error);
4999
5055
  return;
5000
5056
  }
5001
- resolve2();
5057
+ resolve3();
5002
5058
  });
5003
5059
  });
5004
5060
  }
@@ -5015,14 +5071,14 @@ async function cancelChildProcess(runtime, reason) {
5015
5071
 
5016
5072
  // src/subagents/child-process-subagent-runner-result.ts
5017
5073
  function createChildProcessSubagentResult(options) {
5018
- return new Promise((resolve2, reject) => {
5019
- new ChildProcessSubagentResultController(options, resolve2, reject).start();
5074
+ return new Promise((resolve3, reject) => {
5075
+ new ChildProcessSubagentResultController(options, resolve3, reject).start();
5020
5076
  });
5021
5077
  }
5022
5078
  var ChildProcessSubagentResultController = class {
5023
- constructor(options, resolve2, reject) {
5079
+ constructor(options, resolve3, reject) {
5024
5080
  this.options = options;
5025
- this.resolve = resolve2;
5081
+ this.resolve = resolve3;
5026
5082
  this.reject = reject;
5027
5083
  this.timeoutTimer = createTimeoutTimer(this.options.runtime, (error) => this.rejectOnce(error));
5028
5084
  }
@@ -5051,7 +5107,7 @@ var ChildProcessSubagentResultController = class {
5051
5107
  onMessage = (message) => {
5052
5108
  if (!isSubagentWorkerChildMessage(message)) {
5053
5109
  this.rejectOnce(
5054
- new import_agent_sdk11.BackgroundTaskError("runner", "Received malformed subagent worker message")
5110
+ new import_agent_sdk12.BackgroundTaskError("runner", "Received malformed subagent worker message")
5055
5111
  );
5056
5112
  return;
5057
5113
  }
@@ -5059,11 +5115,11 @@ var ChildProcessSubagentResultController = class {
5059
5115
  handleWorkerMessage(message, this.startWorker, this.resolveOnce, this.rejectOnce, job.emit);
5060
5116
  };
5061
5117
  onError = (error) => {
5062
- this.rejectOnce(new import_agent_sdk11.BackgroundTaskError("crash", error.message));
5118
+ this.rejectOnce(new import_agent_sdk12.BackgroundTaskError("crash", error.message));
5063
5119
  };
5064
5120
  onExit = (code, signal) => {
5065
5121
  if (this.settled) return;
5066
- this.rejectOnce(new import_agent_sdk11.BackgroundTaskError("crash", formatEarlyExitMessage(code, signal)));
5122
+ this.rejectOnce(new import_agent_sdk12.BackgroundTaskError("crash", formatEarlyExitMessage(code, signal)));
5067
5123
  };
5068
5124
  resolveOnce = (output) => {
5069
5125
  if (this.settled) return;
@@ -5103,7 +5159,7 @@ function createCancellationResult(jobId) {
5103
5159
  reject(reason) {
5104
5160
  if (settled) return;
5105
5161
  settled = true;
5106
- rejectFn(new import_agent_sdk11.BackgroundTaskError("runner", reason ?? `Subagent job cancelled: ${jobId}`));
5162
+ rejectFn(new import_agent_sdk12.BackgroundTaskError("runner", reason ?? `Subagent job cancelled: ${jobId}`));
5107
5163
  }
5108
5164
  };
5109
5165
  }
@@ -5111,7 +5167,7 @@ function createTimeoutTimer(runtime, rejectOnce) {
5111
5167
  if (!runtime.job.request.timeoutMs) return void 0;
5112
5168
  return setTimeout(() => {
5113
5169
  void cancelChildProcess(runtime, "Subagent worker timed out");
5114
- rejectOnce(new import_agent_sdk11.BackgroundTaskError("timeout", "Subagent worker timed out"));
5170
+ rejectOnce(new import_agent_sdk12.BackgroundTaskError("timeout", "Subagent worker timed out"));
5115
5171
  }, runtime.job.request.timeoutMs);
5116
5172
  }
5117
5173
  function toSubagentResult(job, output, resolveTranscriptPath) {
@@ -5129,10 +5185,10 @@ function formatEarlyExitMessage(code, signal) {
5129
5185
 
5130
5186
  // src/subagents/git-worktree-isolation-adapter.ts
5131
5187
  var import_node_child_process2 = require("child_process");
5132
- var import_node_crypto2 = require("crypto");
5188
+ var import_node_crypto = require("crypto");
5133
5189
  var import_node_fs6 = require("fs");
5134
5190
  var import_node_path8 = require("path");
5135
- var import_agent_sdk12 = require("@robota-sdk/agent-sdk");
5191
+ var import_agent_sdk13 = require("@robota-sdk/agent-sdk");
5136
5192
  var WORKTREE_DIR = ".robota/worktrees";
5137
5193
  var BRANCH_PREFIX = "robota";
5138
5194
  var GIT_ENCODING = "utf8";
@@ -5155,7 +5211,7 @@ var GitWorktreeIsolationAdapter = class {
5155
5211
  }
5156
5212
  prepare(request) {
5157
5213
  if (this.maxCreateAttempts < 1) {
5158
- throw new import_agent_sdk12.BackgroundTaskError("runner", "Git worktree creation attempts must be at least 1");
5214
+ throw new import_agent_sdk13.BackgroundTaskError("runner", "Git worktree creation attempts must be at least 1");
5159
5215
  }
5160
5216
  const repoRoot = resolveRepoRoot(request.cwd);
5161
5217
  const baseRevision = runGit(repoRoot, ["rev-parse", "HEAD"]).trim();
@@ -5176,7 +5232,7 @@ var GitWorktreeIsolationAdapter = class {
5176
5232
  if (!isCollisionError(lastError)) throw lastError;
5177
5233
  }
5178
5234
  }
5179
- throw new import_agent_sdk12.BackgroundTaskError(
5235
+ throw new import_agent_sdk13.BackgroundTaskError(
5180
5236
  "runner",
5181
5237
  `Unable to create Git worktree after ${this.maxCreateAttempts} attempts due to branch or path collisions. Last error: ${lastError?.message ?? "unknown error"}`
5182
5238
  );
@@ -5202,7 +5258,7 @@ function runGit(cwd, args) {
5202
5258
  });
5203
5259
  } catch (error) {
5204
5260
  const message = error instanceof Error ? error.message : String(error);
5205
- throw new import_agent_sdk12.BackgroundTaskError("runner", `git ${args.join(" ")} failed: ${message}`);
5261
+ throw new import_agent_sdk13.BackgroundTaskError("runner", `git ${args.join(" ")} failed: ${message}`);
5206
5262
  }
5207
5263
  }
5208
5264
  function createGitEnvironment() {
@@ -5219,14 +5275,14 @@ function resolveRepoRoot(cwd) {
5219
5275
  return runGit(cwd, ["rev-parse", "--show-toplevel"]).trim();
5220
5276
  } catch (error) {
5221
5277
  const message = error instanceof Error ? error.message : String(error);
5222
- throw new import_agent_sdk12.BackgroundTaskError(
5278
+ throw new import_agent_sdk13.BackgroundTaskError(
5223
5279
  "runner",
5224
5280
  `Worktree isolation requires a Git repository. Run from a Git worktree or request isolation "none". Details: ${message}`
5225
5281
  );
5226
5282
  }
5227
5283
  }
5228
5284
  function createShortId() {
5229
- return (0, import_node_crypto2.randomUUID)().slice(0, SHORT_ID_LENGTH);
5285
+ return (0, import_node_crypto.randomUUID)().slice(0, SHORT_ID_LENGTH);
5230
5286
  }
5231
5287
  function normalizeShortId(value) {
5232
5288
  const sanitized = sanitizePathSegment(value).slice(0, SHORT_ID_LENGTH);
@@ -5245,12 +5301,11 @@ function isCollisionError(error) {
5245
5301
 
5246
5302
  // src/subagents/child-process-subagent-runner.ts
5247
5303
  var DEFAULT_KILL_GRACE_MS2 = 2e3;
5248
- var LOG_PAGE_SIZE2 = 200;
5249
5304
  function createChildProcessSubagentRunnerFactory(options = {}) {
5250
5305
  return (deps) => {
5251
5306
  const runner = new ChildProcessSubagentRunner(deps, options);
5252
5307
  if (options.worktreeIsolation === false) return runner;
5253
- return (0, import_agent_sdk13.createWorktreeSubagentRunner)({
5308
+ return (0, import_agent_sdk14.createWorktreeSubagentRunner)({
5254
5309
  runner,
5255
5310
  worktreeAdapter: options.worktreeAdapter ?? createGitWorktreeIsolationAdapter(),
5256
5311
  hooks: deps.config.hooks,
@@ -5332,9 +5387,9 @@ var ChildProcessSubagentRunner = class {
5332
5387
  }
5333
5388
  };
5334
5389
  function resolveAgentDefinition(agentType, customRegistry) {
5335
- const definition = customRegistry?.(agentType) ?? (0, import_agent_sdk13.getBuiltInAgent)(agentType);
5390
+ const definition = customRegistry?.(agentType) ?? (0, import_agent_sdk14.getBuiltInAgent)(agentType);
5336
5391
  if (!definition) {
5337
- throw new import_agent_sdk13.BackgroundTaskError("validation", `Unknown agent type: ${agentType}`);
5392
+ throw new import_agent_sdk14.BackgroundTaskError("validation", `Unknown agent type: ${agentType}`);
5338
5393
  }
5339
5394
  return definition;
5340
5395
  }
@@ -5383,7 +5438,6 @@ function resolveDefaultExecArgv(workerPath) {
5383
5438
  return [...process.execArgv, "--import", "tsx"];
5384
5439
  }
5385
5440
  function readTranscriptLog(jobId, transcriptPath, cursor) {
5386
- const offset = cursor?.offset ?? 0;
5387
5441
  if (!(0, import_node_fs7.existsSync)(transcriptPath)) {
5388
5442
  return {
5389
5443
  taskId: jobId,
@@ -5392,13 +5446,7 @@ function readTranscriptLog(jobId, transcriptPath, cursor) {
5392
5446
  };
5393
5447
  }
5394
5448
  const lines = (0, import_node_fs7.readFileSync)(transcriptPath, "utf8").split(/\r?\n/).filter(Boolean);
5395
- const nextOffset = Math.min(offset + LOG_PAGE_SIZE2, lines.length);
5396
- return {
5397
- taskId: jobId,
5398
- cursor,
5399
- nextCursor: nextOffset < lines.length ? { offset: nextOffset } : void 0,
5400
- lines: lines.slice(offset, nextOffset)
5401
- };
5449
+ return (0, import_agent_sdk14.createBackgroundTaskLogPage)(jobId, lines, cursor);
5402
5450
  }
5403
5451
 
5404
5452
  // src/cli.ts
@@ -5424,7 +5472,7 @@ function readVersion() {
5424
5472
  }
5425
5473
  }
5426
5474
  function promptInput(label, masked = false) {
5427
- return new Promise((resolve2) => {
5475
+ return new Promise((resolve3) => {
5428
5476
  process.stdout.write(label);
5429
5477
  let input = "";
5430
5478
  const stdin = process.stdin;
@@ -5439,7 +5487,7 @@ function promptInput(label, masked = false) {
5439
5487
  stdin.setRawMode(wasRaw ?? false);
5440
5488
  stdin.pause();
5441
5489
  process.stdout.write("\n");
5442
- resolve2(input.trim());
5490
+ resolve3(input.trim());
5443
5491
  return;
5444
5492
  } else if (ch === "\x7F" || ch === "\b") {
5445
5493
  if (input.length > 0) {
@@ -5458,6 +5506,15 @@ function promptInput(label, masked = false) {
5458
5506
  stdin.on("data", onData);
5459
5507
  });
5460
5508
  }
5509
+ function readTaskFilePrompt(cwd, taskFile) {
5510
+ const taskPath = (0, import_node_path10.resolve)(cwd, taskFile);
5511
+ const content = (0, import_node_fs8.readFileSync)(taskPath, "utf8").trim();
5512
+ if (content.length === 0) {
5513
+ throw new Error(`Task file is empty: ${taskFile}`);
5514
+ }
5515
+ return `Task file (${taskFile}):
5516
+ ${content}`;
5517
+ }
5461
5518
  function resetConfig() {
5462
5519
  const userPath = getUserSettingsPath();
5463
5520
  if (deleteSettings(userPath)) {
@@ -5467,6 +5524,42 @@ function resetConfig() {
5467
5524
  process.stdout.write("No user settings found.\n");
5468
5525
  }
5469
5526
  }
5527
+ function createDefaultCliCommandModules({
5528
+ cwd,
5529
+ providerDefinitions
5530
+ }) {
5531
+ return [
5532
+ (0, import_agent_command_skills.createSkillsCommandModule)({ cwd }),
5533
+ (0, import_agent_command_help.createHelpCommandModule)(),
5534
+ (0, import_agent_command_agent.createAgentCommandModule)(),
5535
+ (0, import_agent_command_model.createModelCommandModule)({
5536
+ providerDefinitions,
5537
+ settings: {
5538
+ readMergedSettings: () => readMergedProviderSettings(cwd)
5539
+ }
5540
+ }),
5541
+ (0, import_agent_command_permissions.createPermissionsCommandModule)(),
5542
+ (0, import_agent_command_language.createLanguageCommandModule)(),
5543
+ (0, import_agent_command_background.createBackgroundCommandModule)(),
5544
+ (0, import_agent_command_memory.createMemoryCommandModule)(),
5545
+ (0, import_agent_command_compact.createCompactCommandModule)(),
5546
+ (0, import_agent_command_context.createContextCommandModule)(),
5547
+ (0, import_agent_command_exit.createExitCommandModule)(),
5548
+ (0, import_agent_command_session.createSessionCommandModule)(),
5549
+ (0, import_agent_command_reset.createResetCommandModule)(),
5550
+ (0, import_agent_command_rewind.createRewindCommandModule)(),
5551
+ (0, import_agent_command_statusline.createStatusLineCommandModule)(),
5552
+ (0, import_agent_command_plugin.createPluginCommandModule)(),
5553
+ (0, import_agent_command_provider.createProviderCommandModule)({
5554
+ providerDefinitions,
5555
+ settings: {
5556
+ readMergedSettings: () => readMergedProviderSettings(cwd),
5557
+ readTargetSettings: () => readSettings(resolveProviderSettingsWriteTargetPath(cwd)),
5558
+ writeTargetSettings: (settings) => writeSettings(resolveProviderSettingsWriteTargetPath(cwd), settings)
5559
+ }
5560
+ })
5561
+ ];
5562
+ }
5470
5563
  async function startCli(options = {}) {
5471
5564
  const args = parseCliArgs();
5472
5565
  const version = readVersion();
@@ -5501,30 +5594,7 @@ async function startCli(options = {}) {
5501
5594
  };
5502
5595
  const providerDefinitions = options.providerDefinitions ?? DEFAULT_PROVIDER_DEFINITIONS;
5503
5596
  const commandModules = [
5504
- (0, import_agent_command_help.createHelpCommandModule)(),
5505
- (0, import_agent_command_agent.createAgentCommandModule)(),
5506
- (0, import_agent_command_model.createModelCommandModule)(),
5507
- (0, import_agent_command_mode.createModeCommandModule)(),
5508
- (0, import_agent_command_permissions.createPermissionsCommandModule)(),
5509
- (0, import_agent_command_language.createLanguageCommandModule)(),
5510
- (0, import_agent_command_background.createBackgroundCommandModule)(),
5511
- (0, import_agent_command_memory.createMemoryCommandModule)(),
5512
- (0, import_agent_command_compact.createCompactCommandModule)(),
5513
- (0, import_agent_command_context.createContextCommandModule)(),
5514
- (0, import_agent_command_exit.createExitCommandModule)(),
5515
- (0, import_agent_command_session.createSessionCommandModule)(),
5516
- (0, import_agent_command_reset.createResetCommandModule)(),
5517
- (0, import_agent_command_rewind.createRewindCommandModule)(),
5518
- (0, import_agent_command_statusline.createStatusLineCommandModule)(),
5519
- (0, import_agent_command_plugin.createPluginCommandModule)(),
5520
- (0, import_agent_command_provider.createProviderCommandModule)({
5521
- providerDefinitions,
5522
- settings: {
5523
- readMergedSettings: () => readMergedProviderSettings(cwd),
5524
- readTargetSettings: () => readSettings(getUserSettingsPath()),
5525
- writeTargetSettings: (settings) => writeSettings(getUserSettingsPath(), settings)
5526
- }
5527
- }),
5597
+ ...createDefaultCliCommandModules({ cwd, providerDefinitions }),
5528
5598
  ...options.commandModules ?? []
5529
5599
  ];
5530
5600
  const startupUpdateNoticePromise = shouldRunStartupCliUpdateCheck(args) ? getStartupCliUpdateNotice({ currentVersion: version }) : void 0;
@@ -5543,31 +5613,28 @@ async function startCli(options = {}) {
5543
5613
  process.exit(1);
5544
5614
  }
5545
5615
  const providerOptions = args.provider ? { providerOverride: args.provider, providerDefinitions } : { providerDefinitions };
5616
+ const activeProviderSettings = readMergedProviderSettings(cwd);
5617
+ const providerProfileName = args.provider ?? activeProviderSettings.currentProvider;
5546
5618
  const providerSettings = readProviderSettings(cwd, providerOptions);
5547
5619
  const modelId = args.model ?? providerSettings.model;
5548
5620
  const provider = createProviderFromSettings(cwd, args.model, providerOptions);
5549
5621
  const backgroundTaskRunners = [createManagedShellProcessRunner()];
5550
- const paths = (0, import_agent_sdk14.projectPaths)(cwd);
5622
+ const paths = (0, import_agent_sdk15.projectPaths)(cwd);
5551
5623
  const subagentRunnerFactory = createChildProcessSubagentRunnerFactory({
5552
5624
  providerConfig: { ...providerSettings, model: modelId },
5553
5625
  logsDir: paths.logs
5554
5626
  });
5555
- const sessionStore = new import_agent_sessions.SessionStore(paths.sessions);
5627
+ const sessionStore = (0, import_agent_sdk15.createProjectSessionStore)(cwd);
5556
5628
  let resumeSessionId;
5629
+ let showSessionPickerOnStart = false;
5557
5630
  if (args.continueMode) {
5558
- const sessions = sessionStore.list().filter((s) => s.cwd === cwd);
5559
- if (sessions.length > 0) {
5560
- resumeSessionId = sessions[0].id;
5561
- }
5631
+ resumeSessionId = (0, import_agent_sdk15.resolveLatestSessionId)(sessionStore, cwd);
5562
5632
  } else if (args.resumeId !== void 0) {
5563
5633
  if (args.resumeId === "") {
5564
- resumeSessionId = "__picker__";
5634
+ showSessionPickerOnStart = true;
5565
5635
  } else {
5566
- const sessions = sessionStore.list();
5567
- const match = sessions.find((s) => s.id === args.resumeId || s.name === args.resumeId);
5568
- if (match) {
5569
- resumeSessionId = match.id;
5570
- } else {
5636
+ resumeSessionId = (0, import_agent_sdk15.resolveSessionIdByIdOrName)(sessionStore, args.resumeId);
5637
+ if (resumeSessionId === void 0) {
5571
5638
  process.stderr.write(`Session not found: ${args.resumeId}
5572
5639
  `);
5573
5640
  process.exit(1);
@@ -5589,13 +5656,22 @@ async function startCli(options = {}) {
5589
5656
  }
5590
5657
  const appendParts = [];
5591
5658
  if (args.appendSystemPrompt) appendParts.push(args.appendSystemPrompt);
5659
+ if (args.taskFile) {
5660
+ try {
5661
+ appendParts.push(readTaskFilePrompt(cwd, args.taskFile));
5662
+ } catch (error) {
5663
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}
5664
+ `);
5665
+ process.exit(1);
5666
+ }
5667
+ }
5592
5668
  if (args.jsonSchema)
5593
5669
  appendParts.push(
5594
5670
  `Respond with valid JSON only, matching this JSON schema:
5595
5671
  ${args.jsonSchema}`
5596
5672
  );
5597
5673
  const appendSystemPrompt = appendParts.length > 0 ? appendParts.join("\n\n") : void 0;
5598
- const session = new import_agent_sdk14.InteractiveSession({
5674
+ const session = new import_agent_sdk15.InteractiveSession({
5599
5675
  cwd,
5600
5676
  provider,
5601
5677
  permissionMode: args.permissionMode ?? "bypassPermissions",
@@ -5623,6 +5699,8 @@ ${args.jsonSchema}`
5623
5699
  cwd,
5624
5700
  provider,
5625
5701
  providerOverride: args.provider,
5702
+ providerProfileName,
5703
+ providerType: providerSettings.name,
5626
5704
  modelId,
5627
5705
  language: args.language,
5628
5706
  permissionMode: args.permissionMode,
@@ -5630,6 +5708,7 @@ ${args.jsonSchema}`
5630
5708
  version,
5631
5709
  sessionStore,
5632
5710
  resumeSessionId,
5711
+ showSessionPickerOnStart,
5633
5712
  forkSession: args.forkSession,
5634
5713
  sessionName: args.sessionName,
5635
5714
  backgroundTaskRunners,