@duke-dsh-plugins/dsh-archive-manager 1.3.5 → 1.4.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.
Files changed (5) hide show
  1. package/README.md +19 -1
  2. package/client.js +928 -530
  3. package/index.js +276 -276
  4. package/package.json +4 -3
  5. package/typert.host.js +278 -224
package/typert.host.js CHANGED
@@ -1,224 +1,278 @@
1
- /**
2
- * dsh-archive-manager — Typert Host manifest.
3
- *
4
- * Hand-written TYPERT manifest (the format the DSH typert-loader consumes from
5
- * the package's `./typert` export). It describes the `archiveManager` Remote
6
- * service the Host half publishes so the browser Client half can call it
7
- * through `ctx.remote.archiveManager.{restore,delete,state}`.
8
- *
9
- * Keep the invocation ids, service/namespace names and method names in sync
10
- * with `index.js` (ArchiveManagerService) and `client.js`.
11
- */
12
-
13
- import { z } from "zod";
14
-
15
- // ---- shared shapes ---------------------------------------------------------
16
-
17
- const sessionIdSchema = z.intersection(z.string(), z.unknown()).readonly();
18
-
19
- const restoreResultSchema = z.union([
20
- z.object({
21
- ok: z.literal(true).readonly(),
22
- value: z.object({
23
- restored: z.literal(true).readonly(),
24
- }).readonly(),
25
- }).readonly(),
26
- z.object({
27
- ok: z.literal(false).readonly(),
28
- error: z.object({
29
- code: z.string().readonly(),
30
- message: z.string().readonly().optional(),
31
- }).readonly(),
32
- }).readonly(),
33
- ]);
34
-
35
- const deleteResultSchema = z.union([
36
- z.object({
37
- ok: z.literal(true).readonly(),
38
- value: z.object({
39
- fileRemoved: z.boolean().readonly(),
40
- live: z.boolean().readonly(),
41
- }).readonly(),
42
- }).readonly(),
43
- z.object({
44
- ok: z.literal(false).readonly(),
45
- error: z.object({
46
- code: z.string().readonly(),
47
- message: z.string().readonly().optional(),
48
- }).readonly(),
49
- }).readonly(),
50
- ]);
51
-
52
- const stateResultSchema = z.union([
53
- z.object({
54
- ok: z.literal(true).readonly(),
55
- value: z.object({
56
- ghostIds: z.array(sessionIdSchema).readonly(),
57
- }).readonly(),
58
- }).readonly(),
59
- z.object({
60
- ok: z.literal(false).readonly(),
61
- error: z.object({
62
- code: z.string().readonly(),
63
- message: z.string().readonly().optional(),
64
- }).readonly(),
65
- }).readonly(),
66
- ]);
67
-
68
- // ---- per-invocation parameter/result schemas -------------------------------
69
-
70
- const _archiveManager_restore_parameter_0$schema = z.object({
71
- sessionId: sessionIdSchema,
72
- });
73
-
74
- const _archiveManager_delete_parameter_0$schema = z.object({
75
- sessionId: sessionIdSchema,
76
- });
77
-
78
- export const TYPERT = {
79
- package: "@duke-dsh-plugins/dsh-archive-manager",
80
- face: "host",
81
- schemas: [],
82
- invocations: [
83
- {
84
- id: "dsh-archive-manager#archiveManager/restore",
85
- service: "archiveManager",
86
- namespace: "archiveManager",
87
- method: "restore",
88
- invocation: { kind: "direct" },
89
- parameters: [
90
- {
91
- name: "request",
92
- wire: "request",
93
- source: "json",
94
- codec: {
95
- mode: "strict",
96
- typeSymbol: "dsh-archive-manager#ArchiveManagerRestoreRequest",
97
- schema: _archiveManager_restore_parameter_0$schema,
98
- },
99
- },
100
- ],
101
- result: {
102
- mode: "strict",
103
- typeSymbol: "dsh-archive-manager#ArchiveManagerRestoreResult",
104
- schema: restoreResultSchema,
105
- },
106
- sourceLocation: { file: "index.js", line: 1, column: 1 },
107
- },
108
- {
109
- id: "dsh-archive-manager#archiveManager/delete",
110
- service: "archiveManager",
111
- namespace: "archiveManager",
112
- method: "delete",
113
- invocation: { kind: "direct" },
114
- parameters: [
115
- {
116
- name: "request",
117
- wire: "request",
118
- source: "json",
119
- codec: {
120
- mode: "strict",
121
- typeSymbol: "dsh-archive-manager#ArchiveManagerDeleteRequest",
122
- schema: _archiveManager_delete_parameter_0$schema,
123
- },
124
- },
125
- ],
126
- result: {
127
- mode: "strict",
128
- typeSymbol: "dsh-archive-manager#ArchiveManagerDeleteResult",
129
- schema: deleteResultSchema,
130
- },
131
- sourceLocation: { file: "index.js", line: 1, column: 1 },
132
- },
133
- {
134
- id: "dsh-archive-manager#archiveManager/state",
135
- service: "archiveManager",
136
- namespace: "archiveManager",
137
- method: "state",
138
- invocation: { kind: "direct" },
139
- parameters: [],
140
- result: {
141
- mode: "strict",
142
- typeSymbol: "dsh-archive-manager#ArchiveManagerStateResult",
143
- schema: stateResultSchema,
144
- },
145
- sourceLocation: { file: "index.js", line: 1, column: 1 },
146
- },
147
- ],
148
- model: {
149
- services: [
150
- {
151
- description:
152
- "Archive manager service: restore, delete and inspect archived sessions for the DeepSeek Harness web UI.",
153
- summary: "Archive manager service.",
154
- tags: [],
155
- jsDoc:
156
- "/**\n * Archive manager service: restore, delete and inspect archived sessions.\n */",
157
- key: "archiveManager",
158
- exportName: "ArchiveManagerService",
159
- members: [
160
- {
161
- kind: "method",
162
- name: "restore",
163
- signature:
164
- "@Remote('restore') async restore(request: ArchiveManagerRestoreRequest): Promise<ArchiveManagerRestoreResult>",
165
- summary: "Remove one session from the archive set so it returns to its project slot.",
166
- jsDoc:
167
- "/**\n * Remove one session from the archive set so it returns to its project slot.\n * @param request - target session id.\n * @returns success or a business failure.\n */",
168
- },
169
- {
170
- kind: "method",
171
- name: "delete",
172
- signature:
173
- "@Remote('delete') async delete(request: ArchiveManagerDeleteRequest): Promise<ArchiveManagerDeleteResult>",
174
- summary: "Permanently delete one archived session's log directory and clear its archive entry.",
175
- jsDoc:
176
- "/**\n * Permanently delete one archived session's log directory and clear its archive\n * entry. Refuses sessions whose agent is running; live-but-idle sessions keep\n * their entry (ghost) until restart.\n * @param request - target session id.\n * @returns success or a business failure.\n */",
177
- },
178
- {
179
- kind: "method",
180
- name: "state",
181
- signature:
182
- "@Remote('state') async state(): Promise<ArchiveManagerStateResult>",
183
- summary: "Report archived sessions that are live in memory but whose logs are gone.",
184
- jsDoc:
185
- "/**\n * Report archived sessions that are still live in memory while their log files\n * no longer exist (ghost records the client hides).\n * @returns the ghost session ids.\n */",
186
- },
187
- ],
188
- types: [
189
- {
190
- name: "ArchiveManagerRestoreRequest",
191
- declaration:
192
- "export interface ArchiveManagerRestoreRequest {\n readonly sessionId: SessionId;\n}",
193
- },
194
- {
195
- name: "ArchiveManagerRestoreResult",
196
- declaration:
197
- "export type ArchiveManagerRestoreResult = { ok: true; value: { restored: true } } | { ok: false; error: { code: string; message?: string } };",
198
- },
199
- {
200
- name: "ArchiveManagerDeleteRequest",
201
- declaration:
202
- "export interface ArchiveManagerDeleteRequest {\n readonly sessionId: SessionId;\n}",
203
- },
204
- {
205
- name: "ArchiveManagerDeleteResult",
206
- declaration:
207
- "export type ArchiveManagerDeleteResult = { ok: true; value: { fileRemoved: boolean; live: boolean } } | { ok: false; error: { code: string; message?: string } };",
208
- },
209
- {
210
- name: "ArchiveManagerStateResult",
211
- declaration:
212
- "export type ArchiveManagerStateResult = { ok: true; value: { ghostIds: readonly SessionId[] } } | { ok: false; error: { code: string; message?: string } };",
213
- },
214
- {
215
- name: "SessionId",
216
- declaration: "export type SessionId = Branded<'SessionId'>;",
217
- },
218
- ],
219
- },
220
- ],
221
- events: [],
222
- objects: [],
223
- },
224
- };
1
+ /**
2
+ * dsh-archive-manager — Typert Host manifest.
3
+ *
4
+ * Hand-written TYPERT manifest (the format the DSH typert-loader consumes from
5
+ * the package's `./typert` export). It describes the `archiveManager` Remote
6
+ * service the Host half publishes so the browser Client half can call it
7
+ * through `ctx.remote.archiveManager.{restore,delete,state}`.
8
+ *
9
+ * Keep the invocation ids, service/namespace names and method names in sync
10
+ * with `index.js` (ArchiveManagerService) and `client.js`.
11
+ *
12
+ * Cross-version note: strict codecs carry BOTH `schema` (DSH < 0.1.7 reads
13
+ * the zod instance) and `create` (DSH >= 0.1.7 requires the factory) — see
14
+ * the codec contract comment below before touching any codec.
15
+ */
16
+
17
+ import { z } from "zod";
18
+
19
+ // ---- shared shapes ---------------------------------------------------------
20
+ //
21
+ // DSH-versioned codec contract (the ONE field that differs across DSH builds):
22
+ // - DSH < 0.1.7 (typert-loader / typert-registry): a strict codec must carry
23
+ // `codec.schema` — a zod v4 INSTANCE (`_zod` + `parse`) — and the runtime
24
+ // calls `codec.schema.parse(...)`.
25
+ // - DSH >= 0.1.7: a strict codec must carry `codec.create` — a FACTORY
26
+ // function returning a zod schema — and the runtime calls
27
+ // `codec.create().parse(...)`; a plain instance in `schema` fails
28
+ // validation with "strict codec has no create() factory".
29
+ // Every codec below therefore carries BOTH: `schema` (materialized instance,
30
+ // read by <0.1.7) and `create` (memoized factory, read by >=0.1.7). Each
31
+ // version's validator only inspects its own field, so the extra field is
32
+ // ignored everywhere. Same for TYPERT.schemas entries (0.1.7 requires
33
+ // `create`; our list stays empty, which satisfies both).
34
+
35
+ /**
36
+ * Memoize one zod schema behind a `create()`-style factory: repeated calls
37
+ * return the same instance (the official 0.1.7 manifests use this exact
38
+ * `value ??= build()` pattern).
39
+ *
40
+ * @param {() => object} build - constructs the zod schema once.
41
+ * @returns {() => object} the factory.
42
+ */
43
+ function lazy(build) {
44
+ let value;
45
+ return () => (value ??= build());
46
+ }
47
+
48
+ const sessionIdSchema = lazy(() => z.intersection(z.string(), z.unknown()).readonly());
49
+
50
+ const restoreResultSchema = lazy(() =>
51
+ z.union([
52
+ z.object({
53
+ ok: z.literal(true).readonly(),
54
+ value: z.object({
55
+ restored: z.literal(true).readonly(),
56
+ }).readonly(),
57
+ }).readonly(),
58
+ z.object({
59
+ ok: z.literal(false).readonly(),
60
+ error: z.object({
61
+ code: z.string().readonly(),
62
+ message: z.string().readonly().optional(),
63
+ }).readonly(),
64
+ }).readonly(),
65
+ ])
66
+ );
67
+
68
+ const deleteResultSchema = lazy(() =>
69
+ z.union([
70
+ z.object({
71
+ ok: z.literal(true).readonly(),
72
+ value: z.object({
73
+ fileRemoved: z.boolean().readonly(),
74
+ live: z.boolean().readonly(),
75
+ }).readonly(),
76
+ }).readonly(),
77
+ z.object({
78
+ ok: z.literal(false).readonly(),
79
+ error: z.object({
80
+ code: z.string().readonly(),
81
+ message: z.string().readonly().optional(),
82
+ }).readonly(),
83
+ }).readonly(),
84
+ ])
85
+ );
86
+
87
+ const stateResultSchema = lazy(() =>
88
+ z.union([
89
+ z.object({
90
+ ok: z.literal(true).readonly(),
91
+ value: z.object({
92
+ ghostIds: z.array(sessionIdSchema()).readonly(),
93
+ }).readonly(),
94
+ }).readonly(),
95
+ z.object({
96
+ ok: z.literal(false).readonly(),
97
+ error: z.object({
98
+ code: z.string().readonly(),
99
+ message: z.string().readonly().optional(),
100
+ }).readonly(),
101
+ }).readonly(),
102
+ ])
103
+ );
104
+
105
+ // ---- per-invocation parameter/result schemas -------------------------------
106
+
107
+ const restoreRequestSchema = lazy(() =>
108
+ z.object({
109
+ sessionId: sessionIdSchema(),
110
+ })
111
+ );
112
+
113
+ const deleteRequestSchema = lazy(() =>
114
+ z.object({
115
+ sessionId: sessionIdSchema(),
116
+ })
117
+ );
118
+
119
+ /**
120
+ * Build the dual-version strict codec: `schema` for DSH < 0.1.7 (instance
121
+ * read at validation time), `create` for DSH >= 0.1.7 (factory invoked by
122
+ * the runtime). Both point at the same memoized instance.
123
+ *
124
+ * @param {string} typeSymbol - wire type symbol.
125
+ * @param {() => object} factory - the memoized schema factory.
126
+ * @returns {object} the codec descriptor.
127
+ */
128
+ function strictCodec(typeSymbol, factory) {
129
+ return {
130
+ mode: "strict",
131
+ typeSymbol,
132
+ schema: factory(),
133
+ create: factory,
134
+ };
135
+ }
136
+
137
+ export const TYPERT = {
138
+ package: "@duke-dsh-plugins/dsh-archive-manager",
139
+ face: "host",
140
+ schemas: [],
141
+ invocations: [
142
+ {
143
+ id: "dsh-archive-manager#archiveManager/restore",
144
+ service: "archiveManager",
145
+ namespace: "archiveManager",
146
+ method: "restore",
147
+ invocation: { kind: "direct" },
148
+ parameters: [
149
+ {
150
+ name: "request",
151
+ wire: "request",
152
+ source: "json",
153
+ codec: strictCodec(
154
+ "dsh-archive-manager#ArchiveManagerRestoreRequest",
155
+ restoreRequestSchema
156
+ ),
157
+ },
158
+ ],
159
+ result: strictCodec(
160
+ "dsh-archive-manager#ArchiveManagerRestoreResult",
161
+ restoreResultSchema
162
+ ),
163
+ sourceLocation: { file: "index.js", line: 1, column: 1 },
164
+ },
165
+ {
166
+ id: "dsh-archive-manager#archiveManager/delete",
167
+ service: "archiveManager",
168
+ namespace: "archiveManager",
169
+ method: "delete",
170
+ invocation: { kind: "direct" },
171
+ parameters: [
172
+ {
173
+ name: "request",
174
+ wire: "request",
175
+ source: "json",
176
+ codec: strictCodec(
177
+ "dsh-archive-manager#ArchiveManagerDeleteRequest",
178
+ deleteRequestSchema
179
+ ),
180
+ },
181
+ ],
182
+ result: strictCodec(
183
+ "dsh-archive-manager#ArchiveManagerDeleteResult",
184
+ deleteResultSchema
185
+ ),
186
+ sourceLocation: { file: "index.js", line: 1, column: 1 },
187
+ },
188
+ {
189
+ id: "dsh-archive-manager#archiveManager/state",
190
+ service: "archiveManager",
191
+ namespace: "archiveManager",
192
+ method: "state",
193
+ invocation: { kind: "direct" },
194
+ parameters: [],
195
+ result: strictCodec(
196
+ "dsh-archive-manager#ArchiveManagerStateResult",
197
+ stateResultSchema
198
+ ),
199
+ sourceLocation: { file: "index.js", line: 1, column: 1 },
200
+ },
201
+ ],
202
+ model: {
203
+ services: [
204
+ {
205
+ description:
206
+ "Archive manager service: restore, delete and inspect archived sessions for the DeepSeek Harness web UI.",
207
+ summary: "Archive manager service.",
208
+ tags: [],
209
+ jsDoc:
210
+ "/**\n * Archive manager service: restore, delete and inspect archived sessions.\n */",
211
+ key: "archiveManager",
212
+ exportName: "ArchiveManagerService",
213
+ members: [
214
+ {
215
+ kind: "method",
216
+ name: "restore",
217
+ signature:
218
+ "@Remote('restore') async restore(request: ArchiveManagerRestoreRequest): Promise<ArchiveManagerRestoreResult>",
219
+ summary: "Remove one session from the archive set so it returns to its project slot.",
220
+ jsDoc:
221
+ "/**\n * Remove one session from the archive set so it returns to its project slot.\n * @param request - target session id.\n * @returns success or a business failure.\n */",
222
+ },
223
+ {
224
+ kind: "method",
225
+ name: "delete",
226
+ signature:
227
+ "@Remote('delete') async delete(request: ArchiveManagerDeleteRequest): Promise<ArchiveManagerDeleteResult>",
228
+ summary: "Permanently delete one archived session's log directory and clear its archive entry.",
229
+ jsDoc:
230
+ "/**\n * Permanently delete one archived session's log directory and clear its archive\n * entry. Refuses sessions whose agent is running; live-but-idle sessions keep\n * their entry (ghost) until restart.\n * @param request - target session id.\n * @returns success or a business failure.\n */",
231
+ },
232
+ {
233
+ kind: "method",
234
+ name: "state",
235
+ signature:
236
+ "@Remote('state') async state(): Promise<ArchiveManagerStateResult>",
237
+ summary: "Report archived sessions that are live in memory but whose logs are gone.",
238
+ jsDoc:
239
+ "/**\n * Report archived sessions that are still live in memory while their log files\n * no longer exist (ghost records the client hides).\n * @returns the ghost session ids.\n */",
240
+ },
241
+ ],
242
+ types: [
243
+ {
244
+ name: "ArchiveManagerRestoreRequest",
245
+ declaration:
246
+ "export interface ArchiveManagerRestoreRequest {\n readonly sessionId: SessionId;\n}",
247
+ },
248
+ {
249
+ name: "ArchiveManagerRestoreResult",
250
+ declaration:
251
+ "export type ArchiveManagerRestoreResult = { ok: true; value: { restored: true } } | { ok: false; error: { code: string; message?: string } };",
252
+ },
253
+ {
254
+ name: "ArchiveManagerDeleteRequest",
255
+ declaration:
256
+ "export interface ArchiveManagerDeleteRequest {\n readonly sessionId: SessionId;\n}",
257
+ },
258
+ {
259
+ name: "ArchiveManagerDeleteResult",
260
+ declaration:
261
+ "export type ArchiveManagerDeleteResult = { ok: true; value: { fileRemoved: boolean; live: boolean } } | { ok: false; error: { code: string; message?: string } };",
262
+ },
263
+ {
264
+ name: "ArchiveManagerStateResult",
265
+ declaration:
266
+ "export type ArchiveManagerStateResult = { ok: true; value: { ghostIds: readonly SessionId[] } } | { ok: false; error: { code: string; message?: string } };",
267
+ },
268
+ {
269
+ name: "SessionId",
270
+ declaration: "export type SessionId = Branded<'SessionId'>;",
271
+ },
272
+ ],
273
+ },
274
+ ],
275
+ events: [],
276
+ objects: [],
277
+ },
278
+ };