@codingame/monaco-vscode-xterm-addons-common 28.4.0 → 29.0.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/package.json +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatContext.d.ts +7 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatContext.js +11 -37
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugAttachment.js +4 -51
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/attachInstructionsAction.js +6 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/newPromptFileActions.d.ts +6 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/newPromptFileActions.js +24 -18
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptName.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptName.js +11 -11
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptSourceFolder.js +25 -25
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/promptFilePickers.js +48 -34
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatPasteProviders.d.ts +6 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatPasteProviders.js +234 -14
- package/vscode/src/vs/workbench/contrib/chat/common/chatDebugEvents.d.ts +58 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatDebugEvents.js +135 -0
- package/vscode/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.js +16 -16
- package/vscode/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.js +20 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codingame/monaco-vscode-xterm-addons-common",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "29.0.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "VSCode public API plugged on the monaco editor - common package depending on xterm addons",
|
|
6
6
|
"keywords": [],
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"type": "module",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@codingame/monaco-vscode-api": "
|
|
18
|
+
"@codingame/monaco-vscode-api": "29.0.0",
|
|
19
19
|
"@xterm/addon-clipboard": "0.3.0-beta.168",
|
|
20
20
|
"@xterm/addon-image": "0.10.0-beta.168",
|
|
21
21
|
"@xterm/addon-ligatures": "0.11.0-beta.168",
|
|
@@ -5,16 +5,18 @@ import { IWorkbenchContribution } from "@codingame/monaco-vscode-api/vscode/vs/w
|
|
|
5
5
|
import { IChatContextValueItem } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/browser/attachments/chatContextPickService";
|
|
6
6
|
import { IChatContextPickService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/browser/attachments/chatContextPickService.service";
|
|
7
7
|
import { IChatRequestVariableEntry } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/attachments/chatVariableEntries";
|
|
8
|
-
import { ILanguageModelToolsService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/tools/languageModelToolsService.service";
|
|
9
8
|
import { IChatWidget } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/browser/chat";
|
|
10
|
-
import { IChatWidgetService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/browser/chat.service";
|
|
11
|
-
import { IChatDebugService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/chatDebugService.service";
|
|
12
|
-
import { IContextKeyService } from "@codingame/monaco-vscode-api/vscode/vs/platform/contextkey/common/contextkey.service";
|
|
13
9
|
import { ITerminalService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/terminal/browser/terminal.service";
|
|
14
10
|
import { URI } from "@codingame/monaco-vscode-api/vscode/vs/base/common/uri";
|
|
11
|
+
/**
|
|
12
|
+
* Command ID that extensions can call to enable debug tools for the current
|
|
13
|
+
* chat session. Sets the context key and immediately flushes tool updates so
|
|
14
|
+
* that newly-enabled tools are visible on the next `vscode.lm.tools` read.
|
|
15
|
+
*/
|
|
16
|
+
export declare const EnableChatDebugToolsCommandId = "chat.enableDebugTools";
|
|
15
17
|
export declare class ChatContextContributions extends Disposable implements IWorkbenchContribution {
|
|
16
18
|
static readonly ID = "chat.contextContributions";
|
|
17
|
-
constructor(instantiationService: IInstantiationService, contextPickService: IChatContextPickService
|
|
19
|
+
constructor(instantiationService: IInstantiationService, contextPickService: IChatContextPickService);
|
|
18
20
|
}
|
|
19
21
|
export declare class TerminalContext implements IChatContextValueItem {
|
|
20
22
|
private readonly _resource;
|
|
@@ -17,15 +17,11 @@ import { NotebookEditorInput } from '@codingame/monaco-vscode-api/vscode/vs/work
|
|
|
17
17
|
import { IChatContextPickService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/browser/attachments/chatContextPickService.service';
|
|
18
18
|
import { toToolSetVariableEntry, toToolVariableEntry } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/attachments/chatVariableEntries';
|
|
19
19
|
import { isToolSet, ToolDataSource } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/tools/languageModelToolsService';
|
|
20
|
-
import { ILanguageModelToolsService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/tools/languageModelToolsService.service';
|
|
21
|
-
import { IChatWidgetService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/browser/chat.service';
|
|
22
20
|
import { isImage } from '../widget/input/editor/chatPasteProviders.js';
|
|
23
21
|
import { convertBufferToScreenshotVariable } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/browser/attachments/chatScreenshotContext';
|
|
24
22
|
import { ChatInstructionsPickerPick } from '../promptSyntax/attachInstructionsAction.js';
|
|
25
23
|
import { createDebugEventsAttachment } from '../chatDebug/chatDebugAttachment.js';
|
|
26
24
|
import { IChatDebugService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/chatDebugService.service';
|
|
27
|
-
import { ChatContextKeys } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/actions/chatContextKeys';
|
|
28
|
-
import { IContextKeyService } from '@codingame/monaco-vscode-api/vscode/vs/platform/contextkey/common/contextkey.service';
|
|
29
25
|
import { ITerminalService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/terminal/browser/terminal.service';
|
|
30
26
|
import { TerminalCapability } from '@codingame/monaco-vscode-api/vscode/vs/platform/terminal/common/capabilities/capabilities';
|
|
31
27
|
import { imageToHash } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/browser/chatImageUtils';
|
|
@@ -34,30 +30,8 @@ let ChatContextContributions = class ChatContextContributions extends Disposable
|
|
|
34
30
|
static {
|
|
35
31
|
this.ID = "chat.contextContributions";
|
|
36
32
|
}
|
|
37
|
-
constructor(
|
|
38
|
-
instantiationService,
|
|
39
|
-
contextPickService,
|
|
40
|
-
chatDebugService,
|
|
41
|
-
contextKeyService,
|
|
42
|
-
languageModelToolsService,
|
|
43
|
-
chatWidgetService
|
|
44
|
-
) {
|
|
33
|
+
constructor(instantiationService, contextPickService) {
|
|
45
34
|
super();
|
|
46
|
-
const hasAttachedDebugDataKey = ChatContextKeys.chatSessionHasAttachedDebugData.bindTo(contextKeyService);
|
|
47
|
-
this._store.add(chatWidgetService.onDidChangeFocusedSession(() => {
|
|
48
|
-
const sessionResource = chatWidgetService.lastFocusedWidget?.viewModel?.sessionResource;
|
|
49
|
-
hasAttachedDebugDataKey.set(
|
|
50
|
-
!!sessionResource && chatDebugService.hasAttachedDebugData(sessionResource)
|
|
51
|
-
);
|
|
52
|
-
languageModelToolsService.flushToolUpdates();
|
|
53
|
-
}));
|
|
54
|
-
this._store.add(chatDebugService.onDidAttachDebugData(sessionResource => {
|
|
55
|
-
const focusedSession = chatWidgetService.lastFocusedWidget?.viewModel?.sessionResource;
|
|
56
|
-
if (focusedSession && ( focusedSession.toString()) === ( sessionResource.toString())) {
|
|
57
|
-
hasAttachedDebugDataKey.set(true);
|
|
58
|
-
languageModelToolsService.flushToolUpdates();
|
|
59
|
-
}
|
|
60
|
-
}));
|
|
61
35
|
this._store.add(
|
|
62
36
|
contextPickService.registerChatContextItem(instantiationService.createInstance(ToolsContextPickerPick))
|
|
63
37
|
);
|
|
@@ -78,11 +52,11 @@ let ChatContextContributions = class ChatContextContributions extends Disposable
|
|
|
78
52
|
);
|
|
79
53
|
}
|
|
80
54
|
};
|
|
81
|
-
ChatContextContributions = ( __decorate([( __param(0, IInstantiationService)), ( __param(1, IChatContextPickService))
|
|
55
|
+
ChatContextContributions = ( __decorate([( __param(0, IInstantiationService)), ( __param(1, IChatContextPickService))], ChatContextContributions));
|
|
82
56
|
class ToolsContextPickerPick {
|
|
83
57
|
constructor() {
|
|
84
58
|
this.type = "pickerPick";
|
|
85
|
-
this.label = ( localize(
|
|
59
|
+
this.label = ( localize(4862, "Tools..."));
|
|
86
60
|
this.icon = Codicon.tools;
|
|
87
61
|
this.ordinal = -500;
|
|
88
62
|
}
|
|
@@ -133,7 +107,7 @@ class ToolsContextPickerPick {
|
|
|
133
107
|
picks.push(item);
|
|
134
108
|
}
|
|
135
109
|
return {
|
|
136
|
-
placeholder: ( localize(
|
|
110
|
+
placeholder: ( localize(4863, "Select a tool")),
|
|
137
111
|
picks: Promise.resolve(picks)
|
|
138
112
|
};
|
|
139
113
|
}
|
|
@@ -143,7 +117,7 @@ let OpenEditorContextValuePick = class OpenEditorContextValuePick {
|
|
|
143
117
|
this._editorService = _editorService;
|
|
144
118
|
this._labelService = _labelService;
|
|
145
119
|
this.type = "valuePick";
|
|
146
|
-
this.label = ( localize(
|
|
120
|
+
this.label = ( localize(4864, "Open Editors"));
|
|
147
121
|
this.icon = Codicon.file;
|
|
148
122
|
this.ordinal = 800;
|
|
149
123
|
}
|
|
@@ -179,7 +153,7 @@ let ClipboardImageContextValuePick = class ClipboardImageContextValuePick {
|
|
|
179
153
|
constructor(_clipboardService) {
|
|
180
154
|
this._clipboardService = _clipboardService;
|
|
181
155
|
this.type = "valuePick";
|
|
182
|
-
this.label = ( localize(
|
|
156
|
+
this.label = ( localize(4865, "Image from Clipboard"));
|
|
183
157
|
this.icon = Codicon.fileMedia;
|
|
184
158
|
}
|
|
185
159
|
async isEnabled(widget) {
|
|
@@ -196,8 +170,8 @@ let ClipboardImageContextValuePick = class ClipboardImageContextValuePick {
|
|
|
196
170
|
const fileBuffer = await this._clipboardService.readImage();
|
|
197
171
|
return {
|
|
198
172
|
id: await imageToHash(fileBuffer),
|
|
199
|
-
name: ( localize(
|
|
200
|
-
fullName: ( localize(
|
|
173
|
+
name: ( localize(4866, "Pasted Image")),
|
|
174
|
+
fullName: ( localize(4866, "Pasted Image")),
|
|
201
175
|
value: fileBuffer,
|
|
202
176
|
kind: "image"
|
|
203
177
|
};
|
|
@@ -210,7 +184,7 @@ let TerminalContext = class TerminalContext {
|
|
|
210
184
|
this._terminalService = _terminalService;
|
|
211
185
|
this.type = "valuePick";
|
|
212
186
|
this.icon = Codicon.terminal;
|
|
213
|
-
this.label = ( localize(
|
|
187
|
+
this.label = ( localize(4867, "Terminal"));
|
|
214
188
|
}
|
|
215
189
|
isEnabled(widget) {
|
|
216
190
|
const terminal = this._terminalService.getInstanceFromResource(this._resource);
|
|
@@ -275,7 +249,7 @@ let ScreenshotContextValuePick = class ScreenshotContextValuePick {
|
|
|
275
249
|
this._hostService = _hostService;
|
|
276
250
|
this.type = "valuePick";
|
|
277
251
|
this.icon = Codicon.deviceCamera;
|
|
278
|
-
this.label = (isElectron ? ( localize(
|
|
252
|
+
this.label = (isElectron ? ( localize(4868, "Screenshot Window")) : ( localize(4869, "Screenshot")));
|
|
279
253
|
}
|
|
280
254
|
async isEnabled(widget) {
|
|
281
255
|
return !!widget.attachmentCapabilities.supportsImageAttachments && !!widget.input.selectedLanguageModel.get()?.metadata.capabilities?.vision;
|
|
@@ -291,7 +265,7 @@ let DebugEventsSnapshotContextValuePick = class DebugEventsSnapshotContextValueP
|
|
|
291
265
|
this._chatDebugService = _chatDebugService;
|
|
292
266
|
this.type = "valuePick";
|
|
293
267
|
this.icon = Codicon.output;
|
|
294
|
-
this.label = ( localize(
|
|
268
|
+
this.label = ( localize(4870, "Debug Events Snapshot"));
|
|
295
269
|
this.ordinal = -600;
|
|
296
270
|
}
|
|
297
271
|
isEnabled(widget) {
|
|
@@ -1,71 +1,24 @@
|
|
|
1
1
|
|
|
2
2
|
import { Codicon } from '@codingame/monaco-vscode-api/vscode/vs/base/common/codicons';
|
|
3
3
|
import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
|
|
4
|
+
import { formatDebugEventsForContext, getDebugEventsModelDescription } from '../../common/chatDebugEvents.js';
|
|
4
5
|
|
|
5
|
-
const debugEventKindDescriptions = {
|
|
6
|
-
generic: "- generic (category: \"discovery\"): File discovery for instructions, skills, agents, hooks. Resolving returns a fileList with full file paths, load status, skip reasons, and source folders. Always resolve these for questions about customization files.\n" + "- generic (other): Miscellaneous logs. Resolving returns additional text details.",
|
|
7
|
-
toolCall: "- toolCall: A tool invocation. Resolving returns tool name, input, output, status, and duration.",
|
|
8
|
-
modelTurn: "- modelTurn: An LLM round-trip. Resolving returns model name, token usage, timing, errors, and prompt sections.",
|
|
9
|
-
subagentInvocation: "- subagentInvocation: A sub-agent spawn. Resolving returns agent name, status, duration, and counts.",
|
|
10
|
-
userMessage: "- userMessage: The full prompt sent to the model. Resolving returns the complete message and all prompt sections (system prompt, instructions, context). Essential for understanding what the model received.",
|
|
11
|
-
agentResponse: "- agentResponse: The model's response. Resolving returns the full response text and sections."
|
|
12
|
-
};
|
|
13
|
-
function formatDebugEventsForContext(events) {
|
|
14
|
-
const lines = [];
|
|
15
|
-
for (const event of events) {
|
|
16
|
-
const ts = event.created.toISOString();
|
|
17
|
-
const id = event.id ? ` [id=${event.id}]` : "";
|
|
18
|
-
switch (event.kind) {
|
|
19
|
-
case "generic":
|
|
20
|
-
lines.push(
|
|
21
|
-
`[${ts}]${id} ${event.level >= 3 ? "ERROR" : event.level >= 2 ? "WARN" : "INFO"}: ${event.name}${event.details ? " - " + event.details : ""}${event.category ? " (category: " + event.category + ")" : ""}`
|
|
22
|
-
);
|
|
23
|
-
break;
|
|
24
|
-
case "toolCall":
|
|
25
|
-
lines.push(
|
|
26
|
-
`[${ts}]${id} TOOL_CALL: ${event.toolName}${event.result ? " result=" + event.result : ""}${event.durationInMillis !== undefined ? " duration=" + event.durationInMillis + "ms" : ""}`
|
|
27
|
-
);
|
|
28
|
-
break;
|
|
29
|
-
case "modelTurn":
|
|
30
|
-
lines.push(
|
|
31
|
-
`[${ts}]${id} MODEL_TURN: ${event.requestName ?? "unknown"}${event.model ? " model=" + event.model : ""}${event.inputTokens !== undefined ? " tokens(in=" + event.inputTokens + ",out=" + (event.outputTokens ?? "?") + ")" : ""}${event.durationInMillis !== undefined ? " duration=" + event.durationInMillis + "ms" : ""}`
|
|
32
|
-
);
|
|
33
|
-
break;
|
|
34
|
-
case "subagentInvocation":
|
|
35
|
-
lines.push(
|
|
36
|
-
`[${ts}]${id} SUBAGENT: ${event.agentName}${event.status ? " status=" + event.status : ""}${event.durationInMillis !== undefined ? " duration=" + event.durationInMillis + "ms" : ""}`
|
|
37
|
-
);
|
|
38
|
-
break;
|
|
39
|
-
case "userMessage":
|
|
40
|
-
lines.push(
|
|
41
|
-
`[${ts}]${id} USER_MESSAGE: ${event.message.substring(0, 200)}${event.message.length > 200 ? "..." : ""} (${event.sections.length} sections)`
|
|
42
|
-
);
|
|
43
|
-
break;
|
|
44
|
-
case "agentResponse":
|
|
45
|
-
lines.push(
|
|
46
|
-
`[${ts}]${id} AGENT_RESPONSE: ${event.message.substring(0, 200)}${event.message.length > 200 ? "..." : ""} (${event.sections.length} sections)`
|
|
47
|
-
);
|
|
48
|
-
break;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return lines.join("\n");
|
|
52
|
-
}
|
|
53
6
|
async function createDebugEventsAttachment(sessionResource, chatDebugService) {
|
|
54
7
|
chatDebugService.markDebugDataAttached(sessionResource);
|
|
55
8
|
if (!chatDebugService.hasInvokedProviders(sessionResource)) {
|
|
56
9
|
await chatDebugService.invokeProviders(sessionResource);
|
|
57
10
|
}
|
|
58
11
|
const events = chatDebugService.getEvents(sessionResource);
|
|
59
|
-
const summary = events.length > 0 ? formatDebugEventsForContext(events) : ( localize(
|
|
12
|
+
const summary = events.length > 0 ? formatDebugEventsForContext(events) : ( localize(5743, "No debug events found for this conversation."));
|
|
60
13
|
return {
|
|
61
14
|
id: "chatDebugEvents",
|
|
62
|
-
name: ( localize(
|
|
15
|
+
name: ( localize(5744, "Debug Events Snapshot")),
|
|
63
16
|
icon: Codicon.output,
|
|
64
17
|
kind: "debugEvents",
|
|
65
18
|
snapshotTime: Date.now(),
|
|
66
19
|
sessionResource,
|
|
67
20
|
value: summary,
|
|
68
|
-
modelDescription:
|
|
21
|
+
modelDescription: getDebugEventsModelDescription()
|
|
69
22
|
};
|
|
70
23
|
}
|
|
71
24
|
|
package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/attachInstructionsAction.js
CHANGED
|
@@ -23,8 +23,8 @@ class ManageInstructionsFilesAction extends Action2 {
|
|
|
23
23
|
constructor() {
|
|
24
24
|
super({
|
|
25
25
|
id: CONFIGURE_INSTRUCTIONS_ACTION_ID,
|
|
26
|
-
title: ( localize2(
|
|
27
|
-
shortTitle: ( localize2(
|
|
26
|
+
title: ( localize2(6420, "Configure Instructions & Rules...")),
|
|
27
|
+
shortTitle: ( localize2(6421, "Instructions & Rules")),
|
|
28
28
|
icon: Codicon.bookmark,
|
|
29
29
|
f1: true,
|
|
30
30
|
precondition: ChatContextKeys.enabled,
|
|
@@ -41,7 +41,7 @@ class ManageInstructionsFilesAction extends Action2 {
|
|
|
41
41
|
const openerService = accessor.get(IOpenerService);
|
|
42
42
|
const instaService = accessor.get(IInstantiationService);
|
|
43
43
|
const pickers = instaService.createInstance(PromptFilePickers);
|
|
44
|
-
const placeholder = ( localize(
|
|
44
|
+
const placeholder = ( localize(6422, "Select the instructions file to open"));
|
|
45
45
|
const result = await pickers.selectPromptFile({
|
|
46
46
|
placeholder,
|
|
47
47
|
type: PromptsType.instructions,
|
|
@@ -59,7 +59,7 @@ let ChatInstructionsPickerPick = class ChatInstructionsPickerPick {
|
|
|
59
59
|
constructor(promptsService) {
|
|
60
60
|
this.promptsService = promptsService;
|
|
61
61
|
this.type = "pickerPick";
|
|
62
|
-
this.label = ( localize(
|
|
62
|
+
this.label = ( localize(6423, "Instructions..."));
|
|
63
63
|
this.icon = Codicon.bookmark;
|
|
64
64
|
this.commandId = ATTACH_INSTRUCTIONS_ACTION_ID;
|
|
65
65
|
}
|
|
@@ -89,10 +89,10 @@ let ChatInstructionsPickerPick = class ChatInstructionsPickerPick {
|
|
|
89
89
|
return result;
|
|
90
90
|
});
|
|
91
91
|
return {
|
|
92
|
-
placeholder: ( localize(
|
|
92
|
+
placeholder: ( localize(6424, "Select instructions files to attach")),
|
|
93
93
|
picks,
|
|
94
94
|
configure: {
|
|
95
|
-
label: ( localize(
|
|
95
|
+
label: ( localize(6425, "Configure Instructions...")),
|
|
96
96
|
commandId: CONFIGURE_INSTRUCTIONS_ACTION_ID
|
|
97
97
|
}
|
|
98
98
|
};
|
|
@@ -10,6 +10,12 @@ export interface INewPromptOptions {
|
|
|
10
10
|
readonly targetFolder?: URI;
|
|
11
11
|
readonly targetStorage?: PromptsStorage;
|
|
12
12
|
readonly openFile?: (uri: URI) => Promise<ICodeEditor | undefined>;
|
|
13
|
+
/**
|
|
14
|
+
* Override the file extension (e.g. `.md` for Claude rules instead of
|
|
15
|
+
* `.instructions.md`). When set, the name picker uses this extension
|
|
16
|
+
* instead of the default for the prompt type.
|
|
17
|
+
*/
|
|
18
|
+
readonly fileExtension?: string;
|
|
13
19
|
}
|
|
14
20
|
export declare const NEW_PROMPT_COMMAND_ID = "workbench.command.new.prompt";
|
|
15
21
|
export declare const NEW_INSTRUCTIONS_COMMAND_ID = "workbench.command.new.instructions";
|
|
@@ -23,7 +23,7 @@ import { CHAT_CATEGORY } from '@codingame/monaco-vscode-api/vscode/vs/workbench/
|
|
|
23
23
|
import { askForPromptFileName } from './pickers/askForPromptName.js';
|
|
24
24
|
import { askForPromptSourceFolder } from './pickers/askForPromptSourceFolder.js';
|
|
25
25
|
import { IQuickInputService } from '@codingame/monaco-vscode-api/vscode/vs/platform/quickinput/common/quickInput.service';
|
|
26
|
-
import { getCleanPromptName, SKILL_FILENAME } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/promptSyntax/config/promptFileLocations';
|
|
26
|
+
import { getCleanPromptName, VALID_SKILL_NAME_REGEX, SKILL_FILENAME } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/promptSyntax/config/promptFileLocations';
|
|
27
27
|
import { PromptsStorage } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/promptSyntax/service/promptsService';
|
|
28
28
|
import { getTarget } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/promptSyntax/languageProviders/promptFileAttributes';
|
|
29
29
|
import Severity from '@codingame/monaco-vscode-api/vscode/vs/base/common/severity';
|
|
@@ -68,7 +68,13 @@ class AbstractNewPromptFileAction extends Action2 {
|
|
|
68
68
|
folderUri = selectedFolder.uri;
|
|
69
69
|
storage = selectedFolder.storage;
|
|
70
70
|
}
|
|
71
|
-
const fileName = await instaService.invokeFunction(
|
|
71
|
+
const fileName = await instaService.invokeFunction(
|
|
72
|
+
askForPromptFileName,
|
|
73
|
+
this.type,
|
|
74
|
+
folderUri,
|
|
75
|
+
undefined,
|
|
76
|
+
options?.fileExtension
|
|
77
|
+
);
|
|
72
78
|
if (!fileName) {
|
|
73
79
|
return;
|
|
74
80
|
}
|
|
@@ -98,17 +104,17 @@ class AbstractNewPromptFileAction extends Action2 {
|
|
|
98
104
|
return;
|
|
99
105
|
}
|
|
100
106
|
notificationService.prompt(Severity.Info, ( localize(
|
|
101
|
-
|
|
107
|
+
6457,
|
|
102
108
|
"Do you want to backup and sync your user prompt, instruction and custom agent files with Setting Sync?'"
|
|
103
109
|
)), [{
|
|
104
|
-
label: ( localize(
|
|
110
|
+
label: ( localize(6458, "Enable")),
|
|
105
111
|
run: () => {
|
|
106
112
|
commandService.executeCommand(CONFIGURE_SYNC_COMMAND_ID).catch(error => {
|
|
107
113
|
logService.error(`Failed to run '${CONFIGURE_SYNC_COMMAND_ID}' command: ${error}.`);
|
|
108
114
|
});
|
|
109
115
|
}
|
|
110
116
|
}, {
|
|
111
|
-
label: ( localize(
|
|
117
|
+
label: ( localize(6459, "Learn More")),
|
|
112
118
|
run: () => {
|
|
113
119
|
openerService.open(( URI.parse("https://aka.ms/vscode-settings-sync-help")));
|
|
114
120
|
}
|
|
@@ -206,24 +212,24 @@ const NEW_AGENT_COMMAND_ID = "workbench.command.new.agent";
|
|
|
206
212
|
const NEW_SKILL_COMMAND_ID = "workbench.command.new.skill";
|
|
207
213
|
class NewPromptFileAction extends AbstractNewPromptFileAction {
|
|
208
214
|
constructor() {
|
|
209
|
-
super(NEW_PROMPT_COMMAND_ID, ( localize(
|
|
215
|
+
super(NEW_PROMPT_COMMAND_ID, ( localize(6460, "New Prompt File...")), PromptsType.prompt);
|
|
210
216
|
}
|
|
211
217
|
}
|
|
212
218
|
class NewInstructionsFileAction extends AbstractNewPromptFileAction {
|
|
213
219
|
constructor() {
|
|
214
|
-
super(NEW_INSTRUCTIONS_COMMAND_ID, ( localize(
|
|
220
|
+
super(NEW_INSTRUCTIONS_COMMAND_ID, ( localize(6461, "New Instructions File...")), PromptsType.instructions);
|
|
215
221
|
}
|
|
216
222
|
}
|
|
217
223
|
class NewAgentFileAction extends AbstractNewPromptFileAction {
|
|
218
224
|
constructor() {
|
|
219
|
-
super(NEW_AGENT_COMMAND_ID, ( localize(
|
|
225
|
+
super(NEW_AGENT_COMMAND_ID, ( localize(6462, "New Custom Agent...")), PromptsType.agent);
|
|
220
226
|
}
|
|
221
227
|
}
|
|
222
228
|
class NewSkillFileAction extends Action2 {
|
|
223
229
|
constructor() {
|
|
224
230
|
super({
|
|
225
231
|
id: NEW_SKILL_COMMAND_ID,
|
|
226
|
-
title: ( localize(
|
|
232
|
+
title: ( localize(6463, "New Skill File...")),
|
|
227
233
|
f1: false,
|
|
228
234
|
precondition: ChatContextKeys.enabled,
|
|
229
235
|
category: CHAT_CATEGORY,
|
|
@@ -254,29 +260,29 @@ class NewSkillFileAction extends Action2 {
|
|
|
254
260
|
}
|
|
255
261
|
const skillName = await quickInputService.input({
|
|
256
262
|
prompt: ( localize(
|
|
257
|
-
|
|
263
|
+
6464,
|
|
258
264
|
"Enter a name for the skill (lowercase letters, numbers, and hyphens only)"
|
|
259
265
|
)),
|
|
260
|
-
placeHolder: ( localize(
|
|
266
|
+
placeHolder: ( localize(6465, "e.g., pdf-processing, data-analysis")),
|
|
261
267
|
validateInput: async value => {
|
|
262
268
|
if (!value || !value.trim()) {
|
|
263
|
-
return localize(
|
|
269
|
+
return localize(6466, "Skill name is required");
|
|
264
270
|
}
|
|
265
271
|
const name = value.trim();
|
|
266
272
|
if (name.length > 64) {
|
|
267
|
-
return localize(
|
|
273
|
+
return localize(6467, "Skill name must be 64 characters or less");
|
|
268
274
|
}
|
|
269
|
-
if (
|
|
275
|
+
if (!VALID_SKILL_NAME_REGEX.test(name)) {
|
|
270
276
|
return localize(
|
|
271
|
-
|
|
277
|
+
6468,
|
|
272
278
|
"Skill name may only contain lowercase letters, numbers, and hyphens"
|
|
273
279
|
);
|
|
274
280
|
}
|
|
275
281
|
if (name.startsWith("-") || name.endsWith("-")) {
|
|
276
|
-
return localize(
|
|
282
|
+
return localize(6469, "Skill name must not start or end with a hyphen");
|
|
277
283
|
}
|
|
278
284
|
if (name.includes("--")) {
|
|
279
|
-
return localize(
|
|
285
|
+
return localize(6470, "Skill name must not contain consecutive hyphens");
|
|
280
286
|
}
|
|
281
287
|
return undefined;
|
|
282
288
|
}
|
|
@@ -308,7 +314,7 @@ class NewUntitledPromptFileAction extends Action2 {
|
|
|
308
314
|
constructor() {
|
|
309
315
|
super({
|
|
310
316
|
id: "workbench.command.new.untitled.prompt",
|
|
311
|
-
title: ( localize2(
|
|
317
|
+
title: ( localize2(6471, "New Untitled Prompt File")),
|
|
312
318
|
f1: true,
|
|
313
319
|
precondition: ChatContextKeys.enabled,
|
|
314
320
|
category: CHAT_CATEGORY,
|
package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptName.d.ts
CHANGED
|
@@ -4,4 +4,4 @@ import { ServicesAccessor } from "@codingame/monaco-vscode-api/vscode/vs/editor/
|
|
|
4
4
|
/**
|
|
5
5
|
* Asks the user for a file name.
|
|
6
6
|
*/
|
|
7
|
-
export declare function askForPromptFileName(accessor: ServicesAccessor, type: PromptsType, selectedFolder: URI, existingFileName?: string): Promise<string | undefined>;
|
|
7
|
+
export declare function askForPromptFileName(accessor: ServicesAccessor, type: PromptsType, selectedFolder: URI, existingFileName?: string, fileExtensionOverride?: string): Promise<string | undefined>;
|
package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptName.js
CHANGED
|
@@ -8,7 +8,7 @@ import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/fi
|
|
|
8
8
|
import Severity from '@codingame/monaco-vscode-api/vscode/vs/base/common/severity';
|
|
9
9
|
import { isValidBasename } from '@codingame/monaco-vscode-api/vscode/vs/base/common/extpath';
|
|
10
10
|
|
|
11
|
-
async function askForPromptFileName(accessor, type, selectedFolder, existingFileName) {
|
|
11
|
+
async function askForPromptFileName(accessor, type, selectedFolder, existingFileName, fileExtensionOverride) {
|
|
12
12
|
const quickInputService = accessor.get(IQuickInputService);
|
|
13
13
|
const fileService = accessor.get(IFileService);
|
|
14
14
|
const sanitizeInput = input => {
|
|
@@ -16,27 +16,27 @@ async function askForPromptFileName(accessor, type, selectedFolder, existingFile
|
|
|
16
16
|
if (!trimmedName) {
|
|
17
17
|
return undefined;
|
|
18
18
|
}
|
|
19
|
-
const fileExtension = getPromptFileExtension(type);
|
|
19
|
+
const fileExtension = fileExtensionOverride ?? getPromptFileExtension(type);
|
|
20
20
|
return (trimmedName.endsWith(fileExtension)) ? trimmedName : `${trimmedName}${fileExtension}`;
|
|
21
21
|
};
|
|
22
22
|
const validateInput = async value => {
|
|
23
23
|
const fileName = sanitizeInput(value);
|
|
24
24
|
if (!fileName) {
|
|
25
25
|
return {
|
|
26
|
-
content: ( localize(
|
|
26
|
+
content: ( localize(6472, "Please enter a name.")),
|
|
27
27
|
severity: Severity.Warning
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
if (!isValidBasename(fileName)) {
|
|
31
31
|
return {
|
|
32
|
-
content: ( localize(
|
|
32
|
+
content: ( localize(6473, "The name contains invalid characters.")),
|
|
33
33
|
severity: Severity.Error
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
const fileUri = URI.joinPath(selectedFolder, fileName);
|
|
37
37
|
if (await fileService.exists(fileUri)) {
|
|
38
38
|
return {
|
|
39
|
-
content: ( localize(
|
|
39
|
+
content: ( localize(6474, "A file for the given name already exists.")),
|
|
40
40
|
severity: Severity.Error
|
|
41
41
|
};
|
|
42
42
|
}
|
|
@@ -56,11 +56,11 @@ async function askForPromptFileName(accessor, type, selectedFolder, existingFile
|
|
|
56
56
|
function getPlaceholderStringForNew(type) {
|
|
57
57
|
switch (type) {
|
|
58
58
|
case PromptsType.instructions:
|
|
59
|
-
return localize(
|
|
59
|
+
return localize(6475, "Enter the name of the instructions file");
|
|
60
60
|
case PromptsType.prompt:
|
|
61
|
-
return localize(
|
|
61
|
+
return localize(6476, "Enter the name of the prompt file");
|
|
62
62
|
case PromptsType.agent:
|
|
63
|
-
return localize(
|
|
63
|
+
return localize(6477, "Enter the name of the agent file");
|
|
64
64
|
default:
|
|
65
65
|
throw ( new Error("Unknown prompt type"));
|
|
66
66
|
}
|
|
@@ -68,11 +68,11 @@ function getPlaceholderStringForNew(type) {
|
|
|
68
68
|
function getPlaceholderStringForRename(type) {
|
|
69
69
|
switch (type) {
|
|
70
70
|
case PromptsType.instructions:
|
|
71
|
-
return localize(
|
|
71
|
+
return localize(6478, "Enter a new name of the instructions file");
|
|
72
72
|
case PromptsType.prompt:
|
|
73
|
-
return localize(
|
|
73
|
+
return localize(6479, "Enter a new name of the prompt file");
|
|
74
74
|
case PromptsType.agent:
|
|
75
|
-
return localize(
|
|
75
|
+
return localize(6480, "Enter a new name of the agent file");
|
|
76
76
|
default:
|
|
77
77
|
throw ( new Error("Unknown prompt type"));
|
|
78
78
|
}
|
|
@@ -27,7 +27,7 @@ async function askForPromptSourceFolder(accessor, type, existingFolder, isMove =
|
|
|
27
27
|
};
|
|
28
28
|
const foldersList = ( folders.map(folder => {
|
|
29
29
|
const uri = folder.uri;
|
|
30
|
-
const detail = (existingFolder && isEqual(uri, existingFolder)) ? ( localize(
|
|
30
|
+
const detail = (existingFolder && isEqual(uri, existingFolder)) ? ( localize(6481, "Current Location")) : undefined;
|
|
31
31
|
if (folder.storage !== PromptsStorage.local) {
|
|
32
32
|
return {
|
|
33
33
|
type: "item",
|
|
@@ -55,7 +55,7 @@ async function askForPromptSourceFolder(accessor, type, existingFolder, isMove =
|
|
|
55
55
|
}
|
|
56
56
|
return {
|
|
57
57
|
type: "item",
|
|
58
|
-
label: ( localize(
|
|
58
|
+
label: ( localize(6482, "Current Workspace")),
|
|
59
59
|
detail,
|
|
60
60
|
tooltip: labelService.getUriLabel(uri),
|
|
61
61
|
folder
|
|
@@ -70,15 +70,15 @@ async function askForPromptSourceFolder(accessor, type, existingFolder, isMove =
|
|
|
70
70
|
function getPlaceholderStringforNew(type) {
|
|
71
71
|
switch (type) {
|
|
72
72
|
case PromptsType.instructions:
|
|
73
|
-
return localize(
|
|
73
|
+
return localize(6483, "Select a location to create the instructions file");
|
|
74
74
|
case PromptsType.prompt:
|
|
75
|
-
return localize(
|
|
75
|
+
return localize(6484, "Select a location to create the prompt file");
|
|
76
76
|
case PromptsType.agent:
|
|
77
|
-
return localize(
|
|
77
|
+
return localize(6485, "Select a location to create the agent file");
|
|
78
78
|
case PromptsType.skill:
|
|
79
|
-
return localize(
|
|
79
|
+
return localize(6486, "Select a location to create the skill");
|
|
80
80
|
case PromptsType.hook:
|
|
81
|
-
return localize(
|
|
81
|
+
return localize(6487, "Select a location to create the hook file");
|
|
82
82
|
default:
|
|
83
83
|
throw ( new Error("Unknown prompt type"));
|
|
84
84
|
}
|
|
@@ -87,13 +87,13 @@ function getPlaceholderStringforMove(type, isMove) {
|
|
|
87
87
|
if (isMove) {
|
|
88
88
|
switch (type) {
|
|
89
89
|
case PromptsType.instructions:
|
|
90
|
-
return localize(
|
|
90
|
+
return localize(6488, "Select a location to move the instructions file to");
|
|
91
91
|
case PromptsType.prompt:
|
|
92
|
-
return localize(
|
|
92
|
+
return localize(6489, "Select a location to move the prompt file to");
|
|
93
93
|
case PromptsType.agent:
|
|
94
|
-
return localize(
|
|
94
|
+
return localize(6490, "Select a location to move the agent file to");
|
|
95
95
|
case PromptsType.skill:
|
|
96
|
-
return localize(
|
|
96
|
+
return localize(6491, "Select a location to move the skill to");
|
|
97
97
|
case PromptsType.hook:
|
|
98
98
|
throw ( new Error("Hooks cannot be moved"));
|
|
99
99
|
default:
|
|
@@ -102,13 +102,13 @@ function getPlaceholderStringforMove(type, isMove) {
|
|
|
102
102
|
}
|
|
103
103
|
switch (type) {
|
|
104
104
|
case PromptsType.instructions:
|
|
105
|
-
return localize(
|
|
105
|
+
return localize(6492, "Select a location to copy the instructions file to");
|
|
106
106
|
case PromptsType.prompt:
|
|
107
|
-
return localize(
|
|
107
|
+
return localize(6493, "Select a location to copy the prompt file to");
|
|
108
108
|
case PromptsType.agent:
|
|
109
|
-
return localize(
|
|
109
|
+
return localize(6494, "Select a location to copy the agent file to");
|
|
110
110
|
case PromptsType.skill:
|
|
111
|
-
return localize(
|
|
111
|
+
return localize(6495, "Select a location to copy the skill to");
|
|
112
112
|
case PromptsType.hook:
|
|
113
113
|
throw ( new Error("Hooks cannot be copied"));
|
|
114
114
|
default:
|
|
@@ -136,15 +136,15 @@ async function showNoFoldersDialog(accessor, type) {
|
|
|
136
136
|
function getLearnLabel(type) {
|
|
137
137
|
switch (type) {
|
|
138
138
|
case PromptsType.prompt:
|
|
139
|
-
return localize(
|
|
139
|
+
return localize(6496, "Learn how to configure reusable prompts");
|
|
140
140
|
case PromptsType.instructions:
|
|
141
|
-
return localize(
|
|
141
|
+
return localize(6497, "Learn how to configure reusable instructions");
|
|
142
142
|
case PromptsType.agent:
|
|
143
|
-
return localize(
|
|
143
|
+
return localize(6498, "Learn how to configure custom agents");
|
|
144
144
|
case PromptsType.skill:
|
|
145
|
-
return localize(
|
|
145
|
+
return localize(6499, "Learn how to configure skills");
|
|
146
146
|
case PromptsType.hook:
|
|
147
|
-
return localize(
|
|
147
|
+
return localize(6500, "Learn how to configure hooks");
|
|
148
148
|
default:
|
|
149
149
|
throw ( new Error("Unknown prompt type"));
|
|
150
150
|
}
|
|
@@ -152,15 +152,15 @@ function getLearnLabel(type) {
|
|
|
152
152
|
function getMissingSourceFolderString(type) {
|
|
153
153
|
switch (type) {
|
|
154
154
|
case PromptsType.instructions:
|
|
155
|
-
return localize(
|
|
155
|
+
return localize(6501, "No instruction source folders found.");
|
|
156
156
|
case PromptsType.prompt:
|
|
157
|
-
return localize(
|
|
157
|
+
return localize(6502, "No prompt source folders found.");
|
|
158
158
|
case PromptsType.agent:
|
|
159
|
-
return localize(
|
|
159
|
+
return localize(6503, "No agent source folders found.");
|
|
160
160
|
case PromptsType.skill:
|
|
161
|
-
return localize(
|
|
161
|
+
return localize(6504, "No skill source folders found.");
|
|
162
162
|
case PromptsType.hook:
|
|
163
|
-
return localize(
|
|
163
|
+
return localize(6505, "No hook source folders found.");
|
|
164
164
|
default:
|
|
165
165
|
throw ( new Error("Unknown prompt type"));
|
|
166
166
|
}
|