@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
@@ -22,9 +22,9 @@ const canAuthorize=computed(()=>required.value&&!untrusted.value)
22
22
  const unavailableKey=computed(()=>shown.value?.reason==='credential_not_ready'?'credential':'unavailable')
23
23
  const title=computed(()=>!shown.value?text.value('checking'):required.value?text.value('title'):shown.value.state==='ready'?text.value('ready'):shown.value.state==='not_admin'?text.value('not_admin.title'):shown.value.state==='session_expired'?text.value('session_expired.title'):text.value(unavailableKey.value+'.title'))
24
24
  const body=computed(()=>required.value?text.value('purpose'):shown.value?.state==='not_admin'?text.value('not_admin.body'):shown.value?.state==='session_expired'?text.value('session_expired.body'):shown.value?.state==='unavailable'?text.value(unavailableKey.value+'.body'):text.value('purpose'))
25
- const reasons=['grant_missing','helper_untrusted','cli_untrusted','grant_incompatible','package_identity_changed','maintenance_task_missing','maintenance_task_mismatch','helper_health_rejected','capability_missing']
25
+ const reasons=['grant_missing','upgrade_reapproval','helper_untrusted','cli_untrusted','grant_incompatible','package_identity_changed','maintenance_task_missing','maintenance_task_mismatch','helper_health_rejected','capability_missing']
26
26
  const reason=computed(()=>reasons.includes(shown.value?.reason||'')?shown.value!.reason!:'unknown')
27
- const next=computed(()=>untrusted.value?'next.reinstall':reason.value==='grant_missing'?'next.install':reason.value==='grant_incompatible'?'next.update':'next.repair')
27
+ const next=computed(()=>untrusted.value?'next.reinstall':reason.value==='grant_missing'?'next.install':reason.value==='upgrade_reapproval'||reason.value==='grant_incompatible'?'next.update':'next.repair')
28
28
  async function action(method:'status'|'request'|'revoke'){
29
29
  if(busy.value||disposed)return
30
30
  const current=++sequence
@@ -37,6 +37,8 @@ async function action(method:'status'|'request'|'revoke'){
37
37
  const result=await props.ctx.authorization?.[method]()
38
38
  if(disposed||current!==sequence)return
39
39
  if(!result||result.command!=='authorization'||result.schema_version!==1||!['ready','authorization_required','not_admin','session_expired','unavailable'].includes(result.state))throw Error('invalid status')
40
+ // A reason-only upgrade tombstone never accompanies a usable authorization.
41
+ if(result.reason==='upgrade_reapproval'&&result.state!=='authorization_required')throw Error('invalid status')
40
42
  state.value=result
41
43
  if(result.state==='ready')emit('ready')
42
44
  } catch(e){if(!disposed&&current===sequence){
@@ -54,7 +56,7 @@ onUnmounted(()=>{disposed=true;sequence++;if(typeof unsubscribe==='function')uns
54
56
  <span class="authorization-icon" aria-hidden="true"><component :is="shown?.state==='unavailable'||shown?.state==='session_expired'?TriangleAlert:ShieldCheck" class="authorization-icon-glyph" /></span>
55
57
  <h1 class="authorization-title">{{ title }}</h1>
56
58
  <p class="authorization-body">{{ body }}</p>
57
- <Callout v-if="required" class="authorization-status" :tone="reason==='grant_missing'?'info':'warning'" :title="text('reason.'+reason)">{{ text(next) }}</Callout>
59
+ <Callout v-if="required" class="authorization-status" :tone="['grant_missing','upgrade_reapproval'].includes(reason)?'info':'warning'" :title="text('reason.'+reason)">{{ text(next) }}</Callout>
58
60
  <Callout v-if="failure" class="authorization-failed" tone="warning">{{ text('failed') }}</Callout>
59
61
  <div class="authorization-actions">
60
62
  <Button v-if="canAuthorize" variant="primary" :loading="busy" :disabled="busy" @click="action('request')">{{ busy ? text('authorizing') : text('authorize') }}</Button>
@@ -2,6 +2,7 @@
2
2
  "authorization.title": "{package} benötigt Ihre Erlaubnis",
3
3
  "authorization.purpose": "Dieses Paket benötigt eine Genehmigung für feste Root-Operationen. DSM verarbeitet Ihr Passwort; das Paket sieht oder speichert es nicht.",
4
4
  "authorization.reason.grant_missing": "Root-Operationen sind noch nicht autorisiert.",
5
+ "authorization.reason.upgrade_reapproval": "Das Paket wurde im Paket-Zentrum aktualisiert, daher wurde die bisherige Autorisierung widerrufen.",
5
6
  "authorization.reason.helper_untrusted": "Dem privilegierten Helfer konnte nicht vertraut werden.",
6
7
  "authorization.reason.cli_untrusted": "Dem privilegierten Befehl konnte nicht vertraut werden.",
7
8
  "authorization.reason.grant_incompatible": "Der privilegierte Helfer muss aktualisiert werden.",
@@ -2,6 +2,7 @@
2
2
  "authorization.title": "{package} needs your permission",
3
3
  "authorization.purpose": "This package needs approval for its fixed root operations. DSM handles your password; the package never sees or stores it.",
4
4
  "authorization.reason.grant_missing": "Root operations are not authorized yet.",
5
+ "authorization.reason.upgrade_reapproval": "The package was updated in Package Center, so its previous authorization was revoked.",
5
6
  "authorization.reason.helper_untrusted": "The privileged helper could not be trusted.",
6
7
  "authorization.reason.cli_untrusted": "The privileged command could not be trusted.",
7
8
  "authorization.reason.grant_incompatible": "The privileged helper needs an update.",
@@ -2,6 +2,7 @@
2
2
  "authorization.title": "{package} necesita su permiso",
3
3
  "authorization.purpose": "Este paquete requiere aprobación para sus operaciones root fijas. DSM gestiona su contraseña; el paquete no la ve ni la almacena.",
4
4
  "authorization.reason.grant_missing": "Las operaciones root aún no están autorizadas.",
5
+ "authorization.reason.upgrade_reapproval": "El paquete se actualizó en el Centro de paquetes, por lo que se revocó la autorización anterior.",
5
6
  "authorization.reason.helper_untrusted": "No se pudo confiar en el asistente privilegiado.",
6
7
  "authorization.reason.cli_untrusted": "No se pudo confiar en el comando privilegiado.",
7
8
  "authorization.reason.grant_incompatible": "El asistente privilegiado necesita una actualización.",
@@ -30,7 +31,7 @@
30
31
  "authorization.ready": "Autorizado",
31
32
  "authorization.revoke": "Revocar autorización",
32
33
  "authorization.revoke.title": "¿Revocar autorización?",
33
- "authorization.revoke.body": "Se desactivarán los nuevos accesos del helper. Se conservan los datos del paquete y los resultados anteriores.",
34
+ "authorization.revoke.body": "Se desactivarán los nuevos accesos del asistente privilegiado. Se conservan los datos del paquete y los resultados anteriores.",
34
35
  "authorization.cancel": "Cancelar",
35
36
  "authorization.checking": "Comprobando autorización…"
36
37
  }
@@ -2,6 +2,7 @@
2
2
  "authorization.title": "{package} demande votre autorisation",
3
3
  "authorization.purpose": "Ce paquet nécessite une autorisation pour ses opérations root fixes. DSM traite votre mot de passe ; le paquet ne le voit ni ne le stocke.",
4
4
  "authorization.reason.grant_missing": "Les opérations root ne sont pas encore autorisées.",
5
+ "authorization.reason.upgrade_reapproval": "Le paquet a été mis à jour dans le Centre de paquets ; l'autorisation précédente a donc été révoquée.",
5
6
  "authorization.reason.helper_untrusted": "L'assistant privilégié n'a pas pu être approuvé.",
6
7
  "authorization.reason.cli_untrusted": "La commande privilégiée n'a pas pu être approuvée.",
7
8
  "authorization.reason.grant_incompatible": "L'assistant privilégié doit être mis à jour.",
@@ -1,7 +1,8 @@
1
1
  {
2
- "authorization.title": "{package} richiede il tuo permesso",
2
+ "authorization.title": "{package} richiede l’autorizzazione",
3
3
  "authorization.purpose": "Questo pacchetto richiede l’approvazione per le sue operazioni root fisse. DSM gestisce la password; il pacchetto non la vede né la memorizza.",
4
4
  "authorization.reason.grant_missing": "Le operazioni root non sono ancora autorizzate.",
5
+ "authorization.reason.upgrade_reapproval": "Il pacchetto è stato aggiornato in Centro pacchetti, quindi l'autorizzazione precedente è stata revocata.",
5
6
  "authorization.reason.helper_untrusted": "Non è stato possibile considerare attendibile l'helper privilegiato.",
6
7
  "authorization.reason.cli_untrusted": "Non è stato possibile considerare attendibile il comando privilegiato.",
7
8
  "authorization.reason.grant_incompatible": "L'helper privilegiato deve essere aggiornato.",
@@ -11,22 +12,22 @@
11
12
  "authorization.reason.helper_health_rejected": "L'helper privilegiato non ha superato il controllo di integrità.",
12
13
  "authorization.reason.capability_missing": "All'helper privilegiato manca una capacità necessaria.",
13
14
  "authorization.reason.unknown": "L'autorizzazione è mancante o non più valida.",
14
- "authorization.next.install": "Scegli Autorizza e conferma la password DSM per approvare questa versione.",
15
- "authorization.next.update": "Questa versione richiede una nuova autorizzazione. Scegli Autorizza e conferma la password DSM.",
16
- "authorization.next.repair": "Controlla le attività del pacchetto nell’Utilità di pianificazione e riprova.",
15
+ "authorization.next.install": "Scegliere «Autorizza» e confermare la password DSM per approvare questa versione.",
16
+ "authorization.next.update": "Questa versione richiede una nuova autorizzazione. Scegliere «Autorizza» e confermare la password DSM.",
17
+ "authorization.next.repair": "Controllare le attività del pacchetto nell’Utilità di pianificazione, quindi riprovare.",
17
18
  "authorization.authorize": "Autorizza",
18
19
  "authorization.authorizing": "In attesa di DSM…",
19
- "authorization.failed": "L'autorizzazione non è stata completata. Puoi riprovare.",
20
+ "authorization.failed": "L’autorizzazione non è stata completata. È possibile riprovare.",
20
21
  "authorization.unavailable.title": "Impossibile verificare l'autorizzazione",
21
- "authorization.unavailable.body": "Di solito è temporaneo. Riprova; {package} non chiederà la password.",
22
+ "authorization.unavailable.body": "Di solito è temporaneo. Riprovare; {package} non chiederà la password.",
22
23
  "authorization.credential.title": "Le credenziali di accesso di DSM non sono pronte",
23
- "authorization.credential.body": "Questa sessione DSM è stata ripristinata senza accesso con password, quindi DSM non può garantire per le richieste di {package}. Disconnettiti da DSM, accedi di nuovo con la password e riapri {package}.",
24
+ "authorization.credential.body": "Questa sessione DSM è stata ripristinata senza accesso con password, quindi DSM non può garantire per le richieste di {package}. Disconnettersi da DSM, accedere di nuovo con la password e riaprire {package}.",
24
25
  "authorization.retry": "Riprova",
25
- "authorization.next.reinstall": "I file installati non corrispondono a questa versione. Reinstalla il pacchetto da una fonte attendibile e riprova.",
26
+ "authorization.next.reinstall": "I file installati non corrispondono a questa versione. Reinstallare il pacchetto da una fonte attendibile, quindi riprovare.",
26
27
  "authorization.not_admin.title": "Amministratore necessario",
27
- "authorization.not_admin.body": "Chiedi a un amministratore DSM di aprire e autorizzare questo pacchetto.",
28
+ "authorization.not_admin.body": "Chiedere a un amministratore DSM di aprire e autorizzare questo pacchetto.",
28
29
  "authorization.session_expired.title": "Sessione scaduta",
29
- "authorization.session_expired.body": "Accedi nuovamente a DSM e riapri questo pacchetto.",
30
+ "authorization.session_expired.body": "Accedere nuovamente a DSM e riaprire questo pacchetto.",
30
31
  "authorization.ready": "Autorizzato",
31
32
  "authorization.revoke": "Revoca autorizzazione",
32
33
  "authorization.revoke.title": "Revocare l’autorizzazione?",
@@ -2,6 +2,7 @@
2
2
  "authorization.title": "{package} に承認が必要です",
3
3
  "authorization.purpose": "このパッケージの固定 root 操作には承認が必要です。パスワードは DSM が処理し、パッケージは閲覧も保存もしません。",
4
4
  "authorization.reason.grant_missing": "root 操作はまだ承認されていません。",
5
+ "authorization.reason.upgrade_reapproval": "パッケージ センターでパッケージが更新されたため、以前の承認は取り消されました。",
5
6
  "authorization.reason.helper_untrusted": "特権ヘルパーを信頼できませんでした。",
6
7
  "authorization.reason.cli_untrusted": "特権コマンドを信頼できませんでした。",
7
8
  "authorization.reason.grant_incompatible": "特権ヘルパーの更新が必要です。",
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "authorization.title": "{package} 승인 필요",
3
- "authorization.purpose": "이 패키지의 고정 root 작업에는 승인이 필요합니다. 비밀번호는 DSM이 처리하며 패키지는 비밀번호를 보거나 저장하지 않습니다.",
3
+ "authorization.purpose": "이 패키지의 고정 root 작업에는 승인이 필요합니다. 암호는 DSM이 처리하며 패키지는 암호를 보거나 저장하지 않습니다.",
4
4
  "authorization.reason.grant_missing": "root 작업이 아직 승인되지 않았습니다.",
5
+ "authorization.reason.upgrade_reapproval": "패키지 센터에서 패키지가 업데이트되어 이전 승인이 취소되었습니다.",
5
6
  "authorization.reason.helper_untrusted": "권한 있는 도우미를 신뢰할 수 없습니다.",
6
7
  "authorization.reason.cli_untrusted": "권한 있는 명령을 신뢰할 수 없습니다.",
7
8
  "authorization.reason.grant_incompatible": "권한 있는 도우미를 업데이트해야 합니다.",
@@ -11,22 +12,22 @@
11
12
  "authorization.reason.helper_health_rejected": "권한 있는 도우미가 상태 검사를 통과하지 못했습니다.",
12
13
  "authorization.reason.capability_missing": "권한 있는 도우미에 필요한 기능이 없습니다.",
13
14
  "authorization.reason.unknown": "권한이 없거나 더 이상 유효하지 않습니다.",
14
- "authorization.next.install": "승인을 선택하고 DSM 비밀번호로 이 빌드를 승인하세요.",
15
- "authorization.next.update": "이 빌드는 새 승인이 필요합니다. 승인을 선택하고 DSM 비밀번호로 확인하세요.",
16
- "authorization.next.repair": "작업 스케줄러에서 패키지 작업을 확인한 후 다시 시도하세요.",
15
+ "authorization.next.install": "승인을 선택하고 DSM 암호로 이 빌드를 승인하십시오.",
16
+ "authorization.next.update": "이 빌드는 새 승인이 필요합니다. 승인을 선택하고 DSM 암호로 확인하십시오.",
17
+ "authorization.next.repair": "작업 스케줄러에서 패키지 작업을 확인한 후 다시 시도하십시오.",
17
18
  "authorization.authorize": "권한 부여",
18
19
  "authorization.authorizing": "DSM을 기다리는 중…",
19
20
  "authorization.failed": "권한 부여가 완료되지 않았습니다. 다시 시도할 수 있습니다.",
20
21
  "authorization.unavailable.title": "권한을 확인할 수 없습니다",
21
- "authorization.unavailable.body": "일반적으로 일시적인 문제입니다. 다시 시도하세요. {package}은 비밀번호를 요구하지 않습니다.",
22
+ "authorization.unavailable.body": "일반적으로 일시적인 문제입니다. 다시 시도하십시오. {package}은 암호를 요구하지 않습니다.",
22
23
  "authorization.credential.title": "DSM 로그인 자격 증명이 준비되지 않았습니다",
23
- "authorization.credential.body": "이 DSM 세션은 비밀번호 로그인 없이 복원되었으므로 DSM이 {package}의 요청을 보증할 수 없습니다. DSM에서 로그아웃한 후 비밀번호로 다시 로그인하고 {package}을 다시 여세요.",
24
+ "authorization.credential.body": "이 DSM 세션은 암호 로그인 없이 복원되었으므로 DSM이 {package}의 요청을 보증할 수 없습니다. DSM에서 로그아웃한 후 암호로 다시 로그인하고 {package}을 다시 여십시오.",
24
25
  "authorization.retry": "다시 시도",
25
- "authorization.next.reinstall": "설치된 파일이 이 빌드와 일치하지 않습니다. 신뢰할 수 있는 출처에서 패키지를 다시 설치한 후 다시 시도하세요.",
26
+ "authorization.next.reinstall": "설치된 파일이 이 빌드와 일치하지 않습니다. 신뢰할 수 있는 출처에서 패키지를 다시 설치한 후 다시 시도하십시오.",
26
27
  "authorization.not_admin.title": "관리자가 필요합니다",
27
- "authorization.not_admin.body": "DSM 관리자에게 이 패키지를 열고 승인하도록 요청하세요.",
28
+ "authorization.not_admin.body": "DSM 관리자에게 이 패키지를 열고 승인하도록 요청하십시오.",
28
29
  "authorization.session_expired.title": "세션이 만료되었습니다",
29
- "authorization.session_expired.body": "DSM에 다시 로그인한 후 패키지를 다시 여세요.",
30
+ "authorization.session_expired.body": "DSM에 다시 로그인한 후 패키지를 다시 여십시오.",
30
31
  "authorization.ready": "승인됨",
31
32
  "authorization.revoke": "승인 취소",
32
33
  "authorization.revoke.title": "승인을 취소하시겠습니까?",
@@ -1,7 +1,8 @@
1
1
  {
2
- "authorization.title": "{package} 需要您的授权",
2
+ "authorization.title": "{package} 需要授权",
3
3
  "authorization.purpose": "此套件执行固定的 root 操作前需要批准。密码由 DSM 处理,套件不会看到或存储。",
4
4
  "authorization.reason.grant_missing": "尚未授权 root 操作。",
5
+ "authorization.reason.upgrade_reapproval": "套件已通过套件中心更新,之前的授权已撤销。",
5
6
  "authorization.reason.helper_untrusted": "无法信任特权 helper。",
6
7
  "authorization.reason.cli_untrusted": "无法信任特权命令。",
7
8
  "authorization.reason.grant_incompatible": "特权 helper 需要更新。",
@@ -11,14 +12,14 @@
11
12
  "authorization.reason.helper_health_rejected": "特权 helper 未通过健康检查。",
12
13
  "authorization.reason.capability_missing": "特权 helper 缺少必要的能力。",
13
14
  "authorization.reason.unknown": "授权已丢失或不再有效。",
14
- "authorization.next.install": "选择“授权”,并使用您的 DSM 密码确认,即可批准此版本。",
15
- "authorization.next.update": "此版本需要重新授权。请选择“授权”,并使用您的 DSM 密码确认。",
15
+ "authorization.next.install": "选择“授权”,并使用 DSM 密码确认,即可批准此版本。",
16
+ "authorization.next.update": "此版本需要重新授权。请选择“授权”,并使用 DSM 密码确认。",
16
17
  "authorization.next.repair": "请在任务计划中检查此套件的任务,再重试。",
17
18
  "authorization.authorize": "授权",
18
19
  "authorization.authorizing": "正在等待 DSM…",
19
- "authorization.failed": "授权未完成,您可以重试。",
20
+ "authorization.failed": "授权未完成,请重试。",
20
21
  "authorization.unavailable.title": "无法检查授权",
21
- "authorization.unavailable.body": "这通常是暂时的。请重试,{package} 不会要求您的密码。",
22
+ "authorization.unavailable.body": "这通常是暂时的。请重试,{package} 不会要求输入密码。",
22
23
  "authorization.credential.title": "DSM 的登录凭据尚未就绪",
23
24
  "authorization.credential.body": "此 DSM 会话是恢复而来,并未使用密码登录,因此 DSM 无法为 {package} 的请求作证。请注销 DSM,使用密码重新登录,然后再打开 {package}。",
24
25
  "authorization.retry": "重试",
@@ -1,7 +1,8 @@
1
1
  {
2
- "authorization.title": "{package} 需要您的授權",
2
+ "authorization.title": "{package} 需要授權",
3
3
  "authorization.purpose": "此套件執行固定的 root 操作前需要核准。密碼由 DSM 處理,套件不會看到或儲存。",
4
4
  "authorization.reason.grant_missing": "尚未授權 root 操作。",
5
+ "authorization.reason.upgrade_reapproval": "套件已透過套件中心更新,先前的授權已撤銷。",
5
6
  "authorization.reason.helper_untrusted": "無法信任特權 helper。",
6
7
  "authorization.reason.cli_untrusted": "無法信任特權命令。",
7
8
  "authorization.reason.grant_incompatible": "特權 helper 需要更新。",
@@ -11,14 +12,14 @@
11
12
  "authorization.reason.helper_health_rejected": "特權 helper 未通過健康檢查。",
12
13
  "authorization.reason.capability_missing": "特權 helper 缺少必要的能力。",
13
14
  "authorization.reason.unknown": "授權已遺失或不再有效。",
14
- "authorization.next.install": "選擇「授權」,並以您的 DSM 密碼確認,即可核准此版本。",
15
- "authorization.next.update": "此版本需要重新授權。請選擇「授權」,並以您的 DSM 密碼確認。",
15
+ "authorization.next.install": "選擇「授權」,並以 DSM 密碼確認,即可核准此版本。",
16
+ "authorization.next.update": "此版本需要重新授權。請選擇「授權」,並以 DSM 密碼確認。",
16
17
  "authorization.next.repair": "請在任務排程表中檢查此套件的任務,再重試。",
17
18
  "authorization.authorize": "授權",
18
19
  "authorization.authorizing": "正在等待 DSM…",
19
- "authorization.failed": "授權未完成,您可以再試一次。",
20
+ "authorization.failed": "授權未完成,請再試一次。",
20
21
  "authorization.unavailable.title": "無法檢查授權",
21
- "authorization.unavailable.body": "這通常是暫時的。請再試一次,{package} 不會要求您的密碼。",
22
+ "authorization.unavailable.body": "這通常是暫時的。請再試一次,{package} 不會要求輸入密碼。",
22
23
  "authorization.credential.title": "DSM 的登入憑證尚未就緒",
23
24
  "authorization.credential.body": "此 DSM 工作階段是還原而來,並未使用密碼登入,因此 DSM 無法為 {package} 的要求作證。請登出 DSM,以密碼重新登入,然後再開啟 {package}。",
24
25
  "authorization.retry": "重試",
@@ -38,8 +38,9 @@ Declare `capabilities.files: session` for interactive File Station access,
38
38
  `capabilities.jobs: true` for persistent package-account jobs,
39
39
  `capabilities.identity: standalone` for independent DSM login, and
40
40
  `capabilities.rootOps: true` for administrator-approved fixed executor operations.
41
- `init --with files,jobs,login,root-ops` supports plain and Vue UI.
42
- Jobs and `daemon` are mutually exclusive; `delegate` is not implemented until P2.
41
+ `init --with files,jobs,root-ops` supports plain and Vue UI; `login` and
42
+ `delegate` need the Vue UI. `daemon` cannot be combined with `jobs`, but it can
43
+ be combined with an until-revoked `delegate`.
43
44
 
44
45
  ```sh
45
46
  synopkgland add files jobs login
@@ -126,7 +127,7 @@ access. The template ships no exceptions and sets DSM `allUsers` to `false`.
126
127
  | absent or `administrators` | `session_required` | `admin_required` | runs |
127
128
  | explicit `authenticated` | `session_required` | runs | runs |
128
129
  | explicit `public` | runs | runs | runs |
129
- | unregistered method | `session_required` | `admin_required` | `unknown_method` |
130
+ | unregistered method | `session_required` | `unknown_method` | `unknown_method` |
130
131
 
131
132
  Missing or invalid JSON, duplicate keys, unknown permissions and rules for
132
133
  unregistered methods fail closed. The CLI validates the file and binds its
@@ -193,13 +194,24 @@ Known limits:
193
194
  - Directory reachability and DSM name-service freshness affect native role
194
195
  checks. The bridge bypasses DSM's administrator-role cache but cannot force
195
196
  an upstream directory replica to be current. It refuses unknown results.
196
- - The static Go CGI embeds a minimal native bridge for Linux amd64/arm64,
197
+ - The static Go CGI embeds a minimal native bridge for Linux amd64/arm64/armv7,
197
198
  reproduced with Zig 0.16.0 from `internal/dsm/native/admin_check.c`. The bridge
198
199
  runs from a sealed memory file with a clean environment, a 3-second deadline
199
200
  and bounded output; no runtime Zig, compiler, writable executable or root
200
201
  privilege is required. The ELF files and build/source hashes are recorded in
201
202
  `native/provenance.json`. DSM must expose the native SDK symbol; otherwise
202
203
  authentication refuses access.
204
+ - Kernels without `memfd_create` (DSM 7 on Linux 3.10: armv7 and the x86_64
205
+ `avoton`, `braswell`, `bromolow`, `grantley` and `cedarview` platforms) cannot
206
+ seal the bridge. Only there, the CGI stages it in the package's own
207
+ `/var/packages/<package>/tmp` (DSM mounts `/tmp` noexec): a fresh 0700
208
+ directory, a 0500 file reopened read-only and unlinked before it runs. The
209
+ seal guarantee is lost: between the write and the unlink, a process running
210
+ as the same package account could replace the bridge. That account already
211
+ runs the CGI, so the bridge never trusts anything that account does not
212
+ already control; other accounts cannot write the directory, which must be
213
+ owned by the package account and not group- or world-writable. Any other
214
+ memfd failure still refuses.
203
215
 
204
216
  ## Customize the UI
205
217
 
@@ -323,6 +335,11 @@ use a DSM term, copy its `text` from the glossary and add your key to the
323
335
  term's `keys`. A Vue or React UI can keep its own i18n library; `ctx.t` and
324
336
  `ctx.locale` are there if you want them.
325
337
 
338
+ The Vue shell (`--ui vue`) keeps its text in `frontend/src/**/i18n/<locale>.json`,
339
+ one folder per area (status page, sign-in, files, background jobs), in the same
340
+ nine languages. Add new text to all nine files rather than writing it into a
341
+ `.vue` file.
342
+
326
343
  ## Package an existing binary
327
344
 
328
345
  Keep the Go backend and call your tool from a handler (recommended: auth
@@ -343,6 +360,22 @@ It then owns everything `backend/internal/api` does for you: bounded reads,
343
360
  POST-only JSON, same-origin checks, authentication before any work, and a
344
361
  refusal for unknown methods.
345
362
 
363
+ ## DSM Application Portal link
364
+
365
+ `synopkgland add portal` adds `portal: {}` to dsm-package.yaml so
366
+ `https://<nas>/<alias>/` opens this app right after DSM sign-in. The install
367
+ wizard proposes the alias (the package name in lowercase by default); an
368
+ administrator turns it on from the app's portal panel or Control Panel >
369
+ Login Portal > Applications. Ordinary users then see the link; until then
370
+ they see "ask an administrator". DSM owns the setting: the backend's
371
+ `portal.status` only reads it, and nothing in the package may write it. See
372
+ `synopkgland skill show portal`.
373
+
374
+ A portal needs DSM 7.3.2-86009 or later, so `add portal` raises a lower
375
+ `os_min_ver` and build refuses one below it. DSM 7.1.1 rejects an unsigned
376
+ package that registers a portal (Package Center error 320); 7.3.2 and 7.4
377
+ install it; 7.2 is untested. To keep supporting older DSM, remove `portal:`.
378
+
346
379
  ## Data, upgrades, uninstall
347
380
 
348
381
  The backend stores data in `/var/packages/__PACKAGE__/var` (the package's
@@ -384,9 +417,9 @@ install reuses the old data and how to start clean.
384
417
  The generated SPK ships
385
418
  an uninstall wizard (English, plus eight other languages) with one box, **Also
386
419
  delete the app data listed above** (`pkgwizard_remove_additional`), unchecked by
387
- default. Ticked, `postuninst` empties `@appdata/<package>` and `@apphome/<package>`
388
- and nothing else: not `@appconf`, Shared Folders, the package account or other
389
- packages. An upgrade never deletes anything. Do not write your own `postuninst`;
420
+ default. Ticked, `postuninst` empties `@appdata/<package>`, `@apphome/<package>`
421
+ and `@appconf/<package>` and nothing else: not Shared Folders, the package
422
+ account or other packages. An upgrade never deletes anything. Do not write your own `postuninst`;
390
423
  `synopkgland inspect` flags a deleting script that lacks the upgrade guard
391
424
  or deletes outside the package's own folders.
392
425
 
@@ -421,6 +454,6 @@ DSM testing.
421
454
  | | Status |
422
455
  | --- | --- |
423
456
  | Build hosts | macOS, Linux (any OS with Go and Node) |
424
- | Target CPUs | x86_64 and aarch64 DSM models (one SPK each) |
425
- | DSM | 7.1 or later declared (`os_min_ver`, change it with `init --min-dsm` or `build --min-dsm`). Installed and tested on DSM 7.4 (x86_64). aarch64 SPKs are built the same way but have not been run on a NAS. |
426
- | Not supported | 32-bit ARM, DSM 6, running anything as root without an administrator's approval |
457
+ | Target CPUs | x86_64 and aarch64 DSM models (one SPK each). armv7 (DSM 7.2+ platforms `alpine`, `alpine4k`, `armada38x`, `monaco`) is opt-in: add it to `arches`; it covers the Go CGI (plain or Vue UI), jobs, daemon, root-ops and delegate. armv7 jobs, daemon and executor (root-ops, delegate) are built and checked locally but have not been verified on a NAS |
458
+ | DSM | 7.1 or later declared (`os_min_ver`, change it with `init --min-dsm` or `build --min-dsm`). Installed and tested on DSM 7.4 and 7.3.2 (x86_64). armv7 was installed and tested on DSM 7.1.1 (`alpine4k`, Linux 3.10, where the bridge runs from the package tmp fallback) with administrator, AppPriv and unauthenticated requests; `armada38x` and `monaco` have not been run on a NAS. No x86_64 Linux 3.10 model has been tested. aarch64 SPKs are built the same way but have not been run on a NAS. |
459
+ | Not supported | armv7 platforms only DSM 7.0/7.1 ship (`armada370`, `armada375`, `armadaxp`, `comcerto2k`); DSM 6, running anything as root without an administrator's approval |
@@ -20,15 +20,22 @@ import (
20
20
 
21
21
  // Set by `synopkgland build-spk` through -ldflags -X; never read from a request.
22
22
  var (
23
- delegateScope = ""
24
- executorDigest = ""
25
- policyDigest = ""
26
- packageID = "dev"
27
- version = "0.0.0"
23
+ delegateScope = ""
24
+ delegateOperationsJSON = ""
25
+ delegateDestinationsJSON = ""
26
+ delegateLifetime = ""
27
+ executorDigest = ""
28
+ policyDigest = ""
29
+ packageID = "dev"
30
+ version = "0.0.0"
28
31
  // "session" when the project opted into the interactive File Station adapter.
29
32
  fileStation = ""
30
33
  // "standalone" enables the SDK identity adapter; the runtime owns authentication.
31
34
  identity = ""
35
+ // dsm-package.yaml entry: "admin-only" or "app-privilege"; empty keeps the route policy alone.
36
+ entry = ""
37
+ // "on" when dsm-package.yaml declares portal: serves portal.status.
38
+ portal = ""
32
39
  )
33
40
 
34
41
  func main() {
@@ -39,15 +46,24 @@ func main() {
39
46
  os.Exit(2)
40
47
  }
41
48
  cfg := app.Config{
42
- DelegateScope: delegateScope,
43
- ExecutorDigest: executorDigest, PolicyDigest: policyDigest,
49
+ DelegateScope: delegateScope,
50
+ DelegateOperationsJSON: delegateOperationsJSON,
51
+ DelegateDestinationsJSON: delegateDestinationsJSON,
52
+ DelegateLifetime: delegateLifetime,
53
+ ExecutorDigest: executorDigest, PolicyDigest: policyDigest,
44
54
  PackageID: packageID,
45
55
  Version: version,
46
56
  DataDir: "/var/packages/" + packageID + "/var",
57
+ Portal: portal == "on",
58
+ }
59
+ if _, err := app.ParseDelegateConfig(cfg); err != nil {
60
+ log.Fatal(err)
47
61
  }
48
62
  if app.SessionFilesEnabled(fileStation) {
49
63
  cfg.SessionFiles = filestation.Local(cfg.DataDir)
50
64
  }
65
+ // Kernels without memfd_create stage DSM's bridges in the package's own temp.
66
+ dsm.SetBridgeFallbackDir("/var/packages/" + packageID + "/tmp")
51
67
  var auth api.Authenticator = dsm.NewAuthenticator()
52
68
  var standalone *standaloneidentity.Service
53
69
  if identity == "standalone" {
@@ -58,6 +74,10 @@ func main() {
58
74
  }
59
75
  auth = standalone
60
76
  }
77
+ auth, err := dsm.NewEntryGate(auth, entry, packageID, cfg.DataDir)
78
+ if err != nil {
79
+ log.Fatal(err)
80
+ }
61
81
  srv, err := api.NewServer(auth, app.Routes(cfg)...)
62
82
  if err != nil {
63
83
  log.Fatal(err)
@@ -2,7 +2,7 @@ module dsmapp
2
2
 
3
3
  go 1.25.0
4
4
 
5
- toolchain go1.26.8
5
+ toolchain go1.26.9
6
6
 
7
7
  require github.com/godbus/dbus/v5 v5.2.3-0.20260924123156-0ea052abeb82
8
8
 
@@ -0,0 +1,47 @@
1
+ package api
2
+
3
+ import (
4
+ "context"
5
+ "encoding/json"
6
+ "errors"
7
+ "testing"
8
+ )
9
+
10
+ func TestEntryRefusalsReachTheBrowserAsStableCodes(t *testing.T) {
11
+ raw := []byte(`{"schema":1,"default":"administrators","methods":{"demo.user":"authenticated"}}`)
12
+ for _, tc := range []struct {
13
+ err error
14
+ code string
15
+ }{
16
+ {ErrAdminRequired, "admin_required"},
17
+ {ErrAppPrivilegeDenied, "app_privilege_denied"},
18
+ {errors.New("bridge exited 2"), "auth_unavailable"},
19
+ } {
20
+ executed := 0
21
+ srv, err := NewServerWithPermissions(&fakeAuth{err: tc.err}, raw, Handle("demo.user", func(context.Context, Caller, json.RawMessage) (any, error) {
22
+ executed++
23
+ return nil, nil
24
+ }))
25
+ if err != nil {
26
+ t.Fatal(err)
27
+ }
28
+ for _, method := range []string{"demo.user", "future.unknown"} {
29
+ _, env := post(t, srv, `{"method":"`+method+`"}`)
30
+ if env.Error == nil || env.Error.Code != tc.code || executed != 0 {
31
+ t.Fatalf("%v %s: %+v executed=%d", tc.err, method, env.Error, executed)
32
+ }
33
+ }
34
+ }
35
+ }
36
+
37
+ func TestRequireAdminLetsHandlersReserveGlobalSettings(t *testing.T) {
38
+ if err := RequireAdmin(Caller{identity: Identity{User: "alice", Admin: true}, authenticated: true}); err != nil {
39
+ t.Fatal(err)
40
+ }
41
+ for _, c := range []Caller{{identity: Identity{User: "bob"}, authenticated: true}, {identity: Identity{User: "alice", Admin: true}}, {}} {
42
+ var apiErr *Error
43
+ if err := RequireAdmin(c); !errors.As(err, &apiErr) || apiErr.Code != "admin_required" {
44
+ t.Fatalf("%+v: %v", c, err)
45
+ }
46
+ }
47
+ }
@@ -9,7 +9,7 @@ import (
9
9
 
10
10
  func TestDefaultPermissionsRequireAdministratorGroup(t *testing.T) {
11
11
  for _, makeRoute := range []func(string, Handler) Route{User, Public, Admin} {
12
- for _, method := range []string{"future.read", "future.unknown"} {
12
+ for method, code := range map[string]string{"future.read": "admin_required", "future.unknown": "unknown_method"} {
13
13
  executed := 0
14
14
  auth := &fakeAuth{user: "admin"} // Name alone confers no group membership.
15
15
  srv, err := NewServer(auth, makeRoute("future.read", func(context.Context, Caller, json.RawMessage) (any, error) {
@@ -20,7 +20,7 @@ func TestDefaultPermissionsRequireAdministratorGroup(t *testing.T) {
20
20
  t.Fatal(err)
21
21
  }
22
22
  _, env := post(t, srv, `{"method":"`+method+`","params":{"admin":true,"groups":["administrators"]}}`)
23
- if env.Error == nil || env.Error.Code != "admin_required" || executed != 0 || auth.calls != 1 {
23
+ if env.Error == nil || env.Error.Code != code || executed != 0 || auth.calls != 1 {
24
24
  t.Fatalf("method=%s error=%+v executed=%d auth=%d", method, env.Error, executed, auth.calls)
25
25
  }
26
26
  }
@@ -39,7 +39,7 @@ func TestCentralPermissionsAreTheOnlyAccessDecision(t *testing.T) {
39
39
  t.Fatal(err)
40
40
  }
41
41
  for _, tc := range []struct{ method, code string }{
42
- {"demo.user", ""}, {"demo.ping", ""}, {"demo.private", "admin_required"}, {"future.unknown", "admin_required"},
42
+ {"demo.user", ""}, {"demo.ping", ""}, {"demo.private", "admin_required"}, {"future.unknown", "unknown_method"},
43
43
  } {
44
44
  _, env := post(t, srv, `{"method":"`+tc.method+`"}`)
45
45
  if tc.code == "" {
@@ -102,6 +102,17 @@ func (c Caller) Authenticated() bool { return c.authenticated }
102
102
  func (c Caller) User() string { return c.identity.User }
103
103
  func (c Caller) Admin() bool { return c.authenticated && c.identity.Admin }
104
104
 
105
+ var adminRequired = &Error{"admin_required", "this action needs the DSM administrators group"}
106
+
107
+ // RequireAdmin reserves part of a shared route, such as global settings, for
108
+ // DSM administrators. Whole routes are reserved in permissions.json instead.
109
+ func RequireAdmin(c Caller) error {
110
+ if !c.Admin() {
111
+ return adminRequired
112
+ }
113
+ return nil
114
+ }
115
+
105
116
  var methodName = regexp.MustCompile(`^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$`)
106
117
 
107
118
  func buildRegistry(routes []Route) (map[string]Route, error) {
@@ -23,6 +23,9 @@
23
23
  "bg.jobs.purge": "administrators",
24
24
  "bg.schedules.enable": "administrators"
25
25
  },
26
+ "portal": {
27
+ "portal.status": "authenticated"
28
+ },
26
29
  "identity": {
27
30
  "identity.status": "public",
28
31
  "identity.login": "public",
@@ -35,12 +38,22 @@
35
38
  "root.run": "administrators"
36
39
  },
37
40
  "delegate": {
41
+ "delegate.destination": "authenticated",
38
42
  "delegate.status": "authenticated",
39
43
  "delegate.create": "authenticated",
40
44
  "delegate.list": "authenticated",
41
45
  "delegate.revoke": "authenticated",
42
46
  "delegate.jobs.submit": "authenticated",
43
47
  "delegate.jobs.list": "authenticated",
44
- "delegate.jobs.cancel": "authenticated"
48
+ "delegate.jobs.cancel": "authenticated",
49
+ "delegate.select_destination": "authenticated",
50
+ "delegate.move_from_staging": "authenticated",
51
+ "delegate.operations.get": "authenticated",
52
+ "delegate.operations.list": "authenticated",
53
+ "delegate.operations.cancel": "authenticated",
54
+ "delegate.disable": "administrators",
55
+ "delegate.enable": "administrators",
56
+ "delegate.audit": "authenticated",
57
+ "delegate.example.export": "authenticated"
45
58
  }
46
59
  }
@@ -40,6 +40,13 @@ func WithRequestDeadline(next http.Handler) http.Handler {
40
40
  // ErrNoSession means the request carries no valid DSM session.
41
41
  var ErrNoSession = errors.New("no valid DSM session")
42
42
 
43
+ // ErrAdminRequired is an entry refusal: the app admits only administrators.
44
+ var ErrAdminRequired = errors.New("app entry requires an administrator")
45
+
46
+ // ErrAppPrivilegeDenied is an entry refusal: DSM Application Privileges do not
47
+ // allow this account to use the app from this address.
48
+ var ErrAppPrivilegeDenied = errors.New("DSM Application Privileges deny this app")
49
+
43
50
  // Authenticator verifies the DSM session behind a request.
44
51
  type Authenticator interface {
45
52
  Authenticate(r *http.Request) (Identity, error)
@@ -212,18 +219,24 @@ func (s *Server) authorize(r *http.Request, method string) (Caller, Route, *Erro
212
219
  if errors.Is(err, ErrNoSession) {
213
220
  return Caller{}, Route{}, &Error{"session_required", "sign in to DSM again"}
214
221
  }
222
+ if errors.Is(err, ErrAdminRequired) {
223
+ return Caller{}, Route{}, adminRequired
224
+ }
225
+ if errors.Is(err, ErrAppPrivilegeDenied) {
226
+ return Caller{}, Route{}, &Error{"app_privilege_denied", "DSM Application Privileges do not allow this account to use this app"}
227
+ }
215
228
  if err != nil {
216
229
  log.Printf("authentication unavailable: %v", err)
217
230
  return Caller{}, Route{}, &Error{"auth_unavailable", "DSM authentication is unavailable"}
218
231
  }
219
- // Unknown methods inherit the fixed administrators default before revealing
220
- // whether a handler exists. Route constructors never grant permission.
221
- if (!known || route.policy == policyAdmin) && !identity.Admin {
222
- return Caller{}, Route{}, &Error{"admin_required", "this action needs the DSM administrators group"}
223
- }
232
+ // Signed-in callers learn that a method is unregistered; method names
233
+ // already ship in the app's UI. Route constructors never grant permission.
224
234
  if !known {
225
235
  return Caller{}, Route{}, &Error{"unknown_method", "unknown method"}
226
236
  }
237
+ if route.policy == policyAdmin && !identity.Admin {
238
+ return Caller{}, Route{}, adminRequired
239
+ }
227
240
  caller := Caller{identity: identity, authenticated: true}
228
241
  return caller, route, nil
229
242
  }