-
Notifications
You must be signed in to change notification settings - Fork 0
chore: remove mcp-notebook, slim down CLAUDE.md, clean up repo #230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
a2a2382
a018a29
47d9a7f
567c88c
dd8ece9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| --- | ||
| name: deus-code-style | ||
| description: "Deus Machine internal code style and conventions. Use when writing, reviewing, or modifying code in this project. Covers Tailwind v4, component patterns, animations, and performance. Triggers on: writing code, styling, components, CSS, tailwind, shadcn, animation, performance, database query, polling, rendering, zustand, react query." | ||
| --- | ||
|
|
||
| # Deus Code Style | ||
|
|
||
| Internal conventions for writing code in the Deus Machine codebase. | ||
|
|
||
| ## Quick Reference | ||
|
|
||
| | Topic | Guide | When to use | | ||
| |---|---|---| | ||
| | [Tailwind & Styling](tailwind.md) | Tailwind v4 gotchas, global CSS rules, color system | Writing any CSS or styling | | ||
| | [Components](components.md) | Shadcn, file locations, architecture patterns | Creating or modifying UI components | | ||
| | [Animations](animations.md) | Easing defaults, CSS vs Framer Motion, performance | Adding motion or transitions | | ||
| | [Performance](performance.md) | DB rules, polling, rendering, git subprocess | Backend queries, frontend lists, data fetching | | ||
|
|
||
| ## Core Conventions | ||
|
|
||
| ### ts-pattern for Discriminated Unions | ||
|
|
||
| Use `ts-pattern` instead of switch/case or if/else chains on `.type`, `.status`, `.state` fields: | ||
|
|
||
| ```tsx | ||
| import { match, P } from "ts-pattern"; | ||
|
|
||
| return match(block) | ||
| .with({ type: "text" }, (b) => <TextBlock block={b} />) | ||
| .with({ type: "tool_use" }, (b) => <ToolUseBlock block={b} />) | ||
| .exhaustive(); // catches missing cases at compile time | ||
| ``` | ||
|
|
||
| - `.exhaustive()` — all cases must be handled | ||
| - `.otherwise()` — intentional fallback for open-ended matching | ||
|
|
||
| ### State Management Split | ||
|
|
||
| - **Zustand** — UI state only (modals, selections, layout, sidebar) | ||
| - **TanStack Query v5** — Server state (workspaces, sessions, repos, messages, settings) | ||
|
|
||
| Feature hooks: `src/features/{feature}/api/{feature}.queries.ts` and `.service.ts`. Never put server data in Zustand. | ||
|
|
||
| ### File Organization | ||
|
|
||
| ``` | ||
| src/features/{feature}/ui/ # Feature-scoped components (default) | ||
| src/shared/components/ # Cross-feature reusable compositions | ||
| src/components/ui/ # Shadcn base primitives (edit freely) | ||
| src/platform/ # Platform abstraction (Electron IPC, socket) | ||
| ``` | ||
|
|
||
| Default to feature-scoped. Only promote to `shared/` when a second feature needs it. | ||
|
|
||
| ### Git Diff Semantics | ||
|
|
||
| - Branch resolution always prefers **remote** (`origin/{branch}`) over local — never change to local-first | ||
| - Diffs use git CLI against **working directory** (committed + staged + unstaged) — `diff_tree_to_tree` would miss uncommitted changes | ||
| - All git calls use `spawn()` with timeouts (5s short ops, 15s diffs) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # Animations | ||
|
|
||
| ## Project Defaults | ||
|
|
||
| - **Default easing:** `ease-out-quart` — `cubic-bezier(.165, .84, .44, 1)` | ||
| - **Default duration:** 200-300ms. Never exceed 1s. | ||
| - **Hover transitions:** `200ms ease` for color/background/opacity. Disable on touch with `@media (hover: hover) and (pointer: fine)`. | ||
| - **Don't use built-in CSS easings** (`ease-out`, `ease-in`) except `ease` for hover and `linear` for constant-speed. Always custom cubic-bezier. | ||
|
|
||
| ## CSS vs Framer Motion | ||
|
|
||
| **CSS/Tailwind** for: | ||
| - Hover/focus transitions | ||
| - Infinite loops (spinners, shimmers) | ||
| - Tooltip/popover enter/exit | ||
| - Simple opacity/transform keyframes | ||
|
|
||
| **Framer Motion** for: | ||
| - Mount/unmount transitions (`AnimatePresence` + `initial`/`animate`/`exit`) | ||
| - Layout animations (items shifting after reorder) | ||
| - Staggered lists (`staggerChildren`) | ||
| - Height auto (CSS can't animate to `auto`) | ||
|
|
||
| ## Rules | ||
|
|
||
| - Animate only `transform` and `opacity` — never width, height, top, left, margin, padding | ||
| - `will-change` only for: transform, opacity, clipPath, filter | ||
| - No blur above 20px | ||
| - Co-locate animation config with the component, not in global.css | ||
| - Never define `@keyframes` in global.css for a single component — use Framer Motion inline | ||
| - Reuse: `{ duration: 0.2, ease: [0.165, 0.84, 0.44, 1] }` (ease-out-quart) | ||
| - Always wrap conditional renders in `AnimatePresence` when exit animations are needed |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| # Components | ||
|
|
||
| ## Shadcn — You Own the Code | ||
|
|
||
| Files in `src/components/ui/` are starter code you're meant to customize. Editing them directly is the intended workflow. | ||
|
|
||
| ### Edit `components/ui/*` directly when: | ||
| - Changing default styles, adding project-wide variants, fixing a11y, adjusting animations | ||
|
|
||
| ### Create feature components when: | ||
| - Adding app-specific behavior, combining shadcn primitives into domain patterns, adding business logic | ||
|
|
||
| ### Shadcn Rules | ||
|
|
||
| 1. **Theme first** — try CSS variables in `global.css` before editing components. If you're overriding the same className everywhere, edit the component once. | ||
| 2. **Keep standard props** — preserve `className`, `variant`, `size`, `asChild`. Don't embed domain logic in `ui/*`. | ||
| 3. **Refresh from upstream** with `bunx shadcn@canary add <component> --overwrite`, then reapply customizations. | ||
|
|
||
| ## Component Architecture | ||
|
|
||
| ### Encapsulate Self-Contained Concerns | ||
|
|
||
| If a piece of UI involves data derivation + rendering + state, make it a component. Don't scatter utilities across the parent. | ||
|
|
||
| ```tsx | ||
| // Bad — parent wires up avatar logic manually | ||
| function Item({ repo }) { | ||
| const owner = getRepoOwner(repo.name); | ||
| const url = getGitHubAvatarUrl(owner); | ||
| return <Avatar><AvatarImage src={url} />...</Avatar>; | ||
| } | ||
|
|
||
| // Good — component owns its concern | ||
| function Item({ repo }) { | ||
| return <RepoAvatar repoName={repo.name} />; | ||
| } | ||
| ``` | ||
|
|
||
| ### Extract vs Keep Inline | ||
|
|
||
| **Extract when:** combines data + rendering, has own state/hooks, reusable, 10+ lines distracting from parent. | ||
|
|
||
| **Keep inline when:** pure layout div, one-liner, only makes sense in this parent. | ||
|
|
||
| ### Where Components Live | ||
|
|
||
| | Location | What goes here | | ||
| |---|---| | ||
| | `src/features/{feature}/ui/` | Default. Feature-scoped components. | | ||
| | `src/shared/components/` | Cross-feature reusable compositions (only when 2+ features need it) | | ||
| | `src/components/ui/` | Shadcn base primitives only | |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # Performance | ||
|
|
||
| The app manages tens of repos, hundreds of workspaces, and multiple concurrent agent sessions. Naive patterns compound at this scale. | ||
|
|
||
| ## Database | ||
|
|
||
| - **Index every query pattern** — all indexes in `shared/schema.ts`. Add one for any new query. | ||
| - **No N+1** — never subquery per row. Use `sessions.last_user_message_at` directly. Batch or denormalize. | ||
| - **Paginate unbounded collections** — messages, file lists. Default 50-100 items. | ||
| - **Auto-update triggers** for `updated_at` columns. | ||
| - **Column deprecation** — rename with `DEPRECATED_` prefix, never drop. | ||
| - **PRAGMA optimize** on startup and graceful shutdown. | ||
|
|
||
| ## Polling Discipline | ||
|
|
||
| - **WebSocket push over polling** — all data resources use WS subscriptions. Never poll data that has a subscription. | ||
| - **Budget:** <5 HTTP req/sec steady state. Only pollers: git diffs on working sessions (2-5s). | ||
| - **Gate polling on state** — don't poll idle workspaces. | ||
|
|
||
| | Frequency | What | | ||
| |---|---| | ||
| | 2-5s | Git diff hooks (only when session status = "working") | | ||
| | 30s+ / on-demand | Settings, repos, config, PR status | | ||
| | Never poll | Workspaces, stats, sessions, messages (WS push) | | ||
|
|
||
| ## Frontend Rendering | ||
|
|
||
| - **Virtualize unbounded lists** — anything >30 items uses `@tanstack/react-virtual` (sidebar, messages, file tree) | ||
| - **Zustand selector discipline** — never destructure entire store. Always individual selectors: | ||
| ```tsx | ||
| // Bad: const { x, y } = useStore(); | ||
| // Good: const x = useStore((s) => s.x); | ||
| ``` | ||
| Use `useShallow` for structurally-equal objects/arrays. | ||
| - **Memoize list items** — `React.memo()` on components in `.map()` loops | ||
| - **Batch queries** — use bulk endpoints (e.g. `useBulkDiffStats`), not per-item hooks | ||
|
|
||
| ## Git + Subprocess | ||
|
|
||
| - Treat git calls as expensive — deduplicate aggressively | ||
| - Use bulk endpoints (one call per repo interval), not per-item hooks | ||
| - Cache diff results with short TTL (5-10s) | ||
| - Cap concurrent git subprocesses to prevent CPU spikes | ||
|
|
||
| ## Read-Layer Priority | ||
|
|
||
| When optimizing, tackle in this order: | ||
| 1. `GET /workspaces/by-repo` (heaviest — joins repos + workspaces + sessions) | ||
| 2. `GET /stats` (consolidated count query) | ||
| 3. `GET /sessions/:id` | ||
| 4. `GET /sessions/:id/messages` (paginated, cursor-based) | ||
| 5. On-demand reads (repos, settings, config, PR status) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| # Tailwind & Styling | ||
|
|
||
| ## Tailwind CSS v4 — Key Differences | ||
|
|
||
| v4 is NOT v3. These are the traps: | ||
|
|
||
| - **No JavaScript config.** All config lives in `src/global.css` using `@theme` directive. Never create `tailwind.config.js`. | ||
| - **No `@layer`** — `@layer base/components/utilities` is not supported in v4. | ||
| - **No `@apply`** — use vanilla CSS instead. | ||
| - **No `@theme inline`** — put everything in the main `@theme` block. | ||
|
Comment on lines
+7
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: In Tailwind CSS v4, the tailwind.config.js file is optional. Configuration has shifted to a CSS-first approach using the Citations:
🏁 Script executed: # Examine the full content of the tailwind.md file to verify the !important contradiction at lines 52 and 60
cat -n .agents/skills/deus-code-style/tailwind.md | head -65 | tail -20Repository: zvadaadam/deus-machine Length of output: 1155 🌐 Web query:
💡 Result: In Tailwind CSS v4, the Citations:
Lines 7–10 contain inaccurate Tailwind v4 constraints that will mislead contributors. According to official Tailwind v4 documentation:
Additionally, there's a contradiction between line 52 ("Never use Suggested fix: Replace absolute prohibitions with pragmatic guidance: "Prefer CSS-first config; use 🧰 Tools🪛 LanguageTool[style] ~10-~10: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym. (ENGLISH_WORD_REPEAT_BEGINNING_RULE) 🤖 Prompt for AI Agents |
||
| - **No `tailwindcss-animate`** — animations are built-in. | ||
| - **Vite plugin:** `@tailwindcss/vite` (not `@tailwindcss/postcss`). | ||
|
|
||
| ### Color System: OKLCH | ||
|
|
||
| All colors use OKLCH, not HSL/RGB. Semantic colors in `:root` and `.dark`: | ||
|
|
||
| ```css | ||
| @theme { | ||
| --color-background: var(--background); | ||
| --color-primary: var(--primary); | ||
| --font-family-sans: "Helvetica Neue", -apple-system, ...; | ||
| } | ||
| ``` | ||
|
|
||
| For semi-transparent: `color-mix(in oklch, var(--primary) 25%, transparent)`. | ||
|
|
||
| ## What Goes Where | ||
|
|
||
| ### Global CSS (`src/global.css`) — ONLY: | ||
|
|
||
| 1. `@theme` block (design tokens) | ||
| 2. `@keyframes` (GPU-accelerated animations shared across components) | ||
| 3. Global element styles (`html`, `body`, `#root`, scrollbars) | ||
| 4. Complex effects Tailwind can't do (vibrancy, backdrop filters, markdown content styling) | ||
| 5. `@media (prefers-reduced-motion)`, `@media (hover: hover)` | ||
|
|
||
| ### Never add to global CSS: | ||
|
|
||
| Simple utilities that Tailwind already handles — spacing, shadows, typography, layout, colors. If Tailwind does it in 2-3 classes, don't make a custom utility. | ||
|
|
||
| ### Component variants (`src/components/ui/*`): | ||
|
|
||
| Repeated patterns: size variations (`size="sm"`), style variations (`variant="outline"`), state variations (`data-state="active"`). | ||
|
|
||
| ### Inline Tailwind: | ||
|
|
||
| Layout, one-off adjustments, responsive, state variants — the usual. | ||
|
|
||
| ## Specificity & Overrides | ||
|
|
||
| - Never use `!important` — if you need it, the specificity architecture is wrong | ||
| - `cn()` / twMerge only merges classes with **identical modifiers**. `has-[>svg]:px-3` and `has-[&>svg]:px-1` coexist instead of overriding. Always match the exact modifier string from the base component. | ||
| - When debugging spacing, always read the base component source (`components/ui/*.tsx`) to see what CVA defaults you're inheriting | ||
|
|
||
| ## Debugging Layout Issues | ||
|
|
||
| Before touching CSS: | ||
|
|
||
| 1. Outline everything: `* { outline: 1px solid rgba(255,0,0,0.3) !important; }` in DevTools | ||
| 2. Trace the full component tree (parent + element + children across files) | ||
| 3. Check parent/grandparent for `p-*`, `gap-*`, flex alignment | ||
| 4. Check compound spacing (parent padding + child margin + flex gap) | ||
| 5. Read the shadcn base component source for hidden defaults | ||
|
|
||
| ## General Rules | ||
|
|
||
| - All colors via CSS variables/tokens, never hardcoded (`bg-blue-500`, `#3b82f6`) | ||
| - Consistent 16px default padding (dense product) | ||
| - Use container queries (`@container`) over media queries for reusable components | ||
| - Prefer logical properties (`margin-inline`, `padding-block`) for future-proofing | ||
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.