@marktrue/dsh-mobile-remote 3.2.3-rc.1 → 3.2.4-alpha.1-app

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 (353) hide show
  1. package/DSH-Remote-v3.2.4.apk +4 -0
  2. package/README.md +6 -254
  3. package/manifest.json +21 -0
  4. package/package.json +12 -65
  5. package/CHANGELOG.md +0 -1362
  6. package/CONTRIBUTING.md +0 -59
  7. package/FAQ.md +0 -111
  8. package/cordis.patch.yml +0 -14
  9. package/docs/00-/345/274/200/345/217/221/346/200/273/347/272/262.md +0 -125
  10. package/docs/01-PRD.md +0 -148
  11. package/docs/02-architecture.md +0 -249
  12. package/docs/03-api.md +0 -930
  13. package/docs/04-security.md +0 -100
  14. package/docs/05-test-cases.md +0 -405
  15. package/docs/06-install-run.md +0 -372
  16. package/docs/07-user-manual.md +0 -70
  17. package/docs/08-/346/211/251/345/261/225/345/274/200/345/217/221/346/214/207/345/215/227.md +0 -86
  18. package/docs/09-compatibility.md +0 -227
  19. package/docs/10-release.md +0 -929
  20. package/docs/screenshots/01-home.png +0 -0
  21. package/docs/screenshots/02-notifications.png +0 -0
  22. package/docs/screenshots/03-sessions.png +0 -0
  23. package/docs/screenshots/04-chat.png +0 -0
  24. package/docs/screenshots/05-settings.png +0 -0
  25. package/docs/screenshots/06-new-session.png +0 -0
  26. package/docs/screenshots/pgy-appstore.jpg +0 -0
  27. package/docs/screenshots/pgy-mobile-app.jpg +0 -0
  28. package/docs/screenshots/pgy-pc-client.jpg +0 -0
  29. package/docs/spec-app-auto-update.md +0 -143
  30. package/lib/account-usage.js +0 -145
  31. package/lib/app-alignment.js +0 -112
  32. package/lib/app-carrier-store.js +0 -1972
  33. package/lib/app-carrier.js +0 -609
  34. package/lib/client.js +0 -1174
  35. package/lib/desktop-form.js +0 -738
  36. package/lib/endpoint-registry.js +0 -165
  37. package/lib/git-read-bundled-provider.js +0 -255
  38. package/lib/git-read-service.js +0 -322
  39. package/lib/index.js +0 -9609
  40. package/lib/npm-update-source.js +0 -226
  41. package/lib/plugin-content-digest.js +0 -80
  42. package/lib/plugin-self-update.js +0 -997
  43. package/lib/plugin-update-controller.js +0 -274
  44. package/lib/plugin-update-log.js +0 -164
  45. package/lib/plugin-update-transaction.js +0 -322
  46. package/lib/plugin-update.js +0 -309
  47. package/lib/runtime-dependency-snapshot.js +0 -345
  48. package/lib/session-title-cache.js +0 -123
  49. package/lib/session-title-refresh.js +0 -261
  50. package/lib/tool-process.js +0 -20
  51. package/lib/update-fetch.js +0 -24
  52. package/lib/update-lock-arbiter.js +0 -170
  53. package/lib/update-supervisor.js +0 -346
  54. package/node_modules/ansi-regex/index.d.ts +0 -37
  55. package/node_modules/ansi-regex/index.js +0 -10
  56. package/node_modules/ansi-regex/license +0 -9
  57. package/node_modules/ansi-regex/package.json +0 -55
  58. package/node_modules/ansi-regex/readme.md +0 -78
  59. package/node_modules/ansi-styles/index.d.ts +0 -345
  60. package/node_modules/ansi-styles/index.js +0 -163
  61. package/node_modules/ansi-styles/license +0 -9
  62. package/node_modules/ansi-styles/package.json +0 -56
  63. package/node_modules/ansi-styles/readme.md +0 -152
  64. package/node_modules/camelcase/index.d.ts +0 -63
  65. package/node_modules/camelcase/index.js +0 -76
  66. package/node_modules/camelcase/license +0 -9
  67. package/node_modules/camelcase/package.json +0 -43
  68. package/node_modules/camelcase/readme.md +0 -99
  69. package/node_modules/cliui/CHANGELOG.md +0 -76
  70. package/node_modules/cliui/LICENSE.txt +0 -14
  71. package/node_modules/cliui/README.md +0 -115
  72. package/node_modules/cliui/index.js +0 -354
  73. package/node_modules/cliui/package.json +0 -65
  74. package/node_modules/color-convert/CHANGELOG.md +0 -54
  75. package/node_modules/color-convert/LICENSE +0 -21
  76. package/node_modules/color-convert/README.md +0 -68
  77. package/node_modules/color-convert/conversions.js +0 -839
  78. package/node_modules/color-convert/index.js +0 -81
  79. package/node_modules/color-convert/package.json +0 -48
  80. package/node_modules/color-convert/route.js +0 -97
  81. package/node_modules/color-name/LICENSE +0 -8
  82. package/node_modules/color-name/README.md +0 -11
  83. package/node_modules/color-name/index.js +0 -152
  84. package/node_modules/color-name/package.json +0 -28
  85. package/node_modules/decamelize/index.js +0 -13
  86. package/node_modules/decamelize/license +0 -21
  87. package/node_modules/decamelize/package.json +0 -38
  88. package/node_modules/decamelize/readme.md +0 -48
  89. package/node_modules/dijkstrajs/.travis.yml +0 -4
  90. package/node_modules/dijkstrajs/CONTRIBUTING.md +0 -8
  91. package/node_modules/dijkstrajs/LICENSE.md +0 -19
  92. package/node_modules/dijkstrajs/README.md +0 -18
  93. package/node_modules/dijkstrajs/dijkstra.js +0 -165
  94. package/node_modules/dijkstrajs/package.json +0 -60
  95. package/node_modules/dijkstrajs/test/dijkstra.test.js +0 -96
  96. package/node_modules/emoji-regex/LICENSE-MIT.txt +0 -20
  97. package/node_modules/emoji-regex/README.md +0 -73
  98. package/node_modules/emoji-regex/es2015/index.js +0 -6
  99. package/node_modules/emoji-regex/es2015/text.js +0 -6
  100. package/node_modules/emoji-regex/index.d.ts +0 -23
  101. package/node_modules/emoji-regex/index.js +0 -6
  102. package/node_modules/emoji-regex/package.json +0 -50
  103. package/node_modules/emoji-regex/text.js +0 -6
  104. package/node_modules/find-up/index.d.ts +0 -137
  105. package/node_modules/find-up/index.js +0 -89
  106. package/node_modules/find-up/license +0 -9
  107. package/node_modules/find-up/package.json +0 -53
  108. package/node_modules/find-up/readme.md +0 -156
  109. package/node_modules/get-caller-file/LICENSE.md +0 -6
  110. package/node_modules/get-caller-file/README.md +0 -41
  111. package/node_modules/get-caller-file/index.d.ts +0 -2
  112. package/node_modules/get-caller-file/index.js +0 -22
  113. package/node_modules/get-caller-file/index.js.map +0 -1
  114. package/node_modules/get-caller-file/package.json +0 -42
  115. package/node_modules/is-fullwidth-code-point/index.d.ts +0 -17
  116. package/node_modules/is-fullwidth-code-point/index.js +0 -50
  117. package/node_modules/is-fullwidth-code-point/license +0 -9
  118. package/node_modules/is-fullwidth-code-point/package.json +0 -42
  119. package/node_modules/is-fullwidth-code-point/readme.md +0 -39
  120. package/node_modules/locate-path/index.d.ts +0 -83
  121. package/node_modules/locate-path/index.js +0 -65
  122. package/node_modules/locate-path/license +0 -9
  123. package/node_modules/locate-path/package.json +0 -45
  124. package/node_modules/locate-path/readme.md +0 -122
  125. package/node_modules/p-limit/index.d.ts +0 -38
  126. package/node_modules/p-limit/index.js +0 -57
  127. package/node_modules/p-limit/license +0 -9
  128. package/node_modules/p-limit/package.json +0 -52
  129. package/node_modules/p-limit/readme.md +0 -101
  130. package/node_modules/p-locate/index.d.ts +0 -64
  131. package/node_modules/p-locate/index.js +0 -52
  132. package/node_modules/p-locate/license +0 -9
  133. package/node_modules/p-locate/package.json +0 -53
  134. package/node_modules/p-locate/readme.md +0 -90
  135. package/node_modules/p-try/index.d.ts +0 -39
  136. package/node_modules/p-try/index.js +0 -9
  137. package/node_modules/p-try/license +0 -9
  138. package/node_modules/p-try/package.json +0 -42
  139. package/node_modules/p-try/readme.md +0 -58
  140. package/node_modules/path-exists/index.d.ts +0 -28
  141. package/node_modules/path-exists/index.js +0 -23
  142. package/node_modules/path-exists/license +0 -9
  143. package/node_modules/path-exists/package.json +0 -39
  144. package/node_modules/path-exists/readme.md +0 -52
  145. package/node_modules/pngjs/.eslintignore +0 -2
  146. package/node_modules/pngjs/.eslintrc.json +0 -19
  147. package/node_modules/pngjs/.prettierignore +0 -3
  148. package/node_modules/pngjs/LICENSE +0 -20
  149. package/node_modules/pngjs/README.md +0 -429
  150. package/node_modules/pngjs/browser.js +0 -16096
  151. package/node_modules/pngjs/coverage/lcov-report/base.css +0 -354
  152. package/node_modules/pngjs/coverage/lcov-report/bitmapper.js.html +0 -881
  153. package/node_modules/pngjs/coverage/lcov-report/bitpacker.js.html +0 -554
  154. package/node_modules/pngjs/coverage/lcov-report/block-navigation.js +0 -77
  155. package/node_modules/pngjs/coverage/lcov-report/chunkstream.js.html +0 -647
  156. package/node_modules/pngjs/coverage/lcov-report/constants.js.html +0 -176
  157. package/node_modules/pngjs/coverage/lcov-report/crc.js.html +0 -200
  158. package/node_modules/pngjs/coverage/lcov-report/favicon.png +0 -0
  159. package/node_modules/pngjs/coverage/lcov-report/filter-pack.js.html +0 -593
  160. package/node_modules/pngjs/coverage/lcov-report/filter-parse-async.js.html +0 -152
  161. package/node_modules/pngjs/coverage/lcov-report/filter-parse-sync.js.html +0 -143
  162. package/node_modules/pngjs/coverage/lcov-report/filter-parse.js.html +0 -611
  163. package/node_modules/pngjs/coverage/lcov-report/format-normaliser.js.html +0 -359
  164. package/node_modules/pngjs/coverage/lcov-report/index.html +0 -426
  165. package/node_modules/pngjs/coverage/lcov-report/interlace.js.html +0 -365
  166. package/node_modules/pngjs/coverage/lcov-report/packer-async.js.html +0 -230
  167. package/node_modules/pngjs/coverage/lcov-report/packer-sync.js.html +0 -248
  168. package/node_modules/pngjs/coverage/lcov-report/packer.js.html +0 -467
  169. package/node_modules/pngjs/coverage/lcov-report/paeth-predictor.js.html +0 -128
  170. package/node_modules/pngjs/coverage/lcov-report/parser-async.js.html +0 -575
  171. package/node_modules/pngjs/coverage/lcov-report/parser-sync.js.html +0 -404
  172. package/node_modules/pngjs/coverage/lcov-report/parser.js.html +0 -950
  173. package/node_modules/pngjs/coverage/lcov-report/png-sync.js.html +0 -116
  174. package/node_modules/pngjs/coverage/lcov-report/png.js.html +0 -662
  175. package/node_modules/pngjs/coverage/lcov-report/prettify.css +0 -101
  176. package/node_modules/pngjs/coverage/lcov-report/prettify.js +0 -1007
  177. package/node_modules/pngjs/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  178. package/node_modules/pngjs/coverage/lcov-report/sorter.js +0 -169
  179. package/node_modules/pngjs/coverage/lcov-report/sync-inflate.js.html +0 -584
  180. package/node_modules/pngjs/coverage/lcov-report/sync-reader.js.html +0 -215
  181. package/node_modules/pngjs/coverage/lcov.info +0 -2177
  182. package/node_modules/pngjs/lib/bitmapper.js +0 -267
  183. package/node_modules/pngjs/lib/bitpacker.js +0 -158
  184. package/node_modules/pngjs/lib/chunkstream.js +0 -189
  185. package/node_modules/pngjs/lib/constants.js +0 -32
  186. package/node_modules/pngjs/lib/crc.js +0 -40
  187. package/node_modules/pngjs/lib/filter-pack.js +0 -171
  188. package/node_modules/pngjs/lib/filter-parse-async.js +0 -24
  189. package/node_modules/pngjs/lib/filter-parse-sync.js +0 -21
  190. package/node_modules/pngjs/lib/filter-parse.js +0 -177
  191. package/node_modules/pngjs/lib/format-normaliser.js +0 -93
  192. package/node_modules/pngjs/lib/interlace.js +0 -95
  193. package/node_modules/pngjs/lib/packer-async.js +0 -50
  194. package/node_modules/pngjs/lib/packer-sync.js +0 -56
  195. package/node_modules/pngjs/lib/packer.js +0 -129
  196. package/node_modules/pngjs/lib/paeth-predictor.js +0 -16
  197. package/node_modules/pngjs/lib/parser-async.js +0 -165
  198. package/node_modules/pngjs/lib/parser-sync.js +0 -108
  199. package/node_modules/pngjs/lib/parser.js +0 -290
  200. package/node_modules/pngjs/lib/png-sync.js +0 -12
  201. package/node_modules/pngjs/lib/png.js +0 -194
  202. package/node_modules/pngjs/lib/sync-inflate.js +0 -168
  203. package/node_modules/pngjs/lib/sync-reader.js +0 -45
  204. package/node_modules/pngjs/package.json +0 -73
  205. package/node_modules/qrcode/README.md +0 -770
  206. package/node_modules/qrcode/bin/qrcode +0 -159
  207. package/node_modules/qrcode/helper/to-sjis-browser.js +0 -2
  208. package/node_modules/qrcode/helper/to-sjis.js +0 -105
  209. package/node_modules/qrcode/lib/browser.js +0 -76
  210. package/node_modules/qrcode/lib/can-promise.js +0 -7
  211. package/node_modules/qrcode/lib/core/alignment-pattern.js +0 -83
  212. package/node_modules/qrcode/lib/core/alphanumeric-data.js +0 -59
  213. package/node_modules/qrcode/lib/core/bit-buffer.js +0 -37
  214. package/node_modules/qrcode/lib/core/bit-matrix.js +0 -65
  215. package/node_modules/qrcode/lib/core/byte-data.js +0 -30
  216. package/node_modules/qrcode/lib/core/error-correction-code.js +0 -135
  217. package/node_modules/qrcode/lib/core/error-correction-level.js +0 -50
  218. package/node_modules/qrcode/lib/core/finder-pattern.js +0 -22
  219. package/node_modules/qrcode/lib/core/format-info.js +0 -29
  220. package/node_modules/qrcode/lib/core/galois-field.js +0 -69
  221. package/node_modules/qrcode/lib/core/kanji-data.js +0 -54
  222. package/node_modules/qrcode/lib/core/mask-pattern.js +0 -234
  223. package/node_modules/qrcode/lib/core/mode.js +0 -167
  224. package/node_modules/qrcode/lib/core/numeric-data.js +0 -43
  225. package/node_modules/qrcode/lib/core/polynomial.js +0 -62
  226. package/node_modules/qrcode/lib/core/qrcode.js +0 -495
  227. package/node_modules/qrcode/lib/core/reed-solomon-encoder.js +0 -56
  228. package/node_modules/qrcode/lib/core/regex.js +0 -31
  229. package/node_modules/qrcode/lib/core/segments.js +0 -330
  230. package/node_modules/qrcode/lib/core/utils.js +0 -63
  231. package/node_modules/qrcode/lib/core/version-check.js +0 -9
  232. package/node_modules/qrcode/lib/core/version.js +0 -163
  233. package/node_modules/qrcode/lib/index.js +0 -12
  234. package/node_modules/qrcode/lib/renderer/canvas.js +0 -63
  235. package/node_modules/qrcode/lib/renderer/png.js +0 -78
  236. package/node_modules/qrcode/lib/renderer/svg-tag.js +0 -81
  237. package/node_modules/qrcode/lib/renderer/svg.js +0 -19
  238. package/node_modules/qrcode/lib/renderer/terminal/terminal-small.js +0 -85
  239. package/node_modules/qrcode/lib/renderer/terminal/terminal.js +0 -49
  240. package/node_modules/qrcode/lib/renderer/terminal.js +0 -9
  241. package/node_modules/qrcode/lib/renderer/utf8.js +0 -71
  242. package/node_modules/qrcode/lib/renderer/utils.js +0 -99
  243. package/node_modules/qrcode/lib/server.js +0 -138
  244. package/node_modules/qrcode/license +0 -10
  245. package/node_modules/qrcode/package.json +0 -77
  246. package/node_modules/require-directory/.jshintrc +0 -67
  247. package/node_modules/require-directory/.npmignore +0 -1
  248. package/node_modules/require-directory/.travis.yml +0 -3
  249. package/node_modules/require-directory/LICENSE +0 -22
  250. package/node_modules/require-directory/README.markdown +0 -184
  251. package/node_modules/require-directory/index.js +0 -86
  252. package/node_modules/require-directory/package.json +0 -40
  253. package/node_modules/require-main-filename/CHANGELOG.md +0 -26
  254. package/node_modules/require-main-filename/LICENSE.txt +0 -14
  255. package/node_modules/require-main-filename/README.md +0 -26
  256. package/node_modules/require-main-filename/index.js +0 -18
  257. package/node_modules/require-main-filename/package.json +0 -35
  258. package/node_modules/set-blocking/CHANGELOG.md +0 -26
  259. package/node_modules/set-blocking/LICENSE.txt +0 -14
  260. package/node_modules/set-blocking/README.md +0 -31
  261. package/node_modules/set-blocking/index.js +0 -7
  262. package/node_modules/set-blocking/package.json +0 -42
  263. package/node_modules/string-width/index.d.ts +0 -29
  264. package/node_modules/string-width/index.js +0 -47
  265. package/node_modules/string-width/license +0 -9
  266. package/node_modules/string-width/package.json +0 -56
  267. package/node_modules/string-width/readme.md +0 -50
  268. package/node_modules/strip-ansi/index.d.ts +0 -17
  269. package/node_modules/strip-ansi/index.js +0 -4
  270. package/node_modules/strip-ansi/license +0 -9
  271. package/node_modules/strip-ansi/package.json +0 -54
  272. package/node_modules/strip-ansi/readme.md +0 -46
  273. package/node_modules/which-module/LICENSE +0 -13
  274. package/node_modules/which-module/README.md +0 -58
  275. package/node_modules/which-module/index.js +0 -9
  276. package/node_modules/which-module/package.json +0 -41
  277. package/node_modules/wrap-ansi/index.js +0 -186
  278. package/node_modules/wrap-ansi/license +0 -9
  279. package/node_modules/wrap-ansi/package.json +0 -61
  280. package/node_modules/wrap-ansi/readme.md +0 -97
  281. package/node_modules/y18n/CHANGELOG.md +0 -35
  282. package/node_modules/y18n/LICENSE +0 -13
  283. package/node_modules/y18n/README.md +0 -109
  284. package/node_modules/y18n/index.js +0 -188
  285. package/node_modules/y18n/package.json +0 -39
  286. package/node_modules/yargs/CHANGELOG.md +0 -420
  287. package/node_modules/yargs/LICENSE +0 -21
  288. package/node_modules/yargs/README.md +0 -140
  289. package/node_modules/yargs/build/lib/apply-extends.d.ts +0 -2
  290. package/node_modules/yargs/build/lib/apply-extends.js +0 -65
  291. package/node_modules/yargs/build/lib/argsert.d.ts +0 -2
  292. package/node_modules/yargs/build/lib/argsert.js +0 -65
  293. package/node_modules/yargs/build/lib/command.d.ts +0 -64
  294. package/node_modules/yargs/build/lib/command.js +0 -416
  295. package/node_modules/yargs/build/lib/common-types.d.ts +0 -36
  296. package/node_modules/yargs/build/lib/common-types.js +0 -25
  297. package/node_modules/yargs/build/lib/completion-templates.d.ts +0 -2
  298. package/node_modules/yargs/build/lib/completion-templates.js +0 -50
  299. package/node_modules/yargs/build/lib/completion.d.ts +0 -21
  300. package/node_modules/yargs/build/lib/completion.js +0 -135
  301. package/node_modules/yargs/build/lib/is-promise.d.ts +0 -1
  302. package/node_modules/yargs/build/lib/is-promise.js +0 -9
  303. package/node_modules/yargs/build/lib/levenshtein.d.ts +0 -1
  304. package/node_modules/yargs/build/lib/levenshtein.js +0 -58
  305. package/node_modules/yargs/build/lib/middleware.d.ts +0 -10
  306. package/node_modules/yargs/build/lib/middleware.js +0 -57
  307. package/node_modules/yargs/build/lib/obj-filter.d.ts +0 -1
  308. package/node_modules/yargs/build/lib/obj-filter.js +0 -14
  309. package/node_modules/yargs/build/lib/parse-command.d.ts +0 -11
  310. package/node_modules/yargs/build/lib/parse-command.js +0 -36
  311. package/node_modules/yargs/build/lib/process-argv.d.ts +0 -2
  312. package/node_modules/yargs/build/lib/process-argv.js +0 -31
  313. package/node_modules/yargs/build/lib/usage.d.ts +0 -49
  314. package/node_modules/yargs/build/lib/usage.js +0 -540
  315. package/node_modules/yargs/build/lib/validation.d.ts +0 -34
  316. package/node_modules/yargs/build/lib/validation.js +0 -330
  317. package/node_modules/yargs/build/lib/yargs.d.ts +0 -274
  318. package/node_modules/yargs/build/lib/yargs.js +0 -1190
  319. package/node_modules/yargs/build/lib/yerror.d.ts +0 -4
  320. package/node_modules/yargs/build/lib/yerror.js +0 -11
  321. package/node_modules/yargs/index.js +0 -40
  322. package/node_modules/yargs/locales/be.json +0 -46
  323. package/node_modules/yargs/locales/de.json +0 -46
  324. package/node_modules/yargs/locales/en.json +0 -51
  325. package/node_modules/yargs/locales/es.json +0 -46
  326. package/node_modules/yargs/locales/fi.json +0 -49
  327. package/node_modules/yargs/locales/fr.json +0 -53
  328. package/node_modules/yargs/locales/hi.json +0 -49
  329. package/node_modules/yargs/locales/hu.json +0 -46
  330. package/node_modules/yargs/locales/id.json +0 -50
  331. package/node_modules/yargs/locales/it.json +0 -46
  332. package/node_modules/yargs/locales/ja.json +0 -51
  333. package/node_modules/yargs/locales/ko.json +0 -49
  334. package/node_modules/yargs/locales/nb.json +0 -44
  335. package/node_modules/yargs/locales/nl.json +0 -49
  336. package/node_modules/yargs/locales/nn.json +0 -44
  337. package/node_modules/yargs/locales/pirate.json +0 -13
  338. package/node_modules/yargs/locales/pl.json +0 -49
  339. package/node_modules/yargs/locales/pt.json +0 -45
  340. package/node_modules/yargs/locales/pt_BR.json +0 -48
  341. package/node_modules/yargs/locales/ru.json +0 -46
  342. package/node_modules/yargs/locales/th.json +0 -46
  343. package/node_modules/yargs/locales/tr.json +0 -48
  344. package/node_modules/yargs/locales/zh_CN.json +0 -48
  345. package/node_modules/yargs/locales/zh_TW.json +0 -47
  346. package/node_modules/yargs/package.json +0 -92
  347. package/node_modules/yargs/yargs.js +0 -14
  348. package/node_modules/yargs-parser/CHANGELOG.md +0 -601
  349. package/node_modules/yargs-parser/LICENSE.txt +0 -14
  350. package/node_modules/yargs-parser/README.md +0 -449
  351. package/node_modules/yargs-parser/index.js +0 -1032
  352. package/node_modules/yargs-parser/lib/tokenize-arg-string.js +0 -40
  353. package/node_modules/yargs-parser/package.json +0 -46
@@ -1,227 +0,0 @@
1
- # 09 兼容性说明(Compatibility)
2
-
3
- > 版本:v3.1.5(当前仓库发布基线;用量与额度功能以当前插件/API 实现为准) · 面向:开源使用者 / 二次开发 / 多设备部署
4
-
5
- > ⚠ **平台范围(issue #6)**:`/m/api/files*`(文件下载/上传)的 TOCTOU 防护基于 descriptor-relative 语义,**仅 Linux/macOS 可用**;**Windows 返回 `503 files-unavailable`**(安全 fail-closed,理由见 docs/04 §6)。其余功能(会话、消息、审批/问询、目录浏览、通知、推送、用量查询)不受平台限制。
6
-
7
- 本文回答两个问题:**App 在哪些手机上能跑**,以及**插件在什么样的 Harness 上能跑**。
8
-
9
- ---
10
-
11
- ## 1. 版本要求
12
-
13
- | 组件 | 要求 |
14
- |---|---|
15
- | 桌面端 DSH(Harness) | 插件不按宿主版本号硬拦截;可用性取决于宿主提供的 Remote RPC、事件桥等接口。诊断提供 `services` / `checks`,**并自 v3.1.6 起提供宿主能力三态报告**(`checks.hostCapabilities` 的 `ok`/`drift`/`missing` 与 `checks.hostGeneration`);仍**不返回宿主版本号**,因此不要把插件版本推断为宿主能力。见 §2.6;**`0.2.1` 起进程内网关调用强制显式 Peer,由 §2.7 适配(issue #34)** |
16
- | dsh-mobile-remote 插件 | **v3.1.5**;`/m/api/diagnostics` 提供 `services` / `checks`,并提供 `/m/api/account-usage` |
17
- | 手机 App(Android) | v3.1.5(与插件同版本便于配对;不同版本按 API 增量兼容);Android 7.0+、64 位机型 |
18
- | 字段级兼容(v3.1.0) | `reasoning`/`title` 为纯增量字段:新插件+旧 App 无影响(忽略新字段);新 App+旧插件自动回退(不渲染折叠块 / 桌面宠物标题兜底短码)——任意组合均可使用 |
19
- | 字段级兼容(v3.1.1) | `/m/api/directories` 根视图新增 `sep`(服务端路径分隔符);新插件+旧 App 忽略该字段即可(旧 App 在 WSL 上仍按 `\` 拼接,由服务端`normalizeServerPath` 归一化兜底,浏览/建夹/建会话均可用);新 App+旧插件缺少 `sep` 时按根视图推断分隔符——任意组合均可使用 |
20
- | 字段级兼容(v3.1.3) | `/m/api/diagnostics` 增加审批策略与远程事件桥状态(`checks.approvalMode` / `checks.remoteEvents`);旧版 App 忽略新增字段,不受影响 |
21
- | 用量与额度(v3.1.5) | 新插件+新 App 通过 `/m/api/account-usage` 显示 DeepSeek/Codex/OpenCode Go;旧 App 忽略新端点。新 App+旧插件进入该入口会显示“电脑端插件版本过旧”,不影响其它功能;升级插件后无需重新配置凭据 |
22
- | 桌面宠物面板用量与额度(沿用 ADR 0008) | 新 App+新插件:桌面宠物面板展开时按需展示三来源区块(金额行文字 + 配额行细条/颜色),整块可点进详情页。新 App+旧插件:区块整体降级为原有单行余额(点击仍=去充值),其余面板功能不受影响;旧 App 忽略新端点。无新增服务端契约 |
23
- | 外观:皮肤与图标(v3.2.2 build 27) | **纯 App 侧,无服务端契约变化**。皮肤是 `ThemeExtension` 令牌,旧插件照常工作;默认皮肤令牌与旧版逐值一致。App 图标用 8 个 `activity-alias`,只在 Android 生效(其它平台隐藏入口) |
24
- | 图标入口迁移(build 27) | 启动入口从 `com.dsh.remote.MainActivity` 改为 `com.dsh.remote.IconDefault`:**升级后桌面旧快捷方式可能失效一次**(组件名变化,桌面固定的是组件名),首次启动有一次性说明引导重拖。抽屉入口不受影响 |
25
- | 桌面宠物前台联动(build 27) | `MainActivity.onStart/onStop` → 服务根视图 `GONE`:App 在前台时收起宠物与状态气泡/迷你面板;`设置 → 桌面宠物 → App 在前台时收起` 可关。旧系统不涉及(仅原生层行为) |
26
- | 图标主题化与圆形图标 | **已知缺口**:`mipmap-anydpi-v26` 未提供 `<monochrome>` 层,Android 13 主题图标不生效;未声明 `android:roundIcon`,圆形图标机型退化为方形。计划在后续版本补齐,不影响功能 |
27
- | Flutter 构建环境 | Flutter 3.35+(Dart SDK ^3.13) |
28
-
29
- **声明式兼容范围(`peerDependencies`)**:`@deepseek-ai/dsh-{credentials,llm,sandbox-policy,scope}` 声明 `>=0.1.0-rc.6 <0.3.0`。宿主 `@deepseek-ai/dsh-app-boot` 的 `evaluatePluginCompatibility()` 用 `semver.satisfies(runtimeVersion, range, { includePrerelease: true })` 判定(**prerelease 参与比较**),因此该范围同时覆盖 `0.1.x`、`0.2.0-rc.*` 与 `0.2.x` 正式版,而 `0.3.0+` 会被判为不兼容。上界**只用于声明可安装边界**,功能路径仍按能力探测(ADR 0017),不按版本号做功能门禁。
30
-
31
- **快速自检**:手机 App → 设置 → 环境诊断。`services` 一节列出每个内核服务是否存在;**v3.1.3+ 看 `checks.approvalMode`**(生效策略)与 **`checks.remoteEvents`**(`true` = `$events` 双端呈现通道就绪,`false` = both 降级 mobile 或配置即 mobile/desktop);`notes` 说明当前审批策略实际语义与**任何非全绿的宿主能力**。
32
-
33
- **v3.1.6+ 新增宿主能力自检**(ADR 0017;issue #30 起补原因码):
34
-
35
- - `checks.hostCapabilities`:逐项给出三态——`ok` / `drift` / `missing`。`drift` 是**能力语义漂移**(服务在、调用不报错,但成员形状不是插件认识的样子),这正是 0.2.0 四处变更与 0.2.1 peer 收紧的形态,旧的两分法看不见它们。**`gateway.eventsPeer`(issue #34)** 专门覆盖"网关入口都在、但进程内 Peer 来源缺失"这一种漂移,原因码为 `gateway-peer-source-missing`。
36
- - `checks.hostCapabilityReasons`(issue #30 审查修复):**只对 `drift` 项**给出 allow-list 原因码,避免"只报状态值查不出哪一步坏了"。`settings.read` 的取值:`settings-get-threw` / `settings-describe-threw` / `settings-describe-shape-invalid` / `settings-descriptor-without-value` / `settings-has-no-read-method`。该探针与真实读取**共享严格读取器**——对插件真正读取的命名空间逐个探测,"命名空间不存在"仍算 ok,读不到才报 `drift`。
37
- - `checks.hostGeneration`:插件**实际走了哪条代际路径**(`jobsCaller` / `settingsRead` / `wireStreamArgs` / `eventsPeer`),排查"为什么同一功能在两台机器上表现不同"时先看这里。`eventsPeer` 取值:`createPeer`(0.2.1+)/ `operatorPeer`(0.2.0 网关兜底)/ `legacy`(旧代 3 参开流不需要 peer)/ `none`(必失败)/ `unknown`(网关服务缺失,无法判定)。
38
-
39
- `services.apiProxy` / `checks.respondBridge` / `checks.frameBridge` **已随 v3.1.6 删除**:该服务自 `0.1.2-rc.1` 起就不存在,保留它们只会让人以为有一条可用的旧代降级通道。同样地,`/m/api/respond` 在待办不在本地清单时返回 `404 respond-not-pending`(此前返回 `503` 并归咎于"内核过旧",属误导——真实原因通常是"另一端已先答"或"已超时")。
40
-
41
- ---
42
-
43
- ## 2. 内核耦合点与降级行为
44
-
45
- 插件与 Harness 的耦合分三档:**硬依赖**(缺失 = 对应功能不可用)、**软依赖**(缺失 = 功能降级)、**可选**(缺失 = 自动禁用该功能)。插件对每个依赖都做了存在性探测,**任何一项缺失都不会让插件崩溃或影响其他功能**;能力缺失一律**明确报错**,不静默伪装成功([ADR 0001 = Issue #9](https://github.com/marktrue-ahu/dsh-mobile-remote/issues/9))。
46
-
47
- ### 2.1 服务(`ctx.get` / `ctx.inject`)
48
-
49
- | 服务 | 用途 | 档位 | 缺失时行为 |
50
- |---|---|---|---|
51
- | `webServer` | 挂载 `/m/api`、`/m/events`、`/m/qr.png` 路由 | 硬依赖(插件存在的意义) | v2.4 起守卫:纯 headless 形态下插件静默无操作,不崩进程 |
52
- | `sessions` | 会话列表/touch/创建/停止 | 硬依赖(内核核心) | 移动端会话功能不可用 |
53
- | `agents` | 会话创建、状态 | 硬依赖(内核核心) | 同上 |
54
- | `workspaceRegistry` | 工作区列表、会话归档(与 PC 端同一份状态) | 软依赖 | 归档/工作区筛选不可用;App 回退为 cwd 前缀分组(旧版兼容路径) |
55
- | `sessionProjections` | `turnOutline` 投影单元注册探测(轮次导航,决定 `capabilities.turnOutline`) | 软依赖 | 缺失或未注册 → 能力位 `supported: false`,App 退回「只用已加载轮次」,不按宿主机版本推断 |
56
- | `messageFeedback` | 消息 👍/👎(与 PC 端同一份) | 软依赖 | 反馈菜单隐藏/报错 |
57
- | `approval` | 权限策略读取(`setPolicy` 仅当存在时调用) | 可选 | 跳过策略写入 |
58
- | `credentials` | DeepSeek 余额查询 | 可选 | 回退环境变量 `DEEPSEEK_API_KEY`;都没有则余额不可用 |
59
- | `approval/request`·`user-questions/request` 瀑布 | Agent 作用域 Cordis 瀑布,插件 answerer 应答(当前代际的交互入口) | 软依赖 | 无瀑布宿主时问询/审批**无手机弹卡**(旧代 `apiProxy` 帧桥已于 v3.1.6 删除,不存在该降级出口;见 §2.6) |
60
- | `typertGateway` — Remote 调用入口(`invokeRpc` / `stream`) | 模型目录、会话配置、发送、队列操作、归档、分支、目标等 RPC | 硬依赖 | 调用失败时对应 API 返回错误;**`0.2.1` 起必须显式传活 Peer(§2.7)**,否则恒返回 `gateway/internal: …reading 'signal'` |
61
- | `typertGateway` — `$events` 远程事件桥(`openWireStream` / 结算 `dispatchRpc`) | 插件进程内 `$events` 客户端:与桌面 GUI 同收事件副本、先答生效 | 可选(v3.1.3) | 桥不可用时 `approvalMode: both` 按 `mobile` 语义降级;`checks.remoteEvents` 和运行日志可辅助诊断。**`0.2.1` 起开流与 `$events/result` 结算都必须带同一个活 Peer(§2.7)** |
62
- | `sessionController`(`prompt`) | 冷会话恢复:不在 live agent 注册表里的持久会话发送 | 冷会话路径依赖 | 宿主若不支持该调用则发送失败;当前诊断不提供该能力的独立布尔字段 |
63
- | `apiProxy`(旧代,0.1.1-rc.2 及更早) | 问询/审批帧桥 + 应答回写 | **弃用通道**(ADR 0001) | **两代宿主(0.1.5 / 0.2.0)内核树内均 0 命中**,插件侧的探测与帧桥代码**已于 v3.1.6 整块删除**(issue #19):保留它的唯一效果是让读者以为存在一条可用的旧代降级通道 |
64
-
65
- > ⚠ **approvalMode(v3.1.3,issue #9)语义**:`both`(默认)= 桌面 GUI 与手机同时弹卡、任一端先答即生效、另一端自动收卡;`mobile` = 手机在线独占应答(v3.1.2 行为),离线交桌面 GUI;`desktop` = 一律交桌面 GUI(手机不弹卡)。手机在场时待办 120s 无应答 fail-close(`unavailable` / 问询跳过)。配置于 `cordis.patch.yml` → mobile-remote 行 `config.approvalMode`,重启生效。
66
-
67
- ### 2.2 事件与 RPC
68
-
69
- | 内核接口 | 用途 | 风险与降级 |
70
- |---|---|---|
71
- | `ctx.on("session/event")` | 消息流/通知聚合/上下文窗口/队列即时同步/Conversation timeline | 事件形态随版本演进;未知类型进入通用事件卡,能力缺失时 App 回退摘要模式;解析异常被 try/catch 兜底 |
72
- | `ctx.on("agent/inbox/spliced")`(经 `session/event` 送达) | 队列即时同步:内核任何生效的 inbox 变更都会 append 该会话事件,据此重推 `mobile/queue` 快照 | 事件名与载荷在当前代际与上一代一致;缺失时手机队列退回 REST 轮询兜底(不报错,仅不实时) |
73
- | `sessionQuery.readEvent`(可选) | Tool activity 与未知 Visible event 的按需无损详情 | 不存在时回退快照;旧历史详情明确显示不可用,不猜测重建 |
74
- | `sessionQuery.observeSession`(可选) | 投影感知的会话观察(轮次大纲,轮次导航) | 不存在时 `/m/api/turn-outline` 显式返回 `capability-missing`;不把「宿主不支持」误报成「该会话没有轮次」 |
75
- | `ctx.on("agent/status")` | 状态点(绿/橙) | 同上 |
76
- | `typertGateway`(`invokeRpc` / `stream` / `openWireStream` / `dispatchRpc`) | 全部内核 RPC 与 `$events` 双端审批通道 | **`0.2.1` 起必须显式传活 Peer(§2.7)**;漏传/传错返回 `gateway/internal: …reading 'signal'`,由错误映射转成业务错误码(不再静默) |
77
- | `session/modelCatalog` RPC | 模型目录(App 模型选择器) | 失败 → 目录为空,App 隐藏模型胶囊 |
78
- | `settings.update`(`agent-presets` / `permission` 命名空间) | 默认预设修改 | 与 PC 端同一写入通道;命名空间变更会导致设置失败(App 报错提示) |
79
- | `session/prompt` | 发消息(`mode: queue \| steer`,`requestId` **必填**) | `requestId` 由插件无条件铸造;缺失会被网关以 `gateway/input-invalid` 拒绝投递 |
80
- | `session/fork` / `session/cancel` | 消息分支 / 停止 | 内核接口变化 → 失败提示 |
81
-
82
- > ⚠ **子代理通知判定需要 `session.header.origin`**:通知聚合对子代理会话(`origin === "subagent"`)抑制完成/失败通知(与内核自身通知一致);fork 出的独立会话(无 origin)照常通知。
83
- >
84
- > ⚠ **两层请求幂等并存(v3.1.3)**:当前代际内核新增了按 `requestId` 的幂等短路(会扫整条持久会话日志找同 `rpcId` 的 `user/message`),与插件自建的发件回执层(`/m/api/send` + `/m/api/send-receipt`)**职责不同、两层都保留**:内核负责「同一请求不重复执行」,插件负责「传输层中断后回答是否已送达」(`Connection reset by peer` 后重试不重复即由此保证)。
85
-
86
- > ⚠ **Issue #1 时间线能力协商(纯增量):** `/bootstrap` 与 SSE `hello` 的 `capabilities.eventTimeline` 声明 `detail`、`unknownEvents`、`callCorrelation` 等能力。新版 App 只在 `capabilities.eventTimeline.detail` 且事件摘要带 `detail.available` 时请求 `/event-detail`;能力是端点级声明,单事件仍可能因旧日志/离线而不可用。旧插件没有声明时继续使用已有摘要/历史路径,并把详情显示为不可用,不按插件版本号猜测能力。
87
- >
88
- > ⚠ **当前界面降级与 dormant-session 依赖:** seeded session 若只能读取当前 surface,`/event-detail` 返回 `degraded: true` 与 `detailMode: "current-surface"`,新版 App 展示不完整提示;无法读取时使用稳定错误码和重试,不显示原始异常。休眠会话的完整读取依赖 issue #7 的独立修复,本分支不复制该实现。
89
- >
90
- > ⚠ **`/bootstrap` 的 `agents[*].sessionId`(纯增量)**:`agentId` 与 `sessionId` 不是同一标识(`session:` 前缀、子代理场景),新版 App 按 session 维护运行状态,需要 bootstrap 一并下发映射,否则冷启动/重连后要等 `agent/status` 变化帧才知道会话在跑(发送键会短暂显示为「发送」而非「停止」)。旧插件不发该字段时 App 回退按 `agentId == sessionId` 取值。`agents[*].title` 的兜底短码也改由 sessionId 派生(旧插件缺字段时不影响)。
91
-
92
- ### 2.3 高度自定义化的 Harness
93
-
94
- - **自定义权限预设/模型/Agent 预设**:App 全部从内核动态读取(catalog、session-config),不内置白名单;未知预设名显示为「…」(后续版本可拉取预设清单美化)。
95
- - **第三方插件动作**:`ctx.mobileActions.register(...)` 注册后自动出现在 App 动作区(v0.1 契约:仅 text 字段)。
96
- - **自定义问答 provider / 自动审批策略**:若用户的 Harness 已经接管人类问询(如自动答题插件、审批策略改为自动放行),内核**不会产生** `question/requested` / `approval/requested` 帧——手机不弹窗是**正确行为**,不是 bug。
97
- - **多 profile**:插件按 profile 安装(`<profile>/node_modules/dsh-mobile-remote`),每个 profile 独立配置口令/连接。
98
- - **内核依赖与宿主 API 需匹配**:`package.json` 声明的 peer dependency 范围是包管理器约束,不等价于对 DSH 宿主版本的运行时兼容保证。profile 若装有与宿主不匹配的依赖副本,可能导致 RPC 失败;升级后按 [安装说明](06-install-run.md) 检查并重装依赖。
99
-
100
- ### 2.4 旧代际与弃用通道
101
-
102
- 插件当前没有宿主版本硬拦截,也没有统一的宿主能力清单;服务可用性由具体路由和交互流程决定。宿主 API 不匹配时,相关调用可能失败或按现有降级路径处理,不应假设所有缺失能力都会映射为专用 503 错误。旧代 `apiProxy` 兼容分支**已于 v3.1.6 删除**(该服务自 `0.1.2-rc.1` 起就不存在),当前只保留 `$events` 网关路径;`dispatchRpc` 等宿主接口属于集成边界,升级 DSH 后应运行对应契约测试并在目标宿主验证问询/审批结算。
103
-
104
- ### 2.5 验收范围(如实标注)
105
-
106
- 自动化验证由仓库中的 Node 契约测试、Flutter 测试和 Android 构建组成;更新安装器、宿主 RPC 与系统权限流程仍需在目标 DSH 宿主和 Android 设备上人工验收。未执行的设备/宿主组合应标记为未验证,不从其他环境的结果推定兼容。
107
-
108
- ---
109
-
110
- ### 2.6 两代宿主 API 适配(v3.1.6,issue #19 / #21)
111
-
112
- 宿主 `0.2.0` 有**四处**接口与 `0.1.x` 不同。四处**全部表现为静默失败**——服务在、调用不报错、行为却已变("能力语义漂移",见 `CONTEXT.md`)。插件按**结构特征**探测代际并各走一条路径,不查版本号(ADR 0017):
113
-
114
- | 差异 | `0.1.x` | `0.2.x` | 插件如何判别 | 传错的后果 |
115
- |---|---|---|---|---|
116
- | 任务查询/终止的 caller | **Agent 对象**(实现内部取其 `.id`) | **SessionId 字符串** | `jobs.events.subscribe` 是否存在(两处差异同版发生) | 列表恒返回空(像"确实没有任务");终止报"任务属于另一个会话" |
117
- | 任务事件订阅 | `onJobsChanged` + `onJobDone` 两个回调 | 统一的 `events.subscribe(filter, listener)` | 同上 | 实时推送静默退化为轮询 |
118
- | 设置读取 | `get(ns)` 返回配置节 | `describe()` 返回描述符数组(取 `value`) | `typeof settings.get === "function"` | 抛出的类型错误被 `try/catch` 吞掉,提供商配置页字段凭空消失 |
119
- | 事件流打开的参数位次 | `(端点, 载荷, 取消信号)` | `(端点, 载荷, uplink, peer, 取消信号, 控制)`;**`0.2.1` 末尾又加 `uplinkWindow`(7 参)** | 形参个数(3 vs ≥5 判 control 位次) | 信号落进 `uplink`、真 signal 为 `undefined`,宿主在 `AbortSignal.any` 处抛错并被重试吞掉 → `approvalMode: both` 的双端呈现**永远不就绪**。peer 从 `0.2.1` 起必填,见 §2.7 |
120
-
121
- **另有一类风险单独处理**:插件依赖的若干宿主成员是 **TS-private**(无契约保证)——权限预设的 `names`/`presets`/`apply`,以及工作区注册表的 `enqueueOperation`/`requireState`/`setState`(后者此前**完全无守卫**)。v3.1.6 起这些成员缺失时**显式报错**(503)或显式降级,不再让 `TypeError` 在深处被吞成"按了没反应"。**不迁移**到公开 API——那是行为改变,与本次兼容修复分开评估。
122
-
123
- **`$events` 流断开改为退避重连**:原实现"就绪后一旦断开即永久放弃",使 `approvalMode: both` 在首次断流后永久退化为手机独占,直到重启宿主——而桌面 GUI 每次开关浏览器都会断流。现语义:**就绪前**失败 = 事件源尚未注册(有界重试 ≈15s);**就绪后**断开 = 瞬时断开(3s 起退避、上限 60s、无限重连,仅插件卸载才停止)。重新就绪后退避复位。
124
-
125
- **`0.2.0` 另外两处破坏(issue #21,与上述四处同类,但位于 #19 未覆盖的位置)**:
126
-
127
- | 差异 | `0.1.x` | `0.2.x` | 插件如何判别 | 传错的后果 |
128
- |---|---|---|---|---|
129
- | 子代理目录 | `subagents/list` Remote 端点 | **该端点已删除**(内核树内 0 命中;只剩 `subagents/prompt` 与 `subagents/interruptByParent`) | 改用 `ctx.subagents.listChildren(parentSessionId)`——**两代都提供**,是持久目录(走 `sessionQuery.observeSession`,**不要求父会话有活跃 Agent**) | 报 `no active Remote method exports this endpoint`,「会话工具 → 子代理」整页打不开 |
130
- | Codex 代理配置 | `settings.get(ns)` | **该方法已移除** | 跨代读取 `readSettingsSectionStrict` | **读不到配置被误判为"用户没开代理"** → 静默改走直连 `chatgpt.com` → 连接超时 → 手机看不到 Codex 余额(桌面网页端正常,因为它用自己的新 API 读同一份设置) |
131
-
132
- **"读不到配置"与"未启用"必须分开**:`codexProxyUrl` 返回三态——用户没开代理(走直连是对的)/代理可用/**读不到宿主设置**(`unreadable`,显式失败)。把第三种当成第一种,是 Codex 余额静默消失里最隐蔽的一环。严格读取还会区分「命名空间确实不存在」与「`get()`/`describe()` 抛错、describe 形状漂移、描述符缺 `value`」——后者一律 `unreadable`。
133
-
134
- **失败原因不外传**:`/m/api/account-usage` 的 `failures[].reason` 只给**稳定错误码 + 固定文案**(`timeout` / `dns` / `connection-refused` / `invalid-request` 等),**绝不回传异常原文**。凭据含内嵌 CR/LF 时,原生 fetch 的 Headers 校验会抛出带完整 Bearer 密钥的消息,而**路径脱敏不等于秘密脱敏**。
135
-
136
- **子代理列表的完整性**:不能拿会话注册表当子代理目录——`sessions.list()` 只有 **live/驻留**会话,continuable 子代理结束并释放 handle 后会从中移除,而持久目录仍保留其身份。只用注册表会在父会话还活着时"成功却显示暂无子代理"。目录读不到时退回注册表并标注 `catalogDegraded`,**不让不完整列表冒充完整目录**。
137
-
138
- **验证范围(如实标注)**:只对 **`0.2.x` 做真实宿主端到端验证**(本机宿主即 0.2.x)。`0.1.x` 那条路径的真实宿主验不到,**靠两代假宿主夹具保护**(`test/host-compat-020.test.mjs`:按真实签名复刻两代差异,让两条分支都被实际执行到)。因此 0.1.x 一侧属于"夹具已验证、真实宿主未验证"。
139
-
140
- ---
141
-
142
- ### 2.7 `0.2.1`:进程内网关调用强制 Peer(issue #34)
143
-
144
- 宿主 `0.2.1-rc.2` 把 `0.2.0` 的"peer 可省"收紧为"**每个进程内网关调用都必须显式传一个活着的 Peer**"。与 §2.6 同类:**服务在、成员在、调用不报参数错,但宿主内部先解引用 `peer.signal`**——漏传只会得到 `gateway/internal: Cannot read properties of undefined (reading 'signal')`,或在插件的重试循环里被吞成"通道不可用"。插件按能力探测(不按版本号)选择 peer 来源:
145
-
146
- | 差异 | `0.2.0` | `0.2.1-rc.2` | 插件如何判别 | 传错的后果 |
147
- |---|---|---|---|---|
148
- | 进程内 Peer 来源 | 网关自带 `operatorPeer()` 兜底(`connection.operator` 单例) | **兜底删除**;改由 `ctx.connection.createPeer({ principal, interactions })` 现造 | `typeof connection.createPeer === "function"` → `createPeer`;否则看 `gateway.operatorPeer` → `operatorPeer`;都没有 → `none` | unary RPC 恒返回 `gateway/internal`;`$events` 永不就绪、`approvalMode: both` 静默降级 mobile |
149
- | 网关四入口的 peer 实参 | 可省 | `invokeRpc(e,p,s,**peer**)` / `stream({…,**peer**})` / `openWireStream(e,p,uplink,**peer**,s,…)` / `dispatchRpc(e,p,s,**peer**)` 均必填 | 同上一行(`hostPeerSource`) | 同上 |
150
- | `$events/result` 结算身份 | peer 不参与 | `assertPeerLive` + `requireInteractions` + owner + **`client.peer !== peer` 拒绝** | 插件把**开流用的同一个 Peer 实例**用于结算 | 结算被 `gateway/interactions-forbidden` 拒绝,手机答了却"没生效" |
151
-
152
- **插件做法(issue #34 实现)**:
153
-
154
- - 插件级**单例** Peer:首次真正调用网关时惰性创建(`owner` + `interactions: "answer"`),跨 RPC 与 `$events` 开流共用;**开流与结算同一个实例**(宿主按 Peer 身份匹配),插件卸载时 `dispose()`。
155
- - `connection` 服务可能晚于插件挂载(`0.2.1` 实测首次 `ctx.get("connection")` 为 `undefined`)——首次取不到就不缓存,交给既有 `$events` 有界重试/下次调用再建;缓存的 Peer 若 `signal` 已 abort(作用域销毁)则自动重建。
156
- - `0.2.0`/`0.1.x` 不改变行为:没有 `createPeer` 时继续传 `undefined`,由网关兜底 / 旧代 3 参开流不需要 peer。
157
- - 诊断显式化:`checks.hostCapabilities["gateway.eventsPeer"]`(`ok`/`drift`,按**真实创建结果**判定而非只看工厂存在)+ `checks.hostGeneration.eventsPeer`(`createPeer`/`operatorPeer`/`legacy`/`none`/`unknown`),`drift` 时附原因码 `gateway-peer-source-missing`;创建失败写一次性告警日志;`approvalMode: both` 的降级文案不再归咎"宿主版本过低"。
158
-
159
- **验证范围(如实标注)**:`0.2.1-rc.2` 路径已在**隔离宿主**(`HOME`/`DSH_HOME` 独立、独立 profile、3099 端口)完成端到端验证:`hostCapabilities` 8/8 `ok`(含 `gateway.eventsPeer: ok`)、`hostGeneration.eventsPeer: createPeer`、`checks.remoteEvents: true`、`POST /m/api/defaults {"permissionPreset":"workspace-write"}` 返回 `200 {"ok":true}`。三代实参位次、peer 同源(含 `$events/result` 结算)、单例复用与释放、drift 上报由 `test/host-compat-021.test.mjs` 夹具钉住(变异验证:去掉结算 peer 或改为每次新建都会红);`0.2.0`/`0.1.x` 回归由 `test/host-compat-020.test.mjs` 保护。**生产宿主部署与真机验收不在本分支自动化范围内**,需按发布流程人工执行。
160
-
161
- ---
162
-
163
- ## 3. Android 多品牌适配
164
-
165
- App 为 Flutter 原生 APK(`com.dsh.remote`),渲染后端为 **Impeller(Vulkan,自动回退 OpenGLES)**。
166
-
167
- | 维度 | 状态 | 说明 |
168
- |---|---|---|
169
- | 渲染 | ✅ 已验证(小米 17 Pro Max) | Flutter 引擎在无 Vulkan 机型自动回退 GLES;再老机型回退 Skia。历史风险点:部分旧 Mali GPU 的 Impeller 花屏(2024 年问题,现版本基本修复) |
170
- | 系统版本 | Android 7.0+ | minSdk 跟随引擎默认 |
171
- | 明文 HTTP | ✅ | `usesCleartextTraffic=true` 已配置(Android 9+) |
172
- | 扫码 | ✅ | mobile_scanner(CameraX)全品牌通用 |
173
- | 后台存活 | 部分依赖系统 | 国产 ROM 杀后台会断 SSE;App 有指数退避重连 + 回前台自动探测。系统级提醒走推送桥(ntfy/Bark/Server酱),不依赖 App 存活 |
174
- | 深色/字体缩放 | ✅ | Flutter 主题自适应 |
175
-
176
- **建议发布前实测**(借 1~2 台其他品牌即可):① 长时间流式回复渲染;② 上翻深历史(Impeller 表现);③ 熄屏后回前台自动重连。
177
-
178
- **如遇渲染异常**:把 `dsh-mobile-app/android/app/src/main/AndroidManifest.xml` 中 `EnableImpeller` 改为 `false` 出一个 Skia 版验证;App 代码无需改动(列表结构两种后端都验证过)。
179
-
180
- ## 4. iOS(未开发)
181
-
182
- > **原因**:开发者手上没有苹果设备(Mac/iPhone),无法构建、真机调试与签名分发 iOS 版本——因此 iOS 端**暂未开发**。**欢迎社区贡献**:iOS 适配工作量不大,任何有 Mac 的开发者都可以按下面清单完成并提交 PR(见 CONTRIBUTING.md)。
183
-
184
- - **Dart 代码零平台依赖**,5 个插件(shared_preferences / http / path_provider / mobile_scanner / url_launcher)均有 iOS 实现;iOS 只有 Impeller 后端,而列表结构恰在 Impeller 下验证过——代码几乎不用改。
185
- - 需要:Mac + Xcode + Apple 开发者账号(自用免签/TestFlight)。
186
- - 必须的配置项(预计半天):`Info.plist` 放行局域网 http(ATS `NSAllowsLocalNetworking`)、iOS 14+ 本地网络权限文案(`NSLocalNetworkUsageDescription`)、相机权限文案。
187
- - 分发:自用可用免费账号侧载(7 天重签);公开分发走 TestFlight/App Store(需付费开发者账号)。
188
-
189
- ## 5. 已知问题清单(发布时如实告知)
190
-
191
- | # | 问题 | 影响 | 状态/缓解 |
192
- |---|---|---|---|
193
- | 1 | 问询/审批的**出站结算**依赖网关未文档化的私有方法 `dispatchRpc` | 上游若变更该通路,问询/审批在手机在线时会失效而非降级 | 启动时探测可调用性 → 缺失则 `checks.remoteEvents=false` 且瀑布按 `mobile` 语义工作(不弹出无法应答的卡片)。见 ADR 0001 |
194
- | 2 | 自定义权限预设名在 App 显示「…」 | 纯展示 | 后续拉取预设清单 |
195
- | 3 | 国产 ROM 杀后台导致通知延迟(App 内角标) | 通知不及时 | 推送桥不受影响;App 重连后补拉 |
196
- | 4 | Impeller 在极老 GPU 的潜在渲染问题(未实测) | 少数旧机可能花屏 | manifest 一行回退 Skia |
197
- | 5 | 大体积消息(数万字符)首次滚动定位 | 仅首屏定位,无功能损失 | 列表已按段加载(50 条/页) |
198
- | 6 | 明文 HTTP 通信 | 仅限可信内网 | 设计如此(docs/04-security.md);公网必须虚拟组网(蒲公英推荐)/ TLS 反代(docs/06 §5/§6b) |
199
- | 7 | 通知记录删除后,同会话同类事件会再生成新通知 | 符合预期(删除≠静音) | 已文档化 |
200
- | 8 | GIF 发送后显示静态 | 与 PC 端一致(内核附件规范化取首帧重编码)| 动态链路已就绪(Flutter 原生支持),待内核保留动画附件 |
201
- | 9 | 思维链块仅标题行(图标+字数+箭头)可点击切换,正文为可选中文本(点正文不切换,属设计) | 轻微认知成本 | 已文档化;折叠状态 v3.1.0 起按消息持久化(滚动/重进/重启保持) |
202
- | 10 | 旧版 App(≤v3.0.0)在 WSL/类 Unix 服务端浏览目录会拼出 `/\home` 形态的路径 | 旧 App 在 WSL 端目录浏览受限 | **v3.1.1 已修复**(服务端 `normalizeServerPath` 归一化);新版 App 按服务端 `sep` 拼接,任意组合可用 |
203
- | 11 | 与 dsh-web 移动端远程(`@linxin666/dsh-remote-web-ui`)同装冲突 | 两者抢 `/m` 路由前缀(对方写死不可配),可能异常/崩溃 | 本插件 `path` 改 `/mr` 等非 `/m` 单段即可共存(App 自动适配,无需重装);详见 FAQ |
204
- | 12 | 手机在线时桌面端不弹审批/问询框(v3.1.2,issue #9) | 桌面用户无法在 PC 审批/应答(只能手机答或 120s fail-close) | **v3.1.3 修复**:默认 `approvalMode: both` 双端同卡、先答生效(0.1.2-rc.1+);旧宿主/历史版本可用 `approvalMode: mobile \| desktop` 明确策略 |
205
- | 13 | `approvalMode: both` 依赖内核 `$events` 通道 | 旧宿主(0.1.1-rc.2 及更早)无法双端同卡 | 自动降级 mobile 并写日志;诊断 `notes` 可查 |
206
- | 14 | 宿主 API 存在**静默语义漂移**(服务在、调用不报错、行为却已变) | 升级宿主后功能"看起来正常但没有内容",且旧的两分法探测(存在/缺失)看不见它们 | 能力三态报告(`checks.hostCapabilities` 的 `drift` + `checks.hostGeneration`)+ 两代假宿主夹具;见 §2.6、§2.7、ADR 0017 |
207
- | 15 | `0.2.1-rc.2` 起进程内网关调用强制显式 Peer(§2.7) | 未适配的插件版本上:RPC 功能报 `gateway/internal`,`$events` 双端审批静默降级 | 已按能力探测适配(`connection.createPeer`,开流与结算同源);诊断 `gateway.eventsPeer` 可归因;旧代行为不变 |
208
-
209
- ## 6. 内置常量与"写死"数据速查
210
-
211
- **零敏感写死**:口令、密钥、推送凭据全部在用户配置(`cordis.patch.yml`)或手机本地,代码与仓库中无任何密钥硬编码。
212
-
213
- | 类别 | 内容 | 说明 |
214
- |---|---|---|
215
- | 设计令牌(有意) | 品牌色 `#426EFE` / 深色 `#0E1116` 等(App `theme.dart`)、`com.dsh.remote`、QR 协议 `DSHREMOTE\|地址\|口令`、`EnableImpeller=true` | 产品设计/通信契约,勿随意改 |
216
- | 内核耦合词(有意) | 系统消息过滤词 `Current runtime context` / `This snapshot supersedes` / `background job `(App `chat_screen.dart`) | 与内核/PC 端保持一致的隐藏规则;apiProxy 帧桥已于 v3.1.6 删除,见 §1.4 |
217
- | 插件可配置项 | `path` / `authToken` / `cookieName` / `sessionTtlMs` / `rechargeUrl` / `maxConnections` / `pushUrls` / `pushCooldownMs` / `pushContent` / `rateLimit` / `trustedHosts` / `doneGraceMs`(v2.8.0)/ `lanBridge`(v3.0.0:`enabled` 可选;未配置时仅可信 Desktop 自动启用,显式 `false` 关闭,可配 `port`/`host`)/ `approvalMode`(v3.1.3:`both` 默认 \| `mobile` \| `desktop`)/ `turnOutlineTimeoutMs`(轮次大纲端点有界等待,默认 5000ms,契约门禁可调短) | schema 默认值,改配置即可 |
218
- | 插件内置常量 | 通知上限 100、catalog 缓存 15s、SSE 心跳 25s、SSE 超时 15s、登录限流默认 10 次/60s(`rateLimit` 可配)、状态文件 `~/.dsh/mobile-remote/` | 合理默认,无需配置 |
219
- | App 内置常量 | HTTP 超时 15/20s(余额 25s)、连接/探测超时 8s、地址表上限 8、重试退避 1s→15s、看门狗 15s 检查 / 心跳 75s(3 周期)、日志保留 15 天/256KB、聊天初始窗口 50 条、历史分段 30 条、上下文圆环阈值 70%/90%、思维链折叠手动状态键 `dsh_mr_reasoning_overrides`(按会话持久化,每会话软上限 100 条) | 合理默认;修改点集中在各文件顶部常量 |
220
- | 已消除的写死 | 充值链接(原 App 硬编码 `platform.deepseek.com/top_up`) | v2.4.2 起走 `catalog.rechargeUrl`(插件配置为准) |
221
-
222
- ## 7. 发布签名
223
-
224
- - Release APK 需正式 keystore:`dsh-mobile-app/android/app/dsh-release.jks` + `android/key.properties`(**均已 gitignore,切勿提交**)。
225
- - 干净克隆无 key.properties 时自动回退 debug 签名(仅自用可安装;商店/公开分发必须自建 keystore)。
226
- - 自建方法见 `dsh-mobile-app/README.md`「构建」一节。
227
- - ⚠ 更换签名 = 新应用:用户需卸载重装并重新扫码。