Commit Graph
2 Commits
Author SHA1 Message Date
pastilhasandClaude Opus 5 c69f6d12a3 Convert Image, and HEIC opens because av-club already knew how
the fourth task. same shape as the other three — beside the original, skip an
existing output, skip a file already in the target format, delete only when asked
and only after the write.

/v1/sharp gets the same path mode /v1/ffmpeg got, for the same reason: the file
browser and the commander both already have the file.

HEIC IS THE POINT OF THIS ONE, and nothing in the task does anything about it.
`decodable.ts` has routed HEIC through ImageMagick since before I touched this
plugin, because the libheif inside sharp is built without the HEVC decoder — a
HEIC reads its own header fine and then fails on the pixels, which looks exactly
like a corrupt file and is not one. the task simply names `.heic` in its trigger
and asks. the photographs open.

I had diagnosed that gap independently against the file browser's thumbnails and
concluded a system decoder would be needed, twice telling the owner these files
could not be read. this plugin had already solved it and documented why. worth the
note: the answer was in the tree.

a path has no stored `format`, so sharp's `metadata()` supplies it — and that only
reads the header, which is precisely the part of a HEIC that works, so it correctly
identifies the files needing ImageMagick.

`rotate` with no argument is in every pipeline: it applies the EXIF orientation and
drops the tag. without it a portrait photo from a phone converts to a landscape
image that viewers rotate back, until one does not.

max_dimension shrinks to fit and never enlarges. quality 82 for jpeg and webp, 55
for avif — where a photograph stops looking better and only gets bigger.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 02:28:06 +01:00
pastilhasandClaude Opus 5 79ff366802 become an Officer plugin
av-club keeps doing exactly what it did — sharp, ffmpeg and ffprobe behind one
API, and the invariant that the caller never names a path. What changes is how it
is reached and who decides who may reach it.

`src/` is `sidecar/`, because that is the name the platform looks for:
`sidecar/index.ts` present means "this plugin ships a process", and presence is
the declaration for everything structural here. `manifest.ts` at the root is the
other half of that rule.

api/router.ts is a proxy and nothing else. the platform authenticates, checks the
`av-club` permission, and forwards — so the sidecar now accepts a request
carrying `X-Officer-User` and no longer demands its own bearer token from
callers who came that way. it binds LOOPBACK to make that trustworthy, which is
the same boundary caldav's DAV door already relies on. AV_CLUB_TOKEN stays, and
still guards anything calling the port directly: fofos/platform is the stated
first consumer and is not Officer.

THREE THINGS HAD TO GO, and each one broke it in a way worth writing down.

package.json and bun.lock: a package.json inside a plugin is a package boundary,
so bun stops walking up for the platform's tsconfig and `@@/sidecar/connect`
stops resolving. the sidecar died on its first import, fifteen times. npm
dependencies go in the manifest instead, where npm-deps.ts intersects them across
plugins into one plugins/node_modules — which is also how this surfaced a real
conflict: sharp ^0.33.5 (atelier) and ^0.35.3 here do not overlap, since a 0.x
caret pins the minor. atelier moved up; it calls one method.

tsconfig.json: same failure one layer earlier, shadowing the platform's `@@/*`
paths so api/router.ts would not mount. no other plugin has one.

no screens, deliberately. this is an API and a body of documentation; its callers
are a commander watching a folder, an agent, or curl. a dock tile would advertise
a page with nothing on it.

verified through /api/av-club with an agent key: a 3000x2000 jpeg uploaded,
probed, and resized to a 1200x800 avif — 166 KB to 1 KB — without the caller ever
holding av-club's own token.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
2026-08-28 22:36:53 +01:00