@ikyyofc/gemini-cli 5.0.0 → 5.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": "@ikyyofc/gemini-cli",
3
- "version": "5.0.0",
3
+ "version": "5.0.1",
4
4
  "description": "AI Agent CLI — native function calling · GEMINI.md context · extensions",
5
5
  "type": "module",
6
6
  "bin": { "gemini": "./index.js" },
package/src/agent.js CHANGED
@@ -25,10 +25,9 @@ function buildSystemPrompt(extra = "") {
25
25
  const skillIndex = skills.length
26
26
  ? "\n## AVAILABLE SKILLS\n" +
27
27
  "Before starting any task, check if a skill applies. If yes, read it with read_file first.\n\n" +
28
- skills.map(s => {
29
- const desc = s.content.split("\n").find(l => l.trim() && !l.startsWith("#")) ?? "";
30
- return `- ${s.slug}: ${desc.slice(0, 100)}\n path: ${SKILLS_DIR}/${s.slug}/SKILL.md`;
31
- }).join("\n")
28
+ skills.map(s =>
29
+ `- ${s.slug}: ${s.description}\n path: ${SKILLS_DIR}/${s.slug}/SKILL.md`
30
+ ).join("\n")
32
31
  : "";
33
32
 
34
33
  return `You are an autonomous AI coding agent running in the user's terminal.
@@ -69,10 +68,9 @@ ${extra ? `\n## EXTRA\n${extra}` : ""}`.trim();
69
68
  function buildSkillPrimer(userMessage, skills) {
70
69
  if (!skills.length) return null;
71
70
 
72
- const index = skills.map(s => {
73
- const desc = s.content.split("\n").find(l => l.trim() && !l.startsWith("#")) ?? "";
74
- return `- ${s.slug}: ${desc.slice(0, 100)}`;
75
- }).join("\n");
71
+ const index = skills.map(s =>
72
+ `- ${s.slug}: ${s.description}`
73
+ ).join("\n");
76
74
 
77
75
  return `You have the following skills available. Before working on the task below, identify which skills (if any) are relevant and read their SKILL.md file using read_file. Only read skills that actually apply — do not read all of them.
78
76
 
package/src/skills.js CHANGED
@@ -96,6 +96,36 @@ export async function listNpxSkills() { return (await npxSkills("list")).stdo
96
96
  export async function updateSkill(slug = "") { return (await npxSkills(slug ? `update ${slug} -y` : "update -y")).stdout; }
97
97
  export async function initSkill(name = "") { return (await npxSkills(name ? `init "${name}"` : "init")).stdout; }
98
98
 
99
+ // ─────────────────────────────────────────────────────────────────
100
+ // Parse YAML frontmatter from SKILL.md
101
+ // Format:
102
+ // ---
103
+ // name: skill-name
104
+ // description: "..."
105
+ // ---
106
+ // ─────────────────────────────────────────────────────────────────
107
+ function parseFrontmatter(content) {
108
+ const match = content.match(/^---\s*\n([\s\S]*?)\n---/);
109
+ if (!match) return { name: null, description: null, body: content };
110
+
111
+ const fm = match[1];
112
+ const body = content.slice(match[0].length).trim();
113
+
114
+ const nameMatch = fm.match(/^name:\s*(.+)$/m);
115
+ const descMatch = fm.match(/^description:\s*["']?([\s\S]*?)["']?\s*$/m);
116
+
117
+ // description may span multiple lines if quoted
118
+ const descFull = fm.match(/^description:\s*"([\s\S]*?)"\s*$/m)
119
+ ?? fm.match(/^description:\s*'([\s\S]*?)'\s*$/m)
120
+ ?? fm.match(/^description:\s*(.+)$/m);
121
+
122
+ return {
123
+ name: nameMatch?.[1]?.trim() ?? null,
124
+ description: descFull?.[1]?.replace(/\s+/g, " ").trim() ?? null,
125
+ body,
126
+ };
127
+ }
128
+
99
129
  // ─────────────────────────────────────────────────────────────────
100
130
  // Load installed skills from SKILLS_DIR
101
131
  // ─────────────────────────────────────────────────────────────────
@@ -108,13 +138,18 @@ export function loadSkills() {
108
138
  const skillMd = path.join(SKILLS_DIR, entry.name, "SKILL.md");
109
139
  if (!fs.existsSync(skillMd)) continue;
110
140
 
111
- const content = fs.readFileSync(skillMd, "utf8");
112
- const nameMatch = content.match(/^#\s+(.+)$/m);
141
+ const content = fs.readFileSync(skillMd, "utf8");
142
+ const fm = parseFrontmatter(content);
143
+
144
+ // Fallback: try # heading if no frontmatter
145
+ const headingMatch = content.match(/^#\s+(.+)$/m);
146
+
113
147
  skills.push({
114
- name: nameMatch?.[1]?.trim() ?? entry.name,
115
- slug: entry.name,
148
+ name: fm.name ?? headingMatch?.[1]?.trim() ?? entry.name,
149
+ description: fm.description ?? fm.body.split("\n").find(l => l.trim() && !l.startsWith("#"))?.slice(0, 120) ?? "",
150
+ slug: entry.name,
116
151
  content,
117
- path: path.join(SKILLS_DIR, entry.name),
152
+ path: path.join(SKILLS_DIR, entry.name),
118
153
  });
119
154
  }
120
155
  return skills;