@3lineas/grooveskills 1.7.1 → 1.7.2
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.
|
@@ -1573,17 +1573,68 @@ async function installSkills(options) {
|
|
|
1573
1573
|
|
|
1574
1574
|
// src/domains/ui/render-onboarding-prompt.ts
|
|
1575
1575
|
import picocolors2 from "picocolors";
|
|
1576
|
+
|
|
1577
|
+
// src/domains/ui/terminal-layout.ts
|
|
1578
|
+
function getTerminalWidth(fallbackWidth = 80) {
|
|
1579
|
+
const terminalColumns = process.stdout.columns;
|
|
1580
|
+
if (typeof terminalColumns === "number" && terminalColumns > 20) {
|
|
1581
|
+
return Math.min(terminalColumns, 100);
|
|
1582
|
+
}
|
|
1583
|
+
return fallbackWidth;
|
|
1584
|
+
}
|
|
1585
|
+
function wrapText(rawText, maxLineWidth = 76) {
|
|
1586
|
+
return rawText.split("\n").map((line) => {
|
|
1587
|
+
if (line.length <= maxLineWidth) {
|
|
1588
|
+
return line;
|
|
1589
|
+
}
|
|
1590
|
+
const words = line.split(" ");
|
|
1591
|
+
const wrappedLines = [];
|
|
1592
|
+
let currentLine = "";
|
|
1593
|
+
for (const word of words) {
|
|
1594
|
+
const potentialLine = currentLine ? `${currentLine} ${word}` : word;
|
|
1595
|
+
if (potentialLine.length <= maxLineWidth) {
|
|
1596
|
+
currentLine = potentialLine;
|
|
1597
|
+
} else {
|
|
1598
|
+
if (currentLine) {
|
|
1599
|
+
wrappedLines.push(currentLine);
|
|
1600
|
+
}
|
|
1601
|
+
currentLine = word;
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
if (currentLine) {
|
|
1605
|
+
wrappedLines.push(currentLine);
|
|
1606
|
+
}
|
|
1607
|
+
return wrappedLines.join("\n");
|
|
1608
|
+
}).join("\n");
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
// src/domains/ui/render-onboarding-prompt.ts
|
|
1576
1612
|
function formatOnboardingPrompt(language = "es") {
|
|
1577
1613
|
const languageConfig = SUPPORTED_LANGUAGES[language] ?? SUPPORTED_LANGUAGES.es;
|
|
1578
1614
|
const title = languageConfig.onboardingPromptTitle;
|
|
1579
1615
|
const prompt = languageConfig.onboardingPrompt;
|
|
1580
|
-
const
|
|
1616
|
+
const boxWidth = Math.max(getTerminalWidth(80) - 4, 50);
|
|
1617
|
+
const contentWidth = boxWidth - 4;
|
|
1618
|
+
const wrappedPromptLines = wrapText(prompt, contentWidth).split("\n");
|
|
1619
|
+
const borderHorizontal = "\u2500".repeat(boxWidth - 2);
|
|
1620
|
+
const badgeText = " COPY & PASTE PROMPT FOR YOUR AI AGENT ";
|
|
1621
|
+
const badgePadded = badgeText.padEnd(contentWidth, " ");
|
|
1622
|
+
const topBorder = picocolors2.cyan(`\u256D${borderHorizontal}\u256E`);
|
|
1623
|
+
const badgeLine = `${picocolors2.cyan("\u2502 ")}${picocolors2.bold(picocolors2.bgCyan(picocolors2.black(badgePadded)))}${picocolors2.cyan(" \u2502")}`;
|
|
1624
|
+
const dividerLine = picocolors2.cyan(`\u251C${borderHorizontal}\u2524`);
|
|
1625
|
+
const promptLines = wrappedPromptLines.map((line) => {
|
|
1626
|
+
const paddedLine = line.padEnd(contentWidth, " ");
|
|
1627
|
+
return `${picocolors2.cyan("\u2502 ")}${picocolors2.bold(picocolors2.white(paddedLine))}${picocolors2.cyan(" \u2502")}`;
|
|
1628
|
+
});
|
|
1629
|
+
const bottomBorder = picocolors2.cyan(`\u2570${borderHorizontal}\u256F`);
|
|
1581
1630
|
const formattedOutput = [
|
|
1582
|
-
separator,
|
|
1583
|
-
picocolors2.bold(picocolors2.yellow(title)),
|
|
1584
1631
|
"",
|
|
1585
|
-
|
|
1586
|
-
|
|
1632
|
+
topBorder,
|
|
1633
|
+
badgeLine,
|
|
1634
|
+
dividerLine,
|
|
1635
|
+
...promptLines,
|
|
1636
|
+
bottomBorder,
|
|
1637
|
+
""
|
|
1587
1638
|
].join("\n");
|
|
1588
1639
|
return {
|
|
1589
1640
|
title,
|
|
@@ -1621,9 +1672,10 @@ function renderInstallFailure(error) {
|
|
|
1621
1672
|
const { stage, causeError, rollbackReport, suggestedFix } = error;
|
|
1622
1673
|
const causeMessage = causeError instanceof Error ? causeError.message : String(causeError);
|
|
1623
1674
|
const nothingTouched = rollbackReport.restoredFiles.length === 0 && rollbackReport.removedFiles.length === 0 && rollbackReport.removedDirs.length === 0 && rollbackReport.failures.length === 0;
|
|
1675
|
+
const safeMaxWidth = Math.max(getTerminalWidth(80) - 10, 50);
|
|
1624
1676
|
const lines = [
|
|
1625
|
-
`${picocolors3.bold("Failed stage:")} ${picocolors3.yellow(stage)}`,
|
|
1626
|
-
`${picocolors3.bold("Cause:")} ${picocolors3.red(causeMessage)}
|
|
1677
|
+
wrapText(`${picocolors3.bold("Failed stage:")} ${picocolors3.yellow(stage)}`, safeMaxWidth),
|
|
1678
|
+
wrapText(`${picocolors3.bold("Cause:")} ${picocolors3.red(causeMessage)}`, safeMaxWidth)
|
|
1627
1679
|
];
|
|
1628
1680
|
if (nothingTouched) {
|
|
1629
1681
|
lines.push(`${picocolors3.bold("Rollback:")} Nothing to roll back, no files were modified.`);
|
|
@@ -1638,12 +1690,12 @@ function renderInstallFailure(error) {
|
|
|
1638
1690
|
if (!rollbackReport.isClean) {
|
|
1639
1691
|
lines.push("", picocolors3.red("Rollback was incomplete. These files may need manual review:"));
|
|
1640
1692
|
for (const failure of rollbackReport.failures) {
|
|
1641
|
-
lines.push(` \u2022 ${failure.path} (${failure.reason})
|
|
1693
|
+
lines.push(wrapText(` \u2022 ${failure.path} (${failure.reason})`, safeMaxWidth));
|
|
1642
1694
|
}
|
|
1643
1695
|
}
|
|
1644
1696
|
}
|
|
1645
1697
|
if (suggestedFix) {
|
|
1646
|
-
lines.push(`${picocolors3.bold("Suggested fix:")} ${picocolors3.green(suggestedFix)}
|
|
1698
|
+
lines.push(wrapText(`${picocolors3.bold("Suggested fix:")} ${picocolors3.green(suggestedFix)}`, safeMaxWidth));
|
|
1647
1699
|
}
|
|
1648
1700
|
prompts5.note(lines.join("\n"), "Installation Aborted");
|
|
1649
1701
|
if (!rollbackReport.isClean) {
|
|
@@ -1695,18 +1747,20 @@ async function runInteractiveUi(context, forceOnboarding = false) {
|
|
|
1695
1747
|
"Welcome to GrooveSkills! Let's tailor your AI agents with clean architectural standards."
|
|
1696
1748
|
)
|
|
1697
1749
|
);
|
|
1750
|
+
const safeMaxWidth = Math.max(getTerminalWidth(80) - 10, 50);
|
|
1698
1751
|
if (context.detectedDependencies.length > 0) {
|
|
1699
1752
|
const harnessInfo = context.harnessExists && !forceOnboarding ? picocolors4.green(
|
|
1700
1753
|
`Active (.grooveskills/memory, lang: ${context.configuredLanguage ?? "es"})`
|
|
1701
1754
|
) : picocolors4.cyan("Will be initialized");
|
|
1702
1755
|
const formattedDependencies = context.detectedDependencies.map((dependencyName) => picocolors4.bold(dependencyName)).join(", ");
|
|
1703
1756
|
const formattedAgents = context.detectedAgents.map((agentName) => picocolors4.green(agentName)).join(", ") || "None (will be created)";
|
|
1704
|
-
|
|
1757
|
+
const environmentNote = wrapText(
|
|
1705
1758
|
`Detected dependencies: ${formattedDependencies}
|
|
1706
1759
|
Active AI folders: ${formattedAgents}
|
|
1707
1760
|
GrooveSkills Harness: ${harnessInfo}`,
|
|
1708
|
-
|
|
1761
|
+
safeMaxWidth
|
|
1709
1762
|
);
|
|
1763
|
+
prompts6.note(environmentNote, "Project Environment");
|
|
1710
1764
|
}
|
|
1711
1765
|
const selectedSkills = await promptSkills(context.suggestedSkillIds);
|
|
1712
1766
|
if (prompts6.isCancel(selectedSkills)) {
|
|
@@ -1748,15 +1802,17 @@ GrooveSkills Harness: ${harnessInfo}`,
|
|
|
1748
1802
|
const formattedInstalledSkills = installResult.installedSkills.map((skillId) => picocolors4.bold(skillId)).join(", ");
|
|
1749
1803
|
const formattedConfiguredAgents = installResult.configuredAgents.map((agentId) => picocolors4.cyan(agentId)).join(", ");
|
|
1750
1804
|
const summaryLines = [
|
|
1751
|
-
`Configured skills: ${formattedInstalledSkills}`,
|
|
1805
|
+
wrapText(`Configured skills: ${formattedInstalledSkills}`, safeMaxWidth),
|
|
1752
1806
|
`Target agents: ${formattedConfiguredAgents}`,
|
|
1753
1807
|
`GrooveSkills Harness: ${harnessStatus}`,
|
|
1754
|
-
...formatReplacedFileNotes(installResult.replacedFiles)
|
|
1808
|
+
...formatReplacedFileNotes(installResult.replacedFiles).map(
|
|
1809
|
+
(note3) => wrapText(note3, safeMaxWidth)
|
|
1810
|
+
)
|
|
1755
1811
|
];
|
|
1756
1812
|
prompts6.note(summaryLines.join("\n"), "Installation Summary");
|
|
1757
1813
|
if (installResult.harnessInitialized) {
|
|
1758
1814
|
const promptRender = formatOnboardingPrompt(selectedLanguage);
|
|
1759
|
-
|
|
1815
|
+
console.log(promptRender.formattedOutput);
|
|
1760
1816
|
}
|
|
1761
1817
|
prompts6.outro(
|
|
1762
1818
|
picocolors4.green(
|
|
@@ -1827,4 +1883,4 @@ export {
|
|
|
1827
1883
|
InstallTransactionError,
|
|
1828
1884
|
runGrooveSkills
|
|
1829
1885
|
};
|
|
1830
|
-
//# sourceMappingURL=chunk-
|
|
1886
|
+
//# sourceMappingURL=chunk-KPDHH2AZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/main.ts","../src/domains/detector/project-detector.ts","../src/domains/detector/detect-agents.ts","../src/domains/detector/detect-dependencies.ts","../src/domains/registry/skill-catalog.ts","../src/domains/ui/ui-orchestrator.ts","../src/domains/ui/banners.ts","../src/domains/ui/prompt-skills.ts","../src/domains/ui/prompt-agents.ts","../src/domains/ui/prompt-language.ts","../src/domains/ui/prompt-confirm-overwrite.ts","../src/domains/installer/verify-skill-exists.ts","../src/domains/installer/install-orchestrator.ts","../src/domains/adapters/skill-reference-builder.ts","../src/domains/project-store/project-paths.ts","../src/domains/fs/safe-file-writer.ts","../src/domains/fs/inspect-file-access.ts","../src/errors/file-permission-error.ts","../src/domains/adapters/antigravity.adapter.ts","../src/domains/adapters/claude.adapter.ts","../src/domains/adapters/cursor.adapter.ts","../src/domains/adapters/gemini.adapter.ts","../src/domains/project-store/sync-project-store.ts","../src/domains/installer/resolve-skills-source.ts","../src/domains/harness/install-harness.ts","../src/domains/harness/harness-languages.ts","../src/domains/harness/harness-templates.ts","../src/domains/harness/scan-project-onboarding.ts","../src/domains/harness/upsert-agent-instructions.ts","../src/domains/harness/write-project-config.ts","../src/domains/fs/install-transaction.ts","../src/domains/fs/preflight-write-check.ts","../src/errors/install-transaction-error.ts","../src/domains/ui/render-onboarding-prompt.ts","../src/domains/ui/terminal-layout.ts","../src/domains/ui/render-install-report.ts"],"sourcesContent":["import { basename } from \"node:path\";\nimport { userInfo } from \"node:os\";\nimport picocolors from \"picocolors\";\nimport { detectProjectContext } from \"@/domains/detector/project-detector\";\nimport { runInteractiveUi } from \"@/domains/ui/ui-orchestrator\";\nimport { installSkills } from \"@/domains/installer/install-orchestrator\";\nimport { formatOnboardingPrompt } from \"@/domains/ui/render-onboarding-prompt\";\nimport { formatOwnerName } from \"@/domains/fs/inspect-file-access\";\nimport type { AgentId } from \"@/types/agent.types\";\nimport type { ProjectLanguage } from \"@/types/harness.types\";\n\nexport interface CliOptions {\n skills?: string[];\n agents?: AgentId[];\n yes?: boolean;\n harness?: boolean;\n language?: ProjectLanguage;\n forceOnboarding?: boolean;\n}\n\nfunction resolveUsername(): string {\n try {\n return userInfo().username;\n } catch {\n return process.env.USER || process.env.LOGNAME || \"current user\";\n }\n}\n\nexport async function runGrooveSkills(options: CliOptions = {}): Promise<void> {\n const targetPath = process.cwd();\n const context = detectProjectContext(targetPath);\n\n const hasSkills = options.skills && options.skills.length > 0;\n const hasAgents = options.agents && options.agents.length > 0;\n const isDirectHarness = Boolean(options.harness) && hasAgents;\n const isDirectInit = Boolean(options.forceOnboarding) && hasAgents;\n\n if ((hasSkills && hasAgents) || isDirectHarness || isDirectInit) {\n const language = options.language ?? context.configuredLanguage ?? \"es\";\n const result = await installSkills({\n targetPath,\n selectedSkillIds: options.skills || [],\n selectedAgents: options.agents || [],\n forceOverwrite: Boolean(options.yes),\n enableHarness: true,\n detectedDependencies: context.detectedDependencies,\n language,\n forceOnboarding: options.forceOnboarding,\n });\n\n if (result.replacedFiles && result.replacedFiles.length > 0) {\n const currentUser = resolveUsername();\n for (const replacedItem of result.replacedFiles) {\n const fileName = basename(replacedItem.filePath);\n const previousOwner = formatOwnerName(replacedItem.previousOwnerUid);\n console.log(\n picocolors.yellow(\n `Note: ${fileName} was owned by ${previousOwner}. It was replaced atomically and is now owned by ${currentUser}.`\n )\n );\n }\n }\n\n if (result.harnessInitialized) {\n const promptRender = formatOnboardingPrompt(language);\n console.log(`\\n${promptRender.formattedOutput}\\n`);\n }\n\n return;\n }\n\n await runInteractiveUi(context, Boolean(options.forceOnboarding));\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { detectAgents } from \"@/domains/detector/detect-agents\";\nimport { detectDependencies } from \"@/domains/detector/detect-dependencies\";\nimport { SKILL_CATALOG } from \"@/domains/registry/skill-catalog\";\nimport type { ProjectContext } from \"@/types/context.types\";\nimport type { GrooveSkillsConfig, ProjectLanguage } from \"@/types/harness.types\";\n\nfunction readConfiguredLanguage(targetPath: string): ProjectLanguage | undefined {\n const configPath = join(targetPath, \".grooveskills\", \"config.json\");\n if (!existsSync(configPath)) {\n return undefined;\n }\n\n try {\n const raw = readFileSync(configPath, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<GrooveSkillsConfig>;\n return typeof parsed.language === \"string\" ? (parsed.language as ProjectLanguage) : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function detectProjectContext(targetPath: string): ProjectContext {\n const detectedAgents = detectAgents(targetPath);\n const { dependencies, exists } = detectDependencies(targetPath);\n\n const suggestedSkillIds: string[] = [\n \"odd-ai\",\n \"best-practices\",\n \"ux-writing\",\n \"docs-standards\",\n \"error-handling-logging\",\n \"clean-architecture-ddd\",\n \"external-service-adapters\",\n \"storage-file-adapters\",\n \"auth-rbac-policies\",\n \"controller-orchestration-queues\",\n \"webhook-idempotency\",\n \"caching-rate-limiting\",\n \"env-feature-flags\",\n ];\n\n for (const skill of SKILL_CATALOG) {\n if (skill.dependencies.length === 0) {\n continue;\n }\n const hasMatch = skill.dependencies.some((dependencyName) =>\n dependencies.includes(dependencyName)\n );\n if (hasMatch && !suggestedSkillIds.includes(skill.id)) {\n suggestedSkillIds.push(skill.id);\n }\n }\n\n const harnessExists = existsSync(join(targetPath, \".grooveskills\", \"memory\", \"context.md\"));\n const configuredLanguage = readConfiguredLanguage(targetPath);\n\n return {\n targetPath,\n detectedDependencies: dependencies,\n suggestedSkillIds,\n detectedAgents,\n packageJsonExists: exists,\n harnessExists,\n configuredLanguage,\n };\n}\n","import { readdirSync } from \"node:fs\";\nimport type { AgentId } from \"@/types/agent.types\";\n\nexport function detectAgents(targetPath: string): AgentId[] {\n const detected: AgentId[] = [];\n\n try {\n const entries = new Set(readdirSync(targetPath));\n\n if (entries.has(\".agents\")) {\n detected.push(\"antigravity\");\n }\n if (entries.has(\".claude\")) {\n detected.push(\"claude\");\n }\n if (entries.has(\".cursor\")) {\n detected.push(\"cursor\");\n }\n if (entries.has(\".gemini\")) {\n detected.push(\"gemini\");\n }\n } catch {\n // If directory cannot be read, return empty list gracefully\n }\n\n return detected;\n}\n","import { readFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport interface PackageJsonDetection {\n dependencies: string[];\n exists: boolean;\n}\n\nexport function detectDependencies(targetPath: string): PackageJsonDetection {\n const detected = new Set<string>();\n let hasManifest = false;\n\n const packageJsonPath = join(targetPath, \"package.json\");\n if (existsSync(packageJsonPath)) {\n hasManifest = true;\n try {\n const raw = readFileSync(packageJsonPath, \"utf-8\");\n const parsed = JSON.parse(raw) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n\n for (const dependencyName of Object.keys(parsed.dependencies ?? {})) {\n detected.add(dependencyName);\n }\n for (const dependencyName of Object.keys(parsed.devDependencies ?? {})) {\n detected.add(dependencyName);\n }\n } catch {\n // Ignore JSON parse errors gracefully\n }\n }\n\n const cargoPath = join(targetPath, \"Cargo.toml\");\n if (existsSync(cargoPath)) {\n hasManifest = true;\n detected.add(\"rust\");\n }\n\n const pyprojectPath = join(targetPath, \"pyproject.toml\");\n const requirementsPath = join(targetPath, \"requirements.txt\");\n if (existsSync(pyprojectPath) || existsSync(requirementsPath)) {\n hasManifest = true;\n detected.add(\"python\");\n }\n\n return {\n dependencies: Array.from(detected),\n exists: hasManifest,\n };\n}\n","import type { SkillMetadata } from \"@/types/skill.types\";\n\nexport const SKILL_CATALOG: SkillMetadata[] = [\n {\n id: \"groove-harness\",\n name: \"GrooveSkills Harness\",\n description: \"Lightweight project harness, context memory, and ODD 3-lane task execution (Answer, Task, Spec) for AI coding agents\",\n dependencies: [],\n directoryName: \"groove-harness\",\n isCoreHarness: true,\n },\n {\n id: \"odd-ai\",\n name: \"Organic & Outcome-Driven Development (ODD)\",\n description: \"7-step ODD protocol for AI agents: authorize, explore, classify, outcome hypotheses, and verifiable evidence receipts\",\n dependencies: [],\n directoryName: \"odd-ai\",\n },\n {\n id: \"best-practices\",\n name: \"Universal Best Practices\",\n description: \"Multi-language clean code standards, early returns, no barrel files, strict typing, <200 lines\",\n dependencies: [],\n directoryName: \"best-practices\",\n },\n {\n id: \"ux-writing\",\n name: \"UX Writing & Microcopy Standards\",\n description: \"Persuasive, empathetic, professional bilingual microcopy (ES/EN) for error messages, forms, CTAs, toasts, and empty states\",\n dependencies: [],\n directoryName: \"ux-writing\",\n },\n {\n id: \"docs-standards\",\n name: \"Documentation & ADR Standards\",\n description: \"English documentation standard, relative POSIX links, resilient Mermaid diagrams, ADR lifecycle, and intent-focused docstrings\",\n dependencies: [],\n directoryName: \"docs-standards\",\n },\n {\n id: \"typescript-clean\",\n name: \"TypeScript Clean Code (TS 5.5+)\",\n description: \"Advanced strict TypeScript, discriminated unions, satisfies, const generics, unknown over any, and zero unsafe casts\",\n dependencies: [\"typescript\"],\n directoryName: \"typescript-clean\",\n },\n {\n id: \"rust-clean\",\n name: \"Rust Clean Code (Rust 2024)\",\n description: \"Idiomatic Rust clean code: let-else guard clauses, no unwrap in production, thiserror typed errors, Newtypes, zero barrel files, <200 lines\",\n dependencies: [\"rust\"],\n directoryName: \"rust-clean\",\n },\n {\n id: \"python-clean\",\n name: \"Python Clean Code (Python 3.12+)\",\n description: \"Modern Python standards: guard clauses (no nested ifs), strict typing (zero Any), uv, Ruff, Pyright, Pydantic v2 boundaries, <200 lines\",\n dependencies: [\"python\"],\n directoryName: \"python-clean\",\n },\n {\n id: \"error-handling-logging\",\n name: \"Error Handling & Structured Logging\",\n description: \"Deterministic error management with AppError, Result/ActionResponse contracts, and structured context logging\",\n dependencies: [],\n directoryName: \"error-handling-logging\",\n },\n {\n id: \"valibot-validation\",\n name: \"Valibot Schema Validation\",\n description: \"Boundary schema validation with Valibot (* as v from 'valibot'), strict type inference, and friendly error messages\",\n dependencies: [\"valibot\"],\n directoryName: \"valibot-validation\",\n },\n {\n id: \"clean-architecture-ddd\",\n name: \"Clean Architecture & DDD\",\n description: \"Domain-driven design, isolated single-purpose Actions, pure functions, immutability, zero barrel files, <200 lines per file\",\n dependencies: [],\n directoryName: \"clean-architecture-ddd\",\n },\n {\n id: \"external-service-adapters\",\n name: \"External Service Adapters & Wrappers\",\n description: \"Standardized adapter and wrapper architecture for external services (payment gateways, emails, SMS, cloud storage)\",\n dependencies: [],\n directoryName: \"external-service-adapters\",\n },\n {\n id: \"storage-file-adapters\",\n name: \"Storage & File Adapters (S3, R2, Supabase)\",\n description: \"Standardized wrapper & adapter architecture for object storage, uploads, presigned URLs, and streaming without repositories\",\n dependencies: [],\n directoryName: \"storage-file-adapters\",\n },\n {\n id: \"auth-rbac-policies\",\n name: \"Auth Adapters & RBAC/ABAC Policies\",\n description: \"Authentication adapter architecture and pure domain authorization policies (RBAC/ABAC) with AuthenticatedActor contract\",\n dependencies: [],\n directoryName: \"auth-rbac-policies\",\n },\n {\n id: \"controller-orchestration-queues\",\n name: \"Controller Orchestration & Queue Adapters\",\n description: \"Strict orchestration rules for Controllers, atomic Actions, DB Transactions, and background Queue Adapters (Cloudflare, BullMQ, SQS)\",\n dependencies: [],\n directoryName: \"controller-orchestration-queues\",\n },\n {\n id: \"webhook-idempotency\",\n name: \"Webhook Verifiers & Idempotency Guards\",\n description: \"Incoming webhook HMAC verification adapters and atomic idempotency guards guaranteeing at-most-once processing\",\n dependencies: [],\n directoryName: \"webhook-idempotency\",\n },\n {\n id: \"caching-rate-limiting\",\n name: \"Cache-Aside & Rate Limiting Adapters\",\n description: \"Cache-aside remember wrapper and interchangeable sliding-window rate limiter adapters (Redis, Cloudflare KV, In-Memory)\",\n dependencies: [],\n directoryName: \"caching-rate-limiting\",\n },\n {\n id: \"env-feature-flags\",\n name: \"Fail-Fast Env & Feature Flags Adapters\",\n description: \"Fail-fast environment schema validation with Valibot and decoupled feature flags adapters (PostHog, LaunchDarkly, Unleash)\",\n dependencies: [],\n directoryName: \"env-feature-flags\",\n },\n {\n id: \"testing-vitest\",\n name: \"Vitest Testing Standards\",\n description: \"Clean unit and integration testing with Vitest: AAA pattern, behavioral testing over mocks, and boundary edge cases\",\n dependencies: [\"vitest\"],\n directoryName: \"testing-vitest\",\n },\n {\n id: \"hono\",\n name: \"Hono Architecture (Valibot)\",\n description: \"Enterprise Hono API standard with Valibot validation, isolated Actions layer, and RPC bindings\",\n dependencies: [\"hono\", \"@hono/valibot-validator\", \"@hono/standard-validator\"],\n directoryName: \"hono\",\n },\n {\n id: \"react-core\",\n name: \"React Core Fundamentals\",\n description: \"Opinionated React fundamentals: function components, JSX, immutable state, core hooks, lists, and controlled inputs\",\n dependencies: [\"react\", \"react-dom\"],\n directoryName: \"react-core\",\n },\n {\n id: \"react-advanced\",\n name: \"React 19 Advanced & Compiler Architecture\",\n description: \"Modern React 19 platform features: React Compiler auto-memoization, concurrent rendering, use(), Actions, virtualization, and RSC boundaries\",\n dependencies: [\"react\", \"react-dom\"],\n directoryName: \"react-advanced\",\n },\n {\n id: \"react-create-page\",\n name: \"React Page & View Architecture\",\n description: \"Clean architecture for React pages: declarative page coordinators, domain hooks, isolated API actions, Valibot + Formisch forms, and atomic co-location\",\n dependencies: [\"react\", \"react-dom\"],\n directoryName: \"react-create-page\",\n },\n];\n","import * as prompts from \"@clack/prompts\";\nimport picocolors from \"picocolors\";\nimport { renderBanner } from \"@/domains/ui/banners\";\nimport { promptSkills } from \"@/domains/ui/prompt-skills\";\nimport { promptAgents } from \"@/domains/ui/prompt-agents\";\nimport { promptLanguage } from \"@/domains/ui/prompt-language\";\nimport { promptConfirmOverwrite } from \"@/domains/ui/prompt-confirm-overwrite\";\nimport { verifySkillExists } from \"@/domains/installer/verify-skill-exists\";\nimport { installSkills } from \"@/domains/installer/install-orchestrator\";\nimport { SKILL_CATALOG } from \"@/domains/registry/skill-catalog\";\nimport { formatOnboardingPrompt } from \"@/domains/ui/render-onboarding-prompt\";\nimport { formatReplacedFileNotes, renderInstallFailure } from \"@/domains/ui/render-install-report\";\nimport { getTerminalWidth, wrapText } from \"@/domains/ui/terminal-layout\";\nimport { InstallTransactionError } from \"@/errors/install-transaction-error\";\nimport type { ProjectContext } from \"@/types/context.types\";\nimport type { AgentId } from \"@/types/agent.types\";\nimport type { ProjectLanguage } from \"@/types/harness.types\";\n\nasync function resolveLanguageSelection(\n harnessExists: boolean,\n configuredLanguage?: ProjectLanguage,\n forceOnboarding?: boolean\n): Promise<ProjectLanguage> {\n if (harnessExists && !forceOnboarding) {\n return configuredLanguage ?? \"es\";\n }\n\n const languageSelection = await promptLanguage(configuredLanguage ?? \"es\");\n if (prompts.isCancel(languageSelection)) {\n prompts.cancel(\"Installation cancelled. Have a wonderful day!\");\n process.exit(0);\n }\n\n return languageSelection as ProjectLanguage;\n}\n\nasync function resolveOverwriteConfirmation(\n targetPath: string,\n selectedSkills: string[],\n selectedAgents: AgentId[]\n): Promise<boolean> {\n const anyExists = selectedSkills.some((skillId) => {\n const skillMetadata = SKILL_CATALOG.find((skill) => skill.id === skillId);\n return skillMetadata\n ? verifySkillExists(targetPath, skillMetadata.directoryName, selectedAgents)\n : false;\n });\n\n if (!anyExists) {\n return true;\n }\n\n const overwriteConfirmed = await promptConfirmOverwrite();\n if (prompts.isCancel(overwriteConfirmed) || !overwriteConfirmed) {\n prompts.cancel(\"Installation stopped to protect existing skills.\");\n process.exit(0);\n }\n\n return Boolean(overwriteConfirmed);\n}\n\nexport async function runInteractiveUi(\n context: ProjectContext,\n forceOnboarding: boolean = false\n): Promise<void> {\n console.log(renderBanner());\n prompts.intro(\n picocolors.magenta(\n \"Welcome to GrooveSkills! Let's tailor your AI agents with clean architectural standards.\"\n )\n );\n\n const safeMaxWidth = Math.max(getTerminalWidth(80) - 10, 50);\n\n if (context.detectedDependencies.length > 0) {\n const harnessInfo =\n context.harnessExists && !forceOnboarding\n ? picocolors.green(\n `Active (.grooveskills/memory, lang: ${context.configuredLanguage ?? \"es\"})`\n )\n : picocolors.cyan(\"Will be initialized\");\n\n const formattedDependencies = context.detectedDependencies\n .map((dependencyName) => picocolors.bold(dependencyName))\n .join(\", \");\n const formattedAgents =\n context.detectedAgents.map((agentName) => picocolors.green(agentName)).join(\", \") ||\n \"None (will be created)\";\n\n const environmentNote = wrapText(\n `Detected dependencies: ${formattedDependencies}\\n` +\n `Active AI folders: ${formattedAgents}\\n` +\n `GrooveSkills Harness: ${harnessInfo}`,\n safeMaxWidth\n );\n\n prompts.note(environmentNote, \"Project Environment\");\n }\n\n const selectedSkills = await promptSkills(context.suggestedSkillIds);\n if (prompts.isCancel(selectedSkills)) {\n prompts.cancel(\"Installation cancelled. Have a wonderful day!\");\n process.exit(0);\n }\n\n const selectedAgents = await promptAgents(context.detectedAgents);\n if (prompts.isCancel(selectedAgents)) {\n prompts.cancel(\"Installation cancelled. Have a wonderful day!\");\n process.exit(0);\n }\n\n const selectedLanguage = await resolveLanguageSelection(\n context.harnessExists,\n context.configuredLanguage,\n forceOnboarding\n );\n\n const forceOverwrite = await resolveOverwriteConfirmation(\n context.targetPath,\n selectedSkills as string[],\n selectedAgents as AgentId[]\n );\n\n const installSpinner = prompts.spinner();\n installSpinner.start(\"Installing and adapting skills across your configured AI agents...\");\n\n try {\n const installResult = await installSkills({\n targetPath: context.targetPath,\n selectedSkillIds: selectedSkills as string[],\n selectedAgents: selectedAgents as AgentId[],\n forceOverwrite,\n enableHarness: true,\n detectedDependencies: context.detectedDependencies,\n language: selectedLanguage,\n forceOnboarding,\n });\n\n installSpinner.stop(\n picocolors.green(\"All skills and harness have been successfully configured!\")\n );\n\n const harnessStatus = installResult.harnessInitialized\n ? picocolors.green(`Initialized in .grooveskills/ (Language: ${selectedLanguage})`)\n : picocolors.cyan(`Preserved in .grooveskills/ (Language: ${selectedLanguage})`);\n\n const formattedInstalledSkills = installResult.installedSkills\n .map((skillId) => picocolors.bold(skillId))\n .join(\", \");\n const formattedConfiguredAgents = installResult.configuredAgents\n .map((agentId) => picocolors.cyan(agentId))\n .join(\", \");\n\n const summaryLines = [\n wrapText(`Configured skills: ${formattedInstalledSkills}`, safeMaxWidth),\n `Target agents: ${formattedConfiguredAgents}`,\n `GrooveSkills Harness: ${harnessStatus}`,\n ...formatReplacedFileNotes(installResult.replacedFiles).map((note) =>\n wrapText(note, safeMaxWidth)\n ),\n ];\n\n prompts.note(summaryLines.join(\"\\n\"), \"Installation Summary\");\n\n if (installResult.harnessInitialized) {\n const promptRender = formatOnboardingPrompt(selectedLanguage);\n console.log(promptRender.formattedOutput);\n }\n\n prompts.outro(\n picocolors.green(\n \"Your AI programming pair is now empowered with your team's architectural habits! 🚀\"\n )\n );\n } catch (error) {\n installSpinner.stop(picocolors.yellow(\"Installation could not be completed.\"));\n\n if (error instanceof InstallTransactionError) {\n renderInstallFailure(error);\n return;\n }\n\n throw error;\n }\n}\n","import picocolors from \"picocolors\";\n\nexport function renderBanner(): string {\n const title = picocolors.bold(picocolors.white(\" GROOVE SKILLS \"));\n const badge = picocolors.bgMagenta(picocolors.black(title));\n const subtitle = picocolors.dim(\"Multi-Agent AI Skills & Architectural Standards\");\n\n return `${badge} ${subtitle}\\n`;\n}\n","import * as prompts from \"@clack/prompts\";\nimport { SKILL_CATALOG } from \"@/domains/registry/skill-catalog\";\n\nexport async function promptSkills(suggestedSkillIds: string[]): Promise<string[] | symbol> {\n const selectableSkills = SKILL_CATALOG.filter((skill) => !skill.isCoreHarness);\n const options = selectableSkills.map((skill) => {\n const isSuggested = suggestedSkillIds.includes(skill.id);\n return {\n value: skill.id,\n label: skill.name,\n hint: isSuggested ? \"Suggested based on your project stack\" : skill.description,\n };\n });\n\n const selected = await prompts.multiselect({\n message: \"Which skills would you like to install in this project?\",\n options,\n initialValues: suggestedSkillIds,\n required: true,\n });\n\n return selected;\n}\n","import * as prompts from \"@clack/prompts\";\nimport type { AgentId } from \"@/types/agent.types\";\n\nexport async function promptAgents(detectedAgents: AgentId[]): Promise<AgentId[] | symbol> {\n const options: Array<{ value: AgentId; label: string; hint: string }> = [\n { value: \"antigravity\", label: \"Antigravity\", hint: \".agents/skills (Google Agentic IDE)\" },\n { value: \"claude\", label: \"Claude Code\", hint: \".claude/skills (Anthropic Claude Code)\" },\n { value: \"cursor\", label: \"Cursor\", hint: \".cursor/rules/*.mdc (Cursor IDE Rules)\" },\n { value: \"gemini\", label: \"Gemini Code Assist\", hint: \".gemini/skills (Google Gemini)\" },\n ];\n\n const initialValues: AgentId[] = detectedAgents.length > 0 ? detectedAgents : [\"antigravity\"];\n\n const selected = await prompts.multiselect({\n message: \"Which AI agents should be configured?\",\n options,\n initialValues,\n required: true,\n });\n\n return selected as AgentId[] | symbol;\n}\n","import * as prompts from \"@clack/prompts\";\nimport type { ProjectLanguage } from \"@/types/harness.types\";\n\nexport async function promptLanguage(\n defaultLanguage: ProjectLanguage = \"es\"\n): Promise<ProjectLanguage | symbol> {\n const options = [\n { value: \"es\", label: \"Español (Spanish)\", hint: \"Recommended for Spanish-speaking projects\" },\n { value: \"en\", label: \"English\", hint: \"Standard international English\" },\n { value: \"pt\", label: \"Português (Portuguese)\", hint: \"Portuguese for Brazil and Portugal\" },\n { value: \"it\", label: \"Italiano (Italian)\", hint: \"Italian language communication\" },\n { value: \"fr\", label: \"Français (French)\", hint: \"French language communication\" },\n ];\n\n const selected = await prompts.select({\n message: \"Which language should AI agents use for user-facing copy and communication?\",\n options,\n initialValue: defaultLanguage,\n });\n\n return selected as ProjectLanguage | symbol;\n}\n","import * as prompts from \"@clack/prompts\";\n\nexport async function promptConfirmOverwrite(): Promise<boolean | symbol> {\n return await prompts.confirm({\n message:\n \"Some skills already exist in this project. Would you like to overwrite them with the latest version?\",\n initialValue: true,\n });\n}\n","import { lstatSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { AgentId } from \"@/types/agent.types\";\n\nconst AGENT_DESTINATION_MAP: Record<AgentId, (directoryName: string) => string> = {\n antigravity: (directoryName) => join(\".agents\", \"skills\", directoryName),\n claude: (directoryName) => join(\".claude\", \"skills\", directoryName),\n cursor: (directoryName) => join(\".cursor\", \"rules\", `${directoryName}.mdc`),\n gemini: (directoryName) => join(\".gemini\", \"skills\", directoryName),\n};\n\nexport function verifySkillExists(\n targetPath: string,\n skillDirectoryName: string,\n agents: AgentId[]\n): boolean {\n for (const agent of agents) {\n const relativePathResolver = AGENT_DESTINATION_MAP[agent];\n const destination = join(targetPath, relativePathResolver(skillDirectoryName));\n\n try {\n lstatSync(destination);\n return true;\n } catch {\n // Path does not exist\n }\n }\n\n return false;\n}\n","import { join } from \"node:path\";\nimport { AntigravityAdapter } from \"@/domains/adapters/antigravity.adapter\";\nimport { ClaudeAdapter } from \"@/domains/adapters/claude.adapter\";\nimport { CursorAdapter } from \"@/domains/adapters/cursor.adapter\";\nimport { GeminiAdapter } from \"@/domains/adapters/gemini.adapter\";\nimport { syncProjectStore } from \"@/domains/project-store/sync-project-store\";\nimport { getProjectSkillsDir } from \"@/domains/project-store/project-paths\";\nimport { installHarness } from \"@/domains/harness/install-harness\";\nimport { writeProjectConfig } from \"@/domains/harness/write-project-config\";\nimport { SKILL_CATALOG } from \"@/domains/registry/skill-catalog\";\nimport { InstallTransaction } from \"@/domains/fs/install-transaction\";\nimport { runPreflightWriteCheck } from \"@/domains/fs/preflight-write-check\";\nimport { InstallTransactionError } from \"@/errors/install-transaction-error\";\nimport { FilePermissionError } from \"@/errors/file-permission-error\";\nimport type { AgentAdapter } from \"@/domains/adapters/adapter.interface\";\nimport type { InstallOptions, InstallResult } from \"@/types/installer.types\";\nimport type { AgentId } from \"@/types/agent.types\";\n\nconst ADAPTER_REGISTRY: Record<AgentId, AgentAdapter> = {\n antigravity: new AntigravityAdapter(),\n claude: new ClaudeAdapter(),\n cursor: new CursorAdapter(),\n gemini: new GeminiAdapter(),\n};\n\nfunction formatSuggestedFix(cause: unknown): string | undefined {\n if (cause instanceof FilePermissionError) {\n return cause.suggestedFixCommand;\n }\n const nodeError = cause as NodeJS.ErrnoException;\n if (nodeError?.code === \"EACCES\" || nodeError?.code === \"EPERM\") {\n if (nodeError.path) {\n return `chmod u+w \"${nodeError.path}\"`;\n }\n }\n return undefined;\n}\n\nexport async function installSkills(options: InstallOptions): Promise<InstallResult> {\n const transaction = new InstallTransaction();\n const skillsToInstall = [...options.selectedSkillIds];\n\n if (!skillsToInstall.includes(\"groove-harness\")) {\n skillsToInstall.push(\"groove-harness\");\n }\n\n if (!skillsToInstall.includes(\"odd-ai\")) {\n skillsToInstall.push(\"odd-ai\");\n }\n\n let currentStage = \"Preflight check\";\n try {\n runPreflightWriteCheck({\n targetPath: options.targetPath,\n selectedAgents: options.selectedAgents,\n });\n\n currentStage = \"Syncing skills store (.grooveskills/skills)\";\n syncProjectStore(options.targetPath, skillsToInstall, options.selectedAgents, transaction);\n\n const projectSkillsDir = getProjectSkillsDir(options.targetPath);\n const createdFiles: string[] = [];\n\n currentStage = \"Configuring agent references (.agents, .claude, etc.)\";\n for (const skillId of skillsToInstall) {\n const skill = SKILL_CATALOG.find((catalogItem) => catalogItem.id === skillId);\n if (!skill) {\n continue;\n }\n\n const skillSourceDir = join(projectSkillsDir, skill.directoryName);\n\n for (const agentId of options.selectedAgents) {\n const adapter = ADAPTER_REGISTRY[agentId];\n if (!adapter) {\n continue;\n }\n\n const files = await adapter.installSkill(\n options.targetPath,\n skill,\n skillSourceDir,\n transaction\n );\n createdFiles.push(...files);\n }\n }\n\n currentStage = \"Installing Groove Harness (context, decisions, tasks, and instructions)\";\n const harnessResult = installHarness({\n targetPath: options.targetPath,\n selectedAgents: options.selectedAgents,\n selectedSkillIds: skillsToInstall,\n detectedDependencies: options.detectedDependencies || [],\n language: options.language,\n forceOnboarding: options.forceOnboarding,\n transaction,\n });\n createdFiles.push(...harnessResult.createdFiles);\n\n currentStage = \"Persisting project configuration (.grooveskills/config.json)\";\n const configPath = writeProjectConfig(\n options.targetPath,\n skillsToInstall,\n options.selectedAgents,\n true,\n options.language,\n transaction\n );\n createdFiles.push(configPath);\n\n return {\n installedSkills: skillsToInstall,\n configuredAgents: options.selectedAgents,\n createdFiles,\n harnessInitialized: harnessResult.onboardingInitialized,\n language: options.language,\n replacedFiles: transaction.getReplacedFiles(),\n };\n } catch (cause) {\n const rollbackReport = transaction.rollback();\n const suggestedFix = formatSuggestedFix(cause);\n throw new InstallTransactionError({\n stage: currentStage,\n cause,\n rollbackReport,\n suggestedFix,\n });\n }\n}\n","import { existsSync, lstatSync, mkdirSync, readFileSync, rmSync, unlinkSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getProjectSkillsDir } from \"@/domains/project-store/project-paths\";\nimport { safeWriteFileSync } from \"@/domains/fs/safe-file-writer\";\nimport type { InstallTransaction } from \"@/domains/fs/install-transaction\";\nimport type { SkillMetadata } from \"@/types/skill.types\";\n\nfunction removeExistingPathSafely(path: string): void {\n const fileExists = existsSync(path);\n\n if (!fileExists) {\n try {\n const lstat = lstatSync(path);\n if (lstat.isSymbolicLink()) {\n unlinkSync(path);\n }\n } catch {\n // Ignored if file really does not exist\n }\n return;\n }\n\n try {\n const lstat = lstatSync(path);\n if (lstat.isSymbolicLink()) {\n unlinkSync(path);\n return;\n }\n\n if (lstat.isDirectory()) {\n rmSync(path, { recursive: true, force: true });\n return;\n }\n\n unlinkSync(path);\n } catch {\n // Graceful fallback\n }\n}\n\nfunction extractSkillDescription(canonicalSkillMdPath: string, fallback: string): string {\n if (!existsSync(canonicalSkillMdPath)) {\n return fallback;\n }\n\n try {\n const content = readFileSync(canonicalSkillMdPath, \"utf-8\");\n const match = content.match(/^description:\\s*(.+)$/m);\n const hasMatchedDesc = Boolean(match && match[1]);\n if (hasMatchedDesc && match?.[1]) {\n return match[1].trim();\n }\n } catch {\n // Use fallback on error\n }\n\n return fallback;\n}\n\nexport function writeAgentSkillReference(\n targetPath: string,\n agentRelativeSkillsDir: string,\n skill: SkillMetadata,\n transaction?: InstallTransaction\n): string {\n const agentSkillFolder = join(targetPath, agentRelativeSkillsDir, skill.directoryName);\n const targetFile = join(agentSkillFolder, \"SKILL.md\");\n if (transaction) {\n transaction.recordCreatedDir(join(targetPath, agentRelativeSkillsDir));\n transaction.recordCreatedDir(agentSkillFolder);\n transaction.recordBeforeWrite(targetFile);\n }\n\n removeExistingPathSafely(agentSkillFolder);\n\n mkdirSync(agentSkillFolder, { recursive: true });\n\n const canonicalSkillMd = join(getProjectSkillsDir(targetPath), skill.directoryName, \"SKILL.md\");\n const description = extractSkillDescription(canonicalSkillMd, skill.description);\n\n const referenceContent = `---\nname: ${skill.id}\ndescription: ${description}\n---\n\n# ${skill.name} — Skill Reference\n\nCanonical skill specification stored in \\`.grooveskills/\\`.\n\n- **Specification**: [\\`.grooveskills/skills/${skill.directoryName}/SKILL.md\\`](../../../.grooveskills/skills/${skill.directoryName}/SKILL.md)\n- **References & Templates**: \\`.grooveskills/skills/${skill.directoryName}/\\`\n\n> **Instruction**: Read \\`.grooveskills/skills/${skill.directoryName}/SKILL.md\\` before executing tasks matching this skill.\n`;\n\n safeWriteFileSync(targetFile, referenceContent);\n\n return targetFile;\n}\n\nexport function writeCursorRuleReference(\n targetPath: string,\n cursorRelativeRulesDir: string,\n skill: SkillMetadata,\n transaction?: InstallTransaction\n): string {\n const rulesDir = join(targetPath, cursorRelativeRulesDir);\n const targetFile = join(rulesDir, `${skill.id}.mdc`);\n if (transaction) {\n transaction.recordCreatedDir(rulesDir);\n transaction.recordBeforeWrite(targetFile);\n }\n if (!existsSync(rulesDir)) {\n mkdirSync(rulesDir, { recursive: true });\n }\n\n removeExistingPathSafely(targetFile);\n\n const canonicalSkillMd = join(getProjectSkillsDir(targetPath), skill.directoryName, \"SKILL.md\");\n const description = extractSkillDescription(canonicalSkillMd, skill.description);\n\n const referenceContent = `---\ndescription: ${description}\nglobs: [\"**/*\"]\nalwaysApply: false\n---\n\n# ${skill.name} — Rule Reference\n\nCanonical rule specification stored in \\`.grooveskills/\\`.\n\n- **Specification**: \\`.grooveskills/skills/${skill.directoryName}/SKILL.md\\`\n- **References & Templates**: \\`.grooveskills/skills/${skill.directoryName}/\\`\n\n> **Instruction**: Read \\`.grooveskills/skills/${skill.directoryName}/SKILL.md\\` before executing tasks matching this rule.\n`;\n\n safeWriteFileSync(targetFile, referenceContent);\n\n return targetFile;\n}\n","import { join } from \"node:path\";\n\nexport function getProjectStoreDir(targetPath: string): string {\n return join(targetPath, \".grooveskills\");\n}\n\nexport function getProjectSkillsDir(targetPath: string): string {\n return join(getProjectStoreDir(targetPath), \"skills\");\n}\n\nexport function getProjectMemoryDir(targetPath: string): string {\n return join(getProjectStoreDir(targetPath), \"memory\");\n}\n\nexport function getProjectTasksDir(targetPath: string): string {\n return join(getProjectMemoryDir(targetPath), \"tasks\");\n}\n\nexport function getProjectConfigPath(targetPath: string): string {\n return join(getProjectStoreDir(targetPath), \"config.json\");\n}\n","import { chmodSync, existsSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { inspectFileAccess } from \"@/domains/fs/inspect-file-access\";\nimport { FilePermissionError } from \"@/errors/file-permission-error\";\n\nexport type WriteStrategyOutcome = \"direct\" | \"chmod\" | \"replaced\";\n\nexport interface WriteOutcome {\n strategy: WriteStrategyOutcome;\n previousOwnerUid: number | null;\n}\n\nexport interface SafeWriteOptions {\n chmodImpl?: (path: string, mode: number) => void;\n}\n\nexport function safeWriteFileSync(\n filePath: string,\n content: string,\n options?: SafeWriteOptions\n): WriteOutcome {\n const chmodFunction = options?.chmodImpl ?? chmodSync;\n\n try {\n writeFileSync(filePath, content, \"utf-8\");\n return { strategy: \"direct\", previousOwnerUid: null };\n } catch (error: unknown) {\n const nodeError = error as NodeJS.ErrnoException;\n if (nodeError.code !== \"EACCES\" && nodeError.code !== \"EPERM\") {\n throw error;\n }\n }\n\n const diagnosis = inspectFileAccess(filePath);\n\n if (diagnosis.exists && diagnosis.ownedByCurrentUser && !diagnosis.immutableFlag) {\n try {\n const targetMode = (diagnosis.mode ?? 0o644) | 0o200;\n chmodFunction(filePath, targetMode);\n writeFileSync(filePath, content, \"utf-8\");\n return { strategy: \"chmod\", previousOwnerUid: diagnosis.ownerUid };\n } catch {\n // Fall through to atomic replacement strategy\n }\n }\n\n if (diagnosis.exists && diagnosis.dirWritable && !diagnosis.immutableFlag) {\n const tempPath = `${filePath}.groove-tmp-${process.pid}-${Date.now()}`;\n try {\n const preservedMode = (diagnosis.mode ?? 0o644) | 0o200;\n writeFileSync(tempPath, content, { encoding: \"utf-8\", mode: preservedMode });\n renameSync(tempPath, filePath);\n return { strategy: \"replaced\", previousOwnerUid: diagnosis.ownerUid };\n } catch {\n if (existsSync(tempPath)) {\n try {\n rmSync(tempPath, { force: true });\n } catch {\n // Ignore cleanup failure\n }\n }\n }\n }\n\n throw new FilePermissionError(filePath, diagnosis);\n}\n","import { execFileSync } from \"node:child_process\";\nimport { accessSync, constants, existsSync, lstatSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nconst UF_IMMUTABLE = 0x00000002;\nconst SF_IMMUTABLE = 0x00020000;\n\nexport interface FileAccessDiagnosis {\n filePath: string;\n exists: boolean;\n isSymlink: boolean;\n ownedByCurrentUser: boolean;\n ownerUid: number | null;\n currentUid: number | null;\n mode: number | null;\n immutableFlag: boolean;\n dirWritable: boolean;\n parentDir: string;\n}\n\nfunction resolveNearestExistingDir(startDir: string): string {\n let current = startDir;\n while (!existsSync(current)) {\n const parent = dirname(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n return current;\n}\n\nfunction detectMacOsImmutableFlag(filePath: string, lstat: ReturnType<typeof lstatSync>): boolean {\n const rawFlags = (lstat as unknown as { flags?: number }).flags;\n if (typeof rawFlags === \"number\") {\n return Boolean(rawFlags & (UF_IMMUTABLE | SF_IMMUTABLE));\n }\n\n if (process.platform !== \"darwin\") {\n return false;\n }\n\n try {\n const out = execFileSync(\"stat\", [\"-f\", \"%f\", filePath], {\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n const parsedFlags = Number.parseInt(out, 10);\n if (Number.isNaN(parsedFlags)) {\n return false;\n }\n return Boolean(parsedFlags & (UF_IMMUTABLE | SF_IMMUTABLE));\n } catch {\n return false;\n }\n}\n\nexport function inspectFileAccess(filePath: string): FileAccessDiagnosis {\n const currentUid = typeof process.getuid === \"function\" ? process.getuid() : null;\n const parentDir = dirname(filePath);\n const checkDir = resolveNearestExistingDir(parentDir);\n\n let dirWritable = false;\n try {\n accessSync(checkDir, constants.W_OK);\n dirWritable = true;\n } catch {\n dirWritable = false;\n }\n\n let lstat: ReturnType<typeof lstatSync> | null = null;\n try {\n lstat = lstatSync(filePath);\n } catch {\n lstat = null;\n }\n\n if (!lstat) {\n return {\n filePath,\n exists: false,\n isSymlink: false,\n ownedByCurrentUser: true,\n ownerUid: null,\n currentUid,\n mode: null,\n immutableFlag: false,\n dirWritable,\n parentDir,\n };\n }\n\n const isSymlink = lstat.isSymbolicLink();\n const ownerUid = lstat.uid;\n const ownedByCurrentUser = currentUid === null || ownerUid === currentUid;\n const mode = lstat.mode & 0o777;\n const immutableFlag = detectMacOsImmutableFlag(filePath, lstat);\n\n return {\n filePath,\n exists: true,\n isSymlink,\n ownedByCurrentUser,\n ownerUid,\n currentUid,\n mode,\n immutableFlag,\n dirWritable,\n parentDir,\n };\n}\n\nexport function formatOwnerName(uid: number | null): string {\n if (uid === 0) {\n return \"root\";\n }\n if (uid === null) {\n return \"another user\";\n }\n return `uid ${uid}`;\n}\n","import {\n formatOwnerName,\n inspectFileAccess,\n type FileAccessDiagnosis,\n} from \"@/domains/fs/inspect-file-access\";\n\nfunction buildDiagnosisReason(diagnosis: FileAccessDiagnosis): string {\n if (diagnosis.immutableFlag) {\n return \"immutable flag (uchg) is set\";\n }\n if (diagnosis.exists && !diagnosis.ownedByCurrentUser) {\n return `owned by ${formatOwnerName(diagnosis.ownerUid)}`;\n }\n if (!diagnosis.dirWritable) {\n return `parent directory '${diagnosis.parentDir}' is not writable`;\n }\n return \"permission denied\";\n}\n\nfunction buildSuggestedFix(diagnosis: FileAccessDiagnosis): string {\n if (diagnosis.immutableFlag) {\n return `chflags nouchg \"${diagnosis.filePath}\"`;\n }\n if (diagnosis.exists && !diagnosis.ownedByCurrentUser) {\n return `sudo chown \"$(id -un)\" \"${diagnosis.filePath}\"`;\n }\n if (!diagnosis.dirWritable) {\n return `chmod u+w \"${diagnosis.parentDir}\"`;\n }\n return `chmod u+w \"${diagnosis.filePath}\"`;\n}\n\nexport class FilePermissionError extends Error {\n readonly code = \"EACCES\";\n readonly filePath: string;\n readonly diagnosis: FileAccessDiagnosis;\n readonly suggestedFixCommand: string;\n\n constructor(filePath: string, diagnosis?: FileAccessDiagnosis) {\n const resolved = diagnosis ?? inspectFileAccess(filePath);\n const reason = buildDiagnosisReason(resolved);\n super(`Cannot write to ${filePath} (${reason})`);\n this.name = \"FilePermissionError\";\n this.filePath = filePath;\n this.diagnosis = resolved;\n this.suggestedFixCommand = buildSuggestedFix(resolved);\n }\n}\n","import type { AgentAdapter } from \"@/domains/adapters/adapter.interface\";\nimport { writeAgentSkillReference } from \"@/domains/adapters/skill-reference-builder\";\nimport type { SkillMetadata } from \"@/types/skill.types\";\n\nexport class AntigravityAdapter implements AgentAdapter {\n readonly id = \"antigravity\" as const;\n readonly name = \"Antigravity\";\n readonly targetRelativeDir = \".agents/skills\";\n\n async installSkill(\n targetPath: string,\n skill: SkillMetadata,\n _skillSourceDir: string,\n transaction?: import(\"@/domains/fs/install-transaction\").InstallTransaction\n ): Promise<string[]> {\n const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill, transaction);\n return [file];\n }\n}\n","import type { AgentAdapter } from \"@/domains/adapters/adapter.interface\";\nimport { writeAgentSkillReference } from \"@/domains/adapters/skill-reference-builder\";\nimport type { SkillMetadata } from \"@/types/skill.types\";\n\nexport class ClaudeAdapter implements AgentAdapter {\n readonly id = \"claude\" as const;\n readonly name = \"Claude Code\";\n readonly targetRelativeDir = \".claude/skills\";\n\n async installSkill(\n targetPath: string,\n skill: SkillMetadata,\n _skillSourceDir: string,\n transaction?: import(\"@/domains/fs/install-transaction\").InstallTransaction\n ): Promise<string[]> {\n const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill, transaction);\n return [file];\n }\n}\n","import type { AgentAdapter } from \"@/domains/adapters/adapter.interface\";\nimport { writeCursorRuleReference } from \"@/domains/adapters/skill-reference-builder\";\nimport type { SkillMetadata } from \"@/types/skill.types\";\n\nexport class CursorAdapter implements AgentAdapter {\n readonly id = \"cursor\" as const;\n readonly name = \"Cursor\";\n readonly targetRelativeDir = \".cursor/rules\";\n\n async installSkill(\n targetPath: string,\n skill: SkillMetadata,\n _skillSourceDir: string,\n transaction?: import(\"@/domains/fs/install-transaction\").InstallTransaction\n ): Promise<string[]> {\n const file = writeCursorRuleReference(targetPath, this.targetRelativeDir, skill, transaction);\n return [file];\n }\n}\n","import type { AgentAdapter } from \"@/domains/adapters/adapter.interface\";\nimport { writeAgentSkillReference } from \"@/domains/adapters/skill-reference-builder\";\nimport type { SkillMetadata } from \"@/types/skill.types\";\n\nexport class GeminiAdapter implements AgentAdapter {\n readonly id = \"gemini\" as const;\n readonly name = \"Gemini Code Assist\";\n readonly targetRelativeDir = \".gemini/skills\";\n\n async installSkill(\n targetPath: string,\n skill: SkillMetadata,\n _skillSourceDir: string,\n transaction?: import(\"@/domains/fs/install-transaction\").InstallTransaction\n ): Promise<string[]> {\n const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill, transaction);\n return [file];\n }\n}\n","import { cpSync, existsSync, mkdirSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { resolveSkillsSourceRoot } from \"@/domains/installer/resolve-skills-source\";\nimport { getProjectSkillsDir } from \"@/domains/project-store/project-paths\";\nimport { SKILL_CATALOG } from \"@/domains/registry/skill-catalog\";\nimport type { InstallTransaction } from \"@/domains/fs/install-transaction\";\nimport type { AgentId } from \"@/types/agent.types\";\n\nexport function syncProjectStore(\n targetPath: string,\n selectedSkillIds: string[],\n _selectedAgents: AgentId[],\n transaction?: InstallTransaction\n): void {\n const bundledSkillsDir = resolveSkillsSourceRoot();\n const projectSkillsDir = getProjectSkillsDir(targetPath);\n\n if (transaction) {\n transaction.recordCreatedDir(projectSkillsDir);\n }\n\n if (!existsSync(projectSkillsDir)) {\n mkdirSync(projectSkillsDir, { recursive: true });\n }\n\n // Clean legacy cursor-rules directory if it exists\n const legacyCursorRules = join(targetPath, \".grooveskills\", \"cursor-rules\");\n if (existsSync(legacyCursorRules)) {\n try {\n rmSync(legacyCursorRules, { recursive: true, force: true });\n } catch {\n // Ignore cleanup error\n }\n }\n\n for (const skillId of selectedSkillIds) {\n const skill = SKILL_CATALOG.find((item) => item.id === skillId);\n if (!skill) {\n continue;\n }\n\n const sourceSkillDir = join(bundledSkillsDir, skill.directoryName);\n const destSkillDir = join(projectSkillsDir, skill.directoryName);\n\n if (transaction) {\n transaction.recordCreatedDir(destSkillDir);\n }\n\n if (existsSync(sourceSkillDir)) {\n cpSync(sourceSkillDir, destSkillDir, { recursive: true });\n }\n }\n}\n","import { fileURLToPath } from \"node:url\";\nimport { dirname, resolve, join } from \"node:path\";\nimport { existsSync } from \"node:fs\";\n\nexport function resolveSkillsSourceRoot(): string {\n const currentFilePath = fileURLToPath(import.meta.url);\n const currentDir = dirname(currentFilePath);\n\n // 1. From dist/ in published npm package or local build: dist/../skills\n const candidateFromDist = resolve(currentDir, \"../skills\");\n if (existsSync(candidateFromDist)) {\n return candidateFromDist;\n }\n\n // 2. From src/domains/installer/ during development: ../../../skills\n const candidateFromSrc = resolve(currentDir, \"../../../skills\");\n if (existsSync(candidateFromSrc)) {\n return candidateFromSrc;\n }\n\n // 3. Search upward for the package root containing a skills directory\n let searchDir = currentDir;\n for (let depth = 0; depth < 5; depth++) {\n const candidate = join(searchDir, \"skills\");\n if (existsSync(candidate)) {\n return candidate;\n }\n const parent = dirname(searchDir);\n if (parent === searchDir) {\n break;\n }\n searchDir = parent;\n }\n\n throw new Error(\n `GrooveSkills internal error: Unable to locate bundled skills directory from ${currentDir}`\n );\n}\n","import { existsSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n getProjectMemoryDir,\n getProjectTasksDir,\n} from \"@/domains/project-store/project-paths\";\nimport {\n buildContextTemplate,\n buildDecisionsTemplate,\n buildOnboardingTaskTemplate,\n buildTaskTemplate,\n} from \"@/domains/harness/harness-templates\";\nimport { scanProjectOnboarding } from \"@/domains/harness/scan-project-onboarding\";\nimport { upsertAgentInstructions } from \"@/domains/harness/upsert-agent-instructions\";\nimport { safeWriteFileSync } from \"@/domains/fs/safe-file-writer\";\nimport type { InstallTransaction } from \"@/domains/fs/install-transaction\";\nimport type {\n HarnessInstallOptions,\n HarnessInstallResult,\n} from \"@/types/harness.types\";\n\nfunction writeTrackedFile(\n filePath: string,\n content: string,\n transaction?: InstallTransaction\n): void {\n if (transaction) {\n transaction.recordBeforeWrite(filePath);\n }\n const outcome = safeWriteFileSync(filePath, content);\n if (outcome.strategy === \"replaced\" && transaction) {\n transaction.recordReplacedFile(filePath, outcome.previousOwnerUid);\n }\n}\n\nexport function installHarness(options: HarnessInstallOptions): HarnessInstallResult {\n const memoryDir = getProjectMemoryDir(options.targetPath);\n const tasksDir = getProjectTasksDir(options.targetPath);\n const language = options.language ?? \"es\";\n const forceOnboarding = Boolean(options.forceOnboarding);\n const transaction = options.transaction;\n\n if (transaction) {\n transaction.recordCreatedDir(memoryDir);\n transaction.recordCreatedDir(tasksDir);\n }\n\n if (!existsSync(tasksDir)) {\n mkdirSync(tasksDir, { recursive: true });\n }\n\n const createdFiles: string[] = [];\n const contextPath = join(memoryDir, \"context.md\");\n const shouldWriteContext = !existsSync(contextPath) || forceOnboarding;\n\n if (shouldWriteContext) {\n const profile = scanProjectOnboarding(options.targetPath);\n const contextContent = buildContextTemplate(\n options.detectedDependencies,\n language,\n profile\n );\n writeTrackedFile(contextPath, contextContent, transaction);\n createdFiles.push(contextPath);\n\n const onboardingTaskPath = join(tasksDir, \"00-onboarding.md\");\n writeTrackedFile(\n onboardingTaskPath,\n buildOnboardingTaskTemplate(profile.projectName),\n transaction\n );\n createdFiles.push(onboardingTaskPath);\n }\n\n const decisionsPath = join(memoryDir, \"decisions.md\");\n if (!existsSync(decisionsPath)) {\n writeTrackedFile(decisionsPath, buildDecisionsTemplate(language), transaction);\n createdFiles.push(decisionsPath);\n }\n\n const templateTaskPath = join(tasksDir, \"_template.md\");\n if (!existsSync(templateTaskPath)) {\n writeTrackedFile(templateTaskPath, buildTaskTemplate(), transaction);\n createdFiles.push(templateTaskPath);\n }\n\n const instructions = upsertAgentInstructions(\n options.targetPath,\n options.selectedAgents,\n language,\n transaction\n );\n createdFiles.push(...instructions);\n\n return {\n createdFiles,\n onboardingInitialized: shouldWriteContext,\n };\n}\n","import type { ProjectLanguage } from \"@/types/harness.types\";\n\nexport interface LanguageDefinition {\n code: ProjectLanguage;\n name: string;\n nativeName: string;\n instruction: string;\n onboardingPromptTitle: string;\n onboardingPrompt: string;\n}\n\nexport const SUPPORTED_LANGUAGES: Record<ProjectLanguage, LanguageDefinition> = {\n es: {\n code: \"es\",\n name: \"Spanish\",\n nativeName: \"Español\",\n instruction: \"Todos los mensajes, validaciones, errores, CTAs y comunicaciones con el usuario deben redactarse estrictamente en Español. El tono debe ser empático, amable, persuasivo y profesional.\",\n onboardingPromptTitle: \"Prompt de inicialización para tu Agente IA (Copia y pega en el chat):\",\n onboardingPrompt: \"Hola. Acabo de configurar GrooveSkills Harness en este proyecto. Por favor lee `.grooveskills/memory/tasks/00-onboarding.md`, `.grooveskills/memory/context.md` y las skills instaladas en `.agents/skills/`. Hazme preguntas interactivas paso a paso para detectar vacíos de arquitectura, aclarar objetivos y adaptar el proyecto a mis necesidades antes de continuar.\",\n },\n en: {\n code: \"en\",\n name: \"English\",\n nativeName: \"English\",\n instruction: \"All user-facing messages, form validations, errors, CTAs, and notifications must be written strictly in English. Tone must be empathetic, friendly, persuasive, and professional.\",\n onboardingPromptTitle: \"Initialization prompt for your AI Agent (Copy and paste into your chat):\",\n onboardingPrompt: \"Hello. I just configured GrooveSkills Harness in this project. Please review `.grooveskills/memory/tasks/00-onboarding.md`, `.grooveskills/memory/context.md`, and the skills installed in `.agents/skills/`. Ask me step-by-step interactive questions to identify architectural gaps, clarify priorities, and adapt the project to my needs before continuing.\",\n },\n pt: {\n code: \"pt\",\n name: \"Portuguese\",\n nativeName: \"Português\",\n instruction: \"Todas as mensagens, validações, erros, CTAs e comunicações voltadas para o usuário devem ser redigidas estritamente em Português. O tom deve ser empático, amigável, persuasivo e profissional.\",\n onboardingPromptTitle: \"Prompt de inicialização para o seu Agente de IA (Copie e cole no chat):\",\n onboardingPrompt: \"Olá. Acabei de configurar o GrooveSkills Harness neste projeto. Por favor leia `.grooveskills/memory/tasks/00-onboarding.md`, `.grooveskills/memory/context.md` e as skills instaladas em `.agents/skills/`. Faça-me perguntas interativas passo a passo para mapear lacunas de arquitetura, alinhar prioridades e adaptar o projeto às minhas necessidades antes de prosseguir.\",\n },\n it: {\n code: \"it\",\n name: \"Italian\",\n nativeName: \"Italiano\",\n instruction: \"Tutti i messaggi, le convalide, gli errori, i pulsanti/CTA e le comunicazioni rivolte all'utente devono essere scritti rigorosamente in Italiano. Il tono deve essere empatico, cordiale, persuasivo e professionale.\",\n onboardingPromptTitle: \"Prompt di inizializzazione per il tuo Agente AI (Copia e incolla nella chat):\",\n onboardingPrompt: \"Ciao. Ho appena configurato GrooveSkills Harness in questo progetto. Ti prego di leggere `.grooveskills/memory/tasks/00-onboarding.md`, `.grooveskills/memory/context.md` e le skills installate in `.agents/skills/`. Fammi domande interattive passo dopo passo per identificare lacune architetturali, allineare le priorità e adattare il progetto alle mie esigenze prima di continuare.\",\n },\n fr: {\n code: \"fr\",\n name: \"French\",\n nativeName: \"Français\",\n instruction: \"Tous les messages, validations, erreurs, boutons d'appel à l'action (CTA) et notifications destinés à l'utilisateur doivent être rédigés strictement en Français. Le ton doit être empathique, courtois, persuasif et professionnel.\",\n onboardingPromptTitle: \"Prompt d'initialisation pour votre Agent IA (Copiez et collez dans le chat) :\",\n onboardingPrompt: \"Bonjour. Je viens de configurer GrooveSkills Harness sur ce projet. Veuillez consulter `.grooveskills/memory/tasks/00-onboarding.md`, `.grooveskills/memory/context.md` et les skills installées dans `.agents/skills/`. Posez-moi des questions interactives étape par étape pour identifier les lacunes d'architecture, préciser les priorités et adapter le projet à mes besoins avant de continuer.\",\n },\n};\n","import type { ProjectLanguage } from \"@/types/harness.types\";\nimport { SUPPORTED_LANGUAGES } from \"@/domains/harness/harness-languages\";\nimport type { ProjectOnboardingProfile } from \"@/domains/harness/scan-project-onboarding\";\n\nexport function buildContextTemplate(\n detectedDependencies: string[],\n language: ProjectLanguage = \"es\",\n profile?: ProjectOnboardingProfile\n): string {\n const dependenciesFormatted =\n detectedDependencies.length > 0\n ? detectedDependencies.map((dependencyName) => `- \\`${dependencyName}\\``).join(\"\\n\")\n : \"- (No external dependencies detected)\";\n\n const languageConfig = SUPPORTED_LANGUAGES[language];\n const projectName = profile?.projectName ?? \"Project\";\n const packageManager = profile?.packageManager ?? \"npm\";\n\n const commandLines: string[] = [];\n if (profile?.commands) {\n for (const [commandKey, commandValue] of Object.entries(profile.commands)) {\n commandLines.push(`- **${commandKey}**: \\`${commandValue}\\``);\n }\n }\n const commandsSection =\n commandLines.length > 0\n ? commandLines.join(\"\\n\")\n : `- Build: Refer to \\`package.json\\` scripts.\\n- Typecheck: Refer to TypeScript configuration.\\n- Tests: Refer to test runner configuration.`;\n\n const aliasLines: string[] = [];\n if (profile?.pathAliases) {\n for (const [aliasPattern, aliasTarget] of Object.entries(profile.pathAliases)) {\n aliasLines.push(`- \\`${aliasPattern}\\` -> \\`${aliasTarget}\\``);\n }\n }\n const aliasesSection =\n aliasLines.length > 0 ? `\\n### Path Aliases\\n${aliasLines.join(\"\\n\")}\\n` : \"\";\n\n const directoryLines: string[] = [];\n if (profile?.sourceDirectories && profile.sourceDirectories.length > 0) {\n for (const directoryName of profile.sourceDirectories) {\n directoryLines.push(`- \\`${directoryName}/\\``);\n }\n }\n const directoriesSection =\n directoryLines.length > 0 ? `\\n### Source Modules\\n${directoryLines.join(\"\\n\")}\\n` : \"\";\n\n return `# Project Context & Architecture: ${projectName}\n\nThis file provides AI agents with instant architectural orientation for this project.\n\n## 1. Stack & Dependencies\n- **Package Manager**: \\`${packageManager}\\`\n${dependenciesFormatted}\n\n## 2. Directory Structure Conventions\n- Follow single-responsibility per file (<200 lines).\n- Maintain direct imports with path aliases; avoid barrel files.\n- Keep domain boundaries explicit and clean.\n${aliasesSection}${directoriesSection}\n## 3. Communication & User Copy Language\n- **Configured Language**: ${languageConfig.nativeName} (\\`${language}\\`).\n- **Policy**: ${languageConfig.instruction}\n\n## 4. Essential Commands\n${commandsSection}\n`;\n}\n\nexport function buildDecisionsTemplate(language: ProjectLanguage = \"es\"): string {\n const currentDate = new Date().toISOString().split(\"T\")[0];\n const languageConfig = SUPPORTED_LANGUAGES[language];\n\n return `# Architecture Decision Records (ADR)\n\nAn append-only log of significant technical and architectural choices.\n\n| Date | Title | Decision | Reason & Consequences |\n| :--- | :--- | :--- | :--- |\n| ${currentDate} | Adopt GrooveSkills Harness | Initialized \\`.grooveskills/\\` control plane with ODD | Clean, encapsulated agent memory, 3-lane ODD flow, and ${languageConfig.nativeName} copy standard |\n`;\n}\n\nexport function buildOnboardingTaskTemplate(projectName: string = \"Project\"): string {\n const currentDate = new Date().toISOString().split(\"T\")[0];\n\n return `---\nstatus: pending\ncreatedAt: ${currentDate}\n---\n\n# 00 — Initial Project Onboarding & Architecture Exploration: ${projectName}\n\n## Outcome Hypothesis\nBy scanning dependencies, entry points, configuration manifests, and module layout, the AI agent will gain a verified architectural understanding of \\`${projectName}\\`, proven by filling out \\`.grooveskills/memory/context.md\\`, formulating interactive alignment questions with the user, and validating the essential build/typecheck commands.\n\n## Scope\n- In scope: Inspect project manifests, entry points, directory conventions, ask interactive alignment questions, and verify script execution.\n- Out of scope: Refactoring business logic or modifying functional code before alignment.\n\n## Checklist\n- [ ] Verify package manager and essential scripts (\\`build\\`, \\`test\\`, \\`typecheck\\`).\n- [ ] Map high-level module architecture and data flow in \\`.grooveskills/memory/context.md\\`.\n- [ ] Ask the user step-by-step interactive questions to clarify goals, domain scope, and adapt project conventions.\n- [ ] Document agreed technical decisions in \\`.grooveskills/memory/decisions.md\\`.\n- [ ] Verify test runner or static checks pass cleanly.\n- [ ] Switch status to \\`completed\\` once project context is fully verified.\n\n## Evidence\n- Observed command runs and outputs during the initial onboarding pass.\n- User answers to alignment questions captured in memory.\n\n## Next\n- Once onboarding is marked completed, proceed with domain tasks following the 3-lane ODD protocol.\n`;\n}\n\nexport function buildTaskTemplate(): string {\n return `---\nstatus: in-progress\ncreatedAt: \\${CURRENT_DATE}\n---\n\n# Feature / Task Title\n\n## Outcome Hypothesis\nDescribe the expected behavioral outcome:\nBy [Output / Technical Change], [Outcome / Verifiable Behavior] will occur, proven by [Evidence / Test / Build Command].\n\n## Scope\n- In scope:\n- Out of scope:\n\n## Checklist\n- [ ] Task 1: (Define expected observed proof)\n- [ ] Task 2: (Define expected observed proof)\n\n## Evidence\n- Observed test/typecheck/build commands or runtime outputs proving completion.\n\n## Next\n- Next concrete step if interrupted.\n`;\n}\n\nexport function buildAgentHarnessBlock(language: ProjectLanguage = \"es\"): string {\n const languageConfig = SUPPORTED_LANGUAGES[language];\n\n return `<!-- grooveskills:harness:start -->\n# GrooveSkills Harness — Agent Rules & Memory\n\nThis project uses the **GrooveSkills Harness** located in \\`.grooveskills/\\`.\n\n## 1. Three-Lane ODD Protocol\n- **Onboarding Check**: If \\`.grooveskills/memory/tasks/00-onboarding.md\\` has \\`status: pending\\`, complete its checklist to enrich \\`context.md\\` and set its status to \\`completed\\`.\n- **Authorize & Explore**: Follow the 7-step ODD protocol (Authorize, Explore, Resolve, Classify, Track & Hypothesize, Execute, Verify).\n- **Lane 1 (Answer)**: Explanations, audits, or questions. Read-only; write zero code.\n- **Lane 2 (Task)**: Direct implementation. Declare Outcome Hypothesis and checklist in \\`.grooveskills/memory/tasks/<slug>.md\\`. Only check off tasks with observed evidence under \\`Evidence\\`.\n- **Lane 3 (Spec)**: Ambiguous or high-impact architecture. Clarify and validate the spec in \\`.grooveskills/memory/tasks/<slug>.md\\` before writing code.\n\n## 2. User Communication Language (${languageConfig.nativeName})\n- **Language**: \\`${language}\\` (${languageConfig.nativeName}).\n- **Requirement**: ${languageConfig.instruction}\n\n## 3. Memory Locations\n- Architecture context: \\`.grooveskills/memory/context.md\\`\n- Technical decisions (ADR): \\`.grooveskills/memory/decisions.md\\`\n- Active tasks & evidence: \\`.grooveskills/memory/tasks/\\`\n<!-- grooveskills:harness:end -->`;\n}\n","import { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\n\nexport interface ProjectOnboardingProfile {\n projectName: string;\n packageManager: string;\n commands: Record<string, string>;\n pathAliases: Record<string, string>;\n sourceDirectories: string[];\n}\n\nfunction detectProjectName(targetPath: string): string {\n const packageJsonPath = join(targetPath, \"package.json\");\n if (existsSync(packageJsonPath)) {\n try {\n const raw = readFileSync(packageJsonPath, \"utf-8\");\n const parsed = JSON.parse(raw) as { name?: string };\n if (typeof parsed.name === \"string\" && parsed.name.trim().length > 0) {\n return parsed.name.trim();\n }\n } catch {\n // Fall through to other manifests\n }\n }\n\n const cargoPath = join(targetPath, \"Cargo.toml\");\n if (existsSync(cargoPath)) {\n try {\n const cargoRaw = readFileSync(cargoPath, \"utf-8\");\n const nameMatch = cargoRaw.match(/name\\s*=\\s*\"([^\"]+)\"/);\n if (nameMatch?.[1]) {\n return nameMatch[1];\n }\n } catch {\n // Fall through\n }\n }\n\n const pyprojectPath = join(targetPath, \"pyproject.toml\");\n if (existsSync(pyprojectPath)) {\n try {\n const pyprojectRaw = readFileSync(pyprojectPath, \"utf-8\");\n const nameMatch = pyprojectRaw.match(/name\\s*=\\s*\"([^\"]+)\"/);\n if (nameMatch?.[1]) {\n return nameMatch[1];\n }\n } catch {\n // Fall through\n }\n }\n\n return basename(targetPath) || \"project\";\n}\n\nfunction detectPackageManager(targetPath: string): string {\n if (existsSync(join(targetPath, \"pnpm-lock.yaml\"))) {\n return \"pnpm\";\n }\n if (existsSync(join(targetPath, \"bun.lockb\")) || existsSync(join(targetPath, \"bun.lock\"))) {\n return \"bun\";\n }\n if (existsSync(join(targetPath, \"yarn.lock\"))) {\n return \"yarn\";\n }\n if (existsSync(join(targetPath, \"package-lock.json\"))) {\n return \"npm\";\n }\n if (existsSync(join(targetPath, \"Cargo.lock\")) || existsSync(join(targetPath, \"Cargo.toml\"))) {\n return \"cargo\";\n }\n if (existsSync(join(targetPath, \"uv.lock\"))) {\n return \"uv\";\n }\n if (existsSync(join(targetPath, \"poetry.lock\"))) {\n return \"poetry\";\n }\n return \"npm\";\n}\n\nfunction detectCommands(targetPath: string, packageManager: string): Record<string, string> {\n const packageJsonPath = join(targetPath, \"package.json\");\n if (!existsSync(packageJsonPath)) {\n return {};\n }\n\n try {\n const raw = readFileSync(packageJsonPath, \"utf-8\");\n const parsed = JSON.parse(raw) as { scripts?: Record<string, string> };\n const scripts = parsed.scripts ?? {};\n const commands: Record<string, string> = {};\n\n const runner = packageManager === \"npm\" ? \"npm run\" : packageManager;\n\n if (scripts.build) {\n commands.build = `${runner} build`;\n }\n if (scripts[\"check-types\"]) {\n commands.typecheck = `${runner} check-types`;\n } else if (scripts.typecheck) {\n commands.typecheck = `${runner} typecheck`;\n } else if (scripts.tsc) {\n commands.typecheck = `${runner} tsc`;\n }\n\n if (scripts.test) {\n commands.test = `${runner} test`;\n }\n if (scripts.lint) {\n commands.lint = `${runner} lint`;\n }\n if (scripts.dev) {\n commands.dev = `${runner} dev`;\n }\n\n return commands;\n } catch {\n return {};\n }\n}\n\nfunction detectPathAliases(targetPath: string): Record<string, string> {\n const tsconfigPath = join(targetPath, \"tsconfig.json\");\n if (!existsSync(tsconfigPath)) {\n return {};\n }\n\n try {\n const raw = readFileSync(tsconfigPath, \"utf-8\");\n const parsed = JSON.parse(raw) as {\n compilerOptions?: {\n paths?: Record<string, string[]>;\n };\n };\n const paths = parsed.compilerOptions?.paths ?? {};\n const aliases: Record<string, string> = {};\n\n for (const [aliasKey, aliasTargets] of Object.entries(paths)) {\n if (Array.isArray(aliasTargets) && typeof aliasTargets[0] === \"string\") {\n aliases[aliasKey] = aliasTargets[0];\n }\n }\n\n return aliases;\n } catch {\n return {};\n }\n}\n\nfunction detectSourceDirectories(targetPath: string): string[] {\n const srcPath = join(targetPath, \"src\");\n const scanTarget = existsSync(srcPath) ? srcPath : targetPath;\n\n try {\n const entries = readdirSync(scanTarget, { withFileTypes: true });\n return entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name)\n .filter((name) => !name.startsWith(\".\") && name !== \"node_modules\" && name !== \"dist\");\n } catch {\n return [];\n }\n}\n\nexport function scanProjectOnboarding(targetPath: string): ProjectOnboardingProfile {\n const projectName = detectProjectName(targetPath);\n const packageManager = detectPackageManager(targetPath);\n const commands = detectCommands(targetPath, packageManager);\n const pathAliases = detectPathAliases(targetPath);\n const sourceDirectories = detectSourceDirectories(targetPath);\n\n return {\n projectName,\n packageManager,\n commands,\n pathAliases,\n sourceDirectories,\n };\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { buildAgentHarnessBlock } from \"@/domains/harness/harness-templates\";\nimport { safeWriteFileSync } from \"@/domains/fs/safe-file-writer\";\nimport type { InstallTransaction } from \"@/domains/fs/install-transaction\";\nimport type { AgentId } from \"@/types/agent.types\";\nimport type { ProjectLanguage } from \"@/types/harness.types\";\n\nconst START_MARKER = \"<!-- grooveskills:harness:start -->\";\nconst END_MARKER = \"<!-- grooveskills:harness:end -->\";\n\nfunction writeWithTransaction(\n filePath: string,\n content: string,\n transaction?: InstallTransaction\n): void {\n const outcome = safeWriteFileSync(filePath, content);\n if (outcome.strategy === \"replaced\" && transaction) {\n transaction.recordReplacedFile(filePath, outcome.previousOwnerUid);\n }\n}\n\nfunction applyHarnessBlock(\n filePath: string,\n language: ProjectLanguage = \"es\",\n transaction?: InstallTransaction\n): void {\n if (transaction) {\n transaction.recordBeforeWrite(filePath);\n }\n\n const block = buildAgentHarnessBlock(language);\n\n if (!existsSync(filePath)) {\n writeWithTransaction(filePath, `${block}\\n`, transaction);\n return;\n }\n\n const existingContent = readFileSync(filePath, \"utf-8\");\n\n if (existingContent.includes(START_MARKER) && existingContent.includes(END_MARKER)) {\n const regex = new RegExp(`${START_MARKER}[\\\\s\\\\S]*?${END_MARKER}`, \"g\");\n const updated = existingContent.replace(regex, block);\n writeWithTransaction(filePath, updated, transaction);\n return;\n }\n\n const separator = existingContent.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n writeWithTransaction(filePath, `${existingContent}${separator}${block}\\n`, transaction);\n}\n\nexport function upsertAgentInstructions(\n targetPath: string,\n selectedAgents: AgentId[],\n language: ProjectLanguage = \"es\",\n transaction?: InstallTransaction\n): string[] {\n const updatedFiles: string[] = [];\n\n const agentsMdPath = join(targetPath, \"AGENTS.md\");\n applyHarnessBlock(agentsMdPath, language, transaction);\n updatedFiles.push(agentsMdPath);\n\n if (selectedAgents.includes(\"claude\")) {\n const claudeMdPath = join(targetPath, \"CLAUDE.md\");\n applyHarnessBlock(claudeMdPath, language, transaction);\n updatedFiles.push(claudeMdPath);\n }\n\n return updatedFiles;\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { getProjectConfigPath } from \"@/domains/project-store/project-paths\";\nimport { safeWriteFileSync } from \"@/domains/fs/safe-file-writer\";\nimport type { InstallTransaction } from \"@/domains/fs/install-transaction\";\nimport type { GrooveSkillsConfig, ProjectLanguage } from \"@/types/harness.types\";\nimport type { AgentId } from \"@/types/agent.types\";\n\ninterface ParsedConfigState {\n skills: string[];\n agents: AgentId[];\n harness: boolean;\n language?: ProjectLanguage;\n}\n\nfunction readExistingConfig(configPath: string): ParsedConfigState {\n const fallback: ParsedConfigState = {\n skills: [],\n agents: [],\n harness: false,\n };\n\n if (!existsSync(configPath)) {\n return fallback;\n }\n\n try {\n const raw = readFileSync(configPath, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<GrooveSkillsConfig>;\n\n return {\n skills: Array.isArray(parsed.skills) ? parsed.skills : [],\n agents: Array.isArray(parsed.agents) ? parsed.agents : [],\n harness: typeof parsed.harness === \"boolean\" ? parsed.harness : false,\n language: typeof parsed.language === \"string\" ? (parsed.language as ProjectLanguage) : undefined,\n };\n } catch {\n return fallback;\n }\n}\n\nexport function writeProjectConfig(\n targetPath: string,\n newSkills: string[],\n newAgents: AgentId[],\n harnessEnabled: boolean,\n language?: ProjectLanguage,\n transaction?: InstallTransaction\n): string {\n const configPath = getProjectConfigPath(targetPath);\n if (transaction) {\n transaction.recordBeforeWrite(configPath);\n }\n\n const existing = readExistingConfig(configPath);\n\n const mergedSkills = Array.from(new Set([...existing.skills, ...newSkills]));\n const mergedAgents = Array.from(new Set([...existing.agents, ...newAgents]));\n const resolvedLanguage = language ?? existing.language ?? \"es\";\n const isHarnessActive = existing.harness || harnessEnabled;\n\n const config: GrooveSkillsConfig = {\n version: 1,\n harness: isHarnessActive,\n ...(isHarnessActive ? { language: resolvedLanguage } : {}),\n agents: mergedAgents,\n skills: mergedSkills,\n updatedAt: new Date().toISOString(),\n };\n\n const outcome = safeWriteFileSync(configPath, `${JSON.stringify(config, null, 2)}\\n`);\n if (outcome.strategy === \"replaced\" && transaction) {\n transaction.recordReplacedFile(configPath, outcome.previousOwnerUid);\n }\n\n return configPath;\n}\n","import { existsSync, readdirSync, readFileSync, rmSync } from \"node:fs\";\nimport { safeWriteFileSync } from \"@/domains/fs/safe-file-writer\";\n\nexport interface RollbackFailure {\n path: string;\n reason: string;\n}\n\nexport interface ReplacedFileNotice {\n filePath: string;\n previousOwnerUid: number | null;\n}\n\nexport interface RollbackReport {\n restoredFiles: string[];\n removedFiles: string[];\n removedDirs: string[];\n failures: RollbackFailure[];\n isClean: boolean;\n}\n\nexport class InstallTransaction {\n private originalFiles = new Map<string, string | null>();\n private createdDirs: string[] = [];\n private replacedFiles: ReplacedFileNotice[] = [];\n\n recordBeforeWrite(filePath: string): void {\n if (this.originalFiles.has(filePath)) {\n return;\n }\n if (existsSync(filePath)) {\n try {\n this.originalFiles.set(filePath, readFileSync(filePath, \"utf-8\"));\n } catch {\n this.originalFiles.set(filePath, null);\n }\n } else {\n this.originalFiles.set(filePath, null);\n }\n }\n\n recordCreatedDir(dirPath: string): void {\n if (!existsSync(dirPath) && !this.createdDirs.includes(dirPath)) {\n this.createdDirs.push(dirPath);\n }\n }\n\n recordReplacedFile(filePath: string, previousOwnerUid: number | null): void {\n if (!this.replacedFiles.some((item) => item.filePath === filePath)) {\n this.replacedFiles.push({ filePath, previousOwnerUid });\n }\n }\n\n getReplacedFiles(): ReplacedFileNotice[] {\n return [...this.replacedFiles];\n }\n\n rollback(): RollbackReport {\n const restoredFiles: string[] = [];\n const removedFiles: string[] = [];\n const removedDirs: string[] = [];\n const failures: RollbackFailure[] = [];\n\n for (const [filePath, content] of this.originalFiles.entries()) {\n try {\n if (content === null) {\n if (existsSync(filePath)) {\n rmSync(filePath, { force: true });\n removedFiles.push(filePath);\n }\n continue;\n }\n\n if (existsSync(filePath)) {\n try {\n const currentContent = readFileSync(filePath, \"utf-8\");\n if (currentContent === content) {\n continue;\n }\n } catch {\n // Proceed to restore if current content cannot be read\n }\n }\n\n safeWriteFileSync(filePath, content);\n restoredFiles.push(filePath);\n } catch (error: unknown) {\n const reason = error instanceof Error ? error.message : String(error);\n failures.push({ path: filePath, reason });\n }\n }\n\n const sortedDirs = [...this.createdDirs].sort(\n (firstDir, secondDir) => secondDir.length - firstDir.length\n );\n for (const directoryPath of sortedDirs) {\n try {\n if (existsSync(directoryPath) && readdirSync(directoryPath).length === 0) {\n rmSync(directoryPath, { recursive: true, force: true });\n removedDirs.push(directoryPath);\n }\n } catch (error: unknown) {\n const reason = error instanceof Error ? error.message : String(error);\n failures.push({ path: directoryPath, reason });\n }\n }\n\n return {\n restoredFiles,\n removedFiles,\n removedDirs,\n failures,\n isClean: failures.length === 0,\n };\n }\n}\n","import { join } from \"node:path\";\nimport { inspectFileAccess } from \"@/domains/fs/inspect-file-access\";\nimport {\n getProjectConfigPath,\n getProjectMemoryDir,\n getProjectTasksDir,\n} from \"@/domains/project-store/project-paths\";\nimport { FilePermissionError } from \"@/errors/file-permission-error\";\nimport type { AgentId } from \"@/types/agent.types\";\n\nexport interface PreflightCheckOptions {\n targetPath: string;\n selectedAgents: AgentId[];\n}\n\nexport function canRecoverOrWriteTarget(filePath: string): void {\n const diagnosis = inspectFileAccess(filePath);\n\n if (diagnosis.immutableFlag) {\n throw new FilePermissionError(filePath, diagnosis);\n }\n\n if (!diagnosis.exists) {\n if (!diagnosis.dirWritable) {\n throw new FilePermissionError(filePath, diagnosis);\n }\n return;\n }\n\n const ownerWritable =\n diagnosis.ownedByCurrentUser && ((diagnosis.mode ?? 0) & 0o200) !== 0;\n\n if (ownerWritable) {\n return;\n }\n\n if (diagnosis.ownedByCurrentUser) {\n return;\n }\n\n if (diagnosis.dirWritable) {\n return;\n }\n\n throw new FilePermissionError(filePath, diagnosis);\n}\n\nexport function runPreflightWriteCheck(options: PreflightCheckOptions): void {\n const memoryDir = getProjectMemoryDir(options.targetPath);\n const tasksDir = getProjectTasksDir(options.targetPath);\n\n const candidatePaths: string[] = [\n join(options.targetPath, \"AGENTS.md\"),\n ];\n\n if (options.selectedAgents.includes(\"claude\")) {\n candidatePaths.push(join(options.targetPath, \"CLAUDE.md\"));\n }\n\n candidatePaths.push(\n getProjectConfigPath(options.targetPath),\n join(memoryDir, \"context.md\"),\n join(memoryDir, \"decisions.md\"),\n join(tasksDir, \"00-onboarding.md\"),\n join(tasksDir, \"_template.md\")\n );\n\n for (const filePath of candidatePaths) {\n canRecoverOrWriteTarget(filePath);\n }\n}\n","import type { RollbackReport } from \"@/domains/fs/install-transaction\";\n\nexport interface InstallTransactionErrorOptions {\n stage: string;\n cause: unknown;\n rollbackReport: RollbackReport;\n suggestedFix?: string;\n}\n\nexport class InstallTransactionError extends Error {\n readonly stage: string;\n readonly causeError: unknown;\n readonly rollbackReport: RollbackReport;\n readonly suggestedFix?: string;\n\n constructor(options: InstallTransactionErrorOptions) {\n const rawMessage =\n options.cause instanceof Error ? options.cause.message : String(options.cause);\n super(`Error during stage '${options.stage}': ${rawMessage}`);\n this.name = \"InstallTransactionError\";\n this.stage = options.stage;\n this.causeError = options.cause;\n this.rollbackReport = options.rollbackReport;\n this.suggestedFix = options.suggestedFix;\n }\n}\n","import picocolors from \"picocolors\";\nimport { SUPPORTED_LANGUAGES } from \"@/domains/harness/harness-languages\";\nimport { getTerminalWidth, wrapText } from \"@/domains/ui/terminal-layout\";\nimport type { ProjectLanguage } from \"@/types/harness.types\";\n\nexport interface OnboardingPromptRender {\n title: string;\n prompt: string;\n formattedOutput: string;\n}\n\nexport function formatOnboardingPrompt(\n language: ProjectLanguage = \"es\"\n): OnboardingPromptRender {\n const languageConfig = SUPPORTED_LANGUAGES[language] ?? SUPPORTED_LANGUAGES.es;\n const title = languageConfig.onboardingPromptTitle;\n const prompt = languageConfig.onboardingPrompt;\n\n const boxWidth = Math.max(getTerminalWidth(80) - 4, 50);\n const contentWidth = boxWidth - 4;\n const wrappedPromptLines = wrapText(prompt, contentWidth).split(\"\\n\");\n\n const borderHorizontal = \"─\".repeat(boxWidth - 2);\n const badgeText = \" COPY & PASTE PROMPT FOR YOUR AI AGENT \";\n const badgePadded = badgeText.padEnd(contentWidth, \" \");\n\n const topBorder = picocolors.cyan(`╭${borderHorizontal}╮`);\n const badgeLine = `${picocolors.cyan(\"│ \")}${picocolors.bold(picocolors.bgCyan(picocolors.black(badgePadded)))}${picocolors.cyan(\" │\")}`;\n const dividerLine = picocolors.cyan(`├${borderHorizontal}┤`);\n const promptLines = wrappedPromptLines.map((line) => {\n const paddedLine = line.padEnd(contentWidth, \" \");\n return `${picocolors.cyan(\"│ \")}${picocolors.bold(picocolors.white(paddedLine))}${picocolors.cyan(\" │\")}`;\n });\n const bottomBorder = picocolors.cyan(`╰${borderHorizontal}╯`);\n\n const formattedOutput = [\n \"\",\n topBorder,\n badgeLine,\n dividerLine,\n ...promptLines,\n bottomBorder,\n \"\",\n ].join(\"\\n\");\n\n return {\n title,\n prompt,\n formattedOutput,\n };\n}\n","export function getTerminalWidth(fallbackWidth: number = 80): number {\n const terminalColumns = process.stdout.columns;\n if (typeof terminalColumns === \"number\" && terminalColumns > 20) {\n return Math.min(terminalColumns, 100);\n }\n return fallbackWidth;\n}\n\nexport function wrapText(rawText: string, maxLineWidth: number = 76): string {\n return rawText\n .split(\"\\n\")\n .map((line) => {\n if (line.length <= maxLineWidth) {\n return line;\n }\n const words = line.split(\" \");\n const wrappedLines: string[] = [];\n let currentLine = \"\";\n\n for (const word of words) {\n const potentialLine = currentLine ? `${currentLine} ${word}` : word;\n if (potentialLine.length <= maxLineWidth) {\n currentLine = potentialLine;\n } else {\n if (currentLine) {\n wrappedLines.push(currentLine);\n }\n currentLine = word;\n }\n }\n\n if (currentLine) {\n wrappedLines.push(currentLine);\n }\n\n return wrappedLines.join(\"\\n\");\n })\n .join(\"\\n\");\n}\n","import { basename } from \"node:path\";\nimport { userInfo } from \"node:os\";\nimport * as prompts from \"@clack/prompts\";\nimport picocolors from \"picocolors\";\nimport { formatOwnerName } from \"@/domains/fs/inspect-file-access\";\nimport { getTerminalWidth, wrapText } from \"@/domains/ui/terminal-layout\";\nimport { InstallTransactionError } from \"@/errors/install-transaction-error\";\nimport type { ReplacedFileNotice } from \"@/domains/fs/install-transaction\";\n\nexport function getCurrentUsername(): string {\n try {\n return userInfo().username;\n } catch {\n return process.env.USER || process.env.LOGNAME || \"current user\";\n }\n}\n\nexport function formatReplacedFileNotes(replacedFiles: ReplacedFileNotice[] = []): string[] {\n if (replacedFiles.length === 0) {\n return [];\n }\n const currentUser = getCurrentUsername();\n return replacedFiles.map((replacedItem) => {\n const fileName = basename(replacedItem.filePath);\n const previousOwner = formatOwnerName(replacedItem.previousOwnerUid);\n return picocolors.yellow(\n `Note: ${fileName} was owned by ${previousOwner}. It was replaced atomically and is now owned by ${currentUser}.`\n );\n });\n}\n\nexport function renderInstallFailure(error: InstallTransactionError): void {\n const { stage, causeError, rollbackReport, suggestedFix } = error;\n const causeMessage = causeError instanceof Error ? causeError.message : String(causeError);\n const nothingTouched =\n rollbackReport.restoredFiles.length === 0 &&\n rollbackReport.removedFiles.length === 0 &&\n rollbackReport.removedDirs.length === 0 &&\n rollbackReport.failures.length === 0;\n\n const safeMaxWidth = Math.max(getTerminalWidth(80) - 10, 50);\n\n const lines: string[] = [\n wrapText(`${picocolors.bold(\"Failed stage:\")} ${picocolors.yellow(stage)}`, safeMaxWidth),\n wrapText(`${picocolors.bold(\"Cause:\")} ${picocolors.red(causeMessage)}`, safeMaxWidth),\n ];\n\n if (nothingTouched) {\n lines.push(`${picocolors.bold(\"Rollback:\")} Nothing to roll back, no files were modified.`);\n } else {\n lines.push(\n \"\",\n picocolors.bold(\"Rollback summary:\"),\n ` • Restored files: ${picocolors.cyan(String(rollbackReport.restoredFiles.length))}`,\n ` • Removed temporary files: ${picocolors.cyan(String(rollbackReport.removedFiles.length))}`,\n ` • Removed empty directories: ${picocolors.cyan(String(rollbackReport.removedDirs.length))}`\n );\n if (!rollbackReport.isClean) {\n lines.push(\"\", picocolors.red(\"Rollback was incomplete. These files may need manual review:\"));\n for (const failure of rollbackReport.failures) {\n lines.push(wrapText(` • ${failure.path} (${failure.reason})`, safeMaxWidth));\n }\n }\n }\n\n if (suggestedFix) {\n lines.push(wrapText(`${picocolors.bold(\"Suggested fix:\")} ${picocolors.green(suggestedFix)}`, safeMaxWidth));\n }\n\n prompts.note(lines.join(\"\\n\"), \"Installation Aborted\");\n\n if (!rollbackReport.isClean) {\n prompts.outro(\n picocolors.red(\n \"Rollback was incomplete. Please review the files listed above and apply the suggested fix.\"\n )\n );\n return;\n }\n\n prompts.outro(\n picocolors.yellow(\n nothingTouched\n ? \"No files were modified. Apply the suggested fix and try again.\"\n : \"Your project was restored to its previous state. Apply the suggested fix and try again.\"\n )\n );\n}\n"],"mappings":"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","names":["basename","userInfo","picocolors","existsSync","readFileSync","join","join","existsSync","readFileSync","prompts","picocolors","prompts","prompts","prompts","join","join","existsSync","lstatSync","readFileSync","rmSync","join","join","existsSync","existsSync","lstatSync","existsSync","existsSync","lstatSync","rmSync","readFileSync","join","existsSync","mkdirSync","rmSync","join","dirname","join","existsSync","existsSync","mkdirSync","join","rmSync","existsSync","mkdirSync","join","existsSync","readdirSync","readFileSync","join","existsSync","readFileSync","join","existsSync","readFileSync","join","existsSync","mkdirSync","join","existsSync","readFileSync","existsSync","readFileSync","existsSync","readdirSync","readFileSync","rmSync","existsSync","readFileSync","rmSync","readdirSync","join","join","join","picocolors","picocolors","basename","prompts","picocolors","basename","picocolors","picocolors","note","userInfo","basename","picocolors"]}
|
package/dist/cli.js
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import {
|
|
3
3
|
InstallTransactionError,
|
|
4
4
|
runGrooveSkills
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-KPDHH2AZ.js";
|
|
6
6
|
|
|
7
7
|
// bin/cli.ts
|
|
8
8
|
import { Command } from "commander";
|
|
9
9
|
import picocolors from "picocolors";
|
|
10
10
|
var program = new Command();
|
|
11
|
-
program.name("grooveskills").description("Multi-agent AI skills, ODD workflow, and persistent project harness installer").version("1.7.
|
|
11
|
+
program.name("grooveskills").description("Multi-agent AI skills, ODD workflow, and persistent project harness installer").version("1.7.2").argument("[command]", "Optional command: use 'init' to initialize or re-run full project onboarding").option("-s, --skills <skills...>", "Specific skill IDs to install (e.g. odd-ai best-practices hono)").option("-a, --agents <agents...>", "Target AI agents (antigravity claude cursor gemini)").option("-y, --yes", "Automatically confirm overwrite of existing skills", false).option("-l, --language <lang>", "Project user copy language (es, en, pt, it, fr)").action(async (command, options) => {
|
|
12
12
|
try {
|
|
13
13
|
const forceOnboarding = command === "init";
|
|
14
14
|
await runGrooveSkills({
|
package/dist/main.js
CHANGED
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/main.ts","../src/domains/detector/project-detector.ts","../src/domains/detector/detect-agents.ts","../src/domains/detector/detect-dependencies.ts","../src/domains/registry/skill-catalog.ts","../src/domains/ui/ui-orchestrator.ts","../src/domains/ui/banners.ts","../src/domains/ui/prompt-skills.ts","../src/domains/ui/prompt-agents.ts","../src/domains/ui/prompt-language.ts","../src/domains/ui/prompt-confirm-overwrite.ts","../src/domains/installer/verify-skill-exists.ts","../src/domains/installer/install-orchestrator.ts","../src/domains/adapters/skill-reference-builder.ts","../src/domains/project-store/project-paths.ts","../src/domains/fs/safe-file-writer.ts","../src/domains/fs/inspect-file-access.ts","../src/errors/file-permission-error.ts","../src/domains/adapters/antigravity.adapter.ts","../src/domains/adapters/claude.adapter.ts","../src/domains/adapters/cursor.adapter.ts","../src/domains/adapters/gemini.adapter.ts","../src/domains/project-store/sync-project-store.ts","../src/domains/installer/resolve-skills-source.ts","../src/domains/harness/install-harness.ts","../src/domains/harness/harness-languages.ts","../src/domains/harness/harness-templates.ts","../src/domains/harness/scan-project-onboarding.ts","../src/domains/harness/upsert-agent-instructions.ts","../src/domains/harness/write-project-config.ts","../src/domains/fs/install-transaction.ts","../src/domains/fs/preflight-write-check.ts","../src/errors/install-transaction-error.ts","../src/domains/ui/render-onboarding-prompt.ts","../src/domains/ui/render-install-report.ts"],"sourcesContent":["import { basename } from \"node:path\";\nimport { userInfo } from \"node:os\";\nimport picocolors from \"picocolors\";\nimport { detectProjectContext } from \"@/domains/detector/project-detector\";\nimport { runInteractiveUi } from \"@/domains/ui/ui-orchestrator\";\nimport { installSkills } from \"@/domains/installer/install-orchestrator\";\nimport { formatOnboardingPrompt } from \"@/domains/ui/render-onboarding-prompt\";\nimport { formatOwnerName } from \"@/domains/fs/inspect-file-access\";\nimport type { AgentId } from \"@/types/agent.types\";\nimport type { ProjectLanguage } from \"@/types/harness.types\";\n\nexport interface CliOptions {\n skills?: string[];\n agents?: AgentId[];\n yes?: boolean;\n harness?: boolean;\n language?: ProjectLanguage;\n forceOnboarding?: boolean;\n}\n\nfunction resolveUsername(): string {\n try {\n return userInfo().username;\n } catch {\n return process.env.USER || process.env.LOGNAME || \"current user\";\n }\n}\n\nexport async function runGrooveSkills(options: CliOptions = {}): Promise<void> {\n const targetPath = process.cwd();\n const context = detectProjectContext(targetPath);\n\n const hasSkills = options.skills && options.skills.length > 0;\n const hasAgents = options.agents && options.agents.length > 0;\n const isDirectHarness = Boolean(options.harness) && hasAgents;\n const isDirectInit = Boolean(options.forceOnboarding) && hasAgents;\n\n if ((hasSkills && hasAgents) || isDirectHarness || isDirectInit) {\n const language = options.language ?? context.configuredLanguage ?? \"es\";\n const result = await installSkills({\n targetPath,\n selectedSkillIds: options.skills || [],\n selectedAgents: options.agents || [],\n forceOverwrite: Boolean(options.yes),\n enableHarness: true,\n detectedDependencies: context.detectedDependencies,\n language,\n forceOnboarding: options.forceOnboarding,\n });\n\n if (result.replacedFiles && result.replacedFiles.length > 0) {\n const currentUser = resolveUsername();\n for (const replacedItem of result.replacedFiles) {\n const fileName = basename(replacedItem.filePath);\n const previousOwner = formatOwnerName(replacedItem.previousOwnerUid);\n console.log(\n picocolors.yellow(\n `Note: ${fileName} was owned by ${previousOwner}. It was replaced atomically and is now owned by ${currentUser}.`\n )\n );\n }\n }\n\n if (result.harnessInitialized) {\n const promptRender = formatOnboardingPrompt(language);\n console.log(`\\n${promptRender.formattedOutput}\\n`);\n }\n\n return;\n }\n\n await runInteractiveUi(context, Boolean(options.forceOnboarding));\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { detectAgents } from \"@/domains/detector/detect-agents\";\nimport { detectDependencies } from \"@/domains/detector/detect-dependencies\";\nimport { SKILL_CATALOG } from \"@/domains/registry/skill-catalog\";\nimport type { ProjectContext } from \"@/types/context.types\";\nimport type { GrooveSkillsConfig, ProjectLanguage } from \"@/types/harness.types\";\n\nfunction readConfiguredLanguage(targetPath: string): ProjectLanguage | undefined {\n const configPath = join(targetPath, \".grooveskills\", \"config.json\");\n if (!existsSync(configPath)) {\n return undefined;\n }\n\n try {\n const raw = readFileSync(configPath, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<GrooveSkillsConfig>;\n return typeof parsed.language === \"string\" ? (parsed.language as ProjectLanguage) : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function detectProjectContext(targetPath: string): ProjectContext {\n const detectedAgents = detectAgents(targetPath);\n const { dependencies, exists } = detectDependencies(targetPath);\n\n const suggestedSkillIds: string[] = [\n \"odd-ai\",\n \"best-practices\",\n \"ux-writing\",\n \"docs-standards\",\n \"error-handling-logging\",\n \"clean-architecture-ddd\",\n \"external-service-adapters\",\n \"storage-file-adapters\",\n \"auth-rbac-policies\",\n \"controller-orchestration-queues\",\n \"webhook-idempotency\",\n \"caching-rate-limiting\",\n \"env-feature-flags\",\n ];\n\n for (const skill of SKILL_CATALOG) {\n if (skill.dependencies.length === 0) {\n continue;\n }\n const hasMatch = skill.dependencies.some((dependencyName) =>\n dependencies.includes(dependencyName)\n );\n if (hasMatch && !suggestedSkillIds.includes(skill.id)) {\n suggestedSkillIds.push(skill.id);\n }\n }\n\n const harnessExists = existsSync(join(targetPath, \".grooveskills\", \"memory\", \"context.md\"));\n const configuredLanguage = readConfiguredLanguage(targetPath);\n\n return {\n targetPath,\n detectedDependencies: dependencies,\n suggestedSkillIds,\n detectedAgents,\n packageJsonExists: exists,\n harnessExists,\n configuredLanguage,\n };\n}\n","import { readdirSync } from \"node:fs\";\nimport type { AgentId } from \"@/types/agent.types\";\n\nexport function detectAgents(targetPath: string): AgentId[] {\n const detected: AgentId[] = [];\n\n try {\n const entries = new Set(readdirSync(targetPath));\n\n if (entries.has(\".agents\")) {\n detected.push(\"antigravity\");\n }\n if (entries.has(\".claude\")) {\n detected.push(\"claude\");\n }\n if (entries.has(\".cursor\")) {\n detected.push(\"cursor\");\n }\n if (entries.has(\".gemini\")) {\n detected.push(\"gemini\");\n }\n } catch {\n // If directory cannot be read, return empty list gracefully\n }\n\n return detected;\n}\n","import { readFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport interface PackageJsonDetection {\n dependencies: string[];\n exists: boolean;\n}\n\nexport function detectDependencies(targetPath: string): PackageJsonDetection {\n const detected = new Set<string>();\n let hasManifest = false;\n\n const packageJsonPath = join(targetPath, \"package.json\");\n if (existsSync(packageJsonPath)) {\n hasManifest = true;\n try {\n const raw = readFileSync(packageJsonPath, \"utf-8\");\n const parsed = JSON.parse(raw) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n\n for (const dependencyName of Object.keys(parsed.dependencies ?? {})) {\n detected.add(dependencyName);\n }\n for (const dependencyName of Object.keys(parsed.devDependencies ?? {})) {\n detected.add(dependencyName);\n }\n } catch {\n // Ignore JSON parse errors gracefully\n }\n }\n\n const cargoPath = join(targetPath, \"Cargo.toml\");\n if (existsSync(cargoPath)) {\n hasManifest = true;\n detected.add(\"rust\");\n }\n\n const pyprojectPath = join(targetPath, \"pyproject.toml\");\n const requirementsPath = join(targetPath, \"requirements.txt\");\n if (existsSync(pyprojectPath) || existsSync(requirementsPath)) {\n hasManifest = true;\n detected.add(\"python\");\n }\n\n return {\n dependencies: Array.from(detected),\n exists: hasManifest,\n };\n}\n","import type { SkillMetadata } from \"@/types/skill.types\";\n\nexport const SKILL_CATALOG: SkillMetadata[] = [\n {\n id: \"groove-harness\",\n name: \"GrooveSkills Harness\",\n description: \"Lightweight project harness, context memory, and ODD 3-lane task execution (Answer, Task, Spec) for AI coding agents\",\n dependencies: [],\n directoryName: \"groove-harness\",\n isCoreHarness: true,\n },\n {\n id: \"odd-ai\",\n name: \"Organic & Outcome-Driven Development (ODD)\",\n description: \"7-step ODD protocol for AI agents: authorize, explore, classify, outcome hypotheses, and verifiable evidence receipts\",\n dependencies: [],\n directoryName: \"odd-ai\",\n },\n {\n id: \"best-practices\",\n name: \"Universal Best Practices\",\n description: \"Multi-language clean code standards, early returns, no barrel files, strict typing, <200 lines\",\n dependencies: [],\n directoryName: \"best-practices\",\n },\n {\n id: \"ux-writing\",\n name: \"UX Writing & Microcopy Standards\",\n description: \"Persuasive, empathetic, professional bilingual microcopy (ES/EN) for error messages, forms, CTAs, toasts, and empty states\",\n dependencies: [],\n directoryName: \"ux-writing\",\n },\n {\n id: \"docs-standards\",\n name: \"Documentation & ADR Standards\",\n description: \"English documentation standard, relative POSIX links, resilient Mermaid diagrams, ADR lifecycle, and intent-focused docstrings\",\n dependencies: [],\n directoryName: \"docs-standards\",\n },\n {\n id: \"typescript-clean\",\n name: \"TypeScript Clean Code (TS 5.5+)\",\n description: \"Advanced strict TypeScript, discriminated unions, satisfies, const generics, unknown over any, and zero unsafe casts\",\n dependencies: [\"typescript\"],\n directoryName: \"typescript-clean\",\n },\n {\n id: \"rust-clean\",\n name: \"Rust Clean Code (Rust 2024)\",\n description: \"Idiomatic Rust clean code: let-else guard clauses, no unwrap in production, thiserror typed errors, Newtypes, zero barrel files, <200 lines\",\n dependencies: [\"rust\"],\n directoryName: \"rust-clean\",\n },\n {\n id: \"python-clean\",\n name: \"Python Clean Code (Python 3.12+)\",\n description: \"Modern Python standards: guard clauses (no nested ifs), strict typing (zero Any), uv, Ruff, Pyright, Pydantic v2 boundaries, <200 lines\",\n dependencies: [\"python\"],\n directoryName: \"python-clean\",\n },\n {\n id: \"error-handling-logging\",\n name: \"Error Handling & Structured Logging\",\n description: \"Deterministic error management with AppError, Result/ActionResponse contracts, and structured context logging\",\n dependencies: [],\n directoryName: \"error-handling-logging\",\n },\n {\n id: \"valibot-validation\",\n name: \"Valibot Schema Validation\",\n description: \"Boundary schema validation with Valibot (* as v from 'valibot'), strict type inference, and friendly error messages\",\n dependencies: [\"valibot\"],\n directoryName: \"valibot-validation\",\n },\n {\n id: \"clean-architecture-ddd\",\n name: \"Clean Architecture & DDD\",\n description: \"Domain-driven design, isolated single-purpose Actions, pure functions, immutability, zero barrel files, <200 lines per file\",\n dependencies: [],\n directoryName: \"clean-architecture-ddd\",\n },\n {\n id: \"external-service-adapters\",\n name: \"External Service Adapters & Wrappers\",\n description: \"Standardized adapter and wrapper architecture for external services (payment gateways, emails, SMS, cloud storage)\",\n dependencies: [],\n directoryName: \"external-service-adapters\",\n },\n {\n id: \"storage-file-adapters\",\n name: \"Storage & File Adapters (S3, R2, Supabase)\",\n description: \"Standardized wrapper & adapter architecture for object storage, uploads, presigned URLs, and streaming without repositories\",\n dependencies: [],\n directoryName: \"storage-file-adapters\",\n },\n {\n id: \"auth-rbac-policies\",\n name: \"Auth Adapters & RBAC/ABAC Policies\",\n description: \"Authentication adapter architecture and pure domain authorization policies (RBAC/ABAC) with AuthenticatedActor contract\",\n dependencies: [],\n directoryName: \"auth-rbac-policies\",\n },\n {\n id: \"controller-orchestration-queues\",\n name: \"Controller Orchestration & Queue Adapters\",\n description: \"Strict orchestration rules for Controllers, atomic Actions, DB Transactions, and background Queue Adapters (Cloudflare, BullMQ, SQS)\",\n dependencies: [],\n directoryName: \"controller-orchestration-queues\",\n },\n {\n id: \"webhook-idempotency\",\n name: \"Webhook Verifiers & Idempotency Guards\",\n description: \"Incoming webhook HMAC verification adapters and atomic idempotency guards guaranteeing at-most-once processing\",\n dependencies: [],\n directoryName: \"webhook-idempotency\",\n },\n {\n id: \"caching-rate-limiting\",\n name: \"Cache-Aside & Rate Limiting Adapters\",\n description: \"Cache-aside remember wrapper and interchangeable sliding-window rate limiter adapters (Redis, Cloudflare KV, In-Memory)\",\n dependencies: [],\n directoryName: \"caching-rate-limiting\",\n },\n {\n id: \"env-feature-flags\",\n name: \"Fail-Fast Env & Feature Flags Adapters\",\n description: \"Fail-fast environment schema validation with Valibot and decoupled feature flags adapters (PostHog, LaunchDarkly, Unleash)\",\n dependencies: [],\n directoryName: \"env-feature-flags\",\n },\n {\n id: \"testing-vitest\",\n name: \"Vitest Testing Standards\",\n description: \"Clean unit and integration testing with Vitest: AAA pattern, behavioral testing over mocks, and boundary edge cases\",\n dependencies: [\"vitest\"],\n directoryName: \"testing-vitest\",\n },\n {\n id: \"hono\",\n name: \"Hono Architecture (Valibot)\",\n description: \"Enterprise Hono API standard with Valibot validation, isolated Actions layer, and RPC bindings\",\n dependencies: [\"hono\", \"@hono/valibot-validator\", \"@hono/standard-validator\"],\n directoryName: \"hono\",\n },\n {\n id: \"react-core\",\n name: \"React Core Fundamentals\",\n description: \"Opinionated React fundamentals: function components, JSX, immutable state, core hooks, lists, and controlled inputs\",\n dependencies: [\"react\", \"react-dom\"],\n directoryName: \"react-core\",\n },\n {\n id: \"react-advanced\",\n name: \"React 19 Advanced & Compiler Architecture\",\n description: \"Modern React 19 platform features: React Compiler auto-memoization, concurrent rendering, use(), Actions, virtualization, and RSC boundaries\",\n dependencies: [\"react\", \"react-dom\"],\n directoryName: \"react-advanced\",\n },\n {\n id: \"react-create-page\",\n name: \"React Page & View Architecture\",\n description: \"Clean architecture for React pages: declarative page coordinators, domain hooks, isolated API actions, Valibot + Formisch forms, and atomic co-location\",\n dependencies: [\"react\", \"react-dom\"],\n directoryName: \"react-create-page\",\n },\n];\n","import * as prompts from \"@clack/prompts\";\nimport picocolors from \"picocolors\";\nimport { renderBanner } from \"@/domains/ui/banners\";\nimport { promptSkills } from \"@/domains/ui/prompt-skills\";\nimport { promptAgents } from \"@/domains/ui/prompt-agents\";\nimport { promptLanguage } from \"@/domains/ui/prompt-language\";\nimport { promptConfirmOverwrite } from \"@/domains/ui/prompt-confirm-overwrite\";\nimport { verifySkillExists } from \"@/domains/installer/verify-skill-exists\";\nimport { installSkills } from \"@/domains/installer/install-orchestrator\";\nimport { SKILL_CATALOG } from \"@/domains/registry/skill-catalog\";\nimport { formatOnboardingPrompt } from \"@/domains/ui/render-onboarding-prompt\";\nimport { formatReplacedFileNotes, renderInstallFailure } from \"@/domains/ui/render-install-report\";\nimport { InstallTransactionError } from \"@/errors/install-transaction-error\";\nimport type { ProjectContext } from \"@/types/context.types\";\nimport type { AgentId } from \"@/types/agent.types\";\nimport type { ProjectLanguage } from \"@/types/harness.types\";\n\nasync function resolveLanguageSelection(\n harnessExists: boolean,\n configuredLanguage?: ProjectLanguage,\n forceOnboarding?: boolean\n): Promise<ProjectLanguage> {\n if (harnessExists && !forceOnboarding) {\n return configuredLanguage ?? \"es\";\n }\n\n const languageSelection = await promptLanguage(configuredLanguage ?? \"es\");\n if (prompts.isCancel(languageSelection)) {\n prompts.cancel(\"Installation cancelled. Have a wonderful day!\");\n process.exit(0);\n }\n\n return languageSelection as ProjectLanguage;\n}\n\nasync function resolveOverwriteConfirmation(\n targetPath: string,\n selectedSkills: string[],\n selectedAgents: AgentId[]\n): Promise<boolean> {\n const anyExists = selectedSkills.some((skillId) => {\n const skillMetadata = SKILL_CATALOG.find((skill) => skill.id === skillId);\n return skillMetadata\n ? verifySkillExists(targetPath, skillMetadata.directoryName, selectedAgents)\n : false;\n });\n\n if (!anyExists) {\n return true;\n }\n\n const overwriteConfirmed = await promptConfirmOverwrite();\n if (prompts.isCancel(overwriteConfirmed) || !overwriteConfirmed) {\n prompts.cancel(\"Installation stopped to protect existing skills.\");\n process.exit(0);\n }\n\n return Boolean(overwriteConfirmed);\n}\n\nexport async function runInteractiveUi(\n context: ProjectContext,\n forceOnboarding: boolean = false\n): Promise<void> {\n console.log(renderBanner());\n prompts.intro(\n picocolors.magenta(\n \"Welcome to GrooveSkills! Let's tailor your AI agents with clean architectural standards.\"\n )\n );\n\n if (context.detectedDependencies.length > 0) {\n const harnessInfo =\n context.harnessExists && !forceOnboarding\n ? picocolors.green(\n `Active (.grooveskills/memory, lang: ${context.configuredLanguage ?? \"es\"})`\n )\n : picocolors.cyan(\"Will be initialized\");\n\n const formattedDependencies = context.detectedDependencies\n .map((dependencyName) => picocolors.bold(dependencyName))\n .join(\", \");\n const formattedAgents =\n context.detectedAgents.map((agentName) => picocolors.green(agentName)).join(\", \") ||\n \"None (will be created)\";\n\n prompts.note(\n `Detected dependencies: ${formattedDependencies}\\n` +\n `Active AI folders: ${formattedAgents}\\n` +\n `GrooveSkills Harness: ${harnessInfo}`,\n \"Project Environment\"\n );\n }\n\n const selectedSkills = await promptSkills(context.suggestedSkillIds);\n if (prompts.isCancel(selectedSkills)) {\n prompts.cancel(\"Installation cancelled. Have a wonderful day!\");\n process.exit(0);\n }\n\n const selectedAgents = await promptAgents(context.detectedAgents);\n if (prompts.isCancel(selectedAgents)) {\n prompts.cancel(\"Installation cancelled. Have a wonderful day!\");\n process.exit(0);\n }\n\n const selectedLanguage = await resolveLanguageSelection(\n context.harnessExists,\n context.configuredLanguage,\n forceOnboarding\n );\n\n const forceOverwrite = await resolveOverwriteConfirmation(\n context.targetPath,\n selectedSkills as string[],\n selectedAgents as AgentId[]\n );\n\n const installSpinner = prompts.spinner();\n installSpinner.start(\"Installing and adapting skills across your configured AI agents...\");\n\n try {\n const installResult = await installSkills({\n targetPath: context.targetPath,\n selectedSkillIds: selectedSkills as string[],\n selectedAgents: selectedAgents as AgentId[],\n forceOverwrite,\n enableHarness: true,\n detectedDependencies: context.detectedDependencies,\n language: selectedLanguage,\n forceOnboarding,\n });\n\n installSpinner.stop(\n picocolors.green(\"All skills and harness have been successfully configured!\")\n );\n\n const harnessStatus = installResult.harnessInitialized\n ? picocolors.green(`Initialized in .grooveskills/ (Language: ${selectedLanguage})`)\n : picocolors.cyan(`Preserved in .grooveskills/ (Language: ${selectedLanguage})`);\n\n const formattedInstalledSkills = installResult.installedSkills\n .map((skillId) => picocolors.bold(skillId))\n .join(\", \");\n const formattedConfiguredAgents = installResult.configuredAgents\n .map((agentId) => picocolors.cyan(agentId))\n .join(\", \");\n\n const summaryLines = [\n `Configured skills: ${formattedInstalledSkills}`,\n `Target agents: ${formattedConfiguredAgents}`,\n `GrooveSkills Harness: ${harnessStatus}`,\n ...formatReplacedFileNotes(installResult.replacedFiles),\n ];\n\n prompts.note(summaryLines.join(\"\\n\"), \"Installation Summary\");\n\n if (installResult.harnessInitialized) {\n const promptRender = formatOnboardingPrompt(selectedLanguage);\n prompts.note(picocolors.green(promptRender.prompt), promptRender.title);\n }\n\n prompts.outro(\n picocolors.green(\n \"Your AI programming pair is now empowered with your team's architectural habits! 🚀\"\n )\n );\n } catch (error) {\n installSpinner.stop(picocolors.yellow(\"Installation could not be completed.\"));\n\n if (error instanceof InstallTransactionError) {\n renderInstallFailure(error);\n return;\n }\n\n throw error;\n }\n}\n","import picocolors from \"picocolors\";\n\nexport function renderBanner(): string {\n const title = picocolors.bold(picocolors.white(\" GROOVE SKILLS \"));\n const badge = picocolors.bgMagenta(picocolors.black(title));\n const subtitle = picocolors.dim(\"Multi-Agent AI Skills & Architectural Standards\");\n\n return `${badge} ${subtitle}\\n`;\n}\n","import * as prompts from \"@clack/prompts\";\nimport { SKILL_CATALOG } from \"@/domains/registry/skill-catalog\";\n\nexport async function promptSkills(suggestedSkillIds: string[]): Promise<string[] | symbol> {\n const selectableSkills = SKILL_CATALOG.filter((skill) => !skill.isCoreHarness);\n const options = selectableSkills.map((skill) => {\n const isSuggested = suggestedSkillIds.includes(skill.id);\n return {\n value: skill.id,\n label: skill.name,\n hint: isSuggested ? \"Suggested based on your project stack\" : skill.description,\n };\n });\n\n const selected = await prompts.multiselect({\n message: \"Which skills would you like to install in this project?\",\n options,\n initialValues: suggestedSkillIds,\n required: true,\n });\n\n return selected;\n}\n","import * as prompts from \"@clack/prompts\";\nimport type { AgentId } from \"@/types/agent.types\";\n\nexport async function promptAgents(detectedAgents: AgentId[]): Promise<AgentId[] | symbol> {\n const options: Array<{ value: AgentId; label: string; hint: string }> = [\n { value: \"antigravity\", label: \"Antigravity\", hint: \".agents/skills (Google Agentic IDE)\" },\n { value: \"claude\", label: \"Claude Code\", hint: \".claude/skills (Anthropic Claude Code)\" },\n { value: \"cursor\", label: \"Cursor\", hint: \".cursor/rules/*.mdc (Cursor IDE Rules)\" },\n { value: \"gemini\", label: \"Gemini Code Assist\", hint: \".gemini/skills (Google Gemini)\" },\n ];\n\n const initialValues: AgentId[] = detectedAgents.length > 0 ? detectedAgents : [\"antigravity\"];\n\n const selected = await prompts.multiselect({\n message: \"Which AI agents should be configured?\",\n options,\n initialValues,\n required: true,\n });\n\n return selected as AgentId[] | symbol;\n}\n","import * as prompts from \"@clack/prompts\";\nimport type { ProjectLanguage } from \"@/types/harness.types\";\n\nexport async function promptLanguage(\n defaultLanguage: ProjectLanguage = \"es\"\n): Promise<ProjectLanguage | symbol> {\n const options = [\n { value: \"es\", label: \"Español (Spanish)\", hint: \"Recommended for Spanish-speaking projects\" },\n { value: \"en\", label: \"English\", hint: \"Standard international English\" },\n { value: \"pt\", label: \"Português (Portuguese)\", hint: \"Portuguese for Brazil and Portugal\" },\n { value: \"it\", label: \"Italiano (Italian)\", hint: \"Italian language communication\" },\n { value: \"fr\", label: \"Français (French)\", hint: \"French language communication\" },\n ];\n\n const selected = await prompts.select({\n message: \"Which language should AI agents use for user-facing copy and communication?\",\n options,\n initialValue: defaultLanguage,\n });\n\n return selected as ProjectLanguage | symbol;\n}\n","import * as prompts from \"@clack/prompts\";\n\nexport async function promptConfirmOverwrite(): Promise<boolean | symbol> {\n return await prompts.confirm({\n message:\n \"Some skills already exist in this project. Would you like to overwrite them with the latest version?\",\n initialValue: true,\n });\n}\n","import { lstatSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { AgentId } from \"@/types/agent.types\";\n\nconst AGENT_DESTINATION_MAP: Record<AgentId, (directoryName: string) => string> = {\n antigravity: (directoryName) => join(\".agents\", \"skills\", directoryName),\n claude: (directoryName) => join(\".claude\", \"skills\", directoryName),\n cursor: (directoryName) => join(\".cursor\", \"rules\", `${directoryName}.mdc`),\n gemini: (directoryName) => join(\".gemini\", \"skills\", directoryName),\n};\n\nexport function verifySkillExists(\n targetPath: string,\n skillDirectoryName: string,\n agents: AgentId[]\n): boolean {\n for (const agent of agents) {\n const relativePathResolver = AGENT_DESTINATION_MAP[agent];\n const destination = join(targetPath, relativePathResolver(skillDirectoryName));\n\n try {\n lstatSync(destination);\n return true;\n } catch {\n // Path does not exist\n }\n }\n\n return false;\n}\n","import { join } from \"node:path\";\nimport { AntigravityAdapter } from \"@/domains/adapters/antigravity.adapter\";\nimport { ClaudeAdapter } from \"@/domains/adapters/claude.adapter\";\nimport { CursorAdapter } from \"@/domains/adapters/cursor.adapter\";\nimport { GeminiAdapter } from \"@/domains/adapters/gemini.adapter\";\nimport { syncProjectStore } from \"@/domains/project-store/sync-project-store\";\nimport { getProjectSkillsDir } from \"@/domains/project-store/project-paths\";\nimport { installHarness } from \"@/domains/harness/install-harness\";\nimport { writeProjectConfig } from \"@/domains/harness/write-project-config\";\nimport { SKILL_CATALOG } from \"@/domains/registry/skill-catalog\";\nimport { InstallTransaction } from \"@/domains/fs/install-transaction\";\nimport { runPreflightWriteCheck } from \"@/domains/fs/preflight-write-check\";\nimport { InstallTransactionError } from \"@/errors/install-transaction-error\";\nimport { FilePermissionError } from \"@/errors/file-permission-error\";\nimport type { AgentAdapter } from \"@/domains/adapters/adapter.interface\";\nimport type { InstallOptions, InstallResult } from \"@/types/installer.types\";\nimport type { AgentId } from \"@/types/agent.types\";\n\nconst ADAPTER_REGISTRY: Record<AgentId, AgentAdapter> = {\n antigravity: new AntigravityAdapter(),\n claude: new ClaudeAdapter(),\n cursor: new CursorAdapter(),\n gemini: new GeminiAdapter(),\n};\n\nfunction formatSuggestedFix(cause: unknown): string | undefined {\n if (cause instanceof FilePermissionError) {\n return cause.suggestedFixCommand;\n }\n const nodeError = cause as NodeJS.ErrnoException;\n if (nodeError?.code === \"EACCES\" || nodeError?.code === \"EPERM\") {\n if (nodeError.path) {\n return `chmod u+w \"${nodeError.path}\"`;\n }\n }\n return undefined;\n}\n\nexport async function installSkills(options: InstallOptions): Promise<InstallResult> {\n const transaction = new InstallTransaction();\n const skillsToInstall = [...options.selectedSkillIds];\n\n if (!skillsToInstall.includes(\"groove-harness\")) {\n skillsToInstall.push(\"groove-harness\");\n }\n\n if (!skillsToInstall.includes(\"odd-ai\")) {\n skillsToInstall.push(\"odd-ai\");\n }\n\n let currentStage = \"Preflight check\";\n try {\n runPreflightWriteCheck({\n targetPath: options.targetPath,\n selectedAgents: options.selectedAgents,\n });\n\n currentStage = \"Syncing skills store (.grooveskills/skills)\";\n syncProjectStore(options.targetPath, skillsToInstall, options.selectedAgents, transaction);\n\n const projectSkillsDir = getProjectSkillsDir(options.targetPath);\n const createdFiles: string[] = [];\n\n currentStage = \"Configuring agent references (.agents, .claude, etc.)\";\n for (const skillId of skillsToInstall) {\n const skill = SKILL_CATALOG.find((catalogItem) => catalogItem.id === skillId);\n if (!skill) {\n continue;\n }\n\n const skillSourceDir = join(projectSkillsDir, skill.directoryName);\n\n for (const agentId of options.selectedAgents) {\n const adapter = ADAPTER_REGISTRY[agentId];\n if (!adapter) {\n continue;\n }\n\n const files = await adapter.installSkill(\n options.targetPath,\n skill,\n skillSourceDir,\n transaction\n );\n createdFiles.push(...files);\n }\n }\n\n currentStage = \"Installing Groove Harness (context, decisions, tasks, and instructions)\";\n const harnessResult = installHarness({\n targetPath: options.targetPath,\n selectedAgents: options.selectedAgents,\n selectedSkillIds: skillsToInstall,\n detectedDependencies: options.detectedDependencies || [],\n language: options.language,\n forceOnboarding: options.forceOnboarding,\n transaction,\n });\n createdFiles.push(...harnessResult.createdFiles);\n\n currentStage = \"Persisting project configuration (.grooveskills/config.json)\";\n const configPath = writeProjectConfig(\n options.targetPath,\n skillsToInstall,\n options.selectedAgents,\n true,\n options.language,\n transaction\n );\n createdFiles.push(configPath);\n\n return {\n installedSkills: skillsToInstall,\n configuredAgents: options.selectedAgents,\n createdFiles,\n harnessInitialized: harnessResult.onboardingInitialized,\n language: options.language,\n replacedFiles: transaction.getReplacedFiles(),\n };\n } catch (cause) {\n const rollbackReport = transaction.rollback();\n const suggestedFix = formatSuggestedFix(cause);\n throw new InstallTransactionError({\n stage: currentStage,\n cause,\n rollbackReport,\n suggestedFix,\n });\n }\n}\n","import { existsSync, lstatSync, mkdirSync, readFileSync, rmSync, unlinkSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getProjectSkillsDir } from \"@/domains/project-store/project-paths\";\nimport { safeWriteFileSync } from \"@/domains/fs/safe-file-writer\";\nimport type { InstallTransaction } from \"@/domains/fs/install-transaction\";\nimport type { SkillMetadata } from \"@/types/skill.types\";\n\nfunction removeExistingPathSafely(path: string): void {\n const fileExists = existsSync(path);\n\n if (!fileExists) {\n try {\n const lstat = lstatSync(path);\n if (lstat.isSymbolicLink()) {\n unlinkSync(path);\n }\n } catch {\n // Ignored if file really does not exist\n }\n return;\n }\n\n try {\n const lstat = lstatSync(path);\n if (lstat.isSymbolicLink()) {\n unlinkSync(path);\n return;\n }\n\n if (lstat.isDirectory()) {\n rmSync(path, { recursive: true, force: true });\n return;\n }\n\n unlinkSync(path);\n } catch {\n // Graceful fallback\n }\n}\n\nfunction extractSkillDescription(canonicalSkillMdPath: string, fallback: string): string {\n if (!existsSync(canonicalSkillMdPath)) {\n return fallback;\n }\n\n try {\n const content = readFileSync(canonicalSkillMdPath, \"utf-8\");\n const match = content.match(/^description:\\s*(.+)$/m);\n const hasMatchedDesc = Boolean(match && match[1]);\n if (hasMatchedDesc && match?.[1]) {\n return match[1].trim();\n }\n } catch {\n // Use fallback on error\n }\n\n return fallback;\n}\n\nexport function writeAgentSkillReference(\n targetPath: string,\n agentRelativeSkillsDir: string,\n skill: SkillMetadata,\n transaction?: InstallTransaction\n): string {\n const agentSkillFolder = join(targetPath, agentRelativeSkillsDir, skill.directoryName);\n const targetFile = join(agentSkillFolder, \"SKILL.md\");\n if (transaction) {\n transaction.recordCreatedDir(join(targetPath, agentRelativeSkillsDir));\n transaction.recordCreatedDir(agentSkillFolder);\n transaction.recordBeforeWrite(targetFile);\n }\n\n removeExistingPathSafely(agentSkillFolder);\n\n mkdirSync(agentSkillFolder, { recursive: true });\n\n const canonicalSkillMd = join(getProjectSkillsDir(targetPath), skill.directoryName, \"SKILL.md\");\n const description = extractSkillDescription(canonicalSkillMd, skill.description);\n\n const referenceContent = `---\nname: ${skill.id}\ndescription: ${description}\n---\n\n# ${skill.name} — Skill Reference\n\nCanonical skill specification stored in \\`.grooveskills/\\`.\n\n- **Specification**: [\\`.grooveskills/skills/${skill.directoryName}/SKILL.md\\`](../../../.grooveskills/skills/${skill.directoryName}/SKILL.md)\n- **References & Templates**: \\`.grooveskills/skills/${skill.directoryName}/\\`\n\n> **Instruction**: Read \\`.grooveskills/skills/${skill.directoryName}/SKILL.md\\` before executing tasks matching this skill.\n`;\n\n safeWriteFileSync(targetFile, referenceContent);\n\n return targetFile;\n}\n\nexport function writeCursorRuleReference(\n targetPath: string,\n cursorRelativeRulesDir: string,\n skill: SkillMetadata,\n transaction?: InstallTransaction\n): string {\n const rulesDir = join(targetPath, cursorRelativeRulesDir);\n const targetFile = join(rulesDir, `${skill.id}.mdc`);\n if (transaction) {\n transaction.recordCreatedDir(rulesDir);\n transaction.recordBeforeWrite(targetFile);\n }\n if (!existsSync(rulesDir)) {\n mkdirSync(rulesDir, { recursive: true });\n }\n\n removeExistingPathSafely(targetFile);\n\n const canonicalSkillMd = join(getProjectSkillsDir(targetPath), skill.directoryName, \"SKILL.md\");\n const description = extractSkillDescription(canonicalSkillMd, skill.description);\n\n const referenceContent = `---\ndescription: ${description}\nglobs: [\"**/*\"]\nalwaysApply: false\n---\n\n# ${skill.name} — Rule Reference\n\nCanonical rule specification stored in \\`.grooveskills/\\`.\n\n- **Specification**: \\`.grooveskills/skills/${skill.directoryName}/SKILL.md\\`\n- **References & Templates**: \\`.grooveskills/skills/${skill.directoryName}/\\`\n\n> **Instruction**: Read \\`.grooveskills/skills/${skill.directoryName}/SKILL.md\\` before executing tasks matching this rule.\n`;\n\n safeWriteFileSync(targetFile, referenceContent);\n\n return targetFile;\n}\n","import { join } from \"node:path\";\n\nexport function getProjectStoreDir(targetPath: string): string {\n return join(targetPath, \".grooveskills\");\n}\n\nexport function getProjectSkillsDir(targetPath: string): string {\n return join(getProjectStoreDir(targetPath), \"skills\");\n}\n\nexport function getProjectMemoryDir(targetPath: string): string {\n return join(getProjectStoreDir(targetPath), \"memory\");\n}\n\nexport function getProjectTasksDir(targetPath: string): string {\n return join(getProjectMemoryDir(targetPath), \"tasks\");\n}\n\nexport function getProjectConfigPath(targetPath: string): string {\n return join(getProjectStoreDir(targetPath), \"config.json\");\n}\n","import { chmodSync, existsSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { inspectFileAccess } from \"@/domains/fs/inspect-file-access\";\nimport { FilePermissionError } from \"@/errors/file-permission-error\";\n\nexport type WriteStrategyOutcome = \"direct\" | \"chmod\" | \"replaced\";\n\nexport interface WriteOutcome {\n strategy: WriteStrategyOutcome;\n previousOwnerUid: number | null;\n}\n\nexport interface SafeWriteOptions {\n chmodImpl?: (path: string, mode: number) => void;\n}\n\nexport function safeWriteFileSync(\n filePath: string,\n content: string,\n options?: SafeWriteOptions\n): WriteOutcome {\n const chmodFunction = options?.chmodImpl ?? chmodSync;\n\n try {\n writeFileSync(filePath, content, \"utf-8\");\n return { strategy: \"direct\", previousOwnerUid: null };\n } catch (error: unknown) {\n const nodeError = error as NodeJS.ErrnoException;\n if (nodeError.code !== \"EACCES\" && nodeError.code !== \"EPERM\") {\n throw error;\n }\n }\n\n const diagnosis = inspectFileAccess(filePath);\n\n if (diagnosis.exists && diagnosis.ownedByCurrentUser && !diagnosis.immutableFlag) {\n try {\n const targetMode = (diagnosis.mode ?? 0o644) | 0o200;\n chmodFunction(filePath, targetMode);\n writeFileSync(filePath, content, \"utf-8\");\n return { strategy: \"chmod\", previousOwnerUid: diagnosis.ownerUid };\n } catch {\n // Fall through to atomic replacement strategy\n }\n }\n\n if (diagnosis.exists && diagnosis.dirWritable && !diagnosis.immutableFlag) {\n const tempPath = `${filePath}.groove-tmp-${process.pid}-${Date.now()}`;\n try {\n const preservedMode = (diagnosis.mode ?? 0o644) | 0o200;\n writeFileSync(tempPath, content, { encoding: \"utf-8\", mode: preservedMode });\n renameSync(tempPath, filePath);\n return { strategy: \"replaced\", previousOwnerUid: diagnosis.ownerUid };\n } catch {\n if (existsSync(tempPath)) {\n try {\n rmSync(tempPath, { force: true });\n } catch {\n // Ignore cleanup failure\n }\n }\n }\n }\n\n throw new FilePermissionError(filePath, diagnosis);\n}\n","import { execFileSync } from \"node:child_process\";\nimport { accessSync, constants, existsSync, lstatSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nconst UF_IMMUTABLE = 0x00000002;\nconst SF_IMMUTABLE = 0x00020000;\n\nexport interface FileAccessDiagnosis {\n filePath: string;\n exists: boolean;\n isSymlink: boolean;\n ownedByCurrentUser: boolean;\n ownerUid: number | null;\n currentUid: number | null;\n mode: number | null;\n immutableFlag: boolean;\n dirWritable: boolean;\n parentDir: string;\n}\n\nfunction resolveNearestExistingDir(startDir: string): string {\n let current = startDir;\n while (!existsSync(current)) {\n const parent = dirname(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n return current;\n}\n\nfunction detectMacOsImmutableFlag(filePath: string, lstat: ReturnType<typeof lstatSync>): boolean {\n const rawFlags = (lstat as unknown as { flags?: number }).flags;\n if (typeof rawFlags === \"number\") {\n return Boolean(rawFlags & (UF_IMMUTABLE | SF_IMMUTABLE));\n }\n\n if (process.platform !== \"darwin\") {\n return false;\n }\n\n try {\n const out = execFileSync(\"stat\", [\"-f\", \"%f\", filePath], {\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n const parsedFlags = Number.parseInt(out, 10);\n if (Number.isNaN(parsedFlags)) {\n return false;\n }\n return Boolean(parsedFlags & (UF_IMMUTABLE | SF_IMMUTABLE));\n } catch {\n return false;\n }\n}\n\nexport function inspectFileAccess(filePath: string): FileAccessDiagnosis {\n const currentUid = typeof process.getuid === \"function\" ? process.getuid() : null;\n const parentDir = dirname(filePath);\n const checkDir = resolveNearestExistingDir(parentDir);\n\n let dirWritable = false;\n try {\n accessSync(checkDir, constants.W_OK);\n dirWritable = true;\n } catch {\n dirWritable = false;\n }\n\n let lstat: ReturnType<typeof lstatSync> | null = null;\n try {\n lstat = lstatSync(filePath);\n } catch {\n lstat = null;\n }\n\n if (!lstat) {\n return {\n filePath,\n exists: false,\n isSymlink: false,\n ownedByCurrentUser: true,\n ownerUid: null,\n currentUid,\n mode: null,\n immutableFlag: false,\n dirWritable,\n parentDir,\n };\n }\n\n const isSymlink = lstat.isSymbolicLink();\n const ownerUid = lstat.uid;\n const ownedByCurrentUser = currentUid === null || ownerUid === currentUid;\n const mode = lstat.mode & 0o777;\n const immutableFlag = detectMacOsImmutableFlag(filePath, lstat);\n\n return {\n filePath,\n exists: true,\n isSymlink,\n ownedByCurrentUser,\n ownerUid,\n currentUid,\n mode,\n immutableFlag,\n dirWritable,\n parentDir,\n };\n}\n\nexport function formatOwnerName(uid: number | null): string {\n if (uid === 0) {\n return \"root\";\n }\n if (uid === null) {\n return \"another user\";\n }\n return `uid ${uid}`;\n}\n","import {\n formatOwnerName,\n inspectFileAccess,\n type FileAccessDiagnosis,\n} from \"@/domains/fs/inspect-file-access\";\n\nfunction buildDiagnosisReason(diagnosis: FileAccessDiagnosis): string {\n if (diagnosis.immutableFlag) {\n return \"immutable flag (uchg) is set\";\n }\n if (diagnosis.exists && !diagnosis.ownedByCurrentUser) {\n return `owned by ${formatOwnerName(diagnosis.ownerUid)}`;\n }\n if (!diagnosis.dirWritable) {\n return `parent directory '${diagnosis.parentDir}' is not writable`;\n }\n return \"permission denied\";\n}\n\nfunction buildSuggestedFix(diagnosis: FileAccessDiagnosis): string {\n if (diagnosis.immutableFlag) {\n return `chflags nouchg \"${diagnosis.filePath}\"`;\n }\n if (diagnosis.exists && !diagnosis.ownedByCurrentUser) {\n return `sudo chown \"$(id -un)\" \"${diagnosis.filePath}\"`;\n }\n if (!diagnosis.dirWritable) {\n return `chmod u+w \"${diagnosis.parentDir}\"`;\n }\n return `chmod u+w \"${diagnosis.filePath}\"`;\n}\n\nexport class FilePermissionError extends Error {\n readonly code = \"EACCES\";\n readonly filePath: string;\n readonly diagnosis: FileAccessDiagnosis;\n readonly suggestedFixCommand: string;\n\n constructor(filePath: string, diagnosis?: FileAccessDiagnosis) {\n const resolved = diagnosis ?? inspectFileAccess(filePath);\n const reason = buildDiagnosisReason(resolved);\n super(`Cannot write to ${filePath} (${reason})`);\n this.name = \"FilePermissionError\";\n this.filePath = filePath;\n this.diagnosis = resolved;\n this.suggestedFixCommand = buildSuggestedFix(resolved);\n }\n}\n","import type { AgentAdapter } from \"@/domains/adapters/adapter.interface\";\nimport { writeAgentSkillReference } from \"@/domains/adapters/skill-reference-builder\";\nimport type { SkillMetadata } from \"@/types/skill.types\";\n\nexport class AntigravityAdapter implements AgentAdapter {\n readonly id = \"antigravity\" as const;\n readonly name = \"Antigravity\";\n readonly targetRelativeDir = \".agents/skills\";\n\n async installSkill(\n targetPath: string,\n skill: SkillMetadata,\n _skillSourceDir: string,\n transaction?: import(\"@/domains/fs/install-transaction\").InstallTransaction\n ): Promise<string[]> {\n const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill, transaction);\n return [file];\n }\n}\n","import type { AgentAdapter } from \"@/domains/adapters/adapter.interface\";\nimport { writeAgentSkillReference } from \"@/domains/adapters/skill-reference-builder\";\nimport type { SkillMetadata } from \"@/types/skill.types\";\n\nexport class ClaudeAdapter implements AgentAdapter {\n readonly id = \"claude\" as const;\n readonly name = \"Claude Code\";\n readonly targetRelativeDir = \".claude/skills\";\n\n async installSkill(\n targetPath: string,\n skill: SkillMetadata,\n _skillSourceDir: string,\n transaction?: import(\"@/domains/fs/install-transaction\").InstallTransaction\n ): Promise<string[]> {\n const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill, transaction);\n return [file];\n }\n}\n","import type { AgentAdapter } from \"@/domains/adapters/adapter.interface\";\nimport { writeCursorRuleReference } from \"@/domains/adapters/skill-reference-builder\";\nimport type { SkillMetadata } from \"@/types/skill.types\";\n\nexport class CursorAdapter implements AgentAdapter {\n readonly id = \"cursor\" as const;\n readonly name = \"Cursor\";\n readonly targetRelativeDir = \".cursor/rules\";\n\n async installSkill(\n targetPath: string,\n skill: SkillMetadata,\n _skillSourceDir: string,\n transaction?: import(\"@/domains/fs/install-transaction\").InstallTransaction\n ): Promise<string[]> {\n const file = writeCursorRuleReference(targetPath, this.targetRelativeDir, skill, transaction);\n return [file];\n }\n}\n","import type { AgentAdapter } from \"@/domains/adapters/adapter.interface\";\nimport { writeAgentSkillReference } from \"@/domains/adapters/skill-reference-builder\";\nimport type { SkillMetadata } from \"@/types/skill.types\";\n\nexport class GeminiAdapter implements AgentAdapter {\n readonly id = \"gemini\" as const;\n readonly name = \"Gemini Code Assist\";\n readonly targetRelativeDir = \".gemini/skills\";\n\n async installSkill(\n targetPath: string,\n skill: SkillMetadata,\n _skillSourceDir: string,\n transaction?: import(\"@/domains/fs/install-transaction\").InstallTransaction\n ): Promise<string[]> {\n const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill, transaction);\n return [file];\n }\n}\n","import { cpSync, existsSync, mkdirSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { resolveSkillsSourceRoot } from \"@/domains/installer/resolve-skills-source\";\nimport { getProjectSkillsDir } from \"@/domains/project-store/project-paths\";\nimport { SKILL_CATALOG } from \"@/domains/registry/skill-catalog\";\nimport type { InstallTransaction } from \"@/domains/fs/install-transaction\";\nimport type { AgentId } from \"@/types/agent.types\";\n\nexport function syncProjectStore(\n targetPath: string,\n selectedSkillIds: string[],\n _selectedAgents: AgentId[],\n transaction?: InstallTransaction\n): void {\n const bundledSkillsDir = resolveSkillsSourceRoot();\n const projectSkillsDir = getProjectSkillsDir(targetPath);\n\n if (transaction) {\n transaction.recordCreatedDir(projectSkillsDir);\n }\n\n if (!existsSync(projectSkillsDir)) {\n mkdirSync(projectSkillsDir, { recursive: true });\n }\n\n // Clean legacy cursor-rules directory if it exists\n const legacyCursorRules = join(targetPath, \".grooveskills\", \"cursor-rules\");\n if (existsSync(legacyCursorRules)) {\n try {\n rmSync(legacyCursorRules, { recursive: true, force: true });\n } catch {\n // Ignore cleanup error\n }\n }\n\n for (const skillId of selectedSkillIds) {\n const skill = SKILL_CATALOG.find((item) => item.id === skillId);\n if (!skill) {\n continue;\n }\n\n const sourceSkillDir = join(bundledSkillsDir, skill.directoryName);\n const destSkillDir = join(projectSkillsDir, skill.directoryName);\n\n if (transaction) {\n transaction.recordCreatedDir(destSkillDir);\n }\n\n if (existsSync(sourceSkillDir)) {\n cpSync(sourceSkillDir, destSkillDir, { recursive: true });\n }\n }\n}\n","import { fileURLToPath } from \"node:url\";\nimport { dirname, resolve, join } from \"node:path\";\nimport { existsSync } from \"node:fs\";\n\nexport function resolveSkillsSourceRoot(): string {\n const currentFilePath = fileURLToPath(import.meta.url);\n const currentDir = dirname(currentFilePath);\n\n // 1. From dist/ in published npm package or local build: dist/../skills\n const candidateFromDist = resolve(currentDir, \"../skills\");\n if (existsSync(candidateFromDist)) {\n return candidateFromDist;\n }\n\n // 2. From src/domains/installer/ during development: ../../../skills\n const candidateFromSrc = resolve(currentDir, \"../../../skills\");\n if (existsSync(candidateFromSrc)) {\n return candidateFromSrc;\n }\n\n // 3. Search upward for the package root containing a skills directory\n let searchDir = currentDir;\n for (let depth = 0; depth < 5; depth++) {\n const candidate = join(searchDir, \"skills\");\n if (existsSync(candidate)) {\n return candidate;\n }\n const parent = dirname(searchDir);\n if (parent === searchDir) {\n break;\n }\n searchDir = parent;\n }\n\n throw new Error(\n `GrooveSkills internal error: Unable to locate bundled skills directory from ${currentDir}`\n );\n}\n","import { existsSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n getProjectMemoryDir,\n getProjectTasksDir,\n} from \"@/domains/project-store/project-paths\";\nimport {\n buildContextTemplate,\n buildDecisionsTemplate,\n buildOnboardingTaskTemplate,\n buildTaskTemplate,\n} from \"@/domains/harness/harness-templates\";\nimport { scanProjectOnboarding } from \"@/domains/harness/scan-project-onboarding\";\nimport { upsertAgentInstructions } from \"@/domains/harness/upsert-agent-instructions\";\nimport { safeWriteFileSync } from \"@/domains/fs/safe-file-writer\";\nimport type { InstallTransaction } from \"@/domains/fs/install-transaction\";\nimport type {\n HarnessInstallOptions,\n HarnessInstallResult,\n} from \"@/types/harness.types\";\n\nfunction writeTrackedFile(\n filePath: string,\n content: string,\n transaction?: InstallTransaction\n): void {\n if (transaction) {\n transaction.recordBeforeWrite(filePath);\n }\n const outcome = safeWriteFileSync(filePath, content);\n if (outcome.strategy === \"replaced\" && transaction) {\n transaction.recordReplacedFile(filePath, outcome.previousOwnerUid);\n }\n}\n\nexport function installHarness(options: HarnessInstallOptions): HarnessInstallResult {\n const memoryDir = getProjectMemoryDir(options.targetPath);\n const tasksDir = getProjectTasksDir(options.targetPath);\n const language = options.language ?? \"es\";\n const forceOnboarding = Boolean(options.forceOnboarding);\n const transaction = options.transaction;\n\n if (transaction) {\n transaction.recordCreatedDir(memoryDir);\n transaction.recordCreatedDir(tasksDir);\n }\n\n if (!existsSync(tasksDir)) {\n mkdirSync(tasksDir, { recursive: true });\n }\n\n const createdFiles: string[] = [];\n const contextPath = join(memoryDir, \"context.md\");\n const shouldWriteContext = !existsSync(contextPath) || forceOnboarding;\n\n if (shouldWriteContext) {\n const profile = scanProjectOnboarding(options.targetPath);\n const contextContent = buildContextTemplate(\n options.detectedDependencies,\n language,\n profile\n );\n writeTrackedFile(contextPath, contextContent, transaction);\n createdFiles.push(contextPath);\n\n const onboardingTaskPath = join(tasksDir, \"00-onboarding.md\");\n writeTrackedFile(\n onboardingTaskPath,\n buildOnboardingTaskTemplate(profile.projectName),\n transaction\n );\n createdFiles.push(onboardingTaskPath);\n }\n\n const decisionsPath = join(memoryDir, \"decisions.md\");\n if (!existsSync(decisionsPath)) {\n writeTrackedFile(decisionsPath, buildDecisionsTemplate(language), transaction);\n createdFiles.push(decisionsPath);\n }\n\n const templateTaskPath = join(tasksDir, \"_template.md\");\n if (!existsSync(templateTaskPath)) {\n writeTrackedFile(templateTaskPath, buildTaskTemplate(), transaction);\n createdFiles.push(templateTaskPath);\n }\n\n const instructions = upsertAgentInstructions(\n options.targetPath,\n options.selectedAgents,\n language,\n transaction\n );\n createdFiles.push(...instructions);\n\n return {\n createdFiles,\n onboardingInitialized: shouldWriteContext,\n };\n}\n","import type { ProjectLanguage } from \"@/types/harness.types\";\n\nexport interface LanguageDefinition {\n code: ProjectLanguage;\n name: string;\n nativeName: string;\n instruction: string;\n onboardingPromptTitle: string;\n onboardingPrompt: string;\n}\n\nexport const SUPPORTED_LANGUAGES: Record<ProjectLanguage, LanguageDefinition> = {\n es: {\n code: \"es\",\n name: \"Spanish\",\n nativeName: \"Español\",\n instruction: \"Todos los mensajes, validaciones, errores, CTAs y comunicaciones con el usuario deben redactarse estrictamente en Español. El tono debe ser empático, amable, persuasivo y profesional.\",\n onboardingPromptTitle: \"Prompt de inicialización para tu Agente IA (Copia y pega en el chat):\",\n onboardingPrompt: \"Hola. Acabo de configurar GrooveSkills Harness en este proyecto. Por favor lee `.grooveskills/memory/tasks/00-onboarding.md`, `.grooveskills/memory/context.md` y las skills instaladas en `.agents/skills/`. Hazme preguntas interactivas paso a paso para detectar vacíos de arquitectura, aclarar objetivos y adaptar el proyecto a mis necesidades antes de continuar.\",\n },\n en: {\n code: \"en\",\n name: \"English\",\n nativeName: \"English\",\n instruction: \"All user-facing messages, form validations, errors, CTAs, and notifications must be written strictly in English. Tone must be empathetic, friendly, persuasive, and professional.\",\n onboardingPromptTitle: \"Initialization prompt for your AI Agent (Copy and paste into your chat):\",\n onboardingPrompt: \"Hello. I just configured GrooveSkills Harness in this project. Please review `.grooveskills/memory/tasks/00-onboarding.md`, `.grooveskills/memory/context.md`, and the skills installed in `.agents/skills/`. Ask me step-by-step interactive questions to identify architectural gaps, clarify priorities, and adapt the project to my needs before continuing.\",\n },\n pt: {\n code: \"pt\",\n name: \"Portuguese\",\n nativeName: \"Português\",\n instruction: \"Todas as mensagens, validações, erros, CTAs e comunicações voltadas para o usuário devem ser redigidas estritamente em Português. O tom deve ser empático, amigável, persuasivo e profissional.\",\n onboardingPromptTitle: \"Prompt de inicialização para o seu Agente de IA (Copie e cole no chat):\",\n onboardingPrompt: \"Olá. Acabei de configurar o GrooveSkills Harness neste projeto. Por favor leia `.grooveskills/memory/tasks/00-onboarding.md`, `.grooveskills/memory/context.md` e as skills instaladas em `.agents/skills/`. Faça-me perguntas interativas passo a passo para mapear lacunas de arquitetura, alinhar prioridades e adaptar o projeto às minhas necessidades antes de prosseguir.\",\n },\n it: {\n code: \"it\",\n name: \"Italian\",\n nativeName: \"Italiano\",\n instruction: \"Tutti i messaggi, le convalide, gli errori, i pulsanti/CTA e le comunicazioni rivolte all'utente devono essere scritti rigorosamente in Italiano. Il tono deve essere empatico, cordiale, persuasivo e professionale.\",\n onboardingPromptTitle: \"Prompt di inizializzazione per il tuo Agente AI (Copia e incolla nella chat):\",\n onboardingPrompt: \"Ciao. Ho appena configurato GrooveSkills Harness in questo progetto. Ti prego di leggere `.grooveskills/memory/tasks/00-onboarding.md`, `.grooveskills/memory/context.md` e le skills installate in `.agents/skills/`. Fammi domande interattive passo dopo passo per identificare lacune architetturali, allineare le priorità e adattare il progetto alle mie esigenze prima di continuare.\",\n },\n fr: {\n code: \"fr\",\n name: \"French\",\n nativeName: \"Français\",\n instruction: \"Tous les messages, validations, erreurs, boutons d'appel à l'action (CTA) et notifications destinés à l'utilisateur doivent être rédigés strictement en Français. Le ton doit être empathique, courtois, persuasif et professionnel.\",\n onboardingPromptTitle: \"Prompt d'initialisation pour votre Agent IA (Copiez et collez dans le chat) :\",\n onboardingPrompt: \"Bonjour. Je viens de configurer GrooveSkills Harness sur ce projet. Veuillez consulter `.grooveskills/memory/tasks/00-onboarding.md`, `.grooveskills/memory/context.md` et les skills installées dans `.agents/skills/`. Posez-moi des questions interactives étape par étape pour identifier les lacunes d'architecture, préciser les priorités et adapter le projet à mes besoins avant de continuer.\",\n },\n};\n","import type { ProjectLanguage } from \"@/types/harness.types\";\nimport { SUPPORTED_LANGUAGES } from \"@/domains/harness/harness-languages\";\nimport type { ProjectOnboardingProfile } from \"@/domains/harness/scan-project-onboarding\";\n\nexport function buildContextTemplate(\n detectedDependencies: string[],\n language: ProjectLanguage = \"es\",\n profile?: ProjectOnboardingProfile\n): string {\n const dependenciesFormatted =\n detectedDependencies.length > 0\n ? detectedDependencies.map((dependencyName) => `- \\`${dependencyName}\\``).join(\"\\n\")\n : \"- (No external dependencies detected)\";\n\n const languageConfig = SUPPORTED_LANGUAGES[language];\n const projectName = profile?.projectName ?? \"Project\";\n const packageManager = profile?.packageManager ?? \"npm\";\n\n const commandLines: string[] = [];\n if (profile?.commands) {\n for (const [commandKey, commandValue] of Object.entries(profile.commands)) {\n commandLines.push(`- **${commandKey}**: \\`${commandValue}\\``);\n }\n }\n const commandsSection =\n commandLines.length > 0\n ? commandLines.join(\"\\n\")\n : `- Build: Refer to \\`package.json\\` scripts.\\n- Typecheck: Refer to TypeScript configuration.\\n- Tests: Refer to test runner configuration.`;\n\n const aliasLines: string[] = [];\n if (profile?.pathAliases) {\n for (const [aliasPattern, aliasTarget] of Object.entries(profile.pathAliases)) {\n aliasLines.push(`- \\`${aliasPattern}\\` -> \\`${aliasTarget}\\``);\n }\n }\n const aliasesSection =\n aliasLines.length > 0 ? `\\n### Path Aliases\\n${aliasLines.join(\"\\n\")}\\n` : \"\";\n\n const directoryLines: string[] = [];\n if (profile?.sourceDirectories && profile.sourceDirectories.length > 0) {\n for (const directoryName of profile.sourceDirectories) {\n directoryLines.push(`- \\`${directoryName}/\\``);\n }\n }\n const directoriesSection =\n directoryLines.length > 0 ? `\\n### Source Modules\\n${directoryLines.join(\"\\n\")}\\n` : \"\";\n\n return `# Project Context & Architecture: ${projectName}\n\nThis file provides AI agents with instant architectural orientation for this project.\n\n## 1. Stack & Dependencies\n- **Package Manager**: \\`${packageManager}\\`\n${dependenciesFormatted}\n\n## 2. Directory Structure Conventions\n- Follow single-responsibility per file (<200 lines).\n- Maintain direct imports with path aliases; avoid barrel files.\n- Keep domain boundaries explicit and clean.\n${aliasesSection}${directoriesSection}\n## 3. Communication & User Copy Language\n- **Configured Language**: ${languageConfig.nativeName} (\\`${language}\\`).\n- **Policy**: ${languageConfig.instruction}\n\n## 4. Essential Commands\n${commandsSection}\n`;\n}\n\nexport function buildDecisionsTemplate(language: ProjectLanguage = \"es\"): string {\n const currentDate = new Date().toISOString().split(\"T\")[0];\n const languageConfig = SUPPORTED_LANGUAGES[language];\n\n return `# Architecture Decision Records (ADR)\n\nAn append-only log of significant technical and architectural choices.\n\n| Date | Title | Decision | Reason & Consequences |\n| :--- | :--- | :--- | :--- |\n| ${currentDate} | Adopt GrooveSkills Harness | Initialized \\`.grooveskills/\\` control plane with ODD | Clean, encapsulated agent memory, 3-lane ODD flow, and ${languageConfig.nativeName} copy standard |\n`;\n}\n\nexport function buildOnboardingTaskTemplate(projectName: string = \"Project\"): string {\n const currentDate = new Date().toISOString().split(\"T\")[0];\n\n return `---\nstatus: pending\ncreatedAt: ${currentDate}\n---\n\n# 00 — Initial Project Onboarding & Architecture Exploration: ${projectName}\n\n## Outcome Hypothesis\nBy scanning dependencies, entry points, configuration manifests, and module layout, the AI agent will gain a verified architectural understanding of \\`${projectName}\\`, proven by filling out \\`.grooveskills/memory/context.md\\`, formulating interactive alignment questions with the user, and validating the essential build/typecheck commands.\n\n## Scope\n- In scope: Inspect project manifests, entry points, directory conventions, ask interactive alignment questions, and verify script execution.\n- Out of scope: Refactoring business logic or modifying functional code before alignment.\n\n## Checklist\n- [ ] Verify package manager and essential scripts (\\`build\\`, \\`test\\`, \\`typecheck\\`).\n- [ ] Map high-level module architecture and data flow in \\`.grooveskills/memory/context.md\\`.\n- [ ] Ask the user step-by-step interactive questions to clarify goals, domain scope, and adapt project conventions.\n- [ ] Document agreed technical decisions in \\`.grooveskills/memory/decisions.md\\`.\n- [ ] Verify test runner or static checks pass cleanly.\n- [ ] Switch status to \\`completed\\` once project context is fully verified.\n\n## Evidence\n- Observed command runs and outputs during the initial onboarding pass.\n- User answers to alignment questions captured in memory.\n\n## Next\n- Once onboarding is marked completed, proceed with domain tasks following the 3-lane ODD protocol.\n`;\n}\n\nexport function buildTaskTemplate(): string {\n return `---\nstatus: in-progress\ncreatedAt: \\${CURRENT_DATE}\n---\n\n# Feature / Task Title\n\n## Outcome Hypothesis\nDescribe the expected behavioral outcome:\nBy [Output / Technical Change], [Outcome / Verifiable Behavior] will occur, proven by [Evidence / Test / Build Command].\n\n## Scope\n- In scope:\n- Out of scope:\n\n## Checklist\n- [ ] Task 1: (Define expected observed proof)\n- [ ] Task 2: (Define expected observed proof)\n\n## Evidence\n- Observed test/typecheck/build commands or runtime outputs proving completion.\n\n## Next\n- Next concrete step if interrupted.\n`;\n}\n\nexport function buildAgentHarnessBlock(language: ProjectLanguage = \"es\"): string {\n const languageConfig = SUPPORTED_LANGUAGES[language];\n\n return `<!-- grooveskills:harness:start -->\n# GrooveSkills Harness — Agent Rules & Memory\n\nThis project uses the **GrooveSkills Harness** located in \\`.grooveskills/\\`.\n\n## 1. Three-Lane ODD Protocol\n- **Onboarding Check**: If \\`.grooveskills/memory/tasks/00-onboarding.md\\` has \\`status: pending\\`, complete its checklist to enrich \\`context.md\\` and set its status to \\`completed\\`.\n- **Authorize & Explore**: Follow the 7-step ODD protocol (Authorize, Explore, Resolve, Classify, Track & Hypothesize, Execute, Verify).\n- **Lane 1 (Answer)**: Explanations, audits, or questions. Read-only; write zero code.\n- **Lane 2 (Task)**: Direct implementation. Declare Outcome Hypothesis and checklist in \\`.grooveskills/memory/tasks/<slug>.md\\`. Only check off tasks with observed evidence under \\`Evidence\\`.\n- **Lane 3 (Spec)**: Ambiguous or high-impact architecture. Clarify and validate the spec in \\`.grooveskills/memory/tasks/<slug>.md\\` before writing code.\n\n## 2. User Communication Language (${languageConfig.nativeName})\n- **Language**: \\`${language}\\` (${languageConfig.nativeName}).\n- **Requirement**: ${languageConfig.instruction}\n\n## 3. Memory Locations\n- Architecture context: \\`.grooveskills/memory/context.md\\`\n- Technical decisions (ADR): \\`.grooveskills/memory/decisions.md\\`\n- Active tasks & evidence: \\`.grooveskills/memory/tasks/\\`\n<!-- grooveskills:harness:end -->`;\n}\n","import { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\n\nexport interface ProjectOnboardingProfile {\n projectName: string;\n packageManager: string;\n commands: Record<string, string>;\n pathAliases: Record<string, string>;\n sourceDirectories: string[];\n}\n\nfunction detectProjectName(targetPath: string): string {\n const packageJsonPath = join(targetPath, \"package.json\");\n if (existsSync(packageJsonPath)) {\n try {\n const raw = readFileSync(packageJsonPath, \"utf-8\");\n const parsed = JSON.parse(raw) as { name?: string };\n if (typeof parsed.name === \"string\" && parsed.name.trim().length > 0) {\n return parsed.name.trim();\n }\n } catch {\n // Fall through to other manifests\n }\n }\n\n const cargoPath = join(targetPath, \"Cargo.toml\");\n if (existsSync(cargoPath)) {\n try {\n const cargoRaw = readFileSync(cargoPath, \"utf-8\");\n const nameMatch = cargoRaw.match(/name\\s*=\\s*\"([^\"]+)\"/);\n if (nameMatch?.[1]) {\n return nameMatch[1];\n }\n } catch {\n // Fall through\n }\n }\n\n const pyprojectPath = join(targetPath, \"pyproject.toml\");\n if (existsSync(pyprojectPath)) {\n try {\n const pyprojectRaw = readFileSync(pyprojectPath, \"utf-8\");\n const nameMatch = pyprojectRaw.match(/name\\s*=\\s*\"([^\"]+)\"/);\n if (nameMatch?.[1]) {\n return nameMatch[1];\n }\n } catch {\n // Fall through\n }\n }\n\n return basename(targetPath) || \"project\";\n}\n\nfunction detectPackageManager(targetPath: string): string {\n if (existsSync(join(targetPath, \"pnpm-lock.yaml\"))) {\n return \"pnpm\";\n }\n if (existsSync(join(targetPath, \"bun.lockb\")) || existsSync(join(targetPath, \"bun.lock\"))) {\n return \"bun\";\n }\n if (existsSync(join(targetPath, \"yarn.lock\"))) {\n return \"yarn\";\n }\n if (existsSync(join(targetPath, \"package-lock.json\"))) {\n return \"npm\";\n }\n if (existsSync(join(targetPath, \"Cargo.lock\")) || existsSync(join(targetPath, \"Cargo.toml\"))) {\n return \"cargo\";\n }\n if (existsSync(join(targetPath, \"uv.lock\"))) {\n return \"uv\";\n }\n if (existsSync(join(targetPath, \"poetry.lock\"))) {\n return \"poetry\";\n }\n return \"npm\";\n}\n\nfunction detectCommands(targetPath: string, packageManager: string): Record<string, string> {\n const packageJsonPath = join(targetPath, \"package.json\");\n if (!existsSync(packageJsonPath)) {\n return {};\n }\n\n try {\n const raw = readFileSync(packageJsonPath, \"utf-8\");\n const parsed = JSON.parse(raw) as { scripts?: Record<string, string> };\n const scripts = parsed.scripts ?? {};\n const commands: Record<string, string> = {};\n\n const runner = packageManager === \"npm\" ? \"npm run\" : packageManager;\n\n if (scripts.build) {\n commands.build = `${runner} build`;\n }\n if (scripts[\"check-types\"]) {\n commands.typecheck = `${runner} check-types`;\n } else if (scripts.typecheck) {\n commands.typecheck = `${runner} typecheck`;\n } else if (scripts.tsc) {\n commands.typecheck = `${runner} tsc`;\n }\n\n if (scripts.test) {\n commands.test = `${runner} test`;\n }\n if (scripts.lint) {\n commands.lint = `${runner} lint`;\n }\n if (scripts.dev) {\n commands.dev = `${runner} dev`;\n }\n\n return commands;\n } catch {\n return {};\n }\n}\n\nfunction detectPathAliases(targetPath: string): Record<string, string> {\n const tsconfigPath = join(targetPath, \"tsconfig.json\");\n if (!existsSync(tsconfigPath)) {\n return {};\n }\n\n try {\n const raw = readFileSync(tsconfigPath, \"utf-8\");\n const parsed = JSON.parse(raw) as {\n compilerOptions?: {\n paths?: Record<string, string[]>;\n };\n };\n const paths = parsed.compilerOptions?.paths ?? {};\n const aliases: Record<string, string> = {};\n\n for (const [aliasKey, aliasTargets] of Object.entries(paths)) {\n if (Array.isArray(aliasTargets) && typeof aliasTargets[0] === \"string\") {\n aliases[aliasKey] = aliasTargets[0];\n }\n }\n\n return aliases;\n } catch {\n return {};\n }\n}\n\nfunction detectSourceDirectories(targetPath: string): string[] {\n const srcPath = join(targetPath, \"src\");\n const scanTarget = existsSync(srcPath) ? srcPath : targetPath;\n\n try {\n const entries = readdirSync(scanTarget, { withFileTypes: true });\n return entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name)\n .filter((name) => !name.startsWith(\".\") && name !== \"node_modules\" && name !== \"dist\");\n } catch {\n return [];\n }\n}\n\nexport function scanProjectOnboarding(targetPath: string): ProjectOnboardingProfile {\n const projectName = detectProjectName(targetPath);\n const packageManager = detectPackageManager(targetPath);\n const commands = detectCommands(targetPath, packageManager);\n const pathAliases = detectPathAliases(targetPath);\n const sourceDirectories = detectSourceDirectories(targetPath);\n\n return {\n projectName,\n packageManager,\n commands,\n pathAliases,\n sourceDirectories,\n };\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { buildAgentHarnessBlock } from \"@/domains/harness/harness-templates\";\nimport { safeWriteFileSync } from \"@/domains/fs/safe-file-writer\";\nimport type { InstallTransaction } from \"@/domains/fs/install-transaction\";\nimport type { AgentId } from \"@/types/agent.types\";\nimport type { ProjectLanguage } from \"@/types/harness.types\";\n\nconst START_MARKER = \"<!-- grooveskills:harness:start -->\";\nconst END_MARKER = \"<!-- grooveskills:harness:end -->\";\n\nfunction writeWithTransaction(\n filePath: string,\n content: string,\n transaction?: InstallTransaction\n): void {\n const outcome = safeWriteFileSync(filePath, content);\n if (outcome.strategy === \"replaced\" && transaction) {\n transaction.recordReplacedFile(filePath, outcome.previousOwnerUid);\n }\n}\n\nfunction applyHarnessBlock(\n filePath: string,\n language: ProjectLanguage = \"es\",\n transaction?: InstallTransaction\n): void {\n if (transaction) {\n transaction.recordBeforeWrite(filePath);\n }\n\n const block = buildAgentHarnessBlock(language);\n\n if (!existsSync(filePath)) {\n writeWithTransaction(filePath, `${block}\\n`, transaction);\n return;\n }\n\n const existingContent = readFileSync(filePath, \"utf-8\");\n\n if (existingContent.includes(START_MARKER) && existingContent.includes(END_MARKER)) {\n const regex = new RegExp(`${START_MARKER}[\\\\s\\\\S]*?${END_MARKER}`, \"g\");\n const updated = existingContent.replace(regex, block);\n writeWithTransaction(filePath, updated, transaction);\n return;\n }\n\n const separator = existingContent.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n writeWithTransaction(filePath, `${existingContent}${separator}${block}\\n`, transaction);\n}\n\nexport function upsertAgentInstructions(\n targetPath: string,\n selectedAgents: AgentId[],\n language: ProjectLanguage = \"es\",\n transaction?: InstallTransaction\n): string[] {\n const updatedFiles: string[] = [];\n\n const agentsMdPath = join(targetPath, \"AGENTS.md\");\n applyHarnessBlock(agentsMdPath, language, transaction);\n updatedFiles.push(agentsMdPath);\n\n if (selectedAgents.includes(\"claude\")) {\n const claudeMdPath = join(targetPath, \"CLAUDE.md\");\n applyHarnessBlock(claudeMdPath, language, transaction);\n updatedFiles.push(claudeMdPath);\n }\n\n return updatedFiles;\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { getProjectConfigPath } from \"@/domains/project-store/project-paths\";\nimport { safeWriteFileSync } from \"@/domains/fs/safe-file-writer\";\nimport type { InstallTransaction } from \"@/domains/fs/install-transaction\";\nimport type { GrooveSkillsConfig, ProjectLanguage } from \"@/types/harness.types\";\nimport type { AgentId } from \"@/types/agent.types\";\n\ninterface ParsedConfigState {\n skills: string[];\n agents: AgentId[];\n harness: boolean;\n language?: ProjectLanguage;\n}\n\nfunction readExistingConfig(configPath: string): ParsedConfigState {\n const fallback: ParsedConfigState = {\n skills: [],\n agents: [],\n harness: false,\n };\n\n if (!existsSync(configPath)) {\n return fallback;\n }\n\n try {\n const raw = readFileSync(configPath, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<GrooveSkillsConfig>;\n\n return {\n skills: Array.isArray(parsed.skills) ? parsed.skills : [],\n agents: Array.isArray(parsed.agents) ? parsed.agents : [],\n harness: typeof parsed.harness === \"boolean\" ? parsed.harness : false,\n language: typeof parsed.language === \"string\" ? (parsed.language as ProjectLanguage) : undefined,\n };\n } catch {\n return fallback;\n }\n}\n\nexport function writeProjectConfig(\n targetPath: string,\n newSkills: string[],\n newAgents: AgentId[],\n harnessEnabled: boolean,\n language?: ProjectLanguage,\n transaction?: InstallTransaction\n): string {\n const configPath = getProjectConfigPath(targetPath);\n if (transaction) {\n transaction.recordBeforeWrite(configPath);\n }\n\n const existing = readExistingConfig(configPath);\n\n const mergedSkills = Array.from(new Set([...existing.skills, ...newSkills]));\n const mergedAgents = Array.from(new Set([...existing.agents, ...newAgents]));\n const resolvedLanguage = language ?? existing.language ?? \"es\";\n const isHarnessActive = existing.harness || harnessEnabled;\n\n const config: GrooveSkillsConfig = {\n version: 1,\n harness: isHarnessActive,\n ...(isHarnessActive ? { language: resolvedLanguage } : {}),\n agents: mergedAgents,\n skills: mergedSkills,\n updatedAt: new Date().toISOString(),\n };\n\n const outcome = safeWriteFileSync(configPath, `${JSON.stringify(config, null, 2)}\\n`);\n if (outcome.strategy === \"replaced\" && transaction) {\n transaction.recordReplacedFile(configPath, outcome.previousOwnerUid);\n }\n\n return configPath;\n}\n","import { existsSync, readdirSync, readFileSync, rmSync } from \"node:fs\";\nimport { safeWriteFileSync } from \"@/domains/fs/safe-file-writer\";\n\nexport interface RollbackFailure {\n path: string;\n reason: string;\n}\n\nexport interface ReplacedFileNotice {\n filePath: string;\n previousOwnerUid: number | null;\n}\n\nexport interface RollbackReport {\n restoredFiles: string[];\n removedFiles: string[];\n removedDirs: string[];\n failures: RollbackFailure[];\n isClean: boolean;\n}\n\nexport class InstallTransaction {\n private originalFiles = new Map<string, string | null>();\n private createdDirs: string[] = [];\n private replacedFiles: ReplacedFileNotice[] = [];\n\n recordBeforeWrite(filePath: string): void {\n if (this.originalFiles.has(filePath)) {\n return;\n }\n if (existsSync(filePath)) {\n try {\n this.originalFiles.set(filePath, readFileSync(filePath, \"utf-8\"));\n } catch {\n this.originalFiles.set(filePath, null);\n }\n } else {\n this.originalFiles.set(filePath, null);\n }\n }\n\n recordCreatedDir(dirPath: string): void {\n if (!existsSync(dirPath) && !this.createdDirs.includes(dirPath)) {\n this.createdDirs.push(dirPath);\n }\n }\n\n recordReplacedFile(filePath: string, previousOwnerUid: number | null): void {\n if (!this.replacedFiles.some((item) => item.filePath === filePath)) {\n this.replacedFiles.push({ filePath, previousOwnerUid });\n }\n }\n\n getReplacedFiles(): ReplacedFileNotice[] {\n return [...this.replacedFiles];\n }\n\n rollback(): RollbackReport {\n const restoredFiles: string[] = [];\n const removedFiles: string[] = [];\n const removedDirs: string[] = [];\n const failures: RollbackFailure[] = [];\n\n for (const [filePath, content] of this.originalFiles.entries()) {\n try {\n if (content === null) {\n if (existsSync(filePath)) {\n rmSync(filePath, { force: true });\n removedFiles.push(filePath);\n }\n continue;\n }\n\n if (existsSync(filePath)) {\n try {\n const currentContent = readFileSync(filePath, \"utf-8\");\n if (currentContent === content) {\n continue;\n }\n } catch {\n // Proceed to restore if current content cannot be read\n }\n }\n\n safeWriteFileSync(filePath, content);\n restoredFiles.push(filePath);\n } catch (error: unknown) {\n const reason = error instanceof Error ? error.message : String(error);\n failures.push({ path: filePath, reason });\n }\n }\n\n const sortedDirs = [...this.createdDirs].sort(\n (firstDir, secondDir) => secondDir.length - firstDir.length\n );\n for (const directoryPath of sortedDirs) {\n try {\n if (existsSync(directoryPath) && readdirSync(directoryPath).length === 0) {\n rmSync(directoryPath, { recursive: true, force: true });\n removedDirs.push(directoryPath);\n }\n } catch (error: unknown) {\n const reason = error instanceof Error ? error.message : String(error);\n failures.push({ path: directoryPath, reason });\n }\n }\n\n return {\n restoredFiles,\n removedFiles,\n removedDirs,\n failures,\n isClean: failures.length === 0,\n };\n }\n}\n","import { join } from \"node:path\";\nimport { inspectFileAccess } from \"@/domains/fs/inspect-file-access\";\nimport {\n getProjectConfigPath,\n getProjectMemoryDir,\n getProjectTasksDir,\n} from \"@/domains/project-store/project-paths\";\nimport { FilePermissionError } from \"@/errors/file-permission-error\";\nimport type { AgentId } from \"@/types/agent.types\";\n\nexport interface PreflightCheckOptions {\n targetPath: string;\n selectedAgents: AgentId[];\n}\n\nexport function canRecoverOrWriteTarget(filePath: string): void {\n const diagnosis = inspectFileAccess(filePath);\n\n if (diagnosis.immutableFlag) {\n throw new FilePermissionError(filePath, diagnosis);\n }\n\n if (!diagnosis.exists) {\n if (!diagnosis.dirWritable) {\n throw new FilePermissionError(filePath, diagnosis);\n }\n return;\n }\n\n const ownerWritable =\n diagnosis.ownedByCurrentUser && ((diagnosis.mode ?? 0) & 0o200) !== 0;\n\n if (ownerWritable) {\n return;\n }\n\n if (diagnosis.ownedByCurrentUser) {\n return;\n }\n\n if (diagnosis.dirWritable) {\n return;\n }\n\n throw new FilePermissionError(filePath, diagnosis);\n}\n\nexport function runPreflightWriteCheck(options: PreflightCheckOptions): void {\n const memoryDir = getProjectMemoryDir(options.targetPath);\n const tasksDir = getProjectTasksDir(options.targetPath);\n\n const candidatePaths: string[] = [\n join(options.targetPath, \"AGENTS.md\"),\n ];\n\n if (options.selectedAgents.includes(\"claude\")) {\n candidatePaths.push(join(options.targetPath, \"CLAUDE.md\"));\n }\n\n candidatePaths.push(\n getProjectConfigPath(options.targetPath),\n join(memoryDir, \"context.md\"),\n join(memoryDir, \"decisions.md\"),\n join(tasksDir, \"00-onboarding.md\"),\n join(tasksDir, \"_template.md\")\n );\n\n for (const filePath of candidatePaths) {\n canRecoverOrWriteTarget(filePath);\n }\n}\n","import type { RollbackReport } from \"@/domains/fs/install-transaction\";\n\nexport interface InstallTransactionErrorOptions {\n stage: string;\n cause: unknown;\n rollbackReport: RollbackReport;\n suggestedFix?: string;\n}\n\nexport class InstallTransactionError extends Error {\n readonly stage: string;\n readonly causeError: unknown;\n readonly rollbackReport: RollbackReport;\n readonly suggestedFix?: string;\n\n constructor(options: InstallTransactionErrorOptions) {\n const rawMessage =\n options.cause instanceof Error ? options.cause.message : String(options.cause);\n super(`Error during stage '${options.stage}': ${rawMessage}`);\n this.name = \"InstallTransactionError\";\n this.stage = options.stage;\n this.causeError = options.cause;\n this.rollbackReport = options.rollbackReport;\n this.suggestedFix = options.suggestedFix;\n }\n}\n","import picocolors from \"picocolors\";\nimport { SUPPORTED_LANGUAGES } from \"@/domains/harness/harness-languages\";\nimport type { ProjectLanguage } from \"@/types/harness.types\";\n\nexport interface OnboardingPromptRender {\n title: string;\n prompt: string;\n formattedOutput: string;\n}\n\nexport function formatOnboardingPrompt(\n language: ProjectLanguage = \"es\"\n): OnboardingPromptRender {\n const languageConfig = SUPPORTED_LANGUAGES[language] ?? SUPPORTED_LANGUAGES.es;\n const title = languageConfig.onboardingPromptTitle;\n const prompt = languageConfig.onboardingPrompt;\n\n const separator = picocolors.cyan(\"─\".repeat(60));\n const formattedOutput = [\n separator,\n picocolors.bold(picocolors.yellow(title)),\n \"\",\n picocolors.green(prompt),\n separator,\n ].join(\"\\n\");\n\n return {\n title,\n prompt,\n formattedOutput,\n };\n}\n","import { basename } from \"node:path\";\nimport { userInfo } from \"node:os\";\nimport * as prompts from \"@clack/prompts\";\nimport picocolors from \"picocolors\";\nimport { formatOwnerName } from \"@/domains/fs/inspect-file-access\";\nimport { InstallTransactionError } from \"@/errors/install-transaction-error\";\nimport type { ReplacedFileNotice } from \"@/domains/fs/install-transaction\";\n\nexport function getCurrentUsername(): string {\n try {\n return userInfo().username;\n } catch {\n return process.env.USER || process.env.LOGNAME || \"current user\";\n }\n}\n\nexport function formatReplacedFileNotes(replacedFiles: ReplacedFileNotice[] = []): string[] {\n if (replacedFiles.length === 0) {\n return [];\n }\n const currentUser = getCurrentUsername();\n return replacedFiles.map((replacedItem) => {\n const fileName = basename(replacedItem.filePath);\n const previousOwner = formatOwnerName(replacedItem.previousOwnerUid);\n return picocolors.yellow(\n `Note: ${fileName} was owned by ${previousOwner}. It was replaced atomically and is now owned by ${currentUser}.`\n );\n });\n}\n\nexport function renderInstallFailure(error: InstallTransactionError): void {\n const { stage, causeError, rollbackReport, suggestedFix } = error;\n const causeMessage = causeError instanceof Error ? causeError.message : String(causeError);\n const nothingTouched =\n rollbackReport.restoredFiles.length === 0 &&\n rollbackReport.removedFiles.length === 0 &&\n rollbackReport.removedDirs.length === 0 &&\n rollbackReport.failures.length === 0;\n\n const lines: string[] = [\n `${picocolors.bold(\"Failed stage:\")} ${picocolors.yellow(stage)}`,\n `${picocolors.bold(\"Cause:\")} ${picocolors.red(causeMessage)}`,\n ];\n\n if (nothingTouched) {\n lines.push(`${picocolors.bold(\"Rollback:\")} Nothing to roll back, no files were modified.`);\n } else {\n lines.push(\n \"\",\n picocolors.bold(\"Rollback summary:\"),\n ` • Restored files: ${picocolors.cyan(String(rollbackReport.restoredFiles.length))}`,\n ` • Removed temporary files: ${picocolors.cyan(String(rollbackReport.removedFiles.length))}`,\n ` • Removed empty directories: ${picocolors.cyan(String(rollbackReport.removedDirs.length))}`\n );\n if (!rollbackReport.isClean) {\n lines.push(\"\", picocolors.red(\"Rollback was incomplete. These files may need manual review:\"));\n for (const failure of rollbackReport.failures) {\n lines.push(` • ${failure.path} (${failure.reason})`);\n }\n }\n }\n\n if (suggestedFix) {\n lines.push(`${picocolors.bold(\"Suggested fix:\")} ${picocolors.green(suggestedFix)}`);\n }\n\n prompts.note(lines.join(\"\\n\"), \"Installation Aborted\");\n\n if (!rollbackReport.isClean) {\n prompts.outro(\n picocolors.red(\n \"Rollback was incomplete. Please review the files listed above and apply the suggested fix.\"\n )\n );\n return;\n }\n\n prompts.outro(\n picocolors.yellow(\n nothingTouched\n ? \"No files were modified. Apply the suggested fix and try again.\"\n : \"Your project was restored to its previous state. Apply the suggested fix and try again.\"\n )\n );\n}\n"],"mappings":"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","names":["basename","userInfo","picocolors","existsSync","readFileSync","join","join","existsSync","readFileSync","prompts","picocolors","prompts","prompts","prompts","join","join","existsSync","lstatSync","readFileSync","rmSync","join","join","existsSync","existsSync","lstatSync","existsSync","existsSync","lstatSync","rmSync","readFileSync","join","existsSync","mkdirSync","rmSync","join","dirname","join","existsSync","existsSync","mkdirSync","join","rmSync","existsSync","mkdirSync","join","existsSync","readdirSync","readFileSync","join","existsSync","readFileSync","join","existsSync","readFileSync","join","existsSync","mkdirSync","join","existsSync","readFileSync","existsSync","readFileSync","existsSync","readdirSync","readFileSync","rmSync","existsSync","readFileSync","rmSync","readdirSync","join","join","join","picocolors","picocolors","basename","prompts","picocolors","basename","picocolors","picocolors","userInfo","basename","picocolors"]}
|