autosnippet
Version:
Extract code patterns into a knowledge base for AI coding assistants
296 lines (295 loc) • 9.35 kB
TypeScript
/**
* CursorDeliveryPipeline — 6 通道交付主入口
*
* 读取知识库 → 筛选 + 分类 + 排序 + 压缩 → 写入 6 个通道
*
* Channel A: .cursor/rules/autosnippet-project-rules.mdc (alwaysApply rules)
* Channel B: .cursor/rules/autosnippet-patterns-{topic}.mdc (smart rules)
* Channel C: .cursor/skills/ (project skills sync)
* Channel D: .cursor/skills/autosnippet-devdocs/ (dev documents)
* Channel F: AGENTS.md + CLAUDE.md + .github/copilot-instructions.md (agent instructions)
* + Mirror: .qoder/ .trae/ (IDE mirror)
*
* 触发时机:
* 1. bootstrap 完成后自动触发
* 2. `asd cursor-rules` CLI 命令手动触发
* 3. Recipe 状态变更(pending → active)后触发
* 4. `asd upgrade` 时作为升级步骤执行
*/
import type { KnowledgeEntryProps } from '../../domain/knowledge/KnowledgeEntry.js';
import { AgentInstructionsGenerator } from './AgentInstructionsGenerator.js';
import { KnowledgeCompressor } from './KnowledgeCompressor.js';
import { RulesGenerator } from './RulesGenerator.js';
import { SkillsSyncer } from './SkillsSyncer.js';
import { TopicClassifier } from './TopicClassifier.js';
export declare class CursorDeliveryPipeline {
agentInstructions: AgentInstructionsGenerator;
compressor: KnowledgeCompressor;
database: Record<string, unknown> | null;
knowledgeService: {
list: (filter: Record<string, unknown>, pagination: {
page: number;
pageSize: number;
}) => Promise<unknown>;
};
logger: {
info?: (...args: unknown[]) => void;
warn?: (...args: unknown[]) => void;
error?: (...args: unknown[]) => void;
};
projectName: string;
projectRoot: string;
rulesGenerator: RulesGenerator;
skillsSyncer: SkillsSyncer;
topicClassifier: TopicClassifier;
/**
* @param options.knowledgeService KnowledgeService 实例
* @param options.projectRoot 用户项目根目录
* @param [options.projectName] 项目名称
* @param [options.logger] 日志器
*/
constructor({ knowledgeService, projectRoot, projectName, logger, database, }: {
knowledgeService: {
list: (filter: Record<string, unknown>, pagination: {
page: number;
pageSize: number;
}) => Promise<unknown>;
};
projectRoot: string;
projectName?: string;
logger?: {
info?: (...args: unknown[]) => void;
warn?: (...args: unknown[]) => void;
error?: (...args: unknown[]) => void;
};
database?: Record<string, unknown> | null;
});
/**
* 完整交付流程 — 生成 6 通道消费物料
* @returns >}
*/
deliver(): Promise<{
channelA: {
filePath: string;
tokensUsed: number;
rulesCount: number;
} | {
rulesCount: number;
tokensUsed: number;
filePath: null;
};
channelB: {
topicCount: number;
patternsCount: number;
factsCount: number;
totalTokens: number;
topics: Record<string, {
patternsCount: number;
factsCount: number;
tokensUsed: number;
}>;
};
channelC: {
synced: number;
builtinSynced: number;
projectSynced: number;
skipped: number;
errors: number;
details: {
synced: string[];
skipped: string[];
errors: string[];
builtinSynced: string[];
};
};
channelD: {
documentsCount: number;
filesWritten: number;
filePaths: string[];
};
channelF: {
filesWritten: number;
totalTokens: number;
files: {
agents: string;
claude: string;
copilot: string;
};
} | {
filesWritten: number;
totalTokens: number;
files: {
agents?: undefined;
claude?: undefined;
copilot?: undefined;
};
};
stats: {
channelA: {
rulesCount: number;
tokensUsed: number;
};
channelB: {
topicCount: number;
patternsCount: number;
totalTokens: number;
topics: Record<string, {
patternsCount: number;
factsCount: number;
tokensUsed: number;
}>;
};
channelC: {
synced: number;
skipped: number;
errors: number;
};
channelD: {
documentsCount: number;
filesWritten: number;
};
channelF: {
filesWritten: number;
totalTokens: number;
};
totalTokensUsed: number;
duration: number;
};
}>;
/**
* 加载知识条目(active + staging + high-confidence pending)
*
* M2 六态状态机: staging/active/evolving 均为 CONSUMABLE 状态
*/
_loadEntries(): Promise<KnowledgeEntryProps[]>;
/**
* 从 KnowledgeService.list() 返回值提取条目数组
*/
_extractItems(result: unknown): KnowledgeEntryProps[];
/**
* 按 kind 分类知识条目
* dev-document 类型单独分流,不进入 Channel A/B 压缩
*/
_classify(entries: KnowledgeEntryProps[]): {
rules: KnowledgeEntryProps[];
patterns: KnowledgeEntryProps[];
facts: KnowledgeEntryProps[];
documents: KnowledgeEntryProps[];
};
/**
* 排序 — 质量分 + 统计使用量
*/
_rank(entries: KnowledgeEntryProps[]): KnowledgeEntryProps[];
/**
* 计算排名分
*/
_rankScore(entry: KnowledgeEntryProps): number;
/**
* Channel A 生成
*/
_generateChannelA(rules: KnowledgeEntryProps[]): {
filePath: string;
tokensUsed: number;
rulesCount: number;
} | {
rulesCount: number;
tokensUsed: number;
filePath: null;
};
/**
* Channel B 生成(patterns + facts)
* @param patterns kind='pattern' 的知识条目
* @param [facts=[]] kind='fact' 的知识条目
*/
_generateChannelB(patterns: KnowledgeEntryProps[], facts?: KnowledgeEntryProps[]): {
topicCount: number;
patternsCount: number;
factsCount: number;
totalTokens: number;
topics: Record<string, {
patternsCount: number;
factsCount: number;
tokensUsed: number;
}>;
};
/**
* Channel B+ — Call Graph Architecture Rules (Phase 5.2)
* 从调用图拓扑分析架构分层,生成 architecture smart rule
* @returns |null}
*/
_generateCallGraphArchitectureRules(): {
insightsCount: number;
tokensUsed: number;
filePath: string;
} | null;
/**
* 从文件路径中提取层级目录 (第一或第二级有意义的目录)
*/
_extractLayerDir(filePath: string): string | null;
/**
* Channel C 生成
*/
_generateChannelC(): Promise<{
synced: number;
builtinSynced: number;
projectSynced: number;
skipped: number;
errors: number;
details: {
synced: string[];
skipped: string[];
errors: string[];
builtinSynced: string[];
};
}>;
/**
* Channel D — Dev Documents 生成
* 将 knowledgeType='dev-document' 的条目以原始 MD 写入
* .cursor/skills/autosnippet-devdocs/references/ 目录
*/
_generateChannelD(documents: KnowledgeEntryProps[]): {
documentsCount: number;
filesWritten: number;
filePaths: string[];
};
/**
* Channel F — Agent Instructions 生成
* 生成 AGENTS.md / CLAUDE.md / .github/copilot-instructions.md
*/
_generateChannelF(rules: KnowledgeEntryProps[], patterns: KnowledgeEntryProps[]): {
filesWritten: number;
totalTokens: number;
files: {
agents: string;
claude: string;
copilot: string;
};
} | {
filesWritten: number;
totalTokens: number;
files: {
agents?: undefined;
claude?: undefined;
copilot?: undefined;
};
};
/**
* 文件名安全 slug 化
*/
_slugify(text: string): string;
/**
* 镜像 .cursor/ 交付物料到目标 IDE 目录(Qoder / Trae 等兼容 IDE)
* 只复制 autosnippet- 前缀的文件/目录,不触碰用户自定义内容
* @param targetDirName 目标目录名,如 '.qoder' 或 '.trae'
*/
_mirrorToIDE(targetDirName: string): void;
/**
* 递归复制目录
*/
_copyDirRecursive(src: string, dest: string): void;
/**
* 从项目路径推断项目名称
*/
_inferProjectName(projectRoot: string): string;
}
export default CursorDeliveryPipeline;