keryx

module
v0.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 12, 2026 License: MIT

README

keryx

keryx · say it “KEH-riks” (/ˈkɛrɪks/) · from Greek κῆρυξ, "herald". Other readings — Modern Greek “KEE-riks”, biblical “KAY-roox”, Classical Attic /kɛ̂ːryks/ — are all equally welcome (about the name).

Turn a written post into a short narrated video and proclaim it across social platforms — on demand and on a schedule.

keryx is the content-marketing automation for phpboyscout.uk. It builds a 9:16 reel from a storyboard — text cards over generated/uploaded imagery, voice-clone narration, a tone-matched music bed — and publishes it to Instagram, YouTube, TikTok and LinkedIn. It runs interactively from the CLI (and a future web studio) and unattended from GitLab scheduled pipelines. Built on go-tool-base.

Status — generation pipeline works end-to-end; posting + the web studio are landing. The CLI builds and runs the full reel pipeline — storyboard → ElevenLabs voice-clone VO + music bed → Gemini cards/cover → an assembled 1080×1920 mp4 — and composes per-platform social copy. Instagram, YouTube and TikTok publishing are implemented; LinkedIn and the local web studio are in active development. Design source of truth: spec 0001.

For engineers — start here

Specs live on the project wiki, not in this repository — a spec is a point-in-time decision record, and keeping them here buried the living documentation beside them. docs/development/specs/index.md is the register.

Read For
spec 0001 The design: purpose, providers, themes, the authoring loop, persistence, roadmap. The source of truth.
0053 · 0054 · 0055 · 0056 The interface contracts — the studio wire format, what the studio owes a human, the CLI + MCP surfaces, and the shared workspace state. These supersede 0002.
AGENTS.md Ways of working for AI coding agents — architecture rules, the domain facts that must stay in parity, the traps.
docs/ User documentation, Diátaxis-tiered.

What it does

The fast path is one command — keryx reel make runs the whole gen→pick→build in a single pass (idempotent, asks before spending):

keryx reel new <slug> --bundle <content-dir>          # scaffold a reel workspace
keryx storyboard draft <post.md> -w <slug>            # AI-draft the board (or --inject <board.json>)
keryx reel make -w <slug> --theme editorial           # VO + music + cards + build, one pass (--dry-run to preview)
keryx social gen -w <slug> --platform instagram       # compose platform-appropriate caption/tags/link
keryx approve instagram -w <slug>                     # gate posting (required before any post)
keryx post instagram -w <slug>                        # post on demand
keryx post due                                        # CI/scheduled: post what's approved + due
keryx studio                                          # web UI: manage reels, author, preview, publish

To audition instead of taking the auto-pick, drive each stage yourself — every generative stage is generate candidates → pick the best (takes are kept):

keryx voice gen  -w <slug> --line 1 --takes 2         # VO takes for a card (clone)
keryx voice pick <line> <take> -w <slug>              #   … audition + select
keryx music gen  -w <slug> --takes 2 && keryx music pick <take> -w <slug>
keryx cards gen  -w <slug> --card 0 --theme editorial # per-card illustrations (or `cards set` your own)
keryx cards pick <card> <take> -w <slug>
keryx cover --theme clay --scene "…"                  # a themed cover bookend
keryx reel build -w <slug>                            # assemble the 9:16 reel (VO-timed, or --silent)

Config lives in the owning project. keryx reads a repo-root .keryx.yaml (themes, providers, non-secret settings), merged over the global ~/.keryx/config.yaml; env vars and flags still override both.

How it's built

  • Stateless tool, project owns the state. keryx holds no per-project data; reels, config/themes, and the schedule live in the owning project's git repo (here, the blog). Persistence is git; large media goes to a configurable store (S3/R2 default, GitLab packages / LFS optional).
  • Everything pluggable. Image/video/voice/music generation and rendering each sit behind a config-selected provider interface (Gemini / ElevenLabs / ffmpeg defaults). Posting is a Publisher per platform.
  • Config-driven themes. Palette, voice, music tone and per-card-illustration style live in config (~/.keryx/config.yaml global; a project-local .keryx.yaml deep-merges over it), not in code; editable live (hot reload) and via the studio.
  • Ported from working Python. The blog's scripts/gen-*.py are the reference implementation; Phase 1 ports them to Go at parity.

Develop

This project uses just:

just              # tidy, generate, build → bin/keryx
just test         # unit tests + coverage
just test-race    # race detector
just lint         # golangci-lint
just ci           # full local CI (tidy, generate, test, test-race, lint)
just docs-serve   # serve the docs site locally

CI runs on GitLab via the shared phpboyscout/cicd components (lint / test / security / goreleaser / pages), with releases cut by releaser-pleaser.

Install

go install gitlab.com/phpboyscout/keryx/cmd/keryx@latest

The main package is cmd/keryx, so the module path alone does not install anything. Pre-built archives are attached to each GitLab release.

Then write the configuration file — keryx refuses to run without one:

keryx init

Build order (posting)

Instagram → YouTube → TikTok → LinkedIn — Instagram is the only platform postable to your own account with no app review; the others have audit/partner lead times worth starting early (see the design spec on the wiki).

Licence

Copyright © Matt Cockayne.

Directories

Path Synopsis
cmd
keryx command
Activates OS keychain support by blank-importing the go-keyring-backed Backend.
Activates OS keychain support by blank-importing the go-keyring-backed Backend.
internal
authcmd
Package authcmd holds the auth command's non-Cobra logic.
Package authcmd holds the auth command's non-Cobra logic.
avatar
Package avatar resolves the named avatar registry (config `avatars.*`) and composes per-panel image prompts for the "actor" capability: a recurring character (the author, later co-authors) composited into reel panels via image-to-image, reacting to each beat.
Package avatar resolves the named avatar registry (config `avatars.*`) and composes per-panel image prompts for the "actor" capability: a recurring character (the author, later co-authors) composited into reel panels via image-to-image, reacting to each beat.
avatarcmd
Package avatarcmd is the shared logic behind `keryx avatar` (add/list/show): register a recurring character, auto-capture its likeness/style/palette via a one-off vision analysis (spec 0006 §4), and persist it to the config registry (avatars.*).
Package avatarcmd is the shared logic behind `keryx avatar` (add/list/show): register a recurring character, auto-capture its likeness/style/palette via a one-off vision analysis (spec 0006 §4), and persist it to the config registry (avatars.*).
certsource
Package certsource resolves keryx's TLS certificate source (spec 0027), shared by the studio HTTPS bind and the OAuth callback loopback.
Package certsource resolves keryx's TLS certificate source (spec 0027), shared by the studio HTTPS bind and the OAuth callback loopback.
chatgen
Package chatgen wires the GTB chat client for keryx's optional AI generation (storyboard draft, social copy).
Package chatgen wires the GTB chat client for keryx's optional AI generation (storyboard draft, social copy).
cliout
Package cliout adapts keryx commands to the GTB output model.
Package cliout adapts keryx commands to the GTB output model.
configstore
Package configstore assembles keryx's configuration — once (spec 0048).
Package configstore assembles keryx's configuration — once (spec 0048).
configtest
Package configtest builds in-memory config.Store values for tests.
Package configtest builds in-memory config.Store values for tests.
content
Package content is keryx's SSG-agnostic content source (spec 0033 §4).
Package content is keryx's SSG-agnostic content source (spec 0033 §4).
gen/elevenlabs
Package elevenlabs adapts ElevenLabs into keryx's voice and music provider seams (pkg/provider).
Package elevenlabs adapts ElevenLabs into keryx's voice and music provider seams (pkg/provider).
gen/gemini
Package gemini adapts Google's Gemini / Imagen into keryx's image provider seam (pkg/provider).
Package gemini adapts Google's Gemini / Imagen into keryx's image provider seam (pkg/provider).
gencache
Package gencache is keryx's content-addressed generation cache (R-GEN-8 / R-GLOBAL-9): a generated artefact set — a VO line's takes, a music bed, a card's illustrations — is keyed by a hash of its request (text/scene/prompt + all the settings that affect the output).
Package gencache is keryx's content-addressed generation cache (R-GEN-8 / R-GLOBAL-9): a generated artefact set — a VO line's takes, a music bed, a card's illustrations — is keyed by a hash of its request (text/scene/prompt + all the settings that affect the output).
gencmd
Package gencmd holds workspace-aware take generation for the authoring loop: generate N candidate takes from a workspace's storyboard into <kind>/takes/, to be auditioned and selected (internal/takes).
Package gencmd holds workspace-aware take generation for the authoring loop: generate N candidate takes from a workspace's storyboard into <kind>/takes/, to be auditioned and selected (internal/takes).
genutil
Package genutil holds small shared helpers for the generation commands (theme resolution from props, flag-default fallbacks, output paths).
Package genutil holds small shared helpers for the generation commands (theme resolution from props, flag-default fallbacks, output paths).
gitrepo
Package gitrepo is keryx's thin wrapper over GTB's pkg/vcs/repo — the single git layer for the studio (spec 0012).
Package gitrepo is keryx's thin wrapper over GTB's pkg/vcs/repo — the single git layer for the studio (spec 0012).
lexicon
Package lexicon reads and writes a project's pronunciation.yaml — the local, version-controlled source of truth for its pronunciation-dictionary rules (spec 0022 R-GEN-35).
Package lexicon reads and writes a project's pronunciation.yaml — the local, version-controlled source of truth for its pronunciation-dictionary rules (spec 0022 R-GEN-35).
lexiconcmd
Package lexiconcmd is the shared logic behind `keryx voice lexicon` — the list/add/sync verbs that manage a project's pronunciation.yaml and push it to the active voice provider's dictionary (spec 0022 R-GEN-35).
Package lexiconcmd is the shared logic behind `keryx voice lexicon` — the list/add/sync verbs that manage a project's pronunciation.yaml and push it to the active voice provider's dictionary (spec 0022 R-GEN-35).
mediastore
Package mediastore syncs a reel workspace's MEDIA to the configured object store.
Package mediastore syncs a reel workspace's MEDIA to the configured object store.
postcmd
Package postcmd is the posting state machine behind `keryx approve` and `keryx post`/`post all`/`post due` (spec 0002 §3.3, R-POST/R-AUTH).
Package postcmd is the posting state machine behind `keryx approve` and `keryx post`/`post all`/`post due` (spec 0002 §3.3, R-POST/R-AUTH).
publish/instagram
Package instagram is the Instagram Reels publisher (spec 0001 §4, build-order #1 — own-account posting under Standard Access, no App Review).
Package instagram is the Instagram Reels publisher (spec 0001 §4, build-order #1 — own-account posting under Standard Access, no App Review).
publish/linkedin
`keryx auth linkedin` — the interactive LinkedIn OAuth flow (spec 0009 §3).
`keryx auth linkedin` — the interactive LinkedIn OAuth flow (spec 0009 §3).
publish/tiktok
`keryx auth tiktok` — the interactive TikTok OAuth flow (spec 0008 §3).
`keryx auth tiktok` — the interactive TikTok OAuth flow (spec 0008 §3).
publish/youtube
Package youtube is the YouTube (Shorts) publisher + auth adapter (spec 0007).
Package youtube is the YouTube (Shorts) publisher + auth adapter (spec 0007).
reel
Package reel holds the deterministic core of the reel pipeline: the storyboard schema and validation, the VO-driven timing maths, orphan-controlled text wrapping, and accent-word parsing.
Package reel holds the deterministic core of the reel pipeline: the storyboard schema and validation, the VO-driven timing maths, orphan-controlled text wrapping, and accent-word parsing.
reelcmd
Package reelcmd holds the shared logic behind the `keryx reel` workspace subcommands (new/list/rename/duplicate/rm/link).
Package reelcmd holds the shared logic behind the `keryx reel` workspace subcommands (new/list/rename/duplicate/rm/link).
refreshcmd
Package refreshcmd orchestrates `keryx auth refresh` (spec 0010): it builds the configured write-back + notifier backends, fans out across the enabled platforms' refreshers, fires alerts, and reports per-platform status.
Package refreshcmd orchestrates `keryx auth refresh` (spec 0010): it builds the configured write-back + notifier backends, fans out across the enabled platforms' refreshers, fires alerts, and reports per-platform status.
render/afmpeg
Package afmpeg renders a keryx timeline by driving FFmpeg compiled to WebAssembly (the ffmpeg-wasi engine) through the afmpeg library — no system ffmpeg binary, entirely in memory.
Package afmpeg renders a keryx timeline by driving FFmpeg compiled to WebAssembly (the ffmpeg-wasi engine) through the afmpeg library — no system ffmpeg binary, entirely in memory.
render/cards
Package cards renders a single storyboard card to a PNG — block mode (a line over a solid palette background, optional cover bookend) and overlay mode (a full-bleed media panel + bottom scrim + overlaid line).
Package cards renders a single storyboard card to a PNG — block mode (a line over a solid palette background, optional cover bookend) and overlay mode (a full-bleed media panel + bottom scrim + overlaid line).
render/ffmpeg
Package ffmpeg renders a keryx timeline into a finished MP4 by shelling out to ffmpeg — the default Renderer adapter (spec §3.4).
Package ffmpeg renders a keryx timeline into a finished MP4 by shelling out to ffmpeg — the default Renderer adapter (spec §3.4).
render/progress
Package progress parses ffmpeg's `-progress` output — the machine-readable key=value blocks ffmpeg emits (one `key=value` per line, a block terminated by `progress=continue|end`) when run with `-progress pipe:N`.
Package progress parses ffmpeg's `-progress` output — the machine-readable key=value blocks ffmpeg emits (one `key=value` per line, a block terminated by `progress=continue|end`) when run with `-progress pipe:N`.
render/silence
Package silence parses ffmpeg's silencedetect filter log — the shared piece both render backends (shell-out ffmpeg and in-memory afmpeg) use to surface internal silences for VO take screening (spec 0023).
Package silence parses ffmpeg's silencedetect filter log — the shared piece both render backends (shell-out ffmpeg and in-memory afmpeg) use to surface internal silences for VO take screening (spec 0023).
social
Package social models the per-platform social set (social.json) — the supporting copy for each platform plus its posting status/schedule/result (contract 0002 §4.4).
Package social models the per-platform social set (social.json) — the supporting copy for each platform plus its posting status/schedule/result (contract 0002 §4.4).
socialcmd
Package socialcmd is the shared logic behind `keryx social` (set/show/gen).
Package socialcmd is the shared logic behind `keryx social` (set/show/gen).
spend
Package spend is keryx's shared generation-cost model (spec 0013 §5, 0031 §5): the per-unit price estimate every surface agrees on (CLI, studio, MCP), and the spend guard threshold that gates a runaway batch.
Package spend is keryx's shared generation-cost model (spec 0013 §5, 0031 §5): the per-unit price estimate every surface agrees on (CLI, studio, MCP), and the spend guard threshold that gates a runaway batch.
takes
Package takes manages candidate takes and the selected slot for a reel workspace (spec 0001 §3.2 "take management"; contract 0002 §2, R-WS-1).
Package takes manages candidate takes and the selected slot for a reel workspace (spec 0001 §3.2 "take management"; contract 0002 §2, R-WS-1).
takescmd
Package takescmd is the shared logic behind the take-management verbs (voice/music/cards pick, cards set, reel prune).
Package takescmd is the shared logic behind the take-management verbs (voice/music/cards pick, cards set, reel prune).
textleak
Package textleak screens generated card illustrations for accidental text (R-GEN-26): image models sometimes render stray letters/words into the art, which look wrong in a promo reel.
Package textleak screens generated card illustrations for accidental text (R-GEN-26): image models sometimes render stray letters/words into the art, which look wrong in a promo reel.
theme
Package theme models keryx's config-driven aesthetic profiles.
Package theme models keryx's config-driven aesthetic profiles.
themecmd
Package themecmd holds the shared logic behind the `keryx theme` subcommands (list/show/add/edit/rm).
Package themecmd holds the shared logic behind the `keryx theme` subcommands (list/show/add/edit/rm).
themestore
Package themestore assembles the config store themes resolve through (spec 0042 §3.6, absorbing spec 0046 step 3).
Package themestore assembles the config store themes resolve through (spec 0042 §3.6, absorbing spec 0046 step 3).
workspace
Package workspace models a reel workspace on disk — the resumable unit of the authoring loop (spec 0001 §3.2, contract 0002 §2).
Package workspace models a reel workspace on disk — the resumable unit of the authoring loop (spec 0001 §3.2, contract 0002 §2).
mocks
pkg
accounts
Package accounts owns ~/.keryx/accounts.yaml — the user-scoped file that holds platform credentials and nothing else (spec 0042 §3.4, D6).
Package accounts owns ~/.keryx/accounts.yaml — the user-scoped file that holds platform credentials and nothing else (spec 0042 §3.4, D6).
cmd/reel/make
Package make is `keryx reel make`: one-command reel orchestration (spec 0020).
Package make is `keryx reel make`: one-command reel orchestration (spec 0020).
credscan
Package credscan finds literal credentials sitting in a config file.
Package credscan finds literal credentials sitting in a config file.
notify
Package notify is keryx's pluggable alert seam (spec 0010 §6): a Notifier interface with config-selected backends (none, webhook, …).
Package notify is keryx's pluggable alert seam (spec 0010 §6): a Notifier interface with config-selected backends (none, webhook, …).
oauth
Package oauth is keryx's provider-neutral OAuth *capture* layer for the CLI: it builds nothing protocol-specific itself, but given an already-built authorize URL and a resolved redirect URI it runs the local callback server (+ stdin paste fallback) and returns the authorization code.
Package oauth is keryx's provider-neutral OAuth *capture* layer for the CLI: it builds nothing protocol-specific itself, but given an already-built authorize URL and a resolved redirect URI it runs the local callback server (+ stdin paste fallback) and returns the authorization code.
objectstore
Package objectstore is the studio/CLI seam to a versioned object store (spec 0039): workspace MEDIA lives in a bucket, git keeps the authored state plus a media.lock manifest pinning each file's content hash and object version.
Package objectstore is the studio/CLI seam to a versioned object store (spec 0039): workspace MEDIA lives in a bucket, git keeps the authored state plus a media.lock manifest pinning each file's content hash and object version.
objectstore/cdk
Package cdk is the multi-backend object-store adapter (spec 0040): one implementation over gocloud.dev/blob, which speaks S3, Google Cloud Storage, Azure Blob, the local filesystem and memory through a single portable API.
Package cdk is the multi-backend object-store adapter (spec 0040): one implementation over gocloud.dev/blob, which speaks S3, Google Cloud Storage, Azure Blob, the local filesystem and memory through a single portable API.
objectstore/s3
Package s3 is the S3 object-store adapter (spec 0039 §3.4): keryx's default storage backend, registered as storage.provider "s3".
Package s3 is the S3 object-store adapter (spec 0039 §3.4): keryx's default storage backend, registered as storage.provider "s3".
provider
Package provider defines keryx's pluggable backend seams.
Package provider defines keryx's pluggable backend seams.
publish
Package publish is the posting seam: one narrow Publisher interface per social platform (spec 0001 §4.1) plus a name-keyed registry so each adapter (internal/publish/<platform>) lands independently and `post all` fans out across the enabled platforms.
Package publish is the posting seam: one narrow Publisher interface per social platform (spec 0001 §4.1) plus a name-keyed registry so each adapter (internal/publish/<platform>) lands independently and `post all` fans out across the enabled platforms.
refresh
Package refresh is keryx's token-refresh seam (spec 0010): a Refresher per platform plus a name-keyed registry, mirroring pkg/publish.
Package refresh is keryx's token-refresh seam (spec 0010): a Refresher per platform plus a name-keyed registry, mirroring pkg/publish.
studio
Package studio serves keryx's local web UI (spec 0011): a single-user web app bound to localhost by default (R-API-3), serving the embedded Svelte SPA plus a thin /api/v1 surface whose handlers map 1:1 to CLI workspace operations.
Package studio serves keryx's local web UI (spec 0011): a single-user web app bound to localhost by default (R-API-3), serving the embedded Svelte SPA plus a thin /api/v1 surface whose handlers map 1:1 to CLI workspace operations.
test
e2e/steps
Package steps holds the keryx BDD end-to-end suite: Gherkin features in /features driven against a compiled keryx binary.
Package steps holds the keryx BDD end-to-end suite: Gherkin features in /features driven against a compiled keryx binary.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL