wezard 0.3.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.
Files changed (117) hide show
  1. package/.claude-plugin/marketplace.json +14 -0
  2. package/.claude-plugin/plugin.json +14 -0
  3. package/CLAUDE.md +83 -0
  4. package/LICENSE +21 -0
  5. package/README.md +410 -0
  6. package/cli/weclaude.sh +236 -0
  7. package/commands/audit.md +7 -0
  8. package/commands/wrc.md +7 -0
  9. package/config.example.jsonc +102 -0
  10. package/dist/cli/audit.js +156 -0
  11. package/dist/cli/audit.js.map +1 -0
  12. package/dist/cli/init.js +311 -0
  13. package/dist/cli/init.js.map +1 -0
  14. package/dist/cli/sync.js +175 -0
  15. package/dist/cli/sync.js.map +1 -0
  16. package/dist/daemon/approval.js +1301 -0
  17. package/dist/daemon/approval.js.map +1 -0
  18. package/dist/daemon/ask.js +101 -0
  19. package/dist/daemon/ask.js.map +1 -0
  20. package/dist/daemon/audit.js +168 -0
  21. package/dist/daemon/audit.js.map +1 -0
  22. package/dist/daemon/cc-bridge.js +204 -0
  23. package/dist/daemon/cc-bridge.js.map +1 -0
  24. package/dist/daemon/cfg-sync.js +240 -0
  25. package/dist/daemon/cfg-sync.js.map +1 -0
  26. package/dist/daemon/claim.js +95 -0
  27. package/dist/daemon/claim.js.map +1 -0
  28. package/dist/daemon/detail.js +153 -0
  29. package/dist/daemon/detail.js.map +1 -0
  30. package/dist/daemon/graph.js +176 -0
  31. package/dist/daemon/graph.js.map +1 -0
  32. package/dist/daemon/http.js +83 -0
  33. package/dist/daemon/http.js.map +1 -0
  34. package/dist/daemon/inbound.js +919 -0
  35. package/dist/daemon/inbound.js.map +1 -0
  36. package/dist/daemon/index.js +569 -0
  37. package/dist/daemon/index.js.map +1 -0
  38. package/dist/daemon/last-response.js +59 -0
  39. package/dist/daemon/last-response.js.map +1 -0
  40. package/dist/daemon/mirror-bridge.js +3512 -0
  41. package/dist/daemon/mirror-bridge.js.map +1 -0
  42. package/dist/daemon/mirror-store.js +39 -0
  43. package/dist/daemon/mirror-store.js.map +1 -0
  44. package/dist/daemon/outbound.js +42 -0
  45. package/dist/daemon/outbound.js.map +1 -0
  46. package/dist/daemon/peers.js +146 -0
  47. package/dist/daemon/peers.js.map +1 -0
  48. package/dist/daemon/pending.js +90 -0
  49. package/dist/daemon/pending.js.map +1 -0
  50. package/dist/daemon/quota.js +164 -0
  51. package/dist/daemon/quota.js.map +1 -0
  52. package/dist/daemon/redact.js +27 -0
  53. package/dist/daemon/redact.js.map +1 -0
  54. package/dist/daemon/session-cache.js +149 -0
  55. package/dist/daemon/session-cache.js.map +1 -0
  56. package/dist/daemon/session-scan.js +273 -0
  57. package/dist/daemon/session-scan.js.map +1 -0
  58. package/dist/daemon/sessions.js +35 -0
  59. package/dist/daemon/sessions.js.map +1 -0
  60. package/dist/daemon/spawn-tmux.js +213 -0
  61. package/dist/daemon/spawn-tmux.js.map +1 -0
  62. package/dist/daemon/tips.js +25 -0
  63. package/dist/daemon/tips.js.map +1 -0
  64. package/dist/daemon/topics.js +197 -0
  65. package/dist/daemon/topics.js.map +1 -0
  66. package/dist/daemon/usage.js +358 -0
  67. package/dist/daemon/usage.js.map +1 -0
  68. package/dist/daemon/wedoc.js +210 -0
  69. package/dist/daemon/wedoc.js.map +1 -0
  70. package/dist/daemon/ws.js +67 -0
  71. package/dist/daemon/ws.js.map +1 -0
  72. package/dist/mcp/server.js +385 -0
  73. package/dist/mcp/server.js.map +1 -0
  74. package/dist/shared/ansi.js +134 -0
  75. package/dist/shared/ansi.js.map +1 -0
  76. package/dist/shared/chat-http.js +195 -0
  77. package/dist/shared/chat-http.js.map +1 -0
  78. package/dist/shared/chat-render.js +53 -0
  79. package/dist/shared/chat-render.js.map +1 -0
  80. package/dist/shared/chat-view.js +116 -0
  81. package/dist/shared/chat-view.js.map +1 -0
  82. package/dist/shared/cli-backends.js +304 -0
  83. package/dist/shared/cli-backends.js.map +1 -0
  84. package/dist/shared/config-writer.js +39 -0
  85. package/dist/shared/config-writer.js.map +1 -0
  86. package/dist/shared/config.js +278 -0
  87. package/dist/shared/config.js.map +1 -0
  88. package/dist/shared/detail-render.js +836 -0
  89. package/dist/shared/detail-render.js.map +1 -0
  90. package/dist/shared/detail-store.js +205 -0
  91. package/dist/shared/detail-store.js.map +1 -0
  92. package/dist/shared/highlight.js +154 -0
  93. package/dist/shared/highlight.js.map +1 -0
  94. package/dist/shared/lan-ip.js +35 -0
  95. package/dist/shared/lan-ip.js.map +1 -0
  96. package/dist/shared/log.js +18 -0
  97. package/dist/shared/log.js.map +1 -0
  98. package/dist/shared/md-chunk.js +99 -0
  99. package/dist/shared/md-chunk.js.map +1 -0
  100. package/dist/shared/paths.js +12 -0
  101. package/dist/shared/paths.js.map +1 -0
  102. package/dist/shared/session-label.js +67 -0
  103. package/dist/shared/session-label.js.map +1 -0
  104. package/dist/shared/web-assets.js +51 -0
  105. package/dist/shared/web-assets.js.map +1 -0
  106. package/dist/svr/index.js +246 -0
  107. package/dist/svr/index.js.map +1 -0
  108. package/hooks/hooks.json +16 -0
  109. package/hooks/pre-tool-use.sh +167 -0
  110. package/launchd/com.weclaude.daemon.plist.template +45 -0
  111. package/package.json +97 -0
  112. package/scripts/install.sh +73 -0
  113. package/scripts/postinstall.sh +12 -0
  114. package/scripts/uninstall.sh +44 -0
  115. package/systemd/weclaude.service.template +17 -0
  116. package/web/chat.css +171 -0
  117. package/web/chat.js +367 -0
@@ -0,0 +1,311 @@
1
+ #!/usr/bin/env node
2
+ // `weclaude init` — interactive onboarding for new users.
3
+ // Flow:
4
+ // 1. Prompt creds + agent kind + hook toggle.
5
+ // 2. Write ~/.weclaude/config.jsonc + secrets.json (split secrets).
6
+ // 3. Build (if needed), run `weclaude sync` against chosen agent settings.json,
7
+ // install resident daemon.
8
+ // 4. Arm bootstrap claim. Wait for the user to send a magic phrase in IM.
9
+ // That message bypasses allowFrom, sets defaultChat, and adds the sender.
10
+ // 5. Mirror 模式下:拉起 tmux+claude pane,提示用户在 WeCom 发首条消息。
11
+ import { existsSync, readFileSync } from "node:fs";
12
+ import { spawnSync } from "node:child_process";
13
+ import { dirname, resolve as pathResolve } from "node:path";
14
+ import { fileURLToPath } from "node:url";
15
+ import { input, password, select, confirm, checkbox } from "@inquirer/prompts";
16
+ import { parse as parseJsonc } from "jsonc-parser";
17
+ import { patchJsonc } from "../shared/config-writer.js";
18
+ import { expandHome } from "../shared/paths.js";
19
+ const here = dirname(fileURLToPath(import.meta.url));
20
+ const REPO = pathResolve(here, "..", "..");
21
+ const CONFIG = "~/.weclaude/config.jsonc";
22
+ const SECRETS = "~/.weclaude/secrets.json";
23
+ const CLAIM_PHRASE = "将本对话设置为默认会话";
24
+ // ── Pretty output (no ink — keep deps light) ─────────────────────────
25
+ const c = {
26
+ dim: (s) => `\x1b[2m${s}\x1b[0m`,
27
+ bold: (s) => `\x1b[1m${s}\x1b[0m`,
28
+ green: (s) => `\x1b[32m${s}\x1b[0m`,
29
+ cyan: (s) => `\x1b[36m${s}\x1b[0m`,
30
+ yellow: (s) => `\x1b[33m${s}\x1b[0m`,
31
+ red: (s) => `\x1b[31m${s}\x1b[0m`,
32
+ };
33
+ const log = (s) => console.log(s);
34
+ const step = (n, title) => log(`\n${c.cyan(`[${n}/3]`)} ${c.bold(title)}`);
35
+ const settingsPathFor = (kind) => {
36
+ switch (kind) {
37
+ case "claude": return "~/.claude/settings.json";
38
+ case "claude-internal": return "~/.claude-internal/settings.json";
39
+ case "codebuddy": return "~/.codebuddy/settings.json";
40
+ }
41
+ };
42
+ const claudeBinFor = (kind) => {
43
+ if (kind === "claude-internal")
44
+ return "claude-internal";
45
+ if (kind === "codebuddy")
46
+ return "codebuddy";
47
+ return "claude";
48
+ };
49
+ // sync.targets[].kind: "claude-internal" 是 claude 家族的特例,
50
+ // collapse 为 "claude" (settingsPath 已表达 internal 语义)。
51
+ const syncKindFor = (kind) => kind === "codebuddy" ? "codebuddy" : "claude";
52
+ // wrc.defaultCli: daemon active backend。与 sync.targets 多值独立。
53
+ const backendNameFor = (kind) => kind;
54
+ // ── HTTP helpers (talk to local daemon) ──────────────────────────────
55
+ const DAEMON = "http://127.0.0.1:17890";
56
+ const get = async (p) => {
57
+ const r = await fetch(`${DAEMON}${p}`);
58
+ return r.json().catch(() => ({}));
59
+ };
60
+ const post = async (p, body) => {
61
+ const r = await fetch(`${DAEMON}${p}`, {
62
+ method: "POST",
63
+ headers: { "content-type": "application/json" },
64
+ body: JSON.stringify(body),
65
+ });
66
+ return r.json().catch(() => ({}));
67
+ };
68
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
69
+ const readBotCreds = () => {
70
+ const p = expandHome(SECRETS);
71
+ if (!existsSync(p))
72
+ return {};
73
+ try {
74
+ const bot = parseJsonc(readFileSync(p, "utf8"))?.bot;
75
+ return bot ?? {};
76
+ }
77
+ catch {
78
+ return {};
79
+ }
80
+ };
81
+ // 只露头尾, 中间省略 —— 足够用户确认"是这个机器人", 又不把凭证打进终端 scrollback。
82
+ const mask = (s) => s.length <= 10 ? `${s.slice(0, 2)}***` : `${s.slice(0, 6)}***${s.slice(-4)}`;
83
+ // ── Build + install + reload daemon ──────────────────────────────────
84
+ const ensureBuild = () => {
85
+ if (existsSync(`${REPO}/dist/daemon/index.js`))
86
+ return;
87
+ log(c.dim(" building..."));
88
+ const r = spawnSync("npx", ["tsc", "-p", "tsconfig.json"], { cwd: REPO, stdio: "inherit" });
89
+ if (r.status !== 0)
90
+ throw new Error("build failed");
91
+ };
92
+ const runSync = () => {
93
+ log(c.dim(" syncing hooks/MCP/env into agent settings.json..."));
94
+ const r = spawnSync(process.execPath, [`${REPO}/dist/cli/sync.js`], { stdio: "inherit" });
95
+ if (r.status !== 0)
96
+ throw new Error("sync failed");
97
+ };
98
+ const installDaemon = () => {
99
+ log(c.dim(" installing resident daemon..."));
100
+ const r = spawnSync("bash", [`${REPO}/scripts/install.sh`], { stdio: "inherit" });
101
+ if (r.status !== 0)
102
+ throw new Error("install.sh failed");
103
+ };
104
+ // Register the local repo as a Claude Code marketplace and install the
105
+ // `weclaude` plugin from it. This is what wires up `hooks/hooks.json` (so
106
+ // `${CLAUDE_PLUGIN_ROOT}` resolves) + `commands/wrc.md` + the MCP server
107
+ // declared in `.claude-plugin/plugin.json`. Idempotent: marketplace add
108
+ // re-uses the existing entry, install upgrades in place.
109
+ //
110
+ // 失败即 throw — 没装上 hook 等于整套授权链路废掉,继续往下跑只会让用户看到
111
+ // 假的"✅ 引导完成",再被 auto mode 拦截一脸懵。
112
+ // status 为 null 的两种真实原因: spawn 失败 (error, 多为 ENOENT —— bin 是
113
+ // alias/函数或不在继承的 PATH 里) 或进程被信号杀死。两者都不是「退出码」,
114
+ // 必须分开报,否则用户拿到 null 一脸懵。
115
+ const describeSpawn = (r) => r.error ? `无法启动 (${r.error.message})`
116
+ : r.signal ? `被信号 ${r.signal} 杀死`
117
+ : `退出码 ${r.status}`;
118
+ const installPlugin = (claudeBin) => {
119
+ log(c.dim(` 注册 marketplace + 安装插件 (${claudeBin}) ...`));
120
+ const m = spawnSync(claudeBin, ["plugin", "marketplace", "add", REPO], { stdio: "inherit" });
121
+ if (m.status !== 0) {
122
+ throw new Error(`plugin marketplace add 失败 (${describeSpawn(m)}) — hook 无法注册。\n` +
123
+ ` 若提示无法启动: ${claudeBin} 不在 PATH 或是 shell alias/函数, 请用绝对路径重试。\n` +
124
+ ` 手动: ${claudeBin} plugin marketplace add ${REPO}`);
125
+ }
126
+ const i = spawnSync(claudeBin, ["plugin", "install", "weclaude@weclaude-local", "--scope", "user"], { stdio: "inherit" });
127
+ if (i.status !== 0) {
128
+ throw new Error(`plugin install 失败 (${describeSpawn(i)}) — hook 无法注册。\n` +
129
+ ` 常见原因: ${claudeBin} 版本过旧,不支持当前插件源类型 — 请先升级 ${claudeBin} 后重试 init。\n` +
130
+ ` 手动: ${claudeBin} plugin install weclaude@weclaude-local --scope user`);
131
+ }
132
+ };
133
+ const waitDaemonReady = async (timeoutMs) => {
134
+ const deadline = Date.now() + timeoutMs;
135
+ while (Date.now() < deadline) {
136
+ try {
137
+ const s = (await get("/status"));
138
+ if (s.wsConnected)
139
+ return;
140
+ }
141
+ catch {
142
+ /* not up yet */
143
+ }
144
+ await sleep(500);
145
+ }
146
+ throw new Error("daemon did not become ready in time");
147
+ };
148
+ // ── Main flow ────────────────────────────────────────────────────────
149
+ const main = async () => {
150
+ log(c.bold("\nweclaude · 新用户引导\n"));
151
+ log(c.dim(" 目标:3 步内完成 → IM 授权转发 + 远程 CC 控制可用。\n"));
152
+ if (existsSync(expandHome(CONFIG))) {
153
+ const ok = await confirm({
154
+ message: `检测到已有 ${CONFIG},覆盖关键字段后继续?`,
155
+ default: false,
156
+ });
157
+ if (!ok) {
158
+ log(c.yellow("已取消。"));
159
+ return;
160
+ }
161
+ }
162
+ // ── Step 1: prompts ────────────────────────────────────────────
163
+ step(1, "采集配置");
164
+ const existing = readBotCreds();
165
+ const reuseCreds = existing.botId
166
+ ? await confirm({
167
+ message: `检测到已有凭证 botId=${mask(existing.botId)}${existing.secret ? " (含 secret)" : ""},复用?`,
168
+ default: true,
169
+ })
170
+ : false;
171
+ const botId = reuseCreds && existing.botId
172
+ ? existing.botId
173
+ : await input({ message: "智能机器人 botId:", required: true });
174
+ // 复用 botId 但 secrets.json 里没有 secret (老配置手写过 config.jsonc) 时仍要问。
175
+ const secret = reuseCreds && existing.secret
176
+ ? existing.secret
177
+ : await password({ message: "机器人 secret:", mask: "•" });
178
+ const agentKinds = (await checkbox({
179
+ message: "选择 Claude agent (空格多选, 至少一个 — hook/MCP/env 会注入到每个选中项):",
180
+ choices: [
181
+ { name: "claude (Anthropic 官方)", value: "claude", checked: true },
182
+ { name: "claude-internal (Tencent 内部)", value: "claude-internal" },
183
+ { name: "codebuddy (Tencent CodeBuddy)", value: "codebuddy" },
184
+ ],
185
+ required: true,
186
+ loop: false,
187
+ }));
188
+ const wrcMode = (await select({
189
+ message: "选择 wrc 模式:",
190
+ choices: [
191
+ {
192
+ name: "mirror (推荐:远程消息注入到本地 tmux 里的 claude 会话,CLI 可见双向同步)",
193
+ value: "mirror",
194
+ },
195
+ {
196
+ name: "headless (远程消息触发新的 `claude -p` 子进程,CLI 不可见)",
197
+ value: "headless",
198
+ },
199
+ ],
200
+ default: "mirror",
201
+ }));
202
+ const enableHook = await confirm({
203
+ message: "开启 PreToolUse 授权拦截 hook?(IM 按钮卡片授权)",
204
+ default: true,
205
+ });
206
+ const targets = agentKinds.map((k) => ({
207
+ kind: syncKindFor(k),
208
+ settingsPath: settingsPathFor(k),
209
+ scope: "user",
210
+ }));
211
+ // 第一个选中项决定 wrc.defaultCli —— 新会话 (/new, sessions/new) 的默认 CLI。
212
+ // 其余已安装的 CLI 依然会被 daemon 镜像, 无需额外配置。
213
+ // checkbox required:true 保证非空, 但 TS 不感知, 这里 narrow 一下。
214
+ const [primary] = agentKinds;
215
+ if (!primary) {
216
+ log(c.red(" ✗ 未选择任何 agent"));
217
+ process.exit(1);
218
+ }
219
+ const claudeBin = claudeBinFor(primary);
220
+ // ── Step 1b: write configs ─────────────────────────────────────
221
+ log(c.dim(` 写入 ${CONFIG} ...`));
222
+ patchJsonc(CONFIG, [
223
+ { path: ["bot", "websocketUrl"], value: "wss://openws.work.weixin.qq.com" },
224
+ { path: ["defaultChat"], value: "" },
225
+ { path: ["wrc", "mode"], value: wrcMode },
226
+ { path: ["wrc", "claudeBin"], value: claudeBin },
227
+ { path: ["wrc", "defaultCli"], value: backendNameFor(primary) },
228
+ { path: ["wrc", "cwd"], value: "~/.weclaude/workspace" },
229
+ { path: ["wrc", "allowFrom"], value: [] },
230
+ { path: ["approval", "enabled"], value: enableHook },
231
+ { path: ["approval", "matcher"], value: ".*" },
232
+ { path: ["sync", "targets"], value: targets },
233
+ ]);
234
+ if (botId === existing.botId && secret === existing.secret) {
235
+ log(c.dim(` 复用 ${SECRETS} 中的凭证 (未改写)`));
236
+ }
237
+ else {
238
+ log(c.dim(` 写入 ${SECRETS} ...`));
239
+ patchJsonc(SECRETS, [
240
+ { path: ["bot", "botId"], value: botId },
241
+ { path: ["bot", "secret"], value: secret },
242
+ ]);
243
+ }
244
+ ensureBuild();
245
+ if (enableHook)
246
+ runSync();
247
+ // marketplace 插件只存在于 claude 家族; codebuddy 的 hook 由 sync 直接
248
+ // 写进 ~/.codebuddy/settings.json (插件未发布到其市场), 装插件必然失败。
249
+ if (enableHook) {
250
+ const pluginBins = [...new Set(agentKinds.filter((k) => k !== "codebuddy").map(claudeBinFor))];
251
+ for (const bin of pluginBins)
252
+ installPlugin(bin);
253
+ }
254
+ installDaemon();
255
+ log(c.dim(" 等待 daemon 上线..."));
256
+ await waitDaemonReady(20_000);
257
+ log(c.green(" ✓ daemon ready"));
258
+ // ── Step 2: claim default chat ─────────────────────────────────
259
+ step(2, "绑定默认会话");
260
+ await post("/claim/start", { phrase: CLAIM_PHRASE, ttlSec: 600 });
261
+ log(`\n ${c.bold("→ 现在打开企业微信,给该机器人发送:")}`);
262
+ log(` ${c.cyan(CLAIM_PHRASE)}\n`);
263
+ log(c.dim(" 等待中... (10 分钟超时)"));
264
+ const claimed = await pollClaim(10 * 60_000);
265
+ if (!claimed) {
266
+ log(c.red("\n 超时未收到消息。可稍后手动编辑 config 的 defaultChat / wrc.allowFrom。"));
267
+ return;
268
+ }
269
+ log(c.green(`\n ✓ 已绑定: ${c.bold(claimed)}`));
270
+ // ── Step 3: spin up mirror pane ────────────────────────────────
271
+ step(3, "拉起 mirror 会话");
272
+ if (!enableHook || wrcMode !== "mirror") {
273
+ log(c.green("\n✅ 引导完成。后续可用 `weclaude status` / `weclaude logs -f` 观察。"));
274
+ return;
275
+ }
276
+ // Mirror 路径:拉起 tmux+claude pane,然后让用户在 WeCom 发首条消息。
277
+ // 首条 inbound 走完整 dispatch 链路:openStream → 注入 tmux → tail 回流为
278
+ // 打字机气泡。比 frame-less /mirror/inject 体验好得多(后者无 liveStream)。
279
+ log(c.dim(" 正在拉起 tmux+claude pane (mirror 模式) ..."));
280
+ const r = (await post("/mirror/spawn", { target: claimed }));
281
+ if (!r.ok) {
282
+ log(c.red(` ✗ /mirror/spawn 失败: ${r.reason ?? "unknown"}`));
283
+ log(c.yellow(" 可手动: tmux new-session -s weclaude 后跑 claude;或在 WeCom 发任意消息触发 auto-spawn。"));
284
+ return;
285
+ }
286
+ log(c.green(` ✓ tmux session=${c.bold(r.tmuxSession ?? "")} pane=${r.tmuxPane ?? ""} sid=${r.sessionId ?? ""}`));
287
+ log(c.dim(` 附加: tmux attach -t ${r.tmuxSession ?? "weclaude"}`));
288
+ log(`\n ${c.bold("→ 现在去 WeCom 给机器人发一条消息(比如 \"hi\"):")}`);
289
+ log(c.dim(" inbound → openStream → 注入 tmux pane → 输出回流为打字机气泡"));
290
+ log(c.green("\n✅ 引导完成。后续可用 `weclaude status` / `weclaude logs -f` 观察。"));
291
+ };
292
+ const pollClaim = async (timeoutMs) => {
293
+ const deadline = Date.now() + timeoutMs;
294
+ while (Date.now() < deadline) {
295
+ const s = (await get("/claim/status"));
296
+ if (s.claimed)
297
+ return s.claimed.principal;
298
+ if (s.armed === false)
299
+ break;
300
+ await sleep(1000);
301
+ }
302
+ return undefined;
303
+ };
304
+ main().catch((e) => {
305
+ // eslint-disable-next-line no-console
306
+ console.error(c.red(`\n[weclaude-init] ${e.message}`));
307
+ process.exit(1);
308
+ });
309
+ // keep loadConfig reference reachable for tree-shaking sanity (used by sub-binaries)
310
+ void readFileSync;
311
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../cli/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,175 @@
1
+ // `weclaude sync` — write weclaude's hooks / MCP / env into target settings.json files
2
+ // (e.g. ~/.claude/settings.json so claude-internal wrappers pick them up).
3
+ // Idempotent + reversible via per-target lock manifest in ~/.weclaude/sync.lock.json.
4
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
+ import { dirname, resolve as pathResolve } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ import { parse as parseJsonc } from "jsonc-parser";
8
+ import { loadConfig } from "../shared/config.js";
9
+ import { expandHome } from "../shared/paths.js";
10
+ // ── Plugin root resolution ────────────────────────────────────────────
11
+ // dist/cli/sync.js → repo root is two `..` up.
12
+ const here = dirname(fileURLToPath(import.meta.url));
13
+ const PLUGIN_ROOT = pathResolve(here, "..", "..");
14
+ const MCP_ENTRY = `${PLUGIN_ROOT}/dist/mcp/server.js`;
15
+ const HOOK_SCRIPT = `${PLUGIN_ROOT}/hooks/pre-tool-use.sh`;
16
+ const LOCK_FILE = expandHome("~/.weclaude/sync.lock.json");
17
+ const MARKER = "weclaude";
18
+ const readLock = () => {
19
+ if (!existsSync(LOCK_FILE))
20
+ return { targets: {} };
21
+ try {
22
+ return JSON.parse(readFileSync(LOCK_FILE, "utf8"));
23
+ }
24
+ catch {
25
+ return { targets: {} };
26
+ }
27
+ };
28
+ const writeLock = (l) => {
29
+ mkdirSync(dirname(LOCK_FILE), { recursive: true });
30
+ writeFileSync(LOCK_FILE, JSON.stringify(l, null, 2));
31
+ };
32
+ const readJson = (p) => {
33
+ if (!existsSync(p))
34
+ return {};
35
+ const txt = readFileSync(p, "utf8");
36
+ return (parseJsonc(txt) ?? {});
37
+ };
38
+ const writeJson = (p, obj) => {
39
+ mkdirSync(dirname(p), { recursive: true });
40
+ writeFileSync(p, JSON.stringify(obj, null, 2) + "\n", "utf8");
41
+ };
42
+ const stripHooks = (settings) => {
43
+ const hooks = settings.hooks;
44
+ if (!hooks)
45
+ return;
46
+ const list = hooks.PreToolUse ?? [];
47
+ hooks.PreToolUse = list.filter((e) => e._managedBy !== MARKER);
48
+ if (hooks.PreToolUse.length === 0)
49
+ delete hooks.PreToolUse;
50
+ };
51
+ // CodeBuddy 不走 Claude Code 的 plugin marketplace (weclaude 插件不会装上),
52
+ // settings.json 是唯一注册点; Claude 家族由 plugin 的 hooks/hooks.json 提供,
53
+ // 不在此写入 (否则双重触发 → 重复卡片)。
54
+ const upsertHook = (settings, timeoutSec) => {
55
+ const hooks = (settings.hooks ??= {});
56
+ const list = (hooks.PreToolUse ??= []);
57
+ list.push({
58
+ matcher: ".*",
59
+ hooks: [{
60
+ type: "command",
61
+ command: HOOK_SCRIPT,
62
+ // 严格大于 daemon 的 longPollSec (= envVals.hookTimeoutSec) + 一点余量,
63
+ // 与 hooks.json 的 timeout 语义对齐 — 否则 curl 先死, 用户点击写进死 socket。
64
+ timeout: timeoutSec + 10,
65
+ }],
66
+ _managedBy: MARKER,
67
+ });
68
+ };
69
+ // ── MCP upsert ────────────────────────────────────────────────────────
70
+ const upsertMcp = (settings) => {
71
+ const m = (settings.mcpServers ??= {});
72
+ // strip legacy `wecom` entry from earlier installs (renamed to weclaude).
73
+ const legacy = m.wecom;
74
+ if (legacy?._managedBy === MARKER)
75
+ delete m.wecom;
76
+ m.weclaude = {
77
+ command: "node",
78
+ args: [MCP_ENTRY],
79
+ _managedBy: MARKER,
80
+ };
81
+ };
82
+ const stripMcp = (settings) => {
83
+ const m = settings.mcpServers;
84
+ if (!m)
85
+ return;
86
+ for (const k of ["weclaude", "wecom"]) {
87
+ const cur = m[k];
88
+ if (cur?._managedBy === MARKER)
89
+ delete m[k];
90
+ }
91
+ };
92
+ // ── Env upsert ────────────────────────────────────────────────────────
93
+ const ENV_KEYS = [
94
+ "WECLAUDE_DAEMON_BASE",
95
+ "WECLAUDE_DAEMON_URL",
96
+ "WECLAUDE_STATE_DIR",
97
+ "WECLAUDE_HOOK_FALLBACK",
98
+ "WECLAUDE_HOOK_TIMEOUT",
99
+ ];
100
+ const upsertEnv = (settings, v) => {
101
+ const env = (settings.env ??= {});
102
+ env.WECLAUDE_DAEMON_BASE = v.base;
103
+ env.WECLAUDE_DAEMON_URL = `${v.base}/approve`;
104
+ env.WECLAUDE_STATE_DIR = expandHome(v.stateDir);
105
+ env.WECLAUDE_HOOK_FALLBACK = v.hookFallback;
106
+ // curl --max-time: 严格大于 longPollSec, 否则长挂的卡在用户点击前就断线。
107
+ env.WECLAUDE_HOOK_TIMEOUT = String(v.hookTimeoutSec);
108
+ return ENV_KEYS;
109
+ };
110
+ const stripEnv = (settings) => {
111
+ const env = settings.env;
112
+ if (!env)
113
+ return;
114
+ for (const k of ENV_KEYS)
115
+ delete env[k];
116
+ };
117
+ // ── Drivers ───────────────────────────────────────────────────────────
118
+ const targetKey = (path) => expandHome(path);
119
+ const syncOne = (settingsPath, kind, opts, lock, env) => {
120
+ const abs = expandHome(settingsPath);
121
+ const settings = readJson(abs);
122
+ // Always strip first — keeps re-runs idempotent and clears any legacy
123
+ // hook entries from earlier installs that wrote into settings.json directly.
124
+ stripHooks(settings);
125
+ if (opts.remove) {
126
+ stripMcp(settings);
127
+ stripEnv(settings);
128
+ delete lock.targets[targetKey(settingsPath)];
129
+ }
130
+ else {
131
+ upsertMcp(settings);
132
+ const wroteEnv = upsertEnv(settings, env);
133
+ // CodeBuddy 无 plugin 路径, settings.json 注册 hook; Claude 家族由 plugin 提供。
134
+ let wroteHooks = false;
135
+ if (kind === "codebuddy") {
136
+ upsertHook(settings, env.hookTimeoutSec);
137
+ wroteHooks = true;
138
+ }
139
+ lock.targets[targetKey(settingsPath)] = { wroteHooks, wroteMcp: true, wroteEnv };
140
+ }
141
+ writeJson(abs, settings);
142
+ };
143
+ const main = () => {
144
+ const argv = process.argv.slice(2);
145
+ const remove = argv.includes("--remove") || argv.includes("--uninstall");
146
+ const dryRun = argv.includes("--dry-run");
147
+ const { config: cfg } = loadConfig();
148
+ const targets = cfg.sync.targets;
149
+ if (targets.length === 0) {
150
+ // eslint-disable-next-line no-console
151
+ console.error("no sync.targets in config — nothing to do.");
152
+ process.exit(0);
153
+ }
154
+ const envVals = {
155
+ base: `http://${cfg.daemon.host}:${cfg.daemon.port}`,
156
+ stateDir: cfg.daemon.stateDir,
157
+ hookFallback: cfg.approval.fallbackOnError,
158
+ hookTimeoutSec: cfg.approval.hookTimeoutSec,
159
+ };
160
+ const lock = readLock();
161
+ for (const t of targets) {
162
+ const action = remove ? "remove" : "upsert";
163
+ // eslint-disable-next-line no-console
164
+ console.log(`[weclaude-sync] ${action} ${t.kind} → ${t.settingsPath}`);
165
+ if (dryRun)
166
+ continue;
167
+ syncOne(t.settingsPath, t.kind, { remove }, lock, envVals);
168
+ }
169
+ if (!dryRun)
170
+ writeLock(lock);
171
+ // eslint-disable-next-line no-console
172
+ console.log(remove ? "[weclaude-sync] removed." : "[weclaude-sync] synced.");
173
+ };
174
+ main();
175
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../cli/sync.ts"],"names":[],"mappings":"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"}