dsh-park-notes
Manifest validdsh-park-notes · 稍后说 / Talk later
Park thoughts while the AI is working — without interrupting the conversation.
⚠️ Disclaimer / 免责声明
Plugins run third-party code on your machine. Review the source before installing — this project is a community plugin, not affiliated with DeepSeek. / 插件会在你的机器上执行第三方代码,安装前请自行审阅源码;本项目为社区插件,与 DeepSeek 官方无关联。
The problem / 要解决的问题
Scenario — 你在和 AI 对话的过程中,突然想到"这个也想和 AI 聊聊"。
- AI 正在输出,你的思路被带跑了——刚想到一条新的问题/话题/补充,想立刻说;
- 但如果直接发送:要么打断 AI 当前的生成(它本该一次说完那件事),要么把两件不相关的事揉进下一个回合,节奏全乱;
- 如果等一会儿再说:等它生成完,你的想法往往已经忘了,或者只记得"好像有个事要说"却想不起来是什么。
一句话:在"现在说会打断"和"晚点说会忘"之间,缺一个零成本的中间态。
What it solves / 它如何解决
稍后说 在输入框上方放了一条常驻便签条:想到什么,点开随手记一条(回车即可,不打断正在进行的对话),然后继续专注当前的事。等这轮聊完、你想聊那个话题了,一键把便签带进输入框草稿(只填草稿、不自动发送),确认后发送即可。
- 记的时候:零打断——便签在输入框旁,3 秒完成,AI 的生成不受影响;
- 存的时候:随会话走——每条便签挂在当前会话下,刷新、重启都不丢;
- 用的时候:一键带入——不再靠记忆,草稿里就是你要聊的内容;
- 用完即清:带入后自动从便签列表移除,不会重复携带。
While the agent is busy writing, you think of something worth raising later.
稍后说 gives you a tiny strip above the composer: jot the thought, forget
about it, and when the current exchange is over push the parked items straight
into your next draft (never sent automatically), then delete them with one
click.
Install / 安装
Requires the web profile (dsh web). / 需要 web 版 dsh(dsh web)。
# from a git checkout / 从 Git 仓库安装
dsh plugin --profile web add github:kevin-zx/dsh-park-notes
# or once published to npm / 或发布 npm 后:
dsh plugin --profile web add dsh-park-notes
Restart dsh web (or refresh the page after the live patch reload), and the
💡 稍后说 strip appears above the message composer in every session. /
重启 dsh web(或刷新页面),输入框上方即出现 💡 稍后说 条带。
Manual alternative — in $DSH_HOME/profiles/web/cordis.patch.yml / 手动方式:
- insert:
- id: park-notes
name: 'dsh-park-notes'
Use either the bundle install (dsh plugin add ...) or the manual
row — not both, or the row id collides. / 二选一,不能同时用,否则行 id 冲突。
Update / 更新
One command pulls the latest main commit — then restart dsh web. / 一条
命令拉取 main 最新提交,然后重启 dsh web。
dsh plugin --profile web update dsh-park-notes
# then: Ctrl+C in the dsh web terminal, and start it again
Restarting is required, not optional. A page refresh is not enough: the
running host keeps the browser bundles it read at startup, and after a pnpm
re-install the bundle lives at a new store path, so the client-HMR file watcher
(which still watches the previous path) never notices the change. Restarting
re-reads both halves. / 必须重启,刷新页面不够:运行中的进程持有启动时读取的
浏览器 bundle 快照,而 pnpm 重新安装后 bundle 位于新的存储路径,客户端 HMR
的文件监视仍指向旧路径,因此永远发现不了变化;重启会重新读取两半边。
Check what is installed / 查看当前版本:
- Settings → Plugins in the web UI lists
dsh-park-noteswith its version. / 网页界面 设置 → 插件 里能看到dsh-park-notes的版本号。 dsh web --dump-config | grep park-notesconfirms the row is mounted. / 该命令可确认挂载行存在。
Notes / 说明:
- Installed without a ref (
github:kevin-zx/dsh-park-notes) keeps trackingmain, so updates just work. Installing a pinned ref (...#v0.5.0) freezes the version — re-addthe unpinned spec to follow again. / 不加 ref 安装才会跟随main更新;装了固定 tag(...#v0.5.0) 就冻结在那个版本,需要重新用不带 ref 的形式 add 一次。 - If GitHub is unreachable, export a proxy first
(
$env:HTTPS_PROXY="http://127.0.0.1:1080"style) or install a tarball. / GitHub 不通时先设置代理环境变量,或改用 tarball 安装。 - Updating never touches your notes or images — they live in the browser (localStorage + IndexedDB), not in the package. / 更新不会影响便签与图片, 它们存在浏览器里,不在插件包里。
Usage / 用法
/note <text>— type it in the composer and press Enter: the text is parked as a pending note, the command runs directly against the agent (no model message is created) and its result row confirms it. Keyboard-only and fully non-interrupting. //note 内容— 在输入框直接敲,回车即记录;命令直接 对 agent 执行、不产生模型消息,结果行给出确认。纯键盘、零打断。Alt+N— reveal and focus the capture box without touching the mouse. /Alt+N— 打开并聚焦记录框,不用鼠标。- Collapsed:
💡 稍后说 (2)— always visible, shows the pending count. / 折叠:常驻条带,显示待聊数量。 - Expanded: pending notes (pinned first), an optional search box, the
quick-capture input, then a collapsed history. / 展开:待聊列表
(置顶优先)→ 搜索框(便签 ≥ 3 条时出现)→ 快捷记录框 → 折叠的「已带入」历史。
Enterrecords (IME-safe,Shift+Enternewline),Esccollapses. /Enter记录(支持中文输入法,Shift+Enter换行),Esc收起。- 带入 appends a note to the composer draft (not sent) and moves it to history; 删除 drops it; 全部带入输入框 does both at once. / 「带入」= 追加到输入框草稿(不发送)并移入历史;「删除」直接丢弃。
- Edit: click a note's text to edit in place (
Entersaves,Esccancels). / 二次编辑:点击条目文字就地编辑(Enter保存、Esc取消)。 - Pin: 📌 keeps a note on top of the pending list. / 置顶:📌 把条目固定在待聊列表最前。
- Images: paste, drop, or
+图片to attach images to a note; thumbnails show in the note, click one to enlarge, and the enlarged view can copy the image to the clipboard or save it to a file. / 图片:粘贴、拖入或点+图片给便签附上图片;缩略图显示在条目里,点击放大;放大后可复制到剪贴板 或保存到本地文件。 - Pushing a note that has images: the text goes into the draft and the
plugin first tries to hand the images to the composer itself (a synthetic
paste into the composer editor, verified against the composer's own image
list). When that is refused it copies the first image to the clipboard
instead (re-encoded to PNG, because the async clipboard only accepts PNG) —
press
Ctrl+Vto attach it. Dragging a thumbnail straight into the composer is the always-available manual route. / 带入含图便签:文字进 草稿,插件会先尝试自动把图片交给输入框(向编辑区派发一次合成粘贴,并用 输入框自己的图片列表校验是否成功);被拒绝时退回复制首图到剪贴板(会转成 PNG,因为异步剪贴板只接受 PNG)→ 按Ctrl+V即成附件。把缩略图直接拖进 输入框 始终可用的手动通道。 - Search: filter pending and history together (substring match). / 搜索:一个输入框同时过滤待聊与历史。
- Export: download every note of the session as Markdown
(
park-notes-YYYY-MM-DD.md). / 导出:把本会话全部便签导出为 Markdown 文件。 - History: pushed notes stay under a collapsed
已带入section, tagged已带入/已发送(a note flips to已发送once the draft carrying it is actually submitted), with 重新带入 / 删除 / 清空. / 历史:带入过的内容收进 折叠的「已带入」区,标注「已带入 / 已发送」(真正把草稿发出去后自动标记), 支持重新带入、删除、清空。
- Data lives in the browser
localStorageper session (keydsh-park-notes:v1:<sessionId>); server restarts don't affect it. Notes written by the pre-renamedsh-idea-notebuild migrate automatically. / 数据存浏览器 localStorage(按会话隔离),服务器重启不影响;旧版dsh-idea-note的便签自动迁移。
How it works / 原理
A DSH web plugin = one package with a host half and a browser half. / DSH 网页插件 = 一个包,含 host 半边和浏览器半边。
lib/index.js— host half: registers the/noteslash command through the hostcommandsservice; the command runs directly against the agent and never creates a model message.lib/client.js— browser half: awindow.__ModuleLoader__.load(...)bundle (same hand-written format as shippeddsh-client-ui-*packages, no build step). It declaresinject: ["slots", "locale"]— theinjectexport is the Cordis dependency declaration; without itapplyruns before theslotsservice exists and fails silently.- The browser half also projects the host command run: a state-only
conversation definition matches
command/runwithname === "note"and parks the text, deduplicated by command id so a replayed history cannot duplicate a note. package.json→dsh.clientis how client-modules discovers and serves the bundle over/plugins;dsh.bundle.patchis whatdsh plugin adduses to mount the row automatically.- UI registers in
conversation.input.dock(order 15), the same slot family as Todo / Goal / queue docks.
Two traps worth knowing / 两个值得注意的坑
- Wait for services with
ctx.inject([name], cb), notctx.get(name). A service provided by a later row (the command registry, the conversation UI) may not exist yet whenapplyruns; a plainctx.getguard then returns silently and the contribution never happens.ctx.injectsuspends the fiber until the service is available. - A client bundle must export
inject. Without that dependency declaration the browser half applies before theslotsservice exists and disappears without an error — the classic "works after hot reload, gone after a refresh" symptom.
Compatibility / 兼容性
Verified against the Harness plugin contracts as of dsh 0.2.1-alpha.2 (and running on a 0.1.7 profile). The surface this plugin depends on is deliberately small, and every piece of it is still current: / 已对照 dsh 0.2.1-alpha.2 的 插件契约核验(当前运行在 0.1.7 profile 上)。本插件依赖的接口刻意保持很小, 且每一项在新版仍然有效:
| Used here / 使用的接口 | Status in 0.2.x |
|---|---|
dsh.bundle.patch manifest + inserted row / 清单与插入行 | unchanged / 未变 |
Host export function apply(ctx) + export const inject | unchanged / 未变 |
ctx.commands.register({ name, description, input: { hint }, handler }) | unchanged (new fields definitionId, recordInput, input.attachments are optional) / 未变(新增字段均为可选) |
Client window.__ModuleLoader__.load({ id, factory }) + exports["./client"] | unchanged / 未变 |
Module-level inject: ["slots", "locale", "uiConversation"] (service names) | unchanged — official plugins declare the same way / 未变,官方插件同样用法 |
Slot conversation.input.dock | still rendered, and the official Goal plugin registers there too / 仍在,官方 Goal 插件也用 |
Standard props useInput, inputActions, sessionId, t | unchanged / 未变 |
ctx.uiConversation.events.register(definition) (command/run records) | unchanged / 未变 |
Display metadata locale/*.json meta.title/meta.description + ./icon | required by the new Plugin Manager/Settings inventory — provided since v0.6.0 / 新版清单要求,v0.6.0 起已提供 |
Known soft spot / 已知薄弱点: the automatic image hand-off dispatches a synthetic
paste into the composer's editor. That is not an official extension point (the
docs advise against cross-plugin DOM coupling), so a future composer rewrite can
disable it — the clipboard and drag routes remain as fallbacks. / 图片"自动进
附件"是向编辑区派发合成粘贴事件,属于非官方扩展点,未来输入框改版可能失效;
剪贴板与拖拽两条兜底通道不受影响。
Develop / edit / 开发
lib/client.js is plain JavaScript — edit it; a running dsh web picks the
change up via client HMR (or Ctrl+Shift+R). Syntax check: node --check lib/client.js.
/ lib/client.js 是纯 JS,直接编辑即可,开发热更新自动生效。
Requirements / limits / 限制
- Web profile only (browser UI). / 仅 web 界面。
- Notes are per-session, per-browser (localStorage); images live in the browser's IndexedDB under the same per-session ownership and are never uploaded. / 便签按会话、按浏览器隔离(localStorage);图片存在浏览器 IndexedDB,同样按会话 归属,不会上传到任何地方。
- Images cannot be injected into the composer as attachments by a third-party plugin; the panel hands them over through the clipboard instead. / 图片无法由 第三方插件直接注入输入框附件;面板改用剪贴板交接。
- Image storage is managed, not left to grow: the panel shows how much is stored and offers 清理历史图片; on every session load orphan images (no note references them) are deleted, and once the store passes an 80 MB budget the oldest images held only by archived notes are trimmed (text is kept). A single image above 12 MB is downscaled to 2560 px before it is stored. Pending notes are never trimmed. / 图片存储是被管理的:面板显示占用并可一键「清理历史 图片」;每次进入会话会删除孤儿图片(没有任何便签引用),总量超过 80MB 时自动 清理最旧的归档图片(文字保留);单张超过 12MB 会先缩到 2560px 再存。待聊 便签的图片永不自动清理。
- The Markdown export marks how many images a note has (blobs stay in the browser). / Markdown 导出会标注每条便签的图片数量(图片本体留在浏览器里)。
- Two browser tabs editing the same session's notes: last write wins. / 同会话双标签页编辑时以最后写入为准。
License
MIT
Comments
Loading…