agents.dev 1.0.3 → 1.0.5

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
@@ -35,7 +35,14 @@ agents-install
35
35
  ```
36
36
 
37
37
  ### First Run
38
- Running the tool will start the **Wizard**:
38
+ Run the **init** command to start the configuration Wizard:
39
+ ```bash
40
+ agents.dev init
41
+ # OR with npx
42
+ npx agents.dev init
43
+ ```
44
+
45
+ The Wizard will guide you through:
39
46
  1. **Select OS**: Windows or Unix.
40
47
  2. **Select Targets**: Choose formats to build (Gemini, Roo, etc.).
41
48
  3. **Docs Auto-Gen**: It automatically creates `docs/` and a workflow guide.
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getAvailableAgents = getAvailableAgents;
6
7
  exports.generateAgents = generateAgents;
7
8
  const fs_extra_1 = __importDefault(require("fs-extra"));
8
9
  const path_1 = __importDefault(require("path"));
@@ -14,14 +15,67 @@ const roo_1 = require("../transformers/roo");
14
15
  const kilo_1 = require("../transformers/kilo");
15
16
  const opencode_1 = require("../transformers/opencode");
16
17
  const markdown_1 = require("../parsers/markdown");
17
- async function generateAgents(definitionsDir, outDir, selectedTargets) {
18
+ async function getAvailableAgents(definitionsDir) {
19
+ if (!(await fs_extra_1.default.pathExists(definitionsDir))) {
20
+ return [];
21
+ }
22
+ const agents = [];
23
+ let files = [];
24
+ let baseDir = definitionsDir;
25
+ const stats = await fs_extra_1.default.stat(definitionsDir);
26
+ if (stats.isFile()) {
27
+ baseDir = path_1.default.dirname(definitionsDir);
28
+ files = [path_1.default.basename(definitionsDir)];
29
+ }
30
+ else {
31
+ files = await fs_extra_1.default.readdir(definitionsDir);
32
+ }
33
+ for (const file of files) {
34
+ const filePath = path_1.default.join(baseDir, file);
35
+ if (file.endsWith('.yaml') || file.endsWith('.yml')) {
36
+ try {
37
+ const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
38
+ const rawAgent = yaml_1.default.parse(content);
39
+ const parseResult = types_1.AgentSchema.safeParse(rawAgent);
40
+ if (parseResult.success) {
41
+ const slug = file.replace(/\.(yaml|yml)$/, '');
42
+ agents.push({
43
+ name: parseResult.data.name,
44
+ slug: slug,
45
+ description: parseResult.data.description
46
+ });
47
+ }
48
+ }
49
+ catch (e) { }
50
+ }
51
+ else if (file.endsWith('.md')) {
52
+ try {
53
+ const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
54
+ const parsedAgents = (0, markdown_1.parseMarkdownAgents)(content);
55
+ for (const agent of parsedAgents) {
56
+ const parseResult = types_1.AgentSchema.safeParse(agent);
57
+ if (parseResult.success) {
58
+ agents.push({
59
+ name: parseResult.data.name,
60
+ slug: toSlug(parseResult.data.name),
61
+ description: parseResult.data.description
62
+ });
63
+ }
64
+ }
65
+ }
66
+ catch (e) { }
67
+ }
68
+ }
69
+ return agents.sort((a, b) => a.name.localeCompare(b.name));
70
+ }
71
+ async function generateAgents(definitionsDir, outDir, selectedTargets, agentWhitelist) {
18
72
  console.log(chalk_1.default.blue(`\nšŸ“¦ Building agents from ${definitionsDir}...`));
19
73
  try {
20
74
  if (outDir !== process.cwd()) {
21
75
  await fs_extra_1.default.ensureDir(outDir);
22
76
  }
23
77
  // Check if input exists
24
- if (!await fs_extra_1.default.pathExists(definitionsDir)) {
78
+ if (!(await fs_extra_1.default.pathExists(definitionsDir))) {
25
79
  console.error(chalk_1.default.red(`Input not found: ${definitionsDir}`));
26
80
  return;
27
81
  }
@@ -49,6 +103,9 @@ async function generateAgents(definitionsDir, outDir, selectedTargets) {
49
103
  }
50
104
  // Use filename as slug for YAML (backward compatibility)
51
105
  const slug = file.replace(/\.(yaml|yml)$/, '');
106
+ if (agentWhitelist && !agentWhitelist.includes(slug)) {
107
+ continue;
108
+ }
52
109
  await buildAgentArtifacts(parseResult.data, slug, outDir, selectedTargets);
53
110
  }
54
111
  catch (e) {
@@ -71,6 +128,9 @@ async function generateAgents(definitionsDir, outDir, selectedTargets) {
71
128
  }
72
129
  // Use agent name as slug for Markdown
73
130
  const slug = toSlug(agent.name);
131
+ if (agentWhitelist && !agentWhitelist.includes(slug)) {
132
+ continue;
133
+ }
74
134
  await buildAgentArtifacts(agent, slug, outDir, selectedTargets);
75
135
  }
76
136
  }
@@ -113,7 +173,7 @@ async function buildAgentArtifacts(agent, slug, outDir, selectedTargets) {
113
173
  name: `${slug}.md`
114
174
  }
115
175
  ];
116
- const targetsToBuild = allTargets.filter(t => selectedTargets.includes(t.id));
176
+ const targetsToBuild = allTargets.filter((t) => selectedTargets.includes(t.id));
117
177
  for (const target of targetsToBuild) {
118
178
  const targetDir = path_1.default.join(outDir, target.subDir);
119
179
  await fs_extra_1.default.ensureDir(targetDir);
@@ -128,7 +188,8 @@ function logValidationErrors(source, error) {
128
188
  });
129
189
  }
130
190
  function toSlug(name) {
131
- return name.toLowerCase()
191
+ return name
192
+ .toLowerCase()
132
193
  .replace(/[^\w\s-]/g, '') // remove non-word chars
133
194
  .replace(/[\s_-]+/g, '-') // collapse whitespace/underscores to hyphens
134
195
  .replace(/^-+|-+$/g, ''); // trim hyphens
package/dist/index.js CHANGED
@@ -15,75 +15,146 @@ const program = new commander_1.Command();
15
15
  program
16
16
  .name('agents')
17
17
  .description('Agent Installer CLI')
18
- .version('1.0.0')
18
+ .version('1.0.4');
19
+ program.command('init')
20
+ .description('Initialize agents configuration interactively')
19
21
  .option('-o, --out <dir>', 'Output directory', '.')
20
22
  .option('-i, --input <path>', 'Input file or directory (default: definitions/ or agents.md)')
21
23
  .option('-t, --target <targets>', 'Comma-separated target formats (gemini, roo, kilo, opencode)')
22
24
  .action(async (options) => {
23
- console.log(chalk_1.default.bold.blue('\nšŸš€ Agents.dev Installer Wizard\n'));
24
- // --- STEP 1: INITIALIZATION (Docs & Shell) ---
25
- const docsDir = path_1.default.join(process.cwd(), 'docs');
26
- // Check if docs directory exists
27
- if (!await fs_extra_1.default.pathExists(docsDir)) {
28
- console.log(chalk_1.default.yellow('ā„¹ļø Project documentation structure not found.'));
29
- const initAnswers = await inquirer_1.default.prompt([
30
- {
31
- type: 'list',
32
- name: 'shell',
33
- message: 'Initialize validation: Which shell do you use?',
34
- choices: [
35
- { name: 'Windows (CMD/PowerShell)', value: 'win32' },
36
- { name: 'Unix-like (Bash/Zsh/Ubuntu)', value: 'unix' }
37
- ]
38
- }
39
- ]);
40
- await (0, docs_1.generateWorkflowGuide)(docsDir, initAnswers.shell);
41
- }
42
- else {
43
- console.log(chalk_1.default.gray('āœ… "docs/" directory already exists.\n'));
25
+ // Safety check for non-interactive environments (CI/CD)
26
+ if (!process.stdout.isTTY || process.env.CI === 'true' || process.env.CI === '1') {
27
+ console.log(chalk_1.default.yellow('Skipping interactive installer (non-interactive environment detected).'));
28
+ console.log(chalk_1.default.gray('Run "npx agents.dev" manually to configure your agents.'));
29
+ return;
44
30
  }
45
- // --- STEP 2: BUILD AGENTS ---
46
- let inputPath = options.input ? path_1.default.resolve(options.input) : path_1.default.join(process.cwd(), 'definitions');
47
- // If default definitions dir doesn't exist and no input specified, try agents.md
48
- if (!options.input && !await fs_extra_1.default.pathExists(inputPath)) {
49
- const localAgentsMd = path_1.default.join(process.cwd(), 'agents.md');
50
- if (await fs_extra_1.default.pathExists(localAgentsMd)) {
51
- inputPath = localAgentsMd;
52
- console.log(chalk_1.default.gray(`ā„¹ļø Using 'agents.md' found in root.`));
31
+ try {
32
+ console.log(chalk_1.default.bold.blue('\nšŸš€ Agents.dev Installer Wizard\n'));
33
+ // --- STEP 1: INITIALIZATION (Docs & Shell) ---
34
+ const docsDir = path_1.default.join(process.cwd(), 'docs');
35
+ // Check if docs directory exists
36
+ if (!(await fs_extra_1.default.pathExists(docsDir))) {
37
+ console.log(chalk_1.default.yellow('ā„¹ļø Project documentation structure not found.'));
38
+ const initAnswers = await inquirer_1.default.prompt([
39
+ {
40
+ type: 'list',
41
+ name: 'shell',
42
+ message: 'Initialize validation: Which shell do you use?',
43
+ choices: [
44
+ { name: 'Windows (CMD/PowerShell)', value: 'win32' },
45
+ { name: 'Unix-like (Bash/Zsh/Ubuntu)', value: 'unix' }
46
+ ]
47
+ }
48
+ ]);
49
+ await (0, docs_1.generateWorkflowGuide)(docsDir, initAnswers.shell);
53
50
  }
54
- }
55
- const outDir = path_1.default.resolve(options.out);
56
- // Determine targets
57
- let selectedTargets = [];
58
- if (options.target) {
59
- selectedTargets = options.target.split(',').map((t) => t.trim().toLowerCase());
60
- }
61
- else {
62
- const buildAnswers = await inquirer_1.default.prompt([
63
- {
64
- type: 'checkbox',
65
- name: 'targets',
66
- message: 'Select target formats to build:',
67
- choices: [
68
- { name: 'Gemini CLI', value: 'gemini', checked: true },
69
- { name: 'Roo Code', value: 'roo', checked: false },
70
- { name: 'Kilo Code', value: 'kilo', checked: false },
71
- { name: 'OpenCode', value: 'opencode', checked: false }
72
- ],
73
- validate: (answer) => {
74
- if (answer.length < 1) {
75
- return 'You must choose at least one target.';
51
+ else {
52
+ console.log(chalk_1.default.gray('āœ… "docs/" directory already exists.\n'));
53
+ }
54
+ // --- STEP 2: BUILD AGENTS ---
55
+ let inputPath = options.input ? path_1.default.resolve(options.input) : path_1.default.join(process.cwd(), 'definitions');
56
+ // If default definitions dir doesn't exist and no input specified, try agents.md
57
+ if (!options.input && !(await fs_extra_1.default.pathExists(inputPath))) {
58
+ const localAgentsMd = path_1.default.join(process.cwd(), 'agents.md');
59
+ if (await fs_extra_1.default.pathExists(localAgentsMd)) {
60
+ inputPath = localAgentsMd;
61
+ console.log(chalk_1.default.gray(`ā„¹ļø Using 'agents.md' found in root.`));
62
+ }
63
+ else {
64
+ // Fallback: Check if we are running from the installed package and definitions exist there
65
+ const packageDefinitions = path_1.default.join(__dirname, '../definitions');
66
+ if (await fs_extra_1.default.pathExists(packageDefinitions)) {
67
+ inputPath = packageDefinitions;
68
+ // console.log(chalk.gray(`ā„¹ļø Using default definitions from package.`));
69
+ }
70
+ }
71
+ }
72
+ const outDir = path_1.default.resolve(options.out);
73
+ // Determine targets
74
+ let selectedTargets = [];
75
+ if (options.target) {
76
+ selectedTargets = options.target.split(',').map((t) => t.trim().toLowerCase());
77
+ }
78
+ else {
79
+ const buildAnswers = await inquirer_1.default.prompt([
80
+ {
81
+ type: 'checkbox',
82
+ name: 'targets',
83
+ message: 'Select target formats to build:',
84
+ choices: [
85
+ { name: 'Gemini CLI', value: 'gemini', checked: true },
86
+ { name: 'Roo Code', value: 'roo', checked: false },
87
+ { name: 'Kilo Code', value: 'kilo', checked: false },
88
+ { name: 'OpenCode', value: 'opencode', checked: false }
89
+ ],
90
+ validate: (answer) => {
91
+ if (answer.length < 1) {
92
+ return 'You must choose at least one target.';
93
+ }
94
+ return true;
95
+ }
96
+ }
97
+ ]);
98
+ selectedTargets = buildAnswers.targets;
99
+ }
100
+ if (selectedTargets.length === 0) {
101
+ console.log(chalk_1.default.yellow('No targets selected. Exiting.'));
102
+ return;
103
+ }
104
+ // --- STEP 3: SELECT AGENTS ---
105
+ let selectedAgents = undefined;
106
+ const availableAgents = await (0, agents_1.getAvailableAgents)(inputPath);
107
+ if (availableAgents.length > 0) {
108
+ const agentSelection = await inquirer_1.default.prompt([
109
+ {
110
+ type: 'list',
111
+ name: 'mode',
112
+ message: 'How do you want to install agents?',
113
+ choices: [
114
+ { name: 'Install All Standard Agents (Recommended)', value: 'all' },
115
+ { name: 'Custom Selection', value: 'custom' }
116
+ ]
117
+ },
118
+ {
119
+ type: 'checkbox',
120
+ name: 'agents',
121
+ message: 'Select agents to install:',
122
+ choices: availableAgents.map((a) => ({
123
+ name: a.description ? `${a.name} - ${chalk_1.default.gray(a.description)}` : a.name,
124
+ value: a.slug,
125
+ checked: true
126
+ })),
127
+ when: (answers) => answers.mode === 'custom',
128
+ validate: (answer) => {
129
+ if (answer.length < 1) {
130
+ return 'You must choose at least one agent.';
131
+ }
132
+ return true;
76
133
  }
77
- return true;
78
134
  }
135
+ ]);
136
+ if (agentSelection.mode === 'custom') {
137
+ selectedAgents = agentSelection.agents;
79
138
  }
80
- ]);
81
- selectedTargets = buildAnswers.targets;
139
+ }
140
+ await (0, agents_1.generateAgents)(inputPath, outDir, selectedTargets, selectedAgents);
82
141
  }
83
- if (selectedTargets.length === 0) {
84
- console.log(chalk_1.default.yellow('No targets selected. Exiting.'));
85
- return;
142
+ catch (error) {
143
+ if (error.isTtyError) {
144
+ console.log(chalk_1.default.yellow('Interactive prompt not supported in this environment.'));
145
+ }
146
+ else if (error.message.includes('User force closed')) {
147
+ console.log(chalk_1.default.yellow('\nInstallation cancelled by user.'));
148
+ }
149
+ else {
150
+ console.error(chalk_1.default.red('\nAn error occurred during installation:'), error.message);
151
+ }
152
+ // Always exit with 0 to prevent npm install from failing loudly
153
+ process.exit(0);
86
154
  }
87
- await (0, agents_1.generateAgents)(inputPath, outDir, selectedTargets);
155
+ });
156
+ // Default command (show help if no command)
157
+ program.action(() => {
158
+ program.help();
88
159
  });
89
160
  program.parse(process.argv);
package/dist/types.js CHANGED
@@ -5,6 +5,7 @@ const zod_1 = require("zod");
5
5
  exports.AgentSchema = zod_1.z.object({
6
6
  name: zod_1.z.string().min(1, "Name is required"),
7
7
  role: zod_1.z.string().min(1, "Role is required"),
8
+ description: zod_1.z.string().optional(),
8
9
  emoji: zod_1.z.string().optional(),
9
10
  systemPrompt: zod_1.z.string().min(10, "System prompt must be at least 10 characters"),
10
11
  rules: zod_1.z.array(zod_1.z.string()).optional(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agents.dev",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "bin": {