@dsh-plugins/dsh-museav-assets 0.1.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,48 @@
1
+ # Changelog
2
+
3
+ ## Unreleased
4
+
5
+ - **接入发版门禁** —— 与另外三个 dsh 插件同一套:`scripts/prepublish-gate.mjs` +
6
+ `scripts/readme-gate.mjs` + `scripts/gate-lib.mjs`(gate-lib 是 prepublish-gate 的
7
+ import 依赖,必须一起拷,否则 `ERR_MODULE_NOT_FOUND`),接在 `prepublishOnly` 末尾。
8
+ 真源在 `CortexOS/scripts/release-gate/`,改逻辑改真源,再用
9
+ `check-release-gate-sync.mjs --fix` 同步 —— **别在本仓就地改**。
10
+ 为什么补:本仓此前是五个插件里唯一没接门禁的(`prepublishOnly` 只跑 `check && test`),
11
+ 四条产物契约和 README 首屏契约都不过。
12
+ - **README 首屏对齐 `open_source_project_baseline`** —— 居中品牌标题 + 4 个
13
+ for-the-badge 徽章 + Why This 对比表 + 中英切换。此前是裸 `# 标题`,readme-gate 判不合规。
14
+
15
+ > 发版状态核实(2026-10-02):scoped 名 `@dsh-plugins/dsh-museav-assets` 在 npm 上
16
+ > **仍不存在(404)**;无 scope 的 `dsh-museav-assets@0.1.0` 存在,且**尚未标 deprecated**。
17
+ > 即上面 0.1.1 写的「已 deprecated 指向本名」目前只是意图 —— 补发成功前,桌面端按
18
+ > scoped 名装不上。
19
+
20
+ ## 0.1.1
21
+
22
+ - **包名迁到 `@dsh-plugins/dsh-museav-assets`**(与另外三个插件同一 scope)。
23
+ 无 scope 的 `dsh-museav-assets` 是 0.1.0 的历史名,已 deprecated 指向本名。
24
+ 四处身份同步改:`package.json` / `export const name` / client 的 `ModuleLoader.id` /
25
+ `cordis.patch.yml`;路由前缀 `/api/dsh-museav-assets` 保持不变(它与包名无关)。
26
+
27
+ - 发布到 npm(0.1.0 是首个版本,本次只补文档与版本号)
28
+ - README 中英:删掉「还没发 npm,所以桌面端装不上」的过渡说明,改成已发布状态 +
29
+ 桌面端在应用内插件管理里装(CLI 装不进 app 独占托管的 `desktop` profile)
30
+ - 加 `.github/workflows/publish.yml`:push `v*` tag → GitHub OIDC Trusted Publishing
31
+ 直发 npm(不需要 npm token/OTP);加 `ci.yml`:语法检查 + 43 个测试 + 打包自检
32
+
33
+ ## 0.1.0
34
+
35
+ 首个版本。
36
+
37
+ - `conversation.view` 注册第 6 个 tab「资产」(order 40):项目切换 + 素材网格 + 最近出图
38
+ - 4 条路由:health / projects(GET、POST) / assets / jobs
39
+ - 适配层锁死 museav-cli 的 stdout 契约(projects→id 换行、assets→`id\turl`、jobs→JSON 数组),
40
+ stderr 表格只补展示字段,解析失败降级不白屏
41
+ - 新建项目带上限保护:已达 5 个(服务端上限)时按钮禁用并提示
42
+ - 28 个测试:12 解析契约(真机输出夹具)+ 8 路由(stub CLI,不联网)+ 8 UI
43
+
44
+ ### 没做的
45
+
46
+ - 不出图、不传文件(走 `mcp__museav__*`)
47
+ - 不轮询、不缓存
48
+ - 不注册 agent 工具(项目相关的工具在 v0.2 考虑)
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 webkubor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.en.md ADDED
@@ -0,0 +1,114 @@
1
+ # dsh-museav-assets
2
+
3
+ An **Assets** tab for DeepSeek Harness: browse MUSE AV assets by project (workspace)
4
+ and see recent generations. Click an asset to copy its direct URL, ready to use as a
5
+ ref image (`museav gen --ref <url>`).
6
+
7
+ Built on the local **museav CLI**. It deliberately does not re-implement generation
8
+ or upload — those stay with the `mcp__museav__*` tools already bridged into DSH. This
9
+ plugin only adds the missing view: *which projects do I have, and what is in each one*.
10
+
11
+ ## Where the tab goes
12
+
13
+ The sixth tab in the main area, registered on `conversation.view` with **order 40**,
14
+ after Chat (0) / Trajectory (10) / Memory (20) / Context / Computer Environment (30).
15
+
16
+ ```js
17
+ ctx.slots.register({
18
+ name: 'conversation.view',
19
+ id: 'museav-assets',
20
+ order: 40,
21
+ label: () => t('title'), // "Assets"
22
+ }, AssetsView)
23
+ ```
24
+
25
+ Main area rather than the right panel: assets are a one-screen job (project chips +
26
+ thumbnail grid + generation feed); the right panel is a narrow pane meant for a single
27
+ selected object, and its tab semantics are "the thing you currently have open" — assets
28
+ are global and belong to no session. There is precedent for a global view living in the
29
+ session shell: `dsh-user-mirror`'s Memory tab does the same.
30
+
31
+ ## Install
32
+
33
+ > **Package name: `@dsh-plugins/dsh-museav-assets`** (same scope as the three sibling plugins).
34
+ > The unscoped `dsh-museav-assets` was the original 0.1.0 name; it is deprecated and points here.
35
+
36
+ On the desktop app, install it from the app's **plugin manager** (it pulls from npm) — the CLI
37
+ cannot write to the `desktop` profile
38
+ (`profile "desktop" is managed exclusively by the Electron application`).
39
+
40
+ Self-managed profile (one the CLI can write to, e.g. `desktop-local` for local dev):
41
+
42
+ ```sh
43
+ npm run deploy # rsync into ~/.dsh/profiles/desktop-local/node_modules/@dsh-plugins/dsh-museav-assets/
44
+ ```
45
+
46
+ Then add the package to that profile (`~/.dsh/profiles/desktop-local/package.json`):
47
+
48
+ ```jsonc
49
+ "dependencies": { "dsh-museav-assets": "^0.1.0" },
50
+ "dsh": { "profile": { "bundles": [ /* … */, "dsh-museav-assets" ] } }
51
+ ```
52
+
53
+ Changing profile config is a topology change: **quit and reopen the desktop app** (`~/.dsh/restart.sh` is retired — it now detects the missing 3080 service and exits 1).
54
+ (never `launchctl kickstart` directly).
55
+
56
+ Only prerequisite: the local `museav` CLI is logged in (`museav login`).
57
+ The plugin never reads or forwards the token in `~/.museav.json`.
58
+
59
+ ## Endpoints
60
+
61
+ | Route | What it does |
62
+ |---|---|
63
+ | `GET /api/dsh-museav-assets/health` | CLI presence + version + workspace cap |
64
+ | `GET /api/dsh-museav-assets/projects` | Workspaces with gen/asset counts + `used/limit/full` |
65
+ | `POST /api/dsh-museav-assets/projects` | `{name}` create a workspace (≤20 chars) |
66
+ | `GET /api/dsh-museav-assets/assets?project=<id\|name>` | Assets in that workspace |
67
+ | `GET /api/dsh-museav-assets/jobs?limit=<n>` | Recent generation records |
68
+
69
+ Failure semantics: any upstream/CLI error returns **200 + `{ok:false,error}`** so the tab
70
+ can render the reason inline; only invalid parameters return 400. One flaky request
71
+ should not blank the tab.
72
+
73
+ ## The CLI contract
74
+
75
+ `lib/museav.js` is the only file that knows what the CLI output looks like. museav-cli's
76
+ stdout/stderr split *is* its scripting contract:
77
+
78
+ | Command | stdout (source of truth) | stderr (human-facing extras) |
79
+ |---|---|---|
80
+ | `museav projects` | one id per line | name / gen x/y / assets n / brand |
81
+ | `museav projects assets --project X` | `id<TAB>url` | name / media_type / tags |
82
+ | `museav jobs` | **a full JSON array** | a pretty summary |
83
+ | `museav projects create --name N` | the new id | success message |
84
+
85
+ So: truth comes from stdout, stderr only fills in display fields. If stderr stops
86
+ parsing, the view degrades (name falls back to the first 8 chars of the id, asset name to
87
+ "(unnamed)") rather than going blank. `test/museav-parse.test.mjs` pins this against
88
+ output captured from the real CLI.
89
+
90
+ > Known fragility: `museav projects` and `projects assets` have **no `--json`**, so the
91
+ > display fields can only be parsed out of the stderr table. Adding `--json` to those two
92
+ > commands in museav-cli removes the fragility for good — the source of truth there is
93
+ > `~/dev/muse/museav-cli/src/commands/projects.ts`, a different repo.
94
+
95
+ ## Non-goals
96
+
97
+ - No generation, no uploads — that is the CLI/MCP's job; a second implementation only
98
+ creates two places to drift
99
+ - No caching — the data is cheap and the state moves; add a cache if it is ever needed
100
+ - No polling — one fetch on mount, then only when the user hits Refresh
101
+
102
+ ## Tests
103
+
104
+ ```sh
105
+ npm run check && npm test # 28: 12 parsing contract + 8 routes + 8 UI
106
+ ```
107
+
108
+ Route tests substitute a stub executable for the CLI (via the `MUSEAW_BIN` environment
109
+ variable) — no network, no real account.
110
+
111
+ Why an env var rather than plugin config: functional plugins in this Cordis cannot read
112
+ `ctx.config` (declaring it leaves the plugin `pending (waiting for service: config)`).
113
+ `MUSEAW_BIN` also matches the convention already used by the MCP bridge in the profile.
114
+ It is read per request, so changing it needs no plugin reload.
package/README.md ADDED
@@ -0,0 +1,127 @@
1
+ <h1 align="center">🖼️ dsh-museav-assets</h1>
2
+
3
+ <p align="center">
4
+ <strong>在 DSH 里看得见你的素材库。</strong><br>
5
+ 主区多一个「资产」tab:按项目(工作区)看 MUSE AV 的素材库与最近出图,<br>
6
+ 点素材即复制直链,直接当垫图用(<code>museav gen --ref &lt;url&gt;</code>)。
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/package/@dsh-plugins/dsh-museav-assets"><img src="https://img.shields.io/npm/v/%40dsh-plugins%2Fdsh-museav-assets?style=for-the-badge&color=4d6bfe&logo=npm&label=npm" alt="npm" /></a>
11
+ <img src="https://img.shields.io/badge/runtime_deps-0-5A9E6F?style=for-the-badge" alt="runtime deps" />
12
+ <img src="https://img.shields.io/badge/license-MIT-777?style=for-the-badge" alt="MIT" />
13
+ <a href="https://github.com/deepseek-ai/deepseek-harness"><img src="https://img.shields.io/badge/DeepSeek_Harness-Plugin-4d6bfe?style=for-the-badge" alt="DSH Plugin" /></a>
14
+ </p>
15
+
16
+ <p align="center">
17
+ <a href="README.en.md">English</a> | 中文
18
+ </p>
19
+
20
+ ## Why This
21
+
22
+ | | 本插件 | `mcp__museav__*` 工具 | 直接敲 CLI |
23
+ |---|---|---|---|
24
+ | 看清「有哪些项目、各有多少素材」 | ✅ 一屏网格 + 计数 | ❌ 单次调用,看不见全貌 | ⚠️ 逐条命令,靠脑记 |
25
+ | 素材拿直链当垫图 | ✅ 点一下复制 | ⚠️ 得先知道素材 id | ⚠️ 手抄 URL |
26
+ | 出图 / 上传能力 | ➖ 不重复实现,转交 MCP | ✅ 完整 | ✅ 完整 |
27
+ | 密钥 | ✅ 不读不转发 `~/.museav.json` | ✅ | ⚠️ token 落在本机明文文件 |
28
+
29
+ 基于本机的 **museav CLI**,不重复造出图能力 —— 出图/上传继续走已经接进 DSH 的
30
+ `mcp__museav__*` 工具(见 profile 的 cordis.patch.yml)。这个插件只补一件事:
31
+ **在 DSH 里看得见「我有哪些项目、每个项目里有什么素材」**。
32
+
33
+ ## 放在哪个 tab
34
+
35
+ 主区顶栏,`conversation.view` 的第 6 个 tab,**order 40**,排在
36
+ 对话(0) / 轨迹(10) / 记忆(20) / 上下文 / 电脑环境(30) 之后。
37
+
38
+ ```js
39
+ ctx.slots.register({
40
+ name: 'conversation.view',
41
+ id: 'museav-assets',
42
+ order: 40,
43
+ label: () => t('title'), // 「资产」
44
+ }, AssetsView)
45
+ ```
46
+
47
+ 为什么是主区而不是右侧面板:资产是「一屏看完的事」(项目列表 + 缩略图网格 + 出图流水),
48
+ 右侧面板是给单份文档/单个预览的窄栏,塞不下网格;而且右侧面板的 tab 语义是
49
+ 「当前选中对象」,资产是全局的,不属于任何一个会话。主区 tab 已有先例
50
+ (dsh-user-mirror 的「记忆」同样是全局内容挂在会话壳里)。
51
+
52
+ ## 装
53
+
54
+ > **包名 `@dsh-plugins/dsh-museav-assets`**(与另外三个插件同一 scope)。
55
+ > `dsh-museav-assets`(无 scope)是最早 0.1.0 的历史名,已 deprecated,指向本名。
56
+
57
+ 桌面端在**应用内的插件管理**里装 —— 它从 npm 拉。命令行装不进 `desktop` profile
58
+ (`profile "desktop" is managed exclusively by the Electron application`)。
59
+
60
+ 自建 profile(CLI 能管的,例如本地开发用的 `desktop-local`):
61
+
62
+ ```sh
63
+ npm run deploy # rsync 进 ~/.dsh/profiles/desktop-local/node_modules/@dsh-plugins/dsh-museav-assets/
64
+ ```
65
+
66
+ 再把包名加进该 profile(`~/.dsh/profiles/desktop-local/package.json`):
67
+
68
+ ```jsonc
69
+ "dependencies": { "@dsh-plugins/dsh-museav-assets": "^0.1.1" },
70
+ "dsh": { "profile": { "bundles": [ /* … */, "@dsh-plugins/dsh-museav-assets" ] } }
71
+ ```
72
+
73
+ 拓扑级变更要重启:桌面端是**退出并重开 app**(`~/.dsh/restart.sh` 已作废,现在探测不到 3080 服务会直接以 1 退出)。
74
+
75
+ 前置条件只有一条:本机 `museav` CLI 已登录(`museav login`)。
76
+ 插件自己**不读也不转发** `~/.museav.json` 里的 token。
77
+
78
+ ## 接口
79
+
80
+ | 路由 | 做什么 |
81
+ |---|---|
82
+ | `GET /api/dsh-museav-assets/health` | CLI 在不在、什么版本、工作区上限 |
83
+ | `GET /api/dsh-museav-assets/projects` | 工作区列表 + 出图/素材计数 + `used/limit/full` |
84
+ | `POST /api/dsh-museav-assets/projects` | `{name}` 新建工作区(≤20 字) |
85
+ | `GET /api/dsh-museav-assets/assets?project=<id\|名>` | 该工作区的素材库 |
86
+ | `GET /api/dsh-museav-assets/jobs?limit=<n>` | 最近出图记录 |
87
+
88
+ 失败语义:**上游/CLI 出错一律 200 + `{ok:false,error}`**,tab 内联显示原因;
89
+ 只有参数不合法才 400。一次网络抖动不该让 tab 变白屏。
90
+
91
+ ## CLI 契约(插件唯一依赖的东西)
92
+
93
+ `lib/museav.js` 是**唯一**知道 CLI 输出长什么样的文件。museav-cli 的
94
+ stdout/stderr 分工就是它的脚本契约:
95
+
96
+ | 命令 | stdout(真值) | stderr(人看的补充) |
97
+ |---|---|---|
98
+ | `museav projects` | id 换行 | 名称 / 出图 x/y / 素材 n / brand |
99
+ | `museav projects assets --project X` | `id<TAB>url` | 名称 / media_type / tags |
100
+ | `museav jobs` | **完整 JSON 数组** | 表格式摘要 |
101
+ | `museav projects create --name N` | 新建 id | 成功提示 |
102
+
103
+ 所以:**真值一律取 stdout,stderr 只用来补展示字段**。stderr 解析不出来就降级
104
+ (项目名退回 id 前 8 位,素材名退回「未命名」),绝不因为上游改一句中文就让整页空白。
105
+ `test/museav-parse.test.mjs` 用真机抓的输出当夹具守着这条线。
106
+
107
+ > 已知脆点:`museav projects` / `projects assets` **没有 `--json`**,展示字段只能从
108
+ > stderr 表格里解析。给 museav-cli 这两个命令加 `--json` 就能把这条脆点彻底消掉 ——
109
+ > 真源在 `~/dev/muse/museav-cli/src/commands/projects.ts`,改的是上游仓,不是本插件。
110
+
111
+ ## 不做什么
112
+
113
+ - 不出图、不传文件 —— 那是 CLI / MCP 的活,重复实现只会两处漂移
114
+ - 不缓存 —— 数据便宜,状态随时在变;想要缓存再加
115
+ - 不轮询 —— 挂载时拉一次,用户点「刷新」才重跑
116
+
117
+ ## 测试
118
+
119
+ ```sh
120
+ npm run check && npm test # 28 个:解析契约 12 + 路由 8 + UI 8
121
+ ```
122
+
123
+ 路由测试用 stub 可执行文件顶替 CLI(走 `MUSEAW_BIN` 环境变量),**全程不联网、不碰真账号**。
124
+
125
+ CLI 路径为什么是环境变量而不是插件配置:这套 Cordis 的函数式插件读不到 `ctx.config`
126
+ (声明了会永远 `pending (waiting for service: config)`)。`MUSEAW_BIN` 也正好和 profile
127
+ 里 MCP 桥的约定一致。改它不用重载插件 —— 每次请求现取。
@@ -0,0 +1,10 @@
1
+ # dsh-museav-assets bundle patch:把资产台插入 web profile。
2
+ #
3
+ # 作为 dsh.bundle.patch 被 dsh 加载器消费。insert 引用本包,加载器从 profile 的
4
+ # node_modules 解析它并挂成 Cordis 插件。
5
+ # 不写 config = 用插件 Config 默认值(见 lib/index.js export const Config)。
6
+ - insert:
7
+ # 插件只暴露 4 条只读/轻写路由,全部 fail-open:CLI 没装、没登录、出错都回
8
+ # {ok:false,error},不影响 boot graph。
9
+ - id: @dsh-plugins/dsh-museav-assets
10
+ name: '@dsh-plugins/dsh-museav-assets'