@floatingsk/dsh-vision 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -1
- package/clipboard/README.md +50 -0
- package/clipboard/clip-hint.js +58 -0
- package/clipboard/clip-state-server.js +45 -0
- package/clipboard/clipboard-watch.sh +73 -0
- package/clipboard/install.sh +85 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# dsh-vision
|
|
2
2
|
|
|
3
|
-
> 给 DeepSeek Harness(dsh
|
|
3
|
+
> 给 DeepSeek Harness(dsh)插件 与 Claude Code(MCP)提供视觉能力的工具:**本地 OCR(macOS / Windows)+ 云端 VLM(多供应商)图片理解**。
|
|
4
4
|
|
|
5
5
|
DeepSeek 的模型 API 目前不支持图像输入,`read_image` 因此无法使用。本插件提供两个工具绕过这个限制:
|
|
6
6
|
|
|
@@ -17,6 +17,7 @@ DeepSeek 的模型 API 目前不支持图像输入,`read_image` 因此无法
|
|
|
17
17
|
- 🔑 **灵活取 Key**:环境变量或 `~/.dsh/.credentials.yaml`
|
|
18
18
|
- 🧪 **零依赖单测**:核心逻辑用 Node 内置 `node:test` 覆盖(13 用例)
|
|
19
19
|
- 🌏 **多供应商 VLM**:内置百炼 / 硅基流动 / 智谱 / 火山方舟,OpenAI 兼容可加任意家
|
|
20
|
+
- 🔌 **双形态**:既是 dsh 插件,也是 MCP server(Claude Code 等 MCP 客户端直接用)
|
|
20
21
|
- 🪟 **Windows 支持**:附 PowerShell OCR 后端(Windows.Media.Ocr),VLM 通道跨平台
|
|
21
22
|
|
|
22
23
|
## 安装
|
|
@@ -176,6 +177,16 @@ claude mcp test dsh-vision # 或直接问 Claude:看下 /path/to/xxx.png 里
|
|
|
176
177
|
|
|
177
178
|
> MCP server 为纯 Node 实现(stdio JSON-RPC),无第三方依赖,Node >= 18 即可。
|
|
178
179
|
|
|
180
|
+
## 剪贴板贴图(copy-to-agent)
|
|
181
|
+
|
|
182
|
+
配套工具集(`clipboard/`):**复制图片 → 直接贴给 agent**,不用手动存文件、不用给路径。
|
|
183
|
+
|
|
184
|
+
```sh
|
|
185
|
+
cd clipboard && bash install.sh # 一键安装:LaunchAgent 自启 + 状态服务 + 前端提示
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
复制图片后,dsh web 右下角显示 `[图片已就绪]`,对 agent 说"看下我刚贴的图"即可。支持连续多张、Finder 多选。详见 [clipboard/README.md](./clipboard/README.md)。
|
|
189
|
+
|
|
179
190
|
## 开发
|
|
180
191
|
|
|
181
192
|
```sh
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# 剪贴板贴图工具集(clipboard)
|
|
2
|
+
|
|
3
|
+
让 dsh web 支持"**复制图片 → 直接贴给 agent**"的工作流:不需要手动保存文件、不需要给路径。
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
你在任何地方复制图片(截图 ⌘C / 右键复制图片 / Finder 多选)
|
|
7
|
+
↓ clipboard-watch.sh(常驻监听,LaunchAgent 开机自启)
|
|
8
|
+
图片自动保存到 pasted-images/(去重 + 只留最近 30 张)
|
|
9
|
+
↓ clip-state-server.js(本地状态服务 127.0.0.1:51799)
|
|
10
|
+
dsh web 前端 clip-hint.js(轮询状态)→ 输入框右下角显示 "[图片已就绪]"
|
|
11
|
+
↓ 你对 agent 说 "看下我刚贴的图"
|
|
12
|
+
agent 读取图片 → OCR 读文字 / VLM 看画面
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 文件
|
|
16
|
+
|
|
17
|
+
| 文件 | 作用 |
|
|
18
|
+
|---|---|
|
|
19
|
+
| `clipboard-watch.sh` | 剪贴板监听:图片数据(⌘C 图片)与文件引用(Finder 多选)双通道,自动保存 + 去重 + 清理 |
|
|
20
|
+
| `clip-state-server.js` | 本地 HTTP 状态服务(零依赖 Node),供前端轮询最新图片 |
|
|
21
|
+
| `clip-hint.js` | dsh web 前端注入脚本:检测到新图时右下角显示占位提示 |
|
|
22
|
+
| `install.sh` | 一键安装:部署脚本 + LaunchAgent 开机自启 + 启动状态服务 + 注入前端 |
|
|
23
|
+
|
|
24
|
+
## 安装
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
bash install.sh [保存目录,默认 ~/Documents/DeepSeek/pasted-images]
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
安装后**刷新 dsh web 页面**,复制一张图,右下角会出现绿色提示条 `[图片已就绪: xxx.png]`。
|
|
31
|
+
|
|
32
|
+
## 多图支持
|
|
33
|
+
|
|
34
|
+
- **连续复制**:每张都会保存,提示条显示"共 N 张,最近5张: ..."
|
|
35
|
+
- **Finder 多选**:选中多张图片 ⌘C,自动全部拷入
|
|
36
|
+
- 对 agent 说"**看下刚贴的图**"(最新一张)或"**看下刚贴的 N 张图**"(最近 N 张)
|
|
37
|
+
|
|
38
|
+
## 配置
|
|
39
|
+
|
|
40
|
+
| 项 | 位置 |
|
|
41
|
+
|---|---|
|
|
42
|
+
| 保存目录 | `install.sh` 第 1 个参数;状态服务读 `$HOME/Documents/DeepSeek/pasted-images` |
|
|
43
|
+
| 保留张数 | `clipboard-watch.sh` 第 2 个参数(默认 30) |
|
|
44
|
+
| 状态服务端口 | `install.sh` 的 `PORT` 变量(默认 51799),`clip-hint.js` 里 `STATE_URL` 需同步 |
|
|
45
|
+
| dsh web 注入 | `install.sh` 自动处理;dsh 升级后若失效,重跑 install.sh |
|
|
46
|
+
|
|
47
|
+
## 平台
|
|
48
|
+
|
|
49
|
+
- macOS(依赖 osascript 读剪贴板)
|
|
50
|
+
- 零第三方依赖:Node >= 18(状态服务)、系统自带 bash/osascript
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// clip-hint.js — dsh web 输入框剪贴板图片提示
|
|
2
|
+
// 轮询本地状态服务(clip-state-server),剪贴板有图片被捕获时,
|
|
3
|
+
// 在输入框上方显示 "[图片已就绪: xxx.png]" 占位提示。
|
|
4
|
+
(function () {
|
|
5
|
+
"use strict";
|
|
6
|
+
const STATE_URL = "http://127.0.0.1:51799/state";
|
|
7
|
+
const POLL_MS = 2000;
|
|
8
|
+
let lastTs = 0;
|
|
9
|
+
let hintEl = null;
|
|
10
|
+
|
|
11
|
+
function ensureHint() {
|
|
12
|
+
if (hintEl) return hintEl;
|
|
13
|
+
hintEl = document.createElement("div");
|
|
14
|
+
hintEl.id = "dsh-clip-hint";
|
|
15
|
+
hintEl.style.cssText = [
|
|
16
|
+
"position:fixed", "bottom:120px", "right:24px", "z-index:99999",
|
|
17
|
+
"background:rgba(20,20,24,0.92)", "color:#7ee787",
|
|
18
|
+
"padding:8px 14px", "border-radius:8px", "font-size:13px",
|
|
19
|
+
"font-family:ui-monospace,SFMono-Regular,Menlo,monospace",
|
|
20
|
+
"box-shadow:0 4px 16px rgba(0,0,0,0.35)", "border:1px solid rgba(126,231,135,0.35)",
|
|
21
|
+
"display:none", "pointer-events:none", "max-width:420px", "white-space:nowrap",
|
|
22
|
+
"overflow:hidden", "text-overflow:ellipsis",
|
|
23
|
+
].join(";");
|
|
24
|
+
document.body.appendChild(hintEl);
|
|
25
|
+
return hintEl;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function show(text) {
|
|
29
|
+
const el = ensureHint();
|
|
30
|
+
el.textContent = text;
|
|
31
|
+
el.style.display = "block";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function hide() {
|
|
35
|
+
if (hintEl) hintEl.style.display = "none";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function poll() {
|
|
39
|
+
try {
|
|
40
|
+
const res = await fetch(STATE_URL, { cache: "no-store" });
|
|
41
|
+
if (!res.ok) return;
|
|
42
|
+
const data = await res.json();
|
|
43
|
+
if (data.latest && data.ts !== lastTs) {
|
|
44
|
+
lastTs = data.ts;
|
|
45
|
+
const n = data.count > 1 ? "(共" + data.count + "张,最近5张: " + data.recent.join(", ") + ")" : "";
|
|
46
|
+
show("[图片已就绪: " + data.latest + "]" + n + " 说\"看下我刚贴的图\"即可");
|
|
47
|
+
// 10 秒后自动隐藏
|
|
48
|
+
setTimeout(hide, 10000);
|
|
49
|
+
}
|
|
50
|
+
} catch {
|
|
51
|
+
// 状态服务不可达(未启动),静默忽略
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 启动轮询
|
|
56
|
+
poll();
|
|
57
|
+
setInterval(poll, POLL_MS);
|
|
58
|
+
})();
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// clip-state-server.js — 剪贴板图片状态服务
|
|
2
|
+
// 供 dsh web 前端轮询:返回 pasted-images 目录的最新图片信息。
|
|
3
|
+
// 前端脚本(clip-hint.js)据此在输入框显示"[图片已就绪]"提示。
|
|
4
|
+
//
|
|
5
|
+
// 用法: node clip-state-server.js [PORT]
|
|
6
|
+
import { createServer } from "node:http";
|
|
7
|
+
import { readdirSync, statSync } from "node:fs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
|
|
10
|
+
const PORT = Number(process.argv[2] || 51799);
|
|
11
|
+
const IMG_DIR = join(process.env.HOME, "Documents", "DeepSeek", "pasted-images");
|
|
12
|
+
|
|
13
|
+
function latestImages(limit) {
|
|
14
|
+
try {
|
|
15
|
+
const files = readdirSync(IMG_DIR)
|
|
16
|
+
.filter((f) => f.startsWith("pasted-") && /\.(png|jpg|jpeg)$/i.test(f))
|
|
17
|
+
.map((f) => ({ name: f, mtime: statSync(join(IMG_DIR, f)).mtimeMs }))
|
|
18
|
+
.sort((a, b) => b.mtime - a.mtime)
|
|
19
|
+
.slice(0, limit);
|
|
20
|
+
if (files.length === 0) return null;
|
|
21
|
+
return {
|
|
22
|
+
latest: files[0].name,
|
|
23
|
+
ts: Math.round(files[0].mtime),
|
|
24
|
+
count: files.length,
|
|
25
|
+
recent: files.map((f) => f.name),
|
|
26
|
+
};
|
|
27
|
+
} catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
createServer((req, res) => {
|
|
33
|
+
// CORS:允许 dsh web(127.0.0.1:3080)跨域读取
|
|
34
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
35
|
+
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
36
|
+
if (req.url === "/state" || req.url === "/") {
|
|
37
|
+
const data = latestImages(5);
|
|
38
|
+
res.end(JSON.stringify(data ?? { latest: null, ts: 0, count: 0, recent: [] }));
|
|
39
|
+
} else {
|
|
40
|
+
res.statusCode = 404;
|
|
41
|
+
res.end('{"error":"not found"}');
|
|
42
|
+
}
|
|
43
|
+
}).listen(PORT, "127.0.0.1", () => {
|
|
44
|
+
console.log(`[clip-state-server] http://127.0.0.1:${PORT}/state`);
|
|
45
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# clipboard-watch.sh — 监听 macOS 剪贴板,图片自动落盘
|
|
3
|
+
# 你在任何地方复制图片(截图后 ⌘C / 网页右键复制图片 / 图片 App 里复制),
|
|
4
|
+
# 脚本自动保存到 OUT_DIR,文件名带时间戳,供 dsh agent 用 OCR/VLM 读取。
|
|
5
|
+
# 自动清理:只保留最近 MAX_FILES 张(默认 30),防止目录无限增长。
|
|
6
|
+
#
|
|
7
|
+
# 用法: bash clipboard-watch.sh [OUT_DIR] [MAX_FILES]
|
|
8
|
+
OUT_DIR="${1:-$HOME/Documents/DeepSeek/pasted-images}"
|
|
9
|
+
MAX_FILES="${2:-30}"
|
|
10
|
+
mkdir -p "$OUT_DIR"
|
|
11
|
+
|
|
12
|
+
LAST_HASH=""
|
|
13
|
+
echo "[clipboard-watch] 监听启动 | 保存目录: $OUT_DIR | 最多保留 $MAX_FILES 张"
|
|
14
|
+
|
|
15
|
+
# 保存一张图(带去重 + 清理)
|
|
16
|
+
save_image() {
|
|
17
|
+
local src="$1"
|
|
18
|
+
local hash ext out
|
|
19
|
+
hash=$(md5 -q "$src")
|
|
20
|
+
EXISTING=$(find "$OUT_DIR" -name "pasted-*.png" -exec md5 -q {} \; 2>/dev/null)
|
|
21
|
+
if echo "$EXISTING" | grep -qx "$hash"; then
|
|
22
|
+
echo "[$(date +%H:%M:%S)] 跳过重复图 (hash $hash)"
|
|
23
|
+
return
|
|
24
|
+
fi
|
|
25
|
+
ext="${src##*.}"; [ "$ext" != "png" ] && [ "$ext" != "jpg" ] && [ "$ext" != "jpeg" ] && [ "$ext" != "PNG" ] && [ "$ext" != "JPG" ] && ext="png"
|
|
26
|
+
TS=$(date +%Y%m%d-%H%M%S)
|
|
27
|
+
OUT="$OUT_DIR/pasted-$TS.$ext"
|
|
28
|
+
cp "$src" "$OUT"
|
|
29
|
+
echo "[$(date +%H:%M:%S)] 已保存: $OUT ($(stat -f%z "$OUT") bytes)"
|
|
30
|
+
# 清理旧图:只保留最近 MAX_FILES 张
|
|
31
|
+
ls -t "$OUT_DIR"/pasted-*.png 2>/dev/null | tail -n +$((MAX_FILES + 1)) | while read -r f; do
|
|
32
|
+
rm -f "$f"
|
|
33
|
+
echo "[$(date +%H:%M:%S)] 清理旧图: $(basename "$f")"
|
|
34
|
+
done
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
while true; do
|
|
38
|
+
# ── 通道1:剪贴板图片数据(⌘C 复制图片 / 截图) ──
|
|
39
|
+
TMP="/tmp/clip_paste_$$.png"
|
|
40
|
+
osascript \
|
|
41
|
+
-e "set p to POSIX file \"$TMP\"" \
|
|
42
|
+
-e 'set d to the clipboard as «class PNGf»' \
|
|
43
|
+
-e 'set fp to open for access p with write permission' \
|
|
44
|
+
-e 'write d to fp' \
|
|
45
|
+
-e 'close access fp' >/dev/null 2>&1
|
|
46
|
+
if [ -f "$TMP" ] && [ -s "$TMP" ]; then
|
|
47
|
+
save_image "$TMP"
|
|
48
|
+
rm -f "$TMP"
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# ── 通道2:剪贴板文件引用(Finder 多选图片 ⌘C) ──
|
|
52
|
+
# 剪贴板为图片数据时 as list 会失败(输出空),自然跳过;仅文件引用时返回 "file <HFS路径>"
|
|
53
|
+
CLIPLIST=$(osascript -e 'the clipboard as list' 2>/dev/null)
|
|
54
|
+
if [ -n "$CLIPLIST" ]; then
|
|
55
|
+
while IFS= read -r line; do
|
|
56
|
+
case "$line" in
|
|
57
|
+
file\ *)
|
|
58
|
+
hfs="${line#file }"
|
|
59
|
+
P=$(osascript -e "POSIX path of (alias \"$hfs\")" 2>/dev/null)
|
|
60
|
+
case "$P" in
|
|
61
|
+
*.png|*.jpg|*.jpeg|*.PNG|*.JPG|*.JPEG)
|
|
62
|
+
if [ -f "$P" ]; then
|
|
63
|
+
save_image "$P"
|
|
64
|
+
fi
|
|
65
|
+
;;
|
|
66
|
+
esac
|
|
67
|
+
;;
|
|
68
|
+
esac
|
|
69
|
+
done <<< "$CLIPLIST"
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
sleep 2.5
|
|
73
|
+
done
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# install.sh — 安装 dsh-vision 剪贴板贴图工具集
|
|
3
|
+
#
|
|
4
|
+
# 功能:
|
|
5
|
+
# 1. 部署脚本到 $INSTALL_DIR
|
|
6
|
+
# 2. 注册 LaunchAgent(开机自启剪贴板监听)
|
|
7
|
+
# 3. 启动状态服务(clip-state-server,端口 $PORT)
|
|
8
|
+
# 4. 注入 dsh web 前端提示脚本(clip-hint.js → dist/index.html)
|
|
9
|
+
#
|
|
10
|
+
# 用法: bash install.sh [保存目录]
|
|
11
|
+
set -e
|
|
12
|
+
|
|
13
|
+
SAVE_DIR="${1:-$HOME/Documents/DeepSeek/pasted-images}"
|
|
14
|
+
INSTALL_DIR="$HOME/.dsh-vision/clipboard"
|
|
15
|
+
PORT=51799
|
|
16
|
+
LABEL="com.floatingsk.clipboard-watch"
|
|
17
|
+
|
|
18
|
+
mkdir -p "$INSTALL_DIR" "$SAVE_DIR"
|
|
19
|
+
|
|
20
|
+
echo "==> 1/4 部署脚本到 $INSTALL_DIR"
|
|
21
|
+
cp "$(dirname "$0")/clipboard-watch.sh" "$INSTALL_DIR/"
|
|
22
|
+
cp "$(dirname "$0")/clip-state-server.js" "$INSTALL_DIR/"
|
|
23
|
+
cp "$(dirname "$0")/clip-hint.js" "$INSTALL_DIR/"
|
|
24
|
+
chmod +x "$INSTALL_DIR/clipboard-watch.sh"
|
|
25
|
+
|
|
26
|
+
echo "==> 2/4 注册 LaunchAgent(开机自启)"
|
|
27
|
+
PLIST="$HOME/Library/LaunchAgents/$LABEL.plist"
|
|
28
|
+
cat > "$PLIST" <<EOF
|
|
29
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
30
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
31
|
+
<plist version="1.0">
|
|
32
|
+
<dict>
|
|
33
|
+
<key>Label</key>
|
|
34
|
+
<string>$LABEL</string>
|
|
35
|
+
<key>ProgramArguments</key>
|
|
36
|
+
<array>
|
|
37
|
+
<string>/bin/bash</string>
|
|
38
|
+
<string>$INSTALL_DIR/clipboard-watch.sh</string>
|
|
39
|
+
<string>$SAVE_DIR</string>
|
|
40
|
+
</array>
|
|
41
|
+
<key>RunAtLoad</key>
|
|
42
|
+
<true/>
|
|
43
|
+
<key>KeepAlive</key>
|
|
44
|
+
<true/>
|
|
45
|
+
<key>StandardOutPath</key>
|
|
46
|
+
<string>$INSTALL_DIR/clipboard-watch.log</string>
|
|
47
|
+
<key>StandardErrorPath</key>
|
|
48
|
+
<string>$INSTALL_DIR/clipboard-watch.log</string>
|
|
49
|
+
<key>ProcessType</key>
|
|
50
|
+
<string>Background</string>
|
|
51
|
+
</dict>
|
|
52
|
+
</plist>
|
|
53
|
+
EOF
|
|
54
|
+
launchctl bootout "gui/$(id -u)/$LABEL" 2>/dev/null || true
|
|
55
|
+
launchctl bootstrap "gui/$(id -u)" "$PLIST" 2>/dev/null || launchctl load -w "$PLIST" 2>/dev/null || echo " (LaunchAgent 加载失败,可手动执行: launchctl bootstrap gui/\$(id -u) $PLIST)"
|
|
56
|
+
|
|
57
|
+
echo "==> 3/4 启动状态服务 (http://127.0.0.1:$PORT/state)"
|
|
58
|
+
if lsof -iTCP:$PORT -sTCP:LISTEN >/dev/null 2>&1; then
|
|
59
|
+
echo " (端口 $PORT 已被占用,跳过)"
|
|
60
|
+
else
|
|
61
|
+
nohup node "$INSTALL_DIR/clip-state-server.js" "$PORT" > "$INSTALL_DIR/clip-state-server.log" 2>&1 &
|
|
62
|
+
echo " 已启动 (PID $!)"
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
echo "==> 4/4 注入 dsh web 前端提示"
|
|
66
|
+
DIST=""
|
|
67
|
+
if command -v node >/dev/null 2>&1; then
|
|
68
|
+
DIST=$(node -e "try{console.log(require.resolve('@deepseek-ai/dsh-web-frontend/dist/index.html'))}catch(e){process.exit(1)}" 2>/dev/null || true)
|
|
69
|
+
fi
|
|
70
|
+
if [ -z "$DIST" ] || [ ! -f "$DIST" ]; then
|
|
71
|
+
echo " (未找到 dsh web dist,跳过注入。找到后手动执行: cp $INSTALL_DIR/clip-hint.js <dist> && 在 index.html 的 </body> 前加 <script src=\"/clip-hint.js\"></script>)"
|
|
72
|
+
else
|
|
73
|
+
cp "$INSTALL_DIR/clip-hint.js" "$(dirname "$DIST")/clip-hint.js"
|
|
74
|
+
if ! grep -q "clip-hint.js" "$DIST"; then
|
|
75
|
+
cp "$DIST" "$DIST.bak"
|
|
76
|
+
sed -i '' 's|</body>| <script src="/clip-hint.js"></script>\n </body>|' "$DIST"
|
|
77
|
+
fi
|
|
78
|
+
echo " 已注入: $DIST"
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
echo ""
|
|
82
|
+
echo "✅ 安装完成"
|
|
83
|
+
echo " 保存目录: $SAVE_DIR"
|
|
84
|
+
echo " 提示条: 复制图片后刷新 dsh web 页面,右下角会显示 [图片已就绪]"
|
|
85
|
+
echo " 使用: 复制图片 → 说\"看下我刚贴的图\""
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@floatingsk/dsh-vision",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "为 DeepSeek Harness
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"description": "为 DeepSeek Harness(dsh 插件)与 Claude Code(MCP)提供图片理解能力:本地 OCR(macOS Vision / Windows 内置 OCR)+ 云端 VLM(多供应商,OpenAI 兼容)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"exports": {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
"lib",
|
|
12
12
|
"mcp",
|
|
13
|
+
"clipboard",
|
|
13
14
|
"bin/vision-ocr.swift",
|
|
14
15
|
"bin/vision-ocr.ps1",
|
|
15
16
|
"README.md",
|