codebase-cli 2.0.0-pre.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.
- package/LICENSE +21 -0
- package/README.md +266 -0
- package/bin/codebase +2 -0
- package/dist/agent/agent.js +198 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/config.js +117 -0
- package/dist/agent/config.js.map +1 -0
- package/dist/agent/events.js +153 -0
- package/dist/agent/events.js.map +1 -0
- package/dist/agent/router.js +35 -0
- package/dist/agent/router.js.map +1 -0
- package/dist/agent/system-prompt.js +21 -0
- package/dist/agent/system-prompt.js.map +1 -0
- package/dist/auth/cli.js +138 -0
- package/dist/auth/cli.js.map +1 -0
- package/dist/auth/credentials.js +105 -0
- package/dist/auth/credentials.js.map +1 -0
- package/dist/auth/flow.js +222 -0
- package/dist/auth/flow.js.map +1 -0
- package/dist/auth/pkce.js +46 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/cli.js +69 -0
- package/dist/cli.js.map +1 -0
- package/dist/clipboard/copy.js +106 -0
- package/dist/clipboard/copy.js.map +1 -0
- package/dist/commands/builtins.js +203 -0
- package/dist/commands/builtins.js.map +1 -0
- package/dist/commands/registry.js +65 -0
- package/dist/commands/registry.js.map +1 -0
- package/dist/commands/types.js +2 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/compaction/engine.js +209 -0
- package/dist/compaction/engine.js.map +1 -0
- package/dist/compaction/tokens.js +79 -0
- package/dist/compaction/tokens.js.map +1 -0
- package/dist/compaction/types.js +2 -0
- package/dist/compaction/types.js.map +1 -0
- package/dist/diagnostics/checkers.js +211 -0
- package/dist/diagnostics/checkers.js.map +1 -0
- package/dist/diagnostics/engine.js +71 -0
- package/dist/diagnostics/engine.js.map +1 -0
- package/dist/diagnostics/types.js +2 -0
- package/dist/diagnostics/types.js.map +1 -0
- package/dist/dotenv/loader.js +115 -0
- package/dist/dotenv/loader.js.map +1 -0
- package/dist/glue/client.js +47 -0
- package/dist/glue/client.js.map +1 -0
- package/dist/glue/intent.js +78 -0
- package/dist/glue/intent.js.map +1 -0
- package/dist/glue/narration.js +55 -0
- package/dist/glue/narration.js.map +1 -0
- package/dist/headless/run.js +89 -0
- package/dist/headless/run.js.map +1 -0
- package/dist/hooks/manager.js +158 -0
- package/dist/hooks/manager.js.map +1 -0
- package/dist/hooks/runner.js +70 -0
- package/dist/hooks/runner.js.map +1 -0
- package/dist/hooks/types.js +2 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/memory/inject.js +12 -0
- package/dist/memory/inject.js.map +1 -0
- package/dist/memory/store.js +178 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/memory/types.js +10 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/permissions/store.js +172 -0
- package/dist/permissions/store.js.map +1 -0
- package/dist/plan/flow.js +214 -0
- package/dist/plan/flow.js.map +1 -0
- package/dist/plan/prompts.js +69 -0
- package/dist/plan/prompts.js.map +1 -0
- package/dist/plan/store.js +37 -0
- package/dist/plan/store.js.map +1 -0
- package/dist/plan/types.js +3 -0
- package/dist/plan/types.js.map +1 -0
- package/dist/sessions/store.js +105 -0
- package/dist/sessions/store.js.map +1 -0
- package/dist/skills/loader.js +41 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/platform-loader.js +63 -0
- package/dist/skills/platform-loader.js.map +1 -0
- package/dist/skills/types.js +21 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/tools/ask-user.js +61 -0
- package/dist/tools/ask-user.js.map +1 -0
- package/dist/tools/dispatch-agent.js +178 -0
- package/dist/tools/dispatch-agent.js.map +1 -0
- package/dist/tools/edit-file.js +80 -0
- package/dist/tools/edit-file.js.map +1 -0
- package/dist/tools/errors.js +89 -0
- package/dist/tools/errors.js.map +1 -0
- package/dist/tools/file-ops.js +136 -0
- package/dist/tools/file-ops.js.map +1 -0
- package/dist/tools/file-state-cache.js +92 -0
- package/dist/tools/file-state-cache.js.map +1 -0
- package/dist/tools/git/branch.js +84 -0
- package/dist/tools/git/branch.js.map +1 -0
- package/dist/tools/git/commit.js +83 -0
- package/dist/tools/git/commit.js.map +1 -0
- package/dist/tools/git/diff.js +72 -0
- package/dist/tools/git/diff.js.map +1 -0
- package/dist/tools/git/git-helpers.js +58 -0
- package/dist/tools/git/git-helpers.js.map +1 -0
- package/dist/tools/git/log.js +70 -0
- package/dist/tools/git/log.js.map +1 -0
- package/dist/tools/git/status.js +97 -0
- package/dist/tools/git/status.js.map +1 -0
- package/dist/tools/git/worktree.js +132 -0
- package/dist/tools/git/worktree.js.map +1 -0
- package/dist/tools/glob.js +128 -0
- package/dist/tools/glob.js.map +1 -0
- package/dist/tools/grep.js +199 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/list-files.js +120 -0
- package/dist/tools/list-files.js.map +1 -0
- package/dist/tools/memory-tools.js +127 -0
- package/dist/tools/memory-tools.js.map +1 -0
- package/dist/tools/multi-edit.js +87 -0
- package/dist/tools/multi-edit.js.map +1 -0
- package/dist/tools/notebook-edit.js +147 -0
- package/dist/tools/notebook-edit.js.map +1 -0
- package/dist/tools/permission.js +168 -0
- package/dist/tools/permission.js.map +1 -0
- package/dist/tools/plan-mode.js +76 -0
- package/dist/tools/plan-mode.js.map +1 -0
- package/dist/tools/read-file.js +135 -0
- package/dist/tools/read-file.js.map +1 -0
- package/dist/tools/registry.js +52 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/shell.js +216 -0
- package/dist/tools/shell.js.map +1 -0
- package/dist/tools/task-store.js +70 -0
- package/dist/tools/task-store.js.map +1 -0
- package/dist/tools/tasks.js +131 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/web-fetch.js +152 -0
- package/dist/tools/web-fetch.js.map +1 -0
- package/dist/tools/web-search.js +169 -0
- package/dist/tools/web-search.js.map +1 -0
- package/dist/tools/write-file.js +70 -0
- package/dist/tools/write-file.js.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/App.js +216 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/Input.js +90 -0
- package/dist/ui/Input.js.map +1 -0
- package/dist/ui/Message.js +89 -0
- package/dist/ui/Message.js.map +1 -0
- package/dist/ui/MessageList.js +35 -0
- package/dist/ui/MessageList.js.map +1 -0
- package/dist/ui/Permission.js +39 -0
- package/dist/ui/Permission.js.map +1 -0
- package/dist/ui/Status.js +34 -0
- package/dist/ui/Status.js.map +1 -0
- package/dist/ui/TaskPanel.js +43 -0
- package/dist/ui/TaskPanel.js.map +1 -0
- package/dist/ui/Throbber.js +20 -0
- package/dist/ui/Throbber.js.map +1 -0
- package/dist/ui/ToolPanel.js +83 -0
- package/dist/ui/ToolPanel.js.map +1 -0
- package/dist/ui/UserQuery.js +38 -0
- package/dist/ui/UserQuery.js.map +1 -0
- package/dist/ui/input-state.js +210 -0
- package/dist/ui/input-state.js.map +1 -0
- package/dist/ui/wrap.js +30 -0
- package/dist/ui/wrap.js.map +1 -0
- package/dist/user-queries/store.js +60 -0
- package/dist/user-queries/store.js.map +1 -0
- package/package.json +76 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-file.js","sourceRoot":"","sources":["../../src/tools/write-file.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA2BA,MAAM,CAAC,MAAM,WAAW,GAAU;IACjC,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,SAAS,EAAE,CAAC;IACZ,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,CAAC;IACd,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;CACpE,CAAC"}
|
package/dist/ui/App.js
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text, useApp } from "ink";
|
|
3
|
+
import { useEffect, useMemo, useReducer, useState } from "react";
|
|
4
|
+
import { createAgent } from "../agent/agent.js";
|
|
5
|
+
import { ConfigError } from "../agent/config.js";
|
|
6
|
+
import { initialState, reducer } from "../agent/events.js";
|
|
7
|
+
import { routeUserInput } from "../agent/router.js";
|
|
8
|
+
import { BUILTIN_COMMANDS } from "../commands/builtins.js";
|
|
9
|
+
import { CommandRegistry } from "../commands/registry.js";
|
|
10
|
+
import { buildAgentPrompt, generatePlan, generateQuestion, MAX_QUESTIONS, parseAnswer, revisePlan, } from "../plan/flow.js";
|
|
11
|
+
import { ANSWER_START_BUILDING } from "../plan/types.js";
|
|
12
|
+
import { UserQueryCancelled } from "../user-queries/store.js";
|
|
13
|
+
import { Input } from "./Input.js";
|
|
14
|
+
import { MessageList } from "./MessageList.js";
|
|
15
|
+
import { Permission } from "./Permission.js";
|
|
16
|
+
import { Status } from "./Status.js";
|
|
17
|
+
import { TaskPanel } from "./TaskPanel.js";
|
|
18
|
+
import { ToolPanel } from "./ToolPanel.js";
|
|
19
|
+
import { UserQueryView } from "./UserQuery.js";
|
|
20
|
+
export function App() {
|
|
21
|
+
const { exit } = useApp();
|
|
22
|
+
let bundle;
|
|
23
|
+
let configError;
|
|
24
|
+
try {
|
|
25
|
+
bundle = createAgent();
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
configError = err instanceof ConfigError ? err.message : String(err);
|
|
29
|
+
}
|
|
30
|
+
if (!bundle) {
|
|
31
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, paddingY: 1, children: [_jsx(Text, { bold: true, color: "red", children: "configuration error" }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { children: configError }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Press Ctrl-C to exit." }) }), _jsx(ExitOnCtrlC, { onExit: exit })] }));
|
|
32
|
+
}
|
|
33
|
+
return _jsx(ChatApp, { bundle: bundle, onExit: exit });
|
|
34
|
+
}
|
|
35
|
+
function ChatApp({ bundle, onExit }) {
|
|
36
|
+
const [state, dispatch] = useReducer(reducer, initialState({ provider: bundle.model.provider, id: bundle.model.id, name: bundle.model.name }));
|
|
37
|
+
const [permRequest, setPermRequest] = useState(bundle.permissions.current());
|
|
38
|
+
const [userQuery, setUserQuery] = useState(bundle.userQueries.current());
|
|
39
|
+
const [statusLines, setStatusLines] = useState([]);
|
|
40
|
+
const [tasks, setTasks] = useState(() => bundle.toolContext.tasks.list());
|
|
41
|
+
const registry = useMemo(() => {
|
|
42
|
+
const reg = new CommandRegistry();
|
|
43
|
+
reg.registerAll(BUILTIN_COMMANDS);
|
|
44
|
+
return reg;
|
|
45
|
+
}, []);
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
const unsubscribe = bundle.subscribe((event) => {
|
|
48
|
+
dispatch({ type: "agent-event", event });
|
|
49
|
+
});
|
|
50
|
+
return unsubscribe;
|
|
51
|
+
}, [bundle]);
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
return bundle.permissions.subscribe((req) => setPermRequest(req));
|
|
54
|
+
}, [bundle]);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
return bundle.userQueries.subscribe((q) => setUserQuery(q));
|
|
57
|
+
}, [bundle]);
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
return bundle.toolContext.tasks.subscribe((snapshot) => setTasks(snapshot));
|
|
60
|
+
}, [bundle]);
|
|
61
|
+
const busy = state.status === "thinking" || state.status === "streaming" || state.status === "tool";
|
|
62
|
+
const handleSubmit = async (text) => {
|
|
63
|
+
// Slash commands first — they bypass the agent.
|
|
64
|
+
if (text.startsWith("/")) {
|
|
65
|
+
const result = await registry.dispatch(text, {
|
|
66
|
+
bundle,
|
|
67
|
+
state: state,
|
|
68
|
+
emit: (line) => setStatusLines((prev) => [...prev, line]),
|
|
69
|
+
clearDisplay: () => dispatch({ type: "reset" }),
|
|
70
|
+
exit: onExit,
|
|
71
|
+
// Inject the registry so /help can list commands.
|
|
72
|
+
// biome-ignore lint/suspicious/noExplicitAny: cross-cutting injection
|
|
73
|
+
registry,
|
|
74
|
+
// biome-ignore lint/suspicious/noExplicitAny: cross-cutting injection
|
|
75
|
+
});
|
|
76
|
+
if (result.handled)
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// Capture history-presence BEFORE the user-prompt dispatch — React's
|
|
80
|
+
// batched updates mean state.messages won't reflect the new user message
|
|
81
|
+
// in the same tick, but the router needs to know whether this is a
|
|
82
|
+
// continuation (greeting fast-track) or a first message.
|
|
83
|
+
const hadHistory = state.messages.some((m) => m.role === "assistant");
|
|
84
|
+
dispatch({ type: "user-prompt", text });
|
|
85
|
+
try {
|
|
86
|
+
const route = await routeUserInput(bundle.glue, text, { hasHistory: hadHistory });
|
|
87
|
+
if (route.kind === "chat") {
|
|
88
|
+
dispatch({ type: "chat-reply", text: route.reply });
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (route.kind === "plan") {
|
|
92
|
+
await runPlanFlow(text);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
// If the router itself crashes, don't drop the request — run the agent.
|
|
98
|
+
// We still log it as a non-fatal status line so users notice.
|
|
99
|
+
setStatusLines((prev) => [
|
|
100
|
+
...prev,
|
|
101
|
+
`(router fell back to agent: ${err instanceof Error ? err.message : err})`,
|
|
102
|
+
]);
|
|
103
|
+
}
|
|
104
|
+
bundle.agent.prompt(text).catch((err) => {
|
|
105
|
+
dispatch({ type: "error", message: err instanceof Error ? err.message : String(err) });
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Plan-mode flow:
|
|
110
|
+
* 1. Q&A loop (up to MAX_QUESTIONS, with the start-building escape).
|
|
111
|
+
* 2. Generate plan, render as a synthetic assistant message so the
|
|
112
|
+
* user can read it in chat.
|
|
113
|
+
* 3. Approve / Revise / Cancel via the UserQuery primitive.
|
|
114
|
+
* 4. On approve, hand the original prompt + plan + Q&A to the agent
|
|
115
|
+
* with the canonical buildAgentPrompt wrapper so weaker models
|
|
116
|
+
* stick to the plan instead of re-planning mid-execution.
|
|
117
|
+
*/
|
|
118
|
+
const runPlanFlow = async (originalPrompt) => {
|
|
119
|
+
const qaHistory = [];
|
|
120
|
+
try {
|
|
121
|
+
for (let i = 0; i < MAX_QUESTIONS; i++) {
|
|
122
|
+
const result = await generateQuestion(bundle.glue, originalPrompt, qaHistory, i);
|
|
123
|
+
if (result.done || !result.question)
|
|
124
|
+
break;
|
|
125
|
+
const q = result.question;
|
|
126
|
+
const optionLabels = q.options?.map((o) => o.label);
|
|
127
|
+
const answer = await bundle.userQueries.ask({
|
|
128
|
+
question: q.question,
|
|
129
|
+
options: optionLabels,
|
|
130
|
+
placeholder: optionLabels ? `1-${optionLabels.length}, or type a free-form answer` : undefined,
|
|
131
|
+
});
|
|
132
|
+
const resolved = parseAnswer(answer, q);
|
|
133
|
+
if (resolved === ANSWER_START_BUILDING)
|
|
134
|
+
break;
|
|
135
|
+
qaHistory.push({ question: q.question, answer: resolved });
|
|
136
|
+
}
|
|
137
|
+
let plan = await generatePlan(bundle.glue, originalPrompt, qaHistory);
|
|
138
|
+
while (true) {
|
|
139
|
+
dispatch({ type: "chat-reply", text: plan });
|
|
140
|
+
const decision = await bundle.userQueries.ask({
|
|
141
|
+
question: "Approve this plan and run it?",
|
|
142
|
+
options: ["Yes — run it", "Revise", "Cancel"],
|
|
143
|
+
});
|
|
144
|
+
const choice = matchOption(decision, ["Yes — run it", "Revise", "Cancel"]);
|
|
145
|
+
if (choice === "Yes — run it") {
|
|
146
|
+
const finalPrompt = buildAgentPrompt(originalPrompt, plan, qaHistory);
|
|
147
|
+
bundle.agent.prompt(finalPrompt).catch((err) => {
|
|
148
|
+
dispatch({ type: "error", message: err instanceof Error ? err.message : String(err) });
|
|
149
|
+
});
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (choice === "Cancel") {
|
|
153
|
+
dispatch({ type: "chat-reply", text: "(plan cancelled)" });
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const feedback = await bundle.userQueries.ask({
|
|
157
|
+
question: "What should change about the plan?",
|
|
158
|
+
placeholder: "describe the revision",
|
|
159
|
+
});
|
|
160
|
+
plan = await revisePlan(bundle.glue, plan, feedback);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
if (err instanceof UserQueryCancelled) {
|
|
165
|
+
dispatch({ type: "chat-reply", text: "(plan cancelled)" });
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
dispatch({
|
|
169
|
+
type: "error",
|
|
170
|
+
message: `plan flow failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
const handleAbort = () => {
|
|
175
|
+
if (busy) {
|
|
176
|
+
bundle.agent.abort();
|
|
177
|
+
dispatch({ type: "abort" });
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
onExit();
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { paddingX: 1, paddingY: 0, marginBottom: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "codebase v2" }), _jsxs(Text, { dimColor: true, children: [" ", "\u00B7 ", bundle.model.name, " (", bundle.source, ")"] })] }), _jsx(MessageList, { messages: state.messages, streaming: state.streaming }), _jsx(ToolPanel, { tools: state.tools }), _jsx(TaskPanel, { tasks: tasks }), statusLines.length > 0 ? (_jsx(Box, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: statusLines.map((line, i) => (_jsx(Text, { dimColor: true, children: line }, `${i}-${line.slice(0, 8)}`))) })) : null, _jsx(Status, { state: state }), permRequest ? (_jsx(Permission, { request: permRequest, onRespond: (choice) => bundle.permissions.respond(permRequest.id, choice) })) : userQuery ? (_jsx(UserQueryView, { query: userQuery, onAnswer: (answer) => bundle.userQueries.respond(userQuery.id, answer), onCancel: () => bundle.userQueries.cancel(userQuery.id) })) : (_jsx(Input, { disabled: busy, onSubmit: handleSubmit, onAbort: handleAbort }))] }));
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Resolve a user's typed answer to one of the supplied options.
|
|
187
|
+
* Accepts the option label (case-insensitive), a 1-based index,
|
|
188
|
+
* or the leading word of the label. Falls back to the raw input
|
|
189
|
+
* if nothing matches — caller decides what to do with that.
|
|
190
|
+
*/
|
|
191
|
+
function matchOption(answer, options) {
|
|
192
|
+
const trimmed = answer.trim();
|
|
193
|
+
const idx = Number.parseInt(trimmed, 10);
|
|
194
|
+
if (Number.isFinite(idx) && idx >= 1 && idx <= options.length) {
|
|
195
|
+
return options[idx - 1];
|
|
196
|
+
}
|
|
197
|
+
const lower = trimmed.toLowerCase();
|
|
198
|
+
for (const option of options) {
|
|
199
|
+
if (option.toLowerCase() === lower)
|
|
200
|
+
return option;
|
|
201
|
+
if (option.toLowerCase().startsWith(lower) && lower.length >= 3)
|
|
202
|
+
return option;
|
|
203
|
+
}
|
|
204
|
+
return trimmed;
|
|
205
|
+
}
|
|
206
|
+
function ExitOnCtrlC({ onExit }) {
|
|
207
|
+
useEffect(() => {
|
|
208
|
+
const handler = () => onExit();
|
|
209
|
+
process.on("SIGINT", handler);
|
|
210
|
+
return () => {
|
|
211
|
+
process.off("SIGINT", handler);
|
|
212
|
+
};
|
|
213
|
+
}, [onExit]);
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=App.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"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"}
|
package/dist/ui/Input.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text, useInput } from "ink";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { backspace, deleteForward, initialInputState, insertChar, killToEnd, killToStart, killWordBack, moveEnd, moveLeft, moveRight, moveStart, undo, yank, } from "./input-state.js";
|
|
5
|
+
/**
|
|
6
|
+
* Single-line input with Emacs / readline editing. Cursor positioning,
|
|
7
|
+
* kill ring with Ctrl-K/U/W/Y, and Ctrl-Z undo. Stay in tight feedback
|
|
8
|
+
* with the user — every keystroke runs through the pure input-state
|
|
9
|
+
* reducer so the editing semantics are unit-testable.
|
|
10
|
+
*
|
|
11
|
+
* Keys:
|
|
12
|
+
* Enter submit (empty input is dropped)
|
|
13
|
+
* Backspace/Del delete char before / after cursor
|
|
14
|
+
* ←/→ move cursor by one
|
|
15
|
+
* Ctrl-A / Ctrl-E start / end of line
|
|
16
|
+
* Ctrl-K kill from cursor to end of line
|
|
17
|
+
* Ctrl-U kill from start of line to cursor
|
|
18
|
+
* Ctrl-W kill word before cursor
|
|
19
|
+
* Ctrl-Y yank (paste from kill ring)
|
|
20
|
+
* Ctrl-Z undo
|
|
21
|
+
* Ctrl-C abort (busy → cancel turn, idle → exit app)
|
|
22
|
+
*/
|
|
23
|
+
export function Input({ disabled, onSubmit, onAbort }) {
|
|
24
|
+
const [state, setState] = useState(initialInputState());
|
|
25
|
+
useInput((input, key) => {
|
|
26
|
+
if (key.ctrl && input === "c") {
|
|
27
|
+
onAbort?.();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (disabled)
|
|
31
|
+
return;
|
|
32
|
+
if (key.return) {
|
|
33
|
+
const trimmed = state.buffer.trim();
|
|
34
|
+
if (trimmed.length > 0) {
|
|
35
|
+
onSubmit(trimmed);
|
|
36
|
+
setState(initialInputState());
|
|
37
|
+
}
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// Cursor movement
|
|
41
|
+
if (key.leftArrow)
|
|
42
|
+
return setState(moveLeft(state));
|
|
43
|
+
if (key.rightArrow)
|
|
44
|
+
return setState(moveRight(state));
|
|
45
|
+
if (key.ctrl && input === "a")
|
|
46
|
+
return setState(moveStart(state));
|
|
47
|
+
if (key.ctrl && input === "e")
|
|
48
|
+
return setState(moveEnd(state));
|
|
49
|
+
// Edits
|
|
50
|
+
if (key.backspace)
|
|
51
|
+
return setState(backspace(state));
|
|
52
|
+
if (key.delete)
|
|
53
|
+
return setState(deleteForward(state));
|
|
54
|
+
if (key.ctrl && input === "d")
|
|
55
|
+
return setState(deleteForward(state));
|
|
56
|
+
// Kill ring
|
|
57
|
+
if (key.ctrl && input === "k")
|
|
58
|
+
return setState(killToEnd(state));
|
|
59
|
+
if (key.ctrl && input === "u")
|
|
60
|
+
return setState(killToStart(state));
|
|
61
|
+
if (key.ctrl && input === "w")
|
|
62
|
+
return setState(killWordBack(state));
|
|
63
|
+
if (key.ctrl && input === "y")
|
|
64
|
+
return setState(yank(state));
|
|
65
|
+
// Undo
|
|
66
|
+
if (key.ctrl && input === "z")
|
|
67
|
+
return setState(undo(state));
|
|
68
|
+
// Printable text — Ink's useInput delivers individual chars (or pasted runs)
|
|
69
|
+
if (input && !key.ctrl && !key.meta) {
|
|
70
|
+
setState(insertChar(state, input));
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return (_jsxs(Box, { paddingX: 1, children: [_jsxs(Text, { color: disabled ? "gray" : "cyan", children: [disabled ? "·" : ">", " "] }), disabled ? _jsx(Text, { children: state.buffer }) : _jsx(RenderedBuffer, { buffer: state.buffer, cursor: state.cursor })] }));
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Render the buffer with a visible cursor block at the cursor position.
|
|
77
|
+
* Inverse-video on the character under the cursor, or a thin block at
|
|
78
|
+
* end-of-line. Keeps the layout stable so the line doesn't shift when
|
|
79
|
+
* the cursor crosses the boundary.
|
|
80
|
+
*/
|
|
81
|
+
function RenderedBuffer({ buffer, cursor }) {
|
|
82
|
+
if (cursor >= buffer.length) {
|
|
83
|
+
return (_jsxs(_Fragment, { children: [_jsx(Text, { children: buffer }), _jsx(Text, { color: "cyan", children: "\u258E" })] }));
|
|
84
|
+
}
|
|
85
|
+
const before = buffer.slice(0, cursor);
|
|
86
|
+
const onCursor = buffer[cursor] === " " ? " " : (buffer[cursor] ?? " ");
|
|
87
|
+
const after = buffer.slice(cursor + 1);
|
|
88
|
+
return (_jsxs(_Fragment, { children: [_jsx(Text, { children: before }), _jsx(Text, { inverse: true, children: onCursor }), _jsx(Text, { children: after })] }));
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=Input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Input.js","sourceRoot":"","sources":["../../src/ui/Input.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import { wrapText } from "./wrap.js";
|
|
4
|
+
const ROLE_STYLE = {
|
|
5
|
+
user: { accent: "yellow", label: "you" },
|
|
6
|
+
assistant: { accent: "cyan", label: "codebase" },
|
|
7
|
+
toolResult: { accent: "magenta", label: "tool" },
|
|
8
|
+
};
|
|
9
|
+
export function Message({ message, streaming, width = 80 }) {
|
|
10
|
+
const role = message.role;
|
|
11
|
+
const style = ROLE_STYLE[role];
|
|
12
|
+
if (!style)
|
|
13
|
+
return null;
|
|
14
|
+
// The body sits inside `Box flexDirection=row` with a 1-col accent + 1-col
|
|
15
|
+
// gap, plus the parent App's paddingX of 1 each side. Reserve 4 cols so
|
|
16
|
+
// the wrapped text never tries to occupy the accent gutter.
|
|
17
|
+
const bodyWidth = Math.max(20, width - 4);
|
|
18
|
+
return (_jsxs(Box, { flexDirection: "row", marginY: 0, children: [_jsx(Box, { marginRight: 1, children: _jsx(Text, { color: style.accent, children: "\u2502" }) }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Text, { color: style.accent, bold: true, children: [style.label, streaming ? " …" : ""] }), _jsx(MessageBody, { message: message, width: bodyWidth })] })] }));
|
|
19
|
+
}
|
|
20
|
+
function MessageBody({ message, width }) {
|
|
21
|
+
if (message.role === "user") {
|
|
22
|
+
const text = typeof message.content === "string" ? message.content : renderUserContent(message.content);
|
|
23
|
+
return _jsx(WrappedLines, { text: text, width: width, keyPrefix: "user" });
|
|
24
|
+
}
|
|
25
|
+
if (message.role === "assistant") {
|
|
26
|
+
return (_jsxs(_Fragment, { children: [message.content.map((block, idx) => {
|
|
27
|
+
const key = blockKey(block, idx);
|
|
28
|
+
if (block.type === "text") {
|
|
29
|
+
return _jsx(WrappedLines, { text: block.text, width: width, keyPrefix: key }, key);
|
|
30
|
+
}
|
|
31
|
+
if (block.type === "thinking") {
|
|
32
|
+
return (_jsx(WrappedLines, { text: `(thinking) ${block.thinking}`, width: width, keyPrefix: key, dimColor: true, italic: true }, key));
|
|
33
|
+
}
|
|
34
|
+
if (block.type === "toolCall") {
|
|
35
|
+
return (_jsx(WrappedLines, { text: `→ ${block.name}(${summarizeArgs(block.arguments)})`, width: width, keyPrefix: key, color: "magenta" }, key));
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}), message.errorMessage ? (_jsx(WrappedLines, { text: `! ${message.errorMessage}`, width: width, keyPrefix: "err", color: "red" })) : null] }));
|
|
39
|
+
}
|
|
40
|
+
if (message.role === "toolResult") {
|
|
41
|
+
const text = message.content
|
|
42
|
+
.map((block) => (block.type === "text" ? block.text : `[image:${block.mimeType}]`))
|
|
43
|
+
.join("");
|
|
44
|
+
return _jsx(WrappedLines, { text: text, width: width, keyPrefix: "tool", color: message.isError ? "red" : undefined });
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Render text as N <Text> elements, one per pre-wrapped line. Stacks
|
|
50
|
+
* vertically inside the parent column-flex Box. Pre-wrap means the
|
|
51
|
+
* wraps happen at word boundaries, so when the user select-and-copies
|
|
52
|
+
* they get clean line endings — no mid-word breaks at column edges.
|
|
53
|
+
*/
|
|
54
|
+
function WrappedLines({ text, width, keyPrefix, color, dimColor, italic }) {
|
|
55
|
+
const lines = wrapText(text, width);
|
|
56
|
+
return (_jsx(_Fragment, { children: lines.map((line, i) => (
|
|
57
|
+
// Wrapped lines have no per-line state — <Text> is pure-presentational —
|
|
58
|
+
// so reusing instances on re-wrap is harmless; index-as-key is fine here.
|
|
59
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: stateless leaf, reuse is safe
|
|
60
|
+
_jsx(Text, { color: color, dimColor: dimColor, italic: italic, children: line.length === 0 ? " " : line }, `${keyPrefix}:${i}`))) }));
|
|
61
|
+
}
|
|
62
|
+
function renderUserContent(content) {
|
|
63
|
+
if (!Array.isArray(content))
|
|
64
|
+
return "";
|
|
65
|
+
return content
|
|
66
|
+
.map((block) => block.type === "text" ? (block.text ?? "") : `[image:${block.mimeType ?? "?"}]`)
|
|
67
|
+
.join("");
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Stable key per assistant content block. Tool calls have an id; text and
|
|
71
|
+
* thinking blocks don't reorder within a message so position-in-type is fine.
|
|
72
|
+
*/
|
|
73
|
+
function blockKey(block, idx) {
|
|
74
|
+
if (block.type === "toolCall" && block.id)
|
|
75
|
+
return `tc-${block.id}`;
|
|
76
|
+
return `${block.type}-${idx}`;
|
|
77
|
+
}
|
|
78
|
+
function summarizeArgs(args) {
|
|
79
|
+
if (!args || typeof args !== "object")
|
|
80
|
+
return "";
|
|
81
|
+
const entries = Object.entries(args).slice(0, 3);
|
|
82
|
+
return entries
|
|
83
|
+
.map(([k, v]) => {
|
|
84
|
+
const s = typeof v === "string" ? `"${v.slice(0, 30)}"` : String(v);
|
|
85
|
+
return `${k}=${s}`;
|
|
86
|
+
})
|
|
87
|
+
.join(", ");
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=Message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Message.js","sourceRoot":"","sources":["../../src/ui/Message.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Static, useStdout } from "ink";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { Message } from "./Message.js";
|
|
5
|
+
/**
|
|
6
|
+
* Static finalized history + a live streaming pane. Ink's <Static> renders
|
|
7
|
+
* each item exactly once, so a 200-message session doesn't repaint the
|
|
8
|
+
* scrollback on every token of the in-progress assistant reply.
|
|
9
|
+
*
|
|
10
|
+
* Threads the live terminal width down to Message so its body pre-wraps
|
|
11
|
+
* at word boundaries — see ui/wrap.ts for why we want manual wrap.
|
|
12
|
+
*/
|
|
13
|
+
export function MessageList({ messages, streaming }) {
|
|
14
|
+
const width = useTerminalWidth();
|
|
15
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Static, { items: messages.map((message, index) => ({ message, key: indexKey(message, index) })), children: ({ message, key }) => (_jsx(Box, { marginBottom: 1, children: _jsx(Message, { message: message, width: width }) }, key)) }), streaming ? (_jsx(Box, { marginBottom: 1, children: _jsx(Message, { message: streaming, streaming: true, width: width }) })) : null] }));
|
|
16
|
+
}
|
|
17
|
+
function useTerminalWidth(fallback = 80) {
|
|
18
|
+
const { stdout } = useStdout();
|
|
19
|
+
const [width, setWidth] = useState(stdout?.columns ?? fallback);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (!stdout)
|
|
22
|
+
return;
|
|
23
|
+
const onResize = () => setWidth(stdout.columns ?? fallback);
|
|
24
|
+
stdout.on("resize", onResize);
|
|
25
|
+
return () => {
|
|
26
|
+
stdout.off("resize", onResize);
|
|
27
|
+
};
|
|
28
|
+
}, [stdout, fallback]);
|
|
29
|
+
return width;
|
|
30
|
+
}
|
|
31
|
+
function indexKey(message, index) {
|
|
32
|
+
const ts = "timestamp" in message && typeof message.timestamp === "number" ? message.timestamp : 0;
|
|
33
|
+
return `${index}:${message.role}:${ts}`;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=MessageList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageList.js","sourceRoot":"","sources":["../../src/ui/MessageList.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAOvC;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAoB;IACpE,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,OAAO,CACN,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aAC1B,KAAC,MAAM,IAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,YAC3F,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CACtB,KAAC,GAAG,IAAW,YAAY,EAAE,CAAC,YAC7B,KAAC,OAAO,IAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAI,IADlC,GAAG,CAEP,CACN,GACO,EACR,SAAS,CAAC,CAAC,CAAC,CACZ,KAAC,GAAG,IAAC,YAAY,EAAE,CAAC,YACnB,KAAC,OAAO,IAAC,OAAO,EAAE,SAAS,EAAE,SAAS,QAAC,KAAK,EAAE,KAAK,GAAI,GAClD,CACN,CAAC,CAAC,CAAC,IAAI,IACH,CACN,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAQ,GAAG,EAAE;IACtC,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IAC/B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,OAAO,IAAI,QAAQ,CAAC,CAAC;IAChE,SAAS,CAAC,GAAG,EAAE;QACd,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,IAAI,QAAQ,CAAC,CAAC;QAC5D,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC9B,OAAO,GAAG,EAAE;YACX,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAChC,CAAC,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IACvB,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,QAAQ,CAAC,OAAqB,EAAE,KAAa;IACrD,MAAM,EAAE,GAAG,WAAW,IAAI,OAAO,IAAI,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACnG,OAAO,GAAG,KAAK,IAAI,OAAO,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text, useInput } from "ink";
|
|
3
|
+
const RISK_COLOR = {
|
|
4
|
+
low: "yellow",
|
|
5
|
+
medium: "yellow",
|
|
6
|
+
high: "red",
|
|
7
|
+
};
|
|
8
|
+
const RISK_GLYPH = {
|
|
9
|
+
low: "?",
|
|
10
|
+
medium: "!",
|
|
11
|
+
high: "‼",
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Modal-ish prompt that takes over the input row while a tool call
|
|
15
|
+
* awaits user approval. Single-keystroke responses keep it fast:
|
|
16
|
+
* y → allow once t → trust this tool for the session
|
|
17
|
+
* a → trust everything n / Esc → deny
|
|
18
|
+
*/
|
|
19
|
+
export function Permission({ request, onRespond }) {
|
|
20
|
+
useInput((input, key) => {
|
|
21
|
+
if (key.escape) {
|
|
22
|
+
onRespond("deny");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const ch = input.toLowerCase();
|
|
26
|
+
if (ch === "y")
|
|
27
|
+
onRespond("allow-once");
|
|
28
|
+
else if (ch === "n")
|
|
29
|
+
onRespond("deny");
|
|
30
|
+
else if (ch === "t")
|
|
31
|
+
onRespond("trust-tool");
|
|
32
|
+
else if (ch === "a")
|
|
33
|
+
onRespond("trust-all");
|
|
34
|
+
});
|
|
35
|
+
const color = RISK_COLOR[request.risk];
|
|
36
|
+
const glyph = RISK_GLYPH[request.risk];
|
|
37
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, marginY: 0, children: [_jsxs(Box, { children: [_jsxs(Text, { color: color, bold: true, children: [glyph, " permission"] }), _jsx(Text, { children: " " }), _jsx(Text, { children: request.summary })] }), request.detail ? (_jsx(Box, { marginLeft: 2, marginY: 0, children: _jsx(Text, { dimColor: true, children: request.detail }) })) : null, _jsx(Box, { marginTop: 0, children: _jsxs(Text, { dimColor: true, children: ["[", _jsx(Text, { color: "green", children: "y" }), "]es \u00B7 [", _jsx(Text, { color: "cyan", children: "t" }), "]rust this tool \u00B7 [", _jsx(Text, { color: "cyan", children: "a" }), "]ll \u00B7 [", _jsx(Text, { color: "red", children: "n" }), "]o"] }) })] }));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=Permission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Permission.js","sourceRoot":"","sources":["../../src/ui/Permission.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAQ1C,MAAM,UAAU,GAA8C;IAC7D,GAAG,EAAE,QAAQ;IACb,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,KAAK;CACX,CAAC;AAEF,MAAM,UAAU,GAA8C;IAC7D,GAAG,EAAE,GAAG;IACR,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,GAAG;CACT,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,OAAO,EAAE,SAAS,EAAmB;IACjE,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACvB,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YAChB,SAAS,CAAC,MAAM,CAAC,CAAC;YAClB,OAAO;QACR,CAAC;QACD,MAAM,EAAE,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QAC/B,IAAI,EAAE,KAAK,GAAG;YAAE,SAAS,CAAC,YAAY,CAAC,CAAC;aACnC,IAAI,EAAE,KAAK,GAAG;YAAE,SAAS,CAAC,MAAM,CAAC,CAAC;aAClC,IAAI,EAAE,KAAK,GAAG;YAAE,SAAS,CAAC,YAAY,CAAC,CAAC;aACxC,IAAI,EAAE,KAAK,GAAG;YAAE,SAAS,CAAC,WAAW,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvC,OAAO,CACN,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,aAClD,MAAC,GAAG,eACH,MAAC,IAAI,IAAC,KAAK,EAAE,KAAK,EAAE,IAAI,mBACtB,KAAK,mBACA,EACP,KAAC,IAAI,oBAAS,EACd,KAAC,IAAI,cAAE,OAAO,CAAC,OAAO,GAAQ,IACzB,EACL,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CACjB,KAAC,GAAG,IAAC,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,YAC7B,KAAC,IAAI,IAAC,QAAQ,kBAAE,OAAO,CAAC,MAAM,GAAQ,GACjC,CACN,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YAChB,MAAC,IAAI,IAAC,QAAQ,wBACZ,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,kBAAS,kBAAO,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,kBAAS,8BAC/D,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,kBAAS,kBAAO,KAAC,IAAI,IAAC,KAAK,EAAC,KAAK,kBAAS,UACtD,GACF,IACD,CACN,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import { Throbber } from "./Throbber.js";
|
|
4
|
+
const STATUS_LABEL = {
|
|
5
|
+
idle: "ready",
|
|
6
|
+
thinking: "thinking",
|
|
7
|
+
streaming: "responding",
|
|
8
|
+
tool: "tool",
|
|
9
|
+
aborted: "aborted",
|
|
10
|
+
error: "error",
|
|
11
|
+
};
|
|
12
|
+
const STATUS_COLOR = {
|
|
13
|
+
idle: "green",
|
|
14
|
+
thinking: "yellow",
|
|
15
|
+
streaming: "cyan",
|
|
16
|
+
tool: "magenta",
|
|
17
|
+
aborted: "red",
|
|
18
|
+
error: "red",
|
|
19
|
+
};
|
|
20
|
+
export function Status({ state }) {
|
|
21
|
+
const busy = state.status === "thinking" || state.status === "streaming" || state.status === "tool";
|
|
22
|
+
const label = STATUS_LABEL[state.status];
|
|
23
|
+
const color = STATUS_COLOR[state.status];
|
|
24
|
+
const u = state.usage;
|
|
25
|
+
return (_jsxs(Box, { flexDirection: "column", children: [state.error ? (_jsx(Box, { paddingX: 1, children: _jsxs(Text, { color: "red", children: ["! ", state.error] }) })) : null, _jsxs(Box, { paddingX: 1, justifyContent: "space-between", children: [_jsxs(Box, { children: [busy ? (_jsxs(_Fragment, { children: [_jsx(Throbber, { color: color }), _jsx(Text, { children: " " })] })) : null, _jsx(Text, { color: color, children: label })] }), _jsx(Box, { children: _jsxs(Text, { dimColor: true, children: [state.model.provider, "/", state.model.id, " \u00B7 \u2193", u.input, " \u2191", u.output, " $", formatCost(u.cost.total)] }) })] })] }));
|
|
26
|
+
}
|
|
27
|
+
function formatCost(value) {
|
|
28
|
+
if (value === 0)
|
|
29
|
+
return "0.0000";
|
|
30
|
+
if (value < 0.01)
|
|
31
|
+
return value.toFixed(4);
|
|
32
|
+
return value.toFixed(2);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=Status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Status.js","sourceRoot":"","sources":["../../src/ui/Status.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAMzC,MAAM,YAAY,GAAwC;IACzD,IAAI,EAAE,OAAO;IACb,QAAQ,EAAE,UAAU;IACpB,SAAS,EAAE,YAAY;IACvB,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;CACd,CAAC;AAEF,MAAM,YAAY,GAAwC;IACzD,IAAI,EAAE,OAAO;IACb,QAAQ,EAAE,QAAQ;IAClB,SAAS,EAAE,MAAM;IACjB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;IACd,KAAK,EAAE,KAAK;CACZ,CAAC;AAEF,MAAM,UAAU,MAAM,CAAC,EAAE,KAAK,EAAe;IAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,KAAK,UAAU,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC;IACpG,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;IAEtB,OAAO,CACN,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CACd,KAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,YACf,MAAC,IAAI,IAAC,KAAK,EAAC,KAAK,mBAAI,KAAK,CAAC,KAAK,IAAQ,GACnC,CACN,CAAC,CAAC,CAAC,IAAI,EACR,MAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,EAAE,cAAc,EAAC,eAAe,aAC/C,MAAC,GAAG,eACF,IAAI,CAAC,CAAC,CAAC,CACP,8BACC,KAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,GAAI,EAC1B,KAAC,IAAI,oBAAS,IACZ,CACH,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,YAAG,KAAK,GAAQ,IAC7B,EACN,KAAC,GAAG,cACH,MAAC,IAAI,IAAC,QAAQ,mBACZ,KAAK,CAAC,KAAK,CAAC,QAAQ,OAAG,KAAK,CAAC,KAAK,CAAC,EAAE,oBAAM,CAAC,CAAC,KAAK,aAAI,CAAC,CAAC,MAAM,QAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IACrF,GACF,IACD,IACD,CACN,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAChC,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IACjC,IAAI,KAAK,GAAG,IAAI;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1C,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
const STATUS_GLYPH = {
|
|
4
|
+
in_progress: "▶",
|
|
5
|
+
pending: "○",
|
|
6
|
+
completed: "✓",
|
|
7
|
+
cancelled: "✗",
|
|
8
|
+
};
|
|
9
|
+
const STATUS_COLOR = {
|
|
10
|
+
in_progress: "magenta",
|
|
11
|
+
pending: undefined,
|
|
12
|
+
completed: "green",
|
|
13
|
+
cancelled: "red",
|
|
14
|
+
};
|
|
15
|
+
const STATUS_ORDER = {
|
|
16
|
+
in_progress: 0,
|
|
17
|
+
pending: 1,
|
|
18
|
+
completed: 2,
|
|
19
|
+
cancelled: 3,
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Sticky panel showing the agent's task checklist. Renders nothing
|
|
23
|
+
* when no non-cancelled tasks exist so it doesn't waste a row on an
|
|
24
|
+
* empty session. In-progress tasks show their activeForm (verb-ing
|
|
25
|
+
* label) when supplied — that's the "Adding OAuth refresh" UX rather
|
|
26
|
+
* than the imperative "Add OAuth refresh".
|
|
27
|
+
*/
|
|
28
|
+
export function TaskPanel({ tasks, maxVisible = 8 }) {
|
|
29
|
+
const visibleSet = tasks.filter((t) => t.status !== "cancelled");
|
|
30
|
+
if (visibleSet.length === 0)
|
|
31
|
+
return null;
|
|
32
|
+
const sorted = [...visibleSet].sort((a, b) => STATUS_ORDER[a.status] - STATUS_ORDER[b.status]);
|
|
33
|
+
const shown = sorted.slice(0, maxVisible);
|
|
34
|
+
const hidden = sorted.length - shown.length;
|
|
35
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [_jsx(Text, { bold: true, dimColor: true, children: "tasks" }), shown.map((task) => (_jsx(TaskLine, { task: task }, task.id))), hidden > 0 ? _jsx(Text, { dimColor: true, children: ` …+${hidden} more` }) : null] }));
|
|
36
|
+
}
|
|
37
|
+
function TaskLine({ task }) {
|
|
38
|
+
const glyph = STATUS_GLYPH[task.status];
|
|
39
|
+
const color = STATUS_COLOR[task.status];
|
|
40
|
+
const label = task.status === "in_progress" && task.activeForm ? task.activeForm : task.title;
|
|
41
|
+
return (_jsx(Box, { children: _jsxs(Text, { color: color, children: [glyph, " ", label] }) }));
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=TaskPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskPanel.js","sourceRoot":"","sources":["../../src/ui/TaskPanel.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAShC,MAAM,YAAY,GAA+B;IAChD,WAAW,EAAE,GAAG;IAChB,OAAO,EAAE,GAAG;IACZ,SAAS,EAAE,GAAG;IACd,SAAS,EAAE,GAAG;CACd,CAAC;AAEF,MAAM,YAAY,GAA2C;IAC5D,WAAW,EAAE,SAAS;IACtB,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,OAAO;IAClB,SAAS,EAAE,KAAK;CAChB,CAAC;AAEF,MAAM,YAAY,GAA+B;IAChD,WAAW,EAAE,CAAC;IACd,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,CAAC;IACZ,SAAS,EAAE,CAAC;CACZ,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,EAAE,KAAK,EAAE,UAAU,GAAG,CAAC,EAAkB;IAClE,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;IACjE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/F,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAE5C,OAAO,CACN,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,aACvD,KAAC,IAAI,IAAC,IAAI,QAAC,QAAQ,4BAEZ,EACN,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACpB,KAAC,QAAQ,IAAe,IAAI,EAAE,IAAI,IAAnB,IAAI,CAAC,EAAE,CAAgB,CACtC,CAAC,EACD,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAC,IAAI,IAAC,QAAQ,kBAAE,OAAO,MAAM,OAAO,GAAQ,CAAC,CAAC,CAAC,IAAI,IAC5D,CACN,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,EAAE,IAAI,EAAkB;IACzC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,KAAK,aAAa,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;IAC9F,OAAO,CACN,KAAC,GAAG,cACH,MAAC,IAAI,IAAC,KAAK,EAAE,KAAK,aAChB,KAAK,OAAG,KAAK,IACR,GACF,CACN,CAAC;AACH,CAAC"}
|