conductor-4-all 0.0.19 → 0.0.20

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.
Files changed (3) hide show
  1. package/dist/index.cjs +214 -15
  2. package/dist/index.js +212 -13
  3. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -33,6 +33,54 @@ var import_helpers = require("yargs/helpers");
33
33
 
34
34
  // src/cli/prompt.ts
35
35
  var import_select = __toESM(require("@inquirer/select"), 1);
36
+ async function promptForInstallMode() {
37
+ const answer = await (0, import_select.default)({
38
+ message: "Select installation mode:",
39
+ choices: [
40
+ {
41
+ name: "Slash Custom Prompts (Commands)",
42
+ value: "prompt",
43
+ description: "Install as standard slash commands (e.g. /conductor:implement)"
44
+ },
45
+ {
46
+ name: "Skills",
47
+ value: "skills",
48
+ description: "Install as agentskills.io compliant skills"
49
+ }
50
+ ],
51
+ default: "prompt"
52
+ });
53
+ return answer;
54
+ }
55
+ async function promptForSkillsTarget() {
56
+ const answer = await (0, import_select.default)({
57
+ message: "Select target agent for skills:",
58
+ choices: [
59
+ {
60
+ name: "General Coding Agents",
61
+ value: "general",
62
+ description: "Install to .agents/skills/ directory"
63
+ },
64
+ {
65
+ name: "Claude Code",
66
+ value: "claude-code",
67
+ description: "Install to .claude/skills/ directory"
68
+ },
69
+ {
70
+ name: "Antigravity",
71
+ value: "antigravity",
72
+ description: "Install to .agents/skills/ with GEMINI.md protocol"
73
+ },
74
+ {
75
+ name: "Gemini CLI",
76
+ value: "gemini",
77
+ description: "Install to .agents/skills/ with GEMINI.md protocol"
78
+ }
79
+ ],
80
+ default: "general"
81
+ });
82
+ return answer;
83
+ }
36
84
  async function promptForInstallScope(agent) {
37
85
  const isCodex = agent === "codex";
38
86
  const isCline = agent === "cline";
@@ -118,21 +166,14 @@ function substituteVariables(template, variables) {
118
166
  });
119
167
  }
120
168
  async function getTemplateRoot() {
121
- const candidates = [
122
- (0, import_path.join)(__dirname, "templates"),
123
- (0, import_path.join)(__dirname, "../templates"),
124
- (0, import_path.join)(__dirname, "../../gemini-conductor-codebase")
125
- ];
126
- for (const path of candidates) {
127
- try {
128
- if ((await (0, import_promises.stat)(path)).isDirectory()) {
129
- return path;
130
- }
131
- } catch {
132
- continue;
169
+ const templateRoot = (0, import_path.join)(__dirname, "templates");
170
+ try {
171
+ if ((await (0, import_promises.stat)(templateRoot)).isDirectory()) {
172
+ return templateRoot;
133
173
  }
174
+ } catch {
134
175
  }
135
- throw new Error(`Template directory not found. Searched in: ${candidates.join(", ")}`);
176
+ throw new Error(`Template directory not found. Searched in: ${templateRoot}`);
136
177
  }
137
178
  async function loadTemplate(templatePath) {
138
179
  const rootDir = await getTemplateRoot();
@@ -585,13 +626,171 @@ function getGenerator(agentType) {
585
626
  return new OpenCodeGenerator();
586
627
  }
587
628
  }
629
+ function getGeneratorConfig(agentType) {
630
+ switch (agentType) {
631
+ case "claude-code":
632
+ return claudeCodeConfig;
633
+ case "antigravity":
634
+ return antigravityConfig;
635
+ case "cursor":
636
+ return cursorConfig;
637
+ case "vscode-copilot":
638
+ return vscodeCopilotConfig;
639
+ case "codex":
640
+ return codexConfig;
641
+ case "windsurf":
642
+ return windsurfConfig;
643
+ case "cline":
644
+ return clineConfig;
645
+ case "gemini":
646
+ return geminiConfig;
647
+ case "opencode":
648
+ default:
649
+ return opencodeConfig;
650
+ }
651
+ }
588
652
 
589
- // src/commands/install.ts
653
+ // src/skills-generators/general/index.ts
654
+ var import_path6 = require("path");
655
+
656
+ // src/skills-generators/base.ts
590
657
  var import_path5 = require("path");
658
+ var import_select3 = __toESM(require("@inquirer/select"), 1);
659
+ var import_fs_extra4 = __toESM(require("fs-extra"), 1);
660
+ var import_smol_toml5 = require("smol-toml");
661
+ var { ensureDir: ensureDir2, writeFile: writeFile4, copy: copy2, existsSync: existsSync2 } = import_fs_extra4.default;
662
+ var BaseSkillsGenerator = class {
663
+ constructor(agentConfig) {
664
+ this.agentConfig = agentConfig;
665
+ }
666
+ getTemplateInstallPath(cmd) {
667
+ if (cmd === "setup") {
668
+ return `${this.getInstallPath()}/skills/conductor-setup`;
669
+ }
670
+ return this.getInstallPath();
671
+ }
672
+ async generate(targetDir) {
673
+ const commands = ["setup", "newTrack", "implement", "status", "revert", "review"];
674
+ const skillsBaseDir = this.getSkillsBaseDir(targetDir);
675
+ const templateRoot = await getTemplateRoot();
676
+ if (this.agentConfig?.protocolFilename) {
677
+ const templateProtocolSource = (0, import_path5.join)(templateRoot, "GEMINI.md");
678
+ const protocolDest = (0, import_path5.join)(targetDir, this.agentConfig.protocolFilename);
679
+ if (existsSync2(templateProtocolSource)) {
680
+ let shouldCopy = true;
681
+ if (existsSync2(protocolDest)) {
682
+ shouldCopy = await (0, import_select3.default)({
683
+ message: `The protocol file '${this.agentConfig.protocolFilename}' already exists. Do you want to overwrite it?`,
684
+ choices: [
685
+ { value: true, name: "Overwrite" },
686
+ { value: false, name: "Skip" }
687
+ ]
688
+ });
689
+ }
690
+ if (shouldCopy) {
691
+ await copy2(templateProtocolSource, protocolDest);
692
+ }
693
+ }
694
+ }
695
+ for (const cmd of commands) {
696
+ try {
697
+ const tomlContent = await loadTemplate(`commands/${cmd}.toml`);
698
+ const parsed = (0, import_smol_toml5.parse)(tomlContent);
699
+ if (!parsed.prompt) {
700
+ continue;
701
+ }
702
+ const skillName = `conductor-${cmd}`;
703
+ const description = parsed.description || `Conductor ${cmd} command`;
704
+ const installPath = this.getTemplateInstallPath(cmd);
705
+ let prompt = parsed.prompt;
706
+ prompt = prompt.replace(/__\$\$CODE_AGENT_INSTALL_PATH\$\$__/g, installPath);
707
+ const finalContent = substituteVariables(prompt, { agent_type: "general" });
708
+ const skillContent = `---
709
+ name: ${skillName}
710
+ description: ${description}
711
+ ---
712
+
713
+ ${finalContent}
714
+ `;
715
+ const skillDir = (0, import_path5.join)(skillsBaseDir, skillName);
716
+ await ensureDir2(skillDir);
717
+ await writeFile4((0, import_path5.join)(skillDir, "SKILL.md"), skillContent);
718
+ await this.onSkillGenerated(skillDir, cmd);
719
+ } catch (e) {
720
+ console.warn(`Failed to process skill ${cmd}:`, e);
721
+ }
722
+ }
723
+ }
724
+ async onSkillGenerated(skillDir, cmd) {
725
+ if (cmd === "setup") {
726
+ const templateRoot = await getTemplateRoot();
727
+ const templateSrc = (0, import_path5.join)(templateRoot, "templates");
728
+ const templateDest = (0, import_path5.join)(skillDir, "templates");
729
+ await copy2(templateSrc, templateDest);
730
+ }
731
+ }
732
+ };
733
+
734
+ // src/skills-generators/general/index.ts
735
+ var GeneralSkillsGenerator = class extends BaseSkillsGenerator {
736
+ constructor(agentConfig) {
737
+ super(agentConfig);
738
+ }
739
+ getSkillsBaseDir(targetDir) {
740
+ return (0, import_path6.join)(targetDir, ".agents", "skills");
741
+ }
742
+ getInstallPath() {
743
+ return ".agents";
744
+ }
745
+ };
746
+
747
+ // src/skills-generators/claude-code/index.ts
748
+ var import_path7 = require("path");
749
+ var ClaudeCodeSkillsGenerator = class extends BaseSkillsGenerator {
750
+ constructor(agentConfig) {
751
+ super(agentConfig);
752
+ }
753
+ getSkillsBaseDir(targetDir) {
754
+ return (0, import_path7.join)(targetDir, ".claude", "skills");
755
+ }
756
+ getInstallPath() {
757
+ return ".claude";
758
+ }
759
+ };
760
+
761
+ // src/skills-generators/factory.ts
762
+ function getSkillsGenerator(target, agentConfig) {
763
+ switch (target) {
764
+ case "general":
765
+ case "antigravity":
766
+ case "gemini":
767
+ return new GeneralSkillsGenerator(agentConfig);
768
+ case "claude-code":
769
+ return new ClaudeCodeSkillsGenerator(agentConfig);
770
+ default:
771
+ throw new Error(`Unsupported skills target: ${target}`);
772
+ }
773
+ }
774
+
775
+ // src/commands/install.ts
776
+ var import_path8 = require("path");
591
777
  async function installHandler(argv) {
592
- const targetDir = (0, import_path5.resolve)(process.cwd(), argv.path);
778
+ const targetDir = (0, import_path8.resolve)(process.cwd(), argv.path);
593
779
  try {
594
780
  console.log(`Initializing Conductor in: ${targetDir}`);
781
+ const installMode = await promptForInstallMode();
782
+ if (installMode === "skills") {
783
+ console.log("Step 1: Prompting for skills target selection...");
784
+ const target = await promptForSkillsTarget();
785
+ console.log(`\u2714 Selected skills target: ${target}`);
786
+ const selectedAgent = target === "general" ? argv.agent ?? "opencode" : target;
787
+ const agentConfig = getGeneratorConfig(selectedAgent);
788
+ const skillsGenerator = getSkillsGenerator(target, agentConfig);
789
+ console.log("\nStep 2: Generating skills...");
790
+ await skillsGenerator.generate(targetDir);
791
+ console.log("\n\u2714 Conductor skills initialized successfully!");
792
+ return;
793
+ }
595
794
  let agent;
596
795
  if (argv.agent) {
597
796
  agent = argv.agent;
package/dist/index.js CHANGED
@@ -6,6 +6,54 @@ import { hideBin } from "yargs/helpers";
6
6
 
7
7
  // src/cli/prompt.ts
8
8
  import select from "@inquirer/select";
9
+ async function promptForInstallMode() {
10
+ const answer = await select({
11
+ message: "Select installation mode:",
12
+ choices: [
13
+ {
14
+ name: "Slash Custom Prompts (Commands)",
15
+ value: "prompt",
16
+ description: "Install as standard slash commands (e.g. /conductor:implement)"
17
+ },
18
+ {
19
+ name: "Skills",
20
+ value: "skills",
21
+ description: "Install as agentskills.io compliant skills"
22
+ }
23
+ ],
24
+ default: "prompt"
25
+ });
26
+ return answer;
27
+ }
28
+ async function promptForSkillsTarget() {
29
+ const answer = await select({
30
+ message: "Select target agent for skills:",
31
+ choices: [
32
+ {
33
+ name: "General Coding Agents",
34
+ value: "general",
35
+ description: "Install to .agents/skills/ directory"
36
+ },
37
+ {
38
+ name: "Claude Code",
39
+ value: "claude-code",
40
+ description: "Install to .claude/skills/ directory"
41
+ },
42
+ {
43
+ name: "Antigravity",
44
+ value: "antigravity",
45
+ description: "Install to .agents/skills/ with GEMINI.md protocol"
46
+ },
47
+ {
48
+ name: "Gemini CLI",
49
+ value: "gemini",
50
+ description: "Install to .agents/skills/ with GEMINI.md protocol"
51
+ }
52
+ ],
53
+ default: "general"
54
+ });
55
+ return answer;
56
+ }
9
57
  async function promptForInstallScope(agent) {
10
58
  const isCodex = agent === "codex";
11
59
  const isCline = agent === "cline";
@@ -91,21 +139,14 @@ function substituteVariables(template, variables) {
91
139
  });
92
140
  }
93
141
  async function getTemplateRoot() {
94
- const candidates = [
95
- join(__dirname2, "templates"),
96
- join(__dirname2, "../templates"),
97
- join(__dirname2, "../../gemini-conductor-codebase")
98
- ];
99
- for (const path of candidates) {
100
- try {
101
- if ((await stat(path)).isDirectory()) {
102
- return path;
103
- }
104
- } catch {
105
- continue;
142
+ const templateRoot = join(__dirname2, "templates");
143
+ try {
144
+ if ((await stat(templateRoot)).isDirectory()) {
145
+ return templateRoot;
106
146
  }
147
+ } catch {
107
148
  }
108
- throw new Error(`Template directory not found. Searched in: ${candidates.join(", ")}`);
149
+ throw new Error(`Template directory not found. Searched in: ${templateRoot}`);
109
150
  }
110
151
  async function loadTemplate(templatePath) {
111
152
  const rootDir = await getTemplateRoot();
@@ -558,6 +599,151 @@ function getGenerator(agentType) {
558
599
  return new OpenCodeGenerator();
559
600
  }
560
601
  }
602
+ function getGeneratorConfig(agentType) {
603
+ switch (agentType) {
604
+ case "claude-code":
605
+ return claudeCodeConfig;
606
+ case "antigravity":
607
+ return antigravityConfig;
608
+ case "cursor":
609
+ return cursorConfig;
610
+ case "vscode-copilot":
611
+ return vscodeCopilotConfig;
612
+ case "codex":
613
+ return codexConfig;
614
+ case "windsurf":
615
+ return windsurfConfig;
616
+ case "cline":
617
+ return clineConfig;
618
+ case "gemini":
619
+ return geminiConfig;
620
+ case "opencode":
621
+ default:
622
+ return opencodeConfig;
623
+ }
624
+ }
625
+
626
+ // src/skills-generators/general/index.ts
627
+ import { join as join6 } from "path";
628
+
629
+ // src/skills-generators/base.ts
630
+ import { join as join5 } from "path";
631
+ import select3 from "@inquirer/select";
632
+ import fs4 from "fs-extra";
633
+ import { parse as parse5 } from "smol-toml";
634
+ var { ensureDir: ensureDir2, writeFile: writeFile4, copy: copy2, existsSync: existsSync2 } = fs4;
635
+ var BaseSkillsGenerator = class {
636
+ constructor(agentConfig) {
637
+ this.agentConfig = agentConfig;
638
+ }
639
+ getTemplateInstallPath(cmd) {
640
+ if (cmd === "setup") {
641
+ return `${this.getInstallPath()}/skills/conductor-setup`;
642
+ }
643
+ return this.getInstallPath();
644
+ }
645
+ async generate(targetDir) {
646
+ const commands = ["setup", "newTrack", "implement", "status", "revert", "review"];
647
+ const skillsBaseDir = this.getSkillsBaseDir(targetDir);
648
+ const templateRoot = await getTemplateRoot();
649
+ if (this.agentConfig?.protocolFilename) {
650
+ const templateProtocolSource = join5(templateRoot, "GEMINI.md");
651
+ const protocolDest = join5(targetDir, this.agentConfig.protocolFilename);
652
+ if (existsSync2(templateProtocolSource)) {
653
+ let shouldCopy = true;
654
+ if (existsSync2(protocolDest)) {
655
+ shouldCopy = await select3({
656
+ message: `The protocol file '${this.agentConfig.protocolFilename}' already exists. Do you want to overwrite it?`,
657
+ choices: [
658
+ { value: true, name: "Overwrite" },
659
+ { value: false, name: "Skip" }
660
+ ]
661
+ });
662
+ }
663
+ if (shouldCopy) {
664
+ await copy2(templateProtocolSource, protocolDest);
665
+ }
666
+ }
667
+ }
668
+ for (const cmd of commands) {
669
+ try {
670
+ const tomlContent = await loadTemplate(`commands/${cmd}.toml`);
671
+ const parsed = parse5(tomlContent);
672
+ if (!parsed.prompt) {
673
+ continue;
674
+ }
675
+ const skillName = `conductor-${cmd}`;
676
+ const description = parsed.description || `Conductor ${cmd} command`;
677
+ const installPath = this.getTemplateInstallPath(cmd);
678
+ let prompt = parsed.prompt;
679
+ prompt = prompt.replace(/__\$\$CODE_AGENT_INSTALL_PATH\$\$__/g, installPath);
680
+ const finalContent = substituteVariables(prompt, { agent_type: "general" });
681
+ const skillContent = `---
682
+ name: ${skillName}
683
+ description: ${description}
684
+ ---
685
+
686
+ ${finalContent}
687
+ `;
688
+ const skillDir = join5(skillsBaseDir, skillName);
689
+ await ensureDir2(skillDir);
690
+ await writeFile4(join5(skillDir, "SKILL.md"), skillContent);
691
+ await this.onSkillGenerated(skillDir, cmd);
692
+ } catch (e) {
693
+ console.warn(`Failed to process skill ${cmd}:`, e);
694
+ }
695
+ }
696
+ }
697
+ async onSkillGenerated(skillDir, cmd) {
698
+ if (cmd === "setup") {
699
+ const templateRoot = await getTemplateRoot();
700
+ const templateSrc = join5(templateRoot, "templates");
701
+ const templateDest = join5(skillDir, "templates");
702
+ await copy2(templateSrc, templateDest);
703
+ }
704
+ }
705
+ };
706
+
707
+ // src/skills-generators/general/index.ts
708
+ var GeneralSkillsGenerator = class extends BaseSkillsGenerator {
709
+ constructor(agentConfig) {
710
+ super(agentConfig);
711
+ }
712
+ getSkillsBaseDir(targetDir) {
713
+ return join6(targetDir, ".agents", "skills");
714
+ }
715
+ getInstallPath() {
716
+ return ".agents";
717
+ }
718
+ };
719
+
720
+ // src/skills-generators/claude-code/index.ts
721
+ import { join as join7 } from "path";
722
+ var ClaudeCodeSkillsGenerator = class extends BaseSkillsGenerator {
723
+ constructor(agentConfig) {
724
+ super(agentConfig);
725
+ }
726
+ getSkillsBaseDir(targetDir) {
727
+ return join7(targetDir, ".claude", "skills");
728
+ }
729
+ getInstallPath() {
730
+ return ".claude";
731
+ }
732
+ };
733
+
734
+ // src/skills-generators/factory.ts
735
+ function getSkillsGenerator(target, agentConfig) {
736
+ switch (target) {
737
+ case "general":
738
+ case "antigravity":
739
+ case "gemini":
740
+ return new GeneralSkillsGenerator(agentConfig);
741
+ case "claude-code":
742
+ return new ClaudeCodeSkillsGenerator(agentConfig);
743
+ default:
744
+ throw new Error(`Unsupported skills target: ${target}`);
745
+ }
746
+ }
561
747
 
562
748
  // src/commands/install.ts
563
749
  import { resolve as resolve2 } from "path";
@@ -565,6 +751,19 @@ async function installHandler(argv) {
565
751
  const targetDir = resolve2(process.cwd(), argv.path);
566
752
  try {
567
753
  console.log(`Initializing Conductor in: ${targetDir}`);
754
+ const installMode = await promptForInstallMode();
755
+ if (installMode === "skills") {
756
+ console.log("Step 1: Prompting for skills target selection...");
757
+ const target = await promptForSkillsTarget();
758
+ console.log(`\u2714 Selected skills target: ${target}`);
759
+ const selectedAgent = target === "general" ? argv.agent ?? "opencode" : target;
760
+ const agentConfig = getGeneratorConfig(selectedAgent);
761
+ const skillsGenerator = getSkillsGenerator(target, agentConfig);
762
+ console.log("\nStep 2: Generating skills...");
763
+ await skillsGenerator.generate(targetDir);
764
+ console.log("\n\u2714 Conductor skills initialized successfully!");
765
+ return;
766
+ }
568
767
  let agent;
569
768
  if (argv.agent) {
570
769
  agent = argv.agent;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conductor-4-all",
3
- "version": "0.0.19",
3
+ "version": "0.0.20",
4
4
  "description": "Conductor spec-driven development CLI - TypeScript/Node.js version",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {