docs: create milestone v1.5 roadmap (6 phases)

This commit is contained in:
Nexus Dev 2026-04-02 22:37:33 +00:00
parent ed14004ceb
commit 5b00379f2c
3 changed files with 226 additions and 233 deletions

View file

@ -69,33 +69,33 @@
| Requirement | Phase | Status |
|-------------|-------|--------|
| ONBD-01 | | Pending |
| ONBD-02 | | Pending |
| ONBD-03 | | Pending |
| ONBD-04 | — | Pending |
| ONBD-05 | — | Pending |
| ONBD-06 | — | Pending |
| ONBD-07 | — | Pending |
| CLOUD-01 | — | Pending |
| CLOUD-02 | — | Pending |
| CLOUD-03 | — | Pending |
| CLOUD-04 | — | Pending |
| CLOUD-05 | — | Pending |
| VOICE-01 | — | Pending |
| VOICE-02 | — | Pending |
| VOICE-03 | — | Pending |
| ASST-01 | — | Pending |
| ASST-02 | — | Pending |
| ASST-03 | — | Pending |
| ASST-04 | — | Pending |
| CLI-01 | | Pending |
| CLI-02 | | Pending |
| ONBD-01 | Phase 30 | Pending |
| ONBD-02 | Phase 30 | Pending |
| ONBD-03 | Phase 30 | Pending |
| ONBD-07 | Phase 30 | Pending |
| CLOUD-01 | Phase 31 | Pending |
| CLOUD-02 | Phase 31 | Pending |
| CLOUD-03 | Phase 31 | Pending |
| CLOUD-04 | Phase 31 | Pending |
| CLOUD-05 | Phase 31 | Pending |
| ONBD-04 | Phase 32 | Pending |
| ONBD-05 | Phase 32 | Pending |
| ONBD-06 | Phase 32 | Pending |
| ASST-01 | Phase 33 | Pending |
| ASST-02 | Phase 33 | Pending |
| ASST-03 | Phase 33 | Pending |
| ASST-04 | Phase 33 | Pending |
| VOICE-01 | Phase 34 | Pending |
| VOICE-02 | Phase 34 | Pending |
| VOICE-03 | Phase 34 | Pending |
| CLI-01 | Phase 35 | Pending |
| CLI-02 | Phase 35 | Pending |
**Coverage:**
- v1.5 requirements: 21 total
- Mapped to phases: 0
- Unmapped: 21 ⚠️
- Mapped to phases: 21
- Unmapped: 0 ✓
---
*Requirements defined: 2026-04-02*
*Last updated: 2026-04-02 after initial definition*
*Last updated: 2026-04-02 after roadmap created (phases 30-35)*

View file

@ -1,93 +1,199 @@
# Roadmap: v1.4 Hermes Default Provider
# Roadmap: Nexus
**Milestone:** v1.4
**Status:** Active
**Phases:** 27-29 (3 phases)
**Granularity:** Coarse
**Coverage:** 16/16 requirements mapped
## Milestones
- ✅ **v1.2.1 Universal Skill Management** - Phase 1 (shipped 2026-04-01)
- ✅ **v1.3 Chat & PWA** - Phases 21-26 (shipped 2026-04-02)
- ✅ **v1.4 Hermes Default Provider** - Phases 27-29 (shipped 2026-04-02)
- 🚧 **v1.5 Smart Onboarding + Personal AI Assistant** - Phases 30-35 (in progress)
---
## Phases
<details>
<summary>✅ v1.2.1 Universal Skill Management (Phase 1) - SHIPPED 2026-04-01</summary>
- [x] **Phase 27: Hermes Adapter** — Install and enable the Hermes adapter, expose it in the Add Agent dialog, and deliver working heartbeat execution with session persistence (completed 2026-04-02)
- [x] **Phase 28: Ollama Integration & Agent Surface** — Detect Ollama, list and recommend models, expose skill/cost/dashboard data for Hermes agents (completed 2026-04-02)
- [x] **Phase 29: Default Provider & End-to-End** — Onboarding fallback to Hermes, agent template compatibility, GSD workflow validation, full end-to-end smoke test (completed 2026-04-02)
### Phase 1: Foundation
**Goal**: Establish the display-layer rename infrastructure, git hygiene tooling, and rebase safety primitives that all subsequent phases depend on
**Plans**: 2/2 plans complete
---
Plans:
- [x] 01-01-PLAN.md — Branding package, VOCAB constants, commit-msg hook
- [x] 01-02-PLAN.md — Zone taxonomy, rerere config, rebase safety infrastructure
## Phase Details
</details>
<details>
<summary>✅ v1.3 Chat & PWA (Phases 21-26) - SHIPPED 2026-04-02</summary>
### Phase 21: Chat Foundation
**Goal**: Users can have real-time chat conversations with agents
**Plans**: 7/7 plans complete
### Phase 22: Agent Streaming
**Goal**: Agent responses stream in real-time with identity, edit, retry, and stop controls
**Plans**: 5/5 plans complete
### Phase 23: Brainstormer Flow
**Goal**: Users can turn a chat conversation into a tracked project with one handoff action
**Plans**: 4/4 plans complete
### Phase 24: Search, History & Branching
**Goal**: Users can find, bookmark, branch, and export any conversation
**Plans**: 4/4 plans complete
### Phase 25: File System
**Goal**: Users can upload, preview, and version files within chat; voice input transcribes speech to text
**Plans**: 9/9 plans complete
### Phase 26: PWA & Performance
**Goal**: Nexus installs as a PWA, works offline, and loads fast on mobile
**Plans**: 5/5 plans complete
</details>
<details>
<summary>✅ v1.4 Hermes Default Provider (Phases 27-29) - SHIPPED 2026-04-02</summary>
### Phase 27: Hermes Adapter
**Goal**: Users can create a Hermes agent in Nexus, configure it, and have it execute heartbeats that spawn `hermes chat -q`, return a result, and persist the session across runs
**Depends on**: Nothing (first phase of v1.4; depends on v1.3 milestone being shipped)
**Requirements**: HERM-01, HERM-02, HERM-03, HERM-04
**Success Criteria** (what must be TRUE):
1. "Hermes" appears in the "Add Agent" dropdown and can be selected to create a new agent
2. When creating a Hermes agent, the user can pick a model and toggle tool permissions; the agent is saved and appears in the agent list
3. When a heartbeat fires for a Hermes agent, Nexus spawns `hermes chat -q` with the task, the process completes, and the result is written back as a task update
4. A second heartbeat on the same Hermes agent resumes the prior session via `--resume`; context from the previous run is accessible
**Plans:** 1/1 plans complete
**Plans**: 1/1 plans complete
Plans:
- [x] 27-01-PLAN.md — Close four integration gaps: SESSIONED_LOCAL_ADAPTERS, create-mode toolsets bug, duplicate constant, session codec test
### Phase 28: Ollama Integration & Agent Surface
**Goal**: Users can see which Ollama models are available, get a recommendation for their hardware, configure any Hermes agent to use a local model, and see Hermes-specific runtime data in the dashboard and agent config
**Depends on**: Phase 27
**Requirements**: OLLA-01, OLLA-02, OLLA-03, OLLA-04, OLLA-05, HERM-05, HERM-06, HERM-07
**Success Criteria** (what must be TRUE):
1. When Ollama is installed, a status indicator in the Hermes agent config shows "Ollama detected" with the version; when Ollama is absent, the config shows installation instructions with a link
2. A Hermes agent's model selector lists all locally available Ollama models pulled from `ollama list`
3. User can save a Hermes agent with any Ollama model from the list; heartbeats use the selected model
4. The model selector shows a recommended model (highlighted) based on detected RAM/VRAM, derived from a shipped catalog
5. The agent config page shows Nexus-managed skills alongside Hermes native skills in a single unified list
6. The dashboard agent card for a Hermes agent shows model name, memory usage, and native skill count
7. Token usage and estimated model cost are recorded per heartbeat and surfaced in the cost tracking view
**Plans:** 3/3 plans complete
**Plans**: 3/3 plans complete
Plans:
- [x] 28-01-PLAN.md — Ollama service, routes, model catalog, and unit tests
- [x] 28-02-PLAN.md — UI model selector dropdown, install callout, Hermes skill badge
- [x] 28-03-PLAN.md — Hermes stateJson runtime data and dashboard HermesRuntimeCard
**UI hint**: yes
### Phase 29: Default Provider & End-to-End
**Goal**: A fresh Nexus install with only Hermes and Ollama works end-to-end — onboarding offers Hermes as the default, PM and Engineer templates run correctly on the Hermes runtime, and GSD workflow tasks complete successfully
**Depends on**: Phase 28
**Requirements**: DFLT-01, DFLT-02, DFLT-03, DFLT-04
**Success Criteria** (what must be TRUE):
1. During onboarding, if no cloud provider API key is detected, the setup flow offers "Use Hermes (local, free)" as the default provider with a one-click path to configure it
2. Creating a PM agent or Engineer agent from the predefined templates and assigning it to a Hermes runtime produces a working agent — heartbeats execute and return meaningful results
3. Running a full GSD workflow task (create issue, assign to Engineer, execute heartbeat, mark complete) with Hermes as the sole runtime completes without errors
4. A machine with only Nexus, Hermes, and Ollama installed (no Anthropic/OpenAI key) can complete the entire onboarding-to-first-task flow with no paywalls or missing-key errors
**Plans:** 2/2 plans complete
**Plans**: 2/2 plans complete
Plans:
- [x] 29-01-PLAN.md — Adapter probe route, onboarding wizard Hermes fallback, adapter-neutral templates
- [x] 29-02-PLAN.md — Hermes skill injection via promptTemplate, integration tests
</details>
---
### 🚧 v1.5 Smart Onboarding + Personal AI Assistant (In Progress)
**Milestone Goal:** The definitive onboarding experience — hardware detection, tiered provider setup (local/free cloud/paid), and a Personal AI Assistant mode that coexists with the Project Builder.
## Phases
- [ ] **Phase 30: Hardware Detection + Mode Selection** — Unauthenticated hardware probe, Apple Silicon unified memory handling, model recommendation database, and mode selector that gates all assistant-specific features
- [ ] **Phase 31: Puter.js Zero-Config Cloud** — Server-proxied Puter.js adapter with full cost tracking, Google OAuth PKCE tier, and subscription auto-detection; no API keys required for zero-config path
- [ ] **Phase 32: Multi-Step Onboarding Wizard** — Assemble all provider tiers and hardware data into a skippable multi-step wizard; summary screen routes directly into chat
- [ ] **Phase 33: Persistent Memory + Personal Assistant Mode** — File-backed memory with write-time sanitization, PersonalAssistantPage, conversation handoff to PM agent
- [ ] **Phase 34: Voice** — Piper TTS with pre-warm progress, Whisper STT wired into voice service, onboarding voice step activated
- [ ] **Phase 35: npx buildthis CLI** — Standalone bootstrapper package with hardware detection and provider tiering parity with web onboarding
---
## Phase Details
### Phase 30: Hardware Detection + Mode Selection
**Goal**: Users see accurate hardware information during onboarding, get a model recommendation matched to their machine, and choose a mode that correctly gates all downstream features — with the probe working before board auth exists
**Depends on**: Phase 29 (v1.4 shipped)
**Requirements**: ONBD-01, ONBD-02, ONBD-03, ONBD-07
**Success Criteria** (what must be TRUE):
1. On a fresh install (before any board auth token exists), the hardware probe returns GPU, RAM, and Apple Silicon unified memory data within 5 seconds
2. A Mac Mini M4 reports "unified memory" (not VRAM) with the 0.75 multiplier applied and copy that says "runs entirely on your machine"
3. The mode selector (Personal AI Assistant / Project Builder / Both) is visible during onboarding and the selected mode is persisted; assistant-specific UI is hidden when Project Builder-only is chosen
4. The model recommendation shown to the user matches an entry in the pre-built JSON catalog for the detected hardware tier (GPU / Apple Silicon / CPU-only)
**Plans**: TBD
### Phase 31: Puter.js Zero-Config Cloud
**Goal**: Users without Ollama installed can reach working AI in one click via Puter.js — all calls server-proxied, tokens server-stored, cost tracked; Google OAuth and subscription auto-detection round out the provider tier
**Depends on**: Phase 30
**Requirements**: CLOUD-01, CLOUD-02, CLOUD-03, CLOUD-04, CLOUD-05
**Success Criteria** (what must be TRUE):
1. A user with no Ollama and no API keys clicks "Continue with Puter" in onboarding, completes the Puter auth popup, and immediately gets a working chat response — no API key entry required
2. All Puter AI calls flow through `POST /api/puter-proxy/chat` (verifiable in server logs); the Puter auth token is stored server-side via secretService, not in localStorage
3. Token cost for Puter responses appears in the cost tracking view, attributed correctly per conversation
4. A user with Hermes, Claude Code, or OpenClaw already installed sees those tools pre-filled in the provider configuration step with no manual entry
5. A user clicking "Sign in with Google" for Gemini completes PKCE OAuth and gets a Gemini-backed chat response; the UI displays a policy-risk note that Google OAuth may trigger abuse detection
**Plans**: TBD
**UI hint**: yes
### Phase 32: Multi-Step Onboarding Wizard
**Goal**: Users move through a complete, skippable onboarding flow that assembles hardware data, provider selection, and voice options into a summary screen — and can jump straight into chat from there
**Depends on**: Phase 31
**Requirements**: ONBD-04, ONBD-05, ONBD-06
**Success Criteria** (what must be TRUE):
1. A user can click "Skip" on every onboarding step (hardware, provider, voice) and reach the summary screen; the resulting workspace has at least one working agent with a valid provider
2. The summary screen shows the configured providers and agent-model pairings for the selected mode; no corporate language ("company", "CEO", "mission") appears anywhere in the flow
3. From the summary screen, one click navigates directly to the Personal Assistant chat or the project dashboard (depending on chosen mode) with no additional prompts
**Plans**: TBD
**UI hint**: yes
### Phase 33: Persistent Memory + Personal Assistant Mode
**Goal**: Users in Personal AI Assistant mode accumulate memory across sessions that shapes future responses — with no risk of credentials leaking into prompts — and can hand off any conversation to a PM agent with context intact
**Depends on**: Phase 32
**Requirements**: ASST-01, ASST-02, ASST-03, ASST-04
**Success Criteria** (what must be TRUE):
1. A fact stated in one chat session ("I prefer TypeScript") is referenced correctly by the assistant in a new session started after closing and reopening the browser
2. Pasting an API key or token into chat and then starting a new session results in the assistant having no knowledge of that credential — the sanitization blocklist prevented it from being stored
3. A user clicks "Turn this into a project" in an assistant conversation; a PM agent is created with a system message containing the conversation summary and they land on the project dashboard
4. A user with mode set to "Both" can switch between Personal Assistant chat and the project dashboard without losing context or cross-contaminating assistant memory with project agent messages
**Plans**: TBD
**UI hint**: yes
### Phase 34: Voice
**Goal**: Users can speak to the assistant (Whisper STT) and hear responses read aloud (Piper TTS) — Piper pre-warms visibly so the first synthesis call does not appear broken, and voice is offered during onboarding based on hardware capability
**Depends on**: Phase 32
**Requirements**: VOICE-01, VOICE-02, VOICE-03
**Success Criteria** (what must be TRUE):
1. On a CPU-only machine (no GPU), enabling Piper TTS in the assistant produces audible speech output within a reasonable time after the first synthesis (not a silent hang)
2. When Piper's WASM voice model is downloading for the first time, a visible progress indicator is shown before the TTS toggle is enabled; the download completes and TTS works without a page reload
3. The onboarding voice step offers Whisper STT and Piper TTS toggles only when the hardware detection step has confirmed sufficient capability; on hardware below the threshold, the step is skipped or shows a capability warning
**Plans**: TBD
### Phase 35: npx buildthis CLI
**Goal**: A developer can run `npx buildthis` on a fresh machine and either open an already-running Nexus or be guided through install — with the same hardware detection and provider tiering as the web onboarding
**Depends on**: Phase 30 (hardware detection service must exist)
**Requirements**: CLI-01, CLI-02
**Success Criteria** (what must be TRUE):
1. Running `npx buildthis` on a machine where Nexus is already running opens the Nexus UI in the default browser; running it on a machine with no Nexus guides the user through installation steps
2. The CLI bootstrapper detects the same hardware tier (GPU / Apple Silicon / CPU-only) as the web onboarding and presents the matching provider tier recommendations in the terminal prompt
**Plans**: TBD
---
## Coverage Validation
All 16 v1 requirements are mapped to exactly one phase. No orphans.
All 21 v1.5 requirements are mapped to exactly one phase. No orphans.
| Requirement | Phase |
|-------------|-------|
| HERM-01 | 27 |
| HERM-02 | 27 |
| HERM-03 | 27 |
| HERM-04 | 27 |
| HERM-05 | 28 |
| HERM-06 | 28 |
| HERM-07 | 28 |
| OLLA-01 | 28 |
| OLLA-02 | 28 |
| OLLA-03 | 28 |
| OLLA-04 | 28 |
| OLLA-05 | 28 |
| DFLT-01 | 29 |
| DFLT-02 | 29 |
| DFLT-03 | 29 |
| DFLT-04 | 29 |
| ONBD-01 | 30 |
| ONBD-02 | 30 |
| ONBD-03 | 30 |
| ONBD-07 | 30 |
| CLOUD-01 | 31 |
| CLOUD-02 | 31 |
| CLOUD-03 | 31 |
| CLOUD-04 | 31 |
| CLOUD-05 | 31 |
| ONBD-04 | 32 |
| ONBD-05 | 32 |
| ONBD-06 | 32 |
| ASST-01 | 33 |
| ASST-02 | 33 |
| ASST-03 | 33 |
| ASST-04 | 33 |
| VOICE-01 | 34 |
| VOICE-02 | 34 |
| VOICE-03 | 34 |
| CLI-01 | 35 |
| CLI-02 | 35 |
---
@ -95,6 +201,19 @@ All 16 v1 requirements are mapped to exactly one phase. No orphans.
| Phase | Milestone | Plans Complete | Status | Completed |
|-------|-----------|----------------|--------|-----------|
| 27. Hermes Adapter | v1.4 | 1/1 | Complete | 2026-04-02 |
| 28. Ollama Integration & Agent Surface | v1.4 | 3/3 | Complete | 2026-04-02 |
| 29. Default Provider & End-to-End | v1.4 | 2/2 | Complete | 2026-04-02 |
| 1. Foundation | v1.2.1 | 2/2 | Complete | 2026-04-01 |
| 21. Chat Foundation | v1.3 | 7/7 | Complete | 2026-04-02 |
| 22. Agent Streaming | v1.3 | 5/5 | Complete | 2026-04-02 |
| 23. Brainstormer Flow | v1.3 | 4/4 | Complete | 2026-04-02 |
| 24. Search, History & Branching | v1.3 | 4/4 | Complete | 2026-04-02 |
| 25. File System | v1.3 | 9/9 | Complete | 2026-04-02 |
| 26. PWA & Performance | v1.3 | 5/5 | Complete | 2026-04-02 |
| 27. Hermes Adapter | v1.4 | 1/1 | Complete | 2026-04-02 |
| 28. Ollama Integration & Agent Surface | v1.4 | 3/3 | Complete | 2026-04-02 |
| 29. Default Provider & End-to-End | v1.4 | 2/2 | Complete | 2026-04-02 |
| 30. Hardware Detection + Mode Selection | v1.5 | 0/TBD | Not started | - |
| 31. Puter.js Zero-Config Cloud | v1.5 | 0/TBD | Not started | - |
| 32. Multi-Step Onboarding Wizard | v1.5 | 0/TBD | Not started | - |
| 33. Persistent Memory + Personal Assistant Mode | v1.5 | 0/TBD | Not started | - |
| 34. Voice | v1.5 | 0/TBD | Not started | - |
| 35. npx buildthis CLI | v1.5 | 0/TBD | Not started | - |

View file

@ -7,7 +7,7 @@ stopped_at: null
last_updated: "2026-04-02T18:00:00.000Z"
last_activity: 2026-04-02
progress:
total_phases: 0
total_phases: 6
completed_phases: 0
total_plans: 0
completed_plans: 0
@ -21,28 +21,22 @@ progress:
See: .planning/PROJECT.md (updated 2026-04-02)
**Core value:** A fresh onboard asks for ONE thing (root directory), auto-creates PM + Engineer agents, and drops you in the dashboard.
**Current focus:** Defining requirements for v1.5
**Current focus:** Phase 30 — Hardware Detection + Mode Selection (ready to plan)
## Current Position
Phase: Not started (defining requirements)
Plan: —
Status: Defining requirements
Last activity: 2026-04-02 — Milestone v1.5 started
Phase: 30 of 35 (Hardware Detection + Mode Selection)
Plan: — (not yet planned)
Status: Ready to plan
Last activity: 2026-04-02 — v1.5 roadmap created; 21 requirements mapped across 6 phases (30-35)
Progress: [__________] 0%
### Upstream Rebase Log
| Date | Commits Behind | Conflicts | Build | Notes |
|------|---------------|-----------|-------|-------|
| 2026-04-01 | 0 | 0 | OK | Already rebased from 120+ commits session; upstream hasn't moved |
## Performance Metrics
**Velocity:**
- Total plans completed: 0
- Total plans completed: 0 (v1.5)
- Average duration: -
- Total execution time: 0 hours
@ -54,149 +48,26 @@ Progress: [__________] 0%
**Recent Trend:**
- Last 5 plans: none yet
- Last 5 plans: none yet (v1.5)
- Trend: -
*Updated after each plan completion*
| Phase 01-foundation P01 | 2 | 2 tasks | 7 files |
| Phase 21-chat-foundation P02 | ~15min | 2 tasks | 5 files |
| Phase 21-chat-foundation P01 | 2 | 2 tasks | 8 files |
| Phase 21-chat-foundation P00 | 2 | 2 tasks | 4 files |
| Phase 21-chat-foundation P04 | 4min | 2 tasks | 7 files |
| Phase 21-chat-foundation P03 | 6 | 2 tasks | 6 files |
| Phase 21-chat-foundation P05 | 4 | 3 tasks | 8 files |
| Phase 21-chat-foundation P06 | 10min | 2 tasks | 7 files |
| Phase 22-agent-streaming P01 | 6min | 2 tasks | 6 files |
| Phase 22-agent-streaming P03 | 3 | 2 tasks | 4 files |
| Phase 22-agent-streaming P04 | 4min | 2 tasks | 5 files |
| Phase 22-agent-streaming P05 | 20min | 3 tasks | 6 files |
| Phase 23-brainstormer-flow P00 | 3min | 2 tasks | 11 files |
| Phase 23-brainstormer-flow P02 | 5min | 2 tasks | 6 files |
| Phase 23-brainstormer-flow P01 | 10min | 2 tasks | 2 files |
| Phase 23-brainstormer-flow P03 | 5 | 2 tasks | 4 files |
| Phase 24-search-history-branching P00 | 5 | 2 tasks | 9 files |
| Phase 24-search-history-branching P01 | 12 | 2 tasks | 2 files |
| Phase 24-search-history-branching P02 | 3min | 2 tasks | 7 files |
| Phase 24-search-history-branching P03 | 4 | 3 tasks | 7 files |
| Phase 25-file-system P00 | 6 | 2 tasks | 11 files |
| Phase 25-file-system P02 | 15 | 2 tasks | 5 files |
| Phase 25-file-system P01 | 15 | 2 tasks | 17 files |
| Phase 25-file-system P03 | 3 | 2 tasks | 7 files |
| Phase 25-file-system P08 | 8 | 2 tasks | 5 files |
| Phase 25-file-system P04 | 5min | 2 tasks | 5 files |
| Phase 25-file-system P06 | 5 | 2 tasks | 5 files |
| Phase 25-file-system P07 | 10 | 2 tasks | 6 files |
| Phase 26-pwa-performance P00 | 5 | 2 tasks | 9 files |
| Phase 26-pwa-performance P01 | 4 | 2 tasks | 2 files |
| Phase 26-pwa-performance P02 | 20 | 2 tasks | 8 files |
| Phase 26-pwa-performance P04 | 15 | 2 tasks | 10 files |
| Phase 27-hermes-adapter P01 | 2 | 3 tasks | 3 files |
| Phase 28-ollama-integration P01 | 3 | 2 tasks | 6 files |
| Phase 28 P03 | 12 | 2 tasks | 3 files |
| Phase 28-ollama-integration P02 | 5min | 2 tasks | 3 files |
| Phase 29-default-provider P01 | 8 | 2 tasks | 4 files |
| Phase 29-default-provider P02 | 12 | 2 tasks | 8 files |
## Accumulated Context
### Decisions
Decisions are logged in PROJECT.md Key Decisions table.
Recent decisions affecting current work:
Key constraints for v1.5 (established at roadmap):
- Roadmap: Company → Workspace (not Project) to avoid collision with existing Project entity
- Roadmap: Display-only renames — all code identifiers, DB schema, routes, env vars unchanged
- Roadmap: Branding package (`packages/branding/`) as single string mutation surface
- Roadmap: Vite alias redirects OnboardingWizard import to Nexus-owned replacement (Phase 4)
- Roadmap: `~/.nexus` pointer file with read-both-paths fallback for migration safety (Phase 2)
- [Phase 01-foundation]: Keep @paperclipai/branding package name for upstream sync compatibility
- [Phase 01-foundation]: Use as const for VOCAB to enable TypeScript literal type inference on all values
- [Phase 01-foundation]: Hook source tracked in scripts/nexus-commit-msg-hook.sh for post-clone reinstallation
- [Phase 01-foundation]: rerere.autoupdate=true so resolved conflicts are auto-staged during future rebases
- [Phase 21-chat-foundation]: Used object-syntax (table) => ({}) for Drizzle index callbacks to match existing codebase convention in documents.ts, agents.ts
- [Phase 21-chat-foundation]: Use it.todo() (not it.skip()) for Wave 0 test scaffolding — vitest marks todos semantically, no false positives
- [Phase 21-chat-foundation]: Minimal imports in test stubs — no service mocks until Plans 01-05 wire up implementations
- [Phase 21-02]: Use ExtraProps from react-markdown for ChatCodeBlock type signature to satisfy ComponentType constraint
- [Phase 21-02]: Add hljs CSS as plain rules (not @import) scoped to .dark, .theme-tokyo-night, :root selectors
- [Phase 21-chat-foundation]: ChatPanelProvider inside PanelProvider so ChatPanel can call setPanelVisible to close PropertiesPanel
- [Phase 21-chat-foundation]: Chat toggle button in desktop sidebar bottom controls with hidden md:inline-flex
- [Phase 21-03]: Pitfall 3 (updatedAt bump): addMessage always updates chatConversations.updatedAt after inserting — ensures conversation list sort order stays correct
- [Phase 21-03]: Pitfall 5 (auto-title idempotency): WHERE title IS NULL guard makes auto-title set safe to call multiple times
- [Phase 21-03]: Missing export fix: createConversationSchema/updateConversationSchema/createMessageSchema were in validators/chat.ts but not re-exported from shared/src/index.ts
- [Phase 21-chat-foundation]: Two-path handleSend in ChatPanel: direct chatApi for path 1 (no active conversation) avoids hook mutation needing a conversationId that does not exist yet
- [Phase 21-chat-foundation]: messages array in useChatMessages flattened from pages and reversed so display is chronological (API returns desc by createdAt)
- [Phase 21-chat-foundation]: Custom window event (nexus:focus-chat-search) used instead of forwardRef drilling to focus search input from Cmd+K
- [Phase 21-chat-foundation]: Cmd+K handler placed before input-guard early return in useKeyboardShortcuts so it fires globally even from input/textarea
- [Phase 22-agent-streaming]: Use fetch ReadableStream instead of EventSource for POST SSE streaming endpoint
- [Phase 22-agent-streaming]: streamEcho stub yields word-by-word with 50ms delay; Phase 23 replaces with real LLM adapter
- [Phase 22-agent-streaming]: Partial content on stop saved with [stopped] suffix via chatApi.savePartialMessage
- [Phase 22-agent-streaming]: isAnyStreaming prop (not isStreaming) distinguishes global streaming state for disabling edit/retry globally in ChatMessage
- [Phase 22-agent-streaming]: /search disabled with Coming soon; resolveAgentFromContent routes slash > @mention > active agent
- [Phase 22-agent-streaming]: [Phase 22-05]: virtualizer.measure() on streamingContent change handles dynamic height re-measurement for growing streaming message (Pitfall 3)
- [Phase 22-agent-streaming]: [Phase 22-05]: handleRetry truncates from user message (not assistant), removing assistant + all subsequent messages before re-streaming
- [Phase 23-brainstormer-flow]: Added journal entries for idx 47 (nebulous_klaw) and 48 (add_chat_messages_updated_at) retroactively to keep journal consistent with files on disk
- [Phase 23-brainstormer-flow]: Used @/lib/router Link abstraction (not react-router-dom) for ChatTaskCreatedBadge and ChatStatusUpdateBadge — consistent with all other link components in the codebase
- [Phase 23-brainstormer-flow]: ChatSpecCardInner extracted as inner component to avoid conditional hook calls after JSON.parse error path in ChatSpecCard
- [Phase 23-brainstormer-flow]: issueService imported directly in chatRoutes(db) — option (a) from plan, simplest approach matching heartbeat.ts pattern
- [Phase 23-brainstormer-flow]: Used activeConversationId === null as proxy for new conversation in brainstormer auto-select
- [Phase 23-brainstormer-flow]: Used useToast()/pushToast() for error toast in ChatPanel handleHandoff (custom ToastContext, not sonner)
- [Phase 24-search-history-branching]: Used AnyPgColumn type annotation for parentConversationId self-referential FK — matches existing pattern in issues.ts, goals.ts, execution_workspaces.ts
- [Phase 24-search-history-branching]: content_search tsvector column omitted from Drizzle schema — Postgres-generated stored column queried via raw sql`` only
- [Phase 24-search-history-branching]: searchMessages returns empty items early when query.trim() is empty — avoids PostgreSQL error on blank tsquery
- [Phase 24-search-history-branching]: exportConversation uses this.getConversation() to reuse notFound guard without duplicating query logic
- [Phase 24-search-history-branching]: Used HighlightedText React component instead of innerHTML for term highlighting — eliminates XSS surface
- [Phase 24-search-history-branching]: exportConversation returns URL string (not fetch call) since server sends file download via browser navigation
- [Phase 24-search-history-branching]: shouldFilter=false pattern on Command for server-side FTS — all future search dialogs should follow this
- [Phase 24-search-history-branching]: Custom event nexus:open-chat-search routes search trigger through CommandPalette without Cmd+K conflict
- [Phase 24-search-history-branching]: Branch-on-edit checks editedIdx < messages.length - 1 before calling branchConversation
- [Phase 24-search-history-branching]: bookmarkedMessageIds as Set<string> for O(1) lookup rebuilt from useChatBookmarks per-conversation data
- [Phase 25-file-system]: Used object-syntax (table) => ({}) for Drizzle index callbacks in chat_files and chat_file_references — matches existing codebase pattern
- [Phase 25-file-system]: chatFiles uses nullable FKs (SET NULL) for conversationId/messageId — file may exist before a conversation or message is created
- [Phase 25-file-system]: chatFileReferences uses CASCADE deletes for fileId and conversationId — reference has no meaning without both anchors
- [Phase 25-file-system]: Used XHR instead of fetch for chatApi.uploadFile to enable upload progress events (fetch lacks upload.onprogress)
- [Phase 25-file-system]: ChatInput onFilesPicked/pendingFiles/onRemoveFile props are all optional for backward compatibility
- [Phase 25-file-system]: Content-Length uses object.contentLength from storage ?? chatFile.sizeBytes to prevent stream ECONNRESET
- [Phase 25-file-system]: createFileReferenceSchema.safeParse() receives fileId injected from URL param for UUID format validation
- [Phase 25-file-system]: ChatFilePreview shows inline image with max-h-[300px] + ChatFileCard below; non-image types use ChatFileCard only
- [Phase 25-file-system]: listMessages fetches chatFiles with inArray(messageId) as second query, merged in-memory
- [Phase 25-file-system]: completedFileIds captured before clearCompleted in handleSend to avoid race condition
- [Phase 25-file-system]: Use functional setState for transcription append in VoiceRecordButton — avoids stale closure vs native DOM event approach
- [Phase 25-file-system]: enableVoiceInput defaults to false for backward-compat; ChatPanel passes true unconditionally — server returns 503 gracefully if whisper absent
- [Phase 25-file-system]: execFileAsync over exec for whisper CLI invocation — no shell injection risk with system-generated tmpPath
- [Phase 25-file-system]: Used DOMParser + replaceChildren to safely render hljs output — avoids raw HTML injection pattern while preserving same visual output as rehype-highlight
- [Phase 25-file-system]: highlight.js added as explicit ui/package.json dependency (was transitive via rehype-highlight only)
- [Phase 25-file-system]: Used execFile (not exec) for git commands in gitFileService — array-based args prevent shell injection
- [Phase 25-file-system]: Git commit is fire-and-forget after upload — response not blocked by git operation
- [Phase 25-file-system]: History route placed before /content route to avoid Express path ambiguity on /files/:fileId/*
- [Phase 25-file-system]: placeholderService reads/writes PLACEHOLDERS.md using regex row parser to avoid markdown deps
- [Phase 25-file-system]: addEntry is fire-and-forget — response not blocked by placeholder manifest I/O
- [Phase 25-file-system]: resolveDefaultStorageDir() used for projectDir in placeholder service — consistent with git-file-service pattern
- [Phase 26-pwa-performance]: [Phase 26-00]: Cache name changed from paperclip-v2 to nexus-v1; activate event deletes all non-nexus-v1 caches to bust stale entries
- [Phase 26-pwa-performance]: [Phase 26-00]: API paths (/api/*) pass through without SW interception — network-only for all API traffic
- [Phase 26-pwa-performance]: All pages use named exports so React.lazy requires .then(m => ({ default: m.X })) module re-mapping
- [Phase 26-pwa-performance]: manualChunks: vendor-react, vendor-router, vendor-query, vendor-markdown (excludes @mdxeditor/editor to avoid circular deps)
- [Phase 26-pwa-performance]: useMediaQuery uses addEventListener('change') not addListener() — addListener is deprecated in modern browsers
- [Phase 26-pwa-performance]: PullToRefresh wraps ScrollArea in ChatConversationList, not the entire list component — keeps desktop layout unaffected
- [Phase 26-pwa-performance]: MobileChatView uses 100dvh not 100vh — avoids keyboard-shrink issue (RESEARCH Pitfall 3)
- [Phase 26-pwa-performance]: pushService uses named exports (not class) matching existing chat.ts service pattern
- [Phase 26-pwa-performance]: initVapid is graceful — checks env vars before calling setVapidDetails, logs warning if absent
- [Phase 26-pwa-performance]: sendPushToAll uses Promise.allSettled so one failed delivery doesn't block others; stale 410/404 subscriptions auto-deleted
- [Phase 26-pwa-performance]: DELETE /api/push/subscribe uses request body (not URL param) — endpoints are long URLs; api.delete() extended with direct fetch
- [Phase 26-pwa-performance]: NotificationPermissionPrompt engagement gate: agentResponseCount >= 3 derived via useMemo from messages with role === assistant
- [Phase 27-hermes-adapter]: Toolsets field moved inside !isCreate guard — new agents get default toolsets; edit form uses adapterConfig.toolsets correctly
- [Phase 27-hermes-adapter]: Hermes session codec has no cwd field (unlike claude/codex/cursor/gemini) — only sessionId tracked
- [Phase 28-ollama-integration]: Force-added server/src/data/ with git add -f — source catalog JSON is not generated data despite data/ gitignore pattern
- [Phase 28-ollama-integration]: getRecommendedModel uses QUALITY_RANK map (best>reasoning>balanced>fast) to pick highest quality variant within 75% RAM budget
- [Phase 28]: hermesNativeSkillCount derived from agentsApi.skills in UI (not stateJson) — avoids cross-DB query in heartbeat path
- [Phase 28]: COALESCE jsonb concat pattern used for stateJson merge in hermes_local heartbeat — prevents overwriting existing fields
- [Phase 28-ollama-integration]: Used useCompany() hook for companyId in hermes config-fields — consistent with AgentConfigForm pattern
- [Phase 28-ollama-integration]: Create mode only sets model (not provider/base_url) — CreateConfigValues lacks those fields; buildHermesConfig resolves provider at runtime
- [Phase 29-default-provider]: Probe route uses board auth (no companyId) — adapter availability is instance-level, not company-level
- [Phase 29-default-provider]: hermes_local makes directory optional — Hermes runtime does not require cwd to operate
- [Phase 29-default-provider]: AGENT_TEMPLATES in NewAgentDialog are adapter-neutral — /agents/new form handles adapter default logic independently
- [Phase 29-default-provider]: hermesPromptTemplate constructed inline in wizard — static content avoids server round-trip
- [Phase 29-default-provider]: persistSession: true for hermes_local agents — preserves execution context across heartbeat runs
- [Phase 29-default-provider]: Test file duplicates promptTemplate string intentionally — validates the contract, not the implementation
- No DB schema changes — all state in existing JSONB fields (`instance_settings.general`) and file-backed JSON (`data/memory/<companyId>.json`)
- Puter.js is server-proxied adapter only — `@heyputer/puter.js` browser import is for auth popup only; all AI calls via `POST /api/puter-proxy/chat`
- OAuth tokens (Google, Puter) stored server-side via `secretService` — never in localStorage
- Memory sanitization blocklist applied at write time, not retrieval time
- Apple Silicon: use `os.freemem()` × 0.75 for VRAM estimate; label as "unified memory" not "VRAM"; use `systeminformation` v5 (not v6)
- Unauthenticated `GET /system/providers` endpoint required for pre-auth hardware probe
- Google OAuth cloud tier: include but flag policy risk (Gemini CLI abuse detection issue #21866)
- Skip-all minimum valid state: one working agent with a valid provider must be created when user skips all steps
### Pending Todos
@ -204,10 +75,13 @@ None yet.
### Blockers/Concerns
None identified yet.
- [Phase 31] Puter.js Node.js server-side streaming API surface unverified — confirm `stream: true` works server-side before designing `puterProxyService`; plan-phase should include a research spike
- [Phase 31] Puter.js ToS on server-side request relaying unverified — attribute costs to user's Puter account in all UI copy as mitigation
- [Phase 33] Chat route injection point needs codebase inspection — confirm correct hook location in `server/src/services/chat.ts` during plan-phase
- [Phase 34] smart-whisper Apple Silicon acceleration claim unverified on Mac Mini M4 — fall back to `tiny.en` if `base.en` acceleration not confirmed on device
## Session Continuity
Last session: 2026-04-02T17:43:07.540Z
Stopped at: Completed 29-default-provider-29-02-PLAN.md
Last session: 2026-04-02T18:00:00.000Z
Stopped at: Roadmap created — v1.5 phases 30-35 defined and written to ROADMAP.md
Resume file: None