@clawos-dev/clawd 0.2.501 → 0.2.502

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 (2) hide show
  1. package/dist/cli.cjs +64 -3
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -47077,6 +47077,7 @@ var SessionRunner = class {
47077
47077
  break;
47078
47078
  }
47079
47079
  case "delete-file":
47080
+ this.pendingFileEdits.clear();
47080
47081
  try {
47081
47082
  this.hooks.store.delete(this.state.file.sessionId);
47082
47083
  } catch (err) {
@@ -48176,13 +48177,20 @@ var SessionManager = class {
48176
48177
  for (const file of this.listAllOwned()) {
48177
48178
  if (file.ephemeral) {
48178
48179
  this.deleteOwned(file.sessionId);
48180
+ this.afterSessionDeleted(this.scopeForFile(file), file.sessionId);
48179
48181
  this.deps.logger?.info?.(`swept ephemeral session ${file.sessionId}`);
48180
48182
  }
48181
48183
  }
48182
48184
  }
48185
+ // SessionFile 之外还挂着的东西(群文件清单)在这里收。每条删除路径删完文件都要过一遍,
48186
+ // 不管是 reducer 的 delete-file effect 删的还是 store.delete 直接删的。
48187
+ afterSessionDeleted(scope, sessionId) {
48188
+ this.deps.attachmentGroup?.onSessionDeleted({ scope, sessionId });
48189
+ }
48183
48190
  delete(args) {
48184
48191
  const existing = this.findOwnedSession(args.sessionId);
48185
48192
  if (!existing) throw new ClawdError(ERROR_CODES.SESSION_NOT_FOUND, args.sessionId);
48193
+ const scope = this.scopeForFile(existing);
48186
48194
  const runner = this.runners.get(args.sessionId);
48187
48195
  if (runner) {
48188
48196
  const { broadcast } = this.withCollector(() => {
@@ -48192,9 +48200,11 @@ var SessionManager = class {
48192
48200
  this.realUuidBySynth.delete(args.sessionId);
48193
48201
  this.lastUiSizeBySessionId.delete(args.sessionId);
48194
48202
  this.clearPendingTurnEnd(args.sessionId);
48203
+ this.afterSessionDeleted(scope, args.sessionId);
48195
48204
  return { response: { sessionId: args.sessionId }, broadcast };
48196
48205
  }
48197
48206
  this.deleteOwned(args.sessionId);
48207
+ this.afterSessionDeleted(scope, args.sessionId);
48198
48208
  return {
48199
48209
  response: { sessionId: args.sessionId },
48200
48210
  broadcast: [
@@ -48823,9 +48833,11 @@ var SessionManager = class {
48823
48833
  this.realUuidBySynth.delete(args.sessionId);
48824
48834
  this.lastUiSizeBySessionId.delete(args.sessionId);
48825
48835
  this.clearPendingTurnEnd(args.sessionId);
48836
+ this.afterSessionDeleted(args.scope, args.sessionId);
48826
48837
  return { response: { sessionId: args.sessionId }, broadcast };
48827
48838
  }
48828
48839
  this.storeFor(args.scope).delete(args.sessionId);
48840
+ this.afterSessionDeleted(args.scope, args.sessionId);
48829
48841
  return {
48830
48842
  response: { sessionId: args.sessionId },
48831
48843
  broadcast: [
@@ -51039,11 +51051,12 @@ var PersonaManager = class {
51039
51051
  * 删除 persona。
51040
51052
  * PersonaStore.remove(personaId) 级联删整个 <personaRoot>/<personaId>/ 目录
51041
51053
  * (含 .clawd/sessions/owner/ 和 .clawd/sessions/guests/<capId>/),rmSync
51042
- * recursive force 一锅清。
51054
+ * recursive force 一锅清。目录外的那份(群文件清单)交给 onPersonaDeleted。
51043
51055
  */
51044
51056
  delete(personaId2) {
51045
51057
  this.deps.store.remove(personaId2);
51046
51058
  this.deps.registry.remove(personaId2);
51059
+ this.deps.onPersonaDeleted?.(personaId2);
51047
51060
  }
51048
51061
  };
51049
51062
 
@@ -62852,6 +62865,34 @@ var GroupFileStore = class {
62852
62865
  this.cache.set(this.cacheKey(scope, sessionId), { entries });
62853
62866
  return true;
62854
62867
  }
62868
+ /**
62869
+ * 会话删除时的收尾:整份清单文件删掉、cache 一起清。
62870
+ *
62871
+ * 清单跟 SessionFile 不在一个目录(这里在 <dataDir>/sessions/…,persona 会话的 SessionFile
62872
+ * 在 persona 目录下),SessionStore.delete 带不走它——不收这一下就留一个孤儿文件。
62873
+ * 没清单的会话(绝大多数)是 noop。
62874
+ */
62875
+ deleteSession(scope, sessionId) {
62876
+ try {
62877
+ import_node_fs45.default.unlinkSync(this.filePath(scope, sessionId));
62878
+ } catch (err) {
62879
+ if (err?.code !== "ENOENT") throw err;
62880
+ }
62881
+ this.cache.delete(this.cacheKey(scope, sessionId));
62882
+ }
62883
+ /**
62884
+ * persona 删除时的收尾:它名下(owner + 每个 guest capId)的清单整棵树删掉,cache 一起清。
62885
+ *
62886
+ * persona 目录 `rm -rf` 带不走这棵树——清单在 `<dataDir>/sessions/<personaId>/…`,
62887
+ * 不在 persona 目录里(见文件头的路径约定)。没树的 persona 是 noop。
62888
+ */
62889
+ deletePersona(personaId2) {
62890
+ import_node_fs45.default.rmSync(import_node_path51.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
62891
+ const prefix = `persona:${personaId2}:`;
62892
+ for (const key of this.cache.keys()) {
62893
+ if (key.startsWith(prefix)) this.cache.delete(key);
62894
+ }
62895
+ }
62855
62896
  };
62856
62897
 
62857
62898
  // src/discovery/state-file.ts
@@ -66467,7 +66508,7 @@ function computeMethodAccess(args) {
66467
66508
  }
66468
66509
 
66469
66510
  // src/version.ts
66470
- var version = "0.2.501".length > 0 ? "0.2.501" : "dev";
66511
+ var version = "0.2.502".length > 0 ? "0.2.502" : "dev";
66471
66512
 
66472
66513
  // src/cli-probe/probe.ts
66473
66514
  var fs76 = __toESM(require("fs"), 1);
@@ -71027,6 +71068,17 @@ async function startDaemon(config) {
71027
71068
  err: err.message
71028
71069
  });
71029
71070
  }
71071
+ },
71072
+ // 会话删了清单一起删。删不掉只记 warn:会话本体已经没了,不能因为一个附属文件把删除报成失败
71073
+ onSessionDeleted: (input) => {
71074
+ try {
71075
+ groupFileStore.deleteSession(input.scope, input.sessionId);
71076
+ } catch (err) {
71077
+ logger.warn("attachment.onSessionDeleted failed", {
71078
+ sessionId: input.sessionId,
71079
+ err: err.message
71080
+ });
71081
+ }
71030
71082
  }
71031
71083
  }
71032
71084
  });
@@ -71182,7 +71234,16 @@ async function startDaemon(config) {
71182
71234
  const personaManager = new PersonaManager({
71183
71235
  store: personaStore,
71184
71236
  registry: personaRegistry,
71185
- sessionManager: manager
71237
+ sessionManager: manager,
71238
+ // persona 目录外的群文件清单树(<dataDir>/sessions/<pid>/)一起收。收不掉只 warn:
71239
+ // persona 本体已经没了,不能因为一棵附属目录把删除报成失败
71240
+ onPersonaDeleted: (personaId2) => {
71241
+ try {
71242
+ groupFileStore.deletePersona(personaId2);
71243
+ } catch (err) {
71244
+ logger.warn("attachment.onPersonaDeleted failed", { personaId: personaId2, err: err.message });
71245
+ }
71246
+ }
71186
71247
  });
71187
71248
  let currentTunnelUrl = null;
71188
71249
  const getHttpBaseUrl = () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.501",
3
+ "version": "0.2.502",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",