@seamnet/client 0.16.0 → 0.16.1

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/lib/guardian.js CHANGED
@@ -89,10 +89,16 @@ export async function guardianStart() {
89
89
  const socketPath = resolveTmuxSocketPath();
90
90
  const tmux = tmuxCmd(socketPath);
91
91
 
92
- let ccSession = '';
93
- try {
94
- ccSession = execSync(`${tmux} display-message -p '#S'`, { encoding: 'utf8' }).trim();
95
- } catch {}
92
+ // SEAM_CC_SESSION env 优先:upgrade-all / 跨 shell 启动时,调用方知道目标 AI
93
+ // 的 tmux session,直接传过来;不传才回退到 `tmux display-message`(取 attached
94
+ // client session)。回退在跨 shell 场景下会拿错 session——比如缝在自己的 tmux
95
+ // 里跑 `cd /home/claude_code/du && seam-client upgrade`,会把"缝"写进渡的 registry。
96
+ let ccSession = process.env.SEAM_CC_SESSION || '';
97
+ if (!ccSession) {
98
+ try {
99
+ ccSession = execSync(`${tmux} display-message -p '#S'`, { encoding: 'utf8' }).trim();
100
+ } catch {}
101
+ }
96
102
 
97
103
  const cwd = process.cwd();
98
104
  const localCli = join(cwd, 'node_modules', '@seamnet', 'client', 'bin', 'cli.js');
@@ -3,18 +3,22 @@
3
3
  *
4
4
  * 流程:
5
5
  * 1. 全局升 npm 包(仅一次)
6
- * 2. 读 ~/.seam-homes,遍历每个 SEAM_HOME
7
- * 3. 每个 SEAM_HOME spawn 子进程 stop → start guardian(隔离 paths.js 缓存)
8
- * 4. 清掉目录已不存在的 entry
6
+ * 2. 读 ~/.shared/seam-registry/*.json(当前在跑的 guardian 列表)
7
+ * 3. 每个 entry spawn 子进程 stop → start guardian
8
+ * (SEAM_HOME / SEAM_CC_SESSION / SEAM_CC_SOCKET 从 entry 取,
9
+ * 避免 guardianStart 回退到 `tmux display-message` 抓错 attached client。)
9
10
  *
10
- * 注:本文件是 stage 1 的 registry 实现;stage 2 会替换为 ~/.shared/seam-registry/<userId>.json。
11
+ * 仅升级"当前在跑的 guardian"——目录还在但 guardian 没开的,跳过。
12
+ * 想拉那些上来,下次自己 `seam-client guardian start` 即可,
13
+ * 那时已是新版 npm 包。
14
+ *
15
+ * 路人 CC(没装 seam-client / 没 register)天然不在 registry,不会被碰。
11
16
  */
12
17
 
13
- import { existsSync, readFileSync, writeFileSync } from 'node:fs';
14
18
  import { join, dirname } from 'node:path';
15
- import { homedir } from 'node:os';
16
19
  import { execSync, spawnSync } from 'node:child_process';
17
20
  import { fileURLToPath } from 'node:url';
21
+ import { readAll } from './registry.js';
18
22
 
19
23
  const __filename = fileURLToPath(import.meta.url);
20
24
  const CLI_PATH = join(dirname(__filename), '..', 'bin', 'cli.js');
@@ -30,38 +34,35 @@ export async function upgradeAll() {
30
34
  process.exit(1);
31
35
  }
32
36
 
33
- const homesPath = join(homedir(), '.seam-homes');
34
- if (!existsSync(homesPath)) {
35
- console.log('\n2. ~/.seam-homes 不存在——无已注册 AI,结束。');
37
+ const entries = readAll();
38
+ if (entries.length === 0) {
39
+ console.log('\n2. registry 为空——没有正在运行的 guardian,结束。');
36
40
  return;
37
41
  }
38
- const lines = readFileSync(homesPath, 'utf8').split('\n').filter(Boolean);
39
- console.log(`\n2. ${lines.length} 个已注册 SEAM_HOME,逐个重启 guardian`);
42
+ console.log(`\n2. registry ${entries.length} 个活 guardian,逐个重启`);
40
43
 
41
- const alive = [];
42
- for (const home of lines) {
43
- console.log(`\n → ${home}`);
44
- if (!existsSync(home)) {
45
- console.log(' 跳过(目录已不存在,从 registry 移除)');
46
- continue;
47
- }
48
- const env = { ...process.env, SEAM_HOME: home };
44
+ let okCount = 0;
45
+ for (const entry of entries) {
46
+ const { userId, seam_home, tmux_session, tmux_socket } = entry;
47
+ console.log(`\n → ${userId} (home=${seam_home}, session=${tmux_session || '?'})`);
48
+
49
+ const env = {
50
+ ...process.env,
51
+ SEAM_HOME: seam_home,
52
+ SEAM_CC_SESSION: tmux_session || '',
53
+ SEAM_CC_SOCKET: tmux_socket || '',
54
+ };
49
55
  const stopRes = spawnSync('node', [CLI_PATH, 'stop'], { env, stdio: 'inherit' });
50
56
  if (stopRes.status !== 0) {
51
- console.log(' stop 非零退出(guardian 可能未运行,继续)');
57
+ console.log(' stop 非零退出(继续)');
52
58
  }
53
59
  const startRes = spawnSync('node', [CLI_PATH, 'guardian', 'start'], { env, stdio: 'inherit' });
54
60
  if (startRes.status !== 0) {
55
61
  console.error(` start 失败 (exit ${startRes.status})`);
56
62
  } else {
57
- alive.push(home);
63
+ okCount += 1;
58
64
  }
59
65
  }
60
66
 
61
- if (alive.length !== lines.length) {
62
- writeFileSync(homesPath, alive.length ? alive.join('\n') + '\n' : '');
63
- console.log(`\n registry 清理:${lines.length} → ${alive.length}`);
64
- }
65
-
66
- console.log(`\nDone. ${alive.length} 个 AI guardian 已重启。`);
67
+ console.log(`\nDone. ${okCount}/${entries.length} guardian 已重启。`);
67
68
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seamnet/client",
3
- "version": "0.16.0",
3
+ "version": "0.16.1",
4
4
  "description": "One command to join Seam — the network where people and AI stay in sync.",
5
5
  "bin": {
6
6
  "seam-client": "bin/cli.js",