kcode-pi 0.1.14 → 0.1.16
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 +31 -25
- package/dist/context/project-context.js +20 -20
- package/extensions/kingdee-harness.ts +89 -82
- package/extensions/kingdee-header.ts +16 -16
- package/extensions/kingdee-tools.ts +112 -83
- package/package.json +2 -2
- package/prompts/kd-discuss.md +4 -4
- package/prompts/kd-execute.md +4 -5
- package/prompts/kd-plan.md +4 -5
- package/prompts/kd-ship.md +4 -5
- package/prompts/kd-spec.md +4 -5
- package/prompts/kd-verify.md +4 -5
- package/src/context/project-context.ts +20 -20
- package/src/harness/artifacts.ts +52 -47
- package/src/harness/format.ts +12 -12
- package/src/harness/gates.ts +23 -13
- package/src/harness/plan-steps.ts +3 -3
- package/src/harness/sdk-policy.ts +37 -0
- package/src/harness/state.ts +4 -4
- package/src/harness/tdd-policy.ts +2 -2
- package/src/knowledge/format.ts +11 -12
- package/src/product/profile.ts +16 -16
- package/src/tools/build-debug.ts +35 -35
- package/src/tools/sdk-signature.ts +10 -10
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
KCode 是面向金蝶开发的 Pi 工作环境启动器。安装后会提供全局命令 `kcode`,自动携带 Pi CLI,并在当前业务项目中加载金蝶专属工具、skills、prompts、themes 和知识库。
|
|
4
4
|
|
|
5
|
+
KCode 默认面向中文用户:README、`kcode help`、Pi 内 `/kd-*` 命令说明、工具参数说明、内置 prompts 和 Harness 阶段文档模板均使用中文。命令名和产品标识仍保持英文,例如 `/kd-start`、`kd_search`、`flagship`。
|
|
6
|
+
|
|
5
7
|
KCode 不要求你单独安装全局 `pi` 命令,也不会修改用户全局 Pi 配置。它只维护当前项目的:
|
|
6
8
|
|
|
7
9
|
```text
|
|
@@ -289,17 +291,17 @@ kcode start --provider openai --model gpt-4o
|
|
|
289
291
|
进入 `kcode start` 后,可以使用以下 KCode 命令:
|
|
290
292
|
|
|
291
293
|
```text
|
|
292
|
-
/kd-start [--product
|
|
293
|
-
/kd-product
|
|
294
|
+
/kd-start [--product 产品] [--version 版本] <需求>
|
|
295
|
+
/kd-product <产品> [--version 版本]
|
|
294
296
|
/kd-status
|
|
295
297
|
/kd-runs
|
|
296
298
|
/kd-switch <run-id>
|
|
297
299
|
/kd-resume [补充说明]
|
|
298
300
|
/kd-finish
|
|
299
301
|
/kd-gate
|
|
300
|
-
/kd-advance [
|
|
301
|
-
/kd-artifact [
|
|
302
|
-
/kd-answer Q-001
|
|
302
|
+
/kd-advance [阶段]
|
|
303
|
+
/kd-artifact [阶段] [内容]
|
|
304
|
+
/kd-answer Q-001 <答案>
|
|
303
305
|
```
|
|
304
306
|
|
|
305
307
|
典型开始方式:
|
|
@@ -393,8 +395,10 @@ ship 汇总变更、验证证据、风险和后续事项
|
|
|
393
395
|
|
|
394
396
|
- 未进入 `execute` 阶段时,KCode 会阻止写入 Java/XML/SQL 等产品代码。
|
|
395
397
|
- 进入 `execute` 前必须已有 `PLAN.md` 和必要证据。
|
|
396
|
-
- `PLAN.md` 必须包含 `##
|
|
397
|
-
- `PLAN.md` 必须包含 `## TDD /
|
|
398
|
+
- `PLAN.md` 必须包含 `## 执行步骤`,并用 `- [ ] STEP-001:...` 格式拆分可跟踪步骤。
|
|
399
|
+
- `PLAN.md` 必须包含 `## TDD / 红绿检查`,声明红灯证据、绿灯证据和测试/检查命令。
|
|
400
|
+
- Java/C# 产品代码进入 `execute` 前必须已有 `evidence/sdk-signature.md`。该证据由 `kd_sdk_signature` 成功查证当前项目真实 SDK jar/dll 后自动写入。
|
|
401
|
+
- LLM 禁止凭记忆、模型知识或随包知识库猜 SDK 方法签名。`kd_search`、`kd_cosmic_api` 只能作为线索;最终签名事实必须来自 `kd_sdk_signature`、当前项目构建输出、项目源码封装或官方元数据。
|
|
398
402
|
- 红绿检查不等于必须写 JUnit。金蝶项目不要为了满足门禁引入额外 jar 或测试框架。
|
|
399
403
|
- 写生产源码前必须已有 `evidence/tdd-red.md`,内容可以是 API/基类/方法签名检查、元数据检查、编译检查、既有测试框架或外部接口最小验证的失败输出。
|
|
400
404
|
- 进入 `execute` 后,只允许写入 `PLAN.md` 明确列出的源码文件;如果临时发现要改新文件,必须先回到 plan 更新 `PLAN.md`。
|
|
@@ -405,36 +409,37 @@ ship 汇总变更、验证证据、风险和后续事项
|
|
|
405
409
|
示例计划步骤:
|
|
406
410
|
|
|
407
411
|
```markdown
|
|
408
|
-
##
|
|
412
|
+
## 执行步骤
|
|
409
413
|
|
|
410
|
-
- [ ] STEP-001
|
|
411
|
-
- [ ] STEP-002
|
|
412
|
-
- [ ] STEP-003
|
|
413
|
-
- [ ] STEP-004
|
|
414
|
-
- [ ] STEP-005
|
|
414
|
+
- [ ] STEP-001:检查现有插件基类、包名和目标字段。
|
|
415
|
+
- [ ] STEP-002:运行 API/元数据/编译等红灯检查并记录证据。
|
|
416
|
+
- [ ] STEP-003:修改 `code/scm/plugin/src/main/java/.../PurchaseOrderPlugin.java`。
|
|
417
|
+
- [ ] STEP-004:运行同一类绿灯检查并记录证据。
|
|
418
|
+
- [ ] STEP-005:记录变更文件和验证证据。
|
|
415
419
|
```
|
|
416
420
|
|
|
417
421
|
示例红绿检查:
|
|
418
422
|
|
|
419
423
|
```markdown
|
|
420
|
-
## TDD /
|
|
424
|
+
## TDD / 红绿检查
|
|
421
425
|
|
|
422
|
-
-
|
|
423
|
-
-
|
|
424
|
-
-
|
|
425
|
-
-
|
|
426
|
+
- 红灯证据:evidence/tdd-red.md
|
|
427
|
+
- 绿灯证据:evidence/tdd-green.md
|
|
428
|
+
- 红绿检查命令或工具:kd_sdk_signature / kd_cosmic_metadata / kd_check / build
|
|
429
|
+
- 不要为了满足门禁引入第三方测试 jar 或测试框架。
|
|
430
|
+
- Java/C# SDK 签名证据:evidence/sdk-signature.md
|
|
426
431
|
```
|
|
427
432
|
|
|
428
433
|
示例执行记录:
|
|
429
434
|
|
|
430
435
|
```markdown
|
|
431
|
-
##
|
|
436
|
+
## 步骤结果
|
|
432
437
|
|
|
433
|
-
- [x] STEP-001
|
|
434
|
-
- [x] STEP-002
|
|
435
|
-
- [x] STEP-003
|
|
436
|
-
- [x] STEP-004
|
|
437
|
-
- [x] STEP-005
|
|
438
|
+
- [x] STEP-001:已完成。证据:evidence/step-001.md
|
|
439
|
+
- [x] STEP-002:已完成。证据:evidence/step-002.md
|
|
440
|
+
- [x] STEP-003:已完成。证据:evidence/step-003.md
|
|
441
|
+
- [x] STEP-004:已完成。证据:evidence/tdd-green.md
|
|
442
|
+
- [x] STEP-005:已完成。证据:evidence/step-005.md
|
|
438
443
|
```
|
|
439
444
|
|
|
440
445
|
如果 LLM 跳过步骤、没有记录 evidence,或只是口头声明完成,KCode 不允许进入 `verify`。
|
|
@@ -449,7 +454,7 @@ ship 汇总变更、验证证据、风险和后续事项
|
|
|
449
454
|
|
|
450
455
|
得到回答后,再继续问触发时机、库存条件、弹窗内容或插件位置。
|
|
451
456
|
|
|
452
|
-
在 `kcode start` 的交互式 TUI 中,`kd_question` 会弹出 KCode
|
|
457
|
+
在 `kcode start` 的交互式 TUI 中,`kd_question` 会弹出 KCode 问题选择/输入对话,并在用户选择或输入后自动记录答案。非交互模式或 UI 不可用时,问题会显示在对话里,用户直接回复;Agent 读取回复后再记录答案。也可以手动执行:
|
|
453
458
|
|
|
454
459
|
```text
|
|
455
460
|
/kd-answer Q-001 采购订单
|
|
@@ -489,6 +494,7 @@ kd_debug 分析金蝶日志和堆栈
|
|
|
489
494
|
- `kd_cosmic_metadata` 使用统一路由 API 查询真实单据/表单元数据,并在当前项目 `.pi/kd/official-skills/` 下维护 JSON 缓存。
|
|
490
495
|
- `kd_sdk_signature` 优先从当前业务项目的实际 SDK jar/dll 中读取类型和方法签名。Cosmic Java 依赖 `javap`,Enterprise C# 依赖 PowerShell 读取 DLL 元数据。
|
|
491
496
|
- `kd_cosmic_api` 查询随包金蝶知识库,只作为 API 线索和兜底;精确方法签名优先使用 `kd_sdk_signature`、当前项目 SDK 或编译输出确认。
|
|
497
|
+
- 当前项目存在 active run 时,`kd_sdk_signature` 成功后会自动写入 `.pi/kd/runs/<run-id>/evidence/sdk-signature.md`。Java/C# 产品代码缺少这份证据时,KCode 不允许进入 `execute` 或写生产源码。
|
|
492
498
|
|
|
493
499
|
示例:
|
|
494
500
|
|
|
@@ -47,33 +47,33 @@ export function generateProjectContext(cwd) {
|
|
|
47
47
|
const buildFiles = scan.files.filter((file) => BUILD_FILE_NAMES.has(basename(file).toLowerCase()) || isSolutionOrProject(file));
|
|
48
48
|
const sourceSamples = scan.files.filter((file) => SOURCE_EXTENSIONS.has(extname(file).toLowerCase())).slice(0, MAX_SOURCE_SAMPLES);
|
|
49
49
|
return [
|
|
50
|
-
"# KCode
|
|
50
|
+
"# KCode 项目上下文",
|
|
51
51
|
"",
|
|
52
|
-
`-
|
|
53
|
-
`-
|
|
54
|
-
`-
|
|
52
|
+
`- 项目根目录:${cwd}`,
|
|
53
|
+
`- 项目名称:${basename(cwd)}`,
|
|
54
|
+
`- 生成时间:${new Date().toISOString()}`,
|
|
55
55
|
"",
|
|
56
|
-
"##
|
|
56
|
+
"## 持久规则",
|
|
57
57
|
"",
|
|
58
|
-
"-
|
|
59
|
-
"-
|
|
60
|
-
"-
|
|
61
|
-
"-
|
|
62
|
-
"-
|
|
63
|
-
"-
|
|
58
|
+
"- 本文件是 KCode 的项目记忆,计划或编辑代码前必须读取。",
|
|
59
|
+
"- 业务需求不得生成 demo/sample/scaffold 代码。",
|
|
60
|
+
"- 不要假设模块结构。必须基于下方真实路径,并在编辑前确认目标文件。",
|
|
61
|
+
"- 调用文件工具时优先使用项目相对路径。在 Windows 中,不要把路径改写为 /mnt/<drive>/... 或 /<drive>/...;只有确需绝对路径时才使用 Windows 路径。",
|
|
62
|
+
"- 如果本文件过期,计划前先运行 `kcode context --refresh` 重新生成。",
|
|
63
|
+
"- 只有 Harness 进入 `execute` 且 PLAN.md 写明真实目标路径后,才能写产品代码。",
|
|
64
64
|
"",
|
|
65
|
-
"##
|
|
65
|
+
"## 项目结构摘要",
|
|
66
66
|
"",
|
|
67
|
-
`-
|
|
68
|
-
`-
|
|
69
|
-
`-
|
|
70
|
-
`-
|
|
67
|
+
`- 是否存在 code 目录:${codeDir ? "是" : "否"}`,
|
|
68
|
+
`- 可能的源码根:${formatList(likelyRoots)}`,
|
|
69
|
+
`- 构建文件:${formatList(buildFiles)}`,
|
|
70
|
+
`- 识别到的模块:${formatList(modules)}`,
|
|
71
71
|
"",
|
|
72
|
-
"##
|
|
72
|
+
"## 源码样例",
|
|
73
73
|
"",
|
|
74
74
|
formatBlockList(sourceSamples),
|
|
75
75
|
"",
|
|
76
|
-
"##
|
|
76
|
+
"## 顶层目录",
|
|
77
77
|
"",
|
|
78
78
|
formatBlockList(scan.directories.filter((dir) => !dir.includes("/") && !dir.includes("\\")).sort()),
|
|
79
79
|
"",
|
|
@@ -181,11 +181,11 @@ function isSolutionOrProject(file) {
|
|
|
181
181
|
return [".sln", ".csproj"].includes(extname(file).toLowerCase());
|
|
182
182
|
}
|
|
183
183
|
function formatList(values) {
|
|
184
|
-
return values.length > 0 ? values.join(", ") : "
|
|
184
|
+
return values.length > 0 ? values.join(", ") : "未识别";
|
|
185
185
|
}
|
|
186
186
|
function formatBlockList(values) {
|
|
187
187
|
if (values.length === 0)
|
|
188
|
-
return "-
|
|
188
|
+
return "- 未识别";
|
|
189
189
|
return values.map((value) => `- ${value}`).join("\n");
|
|
190
190
|
}
|
|
191
191
|
function normalize(path) {
|