From 529f819b0fc3837f7fa313e97313d0f8cc41c3d8 Mon Sep 17 00:00:00 2001 From: defiQUG Date: Sat, 25 Apr 2026 12:42:36 -0700 Subject: [PATCH] chore: add shared devin workspace tooling --- .devin/README.md | 18 +++++++++++ .devin/agents/reviewer/AGENT.md | 21 +++++++++++++ .devin/config.json | 38 ++++++++++++++++++++++++ .devin/hooks.v1.json | 14 +++++++++ .devin/skills/cursor-handoff/SKILL.md | 22 ++++++++++++++ .devin/skills/review/SKILL.md | 28 +++++++++++++++++ .gitignore | 3 ++ scripts/devin/block-dangerous-command.sh | 31 +++++++++++++++++++ 8 files changed, 175 insertions(+) create mode 100644 .devin/README.md create mode 100644 .devin/agents/reviewer/AGENT.md create mode 100644 .devin/config.json create mode 100644 .devin/hooks.v1.json create mode 100644 .devin/skills/cursor-handoff/SKILL.md create mode 100644 .devin/skills/review/SKILL.md create mode 100755 scripts/devin/block-dangerous-command.sh diff --git a/.devin/README.md b/.devin/README.md new file mode 100644 index 00000000..84e6cb7e --- /dev/null +++ b/.devin/README.md @@ -0,0 +1,18 @@ +# Devin for Terminal in Cursor + +This project is configured to use Devin for Terminal as a local CLI companion inside Cursor. + +- Cursor config import is enabled through `.cursor/rules/` and `.cursor/mcp.json` if present. +- Windsurf config import is disabled for this project. +- `AGENTS.md` remains the canonical shared project guidance. +- Personal Devin overrides and secrets belong in `.devin/config.local.json`, which is gitignored. +- Run `devin auth login` interactively before first use. + +Useful commands: + +```bash +devin +devin -- "review this repo and suggest the next safe task" +devin auth status +devin mcp list +``` diff --git a/.devin/agents/reviewer/AGENT.md b/.devin/agents/reviewer/AGENT.md new file mode 100644 index 00000000..02e38486 --- /dev/null +++ b/.devin/agents/reviewer/AGENT.md @@ -0,0 +1,21 @@ +--- +name: reviewer +description: Read-only reviewer for Cursor/Devin handoffs +allowed-tools: + - read + - grep + - glob + - exec +permissions: + allow: + - Exec(git status) + - Exec(git diff) + - Exec(git log) + deny: + - write + - edit +--- + +You are a read-only review subagent for this Cursor workspace. + +Review changes for correctness, security, operational risk, and consistency with `AGENTS.md` and relevant `.cursor/rules/` guidance. Do not modify files. Report only actionable findings first, ordered by severity, with exact file paths. diff --git a/.devin/config.json b/.devin/config.json new file mode 100644 index 00000000..3677315f --- /dev/null +++ b/.devin/config.json @@ -0,0 +1,38 @@ +{ + // Devin for Terminal project config optimized for Cursor as the primary IDE. + "read_config_from": { + "cursor": true, + "windsurf": false, + "claude": true + }, + "permissions": { + "allow": [ + "Read(**)", + "Exec(git status)", + "Exec(git diff)", + "Exec(git log)", + "Exec(pnpm run)", + "Exec(bash scripts/verify)", + "Exec(bash scripts/validation)" + ], + "ask": [ + "Write(**)", + "Exec(git commit)", + "Exec(git push)", + "Exec(docker)", + "Exec(docker compose)", + "mcp__*" + ], + "deny": [ + "Exec(rm)", + "Exec(sudo)", + "Exec(chmod -R)", + "Exec(chown -R)", + "Write(.env*)", + "Write(**/.env*)", + "Write(reports/secrets/**)", + "Write(config/production/*did-secrets.env)" + ] + }, + "mcpServers": {} +} diff --git a/.devin/hooks.v1.json b/.devin/hooks.v1.json new file mode 100644 index 00000000..1c10644b --- /dev/null +++ b/.devin/hooks.v1.json @@ -0,0 +1,14 @@ +{ + "PreToolUse": [ + { + "matcher": "exec", + "hooks": [ + { + "type": "command", + "command": "bash scripts/devin/block-dangerous-command.sh", + "timeout": 10 + } + ] + } + ] +} diff --git a/.devin/skills/cursor-handoff/SKILL.md b/.devin/skills/cursor-handoff/SKILL.md new file mode 100644 index 00000000..fe55a41d --- /dev/null +++ b/.devin/skills/cursor-handoff/SKILL.md @@ -0,0 +1,22 @@ +--- +name: cursor-handoff +description: Align Devin for Terminal work with this Cursor workspace and project rules +allowed-tools: + - read + - grep + - glob + - exec +triggers: + - user + - model +--- + +Use this skill when starting or resuming work in this repository from Devin for Terminal. + +1. Treat Cursor as the primary IDE context and read `.cursor/rules/` when relevant. +2. Read `AGENTS.md` first for canonical project guidance. +3. Do not rely on Windsurf rules, skills, workflows, or MCP settings for this project. +4. Check `git status --short` before editing and preserve unrelated user changes. +5. Prefer dry-run flags for operator, deployment, DNS, Proxmox, and LAN-sensitive scripts. +6. Never write secrets or runtime credentials into tracked files. +7. When using MCP servers, assume Cursor and Devin maintain separate authentication sessions. diff --git a/.devin/skills/review/SKILL.md b/.devin/skills/review/SKILL.md new file mode 100644 index 00000000..57e1359e --- /dev/null +++ b/.devin/skills/review/SKILL.md @@ -0,0 +1,28 @@ +--- +name: review +description: Review code changes before commit or handoff +allowed-tools: + - read + - grep + - glob + - exec +permissions: + allow: + - Exec(git status) + - Exec(git diff) + - Exec(git log) + deny: + - write + - edit +triggers: + - user + - model +--- + +Review the current changes with a correctness-first stance. + +1. Run `git status --short`. +2. Run `git diff` and, if staged changes exist, `git diff --staged`. +3. Focus on bugs, security regressions, deployment risk, missing validation, and secret exposure. +4. Cite exact file paths and keep findings ordered by severity. +5. If no issues are found, say so and call out any test or validation gaps. diff --git a/.gitignore b/.gitignore index 3f393eaf..0c0a6b49 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,9 @@ Thumbs.db # Local-only Cursor session / context (exclude from Gitea) .cursor/local/ +# Devin for Terminal personal overrides / secrets +.devin/config.local.json + # IDE files .vscode/ .idea/ diff --git a/scripts/devin/block-dangerous-command.sh b/scripts/devin/block-dangerous-command.sh new file mode 100755 index 00000000..e8269795 --- /dev/null +++ b/scripts/devin/block-dangerous-command.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +set -euo pipefail + +payload_json="$(cat)" + +PAYLOAD_JSON="$payload_json" python3 - <<'PY' +import json +import os +import re +import sys + +payload = json.loads(os.environ.get("PAYLOAD_JSON", "{}")) +command = str(payload.get("tool_input", {}).get("command", "")).strip() + +blocked = [ + (r"(^|\s)rm\s+-[^;&|]*[rf]", "Recursive or forced removal must be reviewed manually."), + (r"(^|\s)sudo(\s|$)", "sudo is blocked for Devin sessions in this workspace."), + (r"(^|\s)git\s+reset\s+--hard(\s|$)", "Hard resets can discard user work."), + (r"(^|\s)git\s+checkout\s+--(\s|$)", "Checkout restore can discard user work."), + (r"(^|\s)git\s+clean(\s|$)", "git clean can delete untracked user work."), + (r"(^|\s)chmod\s+-R(\s|$)", "Recursive chmod is too broad for an automated hook."), + (r"(^|\s)chown\s+-R(\s|$)", "Recursive chown is too broad for an automated hook."), +] + +for pattern, reason in blocked: + if re.search(pattern, command): + print(json.dumps({"decision": "block", "reason": reason})) + sys.exit(2) + +sys.exit(0) +PY