40 lines
3.6 KiB
Markdown
40 lines
3.6 KiB
Markdown
# 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`: Workspace opening and file tree management.
|
|
- `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.
|
|
- `SaplingLogging`: Thin logging facade over `OSLog`.
|
|
- `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. This distinction is represented in `SaplingCore` so business rules remain shared across macOS and future iOS targets.
|
|
|
|
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. The renderer is injected through `MarkdownRendering` so the current lightweight parser can later be replaced with a richer Markdown/LaTeX/Mermaid pipeline.
|
|
|
|
Storage is abstracted behind small protocols. The current in-memory stores make the application buildable and testable; `JSONWorkspaceMetadataStore` establishes the first production path for workspace metadata without forcing a database decision.
|
|
|
|
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.
|
|
|
|
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.
|
|
|
|
## TODO
|
|
|
|
- TODO: Replace sample data composition with real workspace opening and file loading.
|
|
- 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.
|