Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
ecd401c
docs(11): capture phase context
FSM1 Feb 22, 2026
bd31b15
docs(11): research Windows desktop phase domain
FSM1 Feb 22, 2026
74005b4
docs(11): create Windows Desktop phase plan
FSM1 Feb 22, 2026
b6a48a9
add local claude settings json to gitignore
FSM1 Feb 22, 2026
a387ccd
fix(11): revise plans based on checker feedback
FSM1 Feb 22, 2026
f0acb73
feat(11-01): platform-agnostic inode types and WinFsp build infrastru…
FSM1 Feb 22, 2026
fb1e1f0
feat(11-01): platform-agnostic file handles and operations layer
FSM1 Feb 22, 2026
da36225
docs(11-01): complete platform abstraction layer plan
FSM1 Feb 22, 2026
26a8736
feat(11-02): WinFsp FileSystemContext implementation
FSM1 Feb 22, 2026
fb1802c
feat(11-02): Windows mount/unmount and module dispatch
FSM1 Feb 22, 2026
d709795
docs(11-02): complete WinFsp Operations Implementation plan
FSM1 Feb 22, 2026
0a08ae6
feat(11-03): platform branching and WinFsp runtime detection
FSM1 Feb 22, 2026
a39282d
feat(11-03): NSIS installer with WinFsp bundling and CI Windows build
FSM1 Feb 22, 2026
dc3a5f2
docs(11-03): complete NSIS Installer & CI Windows Build plan
FSM1 Feb 22, 2026
54918a5
fix(11): extract shared decrypt functions for Windows compilation
FSM1 Feb 22, 2026
ace1092
docs(11): complete Windows Desktop phase
FSM1 Feb 22, 2026
428c3ec
fix(11): use allowed CI actions for Windows jobs
FSM1 Feb 22, 2026
8472e5e
fix(11): move nsis config inside bundle.windows and chain CI jobs
FSM1 Feb 22, 2026
7165e14
fix(11): create WinFsp MSI placeholder for cargo check resource glob
FSM1 Feb 22, 2026
71e3281
fix(11): align WinFsp FileSystemContext with actual crate API
FSM1 Feb 22, 2026
64b94cb
fix(11): align WinFsp code with actual crate 0.12.4 API (round 2)
FSM1 Feb 22, 2026
5441df4
fix(11): align WinFsp API types with actual trait signatures (round 3)
FSM1 Feb 22, 2026
7272291
fix(11): fix final 4 WinFsp compilation errors (round 4)
FSM1 Feb 22, 2026
ba6a4d4
fix(11): add DirInfo const generic type annotation
FSM1 Feb 22, 2026
e1e0c9b
fix(11): resolve borrow checker errors in WinFsp read_directory prefetch
FSM1 Feb 23, 2026
baa8d95
fix(ci): pass --no-default-features to Windows Tauri build
FSM1 Feb 23, 2026
202b31b
fix(ci): pass cargo flags via -- separator in tauri build
FSM1 Feb 23, 2026
1a41000
fix(11): fix WinFsp registry detection and add ICO tray icon support
claude Feb 23, 2026
0cecbb3
fix(11): fix WinFsp mount lifecycle and file flush timing
FSM1 Feb 23, 2026
0236bd8
docs(11): add Phase 11 Windows desktop UAT results and WinFsp placeho…
FSM1 Feb 23, 2026
2652c6a
ci: add macOS desktop build to CI pipeline
FSM1 Feb 23, 2026
4e0d343
fix(ci): run macOS cargo check from src-tauri directory
FSM1 Feb 23, 2026
81560a8
fix(desktop): use Tauri IPC for OAuth popup on Windows
FSM1 Feb 23, 2026
1af2c63
fix(desktop): address CodeRabbit review feedback on Phase 11 PR
FSM1 Feb 23, 2026
cc4cefa
fix(desktop): address follow-up CodeRabbit review comments
FSM1 Feb 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,162 @@ jobs:

- name: Build packages (excluding desktop)
run: pnpm --filter @cipherbox/crypto --filter @cipherbox/api --filter @cipherbox/web build

cargo-check-windows:
name: Cargo Check (Windows)
needs: [lint]
runs-on: windows-latest
steps:
- uses: actions/checkout@v4

- name: Install WinFsp
shell: powershell
run: |
$url = "https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi"
$out = "winfsp.msi"
$expectedHash = "073A70E00F77423E34BED98B86E600DEF93393BA5822204FAC57A29324DB9F7A"
Invoke-WebRequest -Uri $url -OutFile $out
$actualHash = (Get-FileHash $out -Algorithm SHA256).Hash
if ($actualHash -ne $expectedHash) { throw "WinFsp MSI hash mismatch: expected $expectedHash, got $actualHash" }
Start-Process msiexec.exe -ArgumentList "/i","$out","/qn","INSTALLLEVEL=1000" -Wait -NoNewWindow
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- name: Create WinFsp MSI placeholder for resource glob
shell: powershell
run: New-Item -ItemType File -Force -Path "apps/desktop/src-tauri/resources/winfsp-placeholder.msi"

- name: Install Rust toolchain
run: rustup default stable

- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
apps/desktop/src-tauri/target
key: windows-cargo-${{ hashFiles('apps/desktop/src-tauri/Cargo.lock') }}
restore-keys: windows-cargo-

- name: Cargo check with winfsp feature
run: cargo check --manifest-path apps/desktop/src-tauri/Cargo.toml --no-default-features --features winfsp

cargo-check-macos:
name: Cargo Check (macOS)
needs: [lint]
runs-on: macos-latest
steps:
- uses: actions/checkout@v4

- name: Install FUSE-T
run: brew install --cask fuse-t

- name: Install Rust toolchain
run: rustup default stable

- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
apps/desktop/src-tauri/target
key: macos-cargo-${{ hashFiles('apps/desktop/src-tauri/Cargo.lock') }}
restore-keys: macos-cargo-

- name: Cargo check with fuse feature
working-directory: apps/desktop/src-tauri
run: cargo check --no-default-features --features fuse

build-desktop-windows:
name: Build Windows Desktop
needs: [cargo-check-windows, typecheck]
runs-on: windows-latest
steps:
- uses: actions/checkout@v4

- name: Install WinFsp
shell: powershell
run: |
$url = "https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi"
$resourceDir = "${{ github.workspace }}/apps/desktop/src-tauri/resources"
$out = "$resourceDir/winfsp-2.1.25156.msi"
$expectedHash = "073A70E00F77423E34BED98B86E600DEF93393BA5822204FAC57A29324DB9F7A"
New-Item -ItemType Directory -Force -Path $resourceDir
Invoke-WebRequest -Uri $url -OutFile $out
$actualHash = (Get-FileHash $out -Algorithm SHA256).Hash
if ($actualHash -ne $expectedHash) { throw "WinFsp MSI hash mismatch: expected $expectedHash, got $actualHash" }
Start-Process msiexec.exe -ArgumentList "/i","$out","/qn","INSTALLLEVEL=1000" -Wait -NoNewWindow

- name: Install Rust toolchain
run: rustup default stable

- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
apps/desktop/src-tauri/target
key: windows-cargo-${{ hashFiles('apps/desktop/src-tauri/Cargo.lock') }}
restore-keys: windows-cargo-

- uses: pnpm/action-setup@v4
with:
version: 10

- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build crypto package
run: pnpm --filter @cipherbox/crypto build

- uses: tauri-apps/tauri-action@v0
with:
projectPath: apps/desktop
tauriScript: pnpm tauri
args: -- --no-default-features --features winfsp
Comment thread
coderabbitai[bot] marked this conversation as resolved.

build-desktop-macos:
name: Build macOS Desktop
needs: [cargo-check-macos, typecheck]
runs-on: macos-latest
steps:
- uses: actions/checkout@v4

- name: Install FUSE-T
run: brew install --cask fuse-t

- name: Install Rust toolchain
run: rustup default stable

- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
apps/desktop/src-tauri/target
key: macos-cargo-${{ hashFiles('apps/desktop/src-tauri/Cargo.lock') }}
restore-keys: macos-cargo-

- uses: pnpm/action-setup@v4
with:
version: 10

- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build crypto package
run: pnpm --filter @cipherbox/crypto build

- uses: tauri-apps/tauri-action@v0
with:
projectPath: apps/desktop
tauriScript: pnpm tauri
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
args: -- --no-default-features --features fuse
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ coverage/
# Temporary files
temp/*
tests/e2e/test-results/*
.claude/settings.local.json
6 changes: 3 additions & 3 deletions .planning/REQUIREMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ Requirements for production release. Each maps to roadmap phases 12+.
### Cross-Platform Desktop

- [ ] **PLAT-01**: Linux desktop app (Tauri + AppImage/deb, FUSE mount via libfuse)
- [ ] **PLAT-02**: Windows desktop app (Tauri + MSI/NSIS, virtual drive via WinFsp/Dokany)
- [x] **PLAT-02**: Windows desktop app (Tauri + MSI/NSIS, virtual drive via WinFsp/Dokany)

## Milestone 3 Requirements (Encrypted Productivity Suite)

Expand Down Expand Up @@ -355,8 +355,8 @@ Which phases cover which requirements. Updated during roadmap creation.
| SYNC-05 | Phase 16 | Pending |
| SYNC-06 | Phase 16 | Pending |
| TEE-06 | Phase 17 | Pending |
| PLAT-01 | Phase 11 | Pending |
| PLAT-02 | Phase 11 | Pending |
| PLAT-01 | Phase 11.3 | Pending |
| PLAT-02 | Phase 11 | Complete |
| BILL-01 | Phase 18 | Pending |
| BILL-02 | Phase 18 | Pending |
| BILL-03 | Phase 18 | Pending |
Expand Down
44 changes: 33 additions & 11 deletions .planning/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ See `.planning/archive/m1-ROADMAP.md` for full M1 phase details and plan lists.

**Milestone Goal:** Elevate the staging MVP into a production-ready encrypted storage platform with sharing, search, MFA, file versioning, cross-platform desktop, and TEE failover.

- [ ] **Phase 11: Cross-Platform Desktop** - Linux and Windows desktop apps (Tauri, platform-specific FUSE/virtual drive) -- can run in parallel
- [x] **Phase 11: Windows Desktop** - Windows desktop app with WinFsp virtual filesystem (Tauri + NSIS installer)
- [x] **Phase 11.1: macOS Desktop Catch-Up** - Close all desktop gaps from Phases 12-12.6 before cross-platform expansion (INSERTED)
- [ ] **Phase 11.3: Linux Desktop** - Linux desktop app with libfuse FUSE mount (Tauri + AppImage/deb) (INSERTED)
- [x] **Phase 12: Core Kit Identity Provider Foundation** - Replace PnP Modal SDK with MPC Core Kit, CipherBox as identity provider
- [x] **Phase 12.1: AES-CTR Streaming Encryption** - AES-256-CTR for media files with byte-range decryption and in-browser playback (INSERTED)
- [x] **Phase 12.2: Encrypted Device Registry** - Encrypted device metadata on IPFS for cross-device infrastructure (INSERTED)
Expand Down Expand Up @@ -76,18 +77,37 @@ See `.planning/milestones/m3/ROADMAP.md` for full M3 phase details.

## Phase Details

### Phase 11: Cross-Platform Desktop
### Phase 11: Windows Desktop

**Goal**: CipherBox desktop app runs on Linux and Windows with native filesystem integration
**Depends on**: Phase 9 (macOS desktop complete in M1). Can run in parallel with any M2 phase.
**Requirements**: PLAT-01, PLAT-02
**Research flag**: NEEDS `/gsd:research-phase` -- Linux FUSE (libfuse) and Windows virtual drive (WinFsp or Dokany) have platform-specific build and packaging requirements. Tauri cross-compilation and CI matrix need investigation.
**Goal**: CipherBox desktop app runs on Windows with WinFsp virtual filesystem, full feature parity with macOS (system tray, credential storage, background sync, auto-start, headless mode)
**Depends on**: Phase 9 (macOS desktop complete in M1), Phase 11.1 (macOS catch-up), Phase 11.2 (v1 removal). Can run in parallel with any M2 phase.
**Requirements**: PLAT-02
**Research flag**: COMPLETE -- WinFsp Rust crate (v0.12.4), platform abstraction architecture, NSIS installer hooks, CI Windows runner researched
**Success Criteria** (what must be TRUE):

1. Windows user can install CipherBox via NSIS installer (WinFsp driver bundled and silently installed)
2. Windows user can log in and access a virtual filesystem mount at C:\Users\<user>\CipherBox
3. Background sync, system tray, and Windows Credential Manager storage work (parity with macOS)
4. CI builds and checks the Windows desktop app on windows-latest runner

**Plans:** 3 plans

Plans:
- [x] 11-01-PLAN.md — Platform abstraction layer: FileAttrs struct, cross-platform inode/cache/file_handle, Cargo.toml winfsp dep, build.rs delayload
- [x] 11-02-PLAN.md — WinFsp FileSystemContext implementation: all callbacks, Windows mount/unmount, path resolution, platform special file filter
- [x] 11-03-PLAN.md — Platform branching (main.rs, tray, commands) + Tauri NSIS packaging with WinFsp bundling + CI Windows build job

### Phase 11.3: Linux Desktop (INSERTED)

**Goal**: CipherBox desktop app runs on Linux with native FUSE filesystem integration via libfuse, full feature parity with macOS and Windows (system tray, credential storage, background sync, auto-start, headless mode)
**Depends on**: Phase 11 (Windows Desktop — platform abstraction layer reused), Phase 11.1 (macOS catch-up), Phase 11.2 (v1 removal)
**Requirements**: PLAT-01
**Research flag**: NEEDS `/gsd:research-phase` -- Linux FUSE (libfuse) packaging differences from macOS fuser, AppImage/deb packaging, Linux system tray (libappindicator vs StatusNotifierItem), Linux keyring (Secret Service API), CI Linux runner requirements
**Success Criteria** (what must be TRUE):

1. Linux user can install CipherBox via AppImage or .deb, log in, and access a FUSE mount at ~/CipherBox
2. Windows user can install CipherBox via MSI or NSIS installer, log in, and access a virtual drive (e.g., C:\CipherBox or mapped drive letter)
3. Background sync, system tray, and keychain storage work on both platforms (parity with macOS)
4. CI builds and packages desktop apps for all three platforms (macOS, Linux, Windows)
2. Background sync, system tray, and keyring storage work on Linux (parity with macOS/Windows)
3. CI builds and packages Linux desktop app (adds to existing macOS + Windows matrix)
**Plans**: TBD

### Phase 12: Core Kit Identity Provider Foundation
Expand Down Expand Up @@ -398,7 +418,8 @@ Sequential order: 12 -> 12.5 -> 12.6 -> 12.1 -> 11.2 -> 13 -> 14 -> 15 -> 16 ->

Parallel phases:

- Phase 11 (Cross-Platform Desktop) can run in parallel with any M2 phase (depends only on Phase 9/M1).
- Phase 11 (Windows Desktop) can run in parallel with any M2 phase (depends only on Phase 9/M1).
- Phase 11.3 (Linux Desktop) can run in parallel with any M2 phase (depends on Phase 11 for platform abstraction).
- Phase 17 (AWS Nitro TEE) can optionally execute in parallel with Phases 14-16 (depends on Phase 12).

| Phase | Milestone | Plans Complete | Status | Completed |
Expand Down Expand Up @@ -434,7 +455,8 @@ Parallel phases:
| 14. User-to-User Sharing | M2 | 6/6 | Complete | 2026-02-21 |
| 15. Link Sharing + Search | M2 | 0/TBD | Not started | - |
| 16. Advanced Sync | M2 | 0/TBD | Not started | - |
| 11. Cross-Platform Desktop | M2 | 0/TBD | Not started | - |
| 11. Windows Desktop | M2 | 3/3 | Complete | 2026-02-22 |
| 11.3 Linux Desktop | M2 | 0/TBD | Not started | - |
| 17. AWS Nitro TEE | M2 | 0/TBD | Not started | - |
| 18. Billing Infrastructure | M3 | 0/TBD | Not started | - |
| 19. Team Accounts | M3 | 0/TBD | Not started | - |
Expand Down
44 changes: 29 additions & 15 deletions .planning/STATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@
See: .planning/PROJECT.md (updated 2026-02-11)

**Core value:** Zero-knowledge privacy - files encrypted client-side, server never sees plaintext
**Current focus:** Milestone 2 -- Phase 14 COMPLETE (User-to-User Sharing)
**Current focus:** Milestone 2 -- Phase 11 Windows Desktop COMPLETE (all 3 plans done)

## Current Position

Phase: 14 (User-to-User Sharing)
Plan: 6 of 6
Phase: 11-windows-desktop (Windows Desktop)
Plan: 3 of 3
Status: Phase complete
Last activity: 2026-02-21 -- Completed 14-06-PLAN.md (Post-Upload Re-Wrapping & Lazy Key Rotation)
Last activity: 2026-02-22 -- Completed 11-03-PLAN.md (NSIS Installer & CI Windows Build)

Progress: [#########################] (M1 complete, M2 Phase 12 complete, Phase 12.2 complete, Phase 12.3 complete, Phase 12.3.1 complete, Phase 12.4 complete, Phase 12.5 complete, Phase 12.6 complete, Phase 12.1 complete, Phase 11.1: 7/7 COMPLETE, Phase 11.2: 3/3 COMPLETE, Phase 13: 5/5 COMPLETE, Phase 14: 6/6 COMPLETE)
Progress: [#########################] (M1 complete, M2 Phase 12 complete, Phase 12.2 complete, Phase 12.3 complete, Phase 12.3.1 complete, Phase 12.4 complete, Phase 12.5 complete, Phase 12.6 complete, Phase 12.1 complete, Phase 11.1: 7/7 COMPLETE, Phase 11.2: 3/3 COMPLETE, Phase 13: 5/5 COMPLETE, Phase 14: 6/6 COMPLETE, Phase 11: 3/3 COMPLETE)

## Performance Metrics

**Velocity:**

- Total plans completed: 127
- Average duration: 5.4 min
- Total execution time: 11.9 hours
- Total plans completed: 130
- Average duration: 5.5 min
- Total execution time: 12.5 hours

**By Phase (M1 summary):**

Expand All @@ -41,11 +41,12 @@ Progress: [#########################] (M1 complete, M2 Phase 12 complete, Phase
| M2 Phase 11.2 | 3/3 | 30 min | 10.0 min |
| M2 Phase 13 | 5/5 | 31 min | 6.2 min |
| M2 Phase 14 | 6/6 | 42 min | 7.0 min |
| M2 Phase 11 | 3/3 | 35 min | 11.7 min |

**Recent Trend:**

- Last 5 plans: 7m, 6m, 5m, 8m, 8m
- Trend: Stable
- Last 5 plans: 8m, 8m, 14m, 16m, 5m
- Trend: Normalizing (final Windows plan was config/CI changes, no complex API translation)

Updated after each plan completion.

Expand Down Expand Up @@ -180,6 +181,18 @@ Recent decisions affecting current work:
| Dynamic import() for checkAndRotateIfNeeded circular dep | 14-06 | share.service imports folder.store; folder.service importing share.service creates circular; dynamic import() defers |
| Lazy rotation defers parent metadata update to caller | 14-06 | checkAndRotateIfNeeded returns new key + rotated flag; caller handles parent folderKeyEncrypted update |
| Post-upload re-wrapping is fire-and-forget | 14-06 | Non-blocking: failures logged but never delay upload completion UI |
| FileAttrs with to_fuse_attr() boundary conversion | 11-01 | Core uses platform-agnostic FileAttrs; uid/gid injected at operations layer, not stored in shared structs |
| AccessMode enum replaces libc POSIX flags | 11-01 | Platform-independent ReadOnly/WriteOnly/ReadWrite instead of O_RDONLY/O_WRONLY/O_RDWR |
| cfg(any(fuse, winfsp)) for shared filesystem code | 11-01 | Shared types available to both platforms; mount/unmount remain feature-specific |
| Self-contained decrypt functions per platform module | 11-02 | Windows module has own decrypt_metadata_from_ipfs; fuse::operations gated to fuse-only, can't be cross-referenced |
| Arc<Mutex<CipherBoxFS>> for WinFsp interior mutability | 11-02 | WinFsp callbacks receive &self; Mutex wraps shared state for safe mutation from any thread |
| OnceLock<AtomicBool> stop signal for WinFsp unmount | 11-02 | Avoids storing FileSystemHost globally; stop flag coordinates shutdown across threads |
| WinFsp creates mount directory (no pre-create) | 11-02 | WinFsp uses reparse point for mount; pre-existing directory causes mount failure |
| Platform dispatch via cfg re-exports in fuse/mod.rs | 11-02 | Same function names (mount_filesystem/unmount_filesystem) resolve to correct impl via feature flags |
| WinFsp runtime detection via winreg at startup | 11-03 | Registry check + DLL existence verification; notification if missing, app still launches |
| NSIS ExecWait for WinFsp MSI install (not nsExec) | 11-03 | Simpler exit code handling; MSI installed silently with INSTALLLEVEL=1000 |
| WinFsp MSI downloaded in CI, not committed to git | 11-03 | Binary files not suitable for source control; CI downloads from official GitHub release |
| cfg(any(fuse, winfsp)) in entry point files | 11-03 | Compound feature gate enables same mount/unmount code paths on both platforms |

### Pending Todos

Expand Down Expand Up @@ -232,7 +245,8 @@ Recent decisions affecting current work:

### Research Flags

- Phase 11 (Desktop): NEEDS `/gsd:research-phase` -- Linux FUSE (libfuse), Windows virtual drive (WinFsp/Dokany), Tauri cross-compilation
- Phase 11 (Windows Desktop): COMPLETE -- WinFsp Rust crate, platform abstraction, NSIS installer hooks, CI Windows runner researched
- Phase 11.3 (Linux Desktop): NEEDS `/gsd:research-phase` -- Linux FUSE (libfuse) packaging, AppImage/deb, Linux system tray, Linux keyring, CI Linux runner
- Phase 14 (Sharing): COMPLETE -- research done, 6 plans created, all 6 executed
- Phase 15 (Link Sharing): NEEDS `/gsd:research-phase` -- unauthenticated web viewer security
- Phase 16 (Advanced Sync): NEEDS `/gsd:research-phase` -- three-way merge edge cases
Expand All @@ -248,12 +262,12 @@ Recent decisions affecting current work:

## Session Continuity

Last session: 2026-02-21
Stopped at: Phase 14 complete and verified (5/5 must-haves passed)
Last session: 2026-02-22
Stopped at: Phase 11 (Windows Desktop) complete and verified (4/4 must-haves passed)
Resume file: None
Next: Run /gsd:discuss-phase 15 or /gsd:plan-phase 15 for Link Sharing + Search.
Next: Phase 11.3 (Linux Desktop) needs /gsd:research-phase, or Phase 15 (Link Sharing + Search) needs /gsd:discuss-phase

---

_State initialized: 2026-01-20_
_Last updated: 2026-02-21 after Phase 14 (User-to-User Sharing) complete — verified, requirements marked Complete_
_Last updated: 2026-02-22 after Phase 11 (Windows Desktop) complete — verified, PLAT-02 marked Complete_
Loading