@takboo/dsh-session-bin 0.1.0 → 0.2.0
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 +10 -10
- package/dist/client-model.js +61 -2
- package/dist/client.js +223 -137
- package/dist/client.js.map +1 -1
- package/dist/host/native-retirement-metadata.d.ts +7 -0
- package/dist/index.js +92 -5
- package/dist/index.js.map +2 -2
- package/dist/types/client/locales.d.ts +11 -4
- package/dist/types/client/model.d.ts +15 -1
- package/docs/client-interface.md +4 -4
- package/docs/host-lifecycle.md +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,19 +6,19 @@
|
|
|
6
6
|
|
|
7
7
|
## 功能
|
|
8
8
|
|
|
9
|
-
-
|
|
9
|
+
- 默认按工作区分组;按会话名称及工作区元数据搜索、筛选。
|
|
10
10
|
- 单项或批量取消归档,让会话回到原生会话列表。
|
|
11
11
|
- 单项永久删除、固定选择的批量永久删除,以及清空点击时的全部归档。
|
|
12
|
-
-
|
|
12
|
+
- 简洁的删除确认,可在设置中全局关闭;批量操作显示进度和日志,完成后保留简短统计及失败项。中断或断线后可查询结果并明确继续。
|
|
13
13
|
- 中英文界面,使用宿主控件、浅色和深色主题。
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
当前版本为 `0.2.0`,包名为 `@takboo/dsh-session-bin`。GitHub Release 提供预编译 tarball;npm 通过 trusted publishing 自动发布同一份产物,dsh-market 收录另行提交。核心功能已完成跨平台验收;运行证据见 [Host 验证](docs/verification/host-lifecycle.md#跨平台生产删除资格晋级验证)和[客户端验证](docs/verification/client-interface.md#跨平台生产删除客户端验证)。
|
|
16
16
|
|
|
17
17
|
## 界面预览
|
|
18
18
|
|
|
19
|
-

|
|
20
20
|
|
|
21
|
-
[深色界面](docs/images/archives-dark.png) · [批量永久删除确认](docs/images/batch-deletion.png)。截图来自 `0.
|
|
21
|
+
[深色界面](docs/images/archives-dark.png) · [批量永久删除确认](docs/images/batch-deletion.png)。截图来自 `0.2.0` 的真实安装验收,使用隔离测试会话。
|
|
22
22
|
|
|
23
23
|
## 兼容性
|
|
24
24
|
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
```sh
|
|
40
40
|
mise exec -- pnpm exec npm pack --ignore-scripts
|
|
41
|
-
dsh plugin --profile web add ./takboo-dsh-session-bin-0.
|
|
41
|
+
dsh plugin --profile web add ./takboo-dsh-session-bin-0.2.0.tgz
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
以上命令使用已安装的 DSH `0.2.0-rc.2`,将完整插件 bundle 安装到 `web` profile;该路径已通过真实 CLI/GUI 验证。启动或重新启动该 profile 后,从侧栏打开“会话回收站”(Session Bin)。tarball 包含预编译 Host 和 Client,使用者安装时无需编译 TypeScript。
|
|
@@ -49,7 +49,7 @@ dsh plugin --profile web add ./takboo-dsh-session-bin-0.1.0.tgz
|
|
|
49
49
|
dsh plugin --profile web remove @takboo/dsh-session-bin
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
也可下载 [v0.
|
|
52
|
+
也可下载 [v0.2.0 Release](https://github.com/takboo/dsh-session-bin/releases/tag/v0.2.0) 中的 `dsh-session-bin.tgz`,通过同一个 `dsh plugin --profile web add` 命令安装。也可从 npm 安装:`dsh plugin --profile web add @takboo/dsh-session-bin@0.2.0`。
|
|
53
53
|
|
|
54
54
|
如安装过早期未加 scope 的开发包,先从同一 profile 卸载 `dsh-session-bin`,再安装 scoped 包,避免重复注册;原生归档和已有操作记录保留。分发契约见[发布文档](docs/release.md)。
|
|
55
55
|
|
|
@@ -63,12 +63,12 @@ dsh plugin --profile web remove @takboo/dsh-session-bin
|
|
|
63
63
|
|
|
64
64
|
1. 使用 Harness 原生“归档会话”操作归档目标会话。
|
|
65
65
|
2. 打开“会话回收站”,搜索或筛选已有归档;选择单项或多项取消归档。
|
|
66
|
-
3.
|
|
67
|
-
4.
|
|
66
|
+
3. 永久删除时,核对确认窗口中的对象和阻止原因,再确认执行。设置中的“永久删除会话前进行确认”默认开启;关闭后,点击单项删除、删除所选或清空将直接开始永久删除。
|
|
67
|
+
4. 批量操作期间查看进度和日志,完成后只保留统计及需要处理的项。如出现部分失败或连接中断,先检查操作状态,再决定是否继续。
|
|
68
68
|
|
|
69
69
|
**“清空全部归档”包含点击时的全部归档,搜索和工作区筛选不会缩小其范围。** 批量删除固定开始时的对象,后来新增的归档不会加入。
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
永久删除不可撤销,仅允许已归档、无活动且无未释放读写引用的冷会话;删除准备会释放由 API Session 激活且确认空闲的目标 Agent,再复核冷会话条件;活动任务、其他所有者的 Agent 和未释放的读写引用仍会阻止删除。清除范围是目标会话日志及已声明的会话元数据、索引;共享附件、外部副本和独立 fork 会保留。插件不提供共享附件垃圾回收或安全擦除保证,也不支持自动定期清空、跨设备同步或多 Host 协调。可通过 Host 配置 `permanentDeletion: false` 关闭永久删除,配置说明见 [Host 生命周期](docs/host-lifecycle.md)。
|
|
72
72
|
|
|
73
73
|
## 开发入门
|
|
74
74
|
|
package/dist/client-model.js
CHANGED
|
@@ -637,10 +637,11 @@ function frozenPurgeKey(plan) {
|
|
|
637
637
|
]);
|
|
638
638
|
}
|
|
639
639
|
var SessionBinClientModel = class {
|
|
640
|
-
constructor(api, createStream, cache) {
|
|
640
|
+
constructor(api, createStream, cache, preferences) {
|
|
641
641
|
this.api = api;
|
|
642
642
|
this.createStream = createStream;
|
|
643
643
|
this.cache = cache;
|
|
644
|
+
this.preferences = preferences;
|
|
644
645
|
try {
|
|
645
646
|
this.state = { ...this.state, pending: pendingPlans(cache?.load()) };
|
|
646
647
|
} catch {
|
|
@@ -696,7 +697,12 @@ var SessionBinClientModel = class {
|
|
|
696
697
|
}
|
|
697
698
|
const purgeCacheBlocked = Boolean(cache?.isPurgeCacheBlocked?.()) || purgeCacheOverflow(rawPurgePlans, rawPurgeGrants, rawPurgeObservations, rawPurgeBatchOperations);
|
|
698
699
|
this.state = { ...this.state, purgeCacheBlocked };
|
|
700
|
+
try {
|
|
701
|
+
this.state.confirmDeletion = preferences?.load() !== false;
|
|
702
|
+
} catch {
|
|
703
|
+
}
|
|
699
704
|
this.snapshot = structuredClone(this.state);
|
|
705
|
+
this.stopPreferences = preferences?.subscribe?.((confirmDeletion) => this.publish({ confirmDeletion }));
|
|
700
706
|
}
|
|
701
707
|
state = {
|
|
702
708
|
phase: "loading",
|
|
@@ -711,7 +717,8 @@ var SessionBinClientModel = class {
|
|
|
711
717
|
purgeResults: [],
|
|
712
718
|
purgeBatch: null,
|
|
713
719
|
purgeBatchOperationIds: [],
|
|
714
|
-
purgeCacheBlocked: false
|
|
720
|
+
purgeCacheBlocked: false,
|
|
721
|
+
confirmDeletion: true
|
|
715
722
|
};
|
|
716
723
|
snapshot = structuredClone(this.state);
|
|
717
724
|
listeners = /* @__PURE__ */ new Set();
|
|
@@ -733,6 +740,14 @@ var SessionBinClientModel = class {
|
|
|
733
740
|
purgeBatch = null;
|
|
734
741
|
purgeBatchRun = null;
|
|
735
742
|
purgePreparationEpoch = 0;
|
|
743
|
+
stopPreferences;
|
|
744
|
+
setConfirmDeletion(confirmDeletion) {
|
|
745
|
+
try {
|
|
746
|
+
this.preferences?.save(confirmDeletion);
|
|
747
|
+
} catch {
|
|
748
|
+
}
|
|
749
|
+
this.publish({ confirmDeletion });
|
|
750
|
+
}
|
|
736
751
|
getSnapshot = () => this.snapshot;
|
|
737
752
|
subscribe = (listener) => {
|
|
738
753
|
this.listeners.add(listener);
|
|
@@ -781,6 +796,7 @@ var SessionBinClientModel = class {
|
|
|
781
796
|
})();
|
|
782
797
|
}
|
|
783
798
|
async dispose() {
|
|
799
|
+
this.stopPreferences?.();
|
|
784
800
|
this.lifetime.abort();
|
|
785
801
|
++this.epoch;
|
|
786
802
|
await this.stream?.dispose();
|
|
@@ -929,6 +945,25 @@ var SessionBinClientModel = class {
|
|
|
929
945
|
return { plan: null, reason: "connection-failed" };
|
|
930
946
|
}
|
|
931
947
|
}
|
|
948
|
+
/** Only a fresh user click can opt out of the presentation confirmation. */
|
|
949
|
+
async requestPurge(entry, title) {
|
|
950
|
+
const skip = !this.state.confirmDeletion;
|
|
951
|
+
const epoch = this.epoch;
|
|
952
|
+
const plan = await this.preparePurge(entry, title);
|
|
953
|
+
if (skip && !this.state.confirmDeletion && epoch === this.epoch && plan && this.confirmation?.plan.operationId === plan.operationId) {
|
|
954
|
+
this.acknowledgePurge(true);
|
|
955
|
+
await this.confirmPurge();
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
async requestPurgeBatch(scope, titles = {}) {
|
|
959
|
+
const skip = !this.state.confirmDeletion;
|
|
960
|
+
const epoch = this.epoch;
|
|
961
|
+
const batch = await this.preparePurgeBatch(scope, titles);
|
|
962
|
+
if (skip && !this.state.confirmDeletion && epoch === this.epoch && batch?.phase === "confirming" && this.purgeBatch?.batchId === batch.batchId && batch.items.some((item) => item.state === "ready")) {
|
|
963
|
+
this.acknowledgePurgeBatch(true);
|
|
964
|
+
await this.runPurgeBatch();
|
|
965
|
+
}
|
|
966
|
+
}
|
|
932
967
|
async preparePurge(entry, title) {
|
|
933
968
|
const target = { sessionId: entry.sessionId, entryId: entry.entryId, title };
|
|
934
969
|
if (this.rejectPurgeCacheCapacity() || this.state.phase !== "ready" || this.state.busy.includes(target.sessionId) || this.confirmation || this.hasActivePurgeBatch() || this.state.purgePending.length > 0 || this.state.pending.some((plan) => plan.schemaVersion === 2 && plan.sessionId === target.sessionId) || this.lifetime.signal.aborted) return null;
|
|
@@ -1666,8 +1701,32 @@ function browserPendingCache(storage) {
|
|
|
1666
1701
|
}
|
|
1667
1702
|
};
|
|
1668
1703
|
}
|
|
1704
|
+
function browserDeletionPreferences(storage, events) {
|
|
1705
|
+
const key2 = "dsh-session-bin.preferences.v1";
|
|
1706
|
+
const parse = (raw) => {
|
|
1707
|
+
try {
|
|
1708
|
+
const value2 = JSON.parse(raw ?? "null");
|
|
1709
|
+
return !(value2?.schemaVersion === 1 && value2.confirmDeletion === false);
|
|
1710
|
+
} catch {
|
|
1711
|
+
return true;
|
|
1712
|
+
}
|
|
1713
|
+
};
|
|
1714
|
+
return {
|
|
1715
|
+
load: () => parse(storage.getItem(key2)),
|
|
1716
|
+
save: (confirmDeletion) => storage.setItem(key2, JSON.stringify({ schemaVersion: 1, confirmDeletion })),
|
|
1717
|
+
subscribe: (listener) => {
|
|
1718
|
+
const changed = (event) => {
|
|
1719
|
+
const update = event;
|
|
1720
|
+
if (update.storageArea === storage && (update.key === key2 || update.key === null)) listener(parse(update.newValue));
|
|
1721
|
+
};
|
|
1722
|
+
events?.addEventListener("storage", changed);
|
|
1723
|
+
return () => events?.removeEventListener("storage", changed);
|
|
1724
|
+
}
|
|
1725
|
+
};
|
|
1726
|
+
}
|
|
1669
1727
|
export {
|
|
1670
1728
|
SessionBinClientModel,
|
|
1729
|
+
browserDeletionPreferences,
|
|
1671
1730
|
browserPendingCache,
|
|
1672
1731
|
retirementManifestDigest
|
|
1673
1732
|
};
|