首页
/ Understand-Anything /understand-domain 设计解析:从代码中萃取三层业务领域知识图谱

Understand-Anything /understand-domain 设计解析:从代码中萃取三层业务领域知识图谱

2026-09-04 16:32:33作者:申梦珏Efrain

本文基于 Understand-Anything 仓库中的设计规格 2026-04-01-business-domain-knowledge-design.md,系统讲解 /understand-domain 技能的设计动机、领域图数据模型、双路径分析流水线与 Dashboard 渲染方案。读完后,你将理解如何用"领域—流程—步骤"三层抽象把业务逻辑从代码结构中剥离出来,并掌握从预处理脚本、LLM 分析 Agent 到 domain-graph.json 落盘、可视化 drill-down 的完整技术链路。

一、问题与方案:从"结构依赖"走向"业务语义"

设计文档开篇指出了既有知识图谱的局限:文件级依赖关系在 IDE 中本就能看到,当文件数量庞大时,罗列依赖边并不能降低认知负荷——开发者仍然需要在脑中重建"这段代码到底在做什么"。真正缺的是业务领域知识:内嵌在代码里的逻辑与领域概念,而非结构性接线。

对应的解决方案是新增 /understand-domain 技能:从代码库中萃取业务领域知识,并在 Dashboard 中渲染为横向流程图(horizontal flow graph)。提供两种视图模式:高层的 Domain 视图(可用时默认)与既有的 Structural 视图,并通过开关切换。

架构上采用设计文档中的 Approach C:独立文件、共享 Schema(Shared Schema):

  • 领域数据存放在独立文件 domain-graph.json 中,复用同一套 KnowledgeGraph 类型系统,仅扩展新的节点/边类型;
  • Dashboard 同时探测两个文件并提供视图切换;
  • 领域节点可以通过 ID 引用结构节点(structural node),实现下钻。

文档给出了选择独立文件的四个理由:/understand-domain 可以轻量独立运行,也可以与完整图谱并存;共享 Schema 使搜索、校验、过滤对两种图都生效;不会污染结构图谱;每个文件本身都是独立合法的。这一决策在当前仓库中得到了落实——types.tsGraphNode 携带可选的 domainMeta?: DomainMeta 字段,KnowledgeGraph 根结构(nodes/edges/layers/tour)不变,领域图因此可以直接走既有的校验与持久化通道。

二、领域图 Schema:三层层级与新节点、边类型

三层业务层级

  1. Business Domain(顶层)——如 "Purchasing"、"Logistics"、"Warehouse Management";
  2. Business Flow(中层)——如 "Create Order"、"Process Refund";
  3. Business Step(叶子)——如 "Validate input"、"Check inventory"、"Persist order"。

新增节点类型(3 种)

类型 用途 示例
domain 业务领域簇 "Order Management"、"Logistics"
flow 领域内的业务流程 "Create Order"、"Process Refund"
step 流程中的单个步骤 "Validate order input"

types.ts 中,NodeType 现已包含 domain | flow | step(该文件注释标注节点类型共 27 种,其中 3 种属于 domain 类)。

新增边类型

类型 用途
contains_flow domain → flow
flow_step flow → step(通过 weight 字段编码顺序,如 0.1、0.2、…)
cross_domain domain → domain(领域间交互)
implements step → 结构图中的 file/function 节点 ID(跨图引用)

从源码结构看,types.tsEdgeType 中新增的 Domain 类别边为 contains_flow | flow_step | cross_domain 三种;implements 复用的是既有的 Structural 结构边类型,用于把 step 指向结构图中的文件/函数节点,实现跨图 drill-down 引用。

flow_step 的顺序编码在实现中约定为:权重取 0–1 之间单调递增的分数值。domain-analyzer.md 给出了具体规则:对 N 个步骤,第 i 步取 i/N 并四舍五入到一位小数(5 步:0.1、0.2、0.3、0.4、0.5;15 步:0.1、0.1、0.1……,以 round(1/N, 1)、最小 0.1 为步长递增)。

节点结构示例

Domain 节点(携带 domainMeta 中的实体、业务规则、跨领域交互):

// domain node
{
  id: "domain:order-management",
  type: "domain",
  name: "Order Management",
  summary: "Handles the complete order lifecycle...",
  tags: ["e-commerce", "core-business"],
  complexity: "complex",
  domainMeta?: {
    entities: ["Order", "LineItem", "OrderStatus"],
    businessRules: ["Orders require inventory check before confirmation"],
    crossDomainInteractions: ["Triggers Logistics on order confirmed", "Reads from Customer Service for buyer info"]
  }
}

Flow 节点(携带入口点信息):

{
  id: "flow:create-order",
  type: "flow",
  name: "Create Order",
  summary: "Customer submits a new order through the API",
  tags: ["write-path", "api"],
  complexity: "moderate",
  domainMeta?: {
    entryPoint: "POST /api/orders",
    entryType: "http" | "cli" | "event" | "cron" | "manual"
  }
}

Step 节点(叶子节点,直接挂 filePathlineRange 指向代码):

{
  id: "step:create-order:validate-input",
  type: "step",
  name: "Validate order input",
  summary: "Checks request body against order schema, rejects invalid payloads",
  tags: ["validation"],
  complexity: "simple",
  filePath: "src/validators/order-validator.ts",
  lineRange: [12, 45]
}

上述 domainMeta 的字段在 types.ts 中被定义为 DomainMeta 接口:entities?businessRules?crossDomainInteractions?entryPoint?entryType?(枚举 http | cli | event | cron | manual),与设计文档完全一致。

文件输出

领域图保存到项目的数据目录(设计文档写作时为 .understand-anything/domain-graph.json,当前实现中数据目录已演进为优先 .ua/、存在旧目录时兼容 .understand-anything/,见后文持久化部分)下的 domain-graph.json——与 knowledge-graph.json 同构、独立合法。persistence/index.ts 中新增了 DOMAIN_GRAPH_FILE = "domain-graph.json" 常量与 saveDomainGraph() / loadDomainGraph() 两个函数:保存前会做文件路径清洗(sanitiseFilePaths);加载时默认走 validateGraph 校验,校验失败抛出 Invalid domain graph 错误,可通过 options.validate: false 跳过。

三、分析流水线:两条路径,同一输出

Path 1:轻量扫描(无既有图谱时)

File tree scan
    → Static entry point detection (tree-sitter)
        → Route definitions, exported handlers, main(), event listeners, cron decorators
    → Feed to LLM: file tree + detected entry points + sampled file contents
        → LLM outputs: domains, flows, steps, cross-domain interactions
    → Build domain-graph.json

Token 成本约为一次完整 /understand 扫描的 10–20%。其核心思想(在 SKILL.md Phase 2 中表述得更直白)是:预处理脚本不产出领域图,而是产出"原料"(文件树、入口点、exports/imports),让昂贵的 LLM 把精力花在真正的领域分析上,而不是用几十次工具调用去探索代码库——"便宜的 Python 预处理 → 昂贵 LLM 拿到小而干净的输入 → 更少的成本获得更好的结果"。

Path 2:从既有图谱推导

Load knowledge-graph.json
    → Extract: all nodes, edges, layers, summaries, tour
    → Feed to LLM: graph data as structured context
        → LLM outputs: domains, flows, steps, cross-domain interactions
    → Build domain-graph.json

这条路径几乎免费:不需要读任何源文件,LLM 直接基于既有的节点摘要、标签与调用边进行推理。

路径选择:/understand-domain 检查数据目录下 knowledge-graph.json 是否存在——存在走 Path 2,否则走 Path 1。--full 参数可强制走 Path 1(即使图谱存在也重新扫描)。

Agent 结构

新增一个 Agent:domain-analyzer(opus 模型),两条路径都由它处理;大型代码库可按入口点分组分批处理。该 Agent 的完整定义见 agents/domain-analyzer.md,它规定了:

  • 输入二选一:Option A 为 domain-context.json(预处理上下文),Option B 为既有 knowledge-graph.json;
  • 输出 Schema:完整的 KnowledgeGraph JSON,project 段含 name/languages/frameworks/description/analyzedAt/gitCommitHash,layerstour 有意留空(Dashboard 用独立视图渲染领域图,不使用 layers/tour);
  • 规则:flow_step 权重单调递增且限于 0–1;每个 flow 必须经 contains_flow 连到 domain;每个 step 必须经 flow_step 连到 flow;step 的 filePath 相对项目根,无法确定时省略 filePathlineRange;规模建议为 2–6 个领域、每域 2–5 个流程、每流程 3–8 个步骤,小项目可以更少;
  • 硬约束:节点 ID 前缀后必须为 kebab-case(如 domain:order-management 而非 domain:OrderManagement);每个节点必须有非空 summary 和至少一个 tag;complexity 只能取 simple | moderate | complex;禁止重复 ID、自引用边,以及虚构代码库中不存在的领域/流程。

四、预处理脚本:extract-domain-context.py

设计文档将脚本定位为技能附带脚本(bundled with the skill),放在 understand-anything-plugin/skills/understand-domain/ 下(而非用于开发工具的 scripts/),在 LLM Agent 之前运行,输出 .understand-anything/intermediate/domain-context.json。实际实现 extract-domain-context.py 的调用方式为 python extract-domain-context.py <project-root>,输出到数据目录(.ua/ 或遗留 .understand-anything/)的 intermediate/domain-context.json

关键配置参数

脚本头部定义了一组控制上下文规模的常量,这是"控制 token 成本"的核心手段:

常量 默认值 作用
MAX_FILE_TREE_DEPTH 6 文件树最大扫描深度
MAX_FILES_PER_DIR 50 每目录最多文件数
MAX_FILES_TOTAL 5000 文件树总量上限
MAX_SAMPLED_FILES 40 提取签名的采样文件数上限
MAX_LINES_PER_FILE 80 每文件签名提取的起始行数
MAX_ENTRY_POINTS 200 入口点数量上限
MAX_OUTPUT_BYTES 512 KB 输出文件体积上限,保证落在 Agent 上下文限制内

入口点检测模式

脚本内置 ENTRY_POINT_PATTERNS 正则表,覆盖六类入口(与设计文档"route decorators、app.get/postmain()、event listeners"等描述对应并实际扩展):

  • http:Express/Koa 路由(app|router|server.get/post/...('/...'))、Flask/FastAPI/NestJS 装饰器路由(@route/@get/@PostMapping 等)、Next.js/Remix 路由处理函数(export async function GET/POST/...);
  • cli:.command('name')(commander 风格)、add_parser('name')(argparse);
  • event:.on('event') 监听器、@EventHandler/@Subscribe/@Listener 装饰器;
  • cron:@Cron('@...')@Schedule(...)、crontab 等;
  • http(GraphQL/gRPC):@Query("...") 等 resolver、.proto 中的 service Xxx {;
  • manual:导出的处理函数(export (async )?function (handle*|process*|on*))。

每个命中项记录 filelinetypedescriptionmatch(截断至 120 字符)与 snippet(签名 + 后几行,截断至 300 字符),落实了设计文档"代码片段保持简短(签名 + 前几行,而非完整函数体)"的要求。

文件签名与元数据

extract_file_signatures() 按"业务逻辑优先"策略采样:文件名中包含 controllerservicehandlerroutermodelrepositoryusecaseeventmiddlewareworkflowjob 等关键词的文件得分更高,被优先提取 exports/imports(分别取前 20 个)与不超过 500 字符的 preview。extract_metadata() 读取 package.jsonCargo.tomlgo.modpyproject.tomlpom.xmlREADME 等元数据文件,截取关键片段,让 LLM 理解项目的业务定位。

体积控制:渐进式裁剪

_truncate_to_fit() 实现四级渐进裁剪,确保输出不超过 512 KB:① 文件树截断到前 200 项;② 签名 preview 截断到 200 字符;③ 入口点 snippet 截断到 100 字符;④ 签名列表缩到 20 个、入口点缩到 100 个。

领域上下文输出结构

设计文档规定的 domain-context.json 结构(文件树、入口点、文件签名)如下:

{
  "fileTree": ["src/api/orders.ts", "src/services/...", "..."],
  "entryPoints": [
    {
      "file": "src/api/orders.ts",
      "type": "http",
      "method": "POST",
      "path": "/api/orders",
      "handler": "createOrder",
      "lineRange": [15, 45],
      "snippet": "async function createOrder(req, res) { ... }"
    }
  ],
  "fileSignatures": {
    "src/services/order-service.ts": {
      "exports": ["createOrder", "cancelOrder", "getOrderById"],
      "imports": ["inventory-service", "pricing-service", "order-repo"],
      "summary": null
    }
  }
}

实际实现中该结构还包含 projectRootfileCountmetadata 段,并且脚本明确不依赖重型库(仅标准库 rejsonpathlib),自行解析 .gitignore 为正则模式、跳过 node_modules/.git/dist 等目录、跳过符号链接以避免死循环——对应设计文档"Walk the file tree (respecting .gitignore)"的要求。

五、技能集成与执行流程

SKILL.md 将设计文档的 7 步执行流细化为 Phase 0–6,并补充了若干实战工程细节:

  1. Phase 0:解析 PROJECT_ROOT$UA_DIR——含 worktree 重定向:若当前目录是 git worktree(通过比较 git rev-parse --git-dir--git-common-dir 判断),输出会重定向到主仓库根,避免 worktree 会话结束时数据目录被销毁(issue #133);数据目录优先保留遗留 .understand-anything/,否则使用 .ua/。同时解析 PLUGIN_ROOT(依次尝试 CLAUDE_PLUGIN_ROOT~/.understand-anything-plugin、符号链接解析、codex/opencode/pi 的克隆安装路径),用于定位 Agent 定义文件。
  2. Phase 1:检测既有图谱——若 knowledge-graph.json 存在且未传 --full,先做新鲜度检查:读取图谱元数据中的 project.gitCommitHash,与 HEAD 做项目作用域的 diff(必须带 -- . pathspec,避免 monorepo 中相邻项目的变更误报过期;哈希不一致但项目 diff 为空不算过期),有变更则提示先运行 /understand 刷新图谱。
  3. Phase 2:轻量扫描(Path 1)——运行 python ./extract-domain-context.py "$PROJECT_ROOT",产出 domain-context.json
  4. Phase 3:从图谱推导(Path 2)——读取 knowledge-graph.json,把节点(类型/名称/摘要/标签)、边(尤其 calls/imports/contains)、层描述与 tour 步骤整理为结构化上下文,无需读源文件。
  5. Phase 4:领域分析——读取 $PLUGIN_ROOT/agents/domain-analyzer.md,派发 subagent,输出写到 intermediate/domain-analysis.json
  6. Phase 5:校验与保存——走标准图谱校验流水线(schema 已支持 domain/flow/step);校验失败时记录警告但保存有效部分(错误容忍);保存到 domain-graph.json,清理两个 intermediate 文件。
  7. Phase 6:自动触发 /understand-dashboard——Dashboard 检测到 domain-graph.json 后默认展示 Domain 视图。

六、Dashboard:Domain 视图

视图切换

  • 左上角胶囊开关:"Domain" / "Structural";
  • domain-graph.json 存在时 Domain 视图为默认;
  • 只存在一个图文件时不显示切换开关;
  • 切换视图时保留侧边栏状态。

App.tsx 中,store 同时持有 graphdomainGraphviewMode 三个状态,仅当结构图与领域图同时存在时才渲染切换开关,与设计文档"only one graph file exists, no toggle shown"一致。

横向流程布局

设计文档规定:布局引擎为 Dagre(rankdir: "LR",从左到右);缩放行为分三层——缩小看整个领域簇(圆角大矩形,簇间为 cross_domain 边);点击领域展开为横向"泳道"展示 flows;点击 flow 展示从左到右的 step 逐步追踪。

实现上,DomainGraphView.tsx 保留了这一从左到右的方向语义:组件先同步构建节点/边,再异步执行布局;源码注释明确写着"DomainGraphView used dagre LR; preserve that direction with ELK",即以 ELK 布局引擎的 "elk.direction": "RIGHT" 承接原 Dagre LR 方案。布局问题会通过 store 汇入 WarningBanner 提示;无领域图时给出引导文案"Run /understand-domain to generate one"。

领域簇与流程追踪渲染

领域簇卡片(设计文档示意):

┌─────────────────────────────────────┐
│  Order Management                   │
│  "Handles the complete order..."    │
│                                     │
│  Entities: Order, LineItem, Status  │
│  Flows: Create Order, Cancel Order  │
│  Rules: "Requires inventory check"  │
└─────────────────────────────────────┘
          ──cross_domain──→  [Logistics]
  • 领域簇使用金色/琥珀色描边(与既有主题一致),簇面上展示 summary、实体列表、流程数量与规则摘要;
  • 跨领域边为粗虚线并带标签

流程追踪渲染:

POST /api/orders
  ┌──────────┐    ┌──────────────┐    ┌───────────┐    ┌──────────┐    ┌────────────┐
  │ Validate  │───→│ Check        │───→│ Calculate  │───→│ Persist   │───→│ Send       │
  │ Input     │    │ Inventory    │    │ Pricing    │    │ Order     │    │ Confirm    │
  └──────────┘    └──────────────┘    └───────────┘    └──────────┘    └────────────┘
  • step 由 flow_step 边按 weight 排序、自左向右连接;
  • 左侧显示入口点标签作为流程触发器;
  • 点击 step 后侧边栏显示详情并链接到结构视图。

侧边栏适配与 Drill-Down

  • 选中 domain:显示 summary、业务规则、实体、跨域交互、可点击的 flow 列表;
  • 选中 flow:显示入口点信息、按序步骤列表、复杂度;
  • 选中 step:显示描述、"View in code" 链接(切换到结构视图并导航到对应文件/函数)、上一步/下一步链接;
  • 跨视图下钻:当 step 存在指向结构节点 ID 的 implements 边时,侧边栏出现 "View implementation" 按钮,点击后切换到结构视图并定位该节点;面包屑形如 Domain: Order Management > Flow: Create Order > Step: Validate Input → [structural view]

NodeInfo.tsx 中同样按 viewModedomainGraph 分支渲染领域侧边栏,CodeViewer 在 domain 模式下切换活动图为 domainGraph,均与上述设计对齐。

七、错误容忍与归一化别名

流水线级容错

阶段 错误处理
预处理脚本 单文件解析失败则跳过并继续,记录被跳过文件;入口点检测为尽力而为(best-effort)
LLM 输出解析 与既有 parseTourGenerationResponse() 同策略——从 markdown 中提取 JSON,处理部分响应
Schema 校验 复用既有自动修复流水线:sanitize → normalize(别名)→ apply defaults → validate;丢弃损坏的节点/边,不让整图失败
跨图引用 implements 边指向不存在的结构节点 ID 时保留边并标记 unresolved;Dashboard 渲染该 step 但不提供下钻链接

领域专属校验规则

  • 没有 flow 的 domain:告警但保留(summary/entities 仍有价值);
  • 没有 step 的 flow:告警但保留(入口点信息仍有价值);
  • step 顺序损坏:weight 缺失/重复时按数组位置重新编号;
  • 孤儿 step:未连接任何 flow 的 step 挂到合成的 "Uncategorized" flow;
  • 重复 domain:按名称相似度模糊匹配合并,flows 合并;
  • 空的领域图:Dashboard 显示错误横幅——"Domain extraction failed — try running /understand first for richer context, then /understand-domain"。

Dashboard 韧性

  • domain 节点缺少 domainMeta 时,侧边栏仅展示 summary/tags;
  • domain-graph.json 整体校验失败时,回退到结构视图并显示警告横幅;
  • 部分有效的图谱渲染其有效部分。

归一化别名与实现差异

设计文档给出了节点与边类型的别名映射(LLM 可能输出同义词,校验流水线将其归一):

// Node type aliases
"business_domain""domain"
"process""flow"
"workflow""flow"
"action""step"
"task""step"

// Edge type aliases
"has_flow""contains_flow"
"next_step""flow_step"
"interacts_with""cross_domain"
"implemented_by""implements"

对照 schema.ts 中的实现表,可以观察到两处有意偏离设计文档的收紧:

  1. 节点别名实际为 business_domain → domainbusiness_flow / business_process → flowtask / business_step → step,而 process刻意排除——源码注释说明其"与操作系统/Node.js 的 process 概念歧义";workflowaction 也未收录,降低了误归一风险;
  2. 边别名收录了 has_flownext_stepinteracts_with,但 implemented_by 没有被映射到 implements——注释指出该别名会反转边的方向,LLM 应直接使用 implements 并保证 source/target 正确。

这些细节说明别名表的最终取舍比设计稿更保守:宁可让未知类型走"丢弃损坏节点"的容错路径,也不做可能引入错误方向关系的激进映射。

八、变更地图

设计文档列出的改动面与实际仓库落点对应如下:

领域 变更 仓库对应
packages/core/src/types.ts 新增 3 种节点类型、域边类型、domainMeta 可选字段 types.ts:DomainMeta 接口与 GraphNode.domainMeta
packages/core/src/schema.ts 扩展 Zod schema 与新类型别名 schema.ts:节点/边别名表及 DomainMeta 校验
packages/core/src/persistence/ 新增 loadDomainGraph() / saveDomainGraph() persistence/index.ts
skills/understand-domain/extract-domain-context.py 新预处理脚本(随技能打包) extract-domain-context.py
agents/domain-analyzer.md 新 Agent 定义 domain-analyzer.md
skills/understand-domain.md 新技能定义 SKILL.md(含 --full 参数)
packages/dashboard/src/store.ts 新增 domainGraphviewMode 状态 已在 App.tsx 等处消费
packages/dashboard/src/components/ 新增 DomainGraphView.tsxDomainClusterNode.tsxStepNode.tsx 等;修改 App.tsxNodeInfo.tsxFilterPanel.tsx DomainGraphView.tsxDomainClusterNode.tsxStepNode.tsx 均已存在
packages/dashboard/src/utils/ 新增领域横向布局工具 布局能力现由共享的 ELK 工具(如 elk-layout.ts)承担,方向参数保持 LR

九、小结

/understand-domain 的设计可以用三句话概括:

  1. 数据层——用"domain → flow → step"三层节点与 contains_flow / flow_step / cross_domain" / 跨图 implements引用,把业务语义叠加在既有KnowledgeGraph类型系统之上,并以独立的domain-graph.json` 文件落盘,与结构图谱互不污染;
  2. 流水线层——"Python 廉价预处理 + opus 领域分析 Agent"的组合,把 LLM 输入压缩到 512 KB 以内的干净上下文;有图谱时直接从图谱推导,把 token 成本压到最低;
  3. 体验层——Dashboard 的 Domain/Structural 双视图、左侧到右的流程泳道、以及 step → 代码位置的 drill-down,让"代码在做什么"这一问题从结构依赖图中被真正回答。

值得注意的是,从设计稿到落地,几处工程决策(数据目录 .ua/ 迁移与兼容、worktree 重定向、图谱新鲜度检查、别名表收紧、Dagre → ELK 布局迁移)都体现了同一原则:领域图谱必须像结构图谱一样,能在真实项目的混乱环境(遗留目录、worktree、monorepo、LLM 不稳定输出)下可靠地跑通并优雅降级。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
docsdocs
暂无描述
Markdown
889
5.78 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384
flutter_flutterflutter_flutter
本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本,由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用,3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。
Dart
1.17 K
341