@3lineas/grooveskills 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/{chunk-HUG3MG3P.js → chunk-E63GTCOE.js} +364 -141
- package/dist/chunk-E63GTCOE.js.map +1 -0
- package/dist/cli.js +23 -3
- package/dist/cli.js.map +1 -1
- package/dist/main.js +1 -1
- package/package.json +3 -2
- package/skills/docs-standards/SKILL.md +113 -0
- package/skills/docs-standards/references/adr-template-and-lifecycle.md +111 -0
- package/skills/docs-standards/references/code-comments-and-docstrings.md +147 -0
- package/skills/docs-standards/references/relative-paths-and-diagrams.md +123 -0
- package/dist/chunk-HUG3MG3P.js.map +0 -1
|
@@ -94,6 +94,13 @@ var SKILL_CATALOG = [
|
|
|
94
94
|
dependencies: [],
|
|
95
95
|
directoryName: "ux-writing"
|
|
96
96
|
},
|
|
97
|
+
{
|
|
98
|
+
id: "docs-standards",
|
|
99
|
+
name: "Documentation & ADR Standards",
|
|
100
|
+
description: "English documentation standard, relative POSIX links, resilient Mermaid diagrams, ADR lifecycle, and intent-focused docstrings",
|
|
101
|
+
dependencies: [],
|
|
102
|
+
directoryName: "docs-standards"
|
|
103
|
+
},
|
|
97
104
|
{
|
|
98
105
|
id: "typescript-clean",
|
|
99
106
|
name: "TypeScript Clean Code (TS 5.5+)",
|
|
@@ -243,6 +250,7 @@ function detectProjectContext(targetPath) {
|
|
|
243
250
|
"odd-ai",
|
|
244
251
|
"best-practices",
|
|
245
252
|
"ux-writing",
|
|
253
|
+
"docs-standards",
|
|
246
254
|
"error-handling-logging",
|
|
247
255
|
"clean-architecture-ddd",
|
|
248
256
|
"external-service-adapters",
|
|
@@ -382,7 +390,7 @@ function verifySkillExists(targetPath, skillDirectoryName, agents) {
|
|
|
382
390
|
import { join as join11 } from "path";
|
|
383
391
|
|
|
384
392
|
// src/domains/adapters/skill-reference-builder.ts
|
|
385
|
-
import { existsSync as
|
|
393
|
+
import { existsSync as existsSync4, lstatSync as lstatSync2, mkdirSync, readFileSync as readFileSync3, rmSync, unlinkSync } from "fs";
|
|
386
394
|
import { join as join5 } from "path";
|
|
387
395
|
|
|
388
396
|
// src/domains/project-store/project-paths.ts
|
|
@@ -403,9 +411,46 @@ function getProjectConfigPath(targetPath) {
|
|
|
403
411
|
return join4(getProjectStoreDir(targetPath), "config.json");
|
|
404
412
|
}
|
|
405
413
|
|
|
414
|
+
// src/domains/fs/safe-file-writer.ts
|
|
415
|
+
import { chmodSync, existsSync as existsSync3, writeFileSync } from "fs";
|
|
416
|
+
|
|
417
|
+
// src/errors/file-permission-error.ts
|
|
418
|
+
var FilePermissionError = class extends Error {
|
|
419
|
+
code = "EACCES";
|
|
420
|
+
filePath;
|
|
421
|
+
suggestedFixCommand;
|
|
422
|
+
constructor(filePath) {
|
|
423
|
+
super(`No tienes permisos de escritura para modificar '${filePath}'.`);
|
|
424
|
+
this.name = "FilePermissionError";
|
|
425
|
+
this.filePath = filePath;
|
|
426
|
+
this.suggestedFixCommand = `chmod u+w "${filePath}"`;
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
// src/domains/fs/safe-file-writer.ts
|
|
431
|
+
function safeWriteFileSync(filePath, content) {
|
|
432
|
+
try {
|
|
433
|
+
writeFileSync(filePath, content, "utf-8");
|
|
434
|
+
} catch (error) {
|
|
435
|
+
const err = error;
|
|
436
|
+
if (err.code === "EACCES" || err.code === "EPERM") {
|
|
437
|
+
if (existsSync3(filePath)) {
|
|
438
|
+
try {
|
|
439
|
+
chmodSync(filePath, 420);
|
|
440
|
+
writeFileSync(filePath, content, "utf-8");
|
|
441
|
+
return;
|
|
442
|
+
} catch {
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
throw new FilePermissionError(filePath);
|
|
446
|
+
}
|
|
447
|
+
throw error;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
406
451
|
// src/domains/adapters/skill-reference-builder.ts
|
|
407
452
|
function removeExistingPathSafely(path) {
|
|
408
|
-
const fileExists =
|
|
453
|
+
const fileExists = existsSync4(path);
|
|
409
454
|
if (!fileExists) {
|
|
410
455
|
try {
|
|
411
456
|
const lstat = lstatSync2(path);
|
|
@@ -431,7 +476,7 @@ function removeExistingPathSafely(path) {
|
|
|
431
476
|
}
|
|
432
477
|
}
|
|
433
478
|
function extractSkillDescription(canonicalSkillMdPath, fallback) {
|
|
434
|
-
if (!
|
|
479
|
+
if (!existsSync4(canonicalSkillMdPath)) {
|
|
435
480
|
return fallback;
|
|
436
481
|
}
|
|
437
482
|
try {
|
|
@@ -445,8 +490,14 @@ function extractSkillDescription(canonicalSkillMdPath, fallback) {
|
|
|
445
490
|
}
|
|
446
491
|
return fallback;
|
|
447
492
|
}
|
|
448
|
-
function writeAgentSkillReference(targetPath, agentRelativeSkillsDir, skill) {
|
|
493
|
+
function writeAgentSkillReference(targetPath, agentRelativeSkillsDir, skill, transaction) {
|
|
449
494
|
const agentSkillFolder = join5(targetPath, agentRelativeSkillsDir, skill.directoryName);
|
|
495
|
+
const targetFile = join5(agentSkillFolder, "SKILL.md");
|
|
496
|
+
if (transaction) {
|
|
497
|
+
transaction.recordCreatedDir(join5(targetPath, agentRelativeSkillsDir));
|
|
498
|
+
transaction.recordCreatedDir(agentSkillFolder);
|
|
499
|
+
transaction.recordBeforeWrite(targetFile);
|
|
500
|
+
}
|
|
450
501
|
removeExistingPathSafely(agentSkillFolder);
|
|
451
502
|
mkdirSync(agentSkillFolder, { recursive: true });
|
|
452
503
|
const canonicalSkillMd = join5(getProjectSkillsDir(targetPath), skill.directoryName, "SKILL.md");
|
|
@@ -465,16 +516,19 @@ Canonical skill specification stored in \`.grooveskills/\`.
|
|
|
465
516
|
|
|
466
517
|
> **Instruction**: Read \`.grooveskills/skills/${skill.directoryName}/SKILL.md\` before executing tasks matching this skill.
|
|
467
518
|
`;
|
|
468
|
-
|
|
469
|
-
writeFileSync(targetFile, referenceContent, "utf-8");
|
|
519
|
+
safeWriteFileSync(targetFile, referenceContent);
|
|
470
520
|
return targetFile;
|
|
471
521
|
}
|
|
472
|
-
function writeCursorRuleReference(targetPath, cursorRelativeRulesDir, skill) {
|
|
522
|
+
function writeCursorRuleReference(targetPath, cursorRelativeRulesDir, skill, transaction) {
|
|
473
523
|
const rulesDir = join5(targetPath, cursorRelativeRulesDir);
|
|
474
|
-
|
|
524
|
+
const targetFile = join5(rulesDir, `${skill.id}.mdc`);
|
|
525
|
+
if (transaction) {
|
|
526
|
+
transaction.recordCreatedDir(rulesDir);
|
|
527
|
+
transaction.recordBeforeWrite(targetFile);
|
|
528
|
+
}
|
|
529
|
+
if (!existsSync4(rulesDir)) {
|
|
475
530
|
mkdirSync(rulesDir, { recursive: true });
|
|
476
531
|
}
|
|
477
|
-
const targetFile = join5(rulesDir, `${skill.id}.mdc`);
|
|
478
532
|
removeExistingPathSafely(targetFile);
|
|
479
533
|
const canonicalSkillMd = join5(getProjectSkillsDir(targetPath), skill.directoryName, "SKILL.md");
|
|
480
534
|
const description = extractSkillDescription(canonicalSkillMd, skill.description);
|
|
@@ -493,7 +547,7 @@ Canonical rule specification stored in \`.grooveskills/\`.
|
|
|
493
547
|
|
|
494
548
|
> **Instruction**: Read \`.grooveskills/skills/${skill.directoryName}/SKILL.md\` before executing tasks matching this rule.
|
|
495
549
|
`;
|
|
496
|
-
|
|
550
|
+
safeWriteFileSync(targetFile, referenceContent);
|
|
497
551
|
return targetFile;
|
|
498
552
|
}
|
|
499
553
|
|
|
@@ -502,8 +556,8 @@ var AntigravityAdapter = class {
|
|
|
502
556
|
id = "antigravity";
|
|
503
557
|
name = "Antigravity";
|
|
504
558
|
targetRelativeDir = ".agents/skills";
|
|
505
|
-
async installSkill(targetPath, skill, _skillSourceDir) {
|
|
506
|
-
const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill);
|
|
559
|
+
async installSkill(targetPath, skill, _skillSourceDir, transaction) {
|
|
560
|
+
const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill, transaction);
|
|
507
561
|
return [file];
|
|
508
562
|
}
|
|
509
563
|
};
|
|
@@ -513,8 +567,8 @@ var ClaudeAdapter = class {
|
|
|
513
567
|
id = "claude";
|
|
514
568
|
name = "Claude Code";
|
|
515
569
|
targetRelativeDir = ".claude/skills";
|
|
516
|
-
async installSkill(targetPath, skill, _skillSourceDir) {
|
|
517
|
-
const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill);
|
|
570
|
+
async installSkill(targetPath, skill, _skillSourceDir, transaction) {
|
|
571
|
+
const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill, transaction);
|
|
518
572
|
return [file];
|
|
519
573
|
}
|
|
520
574
|
};
|
|
@@ -524,8 +578,8 @@ var CursorAdapter = class {
|
|
|
524
578
|
id = "cursor";
|
|
525
579
|
name = "Cursor";
|
|
526
580
|
targetRelativeDir = ".cursor/rules";
|
|
527
|
-
async installSkill(targetPath, skill, _skillSourceDir) {
|
|
528
|
-
const file = writeCursorRuleReference(targetPath, this.targetRelativeDir, skill);
|
|
581
|
+
async installSkill(targetPath, skill, _skillSourceDir, transaction) {
|
|
582
|
+
const file = writeCursorRuleReference(targetPath, this.targetRelativeDir, skill, transaction);
|
|
529
583
|
return [file];
|
|
530
584
|
}
|
|
531
585
|
};
|
|
@@ -535,35 +589,35 @@ var GeminiAdapter = class {
|
|
|
535
589
|
id = "gemini";
|
|
536
590
|
name = "Gemini Code Assist";
|
|
537
591
|
targetRelativeDir = ".gemini/skills";
|
|
538
|
-
async installSkill(targetPath, skill, _skillSourceDir) {
|
|
539
|
-
const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill);
|
|
592
|
+
async installSkill(targetPath, skill, _skillSourceDir, transaction) {
|
|
593
|
+
const file = writeAgentSkillReference(targetPath, this.targetRelativeDir, skill, transaction);
|
|
540
594
|
return [file];
|
|
541
595
|
}
|
|
542
596
|
};
|
|
543
597
|
|
|
544
598
|
// src/domains/project-store/sync-project-store.ts
|
|
545
|
-
import { cpSync, existsSync as
|
|
599
|
+
import { cpSync, existsSync as existsSync6, mkdirSync as mkdirSync2, rmSync as rmSync2 } from "fs";
|
|
546
600
|
import { join as join7 } from "path";
|
|
547
601
|
|
|
548
602
|
// src/domains/installer/resolve-skills-source.ts
|
|
549
603
|
import { fileURLToPath } from "url";
|
|
550
604
|
import { dirname, resolve, join as join6 } from "path";
|
|
551
|
-
import { existsSync as
|
|
605
|
+
import { existsSync as existsSync5 } from "fs";
|
|
552
606
|
function resolveSkillsSourceRoot() {
|
|
553
607
|
const currentFilePath = fileURLToPath(import.meta.url);
|
|
554
608
|
const currentDir = dirname(currentFilePath);
|
|
555
609
|
const candidateFromDist = resolve(currentDir, "../skills");
|
|
556
|
-
if (
|
|
610
|
+
if (existsSync5(candidateFromDist)) {
|
|
557
611
|
return candidateFromDist;
|
|
558
612
|
}
|
|
559
613
|
const candidateFromSrc = resolve(currentDir, "../../../skills");
|
|
560
|
-
if (
|
|
614
|
+
if (existsSync5(candidateFromSrc)) {
|
|
561
615
|
return candidateFromSrc;
|
|
562
616
|
}
|
|
563
617
|
let searchDir = currentDir;
|
|
564
618
|
for (let i = 0; i < 5; i++) {
|
|
565
619
|
const candidate = join6(searchDir, "skills");
|
|
566
|
-
if (
|
|
620
|
+
if (existsSync5(candidate)) {
|
|
567
621
|
return candidate;
|
|
568
622
|
}
|
|
569
623
|
const parent = dirname(searchDir);
|
|
@@ -578,14 +632,17 @@ function resolveSkillsSourceRoot() {
|
|
|
578
632
|
}
|
|
579
633
|
|
|
580
634
|
// src/domains/project-store/sync-project-store.ts
|
|
581
|
-
function syncProjectStore(targetPath, selectedSkillIds, _selectedAgents) {
|
|
635
|
+
function syncProjectStore(targetPath, selectedSkillIds, _selectedAgents, transaction) {
|
|
582
636
|
const bundledSkillsDir = resolveSkillsSourceRoot();
|
|
583
637
|
const projectSkillsDir = getProjectSkillsDir(targetPath);
|
|
584
|
-
if (
|
|
638
|
+
if (transaction) {
|
|
639
|
+
transaction.recordCreatedDir(projectSkillsDir);
|
|
640
|
+
}
|
|
641
|
+
if (!existsSync6(projectSkillsDir)) {
|
|
585
642
|
mkdirSync2(projectSkillsDir, { recursive: true });
|
|
586
643
|
}
|
|
587
644
|
const legacyCursorRules = join7(targetPath, ".grooveskills", "cursor-rules");
|
|
588
|
-
if (
|
|
645
|
+
if (existsSync6(legacyCursorRules)) {
|
|
589
646
|
try {
|
|
590
647
|
rmSync2(legacyCursorRules, { recursive: true, force: true });
|
|
591
648
|
} catch {
|
|
@@ -598,14 +655,17 @@ function syncProjectStore(targetPath, selectedSkillIds, _selectedAgents) {
|
|
|
598
655
|
}
|
|
599
656
|
const sourceSkillDir = join7(bundledSkillsDir, skill.directoryName);
|
|
600
657
|
const destSkillDir = join7(projectSkillsDir, skill.directoryName);
|
|
601
|
-
if (
|
|
658
|
+
if (transaction) {
|
|
659
|
+
transaction.recordCreatedDir(destSkillDir);
|
|
660
|
+
}
|
|
661
|
+
if (existsSync6(sourceSkillDir)) {
|
|
602
662
|
cpSync(sourceSkillDir, destSkillDir, { recursive: true });
|
|
603
663
|
}
|
|
604
664
|
}
|
|
605
665
|
}
|
|
606
666
|
|
|
607
667
|
// src/domains/harness/install-harness.ts
|
|
608
|
-
import { existsSync as
|
|
668
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync3 } from "fs";
|
|
609
669
|
import { join as join10 } from "path";
|
|
610
670
|
|
|
611
671
|
// src/domains/harness/harness-languages.ts
|
|
@@ -805,11 +865,11 @@ This project uses the **GrooveSkills Harness** located in \`.grooveskills/\`.
|
|
|
805
865
|
}
|
|
806
866
|
|
|
807
867
|
// src/domains/harness/scan-project-onboarding.ts
|
|
808
|
-
import { existsSync as
|
|
868
|
+
import { existsSync as existsSync7, readdirSync as readdirSync2, readFileSync as readFileSync4 } from "fs";
|
|
809
869
|
import { basename, join as join8 } from "path";
|
|
810
870
|
function detectProjectName(targetPath) {
|
|
811
871
|
const packageJsonPath = join8(targetPath, "package.json");
|
|
812
|
-
if (
|
|
872
|
+
if (existsSync7(packageJsonPath)) {
|
|
813
873
|
try {
|
|
814
874
|
const raw = readFileSync4(packageJsonPath, "utf-8");
|
|
815
875
|
const parsed = JSON.parse(raw);
|
|
@@ -820,7 +880,7 @@ function detectProjectName(targetPath) {
|
|
|
820
880
|
}
|
|
821
881
|
}
|
|
822
882
|
const cargoPath = join8(targetPath, "Cargo.toml");
|
|
823
|
-
if (
|
|
883
|
+
if (existsSync7(cargoPath)) {
|
|
824
884
|
try {
|
|
825
885
|
const cargoRaw = readFileSync4(cargoPath, "utf-8");
|
|
826
886
|
const nameMatch = cargoRaw.match(/name\s*=\s*"([^"]+)"/);
|
|
@@ -831,7 +891,7 @@ function detectProjectName(targetPath) {
|
|
|
831
891
|
}
|
|
832
892
|
}
|
|
833
893
|
const pyprojectPath = join8(targetPath, "pyproject.toml");
|
|
834
|
-
if (
|
|
894
|
+
if (existsSync7(pyprojectPath)) {
|
|
835
895
|
try {
|
|
836
896
|
const pyRaw = readFileSync4(pyprojectPath, "utf-8");
|
|
837
897
|
const pyMatch = pyRaw.match(/name\s*=\s*"([^"]+)"/);
|
|
@@ -844,32 +904,32 @@ function detectProjectName(targetPath) {
|
|
|
844
904
|
return basename(targetPath) || "project";
|
|
845
905
|
}
|
|
846
906
|
function detectPackageManager(targetPath) {
|
|
847
|
-
if (
|
|
907
|
+
if (existsSync7(join8(targetPath, "pnpm-lock.yaml"))) {
|
|
848
908
|
return "pnpm";
|
|
849
909
|
}
|
|
850
|
-
if (
|
|
910
|
+
if (existsSync7(join8(targetPath, "bun.lockb")) || existsSync7(join8(targetPath, "bun.lock"))) {
|
|
851
911
|
return "bun";
|
|
852
912
|
}
|
|
853
|
-
if (
|
|
913
|
+
if (existsSync7(join8(targetPath, "yarn.lock"))) {
|
|
854
914
|
return "yarn";
|
|
855
915
|
}
|
|
856
|
-
if (
|
|
916
|
+
if (existsSync7(join8(targetPath, "package-lock.json"))) {
|
|
857
917
|
return "npm";
|
|
858
918
|
}
|
|
859
|
-
if (
|
|
919
|
+
if (existsSync7(join8(targetPath, "Cargo.lock")) || existsSync7(join8(targetPath, "Cargo.toml"))) {
|
|
860
920
|
return "cargo";
|
|
861
921
|
}
|
|
862
|
-
if (
|
|
922
|
+
if (existsSync7(join8(targetPath, "uv.lock"))) {
|
|
863
923
|
return "uv";
|
|
864
924
|
}
|
|
865
|
-
if (
|
|
925
|
+
if (existsSync7(join8(targetPath, "poetry.lock"))) {
|
|
866
926
|
return "poetry";
|
|
867
927
|
}
|
|
868
928
|
return "npm";
|
|
869
929
|
}
|
|
870
930
|
function detectCommands(targetPath, pkgManager) {
|
|
871
931
|
const packageJsonPath = join8(targetPath, "package.json");
|
|
872
|
-
if (!
|
|
932
|
+
if (!existsSync7(packageJsonPath)) {
|
|
873
933
|
return {};
|
|
874
934
|
}
|
|
875
935
|
try {
|
|
@@ -904,7 +964,7 @@ function detectCommands(targetPath, pkgManager) {
|
|
|
904
964
|
}
|
|
905
965
|
function detectPathAliases(targetPath) {
|
|
906
966
|
const tsconfigPath = join8(targetPath, "tsconfig.json");
|
|
907
|
-
if (!
|
|
967
|
+
if (!existsSync7(tsconfigPath)) {
|
|
908
968
|
return {};
|
|
909
969
|
}
|
|
910
970
|
try {
|
|
@@ -924,7 +984,7 @@ function detectPathAliases(targetPath) {
|
|
|
924
984
|
}
|
|
925
985
|
function detectSourceDirectories(targetPath) {
|
|
926
986
|
const srcPath = join8(targetPath, "src");
|
|
927
|
-
const scanTarget =
|
|
987
|
+
const scanTarget = existsSync7(srcPath) ? srcPath : targetPath;
|
|
928
988
|
try {
|
|
929
989
|
const entries = readdirSync2(scanTarget, { withFileTypes: true });
|
|
930
990
|
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => !name.startsWith(".") && name !== "node_modules" && name !== "dist");
|
|
@@ -948,36 +1008,39 @@ function scanProjectOnboarding(targetPath) {
|
|
|
948
1008
|
}
|
|
949
1009
|
|
|
950
1010
|
// src/domains/harness/upsert-agent-instructions.ts
|
|
951
|
-
import { existsSync as
|
|
1011
|
+
import { existsSync as existsSync8, readFileSync as readFileSync5 } from "fs";
|
|
952
1012
|
import { join as join9 } from "path";
|
|
953
1013
|
var START_MARKER = "<!-- grooveskills:harness:start -->";
|
|
954
1014
|
var END_MARKER = "<!-- grooveskills:harness:end -->";
|
|
955
|
-
function applyHarnessBlock(filePath, language = "es") {
|
|
1015
|
+
function applyHarnessBlock(filePath, language = "es", transaction) {
|
|
1016
|
+
if (transaction) {
|
|
1017
|
+
transaction.recordBeforeWrite(filePath);
|
|
1018
|
+
}
|
|
956
1019
|
const block = buildAgentHarnessBlock(language);
|
|
957
|
-
if (!
|
|
958
|
-
|
|
959
|
-
|
|
1020
|
+
if (!existsSync8(filePath)) {
|
|
1021
|
+
safeWriteFileSync(filePath, `${block}
|
|
1022
|
+
`);
|
|
960
1023
|
return;
|
|
961
1024
|
}
|
|
962
1025
|
const existingContent = readFileSync5(filePath, "utf-8");
|
|
963
1026
|
if (existingContent.includes(START_MARKER) && existingContent.includes(END_MARKER)) {
|
|
964
1027
|
const regex = new RegExp(`${START_MARKER}[\\s\\S]*?${END_MARKER}`, "g");
|
|
965
1028
|
const updated = existingContent.replace(regex, block);
|
|
966
|
-
|
|
1029
|
+
safeWriteFileSync(filePath, updated);
|
|
967
1030
|
return;
|
|
968
1031
|
}
|
|
969
1032
|
const separator = existingContent.endsWith("\n") ? "\n" : "\n\n";
|
|
970
|
-
|
|
971
|
-
|
|
1033
|
+
safeWriteFileSync(filePath, `${existingContent}${separator}${block}
|
|
1034
|
+
`);
|
|
972
1035
|
}
|
|
973
|
-
function upsertAgentInstructions(targetPath, selectedAgents, language = "es") {
|
|
1036
|
+
function upsertAgentInstructions(targetPath, selectedAgents, language = "es", transaction) {
|
|
974
1037
|
const updatedFiles = [];
|
|
975
1038
|
const agentsMdPath = join9(targetPath, "AGENTS.md");
|
|
976
|
-
applyHarnessBlock(agentsMdPath, language);
|
|
1039
|
+
applyHarnessBlock(agentsMdPath, language, transaction);
|
|
977
1040
|
updatedFiles.push(agentsMdPath);
|
|
978
1041
|
if (selectedAgents.includes("claude")) {
|
|
979
1042
|
const claudeMdPath = join9(targetPath, "CLAUDE.md");
|
|
980
|
-
applyHarnessBlock(claudeMdPath, language);
|
|
1043
|
+
applyHarnessBlock(claudeMdPath, language, transaction);
|
|
981
1044
|
updatedFiles.push(claudeMdPath);
|
|
982
1045
|
}
|
|
983
1046
|
return updatedFiles;
|
|
@@ -989,43 +1052,60 @@ function installHarness(options) {
|
|
|
989
1052
|
const tasksDir = getProjectTasksDir(options.targetPath);
|
|
990
1053
|
const language = options.language ?? "es";
|
|
991
1054
|
const forceOnboarding = Boolean(options.forceOnboarding);
|
|
992
|
-
|
|
1055
|
+
const tx = options.transaction;
|
|
1056
|
+
if (tx) {
|
|
1057
|
+
tx.recordCreatedDir(memoryDir);
|
|
1058
|
+
tx.recordCreatedDir(tasksDir);
|
|
1059
|
+
}
|
|
1060
|
+
if (!existsSync9(tasksDir)) {
|
|
993
1061
|
mkdirSync3(tasksDir, { recursive: true });
|
|
994
1062
|
}
|
|
995
1063
|
const createdFiles = [];
|
|
996
1064
|
const contextPath = join10(memoryDir, "context.md");
|
|
997
|
-
const shouldWriteContext = !
|
|
1065
|
+
const shouldWriteContext = !existsSync9(contextPath) || forceOnboarding;
|
|
998
1066
|
if (shouldWriteContext) {
|
|
1067
|
+
if (tx) {
|
|
1068
|
+
tx.recordBeforeWrite(contextPath);
|
|
1069
|
+
}
|
|
999
1070
|
const profile = scanProjectOnboarding(options.targetPath);
|
|
1000
1071
|
const contextContent = buildContextTemplate(
|
|
1001
1072
|
options.detectedDependencies,
|
|
1002
1073
|
language,
|
|
1003
1074
|
profile
|
|
1004
1075
|
);
|
|
1005
|
-
|
|
1076
|
+
safeWriteFileSync(contextPath, contextContent);
|
|
1006
1077
|
createdFiles.push(contextPath);
|
|
1007
1078
|
const onboardingTaskPath = join10(tasksDir, "00-onboarding.md");
|
|
1008
|
-
|
|
1079
|
+
if (tx) {
|
|
1080
|
+
tx.recordBeforeWrite(onboardingTaskPath);
|
|
1081
|
+
}
|
|
1082
|
+
safeWriteFileSync(
|
|
1009
1083
|
onboardingTaskPath,
|
|
1010
|
-
buildOnboardingTaskTemplate(profile.projectName)
|
|
1011
|
-
"utf-8"
|
|
1084
|
+
buildOnboardingTaskTemplate(profile.projectName)
|
|
1012
1085
|
);
|
|
1013
1086
|
createdFiles.push(onboardingTaskPath);
|
|
1014
1087
|
}
|
|
1015
1088
|
const decisionsPath = join10(memoryDir, "decisions.md");
|
|
1016
|
-
if (!
|
|
1017
|
-
|
|
1089
|
+
if (!existsSync9(decisionsPath)) {
|
|
1090
|
+
if (tx) {
|
|
1091
|
+
tx.recordBeforeWrite(decisionsPath);
|
|
1092
|
+
}
|
|
1093
|
+
safeWriteFileSync(decisionsPath, buildDecisionsTemplate(language));
|
|
1018
1094
|
createdFiles.push(decisionsPath);
|
|
1019
1095
|
}
|
|
1020
1096
|
const templateTaskPath = join10(tasksDir, "_template.md");
|
|
1021
|
-
if (!
|
|
1022
|
-
|
|
1097
|
+
if (!existsSync9(templateTaskPath)) {
|
|
1098
|
+
if (tx) {
|
|
1099
|
+
tx.recordBeforeWrite(templateTaskPath);
|
|
1100
|
+
}
|
|
1101
|
+
safeWriteFileSync(templateTaskPath, buildTaskTemplate());
|
|
1023
1102
|
createdFiles.push(templateTaskPath);
|
|
1024
1103
|
}
|
|
1025
1104
|
const instructions = upsertAgentInstructions(
|
|
1026
1105
|
options.targetPath,
|
|
1027
1106
|
options.selectedAgents,
|
|
1028
|
-
language
|
|
1107
|
+
language,
|
|
1108
|
+
tx
|
|
1029
1109
|
);
|
|
1030
1110
|
createdFiles.push(...instructions);
|
|
1031
1111
|
return {
|
|
@@ -1035,14 +1115,14 @@ function installHarness(options) {
|
|
|
1035
1115
|
}
|
|
1036
1116
|
|
|
1037
1117
|
// src/domains/harness/write-project-config.ts
|
|
1038
|
-
import { existsSync as
|
|
1118
|
+
import { existsSync as existsSync10, readFileSync as readFileSync6 } from "fs";
|
|
1039
1119
|
function readExistingConfig(configPath) {
|
|
1040
1120
|
const fallback = {
|
|
1041
1121
|
skills: [],
|
|
1042
1122
|
agents: [],
|
|
1043
1123
|
harness: false
|
|
1044
1124
|
};
|
|
1045
|
-
if (!
|
|
1125
|
+
if (!existsSync10(configPath)) {
|
|
1046
1126
|
return fallback;
|
|
1047
1127
|
}
|
|
1048
1128
|
try {
|
|
@@ -1058,8 +1138,11 @@ function readExistingConfig(configPath) {
|
|
|
1058
1138
|
return fallback;
|
|
1059
1139
|
}
|
|
1060
1140
|
}
|
|
1061
|
-
function writeProjectConfig(targetPath, newSkills, newAgents, harnessEnabled, language) {
|
|
1141
|
+
function writeProjectConfig(targetPath, newSkills, newAgents, harnessEnabled, language, transaction) {
|
|
1062
1142
|
const configPath = getProjectConfigPath(targetPath);
|
|
1143
|
+
if (transaction) {
|
|
1144
|
+
transaction.recordBeforeWrite(configPath);
|
|
1145
|
+
}
|
|
1063
1146
|
const existing = readExistingConfig(configPath);
|
|
1064
1147
|
const mergedSkills = Array.from(/* @__PURE__ */ new Set([...existing.skills, ...newSkills]));
|
|
1065
1148
|
const mergedAgents = Array.from(/* @__PURE__ */ new Set([...existing.agents, ...newAgents]));
|
|
@@ -1073,11 +1156,84 @@ function writeProjectConfig(targetPath, newSkills, newAgents, harnessEnabled, la
|
|
|
1073
1156
|
skills: mergedSkills,
|
|
1074
1157
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1075
1158
|
};
|
|
1076
|
-
|
|
1077
|
-
|
|
1159
|
+
safeWriteFileSync(configPath, `${JSON.stringify(config, null, 2)}
|
|
1160
|
+
`);
|
|
1078
1161
|
return configPath;
|
|
1079
1162
|
}
|
|
1080
1163
|
|
|
1164
|
+
// src/domains/fs/install-transaction.ts
|
|
1165
|
+
import { existsSync as existsSync11, readdirSync as readdirSync3, readFileSync as readFileSync7, rmSync as rmSync3 } from "fs";
|
|
1166
|
+
var InstallTransaction = class {
|
|
1167
|
+
originalFiles = /* @__PURE__ */ new Map();
|
|
1168
|
+
createdDirs = [];
|
|
1169
|
+
recordBeforeWrite(filePath) {
|
|
1170
|
+
if (this.originalFiles.has(filePath)) {
|
|
1171
|
+
return;
|
|
1172
|
+
}
|
|
1173
|
+
if (existsSync11(filePath)) {
|
|
1174
|
+
try {
|
|
1175
|
+
this.originalFiles.set(filePath, readFileSync7(filePath, "utf-8"));
|
|
1176
|
+
} catch {
|
|
1177
|
+
this.originalFiles.set(filePath, null);
|
|
1178
|
+
}
|
|
1179
|
+
} else {
|
|
1180
|
+
this.originalFiles.set(filePath, null);
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
recordCreatedDir(dirPath) {
|
|
1184
|
+
if (!existsSync11(dirPath) && !this.createdDirs.includes(dirPath)) {
|
|
1185
|
+
this.createdDirs.push(dirPath);
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
rollback() {
|
|
1189
|
+
const restoredFiles = [];
|
|
1190
|
+
const removedFiles = [];
|
|
1191
|
+
const removedDirs = [];
|
|
1192
|
+
for (const [filePath, content] of this.originalFiles.entries()) {
|
|
1193
|
+
try {
|
|
1194
|
+
if (content === null) {
|
|
1195
|
+
if (existsSync11(filePath)) {
|
|
1196
|
+
rmSync3(filePath, { force: true });
|
|
1197
|
+
removedFiles.push(filePath);
|
|
1198
|
+
}
|
|
1199
|
+
} else {
|
|
1200
|
+
safeWriteFileSync(filePath, content);
|
|
1201
|
+
restoredFiles.push(filePath);
|
|
1202
|
+
}
|
|
1203
|
+
} catch {
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
const sortedDirs = [...this.createdDirs].sort((a, b) => b.length - a.length);
|
|
1207
|
+
for (const dir of sortedDirs) {
|
|
1208
|
+
try {
|
|
1209
|
+
if (existsSync11(dir) && readdirSync3(dir).length === 0) {
|
|
1210
|
+
rmSync3(dir, { recursive: true, force: true });
|
|
1211
|
+
removedDirs.push(dir);
|
|
1212
|
+
}
|
|
1213
|
+
} catch {
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
return { restoredFiles, removedFiles, removedDirs };
|
|
1217
|
+
}
|
|
1218
|
+
};
|
|
1219
|
+
|
|
1220
|
+
// src/errors/install-transaction-error.ts
|
|
1221
|
+
var InstallTransactionError = class extends Error {
|
|
1222
|
+
stage;
|
|
1223
|
+
causeError;
|
|
1224
|
+
rollbackReport;
|
|
1225
|
+
suggestedFix;
|
|
1226
|
+
constructor(options) {
|
|
1227
|
+
const rawMessage = options.cause instanceof Error ? options.cause.message : String(options.cause);
|
|
1228
|
+
super(`Error durante la etapa '${options.stage}': ${rawMessage}`);
|
|
1229
|
+
this.name = "InstallTransactionError";
|
|
1230
|
+
this.stage = options.stage;
|
|
1231
|
+
this.causeError = options.cause;
|
|
1232
|
+
this.rollbackReport = options.rollbackReport;
|
|
1233
|
+
this.suggestedFix = options.suggestedFix;
|
|
1234
|
+
}
|
|
1235
|
+
};
|
|
1236
|
+
|
|
1081
1237
|
// src/domains/installer/install-orchestrator.ts
|
|
1082
1238
|
var ADAPTER_REGISTRY = {
|
|
1083
1239
|
antigravity: new AntigravityAdapter(),
|
|
@@ -1085,7 +1241,20 @@ var ADAPTER_REGISTRY = {
|
|
|
1085
1241
|
cursor: new CursorAdapter(),
|
|
1086
1242
|
gemini: new GeminiAdapter()
|
|
1087
1243
|
};
|
|
1244
|
+
function formatSuggestedFix(cause) {
|
|
1245
|
+
if (cause instanceof FilePermissionError) {
|
|
1246
|
+
return cause.suggestedFixCommand;
|
|
1247
|
+
}
|
|
1248
|
+
const err = cause;
|
|
1249
|
+
if (err?.code === "EACCES" || err?.code === "EPERM") {
|
|
1250
|
+
if (err.path) {
|
|
1251
|
+
return `chmod u+w "${err.path}"`;
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
return void 0;
|
|
1255
|
+
}
|
|
1088
1256
|
async function installSkills(options) {
|
|
1257
|
+
const transaction = new InstallTransaction();
|
|
1089
1258
|
const skillsToInstall = [...options.selectedSkillIds];
|
|
1090
1259
|
if (!skillsToInstall.includes("groove-harness")) {
|
|
1091
1260
|
skillsToInstall.push("groove-harness");
|
|
@@ -1093,48 +1262,70 @@ async function installSkills(options) {
|
|
|
1093
1262
|
if (!skillsToInstall.includes("odd-ai")) {
|
|
1094
1263
|
skillsToInstall.push("odd-ai");
|
|
1095
1264
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
const
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
for (const agentId of options.selectedAgents) {
|
|
1106
|
-
const adapter = ADAPTER_REGISTRY[agentId];
|
|
1107
|
-
if (!adapter) {
|
|
1265
|
+
let currentStage = "Sincronizaci\xF3n del almac\xE9n de skills (.grooveskills/skills)";
|
|
1266
|
+
try {
|
|
1267
|
+
syncProjectStore(options.targetPath, skillsToInstall, options.selectedAgents, transaction);
|
|
1268
|
+
const projectSkillsDir = getProjectSkillsDir(options.targetPath);
|
|
1269
|
+
const createdFiles = [];
|
|
1270
|
+
currentStage = "Configuraci\xF3n de referencias de agentes (.agents, .claude, etc.)";
|
|
1271
|
+
for (const skillId of skillsToInstall) {
|
|
1272
|
+
const skill = SKILL_CATALOG.find((item) => item.id === skillId);
|
|
1273
|
+
if (!skill) {
|
|
1108
1274
|
continue;
|
|
1109
1275
|
}
|
|
1110
|
-
const
|
|
1111
|
-
|
|
1276
|
+
const skillSourceDir = join11(projectSkillsDir, skill.directoryName);
|
|
1277
|
+
for (const agentId of options.selectedAgents) {
|
|
1278
|
+
const adapter = ADAPTER_REGISTRY[agentId];
|
|
1279
|
+
if (!adapter) {
|
|
1280
|
+
continue;
|
|
1281
|
+
}
|
|
1282
|
+
const files = await adapter.installSkill(
|
|
1283
|
+
options.targetPath,
|
|
1284
|
+
skill,
|
|
1285
|
+
skillSourceDir,
|
|
1286
|
+
transaction
|
|
1287
|
+
);
|
|
1288
|
+
createdFiles.push(...files);
|
|
1289
|
+
}
|
|
1112
1290
|
}
|
|
1291
|
+
currentStage = "Instalaci\xF3n del Groove Harness (contexto, decisiones, tareas e instrucciones)";
|
|
1292
|
+
const harnessResult = installHarness({
|
|
1293
|
+
targetPath: options.targetPath,
|
|
1294
|
+
selectedAgents: options.selectedAgents,
|
|
1295
|
+
selectedSkillIds: skillsToInstall,
|
|
1296
|
+
detectedDependencies: options.detectedDependencies || [],
|
|
1297
|
+
language: options.language,
|
|
1298
|
+
forceOnboarding: options.forceOnboarding,
|
|
1299
|
+
transaction
|
|
1300
|
+
});
|
|
1301
|
+
createdFiles.push(...harnessResult.createdFiles);
|
|
1302
|
+
currentStage = "Persistencia de la configuraci\xF3n del proyecto (.grooveskills/config.json)";
|
|
1303
|
+
const configPath = writeProjectConfig(
|
|
1304
|
+
options.targetPath,
|
|
1305
|
+
skillsToInstall,
|
|
1306
|
+
options.selectedAgents,
|
|
1307
|
+
true,
|
|
1308
|
+
options.language,
|
|
1309
|
+
transaction
|
|
1310
|
+
);
|
|
1311
|
+
createdFiles.push(configPath);
|
|
1312
|
+
return {
|
|
1313
|
+
installedSkills: skillsToInstall,
|
|
1314
|
+
configuredAgents: options.selectedAgents,
|
|
1315
|
+
createdFiles,
|
|
1316
|
+
harnessInitialized: harnessResult.onboardingInitialized,
|
|
1317
|
+
language: options.language
|
|
1318
|
+
};
|
|
1319
|
+
} catch (cause) {
|
|
1320
|
+
const rollbackReport = transaction.rollback();
|
|
1321
|
+
const suggestedFix = formatSuggestedFix(cause);
|
|
1322
|
+
throw new InstallTransactionError({
|
|
1323
|
+
stage: currentStage,
|
|
1324
|
+
cause,
|
|
1325
|
+
rollbackReport,
|
|
1326
|
+
suggestedFix
|
|
1327
|
+
});
|
|
1113
1328
|
}
|
|
1114
|
-
const harnessResult = installHarness({
|
|
1115
|
-
targetPath: options.targetPath,
|
|
1116
|
-
selectedAgents: options.selectedAgents,
|
|
1117
|
-
selectedSkillIds: skillsToInstall,
|
|
1118
|
-
detectedDependencies: options.detectedDependencies || [],
|
|
1119
|
-
language: options.language,
|
|
1120
|
-
forceOnboarding: options.forceOnboarding
|
|
1121
|
-
});
|
|
1122
|
-
createdFiles.push(...harnessResult.createdFiles);
|
|
1123
|
-
const configPath = writeProjectConfig(
|
|
1124
|
-
options.targetPath,
|
|
1125
|
-
skillsToInstall,
|
|
1126
|
-
options.selectedAgents,
|
|
1127
|
-
true,
|
|
1128
|
-
options.language
|
|
1129
|
-
);
|
|
1130
|
-
createdFiles.push(configPath);
|
|
1131
|
-
return {
|
|
1132
|
-
installedSkills: skillsToInstall,
|
|
1133
|
-
configuredAgents: options.selectedAgents,
|
|
1134
|
-
createdFiles,
|
|
1135
|
-
harnessInitialized: harnessResult.onboardingInitialized,
|
|
1136
|
-
language: options.language
|
|
1137
|
-
};
|
|
1138
1329
|
}
|
|
1139
1330
|
|
|
1140
1331
|
// src/domains/ui/render-onboarding-prompt.ts
|
|
@@ -1165,7 +1356,7 @@ async function resolveLanguageSelection(harnessExists, configuredLanguage, force
|
|
|
1165
1356
|
}
|
|
1166
1357
|
const langChoice = await promptLanguage(configuredLanguage ?? "es");
|
|
1167
1358
|
if (p5.isCancel(langChoice)) {
|
|
1168
|
-
p5.cancel("
|
|
1359
|
+
p5.cancel("Instalaci\xF3n cancelada. \xA1Que tengas un excelente d\xEDa!");
|
|
1169
1360
|
process.exit(0);
|
|
1170
1361
|
}
|
|
1171
1362
|
return langChoice;
|
|
@@ -1180,31 +1371,53 @@ async function resolveOverwriteConfirmation(targetPath, selectedSkills, selected
|
|
|
1180
1371
|
}
|
|
1181
1372
|
const confirm2 = await promptConfirmOverwrite();
|
|
1182
1373
|
if (p5.isCancel(confirm2) || !confirm2) {
|
|
1183
|
-
p5.cancel("
|
|
1374
|
+
p5.cancel("Instalaci\xF3n detenida para proteger las skills existentes.");
|
|
1184
1375
|
process.exit(0);
|
|
1185
1376
|
}
|
|
1186
1377
|
return Boolean(confirm2);
|
|
1187
1378
|
}
|
|
1379
|
+
function renderInstallFailure(error) {
|
|
1380
|
+
const { stage, causeError, rollbackReport, suggestedFix } = error;
|
|
1381
|
+
const rawMsg = causeError instanceof Error ? causeError.message : String(causeError);
|
|
1382
|
+
const lines = [
|
|
1383
|
+
`${pc3.bold("Fase afectada:")} ${pc3.yellow(stage)}`,
|
|
1384
|
+
`${pc3.bold("Causa:")} ${pc3.red(rawMsg)}`,
|
|
1385
|
+
"",
|
|
1386
|
+
pc3.bold("Reporte de Rollback autom\xE1tico:"),
|
|
1387
|
+
` \u2022 Archivos restaurados a su estado previo: ${pc3.cyan(String(rollbackReport.restoredFiles.length))}`,
|
|
1388
|
+
` \u2022 Archivos temporales eliminados: ${pc3.cyan(String(rollbackReport.removedFiles.length))}`,
|
|
1389
|
+
` \u2022 Directorios vac\xEDos eliminados: ${pc3.cyan(String(rollbackReport.removedDirs.length))}`
|
|
1390
|
+
];
|
|
1391
|
+
if (suggestedFix) {
|
|
1392
|
+
lines.push(
|
|
1393
|
+
"",
|
|
1394
|
+
pc3.bold("Soluci\xF3n recomendada:"),
|
|
1395
|
+
` Ejecuta en tu terminal: ${pc3.green(suggestedFix)}`
|
|
1396
|
+
);
|
|
1397
|
+
}
|
|
1398
|
+
p5.note(lines.join("\n"), "Detalles de la interrupci\xF3n y reversi\xF3n");
|
|
1399
|
+
p5.outro(pc3.yellow("Tu proyecto no sufri\xF3 alteraciones y se preserv\xF3 intacto. Corrige la causa y vuelve a intentarlo cuando gustes."));
|
|
1400
|
+
}
|
|
1188
1401
|
async function runInteractiveUi(context, forceOnboarding = false) {
|
|
1189
1402
|
console.log(renderBanner());
|
|
1190
|
-
p5.intro(pc3.magenta("
|
|
1403
|
+
p5.intro(pc3.magenta("\xA1Bienvenido a GrooveSkills! Configuremos tus agentes de IA con est\xE1ndares limpios de arquitectura."));
|
|
1191
1404
|
if (context.detectedDependencies.length > 0) {
|
|
1192
|
-
const harnessInfo = context.harnessExists && !forceOnboarding ? pc3.green(`
|
|
1405
|
+
const harnessInfo = context.harnessExists && !forceOnboarding ? pc3.green(`Activo (.grooveskills/memory, idioma: ${context.configuredLanguage ?? "es"})`) : pc3.cyan("Ser\xE1 inicializado");
|
|
1193
1406
|
p5.note(
|
|
1194
|
-
`
|
|
1195
|
-
|
|
1407
|
+
`Dependencias detectadas: ${context.detectedDependencies.map((d) => pc3.bold(d)).join(", ")}
|
|
1408
|
+
Carpetas de IA activas: ${context.detectedAgents.map((a) => pc3.green(a)).join(", ") || "Ninguna (se crear\xE1n)"}
|
|
1196
1409
|
GrooveSkills Harness: ${harnessInfo}`,
|
|
1197
|
-
"
|
|
1410
|
+
"Entorno del Proyecto"
|
|
1198
1411
|
);
|
|
1199
1412
|
}
|
|
1200
1413
|
const selectedSkills = await promptSkills(context.suggestedSkillIds);
|
|
1201
1414
|
if (p5.isCancel(selectedSkills)) {
|
|
1202
|
-
p5.cancel("
|
|
1415
|
+
p5.cancel("Instalaci\xF3n cancelada. \xA1Que tengas un excelente d\xEDa!");
|
|
1203
1416
|
process.exit(0);
|
|
1204
1417
|
}
|
|
1205
1418
|
const selectedAgents = await promptAgents(context.detectedAgents);
|
|
1206
1419
|
if (p5.isCancel(selectedAgents)) {
|
|
1207
|
-
p5.cancel("
|
|
1420
|
+
p5.cancel("Instalaci\xF3n cancelada. \xA1Que tengas un excelente d\xEDa!");
|
|
1208
1421
|
process.exit(0);
|
|
1209
1422
|
}
|
|
1210
1423
|
const selectedLanguage = await resolveLanguageSelection(
|
|
@@ -1218,33 +1431,42 @@ GrooveSkills Harness: ${harnessInfo}`,
|
|
|
1218
1431
|
selectedAgents
|
|
1219
1432
|
);
|
|
1220
1433
|
const s = p5.spinner();
|
|
1221
|
-
s.start("
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
`Configured skills: ${result.installedSkills.map((s2) => pc3.bold(s2)).join(", ")}
|
|
1236
|
-
Target agents: ${result.configuredAgents.map((a) => pc3.cyan(a)).join(", ")}
|
|
1237
|
-
GrooveSkills Harness: ${harnessStatus}`,
|
|
1238
|
-
"Installation Summary"
|
|
1239
|
-
);
|
|
1240
|
-
if (result.harnessInitialized) {
|
|
1241
|
-
const promptRender = formatOnboardingPrompt(selectedLanguage);
|
|
1434
|
+
s.start("Instalando y adaptando skills para tus agentes de IA configurados...");
|
|
1435
|
+
try {
|
|
1436
|
+
const result = await installSkills({
|
|
1437
|
+
targetPath: context.targetPath,
|
|
1438
|
+
selectedSkillIds: selectedSkills,
|
|
1439
|
+
selectedAgents,
|
|
1440
|
+
forceOverwrite,
|
|
1441
|
+
enableHarness: true,
|
|
1442
|
+
detectedDependencies: context.detectedDependencies,
|
|
1443
|
+
language: selectedLanguage,
|
|
1444
|
+
forceOnboarding
|
|
1445
|
+
});
|
|
1446
|
+
s.stop(pc3.green("\xA1Todas las skills y el harness fueron configurados exitosamente!"));
|
|
1447
|
+
const harnessStatus = result.harnessInitialized ? pc3.green(`Inicializado en .grooveskills/ (Idioma: ${selectedLanguage})`) : pc3.cyan(`Preservado en .grooveskills/ (Idioma: ${selectedLanguage})`);
|
|
1242
1448
|
p5.note(
|
|
1243
|
-
pc3.
|
|
1244
|
-
|
|
1449
|
+
`Skills configuradas: ${result.installedSkills.map((sk) => pc3.bold(sk)).join(", ")}
|
|
1450
|
+
Agentes objetivo: ${result.configuredAgents.map((a) => pc3.cyan(a)).join(", ")}
|
|
1451
|
+
GrooveSkills Harness: ${harnessStatus}`,
|
|
1452
|
+
"Resumen de Instalaci\xF3n"
|
|
1245
1453
|
);
|
|
1454
|
+
if (result.harnessInitialized) {
|
|
1455
|
+
const promptRender = formatOnboardingPrompt(selectedLanguage);
|
|
1456
|
+
p5.note(
|
|
1457
|
+
pc3.green(promptRender.prompt),
|
|
1458
|
+
promptRender.title
|
|
1459
|
+
);
|
|
1460
|
+
}
|
|
1461
|
+
p5.outro(pc3.green("\xA1Tus agentes de IA ahora est\xE1n potenciados con los h\xE1bitos arquitect\xF3nicos de tu equipo! \u{1F680}"));
|
|
1462
|
+
} catch (error) {
|
|
1463
|
+
s.stop(pc3.yellow("La instalaci\xF3n no pudo completarse."));
|
|
1464
|
+
if (error instanceof InstallTransactionError) {
|
|
1465
|
+
renderInstallFailure(error);
|
|
1466
|
+
return;
|
|
1467
|
+
}
|
|
1468
|
+
throw error;
|
|
1246
1469
|
}
|
|
1247
|
-
p5.outro(pc3.green("Your AI programming pair is now empowered with your team's architectural habits! \u{1F680}"));
|
|
1248
1470
|
}
|
|
1249
1471
|
|
|
1250
1472
|
// src/main.ts
|
|
@@ -1279,6 +1501,7 @@ ${promptRender.formattedOutput}
|
|
|
1279
1501
|
}
|
|
1280
1502
|
|
|
1281
1503
|
export {
|
|
1504
|
+
InstallTransactionError,
|
|
1282
1505
|
runGrooveSkills
|
|
1283
1506
|
};
|
|
1284
|
-
//# sourceMappingURL=chunk-
|
|
1507
|
+
//# sourceMappingURL=chunk-E63GTCOE.js.map
|