@skillbolt/core
v1.0.1
Published
Shared core module for Skillbolt - types, parser, config, logger
Downloads
9
Readme
@skillbolt/core
Skill Kit 的核心库,提供所有其他模块共享的基础功能,包括配置加载、日志记录、错误处理、技能解析等。
功能特性
- 配置管理: 支持全局和项目级配置
- 日志系统: 统一的日志记录和进度显示
- 错误处理: 标准化的错误类型和处理
- 技能解析: 解析技能文件(frontmatter、sections)
- 路径工具: 路径处理和规范化
- 字符串工具: 字符串处理和格式化
- 类型定义: 共享的 TypeScript 类型
配置管理
加载配置
import { loadConfig, loadGlobalConfig, loadProjectConfig } from '@skillbolt/core';
// 加载完整配置(全局 + 项目)
const config = await loadConfig();
// 仅加载全局配置
const globalConfig = await loadGlobalConfig();
// 仅加载项目配置
const projectConfig = await loadProjectConfig();
// 获取配置文件路径
const configPath = getConfigPath(); // ~/.skillbolt/config.json配置结构
interface SkillboltConfig {
// 默认配置
defaults?: DefaultsConfig;
// Lint 配置
lint?: LintConfig;
// Registry 配置
registry?: RegistryConfig;
// Sync 配置
sync?: SyncConfig;
// Analytics 配置
analytics?: AnalyticsConfig;
// Test 配置
test?: TestConfig;
}
interface DefaultsConfig {
platform?: 'claude' | 'cursor' | 'continue';
outputDir?: string;
template?: string;
}配置文件位置
# 全局配置
~/.skillbolt/config.json
# 项目配置(按优先级)
./skill.config.json
./.skillboltrc.json
./skill.config.js日志系统
基本使用
import { logger, createLogger } from '@skillbolt/core';
// 使用默认 logger
logger.debug('Debug message');
logger.info('Info message');
logger.warn('Warning message');
logger.error('Error message');
logger.success('Success message');
// 创建自定义 logger
const customLogger = createLogger({
level: 'debug',
prefix: '[MyApp]',
color: true
});日志级别
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'success';
logger.setLevel('debug'); // 设置最低日志级别
logger.getLevel(); // 获取当前级别进度条
import { createSpinner } from '@skillbolt/core';
const spinner = createSpinner('Processing...');
spinner.start();
// 更新文本
spinner.text = 'Still processing...';
// 停止
spinner.stop('Done!');
spinner.succeed('Success!');
spinner.fail('Failed!');
spinner.warn('Warning!');
spinner.info('Info!');错误处理
错误类型
import {
SkillboltError,
ParseError,
ConfigError,
ValidationError,
FileError
} from '@skillbolt/core';
// 抛出错误
throw new ParseError('Failed to parse skill file', {
file: 'skill.md',
line: 10,
column: 5
});
throw new ConfigError('Invalid configuration', {
key: 'lint.rules',
expected: 'array',
received: 'string'
});
throw new ValidationError('Skill validation failed', {
skill: 'my-skill',
errors: ['Missing required field: name']
});
throw new FileError('File not found', {
path: '/path/to/file.md'
});错误代码
enum ErrorCode {
// 通用错误
UNKNOWN_ERROR = 'UNKNOWN_ERROR',
// 解析错误
PARSE_ERROR = 'PARSE_ERROR',
INVALID_FRONTMATTER = 'INVALID_FRONTMATTER',
MISSING_REQUIRED_SECTION = 'MISSING_REQUIRED_SECTION',
// 配置错误
CONFIG_ERROR = 'CONFIG_ERROR',
CONFIG_NOT_FOUND = 'CONFIG_NOT_FOUND',
INVALID_CONFIG = 'INVALID_CONFIG',
// 验证错误
VALIDATION_ERROR = 'VALIDATION_ERROR',
SKILL_NOT_FOUND = 'SKILL_NOT_FOUND',
// 文件错误
FILE_NOT_FOUND = 'FILE_NOT_FOUND',
FILE_READ_ERROR = 'FILE_READ_ERROR',
FILE_WRITE_ERROR = 'FILE_WRITE_ERROR',
}技能解析
解析技能文件
import {
parseSkillFile,
parseSkillString,
parseManifest,
parseSections
} from '@skillbolt/core';
// 从文件解析
const skill = await parseSkillFile('./skill.md');
console.log(skill.manifest);
console.log(skill.sections);
// 从字符串解析
const content = fs.readFileSync('./skill.md', 'utf-8');
const skill = parseSkillString(content);
// 仅解析 frontmatter
const manifest = parseManifest(content);
// 仅解析 sections
const sections = parseSections(content);获取特定章节
import {
getSectionByType,
getSectionsByType,
findSection
} from '@skillbolt/core';
// 获取第一个 @Claude 章节
const claudeSection = getSectionByType(skill, '@Claude');
// 获取所有 @User 章节
const userSections = getSectionsByType(skill, '@User');
// 查找包含特定文本的章节
const section = findSection(skill, 'example');验证技能
import {
validateManifest,
hasRequiredSections
} from '@skillbolt/core';
// 验证 manifest
const valid = validateManifest(manifest);
if (!valid.valid) {
console.error('Errors:', valid.errors);
}
// 检查必需章节
const hasAll = hasRequiredSections(skill);Frontmatter 解析
import { parseFrontmatter } from '@skillbolt/core';
const result = parseFrontmatter(content);
console.log(result.data); // frontmatter 数据
console.log(result.content); // 剩余内容
console.log result.line); // frontmatter 结束行号路径工具
import {
normalizePath,
expandTilde,
resolveSkillPath,
isDirectory,
isFile,
exists,
getSkillDir,
getSkillName,
joinPath
} from '@skillbolt/core';
// 规范化路径
const normalized = normalizePath('path/to/..//file'); // 'path/file'
// 展开波浪号
const expanded = expandTilde('~/documents'); // '/home/user/documents'
// 解析技能路径
const skillPath = resolveSkillPath('my-skill');
// 检查路径类型
const isDir = await isDirectory('/path/to/dir');
const isFile = await isFile('/path/to/file');
const fileExists = await exists('/path/to/file');
// 获取技能目录和名称
const dir = getSkillDir('/path/to/skills/my-skill/skill.md'); // '/path/to/skills/my-skill'
const name = getSkillName('/path/to/skills/my-skill/skill.md'); // 'my-skill'
// 连接路径
const path = joinPath('dir', 'subdir', 'file.txt');字符串工具
import {
slugify,
truncate,
capitalize,
camelCase,
kebabCase,
pascalCase,
countWords,
extractLines,
indentText,
dedent,
escapeRegex
} from '@skillbolt/core';
// 转换为 slug
const slug = slugify('Hello World!'); // 'hello-world'
// 截断文本
const truncated = truncate('Long text here', 10); // 'Long text ...'
// 首字母大写
const capitalized = capitalize('hello'); // 'Hello'
// 驼峰命名
const camel = camelCase('hello-world'); // 'helloWorld'
// 短横线命名
const kebab = kebabCase('helloWorld'); // 'hello-world'
// 帕斯卡命名
const pascal = pascalCase('hello-world'); // 'HelloWorld'
// 计算单词数
const words = countWords('Hello world'); // 2
// 提取行
const lines = extractLines('line1\nline2\nline3', 1, 2); // ['line2']
// 缩进文本
const indented = indentText('text', 2); // ' text'
// 移除缩进
const dedented = dedent(' text'); // 'text'
// 转义正则表达式
const escaped = escapeRegex('a.b'); // 'a\\.b'类型定义
技能相关
interface SkillManifest {
name: string;
version?: string;
description?: string;
triggers?: string[];
[key: string]: unknown;
}
interface SkillSection {
type: string;
content: string;
line: number;
}
interface ParsedSkillResult {
manifest: SkillManifest;
sections: SkillSection[];
rawContent: string;
filePath: string;
}配置相关
interface ResolvedConfig {
global: GlobalConfig;
project: ProjectConfig;
}
interface GlobalConfig {
defaults: DefaultsConfig;
registry: RegistryConfig;
sync: SyncConfig;
}
interface ProjectConfig {
lint?: LintConfig;
analytics?: AnalyticsConfig;
test?: TestConfig;
}错误相关
interface ErrorDetails {
[key: string]: unknown;
}
class SkillboltError extends Error {
code: ErrorCode;
details: ErrorDetails;
}使用示例
完整的技能解析流程
import {
parseSkillFile,
validateManifest,
hasRequiredSections,
getSectionByType
} from '@skillbolt/core';
import { logger } from '@skillbolt/core';
async function analyzeSkill(skillPath: string) {
try {
// 解析技能文件
const skill = await parseSkillFile(skillPath);
logger.info(`Loaded skill: ${skill.manifest.name}`);
// 验证 manifest
const manifestValid = validateManifest(skill.manifest);
if (!manifestValid.valid) {
logger.error('Invalid manifest:', manifestValid.errors);
return;
}
// 检查必需章节
const hasAllSections = hasRequiredSections(skill);
if (!hasAllSections) {
logger.warn('Missing required sections');
}
// 获取 @Claude 章节
const claudeSection = getSectionByType(skill, '@Claude');
if (claudeSection) {
logger.debug('Claude section length:', claudeSection.content.length);
}
return skill;
} catch (error) {
if (error instanceof SkillboltError) {
logger.error(`[${error.code}] ${error.message}`);
if (error.details) {
logger.error('Details:', error.details);
}
}
throw error;
}
}配置驱动的应用
import { loadConfig, logger } from '@skillbolt/core';
async function runApp() {
// 加载配置
const config = await loadConfig();
// 根据配置设置日志级别
logger.setLevel(config.global.defaults.logLevel || 'info');
// 使用配置
const platform = config.global.defaults.platform || 'claude';
const outputDir = config.global.defaults.outputDir || './output';
logger.info(`Running on platform: ${platform}`);
logger.info(`Output directory: ${outputDir}`);
// ... 应用逻辑
}最佳实践
- 错误处理: 始终使用特定的错误类型而不是通用的 Error
- 日志级别: 在生产环境中使用适当的日志级别
- 路径处理: 使用提供的路径工具而不是手写字符串操作
- 配置验证: 加载配置后验证配置的有效性
- 类型安全: 充分利用 TypeScript 类型定义
API 参考
主要导出
// 配置
export {
loadConfig,
loadGlobalConfig,
loadProjectConfig,
getConfigPath
};
// 日志
export {
Logger,
logger,
createLogger,
createSpinner
};
// 错误
export {
SkillboltError,
ParseError,
ConfigError,
ValidationError,
FileError
};
// 解析
export {
parseFrontmatter,
parseManifest,
validateManifest,
parseSections,
getLineNumber,
getSectionByType,
getSectionsByType,
parseSkillFile,
parseSkillString,
findSection,
hasRequiredSections
};
// 路径
export {
normalizePath,
expandTilde,
resolveSkillPath,
isDirectory,
isFile,
exists,
getSkillDir,
getSkillName,
joinPath
};
// 字符串
export {
slugify,
truncate,
capitalize,
camelCase,
kebabCase,
pascalCase,
countWords,
extractLines,
indentText,
dedent,
escapeRegex
};许可证
MIT
