conductor-4-all 0.0.9 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,9 +45,10 @@ You will be prompted to select your AI Coding Agent:
45
45
  - **Codex**
46
46
  - **Windsurf**
47
47
  - **Cline**
48
+ - **Gemini CLI**
48
49
 
49
50
  This will verify the environment and install the necessary Conductor files:
50
- - **Commands:** Agent-specific prompt files (e.g., `.opencode/commands/conductor:setup.md`) that your agent can execute.
51
+ - **Commands:** Agent-specific prompt or command files (e.g., `.opencode/commands/conductor:setup.md` or `.gemini/commands/conductor:setup.toml`) that your agent can execute.
51
52
  - **Templates:** Workflow guides and style guides (e.g., `.opencode/conductor/templates/`).
52
53
 
53
54
  ### 3. Using Conductor with Your Agent
package/dist/index.cjs CHANGED
@@ -87,6 +87,11 @@ async function promptForAgent() {
87
87
  name: "Cline",
88
88
  value: "cline",
89
89
  description: "Cline AI coding assistant"
90
+ },
91
+ {
92
+ name: "Gemini CLI",
93
+ value: "gemini",
94
+ description: "Google Gemini CLI agent"
90
95
  }
91
96
  ],
92
97
  default: "opencode"
@@ -94,7 +99,7 @@ async function promptForAgent() {
94
99
  return answer;
95
100
  }
96
101
 
97
- // src/generators/ConfigurableGenerator.ts
102
+ // src/generators/default/strategy.ts
98
103
  var import_path2 = require("path");
99
104
  var import_fs_extra = __toESM(require("fs-extra"), 1);
100
105
  var import_smol_toml = require("smol-toml");
@@ -135,35 +140,49 @@ async function loadTemplate(templatePath) {
135
140
  return (0, import_promises.readFile)(fullPath, "utf-8");
136
141
  }
137
142
 
138
- // src/generators/ConfigurableGenerator.ts
139
- var { existsSync, ensureDir, writeFile, copy } = import_fs_extra.default;
140
- function processTemplateContent(tomlContent, installPath, agentType, fixedAgent, commandName) {
141
- const parsed = (0, import_smol_toml.parse)(tomlContent);
142
- if (!parsed.prompt) {
143
- return null;
144
- }
145
- let prompt = parsed.prompt;
146
- prompt = prompt.replace(/__\$\$CODE_AGENT_INSTALL_PATH\$\$__/g, installPath);
147
- const finalContent = substituteVariables(prompt, { agent_type: agentType });
148
- if (agentType === "cline") {
149
- const title = commandName ? commandName.charAt(0).toUpperCase() + commandName.slice(1) : "Command";
150
- return `# Conductor ${title}${parsed.description ? "\n\n" + parsed.description + "\n\n" : "\n\n"}${finalContent}`;
151
- }
152
- if (fixedAgent) {
153
- return `---
154
- description: ${parsed.description || ""}
155
- agent: ${fixedAgent}
156
- ---
157
- ${finalContent}`;
158
- }
159
- if (parsed.description) {
160
- return `---
143
+ // src/generators/default/strategy.ts
144
+ var { writeFile } = import_fs_extra.default;
145
+ var DefaultContentStrategy = class {
146
+ process(templateContent, options) {
147
+ const { installPath, agentType } = options;
148
+ const parsed = (0, import_smol_toml.parse)(templateContent);
149
+ if (!parsed.prompt) {
150
+ return null;
151
+ }
152
+ let prompt = parsed.prompt;
153
+ prompt = prompt.replace(/__\$\$CODE_AGENT_INSTALL_PATH\$\$__/g, installPath);
154
+ const finalContent = substituteVariables(prompt, { agent_type: agentType });
155
+ if (parsed.description) {
156
+ return `---
161
157
  description: ${parsed.description}
162
158
  ---
163
159
  ${finalContent}`;
160
+ }
161
+ return finalContent;
164
162
  }
165
- return finalContent;
166
- }
163
+ };
164
+ var DefaultFileStrategy = class {
165
+ async write(options) {
166
+ const { targetDir, agentDir, commandsDir, commandName, extension, content } = options;
167
+ const fileName = `conductor:${commandName}${extension}`;
168
+ await writeFile((0, import_path2.join)(targetDir, agentDir, commandsDir, fileName), content);
169
+ }
170
+ };
171
+ var defaultContentStrategy = new DefaultContentStrategy();
172
+ var defaultFileStrategy = new DefaultFileStrategy();
173
+
174
+ // src/generators/opencode/config.ts
175
+ var opencodeConfig = {
176
+ agentType: "opencode",
177
+ agentDir: ".opencode",
178
+ commandsDir: "commands",
179
+ displayName: "OpenCode"
180
+ };
181
+
182
+ // src/generators/ConfigurableGenerator.ts
183
+ var import_path3 = require("path");
184
+ var import_fs_extra2 = __toESM(require("fs-extra"), 1);
185
+ var { existsSync, ensureDir, writeFile: writeFile2, copy } = import_fs_extra2.default;
167
186
  var ConfigurableGenerator = class {
168
187
  constructor(config) {
169
188
  this.config = config;
@@ -173,8 +192,8 @@ var ConfigurableGenerator = class {
173
192
  throw new Error(`Target directory does not exist: ${targetDir}`);
174
193
  }
175
194
  const { agentDir, commandsDir, displayName } = this.config;
176
- const setupFile = (0, import_path2.join)(targetDir, agentDir, commandsDir, "conductor:setup.md");
177
- const conductorPath = (0, import_path2.join)(targetDir, agentDir, "conductor");
195
+ const setupFile = (0, import_path3.join)(targetDir, agentDir, commandsDir, "conductor:setup.md");
196
+ const conductorPath = (0, import_path3.join)(targetDir, agentDir, "conductor");
178
197
  if (existsSync(conductorPath) && existsSync(setupFile)) {
179
198
  throw new Error(`Conductor (${displayName}) is already installed in: ${targetDir}`);
180
199
  }
@@ -182,18 +201,18 @@ var ConfigurableGenerator = class {
182
201
  }
183
202
  async generate(targetDir, scope) {
184
203
  const { agentDir, commandsDir, agentType } = this.config;
185
- const agentPath = (0, import_path2.join)(targetDir, agentDir);
186
- const targetCommandsDir = (0, import_path2.join)(agentPath, commandsDir);
187
- let installPath = (0, import_path2.join)(agentDir, "conductor");
204
+ const agentPath = (0, import_path3.join)(targetDir, agentDir);
205
+ const targetCommandsDir = (0, import_path3.join)(agentPath, commandsDir);
206
+ let installPath = (0, import_path3.join)(agentDir, "conductor");
188
207
  if (scope === "global") {
189
208
  installPath = `~/${agentDir}/conductor`;
190
209
  }
191
210
  await ensureDir(targetCommandsDir);
192
- await ensureDir((0, import_path2.join)(agentPath, "conductor"));
211
+ await ensureDir((0, import_path3.join)(agentPath, "conductor"));
193
212
  const templateRoot = await getTemplateRoot();
194
213
  try {
195
- const templateSource = (0, import_path2.join)(templateRoot, "templates");
196
- const templateDest = (0, import_path2.join)(agentPath, "conductor", "templates");
214
+ const templateSource = (0, import_path3.join)(templateRoot, "templates");
215
+ const templateDest = (0, import_path3.join)(agentPath, "conductor", "templates");
197
216
  await copy(templateSource, templateDest);
198
217
  } catch (e) {
199
218
  console.warn("Failed to copy templates directory:", e);
@@ -204,10 +223,23 @@ var ConfigurableGenerator = class {
204
223
  for (const cmd of commands) {
205
224
  try {
206
225
  const tomlContent = await loadTemplate(`commands/${cmd}.toml`);
207
- const finalContent = processTemplateContent(tomlContent, installPath, agentType, fixedAgent, cmd);
226
+ const contentStrategy = this.config.strategy?.content || defaultContentStrategy;
227
+ const finalContent = contentStrategy.process(tomlContent, {
228
+ installPath,
229
+ agentType,
230
+ fixedAgent,
231
+ commandName: cmd
232
+ });
208
233
  if (finalContent) {
209
- const fileName = `conductor:${cmd}${extension}`;
210
- await writeFile((0, import_path2.join)(targetCommandsDir, fileName), finalContent);
234
+ const fileStrategy = this.config.strategy?.file || defaultFileStrategy;
235
+ await fileStrategy.write({
236
+ targetDir,
237
+ agentDir,
238
+ commandsDir,
239
+ commandName: cmd,
240
+ extension,
241
+ content: finalContent
242
+ });
211
243
  }
212
244
  } catch (e) {
213
245
  console.warn(`Failed to process ${cmd}:`, e);
@@ -221,64 +253,9 @@ function createGenerator(config) {
221
253
  return new ConfigurableGenerator(config);
222
254
  }
223
255
 
224
- // src/generators/config.ts
225
- var AGENT_CONFIGS = {
226
- opencode: {
227
- agentType: "opencode",
228
- agentDir: ".opencode",
229
- commandsDir: "commands",
230
- displayName: "OpenCode"
231
- },
232
- "claude-code": {
233
- agentType: "claude-code",
234
- agentDir: ".claude",
235
- commandsDir: "commands",
236
- displayName: "Claude Code"
237
- },
238
- antigravity: {
239
- agentType: "antigravity",
240
- agentDir: ".agent",
241
- commandsDir: "workflows",
242
- displayName: "Antigravity"
243
- },
244
- cursor: {
245
- agentType: "cursor",
246
- agentDir: ".cursor",
247
- commandsDir: "commands",
248
- displayName: "Cursor"
249
- },
250
- "vscode-copilot": {
251
- agentType: "vscode-copilot",
252
- agentDir: ".github",
253
- commandsDir: "prompts",
254
- displayName: "VS Code Copilot",
255
- extension: ".prompt.md",
256
- fixedAgent: "agent"
257
- },
258
- codex: {
259
- agentType: "codex",
260
- agentDir: ".codex",
261
- commandsDir: "prompts",
262
- displayName: "Codex",
263
- extension: ".md"
264
- },
265
- windsurf: {
266
- agentType: "windsurf",
267
- agentDir: ".windsurf",
268
- commandsDir: "workflows",
269
- displayName: "Windsurf"
270
- },
271
- cline: {
272
- agentType: "cline",
273
- agentDir: ".clinerules",
274
- commandsDir: "workflows",
275
- displayName: "Cline"
276
- }
277
- };
278
-
279
- // src/generators/OpenCodeGenerator.ts
256
+ // src/generators/opencode/generator.ts
280
257
  var OpenCodeGenerator = class {
281
- generator = createGenerator(AGENT_CONFIGS.opencode);
258
+ generator = createGenerator(opencodeConfig);
282
259
  validate(targetDir) {
283
260
  return this.generator.validate(targetDir);
284
261
  }
@@ -287,9 +264,17 @@ var OpenCodeGenerator = class {
287
264
  }
288
265
  };
289
266
 
290
- // src/generators/ClaudeCodeGenerator.ts
267
+ // src/generators/claude-code/config.ts
268
+ var claudeCodeConfig = {
269
+ agentType: "claude-code",
270
+ agentDir: ".claude",
271
+ commandsDir: "commands",
272
+ displayName: "Claude Code"
273
+ };
274
+
275
+ // src/generators/claude-code/generator.ts
291
276
  var ClaudeCodeGenerator = class {
292
- generator = createGenerator(AGENT_CONFIGS["claude-code"]);
277
+ generator = createGenerator(claudeCodeConfig);
293
278
  validate(targetDir) {
294
279
  return this.generator.validate(targetDir);
295
280
  }
@@ -298,9 +283,17 @@ var ClaudeCodeGenerator = class {
298
283
  }
299
284
  };
300
285
 
301
- // src/generators/AntigravityGenerator.ts
286
+ // src/generators/antigravity/config.ts
287
+ var antigravityConfig = {
288
+ agentType: "antigravity",
289
+ agentDir: ".agent",
290
+ commandsDir: "workflows",
291
+ displayName: "Antigravity"
292
+ };
293
+
294
+ // src/generators/antigravity/generator.ts
302
295
  var AntigravityGenerator = class {
303
- generator = createGenerator(AGENT_CONFIGS.antigravity);
296
+ generator = createGenerator(antigravityConfig);
304
297
  validate(targetDir) {
305
298
  return this.generator.validate(targetDir);
306
299
  }
@@ -309,9 +302,17 @@ var AntigravityGenerator = class {
309
302
  }
310
303
  };
311
304
 
312
- // src/generators/CursorGenerator.ts
305
+ // src/generators/cursor/config.ts
306
+ var cursorConfig = {
307
+ agentType: "cursor",
308
+ agentDir: ".cursor",
309
+ commandsDir: "commands",
310
+ displayName: "Cursor"
311
+ };
312
+
313
+ // src/generators/cursor/generator.ts
313
314
  var CursorGenerator = class {
314
- generator = createGenerator(AGENT_CONFIGS.cursor);
315
+ generator = createGenerator(cursorConfig);
315
316
  validate(targetDir) {
316
317
  return this.generator.validate(targetDir);
317
318
  }
@@ -320,9 +321,43 @@ var CursorGenerator = class {
320
321
  }
321
322
  };
322
323
 
323
- // src/generators/VSCodeCopilotGenerator.ts
324
+ // src/generators/vscode-copilot/strategy.ts
325
+ var import_smol_toml2 = require("smol-toml");
326
+ var VsCodeCopilotContentStrategy = class {
327
+ process(templateContent, options) {
328
+ const { installPath, agentType, fixedAgent } = options;
329
+ const parsed = (0, import_smol_toml2.parse)(templateContent);
330
+ if (!parsed.prompt) {
331
+ return null;
332
+ }
333
+ let prompt = parsed.prompt;
334
+ prompt = prompt.replace(/__\$\$CODE_AGENT_INSTALL_PATH\$\$__/g, installPath);
335
+ const finalContent = substituteVariables(prompt, { agent_type: agentType });
336
+ return `---
337
+ description: ${parsed.description || ""}
338
+ agent: ${fixedAgent}
339
+ ---
340
+ ${finalContent}`;
341
+ }
342
+ };
343
+ var vscodeCopilotContentStrategy = new VsCodeCopilotContentStrategy();
344
+
345
+ // src/generators/vscode-copilot/config.ts
346
+ var vscodeCopilotConfig = {
347
+ agentType: "vscode-copilot",
348
+ agentDir: ".github",
349
+ commandsDir: "prompts",
350
+ displayName: "VS Code Copilot",
351
+ extension: ".prompt.md",
352
+ fixedAgent: "agent",
353
+ strategy: {
354
+ content: vscodeCopilotContentStrategy
355
+ }
356
+ };
357
+
358
+ // src/generators/vscode-copilot/generator.ts
324
359
  var VSCodeCopilotGenerator = class {
325
- generator = createGenerator(AGENT_CONFIGS["vscode-copilot"]);
360
+ generator = createGenerator(vscodeCopilotConfig);
326
361
  validate(targetDir) {
327
362
  return this.generator.validate(targetDir);
328
363
  }
@@ -331,10 +366,19 @@ var VSCodeCopilotGenerator = class {
331
366
  }
332
367
  };
333
368
 
334
- // src/generators/CodexGenerator.ts
369
+ // src/generators/codex/config.ts
370
+ var codexConfig = {
371
+ agentType: "codex",
372
+ agentDir: ".codex",
373
+ commandsDir: "prompts",
374
+ displayName: "Codex",
375
+ extension: ".md"
376
+ };
377
+
378
+ // src/generators/codex/generator.ts
335
379
  var import_os = require("os");
336
380
  var CodexGenerator = class {
337
- generator = createGenerator(AGENT_CONFIGS.codex);
381
+ generator = createGenerator(codexConfig);
338
382
  validate(targetDir, scope) {
339
383
  if (scope === "global") {
340
384
  targetDir = (0, import_os.homedir)();
@@ -349,9 +393,17 @@ var CodexGenerator = class {
349
393
  }
350
394
  };
351
395
 
352
- // src/generators/WindsurfGenerator.ts
396
+ // src/generators/windsurf/config.ts
397
+ var windsurfConfig = {
398
+ agentType: "windsurf",
399
+ agentDir: ".windsurf",
400
+ commandsDir: "workflows",
401
+ displayName: "Windsurf"
402
+ };
403
+
404
+ // src/generators/windsurf/generator.ts
353
405
  var WindsurfGenerator = class {
354
- generator = createGenerator(AGENT_CONFIGS.windsurf);
406
+ generator = createGenerator(windsurfConfig);
355
407
  validate(targetDir) {
356
408
  return this.generator.validate(targetDir);
357
409
  }
@@ -360,9 +412,38 @@ var WindsurfGenerator = class {
360
412
  }
361
413
  };
362
414
 
363
- // src/generators/ClineGenerator.ts
415
+ // src/generators/cline/strategy.ts
416
+ var import_smol_toml3 = require("smol-toml");
417
+ var ClineContentStrategy = class {
418
+ process(templateContent, options) {
419
+ const { installPath, agentType, commandName } = options;
420
+ const parsed = (0, import_smol_toml3.parse)(templateContent);
421
+ if (!parsed.prompt) {
422
+ return null;
423
+ }
424
+ let prompt = parsed.prompt;
425
+ prompt = prompt.replace(/__\$\$CODE_AGENT_INSTALL_PATH\$\$__/g, installPath);
426
+ const finalContent = substituteVariables(prompt, { agent_type: agentType });
427
+ const title = commandName ? commandName.charAt(0).toUpperCase() + commandName.slice(1) : "Command";
428
+ return `# Conductor ${title}${parsed.description ? "\n\n" + parsed.description + "\n\n" : "\n\n"}${finalContent}`;
429
+ }
430
+ };
431
+ var clineContentStrategy = new ClineContentStrategy();
432
+
433
+ // src/generators/cline/config.ts
434
+ var clineConfig = {
435
+ agentType: "cline",
436
+ agentDir: ".clinerules",
437
+ commandsDir: "workflows",
438
+ displayName: "Cline",
439
+ strategy: {
440
+ content: clineContentStrategy
441
+ }
442
+ };
443
+
444
+ // src/generators/cline/generator.ts
364
445
  var ClineGenerator = class {
365
- generator = createGenerator(AGENT_CONFIGS.cline);
446
+ generator = createGenerator(clineConfig);
366
447
  validate(targetDir) {
367
448
  return this.generator.validate(targetDir);
368
449
  }
@@ -371,6 +452,62 @@ var ClineGenerator = class {
371
452
  }
372
453
  };
373
454
 
455
+ // src/generators/gemini/strategy.ts
456
+ var import_path4 = require("path");
457
+ var import_fs_extra3 = __toESM(require("fs-extra"), 1);
458
+ var import_smol_toml4 = require("smol-toml");
459
+ var { writeFile: writeFile3 } = import_fs_extra3.default;
460
+ var GeminiContentStrategy = class {
461
+ process(templateContent, options) {
462
+ const { installPath, agentType } = options;
463
+ const parsed = (0, import_smol_toml4.parse)(templateContent);
464
+ if (!parsed.prompt) {
465
+ return null;
466
+ }
467
+ const content = templateContent.replace(/__\$\$CODE_AGENT_INSTALL_PATH\$\$__/g, installPath);
468
+ return substituteVariables(content, { agent_type: agentType });
469
+ }
470
+ };
471
+ var GeminiFileStrategy = class {
472
+ async write(options) {
473
+ const { targetDir, agentDir, commandsDir, commandName, extension, content } = options;
474
+ const fileName = `${commandName}${extension}`;
475
+ await writeFile3((0, import_path4.join)(targetDir, agentDir, commandsDir, fileName), content);
476
+ }
477
+ };
478
+ var geminiContentStrategy = new GeminiContentStrategy();
479
+ var geminiFileStrategy = new GeminiFileStrategy();
480
+
481
+ // src/generators/gemini/config.ts
482
+ var geminiConfig = {
483
+ agentType: "gemini",
484
+ agentDir: ".gemini",
485
+ commandsDir: "commands/conductor",
486
+ displayName: "Gemini CLI",
487
+ extension: ".toml",
488
+ strategy: {
489
+ content: geminiContentStrategy,
490
+ file: geminiFileStrategy
491
+ }
492
+ };
493
+
494
+ // src/generators/gemini/generator.ts
495
+ var GeminiGenerator = class {
496
+ generator = createGenerator(geminiConfig);
497
+ async validate(targetDir, scope) {
498
+ if (scope === "global") {
499
+ throw new Error("Gemini CLI agent only supports project-level installation");
500
+ }
501
+ return this.generator.validate(targetDir, scope);
502
+ }
503
+ async generate(targetDir, scope) {
504
+ if (scope === "global") {
505
+ throw new Error("Gemini CLI agent only supports project-level installation");
506
+ }
507
+ return this.generator.generate(targetDir, scope);
508
+ }
509
+ };
510
+
374
511
  // src/generators/index.ts
375
512
  function getGenerator(agentType) {
376
513
  switch (agentType) {
@@ -388,6 +525,8 @@ function getGenerator(agentType) {
388
525
  return new WindsurfGenerator();
389
526
  case "cline":
390
527
  return new ClineGenerator();
528
+ case "gemini":
529
+ return new GeminiGenerator();
391
530
  case "opencode":
392
531
  default:
393
532
  return new OpenCodeGenerator();
@@ -395,9 +534,9 @@ function getGenerator(agentType) {
395
534
  }
396
535
 
397
536
  // src/commands/install.ts
398
- var import_path3 = require("path");
537
+ var import_path5 = require("path");
399
538
  async function installHandler(argv) {
400
- const targetDir = (0, import_path3.resolve)(process.cwd(), argv.path);
539
+ const targetDir = (0, import_path5.resolve)(process.cwd(), argv.path);
401
540
  try {
402
541
  console.log(`Initializing Conductor in: ${targetDir}`);
403
542
  let agent;
package/dist/index.js CHANGED
@@ -60,6 +60,11 @@ async function promptForAgent() {
60
60
  name: "Cline",
61
61
  value: "cline",
62
62
  description: "Cline AI coding assistant"
63
+ },
64
+ {
65
+ name: "Gemini CLI",
66
+ value: "gemini",
67
+ description: "Google Gemini CLI agent"
63
68
  }
64
69
  ],
65
70
  default: "opencode"
@@ -67,7 +72,7 @@ async function promptForAgent() {
67
72
  return answer;
68
73
  }
69
74
 
70
- // src/generators/ConfigurableGenerator.ts
75
+ // src/generators/default/strategy.ts
71
76
  import { join as join2 } from "path";
72
77
  import fs from "fs-extra";
73
78
  import { parse } from "smol-toml";
@@ -108,35 +113,49 @@ async function loadTemplate(templatePath) {
108
113
  return readFile(fullPath, "utf-8");
109
114
  }
110
115
 
111
- // src/generators/ConfigurableGenerator.ts
112
- var { existsSync, ensureDir, writeFile, copy } = fs;
113
- function processTemplateContent(tomlContent, installPath, agentType, fixedAgent, commandName) {
114
- const parsed = parse(tomlContent);
115
- if (!parsed.prompt) {
116
- return null;
117
- }
118
- let prompt = parsed.prompt;
119
- prompt = prompt.replace(/__\$\$CODE_AGENT_INSTALL_PATH\$\$__/g, installPath);
120
- const finalContent = substituteVariables(prompt, { agent_type: agentType });
121
- if (agentType === "cline") {
122
- const title = commandName ? commandName.charAt(0).toUpperCase() + commandName.slice(1) : "Command";
123
- return `# Conductor ${title}${parsed.description ? "\n\n" + parsed.description + "\n\n" : "\n\n"}${finalContent}`;
124
- }
125
- if (fixedAgent) {
126
- return `---
127
- description: ${parsed.description || ""}
128
- agent: ${fixedAgent}
129
- ---
130
- ${finalContent}`;
131
- }
132
- if (parsed.description) {
133
- return `---
116
+ // src/generators/default/strategy.ts
117
+ var { writeFile } = fs;
118
+ var DefaultContentStrategy = class {
119
+ process(templateContent, options) {
120
+ const { installPath, agentType } = options;
121
+ const parsed = parse(templateContent);
122
+ if (!parsed.prompt) {
123
+ return null;
124
+ }
125
+ let prompt = parsed.prompt;
126
+ prompt = prompt.replace(/__\$\$CODE_AGENT_INSTALL_PATH\$\$__/g, installPath);
127
+ const finalContent = substituteVariables(prompt, { agent_type: agentType });
128
+ if (parsed.description) {
129
+ return `---
134
130
  description: ${parsed.description}
135
131
  ---
136
132
  ${finalContent}`;
133
+ }
134
+ return finalContent;
137
135
  }
138
- return finalContent;
139
- }
136
+ };
137
+ var DefaultFileStrategy = class {
138
+ async write(options) {
139
+ const { targetDir, agentDir, commandsDir, commandName, extension, content } = options;
140
+ const fileName = `conductor:${commandName}${extension}`;
141
+ await writeFile(join2(targetDir, agentDir, commandsDir, fileName), content);
142
+ }
143
+ };
144
+ var defaultContentStrategy = new DefaultContentStrategy();
145
+ var defaultFileStrategy = new DefaultFileStrategy();
146
+
147
+ // src/generators/opencode/config.ts
148
+ var opencodeConfig = {
149
+ agentType: "opencode",
150
+ agentDir: ".opencode",
151
+ commandsDir: "commands",
152
+ displayName: "OpenCode"
153
+ };
154
+
155
+ // src/generators/ConfigurableGenerator.ts
156
+ import { join as join3 } from "path";
157
+ import fs2 from "fs-extra";
158
+ var { existsSync, ensureDir, writeFile: writeFile2, copy } = fs2;
140
159
  var ConfigurableGenerator = class {
141
160
  constructor(config) {
142
161
  this.config = config;
@@ -146,8 +165,8 @@ var ConfigurableGenerator = class {
146
165
  throw new Error(`Target directory does not exist: ${targetDir}`);
147
166
  }
148
167
  const { agentDir, commandsDir, displayName } = this.config;
149
- const setupFile = join2(targetDir, agentDir, commandsDir, "conductor:setup.md");
150
- const conductorPath = join2(targetDir, agentDir, "conductor");
168
+ const setupFile = join3(targetDir, agentDir, commandsDir, "conductor:setup.md");
169
+ const conductorPath = join3(targetDir, agentDir, "conductor");
151
170
  if (existsSync(conductorPath) && existsSync(setupFile)) {
152
171
  throw new Error(`Conductor (${displayName}) is already installed in: ${targetDir}`);
153
172
  }
@@ -155,18 +174,18 @@ var ConfigurableGenerator = class {
155
174
  }
156
175
  async generate(targetDir, scope) {
157
176
  const { agentDir, commandsDir, agentType } = this.config;
158
- const agentPath = join2(targetDir, agentDir);
159
- const targetCommandsDir = join2(agentPath, commandsDir);
160
- let installPath = join2(agentDir, "conductor");
177
+ const agentPath = join3(targetDir, agentDir);
178
+ const targetCommandsDir = join3(agentPath, commandsDir);
179
+ let installPath = join3(agentDir, "conductor");
161
180
  if (scope === "global") {
162
181
  installPath = `~/${agentDir}/conductor`;
163
182
  }
164
183
  await ensureDir(targetCommandsDir);
165
- await ensureDir(join2(agentPath, "conductor"));
184
+ await ensureDir(join3(agentPath, "conductor"));
166
185
  const templateRoot = await getTemplateRoot();
167
186
  try {
168
- const templateSource = join2(templateRoot, "templates");
169
- const templateDest = join2(agentPath, "conductor", "templates");
187
+ const templateSource = join3(templateRoot, "templates");
188
+ const templateDest = join3(agentPath, "conductor", "templates");
170
189
  await copy(templateSource, templateDest);
171
190
  } catch (e) {
172
191
  console.warn("Failed to copy templates directory:", e);
@@ -177,10 +196,23 @@ var ConfigurableGenerator = class {
177
196
  for (const cmd of commands) {
178
197
  try {
179
198
  const tomlContent = await loadTemplate(`commands/${cmd}.toml`);
180
- const finalContent = processTemplateContent(tomlContent, installPath, agentType, fixedAgent, cmd);
199
+ const contentStrategy = this.config.strategy?.content || defaultContentStrategy;
200
+ const finalContent = contentStrategy.process(tomlContent, {
201
+ installPath,
202
+ agentType,
203
+ fixedAgent,
204
+ commandName: cmd
205
+ });
181
206
  if (finalContent) {
182
- const fileName = `conductor:${cmd}${extension}`;
183
- await writeFile(join2(targetCommandsDir, fileName), finalContent);
207
+ const fileStrategy = this.config.strategy?.file || defaultFileStrategy;
208
+ await fileStrategy.write({
209
+ targetDir,
210
+ agentDir,
211
+ commandsDir,
212
+ commandName: cmd,
213
+ extension,
214
+ content: finalContent
215
+ });
184
216
  }
185
217
  } catch (e) {
186
218
  console.warn(`Failed to process ${cmd}:`, e);
@@ -194,64 +226,9 @@ function createGenerator(config) {
194
226
  return new ConfigurableGenerator(config);
195
227
  }
196
228
 
197
- // src/generators/config.ts
198
- var AGENT_CONFIGS = {
199
- opencode: {
200
- agentType: "opencode",
201
- agentDir: ".opencode",
202
- commandsDir: "commands",
203
- displayName: "OpenCode"
204
- },
205
- "claude-code": {
206
- agentType: "claude-code",
207
- agentDir: ".claude",
208
- commandsDir: "commands",
209
- displayName: "Claude Code"
210
- },
211
- antigravity: {
212
- agentType: "antigravity",
213
- agentDir: ".agent",
214
- commandsDir: "workflows",
215
- displayName: "Antigravity"
216
- },
217
- cursor: {
218
- agentType: "cursor",
219
- agentDir: ".cursor",
220
- commandsDir: "commands",
221
- displayName: "Cursor"
222
- },
223
- "vscode-copilot": {
224
- agentType: "vscode-copilot",
225
- agentDir: ".github",
226
- commandsDir: "prompts",
227
- displayName: "VS Code Copilot",
228
- extension: ".prompt.md",
229
- fixedAgent: "agent"
230
- },
231
- codex: {
232
- agentType: "codex",
233
- agentDir: ".codex",
234
- commandsDir: "prompts",
235
- displayName: "Codex",
236
- extension: ".md"
237
- },
238
- windsurf: {
239
- agentType: "windsurf",
240
- agentDir: ".windsurf",
241
- commandsDir: "workflows",
242
- displayName: "Windsurf"
243
- },
244
- cline: {
245
- agentType: "cline",
246
- agentDir: ".clinerules",
247
- commandsDir: "workflows",
248
- displayName: "Cline"
249
- }
250
- };
251
-
252
- // src/generators/OpenCodeGenerator.ts
229
+ // src/generators/opencode/generator.ts
253
230
  var OpenCodeGenerator = class {
254
- generator = createGenerator(AGENT_CONFIGS.opencode);
231
+ generator = createGenerator(opencodeConfig);
255
232
  validate(targetDir) {
256
233
  return this.generator.validate(targetDir);
257
234
  }
@@ -260,9 +237,17 @@ var OpenCodeGenerator = class {
260
237
  }
261
238
  };
262
239
 
263
- // src/generators/ClaudeCodeGenerator.ts
240
+ // src/generators/claude-code/config.ts
241
+ var claudeCodeConfig = {
242
+ agentType: "claude-code",
243
+ agentDir: ".claude",
244
+ commandsDir: "commands",
245
+ displayName: "Claude Code"
246
+ };
247
+
248
+ // src/generators/claude-code/generator.ts
264
249
  var ClaudeCodeGenerator = class {
265
- generator = createGenerator(AGENT_CONFIGS["claude-code"]);
250
+ generator = createGenerator(claudeCodeConfig);
266
251
  validate(targetDir) {
267
252
  return this.generator.validate(targetDir);
268
253
  }
@@ -271,9 +256,17 @@ var ClaudeCodeGenerator = class {
271
256
  }
272
257
  };
273
258
 
274
- // src/generators/AntigravityGenerator.ts
259
+ // src/generators/antigravity/config.ts
260
+ var antigravityConfig = {
261
+ agentType: "antigravity",
262
+ agentDir: ".agent",
263
+ commandsDir: "workflows",
264
+ displayName: "Antigravity"
265
+ };
266
+
267
+ // src/generators/antigravity/generator.ts
275
268
  var AntigravityGenerator = class {
276
- generator = createGenerator(AGENT_CONFIGS.antigravity);
269
+ generator = createGenerator(antigravityConfig);
277
270
  validate(targetDir) {
278
271
  return this.generator.validate(targetDir);
279
272
  }
@@ -282,9 +275,17 @@ var AntigravityGenerator = class {
282
275
  }
283
276
  };
284
277
 
285
- // src/generators/CursorGenerator.ts
278
+ // src/generators/cursor/config.ts
279
+ var cursorConfig = {
280
+ agentType: "cursor",
281
+ agentDir: ".cursor",
282
+ commandsDir: "commands",
283
+ displayName: "Cursor"
284
+ };
285
+
286
+ // src/generators/cursor/generator.ts
286
287
  var CursorGenerator = class {
287
- generator = createGenerator(AGENT_CONFIGS.cursor);
288
+ generator = createGenerator(cursorConfig);
288
289
  validate(targetDir) {
289
290
  return this.generator.validate(targetDir);
290
291
  }
@@ -293,9 +294,43 @@ var CursorGenerator = class {
293
294
  }
294
295
  };
295
296
 
296
- // src/generators/VSCodeCopilotGenerator.ts
297
+ // src/generators/vscode-copilot/strategy.ts
298
+ import { parse as parse2 } from "smol-toml";
299
+ var VsCodeCopilotContentStrategy = class {
300
+ process(templateContent, options) {
301
+ const { installPath, agentType, fixedAgent } = options;
302
+ const parsed = parse2(templateContent);
303
+ if (!parsed.prompt) {
304
+ return null;
305
+ }
306
+ let prompt = parsed.prompt;
307
+ prompt = prompt.replace(/__\$\$CODE_AGENT_INSTALL_PATH\$\$__/g, installPath);
308
+ const finalContent = substituteVariables(prompt, { agent_type: agentType });
309
+ return `---
310
+ description: ${parsed.description || ""}
311
+ agent: ${fixedAgent}
312
+ ---
313
+ ${finalContent}`;
314
+ }
315
+ };
316
+ var vscodeCopilotContentStrategy = new VsCodeCopilotContentStrategy();
317
+
318
+ // src/generators/vscode-copilot/config.ts
319
+ var vscodeCopilotConfig = {
320
+ agentType: "vscode-copilot",
321
+ agentDir: ".github",
322
+ commandsDir: "prompts",
323
+ displayName: "VS Code Copilot",
324
+ extension: ".prompt.md",
325
+ fixedAgent: "agent",
326
+ strategy: {
327
+ content: vscodeCopilotContentStrategy
328
+ }
329
+ };
330
+
331
+ // src/generators/vscode-copilot/generator.ts
297
332
  var VSCodeCopilotGenerator = class {
298
- generator = createGenerator(AGENT_CONFIGS["vscode-copilot"]);
333
+ generator = createGenerator(vscodeCopilotConfig);
299
334
  validate(targetDir) {
300
335
  return this.generator.validate(targetDir);
301
336
  }
@@ -304,10 +339,19 @@ var VSCodeCopilotGenerator = class {
304
339
  }
305
340
  };
306
341
 
307
- // src/generators/CodexGenerator.ts
342
+ // src/generators/codex/config.ts
343
+ var codexConfig = {
344
+ agentType: "codex",
345
+ agentDir: ".codex",
346
+ commandsDir: "prompts",
347
+ displayName: "Codex",
348
+ extension: ".md"
349
+ };
350
+
351
+ // src/generators/codex/generator.ts
308
352
  import { homedir } from "os";
309
353
  var CodexGenerator = class {
310
- generator = createGenerator(AGENT_CONFIGS.codex);
354
+ generator = createGenerator(codexConfig);
311
355
  validate(targetDir, scope) {
312
356
  if (scope === "global") {
313
357
  targetDir = homedir();
@@ -322,9 +366,17 @@ var CodexGenerator = class {
322
366
  }
323
367
  };
324
368
 
325
- // src/generators/WindsurfGenerator.ts
369
+ // src/generators/windsurf/config.ts
370
+ var windsurfConfig = {
371
+ agentType: "windsurf",
372
+ agentDir: ".windsurf",
373
+ commandsDir: "workflows",
374
+ displayName: "Windsurf"
375
+ };
376
+
377
+ // src/generators/windsurf/generator.ts
326
378
  var WindsurfGenerator = class {
327
- generator = createGenerator(AGENT_CONFIGS.windsurf);
379
+ generator = createGenerator(windsurfConfig);
328
380
  validate(targetDir) {
329
381
  return this.generator.validate(targetDir);
330
382
  }
@@ -333,9 +385,38 @@ var WindsurfGenerator = class {
333
385
  }
334
386
  };
335
387
 
336
- // src/generators/ClineGenerator.ts
388
+ // src/generators/cline/strategy.ts
389
+ import { parse as parse3 } from "smol-toml";
390
+ var ClineContentStrategy = class {
391
+ process(templateContent, options) {
392
+ const { installPath, agentType, commandName } = options;
393
+ const parsed = parse3(templateContent);
394
+ if (!parsed.prompt) {
395
+ return null;
396
+ }
397
+ let prompt = parsed.prompt;
398
+ prompt = prompt.replace(/__\$\$CODE_AGENT_INSTALL_PATH\$\$__/g, installPath);
399
+ const finalContent = substituteVariables(prompt, { agent_type: agentType });
400
+ const title = commandName ? commandName.charAt(0).toUpperCase() + commandName.slice(1) : "Command";
401
+ return `# Conductor ${title}${parsed.description ? "\n\n" + parsed.description + "\n\n" : "\n\n"}${finalContent}`;
402
+ }
403
+ };
404
+ var clineContentStrategy = new ClineContentStrategy();
405
+
406
+ // src/generators/cline/config.ts
407
+ var clineConfig = {
408
+ agentType: "cline",
409
+ agentDir: ".clinerules",
410
+ commandsDir: "workflows",
411
+ displayName: "Cline",
412
+ strategy: {
413
+ content: clineContentStrategy
414
+ }
415
+ };
416
+
417
+ // src/generators/cline/generator.ts
337
418
  var ClineGenerator = class {
338
- generator = createGenerator(AGENT_CONFIGS.cline);
419
+ generator = createGenerator(clineConfig);
339
420
  validate(targetDir) {
340
421
  return this.generator.validate(targetDir);
341
422
  }
@@ -344,6 +425,62 @@ var ClineGenerator = class {
344
425
  }
345
426
  };
346
427
 
428
+ // src/generators/gemini/strategy.ts
429
+ import { join as join4 } from "path";
430
+ import fs3 from "fs-extra";
431
+ import { parse as parse4 } from "smol-toml";
432
+ var { writeFile: writeFile3 } = fs3;
433
+ var GeminiContentStrategy = class {
434
+ process(templateContent, options) {
435
+ const { installPath, agentType } = options;
436
+ const parsed = parse4(templateContent);
437
+ if (!parsed.prompt) {
438
+ return null;
439
+ }
440
+ const content = templateContent.replace(/__\$\$CODE_AGENT_INSTALL_PATH\$\$__/g, installPath);
441
+ return substituteVariables(content, { agent_type: agentType });
442
+ }
443
+ };
444
+ var GeminiFileStrategy = class {
445
+ async write(options) {
446
+ const { targetDir, agentDir, commandsDir, commandName, extension, content } = options;
447
+ const fileName = `${commandName}${extension}`;
448
+ await writeFile3(join4(targetDir, agentDir, commandsDir, fileName), content);
449
+ }
450
+ };
451
+ var geminiContentStrategy = new GeminiContentStrategy();
452
+ var geminiFileStrategy = new GeminiFileStrategy();
453
+
454
+ // src/generators/gemini/config.ts
455
+ var geminiConfig = {
456
+ agentType: "gemini",
457
+ agentDir: ".gemini",
458
+ commandsDir: "commands/conductor",
459
+ displayName: "Gemini CLI",
460
+ extension: ".toml",
461
+ strategy: {
462
+ content: geminiContentStrategy,
463
+ file: geminiFileStrategy
464
+ }
465
+ };
466
+
467
+ // src/generators/gemini/generator.ts
468
+ var GeminiGenerator = class {
469
+ generator = createGenerator(geminiConfig);
470
+ async validate(targetDir, scope) {
471
+ if (scope === "global") {
472
+ throw new Error("Gemini CLI agent only supports project-level installation");
473
+ }
474
+ return this.generator.validate(targetDir, scope);
475
+ }
476
+ async generate(targetDir, scope) {
477
+ if (scope === "global") {
478
+ throw new Error("Gemini CLI agent only supports project-level installation");
479
+ }
480
+ return this.generator.generate(targetDir, scope);
481
+ }
482
+ };
483
+
347
484
  // src/generators/index.ts
348
485
  function getGenerator(agentType) {
349
486
  switch (agentType) {
@@ -361,6 +498,8 @@ function getGenerator(agentType) {
361
498
  return new WindsurfGenerator();
362
499
  case "cline":
363
500
  return new ClineGenerator();
501
+ case "gemini":
502
+ return new GeminiGenerator();
364
503
  case "opencode":
365
504
  default:
366
505
  return new OpenCodeGenerator();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conductor-4-all",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "description": "Conductor spec-driven development CLI - TypeScript/Node.js version",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {