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.
- package/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +3 -3
- package/CLAUDE.md +14 -14
- package/LICENSE +1 -1
- package/README.md +38 -38
- package/cli/{weclaude.sh → wezard.sh} +40 -35
- package/commands/audit.md +2 -2
- package/commands/wrc.md +2 -2
- package/config.example.jsonc +24 -11
- package/dist/cli/audit.js +2 -2
- package/dist/cli/audit.js.map +1 -1
- package/dist/cli/init.js +97 -24
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/migrate.js +213 -0
- package/dist/cli/migrate.js.map +1 -0
- package/dist/cli/sync.js +34 -26
- package/dist/cli/sync.js.map +1 -1
- package/dist/daemon/approval.js +45 -21
- package/dist/daemon/approval.js.map +1 -1
- package/dist/daemon/audit.js +1 -1
- package/dist/daemon/audit.js.map +1 -1
- package/dist/daemon/cc-bridge.js +1 -1
- package/dist/daemon/cc-bridge.js.map +1 -1
- package/dist/daemon/cfg-sync.js +4 -4
- package/dist/daemon/cfg-sync.js.map +1 -1
- package/dist/daemon/claim.js +2 -2
- package/dist/daemon/claim.js.map +1 -1
- package/dist/daemon/danger.js +102 -0
- package/dist/daemon/danger.js.map +1 -0
- package/dist/daemon/inbound.js +42 -40
- package/dist/daemon/inbound.js.map +1 -1
- package/dist/daemon/index.js +7 -7
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/mirror-bridge.js +18 -12
- package/dist/daemon/mirror-bridge.js.map +1 -1
- package/dist/daemon/pending.js +4 -0
- package/dist/daemon/pending.js.map +1 -1
- package/dist/daemon/quota.js +1 -1
- package/dist/daemon/quota.js.map +1 -1
- package/dist/daemon/session-scan.js +88 -26
- package/dist/daemon/session-scan.js.map +1 -1
- package/dist/daemon/spawn-tmux.js +5 -5
- package/dist/daemon/spawn-tmux.js.map +1 -1
- package/dist/daemon/usage.js +1 -1
- package/dist/daemon/usage.js.map +1 -1
- package/dist/daemon/wedoc.js +2 -2
- package/dist/daemon/wedoc.js.map +1 -1
- package/dist/mcp/server.js +4 -4
- package/dist/mcp/server.js.map +1 -1
- package/dist/shared/config-writer.js +1 -1
- package/dist/shared/config-writer.js.map +1 -1
- package/dist/shared/config.js +32 -19
- package/dist/shared/config.js.map +1 -1
- package/dist/shared/svr-token.js +22 -0
- package/dist/shared/svr-token.js.map +1 -0
- package/dist/svr/index.js +16 -31
- package/dist/svr/index.js.map +1 -1
- package/hooks/pre-tool-use.sh +24 -24
- package/launchd/{com.weclaude.daemon.plist.template → com.wezard.daemon.plist.template} +3 -3
- package/package.json +17 -14
- package/scripts/install.sh +15 -8
- package/scripts/postinstall.sh +2 -2
- package/scripts/uninstall.sh +35 -27
- package/systemd/{weclaude.service.template → wezard.service.template} +3 -3
- package/web/chat.css +13 -5
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wezard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Bridge Claude Code and WeCom: PreToolUse approval cards + bidirectional tmux session mirror with image paste",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/guxi11/
|
|
9
|
+
"url": "git+https://github.com/guxi11/wezard.git"
|
|
10
10
|
},
|
|
11
|
-
"homepage": "https://github.com/guxi11/
|
|
11
|
+
"homepage": "https://github.com/guxi11/wezard#readme",
|
|
12
12
|
"bugs": {
|
|
13
|
-
"url": "https://github.com/guxi11/
|
|
13
|
+
"url": "https://github.com/guxi11/wezard/issues"
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
16
16
|
"claude",
|
|
@@ -22,18 +22,21 @@
|
|
|
22
22
|
"mcp"
|
|
23
23
|
],
|
|
24
24
|
"bin": {
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
25
|
+
"wezard": "./cli/wezard.sh",
|
|
26
|
+
"wezard-daemon": "./dist/daemon/index.js",
|
|
27
|
+
"wezard-mcp": "./dist/mcp/server.js",
|
|
28
|
+
"wezard-init": "./dist/cli/init.js",
|
|
29
|
+
"wezard-migrate": "./dist/cli/migrate.js",
|
|
30
|
+
"wezard-svr": "./dist/svr/index.js"
|
|
30
31
|
},
|
|
31
32
|
"files": [
|
|
32
33
|
".claude-plugin/marketplace.json",
|
|
33
34
|
".claude-plugin/plugin.json",
|
|
34
|
-
"cli/
|
|
35
|
+
"cli/wezard.sh",
|
|
35
36
|
"dist/cli/init.js",
|
|
36
37
|
"dist/cli/init.js.map",
|
|
38
|
+
"dist/cli/migrate.js",
|
|
39
|
+
"dist/cli/migrate.js.map",
|
|
37
40
|
"dist/cli/sync.js",
|
|
38
41
|
"dist/cli/sync.js.map",
|
|
39
42
|
"dist/cli/audit.js",
|
|
@@ -53,8 +56,8 @@
|
|
|
53
56
|
"scripts/install.sh",
|
|
54
57
|
"scripts/uninstall.sh",
|
|
55
58
|
"scripts/postinstall.sh",
|
|
56
|
-
"launchd/com.
|
|
57
|
-
"systemd/
|
|
59
|
+
"launchd/com.wezard.daemon.plist.template",
|
|
60
|
+
"systemd/wezard.service.template",
|
|
58
61
|
"config.example.jsonc",
|
|
59
62
|
"commands/wrc.md",
|
|
60
63
|
"commands/audit.md",
|
|
@@ -63,9 +66,9 @@
|
|
|
63
66
|
"LICENSE"
|
|
64
67
|
],
|
|
65
68
|
"scripts": {
|
|
66
|
-
"build": "tsc -p tsconfig.json && chmod +x dist/cli/init.js dist/cli/audit.js dist/daemon/index.js dist/mcp/server.js dist/svr/index.js",
|
|
69
|
+
"build": "tsc -p tsconfig.json && chmod +x dist/cli/init.js dist/cli/migrate.js dist/cli/audit.js dist/daemon/index.js dist/mcp/server.js dist/svr/index.js",
|
|
67
70
|
"dev:daemon": "tsx daemon/index.ts",
|
|
68
|
-
"dev:cli": "tsx cli/
|
|
71
|
+
"dev:cli": "tsx cli/init.ts",
|
|
69
72
|
"typecheck": "tsc --noEmit",
|
|
70
73
|
"prepare": "test -f dist/daemon/index.js || npm run build",
|
|
71
74
|
"prepublishOnly": "rm -rf dist && npm run build",
|
package/scripts/install.sh
CHANGED
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# Install resident
|
|
2
|
+
# Install a resident wezard service. Auto-detects macOS (launchd) vs Linux (systemd --user).
|
|
3
|
+
# install.sh [daemon|svr] (default: daemon)
|
|
3
4
|
set -euo pipefail
|
|
4
5
|
|
|
5
6
|
REPO="$(cd "$(dirname "$0")/.." && pwd)"
|
|
6
7
|
NODE="$(command -v node)"
|
|
7
8
|
HOME_DIR="$HOME"
|
|
8
|
-
|
|
9
|
+
|
|
10
|
+
COMPONENT="${1:-daemon}"
|
|
11
|
+
case "$COMPONENT" in
|
|
12
|
+
daemon) LABEL="com.wezard.daemon"; UNIT="wezard.service"; ENTRY="dist/daemon/index.js" ;;
|
|
13
|
+
svr) LABEL="com.wezard.svr"; UNIT="wezard-svr.service"; ENTRY="dist/svr/index.js" ;;
|
|
14
|
+
*) echo "usage: install.sh [daemon|svr]"; exit 2 ;;
|
|
15
|
+
esac
|
|
9
16
|
|
|
10
17
|
[[ -x "$NODE" ]] || { echo "node not found in PATH"; exit 1; }
|
|
11
18
|
|
|
12
19
|
# Build if missing
|
|
13
|
-
if [[ ! -f "$REPO
|
|
20
|
+
if [[ ! -f "$REPO/$ENTRY" ]]; then
|
|
14
21
|
echo "[install] building..."
|
|
15
22
|
(cd "$REPO" && npm install --silent && npx tsc -p tsconfig.json)
|
|
16
23
|
fi
|
|
17
24
|
|
|
18
|
-
mkdir -p "$HOME_DIR/.
|
|
25
|
+
mkdir -p "$HOME_DIR/.wezard"
|
|
19
26
|
|
|
20
27
|
OS="$(uname -s)"
|
|
21
28
|
case "$OS" in
|
|
@@ -56,18 +63,18 @@ case "$OS" in
|
|
|
56
63
|
Linux)
|
|
57
64
|
UNIT_DIR="$HOME_DIR/.config/systemd/user"
|
|
58
65
|
mkdir -p "$UNIT_DIR"
|
|
59
|
-
UNIT_DST="$UNIT_DIR
|
|
66
|
+
UNIT_DST="$UNIT_DIR/$UNIT"
|
|
60
67
|
sed \
|
|
61
68
|
-e "s|__NODE__|$NODE|g" \
|
|
62
69
|
-e "s|__REPO__|$REPO|g" \
|
|
63
70
|
-e "s|__HOME__|$HOME_DIR|g" \
|
|
64
|
-
"$REPO/systemd
|
|
71
|
+
"$REPO/systemd/${UNIT}.template" > "$UNIT_DST"
|
|
65
72
|
systemctl --user daemon-reload
|
|
66
|
-
systemctl --user enable --now
|
|
73
|
+
systemctl --user enable --now "$UNIT"
|
|
67
74
|
echo "[install] systemd unit enabled: $UNIT_DST"
|
|
68
75
|
;;
|
|
69
76
|
*)
|
|
70
77
|
echo "unsupported OS: $OS"; exit 1 ;;
|
|
71
78
|
esac
|
|
72
79
|
|
|
73
|
-
echo "[install] done. Logs at $HOME_DIR/.
|
|
80
|
+
echo "[install] $COMPONENT done. Logs at $HOME_DIR/.wezard/"
|
package/scripts/postinstall.sh
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
2
|
# Refresh the Claude Code plugin clone after `npm install -g` so the
|
|
3
|
-
# marketplace copy at ~/.claude/plugins/marketplaces/
|
|
3
|
+
# marketplace copy at ~/.claude/plugins/marketplaces/wezard-local/ stays
|
|
4
4
|
# in lockstep with the npm global install. Silent no-op in any irrelevant
|
|
5
5
|
# context (local dev install, claude not on PATH, marketplace never added).
|
|
6
6
|
# Must never fail npm install.
|
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
[ "$npm_config_global" = "true" ] || exit 0
|
|
9
9
|
command -v claude >/dev/null 2>&1 || exit 0
|
|
10
10
|
|
|
11
|
-
claude plugin marketplace update
|
|
11
|
+
claude plugin marketplace update wezard-local >/dev/null 2>&1 || true
|
|
12
12
|
exit 0
|
package/scripts/uninstall.sh
CHANGED
|
@@ -1,44 +1,52 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
set -uo pipefail
|
|
3
|
-
LABEL="com.weclaude.daemon"
|
|
4
3
|
HOME_DIR="$HOME"
|
|
5
4
|
OS="$(uname -s)"
|
|
6
5
|
REPO="$(cd "$(dirname "$0")/.." && pwd)"
|
|
7
6
|
|
|
7
|
+
# label | systemd unit | entry script (for the pkill sweep)
|
|
8
|
+
SERVICES=(
|
|
9
|
+
"com.wezard.daemon|wezard.service|dist/daemon/index.js"
|
|
10
|
+
"com.wezard.svr|wezard-svr.service|dist/svr/index.js"
|
|
11
|
+
)
|
|
12
|
+
|
|
8
13
|
# Best-effort: drop the Claude Code plugin + marketplace registration installed
|
|
9
|
-
# by `
|
|
14
|
+
# by `wezard init`. Tries both `claude` and `claude-internal` since either
|
|
10
15
|
# could have been used at install time. All failures are non-fatal — uninstall
|
|
11
16
|
# must keep going even if claude binaries are gone.
|
|
12
17
|
for bin in claude claude-internal; do
|
|
13
18
|
command -v "$bin" >/dev/null 2>&1 || continue
|
|
14
|
-
"$bin" plugin uninstall
|
|
19
|
+
"$bin" plugin uninstall wezard@wezard-local 2>/dev/null && \
|
|
15
20
|
echo "[uninstall] $bin: plugin uninstalled" || true
|
|
16
21
|
"$bin" plugin marketplace remove "$REPO" 2>/dev/null && \
|
|
17
22
|
echo "[uninstall] $bin: marketplace removed" || true
|
|
18
23
|
done
|
|
19
24
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
25
|
+
for svc in "${SERVICES[@]}"; do
|
|
26
|
+
IFS='|' read -r LABEL UNIT ENTRY <<< "$svc"
|
|
27
|
+
case "$OS" in
|
|
28
|
+
Darwin)
|
|
29
|
+
PLIST="$HOME_DIR/Library/LaunchAgents/${LABEL}.plist"
|
|
30
|
+
if [[ -f "$PLIST" ]]; then
|
|
31
|
+
launchctl unload "$PLIST" 2>/dev/null || true
|
|
32
|
+
rm -f "$PLIST"
|
|
33
|
+
echo "[uninstall] removed $PLIST"
|
|
34
|
+
fi
|
|
35
|
+
# Belt-and-braces: launchctl unload can leave a stray process if the plist
|
|
36
|
+
# was edited mid-flight. bootout the label, then SIGTERM any survivors.
|
|
37
|
+
launchctl bootout "gui/$(id -u)/${LABEL}" 2>/dev/null || true
|
|
38
|
+
pkill -f "$ENTRY" 2>/dev/null || true
|
|
39
|
+
;;
|
|
40
|
+
Linux)
|
|
41
|
+
UNIT_PATH="$HOME_DIR/.config/systemd/user/$UNIT"
|
|
42
|
+
if [[ -f "$UNIT_PATH" ]]; then
|
|
43
|
+
systemctl --user disable --now "$UNIT" 2>/dev/null || true
|
|
44
|
+
rm -f "$UNIT_PATH"
|
|
45
|
+
systemctl --user daemon-reload
|
|
46
|
+
echo "[uninstall] removed $UNIT_PATH"
|
|
47
|
+
fi
|
|
48
|
+
pkill -f "$ENTRY" 2>/dev/null || true
|
|
49
|
+
;;
|
|
50
|
+
esac
|
|
51
|
+
done
|
|
44
52
|
echo "[uninstall] done."
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[Unit]
|
|
2
|
-
Description=
|
|
2
|
+
Description=wezard daemon (WeCom remote control for Claude Code)
|
|
3
3
|
After=network-online.target
|
|
4
4
|
Wants=network-online.target
|
|
5
5
|
|
|
@@ -9,8 +9,8 @@ WorkingDirectory=__REPO__
|
|
|
9
9
|
ExecStart=__NODE__ __REPO__/dist/daemon/index.js
|
|
10
10
|
Restart=always
|
|
11
11
|
RestartSec=5
|
|
12
|
-
StandardOutput=append:__HOME__/.
|
|
13
|
-
StandardError=append:__HOME__/.
|
|
12
|
+
StandardOutput=append:__HOME__/.wezard/daemon.stdout.log
|
|
13
|
+
StandardError=append:__HOME__/.wezard/daemon.stderr.log
|
|
14
14
|
Environment=NODE_ENV=production
|
|
15
15
|
|
|
16
16
|
[Install]
|
package/web/chat.css
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
由 /chat/app.css 拼在本文件之前 —— 这里只管三栏骨架、会话列表与页脚总账。 */
|
|
3
3
|
|
|
4
4
|
html, body { height: 100% }
|
|
5
|
-
|
|
5
|
+
/* overscroll-behavior:none 阻止整页橡皮筋回弹 —— webview 里它会和内层
|
|
6
|
+
.thread 抢滚动手势, 表现为"滚一下卡住/整页在弹"。 */
|
|
7
|
+
body { overflow: hidden; overscroll-behavior: none }
|
|
6
8
|
|
|
7
9
|
.app { display: flex; height: 100vh; height: 100dvh }
|
|
8
10
|
|
|
@@ -77,7 +79,10 @@ body { overflow: hidden }
|
|
|
77
79
|
.tags .empty-side { padding: 28px 12px; text-align: center; color: #8c959f; font-size: 12px }
|
|
78
80
|
|
|
79
81
|
/* ── 主区 ───────────────────────────────────────────────────────── */
|
|
80
|
-
|
|
82
|
+
/* min-height:0 给纵向 flex (mobile) 用: 缺了它 .main 的 min-height:auto 会被
|
|
83
|
+
内容撑破 100dvh, .thread 不产生内部滚动, 底部被 body overflow:hidden 裁掉。
|
|
84
|
+
横向 (桌面) 下无副作用 —— 高度本来就由 stretch 定死。 */
|
|
85
|
+
.main { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column }
|
|
81
86
|
.topbar {
|
|
82
87
|
flex: none; display: flex; align-items: center; gap: 10px; padding: 11px 20px;
|
|
83
88
|
background: #fff; border-bottom: 1px solid #d0d7de;
|
|
@@ -93,6 +98,7 @@ body { overflow: hidden }
|
|
|
93
98
|
.thread {
|
|
94
99
|
flex: 1; min-height: 0; overflow-y: auto; overflow-anchor: none;
|
|
95
100
|
padding: 16px 20px 24px; -webkit-overflow-scrolling: touch;
|
|
101
|
+
overscroll-behavior: contain;
|
|
96
102
|
}
|
|
97
103
|
.thread-in { max-width: 920px; margin: 0 auto; display: flex; flex-direction: column; gap: 18px }
|
|
98
104
|
.empty { color: #8c959f; text-align: center; padding: 60px 0; font-size: 13px }
|
|
@@ -128,7 +134,9 @@ body { overflow: hidden }
|
|
|
128
134
|
/* ── 页脚总账 ───────────────────────────────────────────────────── */
|
|
129
135
|
.statusbar {
|
|
130
136
|
flex: none; display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
|
|
131
|
-
|
|
137
|
+
/* viewport-fit=cover 已开, 底部给 home indicator 让位 (桌面 env=0, 无感)。 */
|
|
138
|
+
padding: 7px 20px calc(7px + env(safe-area-inset-bottom));
|
|
139
|
+
background: #fff; border-top: 1px solid #d0d7de;
|
|
132
140
|
font-size: 11.5px; color: #57606a; font-family: ui-monospace, Menlo, monospace;
|
|
133
141
|
}
|
|
134
142
|
.statusbar .st { display: flex; align-items: baseline; gap: 5px }
|
|
@@ -161,11 +169,11 @@ body { overflow: hidden }
|
|
|
161
169
|
|
|
162
170
|
@media (max-width: 760px) {
|
|
163
171
|
.app { flex-direction: column }
|
|
164
|
-
.side { width: auto; border-right: 0; border-bottom: 1px solid #d0d7de; max-height: 44vh }
|
|
172
|
+
.side { width: auto; border-right: 0; border-bottom: 1px solid #d0d7de; max-height: 44vh; max-height: 44dvh }
|
|
165
173
|
.app.reading .side { display: none }
|
|
166
174
|
.app.reading .topbar .back { display: block }
|
|
167
175
|
.thread { padding: 12px }
|
|
168
176
|
.turn-group { padding: 12px }
|
|
169
|
-
.statusbar { gap: 10px; padding: 7px 12px }
|
|
177
|
+
.statusbar { gap: 10px; padding: 7px 12px calc(7px + env(safe-area-inset-bottom)) }
|
|
170
178
|
.sb-io, .statusbar .model { display: none }
|
|
171
179
|
}
|