@mzzsfy/dsh-session-manager 0.9.3 → 0.9.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.
@@ -26,6 +26,8 @@ import {
26
26
  projectDeletedRows,
27
27
  removeDeletedEntry,
28
28
  selectArchiveCandidates,
29
+ UNARCHIVE_GRACE_MS,
30
+ unarchiveGraceActive,
29
31
  updatedAtOf,
30
32
  workspaceTitleForSession,
31
33
  workspaceTitleOf,
@@ -80,6 +82,18 @@ test('阈值负值与非有限值防御性关闭', () => {
80
82
  assert.deepEqual(selectArchiveCandidates({ records: [record({})], nowMs: NOW, thresholdDays: Number.NaN }), [])
81
83
  })
82
84
 
85
+ test('全局宽限:取消归档后 graceMs 内宽限生效,到期与非法输入失效', () => {
86
+ assert.equal(unarchiveGraceActive(NOW - 2 * 60 * 1000, NOW), true)
87
+ assert.equal(unarchiveGraceActive(NOW - UNARCHIVE_GRACE_MS, NOW), false)
88
+ assert.equal(unarchiveGraceActive(0, NOW), false)
89
+ assert.equal(unarchiveGraceActive(undefined, NOW), false)
90
+ assert.equal(unarchiveGraceActive(Number.NaN, NOW), false)
91
+ })
92
+
93
+ test('全局宽限:常量与天级时长的量级自洽', () => {
94
+ assert.equal(UNARCHIVE_GRACE_MS, 10 * 60 * 1000)
95
+ })
96
+
83
97
  test('updatedAt 取创建时间与最近活跃的较大者', () => {
84
98
  assert.equal(updatedAtOf({ createdAt: 100 }, 50), 100)
85
99
  assert.equal(updatedAtOf({ createdAt: 100 }, 500), 500)
@@ -76,7 +76,7 @@ function makeDomain(initialIds) {
76
76
  // 台账域句柄;openRejected 模拟台账域打开失败
77
77
  function makeLedgerDomain(entries) {
78
78
  const domain = {
79
- state: { deleted: entries },
79
+ state: { deleted: entries, unarchivedAt: 0 },
80
80
  writes: 0,
81
81
  global: {
82
82
  get: () => domain.state,
@@ -481,6 +481,40 @@ test('取消归档路由:快照领先域时补全清理(重试路径)', skipMiss
481
481
  assert.deepEqual(registry.state.archivedSessionIds, [])
482
482
  })
483
483
 
484
+ test('取消归档宽限:恢复后 graceMs 内同进程评估暂停,不秒归档', skipMissingDeps, async () => {
485
+ const dir = await mkdtemp(path.join(tmpdir(), 'sm-grace-'))
486
+ try {
487
+ const artifact = path.join(dir, 's1.jsonl')
488
+ await writeFile(artifact, '{"header":1}\n{"event":0}\n')
489
+ const DAY_MS = 24 * 60 * 60 * 1000
490
+ const stale = Date.now() - 30 * DAY_MS
491
+ await utimes(artifact, stale / 1000, stale / 1000)
492
+ const headers = [{ id: 's1', cwd: 'C:\\x', createdAt: stale }]
493
+ const ctxBundle = makeCtx({
494
+ archivedIds: [],
495
+ headers,
496
+ agents: new Map(),
497
+ sessionPersistence: { locate: () => ({ path: artifact }) },
498
+ domain: makeDomain([]),
499
+ })
500
+ const { activateSettings, registry, handlers, eventHandlers } = ctxBundle
501
+ activateSettings()
502
+ await waitFor(() => registry.archiveCalls.length > 0)
503
+ assert.deepEqual(registry.archiveCalls, ['s1'])
504
+ // 手动恢复:归档集合移除 + 进程内宽限生效
505
+ const res = response()
506
+ await handlers.get('/api/session-manager/unarchive')(request('s1'), res)
507
+ assert.equal(res.status, 200)
508
+ assert.deepEqual(registry.state.archivedSessionIds, [])
509
+ // 宽限内经新会话创建触发评估:同产物仍超期,但不再归档
510
+ eventHandlers['session/created']({ header: { cwd: 'C:\\x' } })
511
+ await new Promise((resolve) => setTimeout(resolve, 80))
512
+ assert.deepEqual(registry.archiveCalls, ['s1'], '宽限期内不得重新归档')
513
+ } finally {
514
+ await rm(dir, { recursive: true, force: true })
515
+ }
516
+ })
517
+
484
518
  test('info 路由:会话不存在拒绝', skipMissingDeps, async () => {
485
519
  const { handlers } = makeCtx({ archivedIds: [], headers: [], agents: new Map() })
486
520
  const res = response()