@jidekaixin2dian/dsh-file-actions 0.1.12 → 0.1.14

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 CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.13 — 2026-10-24
4
+
5
+ - 渠道对齐:0.1.12 的 GitHub Release 资产早于安全修复(tag 停在 `6aa0b38`),而 npm 0.1.12 已包含修复;自 0.1.13 起两个渠道从同一提交构建。代码与 0.1.12(npm)一致,仅升版本号。
6
+ - 发布链:npm 改用 Trusted Publishing(OIDC,无 token、无 OTP),`npm publish --provenance` 附带 SLSA 来源证明。
7
+
3
8
  ## 0.1.12 — 2026-10-24
4
9
 
5
10
  - 「复制文件内容」作用于会话工作区之外的文件时先弹确认框,说明该文件不属于本对话;拒绝则不读取任何字节。工作区内的复制行为不变。缓解聊天文本被注入绝对路径后的诱导复制。
package/README.en.md CHANGED
@@ -58,6 +58,10 @@ The rows follow the file type:
58
58
  | Folders | open folder, reveal, copy path, copy relative path |
59
59
  | Web links | open link, copy link, copy link text, copy as Markdown |
60
60
 
61
+ The link menu:
62
+
63
+ ![Link menu](assets/preview-link.png)
64
+
61
65
  *Open with* keeps every registered application, ordered by preferred application, system default, editors, then other applications. A search box appears above seven entries.
62
66
 
63
67
  Click ☆ beside an application to prefer it for that file type; click ★ to clear it. Keyboard users can select an application and press `Shift+Enter`. Preferences stay in this browser and do not change OS associations. An unavailable preferred application falls back to an available editor.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [English](README.en.md)
4
4
 
5
- **0.1.11** 新增 npm 分发,保留 0.1.10 的文件探测反馈、首选应用、菜单稳定性和字号适配。安装包见 [npm](https://www.npmjs.com/package/@jidekaixin2dian/dsh-file-actions) 和 [Release](https://github.com/jidekaixin2dian/dsh-file-actions/releases/latest),修复记录见[变更记录](CHANGELOG.md)。
5
+ **0.1.13** 对齐 npm 与 GitHub Release 两个安装渠道(同源构建),npm 发布附带 provenance 来源证明;延续 0.1.12 的引用行号、复制动作与工作区外复制确认。安装包见 [npm](https://www.npmjs.com/package/@jidekaixin2dian/dsh-file-actions) 和 [Release](https://github.com/jidekaixin2dian/dsh-file-actions/releases/latest),修复记录见[变更记录](CHANGELOG.md)。
6
6
 
7
7
  右键文件和链接,直接打开、定位、复制或另存。
8
8
 
@@ -16,7 +16,7 @@
16
16
  dsh plugin --profile desktop add @jidekaixin2dian/dsh-file-actions --registry=https://registry.npmjs.org
17
17
  ```
18
18
 
19
- 装完重开 DSH 生效。指定官方 npm 源可以避开镜像同步延迟;安装固定版本时,在包名后加 `@0.1.12`。
19
+ 装完重开 DSH 生效。指定官方 npm 源可以避开镜像同步延迟;安装固定版本时,在包名后加 `@0.1.13`。
20
20
 
21
21
  也可继续通过 GitHub Release 安装:
22
22
 
@@ -58,6 +58,10 @@ npm pack @jidekaixin2dian/dsh-file-actions --registry=https://registry.npmjs.org
58
58
  | 文件夹 | 打开文件夹、在资源管理器中打开、复制路径、复制相对路径 |
59
59
  | 网页链接 | 打开链接、复制链接、复制链接文字、复制为 Markdown |
60
60
 
61
+ 网页链接的菜单:
62
+
63
+ ![链接菜单](assets/preview-link.png)
64
+
61
65
  「打开方式」完整保留系统关联应用,按首选、系统默认、编辑器、其他应用排序;超过 7 个会出现搜索框。
62
66
 
63
67
  点击应用旁的 ☆,将它设为该文件类型的首选;再次点击 ★ 取消。键盘选中应用后也可用 `Shift+Enter` 设置或取消。首选仅保存在当前浏览器中,不修改系统文件关联;若应用不再可用,自动回落到可用编辑器。
Binary file
package/lib/client.js CHANGED
@@ -94,7 +94,7 @@ const factory = () => {
94
94
  denied: '没有权限访问该文件',
95
95
  probeFailed: '无法确认文件,请检查连接或权限',
96
96
  retry: '重试',
97
- nativeHint: 'Shift+右键 使用原生菜单',
97
+ nativeHint: 'Shift+右键 先交给页面处理',
98
98
  kinds: {
99
99
  text: '文本',
100
100
  markdown: 'Markdown',
@@ -177,7 +177,7 @@ const factory = () => {
177
177
  denied: 'Permission to access this file was denied',
178
178
  probeFailed: 'Could not verify file; check connection or permissions',
179
179
  retry: 'Retry',
180
- nativeHint: 'Shift+right-click for the native menu',
180
+ nativeHint: 'Shift+right-click lets the page handle it first',
181
181
  kinds: {
182
182
  text: 'Text',
183
183
  markdown: 'Markdown',
@@ -534,7 +534,7 @@ const factory = () => {
534
534
  primary.push({
535
535
  id: 'open',
536
536
  label: isDir ? t.openFolder : t.open,
537
- icon: isDir ? 'folder' : 'open',
537
+ icon: isDir ? 'folder' : 'file',
538
538
  action: 'open',
539
539
  })
540
540
 
@@ -543,7 +543,7 @@ const factory = () => {
543
543
  primary.push({
544
544
  id: 'editor',
545
545
  label: editor ? t.openIn(editor.name) : input.appsState === 'loading' ? t.appsLoading : t.noPreferred,
546
- icon: 'editor',
546
+ icon: 'code',
547
547
  action: 'open',
548
548
  appId: editor?.id,
549
549
  disabled: !editor,
@@ -584,7 +584,7 @@ const factory = () => {
584
584
  navigate.push({
585
585
  id: 'reveal',
586
586
  label: isDir ? t.revealFolder : t.reveal,
587
- icon: 'reveal',
587
+ icon: 'folderOpen',
588
588
  action: 'reveal',
589
589
  })
590
590
  sections.push(navigate)
@@ -596,11 +596,11 @@ const factory = () => {
596
596
  transfer.push({ id: 'copyRelPath', label: t.copyRelPath, icon: 'copy', action: 'copyRelPath' })
597
597
  }
598
598
  if (!isDir) {
599
- transfer.push({ id: 'copyFileName', label: t.copyFileName, icon: 'copy', action: 'copyFileName' })
599
+ transfer.push({ id: 'copyFileName', label: t.copyFileName, icon: 'tag', action: 'copyFileName' })
600
600
  }
601
601
  // Copying the reference verbatim is only useful when it carries a location.
602
602
  if (!isDir && input.location && Number(input.location.line) && input.reference) {
603
- transfer.push({ id: 'copyReference', label: t.copyReference, icon: 'clipboard', action: 'copyReference' })
603
+ transfer.push({ id: 'copyReference', label: t.copyReference, icon: 'bookmark', action: 'copyReference' })
604
604
  }
605
605
  if (!isDir && file.canCopyText) {
606
606
  transfer.push({ id: 'copyContents', label: t.copyContents, icon: 'clipboard', action: 'copyContents' })
@@ -654,8 +654,8 @@ const factory = () => {
654
654
  pathLine = path === '' ? '/' : path
655
655
  } catch { /* keep the raw URL */ }
656
656
  const copy = [
657
- { id: 'copyLink', label: t.copyLink, icon: 'copy', action: 'copyLink' },
658
- { id: 'copyLinkText', label: t.copyLinkText, icon: 'clipboard', action: 'copyLinkText' },
657
+ { id: 'copyLink', label: t.copyLink, icon: 'link', action: 'copyLink' },
658
+ { id: 'copyLinkText', label: t.copyLinkText, icon: 'text', action: 'copyLinkText' },
659
659
  ]
660
660
  // `[text](url)` only exists when the link has visible text to label it.
661
661
  if (String(input.text || '').trim() !== '') {
@@ -671,7 +671,7 @@ const factory = () => {
671
671
  kind: 'link',
672
672
  outsideWorkspace: false,
673
673
  sections: [
674
- [{ id: 'openLink', label: t.openLink, icon: 'globe', action: 'openLink' }],
674
+ [{ id: 'openLink', label: t.openLink, icon: 'external', action: 'openLink' }],
675
675
  copy,
676
676
  ],
677
677
  }
@@ -680,27 +680,29 @@ const factory = () => {
680
680
  /* ─────────────────────────────── icons ─────────────────────────────── */
681
681
 
682
682
  const ICON_PATHS = {
683
- open: '<path d="M9.2 2.6H4.4a1 1 0 0 0-1 1v8.8a1 1 0 0 0 1 1h7.2a1 1 0 0 0 1-1V6.2z"/><path d="M9.2 2.6v3.6h3.4"/>',
684
- folder: '<path d="M2.5 5.5A1.5 1.5 0 0 1 4 4h3l1.4 1.5H12a1.5 1.5 0 0 1 1.5 1.5v4.5A1.5 1.5 0 0 1 12 13H4a1.5 1.5 0 0 1-1.5-1.5z"/>',
685
- editor: '<path d="M5.8 4.6 2.8 8l3 3.4"/><path d="M10.2 4.6 13.2 8l-3 3.4"/>',
686
- chevron: '<path d="M6.5 4.5 10 8l-3.5 3.5"/>',
687
- reveal: '<path d="M2.5 4.5h5l1.3 1.6H13a1 1 0 0 1 1 1v5.4a1 1 0 0 1-1 1H3.5a1 1 0 0 1-1-1z"/><path d="M6 10.4h4"/>',
688
- copy: '<rect x="5.5" y="5.5" width="7" height="8" rx="1.2"/><path d="M10.5 3.6V3a1 1 0 0 0-1-1H3.9a1 1 0 0 0-1 1v7.2a1 1 0 0 0 1 1h.6"/>',
689
- clipboard: '<rect x="4.5" y="3.5" width="7" height="10" rx="1.3"/><path d="M6.6 3.5V2.8h2.8v.7"/><path d="M6.4 7h3.2"/><path d="M6.4 9.4h3.2"/>',
690
- download: '<path d="M8 2.8v6.4"/><path d="M5.6 7.2 8 9.6l2.4-2.4"/><path d="M3.2 11.4v1.2a1 1 0 0 0 1 1h7.6a1 1 0 0 0 1-1v-1.2"/>',
691
- globe: '<circle cx="8" cy="8" r="5.4"/><path d="M2.8 8h10.4"/><path d="M8 2.6c1.6 1.6 2.4 3.4 2.4 5.4S9.6 11.8 8 13.4C6.4 11.8 5.6 10 5.6 8S6.4 4.2 8 2.6"/>',
692
- check: '<path d="M3.6 8.4 6.6 11.4 12.4 4.9"/>',
693
- link: '<path d="M6.6 9.4a2.6 2.6 0 0 0 3.7 0l1.9-1.9a2.6 2.6 0 0 0-3.7-3.7l-1 1"/><path d="M9.4 6.6a2.6 2.6 0 0 0-3.7 0L3.8 8.5a2.6 2.6 0 0 0 3.7 3.7l1-1"/>',
694
- // File-type glyphs for the header tile: shape carries the kind, the tile hue
695
- // only reinforces it.
696
- text: '<path d="M4 4.6h8"/><path d="M4 7.6h8"/><path d="M4 10.6h5"/>',
697
- markdown: '<path d="M2.8 10.6V5.4l2.1 2.5 2.1-2.5v5.2"/><path d="M11.1 5.6v3.4"/><path d="M9.6 7.6l1.5 1.5 1.5-1.5"/>',
698
- image: '<rect x="2.6" y="3.6" width="10.8" height="8.8" rx="1.4"/><circle cx="6" cy="6.6" r="1"/><path d="M3.6 11.2 6.9 8.3l1.9 1.7 1.8-1.4 1.9 2.1"/>',
699
- web: '<rect x="2.6" y="3.4" width="10.8" height="9.2" rx="1.4"/><path d="M2.6 6.2h10.8"/><circle cx="4.6" cy="4.8" r=".5" fill="currentColor" stroke="none"/><circle cx="6.2" cy="4.8" r=".5" fill="currentColor" stroke="none"/>',
700
- doc: '<path d="M9.2 2.6H4.4a1 1 0 0 0-1 1v8.8a1 1 0 0 0 1 1h7.2a1 1 0 0 0 1-1V6.2z"/><path d="M9.2 2.6v3.6h3.4"/>',
701
- office: '<rect x="3.4" y="2.8" width="9.2" height="10.4" rx="1.3"/><path d="M6 6h4"/><path d="M6 8.3h4"/><path d="M6 10.6h2.4"/>',
702
- archive: '<rect x="3" y="4.8" width="10" height="7.4" rx="1.2"/><path d="M3 7.5h10"/><path d="M6.6 4.8V3.4h2.8v1.4"/>',
703
- binary: '<rect x="3" y="3.4" width="10" height="9.2" rx="1.2"/><path d="M5.6 6.6h1.1v3.2"/><path d="M9.3 6.6h1.5l-1.5 3.2h1.5"/>',
683
+ file: '<path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z"/><path d="M14 3v5h5"/>',
684
+ folder: '<path d="M3 7a2 2 0 0 1 2-2h4l2 2.6h8a2 2 0 0 1 2 2V18a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>',
685
+ folderOpen: '<path d="M3 18V7a2 2 0 0 1 2-2h4l2 2.6h8a2 2 0 0 1 2 2V11"/><path d="M3 18.5 5.7 12a2 2 0 0 1 1.9-1.3H22l-2.7 7.6a2 2 0 0 1-1.9 1.3H4.8a1.8 1.8 0 0 1-1.8-1.1z"/>',
686
+ code: '<path d="m9 8-4 4 4 4"/><path d="m15 8 4 4-4 4"/>',
687
+ chevron: '<path d="m10 7 5 5-5 5"/>',
688
+ globe: '<circle cx="12" cy="12" r="9"/><path d="M3 12h18"/><path d="M12 3a14 14 0 0 1 0 18a14 14 0 0 1 0-18"/>',
689
+ external: '<path d="M14 4h6v6"/><path d="M20 4l-9 9"/><path d="M18 14v4a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4"/>',
690
+ copy: '<rect x="9" y="9" width="11" height="11" rx="2.4"/><path d="M6 15H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v1"/>',
691
+ clipboard: '<rect x="7" y="4.5" width="10" height="16" rx="2.2"/><path d="M10 4.5v-.7a.8.8 0 0 1 .8-.8h2.4a.8.8 0 0 1 .8.8v.7"/>',
692
+ download: '<path d="M12 4v10.5"/><path d="m7.6 11 4.4 4.4L16.4 11"/><path d="M4.8 19.4h14.4"/>',
693
+ link: '<path d="M10.4 13.6a4.3 4.3 0 0 0 6.1 0l2.3-2.3a4.3 4.3 0 0 0-6.1-6.1l-1.2 1.2"/><path d="M13.6 10.4a4.3 4.3 0 0 0-6.1 0l-2.3 2.3a4.3 4.3 0 0 0 6.1 6.1l1.2-1.2"/>',
694
+ text: '<path d="M4 6.5h16"/><path d="M4 12h10.5"/><path d="M4 17.5h13"/>',
695
+ markdown: '<path d="M3.5 17V7l4 5 4-5v10"/><path d="M16.5 7v10"/><path d="m13.8 14.2 2.7 2.8 2.7-2.8"/>',
696
+ image: '<rect x="3" y="4.5" width="18" height="15" rx="2.6"/><circle cx="8.6" cy="9.8" r="1.5"/><path d="m20.5 16-4.2-4.2a2 2 0 0 0-2.8 0L4.5 20"/>',
697
+ web: '<rect x="3" y="4.5" width="18" height="15" rx="2.6"/><path d="M3 9.4h18"/><circle cx="6.6" cy="6.9" r=".75" fill="currentColor" stroke="none"/><circle cx="9.3" cy="6.9" r=".75" fill="currentColor" stroke="none"/>',
698
+ doc: '<path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z"/><path d="M14 3v5h5"/><path d="M8.5 13h7"/><path d="M8.5 17h4.5"/>',
699
+ office: '<path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z"/><path d="M14 3v5h5"/><path d="M8.6 12.4h6.8"/><path d="M8.6 16.4h6.8"/><path d="M12 12.4v4"/>',
700
+ archive: '<rect x="3" y="4" width="18" height="4.6" rx="1.6"/><path d="M5 8.6V18a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8.6"/><path d="M10 12.6h4"/>',
701
+ binary: '<rect x="4" y="4" width="6.2" height="7" rx="2"/><rect x="13.8" y="13" width="6.2" height="7" rx="2"/><path d="M5.4 20.2h3.4"/><path d="M15.2 10.8h3.4"/><path d="M6.8 7.6h1.1v3"/><path d="M16.6 16.6h1.1v3"/>',
702
+ bookmark: '<path d="M7 4.6h10a1.6 1.6 0 0 1 1.6 1.6V21L12 16.8 5.4 21V6.2A1.6 1.6 0 0 1 7 4.6z"/>',
703
+ tag: '<path d="M11.6 3.6H5.4A1.8 1.8 0 0 0 3.6 5.4v6.2a2 2 0 0 0 .6 1.4l7.4 7.4a2 2 0 0 0 2.8 0l5.6-5.6a2 2 0 0 0 0-2.8L12.9 4.2a2 2 0 0 0-1.3-.6z"/><circle cx="8.2" cy="8.2" r="1.2"/>',
704
+ refresh: '<path d="M20 11.5a8 8 0 1 0-2.4 6.4"/><path d="M20 5.5v6h-6"/>',
705
+ check: '<path d="m5 12.6 4.6 4.6L19 7"/>',
704
706
  }
705
707
 
706
708
  /** The header tile glyph for one file kind. */
@@ -718,8 +720,8 @@ const factory = () => {
718
720
  }
719
721
 
720
722
  function iconSvg(name) {
721
- const body = ICON_PATHS[name] || ICON_PATHS.open
722
- return `<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round">${body}</svg>`
723
+ const body = ICON_PATHS[name] || ICON_PATHS.file
724
+ return `<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round">${body}</svg>`
723
725
  }
724
726
 
725
727
  /* ─────────────────────────────── styles ─────────────────────────────── */
@@ -762,11 +764,11 @@ const factory = () => {
762
764
  .dfa-thumb img{max-width:100%;max-height:118px;display:block;object-fit:contain;border-radius:6px}
763
765
  .dfa-head{display:flex;align-items:center;gap:9px;padding:6px 7px 8px;min-width:0;
764
766
  border-bottom:1px solid var(--dsw-alias-border-l2,rgba(127,127,127,.28));margin-bottom:3px}
765
- .dfa-tile{flex:none;width:28px;height:28px;border-radius:8px;display:grid;place-items:center;
767
+ .dfa-tile{flex:none;width:30px;height:30px;border-radius:9px;display:grid;place-items:center;
766
768
  color:var(--dfa-hue,#5b8cff);
767
- background:color-mix(in srgb,var(--dfa-hue,#5b8cff) 13%,transparent);
768
- box-shadow:inset 0 0 0 .5px color-mix(in srgb,var(--dfa-hue,#5b8cff) 30%,transparent)}
769
- .dfa-tile svg{width:16px;height:16px}
769
+ background:linear-gradient(150deg,color-mix(in srgb,var(--dfa-hue,#5b8cff) 24%,transparent),color-mix(in srgb,var(--dfa-hue,#5b8cff) 9%,transparent));
770
+ box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--dfa-hue,#5b8cff) 30%,transparent),0 1px 2px rgba(0,0,0,.08)}
771
+ .dfa-tile svg{width:17px;height:17px}
770
772
  .dfa-tile[data-kind="text"]{--dfa-hue:#5b8cff}
771
773
  .dfa-tile[data-kind="markdown"]{--dfa-hue:#7b8cff}
772
774
  .dfa-tile[data-kind="html"]{--dfa-hue:#e0714a}
@@ -1407,7 +1409,7 @@ const factory = () => {
1407
1409
  })
1408
1410
  const icon = makeNode('span', { class: 'dfa-ico' })
1409
1411
  if (item.iconData) icon.appendChild(makeNode('img', { src: item.iconData, alt: '' }))
1410
- else icon.innerHTML = iconSvg('open')
1412
+ else icon.innerHTML = iconSvg('file')
1411
1413
  row.appendChild(icon)
1412
1414
  row.appendChild(makeNode('span', { class: 'dfa-label', text: item.label }))
1413
1415
  if (item.checked || item.preferred) {
@@ -2126,9 +2128,8 @@ const factory = () => {
2126
2128
  }
2127
2129
  }
2128
2130
 
2129
- function onContextMenu(event) {
2130
- if (event.defaultPrevented) return
2131
- if (event.shiftKey) { closeMenu(); return }
2131
+ /** Take the click and open our menu, unless the pointer sits on our own menu. */
2132
+ function openFromEvent(event) {
2132
2133
  const target = event.target
2133
2134
  // A right-click on the menu itself must not open a second menu over it.
2134
2135
  if (target && target.closest && target.closest(`[${MENU_ATTR}]`)) {
@@ -2148,6 +2149,29 @@ const factory = () => {
2148
2149
  void openAt(candidate, event.clientX, event.clientY, false)
2149
2150
  }
2150
2151
 
2152
+ // The Electron shell ships no native context menu, so a Shift-click that only
2153
+ // stepped aside would be a dead end. Remember the event here, let the page and
2154
+ // any other plugin answer in the bubble phase, and fall back to our own menu
2155
+ // when nobody did.
2156
+ let shiftEvent = null
2157
+
2158
+ function onContextMenu(event) {
2159
+ if (event.defaultPrevented) return
2160
+ if (event.shiftKey) {
2161
+ shiftEvent = event
2162
+ closeMenu()
2163
+ return
2164
+ }
2165
+ openFromEvent(event)
2166
+ }
2167
+
2168
+ function onContextMenuFallback(event) {
2169
+ if (event !== shiftEvent) return
2170
+ shiftEvent = null
2171
+ if (event.defaultPrevented) return
2172
+ openFromEvent(event)
2173
+ }
2174
+
2151
2175
  function onKeyDown(event) {
2152
2176
  const wantsMenu = (event.key === 'F10' && event.shiftKey) || event.key === 'ContextMenu'
2153
2177
  if (!wantsMenu) return
@@ -2197,6 +2221,7 @@ const factory = () => {
2197
2221
  const install = () => {
2198
2222
  if (activeCleanup) activeCleanup()
2199
2223
  document.addEventListener('contextmenu', onContextMenu, true)
2224
+ window.addEventListener('contextmenu', onContextMenuFallback)
2200
2225
  document.addEventListener('pointerover', onWarm, true)
2201
2226
  document.addEventListener('focusin', onWarm, true)
2202
2227
  document.addEventListener('keydown', onKeyDown, true)
@@ -2210,6 +2235,7 @@ const factory = () => {
2210
2235
  disposed = true
2211
2236
  document.documentElement.removeAttribute('data-dfa-ready')
2212
2237
  document.removeEventListener('contextmenu', onContextMenu, true)
2238
+ window.removeEventListener('contextmenu', onContextMenuFallback)
2213
2239
  document.removeEventListener('pointerover', onWarm, true)
2214
2240
  document.removeEventListener('focusin', onWarm, true)
2215
2241
  probeCache.clear()
@@ -2256,6 +2282,8 @@ const factory = () => {
2256
2282
  // test harness evaluates it with a fake `window` and reads these directly.
2257
2283
  __internals: {
2258
2284
  messages,
2285
+ iconSvg,
2286
+ ICON_PATHS,
2259
2287
  isAbsolutePath,
2260
2288
  normalizeSlashes,
2261
2289
  basename,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jidekaixin2dian/dsh-file-actions",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "description": "File and link actions for DeepSeek Harness: open, choose applications, reveal, copy paths or contents, and save files from the chat.",
5
5
  "icon": "icon.svg",
6
6
  "type": "module",