The git surfaces leave the glass — tab, trail, branch line, and the remote pair, peeled
Step 3 of strategy/01-git-excision.md: the popover strip is Info/Theme/Sync, the titlebar widget says the name alone, the card window's History section and its slot go, Board ▸ Pull/Push comes out with the RemoteCommands scaffold, and View ▸ History re-tags from the commit trail to the deferred foreign-change journal. The Sync placeholder re-annotates to the future ops-based sync service. Four git test suites leave with the surfaces they pinned (BoardGitSetup, BoardInfoPopover, BranchSwitch, GitUndo). The git engine still compiles underneath, unreferenced by UI. 2,890 tests green. Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
This commit is contained in:
@@ -257,7 +257,7 @@ final class CardWindowSession: CardSessionFlushing {
|
||||
///
|
||||
/// This file owns identity, lifecycle, the title and subtitle, and where the window opens. The
|
||||
/// two-column composition inside it is `CardWindowView`'s, and what fills those columns — the title
|
||||
/// field, Preview/Edit, the sidebar's five sections — arrives card by card underneath a composition
|
||||
/// field, Preview/Edit, the sidebar's four sections — arrives card by card underneath a composition
|
||||
/// that does not move. The *window-scoped* state those surfaces need lives here, because a window is
|
||||
/// what it is scoped to: the body column's mode (`CardBodyPresentation`) and the raw-source outlet
|
||||
/// (`CardRawSourceSession`), both published through the focus system so the View menu's rows can
|
||||
@@ -288,9 +288,6 @@ struct CardWindowHost: View {
|
||||
/// snapshot the store applies — a cache that died with the view would regenerate every thumbnail
|
||||
/// on every reload (`AttachmentThumbnailCache`).
|
||||
@State private var thumbnails = AttachmentThumbnailCache()
|
||||
/// This card's commit trail (05-card-window.md ▸ History). Held here for `thumbnails`' reason —
|
||||
/// it must survive every snapshot — and surfaced to the view only in git mode (`cardHistory`).
|
||||
@State private var history = CardHistory()
|
||||
/// Whether a close is waiting on the dirty-buffer modal. Set when `windowShouldClose` could not
|
||||
/// flush; cleared by the resolution that lets the close resume.
|
||||
@State private var isClosePending = false
|
||||
@@ -417,31 +414,6 @@ struct CardWindowHost: View {
|
||||
.onDisappear { finish() }
|
||||
}
|
||||
|
||||
/// **This card's commit trail, or nothing at all** (05-card-window.md ▸ History).
|
||||
///
|
||||
/// `nil` is the section's absence rule, read from the board's own git state rather than from a
|
||||
/// flag: a mode other than `git` means a board the app manages no history for, on any tier. The
|
||||
/// question stopped having a tier half at 12-editions.md ▸ PIVOT 2026-08-07 — every session
|
||||
/// composes a git state now, so what decides the section is whether *this board's* history is
|
||||
/// git-backed. The object is held by this host so it survives every snapshot, `thumbnails`'
|
||||
/// reason exactly.
|
||||
private var cardHistory: CardHistory? {
|
||||
guard appModel.session(for: ref.board)?.gitMode == .git else { return nil }
|
||||
return history
|
||||
}
|
||||
|
||||
/// What a trail re-read depends on: this card, and the number of commits the board has landed.
|
||||
///
|
||||
/// The count is the committer's own (`GitAutoCommitter.commitCount`), which advances for every
|
||||
/// commit the app makes — the debounced ones, the launch catch-up, and a restore's. A foreign
|
||||
/// commit an agent made *itself* moves HEAD without touching it; the trail then refreshes at the
|
||||
/// next commit or the next open, which is the same freshness bound the popover's branch line has
|
||||
/// and a great deal cheaper than polling HEAD from a sidebar.
|
||||
private func historyReloadKey(store: BoardStore) -> String {
|
||||
let commits = appModel.session(for: ref.board)?.git?.committer?.commitCount ?? 0
|
||||
return "\(ref.cardID)#\(commits)"
|
||||
}
|
||||
|
||||
/// **The minimum grows only while the comments pane is beside the body** (05-card-window.md ▸
|
||||
/// Composition) — which is the whole reason the stacked mount exists, so a narrow display keeps
|
||||
/// the minimum it always had.
|
||||
@@ -475,20 +447,11 @@ struct CardWindowHost: View {
|
||||
comments: session.comments,
|
||||
thumbnails: thumbnails,
|
||||
undo: session.undo,
|
||||
history: cardHistory,
|
||||
fileDrop: CardWindowDropDelegate(store: store, cardID: placement.card.id),
|
||||
onToggleTask: { offset, checked in
|
||||
store.toggleTaskMarker(inCard: placement.card.id, bodyOffset: offset, checked: checked)
|
||||
}
|
||||
)
|
||||
// **The trail, re-read when a commit lands** (05 ▸ History). The id is the pair of facts
|
||||
// the answer depends on: which card this is, and how many commits this board has made —
|
||||
// so the section refreshes after the app's own commits, after an agent's that the watcher
|
||||
// committed, and after a ⌘Z's restore, with nothing here knowing what a committer is.
|
||||
.task(id: historyReloadKey(store: store)) {
|
||||
guard let cardHistory else { return }
|
||||
await cardHistory.load(boardRoot: store.rootURL, cardFolderName: ref.cardID)
|
||||
}
|
||||
// **The listing is the snapshot's, republished** — `Card.attachments`, which the loader
|
||||
// fills from `attachments/`'s top-level files in Finder order. Every write in the
|
||||
// section is bracketed, so the reload that refreshes this arrives by itself and the
|
||||
|
||||
Reference in New Issue
Block a user