Skip to content

app: whose frame it is, and bubbles that say who - #475

Merged
foxnne merged 3 commits into
mainfrom
app/authors
Oct 16, 2026
Merged

foxnne merged 3 commits into
mainfrom
app/authors

Conversation

@foxnne

@foxnne foxnne commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #474 (the SDK half); review that first. Part of fizzyedit/plans#14: plans/SHARED_HISTORY_PLAN.md, step 2, as amended in fizzyedit/plans#21.

What changes

The app now says who is acting, using #474's Host.act and setInputAuthor.

  • The frame's input author.
    • Editor.tick sets it where input is consumed: around the active document's tick, native menu actions, the layout's draw and floats, then around plugin keybinds, the keymap, overlays and the palette.
    • It clears it around plugins' endFrame. Plugins' beginFrame and event delivery run with none, as the plan says: they act for themselves, or are nobody's.
    • The author is the person's, or a tape's while one drives (Demo.author). The demo player and the live driver stop for a real press or key before the frame's input is consumed, so a frame a person takes over is theirs.
  • Tapes act. A tape's command ops run inside act as the tape (Demo's stage command), and a live tape's as whoever it plays for. A demo's author is its title; a live tape played by nobody in particular is "a tape".
  • automation.Api.playAs(bytes, author) (service version 6): a live tape played for an author. An agent's pointer tape (fizzy_act) is then the agent's. Plain play leaves the tape its own author. The service tells the app through a new OnAuthor hook, beside its Other.
  • Bubbles name agents. An edit made while an agent acts shows as "Claude · Draw". The person's own edits stay plain, as the plan has it, and so does a demo narrating itself. The plan says "others", but prefixing every bubble of a playing demo with its title cluttered the demo; that's a judgement call for review.
  • The integration check. The whole-editor test asserts the tour adds no unattributed step. Owners report every step only from the plan's step 3, so today it guards the steps reported while recording.

SDK impact

  • None
  • Core-only or additive: reaches plugins at the next SDK release. The automation service is versioned on its own (service_version 5 → 6), so a plugin built for version 5 gets null from getServiceTyped on this host and degrades. The agent plugin is the one consumer: it moves to playAs with its repin.
  • Fingerprint moved
  • SDK release

Verified

  • macOS:
    • Unit test: an agent-acting edit's activity title is "Claude · Draw", the person's "Draw".
    • Gates: zig build, zig build test, check-fmt. test-integration, check-web and test-sdk-version results are in a comment below once they finish.
  • Not tried by hand: a demo's edits attributed while it plays, and an agent's pointer tape through playAs. The agent plugin calls playAs after the SDK release; that PR will show it end to end.

🤖 Generated with Claude Code

foxnne and others added 2 commits October 16, 2026 16:45
The first half of plans/SHARED_HISTORY_PLAN.md's step 2 (as amended in fizzyedit/plans#21):
who made each step of a document's history, kept by the host on the channel owners already
report through (Host.recordStep, fizzy#456).

- sdk.Author: the person, an agent, a tape, or nobody known; identity is kind, plugin and session.
- Host.act / endAct / acted / actAgain / author: who is acting. Innermost wins; an outermost act
  starts a run; work put off acts again as its stored author and run.
- Host.setInputAuthor: the frame's input author, for the app to set where input is consumed.
- Host.recordStep keeps who made every step not the person's, per document, by step id, and the
  document's top; the recorder still hears a step only while recording. Working alone, nothing
  is kept. Host.stepAuthor, topStep, mayMerge; forgetDocumentAuthors when a document closes.
- Step.top: the entry on top after a step, so Undo can name whose step it takes back.

The fingerprint moves. Nothing calls act yet, and owners report steps only while recording until
the plan's step 3, so nothing changes for a person yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The app half of plans/SHARED_HISTORY_PLAN.md's step 2, on the host's authors (the PR below):

- The frame's input author: Editor.tick sets it around where input is consumed (the layout's
  draw, keybinds, overlays, the palette) and clears it around plugins' frame hooks: the person's,
  or a tape's while one drives (Demo.author), the drivers having already stopped for real input.
- A tape's commands act as the tape (Demo's stage command), a live tape as whoever it plays for.
- automation.Api.playAs (service version 6): play a live tape for an author, so an agent's
  pointer tape is the agent's. play alone leaves the tape its own author.
- An agent's edit says whose in the activity bubble ("Claude · Draw"). The person's, and a demo's
  narrating itself, stay plain.
- The whole-editor test asserts the tour adds no unattributed step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@foxnne

foxnne commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator Author

Gates on this head (macOS): check-fmt, zig build, zig build test, test-sdk-version (no move beyond #474's), check-web, and test-integration (53/53 steps, 555/555 tests, with the new attribution check) all pass.

@foxnne
foxnne marked this pull request as ready for review October 16, 2026 21:53
Base automatically changed from sdk/authors to main October 16, 2026 22:07
#474 landed squashed; this branch carried its original commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@foxnne
foxnne merged commit 6de2df8 into main Oct 16, 2026
11 checks passed
@foxnne
foxnne deleted the app/authors branch October 16, 2026 22:38
foxnne added a commit that referenced this pull request Oct 17, 2026
…g joins (#479)

Part of fizzyedit/plans#14: `plans/SHARED_HISTORY_PLAN.md`, step 3
(text's half; pixi's follows in its repo).

## What changes

- **Text reports every step** through `Host.recordStep`, not only while
recording. The host keeps who made each one (#474); working alone, it
keeps nothing. Encoding a step's `effect` still happens only while the
document is recorded, so a document nobody records costs one call per
step.
- **Each step carries `top`:** the last applied entry after it
(`History.lastApplied`), for added, joined, undone and redone alike. The
host knows the top step and its author without asking for the line,
which Undo's "Undo Claude's …" label (step 5) needs.
- **One hand's typing never joins another's run.** `History.end` takes
`may_join`. The editor's edit hook fills it from `Host.mayMerge` on the
step on top. When that step is someone else's, VSCode's grouping rule
doesn't get to fold the new keystroke into it: an agent typing doesn't
extend the person's step, nor the person an agent's.
- **Typing calls `documentEdited`,** as its doc comment always said it
did. A person's typing runs no command, so it still raises no activity
bubble.

## SDK impact

- [x] None. Text is built in, and #474's API is used as is.

## Verified

- [x] macOS:
- **New unit test:** an edit with `may_join = false` starts a step of
its own where VSCode's rule would have joined it. The existing history
tests pass `true` and behave as before.
- **`zig build test`:** 573/574 (1 skipped). `check-tests-reached`
passes.
- **`test-integration`:** 53/53 steps, 556/556 tests. The whole-editor
test's check from #475, that the tour adds no unattributed step, now
covers real steps: the tour's typing and commands are each attributed to
the tape. Two warnings print, and both are on unmodified `main` too (a
demo replay mismatch and a float position).
  - `check-fmt`, `check-web`, `test-sdk-version`.

🤖 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 17, 2026
## What changes

`sdk_version` goes from 0.2.28 to 0.2.29. Merging this tags
`sdk-v0.2.29` and publishes its tarball.

**Why now:** authors (#474, #475) need a release before plugins can use
them:
- the agent acts as its connection around each command, and plays its
pointer tapes with `playAs`;
- chat acts around its writes;
- pixi's calls that wait out the person's stroke keep their author
(`plans/SHARED_HISTORY_PLAN.md` step 2's plugin PRs).

## SDK impact

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

**`sdk` PRs since `sdk-v0.2.28`:**
- **#474:** who made each step.
- `sdk.Author`; `Host.act` / `endAct` / `acted` / `actAgain` / `author`
/ `setInputAuthor`.
  - The host keeps a per-document author map filled in `recordStep`.
- `stepAuthor`, `topStep`, `mayMerge`, `forgetDocumentAuthors`, and
`Step.top`.
- The fingerprint moved. Everything is additive (a defaulted field, new
functions).

**Reaching plugins, no fingerprint move:**
- **#475:** the automation service's `playAs(bytes, author)`
(`service_version` 5 → 6). Activity titles name an acting agent ("Claude
· Draw").
- **#468:** `core`: `MenuRowOptions.anchor`, a stable name for a menu
row's button.

## Verified

- [x] macOS:
- On this head, `zig build test-sdk-version` passes, and
`scripts/pack-sdk.sh` packs `fizzy-sdk-v0.2.29.tar.gz`.
- fizzyedit/pixi, fizzyedit/agent and fizzyedit/atlas `main` build
against this `sdk/` (`--fork`) with no changes.
- [ ] Windows:
- [ ] Linux: CI.
- [ ] Web:

## Follow-ups

- The repin automation opens `sdk: repin to fizzy SDK 0.2.29` PRs in the
store plugins whose fingerprint moved.
- The agent has no repin automation: its repin is a hand-made PR,
carrying the agent's `act` around `agentCall` and `playAs` for its
pointer tapes.
- Chat's repin carries its `act` around ACP writes.

🤖 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