Portfolio project dashboard (Tauri) replacing day-to-day Unity Hub / VCC list usage and the spreadsheet’s project backlog.
- Projects dashboard with Name, Priority, Status (Urgent/Experiment/To Do/WIP/Testing/Maintaining/Done/Broken), Platform, Category (VR/AR/Utility/Web/Game/Client/Bot/Backup/Other), GitHub status (Location in edit)
- Drag-and-drop sort with autosaved
sortIndex(local app-data JSON) - Add local folder(s) (multi-select; probe Unity version + git remote; path dedupe + link GitHub-only rows)
- Open Unity project / reveal in Explorer
- Run
run.bat/run.commandwhen present (primary); Open in ··· menu - Import repos from
DeaconDP(public always; private with mesh PATgist+repo) + refresh local git status (ahead/behind;githubPrivatelock badge) - Import Unity Hub + VCC project lists (dedupe by path; link onto GitHub-only rows)
- Slim brand chrome + command bar UX (Import menu, search shortcut)
- Sync parent folders: persistent roots list; scan immediate children and add missing projects
- Machine monitor (Ada): header MetricsGlance (CPU/RAM/GPU/Disk) + tabs Overview / Processes / Fuel / Settings; Fuel + spike data reuse Ada on-disk paths
North star: one place to administer, monitor, and orchestrate Dale’s local/git projects across Ada / Edgar / Steve / Luckey / Woz / Hermes — without opening OpenShip UI, site-ops dashboards, or per-app Dock binaries for happy-path ops.
Host ownership (hard rule): each computer hosts a different project inventory. Ada ≠ Edgar ≠ Steve. A live Deez node only runs Update Local / Run / sticky rebuild for rows that live on that machine. Cross-host glance = switch Tailscale MagicDNS peer (or “All hosts” list filter for pathless stamps) — not one mirrored catalog of every sticky site on every box.
Product vs surface (hard rule): one row = one launchable / deployable surface (folder, sticky PWA, Unity/Unreal project, native app, marketing site, …). Stacks differ: Web · Native · Unity · Unreal · site. One product (Emily, deac-online, …) can span many rows — website + app, or several apps — linked by a shared siteId. Ops verbs (Ship / Promote / Update Local) act per surface, never “rebuild the whole product.”
Content class (hard rule): stamp each site’s news / dynamic content before inventing new ship verbs. in-repo rides Promote Live (git / edgar). host-db/CMS needs a content-sync verb. live-feed needs no promote. external-CMS stays outside the git path. Active checklist: TODO.md Fleet ops.
Three verbs (thin backends):
| Verb | Means | Backend |
|---|---|---|
| Administer | Registry: path, owning host, port, repo, URLs, launch | Deez-PM itself (per-host store) |
| Monitor | git behind, last build, Preview/Live, health | site-ops sensors + OpenShip status + local helper |
| Orchestrate | Update Local · Ship Preview · Promote Live · Rollback · Open URL | dale-auto-rebuild / Dock · OpenShip CLI/API |
Poteto slices (in order):
- Ada: OpenShip always-on + one real domain (infra — not this repo alone)
- Deez-PM thin OpenShip adapter: Settings PAT/API + project fleet fields + row Ship Preview / Promote Live / status
- Same row: Update Local (fetch/pull +
dale-auto-rebuild/run.* --rebuild) - Shared
scripts/dale-auto-rebuild.shhelper contract for Dock/run.command - Per-host inventory: stamp
host, default table = This host, mesh keeps sticky path/port local - Product/surface model: shared
siteId+ optionalsurfacelabel; Native platform; one row per face (Emily multi-app) - Pilot green on deac-online against live Ada OpenShip
- Fleet cutover of more rows (only after pilot)
Non-goals: second control-plane UI · GitHub Actions rebuilds · rebuild-on-every-save · Hermes Desktop replacement · federated “union all hosts into one live table” (peer switch is enough) · nested product tree UI (shared siteId is enough)
Re-introduce Learn / Tools nav when content exists— superseded by Projects / Overview / Processes / Fuel / Settings tabs (src/App.tsx)
- Vendor Ada metrics / spikes / net / USB / Fuel into Tauri backend
- Header glance + primary tabs (Projects default)
- Overview gauges, Processes hub (CPU/Network/USB/Spikes), Fuel, Settings
- Polish monitor density to match projects chrome; optional tray later
- Detect installed Unity editors and map to projects
- Warn when required editor version is missing
- Editor picker per project; launch with exact version
- Hub-like favorites / cloud status icons where useful
- Create Avatar / World project from templates
- Package resolve / upgrade UI (“Manage Project”)
- VRChat project type classification (Avatar vs World)
- Template browser
- Read projects from
vcc.litedbwhenuserProjectsis empty
- Monthly income columns, Gross / Nett, currency (from Income & Cashflow sheet)
- Agency / client / region reporting views
- Optional CSV import from the spreadsheet export
- Cross-device metadata + sort + tasks sync via private GitHub gist (mesh hub)
- GitHub PAT in OS-protected credential store (desktop) / device storage (PWA)
- Device roster (peers) + Join mesh / Sync now in Settings
- Phone / browser PWA node (
scripts/serve-mesh.sh) shares the same gist - Private DeaconDP repo import +
githubPrivatevia same PAT (gist+repo) - Rate-limit handling with authenticated API (PAT path covers most cases)
- Open PR count enrichment on project rows (GitHub API; PAT for private) — never GitHub Actions / workflow checks
- Optional LAN peer discovery (still hub-via-gist; true P2P later if needed)
- Per-project board opened from project name click (Backlog → Priority → Doing → Testing → Done)
- Add task with Opt/Low/Med/High/Crit (color-coded; Opt = store Default); auto-sort on add / priority change
- Task comments (append-only); multi-column drag-and-drop reorder
- Import Trello board JSON export into the open project (list→column map, card dedupe)
- Trello import expansion:
- Paste raw board JSON or a public Trello board URL
- Drag-and-drop
.jsonfiles onto the board - Import due dates, checklists as Markdown tasks, labels as tags, archived cards, and attachment links
- Re-sync imported cards with an update-existing mode instead of always skipping duplicates
- Preview and edit Trello list → kanban column mappings before import
- Import Trello Premium CSV and generic mapped CSV
- Choose a destination project or create a project from an imported board
- Trello REST API personal key/token flow for private boards, board browsing, complete comments, and periodic sync; keep credentials in the OS secret store
- Full Trello OAuth flow after the personal-token integration
- Deferred: custom columns, WIP limits, comment edit/delete
- Richer priority presets, tags, active vs archive filters
- Saved views / search presets
- GitHub visibility on rows (
githubPrivate) + Private/Public/Unknown filter + edit toggle
Watch folders (e.g. VRC projects roots) and auto-discover Unity projects— manual Sync parents shipped (immediate children; Add/Remove roots)- Optional filesystem watch / auto-discover (still open)
- Deduplicate against GitHub-imported backlog (via Sync + import path linking)
Job: open the live node (projects + Ada glance) from an iPhone on the same Tailscale tailnet — not a second product, not a public SaaS.
Poteto verdict (do this, refuse the rest):
- PWA URL over Tailscale is the primary phone path (proved).
- Native is optional via a Capacitor shell around the same Vite
dist/(io.worldbuild.deez). Same React UI / browser runtime. No React Native rewrite, no Tauri-mobile Rust port. - Each desktop Deez instance is a node. Networking = Tailscale MagicDNS + HTTP bound to the tailnet IP only (never Funnel / public bind for v1).
- One thin local HTTP surface inside the running Tauri app: static
dist/+ JSON that mirrors the existing invoke commands we actually need remote. Dualapi.ts(Tauri IPC vsfetch). - Multi-node = switch MagicDNS host (bookmark peers). No central coordinator, no CRDT mesh, no custom VPN.
- Keep gist/repo Sync epic separate: that is offline metadata replica; Tailscale is live remote UI into a node’s store + metrics.
Slices (in order):
- Settings: detect Tailscale IPv4 / MagicDNS hostname; sticky remote port; copy URL + QR for phone
- Embed read-mostly HTTP server (bind
100.x/ Tailscale iface only):GETprojects store + metrics/fuel snapshots - Serve Vite build as installable PWA (
manifest+ minimal service worker); phone Add to Home Screen -
api.tsbrowser adapter when__TAURI_INTERNALS__missing; degrade desktop-only actions (Open Unity / Reveal / pickers) - Optional shared secret header (belt on top of tailnet ACL); never commit tokens
- Write-path remote: status / priority / kanban edits that already save through
save_projects - Peer list in Settings (paste MagicDNS names); one-tap switch which node the phone is talking to
- Phone chrome cull: browser/PWA hides host-only Import/Add/Sync/Open/Run/Reveal/Browse; Settings soft-fails without live
/api - Capacitor native shell (
capacitor.config.ts,ios/,android/,npm run native:*) wrapping the samedist/ - Later only if needed: remote “Run / Open on host” with explicit confirm — not in first phone cut
- TestFlight / Play upload — signing via Apple team d@worldbuild.io; not automated in this repo yet
Non-goals (explicit):
- React Native / Expo rewrite of the UI
- Tauri-mobile port of the Rust host into the phone binary
- Tailscale Funnel / public internet exposure
- Replacing local-first store with a cloud DB
- Per-packet sync protocol between nodes (use Sync epic / gist if offline replica is the real need)
- Shipping Fuel credentials or OS secret-store material to the phone
| Need | Use |
|---|---|
| Phone / iPad glance + light edits while on tailnet | Tailscale PWA URL into a live node |
| Two PCs stay aligned when not simultaneously online | Sync epic (gist/repo) — still deferred |
| “Everything” including Open Unity from couch | Host stays authoritative; phone triggers optional remote-exec later |
- 2026-09-10: Loopback
/api/doctor+DEEZ_REMOTE_BIND=127.0.0.1for desktop-agent workflows — cloud agents stay on browsernpm run test:agent; Tailscale CGNAT bind remains default (src-tauri/src/remote/server.rs,tests/harness/). - 2026-09-10: Env-gated app NDJSON logging (
DEEZ_LOG=json) — evidence stays at the browser boundary; do not reintroduce metrics-path agent I/O (TODO.mdAgent verify). - 2026-09-10: Mesh-sync browser proof with mocked gist routes — needs
page.routeafter basic suite; unit coverage already importssrc/lib/mesh.ts(tests/browser/,tests/unit/mesh.test.ts). - 2026-09-03: Fleet cutover of all
/srv/www+ sticky-port rows — wait for deac-online pilot green on Ada OpenShip (ROADMAP.mdFleet ops hub). - 2026-09-03: OpenShip dashboard / site-ops as deploy home — Deez-PM is the only happy-path UI; backends stay headless (
src-tauri/src/openship.rs). - 2026-09-03: GitHub Actions as rebuild path — local
dale-auto-rebuild+ OpenShip CLI only (scripts/dale-auto-rebuild.sh). - 2026-09-03: Rollback / health-sensor feed polish — after Ship Preview + Promote Live prove on one site (
src-tauri/src/openship.rs). - 2026-09-04: Content-sync ship verb — only after a site is classified host-db/CMS; in-repo news stays on Promote Live (
TODO.mdFleet ops ·ROADMAP.mdContent class). - 2026-07-19: Native macOS Apple GPU, CPU temperature, Wi‑Fi, USB topology, and per-process network telemetry — local Mac compatibility ships with explicit unavailable states first (
src-tauri/src/metrics/,src-tauri/src/net/,src-tauri/src/usb/mod.rs:28). - 2026-07-15: Cross-PC metadata sync — superseded 2026-09-02 by gist mesh hub (
src/lib/mesh.ts,src-tauri/src/mesh.rs). - 2026-09-02: True LAN P2P / mDNS mesh — hub-via-private-gist is enough for Dale’s 7-device set; local paths stay per-device (
src/lib/mesh.ts). - 2026-07-15: Full Hub/VCC package + create-project — out of v1 scope; list import is shipped (
src-tauri/src/hub_vcc.rs). - 2026-07-15: Cashflow months/Gross/Nett UI — spreadsheet fields kept optional on Project; ledger epic later.
- 2026-07-15: GitHub PAT / private repo import — shipped 2026-09-17 via mesh PAT (
gist+repo) +githubPrivateon Project (src-tauri/src/github.rs). - 2026-08-21: Open PR counts on rows — deferred until Sync PAT work; never wire GitHub Actions (
src-tauri/src/github.rs). - 2026-07-15: Learn / Tools sidebar stubs — superseded by Projects/Overview/Processes/Fuel/Settings tabs (
src/App.tsx). - 2026-07-15: Multi-root filesystem watch / auto-discover — manual Sync parents shipped instead (
src/components/SyncMenu.tsx). - 2026-07-16: Shared Ada-Monitor / Deez-USB-Hub Rust crate — vendored copy into PM instead (
src-tauri/src/metrics/,src-tauri/src/usb/,src-tauri/src/usage/). - 2026-07-16: Delete / archive standalone Ada-Monitor app — leave sibling repo; PM is day-to-day home.
- 2026-07-16: Process-list virtualization / gauge CSS redesign during lightening pass — not needed at current load; runtime wins were isolate + idle pace + USB gate (
src/App.tsx,src-tauri/src/scheduler.rs). - 2026-07-16: Kanban custom columns / WIP limits / comment edit-delete — v1 is fixed columns with append-only comments (
src/components/KanbanBoard.tsx). - 2026-07-16: Rename project-table Priority “Default” → “Opt” — board tasks only; projects keep Default (
src/types.ts). - 2026-09-04: Native iOS / Expo / Tauri-mobile rewrite — superseded by Capacitor shell around existing
dist/(capacitor.config.ts,ios/,android/). TestFlight upload still open (signing: d@worldbuild.io). - 2026-09-02: Tailscale Funnel / public bind for remote HTTP — stay on tailnet-only bind + MagicDNS; Funnel is a separate threat model (
ROADMAP.mdTailscale mesh epic). - 2026-09-02: Custom multi-node sync protocol / CRDT over Tailscale — live UI is host-authoritative; offline replica stays Sync (gist/repo) epic (
src-tauri/src/store.rs). - 2026-09-02: Phone-side Fuel credential entry or secret-store proxy — credentials stay on the host node (
src-tauri/src/usage/credentials.rs).