The file browser's clipboard moves to the server, files can be dragged between windows, and plugins reach further into the file browser. No schema change and no dependency change — checked rather than assumed, and the plan records the two commands that prove it. The clipboard needs no migration: it is a key in `user_state`, a JSONB column that already exists, written through the same route the dock and the view mode already use. Eleven commits since 2026.08.29.04, one of which is that release's report. Surveyed all seven target hosts while writing the plan. Every one answered and every one is clean. `fofos` sits ahead of the previous tag and behind this one — it has been hand-pulled all day while the fofos plugin work was written against it — and that commit is an ancestor of this tag, so its fast-forward is ordinary. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
5.5 KiB
2026.08.30.01 — the file browser's clipboard moves to the server, and plugins reach further in
No schema change and no dependency change. Verified rather than assumed:
git diff --name-only deploy/2026.08.29.04..deploy/2026.08.30.01 | grep -iE 'schema|/db/|databases' # nothing
git diff --name-only deploy/2026.08.29.04..deploy/2026.08.30.01 -- package.json bun.lock # nothing
So no bun db:push and no bun install step exists in this plan, and neither should be improvised.
Eleven commits; one of them is the previous release's report.
The clipboard is per-user state and it needs no migration — it is a key in user_state, a JSONB column
that already exists, written by the same PATCH /user/state the dock and the view mode already use.
What is in it
- The file browser's clipboard lives on the server. It was
useState, so it existed in one tab and died with it: copying in one window and pasting in another did nothing, and a reload lost a pending cut with no sign that it had. It is now a key inuser_state, per user rather than per browser — cutting on a desktop and pasting on a phone is one gesture across two screens. - Files can be dragged between windows. A custom MIME type on the DataTransfer survives between tabs and windows of the same browser, so a row can be dragged from one Officer window into a folder in another. It cannot cross different browsers or exchange with Finder; that is a property of the platform, not a gap to report.
- A window re-reads its folder and the clipboard when it comes forward, so the window a file was cut from stops listing it. And re-reading no longer blanks the list — the spinner is now for a folder that cannot yet be shown, so a refresh after a paste or a delete leaves the rows and the scroll position where they were.
- A plugin can put an action in the file browser's context menu, and gets an authenticated client to use in it. Three commits, because the first two shipped the registration without forwarding it into the menu, and then without a way to call the API.
- The file browser can be a file picker —
onPickFileturns opening a file into handing it back, rather than a second component that reimplements a listing, a breadcrumb and a sort. - A plugin can hand the agent its own MCP server, declared in its manifest.
- A plugin may not bring its own React.
npmDependenciesstrips and then deletesreactandreact-domafter install: a plugin's peer copy landing inplugins/node_modulesgives the app two Reacts and every hook throws.
Nothing here changes behaviour anyone has to be warned about
No route is removed, no permission changes, nothing 404s that did not before. The clipboard is additive:
a browser that has never set one reads null and behaves exactly as before.
Every host — the commands
The standard steps in prompts/deploy-commander.md are the whole rollout (dirty check,
git fetch origin --tags, git merge --ff-only deploy/2026.08.30.01, bun run plugins:update), plus:
pm2 restart officer
officer only — plugins:update has already restarted the plugin sidecars.
Verify it came back
pm2 jlist: officer online and restart_time moved, then /api/health on the host's own port
(9010 on macbookpro and production-pertento-bridge, 9000 elsewhere). 200 or 401 are healthy.
And check the file browser still lists
This release touched the file browser heavily — the listing loader, the clipboard and the row markup — so one call per host:
bun -e "
const { sign } = await import('./src/servers/jwt');
const t = await sign({ id: 1, email: '<the owner on this host>' }, '2m');
const r = await fetch('http://127.0.0.1:<PORT>/api/file-browser/ls?root=home&path=/', { headers: { Authorization: 'Bearer ' + t } });
const b = await r.json(); console.log(r.status, (b.entries ?? []).length + ' entries');
process.exit(0)"
A 200 with a plausible count. A 500 here is a failed host — report it and move on.
Per host
Surveyed 2026-08-30 while writing this. Every host answered, and every one is clean
(--untracked-files=no).
| Host | HEAD at survey | Note |
|---|---|---|
officer-dev |
— | SKIP ENTIRELY. The rollout runs here and it is already at this code. Name it as skipped. |
alpha |
e9b71522 |
Exactly on the previous tag. Ordinary target. |
fofos |
601849be |
Ahead of the previous tag, behind this one. It has been hand-pulled all day while the fofos plugin work was written against it. That commit is an ancestor of this tag, so the fast-forward is ordinary — it simply travels fewer commits. It is also the only host with av-club and fofos-admin installed, so plugins:update moves more here than anywhere else. |
macbookpro |
e9b71522 |
macOS, port 9010, a laptop. Answered the survey; if it has slept since, unreachable is a SKIP with a note, not a failure. |
macbruno |
e9b71522 |
macOS, login brunoalcadapadezmonteirodaconceicao. |
production-pertento-bridge |
e9b71522 |
Port 9010. |
edge-pertento-bridge |
e9b71522 |
Ordinary target. |
deadpool-rezio-bridge |
e9b71522 |
Login br, checkout /home/br/officerdev/platform. |
What "done" looks like
Per host: HEAD before and after, plugins:update result, officer back online with a moved
restart_time, and the ls check's output.
Nothing in this release needs a database query, a backup or an install. If you find yourself running one, stop — the plan is wrong, and that is worth reporting rather than working around.