@240xu/dsh-message-ops 0.2.3 → 0.2.5
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.md +7 -0
- package/package.json +2 -2
- package/src/client.js +28 -7
package/README.md
CHANGED
|
@@ -44,6 +44,13 @@ dsh plugin --profile web add file:C:/path/to/dsh-message-ops
|
|
|
44
44
|
| GET | `/api/message-ops/export?sessionId=<id>&seq=<可选>` | 导出 Markdown(seq ≤ 上界,缺省全部),附件下载 |
|
|
45
45
|
| POST | `/api/message-ops/restore` | `{sessionId, seq}` 回滚恢复:seq 为某次 revert/delete 标记事件的 seq |
|
|
46
46
|
|
|
47
|
+
## 0.2.4 UI GAP(ux-scout dsh-ui-spec G-M1)
|
|
48
|
+
|
|
49
|
+
- **S6 违规修复**:回滚/删除成功后不再 900ms 裸 `location.reload()`——改为
|
|
50
|
+
devkit 标准 toast(`window.__dshDevkit.toast` 探测,无 devkit 时降级为对话框
|
|
51
|
+
内完成文案)+ done 态新增「刷新页面」按钮由用户手动刷新;与 branch 路径
|
|
52
|
+
(refreshList 不刷新页面)行为拉齐。
|
|
53
|
+
|
|
47
54
|
## 0.2.3 格式兼容(compat-audit + 用户实测紧急修复)
|
|
48
55
|
|
|
49
56
|
- **P0 旧单帧 `session.jsonl.zstd` 读取必崩**:`readSessionFile` 旧实现把帧 0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@240xu/dsh-message-ops",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "Roll back, branch, and export any DSH conversation — from the UI or straight from the agent via a message_ops tool. Non-destructive: logs stay append-only and recoverable. 消息回滚/删除/分支/导出四合一,内置 message_ops agent 工具;非破坏语义,日志只追加可恢复。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -46,6 +46,6 @@
|
|
|
46
46
|
"test": "node --test \"test/*.test.js\""
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"@deepseek-ai/dsh-tools": "^0.1.0-rc.6"
|
|
49
|
+
"@deepseek-ai/dsh-tools": "^0.1.0-rc.6 || ^0.2.0-rc.1"
|
|
50
50
|
}
|
|
51
51
|
}
|
package/src/client.js
CHANGED
|
@@ -54,8 +54,9 @@ window.__ModuleLoader__.load({
|
|
|
54
54
|
'busy.delete': '删除中…',
|
|
55
55
|
'busy.branch': '分支中…',
|
|
56
56
|
'done.branch': '分支完成:新会话 {id}(列表刷新后可见)',
|
|
57
|
-
'done.revert': '
|
|
58
|
-
'done.delete': '
|
|
57
|
+
'done.revert': '回滚完成,刷新页面后生效',
|
|
58
|
+
'done.delete': '删除完成,刷新页面后生效',
|
|
59
|
+
'action.reload': '刷新页面',
|
|
59
60
|
'errorPrefix': '操作失败:',
|
|
60
61
|
'menu.ops': '消息操作',
|
|
61
62
|
}
|
|
@@ -88,8 +89,9 @@ window.__ModuleLoader__.load({
|
|
|
88
89
|
'busy.delete': 'Deleting…',
|
|
89
90
|
'busy.branch': 'Branching…',
|
|
90
91
|
'done.branch': 'Branched: new session {id} (visible after list refresh)',
|
|
91
|
-
'done.revert': 'Reverted;
|
|
92
|
-
'done.delete': 'Deleted;
|
|
92
|
+
'done.revert': 'Reverted; reload to apply',
|
|
93
|
+
'done.delete': 'Deleted; reload to apply',
|
|
94
|
+
'action.reload': 'Reload page',
|
|
93
95
|
'errorPrefix': 'Operation failed: ',
|
|
94
96
|
'menu.ops': 'Message ops',
|
|
95
97
|
}
|
|
@@ -286,14 +288,28 @@ window.__ModuleLoader__.load({
|
|
|
286
288
|
setDoneMsg(t('done.branch', { id: data.newId || '' }))
|
|
287
289
|
setBusyMsg('')
|
|
288
290
|
setState('done')
|
|
289
|
-
|
|
290
|
-
|
|
291
|
+
// ISessions.refresh() 是宿主现行 API;refreshList 是旧名兜底。
|
|
292
|
+
if (__sessionsSvc) {
|
|
293
|
+
try {
|
|
294
|
+
const r = typeof __sessionsSvc.refresh === 'function'
|
|
295
|
+
? __sessionsSvc.refresh()
|
|
296
|
+
: (typeof __sessionsSvc.refreshList === 'function' ? __sessionsSvc.refreshList() : null)
|
|
297
|
+
if (r != null) Promise.resolve(r).catch(() => {})
|
|
298
|
+
} catch { /* ignore */ }
|
|
291
299
|
}
|
|
292
300
|
} else {
|
|
301
|
+
// S6 修复(G-M1):不再 900ms 裸 location.reload。成功走 devkit
|
|
302
|
+
// 标准 toast(无 devkit 时降级为对话框内 doneMsg),并提供手动
|
|
303
|
+
// 「刷新页面」按钮;与 branch 路径的 refreshList 不刷新行为拉齐。
|
|
293
304
|
setDoneMsg(t(mode === 'revert' ? 'done.revert' : 'done.delete'))
|
|
294
305
|
setBusyMsg('')
|
|
295
306
|
setState('done')
|
|
296
|
-
|
|
307
|
+
try {
|
|
308
|
+
const dk = window.__dshDevkit
|
|
309
|
+
if (dk && typeof dk.toast === 'function') {
|
|
310
|
+
dk.toast(t(mode === 'revert' ? 'done.revert' : 'done.delete'), { kind: 'ok' })
|
|
311
|
+
}
|
|
312
|
+
} catch { /* toast 缺席不阻断成功反馈 */ }
|
|
297
313
|
}
|
|
298
314
|
})
|
|
299
315
|
.catch((reason) => {
|
|
@@ -398,6 +414,11 @@ window.__ModuleLoader__.load({
|
|
|
398
414
|
...(!canRun ? { opacity: 0.5, cursor: 'default' } : {}),
|
|
399
415
|
},
|
|
400
416
|
}, confirmLabel),
|
|
417
|
+
...(state === 'done' && (mode === 'revert' || mode === 'delete') ? [React.createElement('button', {
|
|
418
|
+
key: 'reload', type: 'button',
|
|
419
|
+
onClick: () => { try { window.location.reload() } catch { /* non-browser guard */ } },
|
|
420
|
+
style: primaryBtnStyle,
|
|
421
|
+
}, t('action.reload'))] : []),
|
|
401
422
|
],
|
|
402
423
|
}, [
|
|
403
424
|
React.createElement('div', { key: 'meta', style: metaStyle },
|