Repository navigation
Releases: DedsecLemon/dsh-obsidian
Release list
v1.6.0 — 目录树右键菜单 / A tree context menu
v1.6.0 — 目录树右键菜单 / A tree context menu
中文
目录里右键任意一行(或悬停出现的 ⋯ 按钮),就能直接在那一行上操作;同一行再点一次关闭菜单。
菜单内容
| 分组 | 文件行 | 目录行 |
|---|---|---|
| 打开 | 打开、编辑(打开并直接进编辑模式) |
— |
| 引入对话 | 引用到对话(@提及) |
— |
| 复制 | 复制 [[名称]] |
— |
| 关联 / 外部 | 查看关联、在文件管理器中显示、在 Obsidian 中打开 |
在文件管理器中显示 |
| 写操作 | 重命名…、移到 .trash… |
新建笔记… |
菜单是刻意的短:把正文插入对话 和另外三种「复制路径」都删了 —— 实际用起来它们和 引用到对话 / 复制 [[名称]] 重复,留着只是占位置。
写操作刻意保守
移到 .trash从不硬删除:移进<库>/.trash/<时间戳>-<原名>,可以手动移回来。重命名只改名字,不重写别的笔记里的[[链接]]—— 改名后断链样式会精确指出哪些链接失效了。新建笔记建单个文件 + 最小 frontmatter。- 三者都:按库根校验路径、目标已存在一律拒绝、Windows 会改写(
甲.)或建不了(NUL)的名字也拒绝,失败时说清原因。
「在文件管理器中显示」修好了两次
- 先修「完全没反应」:spawn 失败也回 200,现在只有真启动成功才报成功,失败会明确报错并提示「宿主还是旧版」。
- 再修「开了但看不见」:
explorer /select作为子进程启动会继承隐藏显示状态 —— 窗口建了、文件选中了、IsWindowVisible是 false。现在 Windows 上走已在运行的外壳(COM):窗口可见、文件选中、并提到前台。 - 最后修「开两次」:一次点击被执行两遍(菜单在 mousedown 关闭、重渲染后又投递一次 click)。客户端加 800ms 幂等窗(只对会产生可见副作用的动作),宿主再加 1200ms 同路径去重兜底。
English
Right-click any row in the tree — or the ⋯ button that appears on hover — and act on that row directly; a second click on the same row closes the menu.
What is in it
| Group | Note row | Folder row |
|---|---|---|
| open | 打开, 编辑 (opens already editing) |
— |
| hand off | 引用到对话(@提及) |
— |
| copy | 复制 [[名称]] |
— |
| links / elsewhere | 查看关联, 在文件管理器中显示, 在 Obsidian 中打开 |
在文件管理器中显示 |
| writes | 重命名…, 移到 .trash… |
新建笔记… |
Deliberately short: "paste the body into the conversation" and three of the four copy spellings were removed — in use they duplicated 引用到对话 and 复制 [[名称]], and a longer menu is a worse menu.
Writes stay conservative. .trash is a move into <vault>/.trash/<timestamp>-<name>, never a delete. Rename does not rewrite other notes' [[links]]; the broken-link styling then says exactly which links now miss. Create writes one file with a minimal frontmatter. All three validate against the vault root, refuse an existing target, refuse a name Windows would rewrite (甲.) or cannot create (NUL), and name the failure instead of swallowing it.
"Reveal in the file manager" took three fixes
- Fixing "nothing happens": a failed spawn still answered 200. Now only a real launch reports success, and a stale host is named as such.
- Fixing "it opened but was invisible":
explorer /selectas a spawned child inherits the caller's hidden show-state — the window existed, the item was selected, andIsWindowVisiblewas false. On Windows the route now asks the running shell through COM: the window comes out visible, selects the item, and is raised. - Fixing "it opens twice": one click ran the action twice, because the menu closes on
mousedownand a re-render delivers the click again. A per-action 800 ms guard (only for actions whose duplicate is visible) plus a 1200 ms same-path dedupe on the host.
Tests: host-check 139 assertions against the real vault (including the four write routes on files it creates and removes), mount-check 27 steps, render-check for the menu/dialog composition, plus the manifest, platform and lifecycle contracts.
v1.5.2 — 等号串就是高亮标记;客户端会自报版本
v1.5.2 — 等号串就是高亮标记;客户端会自报版本
反馈是「没有看到字体有变色」。查下来 <mark> 一直是有生成的,问题出在标记的写法:
本库把横幅写成 五个等号:
===== 一、核心功能模式 =====
严格按 == 解析时,取的是开头那串等号的最后两个,于是渲染成:
===<mark> 一、核心功能模式 </mark>===
底色其实是有的,但一行里还留着 === —— 看起来就"没变"。同理毛选里那句是六个等号。
改了什么
- 标记改成 两侧各 2 个以上等号,并且整串吃掉:
==x==、===== x =====、======x=======都渲染成一个干净的<mark> - 两条防线保留:标记内容里不许有
=(所以====这种裸等号串不会变成高亮)与不许有反引号(孤立的比较符a == b不会跟后面的==配对、把代码段吞进去) - 客户端现在会自报版本:
GET /dsh-obsidian/diag里多了build字段。这次排查正卡在"页面到底跑的是不是我刚装的包",以后这问题一次请求就能回答
一个意外的发现
排查时发现 diag 已经报 build: "1.5.2" —— 也就是正在跑的页面早就拿到了新包(client-plugin 的 HMR 接收器会自动重载客户端改动)。所以"没变色"不是版本没到,是标记写法与预期不一致。
可验证
render-check新增:五等号、六等号横幅都渲染成一个 mark、多余等号不残留、裸等号串不误判- 仓库与本机副本 render / mount(25) 全绿
说明:这是背景高亮,不是字体变色
Obsidian 的 == 渲染成 <mark>,视觉上是琥珀色底纹(40% 透明),文字颜色不变。如果你想要的是文字本身变色,那是另一种样式,说一声我改成强调色文字。
English
v1.5.2 — the <mark> was being produced all along; the problem was how this vault writes its markers. Its banners are ===== 一、核心功能模式 ===== (five equals) and one banner in 毛选 uses six. A strict == rule took the last two equals of the opening run as its marker and left === on both sides — the tint was there, but the line still began with equals, which reads as "nothing changed".
Markers are now a run of two or more equals on each side, stripped whole, so ==x==, ===== x ===== and ======x======= all render as one clean <mark>. The two guards stay: the body may contain neither = (a bare run is not a highlight) nor a backtick (a lone a == b cannot swallow a code span). The client half also reports CLIENT_BUILD through /dsh-obsidian/diag — the first question this report raised was "is the page running the installed bundle", and the answer was yes (the client-plugin HMR receiver had already picked the change up).
Note: Obsidian's == is a background highlight (a 40% amber tint), not a font-colour change. If coloured text is what you expected, say so and it becomes one line.
v1.5.1 — `==高亮==` 按 Obsidian 的样子渲染
v1.5.1 — ==高亮== 按 Obsidian 的样子渲染
==高亮== 之前是原样显示两个等号的。现在渲染成 Obsidian 的 <mark>(同为 40% 琥珀底色 --text-highlight-bg),正文、表格单元格、callout 标题里都生效 —— 凡是读内联 markdown 的地方都一致。
两条边界是关键的
[^=]—— 挡住====这种等号串(以及空高亮)被误判[^\]—— 挡住**孤立的比较符**a == b与**后面**的==` 配对,把中间的代码段一起吞进高亮
第二条是真被探针抓出来的:第一版把
看 a == b 与 `==代码==` 再来 ==真高亮==
渲染成了 a <mark> b 与 \代码==。修好之后是 a == b 与 ==代码== 再来 真高亮`。
高亮内容允许空格:本库里两种写法都有 ——「==句子==」(毛选里那句整理说明)与「== 一、核心功能模式 ==」(方案文档里当小标题用)。
可验证
render-check新增:标记渲染、等号不泄漏、单个==保持原样、表格单元格里的高亮、以及**「代码段在高亮之前」那个曾经出错的顺序**- 本库实测 14 处
==…==(13 处在方案文档当小标题用,1 处是真正的句子强调) - 仓库 render / mount(25) / host(110) / manifest(24) 全绿
升级提醒
只改了客户端半 → 刷新页面即可,不需要重启。
English
v1.5.1 renders ==highlight== as Obsidian's <mark> with the same 40% amber --text-highlight-bg, everywhere inline markdown is read — prose, table cells, callout titles. Two bounds do the work: [^=] stops a ==== run (or an empty mark) matching, and [^`] stops a lone comparison marker (a == b) from pairing with a later == and swallowing the code span between them — a first attempt rendered a == b 与 \==代码==`asa b 与 `代码==. Spaces are allowed inside because this vault writes both ==句子==and== 标题 ==. Pinned by render-check (the mark, markers never leaking, a lone ==` staying literal, a table cell, and the code-span-before-highlight order that used to break). Client-only: refresh, no restart.
v1.5.0 — 属性、局部关系图谱与链接状态
v1.5.0 — 属性、局部关系图谱、链接状态
三件事之前都缺,而且缺的原因相同:面板只看得见眼前这一篇笔记。
属性(frontmatter)—— 显示,而不是丢弃
// Drop YAML frontmatter: it is metadata, not prose. —— 这句话对一份文档成立,对一个侧栏阅读器不成立。这篇笔记是什么(type、status、parent)、怎么归档(tags),恰恰是最该先看到的。
现在笔记页顶部有一个可折叠的属性卡,按文件里的顺序列出:列表变 chips、布尔打勾、日期与数字照原样、值是 [[链接]] 的仍然可点。渲染器与属性卡共用同一个 parseProperties,两边对「正文从哪开始」不可能有分歧。
关系图谱 —— 只做局部(反向链接 + 本文引用)
笔记页底部是这篇笔记的边:
- 引用本文:哪些笔记链到这里,并显示那一行原文
- 本文引用:这篇链接到谁,坏目标标出来
点任意一行,目标笔记打开成它自己的一页 —— 顺着链接走不会丢掉正在读的那篇。
全库关系图谱是刻意不做的:窄侧栏里一张发丝球图提供不了信息,这个功能在早期设计时就被否掉过。读者真正需要的是脚下这条边。
数据来自一条新路线 GET /dsh-obsidian/links:走一遍库,返回每篇笔记的标题、摘录、标签,以及它的 [[链接]] 落到哪里。本库实测 714 篇 / ~1080 条链接 / ~0.5 秒 / ~290 KB,缓存 15 秒(?refresh=1 重建,面板上的 刷新 就是它)。它和搜索一样有界 —— 文件数/字节/深度上限 + truncated 标记,因为建索引等于把整个库读一遍。
链接状态 —— 断链看得出来,悬停有预览
- 指向不存在笔记的
[[链接]:变淡 + 虚线 + 悬停说明「笔记不存在:X」—— 否则一张密集的目录通篇一个颜色,断了一半也看不出来 - 悬停正常链接:浮出一张卡,显示目标标题 + 目标开头一句;目标不存在时明确说出来,而不是给一张空卡
可验证
render-check新增:属性种类与正文剥离、属性卡渲染、断链样式、悬停卡、以及backlinksOf/outlinksOf/linkStatus/previewOf的派生逻辑mount-check新增一步:挂载一篇笔记,断言属性卡、1:2的边计数、断链样式,以及点反向链接会打开那篇笔记host-check对真实知识库断言索引:覆盖 714 篇、链接能解析到已索引的笔记、[[笔记.md]]也能解析、同页锚点不会被当成外链、刷新能重建- 仓库 render / mount / host(110) / manifest(24) / platform(30) / lifecycle(10) 全绿
升级提醒
宿主半改了,这次必须重启 DSH(只刷新页面不行 —— 没有 /links 路线,属性卡与关联面板会是空的/不出现)。
English
v1.5.0 adds the three things the panel was missing because it only ever looked at the note in front of it.
Properties: frontmatter was dropped as "metadata, not prose". In a sidebar reader it is the first thing you want — what the note is and how it is filed. The note page renders it as a collapsible card in file order (lists as chips, booleans ticked, dates and numbers as themselves, [[links]] clickable), and the renderer reads the same parseProperties, so card and body cannot disagree.
The graph, locally: GET /dsh-obsidian/links walks the vault once and returns every note's title, excerpt, tags and where its [[links]] land — this vault: 714 notes, ~1080 links, ~0.5 s, ~290 KB, cached 15 s. The page shows 引用本文 (who links here, with the line) and 本文引用 (what this links to, broken targets marked); every row opens its note as its own page. A whole-vault graph stays rejected on purpose: a narrow sidebar cannot show it usefully.
Link states: an unresolved link is muted with a dashed underline and says so on hover; any link's hover shows a card with the target's title and first line, and a missing target says that instead of showing an empty card.
Pinned by new render-check assertions (property kinds, the card, broken-link style, hover card, and the backlink/outlink/preview derivations), a new mount-check step (properties card, 1:2 edges, broken style, clicking a backlink opens that note), and host-check assertions against the real vault (coverage, resolution, .md targets, anchors not leaking as edges, refresh). Restart DSH — the host half changed.
v1.4.0 — 跨笔记锚点落到标题与块
v1.4.0 — 跨笔记的 [[笔记#标题]] 会落到标题上,#^块id 也会
以前 [[笔记#标题]] 只打开笔记、把锚点丢掉;[[笔记#^块id]] 根本没有落点。原因很具体:渲染器只把笔记名交给导航器,而页面上没有任何元素带块 id。
改了什么
- 锚点跟着点击一起走,由
pendingAnchors按库内路径转交:目标是另一个标签页实例,没画完就无从滚动,所以由接收页在渲染完成后取走 matchHeading统一匹配规则:Obsidian 的标题原文优先 → GitHub 式 slug → 唯一包含匹配(本库沙盘笔记就是[[笔记#整合性]]指5.1 整合性 (Integration));命中多个则拒绝,不去猜^块id:段落或列表项末尾的^id渲染成data-block-id,不作为文字显示;同页[[#^id]]与跨页[[笔记#^id]]都能落到块上- 找不到时明确提示「找不到标题 / 找不到块」,而不是没反应
可验证
- 对真实知识库:8 个真实跨笔记链接里 6 个现在能落到标题上;其余 2 个指向的文本在目标笔记里不是标题(内容问题,不是渲染器问题 —— 一个该指
七、团体箱庭标准指导语与规则(增强版),另一个"四不"原则是列表项,适合用块引用) render-check新增 10 项断言:锚点随笔记链接传递、段落与列表项的data-block-id、标记不泄漏、四条匹配规则(含歧义拒绝)
English
v1.4.0 makes [[note#heading]] land on the heading and [[note#^block-id]] land on the block. The anchor now travels with the click and is handed over in pendingAnchors keyed by vault path, because the opened note is a different tab instance that cannot scroll before it has drawn. matchHeading owns the rules — Obsidian's exact heading text, then a GitHub-style slug, then a unique containment match, which is how this vault's sandplay notes are written ([[笔记#整合性]] for 5.1 整合性 (Integration)); an ambiguous anchor is refused rather than guessed. A trailing ^id on a paragraph or list item becomes data-block-id and never appears as text, so block links work same-note and cross-note. Against the real vault, 6 of the 8 real cross-note links resolve to a heading; the other two name text that is not a heading in their target note — a content issue, not a renderer one. render-check pins the anchor travelling with the link, the block ids on paragraphs and list items, the marker never leaking, and the four matching rules including the ambiguity refusal.
v1.3.1 — 目录章节可跳(同笔记锚点)+ 长笔记不再被截断
v1.3.1 — 目录里的章节真的能跳了
用户报的是「我点目录里的章节不能跳转过去」。查下去发现两层问题叠在一起,只修一层会被误判成"改坏了"。
第一层:链接形式
合订本目录写的是 Obsidian 的同笔记标题链接 —— 45 个 [[#第 N 节 …\|N. 短标题]](表格里别名管道转义成 \|)。面板把所有 [[…]] 一律送进 /resolve-link 当笔记名解析,于是每个章节都是死按钮;同一类的 [x](#锚点) 被渲染成 target="_blank" 的 <a>,点了开空白页。
第二层:标题根本不在页面上
宿主 MAX_NOTE_BYTES = 512 KB 只读了 2.42 MB 文件的约 21%(≈2,400 行,到第 6 节),客户端 MAX_RENDER_LINES = 3,000 再切一刀 → 45 个目标里 39 个从未被画出来。解析修好了也跳不过去。
改了什么
[[#标题]]/[[#标题|别名]]/[x](#锚点)就地滚动,先剥掉\|的转义反斜杠;[[笔记#标题]]只取笔记名去打开(以前把标题当笔记名,库里 9 处全废)- 跳转读的是已渲染标题的文本与
id,不把笔记再解析一遍(与大纲同一套纪律);先按 Obsidian 的标题文本精确匹配,再退回 GitHub 式 slug - 上限:宿主 512 KB → 4 MB,客户端 3,000 → 40,000 行
- 依据是实测而非手感:整篇 11,738 行 / 2.42 MB → 解析 48 ms + 渲染 84 ms、2.33 MB HTML、8,509 个元素
可验证
- 把 45 个目录格子逐个「点击」 → 45/45 命中已渲染标题(整篇 892 个标题)
render-check新增 12 项:三种锚点写法、转义管道、外链仍是链接、无导航器时降级为虚线 span、slug、4,000 行笔记能画到最后一个小标题host-check新增:超过旧 512 KB 的笔记整篇读取(truncated:false、1,184,494 字符)- 仓库 render / mount / host(104) / manifest(24) / platform(30) 全绿
升级提醒
宿主半的改动需要重启 DSH 才装载,只刷新页面不够 —— 否则笔记仍按旧 512 KB 读,第 7 节以后照旧「找不到标题」。
English
v1.3.1 makes same-note heading links jump. The compiled guide's table of contents is 45 cells of [[#第 N 节 …\|N. 短标题]] — an alias pipe escaped so the table parser keeps the row — and every one was sent to the note resolver as if the heading were a note name, so all 45 were dead buttons; [x](#锚点) links opened a blank tab. They now scroll in place: the jump reads the rendered headings' text and ids instead of parsing the note again, tries Obsidian's exact heading text first and a GitHub-style slug as the fallback, and says so when a heading really is absent.
It also would not have worked past chapter 6. The host read cap (512 KB) and the render cap (3,000 lines) meant 39 of the 45 targets had never been drawn. Both now sit above this note — 4 MB read, 40,000 lines — which the measurements support: the whole 11,738-line guide parses in 48 ms, renders in 84 ms, and becomes 2.3 MB of HTML / 8,509 elements. Verified by clicking all 45 entries in the real note (45/45 resolve to a rendered heading), plus new render-check assertions (three anchor spellings, the escaped pipe, external links staying links, the no-navigator fallback, the slug, and a 4,000-line note reaching its last heading) and a host-check assertion that a note over the old 512 KB cap is read whole. Restart DSH for the host half.
v1.3.0 — Obsidian callout / details 折叠
v1.3.0 — Obsidian 的 callout 按 Obsidian 的方式折叠
合订本《高性价比人生指南》用可折叠 callout 存来源:全文 768 处 > [!cite]- 来源(点开展开)。面板自带一个逐行渲染器(client.js 的 renderMarkdown),它只认 > 引用块,于是标记原样显示、几百个 DOI 直接铺在正文里 —— 折叠只存在于 Obsidian,面板里等于没折。
改了什么
- 三种折叠状态,与 Obsidian 一致:
-默认折叠、+展开但可折、无标记展开且不可折 - 点击标题行折叠/展开(
<button aria-expanded>+ ▸ 旋转),按类型取 Obsidian 的竖线色与 10% 底色;cite是自定义类型,用中性石板色 - 折叠的正文仍挂在 DOM 里(只
display:none):展开不需要重新取数,大纲(读[data-outline])也不会因折叠变形 - 顺带支持原生
<details>/<summary>—— 同一篇笔记末尾的 41 条术语表就是这种,里面的表格照常渲染 - callout /
<details>的正文各自带独立锚点前缀,不与整篇标题撞号
可验证
render-check新增 20 项断言:三种折叠状态、标题、正文仍是 markdown、标记不泄漏、<details>里的表格、非 callout 的引用块仍保持 2px 竖线- 对真实笔记端到端:按面板当时的上限取前 3,000 行 → 202/202 个来源块折叠、标题在位、DOI 保留在 DOM
- README 中英各加一节;CI 全绿
English
v1.3.0 renders Obsidian callouts the way the reading view does. The compiled guide ends all 767 of its items with a folded > [!cite]- 来源(点开展开) source block, and treating every > as a quote put the marker on screen and hundreds of DOIs into the prose. - starts folded, + starts open but foldable, and a bare [!type] is open and not foldable — Obsidian's three states. The header is a real <button aria-expanded> with a rotating caret; the body stays mounted and is hidden with CSS, so opening one needs no refetch and the outline never changes shape when a block folds. Raw <details>/<summary> — the same note's 41-term glossary — renders as the same control, table and all. render-check pins the three states, the title, the markdown inside the body, the table inside <details>, and that a block which is not a callout keeps the quote typography (2px rule, 24px indent).
v1.2.0 — 三平台 Obsidian 查找 + 系统声明
v1.2.0 — Obsidian 在 macOS / Linux 上也能被找到,系统声明补齐
之前 package.json 里没法诚实写 os: [win32, darwin, linux]:Obsidian 的可执行文件只在 Windows 路径里找,知识库注册表只读 %APPDATA%,obsidian:// 回退也总是 cmd.exe —— 在 macOS/Linux 上只能用 DSH_OBSIDIAN_APP 手动指路。现在三平台都通了。
按平台查找(DSH_OBSIDIAN_APP 永远排第一)
| 平台 | 候选路径 |
|---|---|
| Windows | %LOCALAPPDATA%\Obsidian、%LOCALAPPDATA%\Programs\Obsidian、Program Files、Program Files (x86) |
| macOS | /Applications/Obsidian.app/Contents/MacOS/Obsidian、~/Applications/... |
| Linux | ~/.local/bin 与 ~/Applications 的 AppImage、/usr/bin、/usr/local/bin、/snap/bin、系统与用户级 flatpak |
知识库注册表也按平台读取:%APPDATA% / ~/Library/Application Support / $XDG_CONFIG_HOME(默认 ~/.config)。打开笔记的回退处理器按平台选择:start / open / xdg-open。
路径拼接跟随目标平台的分隔符而不是宿主 —— 这正是能让三份清单在同一台机器上被断言的原因。
可验证
test/platform-check.mjs(新增,22 项断言,已进 CI):三个平台的候选清单与注册表路径,含退化情形(空环境、没有 home)。test/manifest-check.mjs扩到 24 项:os必须声明且只能是审核认识的系统。index.mjs导出__internals供断言,与客户端半的exports.__internals一致。- CI run #9 全绿(新增 “Platform paths” 步骤)。
一点如实的说明
目前只在 Windows 上实跑过。macOS/Linux 的清单是被断言过的,还没有对着那两个系统上真实的 Obsidian 运行过 —— README 里就是这么写的,没有假装碰过没碰过的硬件。
English
v1.2.0 makes Obsidian discovery cross-platform, which is what lets the manifest declare
os: [win32, darwin, linux] honestly. candidateApps / configPath are now per-platform
pure functions of (platform, env, home) — /Applications and ~/Applications on macOS,
AppImage//usr/bin//usr/local/bin/snap/flatpak on Linux, the usual installs on Windows,
with DSH_OBSIDIAN_APP first everywhere — and path joining follows the target platform, so
test/platform-check.mjs (22 checks, in CI) asserts all three lists from any machine. The
obsidian:// fallback picks start / open / xdg-open. manifest-check now pins the
declared systems (24 checks). Run on Windows so far; the macOS/Linux lists are asserted, not
yet exercised against a real Obsidian, and the README says so.
v1.1.1 — 兼容性声明 + 一次性 Profile 生命周期证据
v1.1.1 — 兼容性声明与一次性 Profile 生命周期证据
这是对 DSH STORE 自动检查(AI-Scarlett/DSH-Store#1276)的回应。检查给出的两类原因我们已经修掉;剩下的权限信号按策略保留,如实说明。
修掉的两项「未声明」
按检查器实际读取的字段声明(inferredCompatibility):
"engines": { "node": ">=22.12.0" },
"dsh": {
"compatibility": {
"dsh": "^0.2.0-rc.2",
"dshReleases": { "0.1.7-rc.2": "unknown", "0.2.0-rc.1": "unknown", "0.2.0-rc.2": "compatible" },
"dshOperations": { "0.2.0-rc.2": { "install": "passed", "start": "passed", "uninstall": "passed", "rollback": "unknown" } },
"node": ">=22.12.0",
"profiles": ["web"]
}
}只有 0.2.0-rc.2 标为 compatible —— 因为只有它被真正跑过;其余是 unknown,这就是这个字段的含义。
证据(是跑出来的,不是写上去的)
test/profile-lifecycle.mjs:把npm pack的产物装进一个一次性 profile,对装好的副本跑两侧 harness(宿主半跑全部 HTTP 路由,客户端半走真实模块加载器),再卸载并检查 profile 无残留。本地 11/11;CI 用--skip-host跑 10/10(被跳过的那步需要真实知识库)。test/manifest-check.mjs:22 项断言把上面这些声明以及审核在意的卫生条件(身份、files、无生命周期脚本、无运行时依赖、bundle 行、两半的包名)钉住,防止哪天悄悄消失。- 详见 docs/LIFECYCLE.md。
如实的权限说明
README 中英双语各新增一节「它碰了什么」:files/network/commands/credentials 逐条按真实情况写明(含 credentials 是误报 —— 扫描器把任何 process.env 读取都算作凭据信号,而本插件读的是 APPDATA/LOCALAPPDATA/ProgramFiles/DSH_HOME 这类环境路径),外部服务、以及每个缺失服务对应的失败边界。
因为确实用到 files/network,只给「无能力」插件自动放行的商城会让本包保持 user-reviewed —— 这是诚实的结果:另一种做法是做一个读不了笔记的笔记浏览器。
English
v1.1.1 answers the marketplace's automatic review (#1276): engines.node and
dsh.compatibility.{dsh,node,profiles,dshReleases,dshOperations} are now declared in the
manifest, with only the release actually exercised (0.2.0-rc.2) marked compatible.
The evidence is executable — test/profile-lifecycle.mjs packs, installs into a throwaway
profile, exercises both halves as installed, then uninstalls and checks for residue
(11/11 locally, 10/10 in CI), and test/manifest-check.mjs (22 checks) pins every
declaration plus the hygiene the review gates on. The README's new "What it touches"
section states files/network/commands/credentials honestly, including that the
credentials signal is a false positive from process.env path lookups. Because
files/network are genuinely used, the package stays user-reviewed rather than
auto-approved.
v1.1.0 — 大纲 + 对话开在中间 + 实测修复
v1.1.0 — 大纲、对话开在中间、以及一批实测修复
对应提交 d19ea28 及其之前两条。相对 v1.0.0 的变化:
新增
- 笔记大纲:笔记页标题栏的
大纲在窗格右缘浮出标题清单,点击直接跳转;滚动时高亮当前标题;层级用缩进表示;进编辑模式自动收起。列表是从已渲染的 DOM 读回来的(renderMarkdown给每个标题写id+data-outline),不做二次解析 —— 所以它永远等于屏幕上那一页,笔记超长被截断时也不会列出没渲染出来的标题。 - 对话改为在中间区域打开:
对话把知识库那个 Session 交给应用(uiWorkspace.openSession),中间区域用 shell 自己的对话面板显示 —— 整宽、原生输入框/历史/工具轨迹/停止按钮。右侧栏一个像素不占,目录树和笔记可以同时看。插件因此删掉了整套自定义对话 UI(约 -640 行),现在不声明任何子 slot。 - 继续上次,还是新开一个:有历史时
对话会先问(继续上次对话/新开一个对话),第一次使用则直接创建。 - 选好文件夹就注册工作区:确认知识库文件夹的那一刻就建 Workspace,不用等到第一次点对话。
- 侧栏状态不再跟着会话切换消失:切 Session 后目录树/笔记页会被放回去,展开状态、选中项、搜索词、已取回的层级都保留。
- 目录字体调大:目录树 12.5px→14px(行高 24→28、缩进 11→13),大纲 12→13.5px,搜索结果与标题、搜索框一并调大。
修复
- 编辑态与阅读态一致:编辑器从「13px 等宽 + 自己的内边距」改成与阅读视图相同的 16px/1.5、
18px 22px 96px、font-family: inherit—— 按编辑不再重排页面。 - CI 从未真正跑过:
ci.yml里- name: Mount harness (real jsdom mount: tree, ...)是含:的裸标量,整个 workflow 文件解析失败,GitHub 每次都是「0 job、秒失败」。加引号后 CI 开始真正执行。
安装
git clone https://github.com/DedsecLemon/dsh-obsidian.git D:/skill/dsh-obsidian// ~/.dsh/profiles/<profile>/package.json
"dsh-obsidian-panel": "link:D:/skill/dsh-obsidian"
"bundles": ["dsh-obsidian-panel"]包名是 dsh-obsidian-panel,而且没有发布到 npm(npm 上的 dsh-obsidian 属于另一位作者的
DSH + Obsidian 插件)—— 从本仓库 clone 后按 INSTALL.md 用 link:<路径> 安装即可。
插件运行期身份不变:路由 /dsh-obsidian/*、slot 键 dsh-obsidian/*、界面名 知识库。
English
v1.1.0 adds a note outline, moves the conversation into the app's own centre
panel (uiWorkspace.openSession — zero right-Sidebar space, and the plugin now declares
no slot children at all), asks "continue or start over" when there is history, creates
the vault Workspace as soon as the folder is chosen, restores the sidebar (and its
browse state) after a Session switch, matches the editor to the reading view, and
enlarges the tree/outline type. It also fixes the CI workflow, which had never actually
run. The package is named dsh-obsidian-panel and is not published to npm (npm's
dsh-obsidian is another author's plugin) — install it from this repository; runtime
identity — routes, slot keys, UI label — is unchanged.