evizi-cli 1.0.0 → 1.0.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.
- package/bin/evizi.js +42 -2
- package/package.json +1 -1
- package/src/commands/init.js +30 -3
- package/src/commands/upgrade.js +22 -2
- package/src/lib/copier.js +41 -0
- package/src/lib/manifest.js +1 -0
package/bin/evizi.js
CHANGED
|
@@ -6,8 +6,31 @@ import { upgradeCommand } from '../src/commands/upgrade.js';
|
|
|
6
6
|
|
|
7
7
|
program
|
|
8
8
|
.name('evizi')
|
|
9
|
-
.description(
|
|
10
|
-
|
|
9
|
+
.description(
|
|
10
|
+
`Multi-agent development kit CLI
|
|
11
|
+
|
|
12
|
+
Install and manage agent kits (Claude Code, Cursor, GitHub Copilot, etc.)
|
|
13
|
+
into your project. Each kit provides agents and skills tailored for a
|
|
14
|
+
specific AI coding platform.
|
|
15
|
+
|
|
16
|
+
Available kits:
|
|
17
|
+
claude Claude Code (.claude/)
|
|
18
|
+
cursor Cursor (.cursor/)
|
|
19
|
+
github GitHub Copilot (.github/)
|
|
20
|
+
agent VS Code Agent (.agent/)
|
|
21
|
+
shared Shared skills & docs (auto-included as dependency)
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
$ evizi init Interactive kit selection
|
|
25
|
+
$ evizi init --agent claude Install Claude Code kit
|
|
26
|
+
$ evizi init --agent claude,cursor Install multiple kits
|
|
27
|
+
$ evizi init --all Install all kits
|
|
28
|
+
$ evizi upgrade Upgrade to latest version
|
|
29
|
+
|
|
30
|
+
After install, shared skills are automatically merged into each
|
|
31
|
+
agent's skills folder (e.g. .claude/skills/, .cursor/skills/).`,
|
|
32
|
+
)
|
|
33
|
+
.version('1.0.1');
|
|
11
34
|
|
|
12
35
|
program
|
|
13
36
|
.command('init')
|
|
@@ -15,12 +38,29 @@ program
|
|
|
15
38
|
.option('--agent <kits>', 'Comma-separated kit names (e.g. claude,cursor,github)')
|
|
16
39
|
.option('--all', 'Install all available kits')
|
|
17
40
|
.option('--local <path>', 'Use local evizi-kit directory instead of npm')
|
|
41
|
+
.addHelpText(
|
|
42
|
+
'after',
|
|
43
|
+
`
|
|
44
|
+
Examples:
|
|
45
|
+
$ evizi init Prompt to select kits interactively
|
|
46
|
+
$ evizi init --agent claude Install only Claude Code kit
|
|
47
|
+
$ evizi init --agent claude,cursor Install Claude Code and Cursor kits
|
|
48
|
+
$ evizi init --all Install all available kits
|
|
49
|
+
$ evizi init --local ./evizi-kit Use a local evizi-kit directory (for dev)`,
|
|
50
|
+
)
|
|
18
51
|
.action(initCommand);
|
|
19
52
|
|
|
20
53
|
program
|
|
21
54
|
.command('upgrade')
|
|
22
55
|
.description('Upgrade installed agent kits to latest version')
|
|
23
56
|
.option('--local <path>', 'Use local evizi-kit directory instead of npm')
|
|
57
|
+
.addHelpText(
|
|
58
|
+
'after',
|
|
59
|
+
`
|
|
60
|
+
Examples:
|
|
61
|
+
$ evizi upgrade Upgrade all installed kits from npm
|
|
62
|
+
$ evizi upgrade --local ./evizi-kit Upgrade from a local directory`,
|
|
63
|
+
)
|
|
24
64
|
.action(upgradeCommand);
|
|
25
65
|
|
|
26
66
|
program.parse();
|
package/package.json
CHANGED
package/src/commands/init.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
loadManifest,
|
|
8
8
|
} from '../lib/manifest.js';
|
|
9
9
|
import { loadIgnorePatterns } from '../lib/ignore.js';
|
|
10
|
-
import { copyKit } from '../lib/copier.js';
|
|
10
|
+
import { copyKit, copyDependencyFiles } from '../lib/copier.js';
|
|
11
11
|
import { readLockfile, writeLockfile } from '../lib/lockfile.js';
|
|
12
12
|
|
|
13
13
|
export async function initCommand(options) {
|
|
@@ -96,9 +96,13 @@ export async function initCommand(options) {
|
|
|
96
96
|
// Copy kits
|
|
97
97
|
const kitsData = {};
|
|
98
98
|
let totalFiles = 0;
|
|
99
|
+
const manifests = {};
|
|
99
100
|
|
|
101
|
+
// First pass: copy each kit's own files
|
|
100
102
|
for (const kitName of resolvedNames) {
|
|
101
103
|
const manifest = loadManifest(kitsDir, kitName);
|
|
104
|
+
manifests[kitName] = manifest;
|
|
105
|
+
|
|
102
106
|
const copiedFiles = copyKit(
|
|
103
107
|
kitsDir,
|
|
104
108
|
kitName,
|
|
@@ -111,9 +115,32 @@ export async function initCommand(options) {
|
|
|
111
115
|
version: manifest.version,
|
|
112
116
|
files: copiedFiles,
|
|
113
117
|
};
|
|
118
|
+
}
|
|
114
119
|
|
|
115
|
-
|
|
116
|
-
|
|
120
|
+
// Second pass: copy shared dependency files into each agent kit's folder
|
|
121
|
+
for (const kitName of resolvedNames) {
|
|
122
|
+
const manifest = manifests[kitName];
|
|
123
|
+
for (const depName of manifest.dependencies) {
|
|
124
|
+
const depManifest = manifests[depName];
|
|
125
|
+
if (!depManifest) continue;
|
|
126
|
+
|
|
127
|
+
const depFiles = copyDependencyFiles(
|
|
128
|
+
kitsDir,
|
|
129
|
+
depName,
|
|
130
|
+
depManifest,
|
|
131
|
+
manifest,
|
|
132
|
+
targetDir,
|
|
133
|
+
ignorePatterns,
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
kitsData[kitName].files.push(...depFiles);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
for (const kitName of resolvedNames) {
|
|
141
|
+
const fileCount = kitsData[kitName].files.length;
|
|
142
|
+
totalFiles += fileCount;
|
|
143
|
+
console.log(` ✓ ${manifests[kitName].displayName} (${fileCount} files)`);
|
|
117
144
|
}
|
|
118
145
|
|
|
119
146
|
// Write lockfile
|
package/src/commands/upgrade.js
CHANGED
|
@@ -3,7 +3,7 @@ import { join } from 'node:path';
|
|
|
3
3
|
import { resolveKitSource } from '../lib/resolver.js';
|
|
4
4
|
import { loadManifest } from '../lib/manifest.js';
|
|
5
5
|
import { loadIgnorePatterns } from '../lib/ignore.js';
|
|
6
|
-
import { copyKit } from '../lib/copier.js';
|
|
6
|
+
import { copyKit, copyDependencyFiles } from '../lib/copier.js';
|
|
7
7
|
import { readLockfile, writeLockfile } from '../lib/lockfile.js';
|
|
8
8
|
|
|
9
9
|
export async function upgradeCommand(options) {
|
|
@@ -58,7 +58,7 @@ export async function upgradeCommand(options) {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
//
|
|
61
|
+
// Copy kit's own files
|
|
62
62
|
const copiedFiles = copyKit(
|
|
63
63
|
kitsDir,
|
|
64
64
|
kitName,
|
|
@@ -67,6 +67,26 @@ export async function upgradeCommand(options) {
|
|
|
67
67
|
ignorePatterns,
|
|
68
68
|
);
|
|
69
69
|
|
|
70
|
+
// Copy shared dependency files into agent kit's folder
|
|
71
|
+
for (const depName of manifest.dependencies) {
|
|
72
|
+
let depManifest;
|
|
73
|
+
try {
|
|
74
|
+
depManifest = loadManifest(kitsDir, depName);
|
|
75
|
+
} catch {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const depFiles = copyDependencyFiles(
|
|
79
|
+
kitsDir,
|
|
80
|
+
depName,
|
|
81
|
+
depManifest,
|
|
82
|
+
manifest,
|
|
83
|
+
targetDir,
|
|
84
|
+
ignorePatterns,
|
|
85
|
+
);
|
|
86
|
+
copiedFiles.push(...depFiles);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Remove orphaned files (in old lockfile but not in new copy)
|
|
70
90
|
const newFileSet = new Set(copiedFiles);
|
|
71
91
|
for (const oldFile of oldKit.files || []) {
|
|
72
92
|
if (!newFileSet.has(oldFile)) {
|
package/src/lib/copier.js
CHANGED
|
@@ -32,6 +32,47 @@ export function copyKit(kitsDir, kitName, manifest, targetDir, ignorePatterns) {
|
|
|
32
32
|
return copiedFiles;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Copy shared dependency files into an agent kit's folder using dependencyMappings.
|
|
37
|
+
* e.g., shared skills/ → .claude/skills/
|
|
38
|
+
*/
|
|
39
|
+
export function copyDependencyFiles(
|
|
40
|
+
kitsDir,
|
|
41
|
+
depName,
|
|
42
|
+
depManifest,
|
|
43
|
+
agentManifest,
|
|
44
|
+
targetDir,
|
|
45
|
+
ignorePatterns,
|
|
46
|
+
) {
|
|
47
|
+
const mappings = agentManifest.dependencyMappings[depName];
|
|
48
|
+
if (!mappings) return [];
|
|
49
|
+
|
|
50
|
+
const copiedFiles = [];
|
|
51
|
+
const depDir = join(kitsDir, depName);
|
|
52
|
+
|
|
53
|
+
for (const depFileMapping of depManifest.files) {
|
|
54
|
+
const destOverride = mappings[depFileMapping.src];
|
|
55
|
+
if (!destOverride) continue;
|
|
56
|
+
|
|
57
|
+
const srcPath = join(depDir, depFileMapping.src);
|
|
58
|
+
const destPath = join(targetDir, destOverride);
|
|
59
|
+
|
|
60
|
+
const stat = statSync(srcPath, { throwIfNoEntry: false });
|
|
61
|
+
if (!stat) continue;
|
|
62
|
+
|
|
63
|
+
if (stat.isDirectory()) {
|
|
64
|
+
walkAndCopy(srcPath, destPath, destOverride, ignorePatterns, copiedFiles);
|
|
65
|
+
} else {
|
|
66
|
+
if (isIgnored(destOverride, ignorePatterns)) continue;
|
|
67
|
+
mkdirSync(join(targetDir, destOverride, '..'), { recursive: true });
|
|
68
|
+
copyFileSync(srcPath, destPath);
|
|
69
|
+
copiedFiles.push(destOverride);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return copiedFiles;
|
|
74
|
+
}
|
|
75
|
+
|
|
35
76
|
function walkAndCopy(srcDir, destDir, baseRelPath, ignorePatterns, copiedFiles) {
|
|
36
77
|
const entries = readdirSync(srcDir, { withFileTypes: true });
|
|
37
78
|
|
package/src/lib/manifest.js
CHANGED
|
@@ -16,6 +16,7 @@ export function loadManifest(kitsDir, kitName) {
|
|
|
16
16
|
description: manifest.description || '',
|
|
17
17
|
files: manifest.files || [],
|
|
18
18
|
dependencies: manifest.dependencies || [],
|
|
19
|
+
dependencyMappings: manifest.dependencyMappings || {},
|
|
19
20
|
deletions: manifest.deletions || [],
|
|
20
21
|
};
|
|
21
22
|
}
|