feat(workflow): 增加大方向闭环审计
This commit is contained in:
parent
58062e2f44
commit
fe5fab3479
@ -1,6 +1,6 @@
|
||||
# KT Workflow MCP
|
||||
|
||||
`ktWorkflow` 是 KT 工作区的可复用 MCP 能力包,用 TypeScript 封装工具入参、项目别名和返回结构,用来把根目录 `AGENTS.md` 的硬规则、`SKILLS.md` 的工作流索引、`TASKS.md` 的上下文记录和 `docs/` 的详细流程变成可调用工具。当前版本:`0.6.1`。
|
||||
`ktWorkflow` 是 KT 工作区的可复用 MCP 能力包,用 TypeScript 封装工具入参、项目别名和返回结构,用来把根目录 `AGENTS.md` 的硬规则、`SKILLS.md` 的工作流索引、`TASKS.md` 的上下文记录和 `docs/` 的详细流程变成可调用工具。当前版本:`0.6.2`。
|
||||
|
||||
## 能力边界
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
- 生成验证建议:按后端、前端、样式、页面、部署、MCP 等变更类型给出轻量验证命令。
|
||||
- 固化改动后 review:验证计划和提交清单都会提醒执行 `kt_global_code_review` / `pnpm run global-review`。
|
||||
- 生成任务收尾包:把状态、验证计划、可选验证执行、全局 review 和历史清理收成一份结果。
|
||||
- 生成大方向完结闭环审计:确认开发目标、测试证据、问题记录、稳定解法和 ktWorkflow 升级是否齐备。
|
||||
- 生成页面测试用例:内置“先写用例、可视化证据、事不过三”的测试闭环。
|
||||
- 生成接口测试计划:接口改动后输出真实调用命令和统一返回结构断言。
|
||||
- 生成业务链路测试计划:固化 Admin 登录、博客 CRUD、QQBot 扫码/自动回复、更新登录 SSE、FFLogs 命令、系统日志可视化、Web/Playground 回跳。
|
||||
@ -31,6 +32,7 @@ cd D:/MyFiles/KT/mcp/ktWorkflow
|
||||
pnpm install
|
||||
pnpm run typecheck
|
||||
pnpm run self-test
|
||||
pnpm run workstream-closeout -- --title "发布闭环" --verification "Jenkins SUCCESS" --problem "无新卡点" --solution "无新增稳定解法"
|
||||
pnpm run cleanup-history -- --dry-run
|
||||
pnpm run admin-login -- --url http://127.0.0.1:5999/#/auth/login
|
||||
```
|
||||
@ -77,6 +79,7 @@ pnpm run admin-login -- --url http://127.0.0.1:5999/#/auth/login
|
||||
| `kt_risk_scan` | 扫描当前或传入变更文件的偏差风险 |
|
||||
| `kt_global_code_review` | 对 KT 全部子仓库做只读全局 CodeReview 扫描,默认仅深扫变更文件 |
|
||||
| `kt_finish_task` | 生成任务收尾包,可选执行验证和历史清理 |
|
||||
| `kt_workstream_closeout` | 生成大方向完结闭环审计,检查测试证据、问题记录、稳定解法和 ktWorkflow 升级 |
|
||||
| `kt_commit_plan` | 生成多仓库提交计划、建议 commit message 和检查项 |
|
||||
| `kt_push_plan` | 生成多仓库推送计划和远程异常提醒 |
|
||||
| `kt_business_test_plan` | 生成固化业务链路测试计划,包含 QQBot SSE、FFLogs 和系统日志 |
|
||||
@ -93,6 +96,7 @@ pnpm run admin-login -- --url http://127.0.0.1:5999/#/auth/login
|
||||
| --- | --- |
|
||||
| `pnpm run admin-login` | 使用可见 Edge 打开 Admin 登录页,填写账号密码,拖动滑块,保存登录态和截图。默认账号来自初始化数据 `admin/123456`,生产或个人账号用 `KT_ADMIN_USERNAME` / `KT_ADMIN_PASSWORD` 或 CLI 参数覆盖。 |
|
||||
| `pnpm run global-review` | 对 KT 全部子仓库做只读全局 CodeReview 扫描,默认仅对变更文件做内容深扫,输出 JSON 复审报告;确认误报时优先升级 `src/tools/review.ts`,不要把误报沉积到上下文。 |
|
||||
| `pnpm run workstream-closeout` | 生成大方向完结闭环审计;识别测试证据、问题记录、稳定解法和 ktWorkflow 升级缺口。 |
|
||||
|
||||
## 项目别名
|
||||
|
||||
@ -123,6 +127,7 @@ pnpm run admin-login -- --url http://127.0.0.1:5999/#/auth/login
|
||||
- 写代码前先调用 `kt_prepare_task`;只需要单项信息时再调用 `kt_read_context` 或 `kt_inspect_project`。`kt_read_context` 默认紧凑输出,只有确实需要完整 `TASKS.md` 时再传 `includeFullDocs=true`。
|
||||
- 多项目联动时先调用 `kt_inspect_all_projects`。
|
||||
- 要收尾时调用 `kt_finish_task`,默认只生成计划和 review;需要执行验证时显式传 `runValidation=true`。
|
||||
- 大方向结束前调用 `kt_workstream_closeout` 或 `pnpm run workstream-closeout`;如果识别到测试流、卡点、误报、清理、部署观测或命令模板,要先升级对应 ktWorkflow 规则再报告完成。
|
||||
- 文件改动完成并验证后调用 `kt_global_code_review`,或运行 `pnpm run global-review`;它只读扫描,不删除文件、不提交代码。`findings` 先判定真实风险或工具误报,真实风险修业务代码,误报修 `mcp/ktWorkflow/src/tools/review.ts` 并复跑。
|
||||
- 要提交或推送时先调用 `kt_commit_plan` / `kt_push_plan`,按仓库分组确认范围。
|
||||
- 要测真实业务链路时调用 `kt_business_test_plan`,选择 `admin-login`、`qqbot-auto-reply`、`qqbot-login-sse`、`fflogs-command`、`system-log-visualization` 等 flow。
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@kt/mcp-kt-workflow",
|
||||
"version": "0.6.1",
|
||||
"version": "0.6.2",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"description": "Reusable MCP workflow tools for the KT workspace.",
|
||||
@ -10,7 +10,8 @@
|
||||
"global-review": "node --import ./node_modules/tsx/dist/loader.mjs src/server.ts --global-review",
|
||||
"self-test": "node --import ./node_modules/tsx/dist/loader.mjs src/server.ts --self-test",
|
||||
"start": "node --import ./node_modules/tsx/dist/loader.mjs src/server.ts",
|
||||
"typecheck": "tsc --noEmit"
|
||||
"typecheck": "tsc --noEmit",
|
||||
"workstream-closeout": "node --import ./node_modules/tsx/dist/loader.mjs src/server.ts --workstream-closeout"
|
||||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "^1.20.0",
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import type { GlobalCodeReviewInput } from '../types.js';
|
||||
import type { GlobalCodeReviewInput, WorkstreamCloseoutInput, WorkstreamReusablePattern } from '../types.js';
|
||||
import { workstreamReusablePatternValues } from './constants.js';
|
||||
|
||||
function parseContentScanMode(argv: string[]): 'all' | 'changed' {
|
||||
if (argv.includes('--content-scan-all') || argv.includes('--contentScanMode=all')) {
|
||||
@ -20,3 +21,52 @@ export function parseGlobalReviewCliArgs(
|
||||
includeRootScan: !argv.includes('--no-root-scan'),
|
||||
};
|
||||
}
|
||||
|
||||
function readOption(argv: string[], names: string[]): string | undefined {
|
||||
for (const name of names) {
|
||||
const keyValue = argv.find((item) => item.startsWith(`${name}=`));
|
||||
if (keyValue) return keyValue.slice(name.length + 1);
|
||||
|
||||
const index = argv.indexOf(name);
|
||||
if (index >= 0 && argv[index + 1] && !argv[index + 1].startsWith('--')) {
|
||||
return argv[index + 1];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function readOptionList(argv: string[], names: string[]): string[] {
|
||||
const values: string[] = [];
|
||||
|
||||
names.forEach((name) => {
|
||||
argv.forEach((item, index) => {
|
||||
if (item.startsWith(`${name}=`)) {
|
||||
values.push(item.slice(name.length + 1));
|
||||
} else if (item === name && argv[index + 1] && !argv[index + 1].startsWith('--')) {
|
||||
values.push(argv[index + 1]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return values
|
||||
.flatMap((value) => value.split(','))
|
||||
.map((value) => value.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
export function parseWorkstreamCloseoutCliArgs(argv: string[]): WorkstreamCloseoutInput {
|
||||
const patternSet = new Set<string>(workstreamReusablePatternValues);
|
||||
const patterns = readOptionList(argv, ['--pattern', '--reusable-pattern'])
|
||||
.filter((pattern): pattern is WorkstreamReusablePattern => patternSet.has(pattern));
|
||||
|
||||
return {
|
||||
changedProjects: readOptionList(argv, ['--project', '--changed-project']),
|
||||
ktWorkflowUpdated: argv.includes('--kt-workflow-updated'),
|
||||
problemRecords: readOptionList(argv, ['--problem', '--problem-record']),
|
||||
reusablePatterns: patterns,
|
||||
stableSolutions: readOptionList(argv, ['--solution', '--stable-solution']),
|
||||
title: readOption(argv, ['--title']),
|
||||
upgradeNotes: readOption(argv, ['--upgrade-notes']),
|
||||
verificationEvidence: readOptionList(argv, ['--verification', '--verification-evidence']),
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { ProjectAlias, TaskType } from '../types.js';
|
||||
import type { ProjectAlias, TaskType, WorkstreamReusablePattern } from '../types.js';
|
||||
export const projectAliases = {
|
||||
admin: 'Vue/kt-template-admin',
|
||||
api: 'Node/kt-template-online-api',
|
||||
@ -38,6 +38,16 @@ export const taskTypeValues = [
|
||||
'style',
|
||||
] as const satisfies readonly TaskType[];
|
||||
|
||||
export const workstreamReusablePatternValues = [
|
||||
'blocker',
|
||||
'cleanup',
|
||||
'command-template',
|
||||
'deploy-observation',
|
||||
'none',
|
||||
'review-false-positive',
|
||||
'test-flow',
|
||||
] as const satisfies readonly WorkstreamReusablePattern[];
|
||||
|
||||
export const registeredToolNames = [
|
||||
'kt_read_context',
|
||||
'kt_inspect_project',
|
||||
@ -53,6 +63,7 @@ export const registeredToolNames = [
|
||||
'kt_risk_scan',
|
||||
'kt_global_code_review',
|
||||
'kt_finish_task',
|
||||
'kt_workstream_closeout',
|
||||
'kt_commit_plan',
|
||||
'kt_push_plan',
|
||||
'kt_business_test_plan',
|
||||
|
||||
@ -12,7 +12,9 @@ import { buildGlobalCodeReview, defaultReviewProjects } from './tools/review.js'
|
||||
import { appendTaskRecord, createCommitChecklist, prepareTask, readWorkflowContext } from './tools/task.js';
|
||||
import { buildBusinessTestPlan, createApiTestPlan, createPageTestCase } from './tools/testing.js';
|
||||
import { buildVerificationPlan } from './tools/verification.js';
|
||||
import { buildWorkstreamCloseout } from './tools/closeout.js';
|
||||
import { buildCommitPlan, buildComponentWorkflow, buildDbSyncPlan, buildFinishTask, buildPushPlan, buildRemoteHealthCheck } from './tools/workflow.js';
|
||||
import { workstreamReusablePatternValues } from './core/constants.js';
|
||||
export function response(data: unknown): McpTextResponse {
|
||||
return {
|
||||
content: [
|
||||
@ -238,6 +240,25 @@ export function registerTools(server: McpServer): void {
|
||||
async (input) => response(await buildFinishTask(input)),
|
||||
);
|
||||
|
||||
server.registerTool(
|
||||
'kt_workstream_closeout',
|
||||
{
|
||||
description: '生成大方向完结闭环审计:开发、测试证据、问题记录、稳定解法和 ktWorkflow 升级是否齐备。',
|
||||
inputSchema: {
|
||||
changedProjects: z.array(z.string()).default([]),
|
||||
ktWorkflowUpdated: z.boolean().default(false),
|
||||
problemRecords: z.array(z.string()).default([]),
|
||||
reusablePatterns: z.array(z.enum(workstreamReusablePatternValues)).default(['none']),
|
||||
stableSolutions: z.array(z.string()).default([]),
|
||||
title: z.string().optional(),
|
||||
upgradeNotes: z.string().optional(),
|
||||
verificationEvidence: z.array(z.string()).default([]),
|
||||
},
|
||||
title: 'KT Workstream Closeout',
|
||||
},
|
||||
async (input) => response(buildWorkstreamCloseout(input)),
|
||||
);
|
||||
|
||||
server.registerTool(
|
||||
'kt_commit_plan',
|
||||
{
|
||||
|
||||
@ -12,6 +12,7 @@ import { prepareTask, readWorkflowContext } from './tools/task.js';
|
||||
import { buildGlobalCodeReview, isBenignCredentialReviewValue } from './tools/review.js';
|
||||
import { buildBusinessTestPlan } from './tools/testing.js';
|
||||
import { buildVerificationPlan } from './tools/verification.js';
|
||||
import { buildWorkstreamCloseout } from './tools/closeout.js';
|
||||
import { buildCommitPlan, buildComponentWorkflow, buildDbSyncPlan, buildFinishTask, buildPushPlan, buildRemoteHealthCheck } from './tools/workflow.js';
|
||||
export async function runSelfTest(): Promise<void> {
|
||||
const reviewClassifier = {
|
||||
@ -47,6 +48,29 @@ export async function runSelfTest(): Promise<void> {
|
||||
throw new Error('refactor guardrail self-check failed');
|
||||
}
|
||||
|
||||
const closeoutNeedsUpgrade = buildWorkstreamCloseout({
|
||||
problemRecords: ['Jenkins 状态需要结合日志和 K8s 状态确认。'],
|
||||
reusablePatterns: ['deploy-observation'],
|
||||
stableSolutions: ['收尾时固定观测 build、commit、镜像、Deployment、Pod 和 smoke。'],
|
||||
title: '发布闭环',
|
||||
verificationEvidence: ['Jenkins #132 SUCCESS,K8s Pod Running。'],
|
||||
});
|
||||
if ((closeoutNeedsUpgrade.canReportComplete as boolean) !== false) {
|
||||
throw new Error('workstream closeout upgrade gate self-check failed');
|
||||
}
|
||||
|
||||
const closeoutComplete = buildWorkstreamCloseout({
|
||||
ktWorkflowUpdated: true,
|
||||
problemRecords: ['无新卡点。'],
|
||||
reusablePatterns: ['none'],
|
||||
stableSolutions: ['无新增稳定解法。'],
|
||||
title: '文档收尾',
|
||||
verificationEvidence: ['typecheck/self-test/global-review 通过。'],
|
||||
});
|
||||
if ((closeoutComplete.canReportComplete as boolean) !== true) {
|
||||
throw new Error('workstream closeout complete self-check failed');
|
||||
}
|
||||
|
||||
const data = {
|
||||
context: readWorkflowContext({ taskRecordCount: 2 }),
|
||||
guardrails: buildGuardrails({
|
||||
@ -78,6 +102,8 @@ export async function runSelfTest(): Promise<void> {
|
||||
businessTestPlan: buildBusinessTestPlan({
|
||||
flow: 'system-log-visualization',
|
||||
}),
|
||||
closeoutComplete,
|
||||
closeoutNeedsUpgrade,
|
||||
blockerResolution: buildBlockerResolution({
|
||||
attempts: 2,
|
||||
evidence: 'self-test',
|
||||
|
||||
@ -2,8 +2,9 @@
|
||||
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
||||
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
||||
|
||||
import { parseGlobalReviewCliArgs } from './core/cli.js';
|
||||
import { parseGlobalReviewCliArgs, parseWorkstreamCloseoutCliArgs } from './core/cli.js';
|
||||
import { cleanupHistoryArtifacts, parseCliCleanupArgs } from './tools/cleanup.js';
|
||||
import { buildWorkstreamCloseout } from './tools/closeout.js';
|
||||
import { buildGlobalCodeReview } from './tools/review.js';
|
||||
import { registerTools } from './registerTools.js';
|
||||
import { runSelfTest } from './selfTest.js';
|
||||
@ -20,10 +21,12 @@ if (process.argv.includes('--cleanup-history')) {
|
||||
);
|
||||
} else if (process.argv.includes('--self-test')) {
|
||||
await runSelfTest();
|
||||
} else if (process.argv.includes('--workstream-closeout')) {
|
||||
console.log(JSON.stringify(buildWorkstreamCloseout(parseWorkstreamCloseoutCliArgs(process.argv)), null, 2));
|
||||
} else {
|
||||
const server = new McpServer({
|
||||
name: 'kt-workflow',
|
||||
version: '0.6.1',
|
||||
version: '0.6.2',
|
||||
});
|
||||
registerTools(server);
|
||||
await server.connect(new StdioServerTransport());
|
||||
|
||||
129
src/tools/closeout.ts
Normal file
129
src/tools/closeout.ts
Normal file
@ -0,0 +1,129 @@
|
||||
import type { WorkstreamCloseoutInput, WorkstreamReusablePattern } from '../types.js';
|
||||
import { workstreamReusablePatternValues } from '../core/constants.js';
|
||||
import { defaultReviewProjects } from './review.js';
|
||||
|
||||
interface UpgradeTarget {
|
||||
files: string[];
|
||||
label: string;
|
||||
prompt: string;
|
||||
}
|
||||
|
||||
const upgradeTargets = {
|
||||
blocker: {
|
||||
files: ['src/tools/blocker.ts', 'src/tools/workflow.ts', 'README.md'],
|
||||
label: '卡点固化',
|
||||
prompt: '把重复失败的命令、稳定解法、停止条件和后续入口沉淀成 kt_blocker_resolution 或收尾规则。',
|
||||
},
|
||||
cleanup: {
|
||||
files: ['src/tools/cleanup.ts', 'src/tools/verification.ts', 'README.md'],
|
||||
label: '清理需求',
|
||||
prompt: '把历史产物、验证进程或远程临时目录清理变成可复用命令或验证提醒。',
|
||||
},
|
||||
'command-template': {
|
||||
files: ['src/tools/workflow.ts', 'src/tools/testing.ts', 'scripts/'],
|
||||
label: '命令模板',
|
||||
prompt: '把反复使用且容易写错的命令模板封装到工作流、业务测试计划或脚本。',
|
||||
},
|
||||
'deploy-observation': {
|
||||
files: ['src/tools/workflow.ts', 'src/tools/testing.ts', 'README.md'],
|
||||
label: '部署观测',
|
||||
prompt: '把 Jenkins/K8s build、commit、镜像、Deployment、Pod、日志和 smoke 观测步骤写成固定计划。',
|
||||
},
|
||||
none: {
|
||||
files: [],
|
||||
label: '无可执行升级',
|
||||
prompt: '明确说明本轮没有新的可复用流程、误报、清理或命令模板需要沉淀。',
|
||||
},
|
||||
'review-false-positive': {
|
||||
files: ['src/tools/review.ts', 'src/selfTest.ts', 'README.md'],
|
||||
label: '复审误报',
|
||||
prompt: '把已确认的误报规则沉淀到 review 过滤器和 self-test,避免后续污染上下文。',
|
||||
},
|
||||
'test-flow': {
|
||||
files: ['src/tools/testing.ts', 'scripts/', 'README.md'],
|
||||
label: '测试链路',
|
||||
prompt: '把新的真实接口、页面、QQBot、部署或业务 smoke 流程加入测试计划或脚本。',
|
||||
},
|
||||
} satisfies Record<WorkstreamReusablePattern, UpgradeTarget>;
|
||||
|
||||
function normalizeList(values?: string[]): string[] {
|
||||
return (values || []).map((value) => value.trim()).filter(Boolean);
|
||||
}
|
||||
|
||||
function normalizePatterns(values?: WorkstreamReusablePattern[]): WorkstreamReusablePattern[] {
|
||||
const validValues = new Set<WorkstreamReusablePattern>(workstreamReusablePatternValues);
|
||||
const uniqueValues = Array.from(
|
||||
new Set((values || []).filter((value) => validValues.has(value))),
|
||||
);
|
||||
const patterns: WorkstreamReusablePattern[] = uniqueValues.length > 0 ? uniqueValues : ['none'];
|
||||
|
||||
return patterns.length > 1 ? patterns.filter((pattern) => pattern !== 'none') : patterns;
|
||||
}
|
||||
|
||||
function buildPhase(name: string, evidence: string[], emptyHint: string): Record<string, unknown> {
|
||||
return {
|
||||
evidence,
|
||||
name,
|
||||
status: evidence.length > 0 ? 'ok' : 'missing',
|
||||
suggestion: evidence.length > 0 ? undefined : emptyHint,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildWorkstreamCloseout(input: WorkstreamCloseoutInput = {}): Record<string, unknown> {
|
||||
const title = input.title?.trim() || '';
|
||||
const changedProjects = normalizeList(input.changedProjects);
|
||||
const verificationEvidence = normalizeList(input.verificationEvidence);
|
||||
const problemRecords = normalizeList(input.problemRecords);
|
||||
const stableSolutions = normalizeList(input.stableSolutions);
|
||||
const patterns = normalizePatterns(input.reusablePatterns);
|
||||
const upgradeNeeded = patterns.some((pattern) => pattern !== 'none');
|
||||
const ktWorkflowUpdated = input.ktWorkflowUpdated === true;
|
||||
const missingItems = [
|
||||
title ? '' : '填写本轮大方向名称或目标。',
|
||||
verificationEvidence.length > 0 ? '' : '补充测试或 smoke 验证证据;只有计划不算闭环完成。',
|
||||
problemRecords.length > 0 ? '' : '补充问题记录;如无新卡点,显式写“无新卡点”。',
|
||||
stableSolutions.length > 0 ? '' : '补充稳定解法;如无新解法,显式写“无新增稳定解法”。',
|
||||
upgradeNeeded && !ktWorkflowUpdated
|
||||
? '本轮识别到可复用模式,先升级 ktWorkflow 对应规则或脚本,再报告完成。'
|
||||
: '',
|
||||
].filter(Boolean);
|
||||
const targetProjects = changedProjects.length > 0 ? changedProjects : [...defaultReviewProjects];
|
||||
const selectedUpgradeTargets = patterns.map((pattern) => ({
|
||||
pattern,
|
||||
...upgradeTargets[pattern],
|
||||
}));
|
||||
|
||||
return {
|
||||
canReportComplete: missingItems.length === 0,
|
||||
closeoutOrder: [
|
||||
buildPhase('development', title ? [title] : [], '写清本轮完成的开发目标。'),
|
||||
buildPhase('test/smoke verification', verificationEvidence, '补一条可复验的验证证据。'),
|
||||
buildPhase('problem record', problemRecords, '记录问题点;没有问题也要显式写明。'),
|
||||
buildPhase('stable solution', stableSolutions, '记录稳定解法;没有新增解法也要显式写明。'),
|
||||
{
|
||||
evidence: upgradeNeeded
|
||||
? [
|
||||
ktWorkflowUpdated
|
||||
? input.upgradeNotes || '已升级 ktWorkflow。'
|
||||
: '待升级 ktWorkflow。',
|
||||
]
|
||||
: [input.upgradeNotes || '无新的可执行 ktWorkflow 升级需求。'],
|
||||
name: 'ktWorkflow upgrade',
|
||||
status: upgradeNeeded ? (ktWorkflowUpdated ? 'ok' : 'missing') : 'not-needed',
|
||||
},
|
||||
],
|
||||
commands: [
|
||||
'git status --short',
|
||||
'pnpm run typecheck',
|
||||
'pnpm run self-test',
|
||||
'pnpm run global-review',
|
||||
'git diff --check',
|
||||
],
|
||||
missingItems,
|
||||
patterns,
|
||||
targetProjects,
|
||||
title: title || '未命名大方向',
|
||||
upgradeNeeded,
|
||||
upgradeTargets: selectedUpgradeTargets,
|
||||
};
|
||||
}
|
||||
@ -6,6 +6,7 @@ import { cleanupHistoryArtifacts } from './cleanup.js';
|
||||
import { karpathyChangedFileChecklistItem, karpathyFinishNote, karpathyStopCondition } from './karpathy.js';
|
||||
import { buildGlobalCodeReview, defaultReviewProjects } from './review.js';
|
||||
import { buildVerificationPlan } from './verification.js';
|
||||
import { buildWorkstreamCloseout } from './closeout.js';
|
||||
interface RepoSnapshot {
|
||||
branch: string;
|
||||
changedFiles: string[];
|
||||
@ -109,6 +110,16 @@ export async function buildFinishTask(input: FinishTaskInput = {}): Promise<Reco
|
||||
|
||||
return {
|
||||
cleanup,
|
||||
closeout: buildWorkstreamCloseout({
|
||||
changedProjects: changedSnapshots.map((snapshot) => snapshot.project.relativePath),
|
||||
problemRecords: [],
|
||||
reusablePatterns: ['none'],
|
||||
stableSolutions: [],
|
||||
title: 'kt_finish_task 收尾审计',
|
||||
verificationEvidence: validationRuns
|
||||
.filter((item) => item.result.ok)
|
||||
.map((item) => `${item.project.relativePath}: ${item.command}`),
|
||||
}),
|
||||
mode: input.runValidation ? 'validation_executed' : 'plan_only',
|
||||
notes: [
|
||||
'默认只生成收尾结果;runValidation=true 时才执行验证命令。',
|
||||
|
||||
20
src/types.ts
20
src/types.ts
@ -25,6 +25,15 @@ export type TaskType =
|
||||
| 'refactor'
|
||||
| 'style';
|
||||
|
||||
export type WorkstreamReusablePattern =
|
||||
| 'blocker'
|
||||
| 'cleanup'
|
||||
| 'command-template'
|
||||
| 'deploy-observation'
|
||||
| 'none'
|
||||
| 'review-false-positive'
|
||||
| 'test-flow';
|
||||
|
||||
export interface ResolvedProject {
|
||||
alias: ProjectAlias | null;
|
||||
label: string;
|
||||
@ -242,6 +251,17 @@ export interface WorkflowContextInput {
|
||||
taskRecordCount?: number;
|
||||
}
|
||||
|
||||
export interface WorkstreamCloseoutInput {
|
||||
changedProjects?: string[];
|
||||
ktWorkflowUpdated?: boolean;
|
||||
problemRecords?: string[];
|
||||
reusablePatterns?: WorkstreamReusablePattern[];
|
||||
stableSolutions?: string[];
|
||||
title?: string;
|
||||
upgradeNotes?: string;
|
||||
verificationEvidence?: string[];
|
||||
}
|
||||
|
||||
export interface VerificationPlanResult {
|
||||
changeType: TaskType;
|
||||
commands: string[];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user