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.
Files changed (252) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/BDNMzG2s.js +1 -0
  3. package/.output/public/_nuxt/BETID3_E.js +1 -0
  4. package/.output/public/_nuxt/BHenDMeH.js +1 -0
  5. package/.output/public/_nuxt/BYZVrreW.js +1 -0
  6. package/.output/public/_nuxt/BhgehRdJ.js +1 -0
  7. package/.output/public/_nuxt/{yzABg5xl.js → Bpoxvzh6.js} +1 -1
  8. package/.output/public/_nuxt/BtH82ZuZ.js +9 -0
  9. package/.output/public/_nuxt/C25ROUa9.js +3 -0
  10. package/.output/public/_nuxt/C3Bkn4ac.js +62 -0
  11. package/.output/public/_nuxt/CDWjMk9C.js +2 -0
  12. package/.output/public/_nuxt/{Ci8N4mWR.js → CXJnLmWv.js} +1 -1
  13. package/.output/public/_nuxt/CuUQ4mEf.js +1 -0
  14. package/.output/public/_nuxt/DFGEl0v2.js +23 -0
  15. package/.output/public/_nuxt/{CKhgznq4.js → DFmgQVme.js} +42 -39
  16. package/.output/public/_nuxt/DZGKxROq.js +6 -0
  17. package/.output/public/_nuxt/DmkWvmnE.js +2 -0
  18. package/.output/public/_nuxt/DrKKeFFE.js +31 -0
  19. package/.output/public/_nuxt/DyfFwwGq.js +1 -0
  20. package/.output/public/_nuxt/FaNto0ga.js +105 -0
  21. package/.output/public/_nuxt/NIF0VwHk.js +25 -0
  22. package/.output/public/_nuxt/R0Y4VoeX.js +1 -0
  23. package/.output/public/_nuxt/board.CEEcFc6M.css +1 -0
  24. package/.output/public/_nuxt/builds/latest.json +1 -1
  25. package/.output/public/_nuxt/builds/meta/0b28b3e9-664e-4347-a35b-afb0a711d5c5.json +1 -0
  26. package/.output/public/_nuxt/entry.CKoXcwRa.css +2 -0
  27. package/.output/public/_nuxt/pdf.min.t82Z80JU.mjs +28 -0
  28. package/.output/public/_nuxt/pdf.worker.min.wgc6bjNh.mjs +28 -0
  29. package/.output/public/_nuxt/settings.Cdb21nNw.css +1 -0
  30. package/.output/public/sw.js +1 -1
  31. package/.output/server/chunks/_/branding.mjs +1 -1
  32. package/.output/server/chunks/_/changes.mjs +4 -4
  33. package/.output/server/chunks/_/fileDownload.mjs +278 -0
  34. package/.output/server/chunks/_/files.mjs +60 -20
  35. package/.output/server/chunks/_/machineOrder.mjs +1 -1
  36. package/.output/server/chunks/_/onboarding.mjs +1 -1
  37. package/.output/server/chunks/_/package.mjs +11 -3
  38. package/.output/server/chunks/_/plugins.mjs +92 -122
  39. package/.output/server/chunks/_/restart.mjs +1 -1
  40. package/.output/server/chunks/_/selfupdate.mjs +1 -1
  41. package/.output/server/chunks/_/settingstabs.mjs +36 -0
  42. package/.output/server/chunks/_/updates.mjs +1 -1
  43. package/.output/server/chunks/_/worktrees.mjs +1 -1
  44. package/.output/server/chunks/_/ws.mjs +43 -6
  45. package/.output/server/chunks/nitro/nitro.mjs +14126 -10238
  46. package/.output/server/chunks/raw/check-doc-links.mjs +5 -0
  47. package/.output/server/chunks/raw/check-leaks.mjs +1 -1
  48. package/.output/server/chunks/raw/check-release-notes.mjs +5 -0
  49. package/.output/server/chunks/raw/herdr-plugin.mjs +1 -1
  50. package/.output/server/chunks/raw/install-claude-statusline.mjs +1 -1
  51. package/.output/server/chunks/raw/prerelease-summary.mjs +5 -0
  52. package/.output/server/chunks/raw/prerelease.mjs +7 -0
  53. package/.output/server/chunks/raw/reveal.mjs +1 -1
  54. package/.output/server/chunks/raw/test-affected.mjs +5 -0
  55. package/.output/server/chunks/routes/api/_..._.mjs +6 -5
  56. package/.output/server/chunks/routes/api/agents.post.mjs +6 -5
  57. package/.output/server/chunks/routes/api/ask-tab.post.mjs +6 -5
  58. package/.output/server/chunks/routes/api/attach.post.mjs +6 -5
  59. package/.output/server/chunks/routes/api/auth/disable.post.mjs +6 -5
  60. package/.output/server/chunks/routes/api/auth/lock-all.post.mjs +6 -5
  61. package/.output/server/chunks/routes/api/auth/lock.post.mjs +6 -5
  62. package/.output/server/chunks/routes/api/auth/login/options.post.mjs +6 -5
  63. package/.output/server/chunks/routes/api/auth/login/verify.post.mjs +6 -5
  64. package/.output/server/chunks/routes/api/auth/max-session.post.mjs +6 -5
  65. package/.output/server/chunks/routes/api/auth/register/options.post.mjs +6 -5
  66. package/.output/server/chunks/routes/api/auth/register/verify.post.mjs +6 -5
  67. package/.output/server/chunks/routes/api/auth/status.get.mjs +6 -5
  68. package/.output/server/chunks/routes/api/changes.get.mjs +7 -6
  69. package/.output/server/chunks/routes/api/chat/image.get.mjs +7 -6
  70. package/.output/server/chunks/routes/api/chat.get.mjs +44 -11
  71. package/.output/server/chunks/routes/api/choose.post.mjs +44 -30
  72. package/.output/server/chunks/routes/api/claude-setup.post.mjs +42 -0
  73. package/.output/server/chunks/routes/api/claude-statusline.post.mjs +7 -6
  74. package/.output/server/chunks/routes/api/clear-queued-input.post.mjs +42 -0
  75. package/.output/server/chunks/routes/api/close/status.get.mjs +7 -6
  76. package/.output/server/chunks/routes/api/close.post.mjs +6 -5
  77. package/.output/server/chunks/routes/api/codex-update.post.mjs +7 -6
  78. package/.output/server/chunks/routes/api/commands.get.mjs +9 -7
  79. package/.output/server/chunks/routes/api/config.get.mjs +10 -13
  80. package/.output/server/chunks/routes/api/dirs.get.mjs +7 -6
  81. package/.output/server/chunks/routes/api/dismiss-stopped.post.mjs +7 -6
  82. package/.output/server/chunks/routes/api/dismiss.post.mjs +7 -6
  83. package/.output/server/chunks/routes/api/effort.post.mjs +7 -6
  84. package/.output/server/chunks/routes/api/efforts.get.mjs +7 -6
  85. package/.output/server/chunks/routes/api/file.post.mjs +7 -6
  86. package/.output/server/chunks/routes/api/files/download.get.mjs +12 -24
  87. package/.output/server/chunks/routes/api/files/download.head.mjs +41 -0
  88. package/.output/server/chunks/routes/api/files/read.get.mjs +8 -7
  89. package/.output/server/chunks/routes/api/files.get.mjs +7 -6
  90. package/.output/server/chunks/routes/api/health.get.mjs +6 -5
  91. package/.output/server/chunks/routes/api/input.post.mjs +33 -15
  92. package/.output/server/chunks/routes/api/interrupt.post.mjs +24 -21
  93. package/.output/server/chunks/routes/api/isgit.get.mjs +8 -8
  94. package/.output/server/chunks/routes/api/machine/awake.get.mjs +7 -6
  95. package/.output/server/chunks/routes/api/machine/awake.post.mjs +7 -6
  96. package/.output/server/chunks/routes/api/machine/order.get.mjs +6 -5
  97. package/.output/server/chunks/routes/api/machine/order.post.mjs +6 -5
  98. package/.output/server/chunks/routes/api/machine/reconnect.post.mjs +40 -0
  99. package/.output/server/chunks/routes/api/machine/rename.post.mjs +7 -6
  100. package/.output/server/chunks/routes/api/machine/status.post.mjs +39 -0
  101. package/.output/server/chunks/routes/api/menu-left.post.mjs +40 -0
  102. package/.output/server/chunks/routes/api/menu.post.mjs +10 -6
  103. package/.output/server/chunks/routes/api/model.post.mjs +7 -6
  104. package/.output/server/chunks/routes/api/models.get.mjs +7 -6
  105. package/.output/server/chunks/routes/api/nav.post.mjs +40 -26
  106. package/.output/server/chunks/routes/api/onboarding.get.mjs +6 -5
  107. package/.output/server/chunks/routes/api/onboarding.post.mjs +6 -5
  108. package/.output/server/chunks/routes/api/phone.get.mjs +8 -10
  109. package/.output/server/chunks/routes/api/phone.post.mjs +8 -10
  110. package/.output/server/chunks/routes/api/plugins/actions.get.mjs +6 -8
  111. package/.output/server/chunks/routes/api/plugins/invoke.post.mjs +6 -8
  112. package/.output/server/chunks/routes/api/plugins/projects.get.mjs +10 -8
  113. package/.output/server/chunks/routes/api/plugins/projects.post.mjs +11 -7
  114. package/.output/server/chunks/routes/api/prompt.post.mjs +22 -13
  115. package/.output/server/chunks/routes/api/push/quiet.post.mjs +7 -6
  116. package/.output/server/chunks/routes/api/push/subscribe.post.mjs +7 -7
  117. package/.output/server/chunks/routes/api/push/test.post.mjs +7 -6
  118. package/.output/server/chunks/routes/api/push/unsubscribe.post.mjs +7 -6
  119. package/.output/server/chunks/routes/api/quotas.get.mjs +7 -6
  120. package/.output/server/chunks/routes/api/rename.post.mjs +6 -5
  121. package/.output/server/chunks/routes/api/requeue.post.mjs +7 -6
  122. package/.output/server/chunks/routes/api/restart.get.mjs +6 -5
  123. package/.output/server/chunks/routes/api/restart.post.mjs +6 -5
  124. package/.output/server/chunks/routes/api/reveal.post.mjs +91 -8
  125. package/.output/server/chunks/routes/api/screen-key.post.mjs +19 -15
  126. package/.output/server/chunks/routes/api/screen.get.mjs +8 -40
  127. package/.output/server/chunks/routes/api/search.get.mjs +7 -6
  128. package/.output/server/chunks/routes/api/seen.post.mjs +7 -6
  129. package/.output/server/chunks/routes/api/sessions.get.mjs +7 -6
  130. package/.output/server/chunks/routes/api/sessions.post.mjs +7 -6
  131. package/.output/server/chunks/routes/api/settings-tab.post.mjs +90 -0
  132. package/.output/server/chunks/routes/api/{plugins/thread-limits.get.mjs → settings.get.mjs} +10 -9
  133. package/.output/server/chunks/routes/api/settings.post.mjs +40 -0
  134. package/.output/server/chunks/routes/api/space.post.mjs +34 -18
  135. package/.output/server/chunks/routes/api/state.get.mjs +7 -6
  136. package/.output/server/chunks/routes/api/tasks/action.post.mjs +39 -0
  137. package/.output/server/chunks/routes/api/{plugins/profiles.get.mjs → tasks/add.post.mjs} +12 -14
  138. package/.output/server/chunks/routes/api/tasks/after.post.mjs +39 -0
  139. package/.output/server/chunks/routes/api/tasks/approve.post.mjs +39 -0
  140. package/.output/server/chunks/routes/api/{project/report.get.mjs → tasks/archived.get.mjs} +12 -13
  141. package/.output/server/chunks/routes/api/{gitroot.get.mjs → tasks/autopilot.get.mjs} +13 -14
  142. package/.output/server/chunks/routes/api/tasks/autopilot.post.mjs +39 -0
  143. package/.output/server/chunks/routes/api/{index.get.mjs → tasks/board-settings.get.mjs} +12 -13
  144. package/.output/server/chunks/routes/api/tasks/board-settings.post.mjs +39 -0
  145. package/.output/server/chunks/routes/api/tasks/coordinator.get.mjs +40 -0
  146. package/.output/server/chunks/routes/api/tasks/coordinator.post.mjs +39 -0
  147. package/.output/server/chunks/routes/api/tasks/details.get.mjs +40 -0
  148. package/.output/server/chunks/routes/api/tasks/limit.post.mjs +39 -0
  149. package/.output/server/chunks/routes/api/tasks/links.get.mjs +39 -0
  150. package/.output/server/chunks/routes/api/tasks/models.get.mjs +40 -0
  151. package/.output/server/chunks/routes/api/tasks/pick.post.mjs +39 -0
  152. package/.output/server/chunks/routes/api/tasks/question.post.mjs +39 -0
  153. package/.output/server/chunks/routes/api/tasks/scheduled.get.mjs +40 -0
  154. package/.output/server/chunks/routes/api/{project → tasks}/settings.get.mjs +10 -11
  155. package/.output/server/chunks/routes/api/tasks/start.get.mjs +40 -0
  156. package/.output/server/chunks/routes/api/tasks/tell.post.mjs +39 -0
  157. package/.output/server/chunks/routes/api/tasks.get.mjs +39 -0
  158. package/.output/server/chunks/routes/api/unqueue.post.mjs +7 -6
  159. package/.output/server/chunks/routes/api/update/status.get.mjs +6 -5
  160. package/.output/server/chunks/routes/api/update.get.mjs +8 -10
  161. package/.output/server/chunks/routes/api/update.post.mjs +8 -10
  162. package/.output/server/chunks/routes/api/upload.post.mjs +7 -6
  163. package/.output/server/chunks/routes/api/worktrees/remove.post.mjs +6 -5
  164. package/.output/server/chunks/routes/api/worktrees.get.mjs +6 -5
  165. package/.output/server/chunks/routes/favicon.ico.get.mjs +6 -5
  166. package/.output/server/chunks/routes/icons/_name_.get.mjs +7 -6
  167. package/.output/server/chunks/routes/renderer.mjs +8 -7
  168. package/.output/server/chunks/routes/uploads/_...name_.get.mjs +7 -6
  169. package/.output/server/chunks/routes/ws/_..._.mjs +7 -6
  170. package/.output/server/chunks/routes/ws/events.mjs +9 -7
  171. package/.output/server/chunks/routes/ws/term.mjs +7 -6
  172. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  173. package/.output/server/index.mjs +7 -6
  174. package/.output/server/package.json +1 -1
  175. package/README.md +44 -1424
  176. package/bin/lib/commands.mjs +44 -9
  177. package/bin/lib/panel.mjs +3 -11
  178. package/bin/lib/service.mjs +41 -2
  179. package/bin/lib/skill.mjs +1 -1
  180. package/bin/lib/tailnet.d.mts +6 -3
  181. package/bin/lib/tailnet.mjs +70 -32
  182. package/bin/lib/userpath.d.mts +14 -0
  183. package/bin/lib/userpath.mjs +142 -0
  184. package/docs/README.md +58 -0
  185. package/docs/RELEASING.md +174 -0
  186. package/docs/board.md +164 -0
  187. package/docs/command.md +58 -0
  188. package/docs/configuration.md +39 -0
  189. package/docs/conversation.md +132 -0
  190. package/docs/development.md +38 -0
  191. package/docs/devices.md +58 -0
  192. package/docs/files.md +29 -0
  193. package/docs/herdr-projects-1x.md +278 -0
  194. package/docs/home.md +52 -0
  195. package/docs/installation.md +174 -0
  196. package/docs/machines.md +69 -0
  197. package/docs/migrate-from-1.x-docker.md +160 -0
  198. package/docs/networks.md +154 -0
  199. package/docs/notifications.md +83 -0
  200. package/docs/overview.md +71 -0
  201. package/docs/phone.md +26 -0
  202. package/docs/plugins.md +109 -0
  203. package/docs/quick-start.md +89 -0
  204. package/docs/quotas.md +65 -0
  205. package/docs/release-notes-2.0.0.md +84 -0
  206. package/docs/security.md +117 -0
  207. package/docs/terminal.md +15 -0
  208. package/docs/troubleshooting.md +45 -0
  209. package/package.json +11 -3
  210. package/skills/wherdr/SKILL.md +24 -167
  211. package/.output/public/_nuxt/B4Yk2tB1.js +0 -23
  212. package/.output/public/_nuxt/BBw_0a4M.js +0 -6
  213. package/.output/public/_nuxt/BSy6OCIY.js +0 -1
  214. package/.output/public/_nuxt/BX5PM2JQ.js +0 -1
  215. package/.output/public/_nuxt/BgPDnf2S.js +0 -1
  216. package/.output/public/_nuxt/BkOxQzbS.js +0 -2
  217. package/.output/public/_nuxt/CP8o925U.js +0 -1
  218. package/.output/public/_nuxt/CWwyK2XK.js +0 -2
  219. package/.output/public/_nuxt/CkbmecwS.js +0 -1
  220. package/.output/public/_nuxt/Cr3SrGky.js +0 -1
  221. package/.output/public/_nuxt/DAg9fiVh.js +0 -89
  222. package/.output/public/_nuxt/DT8qZ0Wv.js +0 -1
  223. package/.output/public/_nuxt/DaaJIRB3.js +0 -1
  224. package/.output/public/_nuxt/DcJi16XA.js +0 -1
  225. package/.output/public/_nuxt/SiL1FJ5s.js +0 -3
  226. package/.output/public/_nuxt/VpjCgSXu.js +0 -36
  227. package/.output/public/_nuxt/builds/meta/c735b6c0-1bd0-47d7-a208-d310f0a06287.json +0 -1
  228. package/.output/public/_nuxt/dPxB2L94.js +0 -89
  229. package/.output/public/_nuxt/entry.CGWKmYU3.css +0 -2
  230. package/.output/public/_nuxt/xYX85SPI.js +0 -1
  231. package/.output/server/chunks/_/pluginPolicy.mjs +0 -93
  232. package/.output/server/chunks/_/projectBoard.mjs +0 -366
  233. package/.output/server/chunks/_/projectDocs.mjs +0 -106
  234. package/.output/server/chunks/_/projectInbox.mjs +0 -135
  235. package/.output/server/chunks/_/projectThreads.mjs +0 -46
  236. package/.output/server/chunks/_/projectThreads2.mjs +0 -61
  237. package/.output/server/chunks/_/projectsActions.mjs +0 -143
  238. package/.output/server/chunks/_/projectsPlugin.mjs +0 -56
  239. package/.output/server/chunks/_/reveal.mjs +0 -115
  240. package/.output/server/chunks/raw/dev.wherdr.open.mjs +0 -7
  241. package/.output/server/chunks/raw/docker-entrypoint.mjs +0 -7
  242. package/.output/server/chunks/raw/install-host-open.mjs +0 -7
  243. package/.output/server/chunks/raw/wherdr-open.mjs +0 -7
  244. package/.output/server/chunks/routes/api/board.get.mjs +0 -147
  245. package/.output/server/chunks/routes/api/plugins/thread-limits.post.mjs +0 -45
  246. package/.output/server/chunks/routes/api/project/inbox.get.mjs +0 -43
  247. package/.output/server/chunks/routes/api/project/inbox.post.mjs +0 -43
  248. package/.output/server/chunks/routes/api/project/memory.get.mjs +0 -42
  249. package/.output/server/chunks/routes/api/project/routines.get.mjs +0 -43
  250. package/.output/server/chunks/routes/api/project/thread.get.mjs +0 -44
  251. package/.output/server/chunks/routes/api/project/thread.post.mjs +0 -45
  252. package/bin/install-docker-skill.sh +0 -20
@@ -1,5 +1,6 @@
1
- import { a as defineApi } from '../../nitro/nitro.mjs';
2
- import { r as revealPath } from '../../_/reveal.mjs';
1
+ import { H as HerdrError, br as PANE_RE, f as findPane, $ as getMachine, a_ as splitId, t as fmt, aa as log, a as defineApi } from '../../nitro/nitro.mjs';
2
+ import { execFile } from 'node:child_process';
3
+ import { r as resolveAgentPath, a as runnablePath } from '../../_/filePaths.mjs';
3
4
  import 'node:http';
4
5
  import 'node:https';
5
6
  import 'node:crypto';
@@ -17,19 +18,101 @@ import 'node:events';
17
18
  import 'node:buffer';
18
19
  import 'node:fs';
19
20
  import 'node:path';
20
- import 'web-push';
21
21
  import 'node:os';
22
- import 'node:child_process';
23
22
  import 'node:net';
24
- import 'node:fs/promises';
25
- import 'node:readline';
26
23
  import 'node:dns';
27
24
  import 'node:util';
25
+ import 'web-push';
26
+ import 'node:string_decoder';
27
+ import 'node:fs/promises';
28
+ import 'node:readline';
28
29
  import 'qrcode-terminal/vendor/QRCode/index.js';
29
30
  import 'qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js';
30
- import '@simplewebauthn/server';
31
31
  import 'node:url';
32
- import '../../_/filePaths.mjs';
32
+ import '@simplewebauthn/server';
33
+
34
+ const REVEAL_CHECKS = `p=$2
35
+ [ -e "$p" ] || exit 3
36
+ if command -v realpath >/dev/null 2>&1; then
37
+ r=$(realpath "$p" 2>/dev/null) || exit 3
38
+ h=$(realpath "$HOME" 2>/dev/null) || exit 4
39
+ elif [ -d "$p" ]; then
40
+ r=$(cd -P "$p" 2>/dev/null && pwd -P) || exit 3
41
+ h=$(cd -P "$HOME" 2>/dev/null && pwd -P) || exit 4
42
+ else
43
+ d=$(cd -P "$(dirname "$p")" 2>/dev/null && pwd -P) || exit 3
44
+ r="$d/$(basename "$p")"
45
+ [ -L "$r" ] && [ "$1" = open ] && exit 4
46
+ h=$(cd -P "$HOME" 2>/dev/null && pwd -P) || exit 4
47
+ fi
48
+ case "$r/" in "$h"/*) ;; *) exit 4 ;; esac
49
+ [ "$(uname -s)" = Darwin ] || exit 5
50
+ if [ "$1" = open ]; then
51
+ case "$r" in *.app|*.app/*|*.command|*.tool|*.terminal|*.pkg|*.mpkg|*.workflow|*.scpt|*.applescript|*.jar|*.webloc|*.inetloc|*.fileloc|*.dmg) exit 7 ;; esac
52
+ if [ -f "$r" ] && [ -x "$r" ]; then exit 7; fi
53
+ # A folder opens in the configured editor (WH_OPEN_EDITOR, or the first line
54
+ # of ~/.local/share/wherdr/editor \u2014 an app name for open -a); plain open
55
+ # would give the file manager. Files: the LaunchServices default app.
56
+ ed=\${WH_OPEN_EDITOR:-}
57
+ if [ -z "$ed" ] && [ -f "$HOME/.local/share/wherdr/editor" ]; then
58
+ ed=$(head -n1 "$HOME/.local/share/wherdr/editor" | tr -d '[:space:]')
59
+ fi
60
+ if [ -d "$r" ] && [ -n "$ed" ]; then
61
+ open -a "$ed" "$r" || exit 6
62
+ else
63
+ open "$r" || exit 6
64
+ fi
65
+ else
66
+ open -R "$r" || exit 6
67
+ fi
68
+ echo "$r"`;
69
+ const REVEAL_SCRIPT = REVEAL_CHECKS;
70
+ const revealArgs = (mode, absPath) => [mode, absPath];
71
+ const isMac = (m) => m.os === "Darwin";
72
+ function runLocal(script, args) {
73
+ const { promise, resolve } = Promise.withResolvers();
74
+ execFile("/bin/sh", ["-c", script, "sh", ...args], { timeout: 15e3, encoding: "buffer" }, (err, stdout, stderr) => {
75
+ const raw = err ? typeof err === "object" && err !== null && "code" in err ? err.code : void 0 : 0;
76
+ resolve({ code: typeof raw === "number" ? raw : err ? 1 : 0, stdout, stderr: String(stderr || "") });
77
+ });
78
+ return promise;
79
+ }
80
+ function revealError(code, p, m, stderr = "") {
81
+ switch (code) {
82
+ case 3:
83
+ return new HerdrError("not_found", fmt("Not found on {machine}: {path}", { machine: m.label, path: p }));
84
+ case 4:
85
+ return new HerdrError("outside_home", "Only files in your home folder can be shown");
86
+ case 5:
87
+ return new HerdrError("not_mac", fmt("{machine} is not a Mac", { machine: m.label }));
88
+ case 7:
89
+ return new HerdrError("runnable", "Apps and scripts are not opened from wherdr: use Reveal in Finder");
90
+ default:
91
+ return new HerdrError("open_failed", fmt("Could not open on {machine}: {reason}", { machine: m.label, reason: stderr.trim().split("\n").pop() || `code ${code}` }));
92
+ }
93
+ }
94
+ async function revealPath(body) {
95
+ const paneId = String(body.pane_id || "");
96
+ const written = String(body.path || "");
97
+ const mode = body.mode === "open" ? "open" : body.mode === "reveal" ? "reveal" : null;
98
+ if (!mode) throw new HerdrError("bad_mode", "Invalid action");
99
+ if (!PANE_RE.test(paneId)) throw new HerdrError("bad_pane", "Invalid pane");
100
+ const pane = findPane(paneId);
101
+ if (!pane) throw new HerdrError("bad_pane", "Pane not found");
102
+ if (!written || written.length > 1024) throw new HerdrError("bad_path", "Invalid path");
103
+ const m = getMachine(splitId(paneId).machine);
104
+ if (!m) throw new HerdrError("bad_machine", "unknown machine");
105
+ if (!m.local && (m.status !== "online" || !m.home)) throw new HerdrError("unreachable", fmt("{machine} is unreachable", { machine: m.label }));
106
+ if (!isMac(m)) throw new HerdrError("not_mac", fmt("{machine} is not a Mac", { machine: m.label }));
107
+ const abs = resolveAgentPath(written, pane.cwd, m.home);
108
+ if (!abs) throw new HerdrError("outside_home", "Only files in your home folder can be shown");
109
+ if (mode === "open" && runnablePath(abs)) throw revealError(7, abs, m);
110
+ const args = revealArgs(mode, abs);
111
+ const r = m.local ? await runLocal(REVEAL_SCRIPT, args) : await m.exec(REVEAL_SCRIPT, args, { timeoutMs: 15e3 });
112
+ log(`reveal: ${mode} on ${m.label} for ${paneId}: ${r.code === 0 ? "ok" : `refused (code ${r.code})`}`);
113
+ if (r.code !== 0) throw revealError(r.code, abs, m, r.stderr);
114
+ return { ok: true, mode, path: r.stdout.toString("utf8").trim() || abs, machine: m.label };
115
+ }
33
116
 
34
117
  const reveal_post = defineApi((event, b) => revealPath(b));
35
118
 
@@ -1,4 +1,4 @@
1
- import { a as defineApi, P as PANE_RE, H as HerdrError, h as herdr, bn as parseWaitScreen, O as parseChoices, g as choicesCache, p as poll } from '../../nitro/nitro.mjs';
1
+ import { a as defineApi, P as PANE_RE, H as HerdrError, h as herdr, bs as parseWaitScreen, K as parseChoices, bt as waitIdentity, g as choicesCache, p as poll } from '../../nitro/nitro.mjs';
2
2
  import 'node:http';
3
3
  import 'node:https';
4
4
  import 'node:crypto';
@@ -16,30 +16,34 @@ import 'node:events';
16
16
  import 'node:buffer';
17
17
  import 'node:fs';
18
18
  import 'node:path';
19
- import 'web-push';
20
19
  import 'node:os';
21
- import 'node:child_process';
22
20
  import 'node:net';
23
- import 'node:fs/promises';
24
- import 'node:readline';
21
+ import 'node:child_process';
25
22
  import 'node:dns';
26
23
  import 'node:util';
24
+ import 'web-push';
25
+ import 'node:string_decoder';
26
+ import 'node:fs/promises';
27
+ import 'node:readline';
27
28
  import 'qrcode-terminal/vendor/QRCode/index.js';
28
29
  import 'qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js';
29
- import '@simplewebauthn/server';
30
30
  import 'node:url';
31
+ import '@simplewebauthn/server';
31
32
 
32
33
  const screenKey_post = defineApi(async (event, b) => {
33
34
  if (!PANE_RE.test(b.pane_id || "")) throw new HerdrError("bad_pane", "Invalid pane");
34
- const r = await herdr("pane.read", { pane_id: b.pane_id, source: "detection" }, 4e3);
35
- const text = r.read && r.read.text;
36
- const screen = parseWaitScreen(text, { choices: Boolean(parseChoices(text, { strict: true })) });
37
- const a = screen && screen.actions.find((x) => x.key === b.key && x.label === b.label);
38
- if (!a) throw new HerdrError("stale", "The screen has changed \u2014 check the current screen.");
39
- await herdr("pane.send_input", { pane_id: b.pane_id, keys: [a.key] });
40
- choicesCache.delete(b.pane_id);
41
- setTimeout(poll, 300);
42
- return { ok: true };
35
+ try {
36
+ const r = await herdr("pane.read", { pane_id: b.pane_id, source: "detection" }, 4e3);
37
+ const text = r.read && r.read.text;
38
+ const screen = parseWaitScreen(text, { choices: Boolean(parseChoices(text, { strict: true })) });
39
+ const a = screen && screen.actions.find((x) => x.key === b.key && x.label === b.label);
40
+ if (!a || !b.identity || !screen || waitIdentity(screen) !== b.identity) throw new HerdrError("stale", "The screen has changed \u2014 check the current screen.");
41
+ await herdr("pane.send_input", { pane_id: b.pane_id, keys: [a.key] });
42
+ return { ok: true };
43
+ } finally {
44
+ choicesCache.delete(b.pane_id);
45
+ setTimeout(poll, 0);
46
+ }
43
47
  });
44
48
 
45
49
  export { screenKey_post as default };
@@ -1,4 +1,5 @@
1
- import { a as defineApi, i as getQuery, P as PANE_RE, H as HerdrError, h as herdr, bo as settingsTabs, bp as tabsOfRow, f as findPane, bq as classifyScreen, bn as parseWaitScreen, br as parseMenu, b as screenChoices } from '../../nitro/nitro.mjs';
1
+ import { a as defineApi, i as getQuery, P as PANE_RE, H as HerdrError, h as herdr, bu as settingsTabs, bv as tabsOfRow, f as findPane, bw as classifyScreen, bs as parseWaitScreen, bx as parseMenu, b as screenChoices } from '../../nitro/nitro.mjs';
2
+ import { a as activeTab } from '../../_/settingstabs.mjs';
2
3
  import 'node:http';
3
4
  import 'node:https';
4
5
  import 'node:crypto';
@@ -16,52 +17,19 @@ import 'node:events';
16
17
  import 'node:buffer';
17
18
  import 'node:fs';
18
19
  import 'node:path';
19
- import 'web-push';
20
20
  import 'node:os';
21
- import 'node:child_process';
22
21
  import 'node:net';
23
- import 'node:fs/promises';
24
- import 'node:readline';
22
+ import 'node:child_process';
25
23
  import 'node:dns';
26
24
  import 'node:util';
25
+ import 'web-push';
26
+ import 'node:string_decoder';
27
+ import 'node:fs/promises';
28
+ import 'node:readline';
27
29
  import 'qrcode-terminal/vendor/QRCode/index.js';
28
30
  import 'qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js';
29
- import '@simplewebauthn/server';
30
31
  import 'node:url';
31
-
32
- const SGR = /\x1b\[([\d;]*)m/g;
33
- function highlight(params, state) {
34
- const codes = params === "" ? [0] : params.split(";").map(Number);
35
- for (let i = 0; i < codes.length; i++) {
36
- const c = codes[i];
37
- if (c === 38 || c === 48 || c === 58) {
38
- if (c === 48) state.bg = true;
39
- i += codes[i + 1] === 5 ? 2 : codes[i + 1] === 2 ? 4 : 0;
40
- } else if (c === 0) {
41
- state.bg = false;
42
- state.inverse = false;
43
- } else if (c === 7) state.inverse = true;
44
- else if (c === 27) state.inverse = false;
45
- else if (c === 49) state.bg = false;
46
- else if (c >= 40 && c <= 47) state.bg = true;
47
- }
48
- }
49
- function activeTab(line) {
50
- const state = { bg: false, inverse: false };
51
- let last = 0;
52
- const words = [];
53
- const push = (s) => {
54
- for (const w of s.split(/\s+/)) if (w) words.push({ text: w, bg: state.bg || state.inverse });
55
- };
56
- for (const m of line.matchAll(SGR)) {
57
- push(line.slice(last, m.index));
58
- highlight(m[1], state);
59
- last = m.index + m[0].length;
60
- }
61
- push(line.slice(last));
62
- const hit = words.find((w) => w.bg && w.text !== "Settings");
63
- return hit ? hit.text.replace(/[^\w]/g, "") : null;
64
- }
32
+ import '@simplewebauthn/server';
65
33
 
66
34
  const screen_get = defineApi(async (event) => {
67
35
  const pane = String(getQuery(event).pane || "");
@@ -1,4 +1,4 @@
1
- import { a as defineApi, i as getQuery, m as getState, bs as hasTranscript, D as machineOfPane, bt as SEARCH_DEADLINE_MS, bu as SEARCH_MAX_RESULTS, bv as spaceTitle } from '../../nitro/nitro.mjs';
1
+ import { a as defineApi, i as getQuery, a$ as getState, by as hasTranscript, q as machineOfPane, bz as SEARCH_DEADLINE_MS, bA as SEARCH_MAX_RESULTS, bB as spaceTitle } from '../../nitro/nitro.mjs';
2
2
  import 'node:http';
3
3
  import 'node:https';
4
4
  import 'node:crypto';
@@ -16,18 +16,19 @@ import 'node:events';
16
16
  import 'node:buffer';
17
17
  import 'node:fs';
18
18
  import 'node:path';
19
- import 'web-push';
20
19
  import 'node:os';
21
- import 'node:child_process';
22
20
  import 'node:net';
23
- import 'node:fs/promises';
24
- import 'node:readline';
21
+ import 'node:child_process';
25
22
  import 'node:dns';
26
23
  import 'node:util';
24
+ import 'web-push';
25
+ import 'node:string_decoder';
26
+ import 'node:fs/promises';
27
+ import 'node:readline';
27
28
  import 'qrcode-terminal/vendor/QRCode/index.js';
28
29
  import 'qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js';
29
- import '@simplewebauthn/server';
30
30
  import 'node:url';
31
+ import '@simplewebauthn/server';
31
32
 
32
33
  const search_get = defineApi(async (event) => {
33
34
  const query = String(getQuery(event).q || "").trim().slice(0, 100);
@@ -1,4 +1,4 @@
1
- import { a as defineApi, P as PANE_RE, H as HerdrError, bw as markSeen } from '../../nitro/nitro.mjs';
1
+ import { a as defineApi, P as PANE_RE, H as HerdrError, bC as markSeen } from '../../nitro/nitro.mjs';
2
2
  import 'node:http';
3
3
  import 'node:https';
4
4
  import 'node:crypto';
@@ -16,18 +16,19 @@ import 'node:events';
16
16
  import 'node:buffer';
17
17
  import 'node:fs';
18
18
  import 'node:path';
19
- import 'web-push';
20
19
  import 'node:os';
21
- import 'node:child_process';
22
20
  import 'node:net';
23
- import 'node:fs/promises';
24
- import 'node:readline';
21
+ import 'node:child_process';
25
22
  import 'node:dns';
26
23
  import 'node:util';
24
+ import 'web-push';
25
+ import 'node:string_decoder';
26
+ import 'node:fs/promises';
27
+ import 'node:readline';
27
28
  import 'qrcode-terminal/vendor/QRCode/index.js';
28
29
  import 'qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js';
29
- import '@simplewebauthn/server';
30
30
  import 'node:url';
31
+ import '@simplewebauthn/server';
31
32
 
32
33
  const seen_post = defineApi(async (event, b) => {
33
34
  if (!PANE_RE.test(b.pane_id || "")) throw new HerdrError("bad_pane", "Invalid pane");
@@ -1,4 +1,4 @@
1
- import { a as defineApi, i as getQuery, bx as listSessions } from '../../nitro/nitro.mjs';
1
+ import { a as defineApi, i as getQuery, bD as listSessions } from '../../nitro/nitro.mjs';
2
2
  import 'node:http';
3
3
  import 'node:https';
4
4
  import 'node:crypto';
@@ -16,18 +16,19 @@ import 'node:events';
16
16
  import 'node:buffer';
17
17
  import 'node:fs';
18
18
  import 'node:path';
19
- import 'web-push';
20
19
  import 'node:os';
21
- import 'node:child_process';
22
20
  import 'node:net';
23
- import 'node:fs/promises';
24
- import 'node:readline';
21
+ import 'node:child_process';
25
22
  import 'node:dns';
26
23
  import 'node:util';
24
+ import 'web-push';
25
+ import 'node:string_decoder';
26
+ import 'node:fs/promises';
27
+ import 'node:readline';
27
28
  import 'qrcode-terminal/vendor/QRCode/index.js';
28
29
  import 'qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js';
29
- import '@simplewebauthn/server';
30
30
  import 'node:url';
31
+ import '@simplewebauthn/server';
31
32
 
32
33
  const sessions_get = defineApi(async (event) => {
33
34
  const key = String(getQuery(event).machine || "");
@@ -1,4 +1,4 @@
1
- import { a as defineApi, H as HerdrError, by as openSession } from '../../nitro/nitro.mjs';
1
+ import { a as defineApi, H as HerdrError, bE as openSession } from '../../nitro/nitro.mjs';
2
2
  import 'node:http';
3
3
  import 'node:https';
4
4
  import 'node:crypto';
@@ -16,18 +16,19 @@ import 'node:events';
16
16
  import 'node:buffer';
17
17
  import 'node:fs';
18
18
  import 'node:path';
19
- import 'web-push';
20
19
  import 'node:os';
21
- import 'node:child_process';
22
20
  import 'node:net';
23
- import 'node:fs/promises';
24
- import 'node:readline';
21
+ import 'node:child_process';
25
22
  import 'node:dns';
26
23
  import 'node:util';
24
+ import 'web-push';
25
+ import 'node:string_decoder';
26
+ import 'node:fs/promises';
27
+ import 'node:readline';
27
28
  import 'qrcode-terminal/vendor/QRCode/index.js';
28
29
  import 'qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js';
29
- import '@simplewebauthn/server';
30
30
  import 'node:url';
31
+ import '@simplewebauthn/server';
31
32
 
32
33
  const sessions_post = defineApi(async (_event, body) => {
33
34
  if (typeof body.machine !== "string" || typeof body.name !== "string") throw new HerdrError("bad_session", "Invalid session");
@@ -0,0 +1,90 @@
1
+ import { a as defineApi, P as PANE_RE, H as HerdrError, f as findPane, h as herdr, bu as settingsTabs, bv as tabsOfRow, bF as settingsFocus, X as sleep, g as choicesCache } from '../../nitro/nitro.mjs';
2
+ import { a as activeTab } from '../../_/settingstabs.mjs';
3
+ import 'node:http';
4
+ import 'node:https';
5
+ import 'node:crypto';
6
+ import 'stream';
7
+ import 'events';
8
+ import 'http';
9
+ import 'crypto';
10
+ import 'buffer';
11
+ import 'zlib';
12
+ import 'https';
13
+ import 'net';
14
+ import 'tls';
15
+ import 'url';
16
+ import 'node:events';
17
+ import 'node:buffer';
18
+ import 'node:fs';
19
+ import 'node:path';
20
+ import 'node:os';
21
+ import 'node:net';
22
+ import 'node:child_process';
23
+ import 'node:dns';
24
+ import 'node:util';
25
+ import 'web-push';
26
+ import 'node:string_decoder';
27
+ import 'node:fs/promises';
28
+ import 'node:readline';
29
+ import 'qrcode-terminal/vendor/QRCode/index.js';
30
+ import 'qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js';
31
+ import 'node:url';
32
+ import '@simplewebauthn/server';
33
+
34
+ const switching = /* @__PURE__ */ new Set();
35
+ const settingsTab_post = defineApi(async (_event, b) => {
36
+ var _a;
37
+ const pane = String(b.pane_id || "");
38
+ const target = String(b.target || "");
39
+ if (!PANE_RE.test(pane)) throw new HerdrError("bad_pane", "Invalid pane");
40
+ if (((_a = findPane(pane)) == null ? void 0 : _a.agent) !== "claude") throw new HerdrError("stale", "Settings are no longer open.");
41
+ if (switching.has(pane)) throw new HerdrError("busy", "Settings tab change already in progress.");
42
+ const read = async () => {
43
+ var _a2;
44
+ const r = await herdr("pane.read", { pane_id: pane, source: "visible", format: "ansi" }, 4e3);
45
+ const ansi = String(((_a2 = r.read) == null ? void 0 : _a2.text) || "");
46
+ const text = ansi.replace(/\x1b\[[\d;]*m|\r/g, "");
47
+ const tabs = settingsTabs(text);
48
+ const row = ansi.split("\n").find((l) => tabsOfRow(l.replace(/\x1b\[[\d;]*m|\r/g, "")));
49
+ const tab = row && activeTab(row);
50
+ if (!tabs || !tab || !tabs.includes(tab) || !tabs.includes(target)) throw new HerdrError("stale", "Settings have changed.");
51
+ return { text, tabs, tab, ansi };
52
+ };
53
+ switching.add(pane);
54
+ try {
55
+ let screen = await read();
56
+ for (let step = 0; screen.tab !== target; step++) {
57
+ if (step >= screen.tabs.length) throw new HerdrError("stale", "Could not switch settings tabs. Open the terminal and try again.");
58
+ for (let up = 0; screen.tab === "Config" && settingsFocus(screen.text) !== "tabs"; up++) {
59
+ if (up >= 100 || settingsFocus(screen.text) === null) throw new HerdrError("stale", "Use the terminal to focus the settings tabs.");
60
+ const before = screen;
61
+ await herdr("pane.send_input", { pane_id: pane, keys: ["up"] });
62
+ for (let attempt = 0; attempt < 15; attempt++) {
63
+ await sleep(100);
64
+ screen = await read();
65
+ if (screen.ansi !== before.ansi) break;
66
+ }
67
+ if (screen.tab !== before.tab) throw new HerdrError("stale", "Settings have changed.");
68
+ if (screen.ansi === before.ansi) throw new HerdrError("stale", "Use the terminal to focus the settings tabs.");
69
+ }
70
+ if (screen.tab === target) break;
71
+ const direction = screen.tabs.indexOf(target) > screen.tabs.indexOf(screen.tab) ? 1 : -1;
72
+ const next = screen.tabs[screen.tabs.indexOf(screen.tab) + direction];
73
+ const previous = screen.tab;
74
+ await herdr("pane.send_input", { pane_id: pane, keys: [direction > 0 ? "right" : "left"] });
75
+ for (let attempt = 0; attempt < 15; attempt++) {
76
+ await sleep(100);
77
+ screen = await read();
78
+ if (screen.tab !== previous) break;
79
+ }
80
+ if (screen.tab !== next) throw new HerdrError("stale", "Could not switch settings tabs. Open the terminal and try again.");
81
+ }
82
+ return { ok: true, tab: screen.tab };
83
+ } finally {
84
+ choicesCache.delete(pane);
85
+ switching.delete(pane);
86
+ }
87
+ });
88
+
89
+ export { settingsTab_post as default };
90
+ //# sourceMappingURL=settings-tab.post.mjs.map
@@ -1,4 +1,4 @@
1
- import { a as defineApi, u as currentMachineSlots } from '../../../nitro/nitro.mjs';
1
+ import { a as defineApi, bG as readSettings } from '../../nitro/nitro.mjs';
2
2
  import 'node:http';
3
3
  import 'node:https';
4
4
  import 'node:crypto';
@@ -16,20 +16,21 @@ import 'node:events';
16
16
  import 'node:buffer';
17
17
  import 'node:fs';
18
18
  import 'node:path';
19
- import 'web-push';
20
19
  import 'node:os';
21
- import 'node:child_process';
22
20
  import 'node:net';
23
- import 'node:fs/promises';
24
- import 'node:readline';
21
+ import 'node:child_process';
25
22
  import 'node:dns';
26
23
  import 'node:util';
24
+ import 'web-push';
25
+ import 'node:string_decoder';
26
+ import 'node:fs/promises';
27
+ import 'node:readline';
27
28
  import 'qrcode-terminal/vendor/QRCode/index.js';
28
29
  import 'qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js';
29
- import '@simplewebauthn/server';
30
30
  import 'node:url';
31
+ import '@simplewebauthn/server';
31
32
 
32
- const threadLimits_get = defineApi(async () => ({ machines: await currentMachineSlots() }));
33
+ const settings_get = defineApi(async () => ({ settings: await readSettings() }));
33
34
 
34
- export { threadLimits_get as default };
35
- //# sourceMappingURL=thread-limits.get.mjs.map
35
+ export { settings_get as default };
36
+ //# sourceMappingURL=settings.get.mjs.map
@@ -0,0 +1,40 @@
1
+ import { a as defineApi, bH as cleanSettingsPatch, H as HerdrError, bI as patchSettings } from '../../nitro/nitro.mjs';
2
+ import 'node:http';
3
+ import 'node:https';
4
+ import 'node:crypto';
5
+ import 'stream';
6
+ import 'events';
7
+ import 'http';
8
+ import 'crypto';
9
+ import 'buffer';
10
+ import 'zlib';
11
+ import 'https';
12
+ import 'net';
13
+ import 'tls';
14
+ import 'url';
15
+ import 'node:events';
16
+ import 'node:buffer';
17
+ import 'node:fs';
18
+ import 'node:path';
19
+ import 'node:os';
20
+ import 'node:net';
21
+ import 'node:child_process';
22
+ import 'node:dns';
23
+ import 'node:util';
24
+ import 'web-push';
25
+ import 'node:string_decoder';
26
+ import 'node:fs/promises';
27
+ import 'node:readline';
28
+ import 'qrcode-terminal/vendor/QRCode/index.js';
29
+ import 'qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js';
30
+ import 'node:url';
31
+ import '@simplewebauthn/server';
32
+
33
+ const settings_post = defineApi(async (_event, body) => {
34
+ const patch = cleanSettingsPatch(body.settings);
35
+ if (!patch) throw new HerdrError("bad_settings", "Invalid settings");
36
+ return { settings: await patchSettings(patch, { onlyMissing: body.migrate === true }) };
37
+ });
38
+
39
+ export { settings_post as default };
40
+ //# sourceMappingURL=settings.post.mjs.map
@@ -1,4 +1,4 @@
1
- import { bz as PANE_DIRECTIONS, at as splitId, as as PANE_RE, a as defineApi, H as HerdrError, ab as log, p as poll, x as herdrOn } from '../../nitro/nitro.mjs';
1
+ import { bJ as PANE_DIRECTIONS, a_ as splitId, br as PANE_RE, a as defineApi, H as HerdrError, aa as log, p as poll, aZ as herdrOn } from '../../nitro/nitro.mjs';
2
2
  import 'node:http';
3
3
  import 'node:https';
4
4
  import 'node:crypto';
@@ -16,18 +16,19 @@ import 'node:events';
16
16
  import 'node:buffer';
17
17
  import 'node:fs';
18
18
  import 'node:path';
19
- import 'web-push';
20
19
  import 'node:os';
21
- import 'node:child_process';
22
20
  import 'node:net';
23
- import 'node:fs/promises';
24
- import 'node:readline';
21
+ import 'node:child_process';
25
22
  import 'node:dns';
26
23
  import 'node:util';
24
+ import 'web-push';
25
+ import 'node:string_decoder';
26
+ import 'node:fs/promises';
27
+ import 'node:readline';
27
28
  import 'qrcode-terminal/vendor/QRCode/index.js';
28
29
  import 'qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js';
29
- import '@simplewebauthn/server';
30
30
  import 'node:url';
31
+ import '@simplewebauthn/server';
31
32
 
32
33
  var __defProp = Object.defineProperty;
33
34
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -153,17 +154,17 @@ function spaceResult(call, r) {
153
154
  }
154
155
  return {};
155
156
  }
156
- function swapSteps(snap, pane, target2) {
157
- if (!target2 || target2 === pane) fail("no_neighbor", "no pane on that side");
157
+ function swapSteps(snap, pane, target) {
158
+ if (!target || target === pane) fail("no_neighbor", "no pane on that side");
158
159
  const layouts = Array.isArray(snap == null ? void 0 : snap.layouts) ? snap.layouts : [];
159
160
  const tab = layouts.find((l) => {
160
161
  var _a;
161
162
  return (_a = l.panes) == null ? void 0 : _a.some((p) => p.pane_id === pane);
162
163
  });
163
- if (!tab || !tab.panes.some((p) => p.pane_id === target2)) fail("no_neighbor", "no pane on that side");
164
+ if (!tab || !tab.panes.some((p) => p.pane_id === target)) fail("no_neighbor", "no pane on that side");
164
165
  if (tab.zoomed) fail("zoomed", "a pane is zoomed in this tab");
165
166
  const tabFocus = tab.focused_pane_id || null;
166
- const [source, other] = tabFocus === target2 ? [target2, pane] : [pane, target2];
167
+ const [source, other] = tabFocus === target ? [target, pane] : [pane, target];
167
168
  return [{ method: "pane.swap", params: { source_pane_id: source, target_pane_id: other } }, ...refocus(snap, tab, source)];
168
169
  }
169
170
  function refocus(snap, tab, cur) {
@@ -178,24 +179,32 @@ function refocus(snap, tab, cur) {
178
179
  }
179
180
  return steps;
180
181
  }
181
- function dropSteps(snap, pane, target2, side) {
182
- if (side === "center") return swapSteps(snap, pane, target2);
183
- if (!target2 || target2 === pane) fail("no_neighbor", "same pane");
182
+ function dropSteps(snap, pane, target, side) {
183
+ if (side === "center") return swapSteps(snap, pane, target);
184
+ if (!target || target === pane) fail("no_neighbor", "same pane");
184
185
  const layouts = Array.isArray(snap == null ? void 0 : snap.layouts) ? snap.layouts : [];
185
186
  const tab = layouts.find((l) => {
186
187
  var _a;
187
188
  return (_a = l.panes) == null ? void 0 : _a.some((p) => p.pane_id === pane);
188
189
  });
189
- if (!tab || !tab.panes.some((p) => p.pane_id === target2)) fail("no_neighbor", "pane in another tab");
190
+ if (!tab || !tab.panes.some((p) => p.pane_id === target)) fail("no_neighbor", "pane in another tab");
190
191
  if (tab.zoomed) fail("zoomed", "a pane is zoomed in this tab");
191
192
  const before = side === "left" || side === "up";
192
193
  const steps = [
193
194
  { method: "pane.move", params: { pane_id: pane, destination: { type: "new_tab", workspace_id: tab.workspace_id }, focus: false } },
194
- { method: "pane.move", params: { pane_id: pane, destination: { type: "tab", tab_id: tab.tab_id, split: side === "left" || side === "right" ? "right" : "down", target_pane_id: target2 }, focus: false } }
195
+ { method: "pane.move", params: { pane_id: pane, destination: { type: "tab", tab_id: tab.tab_id, split: side === "left" || side === "right" ? "right" : "down", target_pane_id: target }, focus: false } }
195
196
  ];
196
- if (before) steps.push({ method: "pane.swap", params: { source_pane_id: pane, target_pane_id: target2 } });
197
+ if (before) steps.push({ method: "pane.swap", params: { source_pane_id: pane, target_pane_id: target } });
197
198
  return [...steps, ...refocus(snap, tab, before ? pane : null)];
198
199
  }
200
+ function verifySpaceRename(call, snapshot) {
201
+ var _a;
202
+ const tab = call.method === "tab.rename";
203
+ if (!tab && call.method !== "workspace.rename") return;
204
+ const key = tab ? "tab_id" : "workspace_id";
205
+ const target = (_a = tab ? snapshot == null ? void 0 : snapshot.tabs : snapshot == null ? void 0 : snapshot.workspaces) == null ? void 0 : _a.find((x) => x[key] === call.params[key]);
206
+ if (!target || target.label !== call.params.label) throw new SpaceActionError("rename_failed", "Rename failed. The name was not changed.");
207
+ }
199
208
 
200
209
  const space_post = defineApi(async (_event, body) => {
201
210
  let call;
@@ -212,14 +221,21 @@ const space_post = defineApi(async (_event, body) => {
212
221
  return { ok: true };
213
222
  }
214
223
  if (call.method === "pane.drop") {
215
- const { pane_id: pane, target_pane_id: target2, side } = call.params;
224
+ const { pane_id: pane, target_pane_id: target, side } = call.params;
216
225
  const snap = await herdrOn(call.machine, "session.snapshot", {}, 5e3);
217
- await runSteps(call.machine, stepsOf(() => dropSteps((snap == null ? void 0 : snap.snapshot) || snap, pane, target2, side)));
226
+ await runSteps(call.machine, stepsOf(() => dropSteps((snap == null ? void 0 : snap.snapshot) || snap, pane, target, side)));
218
227
  log(`space: pane.drop ${side}${call.machine ? ` (${call.machine})` : ""}`);
219
228
  poll();
220
229
  return { ok: true };
221
230
  }
222
231
  const r = await herdrOn(call.machine, call.method, call.params);
232
+ if (call.method === "workspace.rename" || call.method === "tab.rename") {
233
+ const snap = await herdrOn(call.machine, "session.snapshot", {}, 5e3);
234
+ stepsOf(() => {
235
+ verifySpaceRename(call, (snap == null ? void 0 : snap.snapshot) || snap);
236
+ return [];
237
+ });
238
+ }
223
239
  log(`space: ${call.method}${call.machine ? ` (${call.machine})` : ""}`);
224
240
  poll();
225
241
  return { ok: true, ...spaceResult(call, r) };