window.open with noopener returns null, so the subsequent
location.href assignment was a no-op. Open without noopener,
then null out opener manually before navigating.
Browsers block window.open after an await because the user
gesture is lost. Open a blank tab synchronously first, then
set the URL after PKCE generation completes.
Browser-based OAuth flow using Anthropic's hosted callback.
Users authorize on claude.ai, paste the code back, and tokens
are encrypted and stored in D1. Includes auto-refresh, Bearer
auth via custom fetch wrapper, and mcp_ tool name prefixing
required by the OAuth endpoint.
Also fixes provider-config save bug that required encryption
key unconditionally — now only checks when API key is present.
Extract agent-core as shared package with agentic loop,
tool definitions, and MCP integration. Compass tools
wrapped as MCP server using low-level Server API. Client
manager connects multiple MCP servers (in-memory, stdio,
HTTP) with unified tool routing. External MCP server
configs stored in DB with CRUD actions. Both Workers and
Bun runtimes use the new MCP client manager.
Shareable invite codes (e.g. hps-k7m2x9) let anyone
join an org after authenticating. Admins create/revoke
links from Settings > Team. Public /join/[code] route
handles acceptance with expiry and max-use limits.
Signup redirect now includes userId in the query string so the
verify-email endpoint receives it. After successful verification,
the endpoint creates a local DB user via ensureUserExists() so
the account is ready for login.
Consolidate AI Model, Skills, Code Bridge, and Identity into
one Agent tab with pill-style sub-navigation. Reduces top-level
settings from 8 tabs to 5 (page) / 6 (modal).
Replace Vercel AI SDK with Anthropic Claude Agent SDK.
Add standalone agent server (packages/agent-server/)
with MCP tools, JWT auth, and SSE streaming. Introduce
bridge API routes (src/app/api/compass/) and custom
SSE hooks (use-agent, use-compass-chat) replacing
useChat. Remove provider.ts, tools.ts, system-prompt.ts,
github-tools.ts, usage.ts, and old agent route.
Add 6 schedule tools (getProjectSchedule, createScheduleTask,
updateScheduleTask, deleteScheduleTask, createScheduleDependency,
deleteScheduleDependency) so the agent can read and write project
schedules directly. Uses direct DB access to avoid server action
context issues with streamText callbacks. Includes system prompt
guidance for schedule workflows, phases, and dependency types.
Standardize thinking/tool-call block appearance to
matching pill style. Switch message composer to emit
markdown via tiptap-markdown. Add chat-markdown CSS for
discord-compact rendering. Persist sidebar open state
via cookie. Fix chat-provider resume dispatching
generateUI calls on reload. Use flex layout for channel
page to support thread panel.
Redesign message composer to match Discord's compact input bar
with + button, inline editor, and action icons. Add emoji-mart
picker in popover that follows the active theme. Switch channel
page to CSS grid layout to fix composer overflow issues.
The logo in the org switcher is now a separate clickable link
to /dashboard (fullscreen chat). The org name + chevron still
opens the workspace dropdown independently.
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
* refactor(ui): unify org switcher with compass header
Merge the separate COMPASS branding and org switcher into a
single clean sidebar header element. The compass logo now lives
inside the org switcher trigger alongside the active org name.
Removes redundant SidebarMenu block from app-sidebar header.
Simplifies the org dropdown to just icon + name + checkmark.
* feat(themes): add 5 new presets
Warm Luxury, Black & White, Tweeter, Orang, and Catppuccin.
---------
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
Customers, vendors, and projects were inserted without
organization_id, making them invisible to org-scoped queries
after multi-tenancy was added. All seed rows now belong to
org-1 (Open Range Construction).
Includes UPDATE statements at the bottom so re-running the
seed fixes existing orphaned rows.
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
The demo cookie deletion in getCurrentUser() was a no-op from
Server Component context (cookies().delete() only works in
Server Actions and Route Handlers). The cookie persisted for
its full 24h lifetime, causing middleware to short-circuit auth
checks even when a real WorkOS session existed.
- Middleware: real session now takes priority over demo cookie,
stale cookie actively deleted via Set-Cookie on response
- auth.ts: remove early demo-first check and dead deletion code,
WorkOS session checked before demo fallback
- /demo route: clear compass-active-org so demo doesn't inherit
a real user's workspace selection
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
* feat(security): add multi-tenancy isolation and demo mode
Add org-scoped data isolation across all server actions to
prevent cross-org data leakage. Add read-only demo mode with
mutation guards on all write endpoints.
Multi-tenancy:
- org filter on executeDashboardQueries (all query types)
- org boundary checks on getChannel, joinChannel
- searchMentionableUsers derives org from session
- getConversationUsage scoped to user, not org-wide for admins
- organizations table, members, org switcher component
Demo mode:
- /demo route sets strict sameSite cookie
- isDemoUser guards on all mutation server actions
- demo banner, CTA dialog, and gate components
- seed script for demo org data
Also: exclude scripts/ from tsconfig (fixes build), add
multi-tenancy architecture documentation.
* fix(auth): real session takes priority over demo cookie
The demo cookie was checked unconditionally before WorkOS auth,
so logging in with real credentials after visiting /demo still
returned the demo user. Now getCurrentUser() tries WorkOS first
and only falls back to the demo cookie when no real session
exists. Clears the stale cookie on real login.
---------
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
Add org-scoped data isolation across all server actions to
prevent cross-org data leakage. Add read-only demo mode with
mutation guards on all write endpoints.
Multi-tenancy:
- org filter on executeDashboardQueries (all query types)
- org boundary checks on getChannel, joinChannel
- searchMentionableUsers derives org from session
- getConversationUsage scoped to user, not org-wide for admins
- organizations table, members, org switcher component
Demo mode:
- /demo route sets strict sameSite cookie
- isDemoUser guards on all mutation server actions
- demo banner, CTA dialog, and gate components
- seed script for demo org data
Also: exclude scripts/ from tsconfig (fixes build), add
multi-tenancy architecture documentation.
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
* docs(readme): rewrite to reflect current platform
The README was referencing PostgreSQL, Prisma, pnpm, Redis,
BullMQ, and construction-specific features that no longer
reflect the actual stack or positioning. Rewritten to align
with the landing page messaging and current tech stack.
* docs(agents): update with new modules and commands
Add testing, desktop, and tauri commands. Expand module
listings with voice, offline sync, desktop, and MCP.
Update project structure tree and add tauri/tiptap gotchas.
---------
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
Add voice state management, device picker, connection
panel, and mic/headphone/settings controls to sidebar
footer. Voice channels are now clickable (UI state only,
no WebRTC yet).
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
Add @user, @channel, @here, and @Compass agent mentions
to the conversations module. TipTap Mention extension with
suggestion popup, message_mentions junction table for
efficient querying, push notifications for mentioned users
respecting notifyLevel preferences, and edit support with
mention re-extraction. Also fix crypto.randomUUID fallback
for non-secure contexts.
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
Dark cartographic landing page with compass rose animation,
feature cards, modules ticker, and gantt showcase section.
Unified contacts page, settings page routing, sidebar
updates, and VisibilityState type fix in people table.
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
Move DashboardContextMenu to wrap SidebarProvider so the
right-click menu triggers across the entire dashboard
viewport including sidebar, header, and main content.
- MainContent now forwards refs and spreads props for Radix
asChild compatibility
- FeedbackWidget hoisted above SidebarProvider so
DashboardContextMenu can access useFeedback from wider
scope
- NavFiles uses useFilesOptional to avoid crash when
rendered outside FilesProvider (sidebar is in dashboard
layout, not files route layout)
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
isomorphic-dompurify depends on jsdom which requires Node.js APIs not
available in Cloudflare Workers. Replaced with a simple regex-based
sanitizer that works in edge runtime.
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
* fix: extract useConversations hook to dedicated context file
Move the conversations context and hook from the layout file to
src/contexts/conversations-context.tsx. Next.js layouts cannot export
hooks or types - only the default component export is allowed.
* fix(build): prevent esbuild from bundling memory-provider
The memory-provider module imports better-sqlite3, a native Node.js
module that cannot run in Cloudflare Workers. This causes OpenNext
build failures when esbuild tries to resolve the module.
Changes:
- Use dynamically constructed import path to prevent static analysis
- Remove memory provider from getServerDb (never used on Cloudflare)
- Add memory-provider to serverExternalPackages in next.config.ts
* fix(lint): rename module variable to loadedModule
The variable name 'module' is reserved in Next.js and causes ESLint
error @next/next/no-assign-module-variable.
* fix(conversations): use drizzle query for organization members
---------
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
* fix: extract useConversations hook to dedicated context file
Move the conversations context and hook from the layout file to
src/contexts/conversations-context.tsx. Next.js layouts cannot export
hooks or types - only the default component export is allowed.
* fix(build): prevent esbuild from bundling memory-provider
The memory-provider module imports better-sqlite3, a native Node.js
module that cannot run in Cloudflare Workers. This causes OpenNext
build failures when esbuild tries to resolve the module.
Changes:
- Use dynamically constructed import path to prevent static analysis
- Remove memory provider from getServerDb (never used on Cloudflare)
- Add memory-provider to serverExternalPackages in next.config.ts
* fix(lint): rename module variable to loadedModule
The variable name 'module' is reserved in Next.js and causes ESLint
error @next/next/no-assign-module-variable.
---------
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
* feat: add conversations, desktop (Tauri), and offline sync
Major new features:
- conversations module: Slack-like channels, threads, reactions, pins
- Tauri desktop app with local SQLite for offline-first operation
- Hybrid logical clock sync engine with conflict resolution
- DB provider abstraction (D1/Tauri/memory) with React context
Conversations:
- Text/voice/announcement channels with categories
- Message threads, reactions, attachments, pinning
- Real-time presence and typing indicators
- Full-text search across messages
Desktop (Tauri):
- Local SQLite database with sync to cloud D1
- Offline mutation queue with automatic replay
- Window management and keyboard shortcuts
- Desktop shell with offline banner
Sync infrastructure:
- Vector clock implementation for causality tracking
- Last-write-wins with semantic conflict resolution
- Delta sync via checkpoints for bandwidth efficiency
- Comprehensive test coverage
Also adds e2e test setup with Playwright and CI workflows
for desktop releases.
* fix(tests): sync engine test schema and checkpoint logic
- Add missing process_after column and sync_tombstone table to test schemas
- Fix checkpoint update to save cursor even when records array is empty
- Revert claude-code-review.yml workflow changes to match main
---------
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
- Add docs/development/sidebar.md with full architecture explanation
- Cover desktop expanded/collapsed states and mobile sheet rendering
- Document the gap-and-container pattern for layout stability
- Explain collapsed state centering, mobile-specific sizing
- Document the flicker bug fix in useIsMobile hook
- Add animation performance notes (will-change, ease-out)
- Include component reference and common patterns
- Update AGENTS.md with conversations module (WIP) and schema count
- Add sidebar.md to docs/README.md development section
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
- Fix mobile state initialization bug that caused flickering
(undefined -> false instead of !!undefined)
- Increase mobile sidebar width from 18rem to 20rem with 85vw max
- Add mobile-specific larger touch targets (44px min height)
- Increase icon and text sizes on mobile for better usability
- Fix collapsed sidebar button centering by reducing padding
- Remove fragile manual translate offsets on lg buttons
- Improve animation performance with will-change and ease-out
- Hide collapsed text instead of translating off-screen
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
implement short-term generative UI improvements:
- Add StreamingState type ("started" | "streaming" | "done") to ComponentContext
- Add loadingComponent field to catalog for Card, StatCard, DataTable, SchedulePreview
- Create skeleton components (CardSkeleton, StatCardSkeleton, etc.) with animate-pulse
- Add PropSkeleton component for different prop types (text, badge, table-row, etc.)
- Add useStreamingProps/useStreamingProp hooks to track prop arrival during streaming
- Add ComponentLoadingWrapper for prop-level skeleton display (opt-in via enablePropSkeletons)
- Fix JSON parse errors in API routes when request body is incomplete
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
* feat(ui): improve mobile sidebar and dashboard layout
- Enlarge compass logo on dashboard page (size-14 idle, size-10 active)
- Reposition logo higher with -mt-16 margin
- Add 6rem spacing between logo and chat
- Remove feedback hover button from bottom right
- Add event-based feedback dialog opening for mobile sidebar
- Remove feedback buttons from site header (mobile and desktop)
- Add mobile theme toggle button to header
- Increase mobile menu hitbox to size-10
- Reduce search hitbox to separate clickable area
- Remove redundant Compass/Get Help/Assistant/Search from sidebar
- Rename "People" to "Team"
- Add mobile-only feedback button to sidebar footer
- Reduce mobile sidebar width to 10rem max-width
- Center sidebar menu icons and labels on mobile
- Clean up mobile-specific padding variants
* chore: add local development setup system
- Create .dev-setup directory with patches and scripts
- Add apply-dev.sh to easily enable local dev without WorkOS
- Add restore-dev.sh to revert to original code
- Document all changes in README.md
- Store cloudflare-context.ts in files/ as new dev-only file
- Support re-apply patches for fresh development sessions
This allows running Compass locally without WorkOS authentication
for development and testing purposes.
---------
Co-authored-by: Avery Felts <averyfelts@Averys-MacBook-Air.local>
* feat(settings): redesign modal with improved layout and Agent tab
- Unified desktop/mobile layout using single Dialog component
- Desktop: 2-column grid (nav 180px | content)
- Mobile: Single column with dropdown navigation
- Fixed modal height to prevent content stretching
- Removed AI chat panel (commented out for future use)
- Renamed 'Slab Memory' to 'Agent' tab
- Added mock Agent settings: Signet ID (ETH) input and Configure button
- Added useChatStateOptional hook to chat-provider for safe context usage
- Fixed provider order in dashboard layout
* chore: add auth-bypass.ts to gitignore for local dev
---------
Co-authored-by: Avery Felts <averyfelts@Averys-MacBook-Air.local>
Place the feedback trigger in the header's left action area on desktop and mobile so it stays visible next to navigation controls.
Use a message-circle icon with a labeled button style, remove the old top-right header placement, and update the dialog copy to clarify that submissions go directly to developers for review.
Co-authored-by: Avery Felts <averyfelts@Averys-MacBook-Air.local>
Add local daemon that routes inference through user's own Anthropic
API key with filesystem and terminal access. Includes WebSocket
transport, MCP tool adapter, and API key auth.
Key components:
- compass-bridge package: local daemon with tool registry
- WebSocket transport for agent communication
- MCP API key management with HMAC auth and scoped permissions
- Usage tracking (tool calls, duration, success/failure)
- Settings UI for Claude Code configuration
- Migration 0019: mcp_api_keys and mcp_usage tables
- Test suite for auth and transport layers
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
Restructure docs/ into architecture/, modules/, and
development/ directories. Add thorough documentation
for Compass Core platform and HPS Compass modules.
Rewrite CLAUDE.md as a lean quick-reference that
points to the full docs. Rename files to lowercase,
consolidate old docs, add gotchas section.
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
Refactor ChatMessage to use AI SDK type guards and
render parts in natural order. Collapse reasoning by
default so thinking tokens don't flood the screen.
Cap reasoning content height during streaming. Add
tool workflow guidance to system prompt.
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
Persist agent-generated UIs as bookmarkable dashboards
with CRUD, sidebar nav, and iterative editing support.
Max 5 per user. Fresh data on each visit via saved queries.
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
Document recent features added since initial CLAUDE.md:
- Capacitor mobile app architecture and native hooks
- Plugin/skills system with registry pattern
- Visual theme system with 10 presets + AI generation
- Google Drive integration via service account
- Updated agent harness to reflect unified chat arch
- Expanded project structure and schema file listing
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
* feat(native): Capacitor mobile app shell with native features
Adds iOS + Android native app via Capacitor WebView wrapper
pointing at the live deployment. Includes push notifications,
biometric auth, camera with offline photo queue, offline
detection, status bar theming, keyboard handling, and deep
linking. Zero server-side refactoring required -- web deploys
update the app instantly.
* docs(native): add developer documentation for iOS and Android
---------
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
* fix(agent): add error handling and plugin tools
Replace useless try/catch with streaming-aware error
callbacks. streamText is lazy so errors occur during
streaming, not at call time. Now unwraps RetryError
to extract the actual APICallError with status code
and response body from OpenRouter.
Also adds API key validation, model ID fallback, and
includes plugin tools in the streamText call.
* chore(db): fix file permissions on 0015 snapshot
---------
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
PR #51 was merged with unresolved conflict markers in
drizzle/meta/0016_snapshot.json, producing invalid JSON.
Reconstructed the correct snapshot from the clean 0015
snapshot + the 0016 migration SQL (custom_themes +
user_theme_preference tables).
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
* feat(theme): visual theme system with presets, custom themes, and AI tools
Runtime theming engine with 10 preset palettes, user custom themes
persisted to D1, animated circle-reveal transitions via View Transition
API, and AI agent tools for generating/editing themes incrementally.
- Theme library: types, presets, CSS injection, font loading, animation
- Theme provider with localStorage cache for instant load (no FOUC)
- Server actions for theme CRUD and user preference persistence
- Agent tools: listThemes, setTheme, generateTheme, editTheme
- Appearance tab extracted from settings modal
- Migration 0015: custom_themes + user_theme_preference tables
- Developer documentation in docs/theme-system.md
* fix(db): make migration 0016 idempotent
tables were already created as 0015 before renumber.
use IF NOT EXISTS so the migration is safe to re-run.
---------
Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>