Commit Graph
307 Commits
Author SHA1 Message Date
pastilhasandClaude Opus 4.8 56531aedb7 doc: header running + queued job indicators (3d)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 14:42:30 +00:00
pastilhasandClaude Opus 4.8 ae361d2a2f tasks: inline flag (quick tasks stay in the modal) plumbed through parser + endpoints
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 14:33:08 +00:00
pastilhasandClaude Opus 4.8 46dc6ce507 jobs: script-job terminal view at /jobs/:id (phase 3a)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 14:04:08 +00:00
pastilhasandClaude Opus 4.8 6d7d928806 jobs: queue scheduler + REST job API (phase 1c + 2)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 13:58:42 +00:00
pastilhasandClaude Opus 4.8 234a24ddaf jobs: run script tasks as background jobs via executeScript (phase 1b)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 13:42:57 +00:00
pastilhasandClaude Opus 4.8 843580afff jobs: add mode and exit_code columns (phase 1a)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 13:38:05 +00:00
pastilhasandClaude Opus 4.8 4a5fa89185 add jobs-unification design doc
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 13:35:45 +00:00
pastilhasandClaude Opus 4.8 71dfd394c3 subtitles default to all-unchecked; connect the keep-checkbox label
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 13:35:45 +00:00
pastilhasandClaude Opus 4.8 372fbf11ab per-group folder config: general audio/subtitle/rename pickers via group_config
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 12:46:53 +00:00
pastilhasandClaude Opus 4.8 a0cfb1c526 per-group track config: probe bitrate, per-file track map, folder multi-picker
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 12:11:23 +00:00
pastilhasandClaude Opus 4.8 17b7ca8b72 gate the folder keep-all escape hatch behind config.folderKeepAll
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 11:40:05 +00:00
pastilhasandClaude Opus 4.8 fd2c82da84 log token revoke as a security event
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 00:59:19 +00:00
pastilhasandClaude Opus 4.8 c345bd40ae skip pi install when the binary is already present
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 00:48:44 +00:00
pastilhasandClaude Opus 4.8 fcee091b53 add token revoke and panic lockdown endpoints with security logging
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 00:48:44 +00:00
pastilhasandClaude Opus 4.8 b96b23d92b auth: add POST /auth/lockdown to trigger the distress lockdown
exposes the duress lockdown as an endpoint (needs the distress password in the
body, rate-limited) so it can be tripped from a shortcut/webhook, not only by
typing the distress password at the login form.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 00:22:48 +00:00
pastilhasandClaude Opus 4.8 cf2962fd67 auth: distress-password lockdown + explicit token-revoke endpoint
Add a duress password (DISTRESS_PASSWORD env): entering it at login trips an
in-memory full lockdown — all new logins (password + passkey) and every existing
session are refused until the server is restarted, and the login itself returns a
normal "invalid credentials" so it gives nothing away. Also add
POST /api/auth/blacklist-token as a clearly-named alias for revoking the current
JWT (same effect as signout).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 00:06:42 +00:00
pastilhasandClaude Opus 4.8 f03bf733c8 origin validation: allowlist the Expo app origin via env
APP_ORIGINS now includes EXPO_PUBLIC_CLIENT_ORIGIN when set, so the mobile app's
officer:// custom-scheme origin passes origin validation without weakening it for
anyone else. The origin (with its embedded token) lives in .env, not the repo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 23:54:00 +00:00
pastilhasandClaude Opus 4.8 b3d0de3dcb file browser: download videos via ReClip as a background job
/download-video now delegates to the ReClip service (its own yt-dlp) and runs as
a background job: POST returns a jobId immediately and the client polls
GET /download-video/:jobId, so a large download no longer holds one long request
open (which was 504-ing behind the reverse proxy). the finished file is streamed
into the user's folder with a title-based name.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 22:09:43 +00:00
pastilhasandClaude Opus 4.8 6ce75db150 task runner: keepalive ping so long silent tasks don't get killed
a script task that goes silent for a while (e.g. ffmpeg's faststart pass rewrites
a huge file for minutes with no output) would hit Bun's default 120s websocket
idle timeout → close(ws) → killTree killed the task mid-run, corrupting the
output. now the executor pings the socket every 30s while a task runs, resetting
the idle timer.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 22:09:43 +00:00
pastilhasandClaude Opus 4.8 a82ce9ecb0 drop inherited architecture docs that no longer match the code
AUTOMATION_CONTEXT.md and SIDECAR.md described the multi-tenant scope
model, the seed/ tree, the marketplace, and a single sidecar owning the
queue — all superseded. Fix the stale doc pointers in opencode.json and
CLAUDE.md, and point at TODO.md as the source of truth on direction.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 20:25:44 +01:00
pastilhasandClaude Opus 4.8 23b7df5fa9 task runner: kill the whole process tree on Stop
proc.kill() only signalled the direct child (bash), leaving a running ffmpeg
grandchild orphaned and still encoding. now killTree() walks /proc, SIGTERMs the
whole subtree (bash + ffmpeg), then SIGKILLs any straggler after 2s.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 15:05:23 +00:00
pastilhasandClaude Opus 4.8 e68c8edc23 task runner: "convert all, keep every track" option for mixed-layout folders
when a folder has mixed audio/subtitle layouts, the mismatch banner now offers a
toggle: convert the matching group (pick tracks, skip the rest) OR convert every
video keeping all audio + all subtitles (no picking, nothing skipped). the second
mode hides the pickers and clears the track-selection inputs so run.sh keeps
everything. only shown for tasks with track pickers (Convert Video).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 13:16:11 +00:00
pastilhasandClaude Opus 4.8 068cbfe32b file browser: run a task on a multi-selection
selecting several files/folders and running a task now runs it on the whole
selection instead of just the right-clicked item. reuses the folder + include
mechanism: the run targets the current folder scoped to the selected files
(and everything under selected folders). track-picker tasks scope their probe
to the selection too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 08:38:39 +00:00
pastilhasandClaude Opus 4.8 821e7ab6c4 video player: fill the frame in fullscreen
the video used max-w/max-h so a low-res source stayed at native size surrounded
by black. switch to w-full h-full object-contain so it scales up to fill the
player (windowed and fullscreen) while preserving aspect ratio.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 07:13:11 +00:00
pastilhasandClaude Opus 4.8 a2ca5b0fcd task runner: subtitle_edit input type for the subtitle editor
renders each subtitle as a keep checkbox + editable label field, seeded from the
file's current tracks. reuses the existing probe / folder-grouping / include
plumbing, so it works on a single file or a whole season.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 06:04:20 +00:00
pastilhasandClaude Opus 4.8 ae1ccdec33 task runner: batch track selection for folders
converting a folder now recursively probes every video and groups episodes by
track layout (audio language+channels, subtitle language). the pickers are
driven off the largest matching group; episodes with a different layout are
listed as skipped and converted separately. adds a /probe-folder endpoint and
passes the majority file list to run.sh as INPUT_INCLUDE.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 05:21:01 +00:00
pastilhasandClaude Opus 4.8 0f2b71562a task runner: probe video files and let you pick which audio/subtitle tracks to keep
convert video's task modal now probes a single file on open, lists its audio
and subtitle tracks as inline checkboxes, and passes the selection to the
script. audio defaults to all kept, subtitles to none; a "none" sentinel keeps
empty (folder mode) meaning keep-all.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 04:47:09 +00:00
pastilhasandClaude Opus 4.8 8c9bb9a68e video player: server-side audio track selector
Add /file-browser/audio-tracks (list) and raw?audio=N (serve the video with
a chosen audio track via a cached -c copy remux, byte-range seekable). The
player shows an always-visible selector outside the controls; switching
reloads the source and restores the playhead. Works in Chromium, which
doesn't expose the audioTracks API.

Temp remux file keeps the real extension (a .tmp suffix breaks ffmpeg's
muxer selection); concurrent requests for a track share one remux.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 04:04:47 +00:00
pastilhasandClaude Opus 4.8 921413ca4d lower the task-completion chime volume to a quarter
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 02:48:01 +00:00
pastilhasandClaude Opus 4.8 06bd8a5821 video player: subtitle track support with a selector
Add /file-browser/subtitles (list text subtitle tracks) and /subtitle-vtt
(extract one as WebVTT on demand); the VideoRenderer fetches the list,
renders <track> elements, and shows a CC selector to switch/turn off subs.
Track labels prefer title, then handler_name (mp4), then a real language,
falling back to Track N — so untagged tracks aren't shown as "und".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 02:38:52 +00:00
pastilhasandClaude Opus 4.8 b9eb78c919 add header rescan button to apply officer-items changes without restart
New POST /api/rescan re-runs the boot item setup (ensureItemDirs +
ensureToolLoader) and returns live item counts; the header button calls it
and invalidates the item query caches so the UI refetches from disk.

Also fix ensure-tool-loader to write into OFFICER_ITEMS_DIR/extensions (the
runtime read path) instead of the now-unread DATA_PATH/extensions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 01:31:51 +00:00
pastilhasandClaude Opus 4.8 86a547b216 comment out the web inspector and bug report header buttons
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 01:23:23 +00:00
pastilhasandClaude Opus 4.8 f3492512ba unify agent items into a flat file-based store, drop the marketplace
Replace the marketplace service dependency and the native/global/user
scope tiers with a single external directory ($OFFICER_ITEMS_DIR) holding
skills, tools, tasks, processes and extensions as plain files.

- tasks move from Postgres to TASK.md files (new file-backed task layer);
  task editing now works, which the DB path never supported
- skills/tools/processes collapse into one shared file router (single dir)
- remove the marketplace client (sync-marketplace/sync-version) and the
  boot-time sync; pi-bridge/pi-manager/sandbox point at the flat store
- drop the dead tasks + vestigial skills/tools/processes/extensions +
  item_chats tables (migration 0004)
- one-time migration script exports DB tasks and consolidates disk items

Migration verified: all 6 tasks round-trip through the runtime parser
identically to their DB rows (pipeline steps, triggers, script impls and
agentic bodies all intact).

NOTE: not yet functionally tested end-to-end — every item (each task mode,
tool, skill, extension) still needs to be run/exercised in the app before
this is trusted. To be done manually.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 00:39:17 +00:00
pastilhasandClaude Opus 4.8 5fd3d4faac file browser opens at home instead of restoring the last path
Navigation is now session-local state that always starts at home. The
unscoped browser still mirrors its folder into files/currentPath so the
Create Dashboard flow keeps defaulting a new dashboard's cwd to it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 23:46:15 +00:00
pastilhasandClaude Opus 4.8 82d0e9afd6 remove ffmpeg video transcode, back to native-only playback
Drop the /transcode (and dead /transcode-audio) routes and the frontend
mkv/avi transcode wiring. Only browser-native formats (mp4, webm, mov,
m4v, ogv) are classified as video now; other containers fall through to
the generic file view.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 23:37:14 +00:00
pastilhasandClaude Opus 4.8 510254cbd4 note the x11vnc orphan/duplicate risk in TODO
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 19:17:00 +00:00
pastilhasandClaude Opus 4.8 1ed12cd3ba resolve a relative task cwd against the user's home before spawning
the file browser sends msg.cwd relative to the user's home and it went straight to
Bun.spawn, which resolves it against the server's cwd. when that directory does not
exist posix_spawn reports ENOENT naming the binary rather than the directory, so
"Convert Audio" failed with the misleading "posix_spawn 'bash'".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 00:38:12 +00:00
pastilhasandClaude Opus 4.8 7d8341d3ba note the leftover officer-vnc.service unit in TODO
the hand-installed systemd unit kept a parallel xfce session on :1 alive and
respawned it on every kill, independently of the platform. obsolete now that the
desktop panel mirrors :0; disabled, but the unit file is still on disk.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 22:23:33 +00:00
pastilhasandClaude Opus 4.8 106e5bd17d mirror the physical display over vnc instead of spawning a virtual desktop per user
- vnc-manager now runs x11vnc against :0 rather than vncserver on a fresh display,
  so the browser shows the same session as the tv instead of a parallel one
- x11vnc reads :0's cookie from the logged-in user's own .Xauthority, so no root is
  needed; mirroring only works while someone is logged in (the greeter's cookie
  belongs to lightdm)
- -scale 0.5 halves the 4k framebuffer to 1080p for the stream, -shared -forever
  keeps it up across browser disconnects, -localhost keeps it behind the ws bridge
- readiness is now the listening port, not exit code: x11vnc stays in the
  foreground where vncserver daemonized and exited
- drops findFreeDisplay and per-email session tracking; there is exactly one :0
- the parallel desktops this replaces caused real breakage: a ghost logind session
  that broke lightdm login, and a brave profile lock held on :2

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 22:10:15 +00:00
pastilhasandClaude Opus 4.8 3fc7bcb32f always run pi as the service user, drop the sudo -u branch
- the sandbox already drops privileges to the OS user (id -un), so pi-bridge was
  the only code path that switched to a per-user unix account
- the four accounts it targeted (andrepadez, john-wick, fedra, miguelbenoliel)
  are vestigial: created by scripts/provision-existing-users.sh, with no home
  dirs, no files, no processes. the only live account is pastilhas@officer.dev,
  which maps to the service user, so isServiceUser was always true and the
  sudo -u branch could never fire
- add TODO.md tracking the leftover username plumbing, the useradd script, known
  bugs (task-executor relative cwd, bootstrap pi EEXIST), and the ufw 9010 rule

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 21:57:49 +00:00
pastilhasandClaude Opus 4.8 d723fcb23e extract shared whisper transcribe helper, use in file-browser and pi stt routes
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 13:17:15 +00:00
pastilhasandClaude Opus 4.7 e0bfc3d961 serve static assets from local public/ instead of static.officer.dev, simplify gmail history 404/410 handling
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-30 17:07:55 +00:00
pastilhasandClaude Opus 4.7 3540d53a00 gmail proxy tool with token refresh, claude pro bearer auth, pi --list-models stderr fallback, tool object input type
- add getValidGoogleAccessToken helper and use it in email-cron, email account auth resolver, and the new gmail proxy
- POST /api/integrations/google/gmail-proxy forwards arbitrary gmail rest calls server-side, with auto-refreshed oauth
- pi-manager and claude user-instance inject OFFICER_API_URL + per-session JWT so tools can call back as the user
- claude anthropic proxy uses Authorization: Bearer + preserves any anthropic-beta headers (pro oauth tokens are rejected via x-api-key, and overwriting the beta header broke context_management)
- pi --list-models: fall back to stderr when stdout is empty (pi v0.73.1 writes the table to stderr)
- mcp tool server + pi tool loader: accept type: object inputs so json bodies stay structured

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-30 17:07:51 +00:00
pastilhas 8a583da19b email crons 2026-05-16 07:59:37 +00:00
pastilhasandClaude Opus 4.6 039ea7ae71 remove stale native tasks on marketplace sync
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 17:55:14 +00:00
pastilhasandClaude Opus 4.6 b3f1d10bc1 inline email resync instead of job queue, refresh list on completion
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 17:07:06 +00:00
pastilhasandClaude Opus 4.6 ea8113e61d pipeline: add activity timeout and waiting indicator for local models
Agentic steps now have a 5-minute inactivity timeout (non-Claude-Code
models only) so stalled local LLM requests fail with a clear error
instead of hanging forever. A "Waiting for model" indicator is emitted
every 10s and shown in the pipeline UI stats bar, clearing as soon as
the model starts responding.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 10:56:39 +00:00
pastilhasandClaude Opus 4.6 92da03fcff pipeline executor improvements, proxy refresh, task runner step list
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 07:25:11 +00:00
pastilhasandClaude Opus 4.6 0f1e1f35f1 redesign automation page with simple list + detail panels
Replace 8-category layout with flat task list and detail view using
WorkspaceView. Searchable list with mode badges, run/delete actions,
create dialog. Remove 13 unused component files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 07:24:57 +00:00
pastilhasandClaude Opus 4.6 24ac7ac796 replace gmail resync with Gmail REST API, remove mbsync dependency
First sync still uses IMAP with app password. Subsequent syncs use
Gmail API history.list + messages.get with OAuth for faster, more
reliable incremental sync. Dispatch gmail-sync handler for gmail
accounts instead of generic email-sync. Show sync button for synced
accounts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 07:24:44 +00:00