@agent-api/cli 0.3.3 → 0.3.4
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 +6 -1
- package/dist/tui/ink/components.js +3 -3
- package/package.json +2 -2
package/dist/runtime.d.ts
CHANGED
package/dist/runtime.js
CHANGED
package/dist/tui/ink/app.js
CHANGED
|
@@ -106,6 +106,7 @@ function WorkbenchApp({ authController, onLogin, onLogout, onDeleteProfile, onSw
|
|
|
106
106
|
const app = useApp();
|
|
107
107
|
const { stdout } = useStdout();
|
|
108
108
|
const [draft, setDraft] = useState("");
|
|
109
|
+
const [cursor, setCursor] = useState(0);
|
|
109
110
|
const [spinnerFrame, setSpinnerFrame] = useState(0);
|
|
110
111
|
const [transcriptOffset, setTranscriptOffset] = useState(0);
|
|
111
112
|
const agentEngineRef = useRef(null);
|
|
@@ -128,6 +129,7 @@ function WorkbenchApp({ authController, onLogin, onLogout, onDeleteProfile, onSw
|
|
|
128
129
|
const dispatch = agentEngine.dispatch;
|
|
129
130
|
const renderModel = useMemo(() => buildWorkbenchRenderModel({
|
|
130
131
|
draft,
|
|
132
|
+
cursor,
|
|
131
133
|
profileName,
|
|
132
134
|
spinnerFrame,
|
|
133
135
|
state,
|
|
@@ -137,7 +139,7 @@ function WorkbenchApp({ authController, onLogin, onLogout, onDeleteProfile, onSw
|
|
|
137
139
|
columns: stdout.columns || process.stdout.columns,
|
|
138
140
|
},
|
|
139
141
|
workdirFallback: options.workdir || process.cwd(),
|
|
140
|
-
}), [draft, options.workdir, profileName, spinnerFrame, state, stdout.columns, stdout.rows, transcriptOffset]);
|
|
142
|
+
}), [cursor, draft, options.workdir, profileName, spinnerFrame, state, stdout.columns, stdout.rows, transcriptOffset]);
|
|
141
143
|
useEffect(() => {
|
|
142
144
|
setTranscriptOffset((offset) => Math.min(offset, renderModel.transcript.maxOffset));
|
|
143
145
|
}, [renderModel.transcript.maxOffset]);
|
|
@@ -185,11 +187,14 @@ function WorkbenchApp({ authController, onLogin, onLogout, onDeleteProfile, onSw
|
|
|
185
187
|
useInput((input, key) => {
|
|
186
188
|
const result = inputController.handle(input, key, {
|
|
187
189
|
busy: state.busy,
|
|
190
|
+
cursor,
|
|
188
191
|
draft,
|
|
189
192
|
viewportHeight: renderModel.viewportHeight,
|
|
190
193
|
});
|
|
191
194
|
if (result.draft !== draft)
|
|
192
195
|
setDraft(result.draft);
|
|
196
|
+
if (result.cursor !== cursor)
|
|
197
|
+
setCursor(result.cursor);
|
|
193
198
|
for (const effect of result.effects) {
|
|
194
199
|
switch (effect.type) {
|
|
195
200
|
case "exit":
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Box, Text } from "ink";
|
|
3
3
|
import { activityColor, authMethods, busySpinner, } from "@agent-api/app-engine";
|
|
4
4
|
export function InkWorkbenchScreen({ renderModel, spinnerFrame, }) {
|
|
5
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { contextEnabled: renderModel.header.contextEnabled, conversation: renderModel.header.conversation, conversationId: renderModel.header.conversationId, conversationPreviousResponseId: renderModel.header.conversationPreviousResponseId, conversationStatus: renderModel.header.conversationStatus, 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, { marginTop: 1, height: renderModel.viewportHeight, children: [_jsxs(Box, { flexDirection: "column", width: "72%", paddingRight: 1, children: [renderModel.transcript.visibleLines.map((line) => (_jsx(Text, { bold: line.bold, color: line.color, inverse: line.inverse, wrap: "truncate", children: line.text || " " }, line.id))), renderModel.transcript.visibleLines.length === 0 && _jsx(Text, { color: "gray", children: "No transcript lines." })] }), _jsxs(Box, { flexDirection: "column", width: "28%", height: renderModel.activityHeight, borderStyle: "single", borderColor: "gray", paddingX: 1, children: [_jsx(Text, { bold: true, wrap: "truncate", children: "Activity" }), renderModel.visibleActivities.map((activity) => (_jsxs(Text, { color: activityColor(activity.level), wrap: "truncate", children: [new Date(activity.timestamp).toLocaleTimeString(), " ", activity.text] }, activity.id)))] })] }), _jsxs(Box, { borderStyle: "single", borderColor: renderModel.input.busy ? "yellow" : "green", paddingX: 1, children: [renderModel.input.fullAccess && (_jsx(Text, { color: "red", bold: true, inverse: true, children: "FULL ACCESS" })), renderModel.input.fullAccess && _jsx(Text, { children: " " }), _jsxs(Text, { color: renderModel.input.busy ? "yellow" : "green", children: [renderModel.input.label, " "] }), renderModel.input.busy ? (_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { color: "yellow", children: busySpinner(spinnerFrame) }), " ", renderModel.input.waitingText] })) : (_jsxs(Text, { wrap: "truncate", children: [renderModel.input.
|
|
5
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { contextEnabled: renderModel.header.contextEnabled, conversation: renderModel.header.conversation, conversationId: renderModel.header.conversationId, conversationPreviousResponseId: renderModel.header.conversationPreviousResponseId, conversationStatus: renderModel.header.conversationStatus, 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, { marginTop: 1, height: renderModel.viewportHeight, children: [_jsxs(Box, { flexDirection: "column", width: "72%", paddingRight: 1, children: [renderModel.transcript.visibleLines.map((line) => (_jsx(Text, { bold: line.bold, color: line.color, inverse: line.inverse, wrap: "truncate", children: line.text || " " }, line.id))), renderModel.transcript.visibleLines.length === 0 && _jsx(Text, { color: "gray", children: "No transcript lines." })] }), _jsxs(Box, { flexDirection: "column", width: "28%", height: renderModel.activityHeight, borderStyle: "single", borderColor: "gray", paddingX: 1, children: [_jsx(Text, { bold: true, wrap: "truncate", children: "Activity" }), renderModel.visibleActivities.map((activity) => (_jsxs(Text, { color: activityColor(activity.level), wrap: "truncate", children: [new Date(activity.timestamp).toLocaleTimeString(), " ", activity.text] }, activity.id)))] })] }), _jsxs(Box, { borderStyle: "single", borderColor: renderModel.input.busy ? "yellow" : "green", paddingX: 1, children: [renderModel.input.fullAccess && (_jsx(Text, { color: "red", bold: true, inverse: true, children: "FULL ACCESS" })), renderModel.input.fullAccess && _jsx(Text, { children: " " }), _jsxs(Text, { color: renderModel.input.busy ? "yellow" : "green", children: [renderModel.input.label, " "] }), renderModel.input.busy ? (_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { color: "yellow", children: busySpinner(spinnerFrame) }), " ", renderModel.input.waitingText] })) : (_jsxs(Text, { wrap: "truncate", children: [renderModel.input.beforeCursor, _jsx(Cursor, { text: renderModel.input.cursorText, visible: true }), renderModel.input.afterCursor] }))] }), _jsx(Box, { paddingX: 1, children: _jsx(Text, { color: "gray", wrap: "truncate", children: renderModel.footerText }) })] }));
|
|
6
6
|
}
|
|
7
7
|
export function InkAuthGate({ cursorVisible, state }) {
|
|
8
8
|
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { borderStyle: "round", borderColor: "cyan", paddingX: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Agent API Workbench" }), _jsx(Text, { color: "gray", children: "Authentication required before starting the conversation UI." })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: state.error ? "red" : "gray", children: state.error || state.message }), state.status === "checking" && _jsx(Text, { color: "yellow", children: "Checking..." }), state.status === "select" && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [authMethods.map((method, index) => (_jsxs(Text, { color: index === state.selectedMethod ? "green" : "gray", children: [index === state.selectedMethod ? "›" : " ", " ", method.label, " - ", method.description] }, method.method))), _jsx(Text, { color: "gray", children: "Use \u2191/\u2193 and Enter." })] })), state.status === "api_profile" && _jsx(AuthPrompt, { cursorVisible: cursorVisible, label: "Profile", value: state.profile }), state.status === "api_base_url" && _jsx(AuthPrompt, { cursorVisible: cursorVisible, label: "Base URL", value: state.baseURL }), state.status === "api_key" && _jsx(AuthPrompt, { cursorVisible: cursorVisible, label: "API key", value: state.apiKey ? "•".repeat(Math.min(state.apiKey.length, 32)) : "" }), state.status === "browser_profile" && _jsx(AuthPrompt, { cursorVisible: cursorVisible, label: "Profile", value: state.profile }), state.status === "browser_base_url" && _jsx(AuthPrompt, { cursorVisible: cursorVisible, label: "Base URL", value: state.baseURL }), state.status === "browser_waiting" && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [state.browserURL && _jsxs(Text, { children: ["URL: ", state.browserURL] }), state.browserCode && _jsxs(Text, { children: ["Code: ", state.browserCode] }), _jsx(Text, { color: "yellow", children: "Waiting for browser approval..." })] }))] })] }));
|
|
@@ -13,6 +13,6 @@ function AuthPrompt({ cursorVisible, label, value }) {
|
|
|
13
13
|
function Header({ contextEnabled, conversation, conversationId, conversationPreviousResponseId, conversationStatus, accessMode, model, pendingLocalLabel, preset, profile, renderMode, workdir, }) {
|
|
14
14
|
return (_jsxs(Box, { borderStyle: "round", borderColor: "cyan", paddingX: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Agent API Workbench" }), _jsxs(Text, { color: "gray", wrap: "truncate", children: ["profile=", profile, " conversation=", conversation, " id=", conversationId, " preset=", preset, " model=", model] }), _jsxs(Text, { color: conversationStatus === "continued" ? "yellow" : conversationStatus === "fresh" ? "green" : "gray", wrap: "truncate", children: ["conversation_state=", conversationStatus, conversationPreviousResponseId ? ` previous=${conversationPreviousResponseId}` : ""] }), _jsxs(Text, { color: "gray", wrap: "truncate", children: ["workdir=", workdir, " access=", accessMode, " local_tools=", contextEnabled ? "on" : "off", " render=", renderMode, " pending=", pendingLocalLabel] })] }));
|
|
15
15
|
}
|
|
16
|
-
function Cursor({ visible }) {
|
|
17
|
-
return visible ? _jsx(Text, { inverse: true, children:
|
|
16
|
+
function Cursor({ text = " ", visible }) {
|
|
17
|
+
return visible ? _jsx(Text, { inverse: true, children: text }) : _jsx(Text, { children: text });
|
|
18
18
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-api/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "First-class command line interface for Agent API",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/scalebox-dev/agent-tui#readme",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"test": "npm run sync-version && npm run build && npm run smoke -w @agent-api/app-engine && node --test test/*.test.mjs"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@agent-api/app-engine": "^0.0.
|
|
38
|
+
"@agent-api/app-engine": "^0.0.5",
|
|
39
39
|
"commander": "^14.0.3",
|
|
40
40
|
"ink": "^6.8.0",
|
|
41
41
|
"react": "^19.2.7"
|