wherdr 1.3.3 → 2.0.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/BDNMzG2s.js +1 -0
- package/.output/public/_nuxt/BETID3_E.js +1 -0
- package/.output/public/_nuxt/BHenDMeH.js +1 -0
- package/.output/public/_nuxt/BYZVrreW.js +1 -0
- package/.output/public/_nuxt/BhgehRdJ.js +1 -0
- package/.output/public/_nuxt/{yzABg5xl.js → Bpoxvzh6.js} +1 -1
- package/.output/public/_nuxt/BtH82ZuZ.js +9 -0
- package/.output/public/_nuxt/C25ROUa9.js +3 -0
- package/.output/public/_nuxt/C3Bkn4ac.js +62 -0
- package/.output/public/_nuxt/CDWjMk9C.js +2 -0
- package/.output/public/_nuxt/{Ci8N4mWR.js → CXJnLmWv.js} +1 -1
- package/.output/public/_nuxt/CuUQ4mEf.js +1 -0
- package/.output/public/_nuxt/DFGEl0v2.js +23 -0
- package/.output/public/_nuxt/{CKhgznq4.js → DFmgQVme.js} +42 -39
- package/.output/public/_nuxt/DZGKxROq.js +6 -0
- package/.output/public/_nuxt/DmkWvmnE.js +2 -0
- package/.output/public/_nuxt/DrKKeFFE.js +31 -0
- package/.output/public/_nuxt/DyfFwwGq.js +1 -0
- package/.output/public/_nuxt/FaNto0ga.js +105 -0
- package/.output/public/_nuxt/NIF0VwHk.js +25 -0
- package/.output/public/_nuxt/R0Y4VoeX.js +1 -0
- package/.output/public/_nuxt/board.CEEcFc6M.css +1 -0
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/0b28b3e9-664e-4347-a35b-afb0a711d5c5.json +1 -0
- package/.output/public/_nuxt/entry.CKoXcwRa.css +2 -0
- package/.output/public/_nuxt/pdf.min.t82Z80JU.mjs +28 -0
- package/.output/public/_nuxt/pdf.worker.min.wgc6bjNh.mjs +28 -0
- package/.output/public/_nuxt/settings.Cdb21nNw.css +1 -0
- package/.output/public/sw.js +1 -1
- package/.output/server/chunks/_/branding.mjs +1 -1
- package/.output/server/chunks/_/changes.mjs +4 -4
- package/.output/server/chunks/_/fileDownload.mjs +278 -0
- package/.output/server/chunks/_/files.mjs +60 -20
- package/.output/server/chunks/_/machineOrder.mjs +1 -1
- package/.output/server/chunks/_/onboarding.mjs +1 -1
- package/.output/server/chunks/_/package.mjs +11 -3
- package/.output/server/chunks/_/plugins.mjs +92 -122
- package/.output/server/chunks/_/restart.mjs +1 -1
- package/.output/server/chunks/_/selfupdate.mjs +1 -1
- package/.output/server/chunks/_/settingstabs.mjs +36 -0
- package/.output/server/chunks/_/updates.mjs +1 -1
- package/.output/server/chunks/_/worktrees.mjs +1 -1
- package/.output/server/chunks/_/ws.mjs +43 -6
- package/.output/server/chunks/nitro/nitro.mjs +14126 -10238
- package/.output/server/chunks/raw/check-doc-links.mjs +5 -0
- package/.output/server/chunks/raw/check-leaks.mjs +1 -1
- package/.output/server/chunks/raw/check-release-notes.mjs +5 -0
- package/.output/server/chunks/raw/herdr-plugin.mjs +1 -1
- package/.output/server/chunks/raw/install-claude-statusline.mjs +1 -1
- package/.output/server/chunks/raw/prerelease-summary.mjs +5 -0
- package/.output/server/chunks/raw/prerelease.mjs +7 -0
- package/.output/server/chunks/raw/reveal.mjs +1 -1
- package/.output/server/chunks/raw/test-affected.mjs +5 -0
- package/.output/server/chunks/routes/api/_..._.mjs +6 -5
- package/.output/server/chunks/routes/api/agents.post.mjs +6 -5
- package/.output/server/chunks/routes/api/ask-tab.post.mjs +6 -5
- package/.output/server/chunks/routes/api/attach.post.mjs +6 -5
- package/.output/server/chunks/routes/api/auth/disable.post.mjs +6 -5
- package/.output/server/chunks/routes/api/auth/lock-all.post.mjs +6 -5
- package/.output/server/chunks/routes/api/auth/lock.post.mjs +6 -5
- package/.output/server/chunks/routes/api/auth/login/options.post.mjs +6 -5
- package/.output/server/chunks/routes/api/auth/login/verify.post.mjs +6 -5
- package/.output/server/chunks/routes/api/auth/max-session.post.mjs +6 -5
- package/.output/server/chunks/routes/api/auth/register/options.post.mjs +6 -5
- package/.output/server/chunks/routes/api/auth/register/verify.post.mjs +6 -5
- package/.output/server/chunks/routes/api/auth/status.get.mjs +6 -5
- package/.output/server/chunks/routes/api/changes.get.mjs +7 -6
- package/.output/server/chunks/routes/api/chat/image.get.mjs +7 -6
- package/.output/server/chunks/routes/api/chat.get.mjs +44 -11
- package/.output/server/chunks/routes/api/choose.post.mjs +44 -30
- package/.output/server/chunks/routes/api/claude-setup.post.mjs +42 -0
- package/.output/server/chunks/routes/api/claude-statusline.post.mjs +7 -6
- package/.output/server/chunks/routes/api/clear-queued-input.post.mjs +42 -0
- package/.output/server/chunks/routes/api/close/status.get.mjs +7 -6
- package/.output/server/chunks/routes/api/close.post.mjs +6 -5
- package/.output/server/chunks/routes/api/codex-update.post.mjs +7 -6
- package/.output/server/chunks/routes/api/commands.get.mjs +9 -7
- package/.output/server/chunks/routes/api/config.get.mjs +10 -13
- package/.output/server/chunks/routes/api/dirs.get.mjs +7 -6
- package/.output/server/chunks/routes/api/dismiss-stopped.post.mjs +7 -6
- package/.output/server/chunks/routes/api/dismiss.post.mjs +7 -6
- package/.output/server/chunks/routes/api/effort.post.mjs +7 -6
- package/.output/server/chunks/routes/api/efforts.get.mjs +7 -6
- package/.output/server/chunks/routes/api/file.post.mjs +7 -6
- package/.output/server/chunks/routes/api/files/download.get.mjs +12 -24
- package/.output/server/chunks/routes/api/files/download.head.mjs +41 -0
- package/.output/server/chunks/routes/api/files/read.get.mjs +8 -7
- package/.output/server/chunks/routes/api/files.get.mjs +7 -6
- package/.output/server/chunks/routes/api/health.get.mjs +6 -5
- package/.output/server/chunks/routes/api/input.post.mjs +33 -15
- package/.output/server/chunks/routes/api/interrupt.post.mjs +24 -21
- package/.output/server/chunks/routes/api/isgit.get.mjs +8 -8
- package/.output/server/chunks/routes/api/machine/awake.get.mjs +7 -6
- package/.output/server/chunks/routes/api/machine/awake.post.mjs +7 -6
- package/.output/server/chunks/routes/api/machine/order.get.mjs +6 -5
- package/.output/server/chunks/routes/api/machine/order.post.mjs +6 -5
- package/.output/server/chunks/routes/api/machine/reconnect.post.mjs +40 -0
- package/.output/server/chunks/routes/api/machine/rename.post.mjs +7 -6
- package/.output/server/chunks/routes/api/machine/status.post.mjs +39 -0
- package/.output/server/chunks/routes/api/menu-left.post.mjs +40 -0
- package/.output/server/chunks/routes/api/menu.post.mjs +10 -6
- package/.output/server/chunks/routes/api/model.post.mjs +7 -6
- package/.output/server/chunks/routes/api/models.get.mjs +7 -6
- package/.output/server/chunks/routes/api/nav.post.mjs +40 -26
- package/.output/server/chunks/routes/api/onboarding.get.mjs +6 -5
- package/.output/server/chunks/routes/api/onboarding.post.mjs +6 -5
- package/.output/server/chunks/routes/api/phone.get.mjs +8 -10
- package/.output/server/chunks/routes/api/phone.post.mjs +8 -10
- package/.output/server/chunks/routes/api/plugins/actions.get.mjs +6 -8
- package/.output/server/chunks/routes/api/plugins/invoke.post.mjs +6 -8
- package/.output/server/chunks/routes/api/plugins/projects.get.mjs +10 -8
- package/.output/server/chunks/routes/api/plugins/projects.post.mjs +11 -7
- package/.output/server/chunks/routes/api/prompt.post.mjs +22 -13
- package/.output/server/chunks/routes/api/push/quiet.post.mjs +7 -6
- package/.output/server/chunks/routes/api/push/subscribe.post.mjs +7 -7
- package/.output/server/chunks/routes/api/push/test.post.mjs +7 -6
- package/.output/server/chunks/routes/api/push/unsubscribe.post.mjs +7 -6
- package/.output/server/chunks/routes/api/quotas.get.mjs +7 -6
- package/.output/server/chunks/routes/api/rename.post.mjs +6 -5
- package/.output/server/chunks/routes/api/requeue.post.mjs +7 -6
- package/.output/server/chunks/routes/api/restart.get.mjs +6 -5
- package/.output/server/chunks/routes/api/restart.post.mjs +6 -5
- package/.output/server/chunks/routes/api/reveal.post.mjs +91 -8
- package/.output/server/chunks/routes/api/screen-key.post.mjs +19 -15
- package/.output/server/chunks/routes/api/screen.get.mjs +8 -40
- package/.output/server/chunks/routes/api/search.get.mjs +7 -6
- package/.output/server/chunks/routes/api/seen.post.mjs +7 -6
- package/.output/server/chunks/routes/api/sessions.get.mjs +7 -6
- package/.output/server/chunks/routes/api/sessions.post.mjs +7 -6
- package/.output/server/chunks/routes/api/settings-tab.post.mjs +90 -0
- package/.output/server/chunks/routes/api/{plugins/thread-limits.get.mjs → settings.get.mjs} +10 -9
- package/.output/server/chunks/routes/api/settings.post.mjs +40 -0
- package/.output/server/chunks/routes/api/space.post.mjs +34 -18
- package/.output/server/chunks/routes/api/state.get.mjs +7 -6
- package/.output/server/chunks/routes/api/tasks/action.post.mjs +39 -0
- package/.output/server/chunks/routes/api/{plugins/profiles.get.mjs → tasks/add.post.mjs} +12 -14
- package/.output/server/chunks/routes/api/tasks/after.post.mjs +39 -0
- package/.output/server/chunks/routes/api/tasks/approve.post.mjs +39 -0
- package/.output/server/chunks/routes/api/{project/report.get.mjs → tasks/archived.get.mjs} +12 -13
- package/.output/server/chunks/routes/api/{gitroot.get.mjs → tasks/autopilot.get.mjs} +13 -14
- package/.output/server/chunks/routes/api/tasks/autopilot.post.mjs +39 -0
- package/.output/server/chunks/routes/api/{index.get.mjs → tasks/board-settings.get.mjs} +12 -13
- package/.output/server/chunks/routes/api/tasks/board-settings.post.mjs +39 -0
- package/.output/server/chunks/routes/api/tasks/coordinator.get.mjs +40 -0
- package/.output/server/chunks/routes/api/tasks/coordinator.post.mjs +39 -0
- package/.output/server/chunks/routes/api/tasks/details.get.mjs +40 -0
- package/.output/server/chunks/routes/api/tasks/limit.post.mjs +39 -0
- package/.output/server/chunks/routes/api/tasks/links.get.mjs +39 -0
- package/.output/server/chunks/routes/api/tasks/models.get.mjs +40 -0
- package/.output/server/chunks/routes/api/tasks/pick.post.mjs +39 -0
- package/.output/server/chunks/routes/api/tasks/question.post.mjs +39 -0
- package/.output/server/chunks/routes/api/tasks/scheduled.get.mjs +40 -0
- package/.output/server/chunks/routes/api/{project → tasks}/settings.get.mjs +10 -11
- package/.output/server/chunks/routes/api/tasks/start.get.mjs +40 -0
- package/.output/server/chunks/routes/api/tasks/tell.post.mjs +39 -0
- package/.output/server/chunks/routes/api/tasks.get.mjs +39 -0
- package/.output/server/chunks/routes/api/unqueue.post.mjs +7 -6
- package/.output/server/chunks/routes/api/update/status.get.mjs +6 -5
- package/.output/server/chunks/routes/api/update.get.mjs +8 -10
- package/.output/server/chunks/routes/api/update.post.mjs +8 -10
- package/.output/server/chunks/routes/api/upload.post.mjs +7 -6
- package/.output/server/chunks/routes/api/worktrees/remove.post.mjs +6 -5
- package/.output/server/chunks/routes/api/worktrees.get.mjs +6 -5
- package/.output/server/chunks/routes/favicon.ico.get.mjs +6 -5
- package/.output/server/chunks/routes/icons/_name_.get.mjs +7 -6
- package/.output/server/chunks/routes/renderer.mjs +8 -7
- package/.output/server/chunks/routes/uploads/_...name_.get.mjs +7 -6
- package/.output/server/chunks/routes/ws/_..._.mjs +7 -6
- package/.output/server/chunks/routes/ws/events.mjs +9 -7
- package/.output/server/chunks/routes/ws/term.mjs +7 -6
- package/.output/server/chunks/virtual/precomputed.mjs +1 -1
- package/.output/server/index.mjs +7 -6
- package/.output/server/package.json +1 -1
- package/README.md +44 -1424
- package/bin/lib/commands.mjs +44 -9
- package/bin/lib/panel.mjs +3 -11
- package/bin/lib/service.mjs +41 -2
- package/bin/lib/skill.mjs +1 -1
- package/bin/lib/tailnet.d.mts +6 -3
- package/bin/lib/tailnet.mjs +70 -32
- package/bin/lib/userpath.d.mts +14 -0
- package/bin/lib/userpath.mjs +142 -0
- package/docs/README.md +58 -0
- package/docs/RELEASING.md +174 -0
- package/docs/board.md +164 -0
- package/docs/command.md +58 -0
- package/docs/configuration.md +39 -0
- package/docs/conversation.md +132 -0
- package/docs/development.md +38 -0
- package/docs/devices.md +58 -0
- package/docs/files.md +29 -0
- package/docs/herdr-projects-1x.md +278 -0
- package/docs/home.md +52 -0
- package/docs/installation.md +174 -0
- package/docs/machines.md +69 -0
- package/docs/migrate-from-1.x-docker.md +160 -0
- package/docs/networks.md +154 -0
- package/docs/notifications.md +83 -0
- package/docs/overview.md +71 -0
- package/docs/phone.md +26 -0
- package/docs/plugins.md +109 -0
- package/docs/quick-start.md +89 -0
- package/docs/quotas.md +65 -0
- package/docs/release-notes-2.0.0.md +84 -0
- package/docs/security.md +117 -0
- package/docs/terminal.md +15 -0
- package/docs/troubleshooting.md +45 -0
- package/package.json +11 -3
- package/skills/wherdr/SKILL.md +24 -167
- package/.output/public/_nuxt/B4Yk2tB1.js +0 -23
- package/.output/public/_nuxt/BBw_0a4M.js +0 -6
- package/.output/public/_nuxt/BSy6OCIY.js +0 -1
- package/.output/public/_nuxt/BX5PM2JQ.js +0 -1
- package/.output/public/_nuxt/BgPDnf2S.js +0 -1
- package/.output/public/_nuxt/BkOxQzbS.js +0 -2
- package/.output/public/_nuxt/CP8o925U.js +0 -1
- package/.output/public/_nuxt/CWwyK2XK.js +0 -2
- package/.output/public/_nuxt/CkbmecwS.js +0 -1
- package/.output/public/_nuxt/Cr3SrGky.js +0 -1
- package/.output/public/_nuxt/DAg9fiVh.js +0 -89
- package/.output/public/_nuxt/DT8qZ0Wv.js +0 -1
- package/.output/public/_nuxt/DaaJIRB3.js +0 -1
- package/.output/public/_nuxt/DcJi16XA.js +0 -1
- package/.output/public/_nuxt/SiL1FJ5s.js +0 -3
- package/.output/public/_nuxt/VpjCgSXu.js +0 -36
- package/.output/public/_nuxt/builds/meta/c735b6c0-1bd0-47d7-a208-d310f0a06287.json +0 -1
- package/.output/public/_nuxt/dPxB2L94.js +0 -89
- package/.output/public/_nuxt/entry.CGWKmYU3.css +0 -2
- package/.output/public/_nuxt/xYX85SPI.js +0 -1
- package/.output/server/chunks/_/pluginPolicy.mjs +0 -93
- package/.output/server/chunks/_/projectBoard.mjs +0 -366
- package/.output/server/chunks/_/projectDocs.mjs +0 -106
- package/.output/server/chunks/_/projectInbox.mjs +0 -135
- package/.output/server/chunks/_/projectThreads.mjs +0 -46
- package/.output/server/chunks/_/projectThreads2.mjs +0 -61
- package/.output/server/chunks/_/projectsActions.mjs +0 -143
- package/.output/server/chunks/_/projectsPlugin.mjs +0 -56
- package/.output/server/chunks/_/reveal.mjs +0 -115
- package/.output/server/chunks/raw/dev.wherdr.open.mjs +0 -7
- package/.output/server/chunks/raw/docker-entrypoint.mjs +0 -7
- package/.output/server/chunks/raw/install-host-open.mjs +0 -7
- package/.output/server/chunks/raw/wherdr-open.mjs +0 -7
- package/.output/server/chunks/routes/api/board.get.mjs +0 -147
- package/.output/server/chunks/routes/api/plugins/thread-limits.post.mjs +0 -45
- package/.output/server/chunks/routes/api/project/inbox.get.mjs +0 -43
- package/.output/server/chunks/routes/api/project/inbox.post.mjs +0 -43
- package/.output/server/chunks/routes/api/project/memory.get.mjs +0 -42
- package/.output/server/chunks/routes/api/project/routines.get.mjs +0 -43
- package/.output/server/chunks/routes/api/project/thread.get.mjs +0 -44
- package/.output/server/chunks/routes/api/project/thread.post.mjs +0 -45
- package/bin/install-docker-skill.sh +0 -20
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.notification-level[data-v-aa9b4e30]{flex-direction:column;gap:6px;min-width:0;display:flex}.notification-level select[data-v-aa9b4e30]{border:1px solid var(--line);background:var(--bg);max-width:100%;min-height:44px;color:var(--text);font:inherit;border-radius:0;padding:8px}.notification-level-hint[data-v-aa9b4e30]{color:var(--muted);font-size:12px}.notification-customize summary[data-v-aa9b4e30]{cursor:pointer;min-height:36px;color:var(--muted);align-items:center;gap:4px;font-size:13px;list-style:none;display:flex}.notification-customize summary[data-v-aa9b4e30]::-webkit-details-marker{display:none}.notification-chev[data-v-aa9b4e30]{transition:transform .15s}.notification-customize[open] .notification-chev[data-v-aa9b4e30]{transform:rotate(90deg)}.notification-events[data-v-aa9b4e30]{flex-wrap:wrap;gap:4px 18px;display:flex}.notification-events label[data-v-aa9b4e30]{align-items:center;gap:6px;min-height:44px;display:flex}.notification-events input[data-v-aa9b4e30]{accent-color:var(--accent)}.notification-rules .settings-toggle[data-v-aeafb17e]{gap:16px}.notification-rules .settings-toggle>span[data-v-aeafb17e]{flex:1;min-width:0}.notification-default[data-v-aeafb17e]>.notification-level{margin-bottom:8px}.notification-help[data-v-aeafb17e]{margin:8px 0 0;font-size:12px}.notification-rule[data-v-aeafb17e]{border:1px solid var(--line);flex-direction:column;gap:10px;min-width:0;margin:12px 0;padding:14px;display:flex}.notification-rule-head b[data-v-aeafb17e],.notification-rule-head small[data-v-aeafb17e]{overflow-wrap:anywhere;display:block}.notification-rule-head small[data-v-aeafb17e]{color:var(--muted);font:11px var(--mono);margin-bottom:4px}.notification-rule-head .notification-diff[data-v-aeafb17e]{font:12px var(--sans,inherit);margin:4px 0 0}.notification-rule .settings-action small[data-v-aeafb17e]{margin-left:auto;padding-left:8px;font-size:11px}.notification-add[data-v-aeafb17e]{margin-top:12px}.notification-picker[data-v-aeafb17e]{border:1px solid var(--line);flex-direction:column;gap:12px;margin-top:8px;padding:12px;display:flex}.notification-picker-group[data-v-aeafb17e]{flex-direction:column;gap:4px;display:flex}.notification-picker-group>small[data-v-aeafb17e]{color:var(--muted);font:11px var(--mono)}.notification-reset[data-v-aeafb17e]{margin-top:16px}
|
package/.output/public/sw.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
var sw = self;
|
|
16
16
|
var CACHE = "wherdr-v1";
|
|
17
17
|
var NETWORK_WAIT_MS = 3e3;
|
|
18
|
-
var PRECACHE = ["/", ...[{"revision":"e6a852ba6e2a724d2255af526cb04083","url":"manifest.webmanifest"},{"revision":"b1a14fab8c06784649bf26c636747a86","url":"manifest-en.webmanifest"},{"revision":null,"url":"_nuxt/
|
|
18
|
+
var PRECACHE = ["/", ...[{"revision":"e6a852ba6e2a724d2255af526cb04083","url":"manifest.webmanifest"},{"revision":"b1a14fab8c06784649bf26c636747a86","url":"manifest-en.webmanifest"},{"revision":null,"url":"_nuxt/wherdr-symbols.C1LsPKmg.woff2"},{"revision":null,"url":"_nuxt/wherdr-nerd-powerline.B_kAMxXr.woff2"},{"revision":null,"url":"_nuxt/wherdr-nerd-octicons.Hl4VEx8m.woff2"},{"revision":null,"url":"_nuxt/wherdr-nerd-material-4.CO_PudDR.woff2"},{"revision":null,"url":"_nuxt/wherdr-nerd-material-3.8xz7iX-Y.woff2"},{"revision":null,"url":"_nuxt/wherdr-nerd-material-2.C_flbBWO.woff2"},{"revision":null,"url":"_nuxt/wherdr-nerd-material-1.BdvqkCqW.woff2"},{"revision":null,"url":"_nuxt/wherdr-nerd-extension.Dai_ky39.woff2"},{"revision":null,"url":"_nuxt/wherdr-nerd-devicons.ZMSFX1sW.woff2"},{"revision":null,"url":"_nuxt/wherdr-nerd-codicons.CtEsfSAf.woff2"},{"revision":null,"url":"_nuxt/wherdr-nerd-awesome.DQ3_iAfa.woff2"},{"revision":null,"url":"_nuxt/settings.Cdb21nNw.css"},{"revision":null,"url":"_nuxt/jetbrains-mono-vietnamese-wght-normal.Bt-aOZkq.woff2"},{"revision":null,"url":"_nuxt/jetbrains-mono-latin-wght-normal.B9CIFXIH.woff2"},{"revision":null,"url":"_nuxt/jetbrains-mono-latin-ext-wght-normal.DBQx-q_a.woff2"},{"revision":null,"url":"_nuxt/jetbrains-mono-greek-wght-normal.Bw9x6K1M.woff2"},{"revision":null,"url":"_nuxt/jetbrains-mono-cyrillic-wght-normal.D73BlboJ.woff2"},{"revision":null,"url":"_nuxt/inter-vietnamese-wght-normal.CBcvBZtf.woff2"},{"revision":null,"url":"_nuxt/inter-latin-wght-normal.Dx4kXJAl.woff2"},{"revision":null,"url":"_nuxt/inter-latin-ext-wght-normal.DO1Apj_S.woff2"},{"revision":null,"url":"_nuxt/inter-greek-wght-normal.CkhJZR-_.woff2"},{"revision":null,"url":"_nuxt/inter-greek-ext-wght-normal.DlzME5K_.woff2"},{"revision":null,"url":"_nuxt/inter-cyrillic-wght-normal.DqGufNeO.woff2"},{"revision":null,"url":"_nuxt/inter-cyrillic-ext-wght-normal.BOeWTOD4.woff2"},{"revision":null,"url":"_nuxt/hePW80VL.js"},{"revision":null,"url":"_nuxt/error-500.Bwd7zAaE.css"},{"revision":null,"url":"_nuxt/error-404.Bb87HomL.css"},{"revision":null,"url":"_nuxt/entry.CKoXcwRa.css"},{"revision":null,"url":"_nuxt/board.CEEcFc6M.css"},{"revision":null,"url":"_nuxt/archivo-vietnamese-wght-normal.XAtsl5Q_.woff2"},{"revision":null,"url":"_nuxt/archivo-latin-wght-normal.E0tuGl4L.woff2"},{"revision":null,"url":"_nuxt/archivo-latin-ext-wght-normal.C4zznr8T.woff2"},{"revision":null,"url":"_nuxt/R0Y4VoeX.js"},{"revision":null,"url":"_nuxt/NIF0VwHk.js"},{"revision":null,"url":"_nuxt/FaNto0ga.js"},{"revision":null,"url":"_nuxt/DyfFwwGq.js"},{"revision":null,"url":"_nuxt/DrKKeFFE.js"},{"revision":null,"url":"_nuxt/DmkWvmnE.js"},{"revision":null,"url":"_nuxt/DZGKxROq.js"},{"revision":null,"url":"_nuxt/DFmgQVme.js"},{"revision":null,"url":"_nuxt/DFGEl0v2.js"},{"revision":null,"url":"_nuxt/CuUQ4mEf.js"},{"revision":null,"url":"_nuxt/CXJnLmWv.js"},{"revision":null,"url":"_nuxt/CDWjMk9C.js"},{"revision":null,"url":"_nuxt/C3Bkn4ac.js"},{"revision":null,"url":"_nuxt/C25ROUa9.js"},{"revision":null,"url":"_nuxt/BtH82ZuZ.js"},{"revision":null,"url":"_nuxt/Bpoxvzh6.js"},{"revision":null,"url":"_nuxt/BhgehRdJ.js"},{"revision":null,"url":"_nuxt/Bd17z0YL.js"},{"revision":null,"url":"_nuxt/BYZVrreW.js"},{"revision":null,"url":"_nuxt/BHenDMeH.js"},{"revision":null,"url":"_nuxt/BETID3_E.js"},{"revision":null,"url":"_nuxt/BDNMzG2s.js"},{"revision":null,"url":"_nuxt/AgentView.DzFWBd2A.css"},{"revision":"cd669ad19a6e6aac95c99782fbde9967","url":"_nuxt/builds/latest.json"},{"revision":null,"url":"_nuxt/builds/meta/0b28b3e9-664e-4347-a35b-afb0a711d5c5.json"}].map((e) => "/" + (typeof e === "string" ? e : e.url).replace(/^\//, ""))];
|
|
19
19
|
sw.addEventListener("install", (e) => {
|
|
20
20
|
e.waitUntil((async () => {
|
|
21
21
|
const c = await caches.open(CACHE);
|
|
@@ -55,7 +55,7 @@ function parseNumstat(raw) {
|
|
|
55
55
|
}
|
|
56
56
|
return stats;
|
|
57
57
|
}
|
|
58
|
-
function runner(m) {
|
|
58
|
+
function runner(m, signal) {
|
|
59
59
|
const remoteExec = m.exec;
|
|
60
60
|
if (remoteExec) return async (script, args, timeout = 12e3) => {
|
|
61
61
|
const r = await remoteExec(script, args, { timeoutMs: timeout });
|
|
@@ -63,7 +63,7 @@ function runner(m) {
|
|
|
63
63
|
return r.stdout;
|
|
64
64
|
};
|
|
65
65
|
return (script, args, timeout = 12e3) => new Promise((resolve, reject) => {
|
|
66
|
-
execFile("sh", ["-c", script, "sh", ...args], { timeout, encoding: "buffer", maxBuffer: 512 * 1024 }, (err, out, stderr) => {
|
|
66
|
+
execFile("sh", ["-c", script, "sh", ...args], { timeout, encoding: "buffer", maxBuffer: 512 * 1024, signal }, (err, out, stderr) => {
|
|
67
67
|
if (err) reject(new Error(String(stderr || err.message).trim()));
|
|
68
68
|
else resolve(out);
|
|
69
69
|
});
|
|
@@ -72,8 +72,8 @@ function runner(m) {
|
|
|
72
72
|
const git = "git --no-optional-locks -c core.fsmonitor=false -c core.hooksPath=/dev/null -c core.quotePath=false -c diff.external=";
|
|
73
73
|
const generated = /(^|\/)(?:dist|build|generated|coverage|node_modules|\.nuxt)\/|(^|\/)(?:package-lock\.json|pnpm-lock\.yaml|yarn\.lock|Cargo\.lock|composer\.lock|Gemfile\.lock|.*\.min\.(?:js|css)|.*\.map|.*\.generated\.[^/]+)$/i;
|
|
74
74
|
const emptySet = () => ({ files: [], truncated: false, count: 0 });
|
|
75
|
-
async function gitToplevel(m, cwd) {
|
|
76
|
-
const out = await runner(m)(`cd "$1" 2>/dev/null && ${git} rev-parse --show-toplevel 2>/dev/null || true`, [cwd]).catch(() => Buffer.alloc(0));
|
|
75
|
+
async function gitToplevel(m, cwd, signal) {
|
|
76
|
+
const out = await runner(m, signal)(`cd "$1" 2>/dev/null && ${git} rev-parse --show-toplevel 2>/dev/null || true`, [cwd]).catch(() => Buffer.alloc(0));
|
|
77
77
|
return out.toString("utf8").trim();
|
|
78
78
|
}
|
|
79
79
|
async function readChangeStatus(m, cwd) {
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { H as HerdrError, a as defineApi, i as getQuery, f as findPane, m as machineFor, aw as setResponseHeader, ax as getRequestHeader, ay as setResponseStatus } from '../nitro/nitro.mjs';
|
|
2
|
+
import { w as writtenTarget, c as cleanRelative, r as rootOf, i as isVideo, O as OPEN_FILE, V as VIDEO_HEAD, s as shellError, v as videoType, a as readWrittenBytes, b as readFileBytes, d as isPdf, e as attachmentHeader } from './files.mjs';
|
|
3
|
+
import { spawn } from 'node:child_process';
|
|
4
|
+
import crypto from 'node:crypto';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { Readable } from 'node:stream';
|
|
7
|
+
|
|
8
|
+
const VIDEO_BLOCK = 64 * 1024;
|
|
9
|
+
const OPEN_TIMEOUT_MS = 15e3;
|
|
10
|
+
const STREAM_SCRIPT = `${OPEN_FILE}
|
|
11
|
+
m=$(meta) || exit 4
|
|
12
|
+
echo "$(date +%s) $m"
|
|
13
|
+
dd bs=${VIDEO_HEAD} count=1 <&3 2>/dev/null
|
|
14
|
+
read skip count || exit 0
|
|
15
|
+
[ "$count" -gt 0 ] 2>/dev/null || exit 0
|
|
16
|
+
exec dd bs=${VIDEO_BLOCK} skip="$skip" count="$count" <&3 2>/dev/null`;
|
|
17
|
+
function parseRange(header, size) {
|
|
18
|
+
var _a;
|
|
19
|
+
if (header === void 0) return { kind: "full" };
|
|
20
|
+
const m = /^bytes[ \t]*=[ \t]*(.*)$/i.exec(header.trim());
|
|
21
|
+
if (!m) return { kind: "full" };
|
|
22
|
+
const specs = m[1].split(",").map((x) => x.trim()).filter(Boolean);
|
|
23
|
+
if (!specs.length) return { kind: "full" };
|
|
24
|
+
const parsed = [];
|
|
25
|
+
for (const spec of specs) {
|
|
26
|
+
const r = /^(\d*)-(\d*)$/.exec(spec);
|
|
27
|
+
if (!r || !r[1] && !r[2]) return { kind: "full" };
|
|
28
|
+
if (!r[1]) parsed.push({ suffix: Number(r[2]) });
|
|
29
|
+
else {
|
|
30
|
+
const first = Number(r[1]);
|
|
31
|
+
const last = r[2] ? Number(r[2]) : void 0;
|
|
32
|
+
if (last !== void 0 && last < first) return { kind: "full" };
|
|
33
|
+
parsed.push({ first, last });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
for (const p of parsed) {
|
|
37
|
+
if (p.suffix !== void 0) {
|
|
38
|
+
if (p.suffix > 0 && size > 0) return { kind: "part", start: Math.max(0, size - p.suffix), end: size - 1 };
|
|
39
|
+
} else if (p.first < size) {
|
|
40
|
+
return { kind: "part", start: p.first, end: Math.min((_a = p.last) != null ? _a : size - 1, size - 1) };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return { kind: "none" };
|
|
44
|
+
}
|
|
45
|
+
function answer(v, req) {
|
|
46
|
+
let range = req.method === "HEAD" ? void 0 : req.range;
|
|
47
|
+
if (range !== void 0 && req.ifRange !== void 0 && (req.ifRange.trim() !== v.etag || v.etag.startsWith("W/"))) range = void 0;
|
|
48
|
+
const r = parseRange(range, v.size);
|
|
49
|
+
if (r.kind === "none") return { status: 416, start: 0, len: 0, contentRange: `bytes */${v.size}` };
|
|
50
|
+
if (r.kind === "full") return { status: 200, start: 0, len: v.size };
|
|
51
|
+
return { status: 206, start: r.start, len: r.end - r.start + 1, contentRange: `bytes ${r.start}-${r.end}/${v.size}` };
|
|
52
|
+
}
|
|
53
|
+
function videoEtag(meta) {
|
|
54
|
+
var _a;
|
|
55
|
+
const frac = ((_a = /\.(\d+)/.exec(meta.version)) == null ? void 0 : _a[1]) || "";
|
|
56
|
+
const strong = /[1-9]/.test(frac) && meta.now - meta.mtime >= 2;
|
|
57
|
+
const hash = crypto.createHash("sha1").update(`${meta.ino}|${meta.size}|${meta.version}`).digest("hex").slice(0, 20);
|
|
58
|
+
return `${strong ? "" : "W/"}"${hash}"`;
|
|
59
|
+
}
|
|
60
|
+
function cutOnError(res, body) {
|
|
61
|
+
body.once("error", () => res.destroy());
|
|
62
|
+
return body;
|
|
63
|
+
}
|
|
64
|
+
function readPlan(start, len, head) {
|
|
65
|
+
const fromHead = start < head ? Math.min(len, head - start) : 0;
|
|
66
|
+
const rest = len - fromHead;
|
|
67
|
+
if (rest <= 0) return { fromHead, skip: 0, count: 0, drop: 0 };
|
|
68
|
+
const at = start + fromHead - head;
|
|
69
|
+
const skip = Math.floor(at / VIDEO_BLOCK);
|
|
70
|
+
const drop = at - skip * VIDEO_BLOCK;
|
|
71
|
+
return { fromHead, skip, count: Math.ceil((drop + rest) / VIDEO_BLOCK), drop };
|
|
72
|
+
}
|
|
73
|
+
function spawnScript(m, args) {
|
|
74
|
+
var _a;
|
|
75
|
+
if (!m.exec) {
|
|
76
|
+
return spawn("sh", ["-c", STREAM_SCRIPT, "sh", ...args], { stdio: ["pipe", "pipe", "pipe"], detached: true });
|
|
77
|
+
}
|
|
78
|
+
const child = (_a = m.spawnShell) == null ? void 0 : _a.call(m, STREAM_SCRIPT, args);
|
|
79
|
+
if (!child) throw new HerdrError("unreachable", "Machine unreachable");
|
|
80
|
+
return child;
|
|
81
|
+
}
|
|
82
|
+
function kill(child, local) {
|
|
83
|
+
if (child.exitCode !== null || child.signalCode !== null) return;
|
|
84
|
+
try {
|
|
85
|
+
if (local && child.pid) process.kill(-child.pid, "SIGKILL");
|
|
86
|
+
else child.kill("SIGKILL");
|
|
87
|
+
} catch {
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const closedError = () => new HerdrError("closed", "Request closed");
|
|
91
|
+
async function openAt(m, root, rel, signal) {
|
|
92
|
+
if (signal == null ? void 0 : signal.aborted) throw closedError();
|
|
93
|
+
const child = spawnScript(m, [root, rel]);
|
|
94
|
+
const done = new Promise((resolve) => {
|
|
95
|
+
child.on("close", () => resolve());
|
|
96
|
+
child.on("error", () => resolve());
|
|
97
|
+
});
|
|
98
|
+
const local = !m.exec;
|
|
99
|
+
const close = () => kill(child, local);
|
|
100
|
+
child.stdin.on("error", () => {
|
|
101
|
+
});
|
|
102
|
+
let buf = Buffer.alloc(0);
|
|
103
|
+
let stderr = "";
|
|
104
|
+
child.stderr.on("data", (b) => {
|
|
105
|
+
if (stderr.length < 4e3) stderr += b.toString("utf8");
|
|
106
|
+
});
|
|
107
|
+
const opened = await new Promise((resolve, reject) => {
|
|
108
|
+
const timer = setTimeout(() => {
|
|
109
|
+
close();
|
|
110
|
+
reject(new HerdrError("timeout", "The folder took too long to read"));
|
|
111
|
+
}, OPEN_TIMEOUT_MS);
|
|
112
|
+
const onAbort = () => done2(() => {
|
|
113
|
+
close();
|
|
114
|
+
reject(closedError());
|
|
115
|
+
});
|
|
116
|
+
signal == null ? void 0 : signal.addEventListener("abort", onAbort, { once: true });
|
|
117
|
+
const done2 = (f) => {
|
|
118
|
+
clearTimeout(timer);
|
|
119
|
+
signal == null ? void 0 : signal.removeEventListener("abort", onAbort);
|
|
120
|
+
child.stdout.off("data", onData);
|
|
121
|
+
child.off("close", onClose);
|
|
122
|
+
child.off("error", onError);
|
|
123
|
+
f();
|
|
124
|
+
};
|
|
125
|
+
const onData = (b) => {
|
|
126
|
+
buf = Buffer.concat([buf, b]);
|
|
127
|
+
const nl = buf.indexOf(10);
|
|
128
|
+
if (nl < 0) return;
|
|
129
|
+
const [now = "0", ino = "0", size = "0", mtime = "0", ...version] = buf.subarray(0, nl).toString("utf8").trim().split(/\s+/);
|
|
130
|
+
const n = Number(size) || 0;
|
|
131
|
+
const headLen = Math.min(VIDEO_HEAD, n);
|
|
132
|
+
if (buf.length - nl - 1 < headLen) return;
|
|
133
|
+
child.stdout.pause();
|
|
134
|
+
const head = buf.subarray(nl + 1, nl + 1 + headLen);
|
|
135
|
+
done2(() => resolve({ now: Number(now) || 0, ino, size: n, mtime: Number(mtime) || 0, version: version.join(" "), head }));
|
|
136
|
+
};
|
|
137
|
+
const onClose = (code) => done2(() => reject(code === 0 ? new HerdrError("not_found", "File not found") : shellError(m, code, stderr)));
|
|
138
|
+
const onError = () => done2(() => reject(new HerdrError("unreachable", "Machine unreachable")));
|
|
139
|
+
child.stdout.on("data", onData);
|
|
140
|
+
child.on("close", onClose);
|
|
141
|
+
child.on("error", onError);
|
|
142
|
+
});
|
|
143
|
+
const name = path.posix.basename(rel);
|
|
144
|
+
if (!isVideo(name, opened.head)) {
|
|
145
|
+
close();
|
|
146
|
+
throw new HerdrError("not_video", "Not a video");
|
|
147
|
+
}
|
|
148
|
+
let reading = false;
|
|
149
|
+
return {
|
|
150
|
+
name,
|
|
151
|
+
size: opened.size,
|
|
152
|
+
mtime: opened.mtime,
|
|
153
|
+
etag: videoEtag(opened),
|
|
154
|
+
close,
|
|
155
|
+
done,
|
|
156
|
+
read(start, len) {
|
|
157
|
+
if (reading) throw new Error("read once");
|
|
158
|
+
reading = true;
|
|
159
|
+
const plan = readPlan(start, len, opened.head.length);
|
|
160
|
+
child.stdin.end(`${plan.skip} ${plan.count}
|
|
161
|
+
`);
|
|
162
|
+
const out = child.stdout;
|
|
163
|
+
async function* bytes() {
|
|
164
|
+
let left = len;
|
|
165
|
+
try {
|
|
166
|
+
if (plan.fromHead) {
|
|
167
|
+
yield opened.head.subarray(start, start + plan.fromHead);
|
|
168
|
+
left -= plan.fromHead;
|
|
169
|
+
}
|
|
170
|
+
let drop = plan.drop;
|
|
171
|
+
for await (const chunk of out) {
|
|
172
|
+
if (left <= 0) break;
|
|
173
|
+
let c = chunk;
|
|
174
|
+
if (drop) {
|
|
175
|
+
const n = Math.min(drop, c.length);
|
|
176
|
+
c = c.subarray(n);
|
|
177
|
+
drop -= n;
|
|
178
|
+
}
|
|
179
|
+
if (!c.length) continue;
|
|
180
|
+
if (c.length > left) c = c.subarray(0, left);
|
|
181
|
+
left -= c.length;
|
|
182
|
+
yield c;
|
|
183
|
+
if (left <= 0) break;
|
|
184
|
+
}
|
|
185
|
+
if (left > 0) throw new HerdrError("truncated", "The file shrank while being read");
|
|
186
|
+
} finally {
|
|
187
|
+
close();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return Readable.from(bytes(), { objectMode: false });
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function untilClosed(p, signal) {
|
|
195
|
+
if (!signal) return p;
|
|
196
|
+
if (signal.aborted) return Promise.reject(closedError());
|
|
197
|
+
return new Promise((resolve, reject) => {
|
|
198
|
+
const onAbort = () => reject(closedError());
|
|
199
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
200
|
+
p.then(resolve, reject).finally(() => signal.removeEventListener("abort", onAbort));
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
async function openVideo(m, cwd, rel, signal) {
|
|
204
|
+
if (signal == null ? void 0 : signal.aborted) throw closedError();
|
|
205
|
+
const p = cleanRelative(rel);
|
|
206
|
+
if (!p) throw new HerdrError("not_file", "Not a file");
|
|
207
|
+
const root = await untilClosed(rootOf(m, cwd, signal), signal);
|
|
208
|
+
if (signal == null ? void 0 : signal.aborted) throw closedError();
|
|
209
|
+
return openAt(m, root, p, signal);
|
|
210
|
+
}
|
|
211
|
+
async function openWrittenVideo(m, cwd, written, signal) {
|
|
212
|
+
const t = writtenTarget(m, cwd, written);
|
|
213
|
+
return openAt(m, t.root, t.rel, signal);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
async function serveVideo(event, p, q, type) {
|
|
217
|
+
const m = machineFor(p.machine);
|
|
218
|
+
const res = event.node.res;
|
|
219
|
+
const closed = new AbortController();
|
|
220
|
+
res.once("close", () => closed.abort());
|
|
221
|
+
if (res.destroyed) closed.abort();
|
|
222
|
+
const v = q.from === "chat" ? await openWrittenVideo(m, p.cwd, q.path, closed.signal) : await openVideo(m, p.cwd, q.path, closed.signal);
|
|
223
|
+
if (closed.signal.aborted) {
|
|
224
|
+
v.close();
|
|
225
|
+
return "";
|
|
226
|
+
}
|
|
227
|
+
closed.signal.addEventListener("abort", v.close, { once: true });
|
|
228
|
+
try {
|
|
229
|
+
setResponseHeader(event, "x-content-type-options", "nosniff");
|
|
230
|
+
setResponseHeader(event, "accept-ranges", "bytes");
|
|
231
|
+
setResponseHeader(event, "content-security-policy", "default-src 'none'; media-src 'self'; frame-ancestors 'self'");
|
|
232
|
+
setResponseHeader(event, "etag", v.etag);
|
|
233
|
+
setResponseHeader(event, "last-modified", new Date(v.mtime * 1e3).toUTCString());
|
|
234
|
+
const a = answer(v, { method: event.method, range: getRequestHeader(event, "range"), ifRange: getRequestHeader(event, "if-range") });
|
|
235
|
+
setResponseStatus(event, a.status);
|
|
236
|
+
if (a.contentRange) setResponseHeader(event, "content-range", a.contentRange);
|
|
237
|
+
if (a.status === 416) {
|
|
238
|
+
v.close();
|
|
239
|
+
setResponseHeader(event, "content-type", "text/plain");
|
|
240
|
+
return "";
|
|
241
|
+
}
|
|
242
|
+
setResponseHeader(event, "content-type", type);
|
|
243
|
+
setResponseHeader(event, "content-disposition", attachmentHeader(v.name, "inline"));
|
|
244
|
+
setResponseHeader(event, "content-length", a.len);
|
|
245
|
+
if (event.method === "HEAD" || !a.len) {
|
|
246
|
+
v.close();
|
|
247
|
+
return "";
|
|
248
|
+
}
|
|
249
|
+
return cutOnError(res, v.read(a.start, a.len));
|
|
250
|
+
} catch (e) {
|
|
251
|
+
v.close();
|
|
252
|
+
throw e;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const fileDownload = defineApi(async (event) => {
|
|
256
|
+
const q = getQuery(event);
|
|
257
|
+
const p = findPane(String(q.pane || ""));
|
|
258
|
+
if (!p) throw new HerdrError("bad_pane", "Pane not found");
|
|
259
|
+
if (q.from !== "chat" && !p.cwd) throw new HerdrError("bad_cwd", "This agent\u2019s folder is unknown");
|
|
260
|
+
const video = q.inline === "1" ? videoType(String(q.path || "")) : void 0;
|
|
261
|
+
if (video) return serveVideo(event, p, q, video);
|
|
262
|
+
const f = q.from === "chat" ? await readWrittenBytes(machineFor(p.machine), p.cwd, q.path) : await readFileBytes(machineFor(p.machine), p.cwd, q.path);
|
|
263
|
+
setResponseHeader(event, "x-content-type-options", "nosniff");
|
|
264
|
+
if (q.inline === "1" && isPdf(f.name, f.body)) {
|
|
265
|
+
setResponseHeader(event, "content-type", "application/pdf");
|
|
266
|
+
setResponseHeader(event, "content-disposition", attachmentHeader(f.name, "inline"));
|
|
267
|
+
setResponseHeader(event, "content-security-policy", "default-src 'none'; object-src 'self'; frame-ancestors 'self'");
|
|
268
|
+
setResponseHeader(event, "cache-control", "private, no-store");
|
|
269
|
+
return f.body;
|
|
270
|
+
}
|
|
271
|
+
setResponseHeader(event, "content-type", "application/octet-stream");
|
|
272
|
+
setResponseHeader(event, "content-disposition", attachmentHeader(f.name));
|
|
273
|
+
setResponseHeader(event, "content-security-policy", "default-src 'none'; sandbox");
|
|
274
|
+
return f.body;
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
export { fileDownload as f };
|
|
278
|
+
//# sourceMappingURL=fileDownload.mjs.map
|
|
@@ -19,6 +19,18 @@ const IMAGE_TYPES = {
|
|
|
19
19
|
ico: "image/x-icon",
|
|
20
20
|
svg: "image/svg+xml"
|
|
21
21
|
};
|
|
22
|
+
const PDF_HEAD = 1024;
|
|
23
|
+
const isPdf = (name, head) => path.posix.extname(name).toLowerCase() === ".pdf" && head.subarray(0, PDF_HEAD).includes("%PDF-");
|
|
24
|
+
const VIDEO_TYPES = { mp4: "video/mp4", m4v: "video/mp4", mov: "video/quicktime", webm: "video/webm" };
|
|
25
|
+
const VIDEO_HEAD = 12;
|
|
26
|
+
const MP4_BOXES = /* @__PURE__ */ new Set(["ftyp", "moov", "mdat", "wide", "free", "skip", "pnot"]);
|
|
27
|
+
const videoType = (name) => VIDEO_TYPES[path.posix.extname(name).slice(1).toLowerCase()];
|
|
28
|
+
function isVideo(name, head) {
|
|
29
|
+
const type = videoType(name);
|
|
30
|
+
if (!type || head.length < 8) return false;
|
|
31
|
+
if (type === "video/webm") return head.readUInt32BE(0) === 440786851;
|
|
32
|
+
return MP4_BOXES.has(head.subarray(4, 8).toString("latin1"));
|
|
33
|
+
}
|
|
22
34
|
const RESOLVE = `root=$(cd "$1" 2>/dev/null && pwd -P) || { echo "folder not found" >&2; exit 3; }
|
|
23
35
|
under() { case "$1/" in "\${root%/}/"*) return 0 ;; esac; return 1; }`;
|
|
24
36
|
const LIST_SCRIPT = `${RESOLVE}
|
|
@@ -29,7 +41,10 @@ else
|
|
|
29
41
|
under "$dir" || { echo "outside" >&2; exit 5; }
|
|
30
42
|
fi
|
|
31
43
|
cd "$dir" || exit 4
|
|
32
|
-
|
|
44
|
+
e=$(LC_ALL=C ls -A 2>&1 >/dev/null) || {
|
|
45
|
+
case "$e" in *"not permitted"*) [ "$(uname -s)" = Darwin ] && exit 8 ;; esac
|
|
46
|
+
echo "permission denied" >&2; exit 7
|
|
47
|
+
}
|
|
33
48
|
printf '%s\\0%s\\0' "$root" "$dir"
|
|
34
49
|
max=$3; n=0
|
|
35
50
|
set --
|
|
@@ -47,7 +62,7 @@ printf '=\\0'
|
|
|
47
62
|
[ "$#" -gt 0 ] || exit 0
|
|
48
63
|
if stat -f %z / >/dev/null 2>&1; then stat -f %z -- "$@"; else stat -c %s -- "$@"; fi 2>/dev/null
|
|
49
64
|
exit 0`;
|
|
50
|
-
const
|
|
65
|
+
const OPEN_FILE = `${RESOLVE}
|
|
51
66
|
case "$2" in */*) d=\${2%/*} ;; *) d=. ;; esac
|
|
52
67
|
b=\${2##*/}
|
|
53
68
|
dir=$(cd "$root" && cd -- "./$d" 2>/dev/null && pwd -P) || { echo "not found" >&2; exit 4; }
|
|
@@ -64,10 +79,23 @@ done
|
|
|
64
79
|
under "$f" || { echo "outside" >&2; exit 5; }
|
|
65
80
|
[ -f "$f" ] || { echo "not a file" >&2; exit 6; }
|
|
66
81
|
[ -r "$f" ] || { echo "permission denied" >&2; exit 7; }
|
|
67
|
-
|
|
82
|
+
command exec 3< "$f" || { echo "permission denied" >&2; exit 7; }
|
|
83
|
+
# "<inode> <size> <mtime> <version>" of the opened file, from its metadata:
|
|
84
|
+
# never a read (BusyBox's wc -c reads every byte). <version>: modification
|
|
85
|
+
# and change times to the nanosecond (GNU/BusyBox, then BSD). Without the
|
|
86
|
+
# descriptor's metadata, the path's, with no <version>: never a strong ETag.
|
|
87
|
+
meta() {
|
|
88
|
+
stat -L -c '%i %s %Y %y %z' /dev/fd/3 2>/dev/null || stat -L -f '%i %z %m %Fm %Fc' /dev/fd/3 2>/dev/null ||
|
|
89
|
+
stat -L -c '%i %s %Y' "$f" 2>/dev/null || stat -L -f '%i %z %m' "$f" 2>/dev/null || echo "0 $(wc -c < "$f") 0"
|
|
90
|
+
}`;
|
|
91
|
+
const READ_SCRIPT = `${OPEN_FILE}
|
|
92
|
+
m=$(meta) || exit 4
|
|
93
|
+
s=\${m#* }; s=$((\${s%% *}))
|
|
68
94
|
echo $s
|
|
69
|
-
[ -n "$4" ] && [ $
|
|
70
|
-
head -c "$3"
|
|
95
|
+
[ -n "$4" ] && [ "$s" -ge "$3" ] && exit 0
|
|
96
|
+
head -c "$3" <&3`;
|
|
97
|
+
const MACOS_SSH_DENIED = "macOS blocks access to this folder. On the Mac: System Settings \u203A General \u203A Sharing \u203A Remote Login \u24D8 \u203A \u201CAllow full disk access for remote users\u201D.";
|
|
98
|
+
const MACOS_LOCAL_DENIED = "macOS blocks access to this folder. Allow the app that runs wherdr in System Settings \u203A Privacy & Security \u203A Full Disk Access.";
|
|
71
99
|
function executor(m, { timeoutMs = 15e3, maxBytes = IMAGE_BYTES } = {}) {
|
|
72
100
|
const remote = m.exec;
|
|
73
101
|
if (remote) return (script, args) => remote(script, args, { timeoutMs });
|
|
@@ -82,14 +110,19 @@ function executor(m, { timeoutMs = 15e3, maxBytes = IMAGE_BYTES } = {}) {
|
|
|
82
110
|
async function run(m, script, args, opts) {
|
|
83
111
|
const r = await executor(m, opts)(script, args);
|
|
84
112
|
if (r.code === 0) return r.stdout;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (r.code ===
|
|
90
|
-
if (r.code ===
|
|
91
|
-
if (r.code ===
|
|
92
|
-
|
|
113
|
+
throw shellError(m, r.code, r.stderr);
|
|
114
|
+
}
|
|
115
|
+
function shellError(m, code, stderr) {
|
|
116
|
+
const r = { code, stderr };
|
|
117
|
+
if (r.code === 3) return new HerdrError("bad_cwd", "This agent\u2019s folder is unknown");
|
|
118
|
+
if (r.code === 4) return new HerdrError("not_found", "File not found");
|
|
119
|
+
if (r.code === 5) return new HerdrError("outside", "Outside the project folder");
|
|
120
|
+
if (r.code === 6) return new HerdrError("not_file", "Not a file");
|
|
121
|
+
if (r.code === 7) return new HerdrError("denied", "Permission denied");
|
|
122
|
+
if (r.code === 8) return new HerdrError("denied", m.exec ? MACOS_SSH_DENIED : MACOS_LOCAL_DENIED);
|
|
123
|
+
if (r.code === 124) return new HerdrError("timeout", "The folder took too long to read");
|
|
124
|
+
if (r.code === 255 || r.code === null) return new HerdrError("unreachable", "Machine unreachable");
|
|
125
|
+
return new HerdrError("remote", r.stderr.trim().split("\n").pop() || `code ${r.code}`);
|
|
93
126
|
}
|
|
94
127
|
function cleanRelative(p) {
|
|
95
128
|
const raw = String(p != null ? p : "").replace(/\\/g, "/");
|
|
@@ -126,8 +159,8 @@ function parseListing(raw) {
|
|
|
126
159
|
entries.sort((a, b) => Number(b.kind === "dir") - Number(a.kind === "dir") || a.name.localeCompare(b.name, void 0, { numeric: true, sensitivity: "base" }));
|
|
127
160
|
return { root, dir, entries, truncated };
|
|
128
161
|
}
|
|
129
|
-
async function rootOf(m, cwd) {
|
|
130
|
-
return await gitToplevel(m, cwd) || cwd;
|
|
162
|
+
async function rootOf(m, cwd, signal) {
|
|
163
|
+
return await gitToplevel(m, cwd, signal) || cwd;
|
|
131
164
|
}
|
|
132
165
|
async function listFiles(m, cwd, rel, opts = {}) {
|
|
133
166
|
var _a, _b;
|
|
@@ -160,8 +193,15 @@ async function readHead(m, root, rel, max, opts) {
|
|
|
160
193
|
return { size: Number(out.subarray(0, nl).toString("utf8")) || 0, body: out.subarray(nl + 1) };
|
|
161
194
|
}
|
|
162
195
|
async function previewAt(m, root, rel, shown) {
|
|
163
|
-
const
|
|
164
|
-
const
|
|
196
|
+
const ext = path.posix.extname(rel).slice(1).toLowerCase();
|
|
197
|
+
const mime = IMAGE_TYPES[ext];
|
|
198
|
+
const video = VIDEO_TYPES[ext];
|
|
199
|
+
const { size, body } = await readHead(m, root, rel, mime ? IMAGE_BYTES + 1 : ext === "pdf" ? PDF_HEAD : video ? VIDEO_HEAD : TEXT_BYTES + 1);
|
|
200
|
+
if (video) return { path: shown, size, kind: isVideo(rel, body) ? "video" : "binary", truncated: false };
|
|
201
|
+
if (ext === "pdf") {
|
|
202
|
+
if (!isPdf(rel, body)) return { path: shown, size, kind: "binary", truncated: false };
|
|
203
|
+
return { path: shown, size, kind: size > DOWNLOAD_BYTES ? "large" : "pdf", truncated: false };
|
|
204
|
+
}
|
|
165
205
|
if (mime) {
|
|
166
206
|
if (size > IMAGE_BYTES) return { path: shown, size, kind: "large", truncated: true };
|
|
167
207
|
return { path: shown, size, kind: "image", dataUrl: `data:${mime};base64,${body.toString("base64")}`, truncated: false };
|
|
@@ -194,11 +234,11 @@ async function readWrittenBytes(m, cwd, written) {
|
|
|
194
234
|
const t = writtenTarget(m, cwd, written);
|
|
195
235
|
return bytesAt(m, t.root, t.rel);
|
|
196
236
|
}
|
|
197
|
-
function attachmentHeader(name) {
|
|
237
|
+
function attachmentHeader(name, type = "attachment") {
|
|
198
238
|
const ascii = name.replace(/[^\x20-\x7e]|["\\]/g, "_") || "download";
|
|
199
239
|
const utf8 = encodeURIComponent(name).replace(/['()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
200
|
-
return
|
|
240
|
+
return `${type}; filename="${ascii}"; filename*=UTF-8''${utf8}`;
|
|
201
241
|
}
|
|
202
242
|
|
|
203
|
-
export {
|
|
243
|
+
export { OPEN_FILE as O, VIDEO_HEAD as V, readWrittenBytes as a, readFileBytes as b, cleanRelative as c, isPdf as d, attachmentHeader as e, readWrittenPreview as f, readFilePreview as g, isVideo as i, listFiles as l, rootOf as r, shellError as s, videoType as v, writtenTarget as w };
|
|
204
244
|
//# sourceMappingURL=files.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
|
-
import {
|
|
4
|
+
import { aG as baseMachines, aH as DATA_DIR } from '../nitro/nitro.mjs';
|
|
5
5
|
|
|
6
6
|
function cleanMachineOrder(value, known) {
|
|
7
7
|
if (!Array.isArray(value)) return [];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { aW as HOST_LABEL,
|
|
3
|
+
import { aW as HOST_LABEL, aH as DATA_DIR } from '../nitro/nitro.mjs';
|
|
4
4
|
|
|
5
5
|
const ONBOARDING_FILE = path.join(DATA_DIR, "onboarding.json");
|
|
6
6
|
function readOnboarding(file = ONBOARDING_FILE, host = HOST_LABEL) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var name = "wherdr";
|
|
2
|
-
var version = "
|
|
2
|
+
var version = "2.0.0";
|
|
3
3
|
var license = "MIT";
|
|
4
4
|
var type = "module";
|
|
5
5
|
var description = "Unofficial mobile web client (PWA) to drive the coding agents running in Herdr";
|
|
@@ -25,7 +25,8 @@ var files = [
|
|
|
25
25
|
".output",
|
|
26
26
|
"!.output/**/*.map",
|
|
27
27
|
"bin",
|
|
28
|
-
"skills/wherdr"
|
|
28
|
+
"skills/wherdr",
|
|
29
|
+
"docs/*.md"
|
|
29
30
|
];
|
|
30
31
|
var engines = {
|
|
31
32
|
node: ">=22"
|
|
@@ -38,10 +39,15 @@ var scripts = {
|
|
|
38
39
|
typecheck: "nuxt typecheck",
|
|
39
40
|
test: "vitest run",
|
|
40
41
|
"test:e2e": "playwright test",
|
|
42
|
+
"shots:readme": "node tools/readme-shots/capture.mjs",
|
|
43
|
+
"test:e2e:shots": "SHOTS=${SHOTS:-.shots} playwright test tests/e2e/question-reply.spec.ts --grep screenshot:",
|
|
44
|
+
"test:e2e:stability": "playwright test menu-responsiveness codex-self-update quote-mode onboarding-tailnet --grep \"MCP arrow paints|a new Codex restarts|the former per-device values|a quoted question keeps|#/setup[?]step=security opens|a direct Security link\"",
|
|
41
45
|
prepare: "nuxt prepare",
|
|
42
46
|
prepack: "nuxt build && node scripts/pack-output.mjs",
|
|
47
|
+
"check:docs": "node scripts/check-doc-links.mjs",
|
|
43
48
|
"check:leaks": "node scripts/check-leaks.mjs",
|
|
44
|
-
"hooks:install": "git config core.hooksPath .githooks"
|
|
49
|
+
"hooks:install": "git config core.hooksPath .githooks",
|
|
50
|
+
"test:affected": "node scripts/test-affected.mjs"
|
|
45
51
|
};
|
|
46
52
|
var dependencies = {
|
|
47
53
|
"qrcode-terminal": "^0.12.0"
|
|
@@ -59,6 +65,7 @@ var devDependencies = {
|
|
|
59
65
|
"@types/node": "^22.0.0",
|
|
60
66
|
"@types/web-push": "^3.6.4",
|
|
61
67
|
"@vite-pwa/nuxt": "^1.1.1",
|
|
68
|
+
"@vue/reactivity": "^3.5.43",
|
|
62
69
|
"@vue/test-utils": "^2.5.1",
|
|
63
70
|
"@xterm/addon-fit": "^0.10.0",
|
|
64
71
|
"@xterm/addon-webgl": "^0.18.0",
|
|
@@ -67,6 +74,7 @@ var devDependencies = {
|
|
|
67
74
|
"happy-dom": "^20.14.5",
|
|
68
75
|
marked: "^15.0.12",
|
|
69
76
|
nuxt: "^4.5.2",
|
|
77
|
+
"pdfjs-dist": "5.4.624",
|
|
70
78
|
tailwindcss: "^4.3.3",
|
|
71
79
|
typescript: "~5.9.3",
|
|
72
80
|
vitest: "^4.1.11",
|