diff --git a/plugins/claude/skills/new_user/SKILL.md b/plugins/claude/skills/new_user/SKILL.md index 0efe2ddb..2a4ccd50 100644 --- a/plugins/claude/skills/new_user/SKILL.md +++ b/plugins/claude/skills/new_user/SKILL.md @@ -10,15 +10,65 @@ Guide a new user through what DeepWork can do and help them get started. ## Flow -### 0. Run setup +### 0. Check dependencies and run setup -Before anything else, run the setup command to ensure the user's environment is configured: +#### 0a. Check for `uv` + +The DeepWork MCP server requires `uv` (specifically `uvx`). Check if it is installed: + +```bash +command -v uv +``` + +**If `uv` is NOT found**, install it: + +- On macOS/Linux: + ```bash + curl -LsSf https://astral.sh/uv/install.sh | sh + ``` +- On Windows (PowerShell): + ```powershell + powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" + ``` + +After installing, verify it works: +```bash +uv --version +``` + +If `uv` was just installed, set `UV_WAS_INSTALLED=true` (you will need this later). + +#### 0b. Reload if `uv` was just installed + +If `UV_WAS_INSTALLED=true` (from step 0a), the MCP server could not have started when this session began because `uvx` was missing. Use `AskUserQuestion` to tell the user: + +> I just installed `uv`, which DeepWork's MCP server needs to run. For everything to work, please type `/reload-plugins` now, then come back and tell me it's done. + +Wait for the user to confirm they have reloaded. Do not proceed until they confirm. + +#### 0c. Run setup + +Run the setup command to configure Claude Code settings (marketplace, plugin, MCP permissions, auto-update): ```bash uvx deepwork setup ``` -This configures Claude Code settings (marketplace, plugin, MCP permissions, auto-update). Proceed regardless of the output. +Proceed regardless of the output. + +#### 0d. Verify the MCP server is running + +Call `get_workflows` (using the `mcp__plugin_deepwork_deepwork__get_workflows` tool). If it succeeds, the server is healthy — continue. If it errors, tell the user: + +> The DeepWork MCP server isn't responding. This usually means `uv` isn't on your PATH or the plugin needs a restart. Try quitting Claude Code completely and reopening it, then run `/deepwork:new_user` again. + +Stop the onboarding if the server is not reachable — continuing without it will just produce more confusing errors. + +#### 0e. macOS note (macOS only) + +If the platform is macOS, briefly mention: + +> **Heads up**: during reviews or workflows that scan files, macOS may pop up permission dialogs for Photos, Dropbox, or other locations outside this project. These are safe to **deny** — DeepWork only needs access to your project directory and the review will still complete fine. ### 1. GitHub star (optional) diff --git a/src/deepwork/setup/claude.py b/src/deepwork/setup/claude.py index 9ad74c9e..974bf42c 100644 --- a/src/deepwork/setup/claude.py +++ b/src/deepwork/setup/claude.py @@ -11,14 +11,20 @@ "repo": "Unsupervisedcom/deepwork", } PLUGIN_KEY = "deepwork@deepwork-plugins" -MCP_PERMISSION = "mcp__plugin_deepwork_deepwork__*" -# Permissions granting full access to .deepwork/ in every project. -# Leading slash makes the path project-root-relative (per Claude Code docs), -# so these rules apply to `.deepwork/**/*` in each project, not `~/.deepwork/`. -DEEPWORK_DIR_PERMISSIONS = [ +# All permissions to add to settings.permissions.allow. +ALLOW_PERMISSIONS = [ + # MCP tools + "mcp__plugin_deepwork_deepwork__*", + # .deepwork/ directory access (leading slash = project-root-relative) "Read(/.deepwork/**/*)", "Write(/.deepwork/**/*)", "Edit(/.deepwork/**/*)", + # Bash commands the plugin routinely runs (uv cache glob covers hash-varying paths) + "Bash(deepwork:*)", + "Bash(uvx deepwork:*)", + "Bash(~/.cache/uv/archive-v0/*/bin/deepwork:*)", + "Bash(command -v uv)", + "Bash(uv --version)", ] @@ -65,15 +71,10 @@ def claude_setup() -> list[str]: enabled_plugins[PLUGIN_KEY] = True changes.append(f"Enabled plugin '{PLUGIN_KEY}'") - # 3. Ensure MCP tool permission is in allow list + # 3. Ensure all required permissions are in allow list permissions = settings.setdefault("permissions", {}) allow = permissions.setdefault("allow", []) - if MCP_PERMISSION not in allow: - allow.append(MCP_PERMISSION) - changes.append(f"Added '{MCP_PERMISSION}' to permissions.allow") - - # 4. Ensure full access to .deepwork/ in every project - for perm in DEEPWORK_DIR_PERMISSIONS: + for perm in ALLOW_PERMISSIONS: if perm not in allow: allow.append(perm) changes.append(f"Added '{perm}' to permissions.allow") diff --git a/tests/unit/test_setup.py b/tests/unit/test_setup.py index c9ce2b55..1eb1447d 100644 --- a/tests/unit/test_setup.py +++ b/tests/unit/test_setup.py @@ -11,9 +11,8 @@ from deepwork.cli.main import cli from deepwork.setup.claude import ( - DEEPWORK_DIR_PERMISSIONS, + ALLOW_PERMISSIONS, MARKETPLACE_KEY, - MCP_PERMISSION, PLUGIN_KEY, claude_setup, ) @@ -40,7 +39,8 @@ class TestClaudeSetupFreshFile: # YOU MUST NOT MODIFY THIS TEST UNLESS THE REQUIREMENT CHANGES def test_creates_settings(self, claude_home: Path) -> None: changes = claude_setup() - assert len(changes) == 6 + # 1 marketplace + 1 plugin + len(ALLOW_PERMISSIONS) permissions + assert len(changes) == 2 + len(ALLOW_PERMISSIONS) settings = _read_settings(claude_home) # marketplace registered @@ -53,11 +53,8 @@ def test_creates_settings(self, claude_home: Path) -> None: # plugin enabled assert settings["enabledPlugins"][PLUGIN_KEY] is True - # MCP permission - assert MCP_PERMISSION in settings["permissions"]["allow"] - - # .deepwork directory permissions (project-relative via leading slash) - for perm in DEEPWORK_DIR_PERMISSIONS: + # all permissions present + for perm in ALLOW_PERMISSIONS: assert perm in settings["permissions"]["allow"] @@ -103,7 +100,7 @@ def test_creates_claude_dir(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatc monkeypatch.setattr(Path, "home", staticmethod(lambda: fake_home)) changes = claude_setup() - assert len(changes) == 6 + assert len(changes) == 2 + len(ALLOW_PERMISSIONS) assert (fake_home / ".claude" / "settings.json").exists()