@synopackageland/cli 0.10.2 → 0.10.3
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.
- package/CHANGELOG.md +215 -1696
- package/README.md +21 -2
- package/assets/login-style/mask.png +0 -0
- package/assets/login-style/wallpaper-thumbnail.jpg +0 -0
- package/assets/login-style/wallpaper.jpg +0 -0
- package/dist/build-spk/generator.js +10 -1
- package/dist/build-spk/login-style.d.ts +55 -0
- package/dist/build-spk/login-style.js +115 -0
- package/dist/cli.js +22 -1
- package/dist/error-registry.js +37 -1
- package/dist/host/dsm-client.js +6 -9
- package/dist/init.js +9 -5
- package/dist/runtime/delegate-contract.d.ts +2 -92
- package/dist/runtime/delegate-contract.js +2 -24
- package/dist/runtime/executor-digests.json +11 -0
- package/dist/runtime/executor-policy-check.d.ts +1 -1
- package/dist/runtime/executor-policy-check.js +5 -7
- package/dist/runtime/executor-policy.d.ts +2 -0
- package/dist/runtime/executor-policy.js +5 -1
- package/dist/runtime/root-programs.d.ts +2 -0
- package/dist/runtime/sdk-source.d.ts +4 -0
- package/dist/runtime/sdk-source.js +7 -0
- package/dist/runtime/sdk-timeouts.d.ts +23 -0
- package/dist/runtime/sdk-timeouts.js +44 -0
- package/dist/skill.js +1 -0
- package/dist/standalone/app-scripts.d.ts +26 -0
- package/dist/standalone/app-scripts.js +141 -0
- package/dist/standalone/bridge-app.d.ts +2 -0
- package/dist/standalone/bridge-app.js +9 -1
- package/dist/standalone/bridge-backend.d.ts +1 -1
- package/dist/standalone/build.js +5 -2
- package/dist/standalone/dsm-window.d.ts +14 -3
- package/dist/standalone/dsm-window.js +24 -11
- package/dist/standalone/host-adapter.d.ts +1 -1
- package/dist/standalone/host-adapter.js +1 -1
- package/dist/standalone/host-file-navigation.d.ts +6 -2
- package/dist/standalone/host-file-navigation.js +8 -2
- package/dist/standalone/inspect-spk.d.ts +9 -0
- package/dist/standalone/inspect-spk.js +60 -6
- package/dist/standalone/lifecycle.js +3 -1
- package/dist/standalone/manifest.d.ts +6 -0
- package/dist/standalone/manifest.js +51 -3
- package/dist/standalone/portal-window.d.ts +6 -6
- package/dist/standalone/portal-window.js +12 -32
- package/dist/standalone/request-timeout.d.ts +6 -3
- package/dist/standalone/request-timeout.js +10 -4
- package/dist/standalone/root-ops.d.ts +3 -2
- package/dist/standalone/root-ops.js +9 -3
- package/dist/standalone/root-window.d.ts +2 -2
- package/dist/standalone/root-window.js +173 -49
- package/dist/standalone/sdk-check.js +4 -1
- package/dist/standalone/spk.d.ts +3 -0
- package/dist/standalone/spk.js +10 -3
- package/dist/validate.js +2 -0
- package/package.json +2 -3
- package/skills/SKILL.md +3 -1
- package/skills/reference/create.md +5 -1
- package/skills/reference/identity.md +1 -1
- package/skills/reference/lifecycle.md +110 -0
- package/skills/reference/portal.md +12 -0
- package/dist/authorization-sdk.d.ts +0 -6
- package/dist/authorization-sdk.js +0 -6
- package/dist/standalone/native-authorization-window.d.ts +0 -2
- package/dist/standalone/native-authorization-window.js +0 -36
- package/dist/standalone/native-root-window.d.ts +0 -29
- package/dist/standalone/native-root-window.js +0 -307
package/CHANGELOG.md
CHANGED
|
@@ -1,1705 +1,224 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.10.
|
|
4
|
-
|
|
5
|
-
Builds with SDK 0.10.
|
|
6
|
-
module, Rust crate tag and `backend.sdk`)
|
|
7
|
-
|
|
8
|
-
0.10.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
0.10.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
`
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
`
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
`
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
`
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
`
|
|
93
|
-
|
|
94
|
-
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
`
|
|
119
|
-
`
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
`
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
the
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
`
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
`
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
`
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
unchanged
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
- The Application Portal panel
|
|
173
|
-
|
|
174
|
-
SDK's `
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
Builds with SDK 0.9.8 and templates 0.9.7: `init` writes SDK v0.9.8 (Go
|
|
183
|
-
module and Rust crate tag), `@synopackageland/sdk` 0.9.8 and
|
|
184
|
-
`@synopackageland/ui` 0.9.2. SDK 0.9.8 fixes `BackgroundPanel`, whose controls
|
|
185
|
-
to choose a file and submit it were hidden on DSM. The executor digest table
|
|
186
|
-
records SDK 0.9.8 with the same executor and lifecycle digests as 0.9.7, and
|
|
187
|
-
the policy digest does not change, so a rebuilt App keeps the pins it was
|
|
188
|
-
approved with.
|
|
189
|
-
|
|
190
|
-
繁中摘要:使用 SDK 0.9.8 與 templates 0.9.7(UI 0.9.2)。SDK 0.9.8 修正
|
|
191
|
-
`BackgroundPanel` 在 DSM 上看不到選檔與送出按鈕。digest 表加入 SDK 0.9.8,
|
|
192
|
-
executor 與 lifecycle digest 與 0.9.7 相同,policy digest 也不變,重建的 App
|
|
193
|
-
沿用原本核准的 pins。
|
|
194
|
-
|
|
195
|
-
## 0.9.6 (2026-10-12)
|
|
196
|
-
|
|
197
|
-
Builds with SDK 0.9.7 and templates 0.9.6: `init` writes SDK v0.9.7 (Go
|
|
198
|
-
module and Rust crate tag), `@synopackageland/sdk` 0.9.7 and
|
|
199
|
-
`@synopackageland/ui` 0.9.2. The executor digest table records SDK 0.9.7,
|
|
200
|
-
whose executor and lifecycle binary changed, so a rebuilt App carries new
|
|
201
|
-
executor digests. The policy digest changes only for an App that declares
|
|
202
|
-
`uninstall.purge.root`, and such an App asks for approval again after the
|
|
203
|
-
upgrade; `bg.jobs.pause` and `bg.jobs.resume` reach the CGI route table, not
|
|
204
|
-
the policy. Whether new executor digests alone ask for approval again has not
|
|
205
|
-
been checked on a DSM yet.
|
|
206
|
-
|
|
207
|
-
繁中摘要:使用 SDK 0.9.7 與 templates 0.9.6(UI 0.9.2)。executor digest 表加入
|
|
208
|
-
SDK 0.9.7;executor 與 lifecycle 都有變更,重建的 App 會帶新的 executor digest。
|
|
209
|
-
只有宣告 `uninstall.purge.root` 的 App 的 policy digest 會變,升級後需要重新核准;
|
|
210
|
-
`bg.jobs.pause`、`bg.jobs.resume` 只進 CGI route 表,不影響 policy。只換 executor
|
|
211
|
-
digest 時是否需要重新核准,尚未在 DSM 上驗證。新增解除安裝 hook(`uninstall.purge`)。
|
|
212
|
-
|
|
213
|
-
- Uninstall hook: `uninstall.purge` in dsm-package.yaml (`exec`, `args`,
|
|
214
|
-
`env`, `timeout` 2..120 s, optional `root`) names the App's own command,
|
|
215
|
-
and `uninstall.state.items` lists the state it can delete, each with an
|
|
216
|
-
`uninstall.state.<key>` text. On a real uninstall preuninst stops the
|
|
217
|
-
worker and the daemon, runs the hook as the package account with
|
|
218
|
-
`SYNOPKGLAND_DELETE_STATE` and `SYNOPKGLAND_REMOVE_DATA`, then asks the
|
|
219
|
-
executor to purge; a failing or timed-out hook is logged and never blocks
|
|
220
|
-
the uninstall, and an upgrade skips it. The wizard gains an unchecked
|
|
221
|
-
"delete state" box after the item texts. `purge.root` names a rootOps
|
|
222
|
-
script the executor runs as root only while its approval stands; the
|
|
223
|
-
policy's `purge` member records it, so such an App asks for approval
|
|
224
|
-
again. Build refuses a hook outside the package or one that tries to
|
|
225
|
-
become root. inspect checks an executor SPK's preuninst and wizard against
|
|
226
|
-
the hook recorded in sdk-package.json, and that record's root step against
|
|
227
|
-
the policy's `purge`.
|
|
228
|
-
- `init` and `add` change only the dsm-package.yaml keys they set
|
|
229
|
-
(`capabilities`, `portal`, `os_min_ver`); the template's comments, such as
|
|
230
|
-
the commented `uninstall` example, and its formatting stay as written.
|
|
231
|
-
- With `SYNOPKGLAND_SDK_DIR`, init also drops the released SDK from the
|
|
232
|
-
frontend's package-lock.json, so npm installs the local ts package.
|
|
233
|
-
|
|
234
|
-
## 0.9.5 (2026-10-12)
|
|
235
|
-
|
|
236
|
-
Builds with SDK 0.9.6 and templates 0.9.5: `init` writes SDK v0.9.6,
|
|
237
|
-
`@synopackageland/sdk` 0.9.6 and `@synopackageland/ui` 0.9.2. The executor
|
|
238
|
-
digest table records SDK 0.9.6, whose executor registers the portal entry
|
|
239
|
-
and checks a grant's background work from the browser address it recorded,
|
|
240
|
-
so a rebuilt App carries new executor digests. The policy digest changes
|
|
241
|
-
only for an App whose executor registers its portal entry (a portal and
|
|
242
|
-
os_min_ver below 7.2): after the upgrade it asks for approval again. Other
|
|
243
|
-
Apps keep their policy digest.
|
|
244
|
-
|
|
245
|
-
繁中摘要:使用 SDK 0.9.6 與 templates 0.9.5(UI 0.9.2)。executor digest 表加入
|
|
246
|
-
SDK 0.9.6,重建的 App 會帶新的 executor digest。只有由 executor 註冊入口的
|
|
247
|
-
portal App(宣告 portal 且 os_min_ver 低於 7.2)policy digest 會變,升級後需重新
|
|
248
|
-
核准;其他 App 的 policy digest 不變。DSM 7.1 起可用 portal(executor 模式)。
|
|
249
|
-
|
|
250
|
-
- The generated DSM window stays inside the desktop: its width is at most the
|
|
251
|
-
viewport's and its height at most the viewport's less the DSM taskbar. This
|
|
252
|
-
applies to the default 960×640 and to the size DSM restores from
|
|
253
|
-
`restoreSizePos`, which may have been saved on a larger screen. Position and
|
|
254
|
-
maximized state are restored as before.
|
|
255
|
-
- Native root authorization (`createRootAccess` from
|
|
256
|
-
`@synopackageland/cli/authorization-sdk`): the first `run` after an `authorize`
|
|
257
|
-
runs the task that `authorize` just read back as exactly ours, instead of
|
|
258
|
-
reading the TaskScheduler list and task again. Any later run, a repair, and
|
|
259
|
-
a run after `remove` still read DSM first; `authorize` still reads the task
|
|
260
|
-
back after creating it and checks its identity and script.
|
|
261
|
-
- Native root authorization polls the task history every 0.5 s, then at most
|
|
262
|
-
once a second (was up to every 2 s), so a finished root task is seen up to
|
|
263
|
-
1 s sooner.
|
|
264
|
-
- A portal works from DSM 7.1-42661 on. Below 7.2-64570 (executor mode) the
|
|
265
|
-
SPK carries no web-config resource, `etc/portal.*`, alias wizard step or
|
|
266
|
-
alias lifecycle; the executor policy carries `portal: {application, alias}`
|
|
267
|
-
and the `portal.register` / `portal.unregister` operations, and the CGI is
|
|
268
|
-
built with `-X main.portal=executor`. A package name or displayname the
|
|
269
|
-
executor would refuse fails with `STANDALONE_PORTAL_ENTRY_INVALID`; below
|
|
270
|
-
7.1 `STANDALONE_PORTAL_MIN_DSM` still refuses the portal, and `add portal`
|
|
271
|
-
raises os_min_ver only to 7.1-42661. inspect reports the policy's entry
|
|
272
|
-
and flags an INFO os_min_ver below 7.1. Needs templates 0.9.5 and SDK 0.9.6.
|
|
273
|
-
- `ctx.portal` in executor mode: `status()` carries `entry`, administrators
|
|
274
|
-
get `register()` and `unregister()`, and the plain panel offers "Enable
|
|
275
|
-
entry", "Remove entry" or the alias form by entry state. New texts in nine
|
|
276
|
-
languages, including `PORTAL_FAILED`. The panel's Korean texts use the
|
|
277
|
-
formal -십시오 register.
|
|
278
|
-
- The uninstall wizard and the cleanup list of an executor-mode portal App
|
|
279
|
-
warn that a stopped or never-approved executor leaves the entry, and give
|
|
280
|
-
the root cleanup commands.
|
|
281
|
-
- native-layout: `portal: {}` or `{alias}` (DSM 7.1-42661+) writes
|
|
282
|
-
`synopkgland_portal_alias` into INFO for the product's own root helper;
|
|
283
|
-
inspect checks it against `native-layout.json`.
|
|
284
|
-
- DSM's web-config portal registration now needs `os_min_ver` 7.2-64570 or
|
|
285
|
-
later instead of 7.3.2-86009. DSM 7.1's package manager marks the web-config
|
|
286
|
-
worker Synology-only and refuses it in an unsigned SPK (error 320); synopkg
|
|
287
|
-
from DSM 7.2 on drops that mark, the only change to its worker table. The
|
|
288
|
-
7.2 floor comes from that source and is not yet verified on a 7.2 NAS.
|
|
289
|
-
inspect flags a web-config portal SPK whose INFO os_min_ver is lower, with
|
|
290
|
-
this reason.
|
|
291
|
-
|
|
292
|
-
## 0.9.4 (2026-10-12)
|
|
293
|
-
|
|
294
|
-
Builds with SDK 0.9.5 and templates 0.9.4: `init` writes SDK v0.9.5 and
|
|
295
|
-
`@synopackageland/sdk` 0.9.5, and the Vue App's `AppRoot` lets Dialogs leave
|
|
296
|
-
a DSM window. The executor digest table records SDK 0.9.5, whose executor
|
|
297
|
-
equals 0.9.4's; the policy digest stays the same, so an installed App needs
|
|
298
|
-
no new approval. AI guidance for DSM-window Dialogs matches the Vue App.
|
|
299
|
-
|
|
300
|
-
繁中摘要:使用 SDK 0.9.5 與 templates 0.9.4。SDK 0.9.5 只改 TypeScript(NAS
|
|
301
|
-
picker 改用 UI 0.9.1 元件),executor digest 與 0.9.4 相同,policy digest 不變,
|
|
302
|
-
已安裝的 App 不需重新核准。ui-vue 與 ui-json 指引改為在 DSM 視窗內給 `AppRoot`
|
|
303
|
-
`dialog-bounds="viewport"`,並把 `activate` 接到 `ctx.host.activateWindow()`:
|
|
304
|
-
Dialog 可拖出 App 視窗,點 Dialog 會把視窗帶到最前;600px 以下為底部 sheet。
|
|
305
|
-
|
|
306
|
-
- `ui-vue` and `ui-json`: in a DSM window (`ctx.host.platform().host === 'dsm'`),
|
|
307
|
-
give `AppRoot` `dialog-bounds="viewport"` and connect its `activate` event to
|
|
308
|
-
`ctx.host.activateWindow()`, so Dialogs can be dragged out of the window and
|
|
309
|
-
pressing one brings the window to the front. Below 600px they are bottom
|
|
310
|
-
sheets. Standalone web, Portal and previews keep Dialogs inside the App.
|
|
311
|
-
- A host-window test pins that the mounted App's `activateWindow` fronts only
|
|
312
|
-
its own DSM window.
|
|
313
|
-
|
|
314
|
-
## 0.9.3 (2026-10-12)
|
|
315
|
-
|
|
316
|
-
Builds with SDK 0.9.4 and templates 0.9.3: `init` writes SDK v0.9.4 and
|
|
317
|
-
`@synopackageland/sdk` 0.9.4. The executor digest table records SDK 0.9.4,
|
|
318
|
-
whose executor asks DSM's native `SLIBAppPrivUserHas` for App Privileges
|
|
319
|
-
instead of the `SYNO.Core.AppPriv.App` preview. An App rebuilt with SDK 0.9.4
|
|
320
|
-
gets the new executor; the policy digest stays the same, so an installed App
|
|
321
|
-
needs no new approval.
|
|
322
|
-
|
|
323
|
-
繁中摘要:使用 SDK 0.9.4 與 templates 0.9.3。executor 改以 DSM 原生
|
|
324
|
-
`SLIBAppPrivUserHas` 判斷應用程式權限,digest 表加入 0.9.4;policy digest 不變,
|
|
325
|
-
重新建置後已安裝的 App 不需重新核准。限定 IP 的應用程式權限規則改為依瀏覽器位址
|
|
326
|
-
判斷;自行組 `auth` 的呼叫端必須帶 `remote_addr`,否則 executor 回 `APP_DENIED`。
|
|
327
|
-
|
|
328
|
-
- Behavior change: an Application Privileges rule limited to IP addresses
|
|
329
|
-
applies to the browser's address; with SDK 0.9.3 or earlier the executor
|
|
330
|
-
refused every request under such a rule. Work no browser asked for is
|
|
331
|
-
checked as coming from 127.0.0.1. The generated CGI sends the address
|
|
332
|
-
through `api.DSMSession`; code that builds the executor `auth` itself must
|
|
333
|
-
add `remote_addr` or the executor refuses with `APP_DENIED`.
|
|
334
|
-
- The fake-DSM executor flow tests host the 0.9.4 executor's embedded bridge
|
|
335
|
-
and check the online grant against the browser's address and the offline
|
|
336
|
-
write against 127.0.0.1.
|
|
337
|
-
|
|
338
|
-
## 0.9.2 (2026-10-12)
|
|
339
|
-
|
|
340
|
-
Builds with SDK 0.9.3 and templates 0.9.2: `init` writes SDK v0.9.3 and
|
|
341
|
-
`@synopackageland/sdk` 0.9.3. The executor digest table records SDK 0.9.2 and
|
|
342
|
-
0.9.3 (the same digests; 0.9.3 changes only translations). An App rebuilt
|
|
343
|
-
with SDK 0.9.2 or 0.9.3 gets the new executor; the policy digest stays the
|
|
344
|
-
same, so an installed App needs no new approval.
|
|
345
|
-
|
|
346
|
-
繁中摘要:`check` 與 `build` 的錯誤訊息每個錯誤碼只出現一次;`build --json` 的 SDK
|
|
347
|
-
下載失敗附上 GOPRIVATE 提示;有 executor 並宣告 `install.sharedFolder` 的 App 通過
|
|
348
|
-
`inspect` 的 postinst 檢查。重新安裝後的核准只需輸入一次密碼:共用資料夾讀回等 40 s,
|
|
349
|
-
沒到達 executor 的選擇任務在同一次核准內再跑一次,啟動後的健康檢查等 30 s。
|
|
350
|
-
|
|
351
|
-
- `check` and `build` name each error code once. 0.9.1 printed the first code
|
|
352
|
-
twice, for example
|
|
353
|
-
`[STANDALONE_PORTAL_REQUIRES_EXECUTOR] [STANDALONE_PORTAL_REQUIRES_EXECUTOR] …`.
|
|
354
|
-
- A `--json` error without its own hint takes the registry suggestion of its
|
|
355
|
-
code. `build --json` now answers `SDK_DOWNLOAD_FAILED` with the GOPRIVATE and
|
|
356
|
-
git-credential step instead of the generic hint.
|
|
357
|
-
- `inspect` accepts an App with `capabilities.rootOps` or `delegate` that
|
|
358
|
-
declares `install.sharedFolder`. Its `postinst` and `postupgrade` start the
|
|
359
|
-
executor before the shared-folder script, and 0.9.1 reported them as not
|
|
360
|
-
matching.
|
|
361
|
-
- Re-approval after a reinstall takes one password submission for both the
|
|
362
|
-
executor and an install-selected share. The DSM window now reads the share
|
|
363
|
-
selection back for 40 s instead of 20 s, runs a selection task that missed
|
|
364
|
-
the restarting executor once more without a new confirmation, and waits
|
|
365
|
-
30 s instead of 10 s for a started executor before withdrawing the tasks an
|
|
366
|
-
approval created.
|
|
367
|
-
|
|
368
|
-
## 0.9.1 (2026-10-12)
|
|
369
|
-
|
|
370
|
-
Fixes from the 0.9.0 acceptance on DSM (t-0294, t-0290, t-0292).
|
|
371
|
-
|
|
372
|
-
繁中摘要:`build` 重複 `--arch` 時每個架構都建置;SDK 下載失敗回報
|
|
373
|
-
`SDK_DOWNLOAD_FAILED`(不再包成 `STANDALONE_API_PERMISSIONS_INVALID`),`check`
|
|
374
|
-
顯示每個錯誤碼自己的建議;`status` 列出 portal;Vue App 只在 SDK 的
|
|
375
|
-
ExecutorSettings 核准,plain UI 的 DSM 視窗面板改為有樣式、跟隨 DSM 語言並在面板內
|
|
376
|
-
輸入密碼。更正 0.9.0 的核准說明:policy 不變的升級不需重新核准,只有
|
|
377
|
-
install-selected 的 scope 需要管理員確認一次。記錄 SDK 0.9.1 executor digests(只換
|
|
378
|
-
executor、policy digest 不變,免重新核准)。App 分兩層:有 executor(rootOps 或
|
|
379
|
-
delegate)的 App 解除安裝時自動移除應用程式權限規則,宣告 portal 時再 reload nginx,
|
|
380
|
-
精靈與 cleanup 清單只把它們列為自動清除失敗時的後備;無升權 App 任何階段都不用 root,
|
|
381
|
-
應用程式權限規則仍由管理員手動移除。破壞性變更:portal 只限 executor 層級,無升權
|
|
382
|
-
native App 以 `STANDALONE_PORTAL_REQUIRES_EXECUTOR` 拒絕,Compose App 以
|
|
383
|
-
`CONTRACT_PORTAL_REQUIRES_EXECUTOR` 拒絕。並附 0.9.0 安裝殘留的清理步驟。
|
|
384
|
-
|
|
385
|
-
### Build and check
|
|
386
|
-
|
|
387
|
-
- `build --arch x86_64 --arch aarch64` builds every family named; 0.9.0 built
|
|
388
|
-
only the last one. Repeated values and comma lists combine.
|
|
389
|
-
- An SDK version Go cannot fetch is reported as `SDK_DOWNLOAD_FAILED` with the
|
|
390
|
-
GOPRIVATE and git-credential hint. 0.9.0 wrapped it as
|
|
391
|
-
`STANDALONE_API_PERMISSIONS_INVALID`.
|
|
392
|
-
- `check` shows the registry suggestion of each error code. It no longer
|
|
393
|
-
replaces every `dsm-package.yaml` error's suggestion with "fix the schema 2
|
|
394
|
-
fields".
|
|
395
|
-
- `STANDALONE_ENTRY_UNSUPPORTED` names the `main.go` of the project's
|
|
396
|
-
`backend.main`, not always `cmd/app/main.go`.
|
|
397
|
-
|
|
398
|
-
### Status
|
|
399
|
-
|
|
400
|
-
- `status` lists `portal` for an App with `portal: {}`. It reads the App's
|
|
401
|
-
`portal.status`: `ready` with the URL when an administrator set an alias,
|
|
402
|
-
`needs-admin-approval` when none is set, and `blocked` before install or
|
|
403
|
-
when the status cannot be read.
|
|
404
|
-
|
|
405
|
-
### DSM window approval
|
|
406
|
-
|
|
407
|
-
- A Vue App approves the executor only in the SDK's `ExecutorSettings`. The
|
|
408
|
-
DSM window no longer adds its own approval panel to a Vue App with
|
|
409
|
-
`rootOps` or a fixed delegate scope. That panel used unstyled English
|
|
410
|
-
buttons, and its password prompt was appended below the App, so approving
|
|
411
|
-
from it never reached PasswordConfirm.
|
|
412
|
-
- A plain-UI App keeps the window panel. It now uses the panel styles, shows
|
|
413
|
-
its text in the DSM language (the nine SDK locales), and asks for the
|
|
414
|
-
administrator password inside the panel. The password goes to
|
|
415
|
-
`authorize` the same way as in `ExecutorSettings`.
|
|
416
|
-
- Breaking: `confirmPassword` without a password fails with
|
|
417
|
-
`password_required` and sends nothing; the masked form it appended is gone.
|
|
418
|
-
|
|
419
|
-
### Portal needs the executor tier (breaking)
|
|
420
|
-
|
|
421
|
-
- DSM removes a portal App's Login Portal alias at uninstall but does not
|
|
422
|
-
reload nginx (DSM 7.4, t-0294), so `/<alias>/` kept opening a DSM page.
|
|
423
|
-
Only root can reload it, so a `portal` now needs `capabilities.rootOps` or
|
|
424
|
-
`capabilities.delegate`. A no-privilege native App with `portal` fails
|
|
425
|
-
`check`/`build` with `STANDALONE_PORTAL_REQUIRES_EXECUTOR`; `add portal`
|
|
426
|
-
refuses it unless the same call adds `root-ops` or `delegate`; `inspect`
|
|
427
|
-
flags such an SPK with `PORTAL_REQUIRES_EXECUTOR`.
|
|
428
|
-
- A Compose App has no executor: `integration.web.portal` now always fails
|
|
429
|
-
with `CONTRACT_PORTAL_REQUIRES_EXECUTOR` and the schema no longer describes
|
|
430
|
-
its shape. `CONTRACT_PORTAL_INVALID`, `CONTRACT_PORTAL_UNSUPPORTED` and
|
|
431
|
-
`CONTRACT_PORTAL_MIN_DSM` are gone, and `inspect` reports a Compose SPK's
|
|
432
|
-
`web-config` as an unknown resource.
|
|
433
|
-
- Fix: add `root-ops` or `delegate`, or remove the portal and let an
|
|
434
|
-
administrator set up a reverse proxy in DSM.
|
|
435
|
-
|
|
436
|
-
### Uninstall
|
|
437
|
-
|
|
438
|
-
- An App with the executor (rootOps or delegate) cleans up after DSM itself:
|
|
439
|
-
SDK 0.9.1's root purge deletes the App's rules in Control Panel >
|
|
440
|
-
Application Privileges and, for a portal App, reloads nginx once DSM has
|
|
441
|
-
removed the alias. The uninstall wizard says so in the nine languages, and
|
|
442
|
-
`status`/`inspect` list both only as fallbacks: "Only if automatic cleanup
|
|
443
|
-
failed after uninstall; see the system log entry synopkgland-executor."
|
|
444
|
-
- A no-privilege App never uses root, not even at uninstall. Its wizard keeps
|
|
445
|
-
saying that DSM keeps the App's rules in Control Panel > Application
|
|
446
|
-
Privileges, that a later install under the same name applies them again,
|
|
447
|
-
and that an administrator can remove them; the cleanup list keeps that
|
|
448
|
-
item. It never mentions a Login Portal alias, because it cannot declare one.
|
|
449
|
-
A test builds plain, files, jobs, identity and `entry: app-privilege` SPKs
|
|
450
|
-
and checks they run as the package account, ship no executor or root
|
|
451
|
-
tasks, and that their scripts never call synowebapi, nginx or a system
|
|
452
|
-
unit.
|
|
3
|
+
## 0.10.3 (2026-10-14)
|
|
4
|
+
|
|
5
|
+
Builds with SDK 0.10.3 and templates 0.10.3: `init` writes SDK v0.10.3 (Go
|
|
6
|
+
module, Rust crate tag and `backend.sdk`), `@synopackageland/sdk` 0.10.3 and
|
|
7
|
+
`@synopackageland/ui` 0.9.5. **Incompatible:** `check` and `build` need SDK
|
|
8
|
+
0.10.3 or later. The executor digest table adds SDK 0.10.3 and keeps 0.10.0
|
|
9
|
+
to 0.10.2, so `inspect` still recognizes their SPKs. SDK 0.10.3's executor
|
|
10
|
+
records the package version at every start, so an App rebuilt on it carries
|
|
11
|
+
a new executor digest; when its policy digest does not change, the upgrade
|
|
12
|
+
puts the new executor in place without approval. An App that declares
|
|
13
|
+
`root.start` changes its policy and is approved again. The lifecycle digests
|
|
14
|
+
equal 0.10.2.
|
|
15
|
+
|
|
16
|
+
繁中摘要:使用 SDK 0.10.3 與 templates 0.10.3(UI 0.9.5);`check`/`build` 需要 SDK
|
|
17
|
+
0.10.3 以上(不相容)。digest 表新增 SDK 0.10.3(保留 0.10.0~0.10.2)。policy digest
|
|
18
|
+
不變的 App 升級時自動換 executor;宣告 `root.start` 的 App 需要重新核准。lifecycle
|
|
19
|
+
digest 與 0.10.2 相同。
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- `root.start` in dsm-package.yaml names a `root/` program as the executor's start step: the
|
|
24
|
+
executor runs it as root once at the first start after each install or upgrade (`install`,
|
|
25
|
+
or `upgrade` and the previous version), only while the approval is live, for at most 60
|
|
26
|
+
seconds, and a failure never blocks the start. `build` writes it into the policy as `start`;
|
|
27
|
+
`check` refuses a name outside `root/` and a program that also declares `run` or `job`
|
|
28
|
+
(`STANDALONE_ROOT_PROGRAMS_INVALID`); the SDK executor's `check-policy` checks the rest.
|
|
29
|
+
`inspect` lists the root steps. Declaring it changes the policy digest, so the App needs
|
|
30
|
+
approval again; Apps without it keep their policy.
|
|
31
|
+
|
|
32
|
+
繁中摘要:`root.start` 指定一個 root 程式,executor 在每次安裝或升級後第一次啟動時以 root 執行一次;
|
|
33
|
+
失敗只記 log、不擋啟動。宣告後 policy digest 改變需重新核准,沒有宣告的 App 不受影響。
|
|
34
|
+
|
|
35
|
+
- Lifecycle scripts: a project's `dsm-scripts/<DSM script name>` (`preinst`, `postinst`,
|
|
36
|
+
`preupgrade`, `postupgrade`, `preuninst`, `postuninst`, `start-stop-status`) is packed as
|
|
37
|
+
`scripts/app/<name>` and called from the generated script of the same name: after the SDK
|
|
38
|
+
steps, and before them for `preupgrade`, `preuninst` and `stop`. It runs as the package
|
|
39
|
+
account with DSM's arguments, environment and exit codes; a failed App `start` stops the SDK
|
|
40
|
+
again. Native and Compose projects. `check` refuses other names (`APP_SCRIPT_UNKNOWN`),
|
|
41
|
+
non-executable files and files without `#!`; `inspect` lists the App scripts. Projects
|
|
42
|
+
without `dsm-scripts/` build unchanged. Guide: `synopkgland skill show lifecycle`.
|
|
43
|
+
|
|
44
|
+
繁中摘要:專案 `dsm-scripts/` 下以 DSM 原生檔名放的腳本會被打包,並在 CLI 產生的同名腳本中於
|
|
45
|
+
SDK 步驟之後(preupgrade/preuninst/stop 在之前)以套件帳號執行;沒有該資料夾時行為不變。
|
|
46
|
+
|
|
47
|
+
- Login Portal style: a portal App's launcher now carries DSM's `loginStyle` and `loginIcon`,
|
|
48
|
+
so Control Panel > Login Portal > Applications shows a thumbnail instead of a blank box, and
|
|
49
|
+
the alias login page gets a wallpaper, a button colour and the App icon. The CLI ships a
|
|
50
|
+
neutral default (`assets/login-style/`); `login_style` in dsm-package.yaml overrides
|
|
51
|
+
`color`, `wallpaper` with `wallpaper_thumbnail`, and `title`. `check` validates the images
|
|
52
|
+
(`STANDALONE_LOGIN_STYLE_INVALID`, `STANDALONE_LOGIN_STYLE_IMAGE_INVALID`) and prints the
|
|
53
|
+
style; `inspect` prints it and flags a portal SPK without one (`LOGIN_STYLE_MISSING`).
|
|
54
|
+
Rebuilding an existing portal App with this CLI adds the default; no change to the project.
|
|
55
|
+
|
|
56
|
+
繁中摘要:有 portal 的 App 重新 build 後會自動帶入預設登入樣式,「登入入口 › 應用程式」縮圖不再
|
|
57
|
+
空白,別名登入頁有桌布、按鈕色與 App icon;可用 `login_style` 換主色、桌布與標題圖。
|
|
58
|
+
|
|
59
|
+
### Changed
|
|
60
|
+
|
|
61
|
+
- **Incompatible:** the CLI needs SDK 0.10.3 or later. `check` and `build` refuse an App
|
|
62
|
+
whose backend requires SDK 0.10.0, 0.10.1 or 0.10.2 (`SDK_UNSUPPORTED`, naming 0.10.3);
|
|
63
|
+
raise the Go module, Cargo tag or `backend.sdk` and the frontend's
|
|
64
|
+
`@synopackageland/sdk` to 0.10.3. The CLI no longer carries the fallbacks for those
|
|
65
|
+
releases: the pre-`timeouts.json` timeouts, skipping `executor check-policy` for an SDK
|
|
66
|
+
without it, and `EXECUTOR_START_STEP_UNSUPPORTED`.
|
|
67
|
+
|
|
68
|
+
繁中摘要:CLI 需要 SDK 0.10.3 以上;App 若仍用 SDK 0.10.0~0.10.2,`check`/`build` 會以
|
|
69
|
+
`SDK_UNSUPPORTED` 拒絕。移除為舊版保留的逾時退回值、check-policy 略過與 start 步驟檢查。
|
|
70
|
+
|
|
71
|
+
- `check` and `build` refuse a request deadline that ends before a root program `root.run`
|
|
72
|
+
may run would answer (`STANDALONE_REQUEST_TIMEOUT_SHORT`): `backend.timeout_seconds`
|
|
73
|
+
(60 by default) must be at least the program's `run.timeout_s` (20 by default) + 20, the
|
|
74
|
+
executor's 10 seconds and its client's 10 (SDK `spec/protocol/v1`, Timeouts). The default
|
|
75
|
+
covers programs of up to 40 seconds; a 120-second program needs `timeout_seconds: 140`.
|
|
76
|
+
A program with only `job`, `start` or `stop` is not affected.
|
|
77
|
+
- The request default, the window's wait past the request deadline and the `root.run`
|
|
78
|
+
deadline check read their values from the App's SDK, `spec/protocol/v1/timeouts.json`,
|
|
79
|
+
instead of the CLI's own copies, so they follow the SDK the App builds with. An App
|
|
80
|
+
without the SDK keeps 60 seconds, 2 seconds, and a `run.timeout_s` of 20 + 20. The
|
|
81
|
+
generated values do not change with SDK 0.10.3.
|
|
82
|
+
|
|
83
|
+
繁中摘要:request 預設逾時、視窗多等的時間與 root.run 逾時檢查改讀 App 所用 SDK 的
|
|
84
|
+
timeouts.json,不再用 CLI 手抄的值;沒有 SDK 的 App 沿用 60 秒、2 秒、20 + 20。
|
|
85
|
+
- The DSM window's approval and `control start` wait for an executor that answers
|
|
86
|
+
`state: "starting"` while it runs its start step, for up to 75 seconds, instead of giving
|
|
87
|
+
up after 30 seconds; past that the result is blocked with code `executor_starting`, and the
|
|
88
|
+
plain-UI panel and the SDK settings say the service is still starting. The plain-UI panel
|
|
89
|
+
says it is waiting for the background service while a request runs.
|
|
90
|
+
|
|
91
|
+
繁中摘要:核准與 control start 會等待回報「starting」的 executor(最多 75 秒),超過則以
|
|
92
|
+
`executor_starting` 阻擋並說明仍在啟動。
|
|
93
|
+
|
|
94
|
+
- The DSM window's approval asks DSM's schedulers 8 times instead of 15, following the SDK's
|
|
95
|
+
`spec/scheduler/v1`. The boot task is read with one EventScheduler `get` by its name
|
|
96
|
+
(DSM keeps event task names unique) and never listed; Task Scheduler is listed once before
|
|
97
|
+
and once after the writes, and the control task is then read by its listed id. A step reads
|
|
98
|
+
each task once and reuses that read; a delete still reads the task again first. After the
|
|
99
|
+
boot task runs, only `executor.status` is asked: the tasks were read back exactly just
|
|
100
|
+
before, and the executor's pins answer for the rest. `executor.status` is asked every
|
|
101
|
+
500 ms for the first 4 seconds, then backs off to 2 seconds. `status` (and `check`) gets the
|
|
102
|
+
boot task by name instead of listing EventScheduler. Measured on a DSM 7.4 x86_64 NAS with
|
|
103
|
+
a fresh install: ready came 1.1-4.9 s after the boot task ran instead of 6.3-10.9 s, and
|
|
104
|
+
10.1-21.8 s after Approve instead of 16.3-26.9 s (DSM's scheduler calls vary by seconds).
|
|
105
|
+
|
|
106
|
+
繁中摘要:視窗核准對 DSM 排程 API 的呼叫從 15 次降為 8 次:boot 任務改用名稱 get、不再 list
|
|
107
|
+
EventScheduler;Task Scheduler 在寫入前後各 list 一次,之後用 id get;執行 boot 任務後只問
|
|
108
|
+
`executor.status`,前 4 秒每 500 ms 問一次。安全檢查(重複、內容逐字比對、pins)都保留。
|
|
109
|
+
|
|
110
|
+
### Fixed
|
|
111
|
+
|
|
112
|
+
- The DSM window's `openFileManager` and `revealFile` take a `/volumeN/...` path as the SDK's
|
|
113
|
+
`fileStationPath` does: a DSM volume mount (`/volumeN`, `/volumeUSBN`, `/volumeSATAN`) is
|
|
114
|
+
stripped instead of refused, and the reveal recovery follows the path File Station got.
|
|
115
|
+
Anything but one canonical shared-folder path is still `invalid-input`.
|
|
116
|
+
- Executor approval results carry a structured `code` beside the English `reason`, and an
|
|
117
|
+
`outcome` when the approval rolled back: a refused administrator password is
|
|
118
|
+
`password_rejected` (DSM 3121), other PasswordConfirm refusals `password_required`,
|
|
119
|
+
`session_ended` or `password_confirm_failed`; scheduler, task and executor failures have
|
|
120
|
+
codes of their own (`scheduler_denied`, `task_missing`, `executor_unreachable`, …) and the
|
|
121
|
+
outcomes are `restored`, `withdrawn`, `restore_failed` and `withdraw_failed`. The SDK's
|
|
122
|
+
`ExecutorSettings` reads `code`. The plain-UI window panel now shows the code and outcome in
|
|
123
|
+
the DSM language, followed by the DSM code (`dsm_3121`), instead of the English reason.
|
|
124
|
+
Rebuild the App to pick this up.
|
|
125
|
+
|
|
126
|
+
繁中摘要:核准結果新增結構化 `code`(例如 `password_rejected`)與回復結果 `outcome`,`reason`
|
|
127
|
+
仍保留英文細節;純 UI 視窗面板改以 DSM 語系顯示原因,不再直接顯示英文;需重新 build App。
|
|
128
|
+
|
|
129
|
+
- Executor approval: a scheduler write that fails partway no longer leaves the earlier
|
|
130
|
+
approval half deleted. The approval stops at the first failed write, withdraws the tasks
|
|
131
|
+
it created and recreates the earlier boot and control tasks it removed, then offers
|
|
132
|
+
approval again. DSM cannot hold two same-named tasks, so the old task is still deleted
|
|
133
|
+
before its replacement is created. When the rollback itself fails, the window says so, and
|
|
134
|
+
the next approval converges from what is left. A DSM session that ended (`dsm_106`,
|
|
135
|
+
`dsm_107`, `dsm_119`) asks the administrator to sign in to DSM again.
|
|
136
|
+
|
|
137
|
+
繁中摘要:核准半途寫入失敗時,會撤回這次建立的排程並重建先前核准的舊排程,再提供重新核准;
|
|
138
|
+
還原失敗時會明白說明,下次核准可自動收斂。DSM session 失效時提示重新登入。
|
|
139
|
+
|
|
140
|
+
- An App opened through its Application Portal alias (`https://nas/<alias>/`) reaches its
|
|
141
|
+
backend again. The generated window posted `ctx.call` and `ctx.files` to the absolute
|
|
142
|
+
`/webman/3rdparty/<package>/cgi/api.cgi`, which DSM answers with 403 on the alias, so every
|
|
143
|
+
call failed with `bad_response` and an approved executor read as unavailable. The path is
|
|
144
|
+
now relative to the page, as the App's own assets are; the DSM desktop resolves it to the
|
|
145
|
+
same URL as before. Rebuild the App to pick this up.
|
|
146
|
+
|
|
147
|
+
繁中摘要:從應用程式入口別名網址開啟 App 時,`ctx.call`/`ctx.files` 改用相對路徑,不再被
|
|
148
|
+
DSM 以 403 拒絕(原本顯示 `bad_response`、已核准的 executor 顯示無法使用);需重新 build App。
|
|
149
|
+
|
|
150
|
+
- `check` and `build` refusing a `root.start`, `root.stop` or `uninstall.purge` program that
|
|
151
|
+
also declares `run` or `job` (`EXECUTOR_POLICY_REJECTED`) now say what to do: give the step
|
|
152
|
+
another program name in `root.programs`, one without `run` or `job`.
|
|
153
|
+
|
|
154
|
+
繁中摘要:start/stop/purge 的 program 同時宣告 run/job 而被拒時,提示改用另一個沒有
|
|
155
|
+
run/job 的 program 名稱。
|
|
156
|
+
|
|
157
|
+
- `init` and `build` of a Python App whose SDK has no Python SDK (`python/synopkgland_app`)
|
|
158
|
+
report `STANDALONE_PYTHON_SDK_MISSING` with the path, instead of a bare `ENOENT`.
|
|
159
|
+
|
|
160
|
+
繁中摘要:找不到 Python SDK 時改回專屬錯誤碼 `STANDALONE_PYTHON_SDK_MISSING`,不再是 `ENOENT`。
|
|
161
|
+
|
|
162
|
+
### Removed
|
|
163
|
+
|
|
164
|
+
- `@synopackageland/cli/authorization-sdk` is gone: `ROOT_RUNTIME` and
|
|
165
|
+
`AUTHORIZATION_RUNTIME`, the window runtimes of a native product with its own pinned root
|
|
166
|
+
tasks, ship unchanged in `@synopackageland/sdk/native`. A native product imports them from
|
|
167
|
+
the SDK; generated Apps are not affected.
|
|
168
|
+
|
|
169
|
+
繁中摘要:native 產品的 root/authorization 視窗 runtime 改由 SDK(`@synopackageland/sdk/native`)提供,
|
|
170
|
+
CLI 不再匯出 `authorization-sdk`;一般產生的 App 不受影響。
|
|
171
|
+
|
|
172
|
+
- The CLI's copy of the Application Portal panel text (19 keys in 9 languages) is gone:
|
|
173
|
+
`build` reads it from the App's SDK (`ts/i18n/portal/<locale>.json`, in every SDK 0.10.x),
|
|
174
|
+
the same text the SDK's `PortalSettings` shows. The built window is unchanged; a fix to the
|
|
175
|
+
text reaches an App with its next SDK.
|
|
176
|
+
|
|
177
|
+
繁中摘要:Application Portal 面板文案改從 App 的 SDK 讀取,CLI 不再保留一份;建出的視窗不變,文案修正隨 SDK 更新。
|
|
178
|
+
|
|
179
|
+
- `dist/runtime/delegate-contract.js` keeps only the operation names the build checks; the
|
|
180
|
+
background-save DTOs, route table and limits, which nothing in the CLI used, and the frozen
|
|
181
|
+
v1 vector now live only in the SDK (`ts/src/delegate/long-running.ts`).
|
|
453
182
|
|
|
454
|
-
### SDK 0.9.1
|
|
455
183
|
|
|
456
|
-
|
|
457
|
-
require SDK 0.9.1 (`backend/go.mod` and `@synopackageland/sdk`).
|
|
458
|
-
- The CLI records the SDK 0.9.1 executor digests, rebuilt with the
|
|
459
|
-
uninstall cleanup (x86_64 `5d75af3c…`, aarch64 `b0e1f817…`, armv7
|
|
460
|
-
`17db613a…`; lifecycle digests equal 0.9.0). SDK 0.9.1 only replaces the
|
|
461
|
-
executor: the policy format, task scripts and permissions are unchanged,
|
|
462
|
-
so the policy digest stays the same and no App needs a new approval. An App moved from SDK
|
|
463
|
-
0.9.0 to 0.9.1 in `backend/go.mod` keeps its approval; the installed
|
|
464
|
-
executor re-pins the new executor by itself.
|
|
465
|
-
|
|
466
|
-
### Cleaning up after 0.9.0 installs
|
|
467
|
-
|
|
468
|
-
An App built with SDK 0.9.0 could leave root tasks behind at uninstall
|
|
469
|
-
(t-0294 bugs 1 and 3). If the App is still installed, rebuild it with SDK
|
|
470
|
-
0.9.1, install that build and then uninstall it: the 0.9.1 purge rebuilds the
|
|
471
|
-
task inventory from the approved policy and deletes the tasks. Otherwise an
|
|
472
|
-
administrator removes them by hand:
|
|
473
|
-
|
|
474
|
-
- Control Panel > Task Scheduler: delete `<package> executor control` and
|
|
475
|
-
`<package> executor selection`.
|
|
476
|
-
- The boot event, which DSM's web API refuses to delete over HTTP (error
|
|
477
|
-
119): as root, run
|
|
478
|
-
`/usr/syno/bin/synowebapi --exec api=SYNO.Core.EventScheduler method=delete version=1 task_name="<package> executor boot"`.
|
|
479
|
-
- Control Panel > Application Privileges: remove the App's rules. Control
|
|
480
|
-
Panel > Login Portal: if its alias still opens, save an application alias
|
|
481
|
-
there to reload nginx, or restart the NAS. The 0.9.1 rebuild-and-uninstall
|
|
482
|
-
route above does both for you.
|
|
483
|
-
|
|
484
|
-
### Approval after upgrading (correction to 0.9.0)
|
|
485
|
-
|
|
486
|
-
- 0.9.0 said a delegate App rebuilt with it needs one new approval. Measured
|
|
487
|
-
on DSM 7.4 (t-0294): a `files.moveFromStaging` App upgraded from 0.8.0 to
|
|
488
|
-
0.9.0 kept the same policy digest. The installed executor re-pinned the new
|
|
489
|
-
executor by itself, with no new approval. Only an `install-selected` scope
|
|
490
|
-
needed one administrator confirmation (PasswordConfirm) of the shared
|
|
491
|
-
folder.
|
|
492
|
-
- A new approval is needed only when the executor policy changes, for
|
|
493
|
-
example new operations, another scope or changed root scripts.
|
|
494
|
-
|
|
495
|
-
### Release tooling
|
|
496
|
-
|
|
497
|
-
- `node scripts/executor-digests.mjs <sdk>/release/vX.Y.Z.json` records a
|
|
498
|
-
released SDK's executor and lifecycle digests in
|
|
499
|
-
`src/runtime/executor-digests.json`. It checks the three architectures,
|
|
500
|
-
go1.26.9 and the CLI minor. A tagged release (`commit` set) never changes
|
|
501
|
-
a recorded version; a release not yet tagged (`commit: null`) replaces its
|
|
502
|
-
own entry. SDK 0.9.1's digests were recorded this way.
|
|
503
|
-
- `test/fixtures/executor-setup/` holds the `executor/setup.json` this CLI
|
|
504
|
-
writes for delegate, time-limited delegate with jobs, root-ops and
|
|
505
|
-
install-selected Apps, for the SDK executor's contract test.
|
|
506
|
-
`UPDATE_EXECUTOR_SETUP_FIXTURES=1 npm test` regenerates them.
|
|
507
|
-
- The npm gate runs `scripts/smoke-exports.mjs`, the export check of
|
|
508
|
-
`smoke-pack.sh`. In 0.9.0 that check still imported the removed
|
|
509
|
-
`authorizationTemplateDirectory`, so `gate.sh docker` always failed.
|
|
510
|
-
|
|
511
|
-
## 0.9.0 (2026-10-11)
|
|
512
|
-
|
|
513
|
-
The CLI, the SDK and the project templates are now three repositories, and
|
|
514
|
-
the CLI only packages, deploys and checks. An App names its SDK version once,
|
|
515
|
-
in `backend/go.mod`. Background saves can create subfolders and choose what
|
|
516
|
-
happens on a name conflict, and time-limited delegate jobs gain read, rename,
|
|
517
|
-
copy, move and delete.
|
|
518
|
-
|
|
519
|
-
繁中摘要:CLI 移到 github.com/synopackageland/syno-pkg-land-cli,只負責打包、部署與檢查;
|
|
520
|
-
範本改由 `@synopackageland/templates`(精確 pin)提供;SDK 是
|
|
521
|
-
`github.com/synopackageland/syno-pkg-land-sdk`(Go)與 `@synopackageland/sdk`(前端,含
|
|
522
|
-
`./vue`),版本只寫在 `backend/go.mod`。`build` 依該版本 `go mod download`
|
|
523
|
-
executor 並比對 CLI 內建的 sha256 表。`check` 新增 `SDK_REQUIRED`、
|
|
524
|
-
`SDK_VERSION_MISMATCH`、`SDK_UNSUPPORTED`。`files.moveFromStaging` 的 `name`
|
|
525
|
-
可帶子資料夾,新增 `conflict: fail|overwrite|rename`;有時限的 delegate 新增
|
|
526
|
-
`files.read`、`files.rename`、`files.copy`、`files.move`、`files.delete`。
|
|
527
|
-
管理員只在 executor policy 改變時需要重新核准;0.9.0 的 policy 有改變。
|
|
184
|
+
## 0.10.2 (2026-10-14)
|
|
528
185
|
|
|
529
|
-
|
|
186
|
+
First release of the changelog. `@synopackageland/cli` (`synopkgland`)
|
|
187
|
+
builds Synology DSM 7 packages (SPK) from a template, checks them, and
|
|
188
|
+
installs them on a NAS. It builds with SDK 0.10.2 and templates 0.10.2.
|
|
530
189
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
module `github.com/synopackageland/syno-pkg-land-sdk` and the npm package
|
|
534
|
-
`@synopackageland/sdk`, which includes the Vue components at
|
|
535
|
-
`@synopackageland/sdk/vue`.
|
|
536
|
-
- The `require github.com/synopackageland/syno-pkg-land-sdk` line in `backend/go.mod` is the
|
|
537
|
-
only SDK version. `dsm-package.yaml` has no SDK field.
|
|
538
|
-
- `check` and `build` report `SDK_REQUIRED` when `capabilities.delegate` or
|
|
539
|
-
`rootOps` is declared without that line (an `entry` mode without it fails
|
|
540
|
-
with `STANDALONE_ENTRY_UNSUPPORTED`), `SDK_UNSUPPORTED` when its minor version is not the CLI's (CLI 0.9.x builds
|
|
541
|
-
SDK 0.9.x), and `SDK_VERSION_MISMATCH` when the frontend's
|
|
542
|
-
`@synopackageland/sdk` differs from it. A `file:` frontend dependency is
|
|
543
|
-
compared through that folder's `package.json` version.
|
|
544
|
-
- `build` reads the SDK version from `backend/go.mod`, runs `go mod download`
|
|
545
|
-
for the executor of that version, and builds it with go1.26.9. Its sha256
|
|
546
|
-
must match the table shipped in this CLI, or the build fails with
|
|
547
|
-
`EXECUTOR_DIGEST_MISMATCH`. A version Go cannot fetch fails with
|
|
548
|
-
`SDK_DOWNLOAD_FAILED`. While the SDK repositories are private, set
|
|
549
|
-
`GOPRIVATE=github.com/synopackageland/*` and give git a credential for
|
|
550
|
-
github.com; the error says which of the two is missing. Root task scripts
|
|
551
|
-
and `sdk-permissions.json` come from the same SDK version.
|
|
552
|
-
- The CGI binds both policy digests at link time:
|
|
553
|
-
`<module>/internal/api.expectedPermissionsDigest` for the App and
|
|
554
|
-
`github.com/synopackageland/syno-pkg-land-sdk/api.expectedSDKPermissionsDigest` for the
|
|
555
|
-
SDK.
|
|
556
|
-
- `@synopackageland/cli/authorization-sdk` exports `AUTHORIZATION_RUNTIME`
|
|
557
|
-
and `ROOT_RUNTIME`. `authorizationTemplateDirectory` is removed;
|
|
558
|
-
`AuthorizationGate` is in `@synopackageland/sdk/vue`.
|
|
190
|
+
繁中摘要:`synopkgland` 從模板建立 DSM 7 套件(SPK),檢查、打包並安裝到
|
|
191
|
+
NAS;搭配 SDK 0.10.2 與 templates 0.10.2。
|
|
559
192
|
|
|
560
193
|
### Templates
|
|
561
194
|
|
|
562
|
-
- `
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
- `
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
a canceled move leaves none behind. Existing folders are reused. Limits: 16
|
|
593
|
-
folders, 255 bytes per name, 1024 bytes in total. A name without folders
|
|
594
|
-
behaves exactly as before.
|
|
595
|
-
- New `conflict` field for `files.moveFromStaging` and the time-limited
|
|
596
|
-
`files.write`: `fail` (default, unchanged), `overwrite` (atomic replace of a
|
|
597
|
-
regular file the user can write) or `rename` (`name (1).ext` up to
|
|
598
|
-
`name (99).ext`; the receipt path reports the name used).
|
|
599
|
-
- New error codes: `invalid-path`, `path-too-deep`,
|
|
600
|
-
`destination-not-directory`, `name-too-long`.
|
|
601
|
-
|
|
602
|
-
### Delegate: file operations for time-limited grants
|
|
603
|
-
|
|
604
|
-
- New operations `files.read`, `files.rename`, `files.copy`, `files.move` and
|
|
605
|
-
`files.delete`, each declared on its own; a write operation never implies
|
|
606
|
-
delete. Go: `job.Files()` returns `delegate.JobFiles` with `Read`, `Rename`,
|
|
607
|
-
`CreateFolderAll`, `Copy`, `Move`, `Delete`, `TaskStatus` and `CancelTask`.
|
|
608
|
-
- `files.createFolder` takes `parents` (`CreateFolderAll`, like `mkdir -p`).
|
|
609
|
-
- Except `files.write` and `files.read`, the executor calls File Station as the
|
|
610
|
-
user through one root-side allowlist of methods, and re-checks the paths File
|
|
611
|
-
Station reports against the grant. `files.read` copies the file into staging
|
|
612
|
-
in a child that drops to the user and never follows symlinks.
|
|
613
|
-
- Copy, move and delete run as File Station background tasks followed with the
|
|
614
|
-
implied `files.taskStatus` and `files.taskCancel`; revoking the grant stops
|
|
615
|
-
them. Delete needs `recursive` for folders and goes to the recycle bin; a
|
|
616
|
-
Shared Folder without one needs `permanent`.
|
|
617
|
-
- File Station refusals now report SDK codes (`PERMISSION_DENIED`,
|
|
618
|
-
`not-found`, `destination-exists`, `NO_SPACE`, `invalid-path`,
|
|
619
|
-
`name-too-long`) instead of `DSM_FAILED`. New codes: `not-a-file`,
|
|
620
|
-
`recursive-required`, `recycle-bin-disabled`, `task-not-found`,
|
|
621
|
-
`too-many-tasks`, `READ_FAILED`.
|
|
622
|
-
|
|
623
|
-
### Approval
|
|
624
|
-
|
|
625
|
-
- An administrator approves the executor policy (operations, scope and root
|
|
626
|
-
tasks), not the executor binary. When an upgrade keeps the policy and the
|
|
627
|
-
new executor matches the `INFO` anchor, it installs without a new approval.
|
|
628
|
-
When the policy changes, the App stays at `needs-admin-approval` until an
|
|
629
|
-
administrator approves again.
|
|
630
|
-
- The 0.9.0 policy changes (new operations and `conflict`), so a delegate App
|
|
631
|
-
rebuilt with this CLI needs one new approval after the upgrade.
|
|
632
|
-
Moving the SDK to its own repository does not add one. Apps not rebuilt are
|
|
633
|
-
not affected.
|
|
634
|
-
|
|
635
|
-
## 0.8.0 (2026-10-11)
|
|
636
|
-
|
|
637
|
-
Faster builds, one SPK checker for any package, and a guide for scripts and
|
|
638
|
-
interpreted languages. `validate` is merged into `inspect`.
|
|
639
|
-
|
|
640
|
-
繁中摘要:toolkit 改用使用者層級共用快取;新增 `build --jobs` 多架構並行與
|
|
641
|
-
`build --verify-reproducible` 可重現檢查(可用依賴指紋略過);`inspect` 對任何
|
|
642
|
-
SPK 檢查 DSM 7 格式,synopkgland 建置的 SPK 另查建置合約;native layout 的
|
|
643
|
-
aarch64 INFO arch 改寫機型清單、拒絕無執行權限的 script、toolkit 可用 GNU tar
|
|
644
|
-
或 bsdtar 解開;新增腳本/直譯語言打包指南。無圖示的 native layout SPK 現在會
|
|
645
|
-
因 `SPK_ICON_MISSING` 無法通過 inspect。
|
|
646
|
-
|
|
647
|
-
### Shared toolkit cache
|
|
648
|
-
|
|
649
|
-
- Native layout toolkit archives now default to one per-user cache shared by
|
|
650
|
-
every project and worktree: `$XDG_CACHE_HOME/synopkgland` or
|
|
651
|
-
`~/.cache/synopkgland` on Linux, `~/Library/Caches/synopkgland` on macOS.
|
|
652
|
-
`SYNOPKGLAND_CACHE_DIR` still overrides it. The project's
|
|
653
|
-
`.synopkgland-cache` folder is no longer used by default; delete it or point
|
|
654
|
-
`SYNOPKGLAND_CACHE_DIR` at it. The private-folder and `sha256` checks are
|
|
655
|
-
unchanged, and concurrent builds may share the cache.
|
|
656
|
-
|
|
657
|
-
### Parallel architecture builds
|
|
658
|
-
|
|
659
|
-
- `synopkgland build --jobs <n>` builds up to `n` architectures at the same
|
|
660
|
-
time for native-go, binary, native layout and Compose gateway projects. The
|
|
661
|
-
default stays `1`. Output files and names are byte-identical to a sequential
|
|
662
|
-
build; with `n` above 1 each output line is prefixed with its architecture.
|
|
663
|
-
- SPK files now reach the output folder only after every architecture
|
|
664
|
-
succeeds, also with `--jobs 1`. A failed architecture is named in the error,
|
|
665
|
-
for example `[aarch64]`, and no SPK from that build is written. Before, the
|
|
666
|
-
architectures built before the failure stayed in `dist/`.
|
|
667
|
-
- Native layout compile hooks get `SYNOPKGLAND_WORK_DIR`, an empty scratch
|
|
668
|
-
folder per architecture. `--jobs` above 1 requires `layout.payload` to
|
|
669
|
-
contain `{arch}`. Architectures that pin the same toolkit archive download it
|
|
670
|
-
once.
|
|
671
|
-
- New error code `CLI_JOBS_INVALID`.
|
|
672
|
-
|
|
673
|
-
### Reproducible build check
|
|
674
|
-
|
|
675
|
-
- `synopkgland build --verify-reproducible [changed|always]` keeps this
|
|
676
|
-
build's SPKs as the first round, builds once more into a temporary folder
|
|
677
|
-
with an empty `GOCACHE` after removing the manifest's `reproducible.clean`
|
|
678
|
-
paths, and fails with `BUILD_NOT_REPRODUCIBLE` listing the payload and
|
|
679
|
-
metadata files that differ. Works for every project type.
|
|
680
|
-
- New optional manifest block `reproducible: {inputs, clean}` in
|
|
681
|
-
`dsm-package.yaml` (native-go, binary, native layout) and
|
|
682
|
-
`synology-app.yaml`. The SHA-256 of the `inputs` files, the CLI version and
|
|
683
|
-
native layout toolkit pins form a dependency fingerprint. A passing check
|
|
684
|
-
writes it to `reproducible-fingerprint.json`; `changed` (the default) skips
|
|
685
|
-
the second build while it is unchanged. New error code
|
|
686
|
-
`REPRODUCIBLE_INVALID`.
|
|
687
|
-
|
|
688
|
-
### `inspect` checks any SPK
|
|
689
|
-
|
|
690
|
-
- `synopkgland inspect <spk>` now checks any SPK against the DSM 7 package
|
|
691
|
-
format, whether `synopkgland` built it or not, without installing it: the
|
|
692
|
-
outer archive, `INFO` fields, formats and `checksum`, path and link safety in
|
|
693
|
-
`package.tgz`, `ui/config` JSON and its `"texts"` declaration, ELF files
|
|
694
|
-
against `arch` (none in `noarch`), lifecycle scripts and their execute bit,
|
|
695
|
-
`conf/privilege` and `conf/resource`, icons, `LICENSE`, wizards and
|
|
696
|
-
`syno_signature.asc`. Every finding has a stable `SPK_*` code listed in the
|
|
697
|
-
errors reference.
|
|
698
|
-
- Only an SPK that `synopkgland` built (top-level `sdk-package.json` or
|
|
699
|
-
`native-layout.json`, or `synology-app.yaml` in the payload) is also checked
|
|
700
|
-
against the build contract. Other SPKs are no longer rejected by it.
|
|
701
|
-
- The output has a DSM format section and, for `synopkgland` SPKs, a
|
|
702
|
-
`synopkgland` contract section. An error in either exits 1 with
|
|
703
|
-
`SPK_INSPECTION_FAILED`; warnings alone exit 0. `--json` keeps every earlier
|
|
704
|
-
field and adds `synopkgland` (boolean) and `dsm: {ok, errors, warnings}`.
|
|
705
|
-
- There is no `validate` command; the DSM rules it had during 0.8.0
|
|
706
|
-
development are part of `inspect`. The project check is `check`.
|
|
707
|
-
|
|
708
|
-
### Native layout fixes
|
|
709
|
-
|
|
710
|
-
- `arches: [aarch64]` now writes the same `INFO` `arch` as native-go and
|
|
711
|
-
binary (`armada37xx rtd1296 rtd1619 rtd1619b`) instead of `aarch64`, which
|
|
712
|
-
the Developer Guide arch table does not list.
|
|
713
|
-
- `build` refuses a lifecycle or replace script in `layout.metadata` without
|
|
714
|
-
the execute bit with `NATIVE_LAYOUT_SCRIPT_NOT_EXECUTABLE`; run `chmod +x`.
|
|
715
|
-
Before, the SPK was built and DSM could not run the script.
|
|
716
|
-
- `native.toolkits` archives extract with GNU tar and with bsdtar (the macOS
|
|
717
|
-
default). Other tar programs fail with `NATIVE_TOOLKIT_TAR_UNSUPPORTED`.
|
|
718
|
-
Members with absolute or `..` paths are refused.
|
|
719
|
-
|
|
720
|
-
### Scripts and interpreted languages guide
|
|
721
|
-
|
|
722
|
-
- New guide: package a shell, Node.js, Python, Bun or Deno program by
|
|
723
|
-
compiling it to one executable, bundling the interpreter through
|
|
724
|
-
`native.toolkits`, or running it in a Compose container, with measured sizes,
|
|
725
|
-
architectures and glibc needs, and a hand-packed `noarch` shell SPK. The CLI
|
|
726
|
-
cannot declare `install_dep_packages` for Package Center's Node.js or Python
|
|
727
|
-
packages; the guide says so.
|
|
728
|
-
|
|
729
|
-
### 繁體中文摘要
|
|
730
|
-
|
|
731
|
-
- `synopkgland build --jobs <n>` 可同時建置多個架構(native-go、binary、native layout、
|
|
732
|
-
Compose gateway),預設仍為 1;產出與依序建置逐位元組相同。所有架構成功後才寫入
|
|
733
|
-
SPK,失敗時錯誤標明架構且不寫入任何 SPK。native layout hook 新增
|
|
734
|
-
`SYNOPKGLAND_WORK_DIR`;`--jobs` 大於 1 時 `layout.payload` 必須含 `{arch}`。
|
|
735
|
-
- `synopkgland build --verify-reproducible` 以這次建置為第一輪、從乾淨狀態再建一次比對,
|
|
736
|
-
不同時列出 payload 檔案並以 `BUILD_NOT_REPRODUCIBLE` 失敗。manifest 新增
|
|
737
|
-
`reproducible: {inputs, clean}`;依賴指紋未變時略過(記錄在
|
|
738
|
-
`reproducible-fingerprint.json`)。
|
|
739
|
-
- native layout 的 toolkit 快取預設改為每位使用者一份、所有專案與 worktree 共用
|
|
740
|
-
(Linux `$XDG_CACHE_HOME/synopkgland` 或 `~/.cache/synopkgland`,macOS
|
|
741
|
-
`~/Library/Caches/synopkgland`);`SYNOPKGLAND_CACHE_DIR` 仍可覆寫。專案內的
|
|
742
|
-
`.synopkgland-cache` 不再預設使用。
|
|
743
|
-
- `synopkgland inspect <spk>` 改為不安裝、依 DSM 7 套件格式檢查任何 SPK(不限本 CLI 建置),
|
|
744
|
-
涵蓋外層封存、`INFO` 欄位與 `checksum`、`package.tgz` 路徑與連結安全、`ui/config` 的
|
|
745
|
-
`"texts"`、ELF 與 `arch`(`noarch` 不得有 ELF)、生命週期指令碼與執行權限、`conf/privilege`
|
|
746
|
-
與 `conf/resource`、圖示、`LICENSE`、精靈與簽章。每個問題有固定 `SPK_*` 代碼,列在錯誤碼參考。
|
|
747
|
-
- 只有 `synopkgland` 建置的 SPK(最上層有 `sdk-package.json` 或 `native-layout.json`,或 payload
|
|
748
|
-
有 `synology-app.yaml`)另查建置合約;其他 SPK 不再因合約被拒。任一區段有錯誤時以
|
|
749
|
-
`SPK_INSPECTION_FAILED` 結束碼 1 失敗,只有警告時結束碼 0。`--json` 保留原有欄位,新增
|
|
750
|
-
`synopkgland` 與 `dsm: {ok, errors, warnings}`。
|
|
751
|
-
- 沒有 `validate` 指令;0.8.0 開發期間的 DSM 規則已併入 `inspect`。專案檢查請用 `check`。
|
|
752
|
-
- native layout 以 `arches: [aarch64]` 建置時,INFO `arch` 改為與 native-go/binary 相同的
|
|
753
|
-
`armada37xx rtd1296 rtd1619 rtd1619b`。`layout.metadata` 的指令碼沒有執行權限時 `build` 以
|
|
754
|
-
`NATIVE_LAYOUT_SCRIPT_NOT_EXECUTABLE` 拒絕,請 `chmod +x`。`native.toolkits` 可用 GNU tar 與
|
|
755
|
-
bsdtar 解壓,其他 tar 以 `NATIVE_TOOLKIT_TAR_UNSUPPORTED` 失敗。
|
|
756
|
-
- 新增「封裝指令碼與直譯式語言」指南:編譯成單一執行檔、經 `native.toolkits` 附帶直譯器、或以
|
|
757
|
-
Compose 容器執行,附實測大小、架構與 glibc 需求,以及手動打包的 `noarch` shell SPK。CLI 無法宣告
|
|
758
|
-
`install_dep_packages` 依賴套件中心的 Node.js/Python 套件,指南已明確說明。
|
|
759
|
-
|
|
760
|
-
## 0.7.3 (2026-10-11)
|
|
761
|
-
|
|
762
|
-
Rebuild every package built with 0.7.2 that has `i18n.info` translations. In
|
|
763
|
-
0.7.2 its DSM main-menu entry, desktop shortcut and window title showed the raw
|
|
764
|
-
key `synopkgland:app_title` in every language.
|
|
765
|
-
|
|
766
|
-
### Translated DSM title fix
|
|
767
|
-
|
|
768
|
-
- `ui/config` entries that use the `synopkgland:app_title` and `app_desc`
|
|
769
|
-
strings now declare `"texts": "texts"`: the main-menu `app` entry, its window
|
|
770
|
-
`lib` entry and the `.url` entry of a `synology-app.yaml` app. DSM loads
|
|
771
|
-
`ui/texts/<DSM language>/strings` only for entries that declare `texts`, so
|
|
772
|
-
0.7.2 titles never resolved (seen on DSM 7.4 and 7.1.1). Without `i18n.info`
|
|
773
|
-
`ui/config` is unchanged.
|
|
774
|
-
|
|
775
|
-
### Correction to 0.7.2
|
|
776
|
-
|
|
777
|
-
- 0.7.2 said `synology-app.yaml` `i18n.info` localizes the DSM window title.
|
|
778
|
-
It localizes the DSM main-menu and desktop label only. `launch: dsm-window`
|
|
779
|
-
adds a main-menu and desktop entry that DSM always opens in a new browser
|
|
780
|
-
tab, as it does for every URL entry; the app has no DSM window and no window
|
|
781
|
-
title. This is not caused by DSM's CSRF protection setting. The container app
|
|
782
|
-
guide and the `synology-app.yaml` reference now say so.
|
|
783
|
-
|
|
784
|
-
### 繁體中文摘要
|
|
785
|
-
|
|
786
|
-
- 修正 0.7.2 的在地化標題:有 `i18n.info` 翻譯時,`ui/config` 中使用 `synopkgland:` 字串的
|
|
787
|
-
`app`、`lib` 與 `.url` 項目都加上 `"texts": "texts"`。0.7.2 少了這個欄位,DSM 不會載入
|
|
788
|
-
`ui/texts/<語言>/strings`,主選單、桌面捷徑與視窗標題在各語言都顯示 `synopkgland:app_title`。
|
|
789
|
-
- 用 0.7.2 建置且含 `i18n.info` 的套件,請以 0.7.3 重新建置並遞增 build 後重新發佈;沒有
|
|
790
|
-
`i18n.info` 的套件不受影響。
|
|
791
|
-
- 更正 0.7.2:`synology-app.yaml` 的 `i18n.info` 只翻譯 DSM 主選單與桌面標籤,沒有視窗標題。
|
|
792
|
-
`launch: dsm-window` 的項目一律由 DSM 在新的瀏覽器分頁開啟(DSM 對所有網址項目都如此),
|
|
793
|
-
與 CSRF 防護設定無關;容器 App 指南與 `synology-app.yaml` 參考已更正。
|
|
794
|
-
|
|
795
|
-
## 0.7.2 (2026-10-11)
|
|
796
|
-
|
|
797
|
-
Rebuild packages to pick up the new default icon. Packages without `icon` now
|
|
798
|
-
show the SDK default icon instead of a solid blue square.
|
|
799
|
-
|
|
800
|
-
### Package icon
|
|
801
|
-
|
|
802
|
-
- `dsm-package.yaml` and `synology-app.yaml` accept `icon`: a square PNG of at
|
|
803
|
-
least 256×256 inside the project, or a folder of `icon_<size>.png` (16, 24,
|
|
804
|
-
32, 48, 64, 72, 256; `icon_256.png` required, missing sizes scaled from it).
|
|
805
|
-
`build` writes `PACKAGE_ICON.PNG` (64×64), `PACKAGE_ICON_256.PNG` and every
|
|
806
|
-
DSM window size `ui/images/app_<size>.png` from it. SVG is not accepted, so
|
|
807
|
-
the CLI gains no image dependency. `check` refuses an icon outside the
|
|
808
|
-
project, a non-PNG, a non-square or smaller image, and one whose Package
|
|
809
|
-
Center icons exceed the package source's 256 KiB limit
|
|
810
|
-
(`STANDALONE_ICON_INVALID`, `CONTRACT_ICON_INVALID`).
|
|
811
|
-
|
|
812
|
-
- A native layout may set `icon` too; `build` then writes both Package Center
|
|
813
|
-
icons and refuses a metadata folder that also ships them. Without `icon` the
|
|
814
|
-
layout keeps owning its icons.
|
|
815
|
-
|
|
816
|
-
- `check` reports which icon a build uses: `圖示:自訂 <path>`, or `圖示:SDK
|
|
817
|
-
預設圖示` with an info hint about `icon:` (not an error). It warns when an
|
|
818
|
-
icon is a single colour. `check --json` reports it in `data.icon`.
|
|
819
|
-
|
|
820
|
-
- `inspect` reports `icon` as `default`, `custom` (with the SHA-256 of
|
|
821
|
-
`PACKAGE_ICON_256.PNG`) or `none`, and lists a Package Center icon over
|
|
822
|
-
256 KiB, of the wrong size or not a PNG as a finding.
|
|
823
|
-
|
|
824
|
-
- The SDK default icon replaces the solid blue square in Package Center, the
|
|
825
|
-
DSM main menu and the window. Sources are in `assets/default-icon/`.
|
|
826
|
-
|
|
827
|
-
### Translated DSM title
|
|
828
|
-
|
|
829
|
-
- With `i18n.info` translations, the DSM main-menu entry and window title
|
|
830
|
-
follow the DSM language. `ui/config` refers to `synopkgland:app_title` and
|
|
831
|
-
`app_desc` in `ui/texts/<DSM language>/strings`, written for English and each
|
|
832
|
-
translated language; a language without its own text shows the English one.
|
|
833
|
-
Without translations `ui/config` keeps the literal English title.
|
|
834
|
-
|
|
835
|
-
- `synology-app.yaml` accepts the same `i18n.info` block. It writes INFO
|
|
836
|
-
`displayname_<lang>` / `description_<lang>` and, with `launch: dsm-window`,
|
|
837
|
-
localizes the DSM window entry. Once a translation exists, the English
|
|
838
|
-
`displayname` and `description` must also be one line without `"` or `\`
|
|
839
|
-
(`CONTRACT_I18N_INVALID`).
|
|
840
|
-
|
|
841
|
-
### Delegate window
|
|
842
|
-
|
|
843
|
-
- A DSM window built for a `scope: install-selected` delegate no longer
|
|
844
|
-
contains the dead `if (panels && false)` check. The window leaves out the
|
|
845
|
-
approval panel code instead, and other scopes generate `if (panels)`. The
|
|
846
|
-
behavior is unchanged: this scope is approved only in the app's
|
|
847
|
-
**Administrator setup** panel, because that approval carries the scope the
|
|
848
|
-
administrator picks and the window panel has no scope picker. The delegate
|
|
849
|
-
guide now says so.
|
|
850
|
-
|
|
851
|
-
### 繁體中文摘要
|
|
852
|
-
|
|
853
|
-
- 升級後重新建置套件即可換上新的 SDK 預設圖示(不再是純藍方塊)。executor digest 不變,不需重新核准。
|
|
854
|
-
- `dsm-package.yaml`、`synology-app.yaml` 與 native layout 新增 `icon`:專案內至少 256×256 的正方形
|
|
855
|
-
PNG,或含 `icon_256.png` 的 `icon_<size>.png` 目錄;不接受 SVG。`check` 顯示使用的圖示並檢查格式與
|
|
856
|
-
256 KiB 上限,`inspect` 回報 `default`/`custom`/`none`。
|
|
857
|
-
- 有 `i18n.info` 翻譯時,DSM 主選單與視窗標題會跟著 DSM 語言切換;缺翻譯的語言顯示英文。
|
|
858
|
-
`synology-app.yaml` 也支援 `i18n.info`。
|
|
859
|
-
- `scope: install-selected` 的 DSM 視窗不再產生 `if (panels && false)` 死碼;此 scope 仍只在 App 的
|
|
860
|
-
「管理員設定」核准。
|
|
861
|
-
|
|
862
|
-
## 0.7.1 (2026-10-10)
|
|
863
|
-
|
|
864
|
-
Rebuild packages to pick up template, hook and executor changes. The executor
|
|
865
|
-
digest changed. A package built with CLI 0.7.0 needs one administrator approval
|
|
866
|
-
after upgrading to a 0.7.1 build: the 0.7.0 executor opened the package
|
|
867
|
-
`target` link without following it, so it cannot install the anchored executor
|
|
868
|
-
itself. Executor-only upgrades between 0.7.1 or later builds need no approval.
|
|
869
|
-
|
|
870
|
-
### Executor upgrade and daemon timeouts
|
|
871
|
-
|
|
872
|
-
- During an INFO-anchored executor-only upgrade the executor log said
|
|
873
|
-
`executor paused: package pins require administrator approval` about two
|
|
874
|
-
seconds before the new executor was ready. That line now appears only when
|
|
875
|
-
the pins differ; an anchored handover logs only `executor upgrade:
|
|
876
|
-
INFO-anchored executor installed under the approved policy`. The executor
|
|
877
|
-
digest changes.
|
|
878
|
-
|
|
879
|
-
- `executor_status_mismatch` in the app window and the app's settings names
|
|
880
|
-
its cause: `the approved executor is not answering (<reason>)`, `the running
|
|
881
|
-
executor reports other digests than this package pins`, or `the executor
|
|
882
|
-
status request failed` with the request's own code, instead of `scheduler
|
|
883
|
-
readback or operation failed` for all three. The Data and removal
|
|
884
|
-
troubleshooting table explains each.
|
|
885
|
-
|
|
886
|
-
- After approval or control start the window asked `executor.status` every
|
|
887
|
-
500 ms for up to 10 s. The wait now doubles from 500 ms to 2 s within the
|
|
888
|
-
same 10 s budget: at most 7 requests instead of 20.
|
|
889
|
-
|
|
890
|
-
- For live upgrade tests, the repository's `scripts/test/executor-bump.py`
|
|
891
|
-
makes an executor-only build+1 SPK and now rewrites the window script's
|
|
892
|
-
embedded pins with the INFO anchor and `executor/setup.json`. The earlier
|
|
893
|
-
out-of-tree copy left the window pins behind, so the panel reported
|
|
894
|
-
`executor_status_mismatch` after every such upgrade while CGI and CLI
|
|
895
|
-
status were ready.
|
|
896
|
-
|
|
897
|
-
- On kernel 3.10 (DSM 7.1, for example DS416 armv7) an executor-only
|
|
898
|
-
upgrade, and approving again while the executor runs, no longer fail
|
|
899
|
-
with "pid executable mismatch". That kernel names a running executor
|
|
900
|
-
replaced by a rename after the rename source (`runtime/.executor
|
|
901
|
-
(deleted)`), and root control accepted only `runtime/executor`. Root
|
|
902
|
-
control now identifies the monitor by inode: the current
|
|
903
|
-
`runtime/executor`, or an unlinked root-owned inode on the runtime's
|
|
904
|
-
device whose last name was `executor` or `.executor*` in the runtime.
|
|
905
|
-
The fix runs in the new executor, which the installed one starts: an
|
|
906
|
-
upgrade from a package built with the target-link fix below needs no
|
|
907
|
-
approval; from 0.7.0 it still needs the one approval described there.
|
|
908
|
-
The executor digest changes.
|
|
909
|
-
|
|
910
|
-
- When the approved tasks are ready but the executor does not answer
|
|
911
|
-
(`executor_status_mismatch`), the app window offers Approve background
|
|
912
|
-
access again. With the tasks approved, it restarts the executor without
|
|
913
|
-
a password.
|
|
914
|
-
|
|
915
|
-
- `executor.status` (root-ops) names approval, not "Start the package", as
|
|
916
|
-
the next step when the package's last lifecycle request was start.
|
|
917
|
-
Regenerate or copy `backend/internal/app/executor.go`.
|
|
918
|
-
|
|
919
|
-
- An executor-only upgrade (same policy, new executor matching the INFO
|
|
920
|
-
`synopkgland_executor_sha256` anchor) no longer fails with "executor
|
|
921
|
-
upgrade refused: INFO-anchored executor could not be installed". The
|
|
922
|
-
installer opened `/var/packages/<pkg>/target/executor` without following
|
|
923
|
-
the DSM `target` link, which the executor refuses, so every such upgrade
|
|
924
|
-
stayed paused. The fix runs in the executor that is already installed:
|
|
925
|
-
an upgrade from a package built with an earlier SDK still needs one
|
|
926
|
-
administrator approval. The executor digest changes.
|
|
927
|
-
|
|
928
|
-
- `executor.status` (root-ops and delegate projects) no longer answers
|
|
929
|
-
`internal` while the executor is paused (package stopped, or pins waiting
|
|
930
|
-
for approval). It answers `{ready: false, state: "paused", reason:
|
|
931
|
-
"executor_not_listening", next}`, and `synopkgland status` shows the
|
|
932
|
-
reason and next step. Regenerate or copy
|
|
933
|
-
`backend/internal/app/executor.go` into existing projects.
|
|
934
|
-
|
|
935
|
-
- `daemon.timeouts` defaults are now `{start: 30, stop: 30, status: 5,
|
|
936
|
-
uninstall: 60}` (were `start: 5, stop: 10, status: 2`). On vt-nas under
|
|
937
|
-
IO load a boot start took more than 5 s and a Connect revoke more than
|
|
938
|
-
9 s. The new `timeouts.uninstall` (2–120) bounds `uninstall_args`
|
|
939
|
-
separately; it used to get `stop - 1`, so an app had to raise the SIGKILL
|
|
940
|
-
wait to give its revoke time. DSM's package unit allows 3600 s for start
|
|
941
|
-
and stop. `inspect` still accepts SPKs built before `timeouts.uninstall`.
|
|
942
|
-
The manifest reference explains how to pick values from a loaded NAS.
|
|
943
|
-
|
|
944
|
-
### Approval, identity and uninstall fixes
|
|
945
|
-
|
|
946
|
-
- `identity: standalone`: "Continue with DSM" and every live revalidation
|
|
947
|
-
failed with `session_required` after a DSM web login, because DSM web
|
|
948
|
-
sessions enable SynoToken and DSM answers the `id` cookie alone with 119.
|
|
949
|
-
The backend now forwards the request's single `X-SYNO-TOKEN` header, which
|
|
950
|
-
the DSM window's `ctx.call` already sends, when it checks the DSM session.
|
|
951
|
-
Sessions without SynoToken still verify with the cookie alone. The token is
|
|
952
|
-
never put in a URL, logged or stored. This also unblocks root-ops approval
|
|
953
|
-
in an `identity: standalone` package, which stopped at `executor.control`.
|
|
954
|
-
Existing projects need the updated `internal/identity` files.
|
|
955
|
-
- When approval created and read back both tasks but the executor then did
|
|
956
|
-
not start or report healthy, the window left the tasks behind, and with no
|
|
957
|
-
running executor there was no task inventory for uninstall to delete them.
|
|
958
|
-
The window now withdraws the tasks that approval created; tasks from an
|
|
959
|
-
earlier approval stay.
|
|
960
|
-
- After a wrong password or a withdrawn approval, the window panel showed
|
|
961
|
-
only "Check status". It and the app's settings now keep the approve action.
|
|
962
|
-
- Uninstall no longer logs `task cleanup unconfirmed` for every successful
|
|
963
|
-
delete: EventScheduler `delete` v1 and TaskScheduler `delete` v2 answer
|
|
964
|
-
`{"success":true}` without data, which now counts as confirmed. The task
|
|
965
|
-
definitions are unchanged, so no new approval is needed; the executor
|
|
966
|
-
digest changes.
|
|
967
|
-
- The native root window (`@synopackageland/cli/authorization-sdk`) gave up
|
|
968
|
-
after about 30 s with `root_timeout`, while a loaded NAS ran the bootstrap
|
|
969
|
-
task for up to 4.5 minutes. It now keeps waiting while the task is queued or
|
|
970
|
-
running, up to 10 minutes, reports `{op, state, elapsedMs}` through
|
|
971
|
-
`options.progress`, and the authorization flow accepts the backend's ready
|
|
972
|
-
grant after `root_timeout` or `root_task_failed`.
|
|
973
|
-
- A DSM certificate that Node does not trust failed with only
|
|
974
|
-
`fetch failed`. The CLI now reports `DSM_TLS_UNTRUSTED` with the origin and
|
|
975
|
-
certificate error and points to `NODE_EXTRA_CA_CERTS`; certificate checks
|
|
976
|
-
stay on.
|
|
977
|
-
- Docs: on DSM 7.1 the purge timing lines are only in the journal
|
|
978
|
-
(`journalctl -t synopkgland-executor`); `init -t native-go` does not include
|
|
979
|
-
`armv7` in `arches`, so add it for an armv7 NAS.
|
|
980
|
-
|
|
981
|
-
### Deploy and status fixes
|
|
982
|
-
|
|
983
|
-
- `status` no longer reports `blocked` for every `identity: standalone`
|
|
984
|
-
project. It opens a short-lived App session from the administrator's DSM
|
|
985
|
-
session, reads `executor.status`, then logs out. That needs an `https://`
|
|
986
|
-
host; over `http://` the capability stays `blocked` and the reason says so.
|
|
987
|
-
- `deploy` accepts the install wizard values of an `install-selected`
|
|
988
|
-
delegate: `--param delegate_share=<Shared Folder>` or
|
|
989
|
-
`--param delegate_home=true`. A first install without one now fails with
|
|
990
|
-
`DEPLOY_PARAM_REQUIRED` and a usage line before anything is built, instead
|
|
991
|
-
of failing inside DSM. Invalid values fail with `DEPLOY_PARAM_TYPE_INVALID`.
|
|
992
|
-
- `deploy` and `status` work on a native layout (existing native product).
|
|
993
|
-
`deploy` builds the NAS architecture only; an `aarch64` NAS uses a declared
|
|
994
|
-
`armv8`.
|
|
995
|
-
- The deploy note no longer says every upgrade needs approval: an
|
|
996
|
-
executor-only upgrade stays ready; a policy digest change needs approval.
|
|
997
|
-
- Uninstall logs per-phase purge timing with the package name to the system
|
|
998
|
-
log (`synopkgland-executor`): `task cleanup timing` per task and
|
|
999
|
-
`purge timing` for the task and file phases. The executor digest changes.
|
|
1000
|
-
- `add root-ops` and `add portal` print a notice on stderr when they raise
|
|
1001
|
-
`os_min_ver`.
|
|
1002
|
-
- `inspect` on an executor SPK describes the root boot and control tasks
|
|
1003
|
-
instead of saying the package needs no root privileges.
|
|
1004
|
-
|
|
1005
|
-
### DSM 7.1: root-ops and delegate approval work
|
|
1006
|
-
|
|
1007
|
-
- DSM 7.1.1 has no `SYNO.Core.TaskScheduler.Root` or
|
|
1008
|
-
`SYNO.Core.EventScheduler.Root`, TaskScheduler stops at v3 and
|
|
1009
|
-
PasswordConfirm at v1, so approval failed with "Background file access is
|
|
1010
|
-
unavailable" and `status`/`deploy` showed `rootOps: unsupported — DSM 103`
|
|
1011
|
-
or `DSM 104`. DSM 7.1.1 answers a version above the API's maximum with 104
|
|
1012
|
-
(PasswordConfirm v2, TaskScheduler `get` v4) and a method missing at an
|
|
1013
|
-
existing version with 103 (TaskScheduler `list` v3). When DSM answers a
|
|
1014
|
-
scheduler read or the password check with 103 or 104, the app now uses
|
|
1015
|
-
PasswordConfirm v1, TaskScheduler `list` v2/`get` v3 and creates
|
|
1016
|
-
the tasks with EventScheduler `create` v1 and TaskScheduler `create` v3.
|
|
1017
|
-
The password is still confirmed first and both tasks are still read back
|
|
1018
|
-
exactly before anything runs. Other errors (such as 105, 119, 102 or a
|
|
1019
|
-
wrong password, 3121) never fall back, and a create is never retried. DSM
|
|
1020
|
-
7.1 does not bind task creation to the password check; see the root-ops
|
|
1021
|
-
guide.
|
|
1022
|
-
- `status` and `deploy` read the control task the same way.
|
|
1023
|
-
- Uninstall on DSM 7.1 now removes the boot and control tasks. The executor
|
|
1024
|
-
looked the control task up with TaskScheduler `get` v4, which DSM 7.1.1
|
|
1025
|
-
refuses with 104, so it wrote no task inventory and left both tasks behind.
|
|
1026
|
-
- If approval stops after it created a task (for example, the boot task was
|
|
1027
|
-
created and the control task was not), the app deletes the tasks it created
|
|
1028
|
-
in that attempt instead of leaving an enabled root boot task that nothing
|
|
1029
|
-
owns. Tasks from an earlier approval stay.
|
|
1030
|
-
- A failed approval shows its reason and DSM error code in the app's settings
|
|
1031
|
-
instead of only "Background file access is unavailable", and a refused
|
|
1032
|
-
password reads as a password failure, not a scheduler failure.
|
|
1033
|
-
- After the app's settings approve, the window's status line no longer shows
|
|
1034
|
-
"needs-admin-approval: Task is missing" until a reload; the window panel and
|
|
1035
|
-
the settings now follow each other's results.
|
|
1036
|
-
|
|
1037
|
-
### DSM 7.1: jobs import and file downloads
|
|
1038
|
-
|
|
1039
|
-
- DSM 7.1.1 sends `SYNO.FileStation.Download` v2 replies without
|
|
1040
|
-
`Content-Disposition`, so `bg.jobs.submit` and downloads failed with
|
|
1041
|
-
`unavailable`. With no such header, a body of at most 4 KiB that decodes
|
|
1042
|
-
as a DSM reply is still refused as that reply; any other body is the file.
|
|
1043
|
-
|
|
1044
|
-
### Docs: build your own armv7 Go code with Go 1.26.9
|
|
1045
|
-
|
|
1046
|
-
- On armv7 DSM 7.1.1 (kernel 3.10), a program built with Go 1.26.0 crashed
|
|
1047
|
-
at start (`futexwakeup returned -22`, SIGSEGV) and Go 1.26.9 ran. Other
|
|
1048
|
-
1.26 releases were not tested.
|
|
1049
|
-
|
|
1050
|
-
### init: next steps install frontend dependencies
|
|
1051
|
-
|
|
1052
|
-
- `init -t native-go` with a Vue frontend now lists `(cd frontend && npm ci)`
|
|
1053
|
-
before `synopkgland build`; without it the build fails with
|
|
1054
|
-
`STANDALONE_UI_BUILD_FAILED`. `build` still does not install dependencies.
|
|
1055
|
-
|
|
1056
|
-
### Executor, daemon and gateway build with exactly Go 1.26.9
|
|
1057
|
-
|
|
1058
|
-
- The CLI builds the executor, lifecycle helper, daemon controller and gateway
|
|
1059
|
-
with `GOTOOLCHAIN=go1.26.9`, ignoring your `GOTOOLCHAIN`, `GOFLAGS`,
|
|
1060
|
-
`GOEXPERIMENT`, `GOWORK` and `GOAMD64`/`GOARM64`, so every builder produces
|
|
1061
|
-
the same executor digest. Go 1.21 or later downloads go1.26.9 when needed;
|
|
1062
|
-
offline without it the build fails and names go1.26.9. A binary whose Go
|
|
1063
|
-
build info names another release is refused.
|
|
1064
|
-
- Template go.mod files now say `toolchain go1.26.9`. The executor digest
|
|
1065
|
-
changes; it is anchored in INFO, so an upgrade with an unchanged policy needs
|
|
1066
|
-
no new approval.
|
|
1067
|
-
|
|
1068
|
-
### INFO arch: four more DSM platforms
|
|
1069
|
-
|
|
1070
|
-
- x86_64 SPKs now also list `broadwellntb`, `coffeelake` and `skylaked`, and
|
|
1071
|
-
aarch64 SPKs list `rtd1619` (DSM Developer Guide Appendix A family members).
|
|
1072
|
-
INFO `arch` now matches the platforms the package source maps to each family.
|
|
1073
|
-
|
|
1074
|
-
### 繁體中文摘要
|
|
1075
|
-
|
|
1076
|
-
- 升級後重新建置套件;executor digest 改變。**從 0.7.0 建的套件升級需管理員再核准一次**(0.7.0 的
|
|
1077
|
-
executor 開啟套件 `target` symlink 時未跟隨連結,無法自行安裝錨定的 executor);之後 0.7.1 起的
|
|
1078
|
-
executor-only 升級不需核准。
|
|
1079
|
-
- executor:kernel 3.10(DSM 7.1,如 DS416 armv7)上 executor-only 升級與執行中再核准不再出現
|
|
1080
|
-
`pid executable mismatch`;INFO 錨定升級不再誤報 `executor upgrade refused`,也不再先印
|
|
1081
|
-
「paused: 需管理員核准」;`executor.status` 暫停時回 `paused`/`executor_not_listening` 與下一步。
|
|
1082
|
-
- 面板:executor 不回應時可再按一次「Approve background access」免密碼重啟;
|
|
1083
|
-
`executor_status_mismatch` 會寫出原因(不回應/digest 不同/status 請求失敗);
|
|
1084
|
-
啟動後的 `executor.status` 等待改為 500 ms→2 s 退避,10 s 預算不變。
|
|
1085
|
-
- `daemon.timeouts` 預設改為 `{start: 30, stop: 30, status: 5, uninstall: 60}`,新增 `timeouts.uninstall`。
|
|
1086
|
-
- `identity: standalone`:DSM 網頁 session(SynoToken)下「Continue with DSM」與 root-ops 核准修正;
|
|
1087
|
-
核准建立 task 後 executor 未啟動時自動撤回本次建立的 task;卸載不再誤記 `task cleanup unconfirmed`。
|
|
1088
|
-
- 原生 root window 等待上限改為 10 分鐘並回報進度;`DSM_TLS_UNTRUSTED` 指向 `NODE_EXTRA_CA_CERTS`。
|
|
1089
|
-
- `status`/`deploy`:standalone 專案的 status 改用短期 App session;`deploy` 接受
|
|
1090
|
-
install-selected delegate 的精靈參數;支援 native layout;卸載記錄 purge timing。
|
|
1091
|
-
- DSM 7.1:無 Root API 時改走 PasswordConfirm v1/TaskScheduler v2–v3/EventScheduler create v1,
|
|
1092
|
-
卸載會移除 boot/control task;`SYNO.FileStation.Download` v2 無 `Content-Disposition` 的下載修正。
|
|
1093
|
-
- 建置:executor、lifecycle、daemon、gateway 一律以 Go 1.26.9 建置(armv7 kernel 3.10 上 1.26.0 會當機);
|
|
1094
|
-
INFO `arch` 新增 `broadwellntb`、`coffeelake`、`skylaked`、`rtd1619`。
|
|
1095
|
-
- 測試工具:`scripts/test/executor-bump.py` 收進 repo,會一併改寫視窗腳本內嵌的 executor pin。
|
|
1096
|
-
|
|
1097
|
-
## 0.7.0 (2026-10-10)
|
|
1098
|
-
|
|
1099
|
-
Rebuild packages to pick up template, hook and executor changes. The executor
|
|
1100
|
-
digest changed: apps approved under an earlier CLI need one administrator
|
|
1101
|
-
approval after upgrading.
|
|
1102
|
-
|
|
1103
|
-
### Delegate: save destinations that last until revoked
|
|
1104
|
-
|
|
1105
|
-
- `init --with delegate` / `add delegate` now declare `operations:
|
|
1106
|
-
[files.moveFromStaging]`, `destinations: [save]`, `lifetime: until-revoked`,
|
|
1107
|
-
`scope: install-selected`. Existing TTL declarations (`files.list` …
|
|
1108
|
-
`files.write`, `scope: home`) keep their API and limits.
|
|
1109
|
-
- The install wizard pre-selects home or a local share and an administrator
|
|
1110
|
-
confirms it once. Choosing a destination in the SDK NasPicker grants it until
|
|
1111
|
-
revoked, after fresh DSM session, UID and write checks; administrators run as
|
|
1112
|
-
their own UID, never root. Read the choice from `delegate.status`
|
|
1113
|
-
`selection`, `sdk.destination(key)` or Go `Service.Destination`.
|
|
1114
|
-
- Daemon and export producers save through Go `Service.MoveFromStaging`. The
|
|
1115
|
-
generated Background saves page (`createBackgroundSaveFacade`) lists, cancels
|
|
1116
|
-
and revokes them and includes a working example (`ExportExample`). Daemon can
|
|
1117
|
-
combine with an until-revoked delegate worker.
|
|
1118
|
-
- Retrying `MoveFromStaging` with the same params never copies twice. Journal
|
|
1119
|
-
errors `canceled`, `jobs_busy` and `jobs_unavailable` are retryable;
|
|
1120
|
-
`spool_unsafe` and `journal_corrupt` are terminal.
|
|
1121
|
-
- Cancel is idempotent per reference and survives executor crash, package
|
|
1122
|
-
restart and logout. Revoke, scope change and disable settle copies in flight
|
|
1123
|
-
as `canceled` with that reason (for example `scope-changed`); a scope change
|
|
1124
|
-
no longer restarts the executor. Poll `ctx.executor.status()` while a change
|
|
1125
|
-
answers `blocked`.
|
|
1126
|
-
- Full device lifecycle acceptance (install → setup → reboot → upgrade → revoke
|
|
1127
|
-
→ uninstall) is still pending.
|
|
1128
|
-
|
|
1129
|
-
### Executor
|
|
1130
|
-
|
|
1131
|
-
- Upgrades keep approval: each SPK writes its executor SHA-256 into INFO
|
|
1132
|
-
(`synopkgland_executor_sha256`), and a new executor that matches it installs
|
|
1133
|
-
without PasswordConfirm as long as the policy is unchanged. Policy changes
|
|
1134
|
-
(operations, scope, destinations, root scripts) still need approval. `inspect`
|
|
1135
|
-
refuses a missing, duplicated or different anchor.
|
|
1136
|
-
- A root supervisor restarts the monitor after a crash or kill (1–60 s
|
|
1137
|
-
backoff), so delegate and rootOps recover without a reboot.
|
|
1138
|
-
- Every write publishes only through the executor handshake. A copy whose
|
|
1139
|
-
executor died stops within 1 MiB and removes its `.part`; a lost publish
|
|
1140
|
-
receipt settles `committed` without copying again.
|
|
1141
|
-
- A package without an executor can add one in place on upgrade. Upgrade does
|
|
1142
|
-
not approve an install-selected scope; confirm it in Settings.
|
|
1143
|
-
- Uninstalling a stopped package no longer leaves root tasks and the monitor
|
|
1144
|
-
running for ten minutes; the hook waits at most 50 s for the executor to clean
|
|
1145
|
-
up.
|
|
1146
|
-
|
|
1147
|
-
### Native layout: per-architecture INFO trust anchors
|
|
1148
|
-
|
|
1149
|
-
- `layout.anchors` maps `<key>_sha256` to a payload file. `build` writes that
|
|
1150
|
-
architecture's SHA-256 of the file into INFO, so a product root helper can
|
|
1151
|
-
trust a new build through the root-owned INFO instead of reapproval. Keys
|
|
1152
|
-
match `^[a-z][a-z0-9_]{0,48}_sha256$`, the `synopkgland_` prefix is reserved,
|
|
1153
|
-
and at most 16 are allowed. `inspect` refuses a changed, duplicated, missing
|
|
1154
|
-
or undeclared anchor.
|
|
1155
|
-
|
|
1156
|
-
### App entry and Application Privileges
|
|
1157
|
-
|
|
1158
|
-
- `entry: admin-only` admits administrators only, on every route including the
|
|
1159
|
-
SDK routes; ordinary users get `admin_required`. `entry: app-privilege`
|
|
1160
|
-
registers the app in Control Panel > Application Privileges and gates every
|
|
1161
|
-
route on DSM's decision (`app_privilege_denied`). Omitting `entry` keeps the
|
|
1162
|
-
previous behaviour and byte-identical SPKs.
|
|
1163
|
-
- With an `entry`, an app route marked `authenticated` or `public` fails with
|
|
1164
|
-
`STANDALONE_ENTRY_WIDENED`. `inspect` prints the entry mode and flags
|
|
1165
|
-
`ENTRY_LAUNCHER_MISMATCH`.
|
|
1166
|
-
- The executor applies the same rule: moves for a user DSM no longer allows are
|
|
1167
|
-
refused (`APP_DENIED`).
|
|
1168
|
-
- `ctx.user = {name, isAdmin}` lets UIs hide administrator settings; guard them
|
|
1169
|
-
on the server with Go `api.RequireAdmin(caller)`.
|
|
1170
|
-
- On Linux 3.10 kernels without `memfd_create` (DSM 7 on x86_64 avoton,
|
|
1171
|
-
braswell, bromolow, grantley) the administrator and App Privileges bridges run
|
|
1172
|
-
from an unlinked file in the package's own tmp instead of failing. That path
|
|
1173
|
-
has no memfd seal. Verified on DSM 7.1.1 with an armv7 build only; no x86_64
|
|
1174
|
-
Linux 3.10 model has been tested.
|
|
1175
|
-
|
|
1176
|
-
### Application Portal
|
|
1177
|
-
|
|
1178
|
-
- `portal: {}` or `portal: {alias}` (native) and `integration.web.portal`
|
|
1179
|
-
(Compose DSM-window apps); `synopkgland add portal` adds it. The install
|
|
1180
|
-
wizard prefills the alias, upgrades keep it and an administrator activates it.
|
|
1181
|
-
- `ctx.portal.mountPanel(element)` shows the link, or the alias form to
|
|
1182
|
-
administrators; the Vue and plain starters mount it.
|
|
1183
|
-
- A portal needs `os_min_ver` 7.3.2-86009 or later (DSM 7.1.1 rejects it with
|
|
1184
|
-
error 320; 7.2 is untested). validate/build fail with
|
|
1185
|
-
`STANDALONE_PORTAL_MIN_DSM` / `CONTRACT_PORTAL_MIN_DSM`, and `add portal`
|
|
1186
|
-
raises a lower `os_min_ver`.
|
|
1187
|
-
|
|
1188
|
-
### Catalog metadata
|
|
1189
|
-
|
|
1190
|
-
- An optional `metadata:` block (contact/support email, homepage, source and
|
|
1191
|
-
issues URLs, license, localized long description, changelog, screenshots) is
|
|
1192
|
-
validated and written to INFO for the package catalog.
|
|
1193
|
-
- `metadata.changelog` may be a per-language map. Package Center shows one line
|
|
1194
|
-
in the NAS language, so put the most important change first.
|
|
1195
|
-
|
|
1196
|
-
### Native authorization
|
|
1197
|
-
|
|
1198
|
-
- `authorization_required` gains `reason: upgrade_reapproval` when an upgrade
|
|
1199
|
-
revoked the old grant; the Gate template explains the next step in nine
|
|
1200
|
-
languages. Products that sync the Gate need their helper to write and clear
|
|
1201
|
-
the reason-only tombstone, which grants nothing.
|
|
1202
|
-
|
|
1203
|
-
### Lifecycle
|
|
1204
|
-
|
|
1205
|
-
- Background packages restart a package user systemd manager that lost its
|
|
1206
|
-
runtime socket; a failed worker start names the unit, exit code and socket
|
|
1207
|
-
state.
|
|
1208
|
-
- Stopping the worker is idempotent, fixing uninstall failure 314 for
|
|
1209
|
-
delegate+daemon+jobs.
|
|
1210
|
-
|
|
1211
|
-
### Templates in nine languages
|
|
1212
|
-
|
|
1213
|
-
- All template UI text and install, upgrade and uninstall wizard messages come
|
|
1214
|
-
from catalogs in the nine DSM languages and follow DSM glossary wording. Sizes
|
|
1215
|
-
use DSM's 1024-based KB/MB/GB. Rebuilt Vue and binary SPKs change bytes;
|
|
1216
|
-
plain-UI SPKs are unchanged.
|
|
1217
|
-
- Vue templates pin public `@synopackageland/ui@0.8.1`; the upload FilePicker
|
|
1218
|
-
states `max 16 GB`.
|
|
1219
|
-
|
|
1220
|
-
### armv7 (32-bit ARM) for native-go and binary packages
|
|
1221
|
-
|
|
1222
|
-
- `arches` accepts `armv7` (INFO `alpine alpine4k armada38x monaco`, DSM 7.2+);
|
|
1223
|
-
the default stays `[x86_64, aarch64]`. It covers the Go CGI (plain or Vue UI),
|
|
1224
|
-
`backend.kind: binary`, jobs, daemon, root-ops and delegate. Container
|
|
1225
|
-
projects refuse it with `CONTAINER_ARCH_UNSUPPORTED`.
|
|
1226
|
-
- The plain native-go CGI was verified on a DS416 (DSM 7.1.1, `alpine4k`).
|
|
1227
|
-
armv7 jobs, daemon, executor and lifecycle helper are built and checked but
|
|
1228
|
-
not yet verified on a NAS; `armada38x` and `monaco` are untested.
|
|
1229
|
-
- `deploy` detects armv7 from an Annapurna Labs CPU and asks for `--arch` on a
|
|
1230
|
-
Marvell CPU. x86_64 and aarch64 bridge, executor and lifecycle bytes are
|
|
1231
|
-
unchanged by the armv7 work.
|
|
1232
|
-
|
|
1233
|
-
### Packaging
|
|
1234
|
-
|
|
1235
|
-
- The npm tarball includes this CHANGELOG.md.
|
|
1236
|
-
|
|
1237
|
-
### 繁體中文摘要
|
|
1238
|
-
|
|
1239
|
-
- 升級後重新建置套件;executor digest 改變,舊版 CLI 核准過的 app 需要管理員再核准一次。
|
|
1240
|
-
- delegate:預設改為長期存檔目的地(`files.moveFromStaging`、安裝時選 scope、管理員確認一次、
|
|
1241
|
-
在 NasPicker 選目的地即授權至撤銷);Background saves 頁、`MoveFromStaging` 重送不重複複製、
|
|
1242
|
-
取消跨重啟保留。完整裝置生命週期驗收仍待完成。
|
|
1243
|
-
- executor:INFO 錨定 executor SHA-256,policy 不變的升級免再核准;root supervisor 異常後自動重啟;
|
|
1244
|
-
卸載已停止的套件不再殘留 root task。
|
|
1245
|
-
- 原生 layout:`layout.anchors` 依架構把 payload 檔 SHA-256 寫進 INFO,作為產品 root helper 的信任錨點。
|
|
1246
|
-
- `entry: admin-only | app-privilege`(DSM 應用程式權限)、`ctx.user.isAdmin`、`api.RequireAdmin`;
|
|
1247
|
-
未宣告 entry 的 SPK 不變。Linux 3.10 無 memfd_create 時 bridge 改由套件 tmp 執行(無 memfd seal)。
|
|
1248
|
-
- Application Portal(`portal:`、`add portal`、`ctx.portal`),需 os_min_ver 7.3.2-86009 以上;
|
|
1249
|
-
目錄 `metadata:` 寫入 INFO,`metadata.changelog` 可依語言分開。
|
|
1250
|
-
- 授權契約新增 `reason: upgrade_reapproval`;背景套件 user manager 恢復、卸載 314 修正。
|
|
1251
|
-
- 範本與安裝精靈全部九語系並依 DSM 用語;Vue 範本固定 UI 0.8.1。
|
|
1252
|
-
- armv7(DSM 7.2+)支援 native-go 與 binary;plain CGI 已在 DS416 實機驗證,jobs/daemon/executor 尚未實機驗證。
|
|
1253
|
-
- npm 套件附 CHANGELOG.md。
|
|
1254
|
-
|
|
1255
|
-
## 0.6.1
|
|
1256
|
-
|
|
1257
|
-
- Restore native product packaging as a formal schema 2 `backend: {kind: native}`
|
|
1258
|
-
route. Keep project-owned multi-binary payload/metadata layout, prepare/compile
|
|
1259
|
-
argv hooks, HTTPS/SHA-256 toolkit acquisition and x86_64/aarch64/armv8/armv7.
|
|
1260
|
-
`check`, `build` and `inspect --json` preserve package-only lifecycle/systemd
|
|
1261
|
-
registration and reject root service accounts, privileged execution prefixes,
|
|
1262
|
-
symlinks, setuid files and corrupt toolkit/payload inventories.
|
|
1263
|
-
- Restore `@synopackageland/cli/authorization-sdk` as an explicit native-product
|
|
1264
|
-
adapter with exact pinned-task identity, fresh administrator approval and
|
|
1265
|
-
withdrawal-before-task-removal; do not change generated Go executor semantics.
|
|
1266
|
-
Export `./native-layout` and retain direct `./dist/*` imports.
|
|
1267
|
-
- Document field migration from schema 1 without changing product bootstrap pins,
|
|
1268
|
-
per-build revocation/reapproval or dynamic DSM ABI declarations. Schema 1 remains
|
|
1269
|
-
rejected; no compatibility aliases for retired CLI commands. Generated schema 2
|
|
1270
|
-
check/build/status/logs and Connect/Gopeed APIs remain unchanged.
|
|
1271
|
-
- Align SKILL.md with the shipped delegate/rootOps executor implementation and
|
|
1272
|
-
its documented device acceptance boundaries.
|
|
1273
|
-
- 正式補回 schema 2 原生產品 layout/hooks/toolkit/三架構及 authorization SDK。
|
|
1274
|
-
lifecycle/systemd 維持 package account;root 僅由產品明確核准 digest,
|
|
1275
|
-
不自動授權、不取消逐 build 撤權再授權。新增 Reclaim 欄位 migration 指引。
|
|
1276
|
-
|
|
1277
|
-
## 0.6.0
|
|
1278
|
-
|
|
1279
|
-
- Adopt UI 0.8.0 and its renamed `syno-pkg-land-ui` executable (no old alias).
|
|
1280
|
-
Pin generated Vue apps and all overlays to the public npm artifact and integrity.
|
|
1281
|
-
Skills discover the installed prompt/catalog/describe contract with
|
|
1282
|
-
`npx --no syno-pkg-land-ui`; one-off use explicitly selects the npm package.
|
|
1283
|
-
Render defaults to `syno-pkg-land-ui-render`. CSS/data selectors use the
|
|
1284
|
-
`syno-pkg-land-ui` namespace without old aliases (including select attributes).
|
|
1285
|
-
Add a regression audit for executable names and retired CSS/data selectors in
|
|
1286
|
-
skills, templates, source, tests, docs and scripts; only released history is exempt.
|
|
1287
|
-
跟進 UI 0.8.0 的 CLI 改名及公開 npm integrity;AI 指引維持版本無關,
|
|
1288
|
-
使用已安裝契約,並防止指令名與 selector 回退。預設截圖目錄改為
|
|
1289
|
-
`syno-pkg-land-ui-render`;CSS/data selector 全面使用新 namespace,不保留 alias。
|
|
1290
|
-
|
|
1291
|
-
- Add version-independent Vue UI guidance alongside JSON UI guidance. All
|
|
1292
|
-
generated projects include AGENTS.md and a CLAUDE.md pointer to discover the
|
|
1293
|
-
bundled skills and run local check/build/inspect before authorized NAS work.
|
|
1294
|
-
Template design notes use installed UI contracts while dependency pins remain.
|
|
1295
|
-
新增 Vue UI skill;所有 scaffold 提供 AI 入口與本機驗證流程,設計文件依已安裝
|
|
1296
|
-
SDK 契約,依賴鎖定不變。
|
|
1297
|
-
|
|
1298
|
-
- **Breaking: remove `./authorization-sdk` and the legacy root authorization
|
|
1299
|
-
templates and adapters.** Use delegate/root-ops capabilities and the protected
|
|
1300
|
-
executor with one-time administrator approval; no compatibility exports remain.
|
|
1301
|
-
**不保留相容**:移除 `./authorization-sdk` 與舊 root authorization 模板/adapter,
|
|
1302
|
-
改用 delegate/root-ops 能力及受保護 executor 的一次管理員核准。
|
|
1303
|
-
|
|
1304
|
-
- Pin generated Vue apps to public `@synopackageland/ui@0.8.0` with its npm
|
|
1305
|
-
integrity; keep bounded app-local modal roots, embedded CSS and unique mount
|
|
1306
|
-
ID prefixes, and explicitly retain DSM window layout at wide sizes.
|
|
1307
|
-
Add `skill show ui-json` with installed prompt/catalog/schema discovery,
|
|
1308
|
-
strict validation and screenshot/layout checks through the published `syno-pkg-land-ui`
|
|
1309
|
-
package bin. Update the template
|
|
1310
|
-
DOM test dependency and website configuration to remove gate warnings.
|
|
1311
|
-
Vue 模板固定公開 UI 0.8.0 與 integrity,維持 DSM 的 app scope、embedded CSS、
|
|
1312
|
-
唯一 mount ID 與 window layout;新增不固定版本的 JSON UI skill,依已安裝
|
|
1313
|
-
catalog/schema 產生、嚴格驗證並 render,直接使用套件的 `syno-pkg-land-ui` bin。
|
|
1314
|
-
|
|
1315
|
-
- **Delegate (C), P2/v10 (through 26030e74):** `init --with delegate` / `add delegate` imply jobs;
|
|
1316
|
-
manifest operations use the five fixed files.* IDs with home/shared scope.
|
|
1317
|
-
The worker stages downloads and writes as the consenting user after browser
|
|
1318
|
-
close, without overwriting existing files or retaining DSM credentials.
|
|
1319
|
-
C/R share one-password boot/control task setup and digest approval; stop pauses,
|
|
1320
|
-
start resumes identical pins, changed policy requires reapproval, and uninstall
|
|
1321
|
-
requests asynchronous own-task/protected-state purge (normally seconds with a
|
|
1322
|
-
healthy monitor), with manual cleanup guidance. Task deletion requires byte-for-byte
|
|
1323
|
-
equality with canonical scripts regenerated from package identity and approved pins.
|
|
1324
|
-
Purge reapproval recreates tasks and writes `start` before boot; mailbox failure
|
|
1325
|
-
blocks boot. Local fake-DSM/real-executor lifecycle tests cover this recovery.
|
|
1326
|
-
Package-directory/INFO identity absence immediately pauses the socket/requests,
|
|
1327
|
-
retaining the monitor, approved runtime, delegations and tasks. Polling every
|
|
1328
|
-
500 ms must confirm 10 continuous minutes of absence before fallback purge;
|
|
1329
|
-
reappearance or unverifiable absence resets the timer, with uncertainty staying paused.
|
|
1330
|
-
Recovery rereads even an unchanged mailbox: matching-pin `start` resumes,
|
|
1331
|
-
changed pins stay paused/needs-admin-approval, `stop` stays paused, and `purge`
|
|
1332
|
-
immediately clears state. Temporary DSM-upgrade gaps preserve protected state;
|
|
1333
|
-
preuninst purge remains immediate, with asynchronous cleanup. Boot's absent-package
|
|
1334
|
-
retained-pin purge remains immediate. Local tests cover upgrade gaps, recovery,
|
|
1335
|
-
timer/reset rules and immediate preuninst purge; device acceptance remains separate.
|
|
1336
|
-
Malformed AppPriv responses fail closed, including duplicate keys/target entries,
|
|
1337
|
-
null/missing data and nested error keys. Matching token header aliases are allowed;
|
|
1338
|
-
conflicting/repeated headers, duplicate id cookies and controls are refused.
|
|
1339
|
-
Empty/partial caller auth never falls back to worker revoke. Job admission reserves
|
|
1340
|
-
before creating grants outside the journal lock; retry `jobs_busy` with the same key.
|
|
1341
|
-
Writes fsync an exclusive hidden temporary then publish a hard link without overwrite;
|
|
1342
|
-
cancellation cleans the temporary and leaves no partial final file.
|
|
1343
|
-
Add bilingual developer and administrator guides covering typed Files, stable
|
|
1344
|
-
errors, AppPriv defaults/denies and DSM-retained directories/accounts.
|
|
1345
|
-
Full device lifecycle acceptance remains separate from source/local tests.
|
|
1346
|
-
Delegate 隱含 jobs;以本人身分離線寫檔、不覆寫、不保存 DSM 憑證。
|
|
1347
|
-
C/R 共用一次密碼設定與 digest 核准;中英文文件說明委託/撤銷、
|
|
1348
|
-
typed Files、穩定錯誤碼、paused/purge、手動清理與 DSM 保留界線。
|
|
1349
|
-
AppPriv 異常回應 fail-closed;token alias 同值允許、衝突/重複及控制字元拒絕,
|
|
1350
|
-
空/不完整 caller auth 不降級為 worker。`jobs_busy` 沿用相同 key 重試。
|
|
1351
|
-
隱藏暫存檔 fsync 後以 hard link 發布,不覆寫、取消不留半個正式檔。
|
|
1352
|
-
特權清理非同步,monitor 正常時通常數秒完成;刪 task 前完整 script 須逐字相符。
|
|
1353
|
-
Purge 後重新確認密碼、重建 task,boot 前 mailbox 重設 `start`;寫入失敗不執行 boot。
|
|
1354
|
-
套件目錄/INFO identity 消失立即關 socket、取消/drain 請求並暫停,保留 monitor、
|
|
1355
|
-
核准 runtime、委託與 task;每 500 ms 輪詢確認連續消失達 10 分鐘才後備 purge。
|
|
1356
|
-
重新出現或無法確認消失皆重設計時;無法確認時維持 paused。
|
|
1357
|
-
恢復時重讀未變 mailbox:`start` 且 pins 相同才恢復,pins 改變維持 paused/
|
|
1358
|
-
needs-admin-approval,`stop` 維持暫停,`purge` 立即清理。DSM 升級短暫空窗不誤清;
|
|
1359
|
-
preuninst purge 仍立即處理、非同步清理;boot 套件不存在時驗 retained pins 立即 purge 不變。
|
|
1360
|
-
本機測試涵蓋升級空窗、恢復、計時/重設及 preuninst 立即 purge,不代表裝置驗收。
|
|
1361
|
-
|
|
1362
|
-
- **Breaking: schema 2 and task-based CLI, with no compatibility layer.**
|
|
1363
|
-
Native-go and binary now use dsm-package.yaml schema 2 with backend.kind and
|
|
1364
|
-
declared capabilities. Use init → check → build → deploy → status, positional
|
|
1365
|
-
inspect <spk> and logs. The former build-spk/validate/info/log commands, native
|
|
1366
|
-
layout/native.yaml, native privilege/background/fileStation fields and old
|
|
1367
|
-
capability flags are removed; there are no aliases or migration shims.
|
|
1368
|
-
Schema 2 uses --with files,jobs,delegate,login,root-ops or add to extend native-go:
|
|
1369
|
-
private owner-bound data/jobs (A), live caller-session files/tree/transfers (B),
|
|
1370
|
-
standalone identity (I), offline delegation (C), and fixed administrator
|
|
1371
|
-
operations (R). C/R share one-time protected executor approval.
|
|
1372
|
-
Manifest delegate.operations uses
|
|
1373
|
-
files.list/files.info/files.createFolder/files.checkPermission/files.write
|
|
1374
|
-
directly. Check/build/inspect/deploy/status support structured JSON results.
|
|
1375
|
-
Compose retains its separate contract and uses init -t compose, optionally
|
|
1376
|
-
importing with --from. No publish or signing command is added.
|
|
1377
|
-
**不保留相容**:native-go/binary 改用 schema 2;CLI 依工作流程改名,
|
|
1378
|
-
移除舊欄位、旗標、指令與 native layout,不提供 alias 或 shim。
|
|
1379
|
-
A/B/I/C/R 以能力宣告選用;C/R 共用 executor 一次核准。
|
|
1380
|
-
|
|
1381
|
-
- Generate background submit/schedule keys with cryptographic getRandomValues,
|
|
1382
|
-
which works on DSM HTTP; do not require secure-context randomUUID.
|
|
1383
|
-
背景工作及排程以 getRandomValues 產生請求鍵,可在 DSM HTTP 使用;
|
|
1384
|
-
不再依賴僅限安全環境的 randomUUID。
|
|
1385
|
-
|
|
1386
|
-
- Give interactive File Station uploads their own bounded twenty-minute
|
|
1387
|
-
response-header deadline without changing the shared metadata transport.
|
|
1388
|
-
互動 File Station 上傳使用獨立的二十分鐘回應標頭期限,不修改共用查詢 transport;
|
|
1389
|
-
保留目前 session、不覆寫、不重試及寫入結果不確定契約。
|
|
1390
|
-
|
|
1391
|
-
- Frame native-Go CGI JSON with exact byte lengths, including Unicode and
|
|
1392
|
-
refusal/serialization failures; retain DSM's HTTP-200 JSON error convention.
|
|
1393
|
-
native-Go CGI JSON(含 Unicode、拒絕及序列化失敗)提供精確位元組長度,
|
|
1394
|
-
並保留 DSM 的 HTTP 200 JSON 錯誤契約。
|
|
1395
|
-
|
|
1396
|
-
- Replace R2 publication with a private GitHub catalog and streamed Release SPKs.
|
|
1397
|
-
- Serve live bilingual catalog pages and architecture-specific manual downloads.
|
|
1398
|
-
- Remove the two web demo templates; retain native-go, binary and the single compose template.
|
|
1399
|
-
|
|
1400
|
-
## 0.5.3
|
|
1401
|
-
|
|
1402
|
-
- Ship the native-go root authorization template with build-pinned plans,
|
|
1403
|
-
the canonical Vue gate and nine language catalogs, explicit native approval,
|
|
1404
|
-
exact disabled tasks, bounded legacy terminal proof and lifecycle withdrawal.
|
|
1405
|
-
- Export `@synopackageland/cli/authorization-sdk` for reviewed native-layout
|
|
1406
|
-
adapters to consume the same host runtimes and canonical template resources.
|
|
1407
|
-
- Let an explicitly supplied native-layout withdrawal callback finish before
|
|
1408
|
-
removing tasks; failed or missing callbacks abort withdrawal.
|
|
1409
|
-
- Legacy DSM authorization has no server-enforced one-use create token;
|
|
1410
|
-
modern DSM keeps its native one-use PasswordConfirm token contract.
|
|
1411
|
-
- Isolate packed Docker runtime smoke in temporary share directories and its
|
|
1412
|
-
own Compose project, including owned-volume cleanup. The 0.5.1 release tag
|
|
1413
|
-
did not publish because the existing smoke omitted installer share values.
|
|
1414
|
-
- Use a pinned long-running imported runtime fixture for readiness smoke;
|
|
1415
|
-
the default hello-world demo exits immediately. The 0.5.2 workflow was
|
|
1416
|
-
cancelled before publication when CI exposed that fixture race.
|
|
1417
|
-
- Retain bounded artifact-test diagnostics up to eight MiB and propagate
|
|
1418
|
-
real frontend test failures rather than hitting Node's default buffer limit.
|
|
1419
|
-
|
|
1420
|
-
## 0.5.0
|
|
1421
|
-
|
|
1422
|
-
- Add opt-in native layout packaging for existing products: argv-only build hooks,
|
|
1423
|
-
checksum-pinned HTTPS toolkit caching, custom package-user metadata/payload
|
|
1424
|
-
layouts, explicit ELF linkage assertions, DSM armv8/armv7 and build overrides.
|
|
1425
|
-
- Inspect native layouts with complete payload hash/mode and INFO checksum checks;
|
|
1426
|
-
generated templates retain their existing privilege and architecture contracts.
|
|
1427
|
-
|
|
1428
|
-
- **GitHub CI and tag-based npm releases** (CI-LAND). Add shared full gates, Docker
|
|
1429
|
-
runtime/tarball smoke and credential-free release dry runs for both npm packages.
|
|
1430
|
-
Version tags require matching metadata, default-branch ancestry, an unpublished
|
|
1431
|
-
version and versioned CHANGELOG notes. Push scripts now use the existing GitHub
|
|
1432
|
-
origin; `push:all` preserves the separate Community Apps synchronization.
|
|
1433
|
-
|
|
1434
|
-
- **Vue templates pin UI 0.5.7 and let the UI text follow the app locale**
|
|
1435
|
-
(TEMPLATE-UI-057). Every `native-go --ui vue` project pins
|
|
1436
|
-
`@synopackageland/ui@0.5.7` (integrity `sha512-egHKoU4J...`). Each app root now wraps
|
|
1437
|
-
its content in `ConfigProvider locale`, set from the DSM language by the template's
|
|
1438
|
-
existing `uiLocale()` mapping, so the UI's built-in text follows it in the nine
|
|
1439
|
-
built-in locales. The template drops the per-control `FilePicker` locale and the
|
|
1440
|
-
`Link` `download-label` that only repeated those defaults; a template test requires
|
|
1441
|
-
the provider and rejects those overrides. 0.5.7 also resolves `FormItem`
|
|
1442
|
-
`direction="auto"` by the item's own width, stacks `SettingsRow` below 520px and
|
|
1443
|
-
keeps `KeyValueRow` values wrapping; the template needed no mitigation for any of
|
|
1444
|
-
these. Existing 0.5.6 projects upgrade by regenerating, or by changing the pin and
|
|
1445
|
-
re-running `npm ci`.
|
|
1446
|
-
- **Vue templates use the UI controls instead of native form elements**
|
|
1447
|
-
(TEMPLATE-SELECT). The job form's worker and operation pickers and the
|
|
1448
|
-
background schedule interval are now `Select`; the schedule consent is a
|
|
1449
|
-
`Checkbox`; the job, schedule, sample-note and folder forms are `Form` +
|
|
1450
|
-
`FormItem` + `FormActions` (vertical, controls capped at `md`), and the
|
|
1451
|
-
hand-written `.integration-field` label CSS is gone. Labels are wired to
|
|
1452
|
-
`Input` and `Textarea` through the FormItem control id. A template test now
|
|
1453
|
-
fails when any `.vue` file renders a native `<select>`, `<option>`,
|
|
1454
|
-
`<textarea>` or `<label>`, or a `FormItem` outside a vertical `Form`. Three UI
|
|
1455
|
-
gaps remain and are not worked around with custom components: `Select` does
|
|
1456
|
-
not take the FormItem control id (each Select carries a labelled
|
|
1457
|
-
`role="group"` so it keeps an accessible name), the upload stays a native
|
|
1458
|
-
`<input type="file">` because `FilePicker` hard-codes English "Choose files" and
|
|
1459
|
-
"max" text, and the file download keeps a native `<a>` (no link component).
|
|
1460
|
-
Existing projects pick this up only by regenerating; nothing changes in the
|
|
1461
|
-
manifest, routes or backend.
|
|
1462
|
-
- **Tarball smoke covers the default Vue UI and explicit plain UI**
|
|
1463
|
-
(SMOKE-PACK-VUE). Install each generated Vue frontend with its lockfile before
|
|
1464
|
-
building; keep both architectures and explicit root fixtures, then binary and
|
|
1465
|
-
container packaging. The container smoke now selects `--arch x86_64` for
|
|
1466
|
-
`-o app.spk` and its deployment plan, as explicit output requires one arch.
|
|
1467
|
-
Docker runtime QA is opt-in with `smoke-pack.sh --docker`
|
|
1468
|
-
and is explicitly skipped otherwise. Failed npm UI builds without installed
|
|
1469
|
-
dependencies now name the UI directory and suggest `npm ci` (or `npm install`
|
|
1470
|
-
without a lockfile) before retrying `build`; builds never install implicitly.
|
|
1471
|
-
|
|
1472
|
-
- **Vue templates pin UI 0.5.5 and use PageContent** (TEMPLATE-UI-055). Every
|
|
1473
|
-
`native-go --ui vue` project pins `@synopackageland/ui@0.5.5` (integrity
|
|
1474
|
-
`sha512-pLQmZqNH...`). The sidebar shell now wraps the page header and the page
|
|
1475
|
-
content in the library `PageContent`, so a maximised window keeps both on the
|
|
1476
|
-
same left and right edges; the page area scrolls inside it. 0.5.5 also adds
|
|
1477
|
-
`CardGrid`, `FormActions`, `RepeatRows` and `fieldWidth`; the template has no
|
|
1478
|
-
card lists or custom width CSS, so it needs none of them. Default change to
|
|
1479
|
-
know when upgrading: form controls are capped at `md` (320px) unless you pass
|
|
1480
|
-
`field-width="full"`. Existing 0.5.4 projects upgrade by re-running `npm ci`
|
|
1481
|
-
after the pin change.
|
|
1482
|
-
|
|
1483
|
-
- **Vue templates pin UI 0.5.4** (TEMPLATE-UI-054). Every `native-go --ui vue`
|
|
1484
|
-
project now pins `@synopackageland/ui@0.5.4` (integrity `sha512-mzuGUO+8...`).
|
|
1485
|
-
0.5.4 is visual only and changes nothing in the template source: under the
|
|
1486
|
-
embedded theme, Card, EmptyState, PageHeader and WizardStep titles no longer
|
|
1487
|
-
carry a default margin, the expand buttons of SettingsSection, Card and
|
|
1488
|
-
ExpandableItem lose their grey box, and dashed separators draw only the bottom
|
|
1489
|
-
edge. Existing 0.5.3 projects upgrade by re-running `npm ci` after the pin change.
|
|
1490
|
-
|
|
1491
|
-
- **Root tasks retain DSM 7.1 support.** Probe `list v3` and use the legacy
|
|
1492
|
-
`create v3`, `list v2`, `get v3`, `run/delete v2`, and `view v1` only on code
|
|
1493
|
-
103. Preserve native password confirmation while distinguishing tokenless
|
|
1494
|
-
success from cancellation; DSM 7.1 has no server-side root-creation password
|
|
1495
|
-
token. Require a new successful completion record within a bounded deadline,
|
|
1496
|
-
exact task identity, and no mutation retries. Root init, validation, and build
|
|
1497
|
-
keep a consistent minimum of DSM 7.1-42661.
|
|
1498
|
-
- **Vue templates pin UI 0.5.3** (TEMPLATE-UI-053). Every `native-go --ui vue`
|
|
1499
|
-
project pins `@synopackageland/ui@0.5.3` in `frontend/package.json` and its
|
|
1500
|
-
npmjs lockfile (integrity `sha512-ieKdf0nB...`). 0.4.2 to 0.5.3 is additive for
|
|
1501
|
-
the template: new components (Select search and groups, Combobox,
|
|
1502
|
-
MultipleSelect, SuperboxSelect, Grid/Row/Col, Space, Affix, Breadcrumb,
|
|
1503
|
-
Pagination, SegmentControl, Card, Panel, Fieldset, Form, Notification, and more),
|
|
1504
|
-
DataGrid grouping/expansion/reorder, checkable and draggable TreeView, DropdownMenu
|
|
1505
|
-
submenus, and `Input`/`Dialog`/`SettingsSection`/`Callout` options with unchanged
|
|
1506
|
-
defaults. Visual changes: Tabs and SectionTabs share a sliding marker with a
|
|
1507
|
-
160ms panel fade, the Spinner is a full rotating ring (both honour
|
|
1508
|
-
`prefers-reduced-motion`), selected tab labels are blue, and the DataGrid footer
|
|
1509
|
-
draws both borders and fills its flex container. The template needed no API
|
|
1510
|
-
change; it now uses the library `Checkbox` and `Input` for the consent and limit
|
|
1511
|
-
fields instead of native inputs. Existing 0.4.2 projects upgrade by re-running
|
|
1512
|
-
`npm ci` after the pin change.
|
|
1513
|
-
|
|
1514
|
-
- **Templates never copy a local `node_modules`/`dist`** (TEMPLATE-COPY). A
|
|
1515
|
-
template checkout used for development could leak its own install directory or
|
|
1516
|
-
build output into a generated project, shadowing the project's `npm ci`.
|
|
1517
|
-
|
|
1518
|
-
- **Vue templates pin UI 0.4.2** (TEMPLATE-UI-042). Every `native-go --ui vue`
|
|
1519
|
-
project pins `@synopackageland/ui@0.4.2` in `frontend/package.json` and its
|
|
1520
|
-
npmjs lockfile. 0.4.1/0.4.2 are visual, backward-compatible control changes with
|
|
1521
|
-
no API change: controls share the `--ui-control-*` tokens and
|
|
1522
|
-
`--ui-radius-control`, so overriding `--ui-radius-sm`/`--ui-radius-md` no longer
|
|
1523
|
-
reshapes them; a disabled grey button keeps its surface, a loading button keeps
|
|
1524
|
-
full strength, and the Switch track padding is reset. Existing 0.4.0 projects
|
|
1525
|
-
upgrade by re-running `npm ci` after the pin change.
|
|
1526
|
-
|
|
1527
|
-
- **Private-copy background schedules (S1-a)**: hourly/daily/weekly owner-scoped
|
|
1528
|
-
creation, disable/delete, 8-definition limit, durable atomic trigger checkpoints,
|
|
1529
|
-
missed-without-catch-up recovery, revision mismatch disable and explicit admin
|
|
1530
|
-
re-enable. The Vue panel covers nine locales. Imported/pinned copies count toward
|
|
1531
|
-
quotas; completed results never replay and owner purge also removes schedules.
|
|
1532
|
-
Package account only, no stored credentials or offline personal ACL access.
|
|
1533
|
-
Evidence: local gates and vt-nas DSM 7.4 x86_64 controlled-due-time tests
|
|
1534
|
-
(two runs per owner, stop/start, +1 upgrade, disable and fresh normal1 browser
|
|
1535
|
-
readback). This is not an hour-long cadence or reboot guarantee.
|
|
1536
|
-
|
|
1537
|
-
- **Minimum DSM 7.1 and multiple architectures** (DSM-COMPAT). Every template now declares
|
|
1538
|
-
`os_min_ver: "7.1-42661"` (DSM 7.1; before: `7.2-64570`, `7.2-69057` or `7.2-60000`).
|
|
1539
|
-
`init --min-dsm` and `build --min-dsm` take `7.0`, `7.1`, `7.2` or a full
|
|
1540
|
-
`7.x-build` to override it. `build --arch` accepts a comma-separated list
|
|
1541
|
-
- **Per-runtime minimum DSM and multiple architectures** (DSM-COMPAT, DSM-COMPAT-2).
|
|
1542
|
-
`native-go` and `binary` declare `os_min_ver: "7.1-42661"` (DSM 7.1; before:
|
|
1543
|
-
`7.2-64570`, `7.2-69057` or `7.2-60000`). The container templates declare
|
|
1544
|
-
`7.2.1-69057` (DSM 7.2.1), and `init --min-dsm`/`build --min-dsm` refuse a
|
|
1545
|
-
container value below it (`MIN_DSM_CONTAINER_FLOOR`) because Container Manager's
|
|
1546
|
-
docker-project worker only exists from DSM 7.2.1; `inspect` reports the same
|
|
1547
|
-
gap on an already-built container SPK. `--min-dsm` takes `7.0`, `7.1`, `7.2`,
|
|
1548
|
-
`7.2.1` or a full `7.x-build`. `build --arch` accepts a comma-separated list
|
|
1549
|
-
(`x86_64,aarch64`); without it every family is built, one SPK per family (binary and
|
|
1550
|
-
gateway container Apps used to require `--arch`). `inspect` flags an INFO `arch`
|
|
1551
|
-
that mixes families or names an unknown platform, a CGI built for another family than
|
|
1552
|
-
INFO declares, and an `os_min_ver` that is not a DSM 7 `<version>-<build>`. The
|
|
1553
|
-
x86_64 INFO platform list now includes `kvmcloud`, `epyc7003` and `epyc7003ntb`.
|
|
1554
|
-
Only DSM 7.4 x86_64 has been run.
|
|
1555
|
-
- **Ordinary-user background jobs (U1)**: administrators may independently enable
|
|
1556
|
-
`allowOrdinaryUsers`. Fresh DSM username/UID ownership isolates list/get/cancel/result,
|
|
1557
|
-
counts and idempotency keys; unknown UIDs fail closed. Per-owner admission is bounded
|
|
1558
|
-
to 2 pending jobs and 1 MiB including reserved results, under the same spool lock.
|
|
1559
|
-
Administrators can cancel all jobs and explicitly purge an exact owner with durable
|
|
1560
|
-
audit and running-job drain. The Vue panel and all nine locales cover both roles.
|
|
1561
|
-
No root or stored user credentials; S1-a adds private-copy schedules below.
|
|
1562
|
-
|
|
1563
|
-
- **Container gateway directory groups** (GW-DIRECTORY-GROUPS). Accounts absent
|
|
1564
|
-
from `/etc/passwd` now resolve groups through DSM NSS using the fixed `/usr/bin/id`
|
|
1565
|
-
as the package account. Qualified `DOMAIN\group` and `group@domain` names retain
|
|
1566
|
-
their exact domain and case, including internal spaces; lookup failure denies.
|
|
1567
|
-
The SDK caches nothing (TTL 0); DSM NSS caches and already-open streams remain
|
|
1568
|
-
limitations. AD resolver allow/deny checks passed in a non-root DSM 7.4 package
|
|
1569
|
-
CGI; LDAP, AD-user browser login and group-removal propagation remain unverified.
|
|
1570
|
-
Rebuild container SPKs to obtain the change.
|
|
1571
|
-
|
|
1572
|
-
- **`synopkgland images pin` resolves and writes container image digests**
|
|
1573
|
-
(IMAGE-DIGEST-CLI). It reads every service image in `compose.yaml`, asks the
|
|
1574
|
-
registry for the current multi-arch manifest digest over the OCI Distribution
|
|
1575
|
-
API (anonymous Bearer token flow for Docker Hub and ghcr; no Docker daemon or
|
|
1576
|
-
`buildx`), and rewrites the reference to `tag@sha256:…` in place, keeping
|
|
1577
|
-
comments and file layout. `--check` reports unpinned and stale pins without
|
|
1578
|
-
writing and exits non-zero. `inspect`'s unpinned-image finding now points at
|
|
1579
|
-
the command. Evidence: local unit tests against a fake registry plus one manual
|
|
1580
|
-
Docker Hub resolution of `busybox:1.36`; not verified on a real DSM.
|
|
1581
|
-
- **Container upgrade wizard no longer breaks on an untouched Run-as control; numeric
|
|
1582
|
-
command arguments are rejected for every Compose route** (WIZARD-LIVE-CHECK).
|
|
1583
|
-
Measured on vt-nas (DSM 7.4-90069) with the `compose-import` template: an untouched
|
|
1584
|
-
upgrade submitted `RUN_AS` pre-filled with the name of the first Shared Folder, `preinst`
|
|
1585
|
-
failed, and DSM, which removes the old version before it runs the new `preinst`, left the
|
|
1586
|
-
package not installed (data kept). A `dsm_user` now has the same "Change Container Run-as"
|
|
1587
|
-
box as a Shared Folder: on an upgrade the submitted user only counts when that box (or
|
|
1588
|
-
`deploy --run-as`) is set; otherwise the installed user is kept. Also on vt-nas: the
|
|
1589
|
-
Docker Project worker drops YAML quotes, so `command: ["sleep", "3600"]` ended the
|
|
1590
|
-
install as broken (`failed to acquire postinst worker`). `synopkgland check` and
|
|
1591
|
-
`build` already rejected that on the static route; the dynamic route (install
|
|
1592
|
-
parameters, which includes `compose-import`) now rejects it too
|
|
1593
|
-
(`COMPOSE_NUMERIC_COMMAND_ARG_FORBIDDEN`).
|
|
1594
|
-
- **`install.sharedFolder`** (T-0120): native-go packages can declare a Shared Folder (`select` wizard or `create`
|
|
1595
|
-
via DSM `data-share`), stored by name in `var/config.json`; `init --shared-folder select|create` and an `inspect`
|
|
1596
|
-
check are included. In `select` mode the administrator grants the package account access afterwards.
|
|
1597
|
-
- **Container gateway accepts a query SynoToken; known limit with DSM CSRF protection on**
|
|
1598
|
-
(GW-QUERY-TOKEN). On `GET`, `HEAD` and `OPTIONS` with an empty `X-SYNO-TOKEN`, the
|
|
1599
|
-
gateway hands a `?SynoToken=` value to `authenticate.cgi` (header wins; still stripped
|
|
1600
|
-
upstream); state-changing methods are unchanged. Measured on DSM 7.4 with "Improve
|
|
1601
|
-
protection against cross-site request forgery attacks" on: opening a container App
|
|
1602
|
-
from the DSM desktop sends no token at all, so the gateway answers `401`
|
|
1603
|
-
`session_required`. Known limitation: turn the setting off or use the `native-go`
|
|
1604
|
-
template.
|
|
1605
|
-
- **Container gateway: readable errors, SSE and WebSocket** (GW-ERRORS-WS). DSM's web
|
|
1606
|
-
server replaces the body and headers of any CGI reply with status `403`, `404`,
|
|
1607
|
-
`500`, `502`, `503` or `504` by its generic error page (measured on DSM 7.4-90069;
|
|
1608
|
-
every other status passes whole). The gateway therefore no longer sends those
|
|
1609
|
-
statuses itself: `forbidden` and `token_required` arrive as `401`, a stopped
|
|
1610
|
-
container as `521` with `Retry-After`, a timeout as `524`, an invalid reply as
|
|
1611
|
-
`520`; every gateway error carries `X-Synopkgland-Error` (the code) and, for a
|
|
1612
|
-
stand-in, `X-Synopkgland-Status` (the status it replaces). **Behaviour change:**
|
|
1613
|
-
those statuses were `403`/`503`/`504`/`502`/`500` before. A request header
|
|
1614
|
-
`X-Synopkgland-Keep-Error-Body: 1` makes the same swap for the container's own
|
|
1615
|
-
error replies so an App can read its JSON error bodies. Server-Sent Events pass
|
|
1616
|
-
through unbuffered and **WebSocket now works** (it answered `501`): DSM hands both
|
|
1617
|
-
directions of an upgraded connection to the CGI, which the gateway uses; the
|
|
1618
|
-
handshake must pass the same same-origin check as a state-changing request
|
|
1619
|
-
(`cross_site_blocked`), because a browser cannot add `X-SYNO-TOKEN` to a handshake. Other protocol upgrades stay
|
|
1620
|
-
`501`. See [Container access control](/docs/guides/container-access/).
|
|
1621
|
-
- Fix: **`dsm-groups` with `groups: [users]` let nobody in.** DSM keeps no member
|
|
1622
|
-
list for `users` (every local account has it as its primary group), so the gateway,
|
|
1623
|
-
which only read member lists from `/etc/group`, answered `403` to everyone, including
|
|
1624
|
-
administrators (reproduced on vt-nas). The gateway now also counts the primary gid
|
|
1625
|
-
from `/etc/passwd` as membership and fails closed if it cannot read that file.
|
|
1626
|
-
Rebuild the SPK to pick it up. Real-account `dsm-groups`/`dsm-admins` checks passed on
|
|
1627
|
-
vt-nas (x86_64); the aarch64 gateway is verified in an arm64 Linux VM only, not on an
|
|
1628
|
-
aarch64 DSM NAS.
|
|
1629
|
-
- **Gateway CSRF check no longer relies on the SynoToken value** (GW-TOKEN). On a NAS
|
|
1630
|
-
where DSM's "Improve protection against cross-site request forgery attacks" is off (vt-nas: `enable_syno_token="no"`), DSM
|
|
1631
|
-
issues one fixed placeholder token to every session and validates nothing. The container
|
|
1632
|
-
gateway now also requires `Sec-Fetch-Site: same-origin` and/or an `Origin` equal to the
|
|
1633
|
-
request `Host` for `POST`/`PUT`/`PATCH`/`DELETE` (answer `cross_site_blocked`, sent as `401` because DSM replaces `403` bodies) and a
|
|
1634
|
-
well-formed `X-SYNO-TOKEN`; safe methods are unchanged. Browsers that send neither
|
|
1635
|
-
header on a state-changing request are refused. Verified on a real DSM 7.4 as an
|
|
1636
|
-
administrator and an ordinary user (foreign `Origin`, `null`, `Sec-Fetch-Site`
|
|
1637
|
-
cross-site/same-site, missing evidence refused; same-origin passes). The token path with
|
|
1638
|
-
the DSM setting on is untested. Rebuild container SPKs to pick it up. See
|
|
1639
|
-
[Container access](/docs/guides/container-access/).
|
|
1640
|
-
- **Container templates pin their image by digest** (CONTAINER-PULL): `hello-files` and `compose-import` now use
|
|
1641
|
-
`image: <tag>@sha256:…`. `build` writes `force_pull: false` into the
|
|
1642
|
-
`docker-project` resource when every service image is digest-pinned and keeps
|
|
1643
|
-
`force_pull: true` while any image is a bare tag, so an install no longer
|
|
1644
|
-
re-resolves a moving tag that other containers share. `inspect` reports each
|
|
1645
|
-
service whose image is not digest-pinned. Behaviour for projects with unpinned
|
|
1646
|
-
images is unchanged. Not verified on a real DSM.
|
|
1647
|
-
- **Breaking: container Apps are DSM-authenticated by default.** A container App
|
|
1648
|
-
with an `adminport` is now served through a gateway CGI
|
|
1649
|
-
(`/webman/3rdparty/<package>/cgi/gateway.cgi/…`) that runs as the package
|
|
1650
|
-
account, checks the DSM session and forwards to the container. Without a valid
|
|
1651
|
-
session it answers `401`; unsafe methods need `X-SYNO-TOKEN`; a stopped container
|
|
1652
|
-
gives `521` with `Retry-After` (not `503`: DSM would replace its body). New `integration.web.access`: `dsm-users`
|
|
1653
|
-
(default), `dsm-admins`, `dsm-groups` (+ `groups`), `public`. No Web Station
|
|
1654
|
-
portal is registered unless `public`. The container port must be bound to
|
|
1655
|
-
loopback (`127.0.0.1:<adminport>:<port>`): `check` fails with
|
|
1656
|
-
`COMPOSE_GATEWAY_PORT_EXPOSED`, and `inspect`/`inspect` report
|
|
1657
|
-
`CONTAINER_PORT_EXPOSED` and `CONTAINER_ANONYMOUS_PORTAL`. The gateway is
|
|
1658
|
-
compiled Go, so building such an App needs Go and `--arch`, and the SPK is no
|
|
1659
|
-
longer `noarch`. Privilege stays `run-as: package` with no root task.
|
|
1660
|
-
**Migration:** bind the Compose port to `127.0.0.1`, rebuild with a higher
|
|
1661
|
-
`build` and an `--arch`, then upgrade (the old `/<alias>/` portal and bookmarks
|
|
1662
|
-
go away); or set `integration.web.access: public` to keep the anonymous
|
|
1663
|
-
behaviour. See `website` guide “Container access control”.
|
|
1664
|
-
- Add best-effort `revealFile` selection recovery using File Station 1.4.x
|
|
1665
|
-
private structures, with feature detection and silent cancellation on absent or
|
|
1666
|
-
throwing APIs. One AppLaunch binds its callback receiver; only that receiver's
|
|
1667
|
-
model may be selected once. Interaction, navigation away, close, disposal and
|
|
1668
|
-
replacement requests cancel observers. Named bounds are 5000 ms total, 100 ms
|
|
1669
|
-
checks and 300 ms quiet time, without device latency proof. `requested` still
|
|
1670
|
-
does not mean `selected`. Actual effectiveness on DSM 7.4 / File Station 1.4.4
|
|
1671
|
-
awaits a rebuilt-SPK device matrix; no device fix is claimed.
|
|
1672
|
-
|
|
1673
|
-
- Fix `ctx.host.activateWindow()` to prefer DSM `toFront()`, calling `show()`
|
|
1674
|
-
first for hidden/minimized windows; `activate()` remains a compatibility
|
|
1675
|
-
fallback. `requestClose()` follows DSM standalone truthiness: falsy values
|
|
1676
|
-
(including desktop `undefined`) permit the normal close path, while a truthy
|
|
1677
|
-
standalone-main check refuses it. `canClose === false` and host listeners still
|
|
1678
|
-
veto. Both methods return `requested`, not completion proof; rebuilt-SPK DSM
|
|
1679
|
-
validation remains pending. Source: `7553c24`, `2842634`.
|
|
1680
|
-
- Add opt-in package-owned foreground `daemon` to native manifests, with
|
|
1681
|
-
generated supervision and lifecycle hooks. Daemon-free packages keep their
|
|
1682
|
-
existing lifecycle; no machine-wide service is required.
|
|
1683
|
-
- Add per-mount `ctx.host` platform/title adapters, guarded window activation
|
|
1684
|
-
and close requests, app/external-URL navigation, resize/reopen subscription
|
|
1685
|
-
cleanup, and File Station folder navigation/file reveal. Standalone web uses
|
|
1686
|
-
explicit fallbacks; file reveal is not preview. File preview/details/settings
|
|
1687
|
-
and host theme/language subscriptions remain unsupported. Final DSM runtime
|
|
1688
|
-
behavior and ordinary-user navigation permissions still need NAS validation.
|
|
1689
|
-
- Fix SPK inspection to read the build-specific unique window bundle.
|
|
1690
|
-
|
|
1691
|
-
### Known limitations
|
|
1692
|
-
|
|
1693
|
-
- **File reveal remains a request:** on DSM 7.4-90069 with File Station
|
|
1694
|
-
1.4.4-2221, one `ctx.host.revealFile()` call was observed opening the correct
|
|
1695
|
-
folder without selecting/highlighting the file. A new synthetic fixture retest
|
|
1696
|
-
selected the file with both `/home` and `/homes/admin` inputs, once each
|
|
1697
|
-
(confidence **high**). The earlier non-selection was not reproduced; its cause
|
|
1698
|
-
remains **unknown**. `requested` only means a selection request was issued;
|
|
1699
|
-
it does not guarantee selection, preview, existence or ACL access. No runtime
|
|
1700
|
-
fix is claimed. Source: V1 device validation and fixture retest, 2026-10-04.
|
|
1701
|
-
- Vue templates pin public `@synopackageland/ui@0.4.0`, including app-scoped
|
|
1702
|
-
modals and unique mount IDs, with npmjs-only lockfiles and imports. External
|
|
1703
|
-
developers do not need an internal registry account.
|
|
1704
|
-
- CLI 0.4.0 targets npmjs `latest`; versions 0.1.0–0.3.10 remain available without
|
|
1705
|
-
deprecation or unpublishing.
|
|
195
|
+
- `native-go`: a Go backend with a Vue UI (or `--ui plain`).
|
|
196
|
+
- `native-python`, `native-node`, `native-rust`: the same App with a Python,
|
|
197
|
+
Node.js (TypeScript) or Rust backend behind the SDK's Go runtime.
|
|
198
|
+
- `binary`: a static Linux program you build yourself.
|
|
199
|
+
- `compose`: an existing Docker Compose app (`--from compose.yaml`).
|
|
200
|
+
- Existing native products keep their own payload layout with
|
|
201
|
+
`backend: {kind: native}`.
|
|
202
|
+
|
|
203
|
+
### Capabilities
|
|
204
|
+
|
|
205
|
+
`init --with …` or `add` adds `files`, `jobs`, `login`, `delegate`,
|
|
206
|
+
`root-ops` and `portal`. `delegate` and `root-ops` run through the SDK's
|
|
207
|
+
executor, which an administrator approves once by digest; `check` and
|
|
208
|
+
`build` have the App's executor validate its policy first
|
|
209
|
+
(`EXECUTOR_POLICY_REJECTED`).
|
|
210
|
+
|
|
211
|
+
### Commands
|
|
212
|
+
|
|
213
|
+
- `init`, `add`: create a project and add capabilities.
|
|
214
|
+
- `check`, `build`: validate the manifest and build the SPK for one or more
|
|
215
|
+
architectures, with the executor checked against the digests shipped in the
|
|
216
|
+
CLI.
|
|
217
|
+
- `inspect`: check any SPK against the DSM 7 package format without
|
|
218
|
+
installing it.
|
|
219
|
+
- `deploy`, `status`, `logs`: install on a NAS and read its state.
|
|
220
|
+
- `dev`, `test`, `images`: run, test and pin images for Compose projects.
|
|
221
|
+
- `skill`: the bundled guidance for AI assistants.
|
|
222
|
+
|
|
223
|
+
`--json` prints one JSON object on stdout; failures carry a stable `code`
|
|
224
|
+
and a `hint`.
|