Skip to content

chore: remove mcp-notebook, slim down CLAUDE.md, clean up repo#230

Merged
zvadaadam merged 5 commits into
mainfrom
zvadaadam/remove-mcp-notebook
Apr 4, 2026
Merged

chore: remove mcp-notebook, slim down CLAUDE.md, clean up repo#230
zvadaadam merged 5 commits into
mainfrom
zvadaadam/remove-mcp-notebook

Conversation

@zvadaadam

@zvadaadam zvadaadam commented Apr 3, 2026

Copy link
Copy Markdown
Owner

Summary

  • Remove mcp-notebook — entire package (server, vm-context, tests, build config) and all references from frontend, backend, agent-server, and settings
  • Rewrite CLAUDE.md — from 998 lines to ~96. Code style conventions moved into .claude/skills/deus-code-style/ as a multi-file skill (tailwind, components, animations, performance)
  • Clean up dead weight — remove remotion-best-practices skill, storybook config, outdated docs (browser-tools, scroll-anchoring, visual-effects, deus-json-spec, workspace-tools)
  • README refresh — add logo, centered tagline, macOS/Linux download badges
  • Add CONTRIBUTING.md and LICENSE (ELv2)
  • Rename .claude/ agent config → .agents/ directory structure

Net: -10,478 lines (764 added, 11,242 removed)

Test plan

  • bun install succeeds (lockfile updated)
  • bun run dev:web starts without notebook-related errors
  • bun run test:backend passes
  • bun run test:agent-server passes
  • Settings UI no longer shows notebook toggle
  • README renders correctly on GitHub (logo, badges, links)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Breaking Changes

    • Experimental notebooks feature removed (UI, backend, package, tests).
  • Removals

    • Storybook support and notebook package removed; many Remotion best-practice docs and example animations deleted.
  • Documentation

    • Repository rebranded to “Deus Machine”; added CONTRIBUTING and AGENTS docs; README updated; license switched to Elastic License 2.0; env examples revised.
  • Improvements

    • Centralized animation easing tokens; clearer error handling/logging; manifest command safety checks; removed notebook env forwarding; updated pairing/release links and repo references.

- Remove mcp-notebook package entirely (server, vm-context, tests, build)
- Rewrite CLAUDE.md from 998 lines to ~96 — move code style conventions
  into .claude/skills/deus-code-style/ (tailwind, components, animations,
  performance)
- Remove remotion-best-practices skill and storybook config
- Remove outdated docs (browser-tools, scroll-anchoring, visual-effects, etc.)
- Clean up notebook references from frontend, backend, agent-server, settings
- Add README logo and styled download badges
- Add CONTRIBUTING.md and LICENSE
- Rename .claude/ agent config to .agents/ directory structure

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Apr 3, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 27b053d5-c98b-4509-b790-9a1138a16a82

📥 Commits

Reviewing files that changed from the base of the PR and between 567c88c and dd8ece9.

📒 Files selected for processing (10)
  • apps/web/src/features/browser/automation/VisualEffects.stories.tsx
  • apps/web/src/features/session/ui/AgentOverlays.stories.tsx
  • apps/web/src/features/session/ui/Chat.stories.tsx
  • apps/web/src/features/session/ui/CircularPixelGrid.stories.tsx
  • apps/web/src/features/session/ui/PixelGrid.stories.tsx
  • apps/web/src/features/session/ui/tools/components/SyntaxHighlighter.stories.tsx
  • apps/web/src/features/session/ui/tools/renderers/ToolRenderers.stories.tsx
  • apps/web/src/features/sidebar/ui/WorkspaceItem.stories.tsx
  • apps/web/src/features/workspace/ui/WorkspaceHeader.stories.tsx
  • knip.json
💤 Files with no reviewable changes (9)
  • apps/web/src/features/workspace/ui/WorkspaceHeader.stories.tsx
  • apps/web/src/features/browser/automation/VisualEffects.stories.tsx
  • apps/web/src/features/sidebar/ui/WorkspaceItem.stories.tsx
  • apps/web/src/features/session/ui/tools/components/SyntaxHighlighter.stories.tsx
  • apps/web/src/features/session/ui/CircularPixelGrid.stories.tsx
  • apps/web/src/features/session/ui/AgentOverlays.stories.tsx
  • apps/web/src/features/session/ui/tools/renderers/ToolRenderers.stories.tsx
  • apps/web/src/features/session/ui/PixelGrid.stories.tsx
  • apps/web/src/features/session/ui/Chat.stories.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • knip.json

📝 Walkthrough

Walkthrough

Adds centralized Deus code-style docs and shared animation tokens; rebrands repository to "deus-machine"; removes the MCP Notebook package, server, UI, and tests; adds manifest command safety checks and gates for spawning shell commands; removes Storybook and related build artifacts; and applies widespread UI/branding and minor error‑handling adjustments.

Changes

Cohort / File(s) Summary
Code style & guides
​.agents/skills/deus-code-style/SKILL.md, ​.agents/skills/deus-code-style/*.md
New Deus code-style skill and topic docs (tailwind, animations, components, performance).
Docs, README & License
AGENTS.md, CONTRIBUTING.md, README.md, LICENSE, .claude
Repository rebadge to deus-machine; added contributor docs and ELv2 license; new AGENTS.md/CONTRIBUTING guidance.
Notebook / MCP removal
packages/mcp-notebook/*, apps/agent-server/agents/notebook-server.ts, apps/web/src/features/notebook/*
Deleted mcp-notebook package, build script, server/tools, VM/context/store, NotebookPanel UI, re-exports, and associated tests.
Feature flags & types
shared/types/settings.ts, apps/backend/src/lib/schemas.ts, apps/web/src/features/workspace/store/workspaceLayoutStore.ts
Removed experimental_notebooks setting and schema field; removed "notebook" from ContentTab union and UI visibility.
Manifest safety & spawn gating
apps/backend/src/services/manifest.service.ts, apps/backend/src/routes/workspaces.ts, apps/backend/src/server.ts
Added isManifestCommandSafe() to detect dangerous shell meta-characters; setup/archive spawns now gated on safety check; stopped forwarding NOTEBOOK_SERVER_BUNDLE_PATH.
Storybook & build cleanup
.storybook/*, package.json (scripts & deps), eslint.config.mjs
Removed Storybook configs, scripts and plugin; removed mcp-notebook from build/typecheck scripts and packaging; adjusted knip/ESLint.
Large doc deletions
docs/*, ​.agents/skills/remotion-best-practices/*
Bulk deletion of many documentation pages and Remotion best-practice skill pages and examples.
Animation token centralization
apps/web/src/shared/lib/animation.ts, apps/web/src/features/*/ui/*.tsx
Added shared EASE_OUT_QUART and EASE_OUT_QUART_CSS; components updated to import shared tokens.
Error handling / catch messaging
apps/web/src/**, apps/backend/src/**, apps/cli/**
Replaced silent .catch(()=>{}) usages with documented no‑ops or console warnings in multiple IPC/clipboard/cleanup paths.
Branding & links
apps/cli/*, apps/landing/*, apps/desktop/*, apps/web/src/*, test/e2e/*
Updated domains, GitHub repo references, emails, and release URLs from box-ide/rundeus → deus-machine/deusmachine.ai.
Packaging & scripts
package.json, electron-builder.yml, scripts/*, packages/mcp-notebook/*, .hive/*
Removed mcp-notebook packaging and extraResources; deleted package manifests/build scripts; removed several git submodule pointers.
Frontend UI removals
apps/web/src/app/layouts/content-tabs.ts, apps/web/src/app/layouts/ContentView.tsx, settings UI files
Removed notebook tab, NotebookPanel mounts, settings toggle, and Notebook re-exports.
Tests removed
packages/mcp-notebook/src/__tests__/*
Deleted multiple notebook-related test suites and fixtures.
Small stability fixes
apps/web/src/features/terminal/ui/Terminal.tsx, apps/web/src/features/terminal/ui/TerminalPanel.tsx
Added safe xterm fit wrapper, stable EMPTY_TABS constant, and centralized animation exports.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Backend
  participant ManifestService
  participant Shell

  Client->>Backend: request workspace archive/setup
  Backend->>ManifestService: validate command (isManifestCommandSafe)
  alt command unsafe
    ManifestService-->>Backend: returns false
    Backend->>Client: log warning, emit setup_failed, skip spawn
  else command safe
    ManifestService-->>Backend: returns true
    Backend->>Shell: spawn "sh -c <cmd>" (with merged safe env)
    Shell-->>Backend: process started / errors
    Backend->>Client: progress events / completion
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰 I hopped through branches late at night,

Notebooks tucked away, docs took flight,
Easing shared and spawns kept tight,
Links rebadged to a new bright light,
The rabbit cheers: "Ship safe and right!"

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch zvadaadam/remove-mcp-notebook

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/web/src/features/browser/ui/BrowserPanel.tsx (1)

523-536: 🛠️ Refactor suggestion | 🟠 Major

Refactor .then() chains to async/await.

The handleToggleDevtools callback uses .then() chains, which violates the coding guideline requiring async/await for promises. As per coding guidelines, "Always use async/await for promises. Never use .then() chains for sequential operations."

♻️ Proposed refactor to async/await
-  const handleToggleDevtools = useCallback(() => {
+  const handleToggleDevtools = useCallback(async () => {
     if (!activeTab?.webviewLabel) return;
     if (activeTab.devtoolsOpen) {
-      native.browserViews
-        .closeDevtools(activeTab.webviewLabel)
-        .then(() => handleUpdateTab(activeTab.id, { devtoolsOpen: false }))
-        .catch((err) => handleAddLog(activeTab.id, "error", `Close devtools failed: ${err}`));
+      try {
+        await native.browserViews.closeDevtools(activeTab.webviewLabel);
+        handleUpdateTab(activeTab.id, { devtoolsOpen: false });
+      } catch (err) {
+        handleAddLog(activeTab.id, "error", `Close devtools failed: ${err}`);
+      }
     } else {
-      native.browserViews
-        .openDevtools(activeTab.webviewLabel)
-        .then(() => handleUpdateTab(activeTab.id, { devtoolsOpen: true }))
-        .catch((err) => handleAddLog(activeTab.id, "error", `Open devtools failed: ${err}`));
+      try {
+        await native.browserViews.openDevtools(activeTab.webviewLabel);
+        handleUpdateTab(activeTab.id, { devtoolsOpen: true });
+      } catch (err) {
+        handleAddLog(activeTab.id, "error", `Open devtools failed: ${err}`);
+      }
     }
   }, [activeTab, handleUpdateTab, handleAddLog]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/features/browser/ui/BrowserPanel.tsx` around lines 523 - 536,
Convert the handleToggleDevtools callback to an async function and replace the
.then()/.catch() chains with await inside a try/catch: check
activeTab?.webviewLabel early, then if activeTab.devtoolsOpen await
native.browserViews.closeDevtools(activeTab.webviewLabel) and call
handleUpdateTab(activeTab.id, { devtoolsOpen: false }) after the await,
otherwise await native.browserViews.openDevtools(activeTab.webviewLabel) and
call handleUpdateTab(activeTab.id, { devtoolsOpen: true }); on error use
handleAddLog(activeTab.id, "error", `... failed: ${err}`) in the catch block;
update the dependency array accordingly.
🧹 Nitpick comments (1)
.agents/skills/deus-code-style/tailwind.md (1)

52-60: Clarify the !important exception for DevTools debugging.

Line 52 says never use !important, while Line 60 recommends it in a debug snippet. Please mark Line 60 as a DevTools-only temporary exception to avoid contradictory guidance.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/skills/deus-code-style/tailwind.md around lines 52 - 60, The
guidance is contradictory: the rule "Never use `!important`" conflicts with the
debug snippet that uses `!important`; update the tailwind.md content to mark
that specific debug example ("* { outline: 1px solid rgba(255,0,0,0.3)
!important; }") as a DevTools-only, temporary exception and clarify it should
never be checked into source (add a short note after the snippet like
"DevTools-only temporary exception — do not commit"); keep the global rule
"Never use `!important`" unchanged and ensure the new note explicitly ties the
exception to debugging in DevTools.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.agents/skills/deus-code-style/SKILL.md:
- Around line 46-51: Add a language identifier to the fenced code block in
SKILL.md to satisfy MD040; replace the opening ``` with ```text (or another
suitable language) so the block reads ```text followed by the four path lines
and the closing ```, ensuring consistent linting.

In @.agents/skills/deus-code-style/tailwind.md:
- Around line 7-10: Update the guidance in the Tailwind v4 doc block to remove
absolute prohibitions and reflect current behavior: change the bullets
referencing "No JavaScript config", "No `@layer`", "No `@apply`", and "`@theme
inline`" to pragmatic guidance that `tailwind.config.js` is optional (use
`@config` when needed), `@apply` remains supported but should be used sparingly,
`@layer` is supported with v4 behavior changes (use `@utility` for
variant-compatible utilities), and prefer a single `@theme` block but allow
exceptions; also reconcile the “Never use `!important`” rule with the DevTools
debugging snippet by adding an exception or clarifying when `!important` is
acceptable for debugging.

In @.agents/skills/review/SKILL.md:
- Line 25: The README currently points to the old path string
`.claude/skills/deus-code-style/` which was renamed; update the path reference
in .agents/skills/review/SKILL.md so the review skill looks up the new location
(replace `.claude/skills/deus-code-style/` with
`.agents/skills/deus-code-style/`), ensuring any other occurrences in that file
or nearby review text are similarly updated so lookups succeed.
- Around line 34-45: Update the broken style-guide path references inside the
SKILL.md by replacing all occurrences of ".claude/skills/deus-code-style/" with
the new ".agents/skills/deus-code-style/" so the checklist entries (e.g., the
Tailwind, performance, components, animations links) point to the renamed
directory; ensure every referenced path in SKILL.md (the listed items that
currently start with ".claude/skills/deus-code-style/") is updated to
".agents/skills/deus-code-style/" so the review skill can locate the guides.

In `@AGENTS.md`:
- Line 88: Update the broken code-style path reference in AGENTS.md by replacing
the old directory string `.claude/skills/deus-code-style/` with the new
`.agents/` directory name so the link points to the renamed location; search for
the literal `.claude/skills/deus-code-style/` in AGENTS.md and update it to
`.agents/` (or to `.agents/deus-code-style/` if the subfolder still exists) to
restore the correct link target.
- Around line 29-36: The fenced architecture diagram block in AGENTS.md is
missing a language identifier; update the opening fence for the block that
starts with "Frontend (React)" so it becomes a fenced code block with a language
hint (e.g., text or ascii) to ensure consistent rendering—i.e., change the
opening ``` to include the identifier for that diagram block.

In `@apps/backend/src/routes/workspaces.ts`:
- Around line 121-141: The code currently only console.warn when
isManifestCommandSafe(archiveCmd) rejects the archive command, so API/UI still
see success; instead, propagate a failure the same way setup rejections do by
signaling the caller: when archiveCmd is unsafe, do not merely warn—throw or
return an error (e.g., throw new Error(`Archive hook rejected for workspace
${id}: unsafe command`) or return Promise.reject(...)) so the route handler
fails, or call the existing workspace-hook failure path used by setup
(persist/emit a failure status) so the caller receives a failure signal; update
the block around isManifestCommandSafe(archiveCmd) and use the same
error-handling mechanism used for setup rejection (reference:
isManifestCommandSafe, archiveCmd, archiveProc, getDeusEnv, ws.id) to ensure the
rejection is visible to API/UI.

In `@apps/backend/src/services/manifest.service.ts`:
- Around line 279-288: The rejection branch in isManifestCommandSafe(setupCmd)
updates DB and emits progress but returns before recreating/clearing the
workspace setup log, leaving stale logs available; modify the branch so that
before returning it writes or truncates the workspace's setup log file (using
the same log path logic you use elsewhere for workspaceId/setup logs) with the
rejection reason (e.g., "Setup failed: command rejected for safety") and any
error detail, then continue to update DB and call emitProgress (or ensure the
file write happens before emitProgress) so GET /workspaces/:id/setup-logs
reflects the rejection immediately.
- Around line 87-104: The helper isManifestCommandSafe (which uses
DANGEROUS_SHELL_PATTERN) silently forbids common shell constructs while
lifecycle.setup and lifecycle.archive remain free-form strings in the manifest
schema; to fix this either (A) update the manifest schema to enforce a
restricted command form (e.g., an array of argv or a regex-limited string) and
validate lifecycle.setup/lifecycle.archive against that schema, or (B) change
runtime execution to accept an explicit argv array (spawn/execFile style)
instead of invoking sh -c so you can keep free-form strings but avoid shell
parsing; pick one approach, update the manifest validation and any callers that
use isManifestCommandSafe or command execution to match the chosen contract
(adjust isManifestCommandSafe, schema, and execution in the code paths that
handle lifecycle.setup/lifecycle.archive).

In `@apps/web/src/features/workspace/ui/WorkspaceHeader.tsx`:
- Around line 265-267: The wrapper native.apps.openIn currently discards the
boolean result from the IPC handler, so callers like WorkspaceHeader.tsx call
native.apps.openIn(...).catch(...) and run side effects unconditionally
(setLastAppId, track). Change the wrapper (function openIn in native.apps) to
return Promise<boolean> (propagate the resolved true/false from the desktop
handler) and update call sites (WorkspaceHeader.tsx, OpenInDropdown.tsx,
MainLayout.tsx) to await the boolean result and only execute side effects
(setLastAppId, track) when the result is true; keep the existing .catch handling
for rejected promises but gate success-path logic on the returned boolean.

In `@CONTRIBUTING.md`:
- Around line 34-42: The fenced code block showing the repository layout in
CONTRIBUTING.md currently has no language identifier; update the opening
triple-backtick to include a language (e.g., "text" or "bash") so markdownlint
stops flagging it and editors/previewers get proper syntax highlighting—modify
the code fence around the apps/ desktop/ web/src/ backend/ agent-server/ shared/
packages/ block to use ```text (or another appropriate language) instead of just
```.

---

Outside diff comments:
In `@apps/web/src/features/browser/ui/BrowserPanel.tsx`:
- Around line 523-536: Convert the handleToggleDevtools callback to an async
function and replace the .then()/.catch() chains with await inside a try/catch:
check activeTab?.webviewLabel early, then if activeTab.devtoolsOpen await
native.browserViews.closeDevtools(activeTab.webviewLabel) and call
handleUpdateTab(activeTab.id, { devtoolsOpen: false }) after the await,
otherwise await native.browserViews.openDevtools(activeTab.webviewLabel) and
call handleUpdateTab(activeTab.id, { devtoolsOpen: true }); on error use
handleAddLog(activeTab.id, "error", `... failed: ${err}`) in the catch block;
update the dependency array accordingly.

---

Nitpick comments:
In @.agents/skills/deus-code-style/tailwind.md:
- Around line 52-60: The guidance is contradictory: the rule "Never use
`!important`" conflicts with the debug snippet that uses `!important`; update
the tailwind.md content to mark that specific debug example ("* { outline: 1px
solid rgba(255,0,0,0.3) !important; }") as a DevTools-only, temporary exception
and clarify it should never be checked into source (add a short note after the
snippet like "DevTools-only temporary exception — do not commit"); keep the
global rule "Never use `!important`" unchanged and ensure the new note
explicitly ties the exception to debugging in DevTools.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6031bf30-59e1-4e1e-986b-a283fdb00080

📥 Commits

Reviewing files that changed from the base of the PR and between 79ac00b and a2a2382.

⛔ Files ignored due to path filters (3)
  • assets/logo.png is excluded by !**/*.png
  • bun.lock is excluded by !**/*.lock
  • packages/mcp-notebook/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (161)
  • .agents/agent-memory/code-reviewer/MEMORY.md
  • .agents/agent-memory/code-reviewer/agent-config-patterns.md
  • .agents/agent-memory/code-reviewer/analytics-patterns.md
  • .agents/agent-memory/code-reviewer/create-workspace-command-return.md
  • .agents/agent-memory/code-reviewer/feedback_over_engineering.md
  • .agents/agent-memory/code-reviewer/http-vs-ws-parity.md
  • .agents/agent-memory/code-reviewer/message-envelope-pattern.md
  • .agents/agent-memory/code-reviewer/mobile-layout-patterns.md
  • .agents/agent-memory/code-reviewer/patterns-deep.md
  • .agents/agent-memory/deep-reviewer/MEMORY.md
  • .agents/agents/code-reviewer.md
  • .agents/agents/deep-reviewer.md
  • .agents/agents/dev.md
  • .agents/commands/interrogate-eng.md
  • .agents/commands/interrogate-ux.md
  • .agents/settings.json
  • .agents/skills/commit/SKILL.md
  • .agents/skills/debug/SKILL.md
  • .agents/skills/deep-review/SKILL.md
  • .agents/skills/design-explore/SKILL.md
  • .agents/skills/deus-code-style/SKILL.md
  • .agents/skills/deus-code-style/animations.md
  • .agents/skills/deus-code-style/components.md
  • .agents/skills/deus-code-style/performance.md
  • .agents/skills/deus-code-style/tailwind.md
  • .agents/skills/dev/SKILL.md
  • .agents/skills/explore/SKILL.md
  • .agents/skills/generate-deus-json/SKILL.md
  • .agents/skills/pr/SKILL.md
  • .agents/skills/remotion-best-practices/SKILL.md
  • .agents/skills/remotion-best-practices/rules/3d.md
  • .agents/skills/remotion-best-practices/rules/animations.md
  • .agents/skills/remotion-best-practices/rules/assets.md
  • .agents/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx
  • .agents/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx
  • .agents/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx
  • .agents/skills/remotion-best-practices/rules/audio-visualization.md
  • .agents/skills/remotion-best-practices/rules/audio.md
  • .agents/skills/remotion-best-practices/rules/calculate-metadata.md
  • .agents/skills/remotion-best-practices/rules/can-decode.md
  • .agents/skills/remotion-best-practices/rules/charts.md
  • .agents/skills/remotion-best-practices/rules/compositions.md
  • .agents/skills/remotion-best-practices/rules/display-captions.md
  • .agents/skills/remotion-best-practices/rules/extract-frames.md
  • .agents/skills/remotion-best-practices/rules/ffmpeg.md
  • .agents/skills/remotion-best-practices/rules/fonts.md
  • .agents/skills/remotion-best-practices/rules/get-audio-duration.md
  • .agents/skills/remotion-best-practices/rules/get-video-dimensions.md
  • .agents/skills/remotion-best-practices/rules/get-video-duration.md
  • .agents/skills/remotion-best-practices/rules/gifs.md
  • .agents/skills/remotion-best-practices/rules/images.md
  • .agents/skills/remotion-best-practices/rules/import-srt-captions.md
  • .agents/skills/remotion-best-practices/rules/light-leaks.md
  • .agents/skills/remotion-best-practices/rules/lottie.md
  • .agents/skills/remotion-best-practices/rules/maps.md
  • .agents/skills/remotion-best-practices/rules/measuring-dom-nodes.md
  • .agents/skills/remotion-best-practices/rules/measuring-text.md
  • .agents/skills/remotion-best-practices/rules/parameters.md
  • .agents/skills/remotion-best-practices/rules/sequencing.md
  • .agents/skills/remotion-best-practices/rules/subtitles.md
  • .agents/skills/remotion-best-practices/rules/tailwind.md
  • .agents/skills/remotion-best-practices/rules/text-animations.md
  • .agents/skills/remotion-best-practices/rules/timing.md
  • .agents/skills/remotion-best-practices/rules/transcribe-captions.md
  • .agents/skills/remotion-best-practices/rules/transitions.md
  • .agents/skills/remotion-best-practices/rules/transparent-videos.md
  • .agents/skills/remotion-best-practices/rules/trimming.md
  • .agents/skills/remotion-best-practices/rules/videos.md
  • .agents/skills/review/SKILL.md
  • .agents/skills/risk-tier/SKILL.md
  • .agents/skills/test/SKILL.md
  • .claude
  • .claude/skills/emilkowal-animations
  • .claude/skills/eng-explore/SKILL.md
  • .entire/settings.json
  • .env.example
  • .hive/aquila
  • .hive/arcturus
  • .hive/centauri
  • .hive/corona
  • .hive/deimos
  • .hive/equinox
  • .storybook/main.ts
  • .storybook/preview.tsx
  • .storybook/theme-sync.tsx
  • AGENTS.md
  • CLAUDE.md
  • CLAUDE.md
  • CONTRIBUTING.md
  • LICENSE
  • README.md
  • RELEASE.md
  • apps/agent-server/agents/claude/claude-sdk-options.ts
  • apps/agent-server/agents/notebook-server.ts
  • apps/backend/src/lib/schemas.ts
  • apps/backend/src/routes/workspaces.ts
  • apps/backend/src/server.ts
  • apps/backend/src/services/manifest.service.ts
  • apps/cli/README.md
  • apps/cli/build.ts
  • apps/cli/package.json
  • apps/cli/src/desktop.ts
  • apps/cli/src/onboarding.ts
  • apps/cli/src/pair.ts
  • apps/cli/src/start.ts
  • apps/desktop/main/app-menu.ts
  • apps/desktop/main/backend-process.ts
  • apps/landing/src/components/demo/data.ts
  • apps/landing/src/components/demo/interactive-demo.tsx
  • apps/landing/src/routes/index.tsx
  • apps/web/src/app/layouts/ContentView.tsx
  • apps/web/src/app/layouts/MainContent.tsx
  • apps/web/src/app/layouts/MainLayout.tsx
  • apps/web/src/app/layouts/content-tabs.ts
  • apps/web/src/app/layouts/hooks/useWorkspaceActions.ts
  • apps/web/src/features/ai-status/ui/AIStatusIndicator.tsx
  • apps/web/src/features/auth/ui/PairGatePage.tsx
  • apps/web/src/features/browser/ui/BrowserPanel.tsx
  • apps/web/src/features/browser/ui/BrowserTab.tsx
  • apps/web/src/features/connection/ui/ConnectionBanner.tsx
  • apps/web/src/features/connection/ui/ConnectionOrb.tsx
  • apps/web/src/features/connection/ui/ServerOfflinePage.tsx
  • apps/web/src/features/notebook/index.ts
  • apps/web/src/features/notebook/ui/NotebookPanel.tsx
  • apps/web/src/features/onboarding/ui/steps/WelcomeStep.tsx
  • apps/web/src/features/repository/ui/HomeView.tsx
  • apps/web/src/features/settings/ui/sections/ExperimentalSection.tsx
  • apps/web/src/features/settings/ui/sections/GeneralSection.tsx
  • apps/web/src/features/sidebar/lib/utils.ts
  • apps/web/src/features/terminal/ui/Terminal.tsx
  • apps/web/src/features/updates/hooks/useUpdateToast.ts
  • apps/web/src/features/workspace/store/workspaceLayoutStore.ts
  • apps/web/src/features/workspace/ui/WorkspaceHeader.tsx
  • apps/web/src/platform/native/events.ts
  • apps/web/src/shared/lib/animation.ts
  • docs/agent-server-communication-refactor.md
  • docs/browser-tools-roadmap.md
  • docs/browser-tools.md
  • docs/deus-json-spec.md
  • docs/scroll-anchoring-investigation.md
  • docs/visual-effects-test.html
  • docs/workspace-tools.md
  • electron-builder.yml
  • package.json
  • packages/mcp-notebook/build.ts
  • packages/mcp-notebook/package.json
  • packages/mcp-notebook/src/__tests__/async-timeout-and-destructuring.test.ts
  • packages/mcp-notebook/src/__tests__/coderabbit-fixes.test.ts
  • packages/mcp-notebook/src/__tests__/nested-scope-bug.test.ts
  • packages/mcp-notebook/src/__tests__/vm-context-fixes.test.ts
  • packages/mcp-notebook/src/__tests__/vm-context.test.ts
  • packages/mcp-notebook/src/notebook-store.ts
  • packages/mcp-notebook/src/server.ts
  • packages/mcp-notebook/src/vm-context.ts
  • packages/mcp-notebook/tsconfig.json
  • packages/screen-studio/package.json
  • scripts/bump-version.sh
  • scripts/dev.sh
  • shared/types/settings.ts
  • test/e2e/README.md
  • test/e2e/e2e-flow.test.cjs
💤 Files with no reviewable changes (82)
  • .agents/skills/remotion-best-practices/rules/get-video-duration.md
  • .hive/arcturus
  • .hive/deimos
  • .hive/aquila
  • .hive/centauri
  • .agents/skills/remotion-best-practices/rules/lottie.md
  • .agents/skills/remotion-best-practices/rules/subtitles.md
  • apps/desktop/main/backend-process.ts
  • apps/web/src/app/layouts/content-tabs.ts
  • packages/mcp-notebook/package.json
  • packages/mcp-notebook/src/tests/nested-scope-bug.test.ts
  • .agents/skills/remotion-best-practices/rules/calculate-metadata.md
  • .agents/skills/remotion-best-practices/rules/assets.md
  • .agents/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx
  • .agents/skills/remotion-best-practices/rules/audio.md
  • .agents/skills/remotion-best-practices/rules/compositions.md
  • .agents/skills/remotion-best-practices/rules/gifs.md
  • .agents/skills/remotion-best-practices/rules/charts.md
  • .agents/skills/remotion-best-practices/rules/ffmpeg.md
  • .agents/skills/remotion-best-practices/rules/get-video-dimensions.md
  • .agents/skills/remotion-best-practices/rules/light-leaks.md
  • .agents/skills/remotion-best-practices/rules/sequencing.md
  • .agents/skills/remotion-best-practices/SKILL.md
  • .agents/skills/remotion-best-practices/rules/3d.md
  • .agents/skills/remotion-best-practices/rules/tailwind.md
  • .agents/skills/remotion-best-practices/rules/transparent-videos.md
  • .agents/skills/remotion-best-practices/rules/animations.md
  • .agents/skills/remotion-best-practices/rules/trimming.md
  • .agents/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx
  • .claude/skills/emilkowal-animations
  • .entire/settings.json
  • .hive/corona
  • .storybook/preview.tsx
  • docs/scroll-anchoring-investigation.md
  • .agents/skills/remotion-best-practices/rules/measuring-dom-nodes.md
  • shared/types/settings.ts
  • .agents/skills/remotion-best-practices/rules/maps.md
  • .agents/skills/remotion-best-practices/rules/import-srt-captions.md
  • .agents/skills/remotion-best-practices/rules/parameters.md
  • apps/backend/src/lib/schemas.ts
  • apps/backend/src/server.ts
  • .claude/skills/eng-explore/SKILL.md
  • apps/web/src/features/settings/ui/sections/ExperimentalSection.tsx
  • apps/web/src/features/notebook/index.ts
  • electron-builder.yml
  • .hive/equinox
  • apps/agent-server/agents/claude/claude-sdk-options.ts
  • .storybook/main.ts
  • .storybook/theme-sync.tsx
  • .agents/skills/remotion-best-practices/rules/display-captions.md
  • packages/mcp-notebook/tsconfig.json
  • .agents/skills/remotion-best-practices/rules/measuring-text.md
  • .agents/skills/remotion-best-practices/rules/videos.md
  • .agents/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx
  • packages/mcp-notebook/src/tests/async-timeout-and-destructuring.test.ts
  • apps/web/src/features/workspace/store/workspaceLayoutStore.ts
  • .agents/skills/remotion-best-practices/rules/audio-visualization.md
  • .agents/skills/remotion-best-practices/rules/get-audio-duration.md
  • .agents/skills/remotion-best-practices/rules/extract-frames.md
  • .agents/skills/remotion-best-practices/rules/images.md
  • .agents/skills/remotion-best-practices/rules/text-animations.md
  • .agents/skills/remotion-best-practices/rules/timing.md
  • .agents/skills/remotion-best-practices/rules/transcribe-captions.md
  • .agents/skills/remotion-best-practices/rules/transitions.md
  • docs/visual-effects-test.html
  • docs/workspace-tools.md
  • docs/browser-tools-roadmap.md
  • packages/mcp-notebook/build.ts
  • packages/mcp-notebook/src/tests/vm-context-fixes.test.ts
  • apps/agent-server/agents/notebook-server.ts
  • docs/deus-json-spec.md
  • .agents/skills/remotion-best-practices/rules/fonts.md
  • packages/mcp-notebook/src/tests/vm-context.test.ts
  • docs/browser-tools.md
  • packages/mcp-notebook/src/tests/coderabbit-fixes.test.ts
  • RELEASE.md
  • apps/web/src/features/notebook/ui/NotebookPanel.tsx
  • packages/mcp-notebook/src/server.ts
  • .agents/skills/remotion-best-practices/rules/can-decode.md
  • docs/agent-server-communication-refactor.md
  • packages/mcp-notebook/src/notebook-store.ts
  • packages/mcp-notebook/src/vm-context.ts

Comment thread .agents/skills/deus-code-style/SKILL.md Outdated
Comment on lines +7 to +10
- **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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Tailwind CSS v4 documentation: is tailwind.config.jsoptional or unsupported, and is@apply removed or still supported?

💡 Result:

In Tailwind CSS v4, the tailwind.config.js file is optional. Configuration has shifted to a CSS-first approach using the @theme directive directly in your CSS file where Tailwind is imported, eliminating the need for a separate JS config file in most cases. However, tailwind.config.js is still supported for backward compatibility via the @config directive if needed for advanced customizations like specific content paths or plugins. The @apply directive is still fully supported in Tailwind CSS v4. It allows inlining utility classes into custom CSS, with examples provided in the official documentation. In certain contexts like Vue/Svelte components or CSS modules, use @reference to access utilities. Note that Tailwind's creator recommends avoiding @apply when possible in favor of utility classes, but it remains available and functional.

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 -20

Repository: zvadaadam/deus-machine

Length of output: 1155


🌐 Web query:

Tailwind CSS v4 @layer directive: is it supported, deprecated, or removed?

💡 Result:

In Tailwind CSS v4, the @layer directive is supported as the standard native CSS cascade layers at-rule. Tailwind v4 uses native CSS cascade layers (generated output includes @layer theme, base, components, utilities;) instead of hijacking it like in v3 for special behavior such as automatic variant generation on custom styles in @layer utilities/components. You can still use @layer base, @layer components, @layer utilities in your CSS to organize custom styles into the appropriate cascade layer for correct specificity ordering. However, styles defined in @layer (utilities/components) no longer automatically receive variant support (hover:, md:, etc.). For variant-compatible custom utilities, use the new @utility directive instead. The @layer directive itself is neither deprecated nor removed; its Tailwind-specific "magic" from v3 has been replaced by native CSS behavior and new directives like @utility.

Citations:


Lines 7–10 contain inaccurate Tailwind v4 constraints that will mislead contributors.

According to official Tailwind v4 documentation:

  • tailwind.config.js is optional, not forbidden. The config file is still supported via @config directive for backward compatibility and advanced customization needs; CSS-first approach is preferred but not absolute.
  • @apply is still fully supported in v4 (not removed). The framework's creator recommends avoiding it when possible, but it remains available and functional.
  • @layer is still supported and works as native CSS cascade layers. Behavior changed from v3 (custom styles no longer auto-receive variants), but use @utility directive for variant-compatible custom utilities instead.

Additionally, there's a contradiction between line 52 ("Never use !important") and the DevTools debugging snippet on line 60, which uses !important. Clarify whether the absolute rule applies everywhere or if there are specific exceptions (like DevTools snippets).

Suggested fix: Replace absolute prohibitions with pragmatic guidance: "Prefer CSS-first config; use tailwind.config.js only when CSS cannot express the need. Avoid @apply in favor of utility classes; use @layer for organizing styles with awareness of v4 behavior changes."

🧰 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.
Context: ...apply** — use vanilla CSS instead. - **No @theme inline`** — put everything in t...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/skills/deus-code-style/tailwind.md around lines 7 - 10, Update the
guidance in the Tailwind v4 doc block to remove absolute prohibitions and
reflect current behavior: change the bullets referencing "No JavaScript config",
"No `@layer`", "No `@apply`", and "`@theme inline`" to pragmatic guidance that
`tailwind.config.js` is optional (use `@config` when needed), `@apply` remains
supported but should be used sparingly, `@layer` is supported with v4 behavior
changes (use `@utility` for variant-compatible utilities), and prefer a single
`@theme` block but allow exceptions; also reconcile the “Never use `!important`”
rule with the DevTools debugging snippet by adding an exception or clarifying
when `!important` is acceptable for debugging.

1. **Gather changes**: Run the appropriate git diff command to see what changed
2. **Read changed files**: Read the full content of each changed file for context
3. **Check CLAUDE.md compliance**: Verify changes follow the project's documented conventions
3. **Check conventions**: Read the `deus-code-style` skill files (`.claude/skills/deus-code-style/`) for detailed conventions, then verify changes comply

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Fix path reference after directory rename.

Line 25 references .claude/skills/deus-code-style/ but the PR renamed .claude/ to .agents/. This will break lookups when the review skill attempts to read the code-style documentation.

🔧 Proposed fix
-3. **Check conventions**: Read the `deus-code-style` skill files (`.claude/skills/deus-code-style/`) for detailed conventions, then verify changes comply
+3. **Check conventions**: Read the `deus-code-style` skill files (`.agents/skills/deus-code-style/`) for detailed conventions, then verify changes comply
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
3. **Check conventions**: Read the `deus-code-style` skill files (`.claude/skills/deus-code-style/`) for detailed conventions, then verify changes comply
3. **Check conventions**: Read the `deus-code-style` skill files (`.agents/skills/deus-code-style/`) for detailed conventions, then verify changes comply
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/skills/review/SKILL.md at line 25, The README currently points to
the old path string `.claude/skills/deus-code-style/` which was renamed; update
the path reference in .agents/skills/review/SKILL.md so the review skill looks
up the new location (replace `.claude/skills/deus-code-style/` with
`.agents/skills/deus-code-style/`), ensuring any other occurrences in that file
or nearby review text are similarly updated so lookups succeed.

Comment on lines +34 to +45
See `.claude/skills/deus-code-style/` for the full reference. Quick checklist:

- Bun, not npm/yarn
- Tailwind CSS v4 (no JS config, no `@apply`, no `@layer`, OKLCH colors)
- Tailwind CSS v4 (no JS config, no `@apply`, no `@layer`, OKLCH colors) — see `deus-code-style/tailwind.md`
- Zustand for UI state only, TanStack Query for server state
- `ts-pattern` for discriminated union dispatch
- No hardcoded colors — use CSS variables/tokens
- No N+1 queries — use denormalized columns or batch queries
- New query patterns must have indexes in `schema.ts`
- Components in `src/features/{feature}/ui/` by default
- New query patterns must have indexes in `schema.ts` — see `deus-code-style/performance.md`
- Components in `src/features/{feature}/ui/` by default — see `deus-code-style/components.md`
- Shadcn components are editable — check if overrides should be component edits instead
- Animation conventions (easing, CSS vs Framer Motion) — see `deus-code-style/animations.md`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Fix all code-style path references.

Lines 34, 37, 42, 43, and 45 reference .claude/skills/deus-code-style/ paths, but the directory was renamed to .agents/ per the PR objectives. These broken paths will prevent the review skill from finding the style guides.

🔧 Proposed fix
-See `.claude/skills/deus-code-style/` for the full reference. Quick checklist:
+See `.agents/skills/deus-code-style/` for the full reference. Quick checklist:

 - Bun, not npm/yarn
-- Tailwind CSS v4 (no JS config, no `@apply`, no `@layer`, OKLCH colors) — see `deus-code-style/tailwind.md`
+- Tailwind CSS v4 (no JS config, no `@apply`, no `@layer`, OKLCH colors) — see `.agents/skills/deus-code-style/tailwind.md`
 - Zustand for UI state only, TanStack Query for server state
 - `ts-pattern` for discriminated union dispatch
 - No hardcoded colors — use CSS variables/tokens
 - No N+1 queries — use denormalized columns or batch queries
-- New query patterns must have indexes in `schema.ts` — see `deus-code-style/performance.md`
-- Components in `src/features/{feature}/ui/` by default — see `deus-code-style/components.md`
+- New query patterns must have indexes in `schema.ts` — see `.agents/skills/deus-code-style/performance.md`
+- Components in `src/features/{feature}/ui/` by default — see `.agents/skills/deus-code-style/components.md`
 - Shadcn components are editable — check if overrides should be component edits instead
-- Animation conventions (easing, CSS vs Framer Motion) — see `deus-code-style/animations.md`
+- Animation conventions (easing, CSS vs Framer Motion) — see `.agents/skills/deus-code-style/animations.md`
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
See `.claude/skills/deus-code-style/` for the full reference. Quick checklist:
- Bun, not npm/yarn
- Tailwind CSS v4 (no JS config, no `@apply`, no `@layer`, OKLCH colors)
- Tailwind CSS v4 (no JS config, no `@apply`, no `@layer`, OKLCH colors) — see `deus-code-style/tailwind.md`
- Zustand for UI state only, TanStack Query for server state
- `ts-pattern` for discriminated union dispatch
- No hardcoded colors — use CSS variables/tokens
- No N+1 queries — use denormalized columns or batch queries
- New query patterns must have indexes in `schema.ts`
- Components in `src/features/{feature}/ui/` by default
- New query patterns must have indexes in `schema.ts` — see `deus-code-style/performance.md`
- Components in `src/features/{feature}/ui/` by default — see `deus-code-style/components.md`
- Shadcn components are editable — check if overrides should be component edits instead
- Animation conventions (easing, CSS vs Framer Motion) — see `deus-code-style/animations.md`
See `.agents/skills/deus-code-style/` for the full reference. Quick checklist:
- Bun, not npm/yarn
- Tailwind CSS v4 (no JS config, no `@apply`, no `@layer`, OKLCH colors) — see `.agents/skills/deus-code-style/tailwind.md`
- Zustand for UI state only, TanStack Query for server state
- `ts-pattern` for discriminated union dispatch
- No hardcoded colors — use CSS variables/tokens
- No N+1 queries — use denormalized columns or batch queries
- New query patterns must have indexes in `schema.ts` — see `.agents/skills/deus-code-style/performance.md`
- Components in `src/features/{feature}/ui/` by default — see `.agents/skills/deus-code-style/components.md`
- Shadcn components are editable — check if overrides should be component edits instead
- Animation conventions (easing, CSS vs Framer Motion) — see `.agents/skills/deus-code-style/animations.md`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/skills/review/SKILL.md around lines 34 - 45, Update the broken
style-guide path references inside the SKILL.md by replacing all occurrences of
".claude/skills/deus-code-style/" with the new ".agents/skills/deus-code-style/"
so the checklist entries (e.g., the Tailwind, performance, components,
animations links) point to the renamed directory; ensure every referenced path
in SKILL.md (the listed items that currently start with
".claude/skills/deus-code-style/") is updated to
".agents/skills/deus-code-style/" so the review skill can locate the guides.

Comment thread AGENTS.md Outdated
Comment on lines +121 to +141
if (!isManifestCommandSafe(archiveCmd)) {
console.warn(
`[MANIFEST] Rejected unsafe archive command for workspace ${id}: ${archiveCmd}`
);
} else {
const archiveEnv = getDeusEnv(manifest!, {
id: ws.id,
rootPath: ws.root_path,
workspacePath: wsPath,
});
const archiveProc = spawn("sh", ["-c", archiveCmd], {
cwd: wsPath,
env: { ...process.env, ...archiveEnv },
stdio: "ignore",
detached: false,
});
archiveProc.on("error", (err) => {
console.error(`Archive hook error for workspace ${id}:`, err.message);
});
archiveProc.unref();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Archive hook rejection never reaches the caller.

When archiveCmd is blocked, this only writes a server warning and still returns a successful archive response. That makes “archive hook skipped for safety” indistinguishable from “archive hook ran successfully” for the UI and API consumers. Please persist or emit a failure signal here the same way setup rejection does.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/backend/src/routes/workspaces.ts` around lines 121 - 141, The code
currently only console.warn when isManifestCommandSafe(archiveCmd) rejects the
archive command, so API/UI still see success; instead, propagate a failure the
same way setup rejections do by signaling the caller: when archiveCmd is unsafe,
do not merely warn—throw or return an error (e.g., throw new Error(`Archive hook
rejected for workspace ${id}: unsafe command`) or return Promise.reject(...)) so
the route handler fails, or call the existing workspace-hook failure path used
by setup (persist/emit a failure status) so the caller receives a failure
signal; update the block around isManifestCommandSafe(archiveCmd) and use the
same error-handling mechanism used for setup rejection (reference:
isManifestCommandSafe, archiveCmd, archiveProc, getDeusEnv, ws.id) to ensure the
rejection is visible to API/UI.

Comment on lines +87 to +104
/**
* Dangerous shell metacharacters that indicate command injection.
* We allow simple commands like `bun install` or `npm run build` but reject
* anything that chains, pipes, substitutes, or redirects — these have no
* legitimate use in a deus.json lifecycle/setup command.
*/
const DANGEROUS_SHELL_PATTERN = /[;|&`$><\n]|\$\(|\)\s*\{/;

/**
* Validate a manifest command string for dangerous shell metacharacters.
* Returns true if the command is safe to execute, false otherwise.
*
* Rejects: ; && || | $() `` > < \n and other shell injection vectors.
* Allows: simple commands with flags and arguments (e.g. "bun install", "cargo build --release").
*/
export function isManifestCommandSafe(cmd: string): boolean {
return !DANGEROUS_SHELL_PATTERN.test(cmd);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
python - <<'PY'
from pathlib import Path
import json
import re

pattern = re.compile(r'[;|&`$><\n]|\$\(|\)\s*\{')
fields = [
    ("lifecycle", "setup"),
    ("lifecycle", "archive"),
    ("scripts", "setup"),
    ("scripts", "archive"),
]

def get_field(obj, keys):
    cur = obj
    for key in keys:
        if not isinstance(cur, dict) or key not in cur:
            return None
        cur = cur[key]
    return cur

for path in Path(".").rglob("deus.json"):
    try:
        data = json.loads(path.read_text())
    except Exception:
        continue

    for field in fields:
        value = get_field(data, field)
        if isinstance(value, str) and pattern.search(value):
            print(f"{path}: {'.'.join(field)} -> {value}")
PY

Repository: zvadaadam/deus-machine

Length of output: 48


🏁 Script executed:

# Find all usages of isManifestCommandSafe to understand where it's being enforced
rg "isManifestCommandSafe" -n

Repository: zvadaadam/deus-machine

Length of output: 431


🏁 Script executed:

# Check the implementation around the mentioned lines to see the execution flow
sed -n '75,105p' apps/backend/src/services/manifest.service.ts

Repository: zvadaadam/deus-machine

Length of output: 1145


🏁 Script executed:

# Check lines 279-288 and 293-297 where the function is used
sed -n '270,305p' apps/backend/src/services/manifest.service.ts

Repository: zvadaadam/deus-machine

Length of output: 1285


🏁 Script executed:

# Look for any schema definitions that might constrain manifest commands
find . -type f \( -name "*.ts" -o -name "*.json" \) | xargs grep -l "lifecycle.*setup\|manifest.*schema" | head -20

Repository: zvadaadam/deus-machine

Length of output: 289


Schema allows free-form shell commands, but isManifestCommandSafe rejects common patterns without schema enforcement.

lifecycle.setup and lifecycle.archive remain modeled as free-form strings in the manifest schema, but this helper rejects commands using &&, ||, pipes, redirection, or variable expansion. While the current repository has no existing manifests that would fail (verified via scanning all deus.json files), the implementation silently diverges from what the schema advertises. If the intent is to restrict commands to simple argv patterns, either enforce that in the schema validation or consider spawning with an explicit argv array instead of sh -c.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/backend/src/services/manifest.service.ts` around lines 87 - 104, The
helper isManifestCommandSafe (which uses DANGEROUS_SHELL_PATTERN) silently
forbids common shell constructs while lifecycle.setup and lifecycle.archive
remain free-form strings in the manifest schema; to fix this either (A) update
the manifest schema to enforce a restricted command form (e.g., an array of argv
or a regex-limited string) and validate lifecycle.setup/lifecycle.archive
against that schema, or (B) change runtime execution to accept an explicit argv
array (spawn/execFile style) instead of invoking sh -c so you can keep free-form
strings but avoid shell parsing; pick one approach, update the manifest
validation and any callers that use isManifestCommandSafe or command execution
to match the chosen contract (adjust isManifestCommandSafe, schema, and
execution in the code paths that handle lifecycle.setup/lifecycle.archive).

Comment on lines +279 to +288
if (!isManifestCommandSafe(setupCmd)) {
console.warn(
`[MANIFEST] Rejected unsafe setup command for workspace ${workspaceId}: ${setupCmd}`
);
db.prepare(
"UPDATE workspaces SET setup_status = 'failed', error_message = ?, updated_at = datetime('now') WHERE id = ?"
).run("Setup command rejected: contains dangerous shell metacharacters", workspaceId);
emitProgress(workspaceId, "setup_failed", "Setup failed: command rejected for safety");
return;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Rejected setup attempts can leave stale logs behind.

This returns before the setup log file is recreated. After a retry, GET /workspaces/:id/setup-logs can still serve output from the previous attempt instead of the current rejection reason.

🧹 Suggested fix
 export function runSetupScript(
   db: BetterSqlite3.Database,
   workspaceId: string,
   setupCmd: string,
   setupEnv: Record<string, string>,
   workspacePath: string
 ): void {
+  const setupLogPath = path.join(os.tmpdir(), `deus-${workspaceId}-setup.log`);
+
   if (!isManifestCommandSafe(setupCmd)) {
+    try {
+      fs.writeFileSync(
+        setupLogPath,
+        "Setup command rejected: contains dangerous shell metacharacters\n",
+        "utf8"
+      );
+    } catch {}
     console.warn(
       `[MANIFEST] Rejected unsafe setup command for workspace ${workspaceId}: ${setupCmd}`
     );
     db.prepare(
       "UPDATE workspaces SET setup_status = 'failed', error_message = ?, updated_at = datetime('now') WHERE id = ?"
@@
-  const setupLogPath = path.join(os.tmpdir(), `deus-${workspaceId}-setup.log`);
   const setupLog = fs.createWriteStream(setupLogPath);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/backend/src/services/manifest.service.ts` around lines 279 - 288, The
rejection branch in isManifestCommandSafe(setupCmd) updates DB and emits
progress but returns before recreating/clearing the workspace setup log, leaving
stale logs available; modify the branch so that before returning it writes or
truncates the workspace's setup log file (using the same log path logic you use
elsewhere for workspaceId/setup logs) with the rejection reason (e.g., "Setup
failed: command rejected for safety") and any error detail, then continue to
update DB and call emitProgress (or ensure the file write happens before
emitProgress) so GET /workspaces/:id/setup-logs reflects the rejection
immediately.

Comment on lines +265 to +267
native.apps.openIn(appId, workspacePath).catch((err) => {
console.warn("[WorkspaceHeader] Failed to open in app:", err);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== renderer wrapper =="
rg -n -C3 'export async function openIn|invoke\("open_in_app"' apps/web/src/platform/native/apps.ts

echo
echo "== main-process handler =="
rg -n -C4 'ipcMain\.handle\(\s*"open_in_app"|return false|return true' apps/desktop/main/native-handlers.ts

echo
echo "== call sites that assume rejection-only failure =="
rg -n -C2 'native\.apps\.openIn\(.+\)\.catch' apps/web/src

Repository: zvadaadam/deus-machine

Length of output: 2974


openIn failures can still be treated as success—callers don't handle resolved false outcomes.

The openIn wrapper at apps/web/src/platform/native/apps.ts discards the boolean return value from the IPC handler, returning Promise<void> instead. Meanwhile, the handler at apps/desktop/main/native-handlers.ts explicitly returns false on failure (app not found, execution error) and true on success. Because callers use .catch(), which only handles rejected Promises, they miss the resolved-false case entirely. At lines 263–264 in this file, setLastAppId and track execute before and regardless of whether the app actually opened.

This affects at least three call sites: WorkspaceHeader.tsx:265, OpenInDropdown.tsx:60, and MainLayout.tsx:358.

💡 Suggested fix (return boolean from wrapper and gate side effects)
-  function handleOpenInApp(appId: string) {
+  async function handleOpenInApp(appId: string) {
     setOpen(false);
-    setLastAppId(appId);
-    track("open_in_app", { app_id: appId });
-    native.apps.openIn(appId, workspacePath).catch((err) => {
-      console.warn("[WorkspaceHeader] Failed to open in app:", err);
-    });
+    try {
+      const opened = await native.apps.openIn(appId, workspacePath);
+      if (!opened) {
+        console.warn("[WorkspaceHeader] Failed to open in app: native returned false");
+        return;
+      }
+      setLastAppId(appId);
+      track("open_in_app", { app_id: appId });
+    } catch (err) {
+      console.warn("[WorkspaceHeader] Failed to open in app:", err);
+    }
   }
- export async function openIn(appId: string, workspacePath: string): Promise<void> {
-   if (!capabilities.openInExternalApp) return;
-   await invoke("open_in_app", { appId, workspacePath });
+ export async function openIn(appId: string, workspacePath: string): Promise<boolean> {
+   if (!capabilities.openInExternalApp) return false;
+   return Boolean(await invoke<boolean>("open_in_app", { appId, workspacePath }));
  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/features/workspace/ui/WorkspaceHeader.tsx` around lines 265 -
267, The wrapper native.apps.openIn currently discards the boolean result from
the IPC handler, so callers like WorkspaceHeader.tsx call
native.apps.openIn(...).catch(...) and run side effects unconditionally
(setLastAppId, track). Change the wrapper (function openIn in native.apps) to
return Promise<boolean> (propagate the resolved true/false from the desktop
handler) and update call sites (WorkspaceHeader.tsx, OpenInDropdown.tsx,
MainLayout.tsx) to await the boolean result and only execute side effects
(setLastAppId, track) when the result is true; keep the existing .catch handling
for rejected promises but gate success-path logic on the returned boolean.

Comment thread CONTRIBUTING.md Outdated
zvadaadam and others added 2 commits April 4, 2026 07:25
- Remove eslint-plugin-storybook import (storybook was deleted)
- Add storybook stories and PixelGrid to knip ignoreFiles
- Add @napi-rs/canvas and sharp to knip ignoreDependencies
- Fix prettier formatting in content-tabs.ts
- Clean up stale knip config (remove packages/** ignore, redundant entry)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add `text` language hint to unlabeled code fences in AGENTS.md,
CONTRIBUTING.md, and deus-code-style/SKILL.md to satisfy MD040 lint.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
knip.json (1)

3-20: ⚠️ Potential issue | 🟠 Major

Add apps/cli/build.ts to Knip entry to prevent false-positive unused-file warnings.

apps/cli/build.ts is executed via the build script in apps/cli/package.json ("build": "bunx tsx build.ts"). With rules.files set to "error", the file must be listed in entry to avoid incorrectly flagging it as unused.

Proposed fix
   "entry": [
     "apps/backend/src/server.ts",
     "apps/agent-server/index.ts",
     "apps/desktop/main/index.ts",
     "apps/desktop/preload/index.ts",
     "apps/desktop/preload/browser-preload.ts",
     "shared/types/index.ts",
     "shared/events.ts",
     "shared/agent-events.ts",
     "shared/protocol.ts",
     "shared/schema.ts",
     "shared/session-events.ts",
     "shared/enums.ts",
     "shared/lib/*.ts",
     "apps/cli/src/cli.ts",
+    "apps/cli/build.ts",
     "apps/**/test/**/*.ts",
     "test/**/*.ts"
   ],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@knip.json` around lines 3 - 20, The knip configuration's "entry" array is
missing the CLI build script causing false-positive unused-file warnings; add
the string "apps/cli/build.ts" to the "entry" array in knip.json (alongside
existing entries like "apps/cli/src/cli.ts") so Knip recognizes the build.ts as
an entry point and stops flagging it as unused.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@knip.json`:
- Around line 3-20: The knip configuration's "entry" array is missing the CLI
build script causing false-positive unused-file warnings; add the string
"apps/cli/build.ts" to the "entry" array in knip.json (alongside existing
entries like "apps/cli/src/cli.ts") so Knip recognizes the build.ts as an entry
point and stops flagging it as unused.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 350d8012-8bb6-48e3-9544-a73368a884aa

📥 Commits

Reviewing files that changed from the base of the PR and between a2a2382 and a018a29.

📒 Files selected for processing (3)
  • apps/web/src/app/layouts/content-tabs.ts
  • eslint.config.mjs
  • knip.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/src/app/layouts/content-tabs.ts

- Add safeFit() wrapper that catches xterm's "dimensions" error during
  rapid mount/unmount cycles when render service isn't initialized
- Use stable EMPTY_TABS constant instead of inline `?? []` to prevent
  Zustand selector from creating new array references every render

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/web/src/features/terminal/ui/Terminal.tsx (1)

224-226: Consider debug logging for unexpected kill failures.

While the comment documents the expected "PTY already dead" scenario, this catch also silently swallows unexpected errors (e.g., backend connectivity issues, system errors). During cleanup this is typically acceptable, but completely silent failures can make debugging harder in development.

🔧 Optional: Add debug-level logging for unexpected errors
       ptyCommands.kill(ptyId).catch(() => {
-        /* Expected: PTY process may already be dead or cleaned up */
+        // Expected: PTY process may already be dead or cleaned up.
+        // Silently ignore — no recovery action possible during teardown.
       });

Alternatively, if you have a debug logger:

ptyCommands.kill(ptyId).catch((err) => {
  // Expected: PTY may already be dead. Log at debug level for visibility.
  if (import.meta.env.DEV) console.debug(`PTY ${ptyId} kill failed (expected during cleanup):`, err);
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/features/terminal/ui/Terminal.tsx` around lines 224 - 226, The
catch on ptyCommands.kill(ptyId) silently swallows all errors; update the catch
to log unexpected failures at debug level during development so genuine issues
(e.g., backend connectivity) are visible while still tolerating "PTY already
dead" cases. Modify the promise chain around ptyCommands.kill in Terminal.tsx to
inspect the caught error and, when in dev (import.meta.env.DEV) or using the
app's debug logger, output a debug message including ptyId and the error; keep
the existing behavior of not throwing so cleanup remains safe.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/web/src/features/terminal/ui/Terminal.tsx`:
- Around line 224-226: The catch on ptyCommands.kill(ptyId) silently swallows
all errors; update the catch to log unexpected failures at debug level during
development so genuine issues (e.g., backend connectivity) are visible while
still tolerating "PTY already dead" cases. Modify the promise chain around
ptyCommands.kill in Terminal.tsx to inspect the caught error and, when in dev
(import.meta.env.DEV) or using the app's debug logger, output a debug message
including ptyId and the error; keep the existing behavior of not throwing so
cleanup remains safe.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f4d3efc3-1630-4219-93d5-d3e3360c72af

📥 Commits

Reviewing files that changed from the base of the PR and between 47d9a7f and 567c88c.

📒 Files selected for processing (2)
  • apps/web/src/features/terminal/ui/Terminal.tsx
  • apps/web/src/features/terminal/ui/TerminalPanel.tsx
✅ Files skipped from review due to trivial changes (1)
  • apps/web/src/features/terminal/ui/TerminalPanel.tsx

Storybook was removed but .stories.tsx files were left behind, causing
TS2307 errors for @storybook/react-vite. Delete all 9 story files and
clean up knip config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@zvadaadam zvadaadam merged commit e0be0d2 into main Apr 4, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant