feat: export AutoClip clips into the Library (mp4 storage, preview, download, retry) - #53
Merged
Merged
Conversation
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The new Agent-results UI reads outputs.libraryClips at the top level, but only the background media-fetch job set it there directly. The synchronous crayo.run_autoclip (direct-file) and crayo.export_project steps left their libraryClips nested at outputs[step.id] instead, so those two paths showed nothing in the new clip preview/Download/Retry block. Lift and accumulate libraryClips from every step's result onto outputs.libraryClips, additive to the existing per-step outputs[step.id] copy.
…mbnail cleanup Final-review fix wave for clips-to-library (Tasks 4-10): - ingestFile/attachThumbnail now persist the plain relative key as storage_key instead of writeLibraryFile/writeLibraryBytes's return value, which is an absolute path on the local-disk backend and doubles onto ROOT on read/delete. - ingestFile's checksum-duplicate branch now backfills external_ref onto the pre-existing asset so a retried Crayo export is found by findAssetByExternalRef instead of spending another credit. - media_assets.external_ref gets a unique partial index (new migration 0033 + matching ensureLibrarySchema DDL), and insertAsset treats a unique-violation on external_ref as "already exists" (via a new isUniqueViolation helper in mappers.ts) instead of a hard failure, closing the check-then-act race. - archiveAsset now also deletes the thumbnail version's bytes and clears thumbnail_version_id, so archived assets stop leaking storage and no longer get a signed thumbnailUrl for a video that's gone.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Deployment failed for project clippyos with the following error: Learn More: https://vercel.link/3Fpeeb1 |
Contributor
Author
|
@claude can you fix |
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Continues #51/#52 (schema, budget guard, streaming storage). This PR is Tasks 4-9 of docs/superpowers/plans/2026-09-16-clips-to-library.md, plus a final-review fix wave.
Summary
ingestFile/attachThumbnailinlibrary-pipeline.server.ts— disk-streamed ingest and thumbnail-as-version-row, so nothing is buffered in memory.clip-export.server.ts— resumableexportClipStepstate machine (Crayo export → poll → download → ingest → thumbnail), fully unit-tested against a fake Crayo client, shared by both the background job and the synchronous callers.media-fetch-job.server.tsgains anexportingphase — the background AutoClip job now actually exports and stores clips instead of ingesting only thumbnails./autoclipand manual/exportpaths do the same viaexportClipToLibrary.GET /api/library/file?download=1andsignLibraryAssetsFn— signed preview/download URLs.appendLibraryClips) so the two synchronous paths' results show up in the UI the same way the background job's do.storage_keywas double-joining to a 404 (Critical, now fixed); checksum-duplicate ingests now correctly recordexternal_ref(idempotency);external_refnow has a unique index with conflict-safe insert handling;archiveAssetnow cleans up an asset's thumbnail version too.Verified
tsc --noEmit: 0 errors.npm test: 397 total, 396 pass, 0 fail, 1 pre-existing named skip..superpowers/sdd/2026-09-16-clips-to-library/progress.md(git-ignored, available in this checkout for anyone continuing the work).Known, deliberately unfixed
signLibraryAssetsFn,retryClipExportFn): both match the identical authorization pattern already used by their own pre-existing sibling functions in the same files (getLibraryAssetFn/listLibraryAssetsFn,getAgentRunFn/cancelAgentRunFn) — verified independently three times across reviews. This is ClippyOS's existing, established design (single shared workspace, any authenticated staff member can act on any asset/run), not something this PR introduces./autoclippath now does real export work inside Vercel's 300s function budget, with no resumability if it times out. Explicitly deferred to live verification (below) rather than fixed speculatively.external_refindex gets recreated byensureLibrarySchema's DDL on every start, redundant but harmless; (b) under a narrow concurrent-insert race for the same Crayo project id,ingestFiledoesn't consumeinsertAsset's new conflict-recovery value, so that specific race now surfaces as a thrownASSET_MISSING+ an orphaned version row instead of a silent duplicate asset. Real, not exploitable, not data-loss, but should get a small follow-up (haveingestFilecatch the conflict the same way its checksum-duplicate branch already does)./exporthas no spend guard unlike the other two paths; the thumbnail shows as a confusing "v0" in the version-history UI; signed URLs can outlive an open results panel;ingestFiledoesn't respect the operator'smaxUploadMbsetting).Not yet done
No real Crayo export has been run against this code. Local dev's database is in-memory and loses all keys on every restart, so I could not enter a Crayo key myself (and wouldn't — that's the operator's key to enter, not mine to handle). Before merging, please:
/autoclipon a short (1-3 min) direct mp4 link with 2-3 clips, and watch it end to end: does it fit inside the 300s function budget on the synchronous path? does the clip actually land in the Library, playable, downloadable?