@bleedingdev/modern-js-create 3.2.0-ultramodern.21 → 3.2.0-ultramodern.23

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.
@@ -8,7 +8,7 @@ const lockPath = path.join(root, '.agents/skills-lock.json');
8
8
  const checkOnly = process.argv.includes('--check');
9
9
  const force = process.argv.includes('--force');
10
10
 
11
- const readJson = (filePath) => JSON.parse(fs.readFileSync(filePath, 'utf-8'));
11
+ const readJson = filePath => JSON.parse(fs.readFileSync(filePath, 'utf-8'));
12
12
 
13
13
  const run = (command, args, options = {}) =>
14
14
  execFileSync(command, args, {
@@ -28,6 +28,23 @@ const cloneSource = (source, targetDir) => {
28
28
  stdio: 'inherit',
29
29
  });
30
30
  }
31
+ if (source.commit) {
32
+ try {
33
+ run('git', ['checkout', source.commit], {
34
+ cwd: targetDir,
35
+ stdio: 'inherit',
36
+ });
37
+ } catch {
38
+ run('git', ['fetch', '--depth', '1', 'origin', source.commit], {
39
+ cwd: targetDir,
40
+ stdio: 'inherit',
41
+ });
42
+ run('git', ['checkout', source.commit], {
43
+ cwd: targetDir,
44
+ stdio: 'inherit',
45
+ });
46
+ }
47
+ }
31
48
  };
32
49
 
33
50
  const resolveSkillDir = (sourceRoot, skillName) => {
@@ -37,7 +54,9 @@ const resolveSkillDir = (sourceRoot, skillName) => {
37
54
  path.join(sourceRoot, 'skills', 'engineering', skillName),
38
55
  path.join(sourceRoot, 'skills', 'productivity', skillName),
39
56
  ];
40
- return candidates.find((candidate) => fs.existsSync(path.join(candidate, 'SKILL.md')));
57
+ return candidates.find(candidate =>
58
+ fs.existsSync(path.join(candidate, 'SKILL.md')),
59
+ );
41
60
  };
42
61
 
43
62
  if (!fs.existsSync(lockPath)) {
@@ -47,36 +66,77 @@ if (!fs.existsSync(lockPath)) {
47
66
 
48
67
  const lock = readJson(lockPath);
49
68
  const installDir = path.join(root, lock.installDir ?? '.agents/skills');
50
- const privateSources = (lock.sources ?? []).filter(
51
- (source) => source.install === 'clone-if-authorized',
69
+ const sources = lock.sources ?? [];
70
+ const requiredCloneSources = sources.filter(
71
+ source => source.install === 'clone',
72
+ );
73
+ const optionalCloneSources = sources.filter(
74
+ source => source.install === 'clone-if-authorized',
75
+ );
76
+ const requiredSkills = [
77
+ ...(lock.baseline ?? []),
78
+ ...requiredCloneSources.flatMap(source => source.baseline ?? []),
79
+ ].filter(
80
+ (skill, index, skills) =>
81
+ skills.findIndex(candidate => candidate.name === skill.name) === index,
52
82
  );
53
83
 
54
84
  if (checkOnly) {
55
- const missing = privateSources.flatMap((source) =>
85
+ const missingRequired = requiredSkills
86
+ .map(skill => skill.name)
87
+ .filter(
88
+ skillName => !fs.existsSync(path.join(installDir, skillName, 'SKILL.md')),
89
+ );
90
+ const missingOptional = optionalCloneSources.flatMap(source =>
56
91
  (source.baseline ?? [])
57
- .map((skill) => skill.name)
58
- .filter((skillName) => !fs.existsSync(path.join(installDir, skillName, 'SKILL.md'))),
92
+ .map(skill => skill.name)
93
+ .filter(
94
+ skillName =>
95
+ !fs.existsSync(path.join(installDir, skillName, 'SKILL.md')),
96
+ ),
59
97
  );
60
- if (missing.length > 0) {
98
+
99
+ if (missingRequired.length > 0) {
100
+ console.error(
101
+ `Required agent skills not installed: ${missingRequired.join(', ')}. Run pnpm skills:install.`,
102
+ );
103
+ process.exit(1);
104
+ }
105
+
106
+ if (missingOptional.length > 0) {
61
107
  console.warn(
62
- `Private skills not installed: ${missing.join(', ')}. Run pnpm skills:install if you have access.`,
108
+ `Private skills not installed: ${missingOptional.join(', ')}. Run pnpm skills:install if you have access.`,
63
109
  );
64
110
  } else {
65
- console.log('Agent skills are installed.');
111
+ console.log('Required and private agent skills are installed.');
112
+ process.exit(0);
66
113
  }
114
+ console.log('Required agent skills are installed.');
67
115
  process.exit(0);
68
116
  }
69
117
 
70
118
  fs.mkdirSync(installDir, { recursive: true });
71
119
 
72
- for (const source of privateSources) {
120
+ for (const source of [...requiredCloneSources, ...optionalCloneSources]) {
73
121
  const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ultramodern-skills-'));
74
122
  try {
75
- cloneSource(source, tempDir);
123
+ try {
124
+ cloneSource(source, tempDir);
125
+ } catch (error) {
126
+ if (source.install === 'clone-if-authorized') {
127
+ console.warn(
128
+ `Skipping ${source.repository}; current developer may not have access.`,
129
+ );
130
+ continue;
131
+ }
132
+ throw error;
133
+ }
76
134
  for (const skill of source.baseline ?? []) {
77
135
  const sourceSkillDir = resolveSkillDir(tempDir, skill.name);
78
136
  if (!sourceSkillDir) {
79
- throw new Error(`Skill ${skill.name} not found in ${source.repository}`);
137
+ throw new Error(
138
+ `Skill ${skill.name} not found in ${source.repository}`,
139
+ );
80
140
  }
81
141
  const targetSkillDir = path.join(installDir, skill.name);
82
142
  if (fs.existsSync(targetSkillDir)) {