@3lineas/grooveskills 1.3.1 → 1.4.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
@@ -67,7 +67,7 @@ Through the built-in `odd-ai` and `groove-harness` skills, GrooveSkills guides y
67
67
  Select your preferred language (**Español, English, Português, Italiano, or Français**) during setup so every validation message, toast, and agent interaction remains warm, persuasive, and professional.
68
68
 
69
69
  ### 5. Clean & 100% Portable Repository Layout
70
- All assets reside in `.grooveskills/` and connect to agent directories via **relative symlinks** (`../../.grooveskills/...`), making the environment instantly portable upon `git clone`.
70
+ All canonical skills and project memory reside in `.grooveskills/`. Agent directories (`.agents/`, `.claude/`, `.gemini/`, `.cursor/`) contain **lightweight reference files** that preserve original trigger metadata and instruct each AI agent to consult the canonical specification in `.grooveskills/skills/<skill>/SKILL.md`.
71
71
 
72
72
  ---
73
73
 
@@ -80,11 +80,11 @@ npx @3lineas/grooveskills
80
80
 
81
81
  ### Non-Interactive Mode (CI & Scripting)
82
82
  ```bash
83
- # Install skills and initialize harness in Spanish for Claude and Antigravity
84
- npx @3lineas/grooveskills --skills odd-ai best-practices hono --agents antigravity claude --harness -l es -y
83
+ # Install skills and configure harness in Spanish for Claude and Antigravity
84
+ npx @3lineas/grooveskills --skills odd-ai best-practices hono --agents antigravity claude -l es -y
85
85
 
86
- # Initialize harness across all supported AI assistants
87
- npx @3lineas/grooveskills --harness --agents antigravity claude cursor gemini -l es -y
86
+ # Configure harness and skills across all supported AI assistants
87
+ npx @3lineas/grooveskills --agents antigravity claude cursor gemini -l es -y
88
88
  ```
89
89
 
90
90
  ### CLI Options Reference
@@ -93,10 +93,9 @@ npx @3lineas/grooveskills --harness --agents antigravity claude cursor gemini -l
93
93
  | :--- | :--- | :--- |
94
94
  | `-s, --skills <skills...>` | Space-separated list of skill IDs to install | `--skills odd-ai best-practices` |
95
95
  | `-a, --agents <agents...>` | Target AI assistants (`antigravity`, `claude`, `cursor`, `gemini`) | `--agents antigravity cursor` |
96
- | `--harness` | Initialize or update the GrooveSkills Harness in `.grooveskills/` | `--harness` |
97
- | `--no-harness` | Install selected skills without initializing the project harness | `--no-harness` |
96
+ | `--harness` | Initialize or update GrooveSkills project harness in `.grooveskills/` | `--harness` |
98
97
  | `-l, --language <lang>` | Set the language for user-facing copy (`es`, `en`, `pt`, `it`, `fr`) | `-l es` |
99
- | `-y, --yes` | Automatically confirm updating existing skill links | `-y` |
98
+ | `-y, --yes` | Automatically confirm updating existing skills | `-y` |
100
99
 
101
100
  ---
102
101
 
@@ -106,15 +105,15 @@ npx @3lineas/grooveskills --harness --agents antigravity claude cursor gemini -l
106
105
  my-project/
107
106
  ├── .grooveskills/
108
107
  │ ├── config.json # Manifest of active skills, agents, language & harness state
109
- │ ├── skills/ # Self-contained copy of installed skills
110
- │ ├── cursor-rules/ # Generated .mdc rules (when Cursor IDE is selected)
111
- │ └── memory/ # Persistent project memory (when Harness is enabled)
108
+ │ ├── skills/ # Canonical single source of truth for installed skills
109
+ │ └── memory/ # Persistent project memory (Harness control plane)
112
110
  │ ├── context.md # Stack overview, conventions & essential commands
113
111
  │ ├── decisions.md # Architecture Decision Records (ADR)
114
112
  │ └── tasks/ # Tasks with Outcome Hypotheses & Evidence receipts
115
- ├── .agents/skills/* # Relative symlinks -> ../../.grooveskills/skills/*
116
- ├── .claude/skills/* # Relative symlinks -> ../../.grooveskills/skills/*
117
- ├── .cursor/rules/*.mdc # Relative symlinks -> ../../.grooveskills/cursor-rules/*.mdc
113
+ ├── .agents/skills/<skill>/SKILL.md # Lightweight reference pointer -> .grooveskills/skills/<skill>/SKILL.md
114
+ ├── .claude/skills/<skill>/SKILL.md # Lightweight reference pointer -> .grooveskills/skills/<skill>/SKILL.md
115
+ ├── .gemini/skills/<skill>/SKILL.md # Lightweight reference pointer -> .grooveskills/skills/<skill>/SKILL.md
116
+ ├── .cursor/rules/<skill>.mdc # Lightweight reference rule -> .grooveskills/skills/<skill>/SKILL.md
118
117
  └── AGENTS.md / CLAUDE.md # Concise harness pointer <!-- grooveskills:harness -->
119
118
  ```
120
119
 
@@ -1,5 +1,5 @@
1
1
  // src/domains/detector/project-detector.ts
2
- import { existsSync as existsSync2 } from "fs";
2
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
3
3
  import { join as join2 } from "path";
4
4
 
5
5
  // src/domains/detector/detect-agents.ts
@@ -173,6 +173,19 @@ var SKILL_CATALOG = [
173
173
  ];
174
174
 
175
175
  // src/domains/detector/project-detector.ts
176
+ function readConfiguredLanguage(targetPath) {
177
+ const configPath = join2(targetPath, ".grooveskills", "config.json");
178
+ if (!existsSync2(configPath)) {
179
+ return void 0;
180
+ }
181
+ try {
182
+ const raw = readFileSync2(configPath, "utf-8");
183
+ const parsed = JSON.parse(raw);
184
+ return typeof parsed.language === "string" ? parsed.language : void 0;
185
+ } catch {
186
+ return void 0;
187
+ }
188
+ }
176
189
  function detectProjectContext(targetPath) {
177
190
  const detectedAgents = detectAgents(targetPath);
178
191
  const { dependencies, exists } = detectDependencies(targetPath);
@@ -193,18 +206,20 @@ function detectProjectContext(targetPath) {
193
206
  }
194
207
  }
195
208
  const harnessExists = existsSync2(join2(targetPath, ".grooveskills", "memory", "context.md"));
209
+ const configuredLanguage = readConfiguredLanguage(targetPath);
196
210
  return {
197
211
  targetPath,
198
212
  detectedDependencies: dependencies,
199
213
  suggestedSkillIds,
200
214
  detectedAgents,
201
215
  packageJsonExists: exists,
202
- harnessExists
216
+ harnessExists,
217
+ configuredLanguage
203
218
  };
204
219
  }
205
220
 
206
221
  // src/domains/ui/ui-orchestrator.ts
207
- import * as p6 from "@clack/prompts";
222
+ import * as p5 from "@clack/prompts";
208
223
  import pc2 from "picocolors";
209
224
 
210
225
  // src/domains/ui/banners.ts
@@ -256,19 +271,8 @@ async function promptAgents(detectedAgents) {
256
271
  return selected;
257
272
  }
258
273
 
259
- // src/domains/ui/prompt-harness.ts
260
- import * as p3 from "@clack/prompts";
261
- async function promptHarness(harnessExists) {
262
- const message = harnessExists ? "GrooveSkills Harness is already initialized. Would you like to update agent rules and memory templates?" : "Would you like to initialize the GrooveSkills Harness in .grooveskills/ (project memory, ADR, and 3-lane task execution)?";
263
- const confirm3 = await p3.confirm({
264
- message,
265
- initialValue: true
266
- });
267
- return confirm3;
268
- }
269
-
270
274
  // src/domains/ui/prompt-language.ts
271
- import * as p4 from "@clack/prompts";
275
+ import * as p3 from "@clack/prompts";
272
276
  async function promptLanguage(defaultLanguage = "es") {
273
277
  const options = [
274
278
  { value: "es", label: "Espa\xF1ol (Spanish)", hint: "Recomendado para proyectos en espa\xF1ol" },
@@ -277,7 +281,7 @@ async function promptLanguage(defaultLanguage = "es") {
277
281
  { value: "it", label: "Italiano (Italian)", hint: "Comunicazione in lingua italiana" },
278
282
  { value: "fr", label: "Fran\xE7ais (French)", hint: "Communication en langue fran\xE7aise" }
279
283
  ];
280
- const selected = await p4.select({
284
+ const selected = await p3.select({
281
285
  message: "Which language should AI agents use for user-facing copy and communication?",
282
286
  options,
283
287
  initialValue: defaultLanguage
@@ -286,9 +290,9 @@ async function promptLanguage(defaultLanguage = "es") {
286
290
  }
287
291
 
288
292
  // src/domains/ui/prompt-confirm-overwrite.ts
289
- import * as p5 from "@clack/prompts";
293
+ import * as p4 from "@clack/prompts";
290
294
  async function promptConfirmOverwrite() {
291
- return await p5.confirm({
295
+ return await p4.confirm({
292
296
  message: "Some skills already exist in this project. Would you like to overwrite them with the latest version?",
293
297
  initialValue: true
294
298
  });
@@ -317,10 +321,10 @@ function verifySkillExists(targetPath, skillDirectoryName, agents) {
317
321
  }
318
322
 
319
323
  // src/domains/installer/install-orchestrator.ts
320
- import { join as join13 } from "path";
324
+ import { join as join10 } from "path";
321
325
 
322
- // src/domains/adapters/antigravity.adapter.ts
323
- import { mkdirSync, existsSync as existsSync3 } from "fs";
326
+ // src/domains/adapters/skill-reference-builder.ts
327
+ import { existsSync as existsSync3, lstatSync as lstatSync2, mkdirSync, readFileSync as readFileSync3, rmSync, unlinkSync, writeFileSync } from "fs";
324
328
  import { join as join5 } from "path";
325
329
 
326
330
  // src/domains/project-store/project-paths.ts
@@ -331,9 +335,6 @@ function getProjectStoreDir(targetPath) {
331
335
  function getProjectSkillsDir(targetPath) {
332
336
  return join4(getProjectStoreDir(targetPath), "skills");
333
337
  }
334
- function getProjectCursorRulesDir(targetPath) {
335
- return join4(getProjectStoreDir(targetPath), "cursor-rules");
336
- }
337
338
  function getProjectMemoryDir(targetPath) {
338
339
  return join4(getProjectStoreDir(targetPath), "memory");
339
340
  }
@@ -344,13 +345,26 @@ function getProjectConfigPath(targetPath) {
344
345
  return join4(getProjectStoreDir(targetPath), "config.json");
345
346
  }
346
347
 
347
- // src/domains/adapters/link-helper.ts
348
- import { lstatSync as lstatSync2, unlinkSync, rmSync, symlinkSync } from "fs";
349
- import { dirname, relative } from "path";
350
- function removeExistingLinkPath(path) {
348
+ // src/domains/adapters/skill-reference-builder.ts
349
+ function removeExistingPathSafely(path) {
350
+ const fileExists = existsSync3(path);
351
+ if (!fileExists) {
352
+ try {
353
+ const lstat = lstatSync2(path);
354
+ if (lstat.isSymbolicLink()) {
355
+ unlinkSync(path);
356
+ }
357
+ } catch {
358
+ }
359
+ return;
360
+ }
351
361
  try {
352
362
  const lstat = lstatSync2(path);
353
- if (lstat.isDirectory() && !lstat.isSymbolicLink()) {
363
+ if (lstat.isSymbolicLink()) {
364
+ unlinkSync(path);
365
+ return;
366
+ }
367
+ if (lstat.isDirectory()) {
354
368
  rmSync(path, { recursive: true, force: true });
355
369
  return;
356
370
  }
@@ -358,11 +372,71 @@ function removeExistingLinkPath(path) {
358
372
  } catch {
359
373
  }
360
374
  }
361
- function createOrReplaceSymlink(target, linkPath, type) {
362
- removeExistingLinkPath(linkPath);
363
- const linkDir = dirname(linkPath);
364
- const relativeTarget = relative(linkDir, target);
365
- symlinkSync(relativeTarget, linkPath, type);
375
+ function extractSkillDescription(canonicalSkillMdPath, fallback) {
376
+ if (!existsSync3(canonicalSkillMdPath)) {
377
+ return fallback;
378
+ }
379
+ try {
380
+ const content = readFileSync3(canonicalSkillMdPath, "utf-8");
381
+ const match = content.match(/^description:\s*(.+)$/m);
382
+ const hasMatchedDesc = Boolean(match && match[1]);
383
+ if (hasMatchedDesc && match?.[1]) {
384
+ return match[1].trim();
385
+ }
386
+ } catch {
387
+ }
388
+ return fallback;
389
+ }
390
+ function writeAgentSkillReference(targetPath, agentRelativeSkillsDir, skill) {
391
+ const agentSkillFolder = join5(targetPath, agentRelativeSkillsDir, skill.directoryName);
392
+ removeExistingPathSafely(agentSkillFolder);
393
+ mkdirSync(agentSkillFolder, { recursive: true });
394
+ const canonicalSkillMd = join5(getProjectSkillsDir(targetPath), skill.directoryName, "SKILL.md");
395
+ const description = extractSkillDescription(canonicalSkillMd, skill.description);
396
+ const referenceContent = `---
397
+ name: ${skill.id}
398
+ description: ${description}
399
+ ---
400
+
401
+ # ${skill.name} \u2014 Skill Reference
402
+
403
+ Canonical skill specification stored in \`.grooveskills/\`.
404
+
405
+ - **Specification**: [\`.grooveskills/skills/${skill.directoryName}/SKILL.md\`](../../../.grooveskills/skills/${skill.directoryName}/SKILL.md)
406
+ - **References & Templates**: \`.grooveskills/skills/${skill.directoryName}/\`
407
+
408
+ > **Instruction**: Read \`.grooveskills/skills/${skill.directoryName}/SKILL.md\` before executing tasks matching this skill.
409
+ `;
410
+ const targetFile = join5(agentSkillFolder, "SKILL.md");
411
+ writeFileSync(targetFile, referenceContent, "utf-8");
412
+ return targetFile;
413
+ }
414
+ function writeCursorRuleReference(targetPath, cursorRelativeRulesDir, skill) {
415
+ const rulesDir = join5(targetPath, cursorRelativeRulesDir);
416
+ if (!existsSync3(rulesDir)) {
417
+ mkdirSync(rulesDir, { recursive: true });
418
+ }
419
+ const targetFile = join5(rulesDir, `${skill.id}.mdc`);
420
+ removeExistingPathSafely(targetFile);
421
+ const canonicalSkillMd = join5(getProjectSkillsDir(targetPath), skill.directoryName, "SKILL.md");
422
+ const description = extractSkillDescription(canonicalSkillMd, skill.description);
423
+ const referenceContent = `---
424
+ description: ${description}
425
+ globs: ["**/*"]
426
+ alwaysApply: false
427
+ ---
428
+
429
+ # ${skill.name} \u2014 Rule Reference
430
+
431
+ Canonical rule specification stored in \`.grooveskills/\`.
432
+
433
+ - **Specification**: \`.grooveskills/skills/${skill.directoryName}/SKILL.md\`
434
+ - **References & Templates**: \`.grooveskills/skills/${skill.directoryName}/\`
435
+
436
+ > **Instruction**: Read \`.grooveskills/skills/${skill.directoryName}/SKILL.md\` before executing tasks matching this rule.
437
+ `;
438
+ writeFileSync(targetFile, referenceContent, "utf-8");
439
+ return targetFile;
366
440
  }
367
441
 
368
442
  // src/domains/adapters/antigravity.adapter.ts
@@ -371,101 +445,70 @@ var AntigravityAdapter = class {
371
445
  name = "Antigravity";
372
446
  targetRelativeDir = ".agents/skills";
373
447
  async installSkill(targetPath, skill, _skillSourceDir) {
374
- const parentDir = join5(targetPath, this.targetRelativeDir);
375
- if (!existsSync3(parentDir)) {
376
- mkdirSync(parentDir, { recursive: true });
377
- }
378
- const destination = join5(parentDir, skill.directoryName);
379
- const projectSkillDir = join5(getProjectSkillsDir(targetPath), skill.directoryName);
380
- createOrReplaceSymlink(projectSkillDir, destination, "dir");
381
- return [destination];
448
+ const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill);
449
+ return [file];
382
450
  }
383
451
  };
384
452
 
385
453
  // src/domains/adapters/claude.adapter.ts
386
- import { mkdirSync as mkdirSync2, existsSync as existsSync4 } from "fs";
387
- import { join as join6 } from "path";
388
454
  var ClaudeAdapter = class {
389
455
  id = "claude";
390
456
  name = "Claude Code";
391
457
  targetRelativeDir = ".claude/skills";
392
458
  async installSkill(targetPath, skill, _skillSourceDir) {
393
- const parentDir = join6(targetPath, this.targetRelativeDir);
394
- if (!existsSync4(parentDir)) {
395
- mkdirSync2(parentDir, { recursive: true });
396
- }
397
- const destination = join6(parentDir, skill.directoryName);
398
- const projectSkillDir = join6(getProjectSkillsDir(targetPath), skill.directoryName);
399
- createOrReplaceSymlink(projectSkillDir, destination, "dir");
400
- return [destination];
459
+ const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill);
460
+ return [file];
401
461
  }
402
462
  };
403
463
 
404
464
  // src/domains/adapters/cursor.adapter.ts
405
- import { mkdirSync as mkdirSync3, existsSync as existsSync5 } from "fs";
406
- import { join as join7 } from "path";
407
465
  var CursorAdapter = class {
408
466
  id = "cursor";
409
467
  name = "Cursor";
410
468
  targetRelativeDir = ".cursor/rules";
411
469
  async installSkill(targetPath, skill, _skillSourceDir) {
412
- const rulesDir = join7(targetPath, this.targetRelativeDir);
413
- if (!existsSync5(rulesDir)) {
414
- mkdirSync3(rulesDir, { recursive: true });
415
- }
416
- const filename = `${skill.id}.mdc`;
417
- const destination = join7(rulesDir, filename);
418
- const projectRuleFile = join7(getProjectCursorRulesDir(targetPath), filename);
419
- createOrReplaceSymlink(projectRuleFile, destination, "file");
420
- return [destination];
470
+ const file = writeCursorRuleReference(targetPath, this.targetRelativeDir, skill);
471
+ return [file];
421
472
  }
422
473
  };
423
474
 
424
475
  // src/domains/adapters/gemini.adapter.ts
425
- import { mkdirSync as mkdirSync4, existsSync as existsSync6 } from "fs";
426
- import { join as join8 } from "path";
427
476
  var GeminiAdapter = class {
428
477
  id = "gemini";
429
478
  name = "Gemini Code Assist";
430
479
  targetRelativeDir = ".gemini/skills";
431
480
  async installSkill(targetPath, skill, _skillSourceDir) {
432
- const parentDir = join8(targetPath, this.targetRelativeDir);
433
- if (!existsSync6(parentDir)) {
434
- mkdirSync4(parentDir, { recursive: true });
435
- }
436
- const destination = join8(parentDir, skill.directoryName);
437
- const projectSkillDir = join8(getProjectSkillsDir(targetPath), skill.directoryName);
438
- createOrReplaceSymlink(projectSkillDir, destination, "dir");
439
- return [destination];
481
+ const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill);
482
+ return [file];
440
483
  }
441
484
  };
442
485
 
443
486
  // src/domains/project-store/sync-project-store.ts
444
- import { cpSync, mkdirSync as mkdirSync5, existsSync as existsSync8, writeFileSync, readFileSync as readFileSync2 } from "fs";
445
- import { join as join10 } from "path";
487
+ import { cpSync, existsSync as existsSync5, mkdirSync as mkdirSync2, rmSync as rmSync2 } from "fs";
488
+ import { join as join7 } from "path";
446
489
 
447
490
  // src/domains/installer/resolve-skills-source.ts
448
491
  import { fileURLToPath } from "url";
449
- import { dirname as dirname2, resolve, join as join9 } from "path";
450
- import { existsSync as existsSync7 } from "fs";
492
+ import { dirname, resolve, join as join6 } from "path";
493
+ import { existsSync as existsSync4 } from "fs";
451
494
  function resolveSkillsSourceRoot() {
452
495
  const currentFilePath = fileURLToPath(import.meta.url);
453
- const currentDir = dirname2(currentFilePath);
496
+ const currentDir = dirname(currentFilePath);
454
497
  const candidateFromDist = resolve(currentDir, "../skills");
455
- if (existsSync7(candidateFromDist)) {
498
+ if (existsSync4(candidateFromDist)) {
456
499
  return candidateFromDist;
457
500
  }
458
501
  const candidateFromSrc = resolve(currentDir, "../../../skills");
459
- if (existsSync7(candidateFromSrc)) {
502
+ if (existsSync4(candidateFromSrc)) {
460
503
  return candidateFromSrc;
461
504
  }
462
505
  let searchDir = currentDir;
463
506
  for (let i = 0; i < 5; i++) {
464
- const candidate = join9(searchDir, "skills");
465
- if (existsSync7(candidate)) {
507
+ const candidate = join6(searchDir, "skills");
508
+ if (existsSync4(candidate)) {
466
509
  return candidate;
467
510
  }
468
- const parent = dirname2(searchDir);
511
+ const parent = dirname(searchDir);
469
512
  if (parent === searchDir) {
470
513
  break;
471
514
  }
@@ -477,51 +520,35 @@ function resolveSkillsSourceRoot() {
477
520
  }
478
521
 
479
522
  // src/domains/project-store/sync-project-store.ts
480
- function syncProjectStore(targetPath, selectedSkillIds, selectedAgents) {
523
+ function syncProjectStore(targetPath, selectedSkillIds, _selectedAgents) {
481
524
  const bundledSkillsDir = resolveSkillsSourceRoot();
482
525
  const projectSkillsDir = getProjectSkillsDir(targetPath);
483
- const projectCursorRulesDir = getProjectCursorRulesDir(targetPath);
484
- if (!existsSync8(projectSkillsDir)) {
485
- mkdirSync5(projectSkillsDir, { recursive: true });
526
+ if (!existsSync5(projectSkillsDir)) {
527
+ mkdirSync2(projectSkillsDir, { recursive: true });
486
528
  }
487
- const needsCursorRules = selectedAgents.includes("cursor");
488
- if (needsCursorRules && !existsSync8(projectCursorRulesDir)) {
489
- mkdirSync5(projectCursorRulesDir, { recursive: true });
529
+ const legacyCursorRules = join7(targetPath, ".grooveskills", "cursor-rules");
530
+ if (existsSync5(legacyCursorRules)) {
531
+ try {
532
+ rmSync2(legacyCursorRules, { recursive: true, force: true });
533
+ } catch {
534
+ }
490
535
  }
491
536
  for (const skillId of selectedSkillIds) {
492
537
  const skill = SKILL_CATALOG.find((item) => item.id === skillId);
493
538
  if (!skill) {
494
539
  continue;
495
540
  }
496
- const sourceSkillDir = join10(bundledSkillsDir, skill.directoryName);
497
- const destSkillDir = join10(projectSkillsDir, skill.directoryName);
498
- if (existsSync8(sourceSkillDir)) {
541
+ const sourceSkillDir = join7(bundledSkillsDir, skill.directoryName);
542
+ const destSkillDir = join7(projectSkillsDir, skill.directoryName);
543
+ if (existsSync5(sourceSkillDir)) {
499
544
  cpSync(sourceSkillDir, destSkillDir, { recursive: true });
500
545
  }
501
- if (!needsCursorRules) {
502
- continue;
503
- }
504
- const skillMdPath = join10(destSkillDir, "SKILL.md");
505
- if (!existsSync8(skillMdPath)) {
506
- continue;
507
- }
508
- const content = readFileSync2(skillMdPath, "utf-8");
509
- const mdcHeader = `---
510
- description: ${skill.description}
511
- globs: ["**/*"]
512
- alwaysApply: false
513
- ---
514
-
515
- `;
516
- const cleanedBody = content.replace(/^---[\s\S]*?---\s*/, "");
517
- const targetMdc = join10(projectCursorRulesDir, `${skill.id}.mdc`);
518
- writeFileSync(targetMdc, `${mdcHeader}${cleanedBody}`, "utf-8");
519
546
  }
520
547
  }
521
548
 
522
549
  // src/domains/harness/install-harness.ts
523
- import { existsSync as existsSync10, mkdirSync as mkdirSync6, writeFileSync as writeFileSync3 } from "fs";
524
- import { join as join12 } from "path";
550
+ import { existsSync as existsSync7, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
551
+ import { join as join9 } from "path";
525
552
 
526
553
  // src/domains/harness/harness-languages.ts
527
554
  var SUPPORTED_LANGUAGES = {
@@ -647,18 +674,18 @@ This project uses the **GrooveSkills Harness** located in \`.grooveskills/\`.
647
674
  }
648
675
 
649
676
  // src/domains/harness/upsert-agent-instructions.ts
650
- import { existsSync as existsSync9, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
651
- import { join as join11 } from "path";
677
+ import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
678
+ import { join as join8 } from "path";
652
679
  var START_MARKER = "<!-- grooveskills:harness:start -->";
653
680
  var END_MARKER = "<!-- grooveskills:harness:end -->";
654
681
  function applyHarnessBlock(filePath, language = "es") {
655
682
  const block = buildAgentHarnessBlock(language);
656
- if (!existsSync9(filePath)) {
683
+ if (!existsSync6(filePath)) {
657
684
  writeFileSync2(filePath, `${block}
658
685
  `, "utf-8");
659
686
  return;
660
687
  }
661
- const existingContent = readFileSync3(filePath, "utf-8");
688
+ const existingContent = readFileSync4(filePath, "utf-8");
662
689
  if (existingContent.includes(START_MARKER) && existingContent.includes(END_MARKER)) {
663
690
  const regex = new RegExp(`${START_MARKER}[\\s\\S]*?${END_MARKER}`, "g");
664
691
  const updated = existingContent.replace(regex, block);
@@ -671,11 +698,11 @@ function applyHarnessBlock(filePath, language = "es") {
671
698
  }
672
699
  function upsertAgentInstructions(targetPath, selectedAgents, language = "es") {
673
700
  const updatedFiles = [];
674
- const agentsMdPath = join11(targetPath, "AGENTS.md");
701
+ const agentsMdPath = join8(targetPath, "AGENTS.md");
675
702
  applyHarnessBlock(agentsMdPath, language);
676
703
  updatedFiles.push(agentsMdPath);
677
704
  if (selectedAgents.includes("claude")) {
678
- const claudeMdPath = join11(targetPath, "CLAUDE.md");
705
+ const claudeMdPath = join8(targetPath, "CLAUDE.md");
679
706
  applyHarnessBlock(claudeMdPath, language);
680
707
  updatedFiles.push(claudeMdPath);
681
708
  }
@@ -687,22 +714,22 @@ function installHarness(options) {
687
714
  const memoryDir = getProjectMemoryDir(options.targetPath);
688
715
  const tasksDir = getProjectTasksDir(options.targetPath);
689
716
  const language = options.language ?? "es";
690
- if (!existsSync10(tasksDir)) {
691
- mkdirSync6(tasksDir, { recursive: true });
717
+ if (!existsSync7(tasksDir)) {
718
+ mkdirSync3(tasksDir, { recursive: true });
692
719
  }
693
720
  const createdFiles = [];
694
- const contextPath = join12(memoryDir, "context.md");
695
- if (!existsSync10(contextPath)) {
721
+ const contextPath = join9(memoryDir, "context.md");
722
+ if (!existsSync7(contextPath)) {
696
723
  writeFileSync3(contextPath, buildContextTemplate(options.detectedDependencies, language), "utf-8");
697
724
  createdFiles.push(contextPath);
698
725
  }
699
- const decisionsPath = join12(memoryDir, "decisions.md");
700
- if (!existsSync10(decisionsPath)) {
726
+ const decisionsPath = join9(memoryDir, "decisions.md");
727
+ if (!existsSync7(decisionsPath)) {
701
728
  writeFileSync3(decisionsPath, buildDecisionsTemplate(language), "utf-8");
702
729
  createdFiles.push(decisionsPath);
703
730
  }
704
- const templateTaskPath = join12(tasksDir, "_template.md");
705
- if (!existsSync10(templateTaskPath)) {
731
+ const templateTaskPath = join9(tasksDir, "_template.md");
732
+ if (!existsSync7(templateTaskPath)) {
706
733
  writeFileSync3(templateTaskPath, buildTaskTemplate(), "utf-8");
707
734
  createdFiles.push(templateTaskPath);
708
735
  }
@@ -712,18 +739,18 @@ function installHarness(options) {
712
739
  }
713
740
 
714
741
  // src/domains/harness/write-project-config.ts
715
- import { existsSync as existsSync11, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
742
+ import { existsSync as existsSync8, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
716
743
  function readExistingConfig(configPath) {
717
744
  const fallback = {
718
745
  skills: [],
719
746
  agents: [],
720
747
  harness: false
721
748
  };
722
- if (!existsSync11(configPath)) {
749
+ if (!existsSync8(configPath)) {
723
750
  return fallback;
724
751
  }
725
752
  try {
726
- const raw = readFileSync4(configPath, "utf-8");
753
+ const raw = readFileSync5(configPath, "utf-8");
727
754
  const parsed = JSON.parse(raw);
728
755
  return {
729
756
  skills: Array.isArray(parsed.skills) ? parsed.skills : [],
@@ -764,10 +791,10 @@ var ADAPTER_REGISTRY = {
764
791
  };
765
792
  async function installSkills(options) {
766
793
  const skillsToInstall = [...options.selectedSkillIds];
767
- if (options.enableHarness && !skillsToInstall.includes("groove-harness")) {
794
+ if (!skillsToInstall.includes("groove-harness")) {
768
795
  skillsToInstall.push("groove-harness");
769
796
  }
770
- if (options.enableHarness && !skillsToInstall.includes("odd-ai")) {
797
+ if (!skillsToInstall.includes("odd-ai")) {
771
798
  skillsToInstall.push("odd-ai");
772
799
  }
773
800
  syncProjectStore(options.targetPath, skillsToInstall, options.selectedAgents);
@@ -778,7 +805,7 @@ async function installSkills(options) {
778
805
  if (!skill) {
779
806
  continue;
780
807
  }
781
- const skillSourceDir = join13(projectSkillsDir, skill.directoryName);
808
+ const skillSourceDir = join10(projectSkillsDir, skill.directoryName);
782
809
  for (const agentId of options.selectedAgents) {
783
810
  const adapter = ADAPTER_REGISTRY[agentId];
784
811
  if (!adapter) {
@@ -788,23 +815,19 @@ async function installSkills(options) {
788
815
  createdFiles.push(...files);
789
816
  }
790
817
  }
791
- let harnessInitialized = false;
792
- if (options.enableHarness) {
793
- const harnessFiles = installHarness({
794
- targetPath: options.targetPath,
795
- selectedAgents: options.selectedAgents,
796
- selectedSkillIds: skillsToInstall,
797
- detectedDependencies: options.detectedDependencies || [],
798
- language: options.language
799
- });
800
- createdFiles.push(...harnessFiles);
801
- harnessInitialized = true;
802
- }
818
+ const harnessFiles = installHarness({
819
+ targetPath: options.targetPath,
820
+ selectedAgents: options.selectedAgents,
821
+ selectedSkillIds: skillsToInstall,
822
+ detectedDependencies: options.detectedDependencies || [],
823
+ language: options.language
824
+ });
825
+ createdFiles.push(...harnessFiles);
803
826
  const configPath = writeProjectConfig(
804
827
  options.targetPath,
805
828
  skillsToInstall,
806
829
  options.selectedAgents,
807
- Boolean(options.enableHarness),
830
+ true,
808
831
  options.language
809
832
  );
810
833
  createdFiles.push(configPath);
@@ -812,19 +835,19 @@ async function installSkills(options) {
812
835
  installedSkills: skillsToInstall,
813
836
  configuredAgents: options.selectedAgents,
814
837
  createdFiles,
815
- harnessInitialized,
838
+ harnessInitialized: true,
816
839
  language: options.language
817
840
  };
818
841
  }
819
842
 
820
843
  // src/domains/ui/ui-orchestrator.ts
821
- async function resolveLanguageSelection(harnessEnabled) {
822
- if (!harnessEnabled) {
823
- return "es";
844
+ async function resolveLanguageSelection(harnessExists, configuredLanguage) {
845
+ if (harnessExists) {
846
+ return configuredLanguage ?? "es";
824
847
  }
825
- const langChoice = await promptLanguage("es");
826
- if (p6.isCancel(langChoice)) {
827
- p6.cancel("Installation cancelled. Have a wonderful day!");
848
+ const langChoice = await promptLanguage(configuredLanguage ?? "es");
849
+ if (p5.isCancel(langChoice)) {
850
+ p5.cancel("Installation cancelled. Have a wonderful day!");
828
851
  process.exit(0);
829
852
  }
830
853
  return langChoice;
@@ -837,65 +860,64 @@ async function resolveOverwriteConfirmation(targetPath, selectedSkills, selected
837
860
  if (!anyExists) {
838
861
  return true;
839
862
  }
840
- const confirm3 = await promptConfirmOverwrite();
841
- if (p6.isCancel(confirm3) || !confirm3) {
842
- p6.cancel("Installation stopped to protect existing skills.");
863
+ const confirm2 = await promptConfirmOverwrite();
864
+ if (p5.isCancel(confirm2) || !confirm2) {
865
+ p5.cancel("Installation stopped to protect existing skills.");
843
866
  process.exit(0);
844
867
  }
845
- return Boolean(confirm3);
868
+ return Boolean(confirm2);
846
869
  }
847
870
  async function runInteractiveUi(context) {
848
871
  console.log(renderBanner());
849
- p6.intro(pc2.magenta("Welcome to GrooveSkills! Let's tailor your AI agents with clean architectural standards."));
872
+ p5.intro(pc2.magenta("Welcome to GrooveSkills! Let's tailor your AI agents with clean architectural standards."));
850
873
  if (context.detectedDependencies.length > 0) {
851
- p6.note(
874
+ const harnessInfo = context.harnessExists ? pc2.green(`Active (.grooveskills/memory, lang: ${context.configuredLanguage ?? "es"})`) : pc2.cyan("Will be initialized");
875
+ p5.note(
852
876
  `Detected dependencies: ${context.detectedDependencies.map((d) => pc2.bold(d)).join(", ")}
853
- Active AI folders: ${context.detectedAgents.map((a) => pc2.green(a)).join(", ") || "None (will be created)"}`,
877
+ Active AI folders: ${context.detectedAgents.map((a) => pc2.green(a)).join(", ") || "None (will be created)"}
878
+ GrooveSkills Harness: ${harnessInfo}`,
854
879
  "Project Environment"
855
880
  );
856
881
  }
857
882
  const selectedSkills = await promptSkills(context.suggestedSkillIds);
858
- if (p6.isCancel(selectedSkills)) {
859
- p6.cancel("Installation cancelled. Have a wonderful day!");
883
+ if (p5.isCancel(selectedSkills)) {
884
+ p5.cancel("Installation cancelled. Have a wonderful day!");
860
885
  process.exit(0);
861
886
  }
862
887
  const selectedAgents = await promptAgents(context.detectedAgents);
863
- if (p6.isCancel(selectedAgents)) {
864
- p6.cancel("Installation cancelled. Have a wonderful day!");
865
- process.exit(0);
866
- }
867
- const harnessChoice = await promptHarness(context.harnessExists);
868
- if (p6.isCancel(harnessChoice)) {
869
- p6.cancel("Installation cancelled. Have a wonderful day!");
888
+ if (p5.isCancel(selectedAgents)) {
889
+ p5.cancel("Installation cancelled. Have a wonderful day!");
870
890
  process.exit(0);
871
891
  }
872
- const harnessEnabled = Boolean(harnessChoice);
873
- const selectedLanguage = await resolveLanguageSelection(harnessEnabled);
892
+ const selectedLanguage = await resolveLanguageSelection(
893
+ context.harnessExists,
894
+ context.configuredLanguage
895
+ );
874
896
  const forceOverwrite = await resolveOverwriteConfirmation(
875
897
  context.targetPath,
876
898
  selectedSkills,
877
899
  selectedAgents
878
900
  );
879
- const s = p6.spinner();
901
+ const s = p5.spinner();
880
902
  s.start("Installing and adapting skills across your configured AI agents...");
881
903
  const result = await installSkills({
882
904
  targetPath: context.targetPath,
883
905
  selectedSkillIds: selectedSkills,
884
906
  selectedAgents,
885
907
  forceOverwrite,
886
- enableHarness: harnessEnabled,
908
+ enableHarness: true,
887
909
  detectedDependencies: context.detectedDependencies,
888
910
  language: selectedLanguage
889
911
  });
890
912
  s.stop(pc2.green("All skills and harness have been successfully configured!"));
891
- const harnessStatus = result.harnessInitialized ? pc2.green(`Initialized in .grooveskills/ (Language: ${selectedLanguage})`) : pc2.dim("Skipped");
892
- p6.note(
913
+ const harnessStatus = result.harnessInitialized ? pc2.green(`Initialized in .grooveskills/ (Language: ${selectedLanguage})`) : pc2.cyan(`Preserved in .grooveskills/ (Language: ${selectedLanguage})`);
914
+ p5.note(
893
915
  `Configured skills: ${result.installedSkills.map((s2) => pc2.bold(s2)).join(", ")}
894
916
  Target agents: ${result.configuredAgents.map((a) => pc2.cyan(a)).join(", ")}
895
917
  GrooveSkills Harness: ${harnessStatus}`,
896
918
  "Installation Summary"
897
919
  );
898
- p6.outro(pc2.green("Your AI programming pair is now empowered with your team's architectural habits! \u{1F680}"));
920
+ p5.outro(pc2.green("Your AI programming pair is now empowered with your team's architectural habits! \u{1F680}"));
899
921
  }
900
922
 
901
923
  // src/main.ts
@@ -906,14 +928,15 @@ async function runGrooveSkills(options = {}) {
906
928
  const hasAgents = options.agents && options.agents.length > 0;
907
929
  const isDirectHarness = Boolean(options.harness) && hasAgents;
908
930
  if (hasSkills && hasAgents || isDirectHarness) {
931
+ const language = options.language ?? context.configuredLanguage ?? "es";
909
932
  await installSkills({
910
933
  targetPath,
911
934
  selectedSkillIds: options.skills || [],
912
935
  selectedAgents: options.agents || [],
913
936
  forceOverwrite: Boolean(options.yes),
914
- enableHarness: options.harness,
937
+ enableHarness: true,
915
938
  detectedDependencies: context.detectedDependencies,
916
- language: options.language
939
+ language
917
940
  });
918
941
  return;
919
942
  }
@@ -923,4 +946,4 @@ async function runGrooveSkills(options = {}) {
923
946
  export {
924
947
  runGrooveSkills
925
948
  };
926
- //# sourceMappingURL=chunk-M7ZPBGQE.js.map
949
+ //# sourceMappingURL=chunk-FN4OEDVV.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/upsert-agent-instructions.ts","../src/domains/harness/write-project-config.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 ];\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 },\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: \"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 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): Promise<ProjectLanguage> {\n if (harnessExists) {\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(context: ProjectContext): 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\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 );\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 });\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 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 options = SKILL_CATALOG.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 harnessFiles = installHarness({\n targetPath: options.targetPath,\n selectedAgents: options.selectedAgents,\n selectedSkillIds: skillsToInstall,\n detectedDependencies: options.detectedDependencies || [],\n language: options.language,\n });\n createdFiles.push(...harnessFiles);\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: true,\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 buildTaskTemplate,\n} from \"@/domains/harness/harness-templates\";\nimport { upsertAgentInstructions } from \"@/domains/harness/upsert-agent-instructions\";\nimport type { HarnessInstallOptions } from \"@/types/harness.types\";\n\nexport function installHarness(options: HarnessInstallOptions): string[] {\n const memoryDir = getProjectMemoryDir(options.targetPath);\n const tasksDir = getProjectTasksDir(options.targetPath);\n const language = options.language ?? \"es\";\n\n if (!existsSync(tasksDir)) {\n mkdirSync(tasksDir, { recursive: true });\n }\n\n const createdFiles: string[] = [];\n\n const contextPath = join(memoryDir, \"context.md\");\n if (!existsSync(contextPath)) {\n writeFileSync(contextPath, buildContextTemplate(options.detectedDependencies, language), \"utf-8\");\n createdFiles.push(contextPath);\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(options.targetPath, options.selectedAgents, language);\n createdFiles.push(...instructions);\n\n return createdFiles;\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}\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 },\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 },\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 },\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 },\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 },\n};\n","import type { ProjectLanguage } from \"@/types/harness.types\";\nimport { SUPPORTED_LANGUAGES } from \"@/domains/harness/harness-languages\";\n\nexport function buildContextTemplate(\n detectedDependencies: string[],\n language: ProjectLanguage = \"es\"\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\n return `# Project Context & Architecture\n\nThis file provides AI agents with instant architectural orientation for this project.\n\n## 1. Stack & Dependencies\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\n## 3. Communication & User Copy Language\n- **Configured Language**: ${langConfig.nativeName} (\\`${language}\\`).\n- **Policy**: ${langConfig.instruction}\n\n## 4. Essential Commands\n- Build: Refer to \\`package.json\\` scripts.\n- Typecheck: Refer to TypeScript configuration.\n- Tests: Refer to test runner configuration.\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 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- **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, 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 { detectProjectContext } from \"@/domains/detector/project-detector\";\nimport { runInteractiveUi } from \"@/domains/ui/ui-orchestrator\";\nimport { installSkills } from \"@/domains/installer/install-orchestrator\";\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}\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\n if ((hasSkills && hasAgents) || isDirectHarness) {\n const language = options.language ?? context.configuredLanguage ?? \"es\";\n 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 });\n return;\n }\n\n await runInteractiveUi(context);\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","readFileSync","writeFileSync","join","existsSync","writeFileSync","readFileSync","join","existsSync","mkdirSync","join","writeFileSync","existsSync","readFileSync","writeFileSync","existsSync","readFileSync","writeFileSync","join","confirm","pc","s"]}
package/dist/cli.js CHANGED
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runGrooveSkills
4
- } from "./chunk-M7ZPBGQE.js";
4
+ } from "./chunk-FN4OEDVV.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 and architecture standards installer").version("1.3.1").option("-s, --skills <skills...>", "Specific skill IDs to install (e.g. best-practices hono groove-harness)").option("-a, --agents <agents...>", "Target AI agents (antigravity claude cursor gemini)").option("-y, --yes", "Automatically confirm overwrite of existing skills", false).option("--harness", "Initialize or update GrooveSkills project harness in .grooveskills/").option("--no-harness", "Skip harness initialization").option("-l, --language <lang>", "Project user copy language (es, en, pt, it, fr)", "es").action(async (options) => {
9
+ program.name("grooveskills").description("Multi-agent AI skills and architecture standards installer").version("1.4.0").option("-s, --skills <skills...>", "Specific skill IDs to install (e.g. best-practices hono groove-harness)").option("-a, --agents <agents...>", "Target AI agents (antigravity claude cursor gemini)").option("-y, --yes", "Automatically confirm overwrite of existing skills", false).option("--harness", "Initialize or update GrooveSkills project harness in .grooveskills/").option("-l, --language <lang>", "Project user copy language (es, en, pt, it, fr)").action(async (options) => {
10
10
  try {
11
11
  await runGrooveSkills({
12
12
  skills: options.skills,
13
13
  agents: options.agents,
14
14
  yes: options.yes,
15
15
  harness: options.harness,
16
- language: options.language || "es"
16
+ language: options.language
17
17
  });
18
18
  } catch (error) {
19
19
  console.error("An unexpected error occurred while running GrooveSkills:", error);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../bin/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { runGrooveSkills } from \"@/main\";\nimport type { AgentId } from \"@/types/agent.types\";\nimport type { ProjectLanguage } from \"@/types/harness.types\";\n\nconst program = new Command();\n\nprogram\n .name(\"grooveskills\")\n .description(\"Multi-agent AI skills and architecture standards installer\")\n .version(__VERSION__)\n .option(\"-s, --skills <skills...>\", \"Specific skill IDs to install (e.g. best-practices hono groove-harness)\")\n .option(\"-a, --agents <agents...>\", \"Target AI agents (antigravity claude cursor gemini)\")\n .option(\"-y, --yes\", \"Automatically confirm overwrite of existing skills\", false)\n .option(\"--harness\", \"Initialize or update GrooveSkills project harness in .grooveskills/\")\n .option(\"--no-harness\", \"Skip harness initialization\")\n .option(\"-l, --language <lang>\", \"Project user copy language (es, en, pt, it, fr)\", \"es\")\n .action(async (options: {\n skills?: string[];\n agents?: string[];\n yes?: boolean;\n harness?: boolean;\n language?: string;\n }) => {\n try {\n await runGrooveSkills({\n skills: options.skills,\n agents: options.agents as AgentId[] | undefined,\n yes: options.yes,\n harness: options.harness,\n language: (options.language as ProjectLanguage) || \"es\",\n });\n } catch (error) {\n console.error(\"An unexpected error occurred while running GrooveSkills:\", error);\n process.exit(1);\n }\n });\n\nprogram.parse();\n"],"mappings":";;;;;;AACA,SAAS,eAAe;AAKxB,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,cAAc,EACnB,YAAY,4DAA4D,EACxE,QAAQ,OAAW,EACnB,OAAO,4BAA4B,yEAAyE,EAC5G,OAAO,4BAA4B,qDAAqD,EACxF,OAAO,aAAa,sDAAsD,KAAK,EAC/E,OAAO,aAAa,qEAAqE,EACzF,OAAO,gBAAgB,6BAA6B,EACpD,OAAO,yBAAyB,mDAAmD,IAAI,EACvF,OAAO,OAAO,YAMT;AACJ,MAAI;AACF,UAAM,gBAAgB;AAAA,MACpB,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,MAChB,KAAK,QAAQ;AAAA,MACb,SAAS,QAAQ;AAAA,MACjB,UAAW,QAAQ,YAAgC;AAAA,IACrD,CAAC;AAAA,EACH,SAAS,OAAO;AACd,YAAQ,MAAM,4DAA4D,KAAK;AAC/E,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QAAQ,MAAM;","names":[]}
1
+ {"version":3,"sources":["../bin/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { runGrooveSkills } from \"@/main\";\nimport type { AgentId } from \"@/types/agent.types\";\nimport type { ProjectLanguage } from \"@/types/harness.types\";\n\nconst program = new Command();\n\nprogram\n .name(\"grooveskills\")\n .description(\"Multi-agent AI skills and architecture standards installer\")\n .version(__VERSION__)\n .option(\"-s, --skills <skills...>\", \"Specific skill IDs to install (e.g. best-practices hono groove-harness)\")\n .option(\"-a, --agents <agents...>\", \"Target AI agents (antigravity claude cursor gemini)\")\n .option(\"-y, --yes\", \"Automatically confirm overwrite of existing skills\", false)\n .option(\"--harness\", \"Initialize or update GrooveSkills project harness in .grooveskills/\")\n .option(\"-l, --language <lang>\", \"Project user copy language (es, en, pt, it, fr)\")\n .action(async (options: {\n skills?: string[];\n agents?: string[];\n yes?: boolean;\n harness?: boolean;\n language?: string;\n }) => {\n try {\n await runGrooveSkills({\n skills: options.skills,\n agents: options.agents as AgentId[] | undefined,\n yes: options.yes,\n harness: options.harness,\n language: options.language as ProjectLanguage | undefined,\n });\n } catch (error) {\n console.error(\"An unexpected error occurred while running GrooveSkills:\", error);\n process.exit(1);\n }\n });\n\nprogram.parse();\n"],"mappings":";;;;;;AACA,SAAS,eAAe;AAKxB,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,cAAc,EACnB,YAAY,4DAA4D,EACxE,QAAQ,OAAW,EACnB,OAAO,4BAA4B,yEAAyE,EAC5G,OAAO,4BAA4B,qDAAqD,EACxF,OAAO,aAAa,sDAAsD,KAAK,EAC/E,OAAO,aAAa,qEAAqE,EACzF,OAAO,yBAAyB,iDAAiD,EACjF,OAAO,OAAO,YAMT;AACJ,MAAI;AACF,UAAM,gBAAgB;AAAA,MACpB,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,MAChB,KAAK,QAAQ;AAAA,MACb,SAAS,QAAQ;AAAA,MACjB,UAAU,QAAQ;AAAA,IACpB,CAAC;AAAA,EACH,SAAS,OAAO;AACd,YAAQ,MAAM,4DAA4D,KAAK;AAC/E,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QAAQ,MAAM;","names":[]}
package/dist/main.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runGrooveSkills
3
- } from "./chunk-M7ZPBGQE.js";
3
+ } from "./chunk-FN4OEDVV.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.3.1",
3
+ "version": "1.4.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": {
@@ -1 +0,0 @@
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-harness.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/antigravity.adapter.ts","../src/domains/project-store/project-paths.ts","../src/domains/adapters/link-helper.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/upsert-agent-instructions.ts","../src/domains/harness/write-project-config.ts","../src/main.ts"],"sourcesContent":["import { existsSync } 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\";\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 ];\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\n return {\n targetPath,\n detectedDependencies: dependencies,\n suggestedSkillIds,\n detectedAgents,\n packageJsonExists: exists,\n harnessExists,\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 },\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: \"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 { promptHarness } from \"@/domains/ui/prompt-harness\";\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 type { ProjectContext } from \"@/types/context.types\";\nimport type { AgentId } from \"@/types/agent.types\";\nimport type { ProjectLanguage } from \"@/types/harness.types\";\n\nasync function resolveLanguageSelection(harnessEnabled: boolean): Promise<ProjectLanguage> {\n if (!harnessEnabled) {\n return \"es\";\n }\n\n const langChoice = await promptLanguage(\"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(context: ProjectContext): 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 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 \"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 harnessChoice = await promptHarness(context.harnessExists);\n if (p.isCancel(harnessChoice)) {\n p.cancel(\"Installation cancelled. Have a wonderful day!\");\n process.exit(0);\n }\n\n const harnessEnabled = Boolean(harnessChoice);\n const selectedLanguage = await resolveLanguageSelection(harnessEnabled);\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: harnessEnabled,\n detectedDependencies: context.detectedDependencies,\n language: selectedLanguage,\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.dim(\"Skipped\");\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 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 options = SKILL_CATALOG.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\";\n\nexport async function promptHarness(harnessExists: boolean): Promise<boolean | symbol> {\n const message = harnessExists\n ? \"GrooveSkills Harness is already initialized. Would you like to update agent rules and memory templates?\"\n : \"Would you like to initialize the GrooveSkills Harness in .grooveskills/ (project memory, ADR, and 3-lane task execution)?\";\n\n const confirm = await p.confirm({\n message,\n initialValue: true,\n });\n\n return confirm;\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 (options.enableHarness && !skillsToInstall.includes(\"groove-harness\")) {\n skillsToInstall.push(\"groove-harness\");\n }\n\n if (options.enableHarness && !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 let harnessInitialized = false;\n if (options.enableHarness) {\n const harnessFiles = installHarness({\n targetPath: options.targetPath,\n selectedAgents: options.selectedAgents,\n selectedSkillIds: skillsToInstall,\n detectedDependencies: options.detectedDependencies || [],\n language: options.language,\n });\n createdFiles.push(...harnessFiles);\n harnessInitialized = true;\n }\n\n const configPath = writeProjectConfig(\n options.targetPath,\n skillsToInstall,\n options.selectedAgents,\n Boolean(options.enableHarness),\n options.language\n );\n createdFiles.push(configPath);\n\n return {\n installedSkills: skillsToInstall,\n configuredAgents: options.selectedAgents,\n createdFiles,\n harnessInitialized,\n language: options.language,\n };\n}\n","import { mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getProjectSkillsDir } from \"@/domains/project-store/project-paths\";\nimport { createOrReplaceSymlink } from \"@/domains/adapters/link-helper\";\nimport type { AgentAdapter } from \"@/domains/adapters/adapter.interface\";\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 parentDir = join(targetPath, this.targetRelativeDir);\n if (!existsSync(parentDir)) {\n mkdirSync(parentDir, { recursive: true });\n }\n\n const destination = join(parentDir, skill.directoryName);\n const projectSkillDir = join(getProjectSkillsDir(targetPath), skill.directoryName);\n\n createOrReplaceSymlink(projectSkillDir, destination, \"dir\");\n\n return [destination];\n }\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 getProjectCursorRulesDir(targetPath: string): string {\n return join(getProjectStoreDir(targetPath), \"cursor-rules\");\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 { lstatSync, unlinkSync, rmSync, symlinkSync } from \"node:fs\";\nimport { dirname, relative } from \"node:path\";\n\nfunction removeExistingLinkPath(path: string): void {\n try {\n const lstat = lstatSync(path);\n\n if (lstat.isDirectory() && !lstat.isSymbolicLink()) {\n rmSync(path, { recursive: true, force: true });\n return;\n }\n\n unlinkSync(path);\n } catch {\n // If path does not exist, exit early\n }\n}\n\nexport function createOrReplaceSymlink(\n target: string,\n linkPath: string,\n type: \"dir\" | \"file\"\n): void {\n removeExistingLinkPath(linkPath);\n\n const linkDir = dirname(linkPath);\n const relativeTarget = relative(linkDir, target);\n\n symlinkSync(relativeTarget, linkPath, type);\n}\n","import { mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getProjectSkillsDir } from \"@/domains/project-store/project-paths\";\nimport { createOrReplaceSymlink } from \"@/domains/adapters/link-helper\";\nimport type { AgentAdapter } from \"@/domains/adapters/adapter.interface\";\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 parentDir = join(targetPath, this.targetRelativeDir);\n if (!existsSync(parentDir)) {\n mkdirSync(parentDir, { recursive: true });\n }\n\n const destination = join(parentDir, skill.directoryName);\n const projectSkillDir = join(getProjectSkillsDir(targetPath), skill.directoryName);\n\n createOrReplaceSymlink(projectSkillDir, destination, \"dir\");\n\n return [destination];\n }\n}\n","import { mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getProjectCursorRulesDir } from \"@/domains/project-store/project-paths\";\nimport { createOrReplaceSymlink } from \"@/domains/adapters/link-helper\";\nimport type { AgentAdapter } from \"@/domains/adapters/adapter.interface\";\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 rulesDir = join(targetPath, this.targetRelativeDir);\n if (!existsSync(rulesDir)) {\n mkdirSync(rulesDir, { recursive: true });\n }\n\n const filename = `${skill.id}.mdc`;\n const destination = join(rulesDir, filename);\n const projectRuleFile = join(getProjectCursorRulesDir(targetPath), filename);\n\n createOrReplaceSymlink(projectRuleFile, destination, \"file\");\n\n return [destination];\n }\n}\n","import { mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getProjectSkillsDir } from \"@/domains/project-store/project-paths\";\nimport { createOrReplaceSymlink } from \"@/domains/adapters/link-helper\";\nimport type { AgentAdapter } from \"@/domains/adapters/adapter.interface\";\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 parentDir = join(targetPath, this.targetRelativeDir);\n if (!existsSync(parentDir)) {\n mkdirSync(parentDir, { recursive: true });\n }\n\n const destination = join(parentDir, skill.directoryName);\n const projectSkillDir = join(getProjectSkillsDir(targetPath), skill.directoryName);\n\n createOrReplaceSymlink(projectSkillDir, destination, \"dir\");\n\n return [destination];\n }\n}\n","import { cpSync, mkdirSync, existsSync, writeFileSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n getProjectSkillsDir,\n getProjectCursorRulesDir,\n} from \"@/domains/project-store/project-paths\";\nimport { resolveSkillsSourceRoot } from \"@/domains/installer/resolve-skills-source\";\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 const projectCursorRulesDir = getProjectCursorRulesDir(targetPath);\n\n if (!existsSync(projectSkillsDir)) {\n mkdirSync(projectSkillsDir, { recursive: true });\n }\n\n const needsCursorRules = selectedAgents.includes(\"cursor\");\n if (needsCursorRules && !existsSync(projectCursorRulesDir)) {\n mkdirSync(projectCursorRulesDir, { recursive: true });\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 if (!needsCursorRules) {\n continue;\n }\n\n const skillMdPath = join(destSkillDir, \"SKILL.md\");\n if (!existsSync(skillMdPath)) {\n continue;\n }\n\n const content = readFileSync(skillMdPath, \"utf-8\");\n const mdcHeader = `---\ndescription: ${skill.description}\nglobs: [\"**/*\"]\nalwaysApply: false\n---\n\n`;\n const cleanedBody = content.replace(/^---[\\s\\S]*?---\\s*/, \"\");\n const targetMdc = join(projectCursorRulesDir, `${skill.id}.mdc`);\n writeFileSync(targetMdc, `${mdcHeader}${cleanedBody}`, \"utf-8\");\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 buildTaskTemplate,\n} from \"@/domains/harness/harness-templates\";\nimport { upsertAgentInstructions } from \"@/domains/harness/upsert-agent-instructions\";\nimport type { HarnessInstallOptions } from \"@/types/harness.types\";\n\nexport function installHarness(options: HarnessInstallOptions): string[] {\n const memoryDir = getProjectMemoryDir(options.targetPath);\n const tasksDir = getProjectTasksDir(options.targetPath);\n const language = options.language ?? \"es\";\n\n if (!existsSync(tasksDir)) {\n mkdirSync(tasksDir, { recursive: true });\n }\n\n const createdFiles: string[] = [];\n\n const contextPath = join(memoryDir, \"context.md\");\n if (!existsSync(contextPath)) {\n writeFileSync(contextPath, buildContextTemplate(options.detectedDependencies, language), \"utf-8\");\n createdFiles.push(contextPath);\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(options.targetPath, options.selectedAgents, language);\n createdFiles.push(...instructions);\n\n return createdFiles;\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}\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 },\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 },\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 },\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 },\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 },\n};\n","import type { ProjectLanguage } from \"@/types/harness.types\";\nimport { SUPPORTED_LANGUAGES } from \"@/domains/harness/harness-languages\";\n\nexport function buildContextTemplate(\n detectedDependencies: string[],\n language: ProjectLanguage = \"es\"\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\n return `# Project Context & Architecture\n\nThis file provides AI agents with instant architectural orientation for this project.\n\n## 1. Stack & Dependencies\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\n## 3. Communication & User Copy Language\n- **Configured Language**: ${langConfig.nativeName} (\\`${language}\\`).\n- **Policy**: ${langConfig.instruction}\n\n## 4. Essential Commands\n- Build: Refer to \\`package.json\\` scripts.\n- Typecheck: Refer to TypeScript configuration.\n- Tests: Refer to test runner configuration.\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 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- **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, 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 { detectProjectContext } from \"@/domains/detector/project-detector\";\nimport { runInteractiveUi } from \"@/domains/ui/ui-orchestrator\";\nimport { installSkills } from \"@/domains/installer/install-orchestrator\";\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}\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\n if ((hasSkills && hasAgents) || isDirectHarness) {\n await installSkills({\n targetPath,\n selectedSkillIds: options.skills || [],\n selectedAgents: options.agents || [],\n forceOverwrite: Boolean(options.yes),\n enableHarness: options.harness,\n detectedDependencies: context.detectedDependencies,\n language: options.language,\n });\n return;\n }\n\n await runInteractiveUi(context);\n}\n"],"mappings":"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","names":["existsSync","join","existsSync","join","p","pc","p","p","confirm","p","p","join","join","existsSync","join","join","lstatSync","join","existsSync","mkdirSync","existsSync","join","join","existsSync","mkdirSync","mkdirSync","existsSync","join","join","existsSync","mkdirSync","mkdirSync","existsSync","join","join","existsSync","mkdirSync","mkdirSync","existsSync","readFileSync","join","dirname","join","existsSync","existsSync","mkdirSync","join","readFileSync","existsSync","mkdirSync","writeFileSync","join","existsSync","readFileSync","writeFileSync","join","existsSync","writeFileSync","readFileSync","join","existsSync","mkdirSync","join","writeFileSync","existsSync","readFileSync","writeFileSync","existsSync","readFileSync","writeFileSync","join","confirm","pc","s"]}