@yeaft/webchat-agent 0.1.608 → 0.1.609
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.
|
@@ -36,7 +36,7 @@ import { sendToServer, flushMessageBuffer } from './buffer.js';
|
|
|
36
36
|
import { handleRestartAgent, handleUpgradeAgent } from './upgrade.js';
|
|
37
37
|
import { loadMcpServers, updateMcpConfig } from '../mcp.js';
|
|
38
38
|
import { getLlmConfig, updateLlmConfig, getUnifySettings, updateUnifySettings } from '../unify/config-api.js';
|
|
39
|
-
import { handleUnifyChat, handleUnifyGroupChat, handleUnifyModeSwitch, handleUnifyModelSwitch, resetUnifySession, handleUnifyLoadHistory, handleUnifyMergeThread, handleUnifyForkThread, handleUnifyAbortThread, handleUnifyAbortAll, handleUnifyVpSubscribe, handleUnifyVpCreate, handleUnifyVpUpdate, handleUnifyVpDelete, handleUnifyVpRead, handleUnifyTaskMessage, handleUnifyUserMemoryWrite, handleUnifyUserMemoryRemove, handleUnifyMemoryScopeList, handleUnifyMemoryQuery, handleUnifyMemoryTrace, handleUnifyFetchSummaryHistory, handleUnifyTaskCrud, handleUnifyListGroups, handleUnifyCreateGroup, handleUnifyRenameGroup, handleUnifyArchiveGroup, handleUnifyAddMember, handleUnifyRemoveMember, handleUnifySetDefaultVp, handleUnifyDreamTrigger } from '../unify/web-bridge.js';
|
|
39
|
+
import { handleUnifyChat, handleUnifyGroupChat, handleUnifyModeSwitch, handleUnifyModelSwitch, resetUnifySession, handleUnifyLoadHistory, handleUnifyMergeThread, handleUnifyForkThread, handleUnifyAbortThread, handleUnifyAbortAll, handleUnifyVpSubscribe, handleUnifyVpCreate, handleUnifyVpUpdate, handleUnifyVpDelete, handleUnifyVpRead, handleUnifyTaskMessage, handleUnifyUserMemoryWrite, handleUnifyUserMemoryRemove, handleUnifyMemoryScopeList, handleUnifyMemoryQuery, handleUnifyMemoryTrace, handleUnifyFetchSummaryHistory, handleUnifyTaskCrud, handleUnifyListGroups, handleUnifyCreateGroup, handleUnifyRenameGroup, handleUnifyArchiveGroup, handleUnifyDeleteGroup, handleUnifyAddMember, handleUnifyRemoveMember, handleUnifySetDefaultVp, handleUnifyDreamTrigger } from '../unify/web-bridge.js';
|
|
40
40
|
|
|
41
41
|
export async function handleMessage(msg) {
|
|
42
42
|
switch (msg.type) {
|
|
@@ -479,6 +479,9 @@ export async function handleMessage(msg) {
|
|
|
479
479
|
case 'unify_archive_group':
|
|
480
480
|
handleUnifyArchiveGroup(msg);
|
|
481
481
|
break;
|
|
482
|
+
case 'unify_delete_group':
|
|
483
|
+
handleUnifyDeleteGroup(msg);
|
|
484
|
+
break;
|
|
482
485
|
case 'unify_add_member':
|
|
483
486
|
handleUnifyAddMember(msg);
|
|
484
487
|
break;
|
package/package.json
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
* 'reserved'/'invalid_vp_id'/... — bubbled from ids.js validators
|
|
33
33
|
*/
|
|
34
34
|
|
|
35
|
-
import { existsSync, renameSync } from 'fs';
|
|
35
|
+
import { existsSync, renameSync, rmSync, readdirSync, statSync } from 'fs';
|
|
36
36
|
import { randomBytes } from 'crypto';
|
|
37
37
|
import { join } from 'path';
|
|
38
38
|
import {
|
|
@@ -184,6 +184,74 @@ export function archiveGroup(yeaftDir, groupId) {
|
|
|
184
184
|
return { groupId, archivedAs: dstDir };
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
+
/**
|
|
188
|
+
* (A.3.b) Delete — physically remove the group directory and all its
|
|
189
|
+
* contents (group.json, messages/, tasks/, vps/). Irreversible.
|
|
190
|
+
*
|
|
191
|
+
* Bug 8 fix: replaces the soft-archive flow that left `.archived-*` dirs
|
|
192
|
+
* lying around in `~/.yeaft/groups/`. Per user request, "delete" means
|
|
193
|
+
* physical deletion, not rename.
|
|
194
|
+
*
|
|
195
|
+
* Also sweeps any sibling `.archived-*-<groupId>` dirs that were left
|
|
196
|
+
* behind by the previous soft-archive implementation, so a single
|
|
197
|
+
* delete cleans up legacy state too.
|
|
198
|
+
*/
|
|
199
|
+
export function deleteGroup(yeaftDir, groupId) {
|
|
200
|
+
const root = groupsRoot(yeaftDir);
|
|
201
|
+
const srcDir = join(root, groupId);
|
|
202
|
+
const liveExists = existsSync(srcDir) && !!loadGroupMeta(srcDir);
|
|
203
|
+
|
|
204
|
+
// Collect any leftover soft-archive directories matching this groupId.
|
|
205
|
+
const legacyDirs = [];
|
|
206
|
+
if (existsSync(root)) {
|
|
207
|
+
for (const name of readdirSync(root)) {
|
|
208
|
+
if (!name.startsWith('.archived-')) continue;
|
|
209
|
+
// Soft-archive format: .archived-<ts>-<suffix>-<groupId>
|
|
210
|
+
if (!name.endsWith(`-${groupId}`)) continue;
|
|
211
|
+
const p = join(root, name);
|
|
212
|
+
try {
|
|
213
|
+
if (statSync(p).isDirectory()) legacyDirs.push(p);
|
|
214
|
+
} catch { /* skip */ }
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (!liveExists && legacyDirs.length === 0) {
|
|
219
|
+
throw new GroupCrudError('not_found', groupId);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (liveExists) {
|
|
223
|
+
rmSync(srcDir, { recursive: true, force: true });
|
|
224
|
+
}
|
|
225
|
+
for (const dir of legacyDirs) {
|
|
226
|
+
rmSync(dir, { recursive: true, force: true });
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return { groupId, deleted: true, legacyCleanedUp: legacyDirs.length };
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Sweep any leftover `.archived-*` directories under groups/ that are
|
|
234
|
+
* orphans of the old soft-archive flow. Used at boot so users don't see
|
|
235
|
+
* ghost groups in subsequent loads. Returns the list of removed paths.
|
|
236
|
+
*/
|
|
237
|
+
export function purgeArchivedGroups(yeaftDir) {
|
|
238
|
+
const root = groupsRoot(yeaftDir);
|
|
239
|
+
if (!existsSync(root)) return [];
|
|
240
|
+
const removed = [];
|
|
241
|
+
for (const name of readdirSync(root)) {
|
|
242
|
+
if (!name.startsWith('.archived-')) continue;
|
|
243
|
+
const p = join(root, name);
|
|
244
|
+
try {
|
|
245
|
+
if (!statSync(p).isDirectory()) continue;
|
|
246
|
+
} catch { continue; }
|
|
247
|
+
try {
|
|
248
|
+
rmSync(p, { recursive: true, force: true });
|
|
249
|
+
removed.push(p);
|
|
250
|
+
} catch { /* skip */ }
|
|
251
|
+
}
|
|
252
|
+
return removed;
|
|
253
|
+
}
|
|
254
|
+
|
|
187
255
|
/**
|
|
188
256
|
* (A.4) Add a VP to the group roster. Idempotent — no-op if already present.
|
|
189
257
|
* Returns the new meta.
|
|
@@ -151,6 +151,8 @@ export function listGroups(groupsRoot) {
|
|
|
151
151
|
if (!existsSync(groupsRoot)) return [];
|
|
152
152
|
const out = [];
|
|
153
153
|
for (const name of readdirSync(groupsRoot)) {
|
|
154
|
+
// Skip dotfiles and legacy soft-archive dirs (`.archived-*`).
|
|
155
|
+
if (name.startsWith('.')) continue;
|
|
154
156
|
const p = join(groupsRoot, name);
|
|
155
157
|
try {
|
|
156
158
|
if (!statSync(p).isDirectory()) continue;
|
package/unify/groups/index.js
CHANGED
package/unify/web-bridge.js
CHANGED
|
@@ -40,6 +40,8 @@ import {
|
|
|
40
40
|
createGroupFromSpec,
|
|
41
41
|
renameGroup,
|
|
42
42
|
archiveGroup,
|
|
43
|
+
deleteGroup,
|
|
44
|
+
purgeArchivedGroups,
|
|
43
45
|
addMember,
|
|
44
46
|
removeMember,
|
|
45
47
|
setGroupDefaultVp,
|
|
@@ -455,6 +457,23 @@ export function handleUnifyArchiveGroup(msg) {
|
|
|
455
457
|
}
|
|
456
458
|
}
|
|
457
459
|
|
|
460
|
+
/**
|
|
461
|
+
* Bug 8: physical delete — removes the group dir and any legacy
|
|
462
|
+
* `.archived-*-<groupId>` siblings. Replies with op:'delete'.
|
|
463
|
+
*/
|
|
464
|
+
export function handleUnifyDeleteGroup(msg) {
|
|
465
|
+
const requestId = msg && msg.requestId;
|
|
466
|
+
const groupId = msg && msg.groupId;
|
|
467
|
+
try {
|
|
468
|
+
const yeaftDir = ctx.CONFIG?.yeaftDir;
|
|
469
|
+
const result = deleteGroup(yeaftDir, groupId);
|
|
470
|
+
sendGroupCrudResult({ op: 'delete', requestId, ok: true, groupId: result.groupId });
|
|
471
|
+
sendGroupSnapshotBroadcast();
|
|
472
|
+
} catch (err) {
|
|
473
|
+
sendGroupCrudResult({ op: 'delete', requestId, ok: false, error: groupErrorPayload(err) });
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
458
477
|
export function handleUnifyAddMember(msg) {
|
|
459
478
|
const requestId = msg && msg.requestId;
|
|
460
479
|
const groupId = msg && msg.groupId;
|
|
@@ -1370,6 +1389,21 @@ export async function handleUnifyChat(msg) {
|
|
|
1370
1389
|
runAutoArchiveSweep(session);
|
|
1371
1390
|
scheduleAutoArchive(session);
|
|
1372
1391
|
|
|
1392
|
+
// Bug 8: clean up any legacy `.archived-*` group directories left
|
|
1393
|
+
// behind by the previous soft-archive flow. This is a one-shot
|
|
1394
|
+
// boot-time sweep — physical deletes after this point are immediate.
|
|
1395
|
+
try {
|
|
1396
|
+
const yeaftDir = ctx.CONFIG?.yeaftDir;
|
|
1397
|
+
if (yeaftDir) {
|
|
1398
|
+
const removed = purgeArchivedGroups(yeaftDir);
|
|
1399
|
+
if (removed && removed.length > 0) {
|
|
1400
|
+
console.log(`[Unify] purged ${removed.length} legacy .archived group dir(s)`);
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
} catch (err) {
|
|
1404
|
+
console.warn('[Unify] purgeArchivedGroups failed:', err?.message || err);
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1373
1407
|
// Create a stable conversationId for the Unify session
|
|
1374
1408
|
unifyConversationId = `unify-${Date.now()}`;
|
|
1375
1409
|
|