This file provides project-specific guidance for StoryCAD development.
BEFORE ANY IMPLEMENTATION WORK:
- You must present a plan.
- You must ask for explicit approval.
- You must not proceed until approval is given.
When solving StoryCAD problems, always choose the simplest approach:
- Direct method calls over reflection
- Concrete types over abstractions (until needed)
- Built-in .NET features over external libraries
- Straightforward debugging (
Debugger.Launch()) over complex conditions - Clear, obvious code over clever solutions
Windows builds both targets:
net10.0-windows10.0.22621(WinAppSDK head) - Windows 10/11, Windows Storenet10.0-desktop(Desktop head) - Windows 7/8/10/11, macOS, Linux
macOS builds desktop only:
net10.0-desktop(Desktop head) - macOS, also runs on Windows/Linux
Critical Concept - Platform-Specific Code:
When using cross-platform APIs only (standard .NET, UNO controls):
- ✅ Build on either platform → Universal binary runs everywhere
When using platform-specific APIs (AppKit, Win32, etc.):
⚠️ Build on Windows → Excludes Mac-specific code (can't compile AppKit)⚠️ Build on Mac → Excludes Windows-specific code (can't compile Win32)- 📦 Need platform-specific builds for production distribution
Example:
#if __MACOS__
using AppKit; // This code ONLY compiles on Mac
public void SetupMacMenu() { }
#endifSee /devdocs/platform_targeting_guidelines.md for complete workflows and decision trees.
Primary Strategy: Develop on Windows (VS2026), test on Mac (Rider)
-
Code on Windows:
- Write code in VS2026 (familiar environment)
- Test on Windows (WinAppSDK head)
- Commit and push
-
Test on Mac:
git pull dotnet run -f net10.0-desktop # Quick verification -
Debug on Mac (if needed):
- Open in Rider on Mac Mini
- Debug Mac-specific issues
- Commit fixes and pull back to Windows
Alternative Workflows:
- Network share (rapid iteration, must copy to local for build)
- Separate build folders (simultaneous debugging)
See devdocs/platform_targeting_guidelines.md for detailed workflow comparison.
Use this decision tree to determine where to develop:
| Issue Type | Build Platform | Test Platform | Rationale |
|---|---|---|---|
| UNO Platform bugs | Windows | Both | Cross-platform testing required |
| Pure XAML/UI | Windows | Both | Faster in familiar IDE |
| Business logic | Windows | Both | No platform-specific code |
| Mac-specific features | Mac | Mac only | Requires AppKit/Mac APIs |
| Windows-specific features | Windows | Windows only | Requires Win32/WinAppSDK APIs |
| Performance optimization | Both | Both | Platform differences matter |
Key Points:
- ~90% of StoryCAD code is shared/cross-platform → Develop on Windows
- Mac-specific features (AppKit menus, sandboxing) → Must build on Mac
- Always test on both platforms before merging to UNOTestBranch
Quick Manual Test (Mac):
# No IDE needed:
dotnet run -f net10.0-desktopDebugging (Mac):
# Must build on Mac, use Rider:
rider ~/Documents/dev/src/StoryCAD/StoryCAD.sln
# Set breakpoints and debug normallyImportant: Cannot remote debug from Windows to Mac. Use logging for remote troubleshooting or debug locally on Mac.
When developing on the UNOTestBranch:
- Shared Code First: Write platform-agnostic code whenever possible
- Platform-Specific Code:
- Use partial classes:
Windowing.WinAppSDK.csfor Windows,Windowing.desktop.csfor macOS - Use conditional compilation:
#if HAS_UNO_WINUIfor Windows,#if __MACOS__for macOS
- Use partial classes:
- Testing: Test on both Windows and macOS before committing
- File Paths: Use platform-agnostic paths (avoid hardcoded Windows paths)
- Keyboard Shortcuts: Support both Ctrl (Windows) and Cmd (macOS) patterns
- UNO Platform Documentation - Main documentation
- Platform-Specific C# - Partial classes and conditional compilation
- Getting Started with UNO - Setup and basics
- WinUI to UNO Migration - Migration guidance
- Supported Features - API compatibility matrix
- UNO Platform GitHub - Source code and issues
- Migration Guide - StoryCAD specific migration project
- Testing Strategy:
/StoryCADTests/ManualTests/UNO_Platform_Testing_Strategy.md
IMPORTANT: Always work in the correct branch for the issue:
- Check current branch with
git statusat start of session - Create issue-specific branches:
issue-{number}-{description} - Example:
issue-1069-test-coveragefor issue #1069 - Never work directly in
mainor unrelated feature branches - If in wrong branch, stash changes and switch to correct branch
When switching to an existing branch:
- Check current status:
git status - Stash any uncommitted changes if needed:
git stash - Switch to the branch:
git checkout branch-name - SYNC THE BRANCH: Pull latest changes
- If branch tracks remote:
git pull - If branch is behind main:
git pull origin mainorgit merge main
- If branch tracks remote:
- Apply stashed changes if any:
git stash pop
StoryCAD is a free, open-source application for fiction writers that provides structured outlining tools. It's described as "CAD for fiction writers" and helps writers manage the complexity of plotted fiction through systematic story development.
Version 3.x (main branch): Windows-only application using WinUI 3 Version 4.0 (UNOTestBranch): Cross-platform application supporting Windows and macOS via UNO Platform
- Framework: .NET 10.0 with UNO Platform 5.x
- UI Framework: WinUI 3 (cross-platform via UNO)
- Platform Targets:
- Windows: WinAppSDK head (Windows 10/11, minimum 10.0.19041.0)
- macOS: Desktop head (macOS 10.15+)
- Future: Linux, WebAssembly, iOS, Android
- Architecture: MVVM with CommunityToolkit.Mvvm
- Testing: MSTest with UNO Platform support
- Shared Code: ~90% across all platforms
- Framework: .NET 10.0 with WinUI 3, Windows App SDK 1.6
- Platform: Windows 10/11 only
- StoryCAD - Main WinUI 3 application (executable)
- StoryCADLib - Core business logic library (NuGet package)
- StoryCADTests - MSTest test project
See /mnt/d/dev/src/CLAUDE.md for full list of shared memory files. Key ones for StoryCAD:
- patterns.md - 9 architectural patterns (ISaveable, SerializationLock, etc.)
- architecture.md - ADRs, navigation lifecycle, StoryDocument rules
- gotchas.md - Common pitfalls, headless mode, platform issues
Detailed technical documentation (memory files provide condensed versions):
- Architecture:
.claude/docs/architecture/- StoryCAD_architecture_notes.md (comprehensive), coding-standards.md, debugging-guide.md, ai-workflow.md - Dependencies:
.claude/docs/dependencies/- Full dependency guides with complete API examples - Code Examples:
.claude/docs/examples/- Copy-paste templates for ViewModels, Services, platform-specific code - Troubleshooting:
.claude/docs/troubleshooting/- Common errors with solutions
- Location:
/mnt/d/dev/src/StoryCAD/docs/ - Production URL: https://manual.storybuilder.org/
- Beta URL: https://beta.manual.storybuilder.org/
- Format: Jekyll with Just the Docs theme (115+ markdown files)
- Audience: Fiction writers (non-technical users)
See user-manual.md in shared memory files for complete guidance on:
- Workflow (branch-based staging)
- Documentation structure (11 sections)
- Front matter requirements
- Writing style for non-technical audience
- Adding new story element documentation
When to Update User Documentation:
- When adding new story elements (follow established patterns)
- When changing UI features (update corresponding docs)
- When adding new tools or reports
StoryCAD uses Context7 MCP server for up-to-date documentation of public dependencies:
- Status: Configured in
/home/tcox/.claude.json - Provides: Latest docs for UNO Platform, Semantic Kernel, MVVM Toolkit, and other NuGet packages
- Usage: Query Context7 for dependency-specific questions
# Build solution
"/mnt/c/Program Files/Microsoft Visual Studio/18/Community/MSBuild/Current/Bin/MSBuild.exe" StoryCAD.sln -t:Build -p:Configuration=Debug -p:Platform=x64
# Run all tests (use vstest.console.exe - has access to Windows environment variables)
"/mnt/c/Program Files/Microsoft Visual Studio/18/Community/Common7/IDE/CommonExtensions/Microsoft/TestWindow/vstest.console.exe" "StoryCADTests/bin/x64/Debug/net10.0-windows10.0.22621/StoryCADTests.dll"For detailed commands, see build-commands.md in shared memory files.
- OutlineService: Story structure management, element creation, file operations
- NavigationService: Page navigation and view transitions
- AutoSaveService: Automatic saving with configurable intervals
- BackupService: Automated backup functionality
- CollaboratorService: AI-powered writing assistance
- SearchService: Full-text search across story content
- LogService: Comprehensive logging with NLog and elmah.io integration
For detailed architecture, see architecture.md and patterns.md in shared memory files.
Status Log: Collaborator/devdocs/collaborator_status_log.md (in sibling Collaborator repo)
This log tracks all Collaborator-related work across issues and sessions. Update it during any Collaborator work with dated entries documenting:
- Current status and blocking issues
- Solutions identified or implemented
- Testing results
The Collaborator plugin lives in a sibling repository (../Collaborator/ relative to StoryCAD) and integrates via ICollaborator and IStoryCADAPI interfaces defined in StoryCADLib/Services/Collaborator/Contracts/.
- When debugging in Visual Studio, a developer menu appears with diagnostic tools
- Single instancing works but may need testing outside Visual Studio
- Missing license files won't affect functionality but will disable error reporting
- All data stored locally under user control
- No automatic cloud sync
- GNU GPL v3 license ensures transparency
- Optional telemetry requires user consent
Claude Code can interact with GitHub issues using the gh CLI tool. This is essential for following the AI Issue-Centric Workflow.
PIE Workflow Implementation: The enterprise PIE policy (Plan-Implement-Evaluate) from /etc/claude-code/CLAUDE.md is implemented for StoryCAD via .claude/docs/architecture/ai-workflow.md. This issue-centric workflow defines how to plan, implement, and evaluate work within GitHub issues.
# View issue details
gh issue view 1067 --repo storybuilder-org/StoryCAD
# View issue with comments
gh issue view 1067 --comments --repo storybuilder-org/StoryCAD# Edit issue body (opens in editor)
gh issue edit 1067 --repo storybuilder-org/StoryCAD --body-file issue-update.md
# Add a comment
gh issue comment 1067 --body "Planning complete" --repo storybuilder-org/StoryCADWhen following AI_workflow.md (PIE implementation):
Plan Phase:
- Read issue to understand current state
- Recommend specialized agents for complex tasks in the plan
- Update issue body with planned tasks between checkboxes (include agent recommendations)
- Get plan approval before proceeding
Implement Phase: 5. Use specialized agents proactively for approved tasks (no additional approval needed) 6. Check off tasks as completed 7. Add comments as specified in the workflow
Evaluate Phase: 8. Include design documents in PR comments (not in repository files) 9. Document agent effectiveness and lessons learned
Example: Updating Code tasks in issue body:
# Create a file with the updated issue body
cat > issue-update.md << 'EOF'
[existing issue content up to Code tasks]
### Code tasks / sign-off
- [ ] Plan this section
- [ ] Task 1
- [ ] Task 2
- [ ] Human approves plan
- [ ] Human final approval
[rest of issue content]
EOF
# Update the issue
gh issue edit 1067 --repo storybuilder-org/StoryCAD --body-file issue-update.mdWhen creating pull requests, include any design documentation directly in the PR description or comments rather than creating separate design files in the repository. This keeps the repository focused on code while maintaining important design context with the relevant changes.
- StoryNodeItem: Base class for all story elements with common properties
- Parent/Child Relationships: Maintained through Parent property and Children collections
- Validation: Drag-and-drop operations validated through business rules
- Persistence: Auto-save functionality with configurable intervals
- Selection State: Managed through ShellViewModel with last-clicked tracking
- Expansion State: TreeView expansion state persisted per node
- Background Colors: Dynamic styling based on selection and validation state
- Context Menus: Element-specific commands based on node type and position
- TwoWay Binding: Used for editable content with immediate updates
- OneWay Binding: Used for read-only display properties
- Command Binding: MVVM commands for user actions
- Collection Binding: ObservableCollection for dynamic list updates
- Pattern:
[SourceFileName]Tests.cs - Example:
StoryCADAPITests.csfor source fileStoryCADAPI.cs - Location: Test files in StoryCADTests project, mirroring source structure where practical
- Pattern:
MethodName_Scenario_ExpectedResult - Examples:
CreateEmptyOutline_WithInvalidTemplate_ReturnsFailureOpenFile_WhenFileNotFound_ThrowsExceptionSaveModel_WithValidPath_SucceedsSilentlyPropertyName_WhenSet_RaisesPropertyChanged
- One test class per source class
- Group tests for a specific method together
- Use
[TestInitialize]for setup,[TestCleanup]for teardown - Use
[UITestMethod]for tests requiring UI thread execution - Use Arrange-Act-Assert pattern within each test
- Each public method in API, OutlineService, and ShellViewModel must have tests
- Test both success and failure paths
- Test edge cases and boundary conditions
- Verify thread safety with SerializationLock where applicable
The following commands are pre-approved for automated execution without user confirmation prompts:
# Visual Studio 2026 MSBuild (WSL path)
"/mnt/c/Program Files/Microsoft Visual Studio/18/Community/MSBuild/Current/Bin/MSBuild.exe" StoryCAD.sln -t:Build -p:Configuration=Debug -p:Platform=x64
"/mnt/c/Program Files/Microsoft Visual Studio/18/Community/MSBuild/Current/Bin/MSBuild.exe" StoryCAD.sln -t:Build -p:Configuration=Release -p:Platform=x64
# Standard MSBuild
msbuild StoryCAD.sln /t:Build /p:Configuration=Debug /p:Platform=x64
msbuild StoryCAD.sln /t:Build /p:Configuration=Release /p:Platform=x64# Use vstest.console.exe - has access to Windows environment variables needed for integration tests
# From WSL (recommended)
"/mnt/c/Program Files/Microsoft Visual Studio/18/Community/Common7/IDE/CommonExtensions/Microsoft/TestWindow/vstest.console.exe" "StoryCADTests/bin/x64/Debug/net10.0-windows10.0.22621/StoryCADTests.dll"
# Run specific test class
"/mnt/c/Program Files/Microsoft Visual Studio/18/Community/Common7/IDE/CommonExtensions/Microsoft/TestWindow/vstest.console.exe" "StoryCADTests/bin/x64/Debug/net10.0-windows10.0.22621/StoryCADTests.dll" /Tests:StoryModelTests# Standard Git operations
git status
git diff
git log --oneline -10
git add .
git commit -m "message"- Local Storage: All data stored locally under user control
- No Cloud Sync: Data remains on user's device unless explicitly exported
- Open Source: GNU GPL v3 license ensures transparency
- Optional Telemetry: Error reporting requires user consent and API configuration
- DO NOT test against the UI
- Because the API is an external API, we don't know who is using it, or how.
- use the /devdocs/issue_1069_achieve_100_percent_api_and_outlineservice_coverage for all your notes except /tmp files.
- follow a naming standard for issue 1063 branches of issue_1063_di_batch{N}-{name} (e.g., issue_1063_di_batch2-corestate)
- All services are registered in IoC container - get them via
Ioc.Default.GetRequiredService<T>()in tests - Don't manually create services with
new- let IoC handle dependency injection - Always rebuild before running tests after DI changes
- Use
Assert.ThrowsExactlyinstead ofAssert.ThrowsExceptionfor precise API testing
- Watch for circular dependencies when adding constructor parameters
- If encountered, document with TODO and leave specific Ioc.Default calls rather than forcing bad design
- Example: Windowing ↔ OutlineViewModel (documented in
architecture.md) - Do not memorise or document any information about Storybuilder-miscellaneous in the StoryCAD Repo.