Commit Graph
34 Commits
Author SHA1 Message Date
pastilhasandClaude Opus 4.8 4e78986e39 jobs: video/audio download as a two-phase job (backend)
Turns the downloader into a server-side job on the existing jobs spine (Postgres
persistence, live WS viewers + replay, abort, /jobs UI) — but with its own
executor and its own lane, since it's deterministic scripting, not an agent, and
a multi-hour playlist mustn't block agentic jobs.

- reclip-client.ts (new, shared): reclipInfo / reclipPlaylist / reclipDownloadOne
  (single download → streams the file to a dir, abort-aware). Extracted so both
  the file-browser endpoints and the job executor use one client.
- execute-download.ts (new): the two-phase executor —
  phase 1 metadata (expand playlist, fetch each info, keep survivors, skip
  errors), phase 2 download (each survivor in the chosen format; skip download
  errors). Emits a compact `download:progress` snapshot (counters, not per-item
  events — playlists are thousands of items). Throws on abort / fatal.
- job manager: `download` mode dispatch → executeDownload; persists
  download:progress; adds execution LANES (download vs default) so the two run
  independently and each serializes on its own; promoteNext fills both lanes.
- POST /api/tasks/jobs/download { url, format, dir, root?, label? } — enqueues a
  download job (own lane, no capability task needed; traversal-guarded target).
- schema: `download` added to the mode enum (drizzle text-enum — no DB migration);
  getPendingJobs() query for lane filling.

Verified the executor with a mocked ReClip client: two-phase filtering, skip-on-
error counts, and abort-throws all correct.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 18:09:37 +00:00
pastilhasandClaude Opus 4.8 f18d19e7d2 file browser: video download — metadata prefetch + playlist handling
Reworks the download-video dialog into a prefetch-then-download flow, mirroring
ReClip's own web UI. Still a pure proxy to ReClip (its yt-dlp); no downloader
logic moves to the platform.

Server (thin ReClip proxies alongside /download-video):
- POST /file-browser/video-info { url }     → ReClip /api/info → { title, thumbnail, duration, uploader }
- POST /file-browser/video-playlist { url } → ReClip /api/playlist → { urls }
  Both return { error } inline (200) so the client can render failures per-card.

UI (VideoDownloadDialog, now self-contained; useFileBrowserApp exposes `files`
and drops the old single-shot state/handler):
- Paste a URL → Fetch. A playlist URL (list=) expands via /video-playlist, then
  each entry's /video-info is prefetched sequentially (ReClip does yt-dlp per
  video), rendering a card (thumbnail, title, uploader, duration) that fills in
  progressively.
- Per-entry Download, plus Download All when there's more than one; per-card
  status (downloading → saving → saved / retry-on-error) via the existing
  background job + poll.
- Playlists get an optional "subfolder you name" field (ReClip's /api/playlist
  carries no playlist title); blank = current folder.
- Quality is always best (matches the mobile Share flow — no picker); the
  audio-only toggle applies to the whole batch.

Verified ReClip's contract live: /api/info returns the metadata fields, and
/api/playlist returns { urls } (17 entries in ~1.2s).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 14:19:07 +00:00
pastilhasandClaude Opus 4.8 11263ce120 task modal: audio info panel for Get Lyrics (title/artist/length/lyrics)
Display-only panel at the top of the Get Lyrics run-task form (single file only):

- Backend: GET /file-browser/audio-meta?path= — ffprobe format tags + duration,
  plus a second probe for embedded lyrics (USLT/SYLT/lyrics* keys, case-insensitive).
  Returns { title, artist, duration, hasLyrics }; tolerant of missing tags/probe
  failures.
- Client: files.audioMeta(path) + AudioMeta type in useFilesAPI.
- TaskRunnerModal: prefetch audioMeta for get-lyrics single-file runs (bypasses
  the hasTrackPickers early-return, error-tolerant), and render AudioMetaPanel
  above TaskInputForm — title/artist + a muted length + Lyrics: Yes/No chip,
  filename fallback. Directories + other tasks unaffected (no panel, no probing).

Verified ffprobe logic on a real embedded-lyrics file. tsgo clean; formatted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 17:07:18 +00:00
brunorezioandClaude Opus 5 0c7c015fc3 drop the built-in Extract Audio entry, and its cache
Extract Audio now exists as a task, with recursion, multi-select scoping, a
format choice and multi-track handling — none of which the one-shot menu entry
had, since it always produced a single mp3.

/extract-audio stays because the file viewer's button plays its output rather
than saving it beside the video, but it no longer returns a cached file: like
transcription and OCR, it always redoes the work. The path is now named outRel,
since it is an output location rather than a cache.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 03:50:47 +01:00
brunorezioandClaude Opus 5 d6b4b900ff stop caching transcriptions and OCR
Both endpoints kept a copy under cache/ and returned it on the next call, and
also short-circuited when the sibling .md already existed. So a re-run never
re-ran: a bad transcription stayed bad, and there was no way to ask for a fresh
one. Every caller passes saveNextTo, so the cache-path return was dead code
anyway.

Both now always do the work and overwrite the sibling. CACHE_PREFIXES drops the
two prefixes, since /save-result has nothing left to promote for them; the tts
and audio caches are untouched.

Also fixes the task runner output being unreadable in light mode. The panel is a
fixed dark terminal, but stdout lines were classed text-foreground, which follows
the app theme and renders black on the dark background. They now inherit the
pre's own colour.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 03:23:30 +01:00
brunorezioandClaude Opus 5 1ac79f9c68 remove the onboarding flow and the accountMode leftover
Onboarding was dead in three layers:

- The OnboardingAdmin screen was only reachable from a route block in App.tsx
  that has been commented out, so it never rendered. Its ServerTypeCard carried
  accountMode ('organization' | 'single'), inherited from the codebase this was
  based on and meaningless for a single-user platform.
- Two /onboarding-complete endpoints, one public and one protected, that no
  frontend code called. Both read a server_config key that was never written, so
  both answered false while the app's own path defaulted to true.
- HomeScreen gated on settings.onboarding.complete to show a welcome panel, and
  seedHomeDir created an Onboarding folder from DATA_PATH/Onboarding and
  /Onboarding_Admin — neither seed directory exists, so it only ever produced an
  empty folder.

Also drops the onboarding key from UserSettings and the now-empty home-header
panel from the default home layout.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 23:30:20 +01:00
brunorezioandClaude Opus 5 78130f21ce require a separator when checking a path is inside its root
resolveUserPath and five sibling checks used startsWith(rootDir), which also
accepts a sibling directory whose name begins with the root's: from a root of
/home/br, "../br-backup/secret" resolves to /home/br-backup/secret and passed.
Compare against root + sep (or the root itself) via a shared isInside helper.

Verified the escape cases now deny while "", ".", and ordinary relative paths
still resolve.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 23:30:20 +01: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.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 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 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 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 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 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 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.6 7bbcccabf1 wip: remove opencode, searxng, resources; fix user settings read
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 07:27:19 +00:00
pastilhasandClaude Opus 4.6 c7d509b725 scope file search to current directory
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:58:10 +00:00
pastilhasandClaude Opus 4.6 9a95773664 fix Videos default dir name and strip tts voice subdir in save-result
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:42:47 +00:00
pastilhasandClaude Opus 4.6 6a6ed5487d save ocr/tts/transcription results next to source file from context menu
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 23:52:57 +00:00
pastilhasandClaude Opus 4.6 6897e4e861 separate onboarding seed for super admin vs regular users
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:26:42 +00:00
pastilhasandClaude Opus 4.6 d62280176a remove HomeDirSelector, use HOME_DIR for super admin file browser root
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:05:29 +00:00
pastilhasandClaude Opus 4.6 40a9768cb3 claude-code streaming chat, desktop remote viewer, new-automation route, tiktok task v4, misc fixes
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
pastilhas acd7713c86 projects 2026-02-25 06:59:29 +00:00
pastilhas 7bdeecd7f0 read alout chat messages 2026-02-25 05:11:09 +00:00
pastilhas 6e8ee69311 fixed ocr/tts... caching 2026-02-25 00:16:52 +00:00
pastilhas 8fb96c7cf8 mobile 2026-02-23 11:16:33 +00:00
pastilhas 9acef6cf6c copy path and chat about file/folder 2026-02-23 05:15:13 +00:00
pastilhas 81256a1dc9 Onboarding 2026-02-23 02:03:45 +00:00
pastilhas 8a637c7788 yt-dlp downloads 2026-02-20 05:28:26 +00:00
pastilhas d7503ca56b Files FIles Files 2026-02-20 04:28:02 +00:00
pastilhas dd8ab84df5 Workspaces in Workspaces all around 2026-02-19 01:49:15 +00:00
pastilhas 030cf9fbd3 Code editor and widget 2026-02-17 23:48:46 +00:00
pastilhas 21213c281d File browser as widget 2026-02-17 19:23:01 +00:00