@robota-sdk/agent-cli 3.0.0-beta.61 → 3.0.0-beta.62
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.ko.md +297 -0
- package/README.md +17 -2
- package/bin/robota.cjs +43 -0
- package/dist/node/bin.js +6019 -3
- package/dist/node/{chunk-J654S773.js → chunk-6US65UBD.js} +4609 -4410
- package/dist/node/chunk-7D75HL37.js +287 -0
- package/dist/node/cli-N6TYREZG.js +9 -0
- package/dist/node/index.cjs +540 -258
- package/dist/node/index.js +5813 -8
- package/dist/node/subagents/child-process-subagent-worker.cjs +249 -0
- package/dist/node/subagents/child-process-subagent-worker.d.cts +2 -0
- package/package.json +38 -32
package/dist/node/index.cjs
CHANGED
|
@@ -28,8 +28,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
|
|
30
30
|
// src/index.ts
|
|
31
|
-
var
|
|
32
|
-
__export(
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
33
|
ChildProcessSubagentRunner: () => ChildProcessSubagentRunner,
|
|
34
34
|
GitWorktreeIsolationAdapter: () => GitWorktreeIsolationAdapter,
|
|
35
35
|
createChildProcessSubagentRunnerFactory: () => createChildProcessSubagentRunnerFactory,
|
|
@@ -37,7 +37,7 @@ __export(index_exports, {
|
|
|
37
37
|
createManagedShellProcessRunner: () => createManagedShellProcessRunner,
|
|
38
38
|
startCli: () => startCli
|
|
39
39
|
});
|
|
40
|
-
module.exports = __toCommonJS(
|
|
40
|
+
module.exports = __toCommonJS(src_exports);
|
|
41
41
|
|
|
42
42
|
// src/cli.ts
|
|
43
43
|
var import_node_fs8 = require("fs");
|
|
@@ -60,6 +60,7 @@ var import_agent_command_rewind = require("@robota-sdk/agent-command-rewind");
|
|
|
60
60
|
var import_agent_command_statusline = require("@robota-sdk/agent-command-statusline");
|
|
61
61
|
var import_agent_command_session = require("@robota-sdk/agent-command-session");
|
|
62
62
|
var import_agent_command_skills = require("@robota-sdk/agent-command-skills");
|
|
63
|
+
var import_agent_command_user_local2 = require("@robota-sdk/agent-command-user-local");
|
|
63
64
|
var import_agent_sdk15 = require("@robota-sdk/agent-sdk");
|
|
64
65
|
|
|
65
66
|
// src/utils/cli-args.ts
|
|
@@ -98,6 +99,9 @@ function parseCliArgs() {
|
|
|
98
99
|
"fork-session": { type: "boolean", default: false },
|
|
99
100
|
name: { type: "string", short: "n" },
|
|
100
101
|
"output-format": { type: "string" },
|
|
102
|
+
format: { type: "string" },
|
|
103
|
+
summary: { type: "string" },
|
|
104
|
+
source: { type: "string" },
|
|
101
105
|
"system-prompt": { type: "string" },
|
|
102
106
|
"append-system-prompt": { type: "string" },
|
|
103
107
|
"task-file": { type: "string" },
|
|
@@ -117,7 +121,10 @@ function parseCliArgs() {
|
|
|
117
121
|
"set-current": { type: "boolean", default: false },
|
|
118
122
|
"settings-scope": { type: "string" },
|
|
119
123
|
"check-update": { type: "boolean", default: false },
|
|
120
|
-
"disable-update-check": { type: "boolean", default: false }
|
|
124
|
+
"disable-update-check": { type: "boolean", default: false },
|
|
125
|
+
web: { type: "boolean", default: false },
|
|
126
|
+
"web-port": { type: "string" },
|
|
127
|
+
"no-open": { type: "boolean", default: false }
|
|
121
128
|
}
|
|
122
129
|
});
|
|
123
130
|
return {
|
|
@@ -132,6 +139,9 @@ function parseCliArgs() {
|
|
|
132
139
|
forkSession: values["fork-session"] ?? false,
|
|
133
140
|
sessionName: values["name"],
|
|
134
141
|
outputFormat: values["output-format"],
|
|
142
|
+
format: values["format"],
|
|
143
|
+
summary: values["summary"],
|
|
144
|
+
source: values["source"],
|
|
135
145
|
systemPrompt: values["system-prompt"],
|
|
136
146
|
appendSystemPrompt: values["append-system-prompt"],
|
|
137
147
|
taskFile: values["task-file"],
|
|
@@ -151,9 +161,23 @@ function parseCliArgs() {
|
|
|
151
161
|
setCurrent: values["set-current"] ?? false,
|
|
152
162
|
settingsScope: values["settings-scope"],
|
|
153
163
|
checkUpdate: values["check-update"] ?? false,
|
|
154
|
-
disableUpdateCheck: values["disable-update-check"] ?? false
|
|
164
|
+
disableUpdateCheck: values["disable-update-check"] ?? false,
|
|
165
|
+
web: values["web"] ?? false,
|
|
166
|
+
webPort: parseWebPort(values["web-port"]),
|
|
167
|
+
noOpen: values["no-open"] ?? false
|
|
155
168
|
};
|
|
156
169
|
}
|
|
170
|
+
var DEFAULT_WEB_PORT = 7070;
|
|
171
|
+
function parseWebPort(raw) {
|
|
172
|
+
if (raw === void 0) return DEFAULT_WEB_PORT;
|
|
173
|
+
const n = parseInt(raw, 10);
|
|
174
|
+
if (isNaN(n) || n < 1 || n > 65535) {
|
|
175
|
+
process.stderr.write(`Invalid --web-port "${raw}". Must be 1\u201365535.
|
|
176
|
+
`);
|
|
177
|
+
process.exit(1);
|
|
178
|
+
}
|
|
179
|
+
return n;
|
|
180
|
+
}
|
|
157
181
|
|
|
158
182
|
// src/utils/settings-io.ts
|
|
159
183
|
var import_node_fs = require("fs");
|
|
@@ -658,67 +682,60 @@ function formatConfigureProviderExample(definition) {
|
|
|
658
682
|
var import_agent_transport_headless = require("@robota-sdk/agent-transport-headless");
|
|
659
683
|
|
|
660
684
|
// src/ui/render.tsx
|
|
661
|
-
var
|
|
685
|
+
var import_ink24 = require("ink");
|
|
662
686
|
|
|
663
687
|
// src/ui/App.tsx
|
|
664
|
-
var
|
|
665
|
-
var
|
|
688
|
+
var import_react20 = require("react");
|
|
689
|
+
var import_ink23 = require("ink");
|
|
666
690
|
var import_agent_sdk9 = require("@robota-sdk/agent-sdk");
|
|
667
691
|
var import_agent_core11 = require("@robota-sdk/agent-core");
|
|
668
692
|
|
|
669
693
|
// src/ui/hooks/useInteractiveSession.ts
|
|
670
694
|
var import_react2 = require("react");
|
|
695
|
+
var import_open = __toESM(require("open"), 1);
|
|
671
696
|
var import_agent_sdk5 = require("@robota-sdk/agent-sdk");
|
|
672
|
-
var import_agent_core3 = require("@robota-sdk/agent-core");
|
|
673
697
|
|
|
674
|
-
// src/
|
|
675
|
-
var
|
|
676
|
-
var
|
|
677
|
-
var
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
}
|
|
710
|
-
return state.status;
|
|
711
|
-
}
|
|
712
|
-
function shouldHideAtNextUserTurn(state) {
|
|
713
|
-
return state.status === "completed" && !state.error && (state.result?.exitCode === void 0 || state.result.exitCode === SUCCESS_EXIT_CODE) && !state.result?.signalCode && !state.worktreePath && !state.branchName;
|
|
714
|
-
}
|
|
715
|
-
function trimBackgroundPreview(value) {
|
|
716
|
-
if (!value) return void 0;
|
|
717
|
-
const preview = value.trim().replace(BACKGROUND_PREVIEW_WHITESPACE, BACKGROUND_PREVIEW_SEPARATOR);
|
|
718
|
-
if (!preview) return void 0;
|
|
719
|
-
return preview.length > BACKGROUND_PREVIEW_LENGTH ? `${preview.slice(0, BACKGROUND_PREVIEW_LENGTH)}...` : preview;
|
|
698
|
+
// src/web-sidecar/web-sidecar-server.ts
|
|
699
|
+
var import_node_http = require("http");
|
|
700
|
+
var import_ws = require("ws");
|
|
701
|
+
var import_agent_transport_ws = require("@robota-sdk/agent-transport-ws");
|
|
702
|
+
function startWebSidecarServer(session, port) {
|
|
703
|
+
return new Promise((resolve3, reject) => {
|
|
704
|
+
const httpServer = (0, import_node_http.createServer)((_req, res) => {
|
|
705
|
+
res.writeHead(200, { "Content-Type": "text/plain" });
|
|
706
|
+
res.end("Robota web monitor sidecar");
|
|
707
|
+
});
|
|
708
|
+
const wss = new import_ws.WebSocketServer({ server: httpServer });
|
|
709
|
+
wss.on("connection", (ws) => {
|
|
710
|
+
const send = (message) => {
|
|
711
|
+
if (ws.readyState === import_ws.WebSocket.OPEN) {
|
|
712
|
+
ws.send(JSON.stringify(message));
|
|
713
|
+
}
|
|
714
|
+
};
|
|
715
|
+
const { onMessage, cleanup } = (0, import_agent_transport_ws.createWsHandler)({ session, send });
|
|
716
|
+
ws.on("message", (data) => onMessage(String(data)));
|
|
717
|
+
ws.on("close", cleanup);
|
|
718
|
+
ws.on("error", cleanup);
|
|
719
|
+
const messages = session.getMessages();
|
|
720
|
+
send({ type: "messages", messages });
|
|
721
|
+
});
|
|
722
|
+
httpServer.on("error", reject);
|
|
723
|
+
httpServer.listen(port, "127.0.0.1", () => {
|
|
724
|
+
resolve3({
|
|
725
|
+
port,
|
|
726
|
+
stop: () => new Promise((res) => {
|
|
727
|
+
wss.close(() => {
|
|
728
|
+
httpServer.close(() => res());
|
|
729
|
+
});
|
|
730
|
+
})
|
|
731
|
+
});
|
|
732
|
+
});
|
|
733
|
+
});
|
|
720
734
|
}
|
|
721
735
|
|
|
736
|
+
// src/ui/hooks/useInteractiveSession.ts
|
|
737
|
+
var import_agent_core3 = require("@robota-sdk/agent-core");
|
|
738
|
+
|
|
722
739
|
// src/ui/tui-state-manager.ts
|
|
723
740
|
var MAX_RENDERED_MESSAGES = 100;
|
|
724
741
|
var STREAMING_DEBOUNCE_MS = 300;
|
|
@@ -750,13 +767,12 @@ var TuiStateManager = class {
|
|
|
750
767
|
isAborting = false;
|
|
751
768
|
pendingPrompt = null;
|
|
752
769
|
contextState = { percentage: 0, usedTokens: 0, maxTokens: 0 };
|
|
753
|
-
|
|
770
|
+
executionWorkspaceSnapshot = null;
|
|
771
|
+
selectedExecutionEntryId;
|
|
754
772
|
/** Called after any state change. React hook sets this to trigger re-render. */
|
|
755
773
|
onChange = null;
|
|
756
774
|
// ── Internal ──────────────────────────────────────────────────
|
|
757
775
|
streamBuf = "";
|
|
758
|
-
backgroundTextBuffers = /* @__PURE__ */ new Map();
|
|
759
|
-
backgroundTasksHiddenOnNextTurn = /* @__PURE__ */ new Set();
|
|
760
776
|
debouncedStreamNotify = createDebouncedNotify(() => this.notify(), STREAMING_DEBOUNCE_MS);
|
|
761
777
|
notify() {
|
|
762
778
|
this.onChange?.();
|
|
@@ -825,30 +841,6 @@ var TuiStateManager = class {
|
|
|
825
841
|
maxTokens: state.maxTokens
|
|
826
842
|
});
|
|
827
843
|
};
|
|
828
|
-
onBackgroundTaskEvent = (event) => {
|
|
829
|
-
if ("task" in event) {
|
|
830
|
-
this.upsertBackgroundTask(event.task);
|
|
831
|
-
return;
|
|
832
|
-
}
|
|
833
|
-
if (event.type === "background_task_closed") {
|
|
834
|
-
this.backgroundTextBuffers.delete(event.taskId);
|
|
835
|
-
this.backgroundTasksHiddenOnNextTurn.delete(event.taskId);
|
|
836
|
-
this.backgroundTasks = this.backgroundTasks.filter((task) => task.id !== event.taskId);
|
|
837
|
-
this.notify();
|
|
838
|
-
return;
|
|
839
|
-
}
|
|
840
|
-
if (event.type === "background_task_text_delta") {
|
|
841
|
-
this.appendBackgroundTaskText(event.taskId, event.delta);
|
|
842
|
-
return;
|
|
843
|
-
}
|
|
844
|
-
if (event.type === "background_task_tool_start") {
|
|
845
|
-
this.updateBackgroundTaskAction(event.taskId, event.firstArg ?? event.toolName);
|
|
846
|
-
return;
|
|
847
|
-
}
|
|
848
|
-
if (event.type === "background_task_tool_end") {
|
|
849
|
-
this.updateBackgroundTaskAction(event.taskId, event.success ? void 0 : event.error);
|
|
850
|
-
}
|
|
851
|
-
};
|
|
852
844
|
// ── State updates from external sources ───────────────────────
|
|
853
845
|
/** Sync history from InteractiveSession */
|
|
854
846
|
syncHistory(entries) {
|
|
@@ -885,49 +877,24 @@ var TuiStateManager = class {
|
|
|
885
877
|
this.contextState = state;
|
|
886
878
|
this.notify();
|
|
887
879
|
}
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
const
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
this.
|
|
897
|
-
}
|
|
898
|
-
upsertBackgroundTask(state) {
|
|
899
|
-
const partialText = state.result ? void 0 : this.backgroundTextBuffers.get(state.id);
|
|
900
|
-
const viewModel = toBackgroundTaskViewModel(state, partialText);
|
|
901
|
-
const index = this.backgroundTasks.findIndex((task) => task.id === state.id);
|
|
902
|
-
if (index === -1) {
|
|
903
|
-
this.backgroundTasks = [...this.backgroundTasks, viewModel];
|
|
904
|
-
} else {
|
|
905
|
-
const updated = [...this.backgroundTasks];
|
|
906
|
-
updated[index] = viewModel;
|
|
907
|
-
this.backgroundTasks = updated;
|
|
908
|
-
}
|
|
909
|
-
if (state.status === "completed" || state.status === "failed" || state.status === "cancelled") {
|
|
910
|
-
this.backgroundTextBuffers.delete(state.id);
|
|
911
|
-
}
|
|
912
|
-
if (shouldHideAtNextUserTurn(state)) {
|
|
913
|
-
this.backgroundTasksHiddenOnNextTurn.add(state.id);
|
|
914
|
-
} else {
|
|
915
|
-
this.backgroundTasksHiddenOnNextTurn.delete(state.id);
|
|
916
|
-
}
|
|
917
|
-
this.notify();
|
|
918
|
-
}
|
|
919
|
-
appendBackgroundTaskText(taskId, delta) {
|
|
920
|
-
const nextText = `${this.backgroundTextBuffers.get(taskId) ?? ""}${delta}`;
|
|
921
|
-
this.backgroundTextBuffers.set(taskId, nextText);
|
|
922
|
-
this.backgroundTasks = this.backgroundTasks.map(
|
|
923
|
-
(task) => task.id === taskId ? { ...task, resultPreview: trimBackgroundPreview(nextText) } : task
|
|
924
|
-
);
|
|
880
|
+
syncExecutionWorkspaceSnapshot(snapshot) {
|
|
881
|
+
const currentSelection = this.selectedExecutionEntryId;
|
|
882
|
+
const hasCurrentSelection = currentSelection !== void 0 && snapshot.entries.some((entry) => entry.id === currentSelection);
|
|
883
|
+
const selectedExecutionEntryId = hasCurrentSelection ? currentSelection : snapshot.selectedEntryId ?? snapshot.entries[0]?.id;
|
|
884
|
+
this.executionWorkspaceSnapshot = {
|
|
885
|
+
...snapshot,
|
|
886
|
+
...selectedExecutionEntryId ? { selectedEntryId: selectedExecutionEntryId } : {}
|
|
887
|
+
};
|
|
888
|
+
this.selectedExecutionEntryId = selectedExecutionEntryId;
|
|
925
889
|
this.notify();
|
|
926
890
|
}
|
|
927
|
-
|
|
928
|
-
this.
|
|
929
|
-
|
|
930
|
-
|
|
891
|
+
selectExecutionWorkspaceEntry(entryId) {
|
|
892
|
+
if (!this.executionWorkspaceSnapshot?.entries.some((entry) => entry.id === entryId)) return;
|
|
893
|
+
this.selectedExecutionEntryId = entryId;
|
|
894
|
+
this.executionWorkspaceSnapshot = {
|
|
895
|
+
...this.executionWorkspaceSnapshot,
|
|
896
|
+
selectedEntryId: entryId
|
|
897
|
+
};
|
|
931
898
|
this.notify();
|
|
932
899
|
}
|
|
933
900
|
};
|
|
@@ -965,7 +932,6 @@ function reloadPluginCommandSource(registry) {
|
|
|
965
932
|
function useSlashRouting(interactiveSession, registry, manager, commandEffectQueue) {
|
|
966
933
|
return (0, import_react.useCallback)(
|
|
967
934
|
async (input) => {
|
|
968
|
-
manager.onUserTurnAccepted();
|
|
969
935
|
if (!input.startsWith("/")) {
|
|
970
936
|
await interactiveSession.submit(input);
|
|
971
937
|
manager.setPendingPrompt(interactiveSession.getPendingPrompt());
|
|
@@ -1050,6 +1016,16 @@ function applyCompactEventToManager(interactiveSession, manager) {
|
|
|
1050
1016
|
function applySkillActivationEventToManager(interactiveSession, manager) {
|
|
1051
1017
|
manager.syncHistory(interactiveSession.getFullHistory());
|
|
1052
1018
|
}
|
|
1019
|
+
function syncExecutionWorkspaceFromSession(interactiveSession, manager) {
|
|
1020
|
+
try {
|
|
1021
|
+
manager.syncExecutionWorkspaceSnapshot(
|
|
1022
|
+
interactiveSession.getExecutionWorkspaceSnapshot({
|
|
1023
|
+
selectedEntryId: manager.selectedExecutionEntryId
|
|
1024
|
+
})
|
|
1025
|
+
);
|
|
1026
|
+
} catch {
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1053
1029
|
function initializeSession(props, permissionHandler) {
|
|
1054
1030
|
const interactiveSession = new import_agent_sdk5.InteractiveSession({
|
|
1055
1031
|
cwd: props.cwd,
|
|
@@ -1120,9 +1096,32 @@ function useInteractiveSession(props) {
|
|
|
1120
1096
|
manager.syncHistory(restored);
|
|
1121
1097
|
}
|
|
1122
1098
|
}
|
|
1099
|
+
(0, import_react2.useEffect)(() => {
|
|
1100
|
+
if (!props.webPort) return;
|
|
1101
|
+
const port = props.webPort;
|
|
1102
|
+
let stopped = false;
|
|
1103
|
+
let stopFn = null;
|
|
1104
|
+
startWebSidecarServer(interactiveSession, port).then((server) => {
|
|
1105
|
+
stopFn = server.stop;
|
|
1106
|
+
if (stopped) {
|
|
1107
|
+
server.stop().catch(() => void 0);
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
const shouldOpen = !props.noOpen && !process.env["ROBOTA_NO_OPEN"];
|
|
1111
|
+
const monitorUrl = process.env["ROBOTA_MONITOR_URL"] ?? "http://localhost:7071/monitor";
|
|
1112
|
+
if (shouldOpen) {
|
|
1113
|
+
(0, import_open.default)(monitorUrl).catch(() => void 0);
|
|
1114
|
+
}
|
|
1115
|
+
}).catch(() => void 0);
|
|
1116
|
+
return () => {
|
|
1117
|
+
stopped = true;
|
|
1118
|
+
if (stopFn) stopFn().catch(() => void 0);
|
|
1119
|
+
};
|
|
1120
|
+
}, [interactiveSession, props.webPort, props.noOpen]);
|
|
1123
1121
|
(0, import_react2.useEffect)(() => {
|
|
1124
1122
|
const onCompact = () => applyCompactEventToManager(interactiveSession, manager);
|
|
1125
1123
|
const onSkillActivation = () => applySkillActivationEventToManager(interactiveSession, manager);
|
|
1124
|
+
const onExecutionWorkspaceEvent = (event) => manager.syncExecutionWorkspaceSnapshot(event.snapshot);
|
|
1126
1125
|
interactiveSession.on("text_delta", manager.onTextDelta);
|
|
1127
1126
|
interactiveSession.on("tool_start", manager.onToolStart);
|
|
1128
1127
|
interactiveSession.on("tool_end", manager.onToolEnd);
|
|
@@ -1133,7 +1132,7 @@ function useInteractiveSession(props) {
|
|
|
1133
1132
|
interactiveSession.on("context_update", manager.onContextUpdate);
|
|
1134
1133
|
interactiveSession.on("compact", onCompact);
|
|
1135
1134
|
interactiveSession.on("skill_activation", onSkillActivation);
|
|
1136
|
-
interactiveSession.on("
|
|
1135
|
+
interactiveSession.on("execution_workspace_event", onExecutionWorkspaceEvent);
|
|
1137
1136
|
const initCheck = setInterval(() => {
|
|
1138
1137
|
try {
|
|
1139
1138
|
const ctx = interactiveSession.getContextState();
|
|
@@ -1146,6 +1145,7 @@ function useInteractiveSession(props) {
|
|
|
1146
1145
|
if (restored.length > 0) {
|
|
1147
1146
|
manager.syncHistory(restored);
|
|
1148
1147
|
}
|
|
1148
|
+
syncExecutionWorkspaceFromSession(interactiveSession, manager);
|
|
1149
1149
|
clearInterval(initCheck);
|
|
1150
1150
|
} catch {
|
|
1151
1151
|
}
|
|
@@ -1162,11 +1162,12 @@ function useInteractiveSession(props) {
|
|
|
1162
1162
|
interactiveSession.off("context_update", manager.onContextUpdate);
|
|
1163
1163
|
interactiveSession.off("compact", onCompact);
|
|
1164
1164
|
interactiveSession.off("skill_activation", onSkillActivation);
|
|
1165
|
-
interactiveSession.off("
|
|
1165
|
+
interactiveSession.off("execution_workspace_event", onExecutionWorkspaceEvent);
|
|
1166
1166
|
};
|
|
1167
1167
|
}, [interactiveSession, manager]);
|
|
1168
1168
|
(0, import_react2.useEffect)(() => {
|
|
1169
1169
|
manager.syncHistory(interactiveSession.getFullHistory());
|
|
1170
|
+
syncExecutionWorkspaceFromSession(interactiveSession, manager);
|
|
1170
1171
|
if (!manager.isThinking) {
|
|
1171
1172
|
manager.setPendingPrompt(interactiveSession.getPendingPrompt());
|
|
1172
1173
|
}
|
|
@@ -1189,6 +1190,14 @@ function useInteractiveSession(props) {
|
|
|
1189
1190
|
},
|
|
1190
1191
|
[interactiveSession, manager, isShuttingDown]
|
|
1191
1192
|
);
|
|
1193
|
+
const selectExecutionWorkspaceEntry = (0, import_react2.useCallback)(
|
|
1194
|
+
(entryId) => manager.selectExecutionWorkspaceEntry(entryId),
|
|
1195
|
+
[manager]
|
|
1196
|
+
);
|
|
1197
|
+
const readExecutionWorkspaceDetail = (0, import_react2.useCallback)(
|
|
1198
|
+
(entryId) => interactiveSession.readExecutionWorkspaceDetail(entryId),
|
|
1199
|
+
[interactiveSession]
|
|
1200
|
+
);
|
|
1192
1201
|
return {
|
|
1193
1202
|
interactiveSession,
|
|
1194
1203
|
registry,
|
|
@@ -1201,13 +1210,16 @@ function useInteractiveSession(props) {
|
|
|
1201
1210
|
isAborting: manager.isAborting,
|
|
1202
1211
|
isShuttingDown,
|
|
1203
1212
|
pendingPrompt: manager.pendingPrompt,
|
|
1204
|
-
|
|
1213
|
+
executionWorkspaceSnapshot: manager.executionWorkspaceSnapshot,
|
|
1214
|
+
selectedExecutionEntryId: manager.selectedExecutionEntryId,
|
|
1205
1215
|
permissionRequest,
|
|
1206
1216
|
contextState: manager.contextState,
|
|
1207
1217
|
handleSubmit,
|
|
1208
1218
|
handleAbort,
|
|
1209
1219
|
handleCancelQueue,
|
|
1210
|
-
handleShutdown
|
|
1220
|
+
handleShutdown,
|
|
1221
|
+
selectExecutionWorkspaceEntry,
|
|
1222
|
+
readExecutionWorkspaceDetail
|
|
1211
1223
|
};
|
|
1212
1224
|
}
|
|
1213
1225
|
|
|
@@ -1889,7 +1901,7 @@ function formatUsageTokenCount(tokens) {
|
|
|
1889
1901
|
|
|
1890
1902
|
// src/ui/command-output-summary.ts
|
|
1891
1903
|
var MAX_PREVIEW_LINES = 4;
|
|
1892
|
-
var
|
|
1904
|
+
var SUCCESS_EXIT_CODE = 0;
|
|
1893
1905
|
var COMMAND_TOOL_NAMES = /* @__PURE__ */ new Set(["Bash", "BackgroundProcess"]);
|
|
1894
1906
|
function formatCommandOutputSummary(tool) {
|
|
1895
1907
|
if (!COMMAND_TOOL_NAMES.has(tool.toolName) || !tool.toolResultData) return void 0;
|
|
@@ -1900,7 +1912,7 @@ function formatCommandOutputSummary(tool) {
|
|
|
1900
1912
|
const lines = trimTrailingBlankLines(splitOutputLines(output));
|
|
1901
1913
|
const previewLines = lines.slice(0, MAX_PREVIEW_LINES);
|
|
1902
1914
|
const omittedLineCount = Math.max(0, lines.length - previewLines.length);
|
|
1903
|
-
const isFailed = tool.result === "error" || successValue === false || exitCode !== void 0 && exitCode !==
|
|
1915
|
+
const isFailed = tool.result === "error" || successValue === false || exitCode !== void 0 && exitCode !== SUCCESS_EXIT_CODE;
|
|
1904
1916
|
return {
|
|
1905
1917
|
status: isFailed ? "error" : "success",
|
|
1906
1918
|
statusLabel: formatStatusLabel(isFailed, exitCode),
|
|
@@ -1930,7 +1942,7 @@ function buildOutputText(raw, parsed) {
|
|
|
1930
1942
|
return lines.join("\n");
|
|
1931
1943
|
}
|
|
1932
1944
|
function formatStatusLabel(isFailed, exitCode) {
|
|
1933
|
-
if (exitCode !== void 0 && exitCode !==
|
|
1945
|
+
if (exitCode !== void 0 && exitCode !== SUCCESS_EXIT_CODE) return `exit ${exitCode}`;
|
|
1934
1946
|
return isFailed ? "error" : "ok";
|
|
1935
1947
|
}
|
|
1936
1948
|
function splitOutputLines(output) {
|
|
@@ -4182,115 +4194,281 @@ function SessionPicker({
|
|
|
4182
4194
|
// src/ui/BackgroundTaskPanel.tsx
|
|
4183
4195
|
var import_ink19 = require("ink");
|
|
4184
4196
|
|
|
4185
|
-
// src/ui/
|
|
4186
|
-
var
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
return {
|
|
4200
|
-
...row,
|
|
4201
|
-
accessibleText: formatAccessibleText(row)
|
|
4202
|
-
};
|
|
4197
|
+
// src/ui/execution-workspace-view-model.ts
|
|
4198
|
+
var ACTIVE_STATUSES = [
|
|
4199
|
+
"active",
|
|
4200
|
+
"queued",
|
|
4201
|
+
"running",
|
|
4202
|
+
"waiting_permission"
|
|
4203
|
+
];
|
|
4204
|
+
var DETAIL_RECORD_TEXT_LIMIT = 160;
|
|
4205
|
+
var PREVIEW_WHITESPACE = /\s+/g;
|
|
4206
|
+
var PREVIEW_SEPARATOR = " ";
|
|
4207
|
+
function getDefaultBackgroundWorkspaceEntries(snapshot) {
|
|
4208
|
+
return (snapshot?.entries ?? []).filter(
|
|
4209
|
+
(entry) => entry.kind === "background_task" && entry.visibility === "default"
|
|
4210
|
+
);
|
|
4203
4211
|
}
|
|
4204
|
-
function
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
return "cyan";
|
|
4212
|
+
function countActiveBackgroundWorkspaceEntries(snapshot) {
|
|
4213
|
+
return getDefaultBackgroundWorkspaceEntries(snapshot).filter(
|
|
4214
|
+
(entry) => ACTIVE_STATUSES.includes(entry.status)
|
|
4215
|
+
).length;
|
|
4209
4216
|
}
|
|
4210
|
-
function
|
|
4211
|
-
|
|
4212
|
-
|
|
4217
|
+
function formatExecutionWorkspaceEntryRow(entry, options = {}) {
|
|
4218
|
+
const isSelected = entry.id === options.selectedEntryId;
|
|
4219
|
+
const row = {
|
|
4220
|
+
id: entry.id,
|
|
4221
|
+
radio: isSelected ? "\u25CF" : "\u25CB",
|
|
4222
|
+
title: formatEntryTitle(entry),
|
|
4223
|
+
subtitle: formatEntrySubtitle(entry),
|
|
4224
|
+
statusLabel: formatStatusLabel2(entry.status),
|
|
4225
|
+
preview: trimPreview(entry.preview ?? entry.currentAction),
|
|
4226
|
+
color: getEntryColor(entry),
|
|
4227
|
+
isSelected
|
|
4228
|
+
};
|
|
4229
|
+
return { ...row, accessibleText: formatAccessibleText(row) };
|
|
4230
|
+
}
|
|
4231
|
+
function formatExecutionDetailRecord(record) {
|
|
4232
|
+
const text = record.text.trim().replace(PREVIEW_WHITESPACE, PREVIEW_SEPARATOR);
|
|
4233
|
+
if (!text) return record.kind;
|
|
4234
|
+
return text.length > DETAIL_RECORD_TEXT_LIMIT ? `${text.slice(0, DETAIL_RECORD_TEXT_LIMIT)}...` : text;
|
|
4235
|
+
}
|
|
4236
|
+
function formatEntryTitle(entry) {
|
|
4237
|
+
if (entry.kind === "main_thread") return entry.title;
|
|
4238
|
+
if (entry.kind === "background_group") return `${entry.title} group`;
|
|
4239
|
+
if (entry.taskKind === "agent") return `${entry.title} agent`;
|
|
4240
|
+
if (entry.taskKind === "process") return entry.title || "Process";
|
|
4241
|
+
return entry.title;
|
|
4242
|
+
}
|
|
4243
|
+
function formatEntrySubtitle(entry) {
|
|
4244
|
+
if (entry.kind === "main_thread") return entry.subtitle;
|
|
4245
|
+
const parts = [
|
|
4246
|
+
entry.taskKind,
|
|
4247
|
+
entry.subtitle,
|
|
4248
|
+
entry.attention === "none" ? void 0 : entry.attention
|
|
4249
|
+
];
|
|
4250
|
+
return parts.filter((part) => typeof part === "string" && part.length > 0).join(" \xB7 ") || void 0;
|
|
4213
4251
|
}
|
|
4214
|
-
function
|
|
4215
|
-
|
|
4216
|
-
if (task.kind === "process") return task.label || "Process";
|
|
4217
|
-
return task.label;
|
|
4252
|
+
function formatStatusLabel2(status) {
|
|
4253
|
+
return status.replace(/_/g, " ");
|
|
4218
4254
|
}
|
|
4219
|
-
function
|
|
4220
|
-
|
|
4221
|
-
if (
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
segments.push(task.statusLabel === "timed out" ? "timed out" : "failed");
|
|
4227
|
-
}
|
|
4228
|
-
if (task.status === "cancelled") {
|
|
4229
|
-
segments.push("cancelled");
|
|
4230
|
-
}
|
|
4231
|
-
if (task.timeoutReason) {
|
|
4232
|
-
segments.push(task.timeoutReason);
|
|
4233
|
-
}
|
|
4234
|
-
if (task.status === "completed" && task.exitCode !== void 0 && task.exitCode !== SUCCESS_EXIT_CODE3) {
|
|
4235
|
-
segments.push(`exit ${task.exitCode}`);
|
|
4236
|
-
}
|
|
4237
|
-
if (task.signalCode) {
|
|
4238
|
-
segments.push(`signal ${task.signalCode}`);
|
|
4239
|
-
}
|
|
4240
|
-
if (task.worktreePath || task.branchName) {
|
|
4241
|
-
segments.push("worktree");
|
|
4242
|
-
}
|
|
4243
|
-
return segments;
|
|
4255
|
+
function getEntryColor(entry) {
|
|
4256
|
+
if (entry.attention === "failed" || entry.status === "failed") return "red";
|
|
4257
|
+
if (entry.attention === "permission" || entry.status === "waiting_permission") return "yellow";
|
|
4258
|
+
if (entry.status === "completed") return "green";
|
|
4259
|
+
if (entry.status === "cancelled") return "yellow";
|
|
4260
|
+
if (ACTIVE_STATUSES.includes(entry.status)) return "cyan";
|
|
4261
|
+
return "white";
|
|
4244
4262
|
}
|
|
4245
|
-
function
|
|
4246
|
-
|
|
4247
|
-
if (task.worktreePath) return task.worktreePath;
|
|
4248
|
-
const preview = task.errorPreview ?? task.resultPreview ?? task.currentAction ?? task.preview;
|
|
4263
|
+
function trimPreview(value) {
|
|
4264
|
+
const preview = value?.trim().replace(PREVIEW_WHITESPACE, PREVIEW_SEPARATOR);
|
|
4249
4265
|
return preview || void 0;
|
|
4250
4266
|
}
|
|
4251
|
-
function
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
if (Number.isNaN(timestamp)) return void 0;
|
|
4255
|
-
const seconds = Math.max(0, Math.floor((now - timestamp) / MS_PER_SECOND));
|
|
4256
|
-
if (seconds < SECONDS_PER_MINUTE) return `${seconds}s`;
|
|
4257
|
-
const minutes = Math.floor(seconds / SECONDS_PER_MINUTE);
|
|
4258
|
-
if (minutes < MINUTES_PER_HOUR) return `${minutes}m`;
|
|
4259
|
-
return `${Math.floor(minutes / MINUTES_PER_HOUR)}h`;
|
|
4267
|
+
function formatAccessibleText(row) {
|
|
4268
|
+
const parts = [row.radio, row.title, row.statusLabel, row.subtitle, row.preview];
|
|
4269
|
+
return parts.filter((part) => typeof part === "string" && part.length > 0).join(" \xB7 ");
|
|
4260
4270
|
}
|
|
4261
|
-
|
|
4262
|
-
|
|
4271
|
+
|
|
4272
|
+
// src/ui/background-task-row-format.ts
|
|
4273
|
+
function formatBackgroundTaskRow(entry, options = {}) {
|
|
4274
|
+
const row = formatExecutionWorkspaceEntryRow(entry);
|
|
4275
|
+
const marker = isActiveEntry(entry) ? "\u25A1" : "\u25A0";
|
|
4276
|
+
const segments = [row.statusLabel, row.subtitle].filter(
|
|
4277
|
+
(segment) => typeof segment === "string" && segment.length > 0
|
|
4278
|
+
);
|
|
4279
|
+
return {
|
|
4280
|
+
connector: options.isLast === false ? "\u251C" : "\u2514",
|
|
4281
|
+
marker,
|
|
4282
|
+
color: row.color,
|
|
4283
|
+
label: row.title,
|
|
4284
|
+
segments,
|
|
4285
|
+
preview: row.preview,
|
|
4286
|
+
accessibleText: [
|
|
4287
|
+
`${options.isLast === false ? "\u251C" : "\u2514"} ${marker} ${row.title}`,
|
|
4288
|
+
...segments,
|
|
4289
|
+
row.preview
|
|
4290
|
+
].filter((part) => typeof part === "string" && part.length > 0).join(" \xB7 ")
|
|
4291
|
+
};
|
|
4263
4292
|
}
|
|
4264
|
-
function
|
|
4265
|
-
|
|
4266
|
-
if (row.preview) parts.push(row.preview);
|
|
4267
|
-
return parts.join(" \xB7 ");
|
|
4293
|
+
function isActiveEntry(entry) {
|
|
4294
|
+
return entry.status === "active" || entry.status === "queued" || entry.status === "running" || entry.status === "waiting_permission";
|
|
4268
4295
|
}
|
|
4269
4296
|
|
|
4270
4297
|
// src/ui/BackgroundTaskPanel.tsx
|
|
4271
4298
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
4272
|
-
function BackgroundTaskPanel({
|
|
4273
|
-
if (
|
|
4299
|
+
function BackgroundTaskPanel({ entries }) {
|
|
4300
|
+
if (entries.length === 0) return null;
|
|
4274
4301
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_ink19.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
4275
4302
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_ink19.Text, { color: "cyan", bold: true, children: "Background work" }),
|
|
4276
|
-
|
|
4277
|
-
const row = formatBackgroundTaskRow(
|
|
4303
|
+
entries.map((entry, index) => {
|
|
4304
|
+
const row = formatBackgroundTaskRow(entry, { isLast: index === entries.length - 1 });
|
|
4278
4305
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_ink19.Text, { children: [
|
|
4279
4306
|
`${row.connector} `,
|
|
4280
4307
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_ink19.Text, { color: row.color, children: row.marker }),
|
|
4281
4308
|
` ${row.label}`,
|
|
4282
4309
|
row.segments.map((segment, segmentIndex) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_ink19.Text, { dimColor: true, children: ` \xB7 ${segment}` }, `${segment}-${segmentIndex}`)),
|
|
4283
4310
|
row.preview ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_ink19.Text, { dimColor: true, children: ` \xB7 ${row.preview}` }) : null
|
|
4284
|
-
] },
|
|
4311
|
+
] }, entry.id);
|
|
4285
4312
|
})
|
|
4286
4313
|
] });
|
|
4287
4314
|
}
|
|
4288
4315
|
|
|
4289
|
-
// src/ui/
|
|
4316
|
+
// src/ui/ExecutionWorkspaceSwitcher.tsx
|
|
4317
|
+
var import_react19 = require("react");
|
|
4290
4318
|
var import_ink20 = require("ink");
|
|
4291
4319
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
4320
|
+
var MAX_VISIBLE_WORKSPACE_ENTRIES = 8;
|
|
4321
|
+
function ExecutionWorkspaceSwitcher({
|
|
4322
|
+
snapshot,
|
|
4323
|
+
selectedEntryId,
|
|
4324
|
+
onSelect,
|
|
4325
|
+
onClose
|
|
4326
|
+
}) {
|
|
4327
|
+
const entries = [...snapshot?.entries ?? []];
|
|
4328
|
+
const { normalized, visibleEntries, applyAction } = useWorkspaceSwitcherSelection({
|
|
4329
|
+
entries,
|
|
4330
|
+
selectedEntryId,
|
|
4331
|
+
onSelect,
|
|
4332
|
+
onClose
|
|
4333
|
+
});
|
|
4334
|
+
(0, import_ink20.useInput)((_input, key) => {
|
|
4335
|
+
const action = getVerticalSelectionInputAction(key);
|
|
4336
|
+
if (action !== void 0) applyAction(action);
|
|
4337
|
+
});
|
|
4338
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_ink20.Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
|
|
4339
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ink20.Text, { color: "cyan", bold: true, children: "Execution workspace" }),
|
|
4340
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ink20.Box, { flexDirection: "column", marginTop: 1, children: visibleEntries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ink20.Text, { dimColor: true, children: "No workspace entries" }) : visibleEntries.map((entry, index) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4341
|
+
ExecutionWorkspaceSwitcherRow,
|
|
4342
|
+
{
|
|
4343
|
+
entry,
|
|
4344
|
+
isFocused: normalized.scrollOffset + index === normalized.selectedIndex,
|
|
4345
|
+
selectedEntryId
|
|
4346
|
+
},
|
|
4347
|
+
entry.id
|
|
4348
|
+
)) }),
|
|
4349
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ink20.Text, { dimColor: true, children: "Ctrl+B Close \u2191\u2193 Navigate Enter Switch Esc Close" })
|
|
4350
|
+
] });
|
|
4351
|
+
}
|
|
4352
|
+
function useWorkspaceSwitcherSelection({
|
|
4353
|
+
entries,
|
|
4354
|
+
selectedEntryId,
|
|
4355
|
+
onSelect,
|
|
4356
|
+
onClose
|
|
4357
|
+
}) {
|
|
4358
|
+
const [state, setState] = (0, import_react19.useState)(() => createSelectionFlowState());
|
|
4359
|
+
const stateRef = (0, import_react19.useRef)(state);
|
|
4360
|
+
(0, import_react19.useEffect)(() => {
|
|
4361
|
+
const selectedIndex = Math.max(
|
|
4362
|
+
0,
|
|
4363
|
+
entries.findIndex((entry) => entry.id === selectedEntryId)
|
|
4364
|
+
);
|
|
4365
|
+
const nextState = createNormalizedSelection({ selectedIndex, itemCount: entries.length });
|
|
4366
|
+
stateRef.current = nextState;
|
|
4367
|
+
setState(nextState);
|
|
4368
|
+
}, [entries.length, selectedEntryId]);
|
|
4369
|
+
const normalized = createNormalizedSelection({
|
|
4370
|
+
selectedIndex: state.selectedIndex,
|
|
4371
|
+
scrollOffset: state.scrollOffset,
|
|
4372
|
+
itemCount: entries.length
|
|
4373
|
+
});
|
|
4374
|
+
if (normalized !== state) stateRef.current = normalized;
|
|
4375
|
+
return {
|
|
4376
|
+
normalized,
|
|
4377
|
+
visibleEntries: entries.slice(
|
|
4378
|
+
normalized.scrollOffset,
|
|
4379
|
+
normalized.scrollOffset + MAX_VISIBLE_WORKSPACE_ENTRIES
|
|
4380
|
+
),
|
|
4381
|
+
applyAction: createApplyAction({ entries, stateRef, setState, onSelect, onClose })
|
|
4382
|
+
};
|
|
4383
|
+
}
|
|
4384
|
+
function createApplyAction({
|
|
4385
|
+
entries,
|
|
4386
|
+
stateRef,
|
|
4387
|
+
setState,
|
|
4388
|
+
onSelect,
|
|
4389
|
+
onClose
|
|
4390
|
+
}) {
|
|
4391
|
+
return (action) => {
|
|
4392
|
+
const result = applySelectionInput(stateRef.current, action, {
|
|
4393
|
+
itemCount: entries.length,
|
|
4394
|
+
maxVisible: MAX_VISIBLE_WORKSPACE_ENTRIES
|
|
4395
|
+
});
|
|
4396
|
+
const nextState = result.effect.type === "select" || result.effect.type === "cancel" ? { ...result.state, resolved: false } : result.state;
|
|
4397
|
+
stateRef.current = nextState;
|
|
4398
|
+
setState(nextState);
|
|
4399
|
+
if (result.effect.type === "cancel") {
|
|
4400
|
+
onClose();
|
|
4401
|
+
} else if (result.effect.type === "select") {
|
|
4402
|
+
const entry = entries[result.effect.index];
|
|
4403
|
+
if (entry) onSelect(entry.id);
|
|
4404
|
+
}
|
|
4405
|
+
};
|
|
4406
|
+
}
|
|
4407
|
+
function createNormalizedSelection(input) {
|
|
4408
|
+
return normalizeSelectionState(
|
|
4409
|
+
{
|
|
4410
|
+
selectedIndex: input.selectedIndex,
|
|
4411
|
+
scrollOffset: input.scrollOffset ?? 0,
|
|
4412
|
+
resolved: false
|
|
4413
|
+
},
|
|
4414
|
+
{ itemCount: input.itemCount, maxVisible: MAX_VISIBLE_WORKSPACE_ENTRIES }
|
|
4415
|
+
);
|
|
4416
|
+
}
|
|
4417
|
+
function ExecutionWorkspaceSwitcherRow({
|
|
4418
|
+
entry,
|
|
4419
|
+
isFocused,
|
|
4420
|
+
selectedEntryId
|
|
4421
|
+
}) {
|
|
4422
|
+
const row = formatExecutionWorkspaceEntryRow(entry, { selectedEntryId });
|
|
4423
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_ink20.Text, { children: [
|
|
4424
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ink20.Text, { color: isFocused ? "cyan" : void 0, bold: isFocused, children: isFocused ? "> " : " " }),
|
|
4425
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ink20.Text, { color: row.color, children: row.radio }),
|
|
4426
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ink20.Text, { color: isFocused ? "cyan" : void 0, bold: isFocused, children: ` ${row.title}` }),
|
|
4427
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ink20.Text, { dimColor: true, children: ` \xB7 ${row.statusLabel}` }),
|
|
4428
|
+
row.subtitle ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ink20.Text, { dimColor: true, children: ` \xB7 ${row.subtitle}` }) : null,
|
|
4429
|
+
row.preview ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ink20.Text, { dimColor: true, children: ` \xB7 ${row.preview}` }) : null
|
|
4430
|
+
] });
|
|
4431
|
+
}
|
|
4432
|
+
|
|
4433
|
+
// src/ui/ExecutionWorkspaceDetailPane.tsx
|
|
4434
|
+
var import_ink21 = require("ink");
|
|
4435
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
4436
|
+
var MAX_VISIBLE_DETAIL_RECORDS = 12;
|
|
4437
|
+
function ExecutionWorkspaceDetailPane({
|
|
4438
|
+
entry,
|
|
4439
|
+
page,
|
|
4440
|
+
loading,
|
|
4441
|
+
error
|
|
4442
|
+
}) {
|
|
4443
|
+
const row = formatExecutionWorkspaceEntryRow(entry, { selectedEntryId: entry.id });
|
|
4444
|
+
const records = page?.records.slice(-MAX_VISIBLE_DETAIL_RECORDS) ?? [];
|
|
4445
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_ink21.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
4446
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_ink21.Text, { color: "cyan", bold: true, children: `Viewing ${row.title}` }),
|
|
4447
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_ink21.Text, { dimColor: true, children: [
|
|
4448
|
+
row.statusLabel,
|
|
4449
|
+
row.subtitle ? ` \xB7 ${row.subtitle}` : "",
|
|
4450
|
+
row.preview ? ` \xB7 ${row.preview}` : ""
|
|
4451
|
+
] }),
|
|
4452
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_ink21.Text, { dimColor: true, children: "Loading workspace detail..." }) : null,
|
|
4453
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_ink21.Text, { color: "red", children: error }) : null,
|
|
4454
|
+
!loading && !error && records.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_ink21.Text, { dimColor: true, children: "No detail yet" }) : null,
|
|
4455
|
+
!loading && !error && records.map((record) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_ink21.Text, { color: getDetailRecordColor(record.kind), children: formatExecutionDetailRecord(record) }, record.id)),
|
|
4456
|
+
page?.nextCursor ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_ink21.Text, { dimColor: true, children: "... more detail available" }) : null
|
|
4457
|
+
] });
|
|
4458
|
+
}
|
|
4459
|
+
function getDetailRecordColor(kind) {
|
|
4460
|
+
if (kind === "error") return "red";
|
|
4461
|
+
if (kind === "result") return "green";
|
|
4462
|
+
if (kind === "process_output") return "white";
|
|
4463
|
+
if (kind === "group_summary") return "cyan";
|
|
4464
|
+
return void 0;
|
|
4465
|
+
}
|
|
4466
|
+
|
|
4467
|
+
// src/ui/UpdateNotice.tsx
|
|
4468
|
+
var import_ink22 = require("ink");
|
|
4469
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
4292
4470
|
function UpdateNotice({ message }) {
|
|
4293
|
-
return /* @__PURE__ */ (0,
|
|
4471
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ink22.Box, { paddingX: 1, marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ink22.Text, { color: "yellow", children: message }) });
|
|
4294
4472
|
}
|
|
4295
4473
|
|
|
4296
4474
|
// src/utils/update-check.ts
|
|
@@ -4385,10 +4563,10 @@ function comparePrereleaseIdentifier(left, right) {
|
|
|
4385
4563
|
var CLI_UPDATE_PACKAGE_NAME = "@robota-sdk/agent-cli";
|
|
4386
4564
|
var CLI_UPDATE_REGISTRY_URL = "https://registry.npmjs.org";
|
|
4387
4565
|
var HOURS_PER_DAY = 24;
|
|
4388
|
-
var
|
|
4389
|
-
var
|
|
4390
|
-
var
|
|
4391
|
-
var CLI_UPDATE_CACHE_TTL_MS = HOURS_PER_DAY *
|
|
4566
|
+
var MINUTES_PER_HOUR = 60;
|
|
4567
|
+
var SECONDS_PER_MINUTE = 60;
|
|
4568
|
+
var MS_PER_SECOND = 1e3;
|
|
4569
|
+
var CLI_UPDATE_CACHE_TTL_MS = HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MS_PER_SECOND;
|
|
4392
4570
|
var CLI_UPDATE_TIMEOUT_MS = 1500;
|
|
4393
4571
|
var DEFAULT_INSTALL_COMMAND = "npm install -g '@robota-sdk/agent-cli@latest'";
|
|
4394
4572
|
function getUserUpdateCheckCachePath(home = process.env.HOME ?? process.env.USERPROFILE ?? "/") {
|
|
@@ -4557,13 +4735,13 @@ function isJsonObject(value) {
|
|
|
4557
4735
|
}
|
|
4558
4736
|
|
|
4559
4737
|
// src/ui/App.tsx
|
|
4560
|
-
var
|
|
4738
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
4561
4739
|
function App(props) {
|
|
4562
|
-
const [activeSessionId, setActiveSessionId] = (0,
|
|
4563
|
-
const [showInitialSessionPicker, setShowInitialSessionPicker] = (0,
|
|
4740
|
+
const [activeSessionId, setActiveSessionId] = (0, import_react20.useState)(props.resumeSessionId);
|
|
4741
|
+
const [showInitialSessionPicker, setShowInitialSessionPicker] = (0, import_react20.useState)(
|
|
4564
4742
|
props.showSessionPickerOnStart ?? false
|
|
4565
4743
|
);
|
|
4566
|
-
return /* @__PURE__ */ (0,
|
|
4744
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4567
4745
|
AppInner,
|
|
4568
4746
|
{
|
|
4569
4747
|
...props,
|
|
@@ -4591,7 +4769,10 @@ function AppInner(props) {
|
|
|
4591
4769
|
isAborting,
|
|
4592
4770
|
isShuttingDown,
|
|
4593
4771
|
pendingPrompt,
|
|
4594
|
-
|
|
4772
|
+
executionWorkspaceSnapshot,
|
|
4773
|
+
selectedExecutionEntryId,
|
|
4774
|
+
selectExecutionWorkspaceEntry,
|
|
4775
|
+
readExecutionWorkspaceDetail,
|
|
4595
4776
|
permissionRequest,
|
|
4596
4777
|
contextState,
|
|
4597
4778
|
handleSubmit: baseHandleSubmit,
|
|
@@ -4610,17 +4791,31 @@ function AppInner(props) {
|
|
|
4610
4791
|
backgroundTaskRunners: props.backgroundTaskRunners,
|
|
4611
4792
|
subagentRunnerFactory: props.subagentRunnerFactory,
|
|
4612
4793
|
commandModules: props.commandModules,
|
|
4613
|
-
commandHostAdapters: props.commandHostAdapters
|
|
4794
|
+
commandHostAdapters: props.commandHostAdapters,
|
|
4795
|
+
webPort: props.webPort,
|
|
4796
|
+
noOpen: props.noOpen
|
|
4614
4797
|
});
|
|
4615
4798
|
const fallbackPluginCallbacks = usePluginCallbacks(cwd);
|
|
4616
4799
|
const pluginCallbacks = props.commandHostAdapters?.plugin ?? fallbackPluginCallbacks;
|
|
4617
|
-
const { exit } = (0,
|
|
4618
|
-
const [sessionName, setSessionName] = (0,
|
|
4619
|
-
const [updateNotice, setUpdateNotice] = (0,
|
|
4800
|
+
const { exit } = (0, import_ink23.useApp)();
|
|
4801
|
+
const [sessionName, setSessionName] = (0, import_react20.useState)(props.sessionName);
|
|
4802
|
+
const [updateNotice, setUpdateNotice] = (0, import_react20.useState)();
|
|
4803
|
+
const [showExecutionWorkspaceSwitcher, setShowExecutionWorkspaceSwitcher] = (0, import_react20.useState)(false);
|
|
4804
|
+
const [executionDetailPage, setExecutionDetailPage] = (0, import_react20.useState)(null);
|
|
4805
|
+
const [executionDetailError, setExecutionDetailError] = (0, import_react20.useState)();
|
|
4806
|
+
const [isExecutionDetailLoading, setIsExecutionDetailLoading] = (0, import_react20.useState)(false);
|
|
4620
4807
|
const [statusLineSettings, setStatusLineSettings] = useStatusLineSettings();
|
|
4621
|
-
const
|
|
4622
|
-
(
|
|
4623
|
-
|
|
4808
|
+
const backgroundWorkspaceEntries = (0, import_react20.useMemo)(
|
|
4809
|
+
() => getDefaultBackgroundWorkspaceEntries(executionWorkspaceSnapshot),
|
|
4810
|
+
[executionWorkspaceSnapshot]
|
|
4811
|
+
);
|
|
4812
|
+
const activeBackgroundTaskCount = countActiveBackgroundWorkspaceEntries(
|
|
4813
|
+
executionWorkspaceSnapshot
|
|
4814
|
+
);
|
|
4815
|
+
const selectedExecutionEntry = (0, import_react20.useMemo)(
|
|
4816
|
+
() => executionWorkspaceSnapshot?.entries.find((entry) => entry.id === selectedExecutionEntryId),
|
|
4817
|
+
[executionWorkspaceSnapshot, selectedExecutionEntryId]
|
|
4818
|
+
);
|
|
4624
4819
|
const {
|
|
4625
4820
|
handleSubmit,
|
|
4626
4821
|
pendingModelId,
|
|
@@ -4643,11 +4838,11 @@ function AppInner(props) {
|
|
|
4643
4838
|
setStatusLineSettings,
|
|
4644
4839
|
showSessionPickerOnStart: props.showSessionPickerOnStart
|
|
4645
4840
|
});
|
|
4646
|
-
(0,
|
|
4841
|
+
(0, import_react20.useEffect)(() => {
|
|
4647
4842
|
const name = interactiveSession?.getName?.();
|
|
4648
4843
|
if (name && !sessionName) setSessionName(name);
|
|
4649
4844
|
}, [interactiveSession, sessionName]);
|
|
4650
|
-
(0,
|
|
4845
|
+
(0, import_react20.useEffect)(() => {
|
|
4651
4846
|
let isMounted = true;
|
|
4652
4847
|
props.startupUpdateNoticePromise?.then((notice) => {
|
|
4653
4848
|
if (isMounted && notice !== void 0) {
|
|
@@ -4659,20 +4854,27 @@ function AppInner(props) {
|
|
|
4659
4854
|
isMounted = false;
|
|
4660
4855
|
};
|
|
4661
4856
|
}, [props.startupUpdateNoticePromise]);
|
|
4662
|
-
(0,
|
|
4857
|
+
(0, import_react20.useEffect)(() => {
|
|
4663
4858
|
const title = sessionName ? `Robota \u2014 ${sessionName}` : "Robota";
|
|
4664
4859
|
process.stdout.write(`\x1B]0;${title}\x07`);
|
|
4665
4860
|
}, [sessionName]);
|
|
4666
|
-
(0,
|
|
4861
|
+
(0, import_ink23.useInput)((_input, key) => {
|
|
4667
4862
|
if (!key.escape || !isThinking) return;
|
|
4668
|
-
if (permissionRequest || showPluginTUI || showSessionPicker)
|
|
4863
|
+
if (permissionRequest || showPluginTUI || showSessionPicker || showExecutionWorkspaceSwitcher) {
|
|
4864
|
+
return;
|
|
4865
|
+
}
|
|
4669
4866
|
handleAbort();
|
|
4670
4867
|
});
|
|
4671
|
-
(0,
|
|
4868
|
+
(0, import_ink23.useInput)((input, key) => {
|
|
4869
|
+
if (!key.ctrl || input !== "b") return;
|
|
4870
|
+
if (permissionRequest || showPluginTUI || showSessionPicker || isShuttingDown) return;
|
|
4871
|
+
setShowExecutionWorkspaceSwitcher((shown) => !shown);
|
|
4872
|
+
});
|
|
4873
|
+
(0, import_ink23.useInput)((input, key) => {
|
|
4672
4874
|
if (!key.ctrl || input !== "c" || isShuttingDown) return;
|
|
4673
4875
|
void handleShutdown("prompt_input_exit").finally(() => exit());
|
|
4674
4876
|
});
|
|
4675
|
-
(0,
|
|
4877
|
+
(0, import_react20.useEffect)(() => {
|
|
4676
4878
|
const onSigterm = () => {
|
|
4677
4879
|
if (isShuttingDown) return;
|
|
4678
4880
|
void handleShutdown("other").finally(() => exit());
|
|
@@ -4684,6 +4886,29 @@ function AppInner(props) {
|
|
|
4684
4886
|
process.off("SIGTERM", onSigterm);
|
|
4685
4887
|
};
|
|
4686
4888
|
}, [handleShutdown, exit, isShuttingDown]);
|
|
4889
|
+
(0, import_react20.useEffect)(() => {
|
|
4890
|
+
if (!selectedExecutionEntry || selectedExecutionEntry.kind === "main_thread") {
|
|
4891
|
+
setExecutionDetailPage(null);
|
|
4892
|
+
setExecutionDetailError(void 0);
|
|
4893
|
+
setIsExecutionDetailLoading(false);
|
|
4894
|
+
return;
|
|
4895
|
+
}
|
|
4896
|
+
let isCurrent = true;
|
|
4897
|
+
setIsExecutionDetailLoading(true);
|
|
4898
|
+
setExecutionDetailError(void 0);
|
|
4899
|
+
readExecutionWorkspaceDetail(selectedExecutionEntry.id).then((page) => {
|
|
4900
|
+
if (!isCurrent) return;
|
|
4901
|
+
setExecutionDetailPage(page);
|
|
4902
|
+
setIsExecutionDetailLoading(false);
|
|
4903
|
+
}).catch((error) => {
|
|
4904
|
+
if (!isCurrent) return;
|
|
4905
|
+
setExecutionDetailError(error.message);
|
|
4906
|
+
setIsExecutionDetailLoading(false);
|
|
4907
|
+
});
|
|
4908
|
+
return () => {
|
|
4909
|
+
isCurrent = false;
|
|
4910
|
+
};
|
|
4911
|
+
}, [executionWorkspaceSnapshot, readExecutionWorkspaceDetail, selectedExecutionEntry]);
|
|
4687
4912
|
let permissionMode = props.permissionMode ?? "default";
|
|
4688
4913
|
let sessionId = "";
|
|
4689
4914
|
try {
|
|
@@ -4692,25 +4917,33 @@ function AppInner(props) {
|
|
|
4692
4917
|
sessionId = session.getSessionId();
|
|
4693
4918
|
} catch {
|
|
4694
4919
|
}
|
|
4695
|
-
return /* @__PURE__ */ (0,
|
|
4696
|
-
/* @__PURE__ */ (0,
|
|
4697
|
-
/* @__PURE__ */ (0,
|
|
4920
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_ink23.Box, { flexDirection: "column", children: [
|
|
4921
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_ink23.Box, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
|
|
4922
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ink23.Text, { color: "cyan", bold: true, children: `
|
|
4698
4923
|
____ ___ ____ ___ _____ _
|
|
4699
4924
|
| _ \\ / _ \\| __ ) / _ \\_ _|/ \\
|
|
4700
4925
|
| |_) | | | | _ \\| | | || | / _ \\
|
|
4701
4926
|
| _ <| |_| | |_) | |_| || |/ ___ \\
|
|
4702
4927
|
|_| \\_\\\\___/|____/ \\___/ |_/_/ \\_\\
|
|
4703
4928
|
` }),
|
|
4704
|
-
/* @__PURE__ */ (0,
|
|
4929
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_ink23.Text, { dimColor: true, children: [
|
|
4705
4930
|
" v",
|
|
4706
4931
|
props.version ?? "0.0.0"
|
|
4707
4932
|
] })
|
|
4708
4933
|
] }),
|
|
4709
|
-
updateNotice && /* @__PURE__ */ (0,
|
|
4710
|
-
/* @__PURE__ */ (0,
|
|
4711
|
-
/* @__PURE__ */ (0,
|
|
4712
|
-
|
|
4713
|
-
|
|
4934
|
+
updateNotice && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(UpdateNotice, { message: formatCliUpdateNotice(updateNotice) }),
|
|
4935
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_ink23.Box, { flexDirection: "column", paddingX: 1, flexGrow: 1, children: [
|
|
4936
|
+
selectedExecutionEntry && selectedExecutionEntry.kind !== "main_thread" ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4937
|
+
ExecutionWorkspaceDetailPane,
|
|
4938
|
+
{
|
|
4939
|
+
entry: selectedExecutionEntry,
|
|
4940
|
+
page: executionDetailPage,
|
|
4941
|
+
loading: isExecutionDetailLoading,
|
|
4942
|
+
error: executionDetailError
|
|
4943
|
+
}
|
|
4944
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(MessageList, { history }),
|
|
4945
|
+
isShuttingDown && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ink23.Box, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ink23.Text, { color: "yellow", children: "Shutting down..." }) }),
|
|
4946
|
+
(isThinking || activeTools.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ink23.Box, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4714
4947
|
StreamingIndicator,
|
|
4715
4948
|
{
|
|
4716
4949
|
text: streamingText,
|
|
@@ -4718,17 +4951,26 @@ function AppInner(props) {
|
|
|
4718
4951
|
isThinking
|
|
4719
4952
|
}
|
|
4720
4953
|
) }),
|
|
4721
|
-
/* @__PURE__ */ (0,
|
|
4954
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(BackgroundTaskPanel, { entries: backgroundWorkspaceEntries })
|
|
4722
4955
|
] }),
|
|
4723
|
-
|
|
4724
|
-
|
|
4956
|
+
showExecutionWorkspaceSwitcher && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4957
|
+
ExecutionWorkspaceSwitcher,
|
|
4958
|
+
{
|
|
4959
|
+
snapshot: executionWorkspaceSnapshot,
|
|
4960
|
+
selectedEntryId: selectedExecutionEntryId,
|
|
4961
|
+
onSelect: selectExecutionWorkspaceEntry,
|
|
4962
|
+
onClose: () => setShowExecutionWorkspaceSwitcher(false)
|
|
4963
|
+
}
|
|
4964
|
+
),
|
|
4965
|
+
permissionRequest && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PermissionPrompt, { request: permissionRequest }),
|
|
4966
|
+
pendingModelId && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4725
4967
|
ConfirmPrompt,
|
|
4726
4968
|
{
|
|
4727
4969
|
message: formatModelChangeConfirmationMessage(pendingModelId),
|
|
4728
4970
|
onSelect: handleModelConfirm
|
|
4729
4971
|
}
|
|
4730
4972
|
),
|
|
4731
|
-
pendingInteractionPrompt && /* @__PURE__ */ (0,
|
|
4973
|
+
pendingInteractionPrompt && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4732
4974
|
InteractivePrompt,
|
|
4733
4975
|
{
|
|
4734
4976
|
prompt: pendingInteractionPrompt,
|
|
@@ -4736,7 +4978,7 @@ function AppInner(props) {
|
|
|
4736
4978
|
onCancel: handleInteractionCancel
|
|
4737
4979
|
}
|
|
4738
4980
|
),
|
|
4739
|
-
showPluginTUI && /* @__PURE__ */ (0,
|
|
4981
|
+
showPluginTUI && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4740
4982
|
PluginTUI,
|
|
4741
4983
|
{
|
|
4742
4984
|
callbacks: pluginCallbacks,
|
|
@@ -4744,7 +4986,7 @@ function AppInner(props) {
|
|
|
4744
4986
|
addMessage: (msg) => addEntry((0, import_agent_core11.messageToHistoryEntry)((0, import_agent_core11.createSystemMessage)(msg.content)))
|
|
4745
4987
|
}
|
|
4746
4988
|
),
|
|
4747
|
-
showSessionPicker && /* @__PURE__ */ (0,
|
|
4989
|
+
showSessionPicker && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4748
4990
|
SessionPicker,
|
|
4749
4991
|
{
|
|
4750
4992
|
sessions: (0, import_agent_sdk9.listResumableSessionSummaries)(props.sessionStore, props.cwd),
|
|
@@ -4758,7 +5000,7 @@ function AppInner(props) {
|
|
|
4758
5000
|
}
|
|
4759
5001
|
}
|
|
4760
5002
|
),
|
|
4761
|
-
/* @__PURE__ */ (0,
|
|
5003
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4762
5004
|
SessionStatusBar,
|
|
4763
5005
|
{
|
|
4764
5006
|
cwd,
|
|
@@ -4776,12 +5018,12 @@ function AppInner(props) {
|
|
|
4776
5018
|
settings: statusLineSettings
|
|
4777
5019
|
}
|
|
4778
5020
|
),
|
|
4779
|
-
/* @__PURE__ */ (0,
|
|
5021
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4780
5022
|
InputArea,
|
|
4781
5023
|
{
|
|
4782
5024
|
onSubmit: handleSubmit,
|
|
4783
5025
|
onCancelQueue: handleCancelQueue,
|
|
4784
|
-
isDisabled: !!permissionRequest || showPluginTUI || showSessionPicker || isShuttingDown || pendingInteractionPrompt !== null || isThinking && !!pendingPrompt,
|
|
5026
|
+
isDisabled: !!permissionRequest || showPluginTUI || showSessionPicker || showExecutionWorkspaceSwitcher || isShuttingDown || pendingInteractionPrompt !== null || isThinking && !!pendingPrompt,
|
|
4785
5027
|
isAborting,
|
|
4786
5028
|
pendingPrompt,
|
|
4787
5029
|
registry,
|
|
@@ -4789,12 +5031,12 @@ function AppInner(props) {
|
|
|
4789
5031
|
history
|
|
4790
5032
|
}
|
|
4791
5033
|
),
|
|
4792
|
-
/* @__PURE__ */ (0,
|
|
5034
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ink23.Text, { children: " " })
|
|
4793
5035
|
] });
|
|
4794
5036
|
}
|
|
4795
5037
|
|
|
4796
5038
|
// src/ui/render.tsx
|
|
4797
|
-
var
|
|
5039
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
4798
5040
|
function renderApp(options) {
|
|
4799
5041
|
process.on("unhandledRejection", (reason) => {
|
|
4800
5042
|
process.stderr.write(`
|
|
@@ -4805,7 +5047,7 @@ function renderApp(options) {
|
|
|
4805
5047
|
`);
|
|
4806
5048
|
}
|
|
4807
5049
|
});
|
|
4808
|
-
const instance = (0,
|
|
5050
|
+
const instance = (0, import_ink24.render)(/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(App, { ...options }), {
|
|
4809
5051
|
exitOnCtrlC: false
|
|
4810
5052
|
});
|
|
4811
5053
|
instance.waitUntilExit().then(() => {
|
|
@@ -5449,6 +5691,29 @@ function readTranscriptLog(jobId, transcriptPath, cursor) {
|
|
|
5449
5691
|
return (0, import_agent_sdk14.createBackgroundTaskLogPage)(jobId, lines, cursor);
|
|
5450
5692
|
}
|
|
5451
5693
|
|
|
5694
|
+
// src/user-local-direct-command.ts
|
|
5695
|
+
var import_agent_command_user_local = require("@robota-sdk/agent-command-user-local");
|
|
5696
|
+
async function runUserLocalDirectCommandIfRequested(args, cwd) {
|
|
5697
|
+
if (args.positional[0] !== "user-local") {
|
|
5698
|
+
return false;
|
|
5699
|
+
}
|
|
5700
|
+
const result = await (0, import_agent_command_user_local.executeUserLocalDirectCommand)({
|
|
5701
|
+
cwd,
|
|
5702
|
+
argv: args.positional.slice(1),
|
|
5703
|
+
format: args.format,
|
|
5704
|
+
summary: args.summary,
|
|
5705
|
+
source: args.source
|
|
5706
|
+
});
|
|
5707
|
+
const output = result.message.endsWith("\n") ? result.message : `${result.message}
|
|
5708
|
+
`;
|
|
5709
|
+
if (!result.success) {
|
|
5710
|
+
process.stderr.write(output);
|
|
5711
|
+
process.exit(1);
|
|
5712
|
+
}
|
|
5713
|
+
process.stdout.write(output);
|
|
5714
|
+
return true;
|
|
5715
|
+
}
|
|
5716
|
+
|
|
5452
5717
|
// src/cli.ts
|
|
5453
5718
|
var import_meta = {};
|
|
5454
5719
|
function readVersion() {
|
|
@@ -5472,11 +5737,19 @@ function readVersion() {
|
|
|
5472
5737
|
}
|
|
5473
5738
|
}
|
|
5474
5739
|
function promptInput(label, masked = false) {
|
|
5475
|
-
return new Promise((resolve3) => {
|
|
5740
|
+
return new Promise((resolve3, reject) => {
|
|
5476
5741
|
process.stdout.write(label);
|
|
5477
5742
|
let input = "";
|
|
5478
5743
|
const stdin = process.stdin;
|
|
5479
5744
|
const wasRaw = stdin.isRaw;
|
|
5745
|
+
if (!stdin.isTTY) {
|
|
5746
|
+
reject(
|
|
5747
|
+
new Error(
|
|
5748
|
+
"Cannot prompt for input: stdin is not a TTY.\nSet your API key via environment variable instead:\n ANTHROPIC_API_KEY=<key> robota\n OPENAI_API_KEY=<key> robota"
|
|
5749
|
+
)
|
|
5750
|
+
);
|
|
5751
|
+
return;
|
|
5752
|
+
}
|
|
5480
5753
|
stdin.setRawMode(true);
|
|
5481
5754
|
stdin.resume();
|
|
5482
5755
|
stdin.setEncoding("utf8");
|
|
@@ -5542,6 +5815,7 @@ function createDefaultCliCommandModules({
|
|
|
5542
5815
|
(0, import_agent_command_language.createLanguageCommandModule)(),
|
|
5543
5816
|
(0, import_agent_command_background.createBackgroundCommandModule)(),
|
|
5544
5817
|
(0, import_agent_command_memory.createMemoryCommandModule)(),
|
|
5818
|
+
(0, import_agent_command_user_local2.createUserLocalCommandModule)(),
|
|
5545
5819
|
(0, import_agent_command_compact.createCompactCommandModule)(),
|
|
5546
5820
|
(0, import_agent_command_context.createContextCommandModule)(),
|
|
5547
5821
|
(0, import_agent_command_exit.createExitCommandModule)(),
|
|
@@ -5585,6 +5859,9 @@ async function startCli(options = {}) {
|
|
|
5585
5859
|
return;
|
|
5586
5860
|
}
|
|
5587
5861
|
const cwd = process.cwd();
|
|
5862
|
+
if (await runUserLocalDirectCommandIfRequested(args, cwd)) {
|
|
5863
|
+
return;
|
|
5864
|
+
}
|
|
5588
5865
|
const commandHostAdapters = {
|
|
5589
5866
|
settings: {
|
|
5590
5867
|
read: () => readSettings(getUserSettingsPath()),
|
|
@@ -5671,6 +5948,9 @@ async function startCli(options = {}) {
|
|
|
5671
5948
|
${args.jsonSchema}`
|
|
5672
5949
|
);
|
|
5673
5950
|
const appendSystemPrompt = appendParts.length > 0 ? appendParts.join("\n\n") : void 0;
|
|
5951
|
+
if (args.systemPrompt) {
|
|
5952
|
+
process.stderr.write("Warning: --system-prompt is not yet functional and will be ignored.\n");
|
|
5953
|
+
}
|
|
5674
5954
|
const session = new import_agent_sdk15.InteractiveSession({
|
|
5675
5955
|
cwd,
|
|
5676
5956
|
provider,
|
|
@@ -5715,7 +5995,9 @@ ${args.jsonSchema}`
|
|
|
5715
5995
|
subagentRunnerFactory,
|
|
5716
5996
|
commandModules,
|
|
5717
5997
|
commandHostAdapters,
|
|
5718
|
-
startupUpdateNoticePromise
|
|
5998
|
+
startupUpdateNoticePromise,
|
|
5999
|
+
webPort: args.web ? args.webPort : void 0,
|
|
6000
|
+
noOpen: args.noOpen
|
|
5719
6001
|
});
|
|
5720
6002
|
}
|
|
5721
6003
|
// Annotate the CommonJS export names for ESM import in node:
|