mirror of
https://github.com/andrepimenta/claude-code-chat.git
synced 2025-12-08 18:09:44 +00:00
Compare commits
31 Commits
1.0.0
...
a156881a08
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a156881a08 | ||
|
|
0764bf8202 | ||
|
|
82899ebb40 | ||
|
|
abf81a1176 | ||
|
|
da46d5e3d9 | ||
|
|
d20d8667f3 | ||
|
|
6c37394015 | ||
|
|
2b1ad70f6b | ||
|
|
bf527bb922 | ||
|
|
df8188380d | ||
|
|
79a0b6b4b2 | ||
|
|
dd47efec04 | ||
|
|
d891070d9e | ||
|
|
1be89d43a4 | ||
|
|
0abfab72a8 | ||
|
|
1eacc6ff74 | ||
|
|
031a2c5fc3 | ||
|
|
73c4a38da1 | ||
|
|
53acc0a79f | ||
|
|
62163dbc32 | ||
|
|
d225ff2596 | ||
|
|
ab5c393253 | ||
|
|
d6a73a1a7f | ||
|
|
5abb1fedd9 | ||
|
|
3b534cfce2 | ||
|
|
6bd906981b | ||
|
|
4f126641e4 | ||
|
|
2d63eaac58 | ||
|
|
f44dc28763 | ||
|
|
2c47349282 | ||
|
|
43c1c85efb |
@@ -11,3 +11,6 @@ vsc-extension-quickstart.md
|
|||||||
**/.vscode-test.*
|
**/.vscode-test.*
|
||||||
backup
|
backup
|
||||||
.claude
|
.claude
|
||||||
|
claude-code-chat-permissions-mcp/**
|
||||||
|
node_modules
|
||||||
|
mcp-permissions.js
|
||||||
57
CHANGELOG.md
57
CHANGELOG.md
@@ -4,6 +4,63 @@ 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.
|
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
|
||||||
|
|
||||||
|
## [1.0.7] - 2025-10-01
|
||||||
|
|
||||||
|
### 🚀 Features Added
|
||||||
|
- **Slash Commands Update**: Added 4 new slash commands to the commands modal
|
||||||
|
- `/add-dir` - Add additional working directories
|
||||||
|
- `/agents` - Manage custom AI subagents for specialized tasks
|
||||||
|
- `/rewind` - Rewind the conversation and/or code
|
||||||
|
- `/usage` - Show plan usage limits and rate limit status (subscription plans only)
|
||||||
|
|
||||||
|
### 📚 Documentation Updates
|
||||||
|
- Updated slash commands count from 19+ to 23+ built-in commands
|
||||||
|
- Enhanced command descriptions for better clarity:
|
||||||
|
- `/config` - Now specifies "Open the Settings interface (Config tab)"
|
||||||
|
- `/cost` - Added note about cost tracking guide for subscription-specific details
|
||||||
|
- `/status` - Expanded description to mention version, model, account, and connectivity
|
||||||
|
- `/terminal-setup` - Added clarification about iTerm2 and VSCode only support
|
||||||
|
|
||||||
|
## [1.0.6] - 2025-08-26
|
||||||
|
|
||||||
|
### 🐛 Bug Fixes
|
||||||
|
- Fixed typo in codebase
|
||||||
|
- Removed priority settings that were no longer needed
|
||||||
|
|
||||||
|
### 🔧 Technical Improvements
|
||||||
|
- Moved script to separate file for better code organization
|
||||||
|
|
||||||
|
## [1.0.5] - 2025-07-30
|
||||||
|
|
||||||
|
### 🚀 Features Added
|
||||||
|
- **MCP Integration**: Added claude-code-chat-permissions-mcp folder for enhanced permission management
|
||||||
|
- **Message Persistence**: Save message in text box for better user experience
|
||||||
|
- **UI Improvements**: Always display history and new chat options
|
||||||
|
- **Input Enhancement**: Removed maxlength limit for custom command prompt textarea
|
||||||
|
|
||||||
|
### 🐛 Bug Fixes
|
||||||
|
- Fixed new chat functionality
|
||||||
|
- Fixed request start time isProcessing issue
|
||||||
|
- Fixed close and open conversation behavior
|
||||||
|
|
||||||
|
### 🔄 Merged Pull Requests
|
||||||
|
- Merged PR #87 from horatio-sans-serif/main
|
||||||
|
|
||||||
|
## [1.0.4] - 2025-01-22
|
||||||
|
|
||||||
|
### 🐛 Bug Fixes
|
||||||
|
- Fixed input text area overflow issue by adding `box-sizing: border-box` to prevent padding from extending beyond container width
|
||||||
|
- Fixed command parameter handling for `claude-code-chat.openChat` to properly handle both ViewColumn and Uri parameters from different invocation contexts
|
||||||
|
|
||||||
|
### 🔧 Technical Improvements
|
||||||
|
- Enhanced `show()` method to accept optional ViewColumn parameter with ViewColumn.Two as default
|
||||||
|
- Added proper type checking for command parameters to handle context menu invocations
|
||||||
|
- Improved webview panel positioning with flexible column parameter support
|
||||||
|
|
||||||
|
### 🎨 UI/UX Improvements
|
||||||
|
- Resolved text input container sizing issues that caused visual overflow
|
||||||
|
- Better input field styling consistency across different VS Code themes
|
||||||
|
|
||||||
## [1.0.0] - 2025-01-15
|
## [1.0.0] - 2025-01-15
|
||||||
|
|
||||||
### 🚀 Major Features Added
|
### 🚀 Major Features Added
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ Ditch the command line and experience Claude Code like never before. This extens
|
|||||||
💾 **Conversation History** - Automatic conversation history and session management
|
💾 **Conversation History** - Automatic conversation history and session management
|
||||||
🎨 **VS Code Native** - Claude Code integrated directly into VS Code with native theming and sidebar support
|
🎨 **VS Code Native** - Claude Code integrated directly into VS Code with native theming and sidebar support
|
||||||
🧠 **Plan and Thinking modes** - Plan First and configurable Thinking modes for better results
|
🧠 **Plan and Thinking modes** - Plan First and configurable Thinking modes for better results
|
||||||
⚡ **Smart File/Image Context and Custom Commands** - Reference any file, copy images or screenshots, and create custom commands
|
⚡ **Smart File/Image Context and Custom Commands** - Reference any file, paste images or screenshots and create custom commands
|
||||||
🤖 **Model Selection** - Choose between Opus, Sonnet, or Default based on your needs
|
🤖 **Model Selection** - Choose between Opus, Sonnet, or Default based on your needs
|
||||||
🐧 **WSL Support** - Full Windows Subsystem for Linux integration and compatibility
|
🐧 **Windows/WSL Support** - Full native Windows and WSL support
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ Ditch the command line and experience Claude Code like never before. This extens
|
|||||||
|
|
||||||
### ⚡ **Slash Commands Integration**
|
### ⚡ **Slash Commands Integration**
|
||||||
- **Slash Commands Modal** - Type "/" to access all Claude Code commands instantly
|
- **Slash Commands Modal** - Type "/" to access all Claude Code commands instantly
|
||||||
- **19+ Built-in Commands** - /cost, /status, /config, /help, /memory, /review, and more
|
- **23+ Built-in Commands** - /agents, /cost, /config, /memory, /review, and more
|
||||||
- **Custom Command Support** - Execute any Claude Code command with session context
|
- **Custom Command Support** - Execute any Claude Code command with session context
|
||||||
- **Session-Aware Execution** - All commands run with current conversation context
|
- **Session-Aware Execution** - All commands run with current conversation context
|
||||||
- **Terminal Integration** - Commands open directly in VS Code terminal with WSL support
|
- **Terminal Integration** - Commands open directly in VS Code terminal with WSL support
|
||||||
|
|||||||
13954
claude-code-chat-permissions-mcp/mcp-permissions.js
Normal file
13954
claude-code-chat-permissions-mcp/mcp-permissions.js
Normal file
File diff suppressed because one or more lines are too long
212
claude-code-chat-permissions-mcp/mcp-permissions.ts
Normal file
212
claude-code-chat-permissions-mcp/mcp-permissions.ts
Normal 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);
|
||||||
|
});
|
||||||
1086
claude-code-chat-permissions-mcp/package-lock.json
generated
Normal file
1086
claude-code-chat-permissions-mcp/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
21
claude-code-chat-permissions-mcp/package.json
Normal file
21
claude-code-chat-permissions-mcp/package.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "claude-code-chat-permissions-mcp",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "dist/mcp-permissions.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "tsc && node dist/mcp-permissions.js",
|
||||||
|
"lint": "eslint . --ext .ts",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"description": "",
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^24.0.13",
|
||||||
|
"typescript": "^5.8.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@modelcontextprotocol/sdk": "^1.15.1",
|
||||||
|
"zod": "^3.25.76"
|
||||||
|
}
|
||||||
|
}
|
||||||
11
claude-code-chat-permissions-mcp/tsconfig.json
Normal file
11
claude-code-chat-permissions-mcp/tsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"target": "es6",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"sourceMap": true,
|
||||||
|
"outDir": "dist"
|
||||||
|
},
|
||||||
|
"lib": ["es2015"]
|
||||||
|
}
|
||||||
BIN
icon-bubble.png
Normal file
BIN
icon-bubble.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 469 KiB |
BIN
icon.png
BIN
icon.png
Binary file not shown.
|
Before Width: | Height: | Size: 689 KiB After Width: | Height: | Size: 689 KiB |
10
package.json
10
package.json
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "claude-code-chat",
|
"name": "claude-code-chat",
|
||||||
"displayName": "Claude Code Chat",
|
"displayName": "Chat for Claude Code",
|
||||||
"description": "Beautiful Claude Code Chat Interface for VS Code",
|
"description": "Beautiful Claude Code Chat Interface for VS Code",
|
||||||
"version": "1.0.0",
|
"version": "1.0.7",
|
||||||
"publisher": "AndrePimenta",
|
"publisher": "AndrePimenta",
|
||||||
"author": "Andre Pimenta",
|
"author": "Andre Pimenta",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
"command": "claude-code-chat.openChat",
|
"command": "claude-code-chat.openChat",
|
||||||
"title": "Open Claude Code Chat",
|
"title": "Open Claude Code Chat",
|
||||||
"category": "Claude Code Chat",
|
"category": "Claude Code Chat",
|
||||||
"icon": "icon.png"
|
"icon": "icon-bubble.png"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"keybindings": [
|
"keybindings": [
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
"type": "webview",
|
"type": "webview",
|
||||||
"name": "Claude Code Chat",
|
"name": "Claude Code Chat",
|
||||||
"when": "true",
|
"when": "true",
|
||||||
"icon": "icon.png",
|
"icon": "icon-bubble.png",
|
||||||
"contextualTitle": "Claude Code Chat"
|
"contextualTitle": "Claude Code Chat"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -143,7 +143,7 @@
|
|||||||
{
|
{
|
||||||
"id": "claude-code-chat",
|
"id": "claude-code-chat",
|
||||||
"title": "Claude Code Chat",
|
"title": "Claude Code Chat",
|
||||||
"icon": "icon.png"
|
"icon": "icon-bubble.png"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
1144
src/extension.ts
1144
src/extension.ts
File diff suppressed because it is too large
Load Diff
3225
src/script.ts
Normal file
3225
src/script.ts
Normal file
File diff suppressed because it is too large
Load Diff
165
src/ui-styles.ts
165
src/ui-styles.ts
@@ -86,8 +86,8 @@ const styles = `
|
|||||||
/* Permission Request */
|
/* Permission Request */
|
||||||
.permission-request {
|
.permission-request {
|
||||||
margin: 4px 12px 20px 12px;
|
margin: 4px 12px 20px 12px;
|
||||||
background-color: var(--vscode-inputValidation-warningBackground);
|
background-color: rgba(252, 188, 0, 0.1);
|
||||||
border: 1px solid var(--vscode-inputValidation-warningBorder);
|
border: 1px solid rgba(252, 188, 0, 0.3);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
@@ -302,6 +302,12 @@ const styles = `
|
|||||||
border: 1px solid rgba(231, 76, 60, 0.3);
|
border: 1px solid rgba(231, 76, 60, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.permission-decision.expired {
|
||||||
|
background-color: rgba(128, 128, 128, 0.15);
|
||||||
|
color: var(--vscode-descriptionForeground);
|
||||||
|
border: 1px solid rgba(128, 128, 128, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
.permission-decided {
|
.permission-decided {
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
@@ -321,6 +327,11 @@ const styles = `
|
|||||||
background-color: var(--vscode-inputValidation-errorBackground);
|
background-color: var(--vscode-inputValidation-errorBackground);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.permission-decided.expired {
|
||||||
|
border-color: var(--vscode-panel-border);
|
||||||
|
background-color: rgba(128, 128, 128, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
/* Permissions Management */
|
/* Permissions Management */
|
||||||
.permissions-list {
|
.permissions-list {
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
@@ -1076,34 +1087,25 @@ const styles = `
|
|||||||
|
|
||||||
.diff-line {
|
.diff-line {
|
||||||
padding: 2px 12px;
|
padding: 2px 12px;
|
||||||
white-space: pre-wrap;
|
white-space: pre;
|
||||||
word-break: break-word;
|
font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Courier New', monospace;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-line.context {
|
||||||
|
color: var(--vscode-editor-foreground);
|
||||||
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.diff-line.removed {
|
.diff-line.removed {
|
||||||
background-color: rgba(244, 67, 54, 0.1);
|
background-color: rgba(244, 67, 54, 0.1);
|
||||||
border-left: 3px solid rgba(244, 67, 54, 0.6);
|
color: var(--vscode-gitDecoration-deletedResourceForeground, rgba(244, 67, 54, 0.9));
|
||||||
color: var(--vscode-foreground);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.diff-line.added {
|
.diff-line.added {
|
||||||
background-color: rgba(76, 175, 80, 0.1);
|
background-color: rgba(76, 175, 80, 0.1);
|
||||||
border-left: 3px solid rgba(76, 175, 80, 0.6);
|
color: var(--vscode-gitDecoration-addedResourceForeground, rgba(76, 175, 80, 0.9));
|
||||||
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 {
|
.diff-expand-container {
|
||||||
@@ -1159,7 +1161,39 @@ const styles = `
|
|||||||
margin: 12px 0;
|
margin: 12px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.diff-summary-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 8px;
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-top: 1px solid var(--vscode-panel-border);
|
||||||
|
background-color: var(--vscode-editor-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-summary {
|
||||||
|
color: var(--vscode-descriptionForeground);
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-preview {
|
||||||
|
padding: 4px 12px;
|
||||||
|
color: var(--vscode-descriptionForeground);
|
||||||
|
font-size: 12px;
|
||||||
|
font-style: italic;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
/* File path display styles */
|
/* File path display styles */
|
||||||
|
.diff-file-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
.diff-file-path {
|
.diff-file-path {
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
border: 1px solid var(--vscode-panel-border);
|
border: 1px solid var(--vscode-panel-border);
|
||||||
@@ -1167,6 +1201,7 @@ const styles = `
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.diff-file-path:hover {
|
.diff-file-path:hover {
|
||||||
@@ -1178,6 +1213,35 @@ const styles = `
|
|||||||
transform: translateY(1px);
|
transform: translateY(1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.diff-open-btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid var(--vscode-button-secondaryBorder, var(--vscode-panel-border));
|
||||||
|
color: var(--vscode-foreground);
|
||||||
|
padding: 4px 10px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 11px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-open-btn svg {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-open-btn:hover {
|
||||||
|
background: var(--vscode-button-secondaryHoverBackground, rgba(255, 255, 255, 0.1));
|
||||||
|
border-color: var(--vscode-focusBorder);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-open-btn:active {
|
||||||
|
transform: translateY(1px);
|
||||||
|
}
|
||||||
|
|
||||||
.file-path-short,
|
.file-path-short,
|
||||||
.file-path-truncated {
|
.file-path-truncated {
|
||||||
font-family: var(--vscode-editor-font-family);
|
font-family: var(--vscode-editor-font-family);
|
||||||
@@ -1350,13 +1414,14 @@ const styles = `
|
|||||||
|
|
||||||
.input-field {
|
.input-field {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: var(--vscode-input-foreground);
|
color: var(--vscode-input-foreground);
|
||||||
border: none;
|
border: none;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
outline: none;
|
outline: none;
|
||||||
font-family: var(--vscode-editor-font-family);
|
font-family: var(--vscode-editor-font-family);
|
||||||
min-height: 20px;
|
min-height: 68px;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
resize: none;
|
resize: none;
|
||||||
@@ -2873,6 +2938,60 @@ const styles = `
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Processing indicator - morphing orange dot */
|
||||||
|
.processing-indicator {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 12px 0;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.processing-indicator .morph-dot {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
background: linear-gradient(135deg, #ff9500 0%, #ff6b00 100%);
|
||||||
|
box-shadow: 0 0 8px rgba(255, 149, 0, 0.5);
|
||||||
|
animation: morphShape 3s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes morphShape {
|
||||||
|
0%, 100% {
|
||||||
|
border-radius: 50%;
|
||||||
|
transform: scale(1) rotate(0deg);
|
||||||
|
}
|
||||||
|
15% {
|
||||||
|
border-radius: 50%;
|
||||||
|
transform: scale(1.3) rotate(0deg);
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
border-radius: 20%;
|
||||||
|
transform: scale(1) rotate(45deg);
|
||||||
|
}
|
||||||
|
40% {
|
||||||
|
border-radius: 20%;
|
||||||
|
transform: scale(1.2) rotate(90deg);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
border-radius: 50% 50% 50% 0%;
|
||||||
|
transform: scale(1) rotate(135deg);
|
||||||
|
}
|
||||||
|
65% {
|
||||||
|
border-radius: 0%;
|
||||||
|
transform: scale(1.3) rotate(180deg);
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
border-radius: 50% 0% 50% 0%;
|
||||||
|
transform: scale(1) rotate(270deg);
|
||||||
|
}
|
||||||
|
85% {
|
||||||
|
border-radius: 30%;
|
||||||
|
transform: scale(1.2) rotate(315deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</style>`
|
</style>`
|
||||||
|
|
||||||
export default styles
|
export default styles
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"mcp-permissions.js"
|
"mcp-permissions.js",
|
||||||
|
"claude-code-chat-permissions-mcp"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user