@microi.net/cli 6.1.0 → 6.1.3
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.
- package/.codebuddy-plugin/marketplace.json +2 -2
- package/.codebuddy-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.workbuddy-plugin/marketplace.json +2 -2
- package/.workbuddy-plugin/plugin.json +1 -1
- package/assets/build-meta.json +4 -4
- package/cordis.patch.yml +1 -1
- package/package.json +1 -1
- package/scripts/mcp-server.js +108 -106
- package/scripts/microi-skills.meta.json +312 -312
- package/skills/.microi-skills-version.json +2 -2
- package/skills/.progressive-disclosure-manifest.json +42 -42
- package/skills/README.md +287 -287
- package/skills/ai-engine/SKILL.md +273 -273
- package/skills/ai-engine/references/ai-employees.md +48 -48
- package/skills/ai-engine/references/self-hosted-digital-human.md +59 -59
- package/skills/app-store/SKILL.md +531 -531
- package/skills/business-blueprint/SKILL.md +193 -193
- package/skills/datasource-engine/SKILL.md +93 -93
- package/skills/dos-orm/SKILL.md +105 -105
- package/skills/dos-orm/references/api-reference.md +229 -229
- package/skills/email-engine/SKILL.md +81 -81
- package/skills/email-engine/references/v8-email.md +34 -34
- package/skills/job-engine/SKILL.md +176 -176
- package/skills/message-notification/SKILL.md +156 -156
- package/skills/message-notification/references/contracts.md +102 -102
- package/skills/microi/SKILL.md +14 -14
- package/skills/microi-ai-application/SKILL.md +115 -115
- package/skills/microi-ai-application/references/frontend-baseline.md +164 -164
- package/skills/microi-client-frontend/SKILL.md +19 -19
- 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 +10 -10
- 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 +10 -10
- 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 +10 -10
- package/skills/microi-codex/SKILL.md +130 -130
- package/skills/microi-codex-installer/SKILL.md +233 -233
- package/skills/microi-datasource-mapping/SKILL.md +131 -122
- package/skills/microi-db-schema/SKILL.md +175 -175
- package/skills/microi-db-schema/references/core-tables.md +695 -695
- package/skills/microi-db-schema/references/form-component-options.md +256 -256
- package/skills/microi-db-schema/references/schema-overview.md +202 -202
- package/skills/microi-db-schema/references/schema.md +646 -646
- package/skills/microi-db-schema/references/table-catalog.md +1599 -1599
- package/skills/microi-deployment/SKILL.md +260 -260
- package/skills/microi-deployment/references/deployment-matrix.md +112 -109
- package/skills/microi-docs-coverage/SKILL.md +133 -133
- package/skills/microi-docs-coverage/references/capability-map.md +91 -91
- package/skills/microi-form-engine/SKILL.md +338 -338
- package/skills/microi-form-engine/references/component-catalog.md +218 -218
- package/skills/microi-form-engine/references/data-source-events.md +124 -124
- package/skills/microi-left-right-layout/SKILL.md +141 -141
- package/skills/microi-microservice/SKILL.md +2 -1
- package/skills/microi-microservice/references/runtime-delivery.md +282 -282
- package/skills/microi-solution-quotation/SKILL.md +78 -78
- package/skills/microi-sso/SKILL.md +102 -102
- package/skills/microi-sso/references/acceptance.md +51 -51
- package/skills/microi-sso/references/configuration-and-security.md +53 -53
- package/skills/microi-sso/references/inbound.md +53 -53
- package/skills/microi-sso/references/outbound.md +43 -43
- package/skills/microi-system-delivery/SKILL.md +115 -115
- package/skills/microi-system-delivery/references/context-quality.md +56 -56
- package/skills/microi-system-delivery/references/progressive-01-/346/240/207/345/207/206/345/267/245/344/275/234/346/265/201.md +11 -11
- 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 +12 -12
- package/skills/microi-system-delivery/references/progressive-03-/345/256/211/345/205/250/344/270/216/350/267/250/347/253/257/351/252/214/346/224/266.md +69 -69
- package/skills/microi-uniapp-frontend/SKILL.md +4 -1
- package/skills/module-engine/SKILL.md +297 -297
- package/skills/module-engine/references/module-config.md +204 -204
- package/skills/ocr-engine/SKILL.md +113 -113
- package/skills/page-engine/SKILL.md +24 -24
- 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 +10 -10
- 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 +12 -12
- package/skills/performance-testing/SKILL.md +227 -227
- package/skills/playwright-e2e/SKILL.md +2 -0
- package/skills/print-engine/SKILL.md +259 -259
- package/skills/production-readonly-audit/SKILL.md +41 -41
- package/skills/report-engine/SKILL.md +83 -83
- package/skills/search-engine/SKILL.md +75 -75
- package/skills/spider-engine/SKILL.md +190 -190
- package/skills/system-observability/SKILL.md +264 -264
- package/skills/system-observability/references/memory-incident-triage.md +77 -77
- package/skills/translate-engine/SKILL.md +140 -140
- package/skills/ui-design/assets/templates/MCI-DESIGN.md +206 -206
- package/skills/ui-design/references/design-pattern-library.md +184 -184
- package/skills/ui-design/references/mci-design-contract.md +163 -163
- package/skills/ui-design/references/motion-and-media.md +78 -78
- package/skills/ui-design/references/product-flow-recipes.md +94 -94
- package/skills/uniapp-mall-assets/SKILL.md +176 -176
- package/skills/unity-integration/SKILL.md +178 -178
- package/skills/unity-integration/references/ai-app-delivery.md +119 -119
- package/skills/unity-integration/references/sdk-api.md +82 -82
- package/skills/unity-integration/references/toolbox-migration.md +66 -66
- package/skills/unity-integration/references/webgl-hosting.md +57 -57
- package/skills/v8-api-config/SKILL.md +403 -400
- package/skills/v8-cache-pattern/SKILL.md +320 -320
- package/skills/v8-debugging/SKILL.md +284 -284
- package/skills/v8-explorer-tree/SKILL.md +228 -228
- package/skills/v8-file-upload/references/cdn-alias-repair.md +13 -13
- package/skills/v8-formengine-http/SKILL.md +238 -238
- package/skills/v8-frontend-events/references/bluetooth-print-api.md +135 -135
- package/skills/v8-frontend-events/references/bluetooth-print.md +258 -258
- package/skills/v8-image-processing/SKILL.md +190 -190
- package/skills/v8-image-processing/references/api-reference.md +623 -623
- package/skills/v8-mongodb/SKILL.md +201 -201
- package/skills/v8-mq-mqtt/references/mqtt-production.md +352 -352
- package/skills/v8-saas-multi-tenant/SKILL.md +10 -0
- package/skills/v8-security/SKILL.md +2 -0
- package/skills/v8-security/references/progressive-01-2-/346/235/203/351/231/220/346/240/241/351/252/214.md +9 -3
- package/skills/v8-sql-query/SKILL.md +302 -302
- package/skills/v8-tcp-integration/SKILL.md +225 -158
- package/skills/v8-template-engine/SKILL.md +167 -167
- package/skills/v8-utilities/SKILL.md +105 -104
- package/skills/v8-utilities/references/client-api-index.md +143 -143
- package/skills/v8-utilities/references/platform-http-routes.md +83 -83
- package/skills/v8-utilities/references/server-api-index.md +189 -188
- package/skills/v8-workflow/references/workflow-configuration.md +49 -49
- package/skills/vision-engine/SKILL.md +160 -160
- package/skills/vision-engine/references/architecture-and-acceptance.md +194 -194
- package/skills/workspace-conventions/SKILL.md +6 -0
- 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 +32 -32
- 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 +34 -34
- 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 +6 -6
- package/skills/workspace-conventions/references/progressive-04-/345/267/245/344/275/234/345/214/272/344/270/216/345/271/263/345/217/260/344/270/223/351/241/271/344/277/235/351/232/234.md +188 -188
|
@@ -1,228 +1,228 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: v8-explorer-tree
|
|
3
|
-
description: Microi.Agent 插件 V8 资源管理器目录规范(表单引擎 / 字段V8事件 / 模块引擎按钮)。覆盖 diy_table V8 事件、diy_field V8 事件、sys_menu 按钮 JSON 拆分回写,含 7 条安全不变量。用于实现 VSCode V8 事件树、重构目录布局或处理 sys_menu 按钮 JSON 序列化。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
> **Microi吾码基础规范(强制):** 任何 AI 模型与宿主每次新建或接续吾码任务,先完整读取 `../workspace-conventions/SKILL.md`,必须执行版本播报、`@microi.net/cli` 后台自动升级、Skills/MCP 同步和进度播报。安装与诊断读取 `../microi-codex-installer/SKILL.md`;更新失败延后重试,不阻断当前工作。
|
|
7
|
-
|
|
8
|
-
# v8-explorer-tree — V8 资源管理器目录规范 v2(2026-05)
|
|
9
|
-
|
|
10
|
-
> 涉及文件:[Microi.Agent/src/explorer/engineTreeProvider.ts](Microi.Agent/src/explorer/engineTreeProvider.ts)、[Microi.Agent/src/sync/syncManager.ts](Microi.Agent/src/sync/syncManager.ts)、[Microi.Agent/src/constants.ts](Microi.Agent/src/constants.ts)、[Microi.Agent/src/utils.ts](Microi.Agent/src/utils.ts)、[Microi.Server/Microi.net.Api/Controllers/V8EngineController.cs](Microi.Server/Microi.net.Api/Controllers/V8EngineController.cs)
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
MCP 后端实现位于 `Microi.Server/Microi.MCP/`:`V8Engine/V8McpLogic*.cs` 维护业务操作,`Http/V8McpEndpointService.cs` 维护参数归一化与调用,HTTP/调试权限和 WebSocket 会话也由该独立库承载。API 的 `V8EngineController.cs` 只声明原有路由、HTTP 特性与转发,继续兼容 `/api/V8Engine/*`、`/api/V8Debug/*` 和 `/api/V8Debug/ws`。
|
|
15
|
-
|
|
16
|
-
## 0. 命名规范(强制)
|
|
17
|
-
|
|
18
|
-
**所有目录与文件**统一使用 **中文(英文)** 形式,使用**全角括号 `()`**:
|
|
19
|
-
|
|
20
|
-
| 元素 | 格式 | 示例 |
|
|
21
|
-
|------|------|------|
|
|
22
|
-
| 表 | `<表Label>(<表Name>)` | `仓库档案(diy_cangkuda)` |
|
|
23
|
-
| 字段 | `<字段Label>(<字段Name>)` | `仓库名称(CangKuName)` |
|
|
24
|
-
| 菜单 | `<菜单Name中文>(<菜单英文Name>)` | `订单管理(OrderManage)` |
|
|
25
|
-
| 事件 | `<事件中文名>(<EventType>)` | `前端表单进入V8事件(InFormV8).js` |
|
|
26
|
-
| 字段事件 | `<事件中文名>(<英文Key>)` | `值变更V8事件(V8Code).js` |
|
|
27
|
-
| 按钮 | `<按钮Name>(<按钮Id>)` | `指派(01K3X...).js` |
|
|
28
|
-
| 按钮显隐 | `<按钮Name>_显隐判断(<按钮Id>)` | `指派_显隐判断(01K3X...).js` |
|
|
29
|
-
| 按钮分类目录 | `<按钮类型中文>(<EnglishField>)` | `[行]更多按钮(MoreBtns)/` |
|
|
30
|
-
|
|
31
|
-
### 0.1 7 类表单 V8 事件中文名(以 `diy_table` 对应 `diy_field.Label` 为准)
|
|
32
|
-
|
|
33
|
-
| EventType | 中文名 |
|
|
34
|
-
|-----------|--------|
|
|
35
|
-
| InFormV8 | 前端表单进入V8事件 |
|
|
36
|
-
| SubmitFormV8 | 前端表单提交前V8事件 |
|
|
37
|
-
| SubmitBeforeServerV8 | 后端表单提交前V8事件 |
|
|
38
|
-
| SubmitAfterServerV8 | 后端表单提交后V8事件 |
|
|
39
|
-
| ServerDataV8 | 后端数据处理V8事件 |
|
|
40
|
-
| OutFormV8 | 前端表单提交后V8事件 |
|
|
41
|
-
| DataFilterV8 | 后端数据过滤V8事件 |
|
|
42
|
-
|
|
43
|
-
> 统一用“后端”,不要再生成“服务端”或“服务器端”可见目录/文件名。
|
|
44
|
-
|
|
45
|
-
### 0.2 4 类字段 V8 事件中文名
|
|
46
|
-
|
|
47
|
-
| Key | 中文名 |
|
|
48
|
-
|-----|--------|
|
|
49
|
-
| V8Code | 值变更V8事件 |
|
|
50
|
-
| KeyupV8Code | 键盘抬起V8事件 |
|
|
51
|
-
| V8TmpEngineTable | 表格列模板V8事件 |
|
|
52
|
-
| V8TmpEngineForm | 表单字段模板V8事件 |
|
|
53
|
-
|
|
54
|
-
### 0.3 6 类按钮中文名
|
|
55
|
-
|
|
56
|
-
| Field | 中文名 |
|
|
57
|
-
|-------|--------|
|
|
58
|
-
| PageTabs | 页面多Tab |
|
|
59
|
-
| PageBtns | [页面]更多按钮 |
|
|
60
|
-
| MoreBtns | [行]更多按钮 |
|
|
61
|
-
| FormBtns | [表单]更多按钮 |
|
|
62
|
-
| BatchSelectMoreBtns | [批量选择]更多按钮 |
|
|
63
|
-
| ExportMoreBtns | [导出]更多按钮 |
|
|
64
|
-
|
|
65
|
-
---
|
|
66
|
-
|
|
67
|
-
## 1. 当前结构(v1 基线)
|
|
68
|
-
|
|
69
|
-
```
|
|
70
|
-
<workspace>/microi-v8-engine/
|
|
71
|
-
├── 接口引擎/
|
|
72
|
-
│ └── <ApiEngineName>(<ApiEngineKey>).js // 半角括号,保留不变
|
|
73
|
-
└── V8事件/
|
|
74
|
-
└── <表Description(表Name)>/
|
|
75
|
-
└── <EventType>.js // 扁平,无中文事件名
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## 2. 目标结构(v2)
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
<workspace>/microi-v8-engine/<server>/<osClient>/
|
|
82
|
-
├── 接口引擎/ // 保持不变
|
|
83
|
-
│ └── <分类>/<ApiEngineName>(<ApiEngineKey>).js
|
|
84
|
-
│
|
|
85
|
-
├── 表单引擎/
|
|
86
|
-
│ └── <表Label>(<表Name>)/
|
|
87
|
-
│ ├── 表单V8事件/
|
|
88
|
-
│ │ ├── 前端表单进入V8事件(InFormV8).js // 仅远端非空代码生成文件
|
|
89
|
-
│ │ ├── 前端表单提交前V8事件(SubmitFormV8).js
|
|
90
|
-
│ │ ├── 后端表单提交前V8事件(SubmitBeforeServerV8).js
|
|
91
|
-
│ │ ├── 后端表单提交后V8事件(SubmitAfterServerV8).js
|
|
92
|
-
│ │ ├── 后端数据处理V8事件(ServerDataV8).js
|
|
93
|
-
│ │ ├── 前端表单提交后V8事件(OutFormV8).js
|
|
94
|
-
│ │ └── 后端数据过滤V8事件(DataFilterV8).js
|
|
95
|
-
│ └── 字段V8事件/
|
|
96
|
-
│ └── <字段Label>(<字段Name>)/
|
|
97
|
-
│ ├── 值变更V8事件(V8Code).js // 右键单表拉取后生成,仅远端非空代码生成文件
|
|
98
|
-
│ ├── 键盘V8事件(KeyupV8Code).js
|
|
99
|
-
│ ├── 模板V8引擎(表格)(V8TmpEngineTable).js
|
|
100
|
-
│ └── 模板V8引擎(表单)(V8TmpEngineForm).js
|
|
101
|
-
│
|
|
102
|
-
└── 模块引擎/
|
|
103
|
-
└── <父菜单Name>(<ParentMenuId>)/ // 非叶子模块只显示子模块,不生成按钮目录
|
|
104
|
-
└── <叶子菜单Name>(<LeafMenuId>)/
|
|
105
|
-
├── Join关联(SqlJoin).js // 始终生成,直接映射 sys_menu.SqlJoin
|
|
106
|
-
├── Where条件(SqlWhere).js // 始终生成,直接映射 sys_menu.SqlWhere
|
|
107
|
-
├── 页面多Tab(PageTabs)/ // 叶子模块固定生成全部 6 个按钮目录,即使为空
|
|
108
|
-
│ ├── <按钮Name>(<按钮Id>).js // V8Code,仅远端非空代码生成文件
|
|
109
|
-
│ └── <按钮Name>_显隐判断(<按钮Id>).js // V8CodeShow,仅在非空时生成
|
|
110
|
-
├── [页面]更多按钮(PageBtns)/
|
|
111
|
-
├── [行]更多按钮(MoreBtns)/
|
|
112
|
-
├── [表单]更多按钮(FormBtns)/
|
|
113
|
-
├── [批量选择]更多按钮(BatchSelectMoreBtns)/
|
|
114
|
-
└── [导出]更多按钮(ExportMoreBtns)/
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### 2.1 ⚠️ 空代码不落文件规则(关键约束)
|
|
118
|
-
|
|
119
|
-
> **前端 V8 引擎**只要事件 / 按钮代码字符串非空(哪怕只有注释、空格),就会调用 Jint 解析并执行——产生不必要的 CPU 开销。
|
|
120
|
-
>
|
|
121
|
-
> 因此:拉取远端资源时,空 V8 代码**不要生成本地 `.js` 文件**。若历史同步留下空 `.js` 文件,且远端代码同样为空,应删除本地空文件,避免被“查看同步状态”误判为本地未推送。
|
|
122
|
-
>
|
|
123
|
-
> 用户需要清空远端代码时,可以把已有非空文件清空并推送;推送成功后插件应删除该本地空文件或对齐为“无本地文件”状态。
|
|
124
|
-
>
|
|
125
|
-
> 例外:`SqlJoin`、`SqlWhere` 是模块查询配置,不是按钮 V8 事件。叶子模块必须始终生成两个平级文件,空文件表示远端字段为空,并允许通过推送空文件清空对应字段。
|
|
126
|
-
|
|
127
|
-
---
|
|
128
|
-
|
|
129
|
-
## 3. 数据流
|
|
130
|
-
|
|
131
|
-
### 3.1 表单 V8 事件(✅ 已实现 2026-05)
|
|
132
|
-
|
|
133
|
-
- **拉取**:复用 `GetV8EventList`。对每个返回项:
|
|
134
|
-
1. 每张表固定生成表单 V8 事件目录
|
|
135
|
-
2. 仅远端非空代码生成 `.js`;空代码不生成文件,历史空文件应删除
|
|
136
|
-
- **保存**:`parseEventFilePath` 解析新旧两种结构,调 `UpdateV8EventCode`
|
|
137
|
-
- **删除**:用户删除本地文件默认只删除本地文件,不自动清空远端;清空远端必须通过清空已有文件内容并执行推送,或使用明确的“清空远端代码”命令
|
|
138
|
-
|
|
139
|
-
### 3.2 字段 V8 事件(✅ 已实现 2026-05)
|
|
140
|
-
|
|
141
|
-
**接口**:
|
|
142
|
-
- `GET /api/V8Debug/GetFieldList?osClient&tableId` — 返回字段列表带 `V8Code/KeyupV8Code/V8TmpEngineTable/V8TmpEngineForm`
|
|
143
|
-
- `POST /api/V8Debug/UpdateField` — Body 含 `Id` 或 `TableName + Name`,仅 V8 字段更新时直接写 `diy_field`,不触发表字段物理列变更
|
|
144
|
-
|
|
145
|
-
**实施清单**:
|
|
146
|
-
1. 在 `engineTreeProvider.ts` 的表节点加 inline action「拉取此表字段V8事件」
|
|
147
|
-
2. 调 `GetFieldList` 拿字段,对每个字段固定生成 4 个文件:`字段V8事件/<Label>(<Name>)/<事件中文>(<Key>).js`
|
|
148
|
-
3. 保存时按文件路径解析 `(TableId, FieldName, V8Key)` → 调 `UpdateField`
|
|
149
|
-
|
|
150
|
-
### 3.3 sys_menu 按钮 JSON 拆分(✅ 已实现 2026-05)
|
|
151
|
-
|
|
152
|
-
**接口**:
|
|
153
|
-
- `GET /api/V8Debug/GetModule?osClient&moduleId` — 返回菜单详情,包含 6 类按钮 JSON 以及 `SqlJoin/SqlWhere`
|
|
154
|
-
- `POST /api/V8Debug/UpdateModule` — Body 含 `OsClient/ModuleId` 以及目标按钮字段或 `SqlJoin/SqlWhere`
|
|
155
|
-
|
|
156
|
-
**拉取**:
|
|
157
|
-
1. 解析 `PageTabs/PageBtns/MoreBtns/FormBtns/BatchSelectMoreBtns/ExportMoreBtns` 6 个 JSON 数组(非法 JSON 记录错误并跳过该字段)
|
|
158
|
-
2. 按 `ParentId` 生成与 `sys_menu/GetSysMenuStep` 一致的模块树;非叶子模块只生成子模块目录,不生成按钮目录
|
|
159
|
-
3. 叶子模块固定生成全部 6 个按钮分类目录,并直接生成 `Join关联(SqlJoin).js`、`Where条件(SqlWhere).js`;两个配置文件即使远端为空也必须生成
|
|
160
|
-
4. 对每个按钮:
|
|
161
|
-
- 仅在 `V8Code` 非空时生成 `<按钮Name>(<按钮Id>).js`
|
|
162
|
-
- 若 `V8CodeShow` 非空 → 生成 `<按钮Name>_显隐判断(<按钮Id>).js`
|
|
163
|
-
- 在空按钮目录中新建 `<按钮Name>(<按钮Id>).js` 并推送时,可按文件名创建远端新按钮
|
|
164
|
-
5. `.microi-meta.json` 写入按钮 JSON hash;回写前写 `.backups/<moduleId>/<ButtonField>-<timestamp>.json`
|
|
165
|
-
|
|
166
|
-
**保存(事务,必须满足 §4 全部不变量)**:
|
|
167
|
-
1. 从文件路径解析 `ModuleId / ButtonField / ButtonId / V8Code 或 V8CodeShow`
|
|
168
|
-
2. 二次调 `GetModule` 拉远端当前 JSON
|
|
169
|
-
3. JSON 解析失败立即中止
|
|
170
|
-
4. **Id-Diff 合并**:只修改目标按钮的 `V8Code` 或 `V8CodeShow`,远端其它按钮全部原样保留
|
|
171
|
-
5. 写一份 `.backups/<moduleId>/<ButtonField>-<timestamp>.json`(变更前的远端 JSON)
|
|
172
|
-
6. 调 `UpdateModule` 整段写回;任何一步失败不写库
|
|
173
|
-
|
|
174
|
-
**SqlJoin/SqlWhere 保存**:从文件路径解析 `ModuleId / SqlJoin|SqlWhere`,推送前重新 `GetModule`,备份远端原字段,`UpdateModule` 只提交目标字段;成功后必须再次 `GetModule` 回读正文完全一致,才更新 meta/mtime。空正文正常保留为空文件。
|
|
175
|
-
|
|
176
|
-
**修改状态**:接口引擎、表单V8事件、字段V8事件、模块按钮、模块 SqlJoin/SqlWhere 文件都必须写入 `.microi-meta.json` 的 `updateTime/filePath`;本地 `mtime > updateTime + 1s` 时树节点显示 `已修改`,推送成功后同步更新 meta 并将文件 mtime 设置为远端更新时间以清除标记。
|
|
177
|
-
|
|
178
|
-
**MCP 请求服务 OsClient 规则**:`CheckPermission()` 返回的 `token` 是 `dynamic`。调用 `V8McpLogic.ResolveOsClient` 时必须传 `(object)token`,并让 `ResolveOsClient(string osClient, object currentToken)` 返回真正的 `string`;`Microi.MCP/Http/V8McpEndpointService.cs` 中 OsClient 空判断用 `string.IsNullOrWhiteSpace(osClient)`,不要对 `osClient` 调 `DosIsNullOrWhiteSpace()`。
|
|
179
|
-
|
|
180
|
-
---
|
|
181
|
-
|
|
182
|
-
## 4. 风险与不变量(实施 Stage 2/3 前必读)
|
|
183
|
-
|
|
184
|
-
| # | 不变量 | 违反后果 | 检测手段 |
|
|
185
|
-
|---|--------|---------|---------|
|
|
186
|
-
| I1 | 按钮 `Id` 必须保留且唯一 | 远端按钮丢失/重复 | 文件名中 `(<Id>)` 段 + 头部 `@ButtonId` 双校验,二者必须一致 |
|
|
187
|
-
| I2 | 远端按钮在本地缺失时**保留**而非删除 | 用户只拉了一类按钮就保存 → 其余被清空 | 保存前必须 `GetModule` 重新拉取做 Id-Diff |
|
|
188
|
-
| I3 | 远端整段 JSON 哈希在保存前必须匹配 | 多人/多端冲突覆盖 | `.microi-menu.json.RemoteHash` 检查 |
|
|
189
|
-
| I4 | 任何 JSON 解析失败必须中止保存 | JSON 损坏 | try/catch + 弹窗 |
|
|
190
|
-
| I5 | 按钮元数据头被用户改坏(如 `@ButtonId` 被删) | 写回失败 | 元数据头丢失 → 该文件标记 dirty,提示从远端覆盖 |
|
|
191
|
-
| I6 | 每次回写前自动写 `.backups/<timestamp>.json` | 误操作可恢复 | 强制执行,无配置开关 |
|
|
192
|
-
| I7 | 用户重命名/删除按钮文件 | 误操作 | 重命名按 Id 匹配;删除需弹窗输入按钮名二次确认 |
|
|
193
|
-
|
|
194
|
-
---
|
|
195
|
-
|
|
196
|
-
## 5. 实施状态(2026-05-22)
|
|
197
|
-
|
|
198
|
-
- ✅ **Stage 1 表单V8事件分层 + 中文命名 + 空代码跳过文件生成** —— 已实现
|
|
199
|
-
- ✅ **Stage 2 字段V8事件** —— 已实现:右键单表拉取字段 V8 事件;空代码不生成文件;推送仅更新目标字段的目标 V8 字段
|
|
200
|
-
- ✅ **Stage 3 sys_menu 按钮拆分** —— 已实现:主拉取同步模块引擎;按钮 V8Code 仅在非空时生成 `.js`;推送前重拉远端 JSON、按 ButtonId 只改目标按钮并保留其它按钮,写入前自动备份
|
|
201
|
-
- ✅ **Stage 4 树形模块引擎 + 全类型修改状态** —— 已实现:模块按 ParentId 树形拉取;非叶子只显示子模块;叶子固定生成 6 个按钮目录;字段/按钮文件也显示并清除 `已修改`
|
|
202
|
-
- ✅ **Stage 5 sys_menu 查询脚本本地化** —— 已实现:叶子模块固定生成 `SqlJoin/SqlWhere` 两个平级 `.js` 文件,支持备份、预检、推送、远端回读和修改状态
|
|
203
|
-
|
|
204
|
-
---
|
|
205
|
-
|
|
206
|
-
## 6. 实施约束总结
|
|
207
|
-
|
|
208
|
-
- **不要**在没看过 §4 全部 7 条不变量就动手实现 Stage 3
|
|
209
|
-
- **不要**为远端空 V8 事件/按钮代码生成 `.js` 文件;`SqlJoin/SqlWhere` 属于查询配置,必须保留空文件
|
|
210
|
-
- **不要**用半角括号;统一用全角 `()`
|
|
211
|
-
- **不要**清空 V8事件/ 旧目录;保留兼容直到用户主动删除
|
|
212
|
-
- 文件名中 `<英文Key>` 段必须 ASCII,避免 Windows 不可见字符
|
|
213
|
-
- 远端 Key 若含 `\`、`/`、括号或 Windows 非法字符,文件名中的 Key 段必须使用可逆百分号编码;解析和推送时必须解码回原始 Key,禁止用 `_` 不可逆替换后误更新另一条远端记录。文件名还要处理控制字符、结尾空格/点和 `CON/PRN/AUX/NUL/COM1/LPT1` 等 Windows 保留名。
|
|
214
|
-
- “拉取此服务器代码”必须按接口引擎、表单引擎、模块引擎、流程引擎、数据库结构分阶段执行。某一类型失败时要记录明细并继续后续类型;同一类型内单个文件写入失败也要继续下一项,禁止首个 `ENOENT` 让整个服务器只留下半套源码。
|
|
215
|
-
|
|
216
|
-
## 7. AI 远端修改后的同步约束
|
|
217
|
-
|
|
218
|
-
AI 使用 MCP、接口引擎、数据库脚本或平台 API 修改远端 V8 代码后,必须在任务收尾时同步本地 V8 资源树,并用“查看同步状态”或等价 dry-run 复核。
|
|
219
|
-
|
|
220
|
-
- 远端写入后以远端当前生效代码为准,回写本地文件并更新/对齐 meta 与文件 mtime。
|
|
221
|
-
- 覆盖范围至少包含本次 touched 的接口引擎、表单 V8 事件、字段 V8 事件、模块按钮 V8、工作流节点 V8、数据源 V8。
|
|
222
|
-
- 若没有插件 API 可调用,可在 `.tmp/` 编写一次性同步脚本;脚本必须先 dry-run 输出差异数量,再 apply。
|
|
223
|
-
- 收尾复核应确认 touched 范围没有 `changed/created/local-only` 差异;若存在差异,必须在最终回复中说明原因。
|
|
224
|
-
- 空 V8 代码不生成本地 `.js` 文件;同步收尾时应清理历史空文件。
|
|
225
|
-
- 插件“查看同步状态”不能只显示数量。若本地未推送数量大于 0,必须能列出具体资源类型、Key、名称、同步基准时间、本地修改时间和文件路径,并支持直接打开该文件。
|
|
226
|
-
- 接口引擎、表单引擎、模块引擎、流程引擎四个顶层分类必须分别提供行内“查看同步状态”,分类检测只请求该类型的远端数据,禁止每次强制扫描全部引擎。表单引擎范围必须同时覆盖表单 V8 事件与字段 V8 事件,模块引擎范围必须覆盖按钮 V8 与 `SqlJoin/SqlWhere`。
|
|
227
|
-
- 一次同步检测的结果必须持久保留在侧边“同步结果”树中,按双方冲突、服务器较新、本地未推送分组;用户应能连续点击不同文件查看远端/本地差异,只有主动刷新时才重新请求服务器,禁止每查看一个文件都重新执行整次检测。
|
|
228
|
-
- 表单事件、字段事件、按钮事件等远端 Key 比对要做大小写兼容;当本地代码与远端代码相同但 mtime 晚于 meta 时,应自动刷新 meta/mtime,避免误报“本地未推送”。
|
|
1
|
+
---
|
|
2
|
+
name: v8-explorer-tree
|
|
3
|
+
description: Microi.Agent 插件 V8 资源管理器目录规范(表单引擎 / 字段V8事件 / 模块引擎按钮)。覆盖 diy_table V8 事件、diy_field V8 事件、sys_menu 按钮 JSON 拆分回写,含 7 条安全不变量。用于实现 VSCode V8 事件树、重构目录布局或处理 sys_menu 按钮 JSON 序列化。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
> **Microi吾码基础规范(强制):** 任何 AI 模型与宿主每次新建或接续吾码任务,先完整读取 `../workspace-conventions/SKILL.md`,必须执行版本播报、`@microi.net/cli` 后台自动升级、Skills/MCP 同步和进度播报。安装与诊断读取 `../microi-codex-installer/SKILL.md`;更新失败延后重试,不阻断当前工作。
|
|
7
|
+
|
|
8
|
+
# v8-explorer-tree — V8 资源管理器目录规范 v2(2026-05)
|
|
9
|
+
|
|
10
|
+
> 涉及文件:[Microi.Agent/src/explorer/engineTreeProvider.ts](Microi.Agent/src/explorer/engineTreeProvider.ts)、[Microi.Agent/src/sync/syncManager.ts](Microi.Agent/src/sync/syncManager.ts)、[Microi.Agent/src/constants.ts](Microi.Agent/src/constants.ts)、[Microi.Agent/src/utils.ts](Microi.Agent/src/utils.ts)、[Microi.Server/Microi.net.Api/Controllers/V8EngineController.cs](Microi.Server/Microi.net.Api/Controllers/V8EngineController.cs)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
MCP 后端实现位于 `Microi.Server/Microi.MCP/`:`V8Engine/V8McpLogic*.cs` 维护业务操作,`Http/V8McpEndpointService.cs` 维护参数归一化与调用,HTTP/调试权限和 WebSocket 会话也由该独立库承载。API 的 `V8EngineController.cs` 只声明原有路由、HTTP 特性与转发,继续兼容 `/api/V8Engine/*`、`/api/V8Debug/*` 和 `/api/V8Debug/ws`。
|
|
15
|
+
|
|
16
|
+
## 0. 命名规范(强制)
|
|
17
|
+
|
|
18
|
+
**所有目录与文件**统一使用 **中文(英文)** 形式,使用**全角括号 `()`**:
|
|
19
|
+
|
|
20
|
+
| 元素 | 格式 | 示例 |
|
|
21
|
+
|------|------|------|
|
|
22
|
+
| 表 | `<表Label>(<表Name>)` | `仓库档案(diy_cangkuda)` |
|
|
23
|
+
| 字段 | `<字段Label>(<字段Name>)` | `仓库名称(CangKuName)` |
|
|
24
|
+
| 菜单 | `<菜单Name中文>(<菜单英文Name>)` | `订单管理(OrderManage)` |
|
|
25
|
+
| 事件 | `<事件中文名>(<EventType>)` | `前端表单进入V8事件(InFormV8).js` |
|
|
26
|
+
| 字段事件 | `<事件中文名>(<英文Key>)` | `值变更V8事件(V8Code).js` |
|
|
27
|
+
| 按钮 | `<按钮Name>(<按钮Id>)` | `指派(01K3X...).js` |
|
|
28
|
+
| 按钮显隐 | `<按钮Name>_显隐判断(<按钮Id>)` | `指派_显隐判断(01K3X...).js` |
|
|
29
|
+
| 按钮分类目录 | `<按钮类型中文>(<EnglishField>)` | `[行]更多按钮(MoreBtns)/` |
|
|
30
|
+
|
|
31
|
+
### 0.1 7 类表单 V8 事件中文名(以 `diy_table` 对应 `diy_field.Label` 为准)
|
|
32
|
+
|
|
33
|
+
| EventType | 中文名 |
|
|
34
|
+
|-----------|--------|
|
|
35
|
+
| InFormV8 | 前端表单进入V8事件 |
|
|
36
|
+
| SubmitFormV8 | 前端表单提交前V8事件 |
|
|
37
|
+
| SubmitBeforeServerV8 | 后端表单提交前V8事件 |
|
|
38
|
+
| SubmitAfterServerV8 | 后端表单提交后V8事件 |
|
|
39
|
+
| ServerDataV8 | 后端数据处理V8事件 |
|
|
40
|
+
| OutFormV8 | 前端表单提交后V8事件 |
|
|
41
|
+
| DataFilterV8 | 后端数据过滤V8事件 |
|
|
42
|
+
|
|
43
|
+
> 统一用“后端”,不要再生成“服务端”或“服务器端”可见目录/文件名。
|
|
44
|
+
|
|
45
|
+
### 0.2 4 类字段 V8 事件中文名
|
|
46
|
+
|
|
47
|
+
| Key | 中文名 |
|
|
48
|
+
|-----|--------|
|
|
49
|
+
| V8Code | 值变更V8事件 |
|
|
50
|
+
| KeyupV8Code | 键盘抬起V8事件 |
|
|
51
|
+
| V8TmpEngineTable | 表格列模板V8事件 |
|
|
52
|
+
| V8TmpEngineForm | 表单字段模板V8事件 |
|
|
53
|
+
|
|
54
|
+
### 0.3 6 类按钮中文名
|
|
55
|
+
|
|
56
|
+
| Field | 中文名 |
|
|
57
|
+
|-------|--------|
|
|
58
|
+
| PageTabs | 页面多Tab |
|
|
59
|
+
| PageBtns | [页面]更多按钮 |
|
|
60
|
+
| MoreBtns | [行]更多按钮 |
|
|
61
|
+
| FormBtns | [表单]更多按钮 |
|
|
62
|
+
| BatchSelectMoreBtns | [批量选择]更多按钮 |
|
|
63
|
+
| ExportMoreBtns | [导出]更多按钮 |
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 1. 当前结构(v1 基线)
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
<workspace>/microi-v8-engine/
|
|
71
|
+
├── 接口引擎/
|
|
72
|
+
│ └── <ApiEngineName>(<ApiEngineKey>).js // 半角括号,保留不变
|
|
73
|
+
└── V8事件/
|
|
74
|
+
└── <表Description(表Name)>/
|
|
75
|
+
└── <EventType>.js // 扁平,无中文事件名
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## 2. 目标结构(v2)
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
<workspace>/microi-v8-engine/<server>/<osClient>/
|
|
82
|
+
├── 接口引擎/ // 保持不变
|
|
83
|
+
│ └── <分类>/<ApiEngineName>(<ApiEngineKey>).js
|
|
84
|
+
│
|
|
85
|
+
├── 表单引擎/
|
|
86
|
+
│ └── <表Label>(<表Name>)/
|
|
87
|
+
│ ├── 表单V8事件/
|
|
88
|
+
│ │ ├── 前端表单进入V8事件(InFormV8).js // 仅远端非空代码生成文件
|
|
89
|
+
│ │ ├── 前端表单提交前V8事件(SubmitFormV8).js
|
|
90
|
+
│ │ ├── 后端表单提交前V8事件(SubmitBeforeServerV8).js
|
|
91
|
+
│ │ ├── 后端表单提交后V8事件(SubmitAfterServerV8).js
|
|
92
|
+
│ │ ├── 后端数据处理V8事件(ServerDataV8).js
|
|
93
|
+
│ │ ├── 前端表单提交后V8事件(OutFormV8).js
|
|
94
|
+
│ │ └── 后端数据过滤V8事件(DataFilterV8).js
|
|
95
|
+
│ └── 字段V8事件/
|
|
96
|
+
│ └── <字段Label>(<字段Name>)/
|
|
97
|
+
│ ├── 值变更V8事件(V8Code).js // 右键单表拉取后生成,仅远端非空代码生成文件
|
|
98
|
+
│ ├── 键盘V8事件(KeyupV8Code).js
|
|
99
|
+
│ ├── 模板V8引擎(表格)(V8TmpEngineTable).js
|
|
100
|
+
│ └── 模板V8引擎(表单)(V8TmpEngineForm).js
|
|
101
|
+
│
|
|
102
|
+
└── 模块引擎/
|
|
103
|
+
└── <父菜单Name>(<ParentMenuId>)/ // 非叶子模块只显示子模块,不生成按钮目录
|
|
104
|
+
└── <叶子菜单Name>(<LeafMenuId>)/
|
|
105
|
+
├── Join关联(SqlJoin).js // 始终生成,直接映射 sys_menu.SqlJoin
|
|
106
|
+
├── Where条件(SqlWhere).js // 始终生成,直接映射 sys_menu.SqlWhere
|
|
107
|
+
├── 页面多Tab(PageTabs)/ // 叶子模块固定生成全部 6 个按钮目录,即使为空
|
|
108
|
+
│ ├── <按钮Name>(<按钮Id>).js // V8Code,仅远端非空代码生成文件
|
|
109
|
+
│ └── <按钮Name>_显隐判断(<按钮Id>).js // V8CodeShow,仅在非空时生成
|
|
110
|
+
├── [页面]更多按钮(PageBtns)/
|
|
111
|
+
├── [行]更多按钮(MoreBtns)/
|
|
112
|
+
├── [表单]更多按钮(FormBtns)/
|
|
113
|
+
├── [批量选择]更多按钮(BatchSelectMoreBtns)/
|
|
114
|
+
└── [导出]更多按钮(ExportMoreBtns)/
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 2.1 ⚠️ 空代码不落文件规则(关键约束)
|
|
118
|
+
|
|
119
|
+
> **前端 V8 引擎**只要事件 / 按钮代码字符串非空(哪怕只有注释、空格),就会调用 Jint 解析并执行——产生不必要的 CPU 开销。
|
|
120
|
+
>
|
|
121
|
+
> 因此:拉取远端资源时,空 V8 代码**不要生成本地 `.js` 文件**。若历史同步留下空 `.js` 文件,且远端代码同样为空,应删除本地空文件,避免被“查看同步状态”误判为本地未推送。
|
|
122
|
+
>
|
|
123
|
+
> 用户需要清空远端代码时,可以把已有非空文件清空并推送;推送成功后插件应删除该本地空文件或对齐为“无本地文件”状态。
|
|
124
|
+
>
|
|
125
|
+
> 例外:`SqlJoin`、`SqlWhere` 是模块查询配置,不是按钮 V8 事件。叶子模块必须始终生成两个平级文件,空文件表示远端字段为空,并允许通过推送空文件清空对应字段。
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## 3. 数据流
|
|
130
|
+
|
|
131
|
+
### 3.1 表单 V8 事件(✅ 已实现 2026-05)
|
|
132
|
+
|
|
133
|
+
- **拉取**:复用 `GetV8EventList`。对每个返回项:
|
|
134
|
+
1. 每张表固定生成表单 V8 事件目录
|
|
135
|
+
2. 仅远端非空代码生成 `.js`;空代码不生成文件,历史空文件应删除
|
|
136
|
+
- **保存**:`parseEventFilePath` 解析新旧两种结构,调 `UpdateV8EventCode`
|
|
137
|
+
- **删除**:用户删除本地文件默认只删除本地文件,不自动清空远端;清空远端必须通过清空已有文件内容并执行推送,或使用明确的“清空远端代码”命令
|
|
138
|
+
|
|
139
|
+
### 3.2 字段 V8 事件(✅ 已实现 2026-05)
|
|
140
|
+
|
|
141
|
+
**接口**:
|
|
142
|
+
- `GET /api/V8Debug/GetFieldList?osClient&tableId` — 返回字段列表带 `V8Code/KeyupV8Code/V8TmpEngineTable/V8TmpEngineForm`
|
|
143
|
+
- `POST /api/V8Debug/UpdateField` — Body 含 `Id` 或 `TableName + Name`,仅 V8 字段更新时直接写 `diy_field`,不触发表字段物理列变更
|
|
144
|
+
|
|
145
|
+
**实施清单**:
|
|
146
|
+
1. 在 `engineTreeProvider.ts` 的表节点加 inline action「拉取此表字段V8事件」
|
|
147
|
+
2. 调 `GetFieldList` 拿字段,对每个字段固定生成 4 个文件:`字段V8事件/<Label>(<Name>)/<事件中文>(<Key>).js`
|
|
148
|
+
3. 保存时按文件路径解析 `(TableId, FieldName, V8Key)` → 调 `UpdateField`
|
|
149
|
+
|
|
150
|
+
### 3.3 sys_menu 按钮 JSON 拆分(✅ 已实现 2026-05)
|
|
151
|
+
|
|
152
|
+
**接口**:
|
|
153
|
+
- `GET /api/V8Debug/GetModule?osClient&moduleId` — 返回菜单详情,包含 6 类按钮 JSON 以及 `SqlJoin/SqlWhere`
|
|
154
|
+
- `POST /api/V8Debug/UpdateModule` — Body 含 `OsClient/ModuleId` 以及目标按钮字段或 `SqlJoin/SqlWhere`
|
|
155
|
+
|
|
156
|
+
**拉取**:
|
|
157
|
+
1. 解析 `PageTabs/PageBtns/MoreBtns/FormBtns/BatchSelectMoreBtns/ExportMoreBtns` 6 个 JSON 数组(非法 JSON 记录错误并跳过该字段)
|
|
158
|
+
2. 按 `ParentId` 生成与 `sys_menu/GetSysMenuStep` 一致的模块树;非叶子模块只生成子模块目录,不生成按钮目录
|
|
159
|
+
3. 叶子模块固定生成全部 6 个按钮分类目录,并直接生成 `Join关联(SqlJoin).js`、`Where条件(SqlWhere).js`;两个配置文件即使远端为空也必须生成
|
|
160
|
+
4. 对每个按钮:
|
|
161
|
+
- 仅在 `V8Code` 非空时生成 `<按钮Name>(<按钮Id>).js`
|
|
162
|
+
- 若 `V8CodeShow` 非空 → 生成 `<按钮Name>_显隐判断(<按钮Id>).js`
|
|
163
|
+
- 在空按钮目录中新建 `<按钮Name>(<按钮Id>).js` 并推送时,可按文件名创建远端新按钮
|
|
164
|
+
5. `.microi-meta.json` 写入按钮 JSON hash;回写前写 `.backups/<moduleId>/<ButtonField>-<timestamp>.json`
|
|
165
|
+
|
|
166
|
+
**保存(事务,必须满足 §4 全部不变量)**:
|
|
167
|
+
1. 从文件路径解析 `ModuleId / ButtonField / ButtonId / V8Code 或 V8CodeShow`
|
|
168
|
+
2. 二次调 `GetModule` 拉远端当前 JSON
|
|
169
|
+
3. JSON 解析失败立即中止
|
|
170
|
+
4. **Id-Diff 合并**:只修改目标按钮的 `V8Code` 或 `V8CodeShow`,远端其它按钮全部原样保留
|
|
171
|
+
5. 写一份 `.backups/<moduleId>/<ButtonField>-<timestamp>.json`(变更前的远端 JSON)
|
|
172
|
+
6. 调 `UpdateModule` 整段写回;任何一步失败不写库
|
|
173
|
+
|
|
174
|
+
**SqlJoin/SqlWhere 保存**:从文件路径解析 `ModuleId / SqlJoin|SqlWhere`,推送前重新 `GetModule`,备份远端原字段,`UpdateModule` 只提交目标字段;成功后必须再次 `GetModule` 回读正文完全一致,才更新 meta/mtime。空正文正常保留为空文件。
|
|
175
|
+
|
|
176
|
+
**修改状态**:接口引擎、表单V8事件、字段V8事件、模块按钮、模块 SqlJoin/SqlWhere 文件都必须写入 `.microi-meta.json` 的 `updateTime/filePath`;本地 `mtime > updateTime + 1s` 时树节点显示 `已修改`,推送成功后同步更新 meta 并将文件 mtime 设置为远端更新时间以清除标记。
|
|
177
|
+
|
|
178
|
+
**MCP 请求服务 OsClient 规则**:`CheckPermission()` 返回的 `token` 是 `dynamic`。调用 `V8McpLogic.ResolveOsClient` 时必须传 `(object)token`,并让 `ResolveOsClient(string osClient, object currentToken)` 返回真正的 `string`;`Microi.MCP/Http/V8McpEndpointService.cs` 中 OsClient 空判断用 `string.IsNullOrWhiteSpace(osClient)`,不要对 `osClient` 调 `DosIsNullOrWhiteSpace()`。
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## 4. 风险与不变量(实施 Stage 2/3 前必读)
|
|
183
|
+
|
|
184
|
+
| # | 不变量 | 违反后果 | 检测手段 |
|
|
185
|
+
|---|--------|---------|---------|
|
|
186
|
+
| I1 | 按钮 `Id` 必须保留且唯一 | 远端按钮丢失/重复 | 文件名中 `(<Id>)` 段 + 头部 `@ButtonId` 双校验,二者必须一致 |
|
|
187
|
+
| I2 | 远端按钮在本地缺失时**保留**而非删除 | 用户只拉了一类按钮就保存 → 其余被清空 | 保存前必须 `GetModule` 重新拉取做 Id-Diff |
|
|
188
|
+
| I3 | 远端整段 JSON 哈希在保存前必须匹配 | 多人/多端冲突覆盖 | `.microi-menu.json.RemoteHash` 检查 |
|
|
189
|
+
| I4 | 任何 JSON 解析失败必须中止保存 | JSON 损坏 | try/catch + 弹窗 |
|
|
190
|
+
| I5 | 按钮元数据头被用户改坏(如 `@ButtonId` 被删) | 写回失败 | 元数据头丢失 → 该文件标记 dirty,提示从远端覆盖 |
|
|
191
|
+
| I6 | 每次回写前自动写 `.backups/<timestamp>.json` | 误操作可恢复 | 强制执行,无配置开关 |
|
|
192
|
+
| I7 | 用户重命名/删除按钮文件 | 误操作 | 重命名按 Id 匹配;删除需弹窗输入按钮名二次确认 |
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## 5. 实施状态(2026-05-22)
|
|
197
|
+
|
|
198
|
+
- ✅ **Stage 1 表单V8事件分层 + 中文命名 + 空代码跳过文件生成** —— 已实现
|
|
199
|
+
- ✅ **Stage 2 字段V8事件** —— 已实现:右键单表拉取字段 V8 事件;空代码不生成文件;推送仅更新目标字段的目标 V8 字段
|
|
200
|
+
- ✅ **Stage 3 sys_menu 按钮拆分** —— 已实现:主拉取同步模块引擎;按钮 V8Code 仅在非空时生成 `.js`;推送前重拉远端 JSON、按 ButtonId 只改目标按钮并保留其它按钮,写入前自动备份
|
|
201
|
+
- ✅ **Stage 4 树形模块引擎 + 全类型修改状态** —— 已实现:模块按 ParentId 树形拉取;非叶子只显示子模块;叶子固定生成 6 个按钮目录;字段/按钮文件也显示并清除 `已修改`
|
|
202
|
+
- ✅ **Stage 5 sys_menu 查询脚本本地化** —— 已实现:叶子模块固定生成 `SqlJoin/SqlWhere` 两个平级 `.js` 文件,支持备份、预检、推送、远端回读和修改状态
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 6. 实施约束总结
|
|
207
|
+
|
|
208
|
+
- **不要**在没看过 §4 全部 7 条不变量就动手实现 Stage 3
|
|
209
|
+
- **不要**为远端空 V8 事件/按钮代码生成 `.js` 文件;`SqlJoin/SqlWhere` 属于查询配置,必须保留空文件
|
|
210
|
+
- **不要**用半角括号;统一用全角 `()`
|
|
211
|
+
- **不要**清空 V8事件/ 旧目录;保留兼容直到用户主动删除
|
|
212
|
+
- 文件名中 `<英文Key>` 段必须 ASCII,避免 Windows 不可见字符
|
|
213
|
+
- 远端 Key 若含 `\`、`/`、括号或 Windows 非法字符,文件名中的 Key 段必须使用可逆百分号编码;解析和推送时必须解码回原始 Key,禁止用 `_` 不可逆替换后误更新另一条远端记录。文件名还要处理控制字符、结尾空格/点和 `CON/PRN/AUX/NUL/COM1/LPT1` 等 Windows 保留名。
|
|
214
|
+
- “拉取此服务器代码”必须按接口引擎、表单引擎、模块引擎、流程引擎、数据库结构分阶段执行。某一类型失败时要记录明细并继续后续类型;同一类型内单个文件写入失败也要继续下一项,禁止首个 `ENOENT` 让整个服务器只留下半套源码。
|
|
215
|
+
|
|
216
|
+
## 7. AI 远端修改后的同步约束
|
|
217
|
+
|
|
218
|
+
AI 使用 MCP、接口引擎、数据库脚本或平台 API 修改远端 V8 代码后,必须在任务收尾时同步本地 V8 资源树,并用“查看同步状态”或等价 dry-run 复核。
|
|
219
|
+
|
|
220
|
+
- 远端写入后以远端当前生效代码为准,回写本地文件并更新/对齐 meta 与文件 mtime。
|
|
221
|
+
- 覆盖范围至少包含本次 touched 的接口引擎、表单 V8 事件、字段 V8 事件、模块按钮 V8、工作流节点 V8、数据源 V8。
|
|
222
|
+
- 若没有插件 API 可调用,可在 `.tmp/` 编写一次性同步脚本;脚本必须先 dry-run 输出差异数量,再 apply。
|
|
223
|
+
- 收尾复核应确认 touched 范围没有 `changed/created/local-only` 差异;若存在差异,必须在最终回复中说明原因。
|
|
224
|
+
- 空 V8 代码不生成本地 `.js` 文件;同步收尾时应清理历史空文件。
|
|
225
|
+
- 插件“查看同步状态”不能只显示数量。若本地未推送数量大于 0,必须能列出具体资源类型、Key、名称、同步基准时间、本地修改时间和文件路径,并支持直接打开该文件。
|
|
226
|
+
- 接口引擎、表单引擎、模块引擎、流程引擎四个顶层分类必须分别提供行内“查看同步状态”,分类检测只请求该类型的远端数据,禁止每次强制扫描全部引擎。表单引擎范围必须同时覆盖表单 V8 事件与字段 V8 事件,模块引擎范围必须覆盖按钮 V8 与 `SqlJoin/SqlWhere`。
|
|
227
|
+
- 一次同步检测的结果必须持久保留在侧边“同步结果”树中,按双方冲突、服务器较新、本地未推送分组;用户应能连续点击不同文件查看远端/本地差异,只有主动刷新时才重新请求服务器,禁止每查看一个文件都重新执行整次检测。
|
|
228
|
+
- 表单事件、字段事件、按钮事件等远端 Key 比对要做大小写兼容;当本地代码与远端代码相同但 mtime 晚于 meta 时,应自动刷新 meta/mtime,避免误报“本地未推送”。
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
# 已提交应用的 CDN 特殊字符别名修复
|
|
2
|
-
|
|
3
|
-
## 已提交应用的 CDN 特殊字符别名修复(强制)
|
|
4
|
-
|
|
5
|
-
- 区分逻辑路径、对象键和 URL:原始 `@` 对象的 URL 可写 `%40`;字面量 `%40` 对象的 URL 需写 `%2540`。禁止在 HDFS 全局反解码对象键,禁止迁移或覆盖协议 v3 不可变编码对象、完整性标记及清单摘要。
|
|
6
|
-
- 此类修复使用现有受管接口引擎 `ai_app_cdn_backfill` 的 `Action=RepairCommittedCdnAliases`,不是任意文件复制接口。当前租户超级管理员仍须满足 `Level >= 9999`,精确匹配 `AppId/ConfirmAppId`;只补充已提交公有运行资产的原始 `@` 别名,不接收文件体、桶、URL 或自定义来源/目标路径。
|
|
7
|
-
- 先回读商城及完整版本记录,显式冻结 `ExpectedAppKey/ExpectedVersionId/ExpectedVersionNo`、`ExpectedRequestId/ExpectedRequestFingerprint/ExpectedRuntimeManifestHash`、`ExpectedCommittedPublishVersionId/ExpectedCommittedRuntimeManifestHash`、`ExpectedCurrentVersion/ExpectedPublishFence/ExpectedPublishRowVersion`。后三个数值使用规范十进制字符串。服务端须同时核对活动指针、协议、版本归属、版本 `FencingToken`、派生 `ReleasePrefix` 及完整清单;不得用调用方传入的清单替代权威记录。
|
|
8
|
-
- 商城与版本状态只接受 `ProjectionPending/RepairRequired/Completed`。完整运行清单按平台 ordinal 路径顺序,以 `Path<TAB>Sha256<TAB>Size`、行间 LF、末尾无 LF、UTF-8 重算 SHA-256;后续每次回读还须保持冻结清单字符串不变。指针、活动版本、栅栏、行版本或清单变化即停止,先核对部分副作用,再重新取得契约,不能盲目替换预期值续跑。
|
|
9
|
-
- 仅接受 `assets/<bundle>/import/<两位十六进制>/<文件名>@<子资源>.json` 的非入口、公有运行 JSON,每个不超过 1 MiB;拒绝源码、私有资源、百分号转义、绝对路径、目录穿越和不支持的 `@` 路径。来源为同版本目录中把原始 `@` 替换成字面量 `%40` 的既有对象;目标为版本目录及固定目录的原始 `@` 对象。全部使用当前租户内对象路径和 `Limit:false`,不能用 HTTPS 来源 URL 代替。
|
|
10
|
-
- `DryRun` 默认 `true`,显式 `false` 才复制。`AliasStart` 是冻结清单内符合条件的原始 `@` JSON 列表的零基游标,`AliasCount` 只允许 1–5;每资产最多复制版本和固定两个别名,一批最多 10 次复制。写入前预检整批来源和已有目标:`Sha256` 是原始物理字节摘要,与 `Size` 一同绑定清单;`WireSha256` 是字节转为 Base64 文本后的历史兼容摘要,只校验格式及来源、目标一致,禁止将它与清单原始摘要作相等判断。目标同字节跳过,任一不同即整批拒绝。每次复制前后重新核对摘要及最新绑定。
|
|
11
|
-
- `V8.Method.CopyObject` 没有原子的 create-if-absent/禁止覆盖保证,此动作必须如实返回 `AtomicCreateOnly:false`。预检查存在检查与复制之间的竞态,不能与另一发布者或任意写入者竞争同一固定路径;原后台投影可继续写同一冻结版本的相同字节。不得把“先查不存在再复制”描述为原子 create-only。
|
|
12
|
-
- 每批先 DryRun,再用同一绑定复制,保存 `Attempted/Copied/RequiresReadback/NextAliasStart`,从版本与固定 CDN 独立核对实际字节后再续批。超时、未知结果或 `Code=0` 先回读已尝试路径,不能盲重试;数据库事务无法回滚 OSS 副作用。禁止删除旧对象、重新上传字节、HTTP 回退或直接修改数据库状态。
|
|
13
|
-
- 修复不刷新 CDN、不推进指针、不修改清单或发布状态。原后台必须继续完成刷新、公开回读与 `Completed` 状态收敛;不能以对象复制成功代替公网资源及真实浏览器验收。操作说明见 [分布式存储](https://microi.net/doc/more/hdfs.html)。
|
|
1
|
+
# 已提交应用的 CDN 特殊字符别名修复
|
|
2
|
+
|
|
3
|
+
## 已提交应用的 CDN 特殊字符别名修复(强制)
|
|
4
|
+
|
|
5
|
+
- 区分逻辑路径、对象键和 URL:原始 `@` 对象的 URL 可写 `%40`;字面量 `%40` 对象的 URL 需写 `%2540`。禁止在 HDFS 全局反解码对象键,禁止迁移或覆盖协议 v3 不可变编码对象、完整性标记及清单摘要。
|
|
6
|
+
- 此类修复使用现有受管接口引擎 `ai_app_cdn_backfill` 的 `Action=RepairCommittedCdnAliases`,不是任意文件复制接口。当前租户超级管理员仍须满足 `Level >= 9999`,精确匹配 `AppId/ConfirmAppId`;只补充已提交公有运行资产的原始 `@` 别名,不接收文件体、桶、URL 或自定义来源/目标路径。
|
|
7
|
+
- 先回读商城及完整版本记录,显式冻结 `ExpectedAppKey/ExpectedVersionId/ExpectedVersionNo`、`ExpectedRequestId/ExpectedRequestFingerprint/ExpectedRuntimeManifestHash`、`ExpectedCommittedPublishVersionId/ExpectedCommittedRuntimeManifestHash`、`ExpectedCurrentVersion/ExpectedPublishFence/ExpectedPublishRowVersion`。后三个数值使用规范十进制字符串。服务端须同时核对活动指针、协议、版本归属、版本 `FencingToken`、派生 `ReleasePrefix` 及完整清单;不得用调用方传入的清单替代权威记录。
|
|
8
|
+
- 商城与版本状态只接受 `ProjectionPending/RepairRequired/Completed`。完整运行清单按平台 ordinal 路径顺序,以 `Path<TAB>Sha256<TAB>Size`、行间 LF、末尾无 LF、UTF-8 重算 SHA-256;后续每次回读还须保持冻结清单字符串不变。指针、活动版本、栅栏、行版本或清单变化即停止,先核对部分副作用,再重新取得契约,不能盲目替换预期值续跑。
|
|
9
|
+
- 仅接受 `assets/<bundle>/import/<两位十六进制>/<文件名>@<子资源>.json` 的非入口、公有运行 JSON,每个不超过 1 MiB;拒绝源码、私有资源、百分号转义、绝对路径、目录穿越和不支持的 `@` 路径。来源为同版本目录中把原始 `@` 替换成字面量 `%40` 的既有对象;目标为版本目录及固定目录的原始 `@` 对象。全部使用当前租户内对象路径和 `Limit:false`,不能用 HTTPS 来源 URL 代替。
|
|
10
|
+
- `DryRun` 默认 `true`,显式 `false` 才复制。`AliasStart` 是冻结清单内符合条件的原始 `@` JSON 列表的零基游标,`AliasCount` 只允许 1–5;每资产最多复制版本和固定两个别名,一批最多 10 次复制。写入前预检整批来源和已有目标:`Sha256` 是原始物理字节摘要,与 `Size` 一同绑定清单;`WireSha256` 是字节转为 Base64 文本后的历史兼容摘要,只校验格式及来源、目标一致,禁止将它与清单原始摘要作相等判断。目标同字节跳过,任一不同即整批拒绝。每次复制前后重新核对摘要及最新绑定。
|
|
11
|
+
- `V8.Method.CopyObject` 没有原子的 create-if-absent/禁止覆盖保证,此动作必须如实返回 `AtomicCreateOnly:false`。预检查存在检查与复制之间的竞态,不能与另一发布者或任意写入者竞争同一固定路径;原后台投影可继续写同一冻结版本的相同字节。不得把“先查不存在再复制”描述为原子 create-only。
|
|
12
|
+
- 每批先 DryRun,再用同一绑定复制,保存 `Attempted/Copied/RequiresReadback/NextAliasStart`,从版本与固定 CDN 独立核对实际字节后再续批。超时、未知结果或 `Code=0` 先回读已尝试路径,不能盲重试;数据库事务无法回滚 OSS 副作用。禁止删除旧对象、重新上传字节、HTTP 回退或直接修改数据库状态。
|
|
13
|
+
- 修复不刷新 CDN、不推进指针、不修改清单或发布状态。原后台必须继续完成刷新、公开回读与 `Completed` 状态收敛;不能以对象复制成功代替公网资源及真实浏览器验收。操作说明见 [分布式存储](https://microi.net/doc/more/hdfs.html)。
|