@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
|
@@ -3,55 +3,30 @@ import {
|
|
|
3
3
|
createProviderFromSettings,
|
|
4
4
|
findProviderDefinition,
|
|
5
5
|
formatSupportedProviderTypes,
|
|
6
|
+
getProviderCredentialRequirement,
|
|
6
7
|
getProviderSettingsPaths,
|
|
7
8
|
hasUsableSecretReference,
|
|
8
9
|
isSubagentWorkerChildMessage,
|
|
9
10
|
readMergedProviderSettings,
|
|
10
11
|
readMergedProviderSettingsFromPaths,
|
|
11
12
|
readProviderSettings
|
|
12
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-BENOH47A.js";
|
|
13
14
|
|
|
14
15
|
// src/background/managed-shell-process-runner.ts
|
|
15
16
|
import { spawn } from "child_process";
|
|
16
17
|
import {
|
|
17
|
-
BackgroundTaskError
|
|
18
|
+
BackgroundTaskError,
|
|
19
|
+
appendPrefixedLogLines,
|
|
20
|
+
createBackgroundTaskLogPage,
|
|
21
|
+
createLimitedOutputCapture
|
|
18
22
|
} from "@robota-sdk/agent-sdk";
|
|
19
23
|
var DEFAULT_OUTPUT_LIMIT_BYTES = 3e4;
|
|
20
24
|
var DEFAULT_KILL_GRACE_MS = 2e3;
|
|
21
|
-
var LOG_PAGE_SIZE = 200;
|
|
22
|
-
function createCapture(limitBytes) {
|
|
23
|
-
const chunks = [];
|
|
24
|
-
let capturedBytes = 0;
|
|
25
|
-
let truncated = false;
|
|
26
|
-
return {
|
|
27
|
-
appendOutput(text) {
|
|
28
|
-
if (truncated) return;
|
|
29
|
-
const remaining = limitBytes - capturedBytes;
|
|
30
|
-
const buffer = Buffer.from(text, "utf8");
|
|
31
|
-
if (buffer.byteLength <= remaining) {
|
|
32
|
-
chunks.push(text);
|
|
33
|
-
capturedBytes += buffer.byteLength;
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
chunks.push(buffer.subarray(0, Math.max(remaining, 0)).toString("utf8"));
|
|
37
|
-
chunks.push("\n[output truncated]\n");
|
|
38
|
-
truncated = true;
|
|
39
|
-
},
|
|
40
|
-
getOutput() {
|
|
41
|
-
return chunks.join("");
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
function appendLog(lines, source, text) {
|
|
46
|
-
for (const line of text.split(/\r?\n/)) {
|
|
47
|
-
if (line.length > 0) lines.push(`[${source}] ${line}`);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
25
|
function resolveShell(request) {
|
|
51
26
|
return { command: request.shell ?? "sh", args: ["-c", request.command] };
|
|
52
27
|
}
|
|
53
28
|
function sendInput(child, input) {
|
|
54
|
-
return new Promise((
|
|
29
|
+
return new Promise((resolve3, reject) => {
|
|
55
30
|
const onError = (error) => {
|
|
56
31
|
child.stdin.off("error", onError);
|
|
57
32
|
reject(error);
|
|
@@ -59,7 +34,7 @@ function sendInput(child, input) {
|
|
|
59
34
|
child.stdin.once("error", onError);
|
|
60
35
|
child.stdin.end(input, () => {
|
|
61
36
|
child.stdin.off("error", onError);
|
|
62
|
-
|
|
37
|
+
resolve3();
|
|
63
38
|
});
|
|
64
39
|
});
|
|
65
40
|
}
|
|
@@ -86,7 +61,9 @@ function startProcessTask(taskId, request, killGraceMs) {
|
|
|
86
61
|
stdio: ["pipe", "pipe", "pipe"]
|
|
87
62
|
}),
|
|
88
63
|
logs: [],
|
|
89
|
-
capture:
|
|
64
|
+
capture: createLimitedOutputCapture({
|
|
65
|
+
limitBytes: request.outputLimitBytes ?? DEFAULT_OUTPUT_LIMIT_BYTES
|
|
66
|
+
}),
|
|
90
67
|
killGraceMs
|
|
91
68
|
};
|
|
92
69
|
const result = createProcessResult(runtime);
|
|
@@ -94,9 +71,13 @@ function startProcessTask(taskId, request, killGraceMs) {
|
|
|
94
71
|
}
|
|
95
72
|
function createProcessResult(runtime) {
|
|
96
73
|
let settled = false;
|
|
97
|
-
return new Promise((
|
|
74
|
+
return new Promise((resolve3, reject) => {
|
|
98
75
|
const timeoutTimer = runtime.request.timeoutMs ? setTimeout(() => {
|
|
99
|
-
|
|
76
|
+
appendPrefixedLogLines(
|
|
77
|
+
runtime.logs,
|
|
78
|
+
"system",
|
|
79
|
+
`timed out after ${runtime.request.timeoutMs}ms`
|
|
80
|
+
);
|
|
100
81
|
runtime.child.kill("SIGTERM");
|
|
101
82
|
rejectOnceLocal(new BackgroundTaskError("timeout", "Background process timed out"));
|
|
102
83
|
}, runtime.request.timeoutMs) : void 0;
|
|
@@ -108,7 +89,7 @@ function createProcessResult(runtime) {
|
|
|
108
89
|
if (settled) return;
|
|
109
90
|
settled = true;
|
|
110
91
|
clearTimers();
|
|
111
|
-
|
|
92
|
+
resolve3({
|
|
112
93
|
taskId: runtime.taskId,
|
|
113
94
|
kind: "process",
|
|
114
95
|
output: runtime.capture.getOutput(),
|
|
@@ -124,7 +105,7 @@ function createProcessResult(runtime) {
|
|
|
124
105
|
}
|
|
125
106
|
attachOutputListeners(runtime);
|
|
126
107
|
runtime.child.on("error", (error) => {
|
|
127
|
-
|
|
108
|
+
appendPrefixedLogLines(runtime.logs, "system", error.message);
|
|
128
109
|
rejectOnceLocal(new BackgroundTaskError("process", error.message));
|
|
129
110
|
});
|
|
130
111
|
runtime.child.on("close", (code, signal) => {
|
|
@@ -155,30 +136,27 @@ function attachOutputListeners(runtime) {
|
|
|
155
136
|
runtime.child.stdout.on("data", (chunk) => {
|
|
156
137
|
const text = chunk.toString("utf8");
|
|
157
138
|
runtime.capture.appendOutput(text);
|
|
158
|
-
|
|
139
|
+
appendPrefixedLogLines(runtime.logs, "stdout", text);
|
|
159
140
|
});
|
|
160
141
|
runtime.child.stderr.on("data", (chunk) => {
|
|
161
142
|
const text = chunk.toString("utf8");
|
|
162
143
|
runtime.capture.appendOutput(text);
|
|
163
|
-
|
|
144
|
+
appendPrefixedLogLines(runtime.logs, "stderr", text);
|
|
164
145
|
});
|
|
165
146
|
}
|
|
166
147
|
function cancelProcess(runtime, reason) {
|
|
167
|
-
|
|
148
|
+
appendPrefixedLogLines(
|
|
149
|
+
runtime.logs,
|
|
150
|
+
"system",
|
|
151
|
+
reason ? `cancel requested: ${reason}` : "cancel requested"
|
|
152
|
+
);
|
|
168
153
|
if (!runtime.child.killed) runtime.child.kill("SIGTERM");
|
|
169
154
|
runtime.killTimer = setTimeout(() => {
|
|
170
155
|
if (!runtime.child.killed) runtime.child.kill("SIGKILL");
|
|
171
156
|
}, runtime.killGraceMs);
|
|
172
157
|
}
|
|
173
158
|
function readProcessLog(runtime, cursor) {
|
|
174
|
-
|
|
175
|
-
const nextOffset = Math.min(offset + LOG_PAGE_SIZE, runtime.logs.length);
|
|
176
|
-
return {
|
|
177
|
-
taskId: runtime.taskId,
|
|
178
|
-
cursor,
|
|
179
|
-
nextCursor: nextOffset < runtime.logs.length ? { offset: nextOffset } : void 0,
|
|
180
|
-
lines: runtime.logs.slice(offset, nextOffset)
|
|
181
|
-
};
|
|
159
|
+
return createBackgroundTaskLogPage(runtime.taskId, runtime.logs, cursor);
|
|
182
160
|
}
|
|
183
161
|
|
|
184
162
|
// src/subagents/git-worktree-isolation-adapter.ts
|
|
@@ -305,6 +283,7 @@ import { existsSync, readFileSync } from "fs";
|
|
|
305
283
|
import { dirname, join as join2 } from "path";
|
|
306
284
|
import {
|
|
307
285
|
BackgroundTaskError as BackgroundTaskError5,
|
|
286
|
+
createBackgroundTaskLogPage as createBackgroundTaskLogPage2,
|
|
308
287
|
getBuiltInAgent,
|
|
309
288
|
createWorktreeSubagentRunner
|
|
310
289
|
} from "@robota-sdk/agent-sdk";
|
|
@@ -360,7 +339,7 @@ function extractFirstArg(toolArgs) {
|
|
|
360
339
|
return typeof firstValue === "object" ? JSON.stringify(firstValue) : String(firstValue);
|
|
361
340
|
}
|
|
362
341
|
function sendWorkerMessage(child, message) {
|
|
363
|
-
return new Promise((
|
|
342
|
+
return new Promise((resolve3, reject) => {
|
|
364
343
|
if (!child.connected) {
|
|
365
344
|
reject(new BackgroundTaskError3("crash", "Subagent worker IPC channel is closed"));
|
|
366
345
|
return;
|
|
@@ -370,7 +349,7 @@ function sendWorkerMessage(child, message) {
|
|
|
370
349
|
reject(error);
|
|
371
350
|
return;
|
|
372
351
|
}
|
|
373
|
-
|
|
352
|
+
resolve3();
|
|
374
353
|
});
|
|
375
354
|
});
|
|
376
355
|
}
|
|
@@ -387,14 +366,14 @@ async function cancelChildProcess(runtime, reason) {
|
|
|
387
366
|
|
|
388
367
|
// src/subagents/child-process-subagent-runner-result.ts
|
|
389
368
|
function createChildProcessSubagentResult(options) {
|
|
390
|
-
return new Promise((
|
|
391
|
-
new ChildProcessSubagentResultController(options,
|
|
369
|
+
return new Promise((resolve3, reject) => {
|
|
370
|
+
new ChildProcessSubagentResultController(options, resolve3, reject).start();
|
|
392
371
|
});
|
|
393
372
|
}
|
|
394
373
|
var ChildProcessSubagentResultController = class {
|
|
395
|
-
constructor(options,
|
|
374
|
+
constructor(options, resolve3, reject) {
|
|
396
375
|
this.options = options;
|
|
397
|
-
this.resolve =
|
|
376
|
+
this.resolve = resolve3;
|
|
398
377
|
this.reject = reject;
|
|
399
378
|
this.timeoutTimer = createTimeoutTimer(this.options.runtime, (error) => this.rejectOnce(error));
|
|
400
379
|
}
|
|
@@ -501,7 +480,6 @@ function formatEarlyExitMessage(code, signal) {
|
|
|
501
480
|
|
|
502
481
|
// src/subagents/child-process-subagent-runner.ts
|
|
503
482
|
var DEFAULT_KILL_GRACE_MS2 = 2e3;
|
|
504
|
-
var LOG_PAGE_SIZE2 = 200;
|
|
505
483
|
function createChildProcessSubagentRunnerFactory(options = {}) {
|
|
506
484
|
return (deps) => {
|
|
507
485
|
const runner = new ChildProcessSubagentRunner(deps, options);
|
|
@@ -639,7 +617,6 @@ function resolveDefaultExecArgv(workerPath) {
|
|
|
639
617
|
return [...process.execArgv, "--import", "tsx"];
|
|
640
618
|
}
|
|
641
619
|
function readTranscriptLog(jobId, transcriptPath, cursor) {
|
|
642
|
-
const offset = cursor?.offset ?? 0;
|
|
643
620
|
if (!existsSync(transcriptPath)) {
|
|
644
621
|
return {
|
|
645
622
|
taskId: jobId,
|
|
@@ -648,18 +625,12 @@ function readTranscriptLog(jobId, transcriptPath, cursor) {
|
|
|
648
625
|
};
|
|
649
626
|
}
|
|
650
627
|
const lines = readFileSync(transcriptPath, "utf8").split(/\r?\n/).filter(Boolean);
|
|
651
|
-
|
|
652
|
-
return {
|
|
653
|
-
taskId: jobId,
|
|
654
|
-
cursor,
|
|
655
|
-
nextCursor: nextOffset < lines.length ? { offset: nextOffset } : void 0,
|
|
656
|
-
lines: lines.slice(offset, nextOffset)
|
|
657
|
-
};
|
|
628
|
+
return createBackgroundTaskLogPage2(jobId, lines, cursor);
|
|
658
629
|
}
|
|
659
630
|
|
|
660
631
|
// src/cli.ts
|
|
661
632
|
import { readFileSync as readFileSync6 } from "fs";
|
|
662
|
-
import { join as join9, dirname as dirname5 } from "path";
|
|
633
|
+
import { join as join9, dirname as dirname5, resolve as resolve2 } from "path";
|
|
663
634
|
import { fileURLToPath } from "url";
|
|
664
635
|
import { createAgentCommandModule } from "@robota-sdk/agent-command-agent";
|
|
665
636
|
import { createBackgroundCommandModule } from "@robota-sdk/agent-command-background";
|
|
@@ -670,7 +641,6 @@ import { createExitCommandModule } from "@robota-sdk/agent-command-exit";
|
|
|
670
641
|
import { createHelpCommandModule } from "@robota-sdk/agent-command-help";
|
|
671
642
|
import { createLanguageCommandModule } from "@robota-sdk/agent-command-language";
|
|
672
643
|
import { createMemoryCommandModule } from "@robota-sdk/agent-command-memory";
|
|
673
|
-
import { createModeCommandModule } from "@robota-sdk/agent-command-mode";
|
|
674
644
|
import { createModelCommandModule } from "@robota-sdk/agent-command-model";
|
|
675
645
|
import { createPermissionsCommandModule } from "@robota-sdk/agent-command-permissions";
|
|
676
646
|
import { createPluginCommandModule } from "@robota-sdk/agent-command-plugin";
|
|
@@ -678,8 +648,14 @@ import { createResetCommandModule } from "@robota-sdk/agent-command-reset";
|
|
|
678
648
|
import { createRewindCommandModule } from "@robota-sdk/agent-command-rewind";
|
|
679
649
|
import { createStatusLineCommandModule } from "@robota-sdk/agent-command-statusline";
|
|
680
650
|
import { createSessionCommandModule } from "@robota-sdk/agent-command-session";
|
|
681
|
-
import {
|
|
682
|
-
import {
|
|
651
|
+
import { createSkillsCommandModule } from "@robota-sdk/agent-command-skills";
|
|
652
|
+
import {
|
|
653
|
+
InteractiveSession as InteractiveSession2,
|
|
654
|
+
createProjectSessionStore,
|
|
655
|
+
projectPaths,
|
|
656
|
+
resolveLatestSessionId,
|
|
657
|
+
resolveSessionIdByIdOrName
|
|
658
|
+
} from "@robota-sdk/agent-sdk";
|
|
683
659
|
|
|
684
660
|
// src/utils/cli-args.ts
|
|
685
661
|
import { parseArgs } from "util";
|
|
@@ -719,6 +695,7 @@ function parseCliArgs() {
|
|
|
719
695
|
"output-format": { type: "string" },
|
|
720
696
|
"system-prompt": { type: "string" },
|
|
721
697
|
"append-system-prompt": { type: "string" },
|
|
698
|
+
"task-file": { type: "string" },
|
|
722
699
|
version: { type: "boolean", default: false },
|
|
723
700
|
reset: { type: "boolean", default: false },
|
|
724
701
|
bare: { type: "boolean", default: false },
|
|
@@ -752,6 +729,7 @@ function parseCliArgs() {
|
|
|
752
729
|
outputFormat: values["output-format"],
|
|
753
730
|
systemPrompt: values["system-prompt"],
|
|
754
731
|
appendSystemPrompt: values["append-system-prompt"],
|
|
732
|
+
taskFile: values["task-file"],
|
|
755
733
|
version: values["version"] ?? false,
|
|
756
734
|
reset: values["reset"] ?? false,
|
|
757
735
|
bare: values["bare"] ?? false,
|
|
@@ -824,23 +802,33 @@ function isUsableProviderProfile(type, profile, providerDefinitions) {
|
|
|
824
802
|
if (!profile) {
|
|
825
803
|
return false;
|
|
826
804
|
}
|
|
827
|
-
if (hasUsableSecretReference(profile.apiKey)) {
|
|
828
|
-
return true;
|
|
829
|
-
}
|
|
830
805
|
if (!type) {
|
|
831
|
-
return
|
|
806
|
+
return hasUsableSecretReference(profile.apiKey);
|
|
832
807
|
}
|
|
833
808
|
const definition = findProviderDefinition(providerDefinitions, type);
|
|
834
809
|
if (definition === void 0) {
|
|
835
810
|
return false;
|
|
836
811
|
}
|
|
837
|
-
|
|
812
|
+
const credentialRequirement = getProviderCredentialRequirement(definition);
|
|
813
|
+
if (credentialRequirement === void 0) {
|
|
814
|
+
return true;
|
|
815
|
+
}
|
|
816
|
+
return hasUsableRequiredProviderCredential(profile, definition, credentialRequirement);
|
|
817
|
+
}
|
|
818
|
+
function hasUsableRequiredProviderCredential(profile, definition, requirement) {
|
|
819
|
+
return requirement.anyOf.some(
|
|
820
|
+
(field) => hasUsableSecretReference(resolveProviderCredentialValue(field, profile, definition))
|
|
821
|
+
);
|
|
822
|
+
}
|
|
823
|
+
function resolveProviderCredentialValue(field, profile, definition) {
|
|
824
|
+
return profile[field] ?? definition.defaults?.[field];
|
|
838
825
|
}
|
|
839
826
|
|
|
840
827
|
// src/utils/provider-settings.ts
|
|
841
828
|
import {
|
|
842
829
|
buildProviderProfile,
|
|
843
830
|
buildProviderSetupPatch,
|
|
831
|
+
deleteProviderProfile,
|
|
844
832
|
mergeProviderPatch,
|
|
845
833
|
setCurrentProvider,
|
|
846
834
|
upsertProviderProfile,
|
|
@@ -848,6 +836,14 @@ import {
|
|
|
848
836
|
} from "@robota-sdk/agent-sdk";
|
|
849
837
|
|
|
850
838
|
// src/utils/provider-configuration.ts
|
|
839
|
+
function resolveProviderSettingsWriteTargetPath(cwd, options = {}) {
|
|
840
|
+
const settingsPaths = options.settingsPaths ?? getProviderSettingsPaths(cwd);
|
|
841
|
+
const targetPath = findLastPathWithCurrentProvider(settingsPaths) ?? settingsPaths[0];
|
|
842
|
+
if (targetPath === void 0) {
|
|
843
|
+
throw new Error("No settings path available for provider update");
|
|
844
|
+
}
|
|
845
|
+
return targetPath;
|
|
846
|
+
}
|
|
851
847
|
function readProviderDocument(settingsPath) {
|
|
852
848
|
return readSettings(settingsPath);
|
|
853
849
|
}
|
|
@@ -930,11 +926,21 @@ function findLastPathWithLegacyProvider(settingsPaths) {
|
|
|
930
926
|
}
|
|
931
927
|
return void 0;
|
|
932
928
|
}
|
|
929
|
+
function findLastPathWithCurrentProvider(settingsPaths) {
|
|
930
|
+
for (let index = settingsPaths.length - 1; index >= 0; index -= 1) {
|
|
931
|
+
const settingsPath = settingsPaths[index];
|
|
932
|
+
if (settingsPath === void 0) continue;
|
|
933
|
+
const settings = readProviderDocument(settingsPath);
|
|
934
|
+
if (settings.currentProvider !== void 0) return settingsPath;
|
|
935
|
+
}
|
|
936
|
+
return void 0;
|
|
937
|
+
}
|
|
933
938
|
|
|
934
939
|
// src/utils/provider-setup-flow.ts
|
|
935
940
|
import {
|
|
936
941
|
createProviderSetupFlow,
|
|
937
942
|
formatProviderSetupChoiceLabel,
|
|
943
|
+
formatProviderSetupHelpLinks,
|
|
938
944
|
formatProviderSetupPromptLabel,
|
|
939
945
|
formatProviderSetupSelectionPrompt,
|
|
940
946
|
getProviderSetupStep,
|
|
@@ -965,7 +971,8 @@ function handleProviderConfigurationArgs(cwd, args, providerDefinitions = DEFAUL
|
|
|
965
971
|
return !args.printMode && args.positional.length === 0;
|
|
966
972
|
}
|
|
967
973
|
if (args.provider && args.setCurrent) {
|
|
968
|
-
|
|
974
|
+
const switchSettingsPath = args.settingsScope === void 0 ? resolveProviderSettingsWriteTargetPath(cwd) : settingsPath;
|
|
975
|
+
applyProviderSwitch(switchSettingsPath, args.provider, {
|
|
969
976
|
knownProviders: readMergedProviderSettings(cwd).providers
|
|
970
977
|
});
|
|
971
978
|
process.stdout.write(`Current provider set to ${args.provider}
|
|
@@ -999,7 +1006,9 @@ async function runInteractiveProviderSetup(cwd, args, promptInput2, providerDefi
|
|
|
999
1006
|
const providerChoice = await promptInput2(formatProviderSetupSelectionPrompt(providerDefinitions));
|
|
1000
1007
|
const type = resolveProviderSetupSelection(providerChoice, providerDefinitions);
|
|
1001
1008
|
const settingsPath = getSettingsPathForScope(cwd, args.settingsScope);
|
|
1002
|
-
const input = await runProviderSetupPromptFlow(type, promptInput2, providerDefinitions
|
|
1009
|
+
const input = await runProviderSetupPromptFlow(type, promptInput2, providerDefinitions, {
|
|
1010
|
+
existingProfileNames: Object.keys(readMergedProviderSettings(cwd).providers ?? {})
|
|
1011
|
+
});
|
|
1003
1012
|
applyProviderConfiguration(settingsPath, input, {
|
|
1004
1013
|
providerDefinitions
|
|
1005
1014
|
});
|
|
@@ -1087,16 +1096,12 @@ import { render } from "ink";
|
|
|
1087
1096
|
// src/ui/App.tsx
|
|
1088
1097
|
import { useState as useState14, useEffect as useEffect4 } from "react";
|
|
1089
1098
|
import { Box as Box18, Text as Text20, useApp as useApp2, useInput as useInput8 } from "ink";
|
|
1099
|
+
import { listResumableSessionSummaries } from "@robota-sdk/agent-sdk";
|
|
1090
1100
|
import { createSystemMessage as createSystemMessage6, messageToHistoryEntry as messageToHistoryEntry6 } from "@robota-sdk/agent-core";
|
|
1091
1101
|
|
|
1092
1102
|
// src/ui/hooks/useInteractiveSession.ts
|
|
1093
1103
|
import { useState, useRef, useCallback as useCallback2, useEffect } from "react";
|
|
1094
|
-
import {
|
|
1095
|
-
InteractiveSession,
|
|
1096
|
-
CommandRegistry as CommandRegistry2,
|
|
1097
|
-
createBuiltinCommandModule,
|
|
1098
|
-
SkillCommandSource
|
|
1099
|
-
} from "@robota-sdk/agent-sdk";
|
|
1104
|
+
import { InteractiveSession, CommandRegistry as CommandRegistry2 } from "@robota-sdk/agent-sdk";
|
|
1100
1105
|
import { createSystemMessage as createSystemMessage2, messageToHistoryEntry as messageToHistoryEntry2 } from "@robota-sdk/agent-core";
|
|
1101
1106
|
|
|
1102
1107
|
// src/ui/background-task-view-model.ts
|
|
@@ -1362,7 +1367,6 @@ var TuiStateManager = class {
|
|
|
1362
1367
|
|
|
1363
1368
|
// src/ui/hooks/useSlashRouting.ts
|
|
1364
1369
|
import { useCallback } from "react";
|
|
1365
|
-
import { randomUUID as randomUUID2 } from "crypto";
|
|
1366
1370
|
import { createSystemMessage, messageToHistoryEntry } from "@robota-sdk/agent-core";
|
|
1367
1371
|
|
|
1368
1372
|
// src/plugins/plugin-command-source-loader.ts
|
|
@@ -1391,7 +1395,7 @@ function reloadPluginCommandSource(registry) {
|
|
|
1391
1395
|
}
|
|
1392
1396
|
|
|
1393
1397
|
// src/ui/hooks/useSlashRouting.ts
|
|
1394
|
-
function useSlashRouting(interactiveSession, registry, manager) {
|
|
1398
|
+
function useSlashRouting(interactiveSession, registry, manager, commandEffectQueue) {
|
|
1395
1399
|
return useCallback(
|
|
1396
1400
|
async (input) => {
|
|
1397
1401
|
manager.onUserTurnAccepted();
|
|
@@ -1405,10 +1409,11 @@ function useSlashRouting(interactiveSession, registry, manager) {
|
|
|
1405
1409
|
const args = parts.slice(1).join(" ");
|
|
1406
1410
|
const result = await interactiveSession.executeCommand(cmd, args);
|
|
1407
1411
|
if (result) {
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
+
if (result.effects?.some((effect) => effect.type === "session-execution-started")) {
|
|
1413
|
+
manager.setPendingPrompt(interactiveSession.getPendingPrompt());
|
|
1414
|
+
return;
|
|
1415
|
+
}
|
|
1416
|
+
applySystemCommandResult(result, interactiveSession, registry, manager, commandEffectQueue);
|
|
1412
1417
|
return;
|
|
1413
1418
|
}
|
|
1414
1419
|
manager.addEntry(
|
|
@@ -1417,18 +1422,17 @@ function useSlashRouting(interactiveSession, registry, manager) {
|
|
|
1417
1422
|
)
|
|
1418
1423
|
);
|
|
1419
1424
|
},
|
|
1420
|
-
[interactiveSession, registry, manager]
|
|
1425
|
+
[interactiveSession, registry, manager, commandEffectQueue]
|
|
1421
1426
|
);
|
|
1422
1427
|
}
|
|
1423
|
-
function applySystemCommandResult(result, interactiveSession, registry, manager) {
|
|
1428
|
+
function applySystemCommandResult(result, interactiveSession, registry, manager, commandEffectQueue) {
|
|
1424
1429
|
const pendingEffects = applyImmediateCommandEffects(result.effects, registry, manager);
|
|
1425
1430
|
manager.addEntry(messageToHistoryEntry(createSystemMessage(result.message)));
|
|
1426
|
-
const effects = getEffects(interactiveSession);
|
|
1427
1431
|
if (result.interaction !== void 0) {
|
|
1428
|
-
|
|
1432
|
+
commandEffectQueue.enqueueInteraction(result.interaction);
|
|
1429
1433
|
}
|
|
1430
1434
|
if (pendingEffects.length > 0) {
|
|
1431
|
-
|
|
1435
|
+
commandEffectQueue.enqueueEffects(pendingEffects);
|
|
1432
1436
|
}
|
|
1433
1437
|
const ctx = interactiveSession.getContextState();
|
|
1434
1438
|
manager.setContextState({
|
|
@@ -1453,37 +1457,32 @@ function applyImmediateCommandEffects(effects, registry, manager) {
|
|
|
1453
1457
|
}
|
|
1454
1458
|
return pendingEffects;
|
|
1455
1459
|
}
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
+
|
|
1461
|
+
// src/ui/hooks/command-effect-queue.ts
|
|
1462
|
+
var CommandEffectQueue = class {
|
|
1463
|
+
queue = [];
|
|
1464
|
+
enqueueInteraction(interaction) {
|
|
1465
|
+
this.queue.push({ type: "interaction", interaction });
|
|
1460
1466
|
}
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
const args = input.slice(1 + cmd.length).trimStart();
|
|
1473
|
-
const qualifiedName = registry.resolveQualifiedName(cmd);
|
|
1474
|
-
const hookInput = qualifiedName ? `/${qualifiedName}${input.slice(1 + cmd.length)}` : input;
|
|
1475
|
-
await interactiveSession.executeSkillCommand(skillCmd, args, input, hookInput);
|
|
1476
|
-
manager.setPendingPrompt(interactiveSession.getPendingPrompt());
|
|
1477
|
-
return true;
|
|
1478
|
-
}
|
|
1479
|
-
function getEffects(interactiveSession) {
|
|
1480
|
-
return interactiveSession;
|
|
1481
|
-
}
|
|
1467
|
+
enqueueEffects(effects) {
|
|
1468
|
+
if (effects.length === 0) return;
|
|
1469
|
+
this.queue.push({ type: "effects", effects: [...effects] });
|
|
1470
|
+
}
|
|
1471
|
+
drain() {
|
|
1472
|
+
return this.queue.shift();
|
|
1473
|
+
}
|
|
1474
|
+
clear() {
|
|
1475
|
+
this.queue.length = 0;
|
|
1476
|
+
}
|
|
1477
|
+
};
|
|
1482
1478
|
|
|
1483
1479
|
// src/ui/hooks/useInteractiveSession.ts
|
|
1484
1480
|
function applyCompactEventToManager(interactiveSession, manager) {
|
|
1485
1481
|
manager.syncHistory(interactiveSession.getFullHistory());
|
|
1486
1482
|
}
|
|
1483
|
+
function applySkillActivationEventToManager(interactiveSession, manager) {
|
|
1484
|
+
manager.syncHistory(interactiveSession.getFullHistory());
|
|
1485
|
+
}
|
|
1487
1486
|
function initializeSession(props, permissionHandler) {
|
|
1488
1487
|
const interactiveSession = new InteractiveSession({
|
|
1489
1488
|
cwd: props.cwd,
|
|
@@ -1501,14 +1500,13 @@ function initializeSession(props, permissionHandler) {
|
|
|
1501
1500
|
commandHostAdapters: props.commandHostAdapters
|
|
1502
1501
|
});
|
|
1503
1502
|
const registry = new CommandRegistry2();
|
|
1504
|
-
registry.addModule(createBuiltinCommandModule());
|
|
1505
1503
|
for (const module of props.commandModules ?? []) {
|
|
1506
1504
|
registry.addModule(module);
|
|
1507
1505
|
}
|
|
1508
|
-
registry.addSource(new SkillCommandSource(props.cwd));
|
|
1509
1506
|
reloadPluginCommandSource(registry);
|
|
1510
1507
|
const manager = new TuiStateManager();
|
|
1511
|
-
|
|
1508
|
+
const commandEffectQueue = new CommandEffectQueue();
|
|
1509
|
+
return { interactiveSession, registry, manager, commandEffectQueue };
|
|
1512
1510
|
}
|
|
1513
1511
|
function useInteractiveSession(props) {
|
|
1514
1512
|
const [, forceRender] = useState(0);
|
|
@@ -1537,8 +1535,8 @@ function useInteractiveSession(props) {
|
|
|
1537
1535
|
});
|
|
1538
1536
|
}, []);
|
|
1539
1537
|
const permissionHandler = useCallback2(
|
|
1540
|
-
(toolName, toolArgs) => new Promise((
|
|
1541
|
-
permissionQueueRef.current.push({ toolName, toolArgs, resolve:
|
|
1538
|
+
(toolName, toolArgs) => new Promise((resolve3) => {
|
|
1539
|
+
permissionQueueRef.current.push({ toolName, toolArgs, resolve: resolve3 });
|
|
1542
1540
|
processNextPermission();
|
|
1543
1541
|
}),
|
|
1544
1542
|
[processNextPermission]
|
|
@@ -1547,7 +1545,7 @@ function useInteractiveSession(props) {
|
|
|
1547
1545
|
if (stateRef.current === null) {
|
|
1548
1546
|
stateRef.current = initializeSession(props, permissionHandler);
|
|
1549
1547
|
}
|
|
1550
|
-
const { interactiveSession, registry, manager } = stateRef.current;
|
|
1548
|
+
const { interactiveSession, registry, manager, commandEffectQueue } = stateRef.current;
|
|
1551
1549
|
manager.onChange = () => forceRender((n) => n + 1);
|
|
1552
1550
|
if (manager.history.length === 0) {
|
|
1553
1551
|
const restored = interactiveSession.getFullHistory();
|
|
@@ -1557,6 +1555,7 @@ function useInteractiveSession(props) {
|
|
|
1557
1555
|
}
|
|
1558
1556
|
useEffect(() => {
|
|
1559
1557
|
const onCompact = () => applyCompactEventToManager(interactiveSession, manager);
|
|
1558
|
+
const onSkillActivation = () => applySkillActivationEventToManager(interactiveSession, manager);
|
|
1560
1559
|
interactiveSession.on("text_delta", manager.onTextDelta);
|
|
1561
1560
|
interactiveSession.on("tool_start", manager.onToolStart);
|
|
1562
1561
|
interactiveSession.on("tool_end", manager.onToolEnd);
|
|
@@ -1566,6 +1565,7 @@ function useInteractiveSession(props) {
|
|
|
1566
1565
|
interactiveSession.on("error", manager.onError);
|
|
1567
1566
|
interactiveSession.on("context_update", manager.onContextUpdate);
|
|
1568
1567
|
interactiveSession.on("compact", onCompact);
|
|
1568
|
+
interactiveSession.on("skill_activation", onSkillActivation);
|
|
1569
1569
|
interactiveSession.on("background_task_event", manager.onBackgroundTaskEvent);
|
|
1570
1570
|
const initCheck = setInterval(() => {
|
|
1571
1571
|
try {
|
|
@@ -1594,6 +1594,7 @@ function useInteractiveSession(props) {
|
|
|
1594
1594
|
interactiveSession.off("error", manager.onError);
|
|
1595
1595
|
interactiveSession.off("context_update", manager.onContextUpdate);
|
|
1596
1596
|
interactiveSession.off("compact", onCompact);
|
|
1597
|
+
interactiveSession.off("skill_activation", onSkillActivation);
|
|
1597
1598
|
interactiveSession.off("background_task_event", manager.onBackgroundTaskEvent);
|
|
1598
1599
|
};
|
|
1599
1600
|
}, [interactiveSession, manager]);
|
|
@@ -1603,7 +1604,7 @@ function useInteractiveSession(props) {
|
|
|
1603
1604
|
manager.setPendingPrompt(interactiveSession.getPendingPrompt());
|
|
1604
1605
|
}
|
|
1605
1606
|
}, [manager.isThinking, interactiveSession, manager]);
|
|
1606
|
-
const handleSubmit = useSlashRouting(interactiveSession, registry, manager);
|
|
1607
|
+
const handleSubmit = useSlashRouting(interactiveSession, registry, manager, commandEffectQueue);
|
|
1607
1608
|
const handleAbort = useCallback2(() => {
|
|
1608
1609
|
manager.setAborting(true);
|
|
1609
1610
|
interactiveSession.abort();
|
|
@@ -1624,6 +1625,7 @@ function useInteractiveSession(props) {
|
|
|
1624
1625
|
return {
|
|
1625
1626
|
interactiveSession,
|
|
1626
1627
|
registry,
|
|
1628
|
+
commandEffectQueue,
|
|
1627
1629
|
history: manager.history,
|
|
1628
1630
|
addEntry: (entry) => manager.addEntry(entry),
|
|
1629
1631
|
streamingText: manager.streamingText,
|
|
@@ -1916,10 +1918,12 @@ function useSideEffects({
|
|
|
1916
1918
|
cwd,
|
|
1917
1919
|
providerOverride,
|
|
1918
1920
|
interactiveSession,
|
|
1921
|
+
commandEffectQueue,
|
|
1919
1922
|
addEntry,
|
|
1920
1923
|
baseHandleSubmit,
|
|
1921
1924
|
setSessionName,
|
|
1922
|
-
setStatusLineSettings
|
|
1925
|
+
setStatusLineSettings,
|
|
1926
|
+
showSessionPickerOnStart
|
|
1923
1927
|
}) {
|
|
1924
1928
|
const { exit } = useApp();
|
|
1925
1929
|
const [pendingModelId, setPendingModelId] = useState2(null);
|
|
@@ -1927,7 +1931,7 @@ function useSideEffects({
|
|
|
1927
1931
|
const [pendingInteractionPrompt, setPendingInteractionPrompt] = useState2(null);
|
|
1928
1932
|
const commandInteractionRef = useRef2(null);
|
|
1929
1933
|
const [showPluginTUI, setShowPluginTUI] = useState2(false);
|
|
1930
|
-
const [showSessionPicker, setShowSessionPicker] = useState2(false);
|
|
1934
|
+
const [showSessionPicker, setShowSessionPicker] = useState2(showSessionPickerOnStart ?? false);
|
|
1931
1935
|
const requestShutdown = useCallback3(
|
|
1932
1936
|
(reason, message) => {
|
|
1933
1937
|
addEntry(messageToHistoryEntry5(createSystemMessage5("Shutting down...")));
|
|
@@ -1968,33 +1972,31 @@ function useSideEffects({
|
|
|
1968
1972
|
commandInteractionRef.current = null;
|
|
1969
1973
|
setPendingInteractionPrompt(null);
|
|
1970
1974
|
if (result.effects !== void 0 && result.effects.length > 0) {
|
|
1971
|
-
applyEffects(result.effects, interactiveSession);
|
|
1975
|
+
applyEffects(result.effects, getHostSideEffects(interactiveSession));
|
|
1972
1976
|
}
|
|
1973
1977
|
},
|
|
1974
1978
|
[addEntry, applyEffects, interactiveSession]
|
|
1975
1979
|
);
|
|
1976
1980
|
const applyQueuedCommandState = useCallback3(
|
|
1977
1981
|
(sideEffects) => {
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1982
|
+
const queued = commandEffectQueue.drain();
|
|
1983
|
+
if (queued === void 0) {
|
|
1984
|
+
return false;
|
|
1985
|
+
}
|
|
1986
|
+
if (queued.type === "interaction") {
|
|
1987
|
+
const { interaction } = queued;
|
|
1981
1988
|
commandInteractionRef.current = interaction;
|
|
1982
1989
|
setPendingInteractionPrompt(interaction.prompt);
|
|
1983
1990
|
return true;
|
|
1984
1991
|
}
|
|
1985
|
-
|
|
1986
|
-
const effects = sideEffects._pendingCommandEffects;
|
|
1987
|
-
delete sideEffects._pendingCommandEffects;
|
|
1988
|
-
return applyEffects(effects, sideEffects);
|
|
1989
|
-
}
|
|
1990
|
-
return false;
|
|
1992
|
+
return applyEffects(queued.effects, sideEffects);
|
|
1991
1993
|
},
|
|
1992
|
-
[applyEffects]
|
|
1994
|
+
[applyEffects, commandEffectQueue]
|
|
1993
1995
|
);
|
|
1994
1996
|
const handleSubmit = useCallback3(
|
|
1995
1997
|
async (input) => {
|
|
1996
1998
|
await baseHandleSubmit(input);
|
|
1997
|
-
const sideEffects = interactiveSession;
|
|
1999
|
+
const sideEffects = getHostSideEffects(interactiveSession);
|
|
1998
2000
|
if (applyQueuedCommandState(sideEffects)) return;
|
|
1999
2001
|
if (sideEffects._pendingModelId) {
|
|
2000
2002
|
const modelId = sideEffects._pendingModelId;
|
|
@@ -2105,6 +2107,9 @@ function useSideEffects({
|
|
|
2105
2107
|
handleInteractionCancel
|
|
2106
2108
|
};
|
|
2107
2109
|
}
|
|
2110
|
+
function getHostSideEffects(interactiveSession) {
|
|
2111
|
+
return interactiveSession;
|
|
2112
|
+
}
|
|
2108
2113
|
|
|
2109
2114
|
// src/ui/hooks/useStatusLineSettings.ts
|
|
2110
2115
|
import { useState as useState3 } from "react";
|
|
@@ -2122,10 +2127,12 @@ import { isToolMessage, isAssistantMessage } from "@robota-sdk/agent-core";
|
|
|
2122
2127
|
// src/ui/render-markdown.ts
|
|
2123
2128
|
import { marked } from "marked";
|
|
2124
2129
|
import TerminalRenderer from "marked-terminal";
|
|
2125
|
-
var
|
|
2126
|
-
var
|
|
2130
|
+
var ANSI_LIGHT_RED = "\x1B[38;5;210m";
|
|
2131
|
+
var ANSI_LIGHT_GREEN = "\x1B[38;5;120m";
|
|
2127
2132
|
var ANSI_CYAN = "\x1B[36m";
|
|
2128
2133
|
var ANSI_DIM = "\x1B[2m";
|
|
2134
|
+
var ANSI_DARK_RED_BACKGROUND = "\x1B[48;5;52m";
|
|
2135
|
+
var ANSI_DARK_GREEN_BACKGROUND = "\x1B[48;5;22m";
|
|
2129
2136
|
var ANSI_RESET = "\x1B[0m";
|
|
2130
2137
|
var CODE_BLOCK_INDENT = " ";
|
|
2131
2138
|
var ZERO_COLOR = "0";
|
|
@@ -2145,36 +2152,59 @@ function shouldUseColor(option) {
|
|
|
2145
2152
|
function isDiffLanguage(language) {
|
|
2146
2153
|
return language?.trim().toLowerCase() === "diff";
|
|
2147
2154
|
}
|
|
2148
|
-
function
|
|
2155
|
+
function styleAddedOrRemovedDiffRow(line, rowWidth, color) {
|
|
2156
|
+
const row = `${CODE_BLOCK_INDENT}${line}`.padEnd(rowWidth);
|
|
2149
2157
|
if (!color) {
|
|
2150
|
-
return
|
|
2158
|
+
return row.trimEnd();
|
|
2151
2159
|
}
|
|
2152
2160
|
if (line.startsWith("+")) {
|
|
2153
|
-
return `${
|
|
2161
|
+
return `${ANSI_DARK_GREEN_BACKGROUND}${ANSI_LIGHT_GREEN}${row}${ANSI_RESET}`;
|
|
2154
2162
|
}
|
|
2155
2163
|
if (line.startsWith("-")) {
|
|
2156
|
-
return `${
|
|
2164
|
+
return `${ANSI_DARK_RED_BACKGROUND}${ANSI_LIGHT_RED}${row}${ANSI_RESET}`;
|
|
2165
|
+
}
|
|
2166
|
+
return row.trimEnd();
|
|
2167
|
+
}
|
|
2168
|
+
function colorizeDiffLine(line, color, rowWidth) {
|
|
2169
|
+
if (line.startsWith("+") || line.startsWith("-")) {
|
|
2170
|
+
return styleAddedOrRemovedDiffRow(line, rowWidth, color);
|
|
2171
|
+
}
|
|
2172
|
+
const row = `${CODE_BLOCK_INDENT}${line}`;
|
|
2173
|
+
if (!color) {
|
|
2174
|
+
return row;
|
|
2157
2175
|
}
|
|
2158
2176
|
if (line.startsWith("@@")) {
|
|
2159
|
-
return `${ANSI_CYAN}${
|
|
2177
|
+
return `${ANSI_CYAN}${row}${ANSI_RESET}`;
|
|
2160
2178
|
}
|
|
2161
2179
|
if (line.startsWith("diff ") || line.startsWith("index ")) {
|
|
2162
|
-
return `${ANSI_DIM}${
|
|
2180
|
+
return `${ANSI_DIM}${row}${ANSI_RESET}`;
|
|
2163
2181
|
}
|
|
2164
|
-
return
|
|
2182
|
+
return row;
|
|
2165
2183
|
}
|
|
2166
|
-
function
|
|
2167
|
-
const
|
|
2184
|
+
function resolveDiffRowWidth(lines, requestedWidth) {
|
|
2185
|
+
const minimumWidth = lines.reduce(
|
|
2186
|
+
(maxWidth, line) => Math.max(maxWidth, CODE_BLOCK_INDENT.length + line.length),
|
|
2187
|
+
0
|
|
2188
|
+
);
|
|
2189
|
+
if (requestedWidth === void 0) {
|
|
2190
|
+
return minimumWidth;
|
|
2191
|
+
}
|
|
2192
|
+
return Math.max(minimumWidth, requestedWidth);
|
|
2193
|
+
}
|
|
2194
|
+
function renderDiffCodeBlock(code, color, codeBlockWidth) {
|
|
2195
|
+
const lines = code.split("\n");
|
|
2196
|
+
const rowWidth = resolveDiffRowWidth(lines, codeBlockWidth);
|
|
2197
|
+
const body = lines.map((line) => colorizeDiffLine(line, color, rowWidth)).join("\n");
|
|
2168
2198
|
return `${body}
|
|
2169
2199
|
|
|
2170
2200
|
`;
|
|
2171
2201
|
}
|
|
2172
|
-
function createTerminalRenderer(color) {
|
|
2202
|
+
function createTerminalRenderer(color, codeBlockWidth) {
|
|
2173
2203
|
const renderer = new TerminalRendererConstructor(void 0, { ignoreIllegals: true });
|
|
2174
2204
|
const renderCode = renderer.code.bind(renderer);
|
|
2175
2205
|
renderer.code = (code, language, escaped) => {
|
|
2176
2206
|
if (isDiffLanguage(language)) {
|
|
2177
|
-
return renderDiffCodeBlock(code, color);
|
|
2207
|
+
return renderDiffCodeBlock(code, color, codeBlockWidth);
|
|
2178
2208
|
}
|
|
2179
2209
|
return renderCode(code, language, escaped);
|
|
2180
2210
|
};
|
|
@@ -2182,7 +2212,7 @@ function createTerminalRenderer(color) {
|
|
|
2182
2212
|
}
|
|
2183
2213
|
function renderMarkdown(md, options = {}) {
|
|
2184
2214
|
const result = marked.parse(md, {
|
|
2185
|
-
renderer: createTerminalRenderer(shouldUseColor(options.color))
|
|
2215
|
+
renderer: createTerminalRenderer(shouldUseColor(options.color), options.codeBlockWidth)
|
|
2186
2216
|
});
|
|
2187
2217
|
return typeof result === "string" ? result.trimEnd() : md;
|
|
2188
2218
|
}
|
|
@@ -2694,11 +2724,7 @@ function StatusActivityText({
|
|
|
2694
2724
|
activeBackgroundTaskCount,
|
|
2695
2725
|
hasPendingPrompt
|
|
2696
2726
|
});
|
|
2697
|
-
return /* @__PURE__ */
|
|
2698
|
-
/* @__PURE__ */ jsx5(Text5, { color: "cyan", bold: true, children: "Activity:" }),
|
|
2699
|
-
" ",
|
|
2700
|
-
/* @__PURE__ */ jsx5(Text5, { color: activity.color, bold: activity.kind !== "idle", children: activity.text })
|
|
2701
|
-
] });
|
|
2727
|
+
return /* @__PURE__ */ jsx5(Text5, { color: activity.color, bold: activity.kind !== "idle", children: activity.text });
|
|
2702
2728
|
}
|
|
2703
2729
|
function ContextText({
|
|
2704
2730
|
percentage,
|
|
@@ -2722,77 +2748,79 @@ function ModeText({ permissionMode }) {
|
|
|
2722
2748
|
/* @__PURE__ */ jsx5(Text5, { children: permissionMode })
|
|
2723
2749
|
] });
|
|
2724
2750
|
}
|
|
2725
|
-
function
|
|
2726
|
-
permissionMode
|
|
2751
|
+
function shouldShowPermissionMode(permissionMode) {
|
|
2752
|
+
return permissionMode !== "default";
|
|
2753
|
+
}
|
|
2754
|
+
function ProviderText({
|
|
2727
2755
|
modelName,
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
activeBackgroundTaskCount,
|
|
2731
|
-
hasPendingPrompt,
|
|
2732
|
-
contextPercentage,
|
|
2733
|
-
contextUsedTokens,
|
|
2734
|
-
contextMaxTokens,
|
|
2735
|
-
sessionName,
|
|
2736
|
-
gitBranch,
|
|
2737
|
-
showGitBranch
|
|
2756
|
+
providerProfileName,
|
|
2757
|
+
providerType
|
|
2738
2758
|
}) {
|
|
2739
|
-
|
|
2759
|
+
if (providerProfileName !== void 0 && providerType !== void 0) {
|
|
2760
|
+
return /* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
2761
|
+
providerProfileName,
|
|
2762
|
+
" (",
|
|
2763
|
+
providerType,
|
|
2764
|
+
") ",
|
|
2765
|
+
modelName
|
|
2766
|
+
] });
|
|
2767
|
+
}
|
|
2768
|
+
return /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: modelName });
|
|
2769
|
+
}
|
|
2770
|
+
function StatusLeft(props) {
|
|
2771
|
+
const shouldShowGitBranch = props.showGitBranch && props.gitBranch !== void 0 && props.gitBranch.length > 0;
|
|
2772
|
+
const showPermissionMode = shouldShowPermissionMode(props.permissionMode);
|
|
2740
2773
|
return /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
2741
2774
|
/* @__PURE__ */ jsx5(
|
|
2742
2775
|
StatusActivityText,
|
|
2743
2776
|
{
|
|
2744
|
-
isThinking,
|
|
2745
|
-
activeToolCount,
|
|
2746
|
-
activeBackgroundTaskCount,
|
|
2747
|
-
hasPendingPrompt
|
|
2777
|
+
isThinking: props.isThinking,
|
|
2778
|
+
activeToolCount: props.activeToolCount,
|
|
2779
|
+
activeBackgroundTaskCount: props.activeBackgroundTaskCount,
|
|
2780
|
+
hasPendingPrompt: props.hasPendingPrompt
|
|
2748
2781
|
}
|
|
2749
2782
|
),
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2783
|
+
showPermissionMode && /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
2784
|
+
" | ",
|
|
2785
|
+
/* @__PURE__ */ jsx5(ModeText, { permissionMode: props.permissionMode })
|
|
2786
|
+
] }),
|
|
2787
|
+
props.sessionName && /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
2753
2788
|
" | ",
|
|
2754
|
-
/* @__PURE__ */ jsx5(Text5, { color: "magenta", children: sessionName })
|
|
2789
|
+
/* @__PURE__ */ jsx5(Text5, { color: "magenta", children: props.sessionName })
|
|
2755
2790
|
] }),
|
|
2756
2791
|
shouldShowGitBranch && /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
2757
2792
|
" | ",
|
|
2758
2793
|
/* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
2759
2794
|
"git: ",
|
|
2760
|
-
gitBranch
|
|
2795
|
+
props.gitBranch
|
|
2761
2796
|
] })
|
|
2762
2797
|
] }),
|
|
2763
2798
|
" | ",
|
|
2764
|
-
/* @__PURE__ */ jsx5(
|
|
2799
|
+
/* @__PURE__ */ jsx5(
|
|
2800
|
+
ProviderText,
|
|
2801
|
+
{
|
|
2802
|
+
modelName: props.modelName,
|
|
2803
|
+
providerProfileName: props.providerProfileName,
|
|
2804
|
+
providerType: props.providerType
|
|
2805
|
+
}
|
|
2806
|
+
),
|
|
2765
2807
|
" | ",
|
|
2766
2808
|
/* @__PURE__ */ jsx5(
|
|
2767
2809
|
ContextText,
|
|
2768
2810
|
{
|
|
2769
|
-
percentage: contextPercentage,
|
|
2770
|
-
usedTokens: contextUsedTokens,
|
|
2771
|
-
maxTokens: contextMaxTokens
|
|
2811
|
+
percentage: props.contextPercentage,
|
|
2812
|
+
usedTokens: props.contextUsedTokens,
|
|
2813
|
+
maxTokens: props.contextMaxTokens
|
|
2772
2814
|
}
|
|
2773
2815
|
)
|
|
2774
2816
|
] });
|
|
2775
2817
|
}
|
|
2776
|
-
function StatusRight({
|
|
2777
|
-
isThinking,
|
|
2778
|
-
messageCount
|
|
2779
|
-
}) {
|
|
2780
|
-
return /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
2781
|
-
isThinking && /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
2782
|
-
/* @__PURE__ */ jsx5(Text5, { color: "yellow", children: "thinking..." }),
|
|
2783
|
-
" "
|
|
2784
|
-
] }),
|
|
2785
|
-
/* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
2786
|
-
"msgs: ",
|
|
2787
|
-
messageCount
|
|
2788
|
-
] })
|
|
2789
|
-
] });
|
|
2790
|
-
}
|
|
2791
2818
|
function StatusBar({
|
|
2792
2819
|
permissionMode,
|
|
2793
2820
|
modelName,
|
|
2821
|
+
providerProfileName,
|
|
2822
|
+
providerType,
|
|
2794
2823
|
sessionId: _sessionId,
|
|
2795
|
-
messageCount,
|
|
2796
2824
|
isThinking,
|
|
2797
2825
|
activeToolCount = 0,
|
|
2798
2826
|
activeBackgroundTaskCount = 0,
|
|
@@ -2804,7 +2832,7 @@ function StatusBar({
|
|
|
2804
2832
|
gitBranch,
|
|
2805
2833
|
showGitBranch = true
|
|
2806
2834
|
}) {
|
|
2807
|
-
return /* @__PURE__ */
|
|
2835
|
+
return /* @__PURE__ */ jsx5(
|
|
2808
2836
|
Box5,
|
|
2809
2837
|
{
|
|
2810
2838
|
borderStyle: "single",
|
|
@@ -2812,26 +2840,25 @@ function StatusBar({
|
|
|
2812
2840
|
paddingLeft: 1,
|
|
2813
2841
|
paddingRight: 1,
|
|
2814
2842
|
justifyContent: "space-between",
|
|
2815
|
-
children:
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
]
|
|
2843
|
+
children: /* @__PURE__ */ jsx5(
|
|
2844
|
+
StatusLeft,
|
|
2845
|
+
{
|
|
2846
|
+
permissionMode,
|
|
2847
|
+
modelName,
|
|
2848
|
+
providerProfileName,
|
|
2849
|
+
providerType,
|
|
2850
|
+
isThinking,
|
|
2851
|
+
activeToolCount,
|
|
2852
|
+
activeBackgroundTaskCount,
|
|
2853
|
+
hasPendingPrompt,
|
|
2854
|
+
contextPercentage,
|
|
2855
|
+
contextUsedTokens,
|
|
2856
|
+
contextMaxTokens,
|
|
2857
|
+
sessionName,
|
|
2858
|
+
gitBranch,
|
|
2859
|
+
showGitBranch
|
|
2860
|
+
}
|
|
2861
|
+
)
|
|
2835
2862
|
}
|
|
2836
2863
|
);
|
|
2837
2864
|
}
|
|
@@ -2842,8 +2869,9 @@ function SessionStatusBar({
|
|
|
2842
2869
|
cwd,
|
|
2843
2870
|
permissionMode,
|
|
2844
2871
|
modelId,
|
|
2872
|
+
providerProfileName,
|
|
2873
|
+
providerType,
|
|
2845
2874
|
sessionId,
|
|
2846
|
-
messageCount,
|
|
2847
2875
|
isThinking,
|
|
2848
2876
|
activeToolCount,
|
|
2849
2877
|
activeBackgroundTaskCount,
|
|
@@ -2859,8 +2887,9 @@ function SessionStatusBar({
|
|
|
2859
2887
|
{
|
|
2860
2888
|
permissionMode,
|
|
2861
2889
|
modelName: modelId ? getModelName2(modelId) : "",
|
|
2890
|
+
providerProfileName,
|
|
2891
|
+
providerType,
|
|
2862
2892
|
sessionId,
|
|
2863
|
-
messageCount,
|
|
2864
2893
|
isThinking,
|
|
2865
2894
|
activeToolCount,
|
|
2866
2895
|
activeBackgroundTaskCount,
|
|
@@ -3888,6 +3917,7 @@ function submitTextPromptValue(state, options) {
|
|
|
3888
3917
|
import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3889
3918
|
function TextPrompt({
|
|
3890
3919
|
title,
|
|
3920
|
+
description,
|
|
3891
3921
|
placeholder,
|
|
3892
3922
|
onSubmit,
|
|
3893
3923
|
onCancel,
|
|
@@ -3912,12 +3942,11 @@ function TextPrompt({
|
|
|
3912
3942
|
);
|
|
3913
3943
|
useInput5((input, key) => {
|
|
3914
3944
|
const action = getTextPromptInputAction(input, key);
|
|
3915
|
-
if (action !== void 0)
|
|
3916
|
-
applyAction(action);
|
|
3917
|
-
}
|
|
3945
|
+
if (action !== void 0) applyAction(action);
|
|
3918
3946
|
});
|
|
3919
3947
|
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
3920
3948
|
/* @__PURE__ */ jsx13(Text12, { color: "yellow", bold: true, children: title }),
|
|
3949
|
+
/* @__PURE__ */ jsx13(PromptDescription, { description }),
|
|
3921
3950
|
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
3922
3951
|
/* @__PURE__ */ jsx13(Text12, { color: "cyan", children: "> " }),
|
|
3923
3952
|
state.value ? /* @__PURE__ */ jsx13(Text12, { children: masked ? "*".repeat(state.value.length) : state.value }) : placeholder ? /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: placeholder }) : null,
|
|
@@ -3927,6 +3956,12 @@ function TextPrompt({
|
|
|
3927
3956
|
/* @__PURE__ */ jsx13(Text12, { dimColor: true, children: " Enter Submit Esc Cancel" })
|
|
3928
3957
|
] });
|
|
3929
3958
|
}
|
|
3959
|
+
function PromptDescription({ description }) {
|
|
3960
|
+
if (description === void 0 || description.length === 0) {
|
|
3961
|
+
return null;
|
|
3962
|
+
}
|
|
3963
|
+
return /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: description });
|
|
3964
|
+
}
|
|
3930
3965
|
|
|
3931
3966
|
// src/ui/InteractivePrompt.tsx
|
|
3932
3967
|
import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
@@ -3940,6 +3975,7 @@ function InteractivePrompt({
|
|
|
3940
3975
|
TextPrompt,
|
|
3941
3976
|
{
|
|
3942
3977
|
title: prompt.title,
|
|
3978
|
+
description: prompt.description,
|
|
3943
3979
|
placeholder: prompt.placeholder,
|
|
3944
3980
|
allowEmpty: prompt.allowEmpty,
|
|
3945
3981
|
masked: prompt.masked,
|
|
@@ -3952,6 +3988,7 @@ function InteractivePrompt({
|
|
|
3952
3988
|
}
|
|
3953
3989
|
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
|
|
3954
3990
|
/* @__PURE__ */ jsx14(Text13, { bold: true, children: prompt.title }),
|
|
3991
|
+
prompt.description !== void 0 && prompt.description.length > 0 && /* @__PURE__ */ jsx14(Text13, { dimColor: true, children: prompt.description }),
|
|
3955
3992
|
/* @__PURE__ */ jsx14(
|
|
3956
3993
|
ListPicker,
|
|
3957
3994
|
{
|
|
@@ -4542,26 +4579,20 @@ function PluginTUI({ callbacks, onClose, addMessage }) {
|
|
|
4542
4579
|
import { Box as Box15, Text as Text17 } from "ink";
|
|
4543
4580
|
import { Fragment as Fragment5, jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4544
4581
|
var SESSION_ID_DISPLAY_LENGTH = 8;
|
|
4582
|
+
var SESSION_PREVIEW_DISPLAY_LENGTH = 60;
|
|
4545
4583
|
function SessionPicker({
|
|
4546
|
-
|
|
4547
|
-
cwd,
|
|
4584
|
+
sessions,
|
|
4548
4585
|
onSelect,
|
|
4549
4586
|
onCancel
|
|
4550
4587
|
}) {
|
|
4551
|
-
const sessions = (sessionStore?.list() ?? []).filter((s) => s.cwd === cwd);
|
|
4552
4588
|
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
|
|
4553
4589
|
/* @__PURE__ */ jsx19(Text17, { bold: true, color: "cyan", children: "Select a session to resume (ESC to cancel):" }),
|
|
4554
4590
|
/* @__PURE__ */ jsx19(
|
|
4555
4591
|
ListPicker,
|
|
4556
4592
|
{
|
|
4557
|
-
items: sessions,
|
|
4593
|
+
items: [...sessions],
|
|
4558
4594
|
renderItem: (session, isSelected) => {
|
|
4559
|
-
const
|
|
4560
|
-
const msg = m;
|
|
4561
|
-
return msg.role === "assistant" && msg.content;
|
|
4562
|
-
});
|
|
4563
|
-
const rawPreview = lastMsg?.content?.replace(/[\n\r]+/g, " ").trim() ?? "";
|
|
4564
|
-
const preview = rawPreview ? rawPreview.slice(0, 60) + (rawPreview.length > 60 ? "..." : "") : "";
|
|
4595
|
+
const preview = session.preview ? session.preview.slice(0, SESSION_PREVIEW_DISPLAY_LENGTH) + (session.preview.length > SESSION_PREVIEW_DISPLAY_LENGTH ? "..." : "") : "";
|
|
4565
4596
|
return /* @__PURE__ */ jsxs15(Text17, { children: [
|
|
4566
4597
|
isSelected ? "> " : " ",
|
|
4567
4598
|
/* @__PURE__ */ jsx19(Text17, { bold: true, children: session.name ?? session.id.slice(0, SESSION_ID_DISPLAY_LENGTH) }),
|
|
@@ -4575,7 +4606,7 @@ function SessionPicker({
|
|
|
4575
4606
|
" ",
|
|
4576
4607
|
/* @__PURE__ */ jsxs15(Text17, { dimColor: true, children: [
|
|
4577
4608
|
"msgs: ",
|
|
4578
|
-
session.
|
|
4609
|
+
session.messageCount
|
|
4579
4610
|
] }),
|
|
4580
4611
|
preview ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
4581
4612
|
"\n ",
|
|
@@ -4971,12 +5002,19 @@ function isJsonObject(value) {
|
|
|
4971
5002
|
import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4972
5003
|
function App(props) {
|
|
4973
5004
|
const [activeSessionId, setActiveSessionId] = useState14(props.resumeSessionId);
|
|
5005
|
+
const [showInitialSessionPicker, setShowInitialSessionPicker] = useState14(
|
|
5006
|
+
props.showSessionPickerOnStart ?? false
|
|
5007
|
+
);
|
|
4974
5008
|
return /* @__PURE__ */ jsx22(
|
|
4975
5009
|
AppInner,
|
|
4976
5010
|
{
|
|
4977
5011
|
...props,
|
|
5012
|
+
showSessionPickerOnStart: showInitialSessionPicker,
|
|
4978
5013
|
resumeSessionId: activeSessionId,
|
|
4979
|
-
onSessionSwitch: (sessionId) =>
|
|
5014
|
+
onSessionSwitch: (sessionId) => {
|
|
5015
|
+
setShowInitialSessionPicker(false);
|
|
5016
|
+
setActiveSessionId(sessionId);
|
|
5017
|
+
}
|
|
4980
5018
|
},
|
|
4981
5019
|
activeSessionId ?? "__new__"
|
|
4982
5020
|
);
|
|
@@ -4986,6 +5024,7 @@ function AppInner(props) {
|
|
|
4986
5024
|
const {
|
|
4987
5025
|
interactiveSession,
|
|
4988
5026
|
registry,
|
|
5027
|
+
commandEffectQueue,
|
|
4989
5028
|
history,
|
|
4990
5029
|
addEntry,
|
|
4991
5030
|
streamingText,
|
|
@@ -5039,10 +5078,12 @@ function AppInner(props) {
|
|
|
5039
5078
|
cwd,
|
|
5040
5079
|
providerOverride: props.providerOverride,
|
|
5041
5080
|
interactiveSession,
|
|
5081
|
+
commandEffectQueue,
|
|
5042
5082
|
addEntry,
|
|
5043
5083
|
baseHandleSubmit,
|
|
5044
5084
|
setSessionName,
|
|
5045
|
-
setStatusLineSettings
|
|
5085
|
+
setStatusLineSettings,
|
|
5086
|
+
showSessionPickerOnStart: props.showSessionPickerOnStart
|
|
5046
5087
|
});
|
|
5047
5088
|
useEffect4(() => {
|
|
5048
5089
|
const name = interactiveSession?.getName?.();
|
|
@@ -5148,8 +5189,7 @@ function AppInner(props) {
|
|
|
5148
5189
|
showSessionPicker && /* @__PURE__ */ jsx22(
|
|
5149
5190
|
SessionPicker,
|
|
5150
5191
|
{
|
|
5151
|
-
|
|
5152
|
-
cwd: props.cwd,
|
|
5192
|
+
sessions: listResumableSessionSummaries(props.sessionStore, props.cwd),
|
|
5153
5193
|
onSelect: (id) => {
|
|
5154
5194
|
setShowSessionPicker(false);
|
|
5155
5195
|
props.onSessionSwitch(id);
|
|
@@ -5166,8 +5206,9 @@ function AppInner(props) {
|
|
|
5166
5206
|
cwd,
|
|
5167
5207
|
permissionMode,
|
|
5168
5208
|
modelId: props.modelId,
|
|
5209
|
+
providerProfileName: props.providerProfileName,
|
|
5210
|
+
providerType: props.providerType,
|
|
5169
5211
|
sessionId,
|
|
5170
|
-
messageCount: history.length,
|
|
5171
5212
|
isThinking,
|
|
5172
5213
|
activeToolCount: activeTools.length,
|
|
5173
5214
|
activeBackgroundTaskCount,
|
|
@@ -5243,7 +5284,7 @@ function readVersion() {
|
|
|
5243
5284
|
}
|
|
5244
5285
|
}
|
|
5245
5286
|
function promptInput(label, masked = false) {
|
|
5246
|
-
return new Promise((
|
|
5287
|
+
return new Promise((resolve3) => {
|
|
5247
5288
|
process.stdout.write(label);
|
|
5248
5289
|
let input = "";
|
|
5249
5290
|
const stdin = process.stdin;
|
|
@@ -5258,7 +5299,7 @@ function promptInput(label, masked = false) {
|
|
|
5258
5299
|
stdin.setRawMode(wasRaw ?? false);
|
|
5259
5300
|
stdin.pause();
|
|
5260
5301
|
process.stdout.write("\n");
|
|
5261
|
-
|
|
5302
|
+
resolve3(input.trim());
|
|
5262
5303
|
return;
|
|
5263
5304
|
} else if (ch === "\x7F" || ch === "\b") {
|
|
5264
5305
|
if (input.length > 0) {
|
|
@@ -5277,6 +5318,15 @@ function promptInput(label, masked = false) {
|
|
|
5277
5318
|
stdin.on("data", onData);
|
|
5278
5319
|
});
|
|
5279
5320
|
}
|
|
5321
|
+
function readTaskFilePrompt(cwd, taskFile) {
|
|
5322
|
+
const taskPath = resolve2(cwd, taskFile);
|
|
5323
|
+
const content = readFileSync6(taskPath, "utf8").trim();
|
|
5324
|
+
if (content.length === 0) {
|
|
5325
|
+
throw new Error(`Task file is empty: ${taskFile}`);
|
|
5326
|
+
}
|
|
5327
|
+
return `Task file (${taskFile}):
|
|
5328
|
+
${content}`;
|
|
5329
|
+
}
|
|
5280
5330
|
function resetConfig() {
|
|
5281
5331
|
const userPath = getUserSettingsPath();
|
|
5282
5332
|
if (deleteSettings(userPath)) {
|
|
@@ -5286,6 +5336,42 @@ function resetConfig() {
|
|
|
5286
5336
|
process.stdout.write("No user settings found.\n");
|
|
5287
5337
|
}
|
|
5288
5338
|
}
|
|
5339
|
+
function createDefaultCliCommandModules({
|
|
5340
|
+
cwd,
|
|
5341
|
+
providerDefinitions
|
|
5342
|
+
}) {
|
|
5343
|
+
return [
|
|
5344
|
+
createSkillsCommandModule({ cwd }),
|
|
5345
|
+
createHelpCommandModule(),
|
|
5346
|
+
createAgentCommandModule(),
|
|
5347
|
+
createModelCommandModule({
|
|
5348
|
+
providerDefinitions,
|
|
5349
|
+
settings: {
|
|
5350
|
+
readMergedSettings: () => readMergedProviderSettings(cwd)
|
|
5351
|
+
}
|
|
5352
|
+
}),
|
|
5353
|
+
createPermissionsCommandModule(),
|
|
5354
|
+
createLanguageCommandModule(),
|
|
5355
|
+
createBackgroundCommandModule(),
|
|
5356
|
+
createMemoryCommandModule(),
|
|
5357
|
+
createCompactCommandModule(),
|
|
5358
|
+
createContextCommandModule(),
|
|
5359
|
+
createExitCommandModule(),
|
|
5360
|
+
createSessionCommandModule(),
|
|
5361
|
+
createResetCommandModule(),
|
|
5362
|
+
createRewindCommandModule(),
|
|
5363
|
+
createStatusLineCommandModule(),
|
|
5364
|
+
createPluginCommandModule(),
|
|
5365
|
+
createProviderCommandModule({
|
|
5366
|
+
providerDefinitions,
|
|
5367
|
+
settings: {
|
|
5368
|
+
readMergedSettings: () => readMergedProviderSettings(cwd),
|
|
5369
|
+
readTargetSettings: () => readSettings(resolveProviderSettingsWriteTargetPath(cwd)),
|
|
5370
|
+
writeTargetSettings: (settings) => writeSettings(resolveProviderSettingsWriteTargetPath(cwd), settings)
|
|
5371
|
+
}
|
|
5372
|
+
})
|
|
5373
|
+
];
|
|
5374
|
+
}
|
|
5289
5375
|
async function startCli(options = {}) {
|
|
5290
5376
|
const args = parseCliArgs();
|
|
5291
5377
|
const version = readVersion();
|
|
@@ -5320,30 +5406,7 @@ async function startCli(options = {}) {
|
|
|
5320
5406
|
};
|
|
5321
5407
|
const providerDefinitions = options.providerDefinitions ?? DEFAULT_PROVIDER_DEFINITIONS;
|
|
5322
5408
|
const commandModules = [
|
|
5323
|
-
|
|
5324
|
-
createAgentCommandModule(),
|
|
5325
|
-
createModelCommandModule(),
|
|
5326
|
-
createModeCommandModule(),
|
|
5327
|
-
createPermissionsCommandModule(),
|
|
5328
|
-
createLanguageCommandModule(),
|
|
5329
|
-
createBackgroundCommandModule(),
|
|
5330
|
-
createMemoryCommandModule(),
|
|
5331
|
-
createCompactCommandModule(),
|
|
5332
|
-
createContextCommandModule(),
|
|
5333
|
-
createExitCommandModule(),
|
|
5334
|
-
createSessionCommandModule(),
|
|
5335
|
-
createResetCommandModule(),
|
|
5336
|
-
createRewindCommandModule(),
|
|
5337
|
-
createStatusLineCommandModule(),
|
|
5338
|
-
createPluginCommandModule(),
|
|
5339
|
-
createProviderCommandModule({
|
|
5340
|
-
providerDefinitions,
|
|
5341
|
-
settings: {
|
|
5342
|
-
readMergedSettings: () => readMergedProviderSettings(cwd),
|
|
5343
|
-
readTargetSettings: () => readSettings(getUserSettingsPath()),
|
|
5344
|
-
writeTargetSettings: (settings) => writeSettings(getUserSettingsPath(), settings)
|
|
5345
|
-
}
|
|
5346
|
-
}),
|
|
5409
|
+
...createDefaultCliCommandModules({ cwd, providerDefinitions }),
|
|
5347
5410
|
...options.commandModules ?? []
|
|
5348
5411
|
];
|
|
5349
5412
|
const startupUpdateNoticePromise = shouldRunStartupCliUpdateCheck(args) ? getStartupCliUpdateNotice({ currentVersion: version }) : void 0;
|
|
@@ -5362,6 +5425,8 @@ async function startCli(options = {}) {
|
|
|
5362
5425
|
process.exit(1);
|
|
5363
5426
|
}
|
|
5364
5427
|
const providerOptions = args.provider ? { providerOverride: args.provider, providerDefinitions } : { providerDefinitions };
|
|
5428
|
+
const activeProviderSettings = readMergedProviderSettings(cwd);
|
|
5429
|
+
const providerProfileName = args.provider ?? activeProviderSettings.currentProvider;
|
|
5365
5430
|
const providerSettings = readProviderSettings(cwd, providerOptions);
|
|
5366
5431
|
const modelId = args.model ?? providerSettings.model;
|
|
5367
5432
|
const provider = createProviderFromSettings(cwd, args.model, providerOptions);
|
|
@@ -5371,22 +5436,17 @@ async function startCli(options = {}) {
|
|
|
5371
5436
|
providerConfig: { ...providerSettings, model: modelId },
|
|
5372
5437
|
logsDir: paths.logs
|
|
5373
5438
|
});
|
|
5374
|
-
const sessionStore =
|
|
5439
|
+
const sessionStore = createProjectSessionStore(cwd);
|
|
5375
5440
|
let resumeSessionId;
|
|
5441
|
+
let showSessionPickerOnStart = false;
|
|
5376
5442
|
if (args.continueMode) {
|
|
5377
|
-
|
|
5378
|
-
if (sessions.length > 0) {
|
|
5379
|
-
resumeSessionId = sessions[0].id;
|
|
5380
|
-
}
|
|
5443
|
+
resumeSessionId = resolveLatestSessionId(sessionStore, cwd);
|
|
5381
5444
|
} else if (args.resumeId !== void 0) {
|
|
5382
5445
|
if (args.resumeId === "") {
|
|
5383
|
-
|
|
5446
|
+
showSessionPickerOnStart = true;
|
|
5384
5447
|
} else {
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
if (match) {
|
|
5388
|
-
resumeSessionId = match.id;
|
|
5389
|
-
} else {
|
|
5448
|
+
resumeSessionId = resolveSessionIdByIdOrName(sessionStore, args.resumeId);
|
|
5449
|
+
if (resumeSessionId === void 0) {
|
|
5390
5450
|
process.stderr.write(`Session not found: ${args.resumeId}
|
|
5391
5451
|
`);
|
|
5392
5452
|
process.exit(1);
|
|
@@ -5408,6 +5468,15 @@ async function startCli(options = {}) {
|
|
|
5408
5468
|
}
|
|
5409
5469
|
const appendParts = [];
|
|
5410
5470
|
if (args.appendSystemPrompt) appendParts.push(args.appendSystemPrompt);
|
|
5471
|
+
if (args.taskFile) {
|
|
5472
|
+
try {
|
|
5473
|
+
appendParts.push(readTaskFilePrompt(cwd, args.taskFile));
|
|
5474
|
+
} catch (error) {
|
|
5475
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}
|
|
5476
|
+
`);
|
|
5477
|
+
process.exit(1);
|
|
5478
|
+
}
|
|
5479
|
+
}
|
|
5411
5480
|
if (args.jsonSchema)
|
|
5412
5481
|
appendParts.push(
|
|
5413
5482
|
`Respond with valid JSON only, matching this JSON schema:
|
|
@@ -5442,6 +5511,8 @@ ${args.jsonSchema}`
|
|
|
5442
5511
|
cwd,
|
|
5443
5512
|
provider,
|
|
5444
5513
|
providerOverride: args.provider,
|
|
5514
|
+
providerProfileName,
|
|
5515
|
+
providerType: providerSettings.name,
|
|
5445
5516
|
modelId,
|
|
5446
5517
|
language: args.language,
|
|
5447
5518
|
permissionMode: args.permissionMode,
|
|
@@ -5449,6 +5520,7 @@ ${args.jsonSchema}`
|
|
|
5449
5520
|
version,
|
|
5450
5521
|
sessionStore,
|
|
5451
5522
|
resumeSessionId,
|
|
5523
|
+
showSessionPickerOnStart,
|
|
5452
5524
|
forkSession: args.forkSession,
|
|
5453
5525
|
sessionName: args.sessionName,
|
|
5454
5526
|
backgroundTaskRunners,
|