u-foo 2.2.1 → 2.2.3

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": "u-foo",
3
- "version": "2.2.1",
3
+ "version": "2.2.3",
4
4
  "description": "Multi-Agent Workspace Protocol. Just add u. claude → uclaude, codex → ucodex.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://ufoo.dev",
package/src/bus/store.js CHANGED
@@ -15,19 +15,6 @@ function readQueueTty(queueDir) {
15
15
  }
16
16
  }
17
17
 
18
- function nicknamePrefixForType(agentType = "") {
19
- return agentType === "claude-code" ? "claude"
20
- : agentType === "ufoo-code" ? "ucode"
21
- : String(agentType || "agent");
22
- }
23
-
24
- function isRecoverableSessionId(sessionId = "") {
25
- const text = String(sessionId || "").trim();
26
- if (!text) return false;
27
- if (text.includes(":") || text.includes("_")) return false;
28
- return true;
29
- }
30
-
31
18
  function buildUsedNicknameSet(agents = {}) {
32
19
  const set = new Set();
33
20
  for (const meta of Object.values(agents || {})) {
@@ -38,15 +25,6 @@ function buildUsedNicknameSet(agents = {}) {
38
25
  return set;
39
26
  }
40
27
 
41
- function allocateRecoveredNickname(agentType, used) {
42
- const prefix = nicknamePrefixForType(agentType);
43
- let idx = 1;
44
- while (used.has(`${prefix}-${idx}`)) idx += 1;
45
- const nick = `${prefix}-${idx}`;
46
- used.add(nick);
47
- return nick;
48
- }
49
-
50
28
  function recoverQueueEntry(data, subscriber, queueDir, usedNicknames, now) {
51
29
  if (!subscriber || data.agents[subscriber]) return false;
52
30
 
@@ -67,31 +45,7 @@ function recoverQueueEntry(data, subscriber, queueDir, usedNicknames, now) {
67
45
  };
68
46
  return true;
69
47
  }
70
-
71
- const parts = subscriber.split(":");
72
- if (parts.length !== 2) return false;
73
- const [agentType, sessionId] = parts;
74
- if (!agentType || !sessionId) return false;
75
- if (!isRecoverableSessionId(sessionId)) return false;
76
-
77
- const tty = readQueueTty(queueDir);
78
- const ttyInfo = tty ? getTtyProcessInfo(tty) : null;
79
- const activeByTty = Boolean(ttyInfo && ttyInfo.alive && ttyInfo.hasAgent);
80
- const nickname = activeByTty ? allocateRecoveredNickname(agentType, usedNicknames) : "";
81
-
82
- data.agents[subscriber] = {
83
- agent_type: agentType,
84
- nickname,
85
- status: activeByTty ? "active" : "inactive",
86
- joined_at: now,
87
- last_seen: now,
88
- pid: 0,
89
- tty,
90
- tty_shell_pid: ttyInfo && ttyInfo.shellPid ? ttyInfo.shellPid : 0,
91
- tmux_pane: "",
92
- launch_mode: "",
93
- };
94
- return true;
48
+ return false;
95
49
  }
96
50
 
97
51
  function reconcileReservedControllerAliases(data, now) {
@@ -98,6 +98,30 @@ class SubscriberManager {
98
98
  this.queueManager = queueManager;
99
99
  }
100
100
 
101
+ cleanupSubscriberArtifacts(subscriber) {
102
+ if (!subscriber || !this.queueManager) return;
103
+ try {
104
+ const queueDir = this.queueManager.getQueueDir
105
+ ? this.queueManager.getQueueDir(subscriber)
106
+ : "";
107
+ if (queueDir) {
108
+ fs.rmSync(queueDir, { recursive: true, force: true });
109
+ }
110
+ } catch {
111
+ // ignore cleanup errors
112
+ }
113
+ try {
114
+ const offsetPath = this.queueManager.getOffsetPath
115
+ ? this.queueManager.getOffsetPath(subscriber)
116
+ : "";
117
+ if (offsetPath) {
118
+ fs.rmSync(offsetPath, { force: true });
119
+ }
120
+ } catch {
121
+ // ignore cleanup errors
122
+ }
123
+ }
124
+
101
125
  async cleanupDuplicateTty(currentSubscriber, ttyPath) {
102
126
  if (!ttyPath) return null;
103
127
  if (!this.busData.agents) return null;
@@ -301,6 +325,7 @@ class SubscriberManager {
301
325
  this.busData.agents[subscriber].status = "inactive";
302
326
  this.busData.agents[subscriber].activity_state = "";
303
327
  this.busData.agents[subscriber].last_seen = getTimestamp();
328
+ this.cleanupSubscriberArtifacts(subscriber);
304
329
 
305
330
  return true;
306
331
  }
@@ -364,6 +389,7 @@ class SubscriberManager {
364
389
  meta.status = "inactive";
365
390
  meta.activity_state = "";
366
391
  meta.last_seen = getTimestamp();
392
+ this.cleanupSubscriberArtifacts(id);
367
393
  }
368
394
  }
369
395
  }
package/src/daemon/ops.js CHANGED
@@ -1086,25 +1086,12 @@ function getRecoverableAgents(projectRoot, target = "") {
1086
1086
  }
1087
1087
 
1088
1088
  async function resumeAgents(projectRoot, target = "", processManager = null) {
1089
- const filePath = getUfooPaths(projectRoot).agentsFile;
1090
1089
  const { mode, data, recoverableEntries, skipped } = collectRecoverableAgents(projectRoot, target);
1091
1090
 
1092
1091
  if (recoverableEntries.length === 0) {
1093
1092
  return { ok: true, resumed: [], skipped };
1094
1093
  }
1095
1094
 
1096
- // Clear old nicknames to allow reuse.
1097
- let updated = false;
1098
- for (const item of recoverableEntries) {
1099
- if (item.meta && item.meta.nickname) {
1100
- data.agents[item.id] = { ...item.meta, nickname: "" };
1101
- updated = true;
1102
- }
1103
- }
1104
- if (updated) {
1105
- saveAgentsData(filePath, data);
1106
- }
1107
-
1108
1095
  const resumed = [];
1109
1096
  for (const item of recoverableEntries) {
1110
1097
  const nickname = item.meta.nickname || "";