Skip to content

build: switch to BYK/opencode fork and pin @loreai plugin to @latest - #3

Merged
MathurAditya724 merged 7 commits into
mainfrom
chore/pin-lore-plugin-latest
Apr 29, 2026
Merged

build: switch to BYK/opencode fork and pin @loreai plugin to @latest#3
MathurAditya724 merged 7 commits into
mainfrom
chore/pin-lore-plugin-latest

Conversation

@MathurAditya724

@MathurAditya724 MathurAditya724 commented Apr 29, 2026

Copy link
Copy Markdown
Member

Summary

  • Build OpenCode from source against the BYK/opencode fork at the byk/cumulative branch instead of installing the upstream prebuilt binary via curl https://opencode.ai/install.
  • Append @latest to the @loreai/opencode plugin spec in opencode-user-config.json so it re-resolves to the newest published version on every container start.

Why the fork

byk/cumulative carries fixes that aren't yet in upstream:

  • Question dock: tap-to-collapse, restored scroll, prevent auto-scroll on focus, render text as markdown.
  • Plan mode: deny plan_exit / plan_enter in subagent sessions, render plan content as markdown in the exit prompt, guard against empty plans.
  • DB: enable auto-vacuum + periodic maintenance.

The fork has no release feed (no GitHub releases, no published npm package — its own install script even hardcodes the upstream anomalyco/opencode releases endpoint), so we can't curl a binary; we have to build with bun run build --single inside the downloader stage.

Build args

The opencode source is parameterised so it's a one-flag change to swap back to upstream or pin a SHA:

docker build \
  --build-arg OPENCODE_REPO=https://github.com/anomalyco/opencode.git \
  --build-arg OPENCODE_REF=dev \
  -t my-opencode .

Defaults: BYK/opencode @ byk/cumulative.

Tradeoffs

  • No auto-update. Upstream opencode self-updates on launch; this build pins whatever HEAD was at image build time. Rebuild to pick up new fork commits. (The @loreai plugin still re-resolves on each start because of the @latest change.)
  • Slower build / larger downloader stage. bun install over the monorepo (AWS SDK, Drizzle, AI SDKs, opentui, etc.) plus a bun build step replaces a single curl. Build time goes from seconds to minutes. Final image size is unaffected — the build artifacts only live in the discarded downloader stage.
  • Branch HEAD is mutable. byk/cumulative is a personal working branch with no stability promise. Override OPENCODE_REF to a SHA if you need reproducibility.

Adds Lore (https://github.com/BYK/loreai), a memory plugin for OpenCode that
replaces compaction with incremental distillation, preserving operational
details (file paths, errors, decisions) across long sessions and persisting
curated knowledge to a local SQLite store.
Removes OPENCODE_SERVER_PASSWORD and OPENCODE_SERVER_USERNAME from the
template and the README env-vars table. HTTP basic auth re-prompts
constantly on mobile browsers (especially iOS Safari) because the
credential is only cached in browser memory and there is no persistent
session cookie. Replace it with guidance to front the public hostname
with Cloudflare Access, which issues a long-lived CF_Authorization
cookie that mobile keeps across app kills and reboots.
The README's Auth section already covers this; no need for a duplicated
comment in the env template.
…-latest

# Conflicts:
#	opencode-user-config.json
Replace the prebuilt binary install (curl https://opencode.ai/install)
with a from-source build of the BYK/opencode fork at the byk/cumulative
branch. That branch carries question-dock UX, plan-mode guard, and
db-perf fixes not yet in upstream, and it has no release feed of its
own, so we have to clone and 'bun run build --single' inside the
downloader stage.

Build is gated by OPENCODE_REPO / OPENCODE_REF build args so swapping
back to upstream (or pinning a SHA) is a one-flag change. Adds git,
build-essential, python3, and pkg-config to the downloader stage for
the bun install + native module compilation.
@MathurAditya724 MathurAditya724 changed the title chore: pin @loreai/opencode plugin to @latest build: switch to BYK/opencode fork and pin @loreai plugin to @latest Apr 29, 2026
Runs on PRs and pushes to main when the Dockerfile or its inputs change.
Single-platform (linux/amd64), no push — purely a build-time smoke test
so the bun-from-source opencode build doesn't silently break before
hitting Railway. Uses GHA layer cache (mode=max) to keep iterative
Dockerfile edits cheap.
@MathurAditya724
MathurAditya724 merged commit 76995cf into main Apr 29, 2026
1 check passed
@MathurAditya724
MathurAditya724 deleted the chore/pin-lore-plugin-latest branch April 29, 2026 21:34
MathurAditya724 added a commit that referenced this pull request May 1, 2026
- opencode-webhooks README: replace stale `x-email-from` header reference with JSON `from` field (finding #1).
- http.ts: rewrite MAX_BODY_BYTES comment (no longer about RFC822); add MAX_EMAIL_BODY_BYTES = 64 KB and an optional maxBytes arg to readBodyBytes; email handler now uses the tighter cap (finding #2).
- cloudflare-email-worker README: note that a malformed regex literal in ALLOWED_SENDERS will throw at module init and the worker won't start (finding #3).
- email handler: parseEmailEvent's `str` now throws on non-string for required fields (from/to/subject/message_id) so the 400 detail names the offending field instead of misleading 'missing' messages (finding #4).
- Test gap for email identity fallback chain tracked in #14; no tests added in this commit (finding #5).
MathurAditya724 added a commit that referenced this pull request May 1, 2026
… SIDECAR_URL → WEBHOOK_URL (#13)

* refactor(email-worker): wrangler.json, inline ALLOWED_SENDERS, rename SIDECAR_URL → WEBHOOK_URL

- Replace wrangler.toml with wrangler.json (with $schema reference for
  editor validation). TOML and JSON are both first-class wrangler
  config formats; JSON keeps the worker package consistent with the
  rest of the repo's config files (package.json, tsconfig.json,
  webhooks.json).
- Move ALLOWED_SENDERS out of wrangler vars and into a top-level
  TypeScript const at the head of src/index.ts. The allowlist is
  PR-reviewed code now (typed as readonly string[]), compiled once at
  module load (zero per-request parse overhead), and a malformed regex
  fails the deploy instead of silently dropping at runtime. The Env
  shape no longer needs an ALLOWED_SENDERS field.
- Rename SIDECAR_URL → WEBHOOK_URL in wrangler.json vars, the Env
  interface, and the fetch call. 'Sidecar' was misleading anyway —
  the plugin is in-process with opencode, not a sidecar process.
  WEBHOOK_URL clearly names what it points at: the plugin's
  /webhooks/email endpoint.

* feat(email): worker becomes dumb pipe — unconditional forward + JSON event

The Cloudflare Email Worker now does two things per inbound email:

  1. message.forward(env.FORWARD_TO) unconditionally (if set), so every
     email reaches the operator's real inbox preserving DKIM. Wrapped
     in try/catch so a misconfigured FORWARD_TO doesn't block webhook
     dispatch — failure is logged loudly and we continue.
  2. If the From address is in ALLOWED_SENDERS, build a small JSON
     event from the headers we route on (from, to, subject,
     message_id, in_reply_to, references, list_id, x_github_reason,
     x_github_sender), HMAC-sign it, and POST as application/json to
     WEBHOOK_URL.

The worker no longer parses RFC822 in the plugin path — it just hands
Cloudflare's already-parsed headers to the plugin verbatim. The body
is never sent at all (it never was used; canonical state comes from
the GitHub API).

Plugin side:
- handlers/email.ts: reads req.json() instead of parsing RFC822;
  validates the event shape; everything downstream (identity, synth,
  dispatch) is unchanged.
- email/identity.ts: accepts the EmailEvent JSON shape instead of an
  EmailHeaders object. Same regex matchers; same in-reply-to /
  references fallback chain.
- email/synthesize.ts: reads metadata directly from the event object.
- email/parse.ts: deleted (no more RFC822 parsing).

Other changes:
- wrangler.json: added FORWARD_TO var (optional) and
  observability.logs.enabled = true so 'wrangler tail' and the
  Cloudflare dashboard show structured logs.
- READMEs: updated wire format, architecture diagrams, failure-mode
  table on the worker side.

Verified: bun run typecheck passes for both packages; wrangler deploy
--dry-run accepts the new config with both vars bound.

* fix: review findings on PR #13 (dumb-pipe + wrangler.json)

- opencode-webhooks README: replace stale `x-email-from` header reference with JSON `from` field (finding #1).
- http.ts: rewrite MAX_BODY_BYTES comment (no longer about RFC822); add MAX_EMAIL_BODY_BYTES = 64 KB and an optional maxBytes arg to readBodyBytes; email handler now uses the tighter cap (finding #2).
- cloudflare-email-worker README: note that a malformed regex literal in ALLOWED_SENDERS will throw at module init and the worker won't start (finding #3).
- email handler: parseEmailEvent's `str` now throws on non-string for required fields (from/to/subject/message_id) so the 400 detail names the offending field instead of misleading 'missing' messages (finding #4).
- Test gap for email identity fallback chain tracked in #14; no tests added in this commit (finding #5).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant