kcode-pi 0.1.13 → 0.1.15
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 +47 -27
- package/dist/cli/kcode.d.ts +2 -1
- package/dist/cli/kcode.js +104 -7
- package/dist/context/project-context.js +20 -20
- package/docs/DEVELOPMENT.md +2 -5
- package/extensions/kingdee-harness.ts +80 -80
- package/extensions/kingdee-header.ts +16 -16
- package/extensions/kingdee-tools.ts +82 -82
- package/package.json +3 -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/cli/kcode.ts +101 -7
- package/src/context/project-context.ts +20 -20
- package/src/harness/artifacts.ts +47 -47
- package/src/harness/format.ts +12 -12
- package/src/harness/gates.ts +5 -5
- package/src/harness/plan-steps.ts +3 -3
- 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
|
|
@@ -59,6 +61,13 @@ kcode context --refresh
|
|
|
59
61
|
|
|
60
62
|
```powershell
|
|
61
63
|
kcode doctor
|
|
64
|
+
kcode doctor --deep
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
修复项目级 KCode 配置:
|
|
68
|
+
|
|
69
|
+
```powershell
|
|
70
|
+
kcode repair
|
|
62
71
|
```
|
|
63
72
|
|
|
64
73
|
查看当前 KCode 版本:
|
|
@@ -240,6 +249,17 @@ kcode context --refresh
|
|
|
240
249
|
|
|
241
250
|
```powershell
|
|
242
251
|
kcode doctor
|
|
252
|
+
kcode doctor --deep
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
`--deep` 会额外检查 Node 版本、npm 全局目录、项目 `.pi/settings.json` 中的重复/旧 KCode package 路径、项目上下文和 active run。
|
|
256
|
+
|
|
257
|
+
### `kcode repair`
|
|
258
|
+
|
|
259
|
+
清理当前项目 `.pi/settings.json` 中旧 Node/nvm 版本下的 KCode package 路径,只保留当前安装路径,并刷新项目上下文。
|
|
260
|
+
|
|
261
|
+
```powershell
|
|
262
|
+
kcode repair
|
|
243
263
|
```
|
|
244
264
|
|
|
245
265
|
### `kcode version`
|
|
@@ -271,17 +291,17 @@ kcode start --provider openai --model gpt-4o
|
|
|
271
291
|
进入 `kcode start` 后,可以使用以下 KCode 命令:
|
|
272
292
|
|
|
273
293
|
```text
|
|
274
|
-
/kd-start [--product
|
|
275
|
-
/kd-product
|
|
294
|
+
/kd-start [--product 产品] [--version 版本] <需求>
|
|
295
|
+
/kd-product <产品> [--version 版本]
|
|
276
296
|
/kd-status
|
|
277
297
|
/kd-runs
|
|
278
298
|
/kd-switch <run-id>
|
|
279
299
|
/kd-resume [补充说明]
|
|
280
300
|
/kd-finish
|
|
281
301
|
/kd-gate
|
|
282
|
-
/kd-advance [
|
|
283
|
-
/kd-artifact [
|
|
284
|
-
/kd-answer Q-001
|
|
302
|
+
/kd-advance [阶段]
|
|
303
|
+
/kd-artifact [阶段] [内容]
|
|
304
|
+
/kd-answer Q-001 <答案>
|
|
285
305
|
```
|
|
286
306
|
|
|
287
307
|
典型开始方式:
|
|
@@ -375,8 +395,8 @@ ship 汇总变更、验证证据、风险和后续事项
|
|
|
375
395
|
|
|
376
396
|
- 未进入 `execute` 阶段时,KCode 会阻止写入 Java/XML/SQL 等产品代码。
|
|
377
397
|
- 进入 `execute` 前必须已有 `PLAN.md` 和必要证据。
|
|
378
|
-
- `PLAN.md` 必须包含 `##
|
|
379
|
-
- `PLAN.md` 必须包含 `## TDD /
|
|
398
|
+
- `PLAN.md` 必须包含 `## 执行步骤`,并用 `- [ ] STEP-001:...` 格式拆分可跟踪步骤。
|
|
399
|
+
- `PLAN.md` 必须包含 `## TDD / 红绿检查`,声明红灯证据、绿灯证据和测试/检查命令。
|
|
380
400
|
- 红绿检查不等于必须写 JUnit。金蝶项目不要为了满足门禁引入额外 jar 或测试框架。
|
|
381
401
|
- 写生产源码前必须已有 `evidence/tdd-red.md`,内容可以是 API/基类/方法签名检查、元数据检查、编译检查、既有测试框架或外部接口最小验证的失败输出。
|
|
382
402
|
- 进入 `execute` 后,只允许写入 `PLAN.md` 明确列出的源码文件;如果临时发现要改新文件,必须先回到 plan 更新 `PLAN.md`。
|
|
@@ -387,36 +407,36 @@ ship 汇总变更、验证证据、风险和后续事项
|
|
|
387
407
|
示例计划步骤:
|
|
388
408
|
|
|
389
409
|
```markdown
|
|
390
|
-
##
|
|
410
|
+
## 执行步骤
|
|
391
411
|
|
|
392
|
-
- [ ] STEP-001
|
|
393
|
-
- [ ] STEP-002
|
|
394
|
-
- [ ] STEP-003
|
|
395
|
-
- [ ] STEP-004
|
|
396
|
-
- [ ] STEP-005
|
|
412
|
+
- [ ] STEP-001:检查现有插件基类、包名和目标字段。
|
|
413
|
+
- [ ] STEP-002:运行 API/元数据/编译等红灯检查并记录证据。
|
|
414
|
+
- [ ] STEP-003:修改 `code/scm/plugin/src/main/java/.../PurchaseOrderPlugin.java`。
|
|
415
|
+
- [ ] STEP-004:运行同一类绿灯检查并记录证据。
|
|
416
|
+
- [ ] STEP-005:记录变更文件和验证证据。
|
|
397
417
|
```
|
|
398
418
|
|
|
399
419
|
示例红绿检查:
|
|
400
420
|
|
|
401
421
|
```markdown
|
|
402
|
-
## TDD /
|
|
422
|
+
## TDD / 红绿检查
|
|
403
423
|
|
|
404
|
-
-
|
|
405
|
-
-
|
|
406
|
-
-
|
|
407
|
-
-
|
|
424
|
+
- 红灯证据:evidence/tdd-red.md
|
|
425
|
+
- 绿灯证据:evidence/tdd-green.md
|
|
426
|
+
- 红绿检查命令或工具:kd_sdk_signature / kd_cosmic_metadata / kd_check / build
|
|
427
|
+
- 不要为了满足门禁引入第三方测试 jar 或测试框架。
|
|
408
428
|
```
|
|
409
429
|
|
|
410
430
|
示例执行记录:
|
|
411
431
|
|
|
412
432
|
```markdown
|
|
413
|
-
##
|
|
433
|
+
## 步骤结果
|
|
414
434
|
|
|
415
|
-
- [x] STEP-001
|
|
416
|
-
- [x] STEP-002
|
|
417
|
-
- [x] STEP-003
|
|
418
|
-
- [x] STEP-004
|
|
419
|
-
- [x] STEP-005
|
|
435
|
+
- [x] STEP-001:已完成。证据:evidence/step-001.md
|
|
436
|
+
- [x] STEP-002:已完成。证据:evidence/step-002.md
|
|
437
|
+
- [x] STEP-003:已完成。证据:evidence/step-003.md
|
|
438
|
+
- [x] STEP-004:已完成。证据:evidence/tdd-green.md
|
|
439
|
+
- [x] STEP-005:已完成。证据:evidence/step-005.md
|
|
420
440
|
```
|
|
421
441
|
|
|
422
442
|
如果 LLM 跳过步骤、没有记录 evidence,或只是口头声明完成,KCode 不允许进入 `verify`。
|
|
@@ -431,7 +451,7 @@ ship 汇总变更、验证证据、风险和后续事项
|
|
|
431
451
|
|
|
432
452
|
得到回答后,再继续问触发时机、库存条件、弹窗内容或插件位置。
|
|
433
453
|
|
|
434
|
-
在 `kcode start` 的交互式 TUI 中,`kd_question` 会弹出 KCode
|
|
454
|
+
在 `kcode start` 的交互式 TUI 中,`kd_question` 会弹出 KCode 问题选择/输入对话,并在用户选择或输入后自动记录答案。非交互模式或 UI 不可用时,问题会显示在对话里,用户直接回复;Agent 读取回复后再记录答案。也可以手动执行:
|
|
435
455
|
|
|
436
456
|
```text
|
|
437
457
|
/kd-answer Q-001 采购订单
|
|
@@ -522,7 +542,7 @@ npm install -g kcode-pi@latest
|
|
|
522
542
|
|
|
523
543
|
```powershell
|
|
524
544
|
kcode init
|
|
525
|
-
kcode doctor
|
|
545
|
+
kcode doctor --deep
|
|
526
546
|
```
|
|
527
547
|
|
|
528
548
|
## nvm 与 Node 版本切换
|
|
@@ -646,7 +666,7 @@ type .pi\settings.json
|
|
|
646
666
|
如果 `packages` 中有多条 `kcode-pi` 路径,运行:
|
|
647
667
|
|
|
648
668
|
```powershell
|
|
649
|
-
kcode
|
|
669
|
+
kcode repair
|
|
650
670
|
```
|
|
651
671
|
|
|
652
672
|
如果使用的是 `0.1.1` 或更早版本,请手工删除旧路径,或升级到最新版。
|
package/dist/cli/kcode.d.ts
CHANGED
|
@@ -11,7 +11,8 @@ export interface PiCliCommand {
|
|
|
11
11
|
export declare function runKcodeCli(args: string[], cwd?: string): KcodeCliResult;
|
|
12
12
|
export declare function initProject(cwd: string): KcodeCliResult;
|
|
13
13
|
export declare function context(cwd: string, args: string[]): KcodeCliResult;
|
|
14
|
-
export declare function doctor(cwd: string): KcodeCliResult;
|
|
14
|
+
export declare function doctor(cwd: string, args?: string[]): KcodeCliResult;
|
|
15
|
+
export declare function repair(cwd: string): KcodeCliResult;
|
|
15
16
|
export declare function version(): KcodeCliResult;
|
|
16
17
|
export declare function start(cwd: string, piArgs: string[]): KcodeCliResult;
|
|
17
18
|
export declare function resolvePiCliCommand(piArgs?: string[]): PiCliCommand | undefined;
|
package/dist/cli/kcode.js
CHANGED
|
@@ -17,7 +17,9 @@ export function runKcodeCli(args, cwd = process.cwd()) {
|
|
|
17
17
|
case "context":
|
|
18
18
|
return context(cwd, args.slice(1));
|
|
19
19
|
case "doctor":
|
|
20
|
-
return doctor(cwd);
|
|
20
|
+
return doctor(cwd, args.slice(1));
|
|
21
|
+
case "repair":
|
|
22
|
+
return repair(cwd);
|
|
21
23
|
case "version":
|
|
22
24
|
case "--version":
|
|
23
25
|
case "-v":
|
|
@@ -55,28 +57,96 @@ export function context(cwd, args) {
|
|
|
55
57
|
output: [`项目上下文已${refresh ? "刷新" : "就绪"}:${projectContext.path}`, "", projectContext.content].join("\n"),
|
|
56
58
|
};
|
|
57
59
|
}
|
|
58
|
-
export function doctor(cwd) {
|
|
60
|
+
export function doctor(cwd, args = []) {
|
|
61
|
+
const deep = args.includes("--deep");
|
|
59
62
|
const lines = [];
|
|
60
63
|
const node = spawnSync("node", ["--version"], { encoding: "utf8" });
|
|
61
64
|
const piCli = resolvePiCliCommand(["--version"]);
|
|
62
65
|
const pi = piCli ? spawnSync(piCli.command, piCli.args, { encoding: "utf8" }) : undefined;
|
|
63
66
|
const settingsPath = projectSettingsPath(cwd);
|
|
67
|
+
const projectContextPath = join(cwd, ".pi", "kd", "PROJECT_CONTEXT.md");
|
|
68
|
+
let errors = 0;
|
|
69
|
+
let warnings = 0;
|
|
64
70
|
lines.push(`Node:${node.status === 0 ? node.stdout.trim() : "未找到"}`);
|
|
65
71
|
lines.push(`Pi CLI:${formatPiCliStatus(piCli, pi)}`);
|
|
66
72
|
lines.push(`KCode version:${packageName}@${packageVersion}`);
|
|
67
73
|
lines.push(`KCode package:${packageRoot}`);
|
|
68
74
|
lines.push(`项目配置:${existsSync(settingsPath) ? settingsPath : "未创建,请先运行 kcode init"}`);
|
|
69
|
-
lines.push(`项目上下文:${existsSync(
|
|
75
|
+
lines.push(`项目上下文:${existsSync(projectContextPath) ? projectContextPath : "未创建,请运行 kcode context"}`);
|
|
70
76
|
if (existsSync(settingsPath)) {
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
77
|
+
const settingsResult = readSettingsSafe(settingsPath);
|
|
78
|
+
if (!settingsResult.ok) {
|
|
79
|
+
errors++;
|
|
80
|
+
lines.push(`[ERROR] 项目配置无法解析:${settingsResult.error}`);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const packages = settingsResult.settings.packages ?? [];
|
|
84
|
+
const hasKcode = packages.includes(normalizePath(packageRoot));
|
|
85
|
+
lines.push(`KCode package 已登记:${hasKcode ? "是" : "否"}`);
|
|
86
|
+
if (!hasKcode)
|
|
87
|
+
warnings++;
|
|
88
|
+
if (deep) {
|
|
89
|
+
const kcodePackages = packages.filter((pkg) => isSameKcodePackage(pkg, normalizePath(packageRoot)));
|
|
90
|
+
const stalePackages = kcodePackages.filter((pkg) => normalizePath(pkg) !== normalizePath(packageRoot));
|
|
91
|
+
lines.push(`KCode package 条目数:${kcodePackages.length}`);
|
|
92
|
+
if (stalePackages.length > 0) {
|
|
93
|
+
warnings++;
|
|
94
|
+
lines.push(`[WARN] 发现旧 KCode package 路径:${stalePackages.join(" | ")}`);
|
|
95
|
+
lines.push(" 运行 kcode repair 可清理旧路径并刷新项目上下文。");
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
74
99
|
}
|
|
100
|
+
else {
|
|
101
|
+
warnings++;
|
|
102
|
+
}
|
|
103
|
+
if (deep) {
|
|
104
|
+
if (!isSupportedNodeVersion(process.version)) {
|
|
105
|
+
errors++;
|
|
106
|
+
lines.push(`[ERROR] 当前 Node ${process.version} 不满足要求:>=22.19.0`);
|
|
107
|
+
}
|
|
108
|
+
if (!existsSync(projectContextPath)) {
|
|
109
|
+
warnings++;
|
|
110
|
+
lines.push("[WARN] 项目上下文不存在,运行 kcode context --refresh 或 kcode repair。");
|
|
111
|
+
}
|
|
112
|
+
const npmPrefix = spawnSync("npm", ["prefix", "-g"], { encoding: "utf8" });
|
|
113
|
+
const npmRoot = spawnSync("npm", ["root", "-g"], { encoding: "utf8" });
|
|
114
|
+
lines.push(`npm prefix -g:${npmPrefix.status === 0 ? npmPrefix.stdout.trim() : "不可用"}`);
|
|
115
|
+
lines.push(`npm root -g:${npmRoot.status === 0 ? npmRoot.stdout.trim() : "不可用"}`);
|
|
116
|
+
lines.push(`active run:${existsSync(join(cwd, ".pi", "kd", "active-run.json")) ? "存在" : "无"}`);
|
|
117
|
+
}
|
|
118
|
+
if (deep)
|
|
119
|
+
lines.push(`诊断汇总:errors=${errors} warnings=${warnings}`);
|
|
75
120
|
return {
|
|
76
|
-
exitCode: pi?.status === 0 ? 0 : 1,
|
|
121
|
+
exitCode: pi?.status === 0 && errors === 0 ? 0 : 1,
|
|
77
122
|
output: lines.join("\n"),
|
|
78
123
|
};
|
|
79
124
|
}
|
|
125
|
+
export function repair(cwd) {
|
|
126
|
+
const settingsPath = projectSettingsPath(cwd);
|
|
127
|
+
const settingsResult = readSettingsSafe(settingsPath);
|
|
128
|
+
if (!settingsResult.ok) {
|
|
129
|
+
return {
|
|
130
|
+
exitCode: 1,
|
|
131
|
+
output: `项目配置无法解析,未自动覆盖:${settingsPath}\n原因:${settingsResult.error}`,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const currentPackage = normalizePath(packageRoot);
|
|
135
|
+
const packages = (settingsResult.settings.packages ?? []).filter((pkg) => !isSameKcodePackage(pkg, currentPackage));
|
|
136
|
+
packages.unshift(currentPackage);
|
|
137
|
+
settingsResult.settings.packages = packages;
|
|
138
|
+
mkdirSync(dirname(settingsPath), { recursive: true });
|
|
139
|
+
writeFileSync(settingsPath, `${JSON.stringify(settingsResult.settings, null, 2)}\n`, "utf8");
|
|
140
|
+
const projectContext = writeProjectContext(cwd);
|
|
141
|
+
return {
|
|
142
|
+
exitCode: 0,
|
|
143
|
+
output: [
|
|
144
|
+
`已修复项目级 Pi 配置:${settingsPath}`,
|
|
145
|
+
`已保留当前 KCode package:${currentPackage}`,
|
|
146
|
+
`已刷新项目上下文:${projectContext.path}`,
|
|
147
|
+
].join("\n"),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
80
150
|
export function version() {
|
|
81
151
|
const piCli = resolvePiCliCommand(["--version"]);
|
|
82
152
|
const pi = piCli ? spawnSync(piCli.command, piCli.args, { encoding: "utf8" }) : undefined;
|
|
@@ -136,6 +206,14 @@ function readSettings(path) {
|
|
|
136
206
|
return {};
|
|
137
207
|
return JSON.parse(readFileSync(path, "utf8"));
|
|
138
208
|
}
|
|
209
|
+
function readSettingsSafe(path) {
|
|
210
|
+
try {
|
|
211
|
+
return { ok: true, settings: readSettings(path) };
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
return { ok: false, error: error instanceof Error ? error.message : String(error) };
|
|
215
|
+
}
|
|
216
|
+
}
|
|
139
217
|
function normalizePath(path) {
|
|
140
218
|
return resolve(path);
|
|
141
219
|
}
|
|
@@ -184,6 +262,24 @@ function formatPiCliStatus(piCli, result) {
|
|
|
184
262
|
const source = piCli.source === "bundled" ? "随包" : "全局";
|
|
185
263
|
return `${version}(${source}:${piCli.displayPath})`;
|
|
186
264
|
}
|
|
265
|
+
function isSupportedNodeVersion(version) {
|
|
266
|
+
const match = /^v?(\d+)\.(\d+)\.(\d+)/.exec(version.trim());
|
|
267
|
+
if (!match)
|
|
268
|
+
return false;
|
|
269
|
+
const [, majorText, minorText, patchText] = match;
|
|
270
|
+
const major = Number(majorText);
|
|
271
|
+
const minor = Number(minorText);
|
|
272
|
+
const patch = Number(patchText);
|
|
273
|
+
if (major > 22)
|
|
274
|
+
return true;
|
|
275
|
+
if (major < 22)
|
|
276
|
+
return false;
|
|
277
|
+
if (minor > 19)
|
|
278
|
+
return true;
|
|
279
|
+
if (minor < 19)
|
|
280
|
+
return false;
|
|
281
|
+
return patch >= 0;
|
|
282
|
+
}
|
|
187
283
|
function piCliPackageVersion(piCli) {
|
|
188
284
|
if (piCli.source !== "bundled")
|
|
189
285
|
return undefined;
|
|
@@ -204,6 +300,7 @@ function helpText() {
|
|
|
204
300
|
" kcode init 初始化当前项目的 .pi/settings.json",
|
|
205
301
|
" kcode context 生成或刷新 .pi/kd/PROJECT_CONTEXT.md",
|
|
206
302
|
" kcode doctor 检查 Node、随包 Pi CLI、KCode package 和项目级配置",
|
|
303
|
+
" kcode repair 清理旧 KCode package 路径并刷新项目上下文",
|
|
207
304
|
" kcode version 显示 KCode、随包 Pi CLI 和 Node 版本",
|
|
208
305
|
" kcode start 初始化项目配置后启动 KCode 工作环境",
|
|
209
306
|
].join("\n");
|
|
@@ -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) {
|
package/docs/DEVELOPMENT.md
CHANGED
|
@@ -35,6 +35,7 @@ npm run smoke:build-debug
|
|
|
35
35
|
npm run smoke:sdk-signature
|
|
36
36
|
npm run smoke:package
|
|
37
37
|
npm run smoke:kcode-cli
|
|
38
|
+
npm run release:check
|
|
38
39
|
```
|
|
39
40
|
|
|
40
41
|
这些 smoke 分别验证:
|
|
@@ -107,11 +108,7 @@ npm run build:cli
|
|
|
107
108
|
发布检查:
|
|
108
109
|
|
|
109
110
|
```powershell
|
|
110
|
-
npm run check
|
|
111
|
-
npm run build:cli
|
|
112
|
-
npm run smoke:package
|
|
113
|
-
npm run smoke:kcode-cli
|
|
114
|
-
npm pack --dry-run
|
|
111
|
+
npm run release:check
|
|
115
112
|
```
|
|
116
113
|
|
|
117
114
|
发布:
|