minimal-vibe-coding-kit 0.3.0 → 0.4.1

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 (123) hide show
  1. package/.agents/skills/agentshield-security-review/SKILL.md +6 -6
  2. package/.agents/skills/agentshield-security-review/references/native-install.md +10 -10
  3. package/.agents/skills/agentshield-security-review/references/report-template.md +1 -1
  4. package/.agents/skills/agentshield-security-review/scripts/agentshield_repo_probe.py +3 -3
  5. package/.agents/skills/autoresearch-coding/README.md +1 -1
  6. package/.agents/skills/autoresearch-coding/SKILL.md +4 -4
  7. package/.agents/skills/coding-level/SKILL.md +8 -1
  8. package/.agents/skills/daily-workflow-curator/SKILL.md +3 -3
  9. package/.agents/skills/parallel-analysis/SKILL.md +160 -0
  10. package/.agents/skills/path-sensitive-shell-safety/SKILL.md +69 -0
  11. package/.agents/skills/path-sensitive-shell-safety/references/workflow.md +127 -0
  12. package/.agents/skills/vibekit-init/SKILL.md +6 -6
  13. package/.claude/commands/vibe-finalize.md +1 -1
  14. package/.claude/rules/safe-delete.md +11 -0
  15. package/.claude/rules/security.md +2 -0
  16. package/.claude/rules/tooling.md +1 -1
  17. package/.claude/skills/agentshield-security-review/SKILL.md +6 -6
  18. package/.claude/skills/agentshield-security-review/references/native-install.md +10 -10
  19. package/.claude/skills/agentshield-security-review/references/report-template.md +1 -1
  20. package/.claude/skills/agentshield-security-review/scripts/agentshield_repo_probe.py +3 -3
  21. package/.claude/skills/autoresearch-coding/README.md +1 -1
  22. package/.claude/skills/autoresearch-coding/SKILL.md +4 -4
  23. package/.claude/skills/coding-level/SKILL.md +8 -1
  24. package/.claude/skills/daily-workflow-curator/SKILL.md +3 -3
  25. package/.claude/skills/parallel-analysis/SKILL.md +160 -0
  26. package/.claude/skills/path-sensitive-shell-safety/SKILL.md +69 -0
  27. package/.claude/skills/path-sensitive-shell-safety/references/workflow.md +127 -0
  28. package/.claude/skills/vibekit-init/SKILL.md +6 -6
  29. package/.codex-plugin/plugin.json +2 -2
  30. package/.cursor/commands/vibe-finalize.md +1 -1
  31. package/.cursor/rules/001-vibe-core.mdc +1 -1
  32. package/.cursor/rules/010-init.mdc +1 -1
  33. package/.cursor/rules/020-security-agentshield.mdc +2 -2
  34. package/.cursor/rules/030-autoresearch-loop.mdc +1 -1
  35. package/.cursor/rules/040-safe-delete.mdc +16 -0
  36. package/.cursor/skills/coding-level/SKILL.md +8 -1
  37. package/.cursor/skills/parallel-analysis/SKILL.md +160 -0
  38. package/.cursor/skills/path-sensitive-shell-safety/SKILL.md +69 -0
  39. package/.cursor/skills/path-sensitive-shell-safety/references/workflow.md +127 -0
  40. package/.vibekit/commands/vibe-finalize.md +3 -0
  41. package/{.vbkit-docs → .vibekit/docs}/AUTORESEARCH_LEDGER.md +3 -3
  42. package/{.vbkit-docs → .vibekit/docs}/BACKBONE_REFERENCE.md +1 -1
  43. package/{.vbkit-docs → .vibekit/docs}/INSTALL.md +28 -16
  44. package/{.vbkit-docs → .vibekit/docs}/RESEARCH_NOTES.md +1 -1
  45. package/{.vbkit-docs → .vibekit/docs}/SECURITY_MODEL.md +2 -2
  46. package/{.vbkit-docs → .vibekit/docs}/TOOLING_GUIDE.md +2 -2
  47. package/{.vbkit-docs → .vibekit/docs}/templates/CONTEXT_TEMPLATE.md +1 -1
  48. package/{.vbkit-docs → .vibekit/docs}/templates/PRD_TEMPLATE.md +1 -1
  49. package/{CLAUDE-template.md → .vibekit/init/CLAUDE-template.md} +3 -1
  50. package/{FIRST_PROMPT.md → .vibekit/init/FIRST_PROMPT.md} +6 -6
  51. package/{FIRST_TIME_INIT.md → .vibekit/init/FIRST_TIME_INIT.md} +46 -14
  52. package/{.vbkit-scripts → .vibekit/scripts}/agentshield-probe.mjs +1 -1
  53. package/{.vbkit-scripts → .vibekit/scripts}/daily-enhance.mjs +3 -3
  54. package/{.vbkit-scripts → .vibekit/scripts}/doctor.mjs +22 -7
  55. package/{.vbkit-scripts → .vibekit/scripts}/init-backbone.mjs +31 -22
  56. package/{.vbkit-scripts → .vibekit/scripts}/mvck.mjs +61 -25
  57. package/{.vbkit-scripts → .vibekit/scripts}/test-install.mjs +32 -18
  58. package/{.vbkit-scripts → .vibekit/scripts}/validate-kit.mjs +47 -31
  59. package/{.vbkit-scripts → .vibekit/scripts}/vibekit-finalize.mjs +7 -7
  60. package/{skills → .vibekit/skills}/agentshield-security-review/SKILL.md +6 -6
  61. package/{skills → .vibekit/skills}/agentshield-security-review/references/native-install.md +10 -10
  62. package/{skills → .vibekit/skills}/agentshield-security-review/references/report-template.md +1 -1
  63. package/{skills → .vibekit/skills}/agentshield-security-review/scripts/agentshield_repo_probe.py +3 -3
  64. package/{skills → .vibekit/skills}/autoresearch-coding/README.md +1 -1
  65. package/{skills → .vibekit/skills}/autoresearch-coding/SKILL.md +4 -4
  66. package/{skills → .vibekit/skills}/coding-level/SKILL.md +8 -1
  67. package/{skills → .vibekit/skills}/daily-workflow-curator/SKILL.md +3 -3
  68. package/.vibekit/skills/parallel-analysis/SKILL.md +160 -0
  69. package/.vibekit/skills/path-sensitive-shell-safety/SKILL.md +69 -0
  70. package/.vibekit/skills/path-sensitive-shell-safety/references/workflow.md +127 -0
  71. package/{skills → .vibekit/skills}/vibekit-init/SKILL.md +6 -6
  72. package/AGENTS.md +6 -2
  73. package/CHANGELOG.md +24 -2
  74. package/CONTRIBUTING.md +3 -3
  75. package/README.md +147 -372
  76. package/backbone.yml +8 -7
  77. package/bin/mvck.js +1 -1
  78. package/bin/vibe-kit.js +1 -1
  79. package/docs/README.vi.md +268 -0
  80. package/install.ps1 +1 -1
  81. package/install.sh +5 -3
  82. package/package.json +23 -19
  83. package/.vbkit-commands/vibe-finalize.md +0 -3
  84. package/README.vi.md +0 -431
  85. /package/{.vbkit-commands → .vibekit/commands}/autoresearch-coding.md +0 -0
  86. /package/{.vbkit-commands → .vibekit/commands}/council.md +0 -0
  87. /package/{.vbkit-commands → .vibekit/commands}/daily-enhance.md +0 -0
  88. /package/{.vbkit-commands → .vibekit/commands}/init-vibe.md +0 -0
  89. /package/{.vbkit-commands → .vibekit/commands}/security-scan.md +0 -0
  90. /package/{.vbkit-docs → .vibekit/docs}/backbone.schema.json +0 -0
  91. /package/{.vbkit-scripts → .vibekit/scripts}/pack-dry-run.mjs +0 -0
  92. /package/{skills → .vibekit/skills}/agentshield-security-review/agents/openai.yaml +0 -0
  93. /package/{skills → .vibekit/skills}/agentshield-security-review/references/review-checklist.md +0 -0
  94. /package/{skills → .vibekit/skills}/autoresearch-coding/references/experiment-contract.md +0 -0
  95. /package/{skills → .vibekit/skills}/autoresearch-coding/references/metric-extraction.md +0 -0
  96. /package/{skills → .vibekit/skills}/autoresearch-coding/references/result-ledger.md +0 -0
  97. /package/{skills → .vibekit/skills}/autoresearch-coding/scripts/log_result.py +0 -0
  98. /package/{skills → .vibekit/skills}/autoresearch-coding/scripts/run_logged.py +0 -0
  99. /package/{skills → .vibekit/skills}/clearthought/SKILL.md +0 -0
  100. /package/{skills → .vibekit/skills}/clearthought/examples/decision-framework.md +0 -0
  101. /package/{skills → .vibekit/skills}/clearthought/examples/metagame-examples.md +0 -0
  102. /package/{skills → .vibekit/skills}/clearthought/examples/sequential-thinking.md +0 -0
  103. /package/{skills → .vibekit/skills}/clearthought/references/output-schemas.md +0 -0
  104. /package/{skills → .vibekit/skills}/clearthought/references/parameter-reference.md +0 -0
  105. /package/{skills → .vibekit/skills}/coding-level/references/level-0.md +0 -0
  106. /package/{skills → .vibekit/skills}/coding-level/references/level-1.md +0 -0
  107. /package/{skills → .vibekit/skills}/coding-level/references/level-2.md +0 -0
  108. /package/{skills → .vibekit/skills}/coding-level/references/level-3.md +0 -0
  109. /package/{skills → .vibekit/skills}/coding-level/references/level-4.md +0 -0
  110. /package/{skills → .vibekit/skills}/coding-level/references/level-5.md +0 -0
  111. /package/{skills → .vibekit/skills}/memento/SKILL.md +0 -0
  112. /package/{skills → .vibekit/skills}/reviewing-4p-priorities/SKILL.md +0 -0
  113. /package/{skills → .vibekit/skills}/reviewing-4p-priorities/examples.md +0 -0
  114. /package/{skills → .vibekit/skills}/sequential-thinking/SKILL.md +0 -0
  115. /package/{skills → .vibekit/skills}/sequential-thinking/examples/adaptive-depth.md +0 -0
  116. /package/{skills → .vibekit/skills}/sequential-thinking/examples/branching-exploration.md +0 -0
  117. /package/{skills → .vibekit/skills}/sequential-thinking/examples/linear-reasoning.md +0 -0
  118. /package/{skills → .vibekit/skills}/sequential-thinking/examples/revision-pattern.md +0 -0
  119. /package/{skills → .vibekit/skills}/sequential-thinking/references/output-schema.md +0 -0
  120. /package/{skills → .vibekit/skills}/sequential-thinking/references/parameters.md +0 -0
  121. /package/{skills → .vibekit/skills}/sequential-thinking/references/patterns.md +0 -0
  122. /package/{skills → .vibekit/skills}/visual-design-loop/SKILL.md +0 -0
  123. /package/{skills → .vibekit/skills}/visual-design-loop/agents/openai.yaml +0 -0
@@ -5,7 +5,7 @@ Use one of these after installing the kit into a project.
5
5
  ## Universal first prompt
6
6
 
7
7
  ```text
8
- Read FIRST_TIME_INIT.md and initialize this repo with Minimal Vibe Coding Kit.
8
+ Read .vibekit/init/FIRST_TIME_INIT.md and initialize this repo with Minimal Vibe Coding Kit.
9
9
  First print the requirements you will check. Then run detection, propose one diff for backbone.yml and managed instruction blocks, and wait for my yes before writing.
10
10
  Include inferred project conventions for naming, architecture, resources, localization, generated definitions, and per-app/package differences.
11
11
  After approval, write the files, run validation, and summarize what changed.
@@ -20,13 +20,13 @@ Use /init-vibe. Keep CLAUDE.md short. Import shared AGENTS.md. Do not overwrite
20
20
  ## Cursor
21
21
 
22
22
  ```text
23
- Read FIRST_TIME_INIT.md and .cursor/rules. Initialize backbone.yml. Do not replace existing Cursor rules; add missing Minimal Vibe Coding Kit rules only.
23
+ Read .vibekit/init/FIRST_TIME_INIT.md and .cursor/rules. Initialize backbone.yml. Do not replace existing Cursor rules; add missing Minimal Vibe Coding Kit rules only.
24
24
  ```
25
25
 
26
26
  ## Codex
27
27
 
28
28
  ```text
29
- Read AGENTS.md and FIRST_TIME_INIT.md. Use the vibekit-init skill if available. Initialize backbone.yml, include inferred project conventions, keep AGENTS.md concise, and wait for approval before writing.
29
+ Read AGENTS.md and .vibekit/init/FIRST_TIME_INIT.md. Use the vibekit-init skill if available. Initialize backbone.yml, include inferred project conventions, keep AGENTS.md concise, and wait for approval before writing.
30
30
  ```
31
31
 
32
32
  ## Autoresearch improvement loop for this kit
@@ -34,9 +34,9 @@ Read AGENTS.md and FIRST_TIME_INIT.md. Use the vibekit-init skill if available.
34
34
  ```text
35
35
  Use the autoresearch-coding skill.
36
36
  Goal: improve this Minimal Vibe Coding Kit for existing projects in any language.
37
- Metric command: node .vbkit-scripts/validate-kit.mjs .
37
+ Metric command: node .vibekit/scripts/validate-kit.mjs .
38
38
  Direction: higher.
39
- Editable paths: README.md .vbkit-docs .vbkit-scripts skills .vbkit-commands .claude .cursor .agents .codex-plugin .github backbone.yml AGENTS.md CLAUDE-template.md 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 .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
  ```
@@ -50,5 +50,5 @@ Use the agentshield-security-review skill. Run the read-only probe first. Then,
50
50
  ## Daily improvement prompt
51
51
 
52
52
  ```text
53
- Use the daily-workflow-curator skill. Run node .vbkit-scripts/daily-enhance.mjs . --write-report and node .vbkit-scripts/validate-kit.mjs . Then propose updates to skills, rules, workflows, and backbone.yml. Do not write any change until I approve a diff.
53
+ Use the daily-workflow-curator skill. Run node .vibekit/scripts/daily-enhance.mjs . --write-report and node .vibekit/scripts/validate-kit.mjs . Then propose updates to skills, rules, workflows, and backbone.yml. Do not write any change until I approve a diff.
54
54
  ```
@@ -1,8 +1,8 @@
1
- # FIRST_TIME_INIT.md - bootstrap runbook
1
+ # .vibekit/init/FIRST_TIME_INIT.md - bootstrap runbook
2
2
 
3
3
  Audience: Claude, Cursor, Codex, or any AI coding agent in a repo that just received Minimal Vibe Coding Kit.
4
4
 
5
- Keep this flow short. Detailed schema notes live in `.vbkit-docs/BACKBONE_REFERENCE.md`.
5
+ Keep this flow short. Detailed schema notes live in `.vibekit/docs/BACKBONE_REFERENCE.md`.
6
6
 
7
7
  ## Requirements to print before starting
8
8
 
@@ -10,17 +10,17 @@ Before writing anything, print this checklist and mark each item as found, missi
10
10
 
11
11
  1. `backbone.yml` exists.
12
12
  2. `AGENTS.md` exists or will be created/merged.
13
- 3. `CLAUDE.md` exists or will be created from `CLAUDE-template.md` when Claude support is installed.
13
+ 3. `CLAUDE.md` exists or will be created from `.vibekit/init/CLAUDE-template.md` when Claude support is installed.
14
14
  4. At least one harness folder exists: `.claude/`, `.cursor/`, `.agents/`, or `.codex-plugin/`.
15
15
  5. Git status is known. If user changes exist, do not overwrite them.
16
- 6. A validation command is inferred or set to `node .vbkit-scripts/validate-kit.mjs .` for the kit itself.
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.
18
18
  8. Existing naming, architecture, resource, and localization conventions are scanned or marked missing.
19
19
 
20
20
  ## Canonical prompt
21
21
 
22
22
  ```text
23
- Read FIRST_TIME_INIT.md and initialize this repo with Minimal Vibe Coding Kit.
23
+ Read .vibekit/init/FIRST_TIME_INIT.md and initialize this repo with Minimal Vibe Coding Kit.
24
24
  First print the requirements you will check. Then run detection, propose one diff for backbone.yml and managed instruction blocks, and wait for my yes before writing.
25
25
  Include inferred project conventions for naming, architecture, resources, localization, generated definitions, and per-app/package differences.
26
26
  After approval, write the files, run validation, and summarize what changed.
@@ -64,11 +64,43 @@ Ask (keep it short):
64
64
 
65
65
  Then:
66
66
 
67
- - If `project.prd` is `none`, propose creating `.vbkit-docs/PRD.md` from `.vbkit-docs/templates/PRD_TEMPLATE.md` using the answers, and set `project.prd` to that path in the same diff.
67
+ - If `project.prd` is `none`, propose creating `.vibekit/docs/PRD.md` from `.vibekit/docs/templates/PRD_TEMPLATE.md` using the answers, and set `project.prd` to that path in the same diff.
68
68
  - If a PRD already exists, read it, link it in `project.prd`, and offer to refresh it without overwriting unapproved content.
69
- - Record domain terms and acronyms in `.vbkit-docs/CONTEXT.md` (scaffold from `.vbkit-docs/templates/CONTEXT_TEMPLATE.md`) and link it in `project.context`, so future agents stay concise.
69
+ - Record domain terms and acronyms in `.vibekit/docs/CONTEXT.md` (scaffold from `.vibekit/docs/templates/CONTEXT_TEMPLATE.md`) and link it in `project.context`, so future agents stay concise.
70
70
  - Keep the PRD short: it captures intent and focus, not a full specification.
71
71
 
72
+ ## Setup preferences
73
+
74
+ Ask these two questions right after the PRD interview. Persist both answers as `backbone.yml` `conventions.custom_rules` entries in the same proposed diff.
75
+
76
+ ### 1. Safe delete (trash instead of rm)
77
+
78
+ 1. Detect first: run `command -v trash` (read-only).
79
+ 2. If `trash` is available, ask: "Use `trash` instead of `rm` for deletions so they are recoverable? (recommended: yes)"
80
+ 3. If `trash` is missing, recommend installing it, then ask the same question:
81
+ - macOS 14 or newer: already built in at `/usr/bin/trash`, nothing to install.
82
+ - Older macOS: `brew install trash` (https://formulae.brew.sh/formula/trash)
83
+ - Linux: `sudo apt install trash-cli` or `pip install trash-cli` (https://github.com/andreafrancia/trash-cli)
84
+ - Any OS with Node.js: `npm install --global trash-cli` (https://github.com/sindresorhus/trash-cli)
85
+ 4. Record the answer as a custom rule:
86
+ - yes: `Deletion safety: use trash instead of rm; permanent deletes require explicit approval of the exact paths.`
87
+ - no: `Deletion safety: user declined trash; list the exact paths and wait for approval before any rm.`
88
+
89
+ ### 2. Default coding level
90
+
91
+ Show this table exactly and ask: "Which explanation level should I use by default? Reply 0-5. You can change it anytime with `/coding-level N`."
92
+
93
+ | N | Level | Short description |
94
+ | --- | --- | --- |
95
+ | 0 | ELI5 | New to code. Everything in plain words, no jargon. |
96
+ | 1 | Junior | Knows the basics. Explains the why behind every step. |
97
+ | 2 | Mid-level | Comfortable coder. Patterns, architecture, trade-offs. |
98
+ | 3 | Senior | Concise. Trade-offs, edge cases, operational concerns. |
99
+ | 4 | Tech Lead | Strategic. Risk, ROI, team and organizational impact. |
100
+ | 5 | God | Expert peer. Minimal explanation, maximum signal. |
101
+
102
+ Record the answer as a custom rule: `Default coding level: N (<Level>) - apply this explanation depth every session; change with /coding-level N.`
103
+
72
104
  ## FIRST_TIME_INIT_RULES
73
105
 
74
106
  Create project rules from evidence in the existing repo, not from a fixed language or framework template.
@@ -85,7 +117,7 @@ Create project rules from evidence in the existing repo, not from a fixed langua
85
117
  Optional helper:
86
118
 
87
119
  ```bash
88
- node .vbkit-scripts/init-backbone.mjs . --propose
120
+ node .vibekit/scripts/init-backbone.mjs . --propose
89
121
  ```
90
122
 
91
123
  ## Propose before writing
@@ -117,14 +149,14 @@ Apply this proposed backbone and convention rules? Reply yes, edit, or abort.
117
149
  CLI helper after approval:
118
150
 
119
151
  ```bash
120
- node .vbkit-scripts/init-backbone.mjs . --write --yes
152
+ node .vibekit/scripts/init-backbone.mjs . --write --yes
121
153
  ```
122
154
 
123
155
  ## Merge rules
124
156
 
125
157
  ### CLAUDE.md
126
158
 
127
- - If no `CLAUDE.md` exists, copy `CLAUDE-template.md` to `CLAUDE.md`.
159
+ - If no `CLAUDE.md` exists, copy `.vibekit/init/CLAUDE-template.md` to `CLAUDE.md`.
128
160
  - If `CLAUDE.md` exists, append or replace only this managed block:
129
161
 
130
162
  ```markdown
@@ -134,7 +166,7 @@ node .vbkit-scripts/init-backbone.mjs . --write --yes
134
166
  ## Minimal Vibe Coding Kit
135
167
 
136
168
  - Read `backbone.yml` before changing code.
137
- - If `meta.template_status` is `uninitialized`, follow `FIRST_TIME_INIT.md` and wait for approval before writing.
169
+ - If `meta.template_status` is `uninitialized`, follow `.vibekit/init/FIRST_TIME_INIT.md` and wait for approval before writing.
138
170
  - After init, follow `backbone.yml` `conventions` before adding new project patterns.
139
171
  - Prefer project skills for multi-step workflows: `/autoresearch-coding`, `/security-scan`, `/daily-enhance`.
140
172
  <!-- END: minimal-vibe-coding-kit -->
@@ -150,10 +182,10 @@ node .vbkit-scripts/init-backbone.mjs . --write --yes
150
182
 
151
183
  Once init is `initialized` and the first prompt is complete, the bootstrap files are no longer needed in the project. Offer to graduate them so the repo stays clean.
152
184
 
153
- - Preview: `node .vbkit-scripts/vibekit-finalize.mjs . --propose`
154
- - Apply after the user agrees: `node .vbkit-scripts/vibekit-finalize.mjs . --write --yes`
185
+ - Preview: `node .vibekit/scripts/vibekit-finalize.mjs . --propose`
186
+ - Apply after the user agrees: `node .vibekit/scripts/vibekit-finalize.mjs . --write --yes`
155
187
 
156
- This moves one-time files (`FIRST_TIME_INIT.md`, `FIRST_PROMPT.md`, `PUSH_TO_GITHUB.md`, `CLAUDE-template.md` once `CLAUDE.md` exists) into the folder named by `automation.finalize.cleanup_dir` (default `_vibekit-cleanup/`), writes a `RESTORE.md`, and sets `automation.finalize.marker`. It is idempotent, reversible with `--restore --write`, and refuses to run on the kit source repo. The durable project map is `backbone.yml`; none of the graduated files are needed to keep working. Delete the cleanup folder when satisfied.
188
+ This moves one-time files (`.vibekit/init/FIRST_TIME_INIT.md`, `.vibekit/init/FIRST_PROMPT.md`, `.vibekit/init/PUSH_TO_GITHUB.md`, `.vibekit/init/CLAUDE-template.md` once `CLAUDE.md` exists) into the folder named by `automation.finalize.cleanup_dir` (default `_vibekit-cleanup/`), writes a `RESTORE.md`, and sets `automation.finalize.marker`. It is idempotent, reversible with `--restore --write`, and refuses to run on the kit source repo. The durable project map is `backbone.yml`; none of the graduated files are needed to keep working. Delete the cleanup folder when satisfied.
157
189
 
158
190
  ## Guardrails
159
191
 
@@ -5,7 +5,7 @@ import { spawnSync } from 'node:child_process';
5
5
 
6
6
  const target = path.resolve(process.argv[2] || process.cwd());
7
7
  const extra = process.argv.slice(3);
8
- const probe = path.join(target, 'skills/agentshield-security-review/scripts/agentshield_repo_probe.py');
8
+ const probe = path.join(target, '.vibekit/skills/agentshield-security-review/scripts/agentshield_repo_probe.py');
9
9
 
10
10
  if (!fs.existsSync(probe)) {
11
11
  console.error(`AgentShield probe not found: ${path.relative(target, probe)}`);
@@ -25,17 +25,17 @@ function list(dir) {
25
25
  }
26
26
 
27
27
  const checks = [];
28
- for (const rel of ['backbone.yml', 'AGENTS.md', 'FIRST_TIME_INIT.md', 'skills/autoresearch-coding/SKILL.md', 'skills/agentshield-security-review/SKILL.md']) {
28
+ for (const rel of ['backbone.yml', 'AGENTS.md', '.vibekit/init/FIRST_TIME_INIT.md', '.vibekit/skills/autoresearch-coding/SKILL.md', '.vibekit/skills/agentshield-security-review/SKILL.md']) {
29
29
  checks.push(`- ${rel}: ${exists(rel) ? 'found' : 'missing'}`);
30
30
  }
31
31
 
32
- const skills = list('skills').filter((f) => f.endsWith('SKILL.md'));
32
+ const skills = list('.vibekit/skills').filter((f) => f.endsWith('SKILL.md'));
33
33
  const claudeSkills = list('.claude/skills').filter((f) => f.endsWith('SKILL.md'));
34
34
  const codexSkills = list('.agents/skills').filter((f) => f.endsWith('SKILL.md'));
35
35
  const cursorRules = list('.cursor/rules').filter((f) => f.endsWith('.mdc'));
36
36
 
37
37
  let validation = 'not run';
38
- const validator = path.join(target, '.vbkit-scripts/validate-kit.mjs');
38
+ const validator = path.join(target, '.vibekit/scripts/validate-kit.mjs');
39
39
  if (fs.existsSync(validator)) {
40
40
  const result = spawnSync(process.execPath, [validator, target], { encoding: 'utf8' });
41
41
  validation = result.stdout.trim() || result.stderr.trim() || `exit ${result.status}`;
@@ -122,7 +122,7 @@ function runNodeScript(rel, extra = []) {
122
122
  }
123
123
 
124
124
  function runProbe() {
125
- const nodeProbeRel = '.vbkit-scripts/agentshield-probe.mjs';
125
+ const nodeProbeRel = '.vibekit/scripts/agentshield-probe.mjs';
126
126
  const nodeProbe = path.join(target, nodeProbeRel);
127
127
  if (fs.existsSync(nodeProbe)) {
128
128
  const result = spawnSync(process.execPath, [nodeProbe, target, '--json'], { encoding: 'utf8' });
@@ -134,7 +134,7 @@ function runProbe() {
134
134
  };
135
135
  }
136
136
 
137
- const probe = path.join(target, 'skills/agentshield-security-review/scripts/agentshield_repo_probe.py');
137
+ const probe = path.join(target, '.vibekit/skills/agentshield-security-review/scripts/agentshield_repo_probe.py');
138
138
  if (!fs.existsSync(probe)) return { found: false, status: null, output: 'missing' };
139
139
  for (const python of ['python', 'python3']) {
140
140
  const result = spawnSync(python, [probe, target, '--json'], { encoding: 'utf8' });
@@ -153,6 +153,13 @@ function statusLine(ok, label, detail) {
153
153
  return `${ok ? 'PASS' : 'WARN'} ${label}${detail ? ` - ${detail}` : ''}`;
154
154
  }
155
155
 
156
+ const TRASH_INSTALL_HINT = 'macOS 14+ has it built in; older macOS: brew install trash; Linux: sudo apt install trash-cli; any OS with Node: npm i -g trash-cli';
157
+
158
+ function trashAvailable() {
159
+ const result = spawnSync('trash', ['--help'], { encoding: 'utf8' });
160
+ return !(result.error && result.error.code === 'ENOENT');
161
+ }
162
+
156
163
  const backbone = parseBackbone();
157
164
  const packageJson = readJson('package.json');
158
165
  const isKitTemplate = packageJson?.name === 'minimal-vibe-coding-kit';
@@ -161,7 +168,7 @@ const kitVersion = isKitTemplate
161
168
  : exists('.vibekit/KIT_VERSION') ? read('.vibekit/KIT_VERSION').trim() : 'unknown';
162
169
  const surfaces = {
163
170
  agents: exists('AGENTS.md'),
164
- claude: exists('CLAUDE.md') || exists('CLAUDE-template.md') || exists('.claude'),
171
+ claude: exists('CLAUDE.md') || exists('.vibekit/init/CLAUDE-template.md') || exists('.claude'),
165
172
  cursor: exists('.cursor/rules'),
166
173
  codex: exists('.agents') || exists('.codex-plugin/plugin.json')
167
174
  };
@@ -180,7 +187,7 @@ const legacySurfaces = [
180
187
  ].filter(exists);
181
188
  const nativeReasoningSkills = ['clearthought', 'sequential-thinking', 'reviewing-4p-priorities'];
182
189
  const nativeSkillSurfaces = {
183
- shared: 'skills',
190
+ shared: '.vibekit/skills',
184
191
  claude: '.claude/skills',
185
192
  codex: '.agents/skills',
186
193
  cursor: '.cursor/skills'
@@ -192,10 +199,13 @@ for (const [surface, dir] of Object.entries(nativeSkillSurfaces)) {
192
199
  }
193
200
  }
194
201
  const commands = commandMap();
195
- const validation = runNodeScript('.vbkit-scripts/validate-kit.mjs');
202
+ const validation = runNodeScript('.vibekit/scripts/validate-kit.mjs');
196
203
  const probe = runProbe();
204
+ const hasTrash = trashAvailable();
197
205
  const risks = [];
198
206
 
207
+ if (!hasTrash) risks.push(`trash command not found; agents fall back to asking before rm. Install it for recoverable deletes (${TRASH_INSTALL_HINT}).`);
208
+
199
209
  if (!backbone) risks.push('backbone.yml is missing.');
200
210
  else if (backbone.templateStatus !== 'initialized' && !isKitTemplate) risks.push(`backbone.yml is ${backbone.templateStatus || 'unknown'}; run init before relying on it.`);
201
211
  if (!Object.values(surfaces).some(Boolean)) risks.push('No AI agent surfaces were detected.');
@@ -238,8 +248,12 @@ const report = {
238
248
  command: probe.command,
239
249
  status: probe.status
240
250
  },
251
+ safeDelete: {
252
+ trashAvailable: hasTrash,
253
+ installHint: hasTrash ? null : TRASH_INSTALL_HINT
254
+ },
241
255
  aiRulesLoaded: {
242
- sharedSkills: listFiles('skills').filter((f) => f.endsWith('SKILL.md')).length,
256
+ sharedSkills: listFiles('.vibekit/skills').filter((f) => f.endsWith('SKILL.md')).length,
243
257
  claudeSkills: listFiles('.claude/skills').filter((f) => f.endsWith('SKILL.md')).length,
244
258
  codexSkills: listFiles('.agents/skills').filter((f) => f.endsWith('SKILL.md')).length,
245
259
  cursorSkills: listFiles('.cursor/skills').filter((f) => f.endsWith('SKILL.md')).length,
@@ -256,7 +270,8 @@ function renderMarkdown(data) {
256
270
  statusLine(Boolean(commands.validate), 'validation command detected', commands.validate || 'missing'),
257
271
  statusLine(protectedSane, 'protected paths are sane', `${data.protectedPaths.length} entries`),
258
272
  statusLine(validation.found && validation.status === 0, 'validation runs', validation.found ? `exit ${validation.status}` : 'missing'),
259
- statusLine(probe.found && probe.status === 0, 'AgentShield probe runs', probe.found ? `exit ${probe.status}` : 'missing')
273
+ statusLine(probe.found && probe.status === 0, 'AgentShield probe runs', probe.found ? `exit ${probe.status}` : 'missing'),
274
+ statusLine(hasTrash, 'trash command available for safe deletes', hasTrash ? 'deletions are recoverable' : TRASH_INSTALL_HINT)
260
275
  ];
261
276
 
262
277
  return `# Vibe Report
@@ -1,8 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
3
  import path from 'node:path';
4
+ import { spawnSync } from 'node:child_process';
4
5
 
5
6
  const args = process.argv.slice(2);
7
+
8
+ function trashAvailable() {
9
+ const result = spawnSync('trash', ['--help'], { encoding: 'utf8' });
10
+ return !(result.error && result.error.code === 'ENOENT');
11
+ }
6
12
  const shouldWrite = args.includes('--write');
7
13
  const yes = args.includes('--yes');
8
14
 
@@ -92,22 +98,22 @@ function cleanName(name) {
92
98
  }
93
99
 
94
100
  function isKitManagedPath(file) {
95
- const managedRoots = new Set(['.claude', '.cursor', '.agents', '.codex', '.codex-plugin', 'skills', '.vbkit-commands', '.vbkit-docs', '.vbkit-scripts']);
101
+ const managedRoots = new Set(['.claude', '.cursor', '.agents', '.codex', '.codex-plugin', '.vibekit']);
96
102
  const managedFiles = new Set([
97
103
  'AGENTS.md',
98
- 'CLAUDE-template.md',
99
- 'FIRST_PROMPT.md',
100
- 'FIRST_TIME_INIT.md',
104
+ '.vibekit/init/CLAUDE-template.md',
105
+ '.vibekit/init/FIRST_PROMPT.md',
106
+ '.vibekit/init/FIRST_TIME_INIT.md',
101
107
  'backbone.yml',
102
- '.vbkit-scripts/mvck.mjs',
103
- '.vbkit-scripts/init-backbone.mjs',
104
- '.vbkit-scripts/daily-enhance.mjs',
105
- '.vbkit-scripts/validate-kit.mjs',
106
- '.vbkit-scripts/doctor.mjs',
107
- '.vbkit-scripts/test-install.mjs',
108
- '.vbkit-scripts/agentshield-probe.mjs',
109
- '.vbkit-scripts/pack-dry-run.mjs',
110
- '.vbkit-scripts/vibekit-finalize.mjs'
108
+ '.vibekit/scripts/mvck.mjs',
109
+ '.vibekit/scripts/init-backbone.mjs',
110
+ '.vibekit/scripts/daily-enhance.mjs',
111
+ '.vibekit/scripts/validate-kit.mjs',
112
+ '.vibekit/scripts/doctor.mjs',
113
+ '.vibekit/scripts/test-install.mjs',
114
+ '.vibekit/scripts/agentshield-probe.mjs',
115
+ '.vibekit/scripts/pack-dry-run.mjs',
116
+ '.vibekit/scripts/vibekit-finalize.mjs'
111
117
  ]);
112
118
  const root = file.split('/')[0];
113
119
  return managedRoots.has(root) || managedFiles.has(file);
@@ -514,10 +520,10 @@ function detectConventions(files, type) {
514
520
  }
515
521
 
516
522
  const PRD_CANDIDATES = [
517
- 'PRD.md', '.vbkit-docs/PRD.md', 'prd.md', '.vbkit-docs/prd.md',
518
- 'REQUIREMENTS.md', '.vbkit-docs/REQUIREMENTS.md',
519
- 'SPEC.md', '.vbkit-docs/SPEC.md', '.vbkit-docs/spec.md',
520
- 'PRODUCT.md', '.vbkit-docs/PRODUCT.md'
523
+ 'PRD.md', '.vibekit/docs/PRD.md', 'prd.md', '.vibekit/docs/prd.md',
524
+ 'REQUIREMENTS.md', '.vibekit/docs/REQUIREMENTS.md',
525
+ 'SPEC.md', '.vibekit/docs/SPEC.md', '.vibekit/docs/spec.md',
526
+ 'PRODUCT.md', '.vibekit/docs/PRODUCT.md'
521
527
  ];
522
528
 
523
529
  function countCodeFiles(files) {
@@ -538,7 +544,7 @@ function detectPrd(files) {
538
544
  }
539
545
 
540
546
  function detectContext() {
541
- for (const candidate of ['.vbkit-docs/CONTEXT.md', 'CONTEXT.md', '.vbkit-docs/context.md']) {
547
+ for (const candidate of ['.vibekit/docs/CONTEXT.md', 'CONTEXT.md', '.vibekit/docs/context.md']) {
542
548
  if (fileExists(candidate)) return candidate;
543
549
  }
544
550
  return 'none';
@@ -547,7 +553,7 @@ function detectContext() {
547
553
  function render(data) {
548
554
  const cmd = data.commands;
549
555
  const rules = data.conventions;
550
- return `# Minimal Vibe Coding Kit backbone. See .vbkit-docs/BACKBONE_REFERENCE.md for details.\nversion: 2\nmeta:\n template_status: initialized\n initialized_at: ${yamlString(data.initializedAt)}\n template_source: minimal-vibe-coding-kit\n schema_version: 3\n init_runbook: FIRST_TIME_INIT.md\n init_done_marker: .vibekit/INIT_DONE\n\nproject:\n name: ${yamlString(data.name)}\n description: ${yamlString(data.description)}\n type: ${data.type}\n primary_language: ${data.language}\n package_manager: ${data.packageManager}\n mode: ${data.mode}\n prd: ${yamlString(data.prd)}\n context: ${yamlString(data.context)}\n\npaths:\n root: .\n apps:${yamlList(data.appPaths, 4)}\n source: ${JSON.stringify(data.sourcePaths)}\n tests: ${JSON.stringify(data.testPaths)}\n docs: [README.md, .vbkit-docs/]\n generated: [node_modules/, dist/, build/, coverage/]\n\nconventions:\n review_required_before_write: true\n scope: ${yamlString(rules.scope)}\n naming:\n files: ${yamlString(rules.naming.files)}\n directories: ${yamlString(rules.naming.directories)}\n symbols: follow existing language and framework conventions in nearby code\n evidence:${yamlList(rules.naming.evidence, 6)}\n architecture:\n detected:${yamlList(rules.architecture.detected, 6)}\n rule: ${yamlString(rules.architecture.rule)}\n resources:\n detected_asset_roots:${yamlList(rules.resources.assetRoots, 6)}\n detected_registries:${yamlList(rules.resources.registries, 6)}\n rule: ${yamlString(rules.resources.rule)}\n localization:\n detected_catalogs:${yamlList(rules.localization.catalogs, 6)}\n detected_accessors:${yamlList(rules.localization.accessors, 6)}\n rule: ${yamlString(rules.localization.rule)}\n custom_rules:\n - Add team-specific rules here during init review; future agents must follow them.\n\ncommands:\n install: ${yamlString(cmd.install)}\n test: ${yamlString(cmd.test)}\n lint: ${yamlString(cmd.lint)}\n typecheck: ${yamlString(cmd.typecheck)}\n build: ${yamlString(cmd.build)}\n validate: ${yamlString(cmd.validate)}\n\npolicy:\n default_branch: main\n branch_naming: "feat/<short-topic>"\n commit_style: conventional\n editable_paths: [.]\n protected_paths:\n - .git/\n - .env*\n - "**/*secret*"\n - "**/*token*"\n - "**/migrations/**"\n - "**/node_modules/**"\n - "**/dist/**"\n - "**/build/**"\n - "**/coverage/**"\n - "**/*lock*"\n\nagent_surfaces:\n claude: .claude/\n cursor: .cursor/\n codex: .agents/\n codex_plugin: .codex-plugin/plugin.json\n shared_skills: skills/\n shared_commands: .vbkit-commands/\n\nautomation:\n autoresearch:\n results_file: results.tsv\n logs_dir: .autoresearch/logs\n default_budget: 3\n default_timeout_seconds: 600\n daily_enhance:\n report_dir: .vibekit/reports\n write_mode: propose_only\n finalize:\n cleanup_dir: _vibekit-cleanup\n marker: .vibekit/FINALIZE_DONE\n one_time_files: [FIRST_TIME_INIT.md, FIRST_PROMPT.md, PUSH_TO_GITHUB.md, CLAUDE-template.md]\n security:\n probe: node .vbkit-scripts/agentshield-probe.mjs .\n scan: npx ecc-agentshield scan --path . --format text --min-severity medium\n`;
556
+ return `# Minimal Vibe Coding Kit backbone. See .vibekit/docs/BACKBONE_REFERENCE.md for details.\nversion: 2\nmeta:\n template_status: initialized\n initialized_at: ${yamlString(data.initializedAt)}\n template_source: minimal-vibe-coding-kit\n schema_version: 3\n init_runbook: .vibekit/init/FIRST_TIME_INIT.md\n init_done_marker: .vibekit/INIT_DONE\n\nproject:\n name: ${yamlString(data.name)}\n description: ${yamlString(data.description)}\n type: ${data.type}\n primary_language: ${data.language}\n package_manager: ${data.packageManager}\n mode: ${data.mode}\n prd: ${yamlString(data.prd)}\n context: ${yamlString(data.context)}\n\npaths:\n root: .\n apps:${yamlList(data.appPaths, 4)}\n source: ${JSON.stringify(data.sourcePaths)}\n tests: ${JSON.stringify(data.testPaths)}\n docs: [README.md, .vibekit/docs/]\n generated: [node_modules/, dist/, build/, coverage/]\n\nconventions:\n review_required_before_write: true\n scope: ${yamlString(rules.scope)}\n naming:\n files: ${yamlString(rules.naming.files)}\n directories: ${yamlString(rules.naming.directories)}\n symbols: follow existing language and framework conventions in nearby code\n evidence:${yamlList(rules.naming.evidence, 6)}\n architecture:\n detected:${yamlList(rules.architecture.detected, 6)}\n rule: ${yamlString(rules.architecture.rule)}\n resources:\n detected_asset_roots:${yamlList(rules.resources.assetRoots, 6)}\n detected_registries:${yamlList(rules.resources.registries, 6)}\n rule: ${yamlString(rules.resources.rule)}\n localization:\n detected_catalogs:${yamlList(rules.localization.catalogs, 6)}\n detected_accessors:${yamlList(rules.localization.accessors, 6)}\n rule: ${yamlString(rules.localization.rule)}\n custom_rules:\n - Add team-specific rules here during init review; future agents must follow them.\n\ncommands:\n install: ${yamlString(cmd.install)}\n test: ${yamlString(cmd.test)}\n lint: ${yamlString(cmd.lint)}\n typecheck: ${yamlString(cmd.typecheck)}\n build: ${yamlString(cmd.build)}\n validate: ${yamlString(cmd.validate)}\n\npolicy:\n default_branch: main\n branch_naming: "feat/<short-topic>"\n commit_style: conventional\n editable_paths: [.]\n protected_paths:\n - .git/\n - .env*\n - "**/*secret*"\n - "**/*token*"\n - "**/migrations/**"\n - "**/node_modules/**"\n - "**/dist/**"\n - "**/build/**"\n - "**/coverage/**"\n - "**/*lock*"\n\nagent_surfaces:\n claude: .claude/\n cursor: .cursor/\n codex: .agents/\n codex_plugin: .codex-plugin/plugin.json\n shared_skills: .vibekit/skills/\n shared_commands: .vibekit/commands/\n\nautomation:\n autoresearch:\n results_file: results.tsv\n logs_dir: .autoresearch/logs\n default_budget: 3\n default_timeout_seconds: 600\n daily_enhance:\n report_dir: .vibekit/reports\n write_mode: propose_only\n finalize:\n cleanup_dir: _vibekit-cleanup\n marker: .vibekit/FINALIZE_DONE\n one_time_files: [.vibekit/init/FIRST_TIME_INIT.md, .vibekit/init/FIRST_PROMPT.md, .vibekit/init/PUSH_TO_GITHUB.md, .vibekit/init/CLAUDE-template.md]\n security:\n probe: node .vibekit/scripts/agentshield-probe.mjs .\n scan: npx ecc-agentshield scan --path . --format text --min-severity medium\n`;
551
557
  }
552
558
 
553
559
  function inferPaths(files) {
@@ -614,15 +620,18 @@ if (shouldWrite) {
614
620
  console.log('- What are the key constraints or non-goals?');
615
621
  if (inferred.mode === 'brownfield') console.log('- Which existing area should we focus on improving first?');
616
622
  console.log(inferred.prd === 'none'
617
- ? '- Offer to create .vbkit-docs/PRD.md from .vbkit-docs/templates/PRD_TEMPLATE.md using the answers.'
623
+ ? '- Offer to create .vibekit/docs/PRD.md from .vibekit/docs/templates/PRD_TEMPLATE.md using the answers.'
618
624
  : `- Offer to refresh ${inferred.prd} with the answers; do not overwrite without approval.`);
619
625
  console.log(inferred.context === 'none'
620
- ? '- Offer to create .vbkit-docs/CONTEXT.md (glossary) from .vbkit-docs/templates/CONTEXT_TEMPLATE.md.'
626
+ ? '- Offer to create .vibekit/docs/CONTEXT.md (glossary) from .vibekit/docs/templates/CONTEXT_TEMPLATE.md.'
621
627
  : `- CONTEXT glossary found at ${inferred.context}; keep it current.`);
628
+ console.log('\nSetup preferences (record answers in conventions.custom_rules; see FIRST_TIME_INIT.md "Setup preferences"):');
629
+ console.log(`- Safe delete: trash command ${trashAvailable() ? 'available' : 'NOT found (recommend: macOS 14+ built-in; older macOS `brew install trash`; Linux `sudo apt install trash-cli`; any OS `npm i -g trash-cli`)'} - ask: use trash instead of rm? (recommended: yes)`);
630
+ console.log('- Default coding level: ask 0-5 (0 ELI5, 1 Junior, 2 Mid-level, 3 Senior, 4 Tech Lead, 5 God); changeable later with /coding-level N.');
622
631
  console.log('\nConvention review questions:');
623
632
  for (const question of inferred.conventions.reviewQuestions) console.log(`- ${question}`);
624
633
  console.log('\nProposed backbone.yml:\n');
625
634
  console.log(out);
626
635
  console.log('Apply this proposed backbone and convention rules? Reply yes, edit, or abort.');
627
- console.log('To write it after approval, run: node .vbkit-scripts/init-backbone.mjs . --write --yes');
636
+ console.log('To write it after approval, run: node .vibekit/scripts/init-backbone.mjs . --write --yes');
628
637
  }
@@ -6,7 +6,7 @@ import { spawnSync } from 'node:child_process';
6
6
 
7
7
  const __filename = fileURLToPath(import.meta.url);
8
8
  const __dirname = path.dirname(__filename);
9
- const kitRoot = path.resolve(__dirname, '..');
9
+ const kitRoot = path.resolve(__dirname, '..', '..');
10
10
  const args = process.argv.slice(2);
11
11
 
12
12
  function usage() {
@@ -22,12 +22,12 @@ Usage:
22
22
  mvck finalize [target] [--write --yes] [--restore] [--json]
23
23
 
24
24
  Examples:
25
- node .vbkit-scripts/mvck.mjs install ~/work/my-repo --profile all
25
+ node .vibekit/scripts/mvck.mjs install ~/work/my-repo --profile all
26
26
  npx --yes minimal-vibe-coding-kit@latest update .
27
- node .vbkit-scripts/mvck.mjs init . --propose
28
- node .vbkit-scripts/mvck.mjs doctor .
29
- node .vbkit-scripts/mvck.mjs validate .
30
- node .vbkit-scripts/mvck.mjs finalize .
27
+ node .vibekit/scripts/mvck.mjs init . --propose
28
+ node .vibekit/scripts/mvck.mjs doctor .
29
+ node .vibekit/scripts/mvck.mjs validate .
30
+ node .vibekit/scripts/mvck.mjs finalize .
31
31
 
32
32
  update refreshes kit-owned files (skills, commands, rules, scripts, docs, agent
33
33
  mirrors) to the running kit version. It never overwrites user-owned files
@@ -98,13 +98,14 @@ function copyFileSafe(srcRel, destRel, target, { force = false, dryRun = false }
98
98
  return { action: fs.existsSync(dest) && force ? 'replace' : 'copy', path: destRel ?? srcRel };
99
99
  }
100
100
 
101
- function copyDirSafe(srcRel, destRel, target, { force = false, dryRun = false } = {}) {
101
+ function copyDirSafe(srcRel, destRel, target, { force = false, dryRun = false, exclude = [] } = {}) {
102
102
  const src = path.join(kitRoot, srcRel);
103
103
  const destRoot = path.join(target, destRel ?? srcRel);
104
104
  if (!fs.existsSync(src)) throw new Error(`Missing source dir: ${srcRel}`);
105
105
  let copied = 0;
106
106
  let skipped = 0;
107
107
  function copyRecursive(from, to) {
108
+ if (exclude.includes(path.relative(src, from).replaceAll(path.sep, '/'))) return;
108
109
  const stat = fs.statSync(from);
109
110
  if (stat.isDirectory()) {
110
111
  if (!dryRun) fs.mkdirSync(to, { recursive: true });
@@ -149,19 +150,30 @@ function managedBlockFromTemplate(block, begin, end) {
149
150
  return `${begin}\n${block.trim()}\n${end}`;
150
151
  }
151
152
 
152
- const KIT_SEED_FILES = ['FIRST_TIME_INIT.md', 'FIRST_PROMPT.md', 'CLAUDE-template.md', 'backbone.yml'];
153
- const KIT_SHARED_DIRS = ['skills', '.vbkit-commands', '.vbkit-docs'];
153
+ const KIT_SEED_FILES = ['.vibekit/init/FIRST_TIME_INIT.md', '.vibekit/init/FIRST_PROMPT.md', '.vibekit/init/CLAUDE-template.md', 'backbone.yml'];
154
+ const KIT_SHARED_DIRS = ['.vibekit/skills', '.vibekit/commands', '.vibekit/docs'];
155
+ // Kit-maintainer files that end-user repos do not need; never copied by install/update.
156
+ const KIT_DOC_EXCLUDES = ['RESEARCH_NOTES.md', 'AUTORESEARCH_LEDGER.md'];
154
157
  const KIT_SCRIPTS = [
155
- '.vbkit-scripts/mvck.mjs', '.vbkit-scripts/init-backbone.mjs', '.vbkit-scripts/daily-enhance.mjs', '.vbkit-scripts/validate-kit.mjs',
156
- '.vbkit-scripts/doctor.mjs', '.vbkit-scripts/test-install.mjs', '.vbkit-scripts/agentshield-probe.mjs', '.vbkit-scripts/pack-dry-run.mjs', '.vbkit-scripts/vibekit-finalize.mjs'
158
+ '.vibekit/scripts/mvck.mjs', '.vibekit/scripts/init-backbone.mjs', '.vibekit/scripts/daily-enhance.mjs', '.vibekit/scripts/validate-kit.mjs',
159
+ '.vibekit/scripts/doctor.mjs', '.vibekit/scripts/agentshield-probe.mjs', '.vibekit/scripts/vibekit-finalize.mjs'
157
160
  ];
161
+ const VALID_PROFILES = new Set(['claude', 'cursor', 'codex']);
162
+
163
+ function parseProfiles(profileRaw) {
164
+ const profiles = new Set(profileRaw === 'all' ? ['claude', 'cursor', 'codex'] : profileRaw.split(',').map((x) => x.trim()).filter(Boolean));
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).`);
167
+ }
168
+ return profiles;
169
+ }
158
170
  const CLAUDE_DIRS = ['.claude/agents', '.claude/commands', '.claude/rules'];
159
171
  const CLAUDE_SKILLS = [
160
172
  'autoresearch-coding', 'agentshield-security-review', 'daily-workflow-curator', 'vibekit-init', 'visual-design-loop',
161
- 'clearthought', 'sequential-thinking', 'reviewing-4p-priorities', 'memento', 'coding-level'
173
+ 'clearthought', 'sequential-thinking', 'reviewing-4p-priorities', 'path-sensitive-shell-safety', 'memento', 'coding-level', 'parallel-analysis'
162
174
  ];
163
175
  const CURSOR_DIRS = ['.cursor/rules', '.cursor/commands'];
164
- const CURSOR_SKILLS = ['clearthought', 'sequential-thinking', 'reviewing-4p-priorities', 'memento', 'coding-level'];
176
+ const CURSOR_SKILLS = ['clearthought', 'sequential-thinking', 'reviewing-4p-priorities', 'path-sensitive-shell-safety', 'memento', 'coding-level', 'parallel-analysis'];
165
177
  const CODEX_DIRS = ['.agents', '.codex', '.codex-plugin'];
166
178
  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`;
167
179
 
@@ -187,9 +199,9 @@ function applyManagedBlocks(target, profiles, actions, { dryRun = false } = {})
187
199
  if (profiles.has('claude')) {
188
200
  const claudeTarget = path.join(target, 'CLAUDE.md');
189
201
  if (!fs.existsSync(claudeTarget)) {
190
- actions.push(copyFileSafe('CLAUDE-template.md', 'CLAUDE.md', target, { force: false, dryRun }));
202
+ actions.push(copyFileSafe('.vibekit/init/CLAUDE-template.md', 'CLAUDE.md', target, { force: false, dryRun }));
191
203
  } else {
192
- const block = `<!-- BEGIN: minimal-vibe-coding-kit -->\n@AGENTS.md\n\n## Minimal Vibe Coding Kit\n\n- Read \`backbone.yml\` before changing code.\n- If \`meta.template_status\` is \`uninitialized\`, follow \`FIRST_TIME_INIT.md\` and wait for approval before writing.\n- After init, follow \`backbone.yml\` \`conventions\` before adding new project patterns.\n- Prefer project skills for multi-step workflows: \`/autoresearch-coding\`, \`/security-scan\`, \`/daily-enhance\`.\n<!-- END: minimal-vibe-coding-kit -->`;
204
+ const block = `<!-- BEGIN: minimal-vibe-coding-kit -->\n@AGENTS.md\n\n## Minimal Vibe Coding Kit\n\n- Read \`backbone.yml\` before changing code.\n- If \`meta.template_status\` is \`uninitialized\`, follow \`.vibekit/init/FIRST_TIME_INIT.md\` and wait for approval before writing.\n- After init, follow \`backbone.yml\` \`conventions\` before adding new project patterns.\n- Prefer project skills for multi-step workflows: \`/autoresearch-coding\`, \`/security-scan\`, \`/daily-enhance\`.\n<!-- END: minimal-vibe-coding-kit -->`;
193
205
  appendManagedBlock(claudeTarget, block, '<!-- BEGIN: minimal-vibe-coding-kit -->', '<!-- END: minimal-vibe-coding-kit -->', { dryRun });
194
206
  actions.push({ action: 'managed-block', path: 'CLAUDE.md' });
195
207
  }
@@ -213,8 +225,7 @@ function install() {
213
225
  const dryRun = hasFlag('--dry-run');
214
226
  const json = hasFlag('--json');
215
227
  const target = parseTargetAndFlags('install', { valueFlags: ['--profile'] }).target;
216
- const profileRaw = optionValue('--profile', 'all');
217
- const profiles = new Set(profileRaw === 'all' ? ['claude', 'cursor', 'codex'] : profileRaw.split(',').map((x) => x.trim()).filter(Boolean));
228
+ const profiles = parseProfiles(optionValue('--profile', 'all'));
218
229
 
219
230
  if (!fs.existsSync(target)) throw new Error(`Target does not exist: ${target}`);
220
231
  const actions = [];
@@ -224,7 +235,7 @@ function install() {
224
235
  actions.push(copyFileSafe(file, file, target, opts));
225
236
  }
226
237
  for (const dir of KIT_SHARED_DIRS) {
227
- actions.push(copyDirSafe(dir, dir, target, opts));
238
+ actions.push(copyDirSafe(dir, dir, target, dir === '.vibekit/docs' ? { ...opts, exclude: KIT_DOC_EXCLUDES } : opts));
228
239
  }
229
240
  for (const file of KIT_SCRIPTS) {
230
241
  actions.push(copyFileSafe(file, file, target, opts));
@@ -258,7 +269,8 @@ function install() {
258
269
  writeKitVersion(target, dryRun);
259
270
  actions.push({ action: 'version-marker', path: '.vibekit/KIT_VERSION' });
260
271
 
261
- const nextPrompt = 'Read FIRST_TIME_INIT.md and initialize this repo with Minimal Vibe Coding Kit. Print requirements first, infer project conventions, propose a diff, and wait for my yes before writing.';
272
+ const nextPrompt = 'Read .vibekit/init/FIRST_TIME_INIT.md and initialize this repo with Minimal Vibe Coding Kit. Print requirements first, infer project conventions, propose a diff, and wait for my yes before writing.';
273
+ const legacyPaths = detectLegacyLayout(target);
262
274
  if (json) {
263
275
  console.log(JSON.stringify({
264
276
  status: dryRun ? 'dry-run' : 'installed',
@@ -267,6 +279,7 @@ function install() {
267
279
  force,
268
280
  dryRun,
269
281
  actions,
282
+ legacyPaths,
270
283
  nextPrompt
271
284
  }, null, 2));
272
285
  return;
@@ -274,10 +287,29 @@ function install() {
274
287
 
275
288
  console.log(dryRun ? 'Dry-run install plan:' : 'Install complete:');
276
289
  for (const a of actions) console.log(`- ${a.action}: ${a.path}`);
290
+ printLegacyLayoutNote(legacyPaths);
277
291
  console.log('\nNext prompt:');
278
292
  console.log(nextPrompt);
279
293
  }
280
294
 
295
+ // Pre-0.4 installs placed kit dirs at the target root. Detection is advisory
296
+ // only: nothing is deleted automatically, and a root `skills/` dir is flagged
297
+ // only when it contains a known kit skill (it may be the user's own folder).
298
+ function detectLegacyLayout(target) {
299
+ const legacy = ['.vbkit-scripts', '.vbkit-commands', '.vbkit-docs',
300
+ 'FIRST_TIME_INIT.md', 'FIRST_PROMPT.md', 'CLAUDE-template.md', 'PUSH_TO_GITHUB.md']
301
+ .filter((rel) => fs.existsSync(path.join(target, rel)));
302
+ if (fs.existsSync(path.join(target, 'skills', 'vibekit-init', 'SKILL.md'))) legacy.push('skills');
303
+ return legacy;
304
+ }
305
+
306
+ function printLegacyLayoutNote(legacy) {
307
+ if (!legacy.length) return;
308
+ console.log('\nLegacy kit layout detected (pre-0.4). Kit files now live under .vibekit/.');
309
+ console.log('After verifying the new .vibekit/ copies, remove or `git mv` these leftovers:');
310
+ for (const rel of legacy) console.log(`- ${rel}`);
311
+ }
312
+
281
313
  function updateFileSafe(srcRel, destRel, target, { dryRun = false, backup = null } = {}) {
282
314
  const src = path.join(kitRoot, srcRel);
283
315
  const dest = path.join(target, destRel ?? srcRel);
@@ -312,10 +344,12 @@ function updateFileSafe(srcRel, destRel, target, { dryRun = false, backup = null
312
344
  function updateDirSafe(srcRel, target, opts) {
313
345
  const src = path.join(kitRoot, srcRel);
314
346
  if (!fs.existsSync(src)) throw new Error(`Missing source dir: ${srcRel}`);
347
+ const exclude = opts.exclude ?? [];
315
348
  const results = [];
316
349
  function walk(current) {
317
350
  for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
318
351
  const child = path.join(current, entry.name);
352
+ if (exclude.includes(path.relative(src, child).replaceAll(path.sep, '/'))) continue;
319
353
  if (entry.isDirectory()) walk(child);
320
354
  else {
321
355
  const rel = path.join(srcRel, path.relative(src, child)).replaceAll(path.sep, '/');
@@ -332,15 +366,14 @@ function update() {
332
366
  const json = hasFlag('--json');
333
367
  const noBackup = hasFlag('--no-backup');
334
368
  const target = parseTargetAndFlags('update', { valueFlags: ['--profile'] }).target;
335
- const profileRaw = optionValue('--profile', 'all');
336
- const profiles = new Set(profileRaw === 'all' ? ['claude', 'cursor', 'codex'] : profileRaw.split(',').map((x) => x.trim()).filter(Boolean));
369
+ const profiles = parseProfiles(optionValue('--profile', 'all'));
337
370
 
338
371
  if (!fs.existsSync(target)) throw new Error(`Target does not exist: ${target}`);
339
372
  if (fs.realpathSync(kitRoot) === fs.realpathSync(target)) {
340
373
  throw new Error('Update source and target are the same directory. Run the update from a newer kit, e.g.: npx --yes minimal-vibe-coding-kit@latest update .');
341
374
  }
342
- if (!fs.existsSync(path.join(target, 'backbone.yml')) && !fs.existsSync(path.join(target, '.vbkit-scripts'))) {
343
- throw new Error('Kit not detected in target (no backbone.yml or .vbkit-scripts). Run mvck install first.');
375
+ if (!fs.existsSync(path.join(target, 'backbone.yml')) && !fs.existsSync(path.join(target, '.vibekit/scripts'))) {
376
+ throw new Error('Kit not detected in target (no backbone.yml or .vibekit/scripts). Run mvck install first.');
344
377
  }
345
378
 
346
379
  const previousVersionFile = path.join(target, '.vibekit', 'KIT_VERSION');
@@ -352,7 +385,7 @@ function update() {
352
385
  const actions = [];
353
386
 
354
387
  // Kit-owned surfaces: refresh to the running kit version, never delete extras.
355
- for (const dir of KIT_SHARED_DIRS) actions.push(...updateDirSafe(dir, target, opts));
388
+ for (const dir of KIT_SHARED_DIRS) actions.push(...updateDirSafe(dir, target, dir === '.vibekit/docs' ? { ...opts, exclude: KIT_DOC_EXCLUDES } : opts));
356
389
  for (const file of KIT_SCRIPTS) actions.push(updateFileSafe(file, file, target, opts));
357
390
  if (profiles.has('claude')) {
358
391
  for (const dir of CLAUDE_DIRS) actions.push(...updateDirSafe(dir, target, opts));
@@ -381,6 +414,7 @@ function update() {
381
414
  const backupInfo = backup && backup.count > 0 ? path.relative(target, backup.dir) : null;
382
415
  const preserved = ['backbone.yml', 'CLAUDE.md', 'AGENTS.md content outside the managed block', '.claude/settings.json', '.cursor/settings.json'];
383
416
 
417
+ const legacyPaths = detectLegacyLayout(target);
384
418
  if (json) {
385
419
  console.log(JSON.stringify({
386
420
  status: dryRun ? 'dry-run' : 'updated',
@@ -391,6 +425,7 @@ function update() {
391
425
  summary,
392
426
  backupDir: backupInfo,
393
427
  preserved,
428
+ legacyPaths,
394
429
  actions: actions.filter((a) => a.action !== 'unchanged')
395
430
  }, null, 2));
396
431
  return;
@@ -405,11 +440,12 @@ function update() {
405
440
  console.log(`\nSummary: ${summary.add} added, ${summary.update} updated, ${summary.unchanged} unchanged.`);
406
441
  if (backupInfo) console.log(`Backups of replaced files: ${backupInfo}/`);
407
442
  console.log(`Preserved (never overwritten by update): ${preserved.join(', ')}.`);
443
+ printLegacyLayoutNote(legacyPaths);
408
444
  }
409
445
 
410
446
  function delegate(scriptName, { valueFlags = [] } = {}) {
411
447
  const { target, flags } = parseTargetAndFlags(args[0], { valueFlags });
412
- const script = path.join(kitRoot, '.vbkit-scripts', scriptName);
448
+ const script = path.join(kitRoot, '.vibekit/scripts', scriptName);
413
449
  const childArgs = [script, target, ...flags];
414
450
  const result = spawnSync(process.execPath, childArgs, { stdio: 'inherit' });
415
451
  process.exit(result.status ?? 1);