LikeC4 与 LeanIX 桥接与 Draw.io 往返导出:leanix-bridge、leanix 导出 Profile 与 Agent 边界实践指南
【免费下载链接】likec4Visualize, collaborate, and evolve the software architecture with always actual and live diagrams from your code项目地址: https://gitcode.com/GitHub_Trending/li/likec4
本指南聚焦 LikeC4 生态中的 LeanIX 集成场景:如何以 LikeC4 DSL 为唯一权威源(canonical source of truth),通过likec4 gen leanix/likec4 sync leanix生成并同步 LeanIX 形态的库存制品,如何用--profile leanix导出携带桥接元数据的 Draw.io 图并在导出/解析/同步之间完成身份往返(round-trip),以及 MCP 与 CLI 桥接工具之间应有的边界。读完本文,你将掌握从 LikeC4 模型到 LeanIX 事实表(fact sheet)与关系(relation)的完整工作流,并能正确区分「查询类」MCP 工具与「写入类」CLI 桥接命令的职责。
本指南以仓库中的 bridge-leanix-drawio.md 参考文档为主体骨架,并以其实现包 @likec4/leanix-bridge 与 Draw.io 生成器 的源码作为底层佐证。建议先阅读 CLI 参考 熟悉命令体系。
1. 权威源与职责边界(Canonical source of truth)
与 LeanIX、Draw.io 相关的任务,首先要确立一条铁律:LikeC4 DSL(.c4/.likec4)是唯一权威源。桥接(bridge)所做的一切——生成 LeanIX 形态的库存、为 Draw.io 图添加注解——都是从已解析的 LikeC4 语义模型(resolved model)派生的,而非反向让 LeanIX 或 Draw.io 成为事实来源。
对应到实现层,@likec4/leanix-bridge包在 contracts.ts 中明确声明了这一点:外部 ID 是「按 Provider 隔离」的(external?: Partial<Record<Provider, ProviderExternalIds>>),即 LeanIX 的factSheetId只是 LikeC4 实体的一个外部注解,语义锚点始终是 LikeC4 的 FQN。
在此基础上,Agent Skill 的边界同样清晰:本仓库的 likec4-dsl skill 及其参考文档负责传授 DSL 语法与 CLI 契约,但它不代替运行命令本身。涉及实际产出的操作,必须执行:
likec4 gen leanix …likec4 sync leanix …likec4 export drawio --profile leanix
换言之:Skill 是「教你怎么用」,CLI 是「真正干活」。
2. 一级 CLI 命令:从 dry-run 到 Live Sync
以下命令需在项目根目录执行,完整细节可查阅 @likec4/leanix-bridge 的 README。命令的四个典型目标是:
| 目标 | 命令 |
|---|---|
| Manifest + dry-run + 报告 | likec4 gen leanix dry-run -o out/bridge |
| 同步工作流(dry-run / 计划) | likec4 sync leanix --dry-run -o out/bridge |
| 将同步应用到 LeanIX API | likec4 sync leanix --apply -o out/bridge(需要LEANIX_API_TOKEN) |
| 导出带桥接管理单元的 Draw.io 图 | likec4 export drawio --profile leanix -o ./diagrams |
dry-run 阶段(纯本地、无网络):likec4 gen leanix dry-run一次性产出三类制品到out/bridge:
manifest.json—— 身份清单(canonical ID + 占位外部 ID);leanix-dry-run.json—— LeanIX 形态的库存(事实表 + 关系,无真实 ID);report.json—— 汇总报告(各类数量与制品名)。
同步阶段(涉及 LeanIX API):
likec4 sync leanix --dry-run除了写出制品,还会在设置了LEANIX_API_TOKEN时只读查询LeanIX,产出一个sync-plan.json,描述「将创建 vs 将更新」的每一项,供你在真正推送前审查;likec4 sync leanix --apply才会真实调用 LeanIX API 创建/更新事实表与关系,要求环境变量LEANIX_API_TOKEN存在。
Phase 2 入站(inbound,只读):如需从 LeanIX 拉取快照并与模型对账,可用:
# 只读抓取 LeanIX 库存快照到 out/bridge likec4 gen leanix inventory -o out/bridge # 在 manifest 与 LeanIX 库存之间执行对账,输出到 out/bridge likec4 gen leanix reconcile -o out/bridgeDraw.io 导出:使用 LeanIX profile 导出时,顶点与边会携带likec4Id、likec4ViewId、likec4RelationId与bridgeManaged等属性,为后续同步与往返解析提供稳定身份(详见第 4 节)。
补充说明:Phase 2(库存快照、对账)与 Phase 3(影响分析、漂移检测、ADR 生成、治理检查)均在
@likec4/leanix-bridge的范围内,但「AI 特性」与「新的顶层 CLI 命名空间」不在其范围内——这是该包 README 的 Scope 声明 明确划定的边界。
3. 映射配置:YAML / JSON 与默认映射
LeanIX 的事实表类型、关系类型是按工作区元模型(meta-model)而异的,不存在普适分类法,因此桥接提供可配置的映射,并给出保守的安全默认值。
3.1 配置项
自定义 LeanIX 映射(YAML 或 JSON)在默认映射之上合并(merge over defaults),支持三个顶层键,对应 mapping.ts 中的LeanixMappingConfig:
| 配置键 | 作用 | 默认值(DEFAULT_LEANIX_MAPPING) |
|---|---|---|
factSheetTypes | LikeC4 元素 kind → LeanIX 事实表类型 | system → Application、container → ITComponent、component → ITComponent、actor → Provider |
relationTypes | LikeC4 关系 kind → LeanIX 关系类型名 | default → "depends on" |
metadataToFields | LikeC4 标签 / 元数据键 → LeanIX 字段名 | title → name、description → description、technology → technology |
当某个 kind 未命中时,会沿「精确 kind →default→ 兜底常量」的优先级回退:事实表兜底为Application(FALLBACK_FACT_SHEET_TYPE),关系兜底为depends on(FALLBACK_RELATION_TYPE)。actor类型默认映射到Provider,除非被显式覆盖。
3.2 严格校验:坏形状会被拒绝
映射配置在通过mergeWithDefault/ 校验归一化时,非法形状会抛出带明确信息的错误(见 mapping.ts 的parseLeanixMappingInput):
- 顶层键只能是
factSheetTypes、relationTypes、metadataToFields之一,出现未知键会报错:LeanIX mapping has unknown key "…". Allowed: factSheetTypes, relationTypes, metadataToFields; - 每个键的值必须是「字符串键 → 字符串值」的普通对象;数组会被拒绝(
isPlainObjectRecordOfStrings会检查Array.isArray(value)),非字符串值同样报错; - 传入
null/undefined视为「未提供」,直接返回,走默认映射。
合并语义是浅合并(shallow merge):mergeWithDefault先拷贝默认值,再用用户配置逐键覆盖,因此你只需声明需要偏离默认的部分。
4. Draw.io 导出 Profile 与往返(Round-trip)心智模型
4.1 default profile vs leanix profile
Draw.io 生成器(generate-drawio.ts)支持两种导出 profile,由GenerateDrawioOptions.profile控制:
- 默认 profile(
default):style 中不包含bridgeManaged/likec4Id等桥接字段; - LeanIX profile(
leanix):为往返与 LeanIX 对齐追加桥接元数据。
按源码中buildBridgeManagedStyleForNode与buildBridgeManagedStyleForEdge的实现(generate-drawio.ts),leanix profile 的 style 字段如下:
| 元素 | 写入的 style 字段 |
|---|---|
| 顶点(vertex) | bridgeManaged=true、likec4Id、likec4Kind、likec4ViewId,可选likec4ProjectId;当提供了 kind → 事实表类型映射时,还会写入leanixFactSheetType |
| 边(edge) | bridgeManaged=true、likec4RelationId |
| 根单元(root cell) | bridgeManaged=true、likec4ViewId、可选likec4ProjectId |
同时,无论哪种 profile,节点与边都会写入一组likec4*往返字段(如likec4Description、likec4Technology、likec4Notes、likec4Tags、likec4NavigateTo、likec4Icon、likec4Summary、likec4Border、likec4Opacity、likec4StrokeColor、likec4RelationshipKind、likec4Metadata等),用于把 DSL 属性完整编码进 Draw.io style,保证「图即是数据」。
导出的相关实用旗标:
--roundtrip:将布局信息以注释形式嵌入 DSL 中;--all-in-one:多视图合并导出;--uncompressed:输出未压缩的原始 XML(默认是base64(deflateRaw(encodeURIComponent(xml)))压缩格式,Draw.io 两种都接受)。
4.2 往返闭环
官方参考文档给出的心智模型是三步闭环,其每一环都有源码支撑:
- 导出:用
likec4 export drawio --profile leanix导出,使单元格携带稳定的 LikeC4 身份; - 解析回 DSL:用 Draw.io 解析器(
packages/generators的 Draw.io 模块,见 generate-drawio.spec.ts 与 parse-drawio.spec.ts 的测试)将图解析回 DSL:解析器支持的地方,顶点上的likec4Id与边上的likec4RelationId保留了 FQN 与关系身份; - 同步后映射:LeanIX 同步完成后,
manifestToDrawioLeanixMapping(manifest)把likec4Id与 LeanIX 事实表 / 关系 ID 对应起来,供重新导出或工具链消费。
manifestToDrawioLeanixMapping的实现在 drawio-leanix-roundtrip.ts:它返回{ likec4IdToLeanixId, relationKeyToLeanixRelationId }两个映射——前者从 manifest 实体中取external.leanix.factSheetId ?? external.leanix.externalId,后者以关系的复合键(sourceFqn|targetFqn|relationId)为键取external.leanix.relationId。配套的 drawio-leanix-roundtrip.spec.ts 覆盖了该映射的构建逻辑。
重要约束:不要臆造 bridge JSON 的形状。所有制品要么通过 CLI 生成,要么通过@likec4/leanix-bridge的公开 API 生成,具体契约以包 README 为准。
5. 程序化使用:@likec4/leanix-bridge API
除了 CLI,桥接能力也可以直接以 TypeScript 方式接入 LikeC4 配置或自定义脚本。包 index.ts 导出了完整 API。
5.1 自定义 Generator(替代方案)
在 likec4.config.ts 中注册自定义 generator,用桥接函数产出三类制品:
// likec4.config.ts import { defineConfig } from '@likec4/config' import { buildBridgeReport, toBridgeManifest, toLeanixInventoryDryRun, } from '@likec4/leanix-bridge' export default defineConfig({ name: 'my-project', generators: { 'my-leanix': async ({ likec4model, ctx }) => { const manifest = toBridgeManifest(likec4model, { mappingProfile: 'default' }) const dryRun = toLeanixInventoryDryRun(likec4model, { mappingProfile: 'default' }) const report = buildBridgeReport(manifest, dryRun) await ctx.write({ path: ['out', 'bridge', 'manifest.json'], content: JSON.stringify(manifest, null, 2) }) await ctx.write({ path: ['out', 'bridge', 'leanix-dry-run.json'], content: JSON.stringify(dryRun, null, 2) }) await ctx.write({ path: ['out', 'bridge', 'report.json'], content: JSON.stringify(report, null, 2) }) }, }, })随后运行likec4 gen my-leanix即可。
5.2 同步计划(推送前审查)
planSyncToLeanix只读查询 LeanIX,返回一个描述「将创建 vs 将更新」的同步计划,供人工审查后再执行真正的同步:
import { LeanixApiClient, planSyncToLeanix } from '@likec4/leanix-bridge' const client = new LeanixApiClient({ apiToken: process.env.LEANIX_API_TOKEN!, baseUrl: 'https://app.leanix.net', requestDelayMs: 200, }) const plan = await planSyncToLeanix(dryRun, client, { idempotent: true }) // plan.summary: { factSheetsToCreate, factSheetsToUpdate, relationsToCreate } // plan.factSheetPlans: [{ likec4Id, name, type, action: 'create'|'update', existingFactSheetId? }] // 将 plan 写入 out/bridge/sync-plan.json 审查后再执行同步5.3 同步到 LeanIX API
生成 dry-run 制品(以及可选的同步计划)之后,推送需要 API token:
import { LeanixApiClient, syncToLeanix, manifestToDrawioLeanixMapping } from '@likec4/leanix-bridge' const client = new LeanixApiClient({ apiToken: process.env.LEANIX_API_TOKEN!, baseUrl: 'https://app.leanix.net', requestDelayMs: 200, }) const result = await syncToLeanix(manifest, dryRun, client, { idempotent: true }) // result.manifest 中每个实体带 external.leanix.factSheetId const mapping = manifestToDrawioLeanixMapping(result.manifest) // 使用 mapping.likec4IdToLeanixId 做 Draw.io 往返5.4 底层 API 一览
完整导出(index.ts)包括:
- 制品构建:
toBridgeManifest(model, options?)(身份清单)、toLeanixInventoryDryRun(model, options?)(LeanIX 形态库存)、buildBridgeReport(manifest, leanixDryRun)(汇总报告); - API 客户端:
LeanixApiClient(config)——GraphQL 客户端,带 Bearer 认证与限流(apiToken必填,baseUrl?默认https://app.leanix.net,requestDelayMs?默认 200,见 leanix-api-client.ts); - 同步:
planSyncToLeanix(leanixDryRun, client, options?)、syncToLeanix(manifest, leanixDryRun, client, options?)(返回带external.leanix.factSheetId与关系 ID 的更新后 manifest); - 往返:
manifestToDrawioLeanixMapping(manifest); - Phase 2:
fetchLeanixInventorySnapshot(client, options?)(只读分页快照)、reconcileInventoryWithManifest(snapshot, manifest, options?)(返回 matched / unmatchedInLikec4 / unmatchedInLeanix / ambiguous); - Phase 3:
buildDriftReport(reconciliation)、impactReportFromSyncPlan(plan)、generateAdrFromReconciliation(...)/generateAdrFromDriftReport(...)、runGovernanceChecks(reconciliation, options?); - 类型守卫:
isBridgeManifest(obj)/isLeanixInventorySnapshot(obj),用于校验解析自 CLI 制品文件的 JSON。
5.5 核心契约
manifest 与往返身份遵循以下稳定契约(contracts.ts):
- canonicalId:LikeC4 FQN(如
cloud.backend.api); - viewId:LikeC4 视图 id(如
index、landscape.overview); - relationId + compositeKey:
sourceFqn|targetFqn|relationId,作为关系稳定身份; - manifest 元数据:
manifestVersion(当前为'1.0',见BRIDGE_MANIFEST_VERSION)、generatedAt(ISO 时间戳)、bridgeVersion(与包版本同步)、mappingProfile(default或custom)。
6. MCP 与桥接的边界
很多使用者会混淆 MCP 与 CLI 桥接的职责,参考文档给出了明确划分:
- MCP(
likec4 mcp、@likec4/mcp)暴露的是read / query 类工具——对 LikeC4 工作区模型的元素、视图、关系进行查询。它不替代likec4 gen leanix或likec4 sync leanix; - 凡是涉及LeanIX 制品、Draw.io leanix profile、manifest dry-run的操作,一律走CLI(或程序化的
@likec4/leanix-bridge),如本文第 2、4 节所述。
这一边界的意义在于:查询模型是廉价且只读的,而 LeanIX 同步是对外部系统的写入操作,二者不应混用,避免 Agent 在「只想读模型」时意外触发外部 API 调用。
7. 给 Agent 的实操清单
综合本文,Agent 处理 LeanIX / Draw.io 桥接任务时应遵守:
- 以 LikeC4 DSL 为唯一权威源,所有 LeanIX 形态制品均由已解析模型派生;
- Skill 只教语法与契约,不代替执行命令;产出制品必须运行
likec4 gen leanix …、likec4 sync leanix …、likec4 export drawio --profile leanix; - 先 dry-run 后 apply:用
likec4 gen leanix dry-run与likec4 sync leanix --dry-run审查变更(含只读的 sync plan),确认无误后再--apply; - 导出用 leanix profile并保留
--roundtrip能力,确保likec4Id/likec4RelationId等身份字段写入 style,使图可被解析回 DSL 并与 LeanIX 对齐; - 不要臆造 bridge JSON 形状,一律通过 CLI 或
@likec4/leanix-bridge公开 API 生成; - 映射配置遵循严格校验:仅允许
factSheetTypes/relationTypes/metadataToFields三个顶层键,值为字符串映射对象,非法形状会被mergeWithDefault校验拒绝; - 查询用 MCP,写入用 CLI,不要跨界。
通过以上流程,你可以在不改变 LikeC4 单一事实源的前提下,完成「模型 → LeanIX 库存 → 带桥接元数据的 Draw.io 图 → 解析回 DSL → 同步对齐」的完整闭环,并让 LeanIX 工作区的差异(创建/更新、漂移、影响)始终处于可审查、可回滚的受控状态。
【免费下载链接】likec4Visualize, collaborate, and evolve the software architecture with always actual and live diagrams from your code项目地址: https://gitcode.com/GitHub_Trending/li/likec4
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考