- Inline is a work chat app
- Key paths:
server/Backend (Bun/TS)apple/macOS/iOS clients (SwiftUI/UIKit/AppKit)landing/web app (React/TanStack, not started)desktop/Windows app (Electron, not started)proto/protobufscli/client cli (Rust)packages/mcp/MCPpackages/openclaw/OpenClaw pluginpackages/bot-api/bot API client (HTTP, TypeScript)packages/sdk/realtime SDK (WS, TypeScript)
- Shared Swift packages:
apple/InlineKit,apple/InlineUI,apple/InlineProtocol; app targets:apple/InlineIOS,apple/InlineXIOS,apple/InlineMac. - Backend structure:
src/functions,src/realtime,src/db. - Use
bunfor JS/TS tooling (not npm/yarn); keep IDs asInt64(Id/ID) and timestamps in seconds unless API requires ms. - Production:
https://api.inline.chatandhttps://inline.chat.
- Never revert/discard/reset/clean work unless explicitly asked; ask before one-way deletion commands (
rm, restore/reset/checkout) unless explicitly requested. - When the worktree is dirty, continue without stopping for unrelated modified/untracked files. Only stop if unexpected changes appear in the specific file/hunk currently being edited.
- Never read, write or touch
.envfiles.
- Do not create/apply/drop stashes (including
--autostash) unless explicitly requested. - Do not switch branches, create/modify worktrees, or clone this repo for commit/push unless explicitly requested.
- On "push",
git pull --rebaseis allowed; if conflicts occur, stop and ask before resolving. - Scope commits to your changes unless user asks for "commit all".
- When unrecognized files exist, continue and focus only on relevant files.
- When a file contains unrelated changes, only stage the hunks you changed manually. Do not blindly add files.
- Use existing logging for production logs (
Log,server/src/utils/log.ts). - Avoid unsafe Swift/typescript patterns (
Any/anywhere avoidable, force unwraps,try!, unsafe casts). - Prefer minimizing dependencies and external tooling; do not add new dependencies unless the ongoing maintenance cost is clearly justified.
- Keep commits atomic and scoped; do not amend existing commits.
- Before committing, verify staged files (
git diff --cached --name-only); preferscripts/committer "<msg>" <file...>. - Write commit message in lowercase, include scope like this:
macos: fix ...; scopes include: macos|ios|server|mcp|sdk|cli|openclaw|apple|web|docs|website; for general changes either no prefix or generic ones: eg. chore - If undoing your own changes in a file with other uncommitted edits, ask first.
- Regenerate protobufs when contracts change (
bun run generate:proto); run focusedswift buildfor touched Swift packages. - Run focused tests/typechecks for affected areas; add/update tests for new features and regressions.
- Web is WIP. Do not extend requested changes or investigations to
landing/unless explicitly asked. - New UI work must stay in new UI components; do not modify legacy sidebar/old UI.
- When asked to write a plan or save your investigation, make a file in
.context/namedYYYY-MM-DD-title-kebab-case.md. - In final handoff/review/push, call out security risks, possible performance regressions, and state production readiness.
- Do just the right amount of engineering, not over engineer, and not under engineer. Simple and elegant solutions are often better than prematuraly complex solutions that go beyond the scope and spec.
- When adding colors, ensure the color supports light/dark theming and if it's not a one-off color, add it to the platforms theme class/module.
- Don't put implicit DB read/write calls in computed variables, keep them pure.
- When commiting file(s) with multiple changes/fixes, add a concise bullet list of specific items in the commit description; if fixing regressions or tricky bugs in non-conventional ways, add a very short explaination in commit description. Keep it under ~300 characters.
- Use shorter function/variables names as much as possible, avoid long phrasal function names when we can keep it simply unless required. Don't use weird abbreviations like
idxes;msg,id,ctxand alike are fine. - Keep control flow simple by avoiding nested ifs as much as possible; prefer switch/matching and early return if applicable.
- In classes/modules, group/separate types, variables and methods (public and private); sort methods by most important/most used; keep one-time used functions to minimum.
- After writing a new module, do a second pass to check and fix:
- Avoid duplication of logic that makes modules harder to maintain.
- Avoid making huge functions, split if it makes sense. Unless it hurts it more.
- Simplify logic if possible by using more suitable standard library methods, reusing logic, using better native APIs, extracting common helpers per best practices.
- Don't write unneccessary comments unless the module is complicated or purpose is not immediately clear.
- Always pin dependencies; Keep dependencies to minimum; Do not install new dependencies for simple tasks that we can create our own version in house.
- Security (due 2026-05-18): remove legacy email OTP verification fallback without
challengeTokeninserver/src/modules/auth/emailLoginChallenges.ts.
- Root:
bun run dev,bun run dev:server,bun run generate:proto,bun run db:migrate,bun run db:generate. - Checks: run the workspace-local
typecheck/lint/testscripts from that package instead of guessing commands or usingbun x. - App workspaces:
cd server && bun run typecheck|lint|test,cd landing && bun run typecheck|lint|test,cd desktop && bun run typecheck|lint|test,cd web && bun run typecheck|lint|test. - Package workspaces:
cd packages/openclaw && bun run typecheck|lint|test,cd packages/mcp && bun run typecheck|lint|test,cd packages/sdk && bun run typecheck|lint|test,cd packages/protocol && bun run typecheck|lint|test,cd packages/bot-api && bun run typecheck|lint|test,cd packages/bot-api-types && bun run typecheck|lint|test,cd packages/oauth-core && bun run typecheck|lint|test. - Nested workspaces:
cd landing/packages/client && bun run typecheck|lint|test,cd landing/packages/log && bun run typecheck|lint|test,cd landing/packages/protocol && bun run typecheck|lint|test,cd landing/packages/auth && bun run typecheck|lint|test,cd landing/packages/config && bun run typecheck|lint|test,cd server/packages/email-preview && bun run typecheck|lint|test,cd server/packages/email-templates && bun run typecheck|lint|test,cd scripts && bun run typecheck|lint|test,cd cli && bun run typecheck|lint|test. - Protos:
bun run generate:proto; per-language fromscripts/:bun run generate. - DB:
cd server && bun run db:migrate; create migrationbun run db:generate <name>; inspectbun run db:studio. - Backend tests:
cd server && bun test src/__tests__/modules/...(DEBUG=1for verbose).
- Public SDKs:
@inline-chat/protocol,@inline-chat/realtime-sdk,@inline-chat/bot-api-types,@inline-chat/bot-api. - Publish only when external runtime behavior/public types change.
- Publish order:
protocol -> realtime-sdkandbot-api-types -> bot-api. - For publish requests, provide copy-paste commands with package dir and
--otp=<YOUR_OTP_CODE>.
- CLI source:
cli/(Rust), binaryinline, release artifactsinline-cli-<version>-<target>.tar.gz. - Release flow:
cd scripts && bun run release:cli -- release. - Requires authenticated
ghand release env vars; script checks duplicate tags.
- Prefer new feature work in
apple/InlineIOSUIandapple/InlineMacUI; use legacy targets only when tightly coupled. - Minimum versions: iOS 18, macOS 15.
- Prefer Swift Testing (
import Testing,@Test,@Suite) and Observation (@Observable,@Bindable). - Prefer focused package builds/tests (for example
swift test,swift build, swift syntax typecheck) over fullxcodebuild. don't runxcodebuildyourself. AppDatabasemigrations are inInlineKit/Sources/InlineKit/Database.swift; append new migrations at the bottom.- For protobuf blobs in DB, follow the
DraftMessagetyped-model +ProtocolHelpers+DatabaseValueConvertiblepattern. - Use
Log.scoped; avoid main-thread heavy work; prefer Swift concurrency and composable views. - Regenerate Swift protos with
bun run proto:generate-swift(fromscripts/) when needed. - For Apple docs, use
https://sosumi.ai/...mirror of Developer docs viacurlinstead of web search. - Liquid Glass: gate with
#available(iOS/macOS 26+), apply after layout/appearance, wrap related views inGlassEffectContainer, use.interactive()only for tappable elements. - macOS releases:
bun run release:macos -- --channel <stable|beta>orcd scripts && bun run macos:release-app -- --channel <stable|beta>. - Local macOS direct app test build:
cd scripts && bun run macos:build-local-app -- --channel <stable|beta>; output app:build/InlineMacDirectLocal/Build/Products/DevBuild/Inline (Dev Build).app. DevBuildis an opinionated macOS config forInline (Dev Build); keep it aligned withReleaseand only diverge for its intentional identity values like bundle ID, app name, icon, andINLINE_USER_PROFILE = devbuild.- TestFlight is deprecated for macOS distribution; Sparkle/DMG direct build is primary.
- send-message and open-chat paths are latency-critical; progressive/message-list changes must avoid regressions and include focused perf validation.
- Xcode project uses filesystem-synced groups.
- Bun runtime entry:
server/src/index.ts; logic insrc/functions, realtime handlers/encoders insrc/realtime, DB schema/models insrc/db. - Add shutdown cleanup in
server/src/lifecycle/gracefulShutdown.ts. - Use Drizzle flow for schema changes; do not hand-write migrations.
- User sensitive data must be encrypted.
- Realtime is primary; legacy REST in
src/methods; auth insrc/utils/authorize.ts. - Encrypt user-sensitive data at rest using existing patterns (
src/modules/encryption/encryption2.ts). - Backend checks from
server/:bun test,bun run lint,bun run typecheck. - User data integrity and correctness must be considered during shutdown, DB downtime, burst requests, and such.
- Don't run the server dev server without explicitly being asked.
- Web stack: TanStack Router + Vite + StyleX/Tailwind; keep SSR-safe patterns.
- Web commands:
cd landing && bun run dev|build|typecheck|lint|test;cd web && bun run typecheck|lint|testfor the current stub workspace. - Prefer existing tokens/utilities over ad-hoc CSS; keep light/dark behavior consistent.
- Docs: routes in
landing/src/routes/docs/, content inlanding/src/docs/content/, nav inlanding/src/docs/nav.ts. - Docs additions: add markdown page + route + nav entry; keep writing concise and practical.
- Admin frontend lives in the separate repo at
~/dev/inline-chat/admin; backend remainsserver/src/controllers/admin.ts. - Keep admin endpoints under
/adminwith origin allowlist + admin session cookie. - Never load remote assets/scripts/styles/fonts in admin UI.
- Require valid admin session for all admin endpoints; use step-up checks for sensitive actions.
- Cookies:
httpOnly,securein production,sameSite: "strict", scoped to admin API domain. - Rate-limit auth flows; never expose decrypted secrets to clients.
- Admin metrics should exclude deleted users and bots by default.
- When asked to do a test build: Build the package, replace dist of local openclaw installation plugin with the dist, restart gateway, confirm it's healthy, ask to try.
- New UI: alternate UI switched by settings toggle with a different
MainWindowController. - New sidebar:
apple/InlineMac/Features/Sidebar/MainSidebar.swift. - New chat icon:
apple/InlineMac/Views/ChatIcon/SidebarChatIconView.swift. - CMD+K menu:
apple/InlineMac/Features/MainWindow/QuickSearchPopover.swift.