@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.
- package/README.md +59 -35
- package/dist/node/bin.js +2 -2
- package/dist/node/{chunk-6XQKLNRF.js → chunk-BENOH47A.js} +24 -4
- package/dist/node/{chunk-GHQHUBHC.js → chunk-J654S773.js} +350 -278
- package/dist/node/index.cjs +379 -300
- package/dist/node/index.js +2 -2
- package/dist/node/subagents/child-process-subagent-worker.js +1 -1
- package/package.json +28 -27
package/dist/node/index.cjs
CHANGED
|
@@ -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
|
|
64
|
-
var
|
|
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
|
-
|
|
339
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
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
|
-
|
|
999
|
+
commandEffectQueue.enqueueInteraction(result.interaction);
|
|
955
1000
|
}
|
|
956
1001
|
if (pendingEffects.length > 0) {
|
|
957
|
-
|
|
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
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
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
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
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
|
-
|
|
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((
|
|
1067
|
-
permissionQueueRef.current.push({ toolName, toolArgs, resolve:
|
|
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
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
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
|
-
|
|
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
|
|
1643
|
-
var
|
|
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
|
|
1713
|
+
function styleAddedOrRemovedDiffRow(line, rowWidth, color) {
|
|
1714
|
+
const row = `${CODE_BLOCK_INDENT}${line}`.padEnd(rowWidth);
|
|
1666
1715
|
if (!color) {
|
|
1667
|
-
return
|
|
1716
|
+
return row.trimEnd();
|
|
1668
1717
|
}
|
|
1669
1718
|
if (line.startsWith("+")) {
|
|
1670
|
-
return `${
|
|
1719
|
+
return `${ANSI_DARK_GREEN_BACKGROUND}${ANSI_LIGHT_GREEN}${row}${ANSI_RESET}`;
|
|
1671
1720
|
}
|
|
1672
1721
|
if (line.startsWith("-")) {
|
|
1673
|
-
return `${
|
|
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}${
|
|
1735
|
+
return `${ANSI_CYAN}${row}${ANSI_RESET}`;
|
|
1677
1736
|
}
|
|
1678
1737
|
if (line.startsWith("diff ") || line.startsWith("index ")) {
|
|
1679
|
-
return `${ANSI_DIM}${
|
|
1738
|
+
return `${ANSI_DIM}${row}${ANSI_RESET}`;
|
|
1680
1739
|
}
|
|
1681
|
-
return
|
|
1740
|
+
return row;
|
|
1682
1741
|
}
|
|
1683
|
-
function
|
|
1684
|
-
const
|
|
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.
|
|
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
|
|
2243
|
-
permissionMode
|
|
2309
|
+
function shouldShowPermissionMode(permissionMode) {
|
|
2310
|
+
return permissionMode !== "default";
|
|
2311
|
+
}
|
|
2312
|
+
function ProviderText({
|
|
2244
2313
|
modelName,
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
activeBackgroundTaskCount,
|
|
2248
|
-
hasPendingPrompt,
|
|
2249
|
-
contextPercentage,
|
|
2250
|
-
contextUsedTokens,
|
|
2251
|
-
contextMaxTokens,
|
|
2252
|
-
sessionName,
|
|
2253
|
-
gitBranch,
|
|
2254
|
-
showGitBranch
|
|
2314
|
+
providerProfileName,
|
|
2315
|
+
providerType
|
|
2255
2316
|
}) {
|
|
2256
|
-
|
|
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
|
-
|
|
2269
|
-
|
|
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)(
|
|
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.
|
|
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
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
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) =>
|
|
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
|
-
|
|
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
|
|
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((
|
|
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
|
-
|
|
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
|
|
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:
|
|
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((
|
|
4877
|
+
return new Promise((resolve3, reject) => {
|
|
4823
4878
|
const timeoutTimer = runtime.request.timeoutMs ? setTimeout(() => {
|
|
4824
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
4853
|
-
rejectOnceLocal(new
|
|
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
|
-
|
|
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
|
-
|
|
4947
|
+
(0, import_agent_sdk10.appendPrefixedLogLines)(runtime.logs, "stderr", text);
|
|
4889
4948
|
});
|
|
4890
4949
|
}
|
|
4891
4950
|
function cancelProcess(runtime, reason) {
|
|
4892
|
-
|
|
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
|
-
|
|
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
|
|
4969
|
+
var import_agent_sdk14 = require("@robota-sdk/agent-sdk");
|
|
4914
4970
|
|
|
4915
4971
|
// src/subagents/child-process-subagent-runner-result.ts
|
|
4916
|
-
var
|
|
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
|
|
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
|
|
5014
|
+
rejectOnce(new import_agent_sdk11.BackgroundTaskError("runner", message.message));
|
|
4959
5015
|
break;
|
|
4960
5016
|
case "cancelled":
|
|
4961
|
-
rejectOnce(new
|
|
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
|
|
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((
|
|
5047
|
+
return new Promise((resolve3, reject) => {
|
|
4992
5048
|
if (!child.connected) {
|
|
4993
|
-
reject(new
|
|
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
|
-
|
|
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((
|
|
5019
|
-
new ChildProcessSubagentResultController(options,
|
|
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,
|
|
5079
|
+
constructor(options, resolve3, reject) {
|
|
5024
5080
|
this.options = options;
|
|
5025
|
-
this.resolve =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
5390
|
+
const definition = customRegistry?.(agentType) ?? (0, import_agent_sdk14.getBuiltInAgent)(agentType);
|
|
5336
5391
|
if (!definition) {
|
|
5337
|
-
throw new
|
|
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
|
-
|
|
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((
|
|
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
|
-
|
|
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
|
-
(
|
|
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,
|
|
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 =
|
|
5627
|
+
const sessionStore = (0, import_agent_sdk15.createProjectSessionStore)(cwd);
|
|
5556
5628
|
let resumeSessionId;
|
|
5629
|
+
let showSessionPickerOnStart = false;
|
|
5557
5630
|
if (args.continueMode) {
|
|
5558
|
-
|
|
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
|
-
|
|
5634
|
+
showSessionPickerOnStart = true;
|
|
5565
5635
|
} else {
|
|
5566
|
-
|
|
5567
|
-
|
|
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
|
|
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,
|