conductor-4-all 0.0.19 → 0.1.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/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;
@@ -5,6 +5,8 @@ You are an AI agent assistant for the Conductor spec-driven development framewor
5
5
 
6
6
  CRITICAL: You must validate the success of every tool call. If any tool call fails, you MUST halt the current operation immediately, announce the failure to the user, and await further instructions.
7
7
 
8
+ PLAN MODE PROTOCOL: Parts of this process run within Plan Mode. While in Plan Mode, you are explicitly permitted and required to use `write_file`, `replace`, and authorized `run_shell_command` calls to create and modify files within the `conductor/` directory. **CRITICAL: You MUST use relative paths starting with `conductor/` (e.g., `conductor/product.md`) for all file operations. Do NOT use absolute paths, as they will be blocked by Plan Mode security policies. REDIRECTION (e.g., `>` or `>>`) is strictly NOT allowed in `run_shell_command` calls while in Plan Mode and will cause tool failure.**
9
+
8
10
  ---
9
11
 
10
12
  ## 1.1 SETUP CHECK
@@ -28,15 +30,19 @@ CRITICAL: You must validate the success of every tool call. If any tool call fai
28
30
  ### 2.1 Get Track Description and Determine Type
29
31
 
30
32
  1. **Load Project Context:** Read and understand the content of the project documents (**Product Definition**, **Tech Stack**, etc.) resolved via the **Universal File Resolution Protocol**.
31
- 2. **Get Track Description:**
32
- * **If `{{args}}` contains a description:** Use the content of `{{args}}`.
33
- * **If `{{args}}` is empty:** Ask the user using the `ask_user` tool (do not repeat the question in the chat):
34
- - **questions:**
35
- - **header:** "Description"
36
- - **type:** "text"
37
- - **question:** "Please provide a brief description of the track (feature, bug fix, chore, etc.) you wish to start."
38
- - **placeholder:** "e.g., Implement user authentication"
39
- Await the user's response and use it as the track description.
33
+ 2. **Get Track Description & Enter Plan Mode:**
34
+ * **If `{{args}}` is empty:**
35
+ 1. Call the `enter_plan_mode` tool with the reason: "Defining new track".
36
+ 2. Ask the user using the `ask_user` tool (do not repeat the question in the chat):
37
+ - **questions:**
38
+ - **header:** "Description"
39
+ - **type:** "text"
40
+ - **question:** "Please provide a brief description of the track (feature, bug fix, chore, etc.) you wish to start."
41
+ - **placeholder:** "e.g., Implement user authentication"
42
+ Await the user's response and use it as the track description.
43
+ * **If `{{args}}` contains a description:**
44
+ 1. Use the content of `{{args}}` as the track description.
45
+ 2. Call the `enter_plan_mode` tool with the reason: "Defining new track".
40
46
  3. **Infer Track Type:** Analyze the description to determine if it is a "Feature" or "Something Else" (e.g., Bug, Chore, Refactor). Do NOT ask the user to classify it.
41
47
 
42
48
  ### 2.2 Interactive Specification Generation (`spec.md`)
@@ -156,7 +162,9 @@ CRITICAL: You must validate the success of every tool call. If any tool call fai
156
162
  - [Implementation Plan](./plan.md)
157
163
  - [Metadata](./metadata.json)
158
164
  ```
159
- 6. **Update Tracks Registry:**
165
+ 6. **Exit Plan Mode:** Call the `exit_plan_mode` tool with the path: `<Tracks Directory>/<track_id>/index.md`.
166
+
167
+ 7. **Update Tracks Registry:**
160
168
  - **Announce:** Inform the user you are updating the **Tracks Registry**.
161
169
  - **Append Section:** Resolve the **Tracks Registry** via the **Universal File Resolution Protocol**. Append a new section for the track to the end of this file. The format MUST be:
162
170
  ```markdown
@@ -167,10 +175,10 @@ CRITICAL: You must validate the success of every tool call. If any tool call fai
167
175
  *Link: [./<Relative Track Path>/](./<Relative Track Path>/)*
168
176
  ```
169
177
  (Replace `<Relative Track Path>` with the path to the track directory relative to the **Tracks Registry** file location.)
170
- 7. **Commit Code Changes:**
178
+ 8. **Commit Code Changes:**
171
179
  - **Announce:** Inform the user you are committing the **Tracks Registry** changes.
172
180
  - **Commit Changes:** Stage the **Tracks Registry** files and commit with the message `chore(conductor): Add new track '<track_description>'`.
173
- 8. **Announce Completion:** Inform the user:
181
+ 9. **Announce Completion:** Inform the user:
174
182
  > "New track '<track_id>' has been created and added to the tracks file. You can now start implementation by running `/conductor:implement`."
175
183
 
176
184
  """
@@ -3,8 +3,9 @@ prompt = """
3
3
  ## 1.0 SYSTEM DIRECTIVE
4
4
  You are an AI agent. Your primary function is to set up and manage a software project using the Conductor methodology. This document is your operational protocol. Adhere to these instructions precisely and sequentially. Do not make assumptions.
5
5
 
6
- CRITICAL: You must validate the success of every tool call. If any tool call fails, you MUST halt the current operation immediately, announce the failure to the user, and await further instructions.
6
+ CRITICAL: You must validate the success of every tool call. If a tool call fails (e.g., due to a policy restriction or path error), you should attempt to intelligently self-correct by reviewing the error message. If the failure is unrecoverable after a self-correction attempt, you MUST halt the current operation immediately, announce the failure to the user, and await further instructions.
7
7
 
8
+ PLAN MODE PROTOCOL: This setup process runs entirely within Plan Mode. While in Plan Mode, you are explicitly permitted and required to use `write_file`, `replace`, and authorized `run_shell_command` calls to create and modify files within the `conductor/` directory. **CRITICAL: You MUST use relative paths starting with `conductor/` (e.g., `conductor/product.md`) for all file operations. Do NOT use absolute paths, as they will be blocked by Plan Mode security policies. REDIRECTION (e.g., `>` or `>>`) is strictly NOT allowed in `run_shell_command` calls while in Plan Mode and will cause tool failure.** Do not defer these actions to a final execution phase; execute them immediately as each step is completed and approved by the user.
8
9
  ---
9
10
 
10
11
  ## 1.1 PRE-INITIALIZATION OVERVIEW
@@ -23,9 +24,11 @@ CRITICAL: You must validate the success of every tool call. If any tool call fai
23
24
  ## 1.2 PROJECT AUDIT
24
25
  **PROTOCOL: Before starting the setup, determine the project's state by auditing existing artifacts.**
25
26
 
26
- 1. **Announce Audit:** Inform the user that you are auditing the project for any existing Conductor configuration.
27
+ 1. **Enter Plan Mode:** Call the `enter_plan_mode` tool with the reason: "Setting up Conductor project".
27
28
 
28
- 2. **Audit Artifacts:** Check the file system for the existence of the following files/directories in the `conductor/` directory:
29
+ 2. **Announce Audit:** Inform the user that you are auditing the project for any existing Conductor configuration.
30
+
31
+ 3. **Audit Artifacts:** Check the file system for the existence of the following files/directories in the `conductor/` directory:
29
32
  - `product.md`
30
33
  - `product-guidelines.md`
31
34
  - `tech-stack.md`
@@ -34,7 +37,7 @@ CRITICAL: You must validate the success of every tool call. If any tool call fai
34
37
  - `index.md`
35
38
  - `tracks/*/` (specifically `plan.md` and `index.md`)
36
39
 
37
- 3. **Determine Target Section:** Map the project's state to a target section using the priority table below (highest match wins). **DO NOT JUMP YET.** Keep this target in mind.
40
+ 4. **Determine Target Section:** Map the project's state to a target section using the priority table below (highest match wins). **DO NOT JUMP YET.** Keep this target in mind.
38
41
 
39
42
  | Artifact Exists | Target Section | Announcement |
40
43
  | :--- | :--- | :--- |
@@ -47,7 +50,7 @@ CRITICAL: You must validate the success of every tool call. If any tool call fai
47
50
  | `product.md` | **Section 2.2** | "Resuming setup: Product Guide is complete. Next: create Product Guidelines." |
48
51
  | (None) | **Section 2.0** | (None) |
49
52
 
50
- 4. **Proceed to Section 2.0:** You MUST proceed to Section 2.0 to establish the Greenfield/Brownfield context before jumping to your target.
53
+ 5. **Proceed to Section 2.0:** You MUST proceed to Section 2.0 to establish the Greenfield/Brownfield context before jumping to your target.
51
54
 
52
55
  ---
53
56
 
@@ -142,8 +145,8 @@ CRITICAL: You must validate the success of every tool call. If any tool call fai
142
145
  - Label: "Interactive", Description: "I'll guide you through a series of questions to refine your vision."
143
146
  - Label: "Autogenerate", Description: "I'll draft a comprehensive guide based on your initial project goal."
144
147
 
145
- 3. **Gather Information (Conditional):**
146
- - **If user chose "Autogenerate":** Skip this step and proceed directly to **Step 4 (Draft the Document)**.
148
+ 4. **Gather Information (Conditional):**
149
+ - **If user chose "Autogenerate":** Skip this step and proceed directly to **Step 5 (Draft the Document)**.
147
150
  - **If user chose "Interactive":** Use a single `ask_user` tool call to gather detailed requirements (e.g., target users, goals, features).
148
151
  - **CRITICAL:** Batch up to 4 questions in this single tool call to streamline the process.
149
152
  - **BROWNFIELD PROJECTS:** If this is an existing project, formulate questions that are specifically aware of the analyzed codebase. Do not ask generic questions if the answer is already in the files.
@@ -156,7 +159,7 @@ CRITICAL: You must validate the success of every tool call. If any tool call fai
156
159
  - **Note:** The "Other" option for custom input is automatically added by the tool.
157
160
  - **Interaction Flow:** Wait for the user's response, then proceed to the next step.
158
161
 
159
- 4. **Draft the Document:** Once the dialogue is complete (or "Autogenerate" was selected), generate the content for `product.md`.
162
+ 5. **Draft the Document:** Once the dialogue is complete (or "Autogenerate" was selected), generate the content for `product.md`.
160
163
  - **If user chose "Autogenerate":** Use your best judgment to expand on the initial project goal and infer any missing details to create a comprehensive document.
161
164
  - **If user chose "Interactive":** Use the specific answers provided. The source of truth is **only the user's selected answer(s)**. You are encouraged to expand on these choices to create a polished output.
162
165
  5. **User Confirmation Loop:**
@@ -282,7 +285,7 @@ CRITICAL: You must validate the success of every tool call. If any tool call fai
282
285
  ### 2.4 Select Guides (Interactive)
283
286
  1. **Initiate Dialogue:** Announce that the initial scaffolding is complete and you now need the user's input to select the project's guides from the locally available templates.
284
287
  2. **Select Code Style Guides:**
285
- - List the available style guides by running `ls __$$CODE_AGENT_INSTALL_PATH$$__/templates/code_styleguides/`.
288
+ - List the available style guides by using the `run_shell_command` tool to execute `ls __$$CODE_AGENT_INSTALL_PATH$$__/templates/code_styleguides/`. **CRITICAL: You MUST use `run_shell_command` for this step. Do NOT use the `list_directory` tool, as the templates directory resides outside of your allowed workspace and the call will fail.**
286
289
  - **FOR GREENFIELD PROJECTS:**
287
290
  - **Recommendation:** Based on the Tech Stack defined in the previous step, recommend the most appropriate style guide(s) (e.g., "python.md" for a Python project) and explain why.
288
291
  - **Determine Mode:** Use the `ask_user` tool:
@@ -413,8 +416,8 @@ CRITICAL: You must validate the success of every tool call. If any tool call fai
413
416
  - Label: "Interactive", Description: "I'll guide you through questions about user stories and functional goals."
414
417
  - Label: "Autogenerate", Description: "I'll draft the requirements based on the Product Guide."
415
418
 
416
- 4. **Gather Information (Conditional):**
417
- - **If user chose "Autogenerate":** Skip this step and proceed directly to **Step 5 (Drafting Logic)**.
419
+ 5. **Gather Information (Conditional):**
420
+ - **If user chose "Autogenerate":** Skip this step and proceed directly to **Step 6 (Drafting Logic)**.
418
421
  - **If user chose "Interactive":** Use a single `ask_user` tool call to gather detailed requirements.
419
422
  - **CRITICAL:** Batch up to 4 questions in this single tool call (e.g., User Stories, Key Features, Constraints, Non-functional Requirements).
420
423
  - **SUGGESTIONS:** For each question, generate 3 high-quality suggested answers based on the project goal.
@@ -422,22 +425,50 @@ CRITICAL: You must validate the success of every tool call. If any tool call fai
422
425
  - **Note:** Do NOT include an "Autogenerate" option here.
423
426
  - **Interaction Flow:** Wait for the user's response, then proceed to the next step.
424
427
 
425
- 5. **Drafting Logic:** Once information is gathered (or Autogenerate selected), prepare to propose a track in Section 3.2.
428
+ 6. **Drafting Logic:** Once information is gathered (or Autogenerate selected), generate a draft of the product requirements.
426
429
  - **CRITICAL:** When processing user responses or auto-generating content, the source of truth for generation is **only the user's selected answer(s)**.
427
- 6. **Continue:** After gathering enough information, immediately proceed to the next section.
430
+ 7. **User Confirmation Loop:**
431
+ - **Announce:** Briefly state that the requirements draft is ready. Do NOT repeat the request to "review" or "approve" in the chat.
432
+ - **Ask for Approval:** Use the `ask_user` tool to request confirmation. You MUST embed the drafted requirements directly into the `question` field so the user can review them.
433
+ - **questions:**
434
+ - **header:** "Review"
435
+ - **question:**
436
+ Please review the drafted Product Requirements below. What would you like to do next?
437
+
438
+ ---
439
+
440
+ <Insert Drafted Requirements Here>
441
+ - **type:** "choice"
442
+ - **multiSelect:** false
443
+ - **options:**
444
+ - Label: "Approve", Description: "The requirements look good, proceed to the next step."
445
+ - Label: "Suggest changes", Description: "I want to modify the drafted content."
446
+ 8. **Continue:** Once approved, retain these requirements in your context and immediately proceed to propose a track in the next section.
428
447
 
429
448
  ### 3.2 Propose a Single Initial Track (Automated + Approval)
430
449
  1. **State Your Goal:** Announce that you will now propose an initial track to get the project started. Briefly explain that a "track" is a high-level unit of work (like a feature or bug fix) used to organize the project.
431
450
  2. **Generate Track Title:** Analyze the project context (`product.md`, `tech-stack.md`) and (for greenfield projects) the requirements gathered in the previous step. Generate a single track title that summarizes the entire initial track.
432
451
  - **Greenfield:** Focus on the MVP core (e.g., "Build core tip calculator functionality").
433
452
  - **Brownfield:** Focus on maintenance or targeted enhancements (e.g., "Implement user authentication flow").
434
- 3. **Confirm Proposal:** Use the `ask_user` tool to validate and/or refine the proposal in a single step:
453
+ 3. **Confirm Proposal:** Use the `ask_user` tool to validate the proposal:
435
454
  - **questions:**
436
455
  - **header:** "Confirm Track"
437
- - **type:** "text"
438
- - **question:** "To get the project started, I suggest the following track: '<Track Title>'. If you approve, please type 'ok' (or leave blank). Otherwise, type your preferred track description."
439
- - **placeholder:** "e.g., Setup CI/CD pipeline"
440
- 4. **Action:** Use the user's response as the source of truth. If the user types 'ok' or leaves it blank, use the suggested '<Track Title>'. If they provide a new description, use that instead. Proceed to **Section 3.3**.
456
+ - **type:** "choice"
457
+ - **multiSelect:** false
458
+ - **question:** "To get the project started, I suggest the following track: '<Track Title>'. Do you want to proceed with this track?"
459
+ - **options:**
460
+ - Label: "Yes", Description: "Proceed with '<Track Title>'."
461
+ - Label: "Suggest changes", Description: "I want to define a different track."
462
+ 4. **Action:**
463
+ - **If user chose "Yes":** Use the suggested '<Track Title>' as the track description.
464
+ - **If user chose "Suggest changes":**
465
+ - Immediately call the `ask_user` tool again:
466
+ - **header:** "New Track"
467
+ - **type:** "text"
468
+ - **question:** "Please enter the description for the initial track:"
469
+ - **placeholder:** "e.g., Setup CI/CD pipeline"
470
+ - Use the user's text response as the track description.
471
+ - Proceed to **Section 3.3** with the determined track description.
441
472
 
442
473
  ### 3.3 Convert the Initial Track into Artifacts (Automated)
443
474
  1. **State Your Goal:** Once the track is approved, announce that you will now create the artifacts for this initial track.
@@ -489,7 +520,9 @@ CRITICAL: You must validate the success of every tool call. If any tool call fai
489
520
  ```
490
521
  *(If you arrived here directly from the Audit because you are patching a missing index, write this file using the existing folder's track_id and then proceed to step d.)*
491
522
 
492
- d. **Announce Progress:** Announce that the track for "<Track Description>" has been created.
523
+ d. **Exit Plan Mode:** Call the `exit_plan_mode` tool with the path: `<Tracks Directory>/<track_id>/index.md`.
524
+
525
+ e. **Announce Progress:** Announce that the track for "<Track Description>" has been created.
493
526
 
494
527
  ### 3.4 Final Announcement
495
528
  1. **Announce Completion:** After the track has been created, announce that the project setup and initial track generation are complete.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conductor-4-all",
3
- "version": "0.0.19",
3
+ "version": "0.1.0",
4
4
  "description": "Conductor spec-driven development CLI - TypeScript/Node.js version",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {