@codingame/monaco-vscode-xterm-addons-common 25.1.2 → 26.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 +10 -10
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatContext.js +58 -114
- package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatDynamicVariables.d.ts +42 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatDynamicVariables.js +209 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/attachInstructionsAction.js +18 -16
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/newPromptFileActions.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/newPromptFileActions.js +151 -70
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptName.js +27 -25
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptSourceFolder.js +67 -53
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/promptFilePickers.d.ts +4 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/promptFilePickers.js +188 -116
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatPasteProviders.js +106 -71
- package/vscode/src/vs/workbench/contrib/terminal/browser/terminalUri.js +6 -3
- package/vscode/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.js +204 -140
- package/vscode/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.js +77 -82
- package/vscode/src/vs/workbench/contrib/terminal/browser/xterm/xtermAddonImporter.js +24 -24
- package/vscode/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.d.ts +4 -1
- package/vscode/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.js +262 -162
package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/attachInstructionsAction.js
CHANGED
|
@@ -17,23 +17,23 @@ import { toPromptFileVariableEntry, PromptFileVariableKind } from '@codingame/mo
|
|
|
17
17
|
import { CancellationToken } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation';
|
|
18
18
|
import { IOpenerService } from '@codingame/monaco-vscode-api/vscode/vs/platform/opener/common/opener.service';
|
|
19
19
|
|
|
20
|
-
const ATTACH_INSTRUCTIONS_ACTION_ID =
|
|
21
|
-
const CONFIGURE_INSTRUCTIONS_ACTION_ID =
|
|
20
|
+
const ATTACH_INSTRUCTIONS_ACTION_ID = "workbench.action.chat.attach.instructions";
|
|
21
|
+
const CONFIGURE_INSTRUCTIONS_ACTION_ID = "workbench.action.chat.configure.instructions";
|
|
22
22
|
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(5651, "Configure Instructions...")),
|
|
27
|
+
shortTitle: ( localize2(5652, "Chat Instructions")),
|
|
28
28
|
icon: Codicon.bookmark,
|
|
29
29
|
f1: true,
|
|
30
30
|
precondition: ChatContextKeys.enabled,
|
|
31
31
|
category: CHAT_CATEGORY,
|
|
32
32
|
menu: {
|
|
33
33
|
id: CHAT_CONFIG_MENU_ID,
|
|
34
|
-
when: ( ContextKeyExpr.and(ChatContextKeys.enabled, ( ContextKeyExpr.equals(
|
|
34
|
+
when: ( ContextKeyExpr.and(ChatContextKeys.enabled, ( ContextKeyExpr.equals("view", ChatViewId)))),
|
|
35
35
|
order: 10,
|
|
36
|
-
group:
|
|
36
|
+
group: "1_level"
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
39
|
}
|
|
@@ -41,8 +41,12 @@ 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(
|
|
45
|
-
const result = await pickers.selectPromptFile({
|
|
44
|
+
const placeholder = ( localize(5653, "Select the instructions file to open"));
|
|
45
|
+
const result = await pickers.selectPromptFile({
|
|
46
|
+
placeholder,
|
|
47
|
+
type: PromptsType.instructions,
|
|
48
|
+
optionEdit: false
|
|
49
|
+
});
|
|
46
50
|
if (result !== undefined) {
|
|
47
51
|
await openerService.open(result.promptFile);
|
|
48
52
|
}
|
|
@@ -54,8 +58,8 @@ function registerAttachPromptActions() {
|
|
|
54
58
|
let ChatInstructionsPickerPick = class ChatInstructionsPickerPick {
|
|
55
59
|
constructor(promptsService) {
|
|
56
60
|
this.promptsService = promptsService;
|
|
57
|
-
this.type =
|
|
58
|
-
this.label = ( localize(
|
|
61
|
+
this.type = "pickerPick";
|
|
62
|
+
this.label = ( localize(5654, "Instructions..."));
|
|
59
63
|
this.icon = Codicon.bookmark;
|
|
60
64
|
this.commandId = ATTACH_INSTRUCTIONS_ACTION_ID;
|
|
61
65
|
}
|
|
@@ -71,7 +75,7 @@ let ChatInstructionsPickerPick = class ChatInstructionsPickerPick {
|
|
|
71
75
|
if (storageType !== promptsPath.storage) {
|
|
72
76
|
storageType = promptsPath.storage;
|
|
73
77
|
result.push({
|
|
74
|
-
type:
|
|
78
|
+
type: "separator",
|
|
75
79
|
label: this.promptsService.getPromptLocationLabel(promptsPath)
|
|
76
80
|
});
|
|
77
81
|
}
|
|
@@ -85,17 +89,15 @@ let ChatInstructionsPickerPick = class ChatInstructionsPickerPick {
|
|
|
85
89
|
return result;
|
|
86
90
|
});
|
|
87
91
|
return {
|
|
88
|
-
placeholder: ( localize(
|
|
92
|
+
placeholder: ( localize(5655, "Select instructions files to attach")),
|
|
89
93
|
picks,
|
|
90
94
|
configure: {
|
|
91
|
-
label: ( localize(
|
|
95
|
+
label: ( localize(5656, "Configure Instructions...")),
|
|
92
96
|
commandId: CONFIGURE_INSTRUCTIONS_ACTION_ID
|
|
93
97
|
}
|
|
94
98
|
};
|
|
95
99
|
}
|
|
96
100
|
};
|
|
97
|
-
ChatInstructionsPickerPick = ( __decorate([
|
|
98
|
-
( __param(0, IPromptsService))
|
|
99
|
-
], ChatInstructionsPickerPick));
|
|
101
|
+
ChatInstructionsPickerPick = ( __decorate([( __param(0, IPromptsService))], ChatInstructionsPickerPick));
|
|
100
102
|
|
|
101
103
|
export { ChatInstructionsPickerPick, registerAttachPromptActions };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const NEW_PROMPT_COMMAND_ID = "workbench.command.new.prompt";
|
|
2
2
|
export declare const NEW_INSTRUCTIONS_COMMAND_ID = "workbench.command.new.instructions";
|
|
3
3
|
export declare const NEW_AGENT_COMMAND_ID = "workbench.command.new.agent";
|
|
4
|
+
export declare const NEW_SKILL_COMMAND_ID = "workbench.command.new.skill";
|
|
4
5
|
export declare function registerNewPromptFileActions(): void;
|
|
@@ -22,7 +22,8 @@ import { ChatContextKeys } from '@codingame/monaco-vscode-api/vscode/vs/workbenc
|
|
|
22
22
|
import { CHAT_CATEGORY } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/browser/actions/chatActions';
|
|
23
23
|
import { askForPromptFileName } from './pickers/askForPromptName.js';
|
|
24
24
|
import { askForPromptSourceFolder } from './pickers/askForPromptSourceFolder.js';
|
|
25
|
-
import {
|
|
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
27
|
import Severity from '@codingame/monaco-vscode-api/vscode/vs/base/common/severity';
|
|
27
28
|
|
|
28
29
|
class AbstractNewPromptFileAction extends Action2 {
|
|
@@ -52,7 +53,6 @@ class AbstractNewPromptFileAction extends Action2 {
|
|
|
52
53
|
const editorService = accessor.get(IEditorService);
|
|
53
54
|
const fileService = accessor.get(IFileService);
|
|
54
55
|
const instaService = accessor.get(IInstantiationService);
|
|
55
|
-
const chatModeService = accessor.get(IChatModeService);
|
|
56
56
|
const selectedFolder = await instaService.invokeFunction(askForPromptSourceFolder, this.type);
|
|
57
57
|
if (!selectedFolder) {
|
|
58
58
|
return;
|
|
@@ -65,113 +65,193 @@ class AbstractNewPromptFileAction extends Action2 {
|
|
|
65
65
|
const promptUri = URI.joinPath(selectedFolder.uri, fileName);
|
|
66
66
|
await fileService.createFile(promptUri);
|
|
67
67
|
await openerService.open(promptUri);
|
|
68
|
+
const cleanName = getCleanPromptName(promptUri);
|
|
68
69
|
const editor = getCodeEditor(editorService.activeTextEditorControl);
|
|
69
70
|
if (editor && editor.hasModel() && isEqual(editor.getModel().uri, promptUri)) {
|
|
70
71
|
SnippetController2.get(editor)?.apply([{
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
range: editor.getModel().getFullModelRange(),
|
|
73
|
+
template: getDefaultContentSnippet(this.type, cleanName)
|
|
74
|
+
}]);
|
|
74
75
|
}
|
|
75
|
-
if (selectedFolder.storage !==
|
|
76
|
+
if (selectedFolder.storage !== "user") {
|
|
76
77
|
return;
|
|
77
78
|
}
|
|
78
|
-
const isConfigured = userDataSyncEnablementService
|
|
79
|
-
.isResourceEnablementConfigured(SyncResource.Prompts);
|
|
79
|
+
const isConfigured = userDataSyncEnablementService.isResourceEnablementConfigured(SyncResource.Prompts);
|
|
80
80
|
const isSettingsSyncEnabled = userDataSyncEnablementService.isEnabled();
|
|
81
81
|
if ((isConfigured === true) || (isSettingsSyncEnabled === false)) {
|
|
82
82
|
return;
|
|
83
83
|
}
|
|
84
84
|
notificationService.prompt(Severity.Info, ( localize(
|
|
85
|
-
|
|
85
|
+
5662,
|
|
86
86
|
"Do you want to backup and sync your user prompt, instruction and custom agent files with Setting Sync?'"
|
|
87
|
-
)), [
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
openerService.open(( URI.parse('https://aka.ms/vscode-settings-sync-help')));
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
], {
|
|
87
|
+
)), [{
|
|
88
|
+
label: ( localize(5663, "Enable")),
|
|
89
|
+
run: () => {
|
|
90
|
+
commandService.executeCommand(CONFIGURE_SYNC_COMMAND_ID).catch(error => {
|
|
91
|
+
logService.error(`Failed to run '${CONFIGURE_SYNC_COMMAND_ID}' command: ${error}.`);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}, {
|
|
95
|
+
label: ( localize(5664, "Learn More")),
|
|
96
|
+
run: () => {
|
|
97
|
+
openerService.open(( URI.parse("https://aka.ms/vscode-settings-sync-help")));
|
|
98
|
+
}
|
|
99
|
+
}], {
|
|
104
100
|
neverShowAgain: {
|
|
105
|
-
id:
|
|
106
|
-
scope: NeverShowAgainScope.PROFILE
|
|
107
|
-
}
|
|
101
|
+
id: "workbench.command.prompts.create.user.enable-sync-notification",
|
|
102
|
+
scope: NeverShowAgainScope.PROFILE
|
|
103
|
+
}
|
|
108
104
|
});
|
|
109
105
|
}
|
|
110
106
|
}
|
|
111
|
-
function getDefaultContentSnippet(promptType,
|
|
112
|
-
const agents = chatModeService.getModes();
|
|
113
|
-
const agentNames = ( agents.builtin.map(agent => agent.name.get())).join(',') + (agents.custom.length ? (',' + ( agents.custom.map(agent => agent.name.get())).join(',')) : '');
|
|
107
|
+
function getDefaultContentSnippet(promptType, name) {
|
|
114
108
|
switch (promptType) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
109
|
+
case PromptsType.prompt:
|
|
110
|
+
return [
|
|
111
|
+
`---`,
|
|
112
|
+
`name: ${name ?? "${1:prompt-name}"}`,
|
|
113
|
+
`description: \${2:Describe when to use this prompt}`,
|
|
114
|
+
`---`,
|
|
115
|
+
`\${3:Define the prompt content here. You can include instructions, examples, and any other relevant information to guide the AI's responses.}`
|
|
116
|
+
].join("\n");
|
|
117
|
+
case PromptsType.instructions:
|
|
118
|
+
return [
|
|
119
|
+
`---`,
|
|
120
|
+
`description: \${1:Describe when these instructions should be loaded}`,
|
|
121
|
+
`# applyTo: '\${1|**,**/*.ts|}' # when provided, instructions will automatically be added to the request context when the pattern matches an attached file`,
|
|
122
|
+
`---`,
|
|
123
|
+
`\${2:Provide project context and coding guidelines that AI should follow when generating code, answering questions, or reviewing changes.}`
|
|
124
|
+
].join("\n");
|
|
125
|
+
case PromptsType.agent:
|
|
126
|
+
return [
|
|
127
|
+
`---`,
|
|
128
|
+
`name: ${name ?? "${1:agent-name}"}`,
|
|
129
|
+
`description: \${2:Describe what this custom agent does and when to use it.}`,
|
|
130
|
+
`argument-hint: \${3:The inputs this agent expects, e.g., "a task to implement" or "a question to answer".}`,
|
|
131
|
+
`# tools: ['vscode', 'execute', 'read', 'agent', 'edit', 'search', 'web', 'todo'] # specify the tools this agent can use. If not set, all enabled tools are allowed.`,
|
|
132
|
+
`---`,
|
|
133
|
+
`\${4:Define what this custom agent does, including its behavior, capabilities, and any specific instructions for its operation.}`
|
|
134
|
+
].join("\n");
|
|
135
|
+
case PromptsType.skill:
|
|
136
|
+
return [
|
|
137
|
+
`---`,
|
|
138
|
+
`name: ${name ?? "${1:skill-name}"}`,
|
|
139
|
+
`description: \${2:Describe what this skill does and when to use it. Include keywords that help agents identify relevant tasks.}`,
|
|
140
|
+
`---`,
|
|
141
|
+
`\${3:Define the functionality provided by this skill, including detailed instructions and examples}`
|
|
142
|
+
].join("\n");
|
|
143
|
+
default:
|
|
144
|
+
throw ( new Error(`Unsupported prompt type: ${promptType}`));
|
|
139
145
|
}
|
|
140
146
|
}
|
|
141
|
-
const NEW_PROMPT_COMMAND_ID =
|
|
142
|
-
const NEW_INSTRUCTIONS_COMMAND_ID =
|
|
143
|
-
const NEW_AGENT_COMMAND_ID =
|
|
147
|
+
const NEW_PROMPT_COMMAND_ID = "workbench.command.new.prompt";
|
|
148
|
+
const NEW_INSTRUCTIONS_COMMAND_ID = "workbench.command.new.instructions";
|
|
149
|
+
const NEW_AGENT_COMMAND_ID = "workbench.command.new.agent";
|
|
150
|
+
const NEW_SKILL_COMMAND_ID = "workbench.command.new.skill";
|
|
144
151
|
class NewPromptFileAction extends AbstractNewPromptFileAction {
|
|
145
152
|
constructor() {
|
|
146
|
-
super(NEW_PROMPT_COMMAND_ID, ( localize(
|
|
153
|
+
super(NEW_PROMPT_COMMAND_ID, ( localize(5665, "New Prompt File...")), PromptsType.prompt);
|
|
147
154
|
}
|
|
148
155
|
}
|
|
149
156
|
class NewInstructionsFileAction extends AbstractNewPromptFileAction {
|
|
150
157
|
constructor() {
|
|
151
|
-
super(NEW_INSTRUCTIONS_COMMAND_ID, ( localize(
|
|
158
|
+
super(NEW_INSTRUCTIONS_COMMAND_ID, ( localize(5666, "New Instructions File...")), PromptsType.instructions);
|
|
152
159
|
}
|
|
153
160
|
}
|
|
154
161
|
class NewAgentFileAction extends AbstractNewPromptFileAction {
|
|
155
162
|
constructor() {
|
|
156
|
-
super(NEW_AGENT_COMMAND_ID, ( localize(
|
|
163
|
+
super(NEW_AGENT_COMMAND_ID, ( localize(5667, "New Custom Agent...")), PromptsType.agent);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
class NewSkillFileAction extends Action2 {
|
|
167
|
+
constructor() {
|
|
168
|
+
super({
|
|
169
|
+
id: NEW_SKILL_COMMAND_ID,
|
|
170
|
+
title: ( localize(5668, "New Skill File...")),
|
|
171
|
+
f1: false,
|
|
172
|
+
precondition: ChatContextKeys.enabled,
|
|
173
|
+
category: CHAT_CATEGORY,
|
|
174
|
+
keybinding: {
|
|
175
|
+
weight: KeybindingWeight.WorkbenchContrib
|
|
176
|
+
},
|
|
177
|
+
menu: {
|
|
178
|
+
id: MenuId.CommandPalette,
|
|
179
|
+
when: ChatContextKeys.enabled
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
async run(accessor) {
|
|
184
|
+
const openerService = accessor.get(IOpenerService);
|
|
185
|
+
const editorService = accessor.get(IEditorService);
|
|
186
|
+
const fileService = accessor.get(IFileService);
|
|
187
|
+
const instaService = accessor.get(IInstantiationService);
|
|
188
|
+
const quickInputService = accessor.get(IQuickInputService);
|
|
189
|
+
const selectedFolder = await instaService.invokeFunction(askForPromptSourceFolder, PromptsType.skill);
|
|
190
|
+
if (!selectedFolder) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const skillName = await quickInputService.input({
|
|
194
|
+
prompt: ( localize(
|
|
195
|
+
5669,
|
|
196
|
+
"Enter a name for the skill (lowercase letters, numbers, and hyphens only)"
|
|
197
|
+
)),
|
|
198
|
+
placeHolder: ( localize(5670, "e.g., pdf-processing, data-analysis")),
|
|
199
|
+
validateInput: async value => {
|
|
200
|
+
if (!value || !value.trim()) {
|
|
201
|
+
return localize(5671, "Skill name is required");
|
|
202
|
+
}
|
|
203
|
+
const name = value.trim();
|
|
204
|
+
if (name.length > 64) {
|
|
205
|
+
return localize(5672, "Skill name must be 64 characters or less");
|
|
206
|
+
}
|
|
207
|
+
if (!/^[a-z0-9-]+$/.test(name)) {
|
|
208
|
+
return localize(
|
|
209
|
+
5673,
|
|
210
|
+
"Skill name may only contain lowercase letters, numbers, and hyphens"
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
if (name.startsWith("-") || name.endsWith("-")) {
|
|
214
|
+
return localize(5674, "Skill name must not start or end with a hyphen");
|
|
215
|
+
}
|
|
216
|
+
if (name.includes("--")) {
|
|
217
|
+
return localize(5675, "Skill name must not contain consecutive hyphens");
|
|
218
|
+
}
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
if (!skillName) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const trimmedName = skillName.trim();
|
|
226
|
+
const skillFolder = URI.joinPath(selectedFolder.uri, trimmedName);
|
|
227
|
+
await fileService.createFolder(skillFolder);
|
|
228
|
+
const skillFileUri = URI.joinPath(skillFolder, SKILL_FILENAME);
|
|
229
|
+
await fileService.createFile(skillFileUri);
|
|
230
|
+
await openerService.open(skillFileUri);
|
|
231
|
+
const editor = getCodeEditor(editorService.activeTextEditorControl);
|
|
232
|
+
if (editor && editor.hasModel() && isEqual(editor.getModel().uri, skillFileUri)) {
|
|
233
|
+
SnippetController2.get(editor)?.apply([{
|
|
234
|
+
range: editor.getModel().getFullModelRange(),
|
|
235
|
+
template: getDefaultContentSnippet(PromptsType.skill, trimmedName)
|
|
236
|
+
}]);
|
|
237
|
+
}
|
|
157
238
|
}
|
|
158
239
|
}
|
|
159
240
|
class NewUntitledPromptFileAction extends Action2 {
|
|
160
241
|
constructor() {
|
|
161
242
|
super({
|
|
162
|
-
id:
|
|
163
|
-
title: ( localize2(
|
|
243
|
+
id: "workbench.command.new.untitled.prompt",
|
|
244
|
+
title: ( localize2(5676, "New Untitled Prompt File")),
|
|
164
245
|
f1: true,
|
|
165
246
|
precondition: ChatContextKeys.enabled,
|
|
166
247
|
category: CHAT_CATEGORY,
|
|
167
248
|
keybinding: {
|
|
168
249
|
weight: KeybindingWeight.WorkbenchContrib
|
|
169
|
-
}
|
|
250
|
+
}
|
|
170
251
|
});
|
|
171
252
|
}
|
|
172
253
|
async run(accessor) {
|
|
173
254
|
const editorService = accessor.get(IEditorService);
|
|
174
|
-
const chatModeService = accessor.get(IChatModeService);
|
|
175
255
|
const languageId = getLanguageIdForPromptsType(PromptsType.prompt);
|
|
176
256
|
const input = await editorService.openEditor({
|
|
177
257
|
resource: undefined,
|
|
@@ -184,9 +264,9 @@ class NewUntitledPromptFileAction extends Action2 {
|
|
|
184
264
|
const editor = getCodeEditor(editorService.activeTextEditorControl);
|
|
185
265
|
if (editor && editor.hasModel()) {
|
|
186
266
|
SnippetController2.get(editor)?.apply([{
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
267
|
+
range: editor.getModel().getFullModelRange(),
|
|
268
|
+
template: getDefaultContentSnippet(type, undefined)
|
|
269
|
+
}]);
|
|
190
270
|
}
|
|
191
271
|
return input;
|
|
192
272
|
}
|
|
@@ -195,7 +275,8 @@ function registerNewPromptFileActions() {
|
|
|
195
275
|
registerAction2(NewPromptFileAction);
|
|
196
276
|
registerAction2(NewInstructionsFileAction);
|
|
197
277
|
registerAction2(NewAgentFileAction);
|
|
278
|
+
registerAction2(NewSkillFileAction);
|
|
198
279
|
registerAction2(NewUntitledPromptFileAction);
|
|
199
280
|
}
|
|
200
281
|
|
|
201
|
-
export { NEW_AGENT_COMMAND_ID, NEW_INSTRUCTIONS_COMMAND_ID, NEW_PROMPT_COMMAND_ID, registerNewPromptFileActions };
|
|
282
|
+
export { NEW_AGENT_COMMAND_ID, NEW_INSTRUCTIONS_COMMAND_ID, NEW_PROMPT_COMMAND_ID, NEW_SKILL_COMMAND_ID, registerNewPromptFileActions };
|
package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptName.js
CHANGED
|
@@ -11,41 +11,43 @@ import { isValidBasename } from '@codingame/monaco-vscode-api/vscode/vs/base/com
|
|
|
11
11
|
async function askForPromptFileName(accessor, type, selectedFolder, existingFileName) {
|
|
12
12
|
const quickInputService = accessor.get(IQuickInputService);
|
|
13
13
|
const fileService = accessor.get(IFileService);
|
|
14
|
-
const sanitizeInput =
|
|
14
|
+
const sanitizeInput = input => {
|
|
15
15
|
const trimmedName = input.trim();
|
|
16
16
|
if (!trimmedName) {
|
|
17
17
|
return undefined;
|
|
18
18
|
}
|
|
19
19
|
const fileExtension = getPromptFileExtension(type);
|
|
20
|
-
return (trimmedName.endsWith(fileExtension))
|
|
21
|
-
? trimmedName
|
|
22
|
-
: `${trimmedName}${fileExtension}`;
|
|
20
|
+
return (trimmedName.endsWith(fileExtension)) ? trimmedName : `${trimmedName}${fileExtension}`;
|
|
23
21
|
};
|
|
24
|
-
const validateInput = async
|
|
22
|
+
const validateInput = async value => {
|
|
25
23
|
const fileName = sanitizeInput(value);
|
|
26
24
|
if (!fileName) {
|
|
27
25
|
return {
|
|
28
|
-
content: ( localize(
|
|
26
|
+
content: ( localize(5677, "Please enter a name.")),
|
|
29
27
|
severity: Severity.Warning
|
|
30
28
|
};
|
|
31
29
|
}
|
|
32
30
|
if (!isValidBasename(fileName)) {
|
|
33
31
|
return {
|
|
34
|
-
content: ( localize(
|
|
32
|
+
content: ( localize(5678, "The name contains invalid characters.")),
|
|
35
33
|
severity: Severity.Error
|
|
36
34
|
};
|
|
37
35
|
}
|
|
38
36
|
const fileUri = URI.joinPath(selectedFolder, fileName);
|
|
39
37
|
if (await fileService.exists(fileUri)) {
|
|
40
38
|
return {
|
|
41
|
-
content: ( localize(
|
|
39
|
+
content: ( localize(5679, "A file for the given name already exists.")),
|
|
42
40
|
severity: Severity.Error
|
|
43
41
|
};
|
|
44
42
|
}
|
|
45
43
|
return undefined;
|
|
46
44
|
};
|
|
47
45
|
const placeHolder = existingFileName ? getPlaceholderStringForRename(type) : getPlaceholderStringForNew(type);
|
|
48
|
-
const result = await quickInputService.input({
|
|
46
|
+
const result = await quickInputService.input({
|
|
47
|
+
placeHolder,
|
|
48
|
+
validateInput,
|
|
49
|
+
value: existingFileName
|
|
50
|
+
});
|
|
49
51
|
if (!result) {
|
|
50
52
|
return undefined;
|
|
51
53
|
}
|
|
@@ -53,26 +55,26 @@ async function askForPromptFileName(accessor, type, selectedFolder, existingFile
|
|
|
53
55
|
}
|
|
54
56
|
function getPlaceholderStringForNew(type) {
|
|
55
57
|
switch (type) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
case PromptsType.instructions:
|
|
59
|
+
return localize(5680, "Enter the name of the instructions file");
|
|
60
|
+
case PromptsType.prompt:
|
|
61
|
+
return localize(5681, "Enter the name of the prompt file");
|
|
62
|
+
case PromptsType.agent:
|
|
63
|
+
return localize(5682, "Enter the name of the agent file");
|
|
64
|
+
default:
|
|
65
|
+
throw ( new Error("Unknown prompt type"));
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
68
|
function getPlaceholderStringForRename(type) {
|
|
67
69
|
switch (type) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
case PromptsType.instructions:
|
|
71
|
+
return localize(5683, "Enter a new name of the instructions file");
|
|
72
|
+
case PromptsType.prompt:
|
|
73
|
+
return localize(5684, "Enter a new name of the prompt file");
|
|
74
|
+
case PromptsType.agent:
|
|
75
|
+
return localize(5685, "Enter a new name of the agent file");
|
|
76
|
+
default:
|
|
77
|
+
throw ( new Error("Unknown prompt type"));
|
|
76
78
|
}
|
|
77
79
|
}
|
|
78
80
|
|