fix: remove gray-matter dependency, use inline frontmatter parser
gray-matter was excluded from VSIX via .vscodeignore, causing runtime module not found error. Replaced with a zero-dependency inline parser. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
4019
package-lock.json
generated
Normal file
4019
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@
|
|||||||
"categories": ["AI", "Other"],
|
"categories": ["AI", "Other"],
|
||||||
"keywords": ["copilot", "superpowers", "skills", "tdd", "brainstorming", "debugging"],
|
"keywords": ["copilot", "superpowers", "skills", "tdd", "brainstorming", "debugging"],
|
||||||
"icon": "images/icon.png",
|
"icon": "images/icon.png",
|
||||||
"activationEvents": [],
|
"activationEvents": ["onStartupFinished"],
|
||||||
"main": "./out/extension.js",
|
"main": "./out/extension.js",
|
||||||
"contributes": {
|
"contributes": {
|
||||||
"chatParticipants": [
|
"chatParticipants": [
|
||||||
@@ -65,9 +65,6 @@
|
|||||||
"package": "vsce package",
|
"package": "vsce package",
|
||||||
"publish": "vsce publish"
|
"publish": "vsce publish"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
|
||||||
"gray-matter": "^4.0.3"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.0.0",
|
"@types/node": "^20.0.0",
|
||||||
"@types/vscode": "^1.90.0",
|
"@types/vscode": "^1.90.0",
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import * as fs from 'fs';
|
|||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import matter from 'gray-matter';
|
|
||||||
import { Skill, SkillMap } from './types';
|
import { Skill, SkillMap } from './types';
|
||||||
|
|
||||||
const OUTPUT_CHANNEL_NAME = 'Superpowers';
|
const OUTPUT_CHANNEL_NAME = 'Superpowers';
|
||||||
@@ -16,32 +15,36 @@ function log(message: string): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Parse a SKILL.md file. Returns null and logs a warning on failure. */
|
/** Parse a SKILL.md file. Returns null and logs a warning on failure. */
|
||||||
function parseSkillFile(filePath: string, source: 'bundled' | 'custom'): Skill | null {
|
function parseFrontmatter(raw: string): { data: Record<string, string>; content: string } {
|
||||||
let raw: string;
|
const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
|
||||||
try {
|
if (!match) { return { data: {}, content: raw }; }
|
||||||
raw = fs.readFileSync(filePath, 'utf-8');
|
const data: Record<string, string> = {};
|
||||||
} catch (e) {
|
for (const line of match[1].split('\n')) {
|
||||||
log(`WARNING: Could not read file ${filePath}: ${String(e)}`);
|
const colonIdx = line.indexOf(':');
|
||||||
return null;
|
if (colonIdx === -1) { continue; }
|
||||||
}
|
const key = line.slice(0, colonIdx).trim();
|
||||||
|
let value = line.slice(colonIdx + 1).trim();
|
||||||
let parsed: matter.GrayMatterFile<string>;
|
if (/^["']/.test(value) && value.length > 1) { value = value.slice(1, value.endsWith('"') || value.endsWith("'") ? -1 :
|
||||||
try {
|
value.length); }
|
||||||
parsed = matter(raw);
|
if (key) { data[key] = value; }
|
||||||
} catch (e) {
|
}
|
||||||
log(`WARNING: Could not parse frontmatter in ${filePath}: ${String(e)}`);
|
return { data, content: match[2].trim() };
|
||||||
return null;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const { name, description } = parsed.data as Record<string, string>;
|
|
||||||
if (!name || !description) {
|
|
||||||
log(`WARNING: Missing required frontmatter fields (name, description) in ${filePath} — skipping`);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { name, description, content: parsed.content.trim(), source };
|
|
||||||
}
|
|
||||||
|
|
||||||
|
function parseSkillFile(filePath: string, source: 'bundled' | 'custom'): Skill | null {
|
||||||
|
let raw: string;
|
||||||
|
try { raw = fs.readFileSync(filePath, 'utf-8'); } catch (e) {
|
||||||
|
log(`WARNING: Could not read file ${filePath}: ${String(e)}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const { data, content } = parseFrontmatter(raw);
|
||||||
|
const { name, description } = data;
|
||||||
|
if (!name || !description) {
|
||||||
|
log(`WARNING: Missing required frontmatter (name, description) in ${filePath} — skipping`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return { name, description, content, source };
|
||||||
|
}
|
||||||
/** Resolve the custom skills directory path (cross-platform). */
|
/** Resolve the custom skills directory path (cross-platform). */
|
||||||
function resolveCustomPath(configuredPath: string): string {
|
function resolveCustomPath(configuredPath: string): string {
|
||||||
if (configuredPath && configuredPath !== '') {
|
if (configuredPath && configuredPath !== '') {
|
||||||
|
|||||||
Reference in New Issue
Block a user