Refine inspector and icon-only controls for fluid interaction #10

Open
opened 2026-09-13 13:34:41 +00:00 by kayg · 21 comments
Owner

Request and current status

References and inventory exist. Some formatting tooltip/shortcut changes are integrated; broader inspector polish is unfinished.

Acceptance

Preserve context/focus while switching sections; truthful icon help and working shortcuts; accessible labels. Verify popovers, hover/pressed/disabled states, keyboard and narrow layouts. Apply existing Emil/Jakub guidance with native controls.

Keep open until the user-facing outcome is verified in a delivered build. Source review or a successful build alone is not completion.

## Request and current status References and inventory exist. Some formatting tooltip/shortcut changes are integrated; broader inspector polish is unfinished. ## Acceptance Preserve context/focus while switching sections; truthful icon help and working shortcuts; accessible labels. Verify popovers, hover/pressed/disabled states, keyboard and narrow layouts. Apply existing Emil/Jakub guidance with native controls. Keep open until the user-facing outcome is verified in a delivered build. Source review or a successful build alone is not completion.
Author
Owner

Role: task agent (read-only audit)
Worktree: /Users/kayg/Developer/calternal-app/.worktrees/editor-overnight-combined at 9153c4beda
State: audited; no files changed and no build/runtime claim made.

Concrete audit against current code and Craft acceptance artifacts:

  • Implemented: the editor has a native borderless nonactivating formatting panel with screen clamping, focus restoration, selection anchoring and dismissal on focus/scroll/window changes. FormattingActionDescriptor centralizes eight icon labels and truthful Bold/Italic tooltips/shortcuts. The app has native inspector presentation through SwiftUI .inspector, with Insert/Format/Style/Info sections and native Picker/Stepper/Button controls. The app-level Format menu exposes selection formatting and asset insertion; the shell toolbar has native inspector toggle help.
  • Missing/partial: only Bold and Italic have focused-editor shortcuts; Strike, Code, Link, Heading, List and Task descriptors currently have no shortcut glyph/handler. The app Format menu does not mirror the eight formatting actions. The inspector tab is local @State, so section/context restoration across inspector recreation is not explicit; controls have labels but no comprehensive disabled/pressed/keyboard/narrow-layout verification. There is no pointer-near ellipsis/dwell entry point for formatting, and the existing panel always anchors to the text selection. Image-specific inspector/menu/Quick Look, orthogonal size/fit controls and exact attachment targeting remain absent per the inventory.

Smallest independent implementation plan:

  1. Finish truthful formatting descriptors and focused key routing in Sources/CalternalEditor/BlockEditorView.swift; mirror enabled actions through App/Sources/App/CalternalApp.swift and Sources/CalternalEditor/NoteEditorRegistry.swift (or the existing command seam). Preserve ⌘K for Add Link and choose collision-free bindings for the remaining actions. Extend Tests/CalternalEditorTests/MarkdownBlockDocumentTests.swift from the existing Bold/Italic shortcut seam, including marked text, raw mode, unavailable actions and one undo transaction.
  2. Make inspector section state deliberate at App/Sources/Viewer/ViewerView.swift / App/Sources/Notes/NoteEditorSession.swift only if user requires restoration across teardown; otherwise add accessibility identifiers and state/keyboard tests around the existing Picker/Stepper controls. Keep style mutations in NotePresentationStyle and preserve focus when changing sections.
  3. Add the pointer-near formatting entry at the existing BlockEditorView hover/adornment seam, preferably with a small FormattingToolbarController.swift extraction. Use one cancellable dwell task, no entrance animation, and reuse the existing panel with a point anchor. Avoid the drag owner’s active changes.
  4. Treat image targeting/Quick Look and Size/Fit as a separate later slice owned by BlockEditorView.swift, EditorImagePresentation.swift, a new EditorImageQuickLookController.swift, and focused image geometry tests; do not mix it into the inspector shortcut patch.

Dependencies/order: shortcut truth first; inspector persistence/accessibility second; pointer-near entry third; image controls are independent but larger. Risks: screenshot evidence does not establish dwell duration, motion curves, shortcut semantics beyond existing ⌘B/⌘I, or persistence format for image settings. Do not invent Markdown syntax or claim Craft parity without VM/user acceptance. Validation requires build-host focused tests plus VM checks for popover placement, keyboard/disabled states, narrow width, reduced motion/transparency, VoiceOver labels/order and focus continuity.

Role: task agent (read-only audit) Worktree: /Users/kayg/Developer/calternal-app/.worktrees/editor-overnight-combined at 9153c4beda1d32b3e65b29f6d1a32f65453cfd4c State: audited; no files changed and no build/runtime claim made. Concrete audit against current code and Craft acceptance artifacts: - Implemented: the editor has a native borderless nonactivating formatting panel with screen clamping, focus restoration, selection anchoring and dismissal on focus/scroll/window changes. `FormattingActionDescriptor` centralizes eight icon labels and truthful Bold/Italic tooltips/shortcuts. The app has native inspector presentation through SwiftUI `.inspector`, with Insert/Format/Style/Info sections and native Picker/Stepper/Button controls. The app-level Format menu exposes selection formatting and asset insertion; the shell toolbar has native inspector toggle help. - Missing/partial: only Bold and Italic have focused-editor shortcuts; Strike, Code, Link, Heading, List and Task descriptors currently have no shortcut glyph/handler. The app Format menu does not mirror the eight formatting actions. The inspector tab is local `@State`, so section/context restoration across inspector recreation is not explicit; controls have labels but no comprehensive disabled/pressed/keyboard/narrow-layout verification. There is no pointer-near ellipsis/dwell entry point for formatting, and the existing panel always anchors to the text selection. Image-specific inspector/menu/Quick Look, orthogonal size/fit controls and exact attachment targeting remain absent per the inventory. Smallest independent implementation plan: 1. Finish truthful formatting descriptors and focused key routing in `Sources/CalternalEditor/BlockEditorView.swift`; mirror enabled actions through `App/Sources/App/CalternalApp.swift` and `Sources/CalternalEditor/NoteEditorRegistry.swift` (or the existing command seam). Preserve ⌘K for Add Link and choose collision-free bindings for the remaining actions. Extend `Tests/CalternalEditorTests/MarkdownBlockDocumentTests.swift` from the existing Bold/Italic shortcut seam, including marked text, raw mode, unavailable actions and one undo transaction. 2. Make inspector section state deliberate at `App/Sources/Viewer/ViewerView.swift` / `App/Sources/Notes/NoteEditorSession.swift` only if user requires restoration across teardown; otherwise add accessibility identifiers and state/keyboard tests around the existing Picker/Stepper controls. Keep style mutations in `NotePresentationStyle` and preserve focus when changing sections. 3. Add the pointer-near formatting entry at the existing `BlockEditorView` hover/adornment seam, preferably with a small `FormattingToolbarController.swift` extraction. Use one cancellable dwell task, no entrance animation, and reuse the existing panel with a point anchor. Avoid the drag owner’s active changes. 4. Treat image targeting/Quick Look and Size/Fit as a separate later slice owned by `BlockEditorView.swift`, `EditorImagePresentation.swift`, a new `EditorImageQuickLookController.swift`, and focused image geometry tests; do not mix it into the inspector shortcut patch. Dependencies/order: shortcut truth first; inspector persistence/accessibility second; pointer-near entry third; image controls are independent but larger. Risks: screenshot evidence does not establish dwell duration, motion curves, shortcut semantics beyond existing ⌘B/⌘I, or persistence format for image settings. Do not invent Markdown syntax or claim Craft parity without VM/user acceptance. Validation requires build-host focused tests plus VM checks for popover placement, keyboard/disabled states, narrow width, reduced motion/transparency, VoiceOver labels/order and focus continuity.
Author
Owner

Correction to the earlier audit: the central worktree is now at fb4c66d5956379f3218d84a7a4fd4037ecc608e2 (clean at audit time), not the historical 9153c4be cited above. In the current source, FormattingActionDescriptor covers all eight actions with native icon labels, tooltips, and accessibility help; Bold and Italic additionally have real focused-editor shortcuts (⌘B/⌘I) routed by handleFormattingShortcut. The remaining gap is specifically that Strike, Inline Code, Heading, List, Task, and Link have no key equivalents/glyphs, and the app Format menu does not mirror all eight actions. The existing inspector/panel findings remain partial and unverified in runtime; no implementation or completion claim is being made.

Correction to the earlier audit: the central worktree is now at `fb4c66d5956379f3218d84a7a4fd4037ecc608e2` (clean at audit time), not the historical `9153c4be` cited above. In the current source, `FormattingActionDescriptor` covers all eight actions with native icon labels, tooltips, and accessibility help; Bold and Italic additionally have real focused-editor shortcuts (`⌘B`/`⌘I`) routed by `handleFormattingShortcut`. The remaining gap is specifically that Strike, Inline Code, Heading, List, Task, and Link have no key equivalents/glyphs, and the app Format menu does not mirror all eight actions. The existing inspector/panel findings remain partial and unverified in runtime; no implementation or completion claim is being made.
Author
Owner

Bounded inspector-only follow-up (kept independent of the active editor owner):

  • Candidate owned files: new App/Sources/Viewer/NoteInspectorState.swift for the section enum/selection persistence policy, new App/Sources/Viewer/NoteInspectorControls.swift for reusable native Picker/Stepper/ControlGroup rows and accessibility identifiers, plus a new App/UITests/NoteInspectorUITests.swift fixture target. Do not edit Sources/CalternalEditor/BlockEditorView.swift or formatting shortcut code in this slice.
  • Integration seam: DocumentInspectorView/the current private NoteInspectorView in App/Sources/Viewer/ViewerView.swift will need a small follow-up wiring change to inject the state and controls. Keep that integration separate from the editor-owner branch so the new files can be reviewed independently.
  • Acceptance: switching Insert/Format/Style/Info retains the selected section while the inspector remains mounted; reopening follows the documented session policy; every icon-only/native control has an AX label/help and stable identifier; disabled controls reflect rendered/raw/loading state; keyboard navigation and narrow inspector widths preserve focus and do not collapse labels. Runtime validation belongs on the VM with screenshots plus AX state. This does not claim formatting shortcut or image-control completion; those remain separate dependencies.
Bounded inspector-only follow-up (kept independent of the active editor owner): - Candidate owned files: new `App/Sources/Viewer/NoteInspectorState.swift` for the section enum/selection persistence policy, new `App/Sources/Viewer/NoteInspectorControls.swift` for reusable native Picker/Stepper/ControlGroup rows and accessibility identifiers, plus a new `App/UITests/NoteInspectorUITests.swift` fixture target. Do not edit `Sources/CalternalEditor/BlockEditorView.swift` or formatting shortcut code in this slice. - Integration seam: `DocumentInspectorView`/the current private `NoteInspectorView` in `App/Sources/Viewer/ViewerView.swift` will need a small follow-up wiring change to inject the state and controls. Keep that integration separate from the editor-owner branch so the new files can be reviewed independently. - Acceptance: switching Insert/Format/Style/Info retains the selected section while the inspector remains mounted; reopening follows the documented session policy; every icon-only/native control has an AX label/help and stable identifier; disabled controls reflect rendered/raw/loading state; keyboard navigation and narrow inspector widths preserve focus and do not collapse labels. Runtime validation belongs on the VM with screenshots plus AX state. This does not claim formatting shortcut or image-control completion; those remain separate dependencies.
Author
Owner

Implementation plan for the assigned inspector-only slice (worktree wave16/inspector-polish, base 37c5d40de40a2d0b279aad8d13d6f68837533c2d):

  1. Add a small NoteInspectorState.swift containing the existing tab enum and its stable raw-value/title/accessibility metadata. Use scene-scoped state for the selected section so inspector recreation preserves context without adding session/editor ownership.
  2. Add NoteInspectorControls.swift only for repeated native control labeling/AX identifiers if the extraction removes duplication; otherwise keep controls in the existing inspector view to avoid an abstraction-only layer.
  3. Wire the current NoteInspectorView in App/Sources/Viewer/ViewerView.swift to the state metadata, stable note.inspector.section identifier, explicit accessibility labels/values, and truthful disabled/help text for rendered/raw/loading and formatting availability. Preserve the existing native .inspector and focus path.
  4. Add one focused UI state test covering section switching, inspector recreation, and disabled formatting insertion in raw mode. No editor/projection edits and no cosmetic-only parallel tests.

Reviewer handoff will include the exact diff and limitations; build/VM validation remains the root build pipeline’s responsibility.

Implementation plan for the assigned inspector-only slice (worktree `wave16/inspector-polish`, base `37c5d40de40a2d0b279aad8d13d6f68837533c2d`): 1. Add a small `NoteInspectorState.swift` containing the existing tab enum and its stable raw-value/title/accessibility metadata. Use scene-scoped state for the selected section so inspector recreation preserves context without adding session/editor ownership. 2. Add `NoteInspectorControls.swift` only for repeated native control labeling/AX identifiers if the extraction removes duplication; otherwise keep controls in the existing inspector view to avoid an abstraction-only layer. 3. Wire the current `NoteInspectorView` in `App/Sources/Viewer/ViewerView.swift` to the state metadata, stable `note.inspector.section` identifier, explicit accessibility labels/values, and truthful disabled/help text for rendered/raw/loading and formatting availability. Preserve the existing native `.inspector` and focus path. 4. Add one focused UI state test covering section switching, inspector recreation, and disabled formatting insertion in raw mode. No editor/projection edits and no cosmetic-only parallel tests. Reviewer handoff will include the exact diff and limitations; build/VM validation remains the root build pipeline’s responsibility.
Author
Owner

Implementation ready in worktree /Users/kayg/Developer/calternal-app/.worktrees/inspector-polish (pending commit).

Bounded changes:

  • Moved inspector section identity into NoteInspectorSection and persisted the selected raw value with @SceneStorage so inspector recreation keeps the active context.
  • Added native accessibility identifiers, section values, help text, and stable style control identifiers.
  • Formatting actions now require rendered mode, interaction enabled, and a non-empty availableFormattingActions set, so the inspector does not advertise an unavailable formatting action.
  • Added one focused UI test covering synthetic note inspector discovery, default Style section value, and disabled formatting without a selection.

No BlockEditorView or MarkdownProjection changes. Local validation is limited to git diff --check; build and VM UI execution remain for root/build_pipeline_recover and QA.

Implementation ready in worktree /Users/kayg/Developer/calternal-app/.worktrees/inspector-polish (pending commit). Bounded changes: - Moved inspector section identity into NoteInspectorSection and persisted the selected raw value with @SceneStorage so inspector recreation keeps the active context. - Added native accessibility identifiers, section values, help text, and stable style control identifiers. - Formatting actions now require rendered mode, interaction enabled, and a non-empty availableFormattingActions set, so the inspector does not advertise an unavailable formatting action. - Added one focused UI test covering synthetic note inspector discovery, default Style section value, and disabled formatting without a selection. No BlockEditorView or MarkdownProjection changes. Local validation is limited to git diff --check; build and VM UI execution remain for root/build_pipeline_recover and QA.
Author
Owner

Implementation ready in worktree /Users/kayg/Developer/calternal-app/.worktrees/inspector-polish (pending commit).

Bounded changes:

  • Moved inspector section identity into NoteInspectorSection and persisted the selected raw value with @SceneStorage so inspector recreation keeps the active context.
  • Added native accessibility identifiers, section values, help text, and stable style control identifiers.
  • Formatting actions now require rendered mode, interaction enabled, and a non-empty availableFormattingActions set, so the inspector does not advertise an unavailable formatting action.
  • Added one focused UI test covering synthetic note inspector discovery, default Style section value, and disabled formatting without a selection.

No BlockEditorView or MarkdownProjection changes. Local validation is limited to git diff --check; build and VM UI execution remain for root/build_pipeline_recover and QA.

Implementation ready in worktree /Users/kayg/Developer/calternal-app/.worktrees/inspector-polish (pending commit). Bounded changes: - Moved inspector section identity into NoteInspectorSection and persisted the selected raw value with @SceneStorage so inspector recreation keeps the active context. - Added native accessibility identifiers, section values, help text, and stable style control identifiers. - Formatting actions now require rendered mode, interaction enabled, and a non-empty availableFormattingActions set, so the inspector does not advertise an unavailable formatting action. - Added one focused UI test covering synthetic note inspector discovery, default Style section value, and disabled formatting without a selection. No BlockEditorView or MarkdownProjection changes. Local validation is limited to git diff --check; build and VM UI execution remain for root/build_pipeline_recover and QA.
Author
Owner

Reviewer verdict — exact d10f0cd349ec7d140a2609e4d777027038637b53 is not source-passed

Parent: 37c5d40de40a2d0b279aad8d13d6f68837533c2d. Worktree .worktrees/inspector-polish is clean; exact scope is NoteInspectorState.swift, ViewerView.swift, and NoteInspectorUITests.swift. Source review only; no build or UI run.

Findings:

  • P1 — App/UITests/NoteInspectorUITests.swift:6-33: the new test's core expectation is contrary to production behavior and is likely to fail. BlockEditorView.formattingAvailability() exposes Heading/List/Task actions for a collapsed caret in an eligible paragraph or heading; it does not require a nonempty text selection. The synthetic “Design review” note begins with eligible heading/paragraph blocks, and NoteEditorHost publishes availability without requiring editor focus. After opening Format, Open formatting toolbar should therefore normally be enabled, while line 32 asserts disabled. Fix the test and copy to distinguish inline text formatting from block formatting. To exercise disabled state, switch the session to raw mode through the real “Toggle Rendered / Raw Markdown” command (as the implementation plan promised), then assert disabled; return to rendered/caret and assert enabled.

  • P2 — App/UITests/NoteInspectorUITests.swift:6-33: the test does not cover the feature this patch primarily adds. It never changes the section value, recreates/reopens the inspector, verifies restoration, checks focus continuity, or exercises keyboard/narrow layout. It also locates the segmented control as otherElements and assumes each segment is an XCUI button without validating the actual macOS AX roles. Fix the single focused UI test to switch Style→Format/Insert, assert the picker value, close/reopen the inspector or navigate away/back in the same scene, and assert the retained section using the runtime AX roles. Include the raw/rendered availability transition in that same test.

  • P2 — App/Sources/Viewer/ViewerView.swift:985-1102: availability remains inconsistent across inspector controls. The formatting buttons now mirror availableFormattingActions, but “Image or file…”, style pickers/steppers, background controls, and Reset remain enabled while their session methods reject work during loading or disabled interaction (requestAssetInsertion and applyAppearance both guard those states). This leaves clickable no-op controls and does not meet the issue's disabled-state acceptance. Add one shared canEditInspector = session.document != nil && !session.isLoading && session.isInteractionEnabled and disable the affected sections/controls; formatting additionally requires rendered mode and nonempty formatting availability.

  • P3 — App/Sources/Viewer/ViewerView.swift:935-960: an unknown restored raw value renders Style content/accessibility text while the segmented Picker remains bound to a tag that does not exist. This can show content and control selection out of sync after a future case rename/removal or stale scene restoration. Bind the Picker through a validated Binding that reads/writes NoteInspectorSection (or normalize tabRawValue on appearance) so fallback also repairs the stored value.

  • P3 — ViewerView.swift:996-1018: both formatting helps say “current text selection,” but caret-only block formatting is supported. Use wording such as “current selection or block” so help and disabled behavior are truthful. The background checkmark at lines 1083-1085 is decorative and should be accessibility-hidden or given a meaningful value rather than exposing a symbol name.

Compile plausibility: the enum, @SceneStorage, segmented Picker tags, and accessibility modifiers are SwiftUI-valid, and xcodegen source globs include both new files. Exact gate remains pending repair and a new SHA.

Reviewer verdict — exact `d10f0cd349ec7d140a2609e4d777027038637b53` is **not source-passed** Parent: `37c5d40de40a2d0b279aad8d13d6f68837533c2d`. Worktree `.worktrees/inspector-polish` is clean; exact scope is `NoteInspectorState.swift`, `ViewerView.swift`, and `NoteInspectorUITests.swift`. Source review only; no build or UI run. Findings: - **P1 — `App/UITests/NoteInspectorUITests.swift:6-33`: the new test's core expectation is contrary to production behavior and is likely to fail.** `BlockEditorView.formattingAvailability()` exposes Heading/List/Task actions for a collapsed caret in an eligible paragraph or heading; it does not require a nonempty text selection. The synthetic “Design review” note begins with eligible heading/paragraph blocks, and `NoteEditorHost` publishes availability without requiring editor focus. After opening Format, `Open formatting toolbar` should therefore normally be enabled, while line 32 asserts disabled. Fix the test and copy to distinguish inline text formatting from block formatting. To exercise disabled state, switch the session to raw mode through the real “Toggle Rendered / Raw Markdown” command (as the implementation plan promised), then assert disabled; return to rendered/caret and assert enabled. - **P2 — `App/UITests/NoteInspectorUITests.swift:6-33`: the test does not cover the feature this patch primarily adds.** It never changes the section value, recreates/reopens the inspector, verifies restoration, checks focus continuity, or exercises keyboard/narrow layout. It also locates the segmented control as `otherElements` and assumes each segment is an XCUI `button` without validating the actual macOS AX roles. Fix the single focused UI test to switch Style→Format/Insert, assert the picker value, close/reopen the inspector or navigate away/back in the same scene, and assert the retained section using the runtime AX roles. Include the raw/rendered availability transition in that same test. - **P2 — `App/Sources/Viewer/ViewerView.swift:985-1102`: availability remains inconsistent across inspector controls.** The formatting buttons now mirror `availableFormattingActions`, but “Image or file…”, style pickers/steppers, background controls, and Reset remain enabled while their session methods reject work during loading or disabled interaction (`requestAssetInsertion` and `applyAppearance` both guard those states). This leaves clickable no-op controls and does not meet the issue's disabled-state acceptance. Add one shared `canEditInspector = session.document != nil && !session.isLoading && session.isInteractionEnabled` and disable the affected sections/controls; formatting additionally requires rendered mode and nonempty formatting availability. - **P3 — `App/Sources/Viewer/ViewerView.swift:935-960`: an unknown restored raw value renders Style content/accessibility text while the segmented Picker remains bound to a tag that does not exist.** This can show content and control selection out of sync after a future case rename/removal or stale scene restoration. Bind the Picker through a validated `Binding` that reads/writes `NoteInspectorSection` (or normalize `tabRawValue` on appearance) so fallback also repairs the stored value. - **P3 — `ViewerView.swift:996-1018`: both formatting helps say “current text selection,” but caret-only block formatting is supported.** Use wording such as “current selection or block” so help and disabled behavior are truthful. The background checkmark at lines 1083-1085 is decorative and should be accessibility-hidden or given a meaningful value rather than exposing a symbol name. Compile plausibility: the enum, `@SceneStorage`, segmented Picker tags, and accessibility modifiers are SwiftUI-valid, and xcodegen source globs include both new files. Exact gate remains pending repair and a new SHA.
Author
Owner

Reviewer repair candidate: exact 72f8960d89089da40d3b9520398af86ddb4f5515 in .worktrees/inspector-polish.

Repairs:

  • Formatting availability now distinguishes rendered caret/block availability from raw mode and includes document/loading/interaction gates. Help text says “current selection or block”.
  • Asset insertion and all style controls are disabled while the session is loading, has no document, or interaction is disabled, matching session guards. Decorative background checkmark is AX-hidden.
  • Inspector Picker uses a validated Binding and onAppear normalization, so stale SceneStorage values cannot leave content and selected segment inconsistent.
  • UI test now reaches the synthetic note, asserts rendered block formatting is enabled, hides/reopens the inspector through the real ⌘⌥1 command and verifies Format restoration, then toggles raw mode through ⇧⌘M and verifies formatting is disabled before returning rendered mode.

Validation: git diff --check passes. No local build or VM claim; root build/QA remain required. No BlockEditorView or projection changes.

Reviewer repair candidate: exact `72f8960d89089da40d3b9520398af86ddb4f5515` in `.worktrees/inspector-polish`. Repairs: - Formatting availability now distinguishes rendered caret/block availability from raw mode and includes document/loading/interaction gates. Help text says “current selection or block”. - Asset insertion and all style controls are disabled while the session is loading, has no document, or interaction is disabled, matching session guards. Decorative background checkmark is AX-hidden. - Inspector Picker uses a validated Binding and onAppear normalization, so stale SceneStorage values cannot leave content and selected segment inconsistent. - UI test now reaches the synthetic note, asserts rendered block formatting is enabled, hides/reopens the inspector through the real ⌘⌥1 command and verifies Format restoration, then toggles raw mode through ⇧⌘M and verifies formatting is disabled before returning rendered mode. Validation: git diff --check passes. No local build or VM claim; root build/QA remain required. No BlockEditorView or projection changes.
Author
Owner

Reviewer verdict — exact 72f8960d89089da40d3b9520398af86ddb4f5515 remains not source-passed

Parent: 37c5d40de40a2d0b279aad8d13d6f68837533c2d. Worktree is clean and diff-check clean. The product source fixes the prior availability/help/raw-value findings: inspector controls share the session editability gate, formatting includes real action availability, stale section values normalize to Style, and decorative status imagery is AX-hidden. SwiftUI compile plausibility is sound. Source/test review only; no build or UI run.

Remaining findings:

  • P1 — App/UITests/NoteInspectorUITests.swift:25-27: the test assumes Style is always the initial section even though this patch intentionally persists the section with @SceneStorage. The test itself switches to Format and leaves it there, so a restored/repeated app scene may begin on Format and fail before testing anything. Scene storage is not a clean per-test default. Fix by explicitly selecting Style as test setup (without asserting it was the launch default), or launch through a deterministic test-only scene-state reset; then switch to Format and test hide/reopen persistence.

  • P2 — NoteInspectorUITests.swift:32-50: enabled-state assertions are unsynchronized with the asynchronous note host and rendered/raw host replacement. waitForExistence only waits for the button object, not for availableFormattingActions or isEnabled to update. The immediate XCTAssertTrue(formatButton.isEnabled) after note load and immediate disabled assertion after Command-Shift-M can race SwiftUI observation/host teardown. Use predicate expectations for enabled == true, then enabled == false, and optionally rendered re-enable after toggling back.

  • P3 coverage — NoteInspectorUITests.swift:25-50: focus continuity, segmented-control keyboard navigation, and narrow inspector layout remain unverified. The test invokes global keyboard shortcuts but never captures/asserts first responder before/after section switching, never changes the section from the keyboard, and never narrows the window. Keep these listed as pending VM/UI acceptance, or add bounded assertions if this candidate is meant to satisfy issue #10 rather than only section persistence/availability.

The earlier incorrect “formatting requires nonempty text selection” premise is fixed: rendered caret/block formatting is now asserted enabled, and raw mode is the disabled case. Exact gate is pending deterministic state setup and enabled/disabled waits.

Reviewer verdict — exact `72f8960d89089da40d3b9520398af86ddb4f5515` remains **not source-passed** Parent: `37c5d40de40a2d0b279aad8d13d6f68837533c2d`. Worktree is clean and diff-check clean. The product source fixes the prior availability/help/raw-value findings: inspector controls share the session editability gate, formatting includes real action availability, stale section values normalize to Style, and decorative status imagery is AX-hidden. SwiftUI compile plausibility is sound. Source/test review only; no build or UI run. Remaining findings: - **P1 — `App/UITests/NoteInspectorUITests.swift:25-27`: the test assumes Style is always the initial section even though this patch intentionally persists the section with `@SceneStorage`.** The test itself switches to Format and leaves it there, so a restored/repeated app scene may begin on Format and fail before testing anything. Scene storage is not a clean per-test default. Fix by explicitly selecting Style as test setup (without asserting it was the launch default), or launch through a deterministic test-only scene-state reset; then switch to Format and test hide/reopen persistence. - **P2 — `NoteInspectorUITests.swift:32-50`: enabled-state assertions are unsynchronized with the asynchronous note host and rendered/raw host replacement.** `waitForExistence` only waits for the button object, not for `availableFormattingActions` or `isEnabled` to update. The immediate `XCTAssertTrue(formatButton.isEnabled)` after note load and immediate disabled assertion after Command-Shift-M can race SwiftUI observation/host teardown. Use predicate expectations for `enabled == true`, then `enabled == false`, and optionally rendered re-enable after toggling back. - **P3 coverage — `NoteInspectorUITests.swift:25-50`: focus continuity, segmented-control keyboard navigation, and narrow inspector layout remain unverified.** The test invokes global keyboard shortcuts but never captures/asserts first responder before/after section switching, never changes the section from the keyboard, and never narrows the window. Keep these listed as pending VM/UI acceptance, or add bounded assertions if this candidate is meant to satisfy issue #10 rather than only section persistence/availability. The earlier incorrect “formatting requires nonempty text selection” premise is fixed: rendered caret/block formatting is now asserted enabled, and raw mode is the disabled case. Exact gate is pending deterministic state setup and enabled/disabled waits.
Author
Owner

Determinism repair candidate: exact aaa7fbfe79028d2a297c98447d9e9e504c65fd4c.

UI test repairs:

  • Explicitly clicks Style before asserting the initial section, so prior SceneStorage from another test/run cannot invalidate setup.
  • Uses bounded polling for section AX values and enabled/disabled formatting state to accommodate asynchronous editor-host publication.
  • Keeps the real rendered caret/block availability assertion, toggles inspector via ⌘⌥1, verifies Format restoration, toggles raw mode via ⇧⌘M, verifies disabled formatting, then verifies rendered recovery.
  • Test scope remains one focused state/availability test. Focus continuity, keyboard traversal beyond command shortcuts, and narrow-width layout remain pending VM QA; no claim is made for those here.

Production changes remain the reviewed 72f repairs. git diff --check passes; no local build or VM claim.

Determinism repair candidate: exact `aaa7fbfe79028d2a297c98447d9e9e504c65fd4c`. UI test repairs: - Explicitly clicks Style before asserting the initial section, so prior SceneStorage from another test/run cannot invalidate setup. - Uses bounded polling for section AX values and enabled/disabled formatting state to accommodate asynchronous editor-host publication. - Keeps the real rendered caret/block availability assertion, toggles inspector via ⌘⌥1, verifies Format restoration, toggles raw mode via ⇧⌘M, verifies disabled formatting, then verifies rendered recovery. - Test scope remains one focused state/availability test. Focus continuity, keyboard traversal beyond command shortcuts, and narrow-width layout remain pending VM QA; no claim is made for those here. Production changes remain the reviewed 72f repairs. `git diff --check` passes; no local build or VM claim.
Author
Owner

Reviewer verdict — exact aaa7fbfe79028d2a297c98447d9e9e504c65fd4c remains not source-passed

Parent: 37c5d40de40a2d0b279aad8d13d6f68837533c2d. Worktree and diff-check are clean. The deterministic Style setup and bounded enabled/value polling fix the prior SceneStorage-default and asynchronous availability races. Product SwiftUI/state/availability code remains source-sound. No build or UI run.

Remaining finding:

  • P2 — App/UITests/NoteInspectorUITests.swift:39-45: the test does not establish inspector recreation before asserting SceneStorage restoration. It sends Command-Option-1 twice back-to-back without waiting for the inspector to disappear. SwiftUI can coalesce the false→true state updates in one render transaction, leaving the same NoteInspectorView mounted; the subsequent “Format section” assertion can therefore pass on unchanged local state even if restoration is broken. After the first shortcut, require the identified section element to become nonexistent (for example waitForNonExistence(timeout:)); only then send the reopen shortcut, reacquire the element, and assert Format. This makes the test exercise teardown/recreation rather than a toggle round trip in one update cycle.

Coverage limit, not a product-source failure: focus continuity, segmented-control keyboard navigation, narrow inspector width, hover/pressed visuals, and real AX role discovery remain pending VM/UI verification. Do not claim those acceptance items passed from this test.

Exact gate remains pending the teardown wait amendment.

Reviewer verdict — exact `aaa7fbfe79028d2a297c98447d9e9e504c65fd4c` remains **not source-passed** Parent: `37c5d40de40a2d0b279aad8d13d6f68837533c2d`. Worktree and diff-check are clean. The deterministic Style setup and bounded enabled/value polling fix the prior SceneStorage-default and asynchronous availability races. Product SwiftUI/state/availability code remains source-sound. No build or UI run. Remaining finding: - **P2 — `App/UITests/NoteInspectorUITests.swift:39-45`: the test does not establish inspector recreation before asserting SceneStorage restoration.** It sends Command-Option-1 twice back-to-back without waiting for the inspector to disappear. SwiftUI can coalesce the false→true state updates in one render transaction, leaving the same `NoteInspectorView` mounted; the subsequent “Format section” assertion can therefore pass on unchanged local state even if restoration is broken. After the first shortcut, require the identified section element to become nonexistent (for example `waitForNonExistence(timeout:)`); only then send the reopen shortcut, reacquire the element, and assert Format. This makes the test exercise teardown/recreation rather than a toggle round trip in one update cycle. Coverage limit, not a product-source failure: focus continuity, segmented-control keyboard navigation, narrow inspector width, hover/pressed visuals, and real AX role discovery remain pending VM/UI verification. Do not claim those acceptance items passed from this test. Exact gate remains pending the teardown wait amendment.
Author
Owner

Final UI test lifecycle repair: exact ea36484bb7e59b2324131056de8ffa98289719a5.

After issuing ⌘⌥1 to hide the inspector, the test now waits for the section element to disappear before reopening. It then reacquires the section and formatting button elements from the new inspector instance before asserting restored Format state and raw/rendered availability. This removes SwiftUI coalescing ambiguity and makes the recreation assertion meaningful.

git diff --check passes. Focus continuity, keyboard traversal, and narrow layout remain pending VM acceptance. No local build claim.

Final UI test lifecycle repair: exact `ea36484bb7e59b2324131056de8ffa98289719a5`. After issuing ⌘⌥1 to hide the inspector, the test now waits for the section element to disappear before reopening. It then reacquires the section and formatting button elements from the new inspector instance before asserting restored Format state and raw/rendered availability. This removes SwiftUI coalescing ambiguity and makes the recreation assertion meaningful. `git diff --check` passes. Focus continuity, keyboard traversal, and narrow layout remain pending VM acceptance. No local build claim.
Author
Owner

Reviewer transition — exact source gate PASS for ea36484bb7e59b2324131056de8ffa98289719a5

Parent: 37c5d40de40a2d0b279aad8d13d6f68837533c2d. Worktree .worktrees/inspector-polish is clean and the cumulative diff-check passes. Exact scope remains NoteInspectorState.swift, ViewerView.swift, and NoteInspectorUITests.swift.

No remaining P1–P3 source findings. The UI regression now waits until the original inspector section element is nonexistent before reopening, reacquires the section and formatting elements, verifies Format restoration, and uses bounded waits for rendered/raw/rendered availability availability. SceneStorage setup is deterministic, stale raw values normalize, editability gates mirror session guards, caret/block formatting help is truthful, and the SwiftUI/XCUITest APIs are compile-plausible.

Verification limit: source review only. Actual build/UI execution, focus continuity, segmented-control keyboard traversal, narrow inspector layout, hover/pressed visuals, and runtime AX role discovery remain pending. Keep issue #10 open through those checks and delivered-build user verification.

Reviewer transition — exact source gate **PASS** for `ea36484bb7e59b2324131056de8ffa98289719a5` Parent: `37c5d40de40a2d0b279aad8d13d6f68837533c2d`. Worktree `.worktrees/inspector-polish` is clean and the cumulative diff-check passes. Exact scope remains `NoteInspectorState.swift`, `ViewerView.swift`, and `NoteInspectorUITests.swift`. No remaining P1–P3 source findings. The UI regression now waits until the original inspector section element is nonexistent before reopening, reacquires the section and formatting elements, verifies Format restoration, and uses bounded waits for rendered/raw/rendered availability availability. SceneStorage setup is deterministic, stale raw values normalize, editability gates mirror session guards, caret/block formatting help is truthful, and the SwiftUI/XCUITest APIs are compile-plausible. Verification limit: source review only. Actual build/UI execution, focus continuity, segmented-control keyboard traversal, narrow inspector layout, hover/pressed visuals, and runtime AX role discovery remain pending. Keep issue #10 open through those checks and delivered-build user verification.
Author
Owner

Root: inspector source candidate ea36484b passed independent review and is now integrated into wave14/editor-overnight-combined. Changes restore section state with validated values, expose truthful native help/accessibility metadata, and gate asset/style/format actions against current session availability. Root inspected the product diff and integration is clean.

The existing 37c5 preview is not restaged; this inspector change queues for the next immutable build with image/transcription changes. Build and native UI verification remain pending, including actual focus continuity, keyboard navigation, narrow width and hover/pressed state. No user-acceptance claim; #10 remains open.

Root: inspector source candidate ea36484b passed independent review and is now integrated into wave14/editor-overnight-combined. Changes restore section state with validated values, expose truthful native help/accessibility metadata, and gate asset/style/format actions against current session availability. Root inspected the product diff and integration is clean. The existing 37c5 preview is not restaged; this inspector change queues for the next immutable build with image/transcription changes. Build and native UI verification remain pending, including actual focus continuity, keyboard navigation, narrow width and hover/pressed state. No user-acceptance claim; #10 remains open.
Author
Owner

Build worker /root/build_pipeline_recover has frozen .worktrees/editor-overnight-combined at exact 56e61d2e4d8da6915fc693a99b2d09d8b5160863, tree 3a21c99da5c7c0ab3ae8ec2d949439b5a0c5e5a3, including reviewed inspector commit 56e61d2e. The sole agents@mbp lane is starting exact-source SwiftPM gates followed by an immutable arm64 Release build.

No inspector-specific GUI test is being claimed by this package gate. Focus continuity, keyboard navigation, narrow layout, hover/pressed visuals, runtime AX roles, and user acceptance remain pending; keep #10 open.

<!-- BUILD-START-56E-ISSUE10-20260913 --> Build worker `/root/build_pipeline_recover` has frozen `.worktrees/editor-overnight-combined` at exact `56e61d2e4d8da6915fc693a99b2d09d8b5160863`, tree `3a21c99da5c7c0ab3ae8ec2d949439b5a0c5e5a3`, including reviewed inspector commit `56e61d2e`. The sole `agents@mbp` lane is starting exact-source SwiftPM gates followed by an immutable arm64 Release build. No inspector-specific GUI test is being claimed by this package gate. Focus continuity, keyboard navigation, narrow layout, hover/pressed visuals, runtime AX roles, and user acceptance remain pending; keep #10 open.
Author
Owner

Exact central source 56e61d2e4d8da6915fc693a99b2d09d8b5160863 (tree 3a21c99da5c7c0ab3ae8ec2d949439b5a0c5e5a3) compiled successfully in the SwiftPM Release test lane on agents@mbp; source archive SHA-256 27152b42a01b253d4aa6d439fa28f5f76c71a4903c88c0796469566c5bf35a69, manifest SHA-256 265ca17b8c524f85dacfc2169a6d6a9b69de81ecf0b76de1dfa4cec2f1574abe, package binary SHA-256 5f4cca0e70958fe0b328dbb9c081b560648b259be79b70264c094e2a932fc2fd.

No inspector-specific UI test ran in this package lane. Release is held by an independent focus-selection assertion failure. Inspector runtime/AX/visual/user gates remain pending; keep #10 open.

<!-- TEST-RESULT-56E-ISSUE10-20260913 --> Exact central source `56e61d2e4d8da6915fc693a99b2d09d8b5160863` (`tree 3a21c99da5c7c0ab3ae8ec2d949439b5a0c5e5a3`) compiled successfully in the SwiftPM Release test lane on `agents@mbp`; source archive SHA-256 `27152b42a01b253d4aa6d439fa28f5f76c71a4903c88c0796469566c5bf35a69`, manifest SHA-256 `265ca17b8c524f85dacfc2169a6d6a9b69de81ecf0b76de1dfa4cec2f1574abe`, package binary SHA-256 `5f4cca0e70958fe0b328dbb9c081b560648b259be79b70264c094e2a932fc2fd`. No inspector-specific UI test ran in this package lane. Release is held by an independent focus-selection assertion failure. Inspector runtime/AX/visual/user gates remain pending; keep #10 open.
Author
Owner

The integrated inspector candidate is present in exact Release source 0e835eed87233ab1156fbef86c0286e18a45fa90, tree 48fca32ee4a06602470d50e7cc5ebe953081d018, which compiled successfully on agents@mbp. Source archive SHA-256 7abfd7108583fe70696e53e6e615057e142b6ce6e83f3a5ff736b5c9b93959ec; manifest SHA-256 3a2c2afd60ad995ce4d8bf3dc1c60e65e3376eaef8344d8d056b7933d95afd65.

Verified arm64 archive: /Users/Shared/CalternalBuilds/0e835eed8723-3507d319/Calternal-0e835eed8723-Release-arm64.zip, also staged at /Users/lume/CalternalQA/0e835eed8723-3507d319/; zip SHA-256 a18cecf74cb32fd205201b21783b2a7df56aec77a081e04d3c791f6377b4e0ee, executable SHA-256 e2ce47b34c64f73d5b7d57384e9b17bc13379658138803ab56ec670246965226. Fresh-unzip strict codesign and bundle diff passed.

No inspector-specific UI test or GUI was run by the build worker. Focus continuity, keyboard traversal, narrow layout, hover/pressed visuals, runtime AX roles, and user acceptance remain pending; keep #10 open.

<!-- BUILD-RESULT-0E835EED-ISSUE10-20260913 --> The integrated inspector candidate is present in exact Release source `0e835eed87233ab1156fbef86c0286e18a45fa90`, tree `48fca32ee4a06602470d50e7cc5ebe953081d018`, which compiled successfully on `agents@mbp`. Source archive SHA-256 `7abfd7108583fe70696e53e6e615057e142b6ce6e83f3a5ff736b5c9b93959ec`; manifest SHA-256 `3a2c2afd60ad995ce4d8bf3dc1c60e65e3376eaef8344d8d056b7933d95afd65`. Verified arm64 archive: `/Users/Shared/CalternalBuilds/0e835eed8723-3507d319/Calternal-0e835eed8723-Release-arm64.zip`, also staged at `/Users/lume/CalternalQA/0e835eed8723-3507d319/`; zip SHA-256 `a18cecf74cb32fd205201b21783b2a7df56aec77a081e04d3c791f6377b4e0ee`, executable SHA-256 `e2ce47b34c64f73d5b7d57384e9b17bc13379658138803ab56ec670246965226`. Fresh-unzip strict codesign and bundle diff passed. No inspector-specific UI test or GUI was run by the build worker. Focus continuity, keyboard traversal, narrow layout, hover/pressed visuals, runtime AX roles, and user acceptance remain pending; keep #10 open.
Author
Owner

0e835 VM visual check (exact zip/executable hashes recorded in 01-integrity.txt): PASS for the bounded inspector restoration case.

Using a registered disposable note with a visible inline image, I hid Inspector through its native toolbar control and restored it with the same control. The restored frame shows Inspector with Insert/Format/Style/Info and the Style controls intact. Evidence: 27-inspector-hidden.png and 29-inspector-restored.png in .agents/native-break/0e835-vm-qa/.

This is not a close recommendation: focus preservation while section-switching, icon tooltips/shortcuts, keyboard, disabled, hover/pressed and narrow-layout cases remain unverified.

0e835 VM visual check (exact zip/executable hashes recorded in `01-integrity.txt`): PASS for the bounded inspector restoration case. Using a registered disposable note with a visible inline image, I hid Inspector through its native toolbar control and restored it with the same control. The restored frame shows Inspector with Insert/Format/Style/Info and the Style controls intact. Evidence: `27-inspector-hidden.png` and `29-inspector-restored.png` in `.agents/native-break/0e835-vm-qa/`. This is not a close recommendation: focus preservation while section-switching, icon tooltips/shortcuts, keyboard, disabled, hover/pressed and narrow-layout cases remain unverified.
Author
Owner

Desktop preview26eb155253241603ec8f1a89e263a7a8cd496341 installed and launched at ~/Applications/Calternal.app after normal native Quit. Root verified signature, executable SHA8c37e0f228c29040fb062265c0c1acf5ec8685ea2aade2ace558127f014be649, process, expected Space, restored prior note selection, and Style inspector. No notes/settings files were edited by the installer. Previous37c bundle retained for rollback. Test focus: previously failing existing-event edit, explicit date change, first-line title visual/rename. Native title save/rename passed; native Undo remains unverified and hosted XCTest async teardown aborts (including pre-feature control) remain open; event timing-test correction awaits rerun. This preview does NOT contain pending margins/hover/codeblock/cross-eventdialog changes. No stable/performance acceptance.

Desktop preview26eb155253241603ec8f1a89e263a7a8cd496341 installed and launched at ~/Applications/Calternal.app after normal native Quit. Root verified signature, executable SHA8c37e0f228c29040fb062265c0c1acf5ec8685ea2aade2ace558127f014be649, process, expected Space, restored prior note selection, and Style inspector. No notes/settings files were edited by the installer. Previous37c bundle retained for rollback. Test focus: previously failing existing-event edit, explicit date change, first-line title visual/rename. Native title save/rename passed; native Undo remains unverified and hosted XCTest async teardown aborts (including pre-feature control) remain open; event timing-test correction awaits rerun. This preview does NOT contain pending margins/hover/codeblock/cross-eventdialog changes. No stable/performance acceptance.
Author
Owner

Task /root/editor_polish_inventory — next-combined-preview acceptance handoff (planning only; no GUI/build).

Already established: inspector product/test candidate ea36484b passed source review and compiled in 0e835eed; the earlier VM check proved hide/restore with Style controls. It did not prove focus, keyboard, tooltip, or narrow-layout behavior.

Remaining VM checks, owned by /root on the next exact combined build: with a live editor caret, traverse Insert/Format/Style/Info by pointer and keyboard, confirm the caret/focus returns predictably, and inspect every icon's native tooltip/accessibility name plus only truthful implemented shortcuts. Exercise disabled state in raw mode and recovery in rendered mode, hover/pressed visuals, and a narrow inspector without clipping. Include image-selection context so image controls and inspector section changes do not steal/stick focus. Keep #10 open.

Task `/root/editor_polish_inventory` — next-combined-preview acceptance handoff (planning only; no GUI/build). Already established: inspector product/test candidate `ea36484b` passed source review and compiled in `0e835eed`; the earlier VM check proved hide/restore with Style controls. It did not prove focus, keyboard, tooltip, or narrow-layout behavior. Remaining VM checks, owned by `/root` on the next exact combined build: with a live editor caret, traverse Insert/Format/Style/Info by pointer and keyboard, confirm the caret/focus returns predictably, and inspect every icon's native tooltip/accessibility name plus only truthful implemented shortcuts. Exercise disabled state in raw mode and recovery in rendered mode, hover/pressed visuals, and a narrow inspector without clipping. Include image-selection context so image controls and inspector section changes do not steal/stick focus. Keep #10 open.
Author
Owner

Remote preservation checkpoint — 2026-09-14

The following original-worktree candidates are now pushed and exact hashes verified on both Forgejo and GitHub. These are preserved candidates/diagnostics, not a claim of new acceptance; some may already be integrated by cherry-pick or superseded. Use the issue’s existing evidence before choosing changes to resume.

  • wave16/inspector-polish — ea36484bb7e59b2324131056de8ffa98289719a5

Master #20 contains the resume instructions. No force push; dev remains 1d8f4adf.

Remote preservation checkpoint — 2026-09-14 The following original-worktree candidates are now pushed and exact hashes verified on both Forgejo and GitHub. These are preserved candidates/diagnostics, not a claim of new acceptance; some may already be integrated by cherry-pick or superseded. Use the issue’s existing evidence before choosing changes to resume. - `wave16/inspector-polish` — `ea36484bb7e59b2324131056de8ffa98289719a5` Master #20 contains the resume instructions. No force push; dev remains 1d8f4adf.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal-macos#10
No description provided.