twskin 0.5.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 (65) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/CONTRIBUTING.md +37 -0
  3. package/LICENSE +21 -0
  4. package/README.md +104 -0
  5. package/SECURITY.md +28 -0
  6. package/dist/bin/twskin.d.ts +3 -0
  7. package/dist/bin/twskin.d.ts.map +1 -0
  8. package/dist/bin/twskin.js +4 -0
  9. package/dist/bin/twskin.js.map +1 -0
  10. package/dist/commands.d.ts +41 -0
  11. package/dist/commands.d.ts.map +1 -0
  12. package/dist/commands.js +421 -0
  13. package/dist/commands.js.map +1 -0
  14. package/dist/context.d.ts +14 -0
  15. package/dist/context.d.ts.map +1 -0
  16. package/dist/context.js +51 -0
  17. package/dist/context.js.map +1 -0
  18. package/dist/errors.d.ts +9 -0
  19. package/dist/errors.d.ts.map +1 -0
  20. package/dist/errors.js +20 -0
  21. package/dist/errors.js.map +1 -0
  22. package/dist/lock.d.ts +3 -0
  23. package/dist/lock.d.ts.map +1 -0
  24. package/dist/lock.js +52 -0
  25. package/dist/lock.js.map +1 -0
  26. package/dist/main.d.ts +9 -0
  27. package/dist/main.d.ts.map +1 -0
  28. package/dist/main.js +92 -0
  29. package/dist/main.js.map +1 -0
  30. package/dist/output.d.ts +4 -0
  31. package/dist/output.d.ts.map +1 -0
  32. package/dist/output.js +27 -0
  33. package/dist/output.js.map +1 -0
  34. package/dist/persistent-cdp.d.ts +14 -0
  35. package/dist/persistent-cdp.d.ts.map +1 -0
  36. package/dist/persistent-cdp.js +140 -0
  37. package/dist/persistent-cdp.js.map +1 -0
  38. package/dist/system.d.ts +64 -0
  39. package/dist/system.d.ts.map +1 -0
  40. package/dist/system.js +234 -0
  41. package/dist/system.js.map +1 -0
  42. package/dist/theme-download.d.ts +9 -0
  43. package/dist/theme-download.d.ts.map +1 -0
  44. package/dist/theme-download.js +250 -0
  45. package/dist/theme-download.js.map +1 -0
  46. package/dist/themes.d.ts +9 -0
  47. package/dist/themes.d.ts.map +1 -0
  48. package/dist/themes.js +185 -0
  49. package/dist/themes.js.map +1 -0
  50. package/dist/types.d.ts +58 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +2 -0
  53. package/dist/types.js.map +1 -0
  54. package/docs/publishing.md +45 -0
  55. package/docs/theme-distribution.md +62 -0
  56. package/package.json +74 -0
  57. package/runtime/component-map.mjs +200 -0
  58. package/runtime/injector.mjs +705 -0
  59. package/runtime/manifest.json +47 -0
  60. package/runtime/restore.sh +33 -0
  61. package/runtime/skin.js +1133 -0
  62. package/runtime/start.sh +86 -0
  63. package/runtime/styles/base.css +687 -0
  64. package/runtime/styles/manager.css +346 -0
  65. package/runtime/token-map.mjs +432 -0
@@ -0,0 +1,86 @@
1
+ #!/bin/bash
2
+ # TRAE Work Skin — 启动脚本
3
+ # 退出目标 App → 带 CDP 调试参数重启 → 启动注入守护进程
4
+ set -euo pipefail
5
+
6
+ SRC="${BASH_SOURCE[0]}"
7
+ while [ -L "$SRC" ]; do SRC="$(/usr/bin/readlink "$SRC")"; done
8
+ DIR="$(cd "$(dirname "$SRC")" && pwd -P)"
9
+ PORT="${PORT:-19527}"
10
+ APP_BUNDLE="${APP_BUNDLE:-/Applications/TRAE SOLO CN.app}"
11
+ APP_BUNDLE_ID="${APP_BUNDLE_ID:-cn.trae.solo.app}"
12
+ APP_PROC_MATCH="${APP_PROC_MATCH:-TRAE SOLO CN}"
13
+ NODE_BIN="${NODE_BIN:-node}"
14
+ TWSKIN_DATA_ROOT="${TWSKIN_DATA_DIR:-${HOME}/.trae-work-skin}"
15
+ RUN_DIR="${TWSKIN_STATE_DIR:-$TWSKIN_DATA_ROOT/run}"
16
+ THEMES_DIR="${TWSKIN_THEMES_DIR:-$TWSKIN_DATA_ROOT/themes}"
17
+
18
+ fail() { printf 'twskin: %s\n' "$*" >&2; exit 1; }
19
+
20
+ [ -d "$APP_BUNDLE" ] || fail "app not found: $APP_BUNDLE"
21
+ mkdir -p "$RUN_DIR"
22
+
23
+ EXE_NAME="$(/usr/bin/plutil -extract CFBundleExecutable raw -o - "$APP_BUNDLE/Contents/Info.plist")"
24
+ EXE_PATH="$APP_BUNDLE/Contents/MacOS/$EXE_NAME"
25
+ [ -x "$EXE_PATH" ] || fail "executable missing: $EXE_PATH"
26
+
27
+ # 1. 退出正在运行的实例(调试参数只在启动时生效)
28
+ if /usr/bin/pgrep -f "$EXE_PATH" >/dev/null 2>&1; then
29
+ printf 'Quitting %s ...\n' "$APP_BUNDLE"
30
+ /usr/bin/osascript -e "tell application id \"$APP_BUNDLE_ID\" to quit" >/dev/null 2>&1 || true
31
+ deadline=$((SECONDS + 20))
32
+ while /usr/bin/pgrep -f "$EXE_PATH" >/dev/null 2>&1 && [ "$SECONDS" -lt "$deadline" ]; do
33
+ /bin/sleep 0.5
34
+ done
35
+ /usr/bin/pgrep -f "$EXE_PATH" >/dev/null 2>&1 && fail "app did not quit in time"
36
+ fi
37
+
38
+ # 2. 带 CDP 参数启动(只绑回环地址)
39
+ printf 'Launching %s with CDP on 127.0.0.1:%s ...\n' "$APP_BUNDLE" "$PORT"
40
+ /usr/bin/open -na "$APP_BUNDLE" --args \
41
+ --remote-debugging-address=127.0.0.1 \
42
+ --remote-debugging-port="$PORT" || true
43
+
44
+ cdp_ready() {
45
+ /usr/bin/curl --noproxy '*' --silent --fail --max-time 1 \
46
+ "http://127.0.0.1:${PORT}/json/version" >/dev/null 2>&1
47
+ }
48
+
49
+ deadline=$((SECONDS + 45))
50
+ until cdp_ready || [ "$SECONDS" -ge "$deadline" ]; do /bin/sleep 0.5; done
51
+
52
+ # 兜底:open 传参失败时直接执行二进制
53
+ if ! cdp_ready; then
54
+ printf 'open(1) did not bring up CDP, falling back to direct exec ...\n'
55
+ /usr/bin/pgrep -f "$EXE_PATH" >/dev/null 2>&1 || true
56
+ /usr/bin/nohup "$EXE_PATH" \
57
+ --remote-debugging-address=127.0.0.1 \
58
+ --remote-debugging-port="$PORT" \
59
+ >>"$RUN_DIR/app.log" 2>&1 &
60
+ deadline=$((SECONDS + 45))
61
+ until cdp_ready || [ "$SECONDS" -ge "$deadline" ]; do /bin/sleep 0.5; done
62
+ fi
63
+ cdp_ready || fail "CDP endpoint never came up on port $PORT"
64
+
65
+ # 3. 确认端口确实属于目标 App 进程
66
+ port_pid="$(/usr/sbin/lsof -nP -iTCP:"$PORT" -sTCP:LISTEN -t 2>/dev/null | /usr/bin/head -n 1)"
67
+ [ -n "$port_pid" ] || fail "no listener on port $PORT"
68
+ port_cmd="$(/bin/ps -p "$port_pid" -o command= 2>/dev/null || true)"
69
+ case "$port_cmd" in
70
+ *"$APP_PROC_MATCH"*) ;;
71
+ *) fail "port $PORT is owned by an unexpected process: $port_cmd" ;;
72
+ esac
73
+
74
+ # 4. 启动注入守护进程(主题目录 ./themes,默认主题记于 run/theme.conf)
75
+ [ -f "$RUN_DIR/theme.conf" ] || echo "aurora" > "$RUN_DIR/theme.conf"
76
+ if [ -f "$RUN_DIR/injector.pid" ]; then
77
+ old_pid="$(/bin/cat "$RUN_DIR/injector.pid")"
78
+ [ -n "$old_pid" ] && /bin/kill "$old_pid" >/dev/null 2>&1 || true
79
+ fi
80
+ /usr/bin/nohup "$NODE_BIN" "$DIR/injector.mjs" --watch --port "$PORT" \
81
+ --themes "$THEMES_DIR" \
82
+ >>"$RUN_DIR/injector.log" 2>&1 &
83
+ echo "$!" > "$RUN_DIR/injector.pid"
84
+ echo "$PORT" > "$RUN_DIR/port"
85
+ printf 'Dream skin running: injector pid %s, CDP port %s\n' "$(/bin/cat "$RUN_DIR/injector.pid")" "$PORT"
86
+ printf 'Logs: %s\n' "$RUN_DIR/injector.log"