wherdr 1.3.4 → 2.0.1

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 (243) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/072bjdot.js +2 -0
  3. package/.output/public/_nuxt/8FAMamJX.js +1 -0
  4. package/.output/public/_nuxt/{AgentView.DzFWBd2A.css → AgentView.CfD2RWZY.css} +1 -1
  5. package/.output/public/_nuxt/BDNMzG2s.js +1 -0
  6. package/.output/public/_nuxt/BX8KVYfd.js +1 -0
  7. package/.output/public/_nuxt/{CJKsMzIp.js → BYZVrreW.js} +1 -1
  8. package/.output/public/_nuxt/C2aT0CgA.js +62 -0
  9. package/.output/public/_nuxt/CanLPS0U.js +105 -0
  10. package/.output/public/_nuxt/DGXKTg7D.js +31 -0
  11. package/.output/public/_nuxt/{DMLmW6JM.js → DOsw6KCR.js} +41 -42
  12. package/.output/public/_nuxt/DTiR5P9E.js +25 -0
  13. package/.output/public/_nuxt/{w7Rm7unj.js → DYKfeNM-.js} +1 -1
  14. package/.output/public/_nuxt/DZ7VvF3e.js +1 -0
  15. package/.output/public/_nuxt/DZGKxROq.js +6 -0
  16. package/.output/public/_nuxt/DeLLm2j1.js +23 -0
  17. package/.output/public/_nuxt/DumNBIyF.js +1 -0
  18. package/.output/public/_nuxt/ScQ9FtVj.js +1 -0
  19. package/.output/public/_nuxt/TS7GZUPU.js +9 -0
  20. package/.output/public/_nuxt/board.DK5EU4sL.css +1 -0
  21. package/.output/public/_nuxt/builds/latest.json +1 -1
  22. package/.output/public/_nuxt/builds/meta/b6ed1ddd-d6d6-4137-beab-2548b20dd998.json +1 -0
  23. package/.output/public/_nuxt/entry.BhiYrGAW.css +2 -0
  24. package/.output/public/_nuxt/settings.Cdb21nNw.css +1 -0
  25. package/.output/public/sw.js +1 -1
  26. package/.output/server/chunks/_/branding.mjs +1 -1
  27. package/.output/server/chunks/_/changes.mjs +4 -4
  28. package/.output/server/chunks/_/fileDownload.mjs +278 -0
  29. package/.output/server/chunks/_/files.mjs +44 -17
  30. package/.output/server/chunks/_/machineOrder.mjs +1 -1
  31. package/.output/server/chunks/_/onboarding.mjs +1 -1
  32. package/.output/server/chunks/_/package.mjs +9 -3
  33. package/.output/server/chunks/_/plugins.mjs +92 -125
  34. package/.output/server/chunks/_/restart.mjs +1 -1
  35. package/.output/server/chunks/_/selfupdate.mjs +1 -1
  36. package/.output/server/chunks/_/updates.mjs +1 -1
  37. package/.output/server/chunks/_/worktrees.mjs +1 -1
  38. package/.output/server/chunks/_/ws.mjs +43 -6
  39. package/.output/server/chunks/nitro/nitro.mjs +14073 -10658
  40. package/.output/server/chunks/raw/check-doc-links.mjs +5 -0
  41. package/.output/server/chunks/raw/check-leaks.mjs +1 -1
  42. package/.output/server/chunks/raw/check-release-notes.mjs +5 -0
  43. package/.output/server/chunks/raw/herdr-plugin.mjs +1 -1
  44. package/.output/server/chunks/raw/install-claude-statusline.mjs +1 -1
  45. package/.output/server/chunks/raw/prerelease-summary.mjs +5 -0
  46. package/.output/server/chunks/raw/prerelease.mjs +7 -0
  47. package/.output/server/chunks/raw/reveal.mjs +1 -1
  48. package/.output/server/chunks/raw/test-affected.mjs +5 -0
  49. package/.output/server/chunks/routes/api/_..._.mjs +6 -5
  50. package/.output/server/chunks/routes/api/agents.post.mjs +6 -5
  51. package/.output/server/chunks/routes/api/ask-tab.post.mjs +6 -5
  52. package/.output/server/chunks/routes/api/attach.post.mjs +6 -5
  53. package/.output/server/chunks/routes/api/auth/disable.post.mjs +6 -5
  54. package/.output/server/chunks/routes/api/auth/lock-all.post.mjs +6 -5
  55. package/.output/server/chunks/routes/api/auth/lock.post.mjs +6 -5
  56. package/.output/server/chunks/routes/api/auth/login/options.post.mjs +6 -5
  57. package/.output/server/chunks/routes/api/auth/login/verify.post.mjs +6 -5
  58. package/.output/server/chunks/routes/api/auth/max-session.post.mjs +6 -5
  59. package/.output/server/chunks/routes/api/auth/register/options.post.mjs +6 -5
  60. package/.output/server/chunks/routes/api/auth/register/verify.post.mjs +6 -5
  61. package/.output/server/chunks/routes/api/auth/status.get.mjs +6 -5
  62. package/.output/server/chunks/routes/api/changes.get.mjs +7 -6
  63. package/.output/server/chunks/routes/api/chat/image.get.mjs +7 -6
  64. package/.output/server/chunks/routes/api/chat.get.mjs +20 -7
  65. package/.output/server/chunks/routes/api/choose.post.mjs +31 -17
  66. package/.output/server/chunks/routes/api/claude-setup.post.mjs +42 -0
  67. package/.output/server/chunks/routes/api/claude-statusline.post.mjs +7 -6
  68. package/.output/server/chunks/routes/api/clear-queued-input.post.mjs +42 -0
  69. package/.output/server/chunks/routes/api/close/status.get.mjs +7 -6
  70. package/.output/server/chunks/routes/api/close.post.mjs +6 -5
  71. package/.output/server/chunks/routes/api/codex-update.post.mjs +7 -6
  72. package/.output/server/chunks/routes/api/commands.get.mjs +7 -6
  73. package/.output/server/chunks/routes/api/config.get.mjs +10 -13
  74. package/.output/server/chunks/routes/api/dirs.get.mjs +7 -6
  75. package/.output/server/chunks/routes/api/dismiss-stopped.post.mjs +7 -6
  76. package/.output/server/chunks/routes/api/dismiss.post.mjs +7 -6
  77. package/.output/server/chunks/routes/api/effort.post.mjs +7 -6
  78. package/.output/server/chunks/routes/api/efforts.get.mjs +7 -6
  79. package/.output/server/chunks/routes/api/file.post.mjs +7 -6
  80. package/.output/server/chunks/routes/api/files/download.get.mjs +12 -31
  81. package/.output/server/chunks/routes/api/files/download.head.mjs +41 -0
  82. package/.output/server/chunks/routes/api/files/read.get.mjs +8 -7
  83. package/.output/server/chunks/routes/api/files.get.mjs +7 -6
  84. package/.output/server/chunks/routes/api/health.get.mjs +6 -5
  85. package/.output/server/chunks/routes/api/input.post.mjs +7 -6
  86. package/.output/server/chunks/routes/api/interrupt.post.mjs +24 -21
  87. package/.output/server/chunks/routes/api/isgit.get.mjs +8 -8
  88. package/.output/server/chunks/routes/api/machine/awake.get.mjs +7 -6
  89. package/.output/server/chunks/routes/api/machine/awake.post.mjs +7 -6
  90. package/.output/server/chunks/routes/api/machine/order.get.mjs +6 -5
  91. package/.output/server/chunks/routes/api/machine/order.post.mjs +6 -5
  92. package/.output/server/chunks/routes/api/machine/reconnect.post.mjs +40 -0
  93. package/.output/server/chunks/routes/api/machine/rename.post.mjs +7 -6
  94. package/.output/server/chunks/routes/api/machine/status.post.mjs +39 -0
  95. package/.output/server/chunks/routes/api/menu-left.post.mjs +40 -0
  96. package/.output/server/chunks/routes/api/menu.post.mjs +7 -6
  97. package/.output/server/chunks/routes/api/model.post.mjs +7 -6
  98. package/.output/server/chunks/routes/api/models.get.mjs +7 -6
  99. package/.output/server/chunks/routes/api/nav.post.mjs +7 -6
  100. package/.output/server/chunks/routes/api/onboarding.get.mjs +6 -5
  101. package/.output/server/chunks/routes/api/onboarding.post.mjs +6 -5
  102. package/.output/server/chunks/routes/api/phone.get.mjs +8 -10
  103. package/.output/server/chunks/routes/api/phone.post.mjs +8 -10
  104. package/.output/server/chunks/routes/api/plugins/actions.get.mjs +6 -10
  105. package/.output/server/chunks/routes/api/plugins/invoke.post.mjs +6 -10
  106. package/.output/server/chunks/routes/api/plugins/projects.get.mjs +10 -9
  107. package/.output/server/chunks/routes/api/plugins/projects.post.mjs +11 -8
  108. package/.output/server/chunks/routes/api/prompt.post.mjs +22 -13
  109. package/.output/server/chunks/routes/api/push/quiet.post.mjs +7 -6
  110. package/.output/server/chunks/routes/api/push/subscribe.post.mjs +7 -7
  111. package/.output/server/chunks/routes/api/push/test.post.mjs +7 -6
  112. package/.output/server/chunks/routes/api/push/unsubscribe.post.mjs +7 -6
  113. package/.output/server/chunks/routes/api/quotas.get.mjs +7 -6
  114. package/.output/server/chunks/routes/api/rename.post.mjs +6 -5
  115. package/.output/server/chunks/routes/api/requeue.post.mjs +7 -6
  116. package/.output/server/chunks/routes/api/restart.get.mjs +6 -5
  117. package/.output/server/chunks/routes/api/restart.post.mjs +6 -5
  118. package/.output/server/chunks/routes/api/reveal.post.mjs +91 -8
  119. package/.output/server/chunks/routes/api/screen-key.post.mjs +7 -6
  120. package/.output/server/chunks/routes/api/screen.get.mjs +7 -6
  121. package/.output/server/chunks/routes/api/search.get.mjs +7 -6
  122. package/.output/server/chunks/routes/api/seen.post.mjs +7 -6
  123. package/.output/server/chunks/routes/api/sessions.get.mjs +7 -6
  124. package/.output/server/chunks/routes/api/sessions.post.mjs +7 -6
  125. package/.output/server/chunks/routes/api/settings-tab.post.mjs +7 -6
  126. package/.output/server/chunks/routes/api/{plugins/thread-limits.get.mjs → settings.get.mjs} +10 -9
  127. package/.output/server/chunks/routes/api/settings.post.mjs +40 -0
  128. package/.output/server/chunks/routes/api/space.post.mjs +34 -18
  129. package/.output/server/chunks/routes/api/state.get.mjs +7 -6
  130. package/.output/server/chunks/routes/api/tasks/action.post.mjs +39 -0
  131. package/.output/server/chunks/routes/api/{plugins/profiles.get.mjs → tasks/add.post.mjs} +12 -16
  132. package/.output/server/chunks/routes/api/tasks/after.post.mjs +39 -0
  133. package/.output/server/chunks/routes/api/tasks/approve.post.mjs +39 -0
  134. package/.output/server/chunks/routes/api/{project/report.get.mjs → tasks/archived.get.mjs} +12 -14
  135. package/.output/server/chunks/routes/api/{index.get.mjs → tasks/autopilot.get.mjs} +13 -14
  136. package/.output/server/chunks/routes/api/tasks/autopilot.post.mjs +39 -0
  137. package/.output/server/chunks/routes/api/{gitroot.get.mjs → tasks/board-settings.get.mjs} +12 -14
  138. package/.output/server/chunks/routes/api/tasks/board-settings.post.mjs +39 -0
  139. package/.output/server/chunks/routes/api/tasks/coordinator.get.mjs +40 -0
  140. package/.output/server/chunks/routes/api/tasks/coordinator.post.mjs +39 -0
  141. package/.output/server/chunks/routes/api/tasks/details.get.mjs +40 -0
  142. package/.output/server/chunks/routes/api/tasks/limit.post.mjs +39 -0
  143. package/.output/server/chunks/routes/api/tasks/links.get.mjs +39 -0
  144. package/.output/server/chunks/routes/api/tasks/models.get.mjs +40 -0
  145. package/.output/server/chunks/routes/api/tasks/pick.post.mjs +39 -0
  146. package/.output/server/chunks/routes/api/tasks/question.post.mjs +39 -0
  147. package/.output/server/chunks/routes/api/tasks/scheduled.get.mjs +40 -0
  148. package/.output/server/chunks/routes/api/{project → tasks}/settings.get.mjs +10 -12
  149. package/.output/server/chunks/routes/api/tasks/start.get.mjs +40 -0
  150. package/.output/server/chunks/routes/api/tasks/tell.post.mjs +39 -0
  151. package/.output/server/chunks/routes/api/tasks.get.mjs +39 -0
  152. package/.output/server/chunks/routes/api/unqueue.post.mjs +7 -6
  153. package/.output/server/chunks/routes/api/update/status.get.mjs +6 -5
  154. package/.output/server/chunks/routes/api/update.get.mjs +8 -10
  155. package/.output/server/chunks/routes/api/update.post.mjs +8 -10
  156. package/.output/server/chunks/routes/api/upload.post.mjs +7 -6
  157. package/.output/server/chunks/routes/api/worktrees/remove.post.mjs +6 -5
  158. package/.output/server/chunks/routes/api/worktrees.get.mjs +6 -5
  159. package/.output/server/chunks/routes/favicon.ico.get.mjs +6 -5
  160. package/.output/server/chunks/routes/icons/_name_.get.mjs +7 -6
  161. package/.output/server/chunks/routes/renderer.mjs +8 -7
  162. package/.output/server/chunks/routes/uploads/_...name_.get.mjs +7 -6
  163. package/.output/server/chunks/routes/ws/_..._.mjs +7 -6
  164. package/.output/server/chunks/routes/ws/events.mjs +9 -7
  165. package/.output/server/chunks/routes/ws/term.mjs +7 -6
  166. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  167. package/.output/server/index.mjs +7 -6
  168. package/.output/server/package.json +1 -1
  169. package/README.md +44 -1445
  170. package/bin/lib/commands.mjs +44 -9
  171. package/bin/lib/panel.mjs +3 -11
  172. package/bin/lib/service.mjs +41 -2
  173. package/bin/lib/skill.mjs +1 -1
  174. package/bin/lib/tailnet.d.mts +6 -3
  175. package/bin/lib/tailnet.mjs +70 -32
  176. package/bin/lib/userpath.d.mts +14 -0
  177. package/bin/lib/userpath.mjs +142 -0
  178. package/docs/README.md +58 -0
  179. package/docs/RELEASING.md +174 -0
  180. package/docs/board.md +169 -0
  181. package/docs/command.md +58 -0
  182. package/docs/configuration.md +39 -0
  183. package/docs/conversation.md +132 -0
  184. package/docs/development.md +38 -0
  185. package/docs/devices.md +58 -0
  186. package/docs/files.md +29 -0
  187. package/docs/herdr-projects-1x.md +278 -0
  188. package/docs/home.md +52 -0
  189. package/docs/installation.md +174 -0
  190. package/docs/machines.md +74 -0
  191. package/docs/migrate-from-1.x-docker.md +160 -0
  192. package/docs/networks.md +154 -0
  193. package/docs/notifications.md +83 -0
  194. package/docs/overview.md +71 -0
  195. package/docs/phone.md +26 -0
  196. package/docs/plugins.md +109 -0
  197. package/docs/quick-start.md +89 -0
  198. package/docs/quotas.md +65 -0
  199. package/docs/release-notes-2.0.0.md +84 -0
  200. package/docs/security.md +117 -0
  201. package/docs/terminal.md +15 -0
  202. package/docs/troubleshooting.md +45 -0
  203. package/package.json +9 -3
  204. package/skills/wherdr/SKILL.md +24 -173
  205. package/.output/public/_nuxt/BEJHMUrj.js +0 -1
  206. package/.output/public/_nuxt/BOtcEDnA.js +0 -1
  207. package/.output/public/_nuxt/BUaYhQ2r.js +0 -6
  208. package/.output/public/_nuxt/CJNhn9sA.js +0 -36
  209. package/.output/public/_nuxt/COCvtdHN.js +0 -89
  210. package/.output/public/_nuxt/Cl45J6_Q.js +0 -1
  211. package/.output/public/_nuxt/CndPDbMI.js +0 -2
  212. package/.output/public/_nuxt/Ctbx58Um.js +0 -23
  213. package/.output/public/_nuxt/Dl1PHLOB.js +0 -1
  214. package/.output/public/_nuxt/Nhex3_iH.js +0 -1
  215. package/.output/public/_nuxt/OpWX45i7.js +0 -89
  216. package/.output/public/_nuxt/builds/meta/4994f3a4-4126-4f57-a9e5-c7ebb25850bc.json +0 -1
  217. package/.output/public/_nuxt/dTj21DMs.js +0 -1
  218. package/.output/public/_nuxt/entry.BohTWE-n.css +0 -2
  219. package/.output/public/_nuxt/kwSoIiM7.js +0 -1
  220. package/.output/public/_nuxt/mkEwYka4.js +0 -1
  221. package/.output/server/chunks/_/pluginPolicy.mjs +0 -93
  222. package/.output/server/chunks/_/projectBoard.mjs +0 -363
  223. package/.output/server/chunks/_/projectDocs.mjs +0 -106
  224. package/.output/server/chunks/_/projectInbox.mjs +0 -135
  225. package/.output/server/chunks/_/projectThreads.mjs +0 -46
  226. package/.output/server/chunks/_/projectThreads2.mjs +0 -61
  227. package/.output/server/chunks/_/projectsActions.mjs +0 -143
  228. package/.output/server/chunks/_/projectsPlugin.mjs +0 -30
  229. package/.output/server/chunks/_/projectsPlugin2.mjs +0 -57
  230. package/.output/server/chunks/_/reveal.mjs +0 -115
  231. package/.output/server/chunks/raw/dev.wherdr.open.mjs +0 -7
  232. package/.output/server/chunks/raw/docker-entrypoint.mjs +0 -7
  233. package/.output/server/chunks/raw/install-host-open.mjs +0 -7
  234. package/.output/server/chunks/raw/wherdr-open.mjs +0 -7
  235. package/.output/server/chunks/routes/api/board.get.mjs +0 -148
  236. package/.output/server/chunks/routes/api/plugins/thread-limits.post.mjs +0 -45
  237. package/.output/server/chunks/routes/api/project/inbox.get.mjs +0 -44
  238. package/.output/server/chunks/routes/api/project/inbox.post.mjs +0 -44
  239. package/.output/server/chunks/routes/api/project/memory.get.mjs +0 -43
  240. package/.output/server/chunks/routes/api/project/routines.get.mjs +0 -44
  241. package/.output/server/chunks/routes/api/project/thread.get.mjs +0 -45
  242. package/.output/server/chunks/routes/api/project/thread.post.mjs +0 -47
  243. package/bin/install-docker-skill.sh +0 -20
@@ -1,9 +1,94 @@
1
- import { v as machineFor, x as herdrOn, H as HerdrError, f as findPane, ay as splitId, ag as log, aI as underHome, aO as isGitRepo, G as fmt, m as getState, a4 as sleep, au as IN_DOCKER, y as HERDR_CHILD_ENV, am as HOME, z as HERDR_BIN } from '../nitro/nitro.mjs';
2
- import { execFile } from 'node:child_process';
3
- import { b as binaryOn } from './projectBoard.mjs';
4
- import { p as projectsPluginState } from './projectsPlugin2.mjs';
5
- import { n as normalizeActions, P as PLUGIN_ID_RE, A as ACTION_ID_RE, a as actionContext, l as logResult, s as stripAnsi, o as outputTail, R as REMOTE_PROJECTS_SCRIPT } from './pluginPolicy.mjs';
6
- import { c as cleanProjectInput, r as repoArgument, a as projectCommandArgs, b as parseProfileList, t as tickerRunning, s as setupHeader, P as PROJECT_INPUTS, d as readOnlyMessage } from './projectsActions.mjs';
1
+ import { m as machineFor, aZ as herdrOn, H as HerdrError, f as findPane, a_ as splitId, a$ as getState, aa as log, X as sleep } from '../nitro/nitro.mjs';
2
+
3
+ const PLUGIN_ID_RE = /^[A-Za-z0-9.:_-]{1,100}$/;
4
+ const ACTION_ID_RE = /^[A-Za-z0-9:_-]{1,100}$/;
5
+ function actionContext(pane, workspaces = []) {
6
+ const context = { invocation_source: "wherdr" };
7
+ if (!pane) return context;
8
+ const local = (id) => id.includes("~") ? id.slice(id.indexOf("~") + 1) : id;
9
+ const workspace = workspaces.find((w) => w.id === pane.workspace);
10
+ return {
11
+ ...context,
12
+ focused_pane_id: local(pane.id),
13
+ tab_id: local(pane.tab),
14
+ workspace_id: local(pane.workspace),
15
+ workspace_label: (workspace == null ? void 0 : workspace.label) || "",
16
+ workspace_cwd: pane.cwd || "",
17
+ focused_pane_cwd: pane.cwd || ""
18
+ };
19
+ }
20
+ const AGENT_CONTEXTS = ["workspace", "tab", "pane"];
21
+ const READ_ONLY = /\b(list|lists|show|status|view|info|doctor|check|help|preview|inspect|lister|liste|voir|afficher|état|etat|vérifier|verifier|aide)\b/i;
22
+ function needsConfirm(a) {
23
+ return !(READ_ONLY.test(a.id.replace(/[_:]/g, "-")) || READ_ONLY.test(a.title));
24
+ }
25
+ function shortLabel(title, pluginName) {
26
+ const esc = pluginName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
27
+ const rest = title.replace(new RegExp(`^${esc}\\s*[:\xB7\u2014\u2013-]\\s*`, "i"), "").trim();
28
+ return rest ? rest[0].toUpperCase() + rest.slice(1) : title;
29
+ }
30
+ const isOwnPlugin = (id) => id === "wherdr" || id.endsWith(".wherdr");
31
+ function opensInHerdr(a) {
32
+ if (a.placement === "popup" || a.placement === "overlay") return true;
33
+ const cmd = Array.isArray(a.command) ? a.command.map(String).join(" ") : "";
34
+ if (/\bplugin\s+pane\s+open\b/.test(cmd)) return true;
35
+ return /(^|[-_:])popup($|[-_:])/i.test(String(a.action_id || ""));
36
+ }
37
+ function normalizeActions(actions, plugins = []) {
38
+ const byId = new Map(plugins.filter((p) => p && p.plugin_id).map((p) => [p.plugin_id, p]));
39
+ const out = [];
40
+ for (const a of actions || []) {
41
+ const plugin = String((a == null ? void 0 : a.plugin_id) || "");
42
+ const id = String((a == null ? void 0 : a.action_id) || "");
43
+ if (!PLUGIN_ID_RE.test(plugin) || !ACTION_ID_RE.test(id) || isOwnPlugin(plugin)) continue;
44
+ const p = byId.get(plugin);
45
+ if (p && p.enabled === false) continue;
46
+ const ctx = (Array.isArray(a.contexts) ? a.contexts : []).map(String);
47
+ const agent = ctx.some((c) => AGENT_CONTEXTS.includes(c));
48
+ const machine = !ctx.length || ctx.includes("global");
49
+ if (!agent && !machine) continue;
50
+ const title = String(a.title || id).replace(/\s+/g, " ").trim().slice(0, 120) || id;
51
+ const description = a.description ? String(a.description).replace(/\s+/g, " ").trim().slice(0, 240) || null : null;
52
+ const pluginName = String((p == null ? void 0 : p.name) || plugin).trim() || plugin;
53
+ out.push({
54
+ plugin,
55
+ pluginName,
56
+ id,
57
+ title,
58
+ label: shortLabel(title, pluginName),
59
+ description,
60
+ agent,
61
+ machine,
62
+ confirm: needsConfirm({ id, title }),
63
+ inHerdr: opensInHerdr(a)
64
+ });
65
+ }
66
+ return out.sort((x, y) => x.pluginName.localeCompare(y.pluginName) || x.label.localeCompare(y.label));
67
+ }
68
+ const ANSI = /\x1B(?:\[[0-?]*[ -/]*[@-~]|\][^\x07\x1B]*(?:\x07|\x1B\\)|[@-Z\\-_])/g;
69
+ function stripAnsi(text) {
70
+ return String(text || "").replace(ANSI, "").replace(/[\x00-\x08\x0B-\x1F\x7F]/g, "");
71
+ }
72
+ function outputTail(text, max = 300) {
73
+ const lines = stripAnsi(text).split("\n").map((l) => l.trim()).filter(Boolean);
74
+ let out = "";
75
+ for (let i = lines.length - 1; i >= 0; i--) {
76
+ const next = out ? `${lines[i]}
77
+ ${out}` : lines[i];
78
+ if (next.length > max) {
79
+ if (!out) out = "\u2026" + lines[i].slice(-(max - 1));
80
+ break;
81
+ }
82
+ out = next;
83
+ }
84
+ return out;
85
+ }
86
+ function logResult(log2) {
87
+ const status = (log2 == null ? void 0 : log2.status) === "succeeded" || (log2 == null ? void 0 : log2.status) === "failed" ? log2.status : "running";
88
+ const exitCode = typeof (log2 == null ? void 0 : log2.exit_code) === "number" ? log2.exit_code : null;
89
+ const output = status === "failed" ? outputTail(log2 == null ? void 0 : log2.stderr) || outputTail(log2 == null ? void 0 : log2.error) || outputTail(log2 == null ? void 0 : log2.stdout) : outputTail(log2 == null ? void 0 : log2.stdout) || outputTail(log2 == null ? void 0 : log2.stderr);
90
+ return { status, exitCode, output };
91
+ }
7
92
 
8
93
  const CACHE_MS = 1e4;
9
94
  const cache = /* @__PURE__ */ new Map();
@@ -20,80 +105,6 @@ async function listPluginActions(machineKey, fresh = false) {
20
105
  return actions;
21
106
  }
22
107
  const WAIT_MS = 12e3;
23
- function pluginInputFields(plugin, action) {
24
- return plugin === "herdr-projects" ? PROJECT_INPUTS[action] || [] : [];
25
- }
26
- async function runProjects(m, bin, args, timeoutMs = 6e4) {
27
- var _a;
28
- if (m.exec) {
29
- const herdrBin = "bin" in m && typeof m.bin === "string" && m.bin ? m.bin : "herdr";
30
- const r = await m.exec(REMOTE_PROJECTS_SCRIPT, [herdrBin, bin, ...args], { timeoutMs });
31
- return { code: (_a = r.code) != null ? _a : 1, stdout: r.stdout.toString("utf8").trim(), stderr: r.stderr.trim() };
32
- }
33
- return new Promise((resolve) => execFile(bin, args, {
34
- env: { ...HERDR_CHILD_ENV, HERDR_BIN_PATH: HERDR_BIN },
35
- timeout: timeoutMs,
36
- maxBuffer: 1024 * 1024
37
- }, (err, stdout, stderr) => resolve({
38
- code: err ? typeof err.code === "number" ? err.code : 1 : 0,
39
- stdout: String(stdout).trim(),
40
- stderr: String(stderr || (err && !stdout ? err.message : "")).trim()
41
- })));
42
- }
43
- async function projectsBin(m) {
44
- var _a;
45
- const bin = await binaryOn(m);
46
- if (bin) return bin;
47
- if ((_a = await projectsPluginState(m).catch(() => null)) == null ? void 0 : _a.unsupported) throw new HerdrError("plugin_unsupported", "herdr-projects 1.x is not supported by wherdr yet: install the 0.2 line (Settings \u203A Plugins \u203A herdr-projects)");
48
- throw new HerdrError("plugin_unavailable", "Projects binary not found");
49
- }
50
- async function projectsCommand(m, args, lang = "en") {
51
- const r = await runProjects(m, await projectsBin(m), args);
52
- if (r.code !== 0) {
53
- const error = r.stderr || r.stdout || `code ${r.code}`;
54
- const readOnly = readOnlyMessage(error, { docker: m.local && IN_DOCKER });
55
- if (readOnly) log(`herdr-projects ${args[0]}: ${error}`);
56
- throw new HerdrError(readOnly ? "read_only" : "plugin_failed", readOnly || error);
57
- }
58
- return r.stdout;
59
- }
60
- async function withoutContainerTicker(m, run) {
61
- if (!m.local || !IN_DOCKER) return run();
62
- const bin = await projectsBin(m);
63
- const before = await runProjects(m, bin, ["ticker", "status"]).catch(() => null);
64
- try {
65
- return await run();
66
- } finally {
67
- if (before && before.code === 0 && !tickerRunning(before.stdout)) {
68
- const after = await runProjects(m, bin, ["ticker", "status"]).catch(() => null);
69
- if (after && tickerRunning(after.stdout)) {
70
- log("herdr-projects: ticker started in the container, stop requested (it will restart on the host)");
71
- runProjects(m, bin, ["ticker", "stop"]).then((r) => r.code && log(`herdr-projects ticker stop: ${r.stderr || r.code}`));
72
- }
73
- }
74
- }
75
- }
76
- async function projectsDoctor(m) {
77
- const bin = await projectsBin(m);
78
- const [version, doctor] = await Promise.all([
79
- runProjects(m, bin, ["--version"]).catch(() => null),
80
- runProjects(m, bin, projectCommandArgs("doctor", {}, { session: m.session }))
81
- ]);
82
- const home = m.local ? String(HERDR_CHILD_ENV.HOME || HOME) : m.home;
83
- const full = stripAnsi([doctor.stdout, doctor.stderr].filter(Boolean).join("\n")).slice(-12e3);
84
- return {
85
- status: doctor.code === 0 ? "succeeded" : "failed",
86
- exitCode: doctor.code,
87
- output: outputTail(full),
88
- full,
89
- setup: setupHeader({ version: version && version.code === 0 ? version.stdout : null, binary: bin, home })
90
- };
91
- }
92
- async function projectProfiles(machineKey) {
93
- const m = machineFor(machineKey);
94
- const r = await runProjects(m, await projectsBin(m), ["profile", "list"], 1e4);
95
- return r.code === 0 ? parseProfileList(stripAnsi(r.stdout)) : null;
96
- }
97
108
  async function invokePluginAction(body) {
98
109
  const plugin = String(body.plugin || "");
99
110
  const action = String(body.action || "");
@@ -105,50 +116,6 @@ async function invokePluginAction(body) {
105
116
  const known = (await listPluginActions(m.key, true)).find((a) => a.plugin === plugin && a.id === action);
106
117
  if (!known) throw new HerdrError("plugin_action_not_found", "Action not found on this machine");
107
118
  if (pane ? !known.agent : !known.machine) throw new HerdrError("bad_context", "Action not available here");
108
- if (plugin === "herdr-projects" && action === "open-popup") {
109
- throw new HerdrError("popup_unavailable", "The Projects panel is available in the Herdr client; its inputs are not reachable through the Herdr API.");
110
- }
111
- if (plugin === "herdr-projects" && action === "doctor") {
112
- log(`plugin ${plugin}.${action}${m.local ? "" : ` on ${m.label}`} (command)`);
113
- return projectsDoctor(m);
114
- }
115
- const fields = pluginInputFields(plugin, action);
116
- if (fields.length) {
117
- const input = cleanProjectInput(action, body.input);
118
- if (!input) throw new HerdrError("bad_input", "Invalid plugin input");
119
- if (action === "adopt-workspace" && (!pane || !pane.agent || !pane.cwd)) {
120
- throw new HerdrError("bad_context", "This space needs an agent and its folder");
121
- }
122
- if (input.repo) {
123
- const rm = input.machine ? machineFor(input.machine) : m;
124
- const repo = underHome(input.repo, rm.home);
125
- if (!repo || !await isGitRepo(repo, rm)) throw new HerdrError("bad_input", fmt("Not a Git repository: {path}", { path: input.repo }));
126
- const arg = repoArgument(repo, rm, m);
127
- if (!arg) throw new HerdrError("bad_input", fmt("Repository unusable from {machine}: {path}", { machine: m.label, path: `${repo}${rm === m ? "" : ` (${rm.label})`}` }));
128
- input.repo = arg;
129
- }
130
- delete input.machine;
131
- const lang = body.lang === "fr" ? "fr" : "en";
132
- const args = projectCommandArgs(action, input, { pane: pane ? splitId(pane.id).local : void 0, cwd: (pane == null ? void 0 : pane.cwd) || void 0, session: m.session, lang });
133
- const exec = async () => {
134
- var _a;
135
- const output = await projectsCommand(m, args, lang);
136
- if (action === "new") {
137
- const slug = (_a = /created `([^`]+)`/.exec(output)) == null ? void 0 : _a[1];
138
- if (slug) {
139
- try {
140
- return { status: "succeeded", exitCode: 0, output: outputTail(`${output}
141
- ${await projectsCommand(m, projectCommandArgs("open", { slug }, { session: m.session }), lang)}`) };
142
- } catch (e) {
143
- return { status: "failed", exitCode: null, output: outputTail(`${output}
144
- ${e.message}`) };
145
- }
146
- }
147
- }
148
- return { status: "succeeded", exitCode: 0, output: outputTail(output) };
149
- };
150
- return ["new", "open", "adopt-workspace"].includes(action) ? withoutContainerTicker(m, exec) : exec();
151
- }
152
119
  const context = actionContext(pane || null, getState().workspaces);
153
120
  const r = await herdrOn(m.key, "plugin.action.invoke", { plugin_id: plugin, action_id: action, context }, 1e4);
154
121
  const logId = r.log && r.log.log_id;
@@ -165,5 +132,5 @@ ${e.message}`) };
165
132
  return res;
166
133
  }
167
134
 
168
- export { invokePluginAction as i, listPluginActions as l, projectProfiles as p, withoutContainerTicker as w };
135
+ export { invokePluginAction as i, listPluginActions as l };
169
136
  //# sourceMappingURL=plugins.mjs.map
@@ -1,4 +1,4 @@
1
- import { H as HerdrError, a9 as paneForeground, aa as codexMenuOpen, ab as stopAgent, ac as terminalUpdateLine, ad as waitFor, ae as terminalUpdateDone, af as startAgent, a4 as sleep, f as findPane, a1 as restarts, ag as log, X as withPaneLock, ah as RESTARTABLE, J as transcripts, ai as claudeFooterMode, aj as planRestart, h as herdr, p as poll } from '../nitro/nitro.mjs';
1
+ import { H as HerdrError, a3 as paneForeground, a4 as codexMenuOpen, a5 as stopAgent, a6 as terminalUpdateLine, a7 as waitFor, a8 as terminalUpdateDone, a9 as startAgent, X as sleep, f as findPane, T as restarts, aa as log, M as withPaneLock, ab as RESTARTABLE, y as transcripts, ac as claudeFooterMode, ad as planRestart, h as herdr, p as poll } from '../nitro/nitro.mjs';
2
2
  import crypto from 'node:crypto';
3
3
 
4
4
  const TERM_UPDATE_MS = 10 * 6e4;
@@ -3,7 +3,7 @@ import fs from 'node:fs';
3
3
  import os from 'node:os';
4
4
  import path from 'node:path';
5
5
  import { p as pkg } from './package.mjs';
6
- import { bK as installMode, H as HerdrError, ag as log, bL as oneTapMode, bO as updateRunning } from '../nitro/nitro.mjs';
6
+ import { c6 as installMode, H as HerdrError, aa as log, c7 as oneTapMode, ca as updateRunning } from '../nitro/nitro.mjs';
7
7
  import { c as checkUpdate, R as REPO } from './updates.mjs';
8
8
 
9
9
  function wherdrDir(env = process.env) {
@@ -1,5 +1,5 @@
1
1
  import { p as pkg } from './package.mjs';
2
- import { bK as installMode, bL as oneTapMode, bM as updateCommand, bN as compareVersions } from '../nitro/nitro.mjs';
2
+ import { c6 as installMode, c7 as oneTapMode, c8 as updateCommand, c9 as compareVersions } from '../nitro/nitro.mjs';
3
3
 
4
4
  const REPO = "afloury/wherdr";
5
5
  const RELEASES_URL = `https://api.github.com/repos/${REPO}/releases?per_page=100`;
@@ -1,4 +1,4 @@
1
- import { bP as allMachines, a6 as getMachine, H as HerdrError, ay as splitId, x as herdrOn, p as poll, bQ as recentDirs, bR as joinId, m as getState } from '../nitro/nitro.mjs';
1
+ import { cb as allMachines, $ as getMachine, H as HerdrError, a_ as splitId, aZ as herdrOn, p as poll, an as recentDirs, cc as joinId, a$ as getState } from '../nitro/nitro.mjs';
2
2
 
3
3
  const opts = { trust_repository: true };
4
4
  async function machineWorktrees(m) {
@@ -1,4 +1,4 @@
1
- import { bY as hostAllowed, bZ as sameOrigin, k as auth } from '../nitro/nitro.mjs';
1
+ import { ck as networkReady, cl as ensureFresh, cm as gateDecision, cn as sameOrigin, co as hostAllowed, k as auth, cp as checkRequestClient, cq as onNetworkReading } from '../nitro/nitro.mjs';
2
2
 
3
3
  var _a, _b;
4
4
  const WS_MAX = 256 * 1024;
@@ -9,11 +9,25 @@ function headersOf(h) {
9
9
  });
10
10
  return out;
11
11
  }
12
- function checkUpgrade(request) {
13
- const headers = headersOf(request.headers);
14
- if (!hostAllowed(headers.host)) return new Response(null, { status: 403, statusText: "Host not allowed" });
15
- if (!sameOrigin(headers)) return new Response(null, { status: 403, statusText: "Forbidden" });
16
- if (!auth.isUnlocked({ headers })) return new Response(null, { status: 401, statusText: "Unauthorized" });
12
+ function upgradeVerdict(headers, remoteAddress) {
13
+ return gateDecision({
14
+ check: checkRequestClient(remoteAddress, headers),
15
+ unlocked: auth.isUnlocked({ headers }),
16
+ hostOk: hostAllowed(headers.host),
17
+ crossSite: !sameOrigin(headers),
18
+ path: "/ws",
19
+ ws: true
20
+ });
21
+ }
22
+ async function checkUpgrade(request) {
23
+ var _a2, _b2;
24
+ await networkReady();
25
+ await ensureFresh(0);
26
+ const verdict = upgradeVerdict(headersOf(request.headers), (_b2 = (_a2 = request._req) == null ? void 0 : _a2.socket) == null ? void 0 : _b2.remoteAddress);
27
+ if (verdict === "network") return new Response(null, { status: 403, statusText: "Network not allowed" });
28
+ if (verdict === "host") return new Response(null, { status: 403, statusText: "Host not allowed" });
29
+ if (verdict === "origin") return new Response(null, { status: 403, statusText: "Forbidden" });
30
+ if (verdict === "locked") return new Response(null, { status: 401, statusText: "Unauthorized" });
17
31
  }
18
32
  const rawWs = (peer) => {
19
33
  var _a2;
@@ -32,6 +46,29 @@ function watchPeer(peer) {
32
46
  function unwatchPeer(peer) {
33
47
  alive.delete(peer);
34
48
  }
49
+ function revalidatePeers(peers = alive.keys(), judge = upgradeVerdict) {
50
+ var _a2;
51
+ let closed = 0;
52
+ for (const peer of [...peers]) {
53
+ let verdict;
54
+ try {
55
+ verdict = judge(((_a2 = peer.request) == null ? void 0 : _a2.headers) ? headersOf(peer.request.headers) : {}, peer.remoteAddress);
56
+ } catch {
57
+ verdict = "network";
58
+ }
59
+ if (verdict === "ok") continue;
60
+ closed++;
61
+ alive.delete(peer);
62
+ try {
63
+ peer.close(1008, "Network policy changed");
64
+ } catch {
65
+ }
66
+ }
67
+ return closed;
68
+ }
69
+ onNetworkReading(() => {
70
+ revalidatePeers();
71
+ });
35
72
  (_b = (_a = setInterval(() => {
36
73
  for (const [peer, ok] of alive) {
37
74
  const ws = rawWs(peer);