AGENTS.md · getopenpost/openpost
AGENTS.md from getopenpost/openpost: 233 lines covering Product bar, Route the work, Authorities, Engineering invariants and more.
Template by getopenpost
Chalk Labs
Need help deploying AGENTS.md · getopenpost/openpost?
Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.
Install
Works with Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code. Read the repository before you give any tool access to your data.
curl -fsSL https://raw.githubusercontent.com/getopenpost/openpost/main/AGENTS.md -o AGENTS.md
Read it and adapt it to your project before use.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: documentation
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
What's in it
An AGENTS.md file: instructions coding agents (Codex, Cursor, Copilot, Gemini CLI and others) read before working in a repo.
- For
- Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code
- Length
- 233 lines
- File
AGENTS.md
Sections
- Product bar
- Route the work
- Authorities
- Engineering invariants
- Execution
- Delivery
- Release and incident notes
First lines (shown under the repo's AGPL-3.0 license)
# OpenPost agent guide OpenPost is the all-in-one content team for solo founders. It turns their work into channel-ready content, publishes it, and brings outcomes back into one workspace. Hosted is the primary product; self-hosting is a deployment option. - A **Publication** is the user-visible post. It owns the source idea, schedule, status, and destination outputs. - A **Rendition** is one destination-specific version with its own account, text, media, format, timing, and provider settings. Product copy calls these posts and variants. `Publication` and `Rendition` remain the internal model names. ## Product bar - Start with the founder's launches, updates, lessons, and ideas. Remove repeat work without hiding decisions. - Preserve provider truth. Show real capabilities, limits, review needs, readiness, and failures. - Keep every outcome inspectable: draft, scheduled, queued, published, failed, or retrying. - Use the same terms, permissions, and workspace boundaries across web, mobile, API, CLI, MCP, Hosted, and self-hosted surfaces. - Treat UX consistency as a product requirement. Reuse established patterns and preserve keyboard access, visible focus, readable contrast, reduced motion, localization, and touch targets. ## Route the work Load only the branch the task needs: | Task | Read or use | | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | | Substantial, ambiguous, or multi-ticket work | `agent-workflow`; the OpenPost Vikunja project for the current spec, priority, and execution state | | Product scope, public copy, provider support, or capability claims | `README.md` for current public claims and readiness; `PRODUCT.md` for purpose, terms, and scope | | UI, visual, or user-facing copy changes | `ux-consistency` and `DESIGN.md`; add `impeccable` for design critique | | Public documentation structure, prose, examples, or images | `documentation` and `unslop`; preserve complete tasks, useful images, and old routes | | Public SEO, search discovery, or agent access audits | `openpost-seo`; verify live findings against the marketing and documentation source owners | | Interaction sounds | `cuelume` | | Repository ownership or an unfamiliar seam | `docs/agents/repository-map.md`, then confirm its paths and symbols with `rg` | | Go HTTP or OpenAPI work | `huma`; for TypeScript consumers, also use `openapi-typescript` | | Server-state reads, cache keys, invalidation, or loading boundaries | `docs/specs/server-state-query-migration.md` | | Deployment, runtime configuration, release workflows, or revision proof | `docs/agents/deployable-inventory.md` | | n8n or SDK package release or package-only recovery | `docs/agents/n8n-package-release.md`, `docs/agents/sdk-package-release.md` | | Video Editor, Quick Cut, or Recorder | `docs/specs/video-editors-rebuild.md` and the relevant rows in `docs/specs/freecut-parity-audit.md` | For reference implementations, read `docs/references/README.md` before inspecting a checkout. Use `postiz` or `shoutrrr` for publishing and durable automation, `miniPaint` for the Image Editor, and the named video references for recording or editing. Keep reference checkouts shallow and Git-ignored. Audit source and license before porting code; OpenPost's architecture, security, accessibility, provider rules, and product language remain authoritative. ## Authorities - **Vikunja** owns private work, specs, priorities, and execution state. **GitHub Issues and pull requests** own public reports and contributor discussion. - **Hindsight bank `rodrigo`** owns durable product terms, decisions, constraints, and history. Before substantial work, recall `project:openpost`, then verify the result against current code, Vikunja, or the live system. Retain only verified durable facts tagged `project:openpost` and `source:<agent>`. - **This repository** owns code, tests, generated contracts, build and security rules, and public technical documentation. Keep project state out of repo-local memory files and mutable task boards. `packages/ui` owns reusable Svelte controls, theme manifests, icon registries and shared CSS. App paths may forward exports for compatibility; implement shared changes in the package. Keep SvelteKit, API clients and generated translations in their consuming apps; adapt UI labels through `provideUiMessages`. Docs consume `tokens.css`, and native theme generation consumes the package manifests. Shared package builds must serialize writes to their output directories. Root dependency installation builds the UI package and its Dither dependency before direct format, dev and component-test commands. Keep that preparation in the root postinstall lifecycle so fresh CI and local checkouts behave the same. Recovery pages share `packages/ui/src/lib/recovery.css`. Bundle-free HTML and MCP widgets inline maintained UI tokens and Bayer masks through `scripts/static-ui.mjs`; regenerate the offline page and MCP stylesheet with `bun scripts/sync-static-ui.mjs`, and the marketing 404 with `bun apps/marketing/scripts/sync-static-404.mjs`. Keep offline recovery self-contained. Validate generated output with `bun run check -- ui-consistency`. Keep deployable projects in `apps/`, shared runtime code in `packages/`, browser suites in `tests/`, deployment files in `deploy/`, and repository manifests in `config/`. Public Go module names and root task scopes do not change when source folders move. Keep community policies in `.github/`, launch templates in `docs/launch-kit/`, social artwork in `assets/social/`, and browser configurations with their test suites. Keep `PRODUCT.md` and `DESIGN.md` at the root for design-tool discovery. Local review reports and screenshots are ignored; commit maintained acceptance inputs with their owning tests or design sources. Native README screenshots use `apps/mobile/tests/screenshots/` and `bun run capture:mobile-screenshots`; keep sample data outside the shipping entry and regenerate the labelled phone gallery after mobile UI changes. Keep third-party deployment packaging under `deploy/<platform>/`. If a platform requires its manifest at the repository root, use a dedicated wrapper repository instead of adding another root file here. Public marketing speaks to Cloud customers creating content and running a business. Features navigation points to `/#features`; automation and self-hosting setup belong in the documentation, not duplicate marketing pages. Keep removed public routes out of the route manifest and maintain their deliberate redirects in `apps/marketing/static/_redirects`. Public buying comparisons belong to the shared guide catalogue in `packages/social-images/src/`. Reuse the guide renderer and discovery manifest. Derive OpenPost prices and limits from `@openpost/plan-catalog`; keep competitor facts with official source links and an explicit review date. Change that date only after checking those sources, and state where the competitor fits better. Comparison metadata owns the product name, local official mark, category, and optional free-tool link. The Resources comparison directory and guide hub share one directory component; retain existing guide URLs. Creative-tool comparisons describe free local editing separately from Hosted storage and publishing. Keep third-party mark sources in `assets/logos/comparisons/SOURCES.md` and preserve original colors. Install marketing module-download recovery in the client `init` hook, before hydration imports run. A layout mount callback cannot recover failures that precede its own mount. App module-download recovery clears its persisted retry budget only after a successful SvelteKit navigation. Keep failed routes bounded across reloads. Public OG images use the shared renderer in `scripts/social-images/render.mjs`. Keep generated homepage artwork and its prompt in `assets/brand/social/`, topic icons from Lucide, full titles, stable image URLs, and matching launch-kit PNGs. Verify the full catalogue and inspect cards at 320px preview width. Browser extension listings use `packages/social-images/src/extensions.js` for their descriptions, install links, screenshots and privacy summaries. Keep unlisted store URLs out of public CTAs; use GitHub installation instructions until publication is verified. Extension screenshot assets belong in `assets/marketing/extensions/` and the marketing asset manifest. Label sample-data captures. Public media-tool routes, format pairs and metadata come from `packages/social-images/src/media-tools.js`. Directory thumbnails use static format and operation previews, public Lucide icons, and the paired marketing palette. Keep their palette assignments in the shared media-tool catalogue. Browser video/audio conversion stays behind the marketing `local-media.ts` adapter, loads only on tool routes, bounds inputs and output writes, and rejects failed selected tracks. The UI and guides explicitly disclose primary-track selection and omitted subtitles or attachments. Public entity facts belong to `config/public-brand.json`; marketing JSON-LD and `/.well-known/brand-facts.json` consume it. Include only verified profiles in `sameAs`, keep the project's identity separate from its individual operator, and never infer a legal company or founding date from a release tag. Agent Markdown indexes and bounded corpora come from `scripts/generate-agent-surfaces.mjs`, using the same public page catalogues as their representations. Keep Markdown indexes out of XML sitemap directives. Standalone downloadable HTML kits declare `noindex`; catalogue pages must stay indexable and retain social metadata. Public documentation uses Fumadocs in `apps/docs/`, with authored MDX under `content/docs/` and a static export in `out/`. Keep customer guides, built-in Workflows, external automation, self-hosting, and the generated API reference separate. Workflow tutorials and run controls belong in `content/docs/workflows/`; SDK, HTTP API, CLI, and n8n guides belong in `content/docs/automate/`. Engineering documentation belongs in `docs/development/`; operator reference details belong in `docs/reference/`. Generate API operation pages from `apps/web/openapi.json` on every docs build, never edit generated MDX. The public Cloudflare site composes marketing at `/` and documentation at `/docs` through `bun run build -- public-site`; `openpost-marketing` publishes `dist/public-site`. Keep docs base-path aware, reject output collisions, and keep the retired docs host only as a direct path-and-query-preserving redirect. Keep static redirects before wildcard or placeholder rules in the composed public site. Cloudflare counts every rule after the first dynamic rule against its 100-rule dynamic limit. Generate the media-limits guide with `scripts/sync-docs-openapi.mjs`; edit the capability catalogue or `apps/server/cmd/openpost-media-limits`, never the generated MDX. Verify docs reader interactions against the static export with `bunx playwright test --config tests/docs/playwright.config.ts` after `bun run build -- docs`. Use shared Fumadocs controls and SVG icons for page actions, search, and navigation. Documentation copy controls belong to `apps/docs/components/documentation-copy.tsx`; retain the exact source text for recovery and show success only after the clipboard write completes. Each social network has one self-hosting integration guide. Keep shared credential setup in the integration index and link provider-specific steps to it. Use `SetupScreenshot` for expandable setup screenshots, preserve source attribution and licenses for reused portal images, and label edited example values. Capture OpenPost connection dialogs through `tests/app/product-screenshots.spec.ts` in both schemes. Generated screenshots illustrate setup, never provider approval. Free-tool draft transfer uses `@openpost/draft-transfer`. Keep content and files out of URLs and telemetry. The browser receiver verifies origin, opener and token; uploads resume through the media adapter with an actor and Workspace receipt. Import into a fresh composer, retain the transfer until the draft saves, and keep publishing explicit. ## Engineering invariants - SvelteKit builds the interface; Go embeds it into one binary. Echo serves HTTP, Huma owns OpenAPI, and Bun ORM owns database access. SQLite is the self-host default; PostgreSQL supports Hosted. - Publications are the canonical authored-content inventory. Page reads use stored state; provider calls occur only in explicit sync or durable job flows. Planned views use authored `scheduled_at`; queued `actual_run_at` may include random dispatch delay and is not the authored schedule. Published views use the recorded actual time. - Rendition array order is authored inventory state. Persist input order in `renditions.position`, and project it consistently in reads and actions. Creation timestamps and generated IDs never define destination order. - Publication revision domains compare stored authorship before and after the transaction. Ignore delivery IDs, timestamps and inherited output projections; preserve explicit empty overrides and effective schedule changes. - Hydrate the composer session and visible content from the same Publication response. Never refresh only the save revision behind an open editor; stale content must trigger a revision conflict rather than overwrite newer thread segments. - Joined rendition segments retain authored per-source text and media decisions in `source_overrides`, keyed by canonical Publication segment IDs. Project them into one provider output; never hydrate the flattened output as a first-source override. Missing source overrides inherit, explicit empty values omit, and legacy joined overrides remain a whole-output edit. Deduplicate output media by ID in canonical source order, retaining the first occurrence's item metadata and each source's authored selection. - Selected mentions store versioned UTF-8 byte spans with stable provider and authority identities beside their authored text. Editors are private adapters; never persist editor HTML or document JSON. Resolve canonical, independent and joined-source annotations through `posttext` and `publicationsource`, preserve plain-client compatibility, and preflight mutable identities across the entire thread before provider writes. Read `docs/development/publication-mentions.md` before changing these rules or editor adapters. - Reusable Workspace mentions snapshot their per-network mappings inside the selected identity. Library edits and deletions affect future insertions only. Resolve destination text through the shared mention projection for reads, readiness, text cards and provider-write plans; never persist generated text as an independent authorship override. - Shared polls belong to canonical segment `settings.poll`; destination choices are independent of text and media overrides. The shared composer shows a compact summary and edits common content in a cancellable dialog; account tabs own poll versions, supported voting settings, and unresolved-account notices. Text versions retain authored language without adding engagement prompts. Resolve through `services/publicationpoll` for persistence and delivery. Preserve explicit text/omit choices and legacy polls; see `docs/development/publication-polls.md` before changing poll storage or projection. - Social Set account formats and reusable destination/post settings are defaults for new publications. Copy them into renditions and rendition segments on create, let explicit post values win, and never rewrite existing publications when a set changes. Keep attachment-specific settings on the post. Preset editing and saving use the same account-resolved settings common to every media shape and authoring variant of the selected format; Automatic has no format-specific presets; Instagram and Pixelfed text-card style defaults are format-independent. Account-resolved settings are authoritative even when empty; use provider catalog fields only before account resolution. - Workflows owns automation discovery, templates, editing, and run inspection. Existing repost policies and executions stay in the repost service, retaining IDs, grants, snapshots, and per-post overrides. First comments remain destination settings; never duplicate either system into generic workflow runs. - Workflow node categories and symbols come from the shared workflow catalog. Use `workflows/node-icon.svelte` across the canvas, picker, and previews; category colors never replace labels or run-status indicators. - Workflow reference paths distinguish literal JSON keys with quoted brackets from nested dot paths across discovery, chips, validation, copying and execution. Preserve existing dot-path bindings; see `docs/development/workflows.md`. - Native post imports use the configured provider registry and canonical OAuth grant permissions. X has no import reader, even with an operator budget override. Keep imports in their read-only inventory, retain activation watermarks and unfinished cursors, reserve provider request costs before I/O, and fence checkpoints against disable or reactivation. See `docs/development/native-post-imports.md`. - Job acquisition increments `jobs.lease_generation`. Use that generation to fence worker writes, heartbeats and finalization. `locked_at` records liveness and changes during a healthy execution; `attempts` is a retry counter that can reset. Neither is the identity of a lease. - Persistent work uses database jobs rather than in-memory goroutines. Media crosses the `BlobStorage` boundary. Provider adapters live under `apps/server/internal/platform/`. - Meta comment collection follows outer and nested continuation pages through the shared bounded Graph walker. Share its request budget across one collection, validate continuation hosts, preserve reply parents and ownership, and retain typed recovery errors. A failed later page must fail collection rather than record a partial result as successful. - S3 download bodies follow the caller's cancellation and close lifecycle. Bound connection and response headers through the transport; never apply the short object-operation deadline to the entire media stream. - Workflows persist structured definitions and immutable run snapshots in `services/workflows/`; the canvas is a projection. Canvas placement is device-local, scoped to the Workspace and workflow, and must not change authored definitions or run snapshots. Native effects use publication, Builder, and provider-write owners with stable run/step identity. Read `docs/development/workflows.md` before changing admission, approval, recovery, destinations, canvas actions, editor history, recipes, custom tools, node tests, AI decisions, usage, or workflow credentials. Workflow destinations reuse the composer's Social Set controls; native publication and Builder creation own default snapshots. Stored Builder inspection remains actor- and Workspace-authorized without AI configuration; generation and mutation retain their runtime guards. JavaScript stays inside the bounded WASM adapter; HTTP and AI dispatch require a fenced durable receipt. - The binary roles are `all`, `web`, `worker`, and `migrate`. Self-hosted `all` auto-migrates; Hosted migrates once before starting `web` and `worker` against that schema. - Svelte code uses runes, the typed API client, and shared UI/page controls. Visible form fields use shared primitives. - Social post cards and page shells belong to `packages/social-preview`, shared by the composer and public tools. Account tabs supply editing snippets through the composer mutation owners; All stays shared and Full preview stays read-only. Canonical segment `settings.link` owns account URL choices resolved by `services/publicationlink`; preserve legacy URLs and exclude generated URI projections from authorship. Preview support is separate from publishing readiness. Composer text and preview paragraphs detect their own direction without changing stored text or surrounding controls. Keep layout responsive to its container and explicit appearance independent of the host theme; see `docs/development/social-previews.md` for the rendering contract and references. - Text-card rendering and capability planning share `internal/textcards`. Persist generated media in destination `output_media`, keep authored `media` separate, and preview saved output until relevant edits change it. Read `docs/development/social-previews.md` before changing conversion, snapshots, pagination, or Social Set card defaults. - Composer sync controls follow `docs/development/social-previews.md`. Read its inheritance contract before changing linked state or unlink/relink actions. - `bun run fallow` gates introduced dead code through the maintained audit JSON attribution and reports complexity separately with `health --report-only`. The thin gate adapter preserves full audit JSON and fails closed on tool or protocol errors; combined audit exit codes also enforce health thresholds. Repository build-script dependencies belong to root devDependencies and the Fallow tooling framework. - Frontend checks generate Paraglide declarations before `svelte-check`; source-only generated messages can hide diagnostics behind TypeScript's file-size limit. Turbo must forward `OPENPOST_PARAGLIDE_PRECOMPILED` so browser checks can reuse those declarations without Vite overwriting them. CI uses `check -- frontend-marketing` to prepare translations once for both readers; standalone scopes prepare their own output. - Shared `Select.Root` defaults to a scalar single selection. Pass `type="multiple"` only for array values. - The client-only app sets its initial scheme and canvas in `apps/web/src/app.html` before external resources load. Keep its storage key aligned with ModeWatcher; verify entry and reload with `tests/app/startup-theme.spec.ts`. - Reorder previews stay local to the view until drop. Commit through the owning editor or composer mutation once, preserve selection by key, and let Escape cancel without autosaving. Video Editor clip moves share visual tracks across clip kinds, retain linked audio timing, and reject locked, incompatible, or occupied targets. - PWA registration uses an absolute root URL through `SvelteKitPWA` and `pwa-manager.svelte`. Updates wait for open windows to close. Cache only public app resources; exclude API, authorization, query-bearing navigations, and original media. Test service workers against the production build with `tests/app/pwa.spec.ts`, not Vite dev. - App browser tests use full Chromium's headless backend. Fixed-size component fixtures set their own viewport; isolated files can share Chromium's previous viewport. Their servers disable external diagnostics and product telemetry regardless of inherited environment settings; diagnostics regressions use local HTTP receivers. PWA installability checks require an isolated temporary persistent profile because Chrome disallows installation in private contexts. - Authored color fields use `$lib/components/color-picker.svelte`. Keep canvas sampling, grading tools, CSS color expressions, and provider color categories in their specialized owners. - `@openpost/query-catalog` owns cache-safe remote reads across web and mobile. Mutations reconcile through its affected keys; each route owns one cold loading boundary and keeps cached state visible while refreshing. Media history snapshots retain only discovery controls, guard restoration by actor and Workspace, and reload results through the query owner. - Workspace navigation keeps Posts, Inbox, Analytics, and Media visible; More owns secondary tools. Calendar and List share the Posts destination and remembered view. Calendar keeps a compact date picker with a selected-day agenda on narrow screens; List owns status tabs and search. The List view also remembers its status tab; an explicit tab in the URL takes precedence. Workspace management belongs in the workspace switcher; personal preferences belong in the profile menu. Keep mobile More drill-in views within one menu rather than sideways flyouts. - Notification bells open the shared unread panel. Opening a notification marks it read before navigation; failed read updates leave it available to retry. The full page defaults to Unread and keeps Read and All history, with `?status=all` for the panel history link. Workspace shell owns notification polling once per active Workspace. - App page headers use `PageHeader` and the compact `data-app-title` scale, including List and Calendar. Use `headerActionLayout="inline"` when one compact action fits beside the title on phones. Keep page actions, section navigation, and filters outside content loading boundaries. Use `PageContainer`'s `navigation` snippet for persistent controls and `contentLayout="fill"` when the page owns scrolling; Settings skeletons describe only the selected panel. `navigation-progress.svelte` owns delayed BProgress feedback for SvelteKit navigation, never background queries or measured operation progress. - Native mobile tabs share `WorkspaceHeader`; keep repeated page titles and introductory copy out of it. Use `NativeText` for iOS display text so enlarged Dynamic Type owns the line box. Native analytics uses the shared query catalogue and server aggregates; never rank posts by aggregating only a destination page. - Mobile server, token, and Workspace persistence is one transaction boundary owned by `apps/mobile/src/lib/identity-store.ts`. Keep all three behind its queue and crash marker; a committed server change clears the server-scoped session. - Native media previews use `media-image.tsx` to resolve server-owned `/media/` URLs and carry the current bearer credential. Keep credentials off local and external image sources, and keep protected previews out of the disk cache. - Native attachment uploads measure the local file before reserving a signed upload. Picker metadata may describe the original instead of the exported file. Image pickers use original quality to preserve file formats and bytes. - Native platform marks use `SvgXml` and the generated `platform-marks.json` catalogue from `assets/logos/`; regenerate it with `scripts/generate-native-platform-marks.mjs` when canonical marks change. - Native dependency upgrades retain compatible Bun compiler patches at the new package versions and one installed copy of each native module. Refresh version-referenced overrides, then run the standalone mobile check. - `packages/plan-catalog` owns sellable plans, prices, and limits for marketing, signup, billing settings, and the generated Go catalog. Read `docs/development/billing-and-usage.md` before changing pricing, quotas, checkout, or first-Workspace confirmation. - API, CLI, MCP, and product surfaces share terms, authorization, and workspace boundaries. For a contract change, edit its source and regenerate every consumer. - Maintainer diagnostics send allowlisted error kinds and compiled app stack locations, never raw error messages or concrete browser routes. Preserve opt-out and privacy signals, and deploy receiver schema support before new senders. - OpenAPI declares session-cookie authentication for browser sessions and session-only security for admin operations that reject API tokens. A rejected session challenges with `WWW-Authenticate: Bearer error="invalid_token"`; app clients clear local session state only for that challenge, because action checks such as recent reauthentication also answer 401. - Cookie banners use direct Decline (all optional browser analytics off) and Accept (first-party analytics cookies) actions. Keep cookie-free analytics under More options, and public English copy in `@openpost/telemetry`; the app localizes the same choices. - Hosted waitlist admission uses `OPENPOST_HOSTED_WAITLIST_ENABLED`. Keep password registration and OIDC provisioning closed while it is enabled, including callbacks started earlier; existing accounts retain sign-in. See `docs/development/billing-and-usage.md` for reopening and notification recovery. - Put Huma request size limits on `huma.Operation.MaxBodyBytes`. Do not read and replace an HTTP request body before Huma, because Huma's body-read deadline can then cancel a long-running handler after the body is already buffered. - External application authorization is separate from social-provider OAuth. Keep delegated client identity, consent, grants, credentials, and scope policy in `apps/server/internal/services/externalapps/`; keep durable signed delivery in `apps/server/internal/services/externalwebhooks/`. - External application publication mutations require grants for every stored destination before mutation or idempotency replay, including destinations omitted or removed by the request. Validate newly supplied accounts separately. - MCP clients may request REST scopes from shared OAuth discovery. Keep their consent on the MCP path and show and submit only MCP scopes. Registered `op_app_` clients use delegated application consent. - AI features use maintained SDKs behind `apps/server/internal/ai/` and the shared model and configuration choices. - Publication Builder roles share the authoring rules and source/account context in `publicationbuilder/prompts.go` and the validated generation path in `generation.go`. Keep role prompts task-specific; author choices take precedence over creative advice, while source fidelity and native capability limits remain mandatory. Keep nonempty authored direction fields in native input state. Omit those fields from provider response schemas and restore their trimmed values before validation; models generate only unlocked choices. Drafts and review replacements use destination output limits and native text validation. Repair invalid generated output at most once per generation stage within the build deadline, retaining every call's usage; exhausted repairs fail validation. - Keep feature SVGs in `assets/brand/features/` for the README and public materials. Use recognizable silhouettes with transparent backgrounds and sparse dithering, without a Converge frame. The application uses the theme icon system for page, navigation, and action icons; do not render or distribute feature artwork to the app. Preserve Converge geometry: the app logo follows its theme's focal color, public marks use paired light/dark artwork through `ThemeImage`, and artwork with a colored background keeps its existing colors. - Keep marketing illustration colors in paired public light/dark tokens. Preserve its original green, blue, and lilac palette with the shared neutral public controls. Do not change authenticated organization themes to style public campaigns. - Modal scrims darken the page in both schemes. Keep their theme defaults independent of text colors and synchronize the web, server, and native built-in catalogs. - Keep the built-in theme catalog out of startup imports. Settings loads only the selected panel, through its existing cold loading boundary; failed module downloads must leave navigation usable and offer a page refresh. - Keep authenticated navigation and dialogs in `workspace-shell.svelte`, loaded once after sign-in. Public entry routes must not download that shell; retain its mounted instance across workspace navigation. - Unconfigured organizations start with the orange-brown Dither palette; saved organization and Workspace choices take precedence. Public profiles use the signed-in viewer's Workspace theme, including direct entry and reload, and use Dither for anonymous visitors. Anonymous app entry pages also use Dither. Workshop remains the complete recovery theme. Theme management reads unpublished drafts from the organization catalog; workspace assignments use published themes. Apply server-confirmed settings immediately and keep background refreshes outside the mutation busy state. - App branding belongs to `services/appbranding`, independently of theme manifests and content brand kits. Organization defaults and explicit workspace overrides share the query catalogue across web and native. Keep public entry screens and installed app identity OpenPost, scope runtime branding to the current actor and Workspace, and preserve uploaded artwork colors and proportions. See `docs/development/app-branding.md`. - Theme tests use the request-scoped application preview context and the existing theme runtime. Restore saved appearance on preview exit; persist the scheme only after assignment succeeds. - Theme chart tokens are categorical data colors. Keep `chart1` through `chart5` chromatic and pairwise distinct in every built-in scheme; reserve neutral gray for aggregated data outside the top series. - Dithered buttons share the binary Bayer mask and default 16% ink tint from `@openpost/dither`, including generated README SVGs. Native theme controls resolve a fixed ink and opacity around that default to satisfy contrast across authored palettes. Keep texture contrast between 1.18:1 and 1.8:1 and text at least 4.5:1 on both colors; hover and press change density only. - Dither rendering belongs to `@openpost/dither` across web, marketing, docs, and native mobile. Native controls import the DOM-free `@openpost/dither/paint` entry and render SVG patterns, with press feedback and no idle animation. Keep native content sections on the canvas instead of nesting cards. Measure surfaces to keep Bayer cells at 2 CSS pixels; hover changes density with no idle animation. Keep chart geometry and control semantics in their owners, validate composited action contrast, and preserve the package attribution. - Cloud Video Project copies create independent asset references with stable media IDs and shared originals in one transaction. Media status changes refresh every referencing project in the Workspace; wait for unlinked uploads before copying. - Render queues and completed exports use project export storage: browser storage scoped to the Workspace for Cloud Video Projects, the selected folder for local projects. Recording imports must verify their destination is still open before committing timeline changes. - Local folder permission loss disconnects the active Video Editor root synchronously. Enter reconnect using the mounted gate's folder identity, without waiting for IndexedDB reads. - Video audio stays embedded until detached through the timeline action. Persist audio ownership independently of edit links so unlinking, moving, or deleting detached audio cannot restore the video's sound. Recorder microphone audio belongs to the camera, or to the screen when no camera is selected; mix system and microphone audio into one recorded stream. - Recorder scratch writes append and flush in a dedicated OPFS worker, retaining the atomic-file fallback where synchronous access is unavailable. Acknowledged chunks must survive a lost tab. Finalization and preview preparation are progress states; recovery appears only outside an active recording handoff. - Screenshot templates own versioned structured documents in `lib/screenshot-templates/` and workspace drafts in `screenshot_template_designs`. Preview and browser PNG export use the same authored DOM; keep its appearance independent of the app theme and preserve Unicode shaping. Fixed frames must reject overflowing exports. Generated PNGs retain immutable `MediaGenerationRecipe` snapshots. Chat images and participant photos use workspace Media IDs; validate and lock their sources when saving, retain normalized draft and recipe references for the media lifecycle, and reject exports with unloaded images. Reuse image return tokens for composer attachment, and register the workspace switch guard before discarding unsaved edits. Memes use the same draft editor and library with their existing server renderer; keep AI browsing separate from authoring. Meme overlays and remake parents retain media references, including GIFs. Embedded editors must flush before dismissal or mode changes. - Image and Video Editor headers share `editor-header.svelte` for layout and theme surfaces. Each editor owns its save, history, navigation, and export behavior; keep save feedback visible at narrow widths. Editor property sections use the neutral panel surface; reserve hover and selection colors for interactive states. - Quick Cut and Video Editor share source-time speech and signal analysis in `lib/video-editor/audio/`. Keep cleanup in cancellable workers with bounded PCM chunks, and intersect removable ranges across retained audio channels and streams. Transcript engines own decoding and channel mixing; Quick Cut stores source words for cuts without creating subtitles. Cloud source transcripts are browser-local derived data scoped to the signed-in actor and Workspace; capture the storage target before asynchronous analysis and preserve local folder paths. Keep creation choices in `video-editor-choice.svelte` and source handoffs behind `media/workspace-source.ts`. - Repurpose clip suggestions persist immutable caller-supplied transcript snapshots in `services/repurpose/`. The source revision is a caller fingerprint, never proof of server-verified media contents. Resolve AI word indexes into source times, preserve actor/Workspace scope and generation-fenced cancellation, and require source-fingerprint review before editor changes. Suggestions never create or publish posts. - Repurpose reviews source-word suggestions explicitly before creating independent Quick Cut projects through existing asset and storage owners. Keep review receipts, adjusted bounds, and completed outputs scoped to the actor, Workspace, project, and source revision; keep derived cloud transcripts in the shared browser-local transcript owner.
Signals
- Stars
- 755
- Forks
- 102
- Open issues
- 6
- Contributors
- 18
- Last commit (this folder)
- Oct 24, 2026 (6 days ago)
- Last release
- Oct 22, 2026 (8 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- AGPL-3.0
- Repository
- github.com/getopenpost/openpost
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
Done for you
Rather not set it up yourself?
Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.
See how we build AI agents →Read the case studies
Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.
- launches shipped
- 50+
- launches shipped
- media placements
- 500+
- media placements
- founders on every account
- 2
- founders on every account
Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block
Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.
Get AGENTS.md · getopenpost/openpost running in your business
Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.
Cite this page
AGENTS.md · getopenpost/openpost. Agent Mart. https://agentmart.dev/templates/getopenpost-openpost-agents-md (last updated 2026-10-24)