kcode-pi 0.1.34 → 0.1.38
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 +10 -10
- package/dist/cli/kcode.js +3 -3
- package/dist/context/project-context.js +4 -5
- package/dist/harness/prompt-policy.d.ts +19 -0
- package/dist/harness/prompt-policy.js +206 -0
- package/dist/harness/types.d.ts +74 -0
- package/dist/harness/types.js +16 -0
- package/dist/product/profile.d.ts +20 -0
- package/dist/product/profile.js +103 -0
- package/docs/CHANGELOG.md +90 -2
- package/docs/COMMAND_REFERENCE.md +27 -12
- package/docs/DEVELOPMENT.md +3 -3
- package/docs/EVIDENCE_AND_GATES.md +15 -8
- package/docs/HARNESS_WORKFLOW.md +32 -12
- package/docs/KCODE_DISTRIBUTION.md +7 -7
- package/docs/PRODUCT_PROFILE.md +9 -9
- package/docs/TROUBLESHOOTING.md +8 -8
- package/docs/USER_GUIDE.md +10 -10
- package/extensions/kingdee-harness.ts +141 -86
- package/extensions/kingdee-header.ts +1 -1
- package/extensions/kingdee-subagents.ts +1 -1
- package/extensions/kingdee-tools.ts +44 -44
- package/package.json +1 -1
- package/src/cli/kcode.ts +3 -3
- package/src/context/project-context.ts +4 -5
- package/src/harness/artifacts.ts +6 -7
- package/src/harness/data-source-policy.ts +346 -0
- package/src/harness/delegation.ts +28 -23
- package/src/harness/gates.ts +16 -1
- package/src/harness/messages.ts +65 -11
- package/src/harness/path-policy.ts +1 -0
- package/src/harness/plan-steps.ts +3 -3
- package/src/harness/prompt-policy.ts +227 -0
- package/src/harness/prompt.ts +12 -16
- package/src/harness/question-memory.ts +220 -0
- package/src/harness/repair.ts +18 -3
- package/src/harness/state.ts +93 -6
- package/src/harness/types.ts +19 -0
- package/src/official/kingdee-skills.ts +4 -4
- package/src/product/profile.ts +2 -2
- package/src/rules/checker.ts +27 -27
- package/src/tools/build-debug.ts +5 -5
- package/src/tools/sdk-signature.ts +4 -4
|
@@ -77,7 +77,7 @@ function sdkLanguageForProfile(profile: ProductProfile, value: string | undefine
|
|
|
77
77
|
|
|
78
78
|
function rejectNonCosmic(profile: ProductProfile): string | undefined {
|
|
79
79
|
if (isCosmicFamily(profile)) return undefined;
|
|
80
|
-
if (profile.product === "unknown") return "
|
|
80
|
+
if (profile.product === "unknown") return "必须提供支持 Cosmic 平台能力的产品:cangqiong、xinghan 或 flagship。";
|
|
81
81
|
return `当前产品 ${profile.product} 使用 ${profile.platform}/${profile.techStack},不适用 Cosmic 官方能力。`;
|
|
82
82
|
}
|
|
83
83
|
|
|
@@ -90,7 +90,7 @@ async function runOrDryRun(
|
|
|
90
90
|
const command = await commandPromise;
|
|
91
91
|
if (dryRun) {
|
|
92
92
|
return {
|
|
93
|
-
content: [{ type: "text" as const, text:
|
|
93
|
+
content: [{ type: "text" as const, text: `输出命令预览;不执行:\n${command.display}` }],
|
|
94
94
|
details: { command: command.display, dryRun: true },
|
|
95
95
|
};
|
|
96
96
|
}
|
|
@@ -119,11 +119,11 @@ function autoAdvanceAfterEvidence(cwd: string): { text: string; details: ReturnT
|
|
|
119
119
|
const kdSearchTool = defineTool({
|
|
120
120
|
name: "kd_search",
|
|
121
121
|
label: "KD 搜索",
|
|
122
|
-
description: "搜索 KCode 随包金蝶知识库,包括 SDK
|
|
122
|
+
description: "搜索 KCode 随包金蝶知识库,包括 SDK、插件生命周期、代码模式和实现约束。",
|
|
123
123
|
parameters: Type.Object({
|
|
124
|
-
query: Type.String({ description: "
|
|
124
|
+
query: Type.String({ description: "搜索关键词、API、类名、表名或生命周期术语。" }),
|
|
125
125
|
product: Type.Optional(Type.String({ description: "金蝶产品:flagship、xinghan、cangqiong 或 enterprise。" })),
|
|
126
|
-
edition: Type.Optional(Type.String({ description: "旧参数,等同于 product
|
|
126
|
+
edition: Type.Optional(Type.String({ description: "旧参数,等同于 product;product 覆盖 edition。" })),
|
|
127
127
|
limit: Type.Optional(Type.Number({ description: "最大结果数,默认 5。" })),
|
|
128
128
|
}),
|
|
129
129
|
|
|
@@ -133,7 +133,7 @@ const kdSearchTool = defineTool({
|
|
|
133
133
|
if (!scopes) {
|
|
134
134
|
const guidance =
|
|
135
135
|
profile.product === "unknown"
|
|
136
|
-
? "
|
|
136
|
+
? "必须提供 product,例如 flagship、enterprise、xinghan 或 cangqiong。"
|
|
137
137
|
: "当前产品画像未配置可搜索知识范围。";
|
|
138
138
|
return {
|
|
139
139
|
content: [
|
|
@@ -141,7 +141,7 @@ const kdSearchTool = defineTool({
|
|
|
141
141
|
type: "text",
|
|
142
142
|
text: [
|
|
143
143
|
`产品画像:${profile.product}/${profile.techStack}/${profile.language}`,
|
|
144
|
-
"KCode
|
|
144
|
+
"KCode 随包知识库搜索必须明确产品画像。",
|
|
145
145
|
guidance,
|
|
146
146
|
].join("\n"),
|
|
147
147
|
},
|
|
@@ -166,7 +166,7 @@ const kdTableTool = defineTool({
|
|
|
166
166
|
parameters: Type.Object({
|
|
167
167
|
table: Type.String({ description: "表名,例如 T_PUR_POORDER。" }),
|
|
168
168
|
product: Type.Optional(Type.String({ description: "金蝶产品:flagship、xinghan、cangqiong 或 enterprise。" })),
|
|
169
|
-
edition: Type.Optional(Type.String({ description: "旧参数,等同于 product
|
|
169
|
+
edition: Type.Optional(Type.String({ description: "旧参数,等同于 product;product 覆盖 edition。" })),
|
|
170
170
|
}),
|
|
171
171
|
|
|
172
172
|
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
@@ -175,8 +175,8 @@ const kdTableTool = defineTool({
|
|
|
175
175
|
if (!edition) {
|
|
176
176
|
const guidance =
|
|
177
177
|
profile.product === "unknown"
|
|
178
|
-
? "
|
|
179
|
-
: "
|
|
178
|
+
? "必须提供 product。禁止跨金蝶产品族猜测表结构。"
|
|
179
|
+
: "没有元数据查证前,禁止把旗舰版/企业版表结构假设复用到苍穹/星瀚/Cosmic。";
|
|
180
180
|
return {
|
|
181
181
|
content: [
|
|
182
182
|
{
|
|
@@ -204,12 +204,12 @@ const kdCheckTool = defineTool({
|
|
|
204
204
|
name: "kd_check",
|
|
205
205
|
label: "KD 检查",
|
|
206
206
|
description:
|
|
207
|
-
"检查金蝶 Java/C#/Python 插件代码中的魔法值、命名问题、循环内 DB 调用和空 catch
|
|
207
|
+
"检查金蝶 Java/C#/Python 插件代码中的魔法值、命名问题、循环内 DB 调用和空 catch。",
|
|
208
208
|
parameters: Type.Object({
|
|
209
|
-
code: Type.Optional(Type.String({ description: "
|
|
210
|
-
path: Type.Optional(Type.String({ description: "
|
|
209
|
+
code: Type.Optional(Type.String({ description: "待检查源码。与 path 二选一。" })),
|
|
210
|
+
path: Type.Optional(Type.String({ description: "待检查源码文件路径。与 code 二选一。" })),
|
|
211
211
|
product: Type.Optional(Type.String({ description: "金蝶产品。未提供 language 时用于推导 Java 或 C#。" })),
|
|
212
|
-
language: Type.Optional(Type.String({ description: "语言:java、csharp 或 python
|
|
212
|
+
language: Type.Optional(Type.String({ description: "语言:java、csharp 或 python。覆盖产品推导结果。" })),
|
|
213
213
|
}),
|
|
214
214
|
|
|
215
215
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
@@ -226,7 +226,7 @@ const kdCheckTool = defineTool({
|
|
|
226
226
|
|
|
227
227
|
if (!code) {
|
|
228
228
|
return {
|
|
229
|
-
content: [{ type: "text", text: "kd_check
|
|
229
|
+
content: [{ type: "text", text: "kd_check 必须提供 code 或 path。" }],
|
|
230
230
|
details: { error: "missing-code-or-path" },
|
|
231
231
|
};
|
|
232
232
|
}
|
|
@@ -250,8 +250,8 @@ const kdCosmicConfigTool = defineTool({
|
|
|
250
250
|
description: "运行 Cosmic 家族金蝶产品的官方能力配置预检查。",
|
|
251
251
|
parameters: Type.Object({
|
|
252
252
|
product: Type.String({ description: "支持 Cosmic 平台能力的产品:cangqiong、xinghan 或 flagship。" }),
|
|
253
|
-
config: Type.Optional(Type.String({ description: "
|
|
254
|
-
dryRun: Type.Optional(Type.Boolean({ description: "
|
|
253
|
+
config: Type.Optional(Type.String({ description: "ok-cosmic.json 路径;省略时按当前工作目录解析。" })),
|
|
254
|
+
dryRun: Type.Optional(Type.Boolean({ description: "输出命令预览;不实际执行。" })),
|
|
255
255
|
}),
|
|
256
256
|
|
|
257
257
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
@@ -268,14 +268,14 @@ const kdCosmicMetadataTool = defineTool({
|
|
|
268
268
|
description: "查询官方 Cosmic 表单/单据元数据,包括字段、枚举值、操作和 SQL 表信息。",
|
|
269
269
|
parameters: Type.Object({
|
|
270
270
|
product: Type.String({ description: "支持 Cosmic 平台能力的产品:cangqiong、xinghan 或 flagship。" }),
|
|
271
|
-
form: Type.String({ description: "Form ID、单据 ID
|
|
272
|
-
config: Type.Optional(Type.String({ description: "
|
|
273
|
-
fuzzy: Type.Optional(Type.String({ description: "
|
|
274
|
-
typeFilter: Type.Optional(Type.String({ description: "
|
|
275
|
-
sql: Type.Optional(Type.Boolean({ description: "
|
|
276
|
-
op: Type.Optional(Type.Boolean({ description: "
|
|
277
|
-
showDetail: Type.Optional(Type.Boolean({ description: "
|
|
278
|
-
dryRun: Type.Optional(Type.Boolean({ description: "
|
|
271
|
+
form: Type.String({ description: "Form ID、单据 ID 或中文单据名;多个目标使用逗号分隔。" }),
|
|
272
|
+
config: Type.Optional(Type.String({ description: "ok-cosmic.json 路径;省略时使用默认配置。" })),
|
|
273
|
+
fuzzy: Type.Optional(Type.String({ description: "字段关键词,使用空格或逗号分隔。" })),
|
|
274
|
+
typeFilter: Type.Optional(Type.String({ description: "字段类型正则,例如 combo|check 或 decimal。" })),
|
|
275
|
+
sql: Type.Optional(Type.Boolean({ description: "包含数据库表和字段信息。" })),
|
|
276
|
+
op: Type.Optional(Type.Boolean({ description: "显示表单/单据操作。" })),
|
|
277
|
+
showDetail: Type.Optional(Type.Boolean({ description: "显示详细元数据输出。" })),
|
|
278
|
+
dryRun: Type.Optional(Type.Boolean({ description: "输出命令预览;不实际执行。" })),
|
|
279
279
|
}),
|
|
280
280
|
|
|
281
281
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
@@ -289,15 +289,15 @@ const kdCosmicMetadataTool = defineTool({
|
|
|
289
289
|
const kdCosmicApiTool = defineTool({
|
|
290
290
|
name: "kd_cosmic_api",
|
|
291
291
|
label: "KD Cosmic API",
|
|
292
|
-
description: "查询随包 Cosmic API
|
|
292
|
+
description: "查询随包 Cosmic API 知识,输出类和方法线索;最终签名事实必须以 kd_sdk_signature 或项目构建输出为准。",
|
|
293
293
|
parameters: Type.Object({
|
|
294
294
|
product: Type.String({ description: "支持 Cosmic 平台能力的产品:cangqiong、xinghan 或 flagship。" }),
|
|
295
295
|
mode: Type.String({ description: "查询模式:search、search-method 或 detail。" }),
|
|
296
296
|
query: Type.String({ description: "类名、方法名或完整限定类名。" }),
|
|
297
|
-
config: Type.Optional(Type.String({ description: "
|
|
298
|
-
method: Type.Optional(Type.String({ description: "detail
|
|
299
|
-
compact: Type.Optional(Type.Boolean({ description: "
|
|
300
|
-
dryRun: Type.Optional(Type.Boolean({ description: "
|
|
297
|
+
config: Type.Optional(Type.String({ description: "ok-cosmic.json 路径;省略时使用默认配置。" })),
|
|
298
|
+
method: Type.Optional(Type.String({ description: "detail 模式下的方法过滤条件。" })),
|
|
299
|
+
compact: Type.Optional(Type.Boolean({ description: "启用紧凑详情输出;命令支持时生效。" })),
|
|
300
|
+
dryRun: Type.Optional(Type.Boolean({ description: "输出命令预览;不实际执行。" })),
|
|
301
301
|
}),
|
|
302
302
|
|
|
303
303
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
@@ -323,14 +323,14 @@ const kdSdkSignatureTool = defineTool({
|
|
|
323
323
|
name: "kd_sdk_signature",
|
|
324
324
|
label: "KD SDK 签名",
|
|
325
325
|
description:
|
|
326
|
-
"从当前项目真实存在的 SDK jar 或 dll
|
|
326
|
+
"从当前项目真实存在的 SDK jar 或 dll 中检查方法/类型签名。API 签名事实必须使用此工具查证,不以随包知识库替代。",
|
|
327
327
|
parameters: Type.Object({
|
|
328
328
|
product: Type.Optional(Type.String({ description: "金蝶产品。未提供 language 时用于推导 Java 或 C#。" })),
|
|
329
329
|
language: Type.Optional(Type.String({ description: "java 或 csharp。默认由产品画像推导。" })),
|
|
330
|
-
query: Type.Optional(Type.String({ description: "
|
|
331
|
-
className: Type.Optional(Type.String({ description: "
|
|
332
|
-
method: Type.Optional(Type.String({ description: "
|
|
333
|
-
path: Type.Optional(Type.String({ description: "
|
|
330
|
+
query: Type.Optional(Type.String({ description: "类/类型搜索关键词,例如 QueryServiceHelper 或 DynamicObject。" })),
|
|
331
|
+
className: Type.Optional(Type.String({ description: "完整限定 Java/C# 类型名。" })),
|
|
332
|
+
method: Type.Optional(Type.String({ description: "在匹配类/类型内过滤方法或属性;禁止全局扫描所有方法。" })),
|
|
333
|
+
path: Type.Optional(Type.String({ description: "SDK lib/bin 目录或依赖根路径;省略时从当前项目查找。" })),
|
|
334
334
|
limit: Type.Optional(Type.Number({ description: "最大检查 jar/dll/class 数量。默认 20 个结果类、200 个文件。" })),
|
|
335
335
|
}),
|
|
336
336
|
|
|
@@ -361,8 +361,8 @@ const kdKsqlLintTool = defineTool({
|
|
|
361
361
|
description: "对生成的 KSQL/SQL 文件运行官方 ok-ksql lint 检查。",
|
|
362
362
|
parameters: Type.Object({
|
|
363
363
|
product: Type.String({ description: "支持 Cosmic 平台能力的产品:cangqiong、xinghan 或 flagship。" }),
|
|
364
|
-
path: Type.String({ description: "SQL/KSQL
|
|
365
|
-
dryRun: Type.Optional(Type.Boolean({ description: "
|
|
364
|
+
path: Type.String({ description: "SQL/KSQL 文件路径;支持工作区相对路径或绝对路径。" }),
|
|
365
|
+
dryRun: Type.Optional(Type.Boolean({ description: "输出命令预览;不实际执行。" })),
|
|
366
366
|
}),
|
|
367
367
|
|
|
368
368
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
@@ -379,8 +379,8 @@ const kdBuildTool = defineTool({
|
|
|
379
379
|
description: "按产品画像运行或预览金蝶构建命令,支持 Cosmic Java 和企业版 C# 项目。",
|
|
380
380
|
parameters: Type.Object({
|
|
381
381
|
product: Type.String({ description: "金蝶产品:cangqiong、xinghan、flagship 或 enterprise。" }),
|
|
382
|
-
target: Type.Optional(Type.String({ description: "Java
|
|
383
|
-
dryRun: Type.Optional(Type.Boolean({ description: "
|
|
382
|
+
target: Type.Optional(Type.String({ description: "Java 使用 Gradle task;C# 使用 .sln/.csproj 路径。" })),
|
|
383
|
+
dryRun: Type.Optional(Type.Boolean({ description: "输出构建命令预览;不实际执行。" })),
|
|
384
384
|
}),
|
|
385
385
|
|
|
386
386
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
@@ -400,11 +400,11 @@ const kdBuildTool = defineTool({
|
|
|
400
400
|
const kdDebugTool = defineTool({
|
|
401
401
|
name: "kd_debug",
|
|
402
402
|
label: "KD 调试",
|
|
403
|
-
description: "
|
|
403
|
+
description: "分析金蝶构建/运行日志或堆栈,输出推断原因和检查指令。",
|
|
404
404
|
parameters: Type.Object({
|
|
405
405
|
text: Type.Optional(Type.String({ description: "日志文本或堆栈。与 path 二选一。" })),
|
|
406
406
|
path: Type.Optional(Type.String({ description: "日志文件路径。与 text 二选一。" })),
|
|
407
|
-
product: Type.Optional(Type.String({ description: "
|
|
407
|
+
product: Type.Optional(Type.String({ description: "产品上下文。" })),
|
|
408
408
|
}),
|
|
409
409
|
|
|
410
410
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
@@ -434,10 +434,10 @@ const kdDocReadTool = defineTool({
|
|
|
434
434
|
name: "kd_doc_read",
|
|
435
435
|
label: "KD 文档读取",
|
|
436
436
|
description:
|
|
437
|
-
"读取 PDF、Word (.docx/.doc)、Excel (.xlsx/.xls) 或 CSV 文件并提取文本内容。对于 .pdf、.docx、.doc、.xlsx、.xls、.csv 文件,必须使用此工具而非 read 工具,因为 read 无法解析这些二进制格式。PDF
|
|
437
|
+
"读取 PDF、Word (.docx/.doc)、Excel (.xlsx/.xls) 或 CSV 文件并提取文本内容。对于 .pdf、.docx、.doc、.xlsx、.xls、.csv 文件,必须使用此工具而非 read 工具,因为 read 无法解析这些二进制格式。PDF 目前仅支持可复制文本抽取;扫描型 PDF 必须另行提供图片或 OCR 结果。",
|
|
438
438
|
parameters: Type.Object({
|
|
439
439
|
path: Type.String({ description: "文档文件路径,支持 .pdf、.docx、.doc、.xlsx、.xls、.csv。" }),
|
|
440
|
-
sheet: Type.Optional(Type.String({ description: "Excel 工作表名或序号(从 1
|
|
440
|
+
sheet: Type.Optional(Type.String({ description: "Excel 工作表名或序号(从 1 开始)。默认第一个工作表。" })),
|
|
441
441
|
maxRows: Type.Optional(Type.Number({ description: "Excel/CSV 最大返回行数。默认 200。" })),
|
|
442
442
|
maxPages: Type.Optional(Type.Number({ description: "PDF 最大提取页数。默认 50。" })),
|
|
443
443
|
}),
|
|
@@ -516,7 +516,7 @@ function extractXlsx(filePath: string, sheetNameOrIndex?: string, maxRows?: numb
|
|
|
516
516
|
} else if (sheetNames.includes(sheetNameOrIndex)) {
|
|
517
517
|
sheetName = sheetNameOrIndex;
|
|
518
518
|
} else {
|
|
519
|
-
return `[Excel] 工作表 "${sheetNameOrIndex}"
|
|
519
|
+
return `[Excel] 工作表 "${sheetNameOrIndex}" 不存在。有效工作表:${sheetNames.join(", ")}`;
|
|
520
520
|
}
|
|
521
521
|
} else {
|
|
522
522
|
sheetName = sheetNames[0];
|
package/package.json
CHANGED
package/src/cli/kcode.ts
CHANGED
|
@@ -98,8 +98,8 @@ export function doctor(cwd: string, args: string[] = []): KcodeCliResult {
|
|
|
98
98
|
lines.push(`Pi CLI:${formatPiCliStatus(piCli, pi)}`);
|
|
99
99
|
lines.push(`KCode version:${packageName}@${packageVersion}`);
|
|
100
100
|
lines.push(`KCode package:${packageRoot}`);
|
|
101
|
-
lines.push(`项目配置:${existsSync(settingsPath) ? settingsPath : "
|
|
102
|
-
lines.push(`项目上下文:${existsSync(projectContextPath) ? projectContextPath : "
|
|
101
|
+
lines.push(`项目配置:${existsSync(settingsPath) ? settingsPath : "未创建,运行 kcode init"}`);
|
|
102
|
+
lines.push(`项目上下文:${existsSync(projectContextPath) ? projectContextPath : "未创建,运行 kcode context"}`);
|
|
103
103
|
|
|
104
104
|
if (existsSync(settingsPath)) {
|
|
105
105
|
const settingsResult = readSettingsSafe(settingsPath);
|
|
@@ -199,7 +199,7 @@ export function start(cwd: string, piArgs: string[]): KcodeCliResult {
|
|
|
199
199
|
if (!piCli) {
|
|
200
200
|
return {
|
|
201
201
|
exitCode: 1,
|
|
202
|
-
output: `${init.output}\n未找到随包 Pi CLI 或全局 pi
|
|
202
|
+
output: `${init.output}\n未找到随包 Pi CLI 或全局 pi 命令。重新安装 kcode-pi 后再运行 kcode start。`,
|
|
203
203
|
};
|
|
204
204
|
}
|
|
205
205
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { basename, extname, join, relative } from "node:path";
|
|
3
|
+
import { PROJECT_PERSISTENT_RULES, formatPromptLines } from "../harness/prompt-policy.js";
|
|
3
4
|
|
|
4
5
|
const IGNORED_DIRS = new Set([
|
|
5
6
|
".git",
|
|
@@ -67,11 +68,9 @@ export function generateProjectContext(cwd: string): string {
|
|
|
67
68
|
"",
|
|
68
69
|
"## 持久规则",
|
|
69
70
|
"",
|
|
70
|
-
|
|
71
|
-
"-
|
|
72
|
-
"-
|
|
73
|
-
"- 调用文件工具时优先使用项目相对路径。在 Windows 中,不要把路径改写为 /mnt/<drive>/... 或 /<drive>/...;只有确需绝对路径时才使用 Windows 路径。",
|
|
74
|
-
"- 如果本文件过期,计划前先运行 `kcode context --refresh` 重新生成。",
|
|
71
|
+
...formatPromptLines(PROJECT_PERSISTENT_RULES),
|
|
72
|
+
"- 禁止假设模块结构。必须基于下方真实路径,并在编辑前确认目标文件。",
|
|
73
|
+
"- 调用文件工具时默认使用项目相对路径。在 Windows 中禁止把路径改写为 /mnt/<drive>/... 或 /<drive>/...;绝对路径只允许使用 Windows 路径。",
|
|
75
74
|
"- 只有 Harness 进入 `execute` 且 PLAN.md 写明真实目标路径后,才能写产品代码。",
|
|
76
75
|
"",
|
|
77
76
|
"## 项目结构摘要",
|
package/src/harness/artifacts.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { ActiveRun, KdPhase } from "./types.ts";
|
|
|
3
3
|
import { PHASE_ARTIFACTS } from "./types.ts";
|
|
4
4
|
import { runArtifactPath, runRoot } from "./paths.ts";
|
|
5
5
|
import type { ProductProfile } from "../product/profile.ts";
|
|
6
|
+
import { PLAN_REQUIRED_CHECK_LINES, formatPromptLines } from "./prompt-policy.ts";
|
|
6
7
|
|
|
7
8
|
export function ensureRunDirectories(cwd: string, run: ActiveRun): void {
|
|
8
9
|
mkdirSync(runRoot(cwd, run), { recursive: true });
|
|
@@ -86,7 +87,7 @@ export function defaultArtifactContent(phase: KdPhase, goal?: string, profile?:
|
|
|
86
87
|
"",
|
|
87
88
|
"## 已检查的项目结构",
|
|
88
89
|
"",
|
|
89
|
-
"##
|
|
90
|
+
"## 待读取文件",
|
|
90
91
|
"",
|
|
91
92
|
"## 目标源码根 / 路径",
|
|
92
93
|
"",
|
|
@@ -99,9 +100,7 @@ export function defaultArtifactContent(phase: KdPhase, goal?: string, profile?:
|
|
|
99
100
|
"",
|
|
100
101
|
"## 必需的金蝶查证项",
|
|
101
102
|
"",
|
|
102
|
-
|
|
103
|
-
"- 知识库搜索、随包 Cosmic API 查询只能作为线索,不能作为最终方法签名事实。",
|
|
104
|
-
"- SDK 签名证据:evidence/sdk-signature.md",
|
|
103
|
+
...formatPromptLines(PLAN_REQUIRED_CHECK_LINES),
|
|
105
104
|
"",
|
|
106
105
|
"## 需求条目 / 依赖 / 批次",
|
|
107
106
|
"",
|
|
@@ -120,12 +119,12 @@ export function defaultArtifactContent(phase: KdPhase, goal?: string, profile?:
|
|
|
120
119
|
"- 红灯证据:evidence/tdd-red.md",
|
|
121
120
|
"- 绿灯证据:evidence/tdd-green.md",
|
|
122
121
|
"- 红绿检查命令或工具:未知",
|
|
123
|
-
"- Java
|
|
122
|
+
"- Java 语法/编译检查:使用当前项目 Gradle 命令,例如 `./gradlew build`、`.\\gradlew.bat build` 或 `./gradlew :模块:build`。",
|
|
124
123
|
"- C# 语法/编译检查:使用 `dotnet build`、`dotnet build <.sln>` 或 `dotnet build <.csproj>`。",
|
|
125
124
|
"- 允许的检查:本地 SDK 签名查证、官方 API/基类/方法查证、元数据查证、kd_check、Gradle/dotnet 构建输出、项目已有测试框架、外部接口最小验证。",
|
|
126
|
-
"-
|
|
125
|
+
"- 测试框架:使用项目已有测试基础设施。",
|
|
127
126
|
"- 命令无法运行时记录真实阻塞原因和残余风险,不能作为绿灯证据。",
|
|
128
|
-
"-
|
|
127
|
+
"- 自动化测试不可执行时,记录一个产品相关、实现前应失败且实现后应通过的检查。",
|
|
129
128
|
"- SDK 方法签名事实必须来自当前项目 jar/dll、构建输出或官方元数据。",
|
|
130
129
|
"",
|
|
131
130
|
"## 验证命令",
|