dsh-deeppilot 0.6.0 → 0.6.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/COMPATIBILITY.md +4 -4
- package/PRIVACY.md +23 -1
- package/README.md +19 -19
- package/README.zh-CN.md +17 -17
- package/lib/client.js +31 -6
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +102 -2
- package/lib/index.js +785 -23
- package/lib/index.js.map +1 -1
- package/package.json +16 -16
package/COMPATIBILITY.md
CHANGED
|
@@ -7,7 +7,7 @@ This file separates tested evidence from intended behavior. Passing unit tests d
|
|
|
7
7
|
| Component | Baseline | Evidence |
|
|
8
8
|
|---|---|---|
|
|
9
9
|
| Node.js | 22 or newer | package engine and CI |
|
|
10
|
-
| DSH CLI and Host API | `0.1.
|
|
10
|
+
| DSH CLI and Host API | `0.1.5-rc.1` minimum for plugin `0.6.x` | rc.1 package-family typecheck/build; bridge and `/phone` protocol tests |
|
|
11
11
|
| Host OS | macOS, Linux, Windows on packaged amd64/arm64 helper targets | helper checksums plus user-confirmed Windows/Linux Funnel launch and connection; local LAN validation remains part of alpha testing |
|
|
12
12
|
| Remote access | Tailscale Funnel, ports 443/8443/10000 | helper and supervisor tests |
|
|
13
13
|
| iOS | native DeepPilot client, protocol v2 | simulator build and v2 pairing/challenge evidence |
|
|
@@ -18,8 +18,8 @@ This file separates tested evidence from intended behavior. Passing unit tests d
|
|
|
18
18
|
- Bearer authentication, URL credentials, and first-frame shared tokens are rejected. A supported client registers a P-256 public key through `/phone/pair` and signs each WebSocket challenge.
|
|
19
19
|
- Without a compatible embedded helper, the core bridge and trusted-LAN mode can still run; remote Funnel reports `unavailable`.
|
|
20
20
|
- If a DSH Host API is missing, only the dependent capability should be disabled. The plugin must not crash the Host.
|
|
21
|
-
- Plugin `0.6.
|
|
22
|
-
|
|
21
|
+
- Plugin `0.6.x` requires DSH `0.1.5-rc.1` or newer. Older plugin
|
|
22
|
+
versions used developer-preview DSH builds and remain historical artifacts.
|
|
23
23
|
- The compatibility facade converts the
|
|
24
24
|
current Session controller's raw event arrays into the stable wrapped
|
|
25
25
|
history entries consumed by the phone bridge. Sessions persisted by earlier
|
|
@@ -31,7 +31,7 @@ This file separates tested evidence from intended behavior. Passing unit tests d
|
|
|
31
31
|
|
|
32
32
|
- Intel macOS support for the embedded helper;
|
|
33
33
|
- signed/notarized helper distribution;
|
|
34
|
-
- repair or migration of persisted history rejected by the `0.1.
|
|
34
|
+
- repair or migration of persisted history rejected by the `0.1.5-rc.1`
|
|
35
35
|
Host's own session reader;
|
|
36
36
|
- every DSH developer-preview revision;
|
|
37
37
|
- physical-device performance and every carrier/network combination;
|
package/PRIVACY.md
CHANGED
|
@@ -7,7 +7,7 @@ DeepPilot connects directly to the DSH Host controlled by the user. The plugin d
|
|
|
7
7
|
By default, runtime state is stored under `$DSH_HOME/deeppilot/`:
|
|
8
8
|
|
|
9
9
|
- `host-id`: a random, non-secret stable audience identifier;
|
|
10
|
-
- `devices-v2.json`: paired public keys, fingerprints, scopes, device metadata, revocation/last-seen timestamps, notification preferences, and APNs
|
|
10
|
+
- `devices-v2.json`: paired public keys, fingerprints, scopes, device metadata, revocation/last-seen timestamps, notification preferences, APNs alert registrations, WidgetKit push registrations (a separate token per device used only for content-free widget refresh invalidations), and at most one Live Activity registration per device (activity identifier, session identifier, APNs Live Activity update token, environment, and expiry);
|
|
11
11
|
- `tailscale/`: local state for the optional embedded tsnet node.
|
|
12
12
|
|
|
13
13
|
The directory is owner-only mode `0700`. The Mac never receives or stores iPhone private signing keys. Pairing codes exist only in plugin memory for up to five minutes and are not written to disk.
|
|
@@ -31,6 +31,28 @@ Direct APNs mode sends the device token and notification payload to Apple using
|
|
|
31
31
|
|
|
32
32
|
The relay does not receive complete history, attachments, live token streams, unrelated prompts, pairing codes, device keys, the device registry, or Tailscale state. Disabling offline push removes this path.
|
|
33
33
|
|
|
34
|
+
## WidgetKit refresh push
|
|
35
|
+
|
|
36
|
+
The iOS home-screen widget may register a separate WidgetKit push token (iOS 26+). These invalidations are content-free: the APNs payload is fixed to `{ "aps": { "content-changed": true } }` with no session, title, or body fields, so neither Apple nor the relay learns anything about Host activity beyond "something changed, please refetch". The widget then pulls data over its own short-lived, authenticated read-only connection directly to the user's DSH Host. Widget tokens are stored alongside the alert token in `devices-v2.json`, are throttled to at most one invalidation per Host per 30 seconds, expire after 7 days without re-registration, and are deleted when the device is revoked.
|
|
37
|
+
|
|
38
|
+
## Live Activity push
|
|
39
|
+
|
|
40
|
+
A Live Activity on the Lock Screen or in the Dynamic Island may register a separate ActivityKit **update** token. Unlike the WidgetKit path, Live Activity updates are **not content-free**: each push carries a bounded progress projection — the session title (up to 100 Unicode code points), the current in-progress or pending todo item's text (up to 160 code points), the todo done/total counts, and a fixed phase value (`running`, `approval`, `question`, `ended`, or `unavailable`). This projection goes to Apple in direct APNs mode and to the relay in relay mode. It never contains conversation history, message bodies, prompt text, attachments, full todo lists, file paths, or model output.
|
|
41
|
+
|
|
42
|
+
The activity must be started by the user on the iPhone; there is no push-to-start, and the activity opens no network connection of its own. Only one Live Activity registration is kept per device, registrations expire after eight hours, and the registration is deleted on unregister, token rotation, or device revocation. Relay mode carries only this bounded projection and rejects unknown content-state fields, oversized text, invalid counts, stale timestamps, and event/phase mismatches; the updated relay must be deployed before background Live Activity updates work through relay mode. System delivery and refresh budgets still apply, so updates may be coalesced, delayed, or dropped by iOS.
|
|
43
|
+
|
|
44
|
+
`push.contentMode: generic` applies to alert notifications only. Live Activity content states always carry the bounded title and current-task text described above, because the activity is rendered from this push; do not register a Live Activity on a device whose Lock Screen should never show session text.
|
|
45
|
+
|
|
34
46
|
## Logs
|
|
35
47
|
|
|
36
48
|
Routine logs contain lifecycle state, delivery outcomes, and process-local salted hashes for source/device identifiers. Logs are designed not to contain pairing codes, key material, APNs tokens, or message bodies. Frame diagnostics appear only with `debug`.
|
|
49
|
+
|
|
50
|
+
### Generic offline notifications
|
|
51
|
+
|
|
52
|
+
Set `push.contentMode` to `generic` in the plugin configuration to replace conversation-derived notification titles and bodies with generic status text **before** either APNs or the Relay receives them. The default is `preview`, preserving short previews. Device tokens, Host audience, session and notification identifiers, and categories are still sent. This option controls offline pushes; local notifications generated by the iOS app from its direct connection are unchanged.
|
|
53
|
+
|
|
54
|
+
For identity-tracked sends, the Host stores a bounded local delivery journal containing
|
|
55
|
+
hashed device/send keys, content fingerprints, session identifiers, timestamps, and
|
|
56
|
+
receipts. It does not store prompt bodies or image data in that journal. The iOS app
|
|
57
|
+
stores unresolved send IDs, display text and attachment counts in its instance-scoped
|
|
58
|
+
SQLite cache; removing that instance removes this outbox with its database.
|
package/README.md
CHANGED
|
@@ -37,21 +37,21 @@ does not require the helper.
|
|
|
37
37
|
|
|
38
38
|
| Plugin version | Required DSH | How to install |
|
|
39
39
|
|---|---|---|
|
|
40
|
-
| `0.6.
|
|
41
|
-
| `0.5.x` (previous stable
|
|
40
|
+
| `0.6.x` (current stable, `latest`) | DSH `0.1.5-rc.1` or newer | `dsh plugin --profile web add dsh-deeppilot` |
|
|
41
|
+
| `0.5.x` (previous stable) | DSH `0.1.1-rc.2`–`0.1.2-alpha.1` | `dsh plugin --profile web add dsh-deeppilot@0.5.0` |
|
|
42
42
|
|
|
43
|
-
`0.6.
|
|
44
|
-
[0.1.
|
|
43
|
+
`0.6.x` is built and typechecked against the DSH
|
|
44
|
+
[0.1.5-rc.1](https://www.npmjs.com/package/@deepseek-ai/dsh/v/0.1.5-rc.1)
|
|
45
45
|
Host and client package family. It uses the Gateway multi-client Remote Events
|
|
46
46
|
routing that keeps Web and DeepPilot independently answerable. Earlier plugin
|
|
47
|
-
alphas remain historical artifacts; users installing the
|
|
48
|
-
should update DSH to `0.1.
|
|
47
|
+
alphas remain historical artifacts; users installing the `alpha` tag for
|
|
48
|
+
pre-release testing should update DSH to `0.1.5-rc.1` or newer.
|
|
49
49
|
|
|
50
50
|
```sh
|
|
51
|
-
# DSH 0.1.
|
|
52
|
-
dsh plugin --profile web add dsh-deeppilot@alpha
|
|
53
|
-
# DSH 0.1.1-rc.2 through 0.1.2-alpha.1 (previous stable):
|
|
51
|
+
# DSH 0.1.5-rc.1 or newer (recommended):
|
|
54
52
|
dsh plugin --profile web add dsh-deeppilot
|
|
53
|
+
# DSH 0.1.1-rc.2 through 0.1.2-alpha.1 (previous stable):
|
|
54
|
+
dsh plugin --profile web add dsh-deeppilot@0.5.0
|
|
55
55
|
dsh web
|
|
56
56
|
```
|
|
57
57
|
|
|
@@ -78,33 +78,33 @@ DeepPilot state under `$DSH_HOME/deeppilot/`.
|
|
|
78
78
|
|
|
79
79
|
## Publishing (maintainers)
|
|
80
80
|
|
|
81
|
-
`0.6.
|
|
81
|
+
`0.6.x` targets DSH `0.1.5-rc.1`+; `0.5.x` stays compatible with
|
|
82
82
|
DSH `0.1.1-rc.2`–`0.1.2-alpha.1`. Keep both published:
|
|
83
83
|
|
|
84
84
|
1. Bump `version` in `package.json` and in the root `""` entry of
|
|
85
85
|
`package-lock.json`, then run `npm test && npm run typecheck && npm run build`
|
|
86
86
|
and inspect `npm pack --dry-run --json` (the check
|
|
87
|
-
`tests/compatibility-metadata.test.ts` enforces the `^0.1.
|
|
87
|
+
`tests/compatibility-metadata.test.ts` enforces the `^0.1.5-rc.1` peer
|
|
88
88
|
ranges).
|
|
89
89
|
2. Commit the release and push it. `npm publish` runs `prepack` (build) and
|
|
90
90
|
`prepublishOnly` (test + typecheck) automatically.
|
|
91
|
-
3. Publish
|
|
91
|
+
3. Publish pre-releases without touching `latest`:
|
|
92
92
|
|
|
93
93
|
```sh
|
|
94
94
|
npm publish --tag alpha
|
|
95
95
|
```
|
|
96
96
|
|
|
97
97
|
After a successful publish, `npm view dsh-deeppilot dist-tags --json` shows
|
|
98
|
-
`"latest": "0.
|
|
99
|
-
package by installing it into a DSH `0.1.
|
|
98
|
+
`"latest": "0.6.x"` and `"alpha": "0.6.x-alpha.y"`. Verify the published
|
|
99
|
+
package by installing it into a DSH `0.1.5-rc.1` profile before pointing
|
|
100
100
|
users at it.
|
|
101
|
-
4. Tag the release commit `
|
|
101
|
+
4. Tag the release commit `vX.Y.Z` and prepare a GitHub Release
|
|
102
102
|
(English + 简体中文 notes) that links this README section.
|
|
103
|
-
5.
|
|
104
|
-
`
|
|
105
|
-
|
|
103
|
+
5. Publish stable releases with `npm publish --tag latest`, which moves
|
|
104
|
+
`latest` to the new version. Stable releases must never be published
|
|
105
|
+
with `--tag alpha`.
|
|
106
106
|
|
|
107
|
-
Never run `npm publish` from a copy that still has
|
|
107
|
+
Never run `npm publish` from a copy that still has an older version.
|
|
108
108
|
|
|
109
109
|
|
|
110
110
|
## Connection and privacy
|
package/README.zh-CN.md
CHANGED
|
@@ -34,20 +34,20 @@
|
|
|
34
34
|
|
|
35
35
|
| 插件版本 | 所需 DSH | 安装命令 |
|
|
36
36
|
|---|---|---|
|
|
37
|
-
| `0.6.
|
|
38
|
-
| `0.5.x
|
|
37
|
+
| `0.6.x`(当前稳定版,`latest`) | DSH `0.1.5-rc.1` 或更高 | `dsh plugin --profile web add dsh-deeppilot` |
|
|
38
|
+
| `0.5.x`(旧版稳定版) | DSH `0.1.1-rc.2`–`0.1.2-alpha.1` | `dsh plugin --profile web add dsh-deeppilot@0.5.0` |
|
|
39
39
|
|
|
40
|
-
`0.6.
|
|
41
|
-
[0.1.
|
|
40
|
+
`0.6.x` 基于 DSH
|
|
41
|
+
[0.1.5-rc.1](https://www.npmjs.com/package/@deepseek-ai/dsh/v/0.1.5-rc.1)
|
|
42
42
|
的 Host 与 client 包族构建并完成类型检查。它使用 Gateway 多 Client Remote Events
|
|
43
43
|
路由,使 Web 与 DeepPilot 能独立处理同一交互。旧 alpha 仅保留为历史产物;安装
|
|
44
|
-
|
|
44
|
+
`alpha` tag 进行预发布测试的用户应先把 DSH 更新到 `0.1.5-rc.1` 或更高版本。
|
|
45
45
|
|
|
46
46
|
```sh
|
|
47
|
-
# DSH 0.1.
|
|
48
|
-
dsh plugin --profile web add dsh-deeppilot@alpha
|
|
49
|
-
# DSH 0.1.1-rc.2 至 0.1.2-alpha.1(旧版稳定):
|
|
47
|
+
# DSH 0.1.5-rc.1 或更高(推荐):
|
|
50
48
|
dsh plugin --profile web add dsh-deeppilot
|
|
49
|
+
# DSH 0.1.1-rc.2 至 0.1.2-alpha.1(旧版稳定):
|
|
50
|
+
dsh plugin --profile web add dsh-deeppilot@0.5.0
|
|
51
51
|
dsh web
|
|
52
52
|
```
|
|
53
53
|
|
|
@@ -71,30 +71,30 @@ dsh plugin --profile web remove dsh-deeppilot
|
|
|
71
71
|
|
|
72
72
|
## 发布说明(维护者)
|
|
73
73
|
|
|
74
|
-
`0.6.
|
|
74
|
+
`0.6.x` 面向 DSH `0.1.5-rc.1`+;`0.5.x` 保持兼容 DSH
|
|
75
75
|
`0.1.1-rc.2`–`0.1.2-alpha.1`,两个版本线都要保持发布:
|
|
76
76
|
|
|
77
77
|
1. 同步修改 `package.json` 与 `package-lock.json` 根 `""` 条目中的
|
|
78
78
|
`version`,然后运行 `npm test && npm run typecheck && npm run build`,
|
|
79
79
|
并检查 `npm pack --dry-run --json`(`tests/compatibility-metadata.test.ts`
|
|
80
|
-
会强制校验 `^0.1.
|
|
80
|
+
会强制校验 `^0.1.5-rc.1` 的 peer 范围)。
|
|
81
81
|
2. 提交发布并推送。`npm publish` 会自动执行 `prepack`(构建)与
|
|
82
82
|
`prepublishOnly`(测试 + 类型检查)。
|
|
83
|
-
3.
|
|
83
|
+
3. 发布预发布版本,不要动 `latest`:
|
|
84
84
|
|
|
85
85
|
```sh
|
|
86
86
|
npm publish --tag alpha
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
发布成功后,`npm view dsh-deeppilot dist-tags --json` 应显示
|
|
90
|
-
`"latest": "0.
|
|
91
|
-
DSH `0.1.
|
|
92
|
-
4. 为发布提交打 `
|
|
90
|
+
`"latest": "0.6.x"` 与 `"alpha": "0.6.x-alpha.y"`。向用户推荐前,请先在
|
|
91
|
+
DSH `0.1.5-rc.1` profile 中安装验证发布的包。
|
|
92
|
+
4. 为发布提交打 `vX.Y.Z` tag,并准备包含英文与简体中文说明的
|
|
93
93
|
GitHub Release,链接本 README 的发布说明。
|
|
94
|
-
5.
|
|
95
|
-
|
|
94
|
+
5. 稳定版用 `npm publish --tag latest` 发布,使 `latest` 切换到新版本。
|
|
95
|
+
稳定版绝不使用 `--tag alpha` 发布。
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
绝不要从仍是旧版本的副本执行 `npm publish`。
|
|
98
98
|
|
|
99
99
|
|
|
100
100
|
## 连接与隐私
|
package/lib/client.js
CHANGED
|
@@ -539,6 +539,8 @@ window.__ModuleLoader__.load({
|
|
|
539
539
|
"devices.col.fingerprint": "密钥指纹",
|
|
540
540
|
"devices.col.actions": "操作",
|
|
541
541
|
"devices.revoke": "删除",
|
|
542
|
+
"devices.revokeAria": "删除设备“{name}”",
|
|
543
|
+
"devices.deleting": "删除中…",
|
|
542
544
|
"devices.revokeConfirm": "确定删除设备“{name}”吗?该设备会立即断开,再次使用时需要重新配对。",
|
|
543
545
|
"devices.revoked": "设备已删除",
|
|
544
546
|
"devices.revokeFailed": "设备删除失败:",
|
|
@@ -719,6 +721,8 @@ window.__ModuleLoader__.load({
|
|
|
719
721
|
"devices.col.fingerprint": "Key fingerprint",
|
|
720
722
|
"devices.col.actions": "Actions",
|
|
721
723
|
"devices.revoke": "Delete",
|
|
724
|
+
"devices.revokeAria": "Delete device “{name}”",
|
|
725
|
+
"devices.deleting": "Deleting…",
|
|
722
726
|
"devices.revokeConfirm": "Delete “{name}”? It will disconnect immediately and must pair again before reconnecting.",
|
|
723
727
|
"devices.revoked": "Device deleted",
|
|
724
728
|
"devices.revokeFailed": "Failed to delete device: ",
|
|
@@ -881,10 +885,15 @@ window.__ModuleLoader__.load({
|
|
|
881
885
|
".pbb-action:disabled{cursor:default;opacity:.5}",
|
|
882
886
|
".pbb-actionSelected{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-state-success-primary,#22a06b);background:var(--dsw-alias-bg-module-platform)}",
|
|
883
887
|
".pbb-targetList{display:flex;flex-wrap:wrap;gap:6px;padding-top:4px}",
|
|
884
|
-
".pbb-
|
|
885
|
-
".pbb-
|
|
886
|
-
".pbb-
|
|
887
|
-
".pbb-
|
|
888
|
+
".pbb-actionDangerGhost{color:#dc2626;border-color:rgba(220,38,38,.38);background:transparent;line-height:1.35;padding:3px 9px;box-shadow:none;transition:color .15s ease,background-color .15s ease,border-color .15s ease,box-shadow .15s ease,transform .1s ease}",
|
|
889
|
+
".pbb-actionDangerGhost:hover:not(:disabled){color:#b91c1c;background:rgba(220,38,38,.09);border-color:rgba(185,28,28,.5);box-shadow:0 1px 2px rgba(127,29,29,.1)}",
|
|
890
|
+
".pbb-actionDangerGhost:active:not(:disabled){color:#991b1b;background:rgba(220,38,38,.14);border-color:rgba(153,27,27,.55);box-shadow:none;transform:translateY(1px)}",
|
|
891
|
+
".pbb-actionDangerGhost:focus-visible{outline:2px solid rgba(220,38,38,.32);outline-offset:1px}",
|
|
892
|
+
".pbb-actionDangerGhost:disabled{cursor:default;opacity:.62}",
|
|
893
|
+
".pbb-actionIcon{flex:none;display:inline-block;vertical-align:-2px;margin-right:5px;pointer-events:none}",
|
|
894
|
+
".pbb-actionBusy{display:inline-flex;align-items:center;gap:6px}",
|
|
895
|
+
".pbb-actionBusy::before{content:\"\";width:9px;height:9px;border-radius:50%;border:1.5px solid rgba(220,38,38,.35);border-top-color:currentColor;animation:pbb-spin .7s linear infinite}",
|
|
896
|
+
"@keyframes pbb-spin{to{transform:rotate(360deg)}}",
|
|
888
897
|
".pbb-qrPanel{display:flex;flex-direction:column;align-items:center;gap:9px;padding:12px 0 4px}",
|
|
889
898
|
".pbb-qrImage{width:240px;height:240px;max-width:100%;background:#fff;border-radius:10px;padding:8px;box-sizing:border-box}",
|
|
890
899
|
".pbb-pairCodeBlock{width:min(100%,420px);display:flex;flex-direction:column;gap:5px}",
|
|
@@ -3411,6 +3420,21 @@ window.__ModuleLoader__.load({
|
|
|
3411
3420
|
}
|
|
3412
3421
|
//#endregion
|
|
3413
3422
|
//#region src/client/settings-page.ts
|
|
3423
|
+
/** Inline trash icon for the compact destructive row action. Kept as a tiny
|
|
3424
|
+
* element (no icon dependency) so the client bundle stays dependency-free
|
|
3425
|
+
* apart from React. */
|
|
3426
|
+
const TrashIcon = () => (0, react.createElement)("svg", {
|
|
3427
|
+
className: "pbb-actionIcon",
|
|
3428
|
+
viewBox: "0 0 16 16",
|
|
3429
|
+
width: 13,
|
|
3430
|
+
height: 13,
|
|
3431
|
+
fill: "none",
|
|
3432
|
+
stroke: "currentColor",
|
|
3433
|
+
strokeWidth: 1.5,
|
|
3434
|
+
strokeLinecap: "round",
|
|
3435
|
+
strokeLinejoin: "round",
|
|
3436
|
+
"aria-hidden": true
|
|
3437
|
+
}, (0, react.createElement)("path", { d: "M2.5 4.5h11" }), (0, react.createElement)("path", { d: "M6.5 2.5h3" }), (0, react.createElement)("path", { d: "M4 4.5l.6 8.2a1 1 0 0 0 1 .9h4.8a1 1 0 0 0 1-.9l.6-8.2" }), (0, react.createElement)("path", { d: "M6.6 7v4.2" }), (0, react.createElement)("path", { d: "M9.4 7v4.2" }));
|
|
3414
3438
|
async function writeClipboard(t, value) {
|
|
3415
3439
|
try {
|
|
3416
3440
|
await navigator.clipboard.writeText(value);
|
|
@@ -3754,10 +3778,11 @@ window.__ModuleLoader__.load({
|
|
|
3754
3778
|
const visibleDevices = report?.devices.filter((device) => device.revokedAt === void 0) ?? [];
|
|
3755
3779
|
const deviceTable = visibleDevices.length > 0 ? (0, react.createElement)("table", { className: "pbb-table" }, (0, react.createElement)("thead", null, (0, react.createElement)("tr", null, (0, react.createElement)("th", null, translateWith(props.t, "devices.col.name")), (0, react.createElement)("th", null, translateWith(props.t, "devices.col.fingerprint")), (0, react.createElement)("th", null, translateWith(props.t, "devices.col.lastSeen")), (0, react.createElement)("th", null, translateWith(props.t, "devices.col.actions")))), (0, react.createElement)("tbody", null, visibleDevices.map((d) => (0, react.createElement)("tr", { key: d.deviceId }, (0, react.createElement)("td", null, d.deviceName, (0, react.createElement)("div", { className: "pbb-diag" }, d.appVersion)), (0, react.createElement)("td", null, (0, react.createElement)("code", { className: "pbb-token" }, d.fingerprint.slice(0, 12))), (0, react.createElement)("td", null, new Date(d.lastSeenTs).toLocaleString()), (0, react.createElement)("td", null, (0, react.createElement)("button", {
|
|
3756
3780
|
type: "button",
|
|
3757
|
-
className: "pbb-action pbb-
|
|
3781
|
+
className: "pbb-action pbb-actionDangerGhost",
|
|
3758
3782
|
disabled: deviceBusy === d.deviceId,
|
|
3783
|
+
"aria-label": deviceBusy === d.deviceId ? translateWith(props.t, "devices.deleting", { name: d.deviceName }) : translateWith(props.t, "devices.revokeAria", { name: d.deviceName }),
|
|
3759
3784
|
onClick: () => revokeDevice(d.deviceId, d.deviceName)
|
|
3760
|
-
}, translateWith(props.t, "devices.revoke"))))))) : (0, react.createElement)("p", { className: "pbb-empty" }, translateWith(props.t, "devices.empty"));
|
|
3785
|
+
}, deviceBusy === d.deviceId ? null : TrashIcon(), deviceBusy === d.deviceId ? (0, react.createElement)("span", { className: "pbb-actionBusy" }, translateWith(props.t, "devices.deleting")) : translateWith(props.t, "devices.revoke"))))))) : (0, react.createElement)("p", { className: "pbb-empty" }, translateWith(props.t, "devices.empty"));
|
|
3761
3786
|
const switchTitle = translateWith(props.t, "master.title");
|
|
3762
3787
|
const switchDesc = switchReady ? enabled ? translateWith(props.t, "master.on") : translateWith(props.t, "master.off") : translateWith(props.t, "master.loading");
|
|
3763
3788
|
return (0, react.createElement)("div", { className: "pbb-section" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("h2", { className: "pbb-title" }, "DeepPilot"), (0, react.createElement)("div", { style: { flex: "1" } }), (0, react.createElement)("button", {
|