@securityreviewai/securityreview-kit 0.1.47 → 0.1.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/api.js +44 -0
  2. package/dist/commands/guardrails.js +13 -0
  3. package/dist/commands/init.js +88 -0
  4. package/dist/commands/profile.js +14 -0
  5. package/dist/commands/status.js +27 -0
  6. package/dist/commands/sync.js +6 -0
  7. package/dist/config.js +18 -0
  8. package/dist/fs.js +43 -0
  9. package/dist/index.js +44 -0
  10. package/dist/profile.js +113 -0
  11. package/dist/scaffold/claude-code.js +37 -0
  12. package/dist/scaffold/codex.js +35 -0
  13. package/dist/scaffold/cursor.js +39 -0
  14. package/dist/scaffold/gemini.js +10 -0
  15. package/dist/scaffold/index.js +22 -0
  16. package/dist/scaffold/mcp.js +15 -0
  17. package/dist/scaffold/rules.js +165 -0
  18. package/dist/scaffold/vibreview.js +24 -0
  19. package/dist/scaffold/vscode.js +22 -0
  20. package/dist/scaffold/windsurf.js +10 -0
  21. package/dist/sync/index.js +34 -0
  22. package/dist/sync/payload.js +23 -0
  23. package/dist/sync/state.js +12 -0
  24. package/dist/types.js +1 -0
  25. package/package.json +24 -30
  26. package/templates/claude/CLAUDE.md +13 -0
  27. package/templates/claude/agents/guardrail_profiler.md +12 -0
  28. package/templates/claude/agents/threat_modeler.md +5 -0
  29. package/templates/claude/skills/vibreview/SKILL.md +21 -0
  30. package/templates/claude/skills/vibreview/guardrail_patterns.md +12 -0
  31. package/templates/cursor/rules/vibreview-security.mdc +8 -0
  32. package/README.md +0 -105
  33. package/bin/securityreview-kit.js +0 -5
  34. package/src/cli.js +0 -109
  35. package/src/commands/init.js +0 -851
  36. package/src/commands/status.js +0 -99
  37. package/src/commands/switch-project.js +0 -207
  38. package/src/generators/mcp/claude.js +0 -85
  39. package/src/generators/mcp/claude.test.js +0 -64
  40. package/src/generators/mcp/codex.js +0 -70
  41. package/src/generators/mcp/codex.test.js +0 -43
  42. package/src/generators/mcp/cursor.js +0 -29
  43. package/src/generators/mcp/cursor.test.js +0 -50
  44. package/src/generators/mcp/gemini.js +0 -28
  45. package/src/generators/mcp/vscode.js +0 -48
  46. package/src/generators/mcp/vscode.test.js +0 -21
  47. package/src/generators/mcp/windsurf.js +0 -27
  48. package/src/generators/rules/antigravity.js +0 -22
  49. package/src/generators/rules/claude.js +0 -87
  50. package/src/generators/rules/claude.test.js +0 -60
  51. package/src/generators/rules/codex.js +0 -141
  52. package/src/generators/rules/codex.test.js +0 -59
  53. package/src/generators/rules/content.js +0 -110
  54. package/src/generators/rules/content.md +0 -57
  55. package/src/generators/rules/cursor.js +0 -128
  56. package/src/generators/rules/gemini.js +0 -13
  57. package/src/generators/rules/guardrails-init-profile.md +0 -56
  58. package/src/generators/rules/guardrails-profiler/SKILL.md +0 -130
  59. package/src/generators/rules/guardrails-profiler/references/signal-registry.json +0 -514
  60. package/src/generators/rules/guardrails-selection/SKILL.md +0 -187
  61. package/src/generators/rules/guardrails-selection/references/category-threat-map.md +0 -232
  62. package/src/generators/rules/guardrails_rule.md +0 -94
  63. package/src/generators/rules/hooks.json +0 -11
  64. package/src/generators/rules/skill.md +0 -256
  65. package/src/generators/rules/srai-profile.md +0 -32
  66. package/src/generators/rules/vibereview-sync/SKILL.md +0 -378
  67. package/src/generators/rules/vscode.js +0 -101
  68. package/src/generators/rules/vscode.test.js +0 -54
  69. package/src/generators/rules/windsurf.js +0 -13
  70. package/src/utils/constants.js +0 -95
  71. package/src/utils/cursor-agent-path.js +0 -67
  72. package/src/utils/cursor-cli-permissions.js +0 -28
  73. package/src/utils/detect.js +0 -27
  74. package/src/utils/fs-helpers.js +0 -82
  75. package/src/utils/guardrails-profiler-bundle.js +0 -84
  76. package/src/utils/ide-cli-install.js +0 -138
  77. package/src/utils/profiler-agent.js +0 -446
  78. package/src/utils/profiler-agent.test.js +0 -81
  79. package/src/utils/srai.js +0 -252
@@ -1,128 +0,0 @@
1
- import { existsSync, unlinkSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import {
4
- GUARDRAILS_PROFILER_SKILL_REL_DIR,
5
- GUARDRAILS_SELECTION_SKILL_REL_DIR,
6
- THREAT_MODELLING_SKILL_REL_DIR,
7
- VIBEREVIEW_SYNC_SKILL_REL_DIR,
8
- } from '../../utils/constants.js';
9
- import { writeText } from '../../utils/fs-helpers.js';
10
- import { mergeCursorCliMcpAllowlist } from '../../utils/cursor-cli-permissions.js';
11
- import {
12
- getRuleContent,
13
- getProfileCommandContent,
14
- getThreatModellingSkillContent,
15
- getVibeReviewSyncSkillContent,
16
- getGuardrailsRuleContent,
17
- getGuardrailsInitProfileContent,
18
- getHooksContent,
19
- } from './content.js';
20
-
21
- function writeCursorRule(filePath, description, content) {
22
- const action = existsSync(filePath) ? 'updated' : 'created';
23
- const mdc = `---
24
- description: ${description}
25
- alwaysApply: true
26
- ---
27
-
28
- ${content}
29
- `;
30
-
31
- writeText(filePath, mdc);
32
- return { filePath, action };
33
- }
34
-
35
- function writeCursorCommand(filePath, content) {
36
- const action = existsSync(filePath) ? 'updated' : 'created';
37
- writeText(filePath, content);
38
- return { filePath, action };
39
- }
40
-
41
- function removeGeneratedText(filePath) {
42
- if (existsSync(filePath)) {
43
- unlinkSync(filePath);
44
- return { filePath, action: 'deleted' };
45
- }
46
- return null;
47
- }
48
-
49
- /**
50
- * Generate Cursor workspace rules at .cursor/rules/*.mdc
51
- * Cursor uses .mdc format with YAML front matter.
52
- */
53
- export function generate(cwd, options = {}) {
54
- const optionsWithSkillDirs = {
55
- ...options,
56
- guardrailsSelectionSkillDir: GUARDRAILS_SELECTION_SKILL_REL_DIR.cursor,
57
- threatModellingSkillDir: THREAT_MODELLING_SKILL_REL_DIR.cursor,
58
- vibereviewSyncSkillDir: VIBEREVIEW_SYNC_SKILL_REL_DIR.cursor,
59
- };
60
- const baseRulePath = join(cwd, '.cursor', 'rules', 'srai-security-review.mdc');
61
- const guardrailsRulePath = join(cwd, '.cursor', 'rules', 'guardrails_rule.mdc');
62
- const profileCommandPath = join(cwd, '.cursor', 'commands', 'srai-profile.md');
63
- const guardrailsInitProfileCommandPath = join(cwd, '.cursor', 'commands', 'guardrails-init-profile.md');
64
- const skillPath = join(cwd, '.cursor', 'skills', 'threat-modelling', 'SKILL.md');
65
- const hooksPath = join(cwd, '.cursor', 'hooks.json');
66
-
67
- const baseRuleContent = getRuleContent(optionsWithSkillDirs);
68
- const guardrailsRuleContent = getGuardrailsRuleContent(optionsWithSkillDirs);
69
- const profileCommandContent = getProfileCommandContent(optionsWithSkillDirs);
70
- const guardrailsInitProfileCommandContent = getGuardrailsInitProfileContent({
71
- ...optionsWithSkillDirs,
72
- guardrailsSkillDir: GUARDRAILS_PROFILER_SKILL_REL_DIR.cursor,
73
- });
74
- const skillContent = getThreatModellingSkillContent(optionsWithSkillDirs);
75
- const vibereviewSyncSkillContent = getVibeReviewSyncSkillContent(optionsWithSkillDirs);
76
-
77
- const baseRule = writeCursorRule(
78
- baseRulePath,
79
- 'SRAI Security Review gate — consult security-review-mcp before security-relevant code changes',
80
- baseRuleContent,
81
- );
82
-
83
- const guardrailsRule = writeCursorRule(
84
- guardrailsRulePath,
85
- 'Vibe Guardrails — fetch and enforce project-specific secure coding guardrails from SRAI',
86
- guardrailsRuleContent,
87
- );
88
- const deletedLegacyRule = removeGeneratedText(join(cwd, '.cursor', 'rules', 'ctm_sync_rule.mdc'));
89
- const deletedLegacyCommand = removeGeneratedText(join(cwd, '.cursor', 'commands', 'ctm_sync.md'));
90
- const deletedLegacyAgent = removeGeneratedText(join(cwd, '.cursor', 'agents', 'ctm_sync.md'));
91
- const deletedLegacyWorkflowCommand = removeGeneratedText(
92
- join(cwd, '.cursor', 'commands', 'create-ide-workflow.md'),
93
- );
94
-
95
- const profileCommand = writeCursorCommand(profileCommandPath, profileCommandContent);
96
- const guardrailsInitProfileCommand = writeCursorCommand(
97
- guardrailsInitProfileCommandPath,
98
- guardrailsInitProfileCommandContent,
99
- );
100
- const skillAction = existsSync(skillPath) ? 'updated' : 'created';
101
- writeText(skillPath, skillContent);
102
- const vibereviewSyncSkillPath = join(cwd, VIBEREVIEW_SYNC_SKILL_REL_DIR.cursor, 'SKILL.md');
103
- const vibereviewSyncSkillAction = existsSync(vibereviewSyncSkillPath) ? 'updated' : 'created';
104
- writeText(vibereviewSyncSkillPath, vibereviewSyncSkillContent);
105
-
106
- const hooksContent = getHooksContent();
107
- const hooksAction = existsSync(hooksPath) ? 'updated' : 'created';
108
- writeText(hooksPath, hooksContent);
109
-
110
- const cursorCliPath = join(cwd, '.cursor', 'cli.json');
111
- const cliPermissionsExisted = existsSync(cursorCliPath);
112
- mergeCursorCliMcpAllowlist(cwd);
113
-
114
- return [
115
- { ...baseRule, kind: 'rule' },
116
- { ...guardrailsRule, kind: 'rule' },
117
- { ...profileCommand, kind: 'command' },
118
- { ...guardrailsInitProfileCommand, kind: 'command' },
119
- { filePath: skillPath, action: skillAction, kind: 'skill' },
120
- { filePath: vibereviewSyncSkillPath, action: vibereviewSyncSkillAction, kind: 'skill' },
121
- { filePath: hooksPath, action: hooksAction, kind: 'hooks' },
122
- { filePath: cursorCliPath, action: cliPermissionsExisted ? 'updated' : 'created', kind: 'config' },
123
- ...(deletedLegacyRule ? [{ ...deletedLegacyRule, kind: 'cleanup' }] : []),
124
- ...(deletedLegacyCommand ? [{ ...deletedLegacyCommand, kind: 'cleanup' }] : []),
125
- ...(deletedLegacyAgent ? [{ ...deletedLegacyAgent, kind: 'cleanup' }] : []),
126
- ...(deletedLegacyWorkflowCommand ? [{ ...deletedLegacyWorkflowCommand, kind: 'cleanup' }] : []),
127
- ];
128
- }
@@ -1,13 +0,0 @@
1
- import { join } from 'node:path';
2
- import { upsertSentinelBlock } from '../../utils/fs-helpers.js';
3
- import { getRuleContent } from './content.js';
4
-
5
- /**
6
- * Generate Gemini CLI / Antigravity workspace rule — appends to GEMINI.md
7
- */
8
- export function generate(cwd, options = {}) {
9
- const filePath = join(cwd, 'GEMINI.md');
10
- const content = getRuleContent(options);
11
- const action = upsertSentinelBlock(filePath, content);
12
- return { filePath, action };
13
- }
@@ -1,56 +0,0 @@
1
- ---
2
- name: guardrails-init-profile
3
- description: Run the Security Review Kit guardrails profiler — scan the repo, write `.guardrails/profile.json`, push the profile and default guardrail pack to SecurityReview.ai via MCP.
4
- ---
5
-
6
- # Guardrails init profile
7
-
8
- Execute the workflow defined in **`{{GUARDRAILS_SKILL_DIR}}/SKILL.md`** end-to-end in this workspace (this IDE’s copy of the guardrails-profiler skill).
9
-
10
- Configured SRAI project name: `<SRAI_PROJECT_NAME>`
11
-
12
- **You must:**
13
-
14
- 1. Read `{{GUARDRAILS_SKILL_DIR}}/SKILL.md` and follow every step (use the signal registry at `{{GUARDRAILS_SKILL_DIR}}/references/signal-registry.json`).
15
- 2. Write `.guardrails/profile.json` as specified.
16
- 3. Call **`update_vibe_profile`** and **`write_default_pack`** on `security-review-mcp` after resolving `project_id` for `<SRAI_PROJECT_NAME>`.
17
-
18
- Do not skip MCP upload when credentials and MCP are available.
19
-
20
- Do **not** ask the user to verbally approve MCP for `security-review-mcp`. The init-time profiler runner passes the CLI-specific MCP configuration and approval settings where supported; call the MCP tools directly.
21
-
22
- ## Cursor CLI (scripted)
23
-
24
- From the repo root, non-interactive runs should include workspace trust and MCP approval:
25
-
26
- `agent -p "<your profiling instructions>" --trust --approve-mcps` (or `cursor-agent` if that is what your install provides)
27
-
28
- Add `--output-format stream-json --stream-partial-output` only when you need verbose agent diagnostics (or use `securityreview-kit init` with `--profiler-verbose`).
29
-
30
- During `securityreview-kit init`, choose **Yes** when asked to run Cursor login in-terminal, or pass **`--profiler-cursor-login`** with **`--profile-repo`** so login and profiling stay in one run.
31
-
32
- You can still sign in manually with `agent login` (or `cursor-agent login`). To handle trust/login interactively in the terminal, omit `--trust` and `--approve-mcps`.
33
-
34
- ## Claude Code CLI (scripted)
35
-
36
- From the repo root, non-interactive runs should execute with the project settings file, the project `.mcp.json` server config, explicit MCP-only loading, bypassed tool prompts for the profiling pass, and the Haiku model:
37
-
38
- `claude -p "<your profiling instructions>" --settings .claude/settings.json --mcp-config "$(cat .mcp.json)" --strict-mcp-config --permission-mode bypassPermissions --model haiku`
39
-
40
- During `securityreview-kit init`, choose **Yes** when asked to run Claude Code login, or pass **`--profiler-claude-login`** with **`--profile-repo`** so `claude auth login` and profiling stay in one run.
41
-
42
- Claude profiling can also run with **Anthropic Console**, **ANTHROPIC_API_KEY**, an **Anthropic-compatible gateway** (`ANTHROPIC_BASE_URL` + `ANTHROPIC_AUTH_TOKEN`), or cloud-provider credentials such as **AWS Bedrock** and **Google Vertex AI**. `securityreview-kit init` can branch into those auth modes before profiling.
43
-
44
- ## GitHub Copilot CLI (scripted)
45
-
46
- From the repo root, non-interactive runs should load the SRAI MCP server and allow the tools needed to scan, write profile files, and call MCP:
47
-
48
- `copilot -p "<your profiling instructions>" --additional-mcp-config '{"mcpServers":{"security-review-mcp":{"type":"stdio","command":"npx","args":["-y","@securityreviewai/security-review-mcp@latest"]}}}' --allow-all`
49
-
50
- During `securityreview-kit init`, choose **Yes** when asked to run GitHub Copilot CLI login, or pass **`--profiler-copilot-login`** with **`--profile-repo`** so `copilot login` and profiling stay in one run.
51
-
52
- ## Codex CLI (scripted)
53
-
54
- From the repo root, non-interactive runs should execute via `codex exec` and include the SRAI MCP server configuration for that run.
55
-
56
- During `securityreview-kit init`, choose **Yes** when asked to run Codex login, or pass **`--profiler-codex-login`** with **`--profile-repo`** so `codex login --device-auth` and profiling stay in one run.
@@ -1,130 +0,0 @@
1
- ---
2
- name: guardrails-profiler
3
- description: Profile a codebase to detect its technology stack and generate a guardrails profile for security-aware AI code generation, then publish the profile and default guardrail pack to SecurityReview.ai via security-review-mcp. Use when Security Review Kit init runs profiling, when `.guardrails/profile.json` is missing, or when the developer asks to profile or re-profile the project.
4
- ---
5
-
6
- # Guardrails Profiler
7
-
8
- Profile a codebase's technology stack, write `.guardrails/profile.json`, and upload the detected profile and default guardrail pack to SRAI using `update_vibe_profile` and `write_default_pack`.
9
-
10
- Configured SRAI project name: `<SRAI_PROJECT_NAME>`
11
-
12
- ## Canonical paths
13
-
14
- - **This skill & signal registry (read-only):** `<GUARDRAILS_SKILL_DIR>/` — e.g. `.cursor/skills/guardrails-profiler`, `.github/skills/guardrails-profiler`, `.claude/skills/guardrails-profiler`, or `.codex/skills/guardrails-profiler` for Codex depending on where this file was installed.
15
- - **Signal registry file:** `<GUARDRAILS_SKILL_DIR>/references/signal-registry.json`
16
- - **Local guardrails file:** `.guardrails/profile.json`
17
-
18
- ## When This Runs
19
-
20
- 1. **Kit init**: User opted in to profile the repo and push the default pack.
21
- 2. **First-run / missing profile**: No `.guardrails/profile.json` and guardrails are needed before threat modeling.
22
- 3. **Explicit re-profile**: Developer asks to refresh the profile.
23
-
24
- ## Quick Check: Should I Profile?
25
-
26
- Before profiling, check if a profile already exists:
27
-
28
- - If `.guardrails/profile.json` exists and has a valid `schema_version`: **SKIP** unless the developer asked to re-profile.
29
- - If missing: **PROCEED**.
30
-
31
- ## Profiling Procedure
32
-
33
- Follow these steps in order.
34
-
35
- ### Step 1: Locate the Project Root
36
-
37
- The project root is the current working directory. Confirm with markers such as `.git/`, `package.json`, `go.mod`, etc.
38
-
39
- ### Step 2: Read the Signal Registry
40
-
41
- Read `<GUARDRAILS_SKILL_DIR>/references/signal-registry.json` (the copy next to this `SKILL.md`). Use its categories (`universal`, `languages`, `frameworks`, `auth_identity`, `ai_agent`, `infrastructure`, `ci_cd`, `cloud_compute`, `databases`, `messaging`, `api_protocols`, etc.) to map detected signals to guardrail pack IDs.
42
-
43
- ### Step 3: Scan for Signals
44
-
45
- Same methodology as the upstream guardrails-profiler skill:
46
-
47
- #### 3a. Manifest and Config File Detection
48
-
49
- List files in the project root (1–2 levels deep). Detect manifests (`package.json`, `pyproject.toml`, `go.mod`, `pom.xml`, `Dockerfile`, `.github/workflows/`, `next.config.*`, etc.) per the registry.
50
-
51
- #### 3b. Dependency Parsing
52
-
53
- For each manifest found, read dependencies and match names against `dependency_signals` in the registry. Prefer manifests over extension-only guesses.
54
-
55
- #### 3c. Content Signals (targeted only)
56
-
57
- When needed, grep specific files (e.g. Terraform providers, K8s `apiVersion`, CloudFormation) — do not read the entire repository.
58
-
59
- #### 3d. File Extension Fallback
60
-
61
- If no manifest exists for a language, use dominant extensions as a last resort.
62
-
63
- ### Step 4: Assemble the Guardrails Profile Object
64
-
65
- Build the object for `.guardrails/profile.json`:
66
-
67
- ```json
68
- {
69
- "schema_version": "1.0",
70
- "project_name": "<directory name>",
71
- "profiled_at": "<ISO 8601 timestamp>",
72
- "profiled_by": "<ide or cli id, e.g. agent, cursor-agent, claude, codex>",
73
- "detection_summary": {
74
- "languages": [],
75
- "frameworks": [],
76
- "infrastructure": [],
77
- "databases": [],
78
- "auth": [],
79
- "ai_agent": [],
80
- "ci_cd": [],
81
- "cloud_compute": [],
82
- "messaging": [],
83
- "api_protocols": [],
84
- "mobile": false
85
- },
86
- "guardrail_packs": [],
87
- "pack_count": 0
88
- }
89
- ```
90
-
91
- Rules for `guardrail_packs`:
92
-
93
- 1. Always include `owasp-asvs`.
94
- 2. Include `owasp-masvs` if mobile stacks are detected (flutter, react-native, swift, objective-c, kotlin per registry).
95
- 3. Add language, framework, auth, AI, infra, CI/CD, cloud, DB, messaging, and API packs per registry matches.
96
- 4. Deduplicate and set `pack_count`.
97
-
98
- Do **not** invent packs or signals; if the repo is empty, use universal baseline only and empty category arrays where appropriate.
99
-
100
- ### Step 5: Write `.guardrails/profile.json`
101
-
102
- Create `.guardrails/` if needed and write the profile file.
103
-
104
- ### Step 6: Upload to SecurityReview.ai (security-review-mcp)
105
-
106
- 1. Resolve `project_id`: `find_project_by_name` with `name="<SRAI_PROJECT_NAME>"`. If missing, follow existing kit rules (`list_projects`, `create_project`).
107
-
108
- 2. Call **`update_vibe_profile`** with `project_id` and arguments mapped directly from the `.guardrails/profile.json` object (and any required `project_id` fields) per the MCP tool’s documented schema. Treat the guardrails detection object as the profile payload — **not** a separate prose vibe document.
109
-
110
- 3. Call **`write_default_pack`** with `project_id`, `guardrail_packs`, and `pack_count` derived from `.guardrails/profile.json` (match the MCP tool’s schema).
111
-
112
- 4. **MCP approval:** Do **not** ask the user to “approve MCP” or “say you approve” for `security-review-mcp`. Security Review Kit passes the configured MCP server and approval settings during init-time profiling where the CLI supports it (for example Cursor CLI permissions and Copilot CLI `--additional-mcp-config` / `--allow-all`). Invoke `find_project_by_name`, `update_vibe_profile`, and `write_default_pack` directly. If a call still fails with permissions, report the exact CLI permission error — not a conversational approval step.
113
-
114
- 5. Confirm success: path written (`.guardrails/profile.json`) and whether both MCP calls succeeded, or the exact error.
115
-
116
- ### Step 7: Report
117
-
118
- Give a concise summary of detected stack, pack count, and upload status.
119
-
120
- ## Empty / New Repository Handling
121
-
122
- If there are no signals:
123
-
124
- 1. Optionally read `.git/config` for hints.
125
- 2. Emit minimal profile: `owasp-asvs` only, empty summaries where appropriate.
126
- 3. Still write `.guardrails/profile.json` (minimal baseline profile) and attempt MCP calls.
127
-
128
- ## IDE-Specific Notes
129
-
130
- When run from Cursor Agent CLI, GitHub Copilot CLI, Claude Code, or Codex CLI, set `profiled_by` to a stable id (`agent` or `cursor-agent`, `copilot`, `claude`, `codex`).