flycode-mcp 1.8.0 → 1.9.0
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/README.md +51 -4
- package/dist/service/logic.js +192 -0
- package/dist/service/logic.js.map +1 -1
- package/dist/tools/logic/write.js +147 -1
- package/dist/tools/logic/write.js.map +1 -1
- package/dist/tools/run/read.js +1 -1
- package/dist/tools/run/read.js.map +1 -1
- package/dist/utils/str-replace.js +353 -0
- package/dist/utils/str-replace.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -156,6 +156,51 @@ username=<账号>&password=<密码>&tenantCode=<租户号>&envName=<环境名>
|
|
|
156
156
|
|
|
157
157
|
> 注:`input` / `output` 与 `save_model_logic` 中的结构一致(`LogicParameters[]`,含 `datatype` / `marktype` / `name` / `objectcode` / `objectname` / `properties` 等字段)。仅需变更 `flycode` 时,可只传 `modelLogicCode` + `flycode`,`input` / `output` 留空由服务端保留原值。
|
|
158
158
|
|
|
159
|
+
### `str_replace_flycode` — 批量局部替换 flycode 脚本
|
|
160
|
+
|
|
161
|
+
以 str_replace_editor 模式局部修改业务逻辑的 flycode 脚本:**只需传入要改动的新旧代码片段**,不必回传整份脚本。底层调用 `service/logic.ts` 的 `replaceFlyCodeSegments`:按 `modelLogicCode` 拉取完整对象,在内存副本上完成定位与替换,再以 `overwrite: false` 提交一次 `saveModelLogic`。
|
|
162
|
+
|
|
163
|
+
**与另两个写工具的分工:**
|
|
164
|
+
|
|
165
|
+
| 场景 | 建议工具 |
|
|
166
|
+
| ------------------------------------------------ | --------------------------------- |
|
|
167
|
+
| 改 1~N 处局部片段(最常用) | `str_replace_flycode` |
|
|
168
|
+
| 整份脚本重写、大范围重构 | `simple_save_flycode_model_logic` |
|
|
169
|
+
| 非 flycode 领域(导出 / 微服务)或改 input/output | `save_model_logic` |
|
|
170
|
+
|
|
171
|
+
**事务性**:`ops` 具备事务性——全部 op 预演成功才落库,任一 op 失败则整批中止、**不产生任何写入**。实现上整批只发起一次保存请求,因此不存在「写一半再回滚」的中间态。
|
|
172
|
+
|
|
173
|
+
**执行顺序**:`ops` 按数组顺序依次执行,`ops[i+1]` 在 `ops[i]` 的结果上匹配,因此支持「先插入一段代码、再改这段里的某行」这类依赖。
|
|
174
|
+
|
|
175
|
+
**输入参数:**
|
|
176
|
+
|
|
177
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
178
|
+
| ---------------- | ------- | ---- | ------------------------------------------------------------------------ |
|
|
179
|
+
| `modelLogicCode` | string | 是 | 要修改的业务逻辑编码 |
|
|
180
|
+
| `ops` | array | 是 | 替换操作数组,**至少一个元素**(`min(1)`),按数组顺序依次执行 |
|
|
181
|
+
| `commitMessage` | object | 是 | 提交信息,整批 ops 共用一个 |
|
|
182
|
+
| `dryRun` | boolean | 否 | 只预演输出 diff、不落库,默认 `false` |
|
|
183
|
+
| `contextLines` | number | 否 | diff 中每个改动点上下保留的上下文行数,默认 `3` |
|
|
184
|
+
| `verify` | boolean | 否 | 保存后是否回读校验所有改动已生效,默认 `true` |
|
|
185
|
+
|
|
186
|
+
`ops[]` 元素:
|
|
187
|
+
|
|
188
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
189
|
+
| ---------------- | -------------------------- | ---- | -------------------------------------------------------------------- |
|
|
190
|
+
| `oldString` | string | 是 | 待替换原文,必须非空且在目标脚本中唯一命中 |
|
|
191
|
+
| `newString` | string | 是 | 替换后的新文本,传空串表示删除 |
|
|
192
|
+
| `operationIndex` | number | 否 | 作用于第几个 operation 的脚本,默认 `0` |
|
|
193
|
+
| `replaceAll` | boolean | 否 | 替换全部匹配,默认 `false`;与 `occurrence` 互斥 |
|
|
194
|
+
| `occurrence` | number | 否 | 只替换第 N 个匹配(1-based);与 `replaceAll` 互斥 |
|
|
195
|
+
| `matchMode` | `'exact' \| 'normalized'` | 否 | 默认 `normalized`,容忍 CRLF/LF 与行尾空白差异;`exact` 为字节严格相等 |
|
|
196
|
+
| `label` | string | 否 | 可选标识,仅用于返回报告中辨认该 op |
|
|
197
|
+
|
|
198
|
+
**返回:** `ok` / `applied` / `verified` / `errorCode` / `message` / `lengthBefore` / `lengthAfter` / `diff` / `ops[]`。其中 `ops[].message` 说明失败原因,`NOT_FOUND` 时 `ops[].suggestions` 给出最相似的候选(行号 + 相似度 + 预览),`diff` 只回改动片段、不回整份脚本。
|
|
199
|
+
|
|
200
|
+
**匹配与容错:** 默认 `normalized` 模式会先做归一化再匹配(CRLF/CR 统一为 LF、忽略行尾空白),并把 `newString` 的换行符统一成源脚本的主导换行符,避免混用。`oldString` 未命中 / 命中多处时分别报 `NOT_FOUND` / `NOT_UNIQUE` 并整批中止。
|
|
201
|
+
|
|
202
|
+
**失败即关闭:** 成功后重复调用同一 `oldString` 会因原文已不存在而报 `NOT_FOUND`,不会重复写入。
|
|
203
|
+
|
|
159
204
|
### `page_entity_list` — 分页查询实体列表
|
|
160
205
|
|
|
161
206
|
根据查询条件分页查询 APaaS 平台中的实体定义(只读、幂等)。底层调用 `entityClient.pageEntityList`。
|
|
@@ -341,7 +386,7 @@ flycode-mcp/
|
|
|
341
386
|
│ ├── index.ts # 入口:启动鉴权、注册工具、启动 stdio 服务
|
|
342
387
|
│ ├── service/ # 业务封装
|
|
343
388
|
│ │ ├── auth.ts # 登录 → 获取租户信息 → 获取 IDE Token
|
|
344
|
-
│ │ └── logic.ts # 保存业务逻辑(saveModelLogic / simpleSaveFlyCodeModelLogic):提交信息处理 + 异常兜底
|
|
389
|
+
│ │ └── logic.ts # 保存业务逻辑(saveModelLogic / simpleSaveFlyCodeModelLogic / replaceFlyCodeSegments):提交信息处理 + 局部替换 + 异常兜底
|
|
345
390
|
│ ├── clients/ # 平台接口封装
|
|
346
391
|
│ │ ├── authClient.ts # 登录 / 获取租户信息 / 获取 IDE Token 请求
|
|
347
392
|
│ │ ├── logicClient.ts # 业务逻辑分页/详情查询、保存请求
|
|
@@ -358,7 +403,7 @@ flycode-mcp/
|
|
|
358
403
|
│ │ ├── common.ts # 通用工具(generate_unique_code:雪花算法生成唯一编码)
|
|
359
404
|
│ │ ├── logic/
|
|
360
405
|
│ │ │ ├── read.ts # 只读类工具(page_model_logic_list / get_model_logic)
|
|
361
|
-
│ │ │ ├── write.ts # 写入类工具(save_model_logic / simple_save_model_logic)
|
|
406
|
+
│ │ │ ├── write.ts # 写入类工具(save_model_logic / simple_save_model_logic / str_replace_flycode)
|
|
362
407
|
│ │ │ └── schemas.ts # 业务逻辑共享 zod schema(LogicResult / 参数 / operations / bindjson)
|
|
363
408
|
│ │ ├── entity/
|
|
364
409
|
│ │ │ ├── read.ts # 只读类工具(page_entity_list / get_entity)
|
|
@@ -376,7 +421,9 @@ flycode-mcp/
|
|
|
376
421
|
│ ├── request.ts # 统一 axios 请求层(中心/租户地址切换 + Token 注入)
|
|
377
422
|
│ ├── mcp-types.ts # MCP 工具统一定义类型 ToolDef
|
|
378
423
|
│ ├── snowflake.ts # 雪花算法 ID 生成器(generate_unique_code 依赖)
|
|
379
|
-
│
|
|
424
|
+
│ ├── date.ts # 日期格式化工具(saverecord 提交时间用)
|
|
425
|
+
│ ├── error.ts # 统一错误信息提取
|
|
426
|
+
│ └── str-replace.ts # str_replace_editor 模式纯文本替换(归一化匹配 / 批量 applyOps / diff hunk / 候选建议)
|
|
380
427
|
├── dist/ # 编译产物(由 tsc 生成,已忽略)
|
|
381
428
|
├── package.json
|
|
382
429
|
├── tsconfig.json
|
|
@@ -391,7 +438,7 @@ flycode-mcp/
|
|
|
391
438
|
2. **登录**:`service/auth.ts` 中的 `authenticate()` 调用 `/api/multiplat/auth/login` 获取 Token,存入内存。
|
|
392
439
|
3. **定位租户与环境**:`authenticate()` 调用 `/api/multiplat/auth/getTenantInfo`,依据 `tenantCode + envName` 匹配出目标租户,保存其连接信息(`conn.config`)到内存。
|
|
393
440
|
4. **获取 IDE Token**:`authenticate()` 调用 `/api/multiplat/auth/getIdeToken` 换取 IDE 专用 Token 并覆盖内存中的 Token。
|
|
394
|
-
5. **注册并启动**:创建 `McpServer`,注册 `page_model_logic_list`、`get_model_logic`、`save_model_logic`、`simple_save_flycode_model_logic`、`page_entity_list`、`get_entity`、`page_form_list`、`get_form`、`page_function_list`、`get_function`、`page_database_function_list`、`run_sql`、`generate_unique_code` 等工具,通过 `StdioServerTransport` 监听请求。
|
|
441
|
+
5. **注册并启动**:创建 `McpServer`,注册 `page_model_logic_list`、`get_model_logic`、`save_model_logic`、`simple_save_flycode_model_logic`、`str_replace_flycode`、`page_entity_list`、`get_entity`、`page_form_list`、`get_form`、`page_function_list`、`get_function`、`page_database_function_list`、`run_sql`、`generate_unique_code` 等工具,通过 `StdioServerTransport` 监听请求。
|
|
395
442
|
6. **业务请求**:工具被调用时,`logicClient` / `entityClient` / `formClient` / `functionClient` / `runClient` 通过 `request({ type: "tenant" })` 自动切换到当前租户连接地址,并携带已注入的 Token 发起查询。
|
|
396
443
|
|
|
397
444
|
---
|
package/dist/service/logic.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getModelLogic, saveModelLogic as saveModelLogicApi } from "../clients/logicClient.js";
|
|
2
2
|
import { formatDate } from "../utils/date.js";
|
|
3
3
|
import { extractError } from "../utils/error.js";
|
|
4
|
+
import { applyOps } from "../utils/str-replace.js";
|
|
4
5
|
/**
|
|
5
6
|
* service 层保存业务逻辑方法
|
|
6
7
|
*
|
|
@@ -66,4 +67,195 @@ export async function simpleSaveFlyCodeModelLogic(modelLogicCode, flycode, input
|
|
|
66
67
|
// 3. 复用 saveModelLogic 落库(内部会写入 commitMessage 并以 overwrite=false 保存)
|
|
67
68
|
return saveModelLogic(logic, commitMessage);
|
|
68
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* diff 总行数上限,避免批量改动把上下文又吃回去。
|
|
72
|
+
*/
|
|
73
|
+
const MAX_DIFF_LINES = 150;
|
|
74
|
+
/**
|
|
75
|
+
* 拼接各 op 的 hunk 为一份总 diff,并在超长时截断。
|
|
76
|
+
*/
|
|
77
|
+
function joinHunks(results) {
|
|
78
|
+
const hunks = results
|
|
79
|
+
.filter((r) => r.hunk)
|
|
80
|
+
.map((r) => `--- ops[${r.index}]${r.label ? ` (${r.label})` : ''} @ operation[${r.operationIndex}]\n${r.hunk}`);
|
|
81
|
+
if (hunks.length === 0)
|
|
82
|
+
return '';
|
|
83
|
+
const text = hunks.join('\n');
|
|
84
|
+
const lines = text.split('\n');
|
|
85
|
+
if (lines.length <= MAX_DIFF_LINES)
|
|
86
|
+
return text;
|
|
87
|
+
return `${lines.slice(0, MAX_DIFF_LINES).join('\n')}\n... diff 过长已截断(共 ${lines.length} 行)`;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 写入提交信息并落库,返回是否成功。
|
|
91
|
+
*
|
|
92
|
+
* 与 saveModelLogic 的区别:saveModelLogic 在失败时也返回字符串,调用方无法区分成败;
|
|
93
|
+
* 而批量替换需要明确知道是否写成功(失败则不能回读校验),故这里返回 { ok, text }。
|
|
94
|
+
*/
|
|
95
|
+
async function commitAndSave(logic, commitMessage) {
|
|
96
|
+
if (commitMessage.committype === 'saverecord')
|
|
97
|
+
commitMessage.msgbody = formatDate(new Date(), 'YYYY-MM-DD HH:mm');
|
|
98
|
+
logic.message = JSON.stringify(commitMessage);
|
|
99
|
+
try {
|
|
100
|
+
// saveModelLogicApi 内部会附加 overwrite=false,服务端按版本拒绝冲突写入
|
|
101
|
+
const res = await saveModelLogicApi(logic);
|
|
102
|
+
return { ok: true, text: typeof res?.resp_data === 'string' ? res.resp_data : JSON.stringify(res?.resp_data ?? null) };
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
return { ok: false, text: extractError(e) };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* 批量局部替换 flycode 脚本(str_replace_editor 模式)。
|
|
110
|
+
*
|
|
111
|
+
* 与 simpleSaveFlyCodeModelLogic 的区别:后者需回传整份脚本,本方法只接收
|
|
112
|
+
* 改动片段(oldString / newString),由服务端拉取到的完整脚本上完成定位替换。
|
|
113
|
+
*
|
|
114
|
+
* 事务性实现(关键):
|
|
115
|
+
* 1. 只拉取一次完整 LogicResult,在内存副本上顺序预演全部 op;
|
|
116
|
+
* 2. 任一 op 失败(未命中 / 不唯一 / 参数非法)即整体中止,
|
|
117
|
+
* 由于此时尚未发起任何写请求,服务端状态从未改变,等价于「零写入回滚」;
|
|
118
|
+
* 3. 全部成功后只发起一次 saveModelLogic —— 事务边界即这一次写请求。
|
|
119
|
+
*
|
|
120
|
+
* 因此不存在「写一半再回滚」的中间态,比事后补偿更强。
|
|
121
|
+
*
|
|
122
|
+
* @param modelLogicCode 业务逻辑编码
|
|
123
|
+
* @param ops 替换操作数组,至少一个元素,按数组顺序依次作用于上一步结果
|
|
124
|
+
* @param commitMessage 提交信息,整批共用一个
|
|
125
|
+
* @param options dryRun / contextLines / verify
|
|
126
|
+
*/
|
|
127
|
+
export async function replaceFlyCodeSegments(modelLogicCode, ops, commitMessage, options = {}) {
|
|
128
|
+
const contextLines = options.contextLines ?? 3;
|
|
129
|
+
const dryRun = options.dryRun ?? false;
|
|
130
|
+
const verify = options.verify ?? true;
|
|
131
|
+
const abort = (errorCode, message) => ({
|
|
132
|
+
ok: false,
|
|
133
|
+
applied: false,
|
|
134
|
+
verified: null,
|
|
135
|
+
errorCode,
|
|
136
|
+
message,
|
|
137
|
+
lengthBefore: 0,
|
|
138
|
+
lengthAfter: 0,
|
|
139
|
+
diff: '',
|
|
140
|
+
ops: []
|
|
141
|
+
});
|
|
142
|
+
if (!Array.isArray(ops) || ops.length === 0) {
|
|
143
|
+
return abort('EMPTY_OPS', 'ops 至少需要一个元素');
|
|
144
|
+
}
|
|
145
|
+
// 1. 拉取完整对象(仅此一次读)
|
|
146
|
+
let logic;
|
|
147
|
+
try {
|
|
148
|
+
const res = await getModelLogic({ modellogiccode: modelLogicCode });
|
|
149
|
+
logic = res.resp_data;
|
|
150
|
+
}
|
|
151
|
+
catch (e) {
|
|
152
|
+
return abort('FETCH_FAILED', extractError(e));
|
|
153
|
+
}
|
|
154
|
+
if (!logic) {
|
|
155
|
+
return abort('FETCH_FAILED', `未查询到 modellogiccode=${modelLogicCode} 对应的业务逻辑`);
|
|
156
|
+
}
|
|
157
|
+
if (!logic.operations || logic.operations.length === 0) {
|
|
158
|
+
return abort('NO_OPERATIONS', '该业务逻辑不含 operations(即没有 flycode 脚本),请改用 save_model_logic 保存');
|
|
159
|
+
}
|
|
160
|
+
// 2. 取出各 operation 的脚本原文
|
|
161
|
+
const scripts = logic.operations.map((op) => op.templateparams?.flycode ?? '');
|
|
162
|
+
const lengthBefore = scripts.reduce((n, s) => n + s.length, 0);
|
|
163
|
+
// 3. 在内存副本上顺序预演全部 op(此时零写入)
|
|
164
|
+
const applied = applyOps(scripts, ops, { contextLines });
|
|
165
|
+
const diff = joinHunks(applied.results);
|
|
166
|
+
const lengthAfter = applied.scripts.reduce((n, s) => n + s.length, 0);
|
|
167
|
+
if (!applied.ok) {
|
|
168
|
+
const failed = applied.results.filter((r) => r.status === 'FAILED');
|
|
169
|
+
const idxText = failed.map((r) => r.index).join('、');
|
|
170
|
+
return {
|
|
171
|
+
ok: false,
|
|
172
|
+
applied: false,
|
|
173
|
+
verified: null,
|
|
174
|
+
errorCode: 'OPS_FAILED',
|
|
175
|
+
message: `预演失败:${failed.length} 个 op 未通过(ops[${idxText}])。本批次未产生任何写入,请根据 ops[].message / suggestions 修正后重试`,
|
|
176
|
+
lengthBefore,
|
|
177
|
+
lengthAfter,
|
|
178
|
+
diff,
|
|
179
|
+
ops: applied.results
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
if (dryRun) {
|
|
183
|
+
return {
|
|
184
|
+
ok: true,
|
|
185
|
+
applied: false,
|
|
186
|
+
verified: null,
|
|
187
|
+
errorCode: 'DRY_RUN',
|
|
188
|
+
message: `预演成功(dryRun=true),${ops.length} 个 op 全部命中,未落库`,
|
|
189
|
+
lengthBefore,
|
|
190
|
+
lengthAfter,
|
|
191
|
+
diff,
|
|
192
|
+
ops: applied.results
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
// 4. 写回:仅覆盖 flycode,templateparams 内的 sourcemap / tempcompiledflycode 等
|
|
196
|
+
// 字段随展开原样保留(服务端如何在就如何保留,本方法不擅自改动)
|
|
197
|
+
for (let i = 0; i < applied.scripts.length; i++) {
|
|
198
|
+
if (applied.scripts[i] !== scripts[i]) {
|
|
199
|
+
const tpl = logic.operations[i].templateparams;
|
|
200
|
+
logic.operations[i].templateparams = { ...(tpl ?? {}), flycode: applied.scripts[i] };
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// 5. 唯一一次落库
|
|
204
|
+
const saved = await commitAndSave(logic, commitMessage);
|
|
205
|
+
if (!saved.ok) {
|
|
206
|
+
return {
|
|
207
|
+
ok: false,
|
|
208
|
+
applied: false,
|
|
209
|
+
verified: null,
|
|
210
|
+
errorCode: 'SAVE_FAILED',
|
|
211
|
+
message: saved.text,
|
|
212
|
+
lengthBefore,
|
|
213
|
+
lengthAfter,
|
|
214
|
+
diff,
|
|
215
|
+
ops: applied.results
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
// 6. 回读校验:确认所有改动都真实落库(用于发现并发覆盖等异常)
|
|
219
|
+
let verified = null;
|
|
220
|
+
let message = saved.text;
|
|
221
|
+
if (verify) {
|
|
222
|
+
try {
|
|
223
|
+
const res = await getModelLogic({ modellogiccode: modelLogicCode });
|
|
224
|
+
const after = res.resp_data;
|
|
225
|
+
const afterScripts = (after?.operations ?? []).map((op) => op.templateparams?.flycode ?? '');
|
|
226
|
+
const problems = [];
|
|
227
|
+
applied.results.forEach((r, i) => {
|
|
228
|
+
const op = ops[i];
|
|
229
|
+
const text = afterScripts[r.operationIndex] ?? '';
|
|
230
|
+
// 新增内容应当存在(删除类改动 newString 为空串,跳过此断言)
|
|
231
|
+
if (op.newString.length > 0 && !text.includes(op.newString)) {
|
|
232
|
+
problems.push(`ops[${i}] 的新内容未出现在保存后的脚本中`);
|
|
233
|
+
}
|
|
234
|
+
// 原文应当消失(若新文本本身包含原文,如包裹式修改,则跳过此断言)
|
|
235
|
+
if (!op.newString.includes(op.oldString) && text.includes(op.oldString)) {
|
|
236
|
+
problems.push(`ops[${i}] 的 oldString 仍然存在于保存后的脚本中`);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
verified = problems.length === 0;
|
|
240
|
+
if (problems.length > 0) {
|
|
241
|
+
message = `${saved.text} | 回读校验未通过:${problems.join(';')}`;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
catch (e) {
|
|
245
|
+
verified = false;
|
|
246
|
+
message = `${saved.text} | 回读校验失败:${extractError(e)}`;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return {
|
|
250
|
+
ok: verified === null ? true : verified,
|
|
251
|
+
applied: true,
|
|
252
|
+
verified,
|
|
253
|
+
errorCode: verified === false ? 'VERIFY_FAILED' : 'OK',
|
|
254
|
+
message,
|
|
255
|
+
lengthBefore,
|
|
256
|
+
lengthAfter,
|
|
257
|
+
diff,
|
|
258
|
+
ops: applied.results
|
|
259
|
+
};
|
|
260
|
+
}
|
|
69
261
|
//# sourceMappingURL=logic.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logic.js","sourceRoot":"","sources":["../../src/service/logic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,aAAa,EAAE,cAAc,IAAI,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAC5H,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"logic.js","sourceRoot":"","sources":["../../src/service/logic.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { extractError } from '../../utils/error.js';
|
|
3
|
-
import { saveModelLogic, simpleSaveFlyCodeModelLogic } from '../../service/logic.js';
|
|
3
|
+
import { saveModelLogic, simpleSaveFlyCodeModelLogic, replaceFlyCodeSegments } from '../../service/logic.js';
|
|
4
4
|
import { logicResultSchema, logicParametersSchema } from './schemas.js';
|
|
5
5
|
/**
|
|
6
6
|
* 提交信息结构(CommitMessage)。
|
|
@@ -145,6 +145,152 @@ export const writeTools = [
|
|
|
145
145
|
};
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: 'str_replace_flycode',
|
|
151
|
+
config: {
|
|
152
|
+
title: '批量局部替换 flycode 脚本',
|
|
153
|
+
description: `以 str_replace_editor 模式局部修改业务逻辑的 flycode 脚本:只需传入要改动的新旧代码片段(oldString / newString),不必回传整份脚本,由服务端拉取完整对象后完成定位与替换,大幅节省上下文。
|
|
154
|
+
|
|
155
|
+
【何时用本工具 / 何时用别的】
|
|
156
|
+
- 改 1~N 处局部片段(最常用)→ 本工具,一次调用可批量提交多个 ops
|
|
157
|
+
- 整份脚本重写、大范围重构 → simple_save_flycode_model_logic
|
|
158
|
+
- 非 flycode 领域(导出等)或要改 input / output 结构 → save_model_logic
|
|
159
|
+
|
|
160
|
+
【事务性】ops 具备事务性:全部 op 预演成功才会落库,任一 op 失败则整批中止、不产生任何写入(零写入回滚)。实现上整批只发起一次保存请求,不存在写一半的中间态。
|
|
161
|
+
|
|
162
|
+
【执行顺序】ops 按数组顺序依次执行,ops[i+1] 在 ops[i] 的结果上匹配,因此允许「先插入一段代码,再改这段里的某行」这类依赖;反之若 ops[i+1] 的原文已被 ops[i] 删除,则报 NOT_FOUND 并整批中止。
|
|
163
|
+
|
|
164
|
+
【oldString 书写要求(决定成败)】
|
|
165
|
+
- 必须非空,且在目标脚本中唯一命中(否则报 NOT_UNIQUE)
|
|
166
|
+
- 推荐 3~10 行,务必包含一处能区分于其他位置的上下文;太短容易多命中
|
|
167
|
+
- 直接从查询到的脚本原文里复制,不要凭记忆重写;缩进、空行、换行都要一致
|
|
168
|
+
- 匹配默认容忍换行符差异(CRLF / LF)与行尾空白差异;需要字节严格相等时把 matchMode 设为 exact
|
|
169
|
+
- 命中多处的相同片段:用 occurrence 指定改第几处,或 replaceAll=true 全部替换
|
|
170
|
+
|
|
171
|
+
【失败后的自纠】返回体中 ops[].message 说明原因;NOT_FOUND 时 ops[].suggestions 会给出最相似的候选(含行号与相似度),据此修正 oldString 后重试即可。改动较大或不确定是否唯一时,建议先 dryRun=true 预览 diff 再正式提交。`,
|
|
172
|
+
inputSchema: {
|
|
173
|
+
modelLogicCode: z.string().describe('要修改的业务逻辑的编码(即 get_model_logic 返回的 modellogiccode)'),
|
|
174
|
+
ops: z.array(z.object({
|
|
175
|
+
oldString: z.string().describe('待替换的原文片段,必须非空且在目标脚本中唯一命中;请从查询到的脚本原文原样复制(含缩进与换行)'),
|
|
176
|
+
newString: z.string().describe('替换后的新文本;传空字符串表示删除 oldString 这段内容'),
|
|
177
|
+
operationIndex: z.number().int().nonnegative().optional().describe('作用于第几个 operation 的 flycode 脚本,默认 0。多数业务逻辑只有一个 operation,无需传'),
|
|
178
|
+
replaceAll: z.boolean().optional().describe('是否替换全部匹配,默认 false。与 occurrence 互斥,仅在你确认要改掉所有同名片段时置 true'),
|
|
179
|
+
occurrence: z.number().int().positive().optional().describe('只替换第 N 个匹配(1-based),用于「多处相同片段只改其中一处」;与 replaceAll 互斥'),
|
|
180
|
+
matchMode: z.enum(['exact', 'normalized']).optional().describe('匹配严格度,默认 normalized(容忍 CRLF/LF 与行尾空白差异);exact 为字节严格相等'),
|
|
181
|
+
label: z.string().optional().describe('可选标识,仅用于在返回报告中辨认该 op,不影响执行')
|
|
182
|
+
})).min(1).describe('替换操作数组,至少一个元素;按数组顺序依次执行,全部成功才落库'),
|
|
183
|
+
commitMessage: commitMessageSchema.describe('提交信息,整批 ops 共用一个;类型与名称需一一对应,msgbody 在非 saverecord 时必填'),
|
|
184
|
+
dryRun: z.boolean().optional().describe('只预演并输出 diff、不落库,默认 false。改动较大或不确定 oldString 是否唯一时建议先置 true'),
|
|
185
|
+
contextLines: z.number().int().min(0).max(10).optional().describe('diff 中每个改动点上下保留的上下文行数,默认 3'),
|
|
186
|
+
verify: z.boolean().optional().describe('保存后是否回读校验所有改动已生效,默认 true')
|
|
187
|
+
},
|
|
188
|
+
outputSchema: {
|
|
189
|
+
ok: z.boolean().describe('整体是否成功(dryRun 成功也为 true,但 applied=false)'),
|
|
190
|
+
applied: z.boolean().describe('是否已落库;dryRun 或任一 op 预演失败时为 false'),
|
|
191
|
+
verified: z.boolean().nullable().describe('保存后回读校验结果:true 全部生效、false 存在异常、null 未落库或未开启校验'),
|
|
192
|
+
errorCode: z.string().describe('错误码:OK / DRY_RUN / EMPTY_OPS / FETCH_FAILED / NO_OPERATIONS / OPS_FAILED / SAVE_FAILED / VERIFY_FAILED'),
|
|
193
|
+
message: z.string().describe('结果说明;失败时给出可直接执行的处理建议'),
|
|
194
|
+
lengthBefore: z.coerce.number().describe('替换前脚本总字符数'),
|
|
195
|
+
lengthAfter: z.coerce.number().describe('替换后脚本总字符数'),
|
|
196
|
+
diff: z.string().describe('全部 op 的 diff 片段(unified hunk 形态),超长会截断;此处只回改动片段,不回整份脚本'),
|
|
197
|
+
ops: z.array(z.object({
|
|
198
|
+
index: z.coerce.number().describe('在 ops 数组中的下标'),
|
|
199
|
+
label: z.string().nullable().describe('调用方传入的标识'),
|
|
200
|
+
status: z.string().describe('该 op 的执行状态:OK / FAILED'),
|
|
201
|
+
errorCode: z.string().describe('该 op 的错误码:OK / EMPTY_OLD_STRING / NOT_FOUND / NOT_UNIQUE / NO_TARGET / INVALID_PARAMS / OCCURRENCE_OUT_OF_RANGE'),
|
|
202
|
+
message: z.string().nullable().describe('失败原因说明,成功时为 null'),
|
|
203
|
+
operationIndex: z.coerce.number().describe('实际作用的 operation 下标'),
|
|
204
|
+
matchCount: z.coerce.number().describe('oldString 的匹配总数'),
|
|
205
|
+
replacedCount: z.coerce.number().describe('实际替换的处数'),
|
|
206
|
+
range: z.object({
|
|
207
|
+
startOffset: z.coerce.number().describe('起始字符偏移'),
|
|
208
|
+
endOffset: z.coerce.number().describe('结束字符偏移(不含)'),
|
|
209
|
+
startLine: z.coerce.number().describe('起始行号,1-based'),
|
|
210
|
+
endLine: z.coerce.number().describe('结束行号,1-based')
|
|
211
|
+
}).nullable().describe('首个替换点的位置,未执行时为 null'),
|
|
212
|
+
suggestions: z.array(z.object({
|
|
213
|
+
startLine: z.coerce.number().describe('候选片段起始行号'),
|
|
214
|
+
score: z.coerce.number().describe('相似度,0~1'),
|
|
215
|
+
preview: z.string().describe('候选片段预览')
|
|
216
|
+
})).nullable().describe('NOT_FOUND 时的相似候选,供修正 oldString 参考'),
|
|
217
|
+
dependentOnFailedOp: z.boolean().describe('前序 op 已失败时为 true,表示本 op 的结果可能受其影响'),
|
|
218
|
+
hunk: z.string().nullable().describe('该 op 产生的 diff 片段')
|
|
219
|
+
})).describe('每个 op 的执行结果,与入参 ops 一一对应')
|
|
220
|
+
},
|
|
221
|
+
annotations: {
|
|
222
|
+
readOnlyHint: false, // 此操作会修改数据
|
|
223
|
+
destructiveHint: false, // 局部替换为非破坏性写入,且有事务性保护
|
|
224
|
+
idempotentHint: false // 成功后重复调用会因 oldString 已不存在而失败(fail-closed)
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
handler: async (args) => {
|
|
228
|
+
const { modelLogicCode, ops, commitMessage, dryRun = false, contextLines = 3, verify = true } = args;
|
|
229
|
+
// 兜底 msgbody:service 仅在 committype==='saverecord' 时自动填当前时间,
|
|
230
|
+
// 其他类型若未传则给空字符串,避免把 undefined 透传给服务端。
|
|
231
|
+
const commit = {
|
|
232
|
+
committype: commitMessage.committype,
|
|
233
|
+
committypetext: commitMessage.committypetext,
|
|
234
|
+
msgbody: commitMessage.msgbody ?? ''
|
|
235
|
+
};
|
|
236
|
+
try {
|
|
237
|
+
const result = await replaceFlyCodeSegments(modelLogicCode, ops, commit, { dryRun, contextLines, verify });
|
|
238
|
+
// content 保持精简:只回状态、每个 op 的结论与 diff,不回整份脚本,
|
|
239
|
+
// 避免把大文本塞两份(content 与 structuredContent 各一份)。
|
|
240
|
+
return {
|
|
241
|
+
isError: !result.ok,
|
|
242
|
+
content: [{
|
|
243
|
+
type: 'text',
|
|
244
|
+
text: JSON.stringify({
|
|
245
|
+
ok: result.ok,
|
|
246
|
+
applied: result.applied,
|
|
247
|
+
verified: result.verified,
|
|
248
|
+
errorCode: result.errorCode,
|
|
249
|
+
message: result.message,
|
|
250
|
+
ops: result.ops.map((o) => ({
|
|
251
|
+
index: o.index,
|
|
252
|
+
status: o.status,
|
|
253
|
+
errorCode: o.errorCode,
|
|
254
|
+
message: o.message,
|
|
255
|
+
operationIndex: o.operationIndex,
|
|
256
|
+
matchCount: o.matchCount,
|
|
257
|
+
replacedCount: o.replacedCount,
|
|
258
|
+
range: o.range,
|
|
259
|
+
suggestions: o.suggestions,
|
|
260
|
+
dependentOnFailedOp: o.dependentOnFailedOp
|
|
261
|
+
})),
|
|
262
|
+
diff: result.diff
|
|
263
|
+
})
|
|
264
|
+
}],
|
|
265
|
+
// outputSchema 已在工具上声明,SDK 1.30 要求调用结果必须携带
|
|
266
|
+
// structuredContent 与之匹配,否则会抛 -32602。
|
|
267
|
+
structuredContent: result
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
catch (e) {
|
|
271
|
+
// replaceFlyCodeSegments 内部已捕获业务/网络错误,走到这里通常是入参非法等意外;
|
|
272
|
+
// 把原始错误体原样返回,并保证 structuredContent 与 outputSchema 形状一致。
|
|
273
|
+
const text = extractError(e);
|
|
274
|
+
return {
|
|
275
|
+
isError: true,
|
|
276
|
+
content: [{
|
|
277
|
+
type: 'text',
|
|
278
|
+
text
|
|
279
|
+
}],
|
|
280
|
+
structuredContent: {
|
|
281
|
+
ok: false,
|
|
282
|
+
applied: false,
|
|
283
|
+
verified: null,
|
|
284
|
+
errorCode: 'SAVE_FAILED',
|
|
285
|
+
message: text,
|
|
286
|
+
lengthBefore: 0,
|
|
287
|
+
lengthAfter: 0,
|
|
288
|
+
diff: '',
|
|
289
|
+
ops: []
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
}
|
|
148
294
|
}
|
|
149
295
|
];
|
|
150
296
|
//# sourceMappingURL=write.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../../src/tools/logic/write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,2BAA2B,EAAsB,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../../src/tools/logic/write.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/run/read.js
CHANGED
|
@@ -20,7 +20,7 @@ export const readTools = [
|
|
|
20
20
|
name: 'run_sql',
|
|
21
21
|
config: {
|
|
22
22
|
title: '执行 SQL 查询',
|
|
23
|
-
description: '在业务库(数据库为 PostgreSQL)中执行一条 SELECT 查询 SQL(接口仅支持 SELECT,一次只能一条 SQL),返回查询结果数据 data 与结果总数 influenceCount。适用于直接探查业务表数据、核对字段值、验证同步结果等只读场景。',
|
|
23
|
+
description: '在业务库(数据库为 PostgreSQL)中执行一条 SELECT 查询 SQL(接口仅支持 SELECT,一次只能一条 SQL,只能查业务表的数据,需要查表有哪些字段请使用 get_entity ),返回查询结果数据 data 与结果总数 influenceCount。适用于直接探查业务表数据、核对字段值、验证同步结果等只读场景。',
|
|
24
24
|
inputSchema: {
|
|
25
25
|
sql: z.string().describe('要执行的 SQL 查询语句,只支持 SELECT 查询,一次只能一条 SQL')
|
|
26
26
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../../src/tools/run/read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AAGnD;;;;;;;;GAQG;AACH,MAAM,iBAAiB,GAAG;IACxB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;IACxF,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;CACrD,CAAA;AAEvB,gCAAgC;AAChC,MAAM,CAAC,MAAM,SAAS,GAAc;IAClC;QACE,IAAI,EAAE,SAAS;QACf,MAAM,EAAE;YACN,KAAK,EAAE,WAAW;YAClB,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../../src/tools/run/read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AAGnD;;;;;;;;GAQG;AACH,MAAM,iBAAiB,GAAG;IACxB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;IACxF,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;CACrD,CAAA;AAEvB,gCAAgC;AAChC,MAAM,CAAC,MAAM,SAAS,GAAc;IAClC;QACE,IAAI,EAAE,SAAS;QACf,MAAM,EAAE;YACN,KAAK,EAAE,WAAW;YAClB,WAAW,EAAE,yKAAyK;YACtL,WAAW,EAAE;gBACX,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;aACnE;YACD,6BAA6B;YAC7B,YAAY,EAAE,CAAC,CAAC,WAAW,CAAC,iBAAiB,CAA2B;YACxE,WAAW,EAAE;gBACX,YAAY,EAAE,IAAI,EAAM,0BAA0B;gBAClD,eAAe,EAAE,KAAK,EAAE,YAAY;gBACpC,cAAc,EAAE,IAAI,CAAI,sBAAsB;aAC/C;SACF;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;YACpB,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAA;gBACjC,OAAO;oBACL,OAAO,EAAE,CAAC;4BACR,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC;yBACpC,CAAC;oBACF,2CAA2C;oBAC3C,4CAA4C;oBAC5C,kCAAkC;oBAClC,iBAAiB,EAAE,GAAG,CAAC,SAA+C;iBACvE,CAAA;YACH,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,sCAAsC;gBACtC,4EAA4E;gBAC5E,4BAA4B;gBAC5B,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,CAAC;4BACR,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;yBACtB,CAAC;iBACH,CAAA;YACH,CAAC;QACH,CAAC;KACF;CACF,CAAA"}
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* str_replace_editor 模式的纯文本替换工具集。
|
|
3
|
+
*
|
|
4
|
+
* 设计目标:让 MCP 调用方只传「改动片段」(oldString / newString),
|
|
5
|
+
* 由本模块在服务端拉取到的完整脚本文本上完成定位与替换,
|
|
6
|
+
* 从而避免整份脚本在上下文中往返。
|
|
7
|
+
*
|
|
8
|
+
* 本文件全部为纯函数(无网络、无 MCP 依赖),便于单测与复用。
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* 按模式归一化文本,并给出「归一化文本下标 → 原文本下标」的映射。
|
|
12
|
+
*
|
|
13
|
+
* normalized 模式做两件事:
|
|
14
|
+
* 1. CRLF / CR 统一成 LF(CRLF 整体只映射到一个下标,避免重复);
|
|
15
|
+
* 2. 丢弃紧邻换行符(或文本末尾)之前的空格与制表符,即行尾空白。
|
|
16
|
+
*
|
|
17
|
+
* exact 模式下映射为恒等映射,文本原样返回。
|
|
18
|
+
*/
|
|
19
|
+
function buildNormalized(src, mode) {
|
|
20
|
+
const text = [];
|
|
21
|
+
const map = [];
|
|
22
|
+
if (mode === 'exact') {
|
|
23
|
+
for (let i = 0; i < src.length; i++) {
|
|
24
|
+
text.push(src[i]);
|
|
25
|
+
map.push(i);
|
|
26
|
+
}
|
|
27
|
+
return { text: text.join(''), map };
|
|
28
|
+
}
|
|
29
|
+
for (let i = 0; i < src.length; i++) {
|
|
30
|
+
const c = src[i];
|
|
31
|
+
// 换行符归一:\r\n 与 \r 都记为一个 \n,映射指向 \r 所在下标
|
|
32
|
+
if (c === '\r') {
|
|
33
|
+
text.push('\n');
|
|
34
|
+
map.push(i);
|
|
35
|
+
if (src[i + 1] === '\n')
|
|
36
|
+
i++;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
// 行尾空白:整段吞掉(不进归一化文本),仅当其后是换行或文本末尾
|
|
40
|
+
if (c === ' ' || c === '\t') {
|
|
41
|
+
let j = i;
|
|
42
|
+
while (j < src.length && (src[j] === ' ' || src[j] === '\t'))
|
|
43
|
+
j++;
|
|
44
|
+
if (j >= src.length || src[j] === '\n' || src[j] === '\r') {
|
|
45
|
+
i = j - 1;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
text.push(c);
|
|
49
|
+
map.push(i);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
text.push(c);
|
|
53
|
+
map.push(i);
|
|
54
|
+
}
|
|
55
|
+
return { text: text.join(''), map };
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 把 \r\n / \r 统一成 \n(仅用于切行、预览等只读场景,不做偏移映射)。
|
|
59
|
+
*/
|
|
60
|
+
function toLf(src) {
|
|
61
|
+
return src.replace(/\r\n?/g, '\n');
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 统计 [0, offset) 区间内的换行数,得到 offset 处的行号(1-based)。
|
|
65
|
+
*/
|
|
66
|
+
function lineAt(src, offset) {
|
|
67
|
+
let line = 1;
|
|
68
|
+
const end = Math.min(offset, src.length);
|
|
69
|
+
for (let i = 0; i < end; i++) {
|
|
70
|
+
if (src[i] === '\n')
|
|
71
|
+
line++;
|
|
72
|
+
}
|
|
73
|
+
return line;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 在 source 中查找 oldStr 的全部非重叠匹配。
|
|
77
|
+
*
|
|
78
|
+
* 偏移量会映射回原文本坐标系,因此调用方可以直接用返回的 range 对原文做切片替换。
|
|
79
|
+
*/
|
|
80
|
+
export function findRanges(source, oldStr, mode = 'normalized') {
|
|
81
|
+
if (oldStr.length === 0)
|
|
82
|
+
return [];
|
|
83
|
+
const nSrc = buildNormalized(source, mode);
|
|
84
|
+
const nOld = buildNormalized(oldStr, mode);
|
|
85
|
+
if (nOld.text.length === 0)
|
|
86
|
+
return [];
|
|
87
|
+
const ranges = [];
|
|
88
|
+
let from = 0;
|
|
89
|
+
for (;;) {
|
|
90
|
+
const idx = nSrc.text.indexOf(nOld.text, from);
|
|
91
|
+
if (idx === -1)
|
|
92
|
+
break;
|
|
93
|
+
const startOffset = nSrc.map[idx];
|
|
94
|
+
const endOffset = nSrc.map[idx + nOld.text.length - 1] + 1;
|
|
95
|
+
ranges.push({
|
|
96
|
+
startOffset,
|
|
97
|
+
endOffset,
|
|
98
|
+
startLine: lineAt(source, startOffset),
|
|
99
|
+
endLine: lineAt(source, Math.max(endOffset - 1, 0))
|
|
100
|
+
});
|
|
101
|
+
// 步进 oldStr 长度,避免 "aa" 在 "aaa" 中产生重叠匹配
|
|
102
|
+
from = idx + nOld.text.length;
|
|
103
|
+
}
|
|
104
|
+
return ranges;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 生成字符串的大二元组(bigram)计数表,用于 Dice 相似度计算。
|
|
108
|
+
*/
|
|
109
|
+
function bigrams(text) {
|
|
110
|
+
const m = new Map();
|
|
111
|
+
if (text.length < 2) {
|
|
112
|
+
if (text.length === 1)
|
|
113
|
+
m.set(text, 1);
|
|
114
|
+
return m;
|
|
115
|
+
}
|
|
116
|
+
for (let i = 0; i < text.length - 1; i++) {
|
|
117
|
+
const g = text.slice(i, i + 2);
|
|
118
|
+
m.set(g, (m.get(g) ?? 0) + 1);
|
|
119
|
+
}
|
|
120
|
+
return m;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Dice 系数:2 * 交集 / (|A| + |B|),取值 0~1。
|
|
124
|
+
*/
|
|
125
|
+
function diceCoefficient(a, b) {
|
|
126
|
+
if (a.size === 0 && b.size === 0)
|
|
127
|
+
return 1;
|
|
128
|
+
if (a.size === 0 || b.size === 0)
|
|
129
|
+
return 0;
|
|
130
|
+
let intersection = 0;
|
|
131
|
+
const [small, large] = a.size <= b.size ? [a, b] : [b, a];
|
|
132
|
+
for (const [g, count] of small) {
|
|
133
|
+
const other = large.get(g);
|
|
134
|
+
if (other)
|
|
135
|
+
intersection += Math.min(count, other);
|
|
136
|
+
}
|
|
137
|
+
let total = 0;
|
|
138
|
+
for (const count of a.values())
|
|
139
|
+
total += count;
|
|
140
|
+
for (const count of b.values())
|
|
141
|
+
total += count;
|
|
142
|
+
return total === 0 ? 0 : (2 * intersection) / total;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* 「0 命中」时给出最相似的若干候选片段,帮助模型一次修正。
|
|
146
|
+
*
|
|
147
|
+
* 实现上以行为窗口滑动,用 bigram Dice 系数打分;
|
|
148
|
+
* 比较时按行 trim 后比较,以容忍 LLM 复述时的缩进差异;
|
|
149
|
+
* 窗口大小取 oldString 行数 ±1,容忍行数差异。
|
|
150
|
+
*/
|
|
151
|
+
export function suggestCandidates(source, oldStr, topN = 3) {
|
|
152
|
+
const srcLines = toLf(source).split('\n');
|
|
153
|
+
const oldLines = toLf(oldStr).split('\n');
|
|
154
|
+
if (srcLines.length === 0 || oldLines.length === 0)
|
|
155
|
+
return [];
|
|
156
|
+
const oldText = oldLines.map((l) => l.trim()).join('\n');
|
|
157
|
+
const oldBigrams = bigrams(oldText);
|
|
158
|
+
const trimmedLines = srcLines.map((l) => l.trim());
|
|
159
|
+
const bestByStart = new Map();
|
|
160
|
+
const sizes = new Set([oldLines.length - 1, oldLines.length, oldLines.length + 1]);
|
|
161
|
+
for (const size of sizes) {
|
|
162
|
+
if (size < 1)
|
|
163
|
+
continue;
|
|
164
|
+
for (let i = 0; i + size <= srcLines.length; i++) {
|
|
165
|
+
const window = trimmedLines.slice(i, i + size).join('\n');
|
|
166
|
+
const score = diceCoefficient(bigrams(window), oldBigrams);
|
|
167
|
+
if (score <= 0.3)
|
|
168
|
+
continue;
|
|
169
|
+
const prev = bestByStart.get(i);
|
|
170
|
+
if (!prev || score > prev.score) {
|
|
171
|
+
bestByStart.set(i, { score, preview: srcLines.slice(i, i + size).join('\n').slice(0, 120) });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return Array.from(bestByStart.entries())
|
|
176
|
+
.map(([i, v]) => ({
|
|
177
|
+
startLine: i + 1,
|
|
178
|
+
score: Math.round(v.score * 100) / 100,
|
|
179
|
+
preview: v.preview
|
|
180
|
+
}))
|
|
181
|
+
.sort((a, b) => b.score - a.score)
|
|
182
|
+
.slice(0, topN);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* 探测文本的主导换行符。
|
|
186
|
+
*
|
|
187
|
+
* 背景:脚本在库里可能是 CRLF,而模型给的 newString 通常是 LF。
|
|
188
|
+
* 若直接拼接,替换区域内部会与文件其余部分风格不一致(混用换行符)。
|
|
189
|
+
* 故以多数的那一方为准,把 newString 的换行符统一成源文本的主导换行符。
|
|
190
|
+
*/
|
|
191
|
+
function detectEol(src) {
|
|
192
|
+
const crlf = (src.match(/\r\n/g) ?? []).length;
|
|
193
|
+
const lf = (src.match(/\n/g) ?? []).length - crlf;
|
|
194
|
+
return crlf > lf ? '\r\n' : '\n';
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* 把 newString 的换行符统一成源文本的主导换行符。
|
|
198
|
+
*/
|
|
199
|
+
function adaptEol(newString, src) {
|
|
200
|
+
const eol = detectEol(src);
|
|
201
|
+
return newString.replace(/\r\n?|\n/g, eol);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* 单个 hunk 的内容行数上限,避免超大替换把上下文又吃回去。
|
|
205
|
+
*/
|
|
206
|
+
const MAX_HUNK_LINES = 40;
|
|
207
|
+
/**
|
|
208
|
+
* 渲染 unified diff 形态的片段。
|
|
209
|
+
*
|
|
210
|
+
* 由于已精确知道匹配区间,无需 diff 算法:直接取匹配区前后各 contextLines 行作上下文,
|
|
211
|
+
* 中间以 -/+ 输出被替换与新增内容。
|
|
212
|
+
*/
|
|
213
|
+
export function renderHunk(before, targets, newString, contextLines = 3) {
|
|
214
|
+
const lines = toLf(before).split('\n');
|
|
215
|
+
const parts = [];
|
|
216
|
+
const sorted = targets.slice().sort((a, b) => a.startOffset - b.startOffset);
|
|
217
|
+
for (const t of sorted) {
|
|
218
|
+
const ctxStart = Math.max(1, t.startLine - contextLines);
|
|
219
|
+
const ctxEnd = Math.min(lines.length, t.endLine + contextLines);
|
|
220
|
+
const oldLines = before.slice(t.startOffset, t.endOffset).split('\n').map((l) => l.replace(/\r$/, ''));
|
|
221
|
+
const newLines = newString.split('\n');
|
|
222
|
+
const oldCount = oldLines.length;
|
|
223
|
+
const newCount = newLines.length;
|
|
224
|
+
const header = ['@@', `-${t.startLine},${oldCount}`, `+${t.startLine},${newCount}`, '@@'].join(' ');
|
|
225
|
+
const body = [header];
|
|
226
|
+
for (let i = ctxStart; i < t.startLine; i++)
|
|
227
|
+
body.push(` ${lines[i - 1]}`);
|
|
228
|
+
for (const l of oldLines.slice(0, MAX_HUNK_LINES))
|
|
229
|
+
body.push(`-${l}`);
|
|
230
|
+
if (oldCount > MAX_HUNK_LINES)
|
|
231
|
+
body.push(`... 省略 ${oldCount - MAX_HUNK_LINES} 行`);
|
|
232
|
+
for (const l of newLines.slice(0, MAX_HUNK_LINES))
|
|
233
|
+
body.push(`+${l}`);
|
|
234
|
+
if (newCount > MAX_HUNK_LINES)
|
|
235
|
+
body.push(`... 省略 ${newCount - MAX_HUNK_LINES} 行`);
|
|
236
|
+
for (let i = t.endLine + 1; i <= ctxEnd; i++)
|
|
237
|
+
body.push(` ${lines[i - 1]}`);
|
|
238
|
+
parts.push(body.join('\n'));
|
|
239
|
+
}
|
|
240
|
+
return parts.join('\n');
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* 在脚本文本数组上按顺序批量应用替换操作。
|
|
244
|
+
*
|
|
245
|
+
* 语义要点:
|
|
246
|
+
* 1. 按 ops 数组顺序依次执行,op[i+1] 在 op[i] 的结果上匹配,
|
|
247
|
+
* 因此允许「先插入一段、再改这段里的某行」这类依赖;
|
|
248
|
+
* 2. 失败不早停:失败 op 记 FAILED 并视作 no-op,继续校验剩余 op,
|
|
249
|
+
* 以便一次调用回报全部问题;受影响的后续 op 会标记 dependentOnFailedOp;
|
|
250
|
+
* 3. 调用方须以 ok 决定是否落库——ok 为 false 时本批次不应产生任何写入。
|
|
251
|
+
*
|
|
252
|
+
* @param scripts 脚本文本数组(通常对应 logic.operations[].templateparams.flycode)
|
|
253
|
+
* @param ops 替换操作数组,至少一个元素
|
|
254
|
+
* @param opts contextLines:diff 上下文行数;topN:候选建议条数
|
|
255
|
+
*/
|
|
256
|
+
export function applyOps(scripts, ops, opts = {}) {
|
|
257
|
+
const contextLines = opts.contextLines ?? 3;
|
|
258
|
+
const topN = opts.topN ?? 3;
|
|
259
|
+
const work = scripts.slice();
|
|
260
|
+
const results = [];
|
|
261
|
+
let failedBefore = false;
|
|
262
|
+
for (let i = 0; i < ops.length; i++) {
|
|
263
|
+
const op = ops[i];
|
|
264
|
+
const oi = op.operationIndex ?? 0;
|
|
265
|
+
const base = () => ({
|
|
266
|
+
index: i,
|
|
267
|
+
label: op.label ?? null,
|
|
268
|
+
status: 'FAILED',
|
|
269
|
+
errorCode: 'OK',
|
|
270
|
+
message: null,
|
|
271
|
+
operationIndex: oi,
|
|
272
|
+
matchCount: 0,
|
|
273
|
+
replacedCount: 0,
|
|
274
|
+
range: null,
|
|
275
|
+
suggestions: null,
|
|
276
|
+
dependentOnFailedOp: failedBefore,
|
|
277
|
+
hunk: null
|
|
278
|
+
});
|
|
279
|
+
const fail = (errorCode, message, extra = {}) => {
|
|
280
|
+
results.push({ ...base(), status: 'FAILED', errorCode, message, ...extra });
|
|
281
|
+
failedBefore = true;
|
|
282
|
+
};
|
|
283
|
+
// 校验:目标 operation 必须存在
|
|
284
|
+
if (!Number.isInteger(oi) || oi < 0 || oi >= work.length) {
|
|
285
|
+
fail('NO_TARGET', `operationIndex=${oi} 不存在,当前共有 ${work.length} 个 operation(可用下标 0~${Math.max(work.length - 1, 0)})`);
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
// 校验:oldString 必须非空(空串会让「插入位置」变得不可判定)
|
|
289
|
+
if (typeof op.oldString !== 'string' || op.oldString.length === 0) {
|
|
290
|
+
fail('EMPTY_OLD_STRING', 'oldString 不能为空字符串;如需整份重写请改用 simple_save_flycode_model_logic');
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
// 校验:replaceAll 与 occurrence 互斥
|
|
294
|
+
if (op.replaceAll === true && op.occurrence != null) {
|
|
295
|
+
fail('INVALID_PARAMS', 'replaceAll 与 occurrence 互斥,只能二选一');
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
const mode = op.matchMode ?? 'normalized';
|
|
299
|
+
const src = work[oi];
|
|
300
|
+
const ranges = findRanges(src, op.oldString, mode);
|
|
301
|
+
if (ranges.length === 0) {
|
|
302
|
+
fail('NOT_FOUND', `oldString 在 operation[${oi}] 的脚本中未匹配到任何内容(matchMode=${mode})`, {
|
|
303
|
+
suggestions: suggestCandidates(src, op.oldString, topN)
|
|
304
|
+
});
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
let targets;
|
|
308
|
+
if (op.replaceAll === true) {
|
|
309
|
+
targets = ranges;
|
|
310
|
+
}
|
|
311
|
+
else if (op.occurrence != null) {
|
|
312
|
+
if (!Number.isInteger(op.occurrence) || op.occurrence < 1 || op.occurrence > ranges.length) {
|
|
313
|
+
fail('OCCURRENCE_OUT_OF_RANGE', `occurrence=${op.occurrence} 越界,实际匹配数为 ${ranges.length}`, { matchCount: ranges.length });
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
targets = [ranges[op.occurrence - 1]];
|
|
317
|
+
}
|
|
318
|
+
else if (ranges.length > 1) {
|
|
319
|
+
const where = ranges.map((r) => `第 ${r.startLine}~${r.endLine} 行`).join('、');
|
|
320
|
+
fail('NOT_UNIQUE', `oldString 匹配到 ${ranges.length} 处(${where})。请扩大 oldString 的上下文使其唯一,或使用 occurrence 指定第几处,或 replaceAll=true 全部替换`, {
|
|
321
|
+
matchCount: ranges.length
|
|
322
|
+
});
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
targets = ranges;
|
|
327
|
+
}
|
|
328
|
+
// 应用:从后往前替换,避免前面的替换让后面的偏移失效。
|
|
329
|
+
// newString 的换行符统一成源文本的主导换行符,避免替换区域内部出现混用。
|
|
330
|
+
const newText = adaptEol(op.newString, src);
|
|
331
|
+
let out = src;
|
|
332
|
+
for (let k = targets.length - 1; k >= 0; k--) {
|
|
333
|
+
out = out.slice(0, targets[k].startOffset) + newText + out.slice(targets[k].endOffset);
|
|
334
|
+
}
|
|
335
|
+
const hunk = renderHunk(src, targets, newText, contextLines);
|
|
336
|
+
work[oi] = out;
|
|
337
|
+
results.push({
|
|
338
|
+
...base(),
|
|
339
|
+
status: 'OK',
|
|
340
|
+
errorCode: 'OK',
|
|
341
|
+
matchCount: ranges.length,
|
|
342
|
+
replacedCount: targets.length,
|
|
343
|
+
range: targets[0],
|
|
344
|
+
hunk
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
return {
|
|
348
|
+
scripts: work,
|
|
349
|
+
results,
|
|
350
|
+
ok: results.length > 0 && results.every((r) => r.status === 'OK')
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
//# sourceMappingURL=str-replace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"str-replace.js","sourceRoot":"","sources":["../../src/utils/str-replace.ts"],"names":[],"mappings":"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"}
|