@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
|
@@ -1,29 +1,35 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
SlashCommandRegistry
|
|
4
|
+
} from "./chunk-Z3BOPBVU.js";
|
|
2
5
|
import {
|
|
3
6
|
UiError,
|
|
4
7
|
commandArgs
|
|
5
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-XTEMRAQW.js";
|
|
6
9
|
import {
|
|
7
|
-
GitCheckpointError,
|
|
8
|
-
GitWorkspaceConflictError,
|
|
9
10
|
parsePermissionMode
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-MNBYXL5Y.js";
|
|
11
12
|
import {
|
|
12
13
|
MaybeCodeUsageError,
|
|
13
14
|
mcpPromptToUserMessage,
|
|
14
15
|
mcpResourceToUserMessage,
|
|
15
16
|
previewMcpMessage
|
|
16
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-5SLWALZK.js";
|
|
17
18
|
import {
|
|
18
19
|
__name
|
|
19
20
|
} from "./chunk-E732GDOI.js";
|
|
20
21
|
|
|
22
|
+
// apps/maybecode/src/web-ui.ts
|
|
23
|
+
import { omitUndefined } from "@sortedyuan/may/core";
|
|
24
|
+
|
|
21
25
|
// packages/ui/client/dist/application.js
|
|
22
26
|
import { createHash as createHash2, randomUUID } from "node:crypto";
|
|
23
27
|
import { readEmbeddedImage } from "@sortedyuan/media";
|
|
28
|
+
import { AsyncStateSerializer } from "@sortedyuan/may/core";
|
|
24
29
|
|
|
25
30
|
// packages/ui/client/dist/projection.js
|
|
26
31
|
import { displayParts, imageAttachment } from "@sortedyuan/media";
|
|
32
|
+
import { isSessionRunTerminalEvent, readSessionTranscript, sessionToolFailureStatus } from "@sortedyuan/may/session";
|
|
27
33
|
var LIMIT = 65536;
|
|
28
34
|
function bounded(text) {
|
|
29
35
|
return text.length > LIMIT ? text.slice(0, LIMIT) + "\n\u2026\u663E\u793A\u5DF2\u622A\u65AD\uFF0C\u8BF7\u5728\u5BBF\u4E3B\u4E2D\u67E5\u770B\u5B8C\u6574\u5185\u5BB9\u3002" : text;
|
|
@@ -87,27 +93,21 @@ var UiProjection = class {
|
|
|
87
93
|
}
|
|
88
94
|
history(events) {
|
|
89
95
|
let inputId;
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
return message;
|
|
106
|
-
}));
|
|
107
|
-
} else if (event.type === "input.steering.finished" && event.status === "cancelled")
|
|
108
|
-
for (const id of event.inputIds)
|
|
109
|
-
steering.delete(id);
|
|
110
|
-
else if (event.type === "run.started" && inputId) {
|
|
96
|
+
for (const entry of readSessionTranscript(events)) {
|
|
97
|
+
if (entry.type === "user-message") {
|
|
98
|
+
if (entry.source !== "steering")
|
|
99
|
+
inputId = entry.id;
|
|
100
|
+
this.set({
|
|
101
|
+
id: entry.id,
|
|
102
|
+
kind: "user",
|
|
103
|
+
text: contentText(entry.message.content),
|
|
104
|
+
content: this.content(entry.message.content),
|
|
105
|
+
...entry.runId === void 0 ? {} : { runId: entry.runId }
|
|
106
|
+
});
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const event = entry.event;
|
|
110
|
+
if (event.type === "run.started" && inputId) {
|
|
111
111
|
const input = this.blocks.get(inputId);
|
|
112
112
|
if (input)
|
|
113
113
|
this.set({ ...input, runId: event.runId });
|
|
@@ -134,7 +134,13 @@ var UiProjection = class {
|
|
|
134
134
|
status: recovery.status
|
|
135
135
|
});
|
|
136
136
|
}
|
|
137
|
-
this.set({
|
|
137
|
+
this.set({
|
|
138
|
+
id: `run:${event.runId}`,
|
|
139
|
+
kind: "notice",
|
|
140
|
+
runId: event.runId,
|
|
141
|
+
text: "\u8FD0\u884C\u4E2D\u65AD\uFF1B\u8BF7\u6838\u5BF9\u5BBF\u4E3B\u6062\u590D\u8BC1\u636E\u3002\u4E0D\u4F1A\u81EA\u52A8\u91CD\u8DD1\u5DE5\u5177\u3002",
|
|
142
|
+
status: "interrupted"
|
|
143
|
+
});
|
|
138
144
|
} else if (event.type === "tool.started" || event.type === "tool.completed" || event.type === "tool.failed" || event.type === "run.failed" || event.type === "run.cancelled" || event.type === "run.completed" || event.type === "run.yielded")
|
|
139
145
|
this.run(event);
|
|
140
146
|
}
|
|
@@ -169,7 +175,13 @@ var UiProjection = class {
|
|
|
169
175
|
}
|
|
170
176
|
steered(runId, step, messages) {
|
|
171
177
|
for (const [index, message] of messages.entries())
|
|
172
|
-
this.set({
|
|
178
|
+
this.set({
|
|
179
|
+
id: `steering:${runId}:${step}:${index}`,
|
|
180
|
+
kind: "user",
|
|
181
|
+
runId,
|
|
182
|
+
text: contentText(message.content),
|
|
183
|
+
content: this.content(message.content)
|
|
184
|
+
});
|
|
173
185
|
}
|
|
174
186
|
permission(event, live) {
|
|
175
187
|
if (event.type === "approval.requested") {
|
|
@@ -223,7 +235,9 @@ var UiProjection = class {
|
|
|
223
235
|
id: event.requestId,
|
|
224
236
|
status: cancelled ? "cancelled" : denied ? "denied" : "allowed",
|
|
225
237
|
...block.approval.scopeDescription === void 0 ? {} : { scopeDescription: block.approval.scopeDescription },
|
|
226
|
-
...!cancelled && !denied ? {
|
|
238
|
+
...!cancelled && !denied ? {
|
|
239
|
+
scope: event.decision === "allow-session" ? "session" : event.decision === "allow-persistent" ? "persistent" : "once"
|
|
240
|
+
} : {}
|
|
227
241
|
}
|
|
228
242
|
});
|
|
229
243
|
break;
|
|
@@ -232,14 +246,28 @@ var UiProjection = class {
|
|
|
232
246
|
}
|
|
233
247
|
presentation(event) {
|
|
234
248
|
const id = `tool:${event.runId}:${event.toolCallId}`;
|
|
235
|
-
this.set({
|
|
249
|
+
this.set({
|
|
250
|
+
id,
|
|
251
|
+
kind: "tool",
|
|
252
|
+
runId: event.runId,
|
|
253
|
+
toolCallId: event.toolCallId,
|
|
254
|
+
text: "",
|
|
255
|
+
...this.blocks.get(id),
|
|
256
|
+
presentation: { kind: event.kind, version: event.version, text: displayValue(event.data) }
|
|
257
|
+
});
|
|
236
258
|
}
|
|
237
259
|
run(event) {
|
|
238
260
|
if (event.type === "input.received")
|
|
239
261
|
this.steered(event.runId, event.step, event.messages);
|
|
240
262
|
if ("step" in event && event.type.startsWith("model.")) {
|
|
241
263
|
const id = `assistant:${event.runId}:${event.step}`;
|
|
242
|
-
const previous = this.blocks.get(id) ?? {
|
|
264
|
+
const previous = this.blocks.get(id) ?? {
|
|
265
|
+
id,
|
|
266
|
+
kind: "assistant",
|
|
267
|
+
runId: event.runId,
|
|
268
|
+
text: "",
|
|
269
|
+
status: "streaming"
|
|
270
|
+
};
|
|
243
271
|
if (event.type === "model.text.delta")
|
|
244
272
|
this.set({ ...previous, text: (previous.text + event.delta).slice(0, LIMIT) });
|
|
245
273
|
else if (event.type === "model.reasoning.delta")
|
|
@@ -253,7 +281,7 @@ var UiProjection = class {
|
|
|
253
281
|
const id = `tool:${event.runId}:${event.call.id}`, previous = this.blocks.get(id);
|
|
254
282
|
let status = event.type === "tool.completed" ? "completed" : "running";
|
|
255
283
|
if (event.type === "tool.failed")
|
|
256
|
-
status = event.error
|
|
284
|
+
status = sessionToolFailureStatus(event.error, previous?.approval?.status === "cancelled");
|
|
257
285
|
const text = event.type === "tool.completed" ? displayValue(event.output) : event.type === "tool.output.delta" ? ((previous?.text ?? "") + event.delta).slice(-LIMIT) : previous?.text ?? "";
|
|
258
286
|
this.set({
|
|
259
287
|
...previous,
|
|
@@ -279,13 +307,14 @@ var UiProjection = class {
|
|
|
279
307
|
...event.type === "run.failed" ? { diagnostic: diagnostic(event.error) } : {},
|
|
280
308
|
status: event.type === "run.failed" ? "failed" : "cancelled"
|
|
281
309
|
});
|
|
282
|
-
if (
|
|
310
|
+
if (isSessionRunTerminalEvent(event))
|
|
283
311
|
this.settle(event.runId);
|
|
284
312
|
}
|
|
285
313
|
};
|
|
286
314
|
|
|
287
315
|
// packages/ui/client/dist/reading.js
|
|
288
316
|
import { createHash } from "node:crypto";
|
|
317
|
+
import { readSessionTranscript as readSessionTranscript2, readRecordedModelRequests } from "@sortedyuan/may/session";
|
|
289
318
|
var PAGE_SIZE = 50;
|
|
290
319
|
var PAGE_CHARACTERS = 262144;
|
|
291
320
|
function readPage(hostId, scope, items, request, matches, backwards = false) {
|
|
@@ -325,7 +354,7 @@ function historyPage(hostId, selectedId, blocks, request = {}, matches) {
|
|
|
325
354
|
}
|
|
326
355
|
__name(historyPage, "historyPage");
|
|
327
356
|
function fieldText(block, field) {
|
|
328
|
-
return field === "diagnostic" ? block.diagnostic?.message ?? "" : field === "presentation" ? block.presentation?.text ?? "" : block[field] ?? "";
|
|
357
|
+
return field === "request" ? "" : field === "diagnostic" ? block.diagnostic?.message ?? "" : field === "presentation" ? block.presentation?.text ?? "" : block[field] ?? "";
|
|
329
358
|
}
|
|
330
359
|
__name(fieldText, "fieldText");
|
|
331
360
|
function display(value) {
|
|
@@ -338,54 +367,56 @@ function display(value) {
|
|
|
338
367
|
__name(display, "display");
|
|
339
368
|
function eventFields(event) {
|
|
340
369
|
if (event.type === "approval.requested")
|
|
341
|
-
return {
|
|
370
|
+
return {
|
|
371
|
+
id: `tool:${event.request.runId}:${event.request.toolCallId}`,
|
|
372
|
+
fields: { input: display(event.request.input) }
|
|
373
|
+
};
|
|
342
374
|
if ("runId" in event && "call" in event)
|
|
343
|
-
return {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
375
|
+
return {
|
|
376
|
+
id: `tool:${event.runId}:${event.call.id}`,
|
|
377
|
+
fields: {
|
|
378
|
+
input: display(event.call.input),
|
|
379
|
+
...event.type === "tool.completed" ? { text: display(event.output) } : {},
|
|
380
|
+
...event.type === "tool.failed" ? { diagnostic: event.error.message } : {}
|
|
381
|
+
}
|
|
382
|
+
};
|
|
348
383
|
if (event.type === "tool.presentation")
|
|
349
384
|
return { id: `tool:${event.runId}:${event.toolCallId}`, fields: { presentation: display(event.data) } };
|
|
350
385
|
if (event.type === "assistant.completed")
|
|
351
|
-
return {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
386
|
+
return {
|
|
387
|
+
id: `assistant:${event.runId}:${event.step}`,
|
|
388
|
+
fields: {
|
|
389
|
+
text: event.message.content.filter((part) => part.type === "text").map((part) => part.text).join(""),
|
|
390
|
+
reasoning: event.message.content.filter((part) => part.type === "reasoning").map((part) => part.text).join("")
|
|
391
|
+
}
|
|
392
|
+
};
|
|
357
393
|
if (event.type === "run.failed")
|
|
358
394
|
return { id: `run:${event.runId}`, fields: { diagnostic: event.error.message } };
|
|
359
395
|
return void 0;
|
|
360
396
|
}
|
|
361
397
|
__name(eventFields, "eventFields");
|
|
362
398
|
function* historyFields(events) {
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
throw new Error(`Missing steering input in UI history: ${inputId}`);
|
|
372
|
-
steering.delete(inputId);
|
|
373
|
-
yield { id: `steering:${event.runId}:${event.step}:${index}`, fields: { text } };
|
|
374
|
-
}
|
|
399
|
+
for (const entry of readSessionTranscript2(events)) {
|
|
400
|
+
if (entry.type === "user-message") {
|
|
401
|
+
yield {
|
|
402
|
+
id: entry.id,
|
|
403
|
+
fields: {
|
|
404
|
+
text: entry.message.content.filter((part) => part.type === "text").map((part) => part.text).join("")
|
|
405
|
+
}
|
|
406
|
+
};
|
|
375
407
|
} else {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
for (const inputId of event.inputIds)
|
|
380
|
-
steering.delete(inputId);
|
|
381
|
-
const entry = eventFields(event);
|
|
382
|
-
if (entry)
|
|
383
|
-
yield entry;
|
|
408
|
+
const fields = eventFields(entry.event);
|
|
409
|
+
if (fields)
|
|
410
|
+
yield fields;
|
|
384
411
|
}
|
|
385
412
|
}
|
|
386
413
|
}
|
|
387
414
|
__name(historyFields, "historyFields");
|
|
388
415
|
function recordedField(events, block, field) {
|
|
416
|
+
if (field === "request") {
|
|
417
|
+
const requests = readRecordedModelRequests(events).filter((request) => block.id === `assistant:${request.runId}:${request.step}` || block.id === `run:${request.runId}`);
|
|
418
|
+
return requests.length > 0 ? JSON.stringify(requests, null, 2) : "\u6B64\u5904\u6CA1\u6709\u5DF2\u4FDD\u5B58\u7684\u6A21\u578B\u8BF7\u6C42\u3002";
|
|
419
|
+
}
|
|
389
420
|
let text = fieldText(block, field);
|
|
390
421
|
for (const entry of historyFields(events))
|
|
391
422
|
if (entry.id === block.id && entry.fields[field] !== void 0)
|
|
@@ -413,7 +444,14 @@ function fieldPage(hostId, selectedId, request, text) {
|
|
|
413
444
|
let end = Math.min(text.length, offset + 32768);
|
|
414
445
|
if (end < text.length && /[\uD800-\uDBFF]/u.test(text[end - 1]))
|
|
415
446
|
end--;
|
|
416
|
-
return {
|
|
447
|
+
return {
|
|
448
|
+
hostId,
|
|
449
|
+
text: text.slice(offset, end),
|
|
450
|
+
offset,
|
|
451
|
+
nextOffset: end < text.length ? end : null,
|
|
452
|
+
total: text.length,
|
|
453
|
+
version
|
|
454
|
+
};
|
|
417
455
|
}
|
|
418
456
|
__name(fieldPage, "fieldPage");
|
|
419
457
|
|
|
@@ -430,7 +468,10 @@ var ApplicationUiHost = class {
|
|
|
430
468
|
listeners = /* @__PURE__ */ new Set();
|
|
431
469
|
iterator;
|
|
432
470
|
relay;
|
|
433
|
-
|
|
471
|
+
mutations = new AsyncStateSerializer();
|
|
472
|
+
pendingCommands = /* @__PURE__ */ new Set();
|
|
473
|
+
closed = false;
|
|
474
|
+
closing;
|
|
434
475
|
fault;
|
|
435
476
|
constructor(app, options) {
|
|
436
477
|
this.app = app;
|
|
@@ -442,6 +483,7 @@ var ApplicationUiHost = class {
|
|
|
442
483
|
});
|
|
443
484
|
}
|
|
444
485
|
subscribe(listener) {
|
|
486
|
+
this.assertOpen();
|
|
445
487
|
this.listeners.add(listener);
|
|
446
488
|
return () => this.listeners.delete(listener);
|
|
447
489
|
}
|
|
@@ -470,12 +512,31 @@ var ApplicationUiHost = class {
|
|
|
470
512
|
return this.queuedSnapshot();
|
|
471
513
|
}
|
|
472
514
|
queuedSnapshot(selectedId, all = false) {
|
|
473
|
-
|
|
474
|
-
this.
|
|
475
|
-
|
|
476
|
-
|
|
515
|
+
this.assertOpen();
|
|
516
|
+
return this.mutations.idle().then(() => this.buildSnapshot(selectedId, 0, all));
|
|
517
|
+
}
|
|
518
|
+
commandNames(viewingActive = true) {
|
|
519
|
+
if (this.closed || this.fault)
|
|
520
|
+
return [];
|
|
521
|
+
const running = this.app.isRunning, commands = [];
|
|
522
|
+
if (!running)
|
|
523
|
+
commands.push("session.new", "session.activate", "session.delete");
|
|
524
|
+
if (viewingActive) {
|
|
525
|
+
commands.push(...running ? ["run.cancel", ...this.projection.interactions.size ? ["approval.resolve"] : []] : ["message.submit", "session.rename", "context.compact", ...this.options.commands ?? []]);
|
|
526
|
+
commands.push(...this.options.concurrentCommands ?? []);
|
|
527
|
+
if (this.options.permissionRules !== void 0)
|
|
528
|
+
commands.push("permission.rules.list", "permission.rules.revoke");
|
|
529
|
+
if (this.options.permissionRules?.create !== void 0)
|
|
530
|
+
commands.push("permission.rules.create");
|
|
531
|
+
}
|
|
532
|
+
return this.options.available ? commands.filter((name) => this.options.available(name)) : commands;
|
|
533
|
+
}
|
|
534
|
+
assertOpen() {
|
|
535
|
+
if (this.closed)
|
|
536
|
+
throw new UiError(503, "\u5BBF\u4E3B\u6B63\u5728\u5173\u95ED\u3002");
|
|
477
537
|
}
|
|
478
538
|
async buildSnapshot(selectedId, attempt = 0, all = false) {
|
|
539
|
+
this.assertOpen();
|
|
479
540
|
const revision = this.revision, activeId = this.app.sessionId, running = this.app.isRunning;
|
|
480
541
|
const viewingId = selectedId ?? activeId, viewingActive = viewingId === activeId;
|
|
481
542
|
const sessions = await this.app.listSessions();
|
|
@@ -485,7 +546,13 @@ var ApplicationUiHost = class {
|
|
|
485
546
|
throw new UiError(409, "\u5F53\u524D\u5BBF\u4E3B\u4E0D\u652F\u6301\u53EA\u8BFB\u5386\u53F2\u6D4F\u89C8\u3002");
|
|
486
547
|
const history = viewingActive ? await this.app.history() : await this.app.readSessionHistory(viewingId);
|
|
487
548
|
const visibleSessions = sessions.filter((session, index) => index < 500 || session.id === viewingId || session.id === activeId);
|
|
488
|
-
const resources = visibleSessions.map((s) => ({
|
|
549
|
+
const resources = visibleSessions.map((s) => ({
|
|
550
|
+
id: s.id,
|
|
551
|
+
kind: "session",
|
|
552
|
+
title: s.title ?? s.preview?.slice(0, 72) ?? "\u65B0\u4F1A\u8BDD",
|
|
553
|
+
status: s.id === activeId && running ? "running" : "idle",
|
|
554
|
+
updatedAt: s.lastUsedAt
|
|
555
|
+
}));
|
|
489
556
|
const resourcesVersion = createHash2("sha256").update(JSON.stringify([...sessions].sort((a, b) => b.createdAt - a.createdAt || a.id.localeCompare(b.id)).map((s) => [s.id, s.createdAt, s.title ?? s.preview?.slice(0, 72) ?? "\u65B0\u4F1A\u8BDD"]))).digest("hex");
|
|
490
557
|
const projected = new UiProjection(Infinity);
|
|
491
558
|
projected.history(history);
|
|
@@ -500,24 +567,7 @@ var ApplicationUiHost = class {
|
|
|
500
567
|
...interaction,
|
|
501
568
|
choices: this.options.permissionActor === void 0 ? interaction.choices.filter((choice) => choice.value !== "allow-persistent") : interaction.choices
|
|
502
569
|
})) : [];
|
|
503
|
-
const commands =
|
|
504
|
-
if (!running)
|
|
505
|
-
commands.push("session.new", "session.activate", "session.delete");
|
|
506
|
-
if (viewingActive)
|
|
507
|
-
commands.push(...running ? ["run.cancel", ...interactions.length ? ["approval.resolve"] : []] : ["message.submit", "session.rename", "context.compact", ...this.options.commands ?? []]);
|
|
508
|
-
if (viewingActive)
|
|
509
|
-
commands.push(...this.options.concurrentCommands ?? []);
|
|
510
|
-
if (viewingActive && this.options.permissionRules !== void 0)
|
|
511
|
-
commands.push("permission.rules.list", "permission.rules.revoke");
|
|
512
|
-
if (viewingActive && this.options.permissionRules?.create !== void 0)
|
|
513
|
-
commands.push("permission.rules.create");
|
|
514
|
-
if (this.options.available) {
|
|
515
|
-
for (let index = commands.length - 1; index >= 0; index--)
|
|
516
|
-
if (!this.options.available(commands[index]))
|
|
517
|
-
commands.splice(index, 1);
|
|
518
|
-
}
|
|
519
|
-
if (this.fault)
|
|
520
|
-
commands.length = 0;
|
|
570
|
+
const commands = this.commandNames(viewingActive);
|
|
521
571
|
const panels = viewingActive ? await this.options.panels?.() ?? [] : [];
|
|
522
572
|
const choices = viewingActive ? await this.options.choices?.() ?? [] : [];
|
|
523
573
|
const workspace = await this.options.workspace?.();
|
|
@@ -528,6 +578,7 @@ var ApplicationUiHost = class {
|
|
|
528
578
|
});
|
|
529
579
|
const checkpoints = await this.options.checkpoints?.(viewingId);
|
|
530
580
|
const worktrees = await this.options.worktrees?.();
|
|
581
|
+
this.assertOpen();
|
|
531
582
|
if (activeId !== this.app.sessionId || running !== this.app.isRunning) {
|
|
532
583
|
if (attempt < 2)
|
|
533
584
|
return this.buildSnapshot(selectedId, attempt + 1, all);
|
|
@@ -550,13 +601,32 @@ var ApplicationUiHost = class {
|
|
|
550
601
|
activeId,
|
|
551
602
|
blocks: all ? [...projected.blocks.values()] : page.items,
|
|
552
603
|
historyPage: { nextCursor: page.nextCursor, total: page.total },
|
|
553
|
-
reads: {
|
|
604
|
+
reads: {
|
|
605
|
+
resources: true,
|
|
606
|
+
history: Boolean(this.app.readSessionHistory),
|
|
607
|
+
fields: Boolean(this.app.readSessionHistory)
|
|
608
|
+
},
|
|
554
609
|
interactions,
|
|
555
610
|
commands,
|
|
556
611
|
panels: [
|
|
557
|
-
{
|
|
612
|
+
{
|
|
613
|
+
id: "workspace",
|
|
614
|
+
title: "\u5DE5\u4F5C\u533A",
|
|
615
|
+
fields: [
|
|
616
|
+
{ label: "\u76EE\u5F55", value: this.app.workspace },
|
|
617
|
+
{ label: "\u5F53\u524D\u4F1A\u8BDD", value: viewingId },
|
|
618
|
+
{ label: "\u6267\u884C\u72B6\u6001", value: running ? "\u8FD0\u884C\u4E2D" : "\u7A7A\u95F2" }
|
|
619
|
+
]
|
|
620
|
+
},
|
|
558
621
|
...panels,
|
|
559
|
-
...viewingActive && this.options.permissionRules !== void 0 ? [
|
|
622
|
+
...viewingActive && this.options.permissionRules !== void 0 ? [
|
|
623
|
+
{
|
|
624
|
+
id: "permission-rules",
|
|
625
|
+
title: "\u6301\u4E45\u6743\u9650\u89C4\u5219",
|
|
626
|
+
fields: [],
|
|
627
|
+
actions: [{ label: "\u67E5\u770B\u548C\u7BA1\u7406\u89C4\u5219", command: "permission.rules.list", args: {} }]
|
|
628
|
+
}
|
|
629
|
+
] : []
|
|
560
630
|
],
|
|
561
631
|
choices,
|
|
562
632
|
...viewingActive && this.options.controls ? { controls: this.options.controls() } : {},
|
|
@@ -564,11 +634,19 @@ var ApplicationUiHost = class {
|
|
|
564
634
|
};
|
|
565
635
|
}
|
|
566
636
|
async resources(request) {
|
|
637
|
+
this.assertOpen();
|
|
567
638
|
const sessions = [...await this.app.listSessions()].sort((a, b) => b.createdAt - a.createdAt || a.id.localeCompare(b.id));
|
|
568
|
-
const items = sessions.map((s) => ({
|
|
639
|
+
const items = sessions.map((s) => ({
|
|
640
|
+
id: s.id,
|
|
641
|
+
kind: "session",
|
|
642
|
+
title: s.title ?? s.preview?.slice(0, 72) ?? "\u65B0\u4F1A\u8BDD",
|
|
643
|
+
status: s.id === this.app.sessionId && this.app.isRunning ? "running" : "idle",
|
|
644
|
+
updatedAt: s.lastUsedAt
|
|
645
|
+
}));
|
|
569
646
|
return readPage(this.hostId, "resources", items, request, (item, query) => item.title.toLocaleLowerCase().includes(query));
|
|
570
647
|
}
|
|
571
648
|
async media(selectedId, id) {
|
|
649
|
+
this.assertOpen();
|
|
572
650
|
if (!(await this.app.listSessions()).some((session) => session.id === selectedId))
|
|
573
651
|
throw new UiError(404, "\u4F1A\u8BDD\u4E0D\u5B58\u5728\u6216\u4E0D\u5C5E\u4E8E\u5F53\u524D\u5DE5\u4F5C\u533A\u3002");
|
|
574
652
|
const events = selectedId === this.app.sessionId ? await this.app.history() : await this.app.readSessionHistory?.(selectedId);
|
|
@@ -596,14 +674,16 @@ var ApplicationUiHost = class {
|
|
|
596
674
|
return fieldPage(this.hostId, selectedId, request, recordedField(events, block, request.field));
|
|
597
675
|
}
|
|
598
676
|
execute(command) {
|
|
599
|
-
if (this.
|
|
600
|
-
return
|
|
601
|
-
const
|
|
602
|
-
this.
|
|
603
|
-
|
|
677
|
+
if (this.closed)
|
|
678
|
+
return Promise.reject(new UiError(503, "\u5BBF\u4E3B\u6B63\u5728\u5173\u95ED\u3002"));
|
|
679
|
+
const concurrent = this.options.concurrentCommands?.includes(command.name) === true;
|
|
680
|
+
const work = concurrent ? Promise.resolve().then(() => this.apply(command)) : this.mutations.run(() => this.apply(command));
|
|
681
|
+
this.pendingCommands.add(work);
|
|
682
|
+
void work.then(() => this.pendingCommands.delete(work), () => this.pendingCommands.delete(work));
|
|
604
683
|
return work;
|
|
605
684
|
}
|
|
606
685
|
async complete(selectedId, text) {
|
|
686
|
+
this.assertOpen();
|
|
607
687
|
if (selectedId !== this.app.sessionId || !this.options.complete)
|
|
608
688
|
throw new UiError(409, "\u5F53\u524D\u4F1A\u8BDD\u4E0D\u652F\u6301\u547D\u4EE4\u8865\u5168\u3002");
|
|
609
689
|
return { hostId: this.hostId, items: await this.options.complete(text) };
|
|
@@ -613,20 +693,22 @@ var ApplicationUiHost = class {
|
|
|
613
693
|
if (!command.targetId)
|
|
614
694
|
throw new UiError(409, "\u8BF7\u6307\u5B9A\u4F1A\u8BDD\u3002");
|
|
615
695
|
const assertCurrent = /* @__PURE__ */ __name(() => {
|
|
696
|
+
this.assertOpen();
|
|
616
697
|
if (command.hostId !== this.hostId || (transition ? command.expectedActiveId !== this.app.sessionId : command.targetId !== this.app.sessionId))
|
|
617
698
|
throw new UiError(409, "\u5F53\u524D\u4F1A\u8BDD\u5DF2\u6539\u53D8\uFF0C\u8BF7\u68C0\u67E5\u5F53\u524D\u72B6\u6001\u540E\u91CD\u8BD5\u3002");
|
|
618
699
|
}, "assertCurrent");
|
|
700
|
+
const assertAllowed = /* @__PURE__ */ __name(() => {
|
|
701
|
+
assertCurrent();
|
|
702
|
+
if (!this.commandNames().includes(command.name))
|
|
703
|
+
throw new UiError(409, "\u5F53\u524D\u72B6\u6001\u4E0D\u5141\u8BB8\u6B64\u64CD\u4F5C\u3002");
|
|
704
|
+
}, "assertAllowed");
|
|
619
705
|
assertCurrent();
|
|
620
706
|
if (this.options.interactionCommands?.includes(command.name)) {
|
|
621
707
|
if (!this.options.available?.(command.name) || !this.options.execute)
|
|
622
708
|
throw new UiError(409, "\u4EA4\u4E92\u5DF2\u4E0D\u53EF\u7528\u3002");
|
|
623
709
|
return this.options.execute(command);
|
|
624
710
|
}
|
|
625
|
-
|
|
626
|
-
throw new UiError(409, "\u5F53\u524D\u72B6\u6001\u4E0D\u5141\u8BB8\u6B64\u64CD\u4F5C\u3002");
|
|
627
|
-
if (this.options.available && !this.options.available(command.name))
|
|
628
|
-
throw new UiError(409, "\u5F53\u524D\u72B6\u6001\u4E0D\u5141\u8BB8\u6B64\u64CD\u4F5C\u3002");
|
|
629
|
-
assertCurrent();
|
|
711
|
+
assertAllowed();
|
|
630
712
|
switch (command.name) {
|
|
631
713
|
case "message.submit": {
|
|
632
714
|
commandArgs(command, ["text"]);
|
|
@@ -635,6 +717,7 @@ var ApplicationUiHost = class {
|
|
|
635
717
|
const receipt = await this.options.submit?.(command.args.text);
|
|
636
718
|
if (receipt)
|
|
637
719
|
return receipt;
|
|
720
|
+
assertAllowed();
|
|
638
721
|
const run = await this.app.submit({ input: command.args.text, inputId: `web:${command.requestId}` });
|
|
639
722
|
void run.result.catch(() => {
|
|
640
723
|
}).finally(() => this.changed());
|
|
@@ -662,19 +745,33 @@ var ApplicationUiHost = class {
|
|
|
662
745
|
case "permission.rules.list": {
|
|
663
746
|
commandArgs(command, []);
|
|
664
747
|
const rules = await this.options.permissionRules.list();
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
748
|
+
assertAllowed();
|
|
749
|
+
return {
|
|
750
|
+
selectedId: this.app.sessionId,
|
|
751
|
+
output: {
|
|
752
|
+
title: "\u6301\u4E45\u6743\u9650\u89C4\u5219",
|
|
753
|
+
text: rules.length === 0 ? "\u5F53\u524D\u6CA1\u6709\u6301\u4E45\u6743\u9650\u89C4\u5219\u3002" : rules.map((rule) => `${rule.decision === "allow" ? "\u5141\u8BB8" : "\u7981\u6B62"} \xB7 ${rule.toolName}
|
|
668
754
|
${rule.description}
|
|
669
755
|
\u8303\u56F4\uFF1A${rule.scopeId}
|
|
670
756
|
\u521B\u5EFA\u8005\uFF1A${rule.createdBy}
|
|
671
757
|
\u6709\u6548\u671F\uFF1A${rule.expiresAt === void 0 ? "\u6301\u7EED\u6709\u6548" : new Date(rule.expiresAt).toISOString()}
|
|
672
758
|
\u89C4\u5219 ID\uFF1A${rule.id}`).join("\n\n"),
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
759
|
+
actions: rules.flatMap((rule) => [
|
|
760
|
+
{
|
|
761
|
+
label: `\u64A4\u9500 ${rule.description}`,
|
|
762
|
+
command: "permission.rules.revoke",
|
|
763
|
+
args: { id: rule.id },
|
|
764
|
+
confirm: `\u786E\u8BA4\u64A4\u9500\u89C4\u5219 ${rule.id}\uFF1F\u540E\u7EED\u5DE5\u5177\u8C03\u7528\u5C06\u91CD\u65B0\u68C0\u67E5\u6743\u9650\u3002`
|
|
765
|
+
},
|
|
766
|
+
...this.options.permissionRules.create === void 0 ? [] : ["allow", "deny"].map((decision) => ({
|
|
767
|
+
label: `\u6309\u6B64\u8303\u56F4\u521B\u5EFA${decision === "allow" ? "\u5141\u8BB8" : "\u7981\u6B62"}\u89C4\u5219`,
|
|
768
|
+
command: "permission.rules.create",
|
|
769
|
+
args: { sourceId: rule.id, decision },
|
|
770
|
+
confirm: `\u786E\u8BA4${decision === "allow" ? "\u6301\u7EED\u5141\u8BB8" : "\u6301\u7EED\u7981\u6B62"}\uFF1A${rule.description}\uFF1F\u8303\u56F4\uFF1A${rule.scopeId}\u3002\u7981\u6B62\u89C4\u5219\u4F18\u5148\u4E8E\u5141\u8BB8\u89C4\u5219\u3002`
|
|
771
|
+
}))
|
|
772
|
+
])
|
|
773
|
+
}
|
|
774
|
+
};
|
|
678
775
|
}
|
|
679
776
|
case "permission.rules.create": {
|
|
680
777
|
commandArgs(command, ["sourceId", "decision"]);
|
|
@@ -683,6 +780,7 @@ ${rule.description}
|
|
|
683
780
|
throw new UiError(400, "\u65E0\u6548\u7684\u89C4\u5219\u51B3\u5B9A\u3002");
|
|
684
781
|
if (!(await this.options.permissionRules.list()).some((rule) => rule.id === command.args.sourceId))
|
|
685
782
|
throw new UiError(404, "\u89C4\u5219\u4E0D\u5C5E\u4E8E\u5F53\u524D\u6743\u9650\u8303\u56F4\u3002");
|
|
783
|
+
assertAllowed();
|
|
686
784
|
await this.options.permissionRules.create(command.args.sourceId, decision);
|
|
687
785
|
break;
|
|
688
786
|
}
|
|
@@ -690,6 +788,7 @@ ${rule.description}
|
|
|
690
788
|
commandArgs(command, ["id"]);
|
|
691
789
|
if (!(await this.options.permissionRules.list()).some((rule) => rule.id === command.args.id))
|
|
692
790
|
throw new UiError(404, "\u89C4\u5219\u4E0D\u5C5E\u4E8E\u5F53\u524D\u6743\u9650\u8303\u56F4\u3002");
|
|
791
|
+
assertAllowed();
|
|
693
792
|
if (!await this.options.permissionRules.revoke(command.args.id))
|
|
694
793
|
throw new UiError(404, "\u89C4\u5219\u5DF2\u7ECF\u64A4\u9500\u3002");
|
|
695
794
|
break;
|
|
@@ -703,7 +802,7 @@ ${rule.description}
|
|
|
703
802
|
commandArgs(command, []);
|
|
704
803
|
if (!(await this.app.listSessions()).some((session) => session.id === command.targetId))
|
|
705
804
|
throw new UiError(404, "\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u5F53\u524D\u5DE5\u4F5C\u533A\u3002");
|
|
706
|
-
|
|
805
|
+
assertAllowed();
|
|
707
806
|
await this.app.resumeSession(command.targetId);
|
|
708
807
|
this.projection = new UiProjection();
|
|
709
808
|
break;
|
|
@@ -715,7 +814,7 @@ ${rule.description}
|
|
|
715
814
|
const sessions = await this.app.listSessions();
|
|
716
815
|
if (!sessions.some((session) => session.id === command.targetId))
|
|
717
816
|
throw new UiError(404, "\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u5F53\u524D\u5DE5\u4F5C\u533A\u3002");
|
|
718
|
-
|
|
817
|
+
assertAllowed();
|
|
719
818
|
if (!await this.app.deleteSession(command.targetId))
|
|
720
819
|
throw new UiError(404, "\u4F1A\u8BDD\u5DF2\u4E0D\u5B58\u5728\u3002");
|
|
721
820
|
break;
|
|
@@ -739,14 +838,25 @@ ${rule.description}
|
|
|
739
838
|
this.changed();
|
|
740
839
|
return { selectedId: this.app.sessionId };
|
|
741
840
|
}
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
841
|
+
close() {
|
|
842
|
+
if (this.closing)
|
|
843
|
+
return this.closing;
|
|
844
|
+
this.closed = true;
|
|
845
|
+
return this.closing = this.closeOnce();
|
|
846
|
+
}
|
|
847
|
+
async closeOnce() {
|
|
848
|
+
const [applicationClosing] = await Promise.allSettled([
|
|
849
|
+
this.options.closeApplication === false ? Promise.resolve() : Promise.resolve().then(() => this.app.close()),
|
|
850
|
+
...this.pendingCommands
|
|
851
|
+
]);
|
|
852
|
+
try {
|
|
853
|
+
await this.iterator.return?.();
|
|
854
|
+
await this.relay;
|
|
855
|
+
} finally {
|
|
856
|
+
this.listeners.clear();
|
|
857
|
+
}
|
|
858
|
+
if (applicationClosing?.status === "rejected")
|
|
859
|
+
throw applicationClosing.reason;
|
|
750
860
|
}
|
|
751
861
|
};
|
|
752
862
|
|
|
@@ -759,7 +869,10 @@ function createTelemetryPanel(data) {
|
|
|
759
869
|
id: "telemetry",
|
|
760
870
|
title: "\u8FD0\u884C\u8BCA\u65AD",
|
|
761
871
|
fields: [
|
|
762
|
-
{
|
|
872
|
+
{
|
|
873
|
+
label: "\u8BB0\u5F55\u8303\u56F4",
|
|
874
|
+
value: `${data.total} \u6761\u672C\u5730\u8BB0\u5F55\uFF0C${data.evictedSpans} \u6761\u5DF2\u8D85\u8FC7\u4FDD\u7559\u8303\u56F4${data.hasMore ? "\uFF0C\u8FD8\u6709\u540E\u7EED\u8BB0\u5F55" : ""}\u3002`
|
|
875
|
+
},
|
|
763
876
|
...spans.slice(0, 40).map((span) => ({
|
|
764
877
|
label: `${new Date(span.startTime).toISOString()} \xB7 ${span.name}`,
|
|
765
878
|
value: `${span.ended ? span.status ?? "\u672A\u77E5\u7ED3\u679C" : "\u6B63\u5728\u6267\u884C"} \xB7 ${span.durationMs === void 0 ? "\u8017\u65F6\u5C1A\u672A\u786E\u5B9A" : `${span.durationMs} ms`} \xB7 span ${span.context.spanId}${span.parentSpanId === void 0 ? "" : ` \xB7 parent ${span.parentSpanId}`} \xB7 ${span.sampled ? "\u5DF2\u9009\u62E9\u8FDC\u7A0B\u5BFC\u51FA" : "\u672C\u5730\u8BB0\u5F55"}`
|
|
@@ -769,6 +882,9 @@ function createTelemetryPanel(data) {
|
|
|
769
882
|
}
|
|
770
883
|
__name(createTelemetryPanel, "createTelemetryPanel");
|
|
771
884
|
|
|
885
|
+
// apps/maybecode/src/web-commands.ts
|
|
886
|
+
import { GitCheckpointError, GitWorkspaceConflictError } from "@sortedyuan/may/application/git-workspace";
|
|
887
|
+
|
|
772
888
|
// apps/maybecode/src/mcp-commands.ts
|
|
773
889
|
var MCP_COMMAND_USAGE = "/mcp [apps | catalog [server] | refresh [server] | reconnect server | read server uri | attach server uri [question] | template server uri-template {arguments} | prompt server name {arguments} | use-prompt server name {arguments} | complete server {params} | watch server uri | unwatch server uri | tasks [server] | task-get server id | task-wait server id | task-update server id | task-retry-input server id | task-cancel server id | task-forget server id | task-attach server id [question]]";
|
|
774
890
|
async function executeMcpCommand(input, controller) {
|
|
@@ -776,18 +892,37 @@ async function executeMcpCommand(input, controller) {
|
|
|
776
892
|
const [, action, serverId, tail] = match;
|
|
777
893
|
const display2 = /* @__PURE__ */ __name((text) => ({ type: "mcp.display", text: text.slice(0, 16e3) }), "display");
|
|
778
894
|
const usage2 = /* @__PURE__ */ __name(() => ({ type: "usage", usage: MCP_COMMAND_USAGE }), "usage");
|
|
779
|
-
if (action === "apps")
|
|
895
|
+
if (action === "apps")
|
|
896
|
+
return display2(
|
|
897
|
+
"MCP Apps HTML is not supported in this terminal. Text tool results remain available; use an explicitly configured isolated graphical Host. No HTML was fetched or executed."
|
|
898
|
+
);
|
|
780
899
|
if (action === void 0) return { type: "mcp.status", servers: await controller.getMcpStatus() };
|
|
781
900
|
if (action === "tasks" && tail === void 0 && controller.listMcpTasks !== void 0) {
|
|
782
|
-
const records = (await controller.listMcpTasks()).filter(
|
|
783
|
-
|
|
901
|
+
const records = (await controller.listMcpTasks()).filter(
|
|
902
|
+
(record) => serverId === void 0 || record.binding.serverId === serverId
|
|
903
|
+
);
|
|
904
|
+
return display2(
|
|
905
|
+
JSON.stringify(
|
|
906
|
+
records.map(({ id, binding, status, cancellation }) => ({
|
|
907
|
+
id,
|
|
908
|
+
server: binding.serverId,
|
|
909
|
+
tool: binding.toolName,
|
|
910
|
+
status,
|
|
911
|
+
cancellation
|
|
912
|
+
})),
|
|
913
|
+
null,
|
|
914
|
+
2
|
|
915
|
+
)
|
|
916
|
+
);
|
|
784
917
|
}
|
|
785
918
|
if (action === "catalog" && tail === void 0 && controller.getMcpCatalog !== void 0) {
|
|
786
919
|
const catalogs = controller.getMcpCatalog().filter((catalog) => serverId === void 0 || catalog.serverId === serverId);
|
|
787
920
|
return display2(JSON.stringify(catalogs, null, 2));
|
|
788
921
|
}
|
|
789
|
-
if (action === "refresh" && tail === void 0 && controller.refreshMcp !== void 0)
|
|
790
|
-
|
|
922
|
+
if (action === "refresh" && tail === void 0 && controller.refreshMcp !== void 0)
|
|
923
|
+
await controller.refreshMcp(serverId);
|
|
924
|
+
else if (action === "reconnect" && serverId !== void 0 && tail === void 0 && controller.reconnectMcp !== void 0)
|
|
925
|
+
await controller.reconnectMcp(serverId);
|
|
791
926
|
else {
|
|
792
927
|
if (serverId === void 0 || tail === void 0) return usage2();
|
|
793
928
|
if (action === "complete" && controller.completeMcp !== void 0) {
|
|
@@ -796,15 +931,28 @@ async function executeMcpCommand(input, controller) {
|
|
|
796
931
|
const target = /^(\S+)(?:\s+([\s\S]*))?$/u.exec(tail);
|
|
797
932
|
const name = target[1];
|
|
798
933
|
const rest = target[2];
|
|
799
|
-
if (action === "task-attach" && controller.submitMcpTask !== void 0)
|
|
934
|
+
if (action === "task-attach" && controller.submitMcpTask !== void 0)
|
|
935
|
+
return { type: "mcp.run-started", run: await controller.submitMcpTask(serverId, name, rest) };
|
|
800
936
|
if (rest === void 0) {
|
|
801
|
-
if (action === "task-get" && controller.getMcpTask !== void 0)
|
|
802
|
-
|
|
803
|
-
if (action === "task-
|
|
804
|
-
|
|
937
|
+
if (action === "task-get" && controller.getMcpTask !== void 0)
|
|
938
|
+
return display2(JSON.stringify((await controller.getMcpTask(serverId, name)).state, null, 2));
|
|
939
|
+
if (action === "task-wait" && controller.waitMcpTask !== void 0)
|
|
940
|
+
return display2(JSON.stringify((await controller.waitMcpTask(serverId, name)).state, null, 2));
|
|
941
|
+
if (action === "task-update" && controller.updateMcpTask !== void 0)
|
|
942
|
+
return display2(JSON.stringify((await controller.updateMcpTask(serverId, name)).state, null, 2));
|
|
943
|
+
if (action === "task-retry-input" && controller.updateMcpTask !== void 0)
|
|
944
|
+
return display2(
|
|
945
|
+
JSON.stringify(
|
|
946
|
+
(await controller.updateMcpTask(serverId, name, { retryAbandonedInputs: true })).state,
|
|
947
|
+
null,
|
|
948
|
+
2
|
|
949
|
+
)
|
|
950
|
+
);
|
|
805
951
|
if (action === "task-cancel" && controller.cancelMcpTask !== void 0) {
|
|
806
952
|
const record = await controller.cancelMcpTask(serverId, name);
|
|
807
|
-
return display2(
|
|
953
|
+
return display2(
|
|
954
|
+
`Cancellation ${record.cancellation}; last observed status: ${record.status}. Acknowledgement does not prove the remote work stopped.`
|
|
955
|
+
);
|
|
808
956
|
}
|
|
809
957
|
if (action === "task-forget" && controller.forgetMcpTask !== void 0) {
|
|
810
958
|
await controller.forgetMcpTask(serverId, name);
|
|
@@ -815,16 +963,29 @@ async function executeMcpCommand(input, controller) {
|
|
|
815
963
|
return display2(previewMcpMessage(mcpResourceToUserMessage(await controller.readMcpResource(serverId, name))));
|
|
816
964
|
}
|
|
817
965
|
if (action === "template" && rest !== void 0 && controller.readMcpResourceTemplate !== void 0) {
|
|
818
|
-
return display2(
|
|
966
|
+
return display2(
|
|
967
|
+
previewMcpMessage(
|
|
968
|
+
mcpResourceToUserMessage(await controller.readMcpResourceTemplate(serverId, name, JSON.parse(rest)))
|
|
969
|
+
)
|
|
970
|
+
);
|
|
819
971
|
}
|
|
820
972
|
if (action === "attach" && controller.submitMcpResource !== void 0) {
|
|
821
973
|
return { type: "mcp.run-started", run: await controller.submitMcpResource(serverId, name, rest) };
|
|
822
974
|
}
|
|
823
975
|
if (action === "prompt" && controller.getMcpPrompt !== void 0) {
|
|
824
|
-
return display2(
|
|
976
|
+
return display2(
|
|
977
|
+
previewMcpMessage(
|
|
978
|
+
mcpPromptToUserMessage(
|
|
979
|
+
await controller.getMcpPrompt(serverId, name, rest === void 0 ? {} : JSON.parse(rest))
|
|
980
|
+
)
|
|
981
|
+
)
|
|
982
|
+
);
|
|
825
983
|
}
|
|
826
984
|
if (action === "use-prompt" && controller.submitMcpPrompt !== void 0) {
|
|
827
|
-
return {
|
|
985
|
+
return {
|
|
986
|
+
type: "mcp.run-started",
|
|
987
|
+
run: await controller.submitMcpPrompt(serverId, name, rest === void 0 ? {} : JSON.parse(rest))
|
|
988
|
+
};
|
|
828
989
|
}
|
|
829
990
|
if (action === "watch" && rest === void 0 && controller.watchMcpResource !== void 0) {
|
|
830
991
|
await controller.watchMcpResource(serverId, name);
|
|
@@ -852,7 +1013,8 @@ function parseGoalStart(arguments_) {
|
|
|
852
1013
|
if (!(option in fields)) throw new Error(`Unknown goal option: ${option}`);
|
|
853
1014
|
const field = fields[option];
|
|
854
1015
|
const text = arguments_[index++];
|
|
855
|
-
if (text === void 0 || !/^\d+$/u.test(text) || !Number.isSafeInteger(Number(text)) || Number(text) <= 0)
|
|
1016
|
+
if (text === void 0 || !/^\d+$/u.test(text) || !Number.isSafeInteger(Number(text)) || Number(text) <= 0)
|
|
1017
|
+
throw new Error(`${option} requires a positive safe integer`);
|
|
856
1018
|
if (budget[field] !== void 0) throw new Error(`Duplicate goal option: ${option}`);
|
|
857
1019
|
budget[field] = Number(text);
|
|
858
1020
|
}
|
|
@@ -862,7 +1024,6 @@ function parseGoalStart(arguments_) {
|
|
|
862
1024
|
}
|
|
863
1025
|
__name(parseGoalStart, "parseGoalStart");
|
|
864
1026
|
async function executeGoalCommand(arguments_, app) {
|
|
865
|
-
if (!app.getGoal) throw new Error("This controller does not support goals");
|
|
866
1027
|
const [verb = "status", ...rest] = arguments_;
|
|
867
1028
|
if (verb === "start") {
|
|
868
1029
|
if (!app.startGoal) throw new Error("This controller cannot start goals");
|
|
@@ -870,7 +1031,7 @@ async function executeGoalCommand(arguments_, app) {
|
|
|
870
1031
|
return formatGoal(await app.startGoal(objective, budget));
|
|
871
1032
|
}
|
|
872
1033
|
if (rest.length) throw new Error(GOAL_COMMAND_USAGE);
|
|
873
|
-
if (verb === "status") return formatGoal(app.getGoal());
|
|
1034
|
+
if (verb === "status") return formatGoal(app.application.getGoal());
|
|
874
1035
|
const method = verb === "pause" ? app.pauseGoal : verb === "resume" ? app.resumeGoal : verb === "cancel" ? app.cancelGoal : void 0;
|
|
875
1036
|
if (!method) throw new Error(GOAL_COMMAND_USAGE);
|
|
876
1037
|
return formatGoal(await method.call(app));
|
|
@@ -908,16 +1069,15 @@ function formatDelegationRequests(requests, active) {
|
|
|
908
1069
|
}
|
|
909
1070
|
__name(formatDelegationRequests, "formatDelegationRequests");
|
|
910
1071
|
async function formatDelegationToolRecords(controller, taskId) {
|
|
911
|
-
|
|
912
|
-
throw new Error("Sub-agents are disabled in this workspace");
|
|
913
|
-
}
|
|
914
|
-
const records = await controller.delegationToolRecords(taskId);
|
|
1072
|
+
const records = await controller.application.delegationToolRecords(taskId);
|
|
915
1073
|
if (records.records.length === 0) {
|
|
916
1074
|
return `Task ${taskId} (${records.sessionId}) has no finished tool records.`;
|
|
917
1075
|
}
|
|
918
1076
|
return [
|
|
919
1077
|
`Task ${taskId} \xB7 Session ${records.sessionId}`,
|
|
920
|
-
...records.records.map(
|
|
1078
|
+
...records.records.map(
|
|
1079
|
+
(record) => ` step ${record.step} ${record.status} ${record.name}: ${record.summary.replace(/\s+/gu, " ").slice(0, 160)}`
|
|
1080
|
+
),
|
|
921
1081
|
records.truncated ? " \u2026 more records were omitted" : ""
|
|
922
1082
|
].filter((line) => line !== "").join("\n");
|
|
923
1083
|
}
|
|
@@ -929,18 +1089,20 @@ async function executeDelegationCommand(arguments_, controller) {
|
|
|
929
1089
|
throw new Error(DELEGATION_COMMAND_USAGE);
|
|
930
1090
|
}
|
|
931
1091
|
if (mode !== "status") {
|
|
932
|
-
if (controller.setDelegationNotifications === void 0)
|
|
1092
|
+
if (controller.setDelegationNotifications === void 0)
|
|
1093
|
+
throw new Error("Delegation notifications are unavailable");
|
|
933
1094
|
controller.setDelegationNotifications(mode === "on");
|
|
934
1095
|
}
|
|
935
1096
|
return `Delegation notifications: ${controller.delegationNotifications === true ? "on" : "off"}`;
|
|
936
1097
|
}
|
|
937
|
-
|
|
1098
|
+
const application = controller.application;
|
|
1099
|
+
if (application.subagents === void 0) {
|
|
938
1100
|
return "Sub-agents are disabled in this workspace.";
|
|
939
1101
|
}
|
|
940
|
-
const requests =
|
|
1102
|
+
const requests = application.listDelegationRequests();
|
|
941
1103
|
const verb = arguments_[0];
|
|
942
1104
|
if (arguments_.length === 0 || verb === "show") {
|
|
943
|
-
return formatDelegationRequests(requests,
|
|
1105
|
+
return formatDelegationRequests(requests, application.getDelegationState());
|
|
944
1106
|
}
|
|
945
1107
|
if (verb === "tools") {
|
|
946
1108
|
if (arguments_.length !== 2) throw new Error(DELEGATION_COMMAND_USAGE);
|
|
@@ -1005,94 +1167,14 @@ function renderRequest(request, label) {
|
|
|
1005
1167
|
lines.push(` ${renderDelegationTask(task)}`);
|
|
1006
1168
|
}
|
|
1007
1169
|
if ("budget" in request && request.budget !== void 0) {
|
|
1008
|
-
lines.push(
|
|
1170
|
+
lines.push(
|
|
1171
|
+
` request budget: ${request.budget.modelCalls}/${request.budget.maxModelCalls} model calls, ${request.budget.totalTokens} tokens${request.budget.usageComplete ? "" : " (some calls reported no usage or were charged by reservation)"}`
|
|
1172
|
+
);
|
|
1009
1173
|
}
|
|
1010
1174
|
return lines.join("\n");
|
|
1011
1175
|
}
|
|
1012
1176
|
__name(renderRequest, "renderRequest");
|
|
1013
1177
|
|
|
1014
|
-
// packages/ui/tui/dist/slash-commands.js
|
|
1015
|
-
var SlashCommandRegistry = class {
|
|
1016
|
-
static {
|
|
1017
|
-
__name(this, "SlashCommandRegistry");
|
|
1018
|
-
}
|
|
1019
|
-
definitions;
|
|
1020
|
-
byName = /* @__PURE__ */ new Map();
|
|
1021
|
-
names = [];
|
|
1022
|
-
constructor(definitions) {
|
|
1023
|
-
this.definitions = [...definitions];
|
|
1024
|
-
for (const definition of definitions) {
|
|
1025
|
-
this.registerName(definition.name, definition);
|
|
1026
|
-
for (const alias of definition.aliases ?? []) {
|
|
1027
|
-
this.registerName(alias, definition);
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
find(name) {
|
|
1032
|
-
return this.byName.get(name.toLowerCase());
|
|
1033
|
-
}
|
|
1034
|
-
parse(input) {
|
|
1035
|
-
const trimmed = input.trim();
|
|
1036
|
-
if (!trimmed.startsWith("/"))
|
|
1037
|
-
return { type: "not-command" };
|
|
1038
|
-
const [invokedAs = "", ...arguments_] = trimmed.split(/\s+/u);
|
|
1039
|
-
const definition = this.find(invokedAs);
|
|
1040
|
-
return definition === void 0 ? { type: "unknown", command: invokedAs } : {
|
|
1041
|
-
type: "command",
|
|
1042
|
-
definition,
|
|
1043
|
-
invokedAs,
|
|
1044
|
-
arguments: arguments_
|
|
1045
|
-
};
|
|
1046
|
-
}
|
|
1047
|
-
match(prefix) {
|
|
1048
|
-
if (!prefix.startsWith("/") || /\s/u.test(prefix))
|
|
1049
|
-
return [];
|
|
1050
|
-
const normalized = prefix.toLowerCase();
|
|
1051
|
-
return this.names.filter(({ value }) => value.toLowerCase().startsWith(normalized)).map(({ value, definition }) => ({
|
|
1052
|
-
value,
|
|
1053
|
-
label: value,
|
|
1054
|
-
description: definition.description
|
|
1055
|
-
}));
|
|
1056
|
-
}
|
|
1057
|
-
createSuggester(suggestArguments) {
|
|
1058
|
-
return async (input) => {
|
|
1059
|
-
if (!input.startsWith("/"))
|
|
1060
|
-
return [];
|
|
1061
|
-
const argumentInput = splitSlashCommandArgumentInput(input);
|
|
1062
|
-
if (argumentInput === void 0)
|
|
1063
|
-
return this.match(input);
|
|
1064
|
-
const definition = this.find(argumentInput.invokedAs);
|
|
1065
|
-
if (definition === void 0 || suggestArguments === void 0)
|
|
1066
|
-
return [];
|
|
1067
|
-
return suggestArguments({
|
|
1068
|
-
input,
|
|
1069
|
-
definition,
|
|
1070
|
-
...argumentInput
|
|
1071
|
-
});
|
|
1072
|
-
};
|
|
1073
|
-
}
|
|
1074
|
-
registerName(value, definition) {
|
|
1075
|
-
if (!isCommandName(value)) {
|
|
1076
|
-
throw new TypeError(`Invalid slash command name: ${JSON.stringify(value)}`);
|
|
1077
|
-
}
|
|
1078
|
-
const normalized = value.toLowerCase();
|
|
1079
|
-
if (this.byName.has(normalized)) {
|
|
1080
|
-
throw new Error(`Duplicate slash command name: ${value}`);
|
|
1081
|
-
}
|
|
1082
|
-
this.byName.set(normalized, definition);
|
|
1083
|
-
this.names.push({ value, definition });
|
|
1084
|
-
}
|
|
1085
|
-
};
|
|
1086
|
-
function splitSlashCommandArgumentInput(input) {
|
|
1087
|
-
const match = /^(\/\S+)\s+(.*)$/u.exec(input);
|
|
1088
|
-
return match === null ? void 0 : { invokedAs: match[1], argumentPrefix: match[2] };
|
|
1089
|
-
}
|
|
1090
|
-
__name(splitSlashCommandArgumentInput, "splitSlashCommandArgumentInput");
|
|
1091
|
-
function isCommandName(value) {
|
|
1092
|
-
return /^\/\S+$/u.test(value);
|
|
1093
|
-
}
|
|
1094
|
-
__name(isCommandName, "isCommandName");
|
|
1095
|
-
|
|
1096
1178
|
// apps/maybecode/src/slash-commands.ts
|
|
1097
1179
|
import { userInfo } from "node:os";
|
|
1098
1180
|
var MAYBECODE_COMPACTION_STRATEGIES = [
|
|
@@ -1100,18 +1182,50 @@ var MAYBECODE_COMPACTION_STRATEGIES = [
|
|
|
1100
1182
|
"provider-native"
|
|
1101
1183
|
];
|
|
1102
1184
|
var MAYBECODE_SLASH_COMMANDS = [
|
|
1103
|
-
{
|
|
1104
|
-
|
|
1105
|
-
|
|
1185
|
+
{
|
|
1186
|
+
name: "/permissions",
|
|
1187
|
+
usage: "/permissions [list|allow <id>|deny <id>|revoke <id>]",
|
|
1188
|
+
description: "\u67E5\u770B\u3001\u521B\u5EFA\u6216\u64A4\u9500\u6301\u4E45\u6743\u9650\u89C4\u5219"
|
|
1189
|
+
},
|
|
1190
|
+
{
|
|
1191
|
+
name: "/fork",
|
|
1192
|
+
usage: "/fork",
|
|
1193
|
+
description: "Choose a historical reply and fork in this workspace or a new worktree"
|
|
1194
|
+
},
|
|
1195
|
+
{
|
|
1196
|
+
name: "/changes",
|
|
1197
|
+
usage: "/changes [run <run-id>|session|workspace|commit <commit>]",
|
|
1198
|
+
description: "Browse checkpoint and workspace file changes"
|
|
1199
|
+
},
|
|
1106
1200
|
{ name: "/worktrees", usage: "/worktrees [open|delete <id>]", description: "List, open or delete managed worktrees" },
|
|
1107
|
-
{
|
|
1201
|
+
{
|
|
1202
|
+
name: "/steer",
|
|
1203
|
+
usage: "/steer <message>",
|
|
1204
|
+
description: "Deliver additional input after the current Step finishes"
|
|
1205
|
+
},
|
|
1108
1206
|
{ name: "/stop", usage: "/stop", description: "Cancel the current operation" },
|
|
1109
|
-
{
|
|
1207
|
+
{
|
|
1208
|
+
name: "/yolo",
|
|
1209
|
+
usage: "/yolo [on|off|status]",
|
|
1210
|
+
description: "Enable automatic tool approval; use off to disable or status to inspect"
|
|
1211
|
+
},
|
|
1110
1212
|
{ name: "/goal", usage: GOAL_COMMAND_USAGE, description: "Start, inspect, pause, resume, or cancel a durable goal" },
|
|
1111
1213
|
{ name: "/web", usage: "/web", description: "Open the current workspace and session in a browser" },
|
|
1112
|
-
{
|
|
1113
|
-
|
|
1114
|
-
|
|
1214
|
+
{
|
|
1215
|
+
name: "/skills",
|
|
1216
|
+
usage: "/skills [show <name>|use <name> [task]]",
|
|
1217
|
+
description: "List skills, preview instructions, or activate a skill"
|
|
1218
|
+
},
|
|
1219
|
+
{
|
|
1220
|
+
name: "/recovery",
|
|
1221
|
+
usage: "/recovery [resolve <id> <verified finding>]",
|
|
1222
|
+
description: "Inspect interrupted tools or record verified recovery findings"
|
|
1223
|
+
},
|
|
1224
|
+
{
|
|
1225
|
+
name: "/delegations",
|
|
1226
|
+
usage: DELEGATION_COMMAND_USAGE,
|
|
1227
|
+
description: "Inspect sub-agent requests and tools, and control status notifications"
|
|
1228
|
+
},
|
|
1115
1229
|
{
|
|
1116
1230
|
name: "/new",
|
|
1117
1231
|
usage: "/new",
|
|
@@ -1179,9 +1293,7 @@ function formatMaybeCodeMcpStatus(servers) {
|
|
|
1179
1293
|
const lines = ["MCP servers:"];
|
|
1180
1294
|
for (const server of servers) {
|
|
1181
1295
|
const requirement = server.required ? "required" : "optional";
|
|
1182
|
-
lines.push(
|
|
1183
|
-
`- ${server.serverId}: ${server.state} (${requirement}, ${server.transport})`
|
|
1184
|
-
);
|
|
1296
|
+
lines.push(`- ${server.serverId}: ${server.state} (${requirement}, ${server.transport})`);
|
|
1185
1297
|
if (server.protocolVersion !== void 0) {
|
|
1186
1298
|
lines.push(` protocol: ${server.protocolVersion}`);
|
|
1187
1299
|
}
|
|
@@ -1195,12 +1307,7 @@ function formatMaybeCodeMcpStatus(servers) {
|
|
|
1195
1307
|
}
|
|
1196
1308
|
if (server.diagnostic !== void 0) {
|
|
1197
1309
|
const code = server.diagnostic.code === void 0 ? "" : ` [${server.diagnostic.code}]`;
|
|
1198
|
-
lines.push(
|
|
1199
|
-
...indentLines(
|
|
1200
|
-
` error${code}: `,
|
|
1201
|
-
server.diagnostic.message
|
|
1202
|
-
)
|
|
1203
|
-
);
|
|
1310
|
+
lines.push(...indentLines(` error${code}: `, server.diagnostic.message));
|
|
1204
1311
|
}
|
|
1205
1312
|
const stderr = server.stderr ?? server.diagnostic?.stderr;
|
|
1206
1313
|
if (stderr !== void 0) {
|
|
@@ -1234,7 +1341,8 @@ function createMaybeCodeSlashCommandSuggester(controller, options = {}) {
|
|
|
1234
1341
|
const { definition, invokedAs: command, argumentPrefix } = argumentInput;
|
|
1235
1342
|
if (definition?.name === "/delegations") {
|
|
1236
1343
|
const match = /^notifications\s+(\S*)$/u.exec(argumentPrefix);
|
|
1237
|
-
if (match)
|
|
1344
|
+
if (match)
|
|
1345
|
+
return ["on", "off", "status"].filter((value) => value.startsWith(match[1])).map((value) => ({ value: `${command} notifications ${value}`, label: value }));
|
|
1238
1346
|
return ["show", "notifications", "tools", "resolve"].filter((value) => value.startsWith(argumentPrefix)).map((value) => ({ value: `${command} ${value}`, label: value }));
|
|
1239
1347
|
}
|
|
1240
1348
|
if (definition?.name === "/yolo") {
|
|
@@ -1245,17 +1353,28 @@ function createMaybeCodeSlashCommandSuggester(controller, options = {}) {
|
|
|
1245
1353
|
}
|
|
1246
1354
|
if (definition?.name === "/skills") {
|
|
1247
1355
|
const match = /^(show|use)\s+(\S*)$/u.exec(argumentPrefix);
|
|
1248
|
-
if (match)
|
|
1356
|
+
if (match)
|
|
1357
|
+
return controller.application.listSkills().filter((skill) => skill.name.startsWith(match[2])).map((skill) => ({
|
|
1358
|
+
value: `${command} ${match[1]} ${skill.name}`,
|
|
1359
|
+
label: skill.name,
|
|
1360
|
+
description: skill.description
|
|
1361
|
+
}));
|
|
1249
1362
|
if (/\s/u.test(argumentPrefix)) return [];
|
|
1250
|
-
return ["show", "use"].filter((verb) => verb.startsWith(argumentPrefix)).map((verb) => ({
|
|
1363
|
+
return ["show", "use"].filter((verb) => verb.startsWith(argumentPrefix)).map((verb) => ({
|
|
1364
|
+
value: `${command} ${verb}`,
|
|
1365
|
+
label: verb,
|
|
1366
|
+
description: verb === "show" ? "Preview without activation" : "Activate for the current session"
|
|
1367
|
+
}));
|
|
1251
1368
|
}
|
|
1252
1369
|
if (definition?.name === "/compact") {
|
|
1253
1370
|
if (/\s/u.test(argumentPrefix)) return [];
|
|
1254
|
-
return MAYBECODE_COMPACTION_STRATEGIES.filter((strategy) => strategy.startsWith(argumentPrefix)).map(
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1371
|
+
return MAYBECODE_COMPACTION_STRATEGIES.filter((strategy) => strategy.startsWith(argumentPrefix)).map(
|
|
1372
|
+
(strategy) => ({
|
|
1373
|
+
value: `${command} ${strategy}`,
|
|
1374
|
+
label: strategy,
|
|
1375
|
+
description: strategy === "provider-native" ? "Compact with the active model's native compactor" : "Keep the current request and fresh saved work notes"
|
|
1376
|
+
})
|
|
1377
|
+
);
|
|
1259
1378
|
}
|
|
1260
1379
|
if (definition?.name === "/resume") {
|
|
1261
1380
|
if (/\s/u.test(argumentPrefix)) return [];
|
|
@@ -1266,23 +1385,23 @@ function createMaybeCodeSlashCommandSuggester(controller, options = {}) {
|
|
|
1266
1385
|
}));
|
|
1267
1386
|
}
|
|
1268
1387
|
if (definition?.name === "/model") {
|
|
1269
|
-
const optionInput = /^(\S+)\s+(\S*)$/u.exec(
|
|
1270
|
-
argumentPrefix
|
|
1271
|
-
);
|
|
1388
|
+
const optionInput = /^(\S+)\s+(\S*)$/u.exec(argumentPrefix);
|
|
1272
1389
|
if (optionInput !== null) {
|
|
1273
1390
|
const optionPrefix = optionInput[2];
|
|
1274
|
-
return "--default".startsWith(optionPrefix) ? [
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1391
|
+
return "--default".startsWith(optionPrefix) ? [
|
|
1392
|
+
{
|
|
1393
|
+
value: `${command} ${optionInput[1]} --default`,
|
|
1394
|
+
label: "--default",
|
|
1395
|
+
description: "Switch to this profile and make it the default"
|
|
1396
|
+
}
|
|
1397
|
+
] : [];
|
|
1279
1398
|
}
|
|
1280
1399
|
if (/\s/u.test(argumentPrefix)) return [];
|
|
1281
1400
|
const normalized = argumentPrefix.toLowerCase();
|
|
1282
1401
|
return (await controller.listModels()).filter((model) => model.name.toLowerCase().startsWith(normalized)).map((model) => ({
|
|
1283
1402
|
value: `${command} ${model.name}`,
|
|
1284
1403
|
label: model.name,
|
|
1285
|
-
description: model.name === controller.modelInfo?.profile ? `Current \xB7 ${model.provider}/${model.model}` : `${model.provider}/${model.model} \xB7 ${model.adapter}`
|
|
1404
|
+
description: model.name === controller.application.modelInfo?.profile ? `Current \xB7 ${model.provider}/${model.model}` : `${model.provider}/${model.model} \xB7 ${model.adapter}`
|
|
1286
1405
|
}));
|
|
1287
1406
|
}
|
|
1288
1407
|
if (definition?.name === "/effort") {
|
|
@@ -1309,8 +1428,10 @@ async function executeMaybeCodeSlashCommand(input, controller) {
|
|
|
1309
1428
|
switch (definition.name) {
|
|
1310
1429
|
case "/fork": {
|
|
1311
1430
|
if (arguments_.length) return { type: "usage", usage: "/fork" };
|
|
1312
|
-
if (!controller.getForkPoints || !controller.forkSession)
|
|
1313
|
-
|
|
1431
|
+
if (!controller.getForkPoints || !controller.forkSession)
|
|
1432
|
+
throw new Error("Session forks are unavailable in this host");
|
|
1433
|
+
if (controller.isRunning)
|
|
1434
|
+
throw new Error("Wait for the current request to finish before creating a Session fork");
|
|
1314
1435
|
return { type: "fork.selection.requested", points: await controller.getForkPoints() };
|
|
1315
1436
|
}
|
|
1316
1437
|
case "/changes": {
|
|
@@ -1319,15 +1440,19 @@ async function executeMaybeCodeSlashCommand(input, controller) {
|
|
|
1319
1440
|
if (arguments_.length > 2 || !["run", "session", "workspace", "commit"].includes(scope) || ["run", "commit"].includes(scope) && !value || ["session", "workspace"].includes(scope) && value) {
|
|
1320
1441
|
return { type: "usage", usage: "/changes [run <run-id>|session|workspace|commit <commit>]" };
|
|
1321
1442
|
}
|
|
1322
|
-
return {
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1443
|
+
return {
|
|
1444
|
+
type: "changes.selection.requested",
|
|
1445
|
+
diff: await controller.getChanges({
|
|
1446
|
+
scope: scope === "commit" ? "workspace" : scope,
|
|
1447
|
+
...scope === "run" ? { runId: value } : scope === "commit" ? { commit: value } : {}
|
|
1448
|
+
})
|
|
1449
|
+
};
|
|
1326
1450
|
}
|
|
1327
1451
|
case "/worktrees": {
|
|
1328
1452
|
if (!controller.getWorktrees) throw new Error("Worktree management is unavailable in this host");
|
|
1329
1453
|
if (arguments_.length) {
|
|
1330
|
-
if (arguments_.length !== 2 || !["open", "delete"].includes(arguments_[0]))
|
|
1454
|
+
if (arguments_.length !== 2 || !["open", "delete"].includes(arguments_[0]))
|
|
1455
|
+
return { type: "usage", usage: "/worktrees [open|delete <id>]" };
|
|
1331
1456
|
if (arguments_[0] === "open") {
|
|
1332
1457
|
if (!controller.openWorktree) throw new Error("Opening a worktree is unavailable in this host");
|
|
1333
1458
|
await controller.openWorktree(arguments_[1]);
|
|
@@ -1348,26 +1473,34 @@ async function executeMaybeCodeSlashCommand(input, controller) {
|
|
|
1348
1473
|
case "/stop": {
|
|
1349
1474
|
const invalid = noArguments(arguments_, definition);
|
|
1350
1475
|
if (invalid) return invalid;
|
|
1351
|
-
return {
|
|
1476
|
+
return {
|
|
1477
|
+
type: "display",
|
|
1478
|
+
text: controller.cancel("Stopped by user") ? "Cancellation requested." : "No active operation."
|
|
1479
|
+
};
|
|
1352
1480
|
}
|
|
1353
1481
|
case "/yolo": {
|
|
1354
1482
|
const action = arguments_[0] ?? "on";
|
|
1355
|
-
if (arguments_.length > 1 || !["on", "off", "status"].includes(action))
|
|
1483
|
+
if (arguments_.length > 1 || !["on", "off", "status"].includes(action))
|
|
1484
|
+
return { type: "usage", usage: "/yolo [on|off|status]" };
|
|
1356
1485
|
if (action !== "status") await controller.setPermissionMode(action === "on" ? "yolo" : "default");
|
|
1357
1486
|
return { type: "display", text: controller.permissionMode === "yolo" ? "YOLO enabled" : "YOLO disabled" };
|
|
1358
1487
|
}
|
|
1359
1488
|
case "/permissions": {
|
|
1360
|
-
if (controller.persistentRulesEnabled
|
|
1489
|
+
if (!controller.application.persistentRulesEnabled || !controller.listPermissionRules || !controller.revokePermissionRule)
|
|
1490
|
+
throw new Error("\u6B64\u5BBF\u4E3B\u6CA1\u6709\u542F\u7528\u89C4\u5219\u7BA1\u7406\u3002");
|
|
1361
1491
|
const action = arguments_[0] ?? "list";
|
|
1362
1492
|
if (action === "list" && arguments_.length <= 1) {
|
|
1363
1493
|
const rules = await controller.listPermissionRules();
|
|
1364
|
-
return {
|
|
1365
|
-
|
|
1494
|
+
return {
|
|
1495
|
+
type: "display",
|
|
1496
|
+
text: rules.length === 0 ? "\u5F53\u524D\u6CA1\u6709\u6301\u4E45\u6743\u9650\u89C4\u5219\u3002" : rules.map(
|
|
1497
|
+
(rule) => `${rule.id}
|
|
1366
1498
|
${rule.decision === "allow" ? "\u5141\u8BB8" : "\u7981\u6B62"} \xB7 ${rule.description}
|
|
1367
1499
|
\u8303\u56F4\uFF1A${rule.scopeId}
|
|
1368
1500
|
\u521B\u5EFA\u8005\uFF1A${rule.createdBy}
|
|
1369
1501
|
\u6709\u6548\u671F\uFF1A${rule.expiresAt === void 0 ? "\u6301\u7EED\u6709\u6548" : new Date(rule.expiresAt).toISOString()}`
|
|
1370
|
-
|
|
1502
|
+
).join("\n\n")
|
|
1503
|
+
};
|
|
1371
1504
|
}
|
|
1372
1505
|
if (action === "revoke" && arguments_.length === 2) {
|
|
1373
1506
|
if (!await controller.revokePermissionRule(arguments_[1])) throw new Error("\u89C4\u5219\u4E0D\u5B58\u5728\u3002");
|
|
@@ -1375,11 +1508,17 @@ ${rule.decision === "allow" ? "\u5141\u8BB8" : "\u7981\u6B62"} \xB7 ${rule.descr
|
|
|
1375
1508
|
}
|
|
1376
1509
|
if ((action === "allow" || action === "deny") && arguments_.length === 2) {
|
|
1377
1510
|
if (!controller.createPermissionRuleFrom) throw new Error("\u6B64\u5BBF\u4E3B\u6CA1\u6709\u542F\u7528\u89C4\u5219\u521B\u5EFA\u3002");
|
|
1378
|
-
const rule = await controller.createPermissionRuleFrom(arguments_[1], {
|
|
1379
|
-
|
|
1511
|
+
const rule = await controller.createPermissionRuleFrom(arguments_[1], {
|
|
1512
|
+
decision: action,
|
|
1513
|
+
createdBy: `local:${userInfo().username}`
|
|
1514
|
+
});
|
|
1515
|
+
return {
|
|
1516
|
+
type: "display",
|
|
1517
|
+
text: `\u5DF2\u521B\u5EFA${action === "allow" ? "\u5141\u8BB8" : "\u7981\u6B62"}\u89C4\u5219\uFF1A${rule.id}
|
|
1380
1518
|
${rule.description}
|
|
1381
1519
|
\u8303\u56F4\uFF1A${rule.scopeId}
|
|
1382
|
-
\u540C\u8303\u56F4\u7684\u7981\u6B62\u89C4\u5219\u4F18\u5148\u3002`
|
|
1520
|
+
\u540C\u8303\u56F4\u7684\u7981\u6B62\u89C4\u5219\u4F18\u5148\u3002`
|
|
1521
|
+
};
|
|
1383
1522
|
}
|
|
1384
1523
|
return { type: "usage", usage: definition.usage };
|
|
1385
1524
|
}
|
|
@@ -1389,11 +1528,16 @@ ${rule.description}
|
|
|
1389
1528
|
return noArguments(arguments_, definition) ?? { type: "web.requested" };
|
|
1390
1529
|
case "/skills": {
|
|
1391
1530
|
if (arguments_.length === 0) {
|
|
1392
|
-
const skills = controller.listSkills
|
|
1393
|
-
const diagnostics = controller.
|
|
1394
|
-
const text = skills.length === 0 ? "No skills discovered." : skills.map(
|
|
1395
|
-
|
|
1396
|
-
|
|
1531
|
+
const skills = controller.application.listSkills();
|
|
1532
|
+
const diagnostics = controller.application.agent.skills?.registry.diagnostics ?? [];
|
|
1533
|
+
const text = skills.length === 0 ? "No skills discovered." : skills.map(
|
|
1534
|
+
(skill) => `${skill.name}${skill.active ? " [active]" : ""} \u2014 ${skill.description}
|
|
1535
|
+
${skill.directory}`
|
|
1536
|
+
).join("\n");
|
|
1537
|
+
return {
|
|
1538
|
+
type: "display",
|
|
1539
|
+
text: text + (diagnostics.length === 0 ? "" : "\n\nDiscovery diagnostics:\n" + diagnostics.map((item) => `${item.path}: ${item.message}`).join("\n"))
|
|
1540
|
+
};
|
|
1397
1541
|
}
|
|
1398
1542
|
const [verb, name, ...task] = arguments_;
|
|
1399
1543
|
if (name === void 0 || !["show", "use"].includes(verb)) return usage(definition);
|
|
@@ -1401,11 +1545,14 @@ ${rule.description}
|
|
|
1401
1545
|
if (task.length > 0) return usage(definition);
|
|
1402
1546
|
if (!controller.readSkill) throw new Error("Skills are unsupported by this controller");
|
|
1403
1547
|
const document = await controller.readSkill(name);
|
|
1404
|
-
return {
|
|
1548
|
+
return {
|
|
1549
|
+
type: "display",
|
|
1550
|
+
text: `${document.name}
|
|
1405
1551
|
${document.directory}
|
|
1406
1552
|
Revision: ${document.revision}
|
|
1407
1553
|
|
|
1408
|
-
${document.body}`
|
|
1554
|
+
${document.body}`
|
|
1555
|
+
};
|
|
1409
1556
|
}
|
|
1410
1557
|
if (task.length > 0) {
|
|
1411
1558
|
if (!controller.submitSkill) throw new Error("Skill submission is unsupported by this controller");
|
|
@@ -1417,9 +1564,14 @@ ${document.body}` };
|
|
|
1417
1564
|
}
|
|
1418
1565
|
case "/recovery": {
|
|
1419
1566
|
if (arguments_.length === 0) {
|
|
1420
|
-
const pending2 = controller.listRecoveries
|
|
1421
|
-
return {
|
|
1422
|
-
|
|
1567
|
+
const pending2 = controller.listRecoveries();
|
|
1568
|
+
return {
|
|
1569
|
+
type: "display",
|
|
1570
|
+
text: pending2.length === 0 ? "No unresolved recovery findings." : pending2.map(
|
|
1571
|
+
(item) => `${item.id} \u2014 ${item.call.name}: outcome unknown
|
|
1572
|
+
Input: ${JSON.stringify(item.call.input)}`
|
|
1573
|
+
).join("\n\n") + "\nVerify external effects, then use /recovery resolve <id> <verified finding>."
|
|
1574
|
+
};
|
|
1423
1575
|
}
|
|
1424
1576
|
if (arguments_[0] !== "resolve" || arguments_.length < 3) return usage(definition);
|
|
1425
1577
|
if (!controller.resolveRecovery) throw new Error("Recovery resolution is unsupported");
|
|
@@ -1438,7 +1590,7 @@ Input: ${JSON.stringify(item.call.input)}`).join("\n\n") + "\nVerify external ef
|
|
|
1438
1590
|
case "/instructions":
|
|
1439
1591
|
return noArguments(arguments_, definition) ?? {
|
|
1440
1592
|
type: "instructions",
|
|
1441
|
-
instructions: controller.instructions
|
|
1593
|
+
instructions: controller.application.instructions
|
|
1442
1594
|
};
|
|
1443
1595
|
case "/retry": {
|
|
1444
1596
|
const invalid = noArguments(arguments_, definition);
|
|
@@ -1499,9 +1651,7 @@ Input: ${JSON.stringify(item.call.input)}`).join("\n\n") + "\nVerify external ef
|
|
|
1499
1651
|
return usage(definition);
|
|
1500
1652
|
}
|
|
1501
1653
|
const normalized = query.toLowerCase();
|
|
1502
|
-
const selected = (await controller.listModels()).find(
|
|
1503
|
-
(model2) => model2.name.toLowerCase().startsWith(normalized)
|
|
1504
|
-
);
|
|
1654
|
+
const selected = (await controller.listModels()).find((model2) => model2.name.toLowerCase().startsWith(normalized));
|
|
1505
1655
|
if (selected === void 0) return { type: "model.not-found", query };
|
|
1506
1656
|
const model = await controller.switchModel(selected.name);
|
|
1507
1657
|
if (setDefault) await controller.setDefaultModel(selected.name);
|
|
@@ -1524,15 +1674,11 @@ Input: ${JSON.stringify(item.call.input)}`).join("\n\n") + "\nVerify external ef
|
|
|
1524
1674
|
return { type: "effort.selection.requested", state };
|
|
1525
1675
|
}
|
|
1526
1676
|
const normalized = query.toLowerCase();
|
|
1527
|
-
const selected = reasoningEffortChoices(state).find(
|
|
1528
|
-
(effort) => effort.toLowerCase().startsWith(normalized)
|
|
1529
|
-
);
|
|
1677
|
+
const selected = reasoningEffortChoices(state).find((effort) => effort.toLowerCase().startsWith(normalized));
|
|
1530
1678
|
if (selected === void 0) return { type: "effort.not-found", query };
|
|
1531
1679
|
return {
|
|
1532
1680
|
type: "effort.changed",
|
|
1533
|
-
state: await controller.setReasoningEffort(
|
|
1534
|
-
selected === "default" ? void 0 : selected
|
|
1535
|
-
)
|
|
1681
|
+
state: await controller.setReasoningEffort(selected === "default" ? void 0 : selected)
|
|
1536
1682
|
};
|
|
1537
1683
|
}
|
|
1538
1684
|
}
|
|
@@ -1565,9 +1711,7 @@ function isCompactionStrategy(value) {
|
|
|
1565
1711
|
__name(isCompactionStrategy, "isCompactionStrategy");
|
|
1566
1712
|
function indentLines(prefix, value) {
|
|
1567
1713
|
const lines = value.split("\n");
|
|
1568
|
-
return lines.map(
|
|
1569
|
-
(line, index) => index === 0 ? `${prefix}${line}` : ` ${line}`
|
|
1570
|
-
);
|
|
1714
|
+
return lines.map((line, index) => index === 0 ? `${prefix}${line}` : ` ${line}`);
|
|
1571
1715
|
}
|
|
1572
1716
|
__name(indentLines, "indentLines");
|
|
1573
1717
|
|
|
@@ -1586,13 +1730,18 @@ var MaybeCodeWebCommands = class {
|
|
|
1586
1730
|
busy = false;
|
|
1587
1731
|
suggest;
|
|
1588
1732
|
available(name) {
|
|
1589
|
-
if (["session.fork", "worktree.open", "worktree.delete", "changes.restore.preview", "changes.restore.apply"].includes(
|
|
1590
|
-
|
|
1733
|
+
if (["session.fork", "worktree.open", "worktree.delete", "changes.restore.preview", "changes.restore.apply"].includes(
|
|
1734
|
+
name
|
|
1735
|
+
) && (this.app.isRunning || this.app.application.getGoal()?.status === "active" || this.app.getMcpInteractions?.().length))
|
|
1736
|
+
return false;
|
|
1737
|
+
if (name === "permission.set" && (this.app.isRunning || this.app.application.getGoal()?.status === "active" || this.app.getMcpInteractions?.().length))
|
|
1738
|
+
return false;
|
|
1591
1739
|
if (name === "message.submit") return !this.busy;
|
|
1592
1740
|
if (name === "mcp.respond") return Boolean(this.app.getMcpInteractions?.().length);
|
|
1593
1741
|
if (name === "console.cancel") return true;
|
|
1594
1742
|
if (this.busy) return ["run.cancel", "approval.resolve"].includes(name);
|
|
1595
|
-
if (this.app.getMcpInteractions?.().length && ["session.new", "session.activate", "session.delete", "console.action"].includes(name))
|
|
1743
|
+
if (this.app.getMcpInteractions?.().length && ["session.new", "session.activate", "session.delete", "console.action"].includes(name))
|
|
1744
|
+
return false;
|
|
1596
1745
|
if (name === "console.execute") return true;
|
|
1597
1746
|
if (name === "console.action") return !this.app.isRunning;
|
|
1598
1747
|
return true;
|
|
@@ -1623,16 +1772,23 @@ ${request.params.message}`,
|
|
|
1623
1772
|
const { id, action, content } = command.args;
|
|
1624
1773
|
if (!["accept", "decline", "cancel"].includes(action)) throw new UiError(400, "\u4EA4\u4E92\u64CD\u4F5C\u65E0\u6548\u3002");
|
|
1625
1774
|
const request = this.app.getMcpInteractions?.().find((item) => item.id === id);
|
|
1626
|
-
if (!request || this.app.ownsSession?.(request.owner.sessionId) !== true)
|
|
1775
|
+
if (!request || this.app.ownsSession?.(request.owner.sessionId) !== true)
|
|
1776
|
+
throw new UiError(409, "\u4EA4\u4E92\u5DF2\u7ED3\u675F\u6216\u4F1A\u8BDD\u5DF2\u6539\u53D8\u3002");
|
|
1627
1777
|
const parsed = content === void 0 ? void 0 : JSON.parse(content);
|
|
1628
|
-
if (parsed !== void 0 && (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)))
|
|
1629
|
-
|
|
1778
|
+
if (parsed !== void 0 && (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)))
|
|
1779
|
+
throw new UiError(400, "\u8868\u5355\u5185\u5BB9\u5FC5\u987B\u4E3A JSON \u5BF9\u8C61\u3002");
|
|
1780
|
+
if (!this.app.respondMcpInteraction?.(id, {
|
|
1781
|
+
action,
|
|
1782
|
+
...parsed === void 0 ? {} : { content: parsed }
|
|
1783
|
+
}))
|
|
1784
|
+
throw new UiError(409, "\u4EA4\u4E92\u5DF2\u7ED3\u675F\u3002");
|
|
1630
1785
|
this.changed();
|
|
1631
1786
|
return {};
|
|
1632
1787
|
}
|
|
1633
1788
|
if (command.name === "console.cancel") {
|
|
1634
1789
|
commandArgs(command, []);
|
|
1635
|
-
for (const request of this.app.getMcpInteractions?.() ?? [])
|
|
1790
|
+
for (const request of this.app.getMcpInteractions?.() ?? [])
|
|
1791
|
+
this.app.respondMcpInteraction?.(request.id, { action: "cancel" });
|
|
1636
1792
|
this.app.cancel("Cancelled from Web UI");
|
|
1637
1793
|
this.changed();
|
|
1638
1794
|
return {};
|
|
@@ -1645,29 +1801,37 @@ ${request.params.message}`,
|
|
|
1645
1801
|
commandArgs(command, ["runId"], ["path", "paths"]);
|
|
1646
1802
|
if (!this.app.previewRestore) throw new UiError(400, "\u6587\u4EF6\u6062\u590D\u80FD\u529B\u4E0D\u53EF\u7528\u3002");
|
|
1647
1803
|
const paths = command.args.paths ? JSON.parse(command.args.paths) : command.args.path ? [command.args.path] : [];
|
|
1648
|
-
if (!Array.isArray(paths) || paths.length === 0 || paths.some((path) => typeof path !== "string"))
|
|
1804
|
+
if (!Array.isArray(paths) || paths.length === 0 || paths.some((path) => typeof path !== "string"))
|
|
1805
|
+
throw new UiError(400, "\u8BF7\u9009\u62E9\u9700\u8981\u6062\u590D\u7684\u6587\u4EF6\u3002");
|
|
1649
1806
|
return { diff: (await this.app.previewRestore(command.args.runId, paths)).diff };
|
|
1650
1807
|
}
|
|
1651
1808
|
if (command.name === "changes.restore.apply") {
|
|
1652
1809
|
commandArgs(command, ["previewId"]);
|
|
1653
1810
|
if (!this.app.restoreFiles) throw new UiError(400, "\u6587\u4EF6\u6062\u590D\u80FD\u529B\u4E0D\u53EF\u7528\u3002");
|
|
1654
1811
|
await this.app.restoreFiles(command.args.previewId);
|
|
1655
|
-
return {
|
|
1812
|
+
return {
|
|
1813
|
+
selectedId: this.app.sessionId,
|
|
1814
|
+
output: { title: "\u6587\u4EF6\u6062\u590D", text: "\u5DF2\u6062\u590D\u9009\u5B9A\u6587\u4EF6\u5E76\u66F4\u65B0\u5DE5\u4F5C\u533A\u7248\u672C\u8BB0\u5F55\u3002" }
|
|
1815
|
+
};
|
|
1656
1816
|
}
|
|
1657
1817
|
if (command.name === "session.fork") {
|
|
1658
1818
|
commandArgs(command, ["pointId", "mode"]);
|
|
1659
|
-
if (!this.app.forkSession || !["current", "worktree"].includes(command.args.mode))
|
|
1819
|
+
if (!this.app.forkSession || !["current", "worktree"].includes(command.args.mode))
|
|
1820
|
+
throw new UiError(400, "Session \u5206\u652F\u65B9\u5F0F\u65E0\u6548\u3002");
|
|
1660
1821
|
await this.app.forkSession(command.args.pointId, command.args.mode);
|
|
1661
1822
|
return { selectedId: this.app.sessionId };
|
|
1662
1823
|
}
|
|
1663
1824
|
if (command.name === "changes.view") {
|
|
1664
1825
|
commandArgs(command, ["scope"], ["runId", "commit"]);
|
|
1665
|
-
if (!this.app.getChanges || !["run", "session", "workspace"].includes(command.args.scope))
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1826
|
+
if (!this.app.getChanges || !["run", "session", "workspace"].includes(command.args.scope))
|
|
1827
|
+
throw new UiError(400, "\u6587\u4EF6\u53D8\u5316\u8303\u56F4\u65E0\u6548\u3002");
|
|
1828
|
+
return {
|
|
1829
|
+
diff: await this.app.getChanges({
|
|
1830
|
+
scope: command.args.scope,
|
|
1831
|
+
...command.args.runId ? { runId: command.args.runId } : {},
|
|
1832
|
+
...command.args.commit ? { commit: command.args.commit } : {}
|
|
1833
|
+
})
|
|
1834
|
+
};
|
|
1671
1835
|
}
|
|
1672
1836
|
if (command.name === "worktree.open" || command.name === "worktree.delete") {
|
|
1673
1837
|
commandArgs(command, ["id"]);
|
|
@@ -1689,17 +1853,21 @@ ${request.params.message}`,
|
|
|
1689
1853
|
const allowed = parsed.type === "command" && (parsed.definition.name === "/help" || parsed.definition.name === "/status" || parsed.definition.name === "/steer" || parsed.definition.name === "/stop" || parsed.definition.name === "/delegations" && (arguments_.length === 0 || ["show", "tools", "notifications"].includes(arguments_[0])) || parsed.definition.name === "/yolo" && parsed.arguments[0] === "status" || parsed.definition.name === "/goal" && ["status", "pause", "cancel"].includes(parsed.arguments[0] ?? "status"));
|
|
1690
1854
|
if (!allowed) throw new UiError(409, "\u8BF7\u6682\u505C\u5F53\u524D\u8FD0\u884C\u540E\u6267\u884C\u6B64\u547D\u4EE4\u3002");
|
|
1691
1855
|
}
|
|
1692
|
-
if (this.app.getMcpInteractions?.().length && /^\/(?:new|resume)(?:\s|$)/u.test(command.args.text.trim()))
|
|
1856
|
+
if (this.app.getMcpInteractions?.().length && /^\/(?:new|resume)(?:\s|$)/u.test(command.args.text.trim()))
|
|
1857
|
+
throw new UiError(409, "\u8BF7\u5148\u5B8C\u6210\u6216\u53D6\u6D88\u5F53\u524D MCP \u4EA4\u4E92\u3002");
|
|
1693
1858
|
const result = await executeMaybeCodeSlashCommand(command.args.text, this.app);
|
|
1694
1859
|
return await this.present(result);
|
|
1695
1860
|
}
|
|
1696
1861
|
if (command.name === "permission.set") {
|
|
1697
1862
|
commandArgs(command, ["value"]);
|
|
1698
1863
|
await this.app.setPermissionMode(parsePermissionMode(command.args.value));
|
|
1699
|
-
return {
|
|
1864
|
+
return {
|
|
1865
|
+
output: { title: "Permissions", text: this.app.permissionMode === "yolo" ? "YOLO enabled" : "YOLO disabled" }
|
|
1866
|
+
};
|
|
1700
1867
|
} else if (command.name === "model.capabilities.refresh") {
|
|
1701
1868
|
commandArgs(command, []);
|
|
1702
|
-
if (!this.app.getModelCapabilities || this.app.modelCapabilitiesAvailable === false)
|
|
1869
|
+
if (!this.app.getModelCapabilities || this.app.modelCapabilitiesAvailable === false)
|
|
1870
|
+
throw new UiError(400, "\u6A21\u578B\u80FD\u529B\u67E5\u8BE2\u4E0D\u53EF\u7528\u3002");
|
|
1703
1871
|
await this.app.getModelCapabilities(void 0, true);
|
|
1704
1872
|
this.changed();
|
|
1705
1873
|
} else if (command.name === "model.switch") {
|
|
@@ -1713,8 +1881,10 @@ ${request.params.message}`,
|
|
|
1713
1881
|
} else throw new UiError(400, "\u4E0D\u652F\u6301\u7684\u64CD\u4F5C\u3002");
|
|
1714
1882
|
return { selectedId: this.app.sessionId };
|
|
1715
1883
|
} catch (error) {
|
|
1716
|
-
if (error instanceof GitWorkspaceConflictError || error instanceof MaybeCodeUsageError)
|
|
1717
|
-
|
|
1884
|
+
if (error instanceof GitWorkspaceConflictError || error instanceof MaybeCodeUsageError)
|
|
1885
|
+
throw new UiError(409, error.message);
|
|
1886
|
+
if (error instanceof GitCheckpointError)
|
|
1887
|
+
throw new UiError(409, "Git checkpoint \u4FDD\u5B58\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u9879\u76EE Git \u914D\u7F6E\u4E0E Hooks\u3002");
|
|
1718
1888
|
throw error;
|
|
1719
1889
|
} finally {
|
|
1720
1890
|
this.busy = false;
|
|
@@ -1728,33 +1898,68 @@ ${request.params.message}`,
|
|
|
1728
1898
|
else if (action === "model.switch") await this.app.switchModel(value);
|
|
1729
1899
|
else if (action === "effort.set") await this.app.setReasoningEffort(value === "default" ? void 0 : value);
|
|
1730
1900
|
else if (["session.resume", "session.rename", "session.delete"].includes(action)) {
|
|
1731
|
-
if (action === "session.delete" && value === this.app.sessionId)
|
|
1732
|
-
|
|
1901
|
+
if (action === "session.delete" && value === this.app.sessionId)
|
|
1902
|
+
throw new UiError(409, "\u65E0\u6CD5\u5220\u9664\u5F53\u524D\u4F1A\u8BDD\uFF0C\u8BF7\u5148\u5207\u6362\u5230\u5176\u5B83\u4F1A\u8BDD\u3002");
|
|
1903
|
+
if (!(await this.app.listSessions()).some((session) => session.id === value))
|
|
1904
|
+
throw new UiError(404, "\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u5F53\u524D\u5DE5\u4F5C\u533A\u3002");
|
|
1733
1905
|
if (action === "session.resume") await this.app.resumeSession(value);
|
|
1734
1906
|
else if (action === "session.rename") {
|
|
1735
1907
|
if (!title?.trim() || title.length > 160) throw new UiError(400, "\u8BF7\u8F93\u5165\u4E0D\u8D85\u8FC7 160 \u4E2A\u5B57\u7B26\u7684\u540D\u79F0\u3002");
|
|
1736
1908
|
await this.app.renameSession(value, title);
|
|
1737
1909
|
} else await this.app.deleteSession(value);
|
|
1738
1910
|
} else throw new UiError(400, "\u64CD\u4F5C\u540D\u79F0\u65E0\u6548\u3002");
|
|
1739
|
-
const result = await executeMaybeCodeSlashCommand(
|
|
1911
|
+
const result = await executeMaybeCodeSlashCommand(
|
|
1912
|
+
action?.startsWith("session.") ? "/resume" : action?.startsWith("model.") ? "/model" : "/effort",
|
|
1913
|
+
this.app
|
|
1914
|
+
);
|
|
1740
1915
|
return this.present(result);
|
|
1741
1916
|
}
|
|
1742
1917
|
async present(result) {
|
|
1743
|
-
const output = /* @__PURE__ */ __name((title, text, actions) => ({
|
|
1744
|
-
|
|
1918
|
+
const output = /* @__PURE__ */ __name((title, text, actions) => ({
|
|
1919
|
+
selectedId: this.app.sessionId,
|
|
1920
|
+
output: { title, text, ...actions ? { actions } : {} }
|
|
1921
|
+
}), "output");
|
|
1922
|
+
const action = /* @__PURE__ */ __name((label, name, value) => ({
|
|
1923
|
+
label,
|
|
1924
|
+
command: "console.action",
|
|
1925
|
+
args: { action: name, value }
|
|
1926
|
+
}), "action");
|
|
1745
1927
|
switch (result.type) {
|
|
1746
1928
|
case "fork.selection.requested":
|
|
1747
|
-
return output(
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1929
|
+
return output(
|
|
1930
|
+
"Session \u5206\u652F",
|
|
1931
|
+
"\u9009\u62E9\u5B8C\u6574\u56DE\u590D\u548C\u5DE5\u4F5C\u533A\u65B9\u5F0F\u3002",
|
|
1932
|
+
result.points.filter((point) => point.available).flatMap((point) => [
|
|
1933
|
+
{
|
|
1934
|
+
label: `${point.userPreview} \xB7 \u5F53\u524D\u5DE5\u4F5C\u533A`,
|
|
1935
|
+
command: "session.fork",
|
|
1936
|
+
args: { pointId: point.id, mode: "current" }
|
|
1937
|
+
},
|
|
1938
|
+
...point.worktreeAvailable ? [
|
|
1939
|
+
{
|
|
1940
|
+
label: `${point.userPreview} \xB7 \u65B0\u5EFA worktree`,
|
|
1941
|
+
command: "session.fork",
|
|
1942
|
+
args: { pointId: point.id, mode: "worktree" }
|
|
1943
|
+
}
|
|
1944
|
+
] : []
|
|
1945
|
+
])
|
|
1946
|
+
);
|
|
1751
1947
|
case "changes.selection.requested":
|
|
1752
1948
|
return { diff: result.diff };
|
|
1753
1949
|
case "worktrees.display":
|
|
1754
|
-
return output(
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1950
|
+
return output(
|
|
1951
|
+
"worktrees",
|
|
1952
|
+
result.worktrees.map((tree) => `${tree.branch} \xB7 ${tree.path}`).join("\n"),
|
|
1953
|
+
result.worktrees.flatMap((tree) => [
|
|
1954
|
+
{ label: `\u6253\u5F00 ${tree.branch}`, command: "worktree.open", args: { id: tree.id } },
|
|
1955
|
+
{
|
|
1956
|
+
label: `\u5220\u9664 ${tree.branch}`,
|
|
1957
|
+
command: "worktree.delete",
|
|
1958
|
+
args: { id: tree.id },
|
|
1959
|
+
confirm: `\u5220\u9664\u5DE5\u4F5C\u533A ${tree.path}\uFF1F`
|
|
1960
|
+
}
|
|
1961
|
+
])
|
|
1962
|
+
);
|
|
1758
1963
|
case "exit":
|
|
1759
1964
|
return { disconnect: true };
|
|
1760
1965
|
case "web.requested":
|
|
@@ -1771,19 +1976,28 @@ ${request.params.message}`,
|
|
|
1771
1976
|
case "mcp.display":
|
|
1772
1977
|
return output("\u547D\u4EE4\u7ED3\u679C", result.text);
|
|
1773
1978
|
case "help":
|
|
1774
|
-
return output(
|
|
1979
|
+
return output(
|
|
1980
|
+
"\u547D\u4EE4\u5E2E\u52A9",
|
|
1981
|
+
result.commands.map((item) => `${item.usage} \u2014 ${item.description}`).join("\n") + "\n/details \u2014 \u5C55\u5F00\u6216\u6536\u8D77\u5DE5\u5177\u8BE6\u60C5\n/thinking \u2014 \u663E\u793A\u6216\u9690\u85CF\u601D\u8003\u8FC7\u7A0B"
|
|
1982
|
+
);
|
|
1775
1983
|
case "instructions":
|
|
1776
1984
|
return output("\u5F53\u524D\u6307\u4EE4", result.instructions.effective);
|
|
1777
1985
|
case "status":
|
|
1778
|
-
return output(
|
|
1986
|
+
return output(
|
|
1987
|
+
"\u8FD0\u884C\u72B6\u6001",
|
|
1988
|
+
`Session: ${this.app.sessionId}
|
|
1779
1989
|
Workspace: ${this.app.workspace}
|
|
1780
|
-
Model: ${this.app.modelInfo?.model ?? "\u672A\u77E5"}
|
|
1990
|
+
Model: ${this.app.application.modelInfo?.model ?? "\u672A\u77E5"}
|
|
1781
1991
|
Effort: ${(await this.app.getReasoningEffort()).effectiveEffort ?? "\u9ED8\u8BA4"}
|
|
1782
|
-
${JSON.stringify(result.inspection, null, 2) ?? ""}`
|
|
1992
|
+
${JSON.stringify(result.inspection, null, 2) ?? ""}`
|
|
1993
|
+
);
|
|
1783
1994
|
case "context":
|
|
1784
1995
|
return output("\u4E0A\u4E0B\u6587", JSON.stringify(result.inspection, null, 2) ?? "\u5F53\u524D\u6A21\u578B\u6CA1\u6709\u63D0\u4F9B\u4E0A\u4E0B\u6587\u7528\u91CF\u3002");
|
|
1785
1996
|
case "compacted":
|
|
1786
|
-
return output(
|
|
1997
|
+
return output(
|
|
1998
|
+
"\u4E0A\u4E0B\u6587\u538B\u7F29",
|
|
1999
|
+
`${result.result.strategy}: ${result.result.before.messageCount} \u2192 ${result.result.after.messageCount}`
|
|
2000
|
+
);
|
|
1787
2001
|
case "mcp.status":
|
|
1788
2002
|
return output("MCP", formatMaybeCodeMcpStatus(result.servers));
|
|
1789
2003
|
case "session.created":
|
|
@@ -1791,18 +2005,43 @@ ${JSON.stringify(result.inspection, null, 2) ?? ""}`);
|
|
|
1791
2005
|
case "model.switched":
|
|
1792
2006
|
return { selectedId: this.app.sessionId };
|
|
1793
2007
|
case "session.selection.requested":
|
|
1794
|
-
return output(
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
2008
|
+
return output(
|
|
2009
|
+
"\u4F1A\u8BDD\u7BA1\u7406",
|
|
2010
|
+
"\u9009\u62E9\u4F1A\u8BDD\u64CD\u4F5C\u3002",
|
|
2011
|
+
result.sessions.flatMap((session) => [
|
|
2012
|
+
action(`\u7EE7\u7EED \xB7 ${session.title ?? session.id}`, "session.resume", session.id),
|
|
2013
|
+
{
|
|
2014
|
+
...action(`\u91CD\u547D\u540D \xB7 ${session.title ?? session.id}`, "session.rename", session.id),
|
|
2015
|
+
input: { name: "title", label: "\u4F1A\u8BDD\u540D\u79F0", value: session.title ?? "" }
|
|
2016
|
+
},
|
|
2017
|
+
...session.id === this.app.sessionId ? [] : [
|
|
2018
|
+
{
|
|
2019
|
+
...action(`\u5220\u9664 \xB7 ${session.title ?? session.id}`, "session.delete", session.id),
|
|
2020
|
+
confirm: `\u786E\u8BA4\u5220\u9664\u4F1A\u8BDD ${session.title ?? session.id} \u53CA\u5176\u5386\u53F2\u8BB0\u5F55\uFF1F`
|
|
2021
|
+
}
|
|
2022
|
+
]
|
|
2023
|
+
])
|
|
2024
|
+
);
|
|
1799
2025
|
case "model.selection.requested":
|
|
1800
|
-
return output(
|
|
2026
|
+
return output(
|
|
2027
|
+
"\u6A21\u578B\u914D\u7F6E",
|
|
2028
|
+
`\u5F53\u524D\uFF1A${this.app.application.modelInfo?.profile ?? "\u672A\u77E5"}`,
|
|
2029
|
+
result.models.flatMap((model) => [
|
|
2030
|
+
action(`\u5207\u6362 \xB7 ${model.name}`, "model.switch", model.name),
|
|
2031
|
+
action(`${model.isDefault ? "\u5F53\u524D\u9ED8\u8BA4" : "\u8BBE\u4E3A\u9ED8\u8BA4"} \xB7 ${model.name}`, "model.default", model.name)
|
|
2032
|
+
])
|
|
2033
|
+
);
|
|
1801
2034
|
case "effort.selection.requested":
|
|
1802
2035
|
case "effort.changed":
|
|
1803
|
-
return output(
|
|
2036
|
+
return output(
|
|
2037
|
+
"Reasoning effort",
|
|
2038
|
+
`\u5F53\u524D\uFF1A${result.state.effectiveEffort ?? "\u9ED8\u8BA4"}
|
|
1804
2039
|
Provider \u9ED8\u8BA4\uFF1A${result.state.defaultEffort ?? "\u672A\u63D0\u4F9B"}
|
|
1805
|
-
\u80FD\u529B\u72B6\u6001\uFF1A${result.state.status}`,
|
|
2040
|
+
\u80FD\u529B\u72B6\u6001\uFF1A${result.state.status}`,
|
|
2041
|
+
result.state.status === "known" ? ["default", ...result.state.efforts].map(
|
|
2042
|
+
(effort) => action(effort === "default" ? "\u6062\u590D\u914D\u7F6E\u9ED8\u8BA4" : effort, "effort.set", effort)
|
|
2043
|
+
) : []
|
|
2044
|
+
);
|
|
1806
2045
|
case "skill.run-started":
|
|
1807
2046
|
case "mcp.run-started":
|
|
1808
2047
|
case "retry.started":
|
|
@@ -1820,12 +2059,22 @@ function createMaybeCodeWebHost(app, options = {}) {
|
|
|
1820
2059
|
const host = new ApplicationUiHost(app, {
|
|
1821
2060
|
...options,
|
|
1822
2061
|
permissionActor: /* @__PURE__ */ __name(() => `local:${userInfo2().username}`, "permissionActor"),
|
|
1823
|
-
...app.persistentRulesEnabled
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
2062
|
+
...app.application.persistentRulesEnabled && app.listPermissionRules && app.revokePermissionRule ? {
|
|
2063
|
+
permissionRules: {
|
|
2064
|
+
list: /* @__PURE__ */ __name(() => app.listPermissionRules(), "list"),
|
|
2065
|
+
revoke: /* @__PURE__ */ __name((id) => app.revokePermissionRule(id), "revoke"),
|
|
2066
|
+
...app.createPermissionRuleFrom ? {
|
|
2067
|
+
create: /* @__PURE__ */ __name((id, decision) => app.createPermissionRuleFrom(id, { decision, createdBy: `local:${userInfo2().username}` }), "create")
|
|
2068
|
+
} : {}
|
|
2069
|
+
}
|
|
2070
|
+
} : {},
|
|
2071
|
+
product: {
|
|
2072
|
+
id: "maybecode",
|
|
2073
|
+
title: "MaybeCode",
|
|
2074
|
+
resourceKind: "session",
|
|
2075
|
+
subtitle: "\u56F4\u7ED5\u4F60\u7684\u4EE3\u7801\u5DE5\u4F5C\u3002\u67E5\u770B\u5DE5\u5177\u6267\u884C\uFF0C\u5728\u5173\u952E\u64CD\u4F5C\u524D\u786E\u8BA4\uFF0C\u8BA9\u6BCF\u4E00\u6B65\u90FD\u6709\u8FF9\u53EF\u5FAA\u3002",
|
|
2076
|
+
suggestions: ["\u4ECB\u7ECD\u8FD9\u4E2A\u9879\u76EE\u7684\u7ED3\u6784", "\u68C0\u67E5\u5F53\u524D\u5DE5\u4F5C\u533A\u7684\u6539\u52A8", "\u5E2E\u6211\u5B9A\u4F4D\u4E00\u4E2A\u95EE\u9898"]
|
|
2077
|
+
},
|
|
1829
2078
|
commands: [
|
|
1830
2079
|
"model.switch",
|
|
1831
2080
|
"effort.set",
|
|
@@ -1853,25 +2102,78 @@ function createMaybeCodeWebHost(app, options = {}) {
|
|
|
1853
2102
|
choices: /* @__PURE__ */ __name(async () => {
|
|
1854
2103
|
const models = await app.listModels();
|
|
1855
2104
|
const effort = await app.getReasoningEffort();
|
|
1856
|
-
const resetEffort = models.find((model) => model.name === app.modelInfo?.profile)?.reasoningEffort ?? effort.defaultEffort;
|
|
2105
|
+
const resetEffort = models.find((model) => model.name === app.application.modelInfo?.profile)?.reasoningEffort ?? effort.defaultEffort;
|
|
1857
2106
|
return [
|
|
1858
|
-
...models.length ? [
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
2107
|
+
...models.length ? [
|
|
2108
|
+
{
|
|
2109
|
+
command: "model.switch",
|
|
2110
|
+
label: "\u6A21\u578B\u914D\u7F6E",
|
|
2111
|
+
value: app.application.modelInfo?.profile ?? models[0].name,
|
|
2112
|
+
options: models.map((m) => ({ value: m.name, label: m.name }))
|
|
2113
|
+
}
|
|
2114
|
+
] : [],
|
|
2115
|
+
...effort.status === "known" ? [
|
|
2116
|
+
{
|
|
2117
|
+
command: "effort.set",
|
|
2118
|
+
label: "Reasoning effort",
|
|
2119
|
+
value: effort.overridden ? effort.effectiveEffort ?? "default" : "default",
|
|
2120
|
+
options: [
|
|
2121
|
+
{ value: "default", label: `\u914D\u7F6E\u9ED8\u8BA4 (${resetEffort ?? "Provider"})` },
|
|
2122
|
+
...effort.efforts.map((value) => ({ value, label: value }))
|
|
2123
|
+
]
|
|
2124
|
+
}
|
|
2125
|
+
] : [],
|
|
2126
|
+
{
|
|
2127
|
+
command: "permission.set",
|
|
2128
|
+
label: "Permissions",
|
|
2129
|
+
value: app.permissionMode,
|
|
2130
|
+
options: [
|
|
2131
|
+
{ value: "default", label: "Default" },
|
|
2132
|
+
{ value: "yolo", label: "YOLO \xB7 Auto-approve" }
|
|
2133
|
+
]
|
|
2134
|
+
}
|
|
1864
2135
|
];
|
|
1865
2136
|
}, "choices"),
|
|
1866
2137
|
panels: /* @__PURE__ */ __name(async () => [
|
|
1867
|
-
{
|
|
1868
|
-
|
|
1869
|
-
|
|
2138
|
+
{
|
|
2139
|
+
id: "permissions",
|
|
2140
|
+
title: "Permissions",
|
|
2141
|
+
fields: [{ label: "Mode", value: app.permissionMode === "yolo" ? "YOLO \xB7 Auto-approve" : "Default" }]
|
|
2142
|
+
},
|
|
2143
|
+
{
|
|
2144
|
+
id: "model",
|
|
2145
|
+
title: "\u6A21\u578B",
|
|
2146
|
+
fields: [
|
|
2147
|
+
{ label: "\u5F53\u524D\u6A21\u578B", value: app.application.modelInfo?.model ?? "\u672A\u77E5" },
|
|
2148
|
+
{ label: "Provider", value: app.application.modelInfo?.provider ?? "\u672A\u77E5" }
|
|
2149
|
+
]
|
|
2150
|
+
},
|
|
2151
|
+
...app.getModelCapabilities && app.modelCapabilitiesAvailable !== false ? [
|
|
2152
|
+
{
|
|
2153
|
+
id: "model-capabilities",
|
|
2154
|
+
title: "\u6A21\u578B\u80FD\u529B",
|
|
2155
|
+
fields: capabilityFields(await app.getModelCapabilities()),
|
|
2156
|
+
actions: [{ label: "\u5237\u65B0\u80FD\u529B\u4FE1\u606F", command: "model.capabilities.refresh", args: {} }]
|
|
2157
|
+
}
|
|
2158
|
+
] : [],
|
|
1870
2159
|
...app.getTelemetry ? [createTelemetryPanel(app.getTelemetry({ limit: 40 }))] : [],
|
|
1871
2160
|
{ id: "subagents", title: "\u5B50 Agent", ...subagentPanel(app) },
|
|
1872
|
-
{
|
|
1873
|
-
|
|
1874
|
-
|
|
2161
|
+
{
|
|
2162
|
+
id: "recovery",
|
|
2163
|
+
title: "\u6062\u590D",
|
|
2164
|
+
fields: [
|
|
2165
|
+
{ label: "\u5F85\u5904\u7406\u9879", value: String(app.listRecoveries().length) },
|
|
2166
|
+
{ label: "\u5904\u7406\u65B9\u5F0F", value: "\u4F7F\u7528 /recovery \u67E5\u770B\u8BC1\u636E\u5E76\u8BB0\u5F55\u6838\u67E5\u7ED3\u679C\u3002" }
|
|
2167
|
+
]
|
|
2168
|
+
},
|
|
2169
|
+
{ id: "goal", title: "\u76EE\u6807", fields: [{ label: "\u72B6\u6001", value: formatGoal(app.application.getGoal()) }] },
|
|
2170
|
+
...options.terminal ? [
|
|
2171
|
+
{
|
|
2172
|
+
id: "terminal",
|
|
2173
|
+
title: "\u7EC8\u7AEF",
|
|
2174
|
+
fields: [{ label: "\u5171\u4EAB\u4F1A\u8BDD", value: "MCP \u4EA4\u4E92\u53EF\u4EE5\u5728\u7EC8\u7AEF\u6216\u5F53\u524D\u9875\u9762\u5904\u7406\u3002\u9000\u51FA\u5BBF\u4E3B\u4F1A\u5173\u95ED Web \u670D\u52A1\u3002" }]
|
|
2175
|
+
}
|
|
2176
|
+
] : []
|
|
1875
2177
|
], "panels"),
|
|
1876
2178
|
execute: /* @__PURE__ */ __name((command) => commands.execute(command), "execute")
|
|
1877
2179
|
});
|
|
@@ -1879,28 +2181,45 @@ function createMaybeCodeWebHost(app, options = {}) {
|
|
|
1879
2181
|
}
|
|
1880
2182
|
__name(createMaybeCodeWebHost, "createMaybeCodeWebHost");
|
|
1881
2183
|
function capabilityFields(capabilities) {
|
|
1882
|
-
const names = {
|
|
2184
|
+
const names = {
|
|
2185
|
+
"input.text": "\u6587\u672C\u8F93\u5165",
|
|
2186
|
+
"input.image": "\u56FE\u7247\u8F93\u5165",
|
|
2187
|
+
"input.audio": "\u97F3\u9891\u8F93\u5165",
|
|
2188
|
+
"input.file": "\u6587\u4EF6\u8F93\u5165",
|
|
2189
|
+
"output.text": "\u6587\u672C\u8F93\u51FA",
|
|
2190
|
+
"output.image": "\u56FE\u7247\u8F93\u51FA",
|
|
2191
|
+
"output.audio": "\u97F3\u9891\u8F93\u51FA",
|
|
2192
|
+
tools: "\u5DE5\u5177\u8C03\u7528",
|
|
2193
|
+
"structuredOutput.json": "JSON \u8F93\u51FA",
|
|
2194
|
+
"structuredOutput.jsonSchema": "JSON Schema",
|
|
2195
|
+
contextCompaction: "Context \u538B\u7F29"
|
|
2196
|
+
};
|
|
1883
2197
|
return [
|
|
1884
2198
|
...Object.entries(capabilities.fields ?? {}).slice(0, 40).map(([key, field]) => ({
|
|
1885
2199
|
label: names[key] ?? key,
|
|
1886
2200
|
value: field.status === "unknown" ? "\u80FD\u529B\u672A\u77E5" : field.status === "unsupported" ? `\u4E0D\u652F\u6301 \xB7 ${field.source}` : `${JSON.stringify(field.value)} \xB7 ${field.source}`
|
|
1887
2201
|
})),
|
|
1888
2202
|
...capabilities.version === void 0 ? [] : [{ label: "\u80FD\u529B\u7248\u672C", value: capabilities.version }],
|
|
1889
|
-
...capabilities.diagnostics?.map((item) => ({
|
|
2203
|
+
...capabilities.diagnostics?.map((item) => ({
|
|
2204
|
+
label: item.discovery,
|
|
2205
|
+
value: `${item.code} \xB7 ${new Date(item.observedAt).toISOString()}`
|
|
2206
|
+
})) ?? []
|
|
1890
2207
|
];
|
|
1891
2208
|
}
|
|
1892
2209
|
__name(capabilityFields, "capabilityFields");
|
|
1893
2210
|
function subagentPanel(app) {
|
|
1894
|
-
const state = app.getDelegationState
|
|
1895
|
-
const requests = app.listDelegationRequests
|
|
2211
|
+
const state = app.application.getDelegationState();
|
|
2212
|
+
const requests = app.application.listDelegationRequests();
|
|
1896
2213
|
if (state === void 0 && requests.length === 0) {
|
|
1897
2214
|
return { fields: [{ label: "\u72B6\u6001", value: "\u672C\u6B21\u4F1A\u8BDD\u8FD8\u6CA1\u6709\u5B50 Agent \u8BF7\u6C42\u3002" }] };
|
|
1898
2215
|
}
|
|
1899
2216
|
const tasks = state?.tasks ?? requests[0]?.tasks ?? [];
|
|
1900
|
-
const fields = [
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
2217
|
+
const fields = [
|
|
2218
|
+
{
|
|
2219
|
+
label: "\u5F53\u524D\u8BF7\u6C42",
|
|
2220
|
+
value: state === void 0 ? "\u7A7A\u95F2" : `${state.status} \xB7 ${state.requestId}`
|
|
2221
|
+
}
|
|
2222
|
+
];
|
|
1904
2223
|
for (const task of [...tasks].sort((left, right) => left.depth - right.depth || left.id.localeCompare(right.id)).slice(0, 12)) {
|
|
1905
2224
|
const detail = task.detail ?? (task.output === void 0 ? "" : task.output.replace(/\s+/gu, " ").slice(0, 80));
|
|
1906
2225
|
fields.push({
|
|
@@ -1914,7 +2233,9 @@ function subagentPanel(app) {
|
|
|
1914
2233
|
value: `${state.budget.modelCalls}/${state.budget.maxModelCalls} \u6B21\u6A21\u578B\u8C03\u7528 \xB7 ${state.budget.totalTokens} tokens${state.budget.usageComplete ? "" : "\uFF08\u542B\u9884\u7559\u503C\u8BA1\u8D26\uFF09"}`
|
|
1915
2234
|
});
|
|
1916
2235
|
}
|
|
1917
|
-
const pending2 =
|
|
2236
|
+
const pending2 = requests.flatMap(
|
|
2237
|
+
(request) => request.tasks.filter((task) => task.status === "recovery-required").map((task) => task.id)
|
|
2238
|
+
);
|
|
1918
2239
|
fields.push({
|
|
1919
2240
|
label: "\u67E5\u770B\u4E0E\u6062\u590D",
|
|
1920
2241
|
value: pending2.length === 0 ? "/delegations \u67E5\u770B\u4EFB\u52A1\u6811\uFF0C/delegations tools <\u4EFB\u52A1> \u67E5\u770B\u5DE5\u5177\u8BB0\u5F55" : `/delegations resolve <\u4EFB\u52A1> <failed|cancelled> <\u6838\u67E5\u7ED3\u8BBA>\uFF08\u5F85\u6838\u5BF9\uFF1A${pending2.join(", ")}\uFF09`
|
|
@@ -1924,7 +2245,7 @@ function subagentPanel(app) {
|
|
|
1924
2245
|
__name(subagentPanel, "subagentPanel");
|
|
1925
2246
|
async function startMaybeCodeWebServer(host, options) {
|
|
1926
2247
|
try {
|
|
1927
|
-
const { startMaybeCodeWebServer: startServer } = await import("./web-server-
|
|
2248
|
+
const { startMaybeCodeWebServer: startServer } = await import("./web-server-SXMH6FGA.js");
|
|
1928
2249
|
return await startServer(host, options);
|
|
1929
2250
|
} catch (error) {
|
|
1930
2251
|
await host.close();
|
|
@@ -1942,21 +2263,29 @@ async function runMaybeCodeWebUI(app, options) {
|
|
|
1942
2263
|
await app.close();
|
|
1943
2264
|
throw new Error("Set MAYBECODE_CONTROL_TOKEN (32..256 printable ASCII characters) before starting --ui web.");
|
|
1944
2265
|
}
|
|
1945
|
-
const server = await startMaybeCodeWebUI(app, { token,
|
|
1946
|
-
options.write(
|
|
2266
|
+
const server = await startMaybeCodeWebUI(app, omitUndefined({ token, port: options.port }));
|
|
2267
|
+
options.write(
|
|
2268
|
+
`MaybeCode Web UI: ${server.url}
|
|
1947
2269
|
Enter MAYBECODE_CONTROL_TOKEN in the connection dialog. Closing a browser tab does not stop the agent. Ctrl+C stops the host.
|
|
1948
|
-
`
|
|
2270
|
+
`
|
|
2271
|
+
);
|
|
2272
|
+
let closing;
|
|
2273
|
+
let closingFailure;
|
|
1949
2274
|
const stop = /* @__PURE__ */ __name(() => {
|
|
1950
|
-
|
|
2275
|
+
closing ??= server.close().catch((error) => {
|
|
2276
|
+
closingFailure = error;
|
|
2277
|
+
});
|
|
1951
2278
|
}, "stop");
|
|
1952
2279
|
process.once("SIGINT", stop);
|
|
1953
2280
|
process.once("SIGTERM", stop);
|
|
1954
2281
|
try {
|
|
1955
2282
|
await server.closed;
|
|
1956
|
-
await server.close();
|
|
1957
2283
|
} finally {
|
|
1958
2284
|
process.removeListener("SIGINT", stop);
|
|
1959
2285
|
process.removeListener("SIGTERM", stop);
|
|
2286
|
+
stop();
|
|
2287
|
+
await closing;
|
|
2288
|
+
if (closingFailure !== void 0) throw closingFailure;
|
|
1960
2289
|
}
|
|
1961
2290
|
}
|
|
1962
2291
|
__name(runMaybeCodeWebUI, "runMaybeCodeWebUI");
|
|
@@ -1975,4 +2304,4 @@ export {
|
|
|
1975
2304
|
startMaybeCodeWebUI,
|
|
1976
2305
|
runMaybeCodeWebUI
|
|
1977
2306
|
};
|
|
1978
|
-
//# sourceMappingURL=chunk-
|
|
2307
|
+
//# sourceMappingURL=chunk-WMSG5ZTR.js.map
|