Files
clide/decisions/extensions.md
T
jpmschweitzerandClaude 4d515ce51e scaffold decisions/ with backlog from planning sessions
Adopt settled-reach's Q&D record convention. Confirmed decisions
live under decisions/<domain>.md as D-NNN; open questions under
questions-<domain>.md as Q-NNN; rejected alternatives in rejected.md
as R-NNN. Markdown is source of truth; .pql/pql.db (added later) is a
query index.

Backlog captured from the Tier-0 Flutter planning sessions: bare
WidgetsApp, theme pipeline, kernel admission rule, feature-first
layout, a11y + i18n as Tier-0 contracts, test pyramid, kanban over
Scrum, pql-owns-planning, Python stopgap sunset clause.

ADR migration (D-001, D-003-D-006 confirmed, R-002 rejected) is
staged for the next commit so the diff stays readable.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-21 17:10:42 +02:00

4.2 KiB

Extension Decisions

Extension contract, Lua runtime, grain, contribution points.


D-015: Extension grain — container-level, multi-contribution

  • Date: 2026-04-21
  • Decision: An extension is a shipping unit that contributes one or more named contributions (panel, command, theme, keybinding, language, layout, provider, view). Grain is container-sized — a single builtin.git extension contributes panel + commands + keybindings + status-bar items; we do not ship one extension per contribution.
  • Rationale: Finer grain (one extension per contribution) multiplies manifest files with no win and fragments ownership. Coarser grain (one mega-extension per domain) hides which parts a user might reasonably disable.
  • Cost: Extension authors make a taste call about grouping; disagreements go to review.
  • Raised by: 2026-04-21 planning.

D-016: Built-ins in Dart, third-party in sandboxed Lua

  • Date: 2026-04-21
  • Decision: Bundled extensions (every app/lib/builtin/<name>) are Dart — they link into the app binary. Third-party extensions (Tier 6) run in sandboxed Lua via the ptyc-peer Lua runtime (see D-019). The contribution contract is language-agnostic — same contribution shapes, same manifest schema.
  • Rationale: Dart built-ins get full SDK power (custom painters, isolates, FFI); third-party Lua gets a narrow capability API, no arbitrary syscalls, no deps on pub.dev. VS Code's Node-runs-with-full-power model is a supply-chain nightmare we're explicitly rejecting.
  • Cost: Two implementation paths for the same contract; we pay in API design to keep them equivalent at the seams.
  • Raised by: 2026-04-21 planning.

D-017: Panels are extension-shaped from day one

  • Date: 2026-04-21
  • Decision: Every bundled panel (file tree, git, problems, pql query, terminal, etc.) is a contribution on the extension contract, not a hardcoded widget tree in the panel manager. First party contributes via Dart; third party contributes via Lua; same contract.
  • Rationale: Forces the contract to be real on day one. The alternative ("extensions can contribute panels later") always becomes "the contract doesn't quite fit our bundled panels, so built-ins get a shortcut" — and the shortcut becomes permanent.
  • Cost: Every panel goes through the manifest/registration path even when it's trivial. Price paid once.
  • Raised by: 2026-04-21 planning.

D-018: YAML for themes + manifests; JSON for i18n catalogs

  • Date: 2026-04-21
  • Decision: Themes and extension manifests are YAML; i18n catalogues are JSON (fframe parity — see D-021).
  • Rationale: YAML for human-edited config files (themes, manifests) — comments, multi-line strings, less noise. JSON for machine-written / machine-read files (i18n catalogs get generated by translation tooling eventually). Mixing is fine; each format is where it's best.
  • Cost: Two parsers in the tree. yaml: 3.1.3 is exact-pinned.
  • Raised by: 2026-04-21 planning.

D-019: Lua runtime as ptyc-peer supporter tool

  • Date: 2026-04-21
  • Decision: Third-party extensions run Lua inside a sandboxed runtime (working name TBD; same peer-status as ptyc and pql). The runtime vendors liblua, links from Dart via dart:ffi, exposes a narrow capability API, and takes contributions as a declarative render-intent DSL (widget shapes, not arbitrary widget code).
  • Rationale: Lua is small, embeddable, battle-tested (Neovim, World of Warcraft, Redis). Native sandboxing at the VM level is cheap. A declarative render-intent DSL keeps "run arbitrary Flutter widgets from Lua" off the table — the runtime interprets the DSL into Dart widgets, which keeps Tier 6 supply-chain risk bounded.
  • Cost: Runtime is a separate supporter tool to build; ffi is tricky. Deferred to Tier 6; only the slot is reserved now.
  • Raised by: 2026-04-21 planning.

See also the existing builtin.grammars_core stub for tree-sitter questions (Q-015, Q-016).