@inkeep/create-agents 0.33.2 → 0.34.1
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/__tests__/e2e/quickstart.test.js +2 -0
- package/dist/__tests__/utils.test.js +4 -0
- package/dist/index.js +4 -0
- package/dist/templates.js +13 -1
- package/dist/utils.d.ts +3 -0
- package/dist/utils.js +161 -1
- package/package.json +2 -2
|
@@ -32,6 +32,8 @@ describe('create-agents quickstart e2e', () => {
|
|
|
32
32
|
createAgentsPrefix,
|
|
33
33
|
'--local-templates-prefix',
|
|
34
34
|
projectTemplatesPrefix,
|
|
35
|
+
'--skip-inkeep-cli',
|
|
36
|
+
'--skip-inkeep-mcp',
|
|
35
37
|
], testDir);
|
|
36
38
|
// Verify the CLI completed successfully
|
|
37
39
|
expect(result.exitCode, `CLI failed with exit code ${result.exitCode}\nstdout: ${result.stdout}\nstderr: ${result.stderr}`).toBe(0);
|
|
@@ -46,6 +46,8 @@ describe('createAgents - Template and Project ID Logic', () => {
|
|
|
46
46
|
vi.mocked(fs.pathExists).mockResolvedValue(false);
|
|
47
47
|
vi.mocked(fs.ensureDir).mockResolvedValue(undefined);
|
|
48
48
|
vi.mocked(fs.writeFile).mockResolvedValue(undefined);
|
|
49
|
+
vi.mocked(fs.writeJson).mockResolvedValue(undefined);
|
|
50
|
+
vi.mocked(fs.readJson).mockResolvedValue({});
|
|
49
51
|
vi.mocked(fs.mkdir).mockResolvedValue(undefined);
|
|
50
52
|
vi.mocked(fs.remove).mockResolvedValue(undefined);
|
|
51
53
|
// Mock templates
|
|
@@ -327,6 +329,8 @@ function setupDefaultMocks() {
|
|
|
327
329
|
vi.mocked(fs.pathExists).mockResolvedValue(false);
|
|
328
330
|
vi.mocked(fs.ensureDir).mockResolvedValue(undefined);
|
|
329
331
|
vi.mocked(fs.writeFile).mockResolvedValue(undefined);
|
|
332
|
+
vi.mocked(fs.writeJson).mockResolvedValue(undefined);
|
|
333
|
+
vi.mocked(fs.readJson).mockResolvedValue({});
|
|
330
334
|
vi.mocked(getAvailableTemplates).mockResolvedValue(['event-planner', 'chatbot', 'data-analysis']);
|
|
331
335
|
vi.mocked(cloneTemplate).mockResolvedValue(undefined);
|
|
332
336
|
vi.mocked(cloneTemplateLocal).mockResolvedValue(undefined);
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,8 @@ program
|
|
|
13
13
|
.option('--disable-git', 'Disable git initialization')
|
|
14
14
|
.option('--local-agents-prefix <local-agents-prefix>', 'Local prefix for create-agents-template')
|
|
15
15
|
.option('--local-templates-prefix <local-templates-prefix>', 'Local prefix for project templates')
|
|
16
|
+
.option('--skip-inkeep-cli', 'Skip installing Inkeep CLI globally')
|
|
17
|
+
.option('--skip-inkeep-mcp', 'Skip installing Inkeep MCP server')
|
|
16
18
|
.parse();
|
|
17
19
|
async function main() {
|
|
18
20
|
const options = program.opts();
|
|
@@ -27,6 +29,8 @@ async function main() {
|
|
|
27
29
|
disableGit: options.disableGit,
|
|
28
30
|
localAgentsPrefix: options.localAgentsPrefix,
|
|
29
31
|
localTemplatesPrefix: options.localTemplatesPrefix,
|
|
32
|
+
skipInkeepCli: options.skipInkeepCli,
|
|
33
|
+
skipInkeepMcp: options.skipInkeepMcp,
|
|
30
34
|
});
|
|
31
35
|
}
|
|
32
36
|
catch (error) {
|
package/dist/templates.js
CHANGED
|
@@ -261,6 +261,18 @@ export async function getAvailableTemplates(localPrefix) {
|
|
|
261
261
|
}
|
|
262
262
|
// Fetch the list of templates from your repo
|
|
263
263
|
const response = await fetch(`https://api.github.com/repos/inkeep/agents/contents/agents-cookbook/template-projects`);
|
|
264
|
-
|
|
264
|
+
if (!response.ok) {
|
|
265
|
+
throw new Error(`Failed to fetch templates. Please check your internet connection and try again.`);
|
|
266
|
+
}
|
|
267
|
+
let contents;
|
|
268
|
+
try {
|
|
269
|
+
contents = await response.json();
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
throw new Error(`Failed to parse templates response. Please check your internet connection and try again. ${error}`);
|
|
273
|
+
}
|
|
274
|
+
if (!Array.isArray(contents)) {
|
|
275
|
+
throw new Error('Unexpected response format from templates. Please check your internet connection and try again');
|
|
276
|
+
}
|
|
265
277
|
return contents.filter((item) => item.type === 'dir').map((item) => item.name);
|
|
266
278
|
}
|
package/dist/utils.d.ts
CHANGED
|
@@ -42,5 +42,8 @@ export declare const createAgents: (args?: {
|
|
|
42
42
|
disableGit?: boolean;
|
|
43
43
|
localAgentsPrefix?: string;
|
|
44
44
|
localTemplatesPrefix?: string;
|
|
45
|
+
skipInkeepCli?: boolean;
|
|
46
|
+
skipInkeepMcp?: boolean;
|
|
45
47
|
}) => Promise<void>;
|
|
46
48
|
export declare function createCommand(dirName?: string, options?: any): Promise<void>;
|
|
49
|
+
export declare function addInkeepMcp(): Promise<void>;
|
package/dist/utils.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { exec } from 'node:child_process';
|
|
2
2
|
import crypto from 'node:crypto';
|
|
3
|
+
import os from 'node:os';
|
|
3
4
|
import path from 'node:path';
|
|
4
5
|
import { promisify } from 'node:util';
|
|
5
6
|
import * as p from '@clack/prompts';
|
|
@@ -67,7 +68,8 @@ export const defaultAnthropicModelConfigurations = {
|
|
|
67
68
|
},
|
|
68
69
|
};
|
|
69
70
|
export const createAgents = async (args = {}) => {
|
|
70
|
-
let { dirName, openAiKey, anthropicKey, googleKey, template, customProjectId, disableGit, localAgentsPrefix, localTemplatesPrefix, } = args;
|
|
71
|
+
let { dirName, openAiKey, anthropicKey, googleKey, template, customProjectId, disableGit, localAgentsPrefix, localTemplatesPrefix, skipInkeepCli, skipInkeepMcp, } = args;
|
|
72
|
+
console.log('skipInkeepCli', skipInkeepCli);
|
|
71
73
|
const tenantId = 'default';
|
|
72
74
|
let projectId;
|
|
73
75
|
let templateName;
|
|
@@ -255,6 +257,17 @@ export const createAgents = async (args = {}) => {
|
|
|
255
257
|
}
|
|
256
258
|
await checkPortsAvailability();
|
|
257
259
|
s.stop();
|
|
260
|
+
if (!skipInkeepCli) {
|
|
261
|
+
const installInkeepCLIResponse = await p.confirm({
|
|
262
|
+
message: 'Would you like to install the Inkeep CLI globally?',
|
|
263
|
+
});
|
|
264
|
+
if (!p.isCancel(installInkeepCLIResponse) && installInkeepCLIResponse) {
|
|
265
|
+
await installInkeepCLIGlobally();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (!skipInkeepMcp) {
|
|
269
|
+
await addInkeepMcp();
|
|
270
|
+
}
|
|
258
271
|
p.note(`${color.green('✓')} Workspace created at: ${color.cyan(directoryPath)}\n\n` +
|
|
259
272
|
`${color.yellow('Next steps:')}\n` +
|
|
260
273
|
` cd ${dirName}\n` +
|
|
@@ -348,6 +361,30 @@ export const myProject = project({
|
|
|
348
361
|
await fs.writeFile(`src/projects/${config.projectId}/index.ts`, customIndexContent);
|
|
349
362
|
}
|
|
350
363
|
}
|
|
364
|
+
async function installInkeepCLIGlobally() {
|
|
365
|
+
const s = p.spinner();
|
|
366
|
+
s.start('Installing Inkeep CLI globally with pnpm...');
|
|
367
|
+
try {
|
|
368
|
+
await execAsync('pnpm add -g @inkeep/agents-cli');
|
|
369
|
+
s.stop('✓ Inkeep CLI installed successfully with pnpm');
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
catch (_pnpmError) {
|
|
373
|
+
s.message('pnpm failed, trying npm...');
|
|
374
|
+
try {
|
|
375
|
+
await execAsync('npm install -g @inkeep/agents-cli');
|
|
376
|
+
s.stop('✓ Inkeep CLI installed successfully with npm');
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
catch (_npmError) {
|
|
380
|
+
s.stop('⚠️ Could not automatically install Inkeep CLI globally');
|
|
381
|
+
console.warn('You can install it manually later by running:');
|
|
382
|
+
console.warn(' npm install -g @inkeep/agents-cli');
|
|
383
|
+
console.warn(' or');
|
|
384
|
+
console.warn(' pnpm add -g @inkeep/agents-cli\n');
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
351
388
|
async function installDependencies() {
|
|
352
389
|
try {
|
|
353
390
|
const { stderr } = await execAsync('pnpm install');
|
|
@@ -458,3 +495,126 @@ export async function createCommand(dirName, options) {
|
|
|
458
495
|
...options,
|
|
459
496
|
});
|
|
460
497
|
}
|
|
498
|
+
export async function addInkeepMcp() {
|
|
499
|
+
const editorChoice = await p.select({
|
|
500
|
+
message: 'Give your IDE access to Inkeep docs and types? (Adds Inkeep MCP)',
|
|
501
|
+
options: [
|
|
502
|
+
{ value: 'cursor-project', label: 'Cursor (project only)' },
|
|
503
|
+
{ value: 'cursor-global', label: 'Cursor (global, all projects)' },
|
|
504
|
+
{ value: 'windsurf', label: 'Windsurf' },
|
|
505
|
+
{ value: 'vscode', label: 'VSCode' },
|
|
506
|
+
],
|
|
507
|
+
initialValue: 'cursor-project',
|
|
508
|
+
});
|
|
509
|
+
if (p.isCancel(editorChoice)) {
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
if (!editorChoice) {
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
const s = p.spinner();
|
|
516
|
+
try {
|
|
517
|
+
const mcpConfig = {
|
|
518
|
+
mcpServers: {
|
|
519
|
+
inkeep: {
|
|
520
|
+
type: 'mcp',
|
|
521
|
+
url: 'https://agents.inkeep.com/mcp',
|
|
522
|
+
},
|
|
523
|
+
},
|
|
524
|
+
};
|
|
525
|
+
const homeDir = os.homedir();
|
|
526
|
+
switch (editorChoice) {
|
|
527
|
+
case 'cursor-project': {
|
|
528
|
+
s.start('Adding Inkeep MCP to Cursor (project)...');
|
|
529
|
+
const cursorDir = path.join(process.cwd(), '.cursor');
|
|
530
|
+
const configPath = path.join(cursorDir, 'mcp.json');
|
|
531
|
+
await fs.ensureDir(cursorDir);
|
|
532
|
+
let existingConfig = {};
|
|
533
|
+
if (await fs.pathExists(configPath)) {
|
|
534
|
+
existingConfig = await fs.readJson(configPath);
|
|
535
|
+
}
|
|
536
|
+
const mergedConfig = {
|
|
537
|
+
...existingConfig,
|
|
538
|
+
mcpServers: {
|
|
539
|
+
...existingConfig.mcpServers,
|
|
540
|
+
...mcpConfig.mcpServers,
|
|
541
|
+
},
|
|
542
|
+
};
|
|
543
|
+
await fs.writeJson(configPath, mergedConfig, { spaces: 2 });
|
|
544
|
+
s.stop(`${color.green('✓')} Inkeep MCP added to .cursor/mcp.json`);
|
|
545
|
+
break;
|
|
546
|
+
}
|
|
547
|
+
case 'cursor-global': {
|
|
548
|
+
s.start('Adding Inkeep MCP to Cursor (global)...');
|
|
549
|
+
const configPath = path.join(homeDir, '.cursor', 'mcp.json');
|
|
550
|
+
await fs.ensureDir(path.dirname(configPath));
|
|
551
|
+
let existingConfig = {};
|
|
552
|
+
if (await fs.pathExists(configPath)) {
|
|
553
|
+
existingConfig = await fs.readJson(configPath);
|
|
554
|
+
}
|
|
555
|
+
const mergedConfig = {
|
|
556
|
+
...existingConfig,
|
|
557
|
+
mcpServers: {
|
|
558
|
+
...existingConfig.mcpServers,
|
|
559
|
+
...mcpConfig.mcpServers,
|
|
560
|
+
},
|
|
561
|
+
};
|
|
562
|
+
await fs.writeJson(configPath, mergedConfig, { spaces: 2 });
|
|
563
|
+
s.stop(`${color.green('✓')} Inkeep MCP added to global Cursor settings`);
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
case 'windsurf': {
|
|
567
|
+
s.start('Adding Inkeep MCP to Windsurf...');
|
|
568
|
+
const configPath = path.join(homeDir, '.codeium', 'windsurf', 'mcp_config.json');
|
|
569
|
+
await fs.ensureDir(path.dirname(configPath));
|
|
570
|
+
let existingConfig = {};
|
|
571
|
+
if (await fs.pathExists(configPath)) {
|
|
572
|
+
existingConfig = await fs.readJson(configPath);
|
|
573
|
+
}
|
|
574
|
+
const mergedConfig = {
|
|
575
|
+
...existingConfig,
|
|
576
|
+
mcpServers: {
|
|
577
|
+
...existingConfig.mcpServers,
|
|
578
|
+
...mcpConfig.mcpServers,
|
|
579
|
+
},
|
|
580
|
+
};
|
|
581
|
+
await fs.writeJson(configPath, mergedConfig, { spaces: 2 });
|
|
582
|
+
s.stop(`${color.green('✓')} Inkeep MCP added to Windsurf settings`);
|
|
583
|
+
break;
|
|
584
|
+
}
|
|
585
|
+
case 'vscode': {
|
|
586
|
+
s.start('Adding Inkeep MCP to VSCode...');
|
|
587
|
+
let configPath;
|
|
588
|
+
if (process.platform === 'darwin') {
|
|
589
|
+
configPath = path.join(homeDir, 'Library', 'Application Support', 'Code', 'User', 'mcp.json');
|
|
590
|
+
}
|
|
591
|
+
else if (process.platform === 'win32') {
|
|
592
|
+
configPath = path.join(homeDir, 'AppData', 'Roaming', 'Code', 'User', 'mcp.json');
|
|
593
|
+
}
|
|
594
|
+
else {
|
|
595
|
+
configPath = path.join(homeDir, '.config', 'Code', 'User', 'mcp.json');
|
|
596
|
+
}
|
|
597
|
+
await fs.ensureDir(path.dirname(configPath));
|
|
598
|
+
let existingConfig = {};
|
|
599
|
+
if (await fs.pathExists(configPath)) {
|
|
600
|
+
existingConfig = await fs.readJson(configPath);
|
|
601
|
+
}
|
|
602
|
+
const mergedConfig = {
|
|
603
|
+
...existingConfig,
|
|
604
|
+
servers: {
|
|
605
|
+
...existingConfig.servers,
|
|
606
|
+
...mcpConfig.mcpServers,
|
|
607
|
+
},
|
|
608
|
+
};
|
|
609
|
+
await fs.writeJson(configPath, mergedConfig, { spaces: 2 });
|
|
610
|
+
s.stop(`${color.green('✓')} Inkeep MCP added to VSCode settings\n\n${color.yellow('Next steps:')}\n` +
|
|
611
|
+
` start the MCP by going to ${configPath} and clicking start`);
|
|
612
|
+
break;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
catch (error) {
|
|
617
|
+
s.stop();
|
|
618
|
+
console.error(`${color.yellow('⚠')} Could not automatically configure MCP server: ${error}`);
|
|
619
|
+
}
|
|
620
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inkeep/create-agents",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.1",
|
|
4
4
|
"description": "Create an Inkeep Agent Framework project",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"drizzle-kit": "^0.31.5",
|
|
35
35
|
"fs-extra": "^11.0.0",
|
|
36
36
|
"picocolors": "^1.0.0",
|
|
37
|
-
"@inkeep/agents-core": "0.
|
|
37
|
+
"@inkeep/agents-core": "0.34.1"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/degit": "^2.8.6",
|