@wangxiaocuo/dsh-session-trash 0.6.3 → 0.6.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/lib/members.js CHANGED
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  /**
11
- * @param {unknown} entry index entry (v1 or v2 shape).
11
+ * @param {any} entry index entry (v1 or v2 shape).
12
12
  * @returns {object|null} the parent member, or null when the entry has no directory data.
13
13
  */
14
14
  export function parentMember(entry) {
@@ -28,8 +28,8 @@ export function parentMember(entry) {
28
28
  }
29
29
 
30
30
  /**
31
- * @param {unknown} entry index entry (v1 or v2 shape).
32
- * @returns {object[]} every owned directory, parent first.
31
+ * @param {any} entry index entry (v1 or v2 shape).
32
+ * @returns {any[]} every owned directory, parent first.
33
33
  */
34
34
  export function memberList(entry) {
35
35
  if (entry !== null && typeof entry === 'object' && Array.isArray(entry.members) && entry.members.length > 0) {
@@ -40,7 +40,7 @@ export function memberList(entry) {
40
40
  }
41
41
 
42
42
  /**
43
- * @param {readonly object[]} members member list.
43
+ * @param {readonly any[]} members member list.
44
44
  * @returns {{ sizeBytes: number, fileCount: number }} summed measurable totals.
45
45
  */
46
46
  export function aggregateMetrics(members) {
@@ -57,7 +57,7 @@ export function aggregateMetrics(members) {
57
57
  * Shape-level validation shared by the durable index and object sidecars.
58
58
  * Path strictness belongs to the sidecar validator.
59
59
  *
60
- * @param {unknown} member candidate member.
60
+ * @param {any} member candidate member.
61
61
  * @returns {boolean} whether the member carries the required v2 identity.
62
62
  */
63
63
  export function isValidMemberShape(member) {
@@ -79,7 +79,7 @@ export function isValidMemberShape(member) {
79
79
  /**
80
80
  * Whether the v2 member list is internally consistent with its parent entry.
81
81
  *
82
- * @param {unknown} entry index entry carrying `members`.
82
+ * @param {any} entry index entry carrying `members`.
83
83
  * @returns {boolean} whether the list is acceptable.
84
84
  */
85
85
  export function isValidMemberList(entry) {
package/lib/state.js CHANGED
@@ -10,6 +10,7 @@ const PROBE_CONCURRENCY = 3
10
10
  * stays an English diagnostic for logs and tooltips; the code is what the
11
11
  * Client localizes.
12
12
  */
13
+ /** @type {[RegExp, string][]} */
13
14
  const LAST_ERROR_KINDS = [
14
15
  [/^The trash copy of this session is missing\./, 'TRASH_COPY_MISSING'],
15
16
  [/^The trash copy is missing these member sessions:/, 'TRASH_COPY_MISSING_MEMBERS'],
@@ -22,7 +23,7 @@ const LAST_ERROR_KINDS = [
22
23
  ]
23
24
 
24
25
  /**
25
- * @param {unknown} message raw `lastError` text.
26
+ * @param {any} message raw `lastError` text.
26
27
  * @returns {string | null} a stable failure family, or null when none was recorded.
27
28
  */
28
29
  export function lastErrorCode(message) {
@@ -55,9 +56,10 @@ async function directoryExists(directory) {
55
56
  * config: { retentionDays: number, sweepIntervalHours: number, enableAutoCleanup: boolean },
56
57
  * trashRootDisplay: string,
57
58
  * nextSweepAt?: () => number | null,
58
- * cleanup?: () => object,
59
+ * cleanup?: () => any,
60
+ * directoryExists?: (directory?: any) => Promise<boolean>,
59
61
  * }} deps state inputs.
60
- * @returns {{ snapshot: () => Promise<object>, describe: (entry: object) => Promise<object> }} the state service.
62
+ * @returns {{ snapshot: () => Promise<any>, describe: (entry: any) => Promise<any> }} the state service.
61
63
  */
62
64
  export function createStateService({
63
65
  store,
@@ -68,7 +70,7 @@ export function createStateService({
68
70
  directoryExists: probeDirectory = directoryExists,
69
71
  }) {
70
72
  /**
71
- * @returns {object} cleanup diagnostics, or a neutral fallback.
73
+ * @returns {any} cleanup diagnostics, or a neutral fallback.
72
74
  */
73
75
  function cleanupDiagnostics() {
74
76
  if (typeof cleanup === 'function') {
@@ -92,10 +94,10 @@ export function createStateService({
92
94
  }
93
95
 
94
96
  /**
95
- * @param {object} entry committed index entry.
97
+ * @param {any} entry committed index entry.
96
98
  * @param {Map<string, Promise<boolean>>} [probeCache] workspace probes already
97
99
  * started for this snapshot, so entries sharing a cwd probe it once.
98
- * @returns {Promise<object>} the wire entry.
100
+ * @returns {Promise<any>} the wire entry.
99
101
  */
100
102
  async function describeEntry(entry, probeCache = new Map()) {
101
103
  const cwd = typeof entry.originalCwd === 'string' && entry.originalCwd !== '' ? entry.originalCwd : null
@@ -138,12 +140,12 @@ export function createStateService({
138
140
 
139
141
  return {
140
142
  /**
141
- * @param {object} entry committed index entry.
142
- * @returns {Promise<object>} the wire entry.
143
+ * @param {any} entry committed index entry.
144
+ * @returns {Promise<any>} the wire entry.
143
145
  */
144
146
  describe: describeEntry,
145
147
  /**
146
- * @returns {Promise<object>} the complete `/state` response body.
148
+ * @returns {Promise<any>} the complete `/state` response body.
147
149
  */
148
150
  async snapshot() {
149
151
  const probeCache = new Map()
package/lib/store.js CHANGED
@@ -16,7 +16,7 @@ export const LOCK_REFRESH_MS = 60 * 1000
16
16
 
17
17
  /**
18
18
  * @param {number} [now] timestamp for the new index.
19
- * @returns {{ version: number, updatedAt: number, entries: never[] }} an empty index document.
19
+ * @returns {{ version: number, updatedAt: number, entries: any[] }} an empty index document.
20
20
  */
21
21
  export function emptyIndex(now = Date.now()) {
22
22
  return { version: INDEX_VERSION, updatedAt: now, entries: [] }
@@ -26,8 +26,8 @@ export function emptyIndex(now = Date.now()) {
26
26
  * Coerce one durable entry to the v2 shape. A v1 entry names a single
27
27
  * directory, which becomes the parent member of a one-member tree.
28
28
  *
29
- * @param {object} entry entry from either durable shape.
30
- * @returns {object} the v2 entry.
29
+ * @param {any} entry entry from either durable shape.
30
+ * @returns {any} the v2 entry.
31
31
  */
32
32
  function normalizeEntry(entry) {
33
33
  if (entry === null || typeof entry !== 'object') return entry
@@ -40,7 +40,7 @@ function normalizeEntry(entry) {
40
40
  * Validate the persisted index shape strictly enough that a truncated or
41
41
  * hand-edited file enters protection mode instead of silently vanishing.
42
42
  *
43
- * @param {unknown} value parsed JSON document.
43
+ * @param {any} value parsed JSON document.
44
44
  * @returns {boolean} whether the document is a supported index.
45
45
  */
46
46
  export function isValidIndex(value) {
@@ -141,7 +141,7 @@ export class TrashStore {
141
141
  }
142
142
 
143
143
  /**
144
- * @returns {readonly object[]} the committed entries.
144
+ * @returns {readonly any[]} the committed entries.
145
145
  */
146
146
  entries() {
147
147
  return this.index.entries
@@ -149,7 +149,7 @@ export class TrashStore {
149
149
 
150
150
  /**
151
151
  * @param {string} sessionId session to look up.
152
- * @returns {object | undefined} the index entry for this session.
152
+ * @returns {any | undefined} the index entry for this session.
153
153
  */
154
154
  findEntry(sessionId) {
155
155
  return this.index.entries.find((entry) => entry.sessionId === sessionId)
@@ -235,7 +235,7 @@ export class TrashStore {
235
235
 
236
236
  /**
237
237
  * @param {string} trashId object identity.
238
- * @returns {Promise<object | undefined>} the parsed sidecar metadata, when present.
238
+ * @returns {Promise<any | undefined>} the parsed sidecar metadata, when present.
239
239
  */
240
240
  async readMeta(trashId) {
241
241
  try {
@@ -279,7 +279,7 @@ export class TrashStore {
279
279
  * Atomically write one object sidecar. Metadata is written before the session
280
280
  * directory moves, so a damaged index can rebuild from it later.
281
281
  *
282
- * @param {object} entry index-shaped entry carrying `trashId`.
282
+ * @param {any} entry index-shaped entry carrying `trashId`.
283
283
  * @returns {Promise<void>} resolution once the sidecar is durable.
284
284
  */
285
285
  async writeMeta(entry) {
@@ -331,7 +331,7 @@ export class TrashStore {
331
331
  /**
332
332
  * Commit a complete entry list and refresh the in-memory projection.
333
333
  *
334
- * @param {readonly object[]} entries complete new entry list.
334
+ * @param {readonly any[]} entries complete new entry list.
335
335
  * @returns {Promise<void>} resolution once committed.
336
336
  */
337
337
  async commit(entries) {
@@ -346,7 +346,7 @@ export class TrashStore {
346
346
 
347
347
  /**
348
348
  * @param {string} file index file to read.
349
- * @returns {Promise<unknown>} parsed JSON.
349
+ * @returns {Promise<any>} parsed JSON.
350
350
  */
351
351
  async readJson(file) {
352
352
  return JSON.parse(await fs.readFile(file, 'utf8'))
@@ -392,8 +392,8 @@ export class TrashStore {
392
392
  }
393
393
 
394
394
  /**
395
- * @param {{ version: number, updatedAt: number, entries: readonly object[] }} data parsed index document.
396
- * @returns {{ version: number, updatedAt: number, entries: object[] }} the v2 document.
395
+ * @param {{ version: number, updatedAt: number, entries: readonly any[] }} data parsed index document.
396
+ * @returns {{ version: number, updatedAt: number, entries: any[] }} the v2 document.
397
397
  */
398
398
  normalizeIndex(data) {
399
399
  if (data.version !== INDEX_VERSION) this.needsUpgrade = true
@@ -408,8 +408,8 @@ export class TrashStore {
408
408
  * Atomically commit the index: write a temporary file, preserve the previous
409
409
  * commit as `.bak`, then rename over the live index.
410
410
  *
411
- * @param {readonly object[]} entries the complete entry list to persist.
412
- * @returns {Promise<{ version: number, updatedAt: number, entries: readonly object[] }>} the committed document.
411
+ * @param {readonly any[]} entries the complete entry list to persist.
412
+ * @returns {Promise<{ version: number, updatedAt: number, entries: readonly any[] }>} the committed document.
413
413
  */
414
414
  async writeIndex(entries) {
415
415
  const normalized = entries.map((entry) => normalizeEntry(entry))
@@ -582,7 +582,10 @@ export class TrashStore {
582
582
  await removePathWithRetry(this.lockPath, { recursive: false, force: true, attempts: 5, delayMs: 20 })
583
583
  } catch (removeError) {
584
584
  throw new TrashError('LOCKED', 'A stale trash lock could not be removed. Try again in a moment.', {
585
- code: removeError instanceof Error && typeof removeError.code === 'string' ? removeError.code : null,
585
+ code:
586
+ removeError instanceof Error && typeof /** @type {any} */ (removeError).code === 'string'
587
+ ? /** @type {any} */ (removeError).code
588
+ : null,
586
589
  })
587
590
  }
588
591
  }
@@ -45,7 +45,7 @@ function errorText(message) {
45
45
  }
46
46
 
47
47
  /**
48
- * @param {unknown} error arbitrary failure.
48
+ * @param {any} error arbitrary failure.
49
49
  * @returns {string} a user-facing error message.
50
50
  */
51
51
  function messageOf(error) {
@@ -53,9 +53,9 @@ function messageOf(error) {
53
53
  }
54
54
 
55
55
  /**
56
- * @param {readonly object[]} entries current index entries.
57
- * @param {object} next replacement entry.
58
- * @returns {object[]} a new list with the entry replaced or appended.
56
+ * @param {readonly any[]} entries current index entries.
57
+ * @param {any} next replacement entry.
58
+ * @returns {any[]} a new list with the entry replaced or appended.
59
59
  */
60
60
  function upsertEntry(entries, next) {
61
61
  const copy = [...entries]
@@ -66,9 +66,9 @@ function upsertEntry(entries, next) {
66
66
  }
67
67
 
68
68
  /**
69
- * @param {readonly object[]} entries current index entries.
69
+ * @param {readonly any[]} entries current index entries.
70
70
  * @param {string} sessionId session to drop.
71
- * @returns {object[]} a new list without that session.
71
+ * @returns {any[]} a new list without that session.
72
72
  */
73
73
  function dropEntry(entries, sessionId) {
74
74
  return entries.filter((entry) => entry.sessionId !== sessionId)
@@ -81,23 +81,23 @@ function dropEntry(entries, sessionId) {
81
81
  * @param {{
82
82
  * ctx: import('@deepseek-ai/cordis').Context,
83
83
  * store: import('./store.js').TrashStore,
84
- * eligibility: { evaluate: (sessionId: string) => Promise<object>, invalidate: (sessionId?: string) => void },
84
+ * eligibility: { evaluate: (sessionId: string) => Promise<any>, invalidate: (sessionId?: string) => void },
85
85
  * config: { retentionDays: number, sweepIntervalHours: number, enableAutoCleanup: boolean },
86
86
  * logger: { info: Function, warn: Function, error: Function, debug: Function },
87
87
  * paths: { root: string, display: string },
88
88
  * }} deps host services and resolved paths.
89
- * @returns {object} the operation surface.
89
+ * @returns {any} the operation surface.
90
90
  */
91
91
  export function createTrashService({ ctx, store, eligibility, config, logger, paths }) {
92
92
  /**
93
- * @returns {object | undefined} the optional title service.
93
+ * @returns {any | undefined} the optional title service.
94
94
  */
95
95
  function sessionQuery() {
96
96
  return ctx.get('sessionQuery')
97
97
  }
98
98
 
99
99
  /**
100
- * @returns {object | undefined} the optional workspace registry.
100
+ * @returns {any | undefined} the optional workspace registry.
101
101
  */
102
102
  function workspaceRegistry() {
103
103
  return ctx.get('workspaceRegistry')
@@ -105,7 +105,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
105
105
 
106
106
  /**
107
107
  * @param {string} sessionId session whose storage snapshot to read.
108
- * @returns {Promise<object | undefined>} the persistence snapshot.
108
+ * @returns {Promise<any | undefined>} the persistence snapshot.
109
109
  */
110
110
  async function stat(sessionId) {
111
111
  return ctx.sessionPersistence.stat(sessionId)
@@ -113,7 +113,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
113
113
 
114
114
  /**
115
115
  * @param {string} sessionId session to check.
116
- * @returns {Promise<boolean>} whether the session is live in this process.
116
+ * @returns {boolean} whether the session is live in this process.
117
117
  */
118
118
  function isLive(sessionId) {
119
119
  const liveSession = typeof ctx.sessions?.get === 'function' ? ctx.sessions.get(sessionId) : undefined
@@ -122,7 +122,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
122
122
  }
123
123
 
124
124
  /**
125
- * @param {object} snapshot persistence snapshot.
125
+ * @param {any} snapshot persistence snapshot.
126
126
  * @returns {string} the session header's cwd, or an empty string when absent.
127
127
  */
128
128
  function cwdOf(snapshot) {
@@ -134,7 +134,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
134
134
  * query service.
135
135
  *
136
136
  * @param {string} sessionId session whose title to read.
137
- * @param {object} header persistence header.
137
+ * @param {any} header persistence header.
138
138
  * @returns {Promise<string>} the title, then cwd basename, then session id.
139
139
  */
140
140
  async function resolveTitle(sessionId, header) {
@@ -158,7 +158,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
158
158
  * Find the Workspace that currently accounts for a session.
159
159
  *
160
160
  * @param {string} sessionId session to locate.
161
- * @returns {{ workspace: object, nextSessionId: string | null } | undefined} owning workspace and following sibling.
161
+ * @returns {{ workspace: any, nextSessionId: string | null } | undefined} owning workspace and following sibling.
162
162
  */
163
163
  function findOwningWorkspace(sessionId) {
164
164
  const registry = workspaceRegistry()
@@ -177,7 +177,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
177
177
  }
178
178
 
179
179
  /**
180
- * @param {unknown} target path to probe.
180
+ * @param {any} target path to probe.
181
181
  * @returns {Promise<string>} the entry kind, treating an absent path as missing.
182
182
  */
183
183
  async function kindOf(target) {
@@ -185,15 +185,15 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
185
185
  }
186
186
 
187
187
  /**
188
- * @param {object} entry index entry.
189
- * @returns {object[]} every owned directory, parent first.
188
+ * @param {any} entry index entry.
189
+ * @returns {any[]} every owned directory, parent first.
190
190
  */
191
191
  function membersOf(entry) {
192
192
  return memberList(entry)
193
193
  }
194
194
 
195
195
  /**
196
- * @param {object} entry index entry.
196
+ * @param {any} entry index entry.
197
197
  * @param {number} index member position.
198
198
  * @returns {string} this member's directory inside the trash object.
199
199
  */
@@ -202,7 +202,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
202
202
  }
203
203
 
204
204
  /**
205
- * @param {object} entry trash index entry.
205
+ * @param {any} entry trash index entry.
206
206
  * @returns {Promise<void>} resolution once every member path stays inside `objects/`.
207
207
  */
208
208
  async function assertSafeObject(entry) {
@@ -226,8 +226,8 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
226
226
  * Probe every member directory in parallel: where the source copy and the
227
227
  * trash copy currently live.
228
228
  *
229
- * @param {object} entry index entry.
230
- * @returns {Promise<{ index: number, member: object, source: boolean, trash: boolean }[]>} member positions.
229
+ * @param {any} entry index entry.
230
+ * @returns {Promise<{ index: number, member: any, source: boolean, trash: boolean }[]>} member positions.
231
231
  */
232
232
  async function memberRows(entry) {
233
233
  const members = membersOf(entry)
@@ -251,8 +251,8 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
251
251
  * Probe only the original session directories of every member, in parallel.
252
252
  * Used by recovery after the trash copies were already proven present.
253
253
  *
254
- * @param {object} entry index entry.
255
- * @returns {Promise<{ index: number, member: object, source: boolean }[]>} member source positions.
254
+ * @param {any} entry index entry.
255
+ * @returns {Promise<{ index: number, member: any, source: boolean }[]>} member source positions.
256
256
  */
257
257
  async function sourceRows(entry) {
258
258
  const members = membersOf(entry)
@@ -266,7 +266,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
266
266
  }
267
267
 
268
268
  /**
269
- * @param {object} entry index entry.
269
+ * @param {any} entry index entry.
270
270
  * @param {number} index member position.
271
271
  * @returns {Promise<void>} resolution once the member directory moved into its object.
272
272
  */
@@ -276,7 +276,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
276
276
  }
277
277
 
278
278
  /**
279
- * @param {object} entry index entry.
279
+ * @param {any} entry index entry.
280
280
  * @param {number} index member position.
281
281
  * @returns {Promise<void>} resolution once the member directory moved back to its original location.
282
282
  */
@@ -286,7 +286,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
286
286
  }
287
287
 
288
288
  /**
289
- * @param {object} entry index entry.
289
+ * @param {any} entry index entry.
290
290
  * @param {readonly { index: number }[]} rows members to move into the object.
291
291
  * @returns {Promise<{ index: number, error: unknown }[]>} per-member failures.
292
292
  */
@@ -303,7 +303,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
303
303
  }
304
304
 
305
305
  /**
306
- * @param {object} entry index entry.
306
+ * @param {any} entry index entry.
307
307
  * @param {readonly { index: number }[]} rows members to move back to their original locations.
308
308
  * @returns {Promise<{ index: number, error: unknown }[]>} per-member failures.
309
309
  */
@@ -323,7 +323,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
323
323
  * Move every member directory into the trash object, children first and the
324
324
  * visible parent last so the sidebar keeps the row until the move settles.
325
325
  *
326
- * @param {object} entry index entry.
326
+ * @param {any} entry index entry.
327
327
  * @returns {Promise<void>} resolution once every member directory moved.
328
328
  */
329
329
  async function moveMembersToTrash(entry) {
@@ -337,7 +337,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
337
337
  }
338
338
 
339
339
  /**
340
- * @param {object} entry index entry.
340
+ * @param {any} entry index entry.
341
341
  * @param {number} index member position.
342
342
  * @returns {Promise<void>} resolution once the unusable trash copy is gone.
343
343
  */
@@ -351,7 +351,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
351
351
  }
352
352
 
353
353
  /**
354
- * @param {object} member planned member whose restored copy failed verification.
354
+ * @param {any} member planned member whose restored copy failed verification.
355
355
  * @returns {Promise<void>} resolution once the unusable restored copy is gone.
356
356
  */
357
357
  async function removeRestoredMember(member) {
@@ -363,7 +363,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
363
363
  }
364
364
 
365
365
  /**
366
- * @param {object} entry index entry.
366
+ * @param {any} entry index entry.
367
367
  * @returns {Promise<{ ok: boolean, index?: number, message?: string }>} whether every member landed with its recorded metrics.
368
368
  */
369
369
  async function verifyTrashedMembers(entry) {
@@ -386,7 +386,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
386
386
  }
387
387
 
388
388
  /**
389
- * @param {object} entry index entry.
389
+ * @param {any} entry index entry.
390
390
  * @returns {Promise<{ ok: boolean, index?: number, message?: string }>} whether every member returned with its recorded metrics.
391
391
  */
392
392
  async function verifyRestoredMembers(entry) {
@@ -406,7 +406,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
406
406
  }
407
407
 
408
408
  /**
409
- * @param {object} entry index entry.
409
+ * @param {any} entry index entry.
410
410
  * @returns {Promise<{ hidden: boolean, sessionId?: string }>} whether session storage stopped reporting every member.
411
411
  */
412
412
  async function waitForMembersHidden(entry) {
@@ -421,7 +421,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
421
421
  }
422
422
 
423
423
  /**
424
- * @param {object} entry index entry.
424
+ * @param {any} entry index entry.
425
425
  * @returns {Promise<{ visible: boolean, sessionId?: string }>} whether session storage reports every member again.
426
426
  */
427
427
  async function waitForMembersVisible(entry) {
@@ -440,7 +440,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
440
440
 
441
441
  /**
442
442
  * @param {string} sessionId session to probe.
443
- * @param {(snapshot: object | undefined) => boolean} predicate expected visibility state.
443
+ * @param {(snapshot: any | undefined) => boolean} predicate expected visibility state.
444
444
  * @returns {Promise<boolean>} whether the persistence backend agreed within the retry budget.
445
445
  */
446
446
  async function waitForVisibility(sessionId, predicate) {
@@ -479,8 +479,8 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
479
479
  *
480
480
  * @param {string} sessionId restored session identity.
481
481
  * @param {string} title restored display title.
482
- * @param {object | undefined} snapshot persistence snapshot.
483
- * @returns {object} a `SessionSummary`.
482
+ * @param {any | undefined} snapshot persistence snapshot.
483
+ * @returns {any} a `SessionSummary`.
484
484
  */
485
485
  function buildSummary(sessionId, title, snapshot) {
486
486
  const header = snapshot?.header ?? {}
@@ -501,9 +501,9 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
501
501
  /**
502
502
  * Record a failure summary on one entry and commit it, best effort.
503
503
  *
504
- * @param {object} entry entry to annotate.
504
+ * @param {any} entry entry to annotate.
505
505
  * @param {string} message failure summary.
506
- * @returns {Promise<object>} the annotated entry.
506
+ * @returns {Promise<any>} the annotated entry.
507
507
  */
508
508
  async function markFailure(entry, message) {
509
509
  const next = { ...entry, lastError: errorText(message) }
@@ -521,7 +521,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
521
521
  /**
522
522
  * Restore the workspace accounting after a normal restore.
523
523
  *
524
- * @param {object} entry restored index entry.
524
+ * @param {any} entry restored index entry.
525
525
  * @returns {Promise<{ reattached: boolean, warning?: string }>} reattachment outcome.
526
526
  */
527
527
  async function reattachWorkspace(entry) {
@@ -584,7 +584,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
584
584
  * Remove a session from every workspace that still accounts for it. Used by
585
585
  * orphan restore so the restored log appears under “Ungrouped”.
586
586
  *
587
- * @param {object} entry restored index entry.
587
+ * @param {any} entry restored index entry.
588
588
  * @returns {Promise<{ detached: boolean, warning?: string }>} detach outcome.
589
589
  */
590
590
  async function detachWorkspace(entry) {
@@ -625,7 +625,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
625
625
  *
626
626
  * @param {string} from current path.
627
627
  * @param {string} to previous path.
628
- * @param {object | null | undefined} expected metrics for a cross-device copy.
628
+ * @param {any | null | undefined} expected metrics for a cross-device copy.
629
629
  * @returns {Promise<boolean>} whether the directory now lives at `to`.
630
630
  */
631
631
  async function moveBack(from, to, expected) {
@@ -669,7 +669,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
669
669
  * object or its original location. Never writes the index: the caller owns
670
670
  * the commit so startup recovery can accumulate one write.
671
671
  *
672
- * @param {object} entry `trashing` index entry.
672
+ * @param {any} entry `trashing` index entry.
673
673
  * @returns {Promise<{ kind: 'ready' } | { kind: 'rolledBack' } | { kind: 'missing', entry: object }>} the settled position.
674
674
  */
675
675
  async function resolveTrashing(entry) {
@@ -725,7 +725,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
725
725
  * location, or back into the trash object when the restore cannot complete.
726
726
  * Never writes the index: the caller owns the commit.
727
727
  *
728
- * @param {object} entry `restoring` index entry.
728
+ * @param {any} entry `restoring` index entry.
729
729
  * @returns {Promise<{ kind: 'ready' } | { kind: 'trashed', entry: object } | { kind: 'missing', entry: object }>} the settled position.
730
730
  */
731
731
  async function resolveRestoring(entry) {
@@ -752,6 +752,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
752
752
  row.source = false
753
753
  }
754
754
  }
755
+ /** @returns {{ kind: 'trashed', entry: any }} */
755
756
  const rolledBack = () => ({
756
757
  kind: 'trashed',
757
758
  entry: {
@@ -787,9 +788,9 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
787
788
  }
788
789
 
789
790
  /**
790
- * @param {object} entry settled `trashing` entry.
791
+ * @param {any} entry settled `trashing` entry.
791
792
  * @param {{ emitRemoval?: boolean }} [options] whether to announce the removal to clients.
792
- * @returns {Promise<object>} the committed `trashed` entry.
793
+ * @returns {Promise<any>} the committed `trashed` entry.
793
794
  */
794
795
  async function commitTrashed(entry, options = {}) {
795
796
  const next = { ...entry, state: 'trashed', trashedAt: Date.now(), lastError: null }
@@ -811,9 +812,9 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
811
812
  * Finish a settled restore: wait for visibility, restore workspace
812
813
  * accounting, drop the entry, and optionally announce the session.
813
814
  *
814
- * @param {object} entry settled `restoring` entry.
815
+ * @param {any} entry settled `restoring` entry.
815
816
  * @param {{ mode?: 'normal' | 'orphan', emitAdded?: boolean, reattach?: boolean }} [options] finishing policy.
816
- * @returns {Promise<object>} the workspace attachment outcome.
817
+ * @returns {Promise<any>} the workspace attachment outcome.
817
818
  */
818
819
  async function completeRestore(entry, options = {}) {
819
820
  const mode = options.mode ?? 'normal'
@@ -847,7 +848,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
847
848
  }
848
849
 
849
850
  /**
850
- * @param {object} entry index entry.
851
+ * @param {any} entry index entry.
851
852
  * @param {number} now current timestamp.
852
853
  * @returns {boolean} whether the retention window has elapsed.
853
854
  */
@@ -864,8 +865,8 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
864
865
  * recovery; successes are dropped and failures annotated in one final write.
865
866
  * The caller owns the trash lock.
866
867
  *
867
- * @param {readonly object[]} targets `trashed` entries to purge.
868
- * @returns {Promise<{ purged: number, failures: { entry: object, error: unknown, phase: string }[] }>} per-entry outcome.
868
+ * @param {readonly any[]} targets `trashed` entries to purge.
869
+ * @returns {Promise<{ purged: number, failures: { entry: any, error: unknown, phase: string }[] }>} per-entry outcome.
869
870
  */
870
871
  async function purgeManyInsideLock(targets) {
871
872
  const failures = []
@@ -954,7 +955,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
954
955
  * Permanently remove one object directory and its index entry. The caller
955
956
  * owns the trash lock.
956
957
  *
957
- * @param {object} entry `trashed` index entry to purge.
958
+ * @param {any} entry `trashed` index entry to purge.
958
959
  * @returns {Promise<void>} resolution once the object and entry are gone.
959
960
  */
960
961
  async function purgeInsideLock(entry) {
@@ -967,7 +968,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
967
968
  * their plugin-owned remnants. No session file is deleted. The caller owns
968
969
  * the trash lock.
969
970
  *
970
- * @param {readonly object[]} entries `missing` index entries to forget.
971
+ * @param {readonly any[]} entries `missing` index entries to forget.
971
972
  * @returns {Promise<number>} how many entries were removed from the index.
972
973
  */
973
974
  async function forgetManyInsideLock(entries) {
@@ -993,7 +994,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
993
994
  * Drop one `missing` entry from the index and remove its plugin-owned
994
995
  * remnants. No session file is deleted. The caller owns the trash lock.
995
996
  *
996
- * @param {object} entry `missing` index entry to forget.
997
+ * @param {any} entry `missing` index entry to forget.
997
998
  * @returns {Promise<{ sessionId: string, title: string }>} the removed identity.
998
999
  */
999
1000
  async function forgetInsideLock(entry) {
@@ -1006,7 +1007,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
1006
1007
  * `origin: 'subagent'` descendants moves together with them.
1007
1008
  *
1008
1009
  * @param {string} sessionId session to trash.
1009
- * @returns {Promise<object>} the committed `trashed` entry.
1010
+ * @returns {Promise<any>} the committed `trashed` entry.
1010
1011
  */
1011
1012
  async function trash(sessionId) {
1012
1013
  const startedAt = Date.now()
@@ -1206,7 +1207,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
1206
1207
  *
1207
1208
  * @param {string} sessionId session to restore.
1208
1209
  * @param {'normal' | 'orphan'} [mode] restore mode; orphan restores the log and detaches the Workspace.
1209
- * @returns {Promise<object>} the restore result.
1210
+ * @returns {Promise<any>} the restore result.
1210
1211
  */
1211
1212
  async function restore(sessionId, mode = 'normal') {
1212
1213
  if (mode !== 'normal' && mode !== 'orphan') {
@@ -1471,7 +1472,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
1471
1472
  * object directory vanished. The caller must hold the trash lock.
1472
1473
  *
1473
1474
  * @param {number} now current timestamp.
1474
- * @returns {Promise<object>} reconcile summary.
1475
+ * @returns {Promise<any>} reconcile summary.
1475
1476
  */
1476
1477
  async function reconcileInsideLock(now) {
1477
1478
  try {
@@ -1493,7 +1494,7 @@ export function createTrashService({ ctx, store, eligibility, config, logger, pa
1493
1494
  * entries. Used by startup recovery, the scheduled sweep, and manual cleanup.
1494
1495
  *
1495
1496
  * @param {{ allowPurge?: boolean, now?: number, reason?: string }} [options] sweep policy.
1496
- * @returns {Promise<object>} the sweep summary.
1497
+ * @returns {Promise<any>} the sweep summary.
1497
1498
  */
1498
1499
  async function sweep({ allowPurge = true, now = Date.now(), reason = 'scheduled' } = {}) {
1499
1500
  return store.withLock(async () => {