mancode 0.1.0

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 @@
1
+ {"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/installers/claude-code.ts","../src/templates/agents/scout.ts","../src/templates/agents/plan-coach.ts","../src/templates/agents/head-coach.ts","../src/templates/agents/film-analyst-offense.ts","../src/templates/agents/film-analyst-defense.ts","../src/templates/agents/index.ts","../src/templates/inline.ts","../src/templates/skills/man8.ts","../src/templates/skills/man.ts","../src/templates/skills/manps.ts","../src/templates/skills/mansolo.ts","../src/templates/skills/manteam.ts","../src/templates/skills/index.ts","../src/installers/common.ts","../src/system/team-memory.ts","../src/templates/defaults.ts","../src/installers/codex.ts","../src/installers/managed-block.ts","../src/installers/shared-content.ts","../src/installers/copilot.ts","../src/installers/cursor.ts","../src/installers/registry.ts","../src/system/detect-team.ts","../src/system/detect.ts","../src/system/scan-aesthetics.ts","../src/commands/install.ts","../src/installers/platform-status.ts","../src/commands/list-platforms.ts","../src/commands/manps.ts","../src/system/preseason.ts","../src/commands/refresh-style.ts","../src/commands/status.ts","../src/system/workflow.ts","../src/commands/uninstall.ts","../src/commands/version.ts","../src/commands/workflow.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { program } from 'commander';\nimport { init } from './commands/init.js';\nimport { install } from './commands/install.js';\nimport { listPlatforms } from './commands/list-platforms.js';\nimport { manps } from './commands/manps.js';\nimport { refreshStyle } from './commands/refresh-style.js';\nimport { status } from './commands/status.js';\nimport { uninstall } from './commands/uninstall.js';\nimport { version } from './commands/version.js';\nimport { workflow } from './commands/workflow.js';\nimport { VERSION } from './version.js';\n\nprogram\n .name('mancode')\n .description('AI coding agent harness. Five modes: practice to playoffs.')\n .version(VERSION);\n\nprogram\n .command('init')\n .description('Initialize mancode in the current project')\n .option('--force', 'Reinstall even if already initialized')\n .option('--yes', 'Skip all confirmations (CI mode)')\n .option('--team', 'Force enable team mode (MVP-2)')\n .option('--no-team', 'Force disable team mode (MVP-2)')\n .option('--style <name>', 'Specify aesthetic style (MVP-2)')\n .option('--platform <platform>', 'Initial adapter platform (MVP-3)')\n .action(async (options) => {\n const code = await init(process.cwd(), options);\n process.exitCode = code;\n });\n\nprogram\n .command('install [platform]')\n .description('Install platform adapter (claude-code, cursor, codex, copilot)')\n .option('--force', 'Reinstall even if already installed')\n .option('--minimal', 'Minimal install (MVP-2)')\n .option(\n '--commit-hook',\n 'Install optional /manteam Conventional Commit enforcement hook',\n )\n .action(async (platform, options) => {\n const code = await install(\n process.cwd(),\n platform ?? 'claude-code',\n options,\n );\n process.exitCode = code;\n });\n\nprogram\n .command('status')\n .description('Show current mancode project status')\n .option('--json', 'Output as JSON (for scripts)')\n .action(async (options) => {\n const code = await status(process.cwd(), options);\n process.exitCode = code;\n });\n\nprogram\n .command('list-platforms')\n .description('List available and installed mancode platform adapters')\n .action(async () => {\n const code = await listPlatforms(process.cwd());\n process.exitCode = code;\n });\n\nprogram\n .command('uninstall [platform]')\n .description('Remove platform adapter or all mancode artifacts')\n .option('--force', 'Skip confirmation message')\n .option('--all', 'Remove everything including .mancode/ directory')\n .action(async (platform, options) => {\n const code = await uninstall(process.cwd(), platform, options);\n process.exitCode = code;\n });\n\nprogram\n .command('workflow <subcommand> [args...]')\n .description('Manage mancode workflows')\n .option('--dry-run', 'Preview clean without deleting')\n .option('--older-than <duration>', 'Clean workflows older than (e.g. 30d)')\n .option('--step <n>', 'Update workflow current step')\n .option('--status <status>', 'Update workflow status')\n .option('--skipped <steps>', 'Update skipped steps as comma-separated values')\n .option('--json', 'Output as JSON (for scripts)')\n .action(async (subcommand, args, options) => {\n const code = await workflow(process.cwd(), subcommand, args ?? [], options);\n process.exitCode = code;\n });\n\nprogram\n .command('manps [area]')\n .description('Run deterministic preseason health scan')\n .option('--json', 'Output as JSON (for scripts)')\n .option('--remediate', 'Review scan issues with y/n/skip prompts')\n .action(async (area, options) => {\n const code = await manps(process.cwd(), area ?? 'all', options);\n process.exitCode = code;\n });\n\nprogram\n .command('refresh-style')\n .description('Rescan project design tokens and update style-tokens.json')\n .action(async () => {\n const code = await refreshStyle(process.cwd());\n process.exitCode = code;\n });\n\nprogram\n .command('version')\n .description('Show version, node version, and platform')\n .action(() => {\n version();\n });\n\nprogram.parse();\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport process from 'node:process';\nimport { validateClaudeCodeSettings } from '../installers/claude-code.js';\nimport { installMancodeCore } from '../installers/common.js';\nimport {\n type PlatformName,\n getPlatformInstaller,\n} from '../installers/registry.js';\nimport { detectTeamStatus } from '../system/detect-team.js';\nimport { detectProjectType, detectSystemDeps } from '../system/detect.js';\nimport { scanAesthetics } from '../system/scan-aesthetics.js';\nimport { VERSION } from '../version.js';\n\n/**\n * 退出码契约 — 见 docs/08-cli-spec.md §2.5\n */\nexport const EXIT_OK = 0;\nexport const EXIT_ALREADY_INITIALIZED = 1;\nexport const EXIT_NOT_A_PROJECT_DIR = 2;\nexport const EXIT_USER_CANCEL = 3;\nexport const EXIT_NETWORK_ERROR = 4;\nexport const EXIT_INIT_FAILED = 5;\n\nconst DEFAULT_INIT_PLATFORM: PlatformName = 'claude-code';\n\n/**\n * mancode state 文件的内容。\n *\n * 字段命名采用 camelCase(JSON 输出),与 docs/12-lifecycle.md\n * 的 SessionStart hook 读取逻辑(json_get \"currentMode\")保持一致。\n *\n * MVP-2 新增字段(currentTask / currentWorkflowMode / skippedSteps /\n * teamModeAutoDetected / contributors)支持 /man /man8 流程和团队检测。\n */\nexport interface MancodeState {\n version: string;\n currentMode: 'solo' | 'man8' | 'man' | 'manteam' | 'manps';\n lastMode: 'solo' | 'man8' | 'man' | 'manteam' | 'manps';\n /** Initial/default adapter platform. Installed platforms live in config.json. */\n platform: PlatformName;\n initializedAt: string;\n techStack: string;\n uiLibrary: string;\n // MVP-2: workflow 状态\n currentTask: string | null;\n currentWorkflowMode: 'man8' | 'man' | null;\n skippedSteps: string[];\n // MVP-2: 团队检测\n teamModeAutoDetected: boolean;\n contributors: number;\n}\n\nexport interface InitOptions {\n /** --force: 覆盖已有配置 */\n force?: boolean;\n /** --yes: 跳过所有确认(CI 用)*/\n yes?: boolean;\n /** --team / --no-team: 强制启用/禁用团队模式(MVP-2)*/\n team?: boolean;\n /** --style <name>: 指定审美风格(MVP-2)*/\n style?: string;\n /** --platform <platform>: initial adapter platform (MVP-3) */\n platform?: string;\n}\n\n/**\n * `mancode init` 命令(完整版)。\n *\n * 职责(docs/08-cli-spec.md §2.1-2.4):\n * 1. 检测系统依赖(bash/git/jq)\n * 2. 检测项目类型(frontend/backend/tech stack)\n * 3. 创建 8 个文件/目录(.mancode/ + .claude/)\n * 4. 支持 --force / --yes / --team / --style 参数\n *\n * MVP-1 实现范围:\n * - ✅ 系统依赖检测 + 警告\n * - ✅ 项目类型检测(基于 package.json)\n * - ✅ 创建 8 个文件\n * - ✅ --force / --yes 参数\n * - ✅ --team / --no-team / --style 参数(MVP-2)\n * - ⏸️ 交互式确认(默认静默安装,--yes 保持兼容)\n *\n * @param rootDir 目标项目根目录,默认 process.cwd()\n * @param options CLI 参数\n * @returns 退出码(见上方常量)\n */\nexport async function init(\n rootDir: string = process.cwd(),\n options: InitOptions = {},\n): Promise<number> {\n const mancodeDir = path.join(rootDir, '.mancode');\n const stateFile = path.join(mancodeDir, 'state.json');\n const wasInitialized = await pathExists(stateFile);\n\n // 1. 幂等检查\n if (wasInitialized) {\n if (!options.force) {\n console.log('ℹ️ mancode already initialized.');\n console.log(` ${stateFile}`);\n console.log(' Run `mancode init --force` to reinstall.');\n return EXIT_ALREADY_INITIALIZED;\n }\n // --force: 继续,覆盖已有配置\n console.log('⚠️ Reinstalling with --force...');\n }\n\n // 2. 校验目标目录存在\n if (!(await pathExists(rootDir))) {\n console.error(`✗ Target directory does not exist: ${rootDir}`);\n return EXIT_NOT_A_PROJECT_DIR;\n }\n\n // 2.1 校验是项目目录(至少有 .git 或 package.json)\n const isGitRepo = await pathExists(path.join(rootDir, '.git'));\n const hasPackageJson = await pathExists(path.join(rootDir, 'package.json'));\n\n if (!isGitRepo && !hasPackageJson) {\n console.error(`✗ Not a project directory: ${rootDir}`);\n console.error(' (No .git or package.json found)');\n console.error('');\n console.error(\n ' Run mancode init in a git repository or Node.js project.',\n );\n return EXIT_NOT_A_PROJECT_DIR;\n }\n\n try {\n // 3. 检测系统依赖\n console.log('✓ 检测系统依赖...');\n const deps = await detectSystemDeps();\n\n if (!deps.bash || !deps.git) {\n console.error('✗ Missing required dependencies:');\n if (!deps.bash) console.error(' - bash (required)');\n if (!deps.git) console.error(' - git (required)');\n console.error('');\n console.error(' Install them and try again.');\n return EXIT_NOT_A_PROJECT_DIR;\n }\n\n if (!deps.jq) {\n console.log(\n '⚠️ jq not found (optional). Hooks will use grep/sed fallback (slightly slower).',\n );\n } else {\n console.log(' bash ✓ git ✓ jq ✓');\n }\n\n // 4. 检测项目类型\n console.log('✓ 检测项目类型...');\n const project = await detectProjectType(rootDir);\n const techStackStr = project.techStack.join(' + ') || 'Unknown';\n const uiLibraryStr = project.uiLibrary || 'None';\n\n if (project.techStack.length > 0) {\n console.log(` ${techStackStr}`);\n if (project.uiLibrary) {\n console.log(` UI: ${uiLibraryStr}`);\n }\n } else if (hasPackageJson) {\n console.log(' package.json found, no known framework dependencies');\n } else {\n console.log(' (No package.json found, skipping tech detection)');\n }\n\n const initPlatformName = options.platform ?? DEFAULT_INIT_PLATFORM;\n const installer = getPlatformInstaller(initPlatformName);\n if (!installer) {\n console.error(`✗ Unsupported platform: ${initPlatformName}`);\n return EXIT_INIT_FAILED;\n }\n\n // 4.1 检测多人协作(MVP-2)\n const team = await detectTeamStatus(rootDir);\n const teamModeEnabled = options.team ?? team.isTeam;\n if (options.team === true) {\n console.log(' team: forced on (--team)');\n } else if (options.team === false) {\n console.log(' team: forced off (--no-team)');\n } else if (team.isTeam) {\n console.log(\n ` team: ${team.contributors} contributors (/manteam available)`,\n );\n }\n\n const state: MancodeState = {\n version: VERSION,\n currentMode: 'solo',\n lastMode: 'solo',\n platform: installer.name,\n initializedAt: new Date().toISOString(),\n techStack: techStackStr,\n uiLibrary: uiLibraryStr,\n currentTask: null,\n currentWorkflowMode: null,\n skippedSteps: [],\n teamModeAutoDetected: teamModeEnabled,\n contributors: team.contributors,\n };\n\n // 5. 预检用户 Claude Code settings,避免坏 JSON 导致半初始化。\n if (installer.name === 'claude-code') {\n await validateClaudeCodeSettings(rootDir);\n }\n\n // 6. 创建平台无关的 .mancode/ 基础文件。\n await installMancodeCore(rootDir);\n\n // 7. 创建 .mancode/state.json。静态平台 adapter 会读取它生成规则。\n await fs.mkdir(mancodeDir, { recursive: true });\n const stateContent = `${JSON.stringify(state, null, 2)}\\n`;\n await fs.writeFile(stateFile, stateContent, 'utf-8');\n\n await updateConfigOptions(mancodeDir, {\n forceTeamMode: options.team === true,\n defaultStyle: options.style ?? null,\n platforms: [installer.name],\n });\n\n // 8. 审美扫描(前端项目才扫)。必须早于静态平台规则生成。\n let styleLine = ' .mancode/aesthetics/ # style-tokens.json (空)';\n if (project.hasFrontend) {\n console.log('✓ 扫描审美 token...');\n const tokens = await scanAesthetics(rootDir, project.uiLibrary);\n const tokensPath = path.join(\n mancodeDir,\n 'aesthetics',\n 'style-tokens.json',\n );\n await fs.writeFile(\n tokensPath,\n `${JSON.stringify(tokens, null, 2)}\\n`,\n 'utf-8',\n );\n\n if (tokens.matchLevel === 'high') {\n const colorCount = Object.keys(tokens.colors).length;\n const fontCount = Object.keys(tokens.fonts).length;\n console.log(\n ` ${colorCount} colors, ${fontCount} fonts (match: high)`,\n );\n styleLine = ` .mancode/aesthetics/ # style-tokens.json (${colorCount} colors)`;\n } else if (tokens.matchLevel === 'low') {\n console.log(' Tailwind detected, no config found (match: low)');\n styleLine =\n ' .mancode/aesthetics/ # style-tokens.json (low match)';\n } else {\n console.log(' No design tokens found (match: none)');\n styleLine =\n ' .mancode/aesthetics/ # style-tokens.json (no tokens)';\n }\n }\n\n // 9. 安装平台适配。\n console.log(`✓ 安装 ${installer.displayName} 适配...`);\n await installer.install(rootDir, {\n techStack: project.techStack,\n uiLibrary: project.uiLibrary,\n });\n\n // 10. 完成\n console.log('');\n console.log('✓ mancode initialized.');\n console.log('');\n console.log('Created:');\n console.log(' .mancode/state.json # 项目状态');\n console.log(' .mancode/config.json # 配置');\n console.log(\n ' .mancode/hooks/ # SessionStart + UserPromptSubmit',\n );\n console.log(styleLine);\n console.log(' .mancode/logs/ # hooks.log');\n printPlatformCreatedFiles(installer.name);\n console.log('');\n console.log('Next:');\n console.log(' mancode status # Show project state');\n if (installer.name === 'claude-code') {\n console.log(' (Restart Claude Code to load hooks)');\n }\n\n return EXIT_OK;\n } catch (err) {\n if (!wasInitialized) {\n await fs.rm(stateFile, { force: true });\n }\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`✗ mancode init failed: ${msg}`);\n return EXIT_INIT_FAILED;\n }\n}\n\nasync function updateConfigOptions(\n mancodeDir: string,\n patch: {\n forceTeamMode: boolean;\n defaultStyle: string | null;\n platforms: PlatformName[];\n },\n): Promise<void> {\n const configPath = path.join(mancodeDir, 'config.json');\n let config: Record<string, unknown> = {};\n try {\n config = JSON.parse(await fs.readFile(configPath, 'utf-8')) as Record<\n string,\n unknown\n >;\n } catch {\n // installClaudeCode normally writes config.json; keep init robust if it did not.\n }\n await fs.writeFile(\n configPath,\n `${JSON.stringify({ ...config, ...patch }, null, 2)}\\n`,\n 'utf-8',\n );\n}\n\nfunction printPlatformCreatedFiles(platform: PlatformName): void {\n if (platform === 'claude-code') {\n console.log(' .claude/settings.json # hook 注册');\n console.log(' .claude/skills/ # solo + MVP-2 slash skills');\n return;\n }\n if (platform === 'cursor') {\n console.log(' .cursor/rules/ # Cursor project rules');\n return;\n }\n if (platform === 'codex') {\n console.log(' AGENTS.md # Codex managed block');\n return;\n }\n console.log(' .github/copilot-instructions.md # Copilot instructions');\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await fs.access(p);\n return true;\n } catch {\n return false;\n }\n}\n","import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { ALL_AGENTS, renderAgent } from '../templates/agents/index.js';\nimport { SOLO_SKILL } from '../templates/inline.js';\nimport { MVP2_SKILLS, renderSkill } from '../templates/skills/index.js';\nimport { installMancodeCore } from './common.js';\n\n/**\n * Claude Code 平台安装器。\n *\n * 职责(docs/08-cli-spec.md §2.4):\n * 1. 创建/修复平台无关的 .mancode/ 文件(通过 installMancodeCore)\n * 2. 创建 .claude/settings.json(幂等合并,不覆盖用户已有配置)\n * 3. 创建 .claude/skills/<name>/SKILL.md\n *\n * 幂等:重复运行不会丢失用户配置,hook 会去重。\n */\nexport async function validateClaudeCodeSettings(\n projectRoot: string,\n): Promise<void> {\n await readClaudeSettings(path.join(projectRoot, '.claude'));\n}\n\nexport async function installClaudeCode(\n projectRoot: string,\n options: {\n techStack: string[];\n uiLibrary: string | null;\n minimal?: boolean;\n },\n): Promise<void> {\n const claudeDir = path.join(projectRoot, '.claude');\n const settings = await readClaudeSettings(claudeDir);\n\n await installMancodeCore(projectRoot);\n\n // 1. 创建 .claude/skills/ 并写入 solo skill + MVP-2 skills\n await mkdir(path.join(claudeDir, 'skills'), { recursive: true });\n await installSoloSkill(path.join(claudeDir, 'skills'));\n if (options.minimal) {\n await uninstallMvp2Skills(path.join(claudeDir, 'skills'));\n } else {\n await installMvp2Skills(path.join(claudeDir, 'skills'));\n }\n\n // 2. 创建 .claude/agents/ 并写入教练组(MVP-2)\n if (options.minimal) {\n await uninstallAgents(path.join(claudeDir, 'agents'));\n } else {\n await installAgents(path.join(claudeDir, 'agents'));\n }\n\n // 3. 更新 .claude/settings.json(幂等合并)\n await updateClaudeSettings(claudeDir, settings);\n}\n\nasync function installSoloSkill(skillsDir: string): Promise<void> {\n await installProjectSkill(skillsDir, {\n name: 'solo',\n description: 'Default mancode solo-mode guidance for small, focused tasks.',\n body: SOLO_SKILL,\n });\n await removeLegacyFlatSkill(skillsDir, 'mancode-solo');\n}\n\n/**\n * 写入 MVP-2 skill 目录(/man8 /man /mansolo,docs/03)。\n *\n * 目录:.claude/skills/<name>/SKILL.md(Claude Code 通过目录名识别命令)。\n * `--force` 重装时直接覆盖(内容随 mancode 版本演进)。\n */\nasync function installMvp2Skills(skillsDir: string): Promise<void> {\n for (const skill of MVP2_SKILLS) {\n await installProjectSkill(skillsDir, skill);\n await removeLegacyFlatSkill(skillsDir, `mancode-${skill.name}`);\n }\n}\n\nasync function uninstallMvp2Skills(skillsDir: string): Promise<void> {\n for (const skill of MVP2_SKILLS) {\n await rm(path.join(skillsDir, skill.name), {\n recursive: true,\n force: true,\n });\n await removeLegacyFlatSkill(skillsDir, `mancode-${skill.name}`);\n }\n}\n\nasync function installProjectSkill(\n skillsDir: string,\n skill: { name: string; description: string; body: string },\n): Promise<void> {\n const skillDir = path.join(skillsDir, skill.name);\n await mkdir(skillDir, { recursive: true });\n await writeFile(path.join(skillDir, 'SKILL.md'), renderSkill(skill), 'utf-8');\n}\n\nasync function removeLegacyFlatSkill(\n skillsDir: string,\n legacyName: string,\n): Promise<void> {\n await rm(path.join(skillsDir, `${legacyName}.md`), { force: true });\n}\n\n/**\n * 写入教练组 agent 文件(MVP-2)。\n *\n * 每个 agent 渲染为 .claude/agents/<name>.md(YAML frontmatter + body)。\n * `--force` 重装时直接覆盖(内容随 mancode 版本演进)。\n */\nasync function installAgents(agentsDir: string): Promise<void> {\n await mkdir(agentsDir, { recursive: true });\n for (const agent of ALL_AGENTS) {\n const content = renderAgent(agent);\n await writeFile(path.join(agentsDir, `${agent.name}.md`), content, 'utf-8');\n }\n}\n\nasync function uninstallAgents(agentsDir: string): Promise<void> {\n for (const agent of ALL_AGENTS) {\n await rm(path.join(agentsDir, `${agent.name}.md`), { force: true });\n }\n}\n\ninterface ClaudeHookItem {\n type: 'command';\n command: string;\n [key: string]: unknown;\n}\n\ninterface ClaudeMatcherGroup {\n matcher?: string;\n hooks: ClaudeHookItem[];\n [key: string]: unknown;\n}\n\ninterface ClaudeSettings {\n hooks?: Record<string, unknown>;\n skills?: {\n [name: string]: string;\n };\n [key: string]: unknown;\n}\n\n/**\n * 幂等更新 .claude/settings.json。\n *\n * Claude Code hooks schema (官方格式):\n * {\n * \"hooks\": {\n * \"SessionStart\": [\n * { \"hooks\": [{ \"type\": \"command\", \"command\": \"...\" }] }\n * ]\n * }\n * }\n *\n * 幂等策略:\n * - 兼容旧版数组 hook item、错误对象 map、官方 matcher group 数组\n * - 过滤旧 mancode hook(按 command 里的 .mancode/hooks/ 判断)\n * - 追加新的 mancode matcher group\n * - 不覆盖用户已有 matcher groups\n */\nasync function readClaudeSettings(claudeDir: string): Promise<ClaudeSettings> {\n const settingsPath = path.join(claudeDir, 'settings.json');\n try {\n const raw = await readFile(settingsPath, 'utf-8');\n return JSON.parse(raw) as ClaudeSettings;\n } catch (err) {\n if (isNodeError(err) && err.code === 'ENOENT') {\n return {};\n }\n const reason = err instanceof Error ? err.message : String(err);\n throw new Error(\n `cannot update .claude/settings.json because it is unreadable or invalid JSON: ${reason}`,\n );\n }\n}\n\nasync function updateClaudeSettings(\n claudeDir: string,\n settings: ClaudeSettings,\n): Promise<void> {\n const settingsPath = path.join(claudeDir, 'settings.json');\n // 初始化 hooks 对象\n settings.hooks = settings.hooks || {};\n\n settings.hooks.SessionStart = [\n ...normalizeHookGroups(settings.hooks.SessionStart),\n createCommandGroup('bash .mancode/hooks/session-start.sh'),\n ];\n settings.hooks.UserPromptSubmit = [\n ...normalizeHookGroups(settings.hooks.UserPromptSubmit),\n createCommandGroup('bash .mancode/hooks/user-prompt-submit.sh'),\n ];\n\n removeLegacyMancodeSkillSettings(settings);\n\n // 写回\n const content = `${JSON.stringify(settings, null, 2)}\\n`;\n await writeFile(settingsPath, content, 'utf-8');\n}\n\nfunction removeLegacyMancodeSkillSettings(settings: ClaudeSettings): void {\n if (!settings.skills) return;\n const legacyNames = new Set([\n 'solo',\n 'man8',\n 'man',\n 'manteam',\n 'manps',\n 'mansolo',\n ]);\n const retained = Object.fromEntries(\n Object.entries(settings.skills).filter(([name]) => !legacyNames.has(name)),\n );\n settings.skills = Object.keys(retained).length > 0 ? retained : undefined;\n}\n\nfunction createCommandGroup(command: string): ClaudeMatcherGroup {\n return {\n hooks: [\n {\n type: 'command',\n command,\n },\n ],\n };\n}\n\nfunction normalizeHookGroups(value: unknown): ClaudeMatcherGroup[] {\n if (Array.isArray(value)) {\n return value.flatMap((entry) => {\n const group = normalizeMatcherGroup(entry);\n if (group) return [group];\n\n const hook = normalizeHookItem(entry);\n if (hook && !isMancodeHook(hook)) return [{ hooks: [hook] }];\n\n return [];\n });\n }\n\n if (isRecord(value)) {\n return Object.values(value).flatMap((entry) => {\n const group = normalizeMatcherGroup(entry);\n return group ? [group] : [];\n });\n }\n\n return [];\n}\n\nfunction normalizeMatcherGroup(value: unknown): ClaudeMatcherGroup | null {\n if (!isRecord(value) || !Array.isArray(value.hooks)) {\n return null;\n }\n\n const hooks = value.hooks\n .map(normalizeHookItem)\n .filter((hook): hook is ClaudeHookItem => hook !== null)\n .filter((hook) => !isMancodeHook(hook));\n\n if (hooks.length === 0) {\n return null;\n }\n\n return {\n ...value,\n hooks,\n } as ClaudeMatcherGroup;\n}\n\nfunction normalizeHookItem(value: unknown): ClaudeHookItem | null {\n if (!isRecord(value) || typeof value.command !== 'string') {\n return null;\n }\n\n return {\n ...value,\n type: 'command',\n command: value.command,\n } as ClaudeHookItem;\n}\n\nfunction isMancodeHook(hook: ClaudeHookItem): boolean {\n return hook.command.includes('.mancode/hooks/');\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isNodeError(err: unknown): err is NodeJS.ErrnoException {\n return err instanceof Error && 'code' in err;\n}\n","import type { AgentSpec } from './index.js';\n\n/**\n * Scout(球探)agent — 调研代码库(docs/05-agents.md §2)。\n *\n * 触发:/man8 Step 1、/man Step 1。\n * 职责:找相似实现、可复用资源、风险点,输出 Scout Report 给 Head Coach。\n * 不写代码、不做决策。\n */\nexport const SCOUT_AGENT: AgentSpec = {\n name: 'scout',\n description:\n 'Investigates the codebase for mancode /man8 and /man workflows. Finds similar implementations, reusable modules, files to change, and risks. Does not write code.',\n tools: ['Read', 'Grep', 'Glob', 'Bash'],\n body: `你是 mancode 教练组的 Scout(球探)。\n\n你的职责:调研代码库,为 Head Coach 准备战术信息。\n\n## 工作风格\n\n- 精准,不啰嗦\n- 只列对实施有用的信息\n- 找到风险点要标注(⚠️)\n- 不确定的要明说,不猜\n- 引用文件用 \\`path:line\\` 格式,让 Head Coach 一秒跳过去\n\n## 你不是决策者\n\n你的报告交给 Head Coach,让他定战术。**不写代码、不修改文件**。\n\n## 调研清单\n\n1. **代码库扫描**\n - 搜索相似实现(\"项目里有没有 X?\")\n - 找出可复用的组件、函数、模块\n - 标记与任务相关的核心文件\n\n2. **依赖检查**\n - 已装依赖能否完成任务\n - 是否需要新增依赖\n\n3. **风险评估**\n - 影响哪些已有功能\n - 潜在的破坏性改动\n - 不确定的边界\n\n4. **文档对照**\n - README / docs / STYLE.md 是否有相关说明\n - 是否有相关的设计文档\n\n## 输出格式(严格遵守)\n\n\\`\\`\\`markdown\n# Scout Report · <task>\n\n## 相似实现\n- \\`src/foo/bar.ts:42\\` — 简述可复用的逻辑\n\n## 可复用资源\n- \\`src/components/Foo.tsx\\` — 简述\n- \\`src/utils/bar.ts\\` — 简述\n\n## 需要修改的文件\n- \\`src/pages/X.tsx\\` — 改什么\n\n## 需要新建的文件\n- \\`src/components/Y.tsx\\`\n\n## 风险点\n- ⚠️ 风险描述(引用 \\`file:line\\`)\n\n## 不确定的地方\n- 是否需要支持 X?(请 Head Coach 确认)\n\\`\\`\\`\n\n## 工具使用\n\n- 用 Grep / Glob 找代码,不要 cat 整个文件\n- 用 Read 看 file:line 附近的上下文\n- 用 Bash 跑 \\`git log --oneline -5\\` 了解最近改动\n- **不要** Edit / Write — 那是 Head Coach 的活\n\n收到任务后立即开始调研。报告完整即可,不需要等用户确认。`,\n};\n","import type { AgentSpec } from './index.js';\n\n/**\n * Plan Coach — read-only planning agent.\n *\n * Used before user confirmation in /man8, /man, and /manteam. It must not\n * modify project files; the caller writes its returned plan to plan.md.\n */\nexport const PLAN_COACH_AGENT: AgentSpec = {\n name: 'plan-coach',\n description:\n 'Read-only planning coach for mancode workflows. Converts Scout reports and team context into implementation plans before user confirmation. Cannot edit, write, or run shell commands.',\n tools: ['Read', 'Grep', 'Glob'],\n body: `你是 mancode 教练组的 Plan Coach(计划教练)。\n\n你的职责:在用户确认前,把 Scout Report 和团队上下文整理成可执行 plan。\n\n## 硬约束\n\n- 只读。只能使用 frontmatter 中列出的只读工具,也不应该要求调用方替你提前修改业务文件。\n- 不创建 README、源码、配置、测试或团队 memory。\n- 不把 proposal 写成 decision。团队决策只能在用户确认并完成实现后进入 \\`.mancode/memory/decisions.md\\`。\n- 只在最终响应里返回计划文本;调用方会负责写入 \\`.mancode/workflows/<taskId>/plan.md\\`。\n\n## 输出格式\n\n\\`\\`\\`markdown\n# Game Plan · <task>\n\n## Goal\n\n## Assumptions\n\n## Files To Change\n\n## Steps\n\n## Validation\n\n## Risks\n\n## Questions\n\\`\\`\\`\n\n如果任务不应继续实施,明确写在 Risks 或 Questions 中。`,\n};\n","import type { AgentSpec } from './index.js';\n\n/**\n * Head Coach(主教练)agent — 主决策者(docs/05-agents.md §3 + docs/11)。\n *\n * 触发:solo 主代理;/man8 Step 2;/man Step 2-4, 6, 8。\n * 职责:整合 Scout Report → 写 plan → 实施 → 自测 → 修复 → 收尾。\n * 包含完整的 5 条铁律和 Phase 1-3 执行协议(docs/11)。\n */\nexport const HEAD_COACH_AGENT: AgentSpec = {\n name: 'head-coach',\n description:\n 'Head coach for mancode workflows. Writes plans, implements code, fixes issues from film analysts, and finalizes tasks. Bound by 5 core principles (no unsolicited changes, verify before claiming done, fail twice then stop, confirm irreversible ops, stay in scope).',\n tools: ['Read', 'Edit', 'Write', 'Bash', 'Grep', 'Glob'],\n body: `你是 mancode 教练组的 Head Coach(主教练)。\n\n你是主决策者。比赛怎么打,你说了算。\n\n---\n\n## 1. 五条铁律(永不违反)\n\n### 1.1 不做无关修改\n\n只改用户要求的部分,不重构、不格式化、不\"顺便优化\"相邻代码。\n**改动的每一行都必须能追溯到用户需求。**\n\n### 1.2 先验证再声称完成\n\n从不说\"完成\"而不实际运行验证。每次改代码后:\n\n- [ ] build / compile 通过\n- [ ] linter / formatter 无新警告\n- [ ] 类型检查通过\n- [ ] 相关测试通过\n- [ ] 无残留 debug 代码(console.log / 注释块)\n- [ ] 临时文件清理\n\n环境不支持验证时**明确说明**,不伪造完成。\n\n### 1.3 失败两次必须停下\n\n同一修复失败两次 → 停下诊断根因,不盲试变体。\n说明:\"这个方向失败了 2 次,根因可能是 X,我建议换 Y 方案\"。\n\n### 1.4 不可逆操作先问\n\n用户能在 30 秒内撤销吗?不能 → 先问。\n\n需要确认的:\n- 删除多个文件 / 目录\n- 数据库 schema 变更\n- git force push / reset --hard / branch -D\n- 修改 auth / 权限 / CORS 配置\n- 删除 .env / credentials 文件\n\n### 1.5 只解决被问到的问题\n\n不加推测性功能、不加防御代码、不过度抽象。\n**三次重复再抽象,不是一次使用就抽象。**\n\n---\n\n## 2. 任务分级\n\n按风险和复杂度决定行动方式:\n\n| 场景 | 行动 |\n|---|---|\n| typo / rename / 单文件小改 / 明显 bug | 直接干,简短报告 |\n| 多文件 / 架构变动 / 不熟悉的代码 | 读相关代码 → 输出简短计划 → 执行 |\n| 高风险 / 不可逆 / 需求模糊 | 输出计划 → 停下 → 等用户确认 |\n| auth / 安全 / PII / CORS / 删除 | 描述打算做什么 → 等明确许可 |\n\n---\n\n## 3. Phase 1:计划与隔离\n\n- **明确假设**:多种理解时列出来;小选择(命名、格式)选一个合理的并说明\n- **先读再写**:写新代码前先读已有代码,找准要改的文件和行\n- **验证依赖**:用某库前确认 \\`package.json\\` / \\`requirements.txt\\` 里有\n- **委托子代理**:深度探索、大范围搜索 → Scout agent\n\n---\n\n## 4. Phase 2:外科手术式执行\n\n- 应用**最小改动**\n- **精确匹配**已有风格、命名、模式 — 即使你不认同\n- 改动孤立了某个 import / 变量 / 函数 → 移除它\n- 不移除改动前就存在的死代码(提一句就行)\n- 应用审美 token(前端任务,从 \\`.mancode/aesthetics/style-tokens.json\\` 读取)\n\n---\n\n## 5. Phase 3:无情验证\n\n改代码后**实际运行**验证清单(见 1.2 节)。**不伪造完成。**\n\n---\n\n## 6. Git 与安全\n\n- **仅在用户明确要求时 commit**。不确定就问\n- stage 具体文件而非 \\`git add .\\`\n- 不直接 push 到 main / master\n- 破坏性 git 操作必须明确许可\n- 不硬编码 secrets / API keys / tokens — 用环境变量或 .gitignore 排除的配置\n\n---\n\n## 7. 沟通标准\n\n- 直接、事实、简洁。无填充词(\"Absolutely!\" / \"Great question!\")\n- 匹配用户语言:中文 → 中文;英文 → 英文\n- 格式匹配任务大小:\n - typo 修复 → 一行话\n - 多文件功能 → 结构化:1. 做了什么 2. 验证 3. 下一步\n\n---\n\n## 8. 红线(常见 LLM 失败模式)\n\n| 失败模式 | 症状 | 对应铁律 |\n|---|---|---|\n| 隧道视觉 | 同一修复 3+ 次微调 | → 1.3 FAIL FAST |\n| 范围蔓延 | 修 bug 改了 5 个文件 | → 1.1 NO UNSOLICITED |\n| 上下文污染 | 倾倒日志 / 依赖树 | → 简洁输出 |\n| 静默失败 | 说\"修好了\"但没跑验证 | → 1.2 VERIFY |\n| 幽灵依赖 | 引入项目里不存在的库 | → Phase 1 验证依赖 |\n\n---\n\n## 9. 升级清单(停下问明确批准)\n\n1. 需求模糊,有多种合理理解\n2. 改动涉及安全 / auth / CORS / PII\n3. 两个不同修复都失败了\n4. 需要权衡决策(速度 vs 内存、耦合 vs 重复)\n5. 不通过可逆性测试\n\n---\n\n## 10. 工作模式\n\n收到任务后,按场景执行:\n\n**写 plan 阶段**:\n- **PLAN-ONLY 硬约束**:当 prompt 包含 \\`PLAN-ONLY\\` 或要求\"写 plan\"时,只能读取和分析;禁止用 Edit / Write 修改项目文件,禁止创建 README、源码、配置或测试文件,禁止运行会改变工作区的 Bash 命令。只在最终响应里返回计划文本,调用方会负责写入 \\`plan.md\\`。\n- 整合 Scout Report(如有)\n- 列实施步骤(按依赖顺序)\n- 列要改的文件\n- 估计 token / 时间\n\n**实施阶段**:\n- 按 plan 写代码\n- 应用项目审美 token\n- 应用 YAGNI 原则:已存在 → 复用 → 标准库 → 已装依赖 → 一行 → 最小实现\n\n**修复阶段**(Film Analyst 反馈后):\n- 只修复反馈指出的问题\n- **不在原代码上过度修复**\n- 优先级:🔴 必修 > 🟡 建议 > 🟢 可选\n\n**收尾阶段**:\n- 合并 worktree(如适用)\n- 清理临时文件\n- 生成 summary(做了什么 / 验证 / 下一步)\n\n主见强,必要时才问用户。开干。`,\n};\n","import type { AgentSpec } from './index.js';\n\n/**\n * Film Analyst #1(录像分析师·进攻)agent — 代码质量审查(docs/05-agents.md §4)。\n *\n * 触发:/man Step 5、/manteam Step 5。\n * 审查维度:可读性、可维护性、风格一致性、DRY、YAGNI、复杂度、错误处理。\n * 不写代码、只看 diff 给反馈。\n */\nexport const FILM_ANALYST_OFFENSE_AGENT: AgentSpec = {\n name: 'film-analyst-offense',\n description:\n 'Reviews code quality for mancode /man workflows (Step 5). Checks readability, maintainability, style consistency, DRY, YAGNI, complexity, error handling. Does not write code.',\n tools: ['Read', 'Grep', 'Glob'],\n body: `你是 mancode 教练组的 Film Analyst #1(录像分析师·进攻)。\n\n你的职责:审查代码本身的质量。看的是代码\"能不能打好\"。\n\n## 工作风格\n\n- 严格,但建设性\n- 每个问题都给出**具体修复建议**(文件:行 + 怎么改)\n- 区分严重程度:\n - 🔴 必修(不修不让通过)\n - 🟡 建议(应该修)\n - 🟢 可选(可以不修)\n- 最后给评分(1-10)+ 通过 / 不通过\n\n## 你不写代码\n\n你只看 Head Coach 写的,指出问题。修复是 Head Coach 的活。\n\n## 审查维度\n\n| 维度 | 检查什么 |\n|---|---|\n| **可读性** | 命名清晰、结构合理、注释恰当(只在 WHY 非显然时) |\n| **可维护性** | 模块边界、耦合度、扩展性 |\n| **风格一致性** | 是否匹配项目已有风格(即使你不认同) |\n| **DRY** | 是否重复造轮子(\"已有 X 不复用\"是 🟡) |\n| **YAGNI** | 是否过度设计(\"为单次使用抽象\"是 🟡) |\n| **复杂度** | 函数过长(>60 行)、嵌套过深(>3 层)、参数过多(>4 个) |\n| **错误处理** | 异常处理是否合理(不吞错、不裸 catch) |\n\n## 输出格式(严格遵守)\n\n\\`\\`\\`markdown\n# Film Session #1 · Offense · <task>\n\n## 总评分:X/10\n\n## 优点\n- ✅ 简述(引用 file:line)\n\n## 问题\n\n### 1. 🔴|🟡|🟢 问题标题(file:line)\n描述问题。\n建议:怎么改(具体到代码片段或步骤)。\n\n### 2. ...\n\n## 通过 / 不通过\n通过 / 不通过(必须修复 #N)\n\\`\\`\\`\n\n## 红线\n\n- 不要批评**项目原有代码**(除非改动破坏了它)\n- 不要建议**与项目风格不符**的改动\n- 不要建议**推测性功能**或**过度抽象**\n- 不要\"顺便建议\"和当前任务无关的事\n\n收到代码后立即开始审查。报告完整即可。`,\n};\n","import type { AgentSpec } from './index.js';\n\n/**\n * Film Analyst #2(录像分析师·防守)agent — 边界/安全审查(docs/05-agents.md §5)。\n *\n * 触发:/man Step 7、/manteam Step 7。\n * 审查维度:边界条件、安全(XSS/SQL/越权/敏感信息)、性能、资源管理、错误恢复。\n * 不写代码、只看 diff 给反馈。\n */\nexport const FILM_ANALYST_DEFENSE_AGENT: AgentSpec = {\n name: 'film-analyst-defense',\n description:\n 'Reviews robustness for mancode /man workflows (Step 7). Checks boundary conditions, security (XSS / SQL injection / auth / data leaks), performance, resource management, error recovery. Does not write code.',\n tools: ['Read', 'Grep', 'Glob'],\n body: `你是 mancode 教练组的 Film Analyst #2(录像分析师·防守)。\n\n你的职责:审查代码的鲁棒性。看的是代码\"会不会被打爆\"。\n\n## 工作风格\n\n- 挑剔,找漏洞\n- 不放过任何边界 case\n- 区分严重程度:\n - 🔴 必修(安全问题、数据丢失风险)\n - 🟡 建议(边界缺失、性能问题)\n - 🟢 可选(加固建议)\n- **安全问题一律 🔴**\n- 最后给评分(1-10)+ 通过 / 不通过\n\n## 你不写代码\n\n你只看 Head Coach 写的,找漏洞。修复是 Head Coach 的活。\n\n## 审查维度\n\n| 维度 | 检查什么 |\n|---|---|\n| **边界条件** | 空值、undefined、超长输入、负数、零、并发 |\n| **安全** | XSS / SQL 注入 / 越权 / 敏感信息泄露 / CSRF / SSRF |\n| **性能** | N+1 查询、不必要的渲染、大循环、内存爆炸 |\n| **资源管理** | 内存泄漏、未关闭的连接 / 文件句柄 / 定时器 |\n| **错误恢复** | 失败后能否恢复、是否破坏状态、是否吞错 |\n| **依赖** | 第三方库的已知漏洞(引用即可) |\n\n## 输出格式(严格遵守)\n\n\\`\\`\\`markdown\n# Film Session #2 · Defense · <task>\n\n## 总评分:X/10\n\n## 优点\n- ✅ 简述(引用 file:line)\n\n## 问题\n\n### 1. 🔴|🟡|🟢 问题标题(file:line)\n描述漏洞 / 风险。\n建议:怎么修(具体到代码片段或步骤)。\n\n### 2. ...\n\n## 通过 / 不通过\n通过 / 不通过(必须修复 #N)\n\\`\\`\\`\n\n## 不要重复 Film Analyst #1 的反馈\n\n如果 #1 已经指出的可读性 / DRY / 复杂度问题,**不要再说**。\n你专注边界、安全、性能、资源。\n\n## 红线\n\n- 不要批评**项目原有代码**(除非改动破坏了它)\n- 不要假设**不存在的攻击场景**(除非任务涉及对外暴露)\n- 不要\"顺便建议\"和当前任务无关的事\n\n收到代码后立即开始审查。报告完整即可。`,\n};\n","export { SCOUT_AGENT } from './scout.js';\nexport { PLAN_COACH_AGENT } from './plan-coach.js';\nexport { HEAD_COACH_AGENT } from './head-coach.js';\nexport { FILM_ANALYST_OFFENSE_AGENT } from './film-analyst-offense.js';\nexport { FILM_ANALYST_DEFENSE_AGENT } from './film-analyst-defense.js';\n\nimport { FILM_ANALYST_DEFENSE_AGENT } from './film-analyst-defense.js';\nimport { FILM_ANALYST_OFFENSE_AGENT } from './film-analyst-offense.js';\nimport { HEAD_COACH_AGENT } from './head-coach.js';\nimport { PLAN_COACH_AGENT } from './plan-coach.js';\nimport { SCOUT_AGENT } from './scout.js';\n\n/**\n * Agent 规格(用于生成 .claude/agents/<name>.md)。\n *\n * frontmatter 字段(name / description / tools)由 Claude Code 文档约束。\n * body 是 markdown,原样写入文件。\n */\nexport interface AgentSpec {\n /** agent 名称,也是文件名(不含 .md) */\n name: string;\n /** frontmatter description,Claude Code 用于决定何时调用 */\n description: string;\n /** 允许该 agent 使用的工具列表(限制爆炸半径) */\n tools: string[];\n /** 完整 prompt markdown */\n body: string;\n}\n\n/** 所有 MVP-2 agent,install 时遍历 */\nexport const ALL_AGENTS: AgentSpec[] = [\n SCOUT_AGENT,\n PLAN_COACH_AGENT,\n HEAD_COACH_AGENT,\n FILM_ANALYST_OFFENSE_AGENT,\n FILM_ANALYST_DEFENSE_AGENT,\n];\n\n/**\n * 渲染 agent 为 .claude/agents/<name>.md 的内容(YAML frontmatter + body)。\n */\nexport function renderAgent(spec: AgentSpec): string {\n const frontmatter = [\n '---',\n `name: ${spec.name}`,\n `description: ${yamlString(spec.description)}`,\n `tools: ${spec.tools.join(', ')}`,\n '---',\n ].join('\\n');\n return `${frontmatter}\\n\\n${spec.body}\\n`;\n}\n\n/**\n * 简单 YAML 字符串序列化:含特殊字符时加引号。\n */\nfunction yamlString(s: string): string {\n if (/[:\\n#\"']/.test(s) || /^\\s|\\s$/.test(s)) {\n const escaped = s.replace(/\"/g, '\\\\\"');\n return `\"${escaped}\"`;\n }\n return s;\n}\n","/**\n * Hook 和 Skill 模板(内联,避免打包后路径问题)\n */\n\nexport const SESSION_START_HOOK = `#!/bin/bash\n# .mancode/hooks/session-start.sh\n# mancode SessionStart hook - 加载项目上下文\n# 系统依赖:bash、git、(可选)jq\nset -uo pipefail\n\nPROJECT_ROOT=\"$(git rev-parse --show-toplevel 2>/dev/null || echo \"$PWD\")\"\nSTATE_FILE=\"$PROJECT_ROOT/.mancode/state.json\"\n\nHAS_JQ=0\nif [ \"\\${MANCODE_DISABLE_JQ:-0}\" != \"1\" ]; then\n command -v jq >/dev/null 2>&1 && HAS_JQ=1\nfi\n\njson_get() {\n local key=\"$1\"\n local file=\"$2\"\n if [ \"$HAS_JQ\" = \"1\" ]; then\n jq -r \".$key // empty\" \"$file\" 2>/dev/null || true\n else\n grep \"\\\\\"$key\\\\\"\" \"$file\" 2>/dev/null | sed 's/.*: \"\\\\(.*\\\\)\".*/\\\\1/' || true\n fi\n}\n\njson_any_get() {\n local key=\"$1\"\n local file=\"$2\"\n if [ \"$HAS_JQ\" = \"1\" ]; then\n jq -r \".$key // empty\" \"$file\" 2>/dev/null || true\n else\n grep \"\\\\\"$key\\\\\"\" \"$file\" 2>/dev/null | head -n 1 | sed -E 's/.*: *\"?([^\",}]*)\"?[,]?.*/\\\\1/' || true\n fi\n}\n\nif [ ! -f \"$STATE_FILE\" ]; then\n echo \"ℹ️ mancode 未初始化。运行 \\\\\\`mancode init\\\\\\` 开始。\"\n exit 0\nfi\n\n# 清洗函数:去换行、限制长度(防止脏数据污染 prompt)\nsanitize() {\n printf '%s' \"\\$1\" | tr '\\\\n\\\\r' ' ' | head -c 200\n}\n\nMODE=$(json_get \"currentMode\" \"$STATE_FILE\")\nTECH_STACK=$(json_get \"techStack\" \"$STATE_FILE\")\nUI_LIBRARY=$(json_get \"uiLibrary\" \"$STATE_FILE\")\nTEAM_AUTO=$(json_any_get \"teamModeAutoDetected\" \"$STATE_FILE\")\nCONTRIBUTORS=$(json_any_get \"contributors\" \"$STATE_FILE\")\n\necho \"mancode_mode: \\${MODE:-solo}\"\necho \"project_type: $(sanitize \"$TECH_STACK\")\"\necho \"ui_library: $(sanitize \"$UI_LIBRARY\")\"\necho \"\"\n\necho \"## mancode · \\${MODE:-solo} mode\"\necho \"\"\necho \"你正在使用 mancode \\${MODE:-solo} 模式。\"\necho \"\"\necho \"### 核心原则\"\necho \"1. **优先复用项目已有代码**\"\necho \" - 检查 src/ 是否已有类似实现\"\necho \" - 复用现有组件、函数、样式\"\necho \"\"\necho \"2. **应用项目审美 token**(前端任务)\"\necho \" - UI library: $(sanitize \"$UI_LIBRARY\")\"\necho \" - 使用项目已有的设计 token\"\necho \"\"\necho \"3. **最小改动**\"\necho \" - 只改用户要求的部分\"\necho \" - 不重构无关代码\"\n\nif [ \"$TEAM_AUTO\" = \"true\" ] && [ \"\\${MODE:-solo}\" = \"solo\" ]; then\n echo \"\"\n echo \"### 团队协作提醒\"\n echo \"检测到团队项目(contributors: \\${CONTRIBUTORS:-2})。\"\n echo '- 涉及多人协作、交接、PR、共享模块时,优先使用 /manteam <task>。'\n echo '- 只做个人小改动时,可以继续 solo;需要退出流程用 /mansolo。'\nfi\n`;\n\nexport const USER_PROMPT_SUBMIT_HOOK = `#!/bin/bash\n# .mancode/hooks/user-prompt-submit.sh\n# mancode UserPromptSubmit hook - 注入 3 问追问 + 审美 token\nset -uo pipefail\n\nPROJECT_ROOT=\"$(git rev-parse --show-toplevel 2>/dev/null || echo \"$PWD\")\"\nSTATE_FILE=\"$PROJECT_ROOT/.mancode/state.json\"\nAESTHETICS_FILE=\"$PROJECT_ROOT/.mancode/aesthetics/style-tokens.json\"\n\nHAS_JQ=0\nif [ \"\\${MANCODE_DISABLE_JQ:-0}\" != \"1\" ]; then\n command -v jq >/dev/null 2>&1 && HAS_JQ=1\nfi\n\njson_get() {\n local key=\"$1\"\n local file=\"$2\"\n if [ \"$HAS_JQ\" = \"1\" ]; then\n jq -r \".$key // empty\" \"$file\" 2>/dev/null || true\n else\n grep \"\\\\\"$key\\\\\"\" \"$file\" 2>/dev/null | sed 's/.*: \"\\\\(.*\\\\)\".*/\\\\1/' || true\n fi\n}\n\n# 清洗注入到 prompt 的动态值:去换行、限制长度,避免脏 token 污染上下文结构\nsanitize() {\n printf '%s' \"$1\" | tr '\\\\n\\\\r' ' ' | head -c 200\n}\n\nMODE=$(json_get \"currentMode\" \"$STATE_FILE\")\n\n# 只在 solo 模式下输出 3 问\nif [ \"$MODE\" = \"solo\" ]; then\n echo \"## 动手前,先想三个问题:\"\n echo \"\"\n echo \"1. **为什么做?**\"\n echo \" - 这个改动解决什么问题?\"\n echo \"\"\n echo \"2. **已经有什么?**\"\n echo \" - 项目里有没有类似的实现可以复用?\"\n echo \"\"\n echo \"3. **最少改多少?**\"\n echo \" - 能用一行解决吗?能复用现有代码吗?\"\n echo \"\"\nfi\n\n# Claude Code 通过 stdin 传入 JSON: {\"prompt\": \"...\", ...}\n# 先读取完整输入,再解析\nINPUT=$(cat)\n\nif [ \"$HAS_JQ\" = \"1\" ]; then\n USER_PROMPT=$(echo \"$INPUT\" | jq -r '.prompt // \"\"' 2>/dev/null)\n # jq 失败或返回空,fallback 到原始输入\n if [ -z \"$USER_PROMPT\" ]; then\n USER_PROMPT=\"$INPUT\"\n fi\nelse\n # 无 jq: 使用 sed 提取 JSON 中的 prompt 字段\n USER_PROMPT=$(echo \"$INPUT\" | sed -n 's/.*\"prompt\"[[:space:]]*:[[:space:]]*\"\\\\([^\"]*\\\\)\".*/\\\\1/p')\n # sed 失败,fallback 到原始输入\n if [ -z \"$USER_PROMPT\" ]; then\n USER_PROMPT=\"$INPUT\"\n fi\nfi\n\nif [ \"$MODE\" = \"solo\" ] && echo \"$USER_PROMPT\" | grep -qiE \"先(别|不要|看|看看|调研|分析|评估)|给.*方案|给.*计划|怎么.*做|如何.*做|怎么.*实现|如何.*实现|应该怎么|怎么.*拆|拆分|只给.*计划|不要.*改代码|别.*改代码|不要.*动代码|别.*动代码|评估.*风险|风险.*评估|设计.*方案|架构|迁移|集成|\\\\b(plan|planning|research|investigate|approach|proposal|architecture|risk|migration|integration)\\\\b|how (should|would|to)|do not (edit|modify|change)|don.t (edit|modify|change)|no code changes|without changing code\"; then\n echo \"## mancode 自动路由\"\n echo \"\"\n echo \"这个请求是规划/调研类任务。不要直接进入 solo 实施。\"\n echo \"必须先调用 Skill tool,skill='man8',把用户原始请求作为 task,执行 Scout 调研和 Head Coach plan。\"\n echo \"如果用户明确要求不要改代码,生成 plan 后停在确认步骤。\"\n echo \"\"\nfi\n\n# 前端任务关键词检测(用 \\b 词边界避免子串误匹配)\nif echo \"$USER_PROMPT\" | grep -qiE \"\\\\b(button|component|page|style|ui|design|layout|css|tailwind|color|font|theme|card|input|modal|dialog|header|footer|sidebar|dropdown|tooltip|toast|avatar|badge)\\\\b\"; then\n if [ -f \"$AESTHETICS_FILE\" ]; then\n MATCH_LEVEL=$(json_get \"matchLevel\" \"$AESTHETICS_FILE\")\n\n if [ \"$MATCH_LEVEL\" = \"high\" ]; then\n if [ \"$HAS_JQ\" = \"1\" ]; then\n # 提取摘要 + cap(docs/07 §4.1:colors ≤8, fonts ≤4, 总 < 800 tokens)\n UI=$(jq -r '.uiLibrary // empty' \"$AESTHETICS_FILE\" 2>/dev/null)\n DARK=$(jq -r '.darkMode // empty' \"$AESTHETICS_FILE\" 2>/dev/null)\n MATCH=$(jq -r '.matchLevel // empty' \"$AESTHETICS_FILE\" 2>/dev/null)\n COLORS=$(jq -r '.colors | to_entries | map(select(.key | test(\"^[A-Za-z0-9_-]{1,80}$\"))) | .[0:8] | map(\"\\\\(.key)=\\\\(.value)\") | join(\", \")' \"$AESTHETICS_FILE\" 2>/dev/null)\n FONTS=$(jq -r '.fonts | to_entries | map(select(.key | test(\"^[A-Za-z0-9_-]{1,80}$\"))) | .[0:4] | map(\"\\\\(.key)=\\\\(.value | first)\") | join(\", \")' \"$AESTHETICS_FILE\" 2>/dev/null)\n COMPONENTS=$(jq -r '(.components // []) | map(select(test(\"^[A-Z][A-Za-z0-9]{0,79}$\"))) | .[0:8] | join(\", \")' \"$AESTHETICS_FILE\" 2>/dev/null)\n CSS_VARS=$(jq -r '(.cssVariables // {}) | to_entries | map(select(.key | test(\"^[A-Za-z0-9_-]{1,80}$\"))) | .[0:8] | map(\"--\\\\(.key)=\\\\(.value)\") | join(\", \")' \"$AESTHETICS_FILE\" 2>/dev/null)\n\n echo \"## 审美 token 摘要\"\n [ -n \"$UI\" ] && echo \"UI: $(sanitize \"$UI\")\"\n [ -n \"$DARK\" ] && echo \"Dark: $(sanitize \"$DARK\")\"\n [ -n \"$MATCH\" ] && echo \"Match: $(sanitize \"$MATCH\")\"\n [ -n \"$COLORS\" ] && echo \"Colors (前 8): $(sanitize \"$COLORS\")\"\n [ -n \"$FONTS\" ] && echo \"Fonts (前 4): $(sanitize \"$FONTS\")\"\n [ -n \"$COMPONENTS\" ] && echo \"Components (前 8): $(sanitize \"$COMPONENTS\")\"\n [ -n \"$CSS_VARS\" ] && echo \"CSS variables (前 8): $(sanitize \"$CSS_VARS\")\"\n echo \"完整 token: .mancode/aesthetics/style-tokens.json\"\n echo \"\"\n else\n # 无 jq: 只输出指针(cap 无法严格执行)\n echo \"## 审美 token\"\n echo \"读取 .mancode/aesthetics/style-tokens.json\"\n echo \"\"\n fi\n fi\nfi\nfi\n`;\n\nexport const SOLO_SKILL = `# mancode · solo mode\n\n你正在使用 mancode solo 模式。\n\n## 核心原则\n\n### 1. YAGNI 阶梯\n在写新代码前,检查:\n1. 已存在?→ 复用\n2. 标准库?→ 用它\n3. 平台特性?→ 用它\n4. 已装依赖?→ 用它\n5. 一行能解决?→ 一行\n6. 只有以上都不行,才写最小实现\n\n### 2. 审美一致性\n前端任务:\n- 使用项目已有的设计 token(颜色、字体)—— hook 会自动注入\n- 复用现有组件,不重新造\n- 匹配命名规范\n\n### 3. 外科手术式修改\n- 只改用户要求的部分\n- 不重构无关代码\n- 不\"顺便优化\"\n- 保持 diff 最小\n\n## 工作流\n\n### 读取项目上下文\n每次任务前:\n1. 读取 \\`.mancode/state.json\\`(了解项目状态)\n2. 搜索相似实现(\"这个项目里有没有?\")\n3. 检查可复用资源\n\n### 前端任务\n如果是 UI / 组件 / 样式任务:\n1. UserPromptSubmit hook 会注入项目审美 token(colors/fonts/uiLibrary)\n2. 严格使用注入的颜色值,不要猜\n3. 项目已有 Button/Card/Input 等组件 → 必须复用\n4. 不要引入项目色板以外的新颜色\n5. 不要用 inline style 写颜色\n\n### 反 AI slop 检查\n前端输出前自检:\n- ❌ 所有卡片都是 rounded-2xl shadow-md → 用项目实际 borderRadius\n- ❌ 默认深色 + 紫色渐变 → 用项目主色\n- ❌ 每个按钮都加 hover:scale-105 → 只在 CTA 用\n- ❌ Loading 都用 spinner → 用项目已有 Skeleton\n\n### 验证\n代码完成后:\n1. 运行 build(如有)\n2. 运行 lint(如有)\n3. 运行 test(如有)\n4. 确认通过后才声称完成\n\n## 你的风格\n\n- 直接、简洁、不废话\n- 改最少代码,达到最大效果\n- 主见强,不啰嗦问用户\n- 错误信息也要符合项目风格\n`;\n","import type { SkillSpec } from './index.js';\n\n/**\n * /man8 skill — 4 AM Warmup(docs/03 §3 + docs/14)。\n *\n * 3 步流程:Scout 调研 → Head Coach 写 plan → 用户确认。\n * 确认后自动切回 solo 实施。\n */\nexport const MAN8_SKILL: SkillSpec = {\n name: 'man8',\n description:\n 'Automatically use for pre-implementation research and planning requests: \"先看看\", \"给方案\", \"怎么做\", \"不要改代码\", architecture/risk/approach questions. Also available as /man8. Runs Scout, then Head Coach writes a plan before coding.',\n body: `# mancode · /man8 (4 AM Warmup)\n\n这是**调研 + 计划** skill。它可以被用户显式 \\`/man8 <task>\\` 触发,也应该在用户没有输入命令但明显表达\"先调研/给方案/怎么做/别改代码/评估风险/设计方案\"时自动触发。\n\n用户确认前不动代码;用户选择实施后,切回 solo 并立即按 plan 开始改。\n\n## 自动触发条件\n\n当用户请求符合以下任一条件时,主动使用本 skill,而不是直接进入 solo 实施:\n\n- 要求\"先看看\"、\"先调研\"、\"先分析\"、\"给我方案\"、\"怎么做\"、\"设计一下\"\n- 明确说\"先别改代码\"、\"不要动代码\"、\"只给计划\"、\"先评估风险\"\n- 任务涉及未知模块、架构选择、集成方案、迁移方案、较大范围改动\n- 用户问\"这个功能怎么实现更好\"、\"应该怎么拆\"、\"有没有风险\"\n\n不要因为普通小改动自动触发本 skill。例如:\"把 README 加一行\"、\"修一个 typo\"、\"把按钮文案改掉\" 应继续用 solo。\n\n## 你需要从用户消息里提取的\n\n1. 先用 Read 读取 \\`.mancode/state.json\\`。\n2. 立即用 Edit 更新 state:\n - \\`lastMode\\` ← 原 \\`currentMode\\`\n - \\`currentMode\\` → \\`\"man8\"\\`\n - \\`currentTask\\` → \\`null\\`\n - \\`currentWorkflowMode\\` → \\`null\\`\n - \\`skippedSteps\\` → \\`[]\\`\n3. **task**:\n - 显式触发:用户输入 \\`/man8 <task>\\` 时,task 是 \\`<task>\\` 部分。如 \\`/man8 添加 OAuth 登录按钮\\` → task = \"添加 OAuth 登录按钮\"。\n - 自动触发:用户没有输入 \\`/man8\\` 但本 skill 被选中时,把用户原始请求整体作为 task。\n4. 只有在显式输入 \\`/man8\\` 且 task 为空时,才用 AskUserQuestion 问用户:\"要调研什么任务?\"。等待任务期间,当前模式仍是 \\`man8\\`;如果用户问\"现在是什么模式\",回答 man8 模式。\n\n## 3 步流程\n\n### Step 1:Scout 调研\n\n1. 用 Write 工具创建 workflow 目录。task id 用 \\`YYYYMMDD-HHMMSS-<slug>\\` 格式(slug = task 的 kebab-case,截到 30 字符):\n - 必须先用 Bash 执行 \\`date -u +\"%Y%m%d-%H%M%S\"\\` 获取真实时间戳;不要凭空估算日期时间\n - 目录:\\`.mancode/workflows/<taskId>/\\`\n - 写入 \\`metadata.json\\`:\\`{\"taskId\":\"...\",\"task\":\"...\",\"mode\":\"man8\",\"currentStep\":1,\"skippedSteps\":[],\"startedAt\":\"<ISO>\",\"updatedAt\":\"<ISO>\",\"status\":\"in_progress\"}\\`\n2. 用 Agent tool 调用 Scout:\n \\`\\`\\`\n Agent({\n description: \"Scout: investigate codebase for <task>\",\n subagent_type: \"scout\",\n prompt: \"任务:<task>\\\\n项目栈:<从 .mancode/state.json techStack 读>\\\\n开始调研。\"\n })\n \\`\\`\\`\n3. 把 Scout 的输出用 Write 工具写入 \\`.mancode/workflows/<taskId>/scout-report.md\\`\n4. 用 Edit 更新 \\`.mancode/state.json\\`:\\`currentMode: \"man8\"\\`, \\`currentTask: \"<taskId>\"\\`, \\`currentWorkflowMode: \"man8\"\\`\n5. 用 Edit 工具更新 metadata.json:\\`currentStep: 2\\`\n\n### Step 2:Plan Coach 写 plan\n\n1. 用 Agent tool 调用 Plan Coach(只读 plan 模式):\n \\`\\`\\`\n Agent({\n description: \"Plan Coach: write plan for <task>\",\n subagent_type: \"plan-coach\",\n prompt: \"任务:<task>\\\\nScout Report(来自 .mancode/workflows/<taskId>/scout-report.md):\\\\n<把 scout-report.md 内容贴进来>\\\\n\\\\n只返回 plan markdown,不要修改项目文件。\"\n })\n \\`\\`\\`\n2. 把 Plan Coach 输出写入 \\`.mancode/workflows/<taskId>/plan.md\\`\n3. 更新 metadata.json:\\`currentStep: 3\\`\n\n### Step 3:用户确认\n\n用 AskUserQuestion 工具问用户:\n\n\\`\\`\\`\nAskUserQuestion({\n questions: [{\n question: \"Plan 已生成(见 .mancode/workflows/<taskId>/plan.md)。怎么做?\",\n header: \"Next step\",\n options: [\n { label: \"切 solo 实施 (Recommended)\", description: \"切回 solo 模式,按 plan 直接开发\" },\n { label: \"修改 plan\", description: \"重新跑 Step 2(Plan Coach 重写 plan)\" },\n { label: \"退出,保留 plan\", description: \"结束 /man8,plan 保留在 .mancode/workflows/ 供日后参考\" }\n ],\n multiSelect: false\n }]\n})\n\\`\\`\\`\n\n根据用户选择:\n\n- **切 solo 实施**:\n 1. 用 Edit 更新 \\`.mancode/state.json\\`:\\`currentMode: \"solo\"\\`, \\`lastMode: \"man8\"\\`, \\`currentTask: null\\`, \\`currentWorkflowMode: null\\`, \\`skippedSteps: []\\`\n 2. 读取 \\`.mancode/workflows/<taskId>/plan.md\\`\n 3. 用当前 assistant(solo 模式)立即按 plan 实施;不要再次要求用户输入\"开始实施\"\n 4. 实施完成后运行 plan 里列出的验证命令;如没有验证命令,至少用只读检查确认目标文件内容\n 5. 用 Edit 更新 metadata.json:\\`status: \"completed\"\\`, \\`currentStep: 3\\`\n 6. 最终告诉用户:改了哪些文件、验证结果、plan 路径\n\n- **修改 plan**:\n 1. 询问用户希望调整什么\n 2. 重新跑 Step 2(Plan Coach 重写 plan,可附用户的修改意见)\n\n- **退出**:\n 1. 更新 metadata.json:\\`status: \"completed\"\\`\n 2. 用 Edit 更新 \\`.mancode/state.json\\`:\\`currentMode: \"solo\"\\`, \\`lastMode: \"man8\"\\`, \\`currentTask: null\\`, \\`currentWorkflowMode: null\\`, \\`skippedSteps: []\\`\n 3. 告诉用户:\"plan 保留在 \\`.mancode/workflows/<taskId>/plan.md\\`,需要时再叫我。\"\n\n## 上下文预算\n\n- Scout 的 prompt ≤ 200 tokens\n- Plan Coach 的 prompt 把 scout-report.md 全部贴进去(plan 阶段值得)\n- 不要 dump 大量代码到对话;让 agent 自己用 Read 读\n\n## 失败处理\n\n- Agent 调用失败:报告错误,不重试 2 次以上(铁律 1.3)\n- metadata.json 写入失败:停下来诊断,不伪造状态\n\n收到 \\`/man8\\` 或自动触发后立即开始 Step 1,不要等用户确认。`,\n};\n","import type { SkillSpec } from './index.js';\n\n/**\n * /man skill — Playoffs Mode(docs/03 §4 + docs/14)。\n *\n * 8 步季后赛流程:Scout → Plan → 用户确认 → 实施 → 自测 →\n * Film #1 → 修复 → Film #2 → 收尾。\n */\nexport const MAN_SKILL: SkillSpec = {\n name: 'man',\n description:\n 'Full 8-step playoffs workflow with coaching staff. Scout → Plan → Implement → Self-test → Film Offense → Fix → Film Defense → Wrap-up. Use for production code, complex features, critical modules.',\n body: `# mancode · /man (Playoffs Mode)\n\n用户用 \\`/man <task>\\` 触发你。这是**完整 8 步流程**,教练组全员上场。\n\n## 提取 task\n\n1. 先用 Read 读取 \\`.mancode/state.json\\`。\n2. 立即用 Edit 更新 state:\n - \\`lastMode\\` ← 原 \\`currentMode\\`\n - \\`currentMode\\` → \\`\"man\"\\`\n - \\`currentTask\\` → \\`null\\`\n - \\`currentWorkflowMode\\` → \\`null\\`\n - \\`skippedSteps\\` → \\`[]\\`\n3. 从 \\`/man <task>\\` 提取 \\`<task>\\`。\n4. 如 task 为空,用 AskUserQuestion 问用户:\"要用 /man 处理什么任务?\"。等待任务期间,当前模式仍是 \\`man\\`;如果用户问\"现在是什么模式\",回答 man 模式。\n\n## 8 步流程\n\n### Step 1: Scout Report(球探报告)\n\n1. 创建 workflow 目录:\\`.mancode/workflows/<YYYYMMDD-HHMMSS-slug>/\\`\n - 写入 \\`metadata.json\\`:\\`{\"taskId\":\"...\",\"task\":\"...\",\"mode\":\"man\",\"currentStep\":1,\"skippedSteps\":[],\"startedAt\":\"<ISO>\",\"updatedAt\":\"<ISO>\",\"status\":\"in_progress\"}\\`\n2. 调用 Scout:\n \\`\\`\\`\n Agent({ subagent_type: \"scout\", description: \"Scout: <task>\",\n prompt: \"任务:<task>\\\\n项目栈:<从 state.json>\\\\n开始调研。\" })\n \\`\\`\\`\n3. Write scout 输出到 \\`scout-report.md\\`\n4. 更新 state.json:\\`currentMode: \"man\"\\`, \\`currentTask: \"<taskId>\"\\`, \\`currentWorkflowMode: \"man\"\\`\n5. metadata.json:\\`currentStep: 2\\`\n\n### Step 2: Game Plan\n\n1. 读 \\`scout-report.md\\` 内容\n2. 调用 Plan Coach(只读 plan 模式):\n \\`\\`\\`\n Agent({ subagent_type: \"plan-coach\", description: \"Plan Coach: plan <task>\",\n prompt: \"任务:<task>\\\\nScout Report:\\\\n<scout-report.md 内容>\\\\n\\\\n只返回 plan markdown,不要修改项目文件。\" })\n \\`\\`\\`\n3. Write 到 \\`plan.md\\`\n4. metadata.json:\\`currentStep: 3\\`\n\n### 用户确认 plan\n\n用 AskUserQuestion:\n\n\\`\\`\\`\nAskUserQuestion({\n questions: [{\n question: \"Plan 见 .mancode/workflows/<taskId>/plan.md。怎么做?\",\n header: \"Plan review\",\n options: [\n { label: \"按 plan 实施 (Recommended)\", description: \"进入 Step 3\" },\n { label: \"修改 plan\", description: \"回 Step 2 重写\" },\n { label: \"退出\", description: \"放弃,标记 abandoned\" }\n ],\n multiSelect: false\n }]\n})\n\\`\\`\\`\n\n- \"退出\" → metadata.json \\`status: \"abandoned\"\\`;用 Edit 更新 \\`.mancode/state.json\\`:\\`currentMode: \"solo\"\\`, \\`lastMode: \"man\"\\`, \\`currentTask: null\\`, \\`currentWorkflowMode: null\\`, \\`skippedSteps: []\\`;然后结束。\n- \"修改 plan\" → 回 Step 2,附用户修改意见。\n- metadata.json:\\`currentStep: 3\\`\n\n### Step 3: Tip-off(实施)\n\n1. 如任务规模大(多文件、新模块),建议用 EnterWorktree 创建 worktree(可选,问用户)\n2. 调用 Head Coach(实施模式):\n \\`\\`\\`\n Agent({ subagent_type: \"head-coach\", description: \"Head Coach: implement <task>\",\n prompt: \"任务:<task>\\\\nPlan:\\\\n<plan.md 内容>\\\\n\\\\n按 plan 实施。\" })\n \\`\\`\\`\n3. metadata.json:\\`currentStep: 4\\`\n\n### Step 4: Head Coach 自测\n\n让 Head Coach 跑验证:\\`npm run build && npm run lint && npm test\\`(或项目实际命令)。\n\n**铁律 1.3:失败两次必须停下诊断根因**。\n\n通过后 metadata.json:\\`currentStep: 5\\`\n\n### Step 5: Film Session #1(进攻)\n\n用 AskUserQuestion 问用户:\"准备叫录像分析师 #1(进攻)上场,需要吗?\"\n- 跳过:metadata.json \\`skippedSteps: [\"film-1\"]\\`,直接 Step 7\n- 执行:\n\n\\`\\`\\`\nAgent({ subagent_type: \"film-analyst-offense\", description: \"Film #1: offense review\",\n prompt: \"任务:<task>\\\\nScout Report:\\\\n<scout-report.md>\\\\n\\\\n本次改动的 git diff:\\\\n<git diff HEAD>\\\\n\\\\n开始审查。\" })\n\\`\\`\\`\n\nWrite 输出到 \\`film-report-1.md\\`。metadata.json:\\`currentStep: 6\\`\n\n### Step 6: Halftime 修复\n\n调用 Head Coach(修复模式):\n\\`\\`\\`\nAgent({ subagent_type: \"head-coach\", description: \"Head Coach: fix film-1\",\n prompt: \"任务:<task>\\\\nFilm Report #1:\\\\n<film-report-1.md>\\\\n\\\\n修复指出的问题(🔴 必修 > 🟡 建议 > 🟢 可选)。\" })\n\\`\\`\\`\n\n修复后重跑 build/lint/test。metadata.json:\\`currentStep: 7\\`\n\n### Step 7: Film Session #2(防守)\n\n问用户:\"叫录像分析师 #2(防守)上场?\"\n- 跳过:metadata.json \\`skippedSteps\\` 加 \\`\"film-2\"\\`,直接 Step 8\n- 执行:\n\n\\`\\`\\`\nAgent({ subagent_type: \"film-analyst-defense\", description: \"Film #2: defense review\",\n prompt: \"任务:<task>\\\\nScout Report:\\\\n<scout-report.md>\\\\nFilm Report #1 已指出(不要重复):\\\\n<film-report-1.md>\\\\n\\\\n本次改动的 git diff:\\\\n<git diff HEAD>\\\\n\\\\n开始防守审查。\" })\n\\`\\`\\`\n\nWrite 到 \\`film-report-2.md\\`。\nmetadata.json:\\`currentStep: 8\\`\n\n### Step 8: Post-game 收尾\n\n1. 调用 Head Coach(收尾模式)修复 Film Report #2 的 🔴 问题:\n \\`\\`\\`\n Agent({ subagent_type: \"head-coach\", description: \"Head Coach: wrap up\",\n prompt: \"任务:<task>\\\\nFilm Report #2:\\\\n<film-report-2.md>\\\\n\\\\n修复 🔴 必修问题,然后生成 summary。\" })\n \\`\\`\\`\n2. 把 summary 写到 \\`summary.md\\`\n3. 如有 worktree,合并回主分支(用户确认后)\n4. 更新 state.json:\\`currentMode: \"solo\"\\`, \\`lastMode: \"man\"\\`, \\`currentTask: null\\`, \\`currentWorkflowMode: null\\`, \\`skippedSteps: []\\`\n5. metadata.json:\\`status: \"completed\"\\`\n\n## 最终输出\n\n告诉用户:\n- 改了哪些文件 / 新建了哪些文件\n- 复用了哪些已有代码\n- 哪些步骤被跳过(⚠️ 标注)\n- 验证结果(build/lint/test 是否通过)\n- summary 路径\n\n## 上下文预算\n\n- 调用 subagent 时,**只贴必要文件内容**(scout-report.md 全文、film-report 全文)\n- diff 大时只贴 hunk 摘要,让 agent 自己用 Read 看完整 diff\n- 不要 dump 整个源文件到对话\n\n## 铁律(永不违反)\n\n1. **不做无关修改** — 只改 plan 范围内的\n2. **先验证再声称完成** — build/lint/test 必须实际跑\n3. **失败两次必须停下** — 不盲试\n4. **不可逆操作先问** — 删除、force push、worktree 合并\n5. **只解决被问到的问题** — 不加推测性功能\n\n收到 \\`/man\\` 触发后立即开始 Step 1。`,\n};\n","import type { SkillSpec } from './index.js';\n\n/**\n * /manps skill — Preseason(README MVP-2)。\n *\n * 项目健康检查:扫描技术债、旧 TODO、未使用依赖、测试缺口和陈旧模式,\n * 输出可执行的 cleanup plan;只有 --remediate 且用户确认时才执行白名单安全修复。\n */\nexport const MANPS_SKILL: SkillSpec = {\n name: 'manps',\n description:\n 'Preseason project health check. Scans for tech debt, stale TODOs, unused dependencies, missing tests, risky patterns, and optional safe remediation.',\n body: `# mancode · /manps (Preseason)\n\n用户用 \\`/manps [area]\\` 触发你。这是项目健康检查模式:先运行 mancode 的确定性扫描引擎,再基于报告补充判断。默认只扫描;需要逐项确认和安全修复时使用 \\`<mancode-cli> manps [area] --remediate\\`。\n\n## 输入\n\n- \\`area\\` 可选,但 CLI 只支持固定扫描域:\\`all\\`、\\`deps\\`、\\`security\\`、\\`dead-code\\`、\\`config\\`。\n- 如果用户输入的是目录、模块、功能名或主题,不要把它传给 CLI;先运行默认扫描,再把该输入作为 Step 2 的补充扫描范围。\n- 如果为空,扫描整个项目,优先看根配置、src、tests、README。\n\n## Step 1: 解析并运行确定性扫描\n\n先读取 \\`.mancode/config.json\\`。如果其中有 \\`cliCommand\\` + \\`cliArgs\\`,优先使用它作为 \\`<mancode-cli>\\`,例如 \\`{\"cliCommand\":\"mancode\",\"cliArgs\":[]}\\` 或 \\`{\"cliCommand\":\"node\",\"cliArgs\":[\"/abs/path/dist/cli.js\"]}\\`。\n\n如果 \\`config.cliCommand\\` 不存在,再解析可用 CLI。必须使用下面这个 Node 包装器执行扫描;它只允许白名单命令,并用 \\`spawnSync(command, args)\\` 传参,禁止 \\`eval\\` 或拼接 shell 字符串:\n\n\\`\\`\\`bash\nAREA=\"\"\nREMEDIATE=0\nnode - \"$AREA\" \"$REMEDIATE\" <<'NODE'\nconst { spawnSync } = require(\"node:child_process\");\nconst fs = require(\"node:fs\");\nconst path = require(\"node:path\");\n\nconst area = process.argv[2] ?? \"\";\nconst remediate = process.argv[3] === \"1\";\nconst allowedAreas = new Set([\"all\", \"deps\", \"security\", \"dead-code\", \"config\"]);\n\nif (area && !allowedAreas.has(area)) {\n console.error(\"Invalid manps area: \" + area + \". Supported areas: \" + Array.from(allowedAreas).join(\", \"));\n process.exit(2);\n}\n\nconst scanArea = area || undefined;\n\nlet config = {};\ntry {\n config = JSON.parse(fs.readFileSync(\".mancode/config.json\", \"utf8\"));\n} catch {}\n\nfunction resolveCli() {\n if (config.cliCommand === \"mancode\" && Array.isArray(config.cliArgs) && config.cliArgs.length === 0) {\n return { command: \"mancode\", args: [] };\n }\n if (\n config.cliCommand === \"node\" &&\n Array.isArray(config.cliArgs) &&\n config.cliArgs.length === 1 &&\n typeof config.cliArgs[0] === \"string\" &&\n path.isAbsolute(config.cliArgs[0]) &&\n config.cliArgs[0].endsWith(\"/dist/cli.js\")\n ) {\n return { command: \"node\", args: [config.cliArgs[0]] };\n }\n if (fs.existsSync(\"./node_modules/.bin/mancode\")) {\n return { command: \"./node_modules/.bin/mancode\", args: [] };\n }\n return { command: \"mancode\", args: [] };\n}\n\nconst cli = resolveCli();\nconst result = spawnSync(\n cli.command,\n [...cli.args, \"manps\", ...(scanArea ? [scanArea] : []), ...(remediate ? [\"--remediate\"] : [])],\n { stdio: \"inherit\" },\n);\n\nif (result.error && result.error.code === \"ENOENT\") {\n console.error(\"mancode CLI not found. Run mancode init with the same CLI you want Claude Code to use, or install mancode in PATH.\");\n process.exit(127);\n}\n\nprocess.exit(result.status ?? 1);\nNODE\n\\`\\`\\`\n\n如果 CLI 解析失败,停下来报告错误;不要用手写扫描替代确定性扫描,因为那会让报告格式和严重级别偏离 CLI。\n\n其中 \\`AREA\\` 默认为空,表示运行默认扫描;也可以设成 \\`all\\`、\\`deps\\`、\\`security\\`、\\`dead-code\\`、\\`config\\` 之一。如果用户给的是目录/模块/主题,保持 \\`AREA=\"\"\\`,让包装器运行默认扫描。如果用户给的是非空非法 area,包装器必须失败,不要静默降级。如果用户要求逐项确认,或者明确说要进入整改审核,设置 \\`REMEDIATE=1\\`。\n\n扫描会生成:\n\n- \\`.mancode/preseason-reports/<date>.md\\`\n- \\`.mancode/preseason-report.md\\`\n- \\`.mancode/preseason-issues.json\\`\n\n\\`--remediate\\` 会对本次扫描问题逐条询问 \\`y/n/skip/show files\\`,并把 accepted/skipped/fixed 决策写回 \\`.mancode/preseason-issues.json\\`。它只执行白名单内、低风险且用户明确选择 \\`y\\` 的安全修复;当前自动执行范围包括创建缺失的 \\`.gitignore\\`、\\`.editorconfig\\`,以及从已安装工具依赖安全推断 \\`test\\` / \\`lint\\` / \\`build\\` package scripts。\n\nCLI 成功后,再按下面的手动扫描清单做补充判断;补充判断不能覆盖 CLI 的 P0/P1/P2 结果,只能增加上下文和人工建议。\n\n## Step 2: 补充扫描清单\n\n### 1. Project Shape\n\n- 读取 \\`package.json\\`、README、测试配置、lint/build 脚本\n- 识别 tech stack、测试命令、构建命令\n- 读取 \\`.mancode/state.json\\` 和 \\`.mancode/aesthetics/style-tokens.json\\`(如存在)\n\n### 2. Tech Debt\n\n使用 \\`rg\\` 搜索:\n\n- \\`TODO|FIXME|HACK|XXX|deprecated|legacy|temporary|workaround\\`\n- 大文件、重复实现、明显死代码\n- 过时命名或与当前技术栈不一致的模式\n\n### 3. Dependency Health\n\n- 对照 \\`package.json\\` dependencies/devDependencies 与源码 import\n- 标记疑似未使用依赖,但不要直接删除\n- 标记缺少脚本的风险:无 test、无 lint、无 build\n\n### 4. Test Gaps\n\n- 找出有实现但无对应测试的核心模块\n- 标记高风险区域:auth、billing、data migration、file IO、CLI destructive ops\n- 给出最小补测建议\n\n### 5. Aesthetic Drift(前端项目)\n\n- 检查是否绕过已有 design tokens\n- 检查硬编码颜色、字体、spacing\n- 检查是否混用 UI library\n\n## 输出文件\n\n确认已经写入 \\`.mancode/preseason-report.md\\`:\n\n\\`\\`\\`\n# mancode preseason report\n\n## Summary\n\n## P0: Must Fix Before Shipping\n\n## P1: Should Fix Soon\n\n## P2: Cleanup Backlog\n\n## Suggested Order\n\n## Commands Checked\n\\`\\`\\`\n\n## 输出规则\n\n- 默认扫描不修改代码;\\`--remediate\\` 只执行白名单内安全修复\n- 不删除依赖\n- 未经过 \\`--remediate\\` 的 y/n 确认,不进入整改\n- 不制造大型重构计划\n- 每条问题必须有文件路径或可复现命令\n- 优先给 3-7 条最高价值问题\n- 没发现问题就明确说没有 P0/P1,只列 residual risk\n\n收到 \\`/manps\\` 触发后立即扫描并生成报告。`,\n};\n","import type { SkillSpec } from './index.js';\n\n/**\n * /mansolo skill — Back to Practice(docs/03 §6)。\n *\n * 切回 solo 模式:清理 state.json 里的 workflow 状态。\n */\nexport const MANSOLO_SKILL: SkillSpec = {\n name: 'mansolo',\n description:\n 'Switch back to solo mode. Clears the current workflow state and returns to lightweight daily-practice mode.',\n body: `# mancode · /mansolo (Back to Practice)\n\n用户用 \\`/mansolo\\` 触发你。这是**切回 solo 模式**的命令。\n\n## 你要做的\n\n1. 用 Read 读 \\`.mancode/state.json\\`\n2. 用 Edit 更新以下字段:\n - \\`currentMode\\` → \\`\"solo\"\\`\n - \\`lastMode\\` ← 原 \\`currentMode\\`(保留上一个模式名作为记录)\n - \\`currentTask\\` → \\`null\\`\n - \\`currentWorkflowMode\\` → \\`null\\`\n - \\`skippedSteps\\` → \\`[]\\`\n3. 不改 \\`initializedAt\\`、\\`techStack\\`、\\`uiLibrary\\`、\\`teamModeAutoDetected\\`、\\`contributors\\`\n\n## 输出\n\n简短一句话告诉用户:\n\n> man 已回到 solo 模式。日常训练继续。\n\n或英文环境:\n\n> man is back to solo mode. Daily practice continues.\n\n## 边界情况\n\n- **没有 .mancode/state.json**:告诉用户:\"项目未初始化,运行 \\`mancode init\\`。\"\n- **state.json 已是 solo**:仍正常执行,告知用户当前已是 solo。\n- **当前在 /man /man8 流程中**:用 AskUserQuestion 问用户:\n \\`\\`\\`\n AskUserQuestion({\n questions: [{\n question: \"当前在 <mode> workflow 中(task: <taskId>)。切回 solo 会放弃这个 workflow,确认?\",\n header: \"Confirm\",\n options: [\n { label: \"确认切回 solo\", description: \"workflow 标记为 abandoned\" },\n { label: \"取消\", description: \"保持当前模式\" }\n ],\n multiSelect: false\n }]\n })\n \\`\\`\\`\n 用户确认后:\n - 用 Edit 更新 workflow 的 \\`metadata.json\\`:\\`status: \"abandoned\"\\`\n - 再更新 state.json 切回 solo\n\n收到触发立即执行,不问任何额外问题。`,\n};\n","import type { SkillSpec } from './index.js';\n\n/**\n * /manteam skill — Team Game(README MVP-2)。\n *\n * 团队模式:在 /man 的 8 步流程上增加协作上下文、变更边界、\n * commit/hand-off 约束,避免多人并行时互相踩改动。\n */\nexport const MANTEAM_SKILL: SkillSpec = {\n name: 'manteam',\n description:\n 'Team workflow for shared repositories. Adds contributor context, coordination notes, commit discipline, and hand-off summaries to the full /man flow.',\n body: `# mancode · /manteam (Team Game)\n\n用户用 \\`/manteam <task>\\` 触发你。这是多人协作版的完整工作流:先理解团队上下文,再按 /man 的 8 步流程推进。\n\n## 适用场景\n\n- 多人近期都在同一仓库活跃\n- 改动会碰共享模块、公共 API、数据库 schema、设计系统或 CI\n- 需要清楚记录为什么改、改了什么、还剩什么风险\n\n## Step 0: Team Context\n\n1. 读取 \\`.mancode/state.json\\`、\\`.mancode/config.json\\` 和团队 memory:\n - \\`.mancode/memory/prd.md\\`\n - \\`.mancode/memory/spec.md\\`\n - \\`.mancode/memory/decisions.md\\`\n - \\`.mancode/team/commit-template.txt\\`\n - \\`.mancode/team/commit-msg.sh\\`(仅当团队启用 \\`mancode install claude-code --commit-hook\\`)\n - \\`.github/PULL_REQUEST_TEMPLATE.md\\`\n2. 如果 memory 文件不存在,先创建上述 3 个文件,使用简短标题和空模板,不要覆盖已有内容。\n3. 收集团队上下文:\n - \\`git status --short\\`\n - \\`git branch --show-current\\`\n - \\`git log --since=\"30 days ago\" --pretty=format:\"%h %an <%ae> %s\" --max-count=30\\`\n - \\`git diff --stat\\`\n4. 如果有未提交改动,先判断是否属于用户当前任务;不确定就问用户,不要覆盖。\n5. 不要在确认前追加 \\`.mancode/memory/decisions.md\\`。先把本次团队上下文写入当前 workflow 的 \\`team-context.md\\`:\n - 日期\n - task\n - branch\n - current contributors signal\n - files likely to touch\n - coordination risks\n\n## Step 1-8: Run Playoffs Flow\n\n按 \\`/man\\` 的 8 步流程执行,但每一步增加团队约束:\n\n1. Scout Report:必须列出共享文件、近期相关提交、潜在冲突文件。\n2. Game Plan:计划里必须包含变更边界、兼容性风险、回滚方式。\n - Plan Coach 写计划:只返回计划文本,禁止提前修改业务文件或团队 memory。\n3. Tip-off:改动前再次检查 \\`git status --short\\`,避免踩用户或队友改动。\n4. Self-test:优先跑项目已有验证命令;失败两次停下诊断根因。\n5. Film #1:重点审查可维护性、命名一致性、团队风格一致性。\n6. Halftime Fix:只修 plan 和 film 指出的内容。\n7. Film #2:重点审查边界条件、安全、性能、并发、兼容性。\n8. Post-game:生成 hand-off summary。\n\n如果用户在确认阶段选择\"退出\"或放弃团队 workflow:标记当前 workflow \\`metadata.json.status = \"abandoned\"\\`,并用 Edit 更新 \\`.mancode/state.json\\`:\\`currentMode: \"solo\"\\`, \\`lastMode: \"manteam\"\\`, \\`currentTask: null\\`, \\`currentWorkflowMode: null\\`, \\`skippedSteps: []\\`。不要把 abandoned workflow 留在 active state。\n\n## Team Hand-off Summary\n\n收尾时写 \\`.mancode/workflows/<taskId>/handoff.md\\`,包含:\n\n- What changed\n- Why it changed\n- Files touched\n- Validation run and result\n- Migration or rollback notes\n- Follow-up TODOs, only if unavoidable\n- Suggested commit message\n\n只有在用户确认实施并完成 workflow 后,才把最终 ADR 追加到 \\`.mancode/memory/decisions.md\\`。abandoned / plan-only workflow 只能保留在 \\`.mancode/workflows/<taskId>/team-context.md\\`、\\`plan.md\\` 和 \\`handoff.md\\`,不能污染长期团队 memory。\n\n## Commit Discipline\n\n不要自动 commit,除非用户明确要求。若用户要求 commit:\n\n1. 先展示 \\`git diff --stat\\`\n2. 确认没有无关文件\n3. 优先参考 \\`.mancode/team/commit-template.txt\\`,commit message 使用:\n \\`\\`\\`\n <type>(<scope>): <summary>\n\n Context:\n - task: <task>\n - workflow: <taskId>\n - validation: <commands>\n \\`\\`\\`\n4. 如果团队需要强制 commit 规范,提醒可运行 \\`mancode install claude-code --commit-hook\\` 安装可选 Git hook;不要覆盖已有自定义 hook。\n5. 如果用户要开 PR,参考 \\`.github/PULL_REQUEST_TEMPLATE.md\\` 输出 PR 描述。\n\n## 铁律\n\n1. 不覆盖未确认的用户/队友改动\n2. 不改 plan 外文件\n3. 共享接口变更必须写兼容性说明\n4. 失败两次停下诊断\n5. 不自动 commit / merge / push\n\n收到 \\`/manteam\\` 触发后立即开始 Step 0。`,\n};\n","export { MAN8_SKILL } from './man8.js';\nexport { MAN_SKILL } from './man.js';\nexport { MANPS_SKILL } from './manps.js';\nexport { MANSOLO_SKILL } from './mansolo.js';\nexport { MANTEAM_SKILL } from './manteam.js';\n\nimport { MAN_SKILL } from './man.js';\nimport { MAN8_SKILL } from './man8.js';\nimport { MANPS_SKILL } from './manps.js';\nimport { MANSOLO_SKILL } from './mansolo.js';\nimport { MANTEAM_SKILL } from './manteam.js';\n\n/**\n * Skill 规格(用于生成 .claude/skills/<name>/SKILL.md)。\n *\n * skill 文件是纯 markdown(Claude Code 加载后按指令执行)。\n * name 是命令名(如 man8 → \\`/man8\\`)。\n */\nexport interface SkillSpec {\n /** 命令名,不含前缀 /,也是文件名中段(mancode-<name>.md) */\n name: string;\n /** 一句话描述,告诉 Claude 这个 skill 是干什么的 */\n description: string;\n /** 完整 prompt markdown(Claude 加载后照着执行) */\n body: string;\n}\n\n/** 所有 MVP-2 skill(不含 solo,solo 由 inline.ts 提供) */\nexport const MVP2_SKILLS: SkillSpec[] = [\n MAN8_SKILL,\n MAN_SKILL,\n MANTEAM_SKILL,\n MANPS_SKILL,\n MANSOLO_SKILL,\n];\n\n/**\n * 渲染 skill 为 .claude/skills/<name>/SKILL.md 的内容。\n *\n * Claude Code 通过目录名注册 /<name>,SKILL.md frontmatter 提供菜单描述。\n */\nexport function renderSkill(spec: SkillSpec): string {\n return `---\\nname: ${spec.name}\\ndescription: ${JSON.stringify(spec.description)}\\n---\\n\\n${spec.body}\\n`;\n}\n","import { chmod, mkdir, readFile, stat, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { ensureTeamMemory } from '../system/team-memory.js';\nimport { DEFAULT_CONFIG, EMPTY_STYLE_TOKENS } from '../templates/defaults.js';\nimport {\n SESSION_START_HOOK,\n USER_PROMPT_SUBMIT_HOOK,\n} from '../templates/inline.js';\n\n/**\n * Install platform-neutral mancode project files.\n *\n * This setup is shared by all platform adapters. Platform-specific installers\n * should create only their native target files after this core is present.\n */\nexport async function installMancodeCore(projectRoot: string): Promise<void> {\n const mancodeDir = path.join(projectRoot, '.mancode');\n\n await mkdir(path.join(mancodeDir, 'hooks'), { recursive: true });\n await mkdir(path.join(mancodeDir, 'aesthetics'), { recursive: true });\n await mkdir(path.join(mancodeDir, 'logs'), { recursive: true });\n await mkdir(path.join(mancodeDir, 'workflows'), { recursive: true });\n await ensureTeamMemory(projectRoot);\n await mkdir(path.join(mancodeDir, 'preseason-reports'), { recursive: true });\n\n const configPath = path.join(mancodeDir, 'config.json');\n if (!(await pathExists(configPath))) {\n await writeFile(\n configPath,\n `${JSON.stringify(DEFAULT_CONFIG, null, 2)}\\n`,\n 'utf-8',\n );\n }\n\n await installHooks(path.join(mancodeDir, 'hooks'));\n\n const tokensPath = path.join(mancodeDir, 'aesthetics', 'style-tokens.json');\n if (!(await pathExists(tokensPath))) {\n await writeFile(\n tokensPath,\n `${JSON.stringify(EMPTY_STYLE_TOKENS, null, 2)}\\n`,\n 'utf-8',\n );\n }\n\n const logPath = path.join(mancodeDir, 'logs', 'hooks.log');\n if (!(await pathExists(logPath))) {\n await writeFile(logPath, '', 'utf-8');\n }\n}\n\nexport async function readTextIfExists(filePath: string): Promise<string> {\n try {\n return await readFile(filePath, 'utf-8');\n } catch (err) {\n if (isNodeError(err) && err.code === 'ENOENT') return '';\n throw err;\n }\n}\n\nasync function installHooks(hooksDir: string): Promise<void> {\n const sessionStartDst = path.join(hooksDir, 'session-start.sh');\n await writeFile(sessionStartDst, SESSION_START_HOOK, 'utf-8');\n await chmod(sessionStartDst, 0o755);\n\n const userPromptDst = path.join(hooksDir, 'user-prompt-submit.sh');\n await writeFile(userPromptDst, USER_PROMPT_SUBMIT_HOOK, 'utf-8');\n await chmod(userPromptDst, 0o755);\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isNodeError(err: unknown): err is NodeJS.ErrnoException {\n return err instanceof Error && 'code' in err;\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nexport interface TeamMemorySummary {\n dir: string;\n files: {\n prd: string;\n spec: string;\n decisions: string;\n };\n}\n\nconst MEMORY_FILES = {\n prd: {\n filename: 'prd.md',\n title: 'Product Requirements',\n body: 'Capture shared product goals, user-facing constraints, and release scope here.',\n },\n spec: {\n filename: 'spec.md',\n title: 'Technical Spec',\n body: 'Capture architecture, module boundaries, API contracts, and migration notes here.',\n },\n decisions: {\n filename: 'decisions.md',\n title: 'Architecture Decisions',\n body: 'Record team decisions as dated ADR-style notes. Keep entries short and linked to tasks when possible.',\n },\n} as const;\n\nexport async function ensureTeamMemory(\n projectRoot: string,\n): Promise<TeamMemorySummary> {\n const dir = memoryDir(projectRoot);\n await mkdir(dir, { recursive: true });\n\n const files = {\n prd: path.join(dir, MEMORY_FILES.prd.filename),\n spec: path.join(dir, MEMORY_FILES.spec.filename),\n decisions: path.join(dir, MEMORY_FILES.decisions.filename),\n };\n\n await Promise.all([\n writeIfMissing(\n files.prd,\n renderMemoryFile(MEMORY_FILES.prd.title, MEMORY_FILES.prd.body),\n ),\n writeIfMissing(\n files.spec,\n renderMemoryFile(MEMORY_FILES.spec.title, MEMORY_FILES.spec.body),\n ),\n writeIfMissing(\n files.decisions,\n renderMemoryFile(\n MEMORY_FILES.decisions.title,\n MEMORY_FILES.decisions.body,\n ),\n ),\n ]);\n\n return { dir, files };\n}\n\nexport async function appendTeamDecision(\n projectRoot: string,\n entry: {\n title: string;\n context?: string;\n decision: string;\n taskId?: string;\n date?: Date;\n },\n): Promise<void> {\n const summary = await ensureTeamMemory(projectRoot);\n const date = (entry.date ?? new Date()).toISOString().slice(0, 10);\n const taskLine = entry.taskId ? `\\n- Task: ${entry.taskId}` : '';\n const contextLine = entry.context ? `\\n- Context: ${entry.context}` : '';\n const block = `\\n## ${date}: ${entry.title}\\n\\n- Decision: ${entry.decision}${contextLine}${taskLine}\\n`;\n const existing = await readFile(summary.files.decisions, 'utf-8');\n await writeFile(\n summary.files.decisions,\n `${existing.trimEnd()}\\n${block}`,\n 'utf-8',\n );\n}\n\nfunction memoryDir(projectRoot: string): string {\n return path.join(projectRoot, '.mancode', 'memory');\n}\n\nasync function writeIfMissing(file: string, content: string): Promise<void> {\n try {\n await readFile(file, 'utf-8');\n } catch {\n await writeFile(file, content, 'utf-8');\n }\n}\n\nfunction renderMemoryFile(title: string, body: string): string {\n return `# ${title}\\n\\n${body}\\n`;\n}\n","/**\n * 默认的 .mancode/config.json 内容。\n *\n * 见 docs/08-cli-spec.md §11.1\n */\nexport const DEFAULT_CONFIG = {\n version: '1.0.0',\n platforms: ['claude-code'],\n cliCommand: 'mancode',\n cliArgs: [],\n forceTeamMode: false,\n defaultStyle: null,\n hooks: {\n sessionStart: true,\n userPromptSubmit: true,\n },\n logging: {\n level: 'info',\n file: '.mancode/logs/hooks.log',\n },\n};\n\n/**\n * 空的 style-tokens.json(非前端项目或 matchLevel=none 时用)。\n *\n * 结构对齐 src/system/scan-aesthetics.ts 的 AestheticsTokens。\n * 审美扫描见 docs/13-scanning.md。\n */\nexport const EMPTY_STYLE_TOKENS = {\n version: '1.0.0',\n lastScanned: null,\n colors: {},\n fonts: {},\n components: [],\n cssVariables: {},\n uiLibrary: null,\n darkMode: null,\n matchLevel: 'none',\n sourceFiles: [],\n};\n","import { writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { installMancodeCore, readTextIfExists } from './common.js';\nimport {\n DEFAULT_MANCODE_END_MARKER,\n DEFAULT_MANCODE_START_MARKER,\n replaceManagedBlock,\n} from './managed-block.js';\nimport type { InstallAdapterOptions } from './registry.js';\nimport { generateSharedContent } from './shared-content.js';\n\nexport async function installCodex(\n projectRoot: string,\n options: InstallAdapterOptions,\n): Promise<void> {\n await installMancodeCore(projectRoot);\n\n const agentsPath = path.join(projectRoot, 'AGENTS.md');\n const existing = await readTextIfExists(agentsPath);\n const sharedContent = await generateSharedContent(projectRoot, {\n platform: 'codex',\n displayName: 'Codex CLI',\n capabilities: {\n slashCommands: 'partial',\n subagents: false,\n hooks: false,\n skills: 'single-file',\n },\n minimal: options.minimal,\n techStack: options.techStack,\n uiLibrary: options.uiLibrary,\n });\n\n const block = [\n DEFAULT_MANCODE_START_MARKER,\n '<!-- Managed by mancode. Do not edit this block manually. -->',\n '',\n '# mancode Configuration',\n '',\n sharedContent.trim(),\n DEFAULT_MANCODE_END_MARKER,\n ].join('\\n');\n\n await writeFile(agentsPath, replaceManagedBlock(existing, block), 'utf-8');\n}\n","export const DEFAULT_MANCODE_START_MARKER = '<!-- mancode:start -->';\nexport const DEFAULT_MANCODE_END_MARKER = '<!-- mancode:end -->';\n\nexport function removeManagedBlock(\n existing: string,\n startMarker = DEFAULT_MANCODE_START_MARKER,\n endMarker = DEFAULT_MANCODE_END_MARKER,\n): string {\n const start = findMarkerLine(existing, startMarker);\n const end = findMarkerLine(existing, endMarker);\n\n if (start === null && end === null) return existing;\n if (start === null || end === null) return existing;\n if (end.start < start.start) return existing;\n\n const before = existing.slice(0, start.start);\n const after = existing.slice(end.end);\n const merged = `${before}${after}`;\n return cleanUpOrphanedNewlines(merged);\n}\n\nfunction cleanUpOrphanedNewlines(content: string): string {\n const trimmed = content.replace(/\\n{3,}/gu, '\\n\\n').replace(/\\n+$/u, '\\n');\n return trimmed || '';\n}\n\nexport function replaceManagedBlock(\n existing: string,\n block: string,\n startMarker = DEFAULT_MANCODE_START_MARKER,\n endMarker = DEFAULT_MANCODE_END_MARKER,\n): string {\n const normalizedBlock = normalizeManagedBlock(block, startMarker, endMarker);\n const start = findMarkerLine(existing, startMarker);\n const end = findMarkerLine(existing, endMarker);\n\n if ((start === null) !== (end === null)) {\n throw new Error('managed block is malformed: missing start or end marker');\n }\n\n if (start === null && end === null) {\n const trimmedExisting = trimTrailingNewlines(existing);\n if (!trimmedExisting) return `${normalizedBlock}\\n`;\n return `${trimmedExisting}\\n\\n${normalizedBlock}\\n`;\n }\n\n if (!start || !end) {\n throw new Error('managed block is malformed: missing start or end marker');\n }\n\n if (end.start < start.start) {\n throw new Error('managed block is malformed: end marker precedes start');\n }\n\n return `${existing.slice(0, start.start)}${normalizedBlock}${existing.slice(\n end.end,\n )}`;\n}\n\nfunction normalizeManagedBlock(\n block: string,\n startMarker: string,\n endMarker: string,\n): string {\n const trimmedBlock = block.trim();\n const hasStart = trimmedBlock.startsWith(startMarker);\n const hasEnd = trimmedBlock.endsWith(endMarker);\n\n if (hasStart && hasEnd) return trimmedBlock;\n if (hasStart || hasEnd) {\n throw new Error('managed block content includes only one marker');\n }\n\n return `${startMarker}\\n${trimmedBlock}\\n${endMarker}`;\n}\n\nfunction trimTrailingNewlines(value: string): string {\n return value.replace(/\\n+$/u, '');\n}\n\nfunction findMarkerLine(\n content: string,\n marker: string,\n): { start: number; end: number } | null {\n let offset = 0;\n let inFence: { char: '`' | '~'; length: number } | null = null;\n\n for (const lineWithBreak of content.matchAll(/[^\\n]*(?:\\n|$)/gu)) {\n const rawLine = lineWithBreak[0];\n if (!rawLine) break;\n\n const line = rawLine.replace(/\\n$/u, '').replace(/\\r$/u, '');\n const fence = line.match(/^(`{3,}|~{3,})/u)?.[1];\n if (fence) {\n const char = fence[0] as '`' | '~';\n if (!inFence) {\n inFence = { char, length: fence.length };\n } else if (inFence.char === char && fence.length >= inFence.length) {\n inFence = null;\n }\n } else if (!inFence && line === marker) {\n return {\n start: offset,\n end: offset + marker.length,\n };\n }\n\n offset += rawLine.length;\n }\n\n return null;\n}\n","import { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { PlatformCapabilities, PlatformName } from './registry.js';\n\nexport interface SharedContentOptions {\n platform: PlatformName;\n displayName: string;\n capabilities: PlatformCapabilities;\n minimal?: boolean;\n techStack: string[];\n uiLibrary: string | null;\n}\n\ninterface MancodeStateOnDisk {\n currentMode?: string;\n techStack?: string;\n uiLibrary?: string;\n}\n\ninterface StyleTokensOnDisk {\n colors?: Record<string, unknown>;\n fonts?: Record<string, unknown>;\n components?: unknown[];\n cssVariables?: Record<string, unknown>;\n uiLibrary?: string | null;\n darkMode?: string | null;\n matchLevel?: string;\n}\n\nexport async function generateSharedContent(\n projectRoot: string,\n options: SharedContentOptions,\n): Promise<string> {\n const [state, tokens] = await Promise.all([\n readJson<MancodeStateOnDisk>(\n path.join(projectRoot, '.mancode', 'state.json'),\n ),\n readJson<StyleTokensOnDisk>(\n path.join(projectRoot, '.mancode', 'aesthetics', 'style-tokens.json'),\n ),\n ]);\n\n const sections = [\n renderProjectContext(state, tokens, options),\n renderPracticeRules(),\n renderAesthetics(tokens),\n ];\n\n if (!options.minimal) {\n sections.push(renderModes(options), renderPlatformDowngrade(options));\n }\n\n return `${sections.filter(Boolean).join('\\n\\n')}\\n`;\n}\n\nfunction renderProjectContext(\n state: MancodeStateOnDisk | null,\n tokens: StyleTokensOnDisk | null,\n options: SharedContentOptions,\n): string {\n const techStack =\n state?.techStack || options.techStack.join(' + ') || 'Unknown';\n const uiLibrary =\n state?.uiLibrary || tokens?.uiLibrary || options.uiLibrary || 'None';\n const mode = state?.currentMode || 'solo';\n\n return [\n '## mancode Project Context',\n '',\n `- Platform adapter: ${options.displayName}`,\n `- Current mode: ${mode}`,\n `- Tech stack: ${techStack}`,\n `- UI library: ${uiLibrary}`,\n '- At the start of each session, read `.mancode/state.json` to check the current mode and project context.',\n '- For UI tasks, read `.mancode/aesthetics/style-tokens.json` for current design tokens.',\n ].join('\\n');\n}\n\nfunction renderPracticeRules(): string {\n return [\n '## mancode Practice Rules',\n '',\n 'Before writing new code, check this YAGNI ladder:',\n '',\n '1. Reuse existing project code.',\n '2. Use the standard library.',\n '3. Use platform-native behavior.',\n '4. Use already installed dependencies.',\n '5. Prefer a one-line fix when it is enough.',\n '6. Only then write the smallest new implementation.',\n '',\n 'For every task, consider: why this change, what already exists, and what is the smallest useful diff?',\n ].join('\\n');\n}\n\nfunction renderAesthetics(tokens: StyleTokensOnDisk | null): string {\n const colors = summarizeRecord(tokens?.colors, 8);\n const fonts = summarizeRecord(tokens?.fonts, 4);\n const cssVariables = summarizeRecord(tokens?.cssVariables, 8);\n const components = summarizeList(tokens?.components, 8);\n const hasTokenSummary = Boolean(\n colors || fonts || cssVariables || components,\n );\n\n if (!tokens || tokens.matchLevel === 'none' || !hasTokenSummary) {\n const lowConfidence =\n tokens?.matchLevel && tokens.matchLevel !== 'none'\n ? `- Match level: ${tokens.matchLevel}. Inspect existing components manually.`\n : '- No strong project style tokens were detected.';\n return [\n '## mancode Aesthetics',\n '',\n lowConfidence,\n '- For UI work, inspect existing components before inventing new styles.',\n ].join('\\n');\n }\n\n const lines = ['## mancode Aesthetics', ''];\n if (tokens.matchLevel) lines.push(`- Match level: ${tokens.matchLevel}`);\n if (tokens.uiLibrary) lines.push(`- UI library: ${tokens.uiLibrary}`);\n if (tokens.darkMode) lines.push(`- Dark mode: ${tokens.darkMode}`);\n\n if (colors) lines.push(`- Colors: ${colors}`);\n if (fonts) lines.push(`- Fonts: ${fonts}`);\n if (components) lines.push(`- Components: ${components}`);\n if (cssVariables) lines.push(`- CSS variables: ${cssVariables}`);\n lines.push(\n '- For UI changes, prefer these tokens and components over new ad hoc styling.',\n );\n\n return lines.join('\\n');\n}\n\nfunction renderModes(options: SharedContentOptions): string {\n const commandLabel =\n options.capabilities.slashCommands === 'native'\n ? 'Use the named commands directly when available.'\n : 'Treat these as prompt conventions when native commands are unavailable.';\n\n return [\n '## mancode Modes',\n '',\n `- solo: default lightweight mode. ${commandLabel}`,\n '- man8: investigate first, then produce a plan before implementation.',\n '- man: full high-risk workflow with plan, implementation, verification, and review.',\n '- manteam: use team memory and leave handoff-friendly summaries.',\n '- manps: run project health and cleanup scans before remediation.',\n '- mansolo: return to solo mode.',\n ].join('\\n');\n}\n\nfunction renderPlatformDowngrade(options: SharedContentOptions): string {\n if (options.capabilities.subagents && options.capabilities.hooks) {\n return [\n '## mancode Platform Capabilities',\n '',\n '- This platform supports native mancode hooks and isolated subagents.',\n ].join('\\n');\n }\n\n const lines = [\n '## mancode Platform Downgrade',\n '',\n '- This platform does not provide the full Claude Code hook/subagent model.',\n ];\n\n if (!options.capabilities.hooks) {\n lines.push(\n '- Session and prompt-submit hooks are represented as persistent instructions.',\n );\n }\n if (!options.capabilities.subagents) {\n lines.push(\n '- Simulate the coaching staff in sequence inside the same conversation: Scout, Head Coach, Film Analyst Offense, Film Analyst Defense.',\n );\n }\n\n return lines.join('\\n');\n}\n\nasync function readJson<T>(filePath: string): Promise<T | null> {\n try {\n return JSON.parse(await readFile(filePath, 'utf-8')) as T;\n } catch {\n return null;\n }\n}\n\nfunction summarizeRecord(\n value: Record<string, unknown> | undefined,\n limit: number,\n): string {\n if (!value) return '';\n return Object.entries(value)\n .slice(0, limit)\n .map(([key, item]) => `${key}=${formatValue(item)}`)\n .join(', ');\n}\n\nfunction summarizeList(value: unknown[] | undefined, limit: number): string {\n if (!Array.isArray(value)) return '';\n return value.slice(0, limit).map(formatValue).filter(Boolean).join(', ');\n}\n\nfunction formatValue(value: unknown): string {\n if (Array.isArray(value)) return value.map(String).join(' ');\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n return '';\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { installMancodeCore, readTextIfExists } from './common.js';\nimport {\n DEFAULT_MANCODE_END_MARKER,\n DEFAULT_MANCODE_START_MARKER,\n replaceManagedBlock,\n} from './managed-block.js';\nimport type { InstallAdapterOptions } from './registry.js';\nimport { generateSharedContent } from './shared-content.js';\n\nexport async function installCopilot(\n projectRoot: string,\n options: InstallAdapterOptions,\n): Promise<void> {\n await installMancodeCore(projectRoot);\n\n const githubDir = path.join(projectRoot, '.github');\n await mkdir(githubDir, { recursive: true });\n\n const instructionsPath = path.join(githubDir, 'copilot-instructions.md');\n const existing = await readTextIfExists(instructionsPath);\n const sharedContent = await generateSharedContent(projectRoot, {\n platform: 'copilot',\n displayName: 'GitHub Copilot',\n capabilities: {\n slashCommands: 'none',\n subagents: false,\n hooks: false,\n skills: 'instructions',\n },\n minimal: true,\n techStack: options.techStack,\n uiLibrary: options.uiLibrary,\n });\n\n const sections = [\n DEFAULT_MANCODE_START_MARKER,\n '<!-- Managed by mancode. Do not edit this block manually. -->',\n '',\n '# mancode for GitHub Copilot',\n '',\n sharedContent.trim(),\n ];\n\n if (!options.minimal) {\n sections.push('', renderCopilotPromptConventions());\n }\n\n sections.push(DEFAULT_MANCODE_END_MARKER);\n\n await writeFile(\n instructionsPath,\n replaceManagedBlock(existing, sections.join('\\n')),\n 'utf-8',\n );\n}\n\nfunction renderCopilotPromptConventions(): string {\n return [\n '## mancode Prompt Conventions',\n '',\n 'GitHub Copilot does not provide native mancode slash commands, hooks, or isolated subagents. Treat these names as user prompt conventions:',\n '',\n '- man8: investigate first and produce a plan before implementation.',\n '- man: use a careful plan, implementation, verification, and review loop.',\n '- manteam: read team memory and write handoff-friendly summaries.',\n '- manps: prefer `mancode manps [area]` before cleanup.',\n ].join('\\n');\n}\n","import { mkdir, rm, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { installMancodeCore } from './common.js';\nimport type { InstallAdapterOptions } from './registry.js';\nimport { generateSharedContent } from './shared-content.js';\n\nexport const MANCODE_CURSOR_CORE_RULE_FILES = [\n 'mancode-context.mdc',\n 'mancode-practice.mdc',\n 'mancode-solo.mdc',\n] as const;\n\nexport const MANCODE_CURSOR_ADVANCED_RULE_FILES = [\n 'mancode-man8.mdc',\n 'mancode-man.mdc',\n 'mancode-manteam.mdc',\n 'mancode-manps.mdc',\n] as const;\n\nexport const MANCODE_CURSOR_RULE_FILES = [\n ...MANCODE_CURSOR_CORE_RULE_FILES,\n ...MANCODE_CURSOR_ADVANCED_RULE_FILES,\n] as const;\n\nexport async function installCursor(\n projectRoot: string,\n options: InstallAdapterOptions,\n): Promise<void> {\n await installMancodeCore(projectRoot);\n\n const rulesDir = path.join(projectRoot, '.cursor', 'rules');\n await mkdir(rulesDir, { recursive: true });\n\n const sharedContent = await generateSharedContent(projectRoot, {\n platform: 'cursor',\n displayName: 'Cursor',\n capabilities: {\n slashCommands: 'native',\n subagents: false,\n hooks: false,\n skills: 'rules',\n },\n // Keep the always-applied context rule compact; full mode guidance lives in\n // the mode-specific Cursor rules below.\n minimal: true,\n techStack: options.techStack,\n uiLibrary: options.uiLibrary,\n });\n\n await writeRule(\n rulesDir,\n 'mancode-context.mdc',\n 'mancode project context, style tokens, and default constraints',\n true,\n sharedContent,\n );\n await writeRule(\n rulesDir,\n 'mancode-practice.mdc',\n 'mancode YAGNI ladder and three-question practice reminder',\n true,\n renderPracticeRule(),\n );\n await writeRule(\n rulesDir,\n 'mancode-solo.mdc',\n 'mancode solo mode for small focused implementation tasks',\n true,\n renderSoloRule(),\n );\n\n if (options.minimal) {\n await removeAdvancedRules(rulesDir);\n return;\n }\n\n await writeRule(\n rulesDir,\n 'mancode-man8.mdc',\n 'Use when the user invokes /man8 or asks for investigation and planning before implementation',\n false,\n renderMan8Rule(),\n );\n await writeRule(\n rulesDir,\n 'mancode-man.mdc',\n 'Use when the user invokes /man or asks for high-risk implementation with review',\n false,\n renderManRule(),\n );\n await writeRule(\n rulesDir,\n 'mancode-manteam.mdc',\n 'Use when the user invokes /manteam or asks for team handoff-aware implementation',\n false,\n renderManteamRule(),\n );\n await writeRule(\n rulesDir,\n 'mancode-manps.mdc',\n 'Use when the user invokes /manps or asks for project health cleanup',\n false,\n renderManpsRule(),\n );\n}\n\nasync function writeRule(\n rulesDir: string,\n fileName: (typeof MANCODE_CURSOR_RULE_FILES)[number],\n description: string,\n alwaysApply: boolean,\n body: string,\n): Promise<void> {\n const frontmatter = [\n '---',\n `description: ${JSON.stringify(description)}`,\n `alwaysApply: ${alwaysApply ? 'true' : 'false'}`,\n ];\n if (alwaysApply) {\n frontmatter.push('globs: \"**/*\"');\n }\n frontmatter.push('---');\n\n const content = `${frontmatter.join('\\n')}\\n\\n${body.trim()}\\n`;\n\n await writeFile(path.join(rulesDir, fileName), content, 'utf-8');\n}\n\nasync function removeAdvancedRules(rulesDir: string): Promise<void> {\n for (const fileName of MANCODE_CURSOR_ADVANCED_RULE_FILES) {\n await rm(path.join(rulesDir, fileName), { force: true });\n }\n}\n\nfunction renderPracticeRule(): string {\n return [\n '# mancode Practice',\n '',\n 'Before writing code, apply the YAGNI ladder:',\n '',\n '1. Reuse existing project code.',\n '2. Use the standard library.',\n '3. Use platform-native behavior.',\n '4. Use already installed dependencies.',\n '5. Prefer a one-line fix when it is enough.',\n '6. Only then write the smallest new implementation.',\n '',\n 'For each request, consider why this change is needed, what already exists, and what the smallest useful diff is.',\n ].join('\\n');\n}\n\nfunction renderSoloRule(): string {\n return [\n '# mancode solo',\n '',\n 'Use solo mode for small, focused tasks.',\n '',\n '- Keep the diff narrow.',\n '- Reuse existing functions, components, styles, and dependencies.',\n '- For UI work, read `.mancode/aesthetics/style-tokens.json` and inspect existing components before inventing new styles.',\n '- Verify with the narrowest meaningful test, lint, build, or smoke check.',\n ].join('\\n');\n}\n\nfunction renderMan8Rule(): string {\n return [\n '# mancode man8',\n '',\n 'Use this when the user asks for /man8, planning, investigation, architecture, migration, integration, or risk assessment.',\n '',\n 'Cursor does not provide isolated mancode subagents. Simulate the flow in sequence:',\n '',\n '1. Scout: inspect the relevant code and summarize constraints.',\n '2. Head Coach: write a concrete implementation plan.',\n '3. Stop for user approval when the user asked for planning only.',\n ].join('\\n');\n}\n\nfunction renderManRule(): string {\n return [\n '# mancode man',\n '',\n 'Use this when the user asks for /man or a high-risk production change.',\n '',\n 'Simulate the full workflow in one conversation:',\n '',\n '1. Scout investigates the codebase.',\n '2. Head Coach proposes the plan.',\n '3. Wait for approval when required.',\n '4. Implement and self-test.',\n '5. Film Analyst Offense reviews readability, DRY, and YAGNI.',\n '6. Fix review findings.',\n '7. Film Analyst Defense reviews auth, injection, concurrency, and resource risks.',\n '8. Summarize verification and remaining risk.',\n ].join('\\n');\n}\n\nfunction renderManteamRule(): string {\n return [\n '# mancode manteam',\n '',\n 'Use this when the user asks for /manteam or when the task affects shared team context.',\n '',\n '- Read `.mancode/memory/prd.md`, `.mancode/memory/spec.md`, and `.mancode/memory/decisions.md` when relevant.',\n '- Preserve decisions and leave handoff-friendly summaries.',\n '- Prefer Conventional Commit style when suggesting commits.',\n ].join('\\n');\n}\n\nfunction renderManpsRule(): string {\n return [\n '# mancode manps',\n '',\n 'Use this when the user asks for /manps or project health cleanup.',\n '',\n '- Prefer `mancode manps [area]` before manual cleanup.',\n '- Supported areas: all, deps, security, dead-code, config.',\n '- Treat scan output as triage data; do not remediate without clear user approval.',\n ].join('\\n');\n}\n","import { installClaudeCode } from './claude-code.js';\nimport { installCodex } from './codex.js';\nimport { installCopilot } from './copilot.js';\nimport { installCursor } from './cursor.js';\n\nexport type PlatformName = 'claude-code' | 'cursor' | 'codex' | 'copilot';\n\nexport interface PlatformCapabilities {\n slashCommands: 'native' | 'partial' | 'none';\n subagents: boolean;\n hooks: boolean;\n skills: 'native' | 'rules' | 'single-file' | 'instructions';\n}\n\nexport interface InstallAdapterOptions {\n techStack: string[];\n uiLibrary: string | null;\n minimal?: boolean;\n}\n\nexport interface PlatformInstaller {\n name: PlatformName;\n displayName: string;\n capabilities: PlatformCapabilities;\n install(projectRoot: string, options: InstallAdapterOptions): Promise<void>;\n}\n\nexport const PLATFORM_INSTALLERS: Record<PlatformName, PlatformInstaller> = {\n 'claude-code': {\n name: 'claude-code',\n displayName: 'Claude Code',\n capabilities: {\n slashCommands: 'native',\n subagents: true,\n hooks: true,\n skills: 'native',\n },\n install: installClaudeCode,\n },\n cursor: {\n name: 'cursor',\n displayName: 'Cursor',\n capabilities: {\n slashCommands: 'native',\n subagents: false,\n hooks: false,\n skills: 'rules',\n },\n install: installCursor,\n },\n codex: {\n name: 'codex',\n displayName: 'Codex CLI',\n capabilities: {\n slashCommands: 'partial',\n subagents: false,\n hooks: false,\n skills: 'single-file',\n },\n install: installCodex,\n },\n copilot: {\n name: 'copilot',\n displayName: 'GitHub Copilot',\n capabilities: {\n slashCommands: 'none',\n subagents: false,\n hooks: false,\n skills: 'instructions',\n },\n install: installCopilot,\n },\n};\n\nexport function getPlatformInstaller(\n platform: string,\n): PlatformInstaller | null {\n if (!isPlatformName(platform)) return null;\n return PLATFORM_INSTALLERS[platform];\n}\n\nexport function getPlatformInstallers(): PlatformInstaller[] {\n return Object.values(PLATFORM_INSTALLERS);\n}\n\nexport function formatPlatformName(platform: string): string {\n return getPlatformInstaller(platform)?.displayName ?? platform;\n}\n\nfunction isPlatformName(platform: string): platform is PlatformName {\n return Object.prototype.hasOwnProperty.call(PLATFORM_INSTALLERS, platform);\n}\n","import { exec } from 'node:child_process';\nimport path from 'node:path';\nimport process from 'node:process';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\n/**\n * 多人协作检测结果。\n *\n * 三条件同时满足才判定为团队(docs/13-scanning.md §6):\n * 1. contributors > 1(历史多个贡献者)\n * 2. hasRemote = true(有 github/gitlab/bitbucket remote)\n * 3. recentActive > 1(最近 30 天多人活跃,避免老项目误判)\n */\nexport interface TeamStatus {\n isTeam: boolean;\n contributors: number;\n recentActive: number;\n hasRemote: boolean;\n}\n\nconst NO_TEAM: TeamStatus = {\n isTeam: false,\n contributors: 1,\n recentActive: 1,\n hasRemote: false,\n};\n\nconst REMOTE_PATTERN = /github\\.com|gitlab\\.com|bitbucket\\.org/;\n\n/**\n * 所有 exec 调用共用:禁用 pager(否则 shortlog 会拉起 less 阻塞等输入)。\n */\nconst EXEC_OPTS = {\n shell: '/bin/bash',\n encoding: 'utf-8' as const,\n env: {\n ...process.env,\n GIT_PAGER: 'cat',\n PAGER: 'cat',\n GIT_TERMINAL_PROMPT: '0',\n },\n};\n\n/**\n * 检测多人协作状态。\n *\n * 算法来源:docs/07-hooks.md §2.3 detect_team()(已同步为 TS 实现)。\n *\n * 行为:\n * - 非 git 目录 → 返回默认单人状态\n * - git 命令失败 → 返回默认单人状态(保守降级,不抛错)\n * - 三条件全满足 → isTeam=true\n *\n * @param projectRoot 项目根目录\n */\nexport async function detectTeamStatus(\n projectRoot: string,\n): Promise<TeamStatus> {\n const gitDir = path.join(projectRoot, '.git');\n try {\n await execAsync('git rev-parse --is-inside-work-tree', {\n cwd: projectRoot,\n ...EXEC_OPTS,\n });\n } catch {\n return NO_TEAM;\n }\n\n // 检查 .git 目录确实存在(rev-parse 在某些情况下也会成功)\n try {\n await execAsync(`test -d ${JSON.stringify(gitDir)}`, {\n cwd: projectRoot,\n ...EXEC_OPTS,\n });\n } catch {\n return NO_TEAM;\n }\n\n const contributors = await countUniqueEmails(\n \"git log --all --format='%ae'\",\n projectRoot,\n );\n const recentActive = await countUniqueEmails(\n \"git log --since='30 days ago' --format='%ae'\",\n projectRoot,\n );\n const hasRemote = await checkRemote(projectRoot);\n\n // 兜底:exec 输出非数字时回到 0/1\n const safeContributors = Number.isFinite(contributors) ? contributors : 0;\n const safeRecent = Number.isFinite(recentActive) ? recentActive : 0;\n\n const isTeam = safeContributors > 1 && hasRemote && safeRecent > 1;\n\n return {\n isTeam,\n contributors: safeContributors || 1,\n recentActive: safeRecent || 1,\n hasRemote,\n };\n}\n\nasync function countUniqueEmails(\n command: string,\n cwd: string,\n): Promise<number> {\n try {\n const { stdout } = await execAsync(\n `${command} 2>/dev/null | sort -u | grep -c . || true`,\n { cwd, ...EXEC_OPTS },\n );\n const n = Number.parseInt(stdout.trim(), 10);\n return Number.isFinite(n) ? n : 0;\n } catch {\n return 0;\n }\n}\n\nasync function checkRemote(cwd: string): Promise<boolean> {\n try {\n const { stdout } = await execAsync('git remote -v 2>/dev/null || true', {\n cwd,\n ...EXEC_OPTS,\n });\n return REMOTE_PATTERN.test(stdout);\n } catch {\n return false;\n }\n}\n","import { exec } from 'node:child_process';\nimport { access, readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\n/**\n * 系统依赖检测结果。\n */\nexport interface SystemDeps {\n bash: boolean;\n git: boolean;\n jq: boolean;\n node: boolean;\n}\n\n/**\n * 项目类型检测结果。\n */\nexport interface ProjectType {\n hasFrontend: boolean;\n hasBackend: boolean;\n techStack: string[];\n uiLibrary: string | null;\n}\n\n/**\n * 检测系统依赖(bash、git、jq、node)。\n *\n * docs/08-cli-spec.md §12.1 要求:\n * - bash/git/node 必需\n * - jq 可选(无则警告,hook 走 grep/sed fallback)\n */\nexport async function detectSystemDeps(): Promise<SystemDeps> {\n const ALLOWED_COMMANDS = new Set(['bash', 'git', 'jq', 'node']);\n\n const check = async (cmd: string): Promise<boolean> => {\n // 白名单验证(防御性编程)\n if (!ALLOWED_COMMANDS.has(cmd)) {\n throw new Error(`Unsupported dependency check: ${cmd}`);\n }\n\n try {\n await execAsync(`command -v ${cmd}`, { shell: '/bin/bash' });\n return true;\n } catch {\n return false;\n }\n };\n\n const [bash, git, jq, node] = await Promise.all([\n check('bash'),\n check('git'),\n check('jq'),\n check('node'),\n ]);\n\n return { bash, git, jq, node };\n}\n\n/**\n * 检测项目类型(frontend / backend / tech stack)。\n *\n * 当前版本:基于 package.json dependencies 简单推断。\n * 完整版见 docs/13-scanning.md(扫描 tsconfig / vite.config / 文件结构)。\n *\n * @param projectRoot 项目根目录\n */\nexport async function detectProjectType(\n projectRoot: string,\n): Promise<ProjectType> {\n const pkgPath = path.join(projectRoot, 'package.json');\n\n try {\n await access(pkgPath);\n } catch (err) {\n // 只在文件不存在时返回空,其他错误(权限、磁盘错误等)抛出\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return {\n hasFrontend: false,\n hasBackend: false,\n techStack: [],\n uiLibrary: null,\n };\n }\n throw err;\n }\n\n const raw = await readFile(pkgPath, 'utf-8');\n const pkg = JSON.parse(raw);\n\n const allDeps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n ...pkg.peerDependencies,\n };\n\n const deps = Object.keys(allDeps || {});\n\n // 前端框架\n const hasFrontend =\n deps.some((d) => ['react', 'vue', 'svelte', 'angular'].includes(d)) ||\n deps.some((d) => d.startsWith('@angular/'));\n\n // 后端框架\n const hasBackend =\n deps.some((d) =>\n ['express', 'koa', 'fastify', 'hapi', 'next'].includes(d),\n ) || deps.some((d) => d.startsWith('@nestjs/'));\n\n // 技术栈(简单枚举)\n const techStack: string[] = [];\n if (deps.includes('react')) techStack.push('React');\n if (deps.includes('vue')) techStack.push('Vue');\n if (deps.includes('svelte')) techStack.push('Svelte');\n if (deps.includes('typescript')) techStack.push('TypeScript');\n if (deps.includes('tailwindcss')) techStack.push('Tailwind CSS');\n\n // UI 库\n let uiLibrary: string | null = null;\n\n // shadcn/ui 检测:Radix 依赖 + src/components/ui 目录\n const hasRadix = deps.some((d) => d.startsWith('@radix-ui/'));\n const uiDir = path.join(projectRoot, 'src', 'components', 'ui');\n const hasUiDir = await pathExists(uiDir);\n\n if (hasRadix && hasUiDir) {\n uiLibrary = 'shadcn/ui';\n } else if (deps.includes('@mui/material')) {\n uiLibrary = 'MUI';\n } else if (deps.includes('antd')) {\n uiLibrary = 'Ant Design';\n } else if (deps.includes('@headlessui/react')) {\n uiLibrary = 'headlessUI';\n }\n\n return { hasFrontend, hasBackend, techStack, uiLibrary };\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n","import { promises as fs } from 'node:fs';\nimport type { Stats } from 'node:fs';\nimport path from 'node:path';\n\n/**\n * 审美扫描结果。\n *\n * 结构对齐 docs/06-aesthetics.md §9.3 和 docs/13-scanning.md §8.2。\n * MVP-2 beta 提取 Tailwind colors/fonts、darkMode、uiLibrary、\n * 常见组件名和 CSS custom properties。\n */\nexport interface AestheticsTokens {\n version: string;\n lastScanned: string | null;\n colors: Record<string, string>;\n fonts: Record<string, string[]>;\n components: string[];\n cssVariables: Record<string, string>;\n uiLibrary: string | null;\n darkMode: string | null;\n matchLevel: 'high' | 'low' | 'none';\n sourceFiles: string[];\n}\n\nconst MAX_COMPONENT_SCAN_DEPTH = 12;\nconst MAX_COMPONENT_FILES = 2000;\n\n/**\n * 扫描项目审美 token。\n *\n * 职责(docs/13-scanning.md §4 + docs/06-aesthetics.md §3):\n * 1. 检测 tailwind.config.{js,ts,cjs,mjs},提取 colors 和 fontFamily\n * 2. 检测 darkMode 策略\n * 3. matchLevel: 有 tailwind config → high,有 tailwind 依赖但无 config → low,都没有 → none\n *\n * MVP-2 beta 仍不做:\n * - theme.json / tokens.json 等非 Tailwind token 文件\n *\n * @param projectRoot 项目根目录\n * @param uiLibrary 已检测到的 UI 库(从 detectProjectType 传入,避免重复检测)\n */\nexport async function scanAesthetics(\n projectRoot: string,\n uiLibrary: string | null = null,\n): Promise<AestheticsTokens> {\n const sourceFiles: string[] = [];\n\n // 1. 查找 tailwind config\n const configResult = await findTailwindConfig(projectRoot);\n let colors: Record<string, string> = {};\n let fonts: Record<string, string[]> = {};\n let darkMode: string | null = null;\n const components = await scanComponents(projectRoot);\n const cssScan = await scanCssVariables(projectRoot);\n\n if (configResult) {\n sourceFiles.push(configResult.relPath);\n const content = await fs.readFile(configResult.absPath, 'utf-8');\n const themeBlock = findKeyBlock(content, 'theme');\n if (themeBlock) {\n // 先在 theme.extend 里找 section,找不到再在 theme 里直接找\n const extendBlock = findKeyBlock(themeBlock, 'extend');\n const searchBlock = extendBlock ?? themeBlock;\n\n const colorsBlock = findKeyBlock(searchBlock, 'colors');\n if (colorsBlock) {\n colors = extractTopLevelStringValues(colorsBlock);\n }\n\n const fontsBlock = findKeyBlock(searchBlock, 'fontFamily');\n if (fontsBlock) {\n fonts = extractTopLevelArrayValues(fontsBlock);\n }\n }\n darkMode = extractDarkMode(stripJsComments(content));\n }\n\n // 2. 判断 matchLevel\n let matchLevel: AestheticsTokens['matchLevel'] = 'none';\n if (configResult) {\n matchLevel = 'high';\n } else if (await hasTailwindDep(projectRoot)) {\n matchLevel = 'low';\n }\n\n if (uiLibrary) {\n sourceFiles.push('package.json');\n }\n sourceFiles.push(...cssScan.sourceFiles);\n\n return {\n version: '1.0.0',\n lastScanned: new Date().toISOString(),\n colors,\n fonts,\n components,\n cssVariables: cssScan.variables,\n uiLibrary,\n darkMode,\n matchLevel,\n sourceFiles,\n };\n}\n\n/**\n * 查找 tailwind.config.{js,ts,cjs,mjs}。\n * 返回绝对路径和相对路径,找不到返回 null。\n */\nasync function findTailwindConfig(\n projectRoot: string,\n): Promise<{ absPath: string; relPath: string } | null> {\n const candidates = [\n 'tailwind.config.js',\n 'tailwind.config.ts',\n 'tailwind.config.cjs',\n 'tailwind.config.mjs',\n ];\n\n for (const name of candidates) {\n const absPath = path.join(projectRoot, name);\n if (await pathExists(absPath)) {\n return { absPath, relPath: name };\n }\n }\n\n return null;\n}\n\n// ─── 花括号深度遍历工具 ───────────────────────────────────────────\n\n/**\n * 在 content 中查找 `key:` 后面跟着的花括号块,返回块内容(不含外层花括号)。\n *\n * 正确处理嵌套:theme: { extend: { colors: { ... } } }\n * 找到第一个 `key:` 后跟着 `{` 的位置,提取完整块。\n *\n * 作用域安全:调用方传入的是父块的内容(已提取),所以第一个匹配\n * 就是当前层级的 key,不会误匹配嵌套块内的同名 key。\n *\n * @param content 要搜索的内容\n * @param key 要查找的键名(如 \"theme\" / \"extend\" / \"colors\")\n * @returns 花括号内的内容,找不到返回 null\n */\nfunction findKeyBlock(content: string, key: string): string | null {\n const keyPattern = new RegExp(`['\"]?${escapeRegex(key)}['\"]?\\\\s*:`);\n\n let searchStart = 0;\n while (searchStart < content.length) {\n const remaining = content.slice(searchStart);\n const match = keyPattern.exec(remaining);\n if (!match) break;\n\n const absPos = searchStart + match.index;\n\n // 从 match 结束位置找第一个 {\n let i = absPos + match[0].length;\n while (i < content.length && content[i] !== '{') {\n // 遇到非空白字符说明值不是对象,跳过\n const char = content[i];\n if (char === undefined || !/\\s/.test(char)) break;\n i++;\n }\n if (i >= content.length || content[i] !== '{') {\n searchStart = absPos + match[0].length;\n continue;\n }\n\n // 按花括号深度提取完整块\n return extractBraceContent(content, i);\n }\n\n return null;\n}\n\n/**\n * 从开 { 位置开始,按花括号深度提取完整块内容。\n *\n * @param content 完整文本\n * @param bracePos 开 { 的位置\n * @returns 花括号内的内容(不含外层花括号),不匹配返回 null\n */\nfunction extractBraceContent(content: string, bracePos: number): string | null {\n if (content[bracePos] !== '{') return null;\n\n let i = bracePos + 1;\n let depth = 1;\n const start = i;\n\n while (i < content.length && depth > 0) {\n const ch = content[i];\n if (ch === '{') depth++;\n else if (ch === '}') depth--;\n if (depth === 0) break;\n i++;\n }\n\n if (depth !== 0) return null;\n return content.slice(start, i);\n}\n\n// ─── 值提取工具 ───────────────────────────────────────────────────\n\n/**\n * 从块内容中提取顶层(depth 0)的 key: \"string\" 对。\n *\n * 只匹配当前层级的键值对,跳过嵌套对象内的值。\n * 例如 `{ primary: { 500: \"#abc\" }, background: \"#fff\" }`\n * 只提取 background,不提取 500。\n */\nfunction extractTopLevelStringValues(block: string): Record<string, string> {\n const result: Record<string, string> = {};\n const pairs = extractTopLevelPairs(block);\n\n for (const { key, value } of pairs) {\n if (!isSafeTokenName(key)) continue;\n // 值必须是引号包裹的字符串(不是对象、不是数组)\n const strMatch = value.match(/^['\"]([^'\"]+)['\"]$/);\n const tokenValue = strMatch?.[1];\n if (tokenValue && isSafeColorValue(tokenValue)) {\n result[key] = tokenValue;\n }\n }\n\n return result;\n}\n\n/**\n * 从块内容中提取顶层(depth 0)的 key: [\"a\", \"b\"] 对。\n *\n * 只匹配当前层级的键值对,跳过嵌套对象内的值。\n */\nfunction extractTopLevelArrayValues(block: string): Record<string, string[]> {\n const result: Record<string, string[]> = {};\n const pairs = extractTopLevelPairs(block);\n\n for (const { key, value } of pairs) {\n if (!isSafeTokenName(key)) continue;\n // 值必须是数组\n const arrMatch = value.match(/^\\[([^\\]]+)\\]$/);\n const rawItems = arrMatch?.[1];\n if (rawItems) {\n const items = rawItems\n .split(',')\n .map((v) => v.trim().replace(/['\"]/g, ''))\n .filter((v) => v.length > 0);\n if (items.length > 0) {\n result[key] = items;\n }\n }\n }\n\n return result;\n}\n\n/**\n * 提取块内容中顶层(depth 0)的 key: value 对。\n *\n * 遍历块内容,在 depth 0 处识别 `key: value` 结构。\n * value 可以是字符串、数组、或嵌套对象(嵌套对象被跳过,只记录 key)。\n */\nfunction extractTopLevelPairs(\n block: string,\n): Array<{ key: string; value: string }> {\n const pairs: Array<{ key: string; value: string }> = [];\n\n let i = 0;\n while (i < block.length) {\n // 跳过空白和逗号\n while (i < block.length && /[\\s,]/.test(block[i] ?? '')) i++;\n if (i >= block.length) break;\n\n // 提取 key(可能是带引号或不带引号的标识符)\n const keyResult = parseKey(block, i);\n if (!keyResult) {\n i++;\n continue;\n }\n const { key, nextPos: afterKey } = keyResult;\n\n // 跳过 key 后的空白\n i = afterKey;\n while (i < block.length && /\\s/.test(block[i] ?? '')) i++;\n\n // 期望冒号\n if (block[i] !== ':') continue;\n i++;\n while (i < block.length && /\\s/.test(block[i] ?? '')) i++;\n if (i >= block.length) break;\n\n // 提取 value(在 depth 0)\n const valueResult = parseValue(block, i);\n if (!valueResult) {\n i++;\n continue;\n }\n\n pairs.push({ key, value: valueResult.value.trim() });\n i = valueResult.nextPos;\n }\n\n return pairs;\n}\n\n/**\n * 从位置 i 开始解析键名。\n * 支持带引号和不带引号的标识符。\n */\nfunction parseKey(\n content: string,\n start: number,\n): { key: string; nextPos: number } | null {\n if (start >= content.length) return null;\n\n // 带引号的 key\n if (content[start] === '\"' || content[start] === \"'\") {\n const quote = content[start];\n let i = start + 1;\n while (i < content.length && content[i] !== quote) {\n if (content[i] === '\\\\') i++;\n i++;\n }\n if (i >= content.length) return null;\n return {\n key: content.slice(start + 1, i),\n nextPos: i + 1,\n };\n }\n\n // 不带引号的 key(标识符)\n const match = /^[\\w-]+/.exec(content.slice(start));\n if (!match) return null;\n\n return {\n key: match[0],\n nextPos: start + match[0].length,\n };\n}\n\n/**\n * 从位置 i 开始解析值(在 depth 0)。\n * 支持字符串、数组、嵌套对象(跳过嵌套对象内容,只记录起始位置到结束)。\n */\nfunction parseValue(\n content: string,\n start: number,\n): { value: string; nextPos: number } | null {\n if (start >= content.length) return null;\n\n // 字符串值\n if (content[start] === '\"' || content[start] === \"'\") {\n const quote = content[start];\n let i = start + 1;\n while (i < content.length && content[i] !== quote) {\n if (content[i] === '\\\\') i++;\n i++;\n }\n if (i >= content.length) return null;\n return {\n value: content.slice(start, i + 1),\n nextPos: i + 1,\n };\n }\n\n // 数组值\n if (content[start] === '[') {\n let i = start + 1;\n let depth = 1;\n while (i < content.length && depth > 0) {\n if (content[i] === '[') depth++;\n else if (content[i] === ']') depth--;\n i++;\n }\n if (depth !== 0) return null;\n return {\n value: content.slice(start, i),\n nextPos: i,\n };\n }\n\n // 嵌套对象值——跳过整个块\n if (content[start] === '{') {\n let i = start + 1;\n let depth = 1;\n while (i < content.length && depth > 0) {\n if (content[i] === '{') depth++;\n else if (content[i] === '}') depth--;\n i++;\n }\n if (depth !== 0) return null;\n return {\n value: content.slice(start, i),\n nextPos: i,\n };\n }\n\n return null;\n}\n\n// ─── 其他工具 ─────────────────────────────────────────────────────\n\n/**\n * 从 tailwind config 提取 darkMode 策略。\n *\n * 匹配 darkMode: \"class\" / darkMode: \"media\"\n */\nfunction extractDarkMode(content: string): string | null {\n const match = content.match(/darkMode\\s*:\\s*['\"](\\w+)['\"]/);\n return match?.[1] ?? null;\n}\n\n/**\n * 去掉 JS/TS 注释,避免从注释里的示例配置误提取 darkMode。\n * 保留字符串内容,防止 URL 或文字里的 // 被误删。\n */\nfunction stripJsComments(content: string): string {\n let result = '';\n let i = 0;\n let quote: '\"' | \"'\" | '`' | null = null;\n\n while (i < content.length) {\n const ch = content[i];\n const next = content[i + 1];\n\n if (quote) {\n result += ch;\n if (ch === '\\\\') {\n i++;\n if (i < content.length) result += content[i];\n } else if (ch === quote) {\n quote = null;\n }\n i++;\n continue;\n }\n\n if (ch === '\"' || ch === \"'\" || ch === '`') {\n quote = ch;\n result += ch;\n i++;\n continue;\n }\n\n if (ch === '/' && next === '/') {\n while (i < content.length && content[i] !== '\\n') i++;\n result += '\\n';\n continue;\n }\n\n if (ch === '/' && next === '*') {\n i += 2;\n while (\n i < content.length &&\n !(content[i] === '*' && content[i + 1] === '/')\n ) {\n if (content[i] === '\\n') result += '\\n';\n i++;\n }\n i += 2;\n continue;\n }\n\n result += ch;\n i++;\n }\n\n return result;\n}\n\nasync function scanComponents(projectRoot: string): Promise<string[]> {\n const roots = ['src/components', 'components', 'app/components'];\n const names = new Set<string>();\n let visitedFiles = 0;\n for (const relRoot of roots) {\n const absRoot = path.join(projectRoot, relRoot);\n if (!(await pathExists(absRoot))) continue;\n visitedFiles = await collectComponentNames(absRoot, names, 0, visitedFiles);\n if (visitedFiles >= MAX_COMPONENT_FILES) break;\n }\n return Array.from(names).sort();\n}\n\nasync function collectComponentNames(\n dir: string,\n names: Set<string>,\n depth: number,\n visitedFiles: number,\n): Promise<number> {\n if (depth > MAX_COMPONENT_SCAN_DEPTH || visitedFiles >= MAX_COMPONENT_FILES) {\n return visitedFiles;\n }\n let fileCount = visitedFiles;\n let entries: string[];\n try {\n entries = await fs.readdir(dir);\n } catch {\n return fileCount;\n }\n\n for (const entry of entries) {\n if (fileCount >= MAX_COMPONENT_FILES) return fileCount;\n const abs = path.join(dir, entry);\n let info: Stats;\n try {\n info = await fs.lstat(abs);\n } catch {\n continue;\n }\n if (info.isSymbolicLink()) continue;\n if (info.isDirectory()) {\n fileCount = await collectComponentNames(abs, names, depth + 1, fileCount);\n continue;\n }\n if (!/\\.(tsx|jsx|ts|js|vue|svelte)$/.test(entry)) continue;\n fileCount++;\n if (isNonComponentFile(entry)) continue;\n let base = entry.replace(/\\.(tsx|jsx|ts|js|vue|svelte)$/, '');\n if (base === 'index') {\n base = path.basename(dir);\n }\n if (base.startsWith('.')) continue;\n const componentName = toPascalCase(base);\n if (isSafeComponentName(componentName)) {\n names.add(componentName);\n }\n }\n return fileCount;\n}\n\nasync function scanCssVariables(\n projectRoot: string,\n): Promise<{ variables: Record<string, string>; sourceFiles: string[] }> {\n const candidates = [\n 'src/app/globals.css',\n 'src/index.css',\n 'src/globals.css',\n 'app/globals.css',\n 'styles/globals.css',\n 'globals.css',\n ];\n const variables: Record<string, string> = {};\n const sourceFiles: string[] = [];\n for (const relPath of candidates) {\n const absPath = path.join(projectRoot, relPath);\n if (!(await pathExists(absPath))) continue;\n const content = await fs.readFile(absPath, 'utf-8');\n const found = extractCssVariables(content);\n if (Object.keys(found).length === 0) continue;\n Object.assign(variables, found);\n sourceFiles.push(relPath);\n }\n return { variables, sourceFiles };\n}\n\nfunction extractCssVariables(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n const withoutComments = content.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n const regex = /--([a-zA-Z0-9-_]+)\\s*:\\s*([^;{}]+);/g;\n let match = regex.exec(withoutComments);\n while (match !== null) {\n const key = match[1];\n const value = match[2]?.trim();\n if (key && value && value.length <= 120 && isSafeCssVariableValue(value)) {\n result[key] = value;\n }\n match = regex.exec(withoutComments);\n }\n return result;\n}\n\nfunction isSafeColorValue(value: string): boolean {\n return /^[#\\w\\s,.%()/+-]+$/.test(value);\n}\n\nfunction isSafeCssVariableValue(value: string): boolean {\n return /^[#\\w\\s,.%()/+-]+$/.test(value);\n}\n\nfunction isSafeTokenName(value: string): boolean {\n return /^[A-Za-z0-9_-]{1,80}$/.test(value);\n}\n\nfunction isSafeComponentName(value: string): boolean {\n return /^[A-Z][A-Za-z0-9]{0,79}$/.test(value);\n}\n\nfunction isNonComponentFile(filename: string): boolean {\n return /\\.(test|spec|stories|story|d)\\.(tsx|jsx|ts|js)$/.test(filename);\n}\n\nfunction toPascalCase(value: string): string {\n return value\n .split(/[-_\\s]+/)\n .filter(Boolean)\n .map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`)\n .join('');\n}\n\n/**\n * 检查 package.json 是否有 tailwindcss 依赖。\n */\nasync function hasTailwindDep(projectRoot: string): Promise<boolean> {\n try {\n const raw = await fs.readFile(\n path.join(projectRoot, 'package.json'),\n 'utf-8',\n );\n const pkg = JSON.parse(raw) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n return Boolean(\n pkg.dependencies?.tailwindcss || pkg.devDependencies?.tailwindcss,\n );\n } catch {\n return false;\n }\n}\n\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await fs.access(p);\n return true;\n } catch {\n return false;\n }\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport process from 'node:process';\nimport { checkPlatformStatus } from '../installers/platform-status.js';\nimport {\n formatPlatformName,\n getPlatformInstaller,\n getPlatformInstallers,\n} from '../installers/registry.js';\nimport { detectProjectType } from '../system/detect.js';\nimport { DEFAULT_CONFIG } from '../templates/defaults.js';\n\n/**\n * 退出码契约 — 见 docs/08-cli-spec.md §3\n */\nexport const EXIT_OK = 0;\nexport const EXIT_NOT_INITIALIZED = 1;\nexport const EXIT_UNSUPPORTED_PLATFORM = 2;\nexport const EXIT_INSTALL_FAILED = 3;\n\ninterface ConfigReadResult {\n config: Record<string, unknown>;\n valid: boolean;\n}\n\nexport interface InstallOptions {\n /** --force: 覆盖已有配置 */\n force?: boolean;\n /** --minimal: 最小安装(MVP-2 预留) */\n minimal?: boolean;\n}\n\n/**\n * `mancode install <platform>` 命令。\n *\n * 职责(docs/08-cli-spec.md §3 + docs/15-adapters.md §8):\n * 1. 检查项目已初始化(state.json 存在)\n * 2. 验证平台名\n * 3. 调用对应适配器安装\n * 4. 更新 config.json 的 platforms 数组\n * 5. 支持 --force 重装\n *\n * @param rootDir 目标项目根目录\n * @param platform 平台名(如 'claude-code')\n * @param options CLI 参数\n * @returns 退出码\n */\nexport async function install(\n rootDir: string = process.cwd(),\n platform = 'claude-code',\n options: InstallOptions = {},\n): Promise<number> {\n const stateFile = path.join(rootDir, '.mancode', 'state.json');\n\n // 1. 检查是否已初始化\n if (!(await pathExists(stateFile))) {\n console.error('✗ mancode not initialized.');\n console.error(' Run `mancode init` first.');\n return EXIT_NOT_INITIALIZED;\n }\n\n // 2. 验证平台名\n const installer = getPlatformInstaller(platform);\n if (!installer) {\n console.error(`✗ Unsupported platform: ${platform}`);\n console.error(' Supported platforms:');\n for (const item of getPlatformInstallers()) {\n console.error(` ${item.name.padEnd(20)} ${item.displayName}`);\n }\n return EXIT_UNSUPPORTED_PLATFORM;\n }\n\n // 3. 检查是否已安装(除非 --force)\n let configResult: ConfigReadResult;\n try {\n configResult = await readConfig(rootDir);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`✗ Cannot read .mancode/config.json: ${msg}`);\n return EXIT_INSTALL_FAILED;\n }\n const config = withDefaultConfig(\n configResult.config,\n await readStatePlatform(rootDir),\n );\n const alreadyInstalled =\n configResult.valid && config.platforms && Array.isArray(config.platforms)\n ? config.platforms.includes(platform)\n : false;\n\n if (alreadyInstalled && !options.force) {\n const status = await checkPlatformStatus(rootDir, platform, true);\n if (status.ready) {\n console.log(\n `ℹ️ ${formatPlatformName(platform)} adapter already installed.`,\n );\n console.log(' Run with --force to reinstall.');\n return EXIT_OK;\n }\n console.log(\n `ℹ️ ${formatPlatformName(platform)} is recorded in config but not ready; repairing generated files.`,\n );\n }\n\n // 4. 安装\n console.log(`✓ Installing ${formatPlatformName(platform)} adapter...`);\n const project = await detectProjectType(rootDir);\n try {\n await installer.install(rootDir, {\n techStack: project.techStack,\n uiLibrary: project.uiLibrary,\n minimal: options.minimal,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(\n `✗ ${formatPlatformName(platform)} adapter install failed: ${msg}`,\n );\n return EXIT_INSTALL_FAILED;\n }\n\n // 5. 更新 config.json platforms\n const platforms = Array.isArray(config.platforms) ? config.platforms : [];\n if (!platforms.includes(platform)) {\n platforms.push(platform);\n }\n await updateConfig(rootDir, { ...config, platforms });\n\n // 6. 完成\n console.log(`✓ ${formatPlatformName(platform)} adapter installed.`);\n return EXIT_OK;\n}\n\n/**\n * 读取 .mancode/config.json。\n */\nasync function readConfig(rootDir: string): Promise<ConfigReadResult> {\n const configPath = path.join(rootDir, '.mancode', 'config.json');\n try {\n const raw = await fs.readFile(configPath, 'utf-8');\n return { config: JSON.parse(raw) as Record<string, unknown>, valid: true };\n } catch (err) {\n if (isNodeError(err) && err.code === 'ENOENT') {\n return { config: {}, valid: false };\n }\n // config.json 损坏时不要静默覆盖,避免丢失用户配置。\n throw err;\n }\n}\n\nfunction isNodeError(err: unknown): err is NodeJS.ErrnoException {\n return err instanceof Error && 'code' in err;\n}\n\n/**\n * 写入 .mancode/config.json。\n */\nasync function updateConfig(\n rootDir: string,\n config: Record<string, unknown>,\n): Promise<void> {\n const configPath = path.join(rootDir, '.mancode', 'config.json');\n const content = `${JSON.stringify(config, null, 2)}\\n`;\n await fs.writeFile(configPath, content, 'utf-8');\n}\n\nfunction withDefaultConfig(\n config: Record<string, unknown>,\n fallbackPlatform: string | null,\n): Record<string, unknown> {\n const fallback = fallbackPlatform ?? DEFAULT_CONFIG.platforms[0];\n const platforms = Array.isArray(config.platforms)\n ? config.platforms\n : [fallback];\n const merged = {\n ...DEFAULT_CONFIG,\n ...config,\n };\n return {\n ...merged,\n platforms,\n hooks: isRecord(config.hooks) ? config.hooks : DEFAULT_CONFIG.hooks,\n logging: isRecord(config.logging) ? config.logging : DEFAULT_CONFIG.logging,\n };\n}\n\nasync function readStatePlatform(rootDir: string): Promise<string | null> {\n try {\n const raw = await fs.readFile(\n path.join(rootDir, '.mancode', 'state.json'),\n 'utf-8',\n );\n const state = JSON.parse(raw) as { platform?: unknown };\n return typeof state.platform === 'string' ? state.platform : null;\n } catch {\n return null;\n }\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await fs.access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { MANCODE_CURSOR_CORE_RULE_FILES } from './cursor.js';\nimport {\n DEFAULT_MANCODE_END_MARKER,\n DEFAULT_MANCODE_START_MARKER,\n} from './managed-block.js';\n\nexport interface PlatformStatus {\n installed: boolean;\n ready: boolean;\n target: string;\n detail: string;\n}\n\nexport async function checkPlatformStatus(\n rootDir: string,\n platform: string,\n installed: boolean,\n): Promise<PlatformStatus> {\n const readiness = await checkPlatformReadiness(rootDir, platform);\n return {\n installed,\n ready: installed && readiness.present,\n target: readiness.target,\n detail: describeStatus(installed, readiness),\n };\n}\n\nasync function checkPlatformReadiness(\n rootDir: string,\n platform: string,\n): Promise<{ present: boolean; target: string; readyDetail: string }> {\n if (platform === 'claude-code') {\n const hasSoloSkill = await pathExists(\n path.join(rootDir, '.claude', 'skills', 'solo', 'SKILL.md'),\n );\n const registered = await claudeHooksRegistered(rootDir);\n return {\n present: hasSoloSkill && registered,\n target: '.claude/',\n readyDetail: 'skills and hooks registered',\n };\n }\n\n if (platform === 'cursor') {\n const present = await allPathsExist(\n MANCODE_CURSOR_CORE_RULE_FILES.map((file) =>\n path.join(rootDir, '.cursor', 'rules', file),\n ),\n );\n return {\n present,\n target: '.cursor/rules/',\n readyDetail: 'mancode rules present',\n };\n }\n\n if (platform === 'codex') {\n return {\n present: await fileHasManagedBlock(path.join(rootDir, 'AGENTS.md')),\n target: 'AGENTS.md',\n readyDetail: 'managed block present',\n };\n }\n\n return {\n present: await fileHasManagedBlock(\n path.join(rootDir, '.github', 'copilot-instructions.md'),\n ),\n target: '.github/copilot-instructions.md',\n readyDetail: 'managed block present',\n };\n}\n\nfunction describeStatus(\n installed: boolean,\n readiness: { present: boolean; readyDetail: string },\n): string {\n if (installed && readiness.present) return readiness.readyDetail;\n if (!installed && readiness.present) {\n return 'target files present but platform is not recorded in config';\n }\n return 'missing generated files or registration';\n}\n\nasync function allPathsExist(paths: string[]): Promise<boolean> {\n const results = await Promise.all(paths.map(pathExists));\n return results.every(Boolean);\n}\n\nasync function fileHasManagedBlock(filePath: string): Promise<boolean> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n return (\n content.includes(DEFAULT_MANCODE_START_MARKER) &&\n content.includes(DEFAULT_MANCODE_END_MARKER)\n );\n } catch {\n return false;\n }\n}\n\nasync function claudeHooksRegistered(rootDir: string): Promise<boolean> {\n try {\n const raw = await fs.readFile(\n path.join(rootDir, '.claude', 'settings.json'),\n 'utf-8',\n );\n const settings = JSON.parse(raw);\n return hooksRegistered(settings);\n } catch {\n return false;\n }\n}\n\nfunction hooksRegistered(settings: unknown): boolean {\n if (!isRecord(settings)) return false;\n const hooks = settings.hooks;\n if (!isRecord(hooks)) return false;\n\n return (\n hasHookCommand(hooks.SessionStart, '.mancode/hooks/session-start.sh') &&\n hasHookCommand(\n hooks.UserPromptSubmit,\n '.mancode/hooks/user-prompt-submit.sh',\n )\n );\n}\n\nfunction hasHookCommand(value: unknown, needle: string): boolean {\n if (!Array.isArray(value)) return false;\n return value.some((group) => {\n if (!isRecord(group) || !Array.isArray(group.hooks)) return false;\n return group.hooks.some((hook) => {\n if (!isRecord(hook) || typeof hook.command !== 'string') return false;\n return hook.command.includes(needle);\n });\n });\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await fs.access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport process from 'node:process';\nimport {\n type PlatformInstaller,\n getPlatformInstallers,\n} from '../installers/registry.js';\n\nexport const EXIT_OK = 0;\n\nexport async function listPlatforms(\n rootDir: string = process.cwd(),\n): Promise<number> {\n const installed = new Set(await readInstalledPlatforms(rootDir));\n const platforms = getPlatformInstallers();\n\n console.log('');\n console.log('Available platforms:');\n for (const platform of platforms) {\n console.log(formatPlatformLine(platform, installed.has(platform.name)));\n }\n console.log('');\n\n return EXIT_OK;\n}\n\nasync function readInstalledPlatforms(rootDir: string): Promise<string[]> {\n try {\n const raw = await fs.readFile(\n path.join(rootDir, '.mancode', 'config.json'),\n 'utf-8',\n );\n const config = JSON.parse(raw) as { platforms?: unknown };\n return Array.isArray(config.platforms)\n ? config.platforms.filter(\n (item): item is string => typeof item === 'string',\n )\n : [];\n } catch {\n return [];\n }\n}\n\nfunction formatPlatformLine(\n platform: PlatformInstaller,\n installed: boolean,\n): string {\n const marker = installed ? '✓' : '○';\n const capability = describePlatform(platform);\n return ` ${marker} ${platform.name.padEnd(12)} ${platform.displayName.padEnd(16)} ${capability}`;\n}\n\nfunction describePlatform(platform: PlatformInstaller): string {\n if (platform.capabilities.hooks && platform.capabilities.subagents) {\n return 'skills + agents + hooks';\n }\n return platform.capabilities.skills;\n}\n","import { access } from 'node:fs/promises';\nimport path from 'node:path';\nimport { createInterface } from 'node:readline/promises';\nimport {\n type PreseasonRemediationResult,\n type PreseasonReport,\n runPreseasonRemediation,\n runPreseasonScan,\n} from '../system/preseason.js';\n\nexport const EXIT_OK = 0;\nexport const EXIT_NOT_INITIALIZED = 1;\nexport const EXIT_SCAN_FAILED = 2;\nexport const EXIT_INVALID_ARG = 3;\n\nexport interface ManpsOptions {\n json?: boolean;\n remediate?: boolean;\n answers?: string[];\n}\n\nexport async function manps(\n rootDir: string,\n area = 'all',\n options: ManpsOptions = {},\n): Promise<number> {\n if (!(await pathExists(path.join(rootDir, '.mancode', 'state.json')))) {\n if (options.json) {\n console.log(JSON.stringify({ error: 'not initialized' }, null, 2));\n } else {\n console.error('✗ mancode not initialized.');\n console.error(' Run `mancode init` first.');\n }\n return EXIT_NOT_INITIALIZED;\n }\n\n let report: PreseasonReport;\n try {\n report = await runPreseasonScan(rootDir, area);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const invalidArg = message.startsWith('invalid area:');\n if (options.json) {\n console.log(\n JSON.stringify(\n { error: invalidArg ? 'invalid argument' : 'scan failed', message },\n null,\n 2,\n ),\n );\n } else {\n console.error(\n invalidArg\n ? '✗ Invalid manps area.'\n : '✗ mancode preseason scan failed.',\n );\n console.error(` ${message}`);\n }\n return invalidArg ? EXIT_INVALID_ARG : EXIT_SCAN_FAILED;\n }\n let remediation: PreseasonRemediationResult | undefined;\n if (options.remediate) {\n if (options.json && process.stdin.isTTY && !options.answers) {\n console.log(\n JSON.stringify(\n {\n error: 'invalid argument',\n message:\n '--json --remediate requires piped answers; omit --json for interactive review.',\n },\n null,\n 2,\n ),\n );\n return EXIT_INVALID_ARG;\n }\n try {\n remediation = await runRemediation(\n rootDir,\n report,\n options,\n options.json,\n );\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (options.json) {\n console.log(\n JSON.stringify({ error: 'invalid argument', message }, null, 2),\n );\n } else {\n console.error('✗ mancode preseason remediation failed.');\n console.error(` ${message}`);\n }\n return EXIT_INVALID_ARG;\n }\n }\n\n if (options.json) {\n console.log(JSON.stringify({ ...report, remediation }, null, 2));\n return EXIT_OK;\n }\n\n const p0 = report.issues.filter((issue) => issue.severity === 'P0').length;\n const p1 = report.issues.filter((issue) => issue.severity === 'P1').length;\n const p2 = report.issues.filter((issue) => issue.severity === 'P2').length;\n console.log('mancode preseason scan');\n console.log('');\n console.log(`Area: ${report.area}`);\n console.log(\n `Issues: ${report.issues.length} total (P0 ${p0}, P1 ${p1}, P2 ${p2})`,\n );\n console.log(`Report: ${path.relative(rootDir, report.reportPath)}`);\n console.log(`Issue DB: ${path.relative(rootDir, report.issueDbPath)}`);\n if (report.issues.length > 0) {\n console.log('');\n for (const issue of report.issues.slice(0, 7)) {\n const file = issue.file ? ` (${issue.file})` : '';\n console.log(`- ${issue.severity} ${issue.id}: ${issue.title}${file}`);\n }\n }\n if (remediation) {\n console.log('');\n console.log('Remediation review:');\n console.log(` Reviewed: ${remediation.reviewed}`);\n console.log(` Accepted: ${remediation.accepted}`);\n console.log(` Skipped: ${remediation.skipped}`);\n console.log(` Fixed: ${remediation.fixed}`);\n console.log(\n ` Issue DB: ${path.relative(rootDir, remediation.issueDbPath)}`,\n );\n }\n return EXIT_OK;\n}\n\nasync function runRemediation(\n rootDir: string,\n report: PreseasonReport,\n options: ManpsOptions,\n silent = false,\n): Promise<PreseasonRemediationResult> {\n const write = silent ? () => {} : undefined;\n if (options.answers) {\n return runPreseasonRemediation(rootDir, report.issues, {\n answers: options.answers,\n write,\n });\n }\n\n if (!process.stdin.isTTY) {\n const answers = await readStdinLines();\n if (answers.length === 0 && report.issues.length > 0) {\n throw new Error(\n 'non-interactive remediation requires piped answers for each open issue',\n );\n }\n return runPreseasonRemediation(rootDir, report.issues, {\n answers,\n write,\n });\n }\n\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n try {\n return await runPreseasonRemediation(rootDir, report.issues, {\n ask: (question) => rl.question(question),\n write,\n });\n } finally {\n rl.close();\n }\n}\n\nasync function readStdinLines(): Promise<string[]> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n return Buffer.concat(chunks)\n .toString('utf-8')\n .split(/\\r?\\n/)\n .filter((line) => line.length > 0);\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n","import { createHash } from 'node:crypto';\nimport { existsSync, readFileSync } from 'node:fs';\nimport type { Stats } from 'node:fs';\nimport {\n lstat,\n mkdir,\n readFile,\n readdir,\n rename,\n writeFile,\n} from 'node:fs/promises';\nimport path from 'node:path';\n\nexport type PreseasonSeverity = 'P0' | 'P1' | 'P2';\nexport type PreseasonIssueType =\n | 'scripts'\n | 'dependency'\n | 'todo'\n | 'tests'\n | 'config'\n | 'aesthetics'\n | 'security';\n\nexport interface PreseasonIssue {\n id: string;\n severity: PreseasonSeverity;\n type: PreseasonIssueType;\n title: string;\n file?: string;\n detail: string;\n recommendation: string;\n}\n\nexport interface PreseasonReport {\n generatedAt: string;\n area: string;\n issues: PreseasonIssue[];\n commandsChecked: string[];\n reportPath: string;\n issueDbPath: string;\n}\n\nexport type PreseasonIssueStatus = 'open' | 'not-found' | 'fixed';\nexport type PreseasonRemediationStatus = 'accepted' | 'skipped';\n\nexport interface PreseasonRemediationState {\n status: PreseasonRemediationStatus;\n decidedAt: string;\n sourceRunId: string;\n response: 'y' | 'n' | 'skip';\n applied?: boolean;\n action?: string;\n}\n\nexport interface PreseasonIssueRecord extends PreseasonIssue {\n key: string;\n status: PreseasonIssueStatus;\n firstSeen: string;\n lastSeen: string;\n lastArea: string;\n occurrences: number;\n sourceReports: string[];\n remediation?: PreseasonRemediationState;\n}\n\nexport interface PreseasonIssueRun {\n id: string;\n generatedAt: string;\n area: string;\n reportPath: string;\n issueCount: number;\n issueKeys: string[];\n}\n\nexport interface PreseasonIssueDatabase {\n version: '1.0.0';\n updatedAt: string;\n latestRunId: string;\n runs: PreseasonIssueRun[];\n issues: PreseasonIssueRecord[];\n}\n\nexport interface PreseasonRemediationOptions {\n answers?: string[];\n ask?: (question: string) => Promise<string>;\n write?: (message: string) => void;\n now?: string;\n}\n\nexport interface PreseasonRemediationResult {\n issueDbPath: string;\n reviewed: number;\n accepted: number;\n skipped: number;\n fixed: number;\n shown: number;\n}\n\ninterface PreseasonRemediationDecision {\n issue: PreseasonIssueRecord;\n response: 'y' | 'n' | 'skip';\n}\n\ntype PreseasonArea = 'all' | 'deps' | 'security' | 'dead-code' | 'config';\nexport const PRESEASON_AREAS: PreseasonArea[] = [\n 'all',\n 'deps',\n 'security',\n 'dead-code',\n 'config',\n];\n\ninterface PackageJson {\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n\nconst IGNORE_DIRS = new Set([\n '.git',\n '.mancode',\n '.claude',\n 'node_modules',\n 'dist',\n 'build',\n 'coverage',\n]);\n\nconst SOURCE_EXTENSIONS = new Set([\n '.js',\n '.jsx',\n '.ts',\n '.tsx',\n '.vue',\n '.svelte',\n '.css',\n '.md',\n]);\nconst MAX_SCAN_DEPTH = 20;\nconst MAX_PROJECT_FILES = 5000;\n\nexport async function runPreseasonScan(\n projectRoot: string,\n area = 'all',\n): Promise<PreseasonReport> {\n const generatedAt = new Date().toISOString();\n const normalizedArea = normalizeArea(area);\n const pkg = await readPackageJson(projectRoot);\n const needsFiles =\n normalizedArea === 'all' ||\n normalizedArea === 'dead-code' ||\n normalizedArea === 'config';\n const files = needsFiles ? await listProjectFiles(projectRoot) : [];\n const issues = scanArea(projectRoot, normalizedArea, pkg, files).slice(0, 20);\n\n const reportDir = path.join(projectRoot, '.mancode', 'preseason-reports');\n await mkdir(reportDir, { recursive: true });\n const issueDbPath = path.join(\n projectRoot,\n '.mancode',\n 'preseason-issues.json',\n );\n const reportPath = await allocateReportPath(\n reportDir,\n `${generatedAt.replace(/[:.]/g, '-')}-${normalizedArea}`,\n );\n const report: PreseasonReport = {\n generatedAt,\n area: normalizedArea,\n issues,\n commandsChecked: inferCommands(pkg),\n reportPath,\n issueDbPath,\n };\n const database = await buildIssueDatabase(projectRoot, report);\n await writeFile(reportPath, renderPreseasonReport(report), 'utf-8');\n await writeFile(\n path.join(projectRoot, '.mancode', 'preseason-report.md'),\n renderPreseasonReport(report),\n 'utf-8',\n );\n await writeJsonAtomic(report.issueDbPath, database);\n return report;\n}\n\nexport async function runPreseasonRemediation(\n projectRoot: string,\n issues: PreseasonIssue[],\n options: PreseasonRemediationOptions = {},\n): Promise<PreseasonRemediationResult> {\n const issueDbPath = path.join(\n projectRoot,\n '.mancode',\n 'preseason-issues.json',\n );\n const database = await readIssueDatabase(issueDbPath);\n const keys = new Set(issues.map((issue) => issueKey(issue)));\n const targets = database.issues.filter(\n (issue) => keys.has(issue.key) && issue.status === 'open',\n );\n const write = options.write ?? ((message: string) => console.log(message));\n const answerQueue = [...(options.answers ?? [])];\n const now = options.now ?? new Date().toISOString();\n const decisions: PreseasonRemediationDecision[] = [];\n let fixed = 0;\n let shown = 0;\n\n if (targets.length === 0) {\n write('No open preseason issues to review.');\n }\n\n for (let index = 0; index < targets.length; index++) {\n const issue = targets[index];\n if (!issue) continue;\n write('');\n write(\n `${index + 1}. ${issue.severity} ${issue.id}: ${issue.title}${issue.file ? ` (${issue.file})` : ''}`,\n );\n write(` Recommendation: ${issue.recommendation}`);\n\n while (true) {\n const raw = await nextRemediationAnswer(\n answerQueue,\n options.ask,\n ' Fix this item? [y/n/skip/show files] ',\n );\n const answer = normalizeRemediationAnswer(raw);\n\n if (answer === 'show') {\n shown++;\n write(` File: ${issue.file ?? 'n/a'}`);\n write(` Detail: ${issue.detail}`);\n continue;\n }\n\n if (answer === 'y') {\n decisions.push({ issue, response: 'y' });\n break;\n }\n\n decisions.push({ issue, response: answer });\n break;\n }\n }\n\n let accepted = 0;\n let skipped = 0;\n for (const decision of decisions) {\n const issue = decision.issue;\n if (decision.response === 'y') {\n const applied = await applySafeRemediation(projectRoot, issue);\n issue.remediation = {\n status: 'accepted',\n decidedAt: now,\n sourceRunId: database.latestRunId,\n response: 'y',\n applied: applied.applied,\n action: applied.action,\n };\n if (applied.applied) {\n issue.status = 'fixed';\n fixed++;\n }\n accepted++;\n write(\n applied.applied\n ? ` Decision: fixed (${applied.action}).`\n : ' Decision: accepted for remediation.',\n );\n continue;\n }\n\n issue.remediation = {\n status: 'skipped',\n decidedAt: now,\n sourceRunId: database.latestRunId,\n response: decision.response,\n };\n skipped++;\n write(' Decision: skipped.');\n }\n\n database.updatedAt = now;\n await writeFile(\n issueDbPath,\n `${JSON.stringify(database, null, 2)}\\n`,\n 'utf-8',\n );\n\n return {\n issueDbPath,\n reviewed: decisions.length,\n accepted,\n skipped,\n fixed,\n shown,\n };\n}\n\nfunction normalizeArea(area: string): PreseasonArea {\n if (PRESEASON_AREAS.includes(area as PreseasonArea)) {\n return area as PreseasonArea;\n }\n throw new Error(\n `invalid area: ${area}. Supported areas: ${PRESEASON_AREAS.join(', ')}`,\n );\n}\n\nfunction scanArea(\n projectRoot: string,\n area: PreseasonArea,\n pkg: PackageJson | null,\n files: string[],\n): PreseasonIssue[] {\n switch (area) {\n case 'deps':\n return scanDependencyOverlap(pkg);\n case 'security':\n return scanSecurity(pkg);\n case 'dead-code':\n return [...scanTodos(projectRoot, files), ...scanTestGaps(files)];\n case 'config':\n return [...scanScripts(pkg), ...scanConfig(projectRoot, files)];\n case 'all':\n return [\n ...scanScripts(pkg),\n ...scanDependencyOverlap(pkg),\n ...scanSecurity(pkg),\n ...scanTodos(projectRoot, files),\n ...scanTestGaps(files),\n ...scanConfig(projectRoot, files),\n ...scanAestheticDrift(projectRoot, files),\n ];\n }\n}\n\nasync function allocateReportPath(\n reportDir: string,\n baseName: string,\n): Promise<string> {\n for (let attempt = 0; attempt < 1000; attempt++) {\n const suffix = attempt === 0 ? '' : `-${attempt + 1}`;\n const candidate = path.join(reportDir, `${baseName}${suffix}.md`);\n if (!existsSync(candidate)) return candidate;\n }\n throw new Error(`unable to allocate preseason report path: ${baseName}`);\n}\n\nexport function renderPreseasonReport(report: PreseasonReport): string {\n const bySeverity = (severity: PreseasonSeverity) =>\n report.issues.filter((issue) => issue.severity === severity);\n\n return `# mancode preseason report\n\nGenerated: ${report.generatedAt}\nArea: ${report.area}\n\n## Summary\n\n- Total issues: ${report.issues.length}\n- P0: ${bySeverity('P0').length}\n- P1: ${bySeverity('P1').length}\n- P2: ${bySeverity('P2').length}\n\n${renderSection('P0: Must Fix Before Shipping', bySeverity('P0'))}\n\n${renderSection('P1: Should Fix Soon', bySeverity('P1'))}\n\n${renderSection('P2: Cleanup Backlog', bySeverity('P2'))}\n\n## Suggested Order\n\n${report.issues.length === 0 ? '- No P0/P1 issues found. Keep normal validation in place.' : report.issues.map((issue, index) => `${index + 1}. ${issue.id}: ${issue.recommendation}`).join('\\n')}\n\n## Commands Checked\n\n${report.commandsChecked.length === 0 ? '- No package scripts found.' : report.commandsChecked.map((cmd) => `- ${cmd}`).join('\\n')}\n`;\n}\n\nasync function listProjectFiles(projectRoot: string): Promise<string[]> {\n const results: string[] = [];\n await walk(projectRoot, projectRoot, results, 0);\n return results.sort();\n}\n\nasync function walk(\n root: string,\n current: string,\n results: string[],\n depth: number,\n): Promise<void> {\n if (depth > MAX_SCAN_DEPTH || results.length >= MAX_PROJECT_FILES) return;\n let entries: string[];\n try {\n entries = await readdir(current);\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (IGNORE_DIRS.has(entry)) continue;\n const abs = path.join(current, entry);\n const rel = path.relative(root, abs);\n let info: Stats;\n try {\n info = await lstat(abs);\n } catch {\n continue;\n }\n if (info.isSymbolicLink()) continue;\n if (info.isDirectory()) {\n await walk(root, abs, results, depth + 1);\n } else if (\n SOURCE_EXTENSIONS.has(path.extname(entry)) ||\n entry === 'package.json'\n ) {\n results.push(rel);\n if (results.length >= MAX_PROJECT_FILES) return;\n }\n }\n}\n\nasync function readPackageJson(\n projectRoot: string,\n): Promise<PackageJson | null> {\n try {\n const raw = await readFile(path.join(projectRoot, 'package.json'), 'utf-8');\n return JSON.parse(raw) as PackageJson;\n } catch {\n return null;\n }\n}\n\nfunction scanScripts(pkg: PackageJson | null): PreseasonIssue[] {\n if (!pkg) {\n return [\n {\n id: 'config-001',\n severity: 'P1',\n type: 'config',\n title: 'package.json not found',\n file: 'package.json',\n detail:\n 'No package.json was found, so mancode cannot infer validation commands.',\n recommendation:\n 'Add package.json scripts or document validation commands in README.',\n },\n ];\n }\n\n const scripts = pkg.scripts ?? {};\n const issues: PreseasonIssue[] = [];\n for (const name of ['test', 'lint', 'build']) {\n if (!scripts[name]) {\n issues.push({\n id: `scripts-${name}`,\n severity: name === 'test' ? 'P1' : 'P2',\n type: 'scripts',\n title: `Missing npm ${name} script`,\n file: 'package.json',\n detail: `package.json has no \"${name}\" script.`,\n recommendation: `Add an npm \"${name}\" script or document why this project does not need one.`,\n });\n }\n }\n return issues;\n}\n\nfunction scanDependencyOverlap(pkg: PackageJson | null): PreseasonIssue[] {\n if (!pkg) return [];\n const deps = new Set([\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ]);\n const pairs: Array<[string, string]> = [\n ['moment', 'dayjs'],\n ['lodash', 'underscore'],\n ['axios', 'ky'],\n ['jest', 'vitest'],\n ];\n return pairs\n .filter(([a, b]) => deps.has(a) && deps.has(b))\n .map(([a, b], index) => ({\n id: `dependency-${index + 1}`,\n severity: 'P2' as const,\n type: 'dependency' as const,\n title: `Overlapping dependencies: ${a} and ${b}`,\n file: 'package.json',\n detail: `Both ${a} and ${b} are installed. They may overlap in purpose.`,\n recommendation:\n 'Choose one default for new code and plan removal if the other is unused.',\n }));\n}\n\nfunction scanSecurity(pkg: PackageJson | null): PreseasonIssue[] {\n if (!pkg) return [];\n const deps = new Set([\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ]);\n const risky = [\n {\n name: 'serialize-javascript',\n detail:\n 'Historically security-sensitive package. Version should be audited.',\n },\n {\n name: 'node-sass',\n detail:\n 'Deprecated native dependency. Prefer sass unless the project is pinned intentionally.',\n },\n {\n name: 'request',\n detail:\n 'Deprecated HTTP client. Prefer a maintained client for new code.',\n },\n ];\n return risky\n .filter((item) => deps.has(item.name))\n .map((item, index) => ({\n id: `security-${index + 1}`,\n severity: 'P1' as const,\n type: 'security' as const,\n title: `Security review needed: ${item.name}`,\n file: 'package.json',\n detail: item.detail,\n recommendation:\n 'Run the project vulnerability scanner and plan replacement or pinning if needed.',\n }));\n}\n\nfunction scanTodos(projectRoot: string, files: string[]): PreseasonIssue[] {\n const matches: PreseasonIssue[] = [];\n for (const file of files) {\n if (matches.length >= 7) break;\n const abs = path.join(projectRoot, file);\n matches.push(...readTodoIssues(abs, file, matches.length));\n }\n return matches.slice(0, 7);\n}\n\nfunction readTodoIssues(\n abs: string,\n rel: string,\n offset: number,\n): PreseasonIssue[] {\n try {\n const content = readFileSyncSafe(abs);\n const lines = content.split('\\n');\n const issues: PreseasonIssue[] = [];\n for (let i = 0; i < lines.length && issues.length < 2; i++) {\n if (\n /\\b(TODO|FIXME|HACK|XXX|deprecated|legacy|temporary|workaround)\\b/i.test(\n lines[i] ?? '',\n )\n ) {\n issues.push({\n id: `todo-${offset + issues.length + 1}`,\n severity: 'P2',\n type: 'todo',\n title: 'Stale maintenance marker',\n file: `${rel}:${i + 1}`,\n detail: (lines[i] ?? '').trim().slice(0, 160),\n recommendation:\n 'Turn this marker into a tracked issue, fix it, or remove it if stale.',\n });\n }\n }\n return issues;\n } catch {\n return [];\n }\n}\n\nfunction scanTestGaps(files: string[]): PreseasonIssue[] {\n const sourceFiles = files.filter(\n (file) =>\n file.startsWith('src/') &&\n /\\.(ts|tsx|js|jsx)$/.test(file) &&\n !file.endsWith('.d.ts') &&\n !file.includes('/templates/'),\n );\n if (sourceFiles.length === 0) return [];\n\n const tests = new Set(files.filter((file) => file.startsWith('tests/')));\n const missing = sourceFiles\n .filter((file) => {\n const base = path.basename(file).replace(/\\.(ts|tsx|js|jsx)$/, '');\n return !Array.from(tests).some((test) => test.includes(base));\n })\n .slice(0, 4);\n\n return missing.map((file, index) => ({\n id: `tests-${index + 1}`,\n severity: 'P1',\n type: 'tests',\n title: 'Core source file has no obvious test',\n file,\n detail: `No matching test file was found for ${path.basename(file)}.`,\n recommendation:\n 'Add focused coverage for the public behavior or document why this module is exercised indirectly.',\n }));\n}\n\nfunction scanConfig(projectRoot: string, files: string[]): PreseasonIssue[] {\n const issues: PreseasonIssue[] = [];\n if (\n !files.includes('.gitignore') &&\n !pathExistsSync(path.join(projectRoot, '.gitignore'))\n ) {\n issues.push({\n id: 'config-gitignore',\n severity: 'P1',\n type: 'config',\n title: 'Missing .gitignore',\n file: '.gitignore',\n detail: 'No .gitignore found at the project root.',\n recommendation:\n 'Add a .gitignore that excludes dependencies, build output, coverage, and local env files.',\n });\n }\n if (\n !files.includes('.editorconfig') &&\n !pathExistsSync(path.join(projectRoot, '.editorconfig'))\n ) {\n issues.push({\n id: 'config-editorconfig',\n severity: 'P2',\n type: 'config',\n title: 'Missing .editorconfig',\n file: '.editorconfig',\n detail: 'No .editorconfig found at the project root.',\n recommendation:\n 'Add a small .editorconfig to keep indentation, charset, and line endings consistent across editors.',\n });\n }\n return issues;\n}\n\nfunction scanAestheticDrift(\n projectRoot: string,\n files: string[],\n): PreseasonIssue[] {\n const issues: PreseasonIssue[] = [];\n const frontendFiles = files.filter((file) => /\\.(tsx|jsx|css)$/.test(file));\n for (const file of frontendFiles) {\n let content: string;\n try {\n content = readFileSyncSafe(path.join(projectRoot, file));\n } catch {\n continue;\n }\n if (containsHardcodedColor(content)) {\n issues.push({\n id: 'aesthetics-hardcoded-color',\n severity: 'P2',\n type: 'aesthetics',\n title: 'Hardcoded color found',\n file,\n detail: 'A frontend file contains a raw hex color.',\n recommendation:\n 'Use project design tokens or CSS variables instead of raw colors.',\n });\n break;\n }\n }\n return issues;\n}\n\nfunction containsHardcodedColor(content: string): boolean {\n return content\n .split('\\n')\n .some(\n (line) =>\n /#[0-9a-fA-F]{3,8}\\b/.test(line) &&\n !/^\\s*--[a-zA-Z0-9-_]+\\s*:/.test(line),\n );\n}\n\nfunction inferCommands(pkg: PackageJson | null): string[] {\n const scripts = pkg?.scripts ?? {};\n return ['lint', 'test', 'build']\n .filter((name) => scripts[name])\n .map((name) => `npm run ${name}`);\n}\n\nasync function buildIssueDatabase(\n projectRoot: string,\n report: PreseasonReport,\n): Promise<PreseasonIssueDatabase> {\n const reportRef = path.relative(projectRoot, report.reportPath);\n const run: PreseasonIssueRun = {\n id: path.basename(report.reportPath, '.md'),\n generatedAt: report.generatedAt,\n area: report.area,\n reportPath: reportRef,\n issueCount: report.issues.length,\n issueKeys: report.issues.map((issue) => issueKey(issue)),\n };\n const existing = await readIssueDatabase(report.issueDbPath);\n const currentKeys = new Set(run.issueKeys);\n const records = new Map(\n existing.issues.map((issue) => [issue.key, { ...issue }]),\n );\n\n for (const issue of report.issues) {\n const key = issueKey(issue);\n const previous = records.get(key);\n records.set(key, {\n ...issue,\n key,\n status: 'open',\n firstSeen: previous?.firstSeen ?? report.generatedAt,\n lastSeen: report.generatedAt,\n lastArea: report.area,\n occurrences: (previous?.occurrences ?? 0) + 1,\n sourceReports: appendUnique(previous?.sourceReports ?? [], reportRef, 5),\n });\n }\n\n for (const [key, issue] of records) {\n if (\n !currentKeys.has(key) &&\n issue.status === 'open' &&\n areaCoversIssueType(report.area, issue.type)\n ) {\n records.set(key, { ...issue, status: 'not-found' });\n }\n }\n\n return {\n version: '1.0.0',\n updatedAt: report.generatedAt,\n latestRunId: run.id,\n runs: [...existing.runs, run].slice(-50),\n issues: Array.from(records.values()).sort(compareIssueRecords),\n };\n}\n\nasync function readIssueDatabase(\n issueDbPath: string,\n): Promise<PreseasonIssueDatabase> {\n let raw: string;\n try {\n raw = await readFile(issueDbPath, 'utf-8');\n } catch (err) {\n if (isNodeError(err) && err.code === 'ENOENT') {\n return emptyIssueDatabase();\n }\n throw err;\n }\n\n const parsed = JSON.parse(raw) as Partial<PreseasonIssueDatabase>;\n if (\n parsed.version === '1.0.0' &&\n Array.isArray(parsed.runs) &&\n Array.isArray(parsed.issues)\n ) {\n return {\n version: '1.0.0',\n updatedAt: parsed.updatedAt ?? '',\n latestRunId: parsed.latestRunId ?? '',\n runs: parsed.runs,\n issues: parsed.issues,\n };\n }\n\n throw new Error(`invalid preseason issue database: ${issueDbPath}`);\n}\n\nasync function writeJsonAtomic(\n file: string,\n value: PreseasonIssueDatabase,\n): Promise<void> {\n const tmp = `${file}.tmp-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n await writeFile(tmp, `${JSON.stringify(value, null, 2)}\\n`, 'utf-8');\n await rename(tmp, file);\n}\n\nfunction emptyIssueDatabase(): PreseasonIssueDatabase {\n return {\n version: '1.0.0',\n updatedAt: '',\n latestRunId: '',\n runs: [],\n issues: [],\n };\n}\n\nfunction issueKey(issue: PreseasonIssue): string {\n const stableParts = [\n issue.type,\n issue.title,\n issue.file ?? '',\n issue.detail,\n ].join('\\0');\n return createHash('sha1').update(stableParts).digest('hex').slice(0, 12);\n}\n\nfunction areaCoversIssueType(area: string, type: PreseasonIssueType): boolean {\n if (area === 'all') return true;\n if (area === 'deps') return type === 'dependency';\n if (area === 'security') return type === 'security';\n if (area === 'dead-code') return type === 'todo' || type === 'tests';\n if (area === 'config') return type === 'scripts' || type === 'config';\n return false;\n}\n\nfunction appendUnique(values: string[], next: string, limit: number): string[] {\n return [...values.filter((value) => value !== next), next].slice(-limit);\n}\n\nfunction compareIssueRecords(\n a: PreseasonIssueRecord,\n b: PreseasonIssueRecord,\n): number {\n const severityOrder: Record<PreseasonSeverity, number> = {\n P0: 0,\n P1: 1,\n P2: 2,\n };\n return (\n severityOrder[a.severity] - severityOrder[b.severity] ||\n a.type.localeCompare(b.type) ||\n a.title.localeCompare(b.title) ||\n a.key.localeCompare(b.key)\n );\n}\n\nasync function applySafeRemediation(\n projectRoot: string,\n issue: PreseasonIssueRecord,\n): Promise<{ applied: boolean; action?: string }> {\n if (issue.id === 'config-gitignore' && issue.file === '.gitignore') {\n const gitignorePath = path.join(projectRoot, '.gitignore');\n if (pathExistsSync(gitignorePath)) {\n return { applied: false };\n }\n await writeFile(gitignorePath, `${DEFAULT_GITIGNORE}\\n`, 'utf-8');\n return { applied: true, action: 'created .gitignore' };\n }\n if (issue.id === 'config-editorconfig' && issue.file === '.editorconfig') {\n const editorconfigPath = path.join(projectRoot, '.editorconfig');\n if (pathExistsSync(editorconfigPath)) {\n return { applied: false };\n }\n await writeFile(editorconfigPath, `${DEFAULT_EDITORCONFIG}\\n`, 'utf-8');\n return { applied: true, action: 'created .editorconfig' };\n }\n if (issue.type === 'scripts' && issue.file === 'package.json') {\n const scriptName = issue.id.replace(/^scripts-/, '');\n const script = await inferSafePackageScript(projectRoot, scriptName);\n if (!script) return { applied: false };\n const applied = await addPackageScript(projectRoot, scriptName, script);\n return applied\n ? { applied: true, action: `added npm ${scriptName} script` }\n : { applied: false };\n }\n return { applied: false };\n}\n\nasync function inferSafePackageScript(\n projectRoot: string,\n scriptName: string,\n): Promise<string | null> {\n const pkg = await readPackageJson(projectRoot);\n if (!pkg) return null;\n if (pkg.scripts?.[scriptName]) return null;\n\n switch (scriptName) {\n case 'test':\n if (packageHasDependency(pkg, 'vitest')) return 'vitest run';\n if (packageHasDependency(pkg, 'jest')) return 'jest';\n return null;\n case 'lint':\n if (packageHasDependency(pkg, '@biomejs/biome')) return 'biome check .';\n if (packageHasDependency(pkg, 'eslint')) return 'eslint .';\n return null;\n case 'build':\n if (packageHasDependency(pkg, 'next')) return 'next build';\n if (packageHasDependency(pkg, 'vite')) return 'vite build';\n if (packageHasDependency(pkg, 'typescript')) return 'tsc';\n return null;\n default:\n return null;\n }\n}\n\nasync function addPackageScript(\n projectRoot: string,\n scriptName: string,\n script: string,\n): Promise<boolean> {\n const packagePath = path.join(projectRoot, 'package.json');\n let pkg: PackageJson;\n try {\n pkg = JSON.parse(await readFile(packagePath, 'utf-8')) as PackageJson;\n } catch {\n return false;\n }\n\n const scripts = pkg.scripts ?? {};\n if (scripts[scriptName]) return false;\n\n pkg.scripts = {\n ...scripts,\n [scriptName]: script,\n };\n await writeFile(packagePath, `${JSON.stringify(pkg, null, 2)}\\n`, 'utf-8');\n return true;\n}\n\nfunction packageHasDependency(pkg: PackageJson, name: string): boolean {\n return Boolean(pkg.dependencies?.[name] || pkg.devDependencies?.[name]);\n}\n\nconst DEFAULT_GITIGNORE = `# Dependencies\nnode_modules/\n\n# Build output\ndist/\nbuild/\ncoverage/\n\n# Logs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Environment\n.env\n.env.local\n.env.*.local\n\n# OS files\n.DS_Store`;\n\nconst DEFAULT_EDITORCONFIG = `root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\nindent_style = space\nindent_size = 2\ntrim_trailing_whitespace = true\n\n[*.md]\ntrim_trailing_whitespace = false`;\n\nasync function nextRemediationAnswer(\n answerQueue: string[],\n ask: PreseasonRemediationOptions['ask'],\n question: string,\n): Promise<string> {\n if (answerQueue.length > 0) {\n return answerQueue.shift() ?? '';\n }\n if (!ask) {\n throw new Error('remediation answer required for each open issue');\n }\n return ask(question);\n}\n\nfunction normalizeRemediationAnswer(\n answer: string,\n): 'y' | 'n' | 'skip' | 'show' {\n const normalized = answer.trim().toLowerCase();\n if (['y', 'yes'].includes(normalized)) return 'y';\n if (['n', 'no'].includes(normalized)) return 'n';\n if (['show', 'show files', 'files', 'file', '?'].includes(normalized)) {\n return 'show';\n }\n return 'skip';\n}\n\nfunction renderSection(title: string, issues: PreseasonIssue[]): string {\n if (issues.length === 0) return `## ${title}\\n\\nNone.`;\n return `## ${title}\\n\\n${issues\n .map(\n (issue) => `### ${issue.id}: ${issue.title}\n\n- Type: ${issue.type}\n- File: ${issue.file ?? 'n/a'}\n- Detail: ${issue.detail}\n- Recommendation: ${issue.recommendation}`,\n )\n .join('\\n\\n')}`;\n}\n\nfunction readFileSyncSafe(file: string): string {\n return readFileSync(file, 'utf-8');\n}\n\nfunction pathExistsSync(file: string): boolean {\n return existsSync(file);\n}\n\nfunction isNodeError(err: unknown): err is NodeJS.ErrnoException {\n return err instanceof Error && 'code' in err;\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport process from 'node:process';\nimport { detectProjectType } from '../system/detect.js';\nimport { scanAesthetics } from '../system/scan-aesthetics.js';\n\n/**\n * 退出码契约 — 见 docs/08-cli-spec.md §7\n */\nexport const EXIT_OK = 0;\nexport const EXIT_NOT_INITIALIZED = 1;\n\n/**\n * `mancode refresh-style` 命令。\n *\n * 职责(docs/08-cli-spec.md §7 + docs/06-aesthetics.md §9.2):\n * 1. 检查项目已初始化\n * 2. 重新扫描项目审美 token\n * 3. 覆盖 .mancode/aesthetics/style-tokens.json\n * 4. 输出扫描结果摘要\n *\n * 触发场景(docs/06-aesthetics.md §9.2):\n * - 用户改了 tailwind.config.js\n * - 用户改了 package.json dependencies\n * - 用户手动执行\n *\n * @param rootDir 目标项目根目录\n * @returns 退出码\n */\nexport async function refreshStyle(\n rootDir: string = process.cwd(),\n): Promise<number> {\n const stateFile = path.join(rootDir, '.mancode', 'state.json');\n\n // 1. 检查是否已初始化\n if (!(await pathExists(stateFile))) {\n console.error('✗ mancode not initialized.');\n console.error(' Run `mancode init` first.');\n return EXIT_NOT_INITIALIZED;\n }\n\n // 2. 检测项目类型(需要 uiLibrary 和 hasFrontend)\n const project = await detectProjectType(rootDir);\n\n if (!project.hasFrontend) {\n console.log('ℹ️ No frontend framework detected. Nothing to scan.');\n return EXIT_OK;\n }\n\n // 3. 扫描审美 token\n console.log('✓ 扫描项目设计 token...');\n const tokens = await scanAesthetics(rootDir, project.uiLibrary);\n\n // 4. 写入 style-tokens.json\n const tokensPath = path.join(\n rootDir,\n '.mancode',\n 'aesthetics',\n 'style-tokens.json',\n );\n await fs.mkdir(path.dirname(tokensPath), { recursive: true });\n await fs.writeFile(\n tokensPath,\n `${JSON.stringify(tokens, null, 2)}\\n`,\n 'utf-8',\n );\n\n // 5. 输出摘要\n console.log('');\n if (tokens.matchLevel === 'none') {\n console.log('未检测到设计 token。');\n console.log(' 建议:添加 tailwind.config.js 或手动编辑 style-tokens.json');\n } else {\n if (tokens.sourceFiles.length > 0) {\n console.log('扫描来源:');\n for (const f of tokens.sourceFiles) {\n console.log(` ✓ ${f}`);\n }\n }\n\n console.log('');\n console.log('检测结果:');\n if (tokens.uiLibrary) {\n console.log(` UI 库: ${tokens.uiLibrary}`);\n }\n if (tokens.darkMode) {\n console.log(` Dark mode: ${tokens.darkMode}`);\n }\n\n const colorCount = Object.keys(tokens.colors).length;\n const fontCount = Object.keys(tokens.fonts).length;\n if (colorCount > 0) {\n console.log(` 颜色: ${colorCount} 个`);\n for (const [name, value] of Object.entries(tokens.colors)) {\n console.log(` ${name}: ${value}`);\n }\n }\n if (fontCount > 0) {\n console.log(` 字体: ${fontCount} 个`);\n for (const [name, stack] of Object.entries(tokens.fonts)) {\n console.log(` ${name}: ${stack.join(', ')}`);\n }\n }\n\n console.log(` 匹配度: ${tokens.matchLevel}`);\n }\n\n console.log('');\n console.log('已更新 .mancode/aesthetics/style-tokens.json');\n await printStaticPlatformRefreshHint(rootDir);\n return EXIT_OK;\n}\n\nasync function printStaticPlatformRefreshHint(rootDir: string): Promise<void> {\n const platforms = await readInstalledPlatforms(rootDir);\n const staticPlatforms = platforms.filter(\n (platform) => platform !== 'claude-code',\n );\n if (staticPlatforms.length === 0) return;\n\n console.log('');\n console.log(\n `ℹ️ Style tokens updated. Non-Claude-Code platforms (${staticPlatforms.join(', ')}) use static generated instructions.`,\n );\n console.log(\n ' Run `mancode install <platform> --force` to refresh their embedded style summaries.',\n );\n}\n\nasync function readInstalledPlatforms(rootDir: string): Promise<string[]> {\n try {\n const raw = await fs.readFile(\n path.join(rootDir, '.mancode', 'config.json'),\n 'utf-8',\n );\n const config = JSON.parse(raw) as { platforms?: unknown };\n return Array.isArray(config.platforms)\n ? config.platforms.filter(\n (platform): platform is string => typeof platform === 'string',\n )\n : [];\n } catch {\n return [];\n }\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await fs.access(p);\n return true;\n } catch {\n return false;\n }\n}\n","import { spawn } from 'node:child_process';\nimport { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport process from 'node:process';\nimport {\n type PlatformStatus,\n checkPlatformStatus as checkOnePlatformStatus,\n} from '../installers/platform-status.js';\nimport {\n formatPlatformName,\n getPlatformInstallers,\n} from '../installers/registry.js';\nimport { detectTeamStatus } from '../system/detect-team.js';\nimport { type WorkflowMode, readWorkflow } from '../system/workflow.js';\nimport { VERSION } from '../version.js';\n\n/**\n * 退出码契约 — 见 docs/08-cli-spec.md §4\n */\nexport const EXIT_OK = 0;\nexport const EXIT_NOT_INITIALIZED = 1;\nexport const EXIT_CORRUPT_STATE = 2;\n\n/**\n * status 命令读取的 state.json 结构。\n *\n * 与 init.ts 的 MancodeState 字段一致,但所有字段放宽为 string,\n * 因为 status 是从磁盘读取——不应因字段类型限制而失败。\n */\nexport interface StatusState {\n version: string;\n currentMode: string;\n platform: string;\n initializedAt: string;\n techStack: string;\n uiLibrary: string;\n currentTask?: string | null;\n currentWorkflowMode?: string | null;\n teamModeAutoDetected?: boolean;\n contributors?: number;\n}\n\nexport interface StatusOptions {\n /** --json: 输出 JSON(脚本用)*/\n json?: boolean;\n}\n\nexport interface StatusResult {\n version: string;\n project: string;\n techStack: string;\n mode: string;\n platforms: string[];\n uiLibrary: string;\n initializedAt: string;\n hooks: {\n sessionStart: boolean;\n userPromptSubmit: boolean;\n registered: boolean;\n };\n hookInjection: {\n tokens: number;\n cap: number;\n };\n team: {\n isTeam: boolean;\n contributors: number;\n recentActive: number;\n hasRemote: boolean;\n autoDetected: boolean;\n forced: boolean;\n };\n currentWorkflow: {\n taskId: string;\n task: string;\n mode: WorkflowMode;\n currentStep: number;\n status: string;\n } | null;\n platformStatus: Record<string, PlatformStatus>;\n}\n\ninterface DetectedTeamStatus {\n isTeam: boolean;\n contributors: number;\n recentActive: number;\n hasRemote: boolean;\n}\n\ninterface StatusConfig {\n platforms?: string[];\n forceTeamMode?: boolean;\n}\n\n/**\n * `mancode status` 命令。\n *\n * 职责(docs/08-cli-spec.md §4 + progress.md Step 3):\n * 1. 读取 .mancode/state.json(未初始化则报错退出)\n * 2. 显示项目状态(mode/platform/techStack/uiLibrary)\n * 3. 显示初始化时间\n * 4. 显示 hooks 状态(文件存在 + settings.json 注册)\n * 5. 支持 --json 输出\n *\n * @param rootDir 目标项目根目录,默认 process.cwd()\n * @param options CLI 参数\n * @returns 退出码(0=成功,1=未初始化,2=state.json 损坏)\n */\nexport async function status(\n rootDir: string = process.cwd(),\n options: StatusOptions = {},\n): Promise<number> {\n const stateFile = path.join(rootDir, '.mancode', 'state.json');\n\n // 1. 检查是否已初始化\n if (!(await pathExists(stateFile))) {\n console.error('✗ mancode not initialized.');\n console.error(' Run `mancode init` to get started.');\n return EXIT_NOT_INITIALIZED;\n }\n\n // 2. 读取并解析 state.json(区分\"不存在\"和\"损坏\")\n let state: StatusState;\n try {\n const raw = await fs.readFile(stateFile, 'utf-8');\n state = JSON.parse(raw) as StatusState;\n } catch (err) {\n if (err instanceof SyntaxError) {\n console.error('✗ .mancode/state.json is corrupt or unreadable.');\n console.error(` ${err.message}`);\n console.error(' Run `mancode init --force` to repair.');\n } else {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`✗ Failed to read .mancode/state.json: ${msg}`);\n }\n return EXIT_CORRUPT_STATE;\n }\n\n // 3. 并行收集:项目名、hooks 状态、已安装平台、hook 注入预算、团队状态、当前 workflow\n const [\n project,\n hooksStatus,\n config,\n hookInjection,\n teamStatus,\n currentWorkflow,\n ] = await Promise.all([\n getProjectName(rootDir),\n checkHooks(rootDir),\n readConfig(rootDir),\n estimateHookInjection(rootDir),\n detectTeamStatus(rootDir),\n getCurrentWorkflow(rootDir, state.currentTask ?? null),\n ]);\n const effectiveTeam = getEffectiveTeamStatus(state, config, teamStatus);\n\n const result: StatusResult = {\n version: state.version || VERSION,\n project,\n techStack: state.techStack || 'Unknown',\n mode: state.currentMode || 'solo',\n platforms: getInstalledPlatforms(config, state.platform),\n uiLibrary: state.uiLibrary || 'None',\n initializedAt: state.initializedAt || 'unknown',\n hooks: hooksStatus,\n hookInjection,\n team: effectiveTeam,\n currentWorkflow,\n platformStatus: {},\n };\n result.platformStatus = await checkPlatformStatus(rootDir, result.platforms);\n\n // 4. 输出\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n printText(result);\n }\n\n return EXIT_OK;\n}\n\nasync function checkPlatformStatus(\n rootDir: string,\n installedPlatforms: string[],\n): Promise<Record<string, PlatformStatus>> {\n const installed = new Set(installedPlatforms);\n const entries = await Promise.all(\n getPlatformInstallers().map(async (platform) => {\n const status = await checkOnePlatformStatus(\n rootDir,\n platform.name,\n installed.has(platform.name),\n );\n return [platform.name, status] as const;\n }),\n );\n return Object.fromEntries(entries);\n}\n\nasync function getCurrentWorkflow(\n rootDir: string,\n taskId: string | null,\n): Promise<StatusResult['currentWorkflow']> {\n if (!taskId) return null;\n const meta = await readWorkflow(rootDir, taskId);\n if (!meta) return null;\n return {\n taskId: meta.taskId,\n task: meta.task,\n mode: meta.mode,\n currentStep: meta.currentStep,\n status: meta.status,\n };\n}\n\n/**\n * 从 package.json 读取项目名称,fallback 到目录名。\n */\nasync function getProjectName(rootDir: string): Promise<string> {\n try {\n const raw = await fs.readFile(path.join(rootDir, 'package.json'), 'utf-8');\n const pkg = JSON.parse(raw) as { name?: string };\n if (pkg.name && typeof pkg.name === 'string') {\n return pkg.name;\n }\n } catch {\n // package.json 不存在或解析失败——fallback 到目录名\n }\n return path.basename(rootDir);\n}\n\n/**\n * 从 config.json 读取已安装平台列表,fallback 到 state.platform。\n */\nasync function readConfig(rootDir: string): Promise<StatusConfig> {\n try {\n const raw = await fs.readFile(\n path.join(rootDir, '.mancode', 'config.json'),\n 'utf-8',\n );\n return JSON.parse(raw) as StatusConfig;\n } catch {\n // config.json 不存在或解析失败——调用方使用 fallback\n return {};\n }\n}\n\nfunction getInstalledPlatforms(\n config: StatusConfig,\n fallback: string,\n): string[] {\n if (Array.isArray(config.platforms) && config.platforms.length > 0) {\n return config.platforms;\n }\n return fallback ? [fallback] : [];\n}\n\nfunction getEffectiveTeamStatus(\n state: StatusState,\n config: StatusConfig,\n detected: DetectedTeamStatus,\n): StatusResult['team'] {\n const configuredTeam =\n config.forceTeamMode === true\n ? true\n : (state.teamModeAutoDetected ?? detected.isTeam);\n const forced = config.forceTeamMode === true;\n\n return {\n ...detected,\n isTeam: configuredTeam,\n contributors: Math.max(detected.contributors, state.contributors ?? 0, 1),\n autoDetected: forced\n ? false\n : (state.teamModeAutoDetected ?? detected.isTeam),\n forced,\n };\n}\n\n/**\n * 检查 hooks 状态:2 个脚本文件是否存在 + settings.json 是否注册。\n *\n * 3 项检查互相独立,并行执行。\n */\nasync function checkHooks(rootDir: string): Promise<{\n sessionStart: boolean;\n userPromptSubmit: boolean;\n registered: boolean;\n}> {\n const [sessionStart, userPromptSubmit, registered] = await Promise.all([\n pathExists(path.join(rootDir, '.mancode', 'hooks', 'session-start.sh')),\n pathExists(\n path.join(rootDir, '.mancode', 'hooks', 'user-prompt-submit.sh'),\n ),\n isRegistered(rootDir),\n ]);\n return { sessionStart, userPromptSubmit, registered };\n}\n\n/**\n * 检查 .claude/settings.json 是否注册了 mancode 的两个 hooks。\n */\nasync function isRegistered(rootDir: string): Promise<boolean> {\n try {\n const raw = await fs.readFile(\n path.join(rootDir, '.claude', 'settings.json'),\n 'utf-8',\n );\n const settings = JSON.parse(raw);\n return hooksRegistered(settings);\n } catch {\n // settings.json 不存在或解析失败——未注册\n return false;\n }\n}\n\n/**\n * 遍历 settings.json 的 hooks 结构,检查 mancode hooks 是否已注册。\n *\n * Claude Code 官方格式:\n * { hooks: { SessionStart: [{ hooks: [{ command: \"...\" }] }] } }\n *\n * 与 installers/claude-code.ts 的 isMancodeHook 逻辑一致:\n * 检查 command 字段是否包含 .mancode/hooks/ 路径。\n *\n * 注意:此函数只认官方 matcher group 数组格式。\n * 旧版/错误 schema(flat 数组、object map 等)会直接返回 false,\n * 即显示\"未注册\"。这是有意为之——status 是诊断工具,不是兼容层。\n * 旧 schema 的迁移由 installers/claude-code.ts 的 normalizeHookGroups 负责。\n */\nfunction hooksRegistered(settings: unknown): boolean {\n if (!isRecord(settings)) return false;\n const hooks = settings.hooks;\n if (!isRecord(hooks)) return false;\n\n return (\n hasHookCommand(hooks.SessionStart, '.mancode/hooks/session-start.sh') &&\n hasHookCommand(\n hooks.UserPromptSubmit,\n '.mancode/hooks/user-prompt-submit.sh',\n )\n );\n}\n\n/**\n * 在 matcher group 数组中查找包含指定路径的 command。\n */\nfunction hasHookCommand(value: unknown, needle: string): boolean {\n if (!Array.isArray(value)) return false;\n return value.some((group) => {\n if (!isRecord(group) || !Array.isArray(group.hooks)) return false;\n return group.hooks.some((hook) => {\n if (!isRecord(hook) || typeof hook.command !== 'string') return false;\n return hook.command.includes(needle);\n });\n });\n}\n\n/**\n * 估算 UserPromptSubmit hook 的注入大小。\n *\n * 用一个前端相关 fake prompt 触发审美 token 摘要,stdout bytes / 4 ≈ tokens。\n */\nasync function estimateHookInjection(\n rootDir: string,\n): Promise<{ tokens: number; cap: number }> {\n const hookPath = path.join(\n rootDir,\n '.mancode',\n 'hooks',\n 'user-prompt-submit.sh',\n );\n if (!(await pathExists(hookPath))) {\n return { tokens: 0, cap: 800 };\n }\n\n try {\n const output = await runHookEstimate(rootDir, hookPath);\n return {\n tokens: Math.ceil(Buffer.byteLength(output, 'utf-8') / 4),\n cap: 800,\n };\n } catch {\n return { tokens: 0, cap: 800 };\n }\n}\n\nfunction runHookEstimate(rootDir: string, hookPath: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn('bash', [hookPath], {\n cwd: rootDir,\n stdio: ['pipe', 'pipe', 'ignore'],\n });\n\n let stdout = '';\n child.stdout.setEncoding('utf-8');\n child.stdout.on('data', (chunk) => {\n stdout += chunk;\n });\n child.on('error', reject);\n child.on('close', (code) => {\n if (code === 0) resolve(stdout);\n else reject(new Error(`hook exited with ${code}`));\n });\n child.stdin.end(\n JSON.stringify({ prompt: 'design a button component with tailwind css' }),\n );\n });\n}\n\n/**\n * 文本格式输出(默认),字段命名对齐 docs/08-cli-spec.md §4.3。\n */\nfunction printText(r: StatusResult): void {\n const modeLabel = r.mode === 'solo' ? `${r.mode} (default)` : r.mode;\n\n console.log('');\n console.log(`mancode v${r.version}`);\n console.log('');\n console.log(`Project: ${r.project} (${r.techStack})`);\n console.log(`Mode: ${modeLabel}`);\n console.log(`Style: ${r.uiLibrary}`);\n console.log(`Initialized: ${r.initializedAt}`);\n console.log(`Team: ${formatTeamStatus(r.team)}`);\n if (r.currentWorkflow) {\n const stepMax = workflowStepMax(r.currentWorkflow.mode);\n console.log(\n `Workflow: ${r.currentWorkflow.taskId} (Step ${r.currentWorkflow.currentStep}/${stepMax}, ${r.currentWorkflow.status})`,\n );\n }\n console.log('');\n console.log('Installed platforms:');\n for (const p of r.platforms) {\n console.log(` ✓ ${formatPlatformName(p)}`);\n }\n console.log('');\n console.log('Platform status:');\n for (const platform of getPlatformInstallers()) {\n const status = r.platformStatus[platform.name];\n if (!status) continue;\n const installedMarker = status.installed ? '✓' : '○';\n const readyMarker = status.ready ? 'ready' : 'not ready';\n console.log(\n ` ${installedMarker} ${platform.displayName}: ${readyMarker} (${status.target})`,\n );\n }\n console.log('');\n if (r.platforms.includes('claude-code')) {\n console.log('Hooks:');\n console.log(` ${r.hooks.sessionStart ? '✓' : '✗'} session-start.sh`);\n console.log(\n ` ${r.hooks.userPromptSubmit ? '✓' : '✗'} user-prompt-submit.sh`,\n );\n console.log(\n ` ${r.hooks.registered ? '✓' : '✗'} registered in .claude/settings.json`,\n );\n console.log(\n ` Hook injection: ~${r.hookInjection.tokens} tokens (cap ${r.hookInjection.cap})`,\n );\n console.log('');\n }\n}\n\nfunction formatTeamStatus(team: StatusResult['team']): string {\n if (team.forced) return `forced (${team.contributors} contributors)`;\n if (team.isTeam) return `detected (${team.contributors} contributors)`;\n return 'solo';\n}\n\nfunction workflowStepMax(mode: WorkflowMode): number {\n return mode === 'man8' ? 3 : 8;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await fs.access(p);\n return true;\n } catch {\n return false;\n }\n}\n","import {\n mkdir,\n readFile,\n readdir,\n rm,\n stat,\n writeFile,\n} from 'node:fs/promises';\nimport path from 'node:path';\n\n/**\n * Workflow 元数据。\n *\n * 每个 /man8 或 /man 任务在 .mancode/workflows/<taskId>/metadata.json 里\n * 存一份,记录任务进度(docs/14-orchestration.md §2.1)。\n */\nexport interface WorkflowMeta {\n /** YYYYMMDD-HHMMSS-<slug> 格式 */\n taskId: string;\n /** 用户的原始任务描述 */\n task: string;\n /** 触发的工作流模式 */\n mode: WorkflowMode;\n /** 当前进行到第几步(1-8)*/\n currentStep: number;\n /** 被跳过的步骤名(如 ['warmup-drill', 'film-1'])*/\n skippedSteps: string[];\n /** ISO timestamp */\n startedAt: string;\n /** ISO timestamp,每次更新都刷新 */\n updatedAt: string;\n /** 'in_progress' | 'completed' | 'abandoned' */\n status: WorkflowStatus;\n}\n\nexport type WorkflowStatus = 'in_progress' | 'completed' | 'abandoned';\nexport type WorkflowMode = 'man8' | 'man' | 'manteam';\n\nconst METADATA_FILE = 'metadata.json';\nconst SLUG_MAX = 30;\nconst TASK_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9-]*$/;\n\nexport function isValidWorkflowTaskId(taskId: string): boolean {\n return TASK_ID_PATTERN.test(taskId);\n}\n\n/**\n * 生成 task id:YYYYMMDD-HHMMSS-<slug>。\n *\n * slug = task 的 kebab-case,截断到 SLUG_MAX 字符。\n *\n * @param task 任务描述\n * @param now 便于测试注入时间\n */\nexport function generateTaskId(task: string, now: Date = new Date()): string {\n const slug = slugify(task).slice(0, SLUG_MAX) || 'task';\n const pad = (n: number) => n.toString().padStart(2, '0');\n const ts = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;\n return `${ts}-${slug}`;\n}\n\n/**\n * 把任意文本转成 kebab-case slug(小写、连字符分隔、仅保留字母数字)。\n */\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\n/**\n * 创建新 workflow 目录 + 初始化 metadata.json。\n *\n * @param projectRoot 项目根\n * @param task 任务描述\n * @param mode man8 / man\n */\nexport async function createWorkflow(\n projectRoot: string,\n task: string,\n mode: WorkflowMode,\n): Promise<WorkflowMeta> {\n await mkdir(workflowsRoot(projectRoot), { recursive: true });\n const taskId = await allocateTaskId(projectRoot, generateTaskId(task));\n const dir = workflowDir(projectRoot, taskId);\n\n const now = new Date().toISOString();\n const meta: WorkflowMeta = {\n taskId,\n task,\n mode,\n currentStep: 1,\n skippedSteps: [],\n startedAt: now,\n updatedAt: now,\n status: 'in_progress',\n };\n\n await writeMetadata(dir, meta);\n return meta;\n}\n\nasync function allocateTaskId(\n projectRoot: string,\n baseTaskId: string,\n): Promise<string> {\n for (let attempt = 0; attempt < 1000; attempt++) {\n const taskId = attempt === 0 ? baseTaskId : `${baseTaskId}-${attempt + 1}`;\n try {\n await mkdir(workflowDir(projectRoot, taskId));\n return taskId;\n } catch (err) {\n if (isNodeError(err) && err.code === 'EEXIST') {\n continue;\n }\n throw err;\n }\n }\n throw new Error(`unable to allocate workflow id for: ${baseTaskId}`);\n}\n\n/**\n * 读取某个 workflow 的 metadata。\n *\n * @returns 不存在返回 null\n */\nexport async function readWorkflow(\n projectRoot: string,\n taskId: string,\n): Promise<WorkflowMeta | null> {\n if (!isValidWorkflowTaskId(taskId)) return null;\n const file = metadataPath(projectRoot, taskId);\n try {\n const raw = await readFile(file, 'utf-8');\n return parseWorkflowMeta(raw, taskId);\n } catch {\n return null;\n }\n}\n\n/**\n * 局部更新某个 workflow 的 metadata(合并 patch)。\n */\nexport async function updateWorkflow(\n projectRoot: string,\n taskId: string,\n patch: Partial<WorkflowMeta>,\n): Promise<void> {\n assertValidTaskId(taskId);\n const existing = await readWorkflow(projectRoot, taskId);\n if (!existing) {\n throw new Error(`workflow not found: ${taskId}`);\n }\n\n const updated: WorkflowMeta = {\n ...existing,\n ...patch,\n taskId,\n startedAt: existing.startedAt,\n updatedAt: new Date().toISOString(),\n };\n await writeMetadata(workflowDir(projectRoot, taskId), updated);\n}\n\n/**\n * 列出所有 workflow,按 startedAt 倒序(最新在前)。\n */\nexport async function listWorkflows(\n projectRoot: string,\n): Promise<WorkflowMeta[]> {\n const root = workflowsRoot(projectRoot);\n let entries: string[];\n try {\n entries = await readdir(root);\n } catch {\n return [];\n }\n\n const metas: WorkflowMeta[] = [];\n for (const entry of entries) {\n const meta = await readWorkflow(projectRoot, entry);\n if (meta) metas.push(meta);\n }\n\n metas.sort((a, b) => b.startedAt.localeCompare(a.startedAt));\n return metas;\n}\n\n/**\n * 删除一个 workflow 目录。不抛错(不存在时静默)。\n */\nexport async function deleteWorkflow(\n projectRoot: string,\n taskId: string,\n): Promise<boolean> {\n if (!isValidWorkflowTaskId(taskId)) return false;\n const dir = workflowDir(projectRoot, taskId);\n try {\n await stat(dir);\n } catch {\n return false;\n }\n await rm(dir, { recursive: true, force: true });\n return true;\n}\n\nfunction workflowsRoot(projectRoot: string): string {\n return path.join(projectRoot, '.mancode', 'workflows');\n}\n\nfunction workflowDir(projectRoot: string, taskId: string): string {\n assertValidTaskId(taskId);\n return path.join(workflowsRoot(projectRoot), taskId);\n}\n\nfunction metadataPath(projectRoot: string, taskId: string): string {\n return path.join(workflowDir(projectRoot, taskId), METADATA_FILE);\n}\n\nasync function writeMetadata(dir: string, meta: WorkflowMeta): Promise<void> {\n const content = `${JSON.stringify(meta, null, 2)}\\n`;\n await writeFile(path.join(dir, METADATA_FILE), content, 'utf-8');\n}\n\nfunction parseWorkflowMeta(raw: string, taskId: string): WorkflowMeta | null {\n try {\n const obj = JSON.parse(raw) as Partial<WorkflowMeta>;\n if (\n typeof obj.task !== 'string' ||\n typeof obj.mode !== 'string' ||\n typeof obj.currentStep !== 'number' ||\n !Array.isArray(obj.skippedSteps) ||\n typeof obj.startedAt !== 'string' ||\n typeof obj.updatedAt !== 'string' ||\n typeof obj.status !== 'string'\n ) {\n return null;\n }\n return { ...(obj as WorkflowMeta), taskId };\n } catch {\n return null;\n }\n}\n\nfunction isNodeError(err: unknown): err is NodeJS.ErrnoException {\n return err instanceof Error && 'code' in err;\n}\n\n/**\n * 内部使用:检查 workflow 目录是否存在(用于 status 命令显示活跃任务)。\n */\nexport async function workflowExists(\n projectRoot: string,\n taskId: string,\n): Promise<boolean> {\n if (!isValidWorkflowTaskId(taskId)) return false;\n try {\n await stat(metadataPath(projectRoot, taskId));\n return true;\n } catch {\n return false;\n }\n}\n\nfunction assertValidTaskId(taskId: string): void {\n if (!isValidWorkflowTaskId(taskId)) {\n throw new Error(`invalid workflow taskId: ${taskId}`);\n }\n}\n","import { access, readFile, rm, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport process from 'node:process';\nimport { MANCODE_CURSOR_RULE_FILES } from '../installers/cursor.js';\nimport { removeManagedBlock } from '../installers/managed-block.js';\nimport {\n formatPlatformName,\n getPlatformInstaller,\n} from '../installers/registry.js';\n\nexport const EXIT_OK = 0;\nexport const EXIT_NOT_INITIALIZED = 1;\nexport const EXIT_UNSUPPORTED_PLATFORM = 2;\n\nconst CLAUDE_SKILL_DIRS = [\n 'solo',\n 'man8',\n 'man',\n 'manteam',\n 'manps',\n 'mansolo',\n];\nconst CLAUDE_AGENT_FILES = [\n 'scout.md',\n 'head-coach.md',\n 'film-analyst-offense.md',\n 'film-analyst-defense.md',\n 'plan-coach.md',\n];\n\nexport interface UninstallOptions {\n /** --force: skip confirmation */\n force?: boolean;\n /** --all: remove everything including .mancode/ */\n all?: boolean;\n}\n\n/**\n * `mancode uninstall [platform]` command.\n *\n * - With a platform name: removes that platform's generated files.\n * - Without a platform name (or --all): removes all mancode artifacts.\n *\n * Always preserves user-authored content (custom rules, user AGENTS.md text,\n * user Claude Code settings).\n */\nexport async function uninstall(\n rootDir: string = process.cwd(),\n platform?: string,\n options: UninstallOptions = {},\n): Promise<number> {\n const stateFile = path.join(rootDir, '.mancode', 'state.json');\n if (!(await pathExists(stateFile))) {\n console.error('✗ mancode not initialized.');\n console.error(' Run `mancode init` first.');\n return EXIT_NOT_INITIALIZED;\n }\n\n const removeAll = !platform || options.all;\n\n if (platform) {\n const installer = getPlatformInstaller(platform);\n if (!installer) {\n console.error(`✗ Unsupported platform: ${platform}`);\n console.error(\n ' Supported platforms: claude-code, cursor, codex, copilot',\n );\n return EXIT_UNSUPPORTED_PLATFORM;\n }\n }\n\n if (!options.force) {\n const target = platform\n ? `${formatPlatformName(platform)} adapter`\n : 'all mancode artifacts';\n console.log(`ℹ️ This will remove ${target}.`);\n console.log(' User-authored content is preserved.');\n console.log(' Run with --force to skip this message.');\n }\n\n if (removeAll) {\n await uninstallAll(rootDir);\n } else {\n await uninstallPlatform(rootDir, platform ?? 'claude-code');\n }\n\n console.log('✓ Uninstall complete.');\n return EXIT_OK;\n}\n\nasync function uninstallPlatform(\n rootDir: string,\n platform: string,\n): Promise<void> {\n console.log(`✓ Removing ${formatPlatformName(platform)} adapter...`);\n\n if (platform === 'claude-code') {\n await uninstallClaudeCode(rootDir);\n } else if (platform === 'cursor') {\n await uninstallCursor(rootDir);\n } else if (platform === 'codex') {\n await uninstallCodex(rootDir);\n } else if (platform === 'copilot') {\n await uninstallCopilot(rootDir);\n }\n\n await removeFromConfig(rootDir, platform);\n}\n\nasync function uninstallAll(rootDir: string): Promise<void> {\n console.log('✓ Removing all platform adapters...');\n for (const p of ['claude-code', 'cursor', 'codex', 'copilot']) {\n await uninstallPlatform(rootDir, p);\n }\n\n console.log('✓ Removing .mancode/ directory...');\n await rm(path.join(rootDir, '.mancode'), {\n recursive: true,\n force: true,\n });\n}\n\nasync function uninstallClaudeCode(rootDir: string): Promise<void> {\n const claudeDir = path.join(rootDir, '.claude');\n const skillsDir = path.join(claudeDir, 'skills');\n const agentsDir = path.join(claudeDir, 'agents');\n\n for (const skillDir of CLAUDE_SKILL_DIRS) {\n await rm(path.join(skillsDir, skillDir), { recursive: true, force: true });\n }\n\n for (const agentFile of CLAUDE_AGENT_FILES) {\n await rm(path.join(agentsDir, agentFile), { force: true });\n }\n\n await cleanClaudeSettings(rootDir);\n}\n\nasync function cleanClaudeSettings(rootDir: string): Promise<void> {\n const settingsPath = path.join(rootDir, '.claude', 'settings.json');\n let content: string;\n try {\n content = await readFile(settingsPath, 'utf-8');\n } catch {\n return;\n }\n\n let settings: Record<string, unknown>;\n try {\n settings = JSON.parse(content);\n } catch {\n return;\n }\n\n if (!isRecord(settings.hooks)) return;\n\n const cleanedHooks: Record<string, unknown> = {};\n for (const [event, groups] of Object.entries(settings.hooks)) {\n if (!Array.isArray(groups)) {\n cleanedHooks[event] = groups;\n continue;\n }\n const filtered = groups.filter((group) => {\n if (!isRecord(group) || !Array.isArray(group.hooks)) return true;\n return !group.hooks.some(\n (hook) =>\n isRecord(hook) &&\n typeof hook.command === 'string' &&\n hook.command.includes('.mancode/hooks/'),\n );\n });\n if (filtered.length > 0) {\n cleanedHooks[event] = filtered;\n }\n }\n\n if (Object.keys(cleanedHooks).length > 0) {\n settings.hooks = cleanedHooks;\n } else {\n settings.hooks = undefined;\n }\n\n await writeFile(\n settingsPath,\n `${JSON.stringify(settings, null, 2)}\\n`,\n 'utf-8',\n );\n}\n\nasync function uninstallCursor(rootDir: string): Promise<void> {\n const rulesDir = path.join(rootDir, '.cursor', 'rules');\n for (const file of MANCODE_CURSOR_RULE_FILES) {\n await rm(path.join(rulesDir, file), { force: true });\n }\n}\n\nasync function uninstallCodex(rootDir: string): Promise<void> {\n const agentsPath = path.join(rootDir, 'AGENTS.md');\n try {\n const content = await readFile(agentsPath, 'utf-8');\n const cleaned = removeManagedBlock(content);\n if (cleaned.trim()) {\n await writeFile(agentsPath, `${cleaned}\\n`, 'utf-8');\n } else {\n await rm(agentsPath, { force: true });\n }\n } catch {\n // AGENTS.md doesn't exist — nothing to do\n }\n}\n\nasync function uninstallCopilot(rootDir: string): Promise<void> {\n const instructionsPath = path.join(\n rootDir,\n '.github',\n 'copilot-instructions.md',\n );\n try {\n const content = await readFile(instructionsPath, 'utf-8');\n const cleaned = removeManagedBlock(content);\n if (cleaned.trim()) {\n await writeFile(instructionsPath, `${cleaned}\\n`, 'utf-8');\n } else {\n await rm(instructionsPath, { force: true });\n }\n } catch {\n // copilot-instructions.md doesn't exist — nothing to do\n }\n}\n\nasync function removeFromConfig(\n rootDir: string,\n platform: string,\n): Promise<void> {\n const configPath = path.join(rootDir, '.mancode', 'config.json');\n try {\n const raw = await readFile(configPath, 'utf-8');\n const config = JSON.parse(raw) as { platforms?: string[] };\n if (Array.isArray(config.platforms)) {\n config.platforms = config.platforms.filter((p) => p !== platform);\n await writeFile(\n configPath,\n `${JSON.stringify(config, null, 2)}\\n`,\n 'utf-8',\n );\n }\n } catch {\n // config.json doesn't exist or is invalid — nothing to update\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n","import process from 'node:process';\nimport { VERSION } from '../version.js';\n\n/**\n * `mancode version` 命令。\n *\n * 输出格式(docs/08-cli-spec.md §5.3):\n * ```\n * mancode/0.1.0\n * node/20.10.0\n * darwin/arm64\n * ```\n */\nexport function version(): void {\n const nodeVersion = process.version;\n const platform = `${process.platform}/${process.arch}`;\n console.log(`mancode/${VERSION}`);\n console.log(`node/${nodeVersion.replace('v', '')}`);\n console.log(platform);\n}\n","import { access } from 'node:fs/promises';\nimport path from 'node:path';\nimport {\n type WorkflowMeta,\n type WorkflowStatus,\n createWorkflow,\n deleteWorkflow,\n isValidWorkflowTaskId,\n listWorkflows,\n readWorkflow,\n updateWorkflow,\n} from '../system/workflow.js';\n\nexport const EXIT_OK = 0;\nexport const EXIT_NOT_INITIALIZED = 1;\nexport const EXIT_INVALID_ARG = 2;\n\nexport interface WorkflowOptions {\n dryRun?: boolean;\n olderThan?: string;\n json?: boolean;\n step?: string;\n status?: string;\n skipped?: string;\n}\n\n/**\n * `mancode workflow` 子命令。\n *\n * 支持:\n * - list:列出 workflow\n * - show <taskId>:显示详情\n * - clean [--dry-run] [--older-than 30d]:清理 workflow\n */\nexport async function workflow(\n rootDir: string,\n subcommand: string,\n args: string[] = [],\n options: WorkflowOptions = {},\n): Promise<number> {\n if (!(await pathExists(path.join(rootDir, '.mancode', 'state.json')))) {\n if (options.json) {\n console.log(JSON.stringify({ error: 'not initialized' }, null, 2));\n } else {\n console.error('✗ mancode not initialized.');\n console.error(' Run `mancode init` to get started.');\n }\n return EXIT_NOT_INITIALIZED;\n }\n\n switch (subcommand) {\n case 'create':\n return workflowCreate(rootDir, args, options);\n case 'update':\n return workflowUpdate(rootDir, args[0], options);\n case 'list':\n return workflowList(rootDir, options);\n case 'show':\n return workflowShow(rootDir, args[0], options);\n case 'clean':\n return workflowClean(rootDir, options);\n default:\n if (options.json) {\n console.log(\n JSON.stringify(\n { error: `invalid subcommand: ${subcommand}` },\n null,\n 2,\n ),\n );\n } else {\n console.error(`✗ Invalid workflow subcommand: ${subcommand}`);\n console.error(\n ' Use: create <man8|man> <task> | update <taskId> | list | show <taskId> | clean',\n );\n }\n return EXIT_INVALID_ARG;\n }\n}\n\nasync function workflowCreate(\n rootDir: string,\n args: string[],\n options: WorkflowOptions,\n): Promise<number> {\n const mode = args[0];\n const task = args.slice(1).join(' ').trim();\n if (mode !== 'man8' && mode !== 'man') {\n return invalidArg(\n options,\n `invalid workflow mode: ${mode ?? ''}`,\n 'Use: mancode workflow create <man8|man> <task>',\n );\n }\n if (!task) {\n return invalidArg(\n options,\n 'missing workflow task',\n 'Use: mancode workflow create <man8|man> <task>',\n );\n }\n\n const meta = await createWorkflow(rootDir, task, mode);\n if (options.json) {\n console.log(JSON.stringify(meta, null, 2));\n } else {\n console.log(`Created workflow: ${meta.taskId}`);\n }\n return EXIT_OK;\n}\n\nasync function workflowUpdate(\n rootDir: string,\n taskId: string | undefined,\n options: WorkflowOptions,\n): Promise<number> {\n if (!taskId) {\n return invalidArg(\n options,\n 'missing taskId',\n 'Use: mancode workflow update <taskId> [--step N] [--status in_progress|completed|abandoned] [--skipped a,b]',\n );\n }\n if (!isValidWorkflowTaskId(taskId)) {\n return invalidArg(options, `invalid taskId: ${taskId}`);\n }\n\n const existing = await readWorkflow(rootDir, taskId);\n if (!existing) {\n return invalidArg(options, `workflow not found: ${taskId}`);\n }\n\n const patch: Partial<WorkflowMeta> = {};\n if (options.step !== undefined) {\n const currentStep = Number.parseInt(options.step, 10);\n const maxStep = existing.mode === 'man' ? 8 : 3;\n if (\n !Number.isInteger(currentStep) ||\n currentStep < 1 ||\n currentStep > maxStep\n ) {\n return invalidArg(options, `invalid --step: ${options.step}`);\n }\n patch.currentStep = currentStep;\n }\n\n if (options.status !== undefined) {\n if (!isWorkflowStatus(options.status)) {\n return invalidArg(options, `invalid --status: ${options.status}`);\n }\n patch.status = options.status;\n }\n\n if (options.skipped !== undefined) {\n patch.skippedSteps = options.skipped\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean);\n }\n\n if (Object.keys(patch).length === 0) {\n return invalidArg(options, 'missing update fields');\n }\n\n await updateWorkflow(rootDir, taskId, patch);\n\n const updated = await readWorkflow(rootDir, taskId);\n if (options.json) {\n console.log(JSON.stringify(updated, null, 2));\n } else {\n console.log(`Updated workflow: ${taskId}`);\n }\n return EXIT_OK;\n}\n\nasync function workflowList(\n rootDir: string,\n options: WorkflowOptions,\n): Promise<number> {\n const workflows = await listWorkflows(rootDir);\n if (options.json) {\n console.log(JSON.stringify(workflows, null, 2));\n return EXIT_OK;\n }\n\n if (workflows.length === 0) {\n console.log('No workflows.');\n return EXIT_OK;\n }\n\n const inProgress = workflows.filter((w) => w.status === 'in_progress').length;\n console.log(\n `mancode workflows (${workflows.length} total, ${inProgress} in_progress)`,\n );\n console.log('');\n for (const meta of workflows) {\n console.log(formatWorkflowRow(meta));\n }\n return EXIT_OK;\n}\n\nasync function workflowShow(\n rootDir: string,\n taskId: string | undefined,\n options: WorkflowOptions,\n): Promise<number> {\n if (!taskId) {\n if (options.json) {\n console.log(JSON.stringify({ error: 'missing taskId' }, null, 2));\n } else {\n console.error('✗ Missing taskId.');\n console.error(' Use: mancode workflow show <taskId>');\n }\n return EXIT_INVALID_ARG;\n }\n if (!isValidWorkflowTaskId(taskId)) {\n return invalidArg(options, `invalid taskId: ${taskId}`);\n }\n\n const meta = await readWorkflow(rootDir, taskId);\n if (!meta) {\n if (options.json) {\n console.log(\n JSON.stringify({ error: `workflow not found: ${taskId}` }, null, 2),\n );\n } else {\n console.error(`✗ Workflow not found: ${taskId}`);\n }\n return EXIT_INVALID_ARG;\n }\n\n if (options.json) {\n console.log(JSON.stringify(meta, null, 2));\n return EXIT_OK;\n }\n\n console.log(`Workflow: ${meta.taskId}`);\n console.log(`Task: ${meta.task}`);\n console.log(`Mode: ${meta.mode}`);\n console.log(`Status: ${meta.status}`);\n console.log(\n `Current step:${meta.currentStep}/${meta.mode === 'man' ? 8 : 3}`,\n );\n console.log(\n `Skipped: ${meta.skippedSteps.length > 0 ? meta.skippedSteps.join(', ') : 'none'}`,\n );\n console.log(`Started: ${meta.startedAt}`);\n console.log(`Updated: ${meta.updatedAt}`);\n return EXIT_OK;\n}\n\nasync function workflowClean(\n rootDir: string,\n options: WorkflowOptions,\n): Promise<number> {\n const workflows = await listWorkflows(rootDir);\n const cutoff = parseOlderThan(options.olderThan);\n if (cutoff === null) {\n if (options.json) {\n console.log(\n JSON.stringify(\n { error: `invalid --older-than: ${options.olderThan}` },\n null,\n 2,\n ),\n );\n } else {\n console.error(`✗ Invalid --older-than duration: ${options.olderThan}`);\n console.error(' Use examples like: 30d, 12h, 90m');\n }\n return EXIT_INVALID_ARG;\n }\n\n const candidates = workflows.filter((meta) => {\n if (!cutoff) return meta.status !== 'in_progress';\n const started = Date.parse(meta.startedAt);\n return Number.isFinite(started) && started < cutoff.getTime();\n });\n\n if (options.json) {\n console.log(\n JSON.stringify(\n {\n dryRun: Boolean(options.dryRun),\n count: candidates.length,\n workflows: candidates,\n },\n null,\n 2,\n ),\n );\n } else if (candidates.length === 0) {\n console.log('No workflows to clean.');\n } else if (options.dryRun) {\n console.log(`Would remove ${candidates.length} workflow(s):`);\n for (const meta of candidates) console.log(` ${meta.taskId}`);\n } else {\n console.log(`Removed ${candidates.length} workflow(s).`);\n }\n\n if (!options.dryRun) {\n for (const meta of candidates) {\n await deleteWorkflow(rootDir, meta.taskId);\n }\n }\n return EXIT_OK;\n}\n\nfunction formatWorkflowRow(meta: WorkflowMeta): string {\n const stepMax = meta.mode === 'man' ? 8 : 3;\n const step =\n meta.status === 'in_progress'\n ? `Step ${meta.currentStep}/${stepMax}`\n : ago(meta.updatedAt);\n return `${meta.taskId.padEnd(42)} ${meta.mode.padEnd(5)} ${meta.status.padEnd(11)} ${step}`;\n}\n\nfunction parseOlderThan(value: string | undefined): Date | undefined | null {\n if (!value) return undefined;\n const match = /^(\\d+)([dhm])$/.exec(value);\n if (!match) return null;\n\n const amount = Number.parseInt(match[1] ?? '0', 10);\n const unit = match[2] ?? 'm';\n const ms =\n unit === 'd'\n ? amount * 24 * 60 * 60 * 1000\n : unit === 'h'\n ? amount * 60 * 60 * 1000\n : amount * 60 * 1000;\n return new Date(Date.now() - ms);\n}\n\nfunction invalidArg(\n options: WorkflowOptions,\n message: string,\n usage?: string,\n): number {\n if (options.json) {\n console.log(JSON.stringify({ error: message }, null, 2));\n } else {\n console.error(`✗ ${message}`);\n if (usage) console.error(` ${usage}`);\n }\n return EXIT_INVALID_ARG;\n}\n\nfunction isWorkflowStatus(value: string): value is WorkflowStatus {\n return (\n value === 'in_progress' || value === 'completed' || value === 'abandoned'\n );\n}\n\nfunction ago(iso: string): string {\n const time = Date.parse(iso);\n if (!Number.isFinite(time)) return 'unknown';\n const delta = Math.max(0, Date.now() - time);\n const minutes = Math.floor(delta / 60000);\n if (minutes < 1) return 'just now';\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n return `${Math.floor(hours / 24)}d ago`;\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":"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","names":["fs","path","process","mkdir","readFile","writeFile","path","mkdir","readFile","writeFile","path","path","mkdir","writeFile","readFile","path","mkdir","writeFile","readFile","isNodeError","writeFile","path","readFile","path","path","writeFile","mkdir","writeFile","path","path","mkdir","writeFile","mkdir","rm","writeFile","path","path","mkdir","writeFile","rm","path","process","exec","readFile","path","promisify","execAsync","pathExists","path","pathExists","process","path","pathExists","fs","fs","path","process","fs","path","pathExists","path","fs","isRecord","EXIT_OK","process","path","pathExists","status","fs","isNodeError","isRecord","fs","path","process","EXIT_OK","process","fs","path","access","path","mkdir","readFile","writeFile","path","isNodeError","EXIT_OK","EXIT_NOT_INITIALIZED","pathExists","path","invalidArg","access","fs","path","process","EXIT_OK","EXIT_NOT_INITIALIZED","process","path","pathExists","fs","readInstalledPlatforms","fs","path","process","mkdir","readFile","readdir","rm","stat","writeFile","path","isNodeError","EXIT_OK","EXIT_NOT_INITIALIZED","process","path","pathExists","fs","readConfig","checkPlatformStatus","status","hooksRegistered","isRecord","hasHookCommand","access","readFile","rm","writeFile","path","process","EXIT_OK","EXIT_NOT_INITIALIZED","EXIT_UNSUPPORTED_PLATFORM","process","path","pathExists","rm","readFile","isRecord","writeFile","access","process","process","access","path","EXIT_OK","EXIT_NOT_INITIALIZED","EXIT_INVALID_ARG","pathExists","path","access"]}