44 Commits

Author SHA1 Message Date
andrepimenta
88a2ba71a1 Add permission text 2025-07-09 02:19:50 +01:00
andrepimenta
717284a979 Let user chose yolo mode when there is an error with permissions 2025-07-09 01:59:39 +01:00
andrepimenta
d9baf71e4a Use fs watch instead of polling 2025-07-09 01:36:24 +01:00
andrepimenta
bad8c9a0a8 yolo mode warning 2025-07-09 01:28:43 +01:00
andrepimenta
2e4c866da2 Yolo mode init 2025-07-09 00:32:38 +01:00
andrepimenta
1fa94b9c54 Ability to add permission 2025-07-09 00:19:14 +01:00
andrepimenta
3ec983188a Settings UI for permissions 2025-07-08 23:57:38 +01:00
andrepimenta
0b98538903 permission button ui 2025-07-08 23:32:55 +01:00
andrepimenta
44166defce check commands that make sense to use wildcards 2025-07-08 23:20:50 +01:00
andrepimenta
ddf83cf760 Nice always allow ui 2025-07-08 22:51:52 +01:00
andrepimenta
63acf5e7f9 Always allow 2025-07-08 22:29:57 +01:00
andrepimenta
ede4fbaf98 Permission UI 2025-07-08 22:01:33 +01:00
andrepimenta
06eb335f7b initial implementation 2025-07-08 21:04:10 +01:00
andrepimenta
f501d2ddc4 Move images to .claude folder 2025-07-08 13:16:24 +01:00
andrepimenta
586b004273 Enable sidebar view 2025-07-08 12:48:15 +01:00
andrepimenta
b2579ed0f8 Plan mode only for current message fix 2025-07-07 23:41:34 +01:00
andrepimenta
0bdb0ce30a Allow copy paste images and screenshots 2025-07-07 23:23:27 +01:00
andrepimenta
bb20bb29c5 Display unix time when message is Claude AI usage limit reached 2025-07-07 22:39:39 +01:00
Andre Pimenta
5a59d67021 Merge pull request #38 from tonydehnke/patch-2
fix/Update README.md - Fix Issues Link
2025-07-07 21:38:21 +01:00
Tony Dehnke
7649c9aaab Update README.md - Fix Issues Link
Fix Support - Issues Link so it goes the repo correctly.

https://github.com/andrepimenta/claude-code-chat/issues
2025-07-01 14:32:43 +02:00
andrepimenta
2d3c12ca38 Update expand UI 2025-06-24 22:58:35 +01:00
andrepimenta
c5486c6e26 Write UI 2025-06-24 22:45:58 +01:00
andrepimenta
5168aa0333 changelog 2025-06-24 18:00:02 +01:00
andrepimenta
581ad59ea2 Fix thinking 2025-06-24 17:57:42 +01:00
andrepimenta
4c57af4141 MultiEdit UI 2025-06-24 17:40:55 +01:00
andrepimenta
64767e3850 Update ui-styles.ts 2025-06-24 04:15:47 +01:00
andrepimenta
be8be4c700 Click on file container to open it 2025-06-24 03:46:44 +01:00
andrepimenta
f603b4a298 No completed messages 2025-06-24 03:43:53 +01:00
andrepimenta
e6bdc80946 Better colors 2025-06-24 03:42:22 +01:00
andrepimenta
dcd49458cb Label Todos 2025-06-24 03:36:15 +01:00
andrepimenta
0129cd1bc9 Changed to claude is working 2025-06-24 03:28:12 +01:00
andrepimenta
6dfdc24500 Hide result message for Read and Edit 2025-06-24 03:18:52 +01:00
andrepimenta
e97062ae03 File name better 2025-06-24 02:53:54 +01:00
andrepimenta
8b0bc2904b Diff preview 2025-06-24 02:39:00 +01:00
andrepimenta
bc7fa07e3a Update README 2025-06-24 02:19:36 +01:00
andrepimenta
cd2b563be4 Show WSL alert for windows users 2025-06-24 01:59:24 +01:00
andrepimenta
4bab912554 Thinking modal confirm button 2025-06-24 00:06:22 +01:00
andrepimenta
c3645e5d6b Update thinking mode switch name 2025-06-23 23:58:12 +01:00
andrepimenta
3bd35f0685 Change thinking mode modal to when it is enabled 2025-06-23 23:52:25 +01:00
andrepimenta
a1c2e6d139 Start new session when WSL config changes 2025-06-23 23:33:42 +01:00
andrepimenta
e6681c4ae1 Fix wsl commands 2025-06-23 23:28:11 +01:00
andrepimenta
300e569c96 Fix italic formatting 2025-06-21 00:58:24 +01:00
andrepimenta
cedde172bf version 2025-06-21 00:44:28 +01:00
andrepimenta
1dca03a3ec Always show new session button 2025-06-21 00:39:53 +01:00
10 changed files with 3698 additions and 327 deletions

View File

@@ -9,3 +9,4 @@ vsc-extension-quickstart.md
**/*.map
**/*.ts
**/.vscode-test.*
backup

View File

@@ -4,6 +4,56 @@ All notable changes to the "claude-code-chat" extension will be documented in th
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
## [0.1.3] - 2025-06-24
### 🚀 Features Added
#### **MultiEdit and Edit Tool Diff Display**
- Added comprehensive diff visualization for MultiEdit tool operations
- Shows file path with click-to-open functionality
- Displays multiple edits with numbered labels (Edit #1, Edit #2, etc.)
- Smart truncation handling - shows complete edits within line limits
- Expandable interface with "Show X more edits" button
- Visual separators between individual edits
- Consistent styling with existing Edit tool diff display
#### **Enhanced Tool Result Management**
- Added MultiEdit to hidden tool results list for cleaner interface
- Tool results for Read, Edit, TodoWrite, and MultiEdit now show loading states instead of uninteresting success messages
- Improved user experience by hiding redundant "Tool executed successfully" messages
### 🎨 UI/UX Improvements
#### **Thinking Intensity Modal Enhancement**
- Fixed bug where thinking mode toggle text changed before user confirmation
- Toggle text now only updates when user clicks "Confirm" button
- Preview selection highlighting still works during option exploration
- Improved user experience with proper confirmation workflow
#### **Consistent Message Spacing**
- Standardized spacing between tool messages and user/Claude messages
- Updated tool input padding from 12px to 8px to match message spacing
- Unified visual consistency across all message types
#### **Refined Visual Design**
- Changed MultiEdit edit number labels from purple to subtle professional styling
- Used VS Code theme colors for better integration
- Improved overall visual cohesion with more sober color palette
### 🔧 Technical Improvements
- Enhanced tool message formatting infrastructure
- Improved diff rendering performance for multiple edits
- Better error handling for malformed MultiEdit tool inputs
- Optimized truncation logic for complex multi-edit operations
## [0.1.2] - 2025-06-20
### 🐛 Bug Fixes
- Fixed markdown parsing bug where underscores in code identifiers (like "protein_id") were incorrectly converted to italic formatting
- Updated regex pattern to only apply italic formatting when underscores are surrounded by whitespace or at string boundaries
- Preserved proper formatting for code snippets and technical identifiers
- Always show New Chat button
## [0.1.0] - 2025-06-20
### 🚀 Major Features Added

View File

@@ -17,11 +17,11 @@ Ditch the command line and experience Claude Code like never before. This extens
🖥️ **No Terminal Required** - Beautiful chat interface replaces command-line interactions
**Restore Checkpoints** - Undo changes and restore code to any previous state
💾 **Conversation History** - Automatic conversation history and session management
**Instant Access** - Claude Code integrated directly into VS Code
🎨 **VS Code Native** - Seamlessly matches your editor's theme and design
📁 **Smart File Context** - Reference any file with simple @ mentions
🛑 **Full Control** - Start, stop, and manage AI processes with ease
🎨 **VS Code Native** - Claude Code integrated directly into VS Code with native theming
🧠 **Plan and Thinking modes** - Plan First and configurable Thinking modes for better results
**Smart File Context and Commands** - Reference any file with simple @ mentions and / for commands
🤖 **Model Selection** - Choose between Opus, Sonnet, or Default based on your needs
🐧 **WSL Support** - Full Windows Subsystem for Linux integration and compatibility
![Claude Code Chat Cut](https://github.com/user-attachments/assets/d4ded28f-a4ed-4862-9766-c1ff89947775)
@@ -296,7 +296,7 @@ See the [LICENSE](LICENSE) file for details.
Need help? We've got you covered:
- 🐛 **Issues**: [GitHub Issues](https://github.com/your-repo/claude-code-chat/issues)
- 🐛 **Issues**: [GitHub Issues](https://github.com/andrepimenta/claude-code-chat/issues)
---

729
package-lock.json generated
View File

@@ -1,27 +1,29 @@
{
"name": "claude-code-chat",
"version": "0.0.8",
"version": "0.1.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "claude-code-chat",
"version": "0.0.8",
"version": "0.1.3",
"license": "SEE LICENSE IN LICENSE",
"devDependencies": {
"@modelcontextprotocol/sdk": "^1.15.0",
"@types/mocha": "^10.0.10",
"@types/node": "20.x",
"@types/vscode": "^1.95.0",
"@types/vscode": "^1.94.0",
"@typescript-eslint/eslint-plugin": "^8.31.1",
"@typescript-eslint/parser": "^8.31.1",
"@vscode/test-cli": "^0.0.10",
"@vscode/test-electron": "^2.5.2",
"@vscode/vsce": "^3.5.0",
"eslint": "^9.25.1",
"typescript": "^5.8.3"
"typescript": "^5.8.3",
"zod": "^3.25.76"
},
"engines": {
"vscode": "^1.95.0"
"vscode": "^1.94.0"
}
},
"node_modules/@azu/format-text": {
@@ -556,6 +558,30 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@modelcontextprotocol/sdk": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.15.0.tgz",
"integrity": "sha512-67hnl/ROKdb03Vuu0YOr+baKTvf1/5YBHBm9KnZdjdAh8hjt4FRCPD5ucwxGB237sBpzlqQsLy1PFu7z/ekZ9Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"ajv": "^6.12.6",
"content-type": "^1.0.5",
"cors": "^2.8.5",
"cross-spawn": "^7.0.5",
"eventsource": "^3.0.2",
"eventsource-parser": "^3.0.0",
"express": "^5.0.1",
"express-rate-limit": "^7.5.0",
"pkce-challenge": "^5.0.0",
"raw-body": "^3.0.0",
"zod": "^3.23.8",
"zod-to-json-schema": "^3.24.1"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -978,9 +1004,9 @@
"dev": true
},
"node_modules/@types/vscode": {
"version": "1.100.0",
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.100.0.tgz",
"integrity": "sha512-4uNyvzHoraXEeCamR3+fzcBlh7Afs4Ifjs4epINyUX/jvdk0uzLnwiDY35UKDKnkCHP5Nu3dljl2H8lR6s+rQw==",
"version": "1.101.0",
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.101.0.tgz",
"integrity": "sha512-ZWf0IWa+NGegdW3iU42AcDTFHWW7fApLdkdnBqwYEtHVIBGbTu0ZNQKP/kX3Ds/uMJXIMQNAojHR4vexCEEz5Q==",
"dev": true,
"license": "MIT"
},
@@ -1513,6 +1539,43 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/accepts": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
"integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
"dev": true,
"license": "MIT",
"dependencies": {
"mime-types": "^3.0.0",
"negotiator": "^1.0.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/accepts/node_modules/mime-db": {
"version": "1.54.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/accepts/node_modules/mime-types": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
"integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
"dev": true,
"license": "MIT",
"dependencies": {
"mime-db": "^1.54.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/acorn": {
"version": "8.14.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
@@ -1771,6 +1834,27 @@
"node": ">= 6"
}
},
"node_modules/body-parser": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
"integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
"dev": true,
"license": "MIT",
"dependencies": {
"bytes": "^3.1.2",
"content-type": "^1.0.5",
"debug": "^4.4.0",
"http-errors": "^2.0.0",
"iconv-lite": "^0.6.3",
"on-finished": "^2.4.1",
"qs": "^6.14.0",
"raw-body": "^3.0.0",
"type-is": "^2.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
@@ -1868,6 +1952,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/c8": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/c8/-/c8-9.1.0.tgz",
@@ -2223,6 +2317,50 @@
"dev": true,
"license": "MIT"
},
"node_modules/content-disposition": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
"integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
"dev": true,
"license": "MIT",
"dependencies": {
"safe-buffer": "5.2.1"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/content-disposition/node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
},
"node_modules/content-type": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/convert-source-map": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
@@ -2230,6 +2368,26 @@
"dev": true,
"license": "MIT"
},
"node_modules/cookie": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie-signature": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
"integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.6.0"
}
},
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
@@ -2237,6 +2395,20 @@
"dev": true,
"license": "MIT"
},
"node_modules/cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"dev": true,
"license": "MIT",
"dependencies": {
"object-assign": "^4",
"vary": "^1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -2393,6 +2565,16 @@
"node": ">=0.4.0"
}
},
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/detect-libc": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
@@ -2513,6 +2695,13 @@
"url": "https://bevry.me/fund"
}
},
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
"dev": true,
"license": "MIT"
},
"node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
@@ -2520,6 +2709,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/encoding-sniffer": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz",
@@ -2633,6 +2832,13 @@
"node": ">=6"
}
},
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
"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",
@@ -2887,6 +3093,39 @@
"node": ">=0.10.0"
}
},
"node_modules/etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/eventsource": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
"integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==",
"dev": true,
"license": "MIT",
"dependencies": {
"eventsource-parser": "^3.0.1"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/eventsource-parser": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.3.tgz",
"integrity": "sha512-nVpZkTMM9rF6AQ9gPJpFsNAMt48wIzB5TQgiTLdHiuO8XEDhUgZEhqKlZWXbIzo9VmJ/HvysHqEaVeD5v9TPvA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/expand-template": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
@@ -2897,6 +3136,88 @@
"node": ">=6"
}
},
"node_modules/express": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
"integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
"dev": true,
"license": "MIT",
"dependencies": {
"accepts": "^2.0.0",
"body-parser": "^2.2.0",
"content-disposition": "^1.0.0",
"content-type": "^1.0.5",
"cookie": "^0.7.1",
"cookie-signature": "^1.2.1",
"debug": "^4.4.0",
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"etag": "^1.8.1",
"finalhandler": "^2.1.0",
"fresh": "^2.0.0",
"http-errors": "^2.0.0",
"merge-descriptors": "^2.0.0",
"mime-types": "^3.0.0",
"on-finished": "^2.4.1",
"once": "^1.4.0",
"parseurl": "^1.3.3",
"proxy-addr": "^2.0.7",
"qs": "^6.14.0",
"range-parser": "^1.2.1",
"router": "^2.2.0",
"send": "^1.1.0",
"serve-static": "^2.2.0",
"statuses": "^2.0.1",
"type-is": "^2.0.1",
"vary": "^1.1.2"
},
"engines": {
"node": ">= 18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/express-rate-limit": {
"version": "7.5.1",
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz",
"integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 16"
},
"funding": {
"url": "https://github.com/sponsors/express-rate-limit"
},
"peerDependencies": {
"express": ">= 4.11"
}
},
"node_modules/express/node_modules/mime-db": {
"version": "1.54.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/express/node_modules/mime-types": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
"integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
"dev": true,
"license": "MIT",
"dependencies": {
"mime-db": "^1.54.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -2996,6 +3317,24 @@
"node": ">=8"
}
},
"node_modules/finalhandler": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
"integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"debug": "^4.4.0",
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"on-finished": "^2.4.1",
"parseurl": "^1.3.3",
"statuses": "^2.0.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -3077,6 +3416,26 @@
"node": ">= 6"
}
},
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/fresh": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
"integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
@@ -3410,6 +3769,33 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"depd": "2.0.0",
"inherits": "2.0.4",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"toidentifier": "1.0.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/http-errors/node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/http-proxy-agent": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
@@ -3550,6 +3936,16 @@
"dev": true,
"optional": true
},
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
@@ -3668,6 +4064,13 @@
"node": ">=8"
}
},
"node_modules/is-promise": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
"dev": true,
"license": "MIT"
},
"node_modules/is-unicode-supported": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
@@ -4152,6 +4555,29 @@
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
"dev": true
},
"node_modules/media-typer": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
"integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/merge-descriptors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
"integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@@ -4495,6 +4921,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/negotiator": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
"integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/node-abi": {
"version": "3.75.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz",
@@ -4576,6 +5012,16 @@
"url": "https://github.com/fb55/nth-check?sponsor=1"
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/object-inspect": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
@@ -4588,6 +5034,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
"dev": true,
"license": "MIT",
"dependencies": {
"ee-first": "1.1.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -4927,6 +5386,16 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -4974,6 +5443,16 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/path-to-regexp": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
"integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=16"
}
},
"node_modules/path-type": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz",
@@ -5011,6 +5490,16 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/pkce-challenge": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz",
"integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=16.20.0"
}
},
"node_modules/pluralize": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz",
@@ -5064,6 +5553,20 @@
"dev": true,
"license": "MIT"
},
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
"dev": true,
"license": "MIT",
"dependencies": {
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/pump": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
@@ -5140,6 +5643,32 @@
"safe-buffer": "^5.1.0"
}
},
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/raw-body": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
"integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
"dev": true,
"license": "MIT",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.6.3",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/rc": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
@@ -5294,6 +5823,23 @@
"node": ">=0.10.0"
}
},
"node_modules/router": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
"integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"debug": "^4.4.0",
"depd": "^2.0.0",
"is-promise": "^4.0.0",
"parseurl": "^1.3.3",
"path-to-regexp": "^8.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/run-applescript": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz",
@@ -5383,6 +5929,52 @@
"node": ">=10"
}
},
"node_modules/send": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
"integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
"dev": true,
"license": "MIT",
"dependencies": {
"debug": "^4.3.5",
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"etag": "^1.8.1",
"fresh": "^2.0.0",
"http-errors": "^2.0.0",
"mime-types": "^3.0.1",
"ms": "^2.1.3",
"on-finished": "^2.4.1",
"range-parser": "^1.2.1",
"statuses": "^2.0.1"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/send/node_modules/mime-db": {
"version": "1.54.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/send/node_modules/mime-types": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
"integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
"dev": true,
"license": "MIT",
"dependencies": {
"mime-db": "^1.54.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/serialize-javascript": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
@@ -5393,6 +5985,22 @@
"randombytes": "^2.1.0"
}
},
"node_modules/serve-static": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
"integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"parseurl": "^1.3.3",
"send": "^1.2.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
@@ -5400,6 +6008,13 @@
"dev": true,
"license": "MIT"
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
"dev": true,
"license": "ISC"
},
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -5622,6 +6237,16 @@
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
"dev": true
},
"node_modules/statuses": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/stdin-discarder": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz",
@@ -6063,6 +6688,16 @@
"node": ">=8.0"
}
},
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.6"
}
},
"node_modules/ts-api-utils": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
@@ -6129,6 +6764,44 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/type-is": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
"integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
"dev": true,
"license": "MIT",
"dependencies": {
"content-type": "^1.0.5",
"media-typer": "^1.1.0",
"mime-types": "^3.0.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/type-is/node_modules/mime-db": {
"version": "1.54.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/type-is/node_modules/mime-types": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
"integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
"dev": true,
"license": "MIT",
"dependencies": {
"mime-db": "^1.54.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/typed-rest-client": {
"version": "1.8.11",
"resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz",
@@ -6203,6 +6876,16 @@
"node": ">= 10.0.0"
}
},
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -6260,6 +6943,16 @@
"spdx-expression-parse": "^3.0.0"
}
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/version-range": {
"version": "4.14.0",
"resolved": "https://registry.npmjs.org/version-range/-/version-range-4.14.0.tgz",
@@ -6587,6 +7280,26 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/zod": {
"version": "3.25.76",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/zod-to-json-schema": {
"version": "3.24.6",
"resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz",
"integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==",
"dev": true,
"license": "ISC",
"peerDependencies": {
"zod": "^3.24.1"
}
}
}
}

View File

@@ -2,7 +2,7 @@
"name": "claude-code-chat",
"displayName": "Claude Code Chat",
"description": "Beautiful Claude Code Chat Interface for VS Code",
"version": "0.1.0",
"version": "0.1.3",
"publisher": "AndrePimenta",
"author": "Andre Pimenta",
"repository": {
@@ -11,7 +11,7 @@
},
"license": "SEE LICENSE IN LICENSE",
"engines": {
"vscode": "^1.95.0"
"vscode": "^1.94.0"
},
"categories": [
"Other",
@@ -130,6 +130,7 @@
"claude-code-chat": [
{
"id": "claude-code-chat.chat",
"type": "webview",
"name": "Claude Code Chat",
"when": "true",
"icon": "icon.png",
@@ -171,9 +172,19 @@
},
"claudeCodeChat.thinking.intensity": {
"type": "string",
"enum": ["think", "think-hard", "think-harder", "ultrathink"],
"enum": [
"think",
"think-hard",
"think-harder",
"ultrathink"
],
"default": "think",
"description": "Thinking mode intensity level. Higher levels provide more detailed reasoning but consume more tokens."
},
"claudeCodeChat.permissions.yoloMode": {
"type": "boolean",
"default": false,
"description": "Enable Yolo Mode to skip all permission checks. Use with caution as Claude can execute any command without asking."
}
}
}
@@ -189,13 +200,15 @@
"devDependencies": {
"@types/mocha": "^10.0.10",
"@types/node": "20.x",
"@types/vscode": "^1.95.0",
"@types/vscode": "^1.94.0",
"@typescript-eslint/eslint-plugin": "^8.31.1",
"@typescript-eslint/parser": "^8.31.1",
"@vscode/test-cli": "^0.0.10",
"@vscode/test-electron": "^2.5.2",
"@vscode/vsce": "^3.5.0",
"eslint": "^9.25.1",
"typescript": "^5.8.3"
"typescript": "^5.8.3",
"@modelcontextprotocol/sdk": "^1.15.0",
"zod": "^3.25.76"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,212 @@
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import * as fs from "fs";
import * as path from "path";
const server = new McpServer({
name: "Claude Code Permissions MCP Server",
version: "0.0.1",
});
// Get permissions directory from environment
const PERMISSIONS_PATH = process.env.CLAUDE_PERMISSIONS_PATH;
if (!PERMISSIONS_PATH) {
console.error("CLAUDE_PERMISSIONS_PATH environment variable not set");
process.exit(1);
}
interface WorkspacePermissions {
alwaysAllow: {
[toolName: string]: boolean | string[]; // true for all, or array of allowed commands/patterns
};
}
function getWorkspacePermissionsPath(): string | null {
if (!PERMISSIONS_PATH) return null;
return path.join(PERMISSIONS_PATH, 'permissions.json');
}
function loadWorkspacePermissions(): WorkspacePermissions {
const permissionsPath = getWorkspacePermissionsPath();
if (!permissionsPath || !fs.existsSync(permissionsPath)) {
return { alwaysAllow: {} };
}
try {
const content = fs.readFileSync(permissionsPath, 'utf8');
return JSON.parse(content);
} catch (error) {
console.error(`Error loading workspace permissions: ${error}`);
return { alwaysAllow: {} };
}
}
function isAlwaysAllowed(toolName: string, input: any): boolean {
const permissions = loadWorkspacePermissions();
const toolPermission = permissions.alwaysAllow[toolName];
if (!toolPermission) return false;
// If it's true, always allow
if (toolPermission === true) return true;
// If it's an array, check for specific commands (mainly for Bash)
if (Array.isArray(toolPermission)) {
if (toolName === 'Bash' && input.command) {
const command = input.command.trim();
return toolPermission.some(allowedCmd => {
// Support exact match or pattern matching
if (allowedCmd.includes('*')) {
// Handle patterns like "npm i *" to match both "npm i" and "npm i something"
const baseCommand = allowedCmd.replace(' *', '');
if (command === baseCommand) {
return true; // Exact match for base command
}
// Pattern match for command with arguments
const pattern = allowedCmd.replace(/\*/g, '.*');
return new RegExp(`^${pattern}$`).test(command);
}
return command.startsWith(allowedCmd);
});
}
}
return false;
}
function generateRequestId(): string {
return `req_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
}
async function requestPermission(tool_name: string, input: any): Promise<{approved: boolean, reason?: string}> {
if (!PERMISSIONS_PATH) {
console.error("Permissions path not available");
return { approved: false, reason: "Permissions path not configured" };
}
// Check if this tool/command is always allowed for this workspace
if (isAlwaysAllowed(tool_name, input)) {
console.error(`Tool ${tool_name} is always allowed for this workspace`);
return { approved: true };
}
const requestId = generateRequestId();
const requestFile = path.join(PERMISSIONS_PATH, `${requestId}.request`);
const responseFile = path.join(PERMISSIONS_PATH, `${requestId}.response`);
// Write request file
const request = {
id: requestId,
tool: tool_name,
input: input,
timestamp: new Date().toISOString()
};
try {
fs.writeFileSync(requestFile, JSON.stringify(request, null, 2));
// Use fs.watch to wait for response file
return new Promise<{approved: boolean, reason?: string}>((resolve) => {
const timeout = setTimeout(() => {
watcher.close();
// Clean up request file on timeout
if (fs.existsSync(requestFile)) {
fs.unlinkSync(requestFile);
}
console.error(`Permission request ${requestId} timed out`);
resolve({ approved: false, reason: "Permission request timed out" });
}, 3600000); // 1 hour timeout
const watcher = fs.watch(PERMISSIONS_PATH, (eventType, filename) => {
if (eventType === 'rename' && filename === path.basename(responseFile)) {
// Check if file exists (rename event can be for creation or deletion)
if (fs.existsSync(responseFile)) {
try {
const responseContent = fs.readFileSync(responseFile, 'utf8');
const response = JSON.parse(responseContent);
// Clean up response file
fs.unlinkSync(responseFile);
// Clear timeout and close watcher
clearTimeout(timeout);
watcher.close();
resolve({
approved: response.approved,
reason: response.approved ? undefined : "User rejected the request"
});
} catch (error) {
console.error(`Error reading response file: ${error}`);
// Continue watching in case of read error
}
}
}
});
// Handle watcher errors
watcher.on('error', (error) => {
console.error(`File watcher error: ${error}`);
clearTimeout(timeout);
watcher.close();
resolve({ approved: false, reason: "File watcher error" });
});
});
} catch (error) {
console.error(`Error requesting permission: ${error}`);
return { approved: false, reason: `Error processing permission request: ${error}` };
}
}
server.tool(
"approval_prompt",
'Request user permission to execute a tool via VS Code dialog',
{
tool_name: z.string().describe("The name of the tool requesting permission"),
input: z.object({}).passthrough().describe("The input for the tool"),
tool_use_id: z.string().optional().describe("The unique tool use request ID"),
},
async ({ tool_name, input }) => {
console.error(`Requesting permission for tool: ${tool_name}`);
const permissionResult = await requestPermission(tool_name, input);
const behavior = permissionResult.approved ? "allow" : "deny";
console.error(`Permission ${behavior}ed for tool: ${tool_name}`);
return {
content: [
{
type: "text",
text: behavior === "allow" ?
JSON.stringify({
behavior: behavior,
updatedInput: input,
})
:
JSON.stringify({
behavior: behavior,
message: permissionResult.reason || "Permission denied",
})
,
},
],
};
}
);
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error(`Permissions MCP Server running on stdio`);
console.error(`Using permissions directory: ${PERMISSIONS_PATH}`);
}
main().catch((error) => {
console.error("Fatal error in main():", error);
process.exit(1);
});

View File

@@ -0,0 +1,10 @@
{
"mcpServers": {
"permissions": {
"command": "node",
"args": [
"./out/permissions/mcp-permissions.js"
]
}
}
}

View File

@@ -83,6 +83,504 @@ const styles = `
opacity: 1;
}
/* Permission Request */
.permission-request {
margin: 4px 12px 20px 12px;
background-color: var(--vscode-inputValidation-warningBackground);
border: 1px solid var(--vscode-inputValidation-warningBorder);
border-radius: 8px;
padding: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
animation: slideUp 0.3s ease;
}
.permission-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
font-weight: 600;
color: var(--vscode-foreground);
}
.permission-header .icon {
font-size: 16px;
}
.permission-content {
font-size: 13px;
line-height: 1.4;
color: var(--vscode-descriptionForeground);
}
.permission-tool {
font-family: var(--vscode-editor-font-family);
background-color: var(--vscode-editor-background);
border: 1px solid var(--vscode-panel-border);
border-radius: 4px;
padding: 8px 10px;
margin: 8px 0;
font-size: 12px;
color: var(--vscode-editor-foreground);
}
.permission-buttons {
margin-top: 2px;
display: flex;
gap: 8px;
justify-content: flex-end;
flex-wrap: wrap;
}
.permission-buttons .btn {
font-size: 12px;
padding: 6px 12px;
min-width: 70px;
text-align: center;
display: inline-flex;
align-items: center;
justify-content: center;
height: 28px;
border-radius: 4px;
border: 1px solid;
cursor: pointer;
transition: all 0.2s ease;
white-space: nowrap;
box-sizing: border-box;
}
.permission-buttons .btn.allow {
background-color: var(--vscode-button-background);
color: var(--vscode-button-foreground);
border-color: var(--vscode-button-background);
}
.permission-buttons .btn.allow:hover {
background-color: var(--vscode-button-hoverBackground);
}
.permission-buttons .btn.deny {
background-color: transparent;
color: var(--vscode-foreground);
border-color: var(--vscode-panel-border);
}
.permission-buttons .btn.deny:hover {
background-color: var(--vscode-list-hoverBackground);
border-color: var(--vscode-focusBorder);
}
.permission-buttons .btn.always-allow {
background-color: rgba(0, 122, 204, 0.1);
color: var(--vscode-charts-blue);
border-color: rgba(0, 122, 204, 0.3);
font-weight: 500;
min-width: auto;
padding: 6px 14px;
height: 28px;
}
.permission-buttons .btn.always-allow:hover {
background-color: rgba(0, 122, 204, 0.2);
border-color: rgba(0, 122, 204, 0.5);
transform: translateY(-1px);
}
.permission-buttons .btn.always-allow code {
background-color: rgba(0, 0, 0, 0.2);
padding: 2px 4px;
border-radius: 3px;
font-family: var(--vscode-editor-font-family);
font-size: 11px;
color: var(--vscode-editor-foreground);
margin-left: 4px;
display: inline;
line-height: 1;
vertical-align: baseline;
}
.permission-decision {
font-size: 13px;
font-weight: 600;
padding: 8px 12px;
text-align: center;
border-radius: 4px;
margin-top: 8px;
}
.permission-decision.allowed {
background-color: rgba(0, 122, 204, 0.15);
color: var(--vscode-charts-blue);
border: 1px solid rgba(0, 122, 204, 0.3);
}
.permission-decision.denied {
background-color: rgba(231, 76, 60, 0.15);
color: #e74c3c;
border: 1px solid rgba(231, 76, 60, 0.3);
}
.permission-decided {
opacity: 0.7;
pointer-events: none;
}
.permission-decided .permission-buttons {
display: none;
}
.permission-decided.allowed {
border-color: var(--vscode-inputValidation-infoBackground);
background-color: rgba(0, 122, 204, 0.1);
}
.permission-decided.denied {
border-color: var(--vscode-inputValidation-errorBorder);
background-color: var(--vscode-inputValidation-errorBackground);
}
/* Permissions Management */
.permissions-list {
max-height: 300px;
overflow-y: auto;
border: 1px solid var(--vscode-panel-border);
border-radius: 6px;
background-color: var(--vscode-input-background);
margin-top: 8px;
}
.permission-item {
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 6px;
padding-right: 6px;
border-bottom: 1px solid var(--vscode-panel-border);
transition: background-color 0.2s ease;
min-height: 32px;
}
.permission-item:hover {
background-color: var(--vscode-list-hoverBackground);
}
.permission-item:last-child {
border-bottom: none;
}
.permission-info {
display: flex;
align-items: center;
gap: 8px;
flex-grow: 1;
min-width: 0;
}
.permission-tool {
background-color: var(--vscode-badge-background);
color: var(--vscode-badge-foreground);
padding: 3px 6px;
border-radius: 3px;
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
flex-shrink: 0;
height: 18px;
display: inline-flex;
align-items: center;
line-height: 1;
}
.permission-command {
font-size: 12px;
color: var(--vscode-foreground);
flex-grow: 1;
}
.permission-command code {
background-color: var(--vscode-textCodeBlock-background);
padding: 3px 6px;
border-radius: 3px;
font-family: var(--vscode-editor-font-family);
color: var(--vscode-textLink-foreground);
font-size: 11px;
height: 18px;
display: inline-flex;
align-items: center;
line-height: 1;
}
.permission-desc {
color: var(--vscode-descriptionForeground);
font-size: 11px;
font-style: italic;
flex-grow: 1;
height: 18px;
display: inline-flex;
align-items: center;
line-height: 1;
}
.permission-remove-btn {
background-color: transparent;
color: var(--vscode-descriptionForeground);
border: none;
padding: 4px 8px;
border-radius: 3px;
cursor: pointer;
font-size: 10px;
transition: all 0.2s ease;
font-weight: 500;
flex-shrink: 0;
opacity: 0.7;
}
.permission-remove-btn:hover {
background-color: rgba(231, 76, 60, 0.1);
color: var(--vscode-errorForeground);
opacity: 1;
}
.permissions-empty {
padding: 16px;
text-align: center;
color: var(--vscode-descriptionForeground);
font-style: italic;
font-size: 13px;
}
.permissions-empty::before {
content: "🔒";
display: block;
font-size: 16px;
margin-bottom: 8px;
opacity: 0.5;
}
/* Add Permission Form */
.permissions-add-section {
margin-top: 6px;
}
.permissions-show-add-btn {
background-color: transparent;
color: var(--vscode-descriptionForeground);
border: 1px solid var(--vscode-panel-border);
border-radius: 3px;
padding: 6px 8px;
font-size: 11px;
cursor: pointer;
transition: all 0.2s ease;
font-weight: 400;
opacity: 0.7;
}
.permissions-show-add-btn:hover {
background-color: var(--vscode-list-hoverBackground);
opacity: 1;
}
.permissions-add-form {
margin-top: 8px;
padding: 12px;
border: 1px solid var(--vscode-panel-border);
border-radius: 6px;
background-color: var(--vscode-input-background);
animation: slideDown 0.2s ease;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.permissions-form-row {
display: flex;
gap: 8px;
align-items: center;
margin-bottom: 8px;
}
.permissions-tool-select {
background-color: var(--vscode-input-background);
color: var(--vscode-input-foreground);
border: 1px solid var(--vscode-panel-border);
border-radius: 3px;
padding: 4px 8px;
font-size: 12px;
min-width: 100px;
height: 24px;
flex-shrink: 0;
}
.permissions-command-input {
background-color: var(--vscode-input-background);
color: var(--vscode-input-foreground);
border: 1px solid var(--vscode-panel-border);
border-radius: 3px;
padding: 4px 8px;
font-size: 12px;
flex-grow: 1;
height: 24px;
font-family: var(--vscode-editor-font-family);
}
.permissions-command-input::placeholder {
color: var(--vscode-input-placeholderForeground);
}
.permissions-add-btn {
background-color: var(--vscode-button-background);
color: var(--vscode-button-foreground);
border: none;
border-radius: 3px;
padding: 4px 12px;
font-size: 12px;
cursor: pointer;
transition: background-color 0.2s ease;
height: 24px;
font-weight: 500;
flex-shrink: 0;
}
.permissions-add-btn:hover {
background-color: var(--vscode-button-hoverBackground);
}
.permissions-add-btn:disabled {
background-color: var(--vscode-button-secondaryBackground);
color: var(--vscode-button-secondaryForeground);
cursor: not-allowed;
opacity: 0.5;
}
.permissions-cancel-btn {
background-color: transparent;
color: var(--vscode-foreground);
border: 1px solid var(--vscode-panel-border);
border-radius: 3px;
padding: 4px 12px;
font-size: 12px;
cursor: pointer;
transition: all 0.2s ease;
height: 24px;
font-weight: 500;
}
.permissions-cancel-btn:hover {
background-color: var(--vscode-list-hoverBackground);
border-color: var(--vscode-focusBorder);
}
.permissions-form-hint {
font-size: 11px;
color: var(--vscode-descriptionForeground);
font-style: italic;
line-height: 1.3;
}
.yolo-mode-section {
display: flex;
align-items: center;
gap: 6px;
margin-top: 12px;
opacity: 0.8;
transition: opacity 0.2s ease;
}
.yolo-mode-section:hover {
opacity: 1;
}
.yolo-mode-section input[type="checkbox"] {
transform: scale(0.8);
margin: 0;
}
.yolo-mode-section label {
font-size: 10px;
color: var(--vscode-descriptionForeground);
cursor: pointer;
font-weight: 400;
}
/* WSL Alert */
.wsl-alert {
margin: 8px 12px;
background-color: rgba(135, 206, 235, 0.1);
border: 2px solid rgba(135, 206, 235, 0.3);
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(4px);
animation: slideUp 0.3s ease;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.wsl-alert-content {
display: flex;
align-items: center;
padding: 14px 18px;
gap: 14px;
}
.wsl-alert-icon {
font-size: 22px;
flex-shrink: 0;
}
.wsl-alert-text {
flex: 1;
font-size: 13px;
line-height: 1.4;
color: var(--vscode-foreground);
}
.wsl-alert-text strong {
font-weight: 600;
color: var(--vscode-foreground);
}
.wsl-alert-actions {
display: flex;
gap: 10px;
flex-shrink: 0;
}
.wsl-alert-actions .btn {
padding: 6px 14px;
font-size: 12px;
border-radius: 6px;
}
.wsl-alert-actions .btn:first-child {
background-color: rgba(135, 206, 235, 0.2);
border-color: rgba(135, 206, 235, 0.4);
}
.wsl-alert-actions .btn:first-child:hover {
background-color: rgba(135, 206, 235, 0.3);
border-color: rgba(135, 206, 235, 0.6);
}
.chat-container {
flex: 1;
display: flex;
@@ -106,9 +604,10 @@ const styles = `
}
.message.user {
border: 1px solid rgba(100, 149, 237, 0.1);
border: 1px solid rgba(64, 165, 255, 0.2);
border-radius: 8px;
color: var(--vscode-editor-foreground);
font-family: var(--vscode-editor-font-family);
position: relative;
overflow: hidden;
}
@@ -120,7 +619,7 @@ const styles = `
top: 0;
bottom: 0;
width: 4px;
background: linear-gradient(180deg, #6495ed 0%, #4169e1 100%);
background: linear-gradient(180deg, #40a5ff 0%, #0078d4 100%);
}
.message.claude {
@@ -166,10 +665,9 @@ const styles = `
}
.message.tool {
border: 1px solid rgba(64, 165, 255, 0.2);
border: 1px solid rgba(120, 139, 237, 0.12);
border-radius: 8px;
color: var(--vscode-editor-foreground);
font-family: var(--vscode-editor-font-family);
position: relative;
overflow: hidden;
}
@@ -181,7 +679,7 @@ const styles = `
top: 0;
bottom: 0;
width: 4px;
background: linear-gradient(180deg, #40a5ff 0%, #0078d4 100%);
background: linear-gradient(180deg, #7c8bed 0%, #5d6fe1 100%);
}
.message.tool-result {
@@ -238,7 +736,7 @@ const styles = `
width: 18px;
height: 18px;
border-radius: 4px;
background: linear-gradient(135deg, #40a5ff 0%, #0078d4 100%);
background: linear-gradient(135deg, #7c8bed 0%, #5d6fe1 100%);
display: flex;
align-items: center;
justify-content: center;
@@ -246,6 +744,7 @@ const styles = `
color: white;
font-weight: 600;
flex-shrink: 0;
margin-left: 6px;
}
.tool-info {
@@ -290,8 +789,8 @@ const styles = `
}
.message-icon {
width: 16px;
height: 16px;
width: 18px;
height: 18px;
border-radius: 3px;
display: flex;
align-items: center;
@@ -300,11 +799,11 @@ const styles = `
color: white;
font-weight: 600;
flex-shrink: 0;
margin-left: 4px
margin-left: 6px;
}
.message-icon.user {
background: linear-gradient(135deg, #6495ed 0%, #4169e1 100%);
background: linear-gradient(135deg, #40a5ff 0%, #0078d4 100%);
}
.message-icon.claude {
@@ -328,7 +827,7 @@ const styles = `
}
.message-content {
padding-left: 4px;
padding-left: 6px;
}
.priority-badge {
@@ -361,8 +860,7 @@ const styles = `
}
.tool-input {
margin-top: 4px;
padding: 12px;
padding: 6px;
font-family: var(--vscode-editor-font-family);
font-size: 12px;
line-height: 1.4;
@@ -383,6 +881,169 @@ const styles = `
opacity: 0.95;
}
/* Diff display styles for Edit tool */
.diff-container {
border: 1px solid var(--vscode-panel-border);
border-radius: 4px;
overflow: hidden;
}
.diff-header {
background-color: var(--vscode-panel-background);
padding: 6px 12px;
font-size: 11px;
font-weight: 600;
color: var(--vscode-foreground);
border-bottom: 1px solid var(--vscode-panel-border);
}
.diff-removed,
.diff-added {
font-family: var(--vscode-editor-font-family);
font-size: 12px;
line-height: 1.4;
}
.diff-line {
padding: 2px 12px;
white-space: pre-wrap;
word-break: break-word;
}
.diff-line.removed {
background-color: rgba(244, 67, 54, 0.1);
border-left: 3px solid rgba(244, 67, 54, 0.6);
color: var(--vscode-foreground);
}
.diff-line.added {
background-color: rgba(76, 175, 80, 0.1);
border-left: 3px solid rgba(76, 175, 80, 0.6);
color: var(--vscode-foreground);
}
.diff-line.removed::before {
content: '';
color: rgba(244, 67, 54, 0.8);
font-weight: 600;
margin-right: 8px;
}
.diff-line.added::before {
content: '';
color: rgba(76, 175, 80, 0.8);
font-weight: 600;
margin-right: 8px;
}
.diff-expand-container {
padding: 8px 12px;
text-align: center;
border-top: 1px solid var(--vscode-panel-border);
background-color: var(--vscode-editor-background);
}
.diff-expand-btn {
background: linear-gradient(135deg, rgba(64, 165, 255, 0.15) 0%, rgba(64, 165, 255, 0.1) 100%);
border: 1px solid rgba(64, 165, 255, 0.3);
color: #40a5ff;
padding: 4px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 11px;
font-weight: 500;
transition: all 0.2s ease;
}
.diff-expand-btn:hover {
background: linear-gradient(135deg, rgba(64, 165, 255, 0.25) 0%, rgba(64, 165, 255, 0.15) 100%);
border-color: rgba(64, 165, 255, 0.5);
}
.diff-expand-btn:active {
transform: translateY(1px);
}
/* MultiEdit specific styles */
.single-edit {
margin-bottom: 12px;
}
.edit-number {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.15);
color: var(--vscode-descriptionForeground);
padding: 4px 8px;
border-radius: 4px;
font-size: 11px;
font-weight: 600;
margin-top: 6px;
display: inline-block;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.diff-edit-separator {
height: 1px;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
margin: 12px 0;
}
/* File path display styles */
.diff-file-path {
padding: 8px 12px;
border: 1px solid var(--vscode-panel-border);
border-radius: 4px;
font-size: 12px;
cursor: pointer;
transition: all 0.2s ease;
}
.diff-file-path:hover {
background-color: var(--vscode-list-hoverBackground);
border-color: var(--vscode-focusBorder);
}
.diff-file-path:active {
transform: translateY(1px);
}
.file-path-short,
.file-path-truncated {
font-family: var(--vscode-editor-font-family);
color: var(--vscode-foreground);
font-weight: 500;
}
.file-path-truncated {
display: inline-flex;
align-items: center;
gap: 6px;
cursor: pointer;
transition: all 0.2s ease;
padding: 2px 4px;
border-radius: 3px;
}
.file-path-truncated .file-icon {
font-size: 14px;
opacity: 0.7;
transition: opacity 0.2s ease;
}
.file-path-truncated:hover {
color: var(--vscode-textLink-foreground);
background-color: var(--vscode-list-hoverBackground);
}
.file-path-truncated:hover .file-icon {
opacity: 1;
}
.file-path-truncated:active {
transform: translateY(1px);
}
.expand-btn {
background: linear-gradient(135deg, rgba(64, 165, 255, 0.15) 0%, rgba(64, 165, 255, 0.1) 100%);
border: 1px solid rgba(64, 165, 255, 0.3);
@@ -692,13 +1353,52 @@ const styles = `
gap: 8px;
}
.beta-warning {
font-size: 11px;
color: var(--vscode-descriptionForeground);
.yolo-warning {
font-size: 12px;
color: var(--vscode-inputValidation-errorForeground);
text-align: center;
font-style: italic;
background-color: var(--vscode-panel-background);
padding: 4px
font-weight: 500;
background-color: var(--vscode-inputValidation-errorBackground);
border: 1px solid var(--vscode-inputValidation-errorBorder);
padding: 8px 12px;
margin: 4px 12px;
border-radius: 4px;
animation: slideDown 0.3s ease;
}
.yolo-suggestion {
margin-top: 12px;
padding: 12px;
background-color: rgba(0, 122, 204, 0.1);
border: 1px solid rgba(0, 122, 204, 0.3);
border-radius: 6px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.yolo-suggestion-text {
font-size: 12px;
color: var(--vscode-foreground);
flex-grow: 1;
}
.yolo-suggestion-btn {
background-color: var(--vscode-button-background);
color: var(--vscode-button-foreground);
border: none;
border-radius: 4px;
padding: 6px 12px;
font-size: 11px;
cursor: pointer;
transition: background-color 0.2s ease;
font-weight: 500;
flex-shrink: 0;
}
.yolo-suggestion-btn:hover {
background-color: var(--vscode-button-hoverBackground);
}
.file-picker-modal {
@@ -1052,6 +1752,43 @@ const styles = `
}
/* Thinking intensity modal */
.thinking-modal-description {
padding: 0px 20px;
font-size: 12px;
color: var(--vscode-descriptionForeground);
line-height: 1.5;
text-align: center;
margin: 20px;
margin-bottom: 0px;
}
.thinking-modal-actions {
padding-top: 20px;
text-align: right;
border-top: 1px solid var(--vscode-widget-border);
}
.confirm-btn {
background-color: var(--vscode-button-background);
color: var(--vscode-button-foreground);
border: 1px solid var(--vscode-panel-border);
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
font-weight: 400;
transition: all 0.2s ease;
display: inline-flex;
align-items: center;
gap: 5px;
}
.confirm-btn:hover {
background-color: var(--vscode-button-background);
border-color: var(--vscode-focusBorder);
}
/* Slash commands modal */
.slash-commands-info {
padding: 12px 16px;
@@ -1415,6 +2152,71 @@ const styles = `
color: var(--vscode-descriptionForeground);
opacity: 0.8;
}
/* Tool loading animation */
.tool-loading {
padding: 16px 12px;
display: flex;
align-items: center;
gap: 12px;
background-color: var(--vscode-panel-background);
border-top: 1px solid var(--vscode-panel-border);
}
.loading-spinner {
display: flex;
gap: 4px;
}
.loading-ball {
width: 8px;
height: 8px;
border-radius: 50%;
background-color: var(--vscode-button-background);
animation: bounce 1.4s ease-in-out infinite both;
}
.loading-ball:nth-child(1) { animation-delay: -0.32s; }
.loading-ball:nth-child(2) { animation-delay: -0.16s; }
.loading-ball:nth-child(3) { animation-delay: 0s; }
@keyframes bounce {
0%, 80%, 100% {
transform: scale(0.6);
opacity: 0.5;
}
40% {
transform: scale(1);
opacity: 1;
}
}
.loading-text {
font-size: 12px;
color: var(--vscode-descriptionForeground);
font-style: italic;
}
/* Tool completion indicator */
.tool-completion {
padding: 8px 12px;
display: flex;
align-items: center;
gap: 6px;
background-color: rgba(76, 175, 80, 0.1);
border-top: 1px solid rgba(76, 175, 80, 0.2);
font-size: 12px;
}
.completion-icon {
color: #4caf50;
font-weight: bold;
}
.completion-text {
color: var(--vscode-foreground);
opacity: 0.8;
}
</style>`
export default styles

1096
src/ui.ts

File diff suppressed because it is too large Load Diff