@synopackageland/templates 0.39.2 → 0.40.0

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/README.md CHANGED
@@ -22,7 +22,7 @@ daemon:
22
22
  window_seconds: 300
23
23
  ```
24
24
 
25
- Templates 0.39.2 pin UI 0.19.5 and SDK 0.47.1 in native and Compose projects.
25
+ Templates 0.40.0 pin UI 0.20.0 and SDK 0.50.0 in native and Compose projects.
26
26
  Use a CLI that supports executor manifest format 1. The Vue `AppShell` shows a
27
27
  non-blocking **Reload** notice when an upgrade replaced the UI an open page
28
28
  loaded. Go Apps select
@@ -82,18 +82,18 @@ calls each one from the generated script of the same name (`synopkgland skill sh
82
82
  The placeholders `__PACKAGE__` (also the Go module path), `__DISPLAY_NAME__` and
83
83
  `__BACKGROUND_ENABLED__` are substituted by `init`.
84
84
 
85
- `backend/go.mod` requires `github.com/synopackageland/syno-pkg-land-sdk v0.41.1`; that line is
85
+ `backend/go.mod` requires `github.com/synopackageland/syno-pkg-land-sdk v0.50.0`; that line is
86
86
  the single source of the SDK version and `frontend/package.json` pins
87
87
  `@synopackageland/sdk` to the same version. Python and Node.js name it in
88
88
  `backend.sdk`, Rust in the `syno-pkg-land-app` tag of `backend/Cargo.toml`
89
- (and `Cargo.lock`); all of them pin 0.41.1. The Vue frontend pins
90
- `@synopackageland/ui` 0.19.5. SDK 0.47.1 accepts UI `>=0.10.1 <0.20.0`,
89
+ (and `Cargo.lock`); all of them pin 0.50.0. The Vue frontend pins
90
+ `@synopackageland/ui` 0.20.0. SDK 0.50.0 accepts UI `>=0.10.1 <0.21.0`,
91
91
  so no UI peer override is needed. Tests use jsdom 30 for UI floating-layer styles.
92
92
 
93
93
  Interactive NAS file operations use same-origin browser calls.
94
94
  Custom file handlers use the SDK's
95
95
  [session transport migration](https://github.com/synopackageland/syno-pkg-land-sdk/blob/v0.41.1/docs/dsm-session-transport.md).
96
- The CLI reads SDK 0.47.1's release manifest, which names immutable
96
+ The CLI reads SDK 0.50.0's release manifest, which names immutable
97
97
  executor/v0.39.0 and its executor digests. CLI distributions must resolve
98
98
  templates 0.39.x for the current registry scaffolds.
99
99
 
@@ -109,7 +109,7 @@ Keep punctuation between sentences and intentional loading ellipses.
109
109
 
110
110
  ## Request deadlines and background work
111
111
 
112
- SDK/App 0.47.1 defaults to 300 seconds for cooperative requests and 302 seconds
112
+ SDK/App 0.50.0 defaults to 300 seconds for cooperative requests and 302 seconds
113
113
  for the TS client and generated DSM window. The CLI reads the selected SDK's
114
114
  timeout spec; `backend.timeout_seconds` explicitly overrides it for native
115
115
  backends, and an earlier parent deadline still wins. Go assembly should fall
@@ -303,7 +303,7 @@ The bridge examples expose submission, lookup and cancellation through
303
303
 
304
304
  ## External access
305
305
 
306
- With a compatible CLI and SDK 0.47.1, a gateway App may declare `identity_gateway.external_access: {connect: optional, origin_change: confirm, single_origin: true}` for an upstream that signs in on one fixed URL. The policy is forwarded to the packaged gateway. A single-origin App's `manual_origin` accepts an explicit HTTPS port; the `external-origin` installation setting remains restricted to port 443. The DSM launcher selects a provider destination, probes `/_spl/ping` for up to eight seconds, and explains failures before offering **Open anyway**. A configured single-origin App always opens its primary external origin.
306
+ With a compatible CLI and SDK 0.50.0, a gateway App may declare `identity_gateway.external_access: {connect: optional, origin_change: confirm, single_origin: true}` for an upstream that signs in on one fixed URL. The policy is forwarded to the packaged gateway. A single-origin App's `manual_origin` accepts an explicit HTTPS port; the `external-origin` installation setting remains restricted to port 443. The DSM launcher selects a provider destination, probes `/_spl/ping` for up to eight seconds, and explains failures before offering **Open anyway**. A configured single-origin App always opens its primary external origin.
307
307
 
308
308
 
309
309
  Compose templates declare an app-named dedicated shared folder by default. DSM
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synopackageland/templates",
3
- "version": "0.39.2",
3
+ "version": "0.40.0",
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": {
@@ -23,7 +23,7 @@ compose:
23
23
  web: {service: web, port: 8080, health: {path: /, status: 200}}
24
24
  network: {egress: isolated}
25
25
  identity_gateway:
26
- sdk: 0.47.1
26
+ sdk: 0.50.0
27
27
  mode: none
28
28
  listen: {http: 28000}
29
29
  # Web Apps default to new-page through the shared app-launch resolver.
@@ -17,7 +17,7 @@ DSM main menu → DSM window (ui/app.js)
17
17
 
18
18
  ## Requests and long work
19
19
 
20
- SDK/App 0.47.1 defaults to 300-second requests and a 302-second browser wait.
20
+ SDK/App 0.50.0 defaults to 300-second requests and a 302-second browser wait.
21
21
  Explicit `backend.timeout_seconds` and earlier parent deadlines still apply;
22
22
  rebuild the App to use the new SDK. For long NAS work, enable the existing jobs
23
23
  capability: return admission and the original job ID promptly, execute in the
@@ -27,7 +27,7 @@ last queued/running state intact. After a lost admission reply, reuse the same
27
27
  idempotency key and input instead of replaying a mutation with a new key.
28
28
  Jobs default to 30 minutes; approved executor limits remain separate. ctl keeps
29
29
  its 62-second transport default; use an explicit `--timeout` or an existing
30
- nonblocking job. See the SDK's [request deadline contract](https://github.com/synopackageland/syno-pkg-land-sdk/blob/v0.47.1/docs/request-deadlines.md).
30
+ nonblocking job. See the SDK's [request deadline contract](https://github.com/synopackageland/syno-pkg-land-sdk/blob/v0.50.0/docs/request-deadlines.md).
31
31
 
32
32
  ## Quick start
33
33
 
@@ -1,6 +1,6 @@
1
1
  Native Go package build dependencies
2
2
 
3
- github.com/synopackageland/syno-pkg-land-sdk v0.47.1 (MIT)
3
+ github.com/synopackageland/syno-pkg-land-sdk v0.50.0 (MIT)
4
4
 
5
5
  Copyright (c) 2026 synopkgland
6
6
 
@@ -2,6 +2,6 @@ module __PACKAGE__
2
2
 
3
3
  go 1.26.10
4
4
 
5
- require github.com/synopackageland/syno-pkg-land-sdk v0.47.1
5
+ require github.com/synopackageland/syno-pkg-land-sdk v0.50.0
6
6
 
7
7
  require golang.org/x/sys v0.44.0 // indirect
@@ -1,4 +1,4 @@
1
- github.com/synopackageland/syno-pkg-land-sdk v0.47.1 h1:7HbGRLJUr0ip0isBkvUPfG9p1hLBQ0VmcDskBA4SdTU=
2
- github.com/synopackageland/syno-pkg-land-sdk v0.47.1/go.mod h1:A4ZvKEQnCMk5offv/57Zsf1Z/pV1RmylS9cMfDqdBMQ=
1
+ github.com/synopackageland/syno-pkg-land-sdk v0.50.0 h1:eaehFfsLqa18qFe0S3xjF/eaS3qg5ZSCycZdnGAvt7c=
2
+ github.com/synopackageland/syno-pkg-land-sdk v0.50.0/go.mod h1:A4ZvKEQnCMk5offv/57Zsf1Z/pV1RmylS9cMfDqdBMQ=
3
3
  golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
4
4
  golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
@@ -51,8 +51,11 @@ The manifest is dsm-package.yaml schema 2: backend.kind: go and capabilities.fil
51
51
 
52
52
  Use the installed `@synopackageland/ui`; package.json pins its version.
53
53
  `App.vue` lays the shell out with the SDK's `AppShell` (`@synopackageland/sdk/vue`):
54
- `pages` from `shellPages`, the header buttons in `#actions` and the pages in its
55
- default slot. Given `ctx`, it follows the launch. In a DSM desktop window it
54
+ `pages` from `shellPages`, the page's buttons in `#actions` and the pages in its
55
+ default slot. The sidebar names the page: the shell shows no page title, puts
56
+ `#actions` in a bar above the page and scrolls only the content; a settings
57
+ page (`SectionTabs fill` or `SettingsPage`) keeps its tabs and footer in place
58
+ with no CSS of its own. Given `ctx`, it follows the launch. In a DSM desktop window it
56
59
  keeps `wide-layout="window"`, even maximized; the DSM host sets the 700px
57
60
  minimum window width. A Portal or standalone launch owns the whole page
58
61
  (`ctx.fullPage`, from the generated window): `AppShell` takes
@@ -7,8 +7,8 @@
7
7
  "name": "native-dsm-vue-app",
8
8
  "dependencies": {
9
9
  "@lucide/vue": "1.48.0",
10
- "@synopackageland/sdk": "0.47.1",
11
- "@synopackageland/ui": "0.19.5",
10
+ "@synopackageland/sdk": "0.50.0",
11
+ "@synopackageland/ui": "0.20.0",
12
12
  "vue": "3.5.43"
13
13
  },
14
14
  "devDependencies": {
@@ -1177,13 +1177,13 @@
1177
1177
  }
1178
1178
  },
1179
1179
  "node_modules/@synopackageland/sdk": {
1180
- "version": "0.47.1",
1181
- "resolved": "https://registry.npmjs.org/@synopackageland/sdk/-/sdk-0.47.1.tgz",
1182
- "integrity": "sha512-ZkaNDKfn2zw28UhjKZ493DmEDq6zgr4TbgojXwMEjgRCyY3IRl8JF++LMuf6rrw4dmO7PdOufyAOqAoXulQ6YQ==",
1180
+ "version": "0.50.0",
1181
+ "resolved": "https://registry.npmjs.org/@synopackageland/sdk/-/sdk-0.50.0.tgz",
1182
+ "integrity": "sha512-9cc/aBNicwE/2Ospx1a/akBGU2B8B2cQg6i06LbpZe8rdDBuPdLmAZh5WIlREsUruetq0mfmlVoeQ8l/lrdZ3g==",
1183
1183
  "license": "MIT",
1184
1184
  "peerDependencies": {
1185
1185
  "@lucide/vue": "^1.48.0",
1186
- "@synopackageland/ui": ">=0.10.1 <0.20.0",
1186
+ "@synopackageland/ui": ">=0.10.1 <0.21.0",
1187
1187
  "vue": "^3.5.0"
1188
1188
  },
1189
1189
  "peerDependenciesMeta": {
@@ -1196,9 +1196,9 @@
1196
1196
  }
1197
1197
  },
1198
1198
  "node_modules/@synopackageland/ui": {
1199
- "version": "0.19.5",
1200
- "resolved": "https://registry.npmjs.org/@synopackageland/ui/-/ui-0.19.5.tgz",
1201
- "integrity": "sha512-mVFy1QryQPfJdtjzsvECucFRBPh7oe0L1agJaf0UlA6T3PlsdCly1YhJumXJaY2ABPisGAFcoRCZda36uSIpFA==",
1199
+ "version": "0.20.0",
1200
+ "resolved": "https://registry.npmjs.org/@synopackageland/ui/-/ui-0.20.0.tgz",
1201
+ "integrity": "sha512-YoeMoI2s1jw+1fdyVjc2L9GzwaDCiCrj+zMQDOBiCCjPdPiOElENAbBm1vo/XKViVNhPoH4p3gXQEQxf4RRUXA==",
1202
1202
  "license": "MIT",
1203
1203
  "dependencies": {
1204
1204
  "@floating-ui/dom": "1.8.0",
@@ -8,8 +8,8 @@
8
8
  },
9
9
  "dependencies": {
10
10
  "@lucide/vue": "1.48.0",
11
- "@synopackageland/sdk": "0.47.1",
12
- "@synopackageland/ui": "0.19.5",
11
+ "@synopackageland/sdk": "0.50.0",
12
+ "@synopackageland/ui": "0.20.0",
13
13
  "vue": "3.5.43"
14
14
  },
15
15
  "devDependencies": {
@@ -25,7 +25,6 @@ const page = ref<ShellPage>('status')
25
25
  const pages = computed(() => shellPages({background:backgroundEnabled}))
26
26
  // Only a confirmed sign-in need replaces the App's pages; the sign-in page draws its own title.
27
27
  const signIn = computed(() => login.ready.value && login.enabled.value && !login.subject.value && {header: false as const})
28
- const subtitle = computed(() => app.value?.package)
29
28
  function message(e: unknown) {
30
29
  const code = (e as {code?: string})?.code || 'request_failed'
31
30
  const errors = copy.value.errors as Record<string, string>
@@ -71,7 +70,7 @@ onUnmounted(()=>{disposed=true;unsubscribe?.();login.dispose()})
71
70
  </script>
72
71
 
73
72
  <template>
74
- <AppShell app-root v-model="page" :ctx="shellCtx" :locale="ctx.locale" :pages="pages" :description="subtitle" :denied="signIn" sidebar-storage-key="__PACKAGE__">
73
+ <AppShell app-root v-model="page" :ctx="shellCtx" :locale="ctx.locale" :pages="pages" :denied="signIn" sidebar-storage-key="__PACKAGE__">
75
74
  <template #denied><LoginPage :session="login" :locale="ctx.locale" /></template>
76
75
  <template #actions><Button variant="secondary" :disabled="busy" @click="refreshAll">{{ copy.refresh }}</Button><Button v-if="login.enabled.value" variant="secondary" :disabled="busy" @click="signOut">{{ copy.signOut }}</Button></template>
77
76
  <ExecutorGate :ctx="ctx" :admin="ctx.user?.isAdmin ?? !!app?.admin">
@@ -17,7 +17,7 @@ DSM main menu → DSM window (ui/app.js)
17
17
 
18
18
  ## Requests and long work
19
19
 
20
- SDK/App 0.47.1 defaults to 300-second requests and a 302-second browser wait.
20
+ SDK/App 0.50.0 defaults to 300-second requests and a 302-second browser wait.
21
21
  Explicit `backend.timeout_seconds` and earlier parent deadlines still apply;
22
22
  rebuild the App to use the new SDK. For long NAS work, enable the existing jobs
23
23
  capability: return admission and the original job ID promptly, execute in the
@@ -27,7 +27,7 @@ last queued/running state intact. After a lost admission reply, reuse the same
27
27
  idempotency key and input instead of replaying a mutation with a new key.
28
28
  Jobs default to 30 minutes; approved executor limits remain separate. ctl keeps
29
29
  its 62-second transport default; use an explicit `--timeout` or an existing
30
- nonblocking job. See the SDK's [request deadline contract](https://github.com/synopackageland/syno-pkg-land-sdk/blob/v0.47.1/docs/request-deadlines.md).
30
+ nonblocking job. See the SDK's [request deadline contract](https://github.com/synopackageland/syno-pkg-land-sdk/blob/v0.50.0/docs/request-deadlines.md).
31
31
 
32
32
  ## Quick start
33
33
 
@@ -49,7 +49,7 @@
49
49
  "license": "MIT"
50
50
  },
51
51
  "vendor/@synopackageland/app": {
52
- "version": "0.47.1",
52
+ "version": "0.50.0",
53
53
  "license": "MIT",
54
54
  "engines": {
55
55
  "node": ">=22"
@@ -49,7 +49,7 @@ backend:
49
49
  runtime: node
50
50
  dir: backend/app
51
51
  entry: main.js
52
- sdk: 0.47.1
52
+ sdk: 0.50.0
53
53
  node: { package: Node.js_v22 }
54
54
 
55
55
  ui:
@@ -28,8 +28,11 @@ bridge App's runtime serves.
28
28
 
29
29
  Use the installed `@synopackageland/ui`; package.json pins its version.
30
30
  `App.vue` lays the shell out with the SDK's `AppShell` (`@synopackageland/sdk/vue`):
31
- `pages` from `shellPages`, the header buttons in `#actions` and the pages in its
32
- default slot. Given `ctx`, it follows the launch. In a DSM desktop window it
31
+ `pages` from `shellPages`, the page's buttons in `#actions` and the pages in its
32
+ default slot. The sidebar names the page: the shell shows no page title, puts
33
+ `#actions` in a bar above the page and scrolls only the content; a settings
34
+ page (`SectionTabs fill` or `SettingsPage`) keeps its tabs and footer in place
35
+ with no CSS of its own. Given `ctx`, it follows the launch. In a DSM desktop window it
33
36
  keeps `wide-layout="window"`, even maximized; the DSM host sets the 700px
34
37
  minimum window width. A Portal or standalone launch owns the whole page
35
38
  (`ctx.fullPage`, from the generated window): `AppShell` takes
@@ -17,7 +17,7 @@ DSM main menu → DSM window (ui/app.js)
17
17
 
18
18
  ## Requests and long work
19
19
 
20
- SDK/App 0.47.1 defaults to 300-second requests and a 302-second browser wait.
20
+ SDK/App 0.50.0 defaults to 300-second requests and a 302-second browser wait.
21
21
  Explicit `backend.timeout_seconds` and earlier parent deadlines still apply;
22
22
  rebuild the App to use the new SDK. For long NAS work, enable the existing jobs
23
23
  capability: return admission and the original job ID promptly, execute in the
@@ -27,7 +27,7 @@ last queued/running state intact. After a lost admission reply, reuse the same
27
27
  idempotency key and input instead of replaying a mutation with a new key.
28
28
  Jobs default to 30 minutes; approved executor limits remain separate. ctl keeps
29
29
  its 62-second transport default; use an explicit `--timeout` or an existing
30
- nonblocking job. See the SDK's [request deadline contract](https://github.com/synopackageland/syno-pkg-land-sdk/blob/v0.47.1/docs/request-deadlines.md).
30
+ nonblocking job. See the SDK's [request deadline contract](https://github.com/synopackageland/syno-pkg-land-sdk/blob/v0.50.0/docs/request-deadlines.md).
31
31
 
32
32
  ## Quick start
33
33
 
@@ -47,7 +47,7 @@ backend:
47
47
  runtime: python
48
48
  dir: backend/app
49
49
  entry: main.py
50
- sdk: 0.47.1
50
+ sdk: 0.50.0
51
51
 
52
52
  ui:
53
53
  # Non-UI-SDK frontends open a full page; Portal is a separate opt-in.
@@ -28,8 +28,11 @@ bridge App's runtime serves.
28
28
 
29
29
  Use the installed `@synopackageland/ui`; package.json pins its version.
30
30
  `App.vue` lays the shell out with the SDK's `AppShell` (`@synopackageland/sdk/vue`):
31
- `pages` from `shellPages`, the header buttons in `#actions` and the pages in its
32
- default slot. Given `ctx`, it follows the launch. In a DSM desktop window it
31
+ `pages` from `shellPages`, the page's buttons in `#actions` and the pages in its
32
+ default slot. The sidebar names the page: the shell shows no page title, puts
33
+ `#actions` in a bar above the page and scrolls only the content; a settings
34
+ page (`SectionTabs fill` or `SettingsPage`) keeps its tabs and footer in place
35
+ with no CSS of its own. Given `ctx`, it follows the launch. In a DSM desktop window it
33
36
  keeps `wide-layout="window"`, even maximized; the DSM host sets the 700px
34
37
  minimum window width. A Portal or standalone launch owns the whole page
35
38
  (`ctx.fullPage`, from the generated window): `AppShell` takes
@@ -17,7 +17,7 @@ DSM main menu → DSM window (ui/app.js)
17
17
 
18
18
  ## Requests and long work
19
19
 
20
- SDK/App 0.47.1 defaults to 300-second requests and a 302-second browser wait.
20
+ SDK/App 0.50.0 defaults to 300-second requests and a 302-second browser wait.
21
21
  Explicit `backend.timeout_seconds` and earlier parent deadlines still apply;
22
22
  rebuild the App to use the new SDK. For long NAS work, enable the existing jobs
23
23
  capability: return admission and the original job ID promptly, execute in the
@@ -27,7 +27,7 @@ last queued/running state intact. After a lost admission reply, reuse the same
27
27
  idempotency key and input instead of replaying a mutation with a new key.
28
28
  Jobs default to 30 minutes; approved executor limits remain separate. ctl keeps
29
29
  its 62-second transport default; use an explicit `--timeout` or an existing
30
- nonblocking job. See the SDK's [request deadline contract](https://github.com/synopackageland/syno-pkg-land-sdk/blob/v0.47.1/docs/request-deadlines.md).
30
+ nonblocking job. See the SDK's [request deadline contract](https://github.com/synopackageland/syno-pkg-land-sdk/blob/v0.50.0/docs/request-deadlines.md).
31
31
 
32
32
  ## Quick start
33
33
 
@@ -104,8 +104,8 @@ dependencies = [
104
104
 
105
105
  [[package]]
106
106
  name = "syno-pkg-land-app"
107
- version = "0.47.1"
108
- source = "git+https://github.com/synopackageland/syno-pkg-land-sdk?tag=v0.47.1#a3239a7def2968a111cfb2881fd1726484976c23"
107
+ version = "0.50.0"
108
+ source = "git+https://github.com/synopackageland/syno-pkg-land-sdk?tag=v0.50.0#b1adac9407cf1338fa79741ebfcbdaa5c1698b6f"
109
109
  dependencies = [
110
110
  "libc",
111
111
  "serde",
@@ -9,7 +9,7 @@ libc = "0.2"
9
9
  serde = { version = "1", features = ["derive"] }
10
10
  serde_json = "1"
11
11
  # The SDK version is the tag; `synopkgland check` reads it from Cargo.lock.
12
- syno-pkg-land-app = { git = "https://github.com/synopackageland/syno-pkg-land-sdk", tag = "v0.47.1" }
12
+ syno-pkg-land-app = { git = "https://github.com/synopackageland/syno-pkg-land-sdk", tag = "v0.50.0" }
13
13
 
14
14
  [profile.release]
15
15
  # A handler panic becomes an "internal" reply; abort would end the App without one.
@@ -170,8 +170,8 @@ dependencies = [
170
170
 
171
171
  [[package]]
172
172
  name = "syno-pkg-land-app"
173
- version = "0.47.1"
174
- source = "git+https://github.com/synopackageland/syno-pkg-land-sdk?tag=v0.47.1#a3239a7def2968a111cfb2881fd1726484976c23"
173
+ version = "0.50.0"
174
+ source = "git+https://github.com/synopackageland/syno-pkg-land-sdk?tag=v0.50.0#b1adac9407cf1338fa79741ebfcbdaa5c1698b6f"
175
175
  dependencies = [
176
176
  "libc",
177
177
  "serde",
@@ -10,7 +10,7 @@ libc = "0.2"
10
10
  serde = { version = "1", features = ["derive"] }
11
11
  serde_json = "1"
12
12
  # The SDK version is the tag; `synopkgland check` reads it from Cargo.lock.
13
- syno-pkg-land-app = { git = "https://github.com/synopackageland/syno-pkg-land-sdk", tag = "v0.47.1" }
13
+ syno-pkg-land-app = { git = "https://github.com/synopackageland/syno-pkg-land-sdk", tag = "v0.50.0" }
14
14
 
15
15
  [profile.release]
16
16
  # A handler panic becomes an "internal" reply; abort would end the App without one.
@@ -28,8 +28,11 @@ bridge App's runtime serves.
28
28
 
29
29
  Use the installed `@synopackageland/ui`; package.json pins its version.
30
30
  `App.vue` lays the shell out with the SDK's `AppShell` (`@synopackageland/sdk/vue`):
31
- `pages` from `shellPages`, the header buttons in `#actions` and the pages in its
32
- default slot. Given `ctx`, it follows the launch. In a DSM desktop window it
31
+ `pages` from `shellPages`, the page's buttons in `#actions` and the pages in its
32
+ default slot. The sidebar names the page: the shell shows no page title, puts
33
+ `#actions` in a bar above the page and scrolls only the content; a settings
34
+ page (`SectionTabs fill` or `SettingsPage`) keeps its tabs and footer in place
35
+ with no CSS of its own. Given `ctx`, it follows the launch. In a DSM desktop window it
33
36
  keeps `wide-layout="window"`, even maximized; the DSM host sets the 700px
34
37
  minimum window width. A Portal or standalone launch owns the whole page
35
38
  (`ctx.fullPage`, from the generated window): `AppShell` takes