@agent-api/cli 0.2.1 → 0.3.0

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.
Files changed (61) hide show
  1. package/README.md +11 -5
  2. package/dist/index.js +8 -6
  3. package/dist/runtime.d.ts +4 -0
  4. package/dist/runtime.js +4 -0
  5. package/dist/tui/ink/app.d.ts +1 -1
  6. package/dist/tui/ink/app.js +27 -130
  7. package/dist/tui/ink/components.d.ts +1 -2
  8. package/dist/tui/ink/components.js +1 -3
  9. package/package.json +9 -6
  10. package/dist/agent/runner.d.ts +0 -117
  11. package/dist/agent/runner.js +0 -486
  12. package/dist/agent.d.ts +0 -2
  13. package/dist/agent.js +0 -2
  14. package/dist/chat-options.d.ts +0 -37
  15. package/dist/chat-options.js +0 -42
  16. package/dist/config.d.ts +0 -66
  17. package/dist/config.js +0 -201
  18. package/dist/conversation/index.d.ts +0 -17
  19. package/dist/conversation/index.js +0 -54
  20. package/dist/profile.d.ts +0 -57
  21. package/dist/profile.js +0 -211
  22. package/dist/runtime/index.d.ts +0 -5
  23. package/dist/runtime/index.js +0 -152
  24. package/dist/tui/workbench.d.ts +0 -187
  25. package/dist/tui/workbench.js +0 -392
  26. package/dist/update.d.ts +0 -16
  27. package/dist/update.js +0 -74
  28. package/dist/workbench/auth-controller.d.ts +0 -43
  29. package/dist/workbench/auth-controller.js +0 -84
  30. package/dist/workbench/auth-gate-controller.d.ts +0 -62
  31. package/dist/workbench/auth-gate-controller.js +0 -231
  32. package/dist/workbench/command-controller.d.ts +0 -29
  33. package/dist/workbench/command-controller.js +0 -426
  34. package/dist/workbench/conversation-controller.d.ts +0 -32
  35. package/dist/workbench/conversation-controller.js +0 -53
  36. package/dist/workbench/engine.d.ts +0 -66
  37. package/dist/workbench/engine.js +0 -291
  38. package/dist/workbench/input-controller.d.ts +0 -44
  39. package/dist/workbench/input-controller.js +0 -71
  40. package/dist/workbench/isolator-installer.d.ts +0 -29
  41. package/dist/workbench/isolator-installer.js +0 -208
  42. package/dist/workbench/lifecycle-controller.d.ts +0 -30
  43. package/dist/workbench/lifecycle-controller.js +0 -75
  44. package/dist/workbench/local-controller.d.ts +0 -21
  45. package/dist/workbench/local-controller.js +0 -94
  46. package/dist/workbench/render-model.d.ts +0 -46
  47. package/dist/workbench/render-model.js +0 -61
  48. package/dist/workbench/runtime-controller.d.ts +0 -12
  49. package/dist/workbench/runtime-controller.js +0 -57
  50. package/dist/workbench/session.d.ts +0 -27
  51. package/dist/workbench/session.js +0 -42
  52. package/dist/workbench/settings-controller.d.ts +0 -80
  53. package/dist/workbench/settings-controller.js +0 -309
  54. package/dist/workbench/shell-isolation.d.ts +0 -20
  55. package/dist/workbench/shell-isolation.js +0 -13
  56. package/dist/workbench/turn-controller.d.ts +0 -25
  57. package/dist/workbench/turn-controller.js +0 -164
  58. package/dist/workbench/view-model.d.ts +0 -34
  59. package/dist/workbench/view-model.js +0 -121
  60. package/dist/workdir/index.d.ts +0 -22
  61. package/dist/workdir/index.js +0 -46
@@ -1,32 +0,0 @@
1
- import { mkdir, writeFile } from "node:fs/promises";
2
- import { deleteConversation, listConversations } from "../agent.js";
3
- export interface WorkbenchConversationController {
4
- startNewConversation(name: string | undefined, profileName?: string): Promise<{
5
- name: string;
6
- message: string;
7
- }>;
8
- switchConversation(name: string): {
9
- name: string;
10
- message: string;
11
- };
12
- listConversations(profileName?: string): Promise<string>;
13
- exportTranscript(input: {
14
- path?: string;
15
- transcript: string;
16
- conversation: string;
17
- }): Promise<string>;
18
- }
19
- export interface WorkbenchConversationControllerOptions {
20
- deleteConversationImpl?: typeof deleteConversation;
21
- listConversationsImpl?: typeof listConversations;
22
- mkdirImpl?: typeof mkdir;
23
- writeFileImpl?: typeof writeFile;
24
- now?: () => Date;
25
- dataDir?: string;
26
- }
27
- export declare function createWorkbenchConversationController(options?: WorkbenchConversationControllerOptions): WorkbenchConversationController;
28
- export declare function defaultTranscriptExportPath(conversation: string, options?: {
29
- dataDir?: string;
30
- now?: () => Date;
31
- }): string;
32
- export declare function createConversationName(now?: Date): string;
@@ -1,53 +0,0 @@
1
- import { mkdir, writeFile } from "node:fs/promises";
2
- import path from "node:path";
3
- import { conversationSummary, deleteConversation, listConversations, } from "../agent.js";
4
- import { runtime } from "../runtime/index.js";
5
- export function createWorkbenchConversationController(options = {}) {
6
- const deleteConversationImpl = options.deleteConversationImpl ?? deleteConversation;
7
- const listConversationsImpl = options.listConversationsImpl ?? listConversations;
8
- const mkdirImpl = options.mkdirImpl ?? mkdir;
9
- const writeFileImpl = options.writeFileImpl ?? writeFile;
10
- const now = options.now ?? (() => new Date());
11
- return {
12
- async startNewConversation(name, profileName) {
13
- const conversation = name || createConversationName(now());
14
- await deleteConversationImpl(conversation, profileName);
15
- return {
16
- name: conversation,
17
- message: `Started fresh conversation "${conversation}".`,
18
- };
19
- },
20
- switchConversation(name) {
21
- return {
22
- name,
23
- message: `Switched to conversation "${name}". Future turns will continue this handle when history exists.`,
24
- };
25
- },
26
- async listConversations(profileName) {
27
- const conversations = await listConversationsImpl(profileName);
28
- return conversations.length === 0
29
- ? "No saved conversations yet."
30
- : conversations.map(conversationSummary).join("\n");
31
- },
32
- async exportTranscript(input) {
33
- const file = input.path?.trim()
34
- ? path.resolve(process.cwd(), input.path.trim())
35
- : defaultTranscriptExportPath(input.conversation, {
36
- dataDir: options.dataDir,
37
- now,
38
- });
39
- await mkdirImpl(path.dirname(file), { recursive: true });
40
- await writeFileImpl(file, input.transcript, "utf8");
41
- return file;
42
- },
43
- };
44
- }
45
- export function defaultTranscriptExportPath(conversation, options = {}) {
46
- const safeConversation = conversation.replace(/[^a-z0-9._-]+/gi, "-").replace(/^-+|-+$/g, "") || "conversation";
47
- const stamp = (options.now?.() ?? new Date()).toISOString().replace(/[:.]/g, "-");
48
- return path.join(options.dataDir ?? runtime.dirs.data, "transcripts", `${safeConversation}-${stamp}.txt`);
49
- }
50
- export function createConversationName(now = new Date()) {
51
- const stamp = now.toISOString().replace(/[-:]/g, "").replace(/\..+$/, "").replace("T", "-");
52
- return `thread-${stamp}`;
53
- }
@@ -1,66 +0,0 @@
1
- import { type RenderMode, type WorkbenchAction, type WorkbenchCommand, type WorkbenchState } from "../tui/workbench.js";
2
- import type { AgentTurnEvent, WorkdirAccessMode } from "../agent.js";
3
- export interface WorkbenchEngineOptions {
4
- contextEnabled: boolean;
5
- accessMode?: WorkdirAccessMode;
6
- conversation?: string;
7
- preset?: string;
8
- model?: string;
9
- renderMode?: RenderMode;
10
- defaultPreset?: string | null;
11
- }
12
- export interface WorkbenchEngine {
13
- snapshot(): WorkbenchState;
14
- subscribe(listener: () => void): () => void;
15
- dispatch(action: WorkbenchAction): void;
16
- submit(input: string): WorkbenchSubmission;
17
- handleCommand(command: WorkbenchCommand): WorkbenchCommandResult;
18
- handleAgentEvent(event: AgentTurnEvent): WorkbenchEventResult;
19
- }
20
- export type WorkbenchSubmission = {
21
- kind: "command";
22
- command: WorkbenchCommand;
23
- } | {
24
- kind: "prompt";
25
- prompt: string;
26
- } | {
27
- kind: "handled";
28
- };
29
- export type WorkbenchEffect = {
30
- type: "exit";
31
- } | {
32
- type: "login";
33
- } | {
34
- type: "logout";
35
- } | {
36
- type: "delete_profile";
37
- } | {
38
- type: "switch_profile";
39
- name?: string;
40
- } | {
41
- type: "show_auth_status";
42
- } | {
43
- type: "export_transcript";
44
- path?: string;
45
- transcript: string;
46
- conversation: string;
47
- } | {
48
- type: "clear_preset_tool_catalog_cache";
49
- };
50
- export type WorkbenchRuntimeEffect = {
51
- type: "append_text_delta";
52
- delta: string;
53
- } | {
54
- type: "set_active_response_id";
55
- responseID: string;
56
- } | {
57
- type: "flush_text_delta_buffer";
58
- };
59
- export interface WorkbenchCommandResult {
60
- handled: boolean;
61
- effects: WorkbenchEffect[];
62
- }
63
- export interface WorkbenchEventResult {
64
- effects: WorkbenchRuntimeEffect[];
65
- }
66
- export declare function createWorkbenchEngine(options: WorkbenchEngineOptions): WorkbenchEngine;
@@ -1,291 +0,0 @@
1
- import { createInitialWorkbenchState, formatTranscript, formatTranscriptPreview, helpText, parsePendingApprovalCommand, parseWorkbenchCommand, workbenchReducer, workdirText, } from "../tui/workbench.js";
2
- export function createWorkbenchEngine(options) {
3
- let state = createInitialWorkbenchState(options);
4
- let pendingApprovalInvalidInputs = 0;
5
- const listeners = new Set();
6
- const notify = () => {
7
- for (const listener of listeners)
8
- listener();
9
- };
10
- const dispatch = (action) => {
11
- if (action.type === "local_tool.pending.set" || action.type === "local_tool.pending.clear") {
12
- pendingApprovalInvalidInputs = 0;
13
- }
14
- const next = workbenchReducer(state, action);
15
- if (Object.is(next, state))
16
- return;
17
- state = next;
18
- notify();
19
- };
20
- return {
21
- snapshot() {
22
- return state;
23
- },
24
- subscribe(listener) {
25
- listeners.add(listener);
26
- return () => {
27
- listeners.delete(listener);
28
- };
29
- },
30
- dispatch,
31
- handleCommand(command) {
32
- switch (command.kind) {
33
- case "quit":
34
- return handled({ type: "exit" });
35
- case "login":
36
- return handled({ type: "login" });
37
- case "logout":
38
- return handled({ type: "logout" });
39
- case "delete_profile":
40
- return handled({ type: "delete_profile" });
41
- case "switch_profile":
42
- return handled({ type: "switch_profile", name: command.name });
43
- case "auth_status":
44
- return handled({ type: "show_auth_status" });
45
- case "export":
46
- return handled({
47
- type: "export_transcript",
48
- path: command.path,
49
- transcript: formatTranscript(state.messages),
50
- conversation: state.currentConversation,
51
- });
52
- case "refresh_catalog":
53
- dispatch({ type: "activity.add", level: "success", text: "Preset and tool catalogs refreshed" });
54
- dispatch({ type: "message.add", role: "system", text: "Cleared cached preset and server tool catalogs. The next agent turn will fetch fresh platform configuration." });
55
- return handled({ type: "clear_preset_tool_catalog_cache" });
56
- case "invalid":
57
- dispatch({
58
- type: "message.add",
59
- role: "system",
60
- text: `Unknown command: /${command.command}\nType /help for supported commands.`,
61
- });
62
- dispatch({ type: "activity.add", level: "warning", text: `Unknown command: /${command.command}` });
63
- return handled();
64
- case "help":
65
- dispatch({ type: "message.add", role: "system", text: helpText() });
66
- return handled();
67
- case "clear":
68
- dispatch({ type: "messages.clear" });
69
- return handled();
70
- case "render":
71
- if (!command.mode) {
72
- dispatch({ type: "message.add", role: "system", text: `Render mode: ${state.renderMode}. Use /render markdown or /render raw.` });
73
- return handled();
74
- }
75
- dispatch({ type: "settings.set", settings: { renderMode: command.mode } });
76
- dispatch({ type: "activity.add", level: "success", text: `Render mode: ${command.mode}` });
77
- dispatch({ type: "message.add", role: "system", text: `Render mode set to ${command.mode}.` });
78
- return handled();
79
- case "transcript":
80
- dispatch({ type: "message.add", role: "system", text: formatTranscriptPreview(state.messages) });
81
- dispatch({ type: "activity.add", level: "success", text: "Transcript preview ready" });
82
- return handled();
83
- case "context":
84
- dispatch({ type: "context.set", enabled: command.enabled ?? !state.contextEnabled });
85
- return handled();
86
- case "access":
87
- if (!command.mode) {
88
- dispatch({ type: "message.add", role: "system", text: `Local access: ${state.accessMode}. Use /access off, /access approval, or /access full.` });
89
- return handled();
90
- }
91
- dispatch({ type: "access.set", mode: command.mode });
92
- return handled();
93
- case "model":
94
- if (!command.value) {
95
- dispatch({ type: "message.add", role: "system", text: `Model: ${state.runModel || "auto"}. Use /model <name> or /model auto.` });
96
- return handled();
97
- }
98
- dispatch({ type: "settings.set", settings: { runModel: normalizeOptionalSetting(command.value, ["auto", "none", "off", "clear"]) } });
99
- dispatch({ type: "activity.add", text: `Model: ${normalizeOptionalSetting(command.value, ["auto", "none", "off", "clear"]) || "auto"}` });
100
- return handled();
101
- case "workdir":
102
- if (command.enabled === undefined) {
103
- dispatch({
104
- type: "message.add",
105
- role: "system",
106
- text: [
107
- workdirText(state.workdir),
108
- "",
109
- `local_workdir tool: ${state.contextEnabled ? "on" : "off"}`,
110
- `local_shell tool: ${state.contextEnabled ? "on" : "off"}`,
111
- "Use /access approval or /access full to expose local tools, or /access off to hide them.",
112
- ].join("\n"),
113
- });
114
- return handled();
115
- }
116
- dispatch({ type: "context.set", enabled: command.enabled });
117
- dispatch({
118
- type: "activity.add",
119
- level: command.enabled ? "success" : "warning",
120
- text: `local tools ${command.enabled ? "enabled" : "disabled"}`,
121
- });
122
- dispatch({
123
- type: "message.add",
124
- role: "system",
125
- text: command.enabled
126
- ? "local_workdir and local_shell are now available to the model in approval mode. Use /access full to allow execution without prompts."
127
- : "local tools are now hidden from the model.",
128
- });
129
- return handled();
130
- default:
131
- return unhandled();
132
- }
133
- },
134
- handleAgentEvent(event) {
135
- switch (event.type) {
136
- case "text.delta":
137
- return event.delta ? eventResult({ type: "append_text_delta", delta: event.delta }) : eventResult();
138
- case "response.started":
139
- if (event.responseID) {
140
- dispatch({ type: "activity.add", text: `Response started: ${event.responseID}` });
141
- return eventResult({ type: "set_active_response_id", responseID: event.responseID });
142
- }
143
- dispatch({ type: "activity.add", text: "Response started" });
144
- return eventResult();
145
- case "response.completed":
146
- dispatch({ type: "activity.add", level: "success", text: event.responseID ? `Response completed: ${event.responseID}` : "Response completed" });
147
- return eventResult({ type: "flush_text_delta_buffer" });
148
- case "response.failed":
149
- dispatch({ type: "activity.add", level: "error", text: event.message });
150
- return eventResult({ type: "flush_text_delta_buffer" });
151
- case "reasoning.started":
152
- dispatch({ type: "activity.add", text: "Reasoning started" });
153
- return eventResult();
154
- case "reasoning.stopped":
155
- dispatch({ type: "activity.add", text: event.thought ? `Reasoning stopped: ${event.thought}` : "Reasoning stopped" });
156
- return eventResult();
157
- case "reasoning.search_queries":
158
- dispatch({ type: "activity.add", text: `Search queries: ${event.queries.join(", ") || "none"}` });
159
- return eventResult();
160
- case "reasoning.search_results":
161
- dispatch({ type: "activity.add", text: `Search results: ${event.count}` });
162
- return eventResult();
163
- case "reasoning.fetch_url_queries":
164
- dispatch({ type: "activity.add", text: `Fetch URLs: ${event.urls.join(", ") || "none"}` });
165
- return eventResult();
166
- case "reasoning.fetch_url_results":
167
- dispatch({ type: "activity.add", text: `Fetched URL results: ${event.count}` });
168
- return eventResult();
169
- case "tool.completed":
170
- dispatch({ type: "activity.add", level: event.status === "failed" ? "error" : "success", text: `Tool completed: ${event.name}${event.status ? ` (${event.status})` : ""}` });
171
- return eventResult();
172
- case "local_tool.completed":
173
- dispatch({
174
- type: "activity.add",
175
- level: event.requiresApproval ? "warning" : "success",
176
- text: `Local tool: ${event.name}${event.action ? `.${event.action}` : ""}${event.requiresApproval ? " (approval required)" : ""}`,
177
- });
178
- return eventResult();
179
- case "local_tool.approval_requested":
180
- dispatch({
181
- type: "local_tool.pending.set",
182
- approval: {
183
- name: event.name,
184
- action: event.action,
185
- arguments: event.arguments,
186
- preview: event.preview,
187
- callID: event.callID,
188
- responseID: event.responseID,
189
- },
190
- });
191
- dispatch({ type: "message.add", role: "system", text: formatLocalToolApproval(event) });
192
- return eventResult();
193
- case "model.requested":
194
- dispatch({ type: "activity.add", text: `Model requested: ${modelLabel(event.model, event.provider)}` });
195
- return eventResult();
196
- case "model.completed":
197
- dispatch({ type: "activity.add", level: "success", text: `Model completed: ${modelLabel(event.model, event.provider)}` });
198
- return eventResult();
199
- case "model.failed":
200
- dispatch({ type: "activity.add", level: "error", text: `Model failed: ${modelLabel(event.model, event.provider)}` });
201
- return eventResult();
202
- case "step.completed":
203
- dispatch({ type: "activity.add", level: "success", text: `Step completed: ${event.stepType || "step"}` });
204
- return eventResult();
205
- case "step.failed":
206
- dispatch({ type: "activity.add", level: "error", text: `Step failed: ${event.stepType || "step"}` });
207
- return eventResult();
208
- case "raw":
209
- return eventResult();
210
- }
211
- },
212
- submit(input) {
213
- const trimmed = input.trim();
214
- if (!trimmed)
215
- return { kind: "handled" };
216
- if (state.pendingLocalTool) {
217
- const command = parsePendingApprovalCommand(trimmed);
218
- if (command) {
219
- pendingApprovalInvalidInputs = 0;
220
- return { kind: "command", command };
221
- }
222
- handleInvalidPendingApprovalInput();
223
- return { kind: "handled" };
224
- }
225
- const command = parseWorkbenchCommand(trimmed);
226
- if (command)
227
- return { kind: "command", command };
228
- return { kind: "prompt", prompt: trimmed };
229
- },
230
- };
231
- function handleInvalidPendingApprovalInput() {
232
- pendingApprovalInvalidInputs += 1;
233
- const attempts = pendingApprovalInvalidInputs;
234
- const maxAttempts = 3;
235
- if (attempts >= maxAttempts) {
236
- dispatch({
237
- type: "message.add",
238
- role: "system",
239
- text: "Local approval aborted after too many invalid inputs. The pending action was not executed.",
240
- });
241
- dispatch({ type: "activity.add", level: "warning", text: "Local approval aborted" });
242
- dispatch({ type: "local_tool.pending.clear" });
243
- pendingApprovalInvalidInputs = 0;
244
- return;
245
- }
246
- dispatch({
247
- type: "message.add",
248
- role: "system",
249
- text: `Local approval is pending. Enter /apply or /yes to execute once, /apply-all or /yes-all to allow future local actions, or /reject or /no to discard. Invalid input ${attempts}/${maxAttempts}.`,
250
- });
251
- dispatch({ type: "activity.add", level: "warning", text: "Waiting for local approval command" });
252
- }
253
- }
254
- function handled(...effects) {
255
- return { handled: true, effects };
256
- }
257
- function unhandled() {
258
- return { handled: false, effects: [] };
259
- }
260
- function eventResult(...effects) {
261
- return { effects };
262
- }
263
- function modelLabel(model, provider) {
264
- if (model && provider)
265
- return `${provider}/${model}`;
266
- return model || provider || "unknown";
267
- }
268
- function formatLocalToolApproval(event) {
269
- const label = `${event.name}${event.action ? `.${event.action}` : ""}`;
270
- return [
271
- `Local action requires approval: ${label}.`,
272
- event.preview ? `Preview:\n${formatPreview(event.preview)}` : undefined,
273
- "Review it in the workbench, then use /apply to execute once, /apply-all to allow future local actions, or /reject to discard it.",
274
- ].filter(Boolean).join("\n\n");
275
- }
276
- function formatPreview(preview) {
277
- if (typeof preview === "string")
278
- return preview;
279
- try {
280
- return JSON.stringify(preview, null, 2);
281
- }
282
- catch {
283
- return String(preview);
284
- }
285
- }
286
- function normalizeOptionalSetting(value, clearValues) {
287
- const trimmed = value.trim();
288
- if (!trimmed)
289
- return undefined;
290
- return clearValues.includes(trimmed.toLowerCase()) ? undefined : trimmed;
291
- }
@@ -1,44 +0,0 @@
1
- export interface WorkbenchInputKey {
2
- backspace?: boolean;
3
- ctrl?: boolean;
4
- delete?: boolean;
5
- downArrow?: boolean;
6
- end?: boolean;
7
- escape?: boolean;
8
- home?: boolean;
9
- meta?: boolean;
10
- pageDown?: boolean;
11
- pageUp?: boolean;
12
- return?: boolean;
13
- upArrow?: boolean;
14
- }
15
- export type WorkbenchInputEffect = {
16
- type: "exit";
17
- } | {
18
- type: "scroll";
19
- delta: number;
20
- } | {
21
- type: "scroll_top";
22
- } | {
23
- type: "scroll_bottom";
24
- } | {
25
- type: "abort";
26
- } | {
27
- type: "submit";
28
- input: string;
29
- } | {
30
- type: "ignored_busy";
31
- };
32
- export interface WorkbenchInputResult {
33
- draft: string;
34
- effects: WorkbenchInputEffect[];
35
- }
36
- export interface WorkbenchInputContext {
37
- busy: boolean;
38
- draft: string;
39
- viewportHeight: number;
40
- }
41
- export interface WorkbenchInputController {
42
- handle(input: string, key: WorkbenchInputKey, context: WorkbenchInputContext): WorkbenchInputResult;
43
- }
44
- export declare function createWorkbenchInputController(): WorkbenchInputController;
@@ -1,71 +0,0 @@
1
- import { createInputHistory } from "../tui/workbench.js";
2
- export function createWorkbenchInputController() {
3
- const history = createInputHistory();
4
- return {
5
- handle(input, key, context) {
6
- if (key.ctrl && input === "c")
7
- return result(context.draft, { type: "exit" });
8
- if (key.pageUp || (key.ctrl && input === "u")) {
9
- return result(context.draft, { type: "scroll", delta: Math.max(1, Math.floor(context.viewportHeight / 2)) });
10
- }
11
- if (key.pageDown || (key.ctrl && input === "d")) {
12
- return result(context.draft, { type: "scroll", delta: -Math.max(1, Math.floor(context.viewportHeight / 2)) });
13
- }
14
- if (key.home)
15
- return result(context.draft, { type: "scroll_top" });
16
- if (key.end)
17
- return result(context.draft, { type: "scroll_bottom" });
18
- if (key.upArrow)
19
- return result(history.previous(context.draft));
20
- if (key.downArrow)
21
- return result(history.next(context.draft));
22
- if (context.busy) {
23
- return handleBusyInput(input, key, context.draft, history);
24
- }
25
- return handleReadyInput(input, key, context.draft, history);
26
- },
27
- };
28
- }
29
- function handleBusyInput(input, key, draft, history) {
30
- if (key.escape)
31
- return result(draft, { type: "abort" });
32
- if (key.return) {
33
- const command = draft.trim();
34
- history.record(command);
35
- if (command === "/abort" || command === "/cancel")
36
- return result("", { type: "abort" });
37
- if (command)
38
- return result("", { type: "ignored_busy" });
39
- return result("");
40
- }
41
- if (key.backspace || key.delete) {
42
- history.reset();
43
- return result(draft.slice(0, -1));
44
- }
45
- if (input && !key.ctrl && !key.meta) {
46
- history.reset();
47
- return result(draft + input);
48
- }
49
- return result(draft);
50
- }
51
- function handleReadyInput(input, key, draft, history) {
52
- if (key.return) {
53
- const prompt = draft.trim();
54
- if (!prompt)
55
- return result(draft);
56
- history.record(prompt);
57
- return result("", { type: "submit", input: prompt });
58
- }
59
- if (key.backspace || key.delete) {
60
- history.reset();
61
- return result(draft.slice(0, -1));
62
- }
63
- if (input && !key.ctrl && !key.meta) {
64
- history.reset();
65
- return result(draft + input);
66
- }
67
- return result(draft);
68
- }
69
- function result(draft, ...effects) {
70
- return { draft, effects };
71
- }
@@ -1,29 +0,0 @@
1
- export interface IsolatorInstallConfig {
2
- sourceURL?: string | null;
3
- executablePath?: string | null;
4
- sha256?: string | null;
5
- }
6
- export interface IsolatorInstallResult {
7
- executablePath: string;
8
- sourceURL: string;
9
- bytes: number;
10
- sha256: string;
11
- replaced: boolean;
12
- }
13
- export interface IsolatorEnsureResult {
14
- executablePath: string;
15
- sourceURL: string;
16
- sha256?: string | null;
17
- repaired: boolean;
18
- }
19
- export interface IsolatorInstallOptions {
20
- fetchImpl?: typeof fetch;
21
- probeTimeoutMs?: number;
22
- }
23
- export declare function installConfiguredIsolator(config: IsolatorInstallConfig, options?: IsolatorInstallOptions): Promise<IsolatorInstallResult>;
24
- export declare function validateInstalledIsolator(executablePath: string, options?: Pick<IsolatorInstallOptions, "probeTimeoutMs">): Promise<string>;
25
- export declare function ensureConfiguredIsolator(config: IsolatorInstallConfig, options?: IsolatorInstallOptions): Promise<IsolatorEnsureResult>;
26
- export declare function relocateInstalledIsolator(fromPath: string, toPath: string, options?: Pick<IsolatorInstallOptions, "probeTimeoutMs">): Promise<string>;
27
- export declare function defaultIsolatorInstallPath(): string;
28
- export declare function normalizeSourceURL(value: string | null | undefined): string;
29
- export declare function normalizeInstallPath(value: string | null | undefined): string;