@workbench-kit/shell-react 0.0.2-prototype.0.2.6 → 0.0.2-prototype.0.2.8
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 +41 -0
- package/package.json +9 -9
- package/src/{chat-ai-mock-proposals.ts → chat/ai-mock-proposals.ts} +39 -39
- package/src/{chat-command-input.ts → chat/command-input.ts} +52 -52
- package/src/{chat-command-policy.ts → chat/command-policy.ts} +54 -54
- package/src/{chat-command-surface.tsx → chat/command-surface.tsx} +155 -155
- package/src/{use-workbench-chat-command-proposals.ts → chat/use-chat-command-proposals.ts} +194 -194
- package/src/{chat-view-data.ts → chat/view-data.ts} +20 -20
- package/src/{chat-view.tsx → chat/view.tsx} +220 -220
- package/src/{command-inspector-surface.tsx → commands/inspector-surface.tsx} +46 -46
- package/src/{use-workbench-command-descriptors.ts → commands/use-command-descriptors.ts} +41 -41
- package/src/{use-context-key-revision.ts → commands/use-context-key-revision.ts} +18 -18
- package/src/{commands-view-data.ts → commands/view-data.ts} +17 -17
- package/src/{commands-view.tsx → commands/view.tsx} +43 -43
- package/src/devtools/WorkbenchDevtoolsPanel.tsx +124 -124
- package/src/devtools/WorkbenchDevtoolsShell.tsx +17 -17
- package/src/devtools/index.ts +11 -11
- package/src/devtools/use-workbench-devtools-snapshot.ts +84 -84
- package/src/devtools/workbench-devtools-snapshot.ts +140 -140
- package/src/devtools/workbench-devtools.css +82 -82
- package/src/{editor-area-dnd.ts → editor/area-dnd.ts} +69 -69
- package/src/{editor-area-model.ts → editor/area-model.ts} +71 -71
- package/src/{editor-area.css → editor/area.css} +454 -454
- package/src/{editor-area.tsx → editor/area.tsx} +676 -676
- package/src/{editor-host-surface.tsx → editor/host-surface.tsx} +631 -634
- package/src/{editor-pane-visibility.ts → editor/pane-visibility.ts} +130 -130
- package/src/{editor-resource.ts → editor/resource.ts} +36 -36
- package/src/{editor-state-storage.ts → editor/state-storage.ts} +182 -193
- package/src/{editor-tab-context-menu.ts → editor/tab-context-menu.ts} +118 -118
- package/src/{use-editor.ts → editor/use-editor.ts} +114 -107
- package/src/{editor-view-providers.tsx → editor/view-providers.tsx} +552 -552
- package/src/{editor-workspace-file-availability.ts → editor/workspace-file-availability.ts} +15 -15
- package/src/{editor-workspace-reconcile.tsx → editor/workspace-reconcile.tsx} +31 -28
- package/src/{explorer-context-menu.ts → explorer/context-menu.ts} +114 -114
- package/src/{createCommandWorkspaceExplorerPort.ts → explorer/create-command-workspace-explorer-port.ts} +86 -86
- package/src/{explorer-reveal.ts → explorer/reveal.ts} +112 -112
- package/src/{search-view-data.ts → explorer/search-view-data.ts} +15 -15
- package/src/{search-view.tsx → explorer/search-view.tsx} +65 -62
- package/src/{use-active-workspace-path.ts → explorer/use-active-workspace-path.ts} +15 -15
- package/src/{explorer-view-data.ts → explorer/view-data.ts} +58 -58
- package/src/{explorer-view.tsx → explorer/view.tsx} +227 -224
- package/src/{extension-context-menu.ts → extensions/context-menu.ts} +52 -52
- package/src/{extension-management-model.ts → extensions/management-model.ts} +313 -313
- package/src/{use-extension-management.ts → extensions/use-extension-management.ts} +241 -193
- package/src/{extensions-view-data.ts → extensions/view-data.ts} +19 -19
- package/src/{extensions-view.tsx → extensions/view.tsx} +63 -38
- package/src/{field-remap-demo.tsx → field-remap/demo.tsx} +18 -18
- package/src/{field-remap-editor-surface.tsx → field-remap/editor-surface.tsx} +36 -36
- package/src/{field-remap-flow-adapter.ts → field-remap/flow-adapter.ts} +240 -240
- package/src/{field-remap-flow.tsx → field-remap/flow.tsx} +369 -369
- package/src/{field-remap-graph.tsx → field-remap/graph.tsx} +559 -559
- package/src/field-remap/jsonata-transform.ts +166 -0
- package/src/{field-remap-panel.tsx → field-remap/panel.tsx} +193 -175
- package/src/{field-remap-samples.ts → field-remap/samples.ts} +352 -352
- package/src/{table-mapping-adapter.ts → field-remap/table-mapping-adapter.ts} +59 -59
- package/src/{field-remap-tree.tsx → field-remap/tree.tsx} +404 -404
- package/src/{field-remap-view-data.ts → field-remap/view-data.ts} +16 -16
- package/src/{field-remap-view.css → field-remap/view.css} +676 -676
- package/src/{field-remap-view.tsx → field-remap/view.tsx} +86 -86
- package/src/index.ts +212 -199
- package/src/{json-form-source-patch.ts → jdw/json-form-source-patch.ts} +323 -323
- package/src/{jdw-lab-view-data.ts → jdw/lab-view-data.ts} +25 -25
- package/src/{jdw-lab-view.css → jdw/lab-view.css} +21 -21
- package/src/{jdw-lab-view.tsx → jdw/lab-view.tsx} +79 -79
- package/src/{jdw-widget-form-view.tsx → jdw/widget-form-view.tsx} +68 -65
- package/src/{jdw-widget-preview-view.tsx → jdw/widget-preview-view.tsx} +54 -51
- package/src/{keybinding-overrides-storage.ts → management/keybinding-overrides-storage.ts} +49 -57
- package/src/{keybinding-management-settings.tsx → management/keybinding-settings.tsx} +16 -16
- package/src/{management-palette-commands.ts → management/palette-commands.ts} +38 -38
- package/src/{preference-settings-storage.ts → management/preference-settings-storage.ts} +50 -58
- package/src/{management-settings-ids.ts → management/settings-ids.ts} +12 -12
- package/src/{management-settings.tsx → management/settings.tsx} +96 -75
- package/src/{use-command-management.ts → management/use-command-management.ts} +191 -191
- package/src/{use-keybinding-management.ts → management/use-keybinding-management.ts} +130 -130
- package/src/{shell-model.tsx → shell/model.tsx} +149 -149
- package/src/{provider.tsx → shell/provider.tsx} +603 -573
- package/src/{shell-secondary-actions.tsx → shell/secondary-actions.tsx} +59 -59
- package/src/{shell-settings-constants.ts → shell/settings-constants.ts} +9 -9
- package/src/{shell-settings.tsx → shell/settings.tsx} +599 -599
- package/src/{shell.tsx → shell/shell.tsx} +680 -649
- package/src/{shell-titlebar-layout-controls.tsx → shell/titlebar-layout-controls.tsx} +4 -4
- package/src/{shell-view-host.tsx → shell/view-host.tsx} +212 -199
- package/src/{workbench-appearance-storage.ts → workbench/appearance-storage.ts} +107 -115
- package/src/{workbench-command-host.tsx → workbench/command-host.tsx} +243 -243
- package/src/{workbench-command-palette.ts → workbench/command-palette.ts} +208 -208
- package/src/{workbench-keybinding-bridge.ts → workbench/keybinding-bridge.ts} +54 -54
- package/src/{workbench-layout-storage.ts → workbench/layout-storage.ts} +134 -145
- package/src/{workbench-profile-modal.tsx → workbench/profile-modal.tsx} +118 -118
- package/src/{workbench-shell-command-registration.ts → workbench/shell-command-registration.ts} +58 -58
- package/src/{workbench-startup-gate.tsx → workbench/startup-gate.tsx} +136 -136
- package/src/{workbench-status-sections.ts → workbench/status-sections.ts} +43 -43
- package/src/{use-persisted-workbench-appearance.ts → workbench/use-persisted-appearance.ts} +33 -33
- package/src/{workbench-user-commands.ts → workbench/user-commands.ts} +46 -46
- package/src/{workspace-view-state.ts → workbench/workspace-view-state.ts} +35 -35
- package/src/jsonata-transform.ts +0 -36
|
@@ -1,194 +1,194 @@
|
|
|
1
|
-
import { useCallback, useRef, type Dispatch, type SetStateAction } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
isWorkbenchCommandRunnable,
|
|
4
|
-
resolveWorkbenchCommandExecutionPolicy,
|
|
5
|
-
type ResolveWorkbenchCommandExecutionPolicyInput,
|
|
6
|
-
type WorkbenchCommandDescriptor,
|
|
7
|
-
} from '@workbench-kit/react/workbench';
|
|
8
|
-
import type { ChatCommandProposal, ChatMessage } from '@workbench-kit/react/workbench/chat';
|
|
9
|
-
|
|
10
|
-
import { type WorkbenchChatCommandRunResult } from './
|
|
11
|
-
import { useWorkbench } from '
|
|
12
|
-
|
|
13
|
-
export interface WorkbenchChatCommandProposalInput {
|
|
14
|
-
args?: readonly unknown[] | undefined;
|
|
15
|
-
commandId: string;
|
|
16
|
-
description?: string | undefined;
|
|
17
|
-
id?: string | undefined;
|
|
18
|
-
label?: string | undefined;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface UseWorkbenchChatCommandProposalsOptions {
|
|
22
|
-
commands: readonly WorkbenchCommandDescriptor[];
|
|
23
|
-
onCommandResult?: ((result: WorkbenchChatCommandRunResult) => void) | undefined;
|
|
24
|
-
policyInput?: ResolveWorkbenchCommandExecutionPolicyInput | undefined;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function getCommandErrorMessage(error: unknown) {
|
|
28
|
-
if (error instanceof Error) {
|
|
29
|
-
return error.message;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return String(error);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function createProposalId(commandId: string) {
|
|
36
|
-
return `proposal-${commandId}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function useWorkbenchChatCommandProposals({
|
|
40
|
-
commands,
|
|
41
|
-
onCommandResult,
|
|
42
|
-
policyInput,
|
|
43
|
-
}: UseWorkbenchChatCommandProposalsOptions) {
|
|
44
|
-
const { executeCommand } = useWorkbench();
|
|
45
|
-
const runningProposalIds = useRef(new Set<string>());
|
|
46
|
-
|
|
47
|
-
const resolveDescriptor = useCallback(
|
|
48
|
-
(commandId: string, label?: string) =>
|
|
49
|
-
commands.find((command) => command.id === commandId) ?? {
|
|
50
|
-
id: commandId,
|
|
51
|
-
label: label ?? commandId,
|
|
52
|
-
},
|
|
53
|
-
[commands],
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
const enrichProposal = useCallback(
|
|
57
|
-
(proposal: WorkbenchChatCommandProposalInput): ChatCommandProposal => {
|
|
58
|
-
const descriptor = resolveDescriptor(proposal.commandId, proposal.label);
|
|
59
|
-
const policy = resolveWorkbenchCommandExecutionPolicy(descriptor, policyInput);
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
args: proposal.args,
|
|
63
|
-
commandId: proposal.commandId,
|
|
64
|
-
description: proposal.description ?? descriptor.description,
|
|
65
|
-
id: proposal.id ?? createProposalId(proposal.commandId),
|
|
66
|
-
label: proposal.label ?? descriptor.label,
|
|
67
|
-
policy,
|
|
68
|
-
status: policy === 'auto-deny' ? 'blocked' : 'pending',
|
|
69
|
-
};
|
|
70
|
-
},
|
|
71
|
-
[policyInput, resolveDescriptor],
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
const enrichMessageProposals = useCallback(
|
|
75
|
-
(proposals: readonly WorkbenchChatCommandProposalInput[]) =>
|
|
76
|
-
proposals.map((proposal) => enrichProposal(proposal)),
|
|
77
|
-
[enrichProposal],
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
const updateProposalStatus = useCallback(
|
|
81
|
-
(
|
|
82
|
-
setMessages: Dispatch<SetStateAction<ChatMessage[]>>,
|
|
83
|
-
messageId: string,
|
|
84
|
-
proposalId: string,
|
|
85
|
-
status: ChatCommandProposal['status'],
|
|
86
|
-
) => {
|
|
87
|
-
setMessages((currentMessages) =>
|
|
88
|
-
currentMessages.map((message) => {
|
|
89
|
-
if (message.id !== messageId || !message.commandProposals) {
|
|
90
|
-
return message;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return {
|
|
94
|
-
...message,
|
|
95
|
-
commandProposals: message.commandProposals.map((proposal) =>
|
|
96
|
-
proposal.id === proposalId ? { ...proposal, status } : proposal,
|
|
97
|
-
),
|
|
98
|
-
};
|
|
99
|
-
}),
|
|
100
|
-
);
|
|
101
|
-
},
|
|
102
|
-
[],
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
const runProposal = useCallback(
|
|
106
|
-
async (
|
|
107
|
-
setMessages: Dispatch<SetStateAction<ChatMessage[]>>,
|
|
108
|
-
messageId: string,
|
|
109
|
-
proposal: ChatCommandProposal,
|
|
110
|
-
) => {
|
|
111
|
-
if (runningProposalIds.current.has(proposal.id)) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const descriptor = resolveDescriptor(proposal.commandId, proposal.label);
|
|
116
|
-
if (!isWorkbenchCommandRunnable(descriptor)) {
|
|
117
|
-
updateProposalStatus(setMessages, messageId, proposal.id, 'failed');
|
|
118
|
-
onCommandResult?.({
|
|
119
|
-
commandId: proposal.commandId,
|
|
120
|
-
label: proposal.label,
|
|
121
|
-
message: descriptor.disabledReason ?? 'Command is currently unavailable.',
|
|
122
|
-
status: 'error',
|
|
123
|
-
});
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
runningProposalIds.current.add(proposal.id);
|
|
128
|
-
updateProposalStatus(setMessages, messageId, proposal.id, 'running');
|
|
129
|
-
|
|
130
|
-
try {
|
|
131
|
-
await executeCommand(proposal.commandId, ...(proposal.args ?? []));
|
|
132
|
-
updateProposalStatus(setMessages, messageId, proposal.id, 'executed');
|
|
133
|
-
onCommandResult?.({
|
|
134
|
-
commandId: proposal.commandId,
|
|
135
|
-
label: proposal.label,
|
|
136
|
-
status: 'success',
|
|
137
|
-
});
|
|
138
|
-
} catch (error) {
|
|
139
|
-
updateProposalStatus(setMessages, messageId, proposal.id, 'failed');
|
|
140
|
-
onCommandResult?.({
|
|
141
|
-
commandId: proposal.commandId,
|
|
142
|
-
label: proposal.label,
|
|
143
|
-
message: getCommandErrorMessage(error),
|
|
144
|
-
status: 'error',
|
|
145
|
-
});
|
|
146
|
-
} finally {
|
|
147
|
-
runningProposalIds.current.delete(proposal.id);
|
|
148
|
-
}
|
|
149
|
-
},
|
|
150
|
-
[executeCommand, onCommandResult, resolveDescriptor, updateProposalStatus],
|
|
151
|
-
);
|
|
152
|
-
|
|
153
|
-
const processAutoPolicies = useCallback(
|
|
154
|
-
(
|
|
155
|
-
setMessages: Dispatch<SetStateAction<ChatMessage[]>>,
|
|
156
|
-
messageId: string,
|
|
157
|
-
proposals: readonly ChatCommandProposal[],
|
|
158
|
-
) => {
|
|
159
|
-
proposals.forEach((proposal) => {
|
|
160
|
-
if (proposal.policy === 'auto-allow' && proposal.status === 'pending') {
|
|
161
|
-
void runProposal(setMessages, messageId, proposal);
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
},
|
|
165
|
-
[runProposal],
|
|
166
|
-
);
|
|
167
|
-
|
|
168
|
-
const createProposalHandlers = useCallback(
|
|
169
|
-
(setMessages: Dispatch<SetStateAction<ChatMessage[]>>) => ({
|
|
170
|
-
onProposalAllow: (messageId: string, proposal: ChatCommandProposal) => {
|
|
171
|
-
if (proposal.status !== 'pending' || proposal.policy !== 'approval-required') {
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
updateProposalStatus(setMessages, messageId, proposal.id, 'allowed');
|
|
176
|
-
void runProposal(setMessages, messageId, proposal);
|
|
177
|
-
},
|
|
178
|
-
onProposalDeny: (messageId: string, proposal: ChatCommandProposal) => {
|
|
179
|
-
if (proposal.status !== 'pending') {
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
updateProposalStatus(setMessages, messageId, proposal.id, 'denied');
|
|
184
|
-
},
|
|
185
|
-
}),
|
|
186
|
-
[runProposal, updateProposalStatus],
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
return {
|
|
190
|
-
createProposalHandlers,
|
|
191
|
-
enrichMessageProposals,
|
|
192
|
-
processAutoPolicies,
|
|
193
|
-
};
|
|
194
|
-
}
|
|
1
|
+
import { useCallback, useRef, type Dispatch, type SetStateAction } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
isWorkbenchCommandRunnable,
|
|
4
|
+
resolveWorkbenchCommandExecutionPolicy,
|
|
5
|
+
type ResolveWorkbenchCommandExecutionPolicyInput,
|
|
6
|
+
type WorkbenchCommandDescriptor,
|
|
7
|
+
} from '@workbench-kit/react/workbench';
|
|
8
|
+
import type { ChatCommandProposal, ChatMessage } from '@workbench-kit/react/workbench/chat';
|
|
9
|
+
|
|
10
|
+
import { type WorkbenchChatCommandRunResult } from './command-surface.js';
|
|
11
|
+
import { useWorkbench } from '../shell/provider.js';
|
|
12
|
+
|
|
13
|
+
export interface WorkbenchChatCommandProposalInput {
|
|
14
|
+
args?: readonly unknown[] | undefined;
|
|
15
|
+
commandId: string;
|
|
16
|
+
description?: string | undefined;
|
|
17
|
+
id?: string | undefined;
|
|
18
|
+
label?: string | undefined;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface UseWorkbenchChatCommandProposalsOptions {
|
|
22
|
+
commands: readonly WorkbenchCommandDescriptor[];
|
|
23
|
+
onCommandResult?: ((result: WorkbenchChatCommandRunResult) => void) | undefined;
|
|
24
|
+
policyInput?: ResolveWorkbenchCommandExecutionPolicyInput | undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getCommandErrorMessage(error: unknown) {
|
|
28
|
+
if (error instanceof Error) {
|
|
29
|
+
return error.message;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return String(error);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function createProposalId(commandId: string) {
|
|
36
|
+
return `proposal-${commandId}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function useWorkbenchChatCommandProposals({
|
|
40
|
+
commands,
|
|
41
|
+
onCommandResult,
|
|
42
|
+
policyInput,
|
|
43
|
+
}: UseWorkbenchChatCommandProposalsOptions) {
|
|
44
|
+
const { executeCommand } = useWorkbench();
|
|
45
|
+
const runningProposalIds = useRef(new Set<string>());
|
|
46
|
+
|
|
47
|
+
const resolveDescriptor = useCallback(
|
|
48
|
+
(commandId: string, label?: string) =>
|
|
49
|
+
commands.find((command) => command.id === commandId) ?? {
|
|
50
|
+
id: commandId,
|
|
51
|
+
label: label ?? commandId,
|
|
52
|
+
},
|
|
53
|
+
[commands],
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const enrichProposal = useCallback(
|
|
57
|
+
(proposal: WorkbenchChatCommandProposalInput): ChatCommandProposal => {
|
|
58
|
+
const descriptor = resolveDescriptor(proposal.commandId, proposal.label);
|
|
59
|
+
const policy = resolveWorkbenchCommandExecutionPolicy(descriptor, policyInput);
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
args: proposal.args,
|
|
63
|
+
commandId: proposal.commandId,
|
|
64
|
+
description: proposal.description ?? descriptor.description,
|
|
65
|
+
id: proposal.id ?? createProposalId(proposal.commandId),
|
|
66
|
+
label: proposal.label ?? descriptor.label,
|
|
67
|
+
policy,
|
|
68
|
+
status: policy === 'auto-deny' ? 'blocked' : 'pending',
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
[policyInput, resolveDescriptor],
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const enrichMessageProposals = useCallback(
|
|
75
|
+
(proposals: readonly WorkbenchChatCommandProposalInput[]) =>
|
|
76
|
+
proposals.map((proposal) => enrichProposal(proposal)),
|
|
77
|
+
[enrichProposal],
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const updateProposalStatus = useCallback(
|
|
81
|
+
(
|
|
82
|
+
setMessages: Dispatch<SetStateAction<ChatMessage[]>>,
|
|
83
|
+
messageId: string,
|
|
84
|
+
proposalId: string,
|
|
85
|
+
status: ChatCommandProposal['status'],
|
|
86
|
+
) => {
|
|
87
|
+
setMessages((currentMessages) =>
|
|
88
|
+
currentMessages.map((message) => {
|
|
89
|
+
if (message.id !== messageId || !message.commandProposals) {
|
|
90
|
+
return message;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
...message,
|
|
95
|
+
commandProposals: message.commandProposals.map((proposal) =>
|
|
96
|
+
proposal.id === proposalId ? { ...proposal, status } : proposal,
|
|
97
|
+
),
|
|
98
|
+
};
|
|
99
|
+
}),
|
|
100
|
+
);
|
|
101
|
+
},
|
|
102
|
+
[],
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
const runProposal = useCallback(
|
|
106
|
+
async (
|
|
107
|
+
setMessages: Dispatch<SetStateAction<ChatMessage[]>>,
|
|
108
|
+
messageId: string,
|
|
109
|
+
proposal: ChatCommandProposal,
|
|
110
|
+
) => {
|
|
111
|
+
if (runningProposalIds.current.has(proposal.id)) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const descriptor = resolveDescriptor(proposal.commandId, proposal.label);
|
|
116
|
+
if (!isWorkbenchCommandRunnable(descriptor)) {
|
|
117
|
+
updateProposalStatus(setMessages, messageId, proposal.id, 'failed');
|
|
118
|
+
onCommandResult?.({
|
|
119
|
+
commandId: proposal.commandId,
|
|
120
|
+
label: proposal.label,
|
|
121
|
+
message: descriptor.disabledReason ?? 'Command is currently unavailable.',
|
|
122
|
+
status: 'error',
|
|
123
|
+
});
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
runningProposalIds.current.add(proposal.id);
|
|
128
|
+
updateProposalStatus(setMessages, messageId, proposal.id, 'running');
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
await executeCommand(proposal.commandId, ...(proposal.args ?? []));
|
|
132
|
+
updateProposalStatus(setMessages, messageId, proposal.id, 'executed');
|
|
133
|
+
onCommandResult?.({
|
|
134
|
+
commandId: proposal.commandId,
|
|
135
|
+
label: proposal.label,
|
|
136
|
+
status: 'success',
|
|
137
|
+
});
|
|
138
|
+
} catch (error) {
|
|
139
|
+
updateProposalStatus(setMessages, messageId, proposal.id, 'failed');
|
|
140
|
+
onCommandResult?.({
|
|
141
|
+
commandId: proposal.commandId,
|
|
142
|
+
label: proposal.label,
|
|
143
|
+
message: getCommandErrorMessage(error),
|
|
144
|
+
status: 'error',
|
|
145
|
+
});
|
|
146
|
+
} finally {
|
|
147
|
+
runningProposalIds.current.delete(proposal.id);
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
[executeCommand, onCommandResult, resolveDescriptor, updateProposalStatus],
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
const processAutoPolicies = useCallback(
|
|
154
|
+
(
|
|
155
|
+
setMessages: Dispatch<SetStateAction<ChatMessage[]>>,
|
|
156
|
+
messageId: string,
|
|
157
|
+
proposals: readonly ChatCommandProposal[],
|
|
158
|
+
) => {
|
|
159
|
+
proposals.forEach((proposal) => {
|
|
160
|
+
if (proposal.policy === 'auto-allow' && proposal.status === 'pending') {
|
|
161
|
+
void runProposal(setMessages, messageId, proposal);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
},
|
|
165
|
+
[runProposal],
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
const createProposalHandlers = useCallback(
|
|
169
|
+
(setMessages: Dispatch<SetStateAction<ChatMessage[]>>) => ({
|
|
170
|
+
onProposalAllow: (messageId: string, proposal: ChatCommandProposal) => {
|
|
171
|
+
if (proposal.status !== 'pending' || proposal.policy !== 'approval-required') {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
updateProposalStatus(setMessages, messageId, proposal.id, 'allowed');
|
|
176
|
+
void runProposal(setMessages, messageId, proposal);
|
|
177
|
+
},
|
|
178
|
+
onProposalDeny: (messageId: string, proposal: ChatCommandProposal) => {
|
|
179
|
+
if (proposal.status !== 'pending') {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
updateProposalStatus(setMessages, messageId, proposal.id, 'denied');
|
|
184
|
+
},
|
|
185
|
+
}),
|
|
186
|
+
[runProposal, updateProposalStatus],
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
createProposalHandlers,
|
|
191
|
+
enrichMessageProposals,
|
|
192
|
+
processAutoPolicies,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
export const BUILTIN_CHAT_VIEW_RENDER_KIND = 'workbench-kit.builtin.chat.view' as const;
|
|
2
|
-
|
|
3
|
-
export type BuiltinChatViewMode = 'aiChat' | 'chatting';
|
|
4
|
-
|
|
5
|
-
export interface BuiltinChatViewRenderData {
|
|
6
|
-
readonly kind: typeof BUILTIN_CHAT_VIEW_RENDER_KIND;
|
|
7
|
-
readonly mode: BuiltinChatViewMode;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function isBuiltinChatViewRenderData(value: unknown): value is BuiltinChatViewRenderData {
|
|
11
|
-
if (typeof value !== 'object' || value === null) {
|
|
12
|
-
return false;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const candidate = value as Partial<BuiltinChatViewRenderData>;
|
|
16
|
-
return (
|
|
17
|
-
candidate.kind === BUILTIN_CHAT_VIEW_RENDER_KIND &&
|
|
18
|
-
(candidate.mode === 'chatting' || candidate.mode === 'aiChat')
|
|
19
|
-
);
|
|
20
|
-
}
|
|
1
|
+
export const BUILTIN_CHAT_VIEW_RENDER_KIND = 'workbench-kit.builtin.chat.view' as const;
|
|
2
|
+
|
|
3
|
+
export type BuiltinChatViewMode = 'aiChat' | 'chatting';
|
|
4
|
+
|
|
5
|
+
export interface BuiltinChatViewRenderData {
|
|
6
|
+
readonly kind: typeof BUILTIN_CHAT_VIEW_RENDER_KIND;
|
|
7
|
+
readonly mode: BuiltinChatViewMode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function isBuiltinChatViewRenderData(value: unknown): value is BuiltinChatViewRenderData {
|
|
11
|
+
if (typeof value !== 'object' || value === null) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const candidate = value as Partial<BuiltinChatViewRenderData>;
|
|
16
|
+
return (
|
|
17
|
+
candidate.kind === BUILTIN_CHAT_VIEW_RENDER_KIND &&
|
|
18
|
+
(candidate.mode === 'chatting' || candidate.mode === 'aiChat')
|
|
19
|
+
);
|
|
20
|
+
}
|