@microi.net/cli 4.9.6 → 4.9.7

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 (93) hide show
  1. package/.codebuddy-plugin/marketplace.json +2 -2
  2. package/.codebuddy-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/.workbuddy-plugin/marketplace.json +2 -2
  5. package/.workbuddy-plugin/plugin.json +1 -1
  6. package/assets/build-meta.json +6 -5
  7. package/package.json +1 -1
  8. package/scripts/mcp-server.js +83 -83
  9. package/scripts/microi-cli.js +55 -85
  10. package/scripts/microi-codex-broker.js +418 -0
  11. package/scripts/microi-codex-router.js +129 -65
  12. package/scripts/microi-skills.meta.json +310 -151
  13. package/skills/.microi-skills-version.json +2 -2
  14. package/skills/.progressive-disclosure-manifest.json +3566 -0
  15. package/skills/ai-platform-governance/SKILL.md +21 -166
  16. package/skills/ai-platform-governance/references/progressive-01-/345/212/237/350/203/275/345/274/200/345/205/263.md +190 -0
  17. package/skills/microi-client-frontend/SKILL.md +17 -434
  18. package/skills/microi-client-frontend/references/progressive-01-3-/345/212/250/346/200/201/346/214/211/351/222/256/347/263/273/347/273/237.md +144 -0
  19. package/skills/microi-client-frontend/references/progressive-02-8-/350/277/220/350/241/214/346/227/266/351/253/230/351/242/221/345/235/221/345/244/215/347/233/230.md +178 -0
  20. package/skills/microi-client-frontend/references/progressive-03-vue3-/345/211/215/347/253/257/345/276/256/346/234/215/345/212/241/345/256/277/344/270/273/350/247/204/345/210/231.md +144 -0
  21. package/skills/microi-db-schema/SKILL.md +3 -3
  22. package/skills/microi-db-schema/references/schema-overview.md +1 -1
  23. package/skills/microi-db-schema/references/schema.md +1 -1
  24. package/skills/microi-db-schema/references/table-catalog.md +1 -1
  25. package/skills/microi-form-engine/SKILL.md +1 -1
  26. package/skills/microi-form-layout/SKILL.md +19 -225
  27. package/skills/microi-form-layout/references/progressive-01-3-/344/270/211/347/247/215/345/210/206/347/273/204/347/232/204/345/255/230/345/202/250/344/270/216/351/205/215/347/275/256.md +235 -0
  28. package/skills/microi-frontend-sdk/SKILL.md +17 -151
  29. package/skills/microi-frontend-sdk/references/progressive-01-token-/345/275/223/345/211/215/347/231/273/345/275/225/347/224/250/346/210/267/344/270/216/345/275/223/345/211/215/347/273/210/347/253/257/347/231/273/345/275/225/345/215/217/350/256/256.md +171 -0
  30. package/skills/microi-mobile-app-quality/SKILL.md +22 -288
  31. package/skills/microi-mobile-app-quality/references/progressive-01-4-/351/207/215/350/246/201/346/214/211/351/222/256/345/277/205/351/241/273/345/270/246/345/233/276/346/240/207.md +209 -0
  32. package/skills/microi-mobile-app-quality/references/progressive-02-9-/344/270/273/351/242/230/345/210/207/346/215/242/345/277/205/351/241/273/347/234/237/345/256/236/344/270/224/345/205/250/345/261/200/347/224/237/346/225/210.md +117 -0
  33. package/skills/microi-system-delivery/SKILL.md +16 -380
  34. package/skills/microi-system-delivery/references/progressive-01-/346/240/207/345/207/206/345/267/245/344/275/234/346/265/201.md +186 -0
  35. package/skills/microi-system-delivery/references/progressive-02-/350/207/252/345/212/250/345/214/226/346/265/213/350/257/225/345/277/205/351/241/273/350/246/206/347/233/226/347/232/204/345/235/221.md +210 -0
  36. package/skills/microi-ui/SKILL.md +19 -169
  37. package/skills/microi-ui/references/progressive-01-/347/247/273/345/212/250/347/253/257/345/234/272/346/231/257/350/223/235/345/233/276.md +183 -0
  38. package/skills/microi-uniapp-frontend/SKILL.md +26 -335
  39. package/skills/microi-uniapp-frontend/references/progressive-01-/347/247/273/345/212/250/347/253/257/345/210/206/347/261/273-/345/217/214/346/240/217/345/210/227/350/241/250/347/213/254/347/253/213/346/273/232/345/212/250.md +225 -0
  40. package/skills/microi-uniapp-frontend/references/progressive-02-/345/205/263/351/224/256/344/270/232/345/212/241/350/265/204/344/272/247/344/270/215/345/276/227/351/273/230/350/256/244/351/200/211/344/270/255.md +154 -0
  41. package/skills/page-engine/SKILL.md +23 -271
  42. package/skills/page-engine/references/progressive-01-/346/211/200/346/234/211/347/273/204/344/273/266/347/261/273/345/236/213.md +234 -0
  43. package/skills/page-engine/references/progressive-02-/347/211/210/346/234/254/345/216/206/345/217/262-/345/271/266/345/217/221/344/277/235/345/255/230/344/270/216/345/233/236/346/273/232.md +60 -0
  44. package/skills/playwright-e2e/SKILL.md +24 -590
  45. package/skills/playwright-e2e/references/progressive-01-/345/205/250/350/207/252/345/212/250/347/231/273/345/275/225-/345/205/215/351/252/214/350/257/201/347/240/201-/344/275/206/344/270/215/345/205/215/345/257/206/347/240/201-/345/277/205/350/257/273.md +173 -0
  46. package/skills/playwright-e2e/references/progressive-02-/346/226/207/345/255/227/345/257/271/346/257/224/345/272/246/344/270/216/345/217/257/350/257/273/346/200/247/350/207/252/345/212/250/345/214/226/346/243/200/346/237/245-/345/277/205/345/201/232.md +183 -0
  47. package/skills/playwright-e2e/references/progressive-03-microi-helper-/346/250/241/346/235/277.md +221 -0
  48. package/skills/playwright-e2e/references/progressive-04-ci-/345/273/272/350/256/256.md +69 -0
  49. package/skills/scripts/optimize-progressive-disclosure.mjs +204 -0
  50. package/skills/scripts/refresh-progressive-disclosure.mjs +64 -0
  51. package/skills/scripts/validate-progressive-disclosure.mjs +52 -0
  52. package/skills/ui-design/SKILL.md +26 -1461
  53. package/skills/ui-design/references/progressive-01-/351/242/234/350/211/262/344/275/223/347/263/273-css-variables-/346/224/257/346/214/201/344/270/273/351/242/230/345/210/207/346/215/242.md +218 -0
  54. package/skills/ui-design/references/progressive-02-/345/255/227/344/275/223.md +155 -0
  55. package/skills/ui-design/references/progressive-03-/345/212/250/346/225/210/350/247/204/350/214/203-/344/270/260/345/257/214/344/275/206/344/270/215/345/215/241.md +235 -0
  56. package/skills/ui-design/references/progressive-04-/347/273/204/344/273/266/351/243/216/346/240/274/351/200/237/346/237/245.md +152 -0
  57. package/skills/ui-design/references/progressive-05-/347/247/273/345/212/250/347/253/257/344/270/223/347/224/250/350/247/204/350/214/203.md +238 -0
  58. package/skills/ui-design/references/progressive-06-/344/270/273/351/242/230/345/210/207/346/215/242/345/256/236/347/216/260.md +194 -0
  59. package/skills/ui-design/references/progressive-07-/351/200/237/346/237/245-/344/273/216/345/244/264/346/220/255/345/273/272/344/270/200/344/270/252/347/247/273/345/212/250/347/253/257/351/241/265/351/235/242.md +207 -0
  60. package/skills/ui-design/references/progressive-08-/350/241/250/345/215/225/345/210/206/347/273/204/350/247/204/350/214/203-tabs-vs-collapsegroup-/345/274/272/345/210/266.md +142 -0
  61. package/skills/v8-crud-api/SKILL.md +20 -245
  62. package/skills/v8-crud-api/references/progressive-01-/346/237/245/350/257/242/345/210/227/350/241/250-/345/210/206/351/241/265.md +226 -0
  63. package/skills/v8-crud-api/references/progressive-02-where-/346/235/241/344/273/266/350/257/255/346/263/225/351/200/237/346/237/245.md +49 -0
  64. package/skills/v8-export-import/SKILL.md +15 -425
  65. package/skills/v8-export-import/references/progressive-01-excellayout-/351/253/230/347/272/247/350/207/252/347/224/261/345/270/203/345/261/200.md +211 -0
  66. package/skills/v8-export-import/references/progressive-02-powerpoint-/345/257/274/345/207/272.md +202 -0
  67. package/skills/v8-export-import/references/progressive-03-/345/256/211/345/205/250-/346/200/247/350/203/275/346/263/250/346/204/217.md +42 -0
  68. package/skills/v8-file-upload/SKILL.md +16 -354
  69. package/skills/v8-file-upload/references/progressive-01-/345/205/254/346/234/211/346/241/266-vs-/347/247/201/346/234/211/346/241/266.md +227 -0
  70. package/skills/v8-file-upload/references/progressive-02-office-/346/226/207/344/273/266/345/234/250/347/272/277/347/274/226/350/276/221/347/211/210/346/234/254/345/217/267/350/247/204/345/210/231.md +149 -0
  71. package/skills/v8-frontend-events/SKILL.md +19 -205
  72. package/skills/v8-frontend-events/references/progressive-01-/345/210/227/350/241/250/344/272/213/344/273/266.md +219 -0
  73. package/skills/v8-http-integration/SKILL.md +14 -236
  74. package/skills/v8-http-integration/references/progressive-01-get-/350/257/267/346/261/202.md +220 -0
  75. package/skills/v8-http-integration/references/progressive-02-/351/224/231/350/257/257/345/244/204/347/220/206/346/250/241/345/274/217.md +44 -0
  76. package/skills/v8-menu-buttons/SKILL.md +15 -511
  77. package/skills/v8-menu-buttons/references/progressive-01-2-/346/214/211/351/222/256/345/257/271/350/261/241-schema.md +221 -0
  78. package/skills/v8-menu-buttons/references/progressive-02-8-/346/250/241/345/274/217-f-/345/220/216/345/217/260/344/273/273/345/212/241/346/214/211/351/222/256-/351/225/277/344/273/273/345/212/241.md +224 -0
  79. package/skills/v8-menu-buttons/references/progressive-03-10-/345/217/215/346/250/241/345/274/217-/351/201/277/345/205/215.md +104 -0
  80. package/skills/v8-mq-mqtt/SKILL.md +11 -175
  81. package/skills/v8-mq-mqtt/references/progressive-01-v8-mqtt-iot-/347/211/251/350/201/224/347/275/221.md +181 -0
  82. package/skills/v8-security/SKILL.md +16 -329
  83. package/skills/v8-security/references/progressive-01-2-/346/235/203/351/231/220/346/240/241/351/252/214.md +199 -0
  84. package/skills/v8-security/references/progressive-02-7-/346/227/245/345/277/227/350/256/260/345/275/225.md +158 -0
  85. package/skills/v8-table-event/SKILL.md +16 -236
  86. package/skills/v8-table-event/references/progressive-01-informv8-js-/350/241/250/345/215/225/346/211/223/345/274/200/344/272/213/344/273/266.md +216 -0
  87. package/skills/v8-table-event/references/progressive-02-/345/211/215/347/253/257/344/272/213/344/273/266/345/220/215-v8-eventname-/345/217/257/350/203/275/347/232/204/345/200/274.md +46 -0
  88. package/skills/v8-workflow/SKILL.md +19 -160
  89. package/skills/v8-workflow/references/progressive-01-/350/212/202/347/202/271/345/274/200/345/247/213-v8-/344/272/213/344/273/266.md +180 -0
  90. package/skills/workspace-conventions/SKILL.md +29 -361
  91. package/skills/workspace-conventions/references/progressive-01-/347/211/210/346/234/254/346/233/264/346/226/260/346/227/245/345/277/227/344/277/235/346/212/244/350/247/204/345/210/231-/345/274/272/345/210/266.md +208 -0
  92. package/skills/workspace-conventions/references/progressive-02-microi-net-api-/346/234/254/345/234/260/345/220/257/345/212/250/347/272/246/345/256/232.md +196 -0
  93. package/skills/workspace-conventions/references/progressive-03-cli-/344/270/216-ide-/346/217/222/344/273/266/351/224/231/347/211/210/345/205/261/345/255/230/347/272/246/345/256/232.md +27 -0
@@ -0,0 +1,208 @@
1
+ # workspace-conventions 详细参考 1
2
+
3
+ > 按需读取;本文件由 SKILL.md 的原章节无损拆分。
4
+
5
+ <!-- microi-progressive:chunk id=workspace-conventions-010 sha256=d4ee69df49b8cba8d6365f485bd44aab8f5fcccc4cc1c8394220af14ff68f83f -->
6
+ ## 版本更新日志保护规则(强制)
7
+
8
+ - 日常功能开发、缺陷修复、测试、普通文档补充、Skill 完善和代码重构期间,不得修改 `microi.doc/docs/doc/about/update-log.md`。
9
+ - 只有用户明确提出“发布版本”“准备发版”“更新版本日志”或直接点名要求修改该文件时,才允许编辑更新日志;“完善文档”或“补充官网说明”不等于授权修改版本日志。
10
+ - 如果本轮误改了更新日志,必须先按上节完成多对话归属核验;只撤回有本对话精确写入证据的 hunk。必须保留用户、其它对话或其它任务的已提交和未提交内容,归属不明时不得修改并应询问用户。
11
+
12
+ <!-- /microi-progressive:chunk -->
13
+ <!-- microi-progressive:chunk id=workspace-conventions-011 sha256=8e3904f45392b7c27746de274bbc4725a7eb0964f0aeab1d83918c0174336dc4 -->
14
+ ## 配置文件说明中文优先规则
15
+
16
+ AI 新增或修改 Microi 配置文件时,凡是面向开发者、部署人员或用户阅读的自然语言描述,默认必须写中文。适用范围包括 `appsettings*.json`、`docker-compose*.yml`、`launchSettings.json`、`*.example`、安装脚本注释、部署说明和示例配置。
17
+
18
+ - `Description`、`Important`、`EnvironmentVariables` 的说明文字、JSON/YAML 注释、示例说明、字段说明默认使用中文。
19
+ - 字段名、环境变量名、枚举值、路由、类名、方法名、包名、协议名等标识符保持原始英文,不要为了中文化而破坏程序读取。
20
+ - 如果配置面向海外交付,才可以在中文说明后补充英文括注;不要整段只写英文。
21
+ - 修改配置说明后,必须确认 JSON/YAML 仍可解析,不能因为中文标点或注释方式导致配置文件失效。
22
+
23
+ <!-- /microi-progressive:chunk -->
24
+ <!-- microi-progressive:chunk id=workspace-conventions-012 sha256=f54d1c6d9ce2a86496dbc89d49158fb5efa7501817be350493247bd6bde37f63 -->
25
+ ## 后端 API 配置白名单与 SaaS 单一事实源(强制)
26
+
27
+ - `Microi.net.Api` 的 `AppSettings` 与同名容器环境变量只允许:`OsClient`、`OsClientType`、`OsClientNetwork`、`OsClientDbType`、`OsClientDbConn`、`OsClientRedisHost`、`OsClientRedisPort`、`OsClientRedisPwd`、`OsClientRedisDataBase`、`OsClientDbMongoConn`。
28
+ - 除上述十项外,不得新增 API 业务环境变量或 `AppSettings` 节点。影响整个部署/节点或决定租户基础设施路由的开关、超时、限额、安全策略和密钥进入主控 `sys_osclients`;允许每个子租户自行维护的 OAuth、业务集成和展示设置进入该租户数据库的 `mci_system_setting`。两者都必须提供幂等升级、默认值、缓存刷新、敏感字段脱敏和租户隔离。官方 License 信任链是固定例外:恢复重试次数/间隔使用代码常量,签发私钥固定只读挂载 `/app/microi_private.pem`。禁止新增 `MICROI_*`、`DOS_ORM_*`、额外 `AppSettings` 节点或通用动态环境变量读取。
29
+ - `ASPNETCORE_*`、`DOTNET_*` 是框架宿主配置;`PW_*`、MCP、构建、安装器和发布脚本变量只服务各自工具进程。它们不能成为生产 API 的业务配置入口。
30
+ - 修改后必须用源码测试扫描生产 `.cs`、API `appsettings.json` 及在线/离线 Compose,精确断言十项白名单。不能用注释约定代替自动化守卫。
31
+
32
+ <!-- /microi-progressive:chunk -->
33
+ <!-- microi-progressive:chunk id=workspace-conventions-013 sha256=f71d409558e941597f9d66c10005885e228441df606e97011c798e41f91eff49 -->
34
+ ## 身份、可逆业务秘密与敏感操作统一规范(强制)
35
+
36
+ - DiyToken 是吾码多租户、多终端、V8 和低代码权限体系的唯一会话入口。新增密码、SSO、OAuth、Passkey、人脸或其它登录方式时,验证成功后必须继续签发 DiyToken,并复用现有角色、部门、菜单、表权限、数据范围、终端吊销和 Token 轮换;禁止整体替换为 ASP.NET Identity 或并行建立第二套用户/权限 Token。
37
+ - 登录密码的新存储必须使用后端带盐、可调成本的专用密码哈希。存量 `PwdEncode=DES` 的管理员显示密码只是兼容能力,不得扩展给普通 V8、FormEngine、匿名或访问密钥会话。
38
+ - 业务明确要求再次显示原文的设备口令、第三方业务账号密码等字段,允许使用吾码可逆加密兼容机制。保存只在可信后端加密;列表/导出默认掩码;显示明文走独立授权动作,校验 DiyToken、租户和业务权限,返回 `no-store`,记录不含明文的审计,失焦/超时后清除。
39
+ - DES 是现有兼容格式,不得宣称能抵抗服务器所有者或代码执行者。新高价值秘密优先使用带版本的现代认证加密与集中密钥管理;基础设施密钥仍不得进入可编辑 V8。
40
+ - 登录后的敏感操作优先用 `V8.Identity.Verify` 申请 Passkey、Authenticator TOTP 或严格人脸一次性票据,接口引擎从权威数据重算 `ActionHash` 后调用 `V8.Method.ConsumeIdentityVerificationTicket` 原子消费。票据不能代替菜单/表/行权限、状态机、幂等、事务或审计。
41
+ - Windows Hello、Touch ID、Face ID 和 Android 设备验证优先采用 WebAuthn/Passkey;Microsoft/Google Authenticator 采用标准 TOTP,两者都不增加模型服务。只有服务端严格人脸与活体检测才接入独立 `Microi Face Gateway v1` 云服务或 Docker/集群。完整规范读取 `microi.skills/v8-security/SKILL.md` 与 `microi.doc/docs/doc/more/identity-verification.md`。
42
+ - 外部登录统一在登录页【登录方式】中展示;Gitee、微信、GitHub 等 Provider 只登录个人中心已绑定的吾码用户,最终签发 DiyToken。Provider 固定协议端点,租户自己的 ClientId/ClientSecret 放 `mci_system_setting`,Secret 不进入 `V8.SysConfig.PublicSettings`、普通 V8 或浏览器。
43
+ - 一键安装恢复客户旧库时只允许定位精确主租户三元组;缺失则幂等创建,重复则停止,不能批量重写其它子租户。新主租户行不得持久化数据库、MongoDB 或 Redis 连接,安装器对 MinIO/OCR 等业务配置的后续更新也必须带同一三元组、活动状态条件并做唯一回读。
44
+
45
+ <!-- /microi-progressive:chunk -->
46
+ <!-- microi-progressive:chunk id=workspace-conventions-014 sha256=d17f000dd9548f104277acca846c450066e6979a1e0bfec31879a7ba42deccfe -->
47
+ ## 多语言优先约定
48
+
49
+ Microi 平台默认支持多语言。AI 修改 `Microi.Client`、`Microi.Server`、`Microi-V8-Engine`、MCP 建模数据、菜单按钮、接口引擎或表单 V8 事件时,凡是用户可见文字都必须先考虑多语言,不要把中文提示、按钮名、Tab 名、菜单名、字段名、Toast/Msg 等硬写死后结束任务。
50
+ - 前端框架固定文案优先使用 `$t('Msg.xxx')` 或项目现有 i18n 工具;中文简体、中文繁体、英语作为前端兜底包,其它语言应来自后端 `diy_lang` 缓存/接口返回,不要随意把十几种语言全写死到前端源码。
51
+ - 后端返回给前端的表名、字段名、菜单名、按钮名、Tab 名、错误提示等,优先从 `diy_lang` 缓存取值;没有词条时再返回原文,并异步补齐词条。
52
+ - V8 接口引擎、表单 V8 事件、菜单按钮 V8 若需要返回中文 `Msg`、通知、按钮提示或日志标题,应优先使用 `V8.TranslateEngine.GetLang(key)` / 约定多语言 Key,或至少为后端自动同步留下稳定 Key,不要只写一次性中文字符串。
53
+ - 通过 MCP 创建或维护 `diy_lang` 数据时必须保持树形结构:`系统`、`模块引擎`、`表单引擎`、`业务数据` 等分类。菜单名称归 `模块引擎`;表名、字段名、V8 按钮名、Tab 名归 `表单引擎`;固定框架文案归 `系统`;业务数据默认不写入 `diy_lang`,除非用户明确要求某类业务表进入词库。
54
+ - 不允许把所有多语言映射都创建到 `diy_lang` 根目录。新增词条前先查询是否已有同 Key/同分类数据;写入后需要刷新/回读多语言缓存。
55
+ - 完成多语言相关改动后,至少切换一次目标语言或调用对应接口验证;涉及页面的任务优先用 Playwright 截图确认关键区域没有残留明显中文。
56
+
57
+ <!-- /microi-progressive:chunk -->
58
+ <!-- microi-progressive:chunk id=workspace-conventions-015 sha256=3db1eb06c79e7d3b5158a7fc4992af4848406d892c054699db3f9215849fcab4 -->
59
+ ## 后台菜单层级默认规则
60
+
61
+ AI 通过 MCP、Manifest、V8 或平台 API 创建/修复 Microi 后台菜单时,默认必须规划为至少两级菜单树。真实系统不能把一批 CRUD、报表、日志、设置页直接平铺到根级菜单。
62
+
63
+ - 顶级菜单只放业务域、系统域或产品域父菜单,例如系统引擎、业务中心、运营管理、基础资料等。
64
+ - 具体表单 CRUD、报表、导出、日志、规则、配置、任务页必须挂在对应父级或二级分类下。
65
+ - 同一业务域下超过 3 个叶子模块时,优先再按基础资料、业务执行、配置中心、日志记录、数据产物等通用类别分组。
66
+ - 通过 MCP/Manifest 创建菜单时,必须显式包含父菜单和子菜单关系;叶子菜单必须写入正确 `ParentId`,并在交付说明中列出最终菜单树。
67
+ - 改造已生成菜单时,不能只停留在文档建议。必须回读 `sys_menu`,列出现有菜单、目标父级、`ParentId`/`Sort` 迁移关系,更新管理员角色权限,再次回读验证菜单树深度。
68
+ - 只有表单内嵌子表、隐藏路由、系统内部入口等不应出现在导航中的菜单可以例外隐藏;隐藏菜单必须明确设置 `Display=0`、`AppDisplay=0`,并避免误标为有子级的空父菜单。
69
+
70
+ <!-- /microi-progressive:chunk -->
71
+ <!-- microi-progressive:chunk id=workspace-conventions-016 sha256=ea4975115c96e1968ae32b8f2271b79288f99a35cd8cdbf9de672481f3964521 -->
72
+ ## 后台任务与安全防护约定
73
+
74
+ Microi 平台级长任务和安全防护属于系统能力,AI 修改框架、MCP 或 V8 示例时必须同步考虑:
75
+
76
+ - 应用安装、初始化多语言、批量导入、批量修复、跨系统同步等长任务优先接入后台任务中心,进度通过吾码标准 WebSocket/SignalR 推送,不要默认用前端轮询接口。
77
+ - 菜单按钮可使用 `RunBackground` / `BackgroundTask` / `IsBackgroundTask` 配合 `ApiEngineKey` 启动后台任务;接口引擎内必须用 `V8.Method.UpdateBackgroundTask` 上报进度。
78
+ - 后台任务按钮创建后,平台会向接口引擎参数注入 `_BackgroundTaskId`。V8 代码应读取 `_BackgroundTaskId` / `BackgroundTaskId` / `TaskId`,按真实阶段或处理条数上报 `Current`、`Total`、`Progress`、`Msg` / `Message`。不要写假进度、不要只在结束时写 100%,成功返回 `Code:1` 后由平台统一置为 100%。
79
+ - 后台任务运行态会写入 Redis 并推送通知中心;清除已完成应同时清理内存态和 Redis 态。新增类似能力时要验证刷新页面后任务仍可见、进度百分比正确、完成后可清除。
80
+ - 平台级安全、访问审计、后台任务、运行态监控等系统表统一使用 `mci_` 前缀;普通业务系统表不要使用 `mci_` 前缀,避免与平台能力混淆。
81
+ - 恶意攻击防护只能根据短时间高频、异常状态码爆发、扫描不存在路径、封禁后继续访问等行为判断,不能因为接口执行时间长或排队时间长就封禁用户。
82
+ - 攻击事件、IP 封禁/解封记录应异步写入 MySQL `mci_` 表并写系统日志;同一 IP、同一原因、同一时间窗必须去重合并,不要重复写大量相同失败原因。
83
+ - 手动封禁、手动解封、自动解封都要有审计记录。封禁响应要返回 DosResult 风格 JSON,便于前端明确提示。
84
+
85
+ <!-- /microi-progressive:chunk -->
86
+ <!-- microi-progressive:chunk id=workspace-conventions-017 sha256=f3f2f378b99fc5621ea9a6dd1b924a8db171ca8e55588f6b48d3ac4084306e41 -->
87
+ ## 业务逻辑优先接口引擎约定
88
+
89
+ AI 为 Microi 平台新增或修改任何业务逻辑、后台工具、数据维护能力、官网流程、在线 AI 能力、导入导出、初始化、修复任务、页面配套接口或租户 SaaS 流程时,默认优先使用接口引擎实现,不要直接新增 `Microi.net.Api` Controller 或把业务分支写死到 C# 后端。
90
+
91
+ - 能用 `V8.FormEngine`、`V8.Db`、`V8.Method`、`V8.Http`、`V8.Office`、`V8.ApiEngine` 完成的功能,必须优先建 `sys_apiengine` 接口引擎,并通过前端 `DiyCommon.ApiEngine.Run` 或菜单按钮调用。
92
+ - 需要持久化的数据结构必须优先通过 MCP / Manifest 创建标准低代码表、字段和菜单,让表能在表单引擎中可见、可维护、可授权;不要只在 C# 中 `CREATE TABLE` 物理表。
93
+ - 如果接口引擎缺少底层能力,优先扩展 V8 能力(例如 `V8.Method`、`V8.FormEngine`、HDFS 辅助方法),再让接口引擎调用新增能力;只有跨平台核心框架、协议层、鉴权管线、SignalR/WebSocket、ORM、任务调度内核等接口引擎无法表达的能力,才新增或修改 C# Controller/Service。
94
+ - 新增 C# Controller 前必须能说明为什么不能用接口引擎实现,并在交付说明中列出原因、影响范围和版本升级要求。
95
+ - 从 C# Controller 迁移到接口引擎时,前端不得继续调用旧 `/api/<Controller>/<Action>`;应统一改为 `DiyCommon.ApiEngine.Run('<ApiEngineKey>', params)`,并保留 DosResult 返回格式。
96
+ - 修改 `Microi.Server` 前必须先做四级归类并留下结论:① 现有表单引擎 CRUD/事件能完成;② 现有 V8 接口引擎能完成;③ 只缺一个可复用的底层原子能力,应先扩展 V8 再由接口引擎编排;④ 只有平台协议、可信鉴权、密钥隔离、存储/网络边界或运行时内核才允许直接写 C#。未完成归类不得直接新增 Controller/Service。
97
+ - 第三方回调必须优先采用“C# 最小协议网关 + 应用拥有的 `Managed` 核心接口引擎 + 租户拥有的 `CreateIfMissing` 扩展 Hook”。C# 只验签、解密、校验租户/AppId 和整理脱敏事件;状态、日志、数据写入、通知及业务编排放接口引擎。扩展 Hook 以稳定 `EventId` 幂等,不能因修改业务规则再次发布后端。
98
+ - 第三方平台不支持 QueryString 时使用 `/path--OsClient--{OsClient}--`;支持 Query 时参数名固定为 `?OsClient=`,不得发明 `?o=` 等缩写。路径与 Query 同时出现时必须一致。
99
+ - 第三方 HTTP 集成默认用 `V8.Http` 放在接口引擎;若平台密钥绝不能进入可编辑 V8,只在 C# 暴露最小、租户隔离、不可覆盖密钥的安全原子方法,业务字段选择、状态流转和页面动作仍由接口引擎/表单事件编排。
100
+ - 平台级强制安全校验不能为了“全部低代码化”放进租户可编辑脚本而被绕过;可以留在 C#,但必须是通用、失败关闭的安全边界,不得夹带某个项目的业务文案、字段组合或状态机。
101
+
102
+ <!-- /microi-progressive:chunk -->
103
+ <!-- microi-progressive:chunk id=workspace-conventions-018 sha256=b5ed99d715e5fc5a62d5a9618397f0e40899b400f377dc3fedc41d18d6db73dd -->
104
+ ## 应用商城优先于 Microi.Upgrade(强制)
105
+
106
+ 能由应用包声明、差异安装和回读验收完成的升级,不得在 `Microi.Server/Microi.Upgrade/` 新增定制 .NET 升级类。表、字段、Tab、菜单、角色权限、接口引擎、表单事件、数据源、页面、打印、工作流、任务及可幂等安装的种子数据,默认都属于应用商城资源。
107
+
108
+ - 应用包中的接口引擎必须声明 `ResourcePolicies.ApiEngines`:官方核心使用 `Managed`,租户 Hook 使用 `CreateIfMissing`。`Managed` 以目标端安装记录的上游 SHA-256 为 Base,仅当 `Local == Base` 才升级;本地已改则整包冲突回滚。`CreateIfMissing` 首次创建后永不覆盖,且同一 Key 后续禁止改回 `Managed`;确需收回官方维护时必须发布新 Key 并显式迁移。安全核心禁止自动合并可执行代码,要求把客户差异迁移到 Hook 或人工确认。
109
+ - 吾码官方开发者若可调用绑定 `https://api.itdos.com`、`OsClient=iTdos` 的 `microi_itdos`,必须先在官方主租户通过 MCP 更新资源,重新制作并发布对应官方应用,发布后按字段/菜单/引擎/包版本回读;再用目标租户 MCP 安装/更新并轮询后台任务到 `Succeeded`。
110
+ - 当前用户没有 `microi_itdos` 权限时,通过其自己的 MCP/Manifest 幂等升级自己的数据库并回读;不得为了单个租户把定制迁移塞进通用后端。确需让更多用户复用时,应生成其有权维护的社区/私有应用包。
111
+ - 只有应用商城运行前就必须存在的物理兼容基础、跨版本核心协议迁移、存储格式变化,或安装器自身无法安全表达的不可逆平台迁移,才允许进入 `Microi.Upgrade`。每个例外必须写明“为什么应用包不能完成”、影响范围、回滚/前后兼容、分布式幂等和验收依据。
112
+ - 允许的 .NET 迁移只能按持久化版本/迁移账本执行待办步骤,使用共享租约且业务幂等;禁止把新迁移同时加入版本链和“每次启动无条件全租户对账”列表。启动成本必须与待执行迁移数相关,不能随历史升级文件总数对每个租户线性增长。
113
+ - 评审 `Microi.Upgrade` PR 时先做资源分类:若只是补字段、Tab 或低代码元数据,移出升级器并发布应用包;若保留 C#,必须提供双节点、重复启动、租约丢失、失败不推进版本以及旧新节点共存测试。
114
+
115
+ <!-- /microi-progressive:chunk -->
116
+ <!-- microi-progressive:chunk id=workspace-conventions-019 sha256=333125c854376da9f58b988c0ff2e4e94592de5437107182da838878ceb6b447 -->
117
+ ## 在线 AI 应用上下文默认发现规则(强制)
118
+
119
+ AI 开始处理定制页面、弹窗、Web、UniApp、微服务或应用商城任务时,不能只搜索本地目录。只要当前 MCP 已连接到目标 `OsClient`,必须先读取在线 AI 应用上下文:
120
+
121
+ 1. 调用 `microi_list_applications` 获取当前租户全部 `Web / UniApp / MicroService` 应用和完整文件清单。
122
+ 2. 找到候选应用后调用 `microi_get_application_context`,默认 `includeContents=true`,读取所有可读源码内容以及微服务运行页面。
123
+ 3. 只需核对单个大文件或二进制文件时,再调用 `microi_get_application_file` 精确读取。
124
+ 4. 已存在合适微服务时优先在原应用内新增页面/路由;不存在时才调用 `microi_create_microservice`、`microi_sync_microservice_source`、`microi_publish_microservice` 创建并发布。
125
+
126
+ 三个读取工具的关键参数:
127
+
128
+ | 工具 | 参数 | 说明 |
129
+ |---|---|---|
130
+ | `microi_list_applications` | `appType` | 可选:`Web`、`UniApp`、`MicroService`;省略表示全部类型 |
131
+ | | `keyword` | 可选:按名称、`AppKey`、类型、描述筛选 |
132
+ | | `includeFiles` | 默认 `true`,返回每个应用完整文件清单 |
133
+ | `microi_get_application_context` | `appIdOrKey` | 必填,支持统一应用商城 `sys_microistore.Id` 或 `AppKey` |
134
+ | | `includeContents` | 默认 `true`;读取私有 HDFS 源码内容 |
135
+ | | `maxFileBytes` | 可选,默认单文件 2MB |
136
+ | | `maxTotalBytes` | 可选,默认单应用 50MB |
137
+ | `microi_get_application_file` | `appIdOrKey`、`filePath` | 必填;`filePath` 必须来自文件清单 |
138
+
139
+ 如果 MCP 返回登录过期,必须先修复或刷新目标 MCP 身份,再继续把 MCP 读取结果当作当前事实;不能因为读取失败就假设在线应用不存在并重复创建。
140
+
141
+ <!-- /microi-progressive:chunk -->
142
+ <!-- microi-progressive:chunk id=workspace-conventions-020 sha256=4d3aef6042f7e43be7c2bf61430ce461bfb75bfb853b1ca000b0f5c5836eff7f -->
143
+ ## VS Code 插件空目录生成规则
144
+
145
+ Microi.VSCode 面向普通用户时,用户本地可能只是一个空工作区。插件生成 AI 指令文件时不能假设用户已经有 `microi.skills/`、`Microi-V8-Engine/`、`AI-Project/` 或某个固定前端项目目录。
146
+
147
+ 强制要求:
148
+ - 插件的“初始化AI配置”必须能在空目录生成 `microi.skills/`、`.github/copilot-instructions.md`、`AGENTS.md`、`CLAUDE.md`、`.cursorrules`、`.cursor/rules/microi-skills.mdc`、类型提示、`jsconfig.json` 和 MCP 配置。
149
+ - Cursor rule 的 `globs` 必须覆盖任意新建项目目录下的常见源码、配置和文档文件,例如 `**/*.{vue,js,ts,jsx,tsx,css,scss,json,md,mdc,cs,csproj,xml,yml,yaml}`,不能只覆盖 `Microi-V8-Engine/**/*.js`。
150
+ - 生成文案必须明确:普通用户不需要手动克隆 skills,也不需要每次对 AI 说“严格遵循 microi.skills”;只要插件初始化成功,AI 就应默认按 skills 工作。
151
+ - 插件升级时应继续保护用户本地修改过的 skill 文件,只覆盖插件曾生成且用户未改过的文件。
152
+
153
+ <!-- /microi-progressive:chunk -->
154
+ <!-- microi-progressive:chunk id=workspace-conventions-021 sha256=d6da1a47b1f8ed4b1ea863b052c5e1fa7767e2809c39abe4813ea000d9a30db6 -->
155
+ ## Microi 版本号规则
156
+
157
+ Microi 通用版本号采用 `主版本.次版本.修订版本` 三段数字格式,从 `1.0.0` 开始。每次发布时最后一位加 1;当某一位超过 `9` 时向前一位进位并将当前位归 `0`,例如 `1.0.9 -> 1.1.0`、`1.9.9 -> 2.0.0`、`9.9.9 -> 10.0.0`。
158
+
159
+ 接口引擎代码头、表单/工作流 V8 事件代码头、前端微服务 `sys_microiservice.BuildVersion` 与 `sys_microiservice_page.BuildVersion` 这类业务发布版本统一使用带 `v` 前缀的格式:`v1.0.0 -> v1.0.1 -> v1.0.9 -> v1.1.0 -> v1.9.9 -> v2.0.0 -> v9.9.9 -> v10.0.0`。禁止使用时间戳、随机串或日期作为 BuildVersion;前端微服务上传到分布式存储的目录也必须使用同一个 BuildVersion 分段,便于回溯与 CDN 缓存隔离。
160
+
161
+ `Microi.VSCode` 发布时会通过 `bump-version.js` 自动自增插件版本,并把 `microi.skills/.microi-skills-version.json` 中的 skills 发布版本写成同一个插件版本号;skills 不再独立自增。`.microi-skills-version.json` 只用于记录 skills 包版本和提示用户当前来源,不能单独作为覆盖依据。
162
+
163
+ 插件初始化或升级同步 `microi.skills/` 时,必须以 `.microi-skills-manifest.json` 的逐文件 hash 判断是否可覆盖:本地文件不存在则写入;本地文件与旧 manifest hash 一致说明用户未改,可自动升级;本地文件已被用户修改、或本地版本比插件捆绑版本更新时,必须保留用户版本并提示差异。不能因为插件版本号更高或更低,就粗暴覆盖本地 skills。创始人本地随时修改 skills 的工作区尤其要保护;普通用户未修改过的旧 skills 才应该被最新插件覆盖升级。
164
+
165
+ <!-- /microi-progressive:chunk -->
166
+ <!-- microi-progressive:chunk id=workspace-conventions-022 sha256=709c669676154b9b469feefad4761544a8cb29fba2e050262b26390c1c4e327c -->
167
+ ## C# dynamic 强类型落地规则
168
+
169
+ 后端源码中从 `dynamic`、`JObject`、`ExpandoObject`、表单参数或 `DynamicHelper` 读取出来的值,如果后续要调用字符串方法、扩展方法或参与强类型判断,必须先显式落到强类型变量。不要用 `var` 承接 `DynamicHelper.GetDynamicStringValue(...)` 后再调用 `DosIsNullOrWhiteSpace()` 这类扩展方法,因为调用点可能仍按 dynamic 绑定,运行时会出现 `'string' does not contain a definition for ...`。
170
+
171
+ 错误写法:
172
+
173
+ ```csharp
174
+ var tableName = DynamicHelper.GetDynamicStringValue(diyTableModel, "Name", "");
175
+ if (tableName.DosIsNullOrWhiteSpace()) { return; }
176
+ ```
177
+
178
+ 推荐写法:
179
+
180
+ ```csharp
181
+ string tableName = DynamicHelper.GetDynamicStringValue(diyTableModel, "Name", "");
182
+ if (string.IsNullOrWhiteSpace(tableName)) { return; }
183
+ ```
184
+
185
+ 如果方法内部只通过 `DynamicHelper` 读取对象字段,方法参数优先声明为 `object`,不要声明为 `dynamic`。这样可以减少 C# 运行时动态绑定进入普通字符串工具链的机会。
186
+
187
+ <!-- /microi-progressive:chunk -->
188
+ <!-- microi-progressive:chunk id=workspace-conventions-023 sha256=91feb164525de8824674bd62eae72fc549d64ad253b0551d3504ecb7aba5bf51 -->
189
+ ## 根目录保留文件说明
190
+
191
+ 根目录只允许存在以下类型的文件和目录:
192
+
193
+ | 路径 | 说明 | 是否可删除 |
194
+ |------|------|-----------|
195
+ | `.github/` | GitHub Actions、Copilot 配置 | 否 |
196
+ | `.venv/` | Python 虚拟环境,AI 代理使用 | 否(必要) |
197
+ | `.vscode/` | VS Code 工作区配置 | 否 |
198
+ | `microi.skills/` | 通用技能文档库 | 否 |
199
+ | `Microi.Server/` | .NET 后端 | 否 |
200
+ | `Microi.Client/` | PC 前端 Vue3 | 否 |
201
+ | `microi-v8-engine/` | V8 接口引擎代码 | 否 |
202
+ | `AI-Project/` | 各租户/项目 | 否 |
203
+ | `switch-env.ps1` | 本地环境切换工具 | 否(有用) |
204
+ | `.tmp/` | AI 临时文件(gitignored) | 可删整个目录 |
205
+ | `.microi-e2e/` | Microi.VSCode 插件 E2E 产物 | 可定期清理 |
206
+ | `.microi-performance/` | 性能测试报告 | 可定期清理 |
207
+
208
+ <!-- /microi-progressive:chunk -->
@@ -0,0 +1,196 @@
1
+ # workspace-conventions 详细参考 2
2
+
3
+ > 按需读取;本文件由 SKILL.md 的原章节无损拆分。
4
+
5
+ <!-- microi-progressive:chunk id=workspace-conventions-024 sha256=4e97c278d0a813e23c2c56b11aec8b157b2b100ed6f46ea07d45dbe9954ca5aa -->
6
+ ## Microi.net.Api 本地启动约定
7
+
8
+ 默认本地后端项目是 `Microi.Server/Microi.net.Api/Microi.net.Api.csproj`。AI 需要启动后端、验证接口、跑 Playwright、回读接口引擎或排查前后端联调问题时,优先使用下面的 PowerShell 命令:
9
+
10
+ ```powershell
11
+ Push-Location Microi.Server/Microi.net.Api
12
+ dotnet run --launch-profile Microi.net.Api
13
+ Pop-Location
14
+ ```
15
+
16
+ 必须先进入 `Microi.Server/Microi.net.Api` 再启动。`Program.cs` 会在 `WebApplication.CreateBuilder(args)` 之前读取当前目录下的 `.microi-local`,将其中的环境名写入 `ASPNETCORE_ENVIRONMENT` / `DOTNET_ENVIRONMENT`,随后加载 `appsettings.{环境名}.json`。如果从仓库根目录直接运行并导致配置读取异常,先改用上面的 `Push-Location` 方式。
17
+
18
+ 普通本地启动默认不要额外设置 `ASPNETCORE_ENVIRONMENT` 或 `DOTNET_ENVIRONMENT`;如果这些变量已由 `launchSettings.json`、`launch.json`、终端环境或测试脚本显式设置,`.microi-local` 不会覆盖它们。实际监听地址必须读取 `Microi.Server/Microi.net.Api/Properties/launchSettings.json` 的 `Microi.net.Api` profile;当前标准工作区是后端 `61501`、前端 `61500`,不能继续硬编码历史 `7266/1988`。
19
+
20
+ **本地后端自动重启要求(强制)**:本地联调需要启动或重启 `Microi.net.Api` 时,先检查 `.tmp/microi-process-state/release.lock`;发布锁存在时禁止启动或重启。无发布时先回读标准端口和 `/api/Diagnostics/liveness`,健康服务默认复用;只有本任务修改了需重载的后端代码、服务不健康或用户明确要求重启时,才可精确停止当前工作区的后端进程,然后在 `Microi.Server/Microi.net.Api` 目录执行 `dotnet run --launch-profile Microi.net.Api`。优先使用用户能在 VS Code 中看到和停止的终端(包含 VS Code 集成终端、VS Code 任务终端、用户明确允许的 VS Code 可追踪隐藏终端);如果当前工具没有 VS Code 终端能力,允许使用本机可见的 `cmd`/PowerShell 窗口启动,禁止使用脱离用户可见窗口的后台服务或守护进程。不要误杀数据库、Redis、Node 前端或其它业务进程。
21
+
22
+ <!-- /microi-progressive:chunk -->
23
+ <!-- microi-progressive:chunk id=workspace-conventions-025 sha256=4b9936ad45a2893f4b9c32f3acd7230e4f57cb4314fd67e16d13ce09f368c003 -->
24
+ ## 多 AI 对话共享本地服务与发布互斥(强制)
25
+
26
+ 同一工作区的 4、5 个 AI 对话共用同一份源码和固定端口时,`61500/61501` 是工作区级单例共享服务,不属于某个对话。端口相同意味着无法让每个对话拥有一套独立进程;正确模型是“复用健康服务 + 需要重载时串行重启 + 发布时独占”,不能让每个对话都无条件先杀再启动。
27
+
28
+ - 启动前先检查端口、健康接口、PID、命令行和工作区路径。健康且代码无需重载时直接复用;不得仅为声明“本对话拥有服务”而重启。
29
+ - 长期本地后端必须通过项目目录里的 `dotnet run --launch-profile Microi.net.Api` 使用开发输出。禁止把 `bin/Release/net10.0` 或 `bin/Release/publish` 的 `dotnet Microi.net.Api.dll` 当长期 E2E 服务;运行中的 Release DLL 会让后续 `dotnet build` 报 `MSB3021/MSB3027` 文件锁。
30
+ - 一键编译发布会创建 `.tmp/microi-process-state/release.lock`,并调用 `Microi.Server/tools/Microi.LocalProcessManager.ps1 -Action PrepareRelease`。它只结束命令行和工作区均匹配的 `61501` 后端、`61500` Vite 以及额外 Release 后端,并验证 Release DLL 可独占打开;遇到身份不匹配的端口占用必须停止,不得按进程名全杀。
31
+ - Vite 子进程可能由相对 `node_modules/vite/bin/vite.js` 启动,父 npm/终端退出后命令行不再包含工作区绝对路径。Windows 进程管理器应先匹配命令行绝对路径;无法匹配时只读回读进程 CWD,只有 CWD 精确等于当前工作区 `Microi.Client` 且入口确为 Vite 才可结束。CWD 无法读取、属于其它目录或仅仅“父进程不存在”时必须失败关闭。
32
+ - 发布锁存在期间,所有 AI 自动启动、服务自愈和 Playwright `webServer` 都必须等待或退出,禁止重新抢占 `61500/61501`。发布正常结束或中断时由脚本释放锁;无法证明锁持有者已退出时不得自行删除锁。
33
+ - Edge/Chrome 主浏览器、VS Code 持有的 Playwright Test Server、语言服务和 MCP Node 进程不属于发布文件锁清理范围。浏览器自动化必须关闭本用例创建的 context/browser;不得通过 `taskkill /IM chrome.exe|msedge.exe|node.exe|dotnet.exe` 清空整机进程。
34
+ - 人工盘点使用:`powershell -NoProfile -ExecutionPolicy Bypass -File Microi.Server/tools/Microi.LocalProcessManager.ps1 -Action Status`。需要单独停止当前工作区服务时使用 `-Action StopBackend` 或 `-Action StopFrontend`,不再让用户根据任务管理器猜进程。
35
+
36
+ <!-- /microi-progressive:chunk -->
37
+ <!-- microi-progressive:chunk id=workspace-conventions-026 sha256=73207c0cfcc442a177c47c36503dd6145fc826e23e79df3913861f65d8d16df3 -->
38
+ ## 本地租户与测试凭据读取约定
39
+
40
+ AI 在本地启动后端、跑 Playwright、做登录态页面截图或调用需要登录的接口前,必须先尝试从本地配置判断租户和测试账号,不要直接以“未登录无法测试”结束:
41
+
42
+ 1. 读取 `Microi.Server/Microi.net.Api/.microi-local`,得到当前环境名,例如 `<Environment>`。
43
+ 2. 读取 `Microi.Server/Microi.net.Api/appsettings.<Environment>.json`,或测试脚本传入的 `PW_APPSETTINGS_PATH`。
44
+ 3. 测试账号密码只从用户本轮明确提供、受保护的测试进程变量 `PW_TEST_ACCOUNT` / `PW_TEST_PASSWORD`、CI Secret 或既有安全登录态取得;不得把凭据写入 `appsettings.*.json`、源码或测试报告。
45
+ 4. `MICROI_OSCLIENT`、`PW_OS_CLIENT` 等只属于自动化工具进程,不是 API 生产环境变量;显式设置时可用于选择测试租户。
46
+ 5. `.microi-local`、Token、数据库连接串、Redis 密码和测试凭据都视为本地敏感配置。最终回复、日志摘要和测试报告中不得输出真实值,只能写 `<redacted>`、`本地配置账号` 或 `本地配置凭据`。
47
+
48
+ <!-- /microi-progressive:chunk -->
49
+ <!-- microi-progressive:chunk id=workspace-conventions-027 sha256=84988eac9cf7543a192b3e829b879afb7b35ef92798dc9ea69243f173a8ab674 -->
50
+ ## 自动化登录约定
51
+
52
+ 本地和远端 E2E 统一传真实 `Account` / `Pwd`。需要跳过图形验证码时,只能在目标租户 `sys_config.AutoTestSkipCaptcha=true` 后传 `_AutomationTestLogin=true`;它只跳过验证码,绝不能绕过密码校验。禁止恢复 `DevLoginBypass`、`X-Microi-Dev-Key`、`_DEV_BYPASS_` 或让脚本自动改写后端 `appsettings`。测试完成后不持久化账号密码。
53
+
54
+ <!-- /microi-progressive:chunk -->
55
+ <!-- microi-progressive:chunk id=workspace-conventions-028 sha256=544ab4d52c661e65fb2b0364a3a2107815af366d719f0b1d1cde7b4837226458 -->
56
+ ## V8 远端/本地同步收尾约定
57
+
58
+ AI 通过 MCP、接口引擎、数据库脚本或平台 API 修改任何远端 V8 代码后,任务结束前必须把远端当前生效代码同步回本地 `Microi-V8-Engine/<server>/<osClient>/` 目录,并做一次同步状态复核。
59
+
60
+ 适用范围包括:
61
+ - `sys_apiengine.ApiV8Code` 接口引擎
62
+ - `diy_table` 表单 V8 事件
63
+ - `diy_field` 字段 V8 事件
64
+ - `sys_menu` 模块按钮/Tab V8 代码
65
+ - `wf_node` 工作流节点 V8 代码
66
+ - `sys_datasource` 数据源 V8 代码
67
+
68
+ 收尾流程:
69
+ - 若远端是通过 MCP 写入的,以远端当前生效代码为准回写本地文件。
70
+ - 若本地文件是先手工修改的,先推送到远端,再重新拉取/复核,确保本地与远端一致。
71
+ - 优先使用 Microi.VSCode 插件的同步/查看同步状态能力;没有可调用插件时,可在 `.tmp/` 写一次性同步脚本,但脚本必须先 dry-run 输出差异摘要,再 apply。
72
+ - 复核结果应确认 touched 范围内 `Changed=0`、`Created=0`、`LocalOnly=0` 或说明剩余差异原因。
73
+ - 空 V8 代码不生成本地 `.js` 文件;若已有空 `.js` 文件,收尾同步时应删除,避免被误判为本地未推送。
74
+ - AI 收尾不能只看自写脚本的 dry-run;只要工作区安装了 Microi.VSCode 插件,就必须按插件“查看同步状态”的口径再复核一次。最终回复中要明确说明插件口径是否为 0;若仍有本地未推送/远端差异,必须列出具体资源类型、Key 和本地文件路径,不能只报数量。
75
+ - 当远端代码与本地代码完全一致但插件仍提示“本地未推送”时,优先校准 `.microi-meta.json` 的 `updateTime/filePath` 与本地文件 `mtime`,并再次执行插件口径同步检查;不要让时间戳误差遗留给用户。
76
+ - AI 通过 MCP/API 直接写远端 V8 后,必须立即回读远端当前生效代码到本地并校准 `.microi-meta.json` 与文件 `mtime`。这不是可选清理动作,而是交付完成条件;否则 VS Code 插件会按时间戳继续提示“本地未推送”。
77
+ - 若同步状态非 0,必须先列出具体文件并分类处理:正文一致仅校准 meta/mtime,远端较新则拉回,本地较新则推送,双方都改过则人工合并。生产资金/资产系统不能为清状态盲目覆盖远端。
78
+
79
+ <!-- /microi-progressive:chunk -->
80
+ <!-- microi-progressive:chunk id=workspace-conventions-029 sha256=e90e532f9448b67f98f28a68fd4ea45b79868cf25fc14c5283b9074e91559f27 -->
81
+ ## V8 缓存刷新约定
82
+
83
+ 如果 AI 绕过平台表单提交事件,直接通过 MCP、数据库脚本或自写同步工具更新 `sys_apiengine`、`diy_table`、`diy_field`、`sys_menu`、`wf_node` 等远端 V8 代码,收尾时除了同步本地文件,还必须刷新运行中服务的缓存。至少清理当前 `<OsClient>` 下对应资源的 `Microi:<OsClient>:FormData:<table>:<key>`、`Id` 和地址形式缓存;若可用,优先调用平台缓存接口或插件内置同步流程。清缓存后要重新调用受影响接口做一次真实验证,避免本地/远端代码已一致但 API 仍执行旧缓存代码。
84
+
85
+ <!-- /microi-progressive:chunk -->
86
+ <!-- microi-progressive:chunk id=workspace-conventions-030 sha256=c25d0aaffec64d8a66cda36acd9ec337eda99a4411fddb0e966e45247ba574de -->
87
+ ## MCP 元数据更新验收约定
88
+
89
+ AI 通过 MCP 修改 `diy_field`、`diy_table`、`sys_menu`、`sys_osclients`、`sys_config` 等平台元数据后,不能只看写入返回成功,必须按前端真实消费方式回读验证:
90
+
91
+ 1. 修改 `Select`、`Radio`、`Checkbox`、`MultipleSelect` 等选项组件时,必须回读字段的 `Component`、`Data`、`Config`。已有字段更新时不要假设 `"key|label"` 字符串会被 `microi_update_field` 自动解析;KeyValue 数据源推荐直接把 `Data` 写成 JSON 数组 `[{"Key":"Aliyun","Value":"阿里云机器翻译"}]`,并确保 `Config.DataSource=KeyValue`、`SelectLabel=Value`、`SelectSaveField=Key`。
92
+ 2. 修改字段、表、菜单后,必须调用 `microi_get_field_list` / `microi_get_table_data` 回读关键字段,并调用 `microi_refresh_schema_cache` 或对应清缓存接口刷新 Redis。涉及 SaaS 引擎、系统设置、菜单按钮、接口引擎等运行态缓存时,还要调用对应租户清缓存接口并重新请求受影响页面/API。
93
+ 3. 最终交付说明必须写清楚:改了哪个表/字段,回读值是什么,刷新了哪些缓存,验证入口是什么。若某个缓存刷新接口失败或只能部分成功,需要把失败消息原样摘要出来,不能把“写入成功”当作“页面一定生效”。
94
+
95
+ <!-- /microi-progressive:chunk -->
96
+ <!-- microi-progressive:chunk id=workspace-conventions-031 sha256=3c25a4f5f2571612f6b441e88f4865f916aab0aed3cfe5d06a3be51a736dde0f -->
97
+ ## MCP 可用性排查约定
98
+
99
+ VS Code、Cursor 或 Codex 设置界面显示某个 MCP 服务器“已启用”,不代表当前 AI 会话一定已经成功加载了对应工具。AI 在声称“可以通过 MCP 操作”之前,必须完成一次真实可调用性验证:
100
+
101
+ - 先用当前会话可用的工具发现能力查找目标 MCP 工具;若工具发现为 0,不能继续假设 MCP 可用。
102
+ - 再用 MCP 资源/模板列表或最小 `initialize` / `tools/list` 探测确认服务器握手成功。若返回 `handshaking with MCP server failed`、`initialize response`、`connection closed` 等错误,要明确说明“配置存在但当前会话不可调用”。
103
+ - 同时检查 `.vscode/mcp.json`、`.cursor/mcp.json`、`.mcp.json` 和 `~/.codex/config.toml` 是否能解析,并确认目标服务器名、`MICROI_API_URL`、`MICROI_OS_CLIENT`、`MICROI_TOKEN_FILE` 已写入。
104
+ - 如果手动启动 `mcp-server.js` 能响应,而当前 AI 会话仍握手失败,应优先怀疑 MCP stdio 协议兼容、初始化响应格式/大小、服务器进程提前退出或插件生成的 Codex 配置顺序问题,而不是简单归因于“用户没启用”。
105
+ - 当 MCP 工具数量较多时,`tools/list` 的前段必须优先返回通用建模和维护工具,例如 `microi_get_db_schema`、`microi_get_field_list`、`microi_add_field`、`microi_update_field`、`microi_refresh_schema_cache`、`microi_create_table`、`microi_create_module`、`microi_get_event_code`、`microi_save_event_code`。部分 AI 客户端或模型上下文只注入前若干个工具,若核心工具排在后面,会误报“缺少 MCP 工具”。
106
+ - MCP 的初始化说明必须使用真实 `MICROI_OS_CLIENT` 作为租户边界。中文显示名通过 ASCII 的 `MICROI_LABEL_BASE64` 传输并在 MCP 内解码,旧版 `MICROI_LABEL` 只作兼容;显示名不能当成租户 Key 写入“只能管理某租户”的安全提示。
107
+ - 遇到 `ByteString`、`greater than 255` 或“第 N 个字符无法写入 Header”时,必须先检查实际异常索引和所有 HTTP Header 来源。Microi MCP 的设备标识来自 `did` / `MICROI_MCP_DID`;默认值若直接拼接中文 Windows 主机名,会在 `MCP:` 后第 4 个字符报错。`MICROI_LABEL_BASE64` 只用于显示,不会作为业务 HTTP Header 发送,禁止在未核对调用链前把错误归因于中文 Label。插件和 MCP 必须把 DID 规范化为稳定的可打印 ASCII。
108
+ - MCP 连接失败时,AI 在完成配置、进程、Header、`initialize`、`tools/list` 和只读状态调用的证据链之前,不得修改 Token、租户、服务器地址或执行远端写入。连接恢复后先完成只读基线盘点,再按用户授权开始写入。
109
+ - 修复 Microi.VSCode 插件的 MCP 生成逻辑后,必须重新生成配置、重启对应 MCP server,并在当前 AI 会话中再次验证工具发现与一次只读工具调用。
110
+
111
+ <!-- /microi-progressive:chunk -->
112
+ <!-- microi-progressive:chunk id=workspace-conventions-032 sha256=230c8683389d2b1ee4f5ba88dc4e51cb4dc4eb6a89b76a142b07f479ff5be1c8 -->
113
+ ## MCP 写入超时与降级约定
114
+
115
+ - 写请求超时后的远端回读必须使用独立的短超时,不能继续沿用普通查询的长超时。否则一次 60 秒写超时后,每次回读还可能等待 120 秒,AI 会长期停留在“等待远端回读”,用户误以为菜单按钮或接口引擎完全写不进去。
116
+ - `microi_create_engine` 必须与代码保存、事件保存、菜单更新一样使用写请求超时和远端回读确认。创建响应异常但按 `ApiEngineKey` 回读到相同代码时,返回 `RecoveredAfterTransportError:true`;禁止因超时重复创建同一个接口引擎。
117
+ - 后端创建接口引擎时,数据库新增成功后的路由缓存刷新必须设置硬超时。缓存刷新失败或超时不能把已经成功入库的创建结果伪装成失败,更不能让 HTTP 请求无限等待;响应中应通过 `CacheRefresh` 报告缓存状态。
118
+
119
+ - 接口引擎代码只用 `microi_save_engine_code`,表单事件只用 `microi_save_event_code`,菜单按钮和 Tab 只用 `microi_update_module`。这些标准工具负责版本、校验、缓存和超时回读。
120
+ - 请求超时是“结果不确定”,不是“写入失败”。标准工具返回 `RecoveredAfterTransportError:true` 时,表示已经通过远端回读确认成功,不得再次写入。
121
+ - 标准工具明确返回“回读未确认”时,只调用对应 get 工具继续核对一次。没有用户明确授权,不得改走原生 FormEngine HTTP、直接 SQL、表定义增量更新,也不得创建一次性维护接口引擎绕过原端点。
122
+ - `MoreBtns`、`FormBtns`、`BatchSelectMoreBtns`、`PageTabs`、`ExportMoreBtns`、`PageBtns` 一律向 MCP 传明文 JSON 数组。租户 `sys_menu` 表单事件中的 Base64 解码属于平台内部兼容逻辑,AI 不得据此手工 Base64 编码。
123
+ - AI/终端工具显示的 `…N tokens truncated…`、`Exit code: N`、`Chunk ID:`、`Wall time:` 等是宿主输出标记,不是 V8 源码。禁止复制到本地文件或 MCP 写入参数;读取长源码必须按工具返回的字符范围分段取完,并核对完整源码 SHA-256。标准 MCP 写工具和插件推送检测到这些标记时必须拒绝写入。
124
+ - 远端源码不少于 8000 字符,而新源码减少超过 15% 时,应先视为可能只拿到了截断片段并停止写入。只有核对完整源码且确需大幅删减时,才使用写工具提供的显式大幅删减确认参数。
125
+ - 发生连续写入超时时,要先停止并发写入,记录具体工具、资源 Key、耗时和回读结果;禁止用“服务器整体不可用”“缓存锁死”等没有日志证据的结论代替诊断。
126
+
127
+ <!-- /microi-progressive:chunk -->
128
+ <!-- microi-progressive:chunk id=workspace-conventions-033 sha256=b642bb516a42b50e8b459e5237588e85d71c9715970779e155b88d7c0e8c6536 -->
129
+ ## Codex MCP 单入口约定
130
+
131
+ - Codex 对普通 MCP 大工具集可能无法稳定注入时,使用插件生成的 `microi_codex` 单入口,不要据此判断服务器或帐号不可用。
132
+ - `microi_codex` 的 `action="list_tools"` 可按 `params.keyword` 查找工具,`action="describe_tool"` + `params.name` 可读取参数说明;执行时 action 使用原始 `microi_*` 工具名,参数放在 `params`。
133
+ - 单入口只负责路由,必须复用原工具的参数 schema、写入确认、审计、超时回读和错误返回。不得因为只暴露一个 Codex 工具而放宽远端写入保护。
134
+ - 如果 Codex 仍不注入 `microi_codex`,优先使用它实际提供的资源工具:先 `list_mcp_resources` 并读取 `microi://codex/status` / `microi://codex/tools`;通用调用先 `list_mcp_resource_templates`,再读取 `microi://codex/action/{action}/{params}`,其中 `params` 是 URI 编码后的 JSON 对象。
135
+ - 资源模板只是兼容传输层,执行的仍是原始 `microi_*` handler。写操作同样必须携带原工具要求的 `confirmExecution`,不得把 resource read 当成绕过确认的通道。
136
+ - VS Code/Copilot、Cursor、Claude Code 仍使用完整 MCP 工具集;不要把 Codex 的 `enabled_tools = ["microi_codex"]` 复制到其他客户端配置。
137
+
138
+ <!-- /microi-progressive:chunk -->
139
+ <!-- microi-progressive:chunk id=workspace-conventions-034 sha256=6ffac2793dea9b1d5953d624103d7aea7800b12deaaf71b3b0f5e3cb5b39ac06 -->
140
+ ## .venv Python 环境说明
141
+
142
+ 工作区根目录的 `.venv/` 是 Python 虚拟环境,**保留,不要删除**。已安装:
143
+ - `playwright` — Playwright E2E 测试
144
+ - `openai` — AI 接口调用
145
+ - `httpx` — HTTP 客户端
146
+ - 其他工具(flake8、pytest 等)
147
+
148
+ AI 执行 Python 脚本时应使用 `.venv\Scripts\python.exe`(Windows)而非系统 Python。
149
+ <!-- /microi-progressive:chunk -->
150
+ <!-- microi-progressive:chunk id=workspace-conventions-035 sha256=c114dffea6978f289601a8f71aa83a0466f3d934e96e45bb871af179d319a1e3 -->
151
+ ## 后端代码改动后的重启验收
152
+
153
+ AI 只要修改了 `Microi.Server/**` 下会影响 `Microi.net.Api` 运行结果的后端源码、配置、控制器、服务、依赖项目或接口行为,任务收尾前必须完成一次“编译 + 重启本地后端 + 健康验证”,不要只用隔离输出目录 build 后结束。
154
+
155
+ 强制流程:
156
+
157
+ 1. 先执行后端编译验证。若 launch profile 当前端口上的开发服务导致 `bin/Debug/net10.0` DLL 被锁,可以先精确停止当前工作区的 `Microi.net.Api` 进程后重新编译;只有用户明确要求不中断正在运行服务时,才允许用临时输出目录作为补充验证,并必须说明运行服务尚未替换。
158
+ 2. 从 `launchSettings.json` 回读实际端口,查找并停止该端口上的本地 `Microi.net.Api` 进程。只停止命令行与当前工作区匹配的 Microi 后端,不要误杀数据库、Redis、Node 前端或其它业务进程。
159
+ 3. 必须进入 `Microi.Server/Microi.net.Api` 目录启动:
160
+ ```powershell
161
+ dotnet run --launch-profile Microi.net.Api
162
+ ```
163
+ 启动优先发生在用户能在 VS Code 中看到和停止的终端中,方便用户查看日志并手动停止;用户明确允许时,可以使用 VS Code 可追踪的隐藏终端/任务终端。当前工具环境没有 VS Code 终端能力时,允许使用本机可见的 `cmd`/PowerShell 窗口启动;禁止使用脱离用户可见窗口的后台服务或守护进程方式启动。标准端口无法释放时,只有同步更新前端本地 `ApiBase` 和测试变量后才可使用明确的临时端口,并在任务结束时说明。
164
+ 4. 启动后轮询验证 launch profile 实际地址可访问;至少确认端口已监听、进程存在、最近日志没有立即崩溃。涉及新增 API 时,再调用新增/受影响接口做一次真实请求。
165
+ 5. 最终回复必须明确说明:后端已重新编译、旧进程 PID 是否停止、新进程 PID、实际端口是否监听、验证的 URL 或接口。若因为用户明确要求不中断、端口被非 Microi 进程占用或配置缺失导致无法重启,必须把阻塞原因说具体。
166
+
167
+ 这条规则优先于“避免打断正在运行服务”的默认谨慎策略;本地开发联调场景下,用户通常需要 launch profile 当前端口上的后端加载最新代码。
168
+
169
+ <!-- /microi-progressive:chunk -->
170
+ <!-- microi-progressive:chunk id=workspace-conventions-036 sha256=db96c39a15f4b5637ce37555797858320256dda22daf7ac5cdaae2a436fd214c -->
171
+ ## MCP 可调用性诊断补充
172
+
173
+ 当用户反馈“Codex/VS Code 设置中能看到 MCP,但当前 AI 会话不能调用对应工具”时,不能只回答“当前会话没有注入”。必须按层排查:
174
+
175
+ 1. 先确认 `.vscode/mcp.json`、`.cursor/mcp.json`、工作区根 `.mcp.json` 和 `~/.codex/config.toml` 都能解析,且目标 server key 为稳定 ASCII 格式,例如 `microi_itdos`,不要使用中文名或横杠。
176
+ 2. 再用 Microi.VSCode 插件的“诊断 MCP 可调用性”命令,或等价脚本直接启动对应 `mcp-server.js` / `mcp-codex-stdio-adapter.js`,执行 `initialize` 和 `tools/list`,确认 `microi_get_db_schema`、`microi_get_field_list`、`microi_add_field`、`microi_update_field`、`microi_refresh_schema_cache` 等核心工具真实返回。
177
+ 3. 如果当前 AI 客户端支持工具发现或延迟加载,AI 必须先主动执行工具发现/热加载流程,例如 `tool_search`、客户端 MCP refresh、Microi.VSCode 的启动/诊断命令;不要先让用户手动重启、重载或重新生成 MCP。
178
+ 4. 如果真实握手成功但 Codex 当前对话仍没有注入 `mcp__...` 工具,AI 仍应优先使用等价的 MCP stdio JSON-RPC 直连 fallback 完成当前任务:读取对应 MCP 配置、启动 adapter/server、执行 `initialize`、`tools/list`、`tools/call`,并严格遵守该 MCP 绑定的 API Server 和 OsClient 边界。直连脚本必须放在 `.tmp/` 或使用一次性 stdin,不得散落到项目目录。
179
+ 5. 只有在客户端不支持热加载、直连 fallback 也无法完成任务,或写操作边界无法确认时,才告知用户需要新开对话、重载 Codex 或检查 MCP 配置。说明必须写清楚:MCP 配置和进程是否可用、当前会话为什么没有注入工具、已经尝试过哪些自动恢复动作。
180
+ 6. 如果握手失败,要把失败层级说清楚:配置文件解析失败、路径不存在、token 文件缺失、MCP 进程启动失败、`initialize` 失败、`tools/list` 缺核心工具,不能把这些问题混成“用户没启用 MCP”。
181
+ 7. Microi.VSCode 生成 MCP 配置时应清理旧的中文/横杠 Microi MCP key,只保留 `microi_<osClient>` 或 `microi_<osClient>_<host>` 形式,避免不同 AI 客户端因 namespace 不稳定而无法注入工具。
182
+
183
+ <!-- /microi-progressive:chunk -->
184
+ <!-- microi-progressive:chunk id=workspace-conventions-037 sha256=d0c37c1f0c5ec999b10ed6f0ccbb4f1f32aa8b0fc998a433d020d6552cc6fb5c -->
185
+ ## Windows MCP 控制台闪窗复盘
186
+
187
+ 当用户反馈“打开 Microi.VSCode、添加服务器或初始化 MCP 后连续弹出并立即关闭多个 cmd 窗口”时,应按进程风暴排查,不能只给已有 `spawn` 补 `windowsHide`:
188
+
189
+ 1. MCP 配置文件是各客户端的事实源。内容未变化时必须使用 write-if-changed,禁止仅为“同步”而反复改写文件并触发监听器重启。
190
+ 2. 生成 `~/.codex/config.toml` 后,禁止再隐式循环执行 `codex mcp list/remove/add`;服务器数量越多,这类逐项 CLI 同步越会放大成几十个瞬时控制台进程。
191
+ 3. VS Code 已配置 `chat.mcp.autostart` 时,插件后台监测只能检查配置和状态,禁止在侧栏显示、定时轮询、登录、添加连接或初始化流程里再次执行 `workbench.mcp.startServer('*')`。
192
+ 4. 握手诊断会真实启动每个 stdio MCP,只能由用户显式点击“诊断 MCP 可调用性”触发;常规配置成功提示不得暗中运行整组诊断。
193
+ 5. Windows 的 VS Code/Cursor 配置优先复用 GUI Electron 宿主 `process.execPath` 并设置 `ELECTRON_RUN_AS_NODE=1`,避免把控制台子系统的外部 `node.exe` 持久化为每个 MCP 的启动命令。Trae 若因空格路径兼容必须经过 `cmd.exe`,仍需使用固定 launcher 并隐藏窗口。
194
+ 6. 回归测试至少静态断言:Codex CLI 批量注册函数不存在、后台 monitor 不包含 `startServer`、自动配置不包含诊断、Codex 配置内容不变时不改写、Windows GUI 宿主检查早于外部 Node 探测。再在扩展开发宿主中覆盖打开侧栏、添加连接、初始化 MCP,观察无连续控制台闪窗。
195
+
196
+ <!-- /microi-progressive:chunk -->
@@ -0,0 +1,27 @@
1
+ # workspace-conventions 详细参考 3
2
+
3
+ > 按需读取;本文件由 SKILL.md 的原章节无损拆分。
4
+
5
+ <!-- microi-progressive:chunk id=workspace-conventions-038 sha256=57098466d31d0636bf330fde545daff8cb8e4116ac6ea2efff8abc729fdcef77 -->
6
+ ## CLI 与 IDE 插件错版共存约定
7
+
8
+ - CLI 与 IDE 插件共用配置、Token、MCP、Skills 或生成文件时,所有持久化协议必须按“新字段可选、旧字段保留、未知字段不删除”设计。不得将 JSON 解析到旧类型后只序列化已知字段。
9
+ - 共享 JSON/Token 必须失败关闭:解析失败时保留原文件并停止写入;写入使用同目录临时文件原子替换,多进程可写文件还要使用带超时/死锁恢复的文件锁。
10
+ - MCP 配置要写入工具来源与三段版本;替换同名或同 API/OsClient 的 Microi Server 时实行“较新提供者优先”,同时保留非 Microi MCP。Skills/AI 指令也要记录 bundle/file 版本,旧 bundle 不得覆盖新 bundle 已生成的内容。
11
+ - 已发布的历史二进制无法被新代码追溯修复。诊断必须把无版本记录标记为 `legacy`,说明更新或用较新一端重新初始化的恢复路径;不得宣称新代码已让任意历史版本绝对共存。
12
+ - 多 registry 联合发布没有跨站点原子事务。必须在递增版本前验证本轮必选目标的凭据/权限,对每个产物校验同版本,发布后逐端公开回读。可选目标(例如尚未开通 scope 的 npm CLI)预检或发布失败时,不得阻断已经通过预检的必选目标;必须保留同版本产物、明确报告部分完成并给出精确补发命令。要求全目标成功的发布应提供显式严格模式。补发只能复用完全相同的源码/产物;代码改动后必须发新版本。
13
+
14
+ ### 复盘:可选 npm 目标阻断两个扩展市场发布
15
+
16
+ - 触发场景:联合发布同时包含两个扩展市场和 npm CLI,但 npm 组织 scope 尚未创建,脚本在版本递增前直接退出,导致已经具备权限的两个扩展市场也无法发布。
17
+ - 根因:发布脚本把三个 registry 都视为同一个全局硬门禁,并把最容易受账号、scope 和 2FA 影响的 npm 放在扩展市场之前,没有区分必选目标、可选目标和严格发布模式。
18
+ - 通用规则:默认发布按目标隔离;先完成并回读必选目标,再独立尝试可选目标。可选目标失败应保留同版本不可变产物并输出补发入口;只有显式严格模式才要求所有目标预检通过后继续。
19
+ - 自动化检查:模拟 npm 未登录、scope 404 和 npm publish 非零退出,断言两个扩展市场的发布调用与回读仍会执行;另测严格模式在版本递增前停止,补发命令不递增版本且复用同版本产物。
20
+
21
+ ### 复盘:npm 已接收新版本但公共回读短暂 404
22
+
23
+ - 触发场景:`npm publish` 已成功返回,npmjs.com 包页面也已出现新包或新版本,但紧随其后的 `npm view <package>@<version> version` 在数十秒内连续返回 E404,联合发布脚本因此把成功发布误报为失败。
24
+ - 根因:新 scope/新版本在 npm 网站、写入节点和公共 registry 读取节点之间存在短暂传播窗口;固定少量、短间隔轮询不足以区分“尚未发布”和“已经接收但尚未公开传播”。
25
+ - 通用规则:发布命令成功和公共回读确认必须作为两个阶段记录。npm 新版本回读使用 `--prefer-online` 和分钟级有限重试;重试结束仍为 E404 时标记 `pending-propagation`,禁止自动重发同一不可变版本,并提供独立只读验证命令稍后确认。只有发布命令本身失败且公共 registry 也始终不存在时,才进入补发流程。
26
+ - 自动化检查:模拟 `npm publish` 成功后前几次 `npm view` 返回 E404、随后返回期望版本,断言不会重复发布;再模拟重试窗口结束仍为 E404,断言输出待传播状态和只读验证命令,而不是提示重新上传同一版本。
27
+ <!-- /microi-progressive:chunk -->