dsh-reference-anything 0.4.3 → 0.5.0

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.
Files changed (122) hide show
  1. package/NOTICE.md +58 -0
  2. package/README.md +159 -70
  3. package/cordis.patch.yml +17 -15
  4. package/images/agents/LICENSE +22 -0
  5. package/images/agents/README.md +3 -0
  6. package/images/agents/antigravity.svg +1 -0
  7. package/images/agents/chatgpt.svg +1 -0
  8. package/images/agents/claude.svg +1 -0
  9. package/images/agents/cline.svg +1 -0
  10. package/images/agents/codex.svg +1 -0
  11. package/images/agents/continue.svg +1 -0
  12. package/images/agents/crush.svg +1 -0
  13. package/images/agents/cursor.svg +1 -0
  14. package/images/agents/dsh.svg +1 -0
  15. package/images/agents/gemini.svg +1 -0
  16. package/images/agents/goose.svg +1 -0
  17. package/images/agents/grokbuild.svg +1 -0
  18. package/images/agents/hermes.svg +1 -0
  19. package/images/agents/kilocode.svg +1 -0
  20. package/images/agents/kimi.svg +1 -0
  21. package/images/agents/mimocode.svg +1 -0
  22. package/images/agents/openclaw.svg +1 -0
  23. package/images/agents/opencode.svg +1 -0
  24. package/images/agents/pi.svg +1 -0
  25. package/images/agents/qoder.svg +1 -0
  26. package/images/agents/qwen.svg +1 -0
  27. package/images/agents/reasonix.svg +6 -0
  28. package/images/agents/teleagent.svg +1 -0
  29. package/images/agents/trae.svg +1 -0
  30. package/images/agents/vibe.svg +1 -0
  31. package/images/agents/workbuddy.svg +37 -0
  32. package/images/agents/zcode.svg +1 -0
  33. package/images/agents/zed.svg +1 -0
  34. package/lib/agent-scan-cache.d.ts +13 -0
  35. package/lib/agent-scan-cache.js +43 -0
  36. package/lib/chat-import-compatibility.d.ts +18 -0
  37. package/lib/chat-import-compatibility.js +87 -0
  38. package/lib/chat-import-discovery.d.ts +32 -0
  39. package/lib/chat-import-discovery.js +17 -0
  40. package/lib/chat-import-reader.d.ts +27 -0
  41. package/lib/chat-import-reader.js +111 -0
  42. package/lib/chat-import-runtime.d.ts +4 -0
  43. package/lib/chat-import-runtime.js +4 -0
  44. package/lib/client/index.d.ts +5 -0
  45. package/lib/client.js +4 -33741
  46. package/lib/contract.d.ts +65 -4
  47. package/lib/contract.js +24 -4
  48. package/lib/conversation-availability.d.ts +13 -0
  49. package/lib/conversation-availability.js +76 -0
  50. package/lib/errors.d.ts +2 -2
  51. package/lib/host.d.ts +104 -11
  52. package/lib/host.js +202 -14
  53. package/lib/index.d.ts +3 -1
  54. package/lib/index.js +31 -3
  55. package/lib/local-conversation-reader.d.ts +3 -0
  56. package/lib/local-conversation-reader.js +81 -0
  57. package/lib/local-conversation-scanner.d.ts +18 -0
  58. package/lib/local-conversation-scanner.js +55 -0
  59. package/lib/local-locator.d.ts +14 -0
  60. package/lib/local-locator.js +34 -0
  61. package/lib/local-plugins.d.ts +6 -0
  62. package/lib/local-plugins.js +119 -0
  63. package/lib/local-reference-tools.d.ts +4 -0
  64. package/lib/local-reference-tools.js +195 -0
  65. package/lib/local-reference.d.ts +118 -0
  66. package/lib/local-reference.js +289 -0
  67. package/lib/opencli.d.ts +5 -2
  68. package/lib/opencli.js +88 -64
  69. package/lib/reference.d.ts +5 -3
  70. package/lib/reference.js +167 -72
  71. package/lib/render.d.ts +1 -1
  72. package/lib/render.js +4 -4
  73. package/lib/retain.d.ts +14 -0
  74. package/lib/retain.js +1 -1
  75. package/lib/serialize.d.ts +1 -1
  76. package/lib/serialize.js +2 -2
  77. package/lib/sources/local-agent/index.d.ts +23 -16
  78. package/lib/sources/local-agent/index.js +101 -15
  79. package/lib/store/spec.d.ts +104 -7
  80. package/lib/sync/index.js +4 -0
  81. package/lib/tool.d.ts +2 -0
  82. package/lib/tool.js +36 -41
  83. package/lib/typert.js +3 -0
  84. package/lib/types.d.ts +2 -0
  85. package/lib/update.d.ts +2 -0
  86. package/lib/update.js +12 -0
  87. package/lib/uri-codec.d.ts +1 -0
  88. package/lib/uri-codec.js +64 -3
  89. package/lib/uri.d.ts +1 -10
  90. package/lib/uri.js +16 -5
  91. package/lib/web.js +3 -1
  92. package/lib/wire.d.ts +200 -0
  93. package/lib/wire.js +38 -13
  94. package/opencli-plugin/common.js +5 -3
  95. package/opencli-plugin/opencli-plugin.json +1 -1
  96. package/opencli-plugin/package.json +1 -1
  97. package/package.json +30 -4
  98. package/release-notes/0.4.4/commands.png +0 -0
  99. package/release-notes/0.4.4/demos/agent-import.gif +0 -0
  100. package/release-notes/0.4.4/demos/chat-import-upgrade.gif +0 -0
  101. package/release-notes/0.4.4/demos/folders.gif +0 -0
  102. package/release-notes/0.4.4/demos/local-plugins.gif +0 -0
  103. package/release-notes/0.4.4/demos/shortcuts.gif +0 -0
  104. package/release-notes/0.4.4/features.json +36 -0
  105. package/release-notes/0.4.4/files.png +0 -0
  106. package/release-notes/0.5.0/demos/agent-import.gif +0 -0
  107. package/release-notes/0.5.0/demos/chat-import-upgrade.gif +0 -0
  108. package/release-notes/0.5.0/demos/folders.gif +0 -0
  109. package/release-notes/0.5.0/demos/local-plugins.gif +0 -0
  110. package/release-notes/0.5.0/demos/local-references.gif +0 -0
  111. package/release-notes/0.5.0/demos/shortcuts.gif +0 -0
  112. package/release-notes/0.5.0/features.json +65 -0
  113. package/release-notes/README.md +36 -0
  114. package/vendor/chat-import-reader/LICENSE +22 -0
  115. package/vendor/chat-import-reader/LICENSE.fzstd +21 -0
  116. package/vendor/chat-import-reader/README.md +48 -0
  117. package/vendor/chat-import-reader/availability-worker.mjs +114 -0
  118. package/vendor/chat-import-reader/parsers.d.mts +6 -0
  119. package/vendor/chat-import-reader/parsers.mjs +11168 -0
  120. package/vendor/chat-import-reader/scan-worker.mjs +7 -0
  121. package/vendor/chat-import-reader/scanners.mjs +4286 -0
  122. package/vendor/chat-import-reader/upstream-sha256.json +101 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-reference-anything",
3
- "version": "0.4.3",
3
+ "version": "0.5.0",
4
4
  "description": "Reference files, sessions, commands, skills, and historical external AI chats from the DSH @ menu.",
5
5
  "icon": "./images/logo-icon.png",
6
6
  "license": "MIT",
@@ -15,6 +15,10 @@
15
15
  "main": "lib/index.js",
16
16
  "types": "lib/index.d.ts",
17
17
  "exports": {
18
+ "./chat-import-runtime": {
19
+ "types": "./lib/chat-import-runtime.d.ts",
20
+ "default": "./lib/chat-import-runtime.js"
21
+ },
18
22
  ".": {
19
23
  "types": "./lib/index.d.ts",
20
24
  "default": "./lib/index.js"
@@ -70,11 +74,21 @@
70
74
  "opencli-plugin/package.json",
71
75
  "cordis.patch.yml",
72
76
  "locale/*.json",
77
+ "images/agents",
78
+ "release-notes",
73
79
  "images/logo.png",
74
80
  "images/logo-icon.png",
75
81
  "images/logo-mono.png",
76
82
  "NOTICE.md",
77
- "README.md"
83
+ "vendor/chat-import-reader/parsers.mjs",
84
+ "vendor/chat-import-reader/availability-worker.mjs",
85
+ "vendor/chat-import-reader/parsers.d.mts",
86
+ "vendor/chat-import-reader/LICENSE*",
87
+ "vendor/chat-import-reader/README.md",
88
+ "README.md",
89
+ "vendor/chat-import-reader/scanners.mjs",
90
+ "vendor/chat-import-reader/scan-worker.mjs",
91
+ "vendor/chat-import-reader/upstream-sha256.json"
78
92
  ],
79
93
  "dsh": {
80
94
  "bundle": {
@@ -96,12 +110,19 @@
96
110
  }
97
111
  },
98
112
  "scripts": {
113
+ "agent:context": "node scripts/agent/workflow.mjs context",
114
+ "agent:sync": "node scripts/agent/workflow.mjs sync",
115
+ "agent:verify": "node scripts/agent/workflow.mjs verify",
116
+ "agent:release:prepare": "node scripts/agent/workflow.mjs release-prepare",
117
+ "agent:release:gate": "node scripts/agent/workflow.mjs release-gate",
118
+ "agent:retro": "node scripts/agent/workflow.mjs retro",
99
119
  "build": "node build.mjs",
100
120
  "typecheck": "tsc -p tsconfig.json --noEmit",
101
121
  "test": "vitest run",
102
122
  "check": "npm run typecheck && npm run test && npm run build",
103
123
  "prepublishOnly": "npm run check",
104
- "prepare": "node build.mjs"
124
+ "prepare": "node build.mjs",
125
+ "vendor:sync": "node scripts/vendor-chat-import-reader.mjs"
105
126
  },
106
127
  "peerDependencies": {
107
128
  "@deepseek-ai/cordis": ">=4.0.1",
@@ -126,6 +147,7 @@
126
147
  "@deepseek-ai/dsh-session-reference": ">=0.2.0-rc.2",
127
148
  "@deepseek-ai/dsh-settings": ">=0.2.0-rc.2",
128
149
  "@deepseek-ai/dsh-storage-domain": ">=0.2.0-rc.2",
150
+ "@deepseek-ai/dsh-system-prompt": ">=0.2.0-rc.2",
129
151
  "@deepseek-ai/dsh-tools": ">=0.2.0-rc.2",
130
152
  "@deepseek-ai/dsh-typert-protocol": ">=0.2.0-rc.2",
131
153
  "@deepseek-ai/dsh-typert-registry": ">=0.2.0-rc.2",
@@ -180,13 +202,17 @@
180
202
  },
181
203
  "dependencies": {
182
204
  "@deepseek-ai/schemastery": "^3.18.1",
205
+ "@jackwener/opencli": "2.0.0",
183
206
  "@lobehub/icons": "^5.16.0",
207
+ "fflate": "0.8.2",
184
208
  "react-markdown": "^10.1.0",
185
209
  "sortablejs": "^1.15.7",
186
210
  "zod": "^4.4.3"
187
211
  },
188
212
  "devDependencies": {
189
213
  "@deepseek-ai/cordis": "^4.0.1",
214
+ "@deepseek-ai/cordis-plugin-include": "1.0.9",
215
+ "@deepseek-ai/cordis-plugin-loader": "1.0.5",
190
216
  "@deepseek-ai/dsh-agent": "0.2.0-rc.2",
191
217
  "@deepseek-ai/dsh-api-remotes": "0.2.0-rc.2",
192
218
  "@deepseek-ai/dsh-api-session-controller": "0.2.0-rc.2",
@@ -204,6 +230,7 @@
204
230
  "@deepseek-ai/dsh-file-reference": "0.2.0-rc.2",
205
231
  "@deepseek-ai/dsh-llm": "0.2.0-rc.2",
206
232
  "@deepseek-ai/dsh-output-retention": "0.2.0-rc.2",
233
+ "@deepseek-ai/dsh-plugin-manager": "0.2.0-rc.2",
207
234
  "@deepseek-ai/dsh-session": "0.2.0-rc.2",
208
235
  "@deepseek-ai/dsh-session-reference": "0.2.0-rc.2",
209
236
  "@deepseek-ai/dsh-settings": "0.2.0-rc.2",
@@ -215,7 +242,6 @@
215
242
  "@deepseek-ai/dsh-typert-registry": "0.2.0-rc.2",
216
243
  "@deepseek-ai/dsh-util-code-language": "0.2.0-rc.2",
217
244
  "@deepseek-ai/dsh-util-workspace-path": "0.2.0-rc.2",
218
- "@jackwener/opencli": "1.8.6",
219
245
  "@shikijs/langs": "4.3.1",
220
246
  "@types/node": "^22.20.1",
221
247
  "@types/react": "^18.2.0",
Binary file
@@ -0,0 +1,36 @@
1
+ [
2
+ {
3
+ "title": "引用,或导入后继续",
4
+ "description": "找到本地 Agent 历史会话后,按 Enter 引用到当前对话;想继续之前的工作,按 Tab 打开操作菜单,确认导入完整历史后在 DSH 中继续。",
5
+ "media": "demos/agent-import.gif",
6
+ "alt": "引用,或导入后继续操作演示"
7
+ },
8
+ {
9
+ "title": "升级 Chat Import,启用导入与交接",
10
+ "description": "如果 Chat Import 版本缺少导入或摘要接口,菜单和设置会提示升级。点击升级按钮,安装完成后按提示重启 DSH。演示中的版本号与执行结果为示例。",
11
+ "media": "demos/chat-import-upgrade.gif",
12
+ "alt": "升级 Chat Import,启用导入与交接操作演示"
13
+ },
14
+ {
15
+ "title": "本地插件,也能直接引用",
16
+ "description": "输入 @plugin: 查看本地插件及其状态,继续输入名称筛选。按 Enter 将插件目录插入为引用,让 Agent 基于目录检查配置和实现。",
17
+ "media": "demos/local-plugins.gif",
18
+ "alt": "本地插件,也能直接引用操作演示"
19
+ },
20
+ {
21
+ "title": "用自己的快捷词找到需要的来源",
22
+ "description": "在设置中自定义快捷词,多个词用逗号分隔。多个来源使用同一个词时,可以一起搜索;用 codex 等具体来源快捷词,则能精确限定范围。",
23
+ "media": "demos/shortcuts.gif",
24
+ "alt": "用自己的快捷词找到需要的来源操作演示"
25
+ },
26
+ {
27
+ "title": "Tab 浏览目录,Enter 引用目录",
28
+ "description": "在 @ 文件菜单中,按 Tab 进入目录继续浏览,按 Enter 引用选中的目录。引用保留文件夹图标与目录路径,方便辨认交给 Agent 的内容。",
29
+ "media": "demos/folders.gif",
30
+ "alt": "Tab 浏览目录,Enter 引用目录操作演示"
31
+ },
32
+ {
33
+ "title": "未来更新预告",
34
+ "description": "未来计划带来:\n\n1. 不依赖 OpenCLI 的静默网页端对话同步\n2. 更强大的会话搜索\n3. 更实用的 @云盘权限\n4. @电脑窗口功能\n\n这个插件靠用爱发电持续维护。如果它对你有帮助,欢迎到 GitHub 点一颗 Star 支持!也欢迎有时间、有能力的朋友提交 Issue,反馈问题和建议,或通过 PR 一起完善插件。感谢每一份支持。\n\n[前往 GitHub · Star / Issue / PR](https://github.com/Chael-Chael/dsh-reference-anything)"
35
+ }
36
+ ]
Binary file
@@ -0,0 +1,65 @@
1
+ [
2
+ {
3
+ "title": "把历史对话直接“搬”进 DSH,无缝接着聊",
4
+ "description": "以前想接着别的本地会话继续聊,要么得来回复制粘贴聊天记录,要么只能把旧对话当成静态背景资料。\n\n现在,在 **@** 菜单里找到本地历史会话,你有两种方式处理它:\n- **只当参考资料(按 **Enter**)**:直接引用该会话;\n- **接着往下聊(按 **Tab**)**:在弹出的菜单中选择**导入**并确认,就能把整段历史记录直接搬进 DSH,顺着之前的上下文继续对话!(如果觉得每次确认太麻烦,也可以在设置中关闭二次确认,一步到位)\n\n> 💡 **提示**:使用导入功能需安装并启用 **dsh-chat-import**(0.26.1 或更高兼容版本)。",
5
+ "media": "demos/agent-import.gif",
6
+ "alt": "Enter 引用会话,Tab 打开操作菜单,确认后展示模拟导入的历史;使用虚构数据。",
7
+ "en": {
8
+ "title": "Import Past Conversations into DSH and Pick Up Where You Left Off",
9
+ "description": "Want to continue an existing local session without copying and pasting chat logs or treating old threads purely as static context?\n\nNow, when you find a local session in the **@** menu, you have two ways to use it:\n- **Reference as context (**Enter**)**: Insert the session directly as a reference;\n- **Import and continue chatting (**Tab**)**: Open the action menu, select **Import**, and confirm to bring the entire conversation history into DSH and keep chatting seamlessly! (Prefer a faster workflow? You can disable the confirmation prompt in Settings.)\n\n> 💡 **Note**: Importing requires **dsh-chat-import** v0.26.1 or a compatible newer version to be installed and enabled.",
10
+ "alt": "Press Enter to reference a session, or Tab to open the action menu and import history; uses mock data."
11
+ }
12
+ },
13
+ {
14
+ "title": "菜单内一键升级配套插件,不用手动折腾",
15
+ "description": "如果提示 **dsh-chat-import** 版本太旧、用不了“对话导入”或“交接摘要”,不用自己再去后台找安装包手动更新了。\n\n直接在菜单里点击**升级提示**,即可一键完成更新(需升级至 0.26.1 或更高兼容版本)。升级后如果弹出重启提示,重启一下 DSH 即可生效。",
16
+ "media": "demos/chat-import-upgrade.gif",
17
+ "alt": "在菜单中升级 dsh-chat-import,并在设置中查看模拟的重启提示。",
18
+ "en": {
19
+ "title": "One-Click Upgrade for dsh-chat-import Right from the Menu",
20
+ "description": "If an outdated version of **dsh-chat-import** prevents you from using chat import or handoff summaries, you no longer need to update it manually.\n\nSimply click the **upgrade prompt** right inside the menu to update to v0.26.1 or later. If prompted after the upgrade, restart DSH to apply the changes.",
21
+ "alt": "Upgrade dsh-chat-import from the menu and view the simulated restart prompt in settings."
22
+ }
23
+ },
24
+ {
25
+ "title": "输入 @plugin:,直接让 Agent 帮你检查本地插件",
26
+ "description": "插件报错想让 Agent 帮忙排查,或者想研究某个插件的源码?以前还得自己去电脑深层目录里翻找插件的安装路径,非常劝退。\n\n现在只需输入 **@plugin:**,搜索插件名称并按 **Enter**,就能直接把该插件的本地目录喂给 Agent(支持当前 DSH 环境中已安装的所有插件)。",
27
+ "media": "demos/local-plugins.gif",
28
+ "alt": "在 @plugin: 菜单筛选本地插件,按 Enter 插入插件目录引用。",
29
+ "en": {
30
+ "title": "Type @plugin: to Reference Installed Plugins Directly",
31
+ "description": "Want your Agent to troubleshoot a plugin issue or inspect its source code? Digging through deep system folders just to find the installation path is a hassle.\n\nNow you can simply type **@plugin:**, search for the plugin name, and press **Enter** to pass its installation directory straight to the Agent (supports all plugins currently installed in your DSH environment).",
32
+ "alt": "Filter local plugins in the @plugin: menu and press Enter to insert the plugin directory reference."
33
+ }
34
+ },
35
+ {
36
+ "title": "自定义快捷词,直接缩小搜索范围,不用手动翻找",
37
+ "description": "**@** 菜单里东西太多,想找历史对话时还得在一堆文件、目录和不同来源里手动翻找?\n\n现在你可以给各个对话来源设置**专属快捷词**(支持设置多个,用英文逗号分隔),输入时直接按类别过滤,快速锁定搜索范围:\n- **按分类合并搜**:比如忘了具体在哪聊过,可以给“本地 Agent”和“网页对话”都加上同一个快捷词(如 **chat**),输入 **@chat:** 就能把搜索范围直接缩小到这两类对话中;\n- **按来源精准搜**:明确只想找某一个来源时,直接输入它的专属快捷词(比如 **@codex:**),即可一步到位只搜 Codex。",
38
+ "media": "demos/shortcuts.gif",
39
+ "alt": "在设置中配置共享快捷词,再用共享词和具体来源词搜索会话。",
40
+ "en": {
41
+ "title": "Custom Shortcuts to Narrow Down Your Search Scope Instantly",
42
+ "description": "Tired of scrolling through a cluttered **@** menu full of files, folders, and different sources just to find a past conversation?\n\nYou can now assign **custom shortcuts** to different chat sources in Settings (multiple shortcuts can be separated by commas), allowing you to filter by category and narrow down your search scope right as you type:\n- **Search across a combined group**: Not sure where a conversation happened? Assign the same shortcut (e.g., **chat**) to both Local Agents and Web Chats, then type **@chat:** to narrow your search exclusively to those sources;\n- **Target a specific source**: When you know exactly where to look, use a dedicated shortcut like **@codex:** to filter exclusively for Codex sessions.",
43
+ "alt": "Configure shared shortcuts in settings, then search sessions using both shared and source-specific shortcuts."
44
+ }
45
+ },
46
+ {
47
+ "title": "不用死记路径,像逛文件夹一样找到目录并引用",
48
+ "description": "想引用某个深层文件夹,但记不住完整路径、也不想手打?\n\n现在 **@** 文件菜单支持直接层层浏览了:\n- **进入子目录**:选中文件夹后按 **Tab** 键;\n- **返回上一级**:点击菜单顶部的导航栏;\n- **确认引用**:找到目标文件夹后按 **Enter**,一键插入到当前对话中。",
49
+ "media": "demos/folders.gif",
50
+ "alt": "在文件菜单按 Tab 进入子目录,再返回并按 Enter 引用目录。",
51
+ "en": {
52
+ "title": "Browse Folders Directly in the @ Menu — No Need to Type Full Paths",
53
+ "description": "Want to reference a deeply nested folder without memorizing or typing out its full path?\n\nYou can now navigate folder hierarchies directly inside the **@** file menu:\n- **Open subfolder**: Select a folder and press **Tab** to step inside;\n- **Go back**: Use the breadcrumb navigation bar at the top of the menu;\n- **Insert reference**: Press **Enter** on your target folder to insert it directly into your chat.",
54
+ "alt": "Press Tab in the file menu to enter subdirectories, navigate back, and press Enter to reference a folder."
55
+ }
56
+ },
57
+ {
58
+ "title": "未来更新预告",
59
+ "description": "接下来我们还计划带来这些实用功能,敬请期待:\n\n1. **更省心的网页端对话同步**:后台静默同步网页聊天记录,不再需要额外安装和折腾 OpenCLI\n2. **更强大的会话搜索**:找历史记录更准、更快\n3. **更实用的 **@云盘** 权限支持**:打通更多云端文件引用场景\n4. **全新的 **@电脑窗口** 功能**:不用截图,直接让 AI 读取你当前打开的软件窗口\n\n---\n\n❤️ **写在最后**\n\n这个插件一直靠“用爱发电”持续维护。如果它对你有帮助,欢迎到 [GitHub](https://github.com/Chael-Chael/dsh-reference-anything) 点一颗 **Star ⭐** 支持!平时遇到任何问题或有新点子,随时欢迎提交 Issue 反馈;也特别欢迎有时间、有能力的朋友通过 PR 一起完善插件。感谢每一份支持!",
60
+ "en": {
61
+ "title": "What's Next",
62
+ "description": "Here is what we are planning for upcoming releases:\n\n1. **Zero-Config Web Chat Sync**: Silent background syncing for web conversations — no OpenCLI setup required\n2. **More Powerful Session Search**: Faster and more accurate history lookup\n3. **Enhanced **@CloudDrive** Permissions**: Broader and more practical cloud file referencing\n4. ****@Window** Context**: Reference active desktop application windows directly without taking screenshots\n\n---\n\n❤️ **Support the Project**\n\nThis plugin is a labor of love maintained in our spare time. If it saves you time and makes your workflow smoother, please consider giving us a **Star ⭐ on [GitHub](https://github.com/Chael-Chael/dsh-reference-anything)**! Feel free to open an Issue if you run into bugs or have feature ideas, and PRs are always welcome if you'd like to help build and improve the plugin together. Thank you for all your support!"
63
+ }
64
+ }
65
+ ]
@@ -0,0 +1,36 @@
1
+ # 新功能介绍卡片
2
+
3
+ 每个版本使用一个与 `package.json` 版本号完全一致的目录(不带 `v`):
4
+
5
+ ```text
6
+ release-notes/
7
+ 0.4.4/
8
+ features.json
9
+ files.png
10
+ commands.png
11
+ ```
12
+
13
+ `features.json` 是按展示顺序排列的卡片数组。每张卡片包含:
14
+
15
+ ```json
16
+ [
17
+ {
18
+ "title": "新功能标题",
19
+ "description": "介绍这个功能,以及用户如何使用它。",
20
+ "media": "demo.gif",
21
+ "alt": "动画中展示的操作"
22
+ }
23
+ ]
24
+ ```
25
+
26
+ 图片支持 PNG、JPEG、WebP 和 GIF;路径相对于该版本目录,不可指向目录外。介绍支持 Markdown 段落、列表和链接;链接在新窗口打开。标题和介绍必填;纯文字预告可以省略 media 和 alt,提供图片时必须填写 alt。将预告放在数组最后,即作为最后一页展示。
27
+
28
+ 执行 `npm run build` 后,配置和素材会内嵌到插件客户端,离线也可查看;修改内容后需要重新构建并重载 DSH。请压缩大 GIF,避免增加客户端加载时间。新增版本只需新增目录和内容,不需要修改卡片组件。
29
+
30
+ 卡片可增加 `en: { title, description, alt }` 保存英文原文,媒体共用。默认字段为中文;卡片跟随 DSH 语言设置即时切换,其他语言使用英文,旧版未配置英文的卡片保留原文。GIF 画面内的文字不会自动翻译。
31
+
32
+ 点击菜单项打开介绍后,用右下角“上一个/下一个”切换;关闭弹窗不会隐藏菜单项,只有点击菜单行的叉号才会屏蔽该版本。没有本地卡片配置的版本回退到原来的更新日志。未安装的新版本若尚未包含在本地插件中,也使用远端日志。
33
+
34
+ 每个已安装版本首次进入“引用万物(dsh-reference-anything)”插件的具体设置页面时,会自动展示一次本次更新介绍;仅打开设置窗口或其他设置页不会触发。展示记录单独保存在本地存储中,与菜单入口的叉号互不影响;检测到远端新版本不会触发,安装后版本变化才会再次展示。首次启用此机制时,当前版本也会展示一次。本地存储不可用时,只能保证本次运行内不重复展示。
35
+
36
+ 0.4.4 的初始卡片复用了仓库已有的文件、命令菜单示意图,可直接替换为实际新功能截图或 GIF。
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nwflower
4
+ Copyright (c) 2026 Scarlett
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Arjun Barrett
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.
@@ -0,0 +1,48 @@
1
+ # Bundled conversation scanners and readers
2
+
3
+ Derived from [dsh-chat-import](https://github.com/Nwflower/dsh-chat-import), npm
4
+ 0.26.1 (MIT). `upstream-sha256.json` records the exact version and source hashes.
5
+ Both generated bundles include fzstd (MIT); `LICENSE` and `LICENSE.fzstd` ship
6
+ with the package. Upstream paths in comments are not runtime dependencies.
7
+
8
+ `parsers.mjs` exposes preview-based text/image reading and default roots.
9
+ `scanners.mjs` reuses all upstream source descriptors and SQLite summary readers.
10
+ The scan entry provides filesystem-only access and runs in `scan-worker.mjs`,
11
+ without plugin registration or session mutations. The host caches metadata for
12
+ 30 seconds; missing paths are empty, while permission/database errors are warnings.
13
+ Import status is not inferred locally: Reference Anything asks the optional
14
+ Chat Import API separately. Import and summaries also remain API operations.
15
+
16
+ Local patches expose preview content, preserve Trae message parts, export the
17
+ upstream database-summary table, and replace a dynamic Trae scanner import with
18
+ a static named import so mutation code can be removed by tree shaking.
19
+ The generator rejects leaked mutation code and changed patch anchors.
20
+ Antigravity IDE typed tool results (directory/file reads, code actions,
21
+ subagents, commands and searches) are matched by tool name rather than discarded
22
+ as missing background output; GENERIC results keep their existing handling.
23
+ Async sidecar reports only supplement GENERIC results, never replace typed output.
24
+ Hermes SQLite and JSONL reads preserve tool-only assistant messages, OpenAI-style
25
+ function calls, and role=tool results. Results are associated by call ID, including
26
+ parallel calls; string arguments and result text remain unchanged.
27
+
28
+ ## Update from upstream
29
+
30
+ 1. Download/build the desired upstream version in a separate directory (or use
31
+ an installed npm package directory). Do not overwrite the running Desktop plugin.
32
+ 2. Run `npm run vendor:sync -- <built-dsh-chat-import-directory>` from this repository.
33
+ This regenerates both bundles and their shared version/hash manifest. Normal
34
+ builds never download upstream or inspect another installed plugin.
35
+ 3. Review source/version/license changes, then run `npm run agent:verify` and
36
+ test the Web profile with Chat Import disabled and enabled. The catalog test
37
+ detects new upstream formats that need settings/icon/type support here.
38
+ 4. Ship the verified snapshot in a new Reference Anything release. Users receive
39
+ upstream changes when updating Reference Anything, not automatically at runtime.
40
+
41
+ Parsing a reference may read its whole source before returning a page. Images
42
+ require recoverable bytes or a valid attachment; unavailable images are reported.
43
+
44
+ The structured read projection numbers body messages independently of tools,
45
+ links tool records and images to those numbers, and hashes normalized source
46
+ content before applying presentation budgets. The host adds original-file
47
+ fingerprints/version checks. This projection is used for automatic send-time
48
+ previews and numeric read/search/image calls; it retains no parsed-body cache.
@@ -0,0 +1,114 @@
1
+ import { parentPort } from 'node:worker_threads'
2
+ import { readFile, readdir, stat } from 'node:fs/promises'
3
+ import { join, resolve } from 'node:path'
4
+ import { homedir } from 'node:os'
5
+ import { readConversation } from './parsers.mjs'
6
+ const channel = parentPort || { on: (...args) => process.on(...args), postMessage: value => process.send(value) }
7
+ if (!parentPort) process.on('disconnect', () => process.exit(0))
8
+
9
+ // Parsing stays off the picker thread. Only states and file fingerprints cross back.
10
+ channel.on('message', async ({ id, target }) => {
11
+ const dependencies = new Map()
12
+ const inspect = async path => {
13
+ try {
14
+ const s = await stat(path)
15
+ dependencies.set(path, `${s.size}:${s.mtimeMs}:${s.ctimeMs}`)
16
+ return { type: s.isDirectory() ? 'directory' : 'file', size: s.size, mtimeMs: s.mtimeMs }
17
+ } catch (error) {
18
+ if (error.code !== 'ENOENT') throw error
19
+ dependencies.set(path, 'missing')
20
+ return undefined
21
+ }
22
+ }
23
+ const fs = {
24
+ resolve: async path => ({ displayPath: resolve(path) }),
25
+ processPath: value => value.displayPath,
26
+ stat: async value => inspect(value.displayPath),
27
+ readText: async value => {
28
+ const info = await inspect(value.displayPath)
29
+ // shortcut: large sources stay unknown; use streaming probes before raising this background budget.
30
+ if (info?.size > 8 * 1024 * 1024) throw new Error('Background validation budget exceeded')
31
+ const raw = await readFile(value.displayPath, 'utf8')
32
+ // A tolerant converter may skip broken lines; that must never prove emptiness.
33
+ if (/\.jsonl$/i.test(value.displayPath)) for (const line of raw.split(/\r?\n/)) if (line.trim()) JSON.parse(line)
34
+ return raw
35
+ },
36
+ listDir: async value => {
37
+ await inspect(value.displayPath)
38
+ return (await readdir(value.displayPath, { withFileTypes: true })).map(e => ({
39
+ name: e.name, type: e.isDirectory() ? 'directory' : 'file', target: { displayPath: join(value.displayPath, e.name) },
40
+ }))
41
+ },
42
+ }
43
+ let state = 'unknown'
44
+ try {
45
+ const info = await inspect(target.path)
46
+ if (!info || (info.type === 'file' && info.size === 0)) state = 'empty'
47
+ else if (target.format === 'claude' && /\.json$/i.test(target.path)) {
48
+ const meta = JSON.parse(await fs.readText({ displayPath: target.path }))
49
+ if (meta.cliSessionId && !meta.messages) {
50
+ // Match the exact CLI identity; never substitute another chat in the project.
51
+ const root = join(homedir(), '.claude', 'projects')
52
+ let found = false
53
+ const walk = async dir => {
54
+ await inspect(dir)
55
+ for (const e of await readdir(dir, { withFileTypes: true })) {
56
+ if (e.isDirectory()) await walk(join(dir, e.name))
57
+ else if (e.name === `${meta.cliSessionId}.jsonl`) found = true
58
+ }
59
+ }
60
+ if (await inspect(root)) await walk(root)
61
+ state = found ? 'unknown' : 'empty'
62
+ }
63
+ } else {
64
+ if (info.type === 'directory' && ['grokbuild', 'vibe', 'kimi'].includes(target.format)) {
65
+ const names = target.format === 'grokbuild' ? ['chat_history.jsonl']
66
+ : target.format === 'vibe' ? ['messages.jsonl'] : ['wire.jsonl', 'agents/main/wire.jsonl']
67
+ const bodies = await Promise.all(names.map(name => inspect(join(target.path, name))))
68
+ if (bodies.every(body => !body || body.size === 0)) {
69
+ channel.postMessage({ id, state: 'empty', dependencies: [...dependencies] })
70
+ return
71
+ }
72
+ }
73
+ if (/\.(?:db|vscdb)$/i.test(target.path)) {
74
+ await inspect(target.path + '-wal')
75
+ await inspect(target.path + '-shm')
76
+ const schemas = {
77
+ opencode: ['session', 'message'], mimocode: ['session', 'message'], kilocode: ['session', 'message'],
78
+ teleagent: ['session', 'message'], zcode: ['session', 'message'],
79
+ hermes: ['sessions', 'messages'], goose: ['sessions', 'messages'], crush: ['sessions', 'messages'],
80
+ }
81
+ let schema = schemas[target.format]
82
+ if (schema) {
83
+ const { DatabaseSync } = await import('node:sqlite')
84
+ const db = new DatabaseSync(target.path, { readOnly: true })
85
+ try {
86
+ const tables = new Set(db.prepare("SELECT name FROM sqlite_master WHERE type='table'").all().map(r => r.name))
87
+ if (schema[0] === 'session' && tables.has('session_v2')) schema = ['session_v2', 'session_message']
88
+ if (tables.has(schema[0]) && tables.has(schema[1])
89
+ && db.prepare(`SELECT 1 FROM ${schema[0]} WHERE id = ? LIMIT 1`).get(target.sessionId)
90
+ && !db.prepare(`SELECT 1 FROM ${schema[1]} WHERE session_id = ? LIMIT 1`).get(target.sessionId)) {
91
+ channel.postMessage({ id, state: 'empty', dependencies: [...dependencies] })
92
+ return
93
+ }
94
+ } finally { db.close() }
95
+ }
96
+ }
97
+ if (target.format === 'chatgpt') {
98
+ const exported = JSON.parse(await fs.readText({ displayPath: target.path }))
99
+ const chat = Array.isArray(exported) ? exported.find(c => c.id === target.sessionId) : null
100
+ if (chat?.mapping && Object.values(chat.mapping).every(node => node && !node.message)) {
101
+ channel.postMessage({ id, state: 'empty', dependencies: [...dependencies] })
102
+ return
103
+ }
104
+ }
105
+ state = await readConversation(fs, { ...target, limit: 1, detail: 'full', probe: true })
106
+ if (state === 'unknown' && ['pi', 'codex', 'openclaw', 'hermes', 'dsh', 'dsh4'].includes(target.format) && info.type === 'file' && !/\.(db|vscdb|zstd)$/i.test(target.path)) {
107
+ const records = (await fs.readText({ displayPath: target.path })).split(/\r?\n/).filter(line => line.trim()).map(line => JSON.parse(line))
108
+ const allowed = target.format === 'codex' ? ['session_meta'] : ['session', 'session_info', 'session/title']
109
+ if (records.length && records.every(r => allowed.includes(r.type))) state = 'empty'
110
+ }
111
+ }
112
+ } catch { state = 'unknown' }
113
+ channel.postMessage({ id, state, dependencies: [...dependencies] })
114
+ })
@@ -0,0 +1,6 @@
1
+ export function defaultRoots(): Record<string, string | string[] | null>
2
+ export function readConversation(fs: unknown, input: {
3
+ format: string; path: string; sessionId: string; limit: number;
4
+ before?: number; revision?: string; detail: 'summary' | 'full';
5
+ probe?: boolean; structured?: boolean;
6
+ }, signal?: AbortSignal): Promise<unknown>