wherdr 1.3.1 → 1.3.3

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 (180) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{AgentView.C4YOwvZG.css → AgentView.DzFWBd2A.css} +1 -1
  3. package/.output/public/_nuxt/B4Yk2tB1.js +23 -0
  4. package/.output/public/_nuxt/BBw_0a4M.js +6 -0
  5. package/.output/public/_nuxt/{B6qBWHWB.js → BSy6OCIY.js} +1 -1
  6. package/.output/public/_nuxt/BX5PM2JQ.js +1 -0
  7. package/.output/public/_nuxt/BgPDnf2S.js +1 -0
  8. package/.output/public/_nuxt/BkOxQzbS.js +2 -0
  9. package/.output/public/_nuxt/{WLQjK8uJ.js → CKhgznq4.js} +45 -46
  10. package/.output/public/_nuxt/{C2T9fQ4f.js → CP8o925U.js} +1 -1
  11. package/.output/public/_nuxt/CkbmecwS.js +1 -0
  12. package/.output/public/_nuxt/Cr3SrGky.js +1 -0
  13. package/.output/public/_nuxt/DAg9fiVh.js +89 -0
  14. package/.output/public/_nuxt/DT8qZ0Wv.js +1 -0
  15. package/.output/public/_nuxt/DaaJIRB3.js +1 -0
  16. package/.output/public/_nuxt/DcJi16XA.js +1 -0
  17. package/.output/public/_nuxt/VpjCgSXu.js +36 -0
  18. package/.output/public/_nuxt/builds/latest.json +1 -1
  19. package/.output/public/_nuxt/builds/meta/c735b6c0-1bd0-47d7-a208-d310f0a06287.json +1 -0
  20. package/.output/public/_nuxt/dPxB2L94.js +89 -0
  21. package/.output/public/_nuxt/{entry.cKR16VqG.css → entry.CGWKmYU3.css} +1 -1
  22. package/.output/public/_nuxt/hePW80VL.js +1 -0
  23. package/.output/public/_nuxt/xYX85SPI.js +1 -0
  24. package/.output/public/sw.js +1 -1
  25. package/.output/server/chunks/_/branding.mjs +1 -1
  26. package/.output/server/chunks/_/filePaths.mjs +25 -0
  27. package/.output/server/chunks/_/files.mjs +204 -0
  28. package/.output/server/chunks/_/machineOrder.mjs +1 -1
  29. package/.output/server/chunks/_/onboarding.mjs +1 -1
  30. package/.output/server/chunks/_/package.mjs +97 -0
  31. package/.output/server/chunks/_/pluginPolicy.mjs +93 -0
  32. package/.output/server/chunks/_/plugins.mjs +4 -94
  33. package/.output/server/chunks/_/projectBoard.mjs +120 -29
  34. package/.output/server/chunks/_/projectDocs.mjs +106 -0
  35. package/.output/server/chunks/_/projectInbox.mjs +135 -0
  36. package/.output/server/chunks/_/projectThreads.mjs +46 -0
  37. package/.output/server/chunks/_/projectThreads2.mjs +61 -0
  38. package/.output/server/chunks/_/projectsActions.mjs +1 -1
  39. package/.output/server/chunks/_/projectsPlugin.mjs +1 -1
  40. package/.output/server/chunks/_/restart.mjs +2 -312
  41. package/.output/server/chunks/_/reveal.mjs +2 -24
  42. package/.output/server/chunks/_/selfupdate.mjs +83 -0
  43. package/.output/server/chunks/_/updates.mjs +91 -0
  44. package/.output/server/chunks/_/worktrees.mjs +1 -1
  45. package/.output/server/chunks/_/ws.mjs +1 -1
  46. package/.output/server/chunks/nitro/nitro.mjs +2660 -1061
  47. package/.output/server/chunks/raw/bump-homebrew.mjs +1 -1
  48. package/.output/server/chunks/raw/herdr-plugin.mjs +1 -1
  49. package/.output/server/chunks/raw/release-ready.mjs +5 -0
  50. package/.output/server/chunks/routes/api/_..._.mjs +6 -2
  51. package/.output/server/chunks/routes/api/agents.post.mjs +6 -2
  52. package/.output/server/chunks/routes/api/ask-tab.post.mjs +6 -2
  53. package/.output/server/chunks/routes/api/attach.post.mjs +6 -2
  54. package/.output/server/chunks/routes/api/auth/disable.post.mjs +6 -2
  55. package/.output/server/chunks/routes/api/auth/lock-all.post.mjs +6 -2
  56. package/.output/server/chunks/routes/api/auth/lock.post.mjs +6 -2
  57. package/.output/server/chunks/routes/api/auth/login/options.post.mjs +6 -2
  58. package/.output/server/chunks/routes/api/auth/login/verify.post.mjs +6 -2
  59. package/.output/server/chunks/routes/api/auth/max-session.post.mjs +6 -2
  60. package/.output/server/chunks/routes/api/auth/register/options.post.mjs +6 -2
  61. package/.output/server/chunks/routes/api/auth/register/verify.post.mjs +6 -2
  62. package/.output/server/chunks/routes/api/auth/status.get.mjs +6 -2
  63. package/.output/server/chunks/routes/api/board.get.mjs +147 -0
  64. package/.output/server/chunks/routes/api/changes.get.mjs +7 -3
  65. package/.output/server/chunks/routes/api/chat/image.get.mjs +7 -3
  66. package/.output/server/chunks/routes/api/chat.get.mjs +7 -3
  67. package/.output/server/chunks/routes/api/choose.post.mjs +34 -4
  68. package/.output/server/chunks/routes/api/claude-statusline.post.mjs +7 -3
  69. package/.output/server/chunks/routes/api/close/status.get.mjs +7 -3
  70. package/.output/server/chunks/routes/api/close.post.mjs +6 -2
  71. package/.output/server/chunks/routes/api/codex-update.post.mjs +7 -3
  72. package/.output/server/chunks/routes/api/commands.get.mjs +7 -3
  73. package/.output/server/chunks/routes/api/config.get.mjs +8 -3
  74. package/.output/server/chunks/routes/api/dirs.get.mjs +7 -3
  75. package/.output/server/chunks/routes/api/dismiss-stopped.post.mjs +43 -0
  76. package/.output/server/chunks/routes/api/dismiss.post.mjs +7 -3
  77. package/.output/server/chunks/routes/api/effort.post.mjs +7 -3
  78. package/.output/server/chunks/routes/api/efforts.get.mjs +7 -3
  79. package/.output/server/chunks/routes/api/file.post.mjs +7 -3
  80. package/.output/server/chunks/routes/api/files/download.get.mjs +53 -0
  81. package/.output/server/chunks/routes/api/files/read.get.mjs +45 -0
  82. package/.output/server/chunks/routes/api/files.get.mjs +44 -0
  83. package/.output/server/chunks/routes/api/gitroot.get.mjs +7 -3
  84. package/.output/server/chunks/routes/api/health.get.mjs +36 -0
  85. package/.output/server/chunks/routes/api/index.get.mjs +6 -2
  86. package/.output/server/chunks/routes/api/input.post.mjs +18 -4
  87. package/.output/server/chunks/routes/api/interrupt.post.mjs +7 -3
  88. package/.output/server/chunks/routes/api/isgit.get.mjs +7 -3
  89. package/.output/server/chunks/routes/api/machine/awake.get.mjs +7 -3
  90. package/.output/server/chunks/routes/api/machine/awake.post.mjs +7 -3
  91. package/.output/server/chunks/routes/api/machine/order.get.mjs +6 -2
  92. package/.output/server/chunks/routes/api/machine/order.post.mjs +6 -2
  93. package/.output/server/chunks/routes/api/machine/rename.post.mjs +7 -3
  94. package/.output/server/chunks/routes/api/menu.post.mjs +7 -3
  95. package/.output/server/chunks/routes/api/model.post.mjs +7 -3
  96. package/.output/server/chunks/routes/api/models.get.mjs +7 -3
  97. package/.output/server/chunks/routes/api/nav.post.mjs +10 -5
  98. package/.output/server/chunks/routes/api/onboarding.get.mjs +6 -2
  99. package/.output/server/chunks/routes/api/onboarding.post.mjs +6 -2
  100. package/.output/server/chunks/routes/api/phone.get.mjs +6 -7
  101. package/.output/server/chunks/routes/api/phone.post.mjs +6 -7
  102. package/.output/server/chunks/routes/api/plugins/actions.get.mjs +7 -2
  103. package/.output/server/chunks/routes/api/plugins/invoke.post.mjs +7 -2
  104. package/.output/server/chunks/routes/api/plugins/profiles.get.mjs +7 -2
  105. package/.output/server/chunks/routes/api/plugins/projects.get.mjs +7 -3
  106. package/.output/server/chunks/routes/api/plugins/projects.post.mjs +7 -3
  107. package/.output/server/chunks/routes/api/plugins/thread-limits.get.mjs +7 -3
  108. package/.output/server/chunks/routes/api/plugins/thread-limits.post.mjs +7 -3
  109. package/.output/server/chunks/routes/api/project/inbox.get.mjs +43 -0
  110. package/.output/server/chunks/routes/api/project/inbox.post.mjs +43 -0
  111. package/.output/server/chunks/routes/api/project/memory.get.mjs +42 -0
  112. package/.output/server/chunks/routes/api/project/report.get.mjs +7 -3
  113. package/.output/server/chunks/routes/api/project/routines.get.mjs +43 -0
  114. package/.output/server/chunks/routes/api/project/settings.get.mjs +41 -0
  115. package/.output/server/chunks/routes/api/project/thread.get.mjs +44 -0
  116. package/.output/server/chunks/routes/api/project/thread.post.mjs +45 -0
  117. package/.output/server/chunks/routes/api/prompt.post.mjs +26 -4
  118. package/.output/server/chunks/routes/api/push/quiet.post.mjs +7 -3
  119. package/.output/server/chunks/routes/api/push/subscribe.post.mjs +7 -3
  120. package/.output/server/chunks/routes/api/push/test.post.mjs +7 -3
  121. package/.output/server/chunks/routes/api/push/unsubscribe.post.mjs +7 -3
  122. package/.output/server/chunks/routes/api/quotas.get.mjs +7 -3
  123. package/.output/server/chunks/routes/api/rename.post.mjs +6 -2
  124. package/.output/server/chunks/routes/api/requeue.post.mjs +7 -3
  125. package/.output/server/chunks/routes/api/restart.get.mjs +6 -2
  126. package/.output/server/chunks/routes/api/restart.post.mjs +6 -2
  127. package/.output/server/chunks/routes/api/reveal.post.mjs +7 -2
  128. package/.output/server/chunks/routes/api/screen-key.post.mjs +7 -3
  129. package/.output/server/chunks/routes/api/screen.get.mjs +10 -4
  130. package/.output/server/chunks/routes/api/search.get.mjs +7 -3
  131. package/.output/server/chunks/routes/api/seen.post.mjs +7 -3
  132. package/.output/server/chunks/routes/api/sessions.get.mjs +7 -3
  133. package/.output/server/chunks/routes/api/sessions.post.mjs +7 -3
  134. package/.output/server/chunks/routes/api/space.post.mjs +19 -15
  135. package/.output/server/chunks/routes/api/state.get.mjs +7 -3
  136. package/.output/server/chunks/routes/api/unqueue.post.mjs +7 -3
  137. package/.output/server/chunks/routes/api/update/status.get.mjs +38 -0
  138. package/.output/server/chunks/routes/api/update.get.mjs +12 -51
  139. package/.output/server/chunks/routes/api/update.post.mjs +41 -0
  140. package/.output/server/chunks/routes/api/upload.post.mjs +7 -3
  141. package/.output/server/chunks/routes/api/worktrees/remove.post.mjs +6 -2
  142. package/.output/server/chunks/routes/api/worktrees.get.mjs +6 -2
  143. package/.output/server/chunks/routes/favicon.ico.get.mjs +6 -2
  144. package/.output/server/chunks/routes/icons/_name_.get.mjs +7 -3
  145. package/.output/server/chunks/routes/renderer.mjs +8 -4
  146. package/.output/server/chunks/routes/uploads/_...name_.get.mjs +7 -3
  147. package/.output/server/chunks/routes/ws/_..._.mjs +7 -3
  148. package/.output/server/chunks/routes/ws/events.mjs +7 -3
  149. package/.output/server/chunks/routes/ws/term.mjs +9 -5
  150. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  151. package/.output/server/index.mjs +7 -3
  152. package/.output/server/package.json +1 -1
  153. package/README.md +440 -46
  154. package/bin/install-docker-skill.sh +20 -0
  155. package/bin/lib/commands.mjs +47 -9
  156. package/bin/lib/core.mjs +18 -2
  157. package/bin/lib/install-skill.sh +100 -0
  158. package/bin/lib/skill.mjs +16 -0
  159. package/bin/lib/tailnet.d.mts +12 -3
  160. package/bin/lib/tailnet.mjs +103 -25
  161. package/bin/lib/updater.mjs +320 -0
  162. package/bin/lib/verify-release.mjs +20 -0
  163. package/package.json +4 -2
  164. package/skills/wherdr/SKILL.md +180 -0
  165. package/.output/public/_nuxt/BDNMzG2s.js +0 -1
  166. package/.output/public/_nuxt/BMIe8p_3.js +0 -2
  167. package/.output/public/_nuxt/BpQH8Ho1.js +0 -1
  168. package/.output/public/_nuxt/BrAeJIZR.js +0 -30
  169. package/.output/public/_nuxt/C12eXl5z.js +0 -1
  170. package/.output/public/_nuxt/CXG-cOdh.js +0 -1
  171. package/.output/public/_nuxt/CYxHnMNH.js +0 -83
  172. package/.output/public/_nuxt/CctS2Xn6.js +0 -65
  173. package/.output/public/_nuxt/CiYar6hg.js +0 -6
  174. package/.output/public/_nuxt/DLLQgP0d.js +0 -1
  175. package/.output/public/_nuxt/Dwh-l2rQ.js +0 -17
  176. package/.output/public/_nuxt/bLP7Jj-b.js +0 -1
  177. package/.output/public/_nuxt/builds/meta/6466b0ab-7935-460c-abdf-2ea632dae6d0.json +0 -1
  178. package/.output/public/_nuxt/whFLy_Ne.js +0 -23
  179. package/.output/server/chunks/_/phone.mjs +0 -343
  180. package/.output/server/chunks/routes/ws/mirror.mjs +0 -157
@@ -1,317 +1,6 @@
1
- import { H as HerdrError, K as codexMenuOpen, L as terminalUpdateLine, N as terminalUpdateDone, F as sleep, f as findPane, O as restarts, Q as log, R as withPaneLock, q as transcripts, h as herdr, p as poll } from '../nitro/nitro.mjs';
1
+ import { H as HerdrError, a4 as paneForeground, a5 as codexMenuOpen, a6 as stopAgent, a7 as terminalUpdateLine, a8 as waitFor, a9 as terminalUpdateDone, aa as startAgent, $ as sleep, f as findPane, Y as restarts, ab as log, R as withPaneLock, ac as RESTARTABLE, G as transcripts, ad as claudeFooterMode, ae as planRestart, h as herdr, p as poll } from '../nitro/nitro.mjs';
2
2
  import crypto from 'node:crypto';
3
3
 
4
- const CLAUDE = {
5
- keep: {
6
- "--model": 1,
7
- "--effort": 1,
8
- "--permission-mode": 1,
9
- "--fallback-model": 1,
10
- "--agent": 1,
11
- "--agents": 1,
12
- "--settings": 1,
13
- "--setting-sources": 1,
14
- "--system-prompt": 1,
15
- "--append-system-prompt": 1,
16
- "--autocompact": 1,
17
- "-n": 1,
18
- "--name": 1,
19
- "--debug-file": 1,
20
- "--add-dir": "*",
21
- "--mcp-config": "*",
22
- "--plugin-dir": "*",
23
- "--allowedTools": "*",
24
- "--allowed-tools": "*",
25
- "--disallowedTools": "*",
26
- "--disallowed-tools": "*",
27
- "--tools": "*",
28
- "--betas": "*",
29
- "--dangerously-skip-permissions": 0,
30
- "--allow-dangerously-skip-permissions": 0,
31
- "--verbose": 0,
32
- "--ide": 0,
33
- "--chrome": 0,
34
- "--no-chrome": 0,
35
- "--strict-mcp-config": 0,
36
- "--bare": 0,
37
- "--brief": 0,
38
- "--disable-slash-commands": 0,
39
- "--safe-mode": 0,
40
- "--restricted": 0
41
- },
42
- // Conversation choice, one-off launch or already done (worktree created).
43
- drop: {
44
- "-c": 0,
45
- "--continue": 0,
46
- "-r": "?",
47
- "--resume": "?",
48
- "--session-id": 1,
49
- "--fork-session": 0,
50
- "-w": "?",
51
- "--worktree": "?",
52
- "--tmux": 0,
53
- "--from-pr": "?",
54
- "--teleport": "?",
55
- "-p": 0,
56
- "--print": 0,
57
- "--bg": 0,
58
- "--background": 0,
59
- "--remote-control": "?",
60
- "--cloud": "?",
61
- "--file": "*",
62
- "-d": "?",
63
- "--debug": "?"
64
- }
65
- };
66
- const CODEX = {
67
- keep: {
68
- "-c": 1,
69
- "--config": 1,
70
- "--enable": 1,
71
- "--disable": 1,
72
- "-m": 1,
73
- "--model": 1,
74
- "--local-provider": 1,
75
- "-p": 1,
76
- "--profile": 1,
77
- "-s": 1,
78
- "--sandbox": 1,
79
- "-C": 1,
80
- "--cd": 1,
81
- "--add-dir": 1,
82
- "-a": 1,
83
- "--ask-for-approval": 1,
84
- "--remote": 1,
85
- "--remote-auth-token-env": 1,
86
- "--oss": 0,
87
- "--search": 0,
88
- "--no-alt-screen": 0,
89
- "--no-daemon": 0,
90
- "--full-auto": 0,
91
- "--dangerously-bypass-approvals-and-sandbox": 0,
92
- "--yolo": 0,
93
- "--approve-for-me": 0,
94
- "--strict-config": 0,
95
- "--dangerously-bypass-hook-trust": 0
96
- },
97
- drop: { "--last": 0, "--all": 0, "--include-non-interactive": 0, "-i": "*", "--image": "*", "--worktree": 0 }
98
- };
99
- const OMP = {
100
- keep: {
101
- "--model": 1,
102
- "--smol": 1,
103
- "--slow": 1,
104
- "--plan": 1,
105
- "--prewalk-into": 1,
106
- "--plan-yolo-into": 1,
107
- "--provider": 1,
108
- "--system-prompt": 1,
109
- "--system-prompt-template": 1,
110
- "--append-system-prompt": 1,
111
- "--profile": 1,
112
- "--cwd": 1,
113
- "--config": 1,
114
- "--add-dir": 1,
115
- "--session-dir": 1,
116
- "--models": 1,
117
- "--tools": 1,
118
- "--thinking": 1,
119
- "--service-tier": 1,
120
- "--hook": 1,
121
- "-e": 1,
122
- "--extension": 1,
123
- "--skills": 1,
124
- "--approval-mode": 1,
125
- "--plugin-dir": 1,
126
- "--allow-home": 0,
127
- "--prewalk": 0,
128
- "--no-prewalk": 0,
129
- "--no-tools": 0,
130
- "--no-lsp": 0,
131
- "--no-pty": 0,
132
- "--hide-thinking": 0,
133
- "--advisor": 0,
134
- "--external-thinking": 0,
135
- "--no-extensions": 0,
136
- "--no-skills": 0,
137
- "--no-rules": 0,
138
- "--no-title": 0,
139
- "--auto-approve": 0
140
- },
141
- // Conversation choice, one-off launch; the API key is never replayed
142
- // (it would show in the confirmation).
143
- drop: {
144
- "-c": 0,
145
- "--continue": 0,
146
- "-r": "?",
147
- "--resume": "?",
148
- "-p": 0,
149
- "--print": 0,
150
- "--plan-yolo": 0,
151
- "--from-claude": 0,
152
- "--from-codex": 0,
153
- "--no-session": 0,
154
- "--export": 1,
155
- "--mode": 1,
156
- "--max-time": 1,
157
- "--alias": 1,
158
- "--api-key": 1,
159
- "--no-ui": 0,
160
- "--print-thoughts": 0
161
- }
162
- };
163
- const SILENT = /* @__PURE__ */ new Set(["-c", "--continue", "-r", "--resume", "--session-id", "--fork-session", "--last", "--all"]);
164
- const SPECS = { claude: CLAUDE, codex: CODEX, omp: OMP };
165
- const RESTARTABLE = new Set(Object.keys(SPECS));
166
- const base$1 = (s) => s.replace(/^.*\//, "").replace(/\.(c?js|mjs)$/, "");
167
- function launchOptions(kind, argv) {
168
- const spec = SPECS[kind];
169
- const kept = [];
170
- const dropped = [];
171
- if (!spec) return { kept, dropped };
172
- let i = argv.findIndex((a) => base$1(a) === kind);
173
- i = i < 0 ? 1 : i + 1;
174
- for (; i < argv.length; i++) {
175
- const a = argv[i];
176
- if (a === "--") break;
177
- if (!a.startsWith("-") || a === "-") continue;
178
- const eq = a.indexOf("=");
179
- const flag = eq > 0 ? a.slice(0, eq) : a;
180
- const keep = flag in spec.keep;
181
- const arity = keep ? spec.keep[flag] : spec.drop[flag];
182
- const out = [a];
183
- if (keep) kept.push(out);
184
- else if (!SILENT.has(flag)) dropped.push(out);
185
- if (arity === void 0) {
186
- if (eq < 0 && argv[i + 1] !== void 0 && !argv[i + 1].startsWith("-")) out.push(argv[++i]);
187
- continue;
188
- }
189
- if (eq > 0 || arity === 0) continue;
190
- if (arity === 1) {
191
- if (argv[i + 1] !== void 0) out.push(argv[++i]);
192
- continue;
193
- }
194
- while (argv[i + 1] !== void 0 && !argv[i + 1].startsWith("-")) {
195
- out.push(argv[++i]);
196
- if (arity === "?") break;
197
- }
198
- }
199
- return { kept, dropped };
200
- }
201
- const EFFORTS = /* @__PURE__ */ new Set(["low", "medium", "high", "xhigh", "max"]);
202
- function planRestart(o) {
203
- const opts = o.argv ? launchOptions(o.kind, o.argv) : { kept: [], dropped: [] };
204
- const mode = o.session ? "resume" : o.hadSession ? "fresh" : "continue";
205
- let groups = opts.kept;
206
- const without = (...flags) => {
207
- groups = groups.filter((g) => !flags.includes(g[0].split("=")[0]));
208
- };
209
- if (o.kind === "omp" && mode === "resume") without("--model", "--thinking");
210
- if (o.kind === "claude") {
211
- const cur = o.current || {};
212
- if (mode === "resume") without("--model");
213
- const effort = String(cur.effort || "").toLowerCase();
214
- if (EFFORTS.has(effort)) {
215
- without("--effort");
216
- groups.push(["--effort", effort]);
217
- }
218
- if (cur.permissionMode) {
219
- without("--permission-mode");
220
- if (cur.permissionMode !== "default") groups.push(["--permission-mode", cur.permissionMode]);
221
- }
222
- }
223
- const kept = groups.flat();
224
- const dropped = opts.dropped.flat();
225
- let args;
226
- if (o.kind === "codex") {
227
- args = mode === "fresh" ? kept : ["resume", ...kept, mode === "resume" ? o.session : "--last"];
228
- } else {
229
- args = mode === "resume" ? [...kept, "--resume", o.session] : mode === "continue" ? [...kept, "--continue"] : kept;
230
- }
231
- return { args, mode, kept, dropped, unknownArgs: !o.argv };
232
- }
233
- const FOOTER_MODES = [
234
- [/\bplan mode on\b/i, "plan"],
235
- [/\baccept edits on\b/i, "acceptEdits"],
236
- [/\bauto mode on\b/i, "auto"],
237
- [/\bbypass permissions on\b/i, "bypassPermissions"],
238
- [/\bdon'?t ask (?:mode )?on\b/i, "dontAsk"]
239
- ];
240
- function claudeFooterMode(text) {
241
- const lines = String(text || "").split("\n");
242
- let rule = -1;
243
- for (let i = lines.length - 1; i >= 0 && rule < 0; i--) if (/^\s*─{20,}\s*$/.test(lines[i])) rule = i;
244
- if (rule < 1 || !lines.slice(Math.max(0, rule - 6), rule).some((l) => /^\s*❯/.test(l))) return null;
245
- for (const l of lines.slice(rule + 1)) {
246
- for (const [re, mode] of FOOTER_MODES) if (re.test(l)) return mode;
247
- }
248
- return "default";
249
- }
250
-
251
- const base = (s) => s.replace(/^.*\//, "").replace(/\.(c?js|mjs)$/, "");
252
- async function paneForeground(d, paneId, kind) {
253
- const r = await d.call("pane.process_info", { pane_id: paneId }, 4e3);
254
- const info = r && r.process_info || {};
255
- const procs = info.foreground_processes || [];
256
- const agent = procs.find((p) => p.name === kind || (p.argv || []).some((a) => base(a) === kind)) || null;
257
- const atShell = !agent && Boolean(info.shell_pid) && info.foreground_process_group_id === info.shell_pid;
258
- const sh = procs.find((p) => info.shell_pid && p.pid === info.shell_pid);
259
- const shell = { pid: Number(info.shell_pid) || null, name: sh ? String(sh.name || (sh.argv || [])[0] || "") || null : null };
260
- return { agent, atShell, shell, argv: agent && Array.isArray(agent.argv) ? agent.argv.map(String) : null };
261
- }
262
- async function waitFor(d, ms, test) {
263
- const end = d.now() + ms;
264
- while (d.now() < end) {
265
- await d.sleep(500);
266
- try {
267
- if (await test()) return true;
268
- } catch {
269
- }
270
- }
271
- return false;
272
- }
273
- const waitShell = (d, paneId, kind, ms) => waitFor(d, ms, async () => (await paneForeground(d, paneId, kind)).atShell);
274
- const busy = async (d, paneId) => {
275
- const r = await d.call("pane.get", { pane_id: paneId }, 4e3);
276
- const s = r && r.pane && r.pane.agent_status;
277
- return s === "working" || s === "blocked";
278
- };
279
- async function stopAgent(d, p) {
280
- const kind = p.agent;
281
- const key = (k) => d.call("pane.send_input", { pane_id: p.id, keys: [k] });
282
- if (p.status === "working" || p.status === "blocked") {
283
- for (let i = 0; i < 2; i++) {
284
- await key("esc");
285
- if (await waitFor(d, 3e3, async () => !await busy(d, p.id))) break;
286
- }
287
- }
288
- await d.call("pane.send_input", { pane_id: p.id, text: "/exit" });
289
- await d.sleep(300);
290
- await key("enter");
291
- if (await waitShell(d, p.id, kind, 8e3)) return "exit";
292
- await key("ctrl+c");
293
- await d.sleep(400);
294
- await key("ctrl+c");
295
- if (await waitShell(d, p.id, kind, 6e3)) return "ctrl-c";
296
- throw new HerdrError("restart_stop", "the agent did not stop");
297
- }
298
- async function startAgent(d, p, plan) {
299
- const name = p.name || `${p.agent}-${crypto.randomBytes(2).toString("hex")}`;
300
- let last = null;
301
- for (let i = 0; i < 6; i++) {
302
- try {
303
- await d.call("agent.start", { name, kind: p.agent, pane_id: p.id, timeout_ms: 6e4, ...plan.args.length ? { args: plan.args } : {} }, 75e3);
304
- return;
305
- } catch (e) {
306
- last = e;
307
- if (last.code === "agent_not_ready") return;
308
- if (last.code === "timeout" || last.code === "unreachable") break;
309
- await d.sleep(500);
310
- }
311
- }
312
- throw last || new HerdrError("restart_start", "the agent did not restart");
313
- }
314
-
315
4
  const TERM_UPDATE_MS = 10 * 6e4;
316
5
  const READ_LINES = 400;
317
6
  const readRecent = async (d, paneId) => {
@@ -379,6 +68,7 @@ async function restartPlanFor(p, d = defaultDeps) {
379
68
  const planning = /* @__PURE__ */ new Set();
380
69
  async function restartAgent(paneId) {
381
70
  const p = findPane(paneId);
71
+ if (p == null ? void 0 : p.stopped) throw new HerdrError("stale", "Use the restart buttons for this stopped agent.");
382
72
  if (!p || !p.agent) throw new HerdrError("bad_pane", "agent not found");
383
73
  const cur = restarts.get(paneId);
384
74
  if (planning.has(paneId) || cur && cur.phase !== "failed") throw new HerdrError("restart_busy", "restart already in progress");
@@ -1,29 +1,7 @@
1
1
  import { execFile } from 'node:child_process';
2
2
  import { existsSync } from 'node:fs';
3
- import { a1 as IN_DOCKER, a2 as HOST_OPEN_TARGET, a3 as HOST_OPEN_KEY, H as HerdrError, a4 as PANE_RE, f as findPane, G as getMachine, a5 as splitId, o as fmt, Q as log, a6 as HOST_OPEN_USER } from '../nitro/nitro.mjs';
4
-
5
- function posixResolve(base, p) {
6
- const out = [];
7
- for (const seg of (p.startsWith("/") ? p : `${base}/${p}`).split("/")) {
8
- if (seg === "" || seg === ".") continue;
9
- if (seg === "..") out.pop();
10
- else out.push(seg);
11
- }
12
- return "/" + out.join("/");
13
- }
14
- const POSITION = /:\d+(?::\d+)?$/;
15
- const stripPosition = (s) => s.replace(POSITION, "");
16
- function resolveAgentPath(written, cwd, home) {
17
- const p = stripPosition(String(written || "").trim());
18
- if (!p || !home.startsWith("/") || /[\0\n\r]/.test(p)) return null;
19
- const root = posixResolve("/", home);
20
- const inside = (r2) => r2 === root || r2.startsWith(root === "/" ? "/" : root + "/");
21
- const base = cwd && cwd.startsWith("/") && inside(posixResolve("/", cwd)) ? posixResolve("/", cwd) : root;
22
- const r = posixResolve(base, p.replace(/^~(?=$|\/)/, root));
23
- return inside(r) ? r : null;
24
- }
25
- const RUNNABLE = /\.(app|command|tool|terminal|pkg|mpkg|workflow|action|scpt|scptd|applescript|jar|sh|bash|zsh|csh|fish|py|rb|pl|webloc|inetloc|fileloc|prefpane|qlgenerator|saver|kext|osax|dmg)\/?$/i;
26
- const runnablePath = (p) => RUNNABLE.test(p);
3
+ import { ap as IN_DOCKER, aq as HOST_OPEN_TARGET, ar as HOST_OPEN_KEY, H as HerdrError, as as PANE_RE, f as findPane, a1 as getMachine, at as splitId, E as fmt, ab as log, au as HOST_OPEN_USER } from '../nitro/nitro.mjs';
4
+ import { r as resolveAgentPath, a as runnablePath } from './filePaths.mjs';
27
5
 
28
6
  const REVEAL_CHECKS = `p=$2
29
7
  [ -e "$p" ] || exit 3
@@ -0,0 +1,83 @@
1
+ import { spawnSync, spawn } from 'node:child_process';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { p as pkg } from './package.mjs';
6
+ import { bB as installMode, H as HerdrError, ab as log, bC as oneTapMode, bF as updateRunning } from '../nitro/nitro.mjs';
7
+ import { c as checkUpdate, R as REPO } from './updates.mjs';
8
+
9
+ function wherdrDir(env = process.env) {
10
+ const home = os.homedir();
11
+ const dir = env.WHERDR_DIR || path.join(home, "wherdr");
12
+ return path.resolve(dir === "~" ? home : dir.startsWith("~/") ? path.join(home, dir.slice(2)) : dir);
13
+ }
14
+ function readJob(dir) {
15
+ try {
16
+ const job = JSON.parse(fs.readFileSync(path.join(dir, "update.json"), "utf8"));
17
+ return job && typeof job.state === "string" ? job : null;
18
+ } catch {
19
+ return null;
20
+ }
21
+ }
22
+ function buildPlan(o) {
23
+ if (!oneTapMode(o.mode)) throw new HerdrError("update_manual", "This installation cannot update itself: run the update command");
24
+ if (updateRunning(o.job, o.now)) throw new HerdrError("update_running", "An update is already in progress");
25
+ if (!o.latest || o.to !== o.latest) throw new HerdrError("update_version", "No newer version to install");
26
+ return {
27
+ kind: o.mode,
28
+ from: o.current,
29
+ to: o.latest,
30
+ root: o.root,
31
+ dir: o.dir,
32
+ runtime: o.runtime,
33
+ serverPid: o.pid,
34
+ port: String(o.env.NITRO_PORT || o.env.PORT || 3e3),
35
+ host: String(o.env.NITRO_HOST || o.env.HOST || "127.0.0.1"),
36
+ releaseBase: `https://github.com/${REPO}/releases/download`,
37
+ registry: o.env.npm_config_registry || "https://registry.npmjs.org"
38
+ };
39
+ }
40
+ const packageRoot = () => process.env.WHERDR_ROOT || path.resolve(path.dirname(process.argv[1] || ""), "..", "..");
41
+ async function startUpdate(to) {
42
+ const dir = wherdrDir();
43
+ const info = await checkUpdate();
44
+ const root = packageRoot();
45
+ const plan = buildPlan({
46
+ mode: installMode(process.env.WHERDR_INSTALL),
47
+ current: pkg.version,
48
+ latest: info.latest,
49
+ to,
50
+ job: readJob(dir),
51
+ now: Date.now(),
52
+ root,
53
+ dir,
54
+ runtime: process.execPath,
55
+ pid: process.pid,
56
+ env: process.env
57
+ });
58
+ const source = path.join(root, "bin", "lib", "updater.mjs");
59
+ if (!fs.existsSync(source)) throw new HerdrError("update_manual", "The updater is missing from this installation: run the update command");
60
+ const work = path.join(dir, "update");
61
+ fs.mkdirSync(work, { recursive: true });
62
+ const updater = path.join(work, "updater.mjs");
63
+ const planFile = path.join(work, "plan.json");
64
+ fs.copyFileSync(source, updater);
65
+ fs.writeFileSync(planFile, `${JSON.stringify(plan, null, 2)}
66
+ `);
67
+ const now = Date.now();
68
+ const job = { state: "installing", from: plan.from, to: plan.to, mode: plan.kind, startedAt: now, updatedAt: now };
69
+ fs.writeFileSync(path.join(dir, "update.json"), `${JSON.stringify(job)}
70
+ `);
71
+ const out = fs.openSync(path.join(dir, "update.log"), "a");
72
+ const scoped = !!process.env.INVOCATION_ID && spawnSync("systemd-run", ["--version"], { stdio: "ignore" }).status === 0;
73
+ const [cmd, args] = scoped ? ["systemd-run", ["--user", "--scope", "--collect", "--quiet", process.execPath, updater, planFile]] : [process.execPath, [updater, planFile]];
74
+ const child = spawn(cmd, args, { cwd: dir, env: process.env, detached: true, stdio: ["ignore", out, out] });
75
+ fs.closeSync(out);
76
+ child.on("error", (e) => log(`update: ${e.message}`));
77
+ child.unref();
78
+ log(`update: ${plan.from} \u2192 ${plan.to} (${plan.kind}) started, pid ${child.pid}`);
79
+ return job;
80
+ }
81
+
82
+ export { readJob as r, startUpdate as s, wherdrDir as w };
83
+ //# sourceMappingURL=selfupdate.mjs.map
@@ -0,0 +1,91 @@
1
+ import { p as pkg } from './package.mjs';
2
+ import { bB as installMode, bC as oneTapMode, bD as updateCommand, bE as compareVersions } from '../nitro/nitro.mjs';
3
+
4
+ const REPO = "afloury/wherdr";
5
+ const RELEASES_URL = `https://api.github.com/repos/${REPO}/releases?per_page=100`;
6
+ const DAY_MS = 24 * 60 * 60 * 1e3;
7
+ const RETRY_MS = 60 * 60 * 1e3;
8
+ function createUpdateChecker(opts) {
9
+ var _a;
10
+ const now = (_a = opts.now) != null ? _a : Date.now;
11
+ let cached = null;
12
+ let nextAt = 0;
13
+ let pending = null;
14
+ async function refresh() {
15
+ var _a2;
16
+ try {
17
+ const res = await opts.fetch(RELEASES_URL);
18
+ if (!res.ok) throw new Error("http");
19
+ const releases = await res.json();
20
+ const body = releases.filter((r) => !r.draft && !r.prerelease && /^v\d+\.\d+\.\d+$/.test(String(r.tag_name))).sort((a, b) => compareVersions(String(b.tag_name), String(a.tag_name)))[0];
21
+ if (!body || typeof body.tag_name !== "string") throw new Error("tag");
22
+ const candidate = { version: body.tag_name.replace(/^v/, ""), url: typeof body.html_url === "string" ? body.html_url : "" };
23
+ const mode = installMode(opts.env.WHERDR_INSTALL);
24
+ if (mode === "plugin") {
25
+ const archive = `https://github.com/${REPO}/releases/download/v${candidate.version}/wherdr-${candidate.version}.tgz`;
26
+ if (!(await opts.fetch(archive)).ok || !(await opts.fetch(`${archive}.sha256`)).ok) {
27
+ nextAt = now() + RETRY_MS;
28
+ return;
29
+ }
30
+ }
31
+ if (mode === "npm" || mode === "npm-global") {
32
+ const registry = (opts.env.npm_config_registry || "https://registry.npmjs.org").replace(/\/$/, "");
33
+ const available = await opts.fetch(`${registry}/wherdr/-/wherdr-${candidate.version}.tgz`);
34
+ if (!available.ok) {
35
+ nextAt = now() + RETRY_MS;
36
+ return;
37
+ }
38
+ if (mode === "npm") {
39
+ const latest = await opts.fetch(`${registry}/wherdr/latest`);
40
+ if (!latest.ok || (await latest.json()).version !== candidate.version) {
41
+ nextAt = now() + RETRY_MS;
42
+ return;
43
+ }
44
+ }
45
+ }
46
+ if (mode === "brew") {
47
+ const formula = await opts.fetch("https://raw.githubusercontent.com/afloury/homebrew-tap/main/Formula/wherdr.rb");
48
+ const text = formula.ok ? await ((_a2 = formula.text) == null ? void 0 : _a2.call(formula)) : "";
49
+ if (!(text == null ? void 0 : text.includes(`/v${candidate.version}/wherdr-${candidate.version}.tgz"`))) {
50
+ nextAt = now() + RETRY_MS;
51
+ return;
52
+ }
53
+ }
54
+ cached = candidate;
55
+ nextAt = now() + DAY_MS;
56
+ } catch {
57
+ nextAt = now() + RETRY_MS;
58
+ }
59
+ }
60
+ return async function check() {
61
+ const mode = installMode(opts.env.WHERDR_INSTALL);
62
+ const base = { current: opts.current, mode, command: updateCommand(mode, REPO), oneTap: oneTapMode(mode) };
63
+ if (String(opts.env.WHERDR_UPDATE_CHECK || "").toLowerCase() === "off") return { ...base, latest: null, url: null, checked: false };
64
+ if (now() >= nextAt) {
65
+ pending != null ? pending : pending = refresh().finally(() => {
66
+ pending = null;
67
+ });
68
+ await pending;
69
+ }
70
+ const newer = cached && compareVersions(cached.version, opts.current) > 0;
71
+ return { ...base, latest: newer ? cached.version : null, url: newer ? cached.url || null : null, checked: !!cached };
72
+ };
73
+ }
74
+ function fetchUpdateResource(url, request = fetch) {
75
+ return request(url, {
76
+ method: /\.tgz(?:\.sha256)?$/.test(url) ? "HEAD" : "GET",
77
+ headers: {
78
+ ...new URL(url).hostname === "api.github.com" ? { accept: "application/vnd.github+json" } : {},
79
+ "user-agent": "wherdr"
80
+ },
81
+ signal: AbortSignal.timeout(1e4)
82
+ });
83
+ }
84
+ const checkUpdate = createUpdateChecker({
85
+ current: pkg.version,
86
+ env: process.env,
87
+ fetch: fetchUpdateResource
88
+ });
89
+
90
+ export { REPO as R, checkUpdate as c };
91
+ //# sourceMappingURL=updates.mjs.map
@@ -1,4 +1,4 @@
1
- import { bl as allMachines, G as getMachine, H as HerdrError, a5 as splitId, aB as herdrOn, p as poll, bm as recentDirs, bn as joinId, aC as getState } from '../nitro/nitro.mjs';
1
+ import { bG as allMachines, a1 as getMachine, H as HerdrError, at as splitId, x as herdrOn, p as poll, bH as recentDirs, bI as joinId, m 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 { bv as hostAllowed, bw as sameOrigin, k as auth } from '../nitro/nitro.mjs';
1
+ import { bP as hostAllowed, bQ as sameOrigin, k as auth } from '../nitro/nitro.mjs';
2
2
 
3
3
  var _a, _b;
4
4
  const WS_MAX = 256 * 1024;