@synopackageland/cli 0.7.0 → 0.7.2
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 +301 -1
- package/assets/default-icon/README.md +19 -0
- package/assets/default-icon/default-icon-small.svg +9 -0
- package/assets/default-icon/default-icon.svg +10 -0
- package/assets/default-icon/icon_16.png +0 -0
- package/assets/default-icon/icon_24.png +0 -0
- package/assets/default-icon/icon_256.png +0 -0
- package/assets/default-icon/icon_32.png +0 -0
- package/assets/default-icon/icon_48.png +0 -0
- package/assets/default-icon/icon_64.png +0 -0
- package/assets/default-icon/icon_72.png +0 -0
- package/dist/add.d.ts +4 -1
- package/dist/add.js +14 -9
- package/dist/build-spk/dsm-icons.d.ts +31 -2
- package/dist/build-spk/dsm-icons.js +135 -56
- package/dist/build-spk/dsm-platforms.json +4 -1
- package/dist/build-spk/gateway.d.ts +1 -1
- package/dist/build-spk/gateway.js +8 -4
- package/dist/build-spk/generator.js +17 -3
- package/dist/build-spk/go-toolchain.d.ts +20 -0
- package/dist/build-spk/go-toolchain.js +44 -0
- package/dist/build-spk/png.d.ts +14 -0
- package/dist/build-spk/png.js +161 -0
- package/dist/build-spk/ui-texts.d.ts +20 -0
- package/dist/build-spk/ui-texts.js +42 -0
- package/dist/cli.js +39 -9
- package/dist/contract/i18n.d.ts +5 -0
- package/dist/contract/i18n.js +45 -0
- package/dist/contract/icon.d.ts +5 -0
- package/dist/contract/icon.js +27 -0
- package/dist/contract/validate.js +4 -0
- package/dist/contract/web-launch.js +6 -2
- package/dist/deploy/native-install-values.d.ts +17 -0
- package/dist/deploy/native-install-values.js +32 -0
- package/dist/deploy/plan.d.ts +6 -2
- package/dist/deploy/plan.js +57 -6
- package/dist/error-registry.js +15 -6
- package/dist/host/dsm-client.js +53 -17
- package/dist/host/dsm-http.js +24 -2
- package/dist/host/types.d.ts +1 -0
- package/dist/info.js +28 -9
- package/dist/init.js +1 -1
- package/dist/runtime/dsm-version.d.ts +6 -0
- package/dist/runtime/dsm-version.js +8 -0
- package/dist/runtime/executor-build.d.ts +1 -1
- package/dist/runtime/executor-build.js +8 -5
- package/dist/standalone/daemon.d.ts +2 -1
- package/dist/standalone/daemon.js +10 -6
- package/dist/standalone/dsm-window.d.ts +2 -0
- package/dist/standalone/dsm-window.js +26 -40
- package/dist/standalone/i18n.d.ts +12 -0
- package/dist/standalone/i18n.js +30 -0
- package/dist/standalone/inspect-spk.d.ts +5 -0
- package/dist/standalone/inspect-spk.js +41 -2
- package/dist/standalone/manifest.d.ts +5 -6
- package/dist/standalone/manifest.js +21 -34
- package/dist/standalone/native-authorization-window.d.ts +1 -1
- package/dist/standalone/native-authorization-window.js +7 -1
- package/dist/standalone/native-layout.d.ts +2 -0
- package/dist/standalone/native-layout.js +22 -1
- package/dist/standalone/native-root-window.d.ts +4 -2
- package/dist/standalone/native-root-window.js +33 -18
- package/dist/standalone/root-window.d.ts +4 -1
- package/dist/standalone/root-window.js +143 -33
- package/dist/standalone/spk.js +7 -4
- package/dist/templates/_daemon/go.mod +1 -1
- package/dist/templates/_daemon/main.go +6 -3
- package/dist/templates/_daemon/main_test.go +21 -1
- package/dist/templates/_daemon/testdata/child.go +3 -0
- package/dist/templates/_executor/README.md +4 -1
- package/dist/templates/_executor/anchor.go +10 -0
- package/dist/templates/_executor/anchor_test.go +40 -5
- package/dist/templates/_executor/digest_review_test.go +2 -2
- package/dist/templates/_executor/dsm.go +40 -3
- package/dist/templates/_executor/go.mod +2 -0
- package/dist/templates/_executor/main.go +11 -5
- package/dist/templates/_executor/managed.go +3 -3
- package/dist/templates/_executor/managed_test.go +3 -3
- package/dist/templates/_executor/path_test.go +18 -0
- package/dist/templates/_executor/pid.go +37 -0
- package/dist/templates/_executor/pid_test.go +113 -0
- package/dist/templates/_executor/platform_other.go +8 -0
- package/dist/templates/_executor/purge_log.go +18 -0
- package/dist/templates/_executor/tasks.go +45 -7
- package/dist/templates/_executor/tasks_dsm71_test.go +114 -0
- package/dist/templates/_executor/tasks_test.go +58 -1
- package/dist/templates/_executor/upgrade_watch_test.go +13 -5
- package/dist/templates/_gateway/go.mod +2 -0
- package/dist/templates/binary/dsm-package.yaml +3 -0
- package/dist/templates/compose/synology-app.yaml +3 -0
- package/dist/templates/native-go/backend/go.mod +1 -1
- package/dist/templates/native-go/backend/internal/filestation/client.go +39 -3
- package/dist/templates/native-go/backend/internal/filestation/download_dsm71_test.go +82 -0
- package/dist/templates/native-go/backend/internal/identity/README.md +5 -1
- package/dist/templates/native-go/backend/internal/identity/dsm.go +24 -5
- package/dist/templates/native-go/backend/internal/identity/http.go +1 -1
- package/dist/templates/native-go/backend/internal/identity/identity_test.go +48 -1
- package/dist/templates/native-go/backend/internal/identity/service.go +1 -1
- package/dist/templates/native-go/dsm-package.yaml +3 -0
- package/dist/templates/native-go-delegate/frontend/test/delegate.test.ts +15 -0
- package/dist/templates/native-go-root-ops/backend/internal/app/executor.go +30 -2
- package/dist/templates/native-go-root-ops/backend/internal/app/executor_test.go +64 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/ExecutorSettings.vue +3 -2
- package/dist/templates/native-go-vue/frontend/src/delegate/executor-settings.test.ts +23 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/executor-setup.ts +5 -1
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/de.json +1 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/en.json +1 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/es.json +1 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/fr.json +1 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/it.json +1 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/ja.json +1 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/ko.json +1 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/zh-CN.json +1 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/zh-TW.json +1 -0
- package/package.json +2 -1
- package/schema/synology-app.schema.json +22 -0
- package/templates/_daemon/go.mod +1 -1
- package/templates/_daemon/main.go +6 -3
- package/templates/_daemon/main_test.go +21 -1
- package/templates/_daemon/testdata/child.go +3 -0
- package/templates/_executor/README.md +4 -1
- package/templates/_executor/anchor.go +10 -0
- package/templates/_executor/anchor_test.go +40 -5
- package/templates/_executor/digest_review_test.go +2 -2
- package/templates/_executor/dsm.go +40 -3
- package/templates/_executor/go.mod +2 -0
- package/templates/_executor/main.go +11 -5
- package/templates/_executor/managed.go +3 -3
- package/templates/_executor/managed_test.go +3 -3
- package/templates/_executor/path_test.go +18 -0
- package/templates/_executor/pid.go +37 -0
- package/templates/_executor/pid_test.go +113 -0
- package/templates/_executor/platform_other.go +8 -0
- package/templates/_executor/purge_log.go +18 -0
- package/templates/_executor/tasks.go +45 -7
- package/templates/_executor/tasks_dsm71_test.go +114 -0
- package/templates/_executor/tasks_test.go +58 -1
- package/templates/_executor/upgrade_watch_test.go +13 -5
- package/templates/_gateway/go.mod +2 -0
- package/templates/binary/dsm-package.yaml +3 -0
- package/templates/compose/synology-app.yaml +3 -0
- package/templates/native-go/backend/go.mod +1 -1
- package/templates/native-go/backend/internal/filestation/client.go +39 -3
- package/templates/native-go/backend/internal/filestation/download_dsm71_test.go +82 -0
- package/templates/native-go/backend/internal/identity/README.md +5 -1
- package/templates/native-go/backend/internal/identity/dsm.go +24 -5
- package/templates/native-go/backend/internal/identity/http.go +1 -1
- package/templates/native-go/backend/internal/identity/identity_test.go +48 -1
- package/templates/native-go/backend/internal/identity/service.go +1 -1
- package/templates/native-go/dsm-package.yaml +3 -0
- package/templates/native-go-delegate/frontend/test/delegate.test.ts +15 -0
- package/templates/native-go-root-ops/backend/internal/app/executor.go +30 -2
- package/templates/native-go-root-ops/backend/internal/app/executor_test.go +64 -0
- package/templates/native-go-vue/frontend/src/delegate/ExecutorSettings.vue +3 -2
- package/templates/native-go-vue/frontend/src/delegate/executor-settings.test.ts +23 -0
- package/templates/native-go-vue/frontend/src/delegate/executor-setup.ts +5 -1
- package/templates/native-go-vue/frontend/src/delegate/i18n/de.json +1 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/en.json +1 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/es.json +1 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/fr.json +1 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/it.json +1 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/ja.json +1 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/ko.json +1 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/zh-CN.json +1 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/zh-TW.json +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,306 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 0.7.2 (2026-10-11)
|
|
4
|
+
|
|
5
|
+
Rebuild packages to pick up the new default icon. Packages without `icon` now
|
|
6
|
+
show the SDK default icon instead of a solid blue square.
|
|
7
|
+
|
|
8
|
+
### Package icon
|
|
9
|
+
|
|
10
|
+
- `dsm-package.yaml` and `synology-app.yaml` accept `icon`: a square PNG of at
|
|
11
|
+
least 256×256 inside the project, or a folder of `icon_<size>.png` (16, 24,
|
|
12
|
+
32, 48, 64, 72, 256; `icon_256.png` required, missing sizes scaled from it).
|
|
13
|
+
`build` writes `PACKAGE_ICON.PNG` (64×64), `PACKAGE_ICON_256.PNG` and every
|
|
14
|
+
DSM window size `ui/images/app_<size>.png` from it. SVG is not accepted, so
|
|
15
|
+
the CLI gains no image dependency. `check` refuses an icon outside the
|
|
16
|
+
project, a non-PNG, a non-square or smaller image, and one whose Package
|
|
17
|
+
Center icons exceed the package source's 256 KiB limit
|
|
18
|
+
(`STANDALONE_ICON_INVALID`, `CONTRACT_ICON_INVALID`).
|
|
19
|
+
|
|
20
|
+
- A native layout may set `icon` too; `build` then writes both Package Center
|
|
21
|
+
icons and refuses a metadata folder that also ships them. Without `icon` the
|
|
22
|
+
layout keeps owning its icons.
|
|
23
|
+
|
|
24
|
+
- `check` reports which icon a build uses: `圖示:自訂 <path>`, or `圖示:SDK
|
|
25
|
+
預設圖示` with an info hint about `icon:` (not an error). It warns when an
|
|
26
|
+
icon is a single colour. `check --json` reports it in `data.icon`.
|
|
27
|
+
|
|
28
|
+
- `inspect` reports `icon` as `default`, `custom` (with the SHA-256 of
|
|
29
|
+
`PACKAGE_ICON_256.PNG`) or `none`, and lists a Package Center icon over
|
|
30
|
+
256 KiB, of the wrong size or not a PNG as a finding.
|
|
31
|
+
|
|
32
|
+
- The SDK default icon replaces the solid blue square in Package Center, the
|
|
33
|
+
DSM main menu and the window. Sources are in `assets/default-icon/`.
|
|
34
|
+
|
|
35
|
+
### Translated DSM title
|
|
36
|
+
|
|
37
|
+
- With `i18n.info` translations, the DSM main-menu entry and window title
|
|
38
|
+
follow the DSM language. `ui/config` refers to `synopkgland:app_title` and
|
|
39
|
+
`app_desc` in `ui/texts/<DSM language>/strings`, written for English and each
|
|
40
|
+
translated language; a language without its own text shows the English one.
|
|
41
|
+
Without translations `ui/config` keeps the literal English title.
|
|
42
|
+
|
|
43
|
+
- `synology-app.yaml` accepts the same `i18n.info` block. It writes INFO
|
|
44
|
+
`displayname_<lang>` / `description_<lang>` and, with `launch: dsm-window`,
|
|
45
|
+
localizes the DSM window entry. Once a translation exists, the English
|
|
46
|
+
`displayname` and `description` must also be one line without `"` or `\`
|
|
47
|
+
(`CONTRACT_I18N_INVALID`).
|
|
48
|
+
|
|
49
|
+
### Delegate window
|
|
50
|
+
|
|
51
|
+
- A DSM window built for a `scope: install-selected` delegate no longer
|
|
52
|
+
contains the dead `if (panels && false)` check. The window leaves out the
|
|
53
|
+
approval panel code instead, and other scopes generate `if (panels)`. The
|
|
54
|
+
behavior is unchanged: this scope is approved only in the app's
|
|
55
|
+
**Administrator setup** panel, because that approval carries the scope the
|
|
56
|
+
administrator picks and the window panel has no scope picker. The delegate
|
|
57
|
+
guide now says so.
|
|
58
|
+
|
|
59
|
+
### 繁體中文摘要
|
|
60
|
+
|
|
61
|
+
- 升級後重新建置套件即可換上新的 SDK 預設圖示(不再是純藍方塊)。executor digest 不變,不需重新核准。
|
|
62
|
+
- `dsm-package.yaml`、`synology-app.yaml` 與 native layout 新增 `icon`:專案內至少 256×256 的正方形
|
|
63
|
+
PNG,或含 `icon_256.png` 的 `icon_<size>.png` 目錄;不接受 SVG。`check` 顯示使用的圖示並檢查格式與
|
|
64
|
+
256 KiB 上限,`inspect` 回報 `default`/`custom`/`none`。
|
|
65
|
+
- 有 `i18n.info` 翻譯時,DSM 主選單與視窗標題會跟著 DSM 語言切換;缺翻譯的語言顯示英文。
|
|
66
|
+
`synology-app.yaml` 也支援 `i18n.info`。
|
|
67
|
+
- `scope: install-selected` 的 DSM 視窗不再產生 `if (panels && false)` 死碼;此 scope 仍只在 App 的
|
|
68
|
+
「管理員設定」核准。
|
|
69
|
+
|
|
70
|
+
## 0.7.1 (2026-10-10)
|
|
71
|
+
|
|
72
|
+
Rebuild packages to pick up template, hook and executor changes. The executor
|
|
73
|
+
digest changed. A package built with CLI 0.7.0 needs one administrator approval
|
|
74
|
+
after upgrading to a 0.7.1 build: the 0.7.0 executor opened the package
|
|
75
|
+
`target` link without following it, so it cannot install the anchored executor
|
|
76
|
+
itself. Executor-only upgrades between 0.7.1 or later builds need no approval.
|
|
77
|
+
|
|
78
|
+
### Executor upgrade and daemon timeouts
|
|
79
|
+
|
|
80
|
+
- During an INFO-anchored executor-only upgrade the executor log said
|
|
81
|
+
`executor paused: package pins require administrator approval` about two
|
|
82
|
+
seconds before the new executor was ready. That line now appears only when
|
|
83
|
+
the pins differ; an anchored handover logs only `executor upgrade:
|
|
84
|
+
INFO-anchored executor installed under the approved policy`. The executor
|
|
85
|
+
digest changes.
|
|
86
|
+
|
|
87
|
+
- `executor_status_mismatch` in the app window and the app's settings names
|
|
88
|
+
its cause: `the approved executor is not answering (<reason>)`, `the running
|
|
89
|
+
executor reports other digests than this package pins`, or `the executor
|
|
90
|
+
status request failed` with the request's own code, instead of `scheduler
|
|
91
|
+
readback or operation failed` for all three. The Data and removal
|
|
92
|
+
troubleshooting table explains each.
|
|
93
|
+
|
|
94
|
+
- After approval or control start the window asked `executor.status` every
|
|
95
|
+
500 ms for up to 10 s. The wait now doubles from 500 ms to 2 s within the
|
|
96
|
+
same 10 s budget: at most 7 requests instead of 20.
|
|
97
|
+
|
|
98
|
+
- For live upgrade tests, the repository's `scripts/test/executor-bump.py`
|
|
99
|
+
makes an executor-only build+1 SPK and now rewrites the window script's
|
|
100
|
+
embedded pins with the INFO anchor and `executor/setup.json`. The earlier
|
|
101
|
+
out-of-tree copy left the window pins behind, so the panel reported
|
|
102
|
+
`executor_status_mismatch` after every such upgrade while CGI and CLI
|
|
103
|
+
status were ready.
|
|
104
|
+
|
|
105
|
+
- On kernel 3.10 (DSM 7.1, for example DS416 armv7) an executor-only
|
|
106
|
+
upgrade, and approving again while the executor runs, no longer fail
|
|
107
|
+
with "pid executable mismatch". That kernel names a running executor
|
|
108
|
+
replaced by a rename after the rename source (`runtime/.executor
|
|
109
|
+
(deleted)`), and root control accepted only `runtime/executor`. Root
|
|
110
|
+
control now identifies the monitor by inode: the current
|
|
111
|
+
`runtime/executor`, or an unlinked root-owned inode on the runtime's
|
|
112
|
+
device whose last name was `executor` or `.executor*` in the runtime.
|
|
113
|
+
The fix runs in the new executor, which the installed one starts: an
|
|
114
|
+
upgrade from a package built with the target-link fix below needs no
|
|
115
|
+
approval; from 0.7.0 it still needs the one approval described there.
|
|
116
|
+
The executor digest changes.
|
|
117
|
+
|
|
118
|
+
- When the approved tasks are ready but the executor does not answer
|
|
119
|
+
(`executor_status_mismatch`), the app window offers Approve background
|
|
120
|
+
access again. With the tasks approved, it restarts the executor without
|
|
121
|
+
a password.
|
|
122
|
+
|
|
123
|
+
- `executor.status` (root-ops) names approval, not "Start the package", as
|
|
124
|
+
the next step when the package's last lifecycle request was start.
|
|
125
|
+
Regenerate or copy `backend/internal/app/executor.go`.
|
|
126
|
+
|
|
127
|
+
- An executor-only upgrade (same policy, new executor matching the INFO
|
|
128
|
+
`synopkgland_executor_sha256` anchor) no longer fails with "executor
|
|
129
|
+
upgrade refused: INFO-anchored executor could not be installed". The
|
|
130
|
+
installer opened `/var/packages/<pkg>/target/executor` without following
|
|
131
|
+
the DSM `target` link, which the executor refuses, so every such upgrade
|
|
132
|
+
stayed paused. The fix runs in the executor that is already installed:
|
|
133
|
+
an upgrade from a package built with an earlier SDK still needs one
|
|
134
|
+
administrator approval. The executor digest changes.
|
|
135
|
+
|
|
136
|
+
- `executor.status` (root-ops and delegate projects) no longer answers
|
|
137
|
+
`internal` while the executor is paused (package stopped, or pins waiting
|
|
138
|
+
for approval). It answers `{ready: false, state: "paused", reason:
|
|
139
|
+
"executor_not_listening", next}`, and `synopkgland status` shows the
|
|
140
|
+
reason and next step. Regenerate or copy
|
|
141
|
+
`backend/internal/app/executor.go` into existing projects.
|
|
142
|
+
|
|
143
|
+
- `daemon.timeouts` defaults are now `{start: 30, stop: 30, status: 5,
|
|
144
|
+
uninstall: 60}` (were `start: 5, stop: 10, status: 2`). On vt-nas under
|
|
145
|
+
IO load a boot start took more than 5 s and a Connect revoke more than
|
|
146
|
+
9 s. The new `timeouts.uninstall` (2–120) bounds `uninstall_args`
|
|
147
|
+
separately; it used to get `stop - 1`, so an app had to raise the SIGKILL
|
|
148
|
+
wait to give its revoke time. DSM's package unit allows 3600 s for start
|
|
149
|
+
and stop. `inspect` still accepts SPKs built before `timeouts.uninstall`.
|
|
150
|
+
The manifest reference explains how to pick values from a loaded NAS.
|
|
151
|
+
|
|
152
|
+
### Approval, identity and uninstall fixes
|
|
153
|
+
|
|
154
|
+
- `identity: standalone`: "Continue with DSM" and every live revalidation
|
|
155
|
+
failed with `session_required` after a DSM web login, because DSM web
|
|
156
|
+
sessions enable SynoToken and DSM answers the `id` cookie alone with 119.
|
|
157
|
+
The backend now forwards the request's single `X-SYNO-TOKEN` header, which
|
|
158
|
+
the DSM window's `ctx.call` already sends, when it checks the DSM session.
|
|
159
|
+
Sessions without SynoToken still verify with the cookie alone. The token is
|
|
160
|
+
never put in a URL, logged or stored. This also unblocks root-ops approval
|
|
161
|
+
in an `identity: standalone` package, which stopped at `executor.control`.
|
|
162
|
+
Existing projects need the updated `internal/identity` files.
|
|
163
|
+
- When approval created and read back both tasks but the executor then did
|
|
164
|
+
not start or report healthy, the window left the tasks behind, and with no
|
|
165
|
+
running executor there was no task inventory for uninstall to delete them.
|
|
166
|
+
The window now withdraws the tasks that approval created; tasks from an
|
|
167
|
+
earlier approval stay.
|
|
168
|
+
- After a wrong password or a withdrawn approval, the window panel showed
|
|
169
|
+
only "Check status". It and the app's settings now keep the approve action.
|
|
170
|
+
- Uninstall no longer logs `task cleanup unconfirmed` for every successful
|
|
171
|
+
delete: EventScheduler `delete` v1 and TaskScheduler `delete` v2 answer
|
|
172
|
+
`{"success":true}` without data, which now counts as confirmed. The task
|
|
173
|
+
definitions are unchanged, so no new approval is needed; the executor
|
|
174
|
+
digest changes.
|
|
175
|
+
- The native root window (`@synopackageland/cli/authorization-sdk`) gave up
|
|
176
|
+
after about 30 s with `root_timeout`, while a loaded NAS ran the bootstrap
|
|
177
|
+
task for up to 4.5 minutes. It now keeps waiting while the task is queued or
|
|
178
|
+
running, up to 10 minutes, reports `{op, state, elapsedMs}` through
|
|
179
|
+
`options.progress`, and the authorization flow accepts the backend's ready
|
|
180
|
+
grant after `root_timeout` or `root_task_failed`.
|
|
181
|
+
- A DSM certificate that Node does not trust failed with only
|
|
182
|
+
`fetch failed`. The CLI now reports `DSM_TLS_UNTRUSTED` with the origin and
|
|
183
|
+
certificate error and points to `NODE_EXTRA_CA_CERTS`; certificate checks
|
|
184
|
+
stay on.
|
|
185
|
+
- Docs: on DSM 7.1 the purge timing lines are only in the journal
|
|
186
|
+
(`journalctl -t synopkgland-executor`); `init -t native-go` does not include
|
|
187
|
+
`armv7` in `arches`, so add it for an armv7 NAS.
|
|
188
|
+
|
|
189
|
+
### Deploy and status fixes
|
|
190
|
+
|
|
191
|
+
- `status` no longer reports `blocked` for every `identity: standalone`
|
|
192
|
+
project. It opens a short-lived App session from the administrator's DSM
|
|
193
|
+
session, reads `executor.status`, then logs out. That needs an `https://`
|
|
194
|
+
host; over `http://` the capability stays `blocked` and the reason says so.
|
|
195
|
+
- `deploy` accepts the install wizard values of an `install-selected`
|
|
196
|
+
delegate: `--param delegate_share=<Shared Folder>` or
|
|
197
|
+
`--param delegate_home=true`. A first install without one now fails with
|
|
198
|
+
`DEPLOY_PARAM_REQUIRED` and a usage line before anything is built, instead
|
|
199
|
+
of failing inside DSM. Invalid values fail with `DEPLOY_PARAM_TYPE_INVALID`.
|
|
200
|
+
- `deploy` and `status` work on a native layout (existing native product).
|
|
201
|
+
`deploy` builds the NAS architecture only; an `aarch64` NAS uses a declared
|
|
202
|
+
`armv8`.
|
|
203
|
+
- The deploy note no longer says every upgrade needs approval: an
|
|
204
|
+
executor-only upgrade stays ready; a policy digest change needs approval.
|
|
205
|
+
- Uninstall logs per-phase purge timing with the package name to the system
|
|
206
|
+
log (`synopkgland-executor`): `task cleanup timing` per task and
|
|
207
|
+
`purge timing` for the task and file phases. The executor digest changes.
|
|
208
|
+
- `add root-ops` and `add portal` print a notice on stderr when they raise
|
|
209
|
+
`os_min_ver`.
|
|
210
|
+
- `inspect` on an executor SPK describes the root boot and control tasks
|
|
211
|
+
instead of saying the package needs no root privileges.
|
|
212
|
+
|
|
213
|
+
### DSM 7.1: root-ops and delegate approval work
|
|
214
|
+
|
|
215
|
+
- DSM 7.1.1 has no `SYNO.Core.TaskScheduler.Root` or
|
|
216
|
+
`SYNO.Core.EventScheduler.Root`, TaskScheduler stops at v3 and
|
|
217
|
+
PasswordConfirm at v1, so approval failed with "Background file access is
|
|
218
|
+
unavailable" and `status`/`deploy` showed `rootOps: unsupported — DSM 103`
|
|
219
|
+
or `DSM 104`. DSM 7.1.1 answers a version above the API's maximum with 104
|
|
220
|
+
(PasswordConfirm v2, TaskScheduler `get` v4) and a method missing at an
|
|
221
|
+
existing version with 103 (TaskScheduler `list` v3). When DSM answers a
|
|
222
|
+
scheduler read or the password check with 103 or 104, the app now uses
|
|
223
|
+
PasswordConfirm v1, TaskScheduler `list` v2/`get` v3 and creates
|
|
224
|
+
the tasks with EventScheduler `create` v1 and TaskScheduler `create` v3.
|
|
225
|
+
The password is still confirmed first and both tasks are still read back
|
|
226
|
+
exactly before anything runs. Other errors (such as 105, 119, 102 or a
|
|
227
|
+
wrong password, 3121) never fall back, and a create is never retried. DSM
|
|
228
|
+
7.1 does not bind task creation to the password check; see the root-ops
|
|
229
|
+
guide.
|
|
230
|
+
- `status` and `deploy` read the control task the same way.
|
|
231
|
+
- Uninstall on DSM 7.1 now removes the boot and control tasks. The executor
|
|
232
|
+
looked the control task up with TaskScheduler `get` v4, which DSM 7.1.1
|
|
233
|
+
refuses with 104, so it wrote no task inventory and left both tasks behind.
|
|
234
|
+
- If approval stops after it created a task (for example, the boot task was
|
|
235
|
+
created and the control task was not), the app deletes the tasks it created
|
|
236
|
+
in that attempt instead of leaving an enabled root boot task that nothing
|
|
237
|
+
owns. Tasks from an earlier approval stay.
|
|
238
|
+
- A failed approval shows its reason and DSM error code in the app's settings
|
|
239
|
+
instead of only "Background file access is unavailable", and a refused
|
|
240
|
+
password reads as a password failure, not a scheduler failure.
|
|
241
|
+
- After the app's settings approve, the window's status line no longer shows
|
|
242
|
+
"needs-admin-approval: Task is missing" until a reload; the window panel and
|
|
243
|
+
the settings now follow each other's results.
|
|
244
|
+
|
|
245
|
+
### DSM 7.1: jobs import and file downloads
|
|
246
|
+
|
|
247
|
+
- DSM 7.1.1 sends `SYNO.FileStation.Download` v2 replies without
|
|
248
|
+
`Content-Disposition`, so `bg.jobs.submit` and downloads failed with
|
|
249
|
+
`unavailable`. With no such header, a body of at most 4 KiB that decodes
|
|
250
|
+
as a DSM reply is still refused as that reply; any other body is the file.
|
|
251
|
+
|
|
252
|
+
### Docs: build your own armv7 Go code with Go 1.26.9
|
|
253
|
+
|
|
254
|
+
- On armv7 DSM 7.1.1 (kernel 3.10), a program built with Go 1.26.0 crashed
|
|
255
|
+
at start (`futexwakeup returned -22`, SIGSEGV) and Go 1.26.9 ran. Other
|
|
256
|
+
1.26 releases were not tested.
|
|
257
|
+
|
|
258
|
+
### init: next steps install frontend dependencies
|
|
259
|
+
|
|
260
|
+
- `init -t native-go` with a Vue frontend now lists `(cd frontend && npm ci)`
|
|
261
|
+
before `synopkgland build`; without it the build fails with
|
|
262
|
+
`STANDALONE_UI_BUILD_FAILED`. `build` still does not install dependencies.
|
|
263
|
+
|
|
264
|
+
### Executor, daemon and gateway build with exactly Go 1.26.9
|
|
265
|
+
|
|
266
|
+
- The CLI builds the executor, lifecycle helper, daemon controller and gateway
|
|
267
|
+
with `GOTOOLCHAIN=go1.26.9`, ignoring your `GOTOOLCHAIN`, `GOFLAGS`,
|
|
268
|
+
`GOEXPERIMENT`, `GOWORK` and `GOAMD64`/`GOARM64`, so every builder produces
|
|
269
|
+
the same executor digest. Go 1.21 or later downloads go1.26.9 when needed;
|
|
270
|
+
offline without it the build fails and names go1.26.9. A binary whose Go
|
|
271
|
+
build info names another release is refused.
|
|
272
|
+
- Template go.mod files now say `toolchain go1.26.9`. The executor digest
|
|
273
|
+
changes; it is anchored in INFO, so an upgrade with an unchanged policy needs
|
|
274
|
+
no new approval.
|
|
275
|
+
|
|
276
|
+
### INFO arch: four more DSM platforms
|
|
277
|
+
|
|
278
|
+
- x86_64 SPKs now also list `broadwellntb`, `coffeelake` and `skylaked`, and
|
|
279
|
+
aarch64 SPKs list `rtd1619` (DSM Developer Guide Appendix A family members).
|
|
280
|
+
INFO `arch` now matches the platforms the package source maps to each family.
|
|
281
|
+
|
|
282
|
+
### 繁體中文摘要
|
|
283
|
+
|
|
284
|
+
- 升級後重新建置套件;executor digest 改變。**從 0.7.0 建的套件升級需管理員再核准一次**(0.7.0 的
|
|
285
|
+
executor 開啟套件 `target` symlink 時未跟隨連結,無法自行安裝錨定的 executor);之後 0.7.1 起的
|
|
286
|
+
executor-only 升級不需核准。
|
|
287
|
+
- executor:kernel 3.10(DSM 7.1,如 DS416 armv7)上 executor-only 升級與執行中再核准不再出現
|
|
288
|
+
`pid executable mismatch`;INFO 錨定升級不再誤報 `executor upgrade refused`,也不再先印
|
|
289
|
+
「paused: 需管理員核准」;`executor.status` 暫停時回 `paused`/`executor_not_listening` 與下一步。
|
|
290
|
+
- 面板:executor 不回應時可再按一次「Approve background access」免密碼重啟;
|
|
291
|
+
`executor_status_mismatch` 會寫出原因(不回應/digest 不同/status 請求失敗);
|
|
292
|
+
啟動後的 `executor.status` 等待改為 500 ms→2 s 退避,10 s 預算不變。
|
|
293
|
+
- `daemon.timeouts` 預設改為 `{start: 30, stop: 30, status: 5, uninstall: 60}`,新增 `timeouts.uninstall`。
|
|
294
|
+
- `identity: standalone`:DSM 網頁 session(SynoToken)下「Continue with DSM」與 root-ops 核准修正;
|
|
295
|
+
核准建立 task 後 executor 未啟動時自動撤回本次建立的 task;卸載不再誤記 `task cleanup unconfirmed`。
|
|
296
|
+
- 原生 root window 等待上限改為 10 分鐘並回報進度;`DSM_TLS_UNTRUSTED` 指向 `NODE_EXTRA_CA_CERTS`。
|
|
297
|
+
- `status`/`deploy`:standalone 專案的 status 改用短期 App session;`deploy` 接受
|
|
298
|
+
install-selected delegate 的精靈參數;支援 native layout;卸載記錄 purge timing。
|
|
299
|
+
- DSM 7.1:無 Root API 時改走 PasswordConfirm v1/TaskScheduler v2–v3/EventScheduler create v1,
|
|
300
|
+
卸載會移除 boot/control task;`SYNO.FileStation.Download` v2 無 `Content-Disposition` 的下載修正。
|
|
301
|
+
- 建置:executor、lifecycle、daemon、gateway 一律以 Go 1.26.9 建置(armv7 kernel 3.10 上 1.26.0 會當機);
|
|
302
|
+
INFO `arch` 新增 `broadwellntb`、`coffeelake`、`skylaked`、`rtd1619`。
|
|
303
|
+
- 測試工具:`scripts/test/executor-bump.py` 收進 repo,會一併改寫視窗腳本內嵌的 executor pin。
|
|
4
304
|
|
|
5
305
|
## 0.7.0 (2026-10-10)
|
|
6
306
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# SDK default package icon
|
|
2
|
+
|
|
3
|
+
Used by `synopkgland build` when `dsm-package.yaml` or `synology-app.yaml`
|
|
4
|
+
sets no `icon`. It marks an App that has not chosen its own icon yet: a
|
|
5
|
+
Package Land parcel on the cream brand tile, not a broken image.
|
|
6
|
+
|
|
7
|
+
This folder is itself an icon directory (`icon: <dir>`): `icon_<size>.png`
|
|
8
|
+
files are used as drawn and `icon_256.png` is scaled for any missing size.
|
|
9
|
+
|
|
10
|
+
- `default-icon.svg` draws 48, 64, 72 and 256.
|
|
11
|
+
- `default-icon-small.svg` is a 16 px pixel grid for 16, 24 and 32.
|
|
12
|
+
|
|
13
|
+
Regenerate after editing an SVG (rsvg-convert is a maintainer tool only;
|
|
14
|
+
the CLI never rasterises SVG):
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
for s in 16 24 32; do rsvg-convert -w $s -h $s default-icon-small.svg -o icon_$s.png; done
|
|
18
|
+
for s in 48 64 72 256; do rsvg-convert -w $s -h $s default-icon.svg -o icon_$s.png; done
|
|
19
|
+
```
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" shape-rendering="crispEdges">
|
|
2
|
+
<rect x="0" y="0" width="16" height="16" rx="3.5" fill="#fbf5e8"/>
|
|
3
|
+
<rect x="3" y="2" width="2" height="2" fill="#1f78e5"/>
|
|
4
|
+
<rect x="7" y="1" width="2" height="3" fill="#f6b324"/>
|
|
5
|
+
<rect x="11" y="2" width="2" height="2" fill="#1f78e5"/>
|
|
6
|
+
<rect x="2" y="4" width="12" height="3" fill="#135bb8"/>
|
|
7
|
+
<rect x="3" y="7" width="10" height="7" fill="#1f78e5"/>
|
|
8
|
+
<rect x="6" y="9" width="4" height="1" fill="#fbf5e8"/>
|
|
9
|
+
</svg>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 256 256">
|
|
2
|
+
<rect x="6" y="6" width="244" height="244" rx="56" fill="#fbf5e8" stroke="#e4d8bd" stroke-width="4"/>
|
|
3
|
+
<path d="M212 22l6 14 14 6-14 6-6 14-6-14-14-6 14-6z" fill="#f6b324"/>
|
|
4
|
+
<rect x="62" y="58" width="30" height="30" rx="6" fill="#1f78e5"/>
|
|
5
|
+
<rect x="113" y="50" width="30" height="38" rx="6" fill="#f6b324"/>
|
|
6
|
+
<rect x="164" y="58" width="30" height="30" rx="6" fill="#1f78e5"/>
|
|
7
|
+
<rect x="48" y="80" width="160" height="44" rx="12" fill="#135bb8"/>
|
|
8
|
+
<path d="M58 118h140v66a24 24 0 0 1-24 24H82a24 24 0 0 1-24-24z" fill="#1f78e5"/>
|
|
9
|
+
<rect x="100" y="140" width="56" height="16" rx="8" fill="#fbf5e8"/>
|
|
10
|
+
</svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/add.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
type AddResult = {
|
|
2
2
|
added: string[];
|
|
3
3
|
unchanged: string[];
|
|
4
|
+
notes?: string[];
|
|
4
5
|
};
|
|
6
|
+
export declare function addCapabilities(root: string, requested: string[]): AddResult;
|
|
7
|
+
export {};
|
package/dist/add.js
CHANGED
|
@@ -46,11 +46,17 @@ function safePath(root, file) {
|
|
|
46
46
|
}
|
|
47
47
|
return true;
|
|
48
48
|
}
|
|
49
|
-
/** Raise a lower os_min_ver to the floor a capability needs; a higher one stays. */
|
|
50
|
-
function raiseOsMinVer(doc, current, floor) {
|
|
49
|
+
/** Raise a lower os_min_ver to the floor a capability needs; a higher one stays. Returns the notice. */
|
|
50
|
+
function raiseOsMinVer(doc, current, floor, capability) {
|
|
51
51
|
const osMinVer = doc.get('os_min_ver', true);
|
|
52
|
-
if (isScalar(osMinVer)
|
|
53
|
-
|
|
52
|
+
if (!isScalar(osMinVer) || isDsmAtLeast(current, floor))
|
|
53
|
+
return [];
|
|
54
|
+
osMinVer.value = floor;
|
|
55
|
+
return [`os_min_ver raised from ${current} to ${floor}: ${capability} needs DSM ${floor} or later.`];
|
|
56
|
+
}
|
|
57
|
+
function withNotes(result, notes) {
|
|
58
|
+
const all = [...(result.notes ?? []), ...notes];
|
|
59
|
+
return all.length ? { ...result, notes: all } : result;
|
|
54
60
|
}
|
|
55
61
|
/**
|
|
56
62
|
* `portal: {}` in dsm-package.yaml; the Go and binary starters already carry the UI and backend side.
|
|
@@ -67,9 +73,9 @@ function addPortal(root, result) {
|
|
|
67
73
|
const manifestPath = join(root, 'dsm-package.yaml');
|
|
68
74
|
const doc = parseDocument(readFileSync(manifestPath, 'utf8'));
|
|
69
75
|
doc.set('portal', doc.createNode({}, { flow: true }));
|
|
70
|
-
raiseOsMinVer(doc, loaded.manifest.os_min_ver, PORTAL_MIN_DSM);
|
|
76
|
+
const notes = raiseOsMinVer(doc, loaded.manifest.os_min_ver, PORTAL_MIN_DSM, 'portal');
|
|
71
77
|
writeFileSync(manifestPath, String(doc));
|
|
72
|
-
return { ...result, added: [...result.added, 'portal'] };
|
|
78
|
+
return withNotes({ ...result, added: [...result.added, 'portal'] }, notes);
|
|
73
79
|
}
|
|
74
80
|
export function addCapabilities(root, requested) {
|
|
75
81
|
const wanted = [...new Set(requested.flatMap(value => value.split(',')).map(value => value.trim()))];
|
|
@@ -129,8 +135,7 @@ export function addCapabilities(root, requested) {
|
|
|
129
135
|
for (const [key, value] of Object.entries(nativeCapabilitySettings(added)))
|
|
130
136
|
doc.setIn(['capabilities', key], value);
|
|
131
137
|
// rootOps needs DSM 7.1-42661 or later.
|
|
132
|
-
|
|
133
|
-
raiseOsMinVer(doc, m.os_min_ver, DEFAULT_MIN_DSM);
|
|
138
|
+
const notes = added.includes('root-ops') ? raiseOsMinVer(doc, m.os_min_ver, DEFAULT_MIN_DSM, 'root-ops') : [];
|
|
134
139
|
for (const file of destinations) {
|
|
135
140
|
const path = join(root, file);
|
|
136
141
|
mkdirSync(dirname(path), { recursive: true });
|
|
@@ -139,7 +144,7 @@ export function addCapabilities(root, requested) {
|
|
|
139
144
|
for (const file of deletions)
|
|
140
145
|
rmSync(join(root, file), { force: true });
|
|
141
146
|
writeFileSync(manifestPath, String(doc));
|
|
142
|
-
return { added, unchanged };
|
|
147
|
+
return withNotes({ added, unchanged }, notes);
|
|
143
148
|
}
|
|
144
149
|
finally {
|
|
145
150
|
rmSync(work, { recursive: true, force: true });
|
|
@@ -1,2 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
export declare
|
|
1
|
+
/** Sizes DSM loads for `images/app_{0}.png` (main menu, desktop, window, taskbar). */
|
|
2
|
+
export declare const WINDOW_ICON_SIZES: readonly [16, 24, 32, 48, 64, 72, 256];
|
|
3
|
+
/** The package source drops a release whose PACKAGE_ICON is larger than this. */
|
|
4
|
+
export declare const MAX_ICON_BYTES: number;
|
|
5
|
+
export interface PackageIcons {
|
|
6
|
+
source: "custom" | "default";
|
|
7
|
+
/** Encoded PNG per DSM window size; PACKAGE_ICON.PNG is 64 and PACKAGE_ICON_256.PNG is 256. */
|
|
8
|
+
window: Map<number, Buffer>;
|
|
9
|
+
packageIcon: Buffer;
|
|
10
|
+
packageIcon256: Buffer;
|
|
11
|
+
/** Every pixel of the 256 px icon is the same colour. */
|
|
12
|
+
solid: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** Ships next to dist/ and src/ alike: <package>/assets/default-icon. */
|
|
15
|
+
export declare const DEFAULT_ICON_DIR: string;
|
|
16
|
+
/** A project icon: one square PNG of at least 256 px, or a directory of icon_<size>.png. */
|
|
17
|
+
export declare function renderPackageIcons(path: string): PackageIcons;
|
|
18
|
+
/** The SDK default icon, for projects that set no `icon`. */
|
|
19
|
+
export declare function defaultPackageIcons(): PackageIcons;
|
|
20
|
+
/** The project's icon when it sets one, otherwise the SDK default. */
|
|
21
|
+
export declare function packageIcons(icon: string | undefined): PackageIcons;
|
|
22
|
+
/** What check reports: which icon a build would use, relative to the project. */
|
|
23
|
+
export interface IconReport {
|
|
24
|
+
/** `layout`: a native layout without `icon`, whose metadata owns PACKAGE_ICON*.PNG. */
|
|
25
|
+
source: PackageIcons["source"] | "layout";
|
|
26
|
+
path?: string;
|
|
27
|
+
solid: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare function iconReport(root: string, icon: string | undefined): IconReport;
|
|
30
|
+
export declare function writeDsmWindowIcons(uiDir: string, icons: PackageIcons): void;
|
|
31
|
+
export declare function writePackageCenterIcons(spkRoot: string, icons: PackageIcons): void;
|