wherdr 1.3.2 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.output/nitro.json +1 -1
- package/.output/public/_nuxt/{AgentView.C4YOwvZG.css → AgentView.DzFWBd2A.css} +1 -1
- package/.output/public/_nuxt/{Cd8j9O5w.js → BEJHMUrj.js} +1 -1
- package/.output/public/_nuxt/BOtcEDnA.js +1 -0
- package/.output/public/_nuxt/BUaYhQ2r.js +6 -0
- package/.output/public/_nuxt/{yzABg5xl.js → Bpoxvzh6.js} +1 -1
- package/.output/public/_nuxt/C25ROUa9.js +3 -0
- package/.output/public/_nuxt/CDWjMk9C.js +2 -0
- package/.output/public/_nuxt/CJKsMzIp.js +1 -0
- package/.output/public/_nuxt/CJNhn9sA.js +36 -0
- package/.output/public/_nuxt/COCvtdHN.js +89 -0
- package/.output/public/_nuxt/{Ci8N4mWR.js → CXJnLmWv.js} +1 -1
- package/.output/public/_nuxt/Cl45J6_Q.js +1 -0
- package/.output/public/_nuxt/CndPDbMI.js +2 -0
- package/.output/public/_nuxt/Ctbx58Um.js +23 -0
- package/.output/public/_nuxt/{8ksjcuDu.js → DMLmW6JM.js} +49 -56
- package/.output/public/_nuxt/Dl1PHLOB.js +1 -0
- package/.output/public/_nuxt/Nhex3_iH.js +1 -0
- package/.output/public/_nuxt/OpWX45i7.js +89 -0
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/4994f3a4-4126-4f57-a9e5-c7ebb25850bc.json +1 -0
- package/.output/public/_nuxt/dTj21DMs.js +1 -0
- package/.output/public/_nuxt/entry.BohTWE-n.css +2 -0
- package/.output/public/_nuxt/kwSoIiM7.js +1 -0
- package/.output/public/_nuxt/mkEwYka4.js +1 -0
- package/.output/public/_nuxt/pdf.min.t82Z80JU.mjs +28 -0
- package/.output/public/_nuxt/pdf.worker.min.wgc6bjNh.mjs +28 -0
- package/.output/public/_nuxt/w7Rm7unj.js +1 -0
- package/.output/public/sw.js +1 -1
- package/.output/server/chunks/_/branding.mjs +1 -1
- package/.output/server/chunks/_/filePaths.mjs +25 -0
- package/.output/server/chunks/_/files.mjs +217 -0
- package/.output/server/chunks/_/machineOrder.mjs +1 -1
- package/.output/server/chunks/_/onboarding.mjs +1 -1
- package/.output/server/chunks/_/package.mjs +5 -2
- package/.output/server/chunks/_/pluginPolicy.mjs +93 -0
- package/.output/server/chunks/_/plugins.mjs +9 -96
- package/.output/server/chunks/_/projectBoard.mjs +124 -36
- package/.output/server/chunks/_/projectDocs.mjs +106 -0
- package/.output/server/chunks/_/projectInbox.mjs +135 -0
- package/.output/server/chunks/_/projectThreads.mjs +46 -0
- package/.output/server/chunks/_/projectThreads2.mjs +61 -0
- package/.output/server/chunks/_/projectsActions.mjs +1 -1
- package/.output/server/chunks/_/projectsPlugin.mjs +24 -50
- package/.output/server/chunks/_/projectsPlugin2.mjs +57 -0
- package/.output/server/chunks/_/restart.mjs +2 -312
- package/.output/server/chunks/_/reveal.mjs +2 -24
- package/.output/server/chunks/_/selfupdate.mjs +3 -2
- package/.output/server/chunks/_/settingstabs.mjs +36 -0
- package/.output/server/chunks/_/updates.mjs +51 -10
- package/.output/server/chunks/_/worktrees.mjs +1 -1
- package/.output/server/chunks/_/ws.mjs +1 -1
- package/.output/server/chunks/nitro/nitro.mjs +1718 -417
- package/.output/server/chunks/raw/bump-homebrew.mjs +1 -1
- package/.output/server/chunks/raw/herdr-plugin.mjs +1 -1
- package/.output/server/chunks/raw/release-ready.mjs +5 -0
- package/.output/server/chunks/routes/api/_..._.mjs +1 -1
- package/.output/server/chunks/routes/api/agents.post.mjs +1 -1
- package/.output/server/chunks/routes/api/ask-tab.post.mjs +1 -1
- package/.output/server/chunks/routes/api/attach.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/disable.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/lock-all.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/lock.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/login/options.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/login/verify.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/max-session.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/register/options.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/register/verify.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/status.get.mjs +1 -1
- package/.output/server/chunks/routes/api/board.get.mjs +148 -0
- package/.output/server/chunks/routes/api/changes.get.mjs +2 -2
- package/.output/server/chunks/routes/api/chat/image.get.mjs +2 -2
- package/.output/server/chunks/routes/api/chat.get.mjs +26 -6
- package/.output/server/chunks/routes/api/choose.post.mjs +40 -14
- package/.output/server/chunks/routes/api/claude-statusline.post.mjs +2 -2
- package/.output/server/chunks/routes/api/close/status.get.mjs +2 -2
- package/.output/server/chunks/routes/api/close.post.mjs +1 -1
- package/.output/server/chunks/routes/api/codex-update.post.mjs +2 -2
- package/.output/server/chunks/routes/api/commands.get.mjs +4 -3
- package/.output/server/chunks/routes/api/config.get.mjs +3 -2
- package/.output/server/chunks/routes/api/dirs.get.mjs +2 -2
- package/.output/server/chunks/routes/api/dismiss-stopped.post.mjs +43 -0
- package/.output/server/chunks/routes/api/dismiss.post.mjs +2 -2
- package/.output/server/chunks/routes/api/effort.post.mjs +2 -2
- package/.output/server/chunks/routes/api/efforts.get.mjs +2 -2
- package/.output/server/chunks/routes/api/file.post.mjs +2 -2
- package/.output/server/chunks/routes/api/files/download.get.mjs +60 -0
- package/.output/server/chunks/routes/api/files/read.get.mjs +45 -0
- package/.output/server/chunks/routes/api/files.get.mjs +44 -0
- package/.output/server/chunks/routes/api/gitroot.get.mjs +2 -2
- package/.output/server/chunks/routes/api/health.get.mjs +1 -1
- package/.output/server/chunks/routes/api/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/input.post.mjs +32 -5
- package/.output/server/chunks/routes/api/interrupt.post.mjs +2 -2
- package/.output/server/chunks/routes/api/isgit.get.mjs +2 -2
- package/.output/server/chunks/routes/api/machine/awake.get.mjs +2 -2
- package/.output/server/chunks/routes/api/machine/awake.post.mjs +2 -2
- package/.output/server/chunks/routes/api/machine/order.get.mjs +1 -1
- package/.output/server/chunks/routes/api/machine/order.post.mjs +1 -1
- package/.output/server/chunks/routes/api/machine/rename.post.mjs +2 -2
- package/.output/server/chunks/routes/api/menu.post.mjs +5 -2
- package/.output/server/chunks/routes/api/model.post.mjs +2 -2
- package/.output/server/chunks/routes/api/models.get.mjs +2 -2
- package/.output/server/chunks/routes/api/nav.post.mjs +36 -22
- package/.output/server/chunks/routes/api/onboarding.get.mjs +1 -1
- package/.output/server/chunks/routes/api/onboarding.post.mjs +1 -1
- package/.output/server/chunks/routes/api/phone.get.mjs +2 -2
- package/.output/server/chunks/routes/api/phone.post.mjs +2 -2
- package/.output/server/chunks/routes/api/plugins/actions.get.mjs +4 -1
- package/.output/server/chunks/routes/api/plugins/invoke.post.mjs +4 -1
- package/.output/server/chunks/routes/api/plugins/profiles.get.mjs +4 -1
- package/.output/server/chunks/routes/api/plugins/projects.get.mjs +4 -3
- package/.output/server/chunks/routes/api/plugins/projects.post.mjs +4 -3
- package/.output/server/chunks/routes/api/plugins/thread-limits.get.mjs +2 -2
- package/.output/server/chunks/routes/api/plugins/thread-limits.post.mjs +2 -2
- package/.output/server/chunks/routes/api/project/inbox.get.mjs +44 -0
- package/.output/server/chunks/routes/api/project/inbox.post.mjs +44 -0
- package/.output/server/chunks/routes/api/project/memory.get.mjs +43 -0
- package/.output/server/chunks/routes/api/project/report.get.mjs +3 -2
- package/.output/server/chunks/routes/api/project/routines.get.mjs +44 -0
- package/.output/server/chunks/routes/api/project/settings.get.mjs +42 -0
- package/.output/server/chunks/routes/api/project/thread.get.mjs +45 -0
- package/.output/server/chunks/routes/api/project/thread.post.mjs +47 -0
- package/.output/server/chunks/routes/api/prompt.post.mjs +21 -3
- package/.output/server/chunks/routes/api/push/quiet.post.mjs +2 -2
- package/.output/server/chunks/routes/api/push/subscribe.post.mjs +2 -2
- package/.output/server/chunks/routes/api/push/test.post.mjs +2 -2
- package/.output/server/chunks/routes/api/push/unsubscribe.post.mjs +2 -2
- package/.output/server/chunks/routes/api/quotas.get.mjs +2 -2
- package/.output/server/chunks/routes/api/rename.post.mjs +1 -1
- package/.output/server/chunks/routes/api/requeue.post.mjs +2 -2
- package/.output/server/chunks/routes/api/restart.get.mjs +1 -1
- package/.output/server/chunks/routes/api/restart.post.mjs +1 -1
- package/.output/server/chunks/routes/api/reveal.post.mjs +2 -1
- package/.output/server/chunks/routes/api/screen-key.post.mjs +14 -11
- package/.output/server/chunks/routes/api/screen.get.mjs +6 -37
- package/.output/server/chunks/routes/api/search.get.mjs +2 -2
- package/.output/server/chunks/routes/api/seen.post.mjs +2 -2
- package/.output/server/chunks/routes/api/sessions.get.mjs +2 -2
- package/.output/server/chunks/routes/api/sessions.post.mjs +2 -2
- package/.output/server/chunks/routes/api/settings-tab.post.mjs +89 -0
- package/.output/server/chunks/routes/api/space.post.mjs +14 -14
- package/.output/server/chunks/routes/api/state.get.mjs +2 -2
- package/.output/server/chunks/routes/api/unqueue.post.mjs +2 -2
- package/.output/server/chunks/routes/api/update/status.get.mjs +1 -1
- package/.output/server/chunks/routes/api/update.get.mjs +2 -2
- package/.output/server/chunks/routes/api/update.post.mjs +2 -2
- package/.output/server/chunks/routes/api/upload.post.mjs +2 -2
- package/.output/server/chunks/routes/api/worktrees/remove.post.mjs +1 -1
- package/.output/server/chunks/routes/api/worktrees.get.mjs +1 -1
- package/.output/server/chunks/routes/favicon.ico.get.mjs +1 -1
- package/.output/server/chunks/routes/icons/_name_.get.mjs +2 -2
- package/.output/server/chunks/routes/renderer.mjs +3 -3
- package/.output/server/chunks/routes/uploads/_...name_.get.mjs +2 -2
- package/.output/server/chunks/routes/ws/_..._.mjs +2 -2
- package/.output/server/chunks/routes/ws/events.mjs +2 -2
- package/.output/server/chunks/routes/ws/term.mjs +2 -2
- package/.output/server/chunks/virtual/precomputed.mjs +1 -1
- package/.output/server/index.mjs +2 -2
- package/.output/server/package.json +1 -1
- package/README.md +368 -40
- package/bin/install-docker-skill.sh +20 -0
- package/bin/lib/commands.mjs +5 -1
- package/bin/lib/core.mjs +1 -0
- package/bin/lib/install-skill.sh +100 -0
- package/bin/lib/skill.mjs +16 -0
- package/bin/lib/updater.mjs +65 -12
- package/bin/lib/verify-release.mjs +20 -0
- package/package.json +5 -2
- package/skills/wherdr/SKILL.md +186 -0
- package/.output/public/_nuxt/B7QP1TFs.js +0 -23
- package/.output/public/_nuxt/BDNMzG2s.js +0 -1
- package/.output/public/_nuxt/BOpBIziZ.js +0 -6
- package/.output/public/_nuxt/BWXdFfeg.js +0 -17
- package/.output/public/_nuxt/COFCNFpG.js +0 -83
- package/.output/public/_nuxt/CWwyK2XK.js +0 -2
- package/.output/public/_nuxt/CXG-cOdh.js +0 -1
- package/.output/public/_nuxt/CkZ8t6uB.js +0 -1
- package/.output/public/_nuxt/D4Yz4rat.js +0 -65
- package/.output/public/_nuxt/D7sxNXx1.js +0 -1
- package/.output/public/_nuxt/DViwOclv.js +0 -1
- package/.output/public/_nuxt/DoD7Qb5P.js +0 -30
- package/.output/public/_nuxt/DyBZDSCV.js +0 -2
- package/.output/public/_nuxt/SiL1FJ5s.js +0 -3
- package/.output/public/_nuxt/bLP7Jj-b.js +0 -1
- package/.output/public/_nuxt/builds/meta/7afbf062-5369-4002-b20d-7a582ff6e0f1.json +0 -1
- package/.output/public/_nuxt/entry.Crt1r4l3.css +0 -2
- package/.output/server/chunks/routes/ws/mirror.mjs +0 -161
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<p align="center"><b>A complete workspace for the coding agents running in <a href="https://herdr.dev">Herdr</a>, on your
|
|
8
8
|
computer and on your phone.</b></p>
|
|
9
9
|
|
|
10
|
-
<p align="center"><a href="https://wherdr.dev"><b>wherdr.dev</b></a> · <
|
|
10
|
+
<p align="center"><a href="https://wherdr.dev"><b>wherdr.dev</b></a> · <a href="#ask-your-ai-agent">Ask your AI agent</a></p>
|
|
11
11
|
|
|
12
12
|
<p align="center"><a href="https://wherdr.dev/demo/"><b>Try it in your browser — no install</b></a>: the real app on scripted agents, nothing runs.</p>
|
|
13
13
|
|
|
@@ -15,7 +15,20 @@ computer and on your phone.</b></p>
|
|
|
15
15
|
|
|
16
16
|
## Quick start
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
### Ask your AI agent
|
|
19
|
+
|
|
20
|
+
**Recommended.** Paste this into Claude Code, Codex or any coding agent: it installs and sets up wherdr for you.
|
|
21
|
+
|
|
22
|
+
```text
|
|
23
|
+
Read https://wherdr.dev/agent.md and help me set up wherdr. Check what is already installed first, and ask me before installing anything.
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
It follows [our setup guide for agents](https://wherdr.dev/agent.md): checks what you already have,
|
|
27
|
+
asks before installing anything, sets up your phone over Tailscale, never exposes wherdr to the Internet.
|
|
28
|
+
|
|
29
|
+
### Or run the installer yourself
|
|
30
|
+
|
|
31
|
+
On the computer that runs [Herdr](https://herdr.dev) (≥ 0.9.1), macOS or Linux:
|
|
19
32
|
|
|
20
33
|
```sh
|
|
21
34
|
curl -fsSL https://wherdr.dev/install | sh
|
|
@@ -102,7 +115,8 @@ Details in [Features](#features) and [Security](#security).
|
|
|
102
115
|
- [Features](#features)
|
|
103
116
|
- [How it works](#how-it-works)
|
|
104
117
|
- [Requirements](#requirements)
|
|
105
|
-
- [Installation](#installation): [
|
|
118
|
+
- [Installation](#installation): [ask your AI agent](#ask-your-ai-agent-1) ·
|
|
119
|
+
[or run the installer yourself](#the-one-command) ·
|
|
106
120
|
[which setup?](#which-setup) ·
|
|
107
121
|
[always-on server + Tailscale](#recommended-always-on-server--tailscale) ·
|
|
108
122
|
[other private networks](#other-private-networks) ·
|
|
@@ -126,9 +140,12 @@ Details in [Features](#features) and [Security](#security).
|
|
|
126
140
|
|
|
127
141
|
### Everywhere
|
|
128
142
|
|
|
129
|
-
- **Live agent list**, one line per Herdr space, grouped by state (your turn, working, ready)
|
|
130
|
-
|
|
131
|
-
question,
|
|
143
|
+
- **Live agent list**, one line per Herdr space, grouped by state (your turn, working, ready).
|
|
144
|
+
The list is compact by default: agent, title, project badge and state. When an agent asks for
|
|
145
|
+
permission or asks a question, its card opens on the question and its options: **answer in one
|
|
146
|
+
tap** without opening it; the card is one line again once answered. Turn off Settings ›
|
|
147
|
+
Appearance › Home screen › **Compact list** for detailed cards, with the folder, the model and
|
|
148
|
+
a preview of each agent's last answer.
|
|
132
149
|
- **Conversation view**: the agent's real transcript (Claude Code, Codex and omp), rendered as
|
|
133
150
|
Markdown, with grouped tool calls, images (full-screen viewer with pinch / wheel zoom and pan), timestamps, search and infinite scroll back to the
|
|
134
151
|
first message. Reading a conversation never touches the terminal, so it never resizes a pane.
|
|
@@ -136,7 +153,7 @@ Details in [Features](#features) and [Security](#security).
|
|
|
136
153
|
its prompt, or run in the agent's shell mode (`!`, Claude Code, Codex and omp) after you
|
|
137
154
|
confirm the full command.
|
|
138
155
|
- **Terminal view**: the real terminal (xterm.js, WebGL or DOM renderer) with take-over. Opening
|
|
139
|
-
it resizes the real pane to your screen; closing it gives the pane the size it had before
|
|
156
|
+
it resizes the real pane to your screen (or its cell in a split); closing it gives the pane the size it had before
|
|
140
157
|
(after 30 seconds when the connection just dropped, e.g. a locked phone), unless a Herdr
|
|
141
158
|
client attached meanwhile laid it out its own way. On a
|
|
142
159
|
computer, drag over the text on screen to select it: releasing the button copies it, as do
|
|
@@ -146,6 +163,22 @@ Details in [Features](#features) and [Security](#security).
|
|
|
146
163
|
line wrapped by the width is copied in one piece, without the breaks between its rows. An image
|
|
147
164
|
pasted with `⌘V` (Mac), here or in a side-by-side terminal, goes to the agent's machine and its
|
|
148
165
|
path is pasted, which omp and Claude Code attach as an image, as in the conversation.
|
|
166
|
+
- **Interactive agent screens**: in a conversation, an uncertain menu or panel opens the
|
|
167
|
+
pane's real terminal in a modal window, with arrows, Enter, Escape, Tab, digits and y/n.
|
|
168
|
+
The rest of the app waits behind a scrim (the window fills the screen on a phone); in a
|
|
169
|
+
split, only the cell in use opens it. It closes after the agent's message field returns.
|
|
170
|
+
Close it yourself at any time with its button or a click on the scrim: that releases the
|
|
171
|
+
terminal without pressing Escape, which goes to the agent, and the same interaction stays
|
|
172
|
+
closed until you reopen it. Existing native questions, approvals, menus, waiting screens and
|
|
173
|
+
Claude settings cards keep their controls. The window is a fallback after those
|
|
174
|
+
recognizers, with two explicit exceptions: Codex's two-column `/usage` menu and
|
|
175
|
+
its Agent Command Center. The slash menu still lists and sends commands. On a phone, the window
|
|
176
|
+
temporarily fits the real pane to its width and restores its size on release, using
|
|
177
|
+
the same lease as Terminal view; it does not shrink 120 columns into unreadable text.
|
|
178
|
+
A pane already shown in Terminal keeps its existing live view. Try `/usage` on the
|
|
179
|
+
Codex agent in the browser demo (scripted, no account data).
|
|
180
|
+
In the compact list, native questions keep their preview and one-tap answers.
|
|
181
|
+
Unrecognized blocking screens offer an **Open interactive terminal** button.
|
|
149
182
|
- **Composer**: send messages while the agent works (queued, cancellable), attach or paste
|
|
150
183
|
photos and the files the agent can read (Claude Code: PDFs, notebooks, text and code of any
|
|
151
184
|
extension; Codex: notebooks, text and code), run slash commands (`/compact`, `/clear`, `/context`, `/usage`…) and see the output
|
|
@@ -159,6 +192,20 @@ Details in [Features](#features) and [Security](#security).
|
|
|
159
192
|
resumes the same conversation (only while Codex is idle). Codex's own weekly-limit warning
|
|
160
193
|
(its footer gauge, or its startup heads-up) is repeated above the field, with its values, while
|
|
161
194
|
Codex shows it.
|
|
195
|
+
- **After Codex updates itself and exits**: a **Your turn** card offers **Restart Codex**
|
|
196
|
+
for a new conversation, with the original launch arguments. For an existing conversation,
|
|
197
|
+
choose **Resume conversation** (its exact session, with the original options) or **Start
|
|
198
|
+
fresh**. If wherdr cannot identify the session, Resume opens Codex's picker rather than
|
|
199
|
+
choosing another pane's latest conversation. The usual attention notification applies.
|
|
200
|
+
Nothing restarts automatically: the pane must still show the same empty shell prompt,
|
|
201
|
+
with the shell in the foreground. Unrecognized shell prompts require a manual restart
|
|
202
|
+
in the terminal. wherdr must have observed Codex before it exited.
|
|
203
|
+
**Dismiss** puts the card away for good: the pane is a plain shell again, to use as you like.
|
|
204
|
+
Project panel messages wait in the queue until the agent returns; if it does not (Dismiss, or
|
|
205
|
+
a Codex that simply left), their text goes back into the pane's message field. Continuation
|
|
206
|
+
prompts (unfinished quotes or heredocs) refuse a restart too. If the final
|
|
207
|
+
transcript read fails, both conversation choices remain available; a session
|
|
208
|
+
contradicted by a guessed match is resumed through Codex's picker.
|
|
162
209
|
- **Model and effort pickers** for Claude Code, Codex and omp (omp: its
|
|
163
210
|
"Switch Model" selector, `/switch` or `/model`, and its thinking level, changed with its own
|
|
164
211
|
⇧⇥ cycle). Changes apply **to the current session only**; wherdr never changes your default
|
|
@@ -166,6 +213,30 @@ Details in [Features](#features) and [Security](#security).
|
|
|
166
213
|
- **New agent**: pick an installed agent (or a plain terminal), a folder, optionally a separate
|
|
167
214
|
Git **worktree** and branch, resume the last conversation, and queue a first message.
|
|
168
215
|
- **Changes view**: Git status and diff of an agent's working folder; worktree management.
|
|
216
|
+
Review the diff like a pull request: comment on one line or on a **block of lines**. The code
|
|
217
|
+
itself is plain text — a click on it does nothing, so it can be selected and copied.
|
|
218
|
+
- **Mouse**: a **+** appears in the gutter of the hovered line; click it to comment that line,
|
|
219
|
+
or press it and drag over other lines to comment the block. With an editor open, Shift+click
|
|
220
|
+
another line to change its block.
|
|
221
|
+
- **Touch**: tap a line number to choose the line, tap another line to extend the block, then
|
|
222
|
+
**Comment** in the bar pinned at the bottom. Nothing is written by the first tap.
|
|
223
|
+
- **Keyboard**: one tab stop per file; arrow keys move between lines, Shift+arrows choose a
|
|
224
|
+
block, Enter opens the editor. In the editor, ⌘/Ctrl+Enter saves and Escape cancels (a second
|
|
225
|
+
Escape if text would be lost); the window stays open.
|
|
226
|
+
|
|
227
|
+
A block stays within one hunk (the other hunks dim while it is chosen) and may mix deleted and
|
|
228
|
+
new lines. Each comment is a thread under the last line of its block, headed by its lines
|
|
229
|
+
("Lines 12–18"), with **Edit** and a two-step **Delete**; the lines it covers are marked in
|
|
230
|
+
the gutter. Comments, including the text of an editor left open, are saved on this device for
|
|
231
|
+
that agent, across refreshes and reloads. A block that leaves the diff, or whose code changed
|
|
232
|
+
between its first and last lines, is flagged above the diff and keeps the excerpt that was
|
|
233
|
+
commented.
|
|
234
|
+
**Send review** stays pinned with the number of comments; it groups them by file as
|
|
235
|
+
`file:12-18 — remark` (`file:12` for one line) followed by a short excerpt of the block, and
|
|
236
|
+
appends them to the conversation's message draft, preserving existing text; it never sends a
|
|
237
|
+
message. Deleted lines use the old file's numbers, explicitly labelled. **Discard** clears the
|
|
238
|
+
local review. Works on remote agents and in the demo too, with no writes to the agent's
|
|
239
|
+
machine. Browser storage must be available to retain comments after closing the view.
|
|
169
240
|
- **Several machines**: agents of the SSH machines registered in Herdr (`herdr machine add`)
|
|
170
241
|
appear in their own section; everything works the same on a remote agent.
|
|
171
242
|
- **Named Herdr sessions**, **quotas** (remaining Claude and Codex usage limits), **Herdr plugin
|
|
@@ -176,7 +247,10 @@ Details in [Features](#features) and [Security](#security).
|
|
|
176
247
|
### On a computer
|
|
177
248
|
|
|
178
249
|
- **Split panes, live**: a tab with several panes is drawn with Herdr's real layout; every pane
|
|
179
|
-
shows its conversation or terminal live
|
|
250
|
+
shows its conversation or terminal live. Every visible terminal fills its cell and follows
|
|
251
|
+
window and divider resizing, keeping its instance and connection when focus changes.
|
|
252
|
+
Click a cell to give it the keyboard. Leaving the tab restores each terminal's original size,
|
|
253
|
+
unless a Herdr client has resized it meanwhile.
|
|
180
254
|
- **Rearrange the layout**: drag a pane onto another to move it, drag a divider to resize
|
|
181
255
|
(arrow keys work on a focused divider); changes go to Herdr itself.
|
|
182
256
|
- **Spaces and tabs**: sidebar with every space, tabs at the top, active tab remembered per space.
|
|
@@ -185,7 +259,8 @@ Details in [Features](#features) and [Security](#security).
|
|
|
185
259
|
- **Keyboard shortcuts** (`Mod` is ⌘ on macOS, Ctrl elsewhere; `Mod+/` or `?` lists them all,
|
|
186
260
|
also in Settings › Computer):
|
|
187
261
|
- `Ctrl/⌘+K` global search across agents and conversations, `Alt+↑/↓` previous / next agent
|
|
188
|
-
in the list, `Mod+,` settings
|
|
262
|
+
in the list, `Mod+,` settings, `H` the [Board](#works-great-with-herdr-projects) (outside a
|
|
263
|
+
text field and the terminal).
|
|
189
264
|
- `Mod+Alt+N` new agent in a new space, `Mod+Alt+T` new tab in the current space,
|
|
190
265
|
`Mod+Alt+W` close the current pane (after confirmation). They work from the terminal too.
|
|
191
266
|
- With [herdr-projects](#works-great-with-herdr-projects) on the agent's machine: `Mod+Alt+P`
|
|
@@ -198,10 +273,16 @@ Details in [Features](#features) and [Security](#security).
|
|
|
198
273
|
and `Shift+Enter` adds a new line. On a "Your turn" card, `1`–`9` pick an option (on AZERTY
|
|
199
274
|
without Shift too, outside the message field); on the `/resume` card, `Ctrl+A` switches
|
|
200
275
|
between every project and the current one (`⌘A` still selects all on macOS).
|
|
276
|
+
- In the message field, `↑` on the first line recalls previous messages and slash commands;
|
|
277
|
+
`↓` on the last line returns to newer entries, then restores your draft. History keeps the
|
|
278
|
+
last 100 texts sent from this device per agent, without attachments or quoted references.
|
|
201
279
|
- **Project board** for [herdr-projects](#works-great-with-herdr-projects): coordinator and threads grouped
|
|
202
280
|
under their project, and a side panel with the project's task lists (to test, to decide,
|
|
203
281
|
to review, in progress, in queue, blocked, to do, backlog — each optional) and one-click
|
|
204
282
|
replies to the coordinator.
|
|
283
|
+
- **Board**: every agent, and with herdr-projects every project, thread and task, in four columns
|
|
284
|
+
(Blocked, Todo, Ongoing, Finished). Drag a task card to another column, or use its **Move
|
|
285
|
+
to…** menu, to ask the coordinator to move it.
|
|
205
286
|
- **Settings** in a sidebar, with desktop-only options such as the content width.
|
|
206
287
|
|
|
207
288
|
### On a phone
|
|
@@ -231,7 +312,10 @@ phone / laptop ──private network──> HTTPS (tailscale serve, private prox
|
|
|
231
312
|
|
|
232
313
|
wherdr runs on the same machine as the Herdr server (the "server" below). It uses Herdr's local
|
|
233
314
|
socket API and CLI, reads the agents' transcript files, and serves a client-only Nuxt app. Data
|
|
234
|
-
it keeps (VAPID keys, push subscriptions, passkeys, recent folders) lives in `data/`.
|
|
315
|
+
it keeps (VAPID keys, push subscriptions, passkeys, recent folders) lives in `data/`. So do the
|
|
316
|
+
long texts pasted into the message field, which the server keeps to show them as cards on every
|
|
317
|
+
device: `data/pastes.json`, in clear, readable by the server's user only (mode 600), at most the
|
|
318
|
+
last 100 texts and 2 MB, each one deleted 30 days after it was last sent.
|
|
235
319
|
|
|
236
320
|
Built with Nuxt 4, Nuxt UI 4, Tailwind 4 and TypeScript; the Herdr gateway (API, WebSockets,
|
|
237
321
|
Web Push, lock) runs in Nitro.
|
|
@@ -252,7 +336,20 @@ Web Push, lock) runs in Nitro.
|
|
|
252
336
|
|
|
253
337
|
## Installation
|
|
254
338
|
|
|
255
|
-
###
|
|
339
|
+
### Ask your AI agent
|
|
340
|
+
|
|
341
|
+
**Recommended.** Paste this into Claude Code, Codex or any coding agent: it installs and sets up wherdr for you.
|
|
342
|
+
|
|
343
|
+
```text
|
|
344
|
+
Read https://wherdr.dev/agent.md and help me set up wherdr. Check what is already installed first, and ask me before installing anything.
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
It follows [our setup guide for agents](https://wherdr.dev/agent.md): checks what you already have,
|
|
348
|
+
asks before installing anything, sets up your phone over Tailscale, never exposes wherdr to the Internet.
|
|
349
|
+
|
|
350
|
+
<a id="the-one-command"></a>
|
|
351
|
+
|
|
352
|
+
### Or run the installer yourself
|
|
256
353
|
|
|
257
354
|
On the computer that runs Herdr, as your user, on macOS or Linux:
|
|
258
355
|
|
|
@@ -289,7 +386,7 @@ Settings, as environment variables (`curl -fsSL https://wherdr.dev/install | WHE
|
|
|
289
386
|
| `WHERDR_MODE` | — | `native`: Node.js even when Docker is there. `docker`: no plugin, Docker Compose by hand in `WHERDR_DIR` (Linux; see below). |
|
|
290
387
|
| `WHERDR_YES` | — | `1` answers yes to every question (non-interactive use). |
|
|
291
388
|
| `WHERDR_NO_BROWSER` | — | `1` never opens a browser. |
|
|
292
|
-
| `WHERDR_REF` |
|
|
389
|
+
| `WHERDR_REF` | main | Git tag or branch of the plugin (or of `docker-compose.yml` with `WHERDR_MODE=docker`). |
|
|
293
390
|
| `WHERDR_PLUGIN` | `afloury/wherdr` | A local checkout to link and build instead (development, tests). |
|
|
294
391
|
|
|
295
392
|
**Docker by hand, with the script:** `curl -fsSL https://wherdr.dev/install | WHERDR_MODE=docker sh`
|
|
@@ -615,8 +712,8 @@ setup by itself:
|
|
|
615
712
|
`~/wherdr` (`docker-compose.yml`, `.env`), the same files as `WHERDR_MODE=docker` of
|
|
616
713
|
[the one command](#the-one-command).
|
|
617
714
|
- **Node.js 22** everywhere else, and always on macOS (Docker Desktop cannot reach Herdr's
|
|
618
|
-
socket): the plugin downloads the prebuilt
|
|
619
|
-
|
|
715
|
+
socket): the plugin downloads the prebuilt package of its version from GitHub Releases and
|
|
716
|
+
verifies its SHA-256 checksum, copies it to `~/wherdr/app` and runs it detached from there, with
|
|
620
717
|
its pid and log (`wherdr.log`) in `~/wherdr`. Herdr builds plugins in a temporary folder and
|
|
621
718
|
then moves them, so the server never runs from the plugin folder. Bun works too when Node.js 22
|
|
622
719
|
is missing. Without either, the install stops and says so.
|
|
@@ -738,6 +835,27 @@ home screen and in Settings › About, with the release notes and the exact comm
|
|
|
738
835
|
Hide it until the next version with ×. Set `WHERDR_UPDATE_CHECK=off` to disable the check. The
|
|
739
836
|
installed version is shown in Settings › About.
|
|
740
837
|
|
|
838
|
+
GitHub release packages (including the bundled agent skill), Docker images, and Homebrew
|
|
839
|
+
updates are published without waiting for npm moderation. Native plugin installs and updates
|
|
840
|
+
use the GitHub `.tgz` and verify its SHA-256 checksum before extraction. A failed one-tap
|
|
841
|
+
download or checksum check leaves the running version in place. Plugin installation tries
|
|
842
|
+
GitHub first, then the prebuilt npm package of the exact same version (with its registry integrity hash), and only builds from source when neither works.
|
|
843
|
+
This also keeps older 1.3.x releases without GitHub archives installable with Node.js or Bun.
|
|
844
|
+
Packages predating the bundled skill retain the plugin checkout's commands and skill, so
|
|
845
|
+
skill refresh, installation and uninstallation remain available.
|
|
846
|
+
The installer fetches `main` explicitly unless you set `WHERDR_REF`.
|
|
847
|
+
|
|
848
|
+
The SHA-256 checksum detects damaged downloads. It is served beside the archive, so someone
|
|
849
|
+
who can replace both files can make them match; it does not prove the publisher’s identity
|
|
850
|
+
or protect against replacement of the archive and checksum together.
|
|
851
|
+
|
|
852
|
+
`npm install -g`, `npx`, `bunx` and `pnpm dlx` still need npm to serve the wherdr package.
|
|
853
|
+
Their banner waits for registry availability; Homebrew's banner waits for its formula.
|
|
854
|
+
Versions through 1.3.2 use GitHub's `latest` marker and an npm-based updater. That marker only
|
|
855
|
+
advances once npm **and** Homebrew are ready, so their existing Update button continues to work.
|
|
856
|
+
To update an older native plugin earlier, rerun the installer or press **U** in its Herdr panel.
|
|
857
|
+
See [Releasing](docs/RELEASING.md) for the publication order and recovery steps.
|
|
858
|
+
|
|
741
859
|
**Update in one tap.** When wherdr runs from the Herdr plugin (Node.js mode), a global npm install
|
|
742
860
|
or Homebrew, the banner has an **Update** button instead of the command, for a session opened on
|
|
743
861
|
this computer (`localhost`) or unlocked with a passkey. wherdr installs the new version in a
|
|
@@ -749,7 +867,7 @@ and the app says so. Every step is logged in `~/wherdr/update.log`.
|
|
|
749
867
|
|
|
750
868
|
| Setup | What Update does |
|
|
751
869
|
| --- | --- |
|
|
752
|
-
| Herdr plugin, Node.js |
|
|
870
|
+
| Herdr plugin, Node.js | Verifies and unpacks the GitHub release package of the new version into `~/wherdr/app`, keeps the old copy, restarts |
|
|
753
871
|
| `npm install -g wherdr` | `npm install -g wherdr@X.Y.Z`, then restarts (login service included) |
|
|
754
872
|
| Homebrew | `brew upgrade wherdr`, then `brew services restart wherdr` |
|
|
755
873
|
|
|
@@ -837,6 +955,92 @@ All settings are environment variables (`.env` with Docker).
|
|
|
837
955
|
In the app, **Settings** holds per-device preferences: language, theme, notifications, terminal
|
|
838
956
|
text size and renderer, typing effect, what the home screen shows, and the passkey lock.
|
|
839
957
|
|
|
958
|
+
**Settings › Conversation › Reply style** chooses how an agent's reply offers to be quoted in
|
|
959
|
+
the field, question by question and point by point (a list item or a paragraph that asks
|
|
960
|
+
nothing), so that one message answers them all:
|
|
961
|
+
|
|
962
|
+
| Style | A question | A point |
|
|
963
|
+
| --- | --- | --- |
|
|
964
|
+
| **Icon** (default) | A small `↳` after it, in the middle or at the end of the message. | A grey `↳` at its end: on hover on a computer, always there and pale on a phone. |
|
|
965
|
+
| **Tap the text** | No button: the question is underlined, tap or click it. | Click it on a computer. On a phone, tap it, then **↳ Discuss**: a single tap never quotes, so reading, scrolling and selecting text stay as they are. |
|
|
966
|
+
| **List under the message** | A number after it, and the questions listed under the message. | **+ Quote a point** under the message, then the point. Offered when the reply has a list item to quote, or two points or more: not under one paragraph of prose. |
|
|
967
|
+
|
|
968
|
+
Every one of these is a button reachable with the keyboard (`Tab`, then `Enter`), and selecting a
|
|
969
|
+
passage still offers **Reply** on it. A quoted question or point shows `✓`.
|
|
970
|
+
|
|
971
|
+
**One syntax for every reference.** Whatever you reply to, the field gets one line that names it,
|
|
972
|
+
and your answer goes on the lines below:
|
|
973
|
+
|
|
974
|
+
```
|
|
975
|
+
↳ Quote message 11:37 ~k3f : I can merge the PR —
|
|
976
|
+
Go ahead.
|
|
977
|
+
↳ Quote point 11:37 ~k3f : Shall I tag the release today? —
|
|
978
|
+
Yes
|
|
979
|
+
↳ Quote decision 11:37 #3 ~k3f : Publish the release notes on the site? —
|
|
980
|
+
No
|
|
981
|
+
```
|
|
982
|
+
|
|
983
|
+
| Line | Written by |
|
|
984
|
+
| --- | --- |
|
|
985
|
+
| `↳ Quote message <time> ~<code> : <start of the message> —` | **Reply** under an agent message. |
|
|
986
|
+
| `↳ Quote point <time> ~<code> : <excerpt> —` | `↳` on a question or a point, **Reply** on a selected passage. |
|
|
987
|
+
| `↳ Quote decision <time> #<n> ~<code> : <question> —` | **Yes**, **No** or `↳` on a row of a decision table. |
|
|
988
|
+
| `↳ Quote decisions <time> #<rows> ~<code> : <questions> —` | **OK to all** on a decision table. |
|
|
989
|
+
| `↳ Decision: <task> —`, `↳ Problem: <task> —`, `↳ Question: <task> —`, `↳ Detail on <task> —`, `↳ Feedback on <task> —` (and their French labels) | **Answer**, **Problem**, **Question**, **Clarify** and **Comment** in the Project panel. |
|
|
990
|
+
|
|
991
|
+
- The time is the one shown on the agent's message, so an answer to an earlier message is never
|
|
992
|
+
read as an answer to the last one. The types are the same words in every language.
|
|
993
|
+
- The code after `~` is three characters wherdr derives from the message (and the rank of the
|
|
994
|
+
table, from the second table of a message on). It tells apart two messages of the same minute
|
|
995
|
+
and two tables of one message, whatever the excerpt shows. The field draws it dimmed, like
|
|
996
|
+
the words before the excerpt; the quote of a sent message leaves it out. The rows of **OK to
|
|
997
|
+
all** are the numbers the table really has: `#1-4`, or `#1,4` when rows 2 and 3 do not exist.
|
|
998
|
+
- A reference is a whole line: it starts with `↳` in the first column and ends with ` —` at the
|
|
999
|
+
end of the line, and only there, so an excerpt may hold dashes of its own. The excerpt is plain
|
|
1000
|
+
text on one line; a long one is cut with `…` (a message keeps its start, a passage its start
|
|
1001
|
+
and its end).
|
|
1002
|
+
- Several references fit in one message, each followed by its answer.
|
|
1003
|
+
- Anything else is your own text: a `>` at the start of a line, a `↳` line of an unknown type or
|
|
1004
|
+
with words after its dash. Text you paste never becomes a reference either: a pasted line that
|
|
1005
|
+
reads like one gets a `\` before its `↳`. A long paste, shown as a **Pasted text** card, is
|
|
1006
|
+
sent exactly as it was pasted.
|
|
1007
|
+
- In the conversation, each reference of a sent message shows as a quote; tap it to see the
|
|
1008
|
+
message it names. Messages sent earlier with `> ` lines still show as quotes.
|
|
1009
|
+
|
|
1010
|
+
**Settings › Conversation › Quoted replies** chooses how the field shows these lines: **Tokens,
|
|
1011
|
+
native field** (default) draws each one as a token in the usual field, **Plain text** shows the
|
|
1012
|
+
same lines as text, a fallback if the tokens misbehave. The message sent is the same.
|
|
1013
|
+
|
|
1014
|
+
A **closed question**, one that yes or no answers in full, also gets **Yes** and **No** next to
|
|
1015
|
+
its `↳` (at the end of its row in the list style). A tap refers to the question and writes the
|
|
1016
|
+
answer under it, in the language of the interface, exactly as Reply and typing would; nothing is sent, so several questions can be
|
|
1017
|
+
answered in a row before sending. The keyboard stays down on a phone. Tapping the other answer
|
|
1018
|
+
replaces the first; words you typed under a quote are never replaced. The rule is cautious, and
|
|
1019
|
+
in doubt only Reply is offered: a single sentence that opens like a yes/no question (`Shall I…`,
|
|
1020
|
+
`Do you…`, `Is it…`, `Want me to…`, `Est-ce que…`, `Je lance… ?`, `On…`, `Dois-je…`) or ends
|
|
1021
|
+
with `, OK?` / `, d'accord ?`, with no alternative (`or`, `ou`), no interrogative word (`which`,
|
|
1022
|
+
`how`, `quel`, `comment`…) and no negation.
|
|
1023
|
+
|
|
1024
|
+
A **decision table**, a Markdown table whose rows are numbered questions as a coordinator writes
|
|
1025
|
+
them, gets a panel right under it: **OK to all** refers to the whole table and writes `OK to all`
|
|
1026
|
+
under it (a second tap takes it back), and each row has **Yes**, **No** and `↳`, which refer to
|
|
1027
|
+
the row by its number and write `Yes` or `No` under it, or nothing for an answer in words; a row
|
|
1028
|
+
that asks an open question has `↳` alone. Every answer names the message and the row, even for
|
|
1029
|
+
the last message: the agent may write another one before you send. In French: `OK tout`, `Oui`,
|
|
1030
|
+
`Non`. Here too everything is composed in the field and you send. A table qualifies when it has a
|
|
1031
|
+
number column (a header `#`, `N°`, `No`, `Num`, `ID` or `Q` over short numbers, each once) and a
|
|
1032
|
+
question column, known by its header (`Question`, `Decision`, `Choix`…), by cells that all end
|
|
1033
|
+
with `?`, or by an advice column next to it (`Avis`, `Recommendation`, `Suggestion`…). Any other
|
|
1034
|
+
table is left as it is.
|
|
1035
|
+
|
|
1036
|
+
Above the field, **N questions unanswered** counts the questions of the agent's last message
|
|
1037
|
+
(and the rows of its decision tables) that your draft does not answer yet; tap it to scroll to
|
|
1038
|
+
the first one. A question counts once it is quoted, a row once it is answered, quoted or covered
|
|
1039
|
+
by **OK to all**; when the message asks one thing only, any words you type answer it. The line
|
|
1040
|
+
goes when everything is answered and when you send, and it never shows for earlier messages,
|
|
1041
|
+
while the agent is working, or while it waits on a prompt. It hangs from the top edge of the
|
|
1042
|
+
field, so nothing moves when it comes or goes.
|
|
1043
|
+
|
|
840
1044
|
## Several machines (SSH)
|
|
841
1045
|
|
|
842
1046
|
wherdr also shows the agents of the **SSH machines registered in Herdr** — the ones the Herdr
|
|
@@ -911,15 +1115,33 @@ gets a default workspace, as with any attached client.
|
|
|
911
1115
|
|
|
912
1116
|
## Works great with herdr-projects
|
|
913
1117
|
|
|
914
|
-
[herdr-projects](https://github.com/
|
|
1118
|
+
[herdr-projects](https://github.com/afloury/herdr-projects) is a Herdr plugin that runs a
|
|
915
1119
|
project as one **coordinator** conversation and parallel **threads**, each in its own Git
|
|
916
|
-
worktree. It is optional
|
|
1120
|
+
worktree. It is optional. wherdr works with its **0.2** line, installed from the fork (or with
|
|
1121
|
+
**Install herdr-projects** in **Settings → Plugins → herdr-projects**):
|
|
1122
|
+
|
|
1123
|
+
```sh
|
|
1124
|
+
herdr plugin install afloury/herdr-projects --ref v0.2.36 --yes
|
|
1125
|
+
```
|
|
1126
|
+
|
|
1127
|
+
> **herdr-projects 1.x is not supported yet.** Upstream
|
|
1128
|
+
> ([eliasstravik/herdr-projects](https://github.com/eliasstravik/herdr-projects)) moved to a 1.x
|
|
1129
|
+
> that is a different product (a task board, with no projects, `TASKS.md` or threads), and its
|
|
1130
|
+
> first run moves `~/.herdr-projects` to `~/.herdr-projects-legacy`. Settings says when a machine
|
|
1131
|
+
> has 1.x and gives the command to go back to 0.2. A 0.2 installed from upstream must not run
|
|
1132
|
+
> `herdr-projects update`, which would install 1.x: reinstall it from the fork
|
|
1133
|
+
> (`herdr plugin uninstall herdr-projects && herdr plugin install afloury/herdr-projects --ref v0.2.36 --yes`;
|
|
1134
|
+
> projects stay in `~/.herdr-projects`). The pinned v0.2.36 release downloads a prebuilt binary
|
|
1135
|
+
> for macOS or Linux, on ARM64 or x86_64.
|
|
1136
|
+
|
|
1137
|
+
With it installed, wherdr adds:
|
|
917
1138
|
|
|
918
1139
|
- **Project groups** in the agent list: the coordinator first, its threads indented under it,
|
|
919
1140
|
grouped by repository (`Repo web-shop · 2 worktrees`), with their thread number and state.
|
|
920
1141
|
- **Project panel** next to the coordinator (a side panel on a computer, a tab on a phone). It
|
|
921
1142
|
reads the project's `TASKS.md` and shows the lists it has, always in this order, with the open
|
|
922
|
-
threads live (state, progress, report) and
|
|
1143
|
+
threads live (state, progress, report) and threads marked done under Done (**Tasks** tab; the
|
|
1144
|
+
**Threads**, **Inbox**, **Routines**, **Settings** and **Memory** tabs are described below):
|
|
923
1145
|
|
|
924
1146
|
| List | Meaning | Buttons |
|
|
925
1147
|
| --- | --- | --- |
|
|
@@ -931,7 +1153,7 @@ worktree. It is optional; with it installed, wherdr adds:
|
|
|
931
1153
|
| **Blocked** | Waiting for someone or something external | Unblock, Clarify |
|
|
932
1154
|
| **To do** | To do soon, in your priority order; never launched on its own | Move up / down, Queue it, Launch now, Clarify, Back to backlog |
|
|
933
1155
|
| **Backlog** | Everything else | Launch, Clarify |
|
|
934
|
-
| **Done** |
|
|
1156
|
+
| **Done** | Threads marked done | |
|
|
935
1157
|
|
|
936
1158
|
Every list is **optional**: you and your coordinator pick the ones a project uses (a small
|
|
937
1159
|
project may only need Backlog, In progress and Done); any other `##` list shows in a neutral
|
|
@@ -942,6 +1164,73 @@ worktree. It is optional; with it installed, wherdr adds:
|
|
|
942
1164
|
header shows the thread slots in use (`max_parallel_threads` in `PROJECT.md`) and the next
|
|
943
1165
|
task, plus the machine's global limit when one is set
|
|
944
1166
|
(`2 of 2 thread slots in use on <machine> (all projects)`).
|
|
1167
|
+
- **Threads tab** of the Project panel: every thread of the project, including those marked done.
|
|
1168
|
+
Open threads are grouped as herdr-projects groups them (Your turn, Ready for review, Working…),
|
|
1169
|
+
each with its machine and agent profile; threads marked done stay in their own folded section,
|
|
1170
|
+
shown by pages of 30. One filter covers both (ID, title, machine, profile). A tap opens the
|
|
1171
|
+
thread's record: state, its **Next** list, branch, dates, and these actions:
|
|
1172
|
+
|
|
1173
|
+
| Action | Command | Asks first |
|
|
1174
|
+
| --- | --- | --- |
|
|
1175
|
+
| **Acknowledge** | `thread ack`: you have seen its report | |
|
|
1176
|
+
| **Restart** | `thread restart`: bring back a thread whose pane is gone or whose start failed | |
|
|
1177
|
+
| **Stop** | `thread stop`: Escape in its agent's pane | Yes |
|
|
1178
|
+
| **Mark done** | `thread resolve`: final copy, then its worktree, merged branch and tab are cleaned up (report and library kept) | Yes |
|
|
1179
|
+
|
|
1180
|
+
Open agent, View report and Pull request are there too when they apply. wherdr only runs
|
|
1181
|
+
these `herdr-projects` commands on the coordinator's machine (and reads `thread show --json`);
|
|
1182
|
+
it writes no thread file itself, and herdr-projects has the last word (it refuses to restart a
|
|
1183
|
+
running thread, for instance): its answer is shown as is. With Docker, **Mark done** runs in
|
|
1184
|
+
the container, where the home folder is read-only: a thread of this machine is marked done and
|
|
1185
|
+
its open workspace removed through Herdr, but its merged branch, or a worktree whose workspace
|
|
1186
|
+
was already closed, may stay. herdr-projects lists what it kept, and
|
|
1187
|
+
`herdr-projects sweep <project>` on the host removes it.
|
|
1188
|
+
- **Inbox tab**: the project's unhandled inbox items, what herdr-projects tells the coordinator
|
|
1189
|
+
(a thread's new report, a routine due, a machine out of reach…), oldest first, up to 100. An
|
|
1190
|
+
item about a thread shows the thread's title and opens it. **Done** (✓) marks one item as
|
|
1191
|
+
handled with `herdr-projects inbox done`; a coordinator that has not read it yet will not see
|
|
1192
|
+
it any more. Summaries are shown as plain text.
|
|
1193
|
+
- **Routines tab**: each routine's schedule, whether it is enabled, its kind (prompt only, or a
|
|
1194
|
+
command and its approval) and its last and next run. Read-only: wherdr never approves,
|
|
1195
|
+
switches or runs a routine, and does not expose the plugin's safety settings.
|
|
1196
|
+
- **Settings tab**, read-only: what the project's `PROJECT.md` sets, the keys
|
|
1197
|
+
`herdr-projects set` changes (name, goal, coordinator and thread profiles,
|
|
1198
|
+
`max_parallel_threads`, `auto_resolve_days`, `nudge`, `mute`, repositories). A key the file
|
|
1199
|
+
leaves out shows the plugin's default, marked as such. Safety settings are not shown.
|
|
1200
|
+
- **Memory tab**, read-only: `MEMORY.md` (the index) and the `.md` files of `memory/`, with the
|
|
1201
|
+
title and hook the index gives them; a file the index does not mention is listed by name. A
|
|
1202
|
+
tap opens one, rendered as Markdown. The coordinator writes memory, wherdr never does.
|
|
1203
|
+
|
|
1204
|
+
With six tabs, the bar scrolls sideways on a phone and in a narrow side panel; a fade on its
|
|
1205
|
+
edge says there are more.
|
|
1206
|
+
|
|
1207
|
+
herdr-projects (0.2.34) has no JSON output for the inbox or the routines: wherdr reads the
|
|
1208
|
+
front matter of the project's `inbox/*.md` files, and the tab-separated lines of
|
|
1209
|
+
`herdr-projects routine list`, showing the run texts (`last … · next …`) as printed. No command
|
|
1210
|
+
prints a project's settings or memory either: those two tabs read the files named above.
|
|
1211
|
+
- **Board** (`H`, or the board button above the agent list): every project, thread, task and
|
|
1212
|
+
agent at a glance, in four columns. Agents outside projects show too. Each card opens what it
|
|
1213
|
+
stands for: a project or task opens its Project panel, a thread opens its agent (or its report
|
|
1214
|
+
once closed), an agent opens its conversation. A project card takes the most urgent column of
|
|
1215
|
+
its cards and counts them; Finished shows the 5 most recent threads and done tasks of each
|
|
1216
|
+
project, **Show all** the rest. The filter button in the header hides chosen projects, or the
|
|
1217
|
+
agents outside projects (**Other agents**); the choice is kept on the device, and a new project
|
|
1218
|
+
shows until you hide it.
|
|
1219
|
+
|
|
1220
|
+
| Card | Blocked | Todo | Ongoing | Finished |
|
|
1221
|
+
| --- | --- | --- | --- | --- |
|
|
1222
|
+
| **Task** (its `TASKS.md` list) | Blocked | To test, To decide, To review, In queue, To do, Backlog, other lists | In progress without an open thread | Done, or a checked line |
|
|
1223
|
+
| **Thread** | Its agent is your turn, or *waiting on you* | *Ready for review* | Working, landing, idle | Done |
|
|
1224
|
+
| **Agent** | Your turn | | Working, starting, restarting | Done, ready |
|
|
1225
|
+
|
|
1226
|
+
Moving a **task** card (drag and drop on a computer, **Move to…** everywhere) sends the
|
|
1227
|
+
coordinator the Project panel's message when one says it (**Launch now** from To do or In
|
|
1228
|
+
queue, **Launch** from Backlog, **Unblock** from Blocked, **Tested** from To test, **Reviewed**
|
|
1229
|
+
from To review), otherwise `↳ Mark blocked: …`, `↳ Move to To do: …` or `↳ Mark done: …`. The
|
|
1230
|
+
card shows *Sent* until the coordinator has moved the line; only the allowed columns are
|
|
1231
|
+
offered, and To decide tasks wait for your answer. Thread, agent and project cards follow
|
|
1232
|
+
what they do and do not move. The server reads every project at once
|
|
1233
|
+
(`GET /api/board`); a project on an offline machine keeps its last read, marked as such.
|
|
945
1234
|
- **Max threads per machine**, across all projects: herdr-projects only limits threads per
|
|
946
1235
|
project, so three coordinators could still start a dozen threads on one small machine. Set a
|
|
947
1236
|
limit per machine in **Settings → Plugins → herdr-projects** (empty `—` = no global limit;
|
|
@@ -973,7 +1262,8 @@ worktree. It is optional; with it installed, wherdr adds:
|
|
|
973
1262
|
```markdown
|
|
974
1263
|
- [ ] Stop button on iPhone [b:red(bug)] [b:gray(t-0140)](t-0140) [b:blue(PR #12)](https://github.com/owner/repo/pull/12) (me)
|
|
975
1264
|
```
|
|
976
|
-
- **Settings → Plugins → herdr-projects**: install status per machine
|
|
1265
|
+
- **Settings → Plugins → herdr-projects**: install status per machine (with a warning for an
|
|
1266
|
+
unsupported 1.x, or a 0.2 from upstream whose update would install 1.x), the `TASKS.md` convention,
|
|
977
1267
|
a template, the max threads per machine and the coordinator rules to copy.
|
|
978
1268
|
- **Projects entries** in the menus when the plugin is on the agent's machine: an agent's menu
|
|
979
1269
|
(`…`) and its card's (right click, long press on the phone) offer the Project panel, **New
|
|
@@ -996,17 +1286,57 @@ worktree. It is optional; with it installed, wherdr adds:
|
|
|
996
1286
|
|
|
997
1287
|
The Project panel only works well when the coordinator follows its conventions: which lists
|
|
998
1288
|
mean what, the badges, `(agent → t-NNNN)`, and what to do with each message the buttons send
|
|
999
|
-
(`✓ Tested: …`,
|
|
1289
|
+
(`✓ Tested: …`, `↳ Queue: …`, `↳ Problem: … —` or `↳ Decision: … —` with the answer below it…). They are written once, as an agent skill:
|
|
1000
1290
|
[`skills/wherdr/SKILL.md`](skills/wherdr/SKILL.md).
|
|
1001
1291
|
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1292
|
+
The npm package (also used by Homebrew) and Docker image include the skill from that
|
|
1293
|
+
release. Installation is best effort: a missing agent or an unwritable home never blocks
|
|
1294
|
+
wherdr. It links `~/.claude/skills/wherdr` (or `$CLAUDE_CONFIG_DIR/skills/wherdr`) only
|
|
1295
|
+
when the Claude configuration folder exists, and `~/.agents/skills/wherdr` only when
|
|
1296
|
+
`.agents`, `.codex` or `.omp` exists. Links point to a stable copy in
|
|
1297
|
+
`${WHERDR_DIR:-$HOME/wherdr}/skills/wherdr`. Existing skills from elsewhere are left alone.
|
|
1298
|
+
Relative `WHERDR_DIR` resolves from the working directory; relative `CLAUDE_CONFIG_DIR`
|
|
1299
|
+
resolves from HOME, including when saved in a login service. Unchanged content is not rewritten.
|
|
1300
|
+
A broken link is repaired only when local metadata proves wherdr created it.
|
|
1301
|
+
|
|
1302
|
+
| Install mode | Skill installation and refresh |
|
|
1303
|
+
| --- | --- |
|
|
1304
|
+
| npm / npx / Bun / pnpm | On `wherdr`, `wherdr run`, `wherdr start` or `wherdr service install`; after updating the package, the next start refreshes it. |
|
|
1305
|
+
| Homebrew | On `wherdr` startup, including the Homebrew service; restart the service after `brew upgrade`. |
|
|
1306
|
+
| One-tap update (npm, Homebrew, native plugin) | Restarting wherdr refreshes the skill from the newly installed package; rollback restores the previous copy when that package also bundles the skill. |
|
|
1307
|
+
| Herdr plugin, Node.js | On plugin installation / reinstallation, and on startup from its installed package. |
|
|
1308
|
+
| Herdr plugin, Docker | On plugin installation and Update, extracted from the pulled image on the host. |
|
|
1309
|
+
| One-command installer, Docker | After each pull, including reruns and `WHERDR_MODE=docker`; saves host helpers in `$WHERDR_DIR/skill-installer`. |
|
|
1310
|
+
| Docker by hand | Run the host-side command below after the initial pull and after each image update. |
|
|
1311
|
+
| From source | Use `node bin/wherdr.mjs` after building, or run `sh bin/lib/install-skill.sh` yourself after updating; `npm start` alone does not install the skill. |
|
|
1312
|
+
|
|
1313
|
+
Docker cannot write the host's agent folders through its read-only home mount. From the
|
|
1314
|
+
repository checkout on the **host**, after pulling your image, run:
|
|
1315
|
+
|
|
1316
|
+
```sh
|
|
1317
|
+
sh bin/install-docker-skill.sh ghcr.io/afloury/wherdr:latest
|
|
1318
|
+
```
|
|
1319
|
+
|
|
1320
|
+
Pass your image tag if different. The helper creates a stopped temporary container, copies
|
|
1321
|
+
only `/app/skills/wherdr/SKILL.md` out of it, uses the local host installer, then removes
|
|
1322
|
+
the container. No host home is mounted into it. Repeat this command after each manual Docker update; Docker has no one-tap
|
|
1323
|
+
update in the app. Manual failures (including older images without the skill) return a
|
|
1324
|
+
nonzero status with diagnostics; plugin and one-command installation warn and continue. Without a checkout, use
|
|
1325
|
+
`sh "${WHERDR_DIR:-$HOME/wherdr}/skill-installer/bin/install-docker-skill.sh" <image>` after the one-command install.
|
|
1326
|
+
|
|
1327
|
+
Remove managed links with `sh bin/lib/install-skill.sh uninstall` (or
|
|
1328
|
+
`sh scripts/herdr-plugin.sh skill uninstall` in the plugin folder). Uninstall leaves
|
|
1329
|
+
`~/.local/state/wherdr/skill-disabled`: subsequent starts and updates respect it, even if
|
|
1330
|
+
`WHERDR_DIR` changes. To re-enable, explicitly run `sh bin/lib/install-skill.sh install`
|
|
1331
|
+
or the plugin's `skill install` (or the Docker host helper above). `WHERDR_SKILL=off`
|
|
1332
|
+
disables all installation and refresh, including explicit install; export it for interactive
|
|
1333
|
+
starts or set it when installing the login service to preserve it there.
|
|
1334
|
+
|
|
1335
|
+
Two limitations remain: rollback to an older package without the helper (such as 1.3.2)
|
|
1336
|
+
leaves the failed release's skill in place. With multiple wherdr versions sharing an account,
|
|
1337
|
+
the last one started supplies the skill; there is no version comparison.
|
|
1338
|
+
|
|
1339
|
+
You can also paste **Settings → Plugins → herdr-projects → Copy rules for the coordinator** to your agent.
|
|
1010
1340
|
|
|
1011
1341
|
## Herdr plugins
|
|
1012
1342
|
|
|
@@ -1060,16 +1390,13 @@ container talks to the Herdr server running on the host.
|
|
|
1060
1390
|
allowed"); add it to `HERDR_WEB_ALLOWED_HOSTS`, then restart wherdr. This host check also
|
|
1061
1391
|
applies to WebSockets.
|
|
1062
1392
|
- **Passkey lock** (Settings → Security, recommended): once a passkey is registered, the API,
|
|
1063
|
-
images, photos and WebSockets require an unlocked session (signed HttpOnly cookie).
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
next opening of the app (launch, reload, or back in the foreground), never in the middle of
|
|
1071
|
-
use; the app warns in the last hours. A client that never reopens is cut 12 hours after the
|
|
1072
|
-
deadline. A shorter duration applies to the sessions already open.
|
|
1393
|
+
images, photos and WebSockets require an unlocked session (signed HttpOnly cookie). One rule
|
|
1394
|
+
applies: the duration set in Settings → Security for every device, counted from the last
|
|
1395
|
+
passkey unlock, used or not in between: 1 day, 7 days (default), 30 days, 90 days or 1 year.
|
|
1396
|
+
There is no idle lock. Past it, the device asks for the passkey again at the next opening of
|
|
1397
|
+
the app (launch, reload, or back in the foreground), never in the middle of use; the app warns
|
|
1398
|
+
in the last hours. A client that never reopens is cut 12 hours after the deadline. A changed
|
|
1399
|
+
duration applies to the sessions already open.
|
|
1073
1400
|
|
|
1074
1401
|
A network error or a server restart never locks the app. **Lock all devices** (Settings →
|
|
1075
1402
|
Security, for a lost or stolen device) ends every session, this one included, and keeps the
|
|
@@ -1099,7 +1426,8 @@ See [SECURITY.md](SECURITY.md) to report a vulnerability.
|
|
|
1099
1426
|
`herdr server`). With Docker, check that `HOST_HOME` and `PUID` match your user.
|
|
1100
1427
|
- **No conversation, only the terminal**: the agent was started before the Herdr integration
|
|
1101
1428
|
was installed, or it is not Claude Code / Codex / omp. Install the integration
|
|
1102
|
-
(`herdr integration install claude|codex|omp`) and start a new agent.
|
|
1429
|
+
(`herdr integration install claude|codex|omp`) and start a new agent. When the integration
|
|
1430
|
+
is missing on the agent's machine, the conversation says so with the exact command.
|
|
1103
1431
|
- **Passkeys or notifications unavailable**: the page must be served over HTTPS (or
|
|
1104
1432
|
`localhost`). On iPhone, notifications need the app installed on the home screen.
|
|
1105
1433
|
- **HTTP 403 "This address isn't enabled yet"**: for a tailnet address, run the command the
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Run on the HOST after pulling an image; no container is started, no home mounted.
|
|
3
|
+
# Usage: sh bin/install-docker-skill.sh <image> [refresh|install]
|
|
4
|
+
extract_skill() (
|
|
5
|
+
set -eu
|
|
6
|
+
[ -n "${1:-}" ] || { echo 'usage: install-docker-skill.sh <image> [refresh|install]' >&2; exit 1; }
|
|
7
|
+
[ "${WHERDR_SKILL:-}" != off ] || { echo 'wherdr skill: disabled by WHERDR_SKILL=off'; exit 0; }
|
|
8
|
+
if [ "${2:-install}" != install ] && [ -e "${HOME:-}/.local/state/wherdr/skill-disabled" ]; then exit 0; fi
|
|
9
|
+
helper=$(CDPATH= cd -- "$(dirname "$0")" && pwd -P)/lib/install-skill.sh
|
|
10
|
+
tmp=$(mktemp -d)
|
|
11
|
+
container=
|
|
12
|
+
trap '[ -z "$container" ] || docker rm "$container" >/dev/null 2>&1; rm -rf "$tmp"' EXIT HUP INT TERM
|
|
13
|
+
container=$(docker create -- "$1")
|
|
14
|
+
mkdir -p "$tmp/skills/wherdr"
|
|
15
|
+
# Only data crosses the image boundary. The executed helper is local.
|
|
16
|
+
docker cp "$container:/app/skills/wherdr/SKILL.md" "$tmp/skills/wherdr/SKILL.md"
|
|
17
|
+
sh "$helper" "${2:-install}" "$tmp"
|
|
18
|
+
)
|
|
19
|
+
# Unlike startup, manual and plugin callers see failures and useful diagnostics.
|
|
20
|
+
extract_skill "$@"
|