Commit Graph
8 Commits
Author SHA1 Message Date
pastilhas dbf50325bb declare sharp in the manifest, drop the plugin's own package.json
the platform now merges every plugin's `npmDependencies` into one shared
install at plugins/node_modules/, so this declares a RANGE and shares whatever
the next image plugin resolves rather than carrying its own 50 MB copy of
sharp's platform binaries.

replaces the package.json and lockfile added an hour earlier. that version
worked and was the normal thing for a git repository to do; it just did not
survive the question "what happens when a second plugin wants sharp".
2026-08-20 18:23:11 +00:00
pastilhas 7ea059b01a own package.json and lockfile, for sharp
sharp was a direct dependency of the PLATFORM, added during the extraction
because there was nowhere else to put a javascript package. that broke on the
first other machine: alpha pulled the package.json, nobody ran bun install, and
this sidecar crash-looped on "Cannot find package 'sharp'".

the platform now installs a plugin's own packages into the plugin's own
directory (src/servers/plugins/npm-deps.ts), so this ships its own
package.json and lockfile like any other repository — and uninstalling atelier
takes sharp with it instead of leaving it in the platform's lockfile forever.

the lockfile is committed and frozen on install, same discipline the platform
holds itself to. sharp is load-bearing here, not incidental: inspect.ts uses it
to measure alpha channel and opacity, which is how a `background: transparent`
request that silently produced an opaque image gets caught.
2026-08-20 18:10:20 +00:00
pastilhas 2726541ede providers is a panel, not a section in officer's settings
`IntegrationsSettings/index.tsx` has carried the rule since email was extracted
on 2026-08-18: a plugin contributes panels, not settings sections. the
extraction brief said the opposite and the brief was wrong.

settings living in the platform mean this plugin is not self-contained — it
cannot be configured on an older platform, and uninstalling would leave a dead
"Atelier" section in the settings screen for someone to delete by hand.

so: a fourth panel, `atelier-providers`, and the default layout stacks it under
Collections in the right column. smallest and last because it is configured once
and then ignored — but it has to be REACHABLE, which is the whole point.

Generate's empty state pointed at "Settings → Integrations → Atelier". it now
points at the Providers panel, which is where the key actually goes.
2026-08-20 17:58:38 +00:00
pastilhas c892f2e700 officer_db with atelier_ prefixes, like every other plugin
the extraction kept atelier's own postgres database, because the brief said to
when the tables already had rows. the owner reversed it, and the reason is not
tidiness: a plugin that behaves differently from every other plugin is a
plugin nobody can reason about.

the separate database meant a second connection string to set before install,
a second thing to back up, a second thing to get wrong on a new machine, and
failure modes no other plugin shares — none of it bought anything except
avoiding a migration.

four tables now: atelier_collections, atelier_collection_items,
atelier_providers, atelier_generations. index and check constraint names carry
the prefix too — those are global in postgres and are the one thing that would
otherwise collide with another plugin.

db/schema.ts re-exports the definitions rather than duplicating them: they stay
beside the code that queries them in sidecar/db/, and that file exists to be
found by gen-plugin-schemas.

ATELIER_POSTGRES_URL is gone. db.ts reads OFFICERDEV_POSTGRES_URL ?? POSTGRES_URL,
which the platform already sets.

the standalone service's rows are NOT here and nothing depends on them being
here — the old service is still running against the old database, untouched,
and migrating is a separate watched step after this is proven on alpha.
2026-08-20 17:30:53 +00:00
pastilhas ccfde75aae PLUGIN.md: record the real bundler build as verification
generatePluginsModule + rebuildFrontend, called directly with a synthetic install state, exercises
the same Bun.build + Tailwind path a real install performs — no server running, no port bound. It
compiled cleanly: 3 outputs, 2.2s, zero errors. Stronger than tsgo alone (catches bundler-side module
resolution and JSX/CSS processing), but does not confirm the result renders correctly in a browser —
noted as still open.
2026-08-20 04:11:31 +00:00
pastilhas 4bff81ab2a PLUGIN.md and README.md
PLUGIN.md is the record: what moved, what changed on the way (authenticated image serving, the
secret-store OpenAI key fallback, provider_settings left behind), what stays running untouched (the
standalone service the mobile app still talks to), why there is no db/ directory, and what verification
did and deliberately did not cover.

README.md is the marketplace shop window — what it does, what it needs (its own Postgres database,
an OpenAI key), and an honest limitations section: two Ateliers can exist side by side right now, and
there is no per-user data model yet.
2026-08-20 04:09:27 +00:00
pastilhas 859fb5767c web: three panels — Generate, Gallery, Collections — and a layout
ported from the standalone app's hash-tab UI. The panels do not coordinate through props (the panel
contract only ever hands a component its panelId) or usePanelChannel-as-selection:

- Gallery's lightbox is ?selected=<id>, Collections' detail is ?collection=<id> — different names
  since both panels render on the same route at once
- Generate bumps useAtelierRefresh (added to officerdev/src/channels.ts) when a job finishes;
  Gallery subscribes to it — a genuine signal, not a selection, so it stays a channel

images render through GET /files/:filename with a ?token= query param appended client-side
(lib/api.ts's fileUrl), the same escape hatch FileViewer and the music plugin use for exactly this:
a browser cannot set an Authorization header on an <img src>.

Providers is not here — see PLUGIN.md for why it became a platform settings screen instead.

assets/icon.png and assets/splash.png are [placeholder] flat swatches, not real artwork — see
assets/PLACEHOLDER.md.
2026-08-20 04:01:10 +00:00
pastilhas f23ec1283b manifest, thin proxy router, and the sidecar backend
ported from the standalone officer-atelier service: providers (adapter-shaped, openai the only
adapter today), the generation queue, collections, and the database layer — kept on its own
Postgres database rather than folded into officer_db, since both collections and provider_settings
had rows on the machine this was extracted from.

what changed rather than just moved:
- images are served from an authenticated GET /files/:filename instead of an unauthenticated
  PUBLIC_URL-prefixed static route
- the OpenAI-key bootstrap fallback reads the secret store (getSecret) before .env, per-adapter
- provider_settings (the one-row-per-adapter shape providers replaced) did not come along — it has
  no callers left anywhere in the server code, only a migration script that also did not move

ping/echo (smoke-test routes with no caller) did not move either; the sidecar's own /_health covers
liveness.

not yet wired into the platform: sidecar/index.ts exists but nothing mounts it, and web/ has not
been written, so this is not yet a discoverable plugin.
2026-08-20 03:53:53 +00:00