@vinsonw2/asset-compound 0.0.0-stage → 0.1.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schema.ts","../src/pipeline.ts","../src/setup.ts"],"sourcesContent":["import { Ajv2020, type ValidateFunction } from \"ajv/dist/2020.js\";\nimport formatsPlugin from \"ajv-formats\";\nimport type { AssetRecord, ReadState, RunConfig } from \"./types.js\";\n\nconst dimension = {\n type: \"object\",\n additionalProperties: false,\n required: [\"level\", \"evidence\", \"gaps\", \"recommendations\"],\n properties: {\n level: {\n enum: [\"ready\", \"partial\", \"missing\", \"conflict\", \"high\", \"medium\", \"low\"],\n },\n evidence: { type: \"array\", items: { type: \"string\" } },\n gaps: { type: \"array\", items: { type: \"string\" } },\n recommendations: { type: \"array\", items: { type: \"string\" } },\n },\n} as const;\n\nexport const assetSchema = {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n additionalProperties: false,\n required: [\n \"assetId\",\n \"sourceType\",\n \"sourceRef\",\n \"sourceRevision\",\n \"contentHash\",\n \"title\",\n \"summary\",\n \"facts\",\n \"decisions\",\n \"actions\",\n \"relations\",\n \"analysis\",\n \"writebackKind\",\n ],\n properties: {\n assetId: { type: \"string\", pattern: \"^sha256:[a-f0-9]{64}$\" },\n sourceType: { enum: [\"requirement\", \"design\", \"ai-artifact\", \"git\"] },\n sourceRef: { type: \"string\", minLength: 1 },\n sourceRevision: { type: \"string\", minLength: 1 },\n contentHash: { type: \"string\", pattern: \"^sha256:[a-f0-9]{64}$\" },\n title: { type: \"string\", minLength: 1 },\n summary: { type: \"string\" },\n facts: { type: \"array\", items: { type: \"string\" } },\n decisions: { type: \"array\", items: { type: \"string\" } },\n actions: { type: \"array\", items: { type: \"string\" } },\n relations: { type: \"array\", items: { type: \"string\" } },\n analysis: {\n type: \"object\",\n additionalProperties: false,\n required: [\"completeness\", \"executability\", \"consistency\", \"reuseValue\"],\n properties: {\n completeness: dimension,\n executability: dimension,\n consistency: dimension,\n reuseValue: dimension,\n },\n },\n writebackKind: { enum: [\"新增\", \"增量\", \"未变\"] },\n },\n} as const;\n\nconst configSchema = {\n type: \"object\",\n additionalProperties: false,\n required: [\"outputRoot\", \"sourceSets\"],\n properties: {\n outputRoot: { const: \"docs/可读化\" },\n baseBranch: { type: \"string\", minLength: 1 },\n sourceSets: {\n type: \"array\",\n minItems: 2,\n items: {\n type: \"object\",\n additionalProperties: false,\n required: [\"type\"],\n properties: {\n type: { enum: [\"requirement\", \"design\", \"ai-artifact\", \"git\"] },\n include: { type: \"array\", items: { type: \"string\" } },\n maxCommits: { type: \"integer\", minimum: 1, maximum: 1000 },\n },\n },\n },\n exclude: { type: \"array\", items: { type: \"string\" } },\n },\n} as const;\n\nconst stateSchema = {\n type: \"object\",\n additionalProperties: false,\n required: [\n \"schemaVersion\",\n \"selfHash\",\n \"baseBranch\",\n \"baseCommit\",\n \"lastReadCommit\",\n \"sources\",\n \"assets\",\n \"managedFiles\",\n ],\n properties: {\n schemaVersion: { const: 1 },\n selfHash: { type: \"string\", pattern: \"^sha256:[a-f0-9]{64}$\" },\n baseBranch: { type: \"string\" },\n baseCommit: { type: \"string\" },\n lastReadCommit: { type: \"string\" },\n sources: {\n type: \"object\",\n additionalProperties: {\n type: \"object\",\n additionalProperties: false,\n required: [\"contentHash\", \"sourceRevision\", \"assetIds\", \"status\"],\n properties: {\n contentHash: { type: \"string\", pattern: \"^sha256:[a-f0-9]{64}$\" },\n sourceRevision: { type: \"string\", minLength: 1 },\n assetIds: {\n type: \"array\",\n items: { type: \"string\", pattern: \"^sha256:[a-f0-9]{64}$\" },\n },\n status: { enum: [\"active\", \"stale\"] },\n },\n },\n },\n assets: {\n type: \"object\",\n additionalProperties: {\n type: \"object\",\n additionalProperties: false,\n required: [\"canonicalContentHash\", \"outputPath\", \"lastGeneratedHash\"],\n properties: {\n canonicalContentHash: { type: \"string\", pattern: \"^sha256:[a-f0-9]{64}$\" },\n outputPath: {\n type: \"string\",\n pattern: \"^(?!.*(?:^|/)\\\\.\\\\.(?:/|$))docs/可读化/.+$\",\n },\n lastGeneratedHash: { type: \"string\", pattern: \"^sha256:[a-f0-9]{64}$\" },\n },\n },\n },\n managedFiles: {\n type: \"object\",\n propertyNames: {\n pattern: \"^(?!.*(?:^|/)\\\\.\\\\.(?:/|$))docs/可读化/.+$\",\n },\n additionalProperties: { type: \"string\", pattern: \"^sha256:[a-f0-9]{64}$\" },\n },\n },\n} as const;\n\nconst ajv = new Ajv2020({ strict: true, allErrors: true });\n(formatsPlugin as unknown as (instance: Ajv2020) => Ajv2020)(ajv);\n\nfunction compile<T>(schema: object): ValidateFunction<T> {\n return ajv.compile<T>(schema);\n}\n\nexport const validateAsset = compile<AssetRecord>(assetSchema);\nexport const validateConfig = compile<RunConfig>(configSchema);\nexport const validateState = compile<ReadState>(stateSchema);\n\nexport function assertValid<T>(\n validator: ValidateFunction<T>,\n value: unknown,\n label: string,\n): asserts value is T {\n if (!validator(value)) {\n const details = (validator.errors ?? [])\n .map((error) => `${error.instancePath || \"/\"} ${error.message}`)\n .sort()\n .join(\"; \");\n throw new Error(`${label} 未通过 schema 校验:${details}`);\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { access, lstat, mkdir, readFile, realpath } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport fg from \"fast-glob\";\nimport writeFileAtomic from \"write-file-atomic\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport {\n assertValid,\n validateAsset,\n validateConfig,\n validateState,\n} from \"./schema.js\";\nimport type {\n AssetRecord,\n Conflict,\n DimensionFinding,\n PipelineResult,\n ReadState,\n RunConfig,\n ScanRecord,\n SourceSet,\n SourceType,\n} from \"./types.js\";\n\nconst execFileAsync = promisify(execFile);\nconst OUTPUT_ROOT = \"docs/可读化\";\nconst SOURCE_TYPE_LABEL: Record<SourceType, string> = {\n requirement: \"需求\",\n design: \"设计\",\n \"ai-artifact\": \"AI 产物\",\n git: \"Git 历史\",\n};\nconst LEVEL_LABEL: Record<DimensionFinding[\"level\"], string> = {\n ready: \"就绪\",\n partial: \"部分满足\",\n missing: \"缺失\",\n conflict: \"冲突\",\n high: \"高\",\n medium: \"中\",\n low: \"低\",\n};\n\nexport function sha256(value: string | Buffer): string {\n const normalized =\n typeof value === \"string\"\n ? value.replace(/\\r\\n?/g, \"\\n\").normalize(\"NFC\")\n : value;\n return `sha256:${createHash(\"sha256\").update(normalized).digest(\"hex\")}`;\n}\n\nasync function exists(file: string): Promise<boolean> {\n try {\n await access(file);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function git(repo: string, args: string[]): Promise<string> {\n const { stdout } = await execFileAsync(\"git\", args, {\n cwd: repo,\n encoding: \"utf8\",\n maxBuffer: 20 * 1024 * 1024,\n });\n return stdout.trimEnd();\n}\n\nexport async function assertOutputPath(repo: string, target: string): Promise<string> {\n const root = await realpath(repo);\n const absolute = path.resolve(root, target);\n const relative = path.relative(root, absolute);\n if (\n path.isAbsolute(relative) ||\n relative === \"..\" ||\n relative.startsWith(`..${path.sep}`) ||\n !(relative === OUTPUT_ROOT || relative.startsWith(`${OUTPUT_ROOT}${path.sep}`))\n ) {\n throw new Error(`拒绝写入 ${OUTPUT_ROOT} 之外的路径:${target}`);\n }\n\n let cursor = root;\n for (const segment of relative.split(path.sep)) {\n cursor = path.join(cursor, segment);\n if (await exists(cursor)) {\n const stat = await lstat(cursor);\n if (stat.isSymbolicLink()) {\n throw new Error(`拒绝输出路径中的符号链接:${cursor}`);\n }\n }\n }\n return absolute;\n}\n\nexport async function atomicWriteIfChanged(\n repo: string,\n relativePath: string,\n content: string,\n): Promise<boolean> {\n const target = await assertOutputPath(repo, relativePath);\n const normalized = `${content.replace(/\\r\\n?/g, \"\\n\").trimEnd()}\\n`;\n if (await exists(target)) {\n const current = await readFile(target, \"utf8\");\n if (current === normalized) return false;\n }\n await mkdir(path.dirname(target), { recursive: true });\n await writeFileAtomic(target, normalized, { encoding: \"utf8\", fsync: true });\n return true;\n}\n\nexport async function loadConfig(configPath: string): Promise<RunConfig> {\n const value = parseYaml(await readFile(configPath, \"utf8\")) as unknown;\n assertValid(validateConfig, value, \"运行配置\");\n const types = new Set(value.sourceSets.map((source) => source.type));\n if (types.size < 2) {\n throw new Error(\"V2 要求至少两种不同的来源类型\");\n }\n return value;\n}\n\nexport async function plan(repo: string, configPath: string) {\n const repoRoot = await realpath(repo);\n const config = await loadConfig(configPath);\n const inside = await git(repoRoot, [\"rev-parse\", \"--is-inside-work-tree\"]);\n if (inside !== \"true\") throw new Error(\"目标路径不是 Git 工作树\");\n return {\n repoRoot,\n outputRoot: config.outputRoot,\n sourceTypes: [...new Set(config.sourceSets.map((source) => source.type))].sort(),\n baseCommit: await git(repoRoot, [\"rev-parse\", \"HEAD\"]),\n };\n}\n\nasync function fileRevision(repo: string, file: string): Promise<string> {\n try {\n return (await git(repo, [\"log\", \"-1\", \"--format=%H\", \"--\", file])) || \"untracked\";\n } catch {\n return \"untracked\";\n }\n}\n\nasync function scanFileSet(\n repo: string,\n source: SourceSet,\n excludes: string[],\n): Promise<ScanRecord[]> {\n if (!source.include?.length) {\n throw new Error(`${SOURCE_TYPE_LABEL[source.type]}来源必须配置 include glob`);\n }\n const files = await fg(source.include, {\n cwd: repo,\n onlyFiles: true,\n unique: true,\n dot: false,\n followSymbolicLinks: false,\n ignore: excludes,\n });\n files.sort();\n if (files.length === 0) {\n throw new Error(`${SOURCE_TYPE_LABEL[source.type]}来源为空`);\n }\n return Promise.all(\n files.map(async (file) => {\n if (redactSensitive(file) !== file) {\n throw new Error(`拒绝包含敏感信息的来源路径:${file}`);\n }\n const root = await realpath(repo);\n const absolute = path.resolve(root, file);\n const relative = path.relative(root, absolute);\n if (\n path.isAbsolute(relative) ||\n relative === \"..\" ||\n relative.startsWith(`..${path.sep}`)\n ) {\n throw new Error(`拒绝读取仓库之外的来源:${file}`);\n }\n const stat = await lstat(absolute);\n if (stat.isSymbolicLink()) throw new Error(`拒绝符号链接来源:${file}`);\n const resolvedSource = await realpath(absolute);\n if (resolvedSource !== absolute) {\n throw new Error(`拒绝通过符号链接逃逸仓库的来源:${file}`);\n }\n const buffer = await readFile(absolute);\n const text = buffer.toString(\"utf8\");\n const isText = /\\.(?:md|mdx|txt|json|ya?ml|tsx?|jsx?|css|html)$/i.test(file);\n return {\n sourceType: source.type,\n sourceRef: file.split(path.sep).join(\"/\"),\n sourceRevision: await fileRevision(repo, file),\n contentHash: sha256(isText ? text : buffer),\n content: text,\n };\n }),\n );\n}\n\nasync function scanGitSet(repo: string, source: SourceSet): Promise<ScanRecord[]> {\n const maxCommits = source.maxCommits ?? 20;\n const output = await git(repo, [\n \"log\",\n `-${maxCommits}`,\n \"--format=%H%x1f%s%x1f%b%x1f%aI%x00\",\n ]);\n const records = output\n .split(\"\\0\")\n .map((record) => record.trim())\n .filter(Boolean)\n .map((record) => {\n const [commit = \"\", subject = \"\", body = \"\", authoredAt = \"\"] = record.split(\"\\x1f\");\n const content = [subject, body, authoredAt].filter(Boolean).join(\"\\n\");\n return {\n sourceType: \"git\" as const,\n sourceRef: `git:${commit}`,\n sourceRevision: commit,\n contentHash: sha256(content),\n content,\n };\n });\n if (records.length === 0) throw new Error(\"Git 历史来源为空\");\n return records;\n}\n\nexport async function scan(repo: string, config: RunConfig): Promise<ScanRecord[]> {\n const excludes = [\n `${OUTPUT_ROOT}/**`,\n \"node_modules/**\",\n \"dist/**\",\n ...(config.exclude ?? []),\n ];\n const groups = await Promise.all(\n config.sourceSets.map((source) =>\n source.type === \"git\"\n ? scanGitSet(repo, source)\n : scanFileSet(repo, source, excludes),\n ),\n );\n const records = groups.flat().sort((a, b) =>\n `${a.sourceType}:${a.sourceRef}`.localeCompare(`${b.sourceType}:${b.sourceRef}`),\n );\n const nonEmptyTypes = new Set(records.map((record) => record.sourceType));\n if (nonEmptyTypes.size < 2) {\n throw new Error(\"V2 要求至少两类真实且非空的来源\");\n }\n return records;\n}\n\nfunction titleFor(record: ScanRecord): string {\n const content = redactSensitive(record.content);\n if (record.sourceType === \"git\") {\n return content.split(\"\\n\")[0]?.trim() || record.sourceRevision.slice(0, 12);\n }\n const heading = content.match(/^#\\s+(.+)$/m)?.[1]?.trim();\n return heading || path.basename(record.sourceRef, path.extname(record.sourceRef));\n}\n\nfunction compactLines(content: string): string[] {\n return content\n .replace(/^#{1,6}\\s+/gm, \"\")\n .split(/\\n+/)\n .map((line) => line.trim())\n .filter(Boolean);\n}\n\nexport function redactSensitive(value: string): string {\n return value\n .replace(/\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}\\b/gi, \"[REDACTED_EMAIL]\")\n .replace(/\\b(?:gh[pousr]_[A-Za-z0-9_]{20,}|AKIA[A-Z0-9]{16})\\b/g, \"[REDACTED_SECRET]\")\n .replace(\n /\\b(api[_-]?key|token|secret|password)\\s*[:=]\\s*[\"']?[^\\s\"'`]+/gi,\n \"$1=[REDACTED_SECRET]\",\n );\n}\n\nexport function prepare(records: ScanRecord[], previous: ReadState | null): AssetRecord[] {\n return records.map((record) => {\n const sourceKey = `${record.sourceType}:${record.sourceRef}`;\n const old = previous?.sources[sourceKey];\n const writebackKind =\n old?.contentHash === record.contentHash ? \"未变\" : old ? \"增量\" : \"新增\";\n const lines = compactLines(redactSensitive(record.content));\n const evidence = [`${record.sourceRef}@${record.sourceRevision}`];\n const hasActions = lines.some((line) => /(^|\\s)(must|should|todo|需要|必须|应当)/i.test(line));\n const summary = lines.join(\" \").slice(0, 280);\n const asset: AssetRecord = {\n assetId: sha256(sourceKey),\n sourceType: record.sourceType,\n sourceRef: record.sourceRef,\n sourceRevision: record.sourceRevision,\n contentHash: record.contentHash,\n title: titleFor(record),\n summary,\n facts: lines.slice(0, 5),\n decisions: [],\n actions: hasActions ? lines.filter((line) => /must|should|todo|需要|必须|应当/i.test(line)).slice(0, 5) : [],\n relations: [],\n analysis: {\n completeness: {\n level: summary.length >= 80 ? \"partial\" : \"missing\",\n evidence,\n gaps: [\"需要人工确认范围、约束与验收边界\"],\n recommendations: [\"由 Skill 基于业务上下文补全完整性分析\"],\n },\n executability: {\n level: hasActions ? \"partial\" : \"missing\",\n evidence,\n gaps: hasActions ? [\"行动项负责人和完成条件待确认\"] : [\"未识别到明确行动项\"],\n recommendations: [\"补充负责人、前置条件和可验证完成标准\"],\n },\n consistency: {\n level: \"partial\",\n evidence,\n gaps: [\"需要跨资产对照后确认一致性\"],\n recommendations: [\"将相关需求、设计和历史决策进行交叉核验\"],\n },\n reuseValue: {\n level: lines.length >= 3 ? \"medium\" : \"low\",\n evidence,\n gaps: [\"复用场景与适用边界待确认\"],\n recommendations: [\"提炼可复制的决策、检查表或模板\"],\n },\n },\n writebackKind,\n };\n assertValid(validateAsset, asset, `资产 ${asset.assetId}`);\n return asset;\n });\n}\n\nexport async function loadAssetsFile(\n file: string,\n records?: ScanRecord[],\n): Promise<AssetRecord[]> {\n const value = JSON.parse(await readFile(file, \"utf8\")) as unknown;\n if (!Array.isArray(value)) throw new Error(\"增强资产输入必须是 JSON 数组\");\n const assets = value.map((candidate, index) => {\n assertValid(validateAsset, candidate, `资产输入 ${index}`);\n const serialized = JSON.stringify(candidate);\n if (redactSensitive(serialized) !== serialized) {\n throw new Error(`资产输入 ${index} 包含敏感数据`);\n }\n return candidate;\n });\n const sourceKeys = assets.map((asset) => `${asset.sourceType}:${asset.sourceRef}`);\n if (\n new Set(sourceKeys).size !== assets.length ||\n new Set(assets.map((asset) => asset.assetId)).size !== assets.length\n ) {\n throw new Error(\"增强资产输入包含重复来源或重复资产 ID\");\n }\n if (records) {\n const bySource = new Map(\n records.map((record) => [`${record.sourceType}:${record.sourceRef}`, record]),\n );\n for (const asset of assets) {\n const record = bySource.get(`${asset.sourceType}:${asset.sourceRef}`);\n if (!record) throw new Error(`资产来源不在本次扫描中:${asset.sourceRef}`);\n if (\n asset.assetId !== sha256(`${record.sourceType}:${record.sourceRef}`) ||\n asset.contentHash !== record.contentHash ||\n asset.sourceRevision !== record.sourceRevision\n ) {\n throw new Error(`资产来源追踪字段被修改:${asset.sourceRef}`);\n }\n }\n if (assets.length !== records.length) {\n throw new Error(\"增强资产输入必须为每个扫描来源提供且仅提供一条资产\");\n }\n const expectedSources = new Set(bySource.keys());\n if (sourceKeys.some((key) => !expectedSources.has(key))) {\n throw new Error(\"增强资产输入与本次扫描不匹配\");\n }\n }\n return assets;\n}\n\nfunction renderDimension(label: string, finding: AssetRecord[\"analysis\"][\"completeness\"]): string {\n const bullets = (items: string[]) =>\n items.length ? items.map((item) => `- ${redactSensitive(item)}`).join(\"\\n\") : \"- 无\";\n return `### ${label}:${LEVEL_LABEL[finding.level]}\\n\\n**证据**\\n${bullets(finding.evidence)}\\n\\n**缺口**\\n${bullets(finding.gaps)}\\n\\n**建议**\\n${bullets(finding.recommendations)}`;\n}\n\nexport function renderAsset(asset: AssetRecord): string {\n return `# ${redactSensitive(asset.title)}\n\n- 标记:${asset.writebackKind}\n- 类型:${SOURCE_TYPE_LABEL[asset.sourceType]}\n- 来源:\\`${redactSensitive(asset.sourceRef)}\\`\n- 来源版本(sourceRevision):\\`${asset.sourceRevision}\\`\n- 内容指纹(contentHash):\\`${asset.contentHash}\\`\n- 资产 ID(assetId):\\`${asset.assetId}\\`\n\n## 摘要\n\n${redactSensitive(asset.summary) || \"无可提取摘要。\"}\n\n## 四维分析\n\n${renderDimension(\"完整性\", asset.analysis.completeness)}\n\n${renderDimension(\"可执行性\", asset.analysis.executability)}\n\n${renderDimension(\"一致性\", asset.analysis.consistency)}\n\n${renderDimension(\"复用价值\", asset.analysis.reuseValue)}\n`;\n}\n\nasync function readState(repo: string): Promise<ReadState | null> {\n const statePath = path.join(repo, OUTPUT_ROOT, \"state/read-state.json\");\n if (!(await exists(statePath))) return null;\n const value = JSON.parse(await readFile(statePath, \"utf8\")) as unknown;\n assertValid(validateState, value, \"读取状态\");\n const expected = sha256(JSON.stringify({ ...value, selfHash: \"\" }, null, 2));\n if (value.selfHash !== expected) {\n throw new Error(\"读取状态的 selfHash 不匹配;拒绝覆盖已编辑的 state\");\n }\n return value;\n}\n\nfunction renderIndex(assets: AssetRecord[]): string {\n const rows = assets\n .map(\n (asset) =>\n `| [${redactSensitive(asset.title)}](assets/${asset.assetId.slice(7)}.md) | ${SOURCE_TYPE_LABEL[asset.sourceType]} | ${asset.writebackKind} | \\`${redactSensitive(asset.sourceRef)}\\` |`,\n )\n .join(\"\\n\");\n return `# 资产复利索引\n\n> 本目录由 asset-compound 管理。示例 fixture 不能作为真实验收数据。\n\n| 资产 | 类型 | 标记 | 来源 |\n|---|---|---|---|\n${rows}\n`;\n}\n\nasync function loadTemplate(name: string): Promise<string> {\n return readFile(new URL(`../templates/${name}`, import.meta.url), \"utf8\");\n}\n\nasync function renderConflicts(runId: string, conflicts: Conflict[]): Promise<string> {\n const details =\n conflicts.length === 0\n ? \"本次检查发现 0 个冲突。\"\n : conflicts\n .map(\n (conflict) =>\n `## ${conflict.assetId}\\n\\n- 路径:\\`${conflict.path}\\`\\n- 原因:${conflict.reason}\\n- 期望内容指纹(hash):\\`${conflict.expectedHash ?? \"无\"}\\`\\n- 当前内容指纹(hash):\\`${conflict.actualHash ?? \"无\"}\\``,\n )\n .join(\"\\n\\n\");\n return (await loadTemplate(\"conflict-report.md\"))\n .replaceAll(\"{{run_id}}\", runId)\n .replaceAll(\"{{conflict_count}}\", String(conflicts.length))\n .replaceAll(\"{{conflicts}}\", details);\n}\n\nasync function renderAcceptance(\n branch: string,\n base: string,\n head: string,\n result: Omit<PipelineResult, \"changedFiles\">,\n): Promise<string> {\n const requirements = [\n \"| 条款 | 结果 |\",\n \"|---|---|\",\n \"| R1 识别读取 | 已生成 manifest,仍需人工确认材料范围 |\",\n \"| R2 结构化提取 | 已通过 JSON Schema |\",\n \"| R3 四维分析 | 已生成四维基线,业务结论需人工抽检 |\",\n \"| R4 增量回写 | 已限制 docs/可读化 并输出冲突报告 |\",\n \"| R5 增量状态 | 已保存文件 hash 与 commit;需二次运行验证 |\",\n \"| R6 全链路留痕 | 已建立来源、revision、asset 与输出映射 |\",\n ].join(\"\\n\");\n const verification = [\n \"| 验收点 | 结果 |\",\n \"|---|---|\",\n \"| V1–V4 | 已产出机器证据;真实材料与四维结论仍需人工验收 |\",\n \"| V5 | 已验证非基线分支与 Git scope;提交/PR 待外部流程确认 |\",\n \"| V6 | 待相同输入二次运行证明零业务 diff |\",\n \"| V7 | 已记录 revision 与 hash;回写 commit 待提交后补齐 |\",\n \"| V8 | 已生成索引与资产详情;可读复用需人工抽检 |\",\n ].join(\"\\n\");\n return (await loadTemplate(\"acceptance-report.md\"))\n .replaceAll(\"{{run_id}}\", result.runId)\n .replaceAll(\"{{branch}}\", branch)\n .replaceAll(\"{{base_sha}}\", base)\n .replaceAll(\"{{head_sha}}\", head)\n .replaceAll(\n \"{{source_type_summary}}\",\n [...new Set(result.assets.map((asset) => SOURCE_TYPE_LABEL[asset.sourceType]))]\n .sort()\n .join(\"、\"),\n )\n .replaceAll(\"{{new_count}}\", String(result.counts.new))\n .replaceAll(\"{{updated_count}}\", String(result.counts.updated))\n .replaceAll(\"{{unchanged_count}}\", String(result.counts.unchanged))\n .replaceAll(\"{{conflict_count}}\", String(result.counts.conflicts))\n .replaceAll(\"{{requirements_matrix}}\", requirements)\n .replaceAll(\"{{verification_matrix}}\", verification)\n .replaceAll(\n \"{{four_dimension_summary}}\",\n `${result.assets.length} 条资产均包含完整性、可执行性、一致性、复用价值四项结构化结论。`,\n )\n .replaceAll(\n \"{{conflict_and_evidence_links}}\",\n `- [冲突报告](../conflicts/${result.runId}.md)\\n- [来源清单](../source-manifest.yaml)`,\n );\n}\n\nexport async function render(\n repo: string,\n config: RunConfig,\n records: ScanRecord[],\n assets: AssetRecord[],\n previous: ReadState | null,\n): Promise<PipelineResult> {\n const head = await git(repo, [\"rev-parse\", \"HEAD\"]);\n const branch = await git(repo, [\"branch\", \"--show-current\"]);\n const baseBranch = config.baseBranch ?? \"main\";\n const baseCommit = await git(repo, [\"merge-base\", \"HEAD\", baseBranch]);\n const changedAssets = assets.filter((asset) => asset.writebackKind !== \"未变\");\n const conflicts: Conflict[] = [];\n const contentByAsset = new Map<string, string>();\n\n for (const asset of assets) {\n const content = renderAsset(asset);\n contentByAsset.set(asset.assetId, content);\n const old = previous?.assets[asset.assetId];\n const expectedPath = `${OUTPUT_ROOT}/assets/${asset.assetId.slice(7)}.md`;\n if (old) {\n const oldPath = await assertOutputPath(repo, old.outputPath);\n if (await exists(oldPath)) {\n const actualHash = sha256(await readFile(oldPath, \"utf8\"));\n if (actualHash !== old.lastGeneratedHash) {\n conflicts.push({\n assetId: asset.assetId,\n path: old.outputPath,\n reason: \"人工编辑与生成内容冲突,已拒绝覆盖\",\n expectedHash: old.lastGeneratedHash,\n actualHash,\n });\n }\n } else {\n conflicts.push({\n assetId: asset.assetId,\n path: old.outputPath,\n reason: \"state 引用的生成文件缺失,已拒绝静默重建\",\n expectedHash: old.lastGeneratedHash,\n });\n }\n } else if (await exists(path.join(repo, expectedPath))) {\n conflicts.push({\n assetId: asset.assetId,\n path: expectedPath,\n reason: \"发现无 state 归属的既有资产文件,已拒绝覆盖\",\n actualHash: sha256(await readFile(path.join(repo, expectedPath), \"utf8\")),\n });\n }\n }\n for (const [managedPath, expectedHash] of Object.entries(previous?.managedFiles ?? {})) {\n const absolute = await assertOutputPath(repo, managedPath);\n if (!(await exists(absolute))) {\n conflicts.push({\n assetId: `managed:${managedPath}`,\n path: managedPath,\n reason: \"受管输出文件缺失,已拒绝静默重建\",\n expectedHash,\n });\n continue;\n }\n const actualHash = sha256(await readFile(absolute));\n if (actualHash !== expectedHash) {\n conflicts.push({\n assetId: `managed:${managedPath}`,\n path: managedPath,\n reason: \"受管输出被人工编辑,已拒绝覆盖\",\n expectedHash,\n actualHash,\n });\n }\n }\n\n const runId = sha256(\n `${head}\\n${records.map((record) => `${record.sourceRef}:${record.contentHash}`).join(\"\\n\")}`,\n ).slice(7, 23);\n if (!previous) {\n const firstRunManagedPaths = [\n `${OUTPUT_ROOT}/README.md`,\n `${OUTPUT_ROOT}/index.md`,\n `${OUTPUT_ROOT}/source-manifest.yaml`,\n `${OUTPUT_ROOT}/conflicts/${runId}.md`,\n `${OUTPUT_ROOT}/evidence/acceptance-report.md`,\n `${OUTPUT_ROOT}/runs/${runId}.md`,\n `${OUTPUT_ROOT}/state/asset-index.jsonl`,\n ];\n for (const managedPath of firstRunManagedPaths) {\n const absolute = await assertOutputPath(repo, managedPath);\n if (await exists(absolute)) {\n conflicts.push({\n assetId: `managed:${managedPath}`,\n path: managedPath,\n reason: \"首次运行发现无 state 归属的既有受管文件,已拒绝覆盖\",\n actualHash: sha256(await readFile(absolute)),\n });\n }\n }\n }\n const conflictIds = new Set(conflicts.map((conflict) => conflict.assetId));\n const writableAssets = changedAssets.filter((asset) => !conflictIds.has(asset.assetId));\n const currentSourceKeys = new Set(\n records.map((record) => `${record.sourceType}:${record.sourceRef}`),\n );\n const hasStaleTransition = Object.entries(previous?.sources ?? {}).some(\n ([key, value]) => value.status === \"active\" && !currentSourceKeys.has(key),\n );\n const resultBase = {\n runId,\n counts: {\n new: assets.filter((asset) => asset.writebackKind === \"新增\").length,\n updated: assets.filter((asset) => asset.writebackKind === \"增量\").length,\n unchanged: assets.filter((asset) => asset.writebackKind === \"未变\").length,\n conflicts: conflicts.length,\n },\n assets,\n conflicts,\n noOp: changedAssets.length === 0 && conflicts.length === 0 && !hasStaleTransition,\n };\n\n if (resultBase.noOp) {\n return { ...resultBase, changedFiles: [], secondRunZeroDiff: true };\n }\n\n if (conflicts.length > 0) {\n const conflictKey = sha256(JSON.stringify(conflicts)).slice(7, 19);\n const conflictPath = `${OUTPUT_ROOT}/conflicts/${runId}-${conflictKey}.md`;\n const changed = await atomicWriteIfChanged(\n repo,\n conflictPath,\n await renderConflicts(runId, conflicts),\n );\n return {\n ...resultBase,\n changedFiles: changed ? [conflictPath] : [],\n };\n }\n\n const changedFiles: string[] = [];\n const write = async (file: string, content: string) => {\n if (await atomicWriteIfChanged(repo, file, content)) changedFiles.push(file);\n };\n\n for (const asset of writableAssets) {\n const file = `${OUTPUT_ROOT}/assets/${asset.assetId.slice(7)}.md`;\n await write(file, contentByAsset.get(asset.assetId) ?? renderAsset(asset));\n }\n\n const sources: ReadState[\"sources\"] = {};\n for (const [key, value] of Object.entries(previous?.sources ?? {})) {\n sources[key] = { ...value, status: \"stale\" };\n }\n for (const record of records) {\n const sourceKey = `${record.sourceType}:${record.sourceRef}`;\n const asset = assets.find(\n (candidate) =>\n candidate.sourceType === record.sourceType && candidate.sourceRef === record.sourceRef,\n );\n if (!asset || conflictIds.has(asset.assetId)) continue;\n sources[sourceKey] = {\n contentHash: record.contentHash,\n sourceRevision: record.sourceRevision,\n assetIds: [asset.assetId],\n status: \"active\",\n };\n }\n\n const stateAssets: ReadState[\"assets\"] = { ...(previous?.assets ?? {}) };\n for (const asset of writableAssets) {\n const outputPath = `${OUTPUT_ROOT}/assets/${asset.assetId.slice(7)}.md`;\n const content = contentByAsset.get(asset.assetId) ?? renderAsset(asset);\n stateAssets[asset.assetId] = {\n canonicalContentHash: asset.contentHash,\n outputPath,\n lastGeneratedHash: sha256(`${content.trimEnd()}\\n`),\n };\n }\n const manifest = {\n sourceTypes: [...new Set(records.map((record) => record.sourceType))].sort(),\n sources: records.map(({ content: _content, ...record }) => record),\n };\n const managedContents: Record<string, string> = {\n [`${OUTPUT_ROOT}/README.md`]:\n \"# 可读化资产\\n\\n从 `index.md` 开始阅读。所有内容均保留来源和来源版本(revision)。\\n\",\n [`${OUTPUT_ROOT}/index.md`]: renderIndex(assets),\n [`${OUTPUT_ROOT}/source-manifest.yaml`]: stringifyYaml(manifest),\n [`${OUTPUT_ROOT}/conflicts/${runId}.md`]: await renderConflicts(runId, conflicts),\n [`${OUTPUT_ROOT}/evidence/acceptance-report.md`]: await renderAcceptance(\n branch,\n baseCommit,\n head,\n resultBase,\n ),\n [`${OUTPUT_ROOT}/runs/${runId}.md`]:\n `# 运行记录 ${runId}\\n\\n- 当前提交:\\`${head}\\`\\n- 来源数:${records.length}\\n- 新增:${resultBase.counts.new}\\n- 增量:${resultBase.counts.updated}\\n- 未变:${resultBase.counts.unchanged}\\n- 冲突:${conflicts.length}\\n`,\n [`${OUTPUT_ROOT}/state/asset-index.jsonl`]:\n `${assets.map((asset) => JSON.stringify(asset)).join(\"\\n\")}\\n`,\n };\n const managedFiles = {\n ...(previous?.managedFiles ?? {}),\n ...Object.fromEntries(\n Object.entries(managedContents).map(([file, content]) => [\n file,\n sha256(`${content.trimEnd()}\\n`),\n ]),\n ),\n };\n const nextState: ReadState = {\n schemaVersion: 1,\n selfHash: \"\",\n baseBranch,\n baseCommit: previous?.baseCommit ?? baseCommit,\n lastReadCommit: head,\n sources,\n assets: stateAssets,\n managedFiles,\n };\n nextState.selfHash = sha256(JSON.stringify({ ...nextState, selfHash: \"\" }, null, 2));\n assertValid(validateState, nextState, \"下一版状态\");\n\n for (const [file, content] of Object.entries(managedContents)) {\n await write(file, content);\n }\n await write(`${OUTPUT_ROOT}/state/read-state.json`, JSON.stringify(nextState, null, 2));\n\n changedFiles.sort();\n return { ...resultBase, changedFiles };\n}\n\nexport async function verifyGitScope(repo: string): Promise<string[]> {\n const output = await git(repo, [\"status\", \"--porcelain=v1\", \"-z\", \"--untracked-files=all\"]);\n const entries = output.split(\"\\0\").filter(Boolean);\n const paths: string[] = [];\n for (let index = 0; index < entries.length; index += 1) {\n const entry = entries[index] ?? \"\";\n paths.push(entry.slice(3));\n const status = entry.slice(0, 2);\n if (status.includes(\"R\") || status.includes(\"C\")) {\n const original = entries[index + 1];\n if (original) paths.push(original);\n index += 1;\n }\n }\n const outside = paths.filter(\n (file) => file !== OUTPUT_ROOT && !file.startsWith(`${OUTPUT_ROOT}/`),\n );\n if (outside.length) {\n throw new Error(`检测到 ${OUTPUT_ROOT} 之外的改动:${outside.join(\"、\")}`);\n }\n return paths.sort();\n}\n\nexport async function runPipeline(\n repoInput: string,\n configPath: string,\n assetsFile?: string,\n): Promise<PipelineResult> {\n const repo = await realpath(repoInput);\n const config = await loadConfig(configPath);\n const branch = await git(repo, [\"branch\", \"--show-current\"]);\n const baseBranch = config.baseBranch ?? \"main\";\n if (!branch || branch === baseBranch) {\n throw new Error(`写入必须使用独立分支;当前分支为 ${branch || \"(分离 HEAD)\"}`);\n }\n await verifyGitScope(repo);\n const previous = await readState(repo);\n const records = await scan(repo, config);\n const baselineAssets = prepare(records, previous);\n const assets = assetsFile\n ? (await loadAssetsFile(assetsFile, records)).map((asset) => ({\n ...asset,\n writebackKind:\n baselineAssets.find((baseline) => baseline.assetId === asset.assetId)?.writebackKind ??\n asset.writebackKind,\n }))\n : baselineAssets;\n const result = await render(repo, config, records, assets, previous);\n await verifyGitScope(repo);\n return result;\n}\n\nexport async function inspectPipeline(repoInput: string, configPath: string) {\n const repo = await realpath(repoInput);\n const config = await loadConfig(configPath);\n const previous = await readState(repo);\n const records = await scan(repo, config);\n return { records, assets: prepare(records, previous) };\n}\n\nexport async function verifySecondRun(repoInput: string, configPath: string) {\n const repo = await realpath(repoInput);\n const config = await loadConfig(configPath);\n const previous = await readState(repo);\n if (!previous) throw new Error(\"二次运行验证需要已有 state\");\n const records = await scan(repo, config);\n const assets = prepare(records, previous);\n const changed = assets.filter((asset) => asset.writebackKind !== \"未变\");\n if (changed.length) {\n throw new Error(`第二次运行仍有 ${changed.length} 条新增或增量资产`);\n }\n for (const asset of assets) {\n const state = previous.assets[asset.assetId];\n if (!state) throw new Error(`缺少资产状态:${asset.assetId}`);\n const target = await assertOutputPath(repo, state.outputPath);\n if (!(await exists(target)) || sha256(await readFile(target)) !== state.lastGeneratedHash) {\n throw new Error(`生成资产与 state 不一致:${state.outputPath}`);\n }\n }\n for (const [managedPath, expectedHash] of Object.entries(previous.managedFiles)) {\n const target = await assertOutputPath(repo, managedPath);\n if (!(await exists(target)) || sha256(await readFile(target)) !== expectedHash) {\n throw new Error(`受管输出与 state 不一致:${managedPath}`);\n }\n }\n await verifyGitScope(repo);\n return {\n secondRunZeroDiff: true,\n counts: { new: 0, updated: 0, unchanged: assets.length, conflicts: 0 },\n stateCommit: previous.lastReadCommit,\n };\n}\n","import { mkdir, readFile, stat } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport writeFileAtomic from \"write-file-atomic\";\n\nconst PACKAGE_ROOT = new URL(\"../\", import.meta.url);\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await stat(target);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function packageText(relativePath: string): Promise<string> {\n return readFile(new URL(relativePath, PACKAGE_ROOT), \"utf8\");\n}\n\nasync function writeGenerated(\n target: string,\n content: string,\n force: boolean,\n): Promise<void> {\n if (!force && (await exists(target))) {\n throw new Error(`目标文件已存在;如需覆盖请使用 --force:${target}`);\n }\n await mkdir(path.dirname(target), { recursive: true });\n await writeFileAtomic(target, `${content.trimEnd()}\\n`, {\n encoding: \"utf8\",\n fsync: true,\n });\n}\n\nexport interface InitOptions {\n output?: string;\n baseBranch?: string;\n force?: boolean;\n}\n\nexport async function initGenericWorkspace(options: InitOptions = {}) {\n const outputDir = path.resolve(\n options.output ?? path.join(os.homedir(), \".asset-compound\"),\n );\n const baseBranch = options.baseBranch ?? \"main\";\n const files = {\n readme: path.join(outputDir, \"README.md\"),\n config: path.join(outputDir, \"run.yaml\"),\n prompt: path.join(outputDir, \"prompts\", \"asset-analysis.zh-CN.md\"),\n protocol: path.join(outputDir, \"protocol\", \"README.zh-CN.md\"),\n inputSchema: path.join(outputDir, \"schemas\", \"analysis-input.schema.json\"),\n outputSchema: path.join(outputDir, \"schemas\", \"analysis-output.schema.json\"),\n };\n const config = `outputRoot: docs/可读化\nbaseBranch: ${baseBranch}\nsourceSets:\n - type: requirement\n include:\n - docs/requirements/**/*.md\n - type: design\n include:\n - docs/design/**/*.md\nexclude:\n - node_modules/**\n - dist/**\n - build/**\n - coverage/**\n`;\n const readme = `# 资产复利通用工作区\n\n本目录由 \\`asset-compound init\\` 生成,不依赖特定编辑器。\n\n1. 修改 \\`run.yaml\\`,使用至少两类真实非空来源。\n2. 执行 \\`npx @vinsonw2/asset-compound prepare --repo <仓库> --config \"${files.config}\" > prepared.json\\`。\n3. 让任意 AI 编辑器按 \\`prompts/asset-analysis.zh-CN.md\\` 和 \\`protocol/README.zh-CN.md\\` 生成 \\`enriched.json\\`。\n4. 执行 \\`npx @vinsonw2/asset-compound validate --input enriched.json\\`。\n5. 在独立分支执行 \\`npx @vinsonw2/asset-compound finalize --repo <仓库> --config \"${files.config}\" --assets enriched.json\\`。\n\n命令名、JSON 字段和枚举保持英文;中文含义见提示协议。\n`;\n const force = options.force ?? false;\n await writeGenerated(files.readme, readme, force);\n await writeGenerated(files.config, config, force);\n await writeGenerated(\n files.prompt,\n await packageText(\"prompts/asset-analysis.zh-CN.md\"),\n force,\n );\n await writeGenerated(\n files.protocol,\n await packageText(\"protocol/README.zh-CN.md\"),\n force,\n );\n await writeGenerated(\n files.inputSchema,\n await packageText(\"schemas/analysis-input.schema.json\"),\n force,\n );\n await writeGenerated(\n files.outputSchema,\n await packageText(\"schemas/analysis-output.schema.json\"),\n force,\n );\n return {\n mode: \"generic\",\n outputDir,\n ...files,\n };\n}\n\nexport interface InstallSkillOptions {\n editor: string;\n target?: string;\n force?: boolean;\n}\n\nexport async function installEditorSkill(options: InstallSkillOptions) {\n if (options.editor !== \"cursor\") {\n throw new Error(\n `当前仅提供 Cursor 适配器;通用模式请使用 init。收到 editor=${options.editor}`,\n );\n }\n const target = path.resolve(\n options.target ??\n path.join(os.homedir(), \".cursor\", \"skills\", \"asset-compounding\"),\n );\n const skillFile = path.join(target, \"SKILL.md\");\n await writeGenerated(\n skillFile,\n await packageText(\"skill/asset-compounding/SKILL.md\"),\n options.force ?? false,\n );\n return {\n editor: \"cursor\",\n target,\n skillFile,\n };\n}\n"],"mappings":"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","names":["stat","mkdir","readFile","path","writeFileAtomic","exists"]}
package/dist/cli.js ADDED
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ initGenericWorkspace,
4
+ inspectPipeline,
5
+ installEditorSkill,
6
+ loadAssetsFile,
7
+ loadConfig,
8
+ plan,
9
+ runPipeline,
10
+ scan,
11
+ verifyGitScope,
12
+ verifySecondRun
13
+ } from "./chunk-P2MVWNYS.js";
14
+
15
+ // src/cli.ts
16
+ import { Command } from "commander";
17
+ function print(value) {
18
+ process.stdout.write(`${JSON.stringify(value, null, 2)}
19
+ `);
20
+ }
21
+ function withCommonOptions(command) {
22
+ return command.requiredOption("--repo <path>", "\u76EE\u6807 Git \u4ED3\u5E93").requiredOption("--config <path>", "YAML \u8FD0\u884C\u914D\u7F6E");
23
+ }
24
+ async function main() {
25
+ const titleMap = {
26
+ "Usage:": "\u7528\u6CD5\uFF1A",
27
+ "Arguments:": "\u53C2\u6570\uFF1A",
28
+ "Options:": "\u9009\u9879\uFF1A",
29
+ "Global Options:": "\u5168\u5C40\u9009\u9879\uFF1A",
30
+ "Commands:": "\u547D\u4EE4\uFF1A"
31
+ };
32
+ const program = new Command().name("asset-compound").description("\u5728 docs/\u53EF\u8BFB\u5316 \u4E0B\u751F\u6210\u53EF\u589E\u91CF\u3001\u53EF\u8FFD\u6EAF\u7684\u8D44\u4EA7").usage("[\u9009\u9879] <\u547D\u4EE4>").version("0.1.1", "-V, --version", "\u663E\u793A\u7248\u672C").helpOption("-h, --help", "\u663E\u793A\u5E2E\u52A9").addHelpCommand("help [command]", "\u663E\u793A\u6307\u5B9A\u547D\u4EE4\u7684\u5E2E\u52A9").showHelpAfterError("\uFF08\u4F7F\u7528 --help \u67E5\u770B\u5E2E\u52A9\uFF09").configureHelp({
33
+ styleTitle: (title) => titleMap[title] ?? title,
34
+ subcommandTerm: (command) => command.name() === "help" ? "help [\u547D\u4EE4]" : `${command.name()} [\u9009\u9879]`
35
+ }).configureOutput({
36
+ outputError: (text, write) => write(
37
+ text.replace(/^error:/gm, "\u9519\u8BEF\uFF1A").replace(/required option '([^']+)' not specified/g, "\u7F3A\u5C11\u5FC5\u586B\u9009\u9879 '$1'").replace(/unknown command '([^']+)'/g, "\u672A\u77E5\u547D\u4EE4 '$1'").replace(/unknown option '([^']+)'/g, "\u672A\u77E5\u9009\u9879 '$1'")
38
+ )
39
+ });
40
+ program.command("init").description("\u521D\u59CB\u5316\u7F16\u8F91\u5668\u65E0\u5173\u7684\u914D\u7F6E\u3001\u4E2D\u6587\u63D0\u793A\u534F\u8BAE\u548C schema").option("--output <path>", "\u8F93\u51FA\u76EE\u5F55\uFF1B\u9ED8\u8BA4 ~/.asset-compound").option("--base-branch <name>", "\u76EE\u6807\u4ED3\u5E93\u57FA\u7EBF\u5206\u652F", "main").option("--mode <mode>", "\u521D\u59CB\u5316\u6A21\u5F0F\uFF1B\u5F53\u524D\u652F\u6301 generic", "generic").option("--force", "\u8986\u76D6\u5DF2\u5B58\u5728\u7684\u521D\u59CB\u5316\u6587\u4EF6").action(
41
+ async (options) => {
42
+ if (options.mode !== "generic") {
43
+ throw new Error(`init \u5F53\u524D\u4EC5\u652F\u6301 generic \u6A21\u5F0F\uFF1B\u6536\u5230 mode=${options.mode}`);
44
+ }
45
+ print(
46
+ await initGenericWorkspace({
47
+ baseBranch: options.baseBranch,
48
+ force: options.force ?? false,
49
+ ...options.output ? { output: options.output } : {}
50
+ })
51
+ );
52
+ }
53
+ );
54
+ program.command("install-skill").description("\u5B89\u88C5\u53EF\u9009\u7F16\u8F91\u5668\u9002\u914D\u5668\uFF1B\u5F53\u524D\u652F\u6301 Cursor").requiredOption("--editor <name>", "\u7F16\u8F91\u5668\u540D\u79F0\uFF1B\u5F53\u524D\u4E3A cursor").option("--target <path>", "\u81EA\u5B9A\u4E49 Skill \u5B89\u88C5\u76EE\u5F55").option("--force", "\u8986\u76D6\u5DF2\u5B58\u5728\u7684 Skill").action(
55
+ async (options) => print(
56
+ await installEditorSkill({
57
+ editor: options.editor,
58
+ force: options.force ?? false,
59
+ ...options.target ? { target: options.target } : {}
60
+ })
61
+ )
62
+ );
63
+ withCommonOptions(
64
+ program.command("plan").description("\u6821\u9A8C\u8F93\u5165\u5E76\u8F93\u51FA\u6267\u884C\u8BA1\u5212")
65
+ ).action(async (options) => print(await plan(options.repo, options.config)));
66
+ withCommonOptions(
67
+ program.command("scan").description("\u53D1\u73B0\u914D\u7F6E\u6765\u6E90\u5E76\u8BA1\u7B97\u5185\u5BB9\u6307\u7EB9")
68
+ ).action(async (options) => {
69
+ const config = await loadConfig(options.config);
70
+ print(await scan(options.repo, config));
71
+ });
72
+ withCommonOptions(
73
+ program.command("prepare").description("\u8F93\u51FA\u901A\u8FC7 schema \u7684\u8D44\u4EA7\uFF0C\u4E0D\u5199\u5165\u76EE\u6807\u4ED3\u5E93")
74
+ ).action(async (options) => {
75
+ const prepared = await inspectPipeline(options.repo, options.config);
76
+ print(prepared.assets);
77
+ });
78
+ program.command("validate").description("\u6821\u9A8C\u8865\u5145\u540E\u7684\u56DB\u7EF4\u8D44\u4EA7 JSON").requiredOption("--input <path>", "\u7531 prepare \u751F\u6210\u5E76\u8865\u5145\u7684 JSON \u6570\u7EC4").action(
79
+ async (options) => print({ valid: true, count: (await loadAssetsFile(options.input)).length })
80
+ );
81
+ withCommonOptions(
82
+ program.command("render").description("\u6267\u884C\u5B8C\u6574\u7BA1\u7EBF\u5E76\u6E32\u67D3\u6587\u6863").option("--assets <path>", "\u5DF2\u6821\u9A8C\u7684\u8865\u5145\u8D44\u4EA7 JSON")
83
+ ).action(
84
+ async (options) => print(await runPipeline(options.repo, options.config, options.assets))
85
+ );
86
+ program.command("verify").description("\u9A8C\u8BC1\u5DE5\u4F5C\u6811\u6539\u52A8\u4EC5\u4F4D\u4E8E docs/\u53EF\u8BFB\u5316").requiredOption("--repo <path>", "\u76EE\u6807 Git \u4ED3\u5E93").option("--config <path>", "\u540C\u65F6\u8BC1\u660E\u65E0\u53D8\u5316\u4E8C\u6B21\u8FD0\u884C").action(async (options) => {
87
+ if (options.config) {
88
+ print(await verifySecondRun(options.repo, options.config));
89
+ return;
90
+ }
91
+ print({ valid: true, changedFiles: await verifyGitScope(options.repo) });
92
+ });
93
+ withCommonOptions(
94
+ program.command("finalize").description("\u6267\u884C\u3001\u9A8C\u8BC1\u5E76\u8F93\u51FA\u6700\u7EC8\u7ED3\u679C").option("--assets <path>", "\u5DF2\u6821\u9A8C\u7684\u8865\u5145\u8D44\u4EA7 JSON")
95
+ ).action(
96
+ async (options) => print(await runPipeline(options.repo, options.config, options.assets))
97
+ );
98
+ withCommonOptions(
99
+ program.command("run").description("finalize \u7684\u522B\u540D").option("--assets <path>", "\u5DF2\u6821\u9A8C\u7684\u8865\u5145\u8D44\u4EA7 JSON")
100
+ ).action(
101
+ async (options) => print(await runPipeline(options.repo, options.config, options.assets))
102
+ );
103
+ await program.parseAsync(process.argv);
104
+ }
105
+ main().catch((error) => {
106
+ const message = error instanceof Error ? error.message : String(error);
107
+ process.stderr.write(`asset-compound\uFF1A${message}
108
+ `);
109
+ process.exitCode = 1;
110
+ });
111
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport {\n inspectPipeline,\n loadAssetsFile,\n loadConfig,\n plan,\n runPipeline,\n scan,\n verifyGitScope,\n verifySecondRun,\n} from \"./pipeline.js\";\nimport { initGenericWorkspace, installEditorSkill } from \"./setup.js\";\n\ninterface CommonOptions {\n repo: string;\n config: string;\n assets?: string;\n}\n\nfunction print(value: unknown): void {\n process.stdout.write(`${JSON.stringify(value, null, 2)}\\n`);\n}\n\nfunction withCommonOptions(command: Command): Command {\n return command\n .requiredOption(\"--repo <path>\", \"目标 Git 仓库\")\n .requiredOption(\"--config <path>\", \"YAML 运行配置\");\n}\n\nasync function main(): Promise<void> {\n const titleMap: Record<string, string> = {\n \"Usage:\": \"用法:\",\n \"Arguments:\": \"参数:\",\n \"Options:\": \"选项:\",\n \"Global Options:\": \"全局选项:\",\n \"Commands:\": \"命令:\",\n };\n const program = new Command()\n .name(\"asset-compound\")\n .description(\"在 docs/可读化 下生成可增量、可追溯的资产\")\n .usage(\"[选项] <命令>\")\n .version(\"0.1.1\", \"-V, --version\", \"显示版本\")\n .helpOption(\"-h, --help\", \"显示帮助\")\n .addHelpCommand(\"help [command]\", \"显示指定命令的帮助\")\n .showHelpAfterError(\"(使用 --help 查看帮助)\")\n .configureHelp({\n styleTitle: (title) => titleMap[title] ?? title,\n subcommandTerm: (command) =>\n command.name() === \"help\" ? \"help [命令]\" : `${command.name()} [选项]`,\n })\n .configureOutput({\n outputError: (text, write) =>\n write(\n text\n .replace(/^error:/gm, \"错误:\")\n .replace(/required option '([^']+)' not specified/g, \"缺少必填选项 '$1'\")\n .replace(/unknown command '([^']+)'/g, \"未知命令 '$1'\")\n .replace(/unknown option '([^']+)'/g, \"未知选项 '$1'\"),\n ),\n });\n\n program\n .command(\"init\")\n .description(\"初始化编辑器无关的配置、中文提示协议和 schema\")\n .option(\"--output <path>\", \"输出目录;默认 ~/.asset-compound\")\n .option(\"--base-branch <name>\", \"目标仓库基线分支\", \"main\")\n .option(\"--mode <mode>\", \"初始化模式;当前支持 generic\", \"generic\")\n .option(\"--force\", \"覆盖已存在的初始化文件\")\n .action(\n async (options: {\n output?: string;\n baseBranch: string;\n mode: string;\n force?: boolean;\n }) => {\n if (options.mode !== \"generic\") {\n throw new Error(`init 当前仅支持 generic 模式;收到 mode=${options.mode}`);\n }\n print(\n await initGenericWorkspace({\n baseBranch: options.baseBranch,\n force: options.force ?? false,\n ...(options.output ? { output: options.output } : {}),\n }),\n );\n },\n );\n\n program\n .command(\"install-skill\")\n .description(\"安装可选编辑器适配器;当前支持 Cursor\")\n .requiredOption(\"--editor <name>\", \"编辑器名称;当前为 cursor\")\n .option(\"--target <path>\", \"自定义 Skill 安装目录\")\n .option(\"--force\", \"覆盖已存在的 Skill\")\n .action(\n async (options: {\n editor: string;\n target?: string;\n force?: boolean;\n }) =>\n print(\n await installEditorSkill({\n editor: options.editor,\n force: options.force ?? false,\n ...(options.target ? { target: options.target } : {}),\n }),\n ),\n );\n\n withCommonOptions(\n program.command(\"plan\").description(\"校验输入并输出执行计划\"),\n ).action(async (options: CommonOptions) => print(await plan(options.repo, options.config)));\n\n withCommonOptions(\n program.command(\"scan\").description(\"发现配置来源并计算内容指纹\"),\n ).action(async (options: CommonOptions) => {\n const config = await loadConfig(options.config);\n print(await scan(options.repo, config));\n });\n\n withCommonOptions(\n program.command(\"prepare\").description(\"输出通过 schema 的资产,不写入目标仓库\"),\n ).action(async (options: CommonOptions) => {\n const prepared = await inspectPipeline(options.repo, options.config);\n print(prepared.assets);\n });\n\n program\n .command(\"validate\")\n .description(\"校验补充后的四维资产 JSON\")\n .requiredOption(\"--input <path>\", \"由 prepare 生成并补充的 JSON 数组\")\n .action(async (options: { input: string }) =>\n print({ valid: true, count: (await loadAssetsFile(options.input)).length }),\n );\n\n withCommonOptions(\n program\n .command(\"render\")\n .description(\"执行完整管线并渲染文档\")\n .option(\"--assets <path>\", \"已校验的补充资产 JSON\"),\n ).action(async (options: CommonOptions) =>\n print(await runPipeline(options.repo, options.config, options.assets)),\n );\n\n program\n .command(\"verify\")\n .description(\"验证工作树改动仅位于 docs/可读化\")\n .requiredOption(\"--repo <path>\", \"目标 Git 仓库\")\n .option(\"--config <path>\", \"同时证明无变化二次运行\")\n .action(async (options: Pick<CommonOptions, \"repo\"> & { config?: string }) => {\n if (options.config) {\n print(await verifySecondRun(options.repo, options.config));\n return;\n }\n print({ valid: true, changedFiles: await verifyGitScope(options.repo) });\n });\n\n withCommonOptions(\n program\n .command(\"finalize\")\n .description(\"执行、验证并输出最终结果\")\n .option(\"--assets <path>\", \"已校验的补充资产 JSON\"),\n ).action(async (options: CommonOptions) =>\n print(await runPipeline(options.repo, options.config, options.assets)),\n );\n\n withCommonOptions(\n program\n .command(\"run\")\n .description(\"finalize 的别名\")\n .option(\"--assets <path>\", \"已校验的补充资产 JSON\"),\n ).action(async (options: CommonOptions) =>\n print(await runPipeline(options.repo, options.config, options.assets)),\n );\n\n await program.parseAsync(process.argv);\n}\n\nmain().catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n process.stderr.write(`asset-compound:${message}\\n`);\n process.exitCode = 1;\n});\n"],"mappings":"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","names":[]}
package/dist/index.js ADDED
@@ -0,0 +1,51 @@
1
+ import {
2
+ assertOutputPath,
3
+ assertValid,
4
+ assetSchema,
5
+ atomicWriteIfChanged,
6
+ git,
7
+ initGenericWorkspace,
8
+ inspectPipeline,
9
+ installEditorSkill,
10
+ loadAssetsFile,
11
+ loadConfig,
12
+ plan,
13
+ prepare,
14
+ redactSensitive,
15
+ render,
16
+ renderAsset,
17
+ runPipeline,
18
+ scan,
19
+ sha256,
20
+ validateAsset,
21
+ validateConfig,
22
+ validateState,
23
+ verifyGitScope,
24
+ verifySecondRun
25
+ } from "./chunk-P2MVWNYS.js";
26
+ export {
27
+ assertOutputPath,
28
+ assertValid,
29
+ assetSchema,
30
+ atomicWriteIfChanged,
31
+ git,
32
+ initGenericWorkspace,
33
+ inspectPipeline,
34
+ installEditorSkill,
35
+ loadAssetsFile,
36
+ loadConfig,
37
+ plan,
38
+ prepare,
39
+ redactSensitive,
40
+ render,
41
+ renderAsset,
42
+ runPipeline,
43
+ scan,
44
+ sha256,
45
+ validateAsset,
46
+ validateConfig,
47
+ validateState,
48
+ verifyGitScope,
49
+ verifySecondRun
50
+ };
51
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,5 @@
1
+ export { assertOutputPath, atomicWriteIfChanged, git, inspectPipeline, loadAssetsFile, loadConfig, plan, prepare, redactSensitive, render, renderAsset, runPipeline, scan, sha256, verifyGitScope, verifySecondRun, } from "./pipeline.js";
2
+ export { assertValid, assetSchema, validateAsset, validateConfig, validateState, } from "./schema.js";
3
+ export { initGenericWorkspace, installEditorSkill, } from "./setup.js";
4
+ export type { AssetRecord, AssetState, ChangeKind, Conflict, DimensionFinding, PipelineResult, ReadState, RunConfig, ScanRecord, SourceSet, SourceState, SourceType, } from "./types.js";
5
+ export type { InitOptions, InstallSkillOptions, } from "./setup.js";
@@ -0,0 +1,34 @@
1
+ import type { AssetRecord, PipelineResult, ReadState, RunConfig, ScanRecord, SourceType } from "./types.js";
2
+ export declare function sha256(value: string | Buffer): string;
3
+ export declare function git(repo: string, args: string[]): Promise<string>;
4
+ export declare function assertOutputPath(repo: string, target: string): Promise<string>;
5
+ export declare function atomicWriteIfChanged(repo: string, relativePath: string, content: string): Promise<boolean>;
6
+ export declare function loadConfig(configPath: string): Promise<RunConfig>;
7
+ export declare function plan(repo: string, configPath: string): Promise<{
8
+ repoRoot: string;
9
+ outputRoot: "docs/可读化";
10
+ sourceTypes: SourceType[];
11
+ baseCommit: string;
12
+ }>;
13
+ export declare function scan(repo: string, config: RunConfig): Promise<ScanRecord[]>;
14
+ export declare function redactSensitive(value: string): string;
15
+ export declare function prepare(records: ScanRecord[], previous: ReadState | null): AssetRecord[];
16
+ export declare function loadAssetsFile(file: string, records?: ScanRecord[]): Promise<AssetRecord[]>;
17
+ export declare function renderAsset(asset: AssetRecord): string;
18
+ export declare function render(repo: string, config: RunConfig, records: ScanRecord[], assets: AssetRecord[], previous: ReadState | null): Promise<PipelineResult>;
19
+ export declare function verifyGitScope(repo: string): Promise<string[]>;
20
+ export declare function runPipeline(repoInput: string, configPath: string, assetsFile?: string): Promise<PipelineResult>;
21
+ export declare function inspectPipeline(repoInput: string, configPath: string): Promise<{
22
+ records: ScanRecord[];
23
+ assets: AssetRecord[];
24
+ }>;
25
+ export declare function verifySecondRun(repoInput: string, configPath: string): Promise<{
26
+ secondRunZeroDiff: boolean;
27
+ counts: {
28
+ new: number;
29
+ updated: number;
30
+ unchanged: number;
31
+ conflicts: number;
32
+ };
33
+ stateCommit: string;
34
+ }>;
@@ -0,0 +1,186 @@
1
+ import { type ValidateFunction } from "ajv/dist/2020.js";
2
+ import type { AssetRecord, ReadState, RunConfig } from "./types.js";
3
+ export declare const assetSchema: {
4
+ readonly $schema: "https://json-schema.org/draft/2020-12/schema";
5
+ readonly type: "object";
6
+ readonly additionalProperties: false;
7
+ readonly required: readonly ["assetId", "sourceType", "sourceRef", "sourceRevision", "contentHash", "title", "summary", "facts", "decisions", "actions", "relations", "analysis", "writebackKind"];
8
+ readonly properties: {
9
+ readonly assetId: {
10
+ readonly type: "string";
11
+ readonly pattern: "^sha256:[a-f0-9]{64}$";
12
+ };
13
+ readonly sourceType: {
14
+ readonly enum: readonly ["requirement", "design", "ai-artifact", "git"];
15
+ };
16
+ readonly sourceRef: {
17
+ readonly type: "string";
18
+ readonly minLength: 1;
19
+ };
20
+ readonly sourceRevision: {
21
+ readonly type: "string";
22
+ readonly minLength: 1;
23
+ };
24
+ readonly contentHash: {
25
+ readonly type: "string";
26
+ readonly pattern: "^sha256:[a-f0-9]{64}$";
27
+ };
28
+ readonly title: {
29
+ readonly type: "string";
30
+ readonly minLength: 1;
31
+ };
32
+ readonly summary: {
33
+ readonly type: "string";
34
+ };
35
+ readonly facts: {
36
+ readonly type: "array";
37
+ readonly items: {
38
+ readonly type: "string";
39
+ };
40
+ };
41
+ readonly decisions: {
42
+ readonly type: "array";
43
+ readonly items: {
44
+ readonly type: "string";
45
+ };
46
+ };
47
+ readonly actions: {
48
+ readonly type: "array";
49
+ readonly items: {
50
+ readonly type: "string";
51
+ };
52
+ };
53
+ readonly relations: {
54
+ readonly type: "array";
55
+ readonly items: {
56
+ readonly type: "string";
57
+ };
58
+ };
59
+ readonly analysis: {
60
+ readonly type: "object";
61
+ readonly additionalProperties: false;
62
+ readonly required: readonly ["completeness", "executability", "consistency", "reuseValue"];
63
+ readonly properties: {
64
+ readonly completeness: {
65
+ readonly type: "object";
66
+ readonly additionalProperties: false;
67
+ readonly required: readonly ["level", "evidence", "gaps", "recommendations"];
68
+ readonly properties: {
69
+ readonly level: {
70
+ readonly enum: readonly ["ready", "partial", "missing", "conflict", "high", "medium", "low"];
71
+ };
72
+ readonly evidence: {
73
+ readonly type: "array";
74
+ readonly items: {
75
+ readonly type: "string";
76
+ };
77
+ };
78
+ readonly gaps: {
79
+ readonly type: "array";
80
+ readonly items: {
81
+ readonly type: "string";
82
+ };
83
+ };
84
+ readonly recommendations: {
85
+ readonly type: "array";
86
+ readonly items: {
87
+ readonly type: "string";
88
+ };
89
+ };
90
+ };
91
+ };
92
+ readonly executability: {
93
+ readonly type: "object";
94
+ readonly additionalProperties: false;
95
+ readonly required: readonly ["level", "evidence", "gaps", "recommendations"];
96
+ readonly properties: {
97
+ readonly level: {
98
+ readonly enum: readonly ["ready", "partial", "missing", "conflict", "high", "medium", "low"];
99
+ };
100
+ readonly evidence: {
101
+ readonly type: "array";
102
+ readonly items: {
103
+ readonly type: "string";
104
+ };
105
+ };
106
+ readonly gaps: {
107
+ readonly type: "array";
108
+ readonly items: {
109
+ readonly type: "string";
110
+ };
111
+ };
112
+ readonly recommendations: {
113
+ readonly type: "array";
114
+ readonly items: {
115
+ readonly type: "string";
116
+ };
117
+ };
118
+ };
119
+ };
120
+ readonly consistency: {
121
+ readonly type: "object";
122
+ readonly additionalProperties: false;
123
+ readonly required: readonly ["level", "evidence", "gaps", "recommendations"];
124
+ readonly properties: {
125
+ readonly level: {
126
+ readonly enum: readonly ["ready", "partial", "missing", "conflict", "high", "medium", "low"];
127
+ };
128
+ readonly evidence: {
129
+ readonly type: "array";
130
+ readonly items: {
131
+ readonly type: "string";
132
+ };
133
+ };
134
+ readonly gaps: {
135
+ readonly type: "array";
136
+ readonly items: {
137
+ readonly type: "string";
138
+ };
139
+ };
140
+ readonly recommendations: {
141
+ readonly type: "array";
142
+ readonly items: {
143
+ readonly type: "string";
144
+ };
145
+ };
146
+ };
147
+ };
148
+ readonly reuseValue: {
149
+ readonly type: "object";
150
+ readonly additionalProperties: false;
151
+ readonly required: readonly ["level", "evidence", "gaps", "recommendations"];
152
+ readonly properties: {
153
+ readonly level: {
154
+ readonly enum: readonly ["ready", "partial", "missing", "conflict", "high", "medium", "low"];
155
+ };
156
+ readonly evidence: {
157
+ readonly type: "array";
158
+ readonly items: {
159
+ readonly type: "string";
160
+ };
161
+ };
162
+ readonly gaps: {
163
+ readonly type: "array";
164
+ readonly items: {
165
+ readonly type: "string";
166
+ };
167
+ };
168
+ readonly recommendations: {
169
+ readonly type: "array";
170
+ readonly items: {
171
+ readonly type: "string";
172
+ };
173
+ };
174
+ };
175
+ };
176
+ };
177
+ };
178
+ readonly writebackKind: {
179
+ readonly enum: readonly ["新增", "增量", "未变"];
180
+ };
181
+ };
182
+ };
183
+ export declare const validateAsset: ValidateFunction<AssetRecord>;
184
+ export declare const validateConfig: ValidateFunction<RunConfig>;
185
+ export declare const validateState: ValidateFunction<ReadState>;
186
+ export declare function assertValid<T>(validator: ValidateFunction<T>, value: unknown, label: string): asserts value is T;
@@ -0,0 +1,25 @@
1
+ export interface InitOptions {
2
+ output?: string;
3
+ baseBranch?: string;
4
+ force?: boolean;
5
+ }
6
+ export declare function initGenericWorkspace(options?: InitOptions): Promise<{
7
+ readme: string;
8
+ config: string;
9
+ prompt: string;
10
+ protocol: string;
11
+ inputSchema: string;
12
+ outputSchema: string;
13
+ mode: string;
14
+ outputDir: string;
15
+ }>;
16
+ export interface InstallSkillOptions {
17
+ editor: string;
18
+ target?: string;
19
+ force?: boolean;
20
+ }
21
+ export declare function installEditorSkill(options: InstallSkillOptions): Promise<{
22
+ editor: string;
23
+ target: string;
24
+ skillFile: string;
25
+ }>;