Sapling/Docs/Architecture.md

42 lines
3.8 KiB
Markdown
Raw Normal View History

2026-05-29 15:19:33 +02:00
# Sapling Architecture
Sapling is organized as a Swift Package with an executable app target and focused library targets. The app shell depends on feature modules, feature modules depend on protocols and domain models, and `SaplingCore` has no dependency on UI or platform-specific services.
## Targets
- `SaplingApp`: SwiftUI application entry point and dependency composition.
- `SaplingCore`: Domain models, sample data, and business rules.
- `SaplingWorkspace`: Filesystem-backed workspace opening and file tree discovery.
2026-05-29 15:19:33 +02:00
- `SaplingGit`: Protocol-first Git abstraction plus macOS, embedded, and mock providers.
- `SaplingEditor`: Hybrid Markdown editor state and SwiftUI editing surface.
- `SaplingRenderer`: Markdown parsing/rendering primitives for headings, emphasis, code blocks, task lists, and images.
- `SaplingStorage`: Configuration and workspace metadata persistence contracts.
2026-05-29 15:34:15 +02:00
- `SaplingLogging`: Thin logging facade over `OSLog`.
2026-05-29 15:19:33 +02:00
- `SaplingUI`: Shared SwiftUI sidebar, inspector, and empty-state components.
## Architectural Decisions
The Git layer is protocol-first because macOS and iOS need different implementations. `MacGitProvider` uses the system `git` binary behind the `GitProvider` and `Repository` protocols. `EmbeddedGitProvider` is intentionally stubbed as the future iOS-compatible implementation point. `MockGitProvider` is used by the initial app shell and previews/tests so UI work is not coupled to local repositories.
Workspaces are local containers and are not versioned. Projects are Git repositories, while subprojects model Git submodules. Workspace contents are derived lazily from the filesystem rather than a Sapling-owned manifest or database. This distinction is represented in `SaplingCore` so business rules remain shared across macOS and future iOS targets.
2026-05-29 15:19:33 +02:00
The editor follows an MVVM shape. `HybridMarkdownEditorViewModel` owns document editing state, while `HybridMarkdownEditor` renders the active line as source and inactive lines as rendered Markdown. `DocumentSessionStore` keeps open document sessions separate from the workspace tree so opening the same file activates the existing editor state instead of creating a duplicate. The renderer is injected through `MarkdownRendering` so the current lightweight parser can later be replaced with a richer Markdown/LaTeX/Mermaid pipeline.
2026-05-29 15:19:33 +02:00
Storage is abstracted behind small protocols. `SaplingConfiguration` persists application settings such as the last opened workspace path. Workspace contents are not persisted; they are rebuilt from the filesystem.
2026-05-29 15:19:33 +02:00
2026-05-29 15:34:15 +02:00
Dependency injection starts in `SaplingApp` through `AppDependencies`. The composition root owns concrete providers and passes protocols into application state. This keeps feature modules testable and prevents UI code from constructing infrastructure ad hoc.
Settings are represented by `SaplingConfiguration`, persisted by `ConfigurationStore`, and exposed through the SwiftUI `Settings` scene. Logging flows through `SaplingLogger` so feature code uses stable categories without depending directly on logger construction details.
See `Docs/Workspace.md` for the Milestone 4.1 workspace scanning and document session model.
2026-05-29 15:34:15 +02:00
The development workflow is captured in `Makefile` and `Scripts/`. `make validate` runs formatting, linting, build, and tests; this is the Milestone 0 gate before updating roadmap status.
2026-05-29 15:19:33 +02:00
## TODO
- TODO: Add security-scoped bookmark handling for sandboxed macOS distribution.
- TODO: Expand `MarkdownRenderer` to support full Markdown block parsing, LaTeX, Mermaid, and attachment previews.
- TODO: Replace the placeholder source-line editor with a text layout engine that preserves cursor position across rendered/source transitions.
- TODO: Complete submodule removal as a transactional operation across `.gitmodules`, index state, and module metadata.
- TODO: Implement `EmbeddedGitProvider` with an iOS-compatible Git engine.