@chaoset/session-archive 0.1.2 → 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.
@@ -0,0 +1,62 @@
1
+ /**
2
+ * typert.host.js — 手写的 Typert host 工件(typert-loader 机制)。
3
+ *
4
+ * DSH 的 typert-loader 会为「导出 ./typert 的 loader 条目」把本工件注册进
5
+ * ctx.typert.local,于是 api-gateway 直接认领这些端点。这是官方扩展点:
6
+ * 不依赖 remote.ts 的 Remote 装饰器 markers(markers 表是 typert-protocol
7
+ * 模块私有的 WeakMap,当插件从 profile 安装、typert-protocol 与 harness
8
+ * 各持一份模块实例时 markers 会丢失,SRC 认领为空,web 端报
9
+ * "transport failure ... HTTP 404")。
10
+ *
11
+ * codec 使用最小透传 schema({_zod, parse}):typert-loader 的
12
+ * requireStrictCodec 只校验这两个字段,网关 decode/encode 走 parse 透传,
13
+ * 与 client.tsx 里 $mount 的透传描述符一致。
14
+ */
15
+ declare const passthrough: (value: any) => any;
16
+ export declare const TYPERT: {
17
+ package: string;
18
+ face: string;
19
+ schemas: never[];
20
+ invocations: {
21
+ id: string;
22
+ service: string;
23
+ namespace: string;
24
+ method: string;
25
+ invocation: {
26
+ kind: string;
27
+ };
28
+ parameters: {
29
+ name: string;
30
+ wire: string;
31
+ source: string;
32
+ codec: {
33
+ mode: string;
34
+ typeSymbol: any;
35
+ schema: {
36
+ _zod: boolean;
37
+ parse: typeof passthrough;
38
+ };
39
+ };
40
+ }[];
41
+ result: {
42
+ mode: string;
43
+ typeSymbol: any;
44
+ schema: {
45
+ _zod: boolean;
46
+ parse: typeof passthrough;
47
+ };
48
+ };
49
+ sourceLocation: {
50
+ file: string;
51
+ line: number;
52
+ column: number;
53
+ };
54
+ }[];
55
+ model: {
56
+ services: never[];
57
+ events: never[];
58
+ objects: never[];
59
+ };
60
+ };
61
+ export {};
62
+ //# sourceMappingURL=typert.host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typert.host.d.ts","sourceRoot":"","sources":["../src/typert.host.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;GAaG;AAEH,QAAA,MAAM,WAAW,qBAAmB,CAAC;AAOrC,eAAO,MAAM,MAAM;;;;;;;;;;YAoBC,IAAI;;;;;;;;;;oBAvBZ,IAAI;oBAAQ,KAAK;;;;;;;;;;;;;YAiCL,IAAI;YAA4C,IAAI;YAAK,MAAM;;;;QAqC5E,QAAQ;QAAM,MAAM;QAAM,OAAO;;CAC3C,CAAC"}
@@ -1,91 +1,91 @@
1
+ // @ts-nocheck
1
2
  /**
2
3
  * typert.host.js — 手写的 Typert host 工件(typert-loader 机制)。
3
4
  *
4
5
  * DSH 的 typert-loader 会为「导出 ./typert 的 loader 条目」把本工件注册进
5
6
  * ctx.typert.local,于是 api-gateway 直接认领这些端点。这是官方扩展点:
6
- * 不依赖 remote.mjs 的 Remote 装饰器 markers(markers 表是 typert-protocol
7
+ * 不依赖 remote.ts 的 Remote 装饰器 markers(markers 表是 typert-protocol
7
8
  * 模块私有的 WeakMap,当插件从 profile 安装、typert-protocol 与 harness
8
9
  * 各持一份模块实例时 markers 会丢失,SRC 认领为空,web 端报
9
10
  * "transport failure ... HTTP 404")。
10
11
  *
11
12
  * codec 使用最小透传 schema({_zod, parse}):typert-loader 的
12
13
  * requireStrictCodec 只校验这两个字段,网关 decode/encode 走 parse 透传,
13
- * 与 client.cjs 里 $mount 的透传描述符一致。
14
+ * 与 client.tsx 里 $mount 的透传描述符一致。
14
15
  */
15
-
16
16
  const passthrough = (value) => value;
17
17
  const codec = (typeSymbol) => ({
18
- mode: 'strict',
19
- typeSymbol,
20
- schema: { _zod: true, parse: passthrough },
18
+ mode: 'strict',
19
+ typeSymbol,
20
+ schema: { _zod: true, parse: passthrough },
21
21
  });
22
-
23
22
  export const TYPERT = {
24
- package: '@chaoset/session-archive',
25
- face: 'host',
26
- schemas: [],
27
- invocations: [
28
- {
29
- id: '@chaoset/session-archive#sessionArchive/list',
30
- service: 'sessionArchive',
31
- namespace: 'sessionArchive',
32
- method: 'list',
33
- invocation: { kind: 'direct' },
34
- parameters: [],
35
- result: codec('@chaoset/session-archive/types#ArchiveListResult'),
36
- sourceLocation: { file: 'packages/session-archive/lib/remote.mjs', line: 1, column: 1 },
37
- },
38
- {
39
- id: '@chaoset/session-archive#sessionArchive/detail',
40
- service: 'sessionArchive',
41
- namespace: 'sessionArchive',
42
- method: 'detail',
43
- invocation: { kind: 'direct' },
44
- parameters: [
23
+ package: '@chaoset/session-archive',
24
+ face: 'host',
25
+ schemas: [],
26
+ invocations: [
45
27
  {
46
- name: 'sessionId',
47
- wire: 'sessionId',
48
- source: 'json',
49
- codec: codec('@chaoset/session-archive/types#SessionId'),
28
+ id: '@chaoset/session-archive#sessionArchive/list',
29
+ service: 'sessionArchive',
30
+ namespace: 'sessionArchive',
31
+ method: 'list',
32
+ invocation: { kind: 'direct' },
33
+ parameters: [],
34
+ result: codec('@chaoset/session-archive/types#ArchiveListResult'),
35
+ sourceLocation: { file: 'packages/session-archive/src/remote.ts', line: 1, column: 1 },
50
36
  },
51
- ],
52
- result: codec('@chaoset/session-archive/types#ArchiveDetailResult'),
53
- sourceLocation: { file: 'packages/session-archive/lib/remote.mjs', line: 1, column: 1 },
54
- },
55
- {
56
- id: '@chaoset/session-archive#sessionArchive/delete',
57
- service: 'sessionArchive',
58
- namespace: 'sessionArchive',
59
- method: 'delete',
60
- invocation: { kind: 'direct' },
61
- parameters: [
62
37
  {
63
- name: 'sessionIds',
64
- wire: 'sessionIds',
65
- source: 'json',
66
- codec: codec('@chaoset/session-archive/types#SessionIdArray'),
38
+ id: '@chaoset/session-archive#sessionArchive/detail',
39
+ service: 'sessionArchive',
40
+ namespace: 'sessionArchive',
41
+ method: 'detail',
42
+ invocation: { kind: 'direct' },
43
+ parameters: [
44
+ {
45
+ name: 'sessionId',
46
+ wire: 'sessionId',
47
+ source: 'json',
48
+ codec: codec('@chaoset/session-archive/types#SessionId'),
49
+ },
50
+ ],
51
+ result: codec('@chaoset/session-archive/types#ArchiveDetailResult'),
52
+ sourceLocation: { file: 'packages/session-archive/src/remote.ts', line: 1, column: 1 },
67
53
  },
68
- ],
69
- result: codec('@chaoset/session-archive/types#DeleteResult'),
70
- sourceLocation: { file: 'packages/session-archive/lib/remote.mjs', line: 1, column: 1 },
71
- },
72
- {
73
- id: '@chaoset/session-archive#sessionArchive/unarchive',
74
- service: 'sessionArchive',
75
- namespace: 'sessionArchive',
76
- method: 'unarchive',
77
- invocation: { kind: 'direct' },
78
- parameters: [
79
54
  {
80
- name: 'sessionIds',
81
- wire: 'sessionIds',
82
- source: 'json',
83
- codec: codec('@chaoset/session-archive/types#SessionIdArray'),
55
+ id: '@chaoset/session-archive#sessionArchive/delete',
56
+ service: 'sessionArchive',
57
+ namespace: 'sessionArchive',
58
+ method: 'delete',
59
+ invocation: { kind: 'direct' },
60
+ parameters: [
61
+ {
62
+ name: 'sessionIds',
63
+ wire: 'sessionIds',
64
+ source: 'json',
65
+ codec: codec('@chaoset/session-archive/types#SessionIdArray'),
66
+ },
67
+ ],
68
+ result: codec('@chaoset/session-archive/types#DeleteResult'),
69
+ sourceLocation: { file: 'packages/session-archive/src/remote.ts', line: 1, column: 1 },
84
70
  },
85
- ],
86
- result: codec('@chaoset/session-archive/types#UnarchiveResult'),
87
- sourceLocation: { file: 'packages/session-archive/lib/remote.mjs', line: 1, column: 1 },
88
- },
89
- ],
90
- model: { services: [], events: [], objects: [] },
71
+ {
72
+ id: '@chaoset/session-archive#sessionArchive/unarchive',
73
+ service: 'sessionArchive',
74
+ namespace: 'sessionArchive',
75
+ method: 'unarchive',
76
+ invocation: { kind: 'direct' },
77
+ parameters: [
78
+ {
79
+ name: 'sessionIds',
80
+ wire: 'sessionIds',
81
+ source: 'json',
82
+ codec: codec('@chaoset/session-archive/types#SessionIdArray'),
83
+ },
84
+ ],
85
+ result: codec('@chaoset/session-archive/types#UnarchiveResult'),
86
+ sourceLocation: { file: 'packages/session-archive/src/remote.ts', line: 1, column: 1 },
87
+ },
88
+ ],
89
+ model: { services: [], events: [], objects: [] },
91
90
  };
91
+ //# sourceMappingURL=typert.host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typert.host.js","sourceRoot":"","sources":["../src/typert.host.ts"],"names":[],"mappings":"AAAA,cAAc;AACd;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC;AACrC,MAAM,KAAK,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC7B,IAAI,EAAE,QAAQ;IACd,UAAU;IACV,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE;CAC3C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,OAAO,EAAE,0BAA0B;IACnC,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,EAAE;IACX,WAAW,EAAE;QACX;YACE,EAAE,EAAE,8CAA8C;YAClD,OAAO,EAAE,gBAAgB;YACzB,SAAS,EAAE,gBAAgB;YAC3B,MAAM,EAAE,MAAM;YACd,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC9B,UAAU,EAAE,EAAE;YACd,MAAM,EAAE,KAAK,CAAC,kDAAkD,CAAC;YACjE,cAAc,EAAE,EAAE,IAAI,EAAE,wCAAwC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;SACvF;QACD;YACE,EAAE,EAAE,gDAAgD;YACpD,OAAO,EAAE,gBAAgB;YACzB,SAAS,EAAE,gBAAgB;YAC3B,MAAM,EAAE,QAAQ;YAChB,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC9B,UAAU,EAAE;gBACV;oBACE,IAAI,EAAE,WAAW;oBACjB,IAAI,EAAE,WAAW;oBACjB,MAAM,EAAE,MAAM;oBACd,KAAK,EAAE,KAAK,CAAC,0CAA0C,CAAC;iBACzD;aACF;YACD,MAAM,EAAE,KAAK,CAAC,oDAAoD,CAAC;YACnE,cAAc,EAAE,EAAE,IAAI,EAAE,wCAAwC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;SACvF;QACD;YACE,EAAE,EAAE,gDAAgD;YACpD,OAAO,EAAE,gBAAgB;YACzB,SAAS,EAAE,gBAAgB;YAC3B,MAAM,EAAE,QAAQ;YAChB,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC9B,UAAU,EAAE;gBACV;oBACE,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE,YAAY;oBAClB,MAAM,EAAE,MAAM;oBACd,KAAK,EAAE,KAAK,CAAC,+CAA+C,CAAC;iBAC9D;aACF;YACD,MAAM,EAAE,KAAK,CAAC,6CAA6C,CAAC;YAC5D,cAAc,EAAE,EAAE,IAAI,EAAE,wCAAwC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;SACvF;QACD;YACE,EAAE,EAAE,mDAAmD;YACvD,OAAO,EAAE,gBAAgB;YACzB,SAAS,EAAE,gBAAgB;YAC3B,MAAM,EAAE,WAAW;YACnB,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC9B,UAAU,EAAE;gBACV;oBACE,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE,YAAY;oBAClB,MAAM,EAAE,MAAM;oBACd,KAAK,EAAE,KAAK,CAAC,+CAA+C,CAAC;iBAC9D;aACF;YACD,MAAM,EAAE,KAAK,CAAC,gDAAgD,CAAC;YAC/D,cAAc,EAAE,EAAE,IAAI,EAAE,wCAAwC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;SACvF;KACF;IACD,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;CACjD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chaoset/session-archive",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "DSH plugin: browse archived sessions, inspect their content, batch-restore or permanently delete them with multi-select",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -8,10 +8,12 @@
8
8
  "lib",
9
9
  "client",
10
10
  "cordis.patch.yml",
11
- "README.md"
11
+ "README.md",
12
+ "CHANGELOG.md",
13
+ "LICENSE"
12
14
  ],
13
15
  "exports": {
14
- ".": "./lib/index.mjs",
16
+ ".": "./lib/index.js",
15
17
  "./client": "./client/client.cjs",
16
18
  "./typert": "./lib/typert.host.js",
17
19
  "./cordis.patch.yml": "./cordis.patch.yml",
@@ -31,14 +33,13 @@
31
33
  }
32
34
  },
33
35
  "optionalDependencies": {
34
- "@deepseek-ai/dsh-typert-protocol": "^0.1.0-rc.6"
35
- },
36
- "engines": {
37
- "node": ">=22.19.0"
36
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.0-rc.7"
38
37
  },
39
38
  "scripts": {
40
- "test": "node ../../scripts/test.mjs",
41
- "prepublishOnly": "npm test"
39
+ "build": "bun ../../scripts/build.mjs",
40
+ "typecheck": "tsc -p tsconfig.json --noEmit",
41
+ "test": "bun ../../scripts/build.mjs && vitest run",
42
+ "prepublishOnly": "bun run test"
42
43
  },
43
44
  "repository": {
44
45
  "type": "git",
@@ -1,97 +0,0 @@
1
- /**
2
- * config-store — 插件配置持久化
3
- *
4
- * 配置文件位于 $DSH_HOME/plugins/<name>/config.json(默认 ~/.dsh,与
5
- * file:// 部署模式共用)。生效顺序(后者覆盖前者):
6
- * 1. 插件内置默认值(DEFAULT_CONFIG)
7
- * 2. cordis.patch.yml 传入的 config(安装时生成的默认块)
8
- * 3. config.json(设置页 UI 保存,权威)
9
- *
10
- * 保存后通过 onUpdate 回调立即热更新运行中的配置(包装闭包读共享 state)。
11
- * 写入采用随机临时文件 + fsync + rename,权限 0600;损坏 JSON 只告警并回退。
12
- */
13
-
14
- import { randomUUID } from "node:crypto";
15
- import { closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
16
- import { dirname, join, resolve } from "node:path";
17
- import { homedir } from "node:os";
18
-
19
- /**
20
- * 创建配置存储。
21
- * @param options - { name, defaults, patchConfig, onUpdate,
22
- * validate?: (partial) => void, warn?: (message) => void }
23
- */
24
- export function createConfigStore(options) {
25
- // 与 harness 的 DSH_HOME 约定保持一致:默认 ~/.dsh,可用 $DSH_HOME 覆盖。
26
- const dshHome = process.env.DSH_HOME?.trim() ? resolve(process.env.DSH_HOME) : join(homedir(), ".dsh");
27
- const file = join(dshHome, "plugins", options.name, "config.json");
28
- const warn = options.warn ?? (() => {});
29
- let readWarningShown = false;
30
-
31
- function readJson() {
32
- try {
33
- if (!existsSync(file)) return {};
34
- const parsed = JSON.parse(readFileSync(file, "utf8"));
35
- if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
36
- readWarningShown = false;
37
- return parsed;
38
- }
39
- if (!readWarningShown) {
40
- readWarningShown = true;
41
- warn(`config file ${file} must contain a JSON object; using empty config`);
42
- }
43
- return {};
44
- } catch (error) {
45
- if (!readWarningShown) {
46
- readWarningShown = true;
47
- warn(`failed to read config file ${file}: ${error?.message || error}; using empty config`);
48
- }
49
- return {};
50
- }
51
- }
52
-
53
- /** 当前生效配置(默认 + patch + json 合并)。 */
54
- function effective() {
55
- return { ...options.defaults, ...options.patchConfig, ...readJson() };
56
- }
57
-
58
- /** 保存部分配置到 config.json 并触发热更新,返回新的生效配置。 */
59
- function set(partial) {
60
- if (partial === null || typeof partial !== "object" || Array.isArray(partial)) {
61
- throw new TypeError("set expects a plain config object");
62
- }
63
- options.validate?.(partial);
64
- const merged = { ...readJson(), ...partial };
65
- mkdirSync(dirname(file), { recursive: true });
66
-
67
- const tmp = `${file}.${process.pid}.${randomUUID()}.tmp`;
68
- let fd;
69
- try {
70
- fd = openSync(tmp, "w", 0o600);
71
- writeFileSync(fd, JSON.stringify(merged, null, 2) + "\n", "utf8");
72
- fsyncSync(fd);
73
- closeSync(fd);
74
- fd = void 0;
75
- renameSync(tmp, file);
76
- // POSIX 目录项持久化(Windows 上目录句柄不可打开时忽略)。
77
- try {
78
- const dir = openSync(dirname(file), "r");
79
- try { fsyncSync(dir); } finally { closeSync(dir); }
80
- } catch {}
81
- } catch (error) {
82
- if (fd !== void 0) try { closeSync(fd); } catch {}
83
- try { unlinkSync(tmp); } catch {}
84
- throw error;
85
- }
86
-
87
- const next = { ...options.defaults, ...options.patchConfig, ...merged };
88
- try {
89
- options.onUpdate?.(merged, next);
90
- } catch (error) {
91
- warn(`onUpdate failed after config save: ${error?.message || error}`);
92
- }
93
- return next;
94
- }
95
-
96
- return { file, effective, set };
97
- }