viepilot 3.9.1 → 3.10.0

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.
package/CHANGELOG.md CHANGED
@@ -9,6 +9,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ---
11
11
 
12
+ ## [3.10.0] - 2026-05-25
13
+
14
+ ### Added
15
+ - ENH-101: `vp-crystallize` now generates adapter-specific AI context files at Step 1F
16
+ - ENH-101: New `vp-tools context-files` subcommand generates CLAUDE.md (Claude Code),
17
+ GEMINI.md (Antigravity), AGENTS.md (Codex), .cursorrules + .cursor/rules/ (Cursor),
18
+ .github/copilot-instructions.md (Copilot) from `.viepilot/` sources
19
+ - ENH-101: `--all` flag generates all 5 adapter files simultaneously
20
+ - ENH-101: Content sourced from AI-GUIDE.md, PROJECT-CONTEXT.md, SYSTEM-RULES.md, STACKS.md
21
+
22
+ ---
23
+
12
24
  ## [3.9.1] - 2026-05-25
13
25
 
14
26
  ### Fixed
package/bin/vp-tools.cjs CHANGED
@@ -1210,6 +1210,44 @@ ${colors.cyan}Examples:${colors.reset}
1210
1210
  });
1211
1211
  },
1212
1212
 
1213
+ /**
1214
+ * ENH-101: Generate adapter context files (CLAUDE.md, GEMINI.md, AGENTS.md, .cursorrules, .github/copilot-instructions.md)
1215
+ * Usage: vp-tools context-files [--all]
1216
+ */
1217
+ 'context-files': (args) => {
1218
+ const { generateAll, generateClaudeMd, generateGeminiMd, generateAgentsMd,
1219
+ generateCursorRules, generateCursorMdc, generateCopilotInstructions }
1220
+ = require('../lib/context-file-generators.cjs');
1221
+ const allFlag = args.includes('--all');
1222
+ const projectRoot = process.cwd();
1223
+
1224
+ // detect adapter
1225
+ const adapterCtx = require('../lib/adapter-context.cjs');
1226
+ const adapterId = adapterCtx.detectAdapter ? adapterCtx.detectAdapter() : 'claude-code';
1227
+
1228
+ const targets = allFlag ? generateAll(projectRoot) : (() => {
1229
+ const map = {
1230
+ 'claude-code': [{ path: 'CLAUDE.md', content: generateClaudeMd(projectRoot) }],
1231
+ 'antigravity': [{ path: 'GEMINI.md', content: generateGeminiMd(projectRoot) }],
1232
+ 'codex': [{ path: 'AGENTS.md', content: generateAgentsMd(projectRoot) }],
1233
+ 'cursor-agent': [
1234
+ { path: '.cursorrules', content: generateCursorRules(projectRoot) },
1235
+ { path: '.cursor/rules/viepilot-context.mdc', content: generateCursorMdc(projectRoot) },
1236
+ ],
1237
+ 'copilot': [{ path: '.github/copilot-instructions.md', content: generateCopilotInstructions(projectRoot) }],
1238
+ };
1239
+ return map[adapterId] || map['claude-code'];
1240
+ })();
1241
+
1242
+ for (const { path: relPath, content } of targets) {
1243
+ const absPath = require('path').join(projectRoot, relPath);
1244
+ require('fs').mkdirSync(require('path').dirname(absPath), { recursive: true });
1245
+ require('fs').writeFileSync(absPath, content, 'utf8');
1246
+ console.log(formatSuccess(`Written: ${relPath}`));
1247
+ }
1248
+ process.exit(0);
1249
+ },
1250
+
1213
1251
  /**
1214
1252
  * ENH-073: Manage cross-project personas.
1215
1253
  * persona get → print active persona JSON
@@ -1627,6 +1665,7 @@ ${colors.cyan}Commands:${colors.reset}
1627
1665
  ${colors.bold}get-registry${colors.reset} [--id <id>] Output global skill registry as JSON
1628
1666
  ${colors.bold}scan-skills${colors.reset} Scan installed skills → ~/.viepilot/skill-registry.json
1629
1667
  ${colors.bold}check-update${colors.reset} [--silent] Check for latest ViePilot version on npm (24h cached)
1668
+ ${colors.bold}context-files${colors.reset} [--all] Generate adapter context files (CLAUDE.md, GEMINI.md, etc.)
1630
1669
  ${colors.bold}persona${colors.reset} <op> Manage user personas (get|infer|list|set|auto-switch|context)
1631
1670
  ${colors.bold}detect-adapter${colors.reset} [--json] Detect active adapter (claude-code/cursor/antigravity/codex/copilot)
1632
1671
  ${colors.bold}validate${colors.reset} --adapter <id> Validate adapter capability requirements; exits 1 on critical gaps
@@ -0,0 +1,147 @@
1
+ 'use strict';
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ /**
6
+ * Read a .viepilot/ source file, return '' if missing.
7
+ */
8
+ function readSource(projectRoot, relPath) {
9
+ try {
10
+ return fs.readFileSync(path.join(projectRoot, relPath), 'utf8');
11
+ } catch { return ''; }
12
+ }
13
+
14
+ /**
15
+ * Build the shared core block used by all adapters.
16
+ * Sources: AI-GUIDE.md, PROJECT-CONTEXT.md, SYSTEM-RULES.md, STACKS.md
17
+ */
18
+ function buildCoreBlock(projectRoot) {
19
+ const meta = readSource(projectRoot, '.viepilot/PROJECT-META.md');
20
+ const guide = readSource(projectRoot, '.viepilot/AI-GUIDE.md');
21
+ const context = readSource(projectRoot, '.viepilot/PROJECT-CONTEXT.md');
22
+ const rules = readSource(projectRoot, '.viepilot/SYSTEM-RULES.md');
23
+ const stacks = readSource(projectRoot, '.viepilot/STACKS.md');
24
+
25
+ // Extract project name from PROJECT-META.md header or package.json
26
+ let projectName = 'Project';
27
+ const nameMatch = meta.match(/^#\s+(.+)/m);
28
+ if (nameMatch) projectName = nameMatch[1].trim();
29
+ else {
30
+ try {
31
+ projectName = require(path.join(projectRoot, 'package.json')).name || 'Project';
32
+ } catch { /* noop */ }
33
+ }
34
+
35
+ return { projectName, guide, context, rules, stacks };
36
+ }
37
+
38
+ /**
39
+ * CLAUDE.md — Claude Code context file (full Markdown, no frontmatter)
40
+ */
41
+ function generateClaudeMd(projectRoot) {
42
+ const { projectName, guide, context, rules, stacks } = buildCoreBlock(projectRoot);
43
+ const sections = [];
44
+ sections.push(`# ${projectName} — Claude Code Context\n`);
45
+ if (guide) sections.push(`## Navigation\n\n${guide}`);
46
+ if (context) sections.push(`## Domain Context\n\n${context}`);
47
+ if (rules) sections.push(`## Coding Standards\n\n${rules}`);
48
+ if (stacks) sections.push(`## Stack\n\n${stacks}`);
49
+ sections.push(`\n## ViePilot Workflow\n\n` +
50
+ `- Run \`/vp-auto\` to execute planned phases\n` +
51
+ `- Run \`/vp-request\` to log bugs or features\n` +
52
+ `- Current state: \`.viepilot/TRACKER.md\`\n`);
53
+ return sections.join('\n\n---\n\n');
54
+ }
55
+
56
+ /**
57
+ * GEMINI.md — Antigravity / Gemini CLI context file
58
+ */
59
+ function generateGeminiMd(projectRoot) {
60
+ // Same structure as CLAUDE.md; different header note
61
+ const content = generateClaudeMd(projectRoot);
62
+ return content.replace('Claude Code Context', 'Gemini / Antigravity Context');
63
+ }
64
+
65
+ /**
66
+ * AGENTS.md — Codex CLI context file
67
+ * Codex is patch-based + sequential; emphasize apply_patch conventions
68
+ */
69
+ function generateAgentsMd(projectRoot) {
70
+ const { projectName, context, rules, stacks } = buildCoreBlock(projectRoot);
71
+ const sections = [];
72
+ sections.push(`# ${projectName} — Codex Agent Instructions\n`);
73
+ sections.push(`## Conventions\n\n` +
74
+ `- Use \`apply_patch\` for all file edits\n` +
75
+ `- No interactive prompts — work sequentially\n` +
76
+ `- Commit after each logical unit\n`);
77
+ if (context) sections.push(`## Domain Context\n\n${context}`);
78
+ if (rules) sections.push(`## Coding Standards\n\n${rules}`);
79
+ if (stacks) sections.push(`## Stack\n\n${stacks}`);
80
+ sections.push(`\n## ViePilot\n\nPhase state: \`.viepilot/TRACKER.md\`\n`);
81
+ return sections.join('\n\n---\n\n');
82
+ }
83
+
84
+ /**
85
+ * .cursorrules — Cursor legacy flat-file format
86
+ */
87
+ function generateCursorRules(projectRoot) {
88
+ const { projectName, context, rules, stacks } = buildCoreBlock(projectRoot);
89
+ const parts = [`# ${projectName} — Cursor Rules\n`];
90
+ if (rules) parts.push(rules);
91
+ if (context) parts.push(`## Domain\n\n${context}`);
92
+ if (stacks) parts.push(`## Stack\n\n${stacks}`);
93
+ return parts.join('\n\n');
94
+ }
95
+
96
+ /**
97
+ * .cursor/rules/viepilot-context.mdc — Cursor new MDC format
98
+ */
99
+ function generateCursorMdc(projectRoot) {
100
+ const body = generateCursorRules(projectRoot)
101
+ .replace(/^# .+\n/, ''); // strip header — MDC description field covers it
102
+ const { projectName } = buildCoreBlock(projectRoot);
103
+ return `---
104
+ description: ${projectName} coding standards and architecture context
105
+ globs: ["**/*"]
106
+ alwaysApply: true
107
+ ---
108
+
109
+ ${body}`;
110
+ }
111
+
112
+ /**
113
+ * .github/copilot-instructions.md — GitHub Copilot
114
+ * Copilot has shorter context; be concise, focus on coding standards
115
+ */
116
+ function generateCopilotInstructions(projectRoot) {
117
+ const { projectName, rules, stacks } = buildCoreBlock(projectRoot);
118
+ const parts = [`# Copilot Instructions — ${projectName}\n`];
119
+ if (rules) parts.push(rules);
120
+ if (stacks) parts.push(`## Stack\n\n${stacks}`);
121
+ return parts.join('\n\n');
122
+ }
123
+
124
+ /**
125
+ * Generate all 5 adapter context files.
126
+ * Returns { path: string, content: string }[] — caller writes them.
127
+ */
128
+ function generateAll(projectRoot) {
129
+ return [
130
+ { path: 'CLAUDE.md', content: generateClaudeMd(projectRoot) },
131
+ { path: 'GEMINI.md', content: generateGeminiMd(projectRoot) },
132
+ { path: 'AGENTS.md', content: generateAgentsMd(projectRoot) },
133
+ { path: '.cursorrules', content: generateCursorRules(projectRoot) },
134
+ { path: '.cursor/rules/viepilot-context.mdc', content: generateCursorMdc(projectRoot) },
135
+ { path: '.github/copilot-instructions.md', content: generateCopilotInstructions(projectRoot) },
136
+ ];
137
+ }
138
+
139
+ module.exports = {
140
+ generateClaudeMd,
141
+ generateGeminiMd,
142
+ generateAgentsMd,
143
+ generateCursorRules,
144
+ generateCursorMdc,
145
+ generateCopilotInstructions,
146
+ generateAll,
147
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viepilot",
3
- "version": "3.9.1",
3
+ "version": "3.10.0",
4
4
  "description": "**Autonomous Vibe Coding Framework / Bộ khung phát triển tự động có kiểm soát**",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -2172,8 +2172,40 @@ Append to `.viepilot/PROJECT-CONTEXT.md`:
2172
2172
  **Lock semantics**: once written, `## Skills` is the authoritative skill decision for the project. `vp-auto` reads it and **never re-prompts**.
2173
2173
  </step>
2174
2174
 
2175
+ <step name="adapter_context_files">
2176
+ ## Step 1F: Generate Adapter Context Files (ENH-101)
2177
+
2178
+ Generate the native AI context file for the active adapter so it starts with full project context.
2179
+
2180
+ **Detect adapter and generate:**
2181
+ ```bash
2182
+ node bin/vp-tools.cjs context-files
2183
+ # or with --all to generate all 5 adapters at once:
2184
+ node bin/vp-tools.cjs context-files --all
2185
+ ```
2186
+
2187
+ **What gets generated:**
2188
+ | Adapter | File |
2189
+ |---------|------|
2190
+ | Claude Code | `CLAUDE.md` (project root) |
2191
+ | Cursor | `.cursorrules` + `.cursor/rules/viepilot-context.mdc` |
2192
+ | Codex | `AGENTS.md` (project root) |
2193
+ | Antigravity | `GEMINI.md` (project root) |
2194
+ | GitHub Copilot | `.github/copilot-instructions.md` |
2195
+
2196
+ **Content sources** (from `.viepilot/` — skip if not yet generated):
2197
+ - `AI-GUIDE.md` → navigation + architecture summary
2198
+ - `PROJECT-CONTEXT.md` → domain knowledge, business rules
2199
+ - `SYSTEM-RULES.md` → coding standards, patterns
2200
+ - `STACKS.md` → tech stack, versions
2201
+
2202
+ **Note**: Re-running overwrites existing files with latest `.viepilot/` content.
2203
+ Step 1F is non-blocking — if `.viepilot/` sources are incomplete, outputs a partial file
2204
+ with a `<!-- viepilot: incomplete -->` comment at the top as a re-run reminder.
2205
+ </step>
2206
+
2175
2207
  <step name="cross_reference_gate">
2176
- ## Step 1F: Cross-Reference Gate (ENH-064)
2208
+ ## Step 1G: Cross-Reference Gate (ENH-064)
2177
2209
 
2178
2210
  Run when BOTH `architect_read_complete: true` AND `ui_direction_read_complete: true` are set in working notes:
2179
2211
 
@@ -2208,9 +2240,9 @@ Run when BOTH `architect_read_complete: true` AND `ui_direction_read_complete: t
2208
2240
  <step name="stakeholder_review_gate">
2209
2241
  ---
2210
2242
 
2211
- ## Step 1G: Stakeholder Review Gate (ENH-098)
2243
+ ## Step 1H: Stakeholder Review Gate (ENH-098)
2212
2244
 
2213
- **Trigger**: Runs automatically after Step 1F, before Step 2.
2245
+ **Trigger**: Runs automatically after Step 1G, before Step 2.
2214
2246
 
2215
2247
  **Skip conditions**:
2216
2248
  - `--no-stakeholders` flag passed to `/vp-crystallize`