apps/mind, runs locally on port 7816, and is served in
production from https://mind.tuturuuu.com. Local development should use
Portless at https://mind.tuturuuu.localhost; the legacy direct fallback is
http://localhost:7816.
Mind is available to signed-in Tuturuuu users, not only internal
@tuturuuu.com accounts. The satellite app accepts the Tuturuuu cross-app login
handoff through /verify-token, stores a host-local tuturuuu_app_session
cookie for the mind app target, and keeps workspace data behind membership
checks. Mind must not create a local Supabase Auth session.
Mind consumes /verify-token in the proxy and requires the coordinated cookie
pair on protected routes: the Mind-local app-session cookie for route guards and
the Web-issued app-session cookie for forwarded central APIs. If only the
Mind-local cookie remains, route users through local /login to refresh the
pair. Expired access tokens should rotate through
/api/auth/refresh-app-session on the Mind origin while refresh cookies are
valid.
Mind AI also follows the shared AI credit contract instead of an employee-only
allowlist. The /api/ai/mind route resolves the selected personal or workspace
credit source, checks the caller’s membership for workspace credits, preflights
model availability and remaining credits, and deducts usage from that same
billing workspace after a successful stream.
Mind AI uses the stable google/gemini-3.1-flash-lite model entry for its
Flash Lite default/fallback surface. Stored preferences and old clients that
still send google/gemini-3.1-flash-lite-preview are normalized to the stable
ID before credit model resolution and provider streaming.
The model selector reads from the paginated infrastructure model catalog with
server-side search and “load more” pages. Do not reintroduce first-page-only
catalog fetches or local-only filtering; matching models must remain reachable
even when they are outside the initial response.
Dual-Host Parity
Mind is available through both the standalone satellite host and the main web dashboard. The standalone route shape stays/{wsId} and
/{wsId}/boards/{boardId}. Inside apps/web, the route shape is
/{wsId}/mind and /{wsId}/mind/boards/{boardId}.
Both hosts must render the same shared UI and use the same client logic from
@tuturuuu/mind-ui. Keep apps/mind and the apps/web Mind routes as thin
host wrappers for auth, workspace resolution, and route prefixing only. Future
Mind feature work belongs in packages/mind-ui or the centralized Mind APIs so
the standalone app and web-hosted app stay 1:1.
Board route-segment layouts that render Mind board routes must load
@xyflow/react/dist/style.css, and the shared Mind shell must keep a concrete
dashboard embed height. Keep that stylesheet out of root app layouts and the
Mind index so it is only loaded when users enter a canvas route. Without both
pieces, React Flow can mount but render as a blank or collapsed canvas inside
embedded dashboard routes.
Board library vs studio
The workspace index route is a board library, not the canvas studio:- Web:
/{wsId}/mindlists boards (search, create, pick). Selecting or creating a board navigates to/{wsId}/mind/boards/{boardId}for the studio. - Satellite:
/{wsId}is the same board library;/{wsId}/boards/{boardId}is the studio.
MindBoardIndex from @tuturuuu/mind-ui owns the index experience. Do not
auto-select the first board on the index route. MindDashboard only mounts on
board routes and receives initialBoardId; it must not fall back to
boards[0]. If a board route loads without a selected board, prompt the user to
return to the index instead of showing an infinite loading state.
API Ownership
Protected Mind data stays behindapps/web APIs:
/api/v1/workspaces/:wsId/mind/boards/api/v1/workspaces/:wsId/mind/boards/:boardId/api/v1/workspaces/:wsId/mind/boards/:boardId/graph/api/v1/workspaces/:wsId/mind/boards/:boardId/patches/api/v1/workspaces/:wsId/mind/search/api/v1/workspaces/:wsId/mind/ai/patches/:patchId/apply/api/v1/hive/servers/:serverId/mind-simulationsfor importing a Mind board into Hive as agents plus a saved interaction workflow/api/ai/mind/api/ai/chat/upload-url,/api/ai/chat/delete-file, and/api/ai/chat/file-urlsfor Mind chat attachments
/api/v1/* and /api/ai/* to apps/web and consumes
them through @tuturuuu/internal-api. Do not add direct client Supabase reads
or client-local raw fetch('/api/...') calls for protected Mind data.
Workspace routes must normalize aliases such as personal, verify workspace
membership with the request-scoped auth context, and then perform private-schema
reads or writes through the centralized server repository.
Mind repositories must not use ad-hoc raw SQL from application code. Keep data
operations in private-schema Postgres RPCs and call them through a
service-role Supabase admin client with .schema('private').rpc(...).
apps/database/supabase/config.toml exposes the private schema to PostgREST
so these RPCs are callable, but table/function grants stay service-role-only.
Changing that config requires a local Supabase restart or bun sb:up before the
Mind APIs stop returning Invalid schema: private.
The canvas should load from the graph-only snapshot path, while generated draft
patch artifacts load from the patch-list path. Do not couple canvas rendering to
recent AI patch serialization: a failed patch-artifact refresh should stay
inside the assistant panel and must not replace the board canvas with a board
load error. The legacy full snapshot can still return graph data plus patches
for backward compatibility.
Mind graph handles use loose React Flow connections with one visible connection
point per side. Cluster and children frames are synthetic canvas nodes used only
for interaction: manual links to a frame persist as normal node edges with frame
endpoint metadata, so saved graph payloads still satisfy the node-only edge
schema while rendering the relationship to the group boundary.
Nodes, relationships, clusters, and child-group frames should all be selectable
from the canvas. Node and relationship selections open editable properties,
while synthetic group or cluster frame selections open a compact read-only
properties island that identifies the anchor node and child count.
Hive Integration
Insideapps/web, a Mind board can be sent to Hive from the compact top-right
canvas controls. The import API reads the saved Mind graph, verifies workspace
membership through the request-scoped client, requires Hive admin access, and
creates Hive NPC agents from the highest-signal Mind nodes. Mind edges become
Hive agent interaction pairs, and the generated Hive workflow first stamps the
Mind source context into the world before running the agent-interaction node.
Keep this integration hosted in apps/web: the standalone apps/mind surface
should stay a shared Mind canvas and must not assume that the Hive satellite is
available in the same host. Client code should call
createHiveMindSimulation() from @tuturuuu/internal-api/hive; do not add
client-local raw fetch calls or duplicate graph-to-agent conversion logic.
Data Model
Mind product tables live in theprivate schema. User access goes through the
central web API; direct table access is service-role only.
private.mind_boardsprivate.mind_nodesprivate.mind_edgesprivate.mind_tagsprivate.mind_node_tagsprivate.mind_groupsprivate.mind_group_nodesprivate.mind_node_linksprivate.mind_ai_threadsprivate.mind_ai_messagesprivate.mind_ai_patches
mind_node_links is the first integration seam for Tasks, Calendar, documents,
projects, and external URLs. Live pickers can attach to this link contract later
without changing the core graph schema.
Nodes carry a first-class workflow status: backlog, planned,
in_progress, in_review, blocked, completed, deferred, and
cancelled. The canvas and AI tools should treat status as a planning signal,
not just decoration: blocked nodes need dependencies, in-review nodes need
validation criteria, and completed nodes should remain available for historical
context and dependency tracing.
AI Patch Safety
Mind AI chats default to review mode. In review mode, tools can inspect mindboards, load graph chunks, search nodes, and store proposed patches, but the user applies the patch explicitly from the Mind UI. Direct-write mode is scoped to the current chat. In direct-write mode, theapply_mind_patch tool can write the structured patch transactionally and the
repository records the patch status, applied_at, and applying user for audit.
Structured patches should stay small enough to review. Prefer multiple focused
patches over a single broad rewrite when consolidating large graphs.
For normal structure-generation requests, a patch should still be complete
enough to be useful: include the major clusters, concrete child nodes, and the
relationship edges that connect them to the root goal or to each other. Avoid
AI drafts that expand only one branch while leaving related top-level systems as
isolated nodes.
The existing board is authoritative. AI drafts should reuse and extend relevant
existing node IDs first, then create missing child nodes and relationships
around those anchors. Do not draft a detached replacement root when the current
mindboard already contains a matching goal, system, cluster, or milestone.
The patch tool normalizes generated aliases and stores operations in apply-safe
order: newly-created parent and child nodes are inserted before relationship
edges or updates that reference them. Existing draft patches are normalized
again just before application so older edge-first drafts do not fail foreign-key
checks.
For large boards, the assistant should inspect structure first, then search or
load neighborhoods/chunks instead of requesting a full graph by default. Keep
responses action-oriented: suggest follow-up passes, propose draft patches when
they are useful, and only implement graph writes when the chat is explicitly in
Implement mode.
After a draft patch is applied from the Mind UI, the client closes the
assistant panel, reloads the board, runs the smart canvas organizer, saves the
resulting positions, and refreshes board queries. The organizer should keep
true same-level sequence nodes in a compact horizontal lane, place explicit
children under their parent, and anchor supporting or dependency nodes near the
higher-level node they affect.
Applying a draft and refreshing layout are separate phases: once the patch
application RPC returns, patch artifacts should show Applied immediately. If
the follow-up auto-layout save fails, keep the patch applied and show a retryable
layout-refresh warning instead of treating the graph patch as failed.
Mind boards auto-save canvas edits. The board title, canvas tools, tag filter,
and save status live in one compact top-left island. The title is editable from
that island, the tag filter uses an icon-only ghost dropdown, and the save icon
shows saved, saving, unsaved, or retryable error state and can be clicked to
force a save. In the web-hosted board route, the compact top-right island owns
the Hive simulation launcher and the assistant toggle.
Autosave signatures, tag indexing, group-frame layout, and relationship routing
obstacle scans are intentionally debounced so dragging stays responsive on dense
boards; keep direct node movement immediate and move only derived calculations
onto short debounce windows.
React Flow canvas routes should pan with two-finger trackpad movement while
preserving pinch-to-zoom. Do not switch trackpad scrolling back to zoom-only
behavior; use explicit canvas controls or pinch gestures for zoom.
Generated plans and patch drafts should be treated as artifacts. The newest
artifact can open in the proposal island, while every message keeps a compact
artifact row for reopening it. When a generated visual plan and a draft patch
belong to the same assistant response, render them as one centralized draft
proposal pending approval: the structured patch preview is the review context,
and the single Apply action belongs to the proposal shell. Do not show the
visual plan and draft patch as duplicated stacked content. Tool-call and
artifact sections default to
collapsed compact rows; while the assistant is working, the row should show a
spinner and the latest tool or artifact name without expanding the full debug
list. When a draft is applied, the applied patch should render as Applied in
those artifact views instead of staying visually draft-only.
The canvas toolbar can copy the current board as Markdown or JSON. This export
uses the local in-canvas graph state, including unsaved position edits, so it is
useful for sharing a planning snapshot or debugging AI patch output.
Deployment
Mind has dedicated Vercel workflows:.github/workflows/vercel-preview-mind.yaml.github/workflows/vercel-production-mind.yaml
VERCEL_TOKEN, VERCEL_ORG_ID, and VERCEL_MIND_PROJECT_ID in the
workflow environments vercel-preview-mind and vercel-production-mind.
Deployment should rely on Vercel project environment variables pulled by
vercel pull; do not add provider AI keys, production Supabase service keys,
TURBO_TOKEN, or TURBO_TEAM at workflow scope.
Verification
After changing Mind schema, API, or UI code, run the most relevant focused checks first, then the repo-required checks:bun sb:typegen and consume
database shapes through @tuturuuu/types/db.