@ikyyofc/gemini-cli 3.0.5 → 3.0.6
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 +1 -1
- package/src/skills.js +49 -32
package/package.json
CHANGED
package/src/skills.js
CHANGED
|
@@ -110,40 +110,45 @@ function consolidate(cwd, beforeSnapshot) {
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
// ─────────────────────────────────────────────────────────────────
|
|
113
|
-
// Install
|
|
114
|
-
//
|
|
115
|
-
// 2. npx skills add (wherever it installs)
|
|
116
|
-
// 3. Find new SKILL.md files and copy ALL → ~/.agents/
|
|
113
|
+
// Install — npx skills puts files directly into ~/.agents/skills/
|
|
114
|
+
// No post-copy needed; just run npx and report what's new
|
|
117
115
|
// ─────────────────────────────────────────────────────────────────
|
|
118
116
|
export async function installSkill(rawSource, opts = {}) {
|
|
119
117
|
const { skill: explicitSkill = null, all = false } = opts;
|
|
120
118
|
const { source, skill: parsedSkill } = parseSource(rawSource);
|
|
121
119
|
const skillName = explicitSkill ?? parsedSkill;
|
|
122
120
|
|
|
123
|
-
|
|
124
|
-
const before = new Set(
|
|
125
|
-
KNOWN_AGENT_DIRS.flatMap(rel => scanForSkillMds(path.join(cwd, rel), 3))
|
|
126
|
-
);
|
|
121
|
+
// Snapshot before
|
|
122
|
+
const before = new Set(loadSkills().map(s => s.slug));
|
|
127
123
|
|
|
128
124
|
const parts = ["add", source, "-y"];
|
|
129
125
|
if (skillName) parts.push(`--skill "${skillName}"`);
|
|
130
126
|
if (all) parts.push("--skill '*'");
|
|
131
127
|
|
|
132
128
|
const { stdout, stderr } = await npxSkills(parts.join(" "));
|
|
133
|
-
const installed = consolidate(cwd, before);
|
|
134
129
|
|
|
135
|
-
|
|
130
|
+
// Report what was newly installed
|
|
131
|
+
const after = loadSkills().map(s => s.slug);
|
|
132
|
+
const newSlugs = after.filter(s => !before.has(s));
|
|
133
|
+
|
|
134
|
+
return { output: stdout || stderr, installed: newSlugs };
|
|
136
135
|
}
|
|
137
136
|
|
|
138
137
|
// ─────────────────────────────────────────────────────────────────
|
|
139
|
-
// Remove —
|
|
138
|
+
// Remove — checks both ~/.agents/<slug>/ and ~/.agents/skills/<slug>/
|
|
140
139
|
// ─────────────────────────────────────────────────────────────────
|
|
141
140
|
export async function removeSkillNpx(slug) {
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
const candidates = [
|
|
142
|
+
path.join(AGENTS_DIR, slug),
|
|
143
|
+
path.join(AGENTS_DIR, "skills", slug),
|
|
144
|
+
];
|
|
145
|
+
const found = candidates.filter(d => fs.existsSync(d));
|
|
146
|
+
if (!found.length) throw new Error(`"${slug}" not found in ~/.agents/`);
|
|
147
|
+
|
|
148
|
+
found.forEach(d => fs.rmSync(d, { recursive: true, force: true }));
|
|
145
149
|
try { await npxSkills(`remove ${slug} -y`); } catch {}
|
|
146
|
-
|
|
150
|
+
|
|
151
|
+
return { output: `Removed: ${found.join(", ")}` };
|
|
147
152
|
}
|
|
148
153
|
|
|
149
154
|
// ─────────────────────────────────────────────────────────────────
|
|
@@ -167,26 +172,38 @@ export async function initSkill(name = "") {
|
|
|
167
172
|
}
|
|
168
173
|
|
|
169
174
|
// ─────────────────────────────────────────────────────────────────
|
|
170
|
-
// Load all skills
|
|
175
|
+
// Load all skills — scans both:
|
|
176
|
+
// ~/.agents/<slug>/SKILL.md (manual / flat)
|
|
177
|
+
// ~/.agents/skills/<slug>/SKILL.md (npx skills default)
|
|
171
178
|
// ─────────────────────────────────────────────────────────────────
|
|
172
179
|
export function loadSkills() {
|
|
173
180
|
const skills = [];
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (!
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
181
|
+
const seen = new Set();
|
|
182
|
+
|
|
183
|
+
const scanBase = (baseDir) => {
|
|
184
|
+
if (!fs.existsSync(baseDir)) return;
|
|
185
|
+
for (const entry of fs.readdirSync(baseDir, { withFileTypes: true })) {
|
|
186
|
+
if (!entry.isDirectory()) continue;
|
|
187
|
+
if (seen.has(entry.name)) continue;
|
|
188
|
+
const skillMd = path.join(baseDir, entry.name, "SKILL.md");
|
|
189
|
+
if (!fs.existsSync(skillMd)) continue;
|
|
190
|
+
seen.add(entry.name);
|
|
191
|
+
const content = fs.readFileSync(skillMd, "utf8");
|
|
192
|
+
const nameMatch = content.match(/^#\s+(.+)$/m);
|
|
193
|
+
skills.push({
|
|
194
|
+
name: nameMatch?.[1]?.trim() ?? entry.name,
|
|
195
|
+
slug: entry.name,
|
|
196
|
+
content,
|
|
197
|
+
path: path.join(baseDir, entry.name),
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
// Flat: ~/.agents/<slug>/SKILL.md
|
|
203
|
+
scanBase(AGENTS_DIR);
|
|
204
|
+
// Nested: ~/.agents/skills/<slug>/SKILL.md (npx skills default)
|
|
205
|
+
scanBase(path.join(AGENTS_DIR, "skills"));
|
|
206
|
+
|
|
190
207
|
return skills;
|
|
191
208
|
}
|
|
192
209
|
|