teamix-evo 0.13.4 → 0.14.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.
- package/README.md +1 -4
- package/dist/core/index.d.ts +49 -68
- package/dist/core/index.js +837 -713
- package/dist/core/index.js.map +1 -1
- package/dist/index.js +1821 -2110
- package/dist/index.js.map +1 -1
- package/package.json +8 -7
package/dist/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/tokens-init.ts","../../src/utils/fs.ts","../../src/utils/logger.ts","../../src/utils/hash.ts","../../src/core/state.ts","../../src/utils/error.ts","../../src/core/skills-client.ts","../../src/core/skills-installer.ts","../../src/ide/QoderAdapter.ts","../../src/ide/ClaudeAdapter.ts","../../src/ide/index.ts","../../src/utils/template.ts","../../src/utils/path.ts","../../src/utils/mcp.ts","../../src/core/skills-add.ts","../../src/core/skills-update.ts","../../src/core/ui-init.ts","../../src/core/ui-client.ts","../../src/core/ui-installer.ts","../../src/utils/transform-imports.ts","../../src/core/ui-add.ts","../../src/core/ui-list.ts","../../src/core/variant-ui-add.ts","../../src/core/lint-init.ts","../../src/core/agents-md.ts","../../src/core/init-detect.ts","../../src/core/init-conflicts.ts","../../src/core/deps-install.ts","../../src/core/init-checklist-template.ts","../../src/core/file-changes.ts","../../src/core/project-init.ts","../../src/core/installer.ts","../../src/core/registry-client.ts"],"sourcesContent":["/**\n * Programmatic tokens init — installs one variant's token files into the\n * consumer's project root `tokens/` directory.\n *\n * Per [ADR 0020](../../../../docs/adr/0020-design-to-tokens-skill-fusion.md)\n * the install model is now a flat copy: each variant in `@teamix-evo/tokens`\n * advertises its files in the package manifest; for each advertised file we\n * copy by basename into `<projectRoot>/tokens/`:\n *\n * variants/<variant>/theme.css → tokens/tokens.theme.css (regenerable)\n * variants/<variant>/base.tokens.json → (kept in package only — reference data)\n *\n * Plus we always ensure `tokens/tokens.overrides.css` exists at the consumer\n * (created empty if absent, frozen thereafter so user edits are preserved\n * across re-installs).\n *\n * No walk-and-merge, no `default` baseline — every variant is a\n * self-contained token set per ADR 0020 §3.\n */\nimport * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport {\n loadTokensPackageManifest,\n getVariantEntry,\n type TokensPackLock,\n type InstalledManifest,\n type InstalledResource,\n type ProjectConfig,\n type UpdateStrategy,\n} from '@teamix-evo/registry';\nimport { backupFile, writeFileSafe, fileExists } from '../utils/fs.js';\nimport { computeHash } from '../utils/hash.js';\nimport {\n ensureTeamixDir,\n readProjectConfig,\n writeProjectConfig,\n readInstalledManifest,\n writeInstalledManifest,\n} from './state.js';\nimport { runSkillsAdd } from './skills-add.js';\nimport { ensureMcpJson } from '../utils/mcp.js';\nimport { loadSkillsData } from './skills-client.js';\nimport { logger } from '../utils/logger.js';\nimport type { SkillIde, SkillScope } from '@teamix-evo/registry';\nimport { resolveTokensPackageRoot } from '../utils/path.js';\nimport { getErrorMessage } from '../utils/error.js';\n\nconst DEFAULT_SKILLS_PACKAGE = '@teamix-evo/skills';\nconst DEFAULT_AUTO_SKILL_IDES: SkillIde[] = ['qoder', 'claude'];\nconst DEFAULT_AUTO_SKILL_SCOPE: SkillScope = 'project';\n\nconst DEFAULT_TOKENS_PACKAGE = '@teamix-evo/tokens';\n\n/** Consumer-side directory where token files land. */\nconst CONSUMER_TOKENS_DIR = 'tokens';\n\n/** Consumer-side filename for the regenerable theme. */\nconst CONSUMER_THEME_FILE = 'tokens.theme.css';\n\n/** Consumer-side filename for the frozen user-owned override. */\nconst CONSUMER_OVERRIDES_FILE = 'tokens.overrides.css';\n\n/** Default empty content for a fresh `tokens.overrides.css`. */\nconst EMPTY_OVERRIDES_TEMPLATE = `/* User-owned token overrides — frozen on subsequent installs. */\n/* See @teamix-evo/tokens variant theme.css for available CSS custom properties. */\n`;\n\nexport interface RunTokensInitOptions {\n /** Absolute project root directory. */\n projectRoot: string;\n /** Tokens variant id (e.g. `\"opentrek\"`, `\"uni-manager\"`). */\n variant: string;\n /** IDE identifier written into config.json (e.g. `\"qoder\"`, `\"claude\"`). */\n ide: string;\n /** Override the tokens package name (defaults to `\"@teamix-evo/tokens\"`). */\n packageName?: string;\n /**\n * Override resolution of the tokens package root. When provided, skips\n * `require.resolve(\"<packageName>/package.json\")`. Useful for tests that\n * want to point at a fixture tree, and for embedding inside `create`\n * where the package may not yet be installed in the consumer.\n */\n packageRoot?: string;\n}\n\n/**\n * Outcome of the post-init skill auto-install step. `attempted` is the variant\n * skill id we tried to install; `addedSkillIds` is what was actually installed\n * (empty if the skill was already present); `missing` lists ids that aren't in\n * the manifest (warned, not fatal). Per ADR / \"skills self-contained\" decision,\n * each variant skill is fully self-contained — no separate baseline skill.\n */\nexport interface SkillsAutoInstallResult {\n attempted: string[];\n addedSkillIds: string[];\n skippedSkillIds: string[];\n missing: string[];\n}\n\nexport type RunTokensInitResult =\n | {\n status: 'installed';\n packageName: string;\n variant: string;\n version: string;\n count: number;\n resources: InstalledResource[];\n /** Result of the auto-install of the matching design skill. */\n skills?: SkillsAutoInstallResult;\n }\n | {\n status: 'already-initialized';\n existingVariant: string;\n }\n | {\n status: 'variant-mismatch';\n existingVariant: string;\n requestedVariant: string;\n };\n\n/**\n * Programmatic equivalent of `teamix-evo tokens init <variant>`.\n *\n * Side effects:\n * - Creates `<projectRoot>/.teamix-evo/`\n * - Copies the variant's `theme.css` to `<projectRoot>/tokens/tokens.theme.css`\n * - Ensures `<projectRoot>/tokens/tokens.overrides.css` exists (frozen)\n * - Writes `tokens-lock.json`, `config.json`, `manifest.json` (installed)\n *\n * No interactive prompts, no `process.exit`. Throws on hard failure (P8).\n */\nexport async function runTokensInit(\n options: RunTokensInitOptions,\n): Promise<RunTokensInitResult> {\n const { projectRoot, variant, ide } = options;\n const packageName = options.packageName ?? DEFAULT_TOKENS_PACKAGE;\n\n await ensureTeamixDir(projectRoot);\n\n // Resolve the catalog up front so variant-name validation runs before any\n // state-driven branching (#P2-3). An unknown variant should produce a\n // clear \"Unknown variant\" error regardless of whether tokens are already\n // installed for the project.\n const packageRoot =\n options.packageRoot ?? resolveTokensPackageRoot(packageName);\n const catalog = await loadTokensPackageManifest(packageRoot);\n const variantEntry = getVariantEntry(catalog, variant);\n if (!variantEntry) {\n const known = catalog.variants.map((v) => v.name).join(', ');\n throw new Error(\n `Unknown variant \"${variant}\". Available variants: ${\n known || '(none)'\n }.\\nRun \\`npx teamix-evo@latest tokens list-variants\\` to see all options.`,\n );\n }\n\n // Variant-switching guard: if a different variant is already installed,\n // require the user to explicitly uninstall first (#15). Same-variant re-init\n // is a no-op (already-initialized).\n const existingConfig = await readProjectConfig(projectRoot);\n if (existingConfig?.packages?.tokens) {\n const existingVariant = existingConfig.packages.tokens.variant;\n if (existingVariant === variant) {\n return { status: 'already-initialized', existingVariant };\n }\n return {\n status: 'variant-mismatch',\n existingVariant,\n requestedVariant: variant,\n };\n }\n\n // Install advertised files by basename → consumer tokens/ directory.\n const installed: InstalledResource[] = [];\n for (const fileRel of variantEntry.files) {\n const result = await installVariantFile(fileRel, packageRoot, projectRoot);\n if (result) installed.push(result);\n }\n\n // Always ensure the user-owned overrides file exists (frozen).\n const overridesAbs = path.join(\n projectRoot,\n CONSUMER_TOKENS_DIR,\n CONSUMER_OVERRIDES_FILE,\n );\n if (!(await fileExists(overridesAbs))) {\n await writeFileSafe(overridesAbs, EMPTY_OVERRIDES_TEMPLATE);\n }\n // Dedup: only add overrides resource if installVariantFile didn't already\n // register it (happens when the variant ships an overrides.css file).\n const overridesId = `tokens:${CONSUMER_OVERRIDES_FILE}`;\n if (!installed.some((r) => r.id === overridesId)) {\n const overridesContent = await fs.readFile(overridesAbs, 'utf-8');\n installed.push({\n id: overridesId,\n target: path.posix.join(CONSUMER_TOKENS_DIR, CONSUMER_OVERRIDES_FILE),\n hash: computeHash(overridesContent),\n strategy: 'frozen',\n });\n }\n\n // Write consumer-side state files.\n const lock: TokensPackLock = {\n schemaVersion: 1,\n variant: {\n name: variantEntry.name,\n displayName: variantEntry.displayName,\n version: variantEntry.version,\n from: packageName,\n },\n packageVersion: catalog.version,\n linked: variantEntry.linked,\n installedAt: new Date().toISOString(),\n };\n await writeFileSafe(\n path.join(projectRoot, '.teamix-evo', 'tokens-lock.json'),\n JSON.stringify(lock, null, 2) + '\\n',\n );\n\n // Merge into existing config so unrelated package entries (skills / ui)\n // aren't clobbered (#18).\n const config: ProjectConfig = {\n $schema: 'https://teamix-evo.dev/schema/config/v2.json',\n schemaVersion: 2,\n ide: existingConfig?.ide ?? ide,\n packages: {\n ...(existingConfig?.packages ?? {}),\n tokens: {\n variant,\n version: variantEntry.version,\n tailwind: 'v4',\n },\n },\n };\n await writeProjectConfig(projectRoot, config);\n\n // Merge into existing installed manifest so other packages (ui / biz-ui /\n // templates) recorded earlier are preserved.\n const prior = (await readInstalledManifest(projectRoot)) ?? {\n schemaVersion: 1 as const,\n installed: [],\n };\n const tokensIdx = prior.installed.findIndex((p) => p.package === packageName);\n const tokensEntry = {\n package: packageName,\n variant,\n version: variantEntry.version,\n installedAt: new Date().toISOString(),\n resources: installed,\n };\n if (tokensIdx >= 0) prior.installed[tokensIdx] = tokensEntry;\n else prior.installed.push(tokensEntry);\n await writeInstalledManifest(projectRoot, prior);\n\n // Ensure `.mcp.json` exists for incremental adopters (#BUG-103). Done\n // before the auto-skills install so even if the latter fails the MCP\n // wiring is in place.\n await ensureMcpJson(projectRoot);\n\n // After the lock + manifest are persisted, auto-install matching skills.\n // Failures here do NOT roll back the install — the skill layer is additive,\n // and the user can always re-run `skills init` (bulk) or `skills add <id>`\n // (incremental) manually.\n const skills = await tryAutoInstallVariantSkills({\n projectRoot,\n variant,\n ide,\n });\n\n return {\n status: 'installed',\n packageName,\n variant,\n version: variantEntry.version,\n count: installed.length,\n resources: installed,\n skills,\n };\n}\n\n/**\n * Auto-install the variant skill `teamix-evo-design-<variant>` (if present\n * in the skills manifest). Each variant skill is fully self-contained — no\n * separate baseline. A missing variant skill produces a warning, not a failure.\n */\nasync function tryAutoInstallVariantSkills(args: {\n projectRoot: string;\n variant: string;\n ide: string;\n}): Promise<SkillsAutoInstallResult> {\n const { projectRoot, variant, ide } = args;\n const variantSkillId = `teamix-evo-design-${variant}`;\n const desired = [variantSkillId];\n\n // Filter to skills actually present in the manifest. Anything missing\n // becomes a warning but is not fatal.\n let manifestSkillIds: Set<string>;\n try {\n const { manifest } = await loadSkillsData(DEFAULT_SKILLS_PACKAGE);\n manifestSkillIds = new Set(manifest.skills.map((s) => s.id));\n } catch (err) {\n logger.warn(\n `Skipping skills auto-install: could not load skills manifest (${getErrorMessage(\n err,\n )}).`,\n );\n return {\n attempted: [],\n addedSkillIds: [],\n skippedSkillIds: [],\n missing: desired,\n };\n }\n\n const present = desired.filter((id) => manifestSkillIds.has(id));\n const missing = desired.filter((id) => !manifestSkillIds.has(id));\n if (missing.length > 0) {\n logger.warn(\n `Skills auto-install: not found in manifest, skipping: ${missing.join(\n ', ',\n )}.`,\n );\n }\n if (present.length === 0) {\n return {\n attempted: desired,\n addedSkillIds: [],\n skippedSkillIds: [],\n missing,\n };\n }\n\n try {\n const result = await runSkillsAdd({\n projectRoot,\n names: present,\n ides: DEFAULT_AUTO_SKILL_IDES,\n scope: DEFAULT_AUTO_SKILL_SCOPE,\n ide,\n });\n if (result.status !== 'installed') {\n return {\n attempted: desired,\n addedSkillIds: [],\n skippedSkillIds: present,\n missing,\n };\n }\n return {\n attempted: desired,\n addedSkillIds: result.addedSkillIds,\n skippedSkillIds: result.skippedSkillIds,\n missing,\n };\n } catch (err) {\n logger.warn(\n `Skills auto-install failed (continuing): ${getErrorMessage(err)}`,\n );\n return {\n attempted: desired,\n addedSkillIds: [],\n skippedSkillIds: [],\n missing,\n };\n }\n}\n\n/**\n * Install one advertised variant file. Mapping by basename:\n *\n * theme.css → consumer `tokens/tokens.theme.css` (regenerable)\n * overrides.css → consumer `tokens/tokens.overrides.css` (frozen, see runTokensInit)\n * anything else → skipped (reference data — kept in npm package only)\n *\n * The `overrides.css` source file is rare today (variants don't ship one),\n * but the mapping is here so authors can opt in. The \"always-create\" path in\n * `runTokensInit` covers the normal case where no source override is present.\n */\nasync function installVariantFile(\n fileRelToPackage: string,\n packageRoot: string,\n projectRoot: string,\n): Promise<InstalledResource | null> {\n const sourceAbs = path.join(packageRoot, fileRelToPackage);\n const base = path.basename(fileRelToPackage);\n\n if (base === 'theme.css') {\n const targetRel = path.posix.join(CONSUMER_TOKENS_DIR, CONSUMER_THEME_FILE);\n const targetAbs = path.join(projectRoot, targetRel);\n const content = await fs.readFile(sourceAbs, 'utf-8');\n // Phase 1.A2: theme.css is regenerable but users sometimes hand-edit it.\n // Stash any pre-existing copy under .teamix-evo/.backups/ before we\n // overwrite so a stale-state recovery is always possible.\n if (await fileExists(targetAbs)) {\n await backupFile(targetAbs, projectRoot);\n }\n await writeFileSafe(targetAbs, content);\n return {\n id: `tokens:${CONSUMER_THEME_FILE}`,\n target: targetRel,\n hash: computeHash(content),\n strategy: 'regenerable',\n };\n }\n\n if (base === 'overrides.css' || base === 'tokens.overrides.css') {\n const targetRel = path.posix.join(\n CONSUMER_TOKENS_DIR,\n CONSUMER_OVERRIDES_FILE,\n );\n const targetAbs = path.join(projectRoot, targetRel);\n if (await fileExists(targetAbs)) {\n // Frozen — leave the user's customization alone.\n const existing = await fs.readFile(targetAbs, 'utf-8');\n return {\n id: `tokens:${CONSUMER_OVERRIDES_FILE}`,\n target: targetRel,\n hash: computeHash(existing),\n strategy: 'frozen',\n };\n }\n const content = await fs.readFile(sourceAbs, 'utf-8');\n await writeFileSafe(targetAbs, content);\n return {\n id: `tokens:${CONSUMER_OVERRIDES_FILE}`,\n target: targetRel,\n hash: computeHash(content),\n strategy: 'frozen',\n };\n }\n\n // Reference data (e.g. base.tokens.json) — kept in the npm package only.\n return null;\n}\n\n/**\n * List all variants advertised by the top-level tokens catalog. Used by\n * `teamix-evo tokens list-variants`.\n */\nexport interface ListVariantsResult {\n packageName: string;\n packageVersion: string;\n variants: Array<{\n name: string;\n displayName: string;\n version: string;\n description?: string;\n linked?: { 'biz-ui'?: string; templates?: string };\n }>;\n}\n\nexport async function listTokenVariants(\n packageName: string = DEFAULT_TOKENS_PACKAGE,\n packageRoot?: string,\n): Promise<ListVariantsResult> {\n const root = packageRoot ?? resolveTokensPackageRoot(packageName);\n const catalog = await loadTokensPackageManifest(root);\n return {\n packageName,\n packageVersion: catalog.version,\n variants: catalog.variants.map((v) => ({\n name: v.name,\n displayName: v.displayName,\n version: v.version,\n description: v.description,\n linked: v.linked,\n })),\n };\n}\n\n// Re-export the strategy enum constituents so consumers don't have to import\n// from registry separately.\nexport type { UpdateStrategy };\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { logger } from \"./logger.js\";\n\n/**\n * Recursively create a directory (like mkdir -p).\n */\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\n/**\n * Atomic write: write to a .tmp file first, then rename.\n */\nexport async function writeFileSafe(\n filePath: string,\n content: string,\n): Promise<void> {\n const dir = path.dirname(filePath);\n await ensureDir(dir);\n const tmp = filePath + \".tmp\";\n await fs.writeFile(tmp, content, \"utf-8\");\n await fs.rename(tmp, filePath);\n}\n\n/**\n * Read a file or return null if it doesn't exist.\n */\nexport async function readFileOrNull(\n filePath: string,\n): Promise<string | null> {\n try {\n return await fs.readFile(filePath, \"utf-8\");\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n return null;\n }\n throw err;\n }\n}\n\n/**\n * Create a backup of a file under `.teamix-evo/.backups/`.\n */\nexport async function backupFile(\n filePath: string,\n projectRoot: string,\n): Promise<void> {\n const content = await readFileOrNull(filePath);\n if (content === null) {\n logger.debug(`Skip backup: ${filePath} does not exist`);\n return;\n }\n\n const rel = path.relative(projectRoot, filePath);\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backupPath = path.join(\n projectRoot,\n \".teamix-evo\",\n \".backups\",\n `${rel}.${timestamp}.bak`,\n );\n\n await ensureDir(path.dirname(backupPath));\n await fs.writeFile(backupPath, content, \"utf-8\");\n logger.debug(`Backed up ${rel} → ${path.relative(projectRoot, backupPath)}`);\n}\n\n/**\n * Check whether a file exists.\n */\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n","import { red, yellow, cyan, green, gray } from \"kolorist\";\n\nconst isDebug = process.env.TEAMIX_DEBUG === \"1\";\n\nexport const logger = {\n info(msg: string): void {\n console.log(cyan(\"ℹ\"), msg);\n },\n\n warn(msg: string): void {\n console.warn(yellow(\"⚠\"), msg);\n },\n\n error(msg: string): void {\n console.error(red(\"✖\"), msg);\n },\n\n success(msg: string): void {\n console.log(green(\"✔\"), msg);\n },\n\n debug(msg: string): void {\n if (isDebug) {\n console.log(gray(\"⊡\"), gray(msg));\n }\n },\n};\n","import { createHash } from \"node:crypto\";\n\n/**\n * Compute a SHA-256 hash of the given content.\n * Returns a string in the format \"sha256:<hex>\".\n */\nexport function computeHash(content: string): string {\n const hash = createHash(\"sha256\").update(content, \"utf-8\").digest(\"hex\");\n return `sha256:${hash}`;\n}\n","import * as path from 'node:path';\nimport type {\n ProjectConfig,\n InstalledManifest,\n InstalledPackage,\n SkillsLock,\n TokensPackLock,\n} from '@teamix-evo/registry';\nimport {\n validateConfig,\n validateInstalled,\n validateSkillsLock,\n TokensPackLockSchema,\n} from '@teamix-evo/registry';\nimport { readFileOrNull, writeFileSafe, ensureDir } from '../utils/fs.js';\nimport { getErrorMessage } from '../utils/error.js';\nimport { logger } from '../utils/logger.js';\n\nconst TEAMIX_DIR = '.teamix-evo';\nconst CONFIG_FILE = 'config.json';\nconst MANIFEST_FILE = 'manifest.json';\nconst TOKENS_LOCK_FILE = 'tokens-lock.json';\n/**\n * Consumer-side directory under `.teamix-evo/` that holds the skill source\n * mirrors (per ADR 0013). Renamed from `skills` → `skills-source` in the Init\n * landing improvement plan to avoid name-clash with installed package roots\n * and IDE mirror buckets; legacy paths are migrated lazily via\n * `migrateLegacySkillsSourceDir` (see `skills-installer.ts`).\n */\nconst SKILLS_DIR = 'skills-source';\n/** Legacy directory name retained for one-shot migration detection. */\nexport const LEGACY_SKILLS_DIR = 'skills';\nconst SKILLS_LOCK_FILE = 'manifest.lock.json';\n\n/**\n * Get the .teamix-evo directory path for a project.\n */\nexport function getTeamixDir(projectRoot: string): string {\n return path.join(projectRoot, TEAMIX_DIR);\n}\n\n/**\n * Ensure the .teamix-evo directory exists.\n */\nexport async function ensureTeamixDir(projectRoot: string): Promise<string> {\n const dir = getTeamixDir(projectRoot);\n await ensureDir(dir);\n return dir;\n}\n\n/**\n * Read the project config from .teamix-evo/config.json.\n * Returns null if the file does not exist; THROWS on corrupted content\n * so callers don't silently clobber prior config (#32 #18).\n */\nexport async function readProjectConfig(\n projectRoot: string,\n): Promise<ProjectConfig | null> {\n const configPath = path.join(projectRoot, TEAMIX_DIR, CONFIG_FILE);\n const raw = await readFileOrNull(configPath);\n if (raw === null) return null;\n\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch (err) {\n throw new Error(\n `Corrupted config.json (${getErrorMessage(err)}). ` +\n `Fix the JSON manually or remove the file to start fresh; refusing to clobber prior config.`,\n );\n }\n const result = validateConfig(data);\n if (!result.success) {\n throw new Error(\n `Invalid config.json schema: ${result.error}. ` +\n `Fix the file manually or remove it to start fresh.`,\n );\n }\n return result.data;\n}\n\n/**\n * Write the project config to .teamix-evo/config.json.\n */\nexport async function writeProjectConfig(\n projectRoot: string,\n config: ProjectConfig,\n): Promise<void> {\n const configPath = path.join(projectRoot, TEAMIX_DIR, CONFIG_FILE);\n await writeFileSafe(configPath, JSON.stringify(config, null, 2) + '\\n');\n logger.debug(`Wrote config → ${configPath}`);\n}\n\n/**\n * Read the installed manifest from .teamix-evo/manifest.json.\n * Returns null if the file does not exist; THROWS on corrupted content so\n * callers don't silently lose prior installs by treating broken JSON as\n * \"fresh install\" (#32 #18). Use `readInstalledManifestOrNull` for the\n * old lenient behavior.\n */\nexport async function readInstalledManifest(\n projectRoot: string,\n): Promise<InstalledManifest | null> {\n const manifestPath = path.join(projectRoot, TEAMIX_DIR, MANIFEST_FILE);\n const raw = await readFileOrNull(manifestPath);\n if (raw === null) return null;\n\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch (err) {\n throw new Error(\n `Corrupted manifest.json (${getErrorMessage(err)}). ` +\n `Fix the JSON manually or remove the file to start fresh; refusing to clobber prior install records.`,\n );\n }\n const result = validateInstalled(data);\n if (!result.success) {\n throw new Error(\n `Invalid manifest.json schema: ${result.error}. ` +\n `Fix the file manually or remove it to start fresh.`,\n );\n }\n return result.data;\n}\n\n/**\n * Write the installed manifest to .teamix-evo/manifest.json.\n */\nexport async function writeInstalledManifest(\n projectRoot: string,\n manifest: InstalledManifest,\n): Promise<void> {\n const manifestPath = path.join(projectRoot, TEAMIX_DIR, MANIFEST_FILE);\n await writeFileSafe(manifestPath, JSON.stringify(manifest, null, 2) + '\\n');\n logger.debug(`Wrote manifest → ${manifestPath}`);\n}\n\n/**\n * Read .teamix-evo/tokens-lock.json. Returns null if missing or invalid.\n */\nexport async function readTokensLock(\n projectRoot: string,\n): Promise<TokensPackLock | null> {\n const lockPath = path.join(projectRoot, TEAMIX_DIR, TOKENS_LOCK_FILE);\n const raw = await readFileOrNull(lockPath);\n if (raw === null) return null;\n try {\n const parsed = TokensPackLockSchema.safeParse(JSON.parse(raw));\n if (!parsed.success) {\n logger.warn(`Invalid tokens-lock.json: ${parsed.error.message}`);\n return null;\n }\n return parsed.data;\n } catch (err) {\n logger.warn(`Failed to parse tokens-lock.json: ${getErrorMessage(err)}`);\n return null;\n }\n}\n\n/**\n * Convenience: read just the variant id from tokens-lock.json. Returns null\n * when no tokens variant has been installed.\n */\nexport async function readTokensVariant(\n projectRoot: string,\n): Promise<string | null> {\n const lock = await readTokensLock(projectRoot);\n return lock?.variant.name ?? null;\n}\n\n/**\n * Absolute path to the per-skill source directory (consumer-side source).\n * Per ADR 0013, this is the truth source from which IDE mirrors are produced.\n * Resolves under `<projectRoot>/.teamix-evo/skills-source/[<skillName>]`.\n */\nexport function getSkillsSourceDir(\n projectRoot: string,\n skillName?: string,\n): string {\n const base = path.join(projectRoot, TEAMIX_DIR, SKILLS_DIR);\n return skillName ? path.join(base, skillName) : base;\n}\n\n/**\n * Absolute path to the legacy `<projectRoot>/.teamix-evo/skills/` directory.\n * Used **only** by the lazy migration path; do not write into this location.\n */\nexport function getLegacySkillsSourceDir(projectRoot: string): string {\n return path.join(projectRoot, TEAMIX_DIR, LEGACY_SKILLS_DIR);\n}\n\n/**\n * Read .teamix-evo/skills/manifest.lock.json. Returns null if missing.\n */\nexport async function readSkillsLock(\n projectRoot: string,\n): Promise<SkillsLock | null> {\n const lockPath = path.join(\n projectRoot,\n TEAMIX_DIR,\n SKILLS_DIR,\n SKILLS_LOCK_FILE,\n );\n const raw = await readFileOrNull(lockPath);\n if (raw === null) return null;\n try {\n const data = JSON.parse(raw);\n const result = validateSkillsLock(data);\n if (!result.success) {\n logger.warn(`Invalid skills manifest.lock.json: ${result.error}`);\n return null;\n }\n return result.data;\n } catch (err) {\n logger.warn(\n `Failed to parse skills manifest.lock.json: ${getErrorMessage(err)}`,\n );\n return null;\n }\n}\n\n/**\n * Write .teamix-evo/skills/manifest.lock.json.\n */\nexport async function writeSkillsLock(\n projectRoot: string,\n lock: SkillsLock,\n): Promise<void> {\n const lockPath = path.join(\n projectRoot,\n TEAMIX_DIR,\n SKILLS_DIR,\n SKILLS_LOCK_FILE,\n );\n await writeFileSafe(lockPath, JSON.stringify(lock, null, 2) + '\\n');\n logger.debug(`Wrote skills lock → ${lockPath}`);\n}\n\n/**\n * Look up an installed package record by package name.\n *\n * The {@link InstalledManifest} schema does not enforce uniqueness on the\n * `package` key — variant switches re-append a new record rather than\n * mutating the old one. We therefore return the **last** match (chronological\n * latest) and `null` when no record exists.\n *\n * Shared helper consumed by both {@link ui-upgrade-detector} and\n * {@link ui-upgrade-staging} to keep the lookup semantics aligned.\n */\nexport function findInstalledPackage(\n installed: InstalledManifest | null,\n packageName: string,\n): InstalledPackage | null {\n if (!installed) return null;\n const matches = installed.installed.filter((p) => p.package === packageName);\n if (matches.length === 0) return null;\n return matches[matches.length - 1] ?? null;\n}\n","/**\n * Safely extract an error message from an unknown thrown value.\n *\n * JavaScript allows `throw \"string\"` / `throw 42` / `throw null` — using\n * `(err as Error).message` directly is unsafe. This normaliser covers all\n * runtime cases.\n */\nexport function getErrorMessage(err: unknown): string {\n if (err instanceof Error) return err.message;\n if (typeof err === 'string') return err;\n try {\n return JSON.stringify(err);\n } catch {\n return String(err);\n }\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport type { SkillsPackageManifest } from '@teamix-evo/registry';\nimport { loadSkillsPackageManifest } from '@teamix-evo/registry';\nimport { logger } from '../utils/logger.js';\n\nconst require = createRequire(import.meta.url);\n\n/**\n * Resolve the package root directory for the skills package.\n */\nfunction resolvePackageRoot(packageName: string): string {\n const pkgJsonPath = require.resolve(`${packageName}/package.json`);\n return path.dirname(pkgJsonPath);\n}\n\n/**\n * Load the skills package manifest and optional shared `_data.json`.\n *\n * @param packageName - e.g. \"@teamix-evo/skills\"\n */\nexport async function loadSkillsData(packageName: string): Promise<{\n manifest: SkillsPackageManifest;\n data: Record<string, unknown>;\n packageRoot: string;\n}> {\n const packageRoot = resolvePackageRoot(packageName);\n\n logger.debug(`Resolved skills package root: ${packageRoot}`);\n\n const manifest = await loadSkillsPackageManifest(packageRoot);\n\n let data: Record<string, unknown> = {};\n const dataPath = path.join(packageRoot, '_data.json');\n try {\n const raw = await fs.readFile(dataPath, 'utf-8');\n data = JSON.parse(raw) as Record<string, unknown>;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw err;\n }\n logger.debug(`No _data.json found at ${dataPath}, using empty data`);\n }\n\n return { manifest, data, packageRoot };\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport type {\n SkillEntry,\n SkillsPackageManifest,\n InstalledResource,\n SkillIde,\n SkillScope,\n} from '@teamix-evo/registry';\nimport {\n replaceManagedRegion,\n hasManagedRegion,\n extractFrontmatter,\n replaceFrontmatter,\n} from '@teamix-evo/registry';\nimport { getAdapter } from '../ide/index.js';\nimport {\n writeFileSafe,\n readFileOrNull,\n fileExists,\n ensureDir,\n backupFile,\n} from '../utils/fs.js';\nimport { computeHash } from '../utils/hash.js';\nimport { renderTemplate, loadTemplateFile } from '../utils/template.js';\nimport { logger } from '../utils/logger.js';\nimport { getErrorMessage } from '../utils/error.js';\nimport { walkDir } from '../utils/path.js';\nimport {\n getSkillsSourceDir,\n getLegacySkillsSourceDir,\n LEGACY_SKILLS_DIR,\n readInstalledManifest,\n writeInstalledManifest,\n} from './state.js';\n\n/**\n * Source-mirror skills installer (per ADR 0013).\n *\n * Two-stage flow:\n * 1. **writeSkillSources** — render upstream `<packageRoot>/<skill.source>` and\n * write to `<projectRoot>/.teamix-evo/skills-source/<id>/` (the consumer-side\n * source of truth, regenerable, in git).\n * 2. **syncSkillsToIdes** — pure byte-for-byte copy from source dir to each\n * requested IDE mirror path (`.qoder/skills/<id>/`, `.claude/skills/<id>/`).\n * Mirrors are 100% derived; not subject to managed-region preservation.\n *\n * `installSkills` orchestrates both. `updateSkills` re-renders the source with\n * managed-region preservation against the existing source (NOT the mirrors),\n * then re-syncs.\n */\n\nexport interface SkillInstallOptions {\n /** Project root directory */\n projectRoot: string;\n /** Skills package manifest */\n manifest: SkillsPackageManifest;\n /** Template data */\n data: Record<string, unknown>;\n /** Absolute skills package root */\n packageRoot: string;\n /** IDE kinds to install for (intersection with skill.ides is computed) */\n ides: readonly SkillIde[];\n /** Install scope */\n scope: SkillScope;\n /** Optional: limit to specific skill ids */\n onlyIds?: string[];\n}\n\nexport interface SkillInstallResult {\n resources: InstalledResource[];\n count: number;\n}\n\n/**\n * Install (or reinstall) all skills declared in the manifest using the\n * source-mirror flow. Returns InstalledResource records for both source files\n * and IDE mirror files.\n */\nexport async function installSkills(\n options: SkillInstallOptions,\n): Promise<SkillInstallResult> {\n // One-shot lazy migration: rename legacy `.teamix-evo/skills/` to\n // `.teamix-evo/skills-source/` and rewrite manifest target paths if needed.\n // Runs unconditionally on every install; the function short-circuits when\n // there is nothing to migrate.\n await migrateLegacySkillsSourceDir(options.projectRoot);\n\n const { manifest, ides, scope, onlyIds } = options;\n const installed: InstalledResource[] = [];\n\n const targets = manifest.skills.filter(\n (s) => !onlyIds || onlyIds.includes(s.id),\n );\n\n for (const skill of targets) {\n const skillIdes = skill.ides.filter((i) => ides.includes(i));\n if (skillIdes.length === 0) {\n logger.warn(\n `Skill \"${skill.name}\" supports [${skill.ides.join(\n ',',\n )}], no overlap with [${ides.join(',')}]; skipped.`,\n );\n continue;\n }\n\n const sourceRecords = await writeSkillSource(skill, options);\n installed.push(...sourceRecords);\n\n for (const ide of skillIdes) {\n const mirrorRecords = await mirrorSkillToIde(\n skill,\n ide,\n scope,\n options.projectRoot,\n );\n installed.push(...mirrorRecords);\n }\n }\n\n return { resources: installed, count: installed.length };\n}\n\n/**\n * Render upstream skill source(s) and write to `.teamix-evo/skills/<id>/`.\n * Returns InstalledResource records (one per file) describing the source files.\n */\nasync function writeSkillSource(\n skill: SkillEntry,\n options: SkillInstallOptions,\n): Promise<InstalledResource[]> {\n const { data, packageRoot, projectRoot } = options;\n const sourceAbs = path.resolve(packageRoot, skill.source);\n const targetDir = getSkillsSourceDir(projectRoot, skill.name);\n const stat = await fs.stat(sourceAbs);\n const records: InstalledResource[] = [];\n\n if (stat.isFile()) {\n const targetFile = path.join(targetDir, 'SKILL.md');\n const content = await renderSkillContent(sourceAbs, skill, data);\n await writeFileSafe(targetFile, content);\n records.push(makeSourceRecord(skill, targetFile, content));\n logger.debug(` Wrote source: ${targetFile}`);\n return records;\n }\n\n await ensureDir(targetDir);\n const entries = await walkDir(sourceAbs);\n for (const entry of entries) {\n const rel = path.relative(sourceAbs, entry);\n let targetFile = path.join(targetDir, rel);\n if (skill.template && targetFile.endsWith('.hbs')) {\n targetFile = targetFile.slice(0, -4);\n }\n const content =\n skill.template && entry.endsWith('.hbs')\n ? renderTemplate(await loadTemplateFile(entry), { ...data, skill })\n : await fs.readFile(entry, 'utf-8');\n await writeFileSafe(targetFile, content);\n const relWritten = path.relative(targetDir, targetFile);\n records.push(makeSourceRecord(skill, targetFile, content, relWritten));\n logger.debug(` Wrote source: ${targetFile}`);\n }\n return records;\n}\n\n/**\n * Mirror an installed skill source to a single IDE path.\n *\n * Per ADR 0013, mirrors are normally pure byte-for-byte copies of source.\n * However, when the existing mirror file already contains managed-region\n * markers that match the skill's declared `managedRegions`, the writer falls\n * back to a managed-region replacement (#BUG-101) so user-authored notes\n * outside the markers are preserved across `skills update` / `skills sync`.\n * If markers are absent, the full source content is written (backward-compat).\n */\nasync function mirrorSkillToIde(\n skill: SkillEntry,\n ide: SkillIde,\n scope: SkillScope,\n projectRoot: string,\n): Promise<InstalledResource[]> {\n const sourceDir = getSkillsSourceDir(projectRoot, skill.name);\n const adapter = getAdapter(ide);\n const targetDir = adapter.getSkillTargetDir(skill.name, scope, projectRoot);\n const records: InstalledResource[] = [];\n\n const sourceFiles = await walkDir(sourceDir);\n await ensureDir(targetDir);\n for (const src of sourceFiles) {\n const rel = path.relative(sourceDir, src);\n const targetFile = path.join(targetDir, rel);\n const sourceContent = await fs.readFile(src, 'utf-8');\n\n const writtenContent = await writeMirrorContent(\n targetFile,\n sourceContent,\n skill.managedRegions,\n src,\n );\n records.push(\n makeMirrorRecord(skill, targetFile, writtenContent, ide, scope, rel),\n );\n logger.debug(` Mirrored ${ide}:${scope}: ${targetFile}`);\n }\n return records;\n}\n\n/**\n * Write a mirror file with optional managed-region preservation (#BUG-101).\n *\n * Behavior:\n * - Target absent → full write of source.\n * - `managedRegions` empty/undefined OR existing mirror has no matching\n * markers → full overwrite (with drift warning if content differs).\n * - Otherwise → replace each present managed region's content from the\n * source into the existing mirror, preserving content outside markers.\n *\n * Returns the bytes actually written (used for the InstalledResource hash).\n */\nasync function writeMirrorContent(\n targetFile: string,\n sourceContent: string,\n managedRegions: readonly string[] | undefined,\n sourceFile: string,\n): Promise<string> {\n const existing = await readFileOrNull(targetFile);\n\n if (existing === null) {\n await writeFileSafe(targetFile, sourceContent);\n return sourceContent;\n }\n\n const regions = managedRegions ?? [];\n const matchedRegions = regions.filter((id) => hasManagedRegion(existing, id));\n\n if (matchedRegions.length === 0) {\n if (existing !== sourceContent) {\n logger.warn(\n `Mirror drift detected at ${targetFile} — overwriting from source. ` +\n `Edit ${sourceFile} (not the mirror) and re-run \\`npx teamix-evo@latest skills sync\\`.`,\n );\n await writeFileSafe(targetFile, sourceContent);\n return sourceContent;\n }\n return existing;\n }\n\n let merged = existing;\n // ADR 0015: frontmatter is the IDE-facing protocol — always pull from\n // upstream so trigger/description changes propagate through update + sync\n // without requiring uninstall + reinstall. Body outside managed regions\n // remains user-owned.\n const upstreamFm = extractFrontmatter(sourceContent);\n if (upstreamFm) {\n merged = replaceFrontmatter(merged, upstreamFm);\n }\n for (const id of matchedRegions) {\n const newRegion = extractRegionBody(sourceContent, id);\n if (newRegion === null) continue;\n try {\n merged = replaceManagedRegion(merged, id, newRegion);\n } catch {\n // Region present in existing but pattern failed; skip safely.\n }\n }\n if (merged !== existing) {\n await writeFileSafe(targetFile, merged);\n }\n return merged;\n}\n\nfunction extractRegionBody(content: string, id: string): string | null {\n const re = new RegExp(\n `<!-- teamix-evo:managed:start id=\"${escapeRegExp(\n id,\n )}\" -->([\\\\s\\\\S]*?)<!-- teamix-evo:managed:end id=\"${escapeRegExp(\n id,\n )}\" -->`,\n );\n const m = content.match(re);\n if (!m) return null;\n return m[1]!.replace(/^\\n/, '').replace(/\\n$/, '');\n}\n\nasync function renderSkillContent(\n sourceAbs: string,\n skill: SkillEntry,\n data: Record<string, unknown>,\n): Promise<string> {\n if (skill.template ?? sourceAbs.endsWith('.hbs')) {\n const tpl = await loadTemplateFile(sourceAbs);\n return renderTemplate(tpl, { ...data, skill });\n }\n return fs.readFile(sourceAbs, 'utf-8');\n}\n\nfunction makeSourceRecord(\n skill: SkillEntry,\n targetAbs: string,\n content: string,\n rel?: string,\n): InstalledResource {\n const id = rel ? `${skill.id}:source:${rel}` : `${skill.id}:source`;\n return {\n id,\n target: targetAbs,\n hash: computeHash(content),\n strategy: skill.updateStrategy,\n };\n}\n\nfunction makeMirrorRecord(\n skill: SkillEntry,\n targetAbs: string,\n content: string,\n ide: SkillIde,\n scope: SkillScope,\n rel?: string,\n): InstalledResource {\n const id = rel && rel !== 'SKILL.md' ? `${skill.id}:${rel}` : skill.id;\n return {\n id,\n target: targetAbs,\n hash: computeHash(content),\n strategy: skill.updateStrategy,\n ide,\n scope,\n };\n}\n\nexport interface SkillUpdateOptions extends SkillInstallOptions {\n /**\n * Optional: existing installed records (legacy parameter kept for callers that\n * still pass it). The refactored updater consults the file-system source under\n * `.teamix-evo/skills/<id>/` for managed-region preservation, so this is\n * unused by the new flow. Callers should stop passing it.\n */\n installed?: InstalledResource[];\n /**\n * Optional: limit the update to these skill ids. When provided, skills not\n * in the set are skipped (no source rewrite, no mirror). Per ADR 0035,\n * the high-level `runSkillsUpdate` always passes this with the intersection\n * of `keys(lock.skills)` and the current install scope, ensuring update\n * never accidentally installs new skills or skills from a mismatched scope.\n *\n * Type matches `SkillInstallOptions.onlyIds` (mutable `string[] | undefined`).\n */\n onlyIds?: string[];\n}\n\nexport interface SkillUpdateResult {\n resources: InstalledResource[];\n summary: {\n overwritten: number;\n managed: number;\n skipped: number;\n created: number;\n };\n}\n\n/**\n * Update skills with managed-region preservation applied at the SOURCE layer\n * (not the mirrors). After source is rewritten, mirrors are re-synced cleanly.\n */\nexport async function updateSkills(\n options: SkillUpdateOptions,\n): Promise<SkillUpdateResult> {\n const { manifest, ides, scope, projectRoot } = options;\n const idFilter = options.onlyIds ? new Set(options.onlyIds) : null;\n const summary = { overwritten: 0, managed: 0, skipped: 0, created: 0 };\n const updated: InstalledResource[] = [];\n\n for (const skill of manifest.skills) {\n if (idFilter && !idFilter.has(skill.id)) continue;\n const skillIdes = skill.ides.filter((i) => ides.includes(i));\n if (skillIdes.length === 0) continue;\n\n const sourceRecords = await rewriteSkillSource(skill, options, summary);\n updated.push(...sourceRecords);\n\n // Mirrors are always overwritten cleanly from the (now updated) source.\n for (const ide of skillIdes) {\n const mirrorRecords = await mirrorSkillToIde(\n skill,\n ide,\n scope,\n projectRoot,\n );\n updated.push(...mirrorRecords);\n }\n }\n\n return { resources: updated, summary };\n}\n\nasync function rewriteSkillSource(\n skill: SkillEntry,\n options: SkillUpdateOptions,\n summary: SkillUpdateResult['summary'],\n): Promise<InstalledResource[]> {\n const { data, packageRoot, projectRoot } = options;\n const sourceAbs = path.resolve(packageRoot, skill.source);\n const targetDir = getSkillsSourceDir(projectRoot, skill.name);\n const stat = await fs.stat(sourceAbs);\n\n if (!stat.isFile()) {\n await ensureDir(targetDir);\n const entries = await walkDir(sourceAbs);\n const records: InstalledResource[] = [];\n for (const entry of entries) {\n const rel = path.relative(sourceAbs, entry);\n let targetFile = path.join(targetDir, rel);\n if (skill.template && targetFile.endsWith('.hbs')) {\n targetFile = targetFile.slice(0, -4);\n }\n const newContent =\n skill.template && entry.endsWith('.hbs')\n ? renderTemplate(await loadTemplateFile(entry), { ...data, skill })\n : await fs.readFile(entry, 'utf-8');\n const exists = await fileExists(targetFile);\n\n const written = await rewriteSingleFile({\n targetFile,\n newContent,\n exists,\n updateStrategy: skill.updateStrategy,\n managedRegions: skill.managedRegions,\n projectRoot,\n summary,\n });\n const relWritten = path.relative(targetDir, targetFile);\n records.push(makeSourceRecord(skill, targetFile, written, relWritten));\n }\n return records;\n }\n\n // Single-file skill: target = .teamix-evo/skills/<id>/SKILL.md\n const targetFile = path.join(targetDir, 'SKILL.md');\n const newContent = await renderSkillContent(sourceAbs, skill, data);\n const exists = await fileExists(targetFile);\n\n const written = await rewriteSingleFile({\n targetFile,\n newContent,\n exists,\n updateStrategy: skill.updateStrategy,\n managedRegions: skill.managedRegions,\n projectRoot,\n summary,\n });\n return [makeSourceRecord(skill, targetFile, written)];\n}\n\n/**\n * Apply updateStrategy logic to a single file (used by both single-file and\n * directory skill update paths).\n *\n * Returns the content actually on disk after the operation.\n */\nasync function rewriteSingleFile(args: {\n targetFile: string;\n newContent: string;\n exists: boolean;\n updateStrategy: SkillEntry['updateStrategy'];\n managedRegions: readonly string[] | undefined;\n projectRoot: string;\n summary: SkillUpdateResult['summary'];\n}): Promise<string> {\n const {\n targetFile,\n newContent,\n exists,\n updateStrategy,\n managedRegions,\n projectRoot,\n summary,\n } = args;\n\n if (updateStrategy === 'frozen') {\n if (exists) {\n summary.skipped++;\n return (await readFileOrNull(targetFile)) ?? newContent;\n }\n await writeFileSafe(targetFile, newContent);\n summary.created++;\n return newContent;\n }\n\n if (updateStrategy === 'regenerable' || !exists) {\n if (exists) {\n await backupFile(targetFile, projectRoot);\n summary.overwritten++;\n } else {\n summary.created++;\n }\n await writeFileSafe(targetFile, newContent);\n return newContent;\n }\n\n // managed: preserve outside-region content from the existing SOURCE.\n // Per ADR 0015, the YAML frontmatter is part of the skill's PROTOCOL\n // (name / description / trigger contract) and MUST always follow the\n // upstream package — only the body outside managed regions is treated\n // as user-owned. We therefore overlay the upstream frontmatter first,\n // then apply managed-region replacement on the body.\n const current = await readFileOrNull(targetFile);\n let merged = current ?? newContent;\n const upstreamFm = extractFrontmatter(newContent);\n if (upstreamFm) {\n merged = replaceFrontmatter(merged, upstreamFm);\n }\n for (const regionId of managedRegions ?? []) {\n const re = new RegExp(\n `<!-- teamix-evo:managed:start id=\"${escapeRegExp(\n regionId,\n )}\" -->([\\\\s\\\\S]*?)<!-- teamix-evo:managed:end id=\"${escapeRegExp(\n regionId,\n )}\" -->`,\n );\n const match = newContent.match(re);\n if (match) {\n const region = match[1]!.replace(/^\\n/, '').replace(/\\n$/, '');\n try {\n merged = replaceManagedRegion(merged, regionId, region);\n } catch {\n logger.warn(\n `Managed region \"${regionId}\" not found in ${targetFile}. Skipped.`,\n );\n }\n }\n }\n if (merged !== current) {\n await backupFile(targetFile, projectRoot);\n await writeFileSafe(targetFile, merged);\n }\n summary.managed++;\n return merged;\n}\n\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Sync existing skill sources to the requested IDE mirror paths.\n *\n * Used by:\n * - `skills add` (immediate mirror after source write — handled by installSkills)\n * - `skills sync` (re-mirror after the user adds an IDE or moves machines)\n * - `skills update` (re-mirror after source is rewritten)\n *\n * `onlyIds` lets the caller limit which skills are synced.\n */\nexport interface SkillSyncOptions {\n projectRoot: string;\n /** Skills present in the source dir to mirror (caller derives from lock). */\n skills: ReadonlyArray<{\n id: string;\n name: string;\n updateStrategy: SkillEntry['updateStrategy'];\n /** Managed-region ids for region-aware mirror sync. */\n managedRegions?: readonly string[];\n }>;\n ides: readonly SkillIde[];\n scope: SkillScope;\n onlyIds?: string[];\n}\n\nexport interface SkillSyncResult {\n resources: InstalledResource[];\n count: number;\n}\n\n/**\n * Mirror existing source dirs (`.teamix-evo/skills/<id>/`) to the given IDE\n * paths. Pure byte-for-byte copy — no rendering, no merge.\n */\nexport async function syncSkillsToIdes(\n options: SkillSyncOptions,\n): Promise<SkillSyncResult> {\n // One-shot lazy migration so a stale `.teamix-evo/skills/` from a prior CLI\n // version is moved to the new layout before we walk source dirs.\n await migrateLegacySkillsSourceDir(options.projectRoot);\n\n const { projectRoot, skills, ides, scope, onlyIds } = options;\n const out: InstalledResource[] = [];\n\n const targets = skills.filter((s) => !onlyIds || onlyIds.includes(s.id));\n for (const skill of targets) {\n const sourceDir = getSkillsSourceDir(projectRoot, skill.name);\n if (!(await fileExists(sourceDir))) {\n logger.warn(\n `Skill \"${skill.id}\" has no source at ${sourceDir}; skipped.`,\n );\n continue;\n }\n for (const ide of ides) {\n const adapter = getAdapter(ide);\n const targetDir = adapter.getSkillTargetDir(\n skill.name,\n scope,\n projectRoot,\n );\n await ensureDir(targetDir);\n const sourceFiles = await walkDir(sourceDir);\n for (const src of sourceFiles) {\n const rel = path.relative(sourceDir, src);\n const targetFile = path.join(targetDir, rel);\n const sourceContent = await fs.readFile(src, 'utf-8');\n\n // Region-aware mirror write (#BUG-101): keep user content outside\n // managed markers when the mirror already has them; otherwise full\n // overwrite (with drift warning).\n const writtenContent = await writeMirrorContent(\n targetFile,\n sourceContent,\n skill.managedRegions,\n src,\n );\n out.push({\n id: rel === 'SKILL.md' ? skill.id : `${skill.id}:${rel}`,\n target: targetFile,\n hash: computeHash(writtenContent),\n strategy: skill.updateStrategy,\n ide,\n scope,\n });\n }\n }\n }\n return { resources: out, count: out.length };\n}\n\n/**\n * One-shot migration of the consumer-side skill source directory from the\n * legacy `<projectRoot>/.teamix-evo/skills/` layout to the current\n * `<projectRoot>/.teamix-evo/skills-source/` layout (Init landing plan §A3).\n *\n * Behavior:\n * - When **only** the legacy dir exists → rename it to `skills-source`.\n * - When both exist → keep `skills-source` authoritative; warn that legacy\n * `skills/` is now stale (caller may delete manually).\n * - When neither exists or only `skills-source/` exists → no-op.\n *\n * Side effects:\n * - Updates `InstalledManifest` resources whose `target` still references the\n * legacy `.teamix-evo/skills/` path so subsequent `findInstalledPackage` /\n * uninstall lookups don't dangle.\n *\n * Failures are logged and swallowed: the rest of the install/sync should not\n * be blocked by a best-effort migration step.\n */\nexport async function migrateLegacySkillsSourceDir(\n projectRoot: string,\n): Promise<void> {\n const legacyDir = getLegacySkillsSourceDir(projectRoot);\n const newDir = getSkillsSourceDir(projectRoot);\n\n let legacyExists = false;\n let newExists = false;\n try {\n legacyExists = (await fs.stat(legacyDir)).isDirectory();\n } catch {\n legacyExists = false;\n }\n try {\n newExists = (await fs.stat(newDir)).isDirectory();\n } catch {\n newExists = false;\n }\n\n if (!legacyExists) return;\n if (newExists) {\n logger.warn(\n `Detected stale legacy skills source dir at ${legacyDir} alongside ${newDir}; ` +\n `the new layout takes precedence — you can safely delete the legacy dir.`,\n );\n return;\n }\n\n try {\n await fs.rename(legacyDir, newDir);\n logger.info(\n `Migrated skills source dir: \\`.teamix-evo/${LEGACY_SKILLS_DIR}/\\` → \\`.teamix-evo/skills-source/\\``,\n );\n } catch (err) {\n logger.warn(\n `Failed to rename legacy skills source dir (${getErrorMessage(\n err,\n )}); leaving as-is. New skills will install under the new layout.`,\n );\n return;\n }\n\n // Rewrite manifest targets that still reference the legacy path. We match\n // both POSIX and platform-native separators because Windows installs may\n // have stored back-slashed absolute paths.\n try {\n const manifest = await readInstalledManifest(projectRoot);\n if (!manifest) return;\n const legacyFragmentPosix = `/.teamix-evo/${LEGACY_SKILLS_DIR}/`;\n const newFragmentPosix = `/.teamix-evo/skills-source/`;\n const legacyFragmentNative = `${path.sep}.teamix-evo${path.sep}${LEGACY_SKILLS_DIR}${path.sep}`;\n const newFragmentNative = `${path.sep}.teamix-evo${path.sep}skills-source${path.sep}`;\n let touched = 0;\n for (const pkg of manifest.installed) {\n for (const r of pkg.resources) {\n if (typeof r.target !== 'string') continue;\n const before = r.target;\n let after = before.replace(legacyFragmentPosix, newFragmentPosix);\n after = after.replace(legacyFragmentNative, newFragmentNative);\n if (after !== before) {\n r.target = after;\n touched += 1;\n }\n }\n }\n if (touched > 0) {\n await writeInstalledManifest(projectRoot, manifest);\n logger.debug(\n `Rewrote ${touched} manifest target(s) to the new skills-source path.`,\n );\n }\n } catch (err) {\n logger.warn(\n `Migrated skills source dir but failed to update manifest paths (${getErrorMessage(\n err,\n )}); manifest may still reference legacy paths.`,\n );\n }\n}\n\n/**\n * Prune empty IDE skill directories under each adapter's skill root.\n *\n * Some workflows leave behind empty `<ide-root>/skills/<id>/` shells — e.g.\n * the upstream package dropped a skill, the user toggled it out via\n * `onlyIds`, or a partial mirror failed mid-write and removed the SKILL.md\n * but not the parent dir. Per the Init landing plan §G, every install /\n * sync run sweeps these out so the IDE side stays tidy.\n *\n * Safety:\n * - Only completely empty dirs are removed (no SKILL.md AND no other files).\n * - Non-empty dirs without SKILL.md are LEFT ALONE; deciding whether they\n * are user content vs stale mirror is out of scope for this best-effort\n * pass.\n * - All errors are swallowed; this is decoration, never a hard failure.\n *\n * Returns the list of absolute paths that were removed (for diagnostics).\n */\nexport async function pruneEmptyIdeSkillDirs(args: {\n projectRoot: string;\n ides: readonly SkillIde[];\n scope: SkillScope;\n}): Promise<string[]> {\n const removed: string[] = [];\n for (const ide of args.ides) {\n const adapter = getAdapter(ide);\n // Use a placeholder name to derive the per-IDE skill root, then take\n // dirname — every adapter returns `<root>/<name>/` shape.\n const placeholderDir = adapter.getSkillTargetDir(\n '__placeholder__',\n args.scope,\n args.projectRoot,\n );\n const skillsRoot = path.dirname(placeholderDir);\n let entries: string[];\n try {\n entries = await fs.readdir(skillsRoot);\n } catch {\n continue;\n }\n for (const name of entries) {\n const dir = path.join(skillsRoot, name);\n let stat;\n try {\n stat = await fs.stat(dir);\n } catch {\n continue;\n }\n if (!stat.isDirectory()) continue;\n let children: string[];\n try {\n children = await fs.readdir(dir);\n } catch {\n continue;\n }\n // Skip dirs that still contain a SKILL.md — they're live.\n if (children.some((c) => c === 'SKILL.md')) continue;\n // Only delete completely empty dirs; preserve any user content\n // sitting in a SKILL.md-less directory.\n if (children.length !== 0) continue;\n try {\n await fs.rmdir(dir);\n removed.push(dir);\n logger.debug(`Pruned empty IDE skill dir: ${dir}`);\n } catch {\n // Best-effort; ignore.\n }\n }\n }\n return removed;\n}\n\n/**\n * Remove all installed skill files. Returns the absolute paths removed.\n * After files are unlinked, walks up the directory tree pruning empty dirs\n * until a non-empty ancestor is reached (#33).\n */\nexport async function removeSkillFiles(\n records: InstalledResource[],\n): Promise<string[]> {\n const removed: string[] = [];\n for (const r of records) {\n try {\n await fs.unlink(r.target);\n removed.push(r.target);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n logger.warn(`Failed to remove ${r.target}: ${getErrorMessage(err)}`);\n }\n }\n }\n // Walk-up empty-dir prune. Collect immediate parents, then for each, walk\n // up the tree calling rmdir as long as the dir is empty. Bound the walk\n // to a small depth to prevent runaway in pathological filesystems.\n const startDirs = new Set(records.map((r) => path.dirname(r.target)));\n for (const startDir of startDirs) {\n let dir = startDir;\n for (let depth = 0; depth < 8; depth++) {\n try {\n const entries = await fs.readdir(dir);\n if (entries.length !== 0) break;\n await fs.rmdir(dir);\n } catch {\n break;\n }\n dir = path.dirname(dir);\n }\n }\n return removed;\n}\n","import * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { SkillScope } from '@teamix-evo/registry';\nimport type { IdeAdapter } from './IdeAdapter.js';\n\n/**\n * Qoder IDE adapter.\n * Skill paths:\n * - project: <projectRoot>/.qoder/skills/<name>/\n * - global: ~/.qoder/skills/<name>/\n */\nexport class QoderAdapter implements IdeAdapter {\n readonly kind = 'qoder' as const;\n readonly name = 'qoder';\n\n getProjectRoot(): string {\n return process.cwd();\n }\n\n detectIde(): boolean {\n // MVP: default to true. Future: check environment variables\n return true;\n }\n\n getSkillTargetDir(\n skillName: string,\n scope: SkillScope,\n projectRoot?: string,\n ): string {\n const base =\n scope === 'global'\n ? path.join(os.homedir(), '.qoder')\n : path.join(projectRoot ?? this.getProjectRoot(), '.qoder');\n return path.join(base, 'skills', skillName);\n }\n}\n","import * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { SkillScope } from '@teamix-evo/registry';\nimport type { IdeAdapter } from './IdeAdapter.js';\n\n/**\n * Claude Code IDE adapter.\n * Skill paths:\n * - project: <projectRoot>/.claude/skills/<name>/\n * - global: ~/.claude/skills/<name>/\n */\nexport class ClaudeAdapter implements IdeAdapter {\n readonly kind = 'claude' as const;\n readonly name = 'claude';\n\n getProjectRoot(): string {\n return process.cwd();\n }\n\n detectIde(): boolean {\n // Best-effort: presence of .claude/ in cwd or CLAUDECODE env var.\n return Boolean(process.env.CLAUDECODE);\n }\n\n getSkillTargetDir(\n skillName: string,\n scope: SkillScope,\n projectRoot?: string,\n ): string {\n const base =\n scope === 'global'\n ? path.join(os.homedir(), '.claude')\n : path.join(projectRoot ?? this.getProjectRoot(), '.claude');\n return path.join(base, 'skills', skillName);\n }\n}\n","import type { SkillIde } from '@teamix-evo/registry';\nimport type { IdeAdapter } from './IdeAdapter.js';\nimport { QoderAdapter } from './QoderAdapter.js';\nimport { ClaudeAdapter } from './ClaudeAdapter.js';\n\nexport type { IdeAdapter } from './IdeAdapter.js';\nexport { QoderAdapter } from './QoderAdapter.js';\nexport { ClaudeAdapter } from './ClaudeAdapter.js';\n\n/** All supported IDE kinds (also default selection set for skills) */\nexport const ALL_IDE_KINDS: readonly SkillIde[] = ['qoder', 'claude'] as const;\n\n/**\n * Get the adapter for a specific IDE kind.\n */\nexport function getAdapter(kind: SkillIde): IdeAdapter {\n switch (kind) {\n case 'qoder':\n return new QoderAdapter();\n case 'claude':\n return new ClaudeAdapter();\n default: {\n const _exhaustive: never = kind;\n throw new Error(`Unsupported IDE kind: ${_exhaustive as string}`);\n }\n }\n}\n\n/**\n * Detect the current IDE environment and return the appropriate adapter.\n * MVP: prefers Qoder; falls back to Claude if CLAUDECODE env is set.\n */\nexport function detectIde(): IdeAdapter {\n const claude = new ClaudeAdapter();\n if (claude.detectIde()) return claude;\n return new QoderAdapter();\n}\n","import Handlebars from 'handlebars';\nimport * as fs from 'node:fs/promises';\n\n// Register custom helpers\nHandlebars.registerHelper('lowercase', (str: unknown) => {\n return typeof str === 'string'\n ? str.toLowerCase()\n : String(str ?? '').toLowerCase();\n});\n\n/** LRU-style compilation cache to avoid recompiling the same template */\nconst compiledCache = new Map<string, HandlebarsTemplateDelegate>();\nconst MAX_CACHE_SIZE = 64;\n\nfunction getCompiledTemplate(\n templateContent: string,\n): HandlebarsTemplateDelegate {\n let compiled = compiledCache.get(templateContent);\n if (!compiled) {\n if (compiledCache.size >= MAX_CACHE_SIZE) {\n // Evict oldest entry\n const firstKey = compiledCache.keys().next().value!;\n compiledCache.delete(firstKey);\n }\n compiled = Handlebars.compile(templateContent, { noEscape: true });\n compiledCache.set(templateContent, compiled);\n }\n return compiled;\n}\n\n/**\n * Render a Handlebars template string with the given data.\n */\nexport function renderTemplate(\n templateContent: string,\n data: Record<string, unknown>,\n): string {\n const compiled = getCompiledTemplate(templateContent);\n return compiled(data);\n}\n\n/**\n * Load template file content from disk.\n */\nexport async function loadTemplateFile(filePath: string): Promise<string> {\n return fs.readFile(filePath, 'utf-8');\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport { createRequire } from 'node:module';\n\nconst require = createRequire(import.meta.url);\n\n/**\n * Resolve a source path — handles _template/ prefix by resolving from packageRoot.\n */\nexport function resolveSourcePath(\n source: string,\n variantDir: string,\n packageRoot: string,\n): string {\n if (source.startsWith('_template/')) {\n return path.join(packageRoot, source);\n }\n return path.join(variantDir, source);\n}\n\n/**\n * Common directory names to skip when walking user project trees.\n */\nexport const DEFAULT_SKIP_DIRS = new Set([\n 'node_modules',\n 'dist',\n 'build',\n '.teamix-evo',\n]);\n\n/**\n * Recursively walk a directory and return all file paths.\n * When `skipDirs` is provided, directories whose names are in the set will not\n * be entered — this avoids the cost of recursing into large trees like\n * `node_modules/` only to discard results later.\n */\nexport async function walkDir(\n dir: string,\n skipDirs?: Set<string>,\n): Promise<string[]> {\n const files: string[] = [];\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n if (skipDirs && skipDirs.has(entry.name)) continue;\n files.push(...(await walkDir(fullPath, skipDirs)));\n } else if (entry.isFile()) {\n files.push(fullPath);\n }\n }\n\n return files;\n}\n\n/**\n * Locate the root directory of an installed npm package by resolving its\n * `package.json`. Used to read token source CSS and variant manifests.\n */\nexport function resolveTokensPackageRoot(packageName: string): string {\n const pkgJson = require.resolve(`${packageName}/package.json`);\n return path.dirname(pkgJson);\n}\n","import * as path from 'node:path';\nimport { writeFileSafe, fileExists } from './fs.js';\nimport { getErrorMessage } from './error.js';\nimport { logger } from './logger.js';\n\n/**\n * `.mcp.json` content launched by Cursor / Claude Code / Qoder.\n *\n * Uses `node` to directly execute the locally-installed MCP server entry.\n * This avoids npx resolution issues (scoped package bin mismatch, network\n * dependency, internal registry sync problems) and is faster to start.\n *\n * Prerequisite: `@teamix-evo/mcp` must be in devDependencies (guaranteed by\n * both `create-teamix-evo` scaffold and `teamix-evo init` flows).\n *\n * Kept in sync with the scaffold writer in `@teamix-evo/create`. Any change\n * here MUST be mirrored there (see `packages/create/src/orchestrator.ts`).\n */\nconst MCP_JSON_CONTENT = {\n mcpServers: {\n 'teamix-evo': {\n command: 'node',\n args: ['node_modules/@teamix-evo/mcp/dist/cli.js'],\n },\n },\n} as const;\n\n/**\n * Ensure that `<projectRoot>/.mcp.json` exists.\n *\n * This is called from the incremental entry points (`tokens init`, `skills\n * add`, `ui init`) so projects that adopted teamix-evo without `create` still\n * get the MCP wiring (#BUG-103). Existing files are never overwritten — users\n * may have customised them.\n *\n * Returns `'created'` on first write, `'exists'` if a file is already present,\n * `'failed'` if writing failed (logged as a warning; never throws).\n */\nexport async function ensureMcpJson(\n projectRoot: string,\n): Promise<'created' | 'exists' | 'failed'> {\n const mcpPath = path.join(projectRoot, '.mcp.json');\n if (await fileExists(mcpPath)) return 'exists';\n try {\n await writeFileSafe(\n mcpPath,\n JSON.stringify(MCP_JSON_CONTENT, null, 2) + '\\n',\n );\n logger.debug(`Wrote .mcp.json → ${mcpPath}`);\n return 'created';\n } catch (err) {\n logger.warn(`Failed to write .mcp.json: ${getErrorMessage(err)}`);\n return 'failed';\n }\n}\n","import type {\n ProjectConfig,\n InstalledManifest,\n InstalledResource,\n SkillIde,\n SkillScope,\n SkillsLock,\n SkillsPackageManifest,\n} from '@teamix-evo/registry';\nimport { loadSkillsData } from './skills-client.js';\nimport {\n installSkills,\n updateSkills,\n pruneEmptyIdeSkillDirs,\n} from './skills-installer.js';\nimport {\n ensureTeamixDir,\n readProjectConfig,\n writeProjectConfig,\n readInstalledManifest,\n writeInstalledManifest,\n readSkillsLock,\n writeSkillsLock,\n readTokensVariant,\n} from './state.js';\nimport { logger } from '../utils/logger.js';\nimport { ensureMcpJson } from '../utils/mcp.js';\n\nconst DEFAULT_SKILLS_PACKAGE = '@teamix-evo/skills';\nconst FLAT_VARIANT = '_flat';\n\n// ─── runSkillsInit ────────────────────────────────────────────────────────────\n// Bulk bootstrap: install every skill in the manifest that matches the current\n// tokens variant + install scope (per ADR 0033). No skill ids accepted —\n// granular adds go through `runSkillsAdd`. Verb split per ADR 0034.\n\nexport interface RunSkillsInitOptions {\n /** Absolute project root directory. */\n projectRoot: string;\n /** Target IDEs to inject skills into. Required (bulk has no fallback source). */\n ides: readonly SkillIde[];\n /** Install scope. Required (bulk has no fallback source). */\n scope: SkillScope;\n /** IDE identifier written into config.ide when bootstrapping a fresh config (defaults to \"qoder\"). */\n ide?: string;\n /** Override the skills package name (defaults to \"@teamix-evo/skills\"). */\n packageName?: string;\n}\n\nexport type RunSkillsInitResult =\n | {\n status: 'installed';\n packageName: string;\n version: string;\n ides: SkillIde[];\n scope: SkillScope;\n skillCount: number;\n fileCount: number;\n resources: InstalledResource[];\n addedSkillIds: string[];\n skippedSkillIds: string[];\n /**\n * Skill ids that were auto-upgraded because their locked version was\n * older than the manifest version.\n */\n autoUpdatedSkillIds: string[];\n /**\n * @deprecated Outdated skills are now auto-upgraded; kept for compat.\n */\n outdatedSkills: OutdatedSkillInfo[];\n }\n | {\n /** Returned when a skills package is already installed and bulk has nothing new to add. */\n status: 'already-initialized';\n };\n\n/**\n * Programmatic equivalent of `teamix-evo skills init`.\n *\n * Installs every manifest skill that matches the current tokens variant +\n * install scope (per ADR 0033 scope filter). Re-running on a project whose\n * `packages.skills` is already configured AND has no missing candidates\n * returns `'already-initialized'`.\n */\nexport async function runSkillsInit(\n options: RunSkillsInitOptions,\n): Promise<RunSkillsInitResult> {\n const { projectRoot } = options;\n const packageName = options.packageName ?? DEFAULT_SKILLS_PACKAGE;\n const ides = [...options.ides] as SkillIde[];\n const scope = options.scope;\n if (ides.length === 0) {\n throw new Error('At least one IDE must be selected.');\n }\n\n await ensureTeamixDir(projectRoot);\n const existingConfig = await readProjectConfig(projectRoot);\n const existingSkillsCfg = existingConfig?.packages?.skills;\n\n const { manifest, data, packageRoot } = await loadSkillsData(packageName);\n const currentTokensVariant = await readTokensVariant(projectRoot);\n\n const existing = await readExistingState(projectRoot, packageName);\n\n // ADR 0033 + tokens variant: filter manifest skills to those eligible for\n // this install scope and current variant.\n const candidateIds = manifest.skills\n .filter((s) => {\n const effectiveScope = s.scope ?? 'project';\n if (effectiveScope !== scope) {\n logger.debug(\n `Skipping skill \"${s.id}\" (scope=${effectiveScope}): current install scope is \"${scope}\". Use \\`skills add ${s.id} --scope ${effectiveScope}\\` to install.`,\n );\n return false;\n }\n if (!s.variant) return true;\n if (!currentTokensVariant) {\n logger.debug(\n `Skipping variant-bound skill \"${s.id}\" (variant=${s.variant}): no tokens variant installed; will be picked up when \"tokens init\" runs.`,\n );\n return false;\n }\n if (s.variant !== currentTokensVariant) {\n logger.debug(\n `Skipping variant-bound skill \"${s.id}\" (variant=${s.variant}): current tokens variant is \"${currentTokensVariant}\".`,\n );\n return false;\n }\n return true;\n })\n .map((s) => s.id);\n\n // Partition candidate skills the same way `runSkillsAdd` does: brand-new go\n // to `onlyIds`; already installed and at-or-above manifest version go to\n // `skippedSkillIds`; already installed but with `lock.version < manifest.version`\n // surface as `outdatedSkills` so callers can suggest `skills update <id>`.\n const { onlyIds, skippedSkillIds, outdatedSkills } = partitionByVersion(\n candidateIds,\n manifest,\n existing,\n );\n\n // Idempotent fast path: nothing new and nothing outdated. Preserve the\n // historical `already-initialized` status only when there's literally\n // nothing for the caller to act on; if any skill is outdated we fall\n // through to the empty-install fast path below so the upgrade hint is\n // surfaced to the CLI layer.\n if (\n existingSkillsCfg &&\n onlyIds.length === 0 &&\n outdatedSkills.length === 0\n ) {\n return { status: 'already-initialized' };\n }\n\n // Empty-install fast path mirrors `runSkillsAdd`: nothing new to install,\n // but at least one outdated skill needs to be auto-upgraded.\n if (onlyIds.length === 0) {\n let autoUpdatedSkillIds: string[] = [];\n if (outdatedSkills.length > 0) {\n autoUpdatedSkillIds = await autoUpgradeOutdatedSkills({\n projectRoot,\n packageName,\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n outdatedSkills,\n existing,\n existingConfig,\n });\n }\n return {\n status: 'installed',\n packageName,\n version: manifest.version,\n ides,\n scope,\n skillCount: 0,\n fileCount: 0,\n resources: [],\n addedSkillIds: [],\n skippedSkillIds,\n autoUpdatedSkillIds,\n outdatedSkills: [],\n };\n }\n\n return finalizeSkillsInstall({\n projectRoot,\n packageName,\n ideIdent: options.ide ?? 'qoder',\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n onlyIds,\n skippedSkillIds,\n outdatedSkills,\n existing,\n existingConfig,\n });\n}\n\n// ─── runSkillsAdd ─────────────────────────────────────────────────────────────\n// Incremental: install named skill ids. `names` is required (≥ 1).\n// Skills already present are skipped. ADR 0034.\n\nexport interface RunSkillsAddOptions {\n /** Absolute project root directory. */\n projectRoot: string;\n /**\n * Skill ids to add. **Required, must contain at least one id.** Use\n * {@link runSkillsInit} for bulk bootstrap (no ids).\n */\n names: readonly string[];\n /** Target IDEs. Optional — falls back to the previously installed config. */\n ides?: readonly SkillIde[];\n /** Install scope. Optional — falls back to existing config. */\n scope?: SkillScope;\n /** IDE identifier written into config.ide when bootstrapping a fresh config (defaults to \"qoder\"). */\n ide?: string;\n /** Override the skills package name (defaults to \"@teamix-evo/skills\"). */\n packageName?: string;\n}\n\n/**\n * Detail for an already-installed skill whose locked version is older than\n * the manifest's latest version. Use `skills update <id>` to upgrade.\n */\nexport interface OutdatedSkillInfo {\n /** Skill id */\n id: string;\n /** Version recorded in `.teamix-evo/skills.lock.json` */\n installed: string;\n /** Version available in the upstream manifest (i.e. `npx` resolved `@latest`) */\n latest: string;\n}\n\nexport type RunSkillsAddResult = {\n status: 'installed';\n packageName: string;\n version: string;\n ides: SkillIde[];\n scope: SkillScope;\n /** Number of skills that were freshly added in this call. */\n skillCount: number;\n /** Number of files written by `installSkills` for the freshly added skills. */\n fileCount: number;\n /** InstalledResource records for the freshly added skills only. */\n resources: InstalledResource[];\n /** Skill ids that were freshly added in this call. */\n addedSkillIds: string[];\n /**\n * Skill ids that were requested but already installed at the latest version;\n * nothing to do.\n */\n skippedSkillIds: string[];\n /**\n * Skill ids that were auto-upgraded because their locked version was older\n * than the manifest version.\n */\n autoUpdatedSkillIds: string[];\n /**\n * @deprecated Outdated skills are now auto-upgraded; this array is always\n * empty. Kept for backward-compatible callers; will be removed in next major.\n */\n outdatedSkills: OutdatedSkillInfo[];\n};\n\n/**\n * Programmatic equivalent of `teamix-evo skills add <names...>` (ADR 0034).\n *\n * Installs only the listed skills. Skills already present are skipped (use\n * `skills update` to refresh). `ides` / `scope` may be omitted — they fall\n * back to the previously installed config.\n *\n * Throws if `names` is empty — bulk bootstrap belongs to {@link runSkillsInit}.\n */\nexport async function runSkillsAdd(\n options: RunSkillsAddOptions,\n): Promise<RunSkillsAddResult> {\n if (!options.names || options.names.length === 0) {\n throw new Error(\n 'runSkillsAdd requires at least one skill id. Use runSkillsInit() for bulk install.',\n );\n }\n\n const { projectRoot, names: requestedNames } = options;\n const packageName = options.packageName ?? DEFAULT_SKILLS_PACKAGE;\n\n await ensureTeamixDir(projectRoot);\n\n const existingConfig = await readProjectConfig(projectRoot);\n const existingSkillsCfg = existingConfig?.packages?.skills;\n\n // Resolve ides/scope: explicit option wins, else fall back to existing config.\n const ides = (\n options.ides && options.ides.length > 0\n ? [...options.ides]\n : existingSkillsCfg?.ides\n ? [...existingSkillsCfg.ides]\n : []\n ) as SkillIde[];\n const scope = (options.scope ?? existingSkillsCfg?.scope) as\n | SkillScope\n | undefined;\n if (ides.length === 0) {\n throw new Error('At least one IDE must be selected.');\n }\n if (!scope) {\n throw new Error('Scope must be specified (project | global).');\n }\n\n const { manifest, data, packageRoot } = await loadSkillsData(packageName);\n\n // Validate requested names against manifest.\n const known = new Set(manifest.skills.map((s) => s.id));\n const unknown = requestedNames.filter((n) => !known.has(n));\n if (unknown.length > 0) {\n const available = [...known].join(', ');\n throw new Error(\n `Unknown skill id(s): ${unknown.join(', ')}. Available: ${\n available || '(none)'\n }.`,\n );\n }\n\n // ADR 0033: warn when explicitly naming a skill whose declared scope\n // doesn't match the current install scope. Don't block — explicit\n // naming overrides the default; user takes responsibility.\n for (const s of manifest.skills) {\n if (requestedNames.includes(s.id) && s.scope && s.scope !== scope) {\n logger.warn(\n `\"${s.id}\" 推荐 ${s.scope} scope 安装。当前以 ${scope} scope 强制安装,可能与另一 scope 的副本冲突。建议改用 \\`skills add ${s.id} --scope ${s.scope}\\`。`,\n );\n }\n }\n\n const existing = await readExistingState(projectRoot, packageName);\n\n // Partition requested names: already-installed-and-up-to-date go to\n // `skippedSkillIds`; already-installed-but-older go to `outdatedSkills`\n // (caller surfaces an upgrade hint); brand-new go to `onlyIds`.\n const { onlyIds, skippedSkillIds, outdatedSkills } = partitionByVersion(\n requestedNames,\n manifest,\n existing,\n );\n\n // Incremental fast path: nothing new to install. But if there are\n // outdated skills, auto-upgrade them before returning.\n if (onlyIds.length === 0) {\n let autoUpdatedSkillIds: string[] = [];\n if (outdatedSkills.length > 0) {\n autoUpdatedSkillIds = await autoUpgradeOutdatedSkills({\n projectRoot,\n packageName,\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n outdatedSkills,\n existing,\n existingConfig,\n });\n }\n return {\n status: 'installed',\n packageName,\n version: manifest.version,\n ides,\n scope,\n skillCount: 0,\n fileCount: 0,\n resources: [],\n addedSkillIds: [],\n skippedSkillIds,\n autoUpdatedSkillIds,\n outdatedSkills: [],\n };\n }\n\n return finalizeSkillsInstall({\n projectRoot,\n packageName,\n ideIdent: options.ide ?? 'qoder',\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n onlyIds,\n skippedSkillIds,\n outdatedSkills,\n existing,\n existingConfig,\n });\n}\n\n// ─── partition helper (shared by init + add) ────────────────────────────────\n// Split a list of skill ids into three buckets based on `existing` lock state\n// vs `manifest` version. `onlyIds` (new) → drives `installSkills`;\n// `skippedSkillIds` (already at latest) and `outdatedSkills` (lock < manifest)\n// are surfaced to the CLI for messaging. Pre-ADR-0013 legacy installs whose\n// lock is missing fall through to `skippedSkillIds` (conservative — don't\n// nag a user we can't reliably version-check).\nfunction partitionByVersion(\n ids: readonly string[],\n manifest: SkillsPackageManifest,\n existing: ExistingState,\n): {\n onlyIds: string[];\n skippedSkillIds: string[];\n outdatedSkills: OutdatedSkillInfo[];\n} {\n const manifestById = new Map(manifest.skills.map((s) => [s.id, s]));\n const onlyIds: string[] = [];\n const skippedSkillIds: string[] = [];\n const outdatedSkills: OutdatedSkillInfo[] = [];\n for (const name of ids) {\n if (!existing.skillIds.has(name)) {\n onlyIds.push(name);\n continue;\n }\n const installedVer = existing.lock?.skills?.[name]?.version;\n const latestVer = manifestById.get(name)?.version;\n if (\n installedVer &&\n latestVer &&\n compareSemver(installedVer, latestVer) < 0\n ) {\n outdatedSkills.push({\n id: name,\n installed: installedVer,\n latest: latestVer,\n });\n } else {\n skippedSkillIds.push(name);\n }\n }\n return { onlyIds, skippedSkillIds, outdatedSkills };\n}\n\n// ─── semver helpers (light, no dep) ───────────────────────────────────────────\n// Only needed by `runSkillsAdd` to decide whether an already-installed skill is\n// truly outdated (installed < manifest). We deliberately avoid pulling in a\n// `semver` runtime dep; manifest versions are validated against\n// `^\\d+\\.\\d+\\.\\d+/` by the registry schema, so a numeric major.minor.patch\n// triple is sufficient. Pre-release / build metadata is ignored — if two\n// versions share the same triple they're considered equal here.\nfunction parseSemverTriple(v: string): [number, number, number] | null {\n const m = /^(\\d+)\\.(\\d+)\\.(\\d+)/.exec(v);\n if (!m) return null;\n return [Number(m[1]), Number(m[2]), Number(m[3])];\n}\n\n/** -1 if a < b, 0 if equal (or unparseable + identical strings), 1 if a > b. */\nfunction compareSemver(a: string, b: string): number {\n const pa = parseSemverTriple(a);\n const pb = parseSemverTriple(b);\n if (!pa || !pb) {\n if (a === b) return 0;\n return a < b ? -1 : 1;\n }\n for (let i = 0; i < 3; i++) {\n if (pa[i]! !== pb[i]!) return pa[i]! < pb[i]! ? -1 : 1;\n }\n return 0;\n}\n\n// ─── shared internals ─────────────────────────────────────────────────────────\n\ninterface ExistingState {\n installed: InstalledManifest | null;\n pkg:\n | {\n package: string;\n resources: InstalledResource[];\n }\n | undefined;\n lock: SkillsLock | null;\n skillIds: Set<string>;\n}\n\nasync function readExistingState(\n projectRoot: string,\n packageName: string,\n): Promise<ExistingState> {\n const installed = await readInstalledManifest(projectRoot);\n const pkg = installed?.installed.find((p) => p.package === packageName);\n const lock = await readSkillsLock(projectRoot);\n const skillIds = new Set<string>([\n ...Object.keys(lock?.skills ?? {}),\n // Legacy fallback: pre-ADR-0013 installs only had manifest.json. Derive\n // skill ids by stripping the trailing :source / :sub-file suffix.\n ...(pkg?.resources ?? []).map((r) => r.id.split(':')[0] ?? r.id),\n ]);\n return { installed, pkg, lock, skillIds };\n}\n\ninterface FinalizeArgs {\n projectRoot: string;\n packageName: string;\n ideIdent: string;\n manifest: SkillsPackageManifest;\n data: Parameters<typeof installSkills>[0]['data'];\n packageRoot: string;\n ides: SkillIde[];\n scope: SkillScope;\n onlyIds: string[];\n skippedSkillIds: string[];\n /** Optional — only populated by `runSkillsAdd`. `runSkillsInit` leaves empty. */\n outdatedSkills?: OutdatedSkillInfo[];\n existing: ExistingState;\n existingConfig: ProjectConfig | null;\n}\n\nasync function finalizeSkillsInstall(args: FinalizeArgs): Promise<{\n status: 'installed';\n packageName: string;\n version: string;\n ides: SkillIde[];\n scope: SkillScope;\n skillCount: number;\n fileCount: number;\n resources: InstalledResource[];\n addedSkillIds: string[];\n skippedSkillIds: string[];\n autoUpdatedSkillIds: string[];\n outdatedSkills: OutdatedSkillInfo[];\n}> {\n const {\n projectRoot,\n packageName,\n ideIdent,\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n onlyIds,\n skippedSkillIds,\n outdatedSkills,\n existing,\n existingConfig,\n } = args;\n\n const result = await installSkills({\n projectRoot,\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n onlyIds,\n });\n\n const config: ProjectConfig = existingConfig ?? {\n $schema: 'https://teamix-evo.dev/schema/config/v2.json',\n schemaVersion: 2,\n ide: ideIdent,\n packages: {},\n };\n config.packages.skills = {\n variant: FLAT_VARIANT,\n version: manifest.version,\n ides,\n scope,\n };\n await writeProjectConfig(projectRoot, config);\n\n const installedAt = new Date().toISOString();\n const installedManifest: InstalledManifest = existing.installed ?? {\n schemaVersion: 1,\n installed: [],\n };\n const idx = installedManifest.installed.findIndex(\n (p) => p.package === packageName,\n );\n const mergedResources = mergeInstalledResources(\n existing.pkg?.resources ?? [],\n result.resources,\n );\n const entry = {\n package: packageName,\n variant: FLAT_VARIANT,\n version: manifest.version,\n installedAt,\n resources: mergedResources,\n };\n if (idx >= 0) installedManifest.installed[idx] = entry;\n else installedManifest.installed.push(entry);\n await writeInstalledManifest(projectRoot, installedManifest);\n\n // Update skills source-mirror lock (per ADR 0013).\n const lock: SkillsLock = existing.lock ?? {\n schemaVersion: 1,\n skills: {},\n };\n for (const skillId of onlyIds) {\n const skillDef = manifest.skills.find((s) => s.id === skillId);\n if (!skillDef) continue;\n const mirroredTo = skillDef.ides.filter((i) => ides.includes(i));\n lock.skills[skillId] = {\n version: skillDef.version,\n from: packageName,\n installedAt,\n scope,\n mirroredTo,\n };\n }\n await writeSkillsLock(projectRoot, lock);\n\n // After the install completes, ensure the MCP launcher config exists so\n // Cursor / Claude Code / Cline pick up `@teamix-evo/mcp` automatically\n // (#BUG-103). Existing `.mcp.json` files are preserved.\n await ensureMcpJson(projectRoot);\n\n // Phase 5.G: sweep empty IDE skill dirs left over from prior installs\n // (e.g. a removed upstream skill). Best-effort — swallows errors.\n try {\n await pruneEmptyIdeSkillDirs({ projectRoot, ides, scope });\n } catch {\n // Cleanup is decoration; never a hard failure.\n }\n\n // Auto-upgrade outdated skills alongside the fresh install.\n let autoUpdatedSkillIds: string[] = [];\n if (outdatedSkills && outdatedSkills.length > 0) {\n autoUpdatedSkillIds = await autoUpgradeOutdatedSkills({\n projectRoot,\n packageName,\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n outdatedSkills,\n existing,\n existingConfig: existingConfig ?? config,\n });\n }\n\n return {\n status: 'installed',\n packageName,\n version: manifest.version,\n ides,\n scope,\n skillCount: onlyIds.length,\n fileCount: result.count,\n resources: result.resources,\n addedSkillIds: onlyIds,\n skippedSkillIds,\n autoUpdatedSkillIds,\n outdatedSkills: [],\n };\n}\n\nfunction mergeInstalledResources(\n existing: InstalledResource[],\n next: InstalledResource[],\n): InstalledResource[] {\n const map = new Map<string, InstalledResource>();\n const key = (r: InstalledResource): string =>\n `${r.id}|${r.ide ?? ''}|${r.scope ?? ''}`;\n for (const r of existing) map.set(key(r), r);\n for (const r of next) map.set(key(r), r);\n return [...map.values()];\n}\n\n// ─── auto-upgrade outdated skills ──────────────────────────────────────────────\n// When `skills add` detects already-installed skills whose locked version is\n// older than the manifest version, we auto-upgrade them in-place rather than\n// just surfacing a hint. This ensures the client-side AI always uses the latest\n// skill version available in the resolved `@latest` package.\n\ninterface AutoUpgradeArgs {\n projectRoot: string;\n packageName: string;\n manifest: SkillsPackageManifest;\n data: Parameters<typeof installSkills>[0]['data'];\n packageRoot: string;\n ides: SkillIde[];\n scope: SkillScope;\n outdatedSkills: OutdatedSkillInfo[];\n existing: ExistingState;\n existingConfig: ProjectConfig | null;\n}\n\nasync function autoUpgradeOutdatedSkills(\n args: AutoUpgradeArgs,\n): Promise<string[]> {\n const {\n projectRoot,\n packageName,\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n outdatedSkills,\n existing,\n } = args;\n\n const targetIds = outdatedSkills.map((o) => o.id);\n\n // Use the updateSkills flow which preserves managed regions.\n await updateSkills({\n projectRoot,\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n onlyIds: targetIds,\n });\n\n // Update the lock for auto-upgraded skills.\n const lock: SkillsLock = existing.lock ?? {\n schemaVersion: 1,\n skills: {},\n };\n const installedAt = new Date().toISOString();\n const manifestById = new Map(manifest.skills.map((s) => [s.id, s]));\n for (const id of targetIds) {\n const skillDef = manifestById.get(id);\n if (!skillDef) continue;\n const mirroredTo = skillDef.ides.filter((i) => ides.includes(i));\n lock.skills[id] = {\n version: skillDef.version,\n from: packageName,\n installedAt,\n scope,\n mirroredTo,\n };\n }\n await writeSkillsLock(projectRoot, lock);\n\n // Update installed manifest resources for upgraded skills.\n const installedManifest = (await readInstalledManifest(projectRoot)) ?? {\n schemaVersion: 1 as const,\n installed: [],\n };\n const idx = installedManifest.installed.findIndex(\n (p) => p.package === packageName,\n );\n if (idx >= 0) {\n installedManifest.installed[idx]!.version = manifest.version;\n installedManifest.installed[idx]!.installedAt = installedAt;\n }\n await writeInstalledManifest(projectRoot, installedManifest);\n\n logger.debug(\n `Auto-upgraded ${targetIds.length} outdated skill(s): ${targetIds.join(\n ', ',\n )}`,\n );\n\n return targetIds;\n}\n","import type {\n InstalledResource,\n SkillIde,\n SkillScope,\n SkillsLock,\n} from '@teamix-evo/registry';\nimport { loadSkillsData } from './skills-client.js';\nimport { updateSkills } from './skills-installer.js';\nimport {\n readProjectConfig,\n readInstalledManifest,\n writeProjectConfig,\n writeInstalledManifest,\n readSkillsLock,\n writeSkillsLock,\n} from './state.js';\nimport { logger } from '../utils/logger.js';\n\nconst DEFAULT_SKILLS_PACKAGE = '@teamix-evo/skills';\nconst FLAT_VARIANT = '_flat';\n\n// ─── runSkillsUpdate ──────────────────────────────────────────────────────────\n// ADR 0035: update only refreshes skills that are (a) recorded in the lock and\n// (b) match the current install scope. New skills added to the manifest are NOT\n// auto-installed by update — use `skills add <id>` for that. version-diff\n// short-circuits when nothing has actually changed.\n\nexport interface RunSkillsUpdateOptions {\n /** Absolute project (or global meta) root. */\n projectRoot: string;\n /**\n * Optional: limit the update to these skill ids. Falls back to \"every\n * skill in lock that matches the current install scope\".\n */\n names?: readonly string[];\n /** When true, plan only — no source rewrite, no mirror, no lock write. */\n dryRun?: boolean;\n /** Override the skills package name (defaults to `@teamix-evo/skills`). */\n packageName?: string;\n}\n\nexport interface UpdatePlanItem {\n id: string;\n current: string;\n next: string;\n /** Same as updateStrategy semantics, computed from the manifest. */\n strategy: 'frozen' | 'regenerable' | 'managed';\n /**\n * Predicted action for this skill source file in non-dryRun mode.\n * - `up-to-date` — version unchanged; safe to skip\n * - `version-bump` — version changed; will overwrite/merge per strategy\n */\n action: 'up-to-date' | 'version-bump';\n}\n\nexport type RunSkillsUpdateResult =\n | { status: 'no-skills' }\n | {\n status: 'no-changes';\n packageName: string;\n version: string;\n checkedSkillIds: string[];\n }\n | {\n status: 'dry-run';\n packageName: string;\n currentVersion: string;\n availableVersion: string;\n plan: UpdatePlanItem[];\n }\n | {\n status: 'updated';\n packageName: string;\n version: string;\n ides: SkillIde[];\n scope: SkillScope;\n updatedSkillIds: string[];\n skippedSkillIds: string[];\n summary: { overwritten: number; managed: number; skipped: number; created: number };\n resources: InstalledResource[];\n };\n\n/**\n * Programmatic equivalent of `teamix-evo skills update [names...] [--dry-run]`.\n *\n * Per ADR 0035:\n * 1. Range = `keys(lock.skills) ∩ scope-match ∩ (names if given)`\n * 2. version-diff short-circuit when every target id has the same lock\n * version as the manifest\n * 3. New skills (not in lock) are NEVER auto-installed by update\n * 4. lock writeback only touches `targetIds` — existing entries are preserved\n */\nexport async function runSkillsUpdate(\n options: RunSkillsUpdateOptions,\n): Promise<RunSkillsUpdateResult> {\n const { projectRoot, names: requestedNames, dryRun } = options;\n const packageName = options.packageName ?? DEFAULT_SKILLS_PACKAGE;\n\n const config = await readProjectConfig(projectRoot);\n const skillsCfg = config?.packages?.skills;\n if (!skillsCfg) {\n return { status: 'no-skills' };\n }\n\n const ides = (skillsCfg.ides ?? ['qoder', 'claude']) as SkillIde[];\n const scope = (skillsCfg.scope ?? 'project') as SkillScope;\n\n const existingLock = await readSkillsLock(projectRoot);\n if (!existingLock || Object.keys(existingLock.skills).length === 0) {\n return { status: 'no-skills' };\n }\n\n const { manifest, data, packageRoot } = await loadSkillsData(packageName);\n const manifestById = new Map(manifest.skills.map((s) => [s.id, s]));\n\n // Three-gate intersection: lock ∩ scope ∩ names.\n const lockIds = Object.keys(existingLock.skills);\n const requestedSet = requestedNames ? new Set(requestedNames) : null;\n if (requestedSet) {\n const unknown = requestedNames!.filter(\n (n) => !lockIds.includes(n) && !manifestById.has(n),\n );\n if (unknown.length > 0) {\n throw new Error(\n `Unknown skill id(s): ${unknown.join(\n ', ',\n )}. Available (installed): ${lockIds.join(', ') || '(none)'}.`,\n );\n }\n }\n\n const targetIds: string[] = [];\n const skippedSkillIds: string[] = [];\n for (const id of lockIds) {\n if (requestedSet && !requestedSet.has(id)) continue;\n const entry = manifestById.get(id);\n if (!entry) {\n // Lock has it, manifest no longer does (skill removed upstream).\n // Skip without error — uninstall is the user's call.\n logger.debug(\n `Skipping \"${id}\": no longer in upstream manifest. Use \\`skills uninstall ${id}\\` to remove.`,\n );\n skippedSkillIds.push(id);\n continue;\n }\n const effectiveScope = entry.scope ?? 'project';\n if (effectiveScope !== scope) {\n logger.debug(\n `Skipping \"${id}\" (scope=${effectiveScope}): current install scope is \"${scope}\".`,\n );\n skippedSkillIds.push(id);\n continue;\n }\n targetIds.push(id);\n }\n\n // version-diff short-circuit\n const allSame = targetIds.every((id) => {\n const lockVer = existingLock.skills[id]!.version;\n const manVer = manifestById.get(id)!.version;\n return lockVer === manVer;\n });\n if (targetIds.length > 0 && allSame && !dryRun) {\n return {\n status: 'no-changes',\n packageName,\n version: manifest.version,\n checkedSkillIds: targetIds,\n };\n }\n\n if (dryRun) {\n const plan: UpdatePlanItem[] = targetIds.map((id) => {\n const lockVer = existingLock.skills[id]!.version;\n const entry = manifestById.get(id)!;\n const sameVersion = lockVer === entry.version;\n return {\n id,\n current: lockVer,\n next: entry.version,\n strategy: entry.updateStrategy ?? 'managed',\n action: sameVersion ? 'up-to-date' : 'version-bump',\n };\n });\n return {\n status: 'dry-run',\n packageName,\n currentVersion: skillsCfg.version,\n availableVersion: manifest.version,\n plan,\n };\n }\n\n if (targetIds.length === 0) {\n return {\n status: 'updated',\n packageName,\n version: manifest.version,\n ides,\n scope,\n updatedSkillIds: [],\n skippedSkillIds,\n summary: { overwritten: 0, managed: 0, skipped: 0, created: 0 },\n resources: [],\n };\n }\n\n const result = await updateSkills({\n projectRoot,\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n onlyIds: targetIds,\n });\n\n // Update config.version (track the package-level version we last consumed).\n config!.packages.skills = {\n ...skillsCfg,\n version: manifest.version,\n };\n await writeProjectConfig(projectRoot, config!);\n\n // Update installed manifest (replace the package-level entry's resources).\n const installedManifest = (await readInstalledManifest(projectRoot)) ?? {\n schemaVersion: 1 as const,\n installed: [],\n };\n const idx = installedManifest.installed.findIndex(\n (p) => p.package === packageName,\n );\n const installedAt = new Date().toISOString();\n // Merge: keep resources from skills NOT in targetIds (preserve existing\n // entries for skills we didn't touch this round).\n const prior = idx >= 0 ? installedManifest.installed[idx]!.resources : [];\n const targetSet = new Set(targetIds);\n const preserved = prior.filter((r) => {\n const skillId = r.id.split(':')[0];\n return skillId ? !targetSet.has(skillId) : true;\n });\n const entry = {\n package: packageName,\n variant: FLAT_VARIANT,\n version: manifest.version,\n installedAt,\n resources: [...preserved, ...result.resources],\n };\n if (idx >= 0) installedManifest.installed[idx] = entry;\n else installedManifest.installed.push(entry);\n await writeInstalledManifest(projectRoot, installedManifest);\n\n // Update lock — only for targetIds, preserving other entries.\n const lock: SkillsLock = {\n schemaVersion: 1,\n skills: { ...existingLock.skills },\n };\n for (const id of targetIds) {\n const skillDef = manifestById.get(id);\n if (!skillDef) continue;\n const mirroredTo = skillDef.ides.filter((i) => ides.includes(i));\n lock.skills[id] = {\n version: skillDef.version,\n from: packageName,\n installedAt,\n scope,\n mirroredTo,\n };\n }\n await writeSkillsLock(projectRoot, lock);\n\n return {\n status: 'updated',\n packageName,\n version: manifest.version,\n ides,\n scope,\n updatedSkillIds: targetIds,\n skippedSkillIds,\n summary: result.summary,\n resources: result.resources,\n };\n}\n","import type { ProjectConfig, UiAliases } from '@teamix-evo/registry';\nimport { ensureMcpJson } from '../utils/mcp.js';\nimport {\n ensureTeamixDir,\n readProjectConfig,\n writeProjectConfig,\n} from './state.js';\n\nexport const DEFAULT_UI_ALIASES: UiAliases = {\n components: 'src/components/ui',\n hooks: 'src/hooks',\n utils: 'src/lib/utils',\n lib: 'src/lib',\n business: 'src/components/business',\n blocks: 'src/blocks',\n templates: 'src/templates',\n};\n\nexport const DEFAULT_UI_ICON_LIBRARY = 'lucide';\n\nexport interface RunUiInitOptions {\n /** Absolute project root directory. */\n projectRoot: string;\n /** Component aliases. Falls back to {@link DEFAULT_UI_ALIASES}. */\n aliases?: Partial<UiAliases>;\n /** Declared icon library (does not trigger code rewrite). Defaults to \"lucide\". */\n iconLibrary?: string;\n /** Whether the project uses TSX (true) or JSX (false). Defaults to true. */\n tsx?: boolean;\n /** Whether the project emits React Server Components markers. Defaults to false. */\n rsc?: boolean;\n /** IDE identifier written into config.ide when bootstrapping a fresh config (defaults to \"qoder\"). */\n ide?: string;\n}\n\nexport type RunUiInitResult =\n | {\n status: 'installed';\n aliases: UiAliases;\n iconLibrary: string;\n tsx: boolean;\n rsc: boolean;\n }\n | {\n status: 'already-initialized';\n };\n\n/**\n * Programmatic equivalent of `teamix-evo ui init`.\n *\n * Writes `packages.ui` into `.teamix-evo/config.json` only — no resource files\n * are touched. Use {@link runUiAdd} afterwards to install component sources.\n */\nexport async function runUiInit(\n options: RunUiInitOptions,\n): Promise<RunUiInitResult> {\n const { projectRoot } = options;\n const ideIdent = options.ide ?? 'qoder';\n\n await ensureTeamixDir(projectRoot);\n\n const existingConfig = await readProjectConfig(projectRoot);\n if (existingConfig?.packages?.ui) {\n return { status: 'already-initialized' };\n }\n\n const aliases: UiAliases = {\n components: options.aliases?.components ?? DEFAULT_UI_ALIASES.components,\n hooks: options.aliases?.hooks ?? DEFAULT_UI_ALIASES.hooks,\n utils: options.aliases?.utils ?? DEFAULT_UI_ALIASES.utils,\n lib: options.aliases?.lib ?? DEFAULT_UI_ALIASES.lib,\n business: options.aliases?.business ?? DEFAULT_UI_ALIASES.business,\n blocks: options.aliases?.blocks ?? DEFAULT_UI_ALIASES.blocks,\n templates: options.aliases?.templates ?? DEFAULT_UI_ALIASES.templates,\n };\n const iconLibrary = options.iconLibrary ?? DEFAULT_UI_ICON_LIBRARY;\n const tsx = options.tsx ?? true;\n const rsc = options.rsc ?? false;\n\n const config: ProjectConfig = existingConfig ?? {\n $schema: 'https://teamix-evo.dev/schema/config/v2.json',\n schemaVersion: 2,\n ide: ideIdent,\n packages: {},\n };\n config.packages.ui = {\n variant: '_flat',\n version: '0.0.0',\n aliases,\n iconLibrary,\n tsx,\n rsc,\n };\n await writeProjectConfig(projectRoot, config);\n\n // Ensure `.mcp.json` exists so editors auto-launch the MCP server even\n // when the user adopted teamix-evo without the create scaffold (#BUG-103).\n await ensureMcpJson(projectRoot);\n\n return {\n status: 'installed',\n aliases,\n iconLibrary,\n tsx,\n rsc,\n };\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport type { UiPackageManifest } from '@teamix-evo/registry';\nimport { loadUiPackageManifest } from '@teamix-evo/registry';\nimport { logger } from '../utils/logger.js';\n\nconst require = createRequire(import.meta.url);\n\nfunction resolvePackageRoot(packageName: string): string {\n const pkgJsonPath = require.resolve(`${packageName}/package.json`);\n return path.dirname(pkgJsonPath);\n}\n\n/**\n * Load the ui package manifest and optional shared `_data.json`.\n *\n * @param packageName - e.g. \"@teamix-evo/ui\"\n */\nexport async function loadUiData(packageName: string): Promise<{\n manifest: UiPackageManifest;\n data: Record<string, unknown>;\n packageRoot: string;\n}> {\n const packageRoot = resolvePackageRoot(packageName);\n\n logger.debug(`Resolved ui package root: ${packageRoot}`);\n\n const manifest = await loadUiPackageManifest(packageRoot);\n\n let data: Record<string, unknown> = {};\n const dataPath = path.join(packageRoot, '_data.json');\n try {\n const raw = await fs.readFile(dataPath, 'utf-8');\n data = JSON.parse(raw) as Record<string, unknown>;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw err;\n }\n logger.debug(`No _data.json found at ${dataPath}, using empty data`);\n }\n\n return { manifest, data, packageRoot };\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport type {\n UiEntry,\n UiPackageManifest,\n UiAliases,\n InstalledResource,\n} from '@teamix-evo/registry';\nimport { resolveUiEntryOrder } from '@teamix-evo/registry';\nimport { backupFile, writeFileSafe, fileExists } from '../utils/fs.js';\nimport { computeHash } from '../utils/hash.js';\nimport { rewriteImports } from '../utils/transform-imports.js';\nimport { logger } from '../utils/logger.js';\nimport { getErrorMessage } from '../utils/error.js';\n\nexport interface UiInstallOptions {\n /** Project root directory */\n projectRoot: string;\n /** UI package manifest */\n manifest: UiPackageManifest;\n /** Absolute ui package root (used to resolve entry source paths) */\n packageRoot: string;\n /**\n * Optional per-entry package root override. When set, entries in the map\n * resolve their `file.source` against the mapped root instead of `packageRoot`.\n * Used by variant-aware packages (biz-ui / templates) that pull in\n * @teamix-evo/ui transitive deps — each entry resolves from its source package.\n */\n entryPackageRoot?: Map<string, string>;\n /** Aliases configured in `packages.ui.aliases` */\n aliases: UiAliases;\n /** Entry ids the user explicitly requested to add */\n requested: string[];\n /** When true, skip writing entries whose target file already exists (frozen-on-add). */\n skipExisting?: boolean;\n /** When false, preserve directory structure in import paths (skip flattenRestPath). Defaults to true. */\n flatten?: boolean;\n}\n\nexport interface UiInstallResult {\n /** Ordered list of entry ids that were processed (deps + requested) */\n orderedIds: string[];\n /** Per-file install records (for InstalledManifest) */\n resources: InstalledResource[];\n /** Aggregate npm dependencies across the installed entries */\n npmDependencies: Record<string, string>;\n /** Number of files written */\n written: number;\n /** Number of files skipped because they already exist (frozen) */\n skipped: number;\n}\n\n/**\n * Install the requested ui entries (transitively resolving registryDependencies).\n * For frozen entries that already exist on disk, the write is skipped — shadcn-style.\n */\nexport async function installUiEntries(\n options: UiInstallOptions,\n): Promise<UiInstallResult> {\n const {\n projectRoot,\n manifest,\n packageRoot,\n entryPackageRoot,\n aliases,\n requested,\n skipExisting = true,\n flatten = true,\n } = options;\n\n const orderedIds = resolveUiEntryOrder(manifest.entries, requested);\n const idToEntry = new Map(manifest.entries.map((e) => [e.id, e]));\n\n const resources: InstalledResource[] = [];\n const npmDeps: Record<string, string> = {};\n let written = 0;\n let skipped = 0;\n\n for (const id of orderedIds) {\n const entry = idToEntry.get(id);\n if (!entry) continue;\n\n // Aggregate npm deps regardless of whether files were written — the user\n // may have manually deleted node_modules; we want to surface the full set.\n if (entry.dependencies) {\n for (const [name, range] of Object.entries(entry.dependencies)) {\n npmDeps[name] = range;\n }\n }\n\n for (const file of entry.files) {\n const targetAbs = resolveTargetPath(projectRoot, aliases, entry, file);\n const exists = await fileExists(targetAbs);\n\n if (\n exists &&\n skipExisting &&\n (entry.updateStrategy ?? 'frozen') === 'frozen'\n ) {\n logger.info(` skip (frozen, exists): ${rel(projectRoot, targetAbs)}`);\n skipped++;\n continue;\n }\n\n const rootForEntry = entryPackageRoot?.get(entry.id) ?? packageRoot;\n const sourceAbs = path.resolve(rootForEntry, file.source);\n const raw = await fs.readFile(sourceAbs, 'utf-8');\n const transformed = rewriteImports(raw, aliases, { flatten });\n // Phase 1.A2: any existing user file we are about to overwrite must be\n // backed up under .teamix-evo/.backups/. This applies to:\n // - regenerable entries on re-install,\n // - frozen entries when caller passes overwrite=true (init conflict\n // decision \"shadcn-source: overwrite\").\n if (exists) {\n await backupFile(targetAbs, projectRoot);\n }\n await writeFileSafe(targetAbs, transformed);\n written++;\n logger.info(` write: ${rel(projectRoot, targetAbs)}`);\n\n resources.push({\n id: `${entry.id}:${file.targetName}`,\n target: targetAbs,\n hash: computeHash(transformed),\n strategy: entry.updateStrategy ?? 'frozen',\n });\n }\n }\n\n return {\n orderedIds,\n resources,\n npmDependencies: npmDeps,\n written,\n skipped,\n };\n}\n\nfunction resolveTargetPath(\n projectRoot: string,\n aliases: UiAliases,\n entry: UiEntry,\n file: { targetAlias: string; targetName: string },\n): string {\n const aliasDir = aliases[file.targetAlias as keyof UiAliases];\n if (!aliasDir) {\n throw new Error(\n `Entry \"${entry.id}\" requires alias \"${file.targetAlias}\" but it is not configured.`,\n );\n }\n return path.join(projectRoot, aliasDir, file.targetName);\n}\n\nfunction rel(projectRoot: string, abs: string): string {\n return path.relative(projectRoot, abs);\n}\n\n/**\n * Remove all installed ui resource files and prune empty parent directories.\n */\nexport async function removeUiFiles(\n records: InstalledResource[],\n): Promise<string[]> {\n const removed: string[] = [];\n for (const r of records) {\n try {\n await fs.unlink(r.target);\n removed.push(r.target);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n logger.warn(`Failed to remove ${r.target}: ${getErrorMessage(err)}`);\n }\n }\n }\n const parents = new Set(records.map((r) => path.dirname(r.target)));\n for (const dir of parents) {\n try {\n const entries = await fs.readdir(dir);\n if (entries.length === 0) await fs.rmdir(dir);\n } catch {\n /* ignore */\n }\n }\n return removed;\n}\n","import type { UiAliases } from '@teamix-evo/registry';\n\n/**\n * Map between the ui package's \"developer-time\" import roots and the user's\n * configured aliases. The keys are the source roots used inside ui source\n * files (e.g. `@/utils/cn` references `src/utils/`).\n */\nconst SOURCE_ROOT_TO_ALIAS_KEY: Record<string, keyof UiAliases> = {\n components: 'components',\n hooks: 'hooks',\n utils: 'utils',\n lib: 'lib',\n blocks: 'blocks',\n};\n\n/**\n * Rewrite import specifiers in a UI source file so that the developer-time\n * placeholders (e.g. `@/utils/cn`) resolve to the user's configured aliases\n * (e.g. `@/lib/utils/cn` when `aliases.utils === \"src/lib/utils\"`).\n *\n * Matches both static imports and dynamic imports of the form `@/<root>/<rest>`.\n * Bare `@/` (no segment) and unknown segments are left untouched.\n *\n * The rewrite uses each user alias verbatim. If the user alias begins with\n * `src/`, that prefix is stripped because TypeScript-style `@/*` → `src/*`\n * mappings expect paths relative to `src`.\n */\nexport function rewriteImports(\n source: string,\n aliases: UiAliases,\n opts?: { flatten?: boolean },\n): string {\n const shouldFlatten = opts?.flatten !== false;\n return source.replace(\n /(['\"])@\\/([a-z][a-z0-9-]*)(\\/[^'\"]*)?\\1/g,\n (full, quote: string, root: string, rest: string | undefined) => {\n const aliasKey = SOURCE_ROOT_TO_ALIAS_KEY[root];\n if (!aliasKey) return full;\n const alias = aliases[aliasKey];\n const normalized = aliasToImportPath(alias);\n const resolvedRest = shouldFlatten ? flattenRestPath(rest) : (rest ?? '');\n return `${quote}${normalized}${resolvedRest}${quote}`;\n },\n );\n}\n\n/**\n * Flatten a source-tree relative path for the installed (flat) layout.\n *\n * In the UI source tree, files live in per-entry directories:\n * `@/components/skeleton/skeleton` → rest = `/skeleton/skeleton`\n * After install, they are placed flat in the alias directory:\n * `@/components/ui/skeleton` → rest = `/skeleton`\n *\n * When rest has exactly two path segments (`/dir/file`), the first segment\n * (the entry directory) is stripped, leaving only the file reference.\n * Single-segment paths (e.g. `/cn`) pass through unchanged.\n */\nfunction flattenRestPath(rest: string | undefined): string {\n if (!rest) return '';\n // Split: \"/skeleton/skeleton\" → [\"\", \"skeleton\", \"skeleton\"]\n const segments = rest.split('/');\n if (segments.length === 3) {\n // Two real segments: /dir/file → /file\n return `/${segments[2]}`;\n }\n return rest;\n}\n\n/**\n * Convert an alias path (relative to the project root, e.g. `src/lib/utils`)\n * into an import-path prefix (`@/lib/utils`).\n *\n * Strips a leading `src/` so the path matches the convention of a `@/*` →\n * `src/*` tsconfig mapping. If the alias has a different prefix (for projects\n * that don't put code under `src/`), we keep it verbatim with `@/` prepended.\n */\nfunction aliasToImportPath(alias: string): string {\n const trimmed = alias.replace(/^\\.\\//, '').replace(/\\/$/, '');\n if (trimmed.startsWith('src/')) {\n return `@/${trimmed.slice('src/'.length)}`;\n }\n return `@/${trimmed}`;\n}\n","import type {\n InstalledManifest,\n InstalledResource,\n} from '@teamix-evo/registry';\nimport { loadUiData } from './ui-client.js';\nimport { installUiEntries } from './ui-installer.js';\nimport {\n readProjectConfig,\n writeProjectConfig,\n readInstalledManifest,\n writeInstalledManifest,\n} from './state.js';\n\nconst DEFAULT_UI_PACKAGE = '@teamix-evo/ui';\n\nexport interface RunUiAddOptions {\n /** Absolute project root directory. */\n projectRoot: string;\n /** Entry ids to install (registry dependencies are resolved transitively). */\n ids: string[];\n /** When true, overwrite frozen entries that already exist on disk. */\n overwrite?: boolean;\n /** Override the ui package name (defaults to \"@teamix-evo/ui\"). */\n packageName?: string;\n /**\n * When true, allow installing entries that live in `manifest.deprecatedEntries`\n * (ADR 0028). Default: false — deprecated ids are treated as unknown and the\n * call errors with a hint pointing the user at the active replacement.\n */\n includeDeprecated?: boolean;\n}\n\nexport interface RunUiAddResult {\n packageName: string;\n /** Registered ids in install order (deps + requested). */\n orderedIds: string[];\n /** Number of files written. */\n written: number;\n /** Number of files skipped due to frozen + exists. */\n skipped: number;\n /** Aggregate npm dependencies of the installed entries. */\n npmDependencies: Record<string, string>;\n /** Per-file install records merged into the installed manifest. */\n resources: InstalledResource[];\n}\n\n/**\n * Programmatic equivalent of `teamix-evo ui add <ids...>`.\n *\n * Requires `packages.ui` to already exist in `.teamix-evo/config.json`\n * (i.e. {@link runUiInit} was called earlier).\n */\nexport async function runUiAdd(\n options: RunUiAddOptions,\n): Promise<RunUiAddResult> {\n const { projectRoot, ids, overwrite, includeDeprecated } = options;\n const packageName = options.packageName ?? DEFAULT_UI_PACKAGE;\n\n if (ids.length === 0) {\n throw new Error('At least one entry id must be provided.');\n }\n\n const config = await readProjectConfig(projectRoot);\n const uiCfg = config?.packages?.ui;\n if (!config || !uiCfg?.aliases) {\n throw new Error(\n 'UI not initialized. Run `runUiInit` (or `teamix-evo ui init`) first.',\n );\n }\n\n const { manifest, packageRoot } = await loadUiData(packageName);\n\n // Per ADR 0028: deprecated entries are archived in `deprecatedEntries`\n // and not exposed by default. When the caller opts in, we splice them\n // back into the active list so dependency resolution and install work\n // exactly as for active entries.\n const archived = manifest.deprecatedEntries ?? [];\n const archivedIds = new Set(archived.map((e) => e.id));\n const activeIds = new Set(manifest.entries.map((e) => e.id));\n\n const requestedDeprecated = ids.filter((id) => archivedIds.has(id));\n if (requestedDeprecated.length > 0 && !includeDeprecated) {\n const list = requestedDeprecated.map((s) => `\"${s}\"`).join(', ');\n throw new Error(\n `Refusing to install deprecated entr${\n requestedDeprecated.length === 1 ? 'y' : 'ies'\n } ${list}. ` +\n 'These entries are archived and not part of the active distribution (ADR 0028). ' +\n 'Pass `--include-deprecated` to override (e.g. for migration tooling).',\n );\n }\n\n const effectiveManifest = includeDeprecated\n ? { ...manifest, entries: [...manifest.entries, ...archived] }\n : manifest;\n\n const knownIds = new Set([\n ...activeIds,\n ...(includeDeprecated ? archivedIds : []),\n ]);\n const unknown = ids.filter((id) => !knownIds.has(id));\n if (unknown.length > 0) {\n throw new Error(\n `Unknown entry id(s): ${unknown\n .map((s) => `\"${s}\"`)\n .join(', ')}. Run \\`teamix-evo ui list\\` to see options.`,\n );\n }\n\n const result = await installUiEntries({\n projectRoot,\n manifest: effectiveManifest,\n packageRoot,\n aliases: uiCfg.aliases,\n requested: ids,\n skipExisting: !overwrite,\n });\n\n const installed: InstalledManifest = (await readInstalledManifest(\n projectRoot,\n )) ?? { schemaVersion: 1, installed: [] };\n\n const idx = installed.installed.findIndex((p) => p.package === packageName);\n const prior = idx >= 0 ? installed.installed[idx] : null;\n const mergedResources = mergeResources(\n prior?.resources ?? [],\n result.resources,\n );\n\n const entry = {\n package: packageName,\n variant: '_flat',\n version: manifest.version,\n installedAt: new Date().toISOString(),\n resources: mergedResources,\n };\n if (idx >= 0) installed.installed[idx] = entry;\n else installed.installed.push(entry);\n await writeInstalledManifest(projectRoot, installed);\n\n if (uiCfg.version !== manifest.version) {\n uiCfg.version = manifest.version;\n await writeProjectConfig(projectRoot, config);\n }\n\n return {\n packageName,\n orderedIds: result.orderedIds,\n written: result.written,\n skipped: result.skipped,\n npmDependencies: result.npmDependencies,\n resources: result.resources,\n };\n}\n\nfunction mergeResources<T extends { id: string }>(prior: T[], next: T[]): T[] {\n const merged = new Map<string, T>();\n for (const r of prior) merged.set(r.id, r);\n for (const r of next) merged.set(r.id, r);\n return Array.from(merged.values());\n}\n","import type { UiEntry } from '@teamix-evo/registry';\nimport { loadUiData } from './ui-client.js';\nimport { readInstalledManifest } from './state.js';\n\nconst DEFAULT_UI_PACKAGE = '@teamix-evo/ui';\n\nexport interface RunUiListOptions {\n /** Absolute project root directory. */\n projectRoot: string;\n /** When true, only return entries that are already installed. */\n installedOnly?: boolean;\n /** Override the ui package name (defaults to \"@teamix-evo/ui\"). */\n packageName?: string;\n /**\n * When true, also include archived entries from `manifest.deprecatedEntries`\n * (ADR 0028). They are flagged with `deprecated: true` in the result.\n */\n includeDeprecated?: boolean;\n}\n\nexport interface UiEntryListItem {\n id: string;\n type: UiEntry['type'];\n description: string;\n installed: boolean;\n /** True when the entry comes from `manifest.deprecatedEntries` (ADR 0028). */\n deprecated: boolean;\n}\n\nexport interface RunUiListResult {\n packageName: string;\n /** Total number of entries declared by the package manifest. */\n total: number;\n /** Number of installed entries (based on the project's installed manifest). */\n installedCount: number;\n /** Filtered + decorated entries. */\n entries: UiEntryListItem[];\n}\n\n/**\n * Programmatic equivalent of `teamix-evo ui list`.\n *\n * Returns structured data; the CLI command formats it for terminal output.\n */\nexport async function runUiList(\n options: RunUiListOptions,\n): Promise<RunUiListResult> {\n const { projectRoot, installedOnly, includeDeprecated } = options;\n const packageName = options.packageName ?? DEFAULT_UI_PACKAGE;\n\n const { manifest } = await loadUiData(packageName);\n const installedManifest = await readInstalledManifest(projectRoot);\n\n const installedIds = new Set<string>();\n const uiPkg = installedManifest?.installed.find(\n (p) => p.package === packageName,\n );\n for (const r of uiPkg?.resources ?? []) {\n const colon = r.id.indexOf(':');\n installedIds.add(colon >= 0 ? r.id.slice(0, colon) : r.id);\n }\n\n const archived = manifest.deprecatedEntries ?? [];\n const pool = includeDeprecated\n ? [\n ...manifest.entries.map((e) => ({ entry: e, deprecated: false })),\n ...archived.map((e) => ({ entry: e, deprecated: true })),\n ]\n : manifest.entries.map((e) => ({ entry: e, deprecated: false }));\n\n const entries: UiEntryListItem[] = pool\n .filter(({ entry }) => !installedOnly || installedIds.has(entry.id))\n .map(({ entry, deprecated }) => ({\n id: entry.id,\n type: entry.type,\n description: entry.description,\n installed: installedIds.has(entry.id),\n deprecated,\n }));\n\n return {\n packageName,\n total: manifest.entries.length + (includeDeprecated ? archived.length : 0),\n installedCount: installedIds.size,\n entries,\n };\n}\n","/**\n * Programmatic install for variant-aware UI packages — biz-ui & templates.\n *\n * Per [ADR 0014](../../../../docs/adr/0014-ui-biz-ui-templates-tier.md), these\n * two packages share the variant-aware shape: top-level catalog + per-variant\n * manifest. The install logic is the same as `runUiAdd` (registry dependency\n * resolution + frozen-on-add + import rewrite) — only differences are:\n *\n * 1. The package source is `<pkg>/variants/<variant>/` rather than `<pkg>/`\n * 2. A `--variant` selector picks which variant to install from\n * 3. The installed manifest entry records `variant: \"<name>\"` rather than\n * `_flat`\n *\n * This module exposes a single shared implementation parametrized by\n * `packageName` (`@teamix-evo/biz-ui` or `@teamix-evo/templates`) and is\n * surfaced via `runBizUiAdd` / `runTemplatesAdd` thin wrappers.\n */\nimport * as path from 'node:path';\nimport { createRequire } from 'node:module';\nimport type {\n InstalledManifest,\n InstalledResource,\n UiEntry,\n UiPackageManifest,\n VariantUiPackageName,\n} from '@teamix-evo/registry';\nimport {\n loadUiPackageManifest,\n loadVariantUiPackageCatalog,\n loadVariantUiPackageManifest,\n} from '@teamix-evo/registry';\nimport { installUiEntries } from './ui-installer.js';\nimport {\n readProjectConfig,\n readInstalledManifest,\n writeInstalledManifest,\n} from './state.js';\n\nconst require = createRequire(import.meta.url);\n\nfunction resolvePackageRoot(packageName: string): string {\n const pkgJsonPath = require.resolve(`${packageName}/package.json`);\n return path.dirname(pkgJsonPath);\n}\n\nexport interface RunVariantUiAddOptions {\n /** Absolute project root directory. */\n projectRoot: string;\n /** Variant id (e.g. `\"opentrek\"`). */\n variant: string;\n /** Entry ids to install. */\n ids: string[];\n /** When true, overwrite frozen entries that already exist on disk. */\n overwrite?: boolean;\n /** Override the package name. */\n packageName?: string;\n /**\n * Override resolution of the package root. When set, skips\n * `require.resolve(\"<packageName>/package.json\")`.\n */\n packageRoot?: string;\n}\n\nexport interface RunVariantUiAddResult {\n packageName: string;\n variant: string;\n orderedIds: string[];\n written: number;\n skipped: number;\n npmDependencies: Record<string, string>;\n resources: InstalledResource[];\n}\n\nasync function runVariantUiAdd(\n packageName: VariantUiPackageName,\n options: RunVariantUiAddOptions,\n): Promise<RunVariantUiAddResult> {\n const { projectRoot, variant, ids, overwrite } = options;\n const fullPackageName = options.packageName ?? `@teamix-evo/${packageName}`;\n\n if (ids.length === 0) {\n throw new Error('At least one entry id must be provided.');\n }\n\n const config = await readProjectConfig(projectRoot);\n const uiCfg = config?.packages?.ui;\n if (!config || !uiCfg?.aliases) {\n throw new Error(\n `UI not initialized. Run \\`teamix-evo ui init\\` first — \\`${packageName} add\\` writes into the same alias map (business / templates).`,\n );\n }\n\n const packageRoot =\n options.packageRoot ?? resolvePackageRoot(fullPackageName);\n\n // Validate that this variant exists in the catalog (clear error if not).\n const catalog = await loadVariantUiPackageCatalog(packageRoot);\n if (!catalog.variants.some((v) => v.name === variant)) {\n const known = catalog.variants.map((v) => v.name).join(', ');\n throw new Error(\n `Variant \"${variant}\" not found in ${fullPackageName}. Known variants: ${known}. Hint: \\`teamix-evo ${packageName} list-variants\\` shows all.`,\n );\n }\n\n // Load the per-variant manifest from packages/<pkg>/variants/<variant>/.\n const variantDir = path.join(packageRoot, 'variants', variant);\n const variantManifest = await loadVariantUiPackageManifest(variantDir);\n\n // Validate requested ids (must be defined in this variant package, not in ui)\n const knownIds = new Set(variantManifest.entries.map((e) => e.id));\n const unknown = ids.filter((id) => !knownIds.has(id));\n if (unknown.length > 0) {\n throw new Error(\n `Unknown entry id(s) in ${packageName}#${variant}: ${unknown\n .map((s) => `\"${s}\"`)\n .join(', ')}. Run \\`teamix-evo ${packageName} list-variants\\` to see this package's variants, or \\`teamix-evo ${packageName} list --variant ${variant}\\` for its entries.`,\n );\n }\n\n // Cross-package dependency resolution (fixes #22).\n // variant-aware entries (biz-ui / templates) reference @teamix-evo/ui entries\n // by id via `registryDependencies` (e.g. tenant-switcher → popover/button/cn).\n // Merge ui package's entries into the dep graph so the resolver can find\n // them. The installer's skipExisting=frozen guard means already-installed ui\n // entries are not rewritten.\n const uiPackageRoot = resolvePackageRoot('@teamix-evo/ui');\n const uiManifest = await loadUiPackageManifest(uiPackageRoot);\n\n // Resolve each entry's true package root for source file paths. Entries from\n // the variant package live under variantDir; entries from @teamix-evo/ui live\n // under uiPackageRoot.\n const entryPackageRoot = new Map<string, string>();\n const mergedEntries: UiEntry[] = [];\n for (const e of variantManifest.entries) {\n entryPackageRoot.set(e.id, variantDir);\n mergedEntries.push(e);\n }\n for (const e of uiManifest.entries) {\n // variant entry id wins over ui entry of same id (rare/illegal but safe).\n if (entryPackageRoot.has(e.id)) continue;\n entryPackageRoot.set(e.id, uiPackageRoot);\n mergedEntries.push(e);\n }\n\n const adaptedManifest: UiPackageManifest = {\n schemaVersion: 1,\n package: 'ui',\n version: variantManifest.version,\n engines: variantManifest.engines,\n entries: mergedEntries,\n };\n\n const result = await installUiEntries({\n projectRoot,\n manifest: adaptedManifest,\n packageRoot: variantDir, // default for variant entries\n entryPackageRoot, // ui entries resolve from uiPackageRoot\n aliases: uiCfg.aliases,\n requested: ids,\n skipExisting: !overwrite,\n });\n\n // Update installed manifest, keyed by (package, variant). Multiple variants\n // of the same package can co-exist (rare but legal).\n const installed: InstalledManifest = (await readInstalledManifest(\n projectRoot,\n )) ?? { schemaVersion: 1, installed: [] };\n\n const idx = installed.installed.findIndex(\n (p) => p.package === fullPackageName && p.variant === variant,\n );\n const prior = idx >= 0 ? installed.installed[idx] : null;\n const mergedResources = mergeResources(\n prior?.resources ?? [],\n result.resources,\n );\n\n const entry = {\n package: fullPackageName,\n variant,\n version: variantManifest.version,\n installedAt: new Date().toISOString(),\n resources: mergedResources,\n };\n if (idx >= 0) installed.installed[idx] = entry;\n else installed.installed.push(entry);\n await writeInstalledManifest(projectRoot, installed);\n\n return {\n packageName: fullPackageName,\n variant,\n orderedIds: result.orderedIds,\n written: result.written,\n skipped: result.skipped,\n npmDependencies: result.npmDependencies,\n resources: result.resources,\n };\n}\n\nfunction mergeResources<T extends { id: string }>(prior: T[], next: T[]): T[] {\n const merged = new Map<string, T>();\n for (const r of prior) merged.set(r.id, r);\n for (const r of next) merged.set(r.id, r);\n return Array.from(merged.values());\n}\n\n/** `teamix-evo biz-ui add <ids...> --variant <name>`. */\nexport async function runBizUiAdd(\n options: RunVariantUiAddOptions,\n): Promise<RunVariantUiAddResult> {\n return runVariantUiAdd('biz-ui', options);\n}\n\n/** `teamix-evo templates add <ids...> --variant <name>`. */\nexport async function runTemplatesAdd(\n options: RunVariantUiAddOptions,\n): Promise<RunVariantUiAddResult> {\n return runVariantUiAdd('templates', options);\n}\n\n// ─── List variants ───────────────────────────────────────────────────────────\n\nexport interface ListVariantUiResult {\n packageName: string;\n variants: Array<{\n name: string;\n displayName: string;\n version: string;\n description?: string;\n }>;\n}\n\nasync function listVariantUi(\n packageName: VariantUiPackageName,\n packageRoot?: string,\n): Promise<ListVariantUiResult> {\n const fullPackageName = `@teamix-evo/${packageName}`;\n const root = packageRoot ?? resolvePackageRoot(fullPackageName);\n const catalog = await loadVariantUiPackageCatalog(root);\n return {\n packageName: fullPackageName,\n variants: catalog.variants.map((v) => ({\n name: v.name,\n displayName: v.displayName,\n version: v.version,\n description: v.description,\n })),\n };\n}\n\nexport async function listBizUiVariants(\n packageRoot?: string,\n): Promise<ListVariantUiResult> {\n return listVariantUi('biz-ui', packageRoot);\n}\n\nexport async function listTemplatesVariants(\n packageRoot?: string,\n): Promise<ListVariantUiResult> {\n return listVariantUi('templates', packageRoot);\n}\n\n// ─── List entries inside a variant ───────────────────────────────────────────\n\nexport interface ListVariantUiEntriesResult {\n packageName: string;\n variant: string;\n entries: Array<{\n id: string;\n name: string;\n type: string;\n description?: string;\n registryDependencies: string[];\n }>;\n}\n\nasync function listVariantUiEntries(\n packageName: VariantUiPackageName,\n variant: string,\n packageRoot?: string,\n): Promise<ListVariantUiEntriesResult> {\n const fullPackageName = `@teamix-evo/${packageName}`;\n const root = packageRoot ?? resolvePackageRoot(fullPackageName);\n const catalog = await loadVariantUiPackageCatalog(root);\n if (!catalog.variants.some((v) => v.name === variant)) {\n const known = catalog.variants.map((v) => v.name).join(', ');\n throw new Error(\n `Variant \"${variant}\" not found in ${fullPackageName}. Known: ${known}.`,\n );\n }\n const variantDir = path.join(root, 'variants', variant);\n const variantManifest = await loadVariantUiPackageManifest(variantDir);\n return {\n packageName: fullPackageName,\n variant,\n entries: variantManifest.entries.map((e) => ({\n id: e.id,\n name: e.name,\n type: e.type,\n description: e.description,\n registryDependencies: e.registryDependencies ?? [],\n })),\n };\n}\n\nexport async function listBizUiEntries(\n variant: string,\n packageRoot?: string,\n): Promise<ListVariantUiEntriesResult> {\n return listVariantUiEntries('biz-ui', variant, packageRoot);\n}\n\nexport async function listTemplatesEntries(\n variant: string,\n packageRoot?: string,\n): Promise<ListVariantUiEntriesResult> {\n return listVariantUiEntries('templates', variant, packageRoot);\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs';\nimport { execa } from 'execa';\nimport {\n backupFile,\n fileExists,\n readFileOrNull,\n writeFileSafe,\n} from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\n// ─── Config file content ─────────────────────────────────────────────────────\n\nconst ESLINT_CONFIG_CONTENT = `/**\n * teamix-evo consumer ESLint preset — 9 token-discipline rules.\n * - Repo-wide: no-color-literal / no-arbitrary-tw-value / no-raw-color-scale /\n * no-large-radius / prefer-gap-over-space / no-manual-dark-classnames /\n * dialog-must-have-title (all error)\n * - src/components/ui/** only: no-relative-ui-import / icon-from-lucide (error)\n *\n * See ADR 0008 / docs/principles.md §P4.\n */\nimport consumerPreset from '@teamix-evo/eslint-config/presets/consumer';\n\nexport default [...consumerPreset];\n`;\n\nconst STYLELINT_CONFIG_CONTENT = `/** @type {import('stylelint').Config} */\nmodule.exports = {\n extends: ['@teamix-evo/stylelint-config/presets/consumer'],\n // Stylelint does NOT inherit ignoreFiles from extended configs — must declare here.\n ignoreFiles: [\n '**/tokens.theme.css',\n '**/tokens.overrides.css',\n '**/dist/**',\n '**/build/**',\n '**/node_modules/**',\n ],\n};\n`;\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/**\n * Phase 3.E lint conflict strategies (mirrors `init-conflicts.ts`).\n *\n * `merge` and `backup-overwrite` both back up the existing user file before\n * writing the teamix-evo template; `merge` additionally surfaces an AI-assist\n * hint so the manage / code skill can guide the user through merging custom\n * rules. `skip` keeps the user's file as-is and emits no template.\n */\nexport type LintConflictStrategy =\n | 'merge'\n | 'backup-overwrite'\n | 'skip'\n | 'overwrite';\n\nexport interface RunLintInitOptions {\n /** Absolute project root directory. */\n projectRoot: string;\n /**\n * Skip npm dependency installation. Used by the create scaffold where\n * dependencies are already declared in the template package.json and\n * installed in a later batch step.\n */\n skipInstall?: boolean;\n /**\n * Phase 3.E: strategy for handling existing ESLint config files.\n * Defaults to `'overwrite'` (legacy behaviour); the `init` orchestrator\n * passes the wizard-resolved value when consumer files are detected.\n */\n eslintStrategy?: LintConflictStrategy;\n /**\n * Phase 3.E: strategy for handling existing Stylelint config files.\n */\n stylelintStrategy?: LintConflictStrategy;\n /**\n * Phase 3.E: paths of existing ESLint configs (relative to projectRoot)\n * to back up. Empty when no consumer config was detected.\n */\n eslintExistingPaths?: string[];\n /**\n * Phase 3.E: paths of existing Stylelint configs (relative to projectRoot).\n */\n stylelintExistingPaths?: string[];\n}\n\nexport type RunLintInitResult =\n | {\n status: 'installed';\n eslint: boolean;\n stylelint: boolean;\n /** True when the user had a custom config and asked for AI-assisted merge. */\n eslintMergeRequested?: boolean;\n stylelintMergeRequested?: boolean;\n /** True when the strategy asked us to keep the user file untouched. */\n eslintSkipped?: boolean;\n stylelintSkipped?: boolean;\n /**\n * True when `package.json` was actually patched (lint / lint:css\n * scripts inserted). Powers the project-init change ledger so the\n * CLI does not report a phantom write when both scripts already\n * existed.\n */\n packageJsonPatched?: boolean;\n /**\n * True when the consumer's existing stylelint config was kept (skip /\n * merge) and does not extend a teamix-evo preset — token definition\n * files may trigger false-positive lint errors without `ignoreFiles`.\n */\n stylelintIgnoreFilesWarning?: boolean;\n }\n | {\n status: 'already-initialized';\n };\n\n// ─── Lint dependencies ───────────────────────────────────────────────────────\n\nconst ESLINT_DEPS = [\n '@teamix-evo/eslint-config',\n 'eslint',\n '@typescript-eslint/parser',\n];\n\nconst STYLELINT_DEPS = ['@teamix-evo/stylelint-config', 'stylelint'];\n\n// ─── Implementation ──────────────────────────────────────────────────────────\n\n/**\n * Programmatic equivalent of `teamix-evo lint init`.\n *\n * Writes lint configuration files and optionally installs dependencies.\n * Idempotent: if both config files already exist, returns `already-initialized`.\n */\nexport async function runLintInit(\n options: RunLintInitOptions,\n): Promise<RunLintInitResult> {\n const {\n projectRoot,\n skipInstall,\n eslintStrategy = 'overwrite',\n stylelintStrategy = 'overwrite',\n eslintExistingPaths = [],\n stylelintExistingPaths = [],\n } = options;\n\n const eslintConfigPath = path.join(projectRoot, 'eslint.config.js');\n const stylelintConfigPath = path.join(projectRoot, 'stylelint.config.cjs');\n\n const eslintTemplateExists = await fileExists(eslintConfigPath);\n const stylelintTemplateExists = await fileExists(stylelintConfigPath);\n\n // Phase 3.E: a `skip` strategy only short-circuits when the *consumer*\n // already has a config. Without it we still need to write our template.\n const eslintSkipRequested =\n eslintStrategy === 'skip' && eslintExistingPaths.length > 0;\n const stylelintSkipRequested =\n stylelintStrategy === 'skip' && stylelintExistingPaths.length > 0;\n\n const eslintNeedsWrite = !eslintTemplateExists && !eslintSkipRequested;\n const stylelintNeedsWrite =\n !stylelintTemplateExists && !stylelintSkipRequested;\n\n if (!eslintNeedsWrite && !stylelintNeedsWrite) {\n return { status: 'already-initialized' };\n }\n\n // ─── Install dependencies ──────────────────────────────────────────────\n if (!skipInstall) {\n const depsToInstall = [\n ...(eslintNeedsWrite ? ESLINT_DEPS : []),\n ...(stylelintNeedsWrite ? STYLELINT_DEPS : []),\n ];\n\n if (depsToInstall.length > 0) {\n const pm = detectPm(projectRoot);\n const args =\n pm === 'yarn'\n ? ['add', '--dev', ...depsToInstall]\n : pm === 'pnpm'\n ? ['add', '-D', ...depsToInstall]\n : ['install', '--save-dev', ...depsToInstall];\n\n logger.info(`Installing lint deps via ${pm}...`);\n await execa(pm, args, { cwd: projectRoot, stdio: 'inherit' });\n }\n }\n\n // ─── Phase 3.E: back up consumer configs before writing template ───────\n // Phase 1.A2 — `overwrite` strategy still demands a `.bak` so the user\n // can recover the original file. Only `eslintNeedsWrite` /\n // `stylelintNeedsWrite` gates the operation (a `skip`d file is left\n // untouched, so no backup is needed).\n if (eslintNeedsWrite && eslintExistingPaths.length > 0) {\n for (const rel of eslintExistingPaths) {\n await backupFile(path.join(projectRoot, rel), projectRoot);\n }\n }\n if (stylelintNeedsWrite && stylelintExistingPaths.length > 0) {\n for (const rel of stylelintExistingPaths) {\n await backupFile(path.join(projectRoot, rel), projectRoot);\n }\n }\n\n // ─── Write config files ────────────────────────────────────────────────\n let wroteEslint = false;\n let wroteStylelint = false;\n\n if (eslintNeedsWrite) {\n await writeFileSafe(eslintConfigPath, ESLINT_CONFIG_CONTENT);\n logger.debug(`Wrote eslint.config.js → ${eslintConfigPath}`);\n wroteEslint = true;\n }\n\n if (stylelintNeedsWrite) {\n await writeFileSafe(stylelintConfigPath, STYLELINT_CONFIG_CONTENT);\n logger.debug(`Wrote stylelint.config.cjs → ${stylelintConfigPath}`);\n wroteStylelint = true;\n }\n\n // ─── Patch package.json scripts ────────────────────────────────────────\n // Phase 1.A2: package.json is a high-value user file — back it up before\n // we mutate `scripts.lint` / `scripts['lint:css']` so the user can revert\n // the patch without git if needed.\n const packageJsonPatched = await patchPackageJsonScripts(projectRoot);\n\n // ─── Phase 2.3: detect missing ignoreFiles for token files ────────────\n // When the consumer keeps their own stylelint config (skip / merge), check\n // whether it extends a teamix-evo preset. If not, token definition files\n // (tokens.theme.css, tokens.overrides.css) will trigger false-positive\n // no-color-literal / no-hardcoded-dimension errors. Print a non-invasive\n // warning with the recommended fix (review safety-net: never auto-modify).\n let stylelintIgnoreFilesWarning = false;\n if (!stylelintNeedsWrite && stylelintTemplateExists) {\n try {\n const existingContent = fs.readFileSync(stylelintConfigPath, 'utf-8');\n const usesTeamixPreset =\n existingContent.includes('@teamix-evo/stylelint-config/presets/') ||\n existingContent.includes('@teamix-evo/stylelint-config/preset/');\n const hasTokenIgnore =\n existingContent.includes('tokens.theme.css') &&\n existingContent.includes('tokens.overrides.css');\n if (!usesTeamixPreset && !hasTokenIgnore) {\n stylelintIgnoreFilesWarning = true;\n logger.warn(\n [\n '检测到现有 stylelint 配置未排除 token 定义文件。',\n '建议在 stylelint.config.cjs 中添加 ignoreFiles:',\n '',\n ' ignoreFiles: [',\n \" '**/tokens.theme.css',\",\n \" '**/tokens.overrides.css',\",\n ' ]',\n '',\n '或切换到 teamix-evo 预设以自动获得排除规则:',\n '',\n \" extends: ['@teamix-evo/stylelint-config/presets/consumer']\",\n ].join('\\n'),\n );\n }\n } catch {\n // best-effort — config may not be a readable text file\n }\n }\n\n return {\n status: 'installed',\n eslint: wroteEslint,\n stylelint: wroteStylelint,\n eslintMergeRequested:\n wroteEslint &&\n eslintStrategy === 'merge' &&\n eslintExistingPaths.length > 0,\n stylelintMergeRequested:\n wroteStylelint &&\n stylelintStrategy === 'merge' &&\n stylelintExistingPaths.length > 0,\n eslintSkipped: eslintSkipRequested,\n stylelintSkipped: stylelintSkipRequested,\n packageJsonPatched,\n stylelintIgnoreFilesWarning,\n };\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\n/**\n * Detect package manager from lockfile presence.\n */\nfunction detectPm(projectRoot: string): 'pnpm' | 'yarn' | 'npm' {\n if (fs.existsSync(path.join(projectRoot, 'pnpm-lock.yaml'))) return 'pnpm';\n if (fs.existsSync(path.join(projectRoot, 'yarn.lock'))) return 'yarn';\n return 'npm';\n}\n\n/**\n * Add lint scripts to package.json if they don't already exist.\n *\n * Returns `true` when at least one of `scripts.lint` / `scripts['lint:css']`\n * was inserted (so the caller can decide whether to surface a `package.json`\n * change in the project-init ledger). Returns `false` when both scripts\n * already existed or when `package.json` is missing/unparseable.\n */\nasync function patchPackageJsonScripts(projectRoot: string): Promise<boolean> {\n const pkgPath = path.join(projectRoot, 'package.json');\n const raw = await readFileOrNull(pkgPath);\n if (!raw) return false;\n\n let pkg: Record<string, unknown>;\n try {\n pkg = JSON.parse(raw);\n } catch {\n return false;\n }\n\n const scripts = (pkg.scripts ?? {}) as Record<string, string>;\n let changed = false;\n\n if (!scripts.lint) {\n scripts.lint = 'eslint src/';\n changed = true;\n }\n if (!scripts['lint:css']) {\n scripts['lint:css'] = \"stylelint 'src/**/*.css'\";\n changed = true;\n }\n\n if (changed) {\n // Backup user package.json before patching scripts (Phase 1.A2).\n await backupFile(pkgPath, projectRoot);\n pkg.scripts = scripts;\n await writeFileSafe(pkgPath, JSON.stringify(pkg, null, 2) + '\\n');\n logger.debug('Patched package.json scripts with lint / lint:css');\n }\n return changed;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { hasManagedRegion, replaceManagedRegion } from '@teamix-evo/registry';\nimport { backupFile, fileExists, readFileOrNull } from '../utils/fs.js';\nimport { getSkillsSourceDir } from './state.js';\n\n/**\n * Generate `<projectRoot>/AGENTS.md` as a skill-trigger fallback (ADR 0038).\n *\n * The file is **regenerable**: it consolidates TRIGGER / SKIP excerpts from\n * each installed SKILL.md frontmatter description into one terse index, so\n * AGENTS.md-aware IDEs (Codex / Cursor / Claude Code / Qoder) preheat the\n * skill activation conditions even when the user prompt does not directly\n * hit the description-based trigger.\n *\n * Out of scope (per ADR 0038):\n * - Does NOT copy skill body / rules / patterns — those stay in the skill.\n * - Does NOT include `teamix-evo-manage` (entry skill, global scope, ADR 0033).\n *\n * Lifted from `create-teamix-evo` (v0.5) into `teamix-evo/core` so both\n * `npm create teamix-evo` (scaffold path) and `teamix-evo init` (existing-\n * project path, ADR 0019 task #5) emit identical AGENTS.md output.\n *\n * @module teamix-evo/core/agents-md\n */\n\nexport interface RunGenerateAgentsMdOptions {\n /** Absolute path to the consumer project root. */\n projectRoot: string;\n /** Tokens / skills variant (e.g. \"opentrek\"). Used for header context. */\n variant: string;\n /**\n * Skill ids whose `<projectRoot>/.teamix-evo/skills/<id>/SKILL.md` should be\n * indexed. Caller is responsible for filtering out global-only skills\n * (e.g. `teamix-evo-manage`).\n */\n skillIds: string[];\n /**\n * Reconciliation mode (Phase 2.B):\n * - `'overwrite'` (default): always rewrite the full file. Pre-existing\n * content is backed up and discarded.\n * - `'merge-managed'`: rewrite only the `teamix-evo-skills` managed\n * region. When the consumer file lacks the region, prepend a fresh\n * managed block ahead of the user's content (auto-adopt). The user's\n * non-managed sections are preserved.\n *\n * In both modes, an existing file is backed up under\n * `.teamix-evo/.backups/AGENTS.md.<isoTs>.bak` before any mutation.\n */\n mode?: 'overwrite' | 'merge-managed';\n}\n\nexport interface RunGenerateAgentsMdResult {\n /** Absolute path of the written `AGENTS.md`. */\n path: string;\n /** Number of skill sections rendered (missing SKILL.md degradations are still counted). */\n skillCount: number;\n /** Skill ids whose SKILL.md could not be read (rendered as degraded section). */\n missingSkillIds: string[];\n /**\n * True when an existing AGENTS.md was backed up under\n * `.teamix-evo/.backups/AGENTS.md.<isoTs>.bak` before being overwritten\n * (Phase 1.A2 — full backup strategy).\n */\n backedUp: boolean;\n /**\n * Outcome of the merge step (Phase 2.B):\n * - `'created'`: no AGENTS.md existed; wrote a fresh full template.\n * - `'overwritten'`: existed but mode='overwrite' — full rewrite.\n * - `'managed-replaced'`: mode='merge-managed' and the consumer file\n * already had the `teamix-evo-skills` managed region; only that region\n * was rewritten. User content outside is preserved.\n * - `'managed-prepended'`: mode='merge-managed' but the consumer file\n * did not yet have the managed region; a fresh block was inserted at\n * the top, with the existing user content kept below.\n */\n merge: 'created' | 'overwritten' | 'managed-replaced' | 'managed-prepended';\n}\n\n/** Region id wrapping the auto-generated skill index. */\nexport const AGENTS_MD_MANAGED_ID = 'teamix-evo-skills';\n\ninterface SkillDescriptionParts {\n /** First non-empty line(s) of `description` (the capability statement). */\n capability: string;\n trigger: string | null;\n skip: string | null;\n coordinates: string | null;\n}\n\n/**\n * Generate and write the `AGENTS.md` file.\n *\n * Phase 2.B — reconciliation modes:\n * - `'overwrite'` (default): regenerable behaviour, full rewrite.\n * - `'merge-managed'`: rewrite only the `teamix-evo-skills` managed region\n * so user-authored sections (project-specific guidance, design tokens,\n * prompts) are never clobbered.\n *\n * Existing files are always backed up under `.teamix-evo/.backups/` before\n * mutation (ADR 0019 §2, Phase 1.A2).\n */\nexport async function runGenerateAgentsMd(\n options: RunGenerateAgentsMdOptions,\n): Promise<RunGenerateAgentsMdResult> {\n const { projectRoot, variant, skillIds } = options;\n const mode = options.mode ?? 'overwrite';\n\n // Stable order: design → code → others (alphabetical within each bucket).\n const ordered = [...skillIds].sort(\n (a, b) => bucketRank(a) - bucketRank(b) || a.localeCompare(b),\n );\n\n const sections: string[] = [];\n const missingSkillIds: string[] = [];\n for (const id of ordered) {\n const { section, missing } = await renderSkillSection(projectRoot, id);\n sections.push(section);\n if (missing) missingSkillIds.push(id);\n }\n\n const target = path.join(projectRoot, 'AGENTS.md');\n const targetExists = await fileExists(target);\n const fullTemplate = renderAgentsMd({ variant, sections });\n const managedBody = renderManagedBlockBody({ variant, sections });\n\n let outputContent: string;\n let merge: RunGenerateAgentsMdResult['merge'];\n\n if (!targetExists) {\n outputContent = fullTemplate;\n merge = 'created';\n } else {\n // Backup before any mutation — truthful even if downstream throws.\n await backupFile(target, projectRoot);\n if (mode === 'merge-managed') {\n const existing = (await readFileOrNull(target)) ?? '';\n if (hasManagedRegion(existing, AGENTS_MD_MANAGED_ID)) {\n outputContent = replaceManagedRegion(\n existing,\n AGENTS_MD_MANAGED_ID,\n managedBody,\n );\n merge = 'managed-replaced';\n } else {\n // Auto-adopt: place the managed block at the top so AGENTS.md-aware\n // IDEs preheat skill triggers first, then keep the user's prior\n // content as a non-managed tail. A trailing precedence notice goes\n // immediately after the managed block.\n const wrapped = wrapManagedBlock(managedBody);\n outputContent = `${wrapped}\\n\\n${PRECEDENCE_NOTICE}\\n\\n${existing.trimStart()}`;\n merge = 'managed-prepended';\n }\n } else {\n // overwrite — historical default.\n outputContent = fullTemplate;\n merge = 'overwritten';\n }\n }\n\n await fs.writeFile(target, outputContent, 'utf8');\n return {\n path: target,\n skillCount: ordered.length,\n missingSkillIds,\n backedUp: targetExists,\n merge,\n };\n}\n\nfunction bucketRank(id: string): number {\n if (id.startsWith('teamix-evo-design-')) return 0;\n if (id.startsWith('teamix-evo-code-')) return 1;\n return 2;\n}\n\nasync function renderSkillSection(\n projectRoot: string,\n skillId: string,\n): Promise<{ section: string; missing: boolean }> {\n const skillPath = path.join(\n getSkillsSourceDir(projectRoot, skillId),\n 'SKILL.md',\n );\n const lines: string[] = [];\n lines.push(`### ${skillId}`);\n let parts: SkillDescriptionParts | null = null;\n let missing = false;\n try {\n const raw = await fs.readFile(skillPath, 'utf8');\n parts = extractDescriptionParts(raw);\n } catch {\n // SKILL.md missing — degrade gracefully, AI still gets the location hint.\n missing = true;\n }\n\n if (parts?.capability) {\n lines.push(`- ${parts.capability}`);\n }\n lines.push(\n `- **TRIGGER**: ${\n parts?.trigger ?? '未配置触发条件,需手动激活该 skill。'\n }`,\n );\n lines.push(\n `- **SKIP**: ${parts?.skip ?? '未配置跳过条件,按 TRIGGER 兜底判定。'}`,\n );\n if (parts?.coordinates) {\n lines.push(`- **Coordinates with**: ${parts.coordinates}`);\n }\n lines.push(`- **位置**: \\`.teamix-evo/skills-source/${skillId}/SKILL.md\\``);\n return { section: lines.join('\\n'), missing };\n}\n\nfunction renderAgentsMd(args: { variant: string; sections: string[] }): string {\n const { variant, sections } = args;\n const managedBody = renderManagedBlockBody({ variant, sections });\n const wrapped = wrapManagedBlock(managedBody);\n return `${wrapped}\\n\\n${PRECEDENCE_NOTICE}\\n`;\n}\n\n/**\n * Body of the `teamix-evo-skills` managed region (no enclosing markers).\n * Phase 2.B — isolated so {@link runGenerateAgentsMd} can substitute it via\n * `replaceManagedRegion` when reconciling against a user-edited AGENTS.md.\n *\n * Exported so external tools (e.g. the `teamix-evo-manage` skill) can render\n * a preview without depending on the file write path.\n */\nexport function renderManagedBlockBody(args: {\n variant: string;\n sections: string[];\n}): string {\n const { variant, sections } = args;\n const skillBlock =\n sections.length > 0\n ? sections.join('\\n\\n')\n : '_(本工程未装配工程级 skill。)_';\n return `# AGENTS.md\n\n> 本工程已装配 Teamix Evo AI skills。AI 助手在以下场景下**必须先读对应 skill** 再动手。\n> 本文件由 \\`teamix-evo init\\` / \\`create-teamix-evo\\` 自动生成(regenerable,遵循 ADR 0038),刷新方式见底部。\n\n## 已装 Skills(variant: ${variant})\n\n${skillBlock}\n\n## 触发兜底规则\n\n- 写新 \\`.tsx\\` / \\`.ts\\` 前,对照上述 TRIGGER 判定是否命中\n- 命中则先读对应 \\`SKILL.md\\`,再动手;二者同时命中则两个都读\n- 模糊场景:先按 SKIP 反向排除,剩余唯一 skill 即为入口\n- 生命周期命令(\\`init\\` / \\`update\\` / \\`add\\`)走 \\`teamix-evo-manage\\`(全局 skill,本文件不列)\n- 迁移场景(\"代码迁移\" / \"执行迁移\" / \"旧项目迁移\" / \"重建老工程\")同样走 \\`teamix-evo-manage\\` 场景 6\n\n## UI 组件领地(init 后约束)\n\n- \\`src/components/ui/\\` 由 teamix-evo 接管,禁止手工或通过 shadcn CLI 添加新组件\n- 如需新增 UI 组件,使用 \\`npx teamix-evo ui add <id>\\`\n- \\`src/components/shadcn-ui/\\` 是 init 前 legacy 组件归档,只读;新代码不应再 import\n- 升级 legacy 组件:触发 teamix-evo-upgrade skill\n\n> 刷新本文件:\\`npx teamix-evo skills add\\` 或重跑 \\`npm create teamix-evo\\` / \\`teamix-evo init\\`。`;\n}\n\nfunction wrapManagedBlock(body: string): string {\n return `<!-- teamix-evo:managed:start id=\"${AGENTS_MD_MANAGED_ID}\" -->\\n${body}\\n<!-- teamix-evo:managed:end id=\"${AGENTS_MD_MANAGED_ID}\" -->`;\n}\n\n/**\n * Footer notice (Phase 2.B): when AGENTS.md hosts both managed and\n * user-authored sections, the managed Skills index wins on conflict.\n */\nconst PRECEDENCE_NOTICE = `<!-- teamix-evo:precedence -->\n> 冲突以上方的 **Skills** 索引为准(上游路径与 TRIGGER/SKIP 契约);项目特有的人工细则请写在本处以下、不要覆盖上方 managed 区域。`;\n\n// ─── frontmatter parsing ──────────────────────────────────────────────────────\n\n/**\n * Parse a SKILL.md frontmatter description into capability / TRIGGER / SKIP /\n * Coordinates parts.\n *\n * Why hand-rolled (no gray-matter): we only need the `description: |` block.\n * The full YAML grammar is overkill and adds a runtime dep to a CLI / scaffold\n * tool that should stay zero-cost. ADR 0015 keeps frontmatter shape stable.\n */\nexport function extractDescriptionParts(\n fileContent: string,\n): SkillDescriptionParts | null {\n const description = extractDescriptionBlock(fileContent);\n if (description == null) return null;\n\n // Capability = first line that is not a TRIGGER/SKIP/Coordinates marker.\n const allLines = description\n .split('\\n')\n .map((l) => l.trim())\n .filter(Boolean);\n let capability = '';\n for (const line of allLines) {\n if (/^(TRIGGER when:|SKIP:|Coordinates with:)/i.test(line)) break;\n capability = capability ? `${capability} ${line}` : line;\n }\n\n return {\n capability: capability.trim(),\n trigger: extractSection(description, 'TRIGGER when:'),\n skip: extractSection(description, 'SKIP:'),\n coordinates: extractSection(description, 'Coordinates with:'),\n };\n}\n\n/**\n * Extract the `description: |` (or `description: >`) block body. Returns null\n * if the field is missing or not a literal/folded block.\n */\nfunction extractDescriptionBlock(fileContent: string): string | null {\n const lines = fileContent.split('\\n');\n\n // Find frontmatter range: first `---`, then matching `---`.\n if (lines[0]?.trim() !== '---') return null;\n let endIdx = -1;\n for (let i = 1; i < lines.length; i++) {\n if (lines[i]?.trim() === '---') {\n endIdx = i;\n break;\n }\n }\n if (endIdx === -1) return null;\n const fmLines = lines.slice(1, endIdx);\n\n // Locate `description:` key.\n let startIdx = -1;\n let inlineValue: string | null = null;\n let blockMode: 'literal' | 'folded' | 'inline' = 'inline';\n for (let i = 0; i < fmLines.length; i++) {\n const m = fmLines[i]?.match(/^description:\\s*(\\|[+-]?|>[+-]?)?\\s*(.*)$/);\n if (m) {\n startIdx = i;\n const indicator = (m[1] ?? '').trim();\n const rest = m[2] ?? '';\n if (indicator.startsWith('|')) blockMode = 'literal';\n else if (indicator.startsWith('>')) blockMode = 'folded';\n else {\n blockMode = 'inline';\n inlineValue = rest;\n }\n break;\n }\n }\n if (startIdx === -1) return null;\n\n if (blockMode === 'inline') {\n return inlineValue ?? '';\n }\n\n // Block mode: collect indented continuation lines.\n const body: string[] = [];\n // Detect the block indent from the first non-empty continuation line.\n let blockIndent = -1;\n for (let i = startIdx + 1; i < fmLines.length; i++) {\n const line = fmLines[i] ?? '';\n if (line.trim() === '') {\n body.push('');\n continue;\n }\n const indentMatch = line.match(/^(\\s+)/);\n const indent = indentMatch ? indentMatch[1]!.length : 0;\n if (indent === 0) break; // back to top-level key\n if (blockIndent === -1) blockIndent = indent;\n if (indent < blockIndent) break;\n body.push(line.slice(blockIndent));\n }\n // Trim trailing empty lines.\n while (body.length > 0 && body[body.length - 1] === '') body.pop();\n return body.join('\\n');\n}\n\n/**\n * Extract the body of a description sub-section starting with the given\n * marker (e.g. \"TRIGGER when:\"). Stops at the next known marker or end of\n * description. Returns the stripped one-line summary (sub-section text with\n * internal newlines collapsed to spaces).\n */\nfunction extractSection(description: string, marker: string): string | null {\n const markers = ['TRIGGER when:', 'SKIP:', 'Coordinates with:'];\n const lines = description.split('\\n');\n let inSection = false;\n const collected: string[] = [];\n for (const line of lines) {\n const trimmed = line.trim();\n const startsWithMarker = trimmed\n .toLowerCase()\n .startsWith(marker.toLowerCase());\n if (!inSection && startsWithMarker) {\n inSection = true;\n collected.push(trimmed.slice(marker.length).trim());\n continue;\n }\n if (inSection) {\n const hitNextMarker = markers.some(\n (m) =>\n m !== marker && trimmed.toLowerCase().startsWith(m.toLowerCase()),\n );\n if (hitNextMarker) break;\n if (trimmed === '') {\n // Allow blank line within section but stop on second consecutive blank.\n if (collected[collected.length - 1] === '') break;\n collected.push('');\n continue;\n }\n collected.push(trimmed);\n }\n }\n if (!inSection) return null;\n const joined = collected\n .filter((l) => l !== '')\n .join(' ')\n .replace(/\\s+/g, ' ')\n .trim();\n return joined || null;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { fileExists } from '../utils/fs.js';\nimport { getTeamixDir } from './state.js';\n\n/**\n * Three branches of `teamix-evo init` decision tree (ADR 0019 D1).\n *\n * - `empty` : 空目录或仅含可忽略文件 → 推荐用户走 `npm create teamix-evo`(完整版)\n * - `teamix-evo-installed`: 已存在 `.teamix-evo/` → 推荐 `teamix-evo update` / 卸载流程\n * - `non-teamix-evo` : 已有非 teamix-evo 工程 → 走 `teamix-evo init` 普通版接入\n */\nexport type ProjectState = 'empty' | 'teamix-evo-installed' | 'non-teamix-evo';\n\nexport interface ProjectStateReport {\n /** Decision-tree branch the caller should take. */\n state: ProjectState;\n /** Absolute path that was inspected. */\n cwd: string;\n /** Whether `.teamix-evo/` exists at `cwd`. */\n hasTeamixDir: boolean;\n /** Whether `package.json` exists at `cwd`. */\n hasPackageJson: boolean;\n /**\n * Up to 20 entries (relative to `cwd`) that caused us to consider the\n * directory non-empty. Useful for explaining the decision to humans.\n */\n significantEntries: string[];\n}\n\n/**\n * Filenames that should NOT cause us to flip out of the `empty` branch.\n *\n * Mirrors the convention shared by `create-next-app`, `nx init`, and\n * `npm init` — these are typical files added by `git init`, an editor,\n * or the OS, not project content.\n */\nconst IGNORED_TOP_LEVEL = new Set<string>([\n '.git',\n '.gitignore',\n '.gitattributes',\n '.gitkeep',\n '.DS_Store',\n 'Thumbs.db',\n '.idea',\n '.vscode',\n '.qoder',\n '.claude',\n 'README.md',\n 'README',\n 'README.txt',\n 'LICENSE',\n 'LICENSE.md',\n 'LICENSE.txt',\n]);\n\n/**\n * Inspect `cwd` and decide which branch of the `teamix-evo init` decision\n * tree applies. Pure read-only — never mutates the filesystem.\n *\n * Resolution order (first match wins):\n * 1. `.teamix-evo/` exists → `teamix-evo-installed`\n * 2. cwd missing OR all entries are in the IGNORED_TOP_LEVEL set\n * → `empty`\n * 3. otherwise → `non-teamix-evo`\n */\nexport async function detectProjectState(\n cwd: string,\n): Promise<ProjectStateReport> {\n const absCwd = path.resolve(cwd);\n\n const teamixDir = getTeamixDir(absCwd);\n const hasTeamixDir = await fileExists(teamixDir);\n if (hasTeamixDir) {\n return {\n state: 'teamix-evo-installed',\n cwd: absCwd,\n hasTeamixDir: true,\n hasPackageJson: await fileExists(path.join(absCwd, 'package.json')),\n significantEntries: [],\n };\n }\n\n let entries: string[];\n try {\n entries = await fs.readdir(absCwd);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n // Caller pointed us at a directory that doesn't exist yet — treat as\n // empty so `init` can create it (mirrors `npm create` behavior).\n return {\n state: 'empty',\n cwd: absCwd,\n hasTeamixDir: false,\n hasPackageJson: false,\n significantEntries: [],\n };\n }\n throw err;\n }\n\n const significant = entries.filter((e) => !IGNORED_TOP_LEVEL.has(e));\n const hasPackageJson = entries.includes('package.json');\n\n if (significant.length === 0) {\n return {\n state: 'empty',\n cwd: absCwd,\n hasTeamixDir: false,\n hasPackageJson: false,\n significantEntries: [],\n };\n }\n\n return {\n state: 'non-teamix-evo',\n cwd: absCwd,\n hasTeamixDir: false,\n hasPackageJson,\n significantEntries: significant.slice(0, 20).sort(),\n };\n}\n","import * as crypto from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { fileExists, readFileOrNull } from '../utils/fs.js';\n\n/**\n * The 8 categories of consumer-side files that `teamix-evo init` may\n * conflict with when running against a non-teamix-evo project.\n *\n * See ADR 0019 D1 task #5 — these are the only files we mutate at\n * `init` time, so they're the only ones we ask the user about.\n */\nexport type ConflictKey =\n | 'agents-md'\n | 'components-json'\n | 'tailwind-config'\n | 'tokens'\n | 'index-css'\n | 'shadcn-source'\n | 'eslint-config'\n | 'stylelint-config';\n\n/** Strategy options per conflict category. */\nexport type ConflictStrategy =\n // agents-md\n | 'overwrite'\n | 'merge-managed'\n | 'skip'\n // components-json\n | 'diff-prompt'\n // tailwind-config\n | 'backup-overwrite'\n // tokens\n | 'migrate'\n | 'coexist'\n // index-css\n | 'append'\n // shadcn-source\n | 'skip-existing'\n | 'per-file-prompt'\n // eslint-config / stylelint-config (Phase 3.E)\n | 'merge';\n\nexport interface ConflictItem {\n /** Stable id for the category. */\n key: ConflictKey;\n /** True if at least one path in `paths` matched on disk. */\n exists: boolean;\n /**\n * Project-relative paths that matched. Empty when `exists === false`.\n * For `shadcn-source`, may contain a directory path (with trailing `/`).\n */\n paths: string[];\n /** sha256 fingerprint of (sorted) matched contents. Omitted for directories or when nothing matched. */\n fingerprint?: string;\n /** Default strategy presented to the user. */\n recommendedStrategy: ConflictStrategy;\n /** All allowed strategies for this category, in display order. */\n availableStrategies: ConflictStrategy[];\n /** Category-specific metadata (e.g. detected tailwind major version). */\n meta?: Record<string, unknown>;\n}\n\nexport interface ConflictReport {\n cwd: string;\n /** Always 8 items, ordered by ConflictKey enumeration above. */\n items: ConflictItem[];\n /** True if any item has `exists === true`. */\n hasAnyConflict: boolean;\n}\n\n// ─── Path candidates per category ────────────────────────────────────────────\n\nconst TAILWIND_CONFIG_CANDIDATES = [\n 'tailwind.config.ts',\n 'tailwind.config.js',\n 'tailwind.config.cjs',\n 'tailwind.config.mjs',\n];\n\nconst TOKENS_FILE_CANDIDATES = [\n 'src/design-tokens.css',\n 'src/styles/design-tokens.css',\n 'src/styles/tokens.css',\n];\n\nconst TOKENS_DIR_CANDIDATES = ['tokens'];\n\nconst INDEX_CSS_CANDIDATES = [\n 'src/index.css',\n 'src/main.css',\n 'src/app.css',\n 'src/styles/index.css',\n 'src/styles/globals.css',\n];\n\nconst SHADCN_FILE_CANDIDATES = ['src/lib/utils.ts'];\nconst SHADCN_DIR_CANDIDATES = ['src/components/ui'];\n\n// Phase 3.E: 8 ESLint candidates (legacy `.eslintrc.*` + flat `eslint.config.*`)\nconst ESLINT_CONFIG_CANDIDATES = [\n '.eslintrc.cjs',\n '.eslintrc.js',\n '.eslintrc.json',\n '.eslintrc.yml',\n 'eslint.config.js',\n 'eslint.config.cjs',\n 'eslint.config.mjs',\n 'eslint.config.ts',\n];\n\n// Phase 3.E: 8 Stylelint candidates (legacy `.stylelintrc.*` + flat `stylelint.config.*`)\nconst STYLELINT_CONFIG_CANDIDATES = [\n '.stylelintrc.cjs',\n '.stylelintrc.js',\n '.stylelintrc.json',\n '.stylelintrc.yml',\n 'stylelint.config.cjs',\n 'stylelint.config.js',\n 'stylelint.config.mjs',\n 'stylelint.config.ts',\n];\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nasync function isDir(target: string): Promise<boolean> {\n try {\n const stat = await fs.stat(target);\n return stat.isDirectory();\n } catch {\n return false;\n }\n}\n\nasync function dirHasContent(target: string): Promise<boolean> {\n try {\n const entries = await fs.readdir(target);\n return entries.length > 0;\n } catch {\n return false;\n }\n}\n\n/** Hash of UTF-8 string content; truncate to 16 chars for log readability. */\nfunction fingerprint(parts: string[]): string {\n const hash = crypto.createHash('sha256');\n for (const p of [...parts].sort()) hash.update(p);\n return `sha256:${hash.digest('hex').slice(0, 16)}`;\n}\n\ninterface PackageJsonShape {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n\nasync function readPackageJson(cwd: string): Promise<PackageJsonShape | null> {\n const raw = await readFileOrNull(path.join(cwd, 'package.json'));\n if (raw === null) return null;\n try {\n return JSON.parse(raw) as PackageJsonShape;\n } catch {\n return null;\n }\n}\n\n/**\n * Detect tailwind major version from package.json.\n * Returns 4 / 3 / null. We trust dependencies + devDependencies.\n */\nfunction detectTailwindMajor(pkg: PackageJsonShape | null): 3 | 4 | null {\n if (!pkg) return null;\n const v =\n pkg.dependencies?.tailwindcss ?? pkg.devDependencies?.tailwindcss ?? null;\n if (!v) return null;\n // Accept \"^4.0.0\" / \"~4.2.2\" / \"4.x\" / \"next\" → conservative: parse leading digit\n const m = /(\\d+)/.exec(v);\n if (!m) return null;\n const major = Number.parseInt(m[1]!, 10);\n if (major === 3) return 3;\n if (major === 4) return 4;\n return null;\n}\n\n// ─── Per-category detectors ──────────────────────────────────────────────────\n\nasync function detectAgentsMd(cwd: string): Promise<ConflictItem> {\n const target = path.join(cwd, 'AGENTS.md');\n const content = await readFileOrNull(target);\n const exists = content !== null;\n return {\n key: 'agents-md',\n exists,\n paths: exists ? ['AGENTS.md'] : [],\n fingerprint: exists ? fingerprint([content!]) : undefined,\n recommendedStrategy: exists ? 'merge-managed' : 'overwrite',\n availableStrategies: ['merge-managed', 'overwrite', 'skip'],\n };\n}\n\nasync function detectComponentsJson(cwd: string): Promise<ConflictItem> {\n const target = path.join(cwd, 'components.json');\n const content = await readFileOrNull(target);\n const exists = content !== null;\n return {\n key: 'components-json',\n exists,\n paths: exists ? ['components.json'] : [],\n fingerprint: exists ? fingerprint([content!]) : undefined,\n recommendedStrategy: exists ? 'diff-prompt' : 'overwrite',\n availableStrategies: ['diff-prompt', 'overwrite', 'skip'],\n };\n}\n\nasync function detectTailwindConfig(cwd: string): Promise<ConflictItem> {\n const matched: string[] = [];\n const contents: string[] = [];\n for (const rel of TAILWIND_CONFIG_CANDIDATES) {\n const c = await readFileOrNull(path.join(cwd, rel));\n if (c !== null) {\n matched.push(rel);\n contents.push(c);\n }\n }\n const pkg = await readPackageJson(cwd);\n const tailwindMajor = detectTailwindMajor(pkg);\n const exists = matched.length > 0;\n return {\n key: 'tailwind-config',\n exists,\n paths: matched,\n fingerprint: exists ? fingerprint(contents) : undefined,\n recommendedStrategy: exists ? 'backup-overwrite' : 'overwrite',\n availableStrategies: ['backup-overwrite', 'overwrite', 'skip'],\n meta: { tailwindMajor },\n };\n}\n\nasync function detectTokens(cwd: string): Promise<ConflictItem> {\n const matched: string[] = [];\n const contents: string[] = [];\n for (const rel of TOKENS_FILE_CANDIDATES) {\n const c = await readFileOrNull(path.join(cwd, rel));\n if (c !== null) {\n matched.push(rel);\n contents.push(c);\n }\n }\n for (const rel of TOKENS_DIR_CANDIDATES) {\n const abs = path.join(cwd, rel);\n if ((await isDir(abs)) && (await dirHasContent(abs))) {\n matched.push(`${rel}/`);\n }\n }\n const exists = matched.length > 0;\n return {\n key: 'tokens',\n exists,\n paths: matched,\n fingerprint: contents.length > 0 ? fingerprint(contents) : undefined,\n recommendedStrategy: exists ? 'migrate' : 'overwrite',\n availableStrategies: ['migrate', 'coexist', 'overwrite', 'skip'],\n };\n}\n\nasync function detectIndexCss(cwd: string): Promise<ConflictItem> {\n const matched: string[] = [];\n const contents: string[] = [];\n for (const rel of INDEX_CSS_CANDIDATES) {\n const c = await readFileOrNull(path.join(cwd, rel));\n if (c !== null) {\n matched.push(rel);\n contents.push(c);\n }\n }\n const exists = matched.length > 0;\n return {\n key: 'index-css',\n exists,\n paths: matched,\n fingerprint: exists ? fingerprint(contents) : undefined,\n recommendedStrategy: exists ? 'append' : 'overwrite',\n availableStrategies: ['append', 'diff-prompt', 'overwrite', 'skip'],\n };\n}\n\nasync function detectShadcnSource(cwd: string): Promise<ConflictItem> {\n const matched: string[] = [];\n for (const rel of SHADCN_FILE_CANDIDATES) {\n if (await fileExists(path.join(cwd, rel))) matched.push(rel);\n }\n for (const rel of SHADCN_DIR_CANDIDATES) {\n const abs = path.join(cwd, rel);\n if ((await isDir(abs)) && (await dirHasContent(abs))) {\n matched.push(`${rel}/`);\n }\n }\n // For shadcn dir, count component files for meta.\n let componentCount = 0;\n try {\n const uiDir = path.join(cwd, 'src/components/ui');\n if (await isDir(uiDir)) {\n const entries = await fs.readdir(uiDir);\n componentCount = entries.filter(\n (e) => e.endsWith('.tsx') || e.endsWith('.ts'),\n ).length;\n }\n } catch {\n // ignore\n }\n const exists = matched.length > 0;\n return {\n key: 'shadcn-source',\n exists,\n paths: matched,\n recommendedStrategy: exists ? 'skip-existing' : 'overwrite',\n availableStrategies: ['skip-existing', 'per-file-prompt', 'overwrite'],\n meta: { componentCount },\n };\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/**\n * Inspect `cwd` for the 8 categories of files that `teamix-evo init` may\n * touch. Pure read-only — never mutates the filesystem. Returns one\n * `ConflictItem` per category in stable order so callers can render a\n * deterministic wizard.\n */\nexport async function detectConflicts(cwd: string): Promise<ConflictReport> {\n const absCwd = path.resolve(cwd);\n const items: ConflictItem[] = await Promise.all([\n detectAgentsMd(absCwd),\n detectComponentsJson(absCwd),\n detectTailwindConfig(absCwd),\n detectTokens(absCwd),\n detectIndexCss(absCwd),\n detectShadcnSource(absCwd),\n detectEslintConfig(absCwd),\n detectStylelintConfig(absCwd),\n ]);\n return {\n cwd: absCwd,\n items,\n hasAnyConflict: items.some((i) => i.exists),\n };\n}\n\nasync function detectEslintConfig(cwd: string): Promise<ConflictItem> {\n const matched: string[] = [];\n const contents: string[] = [];\n for (const rel of ESLINT_CONFIG_CANDIDATES) {\n const c = await readFileOrNull(path.join(cwd, rel));\n if (c !== null) {\n matched.push(rel);\n contents.push(c);\n }\n }\n const exists = matched.length > 0;\n return {\n key: 'eslint-config',\n exists,\n paths: matched,\n fingerprint: exists ? fingerprint(contents) : undefined,\n recommendedStrategy: exists ? 'merge' : 'overwrite',\n availableStrategies: ['merge', 'backup-overwrite', 'overwrite', 'skip'],\n };\n}\n\nasync function detectStylelintConfig(cwd: string): Promise<ConflictItem> {\n const matched: string[] = [];\n const contents: string[] = [];\n for (const rel of STYLELINT_CONFIG_CANDIDATES) {\n const c = await readFileOrNull(path.join(cwd, rel));\n if (c !== null) {\n matched.push(rel);\n contents.push(c);\n }\n }\n const exists = matched.length > 0;\n return {\n key: 'stylelint-config',\n exists,\n paths: matched,\n fingerprint: exists ? fingerprint(contents) : undefined,\n recommendedStrategy: exists ? 'merge' : 'overwrite',\n availableStrategies: ['merge', 'backup-overwrite', 'overwrite', 'skip'],\n };\n}\n","/**\n * npm dependency auto-installer for `teamix-evo init`.\n *\n * After `runUiAdd` completes, this module:\n * 1. Collects `npmDependencies` from the install result\n * 2. Reads the project's `package.json`\n * 3. Writes missing deps into `dependencies`\n * 4. Detects the package manager and runs install\n *\n * See PLAN Task 3.8 (P0).\n */\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { fileExists, readFileOrNull } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\nconst execAsync = promisify(exec);\n\n// ─── Public types ────────────────────────────────────────────────────────────\n\nexport interface DepsInstallOptions {\n /** Absolute project root */\n projectRoot: string;\n /** npm dependencies to install (name → semver range) */\n npmDependencies: Record<string, string>;\n /** Skip the actual install command (just patch package.json) */\n skipInstall?: boolean;\n}\n\nexport interface DepsInstallResult {\n /** Deps newly written to package.json */\n added: Record<string, string>;\n /** Deps that already existed (skipped) */\n existed: Record<string, string>;\n /** Whether install command was executed */\n installed: boolean;\n /** Detected package manager */\n packageManager: PackageManager;\n}\n\n// ─── Package manager detection ───────────────────────────────────────────────\n\ntype PackageManager = 'pnpm' | 'yarn' | 'bun' | 'npm';\n\nasync function detectPackageManager(\n projectRoot: string,\n): Promise<PackageManager> {\n if (await fileExists(path.join(projectRoot, 'pnpm-lock.yaml'))) return 'pnpm';\n if (await fileExists(path.join(projectRoot, 'pnpm-workspace.yaml')))\n return 'pnpm';\n if (await fileExists(path.join(projectRoot, 'bun.lockb'))) return 'bun';\n if (await fileExists(path.join(projectRoot, 'bun.lock'))) return 'bun';\n if (await fileExists(path.join(projectRoot, 'yarn.lock'))) return 'yarn';\n return 'npm';\n}\n\nfunction getInstallCommand(pm: PackageManager): string {\n switch (pm) {\n case 'pnpm':\n return 'pnpm install';\n case 'yarn':\n return 'yarn install';\n case 'bun':\n return 'bun install';\n case 'npm':\n return 'npm install';\n }\n}\n\n// ─── Core installer ──────────────────────────────────────────────────────────\n\n/**\n * Patch project `package.json` with missing npm dependencies and optionally\n * run the package manager's install command.\n */\nexport async function installProjectDeps(\n options: DepsInstallOptions,\n): Promise<DepsInstallResult> {\n const { projectRoot, npmDependencies, skipInstall = false } = options;\n\n const pkgPath = path.join(projectRoot, 'package.json');\n const raw = await readFileOrNull(pkgPath);\n if (!raw) {\n throw new Error(\n `package.json not found at ${projectRoot}. Cannot install dependencies.`,\n );\n }\n\n const pkg = JSON.parse(raw) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n\n const existingDeps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n\n const added: Record<string, string> = {};\n const existed: Record<string, string> = {};\n\n for (const [name, range] of Object.entries(npmDependencies)) {\n if (existingDeps[name]) {\n existed[name] = existingDeps[name]!;\n } else {\n added[name] = range;\n }\n }\n\n // Patch package.json if there are new deps\n if (Object.keys(added).length > 0) {\n if (!pkg.dependencies) pkg.dependencies = {};\n for (const [name, range] of Object.entries(added)) {\n pkg.dependencies[name] = range;\n }\n // Sort dependencies alphabetically\n pkg.dependencies = Object.fromEntries(\n Object.entries(pkg.dependencies).sort(([a], [b]) => a.localeCompare(b)),\n );\n\n await fs.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\\n', 'utf-8');\n logger.info(\n ` patched package.json: +${Object.keys(added).length} dependencies`,\n );\n }\n\n // Detect package manager and run install\n const packageManager = await detectPackageManager(projectRoot);\n let installed = false;\n\n if (!skipInstall && Object.keys(added).length > 0) {\n const cmd = getInstallCommand(packageManager);\n logger.info(` running ${cmd}...`);\n try {\n await execAsync(cmd, { cwd: projectRoot, timeout: 120_000 });\n installed = true;\n logger.info(' install complete');\n } catch (err) {\n logger.warn(\n ` install failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n logger.warn(' please run install manually');\n }\n }\n\n return { added, existed, installed, packageManager };\n}\n","/**\n * Generates the `.teamix-evo/init-checklist.md` content after `teamix-evo init`.\n *\n * Simplified for ADR 0043: only records the 8-step pipeline results.\n * No Phase B — post-init guidance is handled by AI skills at runtime.\n */\n\nimport type { ProjectInitStep } from './project-init.js';\n\n/** Step display metadata. */\nconst STEP_LABELS: Record<string, string> = {\n tokens: 'tokens — design tokens 安装',\n skills: 'skills — AI skills 批量自举',\n 'agents-md': 'agents-md — AGENTS.md 生成',\n 'ui-init': 'ui-init — UI 配置初始化',\n 'ui-add': 'ui-add — UI 组件全量安装',\n 'biz-ui-add': 'biz-ui-add — 业务组件全量安装',\n lint: 'lint — ESLint + Stylelint 配置',\n gitignore: 'gitignore — .gitignore 追加',\n};\n\nexport function renderInitChecklist(args: {\n variant: string;\n status: string;\n steps: ProjectInitStep[];\n timestamp?: string;\n}): string {\n const { variant, status, steps } = args;\n const ts =\n args.timestamp ?? new Date().toISOString().replace('T', ' ').slice(0, 19);\n\n const stepLines = steps\n .map((s) => {\n const label = STEP_LABELS[s.name] ?? s.name;\n const checked = s.status === 'ok' ? 'x' : ' ';\n const suffix =\n s.status === 'ok'\n ? ''\n : s.status === 'skip'\n ? `(跳过${s.detail ? ':' + s.detail : ''})`\n : s.status === 'fail'\n ? `(失败:${s.detail ?? 'unknown'})`\n : '(计划中)';\n return `- [${checked}] ${label}${suffix}`;\n })\n .join('\\n');\n\n return `# teamix-evo init 安装摘要\n\n> 由 \\`teamix-evo init\\` 自动生成 · ${ts}\n> variant: ${variant} · status: ${status}\n\n## 安装步骤\n\n${stepLines}\n\n## 备注\n\n- 失败或跳过的步骤不影响后续步骤独立执行\n- 修复后重跑 \\`teamix-evo init\\`(每步幂等,自动跳过已完成项)\n- 如需全量覆盖:\\`teamix-evo init --force\\`\n`;\n}\n","/**\n * File-change ledger for the init / update pipelines.\n *\n * Phase 1.A1 (init 落地改进): every orchestrator step records what it touched\n * so the CLI can print a single \"新建 / 修改 / 备份 / 删除\" summary at the end.\n * Today's pipeline only piggybacks on side-effectful sub-commands' result\n * objects (`resources`, `wroteEslint`, …) — without an explicit ledger the\n * user has no way to see, in one glance, which user-owned files moved.\n *\n * Design constraints:\n * - Pure data type — no I/O, no global mutable state. The orchestrator passes\n * a single mutable array down to each helper; sub-step adapters return\n * `FileChange[]` they can derive from their own return values.\n * - \"modified\" vs \"created\" is decided by checking whether a fresh backup\n * exists under `.teamix-evo/.backups/<rel>.*.bak` for that path — see\n * {@link diffBackupSet}. Any path that gained a backup during the pipeline\n * is classified `modified`; everything else surfaced by the steps is\n * `created`. This keeps the classification truthful even when a sub-step\n * has no idea whether the file pre-existed.\n */\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nexport type FileChangeKind = 'created' | 'modified' | 'backed-up' | 'deleted';\n\nexport interface FileChange {\n kind: FileChangeKind;\n /** Project-root-relative path, posix style (forward slashes). */\n path: string;\n /** Originating pipeline step (free-form to avoid coupling on `ProjectInitStepName`). */\n step: string;\n /** Optional human-readable note (e.g. `frozen` / `regenerable` / `managed`). */\n detail?: string;\n}\n\n/**\n * Convert any abs/rel path to a project-root-relative posix path.\n * Returns the input unchanged if it cannot be relativised.\n */\nexport function toRelativePosix(p: string, projectRoot: string): string {\n let rel = p;\n if (path.isAbsolute(p)) {\n rel = path.relative(projectRoot, p);\n }\n return rel.split(path.sep).join('/');\n}\n\n/**\n * Recursively enumerate `.teamix-evo/.backups/` and return the set of\n * original (project-root-relative) paths that have at least one `.bak` copy.\n *\n * Backup file names follow `<rel>.<isoTsSafe>.bak` where `<isoTsSafe>` is the\n * output of `new Date().toISOString().replace(/[:.]/g, '-')` — a fixed-shape\n * `YYYY-MM-DDTHH-MM-SS-mmmZ` token. We strip that suffix to recover `<rel>`.\n *\n * Returns an empty set when the backups directory does not exist.\n */\nexport async function listBackupOriginals(\n projectRoot: string,\n): Promise<Set<string>> {\n const backupsDir = path.join(projectRoot, '.teamix-evo', '.backups');\n const out = new Set<string>();\n const stack: string[] = [backupsDir];\n while (stack.length > 0) {\n const dir = stack.pop()!;\n let entries: import('node:fs').Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') continue;\n throw err;\n }\n for (const e of entries) {\n const full = path.join(dir, e.name);\n if (e.isDirectory()) {\n stack.push(full);\n } else if (e.isFile() && e.name.endsWith('.bak')) {\n const rel = path.relative(backupsDir, full);\n const original = stripBackupSuffix(rel);\n if (original) out.add(original.split(path.sep).join('/'));\n }\n }\n }\n return out;\n}\n\n/**\n * Strip the `.<isoTsSafe>.bak` tail from a backup-relative path. Returns null\n * when the suffix doesn't match (file isn't one of ours — leave untouched).\n */\nexport function stripBackupSuffix(rel: string): string | null {\n const m = rel.match(\n /^(.+)\\.\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-\\d{3}Z\\.bak$/,\n );\n return m?.[1] ?? null;\n}\n\n/**\n * Compute the relative-path set that gained a fresh backup between `before`\n * and `after` (i.e. paths the pipeline modified in-place).\n */\nexport function diffBackupSet(\n before: ReadonlySet<string>,\n after: ReadonlySet<string>,\n): Set<string> {\n const out = new Set<string>();\n for (const p of after) {\n if (!before.has(p)) out.add(p);\n }\n return out;\n}\n\n/**\n * Format a flat list of `FileChange` rows into a markdown-ish summary.\n * Returns an array of lines suitable for the CLI logger.\n *\n * Empty buckets are omitted from the output. Order: created → modified →\n * backed-up → deleted. Each bucket lists paths sorted lexicographically with\n * de-duplication on `(kind, path)`.\n */\nexport function formatFileChangeSummary(changes: FileChange[]): string[] {\n if (changes.length === 0) return [];\n const buckets: Record<FileChangeKind, Map<string, FileChange>> = {\n created: new Map(),\n modified: new Map(),\n 'backed-up': new Map(),\n deleted: new Map(),\n };\n for (const c of changes) {\n const existing = buckets[c.kind].get(c.path);\n if (!existing) buckets[c.kind].set(c.path, c);\n }\n const order: Array<[FileChangeKind, string]> = [\n ['created', '🆕 新建'],\n ['modified', '✏️ 修改'],\n ['backed-up', '💾 已备份'],\n ['deleted', '🗑 删除'],\n ];\n const lines: string[] = [];\n for (const [kind, label] of order) {\n const bucket = buckets[kind];\n if (bucket.size === 0) continue;\n lines.push(`${label}(${bucket.size}):`);\n const sorted = [...bucket.values()].sort((a, b) =>\n a.path.localeCompare(b.path),\n );\n for (const c of sorted) {\n const detail = c.detail ? ` — ${c.detail}` : '';\n lines.push(` • ${c.path} [${c.step}]${detail}`);\n }\n }\n return lines;\n}\n","/**\n * Programmatic orchestrator for `teamix-evo init` (ADR 0043).\n *\n * Drives the 8-step pipeline that installs the full teamix-evo suite into an\n * existing project. Each step is idempotent — re-running `init` picks up from\n * where it left off.\n *\n * Conflict handling is intentionally thin (ADR 0043 §3): detect → terminate →\n * structured output → AI decides. The orchestrator only checks `force` — when\n * true, it skips conflict detection entirely.\n */\nimport type { SkillIde, SkillScope } from '@teamix-evo/registry';\nimport { runTokensInit } from './tokens-init.js';\nimport { runSkillsInit } from './skills-add.js';\nimport { runGenerateAgentsMd } from './agents-md.js';\nimport { runUiInit } from './ui-init.js';\nimport { runUiAdd } from './ui-add.js';\nimport { runBizUiAdd, listBizUiEntries } from './variant-ui-add.js';\nimport { runLintInit } from './lint-init.js';\nimport { installProjectDeps } from './deps-install.js';\nimport { loadUiData } from './ui-client.js';\nimport { renderInitChecklist } from './init-checklist-template.js';\nimport { getErrorMessage } from '../utils/error.js';\nimport { logger } from '../utils/logger.js';\nimport { type FileChange, toRelativePosix } from './file-changes.js';\nimport * as fsNode from 'node:fs/promises';\nimport * as path from 'node:path';\n\n// ─── Types ─────────────────────────────────────────────────────────────────────\n\nexport type ProjectInitStepName =\n | 'tokens'\n | 'skills'\n | 'agents-md'\n | 'ui-init'\n | 'ui-add'\n | 'biz-ui-add'\n | 'lint'\n | 'gitignore';\n\nexport type ProjectInitStepStatus = 'ok' | 'skip' | 'fail' | 'planned';\n\nexport interface ProjectInitStep {\n name: ProjectInitStepName;\n status: ProjectInitStepStatus;\n detail?: string;\n /** Files this step touched. */\n changes?: FileChange[];\n}\n\nexport interface ResumeHint {\n failedAt: ProjectInitStepName;\n completed: ProjectInitStepName[];\n failed: ProjectInitStepName[];\n error: string;\n resumeCommand: string;\n}\n\nexport interface RunProjectInitOptions {\n /** Absolute project root (existing repo to adopt teamix-evo into). */\n projectRoot: string;\n /** Tokens variant (e.g. \"opentrek\" / \"uni-manager\"). */\n variant: string;\n /** Target IDEs (at least one). */\n ides: SkillIde[];\n /** Skill install scope. Defaults to 'project'. */\n scope?: SkillScope;\n /**\n * When true, skip conflict detection and overwrite everything.\n * Distinction: init --force = skip conflict check; create --force = overwrite directory.\n */\n force?: boolean;\n /** Skip `npm install` for lint deps. */\n skipInstall?: boolean;\n /** Step-level progress hook. */\n onStep?: (step: ProjectInitStep) => void;\n /** Plan-only mode: compute steps without running sub-commands. */\n dryRun?: boolean;\n}\n\nexport interface RunProjectInitResult {\n status: 'installed' | 'partial' | 'dry-run';\n steps: ProjectInitStep[];\n changes: FileChange[];\n resumeHint?: ResumeHint;\n}\n\n// ─── Constants ──────────────────────────────────────────────────────────────────\n\n/**\n * Steps whose failure aborts subsequent critical steps. Non-critical leaves\n * (agents-md / ui-add / biz-ui-add / lint / gitignore) continue independently.\n */\nconst CRITICAL_STEPS: ReadonlySet<ProjectInitStepName> = new Set([\n 'tokens',\n 'skills',\n 'ui-init',\n]);\n\nconst GITIGNORE_MARKER_START = '# >>> teamix-evo:managed >>>';\nconst GITIGNORE_MARKER_END = '# <<< teamix-evo:managed <<<';\nconst GITIGNORE_RULES = [\n '# Runtime artifacts (regenerable / archives)',\n '.teamix-evo/.snapshots/',\n '.teamix-evo/logs/',\n '.teamix-evo/.backups/',\n '.teamix-evo/.upgrade-staging/',\n '.teamix-evo/.upgrade-hints/',\n];\n\n// ─── Orchestrator ───────────────────────────────────────────────────────────────\n\nexport async function runProjectInit(\n options: RunProjectInitOptions,\n): Promise<RunProjectInitResult> {\n const {\n projectRoot,\n variant,\n ides,\n scope = 'project',\n dryRun = false,\n onStep,\n } = options;\n const ide = ides[0] ?? 'qoder';\n const steps: ProjectInitStep[] = [];\n const allChanges: FileChange[] = [];\n\n let aborted = false;\n const firstFailure: {\n value: { step: ProjectInitStepName; error: string } | null;\n } = { value: null };\n\n function record(step: ProjectInitStep): void {\n steps.push(step);\n onStep?.(step);\n if (step.changes && step.changes.length > 0) {\n allChanges.push(...step.changes);\n }\n }\n\n function recordFailure(name: ProjectInitStepName, err: unknown): void {\n const message = getErrorMessage(err);\n record({ name, status: 'fail', detail: message });\n if (!firstFailure.value)\n firstFailure.value = { step: name, error: message };\n if (CRITICAL_STEPS.has(name)) aborted = true;\n }\n\n // ─── 1. tokens ──────────────────────────────────────────────────────────────\n if (dryRun) {\n record({\n name: 'tokens',\n status: 'planned',\n detail: `runTokensInit(variant=${variant})`,\n });\n } else {\n try {\n const result = await runTokensInit({ projectRoot, variant, ide });\n const detail =\n result.status === 'installed'\n ? `${result.packageName}@${result.version} (${result.count} files)`\n : result.status;\n record({\n name: 'tokens',\n status: 'ok',\n detail,\n changes:\n result.status === 'installed'\n ? result.resources.map((r) => ({\n kind: 'created' as const,\n path: toRelativePosix(r.target, projectRoot),\n step: 'tokens',\n detail: r.strategy,\n }))\n : [],\n });\n } catch (err) {\n recordFailure('tokens', err);\n }\n }\n\n // ─── 2. skills init (batch bootstrap) ────────────────────────────────────────\n if (dryRun) {\n record({\n name: 'skills',\n status: 'planned',\n detail: `runSkillsInit(scope=${scope})`,\n });\n } else if (aborted) {\n record({\n name: 'skills',\n status: 'skip',\n detail: 'aborted: earlier critical step failed',\n });\n } else {\n try {\n const result = await runSkillsInit({ projectRoot, ides, scope, ide });\n if (result.status === 'already-initialized') {\n record({ name: 'skills', status: 'ok', detail: 'already-initialized' });\n } else {\n record({\n name: 'skills',\n status: 'ok',\n detail: `${result.skillCount} skills, ${\n result.fileCount\n } files (added: ${result.addedSkillIds.join(', ') || 'none'})`,\n changes: result.addedSkillIds.map((id) => ({\n kind: 'created' as const,\n path: `.teamix-evo/skills/${id}/SKILL.md`,\n step: 'skills',\n detail: 'skill installed',\n })),\n });\n }\n } catch (err) {\n recordFailure('skills', err);\n }\n }\n\n // ─── 3. AGENTS.md ─────────────────────────────────────────────────────────────\n if (dryRun) {\n record({\n name: 'agents-md',\n status: 'planned',\n detail: 'runGenerateAgentsMd()',\n });\n } else {\n try {\n const result = await runGenerateAgentsMd({\n projectRoot,\n variant,\n skillIds: [\n `teamix-evo-design-${variant}`,\n `teamix-evo-code-${variant}`,\n ],\n mode: 'merge-managed',\n });\n record({\n name: 'agents-md',\n status: 'ok',\n detail: `${result.skillCount} skill index`,\n changes: [\n {\n kind: result.backedUp ? 'modified' : 'created',\n path: toRelativePosix(result.path, projectRoot),\n step: 'agents-md',\n detail: 'skill-trigger fallback (ADR 0038)',\n },\n ],\n });\n } catch (err) {\n recordFailure('agents-md', err);\n }\n }\n\n // ─── 4. ui-init (.teamix-evo/config.json) ──────────────────────────────────────\n if (dryRun) {\n record({ name: 'ui-init', status: 'planned', detail: 'runUiInit()' });\n } else if (aborted) {\n record({\n name: 'ui-init',\n status: 'skip',\n detail: 'aborted: earlier critical step failed',\n });\n } else {\n try {\n const initResult = await runUiInit({ projectRoot, ide });\n record({\n name: 'ui-init',\n status: 'ok',\n detail:\n initResult.status === 'installed'\n ? 'config.json packages.ui written'\n : initResult.status,\n });\n } catch (err) {\n recordFailure('ui-init', err);\n }\n }\n\n // ─── 5. ui add --all (全量 UI 组件源码) ────────────────────────────────────────\n // 收集 ui-add + biz-ui-add 的 npm 依赖,统一在两步之后调用 installProjectDeps。\n const collectedNpmDeps: Record<string, string> = {};\n if (dryRun) {\n const { manifest } = await loadUiData('@teamix-evo/ui').catch(() => ({\n manifest: { entries: [] as Array<{ id: string }> },\n }));\n record({\n name: 'ui-add',\n status: 'planned',\n detail: `runUiAdd(${manifest.entries.length} entries, --all)`,\n });\n } else if (aborted) {\n record({\n name: 'ui-add',\n status: 'skip',\n detail: 'aborted: earlier critical step failed',\n });\n } else {\n try {\n const { manifest } = await loadUiData('@teamix-evo/ui');\n const allIds = manifest.entries.map((e) => e.id);\n const addResult = await runUiAdd({\n projectRoot,\n ids: allIds,\n overwrite: true,\n });\n // slice(-0) === slice(0) 返回全量;written === 0 时显式返回空数组\n const writtenResources =\n addResult.written > 0\n ? addResult.resources.slice(-addResult.written)\n : [];\n record({\n name: 'ui-add',\n status: 'ok',\n detail: `${addResult.orderedIds.length} entries (${addResult.written} written, ${addResult.skipped} skipped)`,\n changes: writtenResources.map((r) => ({\n kind: 'created' as const,\n path: toRelativePosix(r.target, projectRoot),\n step: 'ui-add',\n detail: r.strategy,\n })),\n });\n Object.assign(collectedNpmDeps, addResult.npmDependencies);\n } catch (err) {\n recordFailure('ui-add', err);\n }\n }\n\n // ─── 6. biz-ui add --all (variant 全量业务组件) ─────────────────────────────────\n if (dryRun) {\n try {\n const listing = await listBizUiEntries(variant);\n record({\n name: 'biz-ui-add',\n status: 'planned',\n detail: `runBizUiAdd(variant=${variant}, ${listing.entries.length} entries)`,\n });\n } catch {\n record({\n name: 'biz-ui-add',\n status: 'planned',\n detail: `runBizUiAdd(variant=${variant})`,\n });\n }\n } else if (aborted) {\n record({\n name: 'biz-ui-add',\n status: 'skip',\n detail: 'aborted: earlier critical step failed',\n });\n } else {\n try {\n const listing = await listBizUiEntries(variant);\n if (listing.entries.length === 0) {\n record({\n name: 'biz-ui-add',\n status: 'skip',\n detail: `no biz-ui entries for variant \"${variant}\"`,\n });\n } else {\n const allIds = listing.entries.map((e) => e.id);\n const result = await runBizUiAdd({\n projectRoot,\n variant,\n ids: allIds,\n overwrite: true,\n });\n record({\n name: 'biz-ui-add',\n status: 'ok',\n detail: `${result.orderedIds.length} entries (${result.written} written, ${result.skipped} skipped)`,\n });\n if (result.npmDependencies) {\n Object.assign(collectedNpmDeps, result.npmDependencies);\n }\n }\n } catch (err) {\n recordFailure('biz-ui-add', err);\n }\n }\n\n // ─── 6.5 install ui / biz-ui transitive npm dependencies ─────────────────────\n // ui-add / biz-ui-add 复制源码后,需要把它们引用的 npm 依赖(@radix-ui/* / cmdk /\n // recharts 等)写入 package.json 并安装,否则 `npm run dev` 会报模块缺失。\n if (!dryRun && !aborted && Object.keys(collectedNpmDeps).length > 0) {\n try {\n await installProjectDeps({\n projectRoot,\n npmDependencies: collectedNpmDeps,\n skipInstall: options.skipInstall ?? false,\n });\n } catch (err) {\n // Non-critical: 失败不应阻断 lint / gitignore;记录但不计入 critical abort。\n logger.warn(\n `安装 ui/biz-ui 传递依赖失败:${getErrorMessage(\n err,\n )}(可手动运行 \\`npm install\\` 重试)`,\n );\n }\n }\n\n // ─── 7. lint init ──────────────────────────────────────────────────────────────\n if (dryRun) {\n record({ name: 'lint', status: 'planned', detail: 'runLintInit()' });\n } else {\n try {\n const result = await runLintInit({\n projectRoot,\n skipInstall: options.skipInstall ?? false,\n eslintStrategy: 'overwrite',\n stylelintStrategy: 'overwrite',\n eslintExistingPaths: [],\n stylelintExistingPaths: [],\n });\n const detailParts: string[] = [];\n if (result.status === 'installed') {\n detailParts.push(\n `eslint=${result.eslint}, stylelint=${result.stylelint}`,\n );\n if (result.packageJsonPatched) detailParts.push('package.json patched');\n } else {\n detailParts.push(result.status);\n }\n record({\n name: 'lint',\n status: 'ok',\n detail: detailParts.join(' / '),\n changes: deriveLintChanges(result),\n });\n } catch (err) {\n recordFailure('lint', err);\n }\n }\n\n // ─── 8. gitignore ──────────────────────────────────────────────────────────────\n if (dryRun) {\n record({\n name: 'gitignore',\n status: 'planned',\n detail: 'append teamix-evo runtime rules',\n });\n } else {\n try {\n let projectRootExists = true;\n try {\n await fsNode.access(projectRoot);\n } catch {\n projectRootExists = false;\n }\n if (!projectRootExists) {\n record({\n name: 'gitignore',\n status: 'skip',\n detail: 'projectRoot does not exist',\n });\n } else {\n const giPath = path.join(projectRoot, '.gitignore');\n let giContent = '';\n try {\n giContent = await fsNode.readFile(giPath, 'utf-8');\n } catch {\n // .gitignore doesn't exist yet — we'll create it\n }\n if (giContent.includes(GITIGNORE_MARKER_START)) {\n record({\n name: 'gitignore',\n status: 'skip',\n detail: 'teamix-evo markers already present',\n });\n } else {\n const block = [\n '',\n GITIGNORE_MARKER_START,\n ...GITIGNORE_RULES,\n GITIGNORE_MARKER_END,\n '',\n ].join('\\n');\n const separator =\n giContent.length > 0 && !giContent.endsWith('\\n') ? '\\n' : '';\n await fsNode.writeFile(\n giPath,\n giContent + separator + block,\n 'utf-8',\n );\n record({\n name: 'gitignore',\n status: 'ok',\n detail: `${\n GITIGNORE_RULES.filter((r) => r && !r.startsWith('#')).length\n } rules appended`,\n changes: [\n {\n kind: 'modified',\n path: '.gitignore',\n step: 'gitignore',\n detail: 'teamix-evo runtime artifact rules',\n },\n ],\n });\n }\n }\n } catch (err) {\n recordFailure('gitignore', err);\n }\n }\n\n // ─── Result assembly ──────────────────────────────────────────────────────────\n const status: RunProjectInitResult['status'] = dryRun\n ? 'dry-run'\n : steps.some((s) => s.status === 'fail')\n ? 'partial'\n : 'installed';\n\n const out: RunProjectInitResult = { status, steps, changes: allChanges };\n\n if (firstFailure.value) {\n out.resumeHint = {\n failedAt: firstFailure.value.step,\n completed: steps.filter((s) => s.status === 'ok').map((s) => s.name),\n failed: steps.filter((s) => s.status === 'fail').map((s) => s.name),\n error: firstFailure.value.error,\n resumeCommand: 'teamix-evo init',\n };\n }\n\n // Write install summary (.teamix-evo/init-checklist.md)\n if (!dryRun) {\n try {\n const checklistContent = renderInitChecklist({ variant, status, steps });\n const checklistPath = path.join(\n projectRoot,\n '.teamix-evo',\n 'init-checklist.md',\n );\n await fsNode.mkdir(path.dirname(checklistPath), { recursive: true });\n await fsNode.writeFile(checklistPath, checklistContent, 'utf-8');\n logger.info(' wrote .teamix-evo/init-checklist.md');\n } catch {\n logger.warn(' failed to write init-checklist.md (non-fatal)');\n }\n }\n\n return out;\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────────────────\n\ntype LintInitResult = Awaited<ReturnType<typeof runLintInit>>;\n\nfunction deriveLintChanges(result: LintInitResult): FileChange[] {\n if (result.status !== 'installed') return [];\n const out: FileChange[] = [];\n if (result.eslint) {\n out.push({\n kind: 'created',\n path: 'eslint.config.js',\n step: 'lint',\n detail: '@teamix-evo/eslint-config',\n });\n }\n if (result.stylelint) {\n out.push({\n kind: 'created',\n path: 'stylelint.config.cjs',\n step: 'lint',\n detail: '@teamix-evo/stylelint-config',\n });\n }\n if (result.packageJsonPatched) {\n out.push({\n kind: 'created',\n path: 'package.json',\n step: 'lint',\n detail: 'scripts.lint / scripts[\"lint:css\"]',\n });\n }\n return out;\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport type {\n VariantManifest,\n Resource,\n InstalledResource,\n} from '@teamix-evo/registry';\nimport { writeFileSafe, ensureDir } from '../utils/fs.js';\nimport { computeHash } from '../utils/hash.js';\nimport { renderTemplate, loadTemplateFile } from '../utils/template.js';\nimport { logger } from '../utils/logger.js';\nimport { resolveSourcePath, walkDir } from '../utils/path.js';\n\nexport interface InstallOptions {\n /** Project root directory */\n projectRoot: string;\n /** The variant manifest */\n manifest: VariantManifest;\n /** Template data for Handlebars rendering */\n data: Record<string, unknown>;\n /** Absolute path to the variant directory (where source files live) */\n variantDir: string;\n /** Absolute path to the package root (for resolving _template/ sources) */\n packageRoot: string;\n}\n\nexport interface InstallResult {\n /** Successfully installed resource records */\n resources: InstalledResource[];\n /** Number of resources installed */\n count: number;\n}\n\n/**\n * Install resources from a variant manifest into the project.\n */\nexport async function installResources(\n options: InstallOptions,\n): Promise<InstallResult> {\n const { projectRoot, manifest, data, variantDir, packageRoot } = options;\n const installedResources: InstalledResource[] = [];\n\n for (const resource of manifest.resources) {\n logger.debug(`Installing resource: ${resource.id} → ${resource.target}`);\n\n if (resource.recursive) {\n const results = await installRecursiveResource(\n resource,\n projectRoot,\n data,\n variantDir,\n packageRoot,\n );\n installedResources.push(...results);\n } else {\n const result = await installSingleResource(\n resource,\n projectRoot,\n data,\n variantDir,\n packageRoot,\n );\n installedResources.push(result);\n }\n }\n\n return {\n resources: installedResources,\n count: installedResources.length,\n };\n}\n\n/**\n * Install a single (non-recursive) resource.\n */\nasync function installSingleResource(\n resource: Resource,\n projectRoot: string,\n data: Record<string, unknown>,\n variantDir: string,\n packageRoot: string,\n): Promise<InstalledResource> {\n const sourcePath = resolveSourcePath(\n resource.source,\n variantDir,\n packageRoot,\n );\n const targetPath = path.join(projectRoot, resource.target);\n\n let content: string;\n if (resource.template) {\n const templateContent = await loadTemplateFile(sourcePath);\n content = renderTemplate(templateContent, data);\n } else {\n content = await fs.readFile(sourcePath, 'utf-8');\n }\n\n await writeFileSafe(targetPath, content);\n const hash = computeHash(content);\n\n logger.debug(` Written: ${resource.target} (${resource.updateStrategy})`);\n\n return {\n id: resource.id,\n target: resource.target,\n hash,\n strategy: resource.updateStrategy,\n };\n}\n\n/**\n * Install a recursive resource (directory).\n */\nasync function installRecursiveResource(\n resource: Resource,\n projectRoot: string,\n data: Record<string, unknown>,\n variantDir: string,\n packageRoot: string,\n): Promise<InstalledResource[]> {\n const sourcePath = resolveSourcePath(\n resource.source,\n variantDir,\n packageRoot,\n );\n const targetDir = path.join(projectRoot, resource.target);\n const results: InstalledResource[] = [];\n\n await ensureDir(targetDir);\n\n const entries = await walkDir(sourcePath);\n for (const entry of entries) {\n const relPath = path.relative(sourcePath, entry);\n let targetFile = path.join(targetDir, relPath);\n\n // Strip .hbs extension from target if template\n if (resource.template && targetFile.endsWith('.hbs')) {\n targetFile = targetFile.slice(0, -4);\n }\n\n let content: string;\n if (resource.template && entry.endsWith('.hbs')) {\n const templateContent = await loadTemplateFile(entry);\n content = renderTemplate(templateContent, data);\n } else {\n content = await fs.readFile(entry, 'utf-8');\n }\n\n await writeFileSafe(targetFile, content);\n const hash = computeHash(content);\n const targetRel = path.relative(projectRoot, targetFile);\n\n results.push({\n id: `${resource.id}:${relPath}`,\n target: targetRel,\n hash,\n strategy: resource.updateStrategy,\n });\n\n logger.debug(` Written: ${targetRel}`);\n }\n\n return results;\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport type { VariantManifest } from '@teamix-evo/registry';\nimport { loadVariantManifest } from '@teamix-evo/registry';\nimport { logger } from '../utils/logger.js';\n\nconst require = createRequire(import.meta.url);\n\n/**\n * Resolve the package root directory for a design package.\n */\nfunction resolvePackageRoot(packageName: string): string {\n const pkgJsonPath = require.resolve(`${packageName}/package.json`);\n return path.dirname(pkgJsonPath);\n}\n\n/**\n * Resolve the directory path for a variant inside a package.\n * MVP: resolves from local node_modules using require.resolve.\n *\n * @param packageName - e.g. \"@teamix-evo/tokens\"\n * @param variant - e.g. \"opentrek\"\n * @returns Absolute path to the variant directory (library/<variant>/)\n */\nexport function resolveVariantPackage(\n packageName: string,\n variant: string,\n): string {\n const pkgRoot = resolvePackageRoot(packageName);\n return path.join(pkgRoot, 'library', variant);\n}\n\n/**\n * Load the variant manifest and _data.json for template rendering.\n *\n * @param packageName - e.g. \"@teamix-evo/tokens\"\n * @param variant - e.g. \"opentrek\"\n * @returns manifest and data for template rendering\n */\nexport async function loadVariantData(\n packageName: string,\n variant: string,\n): Promise<{\n manifest: VariantManifest;\n data: Record<string, unknown>;\n variantDir: string;\n packageRoot: string;\n}> {\n const packageRoot = resolvePackageRoot(packageName);\n const variantDir = path.join(packageRoot, 'library', variant);\n\n logger.debug(`Resolved variant dir: ${variantDir}`);\n logger.debug(`Package root: ${packageRoot}`);\n\n // Load manifest\n const manifest = await loadVariantManifest(variantDir);\n\n // Load _data.json\n let data: Record<string, unknown> = {};\n const dataPath = path.join(variantDir, '_data.json');\n try {\n const raw = await fs.readFile(dataPath, 'utf-8');\n data = JSON.parse(raw) as Record<string, unknown>;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw err;\n }\n logger.debug(`No _data.json found at ${dataPath}, using empty data`);\n }\n\n return { manifest, data, variantDir, packageRoot };\n}\n"],"mappings":"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","names":["path","fs","rel","path","path","fs","require","path","fs","path","os","path","fs","path","fs","createRequire","require","require","stat","rel","targetFile","newContent","exists","written","path","DEFAULT_SKILLS_PACKAGE","DEFAULT_SKILLS_PACKAGE","FLAT_VARIANT","entry","path","fs","createRequire","require","createRequire","resolvePackageRoot","path","fs","DEFAULT_UI_PACKAGE","path","createRequire","loadUiPackageManifest","require","createRequire","resolvePackageRoot","loadUiPackageManifest","mergeResources","path","fs","rel","fs","path","hasManagedRegion","replaceManagedRegion","hasManagedRegion","replaceManagedRegion","fs","path","fs","path","stat","rel","fs","path","fs","path","rel","path","path","fs","path","fs","createRequire","require","createRequire","resolvePackageRoot","resolvePackageRoot"]}
|
|
1
|
+
{"version":3,"sources":["../../src/core/tokens-init.ts","../../src/utils/fs.ts","../../src/utils/logger.ts","../../src/utils/hash.ts","../../src/core/state.ts","../../src/utils/error.ts","../../src/core/skills-client.ts","../../src/core/skills-installer.ts","../../src/ide/QoderAdapter.ts","../../src/ide/ClaudeAdapter.ts","../../src/ide/index.ts","../../src/utils/template.ts","../../src/utils/path.ts","../../src/core/skills-add.ts","../../src/core/agents-md.ts","../../src/core/skills-update.ts","../../src/core/ui-init.ts","../../src/core/ui-client.ts","../../src/core/ui-installer.ts","../../src/utils/transform-imports.ts","../../src/core/ui-add.ts","../../src/core/ui-list.ts","../../src/core/variant-ui-add.ts","../../src/core/lint-init.ts","../../src/core/init-detect.ts","../../src/core/project-state.ts","../../src/core/command-guard.ts","../../src/core/init-conflicts.ts","../../src/core/meta-installer.ts","../../src/core/deps-install.ts","../../src/core/init-checklist-template.ts","../../src/core/file-changes.ts","../../src/core/project-init.ts","../../src/core/installer.ts","../../src/core/registry-client.ts"],"sourcesContent":["/**\n * Programmatic tokens init — installs one variant's token files into the\n * consumer's project root `tokens/` directory.\n *\n * Per [ADR 0020](../../../../docs/adr/0020-design-to-tokens-skill-fusion.md)\n * the install model is now a flat copy: each variant in `@teamix-evo/tokens`\n * advertises its files in the package manifest; for each advertised file we\n * copy by basename into `<projectRoot>/tokens/`:\n *\n * variants/<variant>/theme.css → tokens/tokens.theme.css (regenerable)\n * variants/<variant>/base.tokens.json → (kept in package only — reference data)\n *\n * Plus we always ensure `tokens/tokens.overrides.css` exists at the consumer\n * (created empty if absent, frozen thereafter so user edits are preserved\n * across re-installs).\n *\n * No walk-and-merge, no `default` baseline — every variant is a\n * self-contained token set per ADR 0020 §3.\n */\nimport * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport {\n loadTokensPackageManifest,\n getVariantEntry,\n type TokensPackLock,\n type InstalledManifest,\n type InstalledResource,\n type ProjectConfig,\n type UpdateStrategy,\n} from '@teamix-evo/registry';\nimport { backupFile, writeFileSafe, fileExists } from '../utils/fs.js';\nimport { computeHash } from '../utils/hash.js';\nimport {\n ensureTeamixDir,\n readProjectConfig,\n writeProjectConfig,\n readInstalledManifest,\n writeInstalledManifest,\n} from './state.js';\nimport { runSkillsAdd } from './skills-add.js';\nimport { loadSkillsData } from './skills-client.js';\nimport { logger } from '../utils/logger.js';\nimport type { SkillIde, SkillScope } from '@teamix-evo/registry';\nimport { resolveTokensPackageRoot } from '../utils/path.js';\nimport { getErrorMessage } from '../utils/error.js';\n\nconst DEFAULT_SKILLS_PACKAGE = '@teamix-evo/skills';\nconst DEFAULT_AUTO_SKILL_IDES: SkillIde[] = ['qoder', 'claude'];\nconst DEFAULT_AUTO_SKILL_SCOPE: SkillScope = 'project';\n\nconst DEFAULT_TOKENS_PACKAGE = '@teamix-evo/tokens';\n\n/** Consumer-side directory where token files land. */\nconst CONSUMER_TOKENS_DIR = 'tokens';\n\n/** Consumer-side filename for the regenerable theme. */\nconst CONSUMER_THEME_FILE = 'tokens.theme.css';\n\n/** Consumer-side filename for the frozen user-owned override. */\nconst CONSUMER_OVERRIDES_FILE = 'tokens.overrides.css';\n\n/** Default empty content for a fresh `tokens.overrides.css`. */\nconst EMPTY_OVERRIDES_TEMPLATE = `/* User-owned token overrides — frozen on subsequent installs. */\n/* See @teamix-evo/tokens variant theme.css for available CSS custom properties. */\n`;\n\nexport interface RunTokensInitOptions {\n /** Absolute project root directory. */\n projectRoot: string;\n /** Tokens variant id (e.g. `\"opentrek\"`, `\"uni-manager\"`). */\n variant: string;\n /** IDE identifier written into config.json (e.g. `\"qoder\"`, `\"claude\"`). */\n ide: string;\n /** Override the tokens package name (defaults to `\"@teamix-evo/tokens\"`). */\n packageName?: string;\n /**\n * Override resolution of the tokens package root. When provided, skips\n * `require.resolve(\"<packageName>/package.json\")`. Useful for tests that\n * want to point at a fixture tree, and for embedding inside `create`\n * where the package may not yet be installed in the consumer.\n */\n packageRoot?: string;\n}\n\n/**\n * Outcome of the post-init skill auto-install step. `attempted` is the variant\n * skill id we tried to install; `addedSkillIds` is what was actually installed\n * (empty if the skill was already present); `missing` lists ids that aren't in\n * the manifest (warned, not fatal). Per ADR / \"skills self-contained\" decision,\n * each variant skill is fully self-contained — no separate baseline skill.\n */\nexport interface SkillsAutoInstallResult {\n attempted: string[];\n addedSkillIds: string[];\n skippedSkillIds: string[];\n missing: string[];\n}\n\nexport type RunTokensInitResult =\n | {\n status: 'installed';\n packageName: string;\n variant: string;\n version: string;\n count: number;\n resources: InstalledResource[];\n /** Result of the auto-install of the matching design skill. */\n skills?: SkillsAutoInstallResult;\n }\n | {\n status: 'already-initialized';\n existingVariant: string;\n }\n | {\n status: 'variant-mismatch';\n existingVariant: string;\n requestedVariant: string;\n };\n\n/**\n * Programmatic equivalent of `teamix-evo tokens init <variant>`.\n *\n * Side effects:\n * - Creates `<projectRoot>/.teamix-evo/`\n * - Copies the variant's `theme.css` to `<projectRoot>/tokens/tokens.theme.css`\n * - Ensures `<projectRoot>/tokens/tokens.overrides.css` exists (frozen)\n * - Writes `tokens-lock.json`, `config.json`, `manifest.json` (installed)\n *\n * No interactive prompts, no `process.exit`. Throws on hard failure (P8).\n */\nexport async function runTokensInit(\n options: RunTokensInitOptions,\n): Promise<RunTokensInitResult> {\n const { projectRoot, variant, ide } = options;\n const packageName = options.packageName ?? DEFAULT_TOKENS_PACKAGE;\n\n await ensureTeamixDir(projectRoot);\n\n // Resolve the catalog up front so variant-name validation runs before any\n // state-driven branching (#P2-3). An unknown variant should produce a\n // clear \"Unknown variant\" error regardless of whether tokens are already\n // installed for the project.\n const packageRoot =\n options.packageRoot ?? resolveTokensPackageRoot(packageName);\n const catalog = await loadTokensPackageManifest(packageRoot);\n const variantEntry = getVariantEntry(catalog, variant);\n if (!variantEntry) {\n const known = catalog.variants.map((v) => v.name).join(', ');\n throw new Error(\n `Unknown variant \"${variant}\". Available variants: ${\n known || '(none)'\n }.\\nRun \\`npx teamix-evo@latest tokens list-variants\\` to see all options.`,\n );\n }\n\n // Variant-switching guard: if a different variant is already installed,\n // require the user to explicitly uninstall first (#15). Same-variant re-init\n // is a no-op (already-initialized).\n const existingConfig = await readProjectConfig(projectRoot);\n if (existingConfig?.packages?.tokens) {\n const existingVariant = existingConfig.packages.tokens.variant;\n if (existingVariant === variant) {\n return { status: 'already-initialized', existingVariant };\n }\n return {\n status: 'variant-mismatch',\n existingVariant,\n requestedVariant: variant,\n };\n }\n\n // Install advertised files by basename → consumer tokens/ directory.\n const installed: InstalledResource[] = [];\n for (const fileRel of variantEntry.files) {\n const result = await installVariantFile(fileRel, packageRoot, projectRoot);\n if (result) installed.push(result);\n }\n\n // Always ensure the user-owned overrides file exists (frozen).\n const overridesAbs = path.join(\n projectRoot,\n CONSUMER_TOKENS_DIR,\n CONSUMER_OVERRIDES_FILE,\n );\n if (!(await fileExists(overridesAbs))) {\n await writeFileSafe(overridesAbs, EMPTY_OVERRIDES_TEMPLATE);\n }\n // Dedup: only add overrides resource if installVariantFile didn't already\n // register it (happens when the variant ships an overrides.css file).\n const overridesId = `tokens:${CONSUMER_OVERRIDES_FILE}`;\n if (!installed.some((r) => r.id === overridesId)) {\n const overridesContent = await fs.readFile(overridesAbs, 'utf-8');\n installed.push({\n id: overridesId,\n target: path.posix.join(CONSUMER_TOKENS_DIR, CONSUMER_OVERRIDES_FILE),\n hash: computeHash(overridesContent),\n strategy: 'frozen',\n });\n }\n\n // Write consumer-side state files.\n const lock: TokensPackLock = {\n schemaVersion: 1,\n variant: {\n name: variantEntry.name,\n displayName: variantEntry.displayName,\n version: variantEntry.version,\n from: packageName,\n },\n packageVersion: catalog.version,\n linked: variantEntry.linked,\n installedAt: new Date().toISOString(),\n };\n await writeFileSafe(\n path.join(projectRoot, '.teamix-evo', 'tokens-lock.json'),\n JSON.stringify(lock, null, 2) + '\\n',\n );\n\n // Merge into existing config so unrelated package entries (skills / ui)\n // aren't clobbered (#18).\n const config: ProjectConfig = {\n $schema: 'https://teamix-evo.dev/schema/config/v2.json',\n schemaVersion: 2,\n ide: existingConfig?.ide ?? ide,\n packages: {\n ...(existingConfig?.packages ?? {}),\n tokens: {\n variant,\n version: variantEntry.version,\n tailwind: 'v4',\n },\n },\n };\n await writeProjectConfig(projectRoot, config);\n\n // Merge into existing installed manifest so other packages (ui / biz-ui)\n // recorded earlier are preserved.\n const prior = (await readInstalledManifest(projectRoot)) ?? {\n schemaVersion: 1 as const,\n installed: [],\n };\n const tokensIdx = prior.installed.findIndex((p) => p.package === packageName);\n const tokensEntry = {\n package: packageName,\n variant,\n version: variantEntry.version,\n installedAt: new Date().toISOString(),\n resources: installed,\n };\n if (tokensIdx >= 0) prior.installed[tokensIdx] = tokensEntry;\n else prior.installed.push(tokensEntry);\n await writeInstalledManifest(projectRoot, prior);\n\n // After the lock + manifest are persisted, auto-install matching skills.\n // Failures here do NOT roll back the install — the skill layer is additive,\n // and the user can always re-run `skills init` (bulk) or `skills add <id>`\n // (incremental) manually.\n const skills = await tryAutoInstallVariantSkills({\n projectRoot,\n variant,\n ide,\n });\n\n return {\n status: 'installed',\n packageName,\n variant,\n version: variantEntry.version,\n count: installed.length,\n resources: installed,\n skills,\n };\n}\n\n/**\n * Auto-install the variant skill `teamix-evo-design-<variant>` (if present\n * in the skills manifest). Each variant skill is fully self-contained — no\n * separate baseline. A missing variant skill produces a warning, not a failure.\n */\nasync function tryAutoInstallVariantSkills(args: {\n projectRoot: string;\n variant: string;\n ide: string;\n}): Promise<SkillsAutoInstallResult> {\n const { projectRoot, variant, ide } = args;\n const variantSkillId = `teamix-evo-design-${variant}`;\n const desired = [variantSkillId];\n\n // Filter to skills actually present in the manifest. Anything missing\n // becomes a warning but is not fatal.\n let manifestSkillIds: Set<string>;\n try {\n const { manifest } = await loadSkillsData(DEFAULT_SKILLS_PACKAGE);\n manifestSkillIds = new Set(manifest.skills.map((s) => s.id));\n } catch (err) {\n logger.warn(\n `Skipping skills auto-install: could not load skills manifest (${getErrorMessage(\n err,\n )}).`,\n );\n return {\n attempted: [],\n addedSkillIds: [],\n skippedSkillIds: [],\n missing: desired,\n };\n }\n\n const present = desired.filter((id) => manifestSkillIds.has(id));\n const missing = desired.filter((id) => !manifestSkillIds.has(id));\n if (missing.length > 0) {\n logger.warn(\n `Skills auto-install: not found in manifest, skipping: ${missing.join(\n ', ',\n )}.`,\n );\n }\n if (present.length === 0) {\n return {\n attempted: desired,\n addedSkillIds: [],\n skippedSkillIds: [],\n missing,\n };\n }\n\n try {\n const result = await runSkillsAdd({\n projectRoot,\n names: present,\n ides: DEFAULT_AUTO_SKILL_IDES,\n scope: DEFAULT_AUTO_SKILL_SCOPE,\n ide,\n });\n if (result.status !== 'installed') {\n return {\n attempted: desired,\n addedSkillIds: [],\n skippedSkillIds: present,\n missing,\n };\n }\n return {\n attempted: desired,\n addedSkillIds: result.addedSkillIds,\n skippedSkillIds: result.skippedSkillIds,\n missing,\n };\n } catch (err) {\n logger.warn(\n `Skills auto-install failed (continuing): ${getErrorMessage(err)}`,\n );\n return {\n attempted: desired,\n addedSkillIds: [],\n skippedSkillIds: [],\n missing,\n };\n }\n}\n\n/**\n * Install one advertised variant file. Mapping by basename:\n *\n * theme.css → consumer `tokens/tokens.theme.css` (regenerable)\n * overrides.css → consumer `tokens/tokens.overrides.css` (frozen, see runTokensInit)\n * anything else → skipped (reference data — kept in npm package only)\n *\n * The `overrides.css` source file is rare today (variants don't ship one),\n * but the mapping is here so authors can opt in. The \"always-create\" path in\n * `runTokensInit` covers the normal case where no source override is present.\n */\nasync function installVariantFile(\n fileRelToPackage: string,\n packageRoot: string,\n projectRoot: string,\n): Promise<InstalledResource | null> {\n const sourceAbs = path.join(packageRoot, fileRelToPackage);\n const base = path.basename(fileRelToPackage);\n\n if (base === 'theme.css') {\n const targetRel = path.posix.join(CONSUMER_TOKENS_DIR, CONSUMER_THEME_FILE);\n const targetAbs = path.join(projectRoot, targetRel);\n const content = await fs.readFile(sourceAbs, 'utf-8');\n // Phase 1.A2: theme.css is regenerable but users sometimes hand-edit it.\n // Stash any pre-existing copy under .teamix-evo/.backups/ before we\n // overwrite so a stale-state recovery is always possible.\n if (await fileExists(targetAbs)) {\n await backupFile(targetAbs, projectRoot);\n }\n await writeFileSafe(targetAbs, content);\n return {\n id: `tokens:${CONSUMER_THEME_FILE}`,\n target: targetRel,\n hash: computeHash(content),\n strategy: 'regenerable',\n };\n }\n\n if (base === 'overrides.css' || base === 'tokens.overrides.css') {\n const targetRel = path.posix.join(\n CONSUMER_TOKENS_DIR,\n CONSUMER_OVERRIDES_FILE,\n );\n const targetAbs = path.join(projectRoot, targetRel);\n if (await fileExists(targetAbs)) {\n // Frozen — leave the user's customization alone.\n const existing = await fs.readFile(targetAbs, 'utf-8');\n return {\n id: `tokens:${CONSUMER_OVERRIDES_FILE}`,\n target: targetRel,\n hash: computeHash(existing),\n strategy: 'frozen',\n };\n }\n const content = await fs.readFile(sourceAbs, 'utf-8');\n await writeFileSafe(targetAbs, content);\n return {\n id: `tokens:${CONSUMER_OVERRIDES_FILE}`,\n target: targetRel,\n hash: computeHash(content),\n strategy: 'frozen',\n };\n }\n\n // Reference data (e.g. base.tokens.json) — kept in the npm package only.\n return null;\n}\n\n/**\n * List all variants advertised by the top-level tokens catalog. Used by\n * `teamix-evo tokens list-variants`.\n */\nexport interface ListVariantsResult {\n packageName: string;\n packageVersion: string;\n variants: Array<{\n name: string;\n displayName: string;\n version: string;\n description?: string;\n linked?: { 'biz-ui'?: string };\n }>;\n}\n\nexport async function listTokenVariants(\n packageName: string = DEFAULT_TOKENS_PACKAGE,\n packageRoot?: string,\n): Promise<ListVariantsResult> {\n const root = packageRoot ?? resolveTokensPackageRoot(packageName);\n const catalog = await loadTokensPackageManifest(root);\n return {\n packageName,\n packageVersion: catalog.version,\n variants: catalog.variants.map((v) => ({\n name: v.name,\n displayName: v.displayName,\n version: v.version,\n description: v.description,\n linked: v.linked,\n })),\n };\n}\n\n// Re-export the strategy enum constituents so consumers don't have to import\n// from registry separately.\nexport type { UpdateStrategy };\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { logger } from \"./logger.js\";\n\n/**\n * Recursively create a directory (like mkdir -p).\n */\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\n/**\n * Atomic write: write to a .tmp file first, then rename.\n */\nexport async function writeFileSafe(\n filePath: string,\n content: string,\n): Promise<void> {\n const dir = path.dirname(filePath);\n await ensureDir(dir);\n const tmp = filePath + \".tmp\";\n await fs.writeFile(tmp, content, \"utf-8\");\n await fs.rename(tmp, filePath);\n}\n\n/**\n * Read a file or return null if it doesn't exist.\n */\nexport async function readFileOrNull(\n filePath: string,\n): Promise<string | null> {\n try {\n return await fs.readFile(filePath, \"utf-8\");\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n return null;\n }\n throw err;\n }\n}\n\n/**\n * Create a backup of a file under `.teamix-evo/.backups/`.\n */\nexport async function backupFile(\n filePath: string,\n projectRoot: string,\n): Promise<void> {\n const content = await readFileOrNull(filePath);\n if (content === null) {\n logger.debug(`Skip backup: ${filePath} does not exist`);\n return;\n }\n\n const rel = path.relative(projectRoot, filePath);\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backupPath = path.join(\n projectRoot,\n \".teamix-evo\",\n \".backups\",\n `${rel}.${timestamp}.bak`,\n );\n\n await ensureDir(path.dirname(backupPath));\n await fs.writeFile(backupPath, content, \"utf-8\");\n logger.debug(`Backed up ${rel} → ${path.relative(projectRoot, backupPath)}`);\n}\n\n/**\n * Check whether a file exists.\n */\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n","import { red, yellow, cyan, green, gray } from \"kolorist\";\n\nconst isDebug = process.env.TEAMIX_DEBUG === \"1\";\n\nexport const logger = {\n info(msg: string): void {\n console.log(cyan(\"ℹ\"), msg);\n },\n\n warn(msg: string): void {\n console.warn(yellow(\"⚠\"), msg);\n },\n\n error(msg: string): void {\n console.error(red(\"✖\"), msg);\n },\n\n success(msg: string): void {\n console.log(green(\"✔\"), msg);\n },\n\n debug(msg: string): void {\n if (isDebug) {\n console.log(gray(\"⊡\"), gray(msg));\n }\n },\n};\n","import { createHash } from \"node:crypto\";\n\n/**\n * Compute a SHA-256 hash of the given content.\n * Returns a string in the format \"sha256:<hex>\".\n */\nexport function computeHash(content: string): string {\n const hash = createHash(\"sha256\").update(content, \"utf-8\").digest(\"hex\");\n return `sha256:${hash}`;\n}\n","import * as path from 'node:path';\nimport type {\n ProjectConfig,\n InstalledManifest,\n InstalledPackage,\n SkillsLock,\n TokensPackLock,\n} from '@teamix-evo/registry';\nimport {\n validateConfig,\n validateInstalled,\n validateSkillsLock,\n TokensPackLockSchema,\n} from '@teamix-evo/registry';\nimport * as fs from 'node:fs/promises';\nimport { readFileOrNull, writeFileSafe, ensureDir } from '../utils/fs.js';\nimport { getErrorMessage } from '../utils/error.js';\nimport { logger } from '../utils/logger.js';\n\nconst TEAMIX_DIR = '.teamix-evo';\nconst CONFIG_FILE = 'config.json';\nconst MANIFEST_FILE = 'manifest.json';\nconst TOKENS_LOCK_FILE = 'tokens-lock.json';\nconst SKILLS_LOCK_FILE = 'skills-lock.json';\n\n/** Legacy paths for one-shot lock file migration. */\nconst LEGACY_SKILLS_LOCK_PATHS = [\n path.join('skills-source', 'manifest.lock.json'),\n path.join('skills', 'manifest.lock.json'),\n];\n\n/**\n * Get the .teamix-evo directory path for a project.\n */\nexport function getTeamixDir(projectRoot: string): string {\n return path.join(projectRoot, TEAMIX_DIR);\n}\n\n/**\n * Ensure the .teamix-evo directory exists.\n */\nexport async function ensureTeamixDir(projectRoot: string): Promise<string> {\n const dir = getTeamixDir(projectRoot);\n await ensureDir(dir);\n return dir;\n}\n\n/**\n * Read the project config from .teamix-evo/config.json.\n * Returns null if the file does not exist; THROWS on corrupted content\n * so callers don't silently clobber prior config (#32 #18).\n */\nexport async function readProjectConfig(\n projectRoot: string,\n): Promise<ProjectConfig | null> {\n const configPath = path.join(projectRoot, TEAMIX_DIR, CONFIG_FILE);\n const raw = await readFileOrNull(configPath);\n if (raw === null) return null;\n\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch (err) {\n throw new Error(\n `Corrupted config.json (${getErrorMessage(err)}). ` +\n `Fix the JSON manually or remove the file to start fresh; refusing to clobber prior config.`,\n );\n }\n const result = validateConfig(data);\n if (!result.success) {\n throw new Error(\n `Invalid config.json schema: ${result.error}. ` +\n `Fix the file manually or remove it to start fresh.`,\n );\n }\n return result.data;\n}\n\n/**\n * Write the project config to .teamix-evo/config.json.\n */\nexport async function writeProjectConfig(\n projectRoot: string,\n config: ProjectConfig,\n): Promise<void> {\n const configPath = path.join(projectRoot, TEAMIX_DIR, CONFIG_FILE);\n await writeFileSafe(configPath, JSON.stringify(config, null, 2) + '\\n');\n logger.debug(`Wrote config → ${configPath}`);\n}\n\n/**\n * Read the installed manifest from .teamix-evo/manifest.json.\n * Returns null if the file does not exist; THROWS on corrupted content so\n * callers don't silently lose prior installs by treating broken JSON as\n * \"fresh install\" (#32 #18). Use `readInstalledManifestOrNull` for the\n * old lenient behavior.\n */\nexport async function readInstalledManifest(\n projectRoot: string,\n): Promise<InstalledManifest | null> {\n const manifestPath = path.join(projectRoot, TEAMIX_DIR, MANIFEST_FILE);\n const raw = await readFileOrNull(manifestPath);\n if (raw === null) return null;\n\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch (err) {\n throw new Error(\n `Corrupted manifest.json (${getErrorMessage(err)}). ` +\n `Fix the JSON manually or remove the file to start fresh; refusing to clobber prior install records.`,\n );\n }\n const result = validateInstalled(data);\n if (!result.success) {\n throw new Error(\n `Invalid manifest.json schema: ${result.error}. ` +\n `Fix the file manually or remove it to start fresh.`,\n );\n }\n return result.data;\n}\n\n/**\n * Write the installed manifest to .teamix-evo/manifest.json.\n */\nexport async function writeInstalledManifest(\n projectRoot: string,\n manifest: InstalledManifest,\n): Promise<void> {\n const manifestPath = path.join(projectRoot, TEAMIX_DIR, MANIFEST_FILE);\n await writeFileSafe(manifestPath, JSON.stringify(manifest, null, 2) + '\\n');\n logger.debug(`Wrote manifest → ${manifestPath}`);\n}\n\n/**\n * Read .teamix-evo/tokens-lock.json. Returns null if missing or invalid.\n */\nexport async function readTokensLock(\n projectRoot: string,\n): Promise<TokensPackLock | null> {\n const lockPath = path.join(projectRoot, TEAMIX_DIR, TOKENS_LOCK_FILE);\n const raw = await readFileOrNull(lockPath);\n if (raw === null) return null;\n try {\n const parsed = TokensPackLockSchema.safeParse(JSON.parse(raw));\n if (!parsed.success) {\n logger.warn(`Invalid tokens-lock.json: ${parsed.error.message}`);\n return null;\n }\n return parsed.data;\n } catch (err) {\n logger.warn(`Failed to parse tokens-lock.json: ${getErrorMessage(err)}`);\n return null;\n }\n}\n\n/**\n * Convenience: read just the variant id from tokens-lock.json. Returns null\n * when no tokens variant has been installed.\n */\nexport async function readTokensVariant(\n projectRoot: string,\n): Promise<string | null> {\n const lock = await readTokensLock(projectRoot);\n return lock?.variant.name ?? null;\n}\n\n/**\n * Read .teamix-evo/skills-lock.json. Returns null if missing.\n */\nexport async function readSkillsLock(\n projectRoot: string,\n): Promise<SkillsLock | null> {\n const lockPath = path.join(projectRoot, TEAMIX_DIR, SKILLS_LOCK_FILE);\n const raw = await readFileOrNull(lockPath);\n if (raw === null) return null;\n try {\n const data = JSON.parse(raw);\n const result = validateSkillsLock(data);\n if (!result.success) {\n logger.warn(`Invalid skills-lock.json: ${result.error}`);\n return null;\n }\n return result.data;\n } catch (err) {\n logger.warn(\n `Failed to parse skills-lock.json: ${getErrorMessage(err)}`,\n );\n return null;\n }\n}\n\n/**\n * Write .teamix-evo/skills-lock.json.\n */\nexport async function writeSkillsLock(\n projectRoot: string,\n lock: SkillsLock,\n): Promise<void> {\n const lockPath = path.join(projectRoot, TEAMIX_DIR, SKILLS_LOCK_FILE);\n await writeFileSafe(lockPath, JSON.stringify(lock, null, 2) + '\\n');\n logger.debug(`Wrote skills lock → ${lockPath}`);\n}\n\n/**\n * One-shot migration: move the skills lock file from legacy locations\n * (`.teamix-evo/skills-source/manifest.lock.json` or\n * `.teamix-evo/skills/manifest.lock.json`) to the current\n * `.teamix-evo/skills-lock.json`. Also cleans up stale `skills-source/`\n * and `skills/` directories that are no longer needed.\n */\nexport async function migrateSkillsLockLocation(\n projectRoot: string,\n): Promise<void> {\n const newPath = path.join(projectRoot, TEAMIX_DIR, SKILLS_LOCK_FILE);\n try {\n await fs.access(newPath);\n // New lock already exists — skip migration, just clean up stale dirs.\n } catch {\n // New lock doesn't exist — try to migrate from legacy paths.\n for (const legacyRel of LEGACY_SKILLS_LOCK_PATHS) {\n const legacyPath = path.join(projectRoot, TEAMIX_DIR, legacyRel);\n try {\n await fs.access(legacyPath);\n await ensureDir(path.dirname(newPath));\n await fs.rename(legacyPath, newPath);\n logger.debug(`Migrated skills lock: ${legacyRel} → ${SKILLS_LOCK_FILE}`);\n break;\n } catch {\n continue;\n }\n }\n }\n\n // Clean up stale intermediate directories.\n for (const staleDir of ['skills-source', 'skills']) {\n const abs = path.join(projectRoot, TEAMIX_DIR, staleDir);\n try {\n await fs.rm(abs, { recursive: true, force: true });\n logger.debug(`Cleaned up stale dir: .teamix-evo/${staleDir}/`);\n } catch {\n // Best-effort; ignore.\n }\n }\n}\n\n/**\n * Look up an installed package record by package name.\n *\n * The {@link InstalledManifest} schema does not enforce uniqueness on the\n * `package` key — variant switches re-append a new record rather than\n * mutating the old one. We therefore return the **last** match (chronological\n * latest) and `null` when no record exists.\n *\n * Shared helper consumed by both {@link ui-upgrade-detector} and\n * {@link ui-upgrade-staging} to keep the lookup semantics aligned.\n */\nexport function findInstalledPackage(\n installed: InstalledManifest | null,\n packageName: string,\n): InstalledPackage | null {\n if (!installed) return null;\n const matches = installed.installed.filter((p) => p.package === packageName);\n if (matches.length === 0) return null;\n return matches[matches.length - 1] ?? null;\n}\n","/**\n * Safely extract an error message from an unknown thrown value.\n *\n * JavaScript allows `throw \"string\"` / `throw 42` / `throw null` — using\n * `(err as Error).message` directly is unsafe. This normaliser covers all\n * runtime cases.\n */\nexport function getErrorMessage(err: unknown): string {\n if (err instanceof Error) return err.message;\n if (typeof err === 'string') return err;\n try {\n return JSON.stringify(err);\n } catch {\n return String(err);\n }\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport type { SkillsPackageManifest } from '@teamix-evo/registry';\nimport { loadSkillsPackageManifest } from '@teamix-evo/registry';\nimport { logger } from '../utils/logger.js';\n\nconst require = createRequire(import.meta.url);\n\n/**\n * Resolve the package root directory for the skills package.\n */\nfunction resolvePackageRoot(packageName: string): string {\n const pkgJsonPath = require.resolve(`${packageName}/package.json`);\n return path.dirname(pkgJsonPath);\n}\n\n/**\n * Load the skills package manifest and optional shared `_data.json`.\n *\n * @param packageName - e.g. \"@teamix-evo/skills\"\n */\nexport async function loadSkillsData(packageName: string): Promise<{\n manifest: SkillsPackageManifest;\n data: Record<string, unknown>;\n packageRoot: string;\n}> {\n const packageRoot = resolvePackageRoot(packageName);\n\n logger.debug(`Resolved skills package root: ${packageRoot}`);\n\n const manifest = await loadSkillsPackageManifest(packageRoot);\n\n let data: Record<string, unknown> = {};\n const dataPath = path.join(packageRoot, '_data.json');\n try {\n const raw = await fs.readFile(dataPath, 'utf-8');\n data = JSON.parse(raw) as Record<string, unknown>;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw err;\n }\n logger.debug(`No _data.json found at ${dataPath}, using empty data`);\n }\n\n return { manifest, data, packageRoot };\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport type {\n SkillEntry,\n SkillsPackageManifest,\n InstalledResource,\n SkillIde,\n SkillScope,\n} from '@teamix-evo/registry';\nimport {\n replaceManagedRegion,\n hasManagedRegion,\n extractFrontmatter,\n replaceFrontmatter,\n} from '@teamix-evo/registry';\nimport { getAdapter } from '../ide/index.js';\nimport {\n writeFileSafe,\n readFileOrNull,\n fileExists,\n ensureDir,\n backupFile,\n} from '../utils/fs.js';\nimport { computeHash } from '../utils/hash.js';\nimport { renderTemplate, loadTemplateFile } from '../utils/template.js';\nimport { logger } from '../utils/logger.js';\nimport { getErrorMessage } from '../utils/error.js';\nimport { walkDir, resolveResourceTarget } from '../utils/path.js';\nimport {\n migrateSkillsLockLocation,\n} from './state.js';\n\n/**\n * Skills installer — renders upstream skill sources from the npm package\n * and writes directly to IDE mirror paths (`.qoder/skills/<id>/`,\n * `.claude/skills/<id>/`).\n */\n\nexport interface SkillInstallOptions {\n /** Project root directory */\n projectRoot: string;\n /** Skills package manifest */\n manifest: SkillsPackageManifest;\n /** Template data */\n data: Record<string, unknown>;\n /** Absolute skills package root */\n packageRoot: string;\n /** IDE kinds to install for (intersection with skill.ides is computed) */\n ides: readonly SkillIde[];\n /** Install scope */\n scope: SkillScope;\n /** Optional: limit to specific skill ids */\n onlyIds?: string[];\n}\n\nexport interface SkillInstallResult {\n resources: InstalledResource[];\n count: number;\n}\n\n/**\n * Install (or reinstall) all skills declared in the manifest.\n * Renders from the npm package and writes directly to IDE mirror paths.\n */\nexport async function installSkills(\n options: SkillInstallOptions,\n): Promise<SkillInstallResult> {\n await migrateSkillsLockLocation(options.projectRoot);\n\n const { manifest, ides, scope, onlyIds } = options;\n const installed: InstalledResource[] = [];\n\n const targets = manifest.skills.filter(\n (s) => !onlyIds || onlyIds.includes(s.id),\n );\n\n for (const skill of targets) {\n const skillIdes = skill.ides.filter((i) => ides.includes(i));\n if (skillIdes.length === 0) {\n logger.warn(\n `Skill \"${skill.name}\" supports [${skill.ides.join(\n ',',\n )}], no overlap with [${ides.join(',')}]; skipped.`,\n );\n continue;\n }\n\n const rendered = await renderSkillFiles(skill, options);\n\n for (const ide of skillIdes) {\n const records = await writeRenderedToIde(\n skill,\n rendered,\n ide,\n scope,\n options.projectRoot,\n );\n installed.push(...records);\n }\n }\n\n return { resources: installed, count: installed.length };\n}\n\n/**\n * Render upstream skill source(s) from the npm package into an in-memory map.\n * Does NOT write to disk. Returns `Map<relPath, content>`.\n */\nexport async function renderSkillFiles(\n skill: SkillEntry,\n options: { data: Record<string, unknown>; packageRoot: string },\n): Promise<Map<string, string>> {\n const { data, packageRoot } = options;\n const sourceAbs = path.resolve(packageRoot, skill.source);\n const stat = await fs.stat(sourceAbs);\n const rendered = new Map<string, string>();\n\n if (stat.isFile()) {\n const content = await renderSkillContent(sourceAbs, skill, data);\n rendered.set('SKILL.md', content);\n return rendered;\n }\n\n const entries = await walkDir(sourceAbs);\n for (const entry of entries) {\n let rel = path.relative(sourceAbs, entry);\n if (skill.template && rel.endsWith('.hbs')) {\n rel = rel.slice(0, -4);\n }\n const content =\n skill.template && entry.endsWith('.hbs')\n ? renderTemplate(await loadTemplateFile(entry), { ...data, skill })\n : await fs.readFile(entry, 'utf-8');\n rendered.set(rel, content);\n }\n return rendered;\n}\n\n/**\n * Write rendered skill files to a single IDE mirror path.\n * Uses managed-region-aware writing for existing files.\n */\nasync function writeRenderedToIde(\n skill: SkillEntry,\n rendered: Map<string, string>,\n ide: SkillIde,\n scope: SkillScope,\n projectRoot: string,\n): Promise<InstalledResource[]> {\n const adapter = getAdapter(ide);\n const targetDir = adapter.getSkillTargetDir(skill.name, scope, projectRoot);\n const records: InstalledResource[] = [];\n\n await ensureDir(targetDir);\n for (const [rel, sourceContent] of rendered) {\n const targetFile = path.join(targetDir, rel);\n\n const writtenContent = await writeMirrorContent(\n targetFile,\n sourceContent,\n skill.managedRegions,\n );\n records.push(\n makeMirrorRecord(skill, projectRoot, targetFile, writtenContent, ide, scope, rel),\n );\n logger.debug(` Wrote ${ide}:${scope}: ${targetFile}`);\n }\n return records;\n}\n\n/**\n * Write a file with optional managed-region preservation (#BUG-101).\n *\n * - Target absent → full write.\n * - `managedRegions` empty/undefined OR existing file has no matching\n * markers → full overwrite (with drift warning if content differs).\n * - Otherwise → replace each managed region's content, preserving content\n * outside markers.\n */\nasync function writeMirrorContent(\n targetFile: string,\n sourceContent: string,\n managedRegions: readonly string[] | undefined,\n): Promise<string> {\n const existing = await readFileOrNull(targetFile);\n\n if (existing === null) {\n await writeFileSafe(targetFile, sourceContent);\n return sourceContent;\n }\n\n const regions = managedRegions ?? [];\n const matchedRegions = regions.filter((id) => hasManagedRegion(existing, id));\n\n if (matchedRegions.length === 0) {\n if (existing !== sourceContent) {\n logger.warn(\n `Drift detected at ${targetFile} — overwriting from upstream. ` +\n `Re-run \\`npx teamix-evo@latest skills sync\\` after any manual edits.`,\n );\n await writeFileSafe(targetFile, sourceContent);\n return sourceContent;\n }\n return existing;\n }\n\n let merged = existing;\n const upstreamFm = extractFrontmatter(sourceContent);\n if (upstreamFm) {\n merged = replaceFrontmatter(merged, upstreamFm);\n }\n for (const id of matchedRegions) {\n const newRegion = extractRegionBody(sourceContent, id);\n if (newRegion === null) continue;\n try {\n merged = replaceManagedRegion(merged, id, newRegion);\n } catch {\n // Region present in existing but pattern failed; skip safely.\n }\n }\n if (merged !== existing) {\n await writeFileSafe(targetFile, merged);\n }\n return merged;\n}\n\nfunction extractRegionBody(content: string, id: string): string | null {\n const re = new RegExp(\n `<!-- teamix-evo:managed:start id=\"${escapeRegExp(\n id,\n )}\" -->([\\\\s\\\\S]*?)<!-- teamix-evo:managed:end id=\"${escapeRegExp(\n id,\n )}\" -->`,\n );\n const m = content.match(re);\n if (!m) return null;\n return m[1]!.replace(/^\\n/, '').replace(/\\n$/, '');\n}\n\nasync function renderSkillContent(\n sourceAbs: string,\n skill: SkillEntry,\n data: Record<string, unknown>,\n): Promise<string> {\n if (skill.template ?? sourceAbs.endsWith('.hbs')) {\n const tpl = await loadTemplateFile(sourceAbs);\n return renderTemplate(tpl, { ...data, skill });\n }\n return fs.readFile(sourceAbs, 'utf-8');\n}\n\nfunction makeMirrorRecord(\n skill: SkillEntry,\n projectRoot: string,\n targetAbs: string,\n content: string,\n ide: SkillIde,\n scope: SkillScope,\n rel?: string,\n): InstalledResource {\n const id = rel && rel !== 'SKILL.md' ? `${skill.id}:${rel}` : skill.id;\n return {\n id,\n target: path.relative(projectRoot, targetAbs),\n hash: computeHash(content),\n strategy: skill.updateStrategy,\n ide,\n scope,\n };\n}\n\nexport interface SkillUpdateOptions extends SkillInstallOptions {\n installed?: InstalledResource[];\n onlyIds?: string[];\n}\n\nexport interface SkillUpdateResult {\n resources: InstalledResource[];\n summary: {\n overwritten: number;\n managed: number;\n skipped: number;\n created: number;\n };\n}\n\n/**\n * Update skills with strategy-aware logic (frozen/regenerable/managed) applied\n * directly to IDE mirror files.\n */\nexport async function updateSkills(\n options: SkillUpdateOptions,\n): Promise<SkillUpdateResult> {\n const { manifest, ides, scope, projectRoot } = options;\n const idFilter = options.onlyIds ? new Set(options.onlyIds) : null;\n const summary = { overwritten: 0, managed: 0, skipped: 0, created: 0 };\n const updated: InstalledResource[] = [];\n\n for (const skill of manifest.skills) {\n if (idFilter && !idFilter.has(skill.id)) continue;\n const skillIdes = skill.ides.filter((i) => ides.includes(i));\n if (skillIdes.length === 0) continue;\n\n const rendered = await renderSkillFiles(skill, options);\n\n for (const ide of skillIdes) {\n const records = await updateRenderedInIde(\n skill,\n rendered,\n ide,\n scope,\n projectRoot,\n summary,\n );\n updated.push(...records);\n }\n }\n\n return { resources: updated, summary };\n}\n\n/**\n * Apply strategy-aware update logic to each rendered file in a single IDE path.\n */\nasync function updateRenderedInIde(\n skill: SkillEntry,\n rendered: Map<string, string>,\n ide: SkillIde,\n scope: SkillScope,\n projectRoot: string,\n summary: SkillUpdateResult['summary'],\n): Promise<InstalledResource[]> {\n const adapter = getAdapter(ide);\n const targetDir = adapter.getSkillTargetDir(skill.name, scope, projectRoot);\n const records: InstalledResource[] = [];\n\n await ensureDir(targetDir);\n for (const [rel, newContent] of rendered) {\n const targetFile = path.join(targetDir, rel);\n const exists = await fileExists(targetFile);\n\n const written = await rewriteSingleFile({\n targetFile,\n newContent,\n exists,\n updateStrategy: skill.updateStrategy,\n managedRegions: skill.managedRegions,\n projectRoot,\n summary,\n });\n records.push(makeMirrorRecord(skill, projectRoot, targetFile, written, ide, scope, rel));\n }\n return records;\n}\n\n/**\n * Apply updateStrategy logic to a single file.\n * Returns the content actually on disk after the operation.\n */\nasync function rewriteSingleFile(args: {\n targetFile: string;\n newContent: string;\n exists: boolean;\n updateStrategy: SkillEntry['updateStrategy'];\n managedRegions: readonly string[] | undefined;\n projectRoot: string;\n summary: SkillUpdateResult['summary'];\n}): Promise<string> {\n const {\n targetFile,\n newContent,\n exists,\n updateStrategy,\n managedRegions,\n projectRoot,\n summary,\n } = args;\n\n if (updateStrategy === 'frozen') {\n if (exists) {\n summary.skipped++;\n return (await readFileOrNull(targetFile)) ?? newContent;\n }\n await writeFileSafe(targetFile, newContent);\n summary.created++;\n return newContent;\n }\n\n if (updateStrategy === 'regenerable' || !exists) {\n if (exists) {\n await backupFile(targetFile, projectRoot);\n summary.overwritten++;\n } else {\n summary.created++;\n }\n await writeFileSafe(targetFile, newContent);\n return newContent;\n }\n\n // managed: preserve outside-region content from the existing file.\n const current = await readFileOrNull(targetFile);\n let merged = current ?? newContent;\n const upstreamFm = extractFrontmatter(newContent);\n if (upstreamFm) {\n merged = replaceFrontmatter(merged, upstreamFm);\n }\n for (const regionId of managedRegions ?? []) {\n const re = new RegExp(\n `<!-- teamix-evo:managed:start id=\"${escapeRegExp(\n regionId,\n )}\" -->([\\\\s\\\\S]*?)<!-- teamix-evo:managed:end id=\"${escapeRegExp(\n regionId,\n )}\" -->`,\n );\n const match = newContent.match(re);\n if (match) {\n const region = match[1]!.replace(/^\\n/, '').replace(/\\n$/, '');\n try {\n merged = replaceManagedRegion(merged, regionId, region);\n } catch {\n logger.warn(\n `Managed region \"${regionId}\" not found in ${targetFile}. Skipped.`,\n );\n }\n }\n }\n if (merged !== current) {\n await backupFile(targetFile, projectRoot);\n await writeFileSafe(targetFile, merged);\n }\n summary.managed++;\n return merged;\n}\n\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Re-install skills from the npm package to IDE mirror paths.\n * Used by `skills sync` to refresh IDE files from upstream.\n */\nexport interface ReinstallToIdesOptions {\n projectRoot: string;\n /** Skills to reinstall (caller derives from lock). */\n skills: ReadonlyArray<{\n id: string;\n name: string;\n updateStrategy: SkillEntry['updateStrategy'];\n managedRegions?: readonly string[];\n }>;\n /** Upstream package data for rendering. */\n manifest: SkillsPackageManifest;\n data: Record<string, unknown>;\n packageRoot: string;\n ides: readonly SkillIde[];\n scope: SkillScope;\n}\n\nexport interface ReinstallToIdesResult {\n resources: InstalledResource[];\n count: number;\n}\n\n/**\n * Reinstall skills from npm package directly to IDE mirrors.\n */\nexport async function reinstallSkillsToIdes(\n options: ReinstallToIdesOptions,\n): Promise<ReinstallToIdesResult> {\n const { projectRoot, skills, manifest, data, packageRoot, ides, scope } = options;\n const out: InstalledResource[] = [];\n\n for (const skill of skills) {\n const entry = manifest.skills.find((s) => s.id === skill.id);\n if (!entry) {\n logger.warn(`Skill \"${skill.id}\" not found in npm package manifest; skipped.`);\n continue;\n }\n\n const rendered = await renderSkillFiles(entry, { data, packageRoot });\n\n for (const ide of ides) {\n const adapter = getAdapter(ide);\n const targetDir = adapter.getSkillTargetDir(skill.name, scope, projectRoot);\n await ensureDir(targetDir);\n\n for (const [rel, sourceContent] of rendered) {\n const targetFile = path.join(targetDir, rel);\n const writtenContent = await writeMirrorContent(\n targetFile,\n sourceContent,\n skill.managedRegions,\n );\n out.push({\n id: rel === 'SKILL.md' ? skill.id : `${skill.id}:${rel}`,\n target: path.relative(projectRoot, targetFile),\n hash: computeHash(writtenContent),\n strategy: skill.updateStrategy,\n ide,\n scope,\n });\n }\n }\n }\n return { resources: out, count: out.length };\n}\n\n/**\n * Prune empty IDE skill directories under each adapter's skill root.\n */\nexport async function pruneEmptyIdeSkillDirs(args: {\n projectRoot: string;\n ides: readonly SkillIde[];\n scope: SkillScope;\n}): Promise<string[]> {\n const removed: string[] = [];\n for (const ide of args.ides) {\n const adapter = getAdapter(ide);\n const placeholderDir = adapter.getSkillTargetDir(\n '__placeholder__',\n args.scope,\n args.projectRoot,\n );\n const skillsRoot = path.dirname(placeholderDir);\n let entries: string[];\n try {\n entries = await fs.readdir(skillsRoot);\n } catch {\n continue;\n }\n for (const name of entries) {\n const dir = path.join(skillsRoot, name);\n let stat;\n try {\n stat = await fs.stat(dir);\n } catch {\n continue;\n }\n if (!stat.isDirectory()) continue;\n let children: string[];\n try {\n children = await fs.readdir(dir);\n } catch {\n continue;\n }\n if (children.some((c) => c === 'SKILL.md')) continue;\n if (children.length !== 0) continue;\n try {\n await fs.rmdir(dir);\n removed.push(dir);\n logger.debug(`Pruned empty IDE skill dir: ${dir}`);\n } catch {\n // Best-effort; ignore.\n }\n }\n }\n return removed;\n}\n\n/**\n * Remove all installed skill files. Returns the absolute paths removed.\n */\nexport async function removeSkillFiles(\n records: InstalledResource[],\n projectRoot: string,\n): Promise<string[]> {\n const removed: string[] = [];\n for (const r of records) {\n const abs = resolveResourceTarget(projectRoot, r.target);\n try {\n await fs.unlink(abs);\n removed.push(abs);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n logger.warn(`Failed to remove ${abs}: ${getErrorMessage(err)}`);\n }\n }\n }\n const startDirs = new Set(\n records.map((r) => path.dirname(resolveResourceTarget(projectRoot, r.target))),\n );\n for (const startDir of startDirs) {\n let dir = startDir;\n for (let depth = 0; depth < 8; depth++) {\n try {\n const entries = await fs.readdir(dir);\n if (entries.length !== 0) break;\n await fs.rmdir(dir);\n } catch {\n break;\n }\n dir = path.dirname(dir);\n }\n }\n return removed;\n}\n","import * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { SkillScope } from '@teamix-evo/registry';\nimport type { IdeAdapter } from './IdeAdapter.js';\n\n/**\n * Qoder IDE adapter.\n * Skill paths:\n * - project: <projectRoot>/.qoder/skills/<name>/\n * - global: ~/.qoder/skills/<name>/\n */\nexport class QoderAdapter implements IdeAdapter {\n readonly kind = 'qoder' as const;\n readonly name = 'qoder';\n\n getProjectRoot(): string {\n return process.cwd();\n }\n\n detectIde(): boolean {\n // MVP: default to true. Future: check environment variables\n return true;\n }\n\n getSkillTargetDir(\n skillName: string,\n scope: SkillScope,\n projectRoot?: string,\n ): string {\n const base =\n scope === 'global'\n ? path.join(os.homedir(), '.qoder')\n : path.join(projectRoot ?? this.getProjectRoot(), '.qoder');\n return path.join(base, 'skills', skillName);\n }\n}\n","import * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { SkillScope } from '@teamix-evo/registry';\nimport type { IdeAdapter } from './IdeAdapter.js';\n\n/**\n * Claude Code IDE adapter.\n * Skill paths:\n * - project: <projectRoot>/.claude/skills/<name>/\n * - global: ~/.claude/skills/<name>/\n */\nexport class ClaudeAdapter implements IdeAdapter {\n readonly kind = 'claude' as const;\n readonly name = 'claude';\n\n getProjectRoot(): string {\n return process.cwd();\n }\n\n detectIde(): boolean {\n // Best-effort: presence of .claude/ in cwd or CLAUDECODE env var.\n return Boolean(process.env.CLAUDECODE);\n }\n\n getSkillTargetDir(\n skillName: string,\n scope: SkillScope,\n projectRoot?: string,\n ): string {\n const base =\n scope === 'global'\n ? path.join(os.homedir(), '.claude')\n : path.join(projectRoot ?? this.getProjectRoot(), '.claude');\n return path.join(base, 'skills', skillName);\n }\n}\n","import type { SkillIde } from '@teamix-evo/registry';\nimport type { IdeAdapter } from './IdeAdapter.js';\nimport { QoderAdapter } from './QoderAdapter.js';\nimport { ClaudeAdapter } from './ClaudeAdapter.js';\n\nexport type { IdeAdapter } from './IdeAdapter.js';\nexport { QoderAdapter } from './QoderAdapter.js';\nexport { ClaudeAdapter } from './ClaudeAdapter.js';\n\n/** All supported IDE kinds (also default selection set for skills) */\nexport const ALL_IDE_KINDS: readonly SkillIde[] = ['qoder', 'claude'] as const;\n\n/**\n * Get the adapter for a specific IDE kind.\n */\nexport function getAdapter(kind: SkillIde): IdeAdapter {\n switch (kind) {\n case 'qoder':\n return new QoderAdapter();\n case 'claude':\n return new ClaudeAdapter();\n default: {\n const _exhaustive: never = kind;\n throw new Error(`Unsupported IDE kind: ${_exhaustive as string}`);\n }\n }\n}\n\n/**\n * Detect the current IDE environment and return the appropriate adapter.\n * MVP: prefers Qoder; falls back to Claude if CLAUDECODE env is set.\n */\nexport function detectIde(): IdeAdapter {\n const claude = new ClaudeAdapter();\n if (claude.detectIde()) return claude;\n return new QoderAdapter();\n}\n","import Handlebars from 'handlebars';\nimport * as fs from 'node:fs/promises';\n\n// Register custom helpers\nHandlebars.registerHelper('lowercase', (str: unknown) => {\n return typeof str === 'string'\n ? str.toLowerCase()\n : String(str ?? '').toLowerCase();\n});\n\n/** LRU-style compilation cache to avoid recompiling the same template */\nconst compiledCache = new Map<string, HandlebarsTemplateDelegate>();\nconst MAX_CACHE_SIZE = 64;\n\nfunction getCompiledTemplate(\n templateContent: string,\n): HandlebarsTemplateDelegate {\n let compiled = compiledCache.get(templateContent);\n if (!compiled) {\n if (compiledCache.size >= MAX_CACHE_SIZE) {\n // Evict oldest entry\n const firstKey = compiledCache.keys().next().value!;\n compiledCache.delete(firstKey);\n }\n compiled = Handlebars.compile(templateContent, { noEscape: true });\n compiledCache.set(templateContent, compiled);\n }\n return compiled;\n}\n\n/**\n * Render a Handlebars template string with the given data.\n */\nexport function renderTemplate(\n templateContent: string,\n data: Record<string, unknown>,\n): string {\n const compiled = getCompiledTemplate(templateContent);\n return compiled(data);\n}\n\n/**\n * Load template file content from disk.\n */\nexport async function loadTemplateFile(filePath: string): Promise<string> {\n return fs.readFile(filePath, 'utf-8');\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport { createRequire } from 'node:module';\n\nconst require = createRequire(import.meta.url);\n\n/**\n * Resolve a source path — handles _template/ prefix by resolving from packageRoot.\n */\nexport function resolveSourcePath(\n source: string,\n variantDir: string,\n packageRoot: string,\n): string {\n if (source.startsWith('_template/')) {\n return path.join(packageRoot, source);\n }\n return path.join(variantDir, source);\n}\n\n/**\n * Common directory names to skip when walking user project trees.\n */\nexport const DEFAULT_SKIP_DIRS = new Set([\n 'node_modules',\n 'dist',\n 'build',\n '.teamix-evo',\n]);\n\n/**\n * Recursively walk a directory and return all file paths.\n * When `skipDirs` is provided, directories whose names are in the set will not\n * be entered — this avoids the cost of recursing into large trees like\n * `node_modules/` only to discard results later.\n */\nexport async function walkDir(\n dir: string,\n skipDirs?: Set<string>,\n): Promise<string[]> {\n const files: string[] = [];\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n if (skipDirs && skipDirs.has(entry.name)) continue;\n files.push(...(await walkDir(fullPath, skipDirs)));\n } else if (entry.isFile()) {\n files.push(fullPath);\n }\n }\n\n return files;\n}\n\n/**\n * Locate the root directory of an installed npm package by resolving its\n * `package.json`. Used to read token source CSS and variant manifests.\n */\nexport function resolveTokensPackageRoot(packageName: string): string {\n const pkgJson = require.resolve(`${packageName}/package.json`);\n return path.dirname(pkgJson);\n}\n\n/**\n * Resolve an InstalledResource `target` to an absolute path.\n * Handles both legacy absolute paths and new project-relative paths.\n */\nexport function resolveResourceTarget(\n projectRoot: string,\n target: string,\n): string {\n return path.isAbsolute(target) ? target : path.resolve(projectRoot, target);\n}\n","import type {\n ProjectConfig,\n InstalledManifest,\n InstalledResource,\n SkillIde,\n SkillScope,\n SkillsLock,\n SkillsPackageManifest,\n} from '@teamix-evo/registry';\nimport { loadSkillsData } from './skills-client.js';\nimport {\n installSkills,\n updateSkills,\n pruneEmptyIdeSkillDirs,\n} from './skills-installer.js';\nimport {\n ensureTeamixDir,\n readProjectConfig,\n writeProjectConfig,\n readInstalledManifest,\n writeInstalledManifest,\n readSkillsLock,\n writeSkillsLock,\n readTokensVariant,\n} from './state.js';\nimport { logger } from '../utils/logger.js';\n\nconst DEFAULT_SKILLS_PACKAGE = '@teamix-evo/skills';\nconst FLAT_VARIANT = '_flat';\n\n// ─── runSkillsInit ────────────────────────────────────────────────────────────\n// Bulk bootstrap: install every skill in the manifest that matches the current\n// tokens variant + install scope (per ADR 0033). No skill ids accepted —\n// granular adds go through `runSkillsAdd`. Verb split per ADR 0034.\n\nexport interface RunSkillsInitOptions {\n /** Absolute project root directory. */\n projectRoot: string;\n /** Target IDEs to inject skills into. Required (bulk has no fallback source). */\n ides: readonly SkillIde[];\n /** Install scope. Required (bulk has no fallback source). */\n scope: SkillScope;\n /** IDE identifier written into config.ide when bootstrapping a fresh config (defaults to \"qoder\"). */\n ide?: string;\n /** Override the skills package name (defaults to \"@teamix-evo/skills\"). */\n packageName?: string;\n}\n\nexport type RunSkillsInitResult =\n | {\n status: 'installed';\n packageName: string;\n version: string;\n ides: SkillIde[];\n scope: SkillScope;\n skillCount: number;\n fileCount: number;\n resources: InstalledResource[];\n addedSkillIds: string[];\n skippedSkillIds: string[];\n /**\n * Skill ids that were auto-upgraded because their locked version was\n * older than the manifest version.\n */\n autoUpdatedSkillIds: string[];\n /**\n * @deprecated Outdated skills are now auto-upgraded; kept for compat.\n */\n outdatedSkills: OutdatedSkillInfo[];\n }\n | {\n /** Returned when a skills package is already installed and bulk has nothing new to add. */\n status: 'already-initialized';\n };\n\n/**\n * Programmatic equivalent of `teamix-evo skills init`.\n *\n * Installs every manifest skill that matches the current tokens variant +\n * install scope (per ADR 0033 scope filter). Re-running on a project whose\n * `packages.skills` is already configured AND has no missing candidates\n * returns `'already-initialized'`.\n */\nexport async function runSkillsInit(\n options: RunSkillsInitOptions,\n): Promise<RunSkillsInitResult> {\n const { projectRoot } = options;\n const packageName = options.packageName ?? DEFAULT_SKILLS_PACKAGE;\n const ides = [...options.ides] as SkillIde[];\n const scope = options.scope;\n if (ides.length === 0) {\n throw new Error('At least one IDE must be selected.');\n }\n\n await ensureTeamixDir(projectRoot);\n const existingConfig = await readProjectConfig(projectRoot);\n const existingSkillsCfg = existingConfig?.packages?.skills;\n\n const { manifest, data, packageRoot } = await loadSkillsData(packageName);\n const currentTokensVariant = await readTokensVariant(projectRoot);\n\n const existing = await readExistingState(projectRoot, packageName);\n\n // ADR 0033 + tokens variant: filter manifest skills to those eligible for\n // this install scope and current variant.\n const candidateIds = manifest.skills\n .filter((s) => {\n const effectiveScope = s.scope ?? 'project';\n if (effectiveScope !== scope) {\n logger.debug(\n `Skipping skill \"${s.id}\" (scope=${effectiveScope}): current install scope is \"${scope}\". Use \\`skills add ${s.id} --scope ${effectiveScope}\\` to install.`,\n );\n return false;\n }\n if (!s.variant) return true;\n if (!currentTokensVariant) {\n logger.debug(\n `Skipping variant-bound skill \"${s.id}\" (variant=${s.variant}): no tokens variant installed; will be picked up when \"tokens init\" runs.`,\n );\n return false;\n }\n if (s.variant !== currentTokensVariant) {\n logger.debug(\n `Skipping variant-bound skill \"${s.id}\" (variant=${s.variant}): current tokens variant is \"${currentTokensVariant}\".`,\n );\n return false;\n }\n return true;\n })\n .map((s) => s.id);\n\n // Partition candidate skills the same way `runSkillsAdd` does: brand-new go\n // to `onlyIds`; already installed and at-or-above manifest version go to\n // `skippedSkillIds`; already installed but with `lock.version < manifest.version`\n // surface as `outdatedSkills` so callers can suggest `skills update <id>`.\n const { onlyIds, skippedSkillIds, outdatedSkills } = partitionByVersion(\n candidateIds,\n manifest,\n existing,\n );\n\n // Idempotent fast path: nothing new and nothing outdated. Preserve the\n // historical `already-initialized` status only when there's literally\n // nothing for the caller to act on; if any skill is outdated we fall\n // through to the empty-install fast path below so the upgrade hint is\n // surfaced to the CLI layer.\n if (\n existingSkillsCfg &&\n onlyIds.length === 0 &&\n outdatedSkills.length === 0\n ) {\n return { status: 'already-initialized' };\n }\n\n // Empty-install fast path mirrors `runSkillsAdd`: nothing new to install,\n // but at least one outdated skill needs to be auto-upgraded.\n if (onlyIds.length === 0) {\n let autoUpdatedSkillIds: string[] = [];\n if (outdatedSkills.length > 0) {\n autoUpdatedSkillIds = await autoUpgradeOutdatedSkills({\n projectRoot,\n packageName,\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n outdatedSkills,\n existing,\n existingConfig,\n });\n }\n return {\n status: 'installed',\n packageName,\n version: manifest.version,\n ides,\n scope,\n skillCount: 0,\n fileCount: 0,\n resources: [],\n addedSkillIds: [],\n skippedSkillIds,\n autoUpdatedSkillIds,\n outdatedSkills: [],\n };\n }\n\n return finalizeSkillsInstall({\n projectRoot,\n packageName,\n ideIdent: options.ide ?? 'qoder',\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n onlyIds,\n skippedSkillIds,\n outdatedSkills,\n existing,\n existingConfig,\n });\n}\n\n// ─── runSkillsAdd ─────────────────────────────────────────────────────────────\n// Incremental: install named skill ids. `names` is required (≥ 1).\n// Skills already present are skipped. ADR 0034.\n\nexport interface RunSkillsAddOptions {\n /** Absolute project root directory. */\n projectRoot: string;\n /**\n * Skill ids to add. **Required, must contain at least one id.** Use\n * {@link runSkillsInit} for bulk bootstrap (no ids).\n */\n names: readonly string[];\n /** Target IDEs. Optional — falls back to the previously installed config. */\n ides?: readonly SkillIde[];\n /** Install scope. Optional — falls back to existing config. */\n scope?: SkillScope;\n /** IDE identifier written into config.ide when bootstrapping a fresh config (defaults to \"qoder\"). */\n ide?: string;\n /** Override the skills package name (defaults to \"@teamix-evo/skills\"). */\n packageName?: string;\n}\n\n/**\n * Detail for an already-installed skill whose locked version is older than\n * the manifest's latest version. Use `skills update <id>` to upgrade.\n */\nexport interface OutdatedSkillInfo {\n /** Skill id */\n id: string;\n /** Version recorded in `.teamix-evo/skills.lock.json` */\n installed: string;\n /** Version available in the upstream manifest (i.e. `npx` resolved `@latest`) */\n latest: string;\n}\n\nexport type RunSkillsAddResult = {\n status: 'installed';\n packageName: string;\n version: string;\n ides: SkillIde[];\n scope: SkillScope;\n /** Number of skills that were freshly added in this call. */\n skillCount: number;\n /** Number of files written by `installSkills` for the freshly added skills. */\n fileCount: number;\n /** InstalledResource records for the freshly added skills only. */\n resources: InstalledResource[];\n /** Skill ids that were freshly added in this call. */\n addedSkillIds: string[];\n /**\n * Skill ids that were requested but already installed at the latest version;\n * nothing to do.\n */\n skippedSkillIds: string[];\n /**\n * Skill ids that were auto-upgraded because their locked version was older\n * than the manifest version.\n */\n autoUpdatedSkillIds: string[];\n /**\n * @deprecated Outdated skills are now auto-upgraded; this array is always\n * empty. Kept for backward-compatible callers; will be removed in next major.\n */\n outdatedSkills: OutdatedSkillInfo[];\n};\n\n/**\n * Programmatic equivalent of `teamix-evo skills add <names...>` (ADR 0034).\n *\n * Installs only the listed skills. Skills already present are skipped (use\n * `skills update` to refresh). `ides` / `scope` may be omitted — they fall\n * back to the previously installed config.\n *\n * Throws if `names` is empty — bulk bootstrap belongs to {@link runSkillsInit}.\n */\nexport async function runSkillsAdd(\n options: RunSkillsAddOptions,\n): Promise<RunSkillsAddResult> {\n if (!options.names || options.names.length === 0) {\n throw new Error(\n 'runSkillsAdd requires at least one skill id. Use runSkillsInit() for bulk install.',\n );\n }\n\n const { projectRoot, names: requestedNames } = options;\n const packageName = options.packageName ?? DEFAULT_SKILLS_PACKAGE;\n\n await ensureTeamixDir(projectRoot);\n\n const existingConfig = await readProjectConfig(projectRoot);\n const existingSkillsCfg = existingConfig?.packages?.skills;\n\n // Resolve ides/scope: explicit option wins, else fall back to existing config.\n const ides = (\n options.ides && options.ides.length > 0\n ? [...options.ides]\n : existingSkillsCfg?.ides\n ? [...existingSkillsCfg.ides]\n : []\n ) as SkillIde[];\n const scope = (options.scope ?? existingSkillsCfg?.scope) as\n | SkillScope\n | undefined;\n if (ides.length === 0) {\n throw new Error('At least one IDE must be selected.');\n }\n if (!scope) {\n throw new Error('Scope must be specified (project | global).');\n }\n\n const { manifest, data, packageRoot } = await loadSkillsData(packageName);\n\n // Validate requested names against manifest.\n const known = new Set(manifest.skills.map((s) => s.id));\n const unknown = requestedNames.filter((n) => !known.has(n));\n if (unknown.length > 0) {\n const available = [...known].join(', ');\n throw new Error(\n `Unknown skill id(s): ${unknown.join(', ')}. Available: ${\n available || '(none)'\n }.`,\n );\n }\n\n // ADR 0033: warn when explicitly naming a skill whose declared scope\n // doesn't match the current install scope. Don't block — explicit\n // naming overrides the default; user takes responsibility.\n for (const s of manifest.skills) {\n if (requestedNames.includes(s.id) && s.scope && s.scope !== scope) {\n logger.warn(\n `\"${s.id}\" 推荐 ${s.scope} scope 安装。当前以 ${scope} scope 强制安装,可能与另一 scope 的副本冲突。建议改用 \\`skills add ${s.id} --scope ${s.scope}\\`。`,\n );\n }\n }\n\n const existing = await readExistingState(projectRoot, packageName);\n\n // Partition requested names: already-installed-and-up-to-date go to\n // `skippedSkillIds`; already-installed-but-older go to `outdatedSkills`\n // (caller surfaces an upgrade hint); brand-new go to `onlyIds`.\n const { onlyIds, skippedSkillIds, outdatedSkills } = partitionByVersion(\n requestedNames,\n manifest,\n existing,\n );\n\n // Incremental fast path: nothing new to install. But if there are\n // outdated skills, auto-upgrade them before returning.\n if (onlyIds.length === 0) {\n let autoUpdatedSkillIds: string[] = [];\n if (outdatedSkills.length > 0) {\n autoUpdatedSkillIds = await autoUpgradeOutdatedSkills({\n projectRoot,\n packageName,\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n outdatedSkills,\n existing,\n existingConfig,\n });\n }\n return {\n status: 'installed',\n packageName,\n version: manifest.version,\n ides,\n scope,\n skillCount: 0,\n fileCount: 0,\n resources: [],\n addedSkillIds: [],\n skippedSkillIds,\n autoUpdatedSkillIds,\n outdatedSkills: [],\n };\n }\n\n return finalizeSkillsInstall({\n projectRoot,\n packageName,\n ideIdent: options.ide ?? 'qoder',\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n onlyIds,\n skippedSkillIds,\n outdatedSkills,\n existing,\n existingConfig,\n });\n}\n\n// ─── partition helper (shared by init + add) ────────────────────────────────\n// Split a list of skill ids into three buckets based on `existing` lock state\n// vs `manifest` version. `onlyIds` (new) → drives `installSkills`;\n// `skippedSkillIds` (already at latest) and `outdatedSkills` (lock < manifest)\n// are surfaced to the CLI for messaging. Pre-ADR-0013 legacy installs whose\n// lock is missing fall through to `skippedSkillIds` (conservative — don't\n// nag a user we can't reliably version-check).\nfunction partitionByVersion(\n ids: readonly string[],\n manifest: SkillsPackageManifest,\n existing: ExistingState,\n): {\n onlyIds: string[];\n skippedSkillIds: string[];\n outdatedSkills: OutdatedSkillInfo[];\n} {\n const manifestById = new Map(manifest.skills.map((s) => [s.id, s]));\n const onlyIds: string[] = [];\n const skippedSkillIds: string[] = [];\n const outdatedSkills: OutdatedSkillInfo[] = [];\n for (const name of ids) {\n if (!existing.skillIds.has(name)) {\n onlyIds.push(name);\n continue;\n }\n const installedVer = existing.lock?.skills?.[name]?.version;\n const latestVer = manifestById.get(name)?.version;\n if (\n installedVer &&\n latestVer &&\n compareSemver(installedVer, latestVer) < 0\n ) {\n outdatedSkills.push({\n id: name,\n installed: installedVer,\n latest: latestVer,\n });\n } else {\n skippedSkillIds.push(name);\n }\n }\n return { onlyIds, skippedSkillIds, outdatedSkills };\n}\n\n// ─── semver helpers (light, no dep) ───────────────────────────────────────────\n// Only needed by `runSkillsAdd` to decide whether an already-installed skill is\n// truly outdated (installed < manifest). We deliberately avoid pulling in a\n// `semver` runtime dep; manifest versions are validated against\n// `^\\d+\\.\\d+\\.\\d+/` by the registry schema, so a numeric major.minor.patch\n// triple is sufficient. Pre-release / build metadata is ignored — if two\n// versions share the same triple they're considered equal here.\nfunction parseSemverTriple(v: string): [number, number, number] | null {\n const m = /^(\\d+)\\.(\\d+)\\.(\\d+)/.exec(v);\n if (!m) return null;\n return [Number(m[1]), Number(m[2]), Number(m[3])];\n}\n\n/** -1 if a < b, 0 if equal (or unparseable + identical strings), 1 if a > b. */\nfunction compareSemver(a: string, b: string): number {\n const pa = parseSemverTriple(a);\n const pb = parseSemverTriple(b);\n if (!pa || !pb) {\n if (a === b) return 0;\n return a < b ? -1 : 1;\n }\n for (let i = 0; i < 3; i++) {\n if (pa[i]! !== pb[i]!) return pa[i]! < pb[i]! ? -1 : 1;\n }\n return 0;\n}\n\n// ─── shared internals ─────────────────────────────────────────────────────────\n\ninterface ExistingState {\n installed: InstalledManifest | null;\n pkg:\n | {\n package: string;\n resources: InstalledResource[];\n }\n | undefined;\n lock: SkillsLock | null;\n skillIds: Set<string>;\n}\n\nasync function readExistingState(\n projectRoot: string,\n packageName: string,\n): Promise<ExistingState> {\n const installed = await readInstalledManifest(projectRoot);\n const pkg = installed?.installed.find((p) => p.package === packageName);\n const lock = await readSkillsLock(projectRoot);\n const skillIds = new Set<string>([\n ...Object.keys(lock?.skills ?? {}),\n // Legacy fallback: pre-ADR-0013 installs only had manifest.json. Derive\n // skill ids by stripping the trailing :source / :sub-file suffix.\n ...(pkg?.resources ?? []).map((r) => r.id.split(':')[0] ?? r.id),\n ]);\n return { installed, pkg, lock, skillIds };\n}\n\ninterface FinalizeArgs {\n projectRoot: string;\n packageName: string;\n ideIdent: string;\n manifest: SkillsPackageManifest;\n data: Parameters<typeof installSkills>[0]['data'];\n packageRoot: string;\n ides: SkillIde[];\n scope: SkillScope;\n onlyIds: string[];\n skippedSkillIds: string[];\n /** Optional — only populated by `runSkillsAdd`. `runSkillsInit` leaves empty. */\n outdatedSkills?: OutdatedSkillInfo[];\n existing: ExistingState;\n existingConfig: ProjectConfig | null;\n}\n\nasync function finalizeSkillsInstall(args: FinalizeArgs): Promise<{\n status: 'installed';\n packageName: string;\n version: string;\n ides: SkillIde[];\n scope: SkillScope;\n skillCount: number;\n fileCount: number;\n resources: InstalledResource[];\n addedSkillIds: string[];\n skippedSkillIds: string[];\n autoUpdatedSkillIds: string[];\n outdatedSkills: OutdatedSkillInfo[];\n}> {\n const {\n projectRoot,\n packageName,\n ideIdent,\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n onlyIds,\n skippedSkillIds,\n outdatedSkills,\n existing,\n existingConfig,\n } = args;\n\n const result = await installSkills({\n projectRoot,\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n onlyIds,\n });\n\n const config: ProjectConfig = existingConfig ?? {\n $schema: 'https://teamix-evo.dev/schema/config/v2.json',\n schemaVersion: 2,\n ide: ideIdent,\n packages: {},\n };\n config.packages.skills = {\n variant: FLAT_VARIANT,\n version: manifest.version,\n ides,\n scope,\n };\n await writeProjectConfig(projectRoot, config);\n\n const installedAt = new Date().toISOString();\n const installedManifest: InstalledManifest = existing.installed ?? {\n schemaVersion: 1,\n installed: [],\n };\n const idx = installedManifest.installed.findIndex(\n (p) => p.package === packageName,\n );\n const mergedResources = mergeInstalledResources(\n existing.pkg?.resources ?? [],\n result.resources,\n );\n const entry = {\n package: packageName,\n variant: FLAT_VARIANT,\n version: manifest.version,\n installedAt,\n resources: mergedResources,\n };\n if (idx >= 0) installedManifest.installed[idx] = entry;\n else installedManifest.installed.push(entry);\n await writeInstalledManifest(projectRoot, installedManifest);\n\n // Update skills source-mirror lock (per ADR 0013).\n const lock: SkillsLock = existing.lock ?? {\n schemaVersion: 1,\n skills: {},\n };\n for (const skillId of onlyIds) {\n const skillDef = manifest.skills.find((s) => s.id === skillId);\n if (!skillDef) continue;\n const mirroredTo = skillDef.ides.filter((i) => ides.includes(i));\n lock.skills[skillId] = {\n version: skillDef.version,\n from: packageName,\n installedAt,\n scope,\n mirroredTo,\n };\n }\n await writeSkillsLock(projectRoot, lock);\n\n // Phase 5.G: sweep empty IDE skill dirs left over from prior installs\n // (e.g. a removed upstream skill). Best-effort — swallows errors.\n try {\n await pruneEmptyIdeSkillDirs({ projectRoot, ides, scope });\n } catch {\n // Cleanup is decoration; never a hard failure.\n }\n\n // Auto-upgrade outdated skills alongside the fresh install.\n let autoUpdatedSkillIds: string[] = [];\n if (outdatedSkills && outdatedSkills.length > 0) {\n autoUpdatedSkillIds = await autoUpgradeOutdatedSkills({\n projectRoot,\n packageName,\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n outdatedSkills,\n existing,\n existingConfig: existingConfig ?? config,\n });\n }\n\n return {\n status: 'installed',\n packageName,\n version: manifest.version,\n ides,\n scope,\n skillCount: onlyIds.length,\n fileCount: result.count,\n resources: result.resources,\n addedSkillIds: onlyIds,\n skippedSkillIds,\n autoUpdatedSkillIds,\n outdatedSkills: [],\n };\n}\n\nfunction mergeInstalledResources(\n existing: InstalledResource[],\n next: InstalledResource[],\n): InstalledResource[] {\n const map = new Map<string, InstalledResource>();\n const key = (r: InstalledResource): string =>\n `${r.id}|${r.ide ?? ''}|${r.scope ?? ''}`;\n for (const r of existing) map.set(key(r), r);\n for (const r of next) map.set(key(r), r);\n return [...map.values()];\n}\n\n// ─── auto-upgrade outdated skills ──────────────────────────────────────────────\n// When `skills add` detects already-installed skills whose locked version is\n// older than the manifest version, we auto-upgrade them in-place rather than\n// just surfacing a hint. This ensures the client-side AI always uses the latest\n// skill version available in the resolved `@latest` package.\n\ninterface AutoUpgradeArgs {\n projectRoot: string;\n packageName: string;\n manifest: SkillsPackageManifest;\n data: Parameters<typeof installSkills>[0]['data'];\n packageRoot: string;\n ides: SkillIde[];\n scope: SkillScope;\n outdatedSkills: OutdatedSkillInfo[];\n existing: ExistingState;\n existingConfig: ProjectConfig | null;\n}\n\nasync function autoUpgradeOutdatedSkills(\n args: AutoUpgradeArgs,\n): Promise<string[]> {\n const {\n projectRoot,\n packageName,\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n outdatedSkills,\n existing,\n } = args;\n\n const targetIds = outdatedSkills.map((o) => o.id);\n\n // Use the updateSkills flow which preserves managed regions.\n await updateSkills({\n projectRoot,\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n onlyIds: targetIds,\n });\n\n // Update the lock for auto-upgraded skills.\n const lock: SkillsLock = existing.lock ?? {\n schemaVersion: 1,\n skills: {},\n };\n const installedAt = new Date().toISOString();\n const manifestById = new Map(manifest.skills.map((s) => [s.id, s]));\n for (const id of targetIds) {\n const skillDef = manifestById.get(id);\n if (!skillDef) continue;\n const mirroredTo = skillDef.ides.filter((i) => ides.includes(i));\n lock.skills[id] = {\n version: skillDef.version,\n from: packageName,\n installedAt,\n scope,\n mirroredTo,\n };\n }\n await writeSkillsLock(projectRoot, lock);\n\n // Update installed manifest resources for upgraded skills.\n const installedManifest = (await readInstalledManifest(projectRoot)) ?? {\n schemaVersion: 1 as const,\n installed: [],\n };\n const idx = installedManifest.installed.findIndex(\n (p) => p.package === packageName,\n );\n if (idx >= 0) {\n installedManifest.installed[idx]!.version = manifest.version;\n installedManifest.installed[idx]!.installedAt = installedAt;\n }\n await writeInstalledManifest(projectRoot, installedManifest);\n\n logger.debug(\n `Auto-upgraded ${targetIds.length} outdated skill(s): ${targetIds.join(\n ', ',\n )}`,\n );\n\n return targetIds;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { SkillIde, SkillScope } from '@teamix-evo/registry';\nimport { hasManagedRegion, replaceManagedRegion } from '@teamix-evo/registry';\nimport { getAdapter } from '../ide/index.js';\nimport { backupFile, fileExists, readFileOrNull } from '../utils/fs.js';\nimport { readProjectConfig, readSkillsLock } from './state.js';\n\n/**\n * Generate `<projectRoot>/AGENTS.md` as a skill-trigger fallback (ADR 0038).\n *\n * The file is **regenerable**: it consolidates TRIGGER / SKIP excerpts from\n * each installed SKILL.md frontmatter description into one terse index, so\n * AGENTS.md-aware IDEs (Codex / Cursor / Claude Code / Qoder) preheat the\n * skill activation conditions even when the user prompt does not directly\n * hit the description-based trigger.\n *\n * Out of scope (per ADR 0038):\n * - Does NOT copy skill body / rules / patterns — those stay in the skill.\n * - Does NOT include `teamix-evo-manage` (entry skill, global scope, ADR 0033).\n *\n * Lifted from `create-teamix-evo` (v0.5) into `teamix-evo/core` so both\n * `npm create teamix-evo` (scaffold path) and `teamix-evo init` (existing-\n * project path, ADR 0019 task #5) emit identical AGENTS.md output.\n *\n * @module teamix-evo/core/agents-md\n */\n\nexport interface RunGenerateAgentsMdOptions {\n /** Absolute path to the consumer project root. */\n projectRoot: string;\n /** Tokens / skills variant (e.g. \"opentrek\"). Used for header context. */\n variant: string;\n /**\n * Skill ids to index. Caller is responsible for filtering out global-only\n * skills (e.g. `teamix-evo-manage`).\n */\n skillIds: string[];\n /**\n * Reconciliation mode (Phase 2.B):\n * - `'overwrite'` (default): always rewrite the full file. Pre-existing\n * content is backed up and discarded.\n * - `'merge-managed'`: rewrite only the `teamix-evo-skills` managed\n * region. When the consumer file lacks the region, prepend a fresh\n * managed block ahead of the user's content (auto-adopt). The user's\n * non-managed sections are preserved.\n *\n * In both modes, an existing file is backed up under\n * `.teamix-evo/.backups/AGENTS.md.<isoTs>.bak` before any mutation.\n */\n mode?: 'overwrite' | 'merge-managed';\n}\n\nexport interface RunGenerateAgentsMdResult {\n /** Absolute path of the written `AGENTS.md`. */\n path: string;\n /** Number of skill sections rendered (missing SKILL.md degradations are still counted). */\n skillCount: number;\n /** Skill ids whose SKILL.md could not be read (rendered as degraded section). */\n missingSkillIds: string[];\n /**\n * True when an existing AGENTS.md was backed up under\n * `.teamix-evo/.backups/AGENTS.md.<isoTs>.bak` before being overwritten\n * (Phase 1.A2 — full backup strategy).\n */\n backedUp: boolean;\n /**\n * Outcome of the merge step (Phase 2.B):\n * - `'created'`: no AGENTS.md existed; wrote a fresh full template.\n * - `'overwritten'`: existed but mode='overwrite' — full rewrite.\n * - `'managed-replaced'`: mode='merge-managed' and the consumer file\n * already had the `teamix-evo-skills` managed region; only that region\n * was rewritten. User content outside is preserved.\n * - `'managed-prepended'`: mode='merge-managed' but the consumer file\n * did not yet have the managed region; a fresh block was inserted at\n * the top, with the existing user content kept below.\n */\n merge: 'created' | 'overwritten' | 'managed-replaced' | 'managed-prepended';\n}\n\n/** Region id wrapping the auto-generated skill index. */\nexport const AGENTS_MD_MANAGED_ID = 'teamix-evo-skills';\n\ninterface SkillDescriptionParts {\n /** First non-empty line(s) of `description` (the capability statement). */\n capability: string;\n trigger: string | null;\n skip: string | null;\n coordinates: string | null;\n}\n\n/**\n * Generate and write the `AGENTS.md` file.\n *\n * Phase 2.B — reconciliation modes:\n * - `'overwrite'` (default): regenerable behaviour, full rewrite.\n * - `'merge-managed'`: rewrite only the `teamix-evo-skills` managed region\n * so user-authored sections (project-specific guidance, design tokens,\n * prompts) are never clobbered.\n *\n * Existing files are always backed up under `.teamix-evo/.backups/` before\n * mutation (ADR 0019 §2, Phase 1.A2).\n */\nexport async function runGenerateAgentsMd(\n options: RunGenerateAgentsMdOptions,\n): Promise<RunGenerateAgentsMdResult> {\n const { projectRoot, variant, skillIds } = options;\n const mode = options.mode ?? 'overwrite';\n\n // Resolve IDE list and scope from project config / skills lock.\n const config = await readProjectConfig(projectRoot);\n const lock = await readSkillsLock(projectRoot);\n const ides: SkillIde[] = config?.packages?.skills?.ides ?? ['qoder', 'claude'];\n const scope: SkillScope = config?.packages?.skills?.scope ?? lock?.skills[skillIds[0] ?? '']?.scope ?? 'project';\n\n // Stable order: design → code → others (alphabetical within each bucket).\n const ordered = [...skillIds].sort(\n (a, b) => bucketRank(a) - bucketRank(b) || a.localeCompare(b),\n );\n\n const sections: string[] = [];\n const missingSkillIds: string[] = [];\n for (const id of ordered) {\n const { section, missing } = await renderSkillSection(projectRoot, id, ides, scope);\n sections.push(section);\n if (missing) missingSkillIds.push(id);\n }\n\n const target = path.join(projectRoot, 'AGENTS.md');\n const targetExists = await fileExists(target);\n const fullTemplate = renderAgentsMd({ variant, sections });\n const managedBody = renderManagedBlockBody({ variant, sections });\n\n let outputContent: string;\n let merge: RunGenerateAgentsMdResult['merge'];\n\n if (!targetExists) {\n outputContent = fullTemplate;\n merge = 'created';\n } else {\n // Backup before any mutation — truthful even if downstream throws.\n await backupFile(target, projectRoot);\n if (mode === 'merge-managed') {\n const existing = (await readFileOrNull(target)) ?? '';\n if (hasManagedRegion(existing, AGENTS_MD_MANAGED_ID)) {\n outputContent = replaceManagedRegion(\n existing,\n AGENTS_MD_MANAGED_ID,\n managedBody,\n );\n merge = 'managed-replaced';\n } else {\n // Auto-adopt: place the managed block at the top so AGENTS.md-aware\n // IDEs preheat skill triggers first, then keep the user's prior\n // content as a non-managed tail. A trailing precedence notice goes\n // immediately after the managed block.\n const wrapped = wrapManagedBlock(managedBody);\n outputContent = `${wrapped}\\n\\n${PRECEDENCE_NOTICE}\\n\\n${existing.trimStart()}`;\n merge = 'managed-prepended';\n }\n } else {\n // overwrite — historical default.\n outputContent = fullTemplate;\n merge = 'overwritten';\n }\n }\n\n await fs.writeFile(target, outputContent, 'utf8');\n return {\n path: target,\n skillCount: ordered.length,\n missingSkillIds,\n backedUp: targetExists,\n merge,\n };\n}\n\nfunction bucketRank(id: string): number {\n if (id.startsWith('teamix-evo-design-')) return 0;\n if (id.startsWith('teamix-evo-code-')) return 1;\n return 2;\n}\n\nasync function renderSkillSection(\n projectRoot: string,\n skillId: string,\n ides: readonly SkillIde[],\n scope: SkillScope,\n): Promise<{ section: string; missing: boolean }> {\n const lines: string[] = [];\n lines.push(`### ${skillId}`);\n let parts: SkillDescriptionParts | null = null;\n let missing = false;\n\n // Try each IDE mirror path until we find a SKILL.md.\n for (const ide of ides) {\n const adapter = getAdapter(ide);\n const skillPath = path.join(\n adapter.getSkillTargetDir(skillId, scope, projectRoot),\n 'SKILL.md',\n );\n try {\n const raw = await fs.readFile(skillPath, 'utf8');\n parts = extractDescriptionParts(raw);\n break;\n } catch {\n continue;\n }\n }\n if (!parts) missing = true;\n\n if (parts?.capability) {\n lines.push(`- ${parts.capability}`);\n }\n lines.push(\n `- **TRIGGER**: ${\n parts?.trigger ?? '未配置触发条件,需手动激活该 skill。'\n }`,\n );\n lines.push(\n `- **SKIP**: ${parts?.skip ?? '未配置跳过条件,按 TRIGGER 兜底判定。'}`,\n );\n if (parts?.coordinates) {\n lines.push(`- **Coordinates with**: ${parts.coordinates}`);\n }\n return { section: lines.join('\\n'), missing };\n}\n\nfunction renderAgentsMd(args: { variant: string; sections: string[] }): string {\n const { variant, sections } = args;\n const managedBody = renderManagedBlockBody({ variant, sections });\n const wrapped = wrapManagedBlock(managedBody);\n return `${wrapped}\\n\\n${PRECEDENCE_NOTICE}\\n`;\n}\n\n/**\n * Body of the `teamix-evo-skills` managed region (no enclosing markers).\n * Phase 2.B — isolated so {@link runGenerateAgentsMd} can substitute it via\n * `replaceManagedRegion` when reconciling against a user-edited AGENTS.md.\n *\n * Exported so external tools (e.g. the `teamix-evo-manage` skill) can render\n * a preview without depending on the file write path.\n */\nexport function renderManagedBlockBody(args: {\n variant: string;\n sections: string[];\n}): string {\n const { variant, sections } = args;\n const skillBlock =\n sections.length > 0\n ? sections.join('\\n\\n')\n : '_(本工程未装配工程级 skill。)_';\n return `# AGENTS.md\n\n> AI 助手:写代码前先对照下方 TRIGGER,命中则必须读对应 skill 再动手;不确定时仍建议快速查阅相关 skill 以确认是否涉及规范约束。\n>\n> 激活方式:在对话中直接提及 skill 名称(如 \\`teamix-evo-design-${variant}\\`),IDE 会自动加载其完整内容。\n\n## 已装 Skills(variant: ${variant})\n\n${skillBlock}\n\n> 刷新本文件:\\`npx teamix-evo@latest skills update\\``;\n}\n\nfunction wrapManagedBlock(body: string): string {\n return `<!-- teamix-evo:managed:start id=\"${AGENTS_MD_MANAGED_ID}\" -->\\n${body}\\n<!-- teamix-evo:managed:end id=\"${AGENTS_MD_MANAGED_ID}\" -->`;\n}\n\n/**\n * Footer notice (Phase 2.B): when AGENTS.md hosts both managed and\n * user-authored sections, the managed Skills index wins on conflict.\n */\nconst PRECEDENCE_NOTICE = `<!-- teamix-evo:precedence -->\n> 冲突以上方的 **Skills** 索引为准(上游路径与 TRIGGER/SKIP 契约);项目特有的人工细则请写在本处以下、不要覆盖上方 managed 区域。`;\n\n// ─── frontmatter parsing ──────────────────────────────────────────────────────\n\n/**\n * Parse a SKILL.md frontmatter description into capability / TRIGGER / SKIP /\n * Coordinates parts.\n *\n * Why hand-rolled (no gray-matter): we only need the `description: |` block.\n * The full YAML grammar is overkill and adds a runtime dep to a CLI / scaffold\n * tool that should stay zero-cost. ADR 0015 keeps frontmatter shape stable.\n */\nexport function extractDescriptionParts(\n fileContent: string,\n): SkillDescriptionParts | null {\n const description = extractDescriptionBlock(fileContent);\n if (description == null) return null;\n\n // Capability = first line that is not a TRIGGER/SKIP/Coordinates marker.\n const allLines = description\n .split('\\n')\n .map((l) => l.trim())\n .filter(Boolean);\n let capability = '';\n for (const line of allLines) {\n if (/^(TRIGGER when:|SKIP:|Coordinates with:)/i.test(line)) break;\n capability = capability ? `${capability} ${line}` : line;\n }\n\n return {\n capability: capability.trim(),\n trigger: extractSection(description, 'TRIGGER when:'),\n skip: extractSection(description, 'SKIP:'),\n coordinates: extractSection(description, 'Coordinates with:'),\n };\n}\n\n/**\n * Extract the `description: |` (or `description: >`) block body. Returns null\n * if the field is missing or not a literal/folded block.\n */\nfunction extractDescriptionBlock(fileContent: string): string | null {\n const lines = fileContent.split('\\n');\n\n // Find frontmatter range: first `---`, then matching `---`.\n if (lines[0]?.trim() !== '---') return null;\n let endIdx = -1;\n for (let i = 1; i < lines.length; i++) {\n if (lines[i]?.trim() === '---') {\n endIdx = i;\n break;\n }\n }\n if (endIdx === -1) return null;\n const fmLines = lines.slice(1, endIdx);\n\n // Locate `description:` key.\n let startIdx = -1;\n let inlineValue: string | null = null;\n let blockMode: 'literal' | 'folded' | 'inline' = 'inline';\n for (let i = 0; i < fmLines.length; i++) {\n const m = fmLines[i]?.match(/^description:\\s*(\\|[+-]?|>[+-]?)?\\s*(.*)$/);\n if (m) {\n startIdx = i;\n const indicator = (m[1] ?? '').trim();\n const rest = m[2] ?? '';\n if (indicator.startsWith('|')) blockMode = 'literal';\n else if (indicator.startsWith('>')) blockMode = 'folded';\n else {\n blockMode = 'inline';\n inlineValue = rest;\n }\n break;\n }\n }\n if (startIdx === -1) return null;\n\n if (blockMode === 'inline') {\n return inlineValue ?? '';\n }\n\n // Block mode: collect indented continuation lines.\n const body: string[] = [];\n // Detect the block indent from the first non-empty continuation line.\n let blockIndent = -1;\n for (let i = startIdx + 1; i < fmLines.length; i++) {\n const line = fmLines[i] ?? '';\n if (line.trim() === '') {\n body.push('');\n continue;\n }\n const indentMatch = line.match(/^(\\s+)/);\n const indent = indentMatch ? indentMatch[1]!.length : 0;\n if (indent === 0) break; // back to top-level key\n if (blockIndent === -1) blockIndent = indent;\n if (indent < blockIndent) break;\n body.push(line.slice(blockIndent));\n }\n // Trim trailing empty lines.\n while (body.length > 0 && body[body.length - 1] === '') body.pop();\n return body.join('\\n');\n}\n\n/**\n * Extract the body of a description sub-section starting with the given\n * marker (e.g. \"TRIGGER when:\"). Stops at the next known marker or end of\n * description. Returns the stripped one-line summary (sub-section text with\n * internal newlines collapsed to spaces).\n */\nfunction extractSection(description: string, marker: string): string | null {\n const markers = ['TRIGGER when:', 'SKIP:', 'Coordinates with:'];\n const lines = description.split('\\n');\n let inSection = false;\n const collected: string[] = [];\n for (const line of lines) {\n const trimmed = line.trim();\n const startsWithMarker = trimmed\n .toLowerCase()\n .startsWith(marker.toLowerCase());\n if (!inSection && startsWithMarker) {\n inSection = true;\n collected.push(trimmed.slice(marker.length).trim());\n continue;\n }\n if (inSection) {\n const hitNextMarker = markers.some(\n (m) =>\n m !== marker && trimmed.toLowerCase().startsWith(m.toLowerCase()),\n );\n if (hitNextMarker) break;\n if (trimmed === '') {\n // Allow blank line within section but stop on second consecutive blank.\n if (collected[collected.length - 1] === '') break;\n collected.push('');\n continue;\n }\n collected.push(trimmed);\n }\n }\n if (!inSection) return null;\n const joined = collected\n .filter((l) => l !== '')\n .join(' ')\n .replace(/\\s+/g, ' ')\n .trim();\n return joined || null;\n}\n","import type {\n InstalledResource,\n SkillIde,\n SkillScope,\n SkillsLock,\n} from '@teamix-evo/registry';\nimport { loadSkillsData } from './skills-client.js';\nimport { updateSkills } from './skills-installer.js';\nimport {\n readProjectConfig,\n readInstalledManifest,\n writeProjectConfig,\n writeInstalledManifest,\n readSkillsLock,\n writeSkillsLock,\n readTokensVariant,\n} from './state.js';\nimport { runGenerateAgentsMd } from './agents-md.js';\nimport { logger } from '../utils/logger.js';\n\nconst DEFAULT_SKILLS_PACKAGE = '@teamix-evo/skills';\nconst FLAT_VARIANT = '_flat';\n\n// ─── runSkillsUpdate ──────────────────────────────────────────────────────────\n// ADR 0035: update only refreshes skills that are (a) recorded in the lock and\n// (b) match the current install scope. New skills added to the manifest are NOT\n// auto-installed by update — use `skills add <id>` for that. version-diff\n// short-circuits when nothing has actually changed.\n\nexport interface RunSkillsUpdateOptions {\n /** Absolute project (or global meta) root. */\n projectRoot: string;\n /**\n * Optional: limit the update to these skill ids. Falls back to \"every\n * skill in lock that matches the current install scope\".\n */\n names?: readonly string[];\n /** When true, plan only — no source rewrite, no mirror, no lock write. */\n dryRun?: boolean;\n /** Override the skills package name (defaults to `@teamix-evo/skills`). */\n packageName?: string;\n}\n\nexport interface UpdatePlanItem {\n id: string;\n current: string;\n next: string;\n /** Same as updateStrategy semantics, computed from the manifest. */\n strategy: 'frozen' | 'regenerable' | 'managed';\n /**\n * Predicted action for this skill source file in non-dryRun mode.\n * - `up-to-date` — version unchanged; safe to skip\n * - `version-bump` — version changed; will overwrite/merge per strategy\n */\n action: 'up-to-date' | 'version-bump';\n}\n\nexport type RunSkillsUpdateResult =\n | { status: 'no-skills' }\n | {\n status: 'no-changes';\n packageName: string;\n version: string;\n checkedSkillIds: string[];\n }\n | {\n status: 'dry-run';\n packageName: string;\n currentVersion: string;\n availableVersion: string;\n plan: UpdatePlanItem[];\n }\n | {\n status: 'updated';\n packageName: string;\n version: string;\n ides: SkillIde[];\n scope: SkillScope;\n updatedSkillIds: string[];\n skippedSkillIds: string[];\n summary: { overwritten: number; managed: number; skipped: number; created: number };\n resources: InstalledResource[];\n };\n\n/**\n * Programmatic equivalent of `teamix-evo skills update [names...] [--dry-run]`.\n *\n * Per ADR 0035:\n * 1. Range = `keys(lock.skills) ∩ scope-match ∩ (names if given)`\n * 2. version-diff short-circuit when every target id has the same lock\n * version as the manifest\n * 3. New skills (not in lock) are NEVER auto-installed by update\n * 4. lock writeback only touches `targetIds` — existing entries are preserved\n */\nexport async function runSkillsUpdate(\n options: RunSkillsUpdateOptions,\n): Promise<RunSkillsUpdateResult> {\n const { projectRoot, names: requestedNames, dryRun } = options;\n const packageName = options.packageName ?? DEFAULT_SKILLS_PACKAGE;\n\n const config = await readProjectConfig(projectRoot);\n const skillsCfg = config?.packages?.skills;\n if (!skillsCfg) {\n return { status: 'no-skills' };\n }\n\n const ides = (skillsCfg.ides ?? ['qoder', 'claude']) as SkillIde[];\n const scope = (skillsCfg.scope ?? 'project') as SkillScope;\n\n const existingLock = await readSkillsLock(projectRoot);\n if (!existingLock || Object.keys(existingLock.skills).length === 0) {\n return { status: 'no-skills' };\n }\n\n const { manifest, data, packageRoot } = await loadSkillsData(packageName);\n const manifestById = new Map(manifest.skills.map((s) => [s.id, s]));\n\n // Three-gate intersection: lock ∩ scope ∩ names.\n const lockIds = Object.keys(existingLock.skills);\n const requestedSet = requestedNames ? new Set(requestedNames) : null;\n if (requestedSet) {\n const unknown = requestedNames!.filter(\n (n) => !lockIds.includes(n) && !manifestById.has(n),\n );\n if (unknown.length > 0) {\n throw new Error(\n `Unknown skill id(s): ${unknown.join(\n ', ',\n )}. Available (installed): ${lockIds.join(', ') || '(none)'}.`,\n );\n }\n }\n\n const targetIds: string[] = [];\n const skippedSkillIds: string[] = [];\n for (const id of lockIds) {\n if (requestedSet && !requestedSet.has(id)) continue;\n const entry = manifestById.get(id);\n if (!entry) {\n // Lock has it, manifest no longer does (skill removed upstream).\n // Skip without error — uninstall is the user's call.\n logger.debug(\n `Skipping \"${id}\": no longer in upstream manifest. Use \\`skills uninstall ${id}\\` to remove.`,\n );\n skippedSkillIds.push(id);\n continue;\n }\n const effectiveScope = entry.scope ?? 'project';\n if (effectiveScope !== scope) {\n logger.debug(\n `Skipping \"${id}\" (scope=${effectiveScope}): current install scope is \"${scope}\".`,\n );\n skippedSkillIds.push(id);\n continue;\n }\n targetIds.push(id);\n }\n\n // version-diff short-circuit\n const allSame = targetIds.every((id) => {\n const lockVer = existingLock.skills[id]!.version;\n const manVer = manifestById.get(id)!.version;\n return lockVer === manVer;\n });\n if (targetIds.length > 0 && allSame && !dryRun) {\n return {\n status: 'no-changes',\n packageName,\n version: manifest.version,\n checkedSkillIds: targetIds,\n };\n }\n\n if (dryRun) {\n const plan: UpdatePlanItem[] = targetIds.map((id) => {\n const lockVer = existingLock.skills[id]!.version;\n const entry = manifestById.get(id)!;\n const sameVersion = lockVer === entry.version;\n return {\n id,\n current: lockVer,\n next: entry.version,\n strategy: entry.updateStrategy ?? 'managed',\n action: sameVersion ? 'up-to-date' : 'version-bump',\n };\n });\n return {\n status: 'dry-run',\n packageName,\n currentVersion: skillsCfg.version,\n availableVersion: manifest.version,\n plan,\n };\n }\n\n if (targetIds.length === 0) {\n return {\n status: 'updated',\n packageName,\n version: manifest.version,\n ides,\n scope,\n updatedSkillIds: [],\n skippedSkillIds,\n summary: { overwritten: 0, managed: 0, skipped: 0, created: 0 },\n resources: [],\n };\n }\n\n const result = await updateSkills({\n projectRoot,\n manifest,\n data,\n packageRoot,\n ides,\n scope,\n onlyIds: targetIds,\n });\n\n // Update config.version (track the package-level version we last consumed).\n config!.packages.skills = {\n ...skillsCfg,\n version: manifest.version,\n };\n await writeProjectConfig(projectRoot, config!);\n\n // Update installed manifest (replace the package-level entry's resources).\n const installedManifest = (await readInstalledManifest(projectRoot)) ?? {\n schemaVersion: 1 as const,\n installed: [],\n };\n const idx = installedManifest.installed.findIndex(\n (p) => p.package === packageName,\n );\n const installedAt = new Date().toISOString();\n // Merge: keep resources from skills NOT in targetIds (preserve existing\n // entries for skills we didn't touch this round).\n const prior = idx >= 0 ? installedManifest.installed[idx]!.resources : [];\n const targetSet = new Set(targetIds);\n const preserved = prior.filter((r) => {\n const skillId = r.id.split(':')[0];\n return skillId ? !targetSet.has(skillId) : true;\n });\n const entry = {\n package: packageName,\n variant: FLAT_VARIANT,\n version: manifest.version,\n installedAt,\n resources: [...preserved, ...result.resources],\n };\n if (idx >= 0) installedManifest.installed[idx] = entry;\n else installedManifest.installed.push(entry);\n await writeInstalledManifest(projectRoot, installedManifest);\n\n // Update lock — only for targetIds, preserving other entries.\n const lock: SkillsLock = {\n schemaVersion: 1,\n skills: { ...existingLock.skills },\n };\n for (const id of targetIds) {\n const skillDef = manifestById.get(id);\n if (!skillDef) continue;\n const mirroredTo = skillDef.ides.filter((i) => ides.includes(i));\n lock.skills[id] = {\n version: skillDef.version,\n from: packageName,\n installedAt,\n scope,\n mirroredTo,\n };\n }\n await writeSkillsLock(projectRoot, lock);\n\n // Refresh AGENTS.md managed region so skill descriptions stay current.\n if (scope === 'project') {\n try {\n const variant = await readTokensVariant(projectRoot);\n if (variant) {\n const projectSkillIds = Object.entries(lock.skills)\n .filter(([, v]) => v.scope === 'project')\n .map(([id]) => id);\n await runGenerateAgentsMd({\n projectRoot,\n variant,\n skillIds: projectSkillIds,\n mode: 'merge-managed',\n });\n }\n } catch (err) {\n logger.warn(\n `AGENTS.md 刷新失败(非关键):${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n return {\n status: 'updated',\n packageName,\n version: manifest.version,\n ides,\n scope,\n updatedSkillIds: targetIds,\n skippedSkillIds,\n summary: result.summary,\n resources: result.resources,\n };\n}\n","import type { ProjectConfig, UiAliases } from '@teamix-evo/registry';\nimport {\n ensureTeamixDir,\n readProjectConfig,\n writeProjectConfig,\n} from './state.js';\n\nexport const DEFAULT_UI_ALIASES: UiAliases = {\n components: 'src/components/ui',\n hooks: 'src/hooks',\n utils: 'src/lib/utils',\n lib: 'src/lib',\n business: 'src/components/business',\n blocks: 'src/blocks',\n};\n\nexport const DEFAULT_UI_ICON_LIBRARY = 'lucide';\n\nexport interface RunUiInitOptions {\n /** Absolute project root directory. */\n projectRoot: string;\n /** Component aliases. Falls back to {@link DEFAULT_UI_ALIASES}. */\n aliases?: Partial<UiAliases>;\n /** Declared icon library (does not trigger code rewrite). Defaults to \"lucide\". */\n iconLibrary?: string;\n /** Whether the project uses TSX (true) or JSX (false). Defaults to true. */\n tsx?: boolean;\n /** Whether the project emits React Server Components markers. Defaults to false. */\n rsc?: boolean;\n /** IDE identifier written into config.ide when bootstrapping a fresh config (defaults to \"qoder\"). */\n ide?: string;\n}\n\nexport type RunUiInitResult =\n | {\n status: 'installed';\n aliases: UiAliases;\n iconLibrary: string;\n tsx: boolean;\n rsc: boolean;\n }\n | {\n status: 'already-initialized';\n };\n\n/**\n * Programmatic equivalent of `teamix-evo ui init`.\n *\n * Writes `packages.ui` into `.teamix-evo/config.json` only — no resource files\n * are touched. Use {@link runUiAdd} afterwards to install component sources.\n */\nexport async function runUiInit(\n options: RunUiInitOptions,\n): Promise<RunUiInitResult> {\n const { projectRoot } = options;\n const ideIdent = options.ide ?? 'qoder';\n\n await ensureTeamixDir(projectRoot);\n\n const existingConfig = await readProjectConfig(projectRoot);\n if (existingConfig?.packages?.ui) {\n return { status: 'already-initialized' };\n }\n\n const aliases: UiAliases = {\n components: options.aliases?.components ?? DEFAULT_UI_ALIASES.components,\n hooks: options.aliases?.hooks ?? DEFAULT_UI_ALIASES.hooks,\n utils: options.aliases?.utils ?? DEFAULT_UI_ALIASES.utils,\n lib: options.aliases?.lib ?? DEFAULT_UI_ALIASES.lib,\n business: options.aliases?.business ?? DEFAULT_UI_ALIASES.business,\n blocks: options.aliases?.blocks ?? DEFAULT_UI_ALIASES.blocks,\n };\n const iconLibrary = options.iconLibrary ?? DEFAULT_UI_ICON_LIBRARY;\n const tsx = options.tsx ?? true;\n const rsc = options.rsc ?? false;\n\n const config: ProjectConfig = existingConfig ?? {\n $schema: 'https://teamix-evo.dev/schema/config/v2.json',\n schemaVersion: 2,\n ide: ideIdent,\n packages: {},\n };\n config.packages.ui = {\n variant: '_flat',\n version: '0.0.0',\n aliases,\n iconLibrary,\n tsx,\n rsc,\n };\n await writeProjectConfig(projectRoot, config);\n\n return {\n status: 'installed',\n aliases,\n iconLibrary,\n tsx,\n rsc,\n };\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport type { UiPackageManifest } from '@teamix-evo/registry';\nimport { loadUiPackageManifest } from '@teamix-evo/registry';\nimport { logger } from '../utils/logger.js';\n\nconst require = createRequire(import.meta.url);\n\nfunction resolvePackageRoot(packageName: string): string {\n const pkgJsonPath = require.resolve(`${packageName}/package.json`);\n return path.dirname(pkgJsonPath);\n}\n\n/**\n * Load the ui package manifest and optional shared `_data.json`.\n *\n * @param packageName - e.g. \"@teamix-evo/ui\"\n */\nexport async function loadUiData(packageName: string): Promise<{\n manifest: UiPackageManifest;\n data: Record<string, unknown>;\n packageRoot: string;\n}> {\n const packageRoot = resolvePackageRoot(packageName);\n\n logger.debug(`Resolved ui package root: ${packageRoot}`);\n\n const manifest = await loadUiPackageManifest(packageRoot);\n\n let data: Record<string, unknown> = {};\n const dataPath = path.join(packageRoot, '_data.json');\n try {\n const raw = await fs.readFile(dataPath, 'utf-8');\n data = JSON.parse(raw) as Record<string, unknown>;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw err;\n }\n logger.debug(`No _data.json found at ${dataPath}, using empty data`);\n }\n\n return { manifest, data, packageRoot };\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport type {\n UiEntry,\n UiPackageManifest,\n UiAliases,\n InstalledResource,\n} from '@teamix-evo/registry';\nimport { resolveUiEntryOrder } from '@teamix-evo/registry';\nimport { backupFile, writeFileSafe, fileExists } from '../utils/fs.js';\nimport { computeHash } from '../utils/hash.js';\nimport { rewriteImports } from '../utils/transform-imports.js';\nimport { logger } from '../utils/logger.js';\nimport { getErrorMessage } from '../utils/error.js';\nimport { resolveResourceTarget } from '../utils/path.js';\n\nexport interface UiInstallOptions {\n /** Project root directory */\n projectRoot: string;\n /** UI package manifest */\n manifest: UiPackageManifest;\n /** Absolute ui package root (used to resolve entry source paths) */\n packageRoot: string;\n /**\n * Optional per-entry package root override. When set, entries in the map\n * resolve their `file.source` against the mapped root instead of `packageRoot`.\n * Used by variant-aware packages (biz-ui) that pull in\n * @teamix-evo/ui transitive deps — each entry resolves from its source package.\n */\n entryPackageRoot?: Map<string, string>;\n /** Aliases configured in `packages.ui.aliases` */\n aliases: UiAliases;\n /** Entry ids the user explicitly requested to add */\n requested: string[];\n /** When true, skip writing entries whose target file already exists (frozen-on-add). */\n skipExisting?: boolean;\n /** When false, preserve directory structure in import paths (skip flattenRestPath). Defaults to true. */\n flatten?: boolean;\n}\n\nexport interface UiInstallResult {\n /** Ordered list of entry ids that were processed (deps + requested) */\n orderedIds: string[];\n /** Per-file install records (for InstalledManifest) */\n resources: InstalledResource[];\n /** Aggregate npm dependencies across the installed entries */\n npmDependencies: Record<string, string>;\n /** Number of files written */\n written: number;\n /** Number of files skipped because they already exist (frozen) */\n skipped: number;\n}\n\n/**\n * Install the requested ui entries (transitively resolving registryDependencies).\n * For frozen entries that already exist on disk, the write is skipped — shadcn-style.\n */\nexport async function installUiEntries(\n options: UiInstallOptions,\n): Promise<UiInstallResult> {\n const {\n projectRoot,\n manifest,\n packageRoot,\n entryPackageRoot,\n aliases,\n requested,\n skipExisting = true,\n flatten = true,\n } = options;\n\n const orderedIds = resolveUiEntryOrder(manifest.entries, requested);\n const idToEntry = new Map(manifest.entries.map((e) => [e.id, e]));\n\n const resources: InstalledResource[] = [];\n const npmDeps: Record<string, string> = {};\n let written = 0;\n let skipped = 0;\n\n for (const id of orderedIds) {\n const entry = idToEntry.get(id);\n if (!entry) continue;\n\n // Aggregate npm deps regardless of whether files were written — the user\n // may have manually deleted node_modules; we want to surface the full set.\n if (entry.dependencies) {\n for (const [name, range] of Object.entries(entry.dependencies)) {\n npmDeps[name] = range;\n }\n }\n\n for (const file of entry.files) {\n const targetAbs = resolveTargetPath(projectRoot, aliases, entry, file);\n const exists = await fileExists(targetAbs);\n\n if (\n exists &&\n skipExisting &&\n (entry.updateStrategy ?? 'frozen') === 'frozen'\n ) {\n logger.info(` skip (frozen, exists): ${rel(projectRoot, targetAbs)}`);\n skipped++;\n continue;\n }\n\n const rootForEntry = entryPackageRoot?.get(entry.id) ?? packageRoot;\n const sourceAbs = path.resolve(rootForEntry, file.source);\n const raw = await fs.readFile(sourceAbs, 'utf-8');\n const transformed = rewriteImports(raw, aliases, { flatten });\n\n if (exists) {\n const current = await fs.readFile(targetAbs, 'utf-8');\n if (current === transformed) {\n logger.info(` skip (identical): ${rel(projectRoot, targetAbs)}`);\n skipped++;\n resources.push({\n id: `${entry.id}:${file.targetName}`,\n target: path.relative(projectRoot, targetAbs),\n hash: computeHash(transformed),\n strategy: entry.updateStrategy ?? 'frozen',\n });\n continue;\n }\n await backupFile(targetAbs, projectRoot);\n }\n await writeFileSafe(targetAbs, transformed);\n written++;\n logger.info(` write: ${rel(projectRoot, targetAbs)}`);\n\n resources.push({\n id: `${entry.id}:${file.targetName}`,\n target: path.relative(projectRoot, targetAbs),\n hash: computeHash(transformed),\n strategy: entry.updateStrategy ?? 'frozen',\n });\n }\n }\n\n return {\n orderedIds,\n resources,\n npmDependencies: npmDeps,\n written,\n skipped,\n };\n}\n\nfunction resolveTargetPath(\n projectRoot: string,\n aliases: UiAliases,\n entry: UiEntry,\n file: { targetAlias: string; targetName: string },\n): string {\n const aliasDir = aliases[file.targetAlias as keyof UiAliases];\n if (!aliasDir) {\n throw new Error(\n `Entry \"${entry.id}\" requires alias \"${file.targetAlias}\" but it is not configured.`,\n );\n }\n return path.join(projectRoot, aliasDir, file.targetName);\n}\n\nfunction rel(projectRoot: string, abs: string): string {\n return path.relative(projectRoot, abs);\n}\n\n/**\n * Remove all installed ui resource files and prune empty parent directories.\n */\nexport async function removeUiFiles(\n records: InstalledResource[],\n projectRoot: string,\n): Promise<string[]> {\n const removed: string[] = [];\n for (const r of records) {\n const abs = resolveResourceTarget(projectRoot, r.target);\n try {\n await fs.unlink(abs);\n removed.push(abs);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n logger.warn(`Failed to remove ${abs}: ${getErrorMessage(err)}`);\n }\n }\n }\n const parents = new Set(\n records.map((r) => path.dirname(resolveResourceTarget(projectRoot, r.target))),\n );\n for (const dir of parents) {\n try {\n const entries = await fs.readdir(dir);\n if (entries.length === 0) await fs.rmdir(dir);\n } catch {\n /* ignore */\n }\n }\n return removed;\n}\n","import type { UiAliases } from '@teamix-evo/registry';\n\n/**\n * Map between the ui package's \"developer-time\" import roots and the user's\n * configured aliases. The keys are the source roots used inside ui source\n * files (e.g. `@/utils/cn` references `src/utils/`).\n */\nconst SOURCE_ROOT_TO_ALIAS_KEY: Record<string, keyof UiAliases> = {\n components: 'components',\n hooks: 'hooks',\n utils: 'utils',\n lib: 'lib',\n blocks: 'blocks',\n};\n\n/**\n * Rewrite import specifiers in a UI source file so that the developer-time\n * placeholders (e.g. `@/utils/cn`) resolve to the user's configured aliases\n * (e.g. `@/lib/utils/cn` when `aliases.utils === \"src/lib/utils\"`).\n *\n * Matches both static imports and dynamic imports of the form `@/<root>/<rest>`.\n * Bare `@/` (no segment) and unknown segments are left untouched.\n *\n * The rewrite uses each user alias verbatim. If the user alias begins with\n * `src/`, that prefix is stripped because TypeScript-style `@/*` → `src/*`\n * mappings expect paths relative to `src`.\n */\nexport function rewriteImports(\n source: string,\n aliases: UiAliases,\n opts?: { flatten?: boolean },\n): string {\n const shouldFlatten = opts?.flatten !== false;\n return source.replace(\n /(['\"])@\\/([a-z][a-z0-9-]*)(\\/[^'\"]*)?\\1/g,\n (full, quote: string, root: string, rest: string | undefined) => {\n const aliasKey = SOURCE_ROOT_TO_ALIAS_KEY[root];\n if (!aliasKey) return full;\n const alias = aliases[aliasKey];\n const normalized = aliasToImportPath(alias);\n const resolvedRest = shouldFlatten ? flattenRestPath(rest) : (rest ?? '');\n return `${quote}${normalized}${resolvedRest}${quote}`;\n },\n );\n}\n\n/**\n * Flatten a source-tree relative path for the installed (flat) layout.\n *\n * In the UI source tree, files live in per-entry directories:\n * `@/components/skeleton/skeleton` → rest = `/skeleton/skeleton`\n * After install, they are placed flat in the alias directory:\n * `@/components/ui/skeleton` → rest = `/skeleton`\n *\n * When rest has exactly two path segments (`/dir/file`), the first segment\n * (the entry directory) is stripped, leaving only the file reference.\n * Single-segment paths (e.g. `/cn`) pass through unchanged.\n */\nfunction flattenRestPath(rest: string | undefined): string {\n if (!rest) return '';\n // Split: \"/skeleton/skeleton\" → [\"\", \"skeleton\", \"skeleton\"]\n const segments = rest.split('/');\n if (segments.length === 3) {\n // Two real segments: /dir/file → /file\n return `/${segments[2]}`;\n }\n return rest;\n}\n\n/**\n * Convert an alias path (relative to the project root, e.g. `src/lib/utils`)\n * into an import-path prefix (`@/lib/utils`).\n *\n * Strips a leading `src/` so the path matches the convention of a `@/*` →\n * `src/*` tsconfig mapping. If the alias has a different prefix (for projects\n * that don't put code under `src/`), we keep it verbatim with `@/` prepended.\n */\nfunction aliasToImportPath(alias: string): string {\n const trimmed = alias.replace(/^\\.\\//, '').replace(/\\/$/, '');\n if (trimmed.startsWith('src/')) {\n return `@/${trimmed.slice('src/'.length)}`;\n }\n return `@/${trimmed}`;\n}\n","import type {\n InstalledManifest,\n InstalledResource,\n} from '@teamix-evo/registry';\nimport { loadUiData } from './ui-client.js';\nimport { installUiEntries } from './ui-installer.js';\nimport {\n readProjectConfig,\n writeProjectConfig,\n readInstalledManifest,\n writeInstalledManifest,\n} from './state.js';\n\nconst DEFAULT_UI_PACKAGE = '@teamix-evo/ui';\n\nexport interface RunUiAddOptions {\n /** Absolute project root directory. */\n projectRoot: string;\n /** Entry ids to install (registry dependencies are resolved transitively). */\n ids: string[];\n /** When true, overwrite frozen entries that already exist on disk. */\n overwrite?: boolean;\n /** Override the ui package name (defaults to \"@teamix-evo/ui\"). */\n packageName?: string;\n /**\n * When true, allow installing entries that live in `manifest.deprecatedEntries`\n * (ADR 0028). Default: false — deprecated ids are treated as unknown and the\n * call errors with a hint pointing the user at the active replacement.\n */\n includeDeprecated?: boolean;\n}\n\nexport interface RunUiAddResult {\n packageName: string;\n /** Registered ids in install order (deps + requested). */\n orderedIds: string[];\n /** Number of files written. */\n written: number;\n /** Number of files skipped due to frozen + exists. */\n skipped: number;\n /** Aggregate npm dependencies of the installed entries. */\n npmDependencies: Record<string, string>;\n /** Per-file install records merged into the installed manifest. */\n resources: InstalledResource[];\n}\n\n/**\n * Programmatic equivalent of `teamix-evo ui add <ids...>`.\n *\n * Requires `packages.ui` to already exist in `.teamix-evo/config.json`\n * (i.e. {@link runUiInit} was called earlier).\n */\nexport async function runUiAdd(\n options: RunUiAddOptions,\n): Promise<RunUiAddResult> {\n const { projectRoot, ids, overwrite, includeDeprecated } = options;\n const packageName = options.packageName ?? DEFAULT_UI_PACKAGE;\n\n if (ids.length === 0) {\n throw new Error('At least one entry id must be provided.');\n }\n\n const config = await readProjectConfig(projectRoot);\n const uiCfg = config?.packages?.ui;\n if (!config || !uiCfg?.aliases) {\n throw new Error(\n 'UI not initialized. Run `runUiInit` (or `teamix-evo ui init`) first.',\n );\n }\n\n const { manifest, packageRoot } = await loadUiData(packageName);\n\n // Per ADR 0028: deprecated entries are archived in `deprecatedEntries`\n // and not exposed by default. When the caller opts in, we splice them\n // back into the active list so dependency resolution and install work\n // exactly as for active entries.\n const archived = manifest.deprecatedEntries ?? [];\n const archivedIds = new Set(archived.map((e) => e.id));\n const activeIds = new Set(manifest.entries.map((e) => e.id));\n\n const requestedDeprecated = ids.filter((id) => archivedIds.has(id));\n if (requestedDeprecated.length > 0 && !includeDeprecated) {\n const list = requestedDeprecated.map((s) => `\"${s}\"`).join(', ');\n throw new Error(\n `Refusing to install deprecated entr${\n requestedDeprecated.length === 1 ? 'y' : 'ies'\n } ${list}. ` +\n 'These entries are archived and not part of the active distribution (ADR 0028). ' +\n 'Pass `--include-deprecated` to override (e.g. for migration tooling).',\n );\n }\n\n const effectiveManifest = includeDeprecated\n ? { ...manifest, entries: [...manifest.entries, ...archived] }\n : manifest;\n\n const knownIds = new Set([\n ...activeIds,\n ...(includeDeprecated ? archivedIds : []),\n ]);\n const unknown = ids.filter((id) => !knownIds.has(id));\n if (unknown.length > 0) {\n throw new Error(\n `Unknown entry id(s): ${unknown\n .map((s) => `\"${s}\"`)\n .join(', ')}. Run \\`teamix-evo ui list\\` to see options.`,\n );\n }\n\n const result = await installUiEntries({\n projectRoot,\n manifest: effectiveManifest,\n packageRoot,\n aliases: uiCfg.aliases,\n requested: ids,\n skipExisting: !overwrite,\n });\n\n const installed: InstalledManifest = (await readInstalledManifest(\n projectRoot,\n )) ?? { schemaVersion: 1, installed: [] };\n\n const idx = installed.installed.findIndex((p) => p.package === packageName);\n const prior = idx >= 0 ? installed.installed[idx] : null;\n const mergedResources = mergeResources(\n prior?.resources ?? [],\n result.resources,\n );\n\n const entry = {\n package: packageName,\n variant: '_flat',\n version: manifest.version,\n installedAt: new Date().toISOString(),\n resources: mergedResources,\n };\n if (idx >= 0) installed.installed[idx] = entry;\n else installed.installed.push(entry);\n await writeInstalledManifest(projectRoot, installed);\n\n if (uiCfg.version !== manifest.version) {\n uiCfg.version = manifest.version;\n await writeProjectConfig(projectRoot, config);\n }\n\n return {\n packageName,\n orderedIds: result.orderedIds,\n written: result.written,\n skipped: result.skipped,\n npmDependencies: result.npmDependencies,\n resources: result.resources,\n };\n}\n\nfunction mergeResources<T extends { id: string }>(prior: T[], next: T[]): T[] {\n const merged = new Map<string, T>();\n for (const r of prior) merged.set(r.id, r);\n for (const r of next) merged.set(r.id, r);\n return Array.from(merged.values());\n}\n","import type { UiEntry } from '@teamix-evo/registry';\nimport { loadUiData } from './ui-client.js';\nimport { readInstalledManifest } from './state.js';\n\nconst DEFAULT_UI_PACKAGE = '@teamix-evo/ui';\n\nexport interface RunUiListOptions {\n /** Absolute project root directory. */\n projectRoot: string;\n /** When true, only return entries that are already installed. */\n installedOnly?: boolean;\n /** Override the ui package name (defaults to \"@teamix-evo/ui\"). */\n packageName?: string;\n /**\n * When true, also include archived entries from `manifest.deprecatedEntries`\n * (ADR 0028). They are flagged with `deprecated: true` in the result.\n */\n includeDeprecated?: boolean;\n}\n\nexport interface UiEntryListItem {\n id: string;\n type: UiEntry['type'];\n description: string;\n installed: boolean;\n /** True when the entry comes from `manifest.deprecatedEntries` (ADR 0028). */\n deprecated: boolean;\n}\n\nexport interface RunUiListResult {\n packageName: string;\n /** Total number of entries declared by the package manifest. */\n total: number;\n /** Number of installed entries (based on the project's installed manifest). */\n installedCount: number;\n /** Filtered + decorated entries. */\n entries: UiEntryListItem[];\n}\n\n/**\n * Programmatic equivalent of `teamix-evo ui list`.\n *\n * Returns structured data; the CLI command formats it for terminal output.\n */\nexport async function runUiList(\n options: RunUiListOptions,\n): Promise<RunUiListResult> {\n const { projectRoot, installedOnly, includeDeprecated } = options;\n const packageName = options.packageName ?? DEFAULT_UI_PACKAGE;\n\n const { manifest } = await loadUiData(packageName);\n const installedManifest = await readInstalledManifest(projectRoot);\n\n const installedIds = new Set<string>();\n const uiPkg = installedManifest?.installed.find(\n (p) => p.package === packageName,\n );\n for (const r of uiPkg?.resources ?? []) {\n const colon = r.id.indexOf(':');\n installedIds.add(colon >= 0 ? r.id.slice(0, colon) : r.id);\n }\n\n const archived = manifest.deprecatedEntries ?? [];\n const pool = includeDeprecated\n ? [\n ...manifest.entries.map((e) => ({ entry: e, deprecated: false })),\n ...archived.map((e) => ({ entry: e, deprecated: true })),\n ]\n : manifest.entries.map((e) => ({ entry: e, deprecated: false }));\n\n const entries: UiEntryListItem[] = pool\n .filter(({ entry }) => !installedOnly || installedIds.has(entry.id))\n .map(({ entry, deprecated }) => ({\n id: entry.id,\n type: entry.type,\n description: entry.description,\n installed: installedIds.has(entry.id),\n deprecated,\n }));\n\n return {\n packageName,\n total: manifest.entries.length + (includeDeprecated ? archived.length : 0),\n installedCount: installedIds.size,\n entries,\n };\n}\n","/**\n * Programmatic install for variant-aware UI packages (biz-ui).\n *\n * Per [ADR 0014](../../../../docs/adr/0014-ui-biz-ui-templates-tier.md),\n * variant-aware packages share the variant-aware shape: top-level catalog +\n * per-variant manifest. The install logic is the same as `runUiAdd` (registry\n * dependency resolution + frozen-on-add + import rewrite) — only differences:\n *\n * 1. The package source is `<pkg>/variants/<variant>/` rather than `<pkg>/`\n * 2. A `--variant` selector picks which variant to install from\n * 3. The installed manifest entry records `variant: \"<name>\"` rather than\n * `_flat`\n */\nimport * as path from 'node:path';\nimport { createRequire } from 'node:module';\nimport type {\n InstalledManifest,\n InstalledResource,\n UiEntry,\n UiPackageManifest,\n VariantUiPackageName,\n} from '@teamix-evo/registry';\nimport {\n loadUiPackageManifest,\n loadVariantUiPackageCatalog,\n loadVariantUiPackageManifest,\n} from '@teamix-evo/registry';\nimport { installUiEntries } from './ui-installer.js';\nimport {\n readProjectConfig,\n readInstalledManifest,\n writeInstalledManifest,\n} from './state.js';\n\nconst require = createRequire(import.meta.url);\n\nfunction resolvePackageRoot(packageName: string): string {\n const pkgJsonPath = require.resolve(`${packageName}/package.json`);\n return path.dirname(pkgJsonPath);\n}\n\nexport interface RunVariantUiAddOptions {\n /** Absolute project root directory. */\n projectRoot: string;\n /** Variant id (e.g. `\"opentrek\"`). */\n variant: string;\n /** Entry ids to install. */\n ids: string[];\n /** When true, overwrite frozen entries that already exist on disk. */\n overwrite?: boolean;\n /** Override the package name. */\n packageName?: string;\n /**\n * Override resolution of the package root. When set, skips\n * `require.resolve(\"<packageName>/package.json\")`.\n */\n packageRoot?: string;\n}\n\nexport interface RunVariantUiAddResult {\n packageName: string;\n variant: string;\n orderedIds: string[];\n written: number;\n skipped: number;\n npmDependencies: Record<string, string>;\n resources: InstalledResource[];\n}\n\nasync function runVariantUiAdd(\n packageName: VariantUiPackageName,\n options: RunVariantUiAddOptions,\n): Promise<RunVariantUiAddResult> {\n const { projectRoot, variant, ids, overwrite } = options;\n const fullPackageName = options.packageName ?? `@teamix-evo/${packageName}`;\n\n if (ids.length === 0) {\n throw new Error('At least one entry id must be provided.');\n }\n\n const config = await readProjectConfig(projectRoot);\n const uiCfg = config?.packages?.ui;\n if (!config || !uiCfg?.aliases) {\n throw new Error(\n `UI not initialized. Run \\`teamix-evo ui init\\` first — \\`${packageName} add\\` writes into the same alias map (business / blocks).`,\n );\n }\n\n const packageRoot =\n options.packageRoot ?? resolvePackageRoot(fullPackageName);\n\n // Validate that this variant exists in the catalog (clear error if not).\n const catalog = await loadVariantUiPackageCatalog(packageRoot);\n if (!catalog.variants.some((v) => v.name === variant)) {\n const known = catalog.variants.map((v) => v.name).join(', ');\n throw new Error(\n `Variant \"${variant}\" not found in ${fullPackageName}. Known variants: ${known}. Hint: \\`teamix-evo ${packageName} list-variants\\` shows all.`,\n );\n }\n\n // Load the per-variant manifest from packages/<pkg>/variants/<variant>/.\n const variantDir = path.join(packageRoot, 'variants', variant);\n const variantManifest = await loadVariantUiPackageManifest(variantDir);\n\n // Validate requested ids (must be defined in this variant package, not in ui)\n const knownIds = new Set(variantManifest.entries.map((e) => e.id));\n const unknown = ids.filter((id) => !knownIds.has(id));\n if (unknown.length > 0) {\n throw new Error(\n `Unknown entry id(s) in ${packageName}#${variant}: ${unknown\n .map((s) => `\"${s}\"`)\n .join(', ')}. Run \\`teamix-evo ${packageName} list-variants\\` to see this package's variants, or \\`teamix-evo ${packageName} list --variant ${variant}\\` for its entries.`,\n );\n }\n\n // Cross-package dependency resolution (fixes #22).\n // variant-aware entries (biz-ui) reference @teamix-evo/ui entries\n // by id via `registryDependencies` (e.g. tenant-switcher → popover/button/cn).\n // Merge ui package's entries into the dep graph so the resolver can find\n // them. The installer's skipExisting=frozen guard means already-installed ui\n // entries are not rewritten.\n const uiPackageRoot = resolvePackageRoot('@teamix-evo/ui');\n const uiManifest = await loadUiPackageManifest(uiPackageRoot);\n\n // Resolve each entry's true package root for source file paths. Entries from\n // the variant package live under variantDir; entries from @teamix-evo/ui live\n // under uiPackageRoot.\n const entryPackageRoot = new Map<string, string>();\n const mergedEntries: UiEntry[] = [];\n for (const e of variantManifest.entries) {\n entryPackageRoot.set(e.id, variantDir);\n mergedEntries.push(e);\n }\n for (const e of uiManifest.entries) {\n // variant entry id wins over ui entry of same id (rare/illegal but safe).\n if (entryPackageRoot.has(e.id)) continue;\n entryPackageRoot.set(e.id, uiPackageRoot);\n mergedEntries.push(e);\n }\n\n const adaptedManifest: UiPackageManifest = {\n schemaVersion: 1,\n package: 'ui',\n version: variantManifest.version,\n engines: variantManifest.engines,\n entries: mergedEntries,\n };\n\n const result = await installUiEntries({\n projectRoot,\n manifest: adaptedManifest,\n packageRoot: variantDir, // default for variant entries\n entryPackageRoot, // ui entries resolve from uiPackageRoot\n aliases: uiCfg.aliases,\n requested: ids,\n skipExisting: !overwrite,\n });\n\n // Update installed manifest, keyed by (package, variant). Multiple variants\n // of the same package can co-exist (rare but legal).\n const installed: InstalledManifest = (await readInstalledManifest(\n projectRoot,\n )) ?? { schemaVersion: 1, installed: [] };\n\n const idx = installed.installed.findIndex(\n (p) => p.package === fullPackageName && p.variant === variant,\n );\n const prior = idx >= 0 ? installed.installed[idx] : null;\n const mergedResources = mergeResources(\n prior?.resources ?? [],\n result.resources,\n );\n\n const entry = {\n package: fullPackageName,\n variant,\n version: variantManifest.version,\n installedAt: new Date().toISOString(),\n resources: mergedResources,\n };\n if (idx >= 0) installed.installed[idx] = entry;\n else installed.installed.push(entry);\n await writeInstalledManifest(projectRoot, installed);\n\n return {\n packageName: fullPackageName,\n variant,\n orderedIds: result.orderedIds,\n written: result.written,\n skipped: result.skipped,\n npmDependencies: result.npmDependencies,\n resources: result.resources,\n };\n}\n\nfunction mergeResources<T extends { id: string }>(prior: T[], next: T[]): T[] {\n const merged = new Map<string, T>();\n for (const r of prior) merged.set(r.id, r);\n for (const r of next) merged.set(r.id, r);\n return Array.from(merged.values());\n}\n\n/** `teamix-evo biz-ui add <ids...> --variant <name>`. */\nexport async function runBizUiAdd(\n options: RunVariantUiAddOptions,\n): Promise<RunVariantUiAddResult> {\n return runVariantUiAdd('biz-ui', options);\n}\n\n// ─── List variants ───────────────────────────────────────────────────────────\n\nexport interface ListVariantUiResult {\n packageName: string;\n variants: Array<{\n name: string;\n displayName: string;\n version: string;\n description?: string;\n }>;\n}\n\nasync function listVariantUi(\n packageName: VariantUiPackageName,\n packageRoot?: string,\n): Promise<ListVariantUiResult> {\n const fullPackageName = `@teamix-evo/${packageName}`;\n const root = packageRoot ?? resolvePackageRoot(fullPackageName);\n const catalog = await loadVariantUiPackageCatalog(root);\n return {\n packageName: fullPackageName,\n variants: catalog.variants.map((v) => ({\n name: v.name,\n displayName: v.displayName,\n version: v.version,\n description: v.description,\n })),\n };\n}\n\nexport async function listBizUiVariants(\n packageRoot?: string,\n): Promise<ListVariantUiResult> {\n return listVariantUi('biz-ui', packageRoot);\n}\n\n// ─── List entries inside a variant ───────────────────────────────────────────\n\nexport interface ListVariantUiEntriesResult {\n packageName: string;\n variant: string;\n entries: Array<{\n id: string;\n name: string;\n type: string;\n description?: string;\n registryDependencies: string[];\n }>;\n}\n\nasync function listVariantUiEntries(\n packageName: VariantUiPackageName,\n variant: string,\n packageRoot?: string,\n): Promise<ListVariantUiEntriesResult> {\n const fullPackageName = `@teamix-evo/${packageName}`;\n const root = packageRoot ?? resolvePackageRoot(fullPackageName);\n const catalog = await loadVariantUiPackageCatalog(root);\n if (!catalog.variants.some((v) => v.name === variant)) {\n const known = catalog.variants.map((v) => v.name).join(', ');\n throw new Error(\n `Variant \"${variant}\" not found in ${fullPackageName}. Known: ${known}.`,\n );\n }\n const variantDir = path.join(root, 'variants', variant);\n const variantManifest = await loadVariantUiPackageManifest(variantDir);\n return {\n packageName: fullPackageName,\n variant,\n entries: variantManifest.entries.map((e) => ({\n id: e.id,\n name: e.name,\n type: e.type,\n description: e.description,\n registryDependencies: e.registryDependencies ?? [],\n })),\n };\n}\n\nexport async function listBizUiEntries(\n variant: string,\n packageRoot?: string,\n): Promise<ListVariantUiEntriesResult> {\n return listVariantUiEntries('biz-ui', variant, packageRoot);\n}\n\n","import * as path from 'node:path';\nimport * as fs from 'node:fs';\nimport { execa } from 'execa';\nimport {\n backupFile,\n fileExists,\n readFileOrNull,\n writeFileSafe,\n} from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\n// ─── Config file content ─────────────────────────────────────────────────────\n\nconst ESLINT_CONFIG_CONTENT = `/**\n * teamix-evo consumer ESLint preset — 9 token-discipline rules.\n * - Repo-wide: no-color-literal / no-arbitrary-tw-value / no-raw-color-scale /\n * no-large-radius / prefer-gap-over-space / no-manual-dark-classnames /\n * dialog-must-have-title (all error)\n * - src/components/ui/** only: no-relative-ui-import / icon-from-lucide (error)\n *\n * See ADR 0008 / docs/principles.md §P4.\n */\nimport consumerPreset from '@teamix-evo/eslint-config/presets/consumer';\n\nexport default [...consumerPreset];\n`;\n\nconst STYLELINT_CONFIG_CONTENT = `/** @type {import('stylelint').Config} */\nmodule.exports = {\n extends: ['@teamix-evo/stylelint-config/presets/consumer'],\n // Stylelint does NOT inherit ignoreFiles from extended configs — must declare here.\n ignoreFiles: [\n '**/tokens.theme.css',\n '**/tokens.overrides.css',\n '**/dist/**',\n '**/build/**',\n '**/node_modules/**',\n ],\n};\n`;\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/**\n * Phase 3.E lint conflict strategies (mirrors `init-conflicts.ts`).\n *\n * `merge` and `backup-overwrite` both back up the existing user file before\n * writing the teamix-evo template; `merge` additionally surfaces an AI-assist\n * hint so the manage / code skill can guide the user through merging custom\n * rules. `skip` keeps the user's file as-is and emits no template.\n */\nexport type LintConflictStrategy =\n | 'merge'\n | 'backup-overwrite'\n | 'skip'\n | 'overwrite';\n\nexport interface RunLintInitOptions {\n /** Absolute project root directory. */\n projectRoot: string;\n /**\n * Skip npm dependency installation. Used by the create scaffold where\n * dependencies are already declared in the template package.json and\n * installed in a later batch step.\n */\n skipInstall?: boolean;\n /**\n * Phase 3.E: strategy for handling existing ESLint config files.\n * Defaults to `'overwrite'` (legacy behaviour); the `init` orchestrator\n * passes the wizard-resolved value when consumer files are detected.\n */\n eslintStrategy?: LintConflictStrategy;\n /**\n * Phase 3.E: strategy for handling existing Stylelint config files.\n */\n stylelintStrategy?: LintConflictStrategy;\n /**\n * Phase 3.E: paths of existing ESLint configs (relative to projectRoot)\n * to back up. Empty when no consumer config was detected.\n */\n eslintExistingPaths?: string[];\n /**\n * Phase 3.E: paths of existing Stylelint configs (relative to projectRoot).\n */\n stylelintExistingPaths?: string[];\n}\n\nexport type RunLintInitResult =\n | {\n status: 'installed';\n eslint: boolean;\n stylelint: boolean;\n /** True when the user had a custom config and asked for AI-assisted merge. */\n eslintMergeRequested?: boolean;\n stylelintMergeRequested?: boolean;\n /** True when the strategy asked us to keep the user file untouched. */\n eslintSkipped?: boolean;\n stylelintSkipped?: boolean;\n /**\n * True when `package.json` was actually patched (lint / lint:css\n * scripts inserted). Powers the project-init change ledger so the\n * CLI does not report a phantom write when both scripts already\n * existed.\n */\n packageJsonPatched?: boolean;\n /**\n * True when the consumer's existing stylelint config was kept (skip /\n * merge) and does not extend a teamix-evo preset — token definition\n * files may trigger false-positive lint errors without `ignoreFiles`.\n */\n stylelintIgnoreFilesWarning?: boolean;\n }\n | {\n status: 'already-initialized';\n };\n\n// ─── Lint dependencies ───────────────────────────────────────────────────────\n\nconst ESLINT_DEPS = [\n '@teamix-evo/eslint-config',\n 'eslint',\n '@typescript-eslint/parser',\n];\n\nconst STYLELINT_DEPS = ['@teamix-evo/stylelint-config', 'stylelint'];\n\n// ─── Implementation ──────────────────────────────────────────────────────────\n\n/**\n * Programmatic equivalent of `teamix-evo lint init`.\n *\n * Writes lint configuration files and optionally installs dependencies.\n * Idempotent: if both config files already exist, returns `already-initialized`.\n */\nexport async function runLintInit(\n options: RunLintInitOptions,\n): Promise<RunLintInitResult> {\n const {\n projectRoot,\n skipInstall,\n eslintStrategy = 'overwrite',\n stylelintStrategy = 'overwrite',\n eslintExistingPaths = [],\n stylelintExistingPaths = [],\n } = options;\n\n const eslintConfigPath = path.join(projectRoot, 'eslint.config.js');\n const stylelintConfigPath = path.join(projectRoot, 'stylelint.config.cjs');\n\n const eslintTemplateExists = await fileExists(eslintConfigPath);\n const stylelintTemplateExists = await fileExists(stylelintConfigPath);\n\n // Phase 3.E: a `skip` strategy only short-circuits when the *consumer*\n // already has a config. Without it we still need to write our template.\n const eslintSkipRequested =\n eslintStrategy === 'skip' && eslintExistingPaths.length > 0;\n const stylelintSkipRequested =\n stylelintStrategy === 'skip' && stylelintExistingPaths.length > 0;\n\n const eslintNeedsWrite = !eslintTemplateExists && !eslintSkipRequested;\n const stylelintNeedsWrite =\n !stylelintTemplateExists && !stylelintSkipRequested;\n\n if (!eslintNeedsWrite && !stylelintNeedsWrite) {\n return { status: 'already-initialized' };\n }\n\n // ─── Install dependencies ──────────────────────────────────────────────\n if (!skipInstall) {\n const depsToInstall = [\n ...(eslintNeedsWrite ? ESLINT_DEPS : []),\n ...(stylelintNeedsWrite ? STYLELINT_DEPS : []),\n ];\n\n if (depsToInstall.length > 0) {\n const pm = detectPm(projectRoot);\n const args =\n pm === 'yarn'\n ? ['add', '--dev', ...depsToInstall]\n : pm === 'pnpm'\n ? ['add', '-D', ...depsToInstall]\n : ['install', '--save-dev', ...depsToInstall];\n\n logger.info(`Installing lint deps via ${pm}...`);\n await execa(pm, args, { cwd: projectRoot, stdio: 'inherit' });\n }\n }\n\n // ─── Phase 3.E: back up consumer configs before writing template ───────\n // Phase 1.A2 — `overwrite` strategy still demands a `.bak` so the user\n // can recover the original file. Only `eslintNeedsWrite` /\n // `stylelintNeedsWrite` gates the operation (a `skip`d file is left\n // untouched, so no backup is needed).\n if (eslintNeedsWrite && eslintExistingPaths.length > 0) {\n for (const rel of eslintExistingPaths) {\n await backupFile(path.join(projectRoot, rel), projectRoot);\n }\n }\n if (stylelintNeedsWrite && stylelintExistingPaths.length > 0) {\n for (const rel of stylelintExistingPaths) {\n await backupFile(path.join(projectRoot, rel), projectRoot);\n }\n }\n\n // ─── Write config files ────────────────────────────────────────────────\n let wroteEslint = false;\n let wroteStylelint = false;\n\n if (eslintNeedsWrite) {\n await writeFileSafe(eslintConfigPath, ESLINT_CONFIG_CONTENT);\n logger.debug(`Wrote eslint.config.js → ${eslintConfigPath}`);\n wroteEslint = true;\n }\n\n if (stylelintNeedsWrite) {\n await writeFileSafe(stylelintConfigPath, STYLELINT_CONFIG_CONTENT);\n logger.debug(`Wrote stylelint.config.cjs → ${stylelintConfigPath}`);\n wroteStylelint = true;\n }\n\n // ─── Patch package.json scripts ────────────────────────────────────────\n // Phase 1.A2: package.json is a high-value user file — back it up before\n // we mutate `scripts.lint` / `scripts['lint:css']` so the user can revert\n // the patch without git if needed.\n const packageJsonPatched = await patchPackageJsonScripts(projectRoot);\n\n // ─── Phase 2.3: detect missing ignoreFiles for token files ────────────\n // When the consumer keeps their own stylelint config (skip / merge), check\n // whether it extends a teamix-evo preset. If not, token definition files\n // (tokens.theme.css, tokens.overrides.css) will trigger false-positive\n // no-color-literal / no-hardcoded-dimension errors. Print a non-invasive\n // warning with the recommended fix (review safety-net: never auto-modify).\n let stylelintIgnoreFilesWarning = false;\n if (!stylelintNeedsWrite && stylelintTemplateExists) {\n try {\n const existingContent = fs.readFileSync(stylelintConfigPath, 'utf-8');\n const usesTeamixPreset =\n existingContent.includes('@teamix-evo/stylelint-config/presets/') ||\n existingContent.includes('@teamix-evo/stylelint-config/preset/');\n const hasTokenIgnore =\n existingContent.includes('tokens.theme.css') &&\n existingContent.includes('tokens.overrides.css');\n if (!usesTeamixPreset && !hasTokenIgnore) {\n stylelintIgnoreFilesWarning = true;\n logger.warn(\n [\n '检测到现有 stylelint 配置未排除 token 定义文件。',\n '建议在 stylelint.config.cjs 中添加 ignoreFiles:',\n '',\n ' ignoreFiles: [',\n \" '**/tokens.theme.css',\",\n \" '**/tokens.overrides.css',\",\n ' ]',\n '',\n '或切换到 teamix-evo 预设以自动获得排除规则:',\n '',\n \" extends: ['@teamix-evo/stylelint-config/presets/consumer']\",\n ].join('\\n'),\n );\n }\n } catch {\n // best-effort — config may not be a readable text file\n }\n }\n\n return {\n status: 'installed',\n eslint: wroteEslint,\n stylelint: wroteStylelint,\n eslintMergeRequested:\n wroteEslint &&\n eslintStrategy === 'merge' &&\n eslintExistingPaths.length > 0,\n stylelintMergeRequested:\n wroteStylelint &&\n stylelintStrategy === 'merge' &&\n stylelintExistingPaths.length > 0,\n eslintSkipped: eslintSkipRequested,\n stylelintSkipped: stylelintSkipRequested,\n packageJsonPatched,\n stylelintIgnoreFilesWarning,\n };\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\n/**\n * Detect package manager from lockfile presence.\n */\nfunction detectPm(projectRoot: string): 'pnpm' | 'yarn' | 'npm' {\n if (fs.existsSync(path.join(projectRoot, 'pnpm-lock.yaml'))) return 'pnpm';\n if (fs.existsSync(path.join(projectRoot, 'yarn.lock'))) return 'yarn';\n return 'npm';\n}\n\n/**\n * Add lint scripts to package.json if they don't already exist.\n *\n * Returns `true` when at least one of `scripts.lint` / `scripts['lint:css']`\n * was inserted (so the caller can decide whether to surface a `package.json`\n * change in the project-init ledger). Returns `false` when both scripts\n * already existed or when `package.json` is missing/unparseable.\n */\nasync function patchPackageJsonScripts(projectRoot: string): Promise<boolean> {\n const pkgPath = path.join(projectRoot, 'package.json');\n const raw = await readFileOrNull(pkgPath);\n if (!raw) return false;\n\n let pkg: Record<string, unknown>;\n try {\n pkg = JSON.parse(raw);\n } catch {\n return false;\n }\n\n const scripts = (pkg.scripts ?? {}) as Record<string, string>;\n let changed = false;\n\n if (!scripts.lint) {\n scripts.lint = 'eslint src/';\n changed = true;\n }\n if (!scripts['lint:css']) {\n scripts['lint:css'] = \"stylelint 'src/**/*.css'\";\n changed = true;\n }\n\n if (changed) {\n // Backup user package.json before patching scripts (Phase 1.A2).\n await backupFile(pkgPath, projectRoot);\n pkg.scripts = scripts;\n await writeFileSafe(pkgPath, JSON.stringify(pkg, null, 2) + '\\n');\n logger.debug('Patched package.json scripts with lint / lint:css');\n }\n return changed;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { fileExists } from '../utils/fs.js';\nimport { getTeamixDir } from './state.js';\n\n/**\n * Three branches of `teamix-evo init` decision tree (ADR 0019 D1).\n *\n * - `empty` : 空目录或仅含可忽略文件 → 推荐用户走 `npm create teamix-evo`(完整版)\n * - `teamix-evo-installed`: 已存在 `.teamix-evo/` → 推荐 `teamix-evo update` / 卸载流程\n * - `non-teamix-evo` : 已有非 teamix-evo 工程 → 走 `teamix-evo init` 普通版接入\n */\nexport type ProjectState = 'empty' | 'teamix-evo-installed' | 'non-teamix-evo';\n\nexport interface ProjectStateReport {\n /** Decision-tree branch the caller should take. */\n state: ProjectState;\n /** Absolute path that was inspected. */\n cwd: string;\n /** Whether `.teamix-evo/` exists at `cwd`. */\n hasTeamixDir: boolean;\n /** Whether `package.json` exists at `cwd`. */\n hasPackageJson: boolean;\n /**\n * Up to 20 entries (relative to `cwd`) that caused us to consider the\n * directory non-empty. Useful for explaining the decision to humans.\n */\n significantEntries: string[];\n}\n\n/**\n * Filenames that should NOT cause us to flip out of the `empty` branch.\n *\n * Mirrors the convention shared by `create-next-app`, `nx init`, and\n * `npm init` — these are typical files added by `git init`, an editor,\n * or the OS, not project content.\n */\nconst IGNORED_TOP_LEVEL = new Set<string>([\n '.git',\n '.gitignore',\n '.gitattributes',\n '.gitkeep',\n '.DS_Store',\n 'Thumbs.db',\n '.idea',\n '.vscode',\n '.qoder',\n '.claude',\n 'README.md',\n 'README',\n 'README.txt',\n 'LICENSE',\n 'LICENSE.md',\n 'LICENSE.txt',\n]);\n\n/**\n * Inspect `cwd` and decide which branch of the `teamix-evo init` decision\n * tree applies. Pure read-only — never mutates the filesystem.\n *\n * Resolution order (first match wins):\n * 1. `.teamix-evo/` exists → `teamix-evo-installed`\n * 2. cwd missing OR all entries are in the IGNORED_TOP_LEVEL set\n * → `empty`\n * 3. otherwise → `non-teamix-evo`\n */\nexport async function detectProjectState(\n cwd: string,\n): Promise<ProjectStateReport> {\n const absCwd = path.resolve(cwd);\n\n const teamixDir = getTeamixDir(absCwd);\n const hasTeamixDir = await fileExists(teamixDir);\n if (hasTeamixDir) {\n return {\n state: 'teamix-evo-installed',\n cwd: absCwd,\n hasTeamixDir: true,\n hasPackageJson: await fileExists(path.join(absCwd, 'package.json')),\n significantEntries: [],\n };\n }\n\n let entries: string[];\n try {\n entries = await fs.readdir(absCwd);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n // Caller pointed us at a directory that doesn't exist yet — treat as\n // empty so `init` can create it (mirrors `npm create` behavior).\n return {\n state: 'empty',\n cwd: absCwd,\n hasTeamixDir: false,\n hasPackageJson: false,\n significantEntries: [],\n };\n }\n throw err;\n }\n\n const significant = entries.filter((e) => !IGNORED_TOP_LEVEL.has(e));\n const hasPackageJson = entries.includes('package.json');\n\n if (significant.length === 0) {\n return {\n state: 'empty',\n cwd: absCwd,\n hasTeamixDir: false,\n hasPackageJson: false,\n significantEntries: [],\n };\n }\n\n return {\n state: 'non-teamix-evo',\n cwd: absCwd,\n hasTeamixDir: false,\n hasPackageJson,\n significantEntries: significant.slice(0, 20).sort(),\n };\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { fileExists, readFileOrNull } from '../utils/fs.js';\nimport { getTeamixDir } from './state.js';\n\n/**\n * ADR 0046 — Three-command lifecycle model.\n *\n * Detection priority:\n * .teamix-evo/ → components.json (with shadcn traits) → empty → other\n */\nexport type ProjectState = 'empty' | 'shadcn' | 'teamix-evo' | 'other';\n\nexport interface ProjectStateReport {\n state: ProjectState;\n cwd: string;\n hasTeamixDir: boolean;\n hasPackageJson: boolean;\n hasComponentsJson: boolean;\n significantEntries: string[];\n}\n\nconst IGNORED_TOP_LEVEL = new Set<string>([\n '.git',\n '.gitignore',\n '.gitattributes',\n '.gitkeep',\n '.DS_Store',\n 'Thumbs.db',\n '.idea',\n '.vscode',\n '.qoder',\n '.claude',\n 'README.md',\n 'README',\n 'README.txt',\n 'LICENSE',\n 'LICENSE.md',\n 'LICENSE.txt',\n]);\n\nconst SHADCN_TRAIT_KEYS = ['$schema', 'style', 'rsc', 'tsx', 'aliases'];\n\nasync function isShadcnComponentsJson(filePath: string): Promise<boolean> {\n const content = await readFileOrNull(filePath);\n if (!content) return false;\n try {\n const json = JSON.parse(content) as Record<string, unknown>;\n return SHADCN_TRAIT_KEYS.some((key) => key in json);\n } catch {\n return false;\n }\n}\n\nexport async function detectProjectState(\n cwd: string,\n): Promise<ProjectStateReport> {\n const absCwd = path.resolve(cwd);\n\n const teamixDir = getTeamixDir(absCwd);\n const hasTeamixDir = await fileExists(teamixDir);\n if (hasTeamixDir) {\n return {\n state: 'teamix-evo',\n cwd: absCwd,\n hasTeamixDir: true,\n hasPackageJson: await fileExists(path.join(absCwd, 'package.json')),\n hasComponentsJson: false,\n significantEntries: [],\n };\n }\n\n const componentsJsonPath = path.join(absCwd, 'components.json');\n const hasPackageJson = await fileExists(path.join(absCwd, 'package.json'));\n const hasComponentsJson = await isShadcnComponentsJson(componentsJsonPath);\n if (hasPackageJson && hasComponentsJson) {\n return {\n state: 'shadcn',\n cwd: absCwd,\n hasTeamixDir: false,\n hasPackageJson: true,\n hasComponentsJson: true,\n significantEntries: [],\n };\n }\n\n let entries: string[];\n try {\n entries = await fs.readdir(absCwd);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return {\n state: 'empty',\n cwd: absCwd,\n hasTeamixDir: false,\n hasPackageJson: false,\n hasComponentsJson: false,\n significantEntries: [],\n };\n }\n throw err;\n }\n\n const significant = entries.filter((e) => !IGNORED_TOP_LEVEL.has(e));\n if (significant.length === 0) {\n return {\n state: 'empty',\n cwd: absCwd,\n hasTeamixDir: false,\n hasPackageJson: false,\n hasComponentsJson: false,\n significantEntries: [],\n };\n }\n\n return {\n state: 'other',\n cwd: absCwd,\n hasTeamixDir: false,\n hasPackageJson,\n hasComponentsJson: hasComponentsJson,\n significantEntries: significant.slice(0, 20).sort(),\n };\n}\n","import { logger } from '../utils/logger.js';\nimport type { ProjectState } from './project-state.js';\n\ntype LifecycleCommand = 'init' | 'migrate' | 'update';\n\nconst COMMAND_LABELS: Record<LifecycleCommand, string> = {\n init: '初始化 Teamix Evo 套件',\n migrate: 'shadcn 项目迁移为 Teamix Evo 套件',\n update: 'Teamix Evo 套件更新',\n};\n\nconst STATE_LABELS: Record<ProjectState, string> = {\n empty: '空目录',\n shadcn: 'shadcn 工程',\n 'teamix-evo': 'Teamix Evo 工程',\n other: '普通 npm 工程',\n};\n\nconst VALID_STATES: Record<LifecycleCommand, ProjectState> = {\n init: 'empty',\n migrate: 'shadcn',\n update: 'teamix-evo',\n};\n\nconst STATE_TO_COMMAND: Record<ProjectState, LifecycleCommand | null> = {\n empty: 'init',\n shadcn: 'migrate',\n 'teamix-evo': 'update',\n other: null,\n};\n\nexport function assertCommandPrecondition(\n command: LifecycleCommand,\n state: ProjectState,\n): void {\n const expected = VALID_STATES[command];\n if (state === expected) return;\n\n const stateLabel = STATE_LABELS[state];\n const commandLabel = COMMAND_LABELS[command];\n\n logger.error(\n `当前项目状态为「${stateLabel}」,无法执行「${commandLabel}」。`,\n );\n\n const suggestion = STATE_TO_COMMAND[state];\n if (suggestion) {\n const suggestionLabel = COMMAND_LABELS[suggestion];\n logger.info(`建议使用:teamix-evo ${suggestion}(${suggestionLabel})`);\n } else {\n logger.info(\n '当前项目类型暂不支持直接接入。',\n );\n logger.info(\n '建议:先用 teamix-evo init 初始化 Teamix Evo 套件(空目录),然后对旧项目进行重构。',\n );\n }\n\n process.exitCode = 1;\n}\n","import * as crypto from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { fileExists, readFileOrNull } from '../utils/fs.js';\n\n/**\n * The 8 categories of consumer-side files that `teamix-evo init` may\n * conflict with when running against a non-teamix-evo project.\n *\n * See ADR 0019 D1 task #5 — these are the only files we mutate at\n * `init` time, so they're the only ones we ask the user about.\n */\nexport type ConflictKey =\n | 'agents-md'\n | 'components-json'\n | 'tailwind-config'\n | 'tokens'\n | 'index-css'\n | 'shadcn-source'\n | 'eslint-config'\n | 'stylelint-config';\n\n/** Strategy options per conflict category. */\nexport type ConflictStrategy =\n // agents-md\n | 'overwrite'\n | 'merge-managed'\n | 'skip'\n // components-json\n | 'diff-prompt'\n // tailwind-config\n | 'backup-overwrite'\n // tokens\n | 'migrate'\n | 'coexist'\n // index-css\n | 'append'\n // shadcn-source\n | 'skip-existing'\n | 'per-file-prompt'\n // eslint-config / stylelint-config (Phase 3.E)\n | 'merge';\n\nexport interface ConflictItem {\n /** Stable id for the category. */\n key: ConflictKey;\n /** True if at least one path in `paths` matched on disk. */\n exists: boolean;\n /**\n * Project-relative paths that matched. Empty when `exists === false`.\n * For `shadcn-source`, may contain a directory path (with trailing `/`).\n */\n paths: string[];\n /** sha256 fingerprint of (sorted) matched contents. Omitted for directories or when nothing matched. */\n fingerprint?: string;\n /** Default strategy presented to the user. */\n recommendedStrategy: ConflictStrategy;\n /** All allowed strategies for this category, in display order. */\n availableStrategies: ConflictStrategy[];\n /** Category-specific metadata (e.g. detected tailwind major version). */\n meta?: Record<string, unknown>;\n}\n\nexport interface ConflictReport {\n cwd: string;\n /** Always 8 items, ordered by ConflictKey enumeration above. */\n items: ConflictItem[];\n /** True if any item has `exists === true`. */\n hasAnyConflict: boolean;\n}\n\n// ─── Path candidates per category ────────────────────────────────────────────\n\nconst TAILWIND_CONFIG_CANDIDATES = [\n 'tailwind.config.ts',\n 'tailwind.config.js',\n 'tailwind.config.cjs',\n 'tailwind.config.mjs',\n];\n\nconst TOKENS_FILE_CANDIDATES = [\n 'src/design-tokens.css',\n 'src/styles/design-tokens.css',\n 'src/styles/tokens.css',\n];\n\nconst TOKENS_DIR_CANDIDATES = ['tokens'];\n\nconst INDEX_CSS_CANDIDATES = [\n 'src/index.css',\n 'src/main.css',\n 'src/app.css',\n 'src/styles/index.css',\n 'src/styles/globals.css',\n];\n\nconst SHADCN_FILE_CANDIDATES = ['src/lib/utils.ts'];\nconst SHADCN_DIR_CANDIDATES = ['src/components/ui'];\n\n// Phase 3.E: 8 ESLint candidates (legacy `.eslintrc.*` + flat `eslint.config.*`)\nconst ESLINT_CONFIG_CANDIDATES = [\n '.eslintrc.cjs',\n '.eslintrc.js',\n '.eslintrc.json',\n '.eslintrc.yml',\n 'eslint.config.js',\n 'eslint.config.cjs',\n 'eslint.config.mjs',\n 'eslint.config.ts',\n];\n\n// Phase 3.E: 8 Stylelint candidates (legacy `.stylelintrc.*` + flat `stylelint.config.*`)\nconst STYLELINT_CONFIG_CANDIDATES = [\n '.stylelintrc.cjs',\n '.stylelintrc.js',\n '.stylelintrc.json',\n '.stylelintrc.yml',\n 'stylelint.config.cjs',\n 'stylelint.config.js',\n 'stylelint.config.mjs',\n 'stylelint.config.ts',\n];\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nasync function isDir(target: string): Promise<boolean> {\n try {\n const stat = await fs.stat(target);\n return stat.isDirectory();\n } catch {\n return false;\n }\n}\n\nasync function dirHasContent(target: string): Promise<boolean> {\n try {\n const entries = await fs.readdir(target);\n return entries.length > 0;\n } catch {\n return false;\n }\n}\n\n/** Hash of UTF-8 string content; truncate to 16 chars for log readability. */\nfunction fingerprint(parts: string[]): string {\n const hash = crypto.createHash('sha256');\n for (const p of [...parts].sort()) hash.update(p);\n return `sha256:${hash.digest('hex').slice(0, 16)}`;\n}\n\ninterface PackageJsonShape {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n\nasync function readPackageJson(cwd: string): Promise<PackageJsonShape | null> {\n const raw = await readFileOrNull(path.join(cwd, 'package.json'));\n if (raw === null) return null;\n try {\n return JSON.parse(raw) as PackageJsonShape;\n } catch {\n return null;\n }\n}\n\n/**\n * Detect tailwind major version from package.json.\n * Returns 4 / 3 / null. We trust dependencies + devDependencies.\n */\nfunction detectTailwindMajor(pkg: PackageJsonShape | null): 3 | 4 | null {\n if (!pkg) return null;\n const v =\n pkg.dependencies?.tailwindcss ?? pkg.devDependencies?.tailwindcss ?? null;\n if (!v) return null;\n // Accept \"^4.0.0\" / \"~4.2.2\" / \"4.x\" / \"next\" → conservative: parse leading digit\n const m = /(\\d+)/.exec(v);\n if (!m) return null;\n const major = Number.parseInt(m[1]!, 10);\n if (major === 3) return 3;\n if (major === 4) return 4;\n return null;\n}\n\n// ─── Per-category detectors ──────────────────────────────────────────────────\n\nasync function detectAgentsMd(cwd: string): Promise<ConflictItem> {\n const target = path.join(cwd, 'AGENTS.md');\n const content = await readFileOrNull(target);\n const exists = content !== null;\n return {\n key: 'agents-md',\n exists,\n paths: exists ? ['AGENTS.md'] : [],\n fingerprint: exists ? fingerprint([content!]) : undefined,\n recommendedStrategy: exists ? 'merge-managed' : 'overwrite',\n availableStrategies: ['merge-managed', 'overwrite', 'skip'],\n };\n}\n\nasync function detectComponentsJson(cwd: string): Promise<ConflictItem> {\n const target = path.join(cwd, 'components.json');\n const content = await readFileOrNull(target);\n const exists = content !== null;\n return {\n key: 'components-json',\n exists,\n paths: exists ? ['components.json'] : [],\n fingerprint: exists ? fingerprint([content!]) : undefined,\n recommendedStrategy: exists ? 'diff-prompt' : 'overwrite',\n availableStrategies: ['diff-prompt', 'overwrite', 'skip'],\n };\n}\n\nasync function detectTailwindConfig(cwd: string): Promise<ConflictItem> {\n const matched: string[] = [];\n const contents: string[] = [];\n for (const rel of TAILWIND_CONFIG_CANDIDATES) {\n const c = await readFileOrNull(path.join(cwd, rel));\n if (c !== null) {\n matched.push(rel);\n contents.push(c);\n }\n }\n const pkg = await readPackageJson(cwd);\n const tailwindMajor = detectTailwindMajor(pkg);\n const exists = matched.length > 0;\n return {\n key: 'tailwind-config',\n exists,\n paths: matched,\n fingerprint: exists ? fingerprint(contents) : undefined,\n recommendedStrategy: exists ? 'backup-overwrite' : 'overwrite',\n availableStrategies: ['backup-overwrite', 'overwrite', 'skip'],\n meta: { tailwindMajor },\n };\n}\n\nasync function detectTokens(cwd: string): Promise<ConflictItem> {\n const matched: string[] = [];\n const contents: string[] = [];\n for (const rel of TOKENS_FILE_CANDIDATES) {\n const c = await readFileOrNull(path.join(cwd, rel));\n if (c !== null) {\n matched.push(rel);\n contents.push(c);\n }\n }\n for (const rel of TOKENS_DIR_CANDIDATES) {\n const abs = path.join(cwd, rel);\n if ((await isDir(abs)) && (await dirHasContent(abs))) {\n matched.push(`${rel}/`);\n }\n }\n const exists = matched.length > 0;\n return {\n key: 'tokens',\n exists,\n paths: matched,\n fingerprint: contents.length > 0 ? fingerprint(contents) : undefined,\n recommendedStrategy: exists ? 'migrate' : 'overwrite',\n availableStrategies: ['migrate', 'coexist', 'overwrite', 'skip'],\n };\n}\n\nasync function detectIndexCss(cwd: string): Promise<ConflictItem> {\n const matched: string[] = [];\n const contents: string[] = [];\n for (const rel of INDEX_CSS_CANDIDATES) {\n const c = await readFileOrNull(path.join(cwd, rel));\n if (c !== null) {\n matched.push(rel);\n contents.push(c);\n }\n }\n const exists = matched.length > 0;\n return {\n key: 'index-css',\n exists,\n paths: matched,\n fingerprint: exists ? fingerprint(contents) : undefined,\n recommendedStrategy: exists ? 'append' : 'overwrite',\n availableStrategies: ['append', 'diff-prompt', 'overwrite', 'skip'],\n };\n}\n\nasync function detectShadcnSource(cwd: string): Promise<ConflictItem> {\n const matched: string[] = [];\n for (const rel of SHADCN_FILE_CANDIDATES) {\n if (await fileExists(path.join(cwd, rel))) matched.push(rel);\n }\n for (const rel of SHADCN_DIR_CANDIDATES) {\n const abs = path.join(cwd, rel);\n if ((await isDir(abs)) && (await dirHasContent(abs))) {\n matched.push(`${rel}/`);\n }\n }\n // For shadcn dir, count component files for meta.\n let componentCount = 0;\n try {\n const uiDir = path.join(cwd, 'src/components/ui');\n if (await isDir(uiDir)) {\n const entries = await fs.readdir(uiDir);\n componentCount = entries.filter(\n (e) => e.endsWith('.tsx') || e.endsWith('.ts'),\n ).length;\n }\n } catch {\n // ignore\n }\n const exists = matched.length > 0;\n return {\n key: 'shadcn-source',\n exists,\n paths: matched,\n recommendedStrategy: exists ? 'skip-existing' : 'overwrite',\n availableStrategies: ['skip-existing', 'per-file-prompt', 'overwrite'],\n meta: { componentCount },\n };\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/**\n * Inspect `cwd` for the 8 categories of files that `teamix-evo init` may\n * touch. Pure read-only — never mutates the filesystem. Returns one\n * `ConflictItem` per category in stable order so callers can render a\n * deterministic wizard.\n */\nexport async function detectConflicts(cwd: string): Promise<ConflictReport> {\n const absCwd = path.resolve(cwd);\n const items: ConflictItem[] = await Promise.all([\n detectAgentsMd(absCwd),\n detectComponentsJson(absCwd),\n detectTailwindConfig(absCwd),\n detectTokens(absCwd),\n detectIndexCss(absCwd),\n detectShadcnSource(absCwd),\n detectEslintConfig(absCwd),\n detectStylelintConfig(absCwd),\n ]);\n return {\n cwd: absCwd,\n items,\n hasAnyConflict: items.some((i) => i.exists),\n };\n}\n\nasync function detectEslintConfig(cwd: string): Promise<ConflictItem> {\n const matched: string[] = [];\n const contents: string[] = [];\n for (const rel of ESLINT_CONFIG_CANDIDATES) {\n const c = await readFileOrNull(path.join(cwd, rel));\n if (c !== null) {\n matched.push(rel);\n contents.push(c);\n }\n }\n const exists = matched.length > 0;\n return {\n key: 'eslint-config',\n exists,\n paths: matched,\n fingerprint: exists ? fingerprint(contents) : undefined,\n recommendedStrategy: exists ? 'merge' : 'overwrite',\n availableStrategies: ['merge', 'backup-overwrite', 'overwrite', 'skip'],\n };\n}\n\nasync function detectStylelintConfig(cwd: string): Promise<ConflictItem> {\n const matched: string[] = [];\n const contents: string[] = [];\n for (const rel of STYLELINT_CONFIG_CANDIDATES) {\n const c = await readFileOrNull(path.join(cwd, rel));\n if (c !== null) {\n matched.push(rel);\n contents.push(c);\n }\n }\n const exists = matched.length > 0;\n return {\n key: 'stylelint-config',\n exists,\n paths: matched,\n fingerprint: exists ? fingerprint(contents) : undefined,\n recommendedStrategy: exists ? 'merge' : 'overwrite',\n availableStrategies: ['merge', 'backup-overwrite', 'overwrite', 'skip'],\n };\n}\n","/**\n * meta-installer.ts\n *\n * Lands component meta files (manifest.json + per-component meta.md) into\n * `.teamix-evo/meta/<category>/` so that AI skills can read them locally\n * without network access.\n *\n * Called during `teamix-evo init` (after ui-add / biz-ui-add) and\n * `teamix-evo ui upgrade` / `teamix-evo biz-ui upgrade`.\n */\nimport * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport type { UiEntry } from '@teamix-evo/registry';\nimport {\n loadUiPackageManifest,\n loadVariantUiPackageManifest,\n} from '@teamix-evo/registry';\nimport { getTeamixDir, ensureTeamixDir } from './state.js';\nimport { ensureDir } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\nconst require = createRequire(import.meta.url);\n\nconst META_DIR = 'meta';\n\nfunction resolvePackageRoot(packageName: string): string {\n const pkgJsonPath = require.resolve(`${packageName}/package.json`);\n return path.dirname(pkgJsonPath);\n}\n\n/**\n * Resolve the `.teamix-evo/meta/<category>/` directory.\n */\nexport function getMetaDir(projectRoot: string, category?: string): string {\n const base = path.join(getTeamixDir(projectRoot), META_DIR);\n return category ? path.join(base, category) : base;\n}\n\nexport interface MetaLandingResult {\n category: string;\n manifestWritten: boolean;\n metaFilesWritten: number;\n metaFilesTotal: number;\n}\n\n/**\n * Land ui package meta files to `.teamix-evo/meta/ui/`.\n *\n * Copies:\n * - manifest.json → `.teamix-evo/meta/ui/manifest.json`\n * - Each entry's meta.md → `.teamix-evo/meta/ui/<id>.md`\n */\nexport async function landUiMeta(\n projectRoot: string,\n): Promise<MetaLandingResult> {\n const packageRoot = resolvePackageRoot('@teamix-evo/ui');\n const manifest = await loadUiPackageManifest(packageRoot);\n\n return landManifestMeta({\n projectRoot,\n packageRoot,\n manifest,\n category: 'ui',\n });\n}\n\n/**\n * Land biz-ui variant meta files to `.teamix-evo/meta/biz-ui/`.\n */\nexport async function landBizUiMeta(\n projectRoot: string,\n variant: string,\n): Promise<MetaLandingResult> {\n const packageRoot = resolvePackageRoot('@teamix-evo/biz-ui');\n const variantRoot = path.join(packageRoot, 'variants', variant);\n const manifest = await loadVariantUiPackageManifest(variantRoot);\n\n return landManifestMeta({\n projectRoot,\n packageRoot: variantRoot,\n manifest,\n category: 'biz-ui',\n });\n}\n\nasync function landManifestMeta(opts: {\n projectRoot: string;\n packageRoot: string;\n manifest: { entries: UiEntry[] };\n category: string;\n}): Promise<MetaLandingResult> {\n const { projectRoot, packageRoot, manifest, category } = opts;\n await ensureTeamixDir(projectRoot);\n const metaDir = getMetaDir(projectRoot, category);\n await ensureDir(metaDir);\n\n const manifestDest = path.join(metaDir, 'manifest.json');\n const manifestSrc = path.join(packageRoot, 'manifest.json');\n await fs.copyFile(manifestSrc, manifestDest);\n logger.debug(`meta: copied manifest.json → ${manifestDest}`);\n\n let written = 0;\n let total = 0;\n\n for (const entry of manifest.entries) {\n if (!entry.meta) continue;\n total++;\n\n const srcPath = path.join(packageRoot, entry.meta);\n const destPath = path.join(metaDir, `${entry.id}.md`);\n\n try {\n await fs.copyFile(srcPath, destPath);\n written++;\n logger.debug(`meta: ${entry.id} → ${destPath}`);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n logger.warn(`meta: ${entry.id} — source not found: ${srcPath}`);\n } else {\n throw err;\n }\n }\n }\n\n logger.info(\n ` meta/${category}: ${written}/${total} meta files, manifest.json`,\n );\n\n return {\n category,\n manifestWritten: true,\n metaFilesWritten: written,\n metaFilesTotal: total,\n };\n}\n\n/**\n * Land meta for a single component (used during upgrade).\n */\nexport async function landSingleMeta(opts: {\n projectRoot: string;\n category: string;\n entryId: string;\n metaSourcePath: string;\n}): Promise<boolean> {\n const { projectRoot, category, entryId, metaSourcePath } = opts;\n const metaDir = getMetaDir(projectRoot, category);\n await ensureDir(metaDir);\n\n const destPath = path.join(metaDir, `${entryId}.md`);\n try {\n await fs.copyFile(metaSourcePath, destPath);\n logger.debug(`meta: updated ${entryId} → ${destPath}`);\n return true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n logger.warn(`meta: ${entryId} — source not found: ${metaSourcePath}`);\n return false;\n }\n throw err;\n }\n}\n","/**\n * npm dependency auto-installer for `teamix-evo init`.\n *\n * After `runUiAdd` completes, this module:\n * 1. Collects `npmDependencies` from the install result\n * 2. Reads the project's `package.json`\n * 3. Writes missing deps into `dependencies`\n * 4. Detects the package manager and runs install\n *\n * See PLAN Task 3.8 (P0).\n */\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { fileExists, readFileOrNull } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\nconst execAsync = promisify(exec);\n\n// ─── Public types ────────────────────────────────────────────────────────────\n\nexport interface DepsInstallOptions {\n /** Absolute project root */\n projectRoot: string;\n /** npm dependencies to install (name → semver range) */\n npmDependencies: Record<string, string>;\n /** Skip the actual install command (just patch package.json) */\n skipInstall?: boolean;\n}\n\nexport interface DepsInstallResult {\n /** Deps newly written to package.json */\n added: Record<string, string>;\n /** Deps that already existed (skipped) */\n existed: Record<string, string>;\n /** Whether install command was executed */\n installed: boolean;\n /** Detected package manager */\n packageManager: PackageManager;\n}\n\n// ─── Package manager detection ───────────────────────────────────────────────\n\ntype PackageManager = 'pnpm' | 'yarn' | 'bun' | 'npm';\n\nasync function detectPackageManager(\n projectRoot: string,\n): Promise<PackageManager> {\n if (await fileExists(path.join(projectRoot, 'pnpm-lock.yaml'))) return 'pnpm';\n if (await fileExists(path.join(projectRoot, 'pnpm-workspace.yaml')))\n return 'pnpm';\n if (await fileExists(path.join(projectRoot, 'bun.lockb'))) return 'bun';\n if (await fileExists(path.join(projectRoot, 'bun.lock'))) return 'bun';\n if (await fileExists(path.join(projectRoot, 'yarn.lock'))) return 'yarn';\n return 'npm';\n}\n\nfunction getInstallCommand(pm: PackageManager): string {\n switch (pm) {\n case 'pnpm':\n return 'pnpm install';\n case 'yarn':\n return 'yarn install';\n case 'bun':\n return 'bun install';\n case 'npm':\n return 'npm install';\n }\n}\n\n// ─── Core installer ──────────────────────────────────────────────────────────\n\n/**\n * Patch project `package.json` with missing npm dependencies and optionally\n * run the package manager's install command.\n */\nexport async function installProjectDeps(\n options: DepsInstallOptions,\n): Promise<DepsInstallResult> {\n const { projectRoot, npmDependencies, skipInstall = false } = options;\n\n const pkgPath = path.join(projectRoot, 'package.json');\n const raw = await readFileOrNull(pkgPath);\n if (!raw) {\n throw new Error(\n `package.json not found at ${projectRoot}. Cannot install dependencies.`,\n );\n }\n\n const pkg = JSON.parse(raw) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n\n const existingDeps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n\n const added: Record<string, string> = {};\n const existed: Record<string, string> = {};\n\n for (const [name, range] of Object.entries(npmDependencies)) {\n if (existingDeps[name]) {\n existed[name] = existingDeps[name]!;\n } else {\n added[name] = range;\n }\n }\n\n // Patch package.json if there are new deps\n if (Object.keys(added).length > 0) {\n if (!pkg.dependencies) pkg.dependencies = {};\n for (const [name, range] of Object.entries(added)) {\n pkg.dependencies[name] = range;\n }\n // Sort dependencies alphabetically\n pkg.dependencies = Object.fromEntries(\n Object.entries(pkg.dependencies).sort(([a], [b]) => a.localeCompare(b)),\n );\n\n await fs.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\\n', 'utf-8');\n logger.info(\n ` patched package.json: +${Object.keys(added).length} dependencies`,\n );\n }\n\n // Detect package manager and run install\n const packageManager = await detectPackageManager(projectRoot);\n let installed = false;\n\n if (!skipInstall && Object.keys(added).length > 0) {\n const cmd = getInstallCommand(packageManager);\n logger.info(` running ${cmd}...`);\n try {\n await execAsync(cmd, { cwd: projectRoot, timeout: 120_000 });\n installed = true;\n logger.info(' install complete');\n } catch (err) {\n logger.warn(\n ` install failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n logger.warn(' please run install manually');\n }\n }\n\n return { added, existed, installed, packageManager };\n}\n","/**\n * Generates the `.teamix-evo/init-checklist.md` content after `teamix-evo init`.\n *\n * Simplified for ADR 0043: only records the 8-step pipeline results.\n * No Phase B — post-init guidance is handled by AI skills at runtime.\n */\n\nimport type { ProjectInitStep } from './project-init.js';\n\n/** Step display metadata. */\nconst STEP_LABELS: Record<string, string> = {\n tokens: 'tokens — design tokens 安装',\n skills: 'skills — AI skills 批量自举',\n 'agents-md': 'agents-md — AGENTS.md 生成',\n 'ui-init': 'ui-init — UI 配置初始化',\n 'ui-add': 'ui-add — UI 组件全量安装',\n 'biz-ui-add': 'biz-ui-add — 业务组件全量安装',\n lint: 'lint — ESLint + Stylelint 配置',\n gitignore: 'gitignore — .gitignore 追加',\n};\n\nexport function renderInitChecklist(args: {\n variant: string;\n status: string;\n steps: ProjectInitStep[];\n timestamp?: string;\n}): string {\n const { variant, status, steps } = args;\n const ts =\n args.timestamp ?? new Date().toISOString().replace('T', ' ').slice(0, 19);\n\n const stepLines = steps\n .map((s) => {\n const label = STEP_LABELS[s.name] ?? s.name;\n const checked = s.status === 'ok' ? 'x' : ' ';\n const suffix =\n s.status === 'ok'\n ? ''\n : s.status === 'skip'\n ? `(跳过${s.detail ? ':' + s.detail : ''})`\n : s.status === 'fail'\n ? `(失败:${s.detail ?? 'unknown'})`\n : '(计划中)';\n return `- [${checked}] ${label}${suffix}`;\n })\n .join('\\n');\n\n return `# teamix-evo init 安装摘要\n\n> 由 \\`teamix-evo init\\` 自动生成 · ${ts}\n> variant: ${variant} · status: ${status}\n\n## 安装步骤\n\n${stepLines}\n\n## 备注\n\n- 失败或跳过的步骤不影响后续步骤独立执行\n- 修复后重跑 \\`teamix-evo init\\`(每步幂等,自动跳过已完成项)\n- 如需全量覆盖:\\`teamix-evo init --force\\`\n`;\n}\n","/**\n * File-change ledger for the init / update pipelines.\n *\n * Phase 1.A1 (init 落地改进): every orchestrator step records what it touched\n * so the CLI can print a single \"新建 / 修改 / 备份 / 删除\" summary at the end.\n * Today's pipeline only piggybacks on side-effectful sub-commands' result\n * objects (`resources`, `wroteEslint`, …) — without an explicit ledger the\n * user has no way to see, in one glance, which user-owned files moved.\n *\n * Design constraints:\n * - Pure data type — no I/O, no global mutable state. The orchestrator passes\n * a single mutable array down to each helper; sub-step adapters return\n * `FileChange[]` they can derive from their own return values.\n * - \"modified\" vs \"created\" is decided by checking whether a fresh backup\n * exists under `.teamix-evo/.backups/<rel>.*.bak` for that path — see\n * {@link diffBackupSet}. Any path that gained a backup during the pipeline\n * is classified `modified`; everything else surfaced by the steps is\n * `created`. This keeps the classification truthful even when a sub-step\n * has no idea whether the file pre-existed.\n */\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nexport type FileChangeKind = 'created' | 'modified' | 'backed-up' | 'deleted';\n\nexport interface FileChange {\n kind: FileChangeKind;\n /** Project-root-relative path, posix style (forward slashes). */\n path: string;\n /** Originating pipeline step (free-form to avoid coupling on `ProjectInitStepName`). */\n step: string;\n /** Optional human-readable note (e.g. `frozen` / `regenerable` / `managed`). */\n detail?: string;\n}\n\n/**\n * Convert any abs/rel path to a project-root-relative posix path.\n * Returns the input unchanged if it cannot be relativised.\n */\nexport function toRelativePosix(p: string, projectRoot: string): string {\n let rel = p;\n if (path.isAbsolute(p)) {\n rel = path.relative(projectRoot, p);\n }\n return rel.split(path.sep).join('/');\n}\n\n/**\n * Recursively enumerate `.teamix-evo/.backups/` and return the set of\n * original (project-root-relative) paths that have at least one `.bak` copy.\n *\n * Backup file names follow `<rel>.<isoTsSafe>.bak` where `<isoTsSafe>` is the\n * output of `new Date().toISOString().replace(/[:.]/g, '-')` — a fixed-shape\n * `YYYY-MM-DDTHH-MM-SS-mmmZ` token. We strip that suffix to recover `<rel>`.\n *\n * Returns an empty set when the backups directory does not exist.\n */\nexport async function listBackupOriginals(\n projectRoot: string,\n): Promise<Set<string>> {\n const backupsDir = path.join(projectRoot, '.teamix-evo', '.backups');\n const out = new Set<string>();\n const stack: string[] = [backupsDir];\n while (stack.length > 0) {\n const dir = stack.pop()!;\n let entries: import('node:fs').Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') continue;\n throw err;\n }\n for (const e of entries) {\n const full = path.join(dir, e.name);\n if (e.isDirectory()) {\n stack.push(full);\n } else if (e.isFile() && e.name.endsWith('.bak')) {\n const rel = path.relative(backupsDir, full);\n const original = stripBackupSuffix(rel);\n if (original) out.add(original.split(path.sep).join('/'));\n }\n }\n }\n return out;\n}\n\n/**\n * Strip the `.<isoTsSafe>.bak` tail from a backup-relative path. Returns null\n * when the suffix doesn't match (file isn't one of ours — leave untouched).\n */\nexport function stripBackupSuffix(rel: string): string | null {\n const m = rel.match(\n /^(.+)\\.\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-\\d{3}Z\\.bak$/,\n );\n return m?.[1] ?? null;\n}\n\n/**\n * Compute the relative-path set that gained a fresh backup between `before`\n * and `after` (i.e. paths the pipeline modified in-place).\n */\nexport function diffBackupSet(\n before: ReadonlySet<string>,\n after: ReadonlySet<string>,\n): Set<string> {\n const out = new Set<string>();\n for (const p of after) {\n if (!before.has(p)) out.add(p);\n }\n return out;\n}\n\n/**\n * Format a flat list of `FileChange` rows into a markdown-ish summary.\n * Returns an array of lines suitable for the CLI logger.\n *\n * Empty buckets are omitted from the output. Order: created → modified →\n * backed-up → deleted. Each bucket lists paths sorted lexicographically with\n * de-duplication on `(kind, path)`.\n */\nexport function formatFileChangeSummary(changes: FileChange[]): string[] {\n if (changes.length === 0) return [];\n const buckets: Record<FileChangeKind, Map<string, FileChange>> = {\n created: new Map(),\n modified: new Map(),\n 'backed-up': new Map(),\n deleted: new Map(),\n };\n for (const c of changes) {\n const existing = buckets[c.kind].get(c.path);\n if (!existing) buckets[c.kind].set(c.path, c);\n }\n const order: Array<[FileChangeKind, string]> = [\n ['created', '🆕 新建'],\n ['modified', '✏️ 修改'],\n ['backed-up', '💾 已备份'],\n ['deleted', '🗑 删除'],\n ];\n const lines: string[] = [];\n for (const [kind, label] of order) {\n const bucket = buckets[kind];\n if (bucket.size === 0) continue;\n lines.push(`${label}(${bucket.size}):`);\n const sorted = [...bucket.values()].sort((a, b) =>\n a.path.localeCompare(b.path),\n );\n for (const c of sorted) {\n const detail = c.detail ? ` — ${c.detail}` : '';\n lines.push(` • ${c.path} [${c.step}]${detail}`);\n }\n }\n return lines;\n}\n","/**\n * Programmatic orchestrator for `teamix-evo init` (ADR 0043).\n *\n * Drives the 8-step pipeline that installs the full teamix-evo suite into an\n * existing project. Each step is idempotent — re-running `init` picks up from\n * where it left off.\n *\n * Conflict handling is intentionally thin (ADR 0043 §3): detect → terminate →\n * structured output → AI decides. The orchestrator only checks `force` — when\n * true, it skips conflict detection entirely.\n */\nimport type { SkillIde, SkillScope } from '@teamix-evo/registry';\nimport { runTokensInit } from './tokens-init.js';\nimport { runSkillsInit } from './skills-add.js';\nimport { runGenerateAgentsMd } from './agents-md.js';\nimport { runUiInit } from './ui-init.js';\nimport { runUiAdd } from './ui-add.js';\nimport { runBizUiAdd, listBizUiEntries } from './variant-ui-add.js';\nimport { runLintInit } from './lint-init.js';\nimport { landUiMeta, landBizUiMeta } from './meta-installer.js';\nimport { installProjectDeps } from './deps-install.js';\nimport { loadUiData } from './ui-client.js';\nimport { renderInitChecklist } from './init-checklist-template.js';\nimport { getErrorMessage } from '../utils/error.js';\nimport { logger } from '../utils/logger.js';\nimport { type FileChange, toRelativePosix } from './file-changes.js';\nimport * as fsNode from 'node:fs/promises';\nimport * as path from 'node:path';\n\n// ─── Types ─────────────────────────────────────────────────────────────────────\n\nexport type ProjectInitStepName =\n | 'tokens'\n | 'skills'\n | 'agents-md'\n | 'ui-init'\n | 'ui-add'\n | 'biz-ui-add'\n | 'meta-landing'\n | 'lint'\n | 'gitignore';\n\nexport type ProjectInitStepStatus = 'ok' | 'skip' | 'fail' | 'planned';\n\nexport interface ProjectInitStep {\n name: ProjectInitStepName;\n status: ProjectInitStepStatus;\n detail?: string;\n /** Files this step touched. */\n changes?: FileChange[];\n}\n\nexport interface ResumeHint {\n failedAt: ProjectInitStepName;\n completed: ProjectInitStepName[];\n failed: ProjectInitStepName[];\n error: string;\n resumeCommand: string;\n}\n\nexport interface RunProjectInitOptions {\n /** Absolute project root (existing repo to adopt teamix-evo into). */\n projectRoot: string;\n /** Tokens variant (e.g. \"opentrek\" / \"uni-manager\"). */\n variant: string;\n /** Target IDEs (at least one). */\n ides: SkillIde[];\n /** Skill install scope. Defaults to 'project'. */\n scope?: SkillScope;\n /**\n * When true, skip conflict detection and overwrite everything.\n * Distinction: init --force = skip conflict check; create --force = overwrite directory.\n */\n force?: boolean;\n /** Skip `npm install` for lint deps. */\n skipInstall?: boolean;\n /** Step-level progress hook. */\n onStep?: (step: ProjectInitStep) => void;\n /** Plan-only mode: compute steps without running sub-commands. */\n dryRun?: boolean;\n}\n\nexport interface RunProjectInitResult {\n status: 'installed' | 'partial' | 'dry-run';\n steps: ProjectInitStep[];\n changes: FileChange[];\n resumeHint?: ResumeHint;\n}\n\n// ─── Constants ──────────────────────────────────────────────────────────────────\n\n/**\n * Steps whose failure aborts subsequent critical steps. Non-critical leaves\n * (agents-md / ui-add / biz-ui-add / lint / gitignore) continue independently.\n */\nconst CRITICAL_STEPS: ReadonlySet<ProjectInitStepName> = new Set([\n 'tokens',\n 'skills',\n 'ui-init',\n]);\n\nconst GITIGNORE_MARKER_START = '# >>> teamix-evo:managed >>>';\nconst GITIGNORE_MARKER_END = '# <<< teamix-evo:managed <<<';\nconst GITIGNORE_RULES = [\n '# Runtime artifacts (regenerable / archives)',\n '.teamix-evo/.snapshots/',\n '.teamix-evo/.backups/',\n '.teamix-evo/.upgrade-staging/',\n '.teamix-evo/.upgrade-hints/',\n];\n\n// ─── Orchestrator ───────────────────────────────────────────────────────────────\n\nexport async function runProjectInit(\n options: RunProjectInitOptions,\n): Promise<RunProjectInitResult> {\n const {\n projectRoot,\n variant,\n ides,\n scope = 'project',\n dryRun = false,\n onStep,\n } = options;\n const ide = ides[0] ?? 'qoder';\n const steps: ProjectInitStep[] = [];\n const allChanges: FileChange[] = [];\n\n let aborted = false;\n const firstFailure: {\n value: { step: ProjectInitStepName; error: string } | null;\n } = { value: null };\n\n function record(step: ProjectInitStep): void {\n steps.push(step);\n onStep?.(step);\n if (step.changes && step.changes.length > 0) {\n allChanges.push(...step.changes);\n }\n }\n\n function recordFailure(name: ProjectInitStepName, err: unknown): void {\n const message = getErrorMessage(err);\n record({ name, status: 'fail', detail: message });\n if (!firstFailure.value)\n firstFailure.value = { step: name, error: message };\n if (CRITICAL_STEPS.has(name)) aborted = true;\n }\n\n // ─── 1. tokens ──────────────────────────────────────────────────────────────\n if (dryRun) {\n record({\n name: 'tokens',\n status: 'planned',\n detail: `runTokensInit(variant=${variant})`,\n });\n } else {\n try {\n const result = await runTokensInit({ projectRoot, variant, ide });\n const detail =\n result.status === 'installed'\n ? `${result.packageName}@${result.version} (${result.count} files)`\n : result.status;\n record({\n name: 'tokens',\n status: 'ok',\n detail,\n changes:\n result.status === 'installed'\n ? result.resources.map((r) => ({\n kind: 'created' as const,\n path: toRelativePosix(r.target, projectRoot),\n step: 'tokens',\n detail: r.strategy,\n }))\n : [],\n });\n } catch (err) {\n recordFailure('tokens', err);\n }\n }\n\n // ─── 2. skills init (batch bootstrap) ────────────────────────────────────────\n if (dryRun) {\n record({\n name: 'skills',\n status: 'planned',\n detail: `runSkillsInit(scope=${scope})`,\n });\n } else if (aborted) {\n record({\n name: 'skills',\n status: 'skip',\n detail: 'aborted: earlier critical step failed',\n });\n } else {\n try {\n const result = await runSkillsInit({ projectRoot, ides, scope, ide });\n if (result.status === 'already-initialized') {\n record({ name: 'skills', status: 'ok', detail: 'already-initialized' });\n } else {\n record({\n name: 'skills',\n status: 'ok',\n detail: `${result.skillCount} skills, ${\n result.fileCount\n } files (added: ${result.addedSkillIds.join(', ') || 'none'})`,\n changes: result.addedSkillIds.map((id) => ({\n kind: 'created' as const,\n path: `.${ides[0] ?? 'qoder'}/skills/${id}/SKILL.md`,\n step: 'skills',\n detail: 'skill installed',\n })),\n });\n }\n } catch (err) {\n recordFailure('skills', err);\n }\n }\n\n // ─── 3. AGENTS.md ─────────────────────────────────────────────────────────────\n if (dryRun) {\n record({\n name: 'agents-md',\n status: 'planned',\n detail: 'runGenerateAgentsMd()',\n });\n } else {\n try {\n const result = await runGenerateAgentsMd({\n projectRoot,\n variant,\n skillIds: [\n `teamix-evo-design-${variant}`,\n `teamix-evo-code-${variant}`,\n ],\n mode: 'merge-managed',\n });\n record({\n name: 'agents-md',\n status: 'ok',\n detail: `${result.skillCount} skill index`,\n changes: [\n {\n kind: result.backedUp ? 'modified' : 'created',\n path: toRelativePosix(result.path, projectRoot),\n step: 'agents-md',\n detail: 'skill-trigger fallback (ADR 0038)',\n },\n ],\n });\n } catch (err) {\n recordFailure('agents-md', err);\n }\n }\n\n // ─── 4. ui-init (.teamix-evo/config.json) ──────────────────────────────────────\n if (dryRun) {\n record({ name: 'ui-init', status: 'planned', detail: 'runUiInit()' });\n } else if (aborted) {\n record({\n name: 'ui-init',\n status: 'skip',\n detail: 'aborted: earlier critical step failed',\n });\n } else {\n try {\n const initResult = await runUiInit({ projectRoot, ide });\n record({\n name: 'ui-init',\n status: 'ok',\n detail:\n initResult.status === 'installed'\n ? 'config.json packages.ui written'\n : initResult.status,\n });\n } catch (err) {\n recordFailure('ui-init', err);\n }\n }\n\n // ─── 5. ui add --all (全量 UI 组件源码) ────────────────────────────────────────\n // 收集 ui-add + biz-ui-add 的 npm 依赖,统一在两步之后调用 installProjectDeps。\n const collectedNpmDeps: Record<string, string> = {};\n if (dryRun) {\n const { manifest } = await loadUiData('@teamix-evo/ui').catch(() => ({\n manifest: { entries: [] as Array<{ id: string }> },\n }));\n record({\n name: 'ui-add',\n status: 'planned',\n detail: `runUiAdd(${manifest.entries.length} entries, --all)`,\n });\n } else if (aborted) {\n record({\n name: 'ui-add',\n status: 'skip',\n detail: 'aborted: earlier critical step failed',\n });\n } else {\n try {\n const { manifest } = await loadUiData('@teamix-evo/ui');\n const allIds = manifest.entries.map((e) => e.id);\n const addResult = await runUiAdd({\n projectRoot,\n ids: allIds,\n overwrite: true,\n });\n // slice(-0) === slice(0) 返回全量;written === 0 时显式返回空数组\n const writtenResources =\n addResult.written > 0\n ? addResult.resources.slice(-addResult.written)\n : [];\n record({\n name: 'ui-add',\n status: 'ok',\n detail: `${addResult.orderedIds.length} entries (${addResult.written} written, ${addResult.skipped} skipped)`,\n changes: writtenResources.map((r) => ({\n kind: 'created' as const,\n path: toRelativePosix(r.target, projectRoot),\n step: 'ui-add',\n detail: r.strategy,\n })),\n });\n Object.assign(collectedNpmDeps, addResult.npmDependencies);\n } catch (err) {\n recordFailure('ui-add', err);\n }\n }\n\n // ─── 6. biz-ui add --all (variant 全量业务组件) ─────────────────────────────────\n if (dryRun) {\n try {\n const listing = await listBizUiEntries(variant);\n record({\n name: 'biz-ui-add',\n status: 'planned',\n detail: `runBizUiAdd(variant=${variant}, ${listing.entries.length} entries)`,\n });\n } catch {\n record({\n name: 'biz-ui-add',\n status: 'planned',\n detail: `runBizUiAdd(variant=${variant})`,\n });\n }\n } else if (aborted) {\n record({\n name: 'biz-ui-add',\n status: 'skip',\n detail: 'aborted: earlier critical step failed',\n });\n } else {\n try {\n const listing = await listBizUiEntries(variant);\n if (listing.entries.length === 0) {\n record({\n name: 'biz-ui-add',\n status: 'skip',\n detail: `no biz-ui entries for variant \"${variant}\"`,\n });\n } else {\n const allIds = listing.entries.map((e) => e.id);\n const result = await runBizUiAdd({\n projectRoot,\n variant,\n ids: allIds,\n overwrite: true,\n });\n record({\n name: 'biz-ui-add',\n status: 'ok',\n detail: `${result.orderedIds.length} entries (${result.written} written, ${result.skipped} skipped)`,\n });\n if (result.npmDependencies) {\n Object.assign(collectedNpmDeps, result.npmDependencies);\n }\n }\n } catch (err) {\n recordFailure('biz-ui-add', err);\n }\n }\n\n // ─── 6.5 meta landing (.teamix-evo/meta/) ────────────────────────────────────\n if (dryRun) {\n record({\n name: 'meta-landing',\n status: 'planned',\n detail: `landUiMeta() + landBizUiMeta(${variant})`,\n });\n } else if (aborted) {\n record({\n name: 'meta-landing',\n status: 'skip',\n detail: 'aborted: earlier critical step failed',\n });\n } else {\n try {\n const uiResult = await landUiMeta(projectRoot);\n const bizResult = await landBizUiMeta(projectRoot, variant);\n record({\n name: 'meta-landing',\n status: 'ok',\n detail: `ui: ${uiResult.metaFilesWritten}/${uiResult.metaFilesTotal}, biz-ui: ${bizResult.metaFilesWritten}/${bizResult.metaFilesTotal}`,\n });\n } catch (err) {\n recordFailure('meta-landing', err);\n }\n }\n\n // ─── 6.75 install ui / biz-ui transitive npm dependencies ───────────────────\n // ui-add / biz-ui-add 复制源码后,需要把它们引用的 npm 依赖(@radix-ui/* / cmdk /\n // recharts 等)写入 package.json 并安装,否则 `npm run dev` 会报模块缺失。\n if (!dryRun && !aborted && Object.keys(collectedNpmDeps).length > 0) {\n try {\n await installProjectDeps({\n projectRoot,\n npmDependencies: collectedNpmDeps,\n skipInstall: options.skipInstall ?? false,\n });\n } catch (err) {\n // Non-critical: 失败不应阻断 lint / gitignore;记录但不计入 critical abort。\n logger.warn(\n `安装 ui/biz-ui 传递依赖失败:${getErrorMessage(\n err,\n )}(可手动运行 \\`npm install\\` 重试)`,\n );\n }\n }\n\n // ─── 7. lint init ──────────────────────────────────────────────────────────────\n if (dryRun) {\n record({ name: 'lint', status: 'planned', detail: 'runLintInit()' });\n } else {\n try {\n const result = await runLintInit({\n projectRoot,\n skipInstall: options.skipInstall ?? false,\n eslintStrategy: 'overwrite',\n stylelintStrategy: 'overwrite',\n eslintExistingPaths: [],\n stylelintExistingPaths: [],\n });\n const detailParts: string[] = [];\n if (result.status === 'installed') {\n detailParts.push(\n `eslint=${result.eslint}, stylelint=${result.stylelint}`,\n );\n if (result.packageJsonPatched) detailParts.push('package.json patched');\n } else {\n detailParts.push(result.status);\n }\n record({\n name: 'lint',\n status: 'ok',\n detail: detailParts.join(' / '),\n changes: deriveLintChanges(result),\n });\n } catch (err) {\n recordFailure('lint', err);\n }\n }\n\n // ─── 8. gitignore ──────────────────────────────────────────────────────────────\n if (dryRun) {\n record({\n name: 'gitignore',\n status: 'planned',\n detail: 'append teamix-evo runtime rules',\n });\n } else {\n try {\n let projectRootExists = true;\n try {\n await fsNode.access(projectRoot);\n } catch {\n projectRootExists = false;\n }\n if (!projectRootExists) {\n record({\n name: 'gitignore',\n status: 'skip',\n detail: 'projectRoot does not exist',\n });\n } else {\n const giPath = path.join(projectRoot, '.gitignore');\n let giContent = '';\n try {\n giContent = await fsNode.readFile(giPath, 'utf-8');\n } catch {\n // .gitignore doesn't exist yet — we'll create it\n }\n if (giContent.includes(GITIGNORE_MARKER_START)) {\n record({\n name: 'gitignore',\n status: 'skip',\n detail: 'teamix-evo markers already present',\n });\n } else {\n const block = [\n '',\n GITIGNORE_MARKER_START,\n ...GITIGNORE_RULES,\n GITIGNORE_MARKER_END,\n '',\n ].join('\\n');\n const separator =\n giContent.length > 0 && !giContent.endsWith('\\n') ? '\\n' : '';\n await fsNode.writeFile(\n giPath,\n giContent + separator + block,\n 'utf-8',\n );\n record({\n name: 'gitignore',\n status: 'ok',\n detail: `${\n GITIGNORE_RULES.filter((r) => r && !r.startsWith('#')).length\n } rules appended`,\n changes: [\n {\n kind: 'modified',\n path: '.gitignore',\n step: 'gitignore',\n detail: 'teamix-evo runtime artifact rules',\n },\n ],\n });\n }\n }\n } catch (err) {\n recordFailure('gitignore', err);\n }\n }\n\n // ─── Result assembly ──────────────────────────────────────────────────────────\n const status: RunProjectInitResult['status'] = dryRun\n ? 'dry-run'\n : steps.some((s) => s.status === 'fail')\n ? 'partial'\n : 'installed';\n\n const out: RunProjectInitResult = { status, steps, changes: allChanges };\n\n if (firstFailure.value) {\n out.resumeHint = {\n failedAt: firstFailure.value.step,\n completed: steps.filter((s) => s.status === 'ok').map((s) => s.name),\n failed: steps.filter((s) => s.status === 'fail').map((s) => s.name),\n error: firstFailure.value.error,\n resumeCommand: 'teamix-evo init',\n };\n }\n\n // Write install summary only when there are failures/skips (debugging aid).\n // All-green init doesn't need a checklist file cluttering .teamix-evo/.\n const hasFailures = steps.some((s) => s.status === 'fail' || s.status === 'skip');\n if (!dryRun && hasFailures) {\n try {\n const checklistContent = renderInitChecklist({ variant, status, steps });\n const checklistPath = path.join(\n projectRoot,\n '.teamix-evo',\n 'init-checklist.md',\n );\n await fsNode.mkdir(path.dirname(checklistPath), { recursive: true });\n await fsNode.writeFile(checklistPath, checklistContent, 'utf-8');\n logger.info(' wrote .teamix-evo/init-checklist.md');\n } catch {\n logger.warn(' failed to write init-checklist.md (non-fatal)');\n }\n }\n\n return out;\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────────────────\n\ntype LintInitResult = Awaited<ReturnType<typeof runLintInit>>;\n\nfunction deriveLintChanges(result: LintInitResult): FileChange[] {\n if (result.status !== 'installed') return [];\n const out: FileChange[] = [];\n if (result.eslint) {\n out.push({\n kind: 'created',\n path: 'eslint.config.js',\n step: 'lint',\n detail: '@teamix-evo/eslint-config',\n });\n }\n if (result.stylelint) {\n out.push({\n kind: 'created',\n path: 'stylelint.config.cjs',\n step: 'lint',\n detail: '@teamix-evo/stylelint-config',\n });\n }\n if (result.packageJsonPatched) {\n out.push({\n kind: 'created',\n path: 'package.json',\n step: 'lint',\n detail: 'scripts.lint / scripts[\"lint:css\"]',\n });\n }\n return out;\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport type {\n VariantManifest,\n Resource,\n InstalledResource,\n} from '@teamix-evo/registry';\nimport { writeFileSafe, ensureDir } from '../utils/fs.js';\nimport { computeHash } from '../utils/hash.js';\nimport { renderTemplate, loadTemplateFile } from '../utils/template.js';\nimport { logger } from '../utils/logger.js';\nimport { resolveSourcePath, walkDir } from '../utils/path.js';\n\nexport interface InstallOptions {\n /** Project root directory */\n projectRoot: string;\n /** The variant manifest */\n manifest: VariantManifest;\n /** Template data for Handlebars rendering */\n data: Record<string, unknown>;\n /** Absolute path to the variant directory (where source files live) */\n variantDir: string;\n /** Absolute path to the package root (for resolving _template/ sources) */\n packageRoot: string;\n}\n\nexport interface InstallResult {\n /** Successfully installed resource records */\n resources: InstalledResource[];\n /** Number of resources installed */\n count: number;\n}\n\n/**\n * Install resources from a variant manifest into the project.\n */\nexport async function installResources(\n options: InstallOptions,\n): Promise<InstallResult> {\n const { projectRoot, manifest, data, variantDir, packageRoot } = options;\n const installedResources: InstalledResource[] = [];\n\n for (const resource of manifest.resources) {\n logger.debug(`Installing resource: ${resource.id} → ${resource.target}`);\n\n if (resource.recursive) {\n const results = await installRecursiveResource(\n resource,\n projectRoot,\n data,\n variantDir,\n packageRoot,\n );\n installedResources.push(...results);\n } else {\n const result = await installSingleResource(\n resource,\n projectRoot,\n data,\n variantDir,\n packageRoot,\n );\n installedResources.push(result);\n }\n }\n\n return {\n resources: installedResources,\n count: installedResources.length,\n };\n}\n\n/**\n * Install a single (non-recursive) resource.\n */\nasync function installSingleResource(\n resource: Resource,\n projectRoot: string,\n data: Record<string, unknown>,\n variantDir: string,\n packageRoot: string,\n): Promise<InstalledResource> {\n const sourcePath = resolveSourcePath(\n resource.source,\n variantDir,\n packageRoot,\n );\n const targetPath = path.join(projectRoot, resource.target);\n\n let content: string;\n if (resource.template) {\n const templateContent = await loadTemplateFile(sourcePath);\n content = renderTemplate(templateContent, data);\n } else {\n content = await fs.readFile(sourcePath, 'utf-8');\n }\n\n await writeFileSafe(targetPath, content);\n const hash = computeHash(content);\n\n logger.debug(` Written: ${resource.target} (${resource.updateStrategy})`);\n\n return {\n id: resource.id,\n target: resource.target,\n hash,\n strategy: resource.updateStrategy,\n };\n}\n\n/**\n * Install a recursive resource (directory).\n */\nasync function installRecursiveResource(\n resource: Resource,\n projectRoot: string,\n data: Record<string, unknown>,\n variantDir: string,\n packageRoot: string,\n): Promise<InstalledResource[]> {\n const sourcePath = resolveSourcePath(\n resource.source,\n variantDir,\n packageRoot,\n );\n const targetDir = path.join(projectRoot, resource.target);\n const results: InstalledResource[] = [];\n\n await ensureDir(targetDir);\n\n const entries = await walkDir(sourcePath);\n for (const entry of entries) {\n const relPath = path.relative(sourcePath, entry);\n let targetFile = path.join(targetDir, relPath);\n\n // Strip .hbs extension from target if template\n if (resource.template && targetFile.endsWith('.hbs')) {\n targetFile = targetFile.slice(0, -4);\n }\n\n let content: string;\n if (resource.template && entry.endsWith('.hbs')) {\n const templateContent = await loadTemplateFile(entry);\n content = renderTemplate(templateContent, data);\n } else {\n content = await fs.readFile(entry, 'utf-8');\n }\n\n await writeFileSafe(targetFile, content);\n const hash = computeHash(content);\n const targetRel = path.relative(projectRoot, targetFile);\n\n results.push({\n id: `${resource.id}:${relPath}`,\n target: targetRel,\n hash,\n strategy: resource.updateStrategy,\n });\n\n logger.debug(` Written: ${targetRel}`);\n }\n\n return results;\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport type { VariantManifest } from '@teamix-evo/registry';\nimport { loadVariantManifest } from '@teamix-evo/registry';\nimport { logger } from '../utils/logger.js';\n\nconst require = createRequire(import.meta.url);\n\n/**\n * Resolve the package root directory for a design package.\n */\nfunction resolvePackageRoot(packageName: string): string {\n const pkgJsonPath = require.resolve(`${packageName}/package.json`);\n return path.dirname(pkgJsonPath);\n}\n\n/**\n * Resolve the directory path for a variant inside a package.\n * MVP: resolves from local node_modules using require.resolve.\n *\n * @param packageName - e.g. \"@teamix-evo/tokens\"\n * @param variant - e.g. \"opentrek\"\n * @returns Absolute path to the variant directory (library/<variant>/)\n */\nexport function resolveVariantPackage(\n packageName: string,\n variant: string,\n): string {\n const pkgRoot = resolvePackageRoot(packageName);\n return path.join(pkgRoot, 'library', variant);\n}\n\n/**\n * Load the variant manifest and _data.json for template rendering.\n *\n * @param packageName - e.g. \"@teamix-evo/tokens\"\n * @param variant - e.g. \"opentrek\"\n * @returns manifest and data for template rendering\n */\nexport async function loadVariantData(\n packageName: string,\n variant: string,\n): Promise<{\n manifest: VariantManifest;\n data: Record<string, unknown>;\n variantDir: string;\n packageRoot: string;\n}> {\n const packageRoot = resolvePackageRoot(packageName);\n const variantDir = path.join(packageRoot, 'library', variant);\n\n logger.debug(`Resolved variant dir: ${variantDir}`);\n logger.debug(`Package root: ${packageRoot}`);\n\n // Load manifest\n const manifest = await loadVariantManifest(variantDir);\n\n // Load _data.json\n let data: Record<string, unknown> = {};\n const dataPath = path.join(variantDir, '_data.json');\n try {\n const raw = await fs.readFile(dataPath, 'utf-8');\n data = JSON.parse(raw) as Record<string, unknown>;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw err;\n }\n logger.debug(`No _data.json found at ${dataPath}, using empty data`);\n }\n\n return { manifest, data, variantDir, packageRoot };\n}\n"],"mappings":"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","names":["path","fs","rel","path","fs","path","fs","require","path","fs","path","os","path","fs","path","fs","createRequire","require","require","stat","rel","DEFAULT_SKILLS_PACKAGE","fs","path","hasManagedRegion","replaceManagedRegion","hasManagedRegion","replaceManagedRegion","DEFAULT_SKILLS_PACKAGE","FLAT_VARIANT","entry","path","fs","createRequire","require","createRequire","resolvePackageRoot","path","fs","DEFAULT_UI_PACKAGE","path","createRequire","loadUiPackageManifest","require","createRequire","resolvePackageRoot","loadUiPackageManifest","mergeResources","path","fs","rel","fs","path","fs","path","IGNORED_TOP_LEVEL","detectProjectState","fs","path","stat","rel","path","fs","createRequire","loadUiPackageManifest","loadVariantUiPackageManifest","require","createRequire","resolvePackageRoot","loadUiPackageManifest","loadVariantUiPackageManifest","fs","path","fs","path","rel","path","path","fs","path","fs","createRequire","require","createRequire","resolvePackageRoot","resolvePackageRoot"]}
|