Build the Raw Source outlet

The escape hatch: View > Raw Source (opt-cmd-E) unmounts the whole
content area for the literal on-disk index.md in a plain monospaced
editor with Cancel/Apply. Raw source is window-level state, not a third
body mode — entry rides setMode(.preview), which flushes the Edit
session by construction, then reads the file fresh; exit reveals
Preview, and an empty body after Apply does not reopen Edit (openIfNeeded
already ran). Apply validates the proposed bytes through the loader's
own card checks — parseDocument's strict UTF-8/BOM rejection, schema,
order — deliberately skipping the uneditable-shape refusal, since a
flow-mapping card is exactly what the hatch repairs; invalid bytes
alert in place with the loader's own error and no bracket opens. The
write is byte-for-byte with no modified stamp and no modified-by clear,
per 01's explicit carve-out — the verbatim contract outranks stamping —
and identical bytes write nothing. Escape cancels, cmd-Return applies,
toggle-off applies too, and cmd-E disables while raw is active via a
testable predicate. Tombstoned targets refuse as vanished: a foreign
delete is never reverted by a stale buffer.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
2026-07-28 11:25:25 -04:00
parent e989c1f26e
commit 40c0a75c24
12 changed files with 1733 additions and 65 deletions
+19 -33
View File
@@ -6,18 +6,22 @@ import SwiftUI
///
/// 11-command-nexus.md's own contract runs both directions: "a command absent here doesn't exist, and
/// adding one means adding a row here first" so once a row *is* in the Nexus, shipping the window
/// behind it is a validation-and-action change, not a menu change. `FutureCommand` (a `Button`) and
/// `FutureToggleCommand` (a `Toggle`) below are that reading, applied: the row exists now, stably
/// titled and stably chorded `NSUserKeyEquivalents` already resolves it, so a user can remap it
/// today with validation pinned to `false` and the action a no-op until the milestone named at the
/// call site fills both in. That milestone's whole diff then reads as "flip `.disabled`, fill the
/// closure" rather than "add a menu item", which is also why every call site below carries the
/// codebase's `mN-` marker for a component still owed.
/// behind it is a validation-and-action change, not a menu change. `FutureCommand` below is that
/// reading, applied: the row exists now, stably titled and stably chorded `NSUserKeyEquivalents`
/// already resolves it, so a user can remap it today with validation pinned to `false` and the
/// action a no-op until the milestone named at the call site fills both in. That milestone's whole
/// diff then reads as "flip `.disabled`, fill the closure" rather than "add a menu item", which is
/// also why every call site below carries the codebase's `mN-` marker for a component still owed.
///
/// **The title never moves once a row ships**, disabled or not: a toggle wired live later must not
/// **The title never moves once a row ships**, disabled or not: a command wired live later must not
/// gain a second spelling on the way (04-interactions.md Configurable bindings "toggles keep one
/// stable title, checkmark state only" which applies to a row that has not started ticking yet
/// exactly as it does to one that has).
///
/// There was a `FutureToggleCommand` beside this a disabled `Toggle` for a checkmark row and it
/// went with the last of its call sites (Raw Source, `RawSourceCommand`). Every row still owed is a
/// plain command; a future checkmark row brings its scaffold back with it rather than keeping an
/// unused one warm.
struct FutureCommand: View {
let title: String
var key: KeyEquivalent?
@@ -32,22 +36,6 @@ struct FutureCommand: View {
}
}
/// `FutureCommand`'s checkmark-state twin, for a row the Nexus already marks "(checkmark toggle)".
///
/// `isOn` is a constant `false` rather than real state: there is no session yet for a binding to
/// read, which is exactly the disabled, unchecked state a not-yet-wired toggle should show.
struct FutureToggleCommand: View {
let title: String
var key: KeyEquivalent?
var modifiers: EventModifiers = .command
var body: some View {
Toggle(title, isOn: .constant(false))
.keyboardShortcut(key.map { KeyboardShortcut($0, modifiers: modifiers) })
.disabled(true)
}
}
// MARK: - File Save as Template
/// File Save as Template no default chord (11-command-nexus.md; 09-templates.md).
@@ -108,21 +96,19 @@ struct FindSteppingCommands: View {
/// View Edit Body (E) / Raw Source (E) / History the card window's three view-state rows
/// (11-command-nexus.md).
///
/// **Edit Body is live** (`EditBodyCommand`, beside the focused value it reads): the body column's
/// Preview/Edit toggle, checkmark state and all. Its diff was the one `FutureCommand` promises
/// the title and the chord did not move, the validation and the action filled in.
/// **Edit Body and Raw Source are both live** (`EditBodyCommand`, `RawSourceCommand`, each beside the
/// focused value it reads): the body column's Preview/Edit toggle, and the window-level outlet whose
/// toggling-off *applies*. Each diff was the one `FutureCommand` promises the title and the chord
/// did not move, the validation and the action filled in and the pair also carries the clause that
/// joins them, "Edit Body disables while Raw Source is active" (05-card-window.md).
///
// m6-raw-source: Raw Source is the same shape one card later a checkmark toggle over a
// window-level mode, which also adds the "Edit Body disables while Raw Source is active" clause to
// the row above (05-card-window.md).
//
// m6-card-sidebar: History is a plain command that focuses the sidebar's History section, and
// disables outright on mode `none` / repo-nested boards once that section exists (05-card-window.md,
// 07-sync-collab.md). Both remain unconditionally disabled here neither surface exists yet.
// 07-sync-collab.md). It remains unconditionally disabled here that surface does not exist yet.
struct CardViewCommands: View {
var body: some View {
EditBodyCommand()
FutureToggleCommand(title: "Raw Source", key: "e", modifiers: [.option, .command])
RawSourceCommand()
FutureCommand(title: "History")
}
}