wezard 0.3.3 → 1.0.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.
Files changed (65) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.claude-plugin/plugin.json +3 -3
  3. package/CLAUDE.md +14 -14
  4. package/LICENSE +1 -1
  5. package/README.md +38 -38
  6. package/cli/{weclaude.sh → wezard.sh} +40 -35
  7. package/commands/audit.md +2 -2
  8. package/commands/wrc.md +2 -2
  9. package/config.example.jsonc +24 -11
  10. package/dist/cli/audit.js +2 -2
  11. package/dist/cli/audit.js.map +1 -1
  12. package/dist/cli/init.js +97 -24
  13. package/dist/cli/init.js.map +1 -1
  14. package/dist/cli/migrate.js +213 -0
  15. package/dist/cli/migrate.js.map +1 -0
  16. package/dist/cli/sync.js +34 -26
  17. package/dist/cli/sync.js.map +1 -1
  18. package/dist/daemon/approval.js +45 -21
  19. package/dist/daemon/approval.js.map +1 -1
  20. package/dist/daemon/audit.js +1 -1
  21. package/dist/daemon/audit.js.map +1 -1
  22. package/dist/daemon/cc-bridge.js +1 -1
  23. package/dist/daemon/cc-bridge.js.map +1 -1
  24. package/dist/daemon/cfg-sync.js +4 -4
  25. package/dist/daemon/cfg-sync.js.map +1 -1
  26. package/dist/daemon/claim.js +2 -2
  27. package/dist/daemon/claim.js.map +1 -1
  28. package/dist/daemon/danger.js +102 -0
  29. package/dist/daemon/danger.js.map +1 -0
  30. package/dist/daemon/inbound.js +42 -40
  31. package/dist/daemon/inbound.js.map +1 -1
  32. package/dist/daemon/index.js +7 -7
  33. package/dist/daemon/index.js.map +1 -1
  34. package/dist/daemon/mirror-bridge.js +18 -12
  35. package/dist/daemon/mirror-bridge.js.map +1 -1
  36. package/dist/daemon/pending.js +4 -0
  37. package/dist/daemon/pending.js.map +1 -1
  38. package/dist/daemon/quota.js +1 -1
  39. package/dist/daemon/quota.js.map +1 -1
  40. package/dist/daemon/session-scan.js +88 -26
  41. package/dist/daemon/session-scan.js.map +1 -1
  42. package/dist/daemon/spawn-tmux.js +5 -5
  43. package/dist/daemon/spawn-tmux.js.map +1 -1
  44. package/dist/daemon/usage.js +1 -1
  45. package/dist/daemon/usage.js.map +1 -1
  46. package/dist/daemon/wedoc.js +2 -2
  47. package/dist/daemon/wedoc.js.map +1 -1
  48. package/dist/mcp/server.js +4 -4
  49. package/dist/mcp/server.js.map +1 -1
  50. package/dist/shared/config-writer.js +1 -1
  51. package/dist/shared/config-writer.js.map +1 -1
  52. package/dist/shared/config.js +32 -19
  53. package/dist/shared/config.js.map +1 -1
  54. package/dist/shared/svr-token.js +22 -0
  55. package/dist/shared/svr-token.js.map +1 -0
  56. package/dist/svr/index.js +16 -31
  57. package/dist/svr/index.js.map +1 -1
  58. package/hooks/pre-tool-use.sh +24 -24
  59. package/launchd/{com.weclaude.daemon.plist.template → com.wezard.daemon.plist.template} +3 -3
  60. package/package.json +17 -14
  61. package/scripts/install.sh +15 -8
  62. package/scripts/postinstall.sh +2 -2
  63. package/scripts/uninstall.sh +35 -27
  64. package/systemd/{weclaude.service.template → wezard.service.template} +3 -3
  65. package/web/chat.css +13 -5
@@ -1,11 +1,11 @@
1
1
  {
2
- "name": "weclaude-local",
2
+ "name": "wezard-local",
3
3
  "version": "0.0.1",
4
- "description": "Local marketplace shim — exposes weclaude plugin from this repo.",
4
+ "description": "Local marketplace shim — exposes wezard plugin from this repo.",
5
5
  "owner": { "name": "zyy" },
6
6
  "plugins": [
7
7
  {
8
- "name": "weclaude",
8
+ "name": "wezard",
9
9
  "source": "./",
10
10
  "description": "Remote-control Claude Code from WeCom (/wrc).",
11
11
  "category": "productivity"
@@ -1,12 +1,12 @@
1
1
  {
2
- "name": "weclaude",
3
- "version": "0.2.7",
2
+ "name": "wezard",
3
+ "version": "1.0.0",
4
4
  "description": "Remote-control Claude Code from WeCom (/wrc) via WebSocket smart bot. Cards for tool approval, skills for doc r/w.",
5
5
  "author": {
6
6
  "name": "zyy"
7
7
  },
8
8
  "mcpServers": {
9
- "weclaude": {
9
+ "wezard": {
10
10
  "command": "node",
11
11
  "args": ["${CLAUDE_PLUGIN_ROOT}/dist/mcp/server.js"]
12
12
  }
package/CLAUDE.md CHANGED
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
4
4
 
5
5
  ## What this project is
6
6
 
7
- `weclaude` (CLI `weclaude`) bridges Claude Code and WeCom (企业微信) smart bots:
7
+ `wezard` (CLI `wezard`) bridges Claude Code and WeCom (企业微信) smart bots:
8
8
  - **PreToolUse approval forwarding**: every tool call is gated by a button card pushed to WeCom; clicking ✅/❌/⏱ resolves the long-poll the hook is parked on.
9
9
  - **Remote `/wrc`**: messages sent to the bot drive a local Claude (headless `claude -p` or mirroring an interactive session).
10
10
  - **MCP server** (`wecom`): exposes `send_markdown` / `send_card` / `ask_user` / `daemon_status` tools that talk to the resident daemon over loopback HTTP.
@@ -15,23 +15,23 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
15
15
  npm run build # tsc → dist/, then chmod +x on the three bin entry scripts
16
16
  npm run typecheck # tsc --noEmit
17
17
  npm run dev:daemon # tsx daemon/index.ts (no install / hot iteration)
18
- npm run dev:cli # tsx cli/weclaude.ts
18
+ npm run dev:cli # tsx cli/wezard.ts
19
19
  ```
20
20
 
21
21
  There are **no tests**. Don't fabricate test commands.
22
22
 
23
23
  Local dev loop:
24
24
  ```bash
25
- npm run build && ./cli/weclaude.sh reload # rebuild, then bounce the resident daemon
26
- ./cli/weclaude.sh logs -f # tail ~/.weclaude/daemon.log
27
- ./cli/weclaude.sh status # HTTP /status — wsConnected, pending count, sourcePath
25
+ npm run build && ./cli/wezard.sh reload # rebuild, then bounce the resident daemon
26
+ ./cli/wezard.sh logs -f # tail ~/.wezard/daemon.log
27
+ ./cli/wezard.sh status # HTTP /status — wsConnected, pending count, sourcePath
28
28
  ```
29
29
 
30
- When the user says **"reload"** in this repo, it means exactly: `npm run build && ./cli/weclaude.sh reload`. The global `weclaude` binary may not be on `$PATH` in dev shells — always invoke `./cli/weclaude.sh` from the repo root.
30
+ When the user says **"reload"** in this repo, it means exactly: `npm run build && ./cli/wezard.sh reload`. The global `wezard` binary may not be on `$PATH` in dev shells — always invoke `./cli/wezard.sh` from the repo root.
31
31
 
32
32
  ## High-level architecture
33
33
 
34
- Three processes, all coordinating via 127.0.0.1:17890 and `~/.weclaude/`:
34
+ Three processes, all coordinating via 127.0.0.1:17890 and `~/.wezard/`:
35
35
 
36
36
  ```
37
37
  WeCom ── WS ──► daemon (resident, launchd/systemd --user)
@@ -46,31 +46,31 @@ Three processes, all coordinating via 127.0.0.1:17890 and `~/.weclaude/`:
46
46
  - `ws.ts` owns the `@wecom/aibot-node-sdk` `WSClient`. Fatal auth/reconnect → `process.exit(1)` (launchd respawns).
47
47
  - `approval.ts` builds the button card, parks an HTTP request via `pending.ts`, and resolves it on `event.template_card_event`. Three click outcomes: `allow` / `allow_window` (auto-allow N min for that session) / `deny`. `session-cache.ts` short-circuits repeats.
48
48
  - `inbound.ts` routes `message.text` / `message.image` / `message.mixed` → either headless `cc-bridge.ts` or `mirror-bridge.ts`. Gates on `allowFrom`; one-shot exception is the bootstrap claim (see below).
49
- - `cc-bridge.ts` (mode=headless) spawns `claude -p --output-format stream-json --verbose`, parses `assistant`/`stream_event` lines, and pumps text via `client.replyStream`. Per-principal queue serializes turns; session id is captured from the `system/init` line and persisted to `~/.weclaude/sessions.json` for `--resume`.
49
+ - `cc-bridge.ts` (mode=headless) spawns `claude -p --output-format stream-json --verbose`, parses `assistant`/`stream_event` lines, and pumps text via `client.replyStream`. Per-principal queue serializes turns; session id is captured from the `system/init` line and persisted to `~/.wezard/sessions.json` for `--resume`.
50
50
  - `mirror-bridge.ts` (mode=mirror) tails `<projectsDir>/<encoded(cwd)>/<sid>.jsonl` and pushes new `assistant` content to a chat. Inbound injection is either `claude --resume <sid> -p` (writes a turn into the same jsonl) or `tmux paste-buffer` against a live TTY (only path that makes WeCom messages visible in the user's CLI window). `recentInjects` ring buffer suppresses the WeCom→CLI echo when tailing.
51
51
  - `claim.ts` is a single-shot bootstrap: an exact-match magic phrase from any sender bypasses `allowFrom`, writes that principal as `defaultChat`, and appends to `allowFrom`. This is the **only** legitimate ingress for first-time setup.
52
52
  - `peers.ts` is the read side of multi-agent awareness: sibling sessions of one chat are exactly the target keys sharing a base principal (`baseOfKey`), i.e. the untagged default plus every `#tag`. Pure parsing only — bounded transcript-tail reads (`tailTurns` / `lastAssistantText` / `summarizeTail`, shared with `session-scan.ts`) and pane classification (`paneIsBusy`). **Busy detection matches the TUI spinner footer** (`… (12m 31s · …)` on current versions, `esc to interrupt` on older ones) in the last 8 non-blank rows — transcript mtime is useless here, it goes quiet during long tool calls.
53
53
  - `graph.ts` is the loop-graph runner: `nodes` = tagged sessions (own cli/model/cwd), `steps` = an ordered pipeline walked `rounds` times, each step injecting a prompt, waiting for that agent to go idle, then feeding its reply forward as `{{last}}` / `{{<tag>}}`. Stops early on the `until` sentinel. All effects go through injected deps backed by `mirror-bridge`, so a step is exactly what a human typing `#tag …` would do. Runs are **in-memory only** — a reload cancels them (panes survive).
54
54
 
55
55
  **Configuration** (`shared/config.ts`):
56
- - Loaded by every binary via `loadConfig()`. Resolution order: explicit arg → `$WECLAUDE_CONFIG` → `~/.weclaude/config.jsonc` → `~/.weclaude/config.json`.
57
- - Secrets (`bot.botId`, `bot.secret`) live in `~/.weclaude/secrets.json` and are deep-merged on top of the main config — keeps secrets out of dotfile repos.
56
+ - Loaded by every binary via `loadConfig()`. Resolution order: explicit arg → `$WEZARD_CONFIG` → `~/.wezard/config.jsonc` → `~/.wezard/config.json`.
57
+ - Secrets (`bot.botId`, `bot.secret`) live in `~/.wezard/secrets.json` and are deep-merged on top of the main config — keeps secrets out of dotfile repos.
58
58
  - Schema is zod (`ConfigSchema`); shape mismatches throw with a path-pointed error.
59
59
  - `shared/config-writer.ts` is the only sanctioned way to mutate the on-disk jsonc — it preserves comments via `jsonc-parser` edits. `cli/init.ts` and `daemon/claim.ts` use it.
60
60
 
61
61
  **Hook + sync**:
62
62
  - `hooks/hooks.json` is registered automatically by Claude Code when the plugin is installed (uses `${CLAUDE_PLUGIN_ROOT:-${CODEBUDDY_PLUGIN_ROOT}}` so the same file works under CodeBuddy's plugin loader if ever published there).
63
- - For non-plugin installs (`claude-internal` wrapper), `cli/sync.ts` writes the MCP server entry + `WECLAUDE_DAEMON_BASE` env into target `settings.json`s listed in `config.sync.targets`. **It deliberately strips legacy hook entries** for `kind:"claude"` targets — registering both the plugin's `hooks.json` AND a settings.json hook fires the hook twice per tool call (= duplicate cards). For `kind:"codebuddy"` targets, since the weclaude plugin is not published to CodeBuddy's marketplace, sync **writes the hook directly into `~/.codebuddy/settings.json`** with an absolute path to `hooks/pre-tool-use.sh` — this is the only registration path for CodeBuddy. `~/.weclaude/sync.lock.json` tracks what was written so `--remove` is reversible.
63
+ - For non-plugin installs (`claude-internal` wrapper), `cli/sync.ts` writes the MCP server entry + `WEZARD_DAEMON_BASE` env into target `settings.json`s listed in `config.sync.targets`. **It deliberately strips legacy hook entries** for `kind:"claude"` targets — registering both the plugin's `hooks.json` AND a settings.json hook fires the hook twice per tool call (= duplicate cards). For `kind:"codebuddy"` targets, since the wezard plugin is not published to CodeBuddy's marketplace, sync **writes the hook directly into `~/.codebuddy/settings.json`** with an absolute path to `hooks/pre-tool-use.sh` — this is the only registration path for CodeBuddy. `~/.wezard/sync.lock.json` tracks what was written so `--remove` is reversible.
64
64
 
65
65
  **MCP server** (`mcp/server.ts`): stdio transport, completely stateless w.r.t. WeCom. Every tool just `POST`s to the daemon. Add a tool here AND a route handler in `daemon/`. The peer tools (`list_peers` / `peek_peer` / `send_peer` / `wait_peer` / `run_agent_graph` / `graph_status` / `stop_graph`) all send `selfRef()` = `{sessionId, tmuxPane}` so the daemon can resolve *which* session is asking — env sessionId goes stale after a `/clear`, pane id doesn't. Their descriptions are the whole discovery mechanism for agent↔agent collaboration: an agent only realizes it can drive `#fix` because `send_peer` says so.
66
66
 
67
67
  ## Important patterns / pitfalls
68
68
 
69
69
  - **PATH for spawn**: `cc-bridge.ts` and `mirror-bridge.ts` both `augmentedPath()` because launchd/systemd start the daemon with a stripped PATH that often lacks nvm/homebrew. If you spawn anything new from the daemon, do the same or it will ENOENT in production but work fine under `npm run dev:daemon`.
70
- - **launchd respawn**: `KeepAlive.SuccessfulExit=false`. `weclaude reload` does `POST /shutdown` AND `launchctl kickstart`; just hitting `/shutdown` won't bounce the binary.
71
- - **Uninstall order**: `weclaude uninstall` *before* `npm uninstall -g weclaude`. Otherwise launchd repeatedly tries to relaunch a deleted binary. State at `~/.weclaude/` is intentionally preserved.
70
+ - **launchd respawn**: `KeepAlive.SuccessfulExit=false`. `wezard reload` does `POST /shutdown` AND `launchctl kickstart`; just hitting `/shutdown` won't bounce the binary.
71
+ - **Uninstall order**: `wezard uninstall` *before* `npm uninstall -g wezard`. Otherwise launchd repeatedly tries to relaunch a deleted binary. State at `~/.wezard/` is intentionally preserved.
72
72
  - **Card update has a 5s window**: `client.updateTemplateCard` only works within 5s of the click event — `installApprovalEventListener` does the rewrite synchronously inside the event handler.
73
- - **Mirror mode** runs against either `~/.claude-internal/projects/` or `~/.claude/projects/` — `cli/weclaude.sh mirror` probes both bases for the encoded cwd.
73
+ - **Mirror mode** runs against either `~/.claude-internal/projects/` or `~/.claude/projects/` — `cli/wezard.sh mirror` probes both bases for the encoded cwd.
74
74
  - **Long-poll timeouts**: hook curl `--max-time` (`approval.hookTimeoutSec`, default 43210) must be **strictly larger** than `approval.longPollSec` (default 43200 = 12h), or the hook returns `ask` while the daemon is still waiting on a click.
75
75
  - **Sensitive arg redaction** (`daemon/redact.ts`) runs before card render when `approval.sensitiveArgRedact=true`. Only the redacted form is shown in WeCom and stored in pending meta.
76
76
 
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 weclaude contributors
3
+ Copyright (c) 2026 wezard contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # weclaude
1
+ # wezard
2
2
 
3
3
  **把 Claude Code 装进企业微信。** 在地铁上、被窝里、开会摸鱼时,照样能跟你电脑上的 Claude 干活。
4
4
 
@@ -12,7 +12,7 @@
12
12
  - 📡 **MCP 主动推送** — Claude 通过 `wecom__send_markdown` / `wecom__send_card` / `wecom__ask_user` 主动汇报或问询。
13
13
  - 📄 **文档读写** — Claude 通过 `wecom_doc_list_tools` / `wecom_doc_call` 直接调企业微信智能机器人的 doc / smartsheet / smartpage MCP,新建在线文档、写 Markdown、读链接、操作智能表格——全程在内网,不需要 corp access_token。
14
14
  - 🗂 **多会话发现/切换** — Claude 通过 `list_claude_sessions` / `switch_claude_session` / `new_claude_session` 列出本机 tmux 内所有在跑的 Claude 会话(带摘要 + 稳定动物 emoji 标签)、把 IM 镜像切到其中任一个、或在指定路径新开一个会话。审批卡标题也带同一枚 emoji,多个会话兜底到同一 IM 时一眼区分。
15
- - 🔄 **重启即续** — 电脑重启 / tmux 全没了 / daemon 崩了都不掉档:IM ↔ 会话绑定持久化在 `~/.weclaude/mirror-attachments.json`,下一条 IM 消息自动 `claude --resume` 拉起新 tmux pane,历史完整继承;`tmux attach -t weclaude` 接管即可。
15
+ - 🔄 **重启即续** — 电脑重启 / tmux 全没了 / daemon 崩了都不掉档:IM ↔ 会话绑定持久化在 `~/.wezard/mirror-attachments.json`,下一条 IM 消息自动 `claude --resume` 拉起新 tmux pane,历史完整继承;`tmux attach -t wezard` 接管即可。
16
16
 
17
17
  ---
18
18
 
@@ -21,18 +21,18 @@
21
21
  **前置**:macOS / Linux、Node ≥ 20、PATH 里能找到 `claude` 或 `claude-internal`、企业微信「智能机器人」的 `botId` + `secret`。镜像模式额外需要 `tmux`。
22
22
 
23
23
  ```bash
24
- npm install -g weclaude
25
- weclaude init
24
+ npm install -g wezard
25
+ wezard init
26
26
  ```
27
27
 
28
- `init` 会交互式问你 4 个问题,把配置落到 `~/.weclaude/`:
28
+ `init` 会交互式问你 4 个问题,把配置落到 `~/.wezard/`:
29
29
 
30
30
  | 问什么 | 落到哪 |
31
31
  | --- | --- |
32
- | botId / secret | `~/.weclaude/secrets.json` |
33
- | 用哪个 Claude(`claude` / `claude-internal` / 自定义路径) | `~/.weclaude/config.jsonc` |
34
- | 用哪种模式(`headless` / `mirror`,见下文) | `~/.weclaude/config.jsonc` |
35
- | 是否开启 PreToolUse 远程审批 | `~/.weclaude/config.jsonc` |
32
+ | botId / secret | `~/.wezard/secrets.json` |
33
+ | 用哪个 Claude(`claude` / `claude-internal` / 自定义路径) | `~/.wezard/config.jsonc` |
34
+ | 用哪种模式(`headless` / `mirror`,见下文) | `~/.wezard/config.jsonc` |
35
+ | 是否开启 PreToolUse 远程审批 | `~/.wezard/config.jsonc` |
36
36
 
37
37
  然后自动:编译 → 注入 hook/MCP → 装常驻 daemon(macOS launchd / Linux systemd --user)→ 等 WebSocket 鉴权。
38
38
 
@@ -49,28 +49,28 @@ weclaude init
49
49
  **从某个 fork / 分支装(自带改动的版本)**:`dist/` 不入库,但 `prepare` 脚本会在 git 安装时自动编译,所以可以直接:
50
50
 
51
51
  ```bash
52
- npm i -g github:<你的用户名>/weclaude # 默认分支
53
- npm i -g github:<你的用户名>/weclaude#<分支名> # 指定分支
52
+ npm i -g github:<你的用户名>/wezard # 默认分支
53
+ npm i -g github:<你的用户名>/wezard#<分支名> # 指定分支
54
54
  ```
55
55
 
56
- **内网 / 需要正向代理**:weclaude 的出站(WeCom WebSocket、智能机器人文档 MCP)会读环境变量里的代理。安装与运行都带上 `HTTPS_PROXY`:
56
+ **内网 / 需要正向代理**:wezard 的出站(WeCom WebSocket、智能机器人文档 MCP)会读环境变量里的代理。安装与运行都带上 `HTTPS_PROXY`:
57
57
 
58
58
  ```bash
59
- HTTPS_PROXY=http://your-proxy:port npm i -g github:<你的用户名>/weclaude
59
+ HTTPS_PROXY=http://your-proxy:port npm i -g github:<你的用户名>/wezard
60
60
  # 也可在 config.jsonc 写死: bot.proxy = "http://your-proxy:port"(优先级高于环境变量)
61
61
  ```
62
62
 
63
63
  daemon 进程同样需要能读到代理变量(见下方守护脚本里 `export HTTPS_PROXY`)。
64
64
 
65
- **无 systemd 的环境(容器等)**:`init` 装 daemon 这步在 macOS 走 launchd、Linux 走 `systemd --user`。若机器没有 systemd user session(很多容器:PID 1 非 systemd、无 `XDG_RUNTIME_DIR`),这步会失败——其余配置(hook / MCP / 插件)已生效,只差 daemon 没被托管。用一个简单的重启循环守护即可,存成 `~/.weclaude/daemonctl.sh`:
65
+ **无 systemd 的环境(容器等)**:`init` 装 daemon 这步在 macOS 走 launchd、Linux 走 `systemd --user`。若机器没有 systemd user session(很多容器:PID 1 非 systemd、无 `XDG_RUNTIME_DIR`),这步会失败——其余配置(hook / MCP / 插件)已生效,只差 daemon 没被托管。用一个简单的重启循环守护即可,存成 `~/.wezard/daemonctl.sh`:
66
66
 
67
67
  ```bash
68
68
  #!/usr/bin/env bash
69
- # 无 systemd 时的 weclaude daemon 守护:setsid 脱离终端的重启循环。
69
+ # 无 systemd 时的 wezard daemon 守护:setsid 脱离终端的重启循环。
70
70
  set -uo pipefail
71
- REPO="$(npm root -g)/weclaude"
71
+ REPO="$(npm root -g)/wezard"
72
72
  NODE="$(command -v node)"
73
- WC="$HOME/.weclaude"; PIDFILE="$WC/supervisor.pid"; LOG="$WC/daemon.log"
73
+ WC="$HOME/.wezard"; PIDFILE="$WC/supervisor.pid"; LOG="$WC/daemon.log"
74
74
  mkdir -p "$WC"
75
75
  # 内网:daemon 出站要走代理。按需改成你的代理地址,或删掉这两行。
76
76
  export HTTPS_PROXY="${HTTPS_PROXY:-http://your-proxy:port}"; export https_proxy="$HTTPS_PROXY"
@@ -92,12 +92,12 @@ esac
92
92
  ```
93
93
 
94
94
  ```bash
95
- chmod +x ~/.weclaude/daemonctl.sh
96
- ~/.weclaude/daemonctl.sh start # 起 daemon(自带崩溃重启)
97
- ~/.weclaude/daemonctl.sh status # 看状态
95
+ chmod +x ~/.wezard/daemonctl.sh
96
+ ~/.wezard/daemonctl.sh start # 起 daemon(自带崩溃重启)
97
+ ~/.wezard/daemonctl.sh status # 看状态
98
98
  ```
99
99
 
100
- 容器重启不会自动拉起 daemon——把 `~/.weclaude/daemonctl.sh start` 加进 shell profile 或容器入口即可(幂等,已在跑就 no-op)。
100
+ 容器重启不会自动拉起 daemon——把 `~/.wezard/daemonctl.sh start` 加进 shell profile 或容器入口即可(幂等,已在跑就 no-op)。
101
101
 
102
102
  ---
103
103
 
@@ -111,9 +111,9 @@ chmod +x ~/.weclaude/daemonctl.sh
111
111
  | **流式输出** | 转发 assistant 文本块 | 完整流式:打字机、tool_use、思考过程都看得到 |
112
112
  | **适合谁** | 简单单轮问答 / CI 类自动化 | 真·远程结对编程 |
113
113
 
114
- 镜像模式下,IM 里发 `/new` 直接开新 tmux 窗口 + 新 Claude 会话;`/clear` 清当前上下文;带图消息自动注入剪贴板。所有 IM 聊天共享一个 tmux session(默认名 `weclaude`),每个聊天一个独立 window,**关 tmux / daemon 崩了 / 整机重启都能自愈**:IM↔会话绑定 write-through 落到 `~/.weclaude/mirror-attachments.json`,daemon 起来就 eager restore;重启后 pane 全死,下一条 IM 消息触发 `claude --resume <sid>` 拉起新 pane,`--resume` fork 出的新 jsonl 由 watcher 从 EOF 无缝接管(不会把整段历史再推一遍到 IM)。中途在别处 `/clear` 把 jsonl rotate 掉也不丢绑定,会自愈到同项目目录下最新的 jsonl。
114
+ 镜像模式下,IM 里发 `/new` 直接开新 tmux 窗口 + 新 Claude 会话;`/clear` 清当前上下文;带图消息自动注入剪贴板。所有 IM 聊天共享一个 tmux session(默认名 `wezard`),每个聊天一个独立 window,**关 tmux / daemon 崩了 / 整机重启都能自愈**:IM↔会话绑定 write-through 落到 `~/.wezard/mirror-attachments.json`,daemon 起来就 eager restore;重启后 pane 全死,下一条 IM 消息触发 `claude --resume <sid>` 拉起新 pane,`--resume` fork 出的新 jsonl 由 watcher 从 EOF 无缝接管(不会把整段历史再推一遍到 IM)。中途在别处 `/clear` 把 jsonl rotate 掉也不丢绑定,会自愈到同项目目录下最新的 jsonl。
115
115
 
116
- > 💡 **mirror 不要求你必须先在 CLI 里开 tmux**:在企业微信里直接发 `/new` 就能从零起一个新 tmux 窗口 + Claude 会话;甚至首次发任意消息都会自动 spawn + 绑定(首条消息既是绑定信号也是第一句 prompt)。回家打开终端 `tmux attach -t weclaude` 接管即可。
116
+ > 💡 **mirror 不要求你必须先在 CLI 里开 tmux**:在企业微信里直接发 `/new` 就能从零起一个新 tmux 窗口 + Claude 会话;甚至首次发任意消息都会自动 spawn + 绑定(首条消息既是绑定信号也是第一句 prompt)。回家打开终端 `tmux attach -t wezard` 接管即可。
117
117
 
118
118
  ---
119
119
 
@@ -145,7 +145,7 @@ chmod +x ~/.weclaude/daemonctl.sh
145
145
 
146
146
  ## 文档 / 智能表格 / 智能文档
147
147
 
148
- `weclaude` 把企业微信智能机器人的远端 MCP(doc / smartsheet / contact 等)桥接到本地 Claude,**不走 corp access_token**:daemon 直接复用 botId+secret 的 WS 长连,通过 `aibot_get_mcp_config` 命令拉到每个 category 的 Streamable HTTP MCP URL,再以 JSON-RPC 调 `tools/list` / `tools/call`,`x-openclaw-wecom-userid` header 透传文档归属人。
148
+ `wezard` 把企业微信智能机器人的远端 MCP(doc / smartsheet / contact 等)桥接到本地 Claude,**不走 corp access_token**:daemon 直接复用 botId+secret 的 WS 长连,通过 `aibot_get_mcp_config` 命令拉到每个 category 的 Streamable HTTP MCP URL,再以 JSON-RPC 调 `tools/list` / `tools/call`,`x-openclaw-wecom-userid` header 透传文档归属人。
149
149
 
150
150
  **前置一次性授权**:在企业微信「工作台 - 智能机器人 - 你的机器人 - 可使用权限」里勾选「文档」「智能表格」对应能力。第一次调用如果未授权,远端会返回结构化错误(errcode 851013)+ 授权链接,原样转给 Claude,照着点同意即可。
151
151
 
@@ -186,7 +186,7 @@ curl -sS -X POST http://127.0.0.1:17890/wedoc/invalidate -H 'content-type: appli
186
186
 
187
187
  ## 事件订阅 / 定时广播
188
188
 
189
- 一个轻量 pub/sub:任意群或单聊都能订阅一个 **topic**(自定义事件名),任何授权用户都能广播;daemon 内置分钟级调度器,每天定点自动推送。订阅关系与定时任务持久化到 `~/.weclaude/config.jsonc` 的 `topics` 段,`weclaude reload` 后自动恢复。
189
+ 一个轻量 pub/sub:任意群或单聊都能订阅一个 **topic**(自定义事件名),任何授权用户都能广播;daemon 内置分钟级调度器,每天定点自动推送。订阅关系与定时任务持久化到 `~/.wezard/config.jsonc` 的 `topics` 段,`wezard reload` 后自动恢复。
190
190
 
191
191
  **IM 命令**(在已授权的会话里说,中英文均可):
192
192
 
@@ -222,7 +222,7 @@ sequenceDiagram
222
222
  autonumber
223
223
  participant CC as Claude Code
224
224
  participant Hook as PreToolUse hook
225
- participant D as weclaude daemon
225
+ participant D as wezard daemon
226
226
  participant WS as WeCom WS
227
227
  participant U as 你 (IM)
228
228
 
@@ -246,7 +246,7 @@ sequenceDiagram
246
246
  autonumber
247
247
  participant U as 你 (IM)
248
248
  participant WS as WeCom WS
249
- participant D as weclaude daemon
249
+ participant D as wezard daemon
250
250
  participant T as tmux + claude
251
251
  participant J as session.jsonl
252
252
 
@@ -361,37 +361,37 @@ IM 里发 `/help` 可随时拉出完整命令表;每次 `/new`、`/clear` 之
361
361
  本机 shell:
362
362
 
363
363
  ```bash
364
- weclaude status # 看 daemon + WS 健康
365
- weclaude logs -f # 实时日志
366
- weclaude send <chat> <text> # 主动推消息
367
- weclaude reload # 重启 daemon(改了配置后用)
368
- weclaude unsync # 卸载 hook/MCP(保留 daemon)
369
- weclaude uninstall # 完整卸载(先于 npm uninstall)
364
+ wezard status # 看 daemon + WS 健康
365
+ wezard logs -f # 实时日志
366
+ wezard send <chat> <text> # 主动推消息
367
+ wezard reload # 重启 daemon(改了配置后用)
368
+ wezard unsync # 卸载 hook/MCP(保留 daemon)
369
+ wezard uninstall # 完整卸载(先于 npm uninstall)
370
370
  ```
371
371
 
372
- > ⚠️ **卸载顺序**:先 `weclaude uninstall` 再 `npm uninstall -g weclaude`。否则 launchd/systemd 会一直尝试拉起已删除的二进制。`~/.weclaude/` 下的 config/secrets 不会被清,二次安装可无缝复用。
372
+ > ⚠️ **卸载顺序**:先 `wezard uninstall` 再 `npm uninstall -g wezard`。否则 launchd/systemd 会一直尝试拉起已删除的二进制。`~/.wezard/` 下的 config/secrets 不会被清,二次安装可无缝复用。
373
373
 
374
374
  ---
375
375
 
376
376
  ## 常见问题
377
377
 
378
378
  **Q: hook 不触发?**
379
- `cat ~/.claude/settings.json | jq .hooks.PreToolUse`,没东西就跑 `weclaude sync` 重写。
379
+ `cat ~/.claude/settings.json | jq .hooks.PreToolUse`,没东西就跑 `wezard sync` 重写。
380
380
 
381
381
  **Q: 卡片点了没反应?**
382
382
  企业微信卡片就地刷新只有 5 秒窗口,超时不刷新是正常的,决策本身仍然生效。
383
383
 
384
384
  **Q: daemon 起不来?**
385
- `weclaude logs -f` 看;常见是 `botId` / `secret` 写错卡在 WebSocket 鉴权。
385
+ `wezard logs -f` 看;常见是 `botId` / `secret` 写错卡在 WebSocket 鉴权。
386
386
 
387
387
  **Q: 多机部署?**
388
- `config.jsonc` 可以纳入 dotfiles;`secrets.json` 每台机器独立填。第二台机器跑 `weclaude init` 会跳过覆盖提示,但仍要重新走 claim 步骤拿本机 IM principal。
388
+ `config.jsonc` 可以纳入 dotfiles;`secrets.json` 每台机器独立填。第二台机器跑 `wezard init` 会跳过覆盖提示,但仍要重新走 claim 步骤拿本机 IM principal。
389
389
 
390
390
  ---
391
391
 
392
392
  ## 架构一瞥
393
393
 
394
- 三个进程走 `127.0.0.1:17890` + `~/.weclaude/`:
394
+ 三个进程走 `127.0.0.1:17890` + `~/.wezard/`:
395
395
 
396
396
  ```
397
397
  WeCom ── WebSocket ──► daemon (常驻, launchd/systemd)
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env bash
2
- # weclaude CLI — talks to local weclaude daemon over HTTP and toggles launchd/systemd.
2
+ # wezard CLI — talks to local wezard daemon over HTTP and toggles launchd/systemd.
3
3
  set -uo pipefail
4
4
 
5
- DAEMON_BASE="${WECLAUDE_DAEMON_BASE:-http://127.0.0.1:17890}"
6
- LABEL="com.weclaude.daemon"
5
+ DAEMON_BASE="${WEZARD_DAEMON_BASE:-http://127.0.0.1:17890}"
6
+ LABEL="com.wezard.daemon"
7
7
  HOME_DIR="$HOME"
8
8
  OS="$(uname -s)"
9
9
 
10
10
  # Resolve symlinks so REPO_ROOT points at the real package dir even when this
11
- # script is invoked via the npm-installed bin symlink (e.g. ~/.npm-global/bin/weclaude).
11
+ # script is invoked via the npm-installed bin symlink (e.g. ~/.npm-global/bin/wezard).
12
12
  # macOS ships BSD readlink without -f, so chase the chain by hand.
13
13
  self="${BASH_SOURCE[0]}"
14
14
  while [[ -L "$self" ]]; do
@@ -24,8 +24,10 @@ shift || true
24
24
 
25
25
  usage() {
26
26
  cat <<'EOF'
27
- weclaude <subcommand>
27
+ wezard <subcommand>
28
28
  init interactive onboarding (write config, install daemon, claim default chat, run demo)
29
+ migrate upgrade an existing weclaude install (state + daemon + plugin + settings.json)
30
+ flags: --dry-run --force --purge -y
29
31
  status daemon health + connection state
30
32
  start load resident daemon (launchd/systemd)
31
33
  stop unload resident daemon
@@ -42,8 +44,8 @@ weclaude <subcommand>
42
44
  unsync remove our entries from sync.targets settings.json
43
45
  audit [tag] token/cost breakdown for current Claude session (main + subagents)
44
46
  uninstall full teardown: stop daemon + unsync + plugin uninstall + remove daemon (run before `npm uninstall -g`)
45
- add `--purge` to also delete ~/.weclaude state
46
- version print weclaude version
47
+ add `--purge` to also delete ~/.wezard state
48
+ version print wezard version
47
49
  help
48
50
  EOF
49
51
  }
@@ -51,37 +53,40 @@ EOF
51
53
  http_get() { curl -sS --max-time 5 "$DAEMON_BASE$1"; }
52
54
  http_post() { curl -sS --max-time 5 -X POST -H 'content-type: application/json' -d "${2:-{\}}" "$DAEMON_BASE$1"; }
53
55
 
56
+ # Run a dist/ entry script, building first when we're sitting in a dev checkout.
57
+ # npm installs ship dist/ in the tarball, so a missing script there means a
58
+ # broken install — fail loudly instead of invoking tsc against no tsconfig.
59
+ exec_node() {
60
+ local rel="$1"; shift
61
+ local script="$REPO_ROOT/$rel"
62
+ if [[ ! -f "$script" ]]; then
63
+ if [[ -f "$REPO_ROOT/tsconfig.json" ]]; then
64
+ echo "[wezard] building..."
65
+ (cd "$REPO_ROOT" && npm install --silent && npx tsc -p tsconfig.json) || { echo "build failed"; exit 1; }
66
+ else
67
+ echo "[wezard] missing $script — try 'npm install -g wezard' to reinstall" >&2
68
+ exit 1
69
+ fi
70
+ fi
71
+ exec "$(command -v node)" "$script" "$@"
72
+ }
73
+
54
74
  svc_load() {
55
75
  case "$OS" in
56
76
  Darwin) launchctl load -w "$HOME_DIR/Library/LaunchAgents/${LABEL}.plist" ;;
57
- Linux) systemctl --user start weclaude.service ;;
77
+ Linux) systemctl --user start wezard.service ;;
58
78
  esac
59
79
  }
60
80
  svc_unload() {
61
81
  case "$OS" in
62
82
  Darwin) launchctl unload "$HOME_DIR/Library/LaunchAgents/${LABEL}.plist" ;;
63
- Linux) systemctl --user stop weclaude.service ;;
83
+ Linux) systemctl --user stop wezard.service ;;
64
84
  esac
65
85
  }
66
86
 
67
87
  case "$cmd" in
68
- init)
69
- NODE_BIN="$(command -v node)"
70
- SCRIPT="$REPO_ROOT/dist/cli/init.js"
71
- if [[ ! -f "$SCRIPT" ]]; then
72
- # Dev repo: tsconfig.json present → build. npm install: tarball ships dist/,
73
- # so a missing init.js means a broken install — fail clearly instead of
74
- # invoking tsc against a non-existent tsconfig.
75
- if [[ -f "$REPO_ROOT/tsconfig.json" ]]; then
76
- echo "[weclaude init] building..."
77
- (cd "$REPO_ROOT" && npm install --silent && npx tsc -p tsconfig.json) || { echo "build failed"; exit 1; }
78
- else
79
- echo "[weclaude init] missing $SCRIPT — try 'npm install -g weclaude' to reinstall" >&2
80
- exit 1
81
- fi
82
- fi
83
- exec "$NODE_BIN" "$SCRIPT" "$@"
84
- ;;
88
+ init) exec_node dist/cli/init.js "$@" ;;
89
+ migrate) exec_node dist/cli/migrate.js "$@" ;;
85
90
  status)
86
91
  if ! out=$(http_get /status 2>/dev/null); then
87
92
  echo "daemon: down ($DAEMON_BASE)"
@@ -97,14 +102,14 @@ case "$cmd" in
97
102
  http_post /shutdown >/dev/null 2>&1 || true
98
103
  case "$OS" in
99
104
  Darwin) launchctl kickstart -k "gui/$(id -u)/${LABEL}" >/dev/null && echo "daemon: reloaded" ;;
100
- Linux) systemctl --user restart weclaude.service && echo "daemon: reloaded" ;;
105
+ Linux) systemctl --user restart wezard.service && echo "daemon: reloaded" ;;
101
106
  esac
102
107
  ;;
103
108
  send)
104
109
  chat="${1:-}"; shift || true
105
110
  text="${*:-}"
106
111
  if [[ -z "$chat" || -z "$text" ]]; then
107
- echo "usage: weclaude send <chat> <text>"; exit 1
112
+ echo "usage: wezard send <chat> <text>"; exit 1
108
113
  fi
109
114
  body=$(jq -nc --arg c "$chat" --arg t "$text" '{chat:$c,text:$t}')
110
115
  http_post /message "$body"
@@ -118,14 +123,14 @@ case "$cmd" in
118
123
  ;;
119
124
  logs)
120
125
  log_path=$(http_get /status 2>/dev/null | jq -r '.logFile // empty' 2>/dev/null || true)
121
- log_path="${log_path:-$HOME_DIR/.weclaude/daemon.log}"
126
+ log_path="${log_path:-$HOME_DIR/.wezard/daemon.log}"
122
127
  if [[ "${1:-}" == "-f" ]]; then tail -f "$log_path"; else tail -n 100 "$log_path"; fi
123
128
  ;;
124
129
  config-path) http_get /status | jq -r '.sourcePath // empty' ;;
125
130
  uninstall)
126
131
  # Order matters: stop the daemon FIRST so it can't rewrite settings/lock
127
132
  # files mid-teardown; then strip MCP/env from agent settings; then remove
128
- # the plist/unit + Claude plugin registration. State at ~/.weclaude is
133
+ # the plist/unit + Claude plugin registration. State at ~/.wezard is
129
134
  # preserved unless `--purge` is given.
130
135
  purge=0
131
136
  [[ "${1:-}" == "--purge" ]] && purge=1
@@ -134,14 +139,14 @@ case "$cmd" in
134
139
  SYNC_SCRIPT="$REPO_ROOT/dist/cli/sync.js"
135
140
  [[ -f "$SYNC_SCRIPT" ]] && "$NODE_BIN" "$SYNC_SCRIPT" --remove || true
136
141
  bash "$REPO_ROOT/scripts/uninstall.sh"
137
- rm -f "$HOME_DIR/.weclaude/sync.lock.json"
142
+ rm -f "$HOME_DIR/.wezard/sync.lock.json"
138
143
  if (( purge )); then
139
- rm -rf "$HOME_DIR/.weclaude"
140
- echo "[weclaude] state purged (~/.weclaude removed)"
144
+ rm -rf "$HOME_DIR/.wezard"
145
+ echo "[wezard] state purged (~/.wezard removed)"
141
146
  else
142
- echo "[weclaude] cleaned. state kept at ~/.weclaude — remove with 'weclaude uninstall --purge' or 'rm -rf ~/.weclaude'"
147
+ echo "[wezard] cleaned. state kept at ~/.wezard — remove with 'wezard uninstall --purge' or 'rm -rf ~/.wezard'"
143
148
  fi
144
- echo "[weclaude] safe to 'npm uninstall -g weclaude' now"
149
+ echo "[wezard] safe to 'npm uninstall -g wezard' now"
145
150
  ;;
146
151
  mirror)
147
152
  cwd="${CLAUDE_PROJECT_DIR:-${CODEBUDDY_PROJECT_DIR:-$(pwd)}}"
package/commands/audit.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: 统计当前会话(含子会话)的 token 用量与成本,不跨 /clear
3
- allowed-tools: Bash(${CLAUDE_PLUGIN_ROOT}/cli/weclaude.sh:*)
3
+ allowed-tools: Bash(${CLAUDE_PLUGIN_ROOT}/cli/wezard.sh:*)
4
4
  argument-hint: [tag]
5
5
  ---
6
6
 
7
- !`${CLAUDE_PLUGIN_ROOT}/cli/weclaude.sh audit $ARGUMENTS`
7
+ !`${CLAUDE_PLUGIN_ROOT}/cli/wezard.sh audit $ARGUMENTS`
package/commands/wrc.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: WeCom remote control — mirror current Claude session to WeCom
3
- allowed-tools: Bash(${CLAUDE_PLUGIN_ROOT}/cli/weclaude.sh:*)
3
+ allowed-tools: Bash(${CLAUDE_PLUGIN_ROOT}/cli/wezard.sh:*)
4
4
  argument-hint: [user:<userid>|chat:<chatid>]
5
5
  ---
6
6
 
7
- !`${CLAUDE_PLUGIN_ROOT}/cli/weclaude.sh mirror $ARGUMENTS`
7
+ !`${CLAUDE_PLUGIN_ROOT}/cli/wezard.sh mirror $ARGUMENTS`
@@ -1,5 +1,5 @@
1
- // Declarative config for weclaude. Copy to ~/.weclaude/config.jsonc and edit.
2
- // All paths support `~`. Secrets (botId/secret) can also live in ~/.weclaude/secrets.json
1
+ // Declarative config for wezard. Copy to ~/.wezard/config.jsonc and edit.
2
+ // All paths support `~`. Secrets (botId/secret) can also live in ~/.wezard/secrets.json
3
3
  // (same shape, deep-merged on top — keep secrets out of dotfile repos).
4
4
  {
5
5
  "$schema": "./schema.json",
@@ -19,8 +19,8 @@
19
19
  "daemon": {
20
20
  "host": "127.0.0.1",
21
21
  "port": 17890,
22
- "stateDir": "~/.weclaude/state",
23
- "logFile": "~/.weclaude/daemon.log",
22
+ "stateDir": "~/.wezard/state",
23
+ "logFile": "~/.wezard/daemon.log",
24
24
  "logLevel": "info" // trace|debug|info|warn|error
25
25
  },
26
26
 
@@ -43,7 +43,7 @@
43
43
  // "codebuddy": { "bin": "/usr/local/bin/codebuddy" }
44
44
  // },
45
45
  "cwd": "~", // workdir (mirror: must match the running claude's cwd)
46
- "sessionMapFile": "~/.weclaude/sessions.json",
46
+ "sessionMapFile": "~/.wezard/sessions.json",
47
47
  "extraArgs": [], // appended to `claude -p`
48
48
  "mirror": {
49
49
  // Pin a session id; empty → auto-pick latest .jsonl mtime under
@@ -69,11 +69,24 @@
69
69
  "sessionCacheMinutes": 30, // (session_id, tool, cmd_prefix_hash) → decision
70
70
  "windowMinutes": 5, // 「⏱ N 分钟」按钮:开窗口期间所有请求自动 allow
71
71
  "sensitiveArgRedact": true, // mask password/token-like values before sending to IM
72
- "fallbackOnError": "ask" // never "deny" — never break workflow
72
+ "fallbackOnError": "ask", // never "deny" — never break workflow
73
+
74
+ // 危险名单:命中者强制逐次单独审批 —— 不吃自动窗口、不吃 session cache、
75
+ // 不参与批量合流、卡上没有「N 分钟全过」按钮、超时降级 ask 不静默放行。
76
+ // 内置覆盖 rm/git push/kubectl delete/DROP TABLE/敏感路径等;下面三组正则
77
+ // (大小写不敏感) 追加自定义规则,allowPatterns 优先级最高。
78
+ "danger": {
79
+ "enabled": true,
80
+ "builtin": true,
81
+ "commandPatterns": [], // 例: ["\\bpm2\\s+delete\\b"]
82
+ "toolPatterns": [], // 例: ["^mcp__prod__"]
83
+ "pathPatterns": [], // 例: ["/prod/"]
84
+ "allowPatterns": [] // 例: ["\\brm\\s+-rf\\s+node_modules\\b"]
85
+ }
73
86
  },
74
87
 
75
88
  // ── claude / codebuddy wrapper sync ───────────────────────────────
76
- // `weclaude sync` writes hooks/MCP/permissions into every target settings.json
89
+ // `wezard sync` writes hooks/MCP/permissions into every target settings.json
77
90
  // listed below. Multi-CLI setups (claude + codebuddy 同时装) 列多项即可。
78
91
  // kind: "claude" (含 claude-internal 等 fork) | "codebuddy"
79
92
  // • claude-internal 通过 settingsPath: "~/.claude-internal/settings.json" 表达
@@ -90,13 +103,13 @@
90
103
  ]
91
104
  },
92
105
 
93
- // ── Standalone detail relay (weclaude svr) ────────────────────────
94
- // `weclaude svr` 读这里作为默认参数, CLI --host/--port 仍可覆盖。省略整段等于
106
+ // ── Standalone detail relay (wezard svr) ────────────────────────
107
+ // `wezard svr` 读这里作为默认参数, CLI --host/--port 仍可覆盖。省略整段等于
95
108
  // 用硬编码兜底 (0.0.0.0:17891)。改到 80 让详情页 URL 用标准端口 (需 root)。
96
109
  "svr": {
97
110
  "host": "0.0.0.0",
98
111
  "port": 17891,
99
- "stateDir": "~/.weclaude/svr",
100
- "tokenFile": "~/.weclaude/svr-token"
112
+ "stateDir": "~/.wezard/svr",
113
+ "tokenFile": "~/.wezard/svr-token"
101
114
  }
102
115
  }
package/dist/cli/audit.js CHANGED
@@ -1,4 +1,4 @@
1
- // Slash-command entry: `weclaude audit [tag]`.
1
+ // Slash-command entry: `wezard audit [tag]`.
2
2
  // - With a tag: ask the daemon for the newest-by-mtime mirror whose target
3
3
  // carries `#<tag>` and audit THAT session (regardless of which CLI/pane
4
4
  // the command was fired from). Fails hard when the daemon is down or no
@@ -13,7 +13,7 @@ import { readdirSync, statSync, existsSync } from "node:fs";
13
13
  import { basename, join } from "node:path";
14
14
  import { homedir } from "node:os";
15
15
  import { computeAuditReport } from "../daemon/audit.js";
16
- const DAEMON_BASE = process.env.WECLAUDE_DAEMON_BASE || "http://127.0.0.1:17890";
16
+ const DAEMON_BASE = process.env.WEZARD_DAEMON_BASE || "http://127.0.0.1:17890";
17
17
  const PROJECT_BASES = [
18
18
  join(homedir(), ".claude-internal", "projects"),
19
19
  join(homedir(), ".claude", "projects"),
@@ -1 +1 @@
1
- {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../cli/audit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../cli/audit.ts"],"names":[],"mappings":"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"}