Skip to content

ci: main's checks pass again (a formatted file, the examples' branch) - #597

Merged
foxnne merged 2 commits into
mainfrom
windows/titlebar-fmt
Oct 19, 2026
Merged

foxnne merged 2 commits into
mainfrom
windows/titlebar-fmt

Conversation

@foxnne

@foxnne foxnne commented Oct 18, 2026 •

Copy link
Copy Markdown
Collaborator

Two fixes that keep every pull request's CI from passing on main right now.

1. win32_titlebar.zig is formatted. #463 merged with backend/src/platform/win32_titlebar.zig not formatted, so the Format check (scripts/check-fmt.sh) fails on main and every pull request since. Just zig fmt.

2. An example repo is cloned from main once its zig-0.17 branch has landed.

  • scripts/check-examples.sh (the Example repos job) cloned both example repos' zig-0.17 branch, as a stopgap until their Zig 0.17 PRs landed.
  • example-plugin's landed (zig: build on Zig 0.17 example-plugin#13) and its branch was deleted, so the clone failed every pull request: "Remote branch zig-0.17 not found".
  • Each repo is now cloned from its zig-0.17 branch while it has one, main once it doesn't. Today that's example-app → zig-0.17, example-plugin → main.
  • When example-app's lands too, main alone, in a PR of its own (the ZIG017 note says so).

SDK impact

  • None

Verified

  • scripts/check-fmt.sh passes; zig build -Dtarget=x86_64-windows builds.
  • bash -n scripts/check-examples.sh; the branch choice run by hand against GitHub: example-app → zig-0.17, example-plugin → main.
  • The Example repos job on this PR.

🤖 Generated with Claude Code

#463 merged with backend/src/platform/win32_titlebar.zig not as zig fmt
leaves it, so the format check failed on main and on every pull request
since. zig fmt, nothing else.
@foxnne foxnne changed the title windows: win32_titlebar.zig is formatted ci: main's checks pass again (a formatted file, the examples' branch) Oct 18, 2026
@foxnne
foxnne merged commit 8723266 into main Oct 19, 2026
11 checks passed
@foxnne
foxnne deleted the windows/titlebar-fmt branch October 19, 2026 00:03
foxnne added a commit that referenced this pull request Oct 19, 2026
Part of fizzyedit/plans#30 (step 0: check that a guide played over the
site gives the site back).

## What changes

A demo sets the person's session aside and reopens it by path when it
ends (`Demo.begin` / `end`). A document whose path can't open it again
was lost:

- a file the web page fetched or the person uploaded
- a zip opened as the project folder, whose tab is its mount

The second case is fizzyed.it's `?open=/site.zip`. The keyframe closes
the zip's tab, which unmounts it, and after the tour the site was gone.

Now `begin` keeps the bytes of each document whose path can't reopen it,
using `Plugin.documentBytes`, the same encode a save does. "Can't
reopen" means the path is neither on a mount nor on disk, and on the
web, not on a mount. `end` opens those documents from their bytes first,
so a zip mounts again under the same prefix before the project folder
and the files inside it are opened.

The document that was active is active again, whichever way it came
back. A never-saved document (`untitled-1`, clean, since a demo won't
start over unsaved work) is left out, as before. Reopened from its
bytes, it would come back as a file named `untitled-1`.

Tried and dropped: keeping the person's documents open through the demo,
with the demo closing only its own. The workbench's panes would still
hold the person's tabs during the demo, and taking those out is
workspaces work (`plans/WORKSPACES_PLAN.md`).

## SDK impact

- [x] None

## Verified

- [x] macOS: the bundled-demos test (`tests/demos.zig`) now opens a zip
from its bytes before playing every demo, then checks the zip is mounted
and is the project folder again, with the same number of documents open
and `site.zip` still the active one. It failed before this change: the
project folder was not the zip's. The test build now bundles the archive
plugin for it. `zig build test-integration` 81/81 steps, `zig build`,
`zig build test`, `zig build check-web`, `zig build
check-tests-reached`.
- [ ] Windows:
- [ ] Linux:
- [ ] Web: same code path (`reopenable` is false for anything off a
mount); not run in a browser.

`scripts/check-fmt.sh` flags `backend/src/platform/win32_titlebar.zig`,
which has been unformatted on `main` since #463 and isn't in this diff;
#597 formats it.

## Follow-ups

- Steps 1–4 of fizzyedit/plans#30: the demo registry, the `guides`
plugin, hosted guides, `?view=`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
foxnne added a commit that referenced this pull request Oct 19, 2026
Part of fizzyedit/plans#5 (`plans/ZIG_0_17_PLAN.md`): the last step of
the Zig 0.17 switch. **Merge after fizzyedit/example-app#8.** Until that
lands, example-app's `main` is still 0.16, and this PR's "Example repos"
check builds `main`.

## What changes

- **`scripts/check-examples.sh` clones each example's default branch
again**, as it did before the move. #597 made it fall back to `main`
when an example's `zig-0.17` branch is gone; with both examples' 0.17
PRs landed (fizzyedit/example-plugin#13, and example-app#8 just before
this), the plain clone is all that's left.
- **The dvui-dev pin is tagged**, per `docs/DEPENDENCIES.md` rule 2
("tag, then pin"): `fizzy-sdk-0.2.30-7` → `1b29a16` on `zig-0.17`, what
SDK 0.2.30 pins. The pin's comment and `docs/DEPENDENCIES.md` say so.
The table names the `zig-0.17` branch, and the `zig/0.17` wording
becomes "since fizzy moved to Zig 0.17 (#575)".

## SDK impact

- [x] None.

## Verified

- [x] `scripts/check-fmt.sh` clean; `bash -n scripts/check-examples.sh`.
- [ ] The example repos at `main`: CI, once example-app#8 is in.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
foxnne added a commit that referenced this pull request Oct 19, 2026
#606)

Stacked on #601 and based on its branch, so the diff is
this change alone; GitHub retargets it to `main` when #601 merges. It
takes up the follow-ups that PR lists.

## What changes

**For plugin authors:** a new optional
`Plugin.VTable.documentBytes(state, doc, path, allocator) → []u8`. It
returns the bytes a save to `path` would write, for a copy that is
**not** a save, with none of a save's bookkeeping or side effects: no
format on save, no edit remembered for `documentWritten`, no undo stop.
fizzy takes these bytes:

- for the crash checkpoint (`KeptDocuments.capture` from `Checkpoint`,
every few seconds of typing)
- for a restart or a plugin reload carrying unsaved work
- for a tape's file (`Tracks.fileAt`)
- for a `fizzy.document.changed` listener that asks for the unsaved text

An owner without the hook keeps working as before:
`Plugin.documentBytes` falls back to `documentSnapshot` +
`encodeSnapshot`, bookkeeping included.

Saves keep the snapshot: `DocumentIo.save`, and the web download
(`Editor.downloadDocument`), which now calls the new `Plugin.saveBytes`
(both halves of a save at once, followed by `documentWritten`).

**Why:** `documentSnapshot` is "the storage-agnostic half of saving". It
runs at a save's start, so it formats on save and records which edit the
bytes stand for. Every non-save copy did the same. In the text plugin
that meant:

1. With `format_on_save` on (off by default), each checkpoint ran the
formatter on a dirty document while the person was typing in it.
2. A checkpoint taken while a save's write was in flight overwrote
`serialized_op_id`. If an edit came in between, the write landed and
`documentWritten` marked the document clean at an edit newer than the
file on disk.

**Implemented in:**

- **text**: the hook returns the text as it stands.
- **archive**: it had the same in-flight bug through
`serialized_generation`, so it gets the hook too (`doc.pack`, with no
generation recorded).

`Document.savedBytes`'s comment now says only a save takes it.
`docs/PLUGINS.md` names the hook, and its storage-agnostic section now
names the snapshot pair, which is what a save uses.

**Tests** (`tests/integration.zig`, the tour test's "A document's steps"
block, after #601's save check):

- **Format on save on, with a stand-in formatter:** a
`KeptDocuments.capture` keeps the text as typed and leaves the document
unformatted. A real save (`saveBytes`) still formats, which shows the
formatter was live.
- **A checkpoint while a save is in flight:** take a save's snapshot at
"a", type "b", take a checkpoint, then land the write
(`documentWritten`). The document is still dirty.

Each check fails without the text plugin's hook: the first with
`formatted` where `as typed` was expected, the second with the document
clean.

## SDK impact

- [ ] None
- [ ] Core-only or additive: reaches plugins at the next SDK release
- [x] Fingerprint moved: recorded in `sdk/src/version.zig`,
`sdk_version` untouched, PR labelled `sdk`
- [ ] SDK release: bumps `sdk_version`, lists the `sdk` PRs since the
last `sdk-v*` tag

A new optional vtable field, null by default. An existing plugin builds
unchanged and gets the fallback, which behaves as before.

**pixi** (`fizzyedit/pixi`) implements `documentSnapshot` and has both
problems in its own form:

- `File.saveSnapshot` sets `editor.saving_bookmark = history.bookmark`,
so a checkpoint during a save moves the bookmark that `written` cleans
to.
- It also calls `finishReveal()`, so a checkpoint ends a reveal in
progress.

pixi would need a `documentBytes` that builds the same `Snapshot`
content without those two lines, encodes it in place (`File.encode`),
and destroys it. The `.pixi` zip encode then runs on the UI thread at
each checkpoint, as it already does through the fallback today.

## Verified

- [x] macOS: `zig build test-integration` (80/80 steps; the two new
checks each fail with the text hook removed), `zig build`, `zig build
test` (113/113), `check-web` (42/42), `test-sdk-version` (35/35).
`scripts/check-fmt.sh` flags only
`backend/src/platform/win32_titlebar.zig`, which this branch's base
(#601's) predates `main`'s fix for (#597); untouched here.
- [ ] Windows:
- [ ] Linux: CI
- [ ] Web: `check-web` builds; the download path was not run

## Follow-ups

- pixi's `documentBytes` is written and builds against this branch's
SDK, with pixi's `zig build test` passing. It's a local change for the
pixi repo, pushed at the repin that brings this SDK, since SDK 0.2.30
has no such field. It splits `saveSnapshot` into the save's bookkeeping
around a `takeSnapshot` that changes nothing. A drawing still being
revealed is completed in the copy, as `captureState` does; a flat image
is the one case that still finishes the reveal, because its composite is
read back from the GPU.
- The checkpoint still encodes on the UI thread for every owner. If a
large document shows up in a frame, the seam is to snapshot through the
hook and encode on `DocumentIo`'s worker.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant