UNPKG

autosnippet

Version:

Extract code patterns into a knowledge base for AI coding assistants

244 lines (243 loc) 8.26 kB
/** * SetupService 项目初始化服务(V2 重构版) * * 一键初始化 AutoSnippet V2 工作空间,5 步完成: * * Step 1 .autosnippet/ 运行时目录 + config.json + .gitignore * Step 2 AutoSnippet/ 知识库目录结构 + AutoSnippet/recipes/(有 --repo clone,无则为普通目录) * Step 3 IDE 集成(VSCode MCP + Cursor MCP + copilot-instructions + cursor-rules * + skills-template + cursor-workflow + claude-hooks + guard-ci + pre-commit-hook) * Step 4 SQLite 数据库 + V1 数据迁移 * Step 5 平台相关初始化(macOS Xcode Snippets) * * ═══════════════════════════════════════════════════════════ * * 数据架构(核心数据在子仓库,受 git 权限保护) * ───────────────────────────────────────────── * AutoSnippet/ (知识库根目录) * ├─ constitution.yaml 权限宪法:角色 + 权限矩阵 + 治理规则 + 能力探测 * ├─ boxspec.json 项目规格定义 * ├─ recipes/ Git 子仓库 = 唯一真实来源 Source of Truth * └─ *.md 统一知识实体(代码规范/模式/架构/调用链/数据流/...) * ├─ candidates/ 候选知识(待审批) * ├─ skills/ Project Skills(冷启动自动生成 + 手动创建) * └─ README.md * * .autosnippet/ (运行时缓存,gitignored) * ├─ config.json 项目配置(含 core.subRepoDir 子仓库路径) * ├─ autosnippet.db SQLite 运行时缓存(从子仓库同步 + candidates/snippets/audit) * ├─ context/ 向量索引缓存 * └─ logs/ 运行日志 * * 数据流 * ───── * 写入:编辑子仓库文件 git push(需权限)→ asd sync 更新 DB 缓存 * 读取:查询 SQLite(快速索引) * 核心数据(统一 Recipe 实体)修改必须经过 git,普通用户无法绕过 * * 权限模型(三层架构) * ────────────────── * 能力层 WriteGuard git push --dry-run:探测子仓库写权限(物理信号) * 角色层 Permission constitution.yaml 角色权限矩阵(逻辑裁决) * 治理层 Constitution constitution.yaml 优先级规则引擎(业务裁决) * * 子仓库 git 权限只是"一种能力(capability)",最终裁决权在 Constitution YAML。 */ export declare class SetupService { force: boolean; projectName: string; projectRoot: string; _results: Array<{ step: number; label: string; ok: boolean; error?: string; }> | null; candidatesDir: string; coreDir: string; dbPath: string; recipesDir: string; runtimeDir: string; seed: boolean; skillsDir: string; /** 子仓库相对路径(相对于 projectRoot),如 'AutoSnippet/recipes' */ subRepoDir: string; /** 子仓库绝对路径 */ subRepoPath: string; /** 子仓库远程仓库 URL(为空则 recipes/ 作为普通目录随主仓库提交) */ subRepoUrl: string | undefined; /** * @param options */ constructor(options: { projectRoot: string; force?: boolean; seed?: boolean; /** 自定义子仓库相对路径(默认 'AutoSnippet/recipes' */ subRepoDir?: string; /** 子仓库远程仓库 URL(提供则 clone,不提供则 recipes/ 为普通目录) */ subRepoUrl?: string; }); getSteps(): ({ label: string; fn: () => { created: string; }; } | { label: string; fn: () => { coreInit: boolean; alreadyRepo: boolean; subRepoPath: string; hasUrl: boolean; }; } | { label: string; fn: () => { configured: string[]; }; } | { label: string; fn: () => Promise<{ dbPath: string; }>; } | { label: string; fn: () => Promise<{ skipped: boolean; }>; } | { label: string; fn: () => Promise<{ status: string; reason: string; hint: string; indexed?: undefined; skipped?: undefined; errors?: undefined; error?: undefined; } | { status: string; reason: string; hint?: undefined; indexed?: undefined; skipped?: undefined; errors?: undefined; error?: undefined; } | { status: string; indexed: number; skipped: number; errors: number; reason?: undefined; hint?: undefined; error?: undefined; } | { status: string; error: string; hint: string; reason?: undefined; indexed?: undefined; skipped?: undefined; errors?: undefined; }>; })[]; run(): Promise<{ step: number; label: string; ok: boolean; error?: string; }[]>; /** 格式化步骤结果的简要信息 */ private _formatStepDetail; printSummary(): void; stepRuntime(): { created: string; }; stepCoreRepo(): { coreInit: boolean; alreadyRepo: boolean; subRepoPath: string; hasUrl: boolean; }; /** 写入 constitution.yaml(优先从模板复制) */ private _writeConstitution; /** 写入 boxspec.json */ private _writeBoxspec; /** 复制 _template.md recipes/ */ private _copyRecipeTemplate; /** 复制示例 Recipe(冷启动推荐) */ private _copySeedRecipes; /** 写入核心目录 README */ private _writeCoreReadme; stepIDE(): { configured: string[]; }; stepDatabase(): Promise<{ dbPath: string; }>; /** * AutoSnippet/recipes/*.md + candidates/*.md 同步到 DB 缓存 * 委托 KnowledgeSyncService 执行全字段同步(setup 场景跳过违规记录) */ private _syncRecipesToDB; stepPlatform(): Promise<{ skipped: boolean; }>; /** * 在项目根目录创建 .env 文件(从 .env.example 复制) * 如果 .env 已存在则跳过并提示用户手动配置。 */ private _ensureEnvFile; /** 在指定目录执行 git 命令 */ private _git; /** 检查目录中是否有文件(排除 . ..) */ private _hasFiles; /** 确保子仓库的 remote origin 与给定 URL 一致 */ private _ensureRemote; /** * 备份已有文件 clone 合并回来(不覆盖远端文件) * 适用于 recipes/ 有模板文件但还不是 git 仓库的场景 */ private _cloneWithMerge; /** * 尝试初始化向量索引: 检查 embedding provider 可用性, * 若可用则自动构建初始索引;否则提示用户手动运行 asd embed。 * * 此步骤为 best-effort: 失败不阻塞 setup 流程。 */ stepVectorIndex(): Promise<{ status: string; reason: string; hint: string; indexed?: undefined; skipped?: undefined; errors?: undefined; error?: undefined; } | { status: string; reason: string; hint?: undefined; indexed?: undefined; skipped?: undefined; errors?: undefined; error?: undefined; } | { status: string; indexed: number; skipped: number; errors: number; reason?: undefined; hint?: undefined; error?: undefined; } | { status: string; error: string; hint: string; reason?: undefined; indexed?: undefined; skipped?: undefined; errors?: undefined; }>; } export default SetupService;