Repository navigation
Releases: jiangmuran/vibepanel
Release list
v1.31.0
v1.31.0
Two contributions, and a switch for each.
- Typing into Claude Code, Codex or opencode draws the character in the
browser in the same frame as the key, and the keystroke still goes to the
server as before; once the agent's own screen shows the same line the
local copy is removed. On a 300 ms round trip a character used to take
332 ms to appear. Only for those three programs, only when the cursor is
visible at the end of the input, and dropped the moment the server shows
something else. Settings → Panel → Local echo turns it off.
(Meinianda-L, #27) - Switching back to a session no longer loses a full-screen program's
status line for a passive viewer: the reveal repaints without refitting
the grid. (MuDong1989, #38) - The terminal renderer switch is in Settings → Panel, and the stress check
floods the WebGL glyph atlas with 27,000 distinct CJK characters and
compares the result against a fresh page. - A plugin download's final step clears its status in the same step it
lands, so a row is never ready and unpacking at once.
v1.30.1
v1.30.1
- The terminal's renderer is a setting: Settings → Panel → Terminal renderer,
GPU (WebGL) when available or DOM. When the GPU one draws characters wrong
or on top of each other, which it can after thousands of distinct CJK
characters have been through its glyph atlas, switch to DOM and reload. The
switch existed as a stored key with nothing on the page that wrote it.
v1.30.0
v1.30.0
Keys for the panel, and a list of them.
- ⌥↑ and ⌥↓ move between sessions in the order the sidebar shows them, and
⌥1 to ⌥9 jump to the Nth; Ctrl+Shift with an arrow still works. ⌥/ opens
the list of keys, which also lives in Settings under Panel. - ⌥← and ⌥→ stay the terminal's word jump unless a setting gives them to the
panel, where they move between projects. - On a Mac, ⌥Tab and ⌥⇧Tab move between the sidebar, the terminal, the side
panel and the bottom strip, skipping whatever is not on screen. - A key pressed in a text field is the field's; Ctrl together with Alt is
never the panel's, because that is AltGr.
v1.29.3
v1.29.3
- Token usage outlives its transcripts. Claude Code deletes transcripts after
thirty days by default, and the rows read from one were deleted with it, so
the month view, the year heatmap and every total older than a month emptied
themselves out while saying they were complete. A vanished transcript is
retired now: what it counted stays, it is never read again, and one that
comes back at the same path is read as new. - A request is counted once however many transcripts carry it. A resumed
session replays its history into a new file and a forked subagent starts
from its parent's; each copy used to count. About two percent of tokens on
a busy machine. Every transcript is re-read once after the upgrade. - Two tests that swapped an adapter's clock while it was running now do so
under its lock.
v1.29.2
v1.29.2
- Closing a session's attachment no longer waits two seconds. A tmux client
does not exit when its PTY closes, and the panel waited for the SIGKILL
timer every time it detached: deleting a session, deleting a project, a
restart. The client is asked to leave first; the session's process, the
tmux server's child, is untouched. - The output stamp written off the pump is waited for, bounded, before the
database closes at shutdown, so a stop no longer reopens the write-ahead
log of a database on its way out. The two-second detach had been hiding
that. - Test binaries hash passwords at a test's cost; a test pins the production
cost at t=2, m=64 MiB. The httpapi package's tests take about half the
time they did.
v1.29.1
v1.29.1
- Setup asks the address allowlist like every other route. On a panel
started with--allow-fromand no account yet, anybody outside the list
who held the setup token could make the first account. - The allowlist is asked through one helper, and a test walks every route
and fails on one that forgot; the routes it does not apply to are listed
with a reason each. Migrations are named by position and purpose, and the
list is pinned so two branches that each add one collide at merge. - A browser that cannot run the panel is told so, in its language, instead
of a spinner; a bundle that fails to start says so with a reload button. - Pinch zoom works on a phone; a double-tap on a key is still not a zoom.
- No console noise on share pages, plugin frames and admin pages: the
permissions policy names only features browsers know, and every built-in
template declares its icon. make testallows a package thirty minutes on the release runner.
v1.29.0
v1.29.0
The October audit: eight reviewers over the code and the running panel,
seven more over the UI on phones, tablets and three browser engines. This
release is what they found, fixed. Nothing new to configure.
Security
- A cookie write with
Origin: nullis refused, and a body that is not
application/jsonanswers 415. Atext/plainform, redirected with a 307
from a page on a neighbouring port, could create a project as the signed-in
owner. - Go 1.26.9 and golang.org/x/net v0.60.0, for ten reachable net/http
vulnerabilities. - A launch profile's secret variables and the webhook list are sealed under
secrets.keylike every other credential; rows from before are sealed at
the next start. The settings page says so. - Anonymous passkey ceremonies are capped per address. The 飞书 adapter checks
the signature before decrypting and refuses without saying why. A
server.jscall has a bound on what it can allocate. publicAddrpins the IPv4-mapped forms and refuses local-use NAT64.- The CLI trusts
panel.urlonly while the panel holds the data directory's
lock, follows no redirect with the token, and refuses plain http off
loopback unlessVIBEPANEL_CLI_INSECURE=1.
Robustness
- Shutdown gives each step its own budget and ends streams first, so
systemctl restartno longer waits on a viewer. A plugin's event worker
survives a failed read and retires without closing its channel; a
supervised process ends with its whole group, cleans up only its own token,
and a stop during its start keeps it from running; the restart backoff
starts over after a run that lasted. - Transactions begin immediately, so a read-then-write waits instead of
failing. The schema version is read inside each migration step. - An unreadable tmux listing or a refused socket is not an empty server. A
create that fails afternew-sessionkills the tmux session it made. Each
tmux call the poller makes has five seconds. - A WebSocket whose ping goes unanswered is closed. An
exitfor a stream
the viewer already replaced no longer ends the new one. - The chat bridge sweeps a deleted session's rows and month-old pushes.
Performance
- A hook report that changes nothing is not rebroadcast;
last_output_atis
stamped every fifteen seconds rather than every second; an unchanged
transcript path, runtime or title is not rewritten; the poller finishes its
tick past a failed session. The sample cache is checked before/procis
walked. The bundle is served gzip-compressed when the browser accepts it.
The panel on a phone, a tablet and a keyboard
- A tablet (768 to 1099 px) gets the side panel as a sheet over the terminal;
a phone reaches the side panel and the project's terminals from the drawer,
where there was no way to them. A phone in landscape or with its keyboard
up keeps its terminal. - The keyboard can choose a session (rows are focusable; Enter chooses, F2
renames, arrows move) and leave a terminal: Ctrl+Shift+Up/Down switch
sessions, Ctrl+Shift+Left goes to the list. A text field keeps its own
word selection. - Every dialog keeps Tab inside it, closes on Escape only when it is the one
on top, and hands the focus back to what opened it. Enter on a destructive
confirmation presses the focused button, which starts on Cancel. - Informational text and the accent meet 4.5:1 in both themes; selection,
tabs, primary buttons and meters stay visible under forced colours; a tab
is never narrower than its label and a long strip scrolls visibly; the
settings dialog lays out by its own width. - A lost connection says so, in the drawer too, and stops looking live. A
send that did not leave keeps its words in the compose box. An input
method's Enter chooses a candidate instead of submitting. Sign-in refusals,
the page templates' labels and the remaining tooltips are translated. The
phone drawer slides in. - A session that exited non-zero is drawn as crashed on a wall. A session
started from the launch picker is the one shown.
v1.28.0
v1.28.0
A session's own voice: an agent inside a session can mark its state,
describe itself, speak to the phone and the panel, and send a file --
with nothing to configure and a credential that names that one session.
vibepanel me:state working|waiting|done --why "…",title,info set summary|progress|labels,say,notify --choices a,b,send <file>,guide. The environment the panel gave the session is the
whole configuration; the token reaches/api/me/v1and nothing else,
so an agent cannot touch another session, a project or the owner's
settings. The owner does the same to any session withvibepanel session info|say|notify|attach.- What a session says about itself -- a one-line summary, a progress
figure and up to five labels -- is drawn under its row in the sidebar,
with the figure printed beside the bar. sayis a line in the session's messages, pushed to the phone by the
chat rules and a quiet toast on every open page.notifyrings every
page and every paired phone whatever the session's state, with the
choices as buttons; a pressed choice is typed into the session. Six a
minute per session.sendkeeps the file under the session (16 MB, the newest twenty) and
hands it to the phone as a photo or as a card with the download link;
the owner downloads it signed in, with HTML and SVG never rendered on
the panel's origin.vibepanel me guideprints the practice -- mark waiting before asking,
one summary per milestone, say a thing once -- and--writeputs it in
a project's AGENTS.md for the agent to find.
v1.27.0
v1.27.0
The command line operates the running panel: everything the sidebar and
the settings page can do, from a shell, for a panel in a container.
vibepanel status,project(ls, add, rename, pin, unpin, order,
archive, restore, rm),session(ls, new, rename, pin, unpin, state,
restart, kill, send, screen, restore),note,todo,token,audit
andsettings, each through the panel's own API: the same handler the
browser uses, audited, every open tab told, tmux asked by the panel.
Things are named by id, name, an unambiguous prefix or a directory.
--jsonprints the panel's answer for scripts. docs/cli.md is the
reference;vibepanel --helplists the commands.- The CLI mints an API token named
clion first use and keeps it in
<data dir>/cli.token(0600); it is on the settings page's token list
and can be revoked there. The panel writes<data dir>/panel.urlso the
CLI reaches the panel that owns its data directory and never another one
on the default port. Without a running panel, or before the first
account, the subcommands that always worked offline still do. - Two owner routes:
GET /api/sessions/{id}/screenand
POST /api/sessions/{id}/input(audited).
v1.26.2
v1.26.2
A plugin disabled from the shell has its process ended within two seconds.
vibepanel plugin disable,installandremovewrite the database
and exit; the running panel reconciled plugins only from its own
settings page, so a plugin disabled from a shell kept its process until
the panel restarted. The panel now notices a change to the plugins table
within two seconds and reconciles processes, services and frames the way
the settings page does.