monorepo wit docs
This commit is contained in:
parent
88ddcfba39
commit
e3e4d1823d
43 changed files with 1585 additions and 29 deletions
21
docs/pages/concepts/architecture.md
Normal file
21
docs/pages/concepts/architecture.md
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
title: Architecture
|
||||
description: How feeds, targets, state, and flow dispatch fit together.
|
||||
---
|
||||
|
||||
# Architecture
|
||||
|
||||
Patch has three runtime pieces:
|
||||
|
||||
- The HTTP server exposes health and admin flow endpoints.
|
||||
- The feed poller reads configured upstream feeds on an interval.
|
||||
- The JSONL store keeps feed signals, fork-sync jobs, flow events, and dispatch
|
||||
outcomes under `DATA_DIR`.
|
||||
|
||||
The poller does not know how to complete product-specific work. It only turns a
|
||||
feed entry into a normalized signal and follows the target configured for that
|
||||
source.
|
||||
|
||||
Flow targets create a generic `FlowEvent` and use the shared flow client. That
|
||||
client gives Patch the same contract in local development and in HTTP-backed
|
||||
service mode.
|
||||
17
docs/pages/concepts/flow-boundary.md
Normal file
17
docs/pages/concepts/flow-boundary.md
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
title: Flow boundary
|
||||
description: What Patch owns and what codex-flow packages own.
|
||||
---
|
||||
|
||||
# Flow boundary
|
||||
|
||||
Patch owns upstream observation. It knows about feeds, source ids, feed state,
|
||||
and dispatch attempts.
|
||||
|
||||
codex-flow owns execution. Flow packages match `FlowEvent.type` and payload
|
||||
schema, run Bun or gated Code Mode steps, and emit `FLOW_RESULT`.
|
||||
|
||||
Product completion stays outside Patch. For example, OpenAI Codex release
|
||||
automation should decide how to update a fork, open a branch, ask for review, or
|
||||
publish a result. Patch only dispatches the upstream release event and records
|
||||
the dispatch outcome.
|
||||
260
docs/pages/concepts/forgejo-forking-problem-space.md
Normal file
260
docs/pages/concepts/forgejo-forking-problem-space.md
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
---
|
||||
title: Forgejo forking problem space
|
||||
description: Historical analysis for tracking and possibly forking Forgejo from Patch signals.
|
||||
---
|
||||
|
||||
# Forgejo Forking Problem Space
|
||||
|
||||
Date: 2026-05-12
|
||||
|
||||
## Current Setup
|
||||
|
||||
Created a jojo.build mirror:
|
||||
|
||||
- Repo: https://jojo.build/peezy-tech/jojo
|
||||
- SSH: `ssh://git@jojo.build/peezy-tech/jojo.git`
|
||||
- Upstream: `https://codeberg.org/forgejo/forgejo.git`
|
||||
- Default branch: `forgejo`
|
||||
- Mirror interval: `8h`
|
||||
|
||||
This is currently a mirror, not a working fork branch. That is a good starting
|
||||
point for source inspection and tracking upstream movement. It is not yet a good
|
||||
place for custom patches, because mirror updates are expected to follow upstream.
|
||||
|
||||
## Executive Summary
|
||||
|
||||
Forking Forgejo is feasible, but it is not a small maintenance commitment.
|
||||
Forgejo is a full Go web application with a substantial frontend build,
|
||||
database migrations, templates, Actions integration, SSH/HTTP Git serving,
|
||||
packages, OAuth2, and admin surfaces. A fork is reasonable only if the desired
|
||||
customization cannot be achieved through supported configuration, OIDC, reverse
|
||||
proxy auth, static assets, or template overrides.
|
||||
|
||||
For SIWE specifically, the preferred order remains:
|
||||
|
||||
1. Use SIWE through an external OpenID Connect provider.
|
||||
2. Use a trusted reverse proxy that performs SIWE and passes identity headers.
|
||||
3. Fork Forgejo only if we need first-class SIWE UX or native account semantics.
|
||||
|
||||
## Upstream Release Cadence
|
||||
|
||||
Forgejo stable releases are published quarterly. LTS releases are published in
|
||||
the first quarter of each year and receive critical bugfix/security support for
|
||||
one year and three months. The current LTS line is v15.0, released 2026-04-16
|
||||
and supported until 2027-07-15.
|
||||
|
||||
Implication: a fork has to either:
|
||||
|
||||
- Track every quarterly release and absorb breaking changes often.
|
||||
- Track only LTS releases and accept slower access to new Forgejo features.
|
||||
- Track upstream `forgejo` continuously, which maximizes merge churn.
|
||||
|
||||
For a production instance, an LTS-based fork is the most conservative option.
|
||||
|
||||
## What A Fork Would Own
|
||||
|
||||
At minimum, a maintained fork owns:
|
||||
|
||||
- A source branch policy.
|
||||
- CI for Go, frontend, templates, linting, and tests.
|
||||
- Binary or container image builds.
|
||||
- A release/version naming scheme.
|
||||
- Security patch intake.
|
||||
- Upgrade rehearsals against jojo.build data.
|
||||
- Documentation for local patches.
|
||||
- A rollback path to upstream Forgejo.
|
||||
|
||||
The risky areas are not only code conflicts. They are also database migrations,
|
||||
template changes, auth/session behavior, Actions behavior, and generated assets.
|
||||
|
||||
## Build And Test Surface
|
||||
|
||||
Forgejo source includes:
|
||||
|
||||
- `go.mod` for the backend.
|
||||
- `package.json` and `webpack.config.js` for frontend assets.
|
||||
- `Makefile` for build/test targets.
|
||||
- `Dockerfile` and `Dockerfile.rootless`.
|
||||
- Published release notes in `release-notes-published/`.
|
||||
|
||||
Official build docs require Go, Node.js/npm, and `make`. Older docs mention Go
|
||||
1.22+ and Node 20+, but we should verify exact versions from the branch we pin
|
||||
before building production artifacts.
|
||||
|
||||
Initial local validation target should be:
|
||||
|
||||
```bash
|
||||
make help
|
||||
make deps-frontend
|
||||
make frontend
|
||||
make test
|
||||
make build
|
||||
```
|
||||
|
||||
Exact target names need confirmation from the current Makefile before scripting.
|
||||
|
||||
## Auth Extension Surface
|
||||
|
||||
Forgejo has configurable auth sources:
|
||||
|
||||
- Local database auth.
|
||||
- LDAP via BindDN.
|
||||
- LDAP simple auth.
|
||||
- SMTP.
|
||||
- PAM.
|
||||
- OAuth2.
|
||||
- OpenID Connect.
|
||||
- OpenID.
|
||||
- Reverse proxy header auth.
|
||||
|
||||
From source inspection, auth source types are compiled into the application.
|
||||
OAuth2 providers are registered in Go during init via an internal Goth provider
|
||||
registry. That registry is useful for patching Forgejo, but it is not an
|
||||
external plugin API.
|
||||
|
||||
Native SIWE would likely require one of these approaches:
|
||||
|
||||
- Add a first-class OAuth2/OIDC provider if SIWE is presented as OIDC.
|
||||
- Add a custom auth flow and routes for EIP-4361 challenge/signature handling.
|
||||
- Add account-linking fields for wallet addresses and ENS-derived display data.
|
||||
- Add admin settings and migration(s) if wallet addresses become persisted
|
||||
first-class identities.
|
||||
|
||||
The more native the SIWE behavior, the more the fork touches security-critical
|
||||
surface: sessions, CSRF, account linking, auto-registration, 2FA bypass rules,
|
||||
and recovery flows.
|
||||
|
||||
## SIWE Fork Design Questions
|
||||
|
||||
Before writing code, resolve these:
|
||||
|
||||
- Is an Ethereum address the canonical Forgejo username, an external account
|
||||
identifier, or merely a linked credential?
|
||||
- Do users need email addresses?
|
||||
- Can a wallet create a new Forgejo account automatically?
|
||||
- How are lost wallets handled?
|
||||
- Can one Forgejo account link multiple wallets?
|
||||
- Is ENS only display metadata, or does it influence identity?
|
||||
- Are smart-contract wallets/EIP-1271 required?
|
||||
- Which chains are accepted?
|
||||
- Does SIWE bypass local 2FA, complement it, or become a second factor?
|
||||
- How do Git over HTTPS, SSH keys, access tokens, and API auth map to wallet
|
||||
sign-in?
|
||||
|
||||
These questions matter more than the login button. Forgejo identity is used by
|
||||
Git, issues, packages, Actions, API tokens, and admin permissions.
|
||||
|
||||
## Fork Strategies
|
||||
|
||||
### Strategy A: No Fork
|
||||
|
||||
Use config, OIDC, reverse proxy auth, and supported UI customization.
|
||||
|
||||
Best for:
|
||||
|
||||
- Branding.
|
||||
- Trusted SIWE/OIDC experiment.
|
||||
- Avoiding security patch ownership.
|
||||
|
||||
Risk:
|
||||
|
||||
- Less native UX.
|
||||
- Identity model constrained by Forgejo's existing auth flows.
|
||||
|
||||
### Strategy B: Patch Branch On LTS
|
||||
|
||||
Create a branch like `jojo/v15.0` from the current LTS tag, maintain a minimal
|
||||
patch stack, and periodically rebase or merge v15.0 patch releases.
|
||||
|
||||
Best for:
|
||||
|
||||
- Production stability.
|
||||
- Small, well-contained changes.
|
||||
- Predictable security patch intake.
|
||||
|
||||
Risk:
|
||||
|
||||
- Larger jumps when moving to the next LTS.
|
||||
- Backport work if desired features land in newer stable releases.
|
||||
|
||||
### Strategy C: Patch Branch On Upstream `forgejo`
|
||||
|
||||
Maintain `jojo/forgejo` on top of upstream development.
|
||||
|
||||
Best for:
|
||||
|
||||
- Contributing changes upstream.
|
||||
- Early access to Forgejo improvements.
|
||||
|
||||
Risk:
|
||||
|
||||
- Highest churn.
|
||||
- Bad fit for production unless we have strong CI and staging.
|
||||
|
||||
### Strategy D: Hard Product Fork
|
||||
|
||||
Rename/rebrand deeply, ship independent releases, and diverge freely.
|
||||
|
||||
Best for:
|
||||
|
||||
- Building a distinct forge product.
|
||||
|
||||
Risk:
|
||||
|
||||
- Largest maintenance burden.
|
||||
- Security, release, migration, and support responsibilities become ours.
|
||||
|
||||
This should be avoided unless jojo.build becomes a product-level Forgejo
|
||||
distribution.
|
||||
|
||||
## Recommended Path
|
||||
|
||||
Use the mirror as the upstream intake point. Do not customize the mirror branch.
|
||||
|
||||
Next create a working fork branch only when we have a concrete patch to test:
|
||||
|
||||
- `jojo/v15.0` from the latest v15.0.x tag for production-minded patches.
|
||||
- `jojo/forgejo` from upstream `forgejo` for exploratory upstreamable patches.
|
||||
|
||||
For SIWE, first prototype without a Forgejo fork:
|
||||
|
||||
1. Configure a SIWE OIDC provider against a test Forgejo instance.
|
||||
2. Test user creation, account linking, logout, API tokens, Git over HTTPS, and
|
||||
SSH key management.
|
||||
3. Separately test reverse proxy header auth with a toy trusted auth service.
|
||||
4. Only fork if those approaches fail on essential UX or identity semantics.
|
||||
|
||||
## Maintenance Checklist For Any Fork
|
||||
|
||||
- Track upstream release notes and security announcements.
|
||||
- Keep a patch inventory with rationale and owner.
|
||||
- Rebase/merge upstream into a staging branch first.
|
||||
- Run full build and test suite.
|
||||
- Run upgrade rehearsal against a copy of production data.
|
||||
- Smoke test login, repo browsing, Git SSH, Git HTTPS, Actions, packages,
|
||||
mirrors, and admin pages.
|
||||
- Keep a rollback artifact for the previous known-good binary/container.
|
||||
- Document every app.ini setting required by the fork.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Is jojo.build currently installed from binary, container, package manager, or
|
||||
local build?
|
||||
- How is production deployment currently rolled out and rolled back?
|
||||
- Do we want custom patches to be private indefinitely, or upstreamable?
|
||||
- Would SIWE be required for all users, optional, or only for selected orgs?
|
||||
- Is the target experience "login with wallet" or broader onchain identity?
|
||||
- Are we willing to run an external IdP such as a SIWE OIDC provider?
|
||||
|
||||
## Sources Consulted
|
||||
|
||||
- Forgejo mirror created from `https://codeberg.org/forgejo/forgejo.git`.
|
||||
- Forgejo auth docs: https://forgejo.org/docs/v11.0/user/authentication/
|
||||
- Forgejo OAuth2 provider docs: https://forgejo.org/docs/v13.0/user/oauth2-provider/
|
||||
- Forgejo customization docs: https://forgejo.org/docs/next/admin/advanced/customization/
|
||||
- Forgejo config cheat sheet: https://forgejo.org/docs/latest/admin/config-cheat-sheet/
|
||||
- Forgejo upgrade guide: https://forgejo.org/docs/next/admin/upgrade/
|
||||
- Forgejo release schedule: https://forgejo.org/docs/v11.0/admin/release-schedule
|
||||
- Forgejo compile-from-source docs: https://forgejo.org/docs/v7.0/developer/from-source/
|
||||
- SIWE docs: https://docs.siwe.xyz/
|
||||
- SIWE hosted OIDC docs: https://docs.login.xyz/servers/oidc-provider/hosted-oidc-provider
|
||||
25
docs/pages/concepts/upstream-use-cases.md
Normal file
25
docs/pages/concepts/upstream-use-cases.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
title: Upstream use cases
|
||||
description: How Patch is used for Forgejo and Codex upstream tracking.
|
||||
---
|
||||
|
||||
# Upstream use cases
|
||||
|
||||
## Forgejo
|
||||
|
||||
Patch watches Codeberg Forgejo branch and release feeds. Branch activity can be
|
||||
notification-only. Release activity can still produce a legacy `fork_sync` job
|
||||
for a jojo-hosted Forgejo fork workflow.
|
||||
|
||||
The Forgejo fork remains a maintenance decision outside Patch. Patch records the
|
||||
upstream signal and job; fork policy, branch policy, CI, and release ownership
|
||||
belong to the Forgejo fork process.
|
||||
|
||||
## OpenAI Codex
|
||||
|
||||
Patch watches GitHub OpenAI Codex branch and release feeds. Branch activity can
|
||||
notify operators. Release activity emits a generic `upstream.release` flow event
|
||||
for codex-flow automation.
|
||||
|
||||
This keeps the release feed integration stable while the actual Codex release
|
||||
automation evolves in flow packages and backends.
|
||||
55
docs/pages/guides/configure-feed-sources.md
Normal file
55
docs/pages/guides/configure-feed-sources.md
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
---
|
||||
title: Configure feed sources
|
||||
description: Add upstream feeds and choose notification, fork-sync, or flow targets.
|
||||
---
|
||||
|
||||
# Configure feed sources
|
||||
|
||||
Feed sources live in a JSON file referenced by `FEED_SOURCES_PATH`. The bundled
|
||||
file is `apps/patch/feed-sources.json`.
|
||||
|
||||
## Choose an event
|
||||
|
||||
Use `event: "push"` for branch commit feeds and `event: "release"` for release
|
||||
feeds. Patch normalizes both into `FeedSignal` records.
|
||||
|
||||
## Choose a target
|
||||
|
||||
`notify_only` stores the signal and can notify Discord:
|
||||
|
||||
```json
|
||||
{
|
||||
"provider": "github",
|
||||
"repoFullName": "peezy-tech/codex",
|
||||
"branch": "main",
|
||||
"mode": "notify_only"
|
||||
}
|
||||
```
|
||||
|
||||
`fork_sync` stores a legacy fork-sync job for release entries:
|
||||
|
||||
```json
|
||||
{
|
||||
"provider": "jojo",
|
||||
"repoFullName": "peezy-tech/jojo",
|
||||
"branch": "forgejo",
|
||||
"mode": "fork_sync"
|
||||
}
|
||||
```
|
||||
|
||||
`flow_dispatch` creates a generic `FlowEvent` and dispatches it:
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "flow_dispatch",
|
||||
"eventType": "upstream.release",
|
||||
"dispatchUrlEnv": "PATCH_FLOW_DISPATCH_URL",
|
||||
"dispatchSecretEnv": "PATCH_FLOW_DISPATCH_SECRET",
|
||||
"payload": {
|
||||
"repo": "openai/codex"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Set `primeOnly: false` only when old feed entries should be emitted on the first
|
||||
poll.
|
||||
41
docs/pages/guides/dispatch-and-replay-flow-events.md
Normal file
41
docs/pages/guides/dispatch-and-replay-flow-events.md
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
title: Dispatch and replay flow events
|
||||
description: Use local or HTTP flow execution and retry stored events.
|
||||
---
|
||||
|
||||
# Dispatch and replay flow events
|
||||
|
||||
Patch creates deterministic event ids:
|
||||
|
||||
```text
|
||||
patch:<sourceId>:<entryId>:<eventType>
|
||||
```
|
||||
|
||||
Dispatch is idempotent at the flow backend by event id. Replay intentionally
|
||||
asks the backend to create another attempt for the stored event.
|
||||
|
||||
## Select HTTP dispatch
|
||||
|
||||
```bash
|
||||
PATCH_FLOW_DISPATCH_URL=http://127.0.0.1:7345/events
|
||||
PATCH_FLOW_DISPATCH_SECRET=dev-secret
|
||||
```
|
||||
|
||||
Patch signs HTTP dispatches with the shared flow HMAC header when a secret is
|
||||
configured.
|
||||
|
||||
## Use local dispatch
|
||||
|
||||
Leave `PATCH_FLOW_DISPATCH_URL` unset. Patch creates a local flow client rooted
|
||||
at the app working directory and runs matching flows synchronously.
|
||||
|
||||
## Retry or replay
|
||||
|
||||
```bash
|
||||
curl -X POST http://127.0.0.1:3000/flow-events/<event-id>/retry
|
||||
curl -X POST http://127.0.0.1:3000/flow-events/<event-id>/replay
|
||||
```
|
||||
|
||||
`retry` dispatches the stored event again. `replay` calls the backend replay
|
||||
endpoint when HTTP mode is configured, or dispatches locally when no backend URL
|
||||
is configured.
|
||||
20
docs/pages/guides/enable-discord-output.md
Normal file
20
docs/pages/guides/enable-discord-output.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
title: Enable Discord output
|
||||
description: Send selected upstream signals to a Discord webhook.
|
||||
---
|
||||
|
||||
# Enable Discord output
|
||||
|
||||
Discord notifications are disabled by default.
|
||||
|
||||
```bash
|
||||
DISCORD_OUTPUT_ENABLED=true
|
||||
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
|
||||
DISCORD_NOTIFY_EVENTS=push,release
|
||||
```
|
||||
|
||||
`DISCORD_NOTIFY_EVENTS` is a comma-separated allow list. Patch still stores feed
|
||||
signals when Discord is disabled or when an event is not in the allow list.
|
||||
|
||||
Notifications include provider, repository, event type, branch, author, short
|
||||
SHA, queued job kind, and source id when those fields are available.
|
||||
35
docs/pages/guides/run-patch-locally.md
Normal file
35
docs/pages/guides/run-patch-locally.md
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
title: Run Patch locally
|
||||
description: Install dependencies, start the service, and run checks.
|
||||
---
|
||||
|
||||
# Run Patch locally
|
||||
|
||||
Install from the repository root:
|
||||
|
||||
```bash
|
||||
bun install
|
||||
```
|
||||
|
||||
Start the service app:
|
||||
|
||||
```bash
|
||||
bun run dev
|
||||
```
|
||||
|
||||
Root scripts delegate into the workspace:
|
||||
|
||||
```bash
|
||||
bun run check
|
||||
bun run test
|
||||
bun run docs:dev
|
||||
```
|
||||
|
||||
Use explicit paths when you run the app package directly:
|
||||
|
||||
```bash
|
||||
cd apps/patch
|
||||
DATA_DIR=./data FEED_SOURCES_PATH=./feed-sources.json bun run dev
|
||||
```
|
||||
|
||||
`GET /healthz` returns `ok` when the server is running.
|
||||
48
docs/pages/index.md
Normal file
48
docs/pages/index.md
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
title: patch.moi
|
||||
description: Feed watching and flow dispatch for upstream project events.
|
||||
---
|
||||
|
||||
# patch.moi
|
||||
|
||||
Patch is a small Bun service that watches upstream Atom/RSS feeds and turns
|
||||
selected upstream activity into durable Patch records, Discord notifications,
|
||||
or generic codex-flow events.
|
||||
|
||||
The service keeps the product boundary narrow:
|
||||
|
||||
- Feeds describe upstream repositories and events.
|
||||
- Patch normalizes feed entries into `FeedSignal` records.
|
||||
- Targets decide whether a signal is notification-only, a legacy fork-sync job,
|
||||
or a generic flow dispatch.
|
||||
- Flow dispatch uses `@peezy.tech/flow-runtime/client` so Patch can run flows
|
||||
locally during development or send events to an HTTP backend in service mode.
|
||||
- Admin endpoints inspect stored flow events and dispatch records, then retry or
|
||||
replay events when an upstream automation needs another attempt.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Feed["Atom or RSS feed"] --> Patch["Patch poller"]
|
||||
Patch --> Signal["FeedSignal JSONL"]
|
||||
Signal --> Notify["Discord output"]
|
||||
Signal --> Job["fork_sync job JSONL"]
|
||||
Signal --> Event["FlowEvent JSONL"]
|
||||
Event --> Client["flow-runtime client"]
|
||||
Client --> Local["local flow execution"]
|
||||
Client --> Backend["HTTP flow backend"]
|
||||
```
|
||||
|
||||
## Start here
|
||||
|
||||
- New service setup: [Watch an upstream release](tutorials/watch-upstream-release).
|
||||
- Codex release automation: [Dispatch a Codex release flow](tutorials/dispatch-codex-release-flow).
|
||||
- Running the service: [Run Patch locally](guides/run-patch-locally).
|
||||
- Exact feed shape: [Feed sources](reference/feed-sources).
|
||||
- Admin operations: [HTTP API](reference/http-api).
|
||||
|
||||
## What is in this repo
|
||||
|
||||
- `apps/patch`: the Patch Bun service, feed poller, JSONL store, Discord output,
|
||||
and flow dispatch adapter.
|
||||
- `docs`: this Tome documentation site, organized with the Diataxis framework.
|
||||
- `Dockerfile`: container image for the Patch service app.
|
||||
25
docs/pages/reference/environment.md
Normal file
25
docs/pages/reference/environment.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
title: Environment
|
||||
description: Runtime environment variables used by Patch.
|
||||
---
|
||||
|
||||
# Environment
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `HOST` | `0.0.0.0` | Server bind host. |
|
||||
| `PORT` | `3000` | Server port. |
|
||||
| `DATA_DIR` | `./data` | Directory for JSONL state files. |
|
||||
| `FEED_SOURCES_PATH` | unset | Enables feed polling from the configured JSON file. |
|
||||
| `PATCH_ADMIN_TOKEN` | unset | Protects admin flow endpoints when set. |
|
||||
| `PATCH_FLOW_DISPATCH_URL` | unset | Default flow backend URL for dispatch targets. |
|
||||
| `PATCH_FLOW_BACKEND_URL` | unset | Alternate default backend base URL. |
|
||||
| `PATCH_FLOW_DISPATCH_SECRET` | unset | HMAC secret for HTTP flow dispatch. |
|
||||
| `DISCORD_OUTPUT_ENABLED` | `false` | Enables Discord webhook output. |
|
||||
| `DISCORD_WEBHOOK_URL` | unset | Discord webhook target. |
|
||||
| `DISCORD_NOTIFY_EVENTS` | `push,release` | Comma-separated notification allow list. |
|
||||
| `CODEX_APP_SERVER_CODEX_COMMAND` | unset | Passed to local code-mode flow execution. |
|
||||
| `CODEX_HOME` | unset | Passed to local code-mode flow execution. |
|
||||
|
||||
Feed target fields can override backend settings with `dispatchUrl`,
|
||||
`dispatchUrlEnv`, and `dispatchSecretEnv`.
|
||||
44
docs/pages/reference/feed-sources.md
Normal file
44
docs/pages/reference/feed-sources.md
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
title: Feed sources
|
||||
description: JSON schema by convention for upstream feed configuration.
|
||||
---
|
||||
|
||||
# Feed sources
|
||||
|
||||
`FEED_SOURCES_PATH` points at a JSON object with a `sources` array.
|
||||
|
||||
```ts
|
||||
type FeedSourceConfig = {
|
||||
id: string;
|
||||
provider: "codeberg" | "github" | "jojo";
|
||||
url: string;
|
||||
event: "push" | "release";
|
||||
repo: {
|
||||
owner: string;
|
||||
name: string;
|
||||
fullName: string;
|
||||
webUrl: string;
|
||||
defaultBranch?: string;
|
||||
};
|
||||
target?: FeedForkSyncTarget | FeedFlowDispatchTarget;
|
||||
pollIntervalSeconds?: number;
|
||||
primeOnly?: boolean;
|
||||
};
|
||||
```
|
||||
|
||||
## Flow dispatch target
|
||||
|
||||
```ts
|
||||
type FeedFlowDispatchTarget = {
|
||||
mode: "flow_dispatch";
|
||||
eventType: string;
|
||||
dispatchUrl?: string;
|
||||
dispatchUrlEnv?: string;
|
||||
dispatchSecretEnv?: string;
|
||||
payload?: Record<string, unknown>;
|
||||
};
|
||||
```
|
||||
|
||||
The flow payload includes provider, event, source id, entry id, title, URL,
|
||||
author, published time, repository fields, ref, SHA, tag, and raw feed metadata.
|
||||
Values from `target.payload` are merged last.
|
||||
41
docs/pages/reference/http-api.md
Normal file
41
docs/pages/reference/http-api.md
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
title: HTTP API
|
||||
description: Health, flow event inspection, retry, replay, and dispatch history.
|
||||
---
|
||||
|
||||
# HTTP API
|
||||
|
||||
## Health
|
||||
|
||||
```text
|
||||
GET /healthz
|
||||
```
|
||||
|
||||
Returns `ok`.
|
||||
|
||||
## Flow events
|
||||
|
||||
```text
|
||||
GET /flow-events?type=<type>&limit=<n>
|
||||
GET /flow-events/:id?limit=<n>
|
||||
POST /flow-events/:id/retry
|
||||
POST /flow-events/:id/replay
|
||||
```
|
||||
|
||||
The list endpoint returns stored events newest first. The detail endpoint
|
||||
returns the event and matching dispatch records.
|
||||
|
||||
## Dispatches
|
||||
|
||||
```text
|
||||
GET /flow-dispatches?eventId=<id>&status=dispatched|failed|skipped&limit=<n>
|
||||
```
|
||||
|
||||
## Admin auth
|
||||
|
||||
When `PATCH_ADMIN_TOKEN` is set, flow endpoints require one of:
|
||||
|
||||
```text
|
||||
Authorization: Bearer <token>
|
||||
X-Patch-Admin-Token: <token>
|
||||
```
|
||||
19
docs/pages/reference/jsonl-state.md
Normal file
19
docs/pages/reference/jsonl-state.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
title: JSONL state
|
||||
description: Files written under DATA_DIR.
|
||||
---
|
||||
|
||||
# JSONL state
|
||||
|
||||
Patch uses append-only JSONL files for durable service records.
|
||||
|
||||
| File | Contents |
|
||||
| --- | --- |
|
||||
| `feed-state.json` | Per-source last seen entry and last checked timestamp. |
|
||||
| `feed-events.jsonl` | Normalized `FeedSignal` records. |
|
||||
| `feed-jobs.jsonl` | Legacy `fork_sync` jobs emitted from release signals. |
|
||||
| `flow-events.jsonl` | Generic `FlowEvent` records emitted by flow targets. |
|
||||
| `flow-dispatches.jsonl` | Dispatch, retry, replay, and failure records. |
|
||||
|
||||
Admin endpoints read `flow-events.jsonl` and `flow-dispatches.jsonl`. The feed
|
||||
poller appends to all relevant files as it accepts new feed entries.
|
||||
28
docs/pages/reference/packages.md
Normal file
28
docs/pages/reference/packages.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
title: Packages
|
||||
description: Workspace packages in the Patch monorepo.
|
||||
---
|
||||
|
||||
# Packages
|
||||
|
||||
## `@peezy.tech/patch`
|
||||
|
||||
The Bun service in `apps/patch`. It exports no public package API; its runtime
|
||||
entry point is `src/server.ts`.
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- Poll configured feeds.
|
||||
- Normalize entries into `FeedSignal` records.
|
||||
- Store JSONL state.
|
||||
- Emit optional Discord notifications.
|
||||
- Dispatch generic codex-flow events through `@peezy.tech/flow-runtime/client`.
|
||||
- Serve admin inspection, retry, and replay endpoints.
|
||||
|
||||
## `@peezy.tech/patch-docs`
|
||||
|
||||
The Tome documentation package in `docs`. Build it with:
|
||||
|
||||
```bash
|
||||
bun run docs:build
|
||||
```
|
||||
44
docs/pages/tutorials/dispatch-codex-release-flow.md
Normal file
44
docs/pages/tutorials/dispatch-codex-release-flow.md
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
title: Dispatch a Codex release flow
|
||||
description: Connect the OpenAI Codex release feed to codex-flow automation.
|
||||
---
|
||||
|
||||
# Dispatch a Codex release flow
|
||||
|
||||
Patch was built to let upstream release activity trigger generic codex-flow
|
||||
automation without putting Codex-specific completion logic into Patch itself.
|
||||
|
||||
## 1. Use the release source
|
||||
|
||||
The bundled `apps/patch/feed-sources.json` includes
|
||||
`github-openai-codex-releases`. Its target emits `upstream.release` events with
|
||||
the upstream repository and release tag in the payload.
|
||||
|
||||
## 2. Point Patch at a backend
|
||||
|
||||
```bash
|
||||
PATCH_FLOW_DISPATCH_URL=http://127.0.0.1:7345/events \
|
||||
PATCH_FLOW_DISPATCH_SECRET=dev-secret \
|
||||
DATA_DIR=./data \
|
||||
FEED_SOURCES_PATH=./feed-sources.json \
|
||||
bun run --filter @peezy.tech/patch start
|
||||
```
|
||||
|
||||
`PATCH_FLOW_DISPATCH_URL` can point at the `/events` endpoint or at the backend
|
||||
base URL. Patch normalizes either form before it creates the shared flow client.
|
||||
|
||||
## 3. Inspect the stored event
|
||||
|
||||
```bash
|
||||
curl http://127.0.0.1:3000/flow-events
|
||||
```
|
||||
|
||||
When `PATCH_ADMIN_TOKEN` is set, include either `Authorization: Bearer <token>`
|
||||
or `X-Patch-Admin-Token: <token>`.
|
||||
|
||||
## 4. Keep completion app-owned
|
||||
|
||||
Patch dispatches the generic event. The installed Codex release flow owns the
|
||||
work that happens next: matching `flow.toml`, running steps, checking gates, and
|
||||
emitting `FLOW_RESULT`. Product-specific completion stays in that flow package
|
||||
or its backend worker.
|
||||
65
docs/pages/tutorials/watch-upstream-release.md
Normal file
65
docs/pages/tutorials/watch-upstream-release.md
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
---
|
||||
title: Watch an upstream release
|
||||
description: Configure a release feed and store the first Patch flow event.
|
||||
---
|
||||
|
||||
# Watch an upstream release
|
||||
|
||||
This tutorial creates the smallest useful release watcher: one upstream release
|
||||
feed that becomes a stored `upstream.release` flow event.
|
||||
|
||||
## 1. Add a feed source
|
||||
|
||||
Create or edit `apps/patch/feed-sources.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"sources": [
|
||||
{
|
||||
"id": "github-openai-codex-releases",
|
||||
"provider": "github",
|
||||
"url": "https://github.com/openai/codex/releases.atom",
|
||||
"event": "release",
|
||||
"repo": {
|
||||
"owner": "openai",
|
||||
"name": "codex",
|
||||
"fullName": "openai/codex",
|
||||
"webUrl": "https://github.com/openai/codex",
|
||||
"defaultBranch": "main"
|
||||
},
|
||||
"target": {
|
||||
"mode": "flow_dispatch",
|
||||
"eventType": "upstream.release",
|
||||
"dispatchUrlEnv": "PATCH_FLOW_DISPATCH_URL",
|
||||
"dispatchSecretEnv": "PATCH_FLOW_DISPATCH_SECRET",
|
||||
"payload": {
|
||||
"provider": "github",
|
||||
"repo": "openai/codex"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 2. Start Patch
|
||||
|
||||
```bash
|
||||
DATA_DIR=./data \
|
||||
FEED_SOURCES_PATH=./feed-sources.json \
|
||||
bun run --filter @peezy.tech/patch dev
|
||||
```
|
||||
|
||||
The first poll primes `data/feed-state.json`. By default, old feed entries are
|
||||
not emitted on that first pass.
|
||||
|
||||
## 3. Dispatch new releases
|
||||
|
||||
When the feed later contains an unseen release entry, Patch appends:
|
||||
|
||||
- `data/feed-events.jsonl` for the normalized signal.
|
||||
- `data/flow-events.jsonl` for the generic flow event.
|
||||
- `data/flow-dispatches.jsonl` for the dispatch outcome.
|
||||
|
||||
If `PATCH_FLOW_DISPATCH_URL` is not set, Patch uses local flow execution from
|
||||
the working directory. If it is set, Patch sends the event to the HTTP backend.
|
||||
Loading…
Add table
Add a link
Reference in a new issue