kcode-pi 0.1.20 → 0.1.24

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.
@@ -0,0 +1,209 @@
1
+ # KCode 用户指南
2
+
3
+ 本文说明 KCode 的安装、初始化、启动、模型配置和升级。Harness 阶段细节见 [Harness 工作流](HARNESS_WORKFLOW.md),所有命令和工具参数见 [命令参考](COMMAND_REFERENCE.md)。
4
+
5
+ ## 安装
6
+
7
+ 环境要求:
8
+
9
+ - Node.js `>=22.19.0`
10
+ - npm
11
+ - Windows 推荐使用 Windows Terminal
12
+ - 不需要安装 Python。KCode 随包工具使用 Node/TypeScript 实现;只有业务项目或外部脚本明确依赖 Python 时才需要另行安装。
13
+
14
+ 全局安装:
15
+
16
+ ```powershell
17
+ npm install -g kcode-pi
18
+ ```
19
+
20
+ 安装后使用全局命令:
21
+
22
+ ```powershell
23
+ kcode
24
+ ```
25
+
26
+ ## 初始化业务项目
27
+
28
+ 先在终端进入你的实际业务项目根目录,不是 KCode 源码目录。
29
+
30
+ 初始化项目级配置:
31
+
32
+ ```powershell
33
+ kcode init
34
+ ```
35
+
36
+ `init` 会登记 KCode package,并生成项目常驻上下文:
37
+
38
+ ```text
39
+ .pi/settings.json
40
+ .pi/kd/PROJECT_CONTEXT.md
41
+ ```
42
+
43
+ 项目结构变化后刷新上下文:
44
+
45
+ ```powershell
46
+ kcode context --refresh
47
+ ```
48
+
49
+ 检查环境:
50
+
51
+ ```powershell
52
+ kcode doctor
53
+ kcode doctor --deep
54
+ ```
55
+
56
+ 修复项目级配置:
57
+
58
+ ```powershell
59
+ kcode repair
60
+ ```
61
+
62
+ 查看版本:
63
+
64
+ ```powershell
65
+ kcode version
66
+ ```
67
+
68
+ 完整终端命令说明见 [命令参考](COMMAND_REFERENCE.md#终端命令)。
69
+
70
+ ## 启动 KCode
71
+
72
+ ```powershell
73
+ kcode start
74
+ ```
75
+
76
+ `kcode start` 会先确保 `.pi/settings.json` 已登记当前安装的 KCode package,然后启动随包 Pi CLI。
77
+
78
+ `start` 后面的参数会原样透传给 Pi CLI:
79
+
80
+ ```powershell
81
+ kcode start --provider openai --model gpt-4o
82
+ ```
83
+
84
+ ## 配置模型
85
+
86
+ 首次启动 Pi 时,如果看到:
87
+
88
+ ```text
89
+ Warning: No models available.
90
+ ```
91
+
92
+ 说明还没有配置模型供应商。进入 `kcode start` 后输入:
93
+
94
+ ```text
95
+ /login
96
+ ```
97
+
98
+ 选择供应商并登录或填写 API Key。常见选择包括:
99
+
100
+ ```text
101
+ ChatGPT Plus/Pro (Codex)
102
+ Claude Pro/Max
103
+ GitHub Copilot
104
+ OpenAI
105
+ Anthropic
106
+ DeepSeek
107
+ Gemini
108
+ ```
109
+
110
+ 也可以在 PowerShell 中设置环境变量后再启动:
111
+
112
+ ```powershell
113
+ $env:OPENAI_API_KEY="sk-..."
114
+ kcode start
115
+ ```
116
+
117
+ 登录或配置完成后,在 Pi 中选择模型:
118
+
119
+ ```text
120
+ /model
121
+ ```
122
+
123
+ KCode 在 Pi 内注册的 `/kd-*` 命令见 [命令参考](COMMAND_REFERENCE.md#pi-内命令)。
124
+
125
+ ## 自定义模型供应商
126
+
127
+ 如果你的模型服务是企业网关、代理服务、Ollama、LM Studio、vLLM,或其他 OpenAI-compatible endpoint,不需要改 KCode。Pi 原生支持通过用户级配置文件添加自定义供应商:
128
+
129
+ ```powershell
130
+ notepad $env:USERPROFILE\.pi\agent\models.json
131
+ ```
132
+
133
+ 写入或合并:
134
+
135
+ ```json
136
+ {
137
+ "providers": {
138
+ "corp-ai": {
139
+ "baseUrl": "https://ai.example.com/v1",
140
+ "api": "openai-completions",
141
+ "apiKey": "$CORP_AI_API_KEY",
142
+ "compat": {
143
+ "supportsDeveloperRole": false,
144
+ "supportsReasoningEffort": false
145
+ },
146
+ "models": [
147
+ {
148
+ "id": "corp-coder",
149
+ "name": "Corp Coder",
150
+ "reasoning": false,
151
+ "input": ["text"],
152
+ "contextWindow": 128000,
153
+ "maxTokens": 16384,
154
+ "cost": {
155
+ "input": 0,
156
+ "output": 0,
157
+ "cacheRead": 0,
158
+ "cacheWrite": 0
159
+ }
160
+ }
161
+ ]
162
+ }
163
+ }
164
+ }
165
+ ```
166
+
167
+ 再设置 API Key 并启动:
168
+
169
+ ```powershell
170
+ $env:CORP_AI_API_KEY="sk-..."
171
+ kcode start
172
+ ```
173
+
174
+ 也可以直接指定:
175
+
176
+ ```powershell
177
+ kcode start --provider corp-ai --model corp-coder
178
+ ```
179
+
180
+ ## 升级
181
+
182
+ 查看当前安装版本:
183
+
184
+ ```powershell
185
+ kcode version
186
+ npm ls -g kcode-pi --depth=0
187
+ ```
188
+
189
+ 查看 npm 最新版本:
190
+
191
+ ```powershell
192
+ npm view kcode-pi version
193
+ ```
194
+
195
+ 升级:
196
+
197
+ ```powershell
198
+ npm install -g kcode-pi@latest
199
+ kcode version
200
+ ```
201
+
202
+ 升级后建议在业务项目根目录执行:
203
+
204
+ ```powershell
205
+ kcode init
206
+ kcode doctor --deep
207
+ ```
208
+
209
+ 如果升级失败或仍加载旧版本,见 [故障排查](TROUBLESHOOTING.md)。
@@ -22,11 +22,8 @@ import { readArtifact } from "../src/harness/artifacts.ts";
22
22
  import { flagshipWriteBlockReason, isSourceLikePath, planWriteBlockReason } from "../src/harness/path-policy.ts";
23
23
  import { sdkSignatureProductionWriteBlockReason } from "../src/harness/sdk-policy.ts";
24
24
  import { tddProductionWriteBlockReason } from "../src/harness/tdd-policy.ts";
25
- import { readProjectContext } from "../src/context/project-context.ts";
26
25
  import { windowsPathHint } from "../src/platform/path.ts";
27
-
28
- const KINGDEE_INTENT_PATTERN =
29
- /金蝶|苍穹|星瀚|星空|旗舰|企业版|单据|表单|列表|插件|操作插件|校验器|反写|转换|工作流|基础资料|动态对象|DynamicObject|BOS|Cosmic|IronPython|Python\s*插件|py\s*插件|kd_|KSQL/i;
26
+ import { workflowPromptForRun } from "../src/harness/prompt.ts";
30
27
 
31
28
  function requireRun(cwd: string): ReturnType<typeof readActiveRun> {
32
29
  return readActiveRun(cwd);
@@ -48,7 +45,7 @@ function parseArtifactArgs(args: string, currentPhase: KdPhase): { phase: KdPhas
48
45
  }
49
46
 
50
47
  function parseStartArgs(args: string): { goal: string; product?: string; version?: string } {
51
- const tokens = args.trim().split(/\s+/).filter(Boolean);
48
+ const tokens = tokenizeArgs(args);
52
49
  const goal: string[] = [];
53
50
  let product: string | undefined;
54
51
  let version: string | undefined;
@@ -66,7 +63,19 @@ function parseStartArgs(args: string): { goal: string; product?: string; version
66
63
  goal.push(token);
67
64
  }
68
65
 
69
- return { goal: goal.join(" "), product, version };
66
+ const goalText = goal.join(" ");
67
+ return { goal: goalText, product, version };
68
+ }
69
+
70
+ function tokenizeArgs(args: string): string[] {
71
+ const tokens: string[] = [];
72
+ const pattern = /"([^"]*)"|'([^']*)'|(\S+)/g;
73
+ let match: RegExpExecArray | null;
74
+ while ((match = pattern.exec(args)) !== null) {
75
+ const token = match[1] ?? match[2] ?? match[3];
76
+ if (token) tokens.push(token);
77
+ }
78
+ return tokens;
70
79
  }
71
80
 
72
81
  function parseProductArgs(args: string): { product: string; version?: string } | undefined {
@@ -87,7 +96,7 @@ function parseRiskArgs(args: string): { risk: KdRisk; reason: string } | undefin
87
96
 
88
97
  function shouldStartHarnessFromInput(text: string): boolean {
89
98
  if (!text.trim() || text.trim().startsWith("/")) return false;
90
- return KINGDEE_INTENT_PATTERN.test(text);
99
+ return true;
91
100
  }
92
101
 
93
102
  function sendWorkflowPrompt(pi: ExtensionAPI, ctx: ExtensionContext, run: NonNullable<ReturnType<typeof readActiveRun>>, userText: string): void {
@@ -100,70 +109,6 @@ function sendWorkflowPrompt(pi: ExtensionAPI, ctx: ExtensionContext, run: NonNul
100
109
  if (ctx.hasUI) ctx.ui.notify("KCode 工作流消息已排队。", "info");
101
110
  }
102
111
 
103
- function workflowPromptForRun(cwd: string, run: NonNullable<ReturnType<typeof readActiveRun>>, userText: string): string {
104
- const status = formatStatus(cwd, run);
105
- const memory = workflowMemoryForRun(cwd, run);
106
- const phaseGuidance: Record<KdPhase, string> = {
107
- discuss:
108
- "当前处于 discuss。先使用 kd-discuss 梳理需求、产品版本、插件类型、目标单据/表单、生命周期、边界和开放问题;不要生成 demo,不要编辑产品代码。",
109
- spec:
110
- "当前处于 spec。先使用 kd-spec 明确验收标准、生命周期、字段/元数据/API 假设和风险;不要编辑产品代码。",
111
- plan:
112
- "当前处于 plan。先使用 kd-plan 检查当前项目结构,写明实际目标路径、要检查和要修改的文件、Kingdee 查证项、验证命令和回滚说明;不要编辑产品代码。",
113
- execute:
114
- "当前处于 execute。只能实现 PLAN.md 中批准的内容。先读取 PLAN.md 和实际项目文件,遵循既有结构写真实可用代码;不要写 demo/sample/scaffold。",
115
- verify:
116
- "当前处于 verify。先使用 kd-verify 收集验证证据,不要继续扩大代码改动。",
117
- ship:
118
- "当前处于 ship。整理发布摘要、验证证据、风险和后续事项,不要继续扩大代码改动。",
119
- };
120
-
121
- return [
122
- "用户输入:",
123
- userText,
124
- "",
125
- "KCode 项目常驻上下文:",
126
- readProjectContext(cwd) ?? "未生成。请在终端运行 `kcode context --refresh` 后继续;在生成前不要猜测项目目录。",
127
- "",
128
- "KCode Harness 状态:",
129
- status,
130
- "",
131
- "KCode 本次工作流本地文档:",
132
- memory,
133
- "",
134
- `当前 active run 只属于这个功能点:${run.goal ?? run.id}。如果用户提出的是另一个功能点或无关新需求,必须停止沿用当前阶段,要求用户运行 /kd-start <新需求> 创建新 run,或 /kd-switch <run-id> 切换已有 run。`,
135
- "需要用户确认时,kd_question 一次只能问一个当前最阻塞的问题;不要把 FormId、触发时机、库存条件、弹窗内容、插件位置等打包成清单。选项最多 3 个;交互模式下会弹出选择/输入对话并自动记录答案。",
136
- "",
137
- phaseGuidance[run.phase],
138
- "必须先理解当前业务项目已有目录、模块、包名、基类和本地封装,再决定文件位置和实现方式。",
139
- "禁止凭记忆、模型知识或随包知识库直接编写 SDK 方法调用。Java/C# 代码中出现的 SDK 类、方法、构造器、枚举和属性,必须来自 kd_sdk_signature 对当前项目 jar/dll 的成功结果、项目构建输出或官方元数据证据。",
140
- "kd_search、kd_cosmic_api 和随包知识只能用于找线索;没有 evidence/sdk-signature.md 或明确构建证据时,不得进入 execute,也不得写生产源码。",
141
- "路径规则:在 Windows 工作区内,优先使用项目相对路径;如需绝对路径必须使用 `D:\\...` 这类 Windows 路径,禁止把路径改写成 `/mnt/d/...`、`/d/...` 等 WSL/MSYS 风格路径。",
142
- "execute 阶段只能写 PLAN.md 明确列出的源码文件;如果目标文件不在计划内,必须先回到 plan 更新 PLAN.md。",
143
- "写生产源码前必须先有红灯证据 evidence/tdd-red.md;Java/C# 还必须有 SDK 签名证据 evidence/sdk-signature.md。红绿证据可以是 kd_sdk_signature 本地 SDK 签名、API/基类/方法签名、元数据、编译、既有测试框架或外部接口最小验证,不要为了测试引入额外 jar。",
144
- "语法/编译验证必须使用真实项目构建命令:Java/Cosmic/苍穹/星空旗舰版使用当前项目 Gradle 命令,例如 `./gradlew build`、`.\\gradlew.bat build` 或 `:模块:build`;C#/企业版使用 `dotnet build` 或 `dotnet build <.sln/.csproj>`。",
145
- "不要写“Kingdee IDE 中编译”作为验证方式或绿灯证据;命令无法运行时,记录真实阻塞原因和残余风险,不能标记为通过。",
146
- "如果门禁提示 evidence 内容无效,不要通过改写结论、补关键词或反复读取文件来过关;必须重新运行 PLAN.md 中声明的真实验证命令,并记录命令、Exit、STDOUT/STDERR 或工具输出。",
147
- ].join("\n");
148
- }
149
-
150
- function workflowMemoryForRun(cwd: string, run: NonNullable<ReturnType<typeof readActiveRun>>): string {
151
- const phases = PHASE_ORDER.slice(0, PHASE_ORDER.indexOf(run.phase) + 1);
152
- return phases
153
- .map((phase) => {
154
- const content = readArtifact(cwd, run, phase);
155
- if (!content) return undefined;
156
- return [`## ${phase}`, trimForPrompt(content, 6000)].join("\n");
157
- })
158
- .filter(Boolean)
159
- .join("\n\n") || "暂无阶段文档。";
160
- }
161
-
162
- function trimForPrompt(content: string, maxLength: number): string {
163
- if (content.length <= maxLength) return content;
164
- return `${content.slice(0, maxLength)}\n\n[...文档过长,已截断;如需完整内容必须读取本地文件...]`;
165
- }
166
-
167
112
  function codeWriteBlockReason(cwd: string, path: string | undefined): string | undefined {
168
113
  if (!path || !isSourceLikePath(path)) return undefined;
169
114
 
@@ -202,11 +147,11 @@ const kdQuestionTool = defineTool({
202
147
  name: "kd_question",
203
148
  label: "KD 问题",
204
149
  description:
205
- "创建、回答或列出金蝶 Harness 结构化问题。每次只能问一个最阻塞的短问题,不要批量列清单。",
150
+ "创建、回答或列出金蝶 Harness 结构化问题。每次只记录一个最阻塞的短问题。",
206
151
  parameters: Type.Object({
207
152
  action: Type.Optional(Type.String({ description: "操作类型:ask、answer 或 list,默认 ask。" })),
208
153
  id: Type.Optional(Type.String({ description: "回答问题时的问题编号,例如 Q-001。" })),
209
- question: Type.Optional(Type.String({ description: "提问内容。只能是一个短问题,不要写编号清单或多个问题。" })),
154
+ question: Type.Optional(Type.String({ description: "提问内容。使用一个短问题。" })),
210
155
  answer: Type.Optional(Type.String({ description: "用户答案,action=answer 时使用。" })),
211
156
  reason: Type.Optional(Type.String({ description: "说明为什么这个问题会阻塞当前阶段。" })),
212
157
  choices: Type.Optional(Type.Array(Type.String(), { description: "可选项,最多 3 个简短选项。" })),
@@ -318,7 +263,7 @@ export default function (pi: ExtensionAPI) {
318
263
  [
319
264
  `发现未完成 KCode run:${run.goal ?? run.id}`,
320
265
  `阶段:${run.phase},产品:${run.profile?.product ?? run.product ?? "unknown"}`,
321
- "输入 /kd-resume 可接续;输入 /kd-runs 查看其他功能点。",
266
+ "输入 /kd-resume 可接续;输入 /kd-runs 查看其他需求或需求组。",
322
267
  ].join("\n"),
323
268
  "info",
324
269
  );
@@ -333,7 +278,7 @@ export default function (pi: ExtensionAPI) {
333
278
  if (ctx.hasUI) {
334
279
  ctx.ui.notify(`已启动 Kingdee Harness run:${run.id}(${run.profile?.product}/${run.profile?.techStack})`, "info");
335
280
  if (run.profile?.product === "unknown") {
336
- ctx.ui.notify("产品画像未识别。下一步先执行 /kd-product <flagship|cosmic|xinghan|cangqiong|enterprise>。", "warning");
281
+ ctx.ui.notify("产品画像未识别。下一步先执行 /kd-product <flagship|xinghan|cangqiong|enterprise>。", "warning");
337
282
  }
338
283
  }
339
284
  }
@@ -351,7 +296,7 @@ export default function (pi: ExtensionAPI) {
351
296
  const path = typeof input.path === "string" ? input.path : undefined;
352
297
  const hint = path ? windowsPathHint(path) : undefined;
353
298
  if (hint && ["read", "write", "edit"].includes(event.toolName)) {
354
- const reason = `当前是 Windows 工作区,不能使用 WSL/MSYS 路径 ${path}。下一步:改用项目相对路径;如果必须使用绝对路径,使用 Windows 路径 ${hint};不要再尝试 /mnt/d 或 /d 路径。`;
299
+ const reason = `当前是 Windows 工作区,路径 ${path} 不是本项目使用的路径形式。下一步:改用项目相对路径;如果必须使用绝对路径,使用 Windows 路径 ${hint}。`;
355
300
  if (ctx.hasUI) ctx.ui.notify(reason, "warning");
356
301
  return { block: true, reason };
357
302
  }
@@ -394,19 +339,19 @@ export default function (pi: ExtensionAPI) {
394
339
  });
395
340
 
396
341
  pi.registerCommand("kd-start", {
397
- description: "启动一个 Kingdee Harness run:/kd-start [--product 产品] [--version 版本] <需求>",
342
+ description: "启动一个 Kingdee Harness run:/kd-start [--product 产品] [--version 版本] <需求或需求组>",
398
343
  handler: async (args, ctx) => {
399
344
  const parsed = parseStartArgs(args);
400
345
  const goal = parsed.goal;
401
346
  if (!goal) {
402
- ctx.ui.notify("用法:/kd-start [--product 产品] [--version 版本] <需求>", "error");
347
+ ctx.ui.notify("用法:/kd-start [--product 产品] [--version 版本] <需求或需求组>", "error");
403
348
  return;
404
349
  }
405
350
 
406
351
  const run = createActiveRun(ctx.cwd, goal, parsed.product, parsed.version);
407
352
  ctx.ui.notify(`已启动 Kingdee Harness run:${run.id}(${run.profile?.product}/${run.profile?.techStack})`, "info");
408
353
  if (run.profile?.product === "unknown") {
409
- ctx.ui.notify("产品画像未识别。下一步先执行 /kd-product <flagship|cosmic|xinghan|cangqiong|enterprise>。", "warning");
354
+ ctx.ui.notify("产品画像未识别。下一步先执行 /kd-product <flagship|xinghan|cangqiong|enterprise>。", "warning");
410
355
  }
411
356
  sendWorkflowPrompt(pi, ctx, run, `继续 KCode Harness run ${run.id}:${goal}`);
412
357
  },
@@ -461,12 +406,12 @@ export default function (pi: ExtensionAPI) {
461
406
  }
462
407
 
463
408
  const finished = finishActiveRun(ctx.cwd, run);
464
- ctx.ui.notify(`已完成 Kingdee Harness run:${finished.id}。下一个功能点请使用 /kd-start <需求>。`, "info");
409
+ ctx.ui.notify(`已完成 Kingdee Harness run:${finished.id}。下一个需求或需求组请使用 /kd-start <需求>。`, "info");
465
410
  },
466
411
  });
467
412
 
468
413
  pi.registerCommand("kd-product", {
469
- description: "设置当前金蝶产品画像:/kd-product <flagship|cosmic|xinghan|cangqiong|enterprise> [--version 版本]",
414
+ description: "设置当前金蝶产品画像:/kd-product <flagship|xinghan|cangqiong|enterprise> [--version 版本]",
470
415
  handler: async (args, ctx) => {
471
416
  const run = requireRun(ctx.cwd);
472
417
  if (!run) {
@@ -476,7 +421,7 @@ export default function (pi: ExtensionAPI) {
476
421
 
477
422
  const parsed = parseProductArgs(args);
478
423
  if (!parsed) {
479
- ctx.ui.notify("用法:/kd-product <flagship|cosmic|xinghan|cangqiong|enterprise> [--version 版本]", "error");
424
+ ctx.ui.notify("用法:/kd-product <flagship|xinghan|cangqiong|enterprise> [--version 版本]", "error");
480
425
  return;
481
426
  }
482
427
 
@@ -545,7 +490,7 @@ export default function (pi: ExtensionAPI) {
545
490
  }
546
491
 
547
492
  if (parsed.content && readArtifact(ctx.cwd, run, parsed.phase) !== undefined && !parsed.replace) {
548
- ctx.ui.notify(`拒绝覆盖 ${parsed.phase} 阶段文档。若确认要整体替换,请追加 --replace;追加内容应让 Agent 更新具体章节。`, "warning");
493
+ ctx.ui.notify(`拒绝覆盖 ${parsed.phase} 阶段文档。若确认要整体替换,请追加 --replace;追加内容应让 KCode 更新具体章节。`, "warning");
549
494
  return;
550
495
  }
551
496
 
@@ -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 "请先提供 Cosmic 家族产品:cangqiong、xinghan、flagshipcosmic。";
80
+ if (profile.product === "unknown") return "请先提供支持 Cosmic 平台能力的产品:cangqiong、xinghan 或 flagship。";
81
81
  return `当前产品 ${profile.product} 使用 ${profile.platform}/${profile.techStack},不适用 Cosmic 官方能力。`;
82
82
  }
83
83
 
@@ -109,7 +109,7 @@ const kdSearchTool = defineTool({
109
109
  description: "搜索 KCode 随包金蝶知识库,包括 SDK、插件生命周期、代码模式和常见实现建议。",
110
110
  parameters: Type.Object({
111
111
  query: Type.String({ description: "要搜索的关键词、API、类名、表名或生命周期术语。" }),
112
- product: Type.Optional(Type.String({ description: "金蝶产品:flagship、cosmic、xinghan、cangqiong 或 enterprise。" })),
112
+ product: Type.Optional(Type.String({ description: "金蝶产品:flagship、xinghan、cangqiong 或 enterprise。" })),
113
113
  edition: Type.Optional(Type.String({ description: "旧参数,等同于 product。优先使用 product。" })),
114
114
  limit: Type.Optional(Type.Number({ description: "最大结果数,默认 5。" })),
115
115
  }),
@@ -120,7 +120,7 @@ const kdSearchTool = defineTool({
120
120
  if (!scopes) {
121
121
  const guidance =
122
122
  profile.product === "unknown"
123
- ? "请先提供 product,例如 flagship、enterprise、cosmic、xinghan 或 cangqiong。"
123
+ ? "请先提供 product,例如 flagship、enterprise、xinghan 或 cangqiong。"
124
124
  : "当前产品画像未配置可搜索知识范围。";
125
125
  return {
126
126
  content: [
@@ -152,7 +152,7 @@ const kdTableTool = defineTool({
152
152
  description: "按表名查询 KCode 随包金蝶表结构,查询结果受产品画像约束。",
153
153
  parameters: Type.Object({
154
154
  table: Type.String({ description: "表名,例如 T_PUR_POORDER。" }),
155
- product: Type.Optional(Type.String({ description: "金蝶产品:flagship、cosmic、xinghan、cangqiong 或 enterprise。" })),
155
+ product: Type.Optional(Type.String({ description: "金蝶产品:flagship、xinghan、cangqiong 或 enterprise。" })),
156
156
  edition: Type.Optional(Type.String({ description: "旧参数,等同于 product。优先使用 product。" })),
157
157
  }),
158
158
 
@@ -236,7 +236,7 @@ const kdCosmicConfigTool = defineTool({
236
236
  label: "KD Cosmic 配置",
237
237
  description: "运行 Cosmic 家族金蝶产品的官方能力配置预检查。",
238
238
  parameters: Type.Object({
239
- product: Type.String({ description: "Cosmic 家族产品:cangqiong、xinghan、flagshipcosmic。" }),
239
+ product: Type.String({ description: "支持 Cosmic 平台能力的产品:cangqiong、xinghan 或 flagship。" }),
240
240
  config: Type.Optional(Type.String({ description: "可选 ok-cosmic.json 路径。默认按当前工作目录解析。" })),
241
241
  dryRun: Type.Optional(Type.Boolean({ description: "只返回命令,不实际执行。" })),
242
242
  }),
@@ -254,7 +254,7 @@ const kdCosmicMetadataTool = defineTool({
254
254
  label: "KD Cosmic 元数据",
255
255
  description: "查询官方 Cosmic 表单/单据元数据,包括字段、枚举值、操作和 SQL 表信息。",
256
256
  parameters: Type.Object({
257
- product: Type.String({ description: "Cosmic 家族产品:cangqiong、xinghan、flagshipcosmic。" }),
257
+ product: Type.String({ description: "支持 Cosmic 平台能力的产品:cangqiong、xinghan 或 flagship。" }),
258
258
  form: Type.String({ description: "Form ID、单据 ID 或中文单据名;多个目标可用逗号分隔。" }),
259
259
  config: Type.Optional(Type.String({ description: "可选 ok-cosmic.json 路径。" })),
260
260
  fuzzy: Type.Optional(Type.String({ description: "可选字段关键词,用空格或逗号分隔。" })),
@@ -278,7 +278,7 @@ const kdCosmicApiTool = defineTool({
278
278
  label: "KD Cosmic API",
279
279
  description: "查询随包 Cosmic API 知识,获取类和方法线索;最终签名事实应以 kd_sdk_signature 或项目构建输出为准。",
280
280
  parameters: Type.Object({
281
- product: Type.String({ description: "Cosmic 家族产品:cangqiong、xinghan、flagshipcosmic。" }),
281
+ product: Type.String({ description: "支持 Cosmic 平台能力的产品:cangqiong、xinghan 或 flagship。" }),
282
282
  mode: Type.String({ description: "查询模式:search、search-method 或 detail。" }),
283
283
  query: Type.String({ description: "类名、方法名或完整限定类名。" }),
284
284
  config: Type.Optional(Type.String({ description: "可选 ok-cosmic.json 路径。" })),
@@ -346,7 +346,7 @@ const kdKsqlLintTool = defineTool({
346
346
  label: "KD KSQL 检查",
347
347
  description: "对生成的 KSQL/SQL 文件运行官方 ok-ksql lint 检查。",
348
348
  parameters: Type.Object({
349
- product: Type.String({ description: "Cosmic 家族产品:cangqiong、xinghan、flagshipcosmic。" }),
349
+ product: Type.String({ description: "支持 Cosmic 平台能力的产品:cangqiong、xinghan 或 flagship。" }),
350
350
  path: Type.String({ description: "SQL/KSQL 文件路径,可为工作区相对路径或绝对路径。" }),
351
351
  dryRun: Type.Optional(Type.Boolean({ description: "只返回命令,不实际执行。" })),
352
352
  }),
@@ -364,7 +364,7 @@ const kdBuildTool = defineTool({
364
364
  label: "KD 构建",
365
365
  description: "按产品画像运行或预览金蝶构建命令,支持 Cosmic Java 和企业版 C# 项目。",
366
366
  parameters: Type.Object({
367
- product: Type.String({ description: "金蝶产品:cangqiong、xinghan、flagship、cosmic 或 enterprise。" }),
367
+ product: Type.String({ description: "金蝶产品:cangqiong、xinghan、flagship 或 enterprise。" }),
368
368
  target: Type.Optional(Type.String({ description: "Java 可提供 Gradle task;C# 可提供 .sln/.csproj 路径。" })),
369
369
  dryRun: Type.Optional(Type.Boolean({ description: "只返回构建命令,不实际执行。" })),
370
370
  }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kcode-pi",
3
- "version": "0.1.20",
3
+ "version": "0.1.24",
4
4
  "description": "面向金蝶开发的 Pi Coding Agent 启动器、工具包和 Harness 工作流",
5
5
  "type": "module",
6
6
  "private": false,
@@ -63,7 +63,7 @@
63
63
  "smoke:build-debug": "tsx scripts/smoke-build-debug.ts",
64
64
  "smoke:sdk-signature": "tsx scripts/smoke-sdk-signature.ts",
65
65
  "smoke:package": "tsx scripts/smoke-package.ts",
66
- "smoke:kcode-cli": "tsx scripts/smoke-kcode-cli.ts",
66
+ "smoke:kcode-command": "tsx scripts/smoke-kcode-command.ts",
67
67
  "release:check": "tsx scripts/release-check.ts",
68
68
  "kcode": "tsx scripts/kcode.ts",
69
69
  "prepack": "npm run build:cli && npm run smoke:package"
@@ -8,4 +8,9 @@ description: 开始或继续金蝶 Harness 工作流的需求讨论阶段。
8
8
 
9
9
  {{args}}
10
10
 
11
- 请把业务目标、金蝶产品/版本、技术栈、插件类型、目标单据/表单/实体、非目标范围和待确认问题记录到 `CONTEXT.md`。
11
+ 请先读取并理解需求来源,再自行判断这是单需求还是需求组。
12
+
13
+ - 单需求:记录业务目标、可判断的产品/版本、技术栈、目标对象、非目标范围和待确认问题。
14
+ - 需求组:从原始文档抽取需求条目、验收标准、优先级、依赖、批次、共同约束和待确认问题。
15
+
16
+ 不要因为正文里出现产品词就直接落产品画像;只有用户显式指定、文档证据充分,或进入具体产品实现前确认后,才写成已确认产品。
@@ -4,9 +4,9 @@ description: 在 Harness 门禁约束下执行当前金蝶实施计划。
4
4
 
5
5
  使用 `kd-execute` skill。
6
6
 
7
- 编辑代码前,先使用 `kd_plan_status` 检查当前 run。如果缺少 `PLAN.md`、`evidence/sdk-signature.md` 或门禁被阻塞,必须停止并说明缺少的文档或证据。通过后只实现 `PLAN.md` 批准的内容,并更新 `EXECUTION.md`。禁止凭记忆、模型知识或随包知识库猜 SDK 方法签名。
7
+ 先检查当前 run 和门禁。通过后只实现 `PLAN.md` 批准的内容,更新 `EXECUTION.md`,并按计划记录红绿 evidence。
8
8
 
9
- 实现后要按计划运行真实构建检查语法问题:Java 使用当前项目 Gradle 命令,例如 `.\gradlew.bat build` 或 `.\gradlew.bat :模块:build`;C# 使用 `dotnet build` 或 `dotnet build <.sln/.csproj>`。不能写“Kingdee IDE 中编译”作为验证结果;命令未运行就不能记录为绿灯证据。
9
+ 实现后运行计划中的验证命令;命令无法运行时记录阻塞原因和残余风险。
10
10
 
11
11
  用户补充说明:
12
12
 
@@ -4,13 +4,9 @@ description: 为当前金蝶 Harness run 编写实施计划。
4
4
 
5
5
  使用 `kd-plan` skill。
6
6
 
7
- 读取 `CONTEXT.md` 和 `SPEC.md`,编写或更新 `PLAN.md`。必须包含已检查的项目结构、需要查看的文件、预计修改的真实路径、必须查证的金蝶 API/元数据、SDK 签名证据、验证命令和回滚说明。Java/C# SDK 方法签名必须来自 `kd_sdk_signature` 当前项目 jar/dll、项目构建输出或官方元数据,不能凭记忆猜。
7
+ 读取 `CONTEXT.md` 和 `SPEC.md`,编写或更新 `PLAN.md`。重点写清:项目结构、目标路径、允许修改文件、SDK/元数据查证、验证命令和回滚说明。
8
8
 
9
- 验证命令必须贴近真实项目:
10
-
11
- - Java / Cosmic / 苍穹 / 星空旗舰版:优先使用当前项目 Gradle 构建做语法和编译检查,例如 `./gradlew build`、`./gradlew :模块:build` 或 Windows 下的 `.\gradlew.bat build`。
12
- - C# / 企业版:使用 `dotnet build` 或 `dotnet build <.sln/.csproj>` 做语法和编译检查。
13
- - 不要写“Kingdee IDE 中编译”。如果当前机器缺少依赖导致命令无法运行,要记录真实阻塞原因,不能把未执行的编译当作绿灯证据。
9
+ 验证命令按产品选择:Cosmic Java 用当前项目 Gradle;企业版 C# 用 `dotnet build`。命令无法运行时记录阻塞原因和应运行的具体命令。
14
10
 
15
11
  用户补充说明:
16
12
 
@@ -4,13 +4,7 @@ description: 验证当前金蝶实现并收集证据。
4
4
 
5
5
  使用 `kd-verify` skill。
6
6
 
7
- 执行计划中的验证命令,收集证据,运行可用检查,并更新 `VERIFY.md`。如果某项验证无法运行,记录具体阻塞原因和残余风险。
8
-
9
- 验证优先使用真实构建命令检查语法和编译:
10
-
11
- - Java / Cosmic / 苍穹 / 星空旗舰版:运行当前项目 Gradle 命令,例如 `.\gradlew.bat build`、`.\gradlew.bat :模块:build` 或同等 Gradle task。
12
- - C# / 企业版:运行 `dotnet build`、`dotnet build <.sln>` 或 `dotnet build <.csproj>`。
13
- - 绿灯证据必须包含实际命令、`Exit: 0` 和输出摘要。不能用“Kingdee IDE 中编译”“需在开发环境验证”替代真实证据。
7
+ 执行 `PLAN.md` 中的验证命令,收集 evidence,并更新 `VERIFY.md`。成功证据记录命令、`Exit: 0` 和输出摘要;命令无法运行时记录阻塞原因和残余风险。
14
8
 
15
9
  用户补充说明:
16
10
 
@@ -1,13 +1,12 @@
1
1
  ---
2
2
  name: kd-cosmic-dev
3
- description: 金蝶 Cosmic 体系 Java 插件开发技能,适用于苍穹、星瀚、星空旗舰版和共享 Cosmic 平台。处理表单、单据、列表、操作、转换、任务、工作流、OpenAPI、元数据、DynamicObject、附件、基础资料、SDK 方法签名等 Cosmic 体系开发时使用。
3
+ description: 金蝶苍穹/Cosmic 平台 Java 插件开发技能,适用于苍穹、星瀚和星空旗舰版。处理表单、单据、列表、操作、转换、任务、工作流、OpenAPI、元数据、DynamicObject、附件、基础资料、SDK 方法签名等平台能力开发时使用。
4
4
  ---
5
5
 
6
6
  # 金蝶 Cosmic 开发
7
7
 
8
- 当需要为 Cosmic 体系产品实现或修改 Java 代码时使用本技能:
8
+ 当需要为以下产品实现或修改 Java 代码时使用本技能:
9
9
 
10
- - `cosmic`
11
10
  - `cangqiong`
12
11
  - `xinghan`
13
12
  - `flagship`
@@ -19,7 +18,7 @@ description: 金蝶 Cosmic 体系 Java 插件开发技能,适用于苍穹、
19
18
  生成或修改代码前:
20
19
 
21
20
  - 先用 `kd_plan_status` 查看当前运行状态。
22
- - 确认产品画像属于 Cosmic 体系。
21
+ - 确认产品画像是 `cangqiong`、`xinghan` 或 `flagship`。
23
22
  - 执行阶段必须已有 `PLAN.md`。
24
23
  - Cosmic 代码生成前必须运行 `kd_cosmic_config`。如果配置检查失败,停止编码并说明缺失配置。
25
24
 
@@ -53,7 +52,7 @@ description: 金蝶 Cosmic 体系 Java 插件开发技能,适用于苍穹、
53
52
  4. 只有插件类型、生命周期方法、字段元数据和 API 签名都明确后,才生成或修改代码。
54
53
  - 遵循项目已有包名、基类、常量、日志风格和 helper 封装。
55
54
  - 星空旗舰版项目先检查当前目录结构,再选择真实目标路径。若存在 `code/`,跟随 `code/` 下既有组织;若不存在,跟随已发现的源码根或目标文件,不要在项目根目录新建 `src/main/java`。
56
- - 优先使用项目本地封装和已批准的 Cosmic helper,再考虑底层 BOS API。
55
+ - 优先使用项目本地封装和已批准的苍穹/Cosmic 平台 helper,再考虑底层 BOS API。
57
56
  - 事件处理器只做当前事件阶段该做的事。
58
57
 
59
58
  5. 验证结果。
@@ -64,7 +63,7 @@ description: 金蝶 Cosmic 体系 Java 插件开发技能,适用于苍穹、
64
63
  ## 硬性规则
65
64
 
66
65
  - 不臆造字段 key、表单 ID、操作名、枚举值、表名或 SDK 方法;本地 SDK 查不到且编译未验证时,不把知识库结果当作最终签名事实。
67
- - 不把 Enterprise C# 命名空间或生命周期假设用于 Cosmic Java。
66
+ - 不把 Enterprise C# 命名空间或生命周期假设用于苍穹/Cosmic 平台 Java。
68
67
  - 星空旗舰版不允许猜目录或写 demo/sample;如果无法判断真实代码位置,先询问或更新计划,不要直接创建新目录。
69
68
  - 不在数据绑定前的初始化阶段操作 UI 控件。
70
69
  - 不在平台期望修改入参数据实体的事务钩子里另起保存。
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: kd-cosmic-review
3
- description: 金蝶 Cosmic 体系 Java 插件和 KSQL 代码审查技能,按官方审查优先级检查代码质量、生命周期、事务、性能、安全、DataSet 泄漏、校验器/操作/表单/列表/转换插件和 KSQL 风险。适用于 Cosmic、苍穹、星瀚、星空旗舰版项目。
3
+ description: 金蝶苍穹/Cosmic 平台 Java 插件和 KSQL 代码审查技能,按官方审查优先级检查代码质量、生命周期、事务、性能、安全、DataSet 泄漏、校验器/操作/表单/列表/转换插件和 KSQL 风险。适用于苍穹、星瀚、星空旗舰版项目。
4
4
  ---
5
5
 
6
6
  # 金蝶 Cosmic 审查
7
7
 
8
- 本技能用于审查 Cosmic 体系 Java 或 KSQL 变更。除非用户明确要求修复,否则只做审查,不直接改代码。
8
+ 本技能用于审查苍穹/Cosmic 平台 Java 或 KSQL 变更。除非用户明确要求修复,否则只做审查,不直接改代码。
9
9
 
10
10
  不要把本技能用于 Enterprise C# 代码;Enterprise 使用通用金蝶检查流程。
11
11
 
@@ -79,7 +79,7 @@ POJO 或简单枚举场景可以简要说明后直接实现。
79
79
  写完测试后:
80
80
 
81
81
  - 使用 `kd_build` 或计划中的命令运行最窄可行 Gradle test 任务。
82
- - 如果本机缺少业务 jar 或本地配置导致 Gradle 不能运行,明确说明真实阻塞原因,并给出应该运行的 Gradle task;不要写“在 IDE 中运行”作为验证结论。
82
+ - 如果本机缺少业务 jar 或本地配置导致 Gradle 不能运行,明确说明真实阻塞原因,并给出应该运行的 Gradle task
83
83
  - 存在 harness run 时,把测试文件和验证结果写入 `.pi/kd/runs/<run-id>/EXECUTION.md`。
84
84
 
85
85
  ## 输出要求
@@ -24,5 +24,5 @@ Rules:
24
24
  - Before entering verify, rerun the same check and record passing output in `evidence/tdd-green.md`.
25
25
  - After implementation, run the planned real build command for syntax/compile validation when available: Java uses the project Gradle command such as `.\gradlew.bat build` or `.\gradlew.bat :module:build`; C# uses `dotnet build` or `dotnet build <.sln/.csproj>`.
26
26
  - Do not add JUnit, Mockito, NUnit, xUnit, or any extra test jar/framework only to satisfy the gate. Use existing approved project test infrastructure if it already exists.
27
- - Do not record "compile in Kingdee IDE" or "needs local development environment verification" as green evidence. If the command cannot run, record the blocker instead of marking verification passed.
27
+ - If the command cannot run, record the blocker instead of marking verification passed.
28
28
  - If implementation needs a plan change, update `PLAN.md` first.