@synopackageland/cli 0.6.1 → 0.7.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 (640) hide show
  1. package/CHANGELOG.md +846 -0
  2. package/README.md +81 -89
  3. package/dist/add.d.ts +4 -1
  4. package/dist/add.js +45 -17
  5. package/dist/build-spk/delegate-scope.d.ts +6 -0
  6. package/dist/build-spk/delegate-scope.js +34 -0
  7. package/dist/build-spk/dsm-arch.d.ts +7 -1
  8. package/dist/build-spk/dsm-arch.js +24 -28
  9. package/dist/build-spk/dsm-platforms.json +42 -0
  10. package/dist/build-spk/dsm-version.d.ts +11 -0
  11. package/dist/build-spk/dsm-version.js +17 -0
  12. package/dist/build-spk/gateway.js +8 -4
  13. package/dist/build-spk/generator.js +30 -5
  14. package/dist/build-spk/go-toolchain.d.ts +20 -0
  15. package/dist/build-spk/go-toolchain.js +44 -0
  16. package/dist/build-spk/notices.js +4 -1
  17. package/dist/build-spk/resource-worker.js +3 -0
  18. package/dist/build-spk/wizard-messages.d.ts +66 -0
  19. package/dist/build-spk/wizard-messages.js +75 -9
  20. package/dist/cli.js +28 -14
  21. package/dist/contract/schema-validate.js +8 -0
  22. package/dist/contract/validate.js +30 -0
  23. package/dist/deploy/deploy.d.ts +1 -1
  24. package/dist/deploy/deploy.js +8 -0
  25. package/dist/deploy/native-install-values.d.ts +17 -0
  26. package/dist/deploy/native-install-values.js +32 -0
  27. package/dist/deploy/plan.d.ts +6 -2
  28. package/dist/deploy/plan.js +58 -7
  29. package/dist/deploy/spk-version.js +1 -1
  30. package/dist/error-registry.js +54 -20
  31. package/dist/host/dsm-client.d.ts +8 -4
  32. package/dist/host/dsm-client.js +63 -21
  33. package/dist/host/dsm-http.js +24 -2
  34. package/dist/host/types.d.ts +3 -1
  35. package/dist/info.js +45 -10
  36. package/dist/init.d.ts +3 -0
  37. package/dist/init.js +50 -19
  38. package/dist/package-metadata.d.ts +21 -0
  39. package/dist/package-metadata.js +101 -0
  40. package/dist/portal/alias.d.ts +25 -0
  41. package/dist/portal/alias.js +48 -0
  42. package/dist/portal/package.d.ts +33 -0
  43. package/dist/portal/package.js +116 -0
  44. package/dist/runtime/delegate-contract.d.ts +79 -0
  45. package/dist/runtime/delegate-contract.js +27 -0
  46. package/dist/runtime/dsm-version.d.ts +6 -0
  47. package/dist/runtime/dsm-version.js +8 -0
  48. package/dist/runtime/executor-build.js +10 -6
  49. package/dist/runtime/executor-inspect.d.ts +3 -0
  50. package/dist/runtime/executor-inspect.js +11 -5
  51. package/dist/runtime/executor-policy.d.ts +12 -0
  52. package/dist/runtime/executor-policy.js +43 -3
  53. package/dist/runtime/executor-scope-task.d.ts +4 -0
  54. package/dist/runtime/executor-scope-task.js +21 -0
  55. package/dist/runtime/executor-tasks.d.ts +2 -1
  56. package/dist/runtime/executor-tasks.js +4 -4
  57. package/dist/skill.js +1 -0
  58. package/dist/standalone/api-permissions.d.ts +10 -0
  59. package/dist/standalone/api-permissions.js +19 -2
  60. package/dist/standalone/background.d.ts +16 -0
  61. package/dist/standalone/background.js +69 -2
  62. package/dist/standalone/binary.d.ts +1 -1
  63. package/dist/standalone/binary.js +22 -8
  64. package/dist/standalone/build.d.ts +1 -1
  65. package/dist/standalone/build.js +38 -8
  66. package/dist/standalone/daemon.d.ts +1 -0
  67. package/dist/standalone/daemon.js +10 -5
  68. package/dist/standalone/dsm-window.d.ts +3 -1
  69. package/dist/standalone/dsm-window.js +78 -49
  70. package/dist/standalone/inspect-spk.d.ts +8 -0
  71. package/dist/standalone/inspect-spk.js +110 -27
  72. package/dist/standalone/lifecycle.js +86 -8
  73. package/dist/standalone/manifest.d.ts +13 -0
  74. package/dist/standalone/manifest.js +57 -8
  75. package/dist/standalone/native-authorization-window.d.ts +1 -1
  76. package/dist/standalone/native-authorization-window.js +9 -1
  77. package/dist/standalone/native-layout.d.ts +3 -0
  78. package/dist/standalone/native-layout.js +37 -5
  79. package/dist/standalone/native-root-window.d.ts +4 -2
  80. package/dist/standalone/native-root-window.js +33 -18
  81. package/dist/standalone/portal-window.d.ts +21 -0
  82. package/dist/standalone/portal-window.js +155 -0
  83. package/dist/standalone/portal.d.ts +4 -0
  84. package/dist/standalone/portal.js +4 -0
  85. package/dist/standalone/resource.d.ts +5 -3
  86. package/dist/standalone/resource.js +6 -3
  87. package/dist/standalone/root-window.d.ts +4 -1
  88. package/dist/standalone/root-window.js +193 -36
  89. package/dist/standalone/spk.d.ts +1 -1
  90. package/dist/standalone/spk.js +25 -7
  91. package/dist/templates/_daemon/go.mod +1 -1
  92. package/dist/templates/_daemon/main.go +6 -3
  93. package/dist/templates/_daemon/main_test.go +82 -9
  94. package/dist/templates/_daemon/testdata/child.go +3 -0
  95. package/dist/templates/_executor/README.md +130 -16
  96. package/dist/templates/_executor/anchor.go +156 -0
  97. package/dist/templates/_executor/anchor_test.go +161 -0
  98. package/dist/templates/_executor/apppriv_review_test.go +1 -1
  99. package/dist/templates/_executor/cancel_contract_test.go +236 -0
  100. package/dist/templates/_executor/copy.go +64 -0
  101. package/dist/templates/_executor/copy_test.go +88 -0
  102. package/dist/templates/_executor/digest_review_test.go +2 -2
  103. package/dist/templates/_executor/dsm.go +63 -13
  104. package/dist/templates/_executor/dsm_test.go +95 -1
  105. package/dist/templates/_executor/executor.go +260 -49
  106. package/dist/templates/_executor/executor_test.go +36 -6
  107. package/dist/templates/_executor/go.mod +2 -0
  108. package/dist/templates/_executor/identity.go +27 -1
  109. package/dist/templates/_executor/identity_kernel_linux_test.go +60 -0
  110. package/dist/templates/_executor/identity_linux.go +82 -0
  111. package/dist/templates/_executor/identity_security_test.go +43 -0
  112. package/dist/templates/_executor/internal/lifecycle/lifecycle.go +5 -0
  113. package/dist/templates/_executor/internal/lifecycle/lifecycle_test.go +61 -3
  114. package/dist/templates/_executor/internal/taskscript/boot.sh +9 -9
  115. package/dist/templates/_executor/internal/taskscript/cmd/main.go +2 -2
  116. package/dist/templates/_executor/internal/taskscript/control.sh +15 -10
  117. package/dist/templates/_executor/internal/taskscript/tasks.go +5 -3
  118. package/dist/templates/_executor/lifecycle_test.go +11 -0
  119. package/dist/templates/_executor/link_linux.go +28 -0
  120. package/dist/templates/_executor/long_running_test.go +530 -0
  121. package/dist/templates/_executor/main.go +83 -25
  122. package/dist/templates/_executor/managed.go +3 -3
  123. package/dist/templates/_executor/managed_test.go +3 -3
  124. package/dist/templates/_executor/move_linux.go +490 -0
  125. package/dist/templates/_executor/move_linux_test.go +460 -0
  126. package/dist/templates/_executor/move_validation.go +46 -0
  127. package/dist/templates/_executor/move_validation_test.go +187 -0
  128. package/dist/templates/_executor/operations.go +926 -0
  129. package/dist/templates/_executor/path_test.go +18 -0
  130. package/dist/templates/_executor/pid.go +37 -0
  131. package/dist/templates/_executor/pid_test.go +113 -0
  132. package/dist/templates/_executor/platform_linux.go +24 -173
  133. package/dist/templates/_executor/platform_linux_test.go +9 -65
  134. package/dist/templates/_executor/platform_other.go +38 -4
  135. package/dist/templates/_executor/process.go +3 -0
  136. package/dist/templates/_executor/purge_log.go +18 -0
  137. package/dist/templates/_executor/records.go +242 -0
  138. package/dist/templates/_executor/scope_cancel_contract_test.go +91 -0
  139. package/dist/templates/_executor/scope_client.go +37 -0
  140. package/dist/templates/_executor/scope_contract.go +12 -0
  141. package/dist/templates/_executor/selected_scope.go +146 -0
  142. package/dist/templates/_executor/selected_scope_test.go +186 -0
  143. package/dist/templates/_executor/status_disabled_test.go +33 -0
  144. package/dist/templates/_executor/store.go +4 -3
  145. package/dist/templates/_executor/supervise.go +109 -0
  146. package/dist/templates/_executor/supervise_test.go +130 -0
  147. package/dist/templates/_executor/task_race_review_test.go +1 -1
  148. package/dist/templates/_executor/tasks.go +52 -15
  149. package/dist/templates/_executor/tasks_dsm71_test.go +114 -0
  150. package/dist/templates/_executor/tasks_review_test.go +1 -1
  151. package/dist/templates/_executor/tasks_test.go +62 -5
  152. package/dist/templates/_executor/upgrade_watch_test.go +13 -5
  153. package/dist/templates/_executor/watch.go +8 -0
  154. package/dist/templates/_executor/watch_test.go +23 -2
  155. package/dist/templates/_executor/write_review_linux_test.go +4 -12
  156. package/dist/templates/_gateway/go.mod +2 -0
  157. package/dist/templates/_shared/AGENTS.md +129 -0
  158. package/dist/templates/binary/dsm-package.yaml +24 -0
  159. package/dist/templates/binary/i18n/messages/de.json +4 -0
  160. package/dist/templates/binary/i18n/messages/en.json +4 -0
  161. package/dist/templates/binary/i18n/messages/es.json +4 -0
  162. package/dist/templates/binary/i18n/messages/fr.json +4 -0
  163. package/dist/templates/binary/i18n/messages/it.json +4 -0
  164. package/dist/templates/binary/i18n/messages/ja.json +4 -0
  165. package/dist/templates/binary/i18n/messages/ko.json +4 -0
  166. package/dist/templates/binary/i18n/messages/zh-CN.json +4 -0
  167. package/dist/templates/binary/i18n/messages/zh-TW.json +4 -0
  168. package/dist/templates/binary/ui/app.js +19 -4
  169. package/dist/templates/native-authorization/AuthorizationGate.vue +5 -3
  170. package/dist/templates/native-authorization/i18n/de.json +1 -0
  171. package/dist/templates/native-authorization/i18n/en.json +1 -0
  172. package/dist/templates/native-authorization/i18n/es.json +2 -1
  173. package/dist/templates/native-authorization/i18n/fr.json +1 -0
  174. package/dist/templates/native-authorization/i18n/it.json +11 -10
  175. package/dist/templates/native-authorization/i18n/ja.json +1 -0
  176. package/dist/templates/native-authorization/i18n/ko.json +10 -9
  177. package/dist/templates/native-authorization/i18n/zh-CN.json +6 -5
  178. package/dist/templates/native-authorization/i18n/zh-TW.json +6 -5
  179. package/dist/templates/native-go/README.md +43 -10
  180. package/dist/templates/native-go/backend/cmd/app/main.go +27 -7
  181. package/dist/templates/native-go/backend/go.mod +1 -1
  182. package/dist/templates/native-go/backend/internal/api/entry_test.go +47 -0
  183. package/dist/templates/native-go/backend/internal/api/permissions_test.go +3 -3
  184. package/dist/templates/native-go/backend/internal/api/registry.go +11 -0
  185. package/dist/templates/native-go/backend/internal/api/sdk-permissions.json +14 -1
  186. package/dist/templates/native-go/backend/internal/api/server.go +18 -5
  187. package/dist/templates/native-go/backend/internal/app/delegate_config.go +57 -0
  188. package/dist/templates/native-go/backend/internal/app/delegate_config_test.go +28 -0
  189. package/dist/templates/native-go/backend/internal/app/portal.go +30 -0
  190. package/dist/templates/native-go/backend/internal/app/portal_test.go +55 -0
  191. package/dist/templates/native-go/backend/internal/app/routes.go +8 -2
  192. package/dist/templates/native-go/backend/internal/background/runner.go +1 -1
  193. package/dist/templates/native-go/backend/internal/background/store.go +16 -14
  194. package/dist/templates/native-go/backend/internal/dsm/admin.go +8 -2
  195. package/dist/templates/native-go/backend/internal/dsm/admin_linux.go +43 -13
  196. package/dist/templates/native-go/backend/internal/dsm/admin_linux_test.go +56 -0
  197. package/dist/templates/native-go/backend/internal/dsm/admin_other.go +4 -1
  198. package/dist/templates/native-go/backend/internal/dsm/apppriv.go +30 -0
  199. package/dist/templates/native-go/backend/internal/dsm/bridge_file.go +75 -0
  200. package/dist/templates/native-go/backend/internal/dsm/bridge_file_test.go +57 -0
  201. package/dist/templates/native-go/backend/internal/dsm/entry.go +177 -0
  202. package/dist/templates/native-go/backend/internal/dsm/entry_test.go +315 -0
  203. package/dist/templates/native-go/backend/internal/dsm/native/admin-armv7.elf +0 -0
  204. package/dist/templates/native-go/backend/internal/dsm/native/apppriv-aarch64.elf +0 -0
  205. package/dist/templates/native-go/backend/internal/dsm/native/apppriv-armv7.elf +0 -0
  206. package/dist/templates/native-go/backend/internal/dsm/native/apppriv-x86_64.elf +0 -0
  207. package/dist/templates/native-go/backend/internal/dsm/native/apppriv_check.c +33 -0
  208. package/dist/templates/native-go/backend/internal/dsm/native/build.sh +13 -4
  209. package/dist/templates/native-go/backend/internal/dsm/native/provenance.json +9 -3
  210. package/dist/templates/native-go/backend/internal/filestation/check_permission.go +71 -0
  211. package/dist/templates/native-go/backend/internal/filestation/check_permission_test.go +77 -0
  212. package/dist/templates/native-go/backend/internal/filestation/client.go +39 -3
  213. package/dist/templates/native-go/backend/internal/filestation/download_dsm71_test.go +82 -0
  214. package/dist/templates/native-go/backend/internal/filestation/sdk_policy_test.go +39 -0
  215. package/dist/templates/native-go/backend/internal/filestation/service.go +1 -1
  216. package/dist/templates/native-go/backend/internal/identity/README.md +5 -1
  217. package/dist/templates/native-go/backend/internal/identity/dsm.go +24 -5
  218. package/dist/templates/native-go/backend/internal/identity/http.go +1 -1
  219. package/dist/templates/native-go/backend/internal/identity/identity_test.go +48 -1
  220. package/dist/templates/native-go/backend/internal/identity/service.go +1 -1
  221. package/dist/templates/native-go/backend/internal/portal/portal.go +138 -0
  222. package/dist/templates/native-go/backend/internal/portal/portal_test.go +89 -0
  223. package/dist/templates/native-go/dsm-package.yaml +20 -1
  224. package/dist/templates/native-go/i18n/glossary.json +2 -1
  225. package/dist/templates/native-go/i18n/messages/de.json +1 -0
  226. package/dist/templates/native-go/i18n/messages/en.json +1 -0
  227. package/dist/templates/native-go/i18n/messages/es.json +1 -0
  228. package/dist/templates/native-go/i18n/messages/fr.json +1 -0
  229. package/dist/templates/native-go/i18n/messages/it.json +1 -0
  230. package/dist/templates/native-go/i18n/messages/ja.json +1 -0
  231. package/dist/templates/native-go/i18n/messages/ko.json +1 -0
  232. package/dist/templates/native-go/i18n/messages/zh-CN.json +1 -0
  233. package/dist/templates/native-go/i18n/messages/zh-TW.json +1 -0
  234. package/dist/templates/native-go/ui/app.css +10 -0
  235. package/dist/templates/native-go/ui/app.js +11 -1
  236. package/dist/templates/native-go-delegate/DELEGATE.md +126 -5
  237. package/dist/templates/native-go-delegate/backend/cmd/background-worker/main.go +7 -0
  238. package/dist/templates/native-go-delegate/backend/internal/app/delegate.go +11 -1
  239. package/dist/templates/native-go-delegate/backend/internal/app/delegate_routes_test.go +14 -0
  240. package/dist/templates/native-go-delegate/backend/internal/background/delegated_moves.go +270 -0
  241. package/dist/templates/native-go-delegate/backend/internal/delegate/admission_recovery_test.go +410 -0
  242. package/dist/templates/native-go-delegate/backend/internal/delegate/cancel_contract_test.go +95 -0
  243. package/dist/templates/native-go-delegate/backend/internal/delegate/client.go +8 -0
  244. package/dist/templates/native-go-delegate/backend/internal/delegate/destination.go +110 -0
  245. package/dist/templates/native-go-delegate/backend/internal/delegate/destination_state.go +117 -0
  246. package/dist/templates/native-go-delegate/backend/internal/delegate/destination_state_test.go +60 -0
  247. package/dist/templates/native-go-delegate/backend/internal/delegate/destination_test.go +116 -0
  248. package/dist/templates/native-go-delegate/backend/internal/delegate/example.go +81 -0
  249. package/dist/templates/native-go-delegate/backend/internal/delegate/example_test.go +91 -0
  250. package/dist/templates/native-go-delegate/backend/internal/delegate/executor_contract_test.go +511 -0
  251. package/dist/templates/native-go-delegate/backend/internal/delegate/files.go +1 -1
  252. package/dist/templates/native-go-delegate/backend/internal/delegate/long_running_routes.go +92 -0
  253. package/dist/templates/native-go-delegate/backend/internal/delegate/long_running_routes_test.go +99 -0
  254. package/dist/templates/native-go-delegate/backend/internal/delegate/move.go +348 -0
  255. package/dist/templates/native-go-delegate/backend/internal/delegate/move_test.go +351 -0
  256. package/dist/templates/native-go-delegate/backend/internal/delegate/operations_list.go +65 -0
  257. package/dist/templates/native-go-delegate/backend/internal/delegate/operations_list_test.go +114 -0
  258. package/dist/templates/native-go-delegate/backend/internal/delegate/retry_test.go +1 -1
  259. package/dist/templates/native-go-delegate/backend/internal/delegate/service.go +58 -17
  260. package/dist/templates/native-go-delegate/backend/internal/delegate/staging.go +121 -0
  261. package/dist/templates/native-go-delegate/backend/internal/delegate/status_disabled_test.go +51 -0
  262. package/dist/templates/native-go-delegate/backend/internal/delegate/testdata/executor_contract.txt +112 -0
  263. package/dist/templates/native-go-delegate/backend/internal/delegate/transient_contract_test.go +137 -0
  264. package/dist/templates/native-go-delegate/backend/internal/filestation/files.go +1 -31
  265. package/dist/templates/native-go-delegate/frontend/src/CapabilityPanels.vue +30 -3
  266. package/dist/templates/native-go-delegate/frontend/src/delegate/BackgroundSavePanel.vue +113 -0
  267. package/dist/templates/native-go-delegate/frontend/src/delegate/copy.ts +5 -6
  268. package/dist/templates/native-go-delegate/frontend/test/background-save.test.ts +121 -0
  269. package/dist/templates/native-go-delegate/frontend/test/delegate.test.ts +15 -0
  270. package/dist/templates/native-go-delegate/frontend/test/scope-settings.test.ts +49 -0
  271. package/dist/templates/native-go-delegate/test.sh +1 -0
  272. package/dist/templates/native-go-jobs/frontend/src/background/i18n/de.json +2 -2
  273. package/dist/templates/native-go-jobs/frontend/src/background/i18n/en.json +2 -2
  274. package/dist/templates/native-go-jobs/frontend/src/background/i18n/es.json +12 -12
  275. package/dist/templates/native-go-jobs/frontend/src/background/i18n/fr.json +4 -4
  276. package/dist/templates/native-go-jobs/frontend/src/background/i18n/it.json +17 -17
  277. package/dist/templates/native-go-jobs/frontend/src/background/i18n/ja.json +7 -7
  278. package/dist/templates/native-go-jobs/frontend/src/background/i18n/ko.json +15 -15
  279. package/dist/templates/native-go-jobs/frontend/src/background/i18n/zh-CN.json +3 -3
  280. package/dist/templates/native-go-jobs/frontend/src/background/i18n/zh-TW.json +2 -2
  281. package/dist/templates/native-go-jobs/frontend/test/background.test.ts +25 -28
  282. package/dist/templates/native-go-root-ops/backend/internal/app/executor.go +30 -2
  283. package/dist/templates/native-go-root-ops/backend/internal/app/executor_test.go +64 -0
  284. package/dist/templates/native-go-vue/README.md +4 -0
  285. package/dist/templates/native-go-vue/frontend/package-lock.json +4 -4
  286. package/dist/templates/native-go-vue/frontend/package.json +1 -1
  287. package/dist/templates/native-go-vue/frontend/src/App.vue +18 -13
  288. package/dist/templates/native-go-vue/frontend/src/context.ts +31 -0
  289. package/dist/templates/native-go-vue/frontend/src/delegate/ExecutorSettings.vue +54 -9
  290. package/dist/templates/native-go-vue/frontend/src/delegate/catalogs.ts +11 -0
  291. package/dist/templates/native-go-vue/frontend/src/delegate/copy.test.ts +12 -0
  292. package/dist/templates/native-go-vue/frontend/src/delegate/copy.ts +4 -4
  293. package/dist/templates/native-go-vue/frontend/src/delegate/executor-settings.test.ts +23 -0
  294. package/dist/templates/native-go-vue/frontend/src/delegate/executor-setup.ts +8 -2
  295. package/dist/templates/native-go-vue/frontend/src/delegate/facade.test.ts +100 -0
  296. package/dist/templates/native-go-vue/frontend/src/delegate/facade.ts +85 -0
  297. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/de.json +47 -0
  298. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/en.json +13 -2
  299. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/es.json +47 -0
  300. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/fr.json +47 -0
  301. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/it.json +47 -0
  302. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/ja.json +47 -0
  303. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/ko.json +47 -0
  304. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/de.json +42 -0
  305. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/en.json +42 -0
  306. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/es.json +42 -0
  307. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/fr.json +42 -0
  308. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/it.json +42 -0
  309. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/ja.json +42 -0
  310. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/ko.json +42 -0
  311. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/zh-CN.json +42 -0
  312. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/zh-TW.json +42 -0
  313. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/zh-CN.json +47 -0
  314. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/zh-TW.json +16 -5
  315. package/dist/templates/native-go-vue/frontend/src/delegate/long-running.ts +57 -0
  316. package/dist/templates/native-go-vue/frontend/src/delegate/save-copy.test.ts +12 -0
  317. package/dist/templates/native-go-vue/frontend/src/delegate/save-copy.ts +24 -0
  318. package/dist/templates/native-go-vue/frontend/src/delegate/scoped-picker.test.ts +12 -0
  319. package/dist/templates/native-go-vue/frontend/src/delegate/scoped-picker.ts +21 -0
  320. package/dist/templates/native-go-vue/frontend/src/files/files.test.ts +7 -0
  321. package/dist/templates/native-go-vue/frontend/src/i18n/de.json +20 -0
  322. package/dist/templates/native-go-vue/frontend/src/i18n/en.json +20 -0
  323. package/dist/templates/native-go-vue/frontend/src/i18n/es.json +20 -0
  324. package/dist/templates/native-go-vue/frontend/src/i18n/fr.json +20 -0
  325. package/dist/templates/native-go-vue/frontend/src/i18n/it.json +20 -0
  326. package/dist/templates/native-go-vue/frontend/src/i18n/ja.json +20 -0
  327. package/dist/templates/native-go-vue/frontend/src/i18n/ko.json +20 -0
  328. package/dist/templates/native-go-vue/frontend/src/i18n/zh-CN.json +20 -0
  329. package/dist/templates/native-go-vue/frontend/src/i18n/zh-TW.json +20 -0
  330. package/dist/templates/native-go-vue/frontend/src/i18n.ts +13 -0
  331. package/dist/templates/native-go-vue/frontend/src/identity/LoginPage.vue +16 -14
  332. package/dist/templates/native-go-vue/frontend/src/identity/i18n/de.json +27 -0
  333. package/dist/templates/native-go-vue/frontend/src/identity/i18n/en.json +27 -0
  334. package/dist/templates/native-go-vue/frontend/src/identity/i18n/es.json +27 -0
  335. package/dist/templates/native-go-vue/frontend/src/identity/i18n/fr.json +27 -0
  336. package/dist/templates/native-go-vue/frontend/src/identity/i18n/it.json +27 -0
  337. package/dist/templates/native-go-vue/frontend/src/identity/i18n/ja.json +27 -0
  338. package/dist/templates/native-go-vue/frontend/src/identity/i18n/ko.json +27 -0
  339. package/dist/templates/native-go-vue/frontend/src/identity/i18n/zh-CN.json +27 -0
  340. package/dist/templates/native-go-vue/frontend/src/identity/i18n/zh-TW.json +27 -0
  341. package/dist/templates/native-go-vue/frontend/src/identity/i18n.ts +14 -0
  342. package/dist/templates/native-go-vue/frontend/src/identity/session.test.ts +4 -0
  343. package/dist/templates/native-go-vue/frontend/src/identity/session.ts +9 -8
  344. package/dist/templates/native-go-vue/frontend/src/nas/NasPicker.vue +31 -12
  345. package/dist/templates/native-go-vue/frontend/src/nas/destination.test.ts +48 -0
  346. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/de.json +1 -1
  347. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/en.json +1 -1
  348. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/es.json +10 -10
  349. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/fr.json +1 -1
  350. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/it.json +12 -12
  351. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/ja.json +15 -15
  352. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/ko.json +12 -12
  353. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/zh-CN.json +1 -1
  354. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/zh-TW.json +1 -1
  355. package/dist/templates/native-go-vue/frontend/src/portal/PortalSettings.vue +39 -0
  356. package/dist/templates/native-go-vue/frontend/src/shell/i18n/fr.json +1 -1
  357. package/dist/templates/native-go-vue/frontend/src/shell/i18n/ja.json +1 -1
  358. package/dist/templates/native-go-vue/frontend/test/apps.test.ts +14 -0
  359. package/dist/templates/native-go-vue/frontend/test/portal-settings.test.ts +71 -0
  360. package/dist/templates/native-go-vue/frontend/test/shell-i18n.test.ts +50 -0
  361. package/package.json +5 -1
  362. package/schema/package-metadata.schema.json +101 -0
  363. package/schema/synology-app.schema.json +112 -0
  364. package/skills/SKILL.md +106 -4
  365. package/skills/reference/create.md +101 -2
  366. package/skills/reference/deploy.md +2 -2
  367. package/skills/reference/files.md +113 -2
  368. package/skills/reference/identity.md +70 -1
  369. package/skills/reference/portal.md +17 -0
  370. package/skills/reference/ui-vue.md +12 -0
  371. package/templates/_daemon/go.mod +1 -1
  372. package/templates/_daemon/main.go +6 -3
  373. package/templates/_daemon/main_test.go +82 -9
  374. package/templates/_daemon/testdata/child.go +3 -0
  375. package/templates/_executor/README.md +130 -16
  376. package/templates/_executor/anchor.go +156 -0
  377. package/templates/_executor/anchor_test.go +161 -0
  378. package/templates/_executor/apppriv_review_test.go +1 -1
  379. package/templates/_executor/cancel_contract_test.go +236 -0
  380. package/templates/_executor/copy.go +64 -0
  381. package/templates/_executor/copy_test.go +88 -0
  382. package/templates/_executor/digest_review_test.go +2 -2
  383. package/templates/_executor/dsm.go +63 -13
  384. package/templates/_executor/dsm_test.go +95 -1
  385. package/templates/_executor/executor.go +260 -49
  386. package/templates/_executor/executor_test.go +36 -6
  387. package/templates/_executor/go.mod +2 -0
  388. package/templates/_executor/identity.go +27 -1
  389. package/templates/_executor/identity_kernel_linux_test.go +60 -0
  390. package/templates/_executor/identity_linux.go +82 -0
  391. package/templates/_executor/identity_security_test.go +43 -0
  392. package/templates/_executor/internal/lifecycle/lifecycle.go +5 -0
  393. package/templates/_executor/internal/lifecycle/lifecycle_test.go +61 -3
  394. package/templates/_executor/internal/taskscript/boot.sh +9 -9
  395. package/templates/_executor/internal/taskscript/cmd/main.go +2 -2
  396. package/templates/_executor/internal/taskscript/control.sh +15 -10
  397. package/templates/_executor/internal/taskscript/tasks.go +5 -3
  398. package/templates/_executor/lifecycle_test.go +11 -0
  399. package/templates/_executor/link_linux.go +28 -0
  400. package/templates/_executor/long_running_test.go +530 -0
  401. package/templates/_executor/main.go +83 -25
  402. package/templates/_executor/managed.go +3 -3
  403. package/templates/_executor/managed_test.go +3 -3
  404. package/templates/_executor/move_linux.go +490 -0
  405. package/templates/_executor/move_linux_test.go +460 -0
  406. package/templates/_executor/move_validation.go +46 -0
  407. package/templates/_executor/move_validation_test.go +187 -0
  408. package/templates/_executor/operations.go +926 -0
  409. package/templates/_executor/path_test.go +18 -0
  410. package/templates/_executor/pid.go +37 -0
  411. package/templates/_executor/pid_test.go +113 -0
  412. package/templates/_executor/platform_linux.go +24 -173
  413. package/templates/_executor/platform_linux_test.go +9 -65
  414. package/templates/_executor/platform_other.go +38 -4
  415. package/templates/_executor/process.go +3 -0
  416. package/templates/_executor/purge_log.go +18 -0
  417. package/templates/_executor/records.go +242 -0
  418. package/templates/_executor/scope_cancel_contract_test.go +91 -0
  419. package/templates/_executor/scope_client.go +37 -0
  420. package/templates/_executor/scope_contract.go +12 -0
  421. package/templates/_executor/selected_scope.go +146 -0
  422. package/templates/_executor/selected_scope_test.go +186 -0
  423. package/templates/_executor/status_disabled_test.go +33 -0
  424. package/templates/_executor/store.go +4 -3
  425. package/templates/_executor/supervise.go +109 -0
  426. package/templates/_executor/supervise_test.go +130 -0
  427. package/templates/_executor/task_race_review_test.go +1 -1
  428. package/templates/_executor/tasks.go +52 -15
  429. package/templates/_executor/tasks_dsm71_test.go +114 -0
  430. package/templates/_executor/tasks_review_test.go +1 -1
  431. package/templates/_executor/tasks_test.go +62 -5
  432. package/templates/_executor/upgrade_watch_test.go +13 -5
  433. package/templates/_executor/watch.go +8 -0
  434. package/templates/_executor/watch_test.go +23 -2
  435. package/templates/_executor/write_review_linux_test.go +4 -12
  436. package/templates/_gateway/go.mod +2 -0
  437. package/templates/_shared/AGENTS.md +129 -0
  438. package/templates/binary/dsm-package.yaml +24 -0
  439. package/templates/binary/i18n/messages/de.json +4 -0
  440. package/templates/binary/i18n/messages/en.json +4 -0
  441. package/templates/binary/i18n/messages/es.json +4 -0
  442. package/templates/binary/i18n/messages/fr.json +4 -0
  443. package/templates/binary/i18n/messages/it.json +4 -0
  444. package/templates/binary/i18n/messages/ja.json +4 -0
  445. package/templates/binary/i18n/messages/ko.json +4 -0
  446. package/templates/binary/i18n/messages/zh-CN.json +4 -0
  447. package/templates/binary/i18n/messages/zh-TW.json +4 -0
  448. package/templates/binary/ui/app.js +19 -4
  449. package/templates/native-authorization/AuthorizationGate.vue +5 -3
  450. package/templates/native-authorization/i18n/de.json +1 -0
  451. package/templates/native-authorization/i18n/en.json +1 -0
  452. package/templates/native-authorization/i18n/es.json +2 -1
  453. package/templates/native-authorization/i18n/fr.json +1 -0
  454. package/templates/native-authorization/i18n/it.json +11 -10
  455. package/templates/native-authorization/i18n/ja.json +1 -0
  456. package/templates/native-authorization/i18n/ko.json +10 -9
  457. package/templates/native-authorization/i18n/zh-CN.json +6 -5
  458. package/templates/native-authorization/i18n/zh-TW.json +6 -5
  459. package/templates/native-go/README.md +43 -10
  460. package/templates/native-go/backend/cmd/app/main.go +27 -7
  461. package/templates/native-go/backend/go.mod +1 -1
  462. package/templates/native-go/backend/internal/api/entry_test.go +47 -0
  463. package/templates/native-go/backend/internal/api/permissions_test.go +3 -3
  464. package/templates/native-go/backend/internal/api/registry.go +11 -0
  465. package/templates/native-go/backend/internal/api/sdk-permissions.json +14 -1
  466. package/templates/native-go/backend/internal/api/server.go +18 -5
  467. package/templates/native-go/backend/internal/app/delegate_config.go +57 -0
  468. package/templates/native-go/backend/internal/app/delegate_config_test.go +28 -0
  469. package/templates/native-go/backend/internal/app/portal.go +30 -0
  470. package/templates/native-go/backend/internal/app/portal_test.go +55 -0
  471. package/templates/native-go/backend/internal/app/routes.go +8 -2
  472. package/templates/native-go/backend/internal/background/runner.go +1 -1
  473. package/templates/native-go/backend/internal/background/store.go +16 -14
  474. package/templates/native-go/backend/internal/dsm/admin.go +8 -2
  475. package/templates/native-go/backend/internal/dsm/admin_linux.go +43 -13
  476. package/templates/native-go/backend/internal/dsm/admin_linux_test.go +56 -0
  477. package/templates/native-go/backend/internal/dsm/admin_other.go +4 -1
  478. package/templates/native-go/backend/internal/dsm/apppriv.go +30 -0
  479. package/templates/native-go/backend/internal/dsm/bridge_file.go +75 -0
  480. package/templates/native-go/backend/internal/dsm/bridge_file_test.go +57 -0
  481. package/templates/native-go/backend/internal/dsm/entry.go +177 -0
  482. package/templates/native-go/backend/internal/dsm/entry_test.go +315 -0
  483. package/templates/native-go/backend/internal/dsm/native/admin-armv7.elf +0 -0
  484. package/templates/native-go/backend/internal/dsm/native/apppriv-aarch64.elf +0 -0
  485. package/templates/native-go/backend/internal/dsm/native/apppriv-armv7.elf +0 -0
  486. package/templates/native-go/backend/internal/dsm/native/apppriv-x86_64.elf +0 -0
  487. package/templates/native-go/backend/internal/dsm/native/apppriv_check.c +33 -0
  488. package/templates/native-go/backend/internal/dsm/native/build.sh +13 -4
  489. package/templates/native-go/backend/internal/dsm/native/provenance.json +9 -3
  490. package/templates/native-go/backend/internal/filestation/check_permission.go +71 -0
  491. package/templates/native-go/backend/internal/filestation/check_permission_test.go +77 -0
  492. package/templates/native-go/backend/internal/filestation/client.go +39 -3
  493. package/templates/native-go/backend/internal/filestation/download_dsm71_test.go +82 -0
  494. package/templates/native-go/backend/internal/filestation/sdk_policy_test.go +39 -0
  495. package/templates/native-go/backend/internal/filestation/service.go +1 -1
  496. package/templates/native-go/backend/internal/identity/README.md +5 -1
  497. package/templates/native-go/backend/internal/identity/dsm.go +24 -5
  498. package/templates/native-go/backend/internal/identity/http.go +1 -1
  499. package/templates/native-go/backend/internal/identity/identity_test.go +48 -1
  500. package/templates/native-go/backend/internal/identity/service.go +1 -1
  501. package/templates/native-go/backend/internal/portal/portal.go +138 -0
  502. package/templates/native-go/backend/internal/portal/portal_test.go +89 -0
  503. package/templates/native-go/dsm-package.yaml +20 -1
  504. package/templates/native-go/i18n/glossary.json +2 -1
  505. package/templates/native-go/i18n/messages/de.json +1 -0
  506. package/templates/native-go/i18n/messages/en.json +1 -0
  507. package/templates/native-go/i18n/messages/es.json +1 -0
  508. package/templates/native-go/i18n/messages/fr.json +1 -0
  509. package/templates/native-go/i18n/messages/it.json +1 -0
  510. package/templates/native-go/i18n/messages/ja.json +1 -0
  511. package/templates/native-go/i18n/messages/ko.json +1 -0
  512. package/templates/native-go/i18n/messages/zh-CN.json +1 -0
  513. package/templates/native-go/i18n/messages/zh-TW.json +1 -0
  514. package/templates/native-go/ui/app.css +10 -0
  515. package/templates/native-go/ui/app.js +11 -1
  516. package/templates/native-go-delegate/DELEGATE.md +126 -5
  517. package/templates/native-go-delegate/backend/cmd/background-worker/main.go +7 -0
  518. package/templates/native-go-delegate/backend/internal/app/delegate.go +11 -1
  519. package/templates/native-go-delegate/backend/internal/app/delegate_routes_test.go +14 -0
  520. package/templates/native-go-delegate/backend/internal/background/delegated_moves.go +270 -0
  521. package/templates/native-go-delegate/backend/internal/delegate/admission_recovery_test.go +410 -0
  522. package/templates/native-go-delegate/backend/internal/delegate/cancel_contract_test.go +95 -0
  523. package/templates/native-go-delegate/backend/internal/delegate/client.go +8 -0
  524. package/templates/native-go-delegate/backend/internal/delegate/destination.go +110 -0
  525. package/templates/native-go-delegate/backend/internal/delegate/destination_state.go +117 -0
  526. package/templates/native-go-delegate/backend/internal/delegate/destination_state_test.go +60 -0
  527. package/templates/native-go-delegate/backend/internal/delegate/destination_test.go +116 -0
  528. package/templates/native-go-delegate/backend/internal/delegate/example.go +81 -0
  529. package/templates/native-go-delegate/backend/internal/delegate/example_test.go +91 -0
  530. package/templates/native-go-delegate/backend/internal/delegate/executor_contract_test.go +511 -0
  531. package/templates/native-go-delegate/backend/internal/delegate/files.go +1 -1
  532. package/templates/native-go-delegate/backend/internal/delegate/long_running_routes.go +92 -0
  533. package/templates/native-go-delegate/backend/internal/delegate/long_running_routes_test.go +99 -0
  534. package/templates/native-go-delegate/backend/internal/delegate/move.go +348 -0
  535. package/templates/native-go-delegate/backend/internal/delegate/move_test.go +351 -0
  536. package/templates/native-go-delegate/backend/internal/delegate/operations_list.go +65 -0
  537. package/templates/native-go-delegate/backend/internal/delegate/operations_list_test.go +114 -0
  538. package/templates/native-go-delegate/backend/internal/delegate/retry_test.go +1 -1
  539. package/templates/native-go-delegate/backend/internal/delegate/service.go +58 -17
  540. package/templates/native-go-delegate/backend/internal/delegate/staging.go +121 -0
  541. package/templates/native-go-delegate/backend/internal/delegate/status_disabled_test.go +51 -0
  542. package/templates/native-go-delegate/backend/internal/delegate/testdata/executor_contract.txt +112 -0
  543. package/templates/native-go-delegate/backend/internal/delegate/transient_contract_test.go +137 -0
  544. package/templates/native-go-delegate/backend/internal/filestation/files.go +1 -31
  545. package/templates/native-go-delegate/frontend/src/CapabilityPanels.vue +30 -3
  546. package/templates/native-go-delegate/frontend/src/delegate/BackgroundSavePanel.vue +113 -0
  547. package/templates/native-go-delegate/frontend/src/delegate/copy.ts +5 -6
  548. package/templates/native-go-delegate/frontend/test/background-save.test.ts +121 -0
  549. package/templates/native-go-delegate/frontend/test/delegate.test.ts +15 -0
  550. package/templates/native-go-delegate/frontend/test/scope-settings.test.ts +49 -0
  551. package/templates/native-go-delegate/test.sh +1 -0
  552. package/templates/native-go-jobs/frontend/src/background/i18n/de.json +2 -2
  553. package/templates/native-go-jobs/frontend/src/background/i18n/en.json +2 -2
  554. package/templates/native-go-jobs/frontend/src/background/i18n/es.json +12 -12
  555. package/templates/native-go-jobs/frontend/src/background/i18n/fr.json +4 -4
  556. package/templates/native-go-jobs/frontend/src/background/i18n/it.json +17 -17
  557. package/templates/native-go-jobs/frontend/src/background/i18n/ja.json +7 -7
  558. package/templates/native-go-jobs/frontend/src/background/i18n/ko.json +15 -15
  559. package/templates/native-go-jobs/frontend/src/background/i18n/zh-CN.json +3 -3
  560. package/templates/native-go-jobs/frontend/src/background/i18n/zh-TW.json +2 -2
  561. package/templates/native-go-jobs/frontend/test/background.test.ts +25 -28
  562. package/templates/native-go-root-ops/backend/internal/app/executor.go +30 -2
  563. package/templates/native-go-root-ops/backend/internal/app/executor_test.go +64 -0
  564. package/templates/native-go-vue/README.md +4 -0
  565. package/templates/native-go-vue/frontend/package-lock.json +4 -4
  566. package/templates/native-go-vue/frontend/package.json +1 -1
  567. package/templates/native-go-vue/frontend/src/App.vue +18 -13
  568. package/templates/native-go-vue/frontend/src/context.ts +31 -0
  569. package/templates/native-go-vue/frontend/src/delegate/ExecutorSettings.vue +54 -9
  570. package/templates/native-go-vue/frontend/src/delegate/catalogs.ts +11 -0
  571. package/templates/native-go-vue/frontend/src/delegate/copy.test.ts +12 -0
  572. package/templates/native-go-vue/frontend/src/delegate/copy.ts +4 -4
  573. package/templates/native-go-vue/frontend/src/delegate/executor-settings.test.ts +23 -0
  574. package/templates/native-go-vue/frontend/src/delegate/executor-setup.ts +8 -2
  575. package/templates/native-go-vue/frontend/src/delegate/facade.test.ts +100 -0
  576. package/templates/native-go-vue/frontend/src/delegate/facade.ts +85 -0
  577. package/templates/native-go-vue/frontend/src/delegate/i18n/de.json +47 -0
  578. package/templates/native-go-vue/frontend/src/delegate/i18n/en.json +13 -2
  579. package/templates/native-go-vue/frontend/src/delegate/i18n/es.json +47 -0
  580. package/templates/native-go-vue/frontend/src/delegate/i18n/fr.json +47 -0
  581. package/templates/native-go-vue/frontend/src/delegate/i18n/it.json +47 -0
  582. package/templates/native-go-vue/frontend/src/delegate/i18n/ja.json +47 -0
  583. package/templates/native-go-vue/frontend/src/delegate/i18n/ko.json +47 -0
  584. package/templates/native-go-vue/frontend/src/delegate/i18n/save/de.json +42 -0
  585. package/templates/native-go-vue/frontend/src/delegate/i18n/save/en.json +42 -0
  586. package/templates/native-go-vue/frontend/src/delegate/i18n/save/es.json +42 -0
  587. package/templates/native-go-vue/frontend/src/delegate/i18n/save/fr.json +42 -0
  588. package/templates/native-go-vue/frontend/src/delegate/i18n/save/it.json +42 -0
  589. package/templates/native-go-vue/frontend/src/delegate/i18n/save/ja.json +42 -0
  590. package/templates/native-go-vue/frontend/src/delegate/i18n/save/ko.json +42 -0
  591. package/templates/native-go-vue/frontend/src/delegate/i18n/save/zh-CN.json +42 -0
  592. package/templates/native-go-vue/frontend/src/delegate/i18n/save/zh-TW.json +42 -0
  593. package/templates/native-go-vue/frontend/src/delegate/i18n/zh-CN.json +47 -0
  594. package/templates/native-go-vue/frontend/src/delegate/i18n/zh-TW.json +16 -5
  595. package/templates/native-go-vue/frontend/src/delegate/long-running.ts +57 -0
  596. package/templates/native-go-vue/frontend/src/delegate/save-copy.test.ts +12 -0
  597. package/templates/native-go-vue/frontend/src/delegate/save-copy.ts +24 -0
  598. package/templates/native-go-vue/frontend/src/delegate/scoped-picker.test.ts +12 -0
  599. package/templates/native-go-vue/frontend/src/delegate/scoped-picker.ts +21 -0
  600. package/templates/native-go-vue/frontend/src/files/files.test.ts +7 -0
  601. package/templates/native-go-vue/frontend/src/i18n/de.json +20 -0
  602. package/templates/native-go-vue/frontend/src/i18n/en.json +20 -0
  603. package/templates/native-go-vue/frontend/src/i18n/es.json +20 -0
  604. package/templates/native-go-vue/frontend/src/i18n/fr.json +20 -0
  605. package/templates/native-go-vue/frontend/src/i18n/it.json +20 -0
  606. package/templates/native-go-vue/frontend/src/i18n/ja.json +20 -0
  607. package/templates/native-go-vue/frontend/src/i18n/ko.json +20 -0
  608. package/templates/native-go-vue/frontend/src/i18n/zh-CN.json +20 -0
  609. package/templates/native-go-vue/frontend/src/i18n/zh-TW.json +20 -0
  610. package/templates/native-go-vue/frontend/src/i18n.ts +13 -0
  611. package/templates/native-go-vue/frontend/src/identity/LoginPage.vue +16 -14
  612. package/templates/native-go-vue/frontend/src/identity/i18n/de.json +27 -0
  613. package/templates/native-go-vue/frontend/src/identity/i18n/en.json +27 -0
  614. package/templates/native-go-vue/frontend/src/identity/i18n/es.json +27 -0
  615. package/templates/native-go-vue/frontend/src/identity/i18n/fr.json +27 -0
  616. package/templates/native-go-vue/frontend/src/identity/i18n/it.json +27 -0
  617. package/templates/native-go-vue/frontend/src/identity/i18n/ja.json +27 -0
  618. package/templates/native-go-vue/frontend/src/identity/i18n/ko.json +27 -0
  619. package/templates/native-go-vue/frontend/src/identity/i18n/zh-CN.json +27 -0
  620. package/templates/native-go-vue/frontend/src/identity/i18n/zh-TW.json +27 -0
  621. package/templates/native-go-vue/frontend/src/identity/i18n.ts +14 -0
  622. package/templates/native-go-vue/frontend/src/identity/session.test.ts +4 -0
  623. package/templates/native-go-vue/frontend/src/identity/session.ts +9 -8
  624. package/templates/native-go-vue/frontend/src/nas/NasPicker.vue +31 -12
  625. package/templates/native-go-vue/frontend/src/nas/destination.test.ts +48 -0
  626. package/templates/native-go-vue/frontend/src/nas/i18n/files/de.json +1 -1
  627. package/templates/native-go-vue/frontend/src/nas/i18n/files/en.json +1 -1
  628. package/templates/native-go-vue/frontend/src/nas/i18n/files/es.json +10 -10
  629. package/templates/native-go-vue/frontend/src/nas/i18n/files/fr.json +1 -1
  630. package/templates/native-go-vue/frontend/src/nas/i18n/files/it.json +12 -12
  631. package/templates/native-go-vue/frontend/src/nas/i18n/files/ja.json +15 -15
  632. package/templates/native-go-vue/frontend/src/nas/i18n/files/ko.json +12 -12
  633. package/templates/native-go-vue/frontend/src/nas/i18n/files/zh-CN.json +1 -1
  634. package/templates/native-go-vue/frontend/src/nas/i18n/files/zh-TW.json +1 -1
  635. package/templates/native-go-vue/frontend/src/portal/PortalSettings.vue +39 -0
  636. package/templates/native-go-vue/frontend/src/shell/i18n/fr.json +1 -1
  637. package/templates/native-go-vue/frontend/src/shell/i18n/ja.json +1 -1
  638. package/templates/native-go-vue/frontend/test/apps.test.ts +14 -0
  639. package/templates/native-go-vue/frontend/test/portal-settings.test.ts +71 -0
  640. package/templates/native-go-vue/frontend/test/shell-i18n.test.ts +50 -0
@@ -4,9 +4,11 @@ import { contractSpan, makeError } from "../errors.js";
4
4
  import { collectInstallParameters, getValuePosition, stringViolations, } from "./load.js";
5
5
  import { validateContractSchema } from "./schema-validate.js";
6
6
  import { DSM_GROUP_NAME, isWebAccessMode, isWebLaunchMode, readWebIntegration } from "./web-launch.js";
7
+ import { contractPortalSupported, readPortalDeclaration } from "../portal/alias.js";
7
8
  import { loadCompose } from "../compose/analyze.js";
8
9
  import { collectPosixAllSharesParameters, isPosixAllSharesType, validatePosixAllSharesSources, } from "./posix-all-shares.js";
9
10
  import { getErrorCode } from "../error-registry.js";
11
+ import { isDsmAtLeast, PORTAL_MIN_DSM, portalMinDsmMessage } from "../build-spk/dsm-version.js";
10
12
  import { FORMAL_PACKAGE_IDENTITY_MAX_LENGTH, PACKAGE_IDENTITY_MAX_LENGTH, } from "../deploy/identity-shared.js";
11
13
  /** DSM 7.4 Package Center rejects a longer package identity outright. */
12
14
  const DSM_PACKAGE_IDENTITY_MAX = 32;
@@ -53,6 +55,7 @@ export function validateContract(parsed, contractFile) {
53
55
  errors.push(...validatePosixAllShares(parsed, contractFile));
54
56
  errors.push(...validateWebLaunch(parsed, contractFile));
55
57
  errors.push(...validateWebAccess(parsed, contractFile));
58
+ errors.push(...validateWebPortal(parsed, contractFile));
56
59
  return errors;
57
60
  }
58
61
  function validatePosixAllShares(parsed, contractFile) {
@@ -119,6 +122,33 @@ function validateWebAccess(parsed, contractFile) {
119
122
  }
120
123
  return [];
121
124
  }
125
+ function validateWebPortal(parsed, contractFile) {
126
+ const { contract, doc } = parsed;
127
+ const portal = readWebIntegration(contract)?.portal;
128
+ if (portal === undefined) {
129
+ return [];
130
+ }
131
+ const pos = getValuePosition(doc, ["integration", "web", "portal"]) ?? { line: 1, column: 1 };
132
+ const at = contractSpan(contractFile, pos.line, pos.column, "integration.web.portal");
133
+ if (!contractPortalSupported(contract)) {
134
+ return [
135
+ makeError("CONTRACT_PORTAL_UNSUPPORTED", at, "Application Portal 只支援以 DSM 視窗開啟、經 DSM 登入閘道的網頁 App。", "請使用 adminport、launch: dsm-window 與非 public 的 access,或移除 integration.web.portal。public App 已有同名的 Web Station 網址。"),
136
+ ];
137
+ }
138
+ if (!readPortalDeclaration(portal, String(contract.package ?? ""))) {
139
+ return [
140
+ makeError("CONTRACT_PORTAL_INVALID", at, "integration.web.portal 必須是 {} 或 { alias },alias 為 1–64 個小寫英數字或 -,且不是 DSM 保留路徑。", "請省略 alias 以使用套件名稱,或改成例如 alias: my-app。"),
141
+ ];
142
+ }
143
+ const osMinVer = contract.os_min_ver;
144
+ if (typeof osMinVer === "string" && FULL_OS_MIN_VER.test(osMinVer) && !isDsmAtLeast(osMinVer, PORTAL_MIN_DSM)) {
145
+ return [
146
+ makeError("CONTRACT_PORTAL_MIN_DSM", at, portalMinDsmMessage(osMinVer, "integration.web.portal"), `請把 os_min_ver 改成 "${PORTAL_MIN_DSM}" 或更新,或移除 integration.web.portal。`),
147
+ ];
148
+ }
149
+ return [];
150
+ }
151
+ const FULL_OS_MIN_VER = /^7\.\d+(\.\d+)?-\d+$/;
122
152
  function validateDeveloperString(value, contractFile, path, pos) {
123
153
  const errors = [];
124
154
  const violations = stringViolations(value);
@@ -1,5 +1,5 @@
1
1
  import type { CommandRunner } from "../standalone/build.js";
2
- import type { NativeArchFamily } from "../build-spk/dsm-arch.js";
2
+ import { type NativeArchFamily } from "../build-spk/dsm-arch.js";
3
3
  import type { ProjectRoot } from "../discovery.js";
4
4
  import type { NasHost } from "../host/types.js";
5
5
  import { resolveDeploySpkVersion } from "./spk-version.js";
@@ -1,4 +1,5 @@
1
1
  import { buildSpk } from "../build-spk/generator.js";
2
+ import { CONTAINER_ARCH_FAMILIES, isContainerArchFamily } from "../build-spk/dsm-arch.js";
2
3
  import { loadContract } from "../contract/load.js";
3
4
  import { usesAuthGateway } from "../contract/web-launch.js";
4
5
  import { findUnsupportedInstallTypes } from "../contract/unsupported-types.js";
@@ -174,6 +175,13 @@ export async function deployProject(options) {
174
175
  };
175
176
  }
176
177
  }
178
+ if (archFamily !== undefined && !isContainerArchFamily(archFamily)) {
179
+ return {
180
+ ok: false,
181
+ code: "CONTAINER_ARCH_UNSUPPORTED",
182
+ message: `Container Manager App 只支援 ${CONTAINER_ARCH_FAMILIES.join("、")};DSM 不為 ${archFamily} 提供 Container Manager。`,
183
+ };
184
+ }
177
185
  const build = await buildSpk({
178
186
  project: options.project,
179
187
  packageIdentity: identity.packageId,
@@ -0,0 +1,17 @@
1
+ import type { StandaloneManifest } from "../standalone/manifest.js";
2
+ export type NativeInstallValuesResult = {
3
+ ok: true;
4
+ extraValues: Record<string, string>;
5
+ } | {
6
+ ok: false;
7
+ code: string;
8
+ message: string;
9
+ };
10
+ /**
11
+ * Install wizard values for a native-go/binary deploy. Only an install-selected
12
+ * delegate asks the wizard for anything; preinst refuses an empty selection on
13
+ * the first install, so refuse it here before building or uploading.
14
+ */
15
+ export declare function resolveNativeInstallValues(manifest: StandaloneManifest, provided: Record<string, string>, state: {
16
+ installed: boolean;
17
+ }): NativeInstallValuesResult;
@@ -0,0 +1,32 @@
1
+ const USAGE = "synopkgland deploy --param delegate_share=<shared folder>,或 --param delegate_home=true";
2
+ /** Mirrors the preinst draft check in build-spk/delegate-scope.ts. */
3
+ function validShareName(name) {
4
+ return (name !== "" && name !== "." && !name.includes("..") &&
5
+ !/[/\\:"%\x00-\x1f\x7f]/.test(name) &&
6
+ !/^homes?$/i.test(name) && name.trim() === name && name.length <= 256);
7
+ }
8
+ /**
9
+ * Install wizard values for a native-go/binary deploy. Only an install-selected
10
+ * delegate asks the wizard for anything; preinst refuses an empty selection on
11
+ * the first install, so refuse it here before building or uploading.
12
+ */
13
+ export function resolveNativeInstallValues(manifest, provided, state) {
14
+ const fail = (code, message) => ({ ok: false, code, message });
15
+ const selected = manifest.capabilities.delegate?.scope === "install-selected";
16
+ const names = Object.keys(provided);
17
+ if (!selected && names.length)
18
+ return fail("DEPLOY_PARAM_UNDECLARED", `${manifest.package} has no install wizard values; remove --param ${names[0]}.`);
19
+ const unknown = names.find((name) => name !== "delegate_share" && name !== "delegate_home");
20
+ if (unknown)
21
+ return fail("DEPLOY_PARAM_UNDECLARED", `--param ${unknown} is not an install wizard value. Use: ${USAGE}.`);
22
+ const { delegate_share: share, delegate_home: home } = provided;
23
+ if (home !== undefined && home !== "true" && home !== "false")
24
+ return fail("DEPLOY_PARAM_TYPE_INVALID", "--param delegate_home must be true or false.");
25
+ if (share !== undefined && !validShareName(share))
26
+ return fail("DEPLOY_PARAM_TYPE_INVALID", `--param delegate_share must be one Shared Folder name, not a path, home or homes.`);
27
+ if (share !== undefined && home === "true")
28
+ return fail("DEPLOY_PARAM_TYPE_INVALID", "Choose either --param delegate_share or --param delegate_home=true, not both.");
29
+ if (selected && !state.installed && share === undefined && home !== "true")
30
+ return fail("DEPLOY_PARAM_REQUIRED", `The first install of ${manifest.package} must select the delegate scope: ${USAGE}.`);
31
+ return { ok: true, extraValues: { ...provided } };
32
+ }
@@ -1,8 +1,9 @@
1
+ import { type CommandRunner } from "../standalone/build.js";
1
2
  import type { NativeArchFamily } from "../build-spk/dsm-arch.js";
2
3
  import type { NasHost } from "../host/types.js";
3
4
  export interface DeploymentPlan {
4
5
  root: string;
5
- kind: "native-go" | "binary" | "container";
6
+ kind: "native-go" | "binary" | "native-layout" | "container";
6
7
  packageId: string;
7
8
  version: string;
8
9
  arch?: NativeArchFamily;
@@ -15,4 +16,7 @@ export declare function planDeployment(root: string, options?: {
15
16
  arch?: NativeArchFamily;
16
17
  dev?: boolean;
17
18
  }): DeploymentPlan;
18
- export declare function deployStandalone(plan: DeploymentPlan, host: NasHost): Promise<string>;
19
+ export declare function deployStandalone(plan: DeploymentPlan, host: NasHost, options?: {
20
+ params?: Record<string, string>;
21
+ run?: CommandRunner;
22
+ }): Promise<string>;
@@ -3,14 +3,18 @@ import { loadContract } from "../contract/load.js";
3
3
  import { validateProject } from "../validate.js";
4
4
  import { findStandaloneRoot, loadStandaloneManifest, } from "../standalone/manifest.js";
5
5
  import { buildStandalone } from "../standalone/build.js";
6
+ import { buildNativeLayout, isNativeLayout, loadNativeLayout } from "../standalone/native-layout.js";
6
7
  import { resolveDeployIdentity } from "./identity.js";
7
8
  import { nextDeployVersion } from "./spk-version.js";
9
+ import { resolveNativeInstallValues } from "./native-install-values.js";
8
10
  function fail(code, message) {
9
11
  return Object.assign(new Error(`[${code}] ${message}`), { code });
10
12
  }
11
13
  /** Purely local planning: no credentials, network, build or installation. */
12
14
  export function planDeployment(root, options = {}) {
13
15
  const standalone = findStandaloneRoot(root);
16
+ if (standalone && isNativeLayout(standalone))
17
+ return planNativeLayout(standalone, options);
14
18
  if (standalone) {
15
19
  const validation = validateProject(findProjectRoot(standalone));
16
20
  if (!validation.ok)
@@ -22,7 +26,7 @@ export function planDeployment(root, options = {}) {
22
26
  if (options.dev)
23
27
  throw fail("DEVELOPMENT_INSTANCE_UNSUPPORTED", "--dev is not supported for native-go/binary; choose a distinct package name at init");
24
28
  if (options.arch && !m.arches.includes(options.arch))
25
- throw fail("STANDALONE_ARCH_NOT_DECLARED", `Architecture not declared: ${options.arch}`);
29
+ throw fail("STANDALONE_ARCH_NOT_DECLARED", `Architecture not declared: ${options.arch}; add it to dsm-package.yaml arches to deploy it`);
26
30
  return {
27
31
  root: standalone,
28
32
  kind: m.backend.kind === "go" ? "native-go" : "binary",
@@ -33,7 +37,7 @@ export function planDeployment(root, options = {}) {
33
37
  transport: "dsm-local-spk",
34
38
  notes: m.capabilities.rootOps || m.capabilities.delegate
35
39
  ? [
36
- "Installation does not mean ready. Approve boot and control tasks once in the App window; executor or policy digest changes require approval again.",
40
+ "Installation does not mean ready. Approve boot and control tasks once in the App window. An executor-only upgrade stays ready without approval (INFO anchors the executor digest); a policy digest change requires approval again.",
37
41
  ]
38
42
  : [],
39
43
  };
@@ -59,7 +63,56 @@ export function planDeployment(root, options = {}) {
59
63
  ],
60
64
  };
61
65
  }
62
- export async function deployStandalone(plan, host) {
66
+ /** DSM reports the aarch64 family; a native layout may name it armv8. */
67
+ function layoutArchFor(arches, family) {
68
+ const names = family === "aarch64" ? ["aarch64", "armv8"] : [family];
69
+ return names.find((name) => arches.includes(name));
70
+ }
71
+ function loadLayout(root) {
72
+ const loaded = loadNativeLayout(root);
73
+ if (!loaded.ok)
74
+ throw fail(loaded.errors[0].code, loaded.errors.map((e) => e.message).join("\n"));
75
+ return loaded.manifest;
76
+ }
77
+ function planNativeLayout(root, options) {
78
+ const m = loadLayout(root);
79
+ if (options.dev)
80
+ throw fail("DEVELOPMENT_INSTANCE_UNSUPPORTED", "--dev is not supported for a native layout; choose a distinct package name");
81
+ if (options.arch && !layoutArchFor(m.arches, options.arch))
82
+ throw fail("STANDALONE_ARCH_NOT_DECLARED", `Architecture not declared: ${options.arch}; add it to dsm-package.yaml arches to deploy it`);
83
+ return {
84
+ root,
85
+ kind: "native-layout",
86
+ packageId: m.package,
87
+ version: `${m.version}-${String(m.build).padStart(4, "0")}`,
88
+ arch: options.arch,
89
+ capabilities: [],
90
+ transport: "dsm-local-spk",
91
+ notes: [],
92
+ };
93
+ }
94
+ async function buildForDeploy(plan, arch, installed, options) {
95
+ if (plan.kind === "native-layout") {
96
+ const m = loadLayout(plan.root);
97
+ const layoutArch = layoutArchFor(m.arches, arch);
98
+ if (!layoutArch)
99
+ throw fail("STANDALONE_ARCH_NOT_DECLARED", `Architecture not declared: ${arch}; add it to dsm-package.yaml arches to deploy it`);
100
+ const name = Object.keys(options.params ?? {})[0];
101
+ if (name)
102
+ throw fail("DEPLOY_PARAM_UNDECLARED", `${m.package} has no install wizard values; remove --param ${name}.`);
103
+ const { outputs } = await buildNativeLayout({ root: plan.root, arches: [layoutArch], run: options.run });
104
+ return { outputs, extraValues: {} };
105
+ }
106
+ const loaded = loadStandaloneManifest(plan.root);
107
+ if (!loaded.ok)
108
+ throw fail(loaded.errors[0].code, loaded.errors.map((e) => e.message).join("\n"));
109
+ const values = resolveNativeInstallValues(loaded.manifest, options.params ?? {}, { installed });
110
+ if (!values.ok)
111
+ throw fail(values.code, values.message);
112
+ const { outputs } = await buildStandalone({ root: plan.root, arches: [arch], run: options.run });
113
+ return { outputs, extraValues: values.extraValues };
114
+ }
115
+ export async function deployStandalone(plan, host, options = {}) {
63
116
  if (plan.kind === "container")
64
117
  throw fail("DEPLOY_PLAN_INVALID", "Expected native-go or binary deployment plan");
65
118
  const arch = plan.arch ?? (await host.getArchFamily?.());
@@ -70,16 +123,14 @@ export async function deployStandalone(plan, host) {
70
123
  nextDeployVersion(plan.version, installed) !== plan.version) {
71
124
  throw fail("DEPLOY_VERSION_INVALID", `Increase dsm-package.yaml version/build above installed ${installed}`);
72
125
  }
73
- const { outputs } = await buildStandalone({
74
- root: plan.root,
75
- arches: [arch],
76
- });
126
+ const { outputs, extraValues } = await buildForDeploy(plan, arch, Boolean(installed), options);
77
127
  if (outputs.length !== 1)
78
128
  throw fail("DEPLOY_BUILD_OUTPUT_INVALID", "Expected one SPK");
79
129
  await host.installFromLocalSpk({
80
130
  packageId: plan.packageId,
81
131
  version: plan.version,
82
132
  spkPath: outputs[0],
133
+ extraValues,
83
134
  });
84
135
  return outputs[0];
85
136
  }
@@ -18,7 +18,7 @@ export function nextDeployVersion(version, installed) {
18
18
  break;
19
19
  }
20
20
  if (order < 0)
21
- throw new Error(`Refusing downgrade from ${installed} to ${version}`);
21
+ throw new Error(`[DEPLOY_VERSION_INVALID] Refusing downgrade from ${installed} to ${version}`);
22
22
  if (order === 0)
23
23
  build = Math.max(build, Number(previous[2] ?? 0) + 1);
24
24
  }
@@ -1,8 +1,8 @@
1
1
  export const ERROR_REGISTRY = {
2
2
  "NATIVE_LAYOUT_INVALID": {
3
3
  code: "NATIVE_LAYOUT_INVALID",
4
- description: "Native layout manifest, hook, toolkit or artifact violates the package-only contract.",
5
- suggestion: "Use schema 2 with backend.kind: native; check paths, ELF linkage and checksum pins."
4
+ description: "native layout 的 manifest、hook、toolkit 或產物違反 package-only 契約。",
5
+ suggestion: "使用 schema 2 與 backend.kind: native;檢查路徑、ELF 連結與 checksum pin。"
6
6
  },
7
7
  "COMPOSE_ROUTE_UNSUPPORTED": {
8
8
  "code": "COMPOSE_ROUTE_UNSUPPORTED",
@@ -59,6 +59,16 @@ export const ERROR_REGISTRY = {
59
59
  "description": "Headless App 不需要宣告 Web Launch Mode。",
60
60
  "suggestion": "請省略 integration.web.launch,或補上對應 Compose published port 的 adminport。"
61
61
  },
62
+ "CONTRACT_PORTAL_INVALID": {
63
+ "code": "CONTRACT_PORTAL_INVALID",
64
+ "description": "integration.web.portal 的格式或 alias 不正確。",
65
+ "suggestion": "請使用 {} 或 { alias: my-app };alias 為 1–64 個小寫英數字或 -,且不是 DSM 保留路徑。"
66
+ },
67
+ "CONTRACT_PORTAL_UNSUPPORTED": {
68
+ "code": "CONTRACT_PORTAL_UNSUPPORTED",
69
+ "description": "這個 App 的網頁入口無法加入 DSM Application Portal。",
70
+ "suggestion": "Application Portal 需要 adminport、launch: dsm-window 與非 public 的 access;否則請移除 integration.web.portal。"
71
+ },
62
72
  "CONTRACT_ACCESS_INVALID": {
63
73
  "code": "CONTRACT_ACCESS_INVALID",
64
74
  "description": "integration.web.access 模式無效。",
@@ -87,12 +97,12 @@ export const ERROR_REGISTRY = {
87
97
  "GATEWAY_GO_MISSING": {
88
98
  "code": "GATEWAY_GO_MISSING",
89
99
  "description": "建置 DSM 驗證閘道需要 Go,但找不到 go 指令。",
90
- "suggestion": "請安裝 Go 1.24 以上版本(https://go.dev/dl/),或在 integration.web.access 明確選 public。"
100
+ "suggestion": "請安裝 Go 1.21 以上版本(https://go.dev/dl/,建置時固定使用 go1.26.9),或在 integration.web.access 明確選 public。"
91
101
  },
92
102
  "GATEWAY_BUILD_FAILED": {
93
103
  "code": "GATEWAY_BUILD_FAILED",
94
104
  "description": "DSM 驗證閘道建置失敗或產出不是對應架構的靜態 ELF。",
95
- "suggestion": "請查看 go build 輸出;確認 Go 版本 1.24 以上且 templates/_gateway 未被修改。"
105
+ "suggestion": "請查看 go build 輸出;閘道固定以 go1.26.9 建置,離線時請安裝 go1.26.9 或讓 GOPROXY 可提供 golang.org/toolchain,並確認 templates/_gateway 未被修改。"
96
106
  },
97
107
  "CONTRACT_INVALID_STRING": {
98
108
  "code": "CONTRACT_INVALID_STRING",
@@ -116,13 +126,13 @@ export const ERROR_REGISTRY = {
116
126
  },
117
127
  "CONTRACT_SECRET_UNSUPPORTED": {
118
128
  "code": "CONTRACT_SECRET_UNSUPPORTED",
119
- "description": "install.<NAME>.type: secret 目前沒有可用的安裝路徑。2026-08-27 於 vt-nas 實測:無論是否在 Compose 引用,Package Center 安裝都以 DSM broken/150 結束且不建立 Container Manager project(同一台 NAS 上無參數的對照套件正常安裝)。",
120
- "suggestion": "請改用 type: string(非敏感值),或把敏感值改成 App 啟動後自行取得/由管理員放進 ${SYNO_APP_SECRETS_DIR} 的檔案。secret 型別要能用,需要先讓 DSM worker 的失敗原因可觀測(見 STATUS.md A22/A45)。"
129
+ "description": "install.<NAME>.type: secret 目前沒有可用的安裝路徑:無論是否在 Compose 引用,Package Center 安裝都以 DSM broken/150 結束,且不建立 Container Manager project。",
130
+ "suggestion": "請改用 type: string(非敏感值),或把敏感值改成 App 啟動後自行取得/由管理員放進 ${SYNO_APP_SECRETS_DIR} 的檔案。在 DSM worker 的失敗原因可觀測之前,secret 型別不會開放。"
121
131
  },
122
132
  "CONTRACT_HOMES_UNSUPPORTED": {
123
133
  "code": "CONTRACT_HOMES_UNSUPPORTED",
124
- "description": "install.<NAME>.type: homes 目前沒有可用的安裝路徑。2026-08-27 於 vt-nas 實測:wizard 不產生輸入控制項,Package Center 安裝以 DSM broken/150 結束;CLI deploy 能解析出 /volume1/homes,但 DSM 於 compound install 回 4540 拒絕。",
125
- "suggestion": "若 App 需要一個由管理員選定的資料夾,請改用 type: shared_folder。homes 型別要能用,需要補齊 wizard 控制項與 preinst materialization(見 STATUS.md A46)。"
134
+ "description": "install.<NAME>.type: homes 目前沒有可用的安裝路徑:安裝精靈不產生輸入控制項,Package Center 安裝以 DSM broken/150 結束;CLI deploy 能解析出 /volume1/homes,但 DSM 於 compound install 回 4540 拒絕。",
135
+ "suggestion": "若 App 需要一個由管理員選定的資料夾,請改用 type: shared_folder。在補齊安裝精靈控制項與 preinst 路徑解析之前,homes 型別不會開放。"
126
136
  },
127
137
  "INSTALL_PARAMETER_UNREFERENCED": {
128
138
  "code": "INSTALL_PARAMETER_UNREFERENCED",
@@ -336,8 +346,13 @@ export const ERROR_REGISTRY = {
336
346
  },
337
347
  "DEPLOY_PARAM_UNDECLARED": {
338
348
  "code": "DEPLOY_PARAM_UNDECLARED",
339
- "description": "deploy --param 提供了契約未宣告的 Install Parameter。",
340
- "suggestion": "請只傳 synology-app.yaml install 中宣告的 string 或 boolean 名稱。"
349
+ "description": "deploy --param 提供了契約未宣告的 Install Parameter,或 native-go/binary 套件沒有的安裝精靈值。",
350
+ "suggestion": "Compose 請只傳 synology-app.yaml install 中宣告的 string 或 boolean 名稱;native-go/binary 只接受 install-selected delegate 的 delegate_share 或 delegate_home。"
351
+ },
352
+ "DEPLOY_PARAM_REQUIRED": {
353
+ "code": "DEPLOY_PARAM_REQUIRED",
354
+ "description": "首次安裝 install-selected delegate 套件時沒有提供安裝精靈的範圍值,preinst 會拒絕安裝。",
355
+ "suggestion": "加上 --param delegate_share=<共用資料夾> 或 --param delegate_home=true 再部署。"
341
356
  },
342
357
  "DEPLOY_PARAM_TYPE_INVALID": {
343
358
  "code": "DEPLOY_PARAM_TYPE_INVALID",
@@ -402,7 +417,7 @@ export const ERROR_REGISTRY = {
402
417
  "STANDALONE_DAEMON_BUILD_FAILED": {
403
418
  "code": "STANDALONE_DAEMON_BUILD_FAILED",
404
419
  "description": "無法建置套件 daemon 的 Go supervisor。",
405
- "suggestion": "安裝 Go 1.24 以上並檢查 compiler stderr;NAS 不需要 Go toolchain。"
420
+ "suggestion": "安裝 Go 1.21 以上(建置固定使用 go1.26.9,離線時請先備妥)並檢查 compiler stderr;NAS 不需要 Go toolchain。"
406
421
  },
407
422
  "STANDALONE_DAEMON_PAYLOAD_INVALID": {
408
423
  "code": "STANDALONE_DAEMON_PAYLOAD_INVALID",
@@ -472,7 +487,7 @@ export const ERROR_REGISTRY = {
472
487
  "STANDALONE_ARCHES_INVALID": {
473
488
  "code": "STANDALONE_ARCHES_INVALID",
474
489
  "description": "arches 不合法。",
475
- "suggestion": "請列出不重複的 x86_64 或 aarch64,至少一個。"
490
+ "suggestion": "請列出不重複的 x86_64、aarch64 或 armv7,至少一個。"
476
491
  },
477
492
  "STANDALONE_ARCH_NOT_DECLARED": {
478
493
  "code": "STANDALONE_ARCH_NOT_DECLARED",
@@ -506,8 +521,8 @@ export const ERROR_REGISTRY = {
506
521
  },
507
522
  "STANDALONE_BINARY_NOT_ELF": {
508
523
  "code": "STANDALONE_BINARY_NOT_ELF",
509
- "description": "backend 執行檔不是 64-bit little-endian Linux ELF。",
510
- "suggestion": "請提供為 Linux 編譯的 x86_64 或 aarch64 執行檔。"
524
+ "description": "backend 執行檔不是該架構需要的 little-endian Linux ELF(x86_64、aarch64 為 64-bit,armv7 為 32-bit)。",
525
+ "suggestion": "請提供為 Linux 編譯的 x86_64、aarch64 或 armv7 執行檔。"
511
526
  },
512
527
  "STANDALONE_BINARY_ARCH_MISMATCH": {
513
528
  "code": "STANDALONE_BINARY_ARCH_MISMATCH",
@@ -574,6 +589,11 @@ export const ERROR_REGISTRY = {
574
589
  "description": "go build 失敗。",
575
590
  "suggestion": "請在 backend 目錄執行 go build ./... 並修正錯誤。"
576
591
  },
592
+ "STANDALONE_PORTAL_INVALID": {
593
+ "code": "STANDALONE_PORTAL_INVALID",
594
+ "description": "dsm-package.yaml 的 portal 格式或 alias 不正確。",
595
+ "suggestion": "請使用 portal: {} 或 portal: { alias: my-app };alias 為 1–64 個小寫英數字或 -,且不是 DSM 保留路徑。"
596
+ },
577
597
  "STANDALONE_I18N_INVALID": {
578
598
  "code": "STANDALONE_I18N_INVALID",
579
599
  "description": "dsm-package.yaml 的 i18n 設定不合法。",
@@ -629,6 +649,8 @@ for (const [code, description, suggestion] of [
629
649
  ERROR_REGISTRY[code] = { code, description, suggestion };
630
650
  ERROR_REGISTRY["ADD_LAYOUT_UNSUPPORTED"] = { "code": "ADD_LAYOUT_UNSUPPORTED", "description": "SDK overlay 需要標準 backend 目錄。", "suggestion": "使用 backend.dir: backend,或手動合併 SDK overlay。" };
631
651
  ERROR_REGISTRY["MIN_DSM_CONTAINER_FLOOR"] = { "code": "MIN_DSM_CONTAINER_FLOOR", "description": "Compose 最低 DSM 版本過低。", "suggestion": "Compose 需要 DSM 7.2.1-69057 或以上。" };
652
+ for (const code of ["STANDALONE_PORTAL_MIN_DSM", "CONTRACT_PORTAL_MIN_DSM"])
653
+ ERROR_REGISTRY[code] = { code, "description": "宣告 portal 的套件 os_min_ver 低於 DSM 7.3.2-86009。", "suggestion": "DSM 7.1.1 以 320 拒裝帶 portal 的未簽章套件、7.2 未驗證;把 os_min_ver 提高到 7.3.2-86009 以上,或移除 portal。" };
632
654
  ERROR_REGISTRY["MIN_DSM_INVALID"] = { "code": "MIN_DSM_INVALID", "description": "最低 DSM 版本格式不合法。", "suggestion": "指定 7.x release 或完整 7.x-build。" };
633
655
  ERROR_REGISTRY["NOTICE_UNSAFE"] = { "code": "NOTICE_UNSAFE", "description": "授權檔案不符合一般檔案限制。", "suggestion": "移除 symlink、特殊檔與超大授權檔案。" };
634
656
  ERROR_REGISTRY["NOTICE_MISSING"] = { "code": "NOTICE_MISSING", "description": "缺少第三方授權資訊。", "suggestion": "重新安裝模板依賴並產生 third-party notices。" };
@@ -641,10 +663,9 @@ ERROR_REGISTRY["SPK_INSPECTION_FAILED"] = { "code": "SPK_INSPECTION_FAILED", "de
641
663
  ERROR_REGISTRY["IMAGE_PIN_REQUIRED"] = { "code": "IMAGE_PIN_REQUIRED", "description": "映像 digest 尚未固定。", "suggestion": "執行 images pin。" };
642
664
  ERROR_REGISTRY["INIT_TEMPLATE_REQUIRED"] = { "code": "INIT_TEMPLATE_REQUIRED", "description": "未指定模板。", "suggestion": "使用 -t native-go、binary 或 compose。" };
643
665
  ERROR_REGISTRY["INIT_TEMPLATE_UNKNOWN"] = { "code": "INIT_TEMPLATE_UNKNOWN", "description": "未知模板。", "suggestion": "使用 -t native-go、binary 或 compose。" };
644
- ERROR_REGISTRY["CLI_ARCH_INVALID"] = { "code": "CLI_ARCH_INVALID", "description": "架構選項不合法。", "suggestion": "使用 x86_64 或 aarch64。" };
645
- ERROR_REGISTRY["NATIVE_ARCH_UNDETERMINED"] = { "code": "NATIVE_ARCH_UNDETERMINED", "description": "無法判定 NAS 架構。", "suggestion": "指定 --arch x86_64 或 aarch64。" };
666
+ ERROR_REGISTRY["CLI_ARCH_INVALID"] = { "code": "CLI_ARCH_INVALID", "description": "架構選項不合法。", "suggestion": "使用 x86_64、aarch64 或 armv7(armv7 用於 native-go 與 binary,不用於 Container Manager App)。" };
667
+ ERROR_REGISTRY["NATIVE_ARCH_UNDETERMINED"] = { "code": "NATIVE_ARCH_UNDETERMINED", "description": "無法判定 NAS 架構。", "suggestion": "指定 --arch x86_64、aarch64 或 armv7。" };
646
668
  ERROR_REGISTRY["DEVELOPMENT_INSTANCE_UNSUPPORTED"] = { "code": "DEVELOPMENT_INSTANCE_UNSUPPORTED", "description": "原生專案不支援 --dev。", "suggestion": "init 時指定不同 package ID。" };
647
- ERROR_REGISTRY["INIT_TEMPLATE_INVALID"] = { "code": "INIT_TEMPLATE_INVALID", "description": "未知模板。", "suggestion": "使用 -t native-go、binary 或 compose。" };
648
669
  ERROR_REGISTRY["INIT_OPTIONS_UNSUPPORTED"] = { "code": "INIT_OPTIONS_UNSUPPORTED", "description": "選項不適用於這個模板。", "suggestion": "--from 僅 compose;--ui 僅 native-go。" };
649
670
  ERROR_REGISTRY["INIT_TARGET_NOT_EMPTY"] = { "code": "INIT_TARGET_NOT_EMPTY", "description": "init 目錄已有衝突檔案。", "suggestion": "使用空目錄;既有專案新增能力使用 add。" };
650
671
  ERROR_REGISTRY["INIT_COMPOSE_INVALID"] = { "code": "INIT_COMPOSE_INVALID", "description": "匯入的 Compose 不合法。", "suggestion": "--from 指向有 services 的 YAML 檔案。" };
@@ -662,10 +683,23 @@ ERROR_REGISTRY["CLI_OPTION_ARGUMENT_MISSING"] = { "code": "CLI_OPTION_ARGUMENT_M
662
683
  ERROR_REGISTRY["CLI_COMMAND_UNKNOWN"] = { "code": "CLI_COMMAND_UNKNOWN", "description": "未知指令。", "suggestion": "使用 synopkgland --help 查看指令。" };
663
684
  ERROR_REGISTRY["COMMAND_FAILED"] = { "code": "COMMAND_FAILED", "description": "指令執行失敗。", "suggestion": "查看 message 與 stderr,修正問題後重試。" };
664
685
  ERROR_REGISTRY["DEPLOY_PLAN_INVALID"] = { "code": "DEPLOY_PLAN_INVALID", "description": "部署計畫與 runtime 不符。", "suggestion": "重新 check 並產生部署計畫。" };
665
- ERROR_REGISTRY["DEPLOY_ARCH_UNDETERMINED"] = { "code": "DEPLOY_ARCH_UNDETERMINED", "description": "無法判定 NAS 架構。", "suggestion": "使用 --arch x86_64 或 aarch64。" };
686
+ ERROR_REGISTRY["DEPLOY_ARCH_UNDETERMINED"] = { "code": "DEPLOY_ARCH_UNDETERMINED", "description": "無法判定 NAS 架構。", "suggestion": "使用 --arch x86_64、aarch64 或 armv7。" };
687
+ ERROR_REGISTRY["CONTAINER_ARCH_UNSUPPORTED"] = { "code": "CONTAINER_ARCH_UNSUPPORTED", "description": "Container Manager App 只支援 x86_64 與 aarch64;DSM 不為 armv7 提供 Container Manager。", "suggestion": "改用 --arch x86_64 或 aarch64,或改用 native-go 模板。" };
666
688
  ERROR_REGISTRY["DEPLOY_BUILD_OUTPUT_INVALID"] = { "code": "DEPLOY_BUILD_OUTPUT_INVALID", "description": "部署建置輸出數量不符。", "suggestion": "指定單一架構並重新 build。" };
667
689
  export function getErrorCode(code) {
668
690
  return ERROR_REGISTRY[code];
669
691
  }
670
- for (const code of ["EXECUTOR_BUILD_FAILED", "EXECUTOR_PIN_REQUIRED", "EXECUTOR_POLICY", "EXECUTOR_PACKAGE", "EXECUTOR_DIGEST", "EXECUTOR_TASK_PERCENT", "EXECUTOR_TASK_LENGTH"])
671
- ERROR_REGISTRY[code] = { code, description: "Executor build or pinned task definition is invalid.", suggestion: "Check manifest capabilities and executor compiler output; rebuild before administrator approval." };
692
+ for (const [code, description, suggestion] of [
693
+ ["EXECUTOR_BUILD_FAILED", "executor 或 lifecycle helper 編譯失敗,或 CLI 套件缺少 executor 原始碼。", "確認已安裝 Go 1.21 以上且可取得 go1.26.9(離線時請先備妥),查看訊息中的編譯器輸出;原始碼缺少時重新安裝 CLI。"],
694
+ ["EXECUTOR_PIN_REQUIRED", "宣告 rootOps 或 delegate 的套件建置時沒有 executor 產物。", "使用 synopkgland build,讓 CLI 編譯並 pin executor;不要直接呼叫低階 SPK API。"],
695
+ ["EXECUTOR_POLICY", "capabilities.delegate 的 operations 或 scope 不合法,無法產生 executor policy。", "改用 init/add 產生的 delegate 宣告,或依 manifest 參考修正 scope 與 operations。"],
696
+ ["EXECUTOR_PACKAGE", "pin 進 root task 的套件名稱不合法。", "package 必須以英文字母開頭,只含英數字(2–64 字)。"],
697
+ ["EXECUTOR_DIGEST", "executor 或 policy 的 sha256 pin 格式不合法。", "重新 build,讓 CLI 重新計算 pin;不要手改 SPK 內的 pin。"],
698
+ ["EXECUTOR_TASK_PERCENT", "root task 腳本含有 %,DSM 工作排程器無法保存。", "從 root/ 腳本移除 % 字元(例如 date 格式改用其他寫法)。"],
699
+ ["EXECUTOR_TASK_LENGTH", "root task 腳本超過 DSM 工作排程器的長度上限。", "縮短 root/ 腳本,把邏輯移到套件內的檔案再由腳本呼叫。"],
700
+ ])
701
+ ERROR_REGISTRY[code] = { code, description, suggestion };
702
+ ERROR_REGISTRY["STANDALONE_ENTRY_INVALID"] = { "code": "STANDALONE_ENTRY_INVALID", "description": "entry 設定不合法。", "suggestion": "entry 填 admin-only 或 app-privilege;app-privilege 需要至少一個 authenticated route。" };
703
+ ERROR_REGISTRY["STANDALONE_ENTRY_WIDENED"] = { "code": "STANDALONE_ENTRY_WIDENED", "description": "entry: admin-only 與放寬權限的 route 設定衝突。", "suggestion": "把 permissions.json 中 authenticated 或 public 的 route 改為 administrators;要開放給一般使用者請改用 entry: app-privilege 或省略 entry。" };
704
+ ERROR_REGISTRY["STANDALONE_ENTRY_UNSUPPORTED"] = { "code": "STANDALONE_ENTRY_UNSUPPORTED", "description": "backend 無法強制 entry 模式。", "suggestion": "使用 Go backend,複製 SDK 的 internal/dsm entry gate 並在 cmd/app/main.go 呼叫 dsm.NewEntryGate。" };
705
+ ERROR_REGISTRY["DSM_TLS_UNTRUSTED"] = { "code": "DSM_TLS_UNTRUSTED", "description": "DSM 的 TLS 憑證不受這台電腦信任(自簽、過期或名稱不符)。", "suggestion": "把 NAS 憑證或其 CA 匯出成 PEM,用 NODE_EXTRA_CA_CERTS=<該檔> 執行;或讓 DSM 使用與 host profile 名稱相符的受信任憑證。不要關閉憑證驗證。" };
@@ -1,4 +1,5 @@
1
1
  import type { HostCredentials, NasHost } from "./types.js";
2
+ import type { NativeArchFamily } from "../build-spk/dsm-arch.js";
2
3
  export interface CreateNasHostOptions {
3
4
  host?: string;
4
5
  credentials?: HostCredentials;
@@ -17,9 +18,12 @@ declare function synoagentcli(args: string[], profileName?: string): {
17
18
  export declare function homesPathFromDsmUserHomeRead(result: Pick<ReturnType<typeof synoagentcli>, "status" | "stdout">): string | undefined;
18
19
  /**
19
20
  * DSM reports the CPU vendor, not the ISA. Every x86_64 platform Synology
20
- * ships is Intel or AMD; every aarch64 one is Realtek, Marvell, Annapurna or
21
- * Rockchip. An unrecognised vendor returns undefined so `deploy` asks for
22
- * `--arch` rather than guessing wrong and building an unusable SPK.
21
+ * ships is Intel or AMD; the aarch64 ones are Realtek (rtd1296, rtd1619b) and
22
+ * Rockchip; Annapurna Labs is DSM 7's alpine/alpine4k, which are armv7 (DS416
23
+ * reports "ANNAPURNALABS"). Marvell makes both armada37xx (aarch64) and
24
+ * armada38x (armv7), so it, like an unrecognised vendor, returns undefined and
25
+ * `deploy` asks for `--arch` rather than guessing wrong and building an
26
+ * unusable SPK.
23
27
  */
24
- export declare function archFamilyForCpuVendor(vendor: string | undefined): "x86_64" | "aarch64" | undefined;
28
+ export declare function archFamilyForCpuVendor(vendor: string | undefined): NativeArchFamily | undefined;
25
29
  export {};
@@ -3,6 +3,7 @@ import { listShareNamesWithSynoagentcli, lookupSharePathWithSynoagentcli, } from
3
3
  import { createSynoagentcliApiCall, fetchSharePermissions, fetchUserGroups, } from "./share-permission-lookup.js";
4
4
  import { fetchPortInfo } from "./port-info-lookup.js";
5
5
  import { dsmFetch } from "./dsm-http.js";
6
+ import { versionUnsupported } from "../runtime/dsm-version.js";
6
7
  import { fetchDsmPortProfileInventory } from "./dsm-port-profile.js";
7
8
  import { installPackageFromLocalSpk, fetchInstalledPackageState, packageStateFromRecord, } from "./catalog-install.js";
8
9
  import { resolveHostCredentials } from "./credentials.js";
@@ -53,6 +54,16 @@ export function homesPathFromDsmUserHomeRead(result) {
53
54
  }
54
55
  return `${volume}/homes`;
55
56
  }
57
+ function setCookiePairs(headers) {
58
+ const lines = typeof headers.getSetCookie === "function"
59
+ ? headers.getSetCookie()
60
+ : headers.get("set-cookie")
61
+ ? [headers.get("set-cookie")]
62
+ : [];
63
+ return lines
64
+ .map((line) => line.split(";")[0]?.trim())
65
+ .filter((pair) => Boolean(pair));
66
+ }
56
67
  function createDsmNasHost(credentials, profileName) {
57
68
  const dsmOrigin = credentials.dsmOrigin.replace(/\/$/, "");
58
69
  let cookieHeader = credentials.cookieHeader;
@@ -77,15 +88,7 @@ function createDsmNasHost(credentials, profileName) {
77
88
  const login = (await response.json());
78
89
  if (!response.ok || login.success !== true)
79
90
  throw new Error("DSM login failed");
80
- const setCookie = typeof response.headers.getSetCookie === "function"
81
- ? response.headers.getSetCookie()
82
- : response.headers.get("set-cookie")
83
- ? [response.headers.get("set-cookie")]
84
- : [];
85
- const pairs = setCookie
86
- .map((line) => line.split(";")[0]?.trim())
87
- .filter((pair) => Boolean(pair));
88
- cookieHeader = pairs.join("; ");
91
+ cookieHeader = setCookiePairs(response.headers).join("; ");
89
92
  if (!cookieHeader)
90
93
  throw new Error("DSM login returned no session cookie");
91
94
  };
@@ -106,12 +109,38 @@ function createDsmNasHost(credentials, profileName) {
106
109
  async getExecutorStatus(packageIdentity) {
107
110
  try {
108
111
  await ensureLogin();
109
- const response = await dsmFetch(`${dsmOrigin}/webman/3rdparty/${encodeURIComponent(packageIdentity)}/cgi/api.cgi`, {
110
- method: "POST", headers: { cookie: cookieHeader ?? "", "content-type": "application/json" },
111
- body: JSON.stringify({ method: "executor.status", params: {} }),
112
- });
113
- const body = await response.json();
114
- return body.success ? body.data : undefined;
112
+ const appCall = async (method, cookie) => {
113
+ const response = await dsmFetch(`${dsmOrigin}/webman/3rdparty/${encodeURIComponent(packageIdentity)}/cgi/api.cgi`, {
114
+ method: "POST", headers: { cookie, origin: dsmOrigin, "content-type": "application/json" },
115
+ body: JSON.stringify({ method, params: method === "identity.session" ? { bootstrap: true } : {} }),
116
+ });
117
+ const body = await response.json();
118
+ return { body, setCookie: setCookiePairs(response.headers) };
119
+ };
120
+ // A paused executor answers with why and what to do next.
121
+ const explain = (status) => status.state === "paused" ? { ...status, error: `Executor paused (${status.reason}). ${status.next}` } : status;
122
+ const direct = await appCall("executor.status", cookieHeader ?? "");
123
+ if (direct.body.success)
124
+ return explain(direct.body.data);
125
+ // identity: standalone wraps business methods in an App session; trade the
126
+ // administrator's DSM cookie for one, read once, then end that session.
127
+ if (direct.body.error?.code !== "session_required")
128
+ return undefined;
129
+ const session = await appCall("identity.session", cookieHeader ?? "");
130
+ if (!session.body.success) {
131
+ const code = session.body.error?.code;
132
+ return { ready: false, executor_digest: "", policy_digest: "", error: code === "https_required"
133
+ ? "identity: standalone status needs an https:// DSM host profile to open an App session."
134
+ : `identity: standalone App session bootstrap failed (${code ?? "error"}).` };
135
+ }
136
+ const appCookie = [cookieHeader ?? "", ...session.setCookie].filter(Boolean).join("; ");
137
+ try {
138
+ const status = await appCall("executor.status", appCookie);
139
+ return status.body.success ? explain(status.body.data) : undefined;
140
+ }
141
+ finally {
142
+ await appCall("identity.logout", appCookie).catch(() => undefined);
143
+ }
115
144
  }
116
145
  catch {
117
146
  return undefined;
@@ -130,6 +159,12 @@ function createDsmNasHost(credentials, profileName) {
130
159
  throw Object.assign(new Error(`DSM ${body.error?.code ?? "error"}: scheduler readback denied; check the administrator session. No retry was made.`), { code: body.error?.code });
131
160
  return body.data;
132
161
  };
162
+ // DSM 7.1 stops at TaskScheduler list v2 (offset) and get v3; only an unsupported version falls back.
163
+ const taskRead = (method, version, params, legacyVersion, legacyParams) => call("SYNO.Core.TaskScheduler", method, version, params).catch((e) => {
164
+ if (!versionUnsupported(e.code))
165
+ throw e;
166
+ return call("SYNO.Core.TaskScheduler", method, legacyVersion, legacyParams);
167
+ });
133
168
  const records = await call("SYNO.Core.EventScheduler", "list", 1, {});
134
169
  if (!Array.isArray(records))
135
170
  throw new Error("Invalid EventScheduler readback.");
@@ -142,13 +177,14 @@ function createDsmNasHost(credentials, profileName) {
142
177
  throw new Error("Invalid boot task readback.");
143
178
  tasks.push({ ...detail, name: detail.task_name, kind: "boot" });
144
179
  }
145
- const listed = await call("SYNO.Core.TaskScheduler", "list", 3, { start: 0, limit: 500 });
180
+ const listed = await taskRead("list", 3, { start: 0, limit: 500 }, 2, { offset: 0, limit: 500 });
146
181
  if (!Array.isArray(listed?.tasks) || !Number.isInteger(listed.total) || listed.total !== listed.tasks.length || listed.total > 500)
147
182
  throw new Error("Incomplete TaskScheduler readback.");
148
183
  for (const summary of listed.tasks) {
149
184
  if (summary?.name !== `${packageIdentity} executor control`)
150
185
  continue;
151
- const detail = await call("SYNO.Core.TaskScheduler", "get", 4, { id: summary.id, real_owner: summary.real_owner });
186
+ const ref = { id: summary.id, real_owner: summary.real_owner };
187
+ const detail = await taskRead("get", 4, ref, 3, ref);
152
188
  if (!detail || String(detail.id) !== String(summary.id) || detail.name !== summary.name)
153
189
  throw new Error("Invalid control task readback.");
154
190
  tasks.push({ ...detail, kind: "control" });
@@ -275,17 +311,23 @@ function createDsmNasHost(credentials, profileName) {
275
311
  }
276
312
  /**
277
313
  * DSM reports the CPU vendor, not the ISA. Every x86_64 platform Synology
278
- * ships is Intel or AMD; every aarch64 one is Realtek, Marvell, Annapurna or
279
- * Rockchip. An unrecognised vendor returns undefined so `deploy` asks for
280
- * `--arch` rather than guessing wrong and building an unusable SPK.
314
+ * ships is Intel or AMD; the aarch64 ones are Realtek (rtd1296, rtd1619b) and
315
+ * Rockchip; Annapurna Labs is DSM 7's alpine/alpine4k, which are armv7 (DS416
316
+ * reports "ANNAPURNALABS"). Marvell makes both armada37xx (aarch64) and
317
+ * armada38x (armv7), so it, like an unrecognised vendor, returns undefined and
318
+ * `deploy` asks for `--arch` rather than guessing wrong and building an
319
+ * unusable SPK.
281
320
  */
282
321
  export function archFamilyForCpuVendor(vendor) {
283
322
  const normalized = (vendor ?? "").trim().toLowerCase();
284
323
  if (normalized === "intel" || normalized === "amd") {
285
324
  return "x86_64";
286
325
  }
287
- if (["realtek", "marvell", "annapurna labs", "annapurna", "rockchip"].includes(normalized)) {
326
+ if (["realtek", "rockchip"].includes(normalized)) {
288
327
  return "aarch64";
289
328
  }
329
+ if (["annapurnalabs", "annapurna labs", "annapurna"].includes(normalized)) {
330
+ return "armv7";
331
+ }
290
332
  return undefined;
291
333
  }