@agent-api/cli 0.4.27 → 0.4.29
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/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +1 -1
- package/dist/tui/ink/app.js +27 -2
- package/dist/tui/ink/components.js +2 -2
- package/package.json +1 -1
package/dist/runtime.d.ts
CHANGED
package/dist/runtime.js
CHANGED
package/dist/tui/ink/app.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
3
|
-
import { useApp, useInput, useStdout } from "ink";
|
|
3
|
+
import { useApp, useInput, useStdin, useStdout } from "ink";
|
|
4
4
|
import { createAgentEngine, defaultBaseURL, } from "@agent-api/app-engine/core";
|
|
5
5
|
import { createWorkbenchAuthController, createWorkbenchAuthGateController, parseWorkbenchCommand, } from "@agent-api/app-engine/workbench";
|
|
6
6
|
import { buildWorkbenchRenderModel, copyTextFromActivitySelection, copyTextFromHeaderSelection, copyTextFromRenderModel, copyTextFromTranscriptSelection, createWorkbenchTerminalController, initialWorkbenchTerminalState, normalizeTerminalState, selectedPanelRange, } from "@agent-api/app-engine/terminal";
|
|
@@ -132,6 +132,7 @@ function isAuthInputStatus(status) {
|
|
|
132
132
|
function WorkbenchApp({ authController, onLogin, onLogout, onDeleteProfile, onSwitchProfile, options, profileName, }) {
|
|
133
133
|
const app = useApp();
|
|
134
134
|
const { stdout } = useStdout();
|
|
135
|
+
const lastRawInputRef = useLastRawInputRef();
|
|
135
136
|
const terminalSize = useTerminalSize(stdout);
|
|
136
137
|
const [clipboardCapabilities, setClipboardCapabilities] = useState(null);
|
|
137
138
|
const [terminalState, setTerminalState] = useState(() => initialWorkbenchTerminalState());
|
|
@@ -301,7 +302,8 @@ function WorkbenchApp({ authController, onLogin, onLogout, onDeleteProfile, onSw
|
|
|
301
302
|
setTerminalState(result.state);
|
|
302
303
|
return;
|
|
303
304
|
}
|
|
304
|
-
const
|
|
305
|
+
const normalizedKey = normalizeInkTerminalKey(key, lastRawInputRef.current);
|
|
306
|
+
const result = terminalController.handle(input, normalizedKey, terminalState, {
|
|
305
307
|
busy: state.busy,
|
|
306
308
|
renderModel,
|
|
307
309
|
});
|
|
@@ -391,6 +393,29 @@ function useTerminalSize(stdout) {
|
|
|
391
393
|
}, [stdout]);
|
|
392
394
|
return size;
|
|
393
395
|
}
|
|
396
|
+
function useLastRawInputRef() {
|
|
397
|
+
const { internal_eventEmitter } = useStdin();
|
|
398
|
+
const lastRawInputRef = useRef("");
|
|
399
|
+
useEffect(() => {
|
|
400
|
+
const recordRawInput = (data) => {
|
|
401
|
+
lastRawInputRef.current = Buffer.isBuffer(data) ? data.toString("utf8") : String(data);
|
|
402
|
+
};
|
|
403
|
+
internal_eventEmitter?.on("input", recordRawInput);
|
|
404
|
+
return () => {
|
|
405
|
+
internal_eventEmitter?.removeListener("input", recordRawInput);
|
|
406
|
+
};
|
|
407
|
+
}, [internal_eventEmitter]);
|
|
408
|
+
return lastRawInputRef;
|
|
409
|
+
}
|
|
410
|
+
function normalizeInkTerminalKey(key, rawInput) {
|
|
411
|
+
if (key.delete && !key.backspace && isRawBackspace(rawInput)) {
|
|
412
|
+
return { ...key, backspace: true, delete: false };
|
|
413
|
+
}
|
|
414
|
+
return key;
|
|
415
|
+
}
|
|
416
|
+
function isRawBackspace(rawInput) {
|
|
417
|
+
return rawInput === "\x7f" || rawInput === "\x1b\x7f";
|
|
418
|
+
}
|
|
394
419
|
function userFacingError(error) {
|
|
395
420
|
if (error instanceof Error)
|
|
396
421
|
return error.message;
|
|
@@ -3,12 +3,12 @@ import { Box, Text } from "ink";
|
|
|
3
3
|
import { activityColor, busySpinner, } from "@agent-api/app-engine/terminal";
|
|
4
4
|
import { authMethods, } from "@agent-api/app-engine/workbench";
|
|
5
5
|
export function InkWorkbenchScreen({ activityCursor, activitySelection, focusedPanel, headerCursor, headerSelection, renderModel, spinnerFrame, transcriptCursor, transcriptSelection, }) {
|
|
6
|
-
const activity = (_jsxs(Box, { borderColor: panelBorderColor(focusedPanel === "activity"), borderStyle: "round", flexDirection: "column", height: renderModel.activityHeight, marginLeft: renderModel.layout === "wide" ? 1 : 0, paddingX: 1, width: renderModel.layout === "wide" ? "27%" : "100%", children: [_jsx(Text, { bold: true, color: focusedPanel === "activity" ? "cyan" : undefined, wrap: "truncate", children: "Activity" }), renderModel.visibleActivities.map((activity, index) => {
|
|
6
|
+
const activity = (_jsxs(Box, { borderColor: panelBorderColor(focusedPanel === "activity"), borderStyle: "round", flexShrink: 0, flexDirection: "column", height: renderModel.activityHeight, marginLeft: renderModel.layout === "wide" ? 1 : 0, paddingX: 1, width: renderModel.layout === "wide" ? "27%" : "100%", children: [_jsx(Text, { bold: true, color: focusedPanel === "activity" ? "cyan" : undefined, wrap: "truncate", children: "Activity" }), renderModel.visibleActivities.map((activity, index) => {
|
|
7
7
|
const cursor = focusedPanel === "activity" && index === activityCursor.line;
|
|
8
8
|
const text = `${new Date(activity.timestamp).toLocaleTimeString()} ${activity.text}`;
|
|
9
9
|
return (_jsxs(Text, { color: activityColor(activity.level), wrap: "truncate", children: [cursor ? _jsx(Text, { color: "cyan", children: "\u203A " }) : _jsx(Text, { children: " " }), _jsx(SelectableText, { cursorColumn: cursor && !activitySelection ? activityCursor.column : null, selection: lineSelection(index, activitySelection), text: text || " " })] }, activity.id));
|
|
10
10
|
})] }));
|
|
11
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { focused: focusedPanel === "header", cursor: headerCursor, selection: headerSelection, contextEnabled: renderModel.header.contextEnabled, conversation: renderModel.header.conversation, conversationId: renderModel.header.conversationId, conversationPreviousResponseId: renderModel.header.conversationPreviousResponseId, conversationStatus: renderModel.header.conversationStatus, lines: renderModel.header.lines, model: renderModel.header.model, accessMode: renderModel.header.accessMode, pendingLocalLabel: renderModel.header.pendingLocalLabel, preset: renderModel.header.preset, profile: renderModel.header.profile, renderMode: renderModel.header.renderMode, workdir: renderModel.header.workdir }), _jsxs(Box, { height: renderModel.viewportHeight, flexDirection: renderModel.layout === "wide" ? "row" : "column", children: [_jsxs(Box, { borderStyle: "round", borderColor: panelBorderColor(focusedPanel === "transcript"), flexDirection: "column", height: renderModel.transcript.viewportHeight + 2, paddingX: 1, width: renderModel.layout === "wide" ?
|
|
11
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { focused: focusedPanel === "header", cursor: headerCursor, selection: headerSelection, contextEnabled: renderModel.header.contextEnabled, conversation: renderModel.header.conversation, conversationId: renderModel.header.conversationId, conversationPreviousResponseId: renderModel.header.conversationPreviousResponseId, conversationStatus: renderModel.header.conversationStatus, lines: renderModel.header.lines, model: renderModel.header.model, accessMode: renderModel.header.accessMode, pendingLocalLabel: renderModel.header.pendingLocalLabel, preset: renderModel.header.preset, profile: renderModel.header.profile, renderMode: renderModel.header.renderMode, workdir: renderModel.header.workdir }), _jsxs(Box, { height: renderModel.viewportHeight, flexDirection: renderModel.layout === "wide" ? "row" : "column", children: [_jsxs(Box, { borderStyle: "round", borderColor: panelBorderColor(focusedPanel === "transcript"), flexGrow: renderModel.layout === "wide" ? 1 : 0, flexDirection: "column", height: renderModel.transcript.viewportHeight + 2, paddingX: 1, width: renderModel.layout === "wide" ? undefined : "100%", children: [renderModel.transcript.visibleLines.map((line, index) => (_jsx(TranscriptText, { cursorColumn: focusedPanel === "transcript" && renderModel.transcript.startLine + index - 1 === transcriptCursor.line && !transcriptSelection
|
|
12
12
|
? transcriptCursor.column
|
|
13
13
|
: null, line: line, lineSelection: lineSelection(renderModel.transcript.startLine + index - 1, transcriptSelection), lineCursor: focusedPanel === "transcript" && renderModel.transcript.startLine + index - 1 === transcriptCursor.line }, line.id))), renderModel.transcript.visibleLines.length === 0 && _jsx(Text, { color: "gray", children: "No transcript lines." })] }), activity] }), _jsxs(Box, { borderStyle: "round", borderColor: panelBorderColor(focusedPanel === "input"), paddingX: 1, flexDirection: "column", children: [_jsxs(Box, { children: [renderModel.input.fullAccess && (_jsx(Text, { color: "red", bold: true, inverse: true, children: "FULL ACCESS" })), renderModel.input.fullAccess && _jsx(Text, { children: " " }), _jsx(Text, { color: renderModel.input.busy ? "yellow" : "green", children: renderModel.input.label }), renderModel.input.statusText && (_jsxs(Text, { color: "yellow", children: [" ", busySpinner(spinnerFrame), " ", renderModel.input.statusText] }))] }), _jsx(Box, { flexDirection: "column", children: renderModel.input.lines.map((line, index) => (_jsx(Text, { wrap: "truncate", children: line.spans.map((span, spanIndex) => (_jsx(Text, { inverse: span.inverse, children: span.text }, spanIndex))) }, index))) })] }), _jsx(Box, { paddingX: 1, children: _jsx(Text, { color: "gray", wrap: "truncate", children: renderModel.footerText }) })] }));
|
|
14
14
|
}
|