evizi-cli 1.0.0 → 1.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evizi-cli",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Install and manage agent kits from evizi-kit",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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
- totalFiles += copiedFiles.length;
116
- console.log(` ✓ ${manifest.displayName} (${copiedFiles.length} files)`);
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
@@ -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
- // Remove orphaned files (in old lockfile but not in new copy)
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
 
@@ -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
  }