dsh-approval-consult 1.1.3 → 1.1.4

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/README.en.md CHANGED
@@ -53,7 +53,7 @@ notes or reject blindly. This plugin adds a consultation panel on top of the app
53
53
 
54
54
  Requires DSH Web `0.2.1-rc.2` (tested) and Node `>=20`.
55
55
 
56
- Current version **v1.1.3**, published to npm ([`dsh-approval-consult`](https://www.npmjs.com/package/dsh-approval-consult)) and as a [GitHub release](https://github.com/0tests/dsh-approval-consult/releases/tag/v1.1.3).
56
+ Current version **v1.1.4**, published to npm ([`dsh-approval-consult`](https://www.npmjs.com/package/dsh-approval-consult)) and as a [GitHub release](https://github.com/0tests/dsh-approval-consult/releases/tag/v1.1.4).
57
57
 
58
58
  ```bash
59
59
  npm install dsh-approval-consult
@@ -61,7 +61,7 @@ npm install dsh-approval-consult
61
61
 
62
62
  Or install the release tarball:
63
63
 
64
- 1. Download `dsh-approval-consult-1.1.3.tgz` from
64
+ 1. Download `dsh-approval-consult-1.1.4.tgz` from
65
65
  [Releases](https://github.com/0tests/dsh-approval-consult/releases/latest).
66
66
  2. Open DSH Web → **Plugins** → **Add plugin** → **Install third-party plugin** and point it at the
67
67
  tarball's absolute path (or the download URL directly).
package/README.md CHANGED
@@ -37,7 +37,7 @@ Auto 审查(`@deepseek-ai/dsh-experimental-auto-review`)会在工具执行
37
37
 
38
38
  ## 安装
39
39
 
40
- > 当前版本 **v1.1.3**,已发布到 npm([`dsh-approval-consult`](https://www.npmjs.com/package/dsh-approval-consult))和 [GitHub Release](https://github.com/0tests/dsh-approval-consult/releases/tag/v1.1.3)。
40
+ > 当前版本 **v1.1.4**,已发布到 npm([`dsh-approval-consult`](https://www.npmjs.com/package/dsh-approval-consult))和 [GitHub Release](https://github.com/0tests/dsh-approval-consult/releases/tag/v1.1.4)。
41
41
  > `npm install dsh-approval-consult`,或让 Agent 用 `plugin_manager` 安装这个包名;下面也保留了 tarball / 本地目录两种方式。
42
42
 
43
43
  ### 方式 A:npm
@@ -49,10 +49,10 @@ Auto 审查(`@deepseek-ai/dsh-experimental-auto-review`)会在工具执行
49
49
  ### 方式 B:从 Release 安装(tarball)
50
50
 
51
51
  1. 在 [Releases](https://github.com/0tests/dsh-approval-consult/releases/latest) 下载
52
- `dsh-approval-consult-1.1.3.tgz`;
52
+ `dsh-approval-consult-1.1.4.tgz`;
53
53
  2. 打开 DSH Web → 左侧「插件」→「添加插件」→「安装第三方插件」,填这个 tarball 的绝对路径,
54
54
  或直接填下载链接
55
- `https://github.com/0tests/dsh-approval-consult/releases/download/v1.1.3/dsh-approval-consult-1.1.3.tgz`;
55
+ `https://github.com/0tests/dsh-approval-consult/releases/download/v1.1.4/dsh-approval-consult-1.1.4.tgz`;
56
56
  3. 安装完成后点「立即启用」,重启一次 `dsh web` 更稳。
57
57
 
58
58
  ### 方式 C:本地目录(源码 / 开发)
package/lib/impl.js CHANGED
@@ -1833,7 +1833,8 @@ export function apply(ctx, config, runtime) {
1833
1833
  const key = typeof input?.consultKey === 'string' ? input.consultKey : ''
1834
1834
  if (key.length > 0) {
1835
1835
  const direct = state.pendings.get(key)
1836
- if (direct !== undefined) return direct
1836
+ // 命中缓存也要同步状态:重建记录可能在别处已经被允许/拒绝(安全复查 2026-11-04)。
1837
+ if (direct !== undefined) return refreshReconstructed(direct)
1837
1838
  }
1838
1839
  const sessionId = input?.sessionId === undefined || input.sessionId === null ? '' : String(input.sessionId)
1839
1840
  if (sessionId.length === 0) return null
@@ -1842,56 +1843,56 @@ export function apply(ctx, config, runtime) {
1842
1843
  const keys = state.pendingBySession.get(sessionId)
1843
1844
  if (!Array.isArray(keys) || keys.length === 0) {
1844
1845
  const rebuilt = reconstructPending(sessionId, callId.length > 0 ? callId : undefined, toolName.length > 0 ? toolName : undefined)
1845
- if (rebuilt !== null) refreshReconstructed(rebuilt)
1846
- return rebuilt
1846
+ return rebuilt === null ? null : refreshReconstructed(rebuilt)
1847
1847
  }
1848
1848
  for (let index = keys.length - 1; index >= 0; index -= 1) {
1849
1849
  const record = state.pendings.get(keys[index])
1850
1850
  if (record === undefined || record.resolvedAt !== null) continue
1851
1851
  if (callId.length > 0) {
1852
- if (record.callId === callId) return record
1852
+ if (record.callId === callId) return refreshReconstructed(record)
1853
1853
  continue
1854
1854
  }
1855
1855
  if (toolName.length > 0) {
1856
- if (record.toolName === toolName) return record
1856
+ if (record.toolName === toolName) return refreshReconstructed(record)
1857
1857
  continue
1858
1858
  }
1859
- return record
1859
+ return refreshReconstructed(record)
1860
1860
  }
1861
1861
  for (let index = keys.length - 1; index >= 0; index -= 1) {
1862
1862
  const record = state.pendings.get(keys[index])
1863
1863
  if (record === undefined) continue
1864
1864
  if (callId.length > 0 && record.callId !== callId) continue
1865
1865
  if (callId.length === 0 && toolName.length > 0 && record.toolName !== toolName) continue
1866
- return record
1866
+ return refreshReconstructed(record)
1867
1867
  }
1868
1868
  // 记录可能因插件热重载/重启丢失:从会话日志里的 approval/asked(尚无 approval/decided)重建。
1869
1869
  const rebuilt = reconstructPending(sessionId, callId.length > 0 ? callId : undefined, toolName.length > 0 ? toolName : undefined)
1870
- if (rebuilt !== null) refreshReconstructed(rebuilt)
1871
- return rebuilt
1870
+ return rebuilt === null ? null : refreshReconstructed(rebuilt)
1872
1871
  }
1873
1872
 
1874
1873
  /**
1875
1874
  * 重建出来的记录没有连接到 approval/request 的 next(),需要自己看日志确认是否已经有结果,
1876
- * 否则用户一旦在别处决定,面板会一直停在“等待审批”。
1875
+ * 否则用户一旦在别处决定,面板会一直停在“等待审批”(安全复查 2026-11-04)。
1876
+ * 命中结果时统一走 finalizePending,确保中止侧调用、失效图片引用等清理一致。
1877
1877
  */
1878
1878
  function refreshReconstructed(record) {
1879
- if (record.reconstructed !== true || record.resolvedAt !== null) return
1880
- if (record.approvalId === undefined) return
1879
+ if (record === null || record === undefined) return record
1880
+ if (record.reconstructed !== true || record.resolvedAt !== null) return record
1881
+ if (record.approvalId === undefined) return record
1881
1882
  try {
1882
1883
  const agent = liveAgentBySessionId(record.sessionId)
1883
- if (agent === null || typeof agent.session?.snapshotEvents !== 'function') return
1884
+ if (agent === null || typeof agent.session?.snapshotEvents !== 'function') return record
1884
1885
  const events = agent.session.snapshotEvents()
1885
1886
  for (const event of events) {
1886
1887
  if (event?.type !== 'approval/decided') continue
1887
1888
  if (event.data?.id === undefined || String(event.data.id) !== record.approvalId) continue
1888
- record.resolvedAt = Date.now()
1889
- record.outcome = typeof event.data?.outcome === 'string' ? event.data.outcome : null
1890
- return
1889
+ finalizePending(record, typeof event.data?.outcome === 'string' ? event.data.outcome : null, null)
1890
+ break
1891
1891
  }
1892
- } catch {
1893
- /* ignore */
1892
+ } catch (error) {
1893
+ noteError('refresh-reconstructed', error)
1894
1894
  }
1895
+ return record
1895
1896
  }
1896
1897
 
1897
1898
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-approval-consult",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Approval consultation panel for DeepSeek Harness: while a tool call waits for approval, ask the executor AI and the auto-review AI independently, in two isolated channels with prompt-cache reuse.",