SvelteKit tool for marketing teams to manage aggregator offers (Wolt, Bolt) and track offer performance.
Matches all tools
Hooks run on every tool call, not just specific ones
Executes bash commands
Hook triggers when Bash tool is used
Own this plugin?
Verify ownership to unlock analytics, metadata editing, and a verified badge. GitHub access is read-only (username + org membership).
Sign in to claimOwn this plugin?
Verify ownership to unlock analytics, metadata editing, and a verified badge. GitHub access is read-only (username + org membership).
Sign in to claimBased on adoption, maintenance, documentation, and repository signals. Not a security audit or endorsement.
Modifies files
Hook triggers on file write and edit operations
Modifies files
Hook triggers on file write and edit operations
SvelteKit + TypeScript tool for marketing teams to register and manage aggregator offers (Wolt, Bolt, etc.) and track offer performance against aggregator invoices.
See CLAUDE.md and AGENTS.md for the full project rules.
bun install
bun run dev
Then open the URL printed in the terminal (default http://localhost:5173).
Other useful scripts:
bun run check # svelte-kit sync + svelte-check
bun run test # vitest run
bun run svelte-autofixer # prettier --write .
bun run build # production build
bun run build
bun run preview
Production deploys run the Node adapter output (
build/). Set the env vars listed in.env.exampleon the host before starting.
The Image Generator persists generated images, reference images, and brand assets through a single object store abstraction (src/lib/server/object-store.server.ts). The store resolves files by a portable, slash-separated storage key (e.g. images/<id>.png, references/<id>.<ext>, brands/<slug>/assets/<id>.<ext>) which is what the localPath columns now hold (the column name is historical — the value is a key, not a filesystem path). There are two drivers, selected at runtime:
Supabase Storage (preferred — required when the database is shared). When SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, and SUPABASE_STORAGE_BUCKET are all set, files live in a private Supabase bucket and are shared across every machine that talks to the same database. Use this whenever DATABASE_URL points at a shared/remote Postgres — otherwise a row created on one machine renders a broken (404) thumbnail on another, because the bytes only exist on the machine that generated them.
| Variable | Purpose |
|---|---|
SUPABASE_URL | Project URL, e.g. https://xxxx.supabase.co |
SUPABASE_SERVICE_ROLE_KEY | Service role key — server-only, never sent to the browser |
SUPABASE_STORAGE_BUCKET | Name of a private bucket (e.g. marketing-offers-uploads) |
Files are served by proxying bytes through the existing API endpoints (/api/images/[id]/file, /api/images/references/[id], /api/brand-assets/[id]), so per-user ownership checks are preserved and no public/signed URLs are exposed.
Local filesystem (fallback — dev + tests only). When the Supabase vars are unset, files are stored under ${UPLOADS_DIR} (default ./uploads, gitignored) at the same key layout. The server creates subdirectories lazily with mode 0700; the parent UPLOADS_DIR must already exist and be writable. Do not rely on local storage when the database is shared across machines.
Operational notes:
$env/dynamic/private, so it can be overridden per deploy without rebuilding.GeneratedImage are not garbage-collected — monitor bucket/disk usage and add a sweep job if it grows unbounded.bun scripts/backfill-storage.ts (uploads everything under UPLOADS_DIR to the configured bucket using the original keys). Rows whose bytes never existed on the current host cannot be recovered.Read this before touching the production DB. Migrations are managed by Prisma 7. The project rule (
CLAUDE.md) is: neverdb push, alwaysmigrate; never destructive migrations without team sign-off.
For your own dev DB pointed at by DATABASE_URL, the normal Prisma loop applies:
bunx prisma migrate dev --name <descriptive_name> # creates + applies on a dev DB
bunx prisma generate # regenerate client
bunx prisma migrate status # show pending vs applied
If migrate dev reports drift (tables or columns in the DB that are not in any migration), it will offer to reset the DB. Do not accept the reset on a shared or production DB. Reconcile the drift first — see "Reconciling drift" below.
Use a checklist, not muscle memory. Each step is reversible until the last.
Snapshot the DB. Take a logical dump before any schema change:
pg_dump --format=custom --no-owner --no-privileges \
--file=backup-$(date +%Y%m%d-%H%M).dump "$DATABASE_URL"
Verify the file is non-empty and store it off-host.
Confirm the migration history is in sync. Against the production DATABASE_URL:
bunx prisma migrate status
npx claudepluginhub michailbouklas/marketing-offers-toolUltra-compressed communication mode. Cuts 65% of output tokens (measured) while keeping full technical accuracy by speaking like a caveman.
Memory compression system for Claude Code - persist context across sessions
Multi-model consensus engine integrating OpenAI Codex CLI, Gemini CLI, and Claude CLI for collaborative code review and problem-solving.
45% cost reduction measured. Cache expiry prevention, SubTask auto-delegation, zero-cost context restoration, real-time cost dashboard. The only Claude Code plugin built from CC source analysis.