@synopackageland/templates 0.40.1 → 0.40.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 ADDED
@@ -0,0 +1,601 @@
1
+ # Changelog
2
+
3
+ ## 0.40.2
4
+
5
+ - Include independent examples and npm scripts for local unit and registry contracts, local package checks, real-NAS ctl, deterministic UI outcomes and optional AI actions
6
+ - Keep the default test command local and offline; running or writing tests remains optional, and NAS or AI tests run only when the user requests them
7
+ - Require CLI `~0.48.20` for the shared test scaffold and e2e helpers, retain the App-open smoke, and load AI configuration only for the separate AI command
8
+ - Make AI dependencies opt-in and require a configured `E2E_LLM_*` profile for AI steps; use low reasoning effort by default
9
+ - Include release notes in the published package
10
+
11
+ ## 0.40.0
12
+
13
+ - The Vue App follows the SDK's page layout: it passes no shell-wide `description` (it only reached the App root as a stray attribute), and the Vue READMEs describe the page bar that holds `#actions` and content-only scrolling. A settings page needs no CSS to pass the height through `.integration-app > [data-page]`.
14
+ - Pin SDK/App 0.50.0 and UI 0.20.0, including Go sums, Rust tag locks and the Vue frontend lockfile
15
+
16
+ ## 0.39.2
17
+
18
+ - Require Go 1.26.10 in native Go scaffolds and align toolchain fixture checks (#56)
19
+ - Pin SDK/App 0.47.1 and UI 0.19.5, including Go sums, Rust tag locks and the Vue frontend lockfile
20
+
21
+ ## 0.39.1
22
+
23
+ - Remove unused loading and greeting catalog entries from the nine plain native App locales and their glossary mappings.
24
+
25
+ ## 0.39.0
26
+
27
+ - Scaffold a single synopkgland.api v2 registry for native Apps, with documentation-only AI class examples and generated runtime metadata
28
+ - Remove default greeting handlers and UI calls; keep selected capability declarations in one merged operation source
29
+ - Pin SDK/App 0.47.0 across native and Compose templates with regenerated npm, Go and Cargo locks
30
+
31
+ ## 0.38.1
32
+
33
+ - Document opt-in custom identity gateway ingress paths, install-time ownership checks and the unsupported origin root.
34
+ - Preserve the default package namespace and existing template SDK pins; custom ingress explicitly requires SDK 0.44.0.
35
+
36
+ ## 0.38.0
37
+
38
+ - Pin SDK/App 0.43.0 across native and Compose templates, with regenerated npm, Go and Cargo locks.
39
+ - Document fixed DSM path ingress for prefix-aware upstream applications.
40
+ - Keep ingress opt-in and reuse the unchanged executor/v0.39.0 inventory.
41
+
42
+ ## 0.37.0
43
+
44
+ - Pin UI 0.19.1 in the Vue frontend (was 0.16.1): calm default motion, DSM Control Panel settings layout, steady hover hit areas between rows.
45
+ - Pin SDK/App exactly to 0.41.1 across native and Compose templates (SDK 0.41.1 accepts UI `>=0.10.1 <0.20.0`); refresh npm, Go and Cargo locks.
46
+ - Reuse the immutable executor/v0.39.0 inventory declared by SDK 0.41.1.
47
+ - Keep the delegate status error Callout in view (`:dismissible="false"`): its Retry is the only way back, and UI 0.17 made Callouts closable by default.
48
+
49
+ ## 0.36.0
50
+
51
+ - Pin SDK/App exactly to 0.40.0 across native and Compose templates; refresh npm, Go and Cargo locks.
52
+ - Reuse the immutable executor/v0.39.0 inventory declared by SDK 0.40.0.
53
+ - Document shared native recovery for failures before and after initial startup.
54
+ - Confine native-go job inputs to an authenticated name-and-UID producer inbox.
55
+ - Scope report staging and job IDs to owner and grant in Node, Python and Rust.
56
+ - Remove newly created reports on definitive delegation refusal; retain uncertain saves for retry.
57
+
58
+
59
+ ## 0.35.5
60
+
61
+ - Include the shared CLI administrator, normal-user and anonymous app-open smoke, config and npm script in every generated project.
62
+
63
+ ## 0.35.4
64
+
65
+ - Align the release guide with the current CLI and SDK executor manifest
66
+
67
+ ## 0.35.2 (2026-10-29)
68
+
69
+ - Pin SDK/App 0.38.2, republished with clean registry metadata.
70
+
71
+ ## 0.35.1 (2026-10-29)
72
+
73
+ - Pin SDK/App 0.38.0 across native backends, Vue and Compose, with matching locks.
74
+ - Document 300-second requests, 302-second browser waits and the existing
75
+ independent-worker admission/progress/status pattern. Preserve original IDs
76
+ and idempotency keys after lost replies, explicit budgets, approved executor
77
+ policy and ctl's separate 62-second transport default.
78
+
79
+ ## 0.35.0 (2026-10-29)
80
+
81
+ - Pin SDK/App 0.37.0 for all native backends and Compose. Use CLI 0.40.0,
82
+ which can run the App backend as the package daemon (`daemon.backend`).
83
+ The executor 0.32.0 payload inventory is unchanged; UI stays at 0.16.1.
84
+
85
+ ## 0.34.0 (2026-10-29)
86
+
87
+ - Pin SDK/App 0.36.0 for all native backends and Compose. Use CLI 0.38.0.
88
+ Executor/root operations retain the 0.32.0 payload inventory; optional peer
89
+ helpers use the protected executor boundary and explicit admission shutdown.
90
+
91
+ ## 0.33.0 (2026-10-29)
92
+
93
+ - Pin SDK/App 0.35.0 across native and Compose scaffolds; use CLI 0.37.0 and
94
+ retain UI 0.16.1.
95
+ - Rebuilt native Apps gain a fixed `scripts/backup/` shim that Hyper Backup
96
+ runs as root. The App itself still runs as the package user, and its
97
+ privilege tier is unchanged. Opt out with `backup: { hyper_backup: false }`.
98
+ - Native templates (Go, Node, Python, Rust and binary) explain Hyper Backup
99
+ application backup in `dsm-package.yaml`: with a matching CLI and SDK the
100
+ App appears in Hyper Backup by default, with offline mode, data version,
101
+ hook and opt-out shown as comments. Compose explains that its volumes are
102
+ not covered. A test keeps every native template on by default and checks
103
+ that no template ships backup scripts.
104
+
105
+ ## 0.32.1 (2026-10-29)
106
+
107
+ - Explain SDK 0.33.0 / CLI 0.35.0 HTTP route and private IPC boundaries in
108
+ generated App guidance. Preserve scaffold dependency pins and runtime files.
109
+
110
+ ## 0.32.0 (2026-10-29)
111
+
112
+ - Pin SDK/App 0.32.0 across native and Compose scaffolds; use CLI 0.34.0 and
113
+ retain UI 0.16.1. Rebuilt Apps with protected executors require fresh
114
+ administrator approval for executor/v0.32.0.
115
+ - Build Vue frontends as `app.module.js` ES modules with relative lazy chunks.
116
+ CLI 0.34.0 snapshots the complete UI tree and verifies it during inspect.
117
+ Each DSM window keeps its own mount/cleanup; reload an open page after an
118
+ upgrade if an old lazy chunk is unavailable.
119
+ - Require an explicit permissions-table entry for every App method. Dynamic
120
+ names and custom HTTP dispatchers are rejected; use fixed SDK routes and
121
+ `identity_gateway.upstream_auth_paths` for upstream-authenticated client APIs.
122
+ No device acceptance or Rust crate publication is claimed.
123
+
124
+ ## 0.31.5 (2026-10-28)
125
+
126
+ - Pin SDK/App 0.31.5 across Go, Python, Node.js, Rust and Compose scaffolds and refresh registry lockfiles; retain UI 0.16.1 (SDK 0.31.5 accepts UI `>=0.10.1 <0.18.0`)
127
+ - Vue scaffolds inherit the SDK's upgrade notice: with CLI 0.33.2 or later, `AppShell` offers **Reload** when an upgrade replaced the UI an open page loaded. CLI 0.33.2 still depends on templates `~0.31.0`
128
+
129
+ ## 0.31.2 (2026-10-25)
130
+
131
+ - Pin SDK/App 0.31.2 across Go, Python, Node.js, Rust and Compose scaffolds and refresh registry lockfiles; retain UI 0.16.1 and CLI 0.31.0
132
+ - The page shown when an App can't be opened from the DSM menu is redesigned and now explains when the App's port isn't reachable from outside
133
+
134
+ ## 0.31.1 (2026-10-25)
135
+
136
+ - Pin SDK/App 0.31.1 across Go, Python, Node.js, Rust and Compose scaffolds and UI 0.16.1 in the shared Vue frontend; refresh registry lockfiles. SDK 0.31.1 accepts UI `>=0.10.1 <0.17.0`.
137
+ - The templates do not use Wizard; no call-site migration is required for its redesigned layout.
138
+
139
+ ## 0.31.0 (2026-10-25)
140
+
141
+ - Pin SDK/App 0.31.0 across Go, Python, Node.js, Rust and Compose scaffolds; use CLI 0.31.0. Keep UI 0.14.10. Rebuilt Apps require administrator approval for changed executor payloads.
142
+
143
+ - native-go: `bg.jobs.submit` no longer accepts an input inside the job spool (`<data>/background`).
144
+
145
+ ## 0.30.0 (2026-10-24)
146
+
147
+ - Pin SDK/App 0.30.0 and use CLI 0.30.0 for external-access single-origin Apps, provider-aware DSM menu launches, reachability probes and HTTPS manual origins with explicit ports for single-origin Apps.
148
+ - Keep UI 0.14.10 and immutable executor/v0.27.0; App releases and NAS acceptance remain separate.
149
+
150
+ ## 0.29.0 (2026-10-24)
151
+
152
+ - Pin SDK/App 0.29.0 across Go, Python, Node.js, Rust and Compose scaffolds, retaining UI 0.14.10. New projects inherit SDK 0.29.0 external-access support: the `external-origin` setting type, external sign-in resume and Compose origin snapshots
153
+ - SDK 0.29.0 reuses executor/v0.27.0; use CLI 0.29.0, which depends on templates `~0.29.0`. No template mechanism, App option or NAS acceptance is added
154
+
155
+ ## 0.28.0 (2026-10-24)
156
+
157
+ - Pin SDK/App 0.28.0 across Go, Python, Node.js, Rust and Compose scaffolds, retaining UI 0.14.10. New Compose projects inherit the SDK's slow-NAS startup defaults: generous health and readiness timing, `/_spl/ping` gateway liveness and a Starting status while the App comes up
158
+ - SDK 0.28.0 reuses executor/v0.27.0; use CLI 0.28.0, which depends on templates `~0.28.0`. No template mechanism, App option or NAS acceptance is added
159
+
160
+ ## 0.27.1 (2026-10-23)
161
+
162
+ - Remove the NAS file hashing example, disabled-example notice and translations from every native runtime and both UI shells
163
+ - Keep job submission for App-owned imported files, progress, cancellation, pause/resume and existing private-copy schedules; remove the NAS browse adapter and session-read test fixtures
164
+ - Retain SDK/App 0.27.0 and UI 0.14.9 pins; CLI 0.27.0 resolves this templates patch through its existing `~0.27.0` dependency
165
+
166
+ ## 0.27.0 (2026-10-23)
167
+
168
+ - Build on templates 0.26.5, retaining UI 0.14.9 and SDK/App 0.27.0 pins across all runtimes. Use CLI 0.27.0 with executor/v0.27.0 and normal administrator approval.
169
+ - Explicitly disable the NAS hashing example and show an unavailable notice. Keep workers and job-control APIs; defer browser-owned input migration instead of relaying DSM sessions from a backend. No SDK API or special option is added.
170
+ - Keep existing toolchain and template mechanisms. No NAS/App upgrade certification or Rust crate publication is claimed.
171
+
172
+ ## 0.26.5 (2026-10-23)
173
+
174
+ - Pin UI 0.14.9 in the shared Vue frontend used by Go, Python, Node.js and Rust scaffolds. This fixes short Link labels wrapping one character per line and retains the DSM 7 appearance refinements from UI 0.14.8.
175
+ - Align native and Compose SDK/App pins with npm latest 0.27.0 and refresh the frontend lockfile against published npm integrity. CLI latest remains 0.26.0; it lacks SDK 0.27.0 executor digests and cannot build the protected executor scaffolds until a compatible CLI is released. SDK 0.27.0 moves interactive NAS file operations to the browser and introduces executor/v0.27.0; rebuilt protected executors follow normal administrator approval. Custom server-side file handlers require migration; no NAS acceptance is claimed.
176
+
177
+ ## 0.26.4 (2026-10-23)
178
+
179
+ - Pin UI 0.14.8 in the shared Vue frontend used by Go, Python, Node.js and Rust scaffolds. This refreshes the DSM 7 default appearance with layered backgrounds, softer card borders and shadows, token-based corner radii and three dark-mode surface levels; component APIs are unchanged.
180
+ - Refresh the frontend lockfile against the published npm integrity; retain SDK/App 0.26.0 and CLI 0.26.0 compatibility.
181
+
182
+ ## 0.26.3 (2026-10-23)
183
+
184
+ - Pin UI 0.14.7 in the shared Vue frontend used by Go, Python, Node.js and Rust scaffolds. UI 0.14.7 adds the DSM button policy: `SettingsSection` / `Card` footer buttons become tool buttons and `Notification` actions become footer capsules; the template pages use neither, so they render as before. Refresh the frontend lockfile against the published npm integrity; retain SDK/App 0.26.0 compatibility.
185
+
186
+ ## 0.26.2 (2026-10-23)
187
+
188
+ - Pin UI 0.14.6 in the shared Vue frontend used by Go, Python, Node.js and Rust scaffolds, with narrow navigation, explicit table widths, ordered-list numbering and disabled description fixes. Refresh the frontend lockfile against the published npm integrity; retain SDK/App 0.26.0 compatibility.
189
+ - Remove terminal sentence periods from all nine template UI locales and DSM glossary entries, preserving internal punctuation and ellipses. Add a catalog check and compare upstream SDK wording with the same UI punctuation convention.
190
+
191
+ ## 0.26.1 (2026-10-23)
192
+
193
+ - Pin UI 0.14.5 in the shared Vue frontend used by Go, Python, Node.js and Rust scaffolds. This includes the iPhone Safari DSM Portal viewport resize fix.
194
+ - Refresh the frontend lockfile and layout check; retain SDK/App 0.26.0 and CLI 0.26.0 compatibility.
195
+
196
+ ## 0.26.0 (2026-10-22)
197
+
198
+ - Pin SDK/App 0.26.0 across native and Compose templates, with native Rust pinned to the public v0.26.0 tag commit. Retain UI 0.14.3 and Go 1.26.10.
199
+ - Document optional bounded native daemon restart policies; use CLI 0.26.0 for `daemon.restart` and native gateway Apps with `ui: false`. Shared-folder preflight and permission guidance come from SDK 0.26.0.
200
+ - Reuse executor/v0.24.0 with unchanged executor payloads. Approval retention still requires matching policy, protected programs and task definitions. No NAS acceptance is claimed.
201
+
202
+ ## 0.25.1 (2026-10-22)
203
+
204
+ - Pin the native Rust SDK 0.25.0 dependency to its public repository commit. Go module checksums and executor/lifecycle payloads are unchanged.
205
+ - Document anonymous access to the public SDK source for template development.
206
+
207
+ ## 0.25.0 (2026-10-22)
208
+
209
+ - Add the opt-in native UI plus administrator-only DSM console example for the CLI `console` declaration.
210
+ - Pin SDK/App 0.25.0 and UI 0.14.3 in generated Apps, retaining Go 1.26.10 and the DSM Node.js_v22 dependency for Node Apps.
211
+ - Reuse executor/v0.24.0 with unchanged protected executor/lifecycle payloads. Administrator approval retention still requires matching policy, programs and task definitions. No NAS acceptance is claimed.
212
+
213
+ ## 0.24.0 (2026-10-22)
214
+
215
+ - Pin SDK/App 0.24.0, Go 1.26.10 and UI 0.14.0 in generated Apps. The Go toolchain fixes crypto/x509 GO-2026-6809.
216
+ - Use the official DSM Node.js_v22 package for native-node Apps and Node.js 22 for runtime compatibility tests. Update frontend test containers to Node.js 24.22.1 LTS.
217
+ - Known limitations: native-node requires a model/DSM combination where Package Center offers Node.js_v22; package availability is checked by DSM at install time. Rebuilt executor Apps require administrator reapproval of system access after upgrading. No NAS acceptance is claimed.
218
+
219
+ ## 0.23.0 (2026-10-21)
220
+
221
+ - Pin SDK/App 0.23.0 across Go, Node, Python and Rust templates; retain UI 0.12.5.
222
+ - Support the matching CLI browser redirect declaration and SDK request-origin resolution.
223
+
224
+ ## 0.22.0 (2026-10-21)
225
+
226
+ - Pin SDK/App 0.22.0 across native and Compose templates; pin published UI 0.12.5.
227
+ - Use CLI 0.22.0 for provider-only public upstream access, host UDP listeners, fixed launch paths and installation settings.
228
+ - Resolve the unchanged helper from executor/v0.20.0.
229
+
230
+ ## 0.21.1 (2026-10-21)
231
+
232
+ - Pin SDK/App 0.21.1 across native and Compose templates and UI 0.13.1 for the updated AppShell layout and navigation.
233
+ - Use CLI 0.21.1 to resolve the unchanged executor from executor/v0.20.0.
234
+
235
+ ## 0.21.0 (2026-10-21)
236
+
237
+ - Pin SDK/App 0.21.0 across Go, Python, Node, Rust and Compose templates; retain published UI 0.12.5.
238
+ - Use CLI 0.21.0 for optional Compose Intel GPU declarations and software fallback.
239
+
240
+ ## 0.20.0 (2026-10-21)
241
+
242
+ - Pin SDK/App 0.20.0 across Go, Python, Node, Rust and Compose templates; retain published UI 0.12.5.
243
+ - Keep shared-folder selection and host health readiness on the common SDK runtime.
244
+
245
+ ## 0.19.0 (2026-10-20)
246
+
247
+ - Pin SDK/App 0.19.0 across Go, Python, Node, Rust and Compose templates; retain published UI 0.12.5.
248
+ - Use the SDK's bounded nonroot OIDC runtime configuration and listener host-port support when declared by an App.
249
+ - Executor Apps rebuilt with this SDK require one administrator reapproval after upgrading.
250
+
251
+ ## 0.18.0 (2026-10-20)
252
+
253
+ - Pin Go, Rust, Python, Node, Compose and Vue SDK/App sources to 0.18.0 for the native OIDC browser bridge and App launch resume flow.
254
+ - Pin UI 0.12.5 and refresh dependency locks and third-party notices.
255
+
256
+ ## 0.17.10 (2026-10-20)
257
+
258
+ - Align the shared-folder status fixture with the SDK authenticated route policy.
259
+
260
+ ## 0.17.9 (2026-10-20)
261
+
262
+ - Pin SDK/App 0.17.7 for the executor administrator-role fix.
263
+
264
+ ## 0.17.8 (2026-10-20)
265
+
266
+ - Pin UI 0.12.4 for compact full-page layouts without an outer card; retain SDK/App 0.17.5 and refresh the frontend dependency lock.
267
+
268
+ ## 0.17.7 (2026-10-20)
269
+
270
+ - Pin SDK/App, Go and Rust sources to 0.17.5 for shared timeout budgets, native DSM HTTPS ingress and retained Compose data volume reporting. Keep UI at 0.12.3 and refresh matching dependency locks.
271
+ - Apps rebuilt with SDK 0.17.5 require administrator reapproval of existing executor approvals after upgrade.
272
+
273
+ ## 0.17.6 (2026-10-19)
274
+
275
+ - Pin SDK/App, Go and Rust sources to 0.17.4 so generated Apps include the declared container startup budget and image-pull diagnostics; keep UI at 0.12.3. Refresh matching dependency locks.
276
+
277
+ ## 0.17.5 (2026-10-19)
278
+
279
+ - Pin all SDK/App and native SDK sources to 0.17.3, including generated runtime version identifiers; keep UI at 0.12.3. Refresh all corresponding lockfiles.
280
+
281
+ ## 0.17.4 (2026-10-19)
282
+
283
+ - Pin SDK/App and native SDK sources to 0.17.2, and UI to 0.12.3; refresh matching lockfiles.
284
+
285
+ - Use “User password” in the Vue approval documentation and executor gate test description.
286
+
287
+ ## 0.17.1 (2026-10-19)
288
+
289
+ - Correct the Vue frontend lockfile SDK 0.17.0 integrity. Templates 0.17.0 retained the SDK 0.16.0 checksum and must not be used; select 0.17.1.
290
+ - Verify release tarball integrity before dependency overrides and verify installed frontend versions, so a warm npm cache cannot hide a stale lockfile. SDK/App stay at 0.17.0 and UI at 0.12.1.
291
+
292
+ ## 0.17.0 (2026-10-19)
293
+
294
+ - Update authoring guidance for Portal without an executor on DSM 7.2-64570+, with DSM managing nginx reload through INFO.
295
+
296
+ - Pin SDK/App 0.17.0 and UI 0.12.1; show the shell during initial reads and load administrator status and greeting concurrently.
297
+
298
+ - Batch independent administrator startup reads through the generated SDK client while keeping the App shell visible and per-method errors independent.
299
+
300
+ ## 0.16.0 (2026-10-19)
301
+
302
+ - Pin Go, Node, Python, Rust and Vue SDKs to 0.16.0; keep UI at 0.12.0.
303
+ - Use shared generic content checks plus an optional external denylist; scanner tooling stays outside published templates.
304
+
305
+ - native-go: `sharedfolder.status` operation and `SharedFolderPath`/`StorageAdapter` wiring on the SDK `sharedfolder` package replace the template's own shared-folder reader; `app.status` no longer carries `shared_folders`.
306
+ - native-go-vue: `SharedFolderSettings` section (per-folder state, grant, Control Panel guidance). Needs an SDK release that contains the `sharedfolder` capability; the SDK pin moves with that release.
307
+
308
+ 繁中摘要:native-go 以 SDK sharedfolder 套件提供 `sharedfolder.status`,取代自有讀取,`app.status` 不再含 shared_folders;native-go-vue 加入 SharedFolderSettings。需待含此能力的 SDK 發版後調整 pin。
309
+
310
+ ## 0.15.2 (2026-10-18)
311
+
312
+ - Pin SDK 0.15.2 across Go, Node, Python, Rust and Vue, and UI 0.12.0 in the shared Vue frontend; remove the SDK 0.15.1 UI peer override now that SDK 0.15.2 accepts UI 0.12.x.
313
+ - Use UI typography/color tokens and concise nine-locale copy in Vue, plain and binary frontends; show package, user and version as separate status rows (TMP-1).
314
+ - Executor and lifecycle digests match SDK 0.15.1 on all three architectures. Upgrading from 0.15.1 adds no administrator reapproval requirement; upgrades from 0.15.0 retain the one-time approval introduced in 0.15.1.
315
+
316
+ 繁中摘要:所有 SDK pins 同步 0.15.2,共用 Vue 前端固定 UI 0.12.0,移除舊 SDK peer override。Vue/plain/binary 對齊 UI token,精簡九語系文字,套件/使用者/版本分列。三架構 executor/lifecycle digest 與 0.15.1 相同,從 0.15.1 升級不新增重新核准要求;從 0.15.0 升級仍需完成一次管理員核准。
317
+
318
+ ## 0.15.1 (2026-10-18)
319
+
320
+ - Pin Go, Node, Python, Rust and Vue SDKs to 0.15.1 for package-named control refusal logs and rejected runtime staging cleanup.
321
+ - Apps rebuilt with the new SDK require one administrator reapproval after upgrade because executor task definitions change.
322
+
323
+ 繁中摘要:所有 SDK pins 同步 0.15.1,帶入 control.sh 拒絕時的套件名 log 與 `.executor`/`.policy.json` 清除。**task 定義改變:App 重建升級後,管理員需重新核准一次。**
324
+
325
+ ## 0.15.0 (2026-10-18)
326
+
327
+ - Pin all SDK runtimes and Vue frontend to 0.15.0; keep API description v1 and explicit ctl command examples in all four native runtimes.
328
+ - Breaking: the Compose scaffold uses only schema 2 and the shared planner's dedicated no-publish ingress. Declare ordered `compose.files`, `compose.web` container port/health and `identity_gateway.sdk: 0.15.0`; remove legacy integration Compose/gateway declarations and do not add host port publications. Rebuild using CLI 0.15.0 and validate the actual NAS install/upgrade. Existing `.sc` residue is not automatically removed; changing ingress candidate requires a clean installation.
329
+
330
+ 繁中摘要:所有語言及 Vue frontend 固定 SDK 0.15.0,包含 API 描述 v1/ctl command 範例。**不相容變更**:Compose 只保留 schema 2 統一路線,使用不 publish port 的 ingress;舊專案須改寫 `compose.files`、`compose.web` 與 `identity_gateway` 並以 CLI 0.15.0 重建。舊 `.sc` 殘留不自動清除,不自動遷移既有子網。
331
+
332
+ ## 0.14.1
333
+
334
+ - 修正 web launcher 的文件:無 SDK class 的 schema 1 使用 url;schema 2 SDK wrapper 使用 standalone。
335
+
336
+ ## 0.14.0
337
+
338
+ - 非 UI SDK 前端明確使用 ui.launch: new-page;UI SDK scaffold 使用 dsm-window。Portal 僅明確 opt-in。SDK pins 更新為 0.14.0。
339
+
340
+ ## 0.13.1 (2026-10-17)
341
+
342
+ - Pin SDK 0.13.1 across all languages and UI 0.11.0 in the Vue frontend.
343
+
344
+ 繁中摘要:各語言模板同步 SDK 0.13.1,Vue frontend 固定 UI 0.11.0。
345
+
346
+ ## 0.13.0 (2026-10-17)
347
+
348
+ Generated Apps pin SDK 0.13.0 across Go, Rust, Python/Node and Vue, and UI 0.10.5. The SDK includes the package-local identity gateway and account status/purge and delete synchronization; these remain explicit consumer opt-ins. UI choices have 18 px boxes, a 9 px text gap and 28 px vertical rows; horizontal RadioGroup spacing is 34 px.
349
+
350
+ 繁中摘要:Go、Rust、Python/Node 與 Vue 的 SDK pin 同步 0.13.0,UI pin 更新至 0.10.5。SDK 包含每包自帶的身分閘道、帳號狀態/purge 與刪除同步,由 App 明確啟用;模板不預設增加授權。UI 選項框 18px、文字間距 9px、直向列距 28px、橫向 RadioGroup 間距 34px。
351
+
352
+ ## 0.12.2 (2026-10-16)
353
+
354
+ Generated Apps pin SDK 0.12.2 across Go, Rust, Python/Node and Vue, and UI 0.10.3. SDK 0.12.2 types the DSM launch parameters CLI 0.12.2 forwards (`ctx.launchParams`, `ctx.onLaunch`) and adds `followLaunchRoute`; templates add no launch handling by default.
355
+
356
+ 繁中摘要:Go、Rust、Python/Node 與 Vue 的 SDK pin 更新至 0.12.2,UI pin 更新至 0.10.3。SDK 0.12.2 提供 CLI 0.12.2 轉來的 DSM 啟動參數型別(`ctx.launchParams`、`ctx.onLaunch`)與 `followLaunchRoute`;templates 預設不處理啟動參數。
357
+
358
+ ## 0.12.0 (2026-10-16)
359
+
360
+ Generated Apps pin SDK 0.12.0 across Go, Rust, Python/Node and Vue, and UI 0.10.1. The Vue App leaves its section and page spacing to the UI section gap: the App root and each page stack their children with `--ui-section-gap`, with no hand-written margins. SDK dialogs size to their content.
361
+
362
+ 繁中摘要:Go、Rust、Python/Node 與 Vue 的 SDK pin 更新至 0.12.0,UI pin 更新至 0.10.1。Vue App 的頁面與區塊間距改由 UI section gap 決定,App 根節點與各頁以 `--ui-section-gap` 排列子元素,不再自訂外距;SDK 對話框改依內容決定寬度。
363
+
364
+ ## 0.11.0 (2026-10-16)
365
+
366
+ Generated Apps pin SDK 0.11.0 across Go, Rust, Python/Node and Vue. UI stays at 0.9.10. The SDK adds profile-scoped JSON WebAPI delegation; Apps opt in explicitly through CLI 0.11.0 capabilities.webapi. Existing templates add no profile or grant by default.
367
+
368
+ 繁中摘要:Go、Rust、Python/Node 與 Vue 的 SDK pin 更新至 0.11.0,UI 保持 0.9.10;WebAPI profile 由 App 透過 CLI 0.11.0 明確宣告,模板不預設啟用授權。
369
+
370
+ ## 0.10.13 (2026-10-15)
371
+
372
+ Generated Apps pin SDK 0.10.12 and UI 0.9.10 across the Go module, Rust crate tag, Python/Node backend.sdk and Vue frontend. Template runtime behavior is unchanged.
373
+
374
+ 繁中摘要:更新 SDK pin 至 0.10.12、UI pin 至 0.9.10 與相應 lock/檢查;模板執行程式不變。
375
+
376
+ ## 0.10.12 (2026-10-15)
377
+
378
+ Generated Apps pin SDK 0.10.11 across the Go module, Rust crate tag, Python/Node backend.sdk and Vue frontend. UI remains pinned to 0.9.9. Template runtime behavior is unchanged.
379
+
380
+ 繁中摘要:僅更新 SDK pin 至 0.10.11 與相應 lock/檢查;UI 保持 0.9.9,模板執行程式不變。
381
+
382
+ ## 0.10.11 (2026-10-15)
383
+
384
+ Generated Apps pin SDK 0.10.10 and UI 0.9.9 across the Go module, Rust crate tag, Python/Node backend.sdk and Vue frontend. This release updates dependency pins and their checks, including consent-copy and save-history assertions for the current SDK; template runtime behavior is unchanged.
385
+
386
+ 繁中摘要:產生的 App 在 Go、Rust、Python/Node backend.sdk 與 Vue frontend 釘選 SDK 0.10.10、UI 0.9.9;本版更新依賴 pin 與相應檢查(含目前 SDK 的核准文案及無存檔紀錄的斷言),模板執行程式不變。
387
+
388
+ ## 0.10.10 (2026-10-15)
389
+
390
+ Generated Apps require SDK 0.10.9 and UI 0.9.8. SDK 0.10.9 fixes 0.10.8's
391
+ `ExecutorApproval`, which showed its loading text beside the pages forever
392
+ when no executor setup was provided. Its executor and lifecycle digests equal
393
+ 0.10.8: an App approved on templates 0.10.9 keeps its approval; one upgraded
394
+ from 0.10.8 or earlier templates is approved once more (see 0.10.9).
395
+ Everything listed under 0.10.9 applies; use 0.10.10 instead of 0.10.9.
396
+
397
+ 繁中摘要:產生的 App 需要 SDK 0.10.9(修正 0.10.8 沒有 executor setup 時「載入中」不消失)與
398
+ UI 0.9.8。executor digest 與 0.10.8 相同;自 templates 0.10.8 以前升級的 App 仍要重新核准一次。
399
+ 0.10.9 的內容全部適用,請改用 0.10.10。
400
+
401
+ ## 0.10.9 (2026-10-15)
402
+
403
+ Generated Apps require SDK 0.10.8 (Go module, Rust crate tag, `backend.sdk`
404
+ and `@synopackageland/sdk`) and the Vue frontend UI 0.9.8. **SDK 0.10.8's
405
+ executor digests change: an installed App rebuilt from these templates is
406
+ approved once more by an administrator after the upgrade.** Its executor
407
+ reports its own task readback (`tasks`), so a DSM window from CLI 0.10.9
408
+ shows an administrator the App without reading the scheduler again.
409
+
410
+ - The root-ops `ExecutorGate.vue` passes `preload` to `ExecutorApproval`: the
411
+ App's pages mount hidden and inert while the executor's first status is
412
+ read, so their own reads run alongside it, and a ready status shows that
413
+ same instance; any other status discards it. The templates open no dialog
414
+ on mount; an App that does should wait until `useExecutorPreload()` is
415
+ false.
416
+
417
+ 繁中摘要:產生的 App 需要 SDK 0.10.8 與 UI 0.9.8。SDK 0.10.8 的 executor digest 改變,
418
+ 重建並升級後要由管理員重新核准一次。root-ops 的 `ExecutorGate.vue` 預設加上 `preload`:
419
+ 核對期間頁面先隱藏掛載並預讀資料,通過才顯示。App 若在掛載時自動開對話框,要等
420
+ `useExecutorPreload()` 為 false。
421
+
422
+ ## 0.10.8 (2026-10-15)
423
+
424
+ Generated Apps require SDK 0.10.7 (Go module, Rust crate tag, `backend.sdk`
425
+ and `@synopackageland/sdk`) and the Vue frontend UI 0.9.8. SDK 0.10.7's
426
+ executor and lifecycle digests equal 0.10.6, so an App rebuilt from these
427
+ templates keeps its approval unless its executor or policy changes. The
428
+ templates' own code did not change: SDK 0.10.7's panels wait out a stopped or
429
+ starting package on their own, and a refused action reads as the SDK's action
430
+ text (`lifecycleRefusal`). Templates 0.10.7 is the last release on SDK 0.10.6.
431
+
432
+ 繁中摘要:產生的 App 需要 SDK 0.10.7 與 UI 0.9.8。SDK 0.10.7 的 executor/lifecycle digest
433
+ 與 0.10.6 相同,重建的 App 不需重新核准(除非 executor 或 policy 改變)。範本自身程式未改;
434
+ SDK 0.10.7 的面板在套件停止/啟動中時會自行等待重試,動作被拒時顯示 `lifecycleRefusal` 文案。
435
+
436
+ ## 0.10.7 (2026-10-15)
437
+
438
+ 0.10.6 was tagged but never published to npm: its delegate template's
439
+ frontend test expected SDK placeholder rows while `CapabilityPanels` draws its
440
+ own `SectionSkeleton` as it detects the mode, so the test failed. 0.10.7 is
441
+ 0.10.6 with that test as in 0.10.5; everything listed under 0.10.6 applies.
442
+ Generated Apps require SDK 0.10.6 and UI 0.9.8.
443
+
444
+ 繁中摘要:0.10.6 已打 tag 但未發佈到 npm(delegate 範本的前端測試錯誤預期 SDK 佔位列,
445
+ `CapabilityPanels` 偵測模式時畫的是自己的 `SectionSkeleton`)。0.10.7 即 0.10.6 加上還原的測試;
446
+ 0.10.6 列出的內容全部適用。產生的 App 需要 SDK 0.10.6 與 UI 0.9.8。
447
+
448
+ ## 0.10.6 (2026-10-15)
449
+
450
+ Generated Apps require SDK 0.10.6 (Go module, Rust crate tag, `backend.sdk`
451
+ and `@synopackageland/sdk`) and the Vue frontend UI 0.9.8. SDK 0.10.6's
452
+ executor and lifecycle digests equal 0.10.5, so an App rebuilt from these
453
+ templates keeps its approval unless its executor or policy changes. SDK
454
+ 0.10.6's settings sections load with `[data-placeholder-row]` rows instead of
455
+ skeleton lines, and the delegate template's test expects them. The Go
456
+ template's nine catalogs add SDK 0.10.6's `error.credential_not_ready` in the
457
+ SDK's wording.
458
+
459
+ 繁中摘要:產生的 App 需要 SDK 0.10.6 與 UI 0.9.8。SDK 0.10.6 的 executor/lifecycle digest
460
+ 與 0.10.5 相同,重建的 App 不需重新核准(除非 executor 或 policy 改變)。SDK 設定區塊首次載入
461
+ 改畫 `[data-placeholder-row]` 最終列,delegate 範本的測試隨之更新。Go 範本 9 語系新增
462
+ `error.credential_not_ready`(SDK 文案)。
463
+
464
+ ### Fixed
465
+
466
+ - `native-go-root-ops`: the App's executor client is the SDK's
467
+ `delegate.Local(packageID)` (its socket still overridable in tests), so it
468
+ reads the package's lifecycle mailbox and a stopped or starting package
469
+ answers `APP_STOPPED` or `APP_STARTING` instead of `EXECUTOR_UNAVAILABLE`.
470
+ It built `&delegate.Client{Socket: …}`, which reads no mailbox.
471
+
472
+ 繁中摘要:`native-go-root-ops` 的 executor client 改用 SDK 的 `delegate.Local`,會讀 lifecycle
473
+ mailbox;套件停止/啟動中回 `APP_STOPPED`/`APP_STARTING`,不再是 `EXECUTOR_UNAVAILABLE`。
474
+
475
+ ## 0.10.5 (2026-10-15)
476
+
477
+ Generated Apps require SDK 0.10.5 (Go module, Rust crate tag, `backend.sdk`
478
+ and `@synopackageland/sdk`) and the Vue frontend UI 0.9.7. SDK 0.10.5's
479
+ executor and lifecycle digests equal 0.10.4, so an App rebuilt from these
480
+ templates keeps its approval unless its own root programs change. UI 0.9.7's
481
+ `Space` aligns its items to the start (it centered them); SDK 0.10.5's saves
482
+ list is "Save history" with five per page, and the delegate template's test
483
+ expects that text.
484
+
485
+ 繁中摘要:產生的 App 需要 SDK 0.10.5 與 UI 0.9.7。SDK 0.10.5 的 executor/lifecycle digest
486
+ 與 0.10.4 相同,重建的 App 不需重新核准(除非自己的 root 程式改變)。UI 0.9.7 的 `Space`
487
+ 改為靠起點對齊;SDK 的存檔清單改名「存檔紀錄」、每頁 5 筆,delegate 範本的測試隨之更新。
488
+
489
+ ### Changed
490
+
491
+ - With `SYNOPKGLAND_DOCKER_SSH` set, the gate checks the Vue frontends in Docker on that
492
+ host (`scripts/frontend-docker-checks.sh`), as it already does Rust. Generated projects
493
+ do not change.
494
+
495
+ 繁中摘要:設定 `SYNOPKGLAND_DOCKER_SSH` 時,Vue 前端檢查改在該主機的 Docker 執行。產生的專案不變。
496
+
497
+ ## 0.10.4 (2026-10-14)
498
+
499
+ Generated Apps require SDK 0.10.4 (Go module, Rust crate tag, `backend.sdk`
500
+ and `@synopackageland/sdk`) and the Vue frontend UI 0.9.6. SDK 0.10.4's
501
+ executor and lifecycle digests equal 0.10.3, so an App rebuilt from these
502
+ templates keeps its approval unless its own root programs change.
503
+
504
+ 繁中摘要:產生的 App 需要 SDK 0.10.4 與 UI 0.9.6。SDK 0.10.4 的 executor/lifecycle digest
505
+ 與 0.10.3 相同,重建的 App 不需重新核准(除非自己的 root 程式改變)。
506
+
507
+ ### Added
508
+
509
+ - The plain UI's catalogs word SDK 0.10.4's retryable bridge codes `APP_STOPPED` (the
510
+ package is stopped) and `APP_STARTING` (it was just started) in every locale, as
511
+ spec/bridge/v1/errors.json does.
512
+
513
+ 繁中摘要:plain UI 語系檔新增 `APP_STOPPED`/`APP_STARTING` 的 9 語系文案。
514
+
515
+ ### Changed
516
+
517
+ - The gate runs combinations, Linux tests and frontends side by side, prints a failing
518
+ step's whole output, packs the SDK once for every Vue frontend and shares the Rust gate
519
+ image and cargo cache; `gate.sh --fast` tests only the combinations the changes reach.
520
+ Generated projects do not change.
521
+
522
+ 繁中摘要:gate 並行、失敗印完整輸出、共用 SDK 打包與 Rust cache;`--fast` 只測受影響的組合。產生的專案不變。
523
+
524
+ ## 0.10.3 (2026-10-14)
525
+
526
+ Generated Apps require SDK 0.10.3 (Go module, Rust crate tag, `backend.sdk`
527
+ and `@synopackageland/sdk`) and the Vue frontend UI 0.9.5, and CLI 0.10.3
528
+ builds them. SDK 0.10.3 has a new executor, so a rebuilt App carries a new
529
+ executor digest; an App whose policy digest does not change gets it without
530
+ approval, and one that declares `root.start` is approved again. The lifecycle
531
+ digests are those of 0.10.2.
532
+
533
+ 繁中摘要:產生的 App 需要 SDK 0.10.3 與 UI 0.9.5,由 CLI 0.10.3 建置。policy digest 不變的 App 升級時自動換 executor;宣告 `root.start` 的 App 需要重新核准。
534
+
535
+ ### Added
536
+
537
+ - Guides: `_shared/AGENTS.md` and the comments of `dsm-scripts/postinst` and `postupgrade`
538
+ divide the work after an install or upgrade: root cleanup or migration goes in the program
539
+ `root.start` names, which the executor runs as root once per new version after approval;
540
+ the unprivileged follow-up stays in `dsm-scripts/`, which cannot wait for that step, and
541
+ the App reads its result from the executor status (`start_step`). Needs CLI and SDK
542
+ 0.10.3. The scripts still exit 0.
543
+
544
+ 繁中摘要:說明分工:安裝/升級後的 root 清理或遷移走 `root.start`,非特權收尾留在 `dsm-scripts/`。
545
+
546
+ - `_shared/dsm-scripts/`: DSM's lifecycle scripts (`preinst`, `postinst`, `preupgrade`,
547
+ `postupgrade`, `preuninst`, `postuninst`, `start-stop-status`) with English comments on
548
+ when each runs, as which account, its environment, exit codes and how to show the user a
549
+ message. Each exits 0, so an App behaves as before until it edits one. CLI 0.10.3's `init`
550
+ copies them into every project's `dsm-scripts/`.
551
+
552
+ 繁中摘要:新增 DSM 原生 lifecycle 腳本範例(預設不做事),CLI 0.10.3 的 init 會複製到每個專案。
553
+
554
+ - Guides: `_shared/AGENTS.md` and the native READMEs explain the Login Portal look a portal
555
+ build gets by default and how `login_style` in dsm-package.yaml replaces its colour,
556
+ wallpaper (with its thumbnail) and title image, with the formats and sizes `check` accepts.
557
+ Needs CLI 0.10.3.
558
+
559
+ 繁中摘要:說明 portal App 預設的登入頁樣式,以及如何用 `login_style` 換成自己的圖(需 CLI 0.10.3)。
560
+
561
+ ### Changed
562
+
563
+ - Every template pins SDK 0.10.3 and the Vue frontend UI 0.9.5: the Go module and `go.sum`,
564
+ `@synopackageland/sdk` and `@synopackageland/ui` in the Vue frontend and its lockfile,
565
+ `backend.sdk` for Python and Node.js, and the Rust crate's tag and `Cargo.lock`.
566
+ - `native-go-delegate`: the background-save section is SDK 0.10.3's `BackgroundSavePanel`:
567
+ the save folder with Choose folder, then My saves; its destination list and status badges
568
+ are gone.
569
+
570
+ 繁中摘要:所有範本改 pin SDK 0.10.3、Vue 前端 UI 0.9.5;delegate 範本的背景存檔區塊跟著 SDK 0.10.3 改版。
571
+
572
+ ### Fixed
573
+
574
+ - native-go-root-ops: the executor client no longer sets its own 30-second wait; it waits as
575
+ the SDK says (`delegate.ExecutorTimeout`, 40 seconds from SDK 0.10.3, past the
576
+ executor's 30; `root.run` 140), so `executor.status`, `executor.control` and the pin check
577
+ no longer give up as the executor answers (SDK `spec/protocol/v1`, Timeouts).
578
+ - `native-go-vue`: the zh-CN `app_privilege_denied` message writes account as
579
+ 账户, not 帐户. The i18n test now refuses 帐号 and 帐户 outside DSM glossary
580
+ strings in both the template and the SDK catalogs, so it needs an SDK
581
+ checkout with the matching zh-CN fix in `SYNOPKGLAND_SDK_DIR`.
582
+
583
+ 繁中摘要:簡中「帐户」改為「账户」(DSM glossary 原文保留)。
584
+
585
+ ## 0.10.2 (2026-10-14)
586
+
587
+ First release of the changelog. `@synopackageland/templates` holds the
588
+ project templates `synopkgland init` and `synopkgland add` copy:
589
+
590
+ - `native-go`, with the overlays `native-go-vue`, `native-go-jobs`,
591
+ `native-go-delegate` and `native-go-root-ops`.
592
+ - `native-python`, `native-node` and `native-rust`, with their `jobs`,
593
+ `root-ops`, `delegate` and `vue` overlays.
594
+ - `binary` (a prebuilt static CGI) and `compose` (a Container Manager
595
+ project).
596
+ - `_shared`: agent guides, the template license, Go license texts and the
597
+ third-party notice writer (`@synopackageland/templates/notices`).
598
+
599
+ Every template pins SDK 0.10.2: the Go module and `go.sum`,
600
+ `@synopackageland/sdk` in the Vue frontend, `backend.sdk` for Python and
601
+ Node.js, and the Rust crate's tag and `Cargo.lock`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synopackageland/templates",
3
- "version": "0.40.1",
3
+ "version": "0.40.2",
4
4
  "description": "Project templates for synopkgland init: native-go, native-python, native-node and native-rust (plain or Vue, with jobs, delegate and root-ops overlays), binary and compose.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -14,7 +14,8 @@
14
14
  "files": [
15
15
  "templates/",
16
16
  "LICENSE",
17
- "README.md"
17
+ "README.md",
18
+ "CHANGELOG.md"
18
19
  ],
19
20
  "scripts": {
20
21
  "check:docs": "node --test scripts/check-doc-versions.test.mjs && node scripts/check-doc-versions.mjs",
@@ -22,9 +22,33 @@ sections at the end name each language's files, types and test commands.
22
22
 
23
23
  From the project root, run `synopkgland check --json`,
24
24
  `synopkgland build --json`, then `synopkgland inspect <spk> --json` on the emitted SPK.
25
- For Vue, first run `npm ci`, `npm test` and `npm run build` in frontend.
25
+ For Vue, first run `npm ci` and `npm run build` in frontend. Run its tests only if the user chose tests.
26
26
  Do not connect to or change a NAS without explicit task authorization.
27
27
 
28
+ ## Optional testing
29
+
30
+ Ask once whether the user wants tests: none, local/non-AI, or optional AI too.
31
+ Accept no tests, remember the choice, do not nag and never block a build or release
32
+ on tests. Scaffolding is included by default; writing and running tests are optional.
33
+ Read `synopkgland skill show testing` when setting up or extending tests.
34
+
35
+ The default `npm test` runs only fast local unit/ctl registry contracts.
36
+ `npm run test:local` opts into check/build/inspect. Only on explicit user request,
37
+ run `npm run test:nas:ctl`, `npm run e2e:smoke`, `npm run e2e:ui` or `npm run e2e:ai`.
38
+ The full suite is slow. Never call these from build, install, DSM hooks or release.
39
+ For non-AI use, no model/key is required; AI dependencies are optional installs.
40
+
41
+ Assert meaningful ctl values and the UI primary action's real result, not only
42
+ schemas or page rendering. Adapt the generated examples to actual App operations.
43
+ Long jobs use start -> progress -> pause -> resume without reset -> cancel with
44
+ bounded polling and fixture cleanup; never wait for full completion.
45
+
46
+ AI steps require a user-selected endpoint, key location and model. If no profile
47
+ is configured and setup is unknown, ask the user for those three values. Choose
48
+ the cheapest adequate model and low effort; never default to an expensive model.
49
+ Use E2E_LLM_BASE_URL, E2E_LLM_MODEL, E2E_LLM_API_KEY_FILE (mode 600) or
50
+ E2E_LLM_API_KEY, and optional E2E_LLM_REASONING_EFFORT (default low).
51
+
28
52
  ## Lifecycle scripts (`dsm-scripts/`)
29
53
 
30
54
  `dsm-scripts/` holds DSM's own lifecycle scripts (preinst, postinst, preupgrade,
@@ -274,8 +298,8 @@ Do not force HTTPS for ordinary CRUD/settings/file Apps. Only secure context
274
298
  features, pairing or a strict secure Origin policy justify it. Return
275
299
  `https_required`, not a generic authentication error, and render the SDK's
276
300
  `identityCopy(locale).httpsTitle` / `errors.https_required` with reopening
277
- instructions. Go `api.RequireSecureOrigin(request)` is opt-in and does not
278
- replace authentication, origin or permission checks.
301
+ instructions. Secure-origin enforcement is opt-in and does not replace
302
+ authentication, origin or permission checks.
279
303
 
280
304
  Call `readDsmPorts` for `dms_https` only when `ctx.user?.isAdmin === true`;
281
305
  `readDsmHttpsURL(ctx, location.href)` applies this guard. Ordinary users see
@@ -287,12 +311,14 @@ For an old tab's stale `X-SYNO-TOKEN`, SDK `createClient` can opt in through
287
311
  `effect: read`, `kind: rpc` calls retry once on `session_required`. Writes, AI,
288
312
  streams, batches and unknown methods never retry. Existing `ctx.call` is not
289
313
  automatically wrapped. Verify the installed SDK exports these APIs before
290
- using them. Follow the [CLI skill](https://github.com/synopackageland/syno-pkg-land-cli/blob/main/skills/SKILL.md#https-與舊-dsm-token)
314
+ using them. Follow the [CLI skill](https://github.com/synopackageland/syno-pkg-land-cli/blob/main/skills/SKILL.md)
291
315
  and [SDK guide](https://github.com/synopackageland/syno-pkg-land-sdk/blob/main/docs/https-and-session-recovery.md).
292
- Test both HTTP/HTTPS entries, both user roles and cross-tab session recovery.
316
+ When the user requests NAS acceptance, test both HTTP/HTTPS entries, both user roles and cross-tab session recovery.
293
317
 
294
318
  ## Go backend
295
319
 
320
+ - `api.RequireSecureOrigin(request)` opts into secure-origin enforcement; it does
321
+ not replace authentication, origin or permission checks.
296
322
  - Routes: `backend/internal/app` (`routes.go` registers them); App
297
323
  permissions: `backend/internal/api/permissions.json`. Test with
298
324
  `(cd backend && go test ./...)`, then `go vet ./...` and `gofmt -l .`.
@@ -0,0 +1,5 @@
1
+ import base from './e2e.config.ts';
2
+ import { e2eAgent } from '@synopackageland/cli/e2e';
3
+
4
+ // Loaded only by e2e:ai; the default config needs no AI dependencies or key.
5
+ export default { ...base, agents: { default: e2eAgent() } };
@@ -2,13 +2,17 @@
2
2
  "private": true,
3
3
  "type": "module",
4
4
  "scripts": {
5
- "e2e:smoke": "node --env-file-if-exists=.env node_modules/@synopackageland/cli/dist/e2e/dsm.js tunnel -- e2e run tests/e2e/smoke.e2e.ts"
5
+ "test": "npm run test:unit",
6
+ "test:unit": "node --test tests/unit/*.test.mjs",
7
+ "test:local": "node --test tests/local/*.test.mjs",
8
+ "test:nas:ctl": "node --env-file-if-exists=.env --test tests/ctl/*.test.mjs",
9
+ "e2e:smoke": "node --env-file-if-exists=.env node_modules/@synopackageland/cli/dist/e2e/dsm.js tunnel -- e2e run tests/e2e/smoke.e2e.ts",
10
+ "e2e:ui": "node --env-file-if-exists=.env node_modules/@synopackageland/cli/dist/e2e/dsm.js tunnel -- e2e run tests/e2e/action.e2e.ts",
11
+ "e2e:ai": "node --env-file-if-exists=.env node_modules/@synopackageland/cli/dist/e2e/dsm.js tunnel -- e2e run --config e2e.ai.config.ts tests/e2e/action.ai.e2e.ts"
6
12
  },
7
13
  "devDependencies": {
8
- "@synopackageland/cli": "^0.41.6",
14
+ "@synopackageland/cli": "~0.48.20",
9
15
  "@e2e-dev/web": "^0.14.0",
10
- "e2e": "^0.19.0",
11
- "@ai-sdk/openai": "^4.0.91",
12
- "ai": "^7.0.137"
16
+ "e2e": "^0.19.0"
13
17
  }
14
18
  }
@@ -0,0 +1,17 @@
1
+ import assert from 'node:assert/strict';
2
+ import { test } from 'node:test';
3
+ import { cli } from '../support/cli.mjs';
4
+
5
+ // Invoke only on user request, after ctl discovery/approval for this installed App.
6
+ // Replace this starter command and assertions when the App's contract changes.
7
+ test('installed status reports the expected package and administrator', {
8
+ skip: !process.env.APP_TEST_HOST && 'Set APP_TEST_HOST to an authorized registered host',
9
+ }, () => {
10
+ const command = JSON.parse(process.env.APP_TEST_CTL_COMMAND || '["app","status"]');
11
+ assert.ok(Array.isArray(command) && command.length && command.every(x => typeof x === 'string'));
12
+ const data = cli('ctl', process.env.APP_TEST_APP || '__PACKAGE__', ...command,
13
+ '--host', process.env.APP_TEST_HOST);
14
+ assert.equal(data.package, '__PACKAGE__');
15
+ assert.equal(data.admin, true);
16
+ assert.ok(data.process.uid > 0, 'the App runs as a nonroot package account');
17
+ });
@@ -0,0 +1,14 @@
1
+ import assert from 'node:assert/strict';
2
+ import { test } from '@e2e-dev/web';
3
+ import { actionFixture, assertOutcome, openFixture } from './support/action.ts';
4
+
5
+ // Opt-in semantic step; keep the final result assertion deterministic.
6
+ test('an AI step performs the authorized fixture action', async ({app, browser, agent}) => {
7
+ const {result, expected} = actionFixture();
8
+ const instruction = process.env.APP_TEST_AI_ACTION;
9
+ assert.ok(instruction, 'Set APP_TEST_AI_ACTION to one bounded authorized fixture action');
10
+ const root = await openFixture(app, browser);
11
+ assert.notEqual((await root.locator(result).textContent())?.trim(), expected);
12
+ await agent.act(instruction);
13
+ await assertOutcome(root, result, expected);
14
+ });
@@ -0,0 +1,14 @@
1
+ import assert from 'node:assert/strict';
2
+ import { test } from '@e2e-dev/web';
3
+ import { actionFixture, assertOutcome, openFixture } from './support/action.ts';
4
+
5
+ // An action and its observable result, without a model or AI key.
6
+ // For CRUD, prepare a private fixture first and assert saved/read-back data.
7
+ // For long jobs, replace this with the bounded lifecycle in the testing guide.
8
+ test('the primary action changes the fixture outcome', async ({app, browser}) => {
9
+ const {action, result, expected} = actionFixture();
10
+ const root = await openFixture(app, browser);
11
+ assert.notEqual((await root.locator(result).textContent())?.trim(), expected);
12
+ await root.locator(action).click();
13
+ await assertOutcome(root, result, expected);
14
+ });
@@ -0,0 +1,30 @@
1
+ import assert from 'node:assert/strict';
2
+ import { setTimeout } from 'node:timers/promises';
3
+ import { openApp, openPortal, readSmokeEntry, signIn } from '@synopackageland/cli/e2e';
4
+
5
+ // Configure an authorized fixture action with a known, initially different result.
6
+ export function actionFixture() {
7
+ const action = process.env.APP_TEST_ACTION;
8
+ const result = process.env.APP_TEST_RESULT;
9
+ const expected = process.env.APP_TEST_EXPECTED;
10
+ assert.ok(action && result && expected, 'Set APP_TEST_ACTION, APP_TEST_RESULT and APP_TEST_EXPECTED');
11
+ return {action, result, expected};
12
+ }
13
+
14
+ export async function openFixture(app: Parameters<typeof signIn>[0], browser: NonNullable<Parameters<typeof openApp>[3]>) {
15
+ const entry = readSmokeEntry({entry: process.env.APP_TEST_ENTRY});
16
+ await signIn(app);
17
+ return entry.window ? openApp(app, entry.appId, 30_000, browser) : openPortal(app, entry.entry, browser);
18
+ }
19
+
20
+ type Root = Awaited<ReturnType<typeof openFixture>>;
21
+ export async function assertOutcome(root: Root, result: string, expected: string) {
22
+ const deadline = Date.now() + 10_000;
23
+ let actual;
24
+ do {
25
+ actual = (await root.locator(result).textContent({timeout: 1000}))?.trim();
26
+ if (actual === expected) break;
27
+ await setTimeout(100);
28
+ } while (Date.now() < deadline);
29
+ assert.equal(actual, expected, 'the primary action changed its real outcome');
30
+ }
@@ -0,0 +1,16 @@
1
+ import assert from 'node:assert/strict';
2
+ import { existsSync } from 'node:fs';
3
+ import { test } from 'node:test';
4
+ import { cli } from '../support/cli.mjs';
5
+
6
+ // Explicit local build tier; no deployment or NAS connection.
7
+ test('the App checks, builds and passes package inspection', {timeout: 300_000}, () => {
8
+ cli('check');
9
+ const built = cli('build', '--arch', process.env.APP_TEST_ARCH || 'amd64');
10
+ assert.ok(built.outputs.length > 0);
11
+ for (const spk of built.outputs) {
12
+ assert.equal(existsSync(spk), true);
13
+ const inspected = cli('inspect', spk);
14
+ assert.equal(inspected.spk, spk);
15
+ }
16
+ });
@@ -0,0 +1,11 @@
1
+ import assert from 'node:assert/strict';
2
+ import { execFileSync } from 'node:child_process';
3
+
4
+ // Use the actual CLI and its registered host/session, never a direct HTTP shortcut.
5
+ export function cli(...args) {
6
+ const result = JSON.parse(execFileSync('synopkgland', [...args, '--json'], {
7
+ encoding: 'utf8', timeout: 120_000, stdio: ['ignore', 'pipe', 'pipe'],
8
+ }));
9
+ assert.equal(result.ok, true);
10
+ return result.data;
11
+ }
@@ -0,0 +1,16 @@
1
+ import assert from 'node:assert/strict';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { test } from 'node:test';
4
+
5
+ // Pin meaningful command behavior, not just JSON schema validity.
6
+ const registry = existsSync('operations.json')
7
+ ? JSON.parse(readFileSync('operations.json', 'utf8')) : undefined;
8
+ test('the starter status command remains a read of app.status', {
9
+ skip: !registry?.operations?.['app.status'] && 'No starter status operation; add your own unit contract',
10
+ }, () => {
11
+ const status = registry.operations['app.status'];
12
+ assert.equal(status.effect, 'read');
13
+ assert.deepEqual(status.cli, ['app', 'status']);
14
+ assert.equal(status.flow.type, 'invoke');
15
+ assert.equal(status.flow.method, 'app.status');
16
+ });