@inkeep/create-agents 0.0.0-dev-20260225021710 → 0.0.0-dev-20260225060111

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.
@@ -229,8 +229,12 @@ describe('create-agents quickstart e2e', () => {
229
229
  console.warn('Login API test failed (non-fatal):', loginTestError);
230
230
  }
231
231
  // --- Dashboard Lap ---
232
+ // Start the dashboard with ENVIRONMENT=development so the proxy middleware
233
+ // auto-logs in using the bypass secret — this mirrors the real quickstart
234
+ // experience where users never see a login form.
232
235
  console.log('Starting dashboard lap');
233
236
  const dashboardProcess = await startDashboardServer(projectDir, {
237
+ ENVIRONMENT: 'development',
234
238
  INKEEP_AGENTS_API_URL: dashboardApiUrl,
235
239
  NEXT_PUBLIC_API_URL: dashboardApiUrl,
236
240
  PUBLIC_INKEEP_AGENTS_API_URL: dashboardApiUrl,
@@ -241,21 +245,19 @@ describe('create-agents quickstart e2e', () => {
241
245
  const browser = await chromium.launch({ headless: true });
242
246
  try {
243
247
  const page = await browser.newPage();
244
- console.log('Navigating to login page');
245
- await page.goto('http://localhost:3000/login', {
248
+ // Navigate to root — the proxy middleware auto-logs in via the bypass
249
+ // secret and sets a session cookie, so no manual login is needed.
250
+ console.log('Navigating to dashboard (auto-login via proxy)');
251
+ await page.goto('http://localhost:3000/', {
246
252
  waitUntil: 'networkidle',
247
- timeout: 15000,
253
+ timeout: 30000,
248
254
  });
249
- console.log('Filling login form');
250
- await page.fill('input[type="email"]', 'admin@example.com');
251
- await page.fill('input[type="password"]', 'adminADMIN!@12');
252
- await page.click('button[type="submit"]');
253
255
  console.log('Waiting for redirect to projects page');
254
256
  await page.waitForURL('**/default/projects**', {
255
- timeout: 15000,
257
+ timeout: 30000,
256
258
  waitUntil: 'domcontentloaded',
257
259
  });
258
- console.log('Redirected to projects page');
260
+ console.log('Auto-login succeeded — redirected to projects page');
259
261
  console.log('Clicking activities-planner project');
260
262
  // Use force:true because card uses a linkoverlay pattern that intercepts pointer events
261
263
  await page.click(`a[href*="${projectId}"]`, { timeout: 15000, force: true });
@@ -137,15 +137,32 @@ export async function verifyDirectoryStructure(baseDir, expectedPaths) {
137
137
  }
138
138
  }
139
139
  }
140
+ /**
141
+ * Recursively find all package.json files in a directory, skipping node_modules and dot-dirs.
142
+ * Mirrors the discovery logic in syncTemplateDependencies so E2E tests cover the same files.
143
+ */
144
+ async function findPackageJsonFiles(dir) {
145
+ const results = [];
146
+ const rootPkg = path.join(dir, 'package.json');
147
+ if (await fs.pathExists(rootPkg)) {
148
+ results.push(rootPkg);
149
+ }
150
+ const entries = await fs.readdir(dir, { withFileTypes: true });
151
+ for (const entry of entries) {
152
+ if (!entry.isDirectory() || entry.name === 'node_modules' || entry.name.startsWith('.')) {
153
+ continue;
154
+ }
155
+ const nested = await findPackageJsonFiles(path.join(dir, entry.name));
156
+ results.push(...nested);
157
+ }
158
+ return results;
159
+ }
140
160
  /**
141
161
  * Link local monorepo packages to the created project
142
162
  * This replaces published @inkeep packages with local versions for testing
143
163
  */
144
164
  export async function linkLocalPackages(projectDir, monorepoRoot) {
145
- const packageJsonPaths = [
146
- path.join(projectDir, 'package.json'),
147
- path.join(projectDir, 'apps/agents-api/package.json'),
148
- ];
165
+ const packageJsonPaths = await findPackageJsonFiles(projectDir);
149
166
  const packageJsons = {};
150
167
  for (const packageJsonPath of packageJsonPaths) {
151
168
  packageJsons[packageJsonPath] = await fs.readJson(packageJsonPath);
@@ -376,13 +376,19 @@ describe('createAgents - Template and Project ID Logic', () => {
376
376
  });
377
377
  });
378
378
  describe('Environment file generation', () => {
379
- it('should contain INKEEP_AGENTS_MANAGE_API_BYPASS_SECRET from .env.example', async () => {
379
+ it('should generate a unique INKEEP_AGENTS_MANAGE_API_BYPASS_SECRET', async () => {
380
380
  await createAgents({
381
381
  dirName: 'test-dir',
382
382
  openAiKey: 'test-openai-key',
383
383
  anthropicKey: 'test-anthropic-key',
384
384
  });
385
- expect(fs.writeFile).toHaveBeenCalledWith('.env', expect.stringContaining('INKEEP_AGENTS_MANAGE_API_BYPASS_SECRET=test-bypass-secret-for-ci'));
385
+ const envWriteCall = vi.mocked(fs.writeFile).mock.calls.find((call) => call[0] === '.env');
386
+ expect(envWriteCall).toBeDefined();
387
+ const envContent = envWriteCall?.[1];
388
+ const match = envContent.match(/INKEEP_AGENTS_MANAGE_API_BYPASS_SECRET=(.+)/);
389
+ expect(match).not.toBeNull();
390
+ expect(match?.[1]).not.toBe('test-bypass-secret-for-ci');
391
+ expect(match?.[1]).toHaveLength(64);
386
392
  });
387
393
  it('should inject CLI-prompted API keys into the .env', async () => {
388
394
  await createAgents({
package/dist/utils.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { exec } from 'node:child_process';
2
+ import crypto from 'node:crypto';
2
3
  import { readFileSync } from 'node:fs';
3
4
  import os from 'node:os';
4
5
  import path from 'node:path';
@@ -509,6 +510,7 @@ async function createWorkspaceStructure() {
509
510
  await fs.ensureDir(`src`);
510
511
  }
511
512
  async function createEnvironmentFiles(config) {
513
+ const bypassSecret = crypto.randomBytes(32).toString('hex');
512
514
  let envExampleContent;
513
515
  try {
514
516
  envExampleContent = await fs.readFile('.env.example', 'utf-8');
@@ -523,6 +525,7 @@ async function createEnvironmentFiles(config) {
523
525
  GOOGLE_GENERATIVE_AI_API_KEY: config.googleKey || '',
524
526
  AZURE_API_KEY: config.azureKey || '',
525
527
  DEFAULT_PROJECT_ID: config.projectId,
528
+ INKEEP_AGENTS_MANAGE_API_BYPASS_SECRET: bypassSecret,
526
529
  };
527
530
  for (let i = 0; i < lines.length; i++) {
528
531
  for (const [varName, value] of Object.entries(injections)) {
@@ -539,8 +542,11 @@ async function createInkeepConfig(config) {
539
542
  const config = defineConfig({
540
543
  tenantId: "${config.tenantId}",
541
544
  agentsApi: {
542
- url: 'http://localhost:3002',
545
+ // Using 127.0.0.1 instead of localhost to avoid IPv6/IPv4 resolution issues
546
+ url: 'http://127.0.0.1:3002',
547
+ apiKey: process.env.INKEEP_AGENTS_MANAGE_API_BYPASS_SECRET,
543
548
  },
549
+ manageUiUrl: 'http://localhost:3000',
544
550
  });
545
551
 
546
552
  export default config;`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkeep/create-agents",
3
- "version": "0.0.0-dev-20260225021710",
3
+ "version": "0.0.0-dev-20260225060111",
4
4
  "description": "Create an Inkeep Agent Framework project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,7 +33,7 @@
33
33
  "degit": "^2.8.4",
34
34
  "fs-extra": "^11.0.0",
35
35
  "picocolors": "^1.0.0",
36
- "@inkeep/agents-core": "0.0.0-dev-20260225021710"
36
+ "@inkeep/agents-core": "0.0.0-dev-20260225060111"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/degit": "^2.8.6",