Repository navigation
Releases: shipwords-dev/shipwords
Releases · shipwords-dev/shipwords
Release list
v0.1.0
The first tagged release of shipwords. Pin your fork to a tag from now on, and read the upgrade notes below before pulling a newer one.
tinydeskai.io runs this version in production; its source is in sites/tinydeskai-example.
Upgrading a site forked before this release
Do these in order. Commands with pnpm db:* run in the site directory; the rest run from the repo root. Finish with pnpm --filter "./sites/<site>" check.
- Split the models file.
site.models.tsnow usesdefinePublicModelsand holds only what pages show (name, credits, guest, inputs, effect slots). Everything else (upstream model,maxCost, timeout, prompts, effect presets) moves to a newsrc/models.server.tsusingserverModels, keyed by the same ids. Then point the two server entries at it: insrc/core.server.tsandsrc/server.ts, changeimport models from '../site.models'toimport models from './models.server'. Pages keep importingsite.models.ts. Extra fields insite.models.tsare rejected (top-level ones at typecheck, nested ones when the file loads), andcheck-siterequiressrc/models.server.ts. See the template and the example site. - Add
signup.bonusSiteDailytosite.config.ts: how many sign-up bonuses the whole site grants per day (0when the site gives none). It is required. - Check
BETTER_AUTH_SECRET. It must now be at least 32 random characters (openssl rand -base64 32), locally and in production; auth and every request that needs it fail otherwise. - Generate and apply a migration:
pnpm db:generate, thenpnpm db:migrate:local, andpnpm db:migrate:remotewhen you deploy. It adds the nullable columnjobs.upstream_cost_usd. - Update
package.json: add"devPort"(each site gets a fixed dev port, 10 apart;pnpm new-siteassigns the next free one), then runpnpm setup:worktreesoAPP_URLin your.dev.varsfollows the new port, and addhttp://localhost:<port>to your Google OAuth origins. Makedeploy/deploy:previewrunnode ../../tools/check-site.mjs .after the build, as the template does; it now scans the client bundle for strings from*.server.tsfiles and for.dev.varsvalues. - Effect models with prep: recheck
maxCost. A slow prep now gets a second, hedged copy, so the model'smaxCostmust cover the sum of segment caps, plus every repair round, plus twice the prep cap per prepped slot. A config that only covered one prep each throws at load. - If the UI cancels jobs, show the cancel button only while the job is
queued(see the template'sJobCard); after that the API refuses with409 job_started. - If you use the compose container, redeploy. The old image ignored SIGTERM, so instances kept running and billing memory for hours after each job. The fixed image is built from
packages/jobs/composeon deploy.
If you extended the engine
emailOnSuccessis nowemailOnFinish; itssiteoption needsdefaultLocale, and it also emails failed jobs.- A custom payment adapter's
PaymentFactneedsmetadataTrusted. Set it totrueonly when the metadata cannot be set by the buyer (Stripe); otherwise payments below the list price are refused. - A custom
Composer(or test double) needslikeness,extractandpatch. EffectCheck.retriesis gone: a missed swap no longer reruns the segment. Usesegment.repairinstead.MockAdapter's third argument is now the site URL, not the fallback file URL.- UI that read
job.error.messagemust switch tojob.error.code.
Behavior changes
- No refund on a path the customer can repeat after the upstream has charged. A cancel only works while the job is queued; once the upstream has it,
POST /api/jobs/:id/cancelanswers409 job_startedand the job keeps going.useGeneration'scancelabsorbs that. Cancelled guest jobs no longer return guest quota. See architecture §6. job.errorcarries only a code, not the stored message (which could hold upstream replies and face-check scores). Show your own copy per code.- Uploads under 160 px on the short side are rejected with
422 image_too_small; files whose size header can't be read get415 invalid_image. - Sign-up attribution goes to the first visit that has a source (UTM or outside referrer), not simply the first visit. Your own pages and payment checkouts no longer count as referrers.
- Engine emails (sign-in codes, job finished or failed) follow
defaultLocale: built-in copy for en, ja and ko, English otherwise. Failed jobs now get an email too. jobs.upstream_cost_usdrecords what the upstream reported for the job's recorded tasks, best effort: a hedged prep copy is not counted, so treat it as a floor, not the exact cost.
New
- Music jobs: a third job kind (style prompt plus optional lyrics in, songs out) through Yir's music endpoint. Stored MP3s have provider ID3 tags stripped.
- Repair for missed face swaps (
segment.repair): missed shots are re-rendered with a replace model, with optional crops for people at the frame edge and alikenessthreshold for close-ups. WithonMiss: 'deliver', a missed swap or a check problem after the upstream has charged delivers the best version so far instead of refunding; a render or compose that fails outright still refunds. - Faster photo prep: a prep that runs over a minute gets a hedged second copy, and all preps are polled together.
- Phone photos: photos over 8 MB or in a format other than PNG/JPEG/WebP (HEIC included) are redrawn as JPEG in the browser before upload when the browser can decode them; otherwise the upload fails with a readable error. Use
UPLOAD_ACCEPTandacceptsUploadfrom@shipwords/jobs/reactfor file pickers and drag and drop. - Money-path fixes: quota counts roll back when a later quota write fails; PayPal only grants credits when the payment covers the list price in the list currency.