mvc-kit 2.1.0 → 2.2.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/README.md
CHANGED
|
@@ -21,16 +21,12 @@ mvc-kit ships with built-in context for AI coding assistants — stays in sync w
|
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
23
|
npx mvc-kit-setup # Set up all agents
|
|
24
|
+
npx mvc-kit-setup claude # Claude Code only
|
|
24
25
|
npx mvc-kit-setup cursor # Cursor only
|
|
25
26
|
npx mvc-kit-setup copilot # GitHub Copilot only
|
|
26
27
|
```
|
|
27
28
|
|
|
28
|
-
**Claude Code** —
|
|
29
|
-
```bash
|
|
30
|
-
claude --plugin-dir node_modules/mvc-kit/agent-config/claude-code
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
Skills: `/mvc-kit:guide` (framework reference), `/mvc-kit:scaffold <type> <Name>` (code generation), `/mvc-kit:review <path>` (pattern review).
|
|
29
|
+
**Claude Code** — installs `.claude/rules/` and `.claude/commands/`. Auto-updates on subsequent `npm install`/`npm update`.
|
|
34
30
|
|
|
35
31
|
**Cursor** — writes `.cursorrules`. **Copilot** — writes `.github/copilot-instructions.md`. Both use idempotent markers, safe to re-run.
|
|
36
32
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { resolve, join, dirname } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = dirname(__filename);
|
|
9
|
+
|
|
10
|
+
// INIT_CWD is set by npm/yarn/pnpm during lifecycle scripts — points to the project root
|
|
11
|
+
const projectRoot = process.env.INIT_CWD;
|
|
12
|
+
|
|
13
|
+
if (!projectRoot) {
|
|
14
|
+
process.exit(0);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Detect self-install (developing mvc-kit itself) — skip
|
|
18
|
+
const ownPackageRoot = resolve(__dirname, '../..');
|
|
19
|
+
if (resolve(projectRoot) === ownPackageRoot) {
|
|
20
|
+
process.exit(0);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// If the developer previously opted in (files exist), auto-update them
|
|
24
|
+
const rulesFile = join(projectRoot, '.claude', 'rules', 'mvc-kit.md');
|
|
25
|
+
|
|
26
|
+
if (existsSync(rulesFile)) {
|
|
27
|
+
try {
|
|
28
|
+
const { installClaude } = await import('../lib/install-claude.mjs');
|
|
29
|
+
installClaude(projectRoot);
|
|
30
|
+
console.log('');
|
|
31
|
+
console.log(' mvc-kit — Claude Code rules updated');
|
|
32
|
+
console.log('');
|
|
33
|
+
} catch {
|
|
34
|
+
// Never break npm install
|
|
35
|
+
}
|
|
36
|
+
} else {
|
|
37
|
+
console.log('');
|
|
38
|
+
console.log(' mvc-kit — AI agent setup available');
|
|
39
|
+
console.log(' Run: npx mvc-kit-setup');
|
|
40
|
+
console.log('');
|
|
41
|
+
}
|
|
@@ -4,6 +4,7 @@ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
|
4
4
|
import { join, dirname, resolve } from 'node:path';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
6
|
import { createInterface } from 'node:readline';
|
|
7
|
+
import { installClaude } from '../lib/install-claude.mjs';
|
|
7
8
|
|
|
8
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
10
|
const __dirname = dirname(__filename);
|
|
@@ -22,7 +23,7 @@ function printUsage() {
|
|
|
22
23
|
Usage: npx mvc-kit-setup [targets...] [options]
|
|
23
24
|
|
|
24
25
|
Targets:
|
|
25
|
-
claude
|
|
26
|
+
claude Install Claude Code rules and commands into .claude/
|
|
26
27
|
cursor Copy mvc-kit rules to .cursorrules
|
|
27
28
|
copilot Copy mvc-kit instructions to .github/copilot-instructions.md
|
|
28
29
|
all Set up all targets (default)
|
|
@@ -77,18 +78,17 @@ async function confirm(message) {
|
|
|
77
78
|
// ─── Target Handlers ──────────────────────────────────────
|
|
78
79
|
|
|
79
80
|
function setupClaude() {
|
|
80
|
-
const
|
|
81
|
+
const { files } = installClaude(PROJECT_DIR);
|
|
81
82
|
|
|
82
83
|
console.log('\n Claude Code');
|
|
83
84
|
console.log(' ───────────');
|
|
84
|
-
console.log('
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
console.log('
|
|
89
|
-
console.log('
|
|
90
|
-
console.log('
|
|
91
|
-
console.log(' /mvc-kit:review — Review code for pattern adherence\n');
|
|
85
|
+
console.log(' Installed (updates automatically on npm install/update):\n');
|
|
86
|
+
for (const f of files) {
|
|
87
|
+
console.log(` ${f}`);
|
|
88
|
+
}
|
|
89
|
+
console.log('');
|
|
90
|
+
console.log(' Commands: /project:mvc-kit-scaffold, /project:mvc-kit-review');
|
|
91
|
+
console.log(' Reference: Auto-loaded via .claude/rules/mvc-kit.md\n');
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
async function setupCursor(force) {
|
|
@@ -207,8 +207,7 @@ async function main() {
|
|
|
207
207
|
await setupCopilot(force);
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
console.log('Done
|
|
211
|
-
console.log(' npx mvc-kit-setup\n');
|
|
210
|
+
console.log('Done!\n');
|
|
212
211
|
}
|
|
213
212
|
|
|
214
213
|
main().catch((err) => {
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = dirname(__filename);
|
|
7
|
+
const SKILLS_DIR = join(__dirname, '..', 'claude-code', 'skills');
|
|
8
|
+
|
|
9
|
+
const AUTO_HEADER = '<!-- Auto-generated by mvc-kit. Updated on npm install/update. Do not edit. -->\n\n';
|
|
10
|
+
|
|
11
|
+
function stripFrontmatter(content) {
|
|
12
|
+
const match = content.match(/^---\n[\s\S]*?\n---\n([\s\S]*)$/);
|
|
13
|
+
return match ? match[1].trim() : content.trim();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function ensureDir(dir) {
|
|
17
|
+
if (!existsSync(dir)) {
|
|
18
|
+
mkdirSync(dir, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Install Claude Code integration files into a project's .claude/ directory.
|
|
24
|
+
*
|
|
25
|
+
* Creates:
|
|
26
|
+
* .claude/rules/mvc-kit.md — Framework reference (always loaded in context)
|
|
27
|
+
* .claude/commands/mvc-kit-scaffold.md — Scaffold command (/project:mvc-kit-scaffold)
|
|
28
|
+
* .claude/commands/mvc-kit-review.md — Review command (/project:mvc-kit-review)
|
|
29
|
+
*
|
|
30
|
+
* @param {string} projectRoot — Absolute path to the consuming project's root
|
|
31
|
+
* @returns {{ files: string[] }} — List of created/updated file paths (relative to projectRoot)
|
|
32
|
+
*/
|
|
33
|
+
export function installClaude(projectRoot) {
|
|
34
|
+
const claudeDir = join(projectRoot, '.claude');
|
|
35
|
+
const rulesDir = join(claudeDir, 'rules');
|
|
36
|
+
const commandsDir = join(claudeDir, 'commands');
|
|
37
|
+
|
|
38
|
+
ensureDir(rulesDir);
|
|
39
|
+
ensureDir(commandsDir);
|
|
40
|
+
|
|
41
|
+
const files = [];
|
|
42
|
+
|
|
43
|
+
// 1. Rules file — framework reference (always loaded in context)
|
|
44
|
+
const guideSkill = readFileSync(join(SKILLS_DIR, 'guide', 'SKILL.md'), 'utf-8');
|
|
45
|
+
const guideBody = stripFrontmatter(guideSkill)
|
|
46
|
+
// Remove the "Supporting Files" section — replaced by "Detailed Reference" below
|
|
47
|
+
.replace(/\n## Supporting Files[\s\S]*$/, '');
|
|
48
|
+
|
|
49
|
+
const rulesContent = AUTO_HEADER + guideBody + `
|
|
50
|
+
|
|
51
|
+
## Detailed Reference
|
|
52
|
+
|
|
53
|
+
For complete API details, patterns, and anti-patterns, read the files in:
|
|
54
|
+
\`node_modules/mvc-kit/agent-config/claude-code/skills/guide/\`
|
|
55
|
+
|
|
56
|
+
- \`api-reference.md\` — Full API reference for all classes and hooks
|
|
57
|
+
- \`patterns.md\` — Prescribed patterns with code examples
|
|
58
|
+
- \`anti-patterns.md\` — Anti-patterns to reject with fixes
|
|
59
|
+
`;
|
|
60
|
+
|
|
61
|
+
writeFileSync(join(rulesDir, 'mvc-kit.md'), rulesContent, 'utf-8');
|
|
62
|
+
files.push('.claude/rules/mvc-kit.md');
|
|
63
|
+
|
|
64
|
+
// 2. Scaffold command
|
|
65
|
+
const scaffoldSkill = readFileSync(join(SKILLS_DIR, 'scaffold', 'SKILL.md'), 'utf-8');
|
|
66
|
+
const scaffoldBody = stripFrontmatter(scaffoldSkill)
|
|
67
|
+
.replace(
|
|
68
|
+
'Read the template file from `templates/<type>.md` in this skill directory.',
|
|
69
|
+
'Read the template file from `node_modules/mvc-kit/agent-config/claude-code/skills/scaffold/templates/<type>.md`.'
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
writeFileSync(join(commandsDir, 'mvc-kit-scaffold.md'), AUTO_HEADER + scaffoldBody, 'utf-8');
|
|
73
|
+
files.push('.claude/commands/mvc-kit-scaffold.md');
|
|
74
|
+
|
|
75
|
+
// 3. Review command
|
|
76
|
+
const reviewSkill = readFileSync(join(SKILLS_DIR, 'review', 'SKILL.md'), 'utf-8');
|
|
77
|
+
const reviewBody = stripFrontmatter(reviewSkill)
|
|
78
|
+
.replaceAll(
|
|
79
|
+
'`checklist.md`',
|
|
80
|
+
'`node_modules/mvc-kit/agent-config/claude-code/skills/review/checklist.md`'
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
writeFileSync(join(commandsDir, 'mvc-kit-review.md'), AUTO_HEADER + reviewBody, 'utf-8');
|
|
84
|
+
files.push('.claude/commands/mvc-kit-review.md');
|
|
85
|
+
|
|
86
|
+
return { files };
|
|
87
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mvc-kit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Zero-magic, class-based reactive ViewModel library",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/mvc-kit.cjs",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"dev": "vite",
|
|
41
41
|
"dev:fullapp": "vite --config examples/react/FullApp/vite.config.ts",
|
|
42
42
|
"build": "rm -rf dist && tsc -p tsconfig.build.json && vite build",
|
|
43
|
+
"postinstall": "node agent-config/bin/postinstall.mjs",
|
|
43
44
|
"test": "vitest run",
|
|
44
45
|
"test:watch": "vitest"
|
|
45
46
|
},
|