dsh-web-annotator 0.0.0-stage → 0.2.0-alpha.11
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 +112 -0
- package/CONTRIBUTING.md +90 -0
- package/LICENSE +21 -0
- package/README.md +110 -2
- package/README_en.md +136 -0
- package/THIRD_PARTY_NOTICES.md +15 -0
- package/cordis.patch.yml +15 -0
- package/docs/AGENTS.md +16 -0
- package/docs/README.md +25 -0
- package/docs/architecture.md +170 -0
- package/docs/browser-integration.md +94 -0
- package/docs/distribution.md +66 -0
- package/docs/harness-browser-annotation.patch +1909 -0
- package/docs/images/annotation-expanded-dark.png +0 -0
- package/docs/images/annotation-expanded.png +0 -0
- package/docs/images/annotation-image.png +0 -0
- package/docs/images/annotation-message.png +0 -0
- package/docs/images/annotation-region.png +0 -0
- package/docs/marketplace/cslkkl__dsh-web-annotator.yml +7 -0
- package/docs/publishing.md +129 -0
- package/docs/roadmap.md +31 -0
- package/docs/verification.md +179 -0
- package/dsh-plugin.naming.json +27 -0
- package/examples/responsive-demo/AGENTS.md +12 -0
- package/examples/responsive-demo/README.md +33 -0
- package/examples/responsive-demo/index.html +13 -0
- package/examples/responsive-demo/src/main.tsx +110 -0
- package/examples/responsive-demo/src/style.css +344 -0
- package/examples/responsive-demo/vite.config.ts +9 -0
- package/lib/THIRD_PARTY_LICENSES.md +345 -0
- package/lib/bridge.js +890 -0
- package/lib/bridge.js.map +7 -0
- package/lib/client.js +1083 -0
- package/lib/client.js.map +7 -0
- package/lib/host/THIRD_PARTY_NOTICES.md +15 -0
- package/lib/host/browser-provider/LICENSE +21 -0
- package/lib/host/browser-provider/README.md +130 -0
- package/lib/host/browser-provider/lib/client.css +217 -0
- package/lib/host/browser-provider/lib/client.css.map +7 -0
- package/lib/host/browser-provider/lib/client.js +2360 -0
- package/lib/host/browser-provider/lib/client.js.map +7 -0
- package/lib/host/browser-provider/lib/index.js +7 -0
- package/lib/host/browser-provider/lib/index.js.map +7 -0
- package/lib/host/browser-provider/package.json +23 -0
- package/lib/host/bundle.json +27 -0
- package/lib/host/chat-provider/LICENSE +21 -0
- package/lib/host/chat-provider/README.md +186 -0
- package/lib/host/chat-provider/lib/client.css +1604 -0
- package/lib/host/chat-provider/lib/client.css.map +7 -0
- package/lib/host/chat-provider/lib/client.js +11074 -0
- package/lib/host/chat-provider/lib/client.js.map +7 -0
- package/lib/host/chat-provider/lib/index.js +911 -0
- package/lib/host/chat-provider/lib/index.js.map +7 -0
- package/lib/host/chat-provider/package.json +31 -0
- package/lib/host/layout-provider/LICENSE +21 -0
- package/lib/host/layout-provider/README.md +109 -0
- package/lib/host/layout-provider/lib/client.css +177 -0
- package/lib/host/layout-provider/lib/client.css.map +7 -0
- package/lib/host/layout-provider/lib/client.js +565 -0
- package/lib/host/layout-provider/lib/client.js.map +7 -0
- package/lib/host/layout-provider/lib/index.js +7 -0
- package/lib/host/layout-provider/lib/index.js.map +7 -0
- package/lib/host/layout-provider/package.json +25 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +9 -0
- package/lib/index.js.map +7 -0
- package/lib/vite.d.ts +8 -0
- package/lib/vite.js +1254 -0
- package/lib/vite.js.map +7 -0
- package/licenses/deepseek-harness-MIT.txt +21 -0
- package/locale/AGENTS.md +11 -0
- package/locale/README.md +11 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +154 -4
- package/screenshots.json +7 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# DSH Web Annotator 架构说明
|
|
2
|
+
|
|
3
|
+
本文件只写不变的设计决策、契约与失败模式(“为什么”)。
|
|
4
|
+
文件级职责与“改哪”见各子树 `README.md`;用法见根 [README.md](../README.md)。
|
|
5
|
+
|
|
6
|
+
## 一、产品边界
|
|
7
|
+
|
|
8
|
+
- 主流程**扩展 Harness 原有 Browser**:点选或框选网页、就地输入评论或提问、发送到当前会话。
|
|
9
|
+
- 不提供独立的浏览器、不提供像素对比、不提供自动改源码引擎;修改源码由当前会话中的 Agent 完成。
|
|
10
|
+
- 页面中的文字、样式、源码标记一律是**引用资料**,不构成指令。
|
|
11
|
+
|
|
12
|
+
## 二、三个半端
|
|
13
|
+
|
|
14
|
+
| 半端 | 运行位置 | 产物 | 约束 |
|
|
15
|
+
| ----------- | ------------------ | -------------------------------------- | --------------------------------------- |
|
|
16
|
+
| 宿主入口 | Harness 宿主进程 | `lib/index.js` | 只声明名字;功能都在 Client 半端 |
|
|
17
|
+
| Client 半端 | Harness Web Client | `lib/client.js` | 反映射到 Browser 插槽;不得引 Node 模块 |
|
|
18
|
+
| 页面拾取器 | 被访问网页 | `lib/bridge.js`(开发页)/ 宿主 picker | 只使用浏览器全局;不得有 import |
|
|
19
|
+
|
|
20
|
+
`lib/vite.js` 是开发期的第四个产物,只在 Vite `serve` 阶段挂载。
|
|
21
|
+
|
|
22
|
+
## 三、契约
|
|
23
|
+
|
|
24
|
+
### 3.1 picker 必须自包含
|
|
25
|
+
|
|
26
|
+
Desktop 只把 `annotatePage` 的**编译体**送进已批准的 guest:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
element.executeJavaScript(`(${annotatePage.toString()})(${JSON.stringify(options)})`)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
因此 `src/browser/page-inspector.ts` **不能有任何 import**:模块级绑定在 guest 中会变成未定义标识符。
|
|
33
|
+
判据:`scripts/check-layering.mjs` 的 `picker-self-contained`,以及 `tests/picker-source.test.ts`。
|
|
34
|
+
|
|
35
|
+
### 3.2 四份共享模块
|
|
36
|
+
|
|
37
|
+
`page-inspector.ts` / `protocol.ts` / `iframe-annotation.ts` / `screenshot.ts` 在宿主补丁中保留同步副本。
|
|
38
|
+
|
|
39
|
+
- 同步方向**单向**:本包是事实源,`npm run sync:browser-provider` 写入宿主检出。
|
|
40
|
+
- 宿主方构建前逐字节比对,不一致就拒绝构建。
|
|
41
|
+
- 模块清单只有一份:`scripts/shared-modules.mjs`。
|
|
42
|
+
|
|
43
|
+
### 3.3 插槽
|
|
44
|
+
|
|
45
|
+
Browser 补丁声明两个会话作用域的 list 子插槽:
|
|
46
|
+
|
|
47
|
+
| 插槽 | 贡献 |
|
|
48
|
+
| --------------------------------------- | ------------------------------ |
|
|
49
|
+
| `sidebar.right.tab.browser.toolbar` | “批注网页/退出批注”按钮 |
|
|
50
|
+
| `sidebar.right.tab.browser.annotations` | 批注队列、发送方式、预览与发送 |
|
|
51
|
+
|
|
52
|
+
Owner props 只暴露 tab ID、已知 URL、加载状态,以及受限的 `annotate(options)` / `cancelAnnotation()`。
|
|
53
|
+
回调**不暴露** DOM、guest 标识或任意求值器。
|
|
54
|
+
|
|
55
|
+
Chat 补丁声明增量 `conversation.message.user-text` chain。
|
|
56
|
+
该 chain 只接管**完整通过格式与协议校验**的本插件请求;其他消息走宿主 fallback。
|
|
57
|
+
被接管的请求默认只显示“N 条注释”与定位资料折叠:逐条卡片(序号、目标元素、评论或提问)
|
|
58
|
+
按需展开,避免长队列撑高聊天记录。
|
|
59
|
+
|
|
60
|
+
### 3.4 消息边界
|
|
61
|
+
|
|
62
|
+
本包的插件与页面之间有两种通道,都必须校验来源、origin 与载荷:
|
|
63
|
+
|
|
64
|
+
| 通道 | 用途 | 校验 |
|
|
65
|
+
| --------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------ |
|
|
66
|
+
| `dsh-browser-annotation-v1` + 独立 `MessageChannel` | Client 半端驱动页面 picker | 只接受 `window.parent`;origin 必须是 loopback HTTP 或显式配置;`options` 逐字段限长 |
|
|
67
|
+
| `__web-annotator__/bridge.js` 内联配置 | 开发页声明允许的父来源 | 只接受精确 HTTP(S) origin,不接受路径、凭据或通配符 |
|
|
68
|
+
|
|
69
|
+
### 3.5 存储
|
|
70
|
+
|
|
71
|
+
- 截图队列进 **IndexedDB**(库名 `dsh-web-annotator`),因为 localStorage 的共享配额会静默丢草稿。
|
|
72
|
+
- 键按**会话 + 完整 URL**(含 path / query / hash)隔离。
|
|
73
|
+
- 旧的 localStorage 记录只有在新键**提交成功之后**才删除。
|
|
74
|
+
- `dsh.layout-care.browser-annotations.v1` 是 alpha.8 及更早的键;读一次迁移,之后不再写入。
|
|
75
|
+
它是唯一允许出现的退休名字,集中在 `src/client/legacy-names.ts`。
|
|
76
|
+
|
|
77
|
+
### 3.6 请求格式
|
|
78
|
+
|
|
79
|
+
- 评论与提问分别保留意图。
|
|
80
|
+
- 图片模式只发批注正文、网页 URL 与对应截图,不含 DOM JSON。
|
|
81
|
+
- 混合模式用 `screenshotIndex` 明确“第 N 张图对应第几条批注”,不位移未附图的批注。
|
|
82
|
+
- 附件在 Client 半端重画:截图角上叠加与附图序号一致的序号徽标,重画不可用时保留宿主截图,
|
|
83
|
+
证据不因绘制失败而丢失。
|
|
84
|
+
- 单条批注 ≤ 1000 字符;一页 ≤ 32 条;请求 ≤ 64000 字符。
|
|
85
|
+
- 页面文字不能闭合 JSON 代码块;识别时逐条重放并比对完整文本。
|
|
86
|
+
|
|
87
|
+
## 四、失败模式
|
|
88
|
+
|
|
89
|
+
| 失败 | 行为 |
|
|
90
|
+
| ------------------- | ------------------------------------------------------------ |
|
|
91
|
+
| 发送失败 | 保留全部批注,只有**成功发送的已选 ID** 被移除 |
|
|
92
|
+
| 存储失败 | 内存内容仍可用,界面提示“刷新前先发送” |
|
|
93
|
+
| 页面导航 / 目标被删 | 目标消失时禁用确认,`targetGone` 提示重新选择 |
|
|
94
|
+
| 握手超时 | 开发页 3 秒,Desktop picker 65 秒;超时后取消 picker 并报错 |
|
|
95
|
+
| 重复连接 | 同一可信父页面可轮换 token;新连接取消旧的 picker 与在途请求 |
|
|
96
|
+
| 处理函数抛出 | 通道返回 `{cancelled:true}` 并关闭,不留下悬挂通道 |
|
|
97
|
+
|
|
98
|
+
## 五、否定式约束(做不到就明说)
|
|
99
|
+
|
|
100
|
+
- Web 不能突破跨源与嵌入策略;iframe 内网页需要目标页面自己启用开发连接。
|
|
101
|
+
- closed Shadow DOM 与嵌套 iframe 内部不提供精确元素证据;只定位外层载体。
|
|
102
|
+
- 不把 CSS selector 或网页 source 提示当作准确的源码文件,需在工作区核实。
|
|
103
|
+
- 模型能否识别图片取决于当前模型的图片能力。
|
|
104
|
+
|
|
105
|
+
## 六、分层与门禁
|
|
106
|
+
|
|
107
|
+
依赖方向(`npm run check:layering` 逐条拦):
|
|
108
|
+
|
|
109
|
+
| 规则 | 含义 |
|
|
110
|
+
| ----------------------- | ------------------------------------------------------------------- |
|
|
111
|
+
| `picker-self-contained` | 页面 picker 不得有任何 import |
|
|
112
|
+
| `browser-no-client` | 页面半端不得依赖 Client 半端 |
|
|
113
|
+
| `client-no-bridge` | Client 半端不得依赖宿主 picker 之外的页面半端实现 |
|
|
114
|
+
| `client-no-node` | 浏览器半端不得依赖 Node 内置模块 |
|
|
115
|
+
| `host-no-client` | 宿主入口与 Vite 插件不得依赖 Client 半端 |
|
|
116
|
+
| `no-retired-names` | 不得重新引入已退休的运行时名字(`src/client/legacy-names.ts` 除外) |
|
|
117
|
+
|
|
118
|
+
每条规则必须真的扫到文件,否则报 `rule-not-wired`:没扫到就等于没生效。
|
|
119
|
+
|
|
120
|
+
### 6.1 两个类型检查项目
|
|
121
|
+
|
|
122
|
+
依赖方向只靠脚本拦不够:类型系统也要能表达"这一半看不到那一半的全局"。
|
|
123
|
+
|
|
124
|
+
| 项目 | 覆盖 | `lib` | 拦住什么 |
|
|
125
|
+
| ----------------------------------------------- | ---------------------------------------------------- | --------------------------------------------------- | -------------------------------------------------- |
|
|
126
|
+
| [tsconfig.json](../tsconfig.json) | `src/index.ts`、`src/vite.ts` | `ES2022`(**无 DOM**) | 宿主半边用 `document` / `window`(报 `TS2584`) |
|
|
127
|
+
| [tsconfig.client.json](../tsconfig.client.json) | `src/browser/`、`src/client/`、`tests/`、`examples/` | `ES2022` + `DOM` + `DOM.Iterable`,`jsx: react-jsx` | 浏览器半边误用宿主模块(另由 `client-no-node` 拦) |
|
|
128
|
+
|
|
129
|
+
`npm run typecheck` 依次跑两个项目。合成一个 program 时两边互相污染:
|
|
130
|
+
宿主文件能用 DOM 全局、浏览器文件能 `import 'node:fs'`,而类型检查**都通过**。
|
|
131
|
+
|
|
132
|
+
## 七、分发
|
|
133
|
+
|
|
134
|
+
- 一个预构建包同时包含插件与 Browser / Chat / Layout 三个派生提供方。
|
|
135
|
+
- 包内 `cordis.patch.yml` 禁用官方三行,再插入包内提供方;卸载整个 bundle 即撤销替换。
|
|
136
|
+
- `npm pack` 由 `prepack` 拦截:缺少产物、版本不符或补丁哈希不符时拒绝打包。
|
|
137
|
+
|
|
138
|
+
## 八、防错清单
|
|
139
|
+
|
|
140
|
+
每条都来自一次真实故障或已核实的机制,改动前先读。
|
|
141
|
+
**编号是稳定的:只增不重排,删掉的条目留下空缺号**,否则引用会指到别处。
|
|
142
|
+
**只收录已挂判据的条目** —— 没有判据的规则留在散文里(如 [tests/README.md](../tests/README.md)
|
|
143
|
+
的「判据不能住在 `.tsx` 里」、根 [AGENTS.md](../AGENTS.md) 活跃坑里的 `--from-default-profile`),
|
|
144
|
+
否则这张表会变成一个会漂的家。
|
|
145
|
+
|
|
146
|
+
| 编号 | 怎么踩的 | 后果(报不报错) | 判据 |
|
|
147
|
+
| ---- | ------------------------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
148
|
+
| F1 | 在 `page-inspector.ts` 里加 import | guest 里模块级绑定变成未定义标识符——**构建期不报** | `check:layering` 的 `picker-self-contained`;`tests/picker-source.test.ts` |
|
|
149
|
+
| F2 | 浏览器半端 `import 'node:fs'` | 产物内联宿主模块——构建不报 | `check:layering` 的 `client-no-node` |
|
|
150
|
+
| F3 | 页面半端依赖 Client 半端 | 运行位置错配——构建不报 | `check:layering` 的 `browser-no-client` |
|
|
151
|
+
| F4 | Client 半端依赖宿主 picker 实现 | 宿主代码被打进浏览器产物 | `check:layering` 的 `client-no-bridge` |
|
|
152
|
+
| F5 | 宿主入口或 Vite 插件依赖 Client 半端 | 产物边界破掉 | `check:layering` 的 `host-no-client` |
|
|
153
|
+
| F6 | 重新引入 `layout-care` 运行时名字 | 静默并存两套协议 | `check:layering` 的 `no-retired-names`(豁免 `src/client/legacy-names.ts`) |
|
|
154
|
+
| F7 | 新增规则但没匹配到任何文件 | 规则**看起来像已生效** | `check:layering` 的 `rule-not-wired` |
|
|
155
|
+
| F8 | 改了四份共享模块却没同步宿主副本 | 中间一路静默,到宿主构建才报错 | `scripts/build-browser-provider.mjs` 逐字节比对;清单 `scripts/shared-modules.mjs` |
|
|
156
|
+
| F9 | 改了宿主检出但没重生成补丁 | `prepack` 哈希断言失败,但**不告诉你哪一行错了** | `npm run verify:browser-patch` |
|
|
157
|
+
| F10 | 产物缺失或过期就分发 | 装完批注按钮不可用——只有用户会碰到 | `prepack`(`scripts/check-package.mjs`) |
|
|
158
|
+
| F11 | 客户端产物少一个 `inject` | 插件**静默不出现** | `npm run verify:artifacts` |
|
|
159
|
+
| F12 | React 被内联进客户端产物 | 加载时 `process is not defined`,插件激活失败 | `verify:artifacts` 的 require 清单断言 |
|
|
160
|
+
| F13 | 包名 / loader id / patch 行 id 漂移 | profile 解析不到,或区块静默不渲染 | `verify:artifacts` 的三处一致断言 |
|
|
161
|
+
| F14 | 在 `.github/` 下放 `README.md` | 仓库首页被换成内部手册,**全部门禁照绿** | `check:doc-paths` 的 `homepageFailures` |
|
|
162
|
+
| F15 | 文件改名后没改文档里的路径 | 零信号 | `check:doc-paths` 的链接检查 |
|
|
163
|
+
| F16 | 文档里写了不存在的 `npm run <脚本名>` | 读者手动执行时才发现 | `check:doc-paths` 的脚本名检查 |
|
|
164
|
+
| F17 | 新增截图没登记 | 只在市场条目里看得出来 | `check:doc-paths` 的 `screenshotFailures` |
|
|
165
|
+
| F18 | 格式门禁比本地钩子窄 | 被漏掉的那批文件格式没有任何信号 | `tests/format-scope.test.ts`(只钉「门禁 ⊇ 钩子」一个方向) |
|
|
166
|
+
| F19 | 宿主半边用了 `document` / `window` | ——**当场报** `TS2584` | [tsconfig.json](../tsconfig.json) 无 DOM;§6.1 |
|
|
167
|
+
| F20 | 把 `check` 改成 typecheck 先于 build | `TS2307`:类型检查要读 `lib/vite.d.ts` | §6.1 与 [../scripts/README.md](../scripts/README.md) 的顺序说明 |
|
|
168
|
+
| F21 | 未登记的错误码默认当成成功 | 真实错误被掩盖 | `tests/annotation-view.test.ts` |
|
|
169
|
+
| F22 | picker 字段表三处漂开 | 页面少一行文字,不报错 | `tests/annotation-view.test.ts` 的逐字段删除断言 |
|
|
170
|
+
| F23 | 文案表里留了没人引用的键 | 表里说有、界面里没有 | `tests/annotation-copy.test.ts` |
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Browser 集成
|
|
2
|
+
|
|
3
|
+
原版 Harness rc.2 不声明批注插槽。本包配套的补丁扩展三个包:
|
|
4
|
+
|
|
5
|
+
| 包 | 补丁做什么 |
|
|
6
|
+
| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
|
|
7
|
+
| `packages/client/ui-sidebar-browser` | 声明 `sidebar.right.tab.browser.toolbar` 与 `...annotations` 子插槽;工具栏贡献渲染在“刷新”左侧;新增受限 picker 与桌面截图 |
|
|
8
|
+
| `packages/client/ui-chat` | 声明增量 `conversation.message.user-text` chain,让插件折叠自己识别的批注消息 |
|
|
9
|
+
| `packages/client/ui-layout` | 右栏全屏时隐藏并将后方主内容设为 inert,避免壁纸玻璃层叠让聊天输入框浮到网页上方 |
|
|
10
|
+
|
|
11
|
+
补丁尚未合入官方 Harness。这是当前安装会替换官方三行的原因。
|
|
12
|
+
|
|
13
|
+
## 补丁是什么
|
|
14
|
+
|
|
15
|
+
[docs/harness-browser-annotation.patch](harness-browser-annotation.patch) 是宿主检出的 `git diff HEAD`,
|
|
16
|
+
基线 commit 记在 [../scripts/shared-modules.mjs](../scripts/shared-modules.mjs)(`HOST_BASE_COMMIT`)。
|
|
17
|
+
|
|
18
|
+
它是**生成物**,不要手改。重新生成:
|
|
19
|
+
|
|
20
|
+
```powershell
|
|
21
|
+
git -C ../harness-browser-integration diff HEAD --output docs/harness-browser-annotation.patch
|
|
22
|
+
npm run verify:browser-patch
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`verify:browser-patch` 会在独立的临时 Git root 里把补丁应用到精确基线,
|
|
26
|
+
再与宿主检出逐字节比对。不这么做时 `git apply` 会静默跳过路径,看不出问题。
|
|
27
|
+
|
|
28
|
+
## 应用与构建
|
|
29
|
+
|
|
30
|
+
在插件目录旁检出 `harness-browser-integration`,切到基线 commit:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
git apply --check /absolute/path/to/harness-browser-annotation.patch
|
|
34
|
+
git apply /absolute/path/to/harness-browser-annotation.patch
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
回到插件目录:
|
|
38
|
+
|
|
39
|
+
```powershell
|
|
40
|
+
npm run sync:browser-provider # 改了共享 picker 模块之后必须跑
|
|
41
|
+
npm run build:browser-provider # 比对四份共享模块,再从宿主检出构建
|
|
42
|
+
npm run build:chat-provider
|
|
43
|
+
npm run build:layout-provider
|
|
44
|
+
npm run typecheck:browser-provider
|
|
45
|
+
npm run typecheck:chat-provider
|
|
46
|
+
npm run typecheck:layout-provider
|
|
47
|
+
npm run build:host # 三个提供方 + 许可证 → lib/host
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
构建脚本读 `DSH_HOST_CHECKOUT`(默认 `../harness-browser-integration`),
|
|
51
|
+
CI 与发布链路用这个变量指向 `.host-source`。
|
|
52
|
+
|
|
53
|
+
四份共享模块在本包与宿主副本之间必须逐字节相同(只有 import 后缀不同),
|
|
54
|
+
清单在 [../scripts/shared-modules.mjs](../scripts/shared-modules.mjs)。
|
|
55
|
+
`build-browser-provider` 会在不一致时直接失败。同步方向是单向的:本包是事实源。
|
|
56
|
+
|
|
57
|
+
局部类型检查针对已安装 rc.2 声明,不能替代官方 monorepo 的全仓检查。
|
|
58
|
+
|
|
59
|
+
## 单包分发
|
|
60
|
+
|
|
61
|
+
三个提供方就绪后 `npm pack`。`prepack` 检查产物齐全、版本一致、补丁哈希一致,
|
|
62
|
+
缺失或过期时拒绝打包。`lib/host/bundle.json` 记录宿主来源与逐文件哈希。
|
|
63
|
+
|
|
64
|
+
包内 [cordis.patch.yml](../cordis.patch.yml) 禁用官方三行,再插入包内提供方。
|
|
65
|
+
Loader 的按 ID patch 里 `name` 只能断言已有名称、不能重命名,因此用新的行 ID。
|
|
66
|
+
卸载整个 bundle 后这些替换随 bundle 层撤销。
|
|
67
|
+
|
|
68
|
+
## 开发页连接
|
|
69
|
+
|
|
70
|
+
Web 侧只向 Browser 自己拥有的 iframe 发送有界请求。目标页面需要启用本包的 Vite 连接:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { defineConfig } from 'vite';
|
|
74
|
+
import { webAnnotator } from 'dsh-web-annotator/vite';
|
|
75
|
+
|
|
76
|
+
export default defineConfig({ plugins: [webAnnotator()] });
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
插件只在 `serve` 阶段生效:托管 `__web-annotator__/bridge.js`、内联允许的父来源、
|
|
80
|
+
给 JSX 原生标签加 `data-web-annotator-source` 提示。生产构建不注入连接脚本或标记。
|
|
81
|
+
|
|
82
|
+
连接默认允许 HTTP loopback 来源;其他来源通过 `allowedParentOrigins` 指定精确 HTTP(S) origin。
|
|
83
|
+
|
|
84
|
+
## Web 与 Desktop 的差别
|
|
85
|
+
|
|
86
|
+
| | Web | Desktop |
|
|
87
|
+
| ------------------------ | ----------------------------- | ----------------------------------- |
|
|
88
|
+
| picker | iframe 内由本包的开发连接提供 | 宿主执行 `annotatePage` 的编译体 |
|
|
89
|
+
| 截图 | 无原生捕获 | 保存后调用 guest 的 `capturePage()` |
|
|
90
|
+
| 图片经 Canvas 标注与缩放 | — | 是 |
|
|
91
|
+
| 导航 / 视口 / 滚动变化 | 拒绝混用 | 拒绝混用截图 |
|
|
92
|
+
| 捕获失败 | — | 保留定位资料 |
|
|
93
|
+
|
|
94
|
+
Desktop 的 guest / 导航 / 关闭 / 快捷键仍需真机验收,不能用 Web 结果代替。
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# 安装与市场发布
|
|
2
|
+
|
|
3
|
+
## 当前状态
|
|
4
|
+
|
|
5
|
+
包名 `dsh-web-annotator`,源码在 [cslkkl/dsh-web-annotator](https://github.com/cslkkl/dsh-web-annotator)。
|
|
6
|
+
预构建包通过 GitHub Release 分发,面向精确 Harness **0.2.0-rc.2**,用户不需要编译。
|
|
7
|
+
版本号见 [../package.json](../package.json)。npm 尚未发布过:发布链路(OIDC Trusted Publishing)
|
|
8
|
+
已就绪,**只差一次性的建包与配置**,步骤在 [发布链路](publishing.md) 的 npm 发布节。
|
|
9
|
+
社区目录的条目已提交、**等待维护者审阅**([awesome-dsh-plugin#6833](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin/pull/6833)),
|
|
10
|
+
**提交不等于收录**:合并并被目录同步之后,才能声明该市场可搜索、可安装。
|
|
11
|
+
|
|
12
|
+
安装包带有 Browser、Chat、Layout 的派生提供方。整个 bundle 的启用、禁用或卸载由官方插件管理负责;
|
|
13
|
+
要恢复官方界面,卸载整个 bundle 后重启。不要单独禁用其中一个组件,因为主插件需要它们提供的接口。
|
|
14
|
+
|
|
15
|
+
旧的两个 Layout Care 预览包(`dsh-layout-care`、`dsh-layout-care-browser-preview`)应先移除再安装新包,
|
|
16
|
+
避免同时挂载两套提供方。
|
|
17
|
+
|
|
18
|
+
## 公开发布顺序
|
|
19
|
+
|
|
20
|
+
1. 源码推到公开仓库,设置 `dsh-plugin` topic。
|
|
21
|
+
2. bump `package.json` 的版本号、`CHANGELOG.md` 的对应一节与市场条目的 `tarball` 行,推 `main`;
|
|
22
|
+
再推 `v<版本>` 标签。[release workflow](../.github/workflows/release.yml) 随后跑门禁、
|
|
23
|
+
打包产物验收与交付一致性,建出挂着预构建 `.tgz`(外加源码 ZIP 与验证记录)的预览 Release,
|
|
24
|
+
最后把同一份产物发到 npm 的 `alpha` dist-tag —— 预览版不碰 `latest`。
|
|
25
|
+
3. 完成稳定版所需的原生截图、真实模型与兼容验收后,去掉 `--tag alpha`,发布稳定版并设置 `latest`。
|
|
26
|
+
4. 向社区目录提交 [marketplace 条目](marketplace/cslkkl__dsh-web-annotator.yml)。
|
|
27
|
+
合并并被目录同步后,才能声明该市场可搜索、可安装。
|
|
28
|
+
5. 在新 Profile 中走一遍搜索、安装、重启、批注、卸载,记录精确市场与宿主版本。
|
|
29
|
+
|
|
30
|
+
## 各渠道的收录规则
|
|
31
|
+
|
|
32
|
+
| 渠道 | 要求 | 本项目的做法 |
|
|
33
|
+
| -------------------------------------- | -------------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
34
|
+
| DSH 官方插件管理页 / CLI | 预构建包声明合法 `dsh.bundle.patch`,可安装 npm spec 或本地 tgz | 安装一个预构建包 |
|
|
35
|
+
| `dshmarket`(awesome-dsh-plugin 目录) | 向目录仓库提交插件 YAML,维护者审阅合并;仓库须创建满一天并带 `dsh-plugin` topic | 条目用 `tarball` 指向已发布的 Release tgz,不必先发 npm |
|
|
36
|
+
| 按 GitHub topic 自动发现的市场 | 仓库带 `dsh-plugin` topic;安装方式取决于各市场 | 标签便于发现,不等于安装已验收 |
|
|
37
|
+
| Desktop 的 `dsh-community-market` | 目录解析唯一 npm 包名,要求 npm `latest` 是稳定精确版本 | alpha 发的是 `alpha` dist-tag,`latest` 留空;稳定版才满足 |
|
|
38
|
+
| npm(可选) | 包的 `repository` 字段必须指回本仓库,否则不会与条目关联 | 已声明;发布走 OIDC,用 `alpha` dist-tag |
|
|
39
|
+
|
|
40
|
+
以上是查阅公开实现得到的规则,未在市场 UI 中实际安装本项目。
|
|
41
|
+
其他版本或来源的行为需要分别确认。收录结果由市场维护者决定。
|
|
42
|
+
命名协调用的 `dsh-plugin-registry` 是另一个机制,不等于市场目录。
|
|
43
|
+
|
|
44
|
+
## 条目里的 tarball 必须跟着版本走
|
|
45
|
+
|
|
46
|
+
[marketplace 条目](marketplace/cslkkl__dsh-web-annotator.yml) 的 `tarball` 钉的是**具体标签**
|
|
47
|
+
(`releases/download/v<版本>/…`),不是 `releases/latest/download/…`:
|
|
48
|
+
|
|
49
|
+
- **为什么不能用 `latest`**:本仓所有 Release 都是预发布版,`/releases/latest` **解析不到任何 Release**
|
|
50
|
+
(实测 `latest/download/<文件>` 直接 404)。上游两种写法都接受,而这里只有钉标签一种可用。
|
|
51
|
+
- **代价**:钉标签意味着**每发一版都要同步改这一行**,否则市场指向的是旧包。
|
|
52
|
+
上游的每日探测会在 URL 404 时把 tarball 从站点上摘掉(不会报错,只是静默回落成源码安装),
|
|
53
|
+
所以这行漏改不会有红信号 —— 判据是发版后手跑一次
|
|
54
|
+
`curl -sI https://github.com/cslkkl/dsh-web-annotator/releases/download/v<版本>/dsh-web-annotator-<版本>.tgz`。
|
|
55
|
+
|
|
56
|
+
上游要求 `url` 与仓库完全一致、描述只说功能且**必须属实**(会被对着代码核),
|
|
57
|
+
仓库需创建满一天、带 `dsh-plugin` topic、`package.json` 声明 `dsh.bundle`。
|
|
58
|
+
提交前可在目录仓库检出里用 `readEntries()` / `validateEntries()` / `tarballProblem()` 与
|
|
59
|
+
`check-submission.mjs --only-list` 自检 —— 全部通过再提 PR。
|
|
60
|
+
|
|
61
|
+
## 规则来源
|
|
62
|
+
|
|
63
|
+
- [DSH 插件发布说明](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.2.0-rc.2/docs/user/develop/basic/publish.zh.md)
|
|
64
|
+
- [dshmarket 的 Submit your plugin](https://github.com/dsh-market/dsh-market#submit-your-plugin)
|
|
65
|
+
- [awesome-dsh-plugin 贡献指南](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin/blob/main/contributing.md)
|
|
66
|
+
- [Desktop Community Market 安装规则](https://github.com/anywhere-labs/dsh-desktop/blob/master/dsh-community-market/docs/install-and-uninstall.zh.md)
|