Skip to content

Catalog format 2, validation CI and contributor docs - #16

Merged
nwparker merged 44 commits into
mainfrom
catalog-v2
Oct 28, 2026
Merged

nwparker merged 44 commits into
mainfrom
catalog-v2

Conversation

@nwparker

@nwparker nwparker commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

What

This turns the catalog repository into the home of the official plugins, and sets the catalog up for Orca's catalog format 2:

  • The official plugins now live in plugins/<name>/, each with its own MIT LICENSE, copied from the manifest-v2 branch of its old repository. The only change to their files is the manifest's repository URL, which now points here.
  • orca-catalog.json (format 2) lists them from this repository: source: {kind: git, url: https://github.com/stablyai/orca-plugins.git, ref: main, path: plugins/<name>}. Orca downloads the pinned commit but installs only that directory, and contentHash covers only its files, so changing one plugin never changes another's hash.
  • orca-marketplace.json (read by released Orca builds) is byte-identical to main.
  • Every plugin requires Orca 1.4.242 or newer (engines.orca: ">=1.4.242", release minimumOrca: "1.4.242"). 1.4.241 shipped without manifest format 2 support.
  • CI, CONTRIBUTING.md, REVIEW_POLICY.md and the README.
Plugin Directory Execution
stablyai.orca-midnight-theme plugins/midnight-theme data
stablyai.orca-nord-theme plugins/nord-theme data
stablyai.orca-minimal-icons plugins/minimal-icons data
stablyai.orca-solarized-terminal plugins/solarized-terminal data
stablyai.orca-multipass-recipes plugins/multipass-recipes declarative
stablyai.orca-oled-theme (new) plugins/oled-theme data
stablyai.orca-dusk-ember (new) plugins/dusk-ember data
stablyai.orca-gleam (new) plugins/gleam data
stablyai.orca-prisma (new) plugins/prisma data

New: Orca OLED (plugins/oled-theme, 1.0.0). A true-black dark theme plus a matching terminal theme for OLED displays: every surface is #000000, panels are separated by #1f1f1f hairlines, and all text pairs meet WCAG AA (body text 16.8:1, muted 7.6:1 or better). It is format 2 only, so orca-marketplace.json is unchanged.

New: Dusk & Ember Themes (plugins/dusk-ember, 1.0.0). A light/dark pair: Dusk is a violet dark app theme, Ember a warm light one, each with a matching terminal theme. Both set every sidebar token.

New: Gleam Language (plugins/gleam, 1.0.0) and Prisma Syntax (plugins/prisma, 1.0.0). Highlighting, comment toggling and bracket matching for .gleam and .prisma files. Their releases list fileTypes (gleam, prisma), so Orca can suggest them when such a file is opened. Orca has no built-in Gleam highlighting. It already colours .prisma files with its GraphQL grammar, so Prisma Syntax replaces that approximation with a Prisma grammar (block keywords, model names, scalar types, attributes, built-in functions). Because .prisma is not plain text in Orca, the open-file suggestion does not appear for it today; the plugin is still listed and installable. The Gleam grammar is Apache-2.0 and ships with its licence in plugins/gleam/syntaxes/, so that plugin's licence is MIT AND Apache-2.0.

These three are format 2 only, so orca-marketplace.json is unchanged.

orca-workflow-skills stays out of format 2: it contributes skills, which manifest format 2 reserves.

Removed: Orca Navigation Shortcuts. It no longer ships (Orca also stops bundling it), so it has no plugins/ directory and no orca-catalog.json entry. Its legacy v1 listing stays in orca-marketplace.json for released Orca builds.

How releases are pinned

A commit can't contain its own hash, so a release can't point at the commit that adds it to the catalog. Instead, scripts/release-entry.mjs runs Orca's validator on each plugins/<name> directory and writes the printed release into orca-catalog.json, pinned to the last commit that changed that directory. So the author commits the plugin change, runs release-entry.mjs --write, and commits the catalog. CI runs the same script in check mode. If a plugin changes without a fresh release, CI fails.

Merge this as a merge commit, not a squash. If this PR is squash-merged, the pinned branch commit is no longer in main's history, and CI on main will report the pins as stale. Then run release-entry.mjs --write on main and merge that small follow-up, which re-pins the releases to the merge commit. A merge commit (not squash) keeps the current pins valid.

What older Orca builds see

Nothing changes for them. Format 1 has no path, so Orca's legacy export leaves out entries that use one; those builds would otherwise install the whole repository. orca-marketplace.json therefore keeps its seven original listings (including Navigation Shortcuts), which install each plugin from its old repository at v1.0.0. All seven ids are in legacy-v1-only.json. CI still checks that the file matches the export plus those frozen listings, and --write-legacy now rewrites the file only when its content actually differs.

How CI works

.github/workflows/validate-catalog.yml runs on every PR and every push to main, at Orca 3fedbacd01a6 (the final plugin stack). It checks out the catalog with full history and:

  1. scripts/release-entry.mjs: every plugins/ directory validates and has a catalog entry, and each entry's newest release matches what the validator prints, pinned to the last commit that changed the directory.
  2. scripts/check-catalog.mjs: validates orca-catalog.json (schema, limits, duplicate ids, images), fetches every pinned commit from the source URL and re-validates that directory, checks that every file under assets/ is referenced, and checks orca-marketplace.json.

Old plugin repositories

The six manifest-v2 draft PRs in the old repositories are closed as superseded. The repositories and their v1.0.0 tags stay, because older Orca builds install from them.

Copied from each repository's manifest-v2 branch with its MIT LICENSE; only
the manifest's repository URL changes. orca-marketplace.json goes back to the
bytes on main so older Orca builds keep their seven listings.
Catalog entries now point at plugins/<name> in this repository. A new
scripts/release-entry.mjs writes each plugin's release from Orca's validator,
pinned to the last commit that changed its directory; CI runs it in check
mode, so a plugin change without a fresh release fails. orca-marketplace.json
stays frozen: the export skips path sources, so all seven legacy ids are
kept as v1-only. CI uses Orca 77e66a707d3f.
@smwbev

smwbev commented Oct 25, 2026

Copy link
Copy Markdown

Where should community language packs go once this lands? At 3a149bec5b the docs say where they don't go, but not where they do:

  • REVIEW_POLICY.md: "This repository holds only official plugins … Community plugins stay in their authors' own repositories and are listed in the community directory, not copied here."
  • CONTRIBUTING.md: "Community plugins stay in their authors' own repositories. List them in the community directory; don't copy their code here." Its steps cover only a new official plugin under plugins/<name>/, and release-entry.mjs writes releases only for those directories.
  • README.md: "Community plugins live in their authors' own repositories. The catalog can list them, but their code is not copied here."

"The community directory" isn't defined in this repository or in Orca's docs/reference/plugin-catalog.md. If it means orca-catalog.json here, I'll move #13 to a format-2 entry after this merges: source at the pack's release tag, no path, releases from pnpm validate:plugin on a manifest-v2 commit, and orca-marketplace.json regenerated with --write-legacy. If community packs go somewhere else, I'll move #13 there.

nwparker and others added 9 commits October 25, 2026 23:02
…242 Orca validator

Orca 1.4.241 shipped without manifest format 2, so format 2 manifests now
need 1.4.242.
The plugin no longer ships. orca-marketplace.json stays byte-identical so released
Orca builds keep their legacy v1 listing.

Co-Authored-By: Claude <noreply@anthropic.com>
Opens .excalidraw and .excalidraw.json files in Excalidraw 0.18.1 inside
Orca's sandboxed editor frame. editor/index.html is one self-contained file
built by build/build.mjs from pinned dependencies, with the Latin fonts
embedded as data: URLs.

Co-authored-by: Roughriver74 <115543510+Roughriver74@users.noreply.github.com>
nwparker and others added 22 commits October 27, 2026 15:34
Read-only viewer for .xlsx, .xlsm, .xlsb, .xls and .ods files, on Orca's
contentKind "bytes" custom editor point. Bundles SheetJS Community Edition
0.20.3 (Apache-2.0) as one offline HTML file: sheet tabs, a virtualized grid,
formulas and stored values in the cell bar, keyboard navigation, copy as TSV,
grid semantics for screen readers, and theme-aware styling.

The zip-bomb guard is adapted from stablyai/orca#29678.

Co-authored-by: nebourocket <70624415+nebourocket@users.noreply.github.com>
Orca lists a stablyai plugin as official only when its id starts with orca-, and
only official plugins get the badge and file-type suggestions. Unreleased, so no
migration.
…draw in the catalog

Repins ORCA_REF to the custom editors branch head, whose validator knows the
customEditors contentKind and readonly fields.
…k and Ember

Each theme colors comments, keywords, strings, numbers, functions, types, variables,
constants, operators, punctuation, Markdown and invalid code at WCAG AA (4.5:1) or better
on its editor background; Nord follows the published Nord syntax palette. Covers and
screenshots are re-rendered from each theme's own tokenColors.
…the sizes it declares

A zip entry may declare 0 bytes (normal with data descriptors) or lie, and SheetJS sizes its
output from those headers, so the declared-size budget alone let a small file inflate to
gigabytes. The editor now inflates each entry itself with DecompressionStream, stops once the
counted output passes the 256 MiB budget, and hands SheetJS a stored copy with true sizes.
…ent field

Orca now drops edits without baseVersion, so an in-flight stroke can no longer overwrite a newer
buffer after an outside change. The editor reads content.text (the duplicate top-level text is
gone) and, when Orca rejects an edit, posts the whole scene again on the next change.
…; pin CI to Orca with custom editors and tokenColors

Release entries for both editors now carry the structured editorFileTypes Orca reads for editor
suggestions. Older theme releases get the image hashes of the files they point at, and CI checks
against the Orca commit that has both tokenColors and the hardened custom editor protocol.
…yntaxes use title, custom editors match extensions with the dot
…ach plugin's newest release already covers the same Orca versions
Both editors now use the frame API Orca injects (orca.document.onDidChange,
applyEdit, and the editor.flush event) instead of posting raw messages,
which are internal from Orca's interface v1 on.
@nwparker
nwparker marked this pull request as ready for review October 28, 2026 06:10
@nwparker
nwparker merged commit c118931 into main Oct 28, 2026
1 check passed
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.

2 participants