Commit Graph
30 Commits
Author SHA1 Message Date
pastilhasandClaude Opus 4.8 1824f53c89 let the pty sidecar decide what shell it runs
officer built the whole PtyInitConfig: it read the owner's SHELL (defaulting to
/bin/zsh), added `-i`, read their HOME, expanded `~` against it, and hardcoded
`host: true`. none of that is a proxy's business — the sidecar is the process that
calls pty.spawn, so it is the one that should know what to spawn and where.

the config now carries only what the bridge actually knows: sessionId, the folder
the panel was opened on, and the client's cols/rows. shell, args, home and cwd
resolution moved into the sidecar. home comes from HOME_DIR ?? HOME, mirroring
data-path.ts:getOwnerHomeDir — terminal was the one host-executing surface reading
process.env.HOME directly, which is identical here and divergent anywhere HOME_DIR
is set to something else.

deleted the bwrap sandbox branch rather than moving it. it was selected by
`config.host`, which officer hardcoded to true, so it never ran — and it expected
`shell` to contain a fully-built bwrap command that nothing on either side ever
built. it could not have worked. a terminal here is the owner's own shell on the
owner's own machine by design (platform/CLAUDE.md), so there is no jail to preserve.
its ensureUserFiles half duplicated api/users/provision.ts:seedShellConfigs, which
is the live seeder of those same templates and stays.

also deleted the 'cwd' handler that turned a message into `cd <path>\r` typed at
the shell. no frontend has ever sent that message — the browser composes its own cd
— so it was unreachable, and synthesizing keystrokes is not something a relay
should do.

the integration test pins SHELL and HOME_DIR now that the sidecar reads them, and
asserts the shell starts in the resolved `~` rather than officer having resolved it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-30 05:02:10 +00:00
pastilhasandClaude Opus 4.8 b92e8dffad keep terminals alive when officer restarts under them
the pty sidecar registered `term.onData` with the socket that happened to be live
when the session was created. officer is a pm2 peer that restarts constantly, and
every restart hands this process a brand new socket, so every pre-existing session
went on writing to a closed one — where sendJson's readyState check dropped it
silently. the shell survived and still accepted input, because input arrives on the
new socket, but nothing ever came back. you typed and the terminal sat there. the
only way out was to close the panel, which orphaned the shell.

sendJson now reads the module-level socket at send time instead of taking one as an
argument, so there is no socket to capture and go stale. that is the whole fix.

the scrollback replay on re-attach becomes its own event, pty:replay -> 'replay'
on the browser socket. it used to arrive as ordinary output, which was fine for a
page load (fresh xterm) but not for a restart: the browser keeps its terminal, so
replaying blind printed a second copy of everything still on screen. marked as
history, Terminal.tsx resets and rebuilds from the sidecar's 50KB buffer instead.
it also stays out of the `output` branch so it cannot re-trigger the command /
initial-input logic that scrapes output for a sentinel.

added an integration test, because this is a reconnect bug and nothing short of an
actual reconnect proves it: it stands up a fake registration socket, runs the real
sidecar against it, echoes into a real shell, kills the socket, rebinds the same
port the way pm2 does, and asserts output still flows. verified it fails against
the old sendJson (times out after 15s waiting for the post-restart echo) and
passes in ~400ms with the fix. it never touches the running officer — the sidecar
dials API_URL, overridden per spawn.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-30 04:59:06 +00:00
brunorezioandClaude Opus 5 044aacf4d5 remove the dead multi-user surface
Officer is single-user: the server owner is the only account, created once by
/auth/bootstrap. Everything that existed to serve additional users was
unreachable, so it is gone rather than left looking like it does something.

Accounts: drop the invite / resend-invite / delete / list-users routes and the
Users settings screen, the inert /auth/signup handler, and the account
verification chain it fed (verify, resend-verification, VerifyScreen, the
UserInvite + VerifyAdmin + VerifyRegistration templates). /auth/verify-token
survives for password resets only, and now requires a reset-password token
rather than accepting any signed JWT.

Roles: drop the users.role column and the four-value USER_ROLES enum. The
permissions table granted every role identical methods, and every
role === 'Super Admin' check was permanently true. The JWT no longer carries a
role claim.

Sandbox: remove sidecar/sandbox.ts and its five call sites. bwrap was selected
only for non-Super-Admin users, so it never ran. It was also not a usable agent
jail as written — --share-net, the project root (with .env) bound read-only,
and runuser dropping to the server's own uid. Rebuilding it for agent
containment would be a different construction, and git history keeps this one.

getHomeDir keeps its DATA_PATH meaning; the new getOwnerHomeDir resolves the
owner's real login home, which is what terminals, chats and task runs use.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 23:30:20 +01:00
pastilhasandClaude Opus 4.6 3eb4bd820f show member username in terminal prompt instead of email
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 08:05:49 +00:00
pastilhasandClaude Opus 4.6 9578110e8b shared bwrap sandbox, skip for super admin, extend to pi and terminals
- extract buildSandboxPrefix/buildRunuserSuffix into shared sandbox.ts
- super admin bypasses bwrap for full host access (claude, pi, terminal)
- member pi processes now use bwrap instead of sudo -u
- member terminals now use bwrap instead of sudo -u
- mount /run for systemd-resolved DNS inside sandbox
- pass role through claude spawn params and channel types

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 00:06:44 +00:00
pastilhasandClaude Opus 4.6 a0d9ea63f9 sidecar self-registration: sidecars connect to API server instead of vice versa
Flips the connection model so sidecars register themselves with the API
server via WebSocket at /api/sidecar/register, enabling dynamic discovery,
location independence, and automatic reconnection from either side.

- Add registration protocol types and PTY command/event types
- Create sidecar-registry.ts (replaces sidecar-client.ts) as passive registry
- Create sidecar connector (connect.ts) with exponential backoff reconnect
- Convert process sidecar from WS server to WS client
- Convert PTY sidecar from WS server to multiplexed WS client
- Simplify terminal bridge to thin adapter using registry
- Add PTY sidecar as PM2-managed process
- Update all consumer imports

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 08:48:19 +00:00
pastilhas ef13f96d36 fix(pi): add snap node compatibility diagnostics and documentation
- Added detailed error logging to detect snap node compatibility issues
- When Pi process exits with code 1, log helpful diagnostic info including node path
- Add hint to check for snap node and reinstall via apt/nvm
- Create SNAP_NODE_COMPATIBILITY.md with full troubleshooting guide
- Document root cause: snap node has file descriptor incompatibility with Bun.spawn stdin pipes
- Provide clear installation instructions for NodeSource and nvm alternatives
2026-03-04 01:45:36 +00:00
pastilhasandClaude Opus 4.6 0068244356 claude-code as channel model, container trust/permissions fixes, terminal cwd fix
- add claude-code as virtual model in channel messaging (telegram/discord/whatsapp)
- new send-claude-code.ts: docker exec claude -p with session resumption
- route claude-code model in sendAndAwait before Pi pipeline
- append claude-code to listPiModels output
- fix container .claude mount (rw for sub-mounts), hooks format (matcher-based)
- pre-seed hasTrustDialogAccepted and bypassPermissions in container settings
- git init in entrypoint to skip workspace trust prompt
- fix ~/~ double-tilde in CommandTerminalWrapper cwd resolution
- remove --continue from claude-code panel command

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 20:00:45 +00:00
pastilhasandClaude Opus 4.6 927267e041 workspaces to dashboards, imap email sync, ffmpeg tool, tts fix, file browser refresh, automation sidebar reorder
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 20:00:45 +00:00
pastilhasandClaude Opus 4.6 30f06e91e4 cliamp music player integration with browser audio streaming
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 17:23:52 +00:00
pastilhasandClaude Opus 4.6 c443fe0fe2 pi session context persistence, fix new session button, add clear all sessions
- handle pi process death by nulling piProcess ref so next message respawns
- replay conversation history on respawn via --session flag
- fix user message JSONL format to array for pi compatibility
- fix container sessions mount to match storage path
- fix ChatPanelWrapper: key on inner component so usePiChat resets on new session
- add bulk delete sessions endpoint and clear all button in chat header

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 00:04:14 +00:00
pastilhasandClaude Opus 4.6 13cfeac384 chat session context scoping, fix sandboxed pi config mounts, dedupe zai/opencode providers
- Add context/contextId fields to session types, storage, and index
- Filter sessions by context (project, workspace, or default chat)
- Pass context through websocket, REST API, and frontend hooks
- Mount ~/.pi/agent into sandboxed containers for auth + writable sessions
- Remove PI_CODING_AGENT_DIR override so container pi uses ~/.pi/agent
- Deduplicate zai/opencode models (same service, show as opencode)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 22:35:02 +00:00
pastilhasandClaude Opus 4.6 11845fbae5 single source of truth for pi config via ~/.pi/agent
auth.json stores api keys, models.json stores local providers directly.
no more copies, sync layers, or per-user config generation.
docker containers mount pi config read-only.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:42:30 +00:00
pastilhasandClaude Opus 4.6 500a70910e migration to postgres
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:42:59 +00:00
pastilhas 466dc3adda sidecar network host 2026-02-26 03:32:04 +00:00
pastilhas 42abb97d7b email syncyng 2026-02-26 01:39:38 +00:00
pastilhas 084dd22d57 fix sidecar issue, node 22 2026-02-25 04:50:16 +00:00
pastilhas e36908cb0b opengraph stuff 2026-02-24 21:47:36 +00:00
pastilhas 05f0d0e8f7 resources 2026-02-24 16:44:22 +00:00
pastilhas d6ffe43a11 tools and skills, etc in the containers 2026-02-24 01:24:28 +00:00
pastilhas 2779fe22c6 file based auth 2026-02-23 09:58:08 +00:00
pastilhas 9acef6cf6c copy path and chat about file/folder 2026-02-23 05:15:13 +00:00
pastilhas 97da2e2736 fixed members login and permissions issues 2026-02-23 00:57:34 +00:00
pastilhas 09cff3f763 Pi running inside the docker containers 2026-02-22 22:21:47 +00:00
pastilhas ab03b175e7 Projects 2026-02-22 01:50:15 +00:00
pastilhas 25f5f74b1b no idea 2026-02-20 18:25:33 +00:00
pastilhas 7c0b11c5a5 sudo commands through ephemeral terminal 2026-02-19 21:43:37 +00:00
pastilhas 4733a972dd Workspaces and Terminals 2026-02-19 18:01:08 +00:00
pastilhas 9870fa7ae8 /workspaces refactor 2026-02-19 16:07:00 +00:00
pastilhas 0746844d6f extracted terminal to a widget 2026-02-17 18:46:18 +00:00