@hasna/skills 0.1.13 → 0.1.14
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/bin/index.js +639 -291
- package/bin/mcp.js +301 -180
- package/dist/index.d.ts +4 -2
- package/dist/index.js +190 -2
- package/dist/lib/config.d.ts +27 -0
- package/dist/lib/config.test.d.ts +1 -0
- package/dist/lib/installer.d.ts +25 -0
- package/dist/lib/registry.d.ts +4 -0
- package/dist/types/api.d.ts +74 -0
- package/package.json +5 -2
- package/skills/skill-academic-journal-matcher/bin/cli.ts +34 -0
- package/skills/skill-action-item-router/bin/cli.ts +34 -0
- package/skills/skill-ad-creative-generator/bin/cli.ts +34 -0
- package/skills/skill-advanced-math/bin/cli.ts +34 -0
- package/skills/skill-analyze-data/bin/cli.ts +19 -0
- package/skills/skill-anomaly-investigator/bin/cli.ts +34 -0
- package/skills/skill-api-test-suite/bin/cli.ts +34 -0
- package/skills/skill-apidocs/bin/cli.ts +87 -0
- package/skills/skill-audio-cleanup-lab/bin/cli.ts +6 -0
- package/skills/skill-audiobook-chapter-proofer/bin/cli.ts +34 -0
- package/skills/skill-banner-ad-suite/bin/cli.ts +34 -0
- package/skills/skill-benchmark-finder/bin/cli.ts +34 -0
- package/skills/skill-bio-sequence-tool/bin/cli.ts +34 -0
- package/skills/skill-blog-topic-cluster/bin/cli.ts +34 -0
- package/skills/skill-brand-style-guide/bin/cli.ts +19 -0
- package/skills/skill-brand-voice-audit/bin/cli.ts +34 -0
- package/skills/skill-budget-variance-analyzer/bin/cli.ts +6 -0
- package/skills/skill-businessactivity/bin/cli.ts +28 -0
- package/skills/skill-calendar-events/bin/cli.ts +34 -0
- package/skills/skill-campaign-metric-brief/bin/cli.ts +34 -0
- package/skills/skill-campaign-moodboard/bin/cli.ts +34 -0
- package/skills/skill-caption-style-stylist/bin/cli.ts +34 -0
- package/skills/skill-chemistry-calculator/bin/cli.ts +34 -0
- package/skills/skill-churn-risk-notifier/bin/cli.ts +34 -0
- package/skills/skill-citation-formatter/bin/cli.ts +34 -0
- package/skills/skill-classroom-newsletter-kit/bin/cli.ts +34 -0
- package/skills/skill-color-palette-harmonizer/bin/cli.ts +34 -0
- package/skills/skill-competitor-ad-analyzer/bin/cli.ts +34 -0
- package/skills/skill-compliance-copy-check/bin/cli.ts +34 -0
- package/skills/skill-compliance-report-pack/bin/cli.ts +34 -0
- package/skills/skill-compress-video/bin/cli.ts +19 -0
- package/skills/skill-consolelog/bin/cli.ts +884 -0
- package/skills/skill-contract-plainlanguage/bin/cli.ts +34 -0
- package/skills/skill-copytone-translator/bin/cli.ts +34 -0
- package/skills/skill-create-blog-article/bin/cli.ts +34 -0
- package/skills/skill-create-ebook/bin/cli.ts +34 -0
- package/skills/skill-crm-note-enhancer/bin/cli.ts +34 -0
- package/skills/skill-customer-journey-mapper/bin/cli.ts +34 -0
- package/skills/skill-dashboard-builder/bin/cli.ts +34 -0
- package/skills/skill-dashboard-narrator/bin/cli.ts +34 -0
- package/skills/skill-data-anonymizer/bin/cli.ts +34 -0
- package/skills/skill-database-explorer/bin/cli.ts +34 -0
- package/skills/skill-dataset-health-check/bin/cli.ts +34 -0
- package/skills/skill-decision-journal/bin/cli.ts +34 -0
- package/skills/skill-delegation-brief-writer/bin/cli.ts +34 -0
- package/skills/skill-destination-briefing/bin/cli.ts +34 -0
- package/skills/skill-diff-viewer/bin/cli.ts +34 -0
- package/skills/skill-domainpurchase/SKILL.md +46 -0
- package/skills/skill-domainpurchase/bin/cli.ts +683 -0
- package/skills/skill-domainsearch/SKILL.md +41 -0
- package/skills/skill-domainsearch/bin/cli.ts +410 -0
- package/skills/skill-educational-resource-finder/bin/cli.ts +34 -0
- package/skills/skill-email-campaign/bin/cli.ts +34 -0
- package/skills/skill-exam-readiness-check/bin/cli.ts +34 -0
- package/skills/skill-experiment-power-calculator/bin/cli.ts +34 -0
- package/skills/skill-extract-audio/bin/cli.ts +19 -0
- package/skills/skill-extract-frames/bin/cli.ts +34 -0
- package/skills/skill-extract-invoice/bin/cli.ts +34 -0
- package/skills/skill-family-activity-curator/bin/cli.ts +34 -0
- package/skills/skill-faq-packager/bin/cli.ts +34 -0
- package/skills/skill-feedback-survey-designer/bin/cli.ts +34 -0
- package/skills/skill-field-trip-planner/bin/cli.ts +34 -0
- package/skills/skill-file-organizer/bin/cli.ts +34 -0
- package/skills/skill-folder-tree/bin/cli.ts +34 -0
- package/skills/skill-forecast-scenario-lab/bin/cli.ts +34 -0
- package/skills/skill-form-filler/bin/cli.ts +34 -0
- package/skills/skill-generate-api-client/bin/cli.ts +34 -0
- package/skills/skill-generate-book-cover/bin/cli.ts +34 -0
- package/skills/skill-generate-chart/bin/cli.ts +34 -0
- package/skills/skill-generate-diagram/bin/cli.ts +34 -0
- package/skills/skill-generate-dockerfile/bin/cli.ts +34 -0
- package/skills/skill-generate-documentation/bin/cli.ts +34 -0
- package/skills/skill-generate-docx/bin/cli.ts +6 -0
- package/skills/skill-generate-env/bin/cli.ts +34 -0
- package/skills/skill-generate-excel/bin/cli.ts +34 -0
- package/skills/skill-generate-favicon/bin/cli.ts +34 -0
- package/skills/skill-generate-mock-data/bin/cli.ts +34 -0
- package/skills/skill-generate-pdf/bin/cli.ts +6 -0
- package/skills/skill-generate-pr-description/bin/cli.ts +34 -0
- package/skills/skill-generate-presentation/bin/cli.ts +34 -0
- package/skills/skill-generate-qrcode/bin/cli.ts +34 -0
- package/skills/skill-generate-regex/bin/cli.ts +34 -0
- package/skills/skill-generate-resume/bin/cli.ts +34 -0
- package/skills/skill-generate-sitemap/bin/cli.ts +34 -0
- package/skills/skill-generate-social-posts/bin/cli.ts +34 -0
- package/skills/skill-generate-sql/bin/cli.ts +34 -0
- package/skills/skill-gif-maker/bin/cli.ts +34 -0
- package/skills/skill-github-manager/bin/cli.ts +34 -0
- package/skills/skill-gmail/bin/cli.ts +34 -0
- package/skills/skill-goal-quarterly-roadmap/bin/cli.ts +34 -0
- package/skills/skill-grant-application-drafter/bin/cli.ts +34 -0
- package/skills/skill-grocery-basket-optimizer/bin/cli.ts +34 -0
- package/skills/skill-guest-communication-suite/bin/cli.ts +34 -0
- package/skills/skill-habit-reflection-digest/bin/cli.ts +34 -0
- package/skills/skill-highlight-reel-generator/bin/cli.ts +34 -0
- package/skills/skill-homework-feedback-coach/bin/cli.ts +34 -0
- package/skills/skill-hook/bunfig.toml +5 -0
- package/skills/skill-household-maintenance-mgr/bin/cli.ts +34 -0
- package/skills/skill-http-server/bin/cli.ts +34 -0
- package/skills/skill-implementation/bunfig.toml +5 -0
- package/skills/skill-implementation-agent/bin/cli.ts +34 -0
- package/skills/skill-implementation-plan/bin/cli.ts +34 -0
- package/skills/skill-implementation-todo/bin/cli.ts +34 -0
- package/skills/skill-inbox-priority-planner/bin/cli.ts +34 -0
- package/skills/skill-invoice/bin/cli.ts +20 -0
- package/skills/skill-invoice-dispute-helper/bin/cli.ts +34 -0
- package/skills/skill-itinerary-architect/bin/cli.ts +34 -0
- package/skills/skill-jingle-composer/bin/cli.ts +34 -0
- package/skills/skill-kpi-digest-generator/bin/cli.ts +34 -0
- package/skills/skill-lab-notebook-formatter/bin/cli.ts +34 -0
- package/skills/skill-landing-page-copy/bin/cli.ts +34 -0
- package/skills/skill-latex-table-generator/bin/cli.ts +34 -0
- package/skills/skill-learning-style-profiler/bin/cli.ts +34 -0
- package/skills/skill-lesson-plan-customizer/bin/cli.ts +34 -0
- package/skills/skill-livestream-runofshow/bin/cli.ts +34 -0
- package/skills/skill-longform-structurer/bin/cli.ts +34 -0
- package/skills/skill-lorem-generator/bin/cli.ts +34 -0
- package/skills/skill-managehook/bin/cli.ts +241 -0
- package/skills/skill-managemcp/bin/cli.ts +241 -0
- package/skills/skill-manageskill/bin/cli.ts +241 -0
- package/skills/skill-markdown-validator/bin/cli.ts +34 -0
- package/skills/skill-mcp-builder/bin/cli.ts +34 -0
- package/skills/skill-meal-plan-designer/bin/cli.ts +34 -0
- package/skills/skill-meeting-insight-summarizer/bin/cli.ts +34 -0
- package/skills/skill-merge-pdfs/bin/cli.ts +34 -0
- package/skills/skill-microcopy-generator/bin/cli.ts +34 -0
- package/skills/skill-mindfulness-prompt-cache/bin/cli.ts +34 -0
- package/skills/skill-notion-manager/bin/cli.ts +34 -0
- package/skills/skill-onboarding-sequence-builder/bin/cli.ts +34 -0
- package/skills/skill-onsite-ops-checklist/bin/cli.ts +34 -0
- package/skills/skill-outreach-cadence-designer/bin/cli.ts +34 -0
- package/skills/skill-packaging-concept-studio/bin/cli.ts +34 -0
- package/skills/skill-packing-plan-pro/bin/cli.ts +34 -0
- package/skills/skill-parent-teacher-brief/bin/cli.ts +34 -0
- package/skills/skill-partner-kit-assembler/bin/cli.ts +34 -0
- package/skills/skill-payroll-change-prepper/bin/cli.ts +34 -0
- package/skills/skill-persona-based-adwriter/bin/cli.ts +34 -0
- package/skills/skill-persona-generator/bin/cli.ts +34 -0
- package/skills/skill-personal-daily-ops/bin/cli.ts +34 -0
- package/skills/skill-pet-care-scheduler/bin/cli.ts +34 -0
- package/skills/skill-podcast-show-notes/bin/cli.ts +34 -0
- package/skills/skill-presentation-theme-maker/bin/cli.ts +34 -0
- package/skills/skill-press-release-drafter/bin/cli.ts +34 -0
- package/skills/skill-print-collateral-designer/bin/cli.ts +34 -0
- package/skills/skill-procurement-scorecard/bin/cli.ts +34 -0
- package/skills/skill-product-demo-script/bin/cli.ts +34 -0
- package/skills/skill-product-mockup/bin/cli.ts +34 -0
- package/skills/skill-project-retro-companion/bin/cli.ts +34 -0
- package/skills/skill-proposal-redline-advisor/bin/cli.ts +34 -0
- package/skills/skill-regex-tester/bin/cli.ts +34 -0
- package/skills/skill-remove-background/bin/cli.ts +34 -0
- package/skills/skill-risk-disclosure-kit/bin/cli.ts +34 -0
- package/skills/skill-roi-comparison-tool/bin/cli.ts +34 -0
- package/skills/skill-sales-call-recapper/bin/cli.ts +34 -0
- package/skills/skill-salescopy/bin/cli.ts +20 -0
- package/skills/skill-scaffold-project/bin/cli.ts +34 -0
- package/skills/skill-scholarship-tracker/bin/cli.ts +34 -0
- package/skills/skill-scientific-figure-check/bin/cli.ts +34 -0
- package/skills/skill-seating-chart-maker/bin/cli.ts +34 -0
- package/skills/skill-security-audit/bin/cli.ts +34 -0
- package/skills/skill-seo-brief-builder/bin/cli.ts +34 -0
- package/skills/skill-slack-assistant/bin/cli.ts +34 -0
- package/skills/skill-sleep-routine-analyzer/bin/cli.ts +34 -0
- package/skills/skill-social-media-kit/bin/cli.ts +34 -0
- package/skills/skill-split-pdf/bin/cli.ts +34 -0
- package/skills/skill-sponsorship-proposal-lab/bin/cli.ts +34 -0
- package/skills/skill-spreadsheet-cleanroom/bin/cli.ts +34 -0
- package/skills/skill-statistical-test-selector/bin/cli.ts +34 -0
- package/skills/skill-stress-relief-playbook/bin/cli.ts +34 -0
- package/skills/skill-study-guide-builder/bin/cli.ts +34 -0
- package/skills/skill-subscription-spend-watcher/bin/cli.ts +34 -0
- package/skills/skill-subtitle/bin/cli.ts +20 -0
- package/skills/skill-survey-insight-extractor/bin/cli.ts +34 -0
- package/skills/skill-terraform-generator/bin/cli.ts +34 -0
- package/skills/skill-testimonial-graphics/bin/cli.ts +34 -0
- package/skills/skill-timesheet/bin/cli.ts +47 -0
- package/skills/skill-travel-budget-balancer/bin/cli.ts +34 -0
- package/skills/skill-validate-config/bin/cli.ts +34 -0
- package/skills/skill-video-cut-suggester/bin/cli.ts +34 -0
- package/skills/skill-video-downloader/bin/cli.ts +34 -0
- package/skills/skill-video-thumbnail/bin/cli.ts +34 -0
- package/skills/skill-voiceover-casting-assistant/bin/cli.ts +34 -0
- package/skills/skill-watermark/bin/cli.ts +34 -0
- package/skills/skill-webcrawling/bin/cli.ts +21 -0
- package/skills/skill-webinar-script-coach/bin/cli.ts +34 -0
- package/skills/skill-wellness-progress-reporter/bin/cli.ts +34 -0
- package/skills/skill-workout-cycle-planner/bin/cli.ts +34 -0
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* Or use the interactive CLI:
|
|
8
8
|
* skills
|
|
9
9
|
*/
|
|
10
|
-
export { SKILLS, CATEGORIES, getSkill, getSkillsByCategory, searchSkills, getSkillsByTag, getAllTags, type SkillMeta, type Category, } from "./lib/registry.js";
|
|
11
|
-
export { installSkill, installSkills, installSkillForAgent, removeSkillForAgent, getInstalledSkills, removeSkill, skillExists, getSkillPath, getAgentSkillsDir, getAgentSkillPath, AGENT_TARGETS, type InstallResult, type InstallOptions, type AgentTarget, type AgentScope, type AgentInstallOptions, } from "./lib/installer.js";
|
|
10
|
+
export { SKILLS, CATEGORIES, getSkill, getSkillsByCategory, searchSkills, getSkillsByTag, getAllTags, findSimilarSkills, type SkillMeta, type Category, } from "./lib/registry.js";
|
|
11
|
+
export { installSkill, installSkills, installSkillForAgent, removeSkillForAgent, getInstalledSkills, removeSkill, skillExists, getSkillPath, getAgentSkillsDir, getAgentSkillPath, AGENT_TARGETS, type InstallResult, type InstallOptions, type AgentTarget, type AgentScope, type AgentInstallOptions, getInstallMeta, disableSkill, enableSkill, getDisabledSkills, } from "./lib/installer.js";
|
|
12
12
|
export { getSkillDocs, getSkillBestDoc, getSkillRequirements, runSkill, generateEnvExample, generateSkillMd, type SkillDocs, type SkillRequirements, } from "./lib/skillinfo.js";
|
|
13
|
+
export { loadConfig, saveConfig, getConfigPath, type SkillsConfig, type ConfigScope, } from "./lib/config.js";
|
|
14
|
+
export type { SkillResponse, SkillDetailResponse, CategoryResponse, TagResponse, InstallResponse, RemoveResponse, VersionResponse, ExportResponse, ImportResponse, SearchResponse, CategoryInstallResponse, ErrorResponse, } from "./types/api.js";
|
package/dist/index.js
CHANGED
|
@@ -1534,8 +1534,23 @@ function getAllTags() {
|
|
|
1534
1534
|
}
|
|
1535
1535
|
return Array.from(tagSet).sort();
|
|
1536
1536
|
}
|
|
1537
|
+
function levenshtein(a, b) {
|
|
1538
|
+
const m = a.length, n = b.length;
|
|
1539
|
+
const dp = Array.from({ length: m + 1 }, (_, i) => Array.from({ length: n + 1 }, (_2, j) => i === 0 ? j : j === 0 ? i : 0));
|
|
1540
|
+
for (let i = 1;i <= m; i++) {
|
|
1541
|
+
for (let j = 1;j <= n; j++) {
|
|
1542
|
+
dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
return dp[m][n];
|
|
1546
|
+
}
|
|
1547
|
+
function findSimilarSkills(query, maxResults = 3) {
|
|
1548
|
+
const q = query.toLowerCase();
|
|
1549
|
+
const scored = SKILLS.map((s) => ({ name: s.name, dist: levenshtein(q, s.name.toLowerCase()) })).filter((s) => s.dist <= Math.max(3, Math.floor(q.length / 2))).sort((a, b) => a.dist - b.dist);
|
|
1550
|
+
return scored.slice(0, maxResults).map((s) => s.name);
|
|
1551
|
+
}
|
|
1537
1552
|
// src/lib/installer.ts
|
|
1538
|
-
import { existsSync, cpSync, mkdirSync, writeFileSync, rmSync, readdirSync, statSync, readFileSync } from "fs";
|
|
1553
|
+
import { existsSync, cpSync, mkdirSync, writeFileSync, rmSync, readdirSync, statSync, readFileSync, accessSync, constants } from "fs";
|
|
1539
1554
|
import { join, dirname } from "path";
|
|
1540
1555
|
import { homedir } from "os";
|
|
1541
1556
|
import { fileURLToPath } from "url";
|
|
@@ -1602,6 +1617,7 @@ function installSkill(name, options = {}) {
|
|
|
1602
1617
|
}
|
|
1603
1618
|
});
|
|
1604
1619
|
updateSkillsIndex(destDir);
|
|
1620
|
+
recordInstall(destDir, name);
|
|
1605
1621
|
const meta = getSkill(name);
|
|
1606
1622
|
if (meta?.dependencies && meta.dependencies.length > 0) {
|
|
1607
1623
|
const installed = getInstalledSkills(targetDir);
|
|
@@ -1630,7 +1646,9 @@ function installSkills(names, options = {}) {
|
|
|
1630
1646
|
}
|
|
1631
1647
|
function updateSkillsIndex(skillsDir) {
|
|
1632
1648
|
const indexPath = join(skillsDir, "index.ts");
|
|
1633
|
-
const
|
|
1649
|
+
const meta = loadMeta(skillsDir);
|
|
1650
|
+
const disabledSet = new Set(meta.disabled || []);
|
|
1651
|
+
const skills = readdirSync(skillsDir).filter((f) => f.startsWith("skill-") && !f.includes(".") && !disabledSet.has(f.replace("skill-", "")));
|
|
1634
1652
|
const exports = skills.map((s) => {
|
|
1635
1653
|
const name = s.replace("skill-", "").replace(/-/g, "_");
|
|
1636
1654
|
return `export * as ${name} from './${s}/src/index.js';`;
|
|
@@ -1645,6 +1663,74 @@ ${exports}
|
|
|
1645
1663
|
`;
|
|
1646
1664
|
writeFileSync(indexPath, content);
|
|
1647
1665
|
}
|
|
1666
|
+
function getMetaPath(skillsDir) {
|
|
1667
|
+
return join(skillsDir, ".meta.json");
|
|
1668
|
+
}
|
|
1669
|
+
function loadMeta(skillsDir) {
|
|
1670
|
+
const metaPath = getMetaPath(skillsDir);
|
|
1671
|
+
if (existsSync(metaPath)) {
|
|
1672
|
+
try {
|
|
1673
|
+
return JSON.parse(readFileSync(metaPath, "utf-8"));
|
|
1674
|
+
} catch {}
|
|
1675
|
+
}
|
|
1676
|
+
return { skills: {} };
|
|
1677
|
+
}
|
|
1678
|
+
function saveMeta(skillsDir, meta) {
|
|
1679
|
+
writeFileSync(getMetaPath(skillsDir), JSON.stringify(meta, null, 2));
|
|
1680
|
+
}
|
|
1681
|
+
function recordInstall(skillsDir, name) {
|
|
1682
|
+
const meta = loadMeta(skillsDir);
|
|
1683
|
+
const skillName = normalizeSkillName(name);
|
|
1684
|
+
let version = "unknown";
|
|
1685
|
+
try {
|
|
1686
|
+
const pkgPath = join(skillsDir, skillName, "package.json");
|
|
1687
|
+
if (existsSync(pkgPath)) {
|
|
1688
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
1689
|
+
version = pkg.version || "unknown";
|
|
1690
|
+
}
|
|
1691
|
+
} catch {}
|
|
1692
|
+
meta.skills[name] = { installedAt: new Date().toISOString(), version };
|
|
1693
|
+
saveMeta(skillsDir, meta);
|
|
1694
|
+
}
|
|
1695
|
+
function recordRemove(skillsDir, name) {
|
|
1696
|
+
const meta = loadMeta(skillsDir);
|
|
1697
|
+
delete meta.skills[name];
|
|
1698
|
+
saveMeta(skillsDir, meta);
|
|
1699
|
+
}
|
|
1700
|
+
function getInstallMeta(targetDir = process.cwd()) {
|
|
1701
|
+
return loadMeta(join(targetDir, ".skills"));
|
|
1702
|
+
}
|
|
1703
|
+
function disableSkill(name, targetDir = process.cwd()) {
|
|
1704
|
+
const skillsDir = join(targetDir, ".skills");
|
|
1705
|
+
const skillName = normalizeSkillName(name);
|
|
1706
|
+
if (!existsSync(join(skillsDir, skillName)))
|
|
1707
|
+
return false;
|
|
1708
|
+
const meta = loadMeta(skillsDir);
|
|
1709
|
+
const disabled = new Set(meta.disabled || []);
|
|
1710
|
+
if (disabled.has(name))
|
|
1711
|
+
return false;
|
|
1712
|
+
disabled.add(name);
|
|
1713
|
+
meta.disabled = [...disabled];
|
|
1714
|
+
saveMeta(skillsDir, meta);
|
|
1715
|
+
updateSkillsIndex(skillsDir);
|
|
1716
|
+
return true;
|
|
1717
|
+
}
|
|
1718
|
+
function enableSkill(name, targetDir = process.cwd()) {
|
|
1719
|
+
const skillsDir = join(targetDir, ".skills");
|
|
1720
|
+
const meta = loadMeta(skillsDir);
|
|
1721
|
+
const disabled = new Set(meta.disabled || []);
|
|
1722
|
+
if (!disabled.has(name))
|
|
1723
|
+
return false;
|
|
1724
|
+
disabled.delete(name);
|
|
1725
|
+
meta.disabled = [...disabled];
|
|
1726
|
+
saveMeta(skillsDir, meta);
|
|
1727
|
+
updateSkillsIndex(skillsDir);
|
|
1728
|
+
return true;
|
|
1729
|
+
}
|
|
1730
|
+
function getDisabledSkills(targetDir = process.cwd()) {
|
|
1731
|
+
const meta = loadMeta(join(targetDir, ".skills"));
|
|
1732
|
+
return meta.disabled || [];
|
|
1733
|
+
}
|
|
1648
1734
|
function getInstalledSkills(targetDir = process.cwd()) {
|
|
1649
1735
|
const skillsDir = join(targetDir, ".skills");
|
|
1650
1736
|
if (!existsSync(skillsDir)) {
|
|
@@ -1664,6 +1750,7 @@ function removeSkill(name, targetDir = process.cwd()) {
|
|
|
1664
1750
|
}
|
|
1665
1751
|
rmSync(skillPath, { recursive: true, force: true });
|
|
1666
1752
|
updateSkillsIndex(skillsDir);
|
|
1753
|
+
recordRemove(skillsDir, name);
|
|
1667
1754
|
return true;
|
|
1668
1755
|
}
|
|
1669
1756
|
var AGENT_TARGETS = ["claude", "codex", "gemini"];
|
|
@@ -1696,6 +1783,30 @@ function installSkillForAgent(name, options, generateSkillMd) {
|
|
|
1696
1783
|
return { skill: name, success: false, error: `No SKILL.md found and could not generate one for '${name}'` };
|
|
1697
1784
|
}
|
|
1698
1785
|
const destDir = getAgentSkillPath(name, agent, scope, projectDir);
|
|
1786
|
+
if (scope === "global") {
|
|
1787
|
+
const agentBaseDir = join(homedir(), `.${agent}`);
|
|
1788
|
+
if (!existsSync(agentBaseDir)) {
|
|
1789
|
+
const agentLabels = {
|
|
1790
|
+
claude: "Claude Code",
|
|
1791
|
+
codex: "Codex CLI",
|
|
1792
|
+
gemini: "Gemini CLI"
|
|
1793
|
+
};
|
|
1794
|
+
return {
|
|
1795
|
+
skill: name,
|
|
1796
|
+
success: false,
|
|
1797
|
+
error: `Agent directory ${agentBaseDir} does not exist. Is ${agentLabels[agent]} installed?`
|
|
1798
|
+
};
|
|
1799
|
+
}
|
|
1800
|
+
try {
|
|
1801
|
+
accessSync(agentBaseDir, constants.W_OK);
|
|
1802
|
+
} catch {
|
|
1803
|
+
return {
|
|
1804
|
+
skill: name,
|
|
1805
|
+
success: false,
|
|
1806
|
+
error: `Agent directory ${agentBaseDir} is not writable. Check permissions.`
|
|
1807
|
+
};
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1699
1810
|
try {
|
|
1700
1811
|
mkdirSync(destDir, { recursive: true });
|
|
1701
1812
|
writeFileSync(join(destDir, "SKILL.md"), skillMdContent);
|
|
@@ -1998,12 +2109,83 @@ function readIfExists(path) {
|
|
|
1998
2109
|
} catch {}
|
|
1999
2110
|
return null;
|
|
2000
2111
|
}
|
|
2112
|
+
// src/lib/config.ts
|
|
2113
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
2114
|
+
import { join as join3, dirname as dirname2 } from "path";
|
|
2115
|
+
import { homedir as homedir2 } from "os";
|
|
2116
|
+
var VALID_KEYS = {
|
|
2117
|
+
defaultAgent: ["claude", "codex", "gemini", "all"],
|
|
2118
|
+
defaultScope: ["global", "project"],
|
|
2119
|
+
format: ["compact", "json", "csv"]
|
|
2120
|
+
};
|
|
2121
|
+
function getConfigPath(scope) {
|
|
2122
|
+
if (scope === "global") {
|
|
2123
|
+
return join3(homedir2(), ".skillsrc");
|
|
2124
|
+
}
|
|
2125
|
+
return join3(process.cwd(), "skills.config.json");
|
|
2126
|
+
}
|
|
2127
|
+
function readConfigFile(path) {
|
|
2128
|
+
if (!existsSync3(path))
|
|
2129
|
+
return {};
|
|
2130
|
+
try {
|
|
2131
|
+
const raw = readFileSync3(path, "utf-8");
|
|
2132
|
+
const parsed = JSON.parse(raw);
|
|
2133
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
|
|
2134
|
+
return {};
|
|
2135
|
+
const config = {};
|
|
2136
|
+
for (const [key, allowed] of Object.entries(VALID_KEYS)) {
|
|
2137
|
+
const val = parsed[key];
|
|
2138
|
+
if (typeof val === "string" && allowed.includes(val)) {
|
|
2139
|
+
config[key] = val;
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
return config;
|
|
2143
|
+
} catch {
|
|
2144
|
+
return {};
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
function loadConfig() {
|
|
2148
|
+
const globalConfig = readConfigFile(getConfigPath("global"));
|
|
2149
|
+
const projectConfig = readConfigFile(getConfigPath("project"));
|
|
2150
|
+
return { ...globalConfig, ...projectConfig };
|
|
2151
|
+
}
|
|
2152
|
+
function saveConfig(key, value, scope = "project") {
|
|
2153
|
+
if (!(key in VALID_KEYS)) {
|
|
2154
|
+
throw new Error(`Unknown config key: ${key}. Valid keys: ${Object.keys(VALID_KEYS).join(", ")}`);
|
|
2155
|
+
}
|
|
2156
|
+
const allowed = VALID_KEYS[key];
|
|
2157
|
+
if (!allowed.includes(value)) {
|
|
2158
|
+
throw new Error(`Invalid value '${value}' for ${key}. Allowed: ${allowed.join(", ")}`);
|
|
2159
|
+
}
|
|
2160
|
+
const filePath = getConfigPath(scope);
|
|
2161
|
+
let existing = {};
|
|
2162
|
+
if (existsSync3(filePath)) {
|
|
2163
|
+
try {
|
|
2164
|
+
existing = JSON.parse(readFileSync3(filePath, "utf-8"));
|
|
2165
|
+
if (typeof existing !== "object" || existing === null || Array.isArray(existing)) {
|
|
2166
|
+
existing = {};
|
|
2167
|
+
}
|
|
2168
|
+
} catch {
|
|
2169
|
+
existing = {};
|
|
2170
|
+
}
|
|
2171
|
+
} else {
|
|
2172
|
+
const dir = dirname2(filePath);
|
|
2173
|
+
if (!existsSync3(dir)) {
|
|
2174
|
+
mkdirSync2(dir, { recursive: true });
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
existing[key] = value;
|
|
2178
|
+
writeFileSync2(filePath, JSON.stringify(existing, null, 2) + `
|
|
2179
|
+
`);
|
|
2180
|
+
}
|
|
2001
2181
|
export {
|
|
2002
2182
|
skillExists,
|
|
2003
2183
|
searchSkills,
|
|
2184
|
+
saveConfig,
|
|
2004
2185
|
runSkill,
|
|
2005
2186
|
removeSkillForAgent,
|
|
2006
2187
|
removeSkill,
|
|
2188
|
+
loadConfig,
|
|
2007
2189
|
installSkills,
|
|
2008
2190
|
installSkillForAgent,
|
|
2009
2191
|
installSkill,
|
|
@@ -2015,11 +2197,17 @@ export {
|
|
|
2015
2197
|
getSkillBestDoc,
|
|
2016
2198
|
getSkill,
|
|
2017
2199
|
getInstalledSkills,
|
|
2200
|
+
getInstallMeta,
|
|
2201
|
+
getDisabledSkills,
|
|
2202
|
+
getConfigPath,
|
|
2018
2203
|
getAllTags,
|
|
2019
2204
|
getAgentSkillsDir,
|
|
2020
2205
|
getAgentSkillPath,
|
|
2021
2206
|
generateSkillMd,
|
|
2022
2207
|
generateEnvExample,
|
|
2208
|
+
findSimilarSkills,
|
|
2209
|
+
enableSkill,
|
|
2210
|
+
disableSkill,
|
|
2023
2211
|
SKILLS,
|
|
2024
2212
|
CATEGORIES,
|
|
2025
2213
|
AGENT_TARGETS
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config file support for Open Skills
|
|
3
|
+
*
|
|
4
|
+
* Loads configuration from:
|
|
5
|
+
* 1. Project-local: ./skills.config.json (highest priority)
|
|
6
|
+
* 2. Global: ~/.skillsrc (JSON format, lowest priority)
|
|
7
|
+
*
|
|
8
|
+
* Values from the project config override global config.
|
|
9
|
+
*/
|
|
10
|
+
export interface SkillsConfig {
|
|
11
|
+
defaultAgent?: "claude" | "codex" | "gemini" | "all";
|
|
12
|
+
defaultScope?: "global" | "project";
|
|
13
|
+
format?: "compact" | "json" | "csv";
|
|
14
|
+
}
|
|
15
|
+
export type ConfigScope = "global" | "project";
|
|
16
|
+
/**
|
|
17
|
+
* Get the config file path for a given scope
|
|
18
|
+
*/
|
|
19
|
+
export declare function getConfigPath(scope: ConfigScope): string;
|
|
20
|
+
/**
|
|
21
|
+
* Load merged config: project-local overrides global
|
|
22
|
+
*/
|
|
23
|
+
export declare function loadConfig(): SkillsConfig;
|
|
24
|
+
/**
|
|
25
|
+
* Save a single config key-value pair to the specified scope
|
|
26
|
+
*/
|
|
27
|
+
export declare function saveConfig(key: string, value: string, scope?: ConfigScope): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/lib/installer.d.ts
CHANGED
|
@@ -27,6 +27,30 @@ export declare function installSkill(name: string, options?: InstallOptions): In
|
|
|
27
27
|
* Install multiple skills
|
|
28
28
|
*/
|
|
29
29
|
export declare function installSkills(names: string[], options?: InstallOptions): InstallResult[];
|
|
30
|
+
interface SkillMeta {
|
|
31
|
+
installedAt: string;
|
|
32
|
+
version: string;
|
|
33
|
+
}
|
|
34
|
+
interface MetaFile {
|
|
35
|
+
skills: Record<string, SkillMeta>;
|
|
36
|
+
disabled?: string[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get installation metadata for installed skills
|
|
40
|
+
*/
|
|
41
|
+
export declare function getInstallMeta(targetDir?: string): MetaFile;
|
|
42
|
+
/**
|
|
43
|
+
* Disable a skill (exclude from .skills/index.ts without removing files)
|
|
44
|
+
*/
|
|
45
|
+
export declare function disableSkill(name: string, targetDir?: string): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Enable a previously disabled skill (re-add to .skills/index.ts)
|
|
48
|
+
*/
|
|
49
|
+
export declare function enableSkill(name: string, targetDir?: string): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Get list of disabled skills
|
|
52
|
+
*/
|
|
53
|
+
export declare function getDisabledSkills(targetDir?: string): string[];
|
|
30
54
|
/**
|
|
31
55
|
* Get list of installed skills in a directory
|
|
32
56
|
*/
|
|
@@ -65,3 +89,4 @@ export declare function installSkillForAgent(name: string, options: AgentInstall
|
|
|
65
89
|
* Remove a skill from an agent's skill directory
|
|
66
90
|
*/
|
|
67
91
|
export declare function removeSkillForAgent(name: string, options: AgentInstallOptions): boolean;
|
|
92
|
+
export {};
|
package/dist/lib/registry.d.ts
CHANGED
|
@@ -23,3 +23,7 @@ export declare function getSkillsByTag(tag: string): SkillMeta[];
|
|
|
23
23
|
* Return all unique tags across every skill, sorted alphabetically.
|
|
24
24
|
*/
|
|
25
25
|
export declare function getAllTags(): string[];
|
|
26
|
+
/**
|
|
27
|
+
* Find skills with names similar to the given query (for "did you mean?" suggestions)
|
|
28
|
+
*/
|
|
29
|
+
export declare function findSimilarSkills(query: string, maxResults?: number): string[];
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared API response types used by both the HTTP server and the dashboard.
|
|
3
|
+
* Import from "@hasna/skills" to get type-safe API responses.
|
|
4
|
+
*/
|
|
5
|
+
export interface SkillResponse {
|
|
6
|
+
name: string;
|
|
7
|
+
displayName: string;
|
|
8
|
+
description: string;
|
|
9
|
+
category: string;
|
|
10
|
+
tags: string[];
|
|
11
|
+
installed: boolean;
|
|
12
|
+
envVars: string[];
|
|
13
|
+
envVarsSet: string[];
|
|
14
|
+
systemDeps: string[];
|
|
15
|
+
cliCommand: string | null;
|
|
16
|
+
}
|
|
17
|
+
export interface SkillDetailResponse extends SkillResponse {
|
|
18
|
+
docs: string | null;
|
|
19
|
+
}
|
|
20
|
+
export interface CategoryResponse {
|
|
21
|
+
name: string;
|
|
22
|
+
count: number;
|
|
23
|
+
}
|
|
24
|
+
export interface TagResponse {
|
|
25
|
+
name: string;
|
|
26
|
+
count: number;
|
|
27
|
+
}
|
|
28
|
+
export interface InstallResponse {
|
|
29
|
+
skill: string;
|
|
30
|
+
success: boolean;
|
|
31
|
+
error?: string;
|
|
32
|
+
results?: Array<{
|
|
33
|
+
skill: string;
|
|
34
|
+
success: boolean;
|
|
35
|
+
error?: string;
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
38
|
+
export interface RemoveResponse {
|
|
39
|
+
skill: string;
|
|
40
|
+
success: boolean;
|
|
41
|
+
}
|
|
42
|
+
export interface VersionResponse {
|
|
43
|
+
version: string;
|
|
44
|
+
name: string;
|
|
45
|
+
}
|
|
46
|
+
export interface ExportResponse {
|
|
47
|
+
version: number;
|
|
48
|
+
skills: string[];
|
|
49
|
+
timestamp: string;
|
|
50
|
+
}
|
|
51
|
+
export interface ImportResponse {
|
|
52
|
+
imported: number;
|
|
53
|
+
total: number;
|
|
54
|
+
results: Array<{
|
|
55
|
+
skill: string;
|
|
56
|
+
success: boolean;
|
|
57
|
+
error?: string;
|
|
58
|
+
}>;
|
|
59
|
+
}
|
|
60
|
+
export interface SearchResponse extends SkillResponse {
|
|
61
|
+
}
|
|
62
|
+
export interface CategoryInstallResponse {
|
|
63
|
+
category: string;
|
|
64
|
+
count: number;
|
|
65
|
+
success: boolean;
|
|
66
|
+
results: Array<{
|
|
67
|
+
skill: string;
|
|
68
|
+
success: boolean;
|
|
69
|
+
error?: string;
|
|
70
|
+
}>;
|
|
71
|
+
}
|
|
72
|
+
export interface ErrorResponse {
|
|
73
|
+
error: string;
|
|
74
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/skills",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"description": "Skills library for AI coding agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -23,9 +23,12 @@
|
|
|
23
23
|
"main": "./dist/index.js",
|
|
24
24
|
"types": "./dist/index.d.ts",
|
|
25
25
|
"scripts": {
|
|
26
|
-
"
|
|
26
|
+
"clean": "rm -rf bin/ dist/",
|
|
27
|
+
"build": "bun run clean && bun build ./src/cli/index.tsx --outdir ./bin --target bun --external ink --external react --external chalk && bun build ./src/mcp/index.ts --outfile ./bin/mcp.js --target bun && bun build ./src/index.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist",
|
|
27
28
|
"test": "bun test",
|
|
28
29
|
"dev": "bun run ./src/cli/index.tsx",
|
|
30
|
+
"dev:watch": "bun --watch run ./src/cli/index.tsx",
|
|
31
|
+
"dev:mcp": "bun --watch run ./src/mcp/index.ts",
|
|
29
32
|
"typecheck": "tsc --noEmit",
|
|
30
33
|
"prepublishOnly": "bun run build",
|
|
31
34
|
"dashboard:dev": "cd dashboard && bun run dev",
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { homedir } from "os";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
|
|
7
|
+
function getDataDir(): string {
|
|
8
|
+
return process.env.DATA_DIR || join(homedir(), ".skill", "skill-academic-journal-matcher");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const program = new Command();
|
|
12
|
+
|
|
13
|
+
program
|
|
14
|
+
.name("skill-academic-journal-matcher")
|
|
15
|
+
.description("Academic Journal Matcher skill")
|
|
16
|
+
.version("0.1.0");
|
|
17
|
+
|
|
18
|
+
program
|
|
19
|
+
.command("run")
|
|
20
|
+
.description("Run the skill")
|
|
21
|
+
.option("-o, --output <path>", "Output directory", join(getDataDir(), "output"))
|
|
22
|
+
.allowUnknownOption(true)
|
|
23
|
+
.action(async (options, command) => {
|
|
24
|
+
try {
|
|
25
|
+
const args = command.args;
|
|
26
|
+
process.env.DATA_DIR = process.env.DATA_DIR || getDataDir();
|
|
27
|
+
await import("../src/index.js");
|
|
28
|
+
} catch (err) {
|
|
29
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
program.parse();
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { homedir } from "os";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
|
|
7
|
+
function getDataDir(): string {
|
|
8
|
+
return process.env.DATA_DIR || join(homedir(), ".skill", "skill-action-item-router");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const program = new Command();
|
|
12
|
+
|
|
13
|
+
program
|
|
14
|
+
.name("skill-action-item-router")
|
|
15
|
+
.description("Action Item Router skill")
|
|
16
|
+
.version("0.1.0");
|
|
17
|
+
|
|
18
|
+
program
|
|
19
|
+
.command("run")
|
|
20
|
+
.description("Run the skill")
|
|
21
|
+
.option("-o, --output <path>", "Output directory", join(getDataDir(), "output"))
|
|
22
|
+
.allowUnknownOption(true)
|
|
23
|
+
.action(async (options, command) => {
|
|
24
|
+
try {
|
|
25
|
+
const args = command.args;
|
|
26
|
+
process.env.DATA_DIR = process.env.DATA_DIR || getDataDir();
|
|
27
|
+
await import("../src/index.js");
|
|
28
|
+
} catch (err) {
|
|
29
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
program.parse();
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { homedir } from "os";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
|
|
7
|
+
function getDataDir(): string {
|
|
8
|
+
return process.env.DATA_DIR || join(homedir(), ".skill", "skill-ad-creative-generator");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const program = new Command();
|
|
12
|
+
|
|
13
|
+
program
|
|
14
|
+
.name("skill-ad-creative-generator")
|
|
15
|
+
.description("Ad Creative Generator skill")
|
|
16
|
+
.version("0.1.0");
|
|
17
|
+
|
|
18
|
+
program
|
|
19
|
+
.command("run")
|
|
20
|
+
.description("Run the skill")
|
|
21
|
+
.option("-o, --output <path>", "Output directory", join(getDataDir(), "output"))
|
|
22
|
+
.allowUnknownOption(true)
|
|
23
|
+
.action(async (options, command) => {
|
|
24
|
+
try {
|
|
25
|
+
const args = command.args;
|
|
26
|
+
process.env.DATA_DIR = process.env.DATA_DIR || getDataDir();
|
|
27
|
+
await import("../src/index.js");
|
|
28
|
+
} catch (err) {
|
|
29
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
program.parse();
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { homedir } from "os";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
|
|
7
|
+
function getDataDir(): string {
|
|
8
|
+
return process.env.DATA_DIR || join(homedir(), ".skill", "skill-advanced-math");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const program = new Command();
|
|
12
|
+
|
|
13
|
+
program
|
|
14
|
+
.name("skill-advanced-math")
|
|
15
|
+
.description("Advanced Math skill")
|
|
16
|
+
.version("0.1.0");
|
|
17
|
+
|
|
18
|
+
program
|
|
19
|
+
.command("run")
|
|
20
|
+
.description("Run the skill")
|
|
21
|
+
.option("-o, --output <path>", "Output directory", join(getDataDir(), "output"))
|
|
22
|
+
.allowUnknownOption(true)
|
|
23
|
+
.action(async (options, command) => {
|
|
24
|
+
try {
|
|
25
|
+
const args = command.args;
|
|
26
|
+
process.env.DATA_DIR = process.env.DATA_DIR || getDataDir();
|
|
27
|
+
await import("../src/index.js");
|
|
28
|
+
} catch (err) {
|
|
29
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
program.parse();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
|
|
4
|
+
const program = new Command();
|
|
5
|
+
|
|
6
|
+
program
|
|
7
|
+
.name("skill-analyze-data")
|
|
8
|
+
.description("Data science insights for CSV and JSON")
|
|
9
|
+
.version("0.1.0");
|
|
10
|
+
|
|
11
|
+
program
|
|
12
|
+
.command("run", { isDefault: true })
|
|
13
|
+
.description("Run the skill")
|
|
14
|
+
.allowUnknownOption(true)
|
|
15
|
+
.action(async () => {
|
|
16
|
+
await import("../src/index.js");
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
program.parse();
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { homedir } from "os";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
|
|
7
|
+
function getDataDir(): string {
|
|
8
|
+
return process.env.DATA_DIR || join(homedir(), ".skill", "skill-anomaly-investigator");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const program = new Command();
|
|
12
|
+
|
|
13
|
+
program
|
|
14
|
+
.name("skill-anomaly-investigator")
|
|
15
|
+
.description("Anomaly Investigator skill")
|
|
16
|
+
.version("0.1.0");
|
|
17
|
+
|
|
18
|
+
program
|
|
19
|
+
.command("run")
|
|
20
|
+
.description("Run the skill")
|
|
21
|
+
.option("-o, --output <path>", "Output directory", join(getDataDir(), "output"))
|
|
22
|
+
.allowUnknownOption(true)
|
|
23
|
+
.action(async (options, command) => {
|
|
24
|
+
try {
|
|
25
|
+
const args = command.args;
|
|
26
|
+
process.env.DATA_DIR = process.env.DATA_DIR || getDataDir();
|
|
27
|
+
await import("../src/index.js");
|
|
28
|
+
} catch (err) {
|
|
29
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
program.parse();
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { homedir } from "os";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
|
|
7
|
+
function getDataDir(): string {
|
|
8
|
+
return process.env.DATA_DIR || join(homedir(), ".skill", "skill-api-test-suite");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const program = new Command();
|
|
12
|
+
|
|
13
|
+
program
|
|
14
|
+
.name("skill-api-test-suite")
|
|
15
|
+
.description("Api Test Suite skill")
|
|
16
|
+
.version("0.1.0");
|
|
17
|
+
|
|
18
|
+
program
|
|
19
|
+
.command("run")
|
|
20
|
+
.description("Run the skill")
|
|
21
|
+
.option("-o, --output <path>", "Output directory", join(getDataDir(), "output"))
|
|
22
|
+
.allowUnknownOption(true)
|
|
23
|
+
.action(async (options, command) => {
|
|
24
|
+
try {
|
|
25
|
+
const args = command.args;
|
|
26
|
+
process.env.DATA_DIR = process.env.DATA_DIR || getDataDir();
|
|
27
|
+
await import("../src/index.js");
|
|
28
|
+
} catch (err) {
|
|
29
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
program.parse();
|