@inkeep/create-agents 0.0.0-dev-20251014203435 → 0.0.0-dev-20251014211138

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.
@@ -49,7 +49,7 @@ describe('createAgents - Template and Project ID Logic', () => {
49
49
  vi.mocked(fs.remove).mockResolvedValue(undefined);
50
50
  // Mock templates
51
51
  vi.mocked(getAvailableTemplates).mockResolvedValue([
52
- 'weather-project',
52
+ 'event-planner',
53
53
  'chatbot',
54
54
  'data-analysis',
55
55
  ]);
@@ -72,7 +72,7 @@ describe('createAgents - Template and Project ID Logic', () => {
72
72
  processChdirSpy.mockRestore();
73
73
  });
74
74
  describe('Default behavior (no template or customProjectId)', () => {
75
- it('should use weather-project as default template and project ID', async () => {
75
+ it('should use event-planner as default template and project ID', async () => {
76
76
  await createAgents({
77
77
  dirName: 'test-dir',
78
78
  openAiKey: 'test-openai-key',
@@ -81,18 +81,18 @@ describe('createAgents - Template and Project ID Logic', () => {
81
81
  // Should clone base template and weather-project template
82
82
  expect(cloneTemplate).toHaveBeenCalledTimes(2);
83
83
  expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/create-agents-template', expect.any(String));
84
- expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/agents-cookbook/template-projects/weather-project', 'src/weather-project', expect.arrayContaining([
84
+ expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/agents-cookbook/template-projects/event-planner', 'src/projects/event-planner', expect.arrayContaining([
85
85
  expect.objectContaining({
86
86
  filePath: 'index.ts',
87
87
  replacements: expect.objectContaining({
88
- models: expect.any(Object)
89
- })
90
- })
88
+ models: expect.any(Object),
89
+ }),
90
+ }),
91
91
  ]));
92
92
  // Should not call getAvailableTemplates since no template validation needed
93
93
  expect(getAvailableTemplates).not.toHaveBeenCalled();
94
94
  });
95
- it('should create project with weather-project as project ID', async () => {
95
+ it('should create project with event-planner as project ID', async () => {
96
96
  await createAgents({
97
97
  dirName: 'test-dir',
98
98
  openAiKey: 'test-openai-key',
@@ -117,13 +117,13 @@ describe('createAgents - Template and Project ID Logic', () => {
117
117
  // Should clone base template and the specified template
118
118
  expect(cloneTemplate).toHaveBeenCalledTimes(2);
119
119
  expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/create-agents-template', expect.any(String));
120
- expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/agents-cookbook/template-projects/chatbot', 'src/chatbot', expect.arrayContaining([
120
+ expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/agents-cookbook/template-projects/chatbot', 'src/projects/chatbot', expect.arrayContaining([
121
121
  expect.objectContaining({
122
122
  filePath: 'index.ts',
123
123
  replacements: expect.objectContaining({
124
- models: expect.any(Object)
125
- })
126
- })
124
+ models: expect.any(Object),
125
+ }),
126
+ }),
127
127
  ]));
128
128
  // Check that .env file is created
129
129
  expect(fs.writeFile).toHaveBeenCalledWith('.env', expect.stringContaining('ENVIRONMENT=development'));
@@ -131,7 +131,7 @@ describe('createAgents - Template and Project ID Logic', () => {
131
131
  expect(fs.writeFile).toHaveBeenCalledWith('src/inkeep.config.ts', expect.stringContaining('tenantId: "default"'));
132
132
  });
133
133
  it('should exit with error when template does not exist', async () => {
134
- vi.mocked(getAvailableTemplates).mockResolvedValue(['weather-project', 'chatbot']);
134
+ vi.mocked(getAvailableTemplates).mockResolvedValue(['event-planner', 'chatbot']);
135
135
  await expect(createAgents({
136
136
  dirName: 'test-dir',
137
137
  template: 'non-existent-template',
@@ -142,7 +142,7 @@ describe('createAgents - Template and Project ID Logic', () => {
142
142
  });
143
143
  it('should show available templates when invalid template is provided', async () => {
144
144
  vi.mocked(getAvailableTemplates).mockResolvedValue([
145
- 'weather-project',
145
+ 'event-planner',
146
146
  'chatbot',
147
147
  'data-analysis',
148
148
  ]);
@@ -152,7 +152,7 @@ describe('createAgents - Template and Project ID Logic', () => {
152
152
  openAiKey: 'test-openai-key',
153
153
  })).rejects.toThrow('process.exit called');
154
154
  const cancelCall = vi.mocked(p.cancel).mock.calls[0][0];
155
- expect(cancelCall).toContain('weather-project');
155
+ expect(cancelCall).toContain('event-planner');
156
156
  expect(cancelCall).toContain('chatbot');
157
157
  expect(cancelCall).toContain('data-analysis');
158
158
  });
@@ -171,13 +171,13 @@ describe('createAgents - Template and Project ID Logic', () => {
171
171
  // Should NOT validate templates
172
172
  expect(getAvailableTemplates).not.toHaveBeenCalled();
173
173
  // Should create empty project directory
174
- expect(fs.ensureDir).toHaveBeenCalledWith('src/my-custom-project');
174
+ expect(fs.ensureDir).toHaveBeenCalledWith('src/projects/my-custom-project');
175
175
  // Check that .env file is created
176
176
  expect(fs.writeFile).toHaveBeenCalledWith('.env', expect.stringContaining('ENVIRONMENT=development'));
177
177
  // Check that inkeep.config.ts is created in src directory
178
178
  expect(fs.writeFile).toHaveBeenCalledWith('src/inkeep.config.ts', expect.stringContaining('tenantId: "default"'));
179
179
  // Check that custom project index.ts is created
180
- expect(fs.writeFile).toHaveBeenCalledWith('src/my-custom-project/index.ts', expect.stringContaining('id: "my-custom-project"'));
180
+ expect(fs.writeFile).toHaveBeenCalledWith('src/projects/my-custom-project/index.ts', expect.stringContaining('id: "my-custom-project"'));
181
181
  });
182
182
  it('should prioritize custom project ID over template if both are provided', async () => {
183
183
  await createAgents({
@@ -191,13 +191,13 @@ describe('createAgents - Template and Project ID Logic', () => {
191
191
  expect(cloneTemplate).toHaveBeenCalledTimes(1);
192
192
  expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/create-agents-template', expect.any(String));
193
193
  expect(getAvailableTemplates).not.toHaveBeenCalled();
194
- expect(fs.ensureDir).toHaveBeenCalledWith('src/my-custom-project');
194
+ expect(fs.ensureDir).toHaveBeenCalledWith('src/projects/my-custom-project');
195
195
  // Check that .env file is created
196
196
  expect(fs.writeFile).toHaveBeenCalledWith('.env', expect.stringContaining('ENVIRONMENT=development'));
197
197
  // Check that inkeep.config.ts is created in src directory
198
198
  expect(fs.writeFile).toHaveBeenCalledWith('src/inkeep.config.ts', expect.stringContaining('tenantId: "default"'));
199
199
  // Check that custom project index.ts is created
200
- expect(fs.writeFile).toHaveBeenCalledWith('src/my-custom-project/index.ts', expect.stringContaining('id: "my-custom-project"'));
200
+ expect(fs.writeFile).toHaveBeenCalledWith('src/projects/my-custom-project/index.ts', expect.stringContaining('id: "my-custom-project"'));
201
201
  });
202
202
  });
203
203
  describe('Edge cases and validation', () => {
@@ -213,13 +213,13 @@ describe('createAgents - Template and Project ID Logic', () => {
213
213
  anthropicKey: 'test-key',
214
214
  });
215
215
  expect(cloneTemplate).toHaveBeenCalledTimes(2);
216
- expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/agents-cookbook/template-projects/my-complex-template', 'src/my-complex-template', expect.arrayContaining([
216
+ expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/agents-cookbook/template-projects/my-complex-template', 'src/projects/my-complex-template', expect.arrayContaining([
217
217
  expect.objectContaining({
218
218
  filePath: 'index.ts',
219
219
  replacements: expect.objectContaining({
220
- models: expect.any(Object)
221
- })
222
- })
220
+ models: expect.any(Object),
221
+ }),
222
+ }),
223
223
  ]));
224
224
  });
225
225
  it('should handle custom project IDs with special characters', async () => {
@@ -229,13 +229,13 @@ describe('createAgents - Template and Project ID Logic', () => {
229
229
  openAiKey: 'test-key',
230
230
  anthropicKey: 'test-key',
231
231
  });
232
- expect(fs.ensureDir).toHaveBeenCalledWith('src/my_project-123');
232
+ expect(fs.ensureDir).toHaveBeenCalledWith('src/projects/my_project-123');
233
233
  // Check that .env file is created
234
234
  expect(fs.writeFile).toHaveBeenCalledWith('.env', expect.stringContaining('ENVIRONMENT=development'));
235
235
  // Check that inkeep.config.ts is created in src directory
236
236
  expect(fs.writeFile).toHaveBeenCalledWith('src/inkeep.config.ts', expect.stringContaining('tenantId: "default"'));
237
237
  // Check that custom project index.ts is created
238
- expect(fs.writeFile).toHaveBeenCalledWith('src/my_project-123/index.ts', expect.stringContaining('id: "my_project-123"'));
238
+ expect(fs.writeFile).toHaveBeenCalledWith('src/projects/my_project-123/index.ts', expect.stringContaining('id: "my_project-123"'));
239
239
  });
240
240
  it('should create correct folder structure for all scenarios', async () => {
241
241
  // Test default
@@ -267,7 +267,7 @@ describe('createAgents - Template and Project ID Logic', () => {
267
267
  anthropicKey: 'key',
268
268
  });
269
269
  expect(fs.ensureDir).toHaveBeenCalledWith('src');
270
- expect(fs.ensureDir).toHaveBeenCalledWith('src/custom');
270
+ expect(fs.ensureDir).toHaveBeenCalledWith('src/projects/custom');
271
271
  });
272
272
  });
273
273
  });
@@ -277,10 +277,6 @@ function setupDefaultMocks() {
277
277
  vi.mocked(fs.pathExists).mockResolvedValue(false);
278
278
  vi.mocked(fs.ensureDir).mockResolvedValue(undefined);
279
279
  vi.mocked(fs.writeFile).mockResolvedValue(undefined);
280
- vi.mocked(getAvailableTemplates).mockResolvedValue([
281
- 'weather-project',
282
- 'chatbot',
283
- 'data-analysis',
284
- ]);
280
+ vi.mocked(getAvailableTemplates).mockResolvedValue(['event-planner', 'chatbot', 'data-analysis']);
285
281
  vi.mocked(cloneTemplate).mockResolvedValue(undefined);
286
282
  }
@@ -5,6 +5,7 @@ export interface ContentReplacement {
5
5
  replacements: Record<string, any>;
6
6
  }
7
7
  export declare function cloneTemplate(templatePath: string, targetPath: string, replacements?: ContentReplacement[]): Promise<void>;
8
+ export declare function cloneTemplateLocal(templatePath: string, targetPath: string, replacements: ContentReplacement[]): Promise<void>;
8
9
  /**
9
10
  * Replace content in cloned template files
10
11
  */
package/dist/templates.js CHANGED
@@ -17,6 +17,22 @@ export async function cloneTemplate(templatePath, targetPath, replacements) {
17
17
  process.exit(1);
18
18
  }
19
19
  }
20
+ export async function cloneTemplateLocal(templatePath, targetPath, replacements) {
21
+ await fs.mkdir(targetPath, { recursive: true });
22
+ try {
23
+ await fs.copy(templatePath, targetPath, {
24
+ overwrite: true,
25
+ errorOnExist: false,
26
+ });
27
+ if (replacements && replacements.length > 0) {
28
+ await replaceContentInFiles(targetPath, replacements);
29
+ }
30
+ }
31
+ catch (error) {
32
+ console.error(`Failed to clone template from ${templatePath}:`, error);
33
+ process.exit(1);
34
+ }
35
+ }
20
36
  /**
21
37
  * Replace content in cloned template files
22
38
  */
package/dist/utils.js CHANGED
@@ -2,9 +2,9 @@ import { exec } from 'node:child_process';
2
2
  import path from 'node:path';
3
3
  import { promisify } from 'node:util';
4
4
  import * as p from '@clack/prompts';
5
+ import { ANTHROPIC_MODELS, GOOGLE_MODELS, OPENAI_MODELS } from '@inkeep/agents-core';
5
6
  import fs from 'fs-extra';
6
7
  import color from 'picocolors';
7
- import { ANTHROPIC_MODELS, OPENAI_MODELS, GOOGLE_MODELS } from '@inkeep/agents-core';
8
8
  import { cloneTemplate, getAvailableTemplates } from './templates.js';
9
9
  const execAsync = promisify(exec);
10
10
  export const defaultGoogleModelConfigurations = {
@@ -63,8 +63,8 @@ export const createAgents = async (args = {}) => {
63
63
  templateName = template;
64
64
  }
65
65
  else {
66
- projectId = 'weather-project';
67
- templateName = 'weather-project';
66
+ projectId = 'event-planner';
67
+ templateName = 'event-planner';
68
68
  }
69
69
  p.intro(color.inverse(' Create Agents Directory '));
70
70
  if (!dirName) {
@@ -205,7 +205,7 @@ export const createAgents = async (args = {}) => {
205
205
  await createEnvironmentFiles(config);
206
206
  if (projectTemplateRepo) {
207
207
  s.message('Creating project template folder...');
208
- const templateTargetPath = `src/${projectId}`;
208
+ const templateTargetPath = `src/projects/${projectId}`;
209
209
  const contentReplacements = [
210
210
  {
211
211
  filePath: 'index.ts',
@@ -218,7 +218,7 @@ export const createAgents = async (args = {}) => {
218
218
  }
219
219
  else {
220
220
  s.message('Creating empty project folder...');
221
- await fs.ensureDir(`src/${projectId}`);
221
+ await fs.ensureDir(`src/projects/${projectId}`);
222
222
  }
223
223
  s.message('Creating inkeep.config.ts...');
224
224
  await createInkeepConfig(config);
@@ -244,7 +244,7 @@ export const createAgents = async (args = {}) => {
244
244
  ` • Manage UI: Available with management API\n` +
245
245
  `\n${color.yellow('Configuration:')}\n` +
246
246
  ` • Edit .env for environment variables\n` +
247
- ` • Edit files in src/${projectId}/ for agent definitions\n` +
247
+ ` • Edit files in src/projects/${projectId}/ for agent definitions\n` +
248
248
  ` • Use 'inkeep push' to deploy agents to the platform\n` +
249
249
  ` • Use 'inkeep chat' to test your agents locally\n`, 'Ready to go!');
250
250
  }
@@ -307,7 +307,7 @@ export const myProject = project({
307
307
  agent: () => [],
308
308
  models: ${JSON.stringify(config.modelSettings, null, 2)},
309
309
  });`;
310
- await fs.writeFile(`src/${config.projectId}/index.ts`, customIndexContent);
310
+ await fs.writeFile(`src/projects/${config.projectId}/index.ts`, customIndexContent);
311
311
  }
312
312
  }
313
313
  async function installDependencies() {
@@ -322,7 +322,7 @@ async function setupProjectInDatabase(config) {
322
322
  });
323
323
  await new Promise((resolve) => setTimeout(resolve, 5000));
324
324
  try {
325
- await execAsync(`pnpm inkeep push --project src/${config.projectId} --config src/inkeep.config.ts`);
325
+ await execAsync(`pnpm inkeep push --project src/projects/${config.projectId} --config src/inkeep.config.ts`);
326
326
  }
327
327
  catch (_error) {
328
328
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkeep/create-agents",
3
- "version": "0.0.0-dev-20251014203435",
3
+ "version": "0.0.0-dev-20251014211138",
4
4
  "description": "Create an Inkeep Agent Framework project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -34,7 +34,7 @@
34
34
  "fs-extra": "^11.0.0",
35
35
  "picocolors": "^1.0.0",
36
36
  "drizzle-kit": "^0.31.5",
37
- "@inkeep/agents-core": "0.0.0-dev-20251014203435"
37
+ "@inkeep/agents-core": "0.0.0-dev-20251014211138"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/degit": "^2.8.6",