dsh-pad-kit 0.0.0-stage → 1.0.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/AGENT-INSTALL.md +126 -0
- package/LICENSE +21 -0
- package/README.md +342 -2
- package/cordis.patch.yml +9 -0
- package/dsh-android-kit.tgz +0 -0
- package/install-unix.sh +86 -0
- package/install-windows.ps1 +102 -0
- package/kit/bootstrap.tmpl +102 -0
- package/kit/dsh-home.js +33 -0
- package/kit/install-addon.sh +56 -0
- package/kit/narb-build.tgz +0 -0
- package/kit/patch-flock.js +75 -0
- package/kit/patch-link.js +133 -0
- package/kit/setup.sh +178 -0
- package/kit/start-dsh.sh +39 -0
- package/kit/termux-boot.apk +0 -0
- package/kit/termux.apk +4 -0
- package/lib/plugin.js +696 -0
- package/package.json +43 -4
- package//344/275/277/347/224/250/350/257/264/346/230/216.md +68 -0
package/kit/setup.sh
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
#!/data/data/com.termux/files/usr/bin/bash
|
|
2
|
+
# ---------------------------------------------------------------------------
|
|
3
|
+
# DSH Android (Termux) 一键安装器
|
|
4
|
+
# 在平板的 Termux 里执行:bash setup.sh
|
|
5
|
+
# 作用:装 node → 装 dsh → 编译 android-arm64 原生绑定 → 打 3 个补丁
|
|
6
|
+
# → 起服务(3080)+ 固定入口(3081)→ 打印可打开的网址
|
|
7
|
+
# ---------------------------------------------------------------------------
|
|
8
|
+
set -u
|
|
9
|
+
KIT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
10
|
+
HOME_DIR="${HOME:-/data/data/com.termux/files/home}"
|
|
11
|
+
PREFIX_DIR="${PREFIX:-/data/data/com.termux/files/usr}"
|
|
12
|
+
|
|
13
|
+
LOGDIR="$HOME_DIR/.dsh-kit/logs"
|
|
14
|
+
mkdir -p "$LOGDIR" 2>/dev/null
|
|
15
|
+
|
|
16
|
+
log() { printf '\n[kit] %s\n' "$*"; }
|
|
17
|
+
warn() { printf '[kit] ! %s\n' "$*"; }
|
|
18
|
+
fail() { printf '\n[kit] 失败:%s\n' "$*"; exit 1; }
|
|
19
|
+
|
|
20
|
+
log "DSH Android 安装器"
|
|
21
|
+
log "kit 目录:$KIT_DIR"
|
|
22
|
+
log "HOME:$HOME_DIR"
|
|
23
|
+
|
|
24
|
+
ARCH="$(uname -m 2>/dev/null || echo unknown)"
|
|
25
|
+
case "$ARCH" in
|
|
26
|
+
aarch64|arm64) ;;
|
|
27
|
+
*) fail "只支持 arm64/aarch64 平板,当前是 $ARCH" ;;
|
|
28
|
+
esac
|
|
29
|
+
|
|
30
|
+
# ---------------------------------------------------------------------------
|
|
31
|
+
# 1. 基础依赖
|
|
32
|
+
# ---------------------------------------------------------------------------
|
|
33
|
+
log "1/6 检查并安装依赖:nodejs clang make python3 binutils tar"
|
|
34
|
+
if command -v pkg >/dev/null 2>&1; then
|
|
35
|
+
pkg install -y nodejs clang make python3 binutils tar >$LOGDIR/kit-pkg.log 2>&1 || warn "pkg install 有警告,见 $LOGDIR/kit-pkg.log"
|
|
36
|
+
else
|
|
37
|
+
warn "没有 pkg 命令,假定依赖已手动装好"
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
command -v node >/dev/null 2>&1 || fail "node 没装上"
|
|
41
|
+
command -v npm >/dev/null 2>&1 || fail "npm 没装上"
|
|
42
|
+
log " node $(node -v) / npm $(npm -v)"
|
|
43
|
+
command -v clang >/dev/null 2>&1 || warn "没有 clang,编译原生绑定大概率失败"
|
|
44
|
+
|
|
45
|
+
# ---------------------------------------------------------------------------
|
|
46
|
+
# 2. 安装 DSH CLI
|
|
47
|
+
# ---------------------------------------------------------------------------
|
|
48
|
+
log "2/6 检查 DSH CLI"
|
|
49
|
+
if command -v dsh >/dev/null 2>&1; then
|
|
50
|
+
log " 已安装:$(dsh --version 2>&1 | head -n 1)"
|
|
51
|
+
else
|
|
52
|
+
log " 正在安装 @deepseek-ai/dsh(--ignore-scripts,跳过 koffi 的 cmake 编译)"
|
|
53
|
+
npm i -g @deepseek-ai/dsh --ignore-scripts --no-audit --no-fund >$LOGDIR/kit-npm.log 2>&1 \
|
|
54
|
+
|| { tail -n 20 $LOGDIR/kit-npm.log; fail "npm 安装 dsh 失败(见 $LOGDIR/kit-npm.log)"; }
|
|
55
|
+
command -v dsh >/dev/null 2>&1 || fail "dsh 装完但不在 PATH"
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
PKG_ROOT="$(npm root -g 2>/dev/null)"
|
|
59
|
+
DSH_DIR="$PKG_ROOT/@deepseek-ai/dsh"
|
|
60
|
+
[ -d "$DSH_DIR" ] || fail "找不到 dsh 安装目录:$DSH_DIR"
|
|
61
|
+
|
|
62
|
+
# ---------------------------------------------------------------------------
|
|
63
|
+
# 3. 编译 android-arm64 原生绑定(官方没发布)
|
|
64
|
+
# ---------------------------------------------------------------------------
|
|
65
|
+
log "3/6 检查 node-addon-require-builtin 的 android-arm64 绑定"
|
|
66
|
+
ADDON_DIR="$(find "$PKG_ROOT" -type d -name 'node-addon-require-builtin' -not -path '*-android-arm64*' 2>/dev/null | head -n 1)"
|
|
67
|
+
[ -n "${ADDON_DIR:-}" ] || fail "找不到 node-addon-require-builtin 包"
|
|
68
|
+
TARGET_DIR="$(dirname "$ADDON_DIR")/node-addon-require-builtin-android-arm64"
|
|
69
|
+
BINDING="$TARGET_DIR/prebuilt/android-arm64-napi-v9.node"
|
|
70
|
+
|
|
71
|
+
if [ -f "$BINDING" ]; then
|
|
72
|
+
log " 已存在,跳过编译:$BINDING"
|
|
73
|
+
else
|
|
74
|
+
log " 开始编译(1~3 分钟,取决于平板性能)"
|
|
75
|
+
WORK="$HOME_DIR/.dsh-kit/narb"
|
|
76
|
+
rm -rf "$WORK"; mkdir -p "$WORK"
|
|
77
|
+
tar -xzf "$KIT_DIR/narb-build.tgz" -C "$WORK" || fail "解压 narb-build.tgz 失败"
|
|
78
|
+
( cd "$WORK" \
|
|
79
|
+
&& npm install --no-audit --no-fund >$LOGDIR/kit-narb-npm.log 2>&1 \
|
|
80
|
+
&& ./node_modules/.bin/node-gyp rebuild --nodedir="$PREFIX_DIR" \
|
|
81
|
+
--python="$(command -v python3)" -j 4 >$LOGDIR/kit-narb-build.log 2>&1 ) \
|
|
82
|
+
|| { tail -n 30 $LOGDIR/kit-narb-build.log 2>/dev/null; fail "原生绑定编译失败(见 $LOGDIR/kit-narb-build.log)"; }
|
|
83
|
+
[ -f "$WORK/build/Release/require_builtin.node" ] || fail "编译没产出 require_builtin.node"
|
|
84
|
+
bash "$KIT_DIR/install-addon.sh" "$WORK/build/Release/require_builtin.node" "$TARGET_DIR" \
|
|
85
|
+
|| fail "安装原生绑定包失败"
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# ---------------------------------------------------------------------------
|
|
89
|
+
# 4. 打补丁(flock / 硬链接)
|
|
90
|
+
# ---------------------------------------------------------------------------
|
|
91
|
+
log "4/6 打 Android 兼容补丁"
|
|
92
|
+
node "$KIT_DIR/patch-flock.js" || fail "flock 补丁失败"
|
|
93
|
+
node "$KIT_DIR/patch-link.js" || fail "硬链接补丁失败"
|
|
94
|
+
|
|
95
|
+
# ---------------------------------------------------------------------------
|
|
96
|
+
# 5. 安装启动脚本与固定入口
|
|
97
|
+
# ---------------------------------------------------------------------------
|
|
98
|
+
log "5/6 安装启动脚本"
|
|
99
|
+
install -m 644 "$KIT_DIR/dsh-home.js" "$HOME_DIR/dsh-home.js" || fail "安装 dsh-home.js 失败"
|
|
100
|
+
install -m 755 "$KIT_DIR/start-dsh.sh" "$HOME_DIR/start-dsh.sh" || fail "安装 start-dsh.sh 失败"
|
|
101
|
+
mkdir -p "$HOME_DIR/dshpad"
|
|
102
|
+
|
|
103
|
+
# ---------------------------------------------------------------------------
|
|
104
|
+
# 6. 启动
|
|
105
|
+
# ---------------------------------------------------------------------------
|
|
106
|
+
log "6/6 启动 DSH 与固定入口"
|
|
107
|
+
bash "$HOME_DIR/start-dsh.sh"
|
|
108
|
+
|
|
109
|
+
# ---------------------------------------------------------------------------
|
|
110
|
+
# 附加:Termux:Boot(开机自启的注册方,装完必须打开一次才生效)
|
|
111
|
+
# ---------------------------------------------------------------------------
|
|
112
|
+
# 开机自启脚本(Termux:Boot 的入口;bootstrap 里也会写,这里保证「远程修」也能补上)
|
|
113
|
+
BOOT_DIR="$HOME/.termux/boot"
|
|
114
|
+
BOOT_SH="$BOOT_DIR/start-dsh.sh"
|
|
115
|
+
mkdir -p "$BOOT_DIR"
|
|
116
|
+
cat > "$BOOT_SH.new" <<'BOOTEOF'
|
|
117
|
+
#!/data/data/com.termux/files/usr/bin/bash
|
|
118
|
+
export HOME=/data/data/com.termux/files/home
|
|
119
|
+
export PREFIX=/data/data/com.termux/files/usr
|
|
120
|
+
export PATH=$PREFIX/bin:$PATH
|
|
121
|
+
{
|
|
122
|
+
echo "=== boot $(date '+%Y-%m-%d %H:%M:%S') ==="
|
|
123
|
+
command -v termux-wake-lock >/dev/null 2>&1 && termux-wake-lock
|
|
124
|
+
sleep 8
|
|
125
|
+
[ -x "$HOME/start-dsh.sh" ] && bash "$HOME/start-dsh.sh" || echo "missing $HOME/start-dsh.sh"
|
|
126
|
+
} >> "$HOME/dsh-boot.log" 2>&1
|
|
127
|
+
BOOTEOF
|
|
128
|
+
chmod +x "$BOOT_SH.new"
|
|
129
|
+
if [ -f "$BOOT_SH" ] && command -v cmp >/dev/null 2>&1 && cmp -s "$BOOT_SH" "$BOOT_SH.new"; then
|
|
130
|
+
rm -f "$BOOT_SH.new"
|
|
131
|
+
log "开机脚本已是最新:$BOOT_SH"
|
|
132
|
+
else
|
|
133
|
+
mv -f "$BOOT_SH.new" "$BOOT_SH"
|
|
134
|
+
log "开机脚本已写入:$BOOT_SH"
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
log "附加:检查 Termux:Boot"
|
|
138
|
+
BOOT_MARK=""
|
|
139
|
+
PM_BIN=/system/bin/pm
|
|
140
|
+
[ -x "$PM_BIN" ] || PM_BIN=pm
|
|
141
|
+
if $PM_BIN list packages 2>/dev/null | grep -q 'com\.termux\.boot'; then
|
|
142
|
+
BOOT_MARK="已安装(重启平板后 DSH 会自动起来)"
|
|
143
|
+
else
|
|
144
|
+
BOOT_APK=""
|
|
145
|
+
for candidate in "/sdcard/Download/termux-boot.apk" \
|
|
146
|
+
"$HOME/storage/downloads/termux-boot.apk" \
|
|
147
|
+
"/storage/emulated/0/Download/termux-boot.apk"; do
|
|
148
|
+
if [ -f "$candidate" ]; then BOOT_APK="$candidate"; break; fi
|
|
149
|
+
done
|
|
150
|
+
if [ -z "$BOOT_APK" ]; then
|
|
151
|
+
BOOT_MARK="未安装,也没找到 termux-boot.apk(先去安装页点「下载 Termux:Boot APK」;读不到 /sdcard 时先 termux-setup-storage 再重跑)"
|
|
152
|
+
elif command -v termux-open >/dev/null 2>&1; then
|
|
153
|
+
termux-open --content-type application/vnd.android.package-archive "$BOOT_APK" >/dev/null 2>&1
|
|
154
|
+
BOOT_MARK="已请求拉起安装界面($BOOT_APK)。没弹出就是被 Android 拦了后台启动:把 Termux 切到前台重跑本脚本,或用文件管理器点开这个 APK 手动装;装完务必点一次「打开」"
|
|
155
|
+
else
|
|
156
|
+
BOOT_MARK="缺 termux-open,跳过自动拉起:$BOOT_APK"
|
|
157
|
+
fi
|
|
158
|
+
fi
|
|
159
|
+
log "Termux:Boot:$BOOT_MARK"
|
|
160
|
+
|
|
161
|
+
FIXED="http://127.0.0.1:3081/"
|
|
162
|
+
TOKEN_URL="$(cat "$HOME_DIR/dshpad/url.txt" 2>/dev/null)"
|
|
163
|
+
cat <<EOF
|
|
164
|
+
|
|
165
|
+
============================================================
|
|
166
|
+
安装完成
|
|
167
|
+
------------------------------------------------------------
|
|
168
|
+
固定网址(以后只记这个,重启后仍可用):$FIXED
|
|
169
|
+
当前 token 直连:${TOKEN_URL:-(未取到,见 ~/dshpad/web.log)}
|
|
170
|
+
Termux:Boot:$BOOT_MARK
|
|
171
|
+
|
|
172
|
+
在平板浏览器打开后:
|
|
173
|
+
菜单 → 添加到主屏幕,以后一点就进
|
|
174
|
+
|
|
175
|
+
平板重启 / Termux 被杀后重新拉起:
|
|
176
|
+
bash ~/start-dsh.sh
|
|
177
|
+
============================================================
|
|
178
|
+
EOF
|
package/kit/start-dsh.sh
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/data/data/com.termux/files/usr/bin/bash
|
|
2
|
+
export HOME=/data/data/com.termux/files/home
|
|
3
|
+
mkdir -p $HOME/dshpad
|
|
4
|
+
termux-wake-lock 2>/dev/null
|
|
5
|
+
|
|
6
|
+
echo "=== 停掉旧的 dsh 与旧入口 ==="
|
|
7
|
+
pkill -f 'dsh --profile web' 2>/dev/null
|
|
8
|
+
pkill -f dsh-home.js 2>/dev/null
|
|
9
|
+
sleep 2
|
|
10
|
+
|
|
11
|
+
echo "=== 启动 dsh web ==="
|
|
12
|
+
rm -f $HOME/dshpad/web.log $HOME/dshpad/url.txt
|
|
13
|
+
nohup dsh --profile web --host 127.0.0.1 --port 3080 --no-open > $HOME/dshpad/web.log 2>&1 &
|
|
14
|
+
|
|
15
|
+
URL=""
|
|
16
|
+
for i in $(seq 1 40); do
|
|
17
|
+
URL=$(grep -o 'http://127.0.0.1:3080/?token=[A-Za-z0-9_-]*' $HOME/dshpad/web.log 2>/dev/null | tail -1)
|
|
18
|
+
[ -n "$URL" ] && break
|
|
19
|
+
sleep 1
|
|
20
|
+
done
|
|
21
|
+
|
|
22
|
+
if [ -z "$URL" ]; then
|
|
23
|
+
echo "FAILED: 没有拿到 token URL"
|
|
24
|
+
tail -20 $HOME/dshpad/web.log
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
echo "$URL" > $HOME/dshpad/url.txt
|
|
28
|
+
echo "TOKEN_URL=$URL"
|
|
29
|
+
|
|
30
|
+
echo "=== 启动固定入口 3081 ==="
|
|
31
|
+
nohup node $HOME/dsh-home.js > $HOME/dshpad/home.log 2>&1 &
|
|
32
|
+
sleep 2
|
|
33
|
+
cat $HOME/dshpad/home.log
|
|
34
|
+
|
|
35
|
+
echo "=== 自检 ==="
|
|
36
|
+
curl -s -o /dev/null -w "home=%{http_code}\n" http://127.0.0.1:3081/
|
|
37
|
+
curl -s -o /dev/null -w "direct=%{http_code}\n" "http://127.0.0.1:3080/?token=$(echo "$URL" | sed 's/.*token=//')"
|
|
38
|
+
curl -sI http://127.0.0.1:3081/ | grep -i '^location' | head -1
|
|
39
|
+
echo "FIXED_URL=http://127.0.0.1:3081/"
|
|
Binary file
|
package/kit/termux.apk
ADDED