// ==UserScript== // @name Claude Code 安装助手 // @namespace http://tampermonkey.net/ // @version 1.0 // @description 一键安装和配置 Claude Code // @author 北枫枫 // @match *://*/* // @grant none // @downloadURL https://update.greasyfork.icu/scripts/551111/Claude%20Code%20%E5%AE%89%E8%A3%85%E5%8A%A9%E6%89%8B.user.js // @updateURL https://update.greasyfork.icu/scripts/551111/Claude%20Code%20%E5%AE%89%E8%A3%85%E5%8A%A9%E6%89%8B.meta.js // ==/UserScript== (function() { 'use strict'; // 创建安装按钮容器 function createInstallButton() { // 检查域名是否匹配 - 只允许 api.ikuncode.cc 和 h.ikuncode.cc const hostname = window.location.hostname; const allowedHosts = ['api.ikuncode.cc', 'hk.ikuncode.cc']; if (!allowedHosts.includes(hostname)) { console.log('不在允许的域名下,跳过按钮创建'); return; } // 创建容器 const container = document.createElement('div'); container.id = 'claude-installer-container'; container.style.cssText = ` position: fixed; top: 13%; right: 20px; transform: translateY(-50%); z-index: 10000; display: flex; align-items: stretch; background: #007bff; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,123,255,0.3); overflow: hidden; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); `; // 创建主按钮 const button = document.createElement('button'); button.id = 'claude-installer-btn'; button.textContent = '安装 Claude Code'; button.style.cssText = ` padding: 12px 20px; background: transparent; color: white; border: none; cursor: pointer; font-size: 15px; font-weight: 500; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); white-space: nowrap; overflow: hidden; max-width: 200px; opacity: 1; `; // 创建分隔线 const divider = document.createElement('div'); divider.id = 'claude-divider'; divider.style.cssText = ` width: 1px; background: rgba(255, 255, 255, 0.3); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); `; // 创建折叠按钮 const collapseBtn = document.createElement('button'); collapseBtn.id = 'claude-collapse-btn'; collapseBtn.innerHTML = '◄'; collapseBtn.style.cssText = ` width: 45px; padding: 0; background: transparent; color: white; border: none; cursor: pointer; font-size: 16px; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); display: flex; align-items: center; justify-content: center; `; // 悬停效果 button.addEventListener('mouseenter', () => { button.style.background = 'rgba(255, 255, 255, 0.1)'; }); button.addEventListener('mouseleave', () => { button.style.background = 'transparent'; }); collapseBtn.addEventListener('mouseenter', () => { collapseBtn.style.background = 'rgba(255, 255, 255, 0.1)'; }); collapseBtn.addEventListener('mouseleave', () => { collapseBtn.style.background = 'transparent'; }); // 添加点击事件 button.addEventListener('click', showInstallDialog); collapseBtn.addEventListener('click', toggleCollapse); // 组装容器 container.appendChild(button); container.appendChild(divider); container.appendChild(collapseBtn); document.body.appendChild(container); } // 折叠/展开功能 function toggleCollapse() { const button = document.getElementById('claude-installer-btn'); const collapseBtn = document.getElementById('claude-collapse-btn'); const divider = document.getElementById('claude-divider'); if (button.style.maxWidth === '0px') { // 展开 button.style.maxWidth = '200px'; button.style.padding = '12px 20px'; button.style.opacity = '1'; divider.style.width = '1px'; divider.style.opacity = '1'; collapseBtn.innerHTML = '◄'; collapseBtn.title = '折叠'; } else { // 折叠 button.style.maxWidth = '0px'; button.style.padding = '12px 0'; button.style.opacity = '0'; divider.style.width = '0px'; divider.style.opacity = '0'; collapseBtn.innerHTML = '►'; collapseBtn.title = '展开 Claude Code 安装助手'; } } // 获取用户ID的辅助函数 function getUserIdFromPage() { let userId = null; // 直接从localStorage中的user对象获取ID try { const userStr = localStorage.getItem('user'); if (userStr) { const user = JSON.parse(userStr); if (user && user.id) { userId = user.id.toString(); console.log('从localStorage[user]获取到用户ID:', userId); } } } catch (e) { console.log('解析localStorage[user]失败:', e); } return userId; } // 获取用户的API密钥 async function fetchUserApiKeys() { try { // 检查是否在 ikuncode.cc 域名下 if (!window.location.hostname.includes('ikuncode.cc')) { console.log('不在 ikuncode.cc 域名下,跳过自动获取'); return null; } console.log('正在获取API密钥...'); // 获取用户ID let userId = getUserIdFromPage(); if (!userId) { console.log('未找到用户ID,无法获取API密钥'); return null; } const headers = { 'accept': 'application/json, text/plain, */*', 'cache-control': 'no-store', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'veloera-user': userId }; console.log('使用用户ID:', userId); const response = await fetch('/api/token/?p=0&size=10', { method: 'GET', headers: headers, credentials: 'include' }); console.log('API响应状态:', response.status); if (response.ok) { const data = await response.json(); console.log('获取到的API数据:', data); return data; } else { const errorText = await response.text(); console.log('API请求失败:', response.status, response.statusText, errorText); return null; } } catch (error) { console.log('获取API密钥失败:', error); return null; } } // 显示API密钥选择器 function showApiKeySelector(apiKeys) { if (!apiKeys || !apiKeys.data || apiKeys.data.length === 0) { return false; } const selector = document.createElement('select'); selector.id = 'apiKeySelect'; selector.style.cssText = ` width: 100%; padding: 8px; margin: 10px 0; border: 1px solid #ddd; border-radius: 4px; `; // 添加默认选项 const defaultOption = document.createElement('option'); defaultOption.value = ''; defaultOption.textContent = '选择API密钥'; selector.appendChild(defaultOption); // 添加API密钥选项 apiKeys.data.forEach(key => { const option = document.createElement('option'); // 确保获取完整的token值 const tokenValue = key.token || key.key || key.name || key.id; option.value = tokenValue; // 显示友好的名称和部分token const displayName = key.name || key.title || '未命名密钥'; const displayToken = key.token ? key.token.substring(0, 20) + '...' : `ID: ${key.id}`; option.textContent = `${displayName} (${displayToken})`; // 添加调试信息 console.log('添加API密钥选项:', { name: displayName, value: tokenValue, fullKey: key }); selector.appendChild(option); }); return selector; } // 显示安装对话框 async function showInstallDialog() { // 先显示加载中的对话框 const dialog = document.createElement('div'); dialog.style.cssText = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 10001; background: white; padding: 20px; border-radius: 10px; box-shadow: 0 4px 20px rgba(0,0,0,0.3); max-width: 500px; width: 90%; `; // 添加背景遮罩 const overlay = document.createElement('div'); overlay.style.cssText = ` position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 10000; `; document.body.appendChild(overlay); document.body.appendChild(dialog); // 显示加载状态 dialog.innerHTML = `
正在获取API密钥...
`; // 尝试获取用户的API密钥 const apiKeys = await fetchUserApiKeys(); const hasApiKeys = apiKeys && apiKeys.data && apiKeys.data.length > 0; console.log('hasApiKeys:', hasApiKeys); if (hasApiKeys) { console.log('API密钥数量:', apiKeys.data.length); } // 更新对话框内容 dialog.innerHTML = `此脚本将生成安装命令和配置文件
${hasApiKeys ? '' + '' + '或者手动输入:
' : '' }npm install -g @anthropic-ai/claude-code
mkdir -p ~/.claude
claude