@3lineas/grooveskills 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -131,6 +131,13 @@ my-project/
131
131
  | `ux-writing` | **UX Writing & Microcopy** | Warm, empathetic, conversion-oriented microcopy for validations, CTAs, toasts, and empty states. | **Default (Universal)** |
132
132
  | `error-handling-logging` | **Error Handling & Logging** | Predictable error flows with typed `AppError`, `ActionResponse` contracts, and structured logging. | **Default (Universal)** |
133
133
  | `clean-architecture-ddd` | **Clean Architecture & DDD** | Domain-driven module boundaries, single-purpose Actions, pure functions, and immutable data models. | **Default (Universal)** |
134
+ | `external-service-adapters` | **External Service Adapters & Wrappers** | Decoupled domain ports, vendor SDK wrappers, and swappable adapters for payment gateways, emails, and APIs. | **Default (Universal)** |
135
+ | `storage-file-adapters` | **Storage & File Adapters (S3, R2, Supabase)** | Object storage ports, uploads, presigned URLs, and streaming without repository abstractions. | **Default (Universal)** |
136
+ | `auth-rbac-policies` | **Auth Adapters & RBAC/ABAC Policies** | Authentication adapter ports with `AuthenticatedActor` and side-effect-free pure authorization policies. | **Default (Universal)** |
137
+ | `controller-orchestration-queues` | **Controller Orchestration & Queues** | Atomic Actions, Controller sequence/transactions, and swappable background Queue adapters. | **Default (Universal)** |
138
+ | `webhook-idempotency` | **Webhook Verifiers & Idempotency** | Cryptographic HMAC webhook verifiers (Stripe, Svix, MercadoPago) and atomic idempotency guards. | **Default (Universal)** |
139
+ | `caching-rate-limiting` | **Cache-Aside & Rate Limiting** | Declarative `cache.remember` wrappers and sliding-window rate limiting adapters (Redis, KV, Memory). | **Default (Universal)** |
140
+ | `env-feature-flags` | **Fail-Fast Env & Feature Flags** | Boot-time fail-fast Valibot environment validation and decoupled feature flag adapters (PostHog, LD). | **Default (Universal)** |
134
141
  | `typescript-clean` | **TypeScript Clean Code (5.5+)** | Modern TypeScript (`satisfies`, discriminated unions, `const` generics, `unknown` narrowing). | `typescript` in `package.json` |
135
142
  | `rust-clean` | **Rust Clean Code (Rust 2024)** | Idiomatic Rust: `let-else` guard clauses, zero `.unwrap()`, `thiserror` typed errors, and Newtypes. | `Cargo.toml` in project root |
136
143
  | `python-clean` | **Python Clean Code (Python 3.12+)** | Modern Python: guard clauses (no nested ifs), strict typing (zero `Any`), uv, Ruff, and Pyright. | `pyproject.toml` / `requirements.txt` |
@@ -136,6 +136,55 @@ var SKILL_CATALOG = [
136
136
  dependencies: [],
137
137
  directoryName: "clean-architecture-ddd"
138
138
  },
139
+ {
140
+ id: "external-service-adapters",
141
+ name: "External Service Adapters & Wrappers",
142
+ description: "Standardized adapter and wrapper architecture for external services (payment gateways, emails, SMS, cloud storage)",
143
+ dependencies: [],
144
+ directoryName: "external-service-adapters"
145
+ },
146
+ {
147
+ id: "storage-file-adapters",
148
+ name: "Storage & File Adapters (S3, R2, Supabase)",
149
+ description: "Standardized wrapper & adapter architecture for object storage, uploads, presigned URLs, and streaming without repositories",
150
+ dependencies: [],
151
+ directoryName: "storage-file-adapters"
152
+ },
153
+ {
154
+ id: "auth-rbac-policies",
155
+ name: "Auth Adapters & RBAC/ABAC Policies",
156
+ description: "Authentication adapter architecture and pure domain authorization policies (RBAC/ABAC) with AuthenticatedActor contract",
157
+ dependencies: [],
158
+ directoryName: "auth-rbac-policies"
159
+ },
160
+ {
161
+ id: "controller-orchestration-queues",
162
+ name: "Controller Orchestration & Queue Adapters",
163
+ description: "Strict orchestration rules for Controllers, atomic Actions, DB Transactions, and background Queue Adapters (Cloudflare, BullMQ, SQS)",
164
+ dependencies: [],
165
+ directoryName: "controller-orchestration-queues"
166
+ },
167
+ {
168
+ id: "webhook-idempotency",
169
+ name: "Webhook Verifiers & Idempotency Guards",
170
+ description: "Incoming webhook HMAC verification adapters and atomic idempotency guards guaranteeing at-most-once processing",
171
+ dependencies: [],
172
+ directoryName: "webhook-idempotency"
173
+ },
174
+ {
175
+ id: "caching-rate-limiting",
176
+ name: "Cache-Aside & Rate Limiting Adapters",
177
+ description: "Cache-aside remember wrapper and interchangeable sliding-window rate limiter adapters (Redis, Cloudflare KV, In-Memory)",
178
+ dependencies: [],
179
+ directoryName: "caching-rate-limiting"
180
+ },
181
+ {
182
+ id: "env-feature-flags",
183
+ name: "Fail-Fast Env & Feature Flags Adapters",
184
+ description: "Fail-fast environment schema validation with Valibot and decoupled feature flags adapters (PostHog, LaunchDarkly, Unleash)",
185
+ dependencies: [],
186
+ directoryName: "env-feature-flags"
187
+ },
139
188
  {
140
189
  id: "testing-vitest",
141
190
  name: "Vitest Testing Standards",
@@ -195,7 +244,14 @@ function detectProjectContext(targetPath) {
195
244
  "best-practices",
196
245
  "ux-writing",
197
246
  "error-handling-logging",
198
- "clean-architecture-ddd"
247
+ "clean-architecture-ddd",
248
+ "external-service-adapters",
249
+ "storage-file-adapters",
250
+ "auth-rbac-policies",
251
+ "controller-orchestration-queues",
252
+ "webhook-idempotency",
253
+ "caching-rate-limiting",
254
+ "env-feature-flags"
199
255
  ];
200
256
  for (const skill of SKILL_CATALOG) {
201
257
  if (skill.dependencies.length === 0) {
@@ -221,7 +277,7 @@ function detectProjectContext(targetPath) {
221
277
 
222
278
  // src/domains/ui/ui-orchestrator.ts
223
279
  import * as p5 from "@clack/prompts";
224
- import pc2 from "picocolors";
280
+ import pc3 from "picocolors";
225
281
 
226
282
  // src/domains/ui/banners.ts
227
283
  import pc from "picocolors";
@@ -558,31 +614,41 @@ var SUPPORTED_LANGUAGES = {
558
614
  code: "es",
559
615
  name: "Spanish",
560
616
  nativeName: "Espa\xF1ol",
561
- instruction: "Todos los mensajes, validaciones, errores, CTAs y comunicaciones con el usuario deben redactarse estrictamente en Espa\xF1ol. El tono debe ser emp\xE1tico, amable, persuasivo y profesional."
617
+ instruction: "Todos los mensajes, validaciones, errores, CTAs y comunicaciones con el usuario deben redactarse estrictamente en Espa\xF1ol. El tono debe ser emp\xE1tico, amable, persuasivo y profesional.",
618
+ onboardingPromptTitle: "Prompt de inicializaci\xF3n para tu Agente IA (Copia y pega en el chat):",
619
+ 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\xEDos de arquitectura, aclarar objetivos y adaptar el proyecto a mis necesidades antes de continuar."
562
620
  },
563
621
  en: {
564
622
  code: "en",
565
623
  name: "English",
566
624
  nativeName: "English",
567
- 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."
625
+ 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.",
626
+ onboardingPromptTitle: "Initialization prompt for your AI Agent (Copy and paste into your chat):",
627
+ 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."
568
628
  },
569
629
  pt: {
570
630
  code: "pt",
571
631
  name: "Portuguese",
572
632
  nativeName: "Portugu\xEAs",
573
- instruction: "Todas as mensagens, valida\xE7\xF5es, erros, CTAs e comunica\xE7\xF5es voltadas para o usu\xE1rio devem ser redigidas estritamente em Portugu\xEAs. O tom deve ser emp\xE1tico, amig\xE1vel, persuasivo e profissional."
633
+ instruction: "Todas as mensagens, valida\xE7\xF5es, erros, CTAs e comunica\xE7\xF5es voltadas para o usu\xE1rio devem ser redigidas estritamente em Portugu\xEAs. O tom deve ser emp\xE1tico, amig\xE1vel, persuasivo e profissional.",
634
+ onboardingPromptTitle: "Prompt de inicializa\xE7\xE3o para o seu Agente de IA (Copie e cole no chat):",
635
+ onboardingPrompt: "Ol\xE1. 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\xE7a-me perguntas interativas passo a passo para mapear lacunas de arquitetura, alinhar prioridades e adaptar o projeto \xE0s minhas necessidades antes de prosseguir."
574
636
  },
575
637
  it: {
576
638
  code: "it",
577
639
  name: "Italian",
578
640
  nativeName: "Italiano",
579
- 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."
641
+ 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.",
642
+ onboardingPromptTitle: "Prompt di inizializzazione per il tuo Agente AI (Copia e incolla nella chat):",
643
+ 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\xE0 e adattare il progetto alle mie esigenze prima di continuare."
580
644
  },
581
645
  fr: {
582
646
  code: "fr",
583
647
  name: "French",
584
648
  nativeName: "Fran\xE7ais",
585
- instruction: "Tous les messages, validations, erreurs, boutons d'appel \xE0 l'action (CTA) et notifications destin\xE9s \xE0 l'utilisateur doivent \xEAtre r\xE9dig\xE9s strictement en Fran\xE7ais. Le ton doit \xEAtre empathique, courtois, persuasif et professionnel."
649
+ instruction: "Tous les messages, validations, erreurs, boutons d'appel \xE0 l'action (CTA) et notifications destin\xE9s \xE0 l'utilisateur doivent \xEAtre r\xE9dig\xE9s strictement en Fran\xE7ais. Le ton doit \xEAtre empathique, courtois, persuasif et professionnel.",
650
+ onboardingPromptTitle: "Prompt d'initialisation pour votre Agent IA (Copiez et collez dans le chat) :",
651
+ 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\xE9es dans `.agents/skills/`. Posez-moi des questions interactives \xE9tape par \xE9tape pour identifier les lacunes d'architecture, pr\xE9ciser les priorit\xE9s et adapter le projet \xE0 mes besoins avant de continuer."
586
652
  }
587
653
  };
588
654
 
@@ -664,20 +730,23 @@ createdAt: ${now}
664
730
  # 00 \u2014 Initial Project Onboarding & Architecture Exploration: ${projectName}
665
731
 
666
732
  ## Outcome Hypothesis
667
- By 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\` and validating the essential build/typecheck commands.
733
+ By 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.
668
734
 
669
735
  ## Scope
670
- - In scope: Inspect project manifests, entry points, directory conventions, and script execution.
671
- - Out of scope: Refactoring business logic or modifying functional code.
736
+ - In scope: Inspect project manifests, entry points, directory conventions, ask interactive alignment questions, and verify script execution.
737
+ - Out of scope: Refactoring business logic or modifying functional code before alignment.
672
738
 
673
739
  ## Checklist
674
740
  - [ ] Verify package manager and essential scripts (\`build\`, \`test\`, \`typecheck\`).
675
741
  - [ ] Map high-level module architecture and data flow in \`.grooveskills/memory/context.md\`.
742
+ - [ ] Ask the user step-by-step interactive questions to clarify goals, domain scope, and adapt project conventions.
743
+ - [ ] Document agreed technical decisions in \`.grooveskills/memory/decisions.md\`.
676
744
  - [ ] Verify test runner or static checks pass cleanly.
677
745
  - [ ] Switch status to \`completed\` once project context is fully verified.
678
746
 
679
747
  ## Evidence
680
748
  - Observed command runs and outputs during the initial onboarding pass.
749
+ - User answers to alignment questions captured in memory.
681
750
 
682
751
  ## Next
683
752
  - Once onboarding is marked completed, proceed with domain tasks following the 3-lane ODD protocol.
@@ -959,7 +1028,10 @@ function installHarness(options) {
959
1028
  language
960
1029
  );
961
1030
  createdFiles.push(...instructions);
962
- return createdFiles;
1031
+ return {
1032
+ createdFiles,
1033
+ onboardingInitialized: shouldWriteContext
1034
+ };
963
1035
  }
964
1036
 
965
1037
  // src/domains/harness/write-project-config.ts
@@ -1039,7 +1111,7 @@ async function installSkills(options) {
1039
1111
  createdFiles.push(...files);
1040
1112
  }
1041
1113
  }
1042
- const harnessFiles = installHarness({
1114
+ const harnessResult = installHarness({
1043
1115
  targetPath: options.targetPath,
1044
1116
  selectedAgents: options.selectedAgents,
1045
1117
  selectedSkillIds: skillsToInstall,
@@ -1047,7 +1119,7 @@ async function installSkills(options) {
1047
1119
  language: options.language,
1048
1120
  forceOnboarding: options.forceOnboarding
1049
1121
  });
1050
- createdFiles.push(...harnessFiles);
1122
+ createdFiles.push(...harnessResult.createdFiles);
1051
1123
  const configPath = writeProjectConfig(
1052
1124
  options.targetPath,
1053
1125
  skillsToInstall,
@@ -1060,11 +1132,32 @@ async function installSkills(options) {
1060
1132
  installedSkills: skillsToInstall,
1061
1133
  configuredAgents: options.selectedAgents,
1062
1134
  createdFiles,
1063
- harnessInitialized: true,
1135
+ harnessInitialized: harnessResult.onboardingInitialized,
1064
1136
  language: options.language
1065
1137
  };
1066
1138
  }
1067
1139
 
1140
+ // src/domains/ui/render-onboarding-prompt.ts
1141
+ import pc2 from "picocolors";
1142
+ function formatOnboardingPrompt(language = "es") {
1143
+ const langConfig = SUPPORTED_LANGUAGES[language] ?? SUPPORTED_LANGUAGES.es;
1144
+ const title = langConfig.onboardingPromptTitle;
1145
+ const prompt = langConfig.onboardingPrompt;
1146
+ const separator = pc2.cyan("\u2500".repeat(60));
1147
+ const formattedOutput = [
1148
+ separator,
1149
+ pc2.bold(pc2.yellow(title)),
1150
+ "",
1151
+ pc2.green(prompt),
1152
+ separator
1153
+ ].join("\n");
1154
+ return {
1155
+ title,
1156
+ prompt,
1157
+ formattedOutput
1158
+ };
1159
+ }
1160
+
1068
1161
  // src/domains/ui/ui-orchestrator.ts
1069
1162
  async function resolveLanguageSelection(harnessExists, configuredLanguage, forceOnboarding) {
1070
1163
  if (harnessExists && !forceOnboarding) {
@@ -1094,12 +1187,12 @@ async function resolveOverwriteConfirmation(targetPath, selectedSkills, selected
1094
1187
  }
1095
1188
  async function runInteractiveUi(context, forceOnboarding = false) {
1096
1189
  console.log(renderBanner());
1097
- p5.intro(pc2.magenta("Welcome to GrooveSkills! Let's tailor your AI agents with clean architectural standards."));
1190
+ p5.intro(pc3.magenta("Welcome to GrooveSkills! Let's tailor your AI agents with clean architectural standards."));
1098
1191
  if (context.detectedDependencies.length > 0) {
1099
- const harnessInfo = context.harnessExists && !forceOnboarding ? pc2.green(`Active (.grooveskills/memory, lang: ${context.configuredLanguage ?? "es"})`) : pc2.cyan("Will be initialized");
1192
+ const harnessInfo = context.harnessExists && !forceOnboarding ? pc3.green(`Active (.grooveskills/memory, lang: ${context.configuredLanguage ?? "es"})`) : pc3.cyan("Will be initialized");
1100
1193
  p5.note(
1101
- `Detected dependencies: ${context.detectedDependencies.map((d) => pc2.bold(d)).join(", ")}
1102
- Active AI folders: ${context.detectedAgents.map((a) => pc2.green(a)).join(", ") || "None (will be created)"}
1194
+ `Detected dependencies: ${context.detectedDependencies.map((d) => pc3.bold(d)).join(", ")}
1195
+ Active AI folders: ${context.detectedAgents.map((a) => pc3.green(a)).join(", ") || "None (will be created)"}
1103
1196
  GrooveSkills Harness: ${harnessInfo}`,
1104
1197
  "Project Environment"
1105
1198
  );
@@ -1136,15 +1229,22 @@ GrooveSkills Harness: ${harnessInfo}`,
1136
1229
  language: selectedLanguage,
1137
1230
  forceOnboarding
1138
1231
  });
1139
- s.stop(pc2.green("All skills and harness have been successfully configured!"));
1140
- const harnessStatus = result.harnessInitialized ? pc2.green(`Initialized in .grooveskills/ (Language: ${selectedLanguage})`) : pc2.cyan(`Preserved in .grooveskills/ (Language: ${selectedLanguage})`);
1232
+ s.stop(pc3.green("All skills and harness have been successfully configured!"));
1233
+ const harnessStatus = result.harnessInitialized ? pc3.green(`Initialized in .grooveskills/ (Language: ${selectedLanguage})`) : pc3.cyan(`Preserved in .grooveskills/ (Language: ${selectedLanguage})`);
1141
1234
  p5.note(
1142
- `Configured skills: ${result.installedSkills.map((s2) => pc2.bold(s2)).join(", ")}
1143
- Target agents: ${result.configuredAgents.map((a) => pc2.cyan(a)).join(", ")}
1235
+ `Configured skills: ${result.installedSkills.map((s2) => pc3.bold(s2)).join(", ")}
1236
+ Target agents: ${result.configuredAgents.map((a) => pc3.cyan(a)).join(", ")}
1144
1237
  GrooveSkills Harness: ${harnessStatus}`,
1145
1238
  "Installation Summary"
1146
1239
  );
1147
- p5.outro(pc2.green("Your AI programming pair is now empowered with your team's architectural habits! \u{1F680}"));
1240
+ if (result.harnessInitialized) {
1241
+ const promptRender = formatOnboardingPrompt(selectedLanguage);
1242
+ p5.note(
1243
+ pc3.green(promptRender.prompt),
1244
+ promptRender.title
1245
+ );
1246
+ }
1247
+ p5.outro(pc3.green("Your AI programming pair is now empowered with your team's architectural habits! \u{1F680}"));
1148
1248
  }
1149
1249
 
1150
1250
  // src/main.ts
@@ -1157,7 +1257,7 @@ async function runGrooveSkills(options = {}) {
1157
1257
  const isDirectInit = Boolean(options.forceOnboarding) && hasAgents;
1158
1258
  if (hasSkills && hasAgents || isDirectHarness || isDirectInit) {
1159
1259
  const language = options.language ?? context.configuredLanguage ?? "es";
1160
- await installSkills({
1260
+ const result = await installSkills({
1161
1261
  targetPath,
1162
1262
  selectedSkillIds: options.skills || [],
1163
1263
  selectedAgents: options.agents || [],
@@ -1167,6 +1267,12 @@ async function runGrooveSkills(options = {}) {
1167
1267
  language,
1168
1268
  forceOnboarding: options.forceOnboarding
1169
1269
  });
1270
+ if (result.harnessInitialized) {
1271
+ const promptRender = formatOnboardingPrompt(language);
1272
+ console.log(`
1273
+ ${promptRender.formattedOutput}
1274
+ `);
1275
+ }
1170
1276
  return;
1171
1277
  }
1172
1278
  await runInteractiveUi(context, Boolean(options.forceOnboarding));
@@ -1175,4 +1281,4 @@ async function runGrooveSkills(options = {}) {
1175
1281
  export {
1176
1282
  runGrooveSkills
1177
1283
  };
1178
- //# sourceMappingURL=chunk-PLMYUKGW.js.map
1284
+ //# sourceMappingURL=chunk-HUG3MG3P.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../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/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/ui/render-onboarding-prompt.ts","../src/main.ts"],"sourcesContent":["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 \"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((dep) => dependencies.includes(dep));\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 dep of Object.keys(parsed.dependencies ?? {})) {\n detected.add(dep);\n }\n for (const dep of Object.keys(parsed.devDependencies ?? {})) {\n detected.add(dep);\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: \"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 p from \"@clack/prompts\";\nimport pc 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 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 langChoice = await promptLanguage(configuredLanguage ?? \"es\");\n if (p.isCancel(langChoice)) {\n p.cancel(\"Installation cancelled. Have a wonderful day!\");\n process.exit(0);\n }\n\n return langChoice 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 meta = SKILL_CATALOG.find((s) => s.id === skillId);\n return meta ? verifySkillExists(targetPath, meta.directoryName, selectedAgents) : false;\n });\n\n if (!anyExists) {\n return true;\n }\n\n const confirm = await promptConfirmOverwrite();\n if (p.isCancel(confirm) || !confirm) {\n p.cancel(\"Installation stopped to protect existing skills.\");\n process.exit(0);\n }\n\n return Boolean(confirm);\n}\n\nexport async function runInteractiveUi(\n context: ProjectContext,\n forceOnboarding: boolean = false\n): Promise<void> {\n console.log(renderBanner());\n p.intro(pc.magenta(\"Welcome to GrooveSkills! Let's tailor your AI agents with clean architectural standards.\"));\n\n if (context.detectedDependencies.length > 0) {\n const harnessInfo = context.harnessExists && !forceOnboarding\n ? pc.green(`Active (.grooveskills/memory, lang: ${context.configuredLanguage ?? \"es\"})`)\n : pc.cyan(\"Will be initialized\");\n\n p.note(\n `Detected dependencies: ${context.detectedDependencies.map((d) => pc.bold(d)).join(\", \")}\\n` +\n `Active AI folders: ${context.detectedAgents.map((a) => pc.green(a)).join(\", \") || \"None (will be created)\"}\\n` +\n `GrooveSkills Harness: ${harnessInfo}`,\n \"Project Environment\"\n );\n }\n\n const selectedSkills = await promptSkills(context.suggestedSkillIds);\n if (p.isCancel(selectedSkills)) {\n p.cancel(\"Installation cancelled. Have a wonderful day!\");\n process.exit(0);\n }\n\n const selectedAgents = await promptAgents(context.detectedAgents);\n if (p.isCancel(selectedAgents)) {\n p.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 s = p.spinner();\n s.start(\"Installing and adapting skills across your configured AI agents...\");\n\n const result = 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 s.stop(pc.green(\"All skills and harness have been successfully configured!\"));\n\n const harnessStatus = result.harnessInitialized\n ? pc.green(`Initialized in .grooveskills/ (Language: ${selectedLanguage})`)\n : pc.cyan(`Preserved in .grooveskills/ (Language: ${selectedLanguage})`);\n\n p.note(\n `Configured skills: ${result.installedSkills.map((s) => pc.bold(s)).join(\", \")}\\n` +\n `Target agents: ${result.configuredAgents.map((a) => pc.cyan(a)).join(\", \")}\\n` +\n `GrooveSkills Harness: ${harnessStatus}`,\n \"Installation Summary\"\n );\n\n if (result.harnessInitialized) {\n const promptRender = formatOnboardingPrompt(selectedLanguage);\n p.note(\n pc.green(promptRender.prompt),\n promptRender.title\n );\n }\n\n p.outro(pc.green(\"Your AI programming pair is now empowered with your team's architectural habits! 🚀\"));\n}\n","import pc from \"picocolors\";\n\nexport function renderBanner(): string {\n const title = pc.bold(pc.white(\" GROOVE SKILLS \"));\n const badge = pc.bgMagenta(pc.black(title));\n const subtitle = pc.dim(\"Multi-Agent AI Skills & Architectural Standards\");\n\n return `${badge} ${subtitle}\\n`;\n}\n","import * as p 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 p.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 p 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 p.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 p from \"@clack/prompts\";\nimport type { ProjectLanguage } from \"@/types/harness.types\";\n\nexport async function promptLanguage(defaultLanguage: ProjectLanguage = \"es\"): Promise<ProjectLanguage | symbol> {\n const options = [\n { value: \"es\", label: \"Español (Spanish)\", hint: \"Recomendado para proyectos en español\" },\n { value: \"en\", label: \"English\", hint: \"Standard international English\" },\n { value: \"pt\", label: \"Português (Portuguese)\", hint: \"Português para o Brasil e Portugal\" },\n { value: \"it\", label: \"Italiano (Italian)\", hint: \"Comunicazione in lingua italiana\" },\n { value: \"fr\", label: \"Français (French)\", hint: \"Communication en langue française\" },\n ];\n\n const selected = await p.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 p from \"@clack/prompts\";\n\nexport async function promptConfirmOverwrite(): Promise<boolean | symbol> {\n return await p.confirm({\n message: \"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, (dir: string) => string> = {\n antigravity: (dir) => join(\".agents\", \"skills\", dir),\n claude: (dir) => join(\".claude\", \"skills\", dir),\n cursor: (dir) => join(\".cursor\", \"rules\", `${dir}.mdc`),\n gemini: (dir) => join(\".gemini\", \"skills\", dir),\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 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\nexport async function installSkills(options: InstallOptions): Promise<InstallResult> {\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 syncProjectStore(options.targetPath, skillsToInstall, options.selectedAgents);\n\n const projectSkillsDir = getProjectSkillsDir(options.targetPath);\n const createdFiles: string[] = [];\n\n for (const skillId of skillsToInstall) {\n const skill = SKILL_CATALOG.find((item) => item.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(options.targetPath, skill, skillSourceDir);\n createdFiles.push(...files);\n }\n }\n\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 });\n createdFiles.push(...harnessResult.createdFiles);\n\n const configPath = writeProjectConfig(\n options.targetPath,\n skillsToInstall,\n options.selectedAgents,\n true,\n options.language\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 };\n}\n","import { existsSync, lstatSync, mkdirSync, readFileSync, rmSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getProjectSkillsDir } from \"@/domains/project-store/project-paths\";\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): string {\n const agentSkillFolder = join(targetPath, agentRelativeSkillsDir, skill.directoryName);\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 const targetFile = join(agentSkillFolder, \"SKILL.md\");\n writeFileSync(targetFile, referenceContent, \"utf-8\");\n\n return targetFile;\n}\n\nexport function writeCursorRuleReference(\n targetPath: string,\n cursorRelativeRulesDir: string,\n skill: SkillMetadata\n): string {\n const rulesDir = join(targetPath, cursorRelativeRulesDir);\n if (!existsSync(rulesDir)) {\n mkdirSync(rulesDir, { recursive: true });\n }\n\n const targetFile = join(rulesDir, `${skill.id}.mdc`);\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 writeFileSync(targetFile, referenceContent, \"utf-8\");\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 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 ): Promise<string[]> {\n const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill);\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 ): Promise<string[]> {\n const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill);\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 ): Promise<string[]> {\n const file = writeCursorRuleReference(targetPath, this.targetRelativeDir, skill);\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 ): Promise<string[]> {\n const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill);\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 { AgentId } from \"@/types/agent.types\";\n\nexport function syncProjectStore(\n targetPath: string,\n selectedSkillIds: string[],\n _selectedAgents: AgentId[]\n): void {\n const bundledSkillsDir = resolveSkillsSourceRoot();\n const projectSkillsDir = getProjectSkillsDir(targetPath);\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 (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 i = 0; i < 5; i++) {\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, writeFileSync } 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 type {\n HarnessInstallOptions,\n HarnessInstallResult,\n} from \"@/types/harness.types\";\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\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 writeFileSync(contextPath, contextContent, \"utf-8\");\n createdFiles.push(contextPath);\n\n const onboardingTaskPath = join(tasksDir, \"00-onboarding.md\");\n writeFileSync(\n onboardingTaskPath,\n buildOnboardingTaskTemplate(profile.projectName),\n \"utf-8\"\n );\n createdFiles.push(onboardingTaskPath);\n }\n\n const decisionsPath = join(memoryDir, \"decisions.md\");\n if (!existsSync(decisionsPath)) {\n writeFileSync(decisionsPath, buildDecisionsTemplate(language), \"utf-8\");\n createdFiles.push(decisionsPath);\n }\n\n const templateTaskPath = join(tasksDir, \"_template.md\");\n if (!existsSync(templateTaskPath)) {\n writeFileSync(templateTaskPath, buildTaskTemplate(), \"utf-8\");\n createdFiles.push(templateTaskPath);\n }\n\n const instructions = upsertAgentInstructions(\n options.targetPath,\n options.selectedAgents,\n language\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 depsFormatted = detectedDependencies.length > 0\n ? detectedDependencies.map((d) => `- \\`${d}\\``).join(\"\\n\")\n : \"- (No external dependencies detected)\";\n\n const langConfig = SUPPORTED_LANGUAGES[language];\n const projectName = profile?.projectName ?? \"Project\";\n const pkgManager = profile?.packageManager ?? \"npm\";\n\n const commandLines: string[] = [];\n if (profile?.commands) {\n for (const [key, cmd] of Object.entries(profile.commands)) {\n commandLines.push(`- **${key}**: \\`${cmd}\\``);\n }\n }\n const commandsSection = 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 [alias, target] of Object.entries(profile.pathAliases)) {\n aliasLines.push(`- \\`${alias}\\` -> \\`${target}\\``);\n }\n }\n const aliasesSection = aliasLines.length > 0\n ? `\\n### Path Aliases\\n${aliasLines.join(\"\\n\")}\\n`\n : \"\";\n\n const dirLines: string[] = [];\n if (profile?.sourceDirectories && profile.sourceDirectories.length > 0) {\n for (const dir of profile.sourceDirectories) {\n dirLines.push(`- \\`${dir}/\\``);\n }\n }\n const dirsSection = dirLines.length > 0\n ? `\\n### Source Modules\\n${dirLines.join(\"\\n\")}\\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**: \\`${pkgManager}\\`\n${depsFormatted}\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}${dirsSection}\n## 3. Communication & User Copy Language\n- **Configured Language**: ${langConfig.nativeName} (\\`${language}\\`).\n- **Policy**: ${langConfig.instruction}\n\n## 4. Essential Commands\n${commandsSection}\n`;\n}\n\nexport function buildDecisionsTemplate(language: ProjectLanguage = \"es\"): string {\n const now = new Date().toISOString().split(\"T\")[0];\n const langConfig = 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| ${now} | Adopt GrooveSkills Harness | Initialized \\`.grooveskills/\\` control plane with ODD | Clean, encapsulated agent memory, 3-lane ODD flow, and ${langConfig.nativeName} copy standard |\n`;\n}\n\nexport function buildOnboardingTaskTemplate(projectName: string = \"Project\"): string {\n const now = new Date().toISOString().split(\"T\")[0];\n\n return `---\nstatus: pending\ncreatedAt: ${now}\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 langConfig = 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 (${langConfig.nativeName})\n- **Language**: \\`${language}\\` (${langConfig.nativeName}).\n- **Requirement**: ${langConfig.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 pyRaw = readFileSync(pyprojectPath, \"utf-8\");\n const pyMatch = pyRaw.match(/name\\s*=\\s*\"([^\"]+)\"/);\n if (pyMatch?.[1]) {\n return pyMatch[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, pkgManager: 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 = pkgManager === \"npm\" ? \"npm run\" : pkgManager;\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 [key, targets] of Object.entries(paths)) {\n if (Array.isArray(targets) && typeof targets[0] === \"string\") {\n aliases[key] = targets[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, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { buildAgentHarnessBlock } from \"@/domains/harness/harness-templates\";\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 applyHarnessBlock(filePath: string, language: ProjectLanguage = \"es\"): void {\n const block = buildAgentHarnessBlock(language);\n\n if (!existsSync(filePath)) {\n writeFileSync(filePath, `${block}\\n`, \"utf-8\");\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 writeFileSync(filePath, updated, \"utf-8\");\n return;\n }\n\n const separator = existingContent.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n writeFileSync(filePath, `${existingContent}${separator}${block}\\n`, \"utf-8\");\n}\n\nexport function upsertAgentInstructions(\n targetPath: string,\n selectedAgents: AgentId[],\n language: ProjectLanguage = \"es\"\n): string[] {\n const updatedFiles: string[] = [];\n\n const agentsMdPath = join(targetPath, \"AGENTS.md\");\n applyHarnessBlock(agentsMdPath, language);\n updatedFiles.push(agentsMdPath);\n\n if (selectedAgents.includes(\"claude\")) {\n const claudeMdPath = join(targetPath, \"CLAUDE.md\");\n applyHarnessBlock(claudeMdPath, language);\n updatedFiles.push(claudeMdPath);\n }\n\n return updatedFiles;\n}\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { getProjectConfigPath } from \"@/domains/project-store/project-paths\";\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): string {\n const configPath = getProjectConfigPath(targetPath);\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 writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\\n`, \"utf-8\");\n\n return configPath;\n}\n","import pc 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 langConfig = SUPPORTED_LANGUAGES[language] ?? SUPPORTED_LANGUAGES.es;\n const title = langConfig.onboardingPromptTitle;\n const prompt = langConfig.onboardingPrompt;\n\n const separator = pc.cyan(\"─\".repeat(60));\n const formattedOutput = [\n separator,\n pc.bold(pc.yellow(title)),\n \"\",\n pc.green(prompt),\n separator,\n ].join(\"\\n\");\n\n return {\n title,\n prompt,\n formattedOutput,\n };\n}\n","import { 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 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\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.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"],"mappings":"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","names":["existsSync","readFileSync","join","join","existsSync","readFileSync","p","pc","p","p","p","join","join","existsSync","lstatSync","readFileSync","join","join","existsSync","lstatSync","readFileSync","join","existsSync","mkdirSync","rmSync","join","join","existsSync","existsSync","mkdirSync","join","rmSync","existsSync","mkdirSync","writeFileSync","join","existsSync","readdirSync","readFileSync","join","existsSync","readFileSync","writeFileSync","join","existsSync","writeFileSync","readFileSync","join","existsSync","mkdirSync","join","writeFileSync","existsSync","readFileSync","writeFileSync","existsSync","readFileSync","writeFileSync","join","pc","pc","confirm","pc","s"]}
package/dist/cli.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runGrooveSkills
4
- } from "./chunk-PLMYUKGW.js";
4
+ } from "./chunk-HUG3MG3P.js";
5
5
 
6
6
  // bin/cli.ts
7
7
  import { Command } from "commander";
8
8
  var program = new Command();
9
- program.name("grooveskills").description("Multi-agent AI skills, ODD workflow, and persistent project harness installer").version("1.5.0").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) => {
9
+ program.name("grooveskills").description("Multi-agent AI skills, ODD workflow, and persistent project harness installer").version("1.6.0").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) => {
10
10
  try {
11
11
  const forceOnboarding = command === "init";
12
12
  await runGrooveSkills({
package/dist/main.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runGrooveSkills
3
- } from "./chunk-PLMYUKGW.js";
3
+ } from "./chunk-HUG3MG3P.js";
4
4
  export {
5
5
  runGrooveSkills
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@3lineas/grooveskills",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Multi-agent CLI to install opinionated AI coding skills and architectural standards (Hono, React, Next.js, and more)",
5
5
  "type": "module",
6
6
  "bin": {