@kubohiroya/turbowarp-extension-security-dialog 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -64,8 +64,8 @@ JSONのメタデータを直ちに表示し、選択一覧には「詳細」やJ
64
64
  共通化した画像・サービスリンク・実行条件には `entry.metadata` と取得したソースのメタデータを使用します。
65
65
  どちらか一方でも `unsandboxed: required` なら必要条件を維持し、バッジ・選択可能なモード・非対応選択の解除・
66
66
  一括初期選択で同じ判断をします。セキュリティ確認のOKは、従来どおりソースのメタデータ取得の成功/失敗が確定するまで待ちます。
67
- それ以外の表示は今回変更せず、セキュリティ確認はソースヘッダーのバージョン・リンクのない製作者名・出所URLを維持し、
68
- 選択一覧はカタログのバージョン・明示された製作者リンク・ドキュメントURLを維持します。
67
+ セキュリティ確認はソースヘッダーのバージョン・明示された製作者リンクとドキュメントリンク・出所URLを使用します。
68
+ URLがない製作者名は通常の文字で表示し、選択一覧はカタログのバージョンとリンクを使用します。
69
69
  `entry.category` があれば両画面で同じ順序・日英見出しにし、カテゴリのないプロジェクトでは取得や推測をせず平坦な一覧を維持します。
70
70
 
71
71
 
@@ -255,7 +255,11 @@ coreとVMアダプターの利用にReact/React DOMは必要ありません。
255
255
  ## メタデータとプレビュー
256
256
 
257
257
  セキュリティ確認ではHTTP/HTTPSの出所URLを別行に完全なURLで表示し、別タブで開きます。
258
- 埋め込み拡張や他のスキームはリンクにしません。選択一覧は従来どおりドキュメントURLを表示し、JS配布URLは表示しません。
258
+ 埋め込みソースのURLや他のスキームは出所リンクにしません。選択一覧は従来どおりドキュメントURLを表示し、JS配布URLは表示しません。
259
+ 埋め込みバンドルは先頭ヘッダーへ `// Author URL: https://example.org/creator`、
260
+ `// Docs URL: https://example.org/docs/`、`// Package: @example/bundle` を宣言できます。
261
+ セキュリティ確認にも、`By` / `Author` と組にした製作者リンク、HTTPSのドキュメントリンク、npmアイコンを表示します。
262
+ `Repository`・`Banner`・`Version`・日英説明も共通の表示部品を使用し、内包メンバーのnoticeからバンドル自身の情報を補いません。
259
263
  ソース先頭の宣言コメントに `// Updated: 2026-10-19T10:30:00+09:00` などの更新日時がある場合、
260
264
  記載値をそのまま表示します。`Updated at` / `Updated-at` / `UpdatedAt` / `Last updated` / `Last-updated` /
261
265
  `Last modified` / `Last-modified` も同じ項目です。カスタム `loadInfo` は `metadata.updatedAt` を返せます。
package/README.md CHANGED
@@ -167,9 +167,15 @@ Spacing tightens on short viewports.
167
167
  ## Metadata and previews
168
168
 
169
169
  The security dialog retains its HTTP/HTTPS source-origin URL as a separate provenance line,
170
- opening in a new tab. Embedded extensions and other schemes are not linked. The selection
170
+ opening in a new tab. Embedded source URLs and other schemes are not linked. The selection
171
171
  list keeps its documentation URL instead; it never displays the JavaScript distribution URL.
172
172
 
173
+ Embedded bundles can declare `// Author URL: https://example.org/creator`,
174
+ `// Docs URL: https://example.org/docs/` and `// Package: @example/bundle` in the leading
175
+ header. Security review displays the declared creator link (with `By`/`Author`), HTTPS
176
+ documentation link and npm icon. `Repository`, `Banner`, `Version` and localized descriptions
177
+ use the same package renderer. Bundle member notices do not supply the bundle's own fields.
178
+
173
179
  If the leading declaration comment in the source carries an update timestamp such as
174
180
  `// Updated: 2026-10-19T10:30:00+09:00`, the written value is displayed verbatim.
175
181
  `Updated at` / `Updated-at` / `UpdatedAt` / `Last updated` / `Last-updated` / `Last modified` /
@@ -306,10 +312,9 @@ For shared images, service links and execution requirements, optional `entry.met
306
312
  complements the fetched source metadata. If either declares `unsandboxed: required`, the
307
313
  shared badge, allowed choices, invalidation and batch defaults all honor that requirement.
308
314
  Security still waits for source metadata to settle (success or failure) before accepting OK;
309
- fetching declarations never executes the code. Its source-header version, plain creator
310
- label and source provenance stay as before. Selection keeps catalog versions, explicit
311
- creator links and documentation links. Those unrequested presentation differences are not
312
- changed by the shared renderer. Supplied `entry.category` is rendered in either view;
315
+ fetching declarations never executes the code. Security uses the source-header version,
316
+ explicit creator/documentation links and source provenance; a creator without a URL stays
317
+ plain text. Selection keeps catalog versions and links. Supplied `entry.category` is rendered in either view;
313
318
  category-free project entries stay flat without any catalog lookup or inferred category.
314
319
 
315
320
 
package/dist/index.cjs CHANGED
@@ -110,6 +110,9 @@ var parseExtensionMetadata = (source) => {
110
110
  description: "description",
111
111
  author: "author",
112
112
  by: "author",
113
+ authorurl: "authorURL",
114
+ "author url": "authorURL",
115
+ "author-url": "authorURL",
113
116
  version: "version",
114
117
  updated: "updatedAt",
115
118
  updatedat: "updatedAt",
@@ -122,6 +125,10 @@ var parseExtensionMetadata = (source) => {
122
125
  license: "license",
123
126
  repository: "repository",
124
127
  source: "repository",
128
+ docsurl: "docsURL",
129
+ "docs url": "docsURL",
130
+ "docs-url": "docsURL",
131
+ package: "package",
125
132
  banner: "banner",
126
133
  thumbnail: "banner",
127
134
  image: "banner",
@@ -387,7 +394,7 @@ var messages = {
387
394
  "pending": "Getting metadata\u2026",
388
395
  "failed": "Could not retrieve metadata",
389
396
  "required": "This extension cannot run inside the sandbox. Choose Without sandbox, or Cancel to stop loading the project.",
390
- "requiredToRun": "Required to run",
397
+ "requiredToRun": "Required",
391
398
  "unsupported": "Unsupported",
392
399
  "choiceReset": "The incompatible selection was cleared. Choose how to run this extension again.",
393
400
  "bulkNote": "Applies only to extensions that support this mode.",
@@ -407,7 +414,7 @@ var messages = {
407
414
  "warning": "Extensions without a sandbox can access your project and browser information."
408
415
  },
409
416
  "ja": {
410
- "securityInstruction": "\u26A0\uFE0F\u30DE\u30FC\u30AF\u306E\u8868\u793A\u3055\u308C\u3066\u3044\u308B\u62E1\u5F35\u3092\u5236\u4F5C\u8005\u306E\u610F\u56F3\u3069\u304A\u308A\u306B\u52D5\u4F5C\u3055\u305B\u308B\u305F\u3081\u306B\u306F\u300E\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306A\u3057\u300F\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
417
+ "securityInstruction": "\u300C\u26A0\uFE0F\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306A\u3057\uFF1A\u5FC5\u8981\u300D\u304C\u8868\u793A\u3055\u308C\u3066\u3044\u308B\u62E1\u5F35\u3092\u5236\u4F5C\u8005\u306E\u610F\u56F3\u3069\u304A\u308A\u306B\u52D5\u4F5C\u3055\u305B\u308B\u305F\u3081\u306B\u306F\u300E\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306A\u3057\u300F\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
411
418
  "catalogCancelDestination": "\u300E\u30AD\u30E3\u30F3\u30BB\u30EB\u300F\u3067\u9078\u629E\u4E00\u89A7\u306B\u623B\u308A\u307E\u3059\u3002",
412
419
  "selectionIntro": "\u8FFD\u52A0\u3059\u308B\u6A5F\u80FD\u62E1\u5F35\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\u3002\u4F9D\u5B58\u3059\u308B\u6A5F\u80FD\u62E1\u5F35\u3082\u81EA\u52D5\u3067\u9078\u629E\u3055\u308C\u307E\u3059\u3002",
413
420
  "documentationFor": "{name}: \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8",
@@ -457,7 +464,7 @@ var messages = {
457
464
  "pending": "\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u4E2D\u2026",
458
465
  "failed": "\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F",
459
466
  "required": "\u3053\u306E\u62E1\u5F35\u306F\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u5185\u3067\u306F\u52D5\u4F5C\u3057\u307E\u305B\u3093\u3002\u300C\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306A\u3057\u300D\u3092\u9078\u3076\u304B\u3001\u300C\u30AD\u30E3\u30F3\u30BB\u30EB\u300D\u3067\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u8AAD\u307F\u8FBC\u307F\u3092\u4E2D\u6B62\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
460
- "requiredToRun": "\u52D5\u4F5C\u306B\u5FC5\u8981",
467
+ "requiredToRun": "\u5FC5\u8981",
461
468
  "unsupported": "\u975E\u5BFE\u5FDC",
462
469
  "choiceReset": "\u975E\u5BFE\u5FDC\u306E\u9078\u629E\u3092\u89E3\u9664\u3057\u307E\u3057\u305F\u3002\u5B9F\u884C\u65B9\u6CD5\u3092\u9078\u3073\u76F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
463
470
  "bulkNote": "\u305D\u306E\u30E2\u30FC\u30C9\u306B\u5BFE\u5FDC\u3059\u308B\u62E1\u5F35\u3060\u3051\u306B\u9069\u7528\u3057\u307E\u3059\u3002",
package/dist/index.mjs CHANGED
@@ -61,6 +61,9 @@ var parseExtensionMetadata = (source) => {
61
61
  description: "description",
62
62
  author: "author",
63
63
  by: "author",
64
+ authorurl: "authorURL",
65
+ "author url": "authorURL",
66
+ "author-url": "authorURL",
64
67
  version: "version",
65
68
  updated: "updatedAt",
66
69
  updatedat: "updatedAt",
@@ -73,6 +76,10 @@ var parseExtensionMetadata = (source) => {
73
76
  license: "license",
74
77
  repository: "repository",
75
78
  source: "repository",
79
+ docsurl: "docsURL",
80
+ "docs url": "docsURL",
81
+ "docs-url": "docsURL",
82
+ package: "package",
76
83
  banner: "banner",
77
84
  thumbnail: "banner",
78
85
  image: "banner",
@@ -338,7 +345,7 @@ var messages = {
338
345
  "pending": "Getting metadata\u2026",
339
346
  "failed": "Could not retrieve metadata",
340
347
  "required": "This extension cannot run inside the sandbox. Choose Without sandbox, or Cancel to stop loading the project.",
341
- "requiredToRun": "Required to run",
348
+ "requiredToRun": "Required",
342
349
  "unsupported": "Unsupported",
343
350
  "choiceReset": "The incompatible selection was cleared. Choose how to run this extension again.",
344
351
  "bulkNote": "Applies only to extensions that support this mode.",
@@ -358,7 +365,7 @@ var messages = {
358
365
  "warning": "Extensions without a sandbox can access your project and browser information."
359
366
  },
360
367
  "ja": {
361
- "securityInstruction": "\u26A0\uFE0F\u30DE\u30FC\u30AF\u306E\u8868\u793A\u3055\u308C\u3066\u3044\u308B\u62E1\u5F35\u3092\u5236\u4F5C\u8005\u306E\u610F\u56F3\u3069\u304A\u308A\u306B\u52D5\u4F5C\u3055\u305B\u308B\u305F\u3081\u306B\u306F\u300E\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306A\u3057\u300F\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
368
+ "securityInstruction": "\u300C\u26A0\uFE0F\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306A\u3057\uFF1A\u5FC5\u8981\u300D\u304C\u8868\u793A\u3055\u308C\u3066\u3044\u308B\u62E1\u5F35\u3092\u5236\u4F5C\u8005\u306E\u610F\u56F3\u3069\u304A\u308A\u306B\u52D5\u4F5C\u3055\u305B\u308B\u305F\u3081\u306B\u306F\u300E\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306A\u3057\u300F\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
362
369
  "catalogCancelDestination": "\u300E\u30AD\u30E3\u30F3\u30BB\u30EB\u300F\u3067\u9078\u629E\u4E00\u89A7\u306B\u623B\u308A\u307E\u3059\u3002",
363
370
  "selectionIntro": "\u8FFD\u52A0\u3059\u308B\u6A5F\u80FD\u62E1\u5F35\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\u3002\u4F9D\u5B58\u3059\u308B\u6A5F\u80FD\u62E1\u5F35\u3082\u81EA\u52D5\u3067\u9078\u629E\u3055\u308C\u307E\u3059\u3002",
364
371
  "documentationFor": "{name}: \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8",
@@ -408,7 +415,7 @@ var messages = {
408
415
  "pending": "\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u4E2D\u2026",
409
416
  "failed": "\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F",
410
417
  "required": "\u3053\u306E\u62E1\u5F35\u306F\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u5185\u3067\u306F\u52D5\u4F5C\u3057\u307E\u305B\u3093\u3002\u300C\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306A\u3057\u300D\u3092\u9078\u3076\u304B\u3001\u300C\u30AD\u30E3\u30F3\u30BB\u30EB\u300D\u3067\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u8AAD\u307F\u8FBC\u307F\u3092\u4E2D\u6B62\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
411
- "requiredToRun": "\u52D5\u4F5C\u306B\u5FC5\u8981",
418
+ "requiredToRun": "\u5FC5\u8981",
412
419
  "unsupported": "\u975E\u5BFE\u5FDC",
413
420
  "choiceReset": "\u975E\u5BFE\u5FDC\u306E\u9078\u629E\u3092\u89E3\u9664\u3057\u307E\u3057\u305F\u3002\u5B9F\u884C\u65B9\u6CD5\u3092\u9078\u3073\u76F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
414
421
  "bulkNote": "\u305D\u306E\u30E2\u30FC\u30C9\u306B\u5BFE\u5FDC\u3059\u308B\u62E1\u5F35\u3060\u3051\u306B\u9069\u7528\u3057\u307E\u3059\u3002",
package/dist/react.cjs CHANGED
@@ -93,6 +93,9 @@ var parseExtensionMetadata = (source) => {
93
93
  description: "description",
94
94
  author: "author",
95
95
  by: "author",
96
+ authorurl: "authorURL",
97
+ "author url": "authorURL",
98
+ "author-url": "authorURL",
96
99
  version: "version",
97
100
  updated: "updatedAt",
98
101
  updatedat: "updatedAt",
@@ -105,6 +108,10 @@ var parseExtensionMetadata = (source) => {
105
108
  license: "license",
106
109
  repository: "repository",
107
110
  source: "repository",
111
+ docsurl: "docsURL",
112
+ "docs url": "docsURL",
113
+ "docs-url": "docsURL",
114
+ package: "package",
108
115
  banner: "banner",
109
116
  thumbnail: "banner",
110
117
  image: "banner",
@@ -223,6 +230,7 @@ var style_names_default = {
223
230
  "error": "twextsec-error",
224
231
  "footer": "twextsec-footer",
225
232
  "securityFooter": "twextsec-security-footer",
233
+ "securityModes": "twextsec-security-modes",
226
234
  "footerControls": "twextsec-footer-controls",
227
235
  "previewColumn": "twextsec-preview-column",
228
236
  "packageHeading": "twextsec-package-heading",
@@ -448,7 +456,7 @@ var messages = {
448
456
  "pending": "Getting metadata\u2026",
449
457
  "failed": "Could not retrieve metadata",
450
458
  "required": "This extension cannot run inside the sandbox. Choose Without sandbox, or Cancel to stop loading the project.",
451
- "requiredToRun": "Required to run",
459
+ "requiredToRun": "Required",
452
460
  "unsupported": "Unsupported",
453
461
  "choiceReset": "The incompatible selection was cleared. Choose how to run this extension again.",
454
462
  "bulkNote": "Applies only to extensions that support this mode.",
@@ -468,7 +476,7 @@ var messages = {
468
476
  "warning": "Extensions without a sandbox can access your project and browser information."
469
477
  },
470
478
  "ja": {
471
- "securityInstruction": "\u26A0\uFE0F\u30DE\u30FC\u30AF\u306E\u8868\u793A\u3055\u308C\u3066\u3044\u308B\u62E1\u5F35\u3092\u5236\u4F5C\u8005\u306E\u610F\u56F3\u3069\u304A\u308A\u306B\u52D5\u4F5C\u3055\u305B\u308B\u305F\u3081\u306B\u306F\u300E\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306A\u3057\u300F\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
479
+ "securityInstruction": "\u300C\u26A0\uFE0F\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306A\u3057\uFF1A\u5FC5\u8981\u300D\u304C\u8868\u793A\u3055\u308C\u3066\u3044\u308B\u62E1\u5F35\u3092\u5236\u4F5C\u8005\u306E\u610F\u56F3\u3069\u304A\u308A\u306B\u52D5\u4F5C\u3055\u305B\u308B\u305F\u3081\u306B\u306F\u300E\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306A\u3057\u300F\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
472
480
  "catalogCancelDestination": "\u300E\u30AD\u30E3\u30F3\u30BB\u30EB\u300F\u3067\u9078\u629E\u4E00\u89A7\u306B\u623B\u308A\u307E\u3059\u3002",
473
481
  "selectionIntro": "\u8FFD\u52A0\u3059\u308B\u6A5F\u80FD\u62E1\u5F35\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\u3002\u4F9D\u5B58\u3059\u308B\u6A5F\u80FD\u62E1\u5F35\u3082\u81EA\u52D5\u3067\u9078\u629E\u3055\u308C\u307E\u3059\u3002",
474
482
  "documentationFor": "{name}: \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8",
@@ -518,7 +526,7 @@ var messages = {
518
526
  "pending": "\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u4E2D\u2026",
519
527
  "failed": "\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F",
520
528
  "required": "\u3053\u306E\u62E1\u5F35\u306F\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u5185\u3067\u306F\u52D5\u4F5C\u3057\u307E\u305B\u3093\u3002\u300C\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306A\u3057\u300D\u3092\u9078\u3076\u304B\u3001\u300C\u30AD\u30E3\u30F3\u30BB\u30EB\u300D\u3067\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u8AAD\u307F\u8FBC\u307F\u3092\u4E2D\u6B62\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
521
- "requiredToRun": "\u52D5\u4F5C\u306B\u5FC5\u8981",
529
+ "requiredToRun": "\u5FC5\u8981",
522
530
  "unsupported": "\u975E\u5BFE\u5FDC",
523
531
  "choiceReset": "\u975E\u5BFE\u5FDC\u306E\u9078\u629E\u3092\u89E3\u9664\u3057\u307E\u3057\u305F\u3002\u5B9F\u884C\u65B9\u6CD5\u3092\u9078\u3073\u76F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
524
532
  "bulkNote": "\u305D\u306E\u30E2\u30FC\u30C9\u306B\u5BFE\u5FDC\u3059\u308B\u62E1\u5F35\u3060\u3051\u306B\u9069\u7528\u3057\u307E\u3059\u3002",
@@ -567,6 +575,12 @@ var externalURL = (value, protocols = ["https:"]) => {
567
575
  }
568
576
  };
569
577
  var PackageIcon = ({ service }) => service === "github" ? /* @__PURE__ */ import_react2.default.createElement("svg", { viewBox: "0 0 16 16", width: "22", height: "22", fill: "currentColor", "aria-hidden": "true", focusable: "false" }, /* @__PURE__ */ import_react2.default.createElement("path", { d: "M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38l-.01-1.49c-2.23.48-2.69-1.08-2.69-1.08-.36-.92-.89-1.17-.89-1.17-.73-.5.06-.49.06-.49.8.06 1.22.82 1.22.82.71 1.22 1.87.87 2.33.67.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82A7.65 7.65 0 018 3.73c.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48l-.01 2.33c0 .21.15.46.55.38A8.01 8.01 0 0016 8c0-4.42-3.58-8-8-8z" })) : /* @__PURE__ */ import_react2.default.createElement("svg", { viewBox: "0 0 18 7", width: "30", height: "16", "aria-hidden": "true", focusable: "false" }, /* @__PURE__ */ import_react2.default.createElement("path", { fill: "#cb3837", d: "M0 0h18v6H9v1H5V6H0z" }), /* @__PURE__ */ import_react2.default.createElement("path", { fill: "#fff", d: "M1 1h4v4H4V2H3v3H1zm5 0h5v4H9v1H7V2H6zm2 1v2h1V2zm4-1h5v4h-1V2h-1v3h-1V2h-1v3h-1z" }));
578
+ var PackageRequirement = ({ metadata, locale, id }) => {
579
+ const t = (key, values) => formatMessage(locale, key, values);
580
+ const declared = typeof metadata.unsandboxed === "string" ? metadata.unsandboxed.trim().toLowerCase() : "";
581
+ const requirement = ["required", "optional", "not-needed"].includes(declared) ? declared : "unknown";
582
+ return /* @__PURE__ */ import_react2.default.createElement("div", { className: style_names_default.requirement, "data-requirement": requirement, id }, requirement === "required" && /* @__PURE__ */ import_react2.default.createElement("span", { "aria-hidden": "true" }, "\u26A0\uFE0F"), t("unsandboxedRequirement", { requirement: t(`requirement-${requirement}`) }));
583
+ };
570
584
  var PackageDescription = ({
571
585
  entry,
572
586
  metadata,
@@ -578,6 +592,7 @@ var PackageDescription = ({
578
592
  onImageError,
579
593
  idPrefix,
580
594
  requirementId,
595
+ showRequirement = true,
581
596
  linkCreator,
582
597
  showMissingMetadata,
583
598
  documentation,
@@ -588,8 +603,6 @@ var PackageDescription = ({
588
603
  const name = metadata.name || entry.ids.join(", ");
589
604
  const description = getExtensionDescription(metadata, locale);
590
605
  const candidates = getPackagePreviewCandidates(entry, sharedMetadata);
591
- const declared = typeof sharedMetadata.unsandboxed === "string" ? sharedMetadata.unsandboxed.trim().toLowerCase() : "";
592
- const requirement = ["required", "optional", "not-needed"].includes(declared) ? declared : "unknown";
593
606
  const docsURL = documentation && externalURL(metadata.docsURL);
594
607
  const authorURL = linkCreator && externalURL(metadata.authorURL, ["https:", "http:"]);
595
608
  const repositoryURL = externalURL(sharedMetadata.repository);
@@ -650,7 +663,7 @@ var PackageDescription = ({
650
663
  rel: "noopener noreferrer"
651
664
  },
652
665
  docsURL
653
- )), provenance, !status && /* @__PURE__ */ import_react2.default.createElement("div", { className: style_names_default.secondary }, t("pending")), status === "failed" && /* @__PURE__ */ import_react2.default.createElement("div", { className: style_names_default.error }, t("failed")), /* @__PURE__ */ import_react2.default.createElement("div", { className: style_names_default.requirement, "data-requirement": requirement, id: requirementId }, requirement === "required" && /* @__PURE__ */ import_react2.default.createElement("span", { "aria-hidden": "true" }, "\u26A0\uFE0F"), t("unsandboxedRequirement", { requirement: t(`requirement-${requirement}`) }))));
666
+ )), provenance, !status && /* @__PURE__ */ import_react2.default.createElement("div", { className: style_names_default.secondary }, t("pending")), status === "failed" && /* @__PURE__ */ import_react2.default.createElement("div", { className: style_names_default.error }, t("failed")), showRequirement && /* @__PURE__ */ import_react2.default.createElement(PackageRequirement, { metadata: sharedMetadata, locale, id: requirementId })));
654
667
  };
655
668
  var package_description_default = PackageDescription;
656
669
 
@@ -979,12 +992,13 @@ var ExtensionSecurityDialog = class extends import_react4.default.Component {
979
992
  index,
980
993
  idPrefix,
981
994
  requirementId: reasonId,
995
+ showRequirement: Boolean(selection),
982
996
  previewIndex: row.previewIndex,
983
997
  status: row.status,
984
998
  onImageError: this.handleImageError,
985
- linkCreator: Boolean(selection),
999
+ linkCreator: Boolean(selection || metadata.author && metadata.authorURL),
986
1000
  showMissingMetadata: Boolean(selection),
987
- documentation: Boolean(selection),
1001
+ documentation: Boolean(selection || metadata.docsURL),
988
1002
  provenance: !selection && /* @__PURE__ */ import_react4.default.createElement("div", { className: style_names_default.secondary }, sourceLink)
989
1003
  },
990
1004
  selection && /* @__PURE__ */ import_react4.default.createElement("div", { className: style_names_default.selectionStatus }, /* @__PURE__ */ import_react4.default.createElement("span", { className: style_names_default.selectionBadge, id: `${idPrefix}-state-${index}` }, /* @__PURE__ */ import_react4.default.createElement(SelectionIcon, { state: selection.state }), this.t(`${selection.state}State`)), selection.dependencyReason && /* @__PURE__ */ import_react4.default.createElement(
@@ -995,7 +1009,7 @@ var ExtensionSecurityDialog = class extends import_react4.default.Component {
995
1009
  },
996
1010
  selection.dependencyReason
997
1011
  ))
998
- ), !selection && row.invalidated && !this.state.choices[entry.url] && /* @__PURE__ */ import_react4.default.createElement("div", { className: style_names_default.packageNotices }, /* @__PURE__ */ import_react4.default.createElement("div", { className: style_names_default.warningText, role: "status" }, this.t("choiceReset")))), !selection && MODES.map((mode) => /* @__PURE__ */ import_react4.default.createElement(
1012
+ ), !selection && row.invalidated && !this.state.choices[entry.url] && /* @__PURE__ */ import_react4.default.createElement("div", { className: style_names_default.packageNotices }, /* @__PURE__ */ import_react4.default.createElement("div", { className: style_names_default.warningText, role: "status" }, this.t("choiceReset")))), !selection && /* @__PURE__ */ import_react4.default.createElement("div", { className: style_names_default.securityModes }, /* @__PURE__ */ import_react4.default.createElement(PackageRequirement, { metadata: sharedMetadata, locale: this.props.locale, id: reasonId }), MODES.map((mode) => /* @__PURE__ */ import_react4.default.createElement(
999
1013
  "label",
1000
1014
  {
1001
1015
  className: style_names_default.choice,
@@ -1021,7 +1035,7 @@ var ExtensionSecurityDialog = class extends import_react4.default.Component {
1021
1035
  /* @__PURE__ */ import_react4.default.createElement("span", { className: style_names_default.mobileLabel }, this.t(mode)),
1022
1036
  !this.canChoose(entry, mode) && /* @__PURE__ */ import_react4.default.createElement("span", { className: style_names_default.modeNote }, this.t("unsupported")),
1023
1037
  required && mode === "unsandboxed" && /* @__PURE__ */ import_react4.default.createElement("span", { id: requiredId, className: style_names_default.requiredMode }, this.t("requiredToRun"))
1024
- )), selection && /* @__PURE__ */ import_react4.default.createElement("label", { className: style_names_default.choice, "aria-disabled": selection.disabled }, /* @__PURE__ */ import_react4.default.createElement(
1038
+ ))), selection && /* @__PURE__ */ import_react4.default.createElement("label", { className: style_names_default.choice, "aria-disabled": selection.disabled }, /* @__PURE__ */ import_react4.default.createElement(
1025
1039
  "input",
1026
1040
  {
1027
1041
  type: "checkbox",
package/dist/react.mjs CHANGED
@@ -61,6 +61,9 @@ var parseExtensionMetadata = (source) => {
61
61
  description: "description",
62
62
  author: "author",
63
63
  by: "author",
64
+ authorurl: "authorURL",
65
+ "author url": "authorURL",
66
+ "author-url": "authorURL",
64
67
  version: "version",
65
68
  updated: "updatedAt",
66
69
  updatedat: "updatedAt",
@@ -73,6 +76,10 @@ var parseExtensionMetadata = (source) => {
73
76
  license: "license",
74
77
  repository: "repository",
75
78
  source: "repository",
79
+ docsurl: "docsURL",
80
+ "docs url": "docsURL",
81
+ "docs-url": "docsURL",
82
+ package: "package",
76
83
  banner: "banner",
77
84
  thumbnail: "banner",
78
85
  image: "banner",
@@ -191,6 +198,7 @@ var style_names_default = {
191
198
  "error": "twextsec-error",
192
199
  "footer": "twextsec-footer",
193
200
  "securityFooter": "twextsec-security-footer",
201
+ "securityModes": "twextsec-security-modes",
194
202
  "footerControls": "twextsec-footer-controls",
195
203
  "previewColumn": "twextsec-preview-column",
196
204
  "packageHeading": "twextsec-package-heading",
@@ -416,7 +424,7 @@ var messages = {
416
424
  "pending": "Getting metadata\u2026",
417
425
  "failed": "Could not retrieve metadata",
418
426
  "required": "This extension cannot run inside the sandbox. Choose Without sandbox, or Cancel to stop loading the project.",
419
- "requiredToRun": "Required to run",
427
+ "requiredToRun": "Required",
420
428
  "unsupported": "Unsupported",
421
429
  "choiceReset": "The incompatible selection was cleared. Choose how to run this extension again.",
422
430
  "bulkNote": "Applies only to extensions that support this mode.",
@@ -436,7 +444,7 @@ var messages = {
436
444
  "warning": "Extensions without a sandbox can access your project and browser information."
437
445
  },
438
446
  "ja": {
439
- "securityInstruction": "\u26A0\uFE0F\u30DE\u30FC\u30AF\u306E\u8868\u793A\u3055\u308C\u3066\u3044\u308B\u62E1\u5F35\u3092\u5236\u4F5C\u8005\u306E\u610F\u56F3\u3069\u304A\u308A\u306B\u52D5\u4F5C\u3055\u305B\u308B\u305F\u3081\u306B\u306F\u300E\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306A\u3057\u300F\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
447
+ "securityInstruction": "\u300C\u26A0\uFE0F\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306A\u3057\uFF1A\u5FC5\u8981\u300D\u304C\u8868\u793A\u3055\u308C\u3066\u3044\u308B\u62E1\u5F35\u3092\u5236\u4F5C\u8005\u306E\u610F\u56F3\u3069\u304A\u308A\u306B\u52D5\u4F5C\u3055\u305B\u308B\u305F\u3081\u306B\u306F\u300E\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306A\u3057\u300F\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
440
448
  "catalogCancelDestination": "\u300E\u30AD\u30E3\u30F3\u30BB\u30EB\u300F\u3067\u9078\u629E\u4E00\u89A7\u306B\u623B\u308A\u307E\u3059\u3002",
441
449
  "selectionIntro": "\u8FFD\u52A0\u3059\u308B\u6A5F\u80FD\u62E1\u5F35\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\u3002\u4F9D\u5B58\u3059\u308B\u6A5F\u80FD\u62E1\u5F35\u3082\u81EA\u52D5\u3067\u9078\u629E\u3055\u308C\u307E\u3059\u3002",
442
450
  "documentationFor": "{name}: \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8",
@@ -486,7 +494,7 @@ var messages = {
486
494
  "pending": "\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u4E2D\u2026",
487
495
  "failed": "\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F",
488
496
  "required": "\u3053\u306E\u62E1\u5F35\u306F\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u5185\u3067\u306F\u52D5\u4F5C\u3057\u307E\u305B\u3093\u3002\u300C\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306A\u3057\u300D\u3092\u9078\u3076\u304B\u3001\u300C\u30AD\u30E3\u30F3\u30BB\u30EB\u300D\u3067\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u8AAD\u307F\u8FBC\u307F\u3092\u4E2D\u6B62\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
489
- "requiredToRun": "\u52D5\u4F5C\u306B\u5FC5\u8981",
497
+ "requiredToRun": "\u5FC5\u8981",
490
498
  "unsupported": "\u975E\u5BFE\u5FDC",
491
499
  "choiceReset": "\u975E\u5BFE\u5FDC\u306E\u9078\u629E\u3092\u89E3\u9664\u3057\u307E\u3057\u305F\u3002\u5B9F\u884C\u65B9\u6CD5\u3092\u9078\u3073\u76F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
492
500
  "bulkNote": "\u305D\u306E\u30E2\u30FC\u30C9\u306B\u5BFE\u5FDC\u3059\u308B\u62E1\u5F35\u3060\u3051\u306B\u9069\u7528\u3057\u307E\u3059\u3002",
@@ -535,6 +543,12 @@ var externalURL = (value, protocols = ["https:"]) => {
535
543
  }
536
544
  };
537
545
  var PackageIcon = ({ service }) => service === "github" ? /* @__PURE__ */ React2.createElement("svg", { viewBox: "0 0 16 16", width: "22", height: "22", fill: "currentColor", "aria-hidden": "true", focusable: "false" }, /* @__PURE__ */ React2.createElement("path", { d: "M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38l-.01-1.49c-2.23.48-2.69-1.08-2.69-1.08-.36-.92-.89-1.17-.89-1.17-.73-.5.06-.49.06-.49.8.06 1.22.82 1.22.82.71 1.22 1.87.87 2.33.67.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82A7.65 7.65 0 018 3.73c.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48l-.01 2.33c0 .21.15.46.55.38A8.01 8.01 0 0016 8c0-4.42-3.58-8-8-8z" })) : /* @__PURE__ */ React2.createElement("svg", { viewBox: "0 0 18 7", width: "30", height: "16", "aria-hidden": "true", focusable: "false" }, /* @__PURE__ */ React2.createElement("path", { fill: "#cb3837", d: "M0 0h18v6H9v1H5V6H0z" }), /* @__PURE__ */ React2.createElement("path", { fill: "#fff", d: "M1 1h4v4H4V2H3v3H1zm5 0h5v4H9v1H7V2H6zm2 1v2h1V2zm4-1h5v4h-1V2h-1v3h-1V2h-1v3h-1z" }));
546
+ var PackageRequirement = ({ metadata, locale, id }) => {
547
+ const t = (key, values) => formatMessage(locale, key, values);
548
+ const declared = typeof metadata.unsandboxed === "string" ? metadata.unsandboxed.trim().toLowerCase() : "";
549
+ const requirement = ["required", "optional", "not-needed"].includes(declared) ? declared : "unknown";
550
+ return /* @__PURE__ */ React2.createElement("div", { className: style_names_default.requirement, "data-requirement": requirement, id }, requirement === "required" && /* @__PURE__ */ React2.createElement("span", { "aria-hidden": "true" }, "\u26A0\uFE0F"), t("unsandboxedRequirement", { requirement: t(`requirement-${requirement}`) }));
551
+ };
538
552
  var PackageDescription = ({
539
553
  entry,
540
554
  metadata,
@@ -546,6 +560,7 @@ var PackageDescription = ({
546
560
  onImageError,
547
561
  idPrefix,
548
562
  requirementId,
563
+ showRequirement = true,
549
564
  linkCreator,
550
565
  showMissingMetadata,
551
566
  documentation,
@@ -556,8 +571,6 @@ var PackageDescription = ({
556
571
  const name = metadata.name || entry.ids.join(", ");
557
572
  const description = getExtensionDescription(metadata, locale);
558
573
  const candidates = getPackagePreviewCandidates(entry, sharedMetadata);
559
- const declared = typeof sharedMetadata.unsandboxed === "string" ? sharedMetadata.unsandboxed.trim().toLowerCase() : "";
560
- const requirement = ["required", "optional", "not-needed"].includes(declared) ? declared : "unknown";
561
574
  const docsURL = documentation && externalURL(metadata.docsURL);
562
575
  const authorURL = linkCreator && externalURL(metadata.authorURL, ["https:", "http:"]);
563
576
  const repositoryURL = externalURL(sharedMetadata.repository);
@@ -618,7 +631,7 @@ var PackageDescription = ({
618
631
  rel: "noopener noreferrer"
619
632
  },
620
633
  docsURL
621
- )), provenance, !status && /* @__PURE__ */ React2.createElement("div", { className: style_names_default.secondary }, t("pending")), status === "failed" && /* @__PURE__ */ React2.createElement("div", { className: style_names_default.error }, t("failed")), /* @__PURE__ */ React2.createElement("div", { className: style_names_default.requirement, "data-requirement": requirement, id: requirementId }, requirement === "required" && /* @__PURE__ */ React2.createElement("span", { "aria-hidden": "true" }, "\u26A0\uFE0F"), t("unsandboxedRequirement", { requirement: t(`requirement-${requirement}`) }))));
634
+ )), provenance, !status && /* @__PURE__ */ React2.createElement("div", { className: style_names_default.secondary }, t("pending")), status === "failed" && /* @__PURE__ */ React2.createElement("div", { className: style_names_default.error }, t("failed")), showRequirement && /* @__PURE__ */ React2.createElement(PackageRequirement, { metadata: sharedMetadata, locale, id: requirementId })));
622
635
  };
623
636
  var package_description_default = PackageDescription;
624
637
 
@@ -947,12 +960,13 @@ var ExtensionSecurityDialog = class extends React4.Component {
947
960
  index,
948
961
  idPrefix,
949
962
  requirementId: reasonId,
963
+ showRequirement: Boolean(selection),
950
964
  previewIndex: row.previewIndex,
951
965
  status: row.status,
952
966
  onImageError: this.handleImageError,
953
- linkCreator: Boolean(selection),
967
+ linkCreator: Boolean(selection || metadata.author && metadata.authorURL),
954
968
  showMissingMetadata: Boolean(selection),
955
- documentation: Boolean(selection),
969
+ documentation: Boolean(selection || metadata.docsURL),
956
970
  provenance: !selection && /* @__PURE__ */ React4.createElement("div", { className: style_names_default.secondary }, sourceLink)
957
971
  },
958
972
  selection && /* @__PURE__ */ React4.createElement("div", { className: style_names_default.selectionStatus }, /* @__PURE__ */ React4.createElement("span", { className: style_names_default.selectionBadge, id: `${idPrefix}-state-${index}` }, /* @__PURE__ */ React4.createElement(SelectionIcon, { state: selection.state }), this.t(`${selection.state}State`)), selection.dependencyReason && /* @__PURE__ */ React4.createElement(
@@ -963,7 +977,7 @@ var ExtensionSecurityDialog = class extends React4.Component {
963
977
  },
964
978
  selection.dependencyReason
965
979
  ))
966
- ), !selection && row.invalidated && !this.state.choices[entry.url] && /* @__PURE__ */ React4.createElement("div", { className: style_names_default.packageNotices }, /* @__PURE__ */ React4.createElement("div", { className: style_names_default.warningText, role: "status" }, this.t("choiceReset")))), !selection && MODES.map((mode) => /* @__PURE__ */ React4.createElement(
980
+ ), !selection && row.invalidated && !this.state.choices[entry.url] && /* @__PURE__ */ React4.createElement("div", { className: style_names_default.packageNotices }, /* @__PURE__ */ React4.createElement("div", { className: style_names_default.warningText, role: "status" }, this.t("choiceReset")))), !selection && /* @__PURE__ */ React4.createElement("div", { className: style_names_default.securityModes }, /* @__PURE__ */ React4.createElement(PackageRequirement, { metadata: sharedMetadata, locale: this.props.locale, id: reasonId }), MODES.map((mode) => /* @__PURE__ */ React4.createElement(
967
981
  "label",
968
982
  {
969
983
  className: style_names_default.choice,
@@ -989,7 +1003,7 @@ var ExtensionSecurityDialog = class extends React4.Component {
989
1003
  /* @__PURE__ */ React4.createElement("span", { className: style_names_default.mobileLabel }, this.t(mode)),
990
1004
  !this.canChoose(entry, mode) && /* @__PURE__ */ React4.createElement("span", { className: style_names_default.modeNote }, this.t("unsupported")),
991
1005
  required && mode === "unsandboxed" && /* @__PURE__ */ React4.createElement("span", { id: requiredId, className: style_names_default.requiredMode }, this.t("requiredToRun"))
992
- )), selection && /* @__PURE__ */ React4.createElement("label", { className: style_names_default.choice, "aria-disabled": selection.disabled }, /* @__PURE__ */ React4.createElement(
1006
+ ))), selection && /* @__PURE__ */ React4.createElement("label", { className: style_names_default.choice, "aria-disabled": selection.disabled }, /* @__PURE__ */ React4.createElement(
993
1007
  "input",
994
1008
  {
995
1009
  type: "checkbox",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubohiroya/turbowarp-extension-security-dialog",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "Batch extension security review, previews and per-project defaults for TurboWarp hosts",
5
5
  "type": "module",
6
6
  "author": {
package/styles.css CHANGED
@@ -27,7 +27,9 @@
27
27
  .twextsec-list { padding: 0 20px; flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior-y: contain; }
28
28
  .twextsec-row { border-bottom: 1px solid var(--ui-black-transparent, #dce1eb); }
29
29
  .twextsec-row:last-child { border-bottom: 0; }
30
- .twextsec-row-main { padding: 16px 0; }
30
+ .twextsec-row-main { padding: 16px 0; grid-template-columns: minmax(0, 1fr) auto; }
31
+ .twextsec-security-modes { display: grid; grid-template-columns: 52px 94px 94px; gap: 8px; align-items: center; min-width: 0; }
32
+ .twextsec-security-modes > .twextsec-requirement { grid-column: 1 / -1; justify-self: start; }
31
33
  .twextsec-package-column { min-width: 0; }
32
34
  .twextsec-package-notices { margin-top: 6px; font-size: 12px; overflow-wrap: anywhere; }
33
35
  .twextsec-metadata { display: grid; grid-template-columns: 128px minmax(0,1fr); gap: 12px; align-items: start; min-width: 0; }
@@ -71,12 +73,15 @@
71
73
  .twextsec-confirmation p { margin: 0 0 24px; line-height: 1.6; }
72
74
  @media (max-width: 720px) {
73
75
  .twextsec-metadata { grid-template-columns: 100px minmax(0,1fr); }
74
- .twextsec-columns, .twextsec-row-main { grid-template-columns: minmax(0,1fr) 44px 74px 74px; gap: 6px; }
76
+ .twextsec-columns { grid-template-columns: minmax(0,1fr) 44px 74px 74px; gap: 6px; }
77
+ .twextsec-row-main { gap: 6px; }
78
+ .twextsec-security-modes { grid-template-columns: 44px 74px 74px; gap: 6px; }
75
79
  }
76
80
  @media (max-width: 580px) {
77
81
  .twextsec-modal { margin: 12px auto; max-height: calc(100vh - 24px); max-height: calc(100dvh - 24px); }
78
82
  .twextsec-columns { display: none; }
79
- .twextsec-row-main { grid-template-columns: repeat(3,minmax(0,1fr)); }
83
+ .twextsec-row-main { grid-template-columns: minmax(0,1fr); }
84
+ .twextsec-security-modes { grid-template-columns: repeat(3,minmax(0,1fr)); }
80
85
  .twextsec-package-column { grid-column: 1 / -1; }
81
86
  .twextsec-metadata { grid-template-columns: 84px minmax(0,1fr); gap: 8px; }
82
87
  .twextsec-choice { grid-row: 2; flex-direction: column; padding: 6px 2px; }
package/webpack4.css CHANGED
@@ -27,7 +27,9 @@
27
27
  :global(.twextsec-list) { padding: 0 20px; flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior-y: contain; }
28
28
  :global(.twextsec-row) { border-bottom: 1px solid var(--ui-black-transparent, #dce1eb); }
29
29
  :global(.twextsec-row):last-child { border-bottom: 0; }
30
- :global(.twextsec-row-main) { padding: 16px 0; }
30
+ :global(.twextsec-row-main) { padding: 16px 0; grid-template-columns: minmax(0, 1fr) auto; }
31
+ :global(.twextsec-security-modes) { display: grid; grid-template-columns: 52px 94px 94px; gap: 8px; align-items: center; min-width: 0; }
32
+ :global(.twextsec-security-modes) > :global(.twextsec-requirement) { grid-column: 1 / -1; justify-self: start; }
31
33
  :global(.twextsec-package-column) { min-width: 0; }
32
34
  :global(.twextsec-package-notices) { margin-top: 6px; font-size: 12px; overflow-wrap: anywhere; }
33
35
  :global(.twextsec-metadata) { display: grid; grid-template-columns: 128px minmax(0,1fr); gap: 12px; align-items: start; min-width: 0; }
@@ -71,12 +73,15 @@
71
73
  :global(.twextsec-confirmation) p { margin: 0 0 24px; line-height: 1.6; }
72
74
  @media (max-width: 720px) {
73
75
  :global(.twextsec-metadata) { grid-template-columns: 100px minmax(0,1fr); }
74
- :global(.twextsec-columns), :global(.twextsec-row-main) { grid-template-columns: minmax(0,1fr) 44px 74px 74px; gap: 6px; }
76
+ :global(.twextsec-columns) { grid-template-columns: minmax(0,1fr) 44px 74px 74px; gap: 6px; }
77
+ :global(.twextsec-row-main) { gap: 6px; }
78
+ :global(.twextsec-security-modes) { grid-template-columns: 44px 74px 74px; gap: 6px; }
75
79
  }
76
80
  @media (max-width: 580px) {
77
81
  :global(.twextsec-modal) { margin: 12px auto; max-height: calc(100vh - 24px); max-height: calc(100dvh - 24px); }
78
82
  :global(.twextsec-columns) { display: none; }
79
- :global(.twextsec-row-main) { grid-template-columns: repeat(3,minmax(0,1fr)); }
83
+ :global(.twextsec-row-main) { grid-template-columns: minmax(0,1fr); }
84
+ :global(.twextsec-security-modes) { grid-template-columns: repeat(3,minmax(0,1fr)); }
80
85
  :global(.twextsec-package-column) { grid-column: 1 / -1; }
81
86
  :global(.twextsec-metadata) { grid-template-columns: 84px minmax(0,1fr); gap: 8px; }
82
87
  :global(.twextsec-choice) { grid-row: 2; flex-direction: column; padding: 6px 2px; }