feat: 配置独立到 ~/kimi-eyes/,向导支持目标工具选择与协议联动

配置从 ~/.kimi-code/kimi-eyes 移到 ~/kimi-eyes/config.json(KIMI_EYES_HOME 可覆盖),KimiCode/Claude Code/Codex 三工具共用;setup.mjs 向导新增目标工具选择(ClaudeCode 固定 Anthropic、Codex 固定 OpenAI、KimiCode 手动选协议)并写入 tool 字段;uninstall/SYSTEM/README/网页同步。1.0.9 → 1.0.10。
This commit is contained in:
billowliu2 committed 2026-08-10 10:27:53 +08:00
1 parent e689b43cd8
commit 711b978240
8 files changed
+57 -15

No files matched your search

+2 -2
View File
@@ -96,7 +96,7 @@ multimodal model → 1×1 image vision check → optionally enter your main mode
models.dev, and if that model supports native image input the tools refuse with a models.dev, and if that model supports native image input the tools refuse with a
hint — the code-level "multimodal → don't trigger" switch (see hint — the code-level "multimodal → don't trigger" switch (see
[Triggering](#triggering-everyday-fully-automatic)) [Triggering](#triggering-everyday-fully-automatic))
- Config is written to `~/.kimi-code/kimi-eyes/config.json` (`chmod 600` on - Config is written to `~/kimi-eyes/config.json` (`chmod 600` on
non-Windows systems) non-Windows systems)
### 3. Enable ### 3. Enable
@@ -256,7 +256,7 @@ claude mcp add --scope user kimi-eyes -- npx --prefer-online -y -p kimi-eyes kim
npx kimi-eyes setup npx kimi-eyes setup
``` ```
> Same config is shared: kimi-eyes uses `~/.kimi-code/kimi-eyes/config.json` (or > Same config is shared: kimi-eyes uses `~/kimi-eyes/config.json` (or
> `VISION_*` env vars) under both Kimi Code and Claude Code. > `VISION_*` env vars) under both Kimi Code and Claude Code.
### 4. Guidance rules (CLAUDE.md) ### 4. Guidance rules (CLAUDE.md)
+3 -3
View File
@@ -64,12 +64,12 @@ cd D:\AIGC\Plugin\kimi-eyes
node setup.mjs node setup.mjs
``` ```
向导按顺序引导:**选择协议(OpenAI 兼容 / Anthropic)→ 填写 BaseUrl → 填写 API Key(掩码输入)→ 拉取模型列表选择多模态模型 → 1×1 图片视觉验证 → 可选填写当前主模型名(用于触发判断)→ 写入配置**。 向导按顺序引导:**选择目标工具(KimiCode / Claude Code / Codex)→ 选择视觉协议 → 填写 BaseUrl → 填写 API Key(掩码输入)→ 拉取模型列表选择多模态模型 → 1×1 图片视觉验证 → 可选填写当前主模型名(用于触发判断)→ 写入配置**。选择 Claude Code 时协议固定为 Anthropic、Codex 固定为 OpenAI,仅 KimiCode 需手动选择协议(OpenAI 兼容 / Anthropic)。
- 模型列表自动从 `GET {BaseUrl}/models` 拉取,用内置的 models.dev 数据库**精确标注「✓视觉 / 文本」**,未收录的按关键词标「★疑似」;拉取失败时回退为手动输入 - 模型列表自动从 `GET {BaseUrl}/models` 拉取,用内置的 models.dev 数据库**精确标注「✓视觉 / 文本」**,未收录的按关键词标「★疑似」;拉取失败时回退为手动输入
- 视觉验证通过才落盘,防止配到一个不收图片的模型 - 视觉验证通过才落盘,防止配到一个不收图片的模型
- 最后一步可填写**当前主模型名**(可选):插件用 models.dev 判定后,若该模型支持原生识图,工具会直接提示无需调用——即「多模态不触发」的代码级判断(详见[触发](#触发日常全自动)) - 最后一步可填写**当前主模型名**(可选):插件用 models.dev 判定后,若该模型支持原生识图,工具会直接提示无需调用——即「多模态不触发」的代码级判断(详见[触发](#触发日常全自动))
- 配置写入 `~/.kimi-code/kimi-eyes/config.json`(类 Unix 系统自动 `chmod 600`) - 配置写入 `~/kimi-eyes/config.json`(独立于 kimi-code 目录,KimiCode / Claude Code / Codex 三工具共用;类 Unix 系统自动 `chmod 600`;可用 `KIMI_EYES_HOME` 覆盖)
### 3. 启用 ### 3. 启用
@@ -207,7 +207,7 @@ claude mcp add --scope user kimi-eyes -- npx --prefer-online -y -p kimi-eyes kim
npx kimi-eyes setup npx kimi-eyes setup
``` ```
> 复用同一份配置:kimi-eyes 在 KimiCode 和 Claude Code 下共用 `~/.kimi-code/kimi-eyes/config.json`(或环境变量 `VISION_*`)。 > 复用同一份配置:kimi-eyes 在 KimiCode / Claude Code / Codex 下共用 `~/kimi-eyes/config.json`(或环境变量 `VISION_*`)。
### 4. 引导规则(CLAUDE.md) ### 4. 引导规则(CLAUDE.md)
+1 -1
View File
@@ -529,7 +529,7 @@ claude mcp remove kimi-eyes</pre>
</div> </div>
<div class="faq-item reveal"> <div class="faq-item reveal">
<button class="faq-q">我的 API Key 安全吗?<span class="ico">+</span></button> <button class="faq-q">我的 API Key 安全吗?<span class="ico">+</span></button>
<div class="faq-a"><div class="faq-a-inner">插件不内置任何密钥,视觉请求只发往你配置的 BaseUrl。Key 以明文存于 ~/.kimi-code/kimi-eyes/config.json(类 Unix 系统已设 600 权限),不会上传到任何第三方。也可用 VISION_API_KEY 等环境变量替代配置文件。</div></div> <div class="faq-a"><div class="faq-a-inner">插件不内置任何密钥,视觉请求只发往你配置的 BaseUrl。Key 以明文存于 ~/kimi-eyes/config.json(独立目录,KimiCode / Claude Code / Codex 三工具共用;类 Unix 系统已设 600 权限),不会上传到任何第三方。也可用 VISION_API_KEY 等环境变量替代配置文件。</div></div>
</div> </div>
<div class="faq-item reveal"> <div class="faq-item reveal">
<button class="faq-q">支持哪些图片格式?<span class="ico">+</span></button> <button class="faq-q">支持哪些图片格式?<span class="ico">+</span></button>
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "kimi-eyes", "name": "kimi-eyes",
"version": "1.0.9", "version": "1.0.10",
"description": "Give non-multimodal models vision: analyze local images and clipboard screenshots through a user-configured VLM API (OpenAI-compatible or Anthropic protocol).", "description": "Give non-multimodal models vision: analyze local images and clipboard screenshots through a user-configured VLM API (OpenAI-compatible or Anthropic protocol).",
"keywords": [ "keywords": [
"vision", "vision",
+4 -2
View File
@@ -46,8 +46,10 @@ export const ONE_PX_PNG_BASE64 =
// Resolution order: environment variables (VISION_*) > config.json. // Resolution order: environment variables (VISION_*) > config.json.
// protocol resolves to 'openai' by default when nothing is set. // protocol resolves to 'openai' by default when nothing is set.
export function getConfig(env = process.env) { export function getConfig(env = process.env) {
const home = env.KIMI_CODE_HOME || path.join(os.homedir(), '.kimi-code'); // 配置独立放在用户目录 ~/kimi-eyes/config.json(不依赖 .kimi-code 插件目录),
const cfgPath = path.join(home, 'kimi-eyes', 'config.json'); // KimiCode / Claude Code / Codex 三工具共用同一份;可用 KIMI_EYES_HOME 覆盖。
const home = env.KIMI_EYES_HOME || path.join(os.homedir(), 'kimi-eyes');
const cfgPath = path.join(home, 'config.json');
let file = {}; let file = {};
try { try {
file = JSON.parse(fs.readFileSync(cfgPath, 'utf8')); file = JSON.parse(fs.readFileSync(cfgPath, 'utf8'));
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "kimi-eyes", "name": "kimi-eyes",
"version": "1.0.9", "version": "1.0.10",
"description": "Give non-multimodal models in Kimi Code the ability to analyze images and screenshots via a user-configured VLM (OpenAI-compatible or Anthropic protocol).", "description": "Give non-multimodal models in Kimi Code the ability to analyze images and screenshots via a user-configured VLM (OpenAI-compatible or Anthropic protocol).",
"keywords": [ "keywords": [
"kimi", "kimi",
+43 -4
View File
@@ -129,6 +129,20 @@ async function fetchModels(protocol, baseUrl, apiKey) {
return [...new Set(list)]; return [...new Set(list)];
} }
async function chooseTool() {
console.log(' 选择目标工具:');
console.log(' [1] KimiCode(插件方式,需手动选协议)');
console.log(' [2] Claude Code(MCP 方式,协议固定 Anthropic)');
console.log(' [3] Codex(MCP 方式,协议固定 OpenAI)');
for (;;) {
const v = (await ask(' 输入序号 [1/2/3]: ')).trim();
if (v === '1') return 'kimicode';
if (v === '2') return 'claudecode';
if (v === '3') return 'codex';
console.log(' 无效输入,请输入 1、2 或 3。');
}
}
async function chooseProtocol() { async function chooseProtocol() {
console.log(' 选择视觉 API 协议:'); console.log(' 选择视觉 API 协议:');
console.log(' [1] OpenAI 兼容 (Chat Completions)'); console.log(' [1] OpenAI 兼容 (Chat Completions)');
@@ -194,20 +208,33 @@ async function verifyModel(cfg) {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
async function main() { async function main() {
const home = process.env.KIMI_CODE_HOME || path.join(os.homedir(), '.kimi-code'); const configPath = path.join(
const configPath = path.join(home, 'kimi-eyes', 'config.json'); process.env.KIMI_EYES_HOME || path.join(os.homedir(), 'kimi-eyes'),
'config.json'
);
console.log('=== Kimi Eyes 配置向导 ==='); console.log('=== Kimi Eyes 配置向导 ===');
console.log(`配置将写入: ${configPath}\n`); console.log(`配置将写入: ${configPath}\n`);
const protocol = await chooseProtocol(); const tool = await chooseTool();
let protocol;
if (tool === 'claudecode') {
console.log(' Claude Code 目标:协议固定为 Anthropic (Messages API)\n');
protocol = 'anthropic';
} else if (tool === 'codex') {
console.log(' Codex 目标:协议固定为 OpenAI (Chat Completions)\n');
protocol = 'openai';
} else {
protocol = await chooseProtocol();
}
const baseUrl = await askRequired(' 视觉 API BaseUrl (如 https://api.openai.com/v1): ', { const baseUrl = await askRequired(' 视觉 API BaseUrl (如 https://api.openai.com/v1): ', {
validate: (v) => (/^https?:\/\//i.test(v) ? null : 'BaseUrl 必须以 http:// 或 https:// 开头。'), validate: (v) => (/^https?:\/\//i.test(v) ? null : 'BaseUrl 必须以 http:// 或 https:// 开头。'),
}); });
const apiKey = await askRequired(' API Key: ', { hidden: true }); const apiKey = await askRequired(' API Key: ', { hidden: true });
const model = await chooseModel(protocol, baseUrl, apiKey); const model = await chooseModel(protocol, baseUrl, apiKey);
const cfg = { protocol, baseUrl, apiKey, model }; const cfg = { protocol, baseUrl, apiKey, model, tool };
console.log(''); console.log('');
for (let attempt = 0; attempt < 3; attempt++) { for (let attempt = 0; attempt < 3; attempt++) {
@@ -235,14 +262,26 @@ async function main() {
console.log(''); console.log('');
console.log(`✓ 配置已写入: ${configPath}`); console.log(`✓ 配置已写入: ${configPath}`);
console.log(` tool : ${cfg.tool}`);
console.log(` protocol: ${cfg.protocol}`); console.log(` protocol: ${cfg.protocol}`);
console.log(` baseUrl : ${cfg.baseUrl}`); console.log(` baseUrl : ${cfg.baseUrl}`);
console.log(` model : ${cfg.model}`); console.log(` model : ${cfg.model}`);
if (cfg.mainModel) console.log(` mainModel: ${cfg.mainModel} (触发判断用)`); if (cfg.mainModel) console.log(` mainModel: ${cfg.mainModel} (触发判断用)`);
console.log(''); console.log('');
console.log('下一步:'); console.log('下一步:');
if (tool === 'kimicode') {
console.log(` 1. 安装插件: /plugins install ${__dirname}`); console.log(` 1. 安装插件: /plugins install ${__dirname}`);
console.log(' (国内镜像: /plugins install https://git.codingplan.site/admin/kimi-eyes/archive/main.zip)');
console.log(' 2. 启用插件: /reload'); console.log(' 2. 启用插件: /reload');
} else if (tool === 'claudecode') {
console.log(' 1. 挂载 MCP(全局): claude mcp add --scope user kimi-eyes -- node <插件目录>/mcp/server.mjs');
console.log(' npx 通用版: claude mcp add --scope user kimi-eyes -- npx --prefer-online -y -p kimi-eyes kimi-eyes-mcp');
console.log(' 2. 验证: claude mcp list');
} else {
console.log(' 1. 挂载 MCP: codex mcp add kimi-eyes -- node <插件目录>/mcp/server.mjs');
console.log(' npx 通用版: codex mcp add kimi-eyes -- npx --prefer-online -y -p kimi-eyes kimi-eyes-mcp');
console.log(' 2. 验证: codex mcp list');
}
console.log(' 3. 开始使用: 非多模态模型下 @图片路径 或 截图后提问'); console.log(' 3. 开始使用: 非多模态模型下 @图片路径 或 截图后提问');
} }
+2 -1
View File
@@ -26,7 +26,8 @@ const PLUGIN_ID = 'kimi-eyes';
const home = process.env.KIMI_CODE_HOME || path.join(os.homedir(), '.kimi-code'); const home = process.env.KIMI_CODE_HOME || path.join(os.homedir(), '.kimi-code');
const installedJsonPath = path.join(home, 'plugins', 'installed.json'); const installedJsonPath = path.join(home, 'plugins', 'installed.json');
const managedDir = path.join(home, 'plugins', 'managed', PLUGIN_ID); const managedDir = path.join(home, 'plugins', 'managed', PLUGIN_ID);
const configDir = path.join(home, PLUGIN_ID); // 配置独立目录(三工具共用),不再放在 .kimi-code/kimi-eyes
const configDir = process.env.KIMI_EYES_HOME || path.join(os.homedir(), 'kimi-eyes');
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// 交互确认(TTY 用 readline;非 TTY / --yes 返回默认值) // 交互确认(TTY 用 readline;非 TTY / --yes 返回默认值)