@yeaft/webchat-agent 0.1.908 → 0.1.910

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.908",
3
+ "version": "0.1.910",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -356,8 +356,11 @@ export function archiveSession(yeaftDir, sessionId) {
356
356
  const groupYeaftDir = resolveSessionYeaftDir(yeaftDir, sessionId);
357
357
  const root = sessionsRoot(groupYeaftDir);
358
358
  const srcDir = join(root, sessionId);
359
+ // Idempotent — nothing on disk, nothing to archive. Workdir-registry is
360
+ // still cleared in case it points at a stale row.
359
361
  if (!existsSync(srcDir) || !loadSessionMeta(srcDir)) {
360
- throw new SessionCrudError('not_found', sessionId);
362
+ unregisterSessionWorkDir(yeaftDir, sessionId);
363
+ return { sessionId, archivedAs: null, alreadyGone: true };
361
364
  }
362
365
  const ts = new Date().toISOString().replace(/[:.]/g, '-');
363
366
  // Append 4 hex chars to disambiguate same-millisecond archives (nit #5).
@@ -365,7 +368,7 @@ export function archiveSession(yeaftDir, sessionId) {
365
368
  const dstDir = join(root, `.archived-${ts}-${suffix}-${sessionId}`);
366
369
  renameSync(srcDir, dstDir);
367
370
  unregisterSessionWorkDir(yeaftDir, sessionId);
368
- return { sessionId, archivedAs: dstDir };
371
+ return { sessionId, archivedAs: dstDir, alreadyGone: false };
369
372
  }
370
373
 
371
374
  /**
@@ -401,10 +404,12 @@ export function deleteSession(yeaftDir, sessionId, options = {}) {
401
404
  }
402
405
  }
403
406
 
404
- if (!liveExists && legacyDirs.length === 0) {
405
- throw new SessionCrudError('not_found', sessionId);
406
- }
407
-
407
+ // Idempotent POSIX `rm -f` / HTTP DELETE semantics. If nothing is on
408
+ // disk, treat as a successful no-op so callers (and any shadow / cache
409
+ // they maintain) can converge to "gone". We still cascade the memory
410
+ // scope and workdir-registry teardown below: a stale `summary.md` left
411
+ // over from a previous incarnation would otherwise contaminate a future
412
+ // recreate of the same id.
408
413
  if (liveExists) {
409
414
  rmSync(srcDir, { recursive: true, force: true });
410
415
  }
@@ -414,6 +419,7 @@ export function deleteSession(yeaftDir, sessionId, options = {}) {
414
419
 
415
420
  // Cascade: drop the group's memory scope so a recreate with the same id
416
421
  // starts clean. Best-effort — never let memory cleanup fail the CRUD op.
422
+ // Runs unconditionally so the idempotent path also clears stale memory.
417
423
  try {
418
424
  removeScopeDirSync({ kind: 'group', id: sessionId }, { root: memoryRoot });
419
425
  } catch (err) {
@@ -421,7 +427,12 @@ export function deleteSession(yeaftDir, sessionId, options = {}) {
421
427
  }
422
428
 
423
429
  unregisterSessionWorkDir(yeaftDir, sessionId);
424
- return { sessionId, deleted: true, legacyCleanedUp: legacyDirs.length };
430
+ return {
431
+ sessionId,
432
+ deleted: liveExists,
433
+ legacyCleanedUp: legacyDirs.length,
434
+ alreadyGone: !liveExists && legacyDirs.length === 0,
435
+ };
425
436
  }
426
437
 
427
438
  /**
@@ -1605,7 +1605,13 @@ export function handleYeaftArchiveSession(msg) {
1605
1605
  const yeaftDir = ctx.CONFIG?.yeaftDir;
1606
1606
  const result = archiveSession(yeaftDir, sessionId);
1607
1607
  invalidateGroupContext(sessionId);
1608
- sendSessionCrudResult({ op: 'archive', requestId, ok: true, sessionId: result.sessionId });
1608
+ sendSessionCrudResult({
1609
+ op: 'archive',
1610
+ requestId,
1611
+ ok: true,
1612
+ sessionId: result.sessionId,
1613
+ alreadyGone: !!result.alreadyGone,
1614
+ });
1609
1615
  sendSessionSnapshotBroadcast();
1610
1616
  } catch (err) {
1611
1617
  sendSessionCrudResult({ op: 'archive', requestId, ok: false, error: sessionErrorPayload(err) });
@@ -1646,6 +1652,7 @@ export function handleYeaftDeleteSession(msg) {
1646
1652
  ok: true,
1647
1653
  sessionId: result.sessionId,
1648
1654
  messagesRemoved,
1655
+ alreadyGone: !!result.alreadyGone,
1649
1656
  });
1650
1657
  sendSessionSnapshotBroadcast();
1651
1658
  } catch (err) {