Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 77 additions & 77 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,77 +1,77 @@
/**
* github-explore dsh bundle entry.
*
* A small Cordis plugin that reads this package's skill (Agent Plugins
* layout: skills/github-explore/SKILL.md) and registers it with ctx.skills,
* so the skill shows up in the agent's catalog when the package is installed
* as a dsh profile bundle:
*
* dsh plugin --profile web add <git-url-or-path>
*
* The skill body's relative references (scripts/, references/) resolve
* against the skill directory (skills/github-explore/) via resourceBase.
*/
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';

export const name = 'github-explore-skill';
export const inject = ['skills'];

/** Skill directory (Agent Plugins layout: skills/<name>/). */
const SKILL_DIR = new URL('../skills/github-explore/', import.meta.url);
const SKILL_FILE = new URL('SKILL.md', SKILL_DIR);

/** Minimal YAML-frontmatter parser for name/description/whenToUse. */
function parseFrontmatter(text) {
const match = text.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);
if (!match) return null;
const fm = match[1];
const get = (key) => {
const line = fm.match(new RegExp('^' + key + ':\s*(.+)$', 'm'));
if (!line) return undefined;
let value = line[1].trim();
const quoted = (value.startsWith('"') && value.endsWith('"'))
|| (value.startsWith("'") && value.endsWith("'"));
if (quoted) value = value.slice(1, -1);
return value;
};
return {
name: get('name'),
description: get('description'),
whenToUse: get('whenToUse'),
};
}

export function apply(ctx) {
let raw;
try {
raw = readFileSync(SKILL_FILE, 'utf-8');
} catch (error) {
ctx.logger.error('github-explore: cannot read SKILL.md: %s', error.message);
return;
}
const meta = parseFrontmatter(raw);
if (!meta || !meta.name || !meta.description) {
ctx.logger.error(
'github-explore: SKILL.md frontmatter missing name/description; skill not registered',
);
return;
}
const content = raw.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, '').trimStart();
const skill = {
name: meta.name,
description: meta.description,
...(meta.whenToUse ? { whenToUse: meta.whenToUse } : {}),
content,
source: 'runtime',
resourceBase: {
kind: 'directory',
path: fileURLToPath(SKILL_DIR),
},
};
const disposer = ctx.skills.register(skill);
ctx.logger.info('github-explore: registered skill "%s"', skill.name);
ctx.on('dispose', () => {
if (typeof disposer === 'function') disposer();
});
}
/**
* github-explore dsh bundle entry.
*
* A small Cordis plugin that reads this package's skill (Agent Plugins
* layout: skills/github-explore/SKILL.md) and registers it with ctx.skills,
* so the skill shows up in the agent's catalog when the package is installed
* as a dsh profile bundle:
*
* dsh plugin --profile web add <git-url-or-path>
*
* The skill body's relative references (scripts/, references/) resolve
* against the skill directory (skills/github-explore/) via resourceBase.
*/
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
export const name = 'github-explore-skill';
export const inject = ['skills'];
/** Skill directory (Agent Plugins layout: skills/<name>/). */
const SKILL_DIR = new URL('../skills/github-explore/', import.meta.url);
const SKILL_FILE = new URL('SKILL.md', SKILL_DIR);
/** Minimal YAML-frontmatter parser for name/description/whenToUse. */
function parseFrontmatter(text) {
const match = text.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);
if (!match) return null;
const fm = match[1];
const get = (key) => {
const line = fm.match(new RegExp('^' + key + ':\\s*(.+)$', 'm'));
if (!line) return undefined;
let value = line[1].trim();
const quoted = (value.startsWith('"') && value.endsWith('"'))
|| (value.startsWith("'") && value.endsWith("'"));
if (quoted) value = value.slice(1, -1);
return value;
};
return {
name: get('name'),
description: get('description'),
whenToUse: get('whenToUse'),
};
}
export function apply(ctx) {
let raw;
try {
raw = readFileSync(SKILL_FILE, 'utf-8');
} catch (error) {
ctx.logger.error('github-explore: cannot read SKILL.md: %s', error.message);
return;
}
const meta = parseFrontmatter(raw);
if (!meta || !meta.name || !meta.description) {
ctx.logger.error(
'github-explore: SKILL.md frontmatter missing name/description; skill not registered',
);
return;
}
const content = raw.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, '').trimStart();
const skill = {
name: meta.name,
description: meta.description,
...(meta.whenToUse ? { whenToUse: meta.whenToUse } : {}),
content,
source: 'runtime',
resourceBase: {
kind: 'directory',
path: fileURLToPath(SKILL_DIR),
},
};
const disposer = ctx.skills.register(skill);
ctx.logger.info('github-explore: registered skill "%s"', skill.name);
ctx.on('dispose', () => {
if (typeof disposer === 'function') disposer();
});
}