@ohos-cpf/3rdloop 0.0.4 → 0.0.6

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 (47) hide show
  1. package/README.md +119 -128
  2. package/lib/cli.js +25 -0
  3. package/lib/serve.js +280 -0
  4. package/lib/update.js +46 -6
  5. package/lib/web-ext.js +454 -0
  6. package/lib/web.js +664 -0
  7. package/package.json +2 -1
  8. package/vendor/Server/CLI/opencode/index.js +2 -2
  9. package/vendor/Server/DbUse/StorageManager.js +7 -1
  10. package/vendor/Server/Routes/controllers/FlexRunnerController.js +92 -0
  11. package/vendor/Server/Routes/routes/flexrunner.js +2 -0
  12. package/vendor/Server/Skills/arkts-code-use/SKILL.md +270 -0
  13. package/vendor/Server/Skills/arkts-code-use/assets/TEMPLATES.md +367 -0
  14. package/vendor/Server/Skills/arkts-code-use/references/API_VERIFICATION.md +144 -0
  15. package/vendor/Server/Skills/arkts-code-use/references/ARKTS_RULES.md +240 -0
  16. package/vendor/Server/Skills/arkts-code-use/references/CODE_PATTERNS.md +431 -0
  17. package/vendor/Server/Skills/arkts-code-use/references/SYNTAX_CHECK_GUIDE.md +164 -0
  18. package/vendor/Server/Skills/arkts-code-use/scripts/verify-arkts.cjs +428 -0
  19. package/vendor/Server/Skills/gitcode-repo-fork/SKILL.md +310 -0
  20. package/vendor/Server/Skills/gitcode-repo-fork/assets/FORK_REPORT_TEMPLATE.md +113 -0
  21. package/vendor/Server/Skills/gitcode-repo-fork/references/FORK_DECISION_GUIDE.md +124 -0
  22. package/vendor/Server/Skills/gitcode-repo-fork/references/GITCODE_FORK_API.md +95 -0
  23. package/vendor/Server/Skills/gitcode-repo-fork/scripts/gitcode-fork.cjs +285 -0
  24. package/vendor/VERSION +3 -3
  25. package/web/css/arktslibrarycheck.css +322 -0
  26. package/web/css/codecheck.css +464 -0
  27. package/web/css/flutterlibrarycheck.css +322 -0
  28. package/web/css/knowledge.css +332 -0
  29. package/web/css/loop.css +578 -0
  30. package/web/css/md-reader.css +240 -0
  31. package/web/css/rnlibrarycheck.css +322 -0
  32. package/web/css/theme.css +702 -0
  33. package/web/index.html +713 -0
  34. package/web/js/arktslibrarycheck.js +1495 -0
  35. package/web/js/codecheck.js +1098 -0
  36. package/web/js/flutterlibrarycheck.js +1447 -0
  37. package/web/js/health.js +69 -0
  38. package/web/js/knowledge.js +358 -0
  39. package/web/js/loop.js +1102 -0
  40. package/web/js/md-reader.js +435 -0
  41. package/web/js/navigation.js +238 -0
  42. package/web/js/rnlibrarycheck.js +1462 -0
  43. package/web/js/stats.js +110 -0
  44. package/web/js/theme.js +46 -0
  45. package/web/js/utils.js +228 -0
  46. package/web/knowledge.html +146 -0
  47. package/web/loop.html +219 -0
@@ -388,7 +388,7 @@ class OpenCodeCLI {
388
388
  try {
389
389
  statusMap = await this.client.session.status({ query: {} });
390
390
  } catch (e) {
391
- this._log('warn', `checkSessionStatus: session.status() 失败,降级为拉消息: ${e.message}`);
391
+ this._log('debug', `checkSessionStatus: session.status() 失败,降级为拉消息: ${e.message}`);
392
392
  }
393
393
  const rawStatus = statusMap?.data?.[sessionId];
394
394
  if (rawStatus && (rawStatus.type === 'busy' || rawStatus.type === 'retry')) {
@@ -487,7 +487,7 @@ class OpenCodeCLI {
487
487
  hasNewMessage: !!checkRes.hasNewMessage
488
488
  };
489
489
  } catch (error) {
490
- this._log('warn', `checkSessionStatus 异常 id=${sessionId}: ${error.message}`);
490
+ this._log('debug', `checkSessionStatus 异常 id=${sessionId}: ${error.message}`);
491
491
  return { status: 'unknown' };
492
492
  }
493
493
  }
@@ -1,4 +1,4 @@
1
- import { join, dirname } from 'node:path';
1
+ import { join, dirname, resolve } from 'node:path';
2
2
  import { fileURLToPath } from 'node:url';
3
3
 
4
4
  import JsonAdapter from './adapters/JsonAdapter.js';
@@ -36,6 +36,12 @@ class StorageManager {
36
36
  constructor(options = {}) {
37
37
  if (options.rootDir) {
38
38
  this.rootDir = options.rootDir;
39
+ } else if (process.env['3LIB_DATA_DIR']) {
40
+ // CLI 数据目录策略(与 WEB_STATS_ROOT 同模式):
41
+ // 3rdloop serve/run 等命令将解析后的数据目录注入 env,
42
+ // 使内部所有自建 createStorage()(FlexRunner/KnowledgeManager/
43
+ // MessageArchive 等)统一落到用户数据目录,而非模块相对路径。
44
+ this.rootDir = resolve(process.env['3LIB_DATA_DIR']);
39
45
  } else {
40
46
  // 本文件 (Server/DbUse/) 上溯 3 层到 workspace 根 → db/
41
47
  const here = dirname(fileURLToPath(import.meta.url));
@@ -776,6 +776,77 @@ class FlexRunnerController {
776
776
  }
777
777
  }
778
778
 
779
+ /**
780
+ * POST /api/flexrunner/clean-source
781
+ * 删除任务目录下的源码克隆目录({taskDir}/source/),释放存储空间。
782
+ *
783
+ * 仓库检视(ArkTS/Flutter/RN)与 PR 代码检视(arkts/flutter/rn-code-check)均把
784
+ * 仓库源码克隆到任务目录的 source/ 固定路径;检视结束后源码不再被引用
785
+ * (检视报告 .md、meta .json、orchestration.json 等过程文件均在 taskDir 根目录),
786
+ * 由前端在任务终态时调用本接口清理。
787
+ *
788
+ * 安全约束:
789
+ * - 只删除固定子目录名 source(不接受任意路径参数,防误删报告/过程文件)
790
+ * - taskDir 经 _resolveTaskDir 解析(内存实例 → 编排元信息 → 磁盘白名单兜底)
791
+ * - 内存中编排器仍有步骤执行(pending/ready/running)时拒绝清理
792
+ * - source/ 不存在时幂等返回 cleaned=false(如 tpc-cpp-check 不克隆源码)
793
+ *
794
+ * Body: { taskId }
795
+ */
796
+ async cleanSource(req, res) {
797
+ const body = req.body || {};
798
+ const { taskId } = body;
799
+ if (!taskId) {
800
+ return res.error(400, 'taskId 为必填项');
801
+ }
802
+
803
+ try {
804
+ // 活跃任务保护:内存中编排器仍有步骤在执行时拒绝(防止误删执行中正在使用的源码)
805
+ if (this._orchestratorController) {
806
+ try {
807
+ const steps = this._orchestratorController.getTaskSteps(taskId);
808
+ const active = steps.some(s =>
809
+ ['pending', 'ready', 'running'].includes(String(s.status || '').toLowerCase()));
810
+ if (active) {
811
+ return res.error(409, '任务仍在执行中,暂不能清理源码');
812
+ }
813
+ } catch { /* 内存无实例(已结束 / 重启后磁盘恢复)→ 继续清理 */ }
814
+ }
815
+
816
+ const taskDir = await this._resolveTaskDir(taskId);
817
+ if (!taskDir) {
818
+ return res.error(404, `未找到任务目录: taskId=${taskId}`);
819
+ }
820
+
821
+ const sourceDir = path.join(taskDir, 'source');
822
+
823
+ let st = null;
824
+ try { st = await fs.stat(sourceDir); } catch { /* 目录不存在 */ }
825
+ if (!st || !st.isDirectory()) {
826
+ return res.json({
827
+ status: 'ok',
828
+ cleaned: false,
829
+ freedBytes: 0,
830
+ message: '任务目录下无源码目录(source/ 不存在),无需清理',
831
+ });
832
+ }
833
+
834
+ // 统计释放空间(统计失败不阻塞删除,按 0 返回)
835
+ const freedBytes = await this._dirSize(sourceDir).catch(() => 0);
836
+ await fs.rm(sourceDir, { recursive: true, force: true });
837
+
838
+ res.json({
839
+ status: 'ok',
840
+ cleaned: true,
841
+ freedBytes,
842
+ path: sourceDir,
843
+ message: '已删除源码目录 source/,报告与过程文件保留',
844
+ });
845
+ } catch (err) {
846
+ res.error(500, `源码清理失败: ${err.message}`);
847
+ }
848
+ }
849
+
779
850
  /**
780
851
  * 解析任务工作目录(供 archive 打包等场景使用)。
781
852
  *
@@ -823,6 +894,27 @@ class FlexRunnerController {
823
894
  return null;
824
895
  }
825
896
 
897
+ /**
898
+ * 递归统计目录占用大小(字节)。符号链接不计入(防循环遍历)。
899
+ * @param {string} dir
900
+ * @returns {Promise<number>}
901
+ * @private
902
+ */
903
+ async _dirSize(dir) {
904
+ let total = 0;
905
+ const entries = await fs.readdir(dir, { withFileTypes: true });
906
+ for (const e of entries) {
907
+ const fp = path.join(dir, e.name);
908
+ if (e.isDirectory()) {
909
+ total += await this._dirSize(fp);
910
+ } else if (e.isFile()) {
911
+ const st = await fs.stat(fp).catch(() => null);
912
+ if (st) total += st.size;
913
+ }
914
+ }
915
+ return total;
916
+ }
917
+
826
918
  /**
827
919
  * GET /api/flexrunner/runners
828
920
  * 列出所有已注册的 FlexRunner 实例
@@ -21,6 +21,7 @@ import FlexRunnerController from '../controllers/FlexRunnerController.js';
21
21
  * GET /steps — 列出任务步骤和文件
22
22
  * GET /file — 读取指定文件内容
23
23
  * GET /archive — 打包下载任务目录下全部 .md 报告(ZIP)
24
+ * POST /clean-source — 删除任务目录下源码克隆目录 source/(释放存储,保留报告/过程文件)
24
25
  * GET /runners — 列出所有已注册实例
25
26
  * DELETE /runner — 移除一个实例
26
27
  *
@@ -51,6 +52,7 @@ export function createFlexRunnerRouter(dependencies) {
51
52
  router.get('/steps', controller.steps.bind(controller));
52
53
  router.get('/file', controller.file.bind(controller));
53
54
  router.get('/archive', controller.archive.bind(controller));
55
+ router.post('/clean-source', controller.cleanSource.bind(controller));
54
56
  router.get('/runners', controller.runners.bind(controller));
55
57
 
56
58
  // ── 控制与检查 ──
@@ -0,0 +1,270 @@
1
+ ---
2
+ name: arkts-code-use
3
+ description: 根据需求编写鸿蒙原生 ArkTS 代码(页面/自定义组件/工具类/服务类),严格遵循 ArkTS 语法约束与华为编码规范,先通过官方文档查证 API(import 路径、方法签名、权限、API Level),再使用 deveco-cli(devecocli build / verify-arkts.cjs)编译验证,确保生成代码零语法错误。当需要为鸿蒙应用或三方库编写、补全、重构 ArkTS 代码,或将功能需求转化为符合规范的 ArkTS 实现时使用。
4
+ license: Apache-2.0
5
+ compatibility: 需要 Node.js、deveco-cli(devecocli 命令:工程脚手架/编译验证/文档检索)及 DevEco Studio + OHOS SDK 构建环境;可选 MCP Gateway 运行中(script_deveco_docs 文档查证、kb_search 知识库)
6
+ metadata:
7
+ author: LoopEngine
8
+ version: "1.0.0"
9
+ category: code-generation
10
+ ---
11
+
12
+ # ArkTS Code Use — 鸿蒙原生 ArkTS 代码编写
13
+
14
+ 本技能用于**根据需求编写符合规范的鸿蒙原生 ArkTS 代码**。核心流程:理解需求 → 查证 API → 编写代码 → 编译验证 → 交付。
15
+
16
+ > ⚠️ **核心原则:所有生成的代码必须同时满足三条底线——① 零语法错误(必须通过 deveco-cli 编译验证,BUILD SUCCESSFUL);② 符合 ArkTS 语法约束与华为编码规范(禁止 `any`/`ESObject`/动态属性访问等);③ API 使用有据可查(import 路径、签名、权限、API Level 均经官方文档查证,禁止凭记忆臆造 API)。**
17
+
18
+ ---
19
+
20
+ ## 任务参数
21
+
22
+ | 参数 | 类型 | 必填 | 说明 |
23
+ |------|------|------|------|
24
+ | `requirement` | string | ✅ | 功能需求描述(自然语言或接口定义) |
25
+ | `targetProject` | string | ❌ | 目标鸿蒙工程路径。提供则代码写入该工程并在其中验证;不提供则独立生成,用临时工程完成语法验证 |
26
+ | `outputPath` | string | ❌ | 生成文件/目录位置。默认:有工程时为工程内对应模块目录;无工程时为当前工作目录 |
27
+ | `apiLevel` | number | ❌ | 目标 API Level(默认取工程 `build-profile.json5` 配置;独立生成时默认 12+) |
28
+ | `codeType` | string | ❌ | 代码类型提示:`page`(页面)/ `component`(自定义组件)/ `util`(工具类)/ `service`(业务服务类)。不提供则从需求推断 |
29
+
30
+ ---
31
+
32
+ ## 输入依赖
33
+
34
+ 无前置SKILL。可作为独立任务调用。若需求涉及已有工程,需目标工程可访问且结构完整(含 `build-profile.json5`)。
35
+
36
+ ---
37
+
38
+ ## 工作流程概览
39
+
40
+ ```
41
+ Phase 1: 需求理解与场景识别
42
+
43
+ Phase 2: API 查证(官方文档)
44
+
45
+ Phase 3: 代码编写(遵循 ArkTS 约束与编码规范)
46
+
47
+ Phase 4: 编译验证与修复循环(deveco-cli)
48
+
49
+ Phase 5: 规范自检与交付
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Phase 1:需求理解与场景识别
55
+
56
+ ### 1.1 解析需求
57
+
58
+ 从 `requirement` 中提取:
59
+ - **功能点列表**:拆分为可实现、可验证的具体功能点
60
+ - **代码类型**:`page` / `component` / `util` / `service`(依据 `codeType` 参数或推断)
61
+ - **技术领域**:网络 / 存储 / UI / 多媒体 / 硬件 / 加密 / 并发等(用于 Phase 2 检索)
62
+ - **涉及的系统资源**:HTTP 连接、文件句柄、订阅、Timer、Worker 等(用于 Phase 3 资源管理设计)
63
+
64
+ ### 1.2 探查目标工程(如提供 `targetProject`)
65
+
66
+ ```
67
+ 1. 列出工程根目录,识别 entry/、library/ 等模块
68
+ 2. 读取 build-profile.json5,确认 compatibleSdkVersion / 编译 SDK 版本(即目标 API Level)
69
+ 3. 读取目标模块 src/main/ets/ 现有源文件与 index.ets 导出,了解代码惯例
70
+ 4. 读取 module.json5,了解已声明权限
71
+ 5. 若新增页面,确认 src/main/resources/base/profile/main_pages.json 的注册方式
72
+ ```
73
+
74
+ > 无 `targetProject` 时跳过本步,采用独立生成模式(Phase 4.2 临时工程验证)。
75
+
76
+ ### 1.3 明确交付边界
77
+
78
+ | 场景 | 处理方式 |
79
+ |------|---------|
80
+ | 需求可实现 | 进入 Phase 2 |
81
+ | 需求依赖设备能力(蓝牙/NFC等) | 代码中加 `canIUse()` 守卫,缺能力时降级 |
82
+ | 需求依赖不存在的系统 API | 明确告知用户不可行及原因,提供最接近的替代方案 |
83
+
84
+ ---
85
+
86
+ ## Phase 2:API 查证(官方文档)
87
+
88
+ > **目标:所有系统 API 的 import 路径、方法签名、参数/返回值、权限、API Level 必须有据可查,禁止凭记忆臆造。**
89
+
90
+ ### 2.1 查证工具(按优先级)
91
+
92
+ | 优先级 | 工具 | 适用 |
93
+ |--------|------|------|
94
+ | 1 | MCP Gateway `script_deveco_docs`(action=search / read) | MCP 可用时,检索+精读 HarmonyOS 官方 API 参考 |
95
+ | 2 | `devecocli docs search <关键词>` / `devecocli docs read <documentId>` | 终端直接查证 |
96
+ | 3 | MCP Gateway `kb_search` / `kb-server_search_knowledge` | 补充最佳实践、平台陷阱等经验知识 |
97
+
98
+ ### 2.2 查证要点(每个用到的系统 API 均须确认)
99
+
100
+ | 查证项 | 说明 |
101
+ |--------|------|
102
+ | import 路径 | `@ohos.*` 模块名或 `@kit.*`(优先 Kit 聚合导入) |
103
+ | 方法签名 | 参数名、类型、可选性、返回值/Promise/callback 形式 |
104
+ | 权限 | 是否需在 `module.json5` 声明 `ohos.permission.*`,是否运行时申请 |
105
+ | API Level | `since` 版本;高于目标 API Level 时须加版本守卫或换用旧接口 |
106
+ | 废弃标注 | `deprecated` 接口禁止使用,查替代方案 |
107
+
108
+ > 查证工具的调用参数、领域关键词速查表、三步查询法参见 [API 查证指南](references/API_VERIFICATION.md)。
109
+
110
+ ### 2.3 输出查证结论
111
+
112
+ 以表格形式记录(作为 Phase 3 编写依据):
113
+
114
+ | 功能点 | API(import 路径) | 关键签名 | 权限 | since | 结论 |
115
+ |--------|-------------------|---------|------|-------|------|
116
+ | ... | ... | ... | ... | ... | ✅ 可用 / ⚠️ 需守卫 / ❌ 不可用 |
117
+
118
+ ---
119
+
120
+ ## Phase 3:代码编写
121
+
122
+ > 📐 本阶段生成的全部代码须符合华为 ArkTS 编程规范与 ArkTS 语法约束。
123
+
124
+ ### 3.1 强制约束(编译必查)
125
+
126
+ 核心禁止项(完整清单与修复方案见 [ArkTS 规范与约束](references/ARKTS_RULES.md)):
127
+
128
+ - 禁止 `any`、`unknown`、`ESObject`、`Object` 作通用类型 → 改用具体类型或泛型 `T`
129
+ - 禁止动态属性访问 `obj['key']` → 类型安全访问
130
+ - 禁止内联匿名对象类型 / 未类型化对象字面量 → 定义命名 `interface` 或 `class`
131
+ - 禁止 `prototype` 扩展、`delete` 运算符、`arguments` 对象、`for...in`、`eval()`
132
+ - 禁止 `catch (e)` 中直接 `throw e`(`arkts-limited-throw`)→ 封装为 `Error` 实例后抛出
133
+ - 禁止结构型类型匹配 → 使用显式 `interface` 继承或 `class implements`
134
+ - 禁止在主线程执行阻塞操作 → `async/await + Promise` 或 `taskpool`
135
+
136
+ ### 3.2 编码规范
137
+
138
+ - **命名**:PascalCase 类/接口/枚举/struct,camelCase 方法/变量,UPPER_SNAKE_CASE 常量
139
+ - **格式**:2 空格缩进、行尾分号、单文件 ≤ 400 行(超过拆分)
140
+ - **类型**:所有变量/参数/返回值显式标注类型;公共类型必须 `export`
141
+ - **日志**:功能模块使用 `hilog`,敏感数据用 `%{private}s`
142
+ - **资源管理**:`create/open/on/connect` 类资源必须存在对称的 `destroy/close/off/disconnect` 释放路径,置于 `try/finally` 或组件销毁回调
143
+
144
+ ### 3.3 按代码类型选择模板
145
+
146
+ 按 Phase 1.1 识别的类型,从 [代码模板](assets/TEMPLATES.md) 选取对应模板起步:
147
+
148
+ | 代码类型 | 模板 | 要点 |
149
+ |---------|------|------|
150
+ | `page` | @Entry 页面模板 | 注册到 main_pages.json;aboutToDisappear 清理资源 |
151
+ | `component` | @Component 模板 | @Prop/@Link/@Builder 状态管理;通用 UI 单位用 vp/fp |
152
+ | `util` | 工具类模板 | 静态方法或单例;无状态依赖 |
153
+ | `service` | 业务服务类模板 | 状态机 + async 方法 + hilog + 资源生命周期 |
154
+
155
+ ### 3.4 采用成熟代码模式
156
+
157
+ 异步封装、taskpool 并发、BusinessError 错误处理、事件订阅、权限申请、HTTP/文件资源清理等标准写法,参见 [ArkTS 代码模式](references/CODE_PATTERNS.md)。
158
+
159
+ ### 3.5 落盘规则
160
+
161
+ - 有 `targetProject`:新文件放入目标模块 `src/main/ets/` 对应子目录(pages/components/utils/service);新导出同步到 `index.ets`;新页面注册到 `main_pages.json`;新权限写入 `module.json5`
162
+ - 无 `targetProject`:输出到 `outputPath`(或当前目录),保持单文件自包含或按 `utils/`、`components/` 子目录组织,相对导入路径正确
163
+
164
+ ---
165
+
166
+ ## Phase 4:编译验证与修复循环(deveco-cli)
167
+
168
+ > **目标:BUILD SUCCESSFUL 是交付的硬性前置条件。仅有 lint 通过或"看起来没问题"不算通过。**
169
+
170
+ > ⚠️ **验证机制**:hvigor 只编译**构建图可达**的文件(被页面/入口 import 链引用的文件)。未被引用的 .ets 文件不参与编译,不报错——因此验证前必须确保新代码已接入 import 链(或使用 verify-arkts.cjs 自动接线)。详细说明参见 [语法验证指南](references/SYNTAX_CHECK_GUIDE.md)。
171
+
172
+ ### 4.1 工程模式(提供了 targetProject)
173
+
174
+ ```
175
+ 1. 确认新代码已接入构建图:
176
+ - 新页面:文件在 pages/ 下且已注册 main_pages.json
177
+ - 新类/组件:已被页面 import(直接或经由 index.ets)
178
+ 2. 执行:devecocli build(在 targetProject 目录下)
179
+ 3. 解析输出,只处理 ERROR(WARNING 记录但不阻断)
180
+ 4. 按错误码修复 → 重新构建,循环直到 BUILD SUCCESSFUL
181
+ ```
182
+
183
+ ### 4.2 独立模式(无 targetProject)
184
+
185
+ 使用本SKILL自带脚本自动完成"脚手架临时工程 → 接线 import → 编译验证 → 回显错误":
186
+
187
+ ```bash
188
+ node {本SKILL目录}/scripts/verify-arkts.cjs --files <生成的.ets文件...> [--work-dir <目录>] [--keep]
189
+ ```
190
+
191
+ 脚本行为:自动 `devecocli create` 临时工程 → 将文件复制到 `entry/src/main/ets/verify/` 并在入口页生成 side-effect import 接入构建图 → `devecocli build` → 将错误按 `规则 (文件:行:列)` 回显并映射回源文件 → 清理临时工程(`--keep` 保留)。
192
+
193
+ - 退出码 0 = 验证通过;1 = 存在编译错误;2 = 环境问题
194
+ - 多文件间的相对导入会按原目录结构保留,支持批量验证
195
+
196
+ ### 4.3 错误修复速查
197
+
198
+ | 错误关键词 / 规则 | 修复方案 |
199
+ |-----------------|---------|
200
+ | `arkts-no-any-unknown` | 替换为具体类型或泛型 `T` |
201
+ | `arkts-no-untyped-obj-literals` | 对象字面量须对应显式 class/interface;先声明类型再赋值 |
202
+ | `arkts-no-obj-literals-as-types` | 内联匿名对象类型改为命名 `interface` |
203
+ | `arkts-limited-throw` | `catch (e)` 中改 `throw e instanceof Error ? e : new Error(String(e))` |
204
+ | `arkts-no-dynamic-property` | `obj['key']` 改为 `obj.key` |
205
+ | `arkts-no-structural-typing` | 类型须显式继承/implements,禁止鸭子类型赋值 |
206
+ | `Cannot find module` | 检查 import 路径大小写与相对层级;`@ohos.*` 拼写以文档为准 |
207
+ | `has been deprecated` | 查官方文档替代 API |
208
+ | `Page ... does not exist` | main_pages.json 与实际文件对齐 |
209
+ | `Permission denied` | module.json5 声明权限(Phase 2 已查证的权限清单) |
210
+
211
+ > 完整验证策略、verify-arkts.cjs 参数、`devecocli check lint` / `check compat` 辅助用法参见 [语法验证指南](references/SYNTAX_CHECK_GUIDE.md)。
212
+
213
+ ### 4.4 修复循环纪律
214
+
215
+ ```
216
+ LOOP(上限 5 轮):
217
+ 1. 构建验证(4.1 或 4.2)
218
+ 2. 收集全部 ERROR(一次修复全部已知错误,避免逐个重跑)
219
+ 3. 按速查表修复;速查表未覆盖的错误用 script_deveco_docs 查证 API 正确用法
220
+ 4. 重新验证
221
+ 5. BUILD SUCCESSFUL → 进入 Phase 5
222
+ 超过 5 轮未通过:停止并向用户报告当前错误清单与已尝试方案
223
+ ```
224
+
225
+ ---
226
+
227
+ ## Phase 5:规范自检与交付
228
+
229
+ ### 5.1 交付前自查清单
230
+
231
+ **编译与正确性**
232
+ - [ ] `devecocli build` 输出 `BUILD SUCCESSFUL`(工程模式)或 verify-arkts.cjs 退出码 0(独立模式)
233
+ - [ ] 新代码已接入构建图(import 链可达 / 页面已注册)
234
+ - [ ] 所有系统 API 均经文档查证,无臆造 API,无 deprecated 接口
235
+
236
+ **ArkTS 约束**
237
+ - [ ] 无 `any` / `unknown` / `ESObject` / `Object` 通用类型;无 `as unknown as T` 双重转型
238
+ - [ ] 无动态属性访问、内联匿名类型、`prototype` 扩展、`delete`、`arguments`、`for...in`、`eval`
239
+ - [ ] `catch (e)` 重抛已封装为 `Error` 实例
240
+ - [ ] 耗时操作使用 `async/await` 或 `taskpool`,主线程无阻塞调用
241
+
242
+ **编码规范**
243
+ - [ ] 命名(PascalCase/camelCase/UPPER_SNAKE_CASE)、2 空格缩进、行尾分号
244
+ - [ ] 所有变量/参数/返回值显式类型标注;公共类型已 export
245
+ - [ ] 功能模块有 hilog 日志,敏感数据使用 `%{private}s`
246
+
247
+ **资源与安全**
248
+ - [ ] `create/open/on/connect` 类资源均有对称释放(`try/finally` 或 `aboutToDisappear`)
249
+ - [ ] 外部输入已校验;SQL 参数化;文件路径校验沙箱边界
250
+ - [ ] since > 目标 API Level 的接口有 `canIUse()` / `deviceInfo.sdkApiVersion` 守卫;硬件能力先检测再调用
251
+ - [ ] 所需权限已在 module.json5 声明(工程模式)
252
+
253
+ ### 5.2 输出交付物
254
+
255
+ - 生成的 .ets 源文件(含新建/修改的 index.ets、main_pages.json、module.json5 变更说明)
256
+ - API 查证结论表(Phase 2.3)
257
+ - 验证结果:构建命令、最终状态(BUILD SUCCESSFUL / 退出码)、验证模式(工程/独立临时工程)
258
+ - 未实现或降级处理的功能点说明(如有)
259
+
260
+ ---
261
+
262
+ ## 参考资料
263
+
264
+ - [ArkTS 规范与约束](references/ARKTS_RULES.md) — 禁止项完整清单(错误码+修复方案)、类型系统约束、命名与格式规范、日志规范
265
+ - [ArkTS 代码模式](references/CODE_PATTERNS.md) — 异步/taskpool 并发、BusinessError 错误处理、事件订阅、权限申请、资源生命周期管理、UI 状态管理模式
266
+ - [API 查证指南](references/API_VERIFICATION.md) — script_deveco_docs / devecocli docs 用法、领域关键词速查、API Level 对照、三步查询法
267
+ - [语法验证指南](references/SYNTAX_CHECK_GUIDE.md) — 构建图可达性机制、verify-arkts.cjs 完整用法、错误输出解析、check lint / check compat 辅助检查
268
+ - [代码模板](assets/TEMPLATES.md) — 页面/自定义组件/工具类/服务类标准模板
269
+ - [华为 ArkTS 编程规范](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-coding-style-guide) — 官方编码标准
270
+ - [ArkTS 语法约束(TypeScript 到 ArkTS 适配)](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/typescript-to-arkts-migration-guide) — 官方语法约束说明