@synopackageland/templates 0.15.1 → 0.15.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.
Files changed (36) hide show
  1. package/README.md +6 -4
  2. package/package.json +1 -1
  3. package/templates/binary/ui/app.css +21 -4
  4. package/templates/compose/dsm-package.yaml +1 -1
  5. package/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +1 -1
  6. package/templates/native-go/backend/go.mod +1 -1
  7. package/templates/native-go/backend/go.sum +2 -2
  8. package/templates/native-go/i18n/messages/de.json +4 -3
  9. package/templates/native-go/i18n/messages/en.json +4 -3
  10. package/templates/native-go/i18n/messages/es.json +4 -3
  11. package/templates/native-go/i18n/messages/fr.json +4 -3
  12. package/templates/native-go/i18n/messages/it.json +4 -3
  13. package/templates/native-go/i18n/messages/ja.json +4 -3
  14. package/templates/native-go/i18n/messages/ko.json +4 -3
  15. package/templates/native-go/i18n/messages/zh-CN.json +4 -3
  16. package/templates/native-go/i18n/messages/zh-TW.json +4 -3
  17. package/templates/native-go/ui/app.css +57 -25
  18. package/templates/native-go/ui/app.js +7 -4
  19. package/templates/native-go-vue/frontend/package-lock.json +118 -193
  20. package/templates/native-go-vue/frontend/package.json +3 -3
  21. package/templates/native-go-vue/frontend/src/App.vue +7 -3
  22. package/templates/native-go-vue/frontend/src/i18n/de.json +5 -2
  23. package/templates/native-go-vue/frontend/src/i18n/en.json +5 -2
  24. package/templates/native-go-vue/frontend/src/i18n/es.json +5 -2
  25. package/templates/native-go-vue/frontend/src/i18n/fr.json +5 -2
  26. package/templates/native-go-vue/frontend/src/i18n/it.json +5 -2
  27. package/templates/native-go-vue/frontend/src/i18n/ja.json +5 -2
  28. package/templates/native-go-vue/frontend/src/i18n/ko.json +5 -2
  29. package/templates/native-go-vue/frontend/src/i18n/zh-CN.json +5 -2
  30. package/templates/native-go-vue/frontend/src/i18n/zh-TW.json +5 -2
  31. package/templates/native-go-vue/frontend/src/style.css +2 -2
  32. package/templates/native-go-vue/frontend/test/apps.test.ts +2 -2
  33. package/templates/native-node/dsm-package.yaml +1 -1
  34. package/templates/native-python/dsm-package.yaml +1 -1
  35. package/templates/native-rust/backend/Cargo.lock +2 -2
  36. package/templates/native-rust/backend/Cargo.toml +1 -1
package/README.md CHANGED
@@ -38,12 +38,13 @@ calls each one from the generated script of the same name (`synopkgland skill sh
38
38
  The placeholders `__PACKAGE__` (also the Go module path), `__DISPLAY_NAME__` and
39
39
  `__BACKGROUND_ENABLED__` are substituted by `init`.
40
40
 
41
- `backend/go.mod` requires `github.com/synopackageland/syno-pkg-land-sdk v0.15.1`; that line is
41
+ `backend/go.mod` requires `github.com/synopackageland/syno-pkg-land-sdk v0.15.2`; that line is
42
42
  the single source of the SDK version and `frontend/package.json` pins
43
43
  `@synopackageland/sdk` to the same version. Python and Node.js name it in
44
44
  `backend.sdk`, Rust in the `syno-pkg-land-app` tag of `backend/Cargo.toml`
45
- (and `Cargo.lock`); all of them pin 0.15.1. The Vue frontend pins
46
- `@synopackageland/ui` 0.11.0.
45
+ (and `Cargo.lock`); all of them pin 0.15.2. The Vue frontend pins
46
+ `@synopackageland/ui` 0.12.0. SDK 0.15.2 accepts UI `>=0.10.1 <0.13.0`,
47
+ so no UI peer override is needed. Tests use jsdom 30 for UI floating-layer styles.
47
48
 
48
49
  ## Notice writer
49
50
 
@@ -76,7 +77,8 @@ Without `SYNOPKGLAND_SDK_DIR` the combinations use the released SDK that
76
77
  `backend/go.mod` and `frontend/package.json` pin. With it, `assemble.sh` adds
77
78
  `replace github.com/synopackageland/syno-pkg-land-sdk => $SYNOPKGLAND_SDK_DIR`
78
79
  and installs `$SYNOPKGLAND_SDK_DIR/ts` as an `npm pack` tarball (not a link, so Vue
79
- resolves once). With `SYNOPKGLAND_UI_TARBALL` set it installs that tarball as
80
+ resolves once). Set `SYNOPKGLAND_SDK_TARBALL` to a published tarball to test that
81
+ release without rebuilding the SDK frontend. With `SYNOPKGLAND_UI_TARBALL` set it installs that tarball as
80
82
  `@synopackageland/ui`, for a UI version not yet on npm.
81
83
  The Python and Node.js combinations need `SYNOPKGLAND_SDK_DIR` (its `python/`,
82
84
  and `node/` built with `npm ci && npm run build`) for their App SDK, and the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synopackageland/templates",
3
- "version": "0.15.1",
3
+ "version": "0.15.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": {"type": "git", "url": "git+https://github.com/synopackageland/syno-pkg-land-templates.git"},
@@ -1,4 +1,21 @@
1
- :root { font-family: system-ui, sans-serif; color: #1e293b; background: #f8fafc; }
2
- .binary-app { padding: 2rem; }
3
- .binary-app h1 { font-size: 1.5rem; }
4
- .binary-app p { line-height: 1.6; }
1
+ /* Static UI subset from @synopackageland/ui 0.12.0 dsm7-embedded theme. */
2
+ .binary-app {
3
+ --ui-font-sans: Verdana, Arial, "Microsoft JhengHei", "Microsoft YaHei", Meiryo, sans-serif;
4
+ --ui-font-size: 13px;
5
+ --ui-font-size-title: 16px;
6
+ --ui-line-height: 20px;
7
+ --ui-text: #414b55;
8
+ --ui-surface: #fff;
9
+ --ui-space-2: 8px;
10
+ --ui-space-5: 20px;
11
+ --ui-space-6: 24px;
12
+ box-sizing: border-box;
13
+ min-height: 100%;
14
+ padding: var(--ui-space-5) var(--ui-space-6);
15
+ font: var(--ui-font-size)/var(--ui-line-height) var(--ui-font-sans);
16
+ color: var(--ui-text);
17
+ background: var(--ui-surface);
18
+ overflow-wrap: anywhere;
19
+ }
20
+ .binary-app h1 { margin: 0 0 var(--ui-space-2); font-size: var(--ui-font-size-title); font-weight: 600; }
21
+ .binary-app p { margin: 0; }
@@ -14,7 +14,7 @@ compose:
14
14
  web: {service: web, port: 8080, health: {path: /, status: 200}}
15
15
  network: {egress: isolated}
16
16
  identity_gateway:
17
- sdk: 0.15.1
17
+ sdk: 0.15.2
18
18
  mode: none
19
19
  listen: {http: 28000}
20
20
  # Web Apps default to new-page through the shared app-launch resolver.
@@ -1,6 +1,6 @@
1
1
  Native Go package build dependencies
2
2
 
3
- github.com/synopackageland/syno-pkg-land-sdk v0.15.1 (MIT)
3
+ github.com/synopackageland/syno-pkg-land-sdk v0.15.2 (MIT)
4
4
 
5
5
  Copyright (c) 2026 synopkgland
6
6
 
@@ -4,6 +4,6 @@ go 1.25.0
4
4
 
5
5
  toolchain go1.26.9
6
6
 
7
- require github.com/synopackageland/syno-pkg-land-sdk v0.15.1
7
+ require github.com/synopackageland/syno-pkg-land-sdk v0.15.2
8
8
 
9
9
  require golang.org/x/sys v0.44.0 // indirect
@@ -1,4 +1,4 @@
1
- github.com/synopackageland/syno-pkg-land-sdk v0.15.1 h1:RxG9aWn6PpAe/0o4jkbfDekrVImuIMSfx21X3lcnn24=
2
- github.com/synopackageland/syno-pkg-land-sdk v0.15.1/go.mod h1:msR4MhJQnVZ8NKLb0E/1K79ldZUvcOJmWhKq+gPEa+4=
1
+ github.com/synopackageland/syno-pkg-land-sdk v0.15.2 h1:IeIe7pb9MnFBYKj/m5AtjCch+vgdDc7VbzQMBVSxM3A=
2
+ github.com/synopackageland/syno-pkg-land-sdk v0.15.2/go.mod h1:msR4MhJQnVZ8NKLb0E/1K79ldZUvcOJmWhKq+gPEa+4=
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=
@@ -8,7 +8,7 @@
8
8
  "error.bad_request": "Überprüfen Sie den eingegebenen Wert und versuchen Sie es erneut.",
9
9
  "error.bad_response": "Dieser Vorgang kann nicht ausgeführt werden. Bitte versuchen Sie es später erneut.",
10
10
  "error.cross_origin": "Dieser Vorgang kann nicht ausgeführt werden. Bitte versuchen Sie es später erneut.",
11
- "error.origin_required": "Die Anfrage wurde abgelehnt: Der Browser hat nicht angegeben, dass sie von der Seite dieser App stammt. Öffnen Sie die App in einem aktuellen Browser erneut.",
11
+ "error.origin_required": "Anfrage abgelehnt. Öffnen Sie die App in einem aktuellen Browser erneut.",
12
12
  "error.internal": "Dieser Vorgang kann nicht ausgeführt werden. Bitte versuchen Sie es später erneut.",
13
13
  "error.json_required": "Dieser Vorgang kann nicht ausgeführt werden. Bitte versuchen Sie es später erneut.",
14
14
  "error.method_not_allowed": "Dieser Vorgang kann nicht ausgeführt werden. Bitte versuchen Sie es später erneut.",
@@ -28,12 +28,13 @@
28
28
  "greeting.adminOnly": "Nur Mitglieder der Gruppe administrators können den Gruß ändern.",
29
29
  "greeting.label": "Neuer Gruß",
30
30
  "greeting.save": "Speichern",
31
- "greeting.setBy": "{text} — festgelegt von {user}",
31
+ "greeting.setBy": "Festgelegt von {user}",
32
32
  "status.backend": "Backend",
33
33
  "status.heading": "Backend-Status",
34
34
  "status.package": "Paketname",
35
35
  "status.uid": "Läuft als UID",
36
36
  "status.user": "Benutzer",
37
37
  "status.userAdmin": "{user} (Administrator)",
38
- "status.version": "Version"
38
+ "status.version": "Version",
39
+ "status.platform": "Plattform"
39
40
  }
@@ -8,7 +8,7 @@
8
8
  "error.bad_request": "Check the entered value and try again.",
9
9
  "error.bad_response": "Unable to perform this operation. Please try again later.",
10
10
  "error.cross_origin": "Unable to perform this operation. Please try again later.",
11
- "error.origin_required": "The request was refused: the browser did not show that it came from this App's page. Open the App again in a current browser.",
11
+ "error.origin_required": "Request refused. Open the App again in a current browser.",
12
12
  "error.internal": "Unable to perform this operation. Please try again later.",
13
13
  "error.json_required": "Unable to perform this operation. Please try again later.",
14
14
  "error.method_not_allowed": "Unable to perform this operation. Please try again later.",
@@ -28,12 +28,13 @@
28
28
  "greeting.adminOnly": "Only members of the administrators group can change the greeting.",
29
29
  "greeting.label": "New greeting",
30
30
  "greeting.save": "Save",
31
- "greeting.setBy": "{text} — set by {user}",
31
+ "greeting.setBy": "Set by {user}",
32
32
  "status.backend": "Backend",
33
33
  "status.heading": "Backend status",
34
34
  "status.package": "Package name",
35
35
  "status.uid": "Runs as UID",
36
36
  "status.user": "User",
37
37
  "status.userAdmin": "{user} (administrator)",
38
- "status.version": "Version"
38
+ "status.version": "Version",
39
+ "status.platform": "Platform"
39
40
  }
@@ -8,7 +8,7 @@
8
8
  "error.bad_request": "Compruebe el valor introducido y vuelva a intentarlo.",
9
9
  "error.bad_response": "No se puede realizar esta operación. Vuelva a intentarlo más tarde.",
10
10
  "error.cross_origin": "No se puede realizar esta operación. Vuelva a intentarlo más tarde.",
11
- "error.origin_required": "Se rechazó la solicitud: el navegador no indicó que procediera de la página de esta App. Vuelva a abrir la App en un navegador actual.",
11
+ "error.origin_required": "Solicitud rechazada. Vuelva a abrir la App en un navegador actualizado.",
12
12
  "error.internal": "No se puede realizar esta operación. Vuelva a intentarlo más tarde.",
13
13
  "error.json_required": "No se puede realizar esta operación. Vuelva a intentarlo más tarde.",
14
14
  "error.method_not_allowed": "No se puede realizar esta operación. Vuelva a intentarlo más tarde.",
@@ -28,12 +28,13 @@
28
28
  "greeting.adminOnly": "Solo los miembros del grupo administrators pueden cambiar el saludo.",
29
29
  "greeting.label": "Nuevo saludo",
30
30
  "greeting.save": "Guardar",
31
- "greeting.setBy": "{text} — establecido por {user}",
31
+ "greeting.setBy": "Establecido por {user}",
32
32
  "status.backend": "Backend",
33
33
  "status.heading": "Estado del backend",
34
34
  "status.package": "Nombre del paquete",
35
35
  "status.uid": "Se ejecuta como UID",
36
36
  "status.user": "Usuario",
37
37
  "status.userAdmin": "{user} (administrador)",
38
- "status.version": "Versión"
38
+ "status.version": "Versión",
39
+ "status.platform": "Plataforma"
39
40
  }
@@ -8,7 +8,7 @@
8
8
  "error.bad_request": "Vérifiez la valeur saisie et réessayez.",
9
9
  "error.bad_response": "Impossible d'effectuer cette opération. Veuillez réessayer ultérieurement.",
10
10
  "error.cross_origin": "Impossible d'effectuer cette opération. Veuillez réessayer ultérieurement.",
11
- "error.origin_required": "La requête a été refusée : le navigateur n’a pas indiqué qu’elle provenait de la page de cette App. Rouvrez l’App dans un navigateur récent.",
11
+ "error.origin_required": "Requête refusée. Rouvrez l’App dans un navigateur récent.",
12
12
  "error.internal": "Impossible d'effectuer cette opération. Veuillez réessayer ultérieurement.",
13
13
  "error.json_required": "Impossible d'effectuer cette opération. Veuillez réessayer ultérieurement.",
14
14
  "error.method_not_allowed": "Impossible d'effectuer cette opération. Veuillez réessayer ultérieurement.",
@@ -28,12 +28,13 @@
28
28
  "greeting.adminOnly": "Seuls les membres du groupe administrators peuvent modifier le message d'accueil.",
29
29
  "greeting.label": "Nouveau message d'accueil",
30
30
  "greeting.save": "Sauvegarder",
31
- "greeting.setBy": "{text} — défini par {user}",
31
+ "greeting.setBy": "Défini par {user}",
32
32
  "status.backend": "Backend",
33
33
  "status.heading": "Statut du backend",
34
34
  "status.package": "Nom du paquet",
35
35
  "status.uid": "Exécuté avec l'UID",
36
36
  "status.user": "Utilisateur",
37
37
  "status.userAdmin": "{user} (administrateur)",
38
- "status.version": "Version"
38
+ "status.version": "Version",
39
+ "status.platform": "Plateforme"
39
40
  }
@@ -8,7 +8,7 @@
8
8
  "error.bad_request": "Controllare il valore inserito e riprovare.",
9
9
  "error.bad_response": "Impossibile eseguire questa operazione. Riprovare più tardi.",
10
10
  "error.cross_origin": "Impossibile eseguire questa operazione. Riprovare più tardi.",
11
- "error.origin_required": "La richiesta è stata rifiutata: il browser non ha indicato che proviene dalla pagina di questa App. Riaprire l’App in un browser aggiornato.",
11
+ "error.origin_required": "Richiesta rifiutata. Riaprire l’App in un browser aggiornato.",
12
12
  "error.internal": "Impossibile eseguire questa operazione. Riprovare più tardi.",
13
13
  "error.json_required": "Impossibile eseguire questa operazione. Riprovare più tardi.",
14
14
  "error.method_not_allowed": "Impossibile eseguire questa operazione. Riprovare più tardi.",
@@ -28,12 +28,13 @@
28
28
  "greeting.adminOnly": "Solo i membri del gruppo administrators possono modificare il saluto.",
29
29
  "greeting.label": "Nuovo saluto",
30
30
  "greeting.save": "Salva",
31
- "greeting.setBy": "{text} — impostato da {user}",
31
+ "greeting.setBy": "Impostato da {user}",
32
32
  "status.backend": "Backend",
33
33
  "status.heading": "Stato del backend",
34
34
  "status.package": "Nome pacchetto",
35
35
  "status.uid": "Eseguito come UID",
36
36
  "status.user": "Utente",
37
37
  "status.userAdmin": "{user} (amministratore)",
38
- "status.version": "Versione"
38
+ "status.version": "Versione",
39
+ "status.platform": "Piattaforma"
39
40
  }
@@ -8,7 +8,7 @@
8
8
  "error.bad_request": "入力した値を確認して、もう一度お試しください。",
9
9
  "error.bad_response": "この操作は実行できません。後でもう一度お試しください。",
10
10
  "error.cross_origin": "この操作は実行できません。後でもう一度お試しください。",
11
- "error.origin_required": "リクエストは拒否されました。ブラウザーがこの App のページからのリクエストであることを示しませんでした。最新のブラウザーで App を開き直してください。",
11
+ "error.origin_required": "リクエストは拒否されました。最新のブラウザーで App を開き直してください。",
12
12
  "error.internal": "この操作は実行できません。後でもう一度お試しください。",
13
13
  "error.json_required": "この操作は実行できません。後でもう一度お試しください。",
14
14
  "error.method_not_allowed": "この操作は実行できません。後でもう一度お試しください。",
@@ -28,12 +28,13 @@
28
28
  "greeting.adminOnly": "あいさつを変更できるのは administrators グループのメンバーのみです。",
29
29
  "greeting.label": "新しいあいさつ",
30
30
  "greeting.save": "保存",
31
- "greeting.setBy": "{text} — {user} が設定",
31
+ "greeting.setBy": "{user} が設定",
32
32
  "status.backend": "バックエンド",
33
33
  "status.heading": "バックエンドの状態",
34
34
  "status.package": "パッケージ名",
35
35
  "status.uid": "実行 UID",
36
36
  "status.user": "ユーザー",
37
37
  "status.userAdmin": "{user}(管理者)",
38
- "status.version": "バージョン"
38
+ "status.version": "バージョン",
39
+ "status.platform": "プラットフォーム"
39
40
  }
@@ -8,7 +8,7 @@
8
8
  "error.bad_request": "입력한 값을 확인한 후 다시 시도하십시오.",
9
9
  "error.bad_response": "이 작업을 수행할 수 없습니다. 나중에 다시 시도하십시오.",
10
10
  "error.cross_origin": "이 작업을 수행할 수 없습니다. 나중에 다시 시도하십시오.",
11
- "error.origin_required": "요청이 거부되었습니다. 브라우저가 이 App 페이지에서 보낸 요청임을 알리지 않았습니다. 최신 브라우저에서 App을 다시 여십시오.",
11
+ "error.origin_required": "요청이 거부되었습니다. 최신 브라우저에서 App을 다시 여십시오.",
12
12
  "error.internal": "이 작업을 수행할 수 없습니다. 나중에 다시 시도하십시오.",
13
13
  "error.json_required": "이 작업을 수행할 수 없습니다. 나중에 다시 시도하십시오.",
14
14
  "error.method_not_allowed": "이 작업을 수행할 수 없습니다. 나중에 다시 시도하십시오.",
@@ -28,12 +28,13 @@
28
28
  "greeting.adminOnly": "administrators 그룹의 구성원만 인사말을 변경할 수 있습니다.",
29
29
  "greeting.label": "새 인사말",
30
30
  "greeting.save": "저장",
31
- "greeting.setBy": "{text} — {user}님이 설정함",
31
+ "greeting.setBy": "{user}님이 설정함",
32
32
  "status.backend": "백엔드",
33
33
  "status.heading": "백엔드 상태",
34
34
  "status.package": "패키지 이름",
35
35
  "status.uid": "실행 UID",
36
36
  "status.user": "사용자",
37
37
  "status.userAdmin": "{user}(관리자)",
38
- "status.version": "버전"
38
+ "status.version": "버전",
39
+ "status.platform": "플랫폼"
39
40
  }
@@ -8,7 +8,7 @@
8
8
  "error.bad_request": "请检查输入的值后重试。",
9
9
  "error.bad_response": "无法执行此操作。请稍后再试。",
10
10
  "error.cross_origin": "无法执行此操作。请稍后再试。",
11
- "error.origin_required": "请求已被拒绝:浏览器没有表明它来自此 App 的页面。请使用新版浏览器重新打开 App。",
11
+ "error.origin_required": "请求已被拒绝。请使用新版浏览器重新打开 App。",
12
12
  "error.internal": "无法执行此操作。请稍后再试。",
13
13
  "error.json_required": "无法执行此操作。请稍后再试。",
14
14
  "error.method_not_allowed": "无法执行此操作。请稍后再试。",
@@ -28,12 +28,13 @@
28
28
  "greeting.adminOnly": "只有 administrators 群组的成员可以更改问候语。",
29
29
  "greeting.label": "新的问候语",
30
30
  "greeting.save": "保存",
31
- "greeting.setBy": "{text} — 由 {user} 设置",
31
+ "greeting.setBy": "由 {user} 设置",
32
32
  "status.backend": "后端",
33
33
  "status.heading": "后端状态",
34
34
  "status.package": "套件名称",
35
35
  "status.uid": "运行身份 UID",
36
36
  "status.user": "用户帐号",
37
37
  "status.userAdmin": "{user}(管理员)",
38
- "status.version": "版本"
38
+ "status.version": "版本",
39
+ "status.platform": "平台"
39
40
  }
@@ -8,7 +8,7 @@
8
8
  "error.bad_request": "請檢查輸入的值後再試一次。",
9
9
  "error.bad_response": "無法執行此操作。請稍後再試。",
10
10
  "error.cross_origin": "無法執行此操作。請稍後再試。",
11
- "error.origin_required": "要求已被拒絕:瀏覽器沒有表明它來自這個 App 的頁面。請使用新版瀏覽器重新開啟 App。",
11
+ "error.origin_required": "要求已被拒絕。請使用新版瀏覽器重新開啟 App。",
12
12
  "error.internal": "無法執行此操作。請稍後再試。",
13
13
  "error.json_required": "無法執行此操作。請稍後再試。",
14
14
  "error.method_not_allowed": "無法執行此操作。請稍後再試。",
@@ -28,12 +28,13 @@
28
28
  "greeting.adminOnly": "只有 administrators 群組的成員可以變更問候語。",
29
29
  "greeting.label": "新的問候語",
30
30
  "greeting.save": "儲存",
31
- "greeting.setBy": "{text} — 由 {user} 設定",
31
+ "greeting.setBy": "由 {user} 設定",
32
32
  "status.backend": "後端",
33
33
  "status.heading": "後端狀態",
34
34
  "status.package": "套件名稱",
35
35
  "status.uid": "執行身分 UID",
36
36
  "status.user": "使用者帳號",
37
37
  "status.userAdmin": "{user}(管理員)",
38
- "status.version": "版本"
38
+ "status.version": "版本",
39
+ "status.platform": "平台"
39
40
  }
@@ -1,45 +1,77 @@
1
1
  /* Scoped to .dsmapp: the DSM desktop shares one page with every other app. */
2
2
  .dsmapp {
3
+ /* Static UI subset from @synopackageland/ui 0.12.0 dsm7-embedded theme. */
4
+ --ui-font-sans: Verdana, Arial, "Microsoft JhengHei", "Microsoft YaHei", Meiryo, sans-serif;
5
+ --ui-font-size-sm: 12px;
6
+ --ui-font-size: 13px;
7
+ --ui-font-size-lg: 14px;
8
+ --ui-font-size-title: 16px;
9
+ --ui-line-height: 20px;
10
+ --ui-hairline: 1px;
11
+ --ui-text: #414b55;
12
+ --ui-text-secondary: #414b55d1;
13
+ --ui-surface: #fff;
14
+ --ui-border: #c6d4e0b3;
15
+ --ui-primary: #057feb;
16
+ --ui-primary-hover: #0075db;
17
+ --ui-primary-active: #0062b8;
18
+ --ui-primary-foreground: #fff;
19
+ --ui-danger-text: #a81b1b;
20
+ --ui-radius-sm: 3px;
21
+ --ui-control-md: 28px;
22
+ --ui-space-1: 4px;
23
+ --ui-space-2: 8px;
24
+ --ui-space-3: 12px;
25
+ --ui-space-4: 16px;
26
+ --ui-space-5: 20px;
27
+ --ui-space-6: 24px;
3
28
  box-sizing: border-box;
4
29
  height: 100%;
5
30
  overflow: auto;
6
- padding: 20px 24px;
7
- font: 13px/1.5 "Noto Sans", "Helvetica Neue", Arial, sans-serif;
8
- color: #1d2733;
9
- background: #fff;
31
+ padding: var(--ui-space-5) var(--ui-space-6);
32
+ font: var(--ui-font-size)/var(--ui-line-height) var(--ui-font-sans);
33
+ color: var(--ui-text);
34
+ background: var(--ui-surface);
10
35
  }
11
- .dsmapp-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
12
- .dsmapp h1 { margin: 0 0 4px; font-size: 20px; font-weight: 600; }
36
+ .dsmapp *, .dsmapp *::before, .dsmapp *::after { box-sizing: inherit; }
37
+ .dsmapp-header { display: flex; align-items: center; justify-content: space-between; gap: var(--ui-space-3); }
38
+ .dsmapp h1 { margin: 0 0 var(--ui-space-1); font-size: var(--ui-font-size-title); font-weight: 600; }
13
39
  .dsmapp-secondary {
14
- height: 28px; padding: 0 12px; border: 1px solid #c8d0da; border-radius: 3px;
15
- background: #fff; color: inherit; font: inherit; cursor: pointer;
40
+ height: var(--ui-control-md); padding: 0 var(--ui-space-3); border: 1px solid var(--ui-border); border-radius: var(--ui-radius-sm);
41
+ background: var(--ui-surface); color: inherit; font: inherit; cursor: pointer;
16
42
  }
17
- .dsmapp h2 { margin: 24px 0 8px; font-size: 14px; font-weight: 600; }
18
- .dsmapp-greeting { margin: 0 0 12px; font-size: 15px; }
19
- .dsmapp-form { display: flex; gap: 8px; max-width: 420px; }
43
+ .dsmapp h2 { margin: var(--ui-space-6) 0 var(--ui-space-2); font-size: var(--ui-font-size-lg); font-weight: 600; }
44
+ .dsmapp-greeting { margin: 0 0 var(--ui-space-3); font-size: var(--ui-font-size-lg); }
45
+ .dsmapp-form { display: flex; gap: var(--ui-space-2); max-width: 420px; }
20
46
  .dsmapp-form[hidden] { display: none; }
21
47
  .dsmapp-form input {
22
- flex: 1; height: 28px; padding: 0 8px;
23
- border: 1px solid #c8d0da; border-radius: 3px; font: inherit;
48
+ flex: 1; min-width: 0; height: var(--ui-control-md); padding: 0 var(--ui-space-2);
49
+ border: 1px solid var(--ui-border); border-radius: var(--ui-radius-sm); font: inherit;
24
50
  }
25
51
  .dsmapp-form button {
26
- height: 30px; padding: 0 16px; border: 0; border-radius: 3px;
27
- background: #0086e5; color: #fff; font: inherit; cursor: pointer;
52
+ height: var(--ui-control-md); padding: 0 var(--ui-space-4); border: 0; border-radius: var(--ui-radius-sm);
53
+ background: var(--ui-primary); color: var(--ui-primary-foreground); font: inherit; cursor: pointer;
28
54
  }
29
55
  .dsmapp-form button:disabled { opacity: 0.6; cursor: default; }
30
- .dsmapp-note { margin: 0; color: #5d6b7a; }
56
+ .dsmapp-note { margin: 0; color: var(--ui-text-secondary); font-size: var(--ui-font-size-sm); }
31
57
  .dsmapp-note[hidden] { display: none; }
32
- .dsmapp-message { min-height: 1.5em; color: #c0392b; }
33
- .dsmapp-facts { display: grid; grid-template-columns: max-content 1fr; gap: 4px 16px; margin: 0; }
34
- .dsmapp-facts dt { color: #5d6b7a; }
58
+ .dsmapp-message { min-height: var(--ui-line-height); color: var(--ui-danger-text); }
59
+ .dsmapp-facts { display: grid; grid-template-columns: fit-content(40%) minmax(0, 1fr); gap: var(--ui-space-1) var(--ui-space-4); margin: 0; }
60
+ .dsmapp-facts dt { color: var(--ui-text-secondary); }
35
61
  .dsmapp-facts dd { margin: 0; }
36
62
  /* SDK portal panel (ctx.portal.mountPanel). */
37
- .dsmapp-portal-form { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; max-width: 560px; }
38
- .dsmapp-portal input { height: 28px; padding: 0 8px; border: 1px solid #c8d0da; border-radius: 3px; font: inherit; }
63
+ .dsmapp-portal-form { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ui-space-2); max-width: 560px; }
64
+ .dsmapp-portal input { height: var(--ui-control-md); padding: 0 var(--ui-space-2); border: 1px solid var(--ui-border); border-radius: var(--ui-radius-sm); font: inherit; }
39
65
  .dsmapp-portal button {
40
- height: 30px; padding: 0 12px; border: 1px solid #c8d0da; border-radius: 3px;
41
- background: #fff; color: inherit; font: inherit; cursor: pointer; margin-top: 8px;
66
+ height: var(--ui-control-md); padding: 0 var(--ui-space-3); border: 1px solid var(--ui-border); border-radius: var(--ui-radius-sm);
67
+ background: var(--ui-surface); color: inherit; font: inherit; cursor: pointer; margin-top: var(--ui-space-2);
42
68
  }
43
69
  .dsmapp-portal-form button { margin-top: 0; }
44
- .dsmapp-portal-form button[type="submit"] { border-color: #0086e5; background: #0086e5; color: #fff; }
45
- .dsmapp-portal-error { color: #c0392b; }
70
+ .dsmapp-portal-form button[type="submit"] { border-color: var(--ui-primary); background: var(--ui-primary); color: var(--ui-primary-foreground); }
71
+ .dsmapp-portal-error { color: var(--ui-danger-text); }
72
+ .dsmapp-secondary:hover, .dsmapp-portal button:hover { border-color: var(--ui-primary); }
73
+ .dsmapp-form button:hover, .dsmapp-portal-form button[type="submit"]:hover { background: var(--ui-primary-hover); }
74
+ .dsmapp-form button:active, .dsmapp-portal-form button[type="submit"]:active { background: var(--ui-primary-active); }
75
+ .dsmapp input:focus-visible, .dsmapp button:focus-visible { outline: 2px solid var(--ui-primary); outline-offset: 2px; }
76
+ .dsmapp-facts dd { min-width: 0; overflow-wrap: anywhere; }
77
+ @media (resolution >= 2dppx) { .dsmapp { --ui-hairline: 0.5px; } }
@@ -37,6 +37,7 @@
37
37
  var t = ctx.t;
38
38
  var status = el("dl", { class: "dsmapp-facts" });
39
39
  var greeting = el("p", { class: "dsmapp-greeting", text: t("app.loading") });
40
+ var setBy = el("p", { class: "dsmapp-note", hidden: "" });
40
41
  var input = el("input", { type: "text", maxlength: "200", "aria-label": t("greeting.label"), placeholder: t("greeting.label") });
41
42
  var save = el("button", { type: "submit", text: t("greeting.save") });
42
43
  var refreshButton = el("button", { type: "button", class: "dsmapp-secondary", text: t("app.refresh") });
@@ -49,6 +50,7 @@
49
50
  root.replaceChildren(
50
51
  el("div", { class: "dsmapp-header" }, [el("h1", { text: t("app.title") }), refreshButton]),
51
52
  greeting,
53
+ setBy,
52
54
  form,
53
55
  adminOnly,
54
56
  message,
@@ -72,7 +74,8 @@
72
74
  [t("status.package"), data.package],
73
75
  [t("status.version"), data.version],
74
76
  // A Go backend reports go_version; a Python, Node.js or Rust App reports language.
75
- [t("status.backend"), (data.language || data.go_version) + " · " + data.platform],
77
+ [t("status.backend"), data.language || data.go_version],
78
+ [t("status.platform"), data.platform],
76
79
  [t("status.uid"), String(data.process.uid)]].forEach(function (row) {
77
80
  status.appendChild(el("dt", { text: row[0] }));
78
81
  status.appendChild(el("dd", { text: row[1] }));
@@ -81,9 +84,9 @@
81
84
  adminOnly.hidden = data.admin;
82
85
  }).catch(showError);
83
86
  ctx.call("greeting.get").then(function (data) {
84
- greeting.textContent = data.updated_by
85
- ? t("greeting.setBy", { text: data.text, user: data.updated_by })
86
- : data.text;
87
+ greeting.textContent = data.text;
88
+ setBy.textContent = data.updated_by ? t("greeting.setBy", { user: data.updated_by }) : "";
89
+ setBy.hidden = !data.updated_by;
87
90
  }).catch(showError);
88
91
  }
89
92