@sortedyuan/maybecode 0.3.2 → 0.5.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/README.md +166 -55
- package/README.zh-CN.md +267 -0
- package/dist/application.d.ts +40 -34
- package/dist/application.d.ts.map +1 -1
- package/dist/application.js +290 -170
- package/dist/application.js.map +1 -1
- package/dist/args.d.ts +2 -2
- package/dist/args.d.ts.map +1 -1
- package/dist/args.js +50 -27
- package/dist/args.js.map +1 -1
- package/dist/bin.js +82 -71
- package/dist/bin.js.map +4 -4
- package/dist/cli/chunk-3IORPKBL.js +3572 -0
- package/dist/cli/chunk-3IORPKBL.js.map +7 -0
- package/dist/cli/{chunk-LVTRXPDS.js → chunk-4B2Z6KW7.js} +1547 -1536
- package/dist/cli/chunk-4B2Z6KW7.js.map +7 -0
- package/dist/cli/{chunk-JT6VBKOM.js → chunk-4WG6JIJJ.js} +127 -33
- package/dist/cli/{chunk-JT6VBKOM.js.map → chunk-4WG6JIJJ.js.map} +3 -3
- package/dist/cli/{chunk-K5JWPNSY.js → chunk-5SLWALZK.js} +3521 -16164
- package/dist/cli/chunk-5SLWALZK.js.map +7 -0
- package/dist/cli/chunk-MNBYXL5Y.js +132 -0
- package/dist/cli/chunk-MNBYXL5Y.js.map +7 -0
- package/dist/cli/{chunk-F4XRPLUM.js → chunk-SLWLUEHQ.js} +226 -86
- package/dist/cli/chunk-SLWLUEHQ.js.map +7 -0
- package/dist/cli/chunk-UQDZ55LQ.js +199 -0
- package/dist/cli/chunk-UQDZ55LQ.js.map +7 -0
- package/dist/cli/{chunk-7ISOHFS7.js → chunk-WMSG5ZTR.js} +717 -388
- package/dist/cli/chunk-WMSG5ZTR.js.map +7 -0
- package/dist/cli/chunk-WVIRS76R.js +4057 -0
- package/dist/cli/chunk-WVIRS76R.js.map +7 -0
- package/dist/cli/{chunk-HOU5ITUK.js → chunk-XTEMRAQW.js} +1 -1
- package/dist/cli/chunk-XTEMRAQW.js.map +7 -0
- package/dist/cli/chunk-Z3BOPBVU.js +91 -0
- package/dist/cli/chunk-Z3BOPBVU.js.map +7 -0
- package/dist/cli/{configured-WHY3GGAJ.js → configured-ACNM6TRQ.js} +10 -9
- package/dist/cli/{file-type-R2T7TBHI.js → file-type-HLHPV7WC.js} +817 -13
- package/dist/cli/file-type-HLHPV7WC.js.map +7 -0
- package/dist/cli/mcp-auth-XD5U7WCV.js +74 -0
- package/dist/cli/mcp-auth-XD5U7WCV.js.map +7 -0
- package/dist/cli/onboarding-WQWCPYEO.js +530 -0
- package/dist/cli/onboarding-WQWCPYEO.js.map +7 -0
- package/dist/cli/onboarding-check-HRRI5OJ7.js +32 -0
- package/dist/cli/onboarding-check-HRRI5OJ7.js.map +7 -0
- package/dist/cli/{retained-tui-VJ3VX4R3.js → retained-tui-QF5VMYLC.js} +788 -332
- package/dist/cli/retained-tui-QF5VMYLC.js.map +7 -0
- package/dist/cli/{sixel-LWTCM76G.js → sixel-ISZ4FZ3U.js} +37 -37
- package/dist/cli/{sixel-LWTCM76G.js.map → sixel-ISZ4FZ3U.js.map} +1 -1
- package/dist/cli/{team-T7G7PPNN.js → team-O2I5BXHM.js} +7 -6
- package/dist/cli/{team-v2-JGBBQ7FR.js → team-v2-YYO2G7DJ.js} +816 -390
- package/dist/cli/team-v2-YYO2G7DJ.js.map +7 -0
- package/dist/cli/{web-server-FOMNPY7Q.js → web-server-SXMH6FGA.js} +55 -19
- package/dist/cli/web-server-SXMH6FGA.js.map +7 -0
- package/dist/cli/{web-ui-COB6PKC5.js → web-ui-UWQUFE4W.js} +7 -6
- package/dist/config-schema.json +337 -0
- package/dist/configured.d.ts +18 -11
- package/dist/configured.d.ts.map +1 -1
- package/dist/configured.js +213 -390
- package/dist/configured.js.map +1 -1
- package/dist/controller.d.ts +19 -18
- package/dist/controller.d.ts.map +1 -1
- package/dist/delegation-commands.d.ts +1 -1
- package/dist/delegation-commands.d.ts.map +1 -1
- package/dist/delegation-commands.js +8 -8
- package/dist/delegation-commands.js.map +1 -1
- package/dist/errors.d.ts +2 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +2 -1
- package/dist/errors.js.map +1 -1
- package/dist/events.d.ts +8 -6
- package/dist/events.d.ts.map +1 -1
- package/dist/fork-picker.d.ts.map +1 -1
- package/dist/fork-picker.js +19 -5
- package/dist/fork-picker.js.map +1 -1
- package/dist/git-request.d.ts +6 -6
- package/dist/git-request.d.ts.map +1 -1
- package/dist/git-request.js +28 -15
- package/dist/git-request.js.map +1 -1
- package/dist/goal-commands.d.ts +1 -1
- package/dist/goal-commands.d.ts.map +1 -1
- package/dist/goal-commands.js +12 -5
- package/dist/goal-commands.js.map +1 -1
- package/dist/index.d.ts +5 -37
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -36
- package/dist/index.js.map +1 -1
- package/dist/instructions.d.ts +2 -7
- package/dist/instructions.d.ts.map +1 -1
- package/dist/instructions.js +7 -15
- package/dist/instructions.js.map +1 -1
- package/dist/keymap.d.ts +2 -2
- package/dist/keymap.d.ts.map +1 -1
- package/dist/keymap.js +2 -2
- package/dist/keymap.js.map +1 -1
- package/dist/maybecode-config.schema.json +1765 -0
- package/dist/mcp-auth.d.ts +1 -1
- package/dist/mcp-auth.d.ts.map +1 -1
- package/dist/mcp-auth.js +11 -8
- package/dist/mcp-auth.js.map +1 -1
- package/dist/mcp-commands.d.ts.map +1 -1
- package/dist/mcp-commands.js +18 -4
- package/dist/mcp-commands.js.map +1 -1
- package/dist/mcp-interaction-ui.d.ts.map +1 -1
- package/dist/mcp-interaction-ui.js +11 -4
- package/dist/mcp-interaction-ui.js.map +1 -1
- package/dist/media-history.d.ts +1 -1
- package/dist/media-history.d.ts.map +1 -1
- package/dist/media-history.js +8 -2
- package/dist/media-history.js.map +1 -1
- package/dist/model-picker.d.ts.map +1 -1
- package/dist/model-picker.js +10 -11
- package/dist/model-picker.js.map +1 -1
- package/dist/model-transition.d.ts +11 -0
- package/dist/model-transition.d.ts.map +1 -0
- package/dist/model-transition.js +48 -0
- package/dist/model-transition.js.map +1 -0
- package/dist/model.d.ts +2 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +8 -4
- package/dist/model.js.map +1 -1
- package/dist/onboarding-check.d.ts +3 -0
- package/dist/onboarding-check.d.ts.map +1 -0
- package/dist/onboarding-check.js +22 -0
- package/dist/onboarding-check.js.map +1 -0
- package/dist/onboarding.d.ts +6 -0
- package/dist/onboarding.d.ts.map +1 -0
- package/dist/onboarding.js +463 -0
- package/dist/onboarding.js.map +1 -0
- package/dist/plugins/application.d.ts +6 -4
- package/dist/plugins/application.d.ts.map +1 -1
- package/dist/plugins/application.js +106 -52
- package/dist/plugins/application.js.map +1 -1
- package/dist/plugins/instructions.d.ts +1 -1
- package/dist/plugins/instructions.d.ts.map +1 -1
- package/dist/plugins/instructions.js +24 -11
- package/dist/plugins/instructions.js.map +1 -1
- package/dist/plugins/resources.d.ts +2 -2
- package/dist/plugins/resources.d.ts.map +1 -1
- package/dist/plugins/resources.js +22 -12
- package/dist/plugins/resources.js.map +1 -1
- package/dist/policy.d.ts +1 -1
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +59 -11
- package/dist/policy.js.map +1 -1
- package/dist/run.d.ts +2 -0
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +38 -33
- package/dist/run.js.map +1 -1
- package/dist/runtime-instructions.d.ts +1 -1
- package/dist/runtime-instructions.d.ts.map +1 -1
- package/dist/runtime-instructions.js +15 -7
- package/dist/runtime-instructions.js.map +1 -1
- package/dist/session-navigation.d.ts +6 -0
- package/dist/session-navigation.d.ts.map +1 -0
- package/dist/session-navigation.js +64 -0
- package/dist/session-navigation.js.map +1 -0
- package/dist/session-picker.d.ts +1 -1
- package/dist/session-picker.d.ts.map +1 -1
- package/dist/session-picker.js +23 -32
- package/dist/session-picker.js.map +1 -1
- package/dist/settings.d.ts +718 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +14 -0
- package/dist/settings.js.map +1 -0
- package/dist/skills.d.ts +1 -1
- package/dist/skills.d.ts.map +1 -1
- package/dist/skills.js +10 -12
- package/dist/skills.js.map +1 -1
- package/dist/slash-commands.d.ts +2 -2
- package/dist/slash-commands.d.ts.map +1 -1
- package/dist/slash-commands.js +149 -67
- package/dist/slash-commands.js.map +1 -1
- package/dist/team-execution.d.ts +10 -0
- package/dist/team-execution.d.ts.map +1 -0
- package/dist/team-execution.js +29 -0
- package/dist/team-execution.js.map +1 -0
- package/dist/team-patches.d.ts.map +1 -1
- package/dist/team-patches.js +149 -52
- package/dist/team-patches.js.map +1 -1
- package/dist/team-plan.d.ts +2 -2
- package/dist/team-plan.d.ts.map +1 -1
- package/dist/team-plan.js +115 -34
- package/dist/team-plan.js.map +1 -1
- package/dist/team-recovery.d.ts +1 -1
- package/dist/team-recovery.d.ts.map +1 -1
- package/dist/team-recovery.js +40 -10
- package/dist/team-recovery.js.map +1 -1
- package/dist/team-v2.d.ts.map +1 -1
- package/dist/team-v2.js +335 -104
- package/dist/team-v2.js.map +1 -1
- package/dist/team-verification.d.ts +4 -2
- package/dist/team-verification.d.ts.map +1 -1
- package/dist/team-verification.js +300 -97
- package/dist/team-verification.js.map +1 -1
- package/dist/team.d.ts +2 -2
- package/dist/team.d.ts.map +1 -1
- package/dist/team.js +172 -62
- package/dist/team.js.map +1 -1
- package/dist/terminal-web.d.ts +1 -0
- package/dist/terminal-web.d.ts.map +1 -1
- package/dist/terminal-web.js +28 -10
- package/dist/terminal-web.js.map +1 -1
- package/dist/ui/actions.d.ts.map +1 -1
- package/dist/ui/actions.js.map +1 -1
- package/dist/ui/retained-tui.d.ts.map +1 -1
- package/dist/ui/retained-tui.js +231 -173
- package/dist/ui/retained-tui.js.map +1 -1
- package/dist/ui/{prototype-view.d.ts → terminal-view.d.ts} +7 -7
- package/dist/ui/terminal-view.d.ts.map +1 -0
- package/dist/ui/{prototype-view.js → terminal-view.js} +185 -98
- package/dist/ui/terminal-view.js.map +1 -0
- package/dist/web-commands.d.ts.map +1 -1
- package/dist/web-commands.js +160 -57
- package/dist/web-commands.js.map +1 -1
- package/dist/web-extension.d.ts.map +1 -1
- package/dist/web-extension.js +14 -4
- package/dist/web-extension.js.map +1 -1
- package/dist/web-server.d.ts.map +1 -1
- package/dist/web-server.js +2 -1
- package/dist/web-server.js.map +1 -1
- package/dist/web-ui.d.ts.map +1 -1
- package/dist/web-ui.js +167 -40
- package/dist/web-ui.js.map +1 -1
- package/dist/workspace-configuration.d.ts +7 -0
- package/dist/workspace-configuration.d.ts.map +1 -0
- package/dist/workspace-configuration.js +134 -0
- package/dist/workspace-configuration.js.map +1 -0
- package/dist/workspace-state.d.ts +20 -0
- package/dist/workspace-state.d.ts.map +1 -0
- package/dist/workspace-state.js +2 -0
- package/dist/workspace-state.js.map +1 -0
- package/dist/workspace.d.ts +26 -43
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +261 -323
- package/dist/workspace.js.map +1 -1
- package/package.json +21 -31
- package/dist/cli/chunk-7ISOHFS7.js.map +0 -7
- package/dist/cli/chunk-F4XRPLUM.js.map +0 -7
- package/dist/cli/chunk-H7SNBFO4.js +0 -5522
- package/dist/cli/chunk-H7SNBFO4.js.map +0 -7
- package/dist/cli/chunk-HOU5ITUK.js.map +0 -7
- package/dist/cli/chunk-K5JWPNSY.js.map +0 -7
- package/dist/cli/chunk-LVTRXPDS.js.map +0 -7
- package/dist/cli/chunk-VAZMCNBB.js +0 -686
- package/dist/cli/chunk-VAZMCNBB.js.map +0 -7
- package/dist/cli/chunk-WOFEI42C.js +0 -7820
- package/dist/cli/chunk-WOFEI42C.js.map +0 -7
- package/dist/cli/file-type-R2T7TBHI.js.map +0 -7
- package/dist/cli/mcp-auth-UNRHSIKJ.js +0 -63
- package/dist/cli/mcp-auth-UNRHSIKJ.js.map +0 -7
- package/dist/cli/retained-tui-VJ3VX4R3.js.map +0 -7
- package/dist/cli/team-v2-JGBBQ7FR.js.map +0 -7
- package/dist/cli/tui-SA74DKMA.js +0 -1705
- package/dist/cli/tui-SA74DKMA.js.map +0 -7
- package/dist/cli/web-server-FOMNPY7Q.js.map +0 -7
- package/dist/delegation.d.ts +0 -2
- package/dist/delegation.d.ts.map +0 -1
- package/dist/delegation.js +0 -2
- package/dist/delegation.js.map +0 -1
- package/dist/history-memory.d.ts +0 -2
- package/dist/history-memory.d.ts.map +0 -1
- package/dist/history-memory.js +0 -2
- package/dist/history-memory.js.map +0 -1
- package/dist/subagent-budget.d.ts +0 -2
- package/dist/subagent-budget.d.ts.map +0 -1
- package/dist/subagent-budget.js +0 -2
- package/dist/subagent-budget.js.map +0 -1
- package/dist/subagent-files.d.ts +0 -2
- package/dist/subagent-files.d.ts.map +0 -1
- package/dist/subagent-files.js +0 -2
- package/dist/subagent-files.js.map +0 -1
- package/dist/subagent-host.d.ts +0 -2
- package/dist/subagent-host.d.ts.map +0 -1
- package/dist/subagent-host.js +0 -2
- package/dist/subagent-host.js.map +0 -1
- package/dist/subagent-instructions.d.ts +0 -2
- package/dist/subagent-instructions.d.ts.map +0 -1
- package/dist/subagent-instructions.js +0 -2
- package/dist/subagent-instructions.js.map +0 -1
- package/dist/subagents.d.ts +0 -2
- package/dist/subagents.d.ts.map +0 -1
- package/dist/subagents.js +0 -2
- package/dist/subagents.js.map +0 -1
- package/dist/summarizer.d.ts +0 -2
- package/dist/summarizer.d.ts.map +0 -1
- package/dist/summarizer.js +0 -2
- package/dist/summarizer.js.map +0 -1
- package/dist/tui.d.ts +0 -7
- package/dist/tui.d.ts.map +0 -1
- package/dist/tui.js +0 -1109
- package/dist/tui.js.map +0 -1
- package/dist/ui/prototype-view.d.ts.map +0 -1
- package/dist/ui/prototype-view.js.map +0 -1
- /package/dist/cli/{configured-WHY3GGAJ.js.map → configured-ACNM6TRQ.js.map} +0 -0
- /package/dist/cli/{team-T7G7PPNN.js.map → team-O2I5BXHM.js.map} +0 -0
- /package/dist/cli/{web-ui-COB6PKC5.js.map → web-ui-UWQUFE4W.js.map} +0 -0
package/dist/cli/tui-SA74DKMA.js
DELETED
|
@@ -1,1705 +0,0 @@
|
|
|
1
|
-
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
ListSelectionModel,
|
|
4
|
-
MaybeCodeTerminalWeb,
|
|
5
|
-
SessionForkPicker,
|
|
6
|
-
TerminalImages,
|
|
7
|
-
WorkspaceDiffViewer,
|
|
8
|
-
createMaybeCodeKeymap,
|
|
9
|
-
encodeImage,
|
|
10
|
-
presentMcpInteraction,
|
|
11
|
-
printableKeyText,
|
|
12
|
-
removeLastCodePoint,
|
|
13
|
-
resolveListInput,
|
|
14
|
-
sanitizeTerminalText,
|
|
15
|
-
workspaceGitLabel
|
|
16
|
-
} from "./chunk-LVTRXPDS.js";
|
|
17
|
-
import {
|
|
18
|
-
createMaybeCodeSlashCommandSuggester,
|
|
19
|
-
executeMaybeCodeSlashCommand,
|
|
20
|
-
formatGoal,
|
|
21
|
-
formatMaybeCodeMcpStatus,
|
|
22
|
-
parseMaybeCodeSlashCommand,
|
|
23
|
-
renderDelegationTask
|
|
24
|
-
} from "./chunk-7ISOHFS7.js";
|
|
25
|
-
import "./chunk-HOU5ITUK.js";
|
|
26
|
-
import {
|
|
27
|
-
createNodeTerminal
|
|
28
|
-
} from "./chunk-JT6VBKOM.js";
|
|
29
|
-
import "./chunk-H7SNBFO4.js";
|
|
30
|
-
import "./chunk-VAZMCNBB.js";
|
|
31
|
-
import "./chunk-K5JWPNSY.js";
|
|
32
|
-
import "./chunk-BSBNNF34.js";
|
|
33
|
-
import {
|
|
34
|
-
__name
|
|
35
|
-
} from "./chunk-E732GDOI.js";
|
|
36
|
-
|
|
37
|
-
// apps/maybecode/src/tui.ts
|
|
38
|
-
import { userInfo } from "node:os";
|
|
39
|
-
|
|
40
|
-
// apps/maybecode/src/model-picker.ts
|
|
41
|
-
async function runModelPicker(options) {
|
|
42
|
-
if (options.models.length === 0) return { type: "empty" };
|
|
43
|
-
if (options.terminal.interactive !== true || options.terminal.readKey === void 0 || options.terminal.renderView === void 0 || options.terminal.closeView === void 0) {
|
|
44
|
-
return runLineModelPicker(options);
|
|
45
|
-
}
|
|
46
|
-
const keymap = createMaybeCodeKeymap();
|
|
47
|
-
const selection = new ListSelectionModel(options.models, {
|
|
48
|
-
initialIndex: Math.max(
|
|
49
|
-
0,
|
|
50
|
-
options.models.findIndex(
|
|
51
|
-
(model) => model.name === options.controller.modelInfo?.profile
|
|
52
|
-
)
|
|
53
|
-
),
|
|
54
|
-
pageSize: 10
|
|
55
|
-
});
|
|
56
|
-
try {
|
|
57
|
-
while (true) {
|
|
58
|
-
options.terminal.renderView(sanitizeTerminalText(renderModelPicker(
|
|
59
|
-
options.models,
|
|
60
|
-
selection.selectedIndex,
|
|
61
|
-
options.controller.modelInfo?.profile
|
|
62
|
-
)));
|
|
63
|
-
const action = resolvePickerAction(
|
|
64
|
-
keymap,
|
|
65
|
-
await options.terminal.readKey()
|
|
66
|
-
);
|
|
67
|
-
if (action === "app.interrupt" || action === "list.cancel") {
|
|
68
|
-
return { type: "cancelled" };
|
|
69
|
-
}
|
|
70
|
-
if (action === "list.accept") {
|
|
71
|
-
return { type: "select", profile: selection.selected.name };
|
|
72
|
-
}
|
|
73
|
-
if (action === "model.default.set") {
|
|
74
|
-
return {
|
|
75
|
-
type: "set-default",
|
|
76
|
-
profile: selection.selected.name
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
const navigation = navigationAction(action);
|
|
80
|
-
if (navigation !== void 0) selection.move(navigation);
|
|
81
|
-
}
|
|
82
|
-
} finally {
|
|
83
|
-
options.terminal.closeView();
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
__name(runModelPicker, "runModelPicker");
|
|
87
|
-
async function runLineModelPicker(options) {
|
|
88
|
-
options.terminal.write(sanitizeTerminalText(`
|
|
89
|
-
${renderLineModelList(
|
|
90
|
-
options.models,
|
|
91
|
-
options.controller.modelInfo?.profile
|
|
92
|
-
)}`));
|
|
93
|
-
const answer = (await options.question(
|
|
94
|
-
"Select a model number/name, or d <selection> to set default (Enter to cancel): "
|
|
95
|
-
)).trim();
|
|
96
|
-
if (answer === "") return { type: "cancelled" };
|
|
97
|
-
const defaultMatch = /^d\s+(.+)$/iu.exec(answer);
|
|
98
|
-
const selection = defaultMatch?.[1] ?? answer;
|
|
99
|
-
const selected = resolveListInput(options.models, selection, (model) => model.name);
|
|
100
|
-
if (selected === void 0) {
|
|
101
|
-
throw new Error(`Unknown model selection: ${selection}`);
|
|
102
|
-
}
|
|
103
|
-
return {
|
|
104
|
-
type: defaultMatch === null ? "select" : "set-default",
|
|
105
|
-
profile: selected.name
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
__name(runLineModelPicker, "runLineModelPicker");
|
|
109
|
-
function resolvePickerAction(keymap, stroke) {
|
|
110
|
-
const result = keymap.resolve(stroke, ["global", "modelPicker", "select"]);
|
|
111
|
-
return result.type === "action" ? result.action : void 0;
|
|
112
|
-
}
|
|
113
|
-
__name(resolvePickerAction, "resolvePickerAction");
|
|
114
|
-
function navigationAction(action) {
|
|
115
|
-
switch (action) {
|
|
116
|
-
case "list.up":
|
|
117
|
-
return "up";
|
|
118
|
-
case "list.down":
|
|
119
|
-
return "down";
|
|
120
|
-
case "list.pageUp":
|
|
121
|
-
return "page-up";
|
|
122
|
-
case "list.pageDown":
|
|
123
|
-
return "page-down";
|
|
124
|
-
case "list.home":
|
|
125
|
-
return "home";
|
|
126
|
-
case "list.end":
|
|
127
|
-
return "end";
|
|
128
|
-
default:
|
|
129
|
-
return void 0;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
__name(navigationAction, "navigationAction");
|
|
133
|
-
function renderModelPicker(models, selectedIndex, currentProfile) {
|
|
134
|
-
const pageSize = 10;
|
|
135
|
-
const start = Math.floor(selectedIndex / pageSize) * pageSize;
|
|
136
|
-
let output = "MaybeCode \u2014 Select model\n\n";
|
|
137
|
-
for (const [offset, model] of models.slice(start, start + pageSize).entries()) {
|
|
138
|
-
const index = start + offset;
|
|
139
|
-
const selected = index === selectedIndex ? ">" : " ";
|
|
140
|
-
const current = model.name === currentProfile ? " [current]" : "";
|
|
141
|
-
const defaultModel = model.isDefault ? " [default]" : "";
|
|
142
|
-
output += `${selected} ${model.name}${current}${defaultModel}
|
|
143
|
-
${model.provider}/${model.model} \xB7 ${model.adapter}
|
|
144
|
-
`;
|
|
145
|
-
}
|
|
146
|
-
return output + "\n\u2191\u2193 move \xB7 Enter select \xB7 D set default \xB7 Esc close\n";
|
|
147
|
-
}
|
|
148
|
-
__name(renderModelPicker, "renderModelPicker");
|
|
149
|
-
function renderLineModelList(models, currentProfile) {
|
|
150
|
-
const lines = models.map((model, index) => {
|
|
151
|
-
const current = model.name === currentProfile ? " [current]" : "";
|
|
152
|
-
const defaultModel = model.isDefault ? " [default]" : "";
|
|
153
|
-
return ` ${index + 1}. ${model.name}${current}${defaultModel}
|
|
154
|
-
${model.provider}/${model.model} \xB7 ${model.adapter}`;
|
|
155
|
-
});
|
|
156
|
-
return `Models:
|
|
157
|
-
${lines.join("\n")}
|
|
158
|
-
`;
|
|
159
|
-
}
|
|
160
|
-
__name(renderLineModelList, "renderLineModelList");
|
|
161
|
-
|
|
162
|
-
// apps/maybecode/src/session-picker.ts
|
|
163
|
-
async function runSessionPicker(options) {
|
|
164
|
-
if (options.sessions.length === 0) return { type: "empty" };
|
|
165
|
-
if (options.terminal.interactive !== true || options.terminal.readKey === void 0 || options.terminal.renderView === void 0 || options.terminal.closeView === void 0) {
|
|
166
|
-
return runLineSessionPicker(options);
|
|
167
|
-
}
|
|
168
|
-
const keymap = createMaybeCodeKeymap();
|
|
169
|
-
const selection = new ListSelectionModel(options.sessions, {
|
|
170
|
-
pageSize: 10,
|
|
171
|
-
filter: sessionMatches
|
|
172
|
-
});
|
|
173
|
-
let mode = "browse";
|
|
174
|
-
let renameText = "";
|
|
175
|
-
let preview = false;
|
|
176
|
-
let notice;
|
|
177
|
-
try {
|
|
178
|
-
while (true) {
|
|
179
|
-
const visible = selection.items;
|
|
180
|
-
const selected = selection.selected;
|
|
181
|
-
options.terminal.renderView(sanitizeTerminalText(renderSessionPicker({
|
|
182
|
-
sessions: visible,
|
|
183
|
-
selectedIndex: selection.selectedIndex,
|
|
184
|
-
currentSessionId: options.controller.sessionId,
|
|
185
|
-
mode,
|
|
186
|
-
query: selection.query,
|
|
187
|
-
renameText,
|
|
188
|
-
preview,
|
|
189
|
-
...notice === void 0 ? {} : { notice }
|
|
190
|
-
})));
|
|
191
|
-
notice = void 0;
|
|
192
|
-
const stroke = await options.terminal.readKey();
|
|
193
|
-
const action = resolvePickerAction2(keymap, stroke, mode);
|
|
194
|
-
if (action === void 0) {
|
|
195
|
-
const text = printableKeyText(stroke);
|
|
196
|
-
if (text !== void 0 && mode === "search") {
|
|
197
|
-
selection.appendQuery(text);
|
|
198
|
-
} else if (text !== void 0 && mode === "rename") {
|
|
199
|
-
renameText += text;
|
|
200
|
-
}
|
|
201
|
-
continue;
|
|
202
|
-
}
|
|
203
|
-
if (action === "app.interrupt") return { type: "cancelled" };
|
|
204
|
-
if (mode === "delete") {
|
|
205
|
-
if (action === "session.delete.cancel") {
|
|
206
|
-
mode = "browse";
|
|
207
|
-
keymap.reset();
|
|
208
|
-
} else if (action === "session.delete.accept" && selected !== void 0) {
|
|
209
|
-
try {
|
|
210
|
-
const removed = await options.controller.deleteSession(selected.id);
|
|
211
|
-
selection.setItems(await options.controller.listSessions());
|
|
212
|
-
notice = removed ? `Deleted ${sessionLabel(selected)}` : `Session ${selected.id} no longer exists`;
|
|
213
|
-
} catch (error) {
|
|
214
|
-
notice = errorMessage(error);
|
|
215
|
-
}
|
|
216
|
-
mode = "browse";
|
|
217
|
-
keymap.reset();
|
|
218
|
-
}
|
|
219
|
-
continue;
|
|
220
|
-
}
|
|
221
|
-
if (mode === "rename") {
|
|
222
|
-
if (action === "list.cancel") {
|
|
223
|
-
mode = "browse";
|
|
224
|
-
renameText = "";
|
|
225
|
-
keymap.reset();
|
|
226
|
-
} else if (action === "text.backspace") {
|
|
227
|
-
renameText = removeLastCodePoint(renameText);
|
|
228
|
-
} else if (action === "text.clear") {
|
|
229
|
-
renameText = "";
|
|
230
|
-
} else if (action === "session.rename.accept" && selected !== void 0) {
|
|
231
|
-
try {
|
|
232
|
-
await options.controller.renameSession(selected.id, renameText);
|
|
233
|
-
selection.setItems(await options.controller.listSessions());
|
|
234
|
-
notice = `Renamed session to ${renameText.trim()}`;
|
|
235
|
-
mode = "browse";
|
|
236
|
-
renameText = "";
|
|
237
|
-
} catch (error) {
|
|
238
|
-
notice = errorMessage(error);
|
|
239
|
-
}
|
|
240
|
-
keymap.reset();
|
|
241
|
-
}
|
|
242
|
-
continue;
|
|
243
|
-
}
|
|
244
|
-
if (mode === "search") {
|
|
245
|
-
if (action === "list.cancel") {
|
|
246
|
-
selection.clearQuery();
|
|
247
|
-
mode = "browse";
|
|
248
|
-
keymap.reset();
|
|
249
|
-
} else if (action === "search.finish") {
|
|
250
|
-
mode = "browse";
|
|
251
|
-
keymap.reset();
|
|
252
|
-
} else if (action === "text.backspace") {
|
|
253
|
-
selection.backspaceQuery();
|
|
254
|
-
} else if (action === "text.clear") {
|
|
255
|
-
selection.clearQuery();
|
|
256
|
-
} else {
|
|
257
|
-
const navigation = navigationAction2(action);
|
|
258
|
-
if (navigation !== void 0) selection.move(navigation);
|
|
259
|
-
}
|
|
260
|
-
continue;
|
|
261
|
-
}
|
|
262
|
-
switch (action) {
|
|
263
|
-
case "list.cancel":
|
|
264
|
-
return { type: "cancelled" };
|
|
265
|
-
case "list.accept":
|
|
266
|
-
if (selected !== void 0) {
|
|
267
|
-
return { type: "resume", sessionId: selected.id };
|
|
268
|
-
}
|
|
269
|
-
break;
|
|
270
|
-
case "preview.toggle":
|
|
271
|
-
preview = !preview;
|
|
272
|
-
break;
|
|
273
|
-
case "search.start":
|
|
274
|
-
mode = "search";
|
|
275
|
-
keymap.reset();
|
|
276
|
-
break;
|
|
277
|
-
case "session.rename.start":
|
|
278
|
-
if (selected !== void 0) {
|
|
279
|
-
mode = "rename";
|
|
280
|
-
renameText = selected.title ?? "";
|
|
281
|
-
keymap.reset();
|
|
282
|
-
}
|
|
283
|
-
break;
|
|
284
|
-
case "session.delete.request":
|
|
285
|
-
if (selected?.id === options.controller.sessionId) {
|
|
286
|
-
notice = "The active session cannot be deleted";
|
|
287
|
-
} else if (selected !== void 0) {
|
|
288
|
-
mode = "delete";
|
|
289
|
-
keymap.reset();
|
|
290
|
-
}
|
|
291
|
-
break;
|
|
292
|
-
default: {
|
|
293
|
-
const navigation = navigationAction2(action);
|
|
294
|
-
if (navigation !== void 0) selection.move(navigation);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
} finally {
|
|
299
|
-
options.terminal.closeView();
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
__name(runSessionPicker, "runSessionPicker");
|
|
303
|
-
async function runLineSessionPicker(options) {
|
|
304
|
-
options.terminal.write(sanitizeTerminalText(`
|
|
305
|
-
${renderLineSessionList(
|
|
306
|
-
options.sessions,
|
|
307
|
-
options.controller.sessionId
|
|
308
|
-
)}`));
|
|
309
|
-
const answer = (await options.question(
|
|
310
|
-
"Select a session number or ID (Enter to cancel): "
|
|
311
|
-
)).trim();
|
|
312
|
-
if (answer === "") return { type: "cancelled" };
|
|
313
|
-
const selected = resolveListInput(options.sessions, answer, (session) => session.id);
|
|
314
|
-
if (selected === void 0) {
|
|
315
|
-
throw new Error(`Unknown session selection: ${answer}`);
|
|
316
|
-
}
|
|
317
|
-
return { type: "resume", sessionId: selected.id };
|
|
318
|
-
}
|
|
319
|
-
__name(runLineSessionPicker, "runLineSessionPicker");
|
|
320
|
-
function resolvePickerAction2(keymap, stroke, mode) {
|
|
321
|
-
const contexts = mode === "browse" ? ["global", "select", "sessionPicker"] : mode === "search" ? ["global", "select", "sessionSearch"] : mode === "rename" ? ["global", "sessionRename"] : ["global", "sessionDelete"];
|
|
322
|
-
const result = keymap.resolve(stroke, contexts);
|
|
323
|
-
return result.type === "action" ? result.action : void 0;
|
|
324
|
-
}
|
|
325
|
-
__name(resolvePickerAction2, "resolvePickerAction");
|
|
326
|
-
function navigationAction2(action) {
|
|
327
|
-
switch (action) {
|
|
328
|
-
case "list.up":
|
|
329
|
-
return "up";
|
|
330
|
-
case "list.down":
|
|
331
|
-
return "down";
|
|
332
|
-
case "list.pageUp":
|
|
333
|
-
return "page-up";
|
|
334
|
-
case "list.pageDown":
|
|
335
|
-
return "page-down";
|
|
336
|
-
case "list.home":
|
|
337
|
-
return "home";
|
|
338
|
-
case "list.end":
|
|
339
|
-
return "end";
|
|
340
|
-
default:
|
|
341
|
-
return void 0;
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
__name(navigationAction2, "navigationAction");
|
|
345
|
-
function renderSessionPicker(state) {
|
|
346
|
-
const pageSize = 10;
|
|
347
|
-
const start = Math.floor(state.selectedIndex / pageSize) * pageSize;
|
|
348
|
-
const page = state.sessions.slice(start, start + pageSize);
|
|
349
|
-
let output = "MaybeCode \u2014 Resume session\n\n";
|
|
350
|
-
output += state.query === "" ? "" : `Filter: ${state.query}${state.mode === "search" ? "\u258C" : ""}
|
|
351
|
-
|
|
352
|
-
`;
|
|
353
|
-
if (page.length === 0) {
|
|
354
|
-
output += " No matching sessions.\n";
|
|
355
|
-
} else {
|
|
356
|
-
for (const [offset, session] of page.entries()) {
|
|
357
|
-
const index = start + offset;
|
|
358
|
-
const selected2 = index === state.selectedIndex ? ">" : " ";
|
|
359
|
-
const current = session.id === state.currentSessionId ? " [current]" : "";
|
|
360
|
-
output += `${selected2} ${sessionLabel(session)}${current}
|
|
361
|
-
`;
|
|
362
|
-
output += ` ${relativeTime(session.lastUsedAt)} \xB7 ${session.turnCount ?? 0} turns \xB7 ${session.id}
|
|
363
|
-
`;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
const selected = state.sessions[state.selectedIndex];
|
|
367
|
-
if (state.preview && selected !== void 0) {
|
|
368
|
-
output += `
|
|
369
|
-
Preview
|
|
370
|
-
created: ${new Date(selected.createdAt).toLocaleString()}
|
|
371
|
-
last used: ${new Date(selected.lastUsedAt).toLocaleString()}
|
|
372
|
-
${selected.preview ?? "No message preview available."}
|
|
373
|
-
`;
|
|
374
|
-
}
|
|
375
|
-
if (state.mode === "rename") {
|
|
376
|
-
output += `
|
|
377
|
-
Rename session
|
|
378
|
-
${state.renameText}\u258C
|
|
379
|
-
Enter save \xB7 Esc cancel \xB7 Ctrl+U clear
|
|
380
|
-
`;
|
|
381
|
-
} else if (state.mode === "delete" && selected !== void 0) {
|
|
382
|
-
output += `
|
|
383
|
-
Delete \u201C${sessionLabel(selected)}\u201D? This also removes its durable history.
|
|
384
|
-
Y delete \xB7 N/Esc cancel
|
|
385
|
-
`;
|
|
386
|
-
} else if (state.mode === "search") {
|
|
387
|
-
output += "\nType to filter \xB7 Enter finish \xB7 Esc close and clear search\n";
|
|
388
|
-
} else {
|
|
389
|
-
output += "\n\u2191\u2193 move \xB7 Enter resume \xB7 / search \xB7 Space preview \xB7 R rename \xB7 D delete \xB7 Esc close\n";
|
|
390
|
-
}
|
|
391
|
-
if (state.notice !== void 0) output += `
|
|
392
|
-
${state.notice}
|
|
393
|
-
`;
|
|
394
|
-
return output;
|
|
395
|
-
}
|
|
396
|
-
__name(renderSessionPicker, "renderSessionPicker");
|
|
397
|
-
function renderLineSessionList(sessions, currentSessionId) {
|
|
398
|
-
const lines = sessions.map((session, index) => {
|
|
399
|
-
const current = session.id === currentSessionId ? " [current]" : "";
|
|
400
|
-
return ` ${index + 1}. ${sessionLabel(session)}${current}
|
|
401
|
-
${relativeTime(session.lastUsedAt)} \xB7 ${session.id}`;
|
|
402
|
-
});
|
|
403
|
-
return `Resume a session:
|
|
404
|
-
${lines.join("\n")}
|
|
405
|
-
`;
|
|
406
|
-
}
|
|
407
|
-
__name(renderLineSessionList, "renderLineSessionList");
|
|
408
|
-
function sessionMatches(session, normalizedQuery) {
|
|
409
|
-
return [session.id, sessionLabel(session), session.preview].some((value) => value?.toLowerCase().includes(normalizedQuery) === true);
|
|
410
|
-
}
|
|
411
|
-
__name(sessionMatches, "sessionMatches");
|
|
412
|
-
function sessionLabel(session) {
|
|
413
|
-
return session.title ?? "Untitled session";
|
|
414
|
-
}
|
|
415
|
-
__name(sessionLabel, "sessionLabel");
|
|
416
|
-
function relativeTime(timestamp) {
|
|
417
|
-
const elapsed = Math.max(0, Date.now() - timestamp);
|
|
418
|
-
if (elapsed < 6e4) return "just now";
|
|
419
|
-
if (elapsed < 36e5) return `${Math.floor(elapsed / 6e4)}m ago`;
|
|
420
|
-
if (elapsed < 864e5) return `${Math.floor(elapsed / 36e5)}h ago`;
|
|
421
|
-
return `${Math.floor(elapsed / 864e5)}d ago`;
|
|
422
|
-
}
|
|
423
|
-
__name(relativeTime, "relativeTime");
|
|
424
|
-
function errorMessage(error) {
|
|
425
|
-
return error instanceof Error ? error.message : String(error);
|
|
426
|
-
}
|
|
427
|
-
__name(errorMessage, "errorMessage");
|
|
428
|
-
|
|
429
|
-
// apps/maybecode/src/fork-picker.ts
|
|
430
|
-
async function runForkPicker(options) {
|
|
431
|
-
if (!options.points.length) {
|
|
432
|
-
options.terminal.write("\n\u6CA1\u6709\u53EF\u9009\u62E9\u7684\u5B8C\u6574\u56DE\u590D\u3002\n");
|
|
433
|
-
return void 0;
|
|
434
|
-
}
|
|
435
|
-
if (!options.terminal.interactive || !options.terminal.readKey || !options.terminal.renderView || !options.terminal.closeView) {
|
|
436
|
-
for (const [index, point2] of options.points.entries()) options.terminal.write(sanitizeTerminalText(`
|
|
437
|
-
${index + 1}. ${point2.userPreview} \xB7 ${point2.commit?.slice(0, 12) ?? "\u65E0\u6587\u4EF6\u7248\u672C"}${point2.available ? "" : ` \xB7 ${point2.reason ?? "\u65E0\u6CD5\u6062\u590D"}`}
|
|
438
|
-
`));
|
|
439
|
-
const answer = (await options.question("\u9009\u62E9\u5386\u53F2\u4F4D\u7F6E\u7F16\u53F7\uFF0C\u76F4\u63A5\u56DE\u8F66\u53D6\u6D88\uFF1A")).trim();
|
|
440
|
-
if (!answer) return void 0;
|
|
441
|
-
const point = options.points[Number(answer) - 1];
|
|
442
|
-
if (!point?.available) throw new Error(point?.reason ?? "\u5386\u53F2\u4F4D\u7F6E\u4E0D\u53EF\u7528\u3002");
|
|
443
|
-
const mode = (await options.question("\u9009\u62E9\u5DE5\u4F5C\u533A\uFF1A1 \u5F53\u524D\u5DE5\u4F5C\u533A\uFF1B2 \u65B0\u5EFA worktree\uFF1B\u76F4\u63A5\u56DE\u8F66\u53D6\u6D88\uFF1A")).trim();
|
|
444
|
-
if (!mode) return void 0;
|
|
445
|
-
if (mode !== "1" && mode !== "2") throw new Error("\u5DE5\u4F5C\u533A\u9009\u62E9\u65E0\u6548\u3002");
|
|
446
|
-
if (mode === "2" && !point.worktreeAvailable) throw new Error("\u5386\u53F2\u6587\u4EF6\u7248\u672C\u4E0D\u53EF\u7528\u4E8E\u521B\u5EFA worktree\u3002");
|
|
447
|
-
return { pointId: point.id, mode: mode === "1" ? "current" : "worktree" };
|
|
448
|
-
}
|
|
449
|
-
let result, complete = false;
|
|
450
|
-
const picker = new SessionForkPicker(options.points, { currentSessionId: options.currentSessionId, onComplete: /* @__PURE__ */ __name((selection) => {
|
|
451
|
-
result = selection;
|
|
452
|
-
complete = true;
|
|
453
|
-
}, "onComplete") });
|
|
454
|
-
await runView(options.terminal, picker, () => complete);
|
|
455
|
-
return result;
|
|
456
|
-
}
|
|
457
|
-
__name(runForkPicker, "runForkPicker");
|
|
458
|
-
async function runChangesPicker(terminal, diff, app) {
|
|
459
|
-
if (!terminal.interactive || !terminal.readKey || !terminal.renderView || !terminal.closeView) {
|
|
460
|
-
terminal.write(sanitizeTerminalText(`
|
|
461
|
-
${diff.title}
|
|
462
|
-
${diff.uncommitted ? "\u5F53\u524D\u672A\u63D0\u4EA4\u53D8\u5316" : `${diff.from ?? ""} \u2192 ${diff.to ?? ""}`}
|
|
463
|
-
`));
|
|
464
|
-
for (const file of diff.files) terminal.write(sanitizeTerminalText(`
|
|
465
|
-
${file.path} \xB7 ${file.status} \xB7 ${file.binary ? "\u4E8C\u8FDB\u5236\u6587\u4EF6" : `+${file.additions} -${file.deletions}
|
|
466
|
-
${file.patch}`}
|
|
467
|
-
`));
|
|
468
|
-
return;
|
|
469
|
-
}
|
|
470
|
-
let complete = false;
|
|
471
|
-
const viewer = new WorkspaceDiffViewer(diff, {
|
|
472
|
-
onClose: /* @__PURE__ */ __name(() => {
|
|
473
|
-
complete = true;
|
|
474
|
-
}, "onClose"),
|
|
475
|
-
...diff.runId && app?.previewRestore ? { onRestore: /* @__PURE__ */ __name(async (path) => (await app.previewRestore(diff.runId, [path])).diff, "onRestore") } : {},
|
|
476
|
-
...app?.restoreFiles ? { onApply: /* @__PURE__ */ __name((previewId) => app.restoreFiles(previewId), "onApply") } : {}
|
|
477
|
-
});
|
|
478
|
-
try {
|
|
479
|
-
while (!complete) {
|
|
480
|
-
terminal.renderView(viewer.render({ width: 100, height: 30 }).lines.join("\n"));
|
|
481
|
-
viewer.handleKey(await terminal.readKey());
|
|
482
|
-
await viewer.waitForPending();
|
|
483
|
-
}
|
|
484
|
-
} finally {
|
|
485
|
-
terminal.closeView();
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
__name(runChangesPicker, "runChangesPicker");
|
|
489
|
-
async function runView(terminal, view, complete) {
|
|
490
|
-
try {
|
|
491
|
-
while (!complete()) {
|
|
492
|
-
terminal.renderView(view.render({ width: 100, height: 30 }).lines.join("\n"));
|
|
493
|
-
view.handleKey(await terminal.readKey());
|
|
494
|
-
}
|
|
495
|
-
} finally {
|
|
496
|
-
terminal.closeView();
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
__name(runView, "runView");
|
|
500
|
-
|
|
501
|
-
// apps/maybecode/src/tui.ts
|
|
502
|
-
async function runTerminalUI(app, options = {}) {
|
|
503
|
-
const terminal = options.terminal ?? createNodeTerminal();
|
|
504
|
-
terminal.imageSupport?.query();
|
|
505
|
-
await terminal.imageSupport?.ready();
|
|
506
|
-
let terminalClosed = false;
|
|
507
|
-
const closeTerminal = /* @__PURE__ */ __name(() => {
|
|
508
|
-
if (terminalClosed) return;
|
|
509
|
-
terminalClosed = true;
|
|
510
|
-
terminal.close();
|
|
511
|
-
}, "closeTerminal");
|
|
512
|
-
const renderer = new TerminalRenderer(terminal);
|
|
513
|
-
const slashCommandSuggestions = createMaybeCodeSlashCommandSuggester(app);
|
|
514
|
-
let activeQuestion;
|
|
515
|
-
let inputQuestionController;
|
|
516
|
-
let inputContinuation = false;
|
|
517
|
-
let gitLabel = "";
|
|
518
|
-
let interactionDone = Promise.resolve();
|
|
519
|
-
const pendingRuns = /* @__PURE__ */ new Set();
|
|
520
|
-
const observeRun = /* @__PURE__ */ __name((result) => {
|
|
521
|
-
const pending = result.then(() => void 0, (error) => {
|
|
522
|
-
if (!terminalClosed && !isCancellation(error)) terminal.write(`
|
|
523
|
-
Error: ${sanitizeTerminalText(errorMessage2(error))}
|
|
524
|
-
`);
|
|
525
|
-
}).finally(() => pendingRuns.delete(pending));
|
|
526
|
-
pendingRuns.add(pending);
|
|
527
|
-
}, "observeRun");
|
|
528
|
-
let exit = false;
|
|
529
|
-
const handleProcessSignal = /* @__PURE__ */ __name(() => {
|
|
530
|
-
exit = true;
|
|
531
|
-
if (app.isRunning) app.cancel("Interrupted by process signal");
|
|
532
|
-
activeQuestion?.abort();
|
|
533
|
-
closeTerminal();
|
|
534
|
-
}, "handleProcessSignal");
|
|
535
|
-
process.on("SIGINT", handleProcessSignal);
|
|
536
|
-
process.on("SIGTERM", handleProcessSignal);
|
|
537
|
-
const question = /* @__PURE__ */ __name(async (prompt, questionOptions = {}) => {
|
|
538
|
-
inputQuestionController?.abort();
|
|
539
|
-
const previousInteraction = interactionDone;
|
|
540
|
-
let release;
|
|
541
|
-
interactionDone = new Promise((resolve) => {
|
|
542
|
-
release = resolve;
|
|
543
|
-
});
|
|
544
|
-
const controller = new AbortController();
|
|
545
|
-
activeQuestion = controller;
|
|
546
|
-
try {
|
|
547
|
-
await previousInteraction;
|
|
548
|
-
return await terminal.question(prompt, {
|
|
549
|
-
...questionOptions,
|
|
550
|
-
signal: questionOptions.signal === void 0 ? controller.signal : AbortSignal.any([controller.signal, questionOptions.signal])
|
|
551
|
-
});
|
|
552
|
-
} finally {
|
|
553
|
-
release();
|
|
554
|
-
if (activeQuestion === controller) activeQuestion = void 0;
|
|
555
|
-
}
|
|
556
|
-
}, "question");
|
|
557
|
-
const inputQuestion = /* @__PURE__ */ __name(async (prompt, questionOptions = {}) => {
|
|
558
|
-
await interactionDone;
|
|
559
|
-
const controller = new AbortController();
|
|
560
|
-
inputQuestionController = controller;
|
|
561
|
-
inputContinuation = prompt.endsWith("... ");
|
|
562
|
-
activeQuestion = controller;
|
|
563
|
-
try {
|
|
564
|
-
return await terminal.question(prompt, { ...questionOptions, signal: controller.signal });
|
|
565
|
-
} finally {
|
|
566
|
-
if (activeQuestion === controller) activeQuestion = void 0;
|
|
567
|
-
if (inputQuestionController === controller) inputQuestionController = void 0;
|
|
568
|
-
}
|
|
569
|
-
}, "inputQuestion");
|
|
570
|
-
const removeInterrupt = terminal.onInterrupt?.(() => {
|
|
571
|
-
if (app.isRunning) {
|
|
572
|
-
terminal.write("\nCancelling current operation...\n");
|
|
573
|
-
app.cancel("Interrupted");
|
|
574
|
-
activeQuestion?.abort();
|
|
575
|
-
} else {
|
|
576
|
-
exit = true;
|
|
577
|
-
activeQuestion?.abort();
|
|
578
|
-
}
|
|
579
|
-
});
|
|
580
|
-
const web = new MaybeCodeTerminalWeb(app, handleProcessSignal);
|
|
581
|
-
const eventTask = consumeEvents(app, renderer, question, web.events, () => {
|
|
582
|
-
if (inputQuestionController !== void 0) terminal.updatePrompt?.(inputPrompt(app.permissionMode === "yolo", inputContinuation, gitLabel));
|
|
583
|
-
});
|
|
584
|
-
const refreshWorkspace = /* @__PURE__ */ __name(async () => {
|
|
585
|
-
if (!app.getWorkspaceGit || terminalClosed) return;
|
|
586
|
-
try {
|
|
587
|
-
gitLabel = workspaceGitLabel(await app.getWorkspaceGit());
|
|
588
|
-
} catch (error) {
|
|
589
|
-
gitLabel = `Git \u9519\u8BEF\uFF1A${sanitizeTerminalText(errorMessage2(error))}`;
|
|
590
|
-
}
|
|
591
|
-
if (inputQuestionController) terminal.updatePrompt?.(inputPrompt(app.permissionMode === "yolo", inputContinuation, gitLabel));
|
|
592
|
-
}, "refreshWorkspace");
|
|
593
|
-
await refreshWorkspace();
|
|
594
|
-
let refreshingWorkspace = false;
|
|
595
|
-
const workspaceTimer = app.getWorkspaceGit ? setInterval(() => {
|
|
596
|
-
if (refreshingWorkspace || terminalClosed) return;
|
|
597
|
-
refreshingWorkspace = true;
|
|
598
|
-
void refreshWorkspace().finally(() => {
|
|
599
|
-
refreshingWorkspace = false;
|
|
600
|
-
});
|
|
601
|
-
}, 2e3) : void 0;
|
|
602
|
-
terminal.write(sanitizeTerminalText(
|
|
603
|
-
`MaybeCode
|
|
604
|
-
Workspace: ${app.workspace}
|
|
605
|
-
Model: ${modelLabel(app)}
|
|
606
|
-
` + (app.permissionMode === "yolo" ? "YOLO \xB7 Auto-approve\n" : "") + `${renderInstructionSources(app)}Type /help for commands. End a line with \\ for multiline input.
|
|
607
|
-
`
|
|
608
|
-
));
|
|
609
|
-
try {
|
|
610
|
-
while (!exit) {
|
|
611
|
-
let input;
|
|
612
|
-
try {
|
|
613
|
-
input = await readInput(inputQuestion, slashCommandSuggestions, () => app.permissionMode === "yolo", () => gitLabel);
|
|
614
|
-
} catch (error) {
|
|
615
|
-
if (isAbortError(error)) {
|
|
616
|
-
if (exit) break;
|
|
617
|
-
continue;
|
|
618
|
-
}
|
|
619
|
-
throw error;
|
|
620
|
-
}
|
|
621
|
-
if (input === "") continue;
|
|
622
|
-
terminal.addHistory?.(input);
|
|
623
|
-
if (input.startsWith("/")) {
|
|
624
|
-
try {
|
|
625
|
-
exit = await handleCommand(input, app, terminal, question, web, observeRun);
|
|
626
|
-
} catch (error) {
|
|
627
|
-
if (!isCancellation(error) && !isAbortError(error)) {
|
|
628
|
-
terminal.write(
|
|
629
|
-
`
|
|
630
|
-
Error: ${sanitizeTerminalText(errorMessage2(error))}
|
|
631
|
-
`
|
|
632
|
-
);
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
continue;
|
|
636
|
-
}
|
|
637
|
-
try {
|
|
638
|
-
const run = await app.submit({ input });
|
|
639
|
-
observeRun(run.result);
|
|
640
|
-
} catch (error) {
|
|
641
|
-
if (!isCancellation(error)) {
|
|
642
|
-
terminal.write(
|
|
643
|
-
`
|
|
644
|
-
Error: ${sanitizeTerminalText(errorMessage2(error))}
|
|
645
|
-
`
|
|
646
|
-
);
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
} finally {
|
|
651
|
-
process.removeListener("SIGINT", handleProcessSignal);
|
|
652
|
-
if (workspaceTimer) clearInterval(workspaceTimer);
|
|
653
|
-
process.removeListener("SIGTERM", handleProcessSignal);
|
|
654
|
-
activeQuestion?.abort();
|
|
655
|
-
removeInterrupt?.();
|
|
656
|
-
closeTerminal();
|
|
657
|
-
await web.close();
|
|
658
|
-
await Promise.all(pendingRuns);
|
|
659
|
-
await eventTask;
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
__name(runTerminalUI, "runTerminalUI");
|
|
663
|
-
async function consumeEvents(app, renderer, question, events, permissionModeChanged) {
|
|
664
|
-
const pending = /* @__PURE__ */ new Map();
|
|
665
|
-
let lastGoalDisplay = "";
|
|
666
|
-
let prompts = Promise.resolve();
|
|
667
|
-
const enqueue = /* @__PURE__ */ __name((id, work, expiresAt) => {
|
|
668
|
-
const controller = new AbortController();
|
|
669
|
-
pending.set(id, controller);
|
|
670
|
-
const signal = expiresAt === void 0 ? controller.signal : AbortSignal.any([controller.signal, AbortSignal.timeout(Math.max(0, Math.ceil(expiresAt - Date.now())))]);
|
|
671
|
-
prompts = prompts.then(async () => {
|
|
672
|
-
if (!signal.aborted) await work(signal);
|
|
673
|
-
}).catch(() => {
|
|
674
|
-
if (!signal.aborted) {
|
|
675
|
-
renderer.write("\nInteraction could not be completed.\n");
|
|
676
|
-
app.cancel("User interaction is unavailable");
|
|
677
|
-
}
|
|
678
|
-
}).finally(() => pending.delete(id));
|
|
679
|
-
}, "enqueue");
|
|
680
|
-
for await (const event of events) {
|
|
681
|
-
if (event.type === "goal.changed") {
|
|
682
|
-
const display = `${event.goal.id}:${event.goal.status}:${event.goal.progress}`;
|
|
683
|
-
if (display !== lastGoalDisplay) {
|
|
684
|
-
lastGoalDisplay = display;
|
|
685
|
-
renderer.write(`
|
|
686
|
-
${sanitizeTerminalText(formatGoal(event.goal))}
|
|
687
|
-
`);
|
|
688
|
-
}
|
|
689
|
-
} else if (event.type === "permission-mode.changed") {
|
|
690
|
-
permissionModeChanged();
|
|
691
|
-
renderer.write(event.mode === "yolo" ? "\nYOLO enabled\n" : "\nYOLO disabled\n");
|
|
692
|
-
} else if (event.type === "run.event") {
|
|
693
|
-
await renderer.runEvent(event.event);
|
|
694
|
-
} else if (event.type === "permission.event") {
|
|
695
|
-
if (event.event.type === "approval.requested") {
|
|
696
|
-
enqueue(`approval:${event.event.request.id}`, (signal) => handlePermissionEvent(
|
|
697
|
-
event.event,
|
|
698
|
-
app,
|
|
699
|
-
renderer,
|
|
700
|
-
(prompt, options) => question(prompt, { ...options, signal })
|
|
701
|
-
));
|
|
702
|
-
} else {
|
|
703
|
-
if (event.event.type === "approval.resolved" || event.event.type === "approval.cancelled") pending.get(`approval:${event.event.requestId}`)?.abort();
|
|
704
|
-
renderer.permissionEvent(event.event);
|
|
705
|
-
}
|
|
706
|
-
} else if (event.type === "mcp.interaction.requested") {
|
|
707
|
-
enqueue(event.request.id, (signal) => presentMcpInteraction(
|
|
708
|
-
event.request,
|
|
709
|
-
app,
|
|
710
|
-
(prompt, signal2) => question(prompt, { history: false, signal: signal2 }),
|
|
711
|
-
signal
|
|
712
|
-
), event.request.expiresAt);
|
|
713
|
-
} else if (event.type === "mcp.interaction.settled") {
|
|
714
|
-
pending.get(event.requestId)?.abort();
|
|
715
|
-
} else if (event.type === "change.preview") {
|
|
716
|
-
renderer.changePreview(event);
|
|
717
|
-
} else if (event.type === "context.compacted") {
|
|
718
|
-
renderer.contextCompacted(event);
|
|
719
|
-
} else if (event.type === "context.compaction.failed") {
|
|
720
|
-
renderer.contextCompactionFailed(event);
|
|
721
|
-
} else if (event.type === "model.changed") {
|
|
722
|
-
renderer.modelChanged(event.model);
|
|
723
|
-
} else if (event.type === "model.default.changed") {
|
|
724
|
-
renderer.defaultModelChanged(event.profile);
|
|
725
|
-
} else if (event.type === "delegation.started" || event.type === "delegation.finished") {
|
|
726
|
-
renderer.delegationLifecycle(event, app.delegationNotifications === true);
|
|
727
|
-
} else if (event.type === "delegation.event") {
|
|
728
|
-
const inner = event.event;
|
|
729
|
-
if (inner.type === "permission.event") {
|
|
730
|
-
if (inner.event.type === "approval.requested") {
|
|
731
|
-
enqueue(`approval:${inner.event.request.id}`, (signal) => handlePermissionEvent(
|
|
732
|
-
inner.event,
|
|
733
|
-
app,
|
|
734
|
-
renderer,
|
|
735
|
-
(prompt, options) => question(prompt, { ...options, signal })
|
|
736
|
-
));
|
|
737
|
-
} else {
|
|
738
|
-
if (inner.event.type === "approval.resolved" || inner.event.type === "approval.cancelled") {
|
|
739
|
-
pending.get(`approval:${inner.event.requestId}`)?.abort();
|
|
740
|
-
}
|
|
741
|
-
renderer.permissionEvent(inner.event);
|
|
742
|
-
}
|
|
743
|
-
} else {
|
|
744
|
-
await renderer.delegationEvent(event);
|
|
745
|
-
}
|
|
746
|
-
} else if (event.type === "delegation.updated") {
|
|
747
|
-
renderer.delegationState(event.state, app.delegationNotifications === true);
|
|
748
|
-
} else if (event.type === "mcp.resource.updated" || event.type === "mcp.resource.watch-closed" || event.type === "mcp.server.connected" || event.type === "mcp.server.catalog-updated" || event.type === "mcp.server.failed" || event.type === "mcp.server.disconnected") {
|
|
749
|
-
renderer.mcpEvent(event);
|
|
750
|
-
} else if (event.type === "workspace.git.changed") {
|
|
751
|
-
if (event.checkpoint.error) renderer.write(`
|
|
752
|
-
Git checkpoint\uFF1A${sanitizeTerminalText(event.checkpoint.error)}
|
|
753
|
-
`);
|
|
754
|
-
} else if (event.type === "session.changed") {
|
|
755
|
-
await renderer.sessionChanged(event, app);
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
for (const controller of pending.values()) controller.abort();
|
|
759
|
-
await prompts;
|
|
760
|
-
}
|
|
761
|
-
__name(consumeEvents, "consumeEvents");
|
|
762
|
-
async function handlePermissionEvent(event, app, renderer, question) {
|
|
763
|
-
if (event.type !== "approval.requested") {
|
|
764
|
-
renderer.permissionEvent(event);
|
|
765
|
-
return;
|
|
766
|
-
}
|
|
767
|
-
renderer.approvalRequest(event.request);
|
|
768
|
-
while (true) {
|
|
769
|
-
const choices = event.request.grantKey === void 0 ? "[a]llow once / [d]eny" : permissionChoices(event.request.tool.name) + (event.request.persistent ? ` / [p]ersistent (${event.request.persistent.description})` : "");
|
|
770
|
-
let answer;
|
|
771
|
-
try {
|
|
772
|
-
answer = (await question(`${choices}: `, { history: false })).trim().toLowerCase();
|
|
773
|
-
} catch (error) {
|
|
774
|
-
if (isAbortError(error)) return;
|
|
775
|
-
throw error;
|
|
776
|
-
}
|
|
777
|
-
const decision = answer === "a" || answer === "allow" || answer === "y" ? "allow" : answer === "d" || answer === "deny" || answer === "n" ? "deny" : answer === "s" || answer === "session" ? "allow-session" : answer === "p" || answer === "persistent" ? "allow-persistent" : void 0;
|
|
778
|
-
if (decision === void 0) {
|
|
779
|
-
renderer.write(event.request.persistent ? "\u8BF7\u8F93\u5165 a\u3001s\u3001p \u6216 d\u3002\n" : "\u8BF7\u8F93\u5165 a\u3001s \u6216 d\u3002\n");
|
|
780
|
-
continue;
|
|
781
|
-
}
|
|
782
|
-
if (decision === "allow-session" && event.request.grantKey === void 0) {
|
|
783
|
-
renderer.write("This request cannot be granted for the session.\n");
|
|
784
|
-
continue;
|
|
785
|
-
}
|
|
786
|
-
if (decision === "allow-persistent" && !event.request.persistent) {
|
|
787
|
-
renderer.write("\u6B64\u8BF7\u6C42\u6CA1\u6709\u53EF\u4FDD\u5B58\u7684\u6388\u6743\u8303\u56F4\u3002\n");
|
|
788
|
-
continue;
|
|
789
|
-
}
|
|
790
|
-
await app.resolveApproval(event.request.id, decision, decision === "allow-persistent" ? { createdBy: `local:${userInfo().username}` } : void 0);
|
|
791
|
-
return;
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
__name(handlePermissionEvent, "handlePermissionEvent");
|
|
795
|
-
async function handleCommand(input, app, terminal, question, web, observeRun) {
|
|
796
|
-
const parsed = parseMaybeCodeSlashCommand(input);
|
|
797
|
-
if (parsed.type === "command" && parsed.definition.name === "/retry" && parsed.arguments.length === 0) {
|
|
798
|
-
terminal.write("\nRetrying the latest failed run...\n");
|
|
799
|
-
}
|
|
800
|
-
if (parsed.type === "command" && parsed.definition.name === "/compact" && parsed.arguments.length === 0) {
|
|
801
|
-
terminal.write("\nPruning old tool results and summarizing context...\n");
|
|
802
|
-
}
|
|
803
|
-
const result = await executeMaybeCodeSlashCommand(input, app);
|
|
804
|
-
if (result.type === "web.requested") {
|
|
805
|
-
terminal.write(`
|
|
806
|
-
Web UI \u5DF2\u6253\u5F00\uFF1A${await web.open()}
|
|
807
|
-
`);
|
|
808
|
-
return false;
|
|
809
|
-
}
|
|
810
|
-
return renderSlashCommandResult(result, app, terminal, question, observeRun);
|
|
811
|
-
}
|
|
812
|
-
__name(handleCommand, "handleCommand");
|
|
813
|
-
async function renderSlashCommandResult(result, app, terminal, question, observeRun) {
|
|
814
|
-
switch (result.type) {
|
|
815
|
-
case "exit":
|
|
816
|
-
return true;
|
|
817
|
-
case "help":
|
|
818
|
-
terminal.write(`
|
|
819
|
-
${renderSlashCommandHelp(result.commands)}`);
|
|
820
|
-
break;
|
|
821
|
-
case "instructions":
|
|
822
|
-
terminal.write(sanitizeTerminalText(
|
|
823
|
-
`
|
|
824
|
-
${renderInstructionSources(app)}Effective instructions:
|
|
825
|
-
---
|
|
826
|
-
${result.instructions.effective}
|
|
827
|
-
---
|
|
828
|
-
`
|
|
829
|
-
));
|
|
830
|
-
break;
|
|
831
|
-
case "mcp.run-started":
|
|
832
|
-
case "skill.run-started":
|
|
833
|
-
case "retry.started":
|
|
834
|
-
observeRun(result.run.result);
|
|
835
|
-
break;
|
|
836
|
-
case "status":
|
|
837
|
-
terminal.write(`
|
|
838
|
-
${renderStatus(app, result.inspection)}`);
|
|
839
|
-
break;
|
|
840
|
-
case "display":
|
|
841
|
-
case "mcp.display":
|
|
842
|
-
terminal.write(`
|
|
843
|
-
${sanitizeTerminalText(result.text)}
|
|
844
|
-
`);
|
|
845
|
-
break;
|
|
846
|
-
case "mcp.status":
|
|
847
|
-
terminal.write(
|
|
848
|
-
`
|
|
849
|
-
${sanitizeTerminalText(formatMaybeCodeMcpStatus(result.servers))}
|
|
850
|
-
`
|
|
851
|
-
);
|
|
852
|
-
break;
|
|
853
|
-
case "context":
|
|
854
|
-
terminal.write(
|
|
855
|
-
result.inspection === void 0 ? "\nContext inspection is not supported by the active context.\n" : `
|
|
856
|
-
${renderContextInspection(result.inspection)}`
|
|
857
|
-
);
|
|
858
|
-
break;
|
|
859
|
-
case "compacted":
|
|
860
|
-
terminal.write(`
|
|
861
|
-
${renderCompactionResult(result.result)}`);
|
|
862
|
-
break;
|
|
863
|
-
case "session.created":
|
|
864
|
-
terminal.write(`
|
|
865
|
-
Created session ${result.sessionId}
|
|
866
|
-
`);
|
|
867
|
-
break;
|
|
868
|
-
case "session.selection.requested": {
|
|
869
|
-
const selection = await runSessionPicker({
|
|
870
|
-
controller: app,
|
|
871
|
-
terminal,
|
|
872
|
-
sessions: result.sessions,
|
|
873
|
-
question: /* @__PURE__ */ __name((prompt) => question(prompt, { history: false }), "question")
|
|
874
|
-
});
|
|
875
|
-
if (selection.type === "empty") {
|
|
876
|
-
terminal.write("\nNo sessions found for this workspace.\n");
|
|
877
|
-
} else if (selection.type === "resume") {
|
|
878
|
-
await app.resumeSession(selection.sessionId);
|
|
879
|
-
terminal.write(`
|
|
880
|
-
Resumed session ${selection.sessionId}
|
|
881
|
-
`);
|
|
882
|
-
}
|
|
883
|
-
break;
|
|
884
|
-
}
|
|
885
|
-
case "fork.selection.requested": {
|
|
886
|
-
const selection = await runForkPicker({ points: result.points, currentSessionId: app.sessionId, terminal, question: /* @__PURE__ */ __name((prompt) => question(prompt, { history: false }), "question") });
|
|
887
|
-
if (selection) {
|
|
888
|
-
if (!app.forkSession) throw new Error("Session \u5206\u652F\u80FD\u529B\u4E0D\u53EF\u7528\u3002");
|
|
889
|
-
const id = await app.forkSession(selection.pointId, selection.mode);
|
|
890
|
-
terminal.write(sanitizeTerminalText(`
|
|
891
|
-
Session \u5206\u652F\u5DF2\u521B\u5EFA\uFF1A${id}
|
|
892
|
-
`));
|
|
893
|
-
}
|
|
894
|
-
break;
|
|
895
|
-
}
|
|
896
|
-
case "changes.selection.requested":
|
|
897
|
-
await runChangesPicker(terminal, result.diff, app);
|
|
898
|
-
break;
|
|
899
|
-
case "worktrees.display":
|
|
900
|
-
terminal.write(sanitizeTerminalText(`
|
|
901
|
-
${result.worktrees.length ? result.worktrees.map((item) => `${item.id}
|
|
902
|
-
${item.path}
|
|
903
|
-
${item.branch} \xB7 ${item.status} \xB7 ${item.commit.slice(0, 12)}`).join("\n\n") : "\u6CA1\u6709\u5DF2\u767B\u8BB0\u7684 worktree\u3002"}
|
|
904
|
-
`));
|
|
905
|
-
break;
|
|
906
|
-
case "session.resumed":
|
|
907
|
-
terminal.write(`
|
|
908
|
-
Resumed session ${result.sessionId}
|
|
909
|
-
`);
|
|
910
|
-
break;
|
|
911
|
-
case "model.selection.requested": {
|
|
912
|
-
let models = result.models;
|
|
913
|
-
while (true) {
|
|
914
|
-
const selection = await runModelPicker({
|
|
915
|
-
controller: app,
|
|
916
|
-
terminal,
|
|
917
|
-
models,
|
|
918
|
-
question: /* @__PURE__ */ __name((prompt) => question(prompt, { history: false }), "question")
|
|
919
|
-
});
|
|
920
|
-
if (selection.type === "empty") {
|
|
921
|
-
terminal.write("\nNo model profiles are configured.\n");
|
|
922
|
-
break;
|
|
923
|
-
}
|
|
924
|
-
if (selection.type === "cancelled") break;
|
|
925
|
-
if (selection.type === "select") {
|
|
926
|
-
await app.switchModel(selection.profile);
|
|
927
|
-
break;
|
|
928
|
-
}
|
|
929
|
-
await app.setDefaultModel(selection.profile);
|
|
930
|
-
models = await app.listModels();
|
|
931
|
-
}
|
|
932
|
-
break;
|
|
933
|
-
}
|
|
934
|
-
case "model.switched":
|
|
935
|
-
break;
|
|
936
|
-
case "model.not-found":
|
|
937
|
-
terminal.write(
|
|
938
|
-
`
|
|
939
|
-
No model profile starts with: ${sanitizeTerminalText(result.query)}
|
|
940
|
-
`
|
|
941
|
-
);
|
|
942
|
-
break;
|
|
943
|
-
case "effort.selection.requested": {
|
|
944
|
-
if (result.state.status !== "known") {
|
|
945
|
-
terminal.write(`
|
|
946
|
-
${renderReasoningEffortState(result.state)}
|
|
947
|
-
`);
|
|
948
|
-
break;
|
|
949
|
-
}
|
|
950
|
-
const choices = ["default", ...result.state.efforts];
|
|
951
|
-
terminal.write(`
|
|
952
|
-
${renderReasoningEffortState(result.state)}`);
|
|
953
|
-
for (const [index, effort] of choices.entries()) {
|
|
954
|
-
terminal.write(
|
|
955
|
-
` ${index + 1}. ${sanitizeTerminalText(effort)}
|
|
956
|
-
`
|
|
957
|
-
);
|
|
958
|
-
}
|
|
959
|
-
const answer = (await question(
|
|
960
|
-
"Select an effort number or name (Enter to cancel): ",
|
|
961
|
-
{ history: false }
|
|
962
|
-
)).trim().toLowerCase();
|
|
963
|
-
if (answer !== "") {
|
|
964
|
-
const numeric = Number(answer);
|
|
965
|
-
const selected = Number.isSafeInteger(numeric) && numeric > 0 ? choices[numeric - 1] : choices.find((choice) => choice.startsWith(answer));
|
|
966
|
-
if (selected === void 0) {
|
|
967
|
-
terminal.write(
|
|
968
|
-
`
|
|
969
|
-
No reasoning effort starts with: ${sanitizeTerminalText(answer)}
|
|
970
|
-
`
|
|
971
|
-
);
|
|
972
|
-
} else {
|
|
973
|
-
const state = await app.setReasoningEffort(
|
|
974
|
-
selected === "default" ? void 0 : selected
|
|
975
|
-
);
|
|
976
|
-
terminal.write(`
|
|
977
|
-
${renderReasoningEffortChanged(state)}
|
|
978
|
-
`);
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
break;
|
|
982
|
-
}
|
|
983
|
-
case "effort.changed":
|
|
984
|
-
terminal.write(`
|
|
985
|
-
${renderReasoningEffortChanged(result.state)}
|
|
986
|
-
`);
|
|
987
|
-
break;
|
|
988
|
-
case "effort.not-found":
|
|
989
|
-
terminal.write(
|
|
990
|
-
`
|
|
991
|
-
No reasoning effort starts with: ${sanitizeTerminalText(result.query)}
|
|
992
|
-
`
|
|
993
|
-
);
|
|
994
|
-
break;
|
|
995
|
-
case "usage":
|
|
996
|
-
terminal.write(`
|
|
997
|
-
Usage: ${sanitizeTerminalText(result.usage)}
|
|
998
|
-
`);
|
|
999
|
-
break;
|
|
1000
|
-
case "unknown":
|
|
1001
|
-
terminal.write(
|
|
1002
|
-
`
|
|
1003
|
-
Unknown command: ${sanitizeTerminalText(result.command)}. Type /help.
|
|
1004
|
-
`
|
|
1005
|
-
);
|
|
1006
|
-
break;
|
|
1007
|
-
}
|
|
1008
|
-
return false;
|
|
1009
|
-
}
|
|
1010
|
-
__name(renderSlashCommandResult, "renderSlashCommandResult");
|
|
1011
|
-
function renderReasoningEffortState(state) {
|
|
1012
|
-
if (state.status === "unknown") {
|
|
1013
|
-
return "Reasoning effort capability is unknown for the active model.";
|
|
1014
|
-
}
|
|
1015
|
-
if (state.status === "unsupported") {
|
|
1016
|
-
return "The active model does not support effort-based reasoning.";
|
|
1017
|
-
}
|
|
1018
|
-
const current = sanitizeTerminalText(
|
|
1019
|
-
state.effectiveEffort ?? "provider/model default"
|
|
1020
|
-
);
|
|
1021
|
-
return `Reasoning effort (source: ${sanitizeTerminalText(state.source)}, current: ${current})
|
|
1022
|
-
`;
|
|
1023
|
-
}
|
|
1024
|
-
__name(renderReasoningEffortState, "renderReasoningEffortState");
|
|
1025
|
-
function renderReasoningEffortChanged(state) {
|
|
1026
|
-
const effort = sanitizeTerminalText(
|
|
1027
|
-
state.effectiveEffort ?? "provider/model default"
|
|
1028
|
-
);
|
|
1029
|
-
return `Reasoning effort: ${effort}${state.overridden ? " (runtime override)" : ""}`;
|
|
1030
|
-
}
|
|
1031
|
-
__name(renderReasoningEffortChanged, "renderReasoningEffortChanged");
|
|
1032
|
-
function renderSlashCommandHelp(commands) {
|
|
1033
|
-
const entries = commands.map((command) => {
|
|
1034
|
-
const aliases = command.aliases === void 0 ? "" : ` (alias ${command.aliases.join(", ")})`;
|
|
1035
|
-
return ` ${command.usage}${aliases}
|
|
1036
|
-
${command.description}`;
|
|
1037
|
-
}).join("\n");
|
|
1038
|
-
return `Commands:
|
|
1039
|
-
${entries}
|
|
1040
|
-
Ctrl+C
|
|
1041
|
-
Cancel the active operation, or exit while idle
|
|
1042
|
-
Multiline
|
|
1043
|
-
End a line with \\ to continue on the next line
|
|
1044
|
-
`;
|
|
1045
|
-
}
|
|
1046
|
-
__name(renderSlashCommandHelp, "renderSlashCommandHelp");
|
|
1047
|
-
function inputPrompt(yolo, continuation, gitLabel = "") {
|
|
1048
|
-
return `${continuation ? "" : "\n"}${!continuation && gitLabel ? `[${gitLabel}] ` : ""}${yolo ? "YOLO \xB7 Auto-approve " : ""}${continuation ? "... " : "> "}`;
|
|
1049
|
-
}
|
|
1050
|
-
__name(inputPrompt, "inputPrompt");
|
|
1051
|
-
async function readInput(question, suggestions, yolo, gitLabel = () => "") {
|
|
1052
|
-
const lines = [];
|
|
1053
|
-
while (true) {
|
|
1054
|
-
let line = await question(inputPrompt(yolo(), lines.length > 0, gitLabel()), {
|
|
1055
|
-
history: false,
|
|
1056
|
-
...lines.length === 0 && suggestions !== void 0 ? { suggestions } : {}
|
|
1057
|
-
});
|
|
1058
|
-
if (lines.length === 0 && suggestions !== void 0) {
|
|
1059
|
-
const candidates = await suggestions(line);
|
|
1060
|
-
line = candidates.length === 1 ? candidates[0].value : line;
|
|
1061
|
-
}
|
|
1062
|
-
const continuation = removeLineContinuation(line);
|
|
1063
|
-
lines.push(continuation.text);
|
|
1064
|
-
if (!continuation.continued) return lines.join("\n").trim();
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
__name(readInput, "readInput");
|
|
1068
|
-
function removeLineContinuation(line) {
|
|
1069
|
-
let backslashes = 0;
|
|
1070
|
-
for (let index = line.length - 1; index >= 0 && line[index] === "\\"; index--) {
|
|
1071
|
-
backslashes += 1;
|
|
1072
|
-
}
|
|
1073
|
-
if (backslashes % 2 === 0) return { text: line, continued: false };
|
|
1074
|
-
return { text: line.slice(0, -1), continued: true };
|
|
1075
|
-
}
|
|
1076
|
-
__name(removeLineContinuation, "removeLineContinuation");
|
|
1077
|
-
var TerminalRenderer = class {
|
|
1078
|
-
constructor(terminal) {
|
|
1079
|
-
this.terminal = terminal;
|
|
1080
|
-
this.images = new TerminalImages(void 0, terminal.imageSupport?.protocol, { cellSize: /* @__PURE__ */ __name(() => terminal.imageSupport?.cellSize, "cellSize") });
|
|
1081
|
-
}
|
|
1082
|
-
terminal;
|
|
1083
|
-
static {
|
|
1084
|
-
__name(this, "TerminalRenderer");
|
|
1085
|
-
}
|
|
1086
|
-
images;
|
|
1087
|
-
textStarted = false;
|
|
1088
|
-
reasoningStarted = false;
|
|
1089
|
-
changePreviews = /* @__PURE__ */ new Map();
|
|
1090
|
-
delegationStatus = /* @__PURE__ */ new Map();
|
|
1091
|
-
lastDelegationKey = "";
|
|
1092
|
-
label = "";
|
|
1093
|
-
toolOutputState = /* @__PURE__ */ new Map();
|
|
1094
|
-
write(text) {
|
|
1095
|
-
this.terminal.write(text);
|
|
1096
|
-
}
|
|
1097
|
-
tagged(text) {
|
|
1098
|
-
return this.label === "" ? text : `${this.label} ${text}`;
|
|
1099
|
-
}
|
|
1100
|
-
async runEvent(event) {
|
|
1101
|
-
switch (event.type) {
|
|
1102
|
-
case "input.received":
|
|
1103
|
-
this.endReasoning();
|
|
1104
|
-
for (const message of event.messages) {
|
|
1105
|
-
this.terminal.write(`
|
|
1106
|
-
You: ${sanitizeTerminalText(textFromContent(message.content))}
|
|
1107
|
-
`);
|
|
1108
|
-
}
|
|
1109
|
-
break;
|
|
1110
|
-
case "model.started":
|
|
1111
|
-
this.textStarted = false;
|
|
1112
|
-
this.reasoningStarted = false;
|
|
1113
|
-
break;
|
|
1114
|
-
case "model.reasoning.delta":
|
|
1115
|
-
if (!this.reasoningStarted) {
|
|
1116
|
-
this.terminal.write(`
|
|
1117
|
-
${this.dim("[thinking] ")}`);
|
|
1118
|
-
this.reasoningStarted = true;
|
|
1119
|
-
}
|
|
1120
|
-
this.terminal.write(this.dim(sanitizeTerminalText(event.delta)));
|
|
1121
|
-
break;
|
|
1122
|
-
case "model.text.delta":
|
|
1123
|
-
this.endReasoning();
|
|
1124
|
-
if (!this.textStarted) {
|
|
1125
|
-
this.terminal.write(this.label === "" ? "\nMaybeCode: " : `
|
|
1126
|
-
${this.label} Sub-agent: `);
|
|
1127
|
-
this.textStarted = true;
|
|
1128
|
-
}
|
|
1129
|
-
this.terminal.write(sanitizeTerminalText(event.delta));
|
|
1130
|
-
break;
|
|
1131
|
-
case "model.retrying":
|
|
1132
|
-
this.endReasoning();
|
|
1133
|
-
if (this.textStarted) this.terminal.write("\n");
|
|
1134
|
-
this.terminal.write(
|
|
1135
|
-
`
|
|
1136
|
-
Model request failed: ${sanitizeTerminalText(event.error.message)}. Retrying in ${formatDelay(event.delayMs)} (attempt ${event.attempt}/${event.maxAttempts})...
|
|
1137
|
-
`
|
|
1138
|
-
);
|
|
1139
|
-
this.textStarted = false;
|
|
1140
|
-
this.reasoningStarted = false;
|
|
1141
|
-
break;
|
|
1142
|
-
case "model.completed": {
|
|
1143
|
-
this.endReasoning();
|
|
1144
|
-
if (event.message.content.some((part) => part.type === "image")) {
|
|
1145
|
-
this.terminal.write("\nMaybeCode \xB7 \u5B8C\u6574\u56FE\u6587\u56DE\u590D\uFF1A\n");
|
|
1146
|
-
await this.renderContent(event.message.content);
|
|
1147
|
-
break;
|
|
1148
|
-
}
|
|
1149
|
-
const text = textFromContent(event.message.content);
|
|
1150
|
-
if (!this.textStarted && text !== "") {
|
|
1151
|
-
this.terminal.write(`
|
|
1152
|
-
MaybeCode: ${sanitizeTerminalText(text)}`);
|
|
1153
|
-
this.textStarted = true;
|
|
1154
|
-
}
|
|
1155
|
-
if (this.textStarted) this.terminal.write("\n");
|
|
1156
|
-
break;
|
|
1157
|
-
}
|
|
1158
|
-
case "tool.started":
|
|
1159
|
-
this.terminal.write(
|
|
1160
|
-
`
|
|
1161
|
-
${this.tagged(`\u2192 ${sanitizeTerminalText(event.call.name)}${toolInputSummary(
|
|
1162
|
-
event.call.name,
|
|
1163
|
-
event.call.input
|
|
1164
|
-
)}`)}
|
|
1165
|
-
`
|
|
1166
|
-
);
|
|
1167
|
-
break;
|
|
1168
|
-
case "tool.output.delta": {
|
|
1169
|
-
const key = toolCallKey(event.runId, event.call.id);
|
|
1170
|
-
const previous = this.toolOutputState.get(key);
|
|
1171
|
-
if (previous !== void 0 && !previous.endsWithNewline && previous.channel !== event.channel) {
|
|
1172
|
-
this.terminal.write("\n");
|
|
1173
|
-
}
|
|
1174
|
-
if (previous === void 0 || previous.endsWithNewline || previous.channel !== event.channel) {
|
|
1175
|
-
this.terminal.write(
|
|
1176
|
-
event.channel === void 0 ? "" : `[${sanitizeTerminalText(event.channel)}] `
|
|
1177
|
-
);
|
|
1178
|
-
}
|
|
1179
|
-
this.terminal.write(sanitizeTerminalText(event.delta));
|
|
1180
|
-
this.toolOutputState.set(key, {
|
|
1181
|
-
endsWithNewline: event.delta.endsWith("\n"),
|
|
1182
|
-
...event.channel === void 0 ? {} : { channel: event.channel }
|
|
1183
|
-
});
|
|
1184
|
-
break;
|
|
1185
|
-
}
|
|
1186
|
-
case "tool.progress":
|
|
1187
|
-
this.endToolOutput(event.runId, event.call.id);
|
|
1188
|
-
this.terminal.write(
|
|
1189
|
-
`\u21B3 ${sanitizeTerminalText(event.call.name)}: ${sanitizeTerminalText(event.message)}
|
|
1190
|
-
`
|
|
1191
|
-
);
|
|
1192
|
-
break;
|
|
1193
|
-
case "tool.completed":
|
|
1194
|
-
this.endToolOutput(event.runId, event.call.id);
|
|
1195
|
-
this.renderToolCompleted(event);
|
|
1196
|
-
if (event.content.some((part) => part.type === "image")) await this.renderContent(event.content);
|
|
1197
|
-
break;
|
|
1198
|
-
case "tool.failed":
|
|
1199
|
-
this.endToolOutput(event.runId, event.call.id);
|
|
1200
|
-
this.changePreviews.delete(toolCallKey(event.runId, event.call.id));
|
|
1201
|
-
this.terminal.write(
|
|
1202
|
-
`
|
|
1203
|
-
${this.tagged(`\u2717 ${sanitizeTerminalText(event.call.name)}: ${sanitizeTerminalText(event.error.message)}`)}
|
|
1204
|
-
`
|
|
1205
|
-
);
|
|
1206
|
-
break;
|
|
1207
|
-
case "run.completed":
|
|
1208
|
-
case "run.yielded":
|
|
1209
|
-
this.clearRunPreviews(event.runId);
|
|
1210
|
-
break;
|
|
1211
|
-
case "run.failed":
|
|
1212
|
-
this.clearRunPreviews(event.runId);
|
|
1213
|
-
this.terminal.write(
|
|
1214
|
-
`
|
|
1215
|
-
${this.tagged(`Run failed: ${sanitizeTerminalText(event.error.message)}`)}
|
|
1216
|
-
`
|
|
1217
|
-
);
|
|
1218
|
-
break;
|
|
1219
|
-
case "run.cancelled":
|
|
1220
|
-
this.clearRunPreviews(event.runId);
|
|
1221
|
-
this.terminal.write(
|
|
1222
|
-
`
|
|
1223
|
-
${this.tagged(`Run cancelled${event.reason === void 0 ? "" : `: ${sanitizeTerminalText(event.reason)}`}`)}
|
|
1224
|
-
`
|
|
1225
|
-
);
|
|
1226
|
-
break;
|
|
1227
|
-
}
|
|
1228
|
-
}
|
|
1229
|
-
async renderContent(content) {
|
|
1230
|
-
await this.images.prepare(content);
|
|
1231
|
-
for (const part of content) {
|
|
1232
|
-
if (part.type === "text") this.terminal.write(sanitizeTerminalText(part.text) + "\n");
|
|
1233
|
-
if (part.type === "image") {
|
|
1234
|
-
const result = this.images.render(part.source, { width: process.stdout.columns || 80, height: 30 });
|
|
1235
|
-
const image = result.images?.[0];
|
|
1236
|
-
this.terminal.write(result.lines.slice(0, image?.y ?? result.lines.length).join("\n") + "\n");
|
|
1237
|
-
if (image) {
|
|
1238
|
-
this.terminal.write("\n".repeat(image.rows) + `\x1B[${image.rows}A\x1B7` + encodeImage(image) + `\x1B8\x1B[${image.rows}B\r`);
|
|
1239
|
-
}
|
|
1240
|
-
}
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
changePreview(event) {
|
|
1244
|
-
this.changePreviews.set(
|
|
1245
|
-
toolCallKey(event.runId, event.toolCallId),
|
|
1246
|
-
event.preview
|
|
1247
|
-
);
|
|
1248
|
-
if (event.preview.status === "unavailable") {
|
|
1249
|
-
this.terminal.write(
|
|
1250
|
-
`
|
|
1251
|
-
Diff unavailable for ${event.preview.tool} ${sanitizeTerminalText(event.preview.path)}: ${sanitizeTerminalText(event.preview.reason)}
|
|
1252
|
-
`
|
|
1253
|
-
);
|
|
1254
|
-
return;
|
|
1255
|
-
}
|
|
1256
|
-
this.terminal.write(
|
|
1257
|
-
`
|
|
1258
|
-
Change preview: ${sanitizeTerminalText(event.preview.path)} (${changeKindLabel(event.preview.kind)})
|
|
1259
|
-
`
|
|
1260
|
-
);
|
|
1261
|
-
this.terminal.write(
|
|
1262
|
-
event.preview.diff === "" ? "(no content changes)\n" : `${sanitizeTerminalText(event.preview.diff)}
|
|
1263
|
-
`
|
|
1264
|
-
);
|
|
1265
|
-
}
|
|
1266
|
-
contextCompacted(event) {
|
|
1267
|
-
const saved = Math.max(
|
|
1268
|
-
0,
|
|
1269
|
-
event.before.estimatedTokens - event.after.estimatedTokens
|
|
1270
|
-
);
|
|
1271
|
-
this.terminal.write(
|
|
1272
|
-
`
|
|
1273
|
-
Context automatically compacted with ${event.strategy}: ${event.before.messageCount} -> ${event.after.messageCount} messages, ~${formatNumber(saved)} tokens saved.
|
|
1274
|
-
`
|
|
1275
|
-
);
|
|
1276
|
-
}
|
|
1277
|
-
contextCompactionFailed(event) {
|
|
1278
|
-
const next = event.continuing ? " Trying the next strategy." : " No fallback strategies remain.";
|
|
1279
|
-
const message = sanitizeTerminalText(event.error.message).replace(/[.!?]+$/u, "");
|
|
1280
|
-
this.terminal.write(
|
|
1281
|
-
`
|
|
1282
|
-
Automatic context compaction failed with ${event.strategy} at ~${formatNumber(event.before.effectiveTokens)} tokens: ${message}.${next}
|
|
1283
|
-
`
|
|
1284
|
-
);
|
|
1285
|
-
}
|
|
1286
|
-
permissionEvent(event) {
|
|
1287
|
-
if (event.type === "approval.resolved") {
|
|
1288
|
-
this.terminal.write(`Permission: ${event.decision}
|
|
1289
|
-
`);
|
|
1290
|
-
} else if (event.type === "approval.cancelled") {
|
|
1291
|
-
this.terminal.write("Permission request cancelled.\n");
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
approvalRequest(request) {
|
|
1295
|
-
const preview = this.changePreviews.get(
|
|
1296
|
-
toolCallKey(request.context.runId, request.context.toolCallId)
|
|
1297
|
-
);
|
|
1298
|
-
if (preview !== void 0) {
|
|
1299
|
-
this.terminal.write(
|
|
1300
|
-
`
|
|
1301
|
-
Approval required for ${sanitizeTerminalText(request.tool.name)}: ${sanitizeTerminalText(preview.path)}
|
|
1302
|
-
`
|
|
1303
|
-
);
|
|
1304
|
-
return;
|
|
1305
|
-
}
|
|
1306
|
-
this.terminal.write(
|
|
1307
|
-
`
|
|
1308
|
-
Approval required for ${sanitizeTerminalText(request.tool.name)}:
|
|
1309
|
-
${sanitizeTerminalText(truncate(stringify(request.input), 1200))}
|
|
1310
|
-
`
|
|
1311
|
-
);
|
|
1312
|
-
}
|
|
1313
|
-
async sessionChanged(event, app) {
|
|
1314
|
-
this.terminal.write(
|
|
1315
|
-
`
|
|
1316
|
-
Session ${event.resumed ? "resumed" : "started"}: ${event.sessionId}
|
|
1317
|
-
`
|
|
1318
|
-
);
|
|
1319
|
-
if (!event.resumed) return;
|
|
1320
|
-
if (app.sessionId !== event.sessionId) return;
|
|
1321
|
-
const history = await app.history();
|
|
1322
|
-
const steering = new Map(history.flatMap((event2) => event2.type === "input.steering.queued" ? [[event2.input.inputId, event2.input.message]] : []));
|
|
1323
|
-
for (const event2 of history) {
|
|
1324
|
-
if (event2.type === "assistant.completed" && event2.message.content.some((part) => part.type === "image")) await this.renderContent(event2.message.content);
|
|
1325
|
-
else renderHistory([event2], this.terminal, steering);
|
|
1326
|
-
}
|
|
1327
|
-
}
|
|
1328
|
-
modelChanged(model) {
|
|
1329
|
-
const profile = model.profile === void 0 ? "" : ` ${sanitizeTerminalText(model.profile)}`;
|
|
1330
|
-
this.terminal.write(
|
|
1331
|
-
`
|
|
1332
|
-
Model switched to${profile}: ${sanitizeTerminalText(model.provider)}/${sanitizeTerminalText(model.model)}
|
|
1333
|
-
`
|
|
1334
|
-
);
|
|
1335
|
-
}
|
|
1336
|
-
defaultModelChanged(profile) {
|
|
1337
|
-
this.terminal.write(
|
|
1338
|
-
`
|
|
1339
|
-
Default model set to ${sanitizeTerminalText(profile)}
|
|
1340
|
-
`
|
|
1341
|
-
);
|
|
1342
|
-
}
|
|
1343
|
-
/** 子 Agent 请求的开始与结束,包含整棵任务树。 */
|
|
1344
|
-
delegationLifecycle(event, enabled) {
|
|
1345
|
-
if (event.type === "delegation.started") {
|
|
1346
|
-
this.delegationStatus.clear();
|
|
1347
|
-
this.lastDelegationKey = "";
|
|
1348
|
-
}
|
|
1349
|
-
if (!enabled) return;
|
|
1350
|
-
this.write(
|
|
1351
|
-
`
|
|
1352
|
-
${event.type === "delegation.started" ? "Sub-agent request" : "Sub-agent request finished"} ${sanitizeTerminalText(event.state.requestId)}
|
|
1353
|
-
`
|
|
1354
|
-
);
|
|
1355
|
-
for (const task of delegationOrder(event.state.tasks)) {
|
|
1356
|
-
this.write(`${sanitizeTerminalText(renderDelegationTask(task))}
|
|
1357
|
-
`);
|
|
1358
|
-
}
|
|
1359
|
-
}
|
|
1360
|
-
/** 子任务运行期间的状态变化;状态未变化时不重复显示。 */
|
|
1361
|
-
delegationState(state, enabled) {
|
|
1362
|
-
const key = `${state.tasks.map((task) => `${task.id}:${task.status}`).join("|")}#${state.status}`;
|
|
1363
|
-
if (key === this.lastDelegationKey) return;
|
|
1364
|
-
this.lastDelegationKey = key;
|
|
1365
|
-
for (const task of delegationOrder(state.tasks)) {
|
|
1366
|
-
if (this.delegationStatus.get(task.id) === task.status) continue;
|
|
1367
|
-
this.delegationStatus.set(task.id, task.status);
|
|
1368
|
-
if (enabled) this.write(`${sanitizeTerminalText(renderDelegationTask(task))}
|
|
1369
|
-
`);
|
|
1370
|
-
}
|
|
1371
|
-
}
|
|
1372
|
-
/** 一个子 Agent Run 事件,带上任务身份前缀。 */
|
|
1373
|
-
async delegationEvent(event) {
|
|
1374
|
-
if (event.event.type !== "run.event") {
|
|
1375
|
-
this.endReasoning();
|
|
1376
|
-
this.write(`
|
|
1377
|
-
[${event.taskId}] ${sanitizeTerminalText(describeApplicationEvent(event.event))}
|
|
1378
|
-
`);
|
|
1379
|
-
return;
|
|
1380
|
-
}
|
|
1381
|
-
this.label = `[${event.taskId}]`;
|
|
1382
|
-
try {
|
|
1383
|
-
await this.runEvent(event.event.event);
|
|
1384
|
-
} finally {
|
|
1385
|
-
this.label = "";
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
mcpEvent(event) {
|
|
1389
|
-
if (event.type === "mcp.resource.updated" || event.type === "mcp.resource.watch-closed") {
|
|
1390
|
-
this.terminal.write(`
|
|
1391
|
-
${sanitizeTerminalText(`${event.type}: ${event.serverId} ${event.uri}${event.type === "mcp.resource.watch-closed" ? ` (${event.reason})` : ""}`)}
|
|
1392
|
-
`);
|
|
1393
|
-
return;
|
|
1394
|
-
}
|
|
1395
|
-
if (event.type === "mcp.server.catalog-updated") {
|
|
1396
|
-
this.terminal.write(`
|
|
1397
|
-
MCP catalog updated: ${sanitizeTerminalText(event.serverId)} (revision ${event.revision})
|
|
1398
|
-
`);
|
|
1399
|
-
return;
|
|
1400
|
-
}
|
|
1401
|
-
if (event.type === "mcp.server.connected") {
|
|
1402
|
-
this.terminal.write(
|
|
1403
|
-
`
|
|
1404
|
-
MCP server connected: ${sanitizeTerminalText(event.serverId)} (${event.toolNames.length} tools)
|
|
1405
|
-
`
|
|
1406
|
-
);
|
|
1407
|
-
return;
|
|
1408
|
-
}
|
|
1409
|
-
if (event.type === "mcp.server.failed") {
|
|
1410
|
-
this.terminal.write(
|
|
1411
|
-
`
|
|
1412
|
-
MCP server failed: ${sanitizeTerminalText(event.serverId)}: ${sanitizeTerminalText(event.diagnostic.message)}
|
|
1413
|
-
`
|
|
1414
|
-
);
|
|
1415
|
-
return;
|
|
1416
|
-
}
|
|
1417
|
-
this.terminal.write(
|
|
1418
|
-
`
|
|
1419
|
-
MCP server disconnected: ${sanitizeTerminalText(event.serverId)}
|
|
1420
|
-
`
|
|
1421
|
-
);
|
|
1422
|
-
}
|
|
1423
|
-
endReasoning() {
|
|
1424
|
-
if (!this.reasoningStarted) return;
|
|
1425
|
-
this.terminal.write(this.terminal.colors ? "\x1B[0m\n" : "\n");
|
|
1426
|
-
this.reasoningStarted = false;
|
|
1427
|
-
}
|
|
1428
|
-
dim(text) {
|
|
1429
|
-
return this.terminal.colors ? `\x1B[2m${text}\x1B[0m` : text;
|
|
1430
|
-
}
|
|
1431
|
-
renderToolCompleted(event) {
|
|
1432
|
-
const key = toolCallKey(event.runId, event.call.id);
|
|
1433
|
-
const preview = this.changePreviews.get(key);
|
|
1434
|
-
this.changePreviews.delete(key);
|
|
1435
|
-
if (preview?.status === "ready") {
|
|
1436
|
-
this.terminal.write(
|
|
1437
|
-
`${this.tagged(`\u2713 ${sanitizeTerminalText(event.call.name)}: ${sanitizeTerminalText(preview.path)} (${changeKindLabel(preview.kind)}, +${preview.additions} -${preview.deletions})`)}
|
|
1438
|
-
`
|
|
1439
|
-
);
|
|
1440
|
-
return;
|
|
1441
|
-
}
|
|
1442
|
-
this.terminal.write(
|
|
1443
|
-
`${this.tagged(`${toolResultMarker(event.output)} ${sanitizeTerminalText(event.call.name)}${toolResultSummary(event.output)}`)}
|
|
1444
|
-
`
|
|
1445
|
-
);
|
|
1446
|
-
}
|
|
1447
|
-
clearRunPreviews(runId) {
|
|
1448
|
-
const prefix = `${runId}:`;
|
|
1449
|
-
for (const key of this.changePreviews.keys()) {
|
|
1450
|
-
if (key.startsWith(prefix)) this.changePreviews.delete(key);
|
|
1451
|
-
}
|
|
1452
|
-
for (const key of this.toolOutputState.keys()) {
|
|
1453
|
-
if (key.startsWith(prefix)) this.toolOutputState.delete(key);
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
endToolOutput(runId, toolCallId) {
|
|
1457
|
-
const key = toolCallKey(runId, toolCallId);
|
|
1458
|
-
const state = this.toolOutputState.get(key);
|
|
1459
|
-
this.toolOutputState.delete(key);
|
|
1460
|
-
if (state?.endsWithNewline === false) this.terminal.write("\n");
|
|
1461
|
-
}
|
|
1462
|
-
};
|
|
1463
|
-
function renderHistory(history, terminal, steering) {
|
|
1464
|
-
for (const event of history) {
|
|
1465
|
-
if (event.type === "input.submitted") {
|
|
1466
|
-
const text = textFromContent(event.message.content);
|
|
1467
|
-
if (text !== "") terminal.write(`You: ${sanitizeTerminalText(text)}
|
|
1468
|
-
`);
|
|
1469
|
-
} else if (event.type === "input.steering.delivered") {
|
|
1470
|
-
for (const inputId of event.inputIds) {
|
|
1471
|
-
const message = steering.get(inputId);
|
|
1472
|
-
if (!message) throw new Error(`Missing steering input: ${inputId}`);
|
|
1473
|
-
const text = textFromContent(message.content);
|
|
1474
|
-
if (text !== "") terminal.write(`You: ${sanitizeTerminalText(text)}
|
|
1475
|
-
`);
|
|
1476
|
-
}
|
|
1477
|
-
} else if (event.type === "assistant.completed") {
|
|
1478
|
-
const text = textFromContent(event.message.content);
|
|
1479
|
-
if (text !== "") {
|
|
1480
|
-
terminal.write(`MaybeCode: ${sanitizeTerminalText(text)}
|
|
1481
|
-
`);
|
|
1482
|
-
}
|
|
1483
|
-
} else if (event.type === "tool.completed") {
|
|
1484
|
-
terminal.write(
|
|
1485
|
-
`${toolResultMarker(event.output)} ${sanitizeTerminalText(event.call.name)}${toolResultSummary(event.output)}
|
|
1486
|
-
`
|
|
1487
|
-
);
|
|
1488
|
-
} else if (event.type === "tool.failed") {
|
|
1489
|
-
terminal.write(
|
|
1490
|
-
`\u2717 ${sanitizeTerminalText(event.call.name)}: ${sanitizeTerminalText(event.error.message)}
|
|
1491
|
-
`
|
|
1492
|
-
);
|
|
1493
|
-
}
|
|
1494
|
-
}
|
|
1495
|
-
}
|
|
1496
|
-
__name(renderHistory, "renderHistory");
|
|
1497
|
-
function textFromContent(content) {
|
|
1498
|
-
return content.filter((part) => part.type === "text").map((part) => part.text).join("");
|
|
1499
|
-
}
|
|
1500
|
-
__name(textFromContent, "textFromContent");
|
|
1501
|
-
function toolResultSummary(output) {
|
|
1502
|
-
if (typeof output !== "object" || output === null) return "";
|
|
1503
|
-
if ("path" in output && typeof output.path === "string") {
|
|
1504
|
-
return `: ${sanitizeTerminalText(output.path)}`;
|
|
1505
|
-
}
|
|
1506
|
-
if ("exitCode" in output && typeof output.exitCode === "number") {
|
|
1507
|
-
return `: exit ${output.exitCode}`;
|
|
1508
|
-
}
|
|
1509
|
-
return "";
|
|
1510
|
-
}
|
|
1511
|
-
__name(toolResultSummary, "toolResultSummary");
|
|
1512
|
-
function toolResultMarker(output) {
|
|
1513
|
-
if (typeof output === "object" && output !== null && "exitCode" in output && typeof output.exitCode === "number" && output.exitCode !== 0) {
|
|
1514
|
-
return "\u2717";
|
|
1515
|
-
}
|
|
1516
|
-
return "\u2713";
|
|
1517
|
-
}
|
|
1518
|
-
__name(toolResultMarker, "toolResultMarker");
|
|
1519
|
-
function permissionChoices(toolName) {
|
|
1520
|
-
const scope = toolName === "shell" || toolName === "bash" ? "same command" : toolName === "edit" || toolName === "write" ? "same path" : "same operation";
|
|
1521
|
-
return `[a]llow once / allow ${scope} for [s]ession / [d]eny`;
|
|
1522
|
-
}
|
|
1523
|
-
__name(permissionChoices, "permissionChoices");
|
|
1524
|
-
function toolInputSummary(toolName, input) {
|
|
1525
|
-
if ((toolName === "edit" || toolName === "write") && typeof input === "object" && input !== null && "path" in input && typeof input.path === "string") {
|
|
1526
|
-
return `: ${sanitizeTerminalText(input.path)}`;
|
|
1527
|
-
}
|
|
1528
|
-
return ` ${sanitizeTerminalText(truncate(stringify(input), 800))}`;
|
|
1529
|
-
}
|
|
1530
|
-
__name(toolInputSummary, "toolInputSummary");
|
|
1531
|
-
function toolCallKey(runId, toolCallId) {
|
|
1532
|
-
return `${runId}:${toolCallId}`;
|
|
1533
|
-
}
|
|
1534
|
-
__name(toolCallKey, "toolCallKey");
|
|
1535
|
-
function delegationOrder(tasks) {
|
|
1536
|
-
return [...tasks].sort((left, right) => left.depth - right.depth || left.id.localeCompare(right.id));
|
|
1537
|
-
}
|
|
1538
|
-
__name(delegationOrder, "delegationOrder");
|
|
1539
|
-
function describeApplicationEvent(event) {
|
|
1540
|
-
if (event.type === "context.compacted") {
|
|
1541
|
-
return `context compacted with ${event.strategy}: ${event.before.messageCount} -> ${event.after.messageCount} messages`;
|
|
1542
|
-
}
|
|
1543
|
-
if (event.type === "context.compaction.failed") {
|
|
1544
|
-
return `context compaction failed with ${event.strategy}: ${event.error.message}`;
|
|
1545
|
-
}
|
|
1546
|
-
if (event.type === "tool.presentation") return `tool presentation recorded`;
|
|
1547
|
-
return "session event";
|
|
1548
|
-
}
|
|
1549
|
-
__name(describeApplicationEvent, "describeApplicationEvent");
|
|
1550
|
-
function renderInstructionSources(app) {
|
|
1551
|
-
const system = app.instructions.system.source;
|
|
1552
|
-
const runtime = app.instructions.runtime?.source;
|
|
1553
|
-
const projects = app.instructions.projects;
|
|
1554
|
-
return `Instructions:
|
|
1555
|
-
system: ${instructionSourceLabel(system)}
|
|
1556
|
-
runtime: ${runtime === void 0 ? "none" : instructionSourceLabel(runtime)}
|
|
1557
|
-
project: ${projects.length === 0 ? "none" : projects.map((project) => instructionSourceLabel(project.source)).join("\n ")}
|
|
1558
|
-
`;
|
|
1559
|
-
}
|
|
1560
|
-
__name(renderInstructionSources, "renderInstructionSources");
|
|
1561
|
-
function renderStatus(app, inspection) {
|
|
1562
|
-
let output = `Status:
|
|
1563
|
-
model: ${modelLabel(app)}
|
|
1564
|
-
session: ${sanitizeTerminalText(app.sessionId)}
|
|
1565
|
-
workspace: ${sanitizeTerminalText(app.workspace)}
|
|
1566
|
-
permissions: ${app.permissionMode === "yolo" ? "YOLO \xB7 Auto-approve" : "Default"}
|
|
1567
|
-
`;
|
|
1568
|
-
if (inspection === void 0) return `${output} context: unavailable
|
|
1569
|
-
`;
|
|
1570
|
-
output += ` context: ~${formatNumber(inspection.effectiveTokens)}`;
|
|
1571
|
-
if (inspection.contextWindowTokens !== void 0) {
|
|
1572
|
-
output += ` / ${formatNumber(inspection.contextWindowTokens)} tokens (${((inspection.usageRatio ?? 0) * 100).toFixed(1)}%)`;
|
|
1573
|
-
} else {
|
|
1574
|
-
output += ` tokens (${inspection.measurementMethod})`;
|
|
1575
|
-
}
|
|
1576
|
-
return `${output}
|
|
1577
|
-
`;
|
|
1578
|
-
}
|
|
1579
|
-
__name(renderStatus, "renderStatus");
|
|
1580
|
-
function modelLabel(app) {
|
|
1581
|
-
if (app.modelInfo === void 0) return "custom";
|
|
1582
|
-
const endpoint = `${sanitizeTerminalText(app.modelInfo.provider)}/` + sanitizeTerminalText(app.modelInfo.model);
|
|
1583
|
-
return app.modelInfo.profile === void 0 ? endpoint : `${sanitizeTerminalText(app.modelInfo.profile)} (${endpoint})`;
|
|
1584
|
-
}
|
|
1585
|
-
__name(modelLabel, "modelLabel");
|
|
1586
|
-
function renderContextInspection(inspection) {
|
|
1587
|
-
const roles = inspection.messagesByRole;
|
|
1588
|
-
let output = `Context:
|
|
1589
|
-
messages: ${inspection.messageCount} (system ${roles.system}, user ${roles.user}, assistant ${roles.assistant}, tool ${roles.tool})
|
|
1590
|
-
instructions: ${formatBytes(inspection.instructionsBytes)}
|
|
1591
|
-
message data: ${formatBytes(inspection.messageBytes)}
|
|
1592
|
-
total: ${formatBytes(inspection.totalBytes)}
|
|
1593
|
-
estimated tokens: ~${inspection.estimatedTokens} (${inspection.tokenEstimateMethod})
|
|
1594
|
-
`;
|
|
1595
|
-
if (inspection.contextWindowTokens === void 0) {
|
|
1596
|
-
output += ` effective usage: ~${formatNumber(inspection.effectiveTokens)} (${inspection.measurementMethod})
|
|
1597
|
-
`;
|
|
1598
|
-
} else {
|
|
1599
|
-
output += ` effective usage: ~${formatNumber(inspection.effectiveTokens)} / ${formatNumber(inspection.contextWindowTokens)} (${((inspection.usageRatio ?? 0) * 100).toFixed(1)}%)
|
|
1600
|
-
`;
|
|
1601
|
-
}
|
|
1602
|
-
if (inspection.measurementMethod === "measured+estimated") {
|
|
1603
|
-
output += ` measurement: ${formatNumber(
|
|
1604
|
-
inspection.measuredInputTokens ?? 0
|
|
1605
|
-
)} measured + ~${formatNumber(
|
|
1606
|
-
inspection.estimatedTailTokens ?? 0
|
|
1607
|
-
)} estimated tail
|
|
1608
|
-
`;
|
|
1609
|
-
} else {
|
|
1610
|
-
output += " measurement: estimated only\n";
|
|
1611
|
-
}
|
|
1612
|
-
if (inspection.remainingTokens !== void 0) {
|
|
1613
|
-
output += ` remaining: ${formatNumber(inspection.remainingTokens)} tokens
|
|
1614
|
-
`;
|
|
1615
|
-
}
|
|
1616
|
-
if (inspection.inputBudgetTokens !== void 0) {
|
|
1617
|
-
output += ` input budget: ${formatNumber(inspection.inputBudgetTokens)} tokens`;
|
|
1618
|
-
if ((inspection.reservedTokens ?? 0) > 0) {
|
|
1619
|
-
output += ` (${formatNumber(inspection.reservedTokens ?? 0)} reserved)`;
|
|
1620
|
-
}
|
|
1621
|
-
output += "\n";
|
|
1622
|
-
}
|
|
1623
|
-
if (inspection.compactTriggerTokens !== void 0) {
|
|
1624
|
-
output += ` compaction threshold: ${formatNumber(
|
|
1625
|
-
inspection.compactTriggerTokens
|
|
1626
|
-
)} tokens (${inspection.shouldCompact === true ? "reached" : "not reached"})
|
|
1627
|
-
`;
|
|
1628
|
-
}
|
|
1629
|
-
return output;
|
|
1630
|
-
}
|
|
1631
|
-
__name(renderContextInspection, "renderContextInspection");
|
|
1632
|
-
function renderCompactionResult(result) {
|
|
1633
|
-
if (!result.changed) {
|
|
1634
|
-
return `No context changes were eligible for ${result.strategy}.
|
|
1635
|
-
`;
|
|
1636
|
-
}
|
|
1637
|
-
const saved = Math.max(
|
|
1638
|
-
0,
|
|
1639
|
-
result.before.estimatedTokens - result.after.estimatedTokens
|
|
1640
|
-
);
|
|
1641
|
-
const ratio = result.before.estimatedTokens === 0 ? 0 : saved / result.before.estimatedTokens * 100;
|
|
1642
|
-
return `Context compacted with ${result.strategy}:
|
|
1643
|
-
messages: ${result.before.messageCount} -> ${result.after.messageCount}
|
|
1644
|
-
estimated tokens: ~${formatNumber(result.before.estimatedTokens)} -> ~${formatNumber(result.after.estimatedTokens)}
|
|
1645
|
-
saved: ~${formatNumber(saved)} tokens (${ratio.toFixed(1)}%)
|
|
1646
|
-
`;
|
|
1647
|
-
}
|
|
1648
|
-
__name(renderCompactionResult, "renderCompactionResult");
|
|
1649
|
-
function formatNumber(value) {
|
|
1650
|
-
return value.toLocaleString("en-US");
|
|
1651
|
-
}
|
|
1652
|
-
__name(formatNumber, "formatNumber");
|
|
1653
|
-
function formatDelay(milliseconds) {
|
|
1654
|
-
return milliseconds < 1e3 ? `${milliseconds}ms` : `${(milliseconds / 1e3).toFixed(milliseconds % 1e3 === 0 ? 0 : 1)}s`;
|
|
1655
|
-
}
|
|
1656
|
-
__name(formatDelay, "formatDelay");
|
|
1657
|
-
function formatBytes(bytes) {
|
|
1658
|
-
if (bytes < 1024) return `${bytes} B`;
|
|
1659
|
-
return `${(bytes / 1024).toFixed(1)} KiB`;
|
|
1660
|
-
}
|
|
1661
|
-
__name(formatBytes, "formatBytes");
|
|
1662
|
-
function instructionSourceLabel(source) {
|
|
1663
|
-
return source.type === "file" ? source.path : source.type;
|
|
1664
|
-
}
|
|
1665
|
-
__name(instructionSourceLabel, "instructionSourceLabel");
|
|
1666
|
-
function changeKindLabel(kind) {
|
|
1667
|
-
switch (kind) {
|
|
1668
|
-
case "create":
|
|
1669
|
-
return "created";
|
|
1670
|
-
case "update":
|
|
1671
|
-
return "updated";
|
|
1672
|
-
case "no-change":
|
|
1673
|
-
return "unchanged";
|
|
1674
|
-
}
|
|
1675
|
-
}
|
|
1676
|
-
__name(changeKindLabel, "changeKindLabel");
|
|
1677
|
-
function stringify(value) {
|
|
1678
|
-
try {
|
|
1679
|
-
return JSON.stringify(value, void 0, 2);
|
|
1680
|
-
} catch {
|
|
1681
|
-
return String(value);
|
|
1682
|
-
}
|
|
1683
|
-
}
|
|
1684
|
-
__name(stringify, "stringify");
|
|
1685
|
-
function truncate(text, limit) {
|
|
1686
|
-
return text.length <= limit ? text : `${text.slice(0, limit)}\u2026`;
|
|
1687
|
-
}
|
|
1688
|
-
__name(truncate, "truncate");
|
|
1689
|
-
function isAbortError(error) {
|
|
1690
|
-
return error instanceof Error && error.name === "AbortError";
|
|
1691
|
-
}
|
|
1692
|
-
__name(isAbortError, "isAbortError");
|
|
1693
|
-
function isCancellation(error) {
|
|
1694
|
-
return error instanceof Error && error.name === "RunCancelledError";
|
|
1695
|
-
}
|
|
1696
|
-
__name(isCancellation, "isCancellation");
|
|
1697
|
-
function errorMessage2(error) {
|
|
1698
|
-
if (error instanceof Error) return error.message;
|
|
1699
|
-
return typeof error === "string" ? error : "Unknown error";
|
|
1700
|
-
}
|
|
1701
|
-
__name(errorMessage2, "errorMessage");
|
|
1702
|
-
export {
|
|
1703
|
-
runTerminalUI
|
|
1704
|
-
};
|
|
1705
|
-
//# sourceMappingURL=tui-SA74DKMA.js.map
|