@synopackageland/cli 0.17.1 → 0.17.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 +13 -2
- package/assets/init-compose.md +1 -1
- package/dist/ctl/cli.js +1 -1
- package/dist/init-upstream.js +1 -1
- package/dist/runtime/executor-digests.json +22 -0
- package/dist/standalone/root-window.js +2 -2
- package/package.json +2 -2
- package/skills/SKILL.md +1 -1
- package/skills/reference/compose.md +2 -2
- package/skills/reference/create.md +2 -2
- package/skills/reference/upstream-fork.md +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.17.
|
|
3
|
+
## 0.17.3 (2026-10-19)
|
|
4
|
+
|
|
5
|
+
- Pin templates 0.17.5, SDK/App 0.17.3 and UI 0.12.3 for generated Apps.
|
|
6
|
+
- Record SDK 0.17.3 executor and lifecycle digests; all six payloads are unchanged from 0.17.1.
|
|
7
|
+
- Keep the “User password” wording in all nine locales and package the generated native SDK version identifiers.
|
|
8
|
+
|
|
9
|
+
## 0.17.2 (2026-10-19)
|
|
10
|
+
|
|
11
|
+
- Pin templates with matching frontend and native SDK versions.
|
|
12
|
+
- Record the verified SDK 0.17.1 executor and lifecycle payload digests.
|
|
13
|
+
- Rename password labels and approval instructions to “User password” across all nine locales.
|
|
14
|
+
|
|
15
|
+
## 0.17.1 (2026-10-19)
|
|
4
16
|
|
|
5
17
|
- Remove environment-specific release notes and source comments from distributed content, including generated DSM window scripts.
|
|
6
18
|
- Prepare npm releases from a clean package directory without local archive references.
|
|
7
|
-
- 清理發佈內容中的環境識別敘述;以乾淨套件目錄準備 npm 發佈。
|
|
8
19
|
|
|
9
20
|
## 0.17.0 (2026-10-19)
|
|
10
21
|
|
package/assets/init-compose.md
CHANGED
|
@@ -22,7 +22,7 @@ Application Portal. Headless Apps omit compose.web and have no launcher.
|
|
|
22
22
|
Compose ctl is unsupported.
|
|
23
23
|
|
|
24
24
|
Use supported upstream config files, environment, argv or reverse proxy for
|
|
25
|
-
login/settings. For integrated upstream Apps, select supported trusted-header authentication or disable upstream login behind the DSM admin gate; or use the existing SDK 0.17.
|
|
25
|
+
login/settings. For integrated upstream Apps, select supported trusted-header authentication or disable upstream login behind the DSM admin gate; or use the existing SDK 0.17.3 token adapter: OpenList uses mode: token, access: dsm-admins and entry: admin-only. Its unmodified admin token CLI supplies a package-private 0600 credential; the gateway injects Authorization server-side after DSM admission, without delivering it to the browser. All DSM admins share one upstream admin; token reset requires package restart; WebDAV keeps its own credentials. Verify each App adapter and DSM admission separately.
|
|
26
26
|
Containers use the package account and a dedicated bridge; they do not inherit
|
|
27
27
|
an interactive user's NAS ACL. Do not use root/chown during any App lifecycle
|
|
28
28
|
phase. Preserve licenses and dependency/source provenance. Read the CLI skill
|
package/dist/ctl/cli.js
CHANGED
|
@@ -99,7 +99,7 @@ export async function runCtl(argv, io = {}) {
|
|
|
99
99
|
throw new CtlError('CTL_URL_REQUIRED', '--url is required.', `run: synopkgland ctl host add ${name} --url https://${name}:5001`);
|
|
100
100
|
const host = old ?? { name, origin: canonicalOrigin(url, tunnel), username: usernameOption ?? await ask('DSM account: '), approved: {}, ...(tunnel ? { tunnel: true } : {}), ...(ca ? { ca } : {}) };
|
|
101
101
|
const previous = old ? await store.credentials.get(store.key(host)) : null;
|
|
102
|
-
const secret = passwordStdin ? readBounded(0, 4096).replace(/[\r\n]+$/, '') : await ask('
|
|
102
|
+
const secret = passwordStdin ? readBounded(0, 4096).replace(/[\r\n]+$/, '') : await ask('User password: ', true);
|
|
103
103
|
const session = await loginDsm(host.origin, host.username, secret, { remember: !noRemember, deviceId: previous?.deviceId, otp: () => ask('DSM OTP: ', true), request: io.requestFor?.(host), ca: host.ca ? readFileSync(host.ca, 'utf8') : undefined });
|
|
104
104
|
try {
|
|
105
105
|
if (old)
|
package/dist/init-upstream.js
CHANGED
|
@@ -58,7 +58,7 @@ Commit the scaffold, then run bash synology/upgrade.sh <upstream-tag> <build-num
|
|
|
58
58
|
|
|
59
59
|
${official ? 'Default: use the upstream official image. upgrade.sh updates its release tag and resolves an OCI index/manifest digest through synopkgland images pin, writing only synology/compose.image.yaml. Container Manager downloads that pinned official image at install. Configure upstream-recipe.json repository/service and imageTag: tag (exact upstream tag) or version (strip v only when upstream image naming requires it). Review multi-architecture support and upstream source/license correspondence. The SELECT_UPSTREAM_TAG placeholder must be replaced by a successful upgrade before check/build.' : 'Native App: implement build-source.sh as the native payload hook; it deliberately fails until implemented. Stage official release binaries pinned by SHA-256 (the OpenList route), or compile the merged source with a source build hook. Verify the release digest before staging architecture-specific daemon.targets; keep the SDK management shell separate.'}
|
|
60
60
|
|
|
61
|
-
Use DSM administrator identity without an additional App password, an OIDC/SSO server or upstream source changes. Prefer supported trusted-header/proxy auth (FreshRSS), otherwise disable upstream login/enable guest behind the administrator-only gateway after a bounded first bootstrap (Uptime Kuma disableAuth). The third shipped pattern is the existing SDK 0.17.
|
|
61
|
+
Use DSM administrator identity without an additional App password, an OIDC/SSO server or upstream source changes. Prefer supported trusted-header/proxy auth (FreshRSS), otherwise disable upstream login/enable guest behind the administrator-only gateway after a bounded first bootstrap (Uptime Kuma disableAuth). The third shipped pattern is the existing SDK 0.17.3 token adapter: mode: token, access: dsm-admins, entry: admin-only. OpenList obtains its native API token with the unmodified admin token CLI while stopped, stores it package-private 0600 under a 0700 directory, and the gateway injects Authorization server-side after DSM admission; packaging never delivers it to the browser. All DSM admins share one upstream admin; token reset requires package restart; WebDAV keeps its own native credentials. The upstream admin token/settings APIs remain unchanged. Verify actual DSM admission/revocation separately. Use supported config, environment, argv or proxy adapters. Every App lifecycle phase runs as the package UID. For upstream fixed-UID data directories, currently provide a synology/ startup adapter or writable path without root/chown; replace it with the framework ownership mechanism when available. Preserve licenses and the full source/component inventory.
|
|
62
62
|
`;
|
|
63
63
|
writeFileSync(join(packaging, 'AGENTS.md'), readFileSync(join(packaging, 'AGENTS.md'), 'utf8') + guidance);
|
|
64
64
|
}
|
|
@@ -9,5 +9,27 @@
|
|
|
9
9
|
"armv7": "cafc97c89f5645c14a8cf31d6d9f258394ed6f2d086478a7aebd04d57c274b4e"
|
|
10
10
|
},
|
|
11
11
|
"goToolchain": "go1.26.9"
|
|
12
|
+
},
|
|
13
|
+
"0.17.1": {
|
|
14
|
+
"x86_64": "68f372684997258adc61312f2c353e1a286a6b5aaa556f716b4e6ba6f33893d0",
|
|
15
|
+
"aarch64": "f6950301e201a4ebc14577a4554fa1b671f90d0f354d1e8809f4d1dafb57c723",
|
|
16
|
+
"armv7": "e77c9b6ae22ecfa85d9834af3350192e445987265a7ca6c02ca9b01d88a1b4f7",
|
|
17
|
+
"lifecycle": {
|
|
18
|
+
"x86_64": "d65500c4f04713a32b45d360059281391acfa5e00ee24895fdd2de7b82735372",
|
|
19
|
+
"aarch64": "94f6cd119186ff482b8aea56541dd1f9d53c147566bc1efdca6f5a1c86198331",
|
|
20
|
+
"armv7": "cafc97c89f5645c14a8cf31d6d9f258394ed6f2d086478a7aebd04d57c274b4e"
|
|
21
|
+
},
|
|
22
|
+
"goToolchain": "go1.26.9"
|
|
23
|
+
},
|
|
24
|
+
"0.17.3": {
|
|
25
|
+
"x86_64": "68f372684997258adc61312f2c353e1a286a6b5aaa556f716b4e6ba6f33893d0",
|
|
26
|
+
"aarch64": "f6950301e201a4ebc14577a4554fa1b671f90d0f354d1e8809f4d1dafb57c723",
|
|
27
|
+
"armv7": "e77c9b6ae22ecfa85d9834af3350192e445987265a7ca6c02ca9b01d88a1b4f7",
|
|
28
|
+
"lifecycle": {
|
|
29
|
+
"x86_64": "d65500c4f04713a32b45d360059281391acfa5e00ee24895fdd2de7b82735372",
|
|
30
|
+
"aarch64": "94f6cd119186ff482b8aea56541dd1f9d53c147566bc1efdca6f5a1c86198331",
|
|
31
|
+
"armv7": "cafc97c89f5645c14a8cf31d6d9f258394ed6f2d086478a7aebd04d57c274b4e"
|
|
32
|
+
},
|
|
33
|
+
"goToolchain": "go1.26.9"
|
|
12
34
|
}
|
|
13
35
|
}
|
|
@@ -388,7 +388,7 @@ export const ROOT_RUNTIME = `function createRootAccess(options) {
|
|
|
388
388
|
/** The plain-UI window panel's text: a state, and a result's code and outcome; reason stays the runtime's English detail. */
|
|
389
389
|
export const ROOT_PANEL_MESSAGES = {
|
|
390
390
|
title: { en: "Background access", "zh-TW": "背景存取", "zh-CN": "后台访问", ja: "バックグラウンドアクセス", ko: "백그라운드 액세스", de: "Hintergrundzugriff", fr: "Accès en arrière-plan", es: "Acceso en segundo plano", it: "Accesso in background" },
|
|
391
|
-
password: { en: "
|
|
391
|
+
password: { en: "User password", "zh-TW": "使用者密碼", "zh-CN": "用户密码", ja: "ユーザーパスワード", ko: "사용자 비밀번호", de: "Benutzerpasswort", fr: "Mot de passe utilisateur", es: "Contraseña de usuario", it: "Password utente" },
|
|
392
392
|
approve: { en: "Approve", "zh-TW": "核准", "zh-CN": "批准", ja: "承認", ko: "승인", de: "Genehmigen", fr: "Approuver", es: "Aprobar", it: "Approva" },
|
|
393
393
|
check: { en: "Check status", "zh-TW": "檢查狀態", "zh-CN": "检查状态", ja: "状態を確認", ko: "상태 확인", de: "Status prüfen", fr: "Vérifier l'état", es: "Comprobar estado", it: "Verifica stato" },
|
|
394
394
|
working: { en: "Waiting for the background service. This can take up to a minute while it starts.", "zh-TW": "正在等候背景服務,啟動時最多可能需要一分鐘。", "zh-CN": "正在等候后台服务,启动时最多可能需要一分钟。", ja: "バックグラウンドサービスを待機しています。開始時は最大 1 分かかることがあります。", ko: "백그라운드 서비스를 기다리는 중입니다. 시작할 때 최대 1분이 걸릴 수 있습니다.", de: "Warten auf den Hintergrunddienst. Beim Start kann dies bis zu einer Minute dauern.", fr: "En attente du service en arrière-plan. Son démarrage peut prendre jusqu'à une minute.", es: "Esperando al servicio en segundo plano. Al iniciarse puede tardar hasta un minuto.", it: "In attesa del servizio in background. All'avvio può richiedere fino a un minuto." },
|
|
@@ -398,7 +398,7 @@ export const ROOT_PANEL_MESSAGES = {
|
|
|
398
398
|
"state.unsupported": { en: "This DSM does not support background access.", "zh-TW": "這台 DSM 不支援背景存取。", "zh-CN": "此 DSM 不支持后台访问。", ja: "この DSM はバックグラウンドアクセスに対応していません。", ko: "이 DSM은 백그라운드 액세스를 지원하지 않습니다.", de: "Dieses DSM unterstützt keinen Hintergrundzugriff.", fr: "Ce DSM ne prend pas en charge l'accès en arrière-plan.", es: "Este DSM no admite el acceso en segundo plano.", it: "Questo DSM non supporta l'accesso in background." },
|
|
399
399
|
"state.cancelled": { en: "Approval was cancelled.", "zh-TW": "已取消核准。", "zh-CN": "已取消批准。", ja: "承認はキャンセルされました。", ko: "승인이 취소되었습니다.", de: "Genehmigung abgebrochen.", fr: "Approbation annulée.", es: "Aprobación cancelada.", it: "Approvazione annullata." },
|
|
400
400
|
"reason.password_rejected": { en: "DSM rejected the administrator password. Nothing was changed.", "zh-TW": "DSM 拒絕了管理員密碼,沒有做任何變更。", "zh-CN": "DSM 拒绝了管理员密码,没有做任何更改。", ja: "DSM が管理者パスワードを拒否しました。何も変更されていません。", ko: "DSM에서 관리자 비밀번호를 거부했습니다. 변경된 내용은 없습니다.", de: "DSM hat das Administratorkennwort abgelehnt. Es wurde nichts geändert.", fr: "DSM a refusé le mot de passe administrateur. Rien n'a été modifié.", es: "DSM rechazó la contraseña de administrador. No se ha cambiado nada.", it: "DSM ha rifiutato la password amministratore. Non è stato modificato nulla." },
|
|
401
|
-
"reason.password_required": { en: "Enter
|
|
401
|
+
"reason.password_required": { en: "Enter your user password.", "zh-TW": "請輸入使用者密碼。", "zh-CN": "请输入用户密码。", ja: "ユーザーパスワードを入力してください。", ko: "사용자 비밀번호를 입력하십시오.", de: "Geben Sie das Benutzerpasswort ein.", fr: "Saisissez le mot de passe utilisateur.", es: "Introduzca la contraseña de usuario.", it: "Immettere la password utente." },
|
|
402
402
|
"reason.password_confirm_failed": { en: "DSM could not confirm the administrator password. Nothing was changed.", "zh-TW": "DSM 無法確認管理員密碼,沒有做任何變更。", "zh-CN": "DSM 无法确认管理员密码,没有做任何更改。", ja: "DSM で管理者パスワードを確認できませんでした。何も変更されていません。", ko: "DSM에서 관리자 비밀번호를 확인할 수 없습니다. 변경된 내용은 없습니다.", de: "DSM konnte das Administratorkennwort nicht bestätigen. Es wurde nichts geändert.", fr: "DSM n'a pas pu confirmer le mot de passe administrateur. Rien n'a été modifié.", es: "DSM no pudo confirmar la contraseña de administrador. No se ha cambiado nada.", it: "DSM non ha potuto confermare la password amministratore. Non è stato modificato nulla." },
|
|
403
403
|
"reason.session_ended": { en: "The DSM session ended. Sign in to DSM again, then approve again.", "zh-TW": "DSM 工作階段已結束。請重新登入 DSM 後再核准一次。", "zh-CN": "DSM 会话已结束。请重新登录 DSM 后再批准一次。", ja: "DSM セッションが終了しました。DSM に再度サインインしてから、もう一度承認してください。", ko: "DSM 세션이 종료되었습니다. DSM에 다시 로그인한 후 다시 승인하십시오.", de: "Die DSM-Sitzung ist abgelaufen. Melden Sie sich erneut bei DSM an und genehmigen Sie dann erneut.", fr: "La session DSM a expiré. Reconnectez-vous à DSM, puis approuvez de nouveau.", es: "La sesión de DSM ha finalizado. Vuelva a iniciar sesión en DSM y apruebe de nuevo.", it: "La sessione DSM è terminata. Accedere di nuovo a DSM, quindi approvare di nuovo." },
|
|
404
404
|
"reason.admin_required": { en: "Only a DSM administrator can approve.", "zh-TW": "只有 DSM 管理員可以核准。", "zh-CN": "只有 DSM 管理员可以批准。", ja: "承認できるのは DSM 管理者のみです。", ko: "DSM 관리자만 승인할 수 있습니다.", de: "Nur ein DSM-Administrator kann genehmigen.", fr: "Seul un administrateur DSM peut approuver.", es: "Solo un administrador de DSM puede aprobar.", it: "Solo un amministratore DSM può approvare." },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synopackageland/cli",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.3",
|
|
4
4
|
"description": "Syno Package Land Developer Kit CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@napi-rs/keyring": "^2.1.1",
|
|
30
|
-
"@synopackageland/templates": "0.17.
|
|
30
|
+
"@synopackageland/templates": "0.17.5",
|
|
31
31
|
"ajv": "^8.17.1",
|
|
32
32
|
"commander": "^13.1.0",
|
|
33
33
|
"json-canonicalize": "^3.0.1",
|
package/skills/SKILL.md
CHANGED
|
@@ -7,7 +7,7 @@ description: Initialize, extend, check, build, inspect, and deploy Synology appl
|
|
|
7
7
|
|
|
8
8
|
Use this guide to initialize, build and inspect own applications or upstream OSS as independent packages. 依已實作能力區分 DSM session 檔案、私有 jobs 與 App 登入;delegate 已實作並隨 CLI 提供固定操作的離線委託(預設 `files.moveFromStaging`);共用 delegate/rootOps executor 的完整裝置生命週期驗收仍待完成,不得宣稱已通過;支援邊界依 delegate guide/support matrix,禁止發明新的身分平台。
|
|
9
9
|
|
|
10
|
-
For an existing open-source App, first read [reference/upstream-fork.md](reference/upstream-fork.md): upstream fork/history + untouched upstream files + all packaging in `synology/`, official container images pinned by tag/index digest, native official release binaries pinned by SHA-256 or a source build hook, and a single tag-merge upgrade command. Use `init --upstream-fork`; never rewrite the App as a component. Integrated upstream Apps require direct DSM administrator entry without a separate App password or an OIDC/SSO server: supported trusted headers first, disabling native login second; the shipped OpenList pattern uses the existing SDK 0.17.
|
|
10
|
+
For an existing open-source App, first read [reference/upstream-fork.md](reference/upstream-fork.md): upstream fork/history + untouched upstream files + all packaging in `synology/`, official container images pinned by tag/index digest, native official release binaries pinned by SHA-256 or a source build hook, and a single tag-merge upgrade command. Use `init --upstream-fork`; never rewrite the App as a component. Integrated upstream Apps require direct DSM administrator entry without a separate App password or an OIDC/SSO server: supported trusted headers first, disabling native login second; the shipped OpenList pattern uses the existing SDK 0.17.3 token adapter (`mode: token`, `access: dsm-admins`, `entry: admin-only`) with server-side Authorization injection. All DSM admins share one upstream admin; token reset requires package restart; WebDAV retains its native credentials.
|
|
11
11
|
|
|
12
12
|
Start with `synopkgland init -t native-go`, `synopkgland init -t binary`, or `synopkgland init -t compose`. Read reference/create.md or reference/wrap.md, then reference/deploy.md. Native CGI session checks belong to the package. For wrapping upstream OSS with DSM accounts, read [reference/identity-gateway.md](reference/identity-gateway.md) first. For all Compose work, read [reference/compose.md](reference/compose.md): schema-2 upstream files, generated override, SDK planner, fixed package identity and current DSM blockers. Containers do not inherit a signed-in user's File Station ACL. Existing Shared Folder mounts are blocked until official protected ACL/project control is verified.
|
|
13
13
|
|
|
@@ -23,7 +23,7 @@ compose:
|
|
|
23
23
|
network: {egress: isolated}
|
|
24
24
|
# Private package binds are rejected by DSM build; keep compatible upstream named volumes.
|
|
25
25
|
identity_gateway:
|
|
26
|
-
sdk: 0.17.
|
|
26
|
+
sdk: 0.17.3
|
|
27
27
|
mode: none
|
|
28
28
|
access: dsm-users
|
|
29
29
|
listen: {http: 28000}
|
|
@@ -151,7 +151,7 @@ declared availability readiness, LAN isolation/egress, protected grant lifecycle
|
|
|
151
151
|
ACLs, two-user visibility and clean install/upgrade/reboot/stop/uninstall before
|
|
152
152
|
calling the package supported on a NAS. No NAS is accessed by the build gate.
|
|
153
153
|
|
|
154
|
-
The unified Compose contract uses SDK 0.17.
|
|
154
|
+
The unified Compose contract uses SDK 0.17.3 and templates 0.17.5 with CLI 0.17.3. Use the published, matching versions together; the legacy packaging route and bridge publish mode are removed.
|
|
155
155
|
|
|
156
156
|
Primary override files, and each included override set, must share a directory. Cross-directory override bases are rejected before loader I/O. Included implicit .env files are confined, inventoried and preserved; symlinks are rejected.
|
|
157
157
|
|
|
@@ -40,8 +40,8 @@ rootOps 與 delegate 已共用管理員 PasswordConfirm 核准的 protected exec
|
|
|
40
40
|
backend 寫 `runtime: python|node|rust`(`runtime: go` 等同 `kind: go`)。CGI 是 SDK 的 Go runtime(`bridge/cmd/runtime`),它驗證 DSM session、entry 與 `permissions.json` 後,以套件帳號(不是 root)每個請求啟動一次 App。App 放在 ui 以外的目錄,打包成 `target/app/`,build 寫入 `bridge.json`(spec/bridge/v1)並把它與 `permissions.json` 的 sha256 編進 runtime。
|
|
41
41
|
|
|
42
42
|
```yaml
|
|
43
|
-
backend: {runtime: python, dir: app, entry: main.py, sdk: 0.17.
|
|
44
|
-
backend: {runtime: node, dir: app, entry: main.mjs, sdk: 0.17.
|
|
43
|
+
backend: {runtime: python, dir: app, entry: main.py, sdk: 0.17.3}
|
|
44
|
+
backend: {runtime: node, dir: app, entry: main.mjs, sdk: 0.17.3, node: {package: Node.js_v20}}
|
|
45
45
|
backend: {runtime: rust, dir: app, entry: hello, methods: [hello.greet]}
|
|
46
46
|
```
|
|
47
47
|
|
|
@@ -104,7 +104,7 @@ upstream mechanisms in order:
|
|
|
104
104
|
If manual App login is still necessary, label bootstrap incomplete. Verify
|
|
105
105
|
subsequent DSM entry, restart and upgrade all retain password-free access,
|
|
106
106
|
while anonymous/nonadmin requests and direct upstream ports remain blocked.
|
|
107
|
-
3. **Existing SDK token adapter**: SDK **0.17.
|
|
107
|
+
3. **Existing SDK token adapter**: SDK **0.17.3** supports `mode: token`, with
|
|
108
108
|
`access: dsm-admins` and `entry: admin-only`. OpenList uses its unmodified
|
|
109
109
|
upstream `admin token` CLI while the server is stopped to obtain the native
|
|
110
110
|
administrator API token. The package stores it in a package-private **0600**
|
|
@@ -142,7 +142,7 @@ is undecided. Never copy credentials into generated projects.
|
|
|
142
142
|
|
|
143
143
|
| Prototype | Reusable lesson and remaining boundary |
|
|
144
144
|
| --- | --- |
|
|
145
|
-
| OpenList | Official release binary pinned by SHA-256, `/ping` and SDK 0.17.
|
|
145
|
+
| OpenList | Official release binary pinned by SHA-256, `/ping` and SDK 0.17.3 server-side token adapter; shared upstream admin, restart after token reset, native WebDAV credentials. Share selection does not grant package ACL/register Local storage. |
|
|
146
146
|
| FreshRSS | Official image, package-UID Apache/config adapter in `synology/`, explicit health; supported proxy authentication with fixed admin mapping and header clearing. |
|
|
147
147
|
| Uptime Kuma | Official image, writable-path adapter, nonredirecting health and `disableAuth` after first bootstrap; WebSocket expiry/revocation need separate tests. |
|
|
148
148
|
|