import type { KdHarnessMode, KdPhase, KdRisk } from "./types.ts"; import { isKdHarnessMode, isKdPhase } from "./types.ts"; import { normalizeProduct } from "../product/profile.ts"; export interface StartArgs { goal: string; product?: string; version?: string; mode?: KdHarnessMode; modeError?: string; } export function parseArtifactArgs(args: string, currentPhase: KdPhase): { phase: KdPhase; content?: string; replace: boolean } | undefined { const replace = /\s*(^|\s)--replace(\s|$)/.test(args); const trimmed = args.replace(/\s*(^|\s)--replace(?=\s|$)/g, " ").trim(); if (!trimmed) return { phase: currentPhase, replace }; const [first] = trimmed.split(/\s+/); if (isKdPhase(first)) { const contentStart = trimmed.indexOf(first) + first.length; const content = trimmed.slice(contentStart).trim(); return { phase: first, content: content || undefined, replace }; } return { phase: currentPhase, content: trimmed, replace }; } export function parseStartArgs(args: string): StartArgs { const tokens = tokenizeArgs(args); const goal: string[] = []; let product: string | undefined; let version: string | undefined; let mode: KdHarnessMode | undefined; for (let i = 0; i < tokens.length; i++) { const token = tokens[i]; if ((token === "--product" || token === "-p") && tokens[i + 1]) { product = tokens[++i]; continue; } if ((token === "--version" || token === "-v") && tokens[i + 1]) { version = tokens[++i]; continue; } if (token === "--mode" && tokens[i + 1]) { const value = tokens[++i]; if (isKdHarnessMode(value)) { mode = value; } else { return { goal: goal.join(" "), product, version, modeError: `未知 Harness 模式:${value}` }; } continue; } if (!mode && isKdHarnessMode(token)) { mode = token; continue; } if (!product) { const normalizedProduct = normalizeProduct(token); if (normalizedProduct !== "unknown") { product = normalizedProduct; continue; } } goal.push(token); } return { goal: goal.join(" "), product, version, mode }; } export function parseProductArgs(args: string): { product: string; version?: string } | undefined { const parsed = parseStartArgs(args); const product = parsed.product ?? parsed.goal.split(/\s+/)[0]; if (!product) return undefined; return { product, version: parsed.version }; } export function parseRiskArgs(args: string): { risk: KdRisk; reason: string } | undefined { const [first, ...rest] = args.trim().split(/\s+/).filter(Boolean); const risk = first?.toLowerCase(); if (risk !== "low" && risk !== "medium" && risk !== "high") return undefined; const reason = rest.join(" ").trim(); if (!reason) return undefined; return { risk, reason }; } function tokenizeArgs(args: string): string[] { const tokens: string[] = []; const pattern = /"([^"]*)"|'([^']*)'|(\S+)/g; let match: RegExpExecArray | null; while ((match = pattern.exec(args)) !== null) { const token = match[1] ?? match[2] ?? match[3]; if (token) tokens.push(token); } return tokens; }