@seamnet/client 0.16.1 → 0.17.0
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 +7 -3
- package/lib/init.js +9 -28
- package/lib/upgrade.js +11 -3
- package/package.json +1 -1
- package/templates/CHANNEL_RULES.md +18 -18
package/lib/guardian.js
CHANGED
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { existsSync, readFileSync, writeFileSync, unlinkSync, mkdirSync, openSync, readlinkSync } from 'node:fs';
|
|
15
|
-
import { join, isAbsolute } from 'node:path';
|
|
15
|
+
import { join, isAbsolute, dirname } from 'node:path';
|
|
16
|
+
import { fileURLToPath } from 'node:url';
|
|
16
17
|
import { execSync, spawn } from 'node:child_process';
|
|
17
18
|
import { SEAM_DIR, CREDENTIALS_PATH, SOCKET_PATH, LOGS_DIR, PID_PATH } from './paths.js';
|
|
18
19
|
import { writeEntry as registryWrite, removeEntry as registryRemove } from './registry.js';
|
|
@@ -101,11 +102,14 @@ export async function guardianStart() {
|
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
const cwd = process.cwd();
|
|
104
|
-
|
|
105
|
+
// guardian-run 进程从 guardian.js 自己所属的包启动(lib/guardian.js → ../bin/cli.js)。
|
|
106
|
+
// 不再相对 cwd 找 node_modules——那样既不支持全局安装(host-tool 模式),
|
|
107
|
+
// cwd 不是项目根时还会崩。模块自解析保证 spawn 出的 guardian 跟当前代码同版本。
|
|
108
|
+
const selfCli = join(dirname(fileURLToPath(import.meta.url)), '..', 'bin', 'cli.js');
|
|
105
109
|
const logPath = join(LOGS_DIR, 'guardian.log');
|
|
106
110
|
const logFd = openSync(logPath, 'a');
|
|
107
111
|
|
|
108
|
-
const child = spawn(process.execPath, [
|
|
112
|
+
const child = spawn(process.execPath, [selfCli, 'guardian', 'run'], {
|
|
109
113
|
cwd,
|
|
110
114
|
detached: true,
|
|
111
115
|
stdio: ['ignore', logFd, logFd],
|
package/lib/init.js
CHANGED
|
@@ -83,10 +83,7 @@ export async function init({ inviteCode, name, apiBase }) {
|
|
|
83
83
|
// Step 8b: Check local install
|
|
84
84
|
checkLocalInstall();
|
|
85
85
|
|
|
86
|
-
// Step
|
|
87
|
-
writeMcpConfig(result);
|
|
88
|
-
|
|
89
|
-
// Step 10: Write .claude/settings.json (pre-authorize MCP + inject SEAM_HOME)
|
|
86
|
+
// Step 10: Write .claude/settings.json (pre-authorize seam CLI + inject SEAM_HOME)
|
|
90
87
|
writeSettings();
|
|
91
88
|
|
|
92
89
|
// Step 10b: Register this SEAM_HOME so `upgrade-all` can find it
|
|
@@ -104,7 +101,7 @@ export async function init({ inviteCode, name, apiBase }) {
|
|
|
104
101
|
Done! You are now on the Seam network.
|
|
105
102
|
|
|
106
103
|
Identity: ${IDENTITY_PATH}
|
|
107
|
-
Tools:
|
|
104
|
+
Tools: \`seam\` CLI (guardian 会在 ~10s 后自动重启 CC)
|
|
108
105
|
|
|
109
106
|
可选 — 开启心跳(定时自唤醒):
|
|
110
107
|
seam self schedule --id heartbeat --every 10m --text-file .seam/heartbeat.md
|
|
@@ -164,27 +161,6 @@ function createSeamDir() {
|
|
|
164
161
|
}
|
|
165
162
|
}
|
|
166
163
|
|
|
167
|
-
function writeMcpConfig(result) {
|
|
168
|
-
const mcpPath = join(process.cwd(), '.mcp.json');
|
|
169
|
-
let mcpConfig = {};
|
|
170
|
-
|
|
171
|
-
if (existsSync(mcpPath)) {
|
|
172
|
-
try {
|
|
173
|
-
mcpConfig = JSON.parse(readFileSync(mcpPath, 'utf8'));
|
|
174
|
-
} catch { /* start fresh */ }
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
178
|
-
|
|
179
|
-
mcpConfig.mcpServers['seam-im'] = {
|
|
180
|
-
command: 'node',
|
|
181
|
-
args: [join(process.cwd(), 'node_modules', '@seamnet', 'client', 'bin', 'cli.js'), 'mcp-serve'],
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2));
|
|
185
|
-
console.log(' .mcp.json updated with seam-im server.');
|
|
186
|
-
}
|
|
187
|
-
|
|
188
164
|
function writeSettings() {
|
|
189
165
|
const settingsDir = join(process.cwd(), '.claude');
|
|
190
166
|
mkdirSync(settingsDir, { recursive: true });
|
|
@@ -198,7 +174,12 @@ function writeSettings() {
|
|
|
198
174
|
} catch { /* start fresh */ }
|
|
199
175
|
}
|
|
200
176
|
|
|
201
|
-
|
|
177
|
+
// pre-authorize seam CLI:AI 用 `seam` 发消息不被权限弹窗打断
|
|
178
|
+
if (!settings.permissions) settings.permissions = {};
|
|
179
|
+
if (!Array.isArray(settings.permissions.allow)) settings.permissions.allow = [];
|
|
180
|
+
if (!settings.permissions.allow.includes('Bash(seam *)')) {
|
|
181
|
+
settings.permissions.allow.push('Bash(seam *)');
|
|
182
|
+
}
|
|
202
183
|
|
|
203
184
|
// host-tool: CC 子进程注入 SEAM_HOME,paths.js 第一级 fallback 命中
|
|
204
185
|
if (!settings.env) settings.env = {};
|
|
@@ -226,7 +207,7 @@ function writeSettings() {
|
|
|
226
207
|
}
|
|
227
208
|
|
|
228
209
|
writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
229
|
-
console.log(`
|
|
210
|
+
console.log(` seam CLI pre-authorized (Bash(seam *)) + env.SEAM_HOME=${SEAM_DIR} + SessionStart hook wired.`);
|
|
230
211
|
}
|
|
231
212
|
|
|
232
213
|
function registerSeamHome() {
|
package/lib/upgrade.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 做:
|
|
5
5
|
* 1. npm install @seamnet/client@latest
|
|
6
|
-
* 2. patch .claude/settings.json
|
|
6
|
+
* 2. patch .claude/settings.json:SessionStart hook 命令(老包名 → bin 名)
|
|
7
|
+
* + 预授权 seam CLI(permissions.allow 加 Bash(seam *))
|
|
7
8
|
* 3. 重新 patchClaudeMd(确保引用 @.seam/contacts.json 等新增的)
|
|
8
9
|
* 4. 重启 guardian(新 detached 后台进程 + 单 seam MCP tool 生效)
|
|
9
10
|
*
|
|
@@ -56,11 +57,18 @@ export async function upgrade() {
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
}
|
|
60
|
+
// 预授权 seam CLI:老 AI 升级后用 `seam` 发消息的路径立刻可用
|
|
61
|
+
if (!s.permissions) s.permissions = {};
|
|
62
|
+
if (!Array.isArray(s.permissions.allow)) s.permissions.allow = [];
|
|
63
|
+
if (!s.permissions.allow.includes('Bash(seam *)')) {
|
|
64
|
+
s.permissions.allow.push('Bash(seam *)');
|
|
65
|
+
changed = true;
|
|
66
|
+
}
|
|
59
67
|
if (changed) {
|
|
60
68
|
writeFileSync(settingsPath, JSON.stringify(s, null, 2));
|
|
61
|
-
console.log(' hook command
|
|
69
|
+
console.log(' settings.json patched (hook command + seam CLI 预授权 Bash(seam *))');
|
|
62
70
|
} else {
|
|
63
|
-
console.log('
|
|
71
|
+
console.log(' settings.json already up-to-date, skip');
|
|
64
72
|
}
|
|
65
73
|
} catch (e) {
|
|
66
74
|
console.error(` failed to patch settings.json: ${e.message}`);
|
package/package.json
CHANGED
|
@@ -7,39 +7,39 @@
|
|
|
7
7
|
收到消息时**看前缀决定怎么回**。回错通道对方就看不到。
|
|
8
8
|
|
|
9
9
|
- **无前缀** → 终端里的直接输入。在终端回(普通文字)。
|
|
10
|
-
- **有前缀,形如 `[... → seam msg send]`** → 远端消息,用 `seam`
|
|
10
|
+
- **有前缀,形如 `[... → seam msg send]`** → 远端消息,用 `seam` 命令行工具回(在 Bash 里跑)。
|
|
11
11
|
|
|
12
|
-
## 前缀 →
|
|
12
|
+
## 前缀 → 命令对照表
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
所有远端消息都用同一个命令行工具 `seam`,子命令不同。直接在 Bash 里执行:
|
|
15
15
|
|
|
16
|
-
| 前缀 | 通道 |
|
|
16
|
+
| 前缀 | 通道 | 回复方式(Bash) |
|
|
17
17
|
|---|---|---|
|
|
18
18
|
| (无) | 终端 | 直接答 |
|
|
19
|
-
| `💬 [Seam HH:mm → seam msg send] sender:` | Seam IM 私聊 | `seam
|
|
20
|
-
| `💬 [Seam群 HH:mm <groupId> → seam msg group] sender:` | Seam 群 | `seam
|
|
19
|
+
| `💬 [Seam HH:mm → seam msg send] sender:` | Seam IM 私聊 | `seam msg send --to <sender的userId> --text "回复内容"` |
|
|
20
|
+
| `💬 [Seam群 HH:mm <groupId> → seam msg group] sender:` | Seam 群 | `seam msg group --group <groupId> --text "回复内容"` |
|
|
21
21
|
| `💬 [Seam图片 ...]` | Seam 图片到达 | 回文本同上;发图用 `--image <path>` |
|
|
22
22
|
| `💬 [Seam文件 ...]` | Seam 文件到达 | 回文本同上;发文件用 `--file <path>` |
|
|
23
|
-
| `📱 [微信 HH:mm → seam wechat send] sender:` | 微信文本 | `seam
|
|
23
|
+
| `📱 [微信 HH:mm → seam wechat send] sender:` | 微信文本 | `seam wechat send --text "回复内容"` |
|
|
24
24
|
| `📱 [微信图片 ...]` | 微信图片到达 | 回文本同上;发图用 `--image <path>` |
|
|
25
25
|
|
|
26
26
|
## 发图/发文件
|
|
27
27
|
|
|
28
28
|
| 用途 | 命令 |
|
|
29
29
|
|---|---|
|
|
30
|
-
| IM 私聊发图 | `seam
|
|
31
|
-
| IM 私聊发文件 | `seam
|
|
32
|
-
| IM 群发图 | `seam
|
|
33
|
-
| IM 群发文件 | `seam
|
|
34
|
-
| 微信发图 | `seam
|
|
35
|
-
| 微信发文件 | `seam
|
|
30
|
+
| IM 私聊发图 | `seam msg send --to <userId> --image <path>` |
|
|
31
|
+
| IM 私聊发文件 | `seam msg send --to <userId> --file <path>` |
|
|
32
|
+
| IM 群发图 | `seam msg group --group <groupId> --image <path>` |
|
|
33
|
+
| IM 群发文件 | `seam msg group --group <groupId> --file <path>` |
|
|
34
|
+
| 微信发图 | `seam wechat send --image <path>` |
|
|
35
|
+
| 微信发文件 | `seam wechat send --file <path>` |
|
|
36
36
|
|
|
37
37
|
`path` 本地绝对路径。`.seam/inbox/` 里收到的文件可以直接转发。
|
|
38
38
|
|
|
39
39
|
## 长文本
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
`seam
|
|
41
|
+
如果回复内容包含换行或复杂字符,先写入临时文件再用 `--text-file`:
|
|
42
|
+
`seam msg send --to <userId> --text-file /tmp/reply.txt`
|
|
43
43
|
|
|
44
44
|
## 文件处理
|
|
45
45
|
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
|
|
50
50
|
## 心跳和定时任务
|
|
51
51
|
|
|
52
|
-
查看/调整心跳:`seam
|
|
53
|
-
改心跳间隔:`seam
|
|
52
|
+
查看/调整心跳:`seam self list`
|
|
53
|
+
改心跳间隔:`seam self schedule --id heartbeat --every 5m`
|
|
54
54
|
|
|
55
55
|
## 系统账号 Needle
|
|
56
56
|
|
|
@@ -68,4 +68,4 @@ npx -p @seamnet/client@latest seam-client upgrade
|
|
|
68
68
|
|
|
69
69
|
## 发现更多能力
|
|
70
70
|
|
|
71
|
-
`seam
|
|
71
|
+
`seam --help` 查看所有可用命令。
|