diff --git a/src/core/project.ts b/src/core/project.ts index 6310683..800c560 100644 --- a/src/core/project.ts +++ b/src/core/project.ts @@ -9,6 +9,20 @@ export function detectRepoType(projectPath: string): RepoType { return 'none'; } +export function parseGitStatusFiles(status: string): string[] { + return status + .split(/\r?\n/) + .map((line) => line.trimEnd()) + .filter(Boolean) + .map((line) => { + const normalized = line.trimStart(); + const match = normalized.match(/^[ MADRCU?!]{1,2}\s+(.+)$/); + const file = (match?.[1] || normalized.replace(/^\S+\s+/, '')).trim(); + return file.includes(' -> ') ? file.split(' -> ').at(-1)!.trim() : file; + }) + .filter(Boolean); +} + export function detectPackageManager(projectPath: string): PackageInfo { const packageJsonPath = path.join(projectPath, 'package.json'); const packageJson = readJson(packageJsonPath); diff --git a/src/tools/envRisk.ts b/src/tools/envRisk.ts index c12e074..e56af00 100644 --- a/src/tools/envRisk.ts +++ b/src/tools/envRisk.ts @@ -3,7 +3,7 @@ import path from 'node:path'; import type { EnvPolicyInput, RiskScanInput } from '../types.js'; import { tryExecFile } from '../core/exec.js'; -import { detectRepoType } from '../core/project.js'; +import { detectRepoType, parseGitStatusFiles } from '../core/project.js'; import { readTextIfExists, resolveProject, toPosix, workspaceRoot } from '../core/workspace.js'; export function buildEnvPolicy(input: EnvPolicyInput): Record { const project = resolveProject(input.project); @@ -43,10 +43,7 @@ export async function scanTaskRisk(input: RiskScanInput): Promise line.slice(3).trim()) - .filter(Boolean); + changedFiles = parseGitStatusFiles(status.stdout); } } diff --git a/src/tools/review.ts b/src/tools/review.ts index 1bd45e0..f2c7964 100644 --- a/src/tools/review.ts +++ b/src/tools/review.ts @@ -3,7 +3,7 @@ import path from 'node:path'; import type { GlobalCodeReviewInput, ProjectAlias, RepoType, ResolvedProject } from '../types.js'; import { tryExecFile } from '../core/exec.js'; -import { detectRepoType } from '../core/project.js'; +import { detectRepoType, parseGitStatusFiles } from '../core/project.js'; import { resolveProject, toPosix, workspaceRoot } from '../core/workspace.js'; import { scanTaskRisk } from './envRisk.js'; export const defaultReviewProjects = [ @@ -59,20 +59,6 @@ interface ReviewProjectResult { trackedSensitiveFiles: string[]; } -export function parseGitStatusFiles(status: string): string[] { - return status - .split(/\r?\n/) - .map((line) => line.trimEnd()) - .filter(Boolean) - .map((line) => { - const normalized = line.trimStart(); - const match = normalized.match(/^[ MADRCU?!]{1,2}\s+(.+)$/); - const file = (match?.[1] || line.slice(3)).trim(); - return file.includes(' -> ') ? file.split(' -> ').at(-1)!.trim() : file; - }) - .filter(Boolean); -} - async function listGitTrackedFiles(projectPath: string): Promise { const tracked = await tryExecFile('git', ['ls-files'], projectPath); if (!tracked.ok) return []; @@ -125,7 +111,7 @@ function isRuntimeDebugAllowed(projectAlias: ProjectAlias | null, file: string): if (projectAlias === 'admin' && normalized.startsWith('internal/vite-config/')) { return true; } - if (projectAlias === 'mcp' && /^(scripts\/|src\/server\.ts$)/.test(normalized)) { + if (projectAlias === 'mcp' && /^(scripts\/|src\/server\.ts$|src\/selfTest\.ts$)/.test(normalized)) { return true; } return false; diff --git a/src/tools/workflow.ts b/src/tools/workflow.ts index 87a3c6c..fdb5a26 100644 --- a/src/tools/workflow.ts +++ b/src/tools/workflow.ts @@ -1,9 +1,9 @@ import type { CommitPlanInput, ComponentWorkflowInput, DbSyncPlanInput, ExecResult, FinishTaskInput, PushPlanInput, RemoteHealthCheckInput, RepoType, ResolvedProject } from '../types.js'; import { tryExecFile, tryPowerShell } from '../core/exec.js'; -import { detectRepoType } from '../core/project.js'; +import { detectRepoType, parseGitStatusFiles } from '../core/project.js'; import { formatDateInShanghai, getGlobalReviewCommand, resolveProject, toPosix, workspaceRoot } from '../core/workspace.js'; import { cleanupHistoryArtifacts } from './cleanup.js'; -import { buildGlobalCodeReview, defaultReviewProjects, parseGitStatusFiles } from './review.js'; +import { buildGlobalCodeReview, defaultReviewProjects } from './review.js'; import { buildVerificationPlan } from './verification.js'; interface RepoSnapshot { branch: string;