wherdr 2.4.0 → 2.6.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/.output/nitro.json +1 -1
- package/.output/public/_nuxt/{CPlkxpge.js → 2fsYF-LK.js} +41 -41
- package/.output/public/_nuxt/2fsYF-LK.js.br +0 -0
- package/.output/public/_nuxt/2fsYF-LK.js.gz +0 -0
- package/.output/public/_nuxt/{CV6ukk-M.js → 3bE7s96N.js} +1 -1
- package/.output/public/_nuxt/6YTlf8ot.js +1 -0
- package/.output/public/_nuxt/6YTlf8ot.js.br +0 -0
- package/.output/public/_nuxt/6YTlf8ot.js.gz +0 -0
- package/.output/public/_nuxt/{BYZVrreW.js → 7KozZy5Y.js} +1 -1
- package/.output/public/_nuxt/AgentView.BwyQIUef.css +1 -0
- package/.output/public/_nuxt/AgentView.BwyQIUef.css.br +0 -0
- package/.output/public/_nuxt/AgentView.BwyQIUef.css.gz +0 -0
- package/.output/public/_nuxt/{BdJIc1Xf.js → B40shTLf.js} +1 -1
- package/.output/public/_nuxt/{BdJIc1Xf.js.br → B40shTLf.js.br} +0 -0
- package/.output/public/_nuxt/B40shTLf.js.gz +0 -0
- package/.output/public/_nuxt/B5cSia3P.js +62 -0
- package/.output/public/_nuxt/B5cSia3P.js.br +0 -0
- package/.output/public/_nuxt/B5cSia3P.js.gz +0 -0
- package/.output/public/_nuxt/BK1_9FXg.js +1 -0
- package/.output/public/_nuxt/BK1_9FXg.js.br +0 -0
- package/.output/public/_nuxt/BK1_9FXg.js.gz +0 -0
- package/.output/public/_nuxt/{CgUSTIM1.js → Bqz3nVVB.js} +1 -1
- package/.output/public/_nuxt/{CgUSTIM1.js.br → Bqz3nVVB.js.br} +0 -0
- package/.output/public/_nuxt/Bqz3nVVB.js.gz +0 -0
- package/.output/public/_nuxt/{B2KlcBQ-.js → ByLPJEo6.js} +1 -1
- package/.output/public/_nuxt/ByLPJEo6.js.br +0 -0
- package/.output/public/_nuxt/ByLPJEo6.js.gz +0 -0
- package/.output/public/_nuxt/C8tHIeGN.js +3 -0
- package/.output/public/_nuxt/C8tHIeGN.js.br +0 -0
- package/.output/public/_nuxt/C8tHIeGN.js.gz +0 -0
- package/.output/public/_nuxt/CAkH_IfS.js +9 -0
- package/.output/public/_nuxt/CAkH_IfS.js.br +0 -0
- package/.output/public/_nuxt/CAkH_IfS.js.gz +0 -0
- package/.output/public/_nuxt/COWXF9OU.js +123 -0
- package/.output/public/_nuxt/COWXF9OU.js.br +0 -0
- package/.output/public/_nuxt/COWXF9OU.js.gz +0 -0
- package/.output/public/_nuxt/{BDTOz37p.js → CiG2Lovu.js} +1 -1
- package/.output/public/_nuxt/CiG2Lovu.js.br +0 -0
- package/.output/public/_nuxt/CiG2Lovu.js.gz +0 -0
- package/.output/public/_nuxt/CnjxEm0H.js +27 -0
- package/.output/public/_nuxt/CnjxEm0H.js.br +0 -0
- package/.output/public/_nuxt/CnjxEm0H.js.gz +0 -0
- package/.output/public/_nuxt/DNs2cMBZ.js +23 -0
- package/.output/public/_nuxt/DNs2cMBZ.js.br +0 -0
- package/.output/public/_nuxt/DNs2cMBZ.js.gz +0 -0
- package/.output/public/_nuxt/D_x7Rysx.js +31 -0
- package/.output/public/_nuxt/D_x7Rysx.js.br +0 -0
- package/.output/public/_nuxt/D_x7Rysx.js.gz +0 -0
- package/.output/public/_nuxt/{CLf2i_DM.js → T-qXNaMY.js} +1 -1
- package/.output/public/_nuxt/{board.fZYj3O-m.css → board.CpFnG_Ho.css} +1 -1
- package/.output/public/_nuxt/board.CpFnG_Ho.css.br +0 -0
- package/.output/public/_nuxt/board.CpFnG_Ho.css.gz +0 -0
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/e2ee8d99-6a6a-4754-934f-8b7dbecfcdcb.json +1 -0
- package/.output/public/_nuxt/entry.C_hImCpq.css +2 -0
- package/.output/public/_nuxt/entry.C_hImCpq.css.br +0 -0
- package/.output/public/_nuxt/entry.C_hImCpq.css.gz +0 -0
- package/.output/public/_nuxt/{settings.Cdb21nNw.css → settings.ycbeituV.css} +1 -1
- package/.output/public/_nuxt/settings.ycbeituV.css.br +0 -0
- package/.output/public/_nuxt/settings.ycbeituV.css.gz +0 -0
- package/.output/public/_nuxt/useViewport.D9mmYA6A.css +1 -0
- package/.output/public/_nuxt/useWorktrees.BWpb3OO0.css +1 -0
- package/.output/public/_nuxt/useWorktrees.BWpb3OO0.css.br +0 -0
- package/.output/public/_nuxt/useWorktrees.BWpb3OO0.css.gz +0 -0
- package/.output/public/sw.js +6 -2
- package/.output/server/chunks/_/branding.mjs +1 -1
- package/.output/server/chunks/_/fileDownload.mjs +1 -1
- package/.output/server/chunks/_/files.mjs +26 -3
- package/.output/server/chunks/_/machineOrder.mjs +1 -1
- package/.output/server/chunks/_/onboarding.mjs +1 -1
- package/.output/server/chunks/_/package.mjs +1 -1
- package/.output/server/chunks/_/plugins.mjs +1 -1
- package/.output/server/chunks/_/restart.mjs +1 -1
- package/.output/server/chunks/_/revoke.mjs +22 -0
- package/.output/server/chunks/_/selfupdate.mjs +2 -1
- package/.output/server/chunks/_/splitShell.mjs +42 -0
- package/.output/server/chunks/_/updates.mjs +18 -4
- package/.output/server/chunks/_/uploadHashes.mjs +46 -0
- package/.output/server/chunks/_/worktrees.mjs +1 -1
- package/.output/server/chunks/_/ws.mjs +3 -3
- package/.output/server/chunks/nitro/nitro.mjs +15815 -15082
- package/.output/server/chunks/raw/check-leaks.mjs +1 -1
- package/.output/server/chunks/raw/ci-browser-plan.mjs +5 -0
- package/.output/server/chunks/raw/engine-changes.mjs +5 -0
- package/.output/server/chunks/raw/engine-result.mjs +7 -0
- package/.output/server/chunks/raw/herdr-plugin.mjs +1 -1
- package/.output/server/chunks/raw/prerelease.mjs +1 -1
- package/.output/server/chunks/raw/test-affected.mjs +1 -1
- package/.output/server/chunks/routes/api/_..._.mjs +5 -5
- package/.output/server/chunks/routes/api/agents.post.mjs +5 -5
- package/.output/server/chunks/routes/api/ask-tab.post.mjs +5 -5
- package/.output/server/chunks/routes/api/attach.post.mjs +5 -5
- package/.output/server/chunks/routes/api/auth/disable.post.mjs +14 -7
- package/.output/server/chunks/routes/api/auth/lock-all.post.mjs +12 -6
- package/.output/server/chunks/routes/api/auth/lock.post.mjs +5 -5
- package/.output/server/chunks/routes/api/auth/login/options.post.mjs +7 -7
- package/.output/server/chunks/routes/api/auth/login/verify.post.mjs +5 -5
- package/.output/server/chunks/routes/api/auth/max-session.post.mjs +5 -5
- package/.output/server/chunks/routes/api/auth/register/options.post.mjs +5 -5
- package/.output/server/chunks/routes/api/auth/register/verify.post.mjs +5 -5
- package/.output/server/chunks/routes/api/auth/status.get.mjs +10 -10
- package/.output/server/chunks/routes/api/changes.get.mjs +6 -6
- package/.output/server/chunks/routes/api/chat/image.get.mjs +6 -6
- package/.output/server/chunks/routes/api/chat.get.mjs +20 -49
- package/.output/server/chunks/routes/api/choose.post.mjs +6 -6
- package/.output/server/chunks/routes/api/claude-setup.post.mjs +6 -6
- package/.output/server/chunks/routes/api/claude-statusline.post.mjs +6 -6
- package/.output/server/chunks/routes/api/clear-queued-input.post.mjs +6 -6
- package/.output/server/chunks/routes/api/close/status.get.mjs +6 -6
- package/.output/server/chunks/routes/api/close-preview.get.mjs +62 -0
- package/.output/server/chunks/routes/api/close.post.mjs +5 -5
- package/.output/server/chunks/routes/api/codex-update.post.mjs +6 -6
- package/.output/server/chunks/routes/api/commands.get.mjs +6 -6
- package/.output/server/chunks/routes/api/config.get.mjs +6 -6
- package/.output/server/chunks/routes/api/dirs.get.mjs +6 -6
- package/.output/server/chunks/routes/api/dismiss-stopped.post.mjs +6 -6
- package/.output/server/chunks/routes/api/dismiss.post.mjs +6 -6
- package/.output/server/chunks/routes/api/effort.post.mjs +6 -6
- package/.output/server/chunks/routes/api/efforts.get.mjs +6 -6
- package/.output/server/chunks/routes/api/file.post.mjs +6 -6
- package/.output/server/chunks/routes/api/files/download.get.mjs +5 -5
- package/.output/server/chunks/routes/api/files/download.head.mjs +5 -5
- package/.output/server/chunks/routes/api/files/read.get.mjs +6 -6
- package/.output/server/chunks/routes/api/files.get.mjs +6 -6
- package/.output/server/chunks/routes/api/health.get.mjs +5 -5
- package/.output/server/chunks/routes/api/input.post.mjs +6 -6
- package/.output/server/chunks/routes/api/interrupt.post.mjs +6 -6
- package/.output/server/chunks/routes/api/isgit.get.mjs +6 -6
- package/.output/server/chunks/routes/api/machine/awake.get.mjs +6 -6
- package/.output/server/chunks/routes/api/machine/awake.post.mjs +6 -6
- package/.output/server/chunks/routes/api/machine/order.get.mjs +5 -5
- package/.output/server/chunks/routes/api/machine/order.post.mjs +5 -5
- package/.output/server/chunks/routes/api/machine/reconnect.post.mjs +6 -6
- package/.output/server/chunks/routes/api/machine/rename.post.mjs +6 -6
- package/.output/server/chunks/routes/api/machine/status.post.mjs +6 -6
- package/.output/server/chunks/routes/api/menu-left.post.mjs +6 -6
- package/.output/server/chunks/routes/api/menu.post.mjs +6 -6
- package/.output/server/chunks/routes/api/model.post.mjs +6 -6
- package/.output/server/chunks/routes/api/models.get.mjs +6 -6
- package/.output/server/chunks/routes/api/nav.post.mjs +6 -6
- package/.output/server/chunks/routes/api/onboarding.get.mjs +5 -5
- package/.output/server/chunks/routes/api/onboarding.post.mjs +5 -5
- package/.output/server/chunks/routes/api/phone.get.mjs +6 -6
- package/.output/server/chunks/routes/api/phone.post.mjs +6 -6
- package/.output/server/chunks/routes/api/plugins/actions.get.mjs +5 -5
- package/.output/server/chunks/routes/api/plugins/invoke.post.mjs +5 -5
- package/.output/server/chunks/routes/api/plugins/projects.get.mjs +6 -6
- package/.output/server/chunks/routes/api/plugins/projects.post.mjs +6 -6
- package/.output/server/chunks/routes/api/prompt.post.mjs +6 -6
- package/.output/server/chunks/routes/api/push/devices.post.mjs +49 -0
- package/.output/server/chunks/routes/api/push/quiet.post.mjs +6 -6
- package/.output/server/chunks/routes/api/push/subscribe.post.mjs +8 -7
- package/.output/server/chunks/routes/api/push/test.post.mjs +6 -6
- package/.output/server/chunks/routes/api/push/unsubscribe.post.mjs +6 -6
- package/.output/server/chunks/routes/api/quotas.get.mjs +6 -6
- package/.output/server/chunks/routes/api/rename.post.mjs +5 -5
- package/.output/server/chunks/routes/api/requeue.post.mjs +6 -6
- package/.output/server/chunks/routes/api/restart.get.mjs +5 -5
- package/.output/server/chunks/routes/api/restart.post.mjs +5 -5
- package/.output/server/chunks/routes/api/reveal.post.mjs +6 -6
- package/.output/server/chunks/routes/api/screen-key.post.mjs +6 -6
- package/.output/server/chunks/routes/api/screen.get.mjs +6 -6
- package/.output/server/chunks/routes/api/search.get.mjs +6 -6
- package/.output/server/chunks/routes/api/seen.post.mjs +6 -6
- package/.output/server/chunks/routes/api/send-now.post.mjs +6 -6
- package/.output/server/chunks/routes/api/sessions.get.mjs +6 -6
- package/.output/server/chunks/routes/api/sessions.post.mjs +6 -6
- package/.output/server/chunks/routes/api/settings-tab.post.mjs +6 -6
- package/.output/server/chunks/routes/api/settings.get.mjs +6 -6
- package/.output/server/chunks/routes/api/settings.post.mjs +6 -6
- package/.output/server/chunks/routes/api/space.post.mjs +6 -6
- package/.output/server/chunks/routes/api/split-command.post.mjs +9 -44
- package/.output/server/chunks/routes/api/state.get.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/action.post.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/add.post.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/after.post.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/approve.post.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/archive-done.post.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/archived.get.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/autopilot.get.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/autopilot.post.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/board-settings.get.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/board-settings.post.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/coordinator.get.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/coordinator.post.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/describe.post.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/details.get.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/limit.post.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/links.get.mjs +7 -7
- package/.output/server/chunks/routes/api/tasks/models.get.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/pick.post.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/project.get.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/project.post.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/question.post.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/scheduled.get.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/settings.get.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/start.get.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/tell.post.mjs +6 -6
- package/.output/server/chunks/routes/api/tasks/transcript-image.get.mjs +47 -0
- package/.output/server/chunks/routes/api/tasks/transcript.get.mjs +48 -0
- package/.output/server/chunks/routes/api/tasks.get.mjs +6 -6
- package/.output/server/chunks/routes/api/unqueue.post.mjs +6 -6
- package/.output/server/chunks/routes/api/update/status.get.mjs +5 -5
- package/.output/server/chunks/routes/api/update.get.mjs +5 -5
- package/.output/server/chunks/routes/api/update.post.mjs +5 -5
- package/.output/server/chunks/routes/api/upload.post.mjs +6 -6
- package/.output/server/chunks/routes/api/worktrees/remove.post.mjs +5 -5
- package/.output/server/chunks/routes/api/worktrees.get.mjs +5 -5
- package/.output/server/chunks/routes/favicon.ico.get.mjs +5 -5
- package/.output/server/chunks/routes/icons/_name_.get.mjs +6 -6
- package/.output/server/chunks/routes/renderer.mjs +7 -7
- package/.output/server/chunks/routes/uploads/_...name_.get.mjs +6 -6
- package/.output/server/chunks/routes/ws/_..._.mjs +6 -6
- package/.output/server/chunks/routes/ws/events.mjs +6 -6
- package/.output/server/chunks/routes/ws/term.mjs +6 -6
- package/.output/server/chunks/virtual/precomputed.mjs +1 -1
- package/.output/server/index.mjs +6 -6
- package/.output/server/package.json +1 -1
- package/README.md +1 -1
- package/bin/lib/tailnet.d.mts +7 -4
- package/bin/lib/tailnet.mjs +76 -18
- package/bin/lib/updater.mjs +6 -0
- package/docs/README.md +4 -0
- package/docs/RELEASING.md +27 -5
- package/docs/configuration.md +3 -4
- package/docs/conversation.md +11 -3
- package/docs/design.md +1 -1
- package/docs/devices.md +28 -0
- package/docs/home.md +29 -0
- package/docs/installation.md +14 -5
- package/docs/networks.md +9 -4
- package/docs/notifications.md +7 -0
- package/docs/plugins.md +1 -1
- package/docs/quick-start.md +7 -6
- package/docs/quotas.md +10 -1
- package/docs/release-notes-2.5.0.md +25 -0
- package/docs/release-notes-2.6.0.md +29 -0
- package/docs/security.md +61 -11
- package/docs/troubleshooting.md +4 -0
- package/package.json +1 -1
- package/skills/wherdr/SKILL.md +21 -0
- package/.output/public/_nuxt/AgentView.B12D6ccj.css +0 -1
- package/.output/public/_nuxt/AgentView.B12D6ccj.css.br +0 -0
- package/.output/public/_nuxt/AgentView.B12D6ccj.css.gz +0 -0
- package/.output/public/_nuxt/B2KlcBQ-.js.br +0 -0
- package/.output/public/_nuxt/B2KlcBQ-.js.gz +0 -0
- package/.output/public/_nuxt/BDTOz37p.js.br +0 -0
- package/.output/public/_nuxt/BDTOz37p.js.gz +0 -0
- package/.output/public/_nuxt/BGD5AamG.js +0 -25
- package/.output/public/_nuxt/BGD5AamG.js.br +0 -0
- package/.output/public/_nuxt/BGD5AamG.js.gz +0 -0
- package/.output/public/_nuxt/BdJIc1Xf.js.gz +0 -0
- package/.output/public/_nuxt/BxlzUs1i.js +0 -23
- package/.output/public/_nuxt/BxlzUs1i.js.br +0 -0
- package/.output/public/_nuxt/BxlzUs1i.js.gz +0 -0
- package/.output/public/_nuxt/C-BDzEtI.js +0 -3
- package/.output/public/_nuxt/C-BDzEtI.js.br +0 -0
- package/.output/public/_nuxt/C-BDzEtI.js.gz +0 -0
- package/.output/public/_nuxt/CO4sDeSt.js +0 -62
- package/.output/public/_nuxt/CO4sDeSt.js.br +0 -0
- package/.output/public/_nuxt/CO4sDeSt.js.gz +0 -0
- package/.output/public/_nuxt/CPlkxpge.js.br +0 -0
- package/.output/public/_nuxt/CPlkxpge.js.gz +0 -0
- package/.output/public/_nuxt/CTPNZj4T.js +0 -9
- package/.output/public/_nuxt/CTPNZj4T.js.br +0 -0
- package/.output/public/_nuxt/CTPNZj4T.js.gz +0 -0
- package/.output/public/_nuxt/CgUSTIM1.js.gz +0 -0
- package/.output/public/_nuxt/CwurhZnh.js +0 -123
- package/.output/public/_nuxt/CwurhZnh.js.br +0 -0
- package/.output/public/_nuxt/CwurhZnh.js.gz +0 -0
- package/.output/public/_nuxt/D7fCPncR.js +0 -1
- package/.output/public/_nuxt/D7fCPncR.js.br +0 -0
- package/.output/public/_nuxt/D7fCPncR.js.gz +0 -0
- package/.output/public/_nuxt/DFe-cDm2.js +0 -1
- package/.output/public/_nuxt/DFe-cDm2.js.br +0 -0
- package/.output/public/_nuxt/DFe-cDm2.js.gz +0 -0
- package/.output/public/_nuxt/Dpe9TNcA.js +0 -31
- package/.output/public/_nuxt/Dpe9TNcA.js.br +0 -0
- package/.output/public/_nuxt/Dpe9TNcA.js.gz +0 -0
- package/.output/public/_nuxt/board.fZYj3O-m.css.br +0 -0
- package/.output/public/_nuxt/board.fZYj3O-m.css.gz +0 -0
- package/.output/public/_nuxt/builds/meta/75cc4ea7-3027-463a-aa3e-29e474ed7173.json +0 -1
- package/.output/public/_nuxt/entry.KNdllmoL.css +0 -2
- package/.output/public/_nuxt/entry.KNdllmoL.css.br +0 -0
- package/.output/public/_nuxt/entry.KNdllmoL.css.gz +0 -0
- package/.output/public/_nuxt/settings.Cdb21nNw.css.br +0 -0
- package/.output/public/_nuxt/settings.Cdb21nNw.css.gz +0 -0
package/docs/configuration.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[Documentation](README.md) · [Project](../README.md)
|
|
4
4
|
|
|
5
5
|
- **Themes**: wherdr Titanium (default), herdr.dev and Herdr's built-in themes, or follow your Herdr theme.
|
|
6
|
-
|
|
6
|
+
English interface.
|
|
7
7
|
|
|
8
8
|
## Configuration
|
|
9
9
|
|
|
@@ -20,7 +20,7 @@ native service (read at each start: `wherdr restart`, or **R** in the panel).
|
|
|
20
20
|
| `TAILNET_REFRESH_MS` | `30000` | How often wherdr reads again what `tailscale serve` publishes for its port. |
|
|
21
21
|
| `HERDR_WEB_ALLOWED_HOSTS` | *(empty)* | Additional hostnames or IP addresses allowed to open the app, comma-separated. |
|
|
22
22
|
| `PASSKEY_USER` | `wherdr` | User name stored with the passkeys. |
|
|
23
|
-
| `DATA_DIR` | `./data` | VAPID keys, push subscriptions, passkeys, recent folders, and `settings.json`: the display settings that follow you across devices (theme, machine bar and groups, home list, Board and file browser preferences). Screen-dependent ones (content width, sidebar width, terminal size and rendering), the
|
|
23
|
+
| `DATA_DIR` | `./data` | VAPID keys, push subscriptions, passkeys, recent folders, and `settings.json`: the display settings that follow you across devices (theme, machine bar and groups, home list, Board and file browser preferences). Screen-dependent ones (content width, sidebar width, terminal size and rendering), the last tab or filter and drafts stay in each browser. |
|
|
24
24
|
| `HERDR_BIN` | `~/.local/bin/herdr`, else `herdr` in `PATH` | Herdr binary. |
|
|
25
25
|
| `HERDR_WEB_SESSION` | *(default session)* | Named Herdr session to drive. Not `HERDR_SESSION`, which Herdr reads itself. |
|
|
26
26
|
| `HERDR_PROJECTS_DATA_DIR` | `~/.herdr-projects/data` | herdr-projects' data folder, where wherdr reads the `PATH` it recorded ([Agent PATH](installation.md#agent-path)). |
|
|
@@ -34,8 +34,7 @@ native service (read at each start: `wherdr restart`, or **R** in the panel).
|
|
|
34
34
|
| `TZ` | `UTC` | Time zone. |
|
|
35
35
|
|
|
36
36
|
In the app, **Settings** holds display preferences such as theme, typing effect and what the
|
|
37
|
-
home screen shows; these follow you across devices through `settings.json`.
|
|
38
|
-
notifications, terminal text size and renderer remain device-specific. The passkey lock is
|
|
37
|
+
home screen shows; these follow you across devices through `settings.json`. Notifications, terminal text size and renderer remain device-specific. The passkey lock is
|
|
39
38
|
managed under Settings › Security.
|
|
40
39
|
|
|
41
40
|
## Paste diagnostics
|
package/docs/conversation.md
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
A command the agent proposes (shell code block, or inline `! command`) can be copied without
|
|
9
9
|
its prompt, or run in the agent's shell mode (`!`, Claude Code, Codex and omp) after you
|
|
10
10
|
confirm the full command.
|
|
11
|
+
- **SVG diagrams**: complete code fences labelled `svg` render as isolated, theme-aware images. **Source / Preview**, beside **Copy** in the card header, switches the same card between the diagram and its original markup; **Copy** always copies that markup. Click or use Enter/Space on the image for the existing full-screen viewer. Static shapes, text and local definitions are supported, up to 150,000 source characters, 2,000 source elements and 10,000 expanded reference instances. Incomplete, unsupported or unsafe diagrams stay readable code. Scripts, foreign HTML, animation and external resources are rejected; raw inline SVG is not inserted into the page. Other fence languages and file-explorer document fences remain code.
|
|
11
12
|
- **Interactive agent screens**: in a conversation, an uncertain menu or panel opens the
|
|
12
13
|
pane's real terminal in a modal window, with arrows, Enter, Escape, Tab, digits and y/n.
|
|
13
14
|
The rest of the app waits behind a scrim (the window fills the screen on a phone); in a
|
|
@@ -39,6 +40,14 @@
|
|
|
39
40
|
pane and opens a new one for the same agent (the same conversation, or the same herdr-projects
|
|
40
41
|
coordinator or task, as after `coordinator restart`), the view moves to the new pane and the
|
|
41
42
|
draft comes along. A pane closed for good keeps it under its banner, with **Copy draft**.
|
|
43
|
+
- **omp context**: beside the model, plain text shows a whole-number percentage and
|
|
44
|
+
estimated tokens in uppercase `K`. Select it for the window, original percentage,
|
|
45
|
+
estimate details and terminal status; no separate status row is added. Estimates use
|
|
46
|
+
omp's rounded percentage, not cumulative token consumption. Unknown readings stay hidden.
|
|
47
|
+
Working panes refresh even when not selected; unviewed resting panes retain their reading.
|
|
48
|
+
Failed or gauge-free reads are marked as last known. On touch screens, context details
|
|
49
|
+
appear with the model picker when the composer expands. Escape closes details without
|
|
50
|
+
stopping the agent.
|
|
42
51
|
- **Model and effort pickers** for Claude Code, Codex and omp (omp: its
|
|
43
52
|
"Switch Model" selector, `/switch` or `/model`, and its thinking level, changed with its own
|
|
44
53
|
⇧⇥ cycle). Changes apply **to the current session only**; wherdr never changes your default
|
|
@@ -100,7 +109,7 @@ same lines as text, a fallback if the tokens misbehave. The message sent is the
|
|
|
100
109
|
|
|
101
110
|
A **closed question**, one that yes or no answers in full, also gets **Yes** and **No** next to
|
|
102
111
|
its `↳` (at the end of its row in the list style). A tap refers to the question and writes the
|
|
103
|
-
answer under it
|
|
112
|
+
answer under it (`Yes` or `No`), exactly as Reply and typing would; nothing is sent, so several questions can be
|
|
104
113
|
answered in a row before sending. On a computer a click hands the field the focus, the caret
|
|
105
114
|
right after the answer, so Enter sends it at once; the keyboard stays down on a phone, and a
|
|
106
115
|
button pressed with the keyboard keeps the focus. Tapping the other answer
|
|
@@ -115,8 +124,7 @@ them, gets a panel right under it: **OK to all** refers to the whole table and w
|
|
|
115
124
|
under it (a second tap takes it back), and each row has **Yes**, **No** and `↳`, which refer to
|
|
116
125
|
the row by its number and write `Yes` or `No` under it, or nothing for an answer in words; a row
|
|
117
126
|
that asks an open question has `↳` alone. Every answer names the message and the row, even for
|
|
118
|
-
the last message: the agent may write another one before you send.
|
|
119
|
-
`Non`. Here too everything is composed in the field and you send; on a computer the field takes the focus
|
|
127
|
+
the last message: the agent may write another one before you send. Here too everything is composed in the field and you send; on a computer the field takes the focus
|
|
120
128
|
after a click, so Enter sends. A table qualifies when it has a
|
|
121
129
|
number column (a header `#`, `N°`, `No`, `Num`, `ID` or `Q` over short numbers, each once) and a
|
|
122
130
|
question column, known by its header (`Question`, `Decision`, `Choix`…), by cells that all end
|
package/docs/design.md
CHANGED
|
@@ -97,7 +97,7 @@ implementations.
|
|
|
97
97
|
## Text and layout checks
|
|
98
98
|
|
|
99
99
|
Follow [Contributing: Conventions](../CONTRIBUTING.md#conventions) for English
|
|
100
|
-
|
|
100
|
+
only interface text and `t()` / `tl()` usage; French translations are optional. Do not duplicate
|
|
101
101
|
those translation rules here. Examples: the translated Send label in
|
|
102
102
|
[Composer.vue](../app/components/Composer.vue) and Back in
|
|
103
103
|
[AgentView.vue](../app/components/AgentView.vue).
|
package/docs/devices.md
CHANGED
|
@@ -38,6 +38,30 @@
|
|
|
38
38
|
|
|
39
39
|
### On a phone
|
|
40
40
|
|
|
41
|
+
- **Compact agent header**: a 44 px bar holds Back, one two-line identity, Terminal and Options.
|
|
42
|
+
The identity shows the pane name, then its square state indicator, state label and agent kind.
|
|
43
|
+
Tap it (always available, even for a lone pane) for the machine/space context and everything
|
|
44
|
+
that manages panes and tabs: switching (listed only when there are several; a lone pane shows its
|
|
45
|
+
full name and state instead), then the current
|
|
46
|
+
pane (rename, split, move, swap, copy ID, then **Close this conversation** or **Close this
|
|
47
|
+
terminal**: only that pane, from either view) and the current tab (rename, new tab, tab
|
|
48
|
+
overview). **Close entire space…** stands apart, and only when the space holds other panes: a
|
|
49
|
+
lone pane has a single close, whose confirmation says the space closes too. A tab closes from its
|
|
50
|
+
overview, which says how many panes go. Every close confirmation names what stops, how many tabs
|
|
51
|
+
and panes go and what stays open; if the structure changes while it is open and the close would
|
|
52
|
+
now take more, the updated confirmation is shown again. Long names ellipsize; multiple panes
|
|
53
|
+
show their position, never 1/1.
|
|
54
|
+
Options keeps the conversation, the agent and its tools: Terminal/Conversation, search,
|
|
55
|
+
notifications, changes, files, plugin actions, take control, restart, reconnect and settings.
|
|
56
|
+
- **Terminal function keys** start closed. The square chevron button above Send shows or hides
|
|
57
|
+
one horizontally scrolling row in both Conversation and Terminal. It holds Ctrl, Esc, Tab,
|
|
58
|
+
arrows, Enter, Ctrl+C, Backspace and the remaining modifiers and function keys. The phone-keyboard
|
|
59
|
+
toggle comes first, and Home, End, PgUp, PgDn, Insert and Delete are available in both modes.
|
|
60
|
+
In Conversation the keyboard toggle focuses the message field, and navigation uses the
|
|
61
|
+
named-key API without opening a terminal connection.
|
|
62
|
+
Select Shift then Tab for Shift+Tab. Closing the bar clears any armed modifier.
|
|
63
|
+
The input stays on one row at rest and expands while editing. Desktop and tablet layouts
|
|
64
|
+
keep their existing controls.
|
|
41
65
|
- **Installable app (PWA)** on iPhone and Android, with safe-area and keyboard handling.
|
|
42
66
|
- **Web Push notifications** when an agent finishes or needs you (with its question), and for
|
|
43
67
|
`herdr notification show` (plugins, scripts).
|
|
@@ -45,6 +69,10 @@
|
|
|
45
69
|
- **Split tabs on a small screen**: a plan of the tab's panes in Herdr's proportions, then each
|
|
46
70
|
pane full screen with a mini-map and swipe to its neighbours.
|
|
47
71
|
- **Terminal key bar** (Esc, Enter, arrows, Shift+Tab, Ctrl+C…) and touch scrolling.
|
|
72
|
+
On iPhone and iPad a tap on the terminal does not open the on-screen keyboard: type in the
|
|
73
|
+
message field, or tap the key bar's keyboard button to type in the terminal.
|
|
74
|
+
Terminal links back to this app stay in the current window on a phone; external
|
|
75
|
+
links still open separately.
|
|
48
76
|
- **Offline reading** of the last known state and of recently opened conversations.
|
|
49
77
|
|
|
50
78
|
### On an iPad
|
package/docs/home.md
CHANGED
|
@@ -23,6 +23,9 @@
|
|
|
23
23
|
the first 2.0 load; turning it on again is kept. Other agents
|
|
24
24
|
also use dense rows, with a last-answer preview in normal mode; waiting agents keep their
|
|
25
25
|
questions and one-tap answers in both modes.
|
|
26
|
+
omp cards show context usage as a thin bottom-border line, without changing row height or
|
|
27
|
+
click targets. Open the conversation for percentage and estimated-token details. Resting
|
|
28
|
+
panes retain their last reading; unknown readings stay hidden.
|
|
26
29
|
With [herdr-projects](board.md#works-great-with-herdr-projects), the board's spaces follow Herdr's sidebar:
|
|
27
30
|
the Coordinators on top, then one group per repo, headed by its project coordinator (the repo's
|
|
28
31
|
name, the wherdr mark, **Coordinator** and its state), a bar that folds the group and sums up its
|
|
@@ -59,3 +62,29 @@ cards remain the default. Board tasks and repository headers keep their existing
|
|
|
59
62
|
grouping, and **Show terminals** still controls plain terminal rows. The setting
|
|
60
63
|
follows you across devices. Workspace drag reordering is disabled in this view;
|
|
61
64
|
switch it off to reorder spaces.
|
|
65
|
+
|
|
66
|
+
## What the counters count
|
|
67
|
+
|
|
68
|
+
The three counters at the top of the home (**Your turn**, **Working**, **Ready**) count the
|
|
69
|
+
rows of the list under them: **one row, one count**, in the state that row shows. The counters,
|
|
70
|
+
the rows' state (their badge, accent and place in their group), the repo bar and the machine
|
|
71
|
+
bar's numbers all come from the same functions (`taskStat`, `memberStat` and `countedPanes` in
|
|
72
|
+
`shared/boardLinks.ts`, `homeCounts` in `shared/homeCounts.ts`).
|
|
73
|
+
|
|
74
|
+
- **A Board task** counts once, by its state on the Board, whatever helpers (reviewer, planner,
|
|
75
|
+
attempts) it has open and in however many spaces. **Needs you** and **Ready to approve** are
|
|
76
|
+
**Your turn**: you must act. A task ready to approve keeps its *Ready to approve* label, but its
|
|
77
|
+
badge and row accent use the Your turn colour, and it sits with the tasks waiting for you. A
|
|
78
|
+
task that waits for you still counts once its agent has exited or its space was closed.
|
|
79
|
+
**Working** is the Board's working group (reviews and checks included); **To do** and
|
|
80
|
+
**Done** are Ready.
|
|
81
|
+
- **A coordinator** (the Board's, a machine's or a project's) is a row with its own state square:
|
|
82
|
+
it counts by that state, like any agent row. The repo bar's summary (`3 TASKS · 1 YOUR TURN`)
|
|
83
|
+
is the one exception: it counts the repo's tasks only, since its coordinator's row and state
|
|
84
|
+
sit right above it.
|
|
85
|
+
- **A row standing for several terminals** (a space with several agents, its card showing their
|
|
86
|
+
number) counts once, in the state the row shows: its most urgent terminal. With Settings ›
|
|
87
|
+
Appearance › Home screen › **Individual agents** on, each agent is a row, and a count. A
|
|
88
|
+
space shared by several tasks, or by a coordinator and other agents, is split into one row per
|
|
89
|
+
task or agent, and counts the same way.
|
|
90
|
+
- Each counter's number uses its own state colour, that of its legend square.
|
package/docs/installation.md
CHANGED
|
@@ -58,7 +58,7 @@ The script ([read it first](https://wherdr.dev/install), source in
|
|
|
58
58
|
Mac with Homebrew, otherwise the official Node.js 22 build from nodejs.org, its checksum
|
|
59
59
|
checked, unpacked in `~/wherdr/node` (used by wherdr only: your `PATH` is not changed). With
|
|
60
60
|
musl libc (Alpine) it gives the install links instead;
|
|
61
|
-
4. runs `herdr plugin install afloury/wherdr --yes`: the [Herdr plugin](plugins.md#install-as-a-herdr-plugin)
|
|
61
|
+
4. runs `herdr plugin install afloury/wherdr --ref 2.x --yes`: the [Herdr plugin](plugins.md#install-as-a-herdr-plugin)
|
|
62
62
|
downloads the GitHub release package of its version (checksum checked, no wait for npm),
|
|
63
63
|
installs it in `~/wherdr/app`, starts it on `http://localhost:7683`, opens the setup guide in
|
|
64
64
|
your browser (first install) and binds **prefix+i** to its panel;
|
|
@@ -87,7 +87,7 @@ Settings, as environment variables (`curl -fsSL https://wherdr.dev/install | WHE
|
|
|
87
87
|
| `WHERDR_SERVICE` | — | `off`: no login service; wherdr then starts with Herdr only (the plugin's startup hook). |
|
|
88
88
|
| `WHERDR_YES` | — | `1` answers yes to every question (non-interactive use), installing Node.js included. |
|
|
89
89
|
| `WHERDR_NO_BROWSER` | — | `1` never opens a browser. |
|
|
90
|
-
| `WHERDR_REF` |
|
|
90
|
+
| `WHERDR_REF` | `2.x` | Git tag or branch of the plugin (`2.x` is the wherdr 2 release branch). |
|
|
91
91
|
| `WHERDR_PLUGIN` | `afloury/wherdr` | A local checkout to link and build instead (development, tests). |
|
|
92
92
|
|
|
93
93
|
Update: run the command again (it offers the update), **U** in the wherdr panel, or **Update** in
|
|
@@ -134,6 +134,13 @@ home screen and in Settings › About, with the release notes and the exact comm
|
|
|
134
134
|
Hide it until the next version with ×. Set `WHERDR_UPDATE_CHECK=off` to disable the check. The
|
|
135
135
|
installed version is shown in Settings › About.
|
|
136
136
|
|
|
137
|
+
Updates stay within the running major version: wherdr 2 only offers 2.x releases, and the
|
|
138
|
+
one-tap update refuses to install a new major. When wherdr 3 is published, the home screen shows
|
|
139
|
+
a **“wherdr 3 is out”** card instead of the banner, with its release notes, its migration guide and a
|
|
140
|
+
Copy button for the command that installs wherdr 3 **beside** wherdr 2 (it only prints its plan
|
|
141
|
+
until you add `--yes`). wherdr 2 keeps running with its data, and 2.x fixes are still offered in
|
|
142
|
+
Settings › About.
|
|
143
|
+
|
|
137
144
|
GitHub release packages (including the bundled agent skill) and Homebrew
|
|
138
145
|
updates are published without waiting for npm moderation. Native plugin installs and updates
|
|
139
146
|
use the GitHub `.tgz` and verify its SHA-256 checksum before extraction. A failed one-tap
|
|
@@ -142,7 +149,9 @@ GitHub first, then the prebuilt npm package of the exact same version (with its
|
|
|
142
149
|
This also keeps older 1.3.x releases without GitHub archives installable with Node.js or Bun.
|
|
143
150
|
Packages predating the bundled skill retain the plugin checkout's commands and skill, so
|
|
144
151
|
skill refresh, installation and uninstallation remain available.
|
|
145
|
-
The installer fetches `
|
|
152
|
+
The installer fetches the `2.x` branch unless you set `WHERDR_REF`. The plugin update command
|
|
153
|
+
adds `--ref 2.x`, and a git checkout follows `2.x` (`git checkout 2.x`) before pulling: `main`
|
|
154
|
+
holds wherdr 3.
|
|
146
155
|
|
|
147
156
|
The SHA-256 checksum detects damaged downloads. It is served beside the archive, so someone
|
|
148
157
|
who can replace both files can make them match; it does not prove the publisher’s identity
|
|
@@ -175,10 +184,10 @@ and the app says so. Every step is logged in `~/wherdr/update.log`.
|
|
|
175
184
|
| Setup | Update command (in the wherdr folder) |
|
|
176
185
|
| --- | --- |
|
|
177
186
|
| The one command | Run `curl -fsSL https://wherdr.dev/install \| sh` again: it offers the update (GitHub release package) |
|
|
178
|
-
| Herdr plugin, Node.js | **U** in the **wherdr** panel, or `herdr plugin install afloury/wherdr --yes` (wherdr restarts on the new version) |
|
|
187
|
+
| Herdr plugin, Node.js | **U** in the **wherdr** panel, or `herdr plugin install afloury/wherdr --ref 2.x --yes` (wherdr restarts on the new version) |
|
|
179
188
|
| `wherdr` command (npm) | `npm install -g wherdr@latest && wherdr restart` (npx: stop it, then `npx wherdr@latest`) |
|
|
180
189
|
| `wherdr` command (Homebrew) | `brew upgrade wherdr`, then `brew services restart wherdr` |
|
|
181
|
-
| From source | `git pull && npm ci && npm run build`, then restart wherdr |
|
|
190
|
+
| From source | `git checkout 2.x && git pull && npm ci && npm run build`, then restart wherdr |
|
|
182
191
|
|
|
183
192
|
Update notices also show the number of newer stable releases and up to four
|
|
184
193
|
additional version numbers besides the latest. This measures published releases,
|
package/docs/networks.md
CHANGED
|
@@ -26,7 +26,10 @@ tailscale serve --bg --https=7683 http://127.0.0.1:7683
|
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Tailscale Serve listens on HTTPS port 7683 of your tailnet name, with a valid certificate, and
|
|
29
|
-
forwards to wherdr's local HTTP port. Only devices of your tailnet can reach it
|
|
29
|
+
forwards to wherdr's local HTTP port. Only devices of your tailnet can reach it, and wherdr
|
|
30
|
+
answers only **your own** devices among them: another user's device in a team tailnet, a node
|
|
31
|
+
shared in from another tailnet or a tagged node is refused until you set up a passkey (see
|
|
32
|
+
[Your own devices only](security.md#own-devices)).
|
|
30
33
|
|
|
31
34
|
**wherdr enables that address by itself**, on a server without a screen too: at startup, every
|
|
32
35
|
30 seconds, and when an address it does not know yet is opened, it reads what `tailscale serve`
|
|
@@ -59,9 +62,11 @@ desktop layout can replace the Herdr terminal client for daily work.
|
|
|
59
62
|
**5. Passkey lock** (optional): Settings → Security → **Enable passkey lock**. The
|
|
60
63
|
first passkey asks for a bootstrap token, printed in the server log (`~/wherdr/wherdr.log`,
|
|
61
64
|
**L** in the wherdr panel); it changes on each restart and is only needed for that first passkey. Add a passkey on each of
|
|
62
|
-
your devices after that (see [New device](security.md#new-device)). Without one,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
your devices after that (see [New device](security.md#new-device)). Without one, wherdr
|
|
66
|
+
answers this computer and your own tailnet devices; devices of other people on your tailnet are
|
|
67
|
+
always refused (with a passkey, they reach the lock screen). A passkey adds an automatic lock on
|
|
68
|
+
each device if you want one, for example on a computer other people log in to (see
|
|
69
|
+
[Shared computers](security.md#shared-computers)).
|
|
65
70
|
|
|
66
71
|
**6. More machines** (optional): register your other computers in Herdr over SSH
|
|
67
72
|
(`herdr machine add`, see [Several machines (SSH)](machines.md#several-machines-ssh)). Their agents show
|
package/docs/notifications.md
CHANGED
|
@@ -52,6 +52,13 @@ The screen reads top to bottom:
|
|
|
52
52
|
others). Each says how it differs from the default; removing one goes back to it.
|
|
53
53
|
4. **This device's notifications** only asks this browser or phone for permission to
|
|
54
54
|
show push notifications, and shows whether it is allowed, blocked or not asked yet.
|
|
55
|
+
Below it, every registered device is listed with the result of the last push sent to it:
|
|
56
|
+
delivered, expired (404/410: the browser dropped the subscription), rejected (401/403),
|
|
57
|
+
push service unreachable, or failed with its HTTP status. Each device keeps its own result,
|
|
58
|
+
so one device's success never hides another's failure. An expired device is no longer
|
|
59
|
+
tried; **Remove** forgets it (otherwise it goes away on its own after 30 days). Only the
|
|
60
|
+
time, the class and the status code are stored in `data/push.json`, never the push
|
|
61
|
+
service's response.
|
|
55
62
|
|
|
56
63
|
A coordinator's exception is kept by its identity (machine, Herdr session, level and
|
|
57
64
|
repo), not its pane: it still applies after `coordinator new` or a restart.
|
package/docs/plugins.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
This is what [the one command](installation.md#the-one-command) installs; you can also run it yourself, on Linux
|
|
8
8
|
and macOS, with Herdr ≥ 0.9.1 (no checks for Herdr or Node.js first). In three lines:
|
|
9
9
|
|
|
10
|
-
1. Run `herdr plugin install afloury/wherdr`: it installs wherdr, starts it
|
|
10
|
+
1. Run `herdr plugin install afloury/wherdr --ref 2.x`: it installs wherdr, starts it
|
|
11
11
|
(`✓ wherdr is running → http://localhost:7683`) and, at the first install on a computer with a
|
|
12
12
|
screen, opens the setup guide in your browser (`open` on macOS, `xdg-open` on Linux with a
|
|
13
13
|
display; a headless server, or `WHERDR_NO_BROWSER=1` in the environment of the install, just
|
package/docs/quick-start.md
CHANGED
|
@@ -33,20 +33,21 @@ address and the phone steps instead. See [The one command](installation.md#the-o
|
|
|
33
33
|
|
|
34
34
|
**wherdr 2.0 runs only natively**, as your user, so it can act on the
|
|
35
35
|
[herdr-projects Board](board.md#works-great-with-herdr-projects) (Coordinator, reply, start, stop,
|
|
36
|
-
approve). Other ways, after it: `herdr plugin install afloury/wherdr` (the same plugin, without
|
|
36
|
+
approve). Other ways, after it: `herdr plugin install afloury/wherdr --ref 2.x` (the same plugin, without
|
|
37
37
|
the checks), and [the `wherdr` command](command.md#the-wherdr-command) from npm or Homebrew (npm can hold a
|
|
38
38
|
new release for up to two days; the installer gets it from GitHub at once).
|
|
39
39
|
|
|
40
40
|
At first launch, wherdr opens a **setup guide**: the Herdr agents it found, your phone
|
|
41
|
-
(Tailscale), then
|
|
41
|
+
(Tailscale), then notifications. Skip it any time; finishing or skipping is
|
|
42
42
|
saved on the server (`data/onboarding.json`), so your other devices do not show it again. Reopen
|
|
43
43
|
it from Settings › About › **Setup guide**. On a phone that already opens wherdr through its
|
|
44
44
|
tailnet address, the phone step becomes Add to Home Screen.
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
Once wherdr's tailnet address is published and answers, the guide opened on `localhost` shows
|
|
47
|
+
**Continue on <machine>.<tailnet>.ts.net**, which reopens it at the same step on that address
|
|
48
|
+
(notifications and the installed app need it). The guide does not propose a passkey: the
|
|
49
|
+
optional passkey lock is in Settings › Security, which also sends it to that address, since
|
|
50
|
+
**passkeys are tied to the address they are created on**. Nothing redirects on its own:
|
|
50
51
|
`localhost` stays valid on the computer. The installer, the Herdr plugin and `wherdr open` open
|
|
51
52
|
that address too when it is already published.
|
|
52
53
|
|
package/docs/quotas.md
CHANGED
|
@@ -30,7 +30,16 @@ week, with reset times), for every online machine.
|
|
|
30
30
|
|
|
31
31
|
- **Codex**: nothing to do, Codex writes its limits in its session files. Machines on different
|
|
32
32
|
Codex accounts get one block each (told apart by a short hash of the account ID found in the
|
|
33
|
-
session files; `~/.codex/auth.json` is never read).
|
|
33
|
+
session files; `~/.codex/auth.json` is never read). Codex only writes that account ID in
|
|
34
|
+
conversations created with a ChatGPT login by a recent Codex version. A reading without it
|
|
35
|
+
joins another machine's reading only when both show the same 5-hour window and the same
|
|
36
|
+
weekly window (resets within a minute, week already started), a sign of one account: the
|
|
37
|
+
machines then share one Codex row at the top, like Claude. Otherwise it stays under its own
|
|
38
|
+
machine and is never merged with another conversation or machine. A new conversation identifies an account switch even before it
|
|
39
|
+
logs limits; until a reading for that account is available, no Codex gauge is shown. Failed reads do not
|
|
40
|
+
reuse an older machine snapshot, and remembered weekly limits cannot cross account
|
|
41
|
+
identities. Without a known fingerprint, remembered weekly corrections are not reused,
|
|
42
|
+
even on the same machine. Session files are read from `~/.codex/sessions`.
|
|
34
43
|
- **Claude Code** only gives them to its status line. On each machine, install wherdr's
|
|
35
44
|
invisible status line (it displays nothing, and chains to your existing status line if you
|
|
36
45
|
have one):
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
## New
|
|
2
|
+
|
|
3
|
+
You can choose the order of the phone key bar in Settings › Terminal, with a preview and a reset to the default. The order is saved on the device and shared by Conversation and Terminal. Thanks to [@followcat](https://github.com/followcat) for the idea.
|
|
4
|
+
|
|
5
|
+
Notification settings show each registered device's last push delivery result and let you remove expired registrations.
|
|
6
|
+
|
|
7
|
+
## Improved
|
|
8
|
+
|
|
9
|
+
The interface is always in English, including on browsers previously set to French. Messages written by you and your agents keep their original language. The phone header chevron has a full-size button box, and desktop view switching uses a single action button.
|
|
10
|
+
|
|
11
|
+
The agent skill explains how to share verified links that users can open. Focused unit and component coverage replaces repeated browser cases, CI shards phone tests, and full develop coverage runs nightly. Develop prereleases are built only from commits that passed CI.
|
|
12
|
+
|
|
13
|
+
## Fixed
|
|
14
|
+
|
|
15
|
+
After a server restart, machines recover independently and existing panes remain visible until their machine has been read or confirmed offline. Codex quota readings stay with the correct account, and Home WORKING counters follow Board groups without counting remote tasks twice.
|
|
16
|
+
|
|
17
|
+
On iPhone and iPad, tapping the terminal keeps the keyboard closed; the message field and keyboard button still open it. Phone navigation returns from tasks to the Board, wherdr links reuse the existing window, and closing a terminal no longer falsely reports that its process stopped.
|
|
18
|
+
|
|
19
|
+
Conversation images can load from other machines and ports on the same tailnet, with an explanation and an open link when loading fails. Codex photo placeholders no longer appear as message text, older explicitly resumed conversations can be found, and current Codex sessions no longer show a false restart-to-update notice. omp provider errors now appear in the conversation, and coordinators can be found by conversation after their pane closes.
|
|
20
|
+
|
|
21
|
+
## Update
|
|
22
|
+
|
|
23
|
+
No migration is required from 2.4.0. Node.js 22 or newer and Herdr 0.9.1 or newer remain required. The Board continues to support herdr-projects 1.2.x, not Shepherdr 2.x.
|
|
24
|
+
|
|
25
|
+
[Full changelog](https://github.com/afloury/wherdr/blob/v2.5.0/CHANGELOG.md)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
## New
|
|
2
|
+
|
|
3
|
+
2.6 is the last new version of wherdr 2. It gets you ready for wherdr 3, which installs **beside** wherdr 2 rather than replacing it.
|
|
4
|
+
|
|
5
|
+
- **Updates stay on wherdr 2.** The update check only offers 2.x versions. When wherdr 3 is published, the Update button never installs it, and wherdr 2 fixes (2.6.1, 2.6.2…) are still offered.
|
|
6
|
+
- **A "wherdr 3 is out" card.** Once wherdr 3 is released, Home shows a card instead of the update banner, with links to its release notes and its migration guide, and a Copy button for the command that installs wherdr 3 beside this version. That command shows its plan first and changes nothing until you add `--yes`. wherdr 2 keeps running with its data, so you can compare both and go back at any time.
|
|
7
|
+
- **Installs follow the 2.x branch.** The Herdr plugin now updates from the `2.x` branch (**U** in the panel, and the update command, add `--ref 2.x`), and the curl installer installs `2.x` by default (`WHERDR_REF` still picks another branch or tag). If you run wherdr from a git checkout, switch it to the release branch once with `git checkout 2.x` before pulling; the update banner shows that command.
|
|
8
|
+
- **SVG diagrams in conversations.** A static `svg` code block shows as a theme-aware preview you can enlarge or copy; unsafe or incomplete content stays plain code. Thanks to [@guileen](https://github.com/guileen).
|
|
9
|
+
- **omp context at a glance.** Agent rows and the composer show how much of omp's context is used.
|
|
10
|
+
|
|
11
|
+
## Improved
|
|
12
|
+
|
|
13
|
+
- **Tighter security on the tailnet.** Without a passkey, only your own Tailscale devices can open wherdr; another user's device in a team tailnet, or a shared-in or tagged node, is refused until a passkey is set. A locked device learns nothing before unlocking (no passkey names, machine name or server clock). **Lock all devices** now invalidates every session, push subscription and open connection at once.
|
|
14
|
+
- **Lighter conversation reads.** While an agent writes, wherdr reads only what was added to its transcript.
|
|
15
|
+
|
|
16
|
+
## Fixed
|
|
17
|
+
|
|
18
|
+
- A finished task's Agent tab shows the agent's conversation instead of the shell left behind.
|
|
19
|
+
- Conversations reopen at their reading position, are not redrawn when nothing changed, and keep a sent message visible while reads fail for a while.
|
|
20
|
+
- A repeated Enter (from a dictation app, for example) no longer sends the same message twice, and a single stray Escape no longer stops the agent.
|
|
21
|
+
- Home counters and badges agree on task states, the Board grouping appears right after a reload, and two machines on one Codex account share one quota row.
|
|
22
|
+
- Reconnecting after a suspend or a redeploy no longer hangs on a stalled read.
|
|
23
|
+
- On macOS, when wherdr runs as a service, Settings › Phone no longer says *not connected* while Tailscale runs, and Web Push works.
|
|
24
|
+
|
|
25
|
+
## Update
|
|
26
|
+
|
|
27
|
+
No migration is required from 2.5.0. Node.js 22 or newer and Herdr 0.9.1 or newer remain required. Git checkouts: run `git checkout 2.x` once before your next `git pull`.
|
|
28
|
+
|
|
29
|
+
[Full changelog](https://github.com/afloury/wherdr/blob/v2.6.0/CHANGELOG.md)
|
package/docs/security.md
CHANGED
|
@@ -10,7 +10,7 @@ wherdr drives Herdr, so **it can run anything as your user**.
|
|
|
10
10
|
network** (Tailscale or [equivalent](networks.md#other-private-networks)). Never add a public route
|
|
11
11
|
(port forwarding, public reverse proxy, ngrok…); the only exception is a Cloudflare Tunnel
|
|
12
12
|
behind Cloudflare Access, with its risks (it needs `WHERDR_TRUSTED_NETWORKS=any`).
|
|
13
|
-
- It answers only this computer and
|
|
13
|
+
- It answers only this computer and your own tailnet devices: see [Network access](security.md#network-access).
|
|
14
14
|
- Requests are accepted only for `localhost`, loopback addresses, the runtime's hostname, the
|
|
15
15
|
hostname in `APP_URL`, the tailnet name `tailscale serve` publishes for wherdr's own port
|
|
16
16
|
(read from Tailscale on the machine, never from a request, and only while it is published),
|
|
@@ -29,21 +29,48 @@ wherdr drives Herdr, so **it can run anything as your user**.
|
|
|
29
29
|
|
|
30
30
|
A network error or a server restart never locks the app. **Lock all devices** (Settings →
|
|
31
31
|
Security, for a lost or stolen device) ends every session, this one included, and keeps the
|
|
32
|
-
passkeys: each device unlocks again with its own.
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
passkeys: each device unlocks again with its own. It draws a new signing secret and a new random
|
|
33
|
+
session generation, so even a cookie forged by someone who once read `data/auth.json` stops
|
|
34
|
+
working; open WebSockets close at once, and every push subscription is removed (a device
|
|
35
|
+
subscribes again by itself once unlocked; its own quiet setting is reset). Turning the lock off
|
|
36
|
+
does the same and removes the passkeys; every open app then posts its push subscription again
|
|
37
|
+
at once, and an app that was closed or asleep does so when it opens or reconnects. The first start after upgrading to this version ends the open
|
|
38
|
+
sessions once (the old numeric generation is replaced); the passkeys stay. Lost passkey: delete
|
|
39
|
+
`data/auth.json` on the server; the app is open again to whoever can reach it.
|
|
40
|
+
- **Before the unlock**, a locked device only learns that the app is locked: no passkey names or
|
|
41
|
+
dates, no machine name, no server clock. Unlocking lists no key: the device offers its own
|
|
42
|
+
passkey for the site (passkeys are registered as discoverable credentials). Unlock attempts
|
|
43
|
+
are limited to 10 per minute per client, and at most 100 unlock challenges wait at once.
|
|
44
|
+
- **Protected files**: the file browser and the file paths shown in conversations never preview,
|
|
45
|
+
download or stream wherdr's data folder (`DATA_DIR`, with `auth.json`, the push keys and
|
|
46
|
+
subscriptions), `~/.ssh` or `~/.config/herdr`, on any machine, even through a symlink or inside
|
|
47
|
+
a browsed project. Agents themselves can still read them: the lock protects the app, not the
|
|
48
|
+
machine.
|
|
35
49
|
- <a id="new-device"></a>**New device**: it can only get in with an existing passkey. Unlock it
|
|
36
50
|
with a passkey synced by your password manager (iCloud Keychain, Google Password Manager,
|
|
37
51
|
1Password…), or with the passkey of another device through the browser's "use a phone or
|
|
38
52
|
tablet" QR code, then Settings → Security → **Add this device** to give it its own passkey.
|
|
39
|
-
-
|
|
40
|
-
on your tailnet
|
|
53
|
+
- By default, with no passkey, wherdr answers **this computer and your own tailnet devices**:
|
|
54
|
+
devices of other people on your tailnet are always filtered out (no setting turns this off).
|
|
55
|
+
Whoever uses this computer or one of your devices can control your agents, other OS users of
|
|
56
|
+
this computer included (see [Shared computers](security.md#shared-computers)). The passkey is
|
|
57
|
+
optional: it adds an automatic lock on each device if you want one, and then lets other
|
|
58
|
+
people's tailnet devices reach that lock.
|
|
41
59
|
- Writes require `Content-Type: application/json` (or `image/*` for photos, `application/octet-stream` for attached files) and an `Origin`
|
|
42
|
-
matching the host, WebSockets included.
|
|
60
|
+
matching the host, WebSockets included. Request bodies are read with a size limit (256 KB for
|
|
61
|
+
JSON, 20 MB for photos, 30 MB for attached files), chunked bodies included: past it the server
|
|
62
|
+
stops reading, answers `too_large` and closes the connection. API reads sent from another site (links, images,
|
|
43
63
|
`no-cors` fetches, reported by the browser's `Sec-Fetch-Site`) are refused too.
|
|
44
64
|
- A strict Content Security Policy limits scripts to the app's own origin and hashed inline
|
|
45
65
|
scripts, and connections to that origin and its WebSockets. It also blocks embedded objects
|
|
46
66
|
and framing.
|
|
67
|
+
- Images in agent replies load from the app's own origin (`data:` and `blob:` included) and,
|
|
68
|
+
over HTTPS only, from any machine and port of the tailnet wherdr is reached on
|
|
69
|
+
(`https://*.<tailnet>.ts.net:*`). That tailnet is read from Tailscale on the machine, from
|
|
70
|
+
`APP_URL`, from `HERDR_WEB_ALLOWED_HOSTS` and from what `tailscale serve` publishes, never from
|
|
71
|
+
a request; a name outside `*.ts.net` adds nothing. Any other image (public sites, another
|
|
72
|
+
tailnet, plain HTTP, Tailscale IP addresses) is refused by the browser and shown as a note with
|
|
73
|
+
a link to open it in a new tab.
|
|
47
74
|
- wherdr never changes your agents' global settings: model and effort changes are for the
|
|
48
75
|
current session only.
|
|
49
76
|
|
|
@@ -51,17 +78,19 @@ See [SECURITY.md](../SECURITY.md) to report a vulnerability.
|
|
|
51
78
|
|
|
52
79
|
### Network access
|
|
53
80
|
|
|
54
|
-
wherdr answers **this computer and your tailnet only**. A device on any other network (a coffee shop
|
|
81
|
+
wherdr answers **this computer and your own tailnet devices only**. A device on any other network (a coffee shop
|
|
55
82
|
Wi-Fi, an office LAN, the Internet) gets HTTP 403 (`network`), with a page that says why, even
|
|
56
|
-
when it knows the address and the port. The passkey lock is never required
|
|
57
|
-
is an extra lock on top, and it needs HTTPS (or `localhost`).
|
|
83
|
+
when it knows the address and the port. The passkey lock is never required for this computer
|
|
84
|
+
and your own devices: it is an extra lock on top, and it needs HTTPS (or `localhost`). Other
|
|
85
|
+
people's tailnet devices get in only once a passkey is set up (see below).
|
|
58
86
|
|
|
59
87
|
**Good practices**
|
|
60
88
|
|
|
61
89
|
- Prefer **Tailscale** (`tailscale serve`): a private HTTPS address, only for your devices.
|
|
62
90
|
- A network you add **without HTTPS** gets no passkey, no installed app and no notifications, and
|
|
63
91
|
any device on that network can control your agents.
|
|
64
|
-
- **
|
|
92
|
+
- **Passkey** (optional, over HTTPS): an automatic lock on each device, if you want one. Your
|
|
93
|
+
own devices get in without it.
|
|
65
94
|
|
|
66
95
|
How a request is judged, before anything else (WebSockets included):
|
|
67
96
|
|
|
@@ -74,6 +103,20 @@ How a request is judged, before anything else (WebSockets included):
|
|
|
74
103
|
reads that from Tailscale every 10 seconds (the CLI or Tailscale's socket); an
|
|
75
104
|
interface address in that range proves nothing, since a LAN may use it too. When Tailscale is
|
|
76
105
|
stopped, missing or unreadable for 30 seconds, no direct connection counts as tailnet.
|
|
106
|
+
- <a id="own-devices"></a>*Your own devices only*: a peer counts when Tailscale lists it under
|
|
107
|
+
the same user as this machine (`UserID`), is not tagged, and is not a node of someone you
|
|
108
|
+
shared this machine with (`ShareeNode`). Every other peer is refused with HTTP 403 (`network`, `why: foreign`) while
|
|
109
|
+
no passkey is set up: another user's device in a team tailnet, a machine someone
|
|
110
|
+
[shared](https://tailscale.com/kb/1084/sharing) with you (it belongs to another user), a
|
|
111
|
+
device of someone you shared this machine with, a tagged node (tagged devices
|
|
112
|
+
belong to no user, your own tagged servers included). When the machine running wherdr is
|
|
113
|
+
itself tagged, its owner is unknown: no peer counts as yours, so only this computer gets in
|
|
114
|
+
until a passkey is set up. The same rule applies to the client `tailscale serve` names in
|
|
115
|
+
`X-Forwarded-For`: without a passkey, it must be one of your devices in the latest reading
|
|
116
|
+
(a device that joined in the last seconds, or any device while Tailscale cannot be read, is
|
|
117
|
+
refused). The other peers are remembered from the last valid reading, so a failed reading
|
|
118
|
+
does not let them in. Once a passkey is set up, they are let through to the lock screen and
|
|
119
|
+
need that passkey like any device.
|
|
77
120
|
- **Proxy headers**, only when the peer is this computer (a proxy on the machine, such as
|
|
78
121
|
`tailscale serve`): every address in `X-Forwarded-For`, `Forwarded`, `X-Real-IP`,
|
|
79
122
|
`CF-Connecting-IP` must be loopback, the tailnet or a trusted range too. They can only refuse
|
|
@@ -99,6 +142,13 @@ How a request is judged, before anything else (WebSockets included):
|
|
|
99
142
|
loopback or this machine's tailnet address as Tailscale reports it, with Tailscale running
|
|
100
143
|
(`HOST=0.0.0.0`, a LAN address), and says how to fix it.
|
|
101
144
|
|
|
145
|
+
> [!IMPORTANT]
|
|
146
|
+
> <a id="shared-computers"></a>**Every user of this computer counts as this computer.** Loopback
|
|
147
|
+
> connections are not tied to an OS user: on a machine where other people have an account (a
|
|
148
|
+
> shared server, a lab machine), any of them can open `http://127.0.0.1:7683/` and control
|
|
149
|
+
> your agents. wherdr keeps loopback open so you can always reach it on your own machine. On a
|
|
150
|
+
> machine others log in to, the optional passkey locks loopback too.
|
|
151
|
+
|
|
102
152
|
> [!IMPORTANT]
|
|
103
153
|
> **A relay on this computer counts as this computer.** A reverse proxy or TCP forward you run
|
|
104
154
|
> on the machine (nginx without forwarded headers, `socat`, an SSH tunnel, a tunnel client) opens
|
package/docs/troubleshooting.md
CHANGED
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
- **HTTP 403 "wherdr only answers this computer and your tailnet"**: the device is on another
|
|
21
21
|
network (Wi-Fi, LAN). Open wherdr through Tailscale, or name that private network in
|
|
22
22
|
`WHERDR_TRUSTED_NETWORKS` ([Network access](security.md#network-access)).
|
|
23
|
+
- **HTTP 403 "This device is not one of the owner's"**: Tailscale lists the device under another
|
|
24
|
+
user (a team tailnet), as shared in from another tailnet, or as a tagged node. Without a passkey,
|
|
25
|
+
wherdr only answers your own devices: log that device in to Tailscale with your own account, or
|
|
26
|
+
set up a passkey ([Your own devices only](security.md#own-devices)).
|
|
23
27
|
- **HTTP 403 "Tailscale Funnel opens wherdr to the Internet"**: turn Funnel off for wherdr’s port (`tailscale funnel status`).
|
|
24
28
|
- **wherdr stops at startup with "Refusing to listen on …"**: `HOST` is not loopback nor this
|
|
25
29
|
machine's tailnet address. Set `HOST=127.0.0.1` and use `tailscale serve`, or see
|
package/package.json
CHANGED
package/skills/wherdr/SKILL.md
CHANGED
|
@@ -30,6 +30,27 @@ So a message from the Board is the user's own words: answer and act on it as on
|
|
|
30
30
|
from them. Report your progress with `herdr-projects report` as usual: the Board shows the
|
|
31
31
|
state, the message and the progress you report, the pull request and the review.
|
|
32
32
|
|
|
33
|
+
## Links
|
|
34
|
+
|
|
35
|
+
- **Files:** verify that the file exists and is readable on the agent's machine, then
|
|
36
|
+
write its absolute path in inline code (backticks), optionally with `:line` or
|
|
37
|
+
`:line:column` (these suffixes are stripped, not navigated to). Chat recognizes
|
|
38
|
+
paths; Markdown file links do not use its file viewer. `~/` means that machine's
|
|
39
|
+
home; relative paths use the pane's working folder, falling back to home when
|
|
40
|
+
unknown or outside home. Never use a path relative to another folder (such as a
|
|
41
|
+
vault). The file and its symlink target must stay inside that machine's home.
|
|
42
|
+
Terminal links open only HTTP(S) URLs, not file paths.
|
|
43
|
+
- **Web:** give an absolute HTTPS URL reachable from the user's phone and other
|
|
44
|
+
machines (for example through their tailnet). Never offer localhost, loopback
|
|
45
|
+
addresses (including `127.0.0.1`) or relative URLs as portable links. Follow
|
|
46
|
+
redirects and verify a successful HTTP status and the final destination; a local
|
|
47
|
+
response alone does not prove access from another device.
|
|
48
|
+
- **Images:** prefer displaying them directly in chat (web images must come from
|
|
49
|
+
wherdr's own origin or an HTTPS tailnet address). For an image URL, verify
|
|
50
|
+
that the final response serves the image itself with an `image/*` Content-Type,
|
|
51
|
+
rather than an HTML page.
|
|
52
|
+
- If no verified link is available, say so clearly instead of offering a broken one.
|
|
53
|
+
|
|
33
54
|
## What the Board does not do
|
|
34
55
|
|
|
35
56
|
No task is added, delegated, stopped, archived or cleared from wherdr: the user asks the
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.header-menu[data-v-562a5bfa]{display:contents}.grid-backdrop[data-v-a290ab6b]{z-index:-1;pointer-events:none;contain:strict;overflow:hidden}.gbd-dots[data-v-a290ab6b],.grid-backdrop[data-v-a290ab6b]{position:absolute;inset:0}.gbd-dots[data-v-a290ab6b]{background-image:radial-gradient(circle at 32px 32px,color-mix(in srgb,var(--muted) 60%,transparent) 1.4px,transparent 2.2px),linear-gradient(color-mix(in srgb,var(--line) 30%,transparent) 1px,transparent 1px),linear-gradient(90deg,color-mix(in srgb,var(--line) 30%,transparent) 1px,transparent 1px),radial-gradient(ellipse 50% 40% at 50% 25%,color-mix(in srgb,var(--accent) 6%,transparent),transparent 75%);background-position:calc(50% - 32px) -32px,top,top,0 0;background-size:64px 64px,64px 64px,64px 64px,100% 100%;-webkit-mask:radial-gradient(85% 75% at 50% 35%,#000 25%,#00000073 60%,#0000 88%);mask:radial-gradient(85% 75% at 50% 35%,#000 25%,#00000073 60%,#0000 88%)}.gbd-packets[data-v-a290ab6b]{position:absolute;inset:0;-webkit-mask:radial-gradient(70% 60% at 50% 30%,#000 30%,#0000 75%);mask:radial-gradient(70% 60% at 50% 30%,#000 30%,#0000 75%)}.gbd-packets[data-v-a290ab6b] .pkt{will-change:transform,opacity;--c:var(--accent);display:block;position:absolute}.gbd-packets[data-v-a290ab6b] .pkt.alt{--c:var(--lav)}.gbd-packets[data-v-a290ab6b] .pkt.h{background:linear-gradient(90deg,transparent,var(--c));width:56px;height:1px;margin-left:-56px}.gbd-packets[data-v-a290ab6b] .pkt.h.rev{background:linear-gradient(270deg,transparent,var(--c));margin-left:0}.gbd-packets[data-v-a290ab6b] .pkt.h:after{content:"";background:var(--c);width:6px;height:5px;box-shadow:0 0 10px var(--c);position:absolute;top:-2px;right:-3px}.gbd-packets[data-v-a290ab6b] .pkt.h.rev:after{left:-3px;right:auto}.gbd-packets[data-v-a290ab6b] .pkt.v{background:linear-gradient(180deg,transparent,var(--c));width:1px;height:56px;margin-top:-56px}.gbd-packets[data-v-a290ab6b] .pkt.v.rev{background:linear-gradient(0deg,transparent,var(--c));margin-top:0}.gbd-packets[data-v-a290ab6b] .pkt.v:after{content:"";background:var(--c);width:5px;height:6px;box-shadow:0 0 10px var(--c);position:absolute;bottom:-3px;left:-2px}.gbd-packets[data-v-a290ab6b] .pkt.v.rev:after{top:-3px;bottom:auto}.gbd-vignette[data-v-a290ab6b]{background:linear-gradient(to right,var(--bg),transparent 14%,transparent 86%,var(--bg)),linear-gradient(to bottom,var(--bg),transparent 18%,transparent 70%,var(--bg));position:absolute;inset:0}.xterm{cursor:text;-webkit-user-select:none;user-select:none;position:relative}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{z-index:5;position:absolute;top:0}.xterm .xterm-helper-textarea{opacity:0;z-index:-5;white-space:nowrap;resize:none;border:0;width:0;height:0;margin:0;padding:0;position:absolute;top:0;left:-9999em;overflow:hidden}.xterm .composition-view{color:#fff;white-space:nowrap;z-index:1;background:#000;display:none;position:absolute}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{cursor:default;background-color:#000;position:absolute;inset:0;overflow-y:scroll}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;top:0;left:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{visibility:hidden;line-height:normal;display:inline-block;position:absolute;top:0;left:-9999em}.xterm.enable-mouse-events{cursor:default}.xterm .xterm-cursor-pointer,.xterm.xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{z-index:10;color:#0000;pointer-events:none;position:absolute;inset:0}.xterm .xterm-accessibility-tree:not(.debug) ::-moz-selection{color:#0000}.xterm .xterm-accessibility-tree:not(.debug) ::selection{color:#0000}.xterm .xterm-accessibility-tree{-webkit-user-select:text;user-select:text;white-space:pre}.xterm .live-region{width:1px;height:1px;position:absolute;left:-9999px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{-webkit-text-decoration:underline double;text-decoration:underline double}.xterm-underline-3{-webkit-text-decoration:underline wavy;text-decoration:underline wavy}.xterm-underline-4{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.xterm-underline-5{-webkit-text-decoration:underline dashed;text-decoration:underline dashed}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:underline overline}.xterm-overline.xterm-underline-2{-webkit-text-decoration:overline double underline;-webkit-text-decoration:overline double underline;text-decoration:overline double underline}.xterm-overline.xterm-underline-3{-webkit-text-decoration:overline wavy underline;-webkit-text-decoration:overline wavy underline;text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{-webkit-text-decoration:overline dotted underline;-webkit-text-decoration:overline dotted underline;text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{-webkit-text-decoration:overline dashed underline;-webkit-text-decoration:overline dashed underline;text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;pointer-events:none;position:absolute;top:0;right:0}.xterm-decoration-top{z-index:2;position:relative}.key-modifier[aria-pressed=true][data-v-33673e53]{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}.usage-limit-card[data-v-8c0c9595]{border-top:1px solid var(--line);white-space:normal;text-align:left;color:var(--ochre);flex-wrap:wrap;justify-content:flex-start;padding-top:8px}.restart-text small[data-v-8c0c9595]{color:var(--muted);display:block}.dismissible-transcript-note[data-v-745f7953]{flex:none;align-items:center;gap:8px;padding:0 4px 0 12px;display:flex}.dismissible-transcript-note>span[data-v-745f7953]{flex:1;padding:7px 0}.dismissible-transcript-note>button[data-v-745f7953]{min-width:40px;min-height:40px;color:var(--muted);font:22px/1 var(--sans);touch-action:manipulation;border-radius:6px;flex:none;align-self:stretch}.dismissible-transcript-note>button[data-v-745f7953]:focus-visible,.dismissible-transcript-note>button[data-v-745f7953]:hover{color:var(--text);background:var(--line-soft)}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|