Remote clients (docs/plans/remote-clients/README.md, B1–B3 for the Claude pool):
- server/hub/ holds the hub-only code (devices, remote sessions, upload ingest,
LAN gateway), required only in server mode; hub-boundary.test.js keeps local
code from importing it.
- A local install enrolls with `agenthub remote login` or Settings → AI tools →
Company hub; the "Company account" AI Proxy (reserved name agenthub.company)
sends a session through the hub's gateway, which adds a pool account's token —
no credential reaches the machine. Only those sessions are uploaded, hourly
and at their end; secret-shaped strings are redacted on the client.
- Gateway refuses: unknown device (401), a message without a session id, an
unregistered session under AGENTHUB_REMOTE_GATE=block, a user over quota
(EQUOTA), a purged session (410). Device tokens 90 days, conversations 30.
- New alert rule type remote_unmonitored: a company-account session its device
never registered; a late registration clears the flag instead.
- The hub imports a session once per upload round (chunks carry `more`),
not once per chunk.
Artifacts:
- Share an artifact with chosen people (artifact_shares, PATCH sharedWith,
GET /api/artifacts/people) besides everyone; a "Shared with you" tab.
Only the owner or an admin sees or edits who it is shared with; audited.
- Folders: each account's own arrangement (agenthub.artifacts.folders pref).
- A claude.ai page keeps a copy viewable without the publishing account: its
HTML file (and supporting files) snapshotted at publish, or the copy Claude
saves for a Doc / Slides / Design in artifacts-export/ (a synchronous
PostToolUse hint hook, scripts/artifact-export-hint.js, admin switch),
attached to the page at Stop. Viewed in HtmlFrame's sandbox, Markdown, or
pdf.js (pdfjs-dist 6.4.299, legacy build, loaded only for a PDF).
Fixes:
- tmux: a cached /proc/<pid>/exe of an exited server falls back to PATH's
tmux (stop the last pane, start again within 10 s failed with ENOENT).
- shelves: a shelf restores beside changes in other files.
- chat: a finished reply ends the turn even with no hook at all.
- Settings → AI tools: profile list display tweaks.
Reverts 21a042d, 0d3e92c, 0016b6a, c797e98, 03ebea1. Keeps the pet's
own-sessions scope, status bar mine=1, scroll speed and the health hover card.
The chat_* tables and <data dir>/chat/ files are left in place (unused).
Server mode: a rail beside the pet's chat lists the pet, then the user's
direct chats (one per pair) and groups with unread counts, and + for a new
chat. A room shows its messages (group senders named), loads older pages,
and sends text, pasted / dropped / attached files (<= 10 x 25 MB; images
inline). A group's creator renames it and adds or removes people; anyone may
leave. A blue dot on the pet counts unread messages.
Only a room's members read or write it, an admin included (roomFor → 404).
Files are stored under server-made names in <data dir>/chat/<room>/ and
served to members only under a sandbox CSP + nosniff. chat_message /
chat_room frames reach exactly the ids in `to` (scope.exactAudience).
New tables chat_rooms / chat_members / chat_messages / chat_files (additive).
Server: git-rewrite.js (rebase + continue/skip/abort, rebase-interactive with
no editor, reset soft/mixed/keep/hard, undo-rewrite, force-push with lease,
remote-branch-delete, remote add/rename/remove) and git-conflicts.js
(conflict stages read + conflict-save, reflog), dispatched from runGitAction;
operationInProgress now reports a rebase and only ALLOWED_WHILE_REBASING
writes run during one. New reads: /git/conflict, /git/reflog, /git/remotes,
/git/rewrite-plan. Client: History tools menu, MergeEditor, ReflogView,
RebaseDialog, InteractiveRebase, ResetDialog, ForcePushDialog, RemotesDialog,
rebase banner Skip. CLAUDE.md git-writes rule rewritten for the new actions.
GET /git/refs lists local branches (upstream, ahead/behind, last commit,
merged, held by a worktree, protected), remote branches grouped by remote
and tags (target, annotated message/tagger/date). New writes in
server/lib/git-refs.js, dispatched from git-ops.js: branch-rename,
branch-upstream (set/unset), tag-create (light/annotated), tag-delete
(confirm), tag-push (one tag to origin, no --tags, no force), and
branch-create with a looked-up from + switch on a clean tree. Every ref is
looked up, never passed through; repo-wide writes are repo-root only
(ESUBDIR) and refused during any operation (EMERGING).
Client: git/BranchManager + TagManager dialog opened from the git bar's
tags icon, en+vi (gitRefs namespace), keyboard navigable.
# Conflicts:
# CLAUDE.md
# client/src/components/lanes/LaneGitBar.tsx
# docs/API.md
# server/__tests__/lanes-api.test.js
# server/routes/lanes.js
- openapi-extra/run.js describes tmux pane runs only: the removed
POST /api/run/{id}/message and stream-json run_stream/run_input_ack are gone.
- 108 operations added to OpenAPI (lanes, run, settings, reports, cc-config,
pets, ai-proxies, tool-profiles, ai-tools, snapshots, locks, ...);
openapi.yaml regenerated.
- docs/API.md: 74 routes added, 4 endpoints that no longer exist removed.
- Role is `developer`, not `member` (CLI.md, DATABASE.md, OVERVIEW.md);
`agenthub update` -> `update-check`; help lists `server install-system|tools`
and `users provision`; ARCHITECTURE.md's stale paths and names fixed.
- cc-config/codex-config writes carry sameOriginGuard (an MCP server or plugin
is code Claude runs later), with a test; `command -v` takes its name as $1.
Whole tree from parallel sessions, plus the version bump:
- Clone: a queue with live progress (Add workspace and extra folders),
clones run under nice/ionice so the machine stays responsive.
- Settings → AI tools → Session defaults: a new session's default
permission mode / bypass per account.
- Chat lists the background subagents that have not reported back yet.
- A file pasted or dropped into a claude pane goes in as an @ mention.
- Changes panel: say why amend/undo is refused on a pushed commit.
- openapi.yaml regenerated (Artifacts, Host, resumeById).
- File Explorer (Files in the sidebar, /files; also from a workspace's Files
tab, portalled so no panel clips it), laid out like GNOME Files: places
(Home, workspaces, Trash), Back/Forward/Up, path bar, search, icon grid with
image thumbnails or list, labelled New/Upload, selection action bar, hidden
files behind Ctrl+H, right-click menus and the usual keys.
Make, rename, move, copy (within a workspace, between workspaces, home ↔
workspace), delete into a per-account trash restorable for 7 days, streamed
upload of files and whole folders (≤ 500 MB a batch, Replace / Keep both /
Skip on a taken name), download a file or a zip of anything.
server/lib/file-explorer.js, /api/lanes/:id/fs/*, /api/homes/:who/fs/*.
- The user's home: every dot entry at its top stays hidden and refused
(also via a symlink, download, zip or as a copy source); an admin may view
other users' homes read-only, audited.
- write-as learns move/copy (re-run `sudo agenthub server install-system`).
- Hardening: a write to a workspace re-checks its owner by the live role;
S3 keeps its server.conf if the file stops reading and a tmux call never
falls back to the host's server; the AI Proxy gateway marks what it relays
and the dashboard refuses it; a NUL in a pane's argv/env is refused.
- OpenAPI for the new routes (server/openapi-extra/files.js); docs (API,
SERVER-MODE, CLAUDE.md) updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Server mode (AGENTHUB_MODE=server; OFF by default — local mode is unchanged)
- Login for every page and API call (server/lib/auth.js, routes/auth.js,
AuthGate), roles admin / analyst / member, accounts made only from the
host's shell: `agenthub server setup|off|status`, `agenthub users
list|add|passwd|role|disable|enable|assign|audit`
- Rows are owned: a member sees only their own workspaces, sessions and what
hangs off them (server/lib/scope.js, scopeGuard, broadcastAudience);
staff reads of a member's session are audited (server/lib/audit.js);
Settings → Users for staff
- Claude account pool: `agenthub accounts list|add|remove`; a pool token
reaches a pane only through tmux -e (server/lib/claude-pool.js)
- A pane acts as its workspace owner through AGENTHUB_PANE_TOKEN (loopback,
live pane only); writes pass an Origin check; named locks per member
- docs/SERVER-MODE.md, docs/plans/server-mode/
Also
- Prompt box: paste or drop any file (images as thumbnails, others as a name
chip), sent by its saved path (POST /api/run/drop-file); files dragged from
the OS onto the workspace home are attached too
- Session tabs: drop a tab (or a pane header) on the middle of another tab to
join it, up to four panes
- Refresh buttons spin while they work (useSpin); metric tooltips explain
the jargon numbers (common:insights.help.*)
- Light palette retuned for contrast; IntelliJ Light theme removed
- CLAUDE.md sync marker trimmed; its history moved to docs/CLAUDE-SYNC-LOG.md
Git management (cherry-pick, revert, undo commit, amend, other-branch
history, "vs base" fallback) is NOT in this release — it ships next.
Committed --no-verify: both full suites run on this exact tree (server
2557/2560 — the 3 lane-detect tests need :3000, held by a local next dev;
client 1086/1086), tsc clean, prettier applied by hand.
Settings → Dashboard gains an AI Tools section (installed tools with
Enabled/Disabled and Set default, available ones with a homepage link,
Refresh). useAiTools shares one catalog copy across the app and replaces
LANE_TOOL_LABEL. The Add-lane modal picks Default (<tool>) or Other…; the
router row reads Native (<tool>) and disables AI Router profiles for tools
that cannot use one. The run form gives catalog tools resume and a red
per-run Bypass permissions switch (Codex too). Claude Code / Codex settings
tabs hide while that tool is disabled. The Workspace probes each lane tool's
CLI fresh.
Docs: CLAUDE.md tool/bypass rule, AGENTS.md, LANES.md, API.md, CLI.md,
server/README.md, OpenAPI fragment + regenerated openapi.yaml.
Internal SmartGift build of a Claude Code monitoring dashboard.
Lanes: a durable unit of parallel agent work, one per working directory,
tracked across session restarts. Managed lanes are git worktrees the
dashboard provisions and can reset or remove behind a three-check destroy
guard and a counted preflight; adopted lanes are directories you already
own and are never destroyable.
Pipelines: a lane moves through pipeline stages. A stage the agent declares
with evidence renders green; a stage inferred from the tool-event stream
renders dashed amber and never counts as done. Detection is forward-only
within a 30-minute window, and never writes the declared stage.
Workspace: one page at /run with a lane grid, the selected lane's pipeline,
and a full Claude console behind a disclosure.