minimal-vibe-coding-kit 0.4.1 → 0.4.2

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 (84) hide show
  1. package/.agents/skills/agentshield-security-review/scripts/agentshield_repo_probe.py +28 -3
  2. package/.agents/skills/prompt-sharpener/SKILL.md +54 -0
  3. package/.agents/skills/vibekit-init/SKILL.md +2 -2
  4. package/.claude/settings.json +10 -3
  5. package/.claude/skills/agentshield-security-review/scripts/agentshield_repo_probe.py +28 -3
  6. package/.claude/skills/prompt-sharpener/SKILL.md +54 -0
  7. package/.claude/skills/vibekit-init/SKILL.md +2 -2
  8. package/.codex/rules/vibekit.rules +77 -0
  9. package/.codex-plugin/plugin.json +1 -1
  10. package/.cursor/cli.json +18 -0
  11. package/.cursor/settings.json +15 -8
  12. package/.cursor/skills/prompt-sharpener/SKILL.md +54 -0
  13. package/.grok/README.md +13 -0
  14. package/.grok/config.example.toml +13 -0
  15. package/.grok/config.toml +29 -0
  16. package/.grok/rules/safe-delete.md +11 -0
  17. package/.grok/rules/security.md +5 -0
  18. package/.grok/rules/vibe-core.md +8 -0
  19. package/.grok/skills/agentshield-security-review/SKILL.md +75 -0
  20. package/.grok/skills/agentshield-security-review/agents/openai.yaml +5 -0
  21. package/.grok/skills/agentshield-security-review/references/native-install.md +97 -0
  22. package/.grok/skills/agentshield-security-review/references/report-template.md +54 -0
  23. package/.grok/skills/agentshield-security-review/references/review-checklist.md +45 -0
  24. package/.grok/skills/agentshield-security-review/scripts/agentshield_repo_probe.py +135 -0
  25. package/.grok/skills/autoresearch-coding/README.md +15 -0
  26. package/.grok/skills/autoresearch-coding/SKILL.md +101 -0
  27. package/.grok/skills/autoresearch-coding/references/experiment-contract.md +13 -0
  28. package/.grok/skills/autoresearch-coding/references/metric-extraction.md +8 -0
  29. package/.grok/skills/autoresearch-coding/references/result-ledger.md +15 -0
  30. package/.grok/skills/autoresearch-coding/scripts/log_result.py +24 -0
  31. package/.grok/skills/autoresearch-coding/scripts/run_logged.py +30 -0
  32. package/.grok/skills/clearthought/SKILL.md +100 -0
  33. package/.grok/skills/clearthought/examples/decision-framework.md +441 -0
  34. package/.grok/skills/clearthought/examples/metagame-examples.md +536 -0
  35. package/.grok/skills/clearthought/examples/sequential-thinking.md +380 -0
  36. package/.grok/skills/clearthought/references/output-schemas.md +494 -0
  37. package/.grok/skills/clearthought/references/parameter-reference.md +482 -0
  38. package/.grok/skills/coding-level/SKILL.md +34 -0
  39. package/.grok/skills/coding-level/references/level-0.md +131 -0
  40. package/.grok/skills/coding-level/references/level-1.md +118 -0
  41. package/.grok/skills/coding-level/references/level-2.md +140 -0
  42. package/.grok/skills/coding-level/references/level-3.md +142 -0
  43. package/.grok/skills/coding-level/references/level-4.md +152 -0
  44. package/.grok/skills/coding-level/references/level-5.md +84 -0
  45. package/.grok/skills/daily-workflow-curator/SKILL.md +52 -0
  46. package/.grok/skills/memento/SKILL.md +36 -0
  47. package/.grok/skills/parallel-analysis/SKILL.md +160 -0
  48. package/.grok/skills/path-sensitive-shell-safety/SKILL.md +69 -0
  49. package/.grok/skills/path-sensitive-shell-safety/references/workflow.md +127 -0
  50. package/.grok/skills/prompt-sharpener/SKILL.md +54 -0
  51. package/.grok/skills/reviewing-4p-priorities/SKILL.md +72 -0
  52. package/.grok/skills/reviewing-4p-priorities/examples.md +298 -0
  53. package/.grok/skills/sequential-thinking/SKILL.md +106 -0
  54. package/.grok/skills/sequential-thinking/examples/adaptive-depth.md +542 -0
  55. package/.grok/skills/sequential-thinking/examples/branching-exploration.md +474 -0
  56. package/.grok/skills/sequential-thinking/examples/linear-reasoning.md +210 -0
  57. package/.grok/skills/sequential-thinking/examples/revision-pattern.md +304 -0
  58. package/.grok/skills/sequential-thinking/references/output-schema.md +483 -0
  59. package/.grok/skills/sequential-thinking/references/parameters.md +463 -0
  60. package/.grok/skills/sequential-thinking/references/patterns.md +666 -0
  61. package/.grok/skills/vibekit-init/SKILL.md +52 -0
  62. package/.grok/skills/visual-design-loop/SKILL.md +103 -0
  63. package/.grok/skills/visual-design-loop/agents/openai.yaml +4 -0
  64. package/.vibekit/docs/BACKBONE_REFERENCE.md +1 -1
  65. package/.vibekit/docs/INSTALL.md +9 -7
  66. package/.vibekit/docs/SECURITY_MODEL.md +1 -1
  67. package/.vibekit/docs/TOOLING_GUIDE.md +5 -0
  68. package/.vibekit/docs/templates/CONTEXT_TEMPLATE.md +1 -1
  69. package/.vibekit/init/CLAUDE-template.md +1 -0
  70. package/.vibekit/init/FIRST_PROMPT.md +1 -1
  71. package/.vibekit/init/FIRST_TIME_INIT.md +2 -2
  72. package/.vibekit/scripts/doctor.mjs +11 -4
  73. package/.vibekit/scripts/mvck.mjs +24 -9
  74. package/.vibekit/scripts/test-install.mjs +8 -0
  75. package/.vibekit/scripts/validate-kit.mjs +104 -39
  76. package/.vibekit/skills/agentshield-security-review/scripts/agentshield_repo_probe.py +28 -3
  77. package/.vibekit/skills/prompt-sharpener/SKILL.md +54 -0
  78. package/.vibekit/skills/vibekit-init/SKILL.md +2 -2
  79. package/AGENTS.md +2 -2
  80. package/CHANGELOG.md +10 -0
  81. package/README.md +17 -12
  82. package/backbone.yml +2 -1
  83. package/docs/README.vi.md +56 -51
  84. package/package.json +7 -2
@@ -0,0 +1,103 @@
1
+ ---
2
+ name: visual-design-loop
3
+ description: Run an iterative visual design improvement loop for UI/product polish tasks. Use when a request involves screenshots, rendering, visual review, frontend polish, layout/typography/color refinement, design QA, or a Claude/Codex loop goal that touches a visible product surface.
4
+ ---
5
+
6
+ # Visual Design Loop
7
+
8
+ Use this skill to improve a visible UI through controlled render-review-fix loops. Keep the brief and existing project conventions as the source of truth; do not add new product requirements just because a screen could be enhanced.
9
+
10
+ ## Contract
11
+
12
+ Before editing, resolve and state:
13
+
14
+ - Goal.
15
+ - Target surface: route, page, component, flow, or supplied screenshot.
16
+ - Source of truth: current brief plus repo instructions, design system, nearby UI, and `backbone.yml` when present.
17
+ - Render method: local URL, app command, Storybook story, preview command, static file, or supplied screenshot.
18
+ - Screenshot method: browser screenshot, Playwright, in-app browser, provided image, or equivalent.
19
+ - Editable paths.
20
+ - Protected paths.
21
+ - Budget: default 3 loops.
22
+ - Timeout: default 10 minutes per loop.
23
+ - Log path: `/tmp/design-{project_slug}.md`.
24
+
25
+ If render or screenshot capture is missing and cannot be inferred safely, ask for the missing command, URL, or image before editing.
26
+
27
+ ## Baseline
28
+
29
+ 1. Render the target surface.
30
+ 2. Capture or inspect the baseline screenshot.
31
+ 3. Review visible issues only; do not invent findings.
32
+ 4. Create or update `/tmp/design-{project_slug}.md`.
33
+ 5. Log the baseline screenshot, visual score, main issues, and any render constraints.
34
+
35
+ Derive `project_slug` from `backbone.yml` `project.name` when available; otherwise use the repository directory name.
36
+
37
+ ## Visual rubric
38
+
39
+ Score screenshots from 1 to 5 using:
40
+
41
+ - Visual hierarchy: primary content and action are obvious.
42
+ - Layout and spacing: alignment, rhythm, density, whitespace.
43
+ - Typography: scale, contrast, readability, consistency.
44
+ - Color and contrast: accessible, intentional, not noisy.
45
+ - Component consistency: matches nearby UI and design system.
46
+ - Responsiveness: works at relevant viewport sizes.
47
+ - Interaction states: hover, focus, disabled, empty, loading, and error states when relevant.
48
+ - Product fit: improves the brief without adding unnecessary features.
49
+
50
+ ## Loop
51
+
52
+ For each loop:
53
+
54
+ 1. Review the latest screenshot.
55
+ 2. Identify the highest-impact visual issue.
56
+ 3. Form one small hypothesis.
57
+ 4. Apply one targeted fix inside editable paths only.
58
+ 5. Render again.
59
+ 6. Capture the after screenshot.
60
+ 7. Compare before and after.
61
+ 8. Keep the change only if quality improves, or if quality is equal with simpler and safer implementation.
62
+ 9. Revert only your own loop changes if the result is worse.
63
+ 10. Run the repo validation command when code changed.
64
+ 11. Append the loop result to `/tmp/design-{project_slug}.md`.
65
+
66
+ Each loop entry must include:
67
+
68
+ - Loop number.
69
+ - Screenshot reviewed.
70
+ - Issue found.
71
+ - Hypothesis.
72
+ - Fix applied.
73
+ - Before/after judgment.
74
+ - Rubric score before.
75
+ - Rubric score after.
76
+ - Validation result.
77
+ - Remaining concerns.
78
+ - Stop/continue decision.
79
+
80
+ ## Stop criteria
81
+
82
+ Stop when:
83
+
84
+ - The design is polished enough for the brief.
85
+ - The latest loop gives no meaningful improvement.
86
+ - Further changes would be subjective or overworked.
87
+ - Budget is reached.
88
+ - Validation fails for a non-trivial reason.
89
+ - A product or design decision is required from the user.
90
+ - Render or screenshot tooling is unavailable.
91
+
92
+ ## Final report
93
+
94
+ Report:
95
+
96
+ - Baseline score.
97
+ - Final score.
98
+ - Screenshots reviewed.
99
+ - Changes kept.
100
+ - Changes discarded, if any.
101
+ - Validation result.
102
+ - Remaining risks or design decisions.
103
+ - Log path.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Visual Design Loop"
3
+ short_description: "Iterative screenshot-based UI polish loop"
4
+ default_prompt: "Use $visual-design-loop to render, screenshot, review, and improve this UI until it is polished but not overworked."
@@ -10,7 +10,7 @@
10
10
  - `conventions`: user-reviewed project rules inferred from existing code.
11
11
  - `commands`: install, test, lint, typecheck, build, validate.
12
12
  - `policy`: branch, commit, editable paths, protected paths.
13
- - `agent_surfaces`: Claude, Cursor, Codex, shared skills, shared commands.
13
+ - `agent_surfaces`: Claude, Cursor, Codex, Grok, shared skills, shared commands.
14
14
  - `automation`: autoresearch, daily enhance, finalize (graduation cleanup), security.
15
15
 
16
16
  ## Init status
@@ -26,9 +26,10 @@ node .vibekit/scripts/mvck.mjs install /path/to/project --profile all
26
26
 
27
27
  Profiles:
28
28
 
29
- - `claude`: `CLAUDE.md`, `.claude/`, Claude skills, agents, commands, rules.
30
- - `cursor`: `.cursor/rules`, `.cursor/commands`, Cursor skill entrypoints.
31
- - `codex`: `AGENTS.md`, `.agents/skills`, `.codex-plugin`, `.codex` examples.
29
+ - `claude`: `CLAUDE.md`, `.claude/`, Claude skills, agents, commands, rules, deny-list settings.
30
+ - `cursor`: `.cursor/rules`, `.cursor/commands`, `.cursor/cli.json` CLI permissions, Cursor skill entrypoints.
31
+ - `codex`: `AGENTS.md`, `.agents/skills`, `.codex/rules` execution-policy rules, `.codex-plugin`, `.codex` examples.
32
+ - `grok`: `AGENTS.md`, `.grok/rules`, `.grok/skills`, `.grok/config.toml` permission rules, user config example.
32
33
  - `all`: every profile.
33
34
 
34
35
  ## Safe behavior
@@ -59,7 +60,7 @@ node /path/to/kit/.vibekit/scripts/mvck.mjs update /path/to/project
59
60
 
60
61
  The updater:
61
62
 
62
- - refreshes kit-owned surfaces (`.vibekit/skills/`, `.vibekit/commands/`, `.vibekit/scripts/`, `.vibekit/docs/`, and the `.claude/`, `.cursor/`, `.agents/`, `.codex*` mirrors) and adds any new kit skills;
63
+ - refreshes kit-owned surfaces (`.vibekit/skills/`, `.vibekit/commands/`, `.vibekit/scripts/`, `.vibekit/docs/`, and the `.claude/`, `.cursor/`, `.agents/`, `.grok/`, `.codex*` mirrors) and adds any new kit skills;
63
64
  - never overwrites `backbone.yml`, `CLAUDE.md`, `AGENTS.md` content outside the managed block, or `settings.json` files — those are seeded only if missing;
64
65
  - backs up every replaced kit file to `.vibekit/update-backup/<timestamp>/` (disable with `--no-backup`);
65
66
  - never deletes files you added, and skips re-seeding one-time files after `mvck finalize`;
@@ -114,7 +115,7 @@ node .vibekit/scripts/mvck.mjs doctor . --write-report
114
115
 
115
116
  ## Native reasoning skills
116
117
 
117
- The installer includes three flexible custom reasoning skills across Claude, Codex, and Cursor. These install as full skill folders, including examples and references for progressive disclosure:
118
+ The installer includes three flexible custom reasoning skills across Claude, Codex, Cursor, and Grok. These install as full skill folders, including examples and references for progressive disclosure:
118
119
 
119
120
  - `clearthought`: clarify ambiguous tasks and choose a reasoning mode.
120
121
  - `sequential-thinking`: split complex work into ordered implementation steps.
@@ -122,11 +123,12 @@ The installer includes three flexible custom reasoning skills across Claude, Cod
122
123
 
123
124
  ## Visual design loop skill
124
125
 
125
- The installer also includes `visual-design-loop` for Claude and Codex surfaces. Use it when a loop goal touches UI polish, screenshots, rendering, visual QA, or visible frontend behavior.
126
+ The installer also includes `visual-design-loop` for Claude, Codex, and Grok surfaces. Use it when a loop goal touches UI polish, screenshots, rendering, visual QA, or visible frontend behavior.
126
127
 
127
128
  ## User-invoked utility skills
128
129
 
129
- Two user-invoked skills install across Claude, Codex, and Cursor surfaces:
130
+ Three user-invoked skills install across Claude, Codex, Cursor, and Grok surfaces:
130
131
 
131
132
  - `memento`: write a `MEMENTO.md` working note before closing a multi-day task (`/memento`), then resume from it in the next session (`/memento resume`).
132
133
  - `coding-level`: set the explanation register from 0 (ELI5) to 5 (expert peer) with `/coding-level N`; stays active until reinvoked.
134
+ - `prompt-sharpener`: sharpen a rough prompt into a precise one with `/prompt-sharpener <rough prompt>`, then execute the sharpened version immediately in the same turn.
@@ -5,7 +5,7 @@
5
5
  Review these before merging changes:
6
6
 
7
7
  - `CLAUDE.md`, `AGENTS.md`, `.github/copilot-instructions.md`
8
- - `.claude/**`, `.cursor/**`, `.agents/**`, `.codex-plugin/**`
8
+ - `.claude/**`, `.cursor/**`, `.agents/**`, `.grok/**`, `.codex-plugin/**`
9
9
  - `.vibekit/skills/**`, `.vibekit/commands/**`, `.vibekit/scripts/**`, `hooks/**`
10
10
  - `.mcp.json`, `mcp.json`, `mcp-configs/**`
11
11
  - installer scripts and CI workflows
@@ -12,11 +12,16 @@ Use `.cursor/rules/*.mdc`. The kit creates always-on core rules plus scoped rule
12
12
 
13
13
  Use `AGENTS.md` for repo instructions and `.agents/skills/*/SKILL.md` for skills. The kit also includes `.codex-plugin/plugin.json` so the shared skills can be packaged as a plugin.
14
14
 
15
+ ## Grok
16
+
17
+ Grok Build reads `AGENTS.md` natively plus every `*.md` rule in `.grok/rules/`, and repository skills from `.grok/skills/*/SKILL.md` (user-invocable skills appear as `/<skill-name>` slash commands). Permission deny rules are user-level only: see `.grok/config.example.toml` for the `~/.grok/config.toml` setup.
18
+
15
19
  ## Shared skill strategy
16
20
 
17
21
  Canonical skill bodies live in `.vibekit/skills/<skill-name>/`. Harness-specific folders contain small shims:
18
22
 
19
23
  - `.claude/skills/<skill-name>/SKILL.md`
20
24
  - `.agents/skills/<skill-name>/SKILL.md`
25
+ - `.grok/skills/<skill-name>/SKILL.md`
21
26
 
22
27
  This reduces drift while still giving each tool the path it expects.
@@ -1,7 +1,7 @@
1
1
  # Project context
2
2
 
3
3
  > Scaffolded by Minimal Vibe Coding Kit. A short, shared glossary and map so any
4
- > agent (Claude, Cursor, Codex) navigates this project with less back-and-forth.
4
+ > agent (Claude, Cursor, Codex, Grok) navigates this project with less back-and-forth.
5
5
  > Keep it current and terse — definitions, not prose.
6
6
 
7
7
  ## Domain glossary
@@ -17,6 +17,7 @@ This file is intentionally small. Shared rules live in `AGENTS.md`, project fact
17
17
  - `/security-scan` - run AgentShield-style review.
18
18
  - `/daily-enhance` - propose rule, skill, and workflow improvements.
19
19
  - `/coding-level N` - set explanation depth 0-5; the project default lives in `backbone.yml` `conventions.custom_rules`.
20
+ - `/prompt-sharpener <rough prompt>` - sharpen a rough prompt into a precise one, then execute it in the same turn.
20
21
 
21
22
  ## Hard rules
22
23
 
@@ -36,7 +36,7 @@ Use the autoresearch-coding skill.
36
36
  Goal: improve this Minimal Vibe Coding Kit for existing projects in any language.
37
37
  Metric command: node .vibekit/scripts/validate-kit.mjs .
38
38
  Direction: higher.
39
- Editable paths: README.md .vibekit/docs .vibekit/scripts skills .vibekit/commands .claude .cursor .agents .codex-plugin .github backbone.yml AGENTS.md .vibekit/init/CLAUDE-template.md .vibekit/init/FIRST_TIME_INIT.md package.json install.sh install.ps1.
39
+ Editable paths: README.md .vibekit/docs .vibekit/scripts skills .vibekit/commands .claude .cursor .agents .grok .codex-plugin .github backbone.yml AGENTS.md .vibekit/init/CLAUDE-template.md .vibekit/init/FIRST_TIME_INIT.md package.json install.sh install.ps1.
40
40
  Protected paths: .git .env* node_modules vendor secrets lockfiles.
41
41
  Budget: 3.
42
42
  ```
@@ -1,6 +1,6 @@
1
1
  # .vibekit/init/FIRST_TIME_INIT.md - bootstrap runbook
2
2
 
3
- Audience: Claude, Cursor, Codex, or any AI coding agent in a repo that just received Minimal Vibe Coding Kit.
3
+ Audience: Claude, Cursor, Codex, Grok, or any AI coding agent in a repo that just received Minimal Vibe Coding Kit.
4
4
 
5
5
  Keep this flow short. Detailed schema notes live in `.vibekit/docs/BACKBONE_REFERENCE.md`.
6
6
 
@@ -11,7 +11,7 @@ Before writing anything, print this checklist and mark each item as found, missi
11
11
  1. `backbone.yml` exists.
12
12
  2. `AGENTS.md` exists or will be created/merged.
13
13
  3. `CLAUDE.md` exists or will be created from `.vibekit/init/CLAUDE-template.md` when Claude support is installed.
14
- 4. At least one harness folder exists: `.claude/`, `.cursor/`, `.agents/`, or `.codex-plugin/`.
14
+ 4. At least one harness folder exists: `.claude/`, `.cursor/`, `.agents/`, `.grok/`, or `.codex-plugin/`.
15
15
  5. Git status is known. If user changes exist, do not overwrite them.
16
16
  6. A validation command is inferred or set to `node .vibekit/scripts/validate-kit.mjs .` for the kit itself.
17
17
  7. Protected paths include `.env*`, secrets, lockfiles, generated files, build output, migrations, and infra unless the user says otherwise.
@@ -170,7 +170,8 @@ const surfaces = {
170
170
  agents: exists('AGENTS.md'),
171
171
  claude: exists('CLAUDE.md') || exists('.vibekit/init/CLAUDE-template.md') || exists('.claude'),
172
172
  cursor: exists('.cursor/rules'),
173
- codex: exists('.agents') || exists('.codex-plugin/plugin.json')
173
+ codex: exists('.agents') || exists('.codex-plugin/plugin.json'),
174
+ grok: exists('.grok')
174
175
  };
175
176
  const managedBlocks = {
176
177
  AGENTS: countManaged('AGENTS.md'),
@@ -190,7 +191,8 @@ const nativeSkillSurfaces = {
190
191
  shared: '.vibekit/skills',
191
192
  claude: '.claude/skills',
192
193
  codex: '.agents/skills',
193
- cursor: '.cursor/skills'
194
+ cursor: '.cursor/skills',
195
+ grok: '.grok/skills'
194
196
  };
195
197
  const missingNativeSkills = [];
196
198
  for (const [surface, dir] of Object.entries(nativeSkillSurfaces)) {
@@ -257,7 +259,9 @@ const report = {
257
259
  claudeSkills: listFiles('.claude/skills').filter((f) => f.endsWith('SKILL.md')).length,
258
260
  codexSkills: listFiles('.agents/skills').filter((f) => f.endsWith('SKILL.md')).length,
259
261
  cursorSkills: listFiles('.cursor/skills').filter((f) => f.endsWith('SKILL.md')).length,
260
- cursorRules: listFiles('.cursor/rules').filter((f) => f.endsWith('.mdc')).length
262
+ cursorRules: listFiles('.cursor/rules').filter((f) => f.endsWith('.mdc')).length,
263
+ grokSkills: listFiles('.grok/skills').filter((f) => f.endsWith('SKILL.md')).length,
264
+ grokRules: listFiles('.grok/rules').filter((f) => f.endsWith('.md')).length
261
265
  },
262
266
  recommendedFirstPrompt: 'Read AGENTS.md and backbone.yml, run mvck doctor ., then propose a small safe plan before editing.',
263
267
  knownRisks: risks
@@ -308,15 +312,18 @@ ${(data.protectedPaths.length ? data.protectedPaths : ['not declared']).map((ite
308
312
  - Claude surface: ${data.agentSurfaces.claude ? 'yes' : 'no'}
309
313
  - Cursor surface: ${data.agentSurfaces.cursor ? 'yes' : 'no'}
310
314
  - Codex surface: ${data.agentSurfaces.codex ? 'yes' : 'no'}
315
+ - Grok surface: ${data.agentSurfaces.grok ? 'yes' : 'no'}
311
316
  - Shared skills: ${data.aiRulesLoaded.sharedSkills}
312
317
  - Claude skills: ${data.aiRulesLoaded.claudeSkills}
313
318
  - Codex skills: ${data.aiRulesLoaded.codexSkills}
314
319
  - Cursor skills: ${data.aiRulesLoaded.cursorSkills}
315
320
  - Cursor rules: ${data.aiRulesLoaded.cursorRules}
321
+ - Grok skills: ${data.aiRulesLoaded.grokSkills}
322
+ - Grok rules: ${data.aiRulesLoaded.grokRules}
316
323
 
317
324
  ## Native reasoning skills
318
325
 
319
- ${data.nativeReasoningSkills.names.map((skill) => `- ${skill}: ${data.nativeReasoningSkills.missing.some((item) => item.endsWith(`:${skill}`)) ? 'missing on one or more surfaces' : 'available on shared, Claude, Codex, and Cursor'}`).join('\n')}
326
+ ${data.nativeReasoningSkills.names.map((skill) => `- ${skill}: ${data.nativeReasoningSkills.missing.some((item) => item.endsWith(`:${skill}`)) ? 'missing on one or more surfaces' : 'available on shared, Claude, Codex, Cursor, and Grok'}`).join('\n')}
320
327
 
321
328
  ## Recommended first prompt
322
329
 
@@ -13,8 +13,8 @@ function usage() {
13
13
  console.log(`Minimal Vibe Coding Kit
14
14
 
15
15
  Usage:
16
- mvck install [target] [--profile all|claude,cursor,codex] [--force] [--dry-run] [--json]
17
- mvck update [target] [--profile all|claude,cursor,codex] [--dry-run] [--json] [--no-backup]
16
+ mvck install [target] [--profile all|claude,cursor,codex,grok] [--force] [--dry-run] [--json]
17
+ mvck update [target] [--profile all|claude,cursor,codex,grok] [--dry-run] [--json] [--no-backup]
18
18
  mvck init [target] [--propose|--write --yes] [--preset nextjs|wordpress|python|laravel|docker]
19
19
  mvck validate [target]
20
20
  mvck doctor [target] [--write-report] [--json]
@@ -158,23 +158,24 @@ const KIT_SCRIPTS = [
158
158
  '.vibekit/scripts/mvck.mjs', '.vibekit/scripts/init-backbone.mjs', '.vibekit/scripts/daily-enhance.mjs', '.vibekit/scripts/validate-kit.mjs',
159
159
  '.vibekit/scripts/doctor.mjs', '.vibekit/scripts/agentshield-probe.mjs', '.vibekit/scripts/vibekit-finalize.mjs'
160
160
  ];
161
- const VALID_PROFILES = new Set(['claude', 'cursor', 'codex']);
161
+ const VALID_PROFILES = new Set(['claude', 'cursor', 'codex', 'grok']);
162
162
 
163
163
  function parseProfiles(profileRaw) {
164
- const profiles = new Set(profileRaw === 'all' ? ['claude', 'cursor', 'codex'] : profileRaw.split(',').map((x) => x.trim()).filter(Boolean));
164
+ const profiles = new Set(profileRaw === 'all' ? ['claude', 'cursor', 'codex', 'grok'] : profileRaw.split(',').map((x) => x.trim()).filter(Boolean));
165
165
  for (const p of profiles) {
166
- if (!VALID_PROFILES.has(p)) throw new Error(`Unknown profile: ${p}. Valid values: all, claude, cursor, codex (comma-separated).`);
166
+ if (!VALID_PROFILES.has(p)) throw new Error(`Unknown profile: ${p}. Valid values: all, claude, cursor, codex, grok (comma-separated).`);
167
167
  }
168
168
  return profiles;
169
169
  }
170
170
  const CLAUDE_DIRS = ['.claude/agents', '.claude/commands', '.claude/rules'];
171
171
  const CLAUDE_SKILLS = [
172
172
  'autoresearch-coding', 'agentshield-security-review', 'daily-workflow-curator', 'vibekit-init', 'visual-design-loop',
173
- 'clearthought', 'sequential-thinking', 'reviewing-4p-priorities', 'path-sensitive-shell-safety', 'memento', 'coding-level', 'parallel-analysis'
173
+ 'clearthought', 'sequential-thinking', 'reviewing-4p-priorities', 'path-sensitive-shell-safety', 'memento', 'coding-level', 'parallel-analysis', 'prompt-sharpener'
174
174
  ];
175
175
  const CURSOR_DIRS = ['.cursor/rules', '.cursor/commands'];
176
- const CURSOR_SKILLS = ['clearthought', 'sequential-thinking', 'reviewing-4p-priorities', 'path-sensitive-shell-safety', 'memento', 'coding-level', 'parallel-analysis'];
176
+ const CURSOR_SKILLS = ['clearthought', 'sequential-thinking', 'reviewing-4p-priorities', 'path-sensitive-shell-safety', 'memento', 'coding-level', 'parallel-analysis', 'prompt-sharpener'];
177
177
  const CODEX_DIRS = ['.agents', '.codex', '.codex-plugin'];
178
+ const GROK_DIRS = ['.grok'];
178
179
  const GITIGNORE_BLOCK = `# BEGIN: minimal-vibe-coding-kit\n.autoresearch/\nresults.tsv\n.vibekit/INIT_DONE\n.vibekit/FINALIZE_DONE\n.vibekit/reports/\n.vibekit/update-backup/\n_vibekit-cleanup/\nCLAUDE.local.md\n# END: minimal-vibe-coding-kit`;
179
180
 
180
181
  function kitVersion() {
@@ -258,12 +259,18 @@ function install() {
258
259
  actions.push(copyDirSafe(`.cursor/skills/${skill}`, `.cursor/skills/${skill}`, target, opts));
259
260
  }
260
261
  actions.push(copyFileSafe('.cursor/settings.json', '.cursor/settings.json', target, opts));
262
+ actions.push(copyFileSafe('.cursor/cli.json', '.cursor/cli.json', target, opts));
261
263
  }
262
264
  if (profiles.has('codex')) {
263
265
  for (const dir of CODEX_DIRS) {
264
266
  actions.push(copyDirSafe(dir, dir, target, opts));
265
267
  }
266
268
  }
269
+ if (profiles.has('grok')) {
270
+ for (const dir of GROK_DIRS) {
271
+ actions.push(copyDirSafe(dir, dir, target, opts));
272
+ }
273
+ }
267
274
 
268
275
  applyManagedBlocks(target, profiles, actions, { dryRun });
269
276
  writeKitVersion(target, dryRun);
@@ -398,13 +405,21 @@ function update() {
398
405
  if (profiles.has('codex')) {
399
406
  for (const dir of CODEX_DIRS) actions.push(...updateDirSafe(dir, target, opts));
400
407
  }
408
+ if (profiles.has('grok')) {
409
+ // .grok/config.toml holds user-editable permission rules; seed it below instead of overwriting.
410
+ for (const dir of GROK_DIRS) actions.push(...updateDirSafe(dir, target, dir === '.grok' ? { ...opts, exclude: ['config.toml'] } : opts));
411
+ }
401
412
 
402
413
  // User-owned files: seed only when missing, never overwrite. Finalized
403
414
  // projects removed the one-time files on purpose, so skip re-seeding them.
404
415
  const seedFiles = finalized ? ['backbone.yml'] : KIT_SEED_FILES;
405
416
  for (const file of seedFiles) actions.push(copyFileSafe(file, file, target, { force: false, dryRun }));
406
417
  if (profiles.has('claude')) actions.push(copyFileSafe('.claude/settings.json', '.claude/settings.json', target, { force: false, dryRun }));
407
- if (profiles.has('cursor')) actions.push(copyFileSafe('.cursor/settings.json', '.cursor/settings.json', target, { force: false, dryRun }));
418
+ if (profiles.has('cursor')) {
419
+ actions.push(copyFileSafe('.cursor/settings.json', '.cursor/settings.json', target, { force: false, dryRun }));
420
+ actions.push(copyFileSafe('.cursor/cli.json', '.cursor/cli.json', target, { force: false, dryRun }));
421
+ }
422
+ if (profiles.has('grok')) actions.push(copyFileSafe('.grok/config.toml', '.grok/config.toml', target, { force: false, dryRun }));
408
423
 
409
424
  applyManagedBlocks(target, profiles, actions, { dryRun });
410
425
  writeKitVersion(target, dryRun);
@@ -412,7 +427,7 @@ function update() {
412
427
  const summary = { add: 0, update: 0, unchanged: 0, skip: 0, 'managed-block': 0 };
413
428
  for (const a of actions) summary[a.action] = (summary[a.action] || 0) + 1;
414
429
  const backupInfo = backup && backup.count > 0 ? path.relative(target, backup.dir) : null;
415
- const preserved = ['backbone.yml', 'CLAUDE.md', 'AGENTS.md content outside the managed block', '.claude/settings.json', '.cursor/settings.json'];
430
+ const preserved = ['backbone.yml', 'CLAUDE.md', 'AGENTS.md content outside the managed block', '.claude/settings.json', '.cursor/settings.json', '.cursor/cli.json', '.grok/config.toml'];
416
431
 
417
432
  const legacyPaths = detectLegacyLayout(target);
418
433
  if (json) {
@@ -120,6 +120,14 @@ try {
120
120
  const updParsed = JSON.parse(updPlan.stdout);
121
121
  assert(updParsed.status === 'dry-run' && typeof updParsed.toVersion === 'string', 'update --dry-run --json returns machine-readable plan');
122
122
 
123
+ // Single-profile installs must pass validation on their own.
124
+ for (const profile of ['claude', 'cursor', 'codex', 'grok']) {
125
+ const solo = tempDir(`profile-${profile}`);
126
+ run(['.vibekit/scripts/mvck.mjs', 'install', solo, '--profile', profile]);
127
+ run(['.vibekit/scripts/validate-kit.mjs', solo]);
128
+ assert(true, `${profile}-only install passes validation`);
129
+ }
130
+
123
131
  console.log('\nInstall behavior tests passed.');
124
132
  } finally {
125
133
  if (!keep) {
@@ -33,30 +33,53 @@ function listFiles(rel) {
33
33
  return out.sort();
34
34
  }
35
35
 
36
+ // Surface presence: end-user repos may install only some profiles, so
37
+ // per-surface files are required only when that surface is installed.
38
+ // The kit source repo always validates every surface.
39
+ const isKitSourceRepo = readJson('package.json')?.name === 'minimal-vibe-coding-kit';
40
+ const surfacePresent = {
41
+ claude: isKitSourceRepo || exists('.claude'),
42
+ cursor: isKitSourceRepo || exists('.cursor'),
43
+ codex: isKitSourceRepo || exists('.agents') || exists('.codex') || exists('.codex-plugin'),
44
+ grok: isKitSourceRepo || exists('.grok')
45
+ };
46
+ for (const [surface, present] of Object.entries(surfacePresent)) {
47
+ if (!present) console.log(`INFO surface ${surface} not installed; skipping its checks`);
48
+ }
49
+
50
+ const KIT_SKILLS = [
51
+ 'autoresearch-coding', 'agentshield-security-review', 'daily-workflow-curator', 'vibekit-init',
52
+ 'clearthought', 'sequential-thinking', 'reviewing-4p-priorities', 'visual-design-loop',
53
+ 'path-sensitive-shell-safety', 'memento', 'coding-level', 'parallel-analysis', 'prompt-sharpener'
54
+ ];
55
+ const CURSOR_KIT_SKILLS = [
56
+ 'clearthought', 'sequential-thinking', 'reviewing-4p-priorities', 'path-sensitive-shell-safety',
57
+ 'memento', 'coding-level', 'parallel-analysis', 'prompt-sharpener'
58
+ ];
59
+
36
60
  const required = [
37
61
  'AGENTS.md', '.vibekit/init/CLAUDE-template.md', '.vibekit/init/FIRST_TIME_INIT.md', '.vibekit/init/FIRST_PROMPT.md', 'backbone.yml',
38
62
  '.vibekit/scripts/mvck.mjs', '.vibekit/scripts/init-backbone.mjs', '.vibekit/scripts/daily-enhance.mjs', '.vibekit/scripts/validate-kit.mjs',
39
63
  '.vibekit/scripts/doctor.mjs', '.vibekit/scripts/agentshield-probe.mjs', '.vibekit/scripts/vibekit-finalize.mjs',
40
- '.vibekit/skills/autoresearch-coding/SKILL.md', '.vibekit/skills/agentshield-security-review/SKILL.md', '.vibekit/skills/daily-workflow-curator/SKILL.md', '.vibekit/skills/vibekit-init/SKILL.md',
41
- '.vibekit/skills/clearthought/SKILL.md', '.vibekit/skills/sequential-thinking/SKILL.md', '.vibekit/skills/reviewing-4p-priorities/SKILL.md', '.vibekit/skills/visual-design-loop/SKILL.md',
42
- '.vibekit/skills/path-sensitive-shell-safety/SKILL.md', '.vibekit/skills/memento/SKILL.md', '.vibekit/skills/coding-level/SKILL.md', '.vibekit/skills/parallel-analysis/SKILL.md',
43
- '.vibekit/docs/templates/PRD_TEMPLATE.md', '.vibekit/docs/templates/CONTEXT_TEMPLATE.md',
44
- '.codex/README.md', '.codex/config.example.toml',
45
- '.claude/skills/autoresearch-coding/SKILL.md', '.claude/skills/agentshield-security-review/SKILL.md',
46
- '.claude/skills/daily-workflow-curator/SKILL.md', '.claude/skills/vibekit-init/SKILL.md',
47
- '.claude/skills/clearthought/SKILL.md', '.claude/skills/sequential-thinking/SKILL.md', '.claude/skills/reviewing-4p-priorities/SKILL.md', '.claude/skills/visual-design-loop/SKILL.md',
48
- '.claude/skills/path-sensitive-shell-safety/SKILL.md', '.claude/skills/memento/SKILL.md', '.claude/skills/coding-level/SKILL.md',
49
- '.claude/skills/parallel-analysis/SKILL.md',
50
- '.cursor/rules/001-vibe-core.mdc', '.cursor/skills/clearthought/SKILL.md', '.cursor/skills/sequential-thinking/SKILL.md', '.cursor/skills/reviewing-4p-priorities/SKILL.md',
51
- '.cursor/skills/path-sensitive-shell-safety/SKILL.md',
52
- '.cursor/skills/memento/SKILL.md', '.cursor/skills/coding-level/SKILL.md', '.cursor/skills/parallel-analysis/SKILL.md',
53
- '.agents/skills/autoresearch-coding/SKILL.md', '.agents/skills/agentshield-security-review/SKILL.md',
54
- '.agents/skills/daily-workflow-curator/SKILL.md', '.agents/skills/vibekit-init/SKILL.md',
55
- '.agents/skills/clearthought/SKILL.md', '.agents/skills/sequential-thinking/SKILL.md', '.agents/skills/reviewing-4p-priorities/SKILL.md', '.agents/skills/visual-design-loop/SKILL.md',
56
- '.agents/skills/path-sensitive-shell-safety/SKILL.md', '.agents/skills/memento/SKILL.md', '.agents/skills/coding-level/SKILL.md',
57
- '.agents/skills/parallel-analysis/SKILL.md',
58
- '.codex-plugin/plugin.json'
64
+ ...KIT_SKILLS.map((skill) => `.vibekit/skills/${skill}/SKILL.md`),
65
+ '.vibekit/docs/templates/PRD_TEMPLATE.md', '.vibekit/docs/templates/CONTEXT_TEMPLATE.md'
59
66
  ];
67
+ if (surfacePresent.claude) {
68
+ required.push(...KIT_SKILLS.map((skill) => `.claude/skills/${skill}/SKILL.md`));
69
+ }
70
+ if (surfacePresent.cursor) {
71
+ required.push('.cursor/rules/001-vibe-core.mdc', '.cursor/cli.json',
72
+ ...CURSOR_KIT_SKILLS.map((skill) => `.cursor/skills/${skill}/SKILL.md`));
73
+ }
74
+ if (surfacePresent.codex) {
75
+ required.push('.codex/README.md', '.codex/config.example.toml', '.codex/rules/vibekit.rules', '.codex-plugin/plugin.json',
76
+ ...KIT_SKILLS.map((skill) => `.agents/skills/${skill}/SKILL.md`));
77
+ }
78
+ if (surfacePresent.grok) {
79
+ required.push('.grok/README.md', '.grok/config.example.toml', '.grok/config.toml',
80
+ '.grok/rules/vibe-core.md', '.grok/rules/security.md', '.grok/rules/safe-delete.md',
81
+ ...KIT_SKILLS.map((skill) => `.grok/skills/${skill}/SKILL.md`));
82
+ }
60
83
 
61
84
  const reasoningSkillResources = {
62
85
  'clearthought': [
@@ -83,7 +106,12 @@ const reasoningSkillResources = {
83
106
  ]
84
107
  };
85
108
 
86
- for (const surface of ['.vibekit/skills', '.claude/skills', '.cursor/skills', '.agents/skills']) {
109
+ const reasoningSurfaceDirs = ['.vibekit/skills'];
110
+ if (surfacePresent.claude) reasoningSurfaceDirs.push('.claude/skills');
111
+ if (surfacePresent.cursor) reasoningSurfaceDirs.push('.cursor/skills');
112
+ if (surfacePresent.codex) reasoningSurfaceDirs.push('.agents/skills');
113
+ if (surfacePresent.grok) reasoningSurfaceDirs.push('.grok/skills');
114
+ for (const surface of reasoningSurfaceDirs) {
87
115
  for (const [skill, files] of Object.entries(reasoningSkillResources)) {
88
116
  for (const file of files) required.push(`${surface}/${skill}/${file}`);
89
117
  }
@@ -94,7 +122,6 @@ if (exists('README.md')) ok('optional README.md present');
94
122
  else console.log('INFO optional README.md not present in target project');
95
123
 
96
124
  // Kit-maintainer files: required in the kit source repo, intentionally absent in end-user installs.
97
- const isKitSourceRepo = readJson('package.json')?.name === 'minimal-vibe-coding-kit';
98
125
  if (isKitSourceRepo) {
99
126
  for (const rel of ['.vibekit/scripts/test-install.mjs', '.vibekit/scripts/pack-dry-run.mjs', '.vibekit/docs/RESEARCH_NOTES.md', '.vibekit/docs/AUTORESEARCH_LEDGER.md']) {
100
127
  exists(rel) ? ok(`kit-source file ${rel}`) : fail(`missing kit-source file ${rel}`);
@@ -116,18 +143,19 @@ if (exists('.vibekit/docs/AUTORESEARCH_LEDGER.md')) {
116
143
  }
117
144
 
118
145
  const skillMirrors = {
119
- 'autoresearch-coding': ['.claude/skills/autoresearch-coding', '.agents/skills/autoresearch-coding'],
120
- 'agentshield-security-review': ['.claude/skills/agentshield-security-review', '.agents/skills/agentshield-security-review'],
121
- 'daily-workflow-curator': ['.claude/skills/daily-workflow-curator', '.agents/skills/daily-workflow-curator'],
122
- 'vibekit-init': ['.claude/skills/vibekit-init', '.agents/skills/vibekit-init'],
123
- 'clearthought': ['.claude/skills/clearthought', '.cursor/skills/clearthought', '.agents/skills/clearthought'],
124
- 'sequential-thinking': ['.claude/skills/sequential-thinking', '.cursor/skills/sequential-thinking', '.agents/skills/sequential-thinking'],
125
- 'reviewing-4p-priorities': ['.claude/skills/reviewing-4p-priorities', '.cursor/skills/reviewing-4p-priorities', '.agents/skills/reviewing-4p-priorities'],
126
- 'path-sensitive-shell-safety': ['.claude/skills/path-sensitive-shell-safety', '.cursor/skills/path-sensitive-shell-safety', '.agents/skills/path-sensitive-shell-safety'],
127
- 'visual-design-loop': ['.claude/skills/visual-design-loop', '.agents/skills/visual-design-loop'],
128
- 'memento': ['.claude/skills/memento', '.cursor/skills/memento', '.agents/skills/memento'],
129
- 'coding-level': ['.claude/skills/coding-level', '.cursor/skills/coding-level', '.agents/skills/coding-level'],
130
- 'parallel-analysis': ['.claude/skills/parallel-analysis', '.cursor/skills/parallel-analysis', '.agents/skills/parallel-analysis']
146
+ 'autoresearch-coding': ['.claude/skills/autoresearch-coding', '.agents/skills/autoresearch-coding', '.grok/skills/autoresearch-coding'],
147
+ 'agentshield-security-review': ['.claude/skills/agentshield-security-review', '.agents/skills/agentshield-security-review', '.grok/skills/agentshield-security-review'],
148
+ 'daily-workflow-curator': ['.claude/skills/daily-workflow-curator', '.agents/skills/daily-workflow-curator', '.grok/skills/daily-workflow-curator'],
149
+ 'vibekit-init': ['.claude/skills/vibekit-init', '.agents/skills/vibekit-init', '.grok/skills/vibekit-init'],
150
+ 'clearthought': ['.claude/skills/clearthought', '.cursor/skills/clearthought', '.agents/skills/clearthought', '.grok/skills/clearthought'],
151
+ 'sequential-thinking': ['.claude/skills/sequential-thinking', '.cursor/skills/sequential-thinking', '.agents/skills/sequential-thinking', '.grok/skills/sequential-thinking'],
152
+ 'reviewing-4p-priorities': ['.claude/skills/reviewing-4p-priorities', '.cursor/skills/reviewing-4p-priorities', '.agents/skills/reviewing-4p-priorities', '.grok/skills/reviewing-4p-priorities'],
153
+ 'path-sensitive-shell-safety': ['.claude/skills/path-sensitive-shell-safety', '.cursor/skills/path-sensitive-shell-safety', '.agents/skills/path-sensitive-shell-safety', '.grok/skills/path-sensitive-shell-safety'],
154
+ 'visual-design-loop': ['.claude/skills/visual-design-loop', '.agents/skills/visual-design-loop', '.grok/skills/visual-design-loop'],
155
+ 'memento': ['.claude/skills/memento', '.cursor/skills/memento', '.agents/skills/memento', '.grok/skills/memento'],
156
+ 'coding-level': ['.claude/skills/coding-level', '.cursor/skills/coding-level', '.agents/skills/coding-level', '.grok/skills/coding-level'],
157
+ 'parallel-analysis': ['.claude/skills/parallel-analysis', '.cursor/skills/parallel-analysis', '.agents/skills/parallel-analysis', '.grok/skills/parallel-analysis'],
158
+ 'prompt-sharpener': ['.claude/skills/prompt-sharpener', '.cursor/skills/prompt-sharpener', '.agents/skills/prompt-sharpener', '.grok/skills/prompt-sharpener']
131
159
  };
132
160
 
133
161
  function validateSkillMirror(sourceRel, mirrorRel) {
@@ -164,8 +192,15 @@ function validateSkillMirror(sourceRel, mirrorRel) {
164
192
  if (mismatches === 0) ok(`skill mirror ${mirrorRel} matches ${sourceRel} (${sourceFiles.length} files)`);
165
193
  }
166
194
 
195
+ const mirrorSurface = (mirror) => mirror.startsWith('.claude/') ? 'claude'
196
+ : mirror.startsWith('.cursor/') ? 'cursor'
197
+ : mirror.startsWith('.agents/') ? 'codex'
198
+ : 'grok';
167
199
  for (const [skill, mirrors] of Object.entries(skillMirrors)) {
168
- for (const mirror of mirrors) validateSkillMirror(`.vibekit/skills/${skill}`, mirror);
200
+ for (const mirror of mirrors) {
201
+ if (!surfacePresent[mirrorSurface(mirror)]) continue;
202
+ validateSkillMirror(`.vibekit/skills/${skill}`, mirror);
203
+ }
169
204
  }
170
205
 
171
206
  function parseFrontmatter(text) {
@@ -179,7 +214,7 @@ function parseFrontmatter(text) {
179
214
  return fields;
180
215
  }
181
216
 
182
- for (const surface of ['.vibekit/skills', '.claude/skills', '.cursor/skills', '.agents/skills']) {
217
+ for (const surface of ['.vibekit/skills', '.claude/skills', '.cursor/skills', '.agents/skills', '.grok/skills']) {
183
218
  if (!exists(surface)) continue;
184
219
  for (const file of listFiles(surface).filter((f) => f.endsWith('SKILL.md'))) {
185
220
  const rel = `${surface}/${file}`;
@@ -198,7 +233,9 @@ function stripFrontmatter(text) {
198
233
 
199
234
  if (exists('.vibekit/commands')) {
200
235
  const canonicalCmds = listFiles('.vibekit/commands').filter((f) => f.endsWith('.md'));
201
- const cmdMirrors = { '.claude/commands': true, '.cursor/commands': true };
236
+ const cmdMirrors = {};
237
+ if (surfacePresent.claude) cmdMirrors['.claude/commands'] = true;
238
+ if (surfacePresent.cursor) cmdMirrors['.cursor/commands'] = true;
202
239
  for (const [mirrorDir, stripFm] of Object.entries(cmdMirrors)) {
203
240
  if (!exists(mirrorDir)) { warn(`command mirror dir missing: ${mirrorDir}`); continue; }
204
241
  for (const file of canonicalCmds) {
@@ -213,7 +250,7 @@ if (exists('.vibekit/commands')) {
213
250
  }
214
251
  }
215
252
 
216
- for (const rel of ['package.json', '.claude/settings.json', '.cursor/settings.json', '.codex-plugin/plugin.json']) {
253
+ for (const rel of ['package.json', '.claude/settings.json', '.cursor/settings.json', '.cursor/cli.json', '.codex-plugin/plugin.json']) {
217
254
  if (!exists(rel)) continue;
218
255
  try { JSON.parse(read(rel)); ok(`valid JSON ${rel}`); } catch (error) { fail(`invalid JSON ${rel}: ${error.message}`); }
219
256
  }
@@ -271,6 +308,33 @@ if (claudeSettings?.permissions?.deny && cursorSettings?.permissions?.deny) {
271
308
  if (parity) ok(`deny list category parity across .claude and .cursor (${claudeCats.size} categories)`);
272
309
  }
273
310
 
311
+ // Guardrail lint: catches known-dead deny patterns at the syntax level. It does
312
+ // not replace native checks — verify semantics with each tool's own validator
313
+ // (e.g. `codex execpolicy check`, `grok inspect`).
314
+ for (const [rel, settings] of [['.claude/settings.json', claudeSettings], ['.cursor/settings.json', cursorSettings]]) {
315
+ const deny = settings?.permissions?.deny;
316
+ if (!Array.isArray(deny)) continue;
317
+ const piped = deny.filter((rule) => rule.includes('|'));
318
+ piped.length === 0
319
+ ? ok(`${rel} deny rules avoid pipe-spanning patterns (subcommands are matched independently)`)
320
+ : fail(`${rel} deny rules span a pipe and never match: ${piped.join(', ')}`);
321
+ const yesFirst = deny.some((rule) => rule.startsWith('Bash(npx --yes') || rule.startsWith('Bash(npx -y'));
322
+ yesFirst
323
+ ? ok(`${rel} denies leading npx --yes/-y forms`)
324
+ : fail(`${rel} missing deny for leading npx --yes/-y forms`);
325
+ }
326
+ if (surfacePresent.cursor && exists('.cursor/cli.json')) {
327
+ const cursorCli = readJson('.cursor/cli.json');
328
+ Array.isArray(cursorCli?.permissions?.deny) && cursorCli.permissions.deny.includes('Shell(rm)')
329
+ ? ok('.cursor/cli.json denies Shell(rm)')
330
+ : fail('.cursor/cli.json missing permissions.deny entry Shell(rm)');
331
+ }
332
+ if (surfacePresent.codex) requireText('.codex/rules/vibekit.rules', 'decision = "forbidden"', 'Codex rules include forbidden decisions');
333
+ if (surfacePresent.grok) {
334
+ requireText('.grok/config.toml', '[permission]', 'Grok project config declares [permission] rules');
335
+ requireText('.grok/config.toml', '"Bash(rm *)"', 'Grok project config denies rm');
336
+ }
337
+
274
338
  if (pkg?.name === 'minimal-vibe-coding-kit') {
275
339
  for (const rel of ['SECURITY.md', 'CONTRIBUTING.md', 'CODE_OF_CONDUCT.md', '.github/dependabot.yml', '.github/workflows/vibekit-validate.yml', '.vibekit/docs/backbone.schema.json']) {
276
340
  exists(rel) ? ok(`release safety file ${rel}`) : fail(`missing release safety file ${rel}`);
@@ -381,7 +445,8 @@ function validateBackboneSchema(text) {
381
445
  if (!surfacePath || surfacePath === 'null') continue;
382
446
  const cleanPath = surfacePath.replace(/^["']|["']$/g, '');
383
447
  if (exists(cleanPath)) ok(`agent_surfaces path exists: ${cleanPath}`);
384
- else fail(`agent_surfaces path missing: ${cleanPath}`);
448
+ else if (isKitSourceRepo) fail(`agent_surfaces path missing: ${cleanPath}`);
449
+ else warn(`agent_surfaces path missing: ${cleanPath} (profile-scoped install?)`);
385
450
  }
386
451
  }
387
452
 
@@ -401,7 +466,7 @@ const riskyPatterns = [
401
466
  { pattern: 'ignore previous' + ' instructions', message: 'prompt injection phrase' }
402
467
  ];
403
468
 
404
- const scanDirs = ['.claude', '.cursor', '.agents', '.codex-plugin', '.vibekit/skills', '.vibekit/commands', '.vibekit/scripts', 'AGENTS.md', '.vibekit/init/CLAUDE-template.md'];
469
+ const scanDirs = ['.claude', '.cursor', '.agents', '.grok', '.codex-plugin', '.vibekit/skills', '.vibekit/commands', '.vibekit/scripts', 'AGENTS.md', '.vibekit/init/CLAUDE-template.md'];
405
470
  function walk(item) {
406
471
  const p = path.join(root, item);
407
472
  if (!fs.existsSync(p)) return [];