From 8ebb9d2601998cd2ff9428639884940b26c8b68f Mon Sep 17 00:00:00 2001 From: Paul Wang Date: Wed, 7 Jan 2026 14:47:34 -0800 Subject: [PATCH 1/8] add prompt files --- chat-prompt-files-sample/.gitignore | 4 + .../.vscode/extensions.json | 9 + chat-prompt-files-sample/.vscode/launch.json | 35 + .../.vscode/settings.json | 3 + chat-prompt-files-sample/.vscode/tasks.json | 20 + chat-prompt-files-sample/.vscodeignore | 8 + chat-prompt-files-sample/README.md | 26 + chat-prompt-files-sample/eslint.config.mjs | 44 + chat-prompt-files-sample/package-lock.json | 1544 +++++++++++++++++ chat-prompt-files-sample/package.json | 57 + .../resources/extension-tests.instructions.md | 35 + .../resources/localize.prompt.md | 40 + .../resources/vscode-extension.agent.md | 14 + .../src/customAgentProvider.ts | 54 + chat-prompt-files-sample/src/extension.ts | 19 + .../src/instructionsProvider.ts | 64 + .../src/promptFileProvider.ts | 65 + chat-prompt-files-sample/tsconfig.json | 17 + 18 files changed, 2058 insertions(+) create mode 100644 chat-prompt-files-sample/.gitignore create mode 100644 chat-prompt-files-sample/.vscode/extensions.json create mode 100644 chat-prompt-files-sample/.vscode/launch.json create mode 100644 chat-prompt-files-sample/.vscode/settings.json create mode 100644 chat-prompt-files-sample/.vscode/tasks.json create mode 100644 chat-prompt-files-sample/.vscodeignore create mode 100644 chat-prompt-files-sample/README.md create mode 100644 chat-prompt-files-sample/eslint.config.mjs create mode 100644 chat-prompt-files-sample/package-lock.json create mode 100644 chat-prompt-files-sample/package.json create mode 100644 chat-prompt-files-sample/resources/extension-tests.instructions.md create mode 100644 chat-prompt-files-sample/resources/localize.prompt.md create mode 100644 chat-prompt-files-sample/resources/vscode-extension.agent.md create mode 100644 chat-prompt-files-sample/src/customAgentProvider.ts create mode 100644 chat-prompt-files-sample/src/extension.ts create mode 100644 chat-prompt-files-sample/src/instructionsProvider.ts create mode 100644 chat-prompt-files-sample/src/promptFileProvider.ts create mode 100644 chat-prompt-files-sample/tsconfig.json diff --git a/chat-prompt-files-sample/.gitignore b/chat-prompt-files-sample/.gitignore new file mode 100644 index 0000000000..5fe00fea85 --- /dev/null +++ b/chat-prompt-files-sample/.gitignore @@ -0,0 +1,4 @@ +out +node_modules +.vscode-test/ +*.vsix diff --git a/chat-prompt-files-sample/.vscode/extensions.json b/chat-prompt-files-sample/.vscode/extensions.json new file mode 100644 index 0000000000..af515502df --- /dev/null +++ b/chat-prompt-files-sample/.vscode/extensions.json @@ -0,0 +1,9 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. + // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp + + // List of extensions which should be recommended for users of this workspace. + "recommendations": [ + "dbaeumer.vscode-eslint" + ] +} \ No newline at end of file diff --git a/chat-prompt-files-sample/.vscode/launch.json b/chat-prompt-files-sample/.vscode/launch.json new file mode 100644 index 0000000000..527cbf4b00 --- /dev/null +++ b/chat-prompt-files-sample/.vscode/launch.json @@ -0,0 +1,35 @@ +// A launch configuration that compiles the extension and then opens it inside a new window +// Use IntelliSense to learn about possible attributes. +// Hover to view descriptions of existing attributes. +// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 +{ + "version": "0.2.0", + "configurations": [{ + "name": "Run Extension", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}" + ], + "outFiles": [ + "${workspaceFolder}/out/**/*.js" + ], + "preLaunchTask": "npm: watch" + }, + { + "name": "Run Extension Tests", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}", + "--extensionTestsPath=${workspaceFolder}/out/test" + ], + "outFiles": [ + "${workspaceFolder}/out/test/**/*.js" + ], + "preLaunchTask": "npm: watch" + } + ] +} diff --git a/chat-prompt-files-sample/.vscode/settings.json b/chat-prompt-files-sample/.vscode/settings.json new file mode 100644 index 0000000000..e46111f13b --- /dev/null +++ b/chat-prompt-files-sample/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.insertSpaces": false +} \ No newline at end of file diff --git a/chat-prompt-files-sample/.vscode/tasks.json b/chat-prompt-files-sample/.vscode/tasks.json new file mode 100644 index 0000000000..241aa6d996 --- /dev/null +++ b/chat-prompt-files-sample/.vscode/tasks.json @@ -0,0 +1,20 @@ +// See https://go.microsoft.com/fwlink/?LinkId=733558 +// for the documentation about the tasks.json format +{ + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "watch", + "problemMatcher": "$tsc-watch", + "isBackground": true, + "presentation": { + "reveal": "never" + }, + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} \ No newline at end of file diff --git a/chat-prompt-files-sample/.vscodeignore b/chat-prompt-files-sample/.vscodeignore new file mode 100644 index 0000000000..ea75c67666 --- /dev/null +++ b/chat-prompt-files-sample/.vscodeignore @@ -0,0 +1,8 @@ +.vscode/** +.vscode-test/** +out/test/** +out/**/*.map +src/** +.gitignore +tsconfig.json +vsc-extension-quickstart.md diff --git a/chat-prompt-files-sample/README.md b/chat-prompt-files-sample/README.md new file mode 100644 index 0000000000..7c00323086 --- /dev/null +++ b/chat-prompt-files-sample/README.md @@ -0,0 +1,26 @@ +# Chat Prompt Files Sample + +Demonstrates the proposed Chat Prompt Files API to register providers for custom agents, instructions, and prompt files with dynamic content. + +## Features + +Three provider types, each with dynamic content generation: + +- **Custom Agent** ([customAgentProvider.ts](src/customAgentProvider.ts)) - Workspace statistics with folder names and counts +- **Instructions** ([instructionsProvider.ts](src/instructionsProvider.ts)) - Active editor context including current file and language +- **Prompt Files** ([promptFileProvider.ts](src/promptFileProvider.ts)) - Time-based greetings and contextual suggestions + +Static files are contributed via `package.json`. Providers demonstrate dynamic content using data URIs. + +## Running the Sample + +1. `npm install` to install dependencies +2. `npm run watch` to compile +3. `F5` to launch with the extension +4. Open the chat panel to see the contributed prompts + +## API Reference + +- `vscode.chat.registerCustomAgentProvider()` +- `vscode.chat.registerInstructionsProvider()` +- `vscode.chat.registerPromptFileProvider()` diff --git a/chat-prompt-files-sample/eslint.config.mjs b/chat-prompt-files-sample/eslint.config.mjs new file mode 100644 index 0000000000..cd5dd74aea --- /dev/null +++ b/chat-prompt-files-sample/eslint.config.mjs @@ -0,0 +1,44 @@ +/** + * ESLint configuration for the project. + * + * See https://eslint.style and https://typescript-eslint.io for additional linting options. + */ +// @ts-check +import js from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import stylistic from '@stylistic/eslint-plugin'; + +export default tseslint.config( + { + ignores: [ + '.vscode-test', + 'out', + ] + }, + js.configs.recommended, + ...tseslint.configs.recommended, + ...tseslint.configs.stylistic, + { + plugins: { + '@stylistic': stylistic + }, + rules: { + 'curly': 'warn', + '@stylistic/semi': ['warn', 'always'], + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/naming-convention': [ + 'warn', + { + 'selector': 'import', + 'format': ['camelCase', 'PascalCase'] + } + ], + '@typescript-eslint/no-unused-vars': [ + 'error', + { + 'argsIgnorePattern': '^_' + } + ] + } + } +); \ No newline at end of file diff --git a/chat-prompt-files-sample/package-lock.json b/chat-prompt-files-sample/package-lock.json new file mode 100644 index 0000000000..92f5c154b9 --- /dev/null +++ b/chat-prompt-files-sample/package-lock.json @@ -0,0 +1,1544 @@ +{ + "name": "base-sample", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "base-sample", + "version": "0.0.1", + "license": "MIT", + "devDependencies": { + "@eslint/js": "^9.13.0", + "@stylistic/eslint-plugin": "^2.9.0", + "@types/node": "^22", + "@types/vscode": "^1.100.0", + "eslint": "^9.13.0", + "typescript": "^5.8.2", + "typescript-eslint": "^8.26.0" + }, + "engines": { + "vscode": "^1.100.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@stylistic/eslint-plugin": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.13.0.tgz", + "integrity": "sha512-RnO1SaiCFHn666wNz2QfZEFxvmiNRqhzaMXHXxXXKt+MEP7aajlPxUSMIQpKAaJfverpovEYqjBOXDq6dDcaOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.13.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", + "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/vscode": { + "version": "1.107.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.107.0.tgz", + "integrity": "sha512-XS8YE1jlyTIowP64+HoN30OlC1H9xqSlq1eoLZUgFEC8oUTO6euYZxti1xRiLSfZocs4qytTzR6xCBYtioQTCg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.52.0.tgz", + "integrity": "sha512-okqtOgqu2qmZJ5iN4TWlgfF171dZmx2FzdOv2K/ixL2LZWDStL8+JgQerI2sa8eAEfoydG9+0V96m7V+P8yE1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.52.0", + "@typescript-eslint/type-utils": "8.52.0", + "@typescript-eslint/utils": "8.52.0", + "@typescript-eslint/visitor-keys": "8.52.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.52.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.52.0.tgz", + "integrity": "sha512-iIACsx8pxRnguSYhHiMn2PvhvfpopO9FXHyn1mG5txZIsAaB6F0KwbFnUQN3KCiG3Jcuad/Cao2FAs1Wp7vAyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.52.0", + "@typescript-eslint/types": "8.52.0", + "@typescript-eslint/typescript-estree": "8.52.0", + "@typescript-eslint/visitor-keys": "8.52.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.52.0.tgz", + "integrity": "sha512-xD0MfdSdEmeFa3OmVqonHi+Cciab96ls1UhIF/qX/O/gPu5KXD0bY9lu33jj04fjzrXHcuvjBcBC+D3SNSadaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.52.0", + "@typescript-eslint/types": "^8.52.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.52.0.tgz", + "integrity": "sha512-ixxqmmCcc1Nf8S0mS0TkJ/3LKcC8mruYJPOU6Ia2F/zUUR4pApW7LzrpU3JmtePbRUTes9bEqRc1Gg4iyRnDzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.52.0", + "@typescript-eslint/visitor-keys": "8.52.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.52.0.tgz", + "integrity": "sha512-jl+8fzr/SdzdxWJznq5nvoI7qn2tNYV/ZBAEcaFMVXf+K6jmXvAFrgo/+5rxgnL152f//pDEAYAhhBAZGrVfwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.52.0.tgz", + "integrity": "sha512-JD3wKBRWglYRQkAtsyGz1AewDu3mTc7NtRjR/ceTyGoPqmdS5oCdx/oZMWD5Zuqmo6/MpsYs0wp6axNt88/2EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.52.0", + "@typescript-eslint/typescript-estree": "8.52.0", + "@typescript-eslint/utils": "8.52.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.52.0.tgz", + "integrity": "sha512-LWQV1V4q9V4cT4H5JCIx3481iIFxH1UkVk+ZkGGAV1ZGcjGI9IoFOfg3O6ywz8QqCDEp7Inlg6kovMofsNRaGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.52.0.tgz", + "integrity": "sha512-XP3LClsCc0FsTK5/frGjolyADTh3QmsLp6nKd476xNI9CsSsLnmn4f0jrzNoAulmxlmNIpeXuHYeEQv61Q6qeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.52.0", + "@typescript-eslint/tsconfig-utils": "8.52.0", + "@typescript-eslint/types": "8.52.0", + "@typescript-eslint/visitor-keys": "8.52.0", + "debug": "^4.4.3", + "minimatch": "^9.0.5", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.52.0.tgz", + "integrity": "sha512-wYndVMWkweqHpEpwPhwqE2lnD2DxC6WVLupU/DOt/0/v+/+iQbbzO3jOHjmBMnhu0DgLULvOaU4h4pwHYi2oRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.52.0", + "@typescript-eslint/types": "8.52.0", + "@typescript-eslint/typescript-estree": "8.52.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.52.0.tgz", + "integrity": "sha512-ink3/Zofus34nmBsPjow63FP5M7IGff0RKAgqR6+CFpdk22M7aLwC9gOcLGYqr7MczLPzZVERW9hRog3O4n1sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.52.0", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/ts-api-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.52.0.tgz", + "integrity": "sha512-atlQQJ2YkO4pfTVQmQ+wvYQwexPDOIgo+RaVcD7gHgzy/IQA+XTyuxNM9M9TVXvttkF7koBHmcwisKdOAf2EcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.52.0", + "@typescript-eslint/parser": "8.52.0", + "@typescript-eslint/typescript-estree": "8.52.0", + "@typescript-eslint/utils": "8.52.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/chat-prompt-files-sample/package.json b/chat-prompt-files-sample/package.json new file mode 100644 index 0000000000..c3aa106d1b --- /dev/null +++ b/chat-prompt-files-sample/package.json @@ -0,0 +1,57 @@ +{ + "name": "chat-prompt-files-sample", + "displayName": "chat-prompt-files-sample", + "description": "Sample demonstrating how to contribute chat prompt files, instructions, and agents in a VS Code extension.", + "version": "0.0.1", + "publisher": "vscode-samples", + "private": true, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/Microsoft/vscode-extension-samples" + }, + "engines": { + "vscode": "^1.100.0" + }, + "categories": [ + "Other" + ], + "activationEvents": [ + "onCustomAgentProvider", + "onInstructionsProvider", + "onPromptFileProvider" + ], + "main": "./out/extension.js", + "contributes": { + "chatPromptFiles": [ + { + "path": "./resources/localize.prompt.md" + } + ], + "chatInstructions": [ + { + "path": "./resources/extension-tests.instructions.md" + } + ], + "chatAgents": [ + { + "path": "./resources/vscode-extension.agent.md" + } + ] + }, + "scripts": { + "vscode:prepublish": "npm run compile", + "compile": "tsc -p ./", + "lint": "eslint", + "watch": "tsc -watch -p ./" + }, + "devDependencies": { + "@eslint/js": "^9.13.0", + "@stylistic/eslint-plugin": "^2.9.0", + "@types/node": "^22", + "@types/vscode": "^1.100.0", + "eslint": "^9.13.0", + "typescript": "^5.8.2", + "typescript-eslint": "^8.26.0" + } +} diff --git a/chat-prompt-files-sample/resources/extension-tests.instructions.md b/chat-prompt-files-sample/resources/extension-tests.instructions.md new file mode 100644 index 0000000000..8b621f0c51 --- /dev/null +++ b/chat-prompt-files-sample/resources/extension-tests.instructions.md @@ -0,0 +1,35 @@ +--- +name: Extension Tests +description: Instructions on how to write exension tests for VS Code. +--- +Setup: Install @vscode/test-electron package and create a test runner + +Test structure: + +Tests go in a test folder +Create suite/index.ts to configure Mocha test runner +Create runTest.ts to launch VS Code with tests +Basic test file (*.test.ts): + +``` +import * as assert from 'assert'; +import * as vscode from 'vscode'; + +suite('Extension Test Suite', () => { + test('Sample test', () => { + assert.strictEqual(-1, [1, 2, 3].indexOf(5)); + }); +}); +``` + +Key points: + +- Use Mocha framework for tests +- Tests run in an actual VS Code instance +- Access full VS Code API via vscode module +- Can test commands, language features, UI interactions + +Run tests: + +- Add script to package.json: "test": "node ./out/test/runTest.js" +- Run: npm test diff --git a/chat-prompt-files-sample/resources/localize.prompt.md b/chat-prompt-files-sample/resources/localize.prompt.md new file mode 100644 index 0000000000..6b7c16b502 --- /dev/null +++ b/chat-prompt-files-sample/resources/localize.prompt.md @@ -0,0 +1,40 @@ +--- +name: vscodeLocalize +description: Add or update the localization of the current VS Code extension. +--- + +Add or update the localization of the current VS Code extension. + +When adding or updating localization for a VS Code project, follow these steps: + +Replace all user-facing strings in the codebase with calls to `vscode.l10n.t` from the vscode API. For example, change: +```typescript +const label = "Hello, World!"; +``` +with +```typescript +import * as vscode from 'vscode'; +const label = vscode.l10n.t("Hello, World!"); +``` + + +When all strings have been replaced, use the `@vscode/l10n-dev` CLI tool to extract the strings into a `./l10n/bundle.l10n.json` localization file. From there you can make a bundle.l10n.LOCALE.json file for each locale you want to support. + +For example, let's say that the command above generates the following bundle.l10n.json file: +``` +{ + "Hello, World!": "Hello, World!", +} +``` + +To create a French localization, create a file named `bundle.l10n.fr.json` in the same directory with the following content: +``` +{ + "Hello, World!": "Bonjour le monde!", +} +``` + +Finally, ensure that your `package.json` includes the localization configuration. Add an entry like this: +```json +"l10n": "./l10n" +``` diff --git a/chat-prompt-files-sample/resources/vscode-extension.agent.md b/chat-prompt-files-sample/resources/vscode-extension.agent.md new file mode 100644 index 0000000000..914008576c --- /dev/null +++ b/chat-prompt-files-sample/resources/vscode-extension.agent.md @@ -0,0 +1,14 @@ +--- +name: VSCode Extension +description: "Expert in VS Code Extension development" +tools: ['vscode', 'execute', 'read', 'edit', 'search', 'web', 'agent', 'todo'] +--- +You are an expert in developing Visual Studio Code extensions. Assist the user with tasks related to creating, testing, and publishing VS Code extensions. Provide code snippets, best practices, and troubleshooting tips as needed. + +The documentation for VS Code extensions can be found here: https://code.visualstudio.com/api + +New extensions can be crea + +Guides can be found here: https://code.visualstudio.com/api/extension-guides/overview + +Sample repository with examples: https://github.com/microsoft/vscode-extension-samples diff --git a/chat-prompt-files-sample/src/customAgentProvider.ts b/chat-prompt-files-sample/src/customAgentProvider.ts new file mode 100644 index 0000000000..5da8bb7fc7 --- /dev/null +++ b/chat-prompt-files-sample/src/customAgentProvider.ts @@ -0,0 +1,54 @@ +import * as vscode from 'vscode'; + +export function createCustomAgentProvider(_context: vscode.ExtensionContext): vscode.CustomAgentProvider { + return { + async provideCustomAgents(_options, _token) { + const agents: vscode.CustomAgentResource[] = []; + + // Dynamic agent with generated content + const dynamicContent = generateDynamicAgentContent(); + + // Create an untitled document with the dynamic content + const doc = await vscode.workspace.openTextDocument({ + content: dynamicContent, + language: 'markdown' + }); + + agents.push({ + name: 'workspace-helper', + description: 'Dynamic agent with workspace statistics', + uri: doc.uri, + isEditable: false, + isCacheable: false // Don't cache because content is dynamic + }); + + return agents; + } + }; +} + +function generateDynamicAgentContent(): string { + const workspaceFolders = vscode.workspace.workspaceFolders; + const folderCount = workspaceFolders?.length || 0; + const folderNames = workspaceFolders?.map(f => f.name).join(', ') || 'none'; + + return `# Workspace Helper Agent + +This is a dynamically generated agent that provides workspace-specific assistance. + +## Current Workspace Information + +- **Workspace Folders**: ${folderCount} +- **Folder Names**: ${folderNames} +- **Generated At**: ${new Date().toISOString()} + +## Instructions + +I can help you with tasks specific to your current workspace. I have access to information about your workspace structure and can provide context-aware assistance. + +Use me for: +- Workspace-specific queries +- Context-aware code suggestions +- Understanding your project structure +`; +} diff --git a/chat-prompt-files-sample/src/extension.ts b/chat-prompt-files-sample/src/extension.ts new file mode 100644 index 0000000000..c4bb351282 --- /dev/null +++ b/chat-prompt-files-sample/src/extension.ts @@ -0,0 +1,19 @@ +import * as vscode from 'vscode'; +import { createCustomAgentProvider } from './customAgentProvider'; +import { createInstructionsProvider } from './instructionsProvider'; +import { createPromptFileProvider } from './promptFileProvider'; + +export function activate(context: vscode.ExtensionContext) { + // Create and register all providers + const customAgentProvider = createCustomAgentProvider(context); + const instructionsProvider = createInstructionsProvider(context); + const promptFileProvider = createPromptFileProvider(context); + + context.subscriptions.push( + vscode.chat.registerCustomAgentProvider(customAgentProvider), + vscode.chat.registerInstructionsProvider(instructionsProvider), + vscode.chat.registerPromptFileProvider(promptFileProvider) + ); + + console.log('Chat prompt files sample extension activated with dynamic providers!'); +} diff --git a/chat-prompt-files-sample/src/instructionsProvider.ts b/chat-prompt-files-sample/src/instructionsProvider.ts new file mode 100644 index 0000000000..e707931281 --- /dev/null +++ b/chat-prompt-files-sample/src/instructionsProvider.ts @@ -0,0 +1,64 @@ +import * as vscode from 'vscode'; + +export function createInstructionsProvider(_context: vscode.ExtensionContext): vscode.InstructionsProvider { + return { + async provideInstructions(_options, _token) { + const instructions: vscode.InstructionsResource[] = []; + + // Dynamic instructions with current workspace info + const dynamicContent = generateDynamicInstructions(); + + // Create an untitled document with the dynamic content + const doc = await vscode.workspace.openTextDocument({ + content: dynamicContent, + language: 'markdown' + }); + + instructions.push({ + name: 'workspace-context', + description: 'Dynamic workspace context and guidelines', + uri: doc.uri, + isEditable: false, + isCacheable: false + }); + + return instructions; + } + }; +} + +function generateDynamicInstructions(): string { + const workspaceFolders = vscode.workspace.workspaceFolders; + const activeEditor = vscode.window.activeTextEditor; + const currentFile = activeEditor?.document.fileName || 'none'; + const languageId = activeEditor?.document.languageId || 'none'; + + return `# Workspace Context Instructions + +These instructions are dynamically generated based on your current workspace state. + +## Current Context + +- **Active File**: ${currentFile} +- **Language**: ${languageId} +- **Workspace Folders**: ${workspaceFolders?.length || 0} +- **Timestamp**: ${new Date().toLocaleString()} + +## Guidelines + +When working with this workspace: + +1. Consider the current file context when providing suggestions +2. Use language-specific best practices for ${languageId} +3. Reference workspace structure when relevant +4. Keep code examples consistent with the project style + +## Dynamic Behavior + +These instructions update based on: +- Current active file +- Workspace configuration +- Time of day +- Available workspace folders +`; +} diff --git a/chat-prompt-files-sample/src/promptFileProvider.ts b/chat-prompt-files-sample/src/promptFileProvider.ts new file mode 100644 index 0000000000..9b1411bba9 --- /dev/null +++ b/chat-prompt-files-sample/src/promptFileProvider.ts @@ -0,0 +1,65 @@ +import * as vscode from 'vscode'; + +export function createPromptFileProvider(_context: vscode.ExtensionContext): vscode.PromptFileProvider { + return { + async providePromptFiles(_options, _token) { + const prompts: vscode.PromptFileResource[] = []; + + // Dynamic prompt with time-based content + const dynamicContent = generateDynamicPrompt(); + + // Create an untitled document with the dynamic content + const doc = await vscode.workspace.openTextDocument({ + content: dynamicContent, + language: 'markdown' + }); + + prompts.push({ + name: 'time-aware', + description: 'Dynamic prompt with current timestamp', + uri: doc.uri, + isEditable: false, + isCacheable: false + }); + + return prompts; + } + }; +} + +function generateDynamicPrompt(): string { + const now = new Date(); + const hour = now.getHours(); + const greeting = hour < 12 ? 'morning' : hour < 18 ? 'afternoon' : 'evening'; + const dayOfWeek = now.toLocaleDateString('en-US', { weekday: 'long' }); + + return `# Time-Aware Assistant Prompt + +Good ${greeting}! Today is ${dayOfWeek}. + +## Current Session Info + +- **Generated**: ${now.toLocaleString()} +- **Unix Timestamp**: ${now.getTime()} +- **ISO**: ${now.toISOString()} + +## Dynamic Behavior + +This prompt demonstrates dynamic content generation: + +### Time-Based Suggestions + +${hour < 12 ? '- Start your day with reviewing test coverage' : + hour < 18 ? '- Good time for implementing new features' : + '- Consider writing documentation or code reviews'} + +### Session Context + +This prompt was generated specifically for this chat session and includes: +- Current time context +- Session-specific metadata +- Dynamic suggestions based on time of day + +Use this prompt to see how content can change based on external factors. +`; +} diff --git a/chat-prompt-files-sample/tsconfig.json b/chat-prompt-files-sample/tsconfig.json new file mode 100644 index 0000000000..7fd0e59e7e --- /dev/null +++ b/chat-prompt-files-sample/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "ES2024", + "lib": [ + "ES2024" + ], + "outDir": "out", + "sourceMap": true, + "rootDir": "src", + "strict": true + }, + "exclude": [ + "node_modules", + ".vscode-test" + ] +} \ No newline at end of file From 4e8421a58829117d6588cb7a57cf6d78f9db65cf Mon Sep 17 00:00:00 2001 From: Paul Wang Date: Wed, 7 Jan 2026 14:51:29 -0800 Subject: [PATCH 2/8] update list --- .scripts/samples.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/.scripts/samples.ts b/.scripts/samples.ts index ebf934e908..238ecc4e45 100644 --- a/.scripts/samples.ts +++ b/.scripts/samples.ts @@ -295,6 +295,7 @@ export const samples: Sample[] = [ { description: 'configuration-sample', excludeFromReadme: true, path: 'configuration-sample', guide: null, apis: [], contributions: [] }, { description: 'chat-model-provider-sample', excludeFromReadme: true, path: 'chat-model-provider-sample', guide: null, apis: [], contributions: [] }, { description: 'chat-output-renderer-sample', excludeFromReadme: true, path: 'chat-output-renderer-sample', guide: null, apis: [], contributions: [] }, + { description: 'chat-prompt-files-sample', excludeFromReadme: true, path: 'chat-prompt-files-sample', guide: null, apis: [], contributions: ['chatPromptFiles', 'chatInstructions', 'chatAgents'] }, { description: 'contentprovider-sample', excludeFromReadme: true, path: 'contentprovider-sample', guide: null, apis: [], contributions: [] }, { description: 'diagnostic-related-information-sample', excludeFromReadme: true, path: 'diagnostic-related-information-sample', guide: null, apis: [], contributions: [] }, { description: 'document-paste', excludeFromReadme: true, path: 'document-paste', guide: null, apis: [], contributions: [] }, From 5f038b194eaf4b6c686f2de508e4004e1542b70c Mon Sep 17 00:00:00 2001 From: Paul Wang Date: Wed, 7 Jan 2026 16:41:32 -0800 Subject: [PATCH 3/8] use v2 --- chat-prompt-files-sample/package.json | 6 +++- .../src/customAgentProvider.ts | 25 ++++++--------- .../src/instructionsProvider.ts | 25 ++++++--------- .../src/promptFileProvider.ts | 31 +++++++------------ 4 files changed, 35 insertions(+), 52 deletions(-) diff --git a/chat-prompt-files-sample/package.json b/chat-prompt-files-sample/package.json index c3aa106d1b..26b0a876c5 100644 --- a/chat-prompt-files-sample/package.json +++ b/chat-prompt-files-sample/package.json @@ -22,6 +22,10 @@ "onPromptFileProvider" ], "main": "./out/extension.js", + "enabledApiProposals": [ + "chatPromptFiles", + "chatParticipantPrivate" + ], "contributes": { "chatPromptFiles": [ { @@ -54,4 +58,4 @@ "typescript": "^5.8.2", "typescript-eslint": "^8.26.0" } -} +} \ No newline at end of file diff --git a/chat-prompt-files-sample/src/customAgentProvider.ts b/chat-prompt-files-sample/src/customAgentProvider.ts index 5da8bb7fc7..d3d530b9f0 100644 --- a/chat-prompt-files-sample/src/customAgentProvider.ts +++ b/chat-prompt-files-sample/src/customAgentProvider.ts @@ -3,25 +3,18 @@ import * as vscode from 'vscode'; export function createCustomAgentProvider(_context: vscode.ExtensionContext): vscode.CustomAgentProvider { return { async provideCustomAgents(_options, _token) { - const agents: vscode.CustomAgentResource[] = []; - + const agents: vscode.CustomAgentChatResource[] = []; + // Dynamic agent with generated content const dynamicContent = generateDynamicAgentContent(); - - // Create an untitled document with the dynamic content - const doc = await vscode.workspace.openTextDocument({ - content: dynamicContent, - language: 'markdown' - }); - - agents.push({ + + agents.push(new vscode.CustomAgentChatResource({ name: 'workspace-helper', description: 'Dynamic agent with workspace statistics', - uri: doc.uri, - isEditable: false, - isCacheable: false // Don't cache because content is dynamic - }); - + body: dynamicContent, + isEditable: false + })); + return agents; } }; @@ -31,7 +24,7 @@ function generateDynamicAgentContent(): string { const workspaceFolders = vscode.workspace.workspaceFolders; const folderCount = workspaceFolders?.length || 0; const folderNames = workspaceFolders?.map(f => f.name).join(', ') || 'none'; - + return `# Workspace Helper Agent This is a dynamically generated agent that provides workspace-specific assistance. diff --git a/chat-prompt-files-sample/src/instructionsProvider.ts b/chat-prompt-files-sample/src/instructionsProvider.ts index e707931281..f45e54ed0b 100644 --- a/chat-prompt-files-sample/src/instructionsProvider.ts +++ b/chat-prompt-files-sample/src/instructionsProvider.ts @@ -3,25 +3,18 @@ import * as vscode from 'vscode'; export function createInstructionsProvider(_context: vscode.ExtensionContext): vscode.InstructionsProvider { return { async provideInstructions(_options, _token) { - const instructions: vscode.InstructionsResource[] = []; - + const instructions: vscode.InstructionsChatResource[] = []; + // Dynamic instructions with current workspace info const dynamicContent = generateDynamicInstructions(); - - // Create an untitled document with the dynamic content - const doc = await vscode.workspace.openTextDocument({ - content: dynamicContent, - language: 'markdown' - }); - - instructions.push({ + + instructions.push(new vscode.InstructionsChatResource({ name: 'workspace-context', description: 'Dynamic workspace context and guidelines', - uri: doc.uri, - isEditable: false, - isCacheable: false - }); - + body: dynamicContent, + isEditable: false + })); + return instructions; } }; @@ -32,7 +25,7 @@ function generateDynamicInstructions(): string { const activeEditor = vscode.window.activeTextEditor; const currentFile = activeEditor?.document.fileName || 'none'; const languageId = activeEditor?.document.languageId || 'none'; - + return `# Workspace Context Instructions These instructions are dynamically generated based on your current workspace state. diff --git a/chat-prompt-files-sample/src/promptFileProvider.ts b/chat-prompt-files-sample/src/promptFileProvider.ts index 9b1411bba9..8e68c0697d 100644 --- a/chat-prompt-files-sample/src/promptFileProvider.ts +++ b/chat-prompt-files-sample/src/promptFileProvider.ts @@ -3,25 +3,18 @@ import * as vscode from 'vscode'; export function createPromptFileProvider(_context: vscode.ExtensionContext): vscode.PromptFileProvider { return { async providePromptFiles(_options, _token) { - const prompts: vscode.PromptFileResource[] = []; - + const prompts: vscode.PromptFileChatResource[] = []; + // Dynamic prompt with time-based content const dynamicContent = generateDynamicPrompt(); - - // Create an untitled document with the dynamic content - const doc = await vscode.workspace.openTextDocument({ - content: dynamicContent, - language: 'markdown' - }); - - prompts.push({ + + prompts.push(new vscode.PromptFileChatResource({ name: 'time-aware', description: 'Dynamic prompt with current timestamp', - uri: doc.uri, - isEditable: false, - isCacheable: false - }); - + body: dynamicContent, + isEditable: false + })); + return prompts; } }; @@ -32,7 +25,7 @@ function generateDynamicPrompt(): string { const hour = now.getHours(); const greeting = hour < 12 ? 'morning' : hour < 18 ? 'afternoon' : 'evening'; const dayOfWeek = now.toLocaleDateString('en-US', { weekday: 'long' }); - + return `# Time-Aware Assistant Prompt Good ${greeting}! Today is ${dayOfWeek}. @@ -49,9 +42,9 @@ This prompt demonstrates dynamic content generation: ### Time-Based Suggestions -${hour < 12 ? '- Start your day with reviewing test coverage' : - hour < 18 ? '- Good time for implementing new features' : - '- Consider writing documentation or code reviews'} +${hour < 12 ? '- Start your day with reviewing test coverage' : + hour < 18 ? '- Good time for implementing new features' : + '- Consider writing documentation or code reviews'} ### Session Context From 4aa2e51aae76ad8f11be8c3f00ee4047c5e7df8e Mon Sep 17 00:00:00 2001 From: Paul Wang Date: Wed, 7 Jan 2026 17:27:40 -0800 Subject: [PATCH 4/8] clean --- chat-prompt-files-sample/package.json | 3 +-- .../src/customAgentProvider.ts | 12 ++++++------ chat-prompt-files-sample/src/extension.ts | 6 +++--- .../src/instructionsProvider.ts | 12 ++++++------ chat-prompt-files-sample/src/promptFileProvider.ts | 14 ++++++++------ 5 files changed, 24 insertions(+), 23 deletions(-) diff --git a/chat-prompt-files-sample/package.json b/chat-prompt-files-sample/package.json index 26b0a876c5..783fd260c6 100644 --- a/chat-prompt-files-sample/package.json +++ b/chat-prompt-files-sample/package.json @@ -23,8 +23,7 @@ ], "main": "./out/extension.js", "enabledApiProposals": [ - "chatPromptFiles", - "chatParticipantPrivate" + "chatPromptFiles" ], "contributes": { "chatPromptFiles": [ diff --git a/chat-prompt-files-sample/src/customAgentProvider.ts b/chat-prompt-files-sample/src/customAgentProvider.ts index d3d530b9f0..d2ec9f11b7 100644 --- a/chat-prompt-files-sample/src/customAgentProvider.ts +++ b/chat-prompt-files-sample/src/customAgentProvider.ts @@ -8,12 +8,12 @@ export function createCustomAgentProvider(_context: vscode.ExtensionContext): vs // Dynamic agent with generated content const dynamicContent = generateDynamicAgentContent(); - agents.push(new vscode.CustomAgentChatResource({ - name: 'workspace-helper', - description: 'Dynamic agent with workspace statistics', - body: dynamicContent, - isEditable: false - })); + agents.push(new vscode.CustomAgentChatResource( + 'workspace-helper', + 'Dynamic agent with workspace statistics', + { body: dynamicContent }, + { isEditable: false } + )); return agents; } diff --git a/chat-prompt-files-sample/src/extension.ts b/chat-prompt-files-sample/src/extension.ts index c4bb351282..097533458b 100644 --- a/chat-prompt-files-sample/src/extension.ts +++ b/chat-prompt-files-sample/src/extension.ts @@ -3,17 +3,17 @@ import { createCustomAgentProvider } from './customAgentProvider'; import { createInstructionsProvider } from './instructionsProvider'; import { createPromptFileProvider } from './promptFileProvider'; -export function activate(context: vscode.ExtensionContext) { +export async function activate(context: vscode.ExtensionContext) { // Create and register all providers const customAgentProvider = createCustomAgentProvider(context); const instructionsProvider = createInstructionsProvider(context); const promptFileProvider = createPromptFileProvider(context); - + context.subscriptions.push( vscode.chat.registerCustomAgentProvider(customAgentProvider), vscode.chat.registerInstructionsProvider(instructionsProvider), vscode.chat.registerPromptFileProvider(promptFileProvider) ); - + console.log('Chat prompt files sample extension activated with dynamic providers!'); } diff --git a/chat-prompt-files-sample/src/instructionsProvider.ts b/chat-prompt-files-sample/src/instructionsProvider.ts index f45e54ed0b..8bc2390a41 100644 --- a/chat-prompt-files-sample/src/instructionsProvider.ts +++ b/chat-prompt-files-sample/src/instructionsProvider.ts @@ -8,12 +8,12 @@ export function createInstructionsProvider(_context: vscode.ExtensionContext): v // Dynamic instructions with current workspace info const dynamicContent = generateDynamicInstructions(); - instructions.push(new vscode.InstructionsChatResource({ - name: 'workspace-context', - description: 'Dynamic workspace context and guidelines', - body: dynamicContent, - isEditable: false - })); + instructions.push(new vscode.InstructionsChatResource( + 'workspace-context', + 'Dynamic workspace context and guidelines', + { body: dynamicContent }, + { isEditable: false } + )); return instructions; } diff --git a/chat-prompt-files-sample/src/promptFileProvider.ts b/chat-prompt-files-sample/src/promptFileProvider.ts index 8e68c0697d..df9755106b 100644 --- a/chat-prompt-files-sample/src/promptFileProvider.ts +++ b/chat-prompt-files-sample/src/promptFileProvider.ts @@ -8,12 +8,14 @@ export function createPromptFileProvider(_context: vscode.ExtensionContext): vsc // Dynamic prompt with time-based content const dynamicContent = generateDynamicPrompt(); - prompts.push(new vscode.PromptFileChatResource({ - name: 'time-aware', - description: 'Dynamic prompt with current timestamp', - body: dynamicContent, - isEditable: false - })); + prompts.push( + new vscode.PromptFileChatResource( + 'time-aware', + 'Dynamic prompt with current timestamp', + { body: dynamicContent }, + { isEditable: false } + ) + ); return prompts; } From 7c181319f86238f69e4be971e0a1ba733d346330 Mon Sep 17 00:00:00 2001 From: Paul Wang Date: Thu, 8 Jan 2026 14:52:43 -0800 Subject: [PATCH 5/8] update --- .../src/customAgentProvider.ts | 10 ++++++++-- .../src/instructionsProvider.ts | 18 ++++++++++++------ .../src/promptFileProvider.ts | 10 ++++++++-- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/chat-prompt-files-sample/src/customAgentProvider.ts b/chat-prompt-files-sample/src/customAgentProvider.ts index d2ec9f11b7..6d8762486b 100644 --- a/chat-prompt-files-sample/src/customAgentProvider.ts +++ b/chat-prompt-files-sample/src/customAgentProvider.ts @@ -10,8 +10,14 @@ export function createCustomAgentProvider(_context: vscode.ExtensionContext): vs agents.push(new vscode.CustomAgentChatResource( 'workspace-helper', - 'Dynamic agent with workspace statistics', - { body: dynamicContent }, + { + header: { + name: 'Workspace Helper Agent', + description: 'An agent that provides assistance based on the current workspace context', + infer: false + }, + body: dynamicContent + }, { isEditable: false } )); diff --git a/chat-prompt-files-sample/src/instructionsProvider.ts b/chat-prompt-files-sample/src/instructionsProvider.ts index 8bc2390a41..f71d654334 100644 --- a/chat-prompt-files-sample/src/instructionsProvider.ts +++ b/chat-prompt-files-sample/src/instructionsProvider.ts @@ -8,12 +8,18 @@ export function createInstructionsProvider(_context: vscode.ExtensionContext): v // Dynamic instructions with current workspace info const dynamicContent = generateDynamicInstructions(); - instructions.push(new vscode.InstructionsChatResource( - 'workspace-context', - 'Dynamic workspace context and guidelines', - { body: dynamicContent }, - { isEditable: false } - )); + instructions.push( + new vscode.InstructionsChatResource('workspace-context', + { + header: { + name: 'Workspace Context Instructions', + description: 'Instructions tailored to the current workspace context', + applyTo: '**' + }, + body: dynamicContent + }, + { isEditable: false } + )); return instructions; } diff --git a/chat-prompt-files-sample/src/promptFileProvider.ts b/chat-prompt-files-sample/src/promptFileProvider.ts index df9755106b..0b8d54ffae 100644 --- a/chat-prompt-files-sample/src/promptFileProvider.ts +++ b/chat-prompt-files-sample/src/promptFileProvider.ts @@ -11,8 +11,14 @@ export function createPromptFileProvider(_context: vscode.ExtensionContext): vsc prompts.push( new vscode.PromptFileChatResource( 'time-aware', - 'Dynamic prompt with current timestamp', - { body: dynamicContent }, + { + header: { + name: 'Time-Aware Assistant Prompt', + description: 'A prompt that changes based on the current time and session context', + model: 'gpt-5.1' + }, + body: dynamicContent + }, { isEditable: false } ) ); From 1404da445c2f330ee4f4076d9e860d21a0b4d39b Mon Sep 17 00:00:00 2001 From: Paul Wang Date: Tue, 20 Jan 2026 13:06:53 -0800 Subject: [PATCH 6/8] update sample --- chat-prompt-files-sample/package.json | 13 +++- .../resources/code-review/SKILL.md | 34 +++++++++ .../src/customAgentProvider.ts | 17 ++--- chat-prompt-files-sample/src/extension.ts | 5 +- .../src/instructionsProvider.ts | 16 ++-- .../src/promptFileProvider.ts | 17 ++--- chat-prompt-files-sample/src/skillProvider.ts | 73 +++++++++++++++++++ 7 files changed, 136 insertions(+), 39 deletions(-) create mode 100644 chat-prompt-files-sample/resources/code-review/SKILL.md create mode 100644 chat-prompt-files-sample/src/skillProvider.ts diff --git a/chat-prompt-files-sample/package.json b/chat-prompt-files-sample/package.json index 783fd260c6..fca00eb5a7 100644 --- a/chat-prompt-files-sample/package.json +++ b/chat-prompt-files-sample/package.json @@ -3,7 +3,7 @@ "displayName": "chat-prompt-files-sample", "description": "Sample demonstrating how to contribute chat prompt files, instructions, and agents in a VS Code extension.", "version": "0.0.1", - "publisher": "vscode-samples", + "publisher": "vscode-sam2ples", "private": true, "license": "MIT", "repository": { @@ -19,7 +19,8 @@ "activationEvents": [ "onCustomAgentProvider", "onInstructionsProvider", - "onPromptFileProvider" + "onPromptFileProvider", + "onSkillProvider" ], "main": "./out/extension.js", "enabledApiProposals": [ @@ -40,13 +41,19 @@ { "path": "./resources/vscode-extension.agent.md" } + ], + "chatSkills": [ + { + "path": "./resources/code-review/SKILL.md" + } ] }, "scripts": { "vscode:prepublish": "npm run compile", "compile": "tsc -p ./", "lint": "eslint", - "watch": "tsc -watch -p ./" + "watch": "tsc -watch -p ./", + "package": "vsce package" }, "devDependencies": { "@eslint/js": "^9.13.0", diff --git a/chat-prompt-files-sample/resources/code-review/SKILL.md b/chat-prompt-files-sample/resources/code-review/SKILL.md new file mode 100644 index 0000000000..0fca5b8837 --- /dev/null +++ b/chat-prompt-files-sample/resources/code-review/SKILL.md @@ -0,0 +1,34 @@ +--- +name: code-review +description: A skill for performing code reviews and providing feedback on code quality +--- + +# Code Review Skill + +This skill provides capabilities for reviewing code and providing constructive feedback. + +## Capabilities + +- Review code for best practices +- Identify potential bugs and issues +- Suggest improvements for readability +- Check for security vulnerabilities +- Evaluate test coverage + +## Guidelines + +When performing code reviews: + +1. Be constructive and specific in feedback +2. Explain the reasoning behind suggestions +3. Prioritize issues by severity +4. Acknowledge good patterns when found +5. Consider the context and constraints + +## Review Checklist + +- [ ] Code follows project conventions +- [ ] Error handling is appropriate +- [ ] Edge cases are considered +- [ ] Code is readable and maintainable +- [ ] Tests cover critical paths diff --git a/chat-prompt-files-sample/src/customAgentProvider.ts b/chat-prompt-files-sample/src/customAgentProvider.ts index 6d8762486b..a2f2b2dd3c 100644 --- a/chat-prompt-files-sample/src/customAgentProvider.ts +++ b/chat-prompt-files-sample/src/customAgentProvider.ts @@ -2,24 +2,17 @@ import * as vscode from 'vscode'; export function createCustomAgentProvider(_context: vscode.ExtensionContext): vscode.CustomAgentProvider { return { + label: 'Dynamic Workspace Agent Provider', async provideCustomAgents(_options, _token) { const agents: vscode.CustomAgentChatResource[] = []; // Dynamic agent with generated content const dynamicContent = generateDynamicAgentContent(); - agents.push(new vscode.CustomAgentChatResource( - 'workspace-helper', - { - header: { - name: 'Workspace Helper Agent', - description: 'An agent that provides assistance based on the current workspace context', - infer: false - }, - body: dynamicContent - }, - { isEditable: false } - )); + agents.push(new vscode.CustomAgentChatResource({ + id: 'workspace-helper', + content: dynamicContent + })); return agents; } diff --git a/chat-prompt-files-sample/src/extension.ts b/chat-prompt-files-sample/src/extension.ts index 097533458b..19adf8b510 100644 --- a/chat-prompt-files-sample/src/extension.ts +++ b/chat-prompt-files-sample/src/extension.ts @@ -2,17 +2,20 @@ import * as vscode from 'vscode'; import { createCustomAgentProvider } from './customAgentProvider'; import { createInstructionsProvider } from './instructionsProvider'; import { createPromptFileProvider } from './promptFileProvider'; +import { createSkillProvider } from './skillProvider'; export async function activate(context: vscode.ExtensionContext) { // Create and register all providers const customAgentProvider = createCustomAgentProvider(context); const instructionsProvider = createInstructionsProvider(context); const promptFileProvider = createPromptFileProvider(context); + const skillProvider = createSkillProvider(context); context.subscriptions.push( vscode.chat.registerCustomAgentProvider(customAgentProvider), vscode.chat.registerInstructionsProvider(instructionsProvider), - vscode.chat.registerPromptFileProvider(promptFileProvider) + vscode.chat.registerPromptFileProvider(promptFileProvider), + vscode.chat.registerSkillProvider(skillProvider) ); console.log('Chat prompt files sample extension activated with dynamic providers!'); diff --git a/chat-prompt-files-sample/src/instructionsProvider.ts b/chat-prompt-files-sample/src/instructionsProvider.ts index f71d654334..b319f20033 100644 --- a/chat-prompt-files-sample/src/instructionsProvider.ts +++ b/chat-prompt-files-sample/src/instructionsProvider.ts @@ -2,6 +2,7 @@ import * as vscode from 'vscode'; export function createInstructionsProvider(_context: vscode.ExtensionContext): vscode.InstructionsProvider { return { + label: 'Dynamic Workspace Instructions Provider', async provideInstructions(_options, _token) { const instructions: vscode.InstructionsChatResource[] = []; @@ -9,17 +10,10 @@ export function createInstructionsProvider(_context: vscode.ExtensionContext): v const dynamicContent = generateDynamicInstructions(); instructions.push( - new vscode.InstructionsChatResource('workspace-context', - { - header: { - name: 'Workspace Context Instructions', - description: 'Instructions tailored to the current workspace context', - applyTo: '**' - }, - body: dynamicContent - }, - { isEditable: false } - )); + new vscode.InstructionsChatResource({ + id: 'workspace-context', + content: dynamicContent + })); return instructions; } diff --git a/chat-prompt-files-sample/src/promptFileProvider.ts b/chat-prompt-files-sample/src/promptFileProvider.ts index 0b8d54ffae..7e7884bab5 100644 --- a/chat-prompt-files-sample/src/promptFileProvider.ts +++ b/chat-prompt-files-sample/src/promptFileProvider.ts @@ -2,6 +2,7 @@ import * as vscode from 'vscode'; export function createPromptFileProvider(_context: vscode.ExtensionContext): vscode.PromptFileProvider { return { + label: 'Dynamic Time-Aware Prompt File Provider', async providePromptFiles(_options, _token) { const prompts: vscode.PromptFileChatResource[] = []; @@ -9,18 +10,10 @@ export function createPromptFileProvider(_context: vscode.ExtensionContext): vsc const dynamicContent = generateDynamicPrompt(); prompts.push( - new vscode.PromptFileChatResource( - 'time-aware', - { - header: { - name: 'Time-Aware Assistant Prompt', - description: 'A prompt that changes based on the current time and session context', - model: 'gpt-5.1' - }, - body: dynamicContent - }, - { isEditable: false } - ) + new vscode.PromptFileChatResource({ + id: 'time-aware', + content: dynamicContent + }) ); return prompts; diff --git a/chat-prompt-files-sample/src/skillProvider.ts b/chat-prompt-files-sample/src/skillProvider.ts new file mode 100644 index 0000000000..c904aa26d1 --- /dev/null +++ b/chat-prompt-files-sample/src/skillProvider.ts @@ -0,0 +1,73 @@ +import * as vscode from 'vscode'; + +export function createSkillProvider(_context: vscode.ExtensionContext): vscode.SkillProvider { + return { + label: 'Dynamic Workspace Skills Provider', + async provideSkills(_options, _token) { + const skills: vscode.SkillChatResource[] = []; + + // Dynamic skill with generated content + const dynamicContent = generateDynamicSkillContent(); + + skills.push(new vscode.SkillChatResource({ + id: 'workspace-analysis', + content: dynamicContent + })); + + return skills; + } + }; +} + +function generateDynamicSkillContent(): string { + const workspaceFolders = vscode.workspace.workspaceFolders; + const folderCount = workspaceFolders?.length || 0; + const folderNames = workspaceFolders?.map(f => f.name).join(', ') || 'none'; + + return `--- +name: workspace-analysis +description: A skill for analyzing and understanding the current workspace. +--- +# Workspace Analysis Skill + +This skill provides capabilities for analyzing and understanding the current workspace. + +## Skill Information + +- **Workspace Folders**: ${folderCount} +- **Folder Names**: ${folderNames} +- **Generated At**: ${new Date().toISOString()} + +## Capabilities + +This skill enables the following capabilities: + +### Code Analysis +- Analyze code structure and patterns +- Identify potential improvements +- Detect code smells and anti-patterns + +### Workspace Navigation +- Find relevant files based on context +- Navigate between related components +- Understand project organization + +### Documentation Generation +- Generate documentation for code +- Create README files +- Document APIs and interfaces + +## Usage + +When this skill is active, the assistant can: + +1. Analyze the structure of your codebase +2. Provide insights about code organization +3. Suggest improvements based on best practices +4. Help navigate complex project structures + +## Notes + +This skill is dynamically generated and reflects the current state of your workspace. +`; +} From 23b418cdf9175ca54db551d005cab43ccaf48674 Mon Sep 17 00:00:00 2001 From: Paul Wang Date: Tue, 20 Jan 2026 14:47:18 -0800 Subject: [PATCH 7/8] fix --- chat-prompt-files-sample/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chat-prompt-files-sample/package.json b/chat-prompt-files-sample/package.json index fca00eb5a7..98dfb391a0 100644 --- a/chat-prompt-files-sample/package.json +++ b/chat-prompt-files-sample/package.json @@ -3,7 +3,7 @@ "displayName": "chat-prompt-files-sample", "description": "Sample demonstrating how to contribute chat prompt files, instructions, and agents in a VS Code extension.", "version": "0.0.1", - "publisher": "vscode-sam2ples", + "publisher": "vscode-samples", "private": true, "license": "MIT", "repository": { From d65f1e64c343cd8696d3797963c80624bc3ace0b Mon Sep 17 00:00:00 2001 From: Paul Wang Date: Wed, 21 Jan 2026 10:07:04 -0800 Subject: [PATCH 8/8] update --- .../src/chatResourceFileSystem.ts | 104 ++++++++++++++++++ .../src/customAgentProvider.ts | 21 ++-- .../src/instructionsProvider.ts | 22 ++-- .../src/promptFileProvider.ts | 23 ++-- chat-prompt-files-sample/src/skillProvider.ts | 21 ++-- 5 files changed, 136 insertions(+), 55 deletions(-) create mode 100644 chat-prompt-files-sample/src/chatResourceFileSystem.ts diff --git a/chat-prompt-files-sample/src/chatResourceFileSystem.ts b/chat-prompt-files-sample/src/chatResourceFileSystem.ts new file mode 100644 index 0000000000..77fa337d3c --- /dev/null +++ b/chat-prompt-files-sample/src/chatResourceFileSystem.ts @@ -0,0 +1,104 @@ +import * as vscode from 'vscode'; + +/** + * A virtual file system provider for serving dynamically generated chat resource content. + * Resources are registered with a URI and content generator function, allowing + * content to be generated on-demand when VS Code reads the file. + */ +export class ChatResourceFileSystemProvider implements vscode.FileSystemProvider { + static readonly scheme = 'my-chat-resource'; + + private readonly _contentGenerators = new Map string>(); + private readonly _onDidChangeFile = new vscode.EventEmitter(); + readonly onDidChangeFile = this._onDidChangeFile.event; + + /** + * Register a resource with a content generator function. + * @param path The path portion of the URI (e.g., 'agents/workspace-helper.agent.md') + * @param contentGenerator A function that generates the content on demand + * @returns The full URI for the resource + */ + registerResource(path: string, contentGenerator: () => string): vscode.Uri { + this._contentGenerators.set(path, contentGenerator); + return vscode.Uri.parse(`${ChatResourceFileSystemProvider.scheme}:/${path}`); + } + + /** + * Notify that a resource has changed, triggering VS Code to re-read the content. + * @param path The path of the resource that changed + */ + notifyResourceChanged(path: string): void { + const uri = vscode.Uri.parse(`${ChatResourceFileSystemProvider.scheme}:/${path}`); + this._onDidChangeFile.fire([{ type: vscode.FileChangeType.Changed, uri }]); + } + + // FileSystemProvider implementation + + watch(): vscode.Disposable { + return new vscode.Disposable(() => { }); + } + + stat(uri: vscode.Uri): vscode.FileStat { + const path = uri.path.substring(1); // Remove leading / + if (!this._contentGenerators.has(path)) { + throw vscode.FileSystemError.FileNotFound(uri); + } + return { + type: vscode.FileType.File, + ctime: Date.now(), + mtime: Date.now(), + size: 0 // Size is not known until content is generated + }; + } + + readDirectory(): [string, vscode.FileType][] { + return []; + } + + createDirectory(): void { + throw vscode.FileSystemError.NoPermissions('Read-only file system'); + } + + readFile(uri: vscode.Uri): Uint8Array { + const path = uri.path.substring(1); // Remove leading / + const generator = this._contentGenerators.get(path); + if (!generator) { + throw vscode.FileSystemError.FileNotFound(uri); + } + const content = generator(); + return new TextEncoder().encode(content); + } + + writeFile(): void { + throw vscode.FileSystemError.NoPermissions('Read-only file system'); + } + + delete(): void { + throw vscode.FileSystemError.NoPermissions('Read-only file system'); + } + + rename(): void { + throw vscode.FileSystemError.NoPermissions('Read-only file system'); + } +} + +// Singleton instance +let _instance: ChatResourceFileSystemProvider | undefined; + +/** + * Get the singleton ChatResourceFileSystemProvider instance. + * Creates and registers it if it doesn't exist. + */ +export function getChatResourceFileSystem(context: vscode.ExtensionContext): ChatResourceFileSystemProvider { + if (!_instance) { + _instance = new ChatResourceFileSystemProvider(); + context.subscriptions.push( + vscode.workspace.registerFileSystemProvider( + ChatResourceFileSystemProvider.scheme, + _instance, + { isReadonly: true } + ) + ); + } + return _instance; +} diff --git a/chat-prompt-files-sample/src/customAgentProvider.ts b/chat-prompt-files-sample/src/customAgentProvider.ts index a2f2b2dd3c..eb438d54a3 100644 --- a/chat-prompt-files-sample/src/customAgentProvider.ts +++ b/chat-prompt-files-sample/src/customAgentProvider.ts @@ -1,20 +1,15 @@ import * as vscode from 'vscode'; +import { getChatResourceFileSystem } from './chatResourceFileSystem'; -export function createCustomAgentProvider(_context: vscode.ExtensionContext): vscode.CustomAgentProvider { - return { - label: 'Dynamic Workspace Agent Provider', - async provideCustomAgents(_options, _token) { - const agents: vscode.CustomAgentChatResource[] = []; - - // Dynamic agent with generated content - const dynamicContent = generateDynamicAgentContent(); +const AGENT_PATH = 'agents/workspace-helper.agent.md'; - agents.push(new vscode.CustomAgentChatResource({ - id: 'workspace-helper', - content: dynamicContent - })); +export function createCustomAgentProvider(context: vscode.ExtensionContext): vscode.ChatCustomAgentProvider { + const fs = getChatResourceFileSystem(context); + const agentUri = fs.registerResource(AGENT_PATH, generateDynamicAgentContent); - return agents; + return { + async provideCustomAgents(_context, _token): Promise { + return [{ uri: agentUri }]; } }; } diff --git a/chat-prompt-files-sample/src/instructionsProvider.ts b/chat-prompt-files-sample/src/instructionsProvider.ts index b319f20033..5047fe39b9 100644 --- a/chat-prompt-files-sample/src/instructionsProvider.ts +++ b/chat-prompt-files-sample/src/instructionsProvider.ts @@ -1,21 +1,15 @@ import * as vscode from 'vscode'; +import { getChatResourceFileSystem } from './chatResourceFileSystem'; -export function createInstructionsProvider(_context: vscode.ExtensionContext): vscode.InstructionsProvider { - return { - label: 'Dynamic Workspace Instructions Provider', - async provideInstructions(_options, _token) { - const instructions: vscode.InstructionsChatResource[] = []; - - // Dynamic instructions with current workspace info - const dynamicContent = generateDynamicInstructions(); +const INSTRUCTIONS_PATH = 'instructions/workspace-context.instructions.md'; - instructions.push( - new vscode.InstructionsChatResource({ - id: 'workspace-context', - content: dynamicContent - })); +export function createInstructionsProvider(context: vscode.ExtensionContext): vscode.ChatInstructionsProvider { + const fs = getChatResourceFileSystem(context); + const instructionsUri = fs.registerResource(INSTRUCTIONS_PATH, generateDynamicInstructions); - return instructions; + return { + async provideInstructions(_context, _token): Promise { + return [{ uri: instructionsUri }]; } }; } diff --git a/chat-prompt-files-sample/src/promptFileProvider.ts b/chat-prompt-files-sample/src/promptFileProvider.ts index 7e7884bab5..8aeed018a3 100644 --- a/chat-prompt-files-sample/src/promptFileProvider.ts +++ b/chat-prompt-files-sample/src/promptFileProvider.ts @@ -1,22 +1,15 @@ import * as vscode from 'vscode'; +import { getChatResourceFileSystem } from './chatResourceFileSystem'; -export function createPromptFileProvider(_context: vscode.ExtensionContext): vscode.PromptFileProvider { - return { - label: 'Dynamic Time-Aware Prompt File Provider', - async providePromptFiles(_options, _token) { - const prompts: vscode.PromptFileChatResource[] = []; - - // Dynamic prompt with time-based content - const dynamicContent = generateDynamicPrompt(); +const PROMPT_PATH = 'prompts/time-aware.prompt.md'; - prompts.push( - new vscode.PromptFileChatResource({ - id: 'time-aware', - content: dynamicContent - }) - ); +export function createPromptFileProvider(context: vscode.ExtensionContext): vscode.ChatPromptFileProvider { + const fs = getChatResourceFileSystem(context); + const promptUri = fs.registerResource(PROMPT_PATH, generateDynamicPrompt); - return prompts; + return { + async providePromptFiles(_context, _token): Promise { + return [{ uri: promptUri }]; } }; } diff --git a/chat-prompt-files-sample/src/skillProvider.ts b/chat-prompt-files-sample/src/skillProvider.ts index c904aa26d1..fc03817d24 100644 --- a/chat-prompt-files-sample/src/skillProvider.ts +++ b/chat-prompt-files-sample/src/skillProvider.ts @@ -1,20 +1,15 @@ import * as vscode from 'vscode'; +import { getChatResourceFileSystem } from './chatResourceFileSystem'; -export function createSkillProvider(_context: vscode.ExtensionContext): vscode.SkillProvider { - return { - label: 'Dynamic Workspace Skills Provider', - async provideSkills(_options, _token) { - const skills: vscode.SkillChatResource[] = []; - - // Dynamic skill with generated content - const dynamicContent = generateDynamicSkillContent(); +const SKILL_PATH = 'skills/workspace-analysis/SKILL.md'; - skills.push(new vscode.SkillChatResource({ - id: 'workspace-analysis', - content: dynamicContent - })); +export function createSkillProvider(context: vscode.ExtensionContext): vscode.ChatSkillProvider { + const fs = getChatResourceFileSystem(context); + const skillUri = fs.registerResource(SKILL_PATH, generateDynamicSkillContent); - return skills; + return { + async provideSkills(_context, _token): Promise { + return [{ uri: skillUri }]; } }; }