@buaa_smat/hometrans 0.1.13 → 0.1.15

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.
Files changed (88) hide show
  1. package/README.md +194 -136
  2. package/agents/build-fixer.md +38 -48
  3. package/agents/code-reviewer.md +20 -20
  4. package/agents/logic-coder.md +8 -8
  5. package/agents/logic-context-builder.md +5 -5
  6. package/agents/review-fixer.md +16 -16
  7. package/agents/self-test-fixer.md +15 -15
  8. package/agents/self-tester.md +56 -55
  9. package/agents/spec-generator.md +16 -16
  10. package/dist/cli/config-store.js +120 -9
  11. package/dist/cli/config.js +4 -4
  12. package/dist/cli/env-vars.js +129 -0
  13. package/dist/cli/init.js +315 -276
  14. package/dist/cli/uninstall.js +152 -17
  15. package/dist/context/index.js +10 -197
  16. package/env-requirements.json +181 -181
  17. package/package.json +1 -1
  18. package/resource/choose_editor.png +0 -0
  19. package/resource/common_config.png +0 -0
  20. package/resource/integration_test_config.png +0 -0
  21. package/resource/migration_process.svg +94 -0
  22. package/resource/migration_process_transparent.svg +93 -0
  23. package/resource/set_env.png +0 -0
  24. package/resource/ui_align_config.png +0 -0
  25. package/skills/hmos-batch-ui-align/SKILL.md +10 -0
  26. package/skills/hmos-batch-ui-align/references/conversion-procedure.md +180 -180
  27. package/skills/hmos-batch-ui-align/references/mappings/android-to-harmonyOS-ui-atomic-component-mapping-reference.md +2533 -2533
  28. package/skills/hmos-batch-ui-align/references/mappings/android-to-harmonyOS-ui-interaction-mapping-reference.md +555 -555
  29. package/skills/hmos-batch-ui-align/references/mappings/android-to-harmonyOS-ui-layout-mapping-reference.md +117 -117
  30. package/skills/hmos-batch-ui-align/references/mvvm/@Link/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/217/214/345/220/221/345/220/214/346/255/245.md +648 -648
  31. package/skills/hmos-batch-ui-align/references/mvvm/@Observed/350/243/205/351/245/260/345/231/250/345/222/214@ObjectLink/350/243/205/351/245/260/345/231/250/357/274/232/345/265/214/345/245/227/347/261/273/345/257/271/350/261/241/345/261/236/346/200/247/345/217/230/345/214/226.md +2088 -2088
  32. package/skills/hmos-batch-ui-align/references/mvvm/@Prop/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/215/225/345/220/221/345/220/214/346/255/245.md +1033 -1033
  33. package/skills/hmos-batch-ui-align/references/mvvm/@Provide/350/243/205/351/245/260/345/231/250/345/222/214@Consume/350/243/205/351/245/260/345/231/250/357/274/232/344/270/216/345/220/216/344/273/243/347/273/204/344/273/266/345/217/214/345/220/221/345/220/214/346/255/245.md +1183 -1183
  34. package/skills/hmos-batch-ui-align/references/mvvm/@State/350/243/205/351/245/260/345/231/250/357/274/232/347/273/204/344/273/266/345/206/205/347/212/266/346/200/201.md +576 -576
  35. package/skills/hmos-batch-ui-align/references/mvvm/@Track/350/243/205/351/245/260/345/231/250/357/274/232class/345/257/271/350/261/241/345/261/236/346/200/247/347/272/247/346/233/264/346/226/260.md +297 -297
  36. package/skills/hmos-batch-ui-align/references/mvvm/@Watch/350/243/205/351/245/260/345/231/250/357/274/232/347/212/266/346/200/201/345/217/230/351/207/217/346/233/264/346/224/271/351/200/232/347/237/245.md +395 -395
  37. package/skills/hmos-batch-ui-align/references/mvvm/AppStorage/357/274/232/345/272/224/347/224/250/345/205/250/345/261/200/347/232/204UI/347/212/266/346/200/201/345/255/230/345/202/250.md +902 -902
  38. package/skills/hmos-batch-ui-align/references/mvvm/Environment/357/274/232/350/256/276/345/244/207/347/216/257/345/242/203/346/237/245/350/257/242.md +106 -106
  39. package/skills/hmos-batch-ui-align/references/mvvm/LocalStorage/357/274/232/351/241/265/351/235/242/347/272/247UI/347/212/266/346/200/201/345/255/230/345/202/250.md +1178 -1178
  40. package/skills/hmos-batch-ui-align/references/mvvm/MVVM/346/250/241/345/274/217/357/274/210V1/357/274/211.md +911 -911
  41. package/skills/hmos-batch-ui-align/references/mvvm/PersistentStorage/357/274/232/346/214/201/344/271/205/345/214/226/345/255/230/345/202/250UI/347/212/266/346/200/201.md +354 -354
  42. package/skills/hmos-batch-ui-align/references/mvvm//347/256/241/347/220/206/345/272/224/347/224/250/346/213/245/346/234/211/347/232/204/347/212/266/346/200/201/346/246/202/350/277/260.md +11 -11
  43. package/skills/hmos-convert-pipeline/SKILL.md +63 -49
  44. package/skills/hmos-fix-build-errors/SKILL.md +5 -6
  45. package/skills/hmos-fix-build-errors/references/arkts-strict-patterns.md +219 -219
  46. package/skills/hmos-fix-build-errors/references/known-patterns.md +157 -157
  47. package/skills/hmos-fix-build-errors/references/rdb-entity-pattern.md +131 -131
  48. package/skills/hmos-incremental-ui-align/{readme.md → README.md} +28 -21
  49. package/skills/hmos-incremental-ui-align/SKILL.md +46 -27
  50. package/skills/hmos-incremental-ui-align/diff_analysis.md +52 -52
  51. package/skills/hmos-incremental-ui-align/page_align.md +62 -62
  52. package/skills/hmos-incremental-ui-align/references/Comparison_Template.md +2 -2
  53. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Link/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/217/214/345/220/221/345/220/214/346/255/245.md +648 -648
  54. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Observed/350/243/205/351/245/260/345/231/250/345/222/214@ObjectLink/350/243/205/351/245/260/345/231/250/357/274/232/345/265/214/345/245/227/347/261/273/345/257/271/350/261/241/345/261/236/346/200/247/345/217/230/345/214/226.md +2088 -2088
  55. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Prop/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/215/225/345/220/221/345/220/214/346/255/245.md +1033 -1033
  56. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Provide/350/243/205/351/245/260/345/231/250/345/222/214@Consume/350/243/205/351/245/260/345/231/250/357/274/232/344/270/216/345/220/216/344/273/243/347/273/204/344/273/266/345/217/214/345/220/221/345/220/214/346/255/245.md +1183 -1183
  57. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@State/350/243/205/351/245/260/345/231/250/357/274/232/347/273/204/344/273/266/345/206/205/347/212/266/346/200/201.md +576 -576
  58. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Track/350/243/205/351/245/260/345/231/250/357/274/232class/345/257/271/350/261/241/345/261/236/346/200/247/347/272/247/346/233/264/346/226/260.md +297 -297
  59. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Watch/350/243/205/351/245/260/345/231/250/357/274/232/347/212/266/346/200/201/345/217/230/351/207/217/346/233/264/346/224/271/351/200/232/347/237/245.md +395 -395
  60. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/AppStorage/357/274/232/345/272/224/347/224/250/345/205/250/345/261/200/347/232/204UI/347/212/266/346/200/201/345/255/230/345/202/250.md +902 -902
  61. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/Environment/357/274/232/350/256/276/345/244/207/347/216/257/345/242/203/346/237/245/350/257/242.md +106 -106
  62. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/LocalStorage/357/274/232/351/241/265/351/235/242/347/272/247UI/347/212/266/346/200/201/345/255/230/345/202/250.md +1178 -1178
  63. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/MVVM/346/250/241/345/274/217V1.md +911 -911
  64. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/PersistentStorage/357/274/232/346/214/201/344/271/205/345/214/226/345/255/230/345/202/250UI/347/212/266/346/200/201.md +354 -354
  65. package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243//347/256/241/347/220/206/345/272/224/347/224/250/346/213/245/346/234/211/347/232/204/347/212/266/346/200/201/346/246/202/350/277/260.md +11 -11
  66. package/skills/hmos-incremental-ui-align/references/UI_Analysis_Template.md +3 -3
  67. package/skills/hmos-incremental-ui-align/references/android-to-harmonyOS-ui-atomic-component-mapping-reference.md +2533 -2533
  68. package/skills/hmos-incremental-ui-align/references/android-to-harmonyOS-ui-interaction-mapping-reference.md +555 -555
  69. package/skills/hmos-incremental-ui-align/references/android-to-harmonyOS-ui-layout-mapping-reference.md +117 -117
  70. package/skills/hmos-incremental-ui-align/scripts/navigation-capure.md +37 -37
  71. package/skills/hmos-integration-test/{readme.md → README.md} +38 -38
  72. package/skills/hmos-integration-test/SKILL.md +63 -52
  73. package/skills/hmos-resources-convert/SKILL.md +5 -5
  74. package/skills/hmos-resources-convert/references/conversion-rules.md +663 -663
  75. package/skills/hmos-resources-convert/references/dependency-analysis-rules.md +388 -388
  76. package/skills/hmos-resources-convert/references/resource-mapping-rules.md +457 -457
  77. package/skills/hmos-resources-convert/references/xml-drawable-to-svg-rules.md +513 -513
  78. package/skills/hmos-spec-generate/SKILL.md +19 -19
  79. package/skills/hmos-spec-generate/references/android-platform-tokens.md +105 -105
  80. package/skills/hmos-spec-generate/references/spec-sample-1.md +78 -78
  81. package/skills/hmos-spec-generate/references/spec-sample-2.md +58 -58
  82. package/skills/hmos-spec-generate/references/spec-sample-3.md +116 -116
  83. package/skills/hmos-spec-generate/references/step4-report-template.md +33 -33
  84. package/tools/test-tools/autotest/README.md +33 -17
  85. package/tools/test-tools/autotest/self_test_runner.py +109 -15
  86. package/resource/hometrans_config.png +0 -0
  87. package/skills/hmos-incremental-ui-align/config-example.json +0 -11
  88. package/tools/test-tools/autotest/config.yaml.example +0 -58
@@ -1,117 +1,117 @@
1
- # Android-to-HarmonyOS UI Layout Mapping Reference
2
-
3
- <!-- TODO: Fill in the actual UI layout mapping content -->
4
- <!-- This reference maps Android layout containers to HarmonyOS ArkUI layout equivalents -->
5
- <!-- Covers: LinearLayout→Column/Row, FrameLayout→Stack, ConstraintLayout→RelativeContainer, RecyclerView→List+LazyForEach, ScrollView→Scroll, etc. -->
6
-
7
-
8
- ## 布局容器映射
9
-
10
- | 安卓部分UI | 对应鸿蒙部分UI | 其他说明 |
11
- |-----------|---------------|---------|
12
- | `LinearLayout` (vertical) | `Column` 组件 | 纵向线性布局,支持 `.justifyContent()`、`.alignItems()` |
13
- | `LinearLayout` (horizontal) | `Row` 组件 | 横向线性布局 |
14
- | `FrameLayout` | `Stack` 组件 | 层叠布局,支持 `.alignContent()` |
15
- | `RelativeLayout` | `RelativeContainer` 组件 | 相对布局,通过 `.alignRules()` 设置定位规则 |
16
- | `ConstraintLayout` | `RelativeContainer` / 自定义布局 | 约束布局,复杂场景可用自定义 `onMeasureSize`/`onPlaceChildren` |
17
- | `FlexboxLayout` | `Flex` 组件 | 弹性布局,支持 `FlexDirection`/`FlexWrap`/`FlexAlign` 标准 Flexbox |
18
- | `GridLayout` | `Grid` 组件 | 网格布局,通过 `.columnsTemplate('1fr 1fr 1fr')` 定义列 |
19
- | `TableLayout` | `Grid` 组件 | 表格布局,使用 `Grid` 组件模拟表格结构 |
20
- | `CoordinatorLayout` | 组合 `Scroll` + `Column` + 动画 | 无直接对应,需组合模拟 AppBar 折叠效果 |
21
- | `AppBarLayout` / `CollapsingToolbarLayout` | `Navigation` 标题栏 + `titleMode` | 折叠工具栏,`NavigationTitleMode.Full`→`.Mini` 自动切换 |
22
- | `ScrollView` | `Scroll` 组件 | 滚动容器,通过 `Scroller` 控制器编程式滚动 |
23
- | `HorizontalScrollView` | `Scroll` + `ScrollDirection.Horizontal` | 横向滚动 |
24
- | `NestedScrollView` | `Scroll` + `.nestedScroll()` | 嵌套滚动策略配置 |
25
- | `ViewPager` / `ViewPager2` | `Swiper` 组件 | 页面滑动切换,支持 `.autoPlay()`、`.indicator()`、`.loop()` |
26
- | `SwipeRefreshLayout` | `Refresh` 组件 | 下拉刷新,通过 `.onRefreshing()` 回调处理刷新 |
27
- | `RecyclerView` | `List` 组件 | 高性能列表,使用 `List` + `ForEach`/`LazyForEach` 渲染子组件 |
28
- | `RecyclerView` (GridLayoutManager) | `Grid` 组件 | 网格布局,通过 `.columnsTemplate()` 设置列数 |
29
- | `RecyclerView` (StaggeredGridLayoutManager) | `WaterFlow` 组件 | 瀑布流布局 |
30
- | `ListView` | `List` 组件 | 传统列表,使用 `List` 组件实现 |
31
- | `GridView` | `Grid` 组件 | 网格视图,使用 `Grid` 组件实现 |
32
- | `DrawerLayout` / `NavigationView` | `SideBarContainer` 组件 | 侧边栏/抽屉 |
33
- | `TabLayout` + `ViewPager` | `Tabs` 组件 | 标签页,`Tabs` 整合标签栏和内容页切换 |
34
- | `BottomNavigationView` | `Tabs` + `BarPosition.End` | 底部导航栏 |
35
- | `CardView` | `Card` 组件 / `Container` + 样式 | 卡片视图,使用 `Card` 组件或自定义样式实现 |
36
- | `Space` | `Blank` 组件 | 空白间隔,使用 `Blank` 组件实现 |
37
- | `FragmentContainerView` | `NavDestination` / `@Component` | 片段容器视图,映射到 `NavDestination` 或自定义组件 |
38
- | `RecyclerViewFastScroller` | 自定义组件 | 列表快速滚动条,需自定义实现 |
39
- | `MySearchMenu` (自定义) | `Search` 组件 + 自定义菜单 | 自定义搜索菜单,使用 `Search` 组件并添加自定义菜单 |
40
- | `MyViewPager` (自定义) | `Swiper` 组件 | 自定义视图分页器,使用 `Swiper` 组件实现 |
41
- | `MyRecyclerView` (自定义) | `List` 组件 | 自定义 RecyclerView,使用 `List` 组件实现 |
42
- | `MyTextView` (自定义) | `Text` 组件 | 自定义 TextView,使用 `Text` 组件实现 |
43
- | `MyAppCompatCheckbox` (自定义) | `Checkbox` 组件 | 自定义 Checkbox,使用 `Checkbox` 组件实现 |
44
-
45
- ## 布局属性映射
46
-
47
- | 安卓部分UI | 对应鸿蒙部分UI | 其他说明 |
48
- |-----------|---------------|---------|
49
- | `layout_weight` | `.layoutWeight()` / `.flexGrow()` | 权重分配 |
50
- | `padding` / `margin` | `.padding()` / `.margin()` | 支持统一或分别指定 `{ top, right, bottom, left }` |
51
- | `View.GONE` / `View.INVISIBLE` | `Visibility.None` / `Visibility.Hidden` | `None`=不占位(GONE);`Hidden`=占位不显示(INVISIBLE) |
52
- | `android:id` | `.id('xxx')` / 组件引用变量 | 组件标识 |
53
- | `android:background` | `.backgroundColor()` / `.backgroundImage()` | 背景 |
54
- | `android:alpha` | `.opacity()` | 透明度 0~1 |
55
- | `android:elevation` | `.shadow({ radius, color, offsetX, offsetY })` | 阴影 |
56
- | `android:rotation` | `.rotate({ angle: xxx })` | 旋转 |
57
- | `android:scaleX/Y` | `.scale({ x: xxx, y: xxx })` | 缩放 |
58
- | `android:translationX/Y` | `.translate({ x: xxx, y: xxx })` | 平移 |
59
- | `android:clipToOutline` | `.clip(true)` / `.clipShape()` | 裁剪 |
60
- | `setEnabled(false)` | `.enabled(false)` | 禁用状态 |
61
- | `android:focusable` | `.focusable(true)` | 可聚焦 |
62
- | `android:focusableInTouchMode` | `.focusable(true)` + `.focusOnTouch(true)` | 触摸模式下可聚焦 |
63
- | `android:clickable` | `.enabled(true)` + `.onClick()` | 可点击 |
64
- | `android:longClickable` | `.gesture(LongPressGesture())` | 可长按 |
65
- | `android:scrollbars` | `.scrollBar()` | 滚动条 |
66
- | `android:fadeScrollbars` | `.scrollBar().fade(true)` | 滚动条自动隐藏 |
67
- | `android:overScrollMode` | `.overScrollMode()` | 过度滚动模式 |
68
- | `GradientDrawable` | `.linearGradient()` / `.radialGradient()` | 渐变背景 |
69
- | `CardView` radius | `.borderRadius()` | 圆角 |
70
- | `GradientDrawable.setStroke()` | `.border({ width, color, radius })` | 边框 |
71
- | `android:layout_width` / `android:layout_height` | `.width()` / `.height()` | 宽高设置,支持具体数值、百分比、`'match_parent'`/`'wrap_content'` |
72
- | `android:gravity` | `.alignItems()` / `.justifyContent()` | 内容对齐方式 |
73
- | `android:layout_gravity` | `.alignSelf()` | 子组件在父容器中的对齐方式 |
74
- | `android:orientation` (LinearLayout) | `Column` / `Row` | 布局方向 |
75
- | `android:divider` (LinearLayout) | `Divider` 组件 | 分隔线 |
76
- | `android:showDividers` (LinearLayout) | `Divider` 组件位置 | 分隔线显示位置 |
77
-
78
- ## 页面结构映射
79
-
80
- | 安卓部分UI | 对应鸿蒙部分UI | 其他说明 |
81
- |-----------|---------------|---------|
82
- | `Activity` | `PageAbility` | 主UI容器 |
83
- | `Fragment` | `NavDestination` / `@Component` | 通过 Navigation + NavDestination 实现子页面路由 |
84
- | `Service` | `ServiceAbility` | 后台服务 |
85
- | `BroadcastReceiver` | `EventHub` + `@Event` | 广播接收器,使用事件订阅机制 |
86
- | `ContentProvider` | `DataAbility` | 内容提供者 |
87
- | `Toolbar` / `ActionBar` | `Navigation` 标题栏 | 通过 `.title()` 和 `.menus()` 配置 |
88
- | `Intent` | `router` 模块 | 页面导航,使用 `router.push()`、`router.replace()` 等 |
89
- | `Bundle` | `router.push({ params: {} })` | 页面间传递数据 |
90
- | `onActivityResult` | `router.push()` + 回调 | 页面返回结果 |
91
- | `startActivityForResult` | `router.push()` + 回调 | 启动页面并获取结果 |
92
-
93
- ## 列表与可滚动组件映射
94
-
95
- | 安卓部分UI | 对应鸿蒙部分UI | 其他说明 |
96
- |-----------|---------------|---------|
97
- | `RecyclerView.Adapter` | `LazyForEach` + `IDataSource` | 数据适配器,实现 `IDataSource` 接口配合 `LazyForEach` 懒加载 |
98
- | `RecyclerView.ViewHolder` | `@Builder` / `@Component` | 声明式 UI 无需 ViewHolder 模式 |
99
- | `LinearLayoutManager` | `List` 默认布局 | 纵向列表,`.listDirection(Axis.Horizontal)` 切换横向 |
100
- | `GridLayoutManager` | `Grid` 组件 | 网格布局管理器 |
101
- | `StaggeredGridLayoutManager` | `WaterFlow` 组件 | 瀑布流布局管理器 |
102
- | `ItemTouchHelper` (swipe) | `ListItem.swipeAction()` | 列表项滑动操作菜单 |
103
- | `ItemTouchHelper` (drag) | `ListItem.dragable()` | 列表项拖拽排序 |
104
- | `DiffUtil` | `IDataSource` 的 `DataChangeListener` | 差异通知,`onDataAdd`/`onDataDelete`/`onDataChange` |
105
- | `PagerAdapter` / `FragmentStateAdapter` | `Swiper` + `ForEach`/`LazyForEach` | 无需 Adapter 模式,直接循环渲染子页面 |
106
- | `ListAdapter` | `LazyForEach` + `IDataSource` | 带 DiffUtil 的适配器 |
107
- | `ArrayAdapter` | `ForEach` + 数组 | 数组适配器 |
108
- | `BaseAdapter` | `ForEach` / `LazyForEach` | 基础适配器 |
109
-
110
- ## 迁移注意事项
111
-
112
- 1. **范式转换**:Android 使用命令式 UI(XML 布局 + Java/Kotlin 操作);ArkUI 使用声明式 UI(ArkTS 组件树 + 状态驱动渲染)
113
- 2. **Adapter 模式消除**:`RecyclerView.Adapter`、`PagerAdapter` 等被 `ForEach`/`LazyForEach` + `IDataSource` 替代
114
- 3. **Fragment → NavDestination**:Fragment 模块化 UI 能力映射到 `Navigation` + `NavDestination` 路由
115
- 4. **布局属性调整**:Android 的布局属性需要转换为 ArkUI 的链式调用语法
116
- 5. **性能优化**:使用 `LazyForEach` 进行懒加载,避免一次性渲染大量数据
117
- 6. **响应式布局**:使用 `Flex` 和 `Grid` 组件实现响应式布局,适应不同屏幕尺寸
1
+ # Android-to-HarmonyOS UI Layout Mapping Reference
2
+
3
+ <!-- TODO: Fill in the actual UI layout mapping content -->
4
+ <!-- This reference maps Android layout containers to HarmonyOS ArkUI layout equivalents -->
5
+ <!-- Covers: LinearLayout→Column/Row, FrameLayout→Stack, ConstraintLayout→RelativeContainer, RecyclerView→List+LazyForEach, ScrollView→Scroll, etc. -->
6
+
7
+
8
+ ## 布局容器映射
9
+
10
+ | 安卓部分UI | 对应鸿蒙部分UI | 其他说明 |
11
+ |-----------|---------------|---------|
12
+ | `LinearLayout` (vertical) | `Column` 组件 | 纵向线性布局,支持 `.justifyContent()`、`.alignItems()` |
13
+ | `LinearLayout` (horizontal) | `Row` 组件 | 横向线性布局 |
14
+ | `FrameLayout` | `Stack` 组件 | 层叠布局,支持 `.alignContent()` |
15
+ | `RelativeLayout` | `RelativeContainer` 组件 | 相对布局,通过 `.alignRules()` 设置定位规则 |
16
+ | `ConstraintLayout` | `RelativeContainer` / 自定义布局 | 约束布局,复杂场景可用自定义 `onMeasureSize`/`onPlaceChildren` |
17
+ | `FlexboxLayout` | `Flex` 组件 | 弹性布局,支持 `FlexDirection`/`FlexWrap`/`FlexAlign` 标准 Flexbox |
18
+ | `GridLayout` | `Grid` 组件 | 网格布局,通过 `.columnsTemplate('1fr 1fr 1fr')` 定义列 |
19
+ | `TableLayout` | `Grid` 组件 | 表格布局,使用 `Grid` 组件模拟表格结构 |
20
+ | `CoordinatorLayout` | 组合 `Scroll` + `Column` + 动画 | 无直接对应,需组合模拟 AppBar 折叠效果 |
21
+ | `AppBarLayout` / `CollapsingToolbarLayout` | `Navigation` 标题栏 + `titleMode` | 折叠工具栏,`NavigationTitleMode.Full`→`.Mini` 自动切换 |
22
+ | `ScrollView` | `Scroll` 组件 | 滚动容器,通过 `Scroller` 控制器编程式滚动 |
23
+ | `HorizontalScrollView` | `Scroll` + `ScrollDirection.Horizontal` | 横向滚动 |
24
+ | `NestedScrollView` | `Scroll` + `.nestedScroll()` | 嵌套滚动策略配置 |
25
+ | `ViewPager` / `ViewPager2` | `Swiper` 组件 | 页面滑动切换,支持 `.autoPlay()`、`.indicator()`、`.loop()` |
26
+ | `SwipeRefreshLayout` | `Refresh` 组件 | 下拉刷新,通过 `.onRefreshing()` 回调处理刷新 |
27
+ | `RecyclerView` | `List` 组件 | 高性能列表,使用 `List` + `ForEach`/`LazyForEach` 渲染子组件 |
28
+ | `RecyclerView` (GridLayoutManager) | `Grid` 组件 | 网格布局,通过 `.columnsTemplate()` 设置列数 |
29
+ | `RecyclerView` (StaggeredGridLayoutManager) | `WaterFlow` 组件 | 瀑布流布局 |
30
+ | `ListView` | `List` 组件 | 传统列表,使用 `List` 组件实现 |
31
+ | `GridView` | `Grid` 组件 | 网格视图,使用 `Grid` 组件实现 |
32
+ | `DrawerLayout` / `NavigationView` | `SideBarContainer` 组件 | 侧边栏/抽屉 |
33
+ | `TabLayout` + `ViewPager` | `Tabs` 组件 | 标签页,`Tabs` 整合标签栏和内容页切换 |
34
+ | `BottomNavigationView` | `Tabs` + `BarPosition.End` | 底部导航栏 |
35
+ | `CardView` | `Card` 组件 / `Container` + 样式 | 卡片视图,使用 `Card` 组件或自定义样式实现 |
36
+ | `Space` | `Blank` 组件 | 空白间隔,使用 `Blank` 组件实现 |
37
+ | `FragmentContainerView` | `NavDestination` / `@Component` | 片段容器视图,映射到 `NavDestination` 或自定义组件 |
38
+ | `RecyclerViewFastScroller` | 自定义组件 | 列表快速滚动条,需自定义实现 |
39
+ | `MySearchMenu` (自定义) | `Search` 组件 + 自定义菜单 | 自定义搜索菜单,使用 `Search` 组件并添加自定义菜单 |
40
+ | `MyViewPager` (自定义) | `Swiper` 组件 | 自定义视图分页器,使用 `Swiper` 组件实现 |
41
+ | `MyRecyclerView` (自定义) | `List` 组件 | 自定义 RecyclerView,使用 `List` 组件实现 |
42
+ | `MyTextView` (自定义) | `Text` 组件 | 自定义 TextView,使用 `Text` 组件实现 |
43
+ | `MyAppCompatCheckbox` (自定义) | `Checkbox` 组件 | 自定义 Checkbox,使用 `Checkbox` 组件实现 |
44
+
45
+ ## 布局属性映射
46
+
47
+ | 安卓部分UI | 对应鸿蒙部分UI | 其他说明 |
48
+ |-----------|---------------|---------|
49
+ | `layout_weight` | `.layoutWeight()` / `.flexGrow()` | 权重分配 |
50
+ | `padding` / `margin` | `.padding()` / `.margin()` | 支持统一或分别指定 `{ top, right, bottom, left }` |
51
+ | `View.GONE` / `View.INVISIBLE` | `Visibility.None` / `Visibility.Hidden` | `None`=不占位(GONE);`Hidden`=占位不显示(INVISIBLE) |
52
+ | `android:id` | `.id('xxx')` / 组件引用变量 | 组件标识 |
53
+ | `android:background` | `.backgroundColor()` / `.backgroundImage()` | 背景 |
54
+ | `android:alpha` | `.opacity()` | 透明度 0~1 |
55
+ | `android:elevation` | `.shadow({ radius, color, offsetX, offsetY })` | 阴影 |
56
+ | `android:rotation` | `.rotate({ angle: xxx })` | 旋转 |
57
+ | `android:scaleX/Y` | `.scale({ x: xxx, y: xxx })` | 缩放 |
58
+ | `android:translationX/Y` | `.translate({ x: xxx, y: xxx })` | 平移 |
59
+ | `android:clipToOutline` | `.clip(true)` / `.clipShape()` | 裁剪 |
60
+ | `setEnabled(false)` | `.enabled(false)` | 禁用状态 |
61
+ | `android:focusable` | `.focusable(true)` | 可聚焦 |
62
+ | `android:focusableInTouchMode` | `.focusable(true)` + `.focusOnTouch(true)` | 触摸模式下可聚焦 |
63
+ | `android:clickable` | `.enabled(true)` + `.onClick()` | 可点击 |
64
+ | `android:longClickable` | `.gesture(LongPressGesture())` | 可长按 |
65
+ | `android:scrollbars` | `.scrollBar()` | 滚动条 |
66
+ | `android:fadeScrollbars` | `.scrollBar().fade(true)` | 滚动条自动隐藏 |
67
+ | `android:overScrollMode` | `.overScrollMode()` | 过度滚动模式 |
68
+ | `GradientDrawable` | `.linearGradient()` / `.radialGradient()` | 渐变背景 |
69
+ | `CardView` radius | `.borderRadius()` | 圆角 |
70
+ | `GradientDrawable.setStroke()` | `.border({ width, color, radius })` | 边框 |
71
+ | `android:layout_width` / `android:layout_height` | `.width()` / `.height()` | 宽高设置,支持具体数值、百分比、`'match_parent'`/`'wrap_content'` |
72
+ | `android:gravity` | `.alignItems()` / `.justifyContent()` | 内容对齐方式 |
73
+ | `android:layout_gravity` | `.alignSelf()` | 子组件在父容器中的对齐方式 |
74
+ | `android:orientation` (LinearLayout) | `Column` / `Row` | 布局方向 |
75
+ | `android:divider` (LinearLayout) | `Divider` 组件 | 分隔线 |
76
+ | `android:showDividers` (LinearLayout) | `Divider` 组件位置 | 分隔线显示位置 |
77
+
78
+ ## 页面结构映射
79
+
80
+ | 安卓部分UI | 对应鸿蒙部分UI | 其他说明 |
81
+ |-----------|---------------|---------|
82
+ | `Activity` | `PageAbility` | 主UI容器 |
83
+ | `Fragment` | `NavDestination` / `@Component` | 通过 Navigation + NavDestination 实现子页面路由 |
84
+ | `Service` | `ServiceAbility` | 后台服务 |
85
+ | `BroadcastReceiver` | `EventHub` + `@Event` | 广播接收器,使用事件订阅机制 |
86
+ | `ContentProvider` | `DataAbility` | 内容提供者 |
87
+ | `Toolbar` / `ActionBar` | `Navigation` 标题栏 | 通过 `.title()` 和 `.menus()` 配置 |
88
+ | `Intent` | `router` 模块 | 页面导航,使用 `router.push()`、`router.replace()` 等 |
89
+ | `Bundle` | `router.push({ params: {} })` | 页面间传递数据 |
90
+ | `onActivityResult` | `router.push()` + 回调 | 页面返回结果 |
91
+ | `startActivityForResult` | `router.push()` + 回调 | 启动页面并获取结果 |
92
+
93
+ ## 列表与可滚动组件映射
94
+
95
+ | 安卓部分UI | 对应鸿蒙部分UI | 其他说明 |
96
+ |-----------|---------------|---------|
97
+ | `RecyclerView.Adapter` | `LazyForEach` + `IDataSource` | 数据适配器,实现 `IDataSource` 接口配合 `LazyForEach` 懒加载 |
98
+ | `RecyclerView.ViewHolder` | `@Builder` / `@Component` | 声明式 UI 无需 ViewHolder 模式 |
99
+ | `LinearLayoutManager` | `List` 默认布局 | 纵向列表,`.listDirection(Axis.Horizontal)` 切换横向 |
100
+ | `GridLayoutManager` | `Grid` 组件 | 网格布局管理器 |
101
+ | `StaggeredGridLayoutManager` | `WaterFlow` 组件 | 瀑布流布局管理器 |
102
+ | `ItemTouchHelper` (swipe) | `ListItem.swipeAction()` | 列表项滑动操作菜单 |
103
+ | `ItemTouchHelper` (drag) | `ListItem.dragable()` | 列表项拖拽排序 |
104
+ | `DiffUtil` | `IDataSource` 的 `DataChangeListener` | 差异通知,`onDataAdd`/`onDataDelete`/`onDataChange` |
105
+ | `PagerAdapter` / `FragmentStateAdapter` | `Swiper` + `ForEach`/`LazyForEach` | 无需 Adapter 模式,直接循环渲染子页面 |
106
+ | `ListAdapter` | `LazyForEach` + `IDataSource` | 带 DiffUtil 的适配器 |
107
+ | `ArrayAdapter` | `ForEach` + 数组 | 数组适配器 |
108
+ | `BaseAdapter` | `ForEach` / `LazyForEach` | 基础适配器 |
109
+
110
+ ## 迁移注意事项
111
+
112
+ 1. **范式转换**:Android 使用命令式 UI(XML 布局 + Java/Kotlin 操作);ArkUI 使用声明式 UI(ArkTS 组件树 + 状态驱动渲染)
113
+ 2. **Adapter 模式消除**:`RecyclerView.Adapter`、`PagerAdapter` 等被 `ForEach`/`LazyForEach` + `IDataSource` 替代
114
+ 3. **Fragment → NavDestination**:Fragment 模块化 UI 能力映射到 `Navigation` + `NavDestination` 路由
115
+ 4. **布局属性调整**:Android 的布局属性需要转换为 ArkUI 的链式调用语法
116
+ 5. **性能优化**:使用 `LazyForEach` 进行懒加载,避免一次性渲染大量数据
117
+ 6. **响应式布局**:使用 `Flex` 和 `Grid` 组件实现响应式布局,适应不同屏幕尺寸
@@ -1,37 +1,37 @@
1
- Create a timestamped output directory under `capture_output_dir`:
2
- ```
3
- task_dir = capture_output_dir / "task_{timestamp}"
4
- android_capture_dir = task_dir / "android_page_{i}_{name}"
5
- hmos_capture_dir = task_dir / "hmos_page_{i}_{name}"
6
- ```
7
- Each paired hmos-android page-pair should have the same `i`
8
-
9
- ## Navigation prompt rules
10
-
11
- Each page's `android_nav_path` / `hmos_nav_path` is used as the `--prompt` for `app_feature_verify.py`.
12
- The `--prompt` mode auto-prepends "打开{app_name}," so do not include "打开{app_name}" in the prompt.
13
-
14
- ## Navigate to Android page and Capture (If navigated Success)
15
- ```bash
16
- PYTHONIOENCODING=utf-8 python ./app_feature_verify.py \
17
- --device adb \
18
- --app "{android.app_name}" \
19
- --package "{android.package}" \
20
- --prompt "{pages[i].android_nav_path}" \
21
- --api-key "{glm_api_key}" \
22
- --max-steps 15
23
- ```
24
-
25
- **Capture Android page** (if navigation succeeded)
26
- ```bash
27
- PYTHONIOENCODING=utf-8 python ./page_capture.py --device adb -o "{android_capture_dir}"
28
- ```
29
-
30
- ## Navigate & Capture HarmonyOS Pages
31
-
32
- Same as Andorid but with `--device hdc` and HarmonyOS config values. Directory pattern:
33
- ```
34
- hmos_capture_dir = task_dir / "hmos_page_{i}_{name}"
35
- ```
36
- For pages missed in harmony OS app, navigation will certainly fail — `hmos_capture_dir` will be empty, which is expected. Skip navigation for these pages and leave the directory empty.
37
-
1
+ Create a timestamped output directory under `capture_output_dir`:
2
+ ```
3
+ task_dir = capture_output_dir / "task_{timestamp}"
4
+ android_capture_dir = task_dir / "android_page_{i}_{name}"
5
+ hmos_capture_dir = task_dir / "hmos_page_{i}_{name}"
6
+ ```
7
+ Each paired hmos-android page-pair should have the same `i`
8
+
9
+ ## Navigation prompt rules
10
+
11
+ Each page's `android_nav_path` / `hmos_nav_path` is used as the `--prompt` for `app_feature_verify.py`.
12
+ The `--prompt` mode auto-prepends "打开{app_name}," so do not include "打开{app_name}" in the prompt.
13
+
14
+ ## Navigate to Android page and Capture (If navigated Success)
15
+ ```bash
16
+ PYTHONIOENCODING=utf-8 python ./app_feature_verify.py \
17
+ --device adb \
18
+ --app "{android.app_name}" \
19
+ --package "{android.package}" \
20
+ --prompt "{pages[i].android_nav_path}" \
21
+ --api-key "{glm_api_key}" \
22
+ --max-steps 15
23
+ ```
24
+
25
+ **Capture Android page** (if navigation succeeded)
26
+ ```bash
27
+ PYTHONIOENCODING=utf-8 python ./page_capture.py --device adb -o "{android_capture_dir}"
28
+ ```
29
+
30
+ ## Navigate & Capture HarmonyOS Pages
31
+
32
+ Same as Andorid but with `--device hdc` and HarmonyOS config values. Directory pattern:
33
+ ```
34
+ hmos_capture_dir = task_dir / "hmos_page_{i}_{name}"
35
+ ```
36
+ For pages missed in harmony OS app, navigation will certainly fail — `hmos_capture_dir` will be empty, which is expected. Skip navigation for these pages and leave the directory empty.
37
+
@@ -10,7 +10,7 @@
10
10
 
11
11
  - **把 Markdown 测试用例变成机器可读的 JSON**:解析你写的 `test_case.md`,自动提取包名、替换应用名,生成 AutoTest 可执行的 `testcases.json`。
12
12
  - **在鸿蒙真机上跑自动化测试**:连接 USB 设备,安装 HAP,逐条执行用例,生成带通过率和失败详情的报告。
13
- - **测试失败后自动修复并重测**:读到失败报告 → 白盒审查源码 → 修改代码 → 重新编译签名 HAP → 重新测试 → 如果还有失败则继续循环,默认最多 3 轮(可通过 `max-rounds` 参数配置)。
13
+ - **测试失败后自动修复并重测**:读到失败报告 → 白盒审查源码 → 修改代码 → 重新编译签名 HAP → 重新测试 → 如果还有失败则继续循环,默认最多 3 轮(可通过 `max_rounds` 参数配置)。
14
14
 
15
15
  ---
16
16
 
@@ -26,15 +26,15 @@
26
26
 
27
27
  **然后会发生什么:**
28
28
 
29
- 1. **测试与修复循环** — 默认最多 3 轮(可通过 `max-rounds` 参数配置),每轮跑完后产物快照到 `output-path/round-{n}/`:
30
- - 首轮:解析 `test_case.md` → 写出 `output-path/testcases.json` 与 `app-metadata.json` → 连接真机、安装 HAP、跑 AutoTest → 产出 `output-path/self-test-report.md`
31
- - 测试完成后,SKILL 把当轮的 `self-test-report.md`、`task/`、`_extracted.json`(若有)快照到 `output-path/round-{n}/`
29
+ 1. **测试与修复循环** — 默认最多 3 轮(可通过 `max_rounds` 参数配置),每轮跑完后产物快照到 `output_path/round-{n}/`:
30
+ - 首轮:解析 `test_case.md` → 写出 `output_path/testcases.json` 与 `app-metadata.json` → 连接真机、安装 HAP、跑 AutoTest → 产出 `output_path/self-test-report.md`
31
+ - 测试完成后,SKILL 把当轮的 `self-test-report.md`、`task/`、`_extracted.json`(若有)快照到 `output_path/round-{n}/`
32
32
  - Fix:白盒审查代码 → 修改源码 → 产出 `round-{n}/self-test-fix-report.md`
33
33
  - Build:重新编译 → 产出 `round-{n}/entry-default-signed.hap` 和 `build-fix-report.md`
34
34
  - 后续轮:跳过解析阶段,直接读首轮已生成的 `testcases.json` + `app-metadata.json`,用新 HAP 跑测试 → 同样快照到对应轮 `round-{n}/`
35
- 2. **HAP 镜像** — 循环结束后,最后一轮的签名 HAP 复制到 `output-path/entry-default-signed.hap`,方便直接取用
35
+ 2. **HAP 镜像** — 循环结束后,最后一轮的签名 HAP 复制到 `output_path/entry-default-signed.hap`,方便直接取用
36
36
 
37
- **最终产物**(在 `output-path` 下):
37
+ **最终产物**(在 `output_path` 下):
38
38
 
39
39
  | 文件 | 位置 | 内容 |
40
40
  |------|------|------|
@@ -53,11 +53,11 @@
53
53
 
54
54
  | 参数 | 是否必填 | 说明 |
55
55
  |------|----------|------|
56
- | `hap-path` | 必填 | 签名后的 `.hap` 安装包路径 |
57
- | `output-path` | 可选,默认 = `test-case-path` 所在目录 | 所有产物输出到这个目录(`testcases.json`、`app-metadata.json`、`self-test-report.md`、`task/` 都写在此根目录)。不指定时直接写在用例文件同目录 |
58
- | `test-case-path` | `setup=true` 时必填 | `test_case.md` 的路径 |
59
- | `pre-test-case-path` | 可选 | 前置用例 `pre_test_case.md` 的路径。不传会自动在同目录查找 |
60
- | `setup` | 可选,默认 `true` | `true` = 解析 `test_case.md` 写出 JSON,再跑测试;`false` = 跳过解析阶段,直接读取 `<output-path>/testcases.json` 与 `<output-path>/app-metadata.json` 跑测试。两个 JSON 都不存在或为空时硬失败,需要重跑一次 `setup=true` |
56
+ | `hap_path` | 必填 | 签名后的 `.hap` 安装包路径 |
57
+ | `output_path` | 可选,默认 = `test_case_path` 所在目录 | 所有产物输出到这个目录(`testcases.json`、`app-metadata.json`、`self-test-report.md`、`task/` 都写在此根目录)。不指定时直接写在用例文件同目录 |
58
+ | `test_case_path` | `setup=true` 时必填 | `test_case.md` 的路径 |
59
+ | `pre_test_case_path` | 可选 | 前置用例 `pre_test_case.md` 的路径。不传会自动在同目录查找 |
60
+ | `setup` | 可选,默认 `true` | `true` = 解析 `test_case.md` 写出 JSON,再跑测试;`false` = 跳过解析阶段,直接读取 `<output_path>/testcases.json` 与 `<output_path>/app-metadata.json` 跑测试。两个 JSON 都不存在或为空时硬失败,需要重跑一次 `setup=true` |
61
61
 
62
62
  ### 自动修复参数
63
63
 
@@ -65,29 +65,29 @@
65
65
 
66
66
  | 参数 | 必填 | 说明 |
67
67
  |------|------|------|
68
- | `harmonyos-project-path` | 是 | 自动从 `app-metadata.json` 的 `project_root` 字段读取 |
69
- | `android-project-path` | 否 | Android 参考项目路径。提供后 fixer 会参考 Android 实现来修 bug,质量更高 |
68
+ | `harmony_project_dir` | 是 | 自动从 `app-metadata.json` 的 `project_root` 字段读取 |
69
+ | `android_project_dir` | 否 | Android 参考项目路径。提供后 fixer 会参考 Android 实现来修 bug,质量更高 |
70
70
 
71
71
  ---
72
72
 
73
73
  ## 输出产物
74
74
 
75
- `testcases.json` 和 `app-metadata.json` 在首轮(`setup=true`)写入 `output-path/` 根目录,后续轮直接复用,不再重新生成。`self-test-report.md` 与 `task/` 每轮都会在根目录覆盖更新,跑完每轮后由 SKILL 快照到 `output-path/round-{n}/`。循环结束后,最后一轮的签名 HAP 镜像到根目录。
75
+ `testcases.json` 和 `app-metadata.json` 在首轮(`setup=true`)写入 `output_path/` 根目录,后续轮直接复用,不再重新生成。`self-test-report.md` 与 `task/` 每轮都会在根目录覆盖更新,跑完每轮后由 SKILL 快照到 `output_path/round-{n}/`。循环结束后,最后一轮的签名 HAP 镜像到根目录。
76
76
 
77
77
  | 文件 | 写入位置 | 内容 |
78
78
  |------|----------|------|
79
- | `testcases.json` | `output-path/` 根目录(首轮写入,跨轮共享) | 结构化的用例列表,供 AutoTest 逐条执行 |
80
- | `app-metadata.json` | `output-path/` 根目录(首轮写入,跨轮共享) | `{ bundle_name, app_name, project_root }` |
81
- | `_extracted.json` | `output-path/` 根目录(首轮写入,跨轮快照保留) | 用例提取的中间文件,排查问题时有用,通常不需要关注 |
82
- | `self-test-report.md` | `output-path/` 根目录(每轮覆盖,跨轮快照保留) | 可读的测试报告,含通过率、失败原因、每条用例的 AutoTest 任务路径 |
83
- | `task/task_<时间戳>/` | `output-path/task/`(每轮覆盖,跨轮快照保留) | 每条用例的 HTML 报告、截图、Agent 日志 |
84
- | `self-test-fix-report.md` | `output-path/round-{n}/`(Fix 步骤,有失败的轮次) | 白盒审查结论、根因分析、修改内容、修复结果 |
85
- | `self-test-fix-commit-info.md` | `output-path/round-{n}/`(Fix 步骤) | `commit-id: <hash>` 或 `commit-id: none` |
86
- | `build-fix-report.md` | `output-path/round-{n}/`(Build 步骤) | 编译是否成功、修复了哪些编译问题 |
87
- | `build-fix-commit-info.md` | `output-path/round-{n}/`(Build 步骤) | `commit-id: <hash>` 或 `commit-id: none` |
88
- | `entry-default-signed.hap` | `output-path/round-{n}/`(Build 步骤);循环结束后镜像到 `output-path/` 根目录 | 修复后重新编译的签名 HAP |
89
-
90
- > **提示**:`output-path/` 根目录下的报告和 task 始终是最近一轮的最新产物;要查看某一轮的历史快照,进入对应的 `round-{n}/` 目录即可。
79
+ | `testcases.json` | `output_path/` 根目录(首轮写入,跨轮共享) | 结构化的用例列表,供 AutoTest 逐条执行 |
80
+ | `app-metadata.json` | `output_path/` 根目录(首轮写入,跨轮共享) | `{ bundle_name, app_name, project_root }` |
81
+ | `_extracted.json` | `output_path/` 根目录(首轮写入,跨轮快照保留) | 用例提取的中间文件,排查问题时有用,通常不需要关注 |
82
+ | `self-test-report.md` | `output_path/` 根目录(每轮覆盖,跨轮快照保留) | 可读的测试报告,含通过率、失败原因、每条用例的 AutoTest 任务路径 |
83
+ | `task/task_<时间戳>/` | `output_path/task/`(每轮覆盖,跨轮快照保留) | 每条用例的 HTML 报告、截图、Agent 日志 |
84
+ | `self-test-fix-report.md` | `output_path/round-{n}/`(Fix 步骤,有失败的轮次) | 白盒审查结论、根因分析、修改内容、修复结果 |
85
+ | `self-test-fix-commit-info.md` | `output_path/round-{n}/`(Fix 步骤) | `commit_id: <hash>` 或 `commit_id: none` |
86
+ | `build-fix-report.md` | `output_path/round-{n}/`(Build 步骤) | 编译是否成功、修复了哪些编译问题 |
87
+ | `build-fix-commit-info.md` | `output_path/round-{n}/`(Build 步骤) | `commit_id: <hash>` 或 `commit_id: none` |
88
+ | `entry-default-signed.hap` | `output_path/round-{n}/`(Build 步骤);循环结束后镜像到 `output_path/` 根目录 | 修复后重新编译的签名 HAP |
89
+
90
+ > **提示**:`output_path/` 根目录下的报告和 task 始终是最近一轮的最新产物;要查看某一轮的历史快照,进入对应的 `round-{n}/` 目录即可。
91
91
 
92
92
  ---
93
93
 
@@ -107,7 +107,7 @@
107
107
  └──────────────────────────────┬───────────────────────────────┘
108
108
 
109
109
 
110
- ┌─ 测试与修复循环(每轮跑完后快照到 output-path/round-{n}/)──┐
110
+ ┌─ 测试与修复循环(每轮跑完后快照到 output_path/round-{n}/)──┐
111
111
  │ │
112
112
  │ ┌── Test ─────────────────────────────────────────────┐ │
113
113
  │ │ 检测真机连接 → 安装 HAP → AutoTest 批量执行用例 │ │
@@ -145,7 +145,7 @@
145
145
  └──────────────────────────────────────────────────────────────┘
146
146
 
147
147
 
148
- 循环结束 → 镜像最终轮报告和 HAP 到 output-path/
148
+ 循环结束 → 镜像最终轮报告和 HAP 到 output_path/
149
149
  ```
150
150
 
151
151
  ### 循环停止条件
@@ -156,10 +156,10 @@
156
156
  |------|-------------|------|
157
157
  | 全部通过 | `all_passed` | 报告 `failed == 0`,所有用例通过 |
158
158
  | 无确认缺陷 | `no_confirmed_defects` | fixer 判定所有失败都是测试误报(false positive),没有需要修改的代码缺陷 |
159
- | 达到最大轮数 | `max_rounds_reached` | 已完成配置的最大轮数循环(`max-rounds`,默认 3),仍有失败未解决 |
159
+ | 达到最大轮数 | `max_rounds_reached` | 已完成配置的最大轮数循环(`max_rounds`,默认 3),仍有失败未解决 |
160
160
  | 编译未产出 HAP(异常) | `no_signed_hap` | build-fixer 未产出签名 HAP,无法继续测试 |
161
161
  | 用例列表为空(异常) | `no_testcases` | `testcases.json` 里 0 条用例,没有可跑的内容。常见原因:解析阶段没识别到 `### Scenario:` 区块 |
162
- | 自测 agent 早退(异常) | `agent_early_exit` | `self-tester` 在跑用例之前就退出了(设备没连、`config.yaml` 没填、`test-tools/autotest` 目录找不到(`env.TOOL_PATH` 未配置或失效)、batch 启动失败 / 超时 / 崩溃、`setup=false` 但所需 JSON 缺失等)。报告首行会是 `status: FAIL`,第二行 `reason: <原因>`。**这种情况下不会进入 fix 循环**——这些是环境/前置条件问题,不是应用缺陷 |
162
+ | 自测 agent 早退(异常) | `agent_early_exit` | `self-tester` 在跑用例之前就退出了(设备没连、autotest api_key 没配(`~/.hometrans/config.json` 的 autotest 块或 `TEST_API_KEY` 环境变量)、`test-tools/autotest` 目录找不到(`HOMETRANS_TOOL_PATH` 环境变量未配置或失效)、batch 启动失败 / 超时 / 崩溃、`setup=false` 但所需 JSON 缺失等)。报告首行会是 `status: FAIL`,第二行 `reason: <原因>`。**这种情况下不会进入 fix 循环**——这些是环境/前置条件问题,不是应用缺陷 |
163
163
 
164
164
  ---
165
165
 
@@ -242,14 +242,14 @@ build-fixer 的输出摘要:编译状态、签名类型、迭代次数、修
242
242
  - 操作系统:**Windows** 是主要测试目标;macOS/Linux 上的核心命令(`hdc`、`uv`、POSIX 工具链)也能跑,Skill 里涉及到的复制操作会按可用 shell 自适应
243
243
  - `hdc` 已安装并在 PATH 中
244
244
  - `uv` 已安装(Python 包管理)
245
- - `<TOOL_PATH>/test-tools/autotest/config.yaml` 已配置真实 api_key(`TOOL_PATH` 取自 `~/.hometrans/config.json` 的 `env.TOOL_PATH`,默认即 `~/.hometrans/tools`;`ht init` 填好 `TEST_API_KEY` 后会自动写入)
245
+ - `~/.hometrans/config.json` 的 `autotest` 块已配置真实 api_key。`api_key` 来源:`ht init` 填好 `TEST_API_KEY` 后自动写入该块;若仍是占位符,`self_test_runner.py` 会在跑用例前用 OS 环境变量 `TEST_API_KEY` 自动补全。运行时由脚本读取该块、物化成临时 YAML 交给 `AutoTest.batch`,不再需要 `config.yaml`
246
246
  - 鸿蒙真机通过 USB 连接,`hdc list targets` 能看到设备
247
247
  - 签名后的 `.hap` 文件
248
248
 
249
249
  ### 自动修复附加条件
250
250
 
251
251
  - `app-metadata.json` 存在(setup 阶段自动产出,内含 `project_root`)
252
- - 建议项目在 Git 仓库中(不在也可以修复,但不会自动 commit;`commit-id: none`)
252
+ - 建议项目在 Git 仓库中(不在也可以修复,但不会自动 commit;`commit_id: none`)
253
253
  - 签名配置已存在于 `build-profile.json5`(DevEco Studio → File → Project Structure → Signing Configs → Automatically generate signature)
254
254
 
255
255
  ---
@@ -260,9 +260,9 @@ build-fixer 的输出摘要:编译状态、签名类型、迭代次数、修
260
260
 
261
261
  A: 检查 USB 连接,跑 `hdc list targets` 看看有没有设备 SN。重新插拔 USB,在设备上重新授权 USB 调试。
262
262
 
263
- **Q: 报 config.yaml missing 或 api_key 没填?**
263
+ **Q: 报 autotest 配置缺失 或 api_key 没填?**
264
264
 
265
- A: AutoTest 目录 `<TOOL_PATH>/test-tools/autotest`(`TOOL_PATH` 取自 `~/.hometrans/config.json` 的 `env.TOOL_PATH`,默认 `~/.hometrans/tools`)下,复制 `config.yaml.example` `config.yaml`,把 `YOUR_API_KEY_HERE` 替换成真实的 API Key。或者重新跑 `ht init` 并填入 `TEST_API_KEY`,它会自动生成。
265
+ A: 三选一:① 设置环境变量 `TEST_API_KEY`(`self_test_runner.py` 跑用例前会自动用它填充);② 重新跑 `ht init` 并填入 `TEST_API_KEY`,它会自动写入 `~/.hometrans/config.json` 的 `autotest` 块;③ 手动编辑 `~/.hometrans/config.json`,把 `autotest.unified_model.api_key` `YOUR_API_KEY_HERE` 替换成真实的 API Key
266
266
 
267
267
  **Q: 前置用例失败了要不要修代码?**
268
268
 
@@ -278,15 +278,15 @@ A: 每条用例大约 6 分钟(含 Agent 决策和执行时间)。整体超
278
278
 
279
279
  **Q: 怎么只重跑失败的用例?**
280
280
 
281
- A: 目前每次都跑 `testcases.json` 的全部用例。你可以手动删掉已通过的条目,只保留失败的,然后用 `setup=false` 重新跑(会跳过解析阶段,直接读取 `<output-path>/testcases.json`)。
281
+ A: 目前每次都跑 `testcases.json` 的全部用例。你可以手动删掉已通过的条目,只保留失败的,然后用 `setup=false` 重新跑(会跳过解析阶段,直接读取 `<output_path>/testcases.json`)。
282
282
 
283
283
  **Q: 产物在哪个目录?**
284
284
 
285
- A: `testcases.json` 和 `app-metadata.json` 在 `output-path/` 根目录。测试和修复的每轮产物在 `output-path/round-1/`、`output-path/round-2/`... 子目录中。循环结束后,最终轮的关键文件(报告、HAP)会镜像到 `output-path/` 根目录,方便直接查看。
285
+ A: `testcases.json` 和 `app-metadata.json` 在 `output_path/` 根目录。测试和修复的每轮产物在 `output_path/round-1/`、`output_path/round-2/`... 子目录中。循环结束后,最终轮的关键文件(报告、HAP)会镜像到 `output_path/` 根目录,方便直接查看。
286
286
 
287
287
  **Q: 怎么启用自动修复?**
288
288
 
289
- A: 说"跑自测,自动修复";或者跑完测试后看到有失败,Skill 会主动问你要不要启用,回复"是"就进去了。默认最多 3 轮,需要更多/更少可以加一句"最多 N 轮"(对应 `max-rounds` 参数)。
289
+ A: 说"跑自测,自动修复";或者跑完测试后看到有失败,Skill 会主动问你要不要启用,回复"是"就进去了。默认最多 3 轮,需要更多/更少可以加一句"最多 N 轮"(对应 `max_rounds` 参数)。
290
290
 
291
291
  **Q: 自动修复会改我的代码吗?**
292
292
 
@@ -298,7 +298,7 @@ A: Fix(白盒分析 + 改代码)约 5-10 分钟,Build(编译)约 2-5
298
298
 
299
299
  **Q: 什么情况下循环会停?**
300
300
 
301
- A: 正常退出 3 种:① 全部通过(`all_passed`);② 所有失败都是误报,无代码缺陷需要修复(`no_confirmed_defects`);③ 跑满 `max-rounds` 轮(默认 3)仍有失败(`max_rounds_reached`)。异常退出 3 种:编译未产出签名 HAP(`no_signed_hap`);`testcases.json` 为空(`no_testcases`);自测 agent 早退,写出首行 `status: FAIL` 的 sentinel 报告(`agent_early_exit`,常见原因:设备没连、api_key 没填、batch 崩溃 / 超时)。异常退出不会进入 fix 循环——那些是环境问题,不是代码缺陷。
301
+ A: 正常退出 3 种:① 全部通过(`all_passed`);② 所有失败都是误报,无代码缺陷需要修复(`no_confirmed_defects`);③ 跑满 `max_rounds` 轮(默认 3)仍有失败(`max_rounds_reached`)。异常退出 3 种:编译未产出签名 HAP(`no_signed_hap`);`testcases.json` 为空(`no_testcases`);自测 agent 早退,写出首行 `status: FAIL` 的 sentinel 报告(`agent_early_exit`,常见原因:设备没连、api_key 没填、batch 崩溃 / 超时)。异常退出不会进入 fix 循环——那些是环境问题,不是代码缺陷。
302
302
 
303
303
  **Q: 需要提供 Android 项目路径吗?**
304
304