Shot action text and summary (#46) #97

Merged
crowmaki merged 1 commit from issue-46-shot-action-text into main 2026-10-08 19:37:46 +00:00
Owner

Closes #46.

A filmmaker can describe each Shot's beat in their own words, with exact dialogue (User Stories 99–101 and 104). The prompt composer (#48) will read these documents.

What changed

  • Schema v18. shot gains action_text and summary. Each is a JSON node document of text, mention{kind,id} and dialogue{line_id} nodes. NULL means the Shot follows the pre-fill. A new shot_mention(shot_id, kind, entity_id) table is rewritten from both documents on every save. Shot and Setup deletes take the rows along, and undo restores them.

  • Pre-fill. The action text is pre-filled from the Shot's countable Lines, one Line per line of text. These become mentions:

    • Character names and aliases written in capitals or in title case
    • Prop names, in any case
  • Dialogue chips. Each dialogue Line is one dialogue node. A save is refused unless the chips are the Shot's dialogue Lines, once each, in script order.

  • Parentheticals that name a Character move out of the quote into a sentence before the chip, without brackets (@MARY to @MARK.). The chip records the moved parentheticals (moved) and is flagged reword until the user clears it. A parenthetical that comes to name a Character later, such as one naming a Character created after the save, moves and is flagged the same way the next time the text is read.

  • Reconcile on read. A saved action text is fitted to the Shot's current Lines when it is read:

    • chips of Lines the Shot no longer covers drop out
    • chips of Lines it newly covers come in before the next chip, or at the end

    Moving or splitting a Shot never loses its text.

  • Summary. Pre-filled from the first sentence of the action text, chips skipped. It holds text and mentions only.

  • Undo. set_shot_action_text / set_shot_summary are undoable, and None returns to the pre-fill. Saving the pre-fill unchanged records nothing.

  • Merges. Character and Location merges rewrite the documents and shot_mention inside the merge transaction, from a snapshot that undo restores.

  • Deletes. A Character, Location or Prop that a saved document mentions can't be deleted (require_not_mentioned).

  • Scenes view. Each Shot gets an Action block:

    • the text between chips is edited as separate runs, so chips cannot be moved or deleted
    • mentions show as pills, and typing @ opens a Bits Popover picker anchored at the caret
    • a Reword badge appears, with Done on the chip to clear it
    • Reset to lines, and an editable summary
  • CONTEXT.md gains an Action text entry.

Decisions worth a look

  • Location mentions. The story says Characters and Props. Locations are mentionable too, because the merge criterion implies Location mentions exist. #48 can map them to <Environment>.
  • dialogue carries reword and moved besides line_id. moved makes the quote stable: the quote no longer depends on which names exist when it is read.
  • Pre-fill isn't stored. Mentions found only by the pre-fill don't hold an entity back from deletion. Merged names still resolve through aliases.
  • Split. The first part keeps its saved text, including mentions of Lines it no longer covers. Only chips are reconciled.
  • Undo granularity. Each run commits on blur, so editing several runs makes several undo steps.
  • The editor normalizes runs client-side. It joins neighbouring text the way the core does, only to decide whether a blur changed anything.

Tests

  • crates/studio-core/tests/action_text.rs has 15 tests:
    • pre-fill, including mentions found through merged aliases
    • the parenthetical rule, including a Character created after the save
    • the first-sentence summary
    • chip order: missing, repeated, swapped, and non-dialogue chips
    • mention validation
    • undo, redo and reset
    • reconcile after moving a Shot
    • Shot and Setup delete with undo
    • delete guards
    • Character and Location merge rewrite, including a chained merge, which proves the mention table moved
  • Unit tests cover name matching and first-sentence splitting.
  • A migration test checks that a Shot from v17 follows the pre-fill. The notation migration test now also winds back v18.
  • The adapter smoke test round-trips the action text and summary and rejects an unknown mention kind.
  • src/lib/scenes/actionText.test.ts covers runs, mention queries and choices, chip captions and plain text.
  • Full cargo test --workspace --all-features (506 passed), bun test src (109 passed) and bun run check pass. Clippy adds no new warnings.
  • Run in the real app. Checked:
    • the pre-fill and the chips
    • the Reword flag, with Done and Ctrl+Z
    • the @ picker: arrow keys, Enter, and saving on blur
Closes #46. A filmmaker can describe each Shot's beat in their own words, with exact dialogue (User Stories 99–101 and 104). The prompt composer (#48) will read these documents. ## What changed - **Schema v18.** `shot` gains `action_text` and `summary`. Each is a JSON node document of `text`, `mention{kind,id}` and `dialogue{line_id}` nodes. NULL means the Shot follows the pre-fill. A new `shot_mention(shot_id, kind, entity_id)` table is rewritten from both documents on every save. Shot and Setup deletes take the rows along, and undo restores them. - **Pre-fill.** The action text is pre-filled from the Shot's countable Lines, one Line per line of text. These become mentions: - Character names and aliases written in capitals or in title case - Prop names, in any case - **Dialogue chips.** Each dialogue Line is one `dialogue` node. A save is refused unless the chips are the Shot's dialogue Lines, once each, in script order. - **Parentheticals that name a Character** move out of the quote into a sentence before the chip, without brackets (`@MARY to @MARK.`). The chip records the moved parentheticals (`moved`) and is flagged `reword` until the user clears it. A parenthetical that comes to name a Character later, such as one naming a Character created after the save, moves and is flagged the same way the next time the text is read. - **Reconcile on read.** A saved action text is fitted to the Shot's current Lines when it is read: - chips of Lines the Shot no longer covers drop out - chips of Lines it newly covers come in before the next chip, or at the end Moving or splitting a Shot never loses its text. - **Summary.** Pre-filled from the first sentence of the action text, chips skipped. It holds text and mentions only. - **Undo.** `set_shot_action_text` / `set_shot_summary` are undoable, and `None` returns to the pre-fill. Saving the pre-fill unchanged records nothing. - **Merges.** Character and Location merges rewrite the documents and `shot_mention` inside the merge transaction, from a snapshot that undo restores. - **Deletes.** A Character, Location or Prop that a saved document mentions can't be deleted (`require_not_mentioned`). - **Scenes view.** Each Shot gets an Action block: - the text between chips is edited as separate runs, so chips cannot be moved or deleted - mentions show as pills, and typing `@` opens a Bits Popover picker anchored at the caret - a Reword badge appears, with Done on the chip to clear it - Reset to lines, and an editable summary - `CONTEXT.md` gains an **Action text** entry. ## Decisions worth a look - **Location mentions.** The story says Characters and Props. Locations are mentionable too, because the merge criterion implies Location mentions exist. #48 can map them to `<Environment>`. - **`dialogue` carries `reword` and `moved`** besides `line_id`. `moved` makes the quote stable: the quote no longer depends on which names exist when it is read. - **Pre-fill isn't stored.** Mentions found only by the pre-fill don't hold an entity back from deletion. Merged names still resolve through aliases. - **Split.** The first part keeps its saved text, including mentions of Lines it no longer covers. Only chips are reconciled. - **Undo granularity.** Each run commits on blur, so editing several runs makes several undo steps. - **The editor normalizes runs client-side.** It joins neighbouring text the way the core does, only to decide whether a blur changed anything. ## Tests - `crates/studio-core/tests/action_text.rs` has 15 tests: - pre-fill, including mentions found through merged aliases - the parenthetical rule, including a Character created after the save - the first-sentence summary - chip order: missing, repeated, swapped, and non-dialogue chips - mention validation - undo, redo and reset - reconcile after moving a Shot - Shot and Setup delete with undo - delete guards - Character and Location merge rewrite, including a chained merge, which proves the mention table moved - Unit tests cover name matching and first-sentence splitting. - A migration test checks that a Shot from v17 follows the pre-fill. The notation migration test now also winds back v18. - The adapter smoke test round-trips the action text and summary and rejects an unknown mention kind. - `src/lib/scenes/actionText.test.ts` covers runs, mention queries and choices, chip captions and plain text. - Full `cargo test --workspace --all-features` (506 passed), `bun test src` (109 passed) and `bun run check` pass. Clippy adds no new warnings. - **Run in the real app.** Checked: - the pre-fill and the chips - the Reword flag, with Done and Ctrl+Z - the `@` picker: arrow keys, Enter, and saving on blur
A filmmaker can describe each Shot's beat in their own words, with exact
dialogue.

- Schema v18: action_text and summary on shot, each a JSON node document
  (text, mention{kind,id}, dialogue{line_id}), plus a shot_mention table
  rewritten from them on every save. NULL follows the pre-fill.
- The action text is pre-filled from the Shot's Lines. Character names and
  aliases in capitals or title case, and Prop names in any case, become
  mentions. Dialogue Lines are chips, once each in script order; saving a
  text whose chips are missing, repeated or reordered is refused.
- A parenthetical that names a Character moves out of the quote into an
  action sentence before its chip. The chip records it as moved and is
  flagged for rewording until cleared. One that comes to name a Character
  later moves the same way.
- A saved text is fitted to the Shot's Lines as it is read, so moving or
  splitting a Shot drops and adds chips without losing the text.
- The summary is pre-filled from the action text's first sentence.
- Saving either is undoable. Character and Location merges rewrite the
  documents and mention table in the merge transaction, and undo restores
  them. An entity a saved text mentions cannot be deleted.
- Each Shot in the Scenes view gets an Action block: runs of text between
  fixed dialogue chips, @-mentions picked from a Bits popover, Reset to
  lines, and the summary.
crowmaki deleted branch issue-46-shot-action-text 2026-10-08 19:37:46 +00:00
Sign in to join this conversation.
No description provided.