fish-dock-plugin-filemgr 1.0.4 → 1.0.5
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 +19 -74
- package/package.json +4 -12
- package/{dist/filemgr/plugin.json → plugin.json} +2 -1
- package/LICENSE +0 -32
- package/bin/fish-dock-filemgr.mjs +0 -151
- package/dist/filemgr/README.md +0 -62
- package/dist/jassdingk.filemgr.fish-plugin +0 -0
- /package/{dist/filemgr/bridge.js → bridge.js} +0 -0
- /package/{dist/filemgr/plugins → plugins}/filemgr/FolderPicker.ps1 +0 -0
- /package/{dist/filemgr/plugins → plugins}/filemgr/backend.mjs +0 -0
- /package/{dist/filemgr/plugins → plugins}/filemgr/clip.ps1 +0 -0
- /package/{dist/filemgr/plugins → plugins}/filemgr/dock.css +0 -0
- /package/{dist/filemgr/plugins → plugins}/filemgr/filemgr.css +0 -0
- /package/{dist/filemgr/plugins → plugins}/filemgr/page.css +0 -0
- /package/{dist/filemgr/plugins → plugins}/filemgr/page.html +0 -0
- /package/{dist/filemgr/plugins → plugins}/filemgr/page.js +0 -0
- /package/{dist/filemgr/plugins → plugins}/filemgr/pick-files.ps1 +0 -0
- /package/{dist/filemgr/plugins → plugins}/filemgr/pick-folder.ps1 +0 -0
- /package/{dist/filemgr/plugins → plugins}/filemgr/preview.mjs +0 -0
- /package/{dist/filemgr/plugins → plugins}/filemgr/sdk.mjs +0 -0
- /package/{dist/filemgr/plugins → plugins}/filemgr/stash.css +0 -0
- /package/{dist/filemgr/plugins → plugins}/filemgr/stash.mjs +0 -0
package/README.md
CHANGED
|
@@ -1,27 +1,18 @@
|
|
|
1
|
-
# 文件管理
|
|
1
|
+
# 文件管理
|
|
2
2
|
|
|
3
|
-
把 FISH Dock
|
|
4
|
-
|
|
5
|
-
插件 id `jassdingk.filemgr`,宿主 API 1,兼容 **FISH Dock v1.2.3 及更早的官方发行版**,不要求宿主做任何改动。
|
|
3
|
+
把 FISH Dock 变成随手可用的文件工作台:左边逛目录、右边看内容,中间还能把常用文件先「暂存」起来,随时拖进别的程序。
|
|
6
4
|
|
|
7
5
|
## 功能
|
|
8
6
|
|
|
9
7
|
### 目录浏览 + 预览
|
|
10
8
|
|
|
11
|
-
-
|
|
9
|
+
- **目录浏览**:从磁盘根目录、用户目录、桌面 / 文档 / 下载逐层进入;支持把文件 / 文件夹直接拖进面板。
|
|
12
10
|
- **预览**:Markdown 渲染、图片(PNG / JPEG / GIF / WebP / BMP / AVIF / ICO / SVG)、Office 文本抽取(docx 段落与标题、xlsx 多工作表、pptx 每页文字,原生解析 OOXML,不需要装 Office)、代码高亮行号、纯文本与二进制兜底。
|
|
13
11
|
- **上下并列**:上半是文件夹浏览器(面包屑 + 列表 + 上一级 / 刷新 / 常用文件夹 / 固定),下半是预览;中间分隔条可拖动调高,高度会被记住。
|
|
14
12
|
- **框选与拖入暂存**:在列表里拖出选框可批量选中(Ctrl / Shift 点选切换),选中项直接拖到左侧暂存区即批量加入;拖到一半拖出列表会自动从「框选」切到「搬运」。
|
|
15
13
|
- **常用文件夹**:记住打开过的目录,浮层里快速跳转;可把目录「固定」到最上面。
|
|
16
14
|
|
|
17
|
-
###
|
|
18
|
-
|
|
19
|
-
- 拖入文件或文件夹即加入暂存区,也可以右键 / 按钮添加。
|
|
20
|
-
- **分组**:暂存区支持多个分组标签,点击切换,标签可折叠;删除分组只走标签右侧的 ×。分组之间完全隔离,切组不会串条目。
|
|
21
|
-
- **拖出**:把暂存项直接拖到桌面、资源管理器、微信等外部程序。
|
|
22
|
-
- 复制路径、复制为文件、多选批量、去重、清空,偏好持久化。
|
|
23
|
-
|
|
24
|
-
## 选择文件夹
|
|
15
|
+
### 选择文件夹
|
|
25
16
|
|
|
26
17
|
「打开文件夹」默认调用 **Windows 原生文件夹选择框**(`pick-folder.ps1` + IFileOpenDialog),选完直接进入该目录。
|
|
27
18
|
|
|
@@ -34,7 +25,7 @@
|
|
|
34
25
|
| 自行编译、带 `fish:hold` 的宿主 | Windows 原生对话框 | 仅对话框期间临时锁定 |
|
|
35
26
|
| 官方发行版(≤ v1.2.3) | 内置选择器 | 不锁定 |
|
|
36
27
|
|
|
37
|
-
|
|
28
|
+
宿主侧要支持这条路,需要三处改动(都已在 `FISH-Dock` 上游以补丁形式验证过):
|
|
38
29
|
|
|
39
30
|
1. `sdk/browser/bridge.js` 暴露 `hold(on)` → `parent.postMessage({type:'fish:hold', ticket, on}, '*')`
|
|
40
31
|
2. `Wakuwaku/src/pet/extension-page.js` 收 `fish:hold` 写入 `record.hold`,并新增 `onHold(record, on)` 回调;`park()` / `enter()` / `retire()` 各自同步
|
|
@@ -42,76 +33,30 @@
|
|
|
42
33
|
|
|
43
34
|
只改插件包、不重编译宿主时,插件自动走内置选择器,功能完整不缺。
|
|
44
35
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
### 方式一:npm(最省事)
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
npm i -g fish-dock-plugin-filemgr
|
|
51
|
-
fish-dock-filemgr # 校验 + 拷到宿主 packages 目录 + 写注册表
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
装完重启 FISH Dock 即可。其它子命令:
|
|
55
|
-
|
|
56
|
-
```bash
|
|
57
|
-
fish-dock-filemgr --dry-run # 只校验包完整性,不写磁盘
|
|
58
|
-
fish-dock-filemgr --path # 只打印 .fish-plugin 路径,自己拖进宿主「从文件安装」
|
|
59
|
-
fish-dock-filemgr --uninstall # 从宿主注册表移除本插件
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### 方式二:打过发行包,走宿主「从文件安装」
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
npm run build
|
|
66
|
-
# 产物 dist/jassdingk.filemgr.fish-plugin,用 FISH Dock 插件页的「从文件安装」装上
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### 方式三:开发加载
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
npm run build
|
|
73
|
-
# 产物 dist/filemgr 就是一个完整的开发目录(含 plugin.json),交给 FISH Dock 开发加载即可
|
|
74
|
-
```
|
|
36
|
+
### 文件暂存(中转站)
|
|
75
37
|
|
|
76
|
-
|
|
38
|
+
- 拖入文件或文件夹即加入暂存区,也可以右键 / 按钮添加。
|
|
39
|
+
- **分组**:暂存区支持多个分组标签,点击切换,标签可折叠;删除分组只走标签右侧的 ×。
|
|
40
|
+
- **拖出**:把暂存项直接拖到桌面、资源管理器、微信等外部程序。
|
|
41
|
+
- 复制路径、复制为文件、多选批量、去重、清空,偏好持久化。
|
|
77
42
|
|
|
78
43
|
## 说明
|
|
79
44
|
|
|
80
45
|
- 只读取路径白名单内的文件,路径解析后必须落在允许的根目录之下;UNC 路径一律拒绝。
|
|
81
|
-
- 「打开文件夹」在支持 `fish:hold` 的宿主上会短暂启动系统 PowerShell 调起 Windows 原生文件夹对话框(`pick-folder.ps1
|
|
46
|
+
- 「打开文件夹」在支持 `fish:hold` 的宿主上会短暂启动系统 PowerShell 调起 Windows 原生文件夹对话框(`pick-folder.ps1`),用于拿到用户亲手选择的路径;不加 `fish:hold` 的宿主上不会启动子进程,走内置选择器。除此之外不启动任何子进程。
|
|
82
47
|
- 页面运行在宿主沙箱里(`default-src 'none'`),PDF 与音视频不做内联播放,会提示用系统程序打开。
|
|
83
48
|
- 不发起网络请求。
|
|
84
|
-
- 大文件保护:单次文本预览上限 800 KB、目录条目上限 2000 条、Office 文件上限 200 MB,超限会截断并给出提示,不会把插件进程撑死。
|
|
85
49
|
|
|
86
50
|
## 存储
|
|
87
51
|
|
|
88
|
-
|
|
52
|
+
偏好(布局、最近打开、额外根目录、暂存分组)保存在插件命名空间的 `config/prefs.json`。
|
|
89
53
|
|
|
90
|
-
##
|
|
54
|
+
## 开发
|
|
91
55
|
|
|
56
|
+
```bash
|
|
57
|
+
# 本地暂存(模拟官方 tools/stage-development.mjs 的产出)
|
|
58
|
+
node _stage_filemgr.mjs
|
|
59
|
+
# 产物
|
|
60
|
+
# dist/filemgr.fish-plugin
|
|
61
|
+
# _stage/filemgr/ ← 可直接用 FISH Dock 的「从文件安装」装上验证
|
|
92
62
|
```
|
|
93
|
-
plugins/filemgr/
|
|
94
|
-
backend.mjs 后端入口:命令路由 + 帧体积兜底
|
|
95
|
-
preview.mjs 目录树 / 文本 / 图片 / Office 读取
|
|
96
|
-
stash.mjs 暂存区数据与拖出服务
|
|
97
|
-
page.html 页面结构(上下并列 + 左侧暂存)
|
|
98
|
-
page.js 页面逻辑(浏览、预览、框选、暂存、目录选择器)
|
|
99
|
-
page.css 布局与主题
|
|
100
|
-
filemgr.css 浏览器列表、行内按钮、高亮
|
|
101
|
-
stash.css 暂存区与分组标签
|
|
102
|
-
dock.css 与宿主共享的配色变量
|
|
103
|
-
pick-folder.ps1 原生文件夹对话框(内联 C#,不依赖 .cs 文件)
|
|
104
|
-
pick-files.ps1 原生多文件对话框
|
|
105
|
-
clip.ps1 复制到剪贴板
|
|
106
|
-
sdk/
|
|
107
|
-
browser/bridge.js 宿主注入页面的桥(官方 v1.2.3 原版)
|
|
108
|
-
node/plugin.mjs 后端 SDK(官方 v1.2.3 原版)
|
|
109
|
-
tools/
|
|
110
|
-
build.mjs 打发行包 / 开发目录
|
|
111
|
-
bin/
|
|
112
|
-
fish-dock-filemgr.mjs npm 全局命令:校验 + 安装 / 卸载插件
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## 许可
|
|
116
|
-
|
|
117
|
-
MIT。`sdk/` 下的两个文件来自 [Fish-under-sea/FISH-Dock](https://github.com/Fish-under-sea/FISH-Dock)(MIT),保留原作者版权。
|
package/package.json
CHANGED
|
@@ -1,25 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fish-dock-plugin-filemgr",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "FISH Dock 文件管理插件:目录浏览 + 文件预览(Markdown / 图片 / Office / 代码)+ 文件暂存中转站,兼容 FISH Dock v1.2.3 及更早官方发行版。",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"fish-dock-filemgr": "bin/fish-dock-filemgr.mjs"
|
|
8
|
-
},
|
|
9
6
|
"files": [
|
|
10
|
-
"
|
|
11
|
-
"dist/",
|
|
7
|
+
"plugin.json",
|
|
12
8
|
"README.md",
|
|
13
|
-
"
|
|
9
|
+
"bridge.js",
|
|
10
|
+
"plugins"
|
|
14
11
|
],
|
|
15
12
|
"engines": {
|
|
16
13
|
"node": ">=18"
|
|
17
14
|
},
|
|
18
|
-
"scripts": {
|
|
19
|
-
"build": "node tools/build.mjs",
|
|
20
|
-
"install-plugin": "node bin/fish-dock-filemgr.mjs",
|
|
21
|
-
"prepack": "node tools/build.mjs"
|
|
22
|
-
},
|
|
23
15
|
"keywords": [
|
|
24
16
|
"fish-dock",
|
|
25
17
|
"fishdock",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schema": 1,
|
|
3
3
|
"id": "jassdingk.filemgr",
|
|
4
4
|
"name": "文件管理",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.5",
|
|
6
6
|
"hostApi": 1,
|
|
7
7
|
"platforms": [
|
|
8
8
|
"windows-x86_64"
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
],
|
|
28
28
|
"files": {
|
|
29
29
|
"bridge.js": "f38f93994e3cb2b71f2ff1810b3f68fb42f4261550f8ab01b0bfa3eecd5f94ee",
|
|
30
|
+
"package.json": "7e9124508cc113f5039ce514573a5f8f280faf9392e4677d30bb144c55351e5c",
|
|
30
31
|
"plugins/filemgr/backend.mjs": "b448aa688ff11f2abc4c5281b4714646ed6c384473d873cfe431a8e64b066d26",
|
|
31
32
|
"plugins/filemgr/clip.ps1": "b0a32fca35cf2d25133338f46e20a0db20d78c5bb6b5c2aab899998bfbd6c6ab",
|
|
32
33
|
"plugins/filemgr/dock.css": "e795214dd39de3b473ac0b1a7b79f6922a88c761fca4d3ea4da8fd9b60188bcf",
|
package/LICENSE
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Fish-under-sea
|
|
4
|
-
Copyright (c) 2026 Pengjie Zhou
|
|
5
|
-
Copyright (c) 2026 Ebony-Vinyl
|
|
6
|
-
|
|
7
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
9
|
-
in the Software without restriction, including without limitation the rights
|
|
10
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
12
|
-
furnished to do so, subject to the following conditions:
|
|
13
|
-
|
|
14
|
-
The above copyright notice and this permission notice shall be included in all
|
|
15
|
-
copies or substantial portions of the Software.
|
|
16
|
-
|
|
17
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
-
SOFTWARE.
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
The root license covers FISH Dock integration code and MIT-licensed upstream
|
|
28
|
-
code, subject to the original notices retained in Wakuwaku/LICENSE and
|
|
29
|
-
dsh-our-free-model/LICENSE. Other bundled libraries retain their own licenses.
|
|
30
|
-
This license does not grant rights to pet sprites, application icons,
|
|
31
|
-
wallpapers, third-party trademarks, accounts, or model services. Verify the
|
|
32
|
-
applicable permissions before redistributing artwork or other assets.
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// fish-dock-filemgr —— 把「文件管理」插件装进本机 FISH Dock。
|
|
3
|
-
//
|
|
4
|
-
// 做的事和宿主「从文件安装 .fish-plugin」等价:
|
|
5
|
-
// 1. 校验 dist/filemgr 里每个文件的 sha256 与 plugin.json 登记值一致
|
|
6
|
-
// 2. 拷到 %USERPROFILE%\.fish-dock\host\packages\<id>\<version>\<整包 sha256>\
|
|
7
|
-
// 3. 往 host/config/installed-plugins.json 写注册条目(manifest 按宿主解析后的形状补全)
|
|
8
|
-
//
|
|
9
|
-
// 仅支持 Windows(宿主只发 windows-x86_64)。
|
|
10
|
-
import fs from 'node:fs'
|
|
11
|
-
import os from 'node:os'
|
|
12
|
-
import path from 'node:path'
|
|
13
|
-
import crypto from 'node:crypto'
|
|
14
|
-
import { fileURLToPath } from 'node:url'
|
|
15
|
-
import { spawnSync } from 'node:child_process'
|
|
16
|
-
|
|
17
|
-
const HERE = path.dirname(fileURLToPath(import.meta.url))
|
|
18
|
-
const PKG_ROOT = path.resolve(HERE, '..')
|
|
19
|
-
const DEV = path.join(PKG_ROOT, 'dist', 'filemgr')
|
|
20
|
-
const ARCHIVE = path.join(PKG_ROOT, 'dist', 'jassdingk.filemgr.fish-plugin')
|
|
21
|
-
|
|
22
|
-
const C = { r: '\x1b[0m', b: '\x1b[1m', dim: '\x1b[2m', g: '\x1b[32m', y: '\x1b[33m', red: '\x1b[31m', cyan: '\x1b[36m' }
|
|
23
|
-
const say = (...a) => console.log(...a)
|
|
24
|
-
const die = msg => { console.error(`${C.red}✗ ${msg}${C.r}`); process.exit(1) }
|
|
25
|
-
const sha256 = b => crypto.createHash('sha256').update(b).digest('hex')
|
|
26
|
-
|
|
27
|
-
const argv = process.argv.slice(2)
|
|
28
|
-
const has = (...names) => names.some(n => argv.includes(n))
|
|
29
|
-
|
|
30
|
-
if (has('-h', '--help')) {
|
|
31
|
-
say(`
|
|
32
|
-
${C.b}fish-dock-filemgr${C.r} — 安装 FISH Dock「文件管理」插件
|
|
33
|
-
|
|
34
|
-
${C.cyan}fish-dock-filemgr${C.r} 安装 / 升级到当前版本
|
|
35
|
-
${C.cyan}fish-dock-filemgr --path${C.r} 只打印 .fish-plugin 包路径(自行拖进宿主安装)
|
|
36
|
-
${C.cyan}fish-dock-filemgr --dry-run${C.r} 只做校验,不写磁盘
|
|
37
|
-
${C.cyan}fish-dock-filemgr --uninstall${C.r} 从注册表移除本插件
|
|
38
|
-
|
|
39
|
-
安装完成后需要 ${C.y}重启 FISH Dock${C.r} 才会加载新版本。
|
|
40
|
-
`)
|
|
41
|
-
process.exit(0)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (process.platform !== 'win32') die('本插件只支持 Windows(FISH Dock 宿主仅提供 windows-x86_64)')
|
|
45
|
-
|
|
46
|
-
if (!fs.existsSync(path.join(DEV, 'plugin.json'))) {
|
|
47
|
-
die(`找不到 dist/filemgr/plugin.json。\n 这是发行包里预构建的产物;如果你是源码检出,先跑 ${C.cyan}npm run build${C.r}`)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const manifest = JSON.parse(fs.readFileSync(path.join(DEV, 'plugin.json'), 'utf8'))
|
|
51
|
-
const version = manifest.version
|
|
52
|
-
const HOST = path.join(os.homedir(), '.fish-dock', 'host')
|
|
53
|
-
const REGISTRY = path.join(HOST, 'config', 'installed-plugins.json')
|
|
54
|
-
|
|
55
|
-
if (has('--path')) {
|
|
56
|
-
say(fs.existsSync(ARCHIVE) ? ARCHIVE : path.join(DEV, 'plugin.json'))
|
|
57
|
-
process.exit(0)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// ---------- uninstall ----------
|
|
61
|
-
if (has('--uninstall')) {
|
|
62
|
-
if (!fs.existsSync(REGISTRY)) die(`注册表不存在:${REGISTRY}\n 看起来这台机器还没装过 FISH Dock 插件。`)
|
|
63
|
-
const reg = JSON.parse(fs.readFileSync(REGISTRY, 'utf8'))
|
|
64
|
-
if (!reg.entries || !reg.entries[manifest.id]) {
|
|
65
|
-
say(`${C.y}!${C.r} 注册表里没有 ${manifest.id},无需卸载`)
|
|
66
|
-
process.exit(0)
|
|
67
|
-
}
|
|
68
|
-
const backup = REGISTRY + '.bak-' + Date.now()
|
|
69
|
-
fs.copyFileSync(REGISTRY, backup)
|
|
70
|
-
delete reg.entries[manifest.id]
|
|
71
|
-
const tmp = REGISTRY + '.tmp-' + process.pid
|
|
72
|
-
fs.writeFileSync(tmp, JSON.stringify(reg, null, 2))
|
|
73
|
-
fs.renameSync(tmp, REGISTRY)
|
|
74
|
-
say(`${C.g}✓${C.r} 已从注册表移除 ${C.b}${manifest.id}${C.r}`)
|
|
75
|
-
say(` ${C.dim}注册表备份 ${backup}${C.r}`)
|
|
76
|
-
say(` ${C.dim}包目录可留可删:${path.join(HOST, 'packages', manifest.id)}${C.r}`)
|
|
77
|
-
say(` ${C.y}重启 FISH Dock 后生效${C.r}`)
|
|
78
|
-
process.exit(0)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// ---------- 校验 ----------
|
|
82
|
-
const declared = manifest.files || {}
|
|
83
|
-
const files = Object.keys(declared)
|
|
84
|
-
if (!files.length) die('plugin.json 里没有 files 清单,包不完整')
|
|
85
|
-
let bad = 0
|
|
86
|
-
for (const name of files) {
|
|
87
|
-
const abs = path.join(DEV, name)
|
|
88
|
-
if (!fs.existsSync(abs)) { console.error(`${C.red}缺失${C.r} ${name}`); bad++; continue }
|
|
89
|
-
const got = sha256(fs.readFileSync(abs))
|
|
90
|
-
if (got !== String(declared[name]).toLowerCase()) { console.error(`${C.red}哈希不符${C.r} ${name}\n 期望 ${declared[name]}\n 实际 ${got}`); bad++ }
|
|
91
|
-
}
|
|
92
|
-
if (bad) die(`包内文件校验失败(${bad} 个异常),已中止,未写入任何文件`)
|
|
93
|
-
|
|
94
|
-
const digest = sha256(fs.readFileSync(ARCHIVE))
|
|
95
|
-
say(`${C.dim}插件${C.r} ${C.b}${manifest.id}${C.r} ${C.cyan}v${version}${C.r}`)
|
|
96
|
-
say(`${C.dim}文件${C.r} ${files.length} 个全部校验通过`)
|
|
97
|
-
say(`${C.dim}整包${C.r} sha256 ${digest.slice(0, 16)}…`)
|
|
98
|
-
|
|
99
|
-
if (has('--dry-run')) { say(`\n${C.y}= dry-run,未写入磁盘 =${C.r}`); process.exit(0) }
|
|
100
|
-
|
|
101
|
-
// ---------- 拷文件 ----------
|
|
102
|
-
const target = path.join(HOST, 'packages', manifest.id, version, digest)
|
|
103
|
-
fs.mkdirSync(target, { recursive: true })
|
|
104
|
-
for (const name of files) {
|
|
105
|
-
const dst = path.join(target, name)
|
|
106
|
-
fs.mkdirSync(path.dirname(dst), { recursive: true })
|
|
107
|
-
fs.copyFileSync(path.join(DEV, name), dst)
|
|
108
|
-
}
|
|
109
|
-
fs.copyFileSync(path.join(DEV, 'plugin.json'), path.join(target, 'plugin.json'))
|
|
110
|
-
say(`${C.dim}落盘${C.r} ${target}`)
|
|
111
|
-
|
|
112
|
-
// ---------- 写注册表 ----------
|
|
113
|
-
// 宿主 Manifest::parse 用 serde(deny_unknown_fields) + camelCase,且 backend.args / locksSettings
|
|
114
|
-
// 有 serde(default)——注册表里存的是解析后的 to_value 结果,所以这两个字段要显式补上。
|
|
115
|
-
const full = {
|
|
116
|
-
...manifest,
|
|
117
|
-
backend: { ...manifest.backend, args: manifest.backend?.args ?? [] },
|
|
118
|
-
locksSettings: manifest.locksSettings ?? false,
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const registry = fs.existsSync(REGISTRY) ? JSON.parse(fs.readFileSync(REGISTRY, 'utf8')) : { schema: 1, entries: {} }
|
|
122
|
-
registry.entries = registry.entries || {}
|
|
123
|
-
const previous = registry.entries[manifest.id] || null
|
|
124
|
-
registry.entries[manifest.id] = {
|
|
125
|
-
manifest: full,
|
|
126
|
-
digest,
|
|
127
|
-
official: false,
|
|
128
|
-
enabled: previous ? previous.enabled !== false : true,
|
|
129
|
-
autostart: previous ? previous.autostart !== false : true,
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (fs.existsSync(REGISTRY)) {
|
|
133
|
-
const backup = REGISTRY + '.bak-' + Date.now()
|
|
134
|
-
fs.copyFileSync(REGISTRY, backup)
|
|
135
|
-
say(`${C.dim}备份${C.r} ${backup}`)
|
|
136
|
-
}
|
|
137
|
-
const tmp = REGISTRY + '.tmp-' + process.pid
|
|
138
|
-
fs.writeFileSync(tmp, JSON.stringify(registry, null, 2))
|
|
139
|
-
fs.renameSync(tmp, REGISTRY)
|
|
140
|
-
|
|
141
|
-
say('')
|
|
142
|
-
say(`${C.g}✓ 已安装${C.r} ${C.b}${manifest.id}${C.r} v${version}${previous ? '(覆盖旧版)' : ''}`)
|
|
143
|
-
|
|
144
|
-
// ---------- 提示重启 ----------
|
|
145
|
-
const running = spawnSync('tasklist', ['/FI', 'IMAGENAME eq DSH-FISH.exe', '/NH'], { encoding: 'utf8' })
|
|
146
|
-
if ((running.stdout || '').includes('DSH-FISH.exe')) {
|
|
147
|
-
say(`${C.y}${C.b}FISH Dock 正在运行${C.r} —— 需要重启它才会加载新版本:`)
|
|
148
|
-
say(` ${C.dim}右下角托盘图标退出,或任务管理器结束 DSH-FISH.exe,然后重新打开${C.r}`)
|
|
149
|
-
} else {
|
|
150
|
-
say(`${C.dim}打开 FISH Dock 即可在插件页看到「文件管理」${C.r}`)
|
|
151
|
-
}
|
package/dist/filemgr/README.md
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
# 文件管理
|
|
2
|
-
|
|
3
|
-
把 FISH Dock 变成随手可用的文件工作台:左边逛目录、右边看内容,中间还能把常用文件先「暂存」起来,随时拖进别的程序。
|
|
4
|
-
|
|
5
|
-
## 功能
|
|
6
|
-
|
|
7
|
-
### 目录浏览 + 预览
|
|
8
|
-
|
|
9
|
-
- **目录浏览**:从磁盘根目录、用户目录、桌面 / 文档 / 下载逐层进入;支持把文件 / 文件夹直接拖进面板。
|
|
10
|
-
- **预览**:Markdown 渲染、图片(PNG / JPEG / GIF / WebP / BMP / AVIF / ICO / SVG)、Office 文本抽取(docx 段落与标题、xlsx 多工作表、pptx 每页文字,原生解析 OOXML,不需要装 Office)、代码高亮行号、纯文本与二进制兜底。
|
|
11
|
-
- **上下并列**:上半是文件夹浏览器(面包屑 + 列表 + 上一级 / 刷新 / 常用文件夹 / 固定),下半是预览;中间分隔条可拖动调高,高度会被记住。
|
|
12
|
-
- **框选与拖入暂存**:在列表里拖出选框可批量选中(Ctrl / Shift 点选切换),选中项直接拖到左侧暂存区即批量加入;拖到一半拖出列表会自动从「框选」切到「搬运」。
|
|
13
|
-
- **常用文件夹**:记住打开过的目录,浮层里快速跳转;可把目录「固定」到最上面。
|
|
14
|
-
|
|
15
|
-
### 选择文件夹
|
|
16
|
-
|
|
17
|
-
「打开文件夹」默认调用 **Windows 原生文件夹选择框**(`pick-folder.ps1` + IFileOpenDialog),选完直接进入该目录。
|
|
18
|
-
|
|
19
|
-
宿主原本会在系统对话框抢走焦点时自动收起设置面板。插件只在**弹出对话框的那一刻**调用 `bridge.js` 的 `hold(true)`,选完(或取消/报错)立刻在 `finally` 里 `hold(false)` 放开——平时浏览、拖放都不锁,点面板外面照常能关。
|
|
20
|
-
|
|
21
|
-
宿主没有 `fish:hold` 能力(官方发行版 ≤ v1.2.3)时,插件自动回落到**内置自绘选择器**(用后端 `preview.tree` 逐层浏览),功能完整,只是不锁面板:
|
|
22
|
-
|
|
23
|
-
| 宿主 | 「打开文件夹」 | 面板锁定 |
|
|
24
|
-
|---|---|---|
|
|
25
|
-
| 自行编译、带 `fish:hold` 的宿主 | Windows 原生对话框 | 仅对话框期间临时锁定 |
|
|
26
|
-
| 官方发行版(≤ v1.2.3) | 内置选择器 | 不锁定 |
|
|
27
|
-
|
|
28
|
-
宿主侧要支持这条路,需要三处改动(都已在 `FISH-Dock` 上游以补丁形式验证过):
|
|
29
|
-
|
|
30
|
-
1. `sdk/browser/bridge.js` 暴露 `hold(on)` → `parent.postMessage({type:'fish:hold', ticket, on}, '*')`
|
|
31
|
-
2. `Wakuwaku/src/pet/extension-page.js` 收 `fish:hold` 写入 `record.hold`,并新增 `onHold(record, on)` 回调;`park()` / `enter()` / `retire()` 各自同步
|
|
32
|
-
3. `Wakuwaku/src/pet/settings.js` 维护 `pluginHold` 标志,`onBlur` 判定里加 `!pluginHold`
|
|
33
|
-
|
|
34
|
-
只改插件包、不重编译宿主时,插件自动走内置选择器,功能完整不缺。
|
|
35
|
-
|
|
36
|
-
### 文件暂存(中转站)
|
|
37
|
-
|
|
38
|
-
- 拖入文件或文件夹即加入暂存区,也可以右键 / 按钮添加。
|
|
39
|
-
- **分组**:暂存区支持多个分组标签,点击切换,标签可折叠;删除分组只走标签右侧的 ×。
|
|
40
|
-
- **拖出**:把暂存项直接拖到桌面、资源管理器、微信等外部程序。
|
|
41
|
-
- 复制路径、复制为文件、多选批量、去重、清空,偏好持久化。
|
|
42
|
-
|
|
43
|
-
## 说明
|
|
44
|
-
|
|
45
|
-
- 只读取路径白名单内的文件,路径解析后必须落在允许的根目录之下;UNC 路径一律拒绝。
|
|
46
|
-
- 「打开文件夹」在支持 `fish:hold` 的宿主上会短暂启动系统 PowerShell 调起 Windows 原生文件夹对话框(`pick-folder.ps1`),用于拿到用户亲手选择的路径;不加 `fish:hold` 的宿主上不会启动子进程,走内置选择器。除此之外不启动任何子进程。
|
|
47
|
-
- 页面运行在宿主沙箱里(`default-src 'none'`),PDF 与音视频不做内联播放,会提示用系统程序打开。
|
|
48
|
-
- 不发起网络请求。
|
|
49
|
-
|
|
50
|
-
## 存储
|
|
51
|
-
|
|
52
|
-
偏好(布局、最近打开、额外根目录、暂存分组)保存在插件命名空间的 `config/prefs.json`。
|
|
53
|
-
|
|
54
|
-
## 开发
|
|
55
|
-
|
|
56
|
-
```bash
|
|
57
|
-
# 本地暂存(模拟官方 tools/stage-development.mjs 的产出)
|
|
58
|
-
node _stage_filemgr.mjs
|
|
59
|
-
# 产物
|
|
60
|
-
# dist/filemgr.fish-plugin
|
|
61
|
-
# _stage/filemgr/ ← 可直接用 FISH Dock 的「从文件安装」装上验证
|
|
62
|
-
```
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|