GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - Tend-Stack/TendExtensions

BranchesTags
Open more actions menu

Latest commit

 

History

91 Commits
91 Commits

Folders and files

NameName
Last commit message
Last commit date
.gitea
.gitea
 
 
.github
.github
 
 
components
components
 
 
developers
developers
 
 
docs
docs
 
 
extensions
extensions
 
 
keys
keys
 
 
recipes
recipes
 
 
scripts
scripts
 
 
templates
templates
 
 
tests
tests
 
 
tools
tools
 
 
.gitignore
.gitignore
 
 
AGENTS.md
AGENTS.md
 
 
CONTRIBUTING.md
CONTRIBUTING.md
 
 
LICENSE
LICENSE
 
 
README.md
README.md
 
 

Repository files navigation

TendExtensions

The public registry of extensions for Tend, the self-hosted server panel.

License: MIT Latest registry release Extensions

Every extension lives here as plain source, in its own folder, next to the community App Store recipes. A pull request adds one or updates one. On merge, CI builds every package, signs the index, and publishes a release that every Tend panel in the world can verify and install from, with no panel update in between.


What is Tend?

Tend is a self-hosted control panel for the servers you own. It deploys apps and services from Git, runs them in containers, watches their health, and wraps the whole thing in a calm, desktop-like shell: windows, a menu bar, a dock, widgets on a home shelf, and a small set of built-in apps. Extensions are how that shell grows. A calculator, a note-taking tool, a game for a coffee break, a dashboard for something you run: each one is a small ES-module package that the panel mounts in its own window and talks to through a narrow host API.

Tend is available as self-hosted (you run the panel) and as hosted panels at Tend. Both read this registry the same way.

What is an extension?

An extension is a folder with an extension.json manifest (schema 2) and the ES modules it declares. The panel loads the entry module, calls activate(host), and mounts what it returns in a tool window or as a full shell app. Through host an extension gets exactly what it declared in permissions and nothing else: key-value storage, notifications, the current theme and user, and, for extensions that declare them, files, media, documents, sites, and the read-only ondacast catalog. There is no direct outbound network from an extension: anything external goes through a panel capability.

Every file an extension ships is pinned in the manifest's integrity map (SHA-256). The panel refuses a package whose bytes disagree with its manifest, and runs every package through its installer, its integrity verifier, and its web application firewall before a single module executes.

// extensions/host.tend.calculator/extension.json (abridged)
{
  "schema": 2,
  "id": "host.tend.calculator",
  "name": "Calculator",
  "version": "3.0.1",
  "author": "Tend",
  "description": "Seven-mode calculator …",
  "icon": "icon.svg",                  // deprecated: only for panels older than themed icons
  "glyph": "glyph.svg",                // required for every non-theme package
  "ui": { "module": "index.js", "mount": "tool-window", "size": { "w": 460, "h": 700 } },
  "permissions": ["storage"],
  "integrity": { "index.js": "sha256-…", "engine/parser.js": "sha256-…" }
}

glyph.svg is the one-colour icon the panel draws on a tile coloured from the active theme; no colour of yours is ever shown. The registry refuses a non-theme package without a valid one, and the rules live in one place, docs/icons.md. icon.svg is deprecated and kept only for panels older than the glyph release. Theme packs carry neither.

Next to the manifest, listing.json carries what the store shows but the runtime does not need: publisher, category, feature bullets, requirements, and the release notes for the current version.

What's in the registry

Extension Version Category What it is
Calculator (host.tend.calculator) 3.0.1 productivity Standard, scientific, graphing, programmer, statistics, financial and converter modes, a real expression engine, a history tape, full keyboard control
Calendar (host.tend.calendar) 1.5.1 productivity Month, week, day and agenda views with local events, reminders and ICS import/export
Developer Tools (host.tend.devtools) 1.0.1 developer-tools JSON, Base64, URL, JWT, hash, UUID, timestamp and guarded regex tools in one offline window
Tend Player (host.tend.media) 1.7.1 media Radio, podcasts and audiobooks from OndaCast with subscriptions, a queue, per-show speed, sleep timer, transcripts and clips to Notes
Riftwing: Skybound (com.tendstack.riftwing) 4.1.2 games A fast, replayable sky-runner with eight worlds and nine pilots
2048 Odyssey (host.tend.2048) 2.0.2 games Merge mastery across an endless target ladder
Breakout Odyssey (host.tend.breakout) 2.2.1 games Campaign Breakout with boss walls and live relayout
Cookie Empire Odyssey (host.tend.cookie) 2.2.1 games An active-idle bakery with upgrades and prestige
Fruit Slash Odyssey (host.tend.fruitninja) 2.2.1 games Fruit-slicing arcade action
Gem Crush Odyssey (host.tend.gemcrush) 3.0.5 games An 80-stage match-three campaign
Match Puzzle: Odyssey (host.tend.matchpuzzle) 2.1.2 games A polished match puzzle adventure
Memory Match Odyssey (host.tend.memory) 2.2.1 games A 50-stage memory campaign
Minesweeper Odyssey (host.tend.minesweeper) 3.0.3 games A no-guess Minesweeper expedition
Neon Cyber-Man (host.tend.neon-cyber-man) 1.0.2 games A cyberpunk maze-chase arcade game with adaptive ghost AI
Peggle Odyssey: Arc Light (host.tend.peggle) 3.0.7 games Arcade ricochet with fever shots and star-rated stages
Simon Odyssey: Neural Pulse (host.tend.simon) 3.0.4 games A 60-session brain-training campaign
Snake Odyssey: Neon Wilds (host.tend.snake) 3.1.2 games Modern Snake with endless classic growth
Solitaire Odyssey: Starlight Circuit (host.tend.solitaire) 3.0.2 games Klondike with fluid card dragging and 36 stages
Sudoku (host.tend.sudoku) 1.1.1 games Classic 9×9 Sudoku
Tetris (host.tend.tetris) 3.1.1 games The classic, rebuilt with keyboard and touch controls
Word Guess (host.tend.wordle) 1.1.1 games Guess the hidden word in six tries
Nebula (host.tend.theme.nebula) 1.0.1 themes Theme pack: orchid starlight and teal dust across a violet spiral galaxy
Synthwave (host.tend.theme.synthwave) 1.0.1 themes Theme pack: gold contrails over a neon wireframe horizon
Inkwell (host.tend.theme.inkwell) 1.0.2 themes Theme pack: cyan, cobalt and gold ink blooming beneath rippling water
Prism (host.tend.theme.prism) 1.0.1 themes Theme pack: a tangerine cube and amber light beams in a quiet concrete gallery
Skyline (host.tend.theme.skyline) 1.0.1 themes Theme pack: sapphire night over a riverside city, window light glowing gold

The table is a snapshot; dist/registry.json built from main is always the authority.

Themes

Not every extension is code. A theme pack is an extension with category: "themes" that carries only a declarative theme object (colours, a wallpaper, a few shell settings) and its images. It has no scripts and no permissions, and every colour passes a closed grammar, so installing one can only change how the panel looks. Enabled packs appear in the wallpaper picker, and each account tunes its own. Five first-party packs ship here (Nebula, Synthwave, Inkwell, Prism, Skyline). To make your own, copy templates/theme-pack and follow docs/themes.md.

Community recipes

The registry also carries App Store recipes: small, reviewed descriptions of how a panel installs a self-hosted app from a container image (image, port, environment hints, volumes, databases). Each lives in recipes/<slug>/, and the merged set is published as a signed Tend Community catalog, listed by default in panels as "Community · reviewed by Tend". "Reviewed" means a person read the recipe's text; it is never tested or certified, which only Tend's first-party catalog can claim. To propose one, copy templates/recipe/example-notes and follow docs/recipes.md.

How an extension reaches a panel

flowchart LR
    A[Contributor opens a pull request<br/>extensions/&lt;id&gt;/] --> B[CI validates the manifest,<br/>rebuilds the integrity map,<br/>builds a deterministic ZIP,<br/>runs it through the real panel installer]
    B --> C[Merge to main]
    C --> D[CI publishes the exact commit here<br/>and signs registry.json]
    D --> E[GitHub release registry-N<br/>every ZIP + registry.json + signed index]
    E --> F[Panels fetch the newest release,<br/>verify the signature and sequence]
    F --> G[Store shows the extension,<br/>installed ones get an Update badge]
Loading
  • The index is signed. tend-extension-registry-v1.json is an Ed25519-signed envelope. Panels pin the registry's public key and refuse anything unsigned, tampered, expired, or older than what they last verified (sequence only ever increases).
  • Every package is pinned. The signed index carries each ZIP's name, size, and SHA-256. Download URLs are never in the file; a panel derives them from the release tag, so the signature always guards the bytes it will install.
  • Builds are reproducible. tools/build.py produces byte-identical ZIPs from the same source, and CI refuses a pull request whose package the panel's own installer would reject.
  • Panels stay in control. The registry is opt-in per panel (Settings → Extensions), checks every six hours by default, and only ever offers an update. Installing still runs the panel's integrity verifier and firewall, and a rollback is one click away.

For panel users

Open Settings → Extensions in your Tend panel. Leave the registry enabled and the panel checks for new extensions and updates on its own, notifying you once per new set. "Check now" asks immediately. Installed extensions with a newer registry version show Update available in the store, with Update all beside it. If you would rather freeze what you have, turn the registry off; the extensions bundled with your panel keep working exactly as before.

Contributing

We would love your extension here. The full guide is in CONTRIBUTING.md; the short version:

Add a new extension

  1. Fork this repository and create extensions/<your.extension.id>/. Ids are reverse-DNS (com.example.weather); host.tend.* and com.tendstack.* are reserved for first-party work.
  2. Start from templates/extension. Write extension.json (schema 2) and your ES modules. Declare only the permissions you use.
  3. Draw glyph.svg and declare "glyph": "glyph.svg" (docs/icons.md).
  4. Write listing.json: publisher, category, three to six feature bullets, requirements, release notes.
  5. Build locally and let the tooling rebuild your integrity map:
    pip install -r tools/requirements.txt
    python tools/build.py
  6. Open a pull request. A public check validates the manifest and rebuilds your package on a GitHub-hosted runner (no secrets), with hints that point the reviewer at risky code. A maintainer reviews the code, tries it in a panel and approves that exact commit; the maintainers' pipeline then imports it, runs your package through the real panel installer and releases it. Your extension ships in the next registry-N release. How that works, and what stays maintainer-only, is in docs/community-review.md.

Add an App Store recipe: copy templates/recipe/example-notes to recipes/<slug>/, pin an exact image version, and run python tools/validate_recipe.py recipes/<slug>. The rules are in docs/recipes.md; one recipe per pull request.

Update an extension you maintain

  1. Change the code, bump version in extension.json (semantic versioning, x.y.z), and write release_notes in listing.json for that version.
  2. python tools/build.py, then open a pull request. Panels that have the older version get an Update available badge as soon as the release is out.

House rules

  • One extension per folder, one folder per pull request.
  • No outbound network, no remote scripts, no minified-only sources. Reviewers read what ships.
  • Every code extension ships a one-colour glyph.svg (docs/icons.md); theme packs ship none.
  • Never edit the integrity map by hand; the build rebuilds it and CI compares.
  • Keep third-party code to what the panel allows as a runtime module; today that is phaser@4.
  • Be kind in reviews and honest in release notes.

Build with AI

An optional developer kit for people and AI coding agents lives in this repository: developers/ (AGENTS.md for the agent, plus a skill for extensions, theme packs, Dockerfiles, compose files, recipes, deploying your own app, Git and PRs, and the API). There is also a human guide, developers/README.md.

Read this before you use it. Every extension, theme pack, App Store recipe and listing is inspected by humans before it is published. The AI kit is a convenience, not the default. You are responsible for inspecting, testing, fixing and patching AI-generated code (and Dockerfiles, compose files and recipes) before you open a PR, and reviewers reject code its author can't explain. Registry PRs always get human review.

Repository layout

extensions/<id>/                 one folder per extension (id = manifest id)
    extension.json               schema-2 manifest: id, name, version, ui, permissions, integrity
    listing.json                 store listing: publisher, category, features, requirements, release notes
    glyph.svg                    the themed icon shape (required unless category is themes)
    README.md, *.js              the extension itself; icon.svg only for panels older than glyphs

developers/                       the developer kit: README, AGENTS.md for AI agents, skills/, guides/

templates/extension/             starter for a code extension, with a conforming glyph.svg (copy into extensions/)
templates/theme-pack/            starter for a gradient-based theme pack (copy into extensions/; never built as is)
templates/recipe/example-notes/  starter for a community recipe (copy to recipes/<slug>/; never built as is)

recipes/<slug>/                  one community App Store recipe: recipe.json + listing.json (nothing else)
recipes/recipe.schema.json       JSON Schema for recipe.json (tools/validate_recipe.py is the authority)

tools/
    build.py                     validate, rebuild integrity maps, build deterministic ZIPs, write registry.json
    sign.py                      sign registry.json into the published envelope (also --verify)
    validate_with_panel.py       run every built package through the panel's own installer
    release.py                   create or update the registry-N GitHub release and upload its assets
    validate_recipe.py           validate recipes/ (public rules) and build the community catalog
    sign_catalog.py              sign the community catalog in the format panels verify
    review_hints.py              reviewer hints and the contributor-path check for a pull request
    import_approved.py           import pull requests the Tend Review App approved (Gitea, scheduled)
    mcp_window.py                derive the MCP runtime's core window, version and sequence from a core checkout
    mcp_release.py               publish mcp-runtime-<version> and move the mcp-runtime-latest alias
    ipmeta_release.py            fetch, manifest, sign and publish the ipmeta-<YYYY.MM> data release
    requirements.txt             the dependencies are `cryptography` and `Pillow`

tests/                           tooling tests (reproducible builds, integrity, signing, panel validation)
scripts/publish-verified-main.py publishes the exact verified commit to this repository
.gitea/workflows/ci.yml          the pipeline: build and validate → publish → sign and release
.gitea/workflows/import-approved.yml  every 10 minutes: import approved community pull requests
.github/workflows/validate-pr.yml     public pull-request checks (GitHub-hosted, no secrets, read-only token)
.gitea/workflows/mcp-runtime.yml build, sign and publish the optional MCP component runtime
.gitea/workflows/ipmeta.yml      monthly: sign and publish the offline IP data (docs/ipmeta.md)
docs/icons.md                    the glyph rules and drawing guide (the one canonical icon page)
docs/themes.md                   how to build and publish a theme pack
docs/recipes.md                  the recipe rulebook, and how the signed community catalog is published
docs/community-review.md         pull-request checks, approval and import, and the operator setup
docs/mcp-runtime.md              what that runtime is, how it is signed, and how a core release re-signs it

dist/ is never committed. Everything a panel downloads is rebuilt by CI from the sources in main.

Security

If you find a problem with the registry, its signing, or a published extension, please do not open a public issue. Use Security → Report a vulnerability on this repository so the report stays private until it is fixed. Every published package can be rebuilt from its source folder at the commit recorded in the release's registry.json, so a reviewer can always check what a panel installed against what was merged.

License

The registry tooling and the first-party extensions are released under the MIT License. Each extension folder may carry its own license file; when it does, that license applies to that folder.

About

No description, website, or topics provided.

Resources

Readme
MIT license

Contributing

Contributing
Activity
Custom properties

Stars

0 stars

Watchers

0 watching

Forks

0 forks
Report repository

Releases

Packages

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.