@marktrue/dsh-mobile-remote 3.2.1-rc.1-app → 3.2.1-rc.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.
Files changed (352) hide show
  1. package/CHANGELOG.md +835 -0
  2. package/CONTRIBUTING.md +59 -0
  3. package/FAQ.md +111 -0
  4. package/README.md +253 -6
  5. package/cordis.patch.yml +14 -0
  6. package/docs/00-/345/274/200/345/217/221/346/200/273/347/272/262.md +122 -0
  7. package/docs/01-PRD.md +148 -0
  8. package/docs/02-architecture.md +249 -0
  9. package/docs/03-api.md +816 -0
  10. package/docs/04-security.md +96 -0
  11. package/docs/05-test-cases.md +326 -0
  12. package/docs/06-install-run.md +308 -0
  13. package/docs/07-user-manual.md +65 -0
  14. package/docs/08-/346/211/251/345/261/225/345/274/200/345/217/221/346/214/207/345/215/227.md +86 -0
  15. package/docs/09-compatibility.md +195 -0
  16. package/docs/10-release.md +927 -0
  17. package/docs/screenshots/01-home.png +0 -0
  18. package/docs/screenshots/02-notifications.png +0 -0
  19. package/docs/screenshots/03-sessions.png +0 -0
  20. package/docs/screenshots/04-chat.png +0 -0
  21. package/docs/screenshots/05-settings.png +0 -0
  22. package/docs/screenshots/06-new-session.png +0 -0
  23. package/docs/screenshots/pgy-appstore.jpg +0 -0
  24. package/docs/screenshots/pgy-mobile-app.jpg +0 -0
  25. package/docs/screenshots/pgy-pc-client.jpg +0 -0
  26. package/lib/account-usage.js +145 -0
  27. package/lib/app-alignment.js +112 -0
  28. package/lib/app-carrier-store.js +1972 -0
  29. package/lib/app-carrier.js +609 -0
  30. package/lib/client.js +1174 -0
  31. package/lib/desktop-form.js +738 -0
  32. package/lib/endpoint-registry.js +165 -0
  33. package/lib/git-read-bundled-provider.js +255 -0
  34. package/lib/git-read-service.js +322 -0
  35. package/lib/index.js +9338 -0
  36. package/lib/npm-update-source.js +226 -0
  37. package/lib/plugin-content-digest.js +80 -0
  38. package/lib/plugin-self-update.js +997 -0
  39. package/lib/plugin-update-controller.js +274 -0
  40. package/lib/plugin-update-log.js +164 -0
  41. package/lib/plugin-update-transaction.js +322 -0
  42. package/lib/plugin-update.js +309 -0
  43. package/lib/runtime-dependency-snapshot.js +345 -0
  44. package/lib/session-title-cache.js +123 -0
  45. package/lib/session-title-refresh.js +261 -0
  46. package/lib/tool-process.js +20 -0
  47. package/lib/update-fetch.js +24 -0
  48. package/lib/update-lock-arbiter.js +170 -0
  49. package/lib/update-supervisor.js +346 -0
  50. package/node_modules/ansi-regex/index.d.ts +37 -0
  51. package/node_modules/ansi-regex/index.js +10 -0
  52. package/node_modules/ansi-regex/license +9 -0
  53. package/node_modules/ansi-regex/package.json +55 -0
  54. package/node_modules/ansi-regex/readme.md +78 -0
  55. package/node_modules/ansi-styles/index.d.ts +345 -0
  56. package/node_modules/ansi-styles/index.js +163 -0
  57. package/node_modules/ansi-styles/license +9 -0
  58. package/node_modules/ansi-styles/package.json +56 -0
  59. package/node_modules/ansi-styles/readme.md +152 -0
  60. package/node_modules/camelcase/index.d.ts +63 -0
  61. package/node_modules/camelcase/index.js +76 -0
  62. package/node_modules/camelcase/license +9 -0
  63. package/node_modules/camelcase/package.json +43 -0
  64. package/node_modules/camelcase/readme.md +99 -0
  65. package/node_modules/cliui/CHANGELOG.md +76 -0
  66. package/node_modules/cliui/LICENSE.txt +14 -0
  67. package/node_modules/cliui/README.md +115 -0
  68. package/node_modules/cliui/index.js +354 -0
  69. package/node_modules/cliui/package.json +65 -0
  70. package/node_modules/color-convert/CHANGELOG.md +54 -0
  71. package/node_modules/color-convert/LICENSE +21 -0
  72. package/node_modules/color-convert/README.md +68 -0
  73. package/node_modules/color-convert/conversions.js +839 -0
  74. package/node_modules/color-convert/index.js +81 -0
  75. package/node_modules/color-convert/package.json +48 -0
  76. package/node_modules/color-convert/route.js +97 -0
  77. package/node_modules/color-name/LICENSE +8 -0
  78. package/node_modules/color-name/README.md +11 -0
  79. package/node_modules/color-name/index.js +152 -0
  80. package/node_modules/color-name/package.json +28 -0
  81. package/node_modules/decamelize/index.js +13 -0
  82. package/node_modules/decamelize/license +21 -0
  83. package/node_modules/decamelize/package.json +38 -0
  84. package/node_modules/decamelize/readme.md +48 -0
  85. package/node_modules/dijkstrajs/.travis.yml +4 -0
  86. package/node_modules/dijkstrajs/CONTRIBUTING.md +8 -0
  87. package/node_modules/dijkstrajs/LICENSE.md +19 -0
  88. package/node_modules/dijkstrajs/README.md +18 -0
  89. package/node_modules/dijkstrajs/dijkstra.js +165 -0
  90. package/node_modules/dijkstrajs/package.json +60 -0
  91. package/node_modules/dijkstrajs/test/dijkstra.test.js +96 -0
  92. package/node_modules/emoji-regex/LICENSE-MIT.txt +20 -0
  93. package/node_modules/emoji-regex/README.md +73 -0
  94. package/node_modules/emoji-regex/es2015/index.js +6 -0
  95. package/node_modules/emoji-regex/es2015/text.js +6 -0
  96. package/node_modules/emoji-regex/index.d.ts +23 -0
  97. package/node_modules/emoji-regex/index.js +6 -0
  98. package/node_modules/emoji-regex/package.json +50 -0
  99. package/node_modules/emoji-regex/text.js +6 -0
  100. package/node_modules/find-up/index.d.ts +137 -0
  101. package/node_modules/find-up/index.js +89 -0
  102. package/node_modules/find-up/license +9 -0
  103. package/node_modules/find-up/package.json +53 -0
  104. package/node_modules/find-up/readme.md +156 -0
  105. package/node_modules/get-caller-file/LICENSE.md +6 -0
  106. package/node_modules/get-caller-file/README.md +41 -0
  107. package/node_modules/get-caller-file/index.d.ts +2 -0
  108. package/node_modules/get-caller-file/index.js +22 -0
  109. package/node_modules/get-caller-file/index.js.map +1 -0
  110. package/node_modules/get-caller-file/package.json +42 -0
  111. package/node_modules/is-fullwidth-code-point/index.d.ts +17 -0
  112. package/node_modules/is-fullwidth-code-point/index.js +50 -0
  113. package/node_modules/is-fullwidth-code-point/license +9 -0
  114. package/node_modules/is-fullwidth-code-point/package.json +42 -0
  115. package/node_modules/is-fullwidth-code-point/readme.md +39 -0
  116. package/node_modules/locate-path/index.d.ts +83 -0
  117. package/node_modules/locate-path/index.js +65 -0
  118. package/node_modules/locate-path/license +9 -0
  119. package/node_modules/locate-path/package.json +45 -0
  120. package/node_modules/locate-path/readme.md +122 -0
  121. package/node_modules/p-limit/index.d.ts +38 -0
  122. package/node_modules/p-limit/index.js +57 -0
  123. package/node_modules/p-limit/license +9 -0
  124. package/node_modules/p-limit/package.json +52 -0
  125. package/node_modules/p-limit/readme.md +101 -0
  126. package/node_modules/p-locate/index.d.ts +64 -0
  127. package/node_modules/p-locate/index.js +52 -0
  128. package/node_modules/p-locate/license +9 -0
  129. package/node_modules/p-locate/package.json +53 -0
  130. package/node_modules/p-locate/readme.md +90 -0
  131. package/node_modules/p-try/index.d.ts +39 -0
  132. package/node_modules/p-try/index.js +9 -0
  133. package/node_modules/p-try/license +9 -0
  134. package/node_modules/p-try/package.json +42 -0
  135. package/node_modules/p-try/readme.md +58 -0
  136. package/node_modules/path-exists/index.d.ts +28 -0
  137. package/node_modules/path-exists/index.js +23 -0
  138. package/node_modules/path-exists/license +9 -0
  139. package/node_modules/path-exists/package.json +39 -0
  140. package/node_modules/path-exists/readme.md +52 -0
  141. package/node_modules/pngjs/.eslintignore +2 -0
  142. package/node_modules/pngjs/.eslintrc.json +19 -0
  143. package/node_modules/pngjs/.prettierignore +3 -0
  144. package/node_modules/pngjs/LICENSE +20 -0
  145. package/node_modules/pngjs/README.md +429 -0
  146. package/node_modules/pngjs/browser.js +16096 -0
  147. package/node_modules/pngjs/coverage/lcov-report/base.css +354 -0
  148. package/node_modules/pngjs/coverage/lcov-report/bitmapper.js.html +881 -0
  149. package/node_modules/pngjs/coverage/lcov-report/bitpacker.js.html +554 -0
  150. package/node_modules/pngjs/coverage/lcov-report/block-navigation.js +77 -0
  151. package/node_modules/pngjs/coverage/lcov-report/chunkstream.js.html +647 -0
  152. package/node_modules/pngjs/coverage/lcov-report/constants.js.html +176 -0
  153. package/node_modules/pngjs/coverage/lcov-report/crc.js.html +200 -0
  154. package/node_modules/pngjs/coverage/lcov-report/favicon.png +0 -0
  155. package/node_modules/pngjs/coverage/lcov-report/filter-pack.js.html +593 -0
  156. package/node_modules/pngjs/coverage/lcov-report/filter-parse-async.js.html +152 -0
  157. package/node_modules/pngjs/coverage/lcov-report/filter-parse-sync.js.html +143 -0
  158. package/node_modules/pngjs/coverage/lcov-report/filter-parse.js.html +611 -0
  159. package/node_modules/pngjs/coverage/lcov-report/format-normaliser.js.html +359 -0
  160. package/node_modules/pngjs/coverage/lcov-report/index.html +426 -0
  161. package/node_modules/pngjs/coverage/lcov-report/interlace.js.html +365 -0
  162. package/node_modules/pngjs/coverage/lcov-report/packer-async.js.html +230 -0
  163. package/node_modules/pngjs/coverage/lcov-report/packer-sync.js.html +248 -0
  164. package/node_modules/pngjs/coverage/lcov-report/packer.js.html +467 -0
  165. package/node_modules/pngjs/coverage/lcov-report/paeth-predictor.js.html +128 -0
  166. package/node_modules/pngjs/coverage/lcov-report/parser-async.js.html +575 -0
  167. package/node_modules/pngjs/coverage/lcov-report/parser-sync.js.html +404 -0
  168. package/node_modules/pngjs/coverage/lcov-report/parser.js.html +950 -0
  169. package/node_modules/pngjs/coverage/lcov-report/png-sync.js.html +116 -0
  170. package/node_modules/pngjs/coverage/lcov-report/png.js.html +662 -0
  171. package/node_modules/pngjs/coverage/lcov-report/prettify.css +101 -0
  172. package/node_modules/pngjs/coverage/lcov-report/prettify.js +1007 -0
  173. package/node_modules/pngjs/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  174. package/node_modules/pngjs/coverage/lcov-report/sorter.js +169 -0
  175. package/node_modules/pngjs/coverage/lcov-report/sync-inflate.js.html +584 -0
  176. package/node_modules/pngjs/coverage/lcov-report/sync-reader.js.html +215 -0
  177. package/node_modules/pngjs/coverage/lcov.info +2177 -0
  178. package/node_modules/pngjs/lib/bitmapper.js +267 -0
  179. package/node_modules/pngjs/lib/bitpacker.js +158 -0
  180. package/node_modules/pngjs/lib/chunkstream.js +189 -0
  181. package/node_modules/pngjs/lib/constants.js +32 -0
  182. package/node_modules/pngjs/lib/crc.js +40 -0
  183. package/node_modules/pngjs/lib/filter-pack.js +171 -0
  184. package/node_modules/pngjs/lib/filter-parse-async.js +24 -0
  185. package/node_modules/pngjs/lib/filter-parse-sync.js +21 -0
  186. package/node_modules/pngjs/lib/filter-parse.js +177 -0
  187. package/node_modules/pngjs/lib/format-normaliser.js +93 -0
  188. package/node_modules/pngjs/lib/interlace.js +95 -0
  189. package/node_modules/pngjs/lib/packer-async.js +50 -0
  190. package/node_modules/pngjs/lib/packer-sync.js +56 -0
  191. package/node_modules/pngjs/lib/packer.js +129 -0
  192. package/node_modules/pngjs/lib/paeth-predictor.js +16 -0
  193. package/node_modules/pngjs/lib/parser-async.js +165 -0
  194. package/node_modules/pngjs/lib/parser-sync.js +108 -0
  195. package/node_modules/pngjs/lib/parser.js +290 -0
  196. package/node_modules/pngjs/lib/png-sync.js +12 -0
  197. package/node_modules/pngjs/lib/png.js +194 -0
  198. package/node_modules/pngjs/lib/sync-inflate.js +168 -0
  199. package/node_modules/pngjs/lib/sync-reader.js +45 -0
  200. package/node_modules/pngjs/package.json +73 -0
  201. package/node_modules/qrcode/README.md +770 -0
  202. package/node_modules/qrcode/bin/qrcode +159 -0
  203. package/node_modules/qrcode/helper/to-sjis-browser.js +2 -0
  204. package/node_modules/qrcode/helper/to-sjis.js +105 -0
  205. package/node_modules/qrcode/lib/browser.js +76 -0
  206. package/node_modules/qrcode/lib/can-promise.js +7 -0
  207. package/node_modules/qrcode/lib/core/alignment-pattern.js +83 -0
  208. package/node_modules/qrcode/lib/core/alphanumeric-data.js +59 -0
  209. package/node_modules/qrcode/lib/core/bit-buffer.js +37 -0
  210. package/node_modules/qrcode/lib/core/bit-matrix.js +65 -0
  211. package/node_modules/qrcode/lib/core/byte-data.js +30 -0
  212. package/node_modules/qrcode/lib/core/error-correction-code.js +135 -0
  213. package/node_modules/qrcode/lib/core/error-correction-level.js +50 -0
  214. package/node_modules/qrcode/lib/core/finder-pattern.js +22 -0
  215. package/node_modules/qrcode/lib/core/format-info.js +29 -0
  216. package/node_modules/qrcode/lib/core/galois-field.js +69 -0
  217. package/node_modules/qrcode/lib/core/kanji-data.js +54 -0
  218. package/node_modules/qrcode/lib/core/mask-pattern.js +234 -0
  219. package/node_modules/qrcode/lib/core/mode.js +167 -0
  220. package/node_modules/qrcode/lib/core/numeric-data.js +43 -0
  221. package/node_modules/qrcode/lib/core/polynomial.js +62 -0
  222. package/node_modules/qrcode/lib/core/qrcode.js +495 -0
  223. package/node_modules/qrcode/lib/core/reed-solomon-encoder.js +56 -0
  224. package/node_modules/qrcode/lib/core/regex.js +31 -0
  225. package/node_modules/qrcode/lib/core/segments.js +330 -0
  226. package/node_modules/qrcode/lib/core/utils.js +63 -0
  227. package/node_modules/qrcode/lib/core/version-check.js +9 -0
  228. package/node_modules/qrcode/lib/core/version.js +163 -0
  229. package/node_modules/qrcode/lib/index.js +12 -0
  230. package/node_modules/qrcode/lib/renderer/canvas.js +63 -0
  231. package/node_modules/qrcode/lib/renderer/png.js +78 -0
  232. package/node_modules/qrcode/lib/renderer/svg-tag.js +81 -0
  233. package/node_modules/qrcode/lib/renderer/svg.js +19 -0
  234. package/node_modules/qrcode/lib/renderer/terminal/terminal-small.js +85 -0
  235. package/node_modules/qrcode/lib/renderer/terminal/terminal.js +49 -0
  236. package/node_modules/qrcode/lib/renderer/terminal.js +9 -0
  237. package/node_modules/qrcode/lib/renderer/utf8.js +71 -0
  238. package/node_modules/qrcode/lib/renderer/utils.js +99 -0
  239. package/node_modules/qrcode/lib/server.js +138 -0
  240. package/node_modules/qrcode/license +10 -0
  241. package/node_modules/qrcode/package.json +77 -0
  242. package/node_modules/require-directory/.jshintrc +67 -0
  243. package/node_modules/require-directory/.npmignore +1 -0
  244. package/node_modules/require-directory/.travis.yml +3 -0
  245. package/node_modules/require-directory/LICENSE +22 -0
  246. package/node_modules/require-directory/README.markdown +184 -0
  247. package/node_modules/require-directory/index.js +86 -0
  248. package/node_modules/require-directory/package.json +40 -0
  249. package/node_modules/require-main-filename/CHANGELOG.md +26 -0
  250. package/node_modules/require-main-filename/LICENSE.txt +14 -0
  251. package/node_modules/require-main-filename/README.md +26 -0
  252. package/node_modules/require-main-filename/index.js +18 -0
  253. package/node_modules/require-main-filename/package.json +35 -0
  254. package/node_modules/set-blocking/CHANGELOG.md +26 -0
  255. package/node_modules/set-blocking/LICENSE.txt +14 -0
  256. package/node_modules/set-blocking/README.md +31 -0
  257. package/node_modules/set-blocking/index.js +7 -0
  258. package/node_modules/set-blocking/package.json +42 -0
  259. package/node_modules/string-width/index.d.ts +29 -0
  260. package/node_modules/string-width/index.js +47 -0
  261. package/node_modules/string-width/license +9 -0
  262. package/node_modules/string-width/package.json +56 -0
  263. package/node_modules/string-width/readme.md +50 -0
  264. package/node_modules/strip-ansi/index.d.ts +17 -0
  265. package/node_modules/strip-ansi/index.js +4 -0
  266. package/node_modules/strip-ansi/license +9 -0
  267. package/node_modules/strip-ansi/package.json +54 -0
  268. package/node_modules/strip-ansi/readme.md +46 -0
  269. package/node_modules/which-module/LICENSE +13 -0
  270. package/node_modules/which-module/README.md +58 -0
  271. package/node_modules/which-module/index.js +9 -0
  272. package/node_modules/which-module/package.json +41 -0
  273. package/node_modules/wrap-ansi/index.js +186 -0
  274. package/node_modules/wrap-ansi/license +9 -0
  275. package/node_modules/wrap-ansi/package.json +61 -0
  276. package/node_modules/wrap-ansi/readme.md +97 -0
  277. package/node_modules/y18n/CHANGELOG.md +35 -0
  278. package/node_modules/y18n/LICENSE +13 -0
  279. package/node_modules/y18n/README.md +109 -0
  280. package/node_modules/y18n/index.js +188 -0
  281. package/node_modules/y18n/package.json +39 -0
  282. package/node_modules/yargs/CHANGELOG.md +420 -0
  283. package/node_modules/yargs/LICENSE +21 -0
  284. package/node_modules/yargs/README.md +140 -0
  285. package/node_modules/yargs/build/lib/apply-extends.d.ts +2 -0
  286. package/node_modules/yargs/build/lib/apply-extends.js +65 -0
  287. package/node_modules/yargs/build/lib/argsert.d.ts +2 -0
  288. package/node_modules/yargs/build/lib/argsert.js +65 -0
  289. package/node_modules/yargs/build/lib/command.d.ts +64 -0
  290. package/node_modules/yargs/build/lib/command.js +416 -0
  291. package/node_modules/yargs/build/lib/common-types.d.ts +36 -0
  292. package/node_modules/yargs/build/lib/common-types.js +25 -0
  293. package/node_modules/yargs/build/lib/completion-templates.d.ts +2 -0
  294. package/node_modules/yargs/build/lib/completion-templates.js +50 -0
  295. package/node_modules/yargs/build/lib/completion.d.ts +21 -0
  296. package/node_modules/yargs/build/lib/completion.js +135 -0
  297. package/node_modules/yargs/build/lib/is-promise.d.ts +1 -0
  298. package/node_modules/yargs/build/lib/is-promise.js +9 -0
  299. package/node_modules/yargs/build/lib/levenshtein.d.ts +1 -0
  300. package/node_modules/yargs/build/lib/levenshtein.js +58 -0
  301. package/node_modules/yargs/build/lib/middleware.d.ts +10 -0
  302. package/node_modules/yargs/build/lib/middleware.js +57 -0
  303. package/node_modules/yargs/build/lib/obj-filter.d.ts +1 -0
  304. package/node_modules/yargs/build/lib/obj-filter.js +14 -0
  305. package/node_modules/yargs/build/lib/parse-command.d.ts +11 -0
  306. package/node_modules/yargs/build/lib/parse-command.js +36 -0
  307. package/node_modules/yargs/build/lib/process-argv.d.ts +2 -0
  308. package/node_modules/yargs/build/lib/process-argv.js +31 -0
  309. package/node_modules/yargs/build/lib/usage.d.ts +49 -0
  310. package/node_modules/yargs/build/lib/usage.js +540 -0
  311. package/node_modules/yargs/build/lib/validation.d.ts +34 -0
  312. package/node_modules/yargs/build/lib/validation.js +330 -0
  313. package/node_modules/yargs/build/lib/yargs.d.ts +274 -0
  314. package/node_modules/yargs/build/lib/yargs.js +1190 -0
  315. package/node_modules/yargs/build/lib/yerror.d.ts +4 -0
  316. package/node_modules/yargs/build/lib/yerror.js +11 -0
  317. package/node_modules/yargs/index.js +40 -0
  318. package/node_modules/yargs/locales/be.json +46 -0
  319. package/node_modules/yargs/locales/de.json +46 -0
  320. package/node_modules/yargs/locales/en.json +51 -0
  321. package/node_modules/yargs/locales/es.json +46 -0
  322. package/node_modules/yargs/locales/fi.json +49 -0
  323. package/node_modules/yargs/locales/fr.json +53 -0
  324. package/node_modules/yargs/locales/hi.json +49 -0
  325. package/node_modules/yargs/locales/hu.json +46 -0
  326. package/node_modules/yargs/locales/id.json +50 -0
  327. package/node_modules/yargs/locales/it.json +46 -0
  328. package/node_modules/yargs/locales/ja.json +51 -0
  329. package/node_modules/yargs/locales/ko.json +49 -0
  330. package/node_modules/yargs/locales/nb.json +44 -0
  331. package/node_modules/yargs/locales/nl.json +49 -0
  332. package/node_modules/yargs/locales/nn.json +44 -0
  333. package/node_modules/yargs/locales/pirate.json +13 -0
  334. package/node_modules/yargs/locales/pl.json +49 -0
  335. package/node_modules/yargs/locales/pt.json +45 -0
  336. package/node_modules/yargs/locales/pt_BR.json +48 -0
  337. package/node_modules/yargs/locales/ru.json +46 -0
  338. package/node_modules/yargs/locales/th.json +46 -0
  339. package/node_modules/yargs/locales/tr.json +48 -0
  340. package/node_modules/yargs/locales/zh_CN.json +48 -0
  341. package/node_modules/yargs/locales/zh_TW.json +47 -0
  342. package/node_modules/yargs/package.json +92 -0
  343. package/node_modules/yargs/yargs.js +14 -0
  344. package/node_modules/yargs-parser/CHANGELOG.md +601 -0
  345. package/node_modules/yargs-parser/LICENSE.txt +14 -0
  346. package/node_modules/yargs-parser/README.md +449 -0
  347. package/node_modules/yargs-parser/index.js +1032 -0
  348. package/node_modules/yargs-parser/lib/tokenize-arg-string.js +40 -0
  349. package/node_modules/yargs-parser/package.json +46 -0
  350. package/package.json +65 -12
  351. package/DSH-Remote-v3.2.1.apk +0 -4
  352. package/manifest.json +0 -21
@@ -0,0 +1,308 @@
1
+ # 06 部署与启用文档 — dsh-mobile-remote
2
+
3
+ > 版本:v3.0.0 · 状态:已在本机安装与验证 · 配套:03-api.md、04-security.md、07-user-manual.md、09-compatibility.md
4
+ > 适用环境:**DSH 0.1.1-rc.2(DSH Desktop v2.0.2)**。桌面版 webserver 强制只听 `127.0.0.1`,移动端经插件 **LAN 桥**(默认 `0.0.0.0:3080`)接入;web 版 DSH 无回环限制,可直接让 webserver 绑 0.0.0.0。
5
+
6
+ ## 1. 部署拓扑
7
+
8
+ ```mermaid
9
+ graph LR
10
+ PH[手机(DSH Remote App)] -->|同一 WiFi:桥 3080| BR[插件 LAN 桥 0.0.0.0:3080]
11
+ PH -.外出(蒲公英虚拟组网).-> PG[蒲公英虚拟网卡] -.-> BR
12
+ BR --> WS[DSH 回环 webserver /m/api]
13
+ WS --> DSH[dsh services: agents / sessions]
14
+ ```
15
+
16
+ - 手机端:安装 DSH Remote App(构建方法见 §8),连接电脑地址(如 `http://192.168.1.100:3080/m` 或 `https://<蒲公英虚拟IP>:3080/m`——**端口 3080 是插件桥端口**,见 §4b)。
17
+ - 桌面端入口:DSH Desktop 设置页「连接移动端设备」(插件客户端模块)显示二维码与连接信息(二维码在桥监听成功时自动使用桥地址)。
18
+ - 外出访问:**蒲公英组网**(推荐,见 §5.1);其他虚拟组网/隧道类见 §5.2。
19
+
20
+ ### 1.1 两种运行形态速查(先看你是哪种)
21
+
22
+ | 形态 | webserver host | 手机连接方式 | 插件额外配置 |
23
+ |---|---|---|---|
24
+ | **web 版**(`dsh --profile web`)| 默认 `0.0.0.0:3080` | **开箱直连** `http://<IP>:3080/m`(老姿势)| 无需 lanBridge、无需覆盖 webserver 行;放行防火墙即可 |
25
+ | **桌面版**(DSH Desktop)| 强制 `127.0.0.1`(不可覆盖)| 启用 **LAN 桥** `0.0.0.0:3080` 后连 `http://<IP>:3080/m` | 见 §4b(桥 + 强口令门禁)|
26
+
27
+ > web 版说明:0.1.1-rc.2 的 dsh-web-app 默认 webserver `host: 0.0.0.0, port: 3080`(实测 `--dump-config`);**不需要**写 `- id: webserver` 覆盖行;更老版本(默认 127.0.0.1 时代)才需覆盖且**必须写全 `host`+`port`**(§4 警示)。
28
+ > **实测记录(2026-08-23)**:在隔离 DSH_HOME 以 web profile 启动(`host: 0.0.0.0, port: 3081`)→ 局域网 IP `http://192.168.10.8:3081/m/api/bootstrap` 直连 **HTTP 200**(plugin v3.0.0,`server.urls[0]` 即局域网地址,auth 生效)——web 形态局域网直连实锤;与桌面版(LAN 桥)并存两条路径,均为真机验证。
29
+
30
+ ## 2. 安装位置说明(以桌面版为主)
31
+
32
+ | 项目 | 位置 |
33
+ |---|---|
34
+ | 插件源码 | `<本仓库>/`(package.json / lib / docs / tools) |
35
+ | 已安装副本 | `~/.dsh/profiles/desktop/node_modules/dsh-mobile-remote/`(web 版为 `profiles/web/...`) |
36
+ | profile 依赖声明 | `~/.dsh/profiles/<profile>/package.json` → `"dsh-mobile-remote": "file:<本仓库路径>"` |
37
+ | 启用配置 | `~/.dsh/profiles/<profile>/cordis.patch.yml`(insert mobile-remote 行;**无需覆盖 webserver 行**,见 §4 警示) |
38
+ | 访问口令 | 部署时生成(`crypto.randomBytes(24).toString('base64url')`),写入 `authToken` |
39
+
40
+ ### 2.1 依赖声明的两种方式
41
+
42
+ **方式 A(推荐,已实测)—— 本地 clone + `file:` 依赖**:
43
+
44
+ ```powershell
45
+ git clone https://github.com/201222-L/dsh-mobile-remote.git
46
+ # 锁版本(推荐):tag 与版本号一致;不 checkout 则跟随最新 main
47
+ git -C dsh-mobile-remote checkout v3.0.0
48
+ # profile package.json:
49
+ # "dsh-mobile-remote": "file:<clone 出来的路径>"
50
+ corepack pnpm install
51
+ ```
52
+
53
+ **方式 B(快捷,免手动 clone)—— 直接写 GitHub 地址,`pnpm install` 自动下载**:
54
+
55
+ ```json
56
+ { "dependencies": { "dsh-mobile-remote": "github:201222-L/dsh-mobile-remote" } }
57
+ ```
58
+
59
+ **锁定指定版本**(推荐:App 与插件版本保持一致)—— 用 git tag 固定:
60
+
61
+ ```json
62
+ { "dependencies": { "dsh-mobile-remote": "github:201222-L/dsh-mobile-remote#v3.0.0" } }
63
+ ```
64
+
65
+ **方式 C —— 下载 Release 里的插件包离线安装**:GitHub Releases 的 `dsh-mobile-remote-vX.Y.Z.tgz` 下载后:
66
+
67
+ ```powershell
68
+ # profile package.json:
69
+ # "dsh-mobile-remote": "file:<下载解压后的包路径>"
70
+ corepack pnpm install
71
+ ```
72
+
73
+ > 版本匹配规则:**App 与插件同版本 = 完美配对**;不同版本也能用(谁旧谁吃亏,但都不崩),详见 README「版本与兼容」。实际配对在 App 设置 → 关于 → 版本查看。
74
+ > 方式 B 依赖网络能访问 GitHub 与 npm(含插件依赖 `qrcode`、`@deepseek-ai/*` 的公开解析;后者桌面端为内置打包、公开 npm 可解析性未逐一验证,遇解析失败请改用方式 A/C)。
75
+ > 更新插件时:方式 A 重新 `git pull` 后 `pnpm install`;方式 B 改 tag 后 `pnpm install`;方式 C 换新 tgz 重装。
76
+
77
+ ## 3. 启用 / 重启步骤
78
+
79
+ **桌面版(DSH Desktop)**:
80
+ 1. 修改插件源码后,同步已安装副本(`file:` 依赖不会自动重装):`cd ~/.dsh/profiles/desktop && corepack pnpm install`(或直接 `git pull` 后在 profile 目录 `pnpm install`)。
81
+ 2. (可选)校验组合配置(不启动):`npx @deepseek-ai/dsh --profile desktop --dump-config`,确认输出包含 `mobile-remote` 行。
82
+ 3. **重启 DSH Desktop**(插件随进程加载)。日志出现 `mobile-remote: lanBridge 已监听 0.0.0.0:3080 → 127.0.0.1:<port>/m/api` 即桥已工作。
83
+
84
+ **web 版(`dsh --profile web`)**:步骤 1 同上(profile 换 `web`),步骤 3 为重启 `dsh web` 进程;**web 版 webserver 默认即 `0.0.0.0:3080`**(局域网直连开箱即用;无需覆盖 webserver 行,见 §4 警示)。注:web 版直连 webserver 时插件路由在同一个 webserver 上;桌面版见 §4b LAN 桥。
85
+
86
+ ## 4. 变更配置(口令/路径/充值地址)
87
+
88
+ 编辑 `cordis.patch.yml` 改 `mobile-remote` 行的 `config`,然后重启:
89
+
90
+ ```yaml
91
+ - insert:
92
+ - id: mobile-remote
93
+ name: dsh-mobile-remote
94
+ config:
95
+ path: /m
96
+ authToken: <新口令,留空=关闭认证>
97
+ rechargeUrl: https://platform.deepseek.com/top_up
98
+ ```
99
+
100
+ 口令生成建议:`node -e "console.log(require('crypto').randomBytes(24).toString('base64url'))"`
101
+
102
+ > ⚠️ **webserver 行覆盖的坑(重要,来自实测 issue)**:cordis patch 对**已有行**是**整体替换 config 对象(非合并)**——若你写 `- id: webserver` + `config: {host: 0.0.0.0}`,DSH 自带行的其余字段(如 `port: !!js ctx.webStartup.port ?? 3080`)会被**顶掉**,而 `port` 是必填 → 启动校验即报 `$port missing required value`(`--dump-config` 与 smoke 测试都不会暴露,只有真启动才报)。
103
+ > **因此**:① **web 版完全不需要覆盖 webserver 行**(默认已是 `host: 0.0.0.0, port: 3080`);② 若出于自定义(如改端口)确要覆盖,**必须写全全部必填字段**(`host` + `port`);③ **桌面版(0.1.1-rc.2)webserver 的 `host` 不可改为 0.0.0.0**(DesktopWebServer 构造器对非回环 host 直接 throw,用户 patch 无法覆盖)——移动端访问请用 **§4b 的 lanBridge**,不要覆盖 webserver 行。
104
+
105
+ ## 4b. 局域网直连(同一 WiFi,v3.0.0 新增:桌面版终于可以连了)
106
+
107
+ > **背景**:DSH Desktop(0.1.1-rc.2 起)强制 web 服务只听 `127.0.0.1`(内核硬限制,改不了),手机无法直连;**web 版默认即监听 `0.0.0.0:3080`**(局域网直连开箱即用,无需覆盖任何行)。v3.0.0 起插件内置 **LAN 桥**:桌面版在 DSH 进程内自建监听,把 `/m` 请求转发给回环服务——手机走局域网 IP 即可连,**无需穿透、无需额外工具、不改 DSH**。
108
+
109
+ 1. **开桥**:`cordis.patch.yml` 的 `mobile-remote` 行 `config` 加:
110
+ ```yaml
111
+ lanBridge:
112
+ enabled: true
113
+ port: 3080 # 与其它服务冲突可改;改后手机地址的端口同步改
114
+ host: 0.0.0.0 # 默认全接口;单机调试可用 127.0.0.1
115
+ ```
116
+ 2. **重启** DSH,首次监听 `0.0.0.0` 时 Windows 防火墙弹窗点「允许」;或手动放行:
117
+ `netsh advfirewall firewall add rule name="DSH Mobile LAN" dir=in action=allow protocol=TCP localport=3080`
118
+ 3. **手机连**:设置 → 重新配置连接 → 扫码(桌面设置页二维码已自动变为桥地址)或手动填 `http://<电脑局域网IP>:3080/m` + 口令。
119
+ 4. **安全**:`authToken` **必须** 配置强口令(桥拒绝无口令启动);桥只转发 `/m/*`,桌面 `/api` 网关与 `qr-config`/`qr.png` 不转发,不扩大攻击面。
120
+ 5. **排查**:`GET /m/api/diagnostics` → `runtime.lanBridge.listening` 应为 `true`;插件日志会打印监听地址;连不上先查防火墙与 IP(`ipconfig`,VMware 虚拟网卡地址手机不可达)。
121
+ 6. **升级自检**:App 断线会自动轮换地址(局域网 IP 优先),出门场景仍走第 5 节组网方案,两者不冲突。
122
+
123
+ ## 5. 外出访问(人不在家)
124
+
125
+ > 共同前提:家里电脑保持开机、dsh 运行。**推荐方案:蒲公英组网**(已真机实测通过,国内可用、免费版够用)。原理是"虚拟局域网"——电脑和手机加入同一个虚拟网,手机无论在家 WiFi 还是户外流量都能直达电脑。**禁止把 3080 端口直接映射/穿透到公网裸奔**。
126
+
127
+ ### 5.1 推荐方案:蒲公英组网(已实测 ✅)
128
+
129
+ 1. **电脑**:从[蒲公英官网下载 PC 客户端](https://pgy.oray.com/download/)安装,登录账号,创建/加入一个**智能组网**(免费版支持 3 个成员)。加入后电脑会获得一个虚拟 IP(客户端界面可见,形如 `172.16.x.x`)。
130
+ 2. **手机**:在手机**应用商店搜索「蒲公英」**安装 App,登录**同一账号**,加入**同一组网**,确认手机与电脑都显示「在线」。
131
+ 3. **DSH Remote App 首连(关键一步)**:设置 → 重新配置连接 → 手动输入 `http://<电脑虚拟IP>:3080` + 口令。连接成功后,App 会自动把电脑的**局域网 IP 和蒲公英虚拟 IP 都记住**(设置 → 电脑地址显示「共 N 个地址自动切换」)。
132
+ 4. **验证**:手机关 WiFi 开流量 → 状态点变绿 → 发一条消息收到回复即成功。
133
+ 5. 之后完全自动:出门自动走蒲公英、回家自动走局域网,无需再手动改任何配置。
134
+ 6. **账号提示**:以上流程对蒲公英账号可用者完全适用;若账号不可用(登录受限/过期等),属账号个体情况,可改用 §5.2 的其他组网方案,插件侧无需改动。
135
+
136
+ | 蒲公英 App(移动端) | 蒲公英 PC 客户端 | 应用商店搜索 |
137
+ |---|---|---|
138
+ | ![蒲公英移动端](screenshots/pgy-mobile-app.jpg) | ![蒲公英PC客户端](screenshots/pgy-pc-client.jpg) | ![应用商店搜索](screenshots/pgy-appstore.jpg) |
139
+
140
+ > ⚠ **手机必须给蒲公英「免死金牌」**(国产 ROM 杀后台是外出断连的头号原因):设置 → 应用管理 → 蒲公英 → **省电策略「无限制」+ 自启动「允许」**;并在最近任务卡片上**锁定**蒲公英(出现锁图标)。否则手机一省电就把 VPN 杀掉,隧道断了 App 再自动切换也没路可走(表现就是"出门连不上、等一会又好了")。
141
+
142
+ ### 5.2 其他方案(思路参考,按自己环境自行适配)
143
+
144
+ 任何"虚拟组网/内网穿透"方案都能接,原理完全一致——电脑上会多出一个虚拟网卡(或中继通道),插件会自动把它收进地址列表(`/api/bootstrap` 的 `server.urls`,按「局域网私有地址优先」排序);App 断线时自动轮换候选地址。已适配的要点:
145
+
146
+ - **虚拟组网类**(Tailscale / ZeroTier / EasyTier / 路由器 WireGuard / 蒲公英):电脑加入组网后其虚拟 IP 自动进入地址列表,无需改插件配置;手机首连手动填一次虚拟 IP 即可(**Tailscale 国内控制面不可达,不推荐**;ZeroTier/EasyTier 亦为备选,注意其公共节点是否在服务期——云侧可用性以官方为准)。
147
+ - **隧道/中继类**(frp 自建 / SakuraFrp 托管等):手机经公网中继访问时,请求的 Host 头是中继地址,需在插件配置显式放行 + 强口令:
148
+
149
+ ```yaml
150
+ - insert:
151
+ - id: mobile-remote
152
+ name: dsh-mobile-remote
153
+ config:
154
+ path: /m
155
+ authToken: <16位以上随机口令> # 公网段的唯一防线,必须强随机
156
+ trustedHosts: ["<中继域名或IP>"] # 如 frp-boy.com / xxx.natfrp.com
157
+ ```
158
+
159
+ > 隧道类注意:域名接入国内托管/反代通常要求 **ICP 备案**(自有域名绑定公网服务必然遇到);未备案时请选择**免备案节点地址/自带域名**,并务必保证 **TLS**(公网明文 HTTP = 口令暴露,违反 04-security 禁止项);若隧道方案拿不到 TLS/免备案入口,请转向 §5.1 的虚拟组网。
160
+ - 全部方案通用:`authToken` 保持开启、别把 3080 裸奔暴露公网;换隧道/换节点后更新手机地址与 `trustedHosts` 即可。
161
+
162
+ ## 6. 推送桥配置(可选,部署者 3 分钟)
163
+ > agent 完成 / 需要你回答 / 失败 → 手机系统通知。**不配置则无推送**,其他功能不受影响。
164
+ > 电脑只需能正常上网(HTTPS 出站),无需公网端口。
165
+ 在 `cordis.patch.yml` 的 `mobile-remote` 行 `config` 下加 `pushUrls`(可配多个通道,事件同时推送到全部):
166
+
167
+ ### 企业微信群机器人(微信推送,推荐:国内稳定、免登录态、几乎无配额限制)
168
+ > 建一个企业微信群(同事/家人/自己一人群均可)→ 群设置 → 添加群机器人 → 复制 **Webhook URL**(形如 `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=…`)。约 20 条/分钟限额,足够日常提醒。
169
+ ```yaml
170
+ pushUrls:
171
+ - name: 企业微信
172
+ url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=<你的key>
173
+ format: wecom
174
+ ```
175
+
176
+ ### Server酱(微信服务号推送,安卓/全平台通用)
177
+ ```yaml
178
+ - insert:
179
+ - id: mobile-remote
180
+ name: dsh-mobile-remote
181
+ config:
182
+ path: /m
183
+ authToken: <口令>
184
+ pushUrls:
185
+ - name: 微信
186
+ # Server酱³(推荐):SendKey 页面可复制 API URL,形如
187
+ # https://<uid>.push.ft07.com/send/<sendkey>.send (key 以 sctp…t 开头)
188
+ url: https://<uid>.push.ft07.com/send/<sendkey>.send
189
+ format: serverchan
190
+ ```
191
+
192
+ Server酱³ SendKey 获取:手机微信扫码打开 `https://sc3.ft07.com/sendkey` → 复制 **API URL**(推荐,`push.ft07.com` 官方入口)。老 Turbo 接口 `sctapi.ftqq.com` 域名偶发不可用(实测 400/连接失败,2026-08),建议用 ³ 官方 URL;`format: serverchan` 两者通用(form: title/desp)。**免费版每天 5 条上限**(AUTH 40001),需更多条数请升级。
193
+ ### ntfy(安卓系统通知栏,开源自托管友好)
194
+ ```yaml
195
+ pushUrls:
196
+ - name: ntfy
197
+ url: https://ntfy.sh/<你的随机topic>
198
+ format: ntfy
199
+ ```
200
+
201
+ 手机装 ntfy App 订阅同一 topic。注意公共服务器 topic 可被猜测,建议用长随机串。⚠️ **`ntfy.sh` 公共服务器在境内通常无法直连**(实测连接超时)——局域网自托管 ntfy 才推荐用这条,否则建议用上面的企业微信机器人或 Server酱。
202
+ ### Bark(iPhone)
203
+ ```yaml
204
+ pushUrls:
205
+ - name: Bark
206
+ url: https://api.day.app/<你的key>
207
+ format: bark
208
+ ```
209
+
210
+ ### 通用 webhook
211
+
212
+ ```yaml
213
+ pushUrls:
214
+ - name: 自建
215
+ url: https://your-server.example.com/hook
216
+ format: generic
217
+ ```
218
+
219
+ **验证两种方式**:
220
+ 1. **推荐:App 设置 → 通知 → 「发送测试通知」**— 配置后重启桌面端,手机点一下即可逐通道验证(绕过节流,结果数即"几个通道成功");
221
+ 2. 或让 agent 跑一个任务(完成/失败/提问任一发)看是否收到。
222
+ 同会话同类型 60 秒内合并(`pushCooldownMs` 可调)。
223
+ > **隐私**:推送默认只含「事件类型 + 会话短码」(`pushContent: minimal`),会话标题/错误详情等核心内容不经过第三方通道;确需完整内容(信任通道时)在 config 加 `pushContent: standard`。
224
+
225
+ ## 6b. HTTPS 反代(可选)
226
+
227
+ > 适用:不信任的 WiFi(酒店/咖啡馆)、或经公网反代访问。原理:用反向代理(Caddy/nginx)在 3080 前加 TLS。
228
+ > **证书**:App 按标准 TLS 校验,**不支持放行自签证书**。请使用受信任 CA(需公网域名,Let's Encrypt),或自建内网 CA 并把**根证书安装进手机**(设置 → 安全 → 安装证书)。
229
+ > **提示**:如需公网域名,国内域名接入须 **ICP 备案**(见 §5.2 提示);内网自用可直接用内网 CA(mkcert)。
230
+
231
+ **Caddy 示例(mkcert 内网 CA)**:
232
+
233
+ ```powershell
234
+ # ① 生成内网 CA 并签发证书(安装 mkcert 后)
235
+ mkcert -install # 把 CA 根证书装进系统
236
+ mkcert 192.168.1.100 172.16.x.x # 给电脑的局域网/组网 IP 签证书
237
+ # ② Caddyfile:
238
+ # :3443 {
239
+ # tls <生成的 cert.pem> <生成的 key.pem>
240
+ # reverse_proxy 127.0.0.1:3080
241
+ # }
242
+ # ③ 把 mkcert 的 CA 根证书传到手机安装(Android:设置 → 安全 → 加密与凭据 → 安装证书)
243
+ # ④ 启动 caddy,App 手动连接 https://<电脑IP>:3443 + 口令
244
+ ```
245
+
246
+ **注意**:
247
+ - 反代只负责传输加密;`authToken` 仍必须启用(v2.6 起未启用会在启动日志与设置页显式警示)。
248
+ - 地址自动收集/二维码按 http 生成;HTTPS 场景请手动填地址。
249
+ - 纯局域网 + 蒲公英(WireGuard 加密)场景无需 TLS。
250
+
251
+ ## 7. 回滚方案
252
+
253
+ 1. 从 `cordis.patch.yml` 删除 `mobile-remote` 行(如有 `webserver` 覆盖行一并删除——若确需写该覆盖,务必按 §4 警示补全必填字段)。
254
+ 2. 从 `package.json` 删除 `dsh-mobile-remote` 依赖并 `corepack pnpm install`。
255
+ 3. 重启 DSH(Desktop 或 web)。插件路由、SSE 连接随 fiber dispose 全部释放,桌面 GUI 不受影响。
256
+
257
+ ## 8. Flutter App(dsh-mobile-app,安卓)
258
+
259
+ > 源码:`dsh-mobile-app/` 子目录(独立 Flutter 工程,与插件同仓库发布)。
260
+ ### 8.0 安装 App(推荐:直接下载 APK)
261
+
262
+ **无需编译环境**:从 [GitHub Releases](https://github.com/201222-L/dsh-mobile-remote/releases/latest) 下载 `DSH-Remote-*.apk`(正式签名)传到手机安装即可。愿意自己改代码/构建的开发者见 §8.2。
263
+ ### 8.1 架构
264
+
265
+ App = **原生 Flutter 应用**(非 WebView):全部界面用 Flutter 原生组件绘制,与插件 `/m/api` 共享同一套 API 与设计令牌(DeepSeek 配色)。
266
+ - 连接:扫码连接(扫桌面 DSH 设置页「连接移动端设备」二维码)或手动输地址+口令。
267
+ - 页面:首页(欢迎 + 最近会话)、对话(流式回复、Markdown、token 用量、工具活动条、图片渲染与全屏)、会话列表、通知中心、设置(余额/默认预设/深色模式/环境诊断)、新建会话(模式 + 工作目录跨盘浏览)。
268
+ - 数据:全部实时读写 PC 端 DSH,无本地状态。
269
+ ### 8.2 构建 APK
270
+
271
+ 前置:Flutter SDK(本项目用 3.47.0) + Android SDK。
272
+
273
+ **构建、Release 签名、代理、Gradle/缓存排障与产物校验的完整步骤,统一见发布操作手册 [`docs/10-release.md`](10-release.md) §4(构建)与[附录 A(Android 构建与排障)](10-release.md#附录-aandroid-apk-构建与排障)。** 日常开发的最短路径:
274
+
275
+ ```powershell
276
+ cd dsh-mobile-app
277
+ flutter analyze # 应为 No issues found
278
+ flutter build apk --release
279
+ # 产物:build\app\outputs\flutter-apk\app-release.apk
280
+ ```
281
+
282
+ > 正式发布必须走 `docs/10-release.md`(含版本 bump、载体打包、预检、演练与发布顺序);本文件不再重复签名/排障细节,避免两处维护。
283
+ > 更换图标:把 1024×1024 PNG 覆盖到 `assets/icon-1024.png`,运行 `python tools/make_icon.py` 后重新构建。
284
+ > 多品牌/兼容性注意事项见 docs/09-compatibility.md。
285
+ ### 8.3 安装与使用
286
+ 1. 把 APK 传到手机(微信文件传输/网盘/USB),点击安装(需允许"安装未知来源应用")。
287
+ 2. 打开 App →「扫码连接」对准电脑屏幕上的二维码(桌面 DSH 设置 →「连接移动端设备」页);或手动输入电脑地址 + 访问口令。
288
+ 3. 连接成功进入首页,直接发消息派活。
289
+ > 说明:Android 9+ 默认禁止明文 HTTP,App 已配置 `usesCleartextTraffic`,仅限局域网/内网使用,勿暴露公网。
290
+ > 换签名安装会报「签名不一致」:先卸载旧版再装新版(连接信息需重新扫码)。
291
+ ### 8.4 重建与更新
292
+ - 插件/网页端改动 → 按 §3 同步并重启 DSH。
293
+ - App 改动 → 重新 `flutter build apk --release` 并重装(同签名覆盖安装,保留连接信息)。
294
+
295
+ ## 9. 验收清单(已执行 ✅)
296
+
297
+ - [x] `--dump-config` 含 mobile-remote 行;启动日志含 lanBridge 监听行(桌面版)
298
+ - [x] **web 版局域网直连实测**(2026-08-23,隔离 DSH_HOME):`0.0.0.0:3081` + 局域网 IP bootstrap 200
299
+ - [x] 未认证 401 / 错误口令 401 / 正确口令通行
300
+ - [x] `POST /m/api/send` 注入成功(200 + messageId;图片路径 200 + accepted:true)
301
+ - [x] SSE 连接 + hello + 事件转发(重连退避、断线补拉、pendingFrames 回放、心跳 25s)
302
+ - [x] `/m/qr.png` 返回 PNG
303
+ - [x] 桌面设置页「连接移动端设备」二维码 + App 扫码自动连接
304
+ - [x] Flutter App:analyze 零问题 + 正式签名 release 构建 + 真机全流程测试
305
+ - [x] 问询弹窗端到端(手机选选项→agent 收到答案 / ✕→取消 / PC 端先答两端同步)
306
+ - [x] 权限审批弹窗端到端(允许一次→操作继续 / 拒绝→操作被拒)
307
+ - [x] 通知删除(单删/批量/清空)+ 诊断页服务探针(respondBridge/frameBridge ✅)
308
+ - [x] 图像链路实机:发送/渲染/全屏/限额/类型纠正(v3.0.0 全套,见 CHANGELOG)
@@ -0,0 +1,65 @@
1
+ # 07 用户操作手册 — DSH Remote
2
+
3
+ > 版本:v2.7.0 · 配套:06-install-run.md · 面向使用手机 App 的最终用户
4
+ ## 1. 快速开始
5
+ 1. 确认电脑端 dsh(DeepSeek Harness)正在运行。
6
+ 2. 手机与电脑连接**同一 WiFi**;**人不在家**时用蒲公英组网(电脑+手机装蒲公英客户端、同一组网,见 06-install-run.md §5)。
7
+ 3. 打开 DSH Remote App:
8
+ - **扫码连接**:对准电脑屏幕上 dsh 设置页「连接移动端设备」的二维码,自动填入地址+口令。
9
+ - **手动输入**:地址 `http://<电脑局域网IP>:3080`(外出首次手动填电脑的蒲公英虚拟 IP) 访问口令(部署者配置的 `authToken`)。
10
+ 4. 连接成功进入首页,直接发消息派活。
11
+ ## 2. 界面说明
12
+
13
+ | 区域 | 功能 |
14
+ |---|---|
15
+ | 首页 | 欢迎语 + 最近会话 + 底部输入框(模型/权限胶囊);右上角铃铛进通知 |
16
+ | 对话页 | 消息流:你的消息(右)、Harness 回复(左,Markdown 渲染)、token 用量、轮次分隔线;底部输入框发送,状态点显示执行中/等待回答 |
17
+ | 会话列表 | 全部会话(标题/时间/工作目录),点按进入;下拉刷新 |
18
+ | 通知中心 | 完成✅ 失败❌ 需回答⚠ 三色通知,未读角标,点击跳转会话,全部已读 |
19
+ | 设置 | 连接信息(电脑地址可点按切换)、默认 Agent/权限预设、余额、深色模式、环境诊断、重新配置连接 |
20
+
21
+ ## 3. 常用操作
22
+
23
+ **发消息/派任务**:首页或对话页底部输入 → 发送。消息注入电脑端正在运行的 agent,立即开始执行;手机实时看到流式回复。
24
+ **切换会话**:抽屉 → 会话 → 点按进入。标题与 PC 端实时同步。
25
+ **切换工作区**:抽屉 → 工作区(或会话页顶部筛选条)→ 选择目标工作区。会话列表与首页"最近会话"只显示该工作区下的会话;新建会话默认在该工作区目录下创建。
26
+ **看更早的消息**:对话页向上滑动——滑到顶部会自动加载更早一页,继续上滑继续加载(微信式,无断页);已到会话开头会有提示。往上翻后右下角(输入框正上方)会出现灰白色「回到底部」圆钮,点按直接回到最新消息。
27
+ **收通知**:agent 完成任务/需要你回答/失败时,App 通知页出现通知;配合推送桥(企业微信机器人 / Server酱 / ntfy / Bark,配置见 docs/06 §6)可收**手机系统弹窗**——不依赖 App 常驻后台。推送默认只含事件类型与会话短码,会话内容不经过第三方通道。
28
+ **删除通知**:通知页**长按**某条可单独删除;右上角垃圾桶 → 批量多选删除或清空全部。仅删除手机 App 里的记录,不影响电脑端。
29
+ **审批/回答**:agent 思考途中需要你拍板时,对话页弹出卡片——按选项选择(可多选),或输入你自己的答案后「提交」;工具需要更高权限时弹出「权限请求」,选「允许一次 / 拒绝」。与电脑端同一个待办,任一端回答后两端同时消失;也可点卡片右上角 ✕ 取消(agent 按取消继续)。agent 只是等待你普通回复时(状态点橙色),直接输入消息即可。
30
+ **新建会话**:首页「+ 新建会话」→ 选模式(标准/PTC/极简/创造)→ 可选工作目录(跨盘浏览、可新建文件夹)→ 创建。
31
+ **修改默认配置**:设置 → 默认 Agent 预设 / 默认权限预设 → 选择(作用于之后新建的会话,与 PC 端同一写入通道)。
32
+ **深色模式**:设置 → 深色模式:跟随系统 / 深色 / 浅色。
33
+ **外出使用**:电脑和手机都装蒲公英客户端登录同一账号、加入同一组网(电脑保持开机)。首次在 App 里手动填一次电脑的蒲公英虚拟 IP(`http://172.16.x.x:3080`),之后 App 自动切换:出门走蒲公英、回家走局域网(设置 → 电脑地址显示「共 N 个地址自动切换」)。详见 06-install-run.md §5。
34
+ **切换电脑地址**:设置 → 电脑地址 → 点按弹出候选地址列表(当前地址打勾),选择后自动探测可达并切换重连——回家切局域网、出门切蒲公英(v2.5.0 起)。
35
+ **重新配置连接**:设置 → 重新配置连接 → 回到连接页(可重新扫码/输入)。
36
+ ## 4. 安全须知
37
+
38
+ - 访问口令是唯一凭据:二维码含口令,请勿截屏转发;怀疑泄露立即在 `cordis.patch.yml` 更换并重启。
39
+ - App 仅与电脑直连(局域网/蒲公英虚拟网),无 TLS —— 只在**自家可信 WiFi** 或**虚拟组网**下使用;不要把 3080 端口暴露公网。
40
+ - 连接信息仅存手机本地,不上传任何第三方。
41
+ ## 5. 常见问题(FAQ)
42
+ **Q1 连接失败/超时**
43
+ - 电脑端 DSH 是否运行?**桌面版请确认插件 LAN 桥已启用**(`lanBridge.enabled: true`,默认 `0.0.0.0:3080`,见 docs/06 §4b);web 版默认即 `0.0.0.0:3080` 无需配置(改端口时覆盖 webserver 行须写全 `host`+`port`)?
44
+ - 手机与电脑是否同一网络?口令是否正确(改过需重启桌面端)?
45
+ - Windows 防火墙若拦截 3080,放行 `node`/`DeepSeek Harness`。
46
+ **Q2 扫码没反应**
47
+ - App 用自带「扫码连接」按钮(系统相机会跳浏览器打开网页);二维码随口令变更而更新(改口令需重启桌面端)。
48
+ **Q3 发消息没反应**
49
+ - agent 正在处理上一轮时新消息会**排队**(App 有提示);等上一轮完成。
50
+ - 状态点:绿色=执行中,橙色=等待你回答(直接回复)。
51
+ **Q4 收不到系统通知**
52
+ - 需部署者配置 `pushUrls`(企业微信机器人 / Server酱 / ntfy / Bark,见 docs/06 §6);检查手机通知权限。
53
+ - **先验证通道**:设置 → 通知 → **「发送测试通知」**——逐个通道发测试消息,返回"成功几个";失败的通道对照 docs/06 检查 URL/格式/配额(Server酱每日 5 条、ntfy.sh 境内不通等)。
54
+ **Q5 看不到实时回复**
55
+ - SSE 断线自动重连(指数退避),恢复后自动补拉历史;检查网络。
56
+ **Q6 新建会话在 PC 端显示"未分组"**
57
+ - 所选目录不在任何已注册工作区(或其子目录);在工作区子目录下会自动归属。
58
+ **Q7 agent 问问题/要权限时,手机不弹卡片**
59
+ - 确认你在**该会话的对话页**(弹窗是会话内的,别处只有通知中心「需要你回答」条目,点进去即见弹窗)。
60
+ - 电脑端 dsh 是否为最新版并已**重启**(弹窗桥随插件加载)?App 设置 → 环境诊断:`respondBridge`/`frameBridge` 应为 ✅(否则见 docs/09-compatibility.md)。
61
+ - 若电脑上也没有弹窗:可能是该会话审批策略为「从不询问」,或你的 Harness 已配置自动答题/自动审批(此时不弹窗是正常行为)。
62
+ **Q8 其他品牌手机能用吗 / 有苹果版吗**
63
+ - Android 7.0+ 均可(渲染自动回退,详见 docs/09-compatibility.md §3);苹果端尚未开发(§4)。
64
+ **Q9 换手机/重装后要重新连接吗**
65
+ - 要:连接信息只存手机本地,换机后用二维码重新扫一次即可(口令未变则无需改电脑端)。
@@ -0,0 +1,86 @@
1
+ # 08 扩展与二次开发指南
2
+ > 本项目的设计目标之一就是**容易扩展**:从改一行文案到加一个完整功能,都有清晰的切入点。
3
+ > 欢迎你在此基础上创建自己的版本,也欢迎把好的改动 PR 回上游。
4
+ > 注:v2.1 起已移除网页版(`page.html`),移动端仅原生 App;扩展主要落在服务端端点、插件契约与 App 界面。
5
+ ## 1. 扩展点总览(由浅入深)
6
+
7
+ | 层级 | 能改什么 | 难度 | 入口 |
8
+ |---|---|---|---|
9
+ | 文案/样式 | 首页文案、配色、圆角、间距 | ★ | App `lib/theme.dart`、各 screen |
10
+ | 插件动作区 | 第三方插件往移动端加"快捷动作" | ★★ | 插件契约 `mobileActions`(见 §2) |
11
+ | 推送通道 | 自定义通知渠道 | ★★ | `pushUrls` + `pushToChannel`(见 §3) |
12
+ | 服务端端点 | 新 API(自定义数据/操作) | ★★★ | `lib/index.js` `handleApi` |
13
+ | App 原生界面 | 主题、图标、页面、深色模式 | ★★★ | `dsh-mobile-app/`(Flutter) |
14
+ | 桌面设置页 | 扫码页样式/信息 | ★★ | `lib/client.js`(dsh 客户端模块) |
15
+
16
+ ## 2. 插件动作区(最推荐的扩展方式)
17
+
18
+ 任何 dsh 插件都可以向移动端注册"快捷动作"——对话页底部自动出现动作按钮,点击后带参数执行。`mobileActions` 服务由本插件提供(`ctx.provide`),**其他插件消费**:
19
+
20
+ ```js
21
+ // 你的插件里:取服务并注册
22
+ const mobileActions = ctx.get("mobileActions");
23
+ mobileActions?.register({
24
+ id: "translate-clipboard",
25
+ title: "翻译剪贴板",
26
+ icon: "globe", // 移动端 App 内置图标 id(见 dsh-mobile-app 图标映射)
27
+ fields: [{ key: "target", label: "目标语言", placeholder: "en" }],
28
+ handler(args) {
29
+ const text = clipboard.read();
30
+ return translator.translate(text, args.target);
31
+ },
32
+ });
33
+ ```
34
+
35
+ 注册后:移动端对话页自动出现「翻译剪贴板」按钮 → 点击弹参数表单 → 执行(跑在电脑端)→ 结果经会话消息回流。
36
+ **约定**:`handler` 在电脑端执行;长任务不要同步等待,通过发消息/工具调用呈现进展(`POST /m/api/actions/:id/invoke` 立即返回 `accepted`)。
37
+ ## 3. 自定义推送通道
38
+
39
+ `pushUrls` 支持 `generic` 格式 —— 任何 HTTP webhook 都能接:
40
+
41
+ ```yaml
42
+ pushUrls:
43
+ - name: 我的机器人
44
+ url: https://my-bot.example.com/hook
45
+ format: generic # POST JSON: { kind, title, detail, sessionId, time }
46
+ ```
47
+
48
+ 想加一个**正式通道**(像 serverchan/ntfy 那样有专属格式):
49
+ 1. 在 `lib/index.js` 的 `pushToChannel` 加一个 `else if (target.format === "xxx")`
50
+ 2. `docs/03-api.md` 与 README 推送节补说明
51
+ ## 4. App 定制(dsh-mobile-app)
52
+ - **主题**:`lib/theme.dart` —— DeepSeek 设计令牌集中在这一个文件(浅色/深色两套),换色只改这里
53
+ - **图标**:覆盖 `assets/icon-1024.png` → `python tools/make_icon.py` → 重新构建
54
+ - **页面**:`lib/screens/` 每页一个文件,结构清晰
55
+ - **状态/事件**:`lib/store.dart` 全局状态 + SSE 事件桥;`lib/api.dart` 全部 API 调用
56
+ - **构建**:见 App README(`flutter analyze` + `flutter build apk --release`)
57
+ ## 5. 桌面设置页定制(lib/client.js)
58
+ - dsh 设置页「连接移动端设备」由 `client.js` 客户端模块提供(React 手写,无构建链)
59
+ - 数据来自 `/m/api/qr-config`(仅 loopback);二维码经 `/m/qr.png?text=...` 生成
60
+ - 改文案/布局直接编辑该文件,重启桌面端生效
61
+ ## 6. 保持兼容的约定
62
+ 改代码时请守住这些边界(否则可能破坏既有部署):
63
+
64
+ - **路由**:`/m` 前缀与 `handleApi` 结构不要动;新端点加在 `handleApi` 内并补文档
65
+ - **认证**:新端点默认走统一鉴权;含敏感数据的端点只允许 loopback(参考 `/api/qr-config`)
66
+ - **API 兼容**:已发布端点(docs/03-api.md 总表)的响应结构不要破坏性变更;要改就加字段
67
+ - **SSE 事件格式**:`summarizeEvent` 输出结构是 App 依赖的契约
68
+ - **App 多端并存**:App 与脚本测试共享同一 API,改服务端时都要验证
69
+
70
+ ## 7. 分享你的版本
71
+
72
+ - **小改动**:直接提 PR 回上游(见 CONTRIBUTING.md)
73
+ - **个性化定制**:Fork 后改自己的分支,README 注明基于哪个版本
74
+ - **独立插件**:动作区/新端点做成独立 dsh 插件(依赖 `ctx.provide("mobileActions")`),互不冲突
75
+ - **展示**:欢迎在 README「衍生项目」区挂你的链接
76
+ ## 8. 常见扩展需求速查
77
+
78
+ | 想要 | 改哪里 |
79
+ |---|---|
80
+ | 换首页欢迎语 | `home_screen.dart`(App) |
81
+ | 换主题色 | App `lib/theme.dart` |
82
+ | 加一个快捷操作按钮 | 动作区注册(§2) |
83
+ | 推送发到我的机器人 | generic webhook(§3) |
84
+ | 对话页加特殊消息类型 | `summarizeEvent` + App `chat_screen.dart` 渲染 |
85
+ | 新建会话加字段 | `handleApi` `/sessions` + 弹层 |
86
+