@synopackageland/cli 0.3.10 → 0.4.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 (641) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +57 -9
  3. package/dist/bin.js +1 -2
  4. package/dist/build-spk/generator.d.ts +0 -3
  5. package/dist/build-spk/generator.js +138 -287
  6. package/dist/build-spk/native-lifecycle.js +0 -3
  7. package/dist/build-spk/native-payload.js +0 -1
  8. package/dist/build-spk/notices.d.ts +5 -0
  9. package/dist/build-spk/notices.js +60 -0
  10. package/dist/cli.js +178 -151
  11. package/dist/compose/analyze.d.ts +1 -2
  12. package/dist/compose/analyze.js +5 -48
  13. package/dist/contract/unsupported-types.d.ts +10 -0
  14. package/dist/contract/unsupported-types.js +49 -0
  15. package/dist/contract/validate.js +25 -2
  16. package/dist/contract/web-launch.js +0 -2
  17. package/dist/deploy/deploy.d.ts +1 -4
  18. package/dist/deploy/deploy.js +45 -156
  19. package/dist/deploy/homes-values.js +1 -1
  20. package/dist/deploy/plan.d.ts +18 -0
  21. package/dist/deploy/plan.js +54 -0
  22. package/dist/deploy/spk-version.d.ts +2 -14
  23. package/dist/deploy/spk-version.js +25 -111
  24. package/dist/dev.d.ts +1 -3
  25. package/dist/dev.js +14 -28
  26. package/dist/error-registry.js +830 -862
  27. package/dist/host/dsm-client.js +12 -272
  28. package/dist/host/dsm-port-profile.d.ts +0 -1
  29. package/dist/host/dsm-port-profile.js +0 -2
  30. package/dist/host/types.d.ts +1 -83
  31. package/dist/index.d.ts +0 -9
  32. package/dist/index.js +0 -6
  33. package/dist/info.d.ts +0 -1
  34. package/dist/info.js +3 -10
  35. package/dist/init.d.ts +15 -1
  36. package/dist/init.js +128 -12
  37. package/dist/log.js +2 -3
  38. package/dist/native/validate.js +0 -1
  39. package/dist/standalone/binary.d.ts +9 -0
  40. package/dist/standalone/binary.js +67 -0
  41. package/dist/standalone/build.d.ts +25 -0
  42. package/dist/standalone/build.js +110 -0
  43. package/dist/standalone/daemon.d.ts +23 -0
  44. package/dist/standalone/daemon.js +114 -0
  45. package/dist/standalone/dsm-window.d.ts +26 -0
  46. package/dist/standalone/dsm-window.js +291 -0
  47. package/dist/standalone/helper-inventory.d.ts +16 -0
  48. package/dist/standalone/helper-inventory.js +2 -0
  49. package/dist/standalone/helper.d.ts +21 -0
  50. package/dist/standalone/helper.js +105 -0
  51. package/dist/standalone/host-adapter.d.ts +5 -0
  52. package/dist/standalone/host-adapter.js +148 -0
  53. package/dist/standalone/host-platform.d.ts +13 -0
  54. package/dist/standalone/host-platform.js +42 -0
  55. package/dist/standalone/host-types.d.ts +49 -0
  56. package/dist/standalone/host-types.js +1 -0
  57. package/dist/standalone/i18n.d.ts +28 -0
  58. package/dist/standalone/i18n.js +161 -0
  59. package/dist/standalone/inspect-helper.d.ts +6 -0
  60. package/dist/standalone/inspect-helper.js +88 -0
  61. package/dist/standalone/inspect-spk.d.ts +23 -0
  62. package/dist/standalone/inspect-spk.js +209 -0
  63. package/dist/standalone/lifecycle-helper.d.ts +2 -0
  64. package/dist/standalone/lifecycle-helper.js +12 -0
  65. package/dist/standalone/lifecycle.d.ts +3 -0
  66. package/dist/standalone/lifecycle.js +53 -0
  67. package/dist/standalone/manifest.d.ts +73 -0
  68. package/dist/standalone/manifest.js +279 -0
  69. package/dist/standalone/reopen-events.d.ts +2 -0
  70. package/dist/standalone/reopen-events.js +28 -0
  71. package/dist/standalone/root-messages.d.ts +7 -0
  72. package/dist/standalone/root-messages.js +259 -0
  73. package/dist/standalone/root-ops.d.ts +42 -0
  74. package/dist/standalone/root-ops.js +101 -0
  75. package/dist/standalone/root-window.d.ts +36 -0
  76. package/dist/standalone/root-window.js +302 -0
  77. package/dist/standalone/spk.d.ts +23 -0
  78. package/dist/standalone/spk.js +192 -0
  79. package/dist/template-paths.d.ts +2 -0
  80. package/dist/template-paths.js +9 -0
  81. package/dist/templates/_daemon/fixture_linux_test.go +15 -0
  82. package/dist/templates/_daemon/fixture_other_test.go +7 -0
  83. package/dist/templates/_daemon/go.mod +3 -0
  84. package/dist/templates/_daemon/main.go +608 -0
  85. package/dist/templates/_daemon/main_test.go +242 -0
  86. package/dist/templates/_daemon/process_linux.go +55 -0
  87. package/dist/templates/_daemon/process_linux_test.go +161 -0
  88. package/dist/templates/_daemon/process_other.go +14 -0
  89. package/dist/templates/_daemon/testdata/child.go +41 -0
  90. package/dist/templates/_shared/GO-LICENSE +27 -0
  91. package/dist/templates/_shared/GO-PATENTS +22 -0
  92. package/dist/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
  93. package/dist/templates/_shared/notice-overrides/index.json +14 -0
  94. package/dist/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
  95. package/dist/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
  96. package/dist/templates/_shared/third-party-notices.mjs +51 -0
  97. package/dist/templates/binary/synology-app.yaml +7 -0
  98. package/dist/templates/hello-files/compose.yaml +0 -1
  99. package/dist/templates/hello-web/compose.yaml +13 -10
  100. package/dist/templates/hello-web/html/app.js +1 -23
  101. package/dist/templates/hello-web/html/index.html +1 -3
  102. package/dist/templates/hello-web-page/compose.yaml +13 -10
  103. package/dist/templates/hello-web-page/html/app.js +1 -23
  104. package/dist/templates/hello-web-page/html/index.html +1 -3
  105. package/dist/templates/native-go/README.md +324 -0
  106. package/dist/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
  107. package/dist/templates/native-go/backend/cmd/app/main.go +49 -0
  108. package/dist/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
  109. package/dist/templates/native-go/backend/cmd/helper/main.go +38 -0
  110. package/dist/templates/native-go/backend/go.mod +7 -0
  111. package/dist/templates/native-go/backend/go.sum +4 -0
  112. package/dist/templates/native-go/backend/internal/api/binary.go +154 -0
  113. package/dist/templates/native-go/backend/internal/api/binary_test.go +165 -0
  114. package/dist/templates/native-go/backend/internal/api/errors.go +33 -0
  115. package/dist/templates/native-go/backend/internal/api/registry.go +104 -0
  116. package/dist/templates/native-go/backend/internal/api/registry_test.go +329 -0
  117. package/dist/templates/native-go/backend/internal/api/server.go +159 -0
  118. package/dist/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
  119. package/dist/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
  120. package/dist/templates/native-go/backend/internal/app/root_none.go +9 -0
  121. package/dist/templates/native-go/backend/internal/app/routes.go +138 -0
  122. package/dist/templates/native-go/backend/internal/app/routes_test.go +172 -0
  123. package/dist/templates/native-go/backend/internal/dsm/auth.go +118 -0
  124. package/dist/templates/native-go/backend/internal/dsm/auth_test.go +139 -0
  125. package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
  126. package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
  127. package/dist/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
  128. package/dist/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
  129. package/dist/templates/native-go/backend/internal/helper/cohort.go +393 -0
  130. package/dist/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
  131. package/dist/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
  132. package/dist/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
  133. package/dist/templates/native-go/backend/internal/helper/control.go +424 -0
  134. package/dist/templates/native-go/backend/internal/helper/control_test.go +250 -0
  135. package/dist/templates/native-go/backend/internal/helper/data_contract.go +242 -0
  136. package/dist/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
  137. package/dist/templates/native-go/backend/internal/helper/data_decode.go +184 -0
  138. package/dist/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
  139. package/dist/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
  140. package/dist/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
  141. package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
  142. package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
  143. package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
  144. package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
  145. package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
  146. package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
  147. package/dist/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
  148. package/dist/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
  149. package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
  150. package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
  151. package/dist/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
  152. package/dist/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
  153. package/dist/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
  154. package/dist/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
  155. package/dist/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
  156. package/dist/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
  157. package/dist/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
  158. package/dist/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
  159. package/dist/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
  160. package/dist/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
  161. package/dist/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
  162. package/dist/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
  163. package/dist/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
  164. package/dist/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
  165. package/dist/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
  166. package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
  167. package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
  168. package/dist/templates/native-go/backend/internal/helper/lease.go +112 -0
  169. package/dist/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
  170. package/dist/templates/native-go/backend/internal/helper/lease_other.go +8 -0
  171. package/dist/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
  172. package/dist/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
  173. package/dist/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
  174. package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
  175. package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
  176. package/dist/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
  177. package/dist/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
  178. package/dist/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
  179. package/dist/templates/native-go/backend/internal/helper/native_identity.go +89 -0
  180. package/dist/templates/native-go/backend/internal/helper/native_provider.go +159 -0
  181. package/dist/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
  182. package/dist/templates/native-go/backend/internal/helper/observation.go +204 -0
  183. package/dist/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
  184. package/dist/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
  185. package/dist/templates/native-go/backend/internal/helper/observation_test.go +196 -0
  186. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
  187. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
  188. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
  189. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
  190. package/dist/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
  191. package/dist/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
  192. package/dist/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
  193. package/dist/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
  194. package/dist/templates/native-go/backend/internal/helper/peer_linux.go +44 -0
  195. package/dist/templates/native-go/backend/internal/helper/peer_other.go +7 -0
  196. package/dist/templates/native-go/backend/internal/helper/process_linux.go +177 -0
  197. package/dist/templates/native-go/backend/internal/helper/process_other.go +5 -0
  198. package/dist/templates/native-go/backend/internal/helper/publication_test.go +178 -0
  199. package/dist/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
  200. package/dist/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
  201. package/dist/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
  202. package/dist/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
  203. package/dist/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
  204. package/dist/templates/native-go/backend/internal/helper/readonly.go +105 -0
  205. package/dist/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
  206. package/dist/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
  207. package/dist/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
  208. package/dist/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
  209. package/dist/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
  210. package/dist/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
  211. package/dist/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
  212. package/dist/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
  213. package/dist/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
  214. package/dist/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
  215. package/dist/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
  216. package/dist/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
  217. package/dist/templates/native-go/backend/internal/helper/repair.go +132 -0
  218. package/dist/templates/native-go/backend/internal/helper/repair_test.go +271 -0
  219. package/dist/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
  220. package/dist/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
  221. package/dist/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
  222. package/dist/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
  223. package/dist/templates/native-go/backend/internal/helper/server_linux.go +124 -0
  224. package/dist/templates/native-go/backend/internal/helper/status.go +334 -0
  225. package/dist/templates/native-go/backend/internal/helper/status_test.go +288 -0
  226. package/dist/templates/native-go/backend/internal/helper/supervision.go +107 -0
  227. package/dist/templates/native-go/backend/internal/helper/supervision_test.go +124 -0
  228. package/dist/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
  229. package/dist/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
  230. package/dist/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
  231. package/dist/templates/native-go/backend/internal/helper/supervisor_linux.go +363 -0
  232. package/dist/templates/native-go/backend/internal/helper/supervisor_linux_test.go +913 -0
  233. package/dist/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
  234. package/dist/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
  235. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
  236. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
  237. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
  238. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
  239. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
  240. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
  241. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
  242. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
  243. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
  244. package/dist/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
  245. package/dist/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
  246. package/dist/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
  247. package/dist/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
  248. package/dist/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
  249. package/dist/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
  250. package/dist/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
  251. package/dist/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
  252. package/dist/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
  253. package/dist/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
  254. package/dist/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
  255. package/dist/templates/native-go/backend/internal/helper/write.go +77 -0
  256. package/dist/templates/native-go/backend/internal/helper/write_admission.go +260 -0
  257. package/dist/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
  258. package/dist/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
  259. package/dist/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
  260. package/dist/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
  261. package/dist/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
  262. package/dist/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
  263. package/dist/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
  264. package/dist/templates/native-go/backend/internal/helper/write_test.go +53 -0
  265. package/dist/templates/native-go/dsm-package.yaml +58 -0
  266. package/dist/templates/native-go/gitignore +1 -0
  267. package/dist/templates/native-go/i18n/glossary.json +662 -0
  268. package/dist/templates/native-go/i18n/messages/de.json +28 -0
  269. package/dist/templates/native-go/i18n/messages/en.json +28 -0
  270. package/dist/templates/native-go/i18n/messages/es.json +28 -0
  271. package/dist/templates/native-go/i18n/messages/fr.json +28 -0
  272. package/dist/templates/native-go/i18n/messages/it.json +28 -0
  273. package/dist/templates/native-go/i18n/messages/ja.json +28 -0
  274. package/dist/templates/native-go/i18n/messages/ko.json +28 -0
  275. package/dist/templates/native-go/i18n/messages/zh-CN.json +28 -0
  276. package/dist/templates/native-go/i18n/messages/zh-TW.json +28 -0
  277. package/dist/templates/native-go/ui/app.css +35 -0
  278. package/dist/templates/native-go/ui/app.js +101 -0
  279. package/dist/templates/native-go-better-auth/backend/internal/app/identity.go +208 -0
  280. package/dist/templates/native-go-better-auth/backend/internal/app/identity_test.go +113 -0
  281. package/dist/templates/native-go-better-auth/node/app.mjs +72 -0
  282. package/dist/templates/native-go-better-auth/node/build.mjs +4 -0
  283. package/dist/templates/native-go-better-auth/node/package-lock.json +862 -0
  284. package/dist/templates/native-go-better-auth/node/package.json +1 -0
  285. package/dist/templates/native-go-better-auth/node/test/auth.test.mjs +31 -0
  286. package/dist/templates/native-go-integration/backend/internal/app/identity_none.go +6 -0
  287. package/dist/templates/native-go-integration/backend/internal/app/personal.go +203 -0
  288. package/dist/templates/native-go-integration/backend/internal/app/personal_test.go +119 -0
  289. package/dist/templates/native-go-root/backend/internal/app/root.go +107 -0
  290. package/dist/templates/native-go-root/backend/internal/app/root_test.go +124 -0
  291. package/dist/templates/native-go-root/root/whoami.sh +6 -0
  292. package/dist/templates/native-go-vue/README.md +224 -0
  293. package/dist/templates/native-go-vue/frontend/DESIGN.md +78 -0
  294. package/dist/templates/native-go-vue/frontend/package-lock.json +2410 -0
  295. package/dist/templates/native-go-vue/frontend/package.json +6 -0
  296. package/dist/templates/native-go-vue/frontend/src/App.vue +159 -0
  297. package/dist/templates/native-go-vue/frontend/src/context.ts +56 -0
  298. package/dist/templates/native-go-vue/frontend/src/main.ts +29 -0
  299. package/dist/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
  300. package/dist/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
  301. package/dist/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
  302. package/dist/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
  303. package/dist/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
  304. package/dist/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
  305. package/dist/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
  306. package/dist/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
  307. package/dist/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
  308. package/dist/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
  309. package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
  310. package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
  311. package/dist/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
  312. package/dist/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
  313. package/dist/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
  314. package/dist/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
  315. package/dist/templates/native-go-vue/frontend/src/style.css +31 -0
  316. package/dist/templates/native-go-vue/frontend/test/apps.test.ts +190 -0
  317. package/dist/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
  318. package/dist/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
  319. package/dist/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
  320. package/dist/templates/native-go-vue/frontend/tsconfig.json +1 -0
  321. package/dist/templates/native-go-vue/frontend/vite.config.ts +10 -0
  322. package/dist/templates/native-go-vue/gitignore +2 -0
  323. package/dist/types.d.ts +1 -1
  324. package/dist/validate.js +11 -7
  325. package/package.json +5 -8
  326. package/schema/synology-app.schema.json +36 -37
  327. package/skills/SKILL.md +4 -48
  328. package/skills/reference/create.md +11 -83
  329. package/skills/reference/deploy.md +7 -78
  330. package/skills/reference/diagnose.md +4 -101
  331. package/skills/reference/files.md +5 -41
  332. package/skills/reference/identity.md +3 -29
  333. package/skills/reference/wrap.md +0 -2
  334. package/templates/_daemon/fixture_linux_test.go +15 -0
  335. package/templates/_daemon/fixture_other_test.go +7 -0
  336. package/templates/_daemon/go.mod +3 -0
  337. package/templates/_daemon/main.go +608 -0
  338. package/templates/_daemon/main_test.go +242 -0
  339. package/templates/_daemon/process_linux.go +55 -0
  340. package/templates/_daemon/process_linux_test.go +161 -0
  341. package/templates/_daemon/process_other.go +14 -0
  342. package/templates/_daemon/testdata/child.go +41 -0
  343. package/templates/_shared/GO-LICENSE +27 -0
  344. package/templates/_shared/GO-PATENTS +22 -0
  345. package/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
  346. package/templates/_shared/notice-overrides/index.json +14 -0
  347. package/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
  348. package/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
  349. package/templates/_shared/third-party-notices.mjs +51 -0
  350. package/templates/binary/synology-app.yaml +7 -0
  351. package/templates/hello-files/compose.yaml +0 -1
  352. package/templates/hello-web/compose.yaml +13 -10
  353. package/templates/hello-web/html/app.js +1 -23
  354. package/templates/hello-web/html/index.html +1 -3
  355. package/templates/hello-web-page/compose.yaml +13 -10
  356. package/templates/hello-web-page/html/app.js +1 -23
  357. package/templates/hello-web-page/html/index.html +1 -3
  358. package/templates/native-go/README.md +324 -0
  359. package/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
  360. package/templates/native-go/backend/cmd/app/main.go +49 -0
  361. package/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
  362. package/templates/native-go/backend/cmd/helper/main.go +38 -0
  363. package/templates/native-go/backend/go.mod +7 -0
  364. package/templates/native-go/backend/go.sum +4 -0
  365. package/templates/native-go/backend/internal/api/binary.go +154 -0
  366. package/templates/native-go/backend/internal/api/binary_test.go +165 -0
  367. package/templates/native-go/backend/internal/api/errors.go +33 -0
  368. package/templates/native-go/backend/internal/api/registry.go +104 -0
  369. package/templates/native-go/backend/internal/api/registry_test.go +329 -0
  370. package/templates/native-go/backend/internal/api/server.go +159 -0
  371. package/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
  372. package/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
  373. package/templates/native-go/backend/internal/app/root_none.go +9 -0
  374. package/templates/native-go/backend/internal/app/routes.go +138 -0
  375. package/templates/native-go/backend/internal/app/routes_test.go +172 -0
  376. package/templates/native-go/backend/internal/dsm/auth.go +118 -0
  377. package/templates/native-go/backend/internal/dsm/auth_test.go +139 -0
  378. package/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
  379. package/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
  380. package/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
  381. package/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
  382. package/templates/native-go/backend/internal/helper/cohort.go +393 -0
  383. package/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
  384. package/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
  385. package/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
  386. package/templates/native-go/backend/internal/helper/control.go +424 -0
  387. package/templates/native-go/backend/internal/helper/control_test.go +250 -0
  388. package/templates/native-go/backend/internal/helper/data_contract.go +242 -0
  389. package/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
  390. package/templates/native-go/backend/internal/helper/data_decode.go +184 -0
  391. package/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
  392. package/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
  393. package/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
  394. package/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
  395. package/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
  396. package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
  397. package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
  398. package/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
  399. package/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
  400. package/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
  401. package/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
  402. package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
  403. package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
  404. package/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
  405. package/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
  406. package/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
  407. package/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
  408. package/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
  409. package/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
  410. package/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
  411. package/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
  412. package/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
  413. package/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
  414. package/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
  415. package/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
  416. package/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
  417. package/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
  418. package/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
  419. package/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
  420. package/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
  421. package/templates/native-go/backend/internal/helper/lease.go +112 -0
  422. package/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
  423. package/templates/native-go/backend/internal/helper/lease_other.go +8 -0
  424. package/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
  425. package/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
  426. package/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
  427. package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
  428. package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
  429. package/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
  430. package/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
  431. package/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
  432. package/templates/native-go/backend/internal/helper/native_identity.go +89 -0
  433. package/templates/native-go/backend/internal/helper/native_provider.go +159 -0
  434. package/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
  435. package/templates/native-go/backend/internal/helper/observation.go +204 -0
  436. package/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
  437. package/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
  438. package/templates/native-go/backend/internal/helper/observation_test.go +196 -0
  439. package/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
  440. package/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
  441. package/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
  442. package/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
  443. package/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
  444. package/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
  445. package/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
  446. package/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
  447. package/templates/native-go/backend/internal/helper/peer_linux.go +44 -0
  448. package/templates/native-go/backend/internal/helper/peer_other.go +7 -0
  449. package/templates/native-go/backend/internal/helper/process_linux.go +177 -0
  450. package/templates/native-go/backend/internal/helper/process_other.go +5 -0
  451. package/templates/native-go/backend/internal/helper/publication_test.go +178 -0
  452. package/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
  453. package/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
  454. package/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
  455. package/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
  456. package/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
  457. package/templates/native-go/backend/internal/helper/readonly.go +105 -0
  458. package/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
  459. package/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
  460. package/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
  461. package/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
  462. package/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
  463. package/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
  464. package/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
  465. package/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
  466. package/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
  467. package/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
  468. package/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
  469. package/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
  470. package/templates/native-go/backend/internal/helper/repair.go +132 -0
  471. package/templates/native-go/backend/internal/helper/repair_test.go +271 -0
  472. package/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
  473. package/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
  474. package/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
  475. package/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
  476. package/templates/native-go/backend/internal/helper/server_linux.go +124 -0
  477. package/templates/native-go/backend/internal/helper/status.go +334 -0
  478. package/templates/native-go/backend/internal/helper/status_test.go +288 -0
  479. package/templates/native-go/backend/internal/helper/supervision.go +107 -0
  480. package/templates/native-go/backend/internal/helper/supervision_test.go +124 -0
  481. package/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
  482. package/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
  483. package/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
  484. package/templates/native-go/backend/internal/helper/supervisor_linux.go +363 -0
  485. package/templates/native-go/backend/internal/helper/supervisor_linux_test.go +913 -0
  486. package/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
  487. package/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
  488. package/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
  489. package/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
  490. package/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
  491. package/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
  492. package/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
  493. package/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
  494. package/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
  495. package/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
  496. package/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
  497. package/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
  498. package/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
  499. package/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
  500. package/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
  501. package/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
  502. package/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
  503. package/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
  504. package/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
  505. package/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
  506. package/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
  507. package/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
  508. package/templates/native-go/backend/internal/helper/write.go +77 -0
  509. package/templates/native-go/backend/internal/helper/write_admission.go +260 -0
  510. package/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
  511. package/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
  512. package/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
  513. package/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
  514. package/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
  515. package/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
  516. package/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
  517. package/templates/native-go/backend/internal/helper/write_test.go +53 -0
  518. package/templates/native-go/dsm-package.yaml +58 -0
  519. package/templates/native-go/gitignore +1 -0
  520. package/templates/native-go/i18n/glossary.json +662 -0
  521. package/templates/native-go/i18n/messages/de.json +28 -0
  522. package/templates/native-go/i18n/messages/en.json +28 -0
  523. package/templates/native-go/i18n/messages/es.json +28 -0
  524. package/templates/native-go/i18n/messages/fr.json +28 -0
  525. package/templates/native-go/i18n/messages/it.json +28 -0
  526. package/templates/native-go/i18n/messages/ja.json +28 -0
  527. package/templates/native-go/i18n/messages/ko.json +28 -0
  528. package/templates/native-go/i18n/messages/zh-CN.json +28 -0
  529. package/templates/native-go/i18n/messages/zh-TW.json +28 -0
  530. package/templates/native-go/ui/app.css +35 -0
  531. package/templates/native-go/ui/app.js +101 -0
  532. package/templates/native-go-better-auth/backend/internal/app/identity.go +208 -0
  533. package/templates/native-go-better-auth/backend/internal/app/identity_test.go +113 -0
  534. package/templates/native-go-better-auth/node/app.mjs +72 -0
  535. package/templates/native-go-better-auth/node/build.mjs +4 -0
  536. package/templates/native-go-better-auth/node/package-lock.json +862 -0
  537. package/templates/native-go-better-auth/node/package.json +1 -0
  538. package/templates/native-go-better-auth/node/test/auth.test.mjs +31 -0
  539. package/templates/native-go-integration/backend/internal/app/identity_none.go +6 -0
  540. package/templates/native-go-integration/backend/internal/app/personal.go +203 -0
  541. package/templates/native-go-integration/backend/internal/app/personal_test.go +119 -0
  542. package/templates/native-go-root/backend/internal/app/root.go +107 -0
  543. package/templates/native-go-root/backend/internal/app/root_test.go +124 -0
  544. package/templates/native-go-root/root/whoami.sh +6 -0
  545. package/templates/native-go-vue/README.md +224 -0
  546. package/templates/native-go-vue/frontend/DESIGN.md +78 -0
  547. package/templates/native-go-vue/frontend/package-lock.json +2410 -0
  548. package/templates/native-go-vue/frontend/package.json +6 -0
  549. package/templates/native-go-vue/frontend/src/App.vue +159 -0
  550. package/templates/native-go-vue/frontend/src/context.ts +56 -0
  551. package/templates/native-go-vue/frontend/src/main.ts +29 -0
  552. package/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
  553. package/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
  554. package/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
  555. package/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
  556. package/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
  557. package/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
  558. package/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
  559. package/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
  560. package/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
  561. package/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
  562. package/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
  563. package/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
  564. package/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
  565. package/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
  566. package/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
  567. package/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
  568. package/templates/native-go-vue/frontend/src/style.css +31 -0
  569. package/templates/native-go-vue/frontend/test/apps.test.ts +190 -0
  570. package/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
  571. package/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
  572. package/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
  573. package/templates/native-go-vue/frontend/tsconfig.json +1 -0
  574. package/templates/native-go-vue/frontend/vite.config.ts +10 -0
  575. package/templates/native-go-vue/gitignore +2 -0
  576. package/dist/attestation/app-package.d.ts +0 -86
  577. package/dist/attestation/app-package.js +0 -206
  578. package/dist/attestation/install-on-host.d.ts +0 -14
  579. package/dist/attestation/install-on-host.js +0 -52
  580. package/dist/attestation/keyring.d.ts +0 -21
  581. package/dist/attestation/keyring.js +0 -168
  582. package/dist/attestation/platform-service.d.ts +0 -70
  583. package/dist/attestation/platform-service.js +0 -250
  584. package/dist/build-spk/broker-glue.d.ts +0 -16
  585. package/dist/build-spk/broker-glue.js +0 -40
  586. package/dist/deploy/catalog-publish.d.ts +0 -3
  587. package/dist/deploy/catalog-publish.js +0 -7
  588. package/dist/doctor.d.ts +0 -22
  589. package/dist/doctor.js +0 -822
  590. package/dist/error-collector.d.ts +0 -2
  591. package/dist/error-collector.js +0 -46
  592. package/dist/host/broker-paths.d.ts +0 -1
  593. package/dist/host/broker-paths.js +0 -1
  594. package/dist/host/broker-upgrade-preflight.d.ts +0 -61
  595. package/dist/host/broker-upgrade-preflight.js +0 -156
  596. package/dist/host/digests.d.ts +0 -5
  597. package/dist/host/digests.js +0 -63
  598. package/dist/host/fake-nas.d.ts +0 -49
  599. package/dist/host/fake-nas.js +0 -193
  600. package/dist/mock-broker/bootstrap.d.ts +0 -2
  601. package/dist/mock-broker/bootstrap.js +0 -8
  602. package/dist/mock-broker/files.d.ts +0 -60
  603. package/dist/mock-broker/files.js +0 -408
  604. package/dist/mock-broker/oidc.d.ts +0 -31
  605. package/dist/mock-broker/oidc.js +0 -161
  606. package/dist/mock-broker/path.d.ts +0 -9
  607. package/dist/mock-broker/path.js +0 -50
  608. package/dist/mock-broker/server.d.ts +0 -19
  609. package/dist/mock-broker/server.js +0 -350
  610. package/dist/publish/build-ledger.d.ts +0 -22
  611. package/dist/publish/build-ledger.js +0 -26
  612. package/dist/publish/community-path.d.ts +0 -6
  613. package/dist/publish/community-path.js +0 -41
  614. package/dist/publish/curated-release.d.ts +0 -78
  615. package/dist/publish/curated-release.js +0 -883
  616. package/dist/publish/file-build-ledger.d.ts +0 -18
  617. package/dist/publish/file-build-ledger.js +0 -268
  618. package/dist/publish/github-pr.d.ts +0 -25
  619. package/dist/publish/github-pr.js +0 -85
  620. package/dist/publish/github-repo.d.ts +0 -8
  621. package/dist/publish/github-repo.js +0 -21
  622. package/dist/publish/platform-service-release.d.ts +0 -60
  623. package/dist/publish/platform-service-release.js +0 -333
  624. package/dist/publish/preflight.d.ts +0 -24
  625. package/dist/publish/preflight.js +0 -138
  626. package/dist/publish/publish.d.ts +0 -27
  627. package/dist/publish/publish.js +0 -136
  628. package/dist/publish/sync-definition.d.ts +0 -4
  629. package/dist/publish/sync-definition.js +0 -48
  630. package/dist/release-bin.d.ts +0 -2
  631. package/dist/release-bin.js +0 -23
  632. package/dist/templates/hello-web/html/sdk.js +0 -68
  633. package/dist/templates/hello-web-page/html/sdk.js +0 -68
  634. package/dist/templates/native/synology-app.yaml +0 -7
  635. package/dist/test-host.d.ts +0 -15
  636. package/dist/test-host.js +0 -37
  637. package/templates/hello-web/html/sdk.js +0 -68
  638. package/templates/hello-web-page/html/sdk.js +0 -68
  639. package/templates/native/synology-app.yaml +0 -7
  640. /package/dist/templates/{native → binary}/native.yaml +0 -0
  641. /package/templates/{native → binary}/native.yaml +0 -0
@@ -0,0 +1,51 @@
1
+ import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+
4
+ // Conservative inventory of every locked production dependency, including
5
+ // dependencies tree-shaken from the bundle. Build tools marked dev are omitted.
6
+ // Read actual upstream license/notice files, never synthesize license text from
7
+ // SPDX metadata. npm ci must have installed the exact lock before this runs.
8
+ export function writeThirdPartyNotices(root, output, { ui = false } = {}) {
9
+ const lock = JSON.parse(readFileSync(join(root, 'package-lock.json'), 'utf8'));
10
+ if (lock.lockfileVersion < 2 || !lock.packages) throw new Error('Notice generation requires a v2/v3 npm lockfile');
11
+ const inventory = [];
12
+ const sections = [];
13
+ let uiFiles;
14
+ for (const [path, entry] of Object.entries(lock.packages).sort(([a], [b]) => a.localeCompare(b, 'en'))) {
15
+ if (!path || entry.dev) continue;
16
+ if (!/^node_modules\//.test(path) || path.split('/').includes('..') || entry.link) throw new Error(`Unsupported notice package path: ${path}`);
17
+ const dir = join(root, path);
18
+ const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8'));
19
+ if (pkg.version !== entry.version) throw new Error(`Notice version mismatch: ${path}; run npm ci`);
20
+ const files = readdirSync(dir, { withFileTypes: true })
21
+ .filter(f => f.isFile() && /^(licen[sc]e|copying|notice|copyright)([.-]|$)/i.test(f.name))
22
+ .map(f => f.name).sort();
23
+ const texts = files.map(file => ({ file, text: readFileSync(join(dir, file), 'utf8') }));
24
+ let source, provenance;
25
+ if (!files.some(f => /^(licen[sc]e|copying)([.-]|$)/i.test(f))) {
26
+ const index = new URL('./notice-overrides/index.json', import.meta.url);
27
+ const overrides = existsSync(index) ? JSON.parse(readFileSync(index, 'utf8')) : {};
28
+ const override = overrides[`${pkg.name}@${pkg.version}`];
29
+ if (!override || !entry.integrity || override.integrity !== entry.integrity) throw new Error(`Missing upstream license text: ${pkg.name}@${pkg.version}`);
30
+ source = override.source;
31
+ provenance = override.provenance;
32
+ texts.push({file: 'LICENSE (pinned upstream source)', text: readFileSync(new URL(`./notice-overrides/${override.file}`, import.meta.url), 'utf8')});
33
+ files.push(override.file);
34
+ }
35
+ // UI ships its own aggregate for fonts, icons and dependencies/assets.
36
+ if (pkg.name === '@synopackageland/ui') {
37
+ uiFiles = {
38
+ 'UI-LICENSE': readFileSync(join(dir, 'LICENSE'), 'utf8'),
39
+ 'UI-THIRD_PARTY.md': readFileSync(join(dir, 'LICENSES/THIRD_PARTY.md'), 'utf8'),
40
+ };
41
+ }
42
+ inventory.push({ name: pkg.name, version: pkg.version, license: pkg.license ?? entry.license ?? 'unknown', integrity: entry.integrity, path, files, ...(source ? {source, provenance} : {}) });
43
+ sections.push(`\n===== ${pkg.name}@${pkg.version} (${pkg.license ?? entry.license ?? 'unknown'}) =====\n` + (source ? `Source: ${source}\n${provenance}\n` : '') + texts.map(({ file, text }) => `\n--- ${file} ---\n${text}\n`).join(''));
44
+ }
45
+ if (ui && !uiFiles) throw new Error('UI dependency is missing from the locked production inventory');
46
+ rmSync(output, { recursive: true, force: true });
47
+ mkdirSync(output, { recursive: true });
48
+ writeFileSync(join(output, 'THIRD_PARTY_NOTICES.txt'), 'Locked production dependency notices (conservative superset of bundled code).\n' + sections.join(''));
49
+ writeFileSync(join(output, 'inventory.json'), JSON.stringify(inventory, null, 2) + '\n');
50
+ for (const [name, text] of Object.entries(uiFiles ?? {})) writeFileSync(join(output, name), text);
51
+ }
@@ -0,0 +1,7 @@
1
+ schema: 1
2
+ package: com.example.binary-app
3
+ version: 0.1.0
4
+ displayname: Binary App
5
+ description: A minimal Syno Package Land app that runs one prebuilt binary.
6
+ maintainer: Syno Package Land
7
+ os_min_ver: "7.2-60000"
@@ -3,7 +3,6 @@ services:
3
3
  image: alpine:3.20
4
4
  command: ["sleep", "infinity"]
5
5
  volumes:
6
- # Dynamic Shared Folder plus writable /state is Broker-managed and is
7
6
  # intentionally outside the zero-config docker-project resource-worker path.
8
7
  - "${MEDIA_SHARE}/data:/data:ro"
9
8
  - "${SYNOPKG_PKGVAR}/state:/state"
@@ -1,16 +1,19 @@
1
1
  services:
2
2
  web:
3
3
  image: busybox:1.36
4
- # 兩個平台限制,改動前先看 docs/impl/STATUS.md 的 2026-08-24 段:
5
- # 1) command/entrypoint 陣列不得有純數字元素(例如 "18333")。DSM 的
6
- # docker-project worker 會在 YAML round-trip 時掉引號、把它變成整數,
7
- # postinst acquire 直接失敗(error 276 → 套件 broken/150,且 worker_msg
8
- # 為空,開發者看不到原因)。所以 port 要包在單一字串裡。
9
- # `synopkgland validate` 已會擋這個寫法。
10
- # 2) 預設不用 8080:那個 port 在真實 NAS 上很常被既有容器占用,而 port
11
- # 衝突同樣以那個看不出原因的 broken/150 呈現。
12
- # 官方 nginx image 也不能用:resource worker 注入任意 package UID/GID,
13
- # nginx entrypoint 啟動階段需要 root,會在該身分下直接退出。
4
+ # DSM worker constraints to preserve when changing this service:
5
+ # 1) command/entrypoint arrays must not contain bare numeric elements
6
+ # (such as "18333"). DSM's docker-project worker drops the quotes on a
7
+ # YAML round-trip and turns them into integers, so postinst acquire
8
+ # fails (error 276 -> package broken/150, with an empty worker_msg that
9
+ # tells the developer nothing). Keep the port inside one string.
10
+ # `synopkgland validate` already rejects the bare form.
11
+ # 2) The default is not 8080: that port is often taken by an existing
12
+ # container on a real NAS, and the conflict shows up as the same
13
+ # unexplained broken/150.
14
+ # The official nginx image cannot be used either: the resource worker
15
+ # injects an arbitrary package UID/GID, and the nginx entrypoint needs
16
+ # root during startup, so it exits immediately under that identity.
14
17
  command: ["sh","-c","httpd -f -p 18333 -h /usr/share/nginx/html"]
15
18
  ports:
16
19
  - "18333:18333"
@@ -1,23 +1 @@
1
- import { createSynologyClient } from "./sdk.js";
2
-
3
- const status = document.getElementById("status");
4
- const userEl = document.getElementById("user");
5
-
6
- const client = createSynologyClient();
7
-
8
- try {
9
- await client.auth.requireLogin();
10
- const user = await client.auth.getCurrentUser();
11
- if (status) {
12
- status.textContent = "Signed in with DSM";
13
- }
14
- if (userEl) {
15
- userEl.textContent = user.username;
16
- }
17
- } catch (error) {
18
- const code = error && typeof error === "object" && "code" in error ? String(error.code) : "";
19
- const message = error instanceof Error ? error.message : String(error);
20
- if (status) {
21
- status.textContent = code === "UNAUTHENTICATED" ? "DSM login required" : message;
22
- }
23
- }
1
+ document.getElementById("status").textContent = "Your app is running.";
@@ -7,9 +7,7 @@
7
7
  </head>
8
8
  <body>
9
9
  <h1>Hello Web</h1>
10
- <p id="status">Opening with your DSM session…</p>
11
- <p id="user"></p>
12
- <script src="./bootstrap.js"></script>
10
+ <p id="status">Loading…</p>
13
11
  <script type="module" src="./app.js"></script>
14
12
  </body>
15
13
  </html>
@@ -1,16 +1,19 @@
1
1
  services:
2
2
  web:
3
3
  image: busybox:1.36
4
- # 兩個平台限制,改動前先看 docs/impl/STATUS.md 的 2026-08-24 段:
5
- # 1) command/entrypoint 陣列不得有純數字元素(例如 "18333")。DSM 的
6
- # docker-project worker 會在 YAML round-trip 時掉引號、把它變成整數,
7
- # postinst acquire 直接失敗(error 276 → 套件 broken/150,且 worker_msg
8
- # 為空,開發者看不到原因)。所以 port 要包在單一字串裡。
9
- # `synopkgland validate` 已會擋這個寫法。
10
- # 2) 預設不用 8080:那個 port 在真實 NAS 上很常被既有容器占用,而 port
11
- # 衝突同樣以那個看不出原因的 broken/150 呈現。
12
- # 官方 nginx image 也不能用:resource worker 注入任意 package UID/GID,
13
- # nginx entrypoint 啟動階段需要 root,會在該身分下直接退出。
4
+ # DSM worker constraints to preserve when changing this service:
5
+ # 1) command/entrypoint arrays must not contain bare numeric elements
6
+ # (such as "18333"). DSM's docker-project worker drops the quotes on a
7
+ # YAML round-trip and turns them into integers, so postinst acquire
8
+ # fails (error 276 -> package broken/150, with an empty worker_msg that
9
+ # tells the developer nothing). Keep the port inside one string.
10
+ # `synopkgland validate` already rejects the bare form.
11
+ # 2) The default is not 8080: that port is often taken by an existing
12
+ # container on a real NAS, and the conflict shows up as the same
13
+ # unexplained broken/150.
14
+ # The official nginx image cannot be used either: the resource worker
15
+ # injects an arbitrary package UID/GID, and the nginx entrypoint needs
16
+ # root during startup, so it exits immediately under that identity.
14
17
  command: ["sh","-c","httpd -f -p 18333 -h /usr/share/nginx/html"]
15
18
  ports:
16
19
  - "18333:18333"
@@ -1,23 +1 @@
1
- import { createSynologyClient } from "./sdk.js";
2
-
3
- const status = document.getElementById("status");
4
- const userEl = document.getElementById("user");
5
-
6
- const client = createSynologyClient();
7
-
8
- try {
9
- await client.auth.requireLogin();
10
- const user = await client.auth.getCurrentUser();
11
- if (status) {
12
- status.textContent = "Signed in with DSM";
13
- }
14
- if (userEl) {
15
- userEl.textContent = user.username;
16
- }
17
- } catch (error) {
18
- const code = error && typeof error === "object" && "code" in error ? String(error.code) : "";
19
- const message = error instanceof Error ? error.message : String(error);
20
- if (status) {
21
- status.textContent = code === "UNAUTHENTICATED" ? "DSM login required" : message;
22
- }
23
- }
1
+ document.getElementById("status").textContent = "Your app is running.";
@@ -7,9 +7,7 @@
7
7
  </head>
8
8
  <body>
9
9
  <h1>Hello Web Page</h1>
10
- <p id="status">Opening with your DSM session…</p>
11
- <p id="user"></p>
12
- <script src="./bootstrap.js"></script>
10
+ <p id="status">Loading…</p>
13
11
  <script type="module" src="./app.js"></script>
14
12
  </body>
15
13
  </html>
@@ -0,0 +1,324 @@
1
+ # __DISPLAY_NAME__
2
+
3
+ A native DSM package (`__PACKAGE__`): a Go backend that DSM runs as a CGI,
4
+ and a UI that opens in its own DSM window. It installs as an **unsigned** SPK,
5
+ runs as its own DSM package account, needs no containers, and has no root by default.
6
+
7
+ ```text
8
+ DSM main menu → DSM window (ui/app.js)
9
+ │ ctx.call("greeting.get") same-origin POST + DSM session
10
+ ▼
11
+ /webman/3rdparty/__PACKAGE__/cgi/api.cgi (backend/, runs as package user)
12
+ 1. transport guards: POST, JSON, same origin, ≤ 1 MiB
13
+ 2. one DSM authentication (unless the route is Public)
14
+ 3. route policy: User or Admin → refusal before any handler
15
+ 4. your handler (backend/internal/app)
16
+ ```
17
+
18
+ ## Quick start
19
+
20
+ Needs Node.js with `synopkgland` installed, and Go 1.24+.
21
+
22
+ ```bash
23
+ (cd backend && go test ./...) # auth policy + route tests
24
+ synopkgland build-spk # → dist/__PACKAGE__-0.1.0-0001-{x86_64,aarch64}.spk
25
+ synopkgland inspect --spk dist/__PACKAGE__-0.1.0-0001-x86_64.spk
26
+ ```
27
+
28
+ Install: Package Center → Settings → General → Trust Level "Any publisher",
29
+ then Manual Install with the SPK for your NAS's CPU. Open
30
+ **__DISPLAY_NAME__** from the DSM main menu: it shows who you are signed in
31
+ as, what the backend reports, and (for administrators) a form that stores a
32
+ greeting in the package's data folder.
33
+
34
+ ## Project layout
35
+
36
+ | Path | What it is | Edit it? |
37
+ | --- | --- | --- |
38
+ | `dsm-package.yaml` | Package identity, version/build, arches, where backend and UI come from | Yes |
39
+ | `ui/app.js`, `ui/app.css` | The app inside the DSM window | Yes — your UI |
40
+ | `ui/…` | Any other assets; served from `/webman/3rdparty/__PACKAGE__/app/` | Yes |
41
+ | `i18n/messages/<locale>.json` | UI text in nine languages | Yes |
42
+ | `i18n/glossary.json` | Synology's official DSM terms, and which messages must use them | Add terms |
43
+ | `backend/internal/app/` | Your API: routes and handlers | Yes — your backend |
44
+ | `backend/internal/api/` | The CGI front door: guards, auth order, route policies | Rarely |
45
+ | `backend/internal/dsm/` | DSM session check and administrators lookup | Rarely |
46
+ | `backend/cmd/app/` | Wires the above together | Rarely |
47
+ | `dist/` | Built SPKs (ignored by git) | No |
48
+
49
+ `build-spk` generates everything else: `INFO`, `conf/privilege`
50
+ (`run-as: package`), no-op lifecycle scripts, icons, the DSM window wrapper
51
+ (`ui/config`, `ui/window-<build>.js`) and the CGI at `ui/cgi/api.cgi`.
52
+
53
+ ## Add an API operation
54
+
55
+ Add a route in `backend/internal/app/routes.go`. The policy is part of the
56
+ route, so you cannot register a handler without one:
57
+
58
+ ```go
59
+ func Routes(cfg Config) []api.Route {
60
+ return []api.Route{
61
+ api.User("app.status", cfg.status),
62
+ api.User("greeting.get", cfg.getGreeting),
63
+ api.Admin("greeting.set", cfg.setGreeting),
64
+ api.User("notes.list", cfg.listNotes), // new: any signed-in user
65
+ api.Admin("notes.purge", cfg.purgeNotes), // new: administrators only
66
+ }
67
+ }
68
+
69
+ func (cfg Config) listNotes(ctx context.Context, caller api.Caller, params json.RawMessage) (any, error) {
70
+ var in struct{ Limit int `json:"limit"` }
71
+ if err := decodeParams(params, &in); err != nil {
72
+ return nil, err
73
+ }
74
+ return map[string]any{"owner": caller.User(), "notes": []string{}}, nil
75
+ }
76
+ ```
77
+
78
+ Then add the method's valid params to `sampleParams` in `routes_test.go`; the
79
+ test fails until you do, and once you do it proves the new route refuses
80
+ callers without a session (and non-admins, for `api.Admin`) without touching
81
+ the data folder.
82
+
83
+ Call it from the UI with `ctx.call("notes.list", { limit: 20 })`. Errors
84
+ reject with `{ code, message }`, for example `session_required`,
85
+ `admin_required`, `bad_request` or `internal`.
86
+
87
+ ### Who can call what
88
+
89
+ | Declared with | No session | Signed-in user | Administrator |
90
+ | --- | --- | --- | --- |
91
+ | `api.User` | `session_required` | runs | runs |
92
+ | `api.Admin` | `session_required` | `admin_required` | runs |
93
+ | `api.Public` | runs | runs | runs |
94
+ | not registered | `session_required` | `unknown_method` | `unknown_method` |
95
+
96
+ Every reply, error or not, is HTTP 200 with `{"success": false, "error":
97
+ {"code", "message"}}` on failure, the same convention as DSM's own WebAPI.
98
+ DSM's web server replaces the body of any CGI reply with status 403, 404 or
99
+ 5xx by its own HTML error page, so a status-coded error would never reach your
100
+ UI.
101
+
102
+ - Handlers get an `api.Caller` the server built after authenticating; code
103
+ outside `internal/api` cannot construct an authenticated one.
104
+ - `api.Public` runs with **no** DSM login. Use it only for data you would show
105
+ anyone who can reach DSM's port; the template ships none.
106
+ - "Administrator" means a member of DSM's `administrators` group, read fresh
107
+ from `/etc/group` on every request.
108
+
109
+ ## How authentication works (and its limits)
110
+
111
+ The CGI hands only the session carriers (`Cookie`, `X-SYNO-TOKEN`, client
112
+ address) to DSM's own `/usr/syno/synoman/webman/modules/authenticate.cgi`,
113
+ which prints the signed-in user name. The backend never parses the session
114
+ cookie and never takes a user name or admin flag from the request.
115
+
116
+ Cross-site requests are refused: the API accepts only `POST` with
117
+ `Content-Type: application/json` (which forces a CORS preflight DSM never
118
+ approves), and it rejects `Sec-Fetch-Site` other than `same-origin` and any
119
+ foreign `Origin`. The DSM window wrapper sends DSM's `SynoToken`, but when DSM
120
+ has `enable_syno_token=no` that token proves nothing, so the same-origin
121
+ checks are what stop cross-site requests.
122
+
123
+ Known limits:
124
+
125
+ - Each request reuses the browser's DSM session; it does not carry DSM's
126
+ per-request `X-SYNO-HASH` proof. Verifying that proof needs private,
127
+ version-specific DSM libraries through a C bridge, so it is not part of this
128
+ template.
129
+ - Users from a directory service (LDAP/AD) who are administrators only
130
+ through directory groups are not listed in `/etc/group`, so they count as
131
+ ordinary users. This errs towards refusal.
132
+
133
+ ## Customize the UI
134
+
135
+ `ui/app.js` must register `window.DsmPackageApps[<package>].mount(root, ctx)`
136
+ (the template shows how, using `document.currentScript.dataset.package`).
137
+ `ctx.call(method, params)` is the only transport. `ctx.reopen(fn)` runs `fn`
138
+ whenever DSM shows the window again and returns an idempotent unsubscribe function. Scope your CSS under your own root class:
139
+ every DSM app shares one page.
140
+
141
+ Plain JS and Vue receive the same `ctx.host` adapter. `ctx.host.platform()`
142
+ returns a fresh frozen snapshot: `web`, `host` (`dsm`, `standalone-web` or
143
+ `unavailable`), `dsmStandalone`, `dsmLanguage`, `appLocale`, `systemVersion`,
144
+ `fullVersion`, and `theme`. Unknown fields are `null`; `theme` stays unknown.
145
+ DSM launch mode is separate from plain-web fallback, and `appLocale` is the
146
+ app's catalog locale, which may differ from DSM's UI language code.
147
+
148
+ ```js
149
+ const platform = ctx.host.platform();
150
+ const result = ctx.host.setTitle('My notes');
151
+ if (result.status !== 'ok') showTitleStatus(result.status);
152
+ ```
153
+
154
+ `setTitle` enables DSM HTML encoding or assigns standalone `document.title`.
155
+ It returns `{status: 'ok', target: 'dsm-window' | 'document'}` on synchronous
156
+ completion, or `unsupported`, `unavailable`, `invalid-input`, `failed` statuses.
157
+ A missing DSM method is unsupported; it never changes the DSM desktop's title.
158
+ Destroy disposes the adapter and clears reopen handlers; retained adapters
159
+ return unavailable. Navigation exposes activateWindow/requestClose/openApp/openURL;
160
+ requests do not acknowledge completion. `ctx.host.subscribe('window-resize', fn)`
161
+ returns `{status: 'subscribed', dispose}` only for a verified DSM window with on/un.
162
+ The callback receives no native arguments. Remove your subscriptions on unmount;
163
+ wrapper destroy also cleans them. `host-theme-change` and `host-language-change`
164
+ return unsupported: no third-party host event is proven. These observations do
165
+ not authorize work.
166
+
167
+ `ctx.host.openFileManager('/example-share/docs')` requests File Station folder
168
+ navigation; `revealFile('/home/report.txt')` requests a file highlight. Both require
169
+ a registered, enabled and launchable File Station and report requested plus action,
170
+ not location completion or ACL success. Use canonical virtual share paths only;
171
+ OS `/volumeN/...`, traversal, repeated/trailing slash, controls and backslash are
172
+ invalid. No path conversion or grant is performed. `openFile`, `showFileDetails`
173
+ and `openAppSetting` return unsupported; private preview/details/settings flows
174
+ have no proven generic contract. DSM runtime remains unknown.
175
+
176
+ For an independent browser shell, use the SPK's generated `ui/host-0001.js`
177
+ (the number follows the manifest build). It has no Ext or npm runtime dependency:
178
+
179
+ ```html
180
+ <script src="./host-0001.js"></script>
181
+ ```
182
+
183
+ ```js
184
+ // shellContext supplies your app's own auth/transport and other context members.
185
+ const ctx = {...shellContext, host: window.DsmPackageHosts.__PACKAGE__({locale: 'en'})};
186
+ const app = window.DsmPackageApps.__PACKAGE__.mount(root, ctx);
187
+ // When your shell unmounts:
188
+ ctx.host.dispose();
189
+ app.unmount();
190
+ ```
191
+
192
+ Serve the generated script with your shell (or reference its same-origin DSM
193
+ static path). `ctx.host` does not create a standalone backend, DSM session,
194
+ cross-origin iframe bridge, or implementations of `ctx.call/t/root/reopen`.
195
+ Standalone title affects the document shared by that shell's mounts.
196
+
197
+ To build the UI with Vite, Vue or React, point `ui` at the build output and
198
+ give the build command as an argv list (no shell):
199
+
200
+ ```yaml
201
+ ui:
202
+ dir: web/dist
203
+ build:
204
+ cwd: web
205
+ command: [npm, run, build]
206
+ ```
207
+
208
+ The build must emit `app.js` (one script that registers `mount`) and
209
+ `app.css`. The public `@synopackageland/ui@0.4.0` package on
210
+ `https://registry.npmjs.org` gives Vue components with DSM 7 styling;
211
+ import its `themes/dsm7-embedded.css` for use inside a DSM window.
212
+
213
+ ## Languages
214
+
215
+ The UI ships in nine of DSM's languages: `en`, `zh-TW`,
216
+ `zh-CN`, `ja`, `ko`, `de`, `fr`, `es` and `it`. DSM's other languages show
217
+ English. The window follows DSM's own language setting (`_S("lang")`).
218
+
219
+ - **Messages**: `i18n/messages/<locale>.json`, flat `"key": "text"`. Use
220
+ `ctx.t("greeting.setBy", { text, user })` in the UI; `{name}` is a
221
+ placeholder, and `ctx.t("files", { count: 3 })` picks `files.one` or
222
+ `files.other`. Missing keys fall back to English, then to the key itself.
223
+ `build-spk` embeds the catalogs in the DSM window script, so there is no
224
+ extra request.
225
+ - **Errors**: the backend returns a `code`; the UI shows
226
+ `error.<code>` from the catalogs and uses the backend's English text only for
227
+ codes it has no message for. Add `error.<code>` for every code you return.
228
+ - **Glossary**: `i18n/glossary.json` records DSM's own words in all nine
229
+ languages, each with its source (`section/key` in DSM 7.4's
230
+ `/usr/syno/synoman/webman/texts/<lang>/strings`). A term's `keys` lists the
231
+ messages that must contain it; that is how "Save" uses DSM's own word in
232
+ every language, the same as the rest of DSM. Product names in `untranslated`
233
+ stay in English everywhere.
234
+ - **Package Center text**: `i18n.info` in `dsm-package.yaml` writes INFO
235
+ `displayname_<lang>` / `description_<lang>` (for example `description_cht`).
236
+
237
+ `synopkgland validate` and `build-spk` refuse a language file with missing or
238
+ extra keys, a translation that drops a `{placeholder}`, an unsupported
239
+ language, or a listed message that drifts from the glossary.
240
+
241
+ To add a message: add the key to `en.json` and to the other eight files. To
242
+ use a DSM term, copy its `text` from the glossary and add your key to the
243
+ term's `keys`. A Vue or React UI can keep its own i18n library; `ctx.t` and
244
+ `ctx.locale` are there if you want them.
245
+
246
+ ## Package an existing binary
247
+
248
+ Keep the Go backend and call your tool from a handler (recommended: auth
249
+ stays central), or replace the CGI with your own executable:
250
+
251
+ ```yaml
252
+ arches: [x86_64]
253
+ backend:
254
+ binary:
255
+ x86_64: prebuilt/api-x86_64
256
+ ```
257
+
258
+ The file must be a regular file in the project, a 64-bit Linux ELF for that
259
+ arch, and statically linked (DSM models ship different libc versions). It is
260
+ installed as `ui/cgi/api.cgi` (mode 0755) and runs as the package account.
261
+ It then owns everything `backend/internal/api` does for you: bounded reads,
262
+ POST-only JSON, same-origin checks, authentication before any work, and a
263
+ refusal for unknown methods.
264
+
265
+ ## Data, upgrades, uninstall
266
+
267
+ The backend stores data in `/var/packages/__PACKAGE__/var` (the package's
268
+ own folder, kept across upgrades). Bump `build` for every SPK you hand out;
269
+ bump `version` for feature releases. There are no lifecycle scripts to write:
270
+ the CGI starts per request, so start/stop do nothing.
271
+
272
+ ## Root access
273
+
274
+ By default (`privilege: none`) nothing in this package ever runs as root, and
275
+ that is the right choice for almost every app. Lifecycle scripts and the CGI
276
+ run as the package account, and nothing the package account can write is ever
277
+ run as root.
278
+
279
+ If your app truly needs root for a few fixed actions, create the project with
280
+ `synopkgland init -t native-go --privilege root`. That sets `privilege: root`
281
+ and adds:
282
+
283
+ - `root/whoami.sh`: one root operation. Each `root/<name>.sh` (lowercase name,
284
+ `#!/bin/sh`, at most 16 KiB) is one operation. The demo only reports the
285
+ user ID it runs as (`{"euid":0}`). Replace it with your own fixed actions.
286
+ - `backend/internal/app/root.go`: the `root.output` route (administrators
287
+ only) that returns an operation's last result.
288
+
289
+ How it works, with no keys or signing involved:
290
+
291
+ 1. `build-spk` embeds each operation's exact task text in the DSM window. The
292
+ SPK payload carries no root script, and the package still runs as its own
293
+ account.
294
+ 2. The window shows an authorization panel above your app, in the user's
295
+ DSM language. A DSM administrator clicks **Authorize** and confirms with
296
+ their DSM password in DSM's own dialog. DSM then creates one **disabled**
297
+ root task in Task Scheduler, named `<package> root: <name>`. The
298
+ confirmation is used for that one task and never stored.
299
+ 3. **Run** checks that the task is still exactly the approved text, runs it
300
+ with the administrator's session and shows its result. The task writes
301
+ only to `/run/synopkgland-<package>/<name>.out`, which root owns and your
302
+ backend can only read.
303
+ 4. The task text includes the package version, so after an upgrade the panel
304
+ shows "needs authorization again" and the old task never runs. A
305
+ same-named task that the panel did not create is never run, replaced or
306
+ deleted.
307
+ 5. **Remove** deletes the task, also an outdated one, without asking for the
308
+ password. Remove it before uninstalling the package, because DSM keeps
309
+ Task Scheduler tasks after an uninstall.
310
+
311
+ Non-administrators see DSM's "Only administrator accounts can perform this
312
+ operation." and nothing else. HTTP requests can never choose what runs as
313
+ root: the only root code is the fixed text an administrator approved. Your app
314
+ can also use `ctx.root` (`state`, `authorize`, `run`, `remove`, `output`) to
315
+ drive the same flow from its own UI.
316
+
317
+ ## Support matrix
318
+
319
+ | | Status |
320
+ | --- | --- |
321
+ | Build hosts | macOS, Linux (any OS with Go and Node) |
322
+ | Target CPUs | x86_64 and aarch64 DSM models (one SPK each) |
323
+ | DSM | 7.2 or later declared (`os_min_ver`). Installed and tested on DSM 7.4 (x86_64). aarch64 SPKs are built the same way but have not been run on a NAS. |
324
+ | Not supported | 32-bit ARM, DSM 6, running anything as root without an administrator's approval |
@@ -0,0 +1,59 @@
1
+ DSM integration helper build dependencies
2
+
3
+ github.com/godbus/dbus/v5 v5.2.2 (BSD-2-Clause)
4
+
5
+ Copyright (c) 2013, Georg Reinke (<guelfey at gmail dot com>), Google
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright notice,
13
+ this list of conditions and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+ notice, this list of conditions and the following disclaimer in the
17
+ documentation and/or other materials provided with the distribution.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
25
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ golang.org/x/sys v0.27.0 (BSD-3-Clause)
32
+
33
+ Copyright 2009 The Go Authors.
34
+
35
+ Redistribution and use in source and binary forms, with or without
36
+ modification, are permitted provided that the following conditions are
37
+ met:
38
+
39
+ * Redistributions of source code must retain the above copyright
40
+ notice, this list of conditions and the following disclaimer.
41
+ * Redistributions in binary form must reproduce the above
42
+ copyright notice, this list of conditions and the following disclaimer
43
+ in the documentation and/or other materials provided with the
44
+ distribution.
45
+ * Neither the name of Google LLC nor the names of its
46
+ contributors may be used to endorse or promote products derived from
47
+ this software without specific prior written permission.
48
+
49
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
50
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
51
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
52
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
53
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
54
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
55
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
56
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
57
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
59
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,49 @@
1
+ // Command app is the package backend. DSM runs it as a CGI (ui/cgi/api.cgi in
2
+ // the package) under the package account, once per request.
3
+ package main
4
+
5
+ import (
6
+ "encoding/json"
7
+ "fmt"
8
+ "log"
9
+ "net/http/cgi"
10
+ "os"
11
+
12
+ "dsmapp/internal/api"
13
+ "dsmapp/internal/app"
14
+ "dsmapp/internal/dsm"
15
+ "dsmapp/internal/helper"
16
+ )
17
+
18
+ // Set by `synopkgland build-spk` through -ldflags -X; never read from a request.
19
+ var (
20
+ packageID = "dev"
21
+ version = "0.0.0"
22
+ helperInventory = ""
23
+ )
24
+
25
+ func main() {
26
+ log.SetFlags(0)
27
+ log.SetPrefix(packageID + ": ")
28
+ if os.Getenv("GATEWAY_INTERFACE") == "" {
29
+ fmt.Fprintf(os.Stderr, "%s %s: this program runs as the package's DSM CGI; open the app from the DSM main menu.\n", packageID, version)
30
+ os.Exit(2)
31
+ }
32
+ cfg := app.Config{
33
+ PackageID: packageID,
34
+ Version: version,
35
+ DataDir: "/var/packages/" + packageID + "/var",
36
+ }
37
+ if helperInventory != "" {
38
+ if json.Unmarshal([]byte(helperInventory), &cfg.HelperInventory) != nil || cfg.HelperInventory.Package != packageID || cfg.HelperInventory.Version != version {
39
+ cfg.HelperInventory = helper.Inventory{Package: packageID}
40
+ }
41
+ }
42
+ srv, err := api.NewServer(dsm.NewAuthenticator(), app.Routes(cfg)...)
43
+ if err != nil {
44
+ log.Fatal(err)
45
+ }
46
+ if err := cgi.Serve(srv); err != nil {
47
+ log.Fatal(err)
48
+ }
49
+ }