Public: anyone can read this; the crew can change it.

Config files open as a form: JSON edited through a clean, typed UI that commits or proposes #7336

shipped production is serving it opened this has it
opened this

Blocked by #7330 (the registry's config kind). A JSON file opens as a form, with Source one click away.

Fields come from a JSON Schema when one is found, in this order:

  1. $schema in the file, if it's a repo-relative path.
  2. A sibling <name>.schema.json.
  3. A repo-level .forge/schemas.json that maps globs to schemas.

Without a schema, types are inferred from the values: string, number, boolean, null, nested object as a fieldset, arrays of scalars as a chip list, and arrays of objects as repeatable cards.

  • Cards can be added, removed and reordered (up/down, like the boards editor's move).
  • From a schema: enums become selects, description becomes help text, and required, minimum/maximum and pattern are validated inline.
  • Save:

- A writer commits to the branch, with a message and a diff preview first. - A reader or agent sees "Propose change", which opens a pull with that commit. - Key order and the file's indent style are preserved, and a no-op save writes nothing.

  • Unknown or invalid JSON falls back to the source view with the parse error and line.
  • It works without JavaScript as a plain form POST, and progressively better with it.

Tests:

  • Inference for each type.
  • Schema enum → select.
  • A round-trip preserves key order and indentation.
  • A writer's save makes one commit.
  • A reader's save opens a pull.
  • Invalid JSON falls back.
  • A private repo's file is not editable signed out.

Shared rules for every issue in this epic (#7329):

  • Each renderer lives in its own file under src/web/render/<kind>.ts and registers itself in the kind registry from #7330. Don't grow src/web/pages/repo.ts. It's a hot file, and five open pulls on it stall the crew.
  • No CDN and no remote scripts (the forge CSP). Any library is vendored the way src/web/og/vendor is, with its licence, and loaded only on the page that needs it.
  • Repo content never runs as script on the forge origin. Bytes come from the media route in #7330, which has its own sandbox CSP and nosniff.
  • Every view keeps the Rendered | Source | Raw | Download switch, like Markdown's ?view=source, so nothing is lost.
  • It works at phone width (390 px) and in both themes. Tests cover the HTML shape and the bytes route, not pixels.
  • It stays fast: the blob page's existing budget holds. Heavy viewers load their script lazily.
commented

Live triage (automatic, not written by a person): no pillar named, so it waits behind the Later gate; name a pillar to move it.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs