@kya-os/cli 0.1.0-beta.8 → 1.0.0-beta-0.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.
Files changed (107) hide show
  1. package/README.md +24 -26
  2. package/dist/commands/check.d.ts.map +1 -1
  3. package/dist/commands/check.js +62 -61
  4. package/dist/commands/check.js.map +1 -1
  5. package/dist/commands/claim.d.ts.map +1 -1
  6. package/dist/commands/claim.js +31 -31
  7. package/dist/commands/claim.js.map +1 -1
  8. package/dist/commands/env.d.ts +1 -1
  9. package/dist/commands/env.js +90 -89
  10. package/dist/commands/env.js.map +1 -1
  11. package/dist/commands/init.d.ts.map +1 -1
  12. package/dist/commands/init.js +268 -218
  13. package/dist/commands/init.js.map +1 -1
  14. package/dist/commands/rotate.d.ts.map +1 -1
  15. package/dist/commands/rotate.js +67 -56
  16. package/dist/commands/rotate.js.map +1 -1
  17. package/dist/components/agent-avatar.d.ts +28 -0
  18. package/dist/components/agent-avatar.d.ts.map +1 -0
  19. package/dist/components/agent-avatar.js +98 -0
  20. package/dist/components/agent-avatar.js.map +1 -0
  21. package/dist/components/agent-card.d.ts +14 -0
  22. package/dist/components/agent-card.d.ts.map +1 -0
  23. package/dist/components/agent-card.js +170 -0
  24. package/dist/components/agent-card.js.map +1 -0
  25. package/dist/components/agent-table.d.ts +20 -0
  26. package/dist/components/agent-table.d.ts.map +1 -0
  27. package/dist/components/agent-table.js +195 -0
  28. package/dist/components/agent-table.js.map +1 -0
  29. package/dist/components/box.d.ts +14 -0
  30. package/dist/components/box.d.ts.map +1 -0
  31. package/dist/components/box.js +222 -0
  32. package/dist/components/box.js.map +1 -0
  33. package/dist/components/index.d.ts +16 -0
  34. package/dist/components/index.d.ts.map +1 -0
  35. package/dist/components/index.js +17 -0
  36. package/dist/components/index.js.map +1 -0
  37. package/dist/components/messages.d.ts +62 -0
  38. package/dist/components/messages.d.ts.map +1 -0
  39. package/dist/components/messages.js +146 -0
  40. package/dist/components/messages.js.map +1 -0
  41. package/dist/components/types.d.ts +51 -0
  42. package/dist/components/types.d.ts.map +1 -0
  43. package/dist/components/types.js +5 -0
  44. package/dist/components/types.js.map +1 -0
  45. package/dist/components/welcome.d.ts +38 -0
  46. package/dist/components/welcome.d.ts.map +1 -0
  47. package/dist/components/welcome.js +149 -0
  48. package/dist/components/welcome.js.map +1 -0
  49. package/dist/effects/cli-integration.js +3 -3
  50. package/dist/effects/cli-integration.js.map +1 -1
  51. package/dist/effects/index.d.ts +9 -12
  52. package/dist/effects/index.d.ts.map +1 -1
  53. package/dist/effects/index.js +69 -34
  54. package/dist/effects/index.js.map +1 -1
  55. package/dist/index.d.ts +1 -1
  56. package/dist/index.js +12 -19
  57. package/dist/utils/env-manager.d.ts +69 -5
  58. package/dist/utils/env-manager.d.ts.map +1 -1
  59. package/dist/utils/env-manager.js +381 -56
  60. package/dist/utils/env-manager.js.map +1 -1
  61. package/dist/utils/prompts.d.ts +1 -0
  62. package/dist/utils/prompts.d.ts.map +1 -1
  63. package/dist/utils/prompts.js +15 -0
  64. package/dist/utils/prompts.js.map +1 -1
  65. package/dist/utils/screen-manager.d.ts +10 -0
  66. package/dist/utils/screen-manager.d.ts.map +1 -0
  67. package/dist/utils/screen-manager.js +50 -0
  68. package/dist/utils/screen-manager.js.map +1 -0
  69. package/dist/utils/validation.d.ts +92 -0
  70. package/dist/utils/validation.d.ts.map +1 -0
  71. package/dist/utils/validation.js +106 -0
  72. package/dist/utils/validation.js.map +1 -0
  73. package/package.json +27 -9
  74. package/dist/commands/cli-experience-demo-simple.d.ts +0 -14
  75. package/dist/commands/cli-experience-demo-simple.d.ts.map +0 -1
  76. package/dist/commands/cli-experience-demo-simple.js +0 -119
  77. package/dist/commands/cli-experience-demo-simple.js.map +0 -1
  78. package/dist/commands/cli-experience-demo.d.ts +0 -14
  79. package/dist/commands/cli-experience-demo.d.ts.map +0 -1
  80. package/dist/commands/cli-experience-demo.js +0 -172
  81. package/dist/commands/cli-experience-demo.js.map +0 -1
  82. package/dist/commands/effects-demo.d.ts +0 -10
  83. package/dist/commands/effects-demo.d.ts.map +0 -1
  84. package/dist/commands/effects-demo.js +0 -292
  85. package/dist/commands/effects-demo.js.map +0 -1
  86. package/dist/dev.d.ts +0 -7
  87. package/dist/dev.d.ts.map +0 -1
  88. package/dist/dev.js +0 -9
  89. package/dist/dev.js.map +0 -1
  90. package/dist/effects/__tests__/effects.test.d.ts +0 -5
  91. package/dist/effects/__tests__/effects.test.d.ts.map +0 -1
  92. package/dist/effects/__tests__/effects.test.js +0 -206
  93. package/dist/effects/__tests__/effects.test.js.map +0 -1
  94. package/dist/effects/implementations/binary-path.d.ts +0 -88
  95. package/dist/effects/implementations/binary-path.d.ts.map +0 -1
  96. package/dist/effects/implementations/binary-path.js +0 -296
  97. package/dist/effects/implementations/binary-path.js.map +0 -1
  98. package/dist/effects/implementations/test.d.ts +0 -113
  99. package/dist/effects/implementations/test.d.ts.map +0 -1
  100. package/dist/effects/implementations/test.js +0 -552
  101. package/dist/effects/implementations/test.js.map +0 -1
  102. package/dist/effects/template/effect-template.d.ts +0 -97
  103. package/dist/effects/template/effect-template.d.ts.map +0 -1
  104. package/dist/effects/template/effect-template.js +0 -208
  105. package/dist/effects/template/effect-template.js.map +0 -1
  106. package/dist/index.d.ts.map +0 -1
  107. package/dist/index.js.map +0 -1
@@ -1,12 +1,15 @@
1
- import { enableMCPIdentity } from "@kya-os/mcp-i";
1
+ import { enableMCPIdentityCLI, } from "@kya-os/mcp-i/cli-internal";
2
2
  import chalk from "chalk";
3
3
  import ora from "ora";
4
4
  import { detectPlatform, getPlatformSpecificConfig, } from "../utils/platform-detector.js";
5
5
  import { EnvManager } from "../utils/env-manager.js";
6
- import { promptForInit, showSuccess, showError, showWarning, } from "../utils/prompts.js";
6
+ import { promptForInit, showError, showWarning, confirmMcpVariableReplacement, } from "../utils/prompts.js";
7
7
  import { existsSync } from "fs";
8
8
  import { join } from "path";
9
9
  import { cliEffects } from "../effects/cli-integration.js";
10
+ import { createAgentTable, createClaimTable, createWelcomeBanner, createGradientBox, createSuccessBox, } from "../components/index.js";
11
+ import { showScreen } from "../utils/screen-manager.js";
12
+ import { validateInput, initOptionsSchema } from "../utils/validation.js";
10
13
  async function checkRegistryHealth(verbose = false) {
11
14
  const healthSpinner = ora("Checking registry status...").start();
12
15
  try {
@@ -68,15 +71,46 @@ async function checkRegistryHealth(verbose = false) {
68
71
  async function sleep(ms) {
69
72
  return new Promise((resolve) => setTimeout(resolve, ms));
70
73
  }
71
- async function attemptRegistrationWithRetry(config, verbose = false, maxRetries = 3) {
74
+ async function attemptRegistrationWithRetry(config, verbose = false, maxRetries = 3, onProgress) {
72
75
  const baseDelay = 2000; // Start with 2 seconds
73
76
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
74
77
  const isLastAttempt = attempt === maxRetries;
75
- const spinner = ora(`Registering agent with knowthat.ai... (attempt ${attempt}/${maxRetries})`).start();
78
+ const spinner = ora(`Connecting to KYA-OS network... (attempt ${attempt}/${maxRetries})`).start();
76
79
  try {
77
- const identity = await enableMCPIdentity(config);
78
- spinner.succeed("Creating Agent ID");
79
- return { success: true, identity };
80
+ const result = await enableMCPIdentityCLI({
81
+ ...config,
82
+ onProgress: async (event) => {
83
+ // Update spinner based on progress
84
+ switch (event.stage) {
85
+ case "checking_existing":
86
+ spinner.text = "Checking for existing identity...";
87
+ break;
88
+ case "generating_keys":
89
+ spinner.text = "Generating cryptographic keys...";
90
+ break;
91
+ case "registering":
92
+ spinner.text = "Registering with KYA-OS network...";
93
+ break;
94
+ case "saving":
95
+ spinner.text = "Saving identity...";
96
+ break;
97
+ case "complete":
98
+ spinner.succeed("Agent registered successfully!");
99
+ break;
100
+ }
101
+ // Call the provided callback if any
102
+ if (onProgress) {
103
+ await onProgress(event);
104
+ }
105
+ },
106
+ });
107
+ // The mcp-i package now handles async registration internally
108
+ // We just get the final result
109
+ return {
110
+ success: true,
111
+ identity: result.identity,
112
+ metadata: result.metadata,
113
+ };
80
114
  }
81
115
  catch (error) {
82
116
  spinner.fail(`Registration attempt ${attempt} failed`);
@@ -225,6 +259,17 @@ function handleRegistrationError(_error, errorInfo, verbose, isFinalAttempt) {
225
259
  }
226
260
  export async function init(options) {
227
261
  try {
262
+ // Validate options
263
+ const validatedOptions = validateInput(initOptionsSchema, options, "init options");
264
+ // Show welcome banner
265
+ try {
266
+ const banner = await createWelcomeBanner("KYA-OS");
267
+ console.log(banner);
268
+ }
269
+ catch (err) {
270
+ // Fallback if figlet fails
271
+ console.log(chalk.cyan.bold("\n🚀 MCP-I Initialization\n"));
272
+ }
228
273
  // Detect platform
229
274
  const platformInfo = detectPlatform();
230
275
  console.log(chalk.cyan("\n🔍 Detected environment:"));
@@ -237,21 +282,21 @@ export async function init(options) {
237
282
  const envManager = new EnvManager();
238
283
  const existingIdentityFile = existsSync(join(process.cwd(), ".mcp-identity.json"));
239
284
  const existingEnvVars = envManager.getFromProcess();
240
- if ((existingIdentityFile || existingEnvVars.MCP_IDENTITY_DID) &&
241
- !options.force) {
285
+ if ((existingIdentityFile || existingEnvVars.MCP_IDENTITY_AGENT_DID) &&
286
+ !validatedOptions.force) {
242
287
  showWarning("MCP-I is already configured in this project.");
243
288
  console.log("Use --force to reconfigure.");
244
289
  // Show current configuration
245
- if (existingEnvVars.MCP_IDENTITY_DID) {
246
- console.log(`\nCurrent DID: ${chalk.green(existingEnvVars.MCP_IDENTITY_DID)}`);
290
+ if (existingEnvVars.MCP_IDENTITY_AGENT_DID) {
291
+ console.log(`\nCurrent DID: ${chalk.green(existingEnvVars.MCP_IDENTITY_AGENT_DID)}`);
247
292
  }
248
293
  return;
249
294
  }
250
295
  // Prompt for configuration
251
296
  const answers = await promptForInit({
252
- name: options.name,
253
- description: options.description,
254
- repository: options.repository,
297
+ name: validatedOptions.name,
298
+ description: validatedOptions.description,
299
+ repository: validatedOptions.repository,
255
300
  });
256
301
  // Determine directories configuration
257
302
  let directories;
@@ -268,9 +313,9 @@ export async function init(options) {
268
313
  const platformConfig = getPlatformSpecificConfig(platformInfo.platform);
269
314
  let identity;
270
315
  let envVars = null;
271
- if (!options.skipRegistration && answers.confirmRegistration) {
316
+ if (!validatedOptions.skipRegistration && answers.confirmRegistration) {
272
317
  // Check registry health first
273
- const healthCheck = await checkRegistryHealth(options.verbose);
318
+ const healthCheck = await checkRegistryHealth(validatedOptions.verbose);
274
319
  if (!healthCheck.available && !healthCheck.shouldProceed) {
275
320
  console.log("\nYou can still create the configuration files and register later.");
276
321
  answers.confirmEnvCreation = await promptForInit({
@@ -278,239 +323,244 @@ export async function init(options) {
278
323
  }).then((a) => a.confirmEnvCreation);
279
324
  }
280
325
  else {
281
- // Register agent with retry logic
282
- const registrationResult = await attemptRegistrationWithRetry({
283
- name: answers.name,
284
- description: answers.description,
285
- repository: answers.repository,
286
- directories: directories,
287
- storage: platformConfig.storage,
288
- transport: platformConfig.transport,
289
- mode: "production",
290
- logLevel: "silent",
291
- }, options.verbose);
326
+ // Register agent with retry logic and enhanced error handling
327
+ let registrationResult;
328
+ try {
329
+ registrationResult = await attemptRegistrationWithRetry({
330
+ name: answers.name,
331
+ description: answers.description,
332
+ repository: answers.repository,
333
+ directories: directories,
334
+ storage: platformConfig.storage,
335
+ transport: platformConfig.transport,
336
+ mode: "production",
337
+ logLevel: "silent",
338
+ }, validatedOptions.verbose, 3, // maxRetries
339
+ async (event) => {
340
+ // Handle progress events for spinner updates
341
+ // The blackhole effect will be shown after successful registration
342
+ });
343
+ }
344
+ catch (registrationError) {
345
+ // Enhanced error handling for common scenarios
346
+ if (registrationError.message?.includes("already exists") ||
347
+ registrationError.message?.includes("name taken") ||
348
+ registrationError.response?.status === 409) {
349
+ showError("Agent name already exists in the registry.");
350
+ console.log(chalk.yellow("\n🔍 This usually means:"));
351
+ console.log(" 1. You previously registered this agent name");
352
+ console.log(" 2. Your .env file was deleted/missing");
353
+ console.log(" 3. Someone else is using this name\n");
354
+ console.log(chalk.cyan("💡 Solutions:"));
355
+ console.log(" 1. If this is YOUR agent, restore your .env file:");
356
+ console.log(` ${chalk.green('MCP_IDENTITY_AGENT_DID="did:web:knowthat.ai:agents:' +
357
+ answers.name +
358
+ '"')}`);
359
+ console.log(` ${chalk.green('MCP_IDENTITY_AGENT_PUBLIC_KEY="your-public-key"')}`);
360
+ console.log(` ${chalk.green('MCP_IDENTITY_AGENT_PRIVATE_KEY="your-private-key"')}`);
361
+ console.log("\n 2. Or choose a different agent name");
362
+ console.log(` 3. Or visit: ${chalk.blue("https://knowthat.ai/agents/claim")}\n`);
363
+ process.exit(1);
364
+ }
365
+ // For other errors, show them and continue with config creation option
366
+ showError(`Registration failed: ${registrationError.message}`);
367
+ console.log("\nYou can still create the configuration files and register later.");
368
+ answers.confirmEnvCreation = await promptForInit({
369
+ confirmEnvCreation: true,
370
+ }).then((a) => a.confirmEnvCreation);
371
+ registrationResult = { success: false };
372
+ }
292
373
  if (registrationResult.success && registrationResult.identity) {
293
374
  identity = registrationResult.identity;
375
+ const metadata = registrationResult.metadata;
294
376
  // Extract environment variables
295
377
  envVars = {
296
- MCP_IDENTITY_DID: identity.did,
297
- MCP_IDENTITY_PUBLIC_KEY: identity.publicKey,
298
- MCP_IDENTITY_PRIVATE_KEY: identity.privateKey || "",
378
+ MCP_IDENTITY_AGENT_DID: identity.did,
379
+ MCP_IDENTITY_AGENT_PUBLIC_KEY: identity.publicKey,
380
+ MCP_IDENTITY_AGENT_PRIVATE_KEY: identity.privateKey || "",
299
381
  MCP_IDENTITY_AGENT_ID: identity.agentId || "",
300
382
  MCP_IDENTITY_AGENT_SLUG: identity.agentSlug || "",
301
383
  };
302
- // Clear some space for the effect
303
- console.log("\n");
304
- // Show DID generation with Blackhole effect
305
- const didGenerationText = `🔐 ${chalk.bold("Generating Decentralized Identity")}\n` +
306
- `\n` +
307
- `DID: ${chalk.green(identity.did)}`;
308
- await cliEffects.showCustomEffect("blackhole", didGenerationText, {
309
- config: {
310
- duration: 5000, // Increased duration for smoother transition
311
- blackholeColor: "ffffff",
312
- starColors: [
313
- "ffcc0d",
314
- "ff7326",
315
- "ff194d",
316
- "bf2669",
317
- "702a8c",
318
- "049dbf",
319
- ],
320
- finalColor: "00ff00",
321
- useGradient: true,
322
- gradientDirection: "diagonal",
323
- blackholeSize: 0.3,
324
- },
325
- persistent: true, // Keep the DID visible after animation
326
- skipExitPrompt: true, // Don't show "Press any key to exit"
327
- });
328
- // Get claim URL if available
329
- let claimUrl = null;
330
- try {
331
- const result = await identity.requestEditAccess();
332
- claimUrl = result.claimUrl;
333
- }
334
- catch (error) {
335
- // Ignore errors - claim URL is optional
336
- }
337
- // Wait a moment for the effect to finish and let the user see the DID
338
- await new Promise(resolve => setTimeout(resolve, 2000));
339
- // Gentle fade by adding some spacing before clearing
340
- console.log("\n\n\n");
341
- await new Promise(resolve => setTimeout(resolve, 300));
342
- // Clear screen and show elegant agent identity card
343
- console.clear();
344
- // Display elegant agent identity card
345
- console.log("\n");
346
- console.log(chalk.cyan("╔═══════════════════════════════════════════════════════════════════════╗"));
347
- console.log(chalk.cyan("║") + chalk.bold.white(" 🤖 AGENT IDENTITY CREATED ") + chalk.cyan("║"));
348
- console.log(chalk.cyan("╠═══════════════════════════════════════════════════════════════════════╣"));
349
- console.log(chalk.cyan("║ ║"));
350
- console.log(chalk.cyan("║") + chalk.bold(" Agent Name: ") + chalk.yellow(answers.name.padEnd(57)) + chalk.cyan("║"));
351
- console.log(chalk.cyan("║") + chalk.bold(" Description: ") + chalk.gray((answers.description || "").substring(0, 56).padEnd(56)) + chalk.cyan("║"));
352
- if (answers.description && answers.description.length > 56) {
353
- console.log(chalk.cyan("║") + " " + chalk.gray(answers.description.substring(56, 112).padEnd(55)) + chalk.cyan("║"));
354
- }
355
- console.log(chalk.cyan("║ ║"));
356
- console.log(chalk.cyan("║") + chalk.bold(" DID: ") + chalk.green(identity.did.substring(0, 64).padEnd(64)) + chalk.cyan("║"));
357
- if (identity.did.length > 64) {
358
- console.log(chalk.cyan("║") + " " + chalk.green(identity.did.substring(64).padEnd(63)) + chalk.cyan("║"));
384
+ // Show blackhole effect for successful registrations
385
+ if (validatedOptions.verbose) {
386
+ console.log(chalk.gray(`[DEBUG] metadata.isNewIdentity: ${metadata?.isNewIdentity}`));
387
+ console.log(chalk.gray(`[DEBUG] Full metadata: ${JSON.stringify(metadata)}`));
359
388
  }
360
- console.log(chalk.cyan("║ ║"));
361
- console.log(chalk.cyan("║") + chalk.bold(" Profile: ") + chalk.blue(`https://knowthat.ai/agents/${envVars.MCP_IDENTITY_AGENT_SLUG}`.padEnd(60)) + chalk.cyan("║"));
362
- console.log(chalk.cyan("║ ║"));
363
- if (claimUrl) {
364
- console.log(chalk.cyan("╠═══════════════════════════════════════════════════════════════════════╣"));
365
- console.log(chalk.cyan("║ ║"));
366
- console.log(chalk.cyan("║") + chalk.bold.yellow(" 🎯 CLAIM YOUR AGENT NOW: ") + chalk.cyan("║"));
367
- console.log(chalk.cyan("║ ║"));
368
- // Break URL into chunks that fit within the box
369
- const maxUrlLength = 65; // Leave some padding
370
- const urlChunks = [];
371
- let remainingUrl = claimUrl;
372
- while (remainingUrl.length > 0) {
373
- if (remainingUrl.length <= maxUrlLength) {
374
- urlChunks.push(remainingUrl);
375
- break;
376
- }
377
- // Try to break at a good spot (& or %)
378
- let breakPoint = maxUrlLength;
379
- const lastAmpersand = remainingUrl.lastIndexOf('&', maxUrlLength);
380
- const lastPercent = remainingUrl.lastIndexOf('%', maxUrlLength);
381
- if (lastAmpersand > maxUrlLength * 0.7) {
382
- breakPoint = lastAmpersand + 1;
383
- }
384
- else if (lastPercent > maxUrlLength * 0.7) {
385
- breakPoint = lastPercent + 3; // Include %XX
386
- }
387
- urlChunks.push(remainingUrl.substring(0, breakPoint));
388
- remainingUrl = remainingUrl.substring(breakPoint);
389
- }
390
- // Display URL chunks
391
- urlChunks.forEach((chunk, index) => {
392
- const paddedChunk = chunk.padEnd(68);
393
- if (index === 0) {
394
- console.log(chalk.cyan("║") + " " + chalk.cyan.underline(paddedChunk) + " " + chalk.cyan("║"));
395
- }
396
- else {
397
- console.log(chalk.cyan("║") + " " + chalk.cyan.underline(paddedChunk.substring(0, 66)) + " " + chalk.cyan("║"));
398
- }
389
+ // Always show effect for successful registrations
390
+ const shouldShowEffect = true;
391
+ if (shouldShowEffect && metadata?.did) {
392
+ // Clear some space for the effect
393
+ console.log("\n");
394
+ // Show DID generation with Blackhole effect
395
+ const didGenerationText = `🔐 ${chalk.bold("Generating Decentralized Identity")}\n` +
396
+ `\n` +
397
+ `DID: ${chalk.green(metadata.did)}`;
398
+ await cliEffects.showCustomEffect("blackhole", didGenerationText, {
399
+ config: {
400
+ duration: 5000, // Increased duration for smoother transition
401
+ blackholeColor: "ffffff",
402
+ starColors: [
403
+ "ffcc0d",
404
+ "ff7326",
405
+ "ff194d",
406
+ "bf2669",
407
+ "702a8c",
408
+ "049dbf",
409
+ ],
410
+ finalColor: "00ff00",
411
+ useGradient: true,
412
+ gradientDirection: "diagonal",
413
+ blackholeSize: 0.3,
414
+ },
415
+ persistent: true, // Keep the DID visible after animation
416
+ skipExitPrompt: true, // Don't show "Press any key to exit"
399
417
  });
400
- console.log(chalk.cyan("║ ║"));
401
- console.log(chalk.cyan("║") + chalk.gray(" This link lets you manage your agent and add capabilities. ") + chalk.cyan("║"));
402
- console.log(chalk.cyan("║ ║"));
403
- }
404
- console.log(chalk.cyan("╠═══════════════════════════════════════════════════════════════════════╣"));
405
- console.log(chalk.cyan("║ ║"));
406
- console.log(chalk.cyan("║") + chalk.bold.green(" ✅ Agent successfully registered on the KYA-OS network ") + chalk.cyan("║"));
407
- console.log(chalk.cyan("║") + chalk.gray(" Your AI agent now has a verifiable decentralized identity ") + chalk.cyan("║"));
408
- console.log(chalk.cyan("║ ║"));
409
- console.log(chalk.cyan("╚═══════════════════════════════════════════════════════════════════════╝"));
410
- console.log("\n");
411
- // Interactive prompt
412
- if (claimUrl) {
413
- console.log(chalk.yellow(" Press ENTER to open claim URL in browser, or 'x' to skip and continue..."));
414
- // Wait for user input
415
- const keypress = await new Promise((resolve) => {
416
- import('readline').then((readline) => {
417
- readline.emitKeypressEvents(process.stdin);
418
- if (process.stdin.isTTY) {
419
- process.stdin.setRawMode(true);
420
- }
421
- const handleKeypress = (str, key) => {
422
- if (key && key.name === 'return') {
423
- resolve('enter');
424
- }
425
- else if (str === 'x' || str === 'X') {
426
- resolve('x');
427
- }
428
- };
429
- process.stdin.once('keypress', handleKeypress);
430
- process.stdin.resume();
418
+ // Wait a moment for the effect to finish and let the user see the DID
419
+ await new Promise((resolve) => setTimeout(resolve, 2000));
420
+ // 1. Claim Your Agent screen (FIRST)
421
+ if (metadata?.claimUrl) {
422
+ await showScreen(createClaimTable({ claimUrl: metadata.claimUrl }), {
423
+ requireInput: true,
424
+ clearBefore: true,
425
+ prompt: "Press Enter to continue...",
431
426
  });
432
- });
433
- if (process.stdin.isTTY) {
434
- process.stdin.setRawMode(false);
435
- }
436
- if (keypress === 'enter') {
437
- // Try to open URL in browser
438
- try {
439
- const open = (await import('open')).default;
440
- await open(claimUrl);
441
- console.log(chalk.green("\n ✓ Opening claim URL in your browser...\n"));
442
- }
443
- catch (err) {
444
- console.log(chalk.gray("\n Could not open browser. Please visit the URL manually.\n"));
445
- }
446
- }
447
- else {
448
- console.log(chalk.gray("\n You can claim your agent later using the URL above.\n"));
449
427
  }
450
- }
451
- else {
452
- // If no claim URL, just wait for any key
453
- console.log(chalk.gray(" Press any key to continue..."));
454
- await new Promise((resolve) => {
455
- process.stdin.once('data', () => resolve(undefined));
456
- process.stdin.resume();
428
+ // 2. Agent Identity Created screen (SECOND)
429
+ const agentTable = createAgentTable({
430
+ name: answers.name,
431
+ description: answers.description,
432
+ did: metadata?.did || envVars?.MCP_IDENTITY_AGENT_DID || "",
433
+ privateKey: envVars?.MCP_IDENTITY_AGENT_PRIVATE_KEY || "",
434
+ agentSlug: answers.name,
435
+ profileUrl: `https://knowthat.ai/agents/${answers.name}`,
436
+ });
437
+ await showScreen(agentTable, {
438
+ requireInput: true,
439
+ clearBefore: true,
440
+ prompt: "Press Enter to continue...",
457
441
  });
458
442
  }
459
443
  }
460
- else {
461
- console.log("\nYou can still create the configuration files and register later.");
462
- answers.confirmEnvCreation = await promptForInit({
463
- confirmEnvCreation: true,
464
- }).then((a) => a.confirmEnvCreation);
465
- }
466
444
  }
467
445
  }
468
446
  // Create environment files
469
447
  if (answers.confirmEnvCreation && envVars) {
470
448
  console.log(`\n📄 ${chalk.bold("Creating environment files...")}`);
471
449
  try {
472
- // Create actual env file
473
- const envFile = platformConfig.envFile;
474
- await envManager.createEnvFile(envFile, envVars, {
475
- force: options.force,
450
+ // Check for existing MCP variables in env files
451
+ const envFiles = envManager.scanEnvFiles();
452
+ let hasExistingMcpVars = false;
453
+ let existingDid = '';
454
+ for (const envFile of envFiles) {
455
+ if (envFile.exists && envFile.hasMcpIdentity && envFile.mcpVariables?.MCP_IDENTITY_AGENT_DID) {
456
+ hasExistingMcpVars = true;
457
+ existingDid = envFile.mcpVariables.MCP_IDENTITY_AGENT_DID;
458
+ break;
459
+ }
460
+ }
461
+ // If existing MCP variables found and not forcing, prompt for confirmation
462
+ if (hasExistingMcpVars && !validatedOptions.force) {
463
+ const shouldReplace = await confirmMcpVariableReplacement(existingDid);
464
+ if (!shouldReplace) {
465
+ console.log(chalk.yellow('\n⚠ Skipping environment file update.'));
466
+ console.log(' Your existing MCP identity has been preserved.');
467
+ return;
468
+ }
469
+ }
470
+ // Use smart insertion with best practices
471
+ const result = await envManager.smartInsertMcpVariables(envVars, {
472
+ force: validatedOptions.force,
476
473
  });
477
- console.log(` ✓ Created ${chalk.green(envFile)}`);
478
- // Create example file
479
- const exampleFile = `${envFile}.example`;
480
- await envManager.createEnvFile(exampleFile, envVars, { example: true });
481
- console.log(` ✓ Created ${chalk.green(exampleFile)}`);
482
- // Check gitignore
483
- const { missing } = envManager.checkGitignore([
484
- envFile,
485
- ".mcp-identity.json",
486
- ]);
487
- if (missing.length > 0) {
488
- envManager.addToGitignore(missing);
489
- console.log(` ✓ Added to ${chalk.green(".gitignore")}: ${missing.join(", ")}`);
474
+ if (result.success) {
475
+ // Show operation result
476
+ const operation = result.operation === "created"
477
+ ? "Created"
478
+ : result.operation === "updated"
479
+ ? "Updated"
480
+ : "Replaced variables in";
481
+ console.log(` ✓ ${operation} ${chalk.green(result.targetFile)}`);
482
+ // Show warnings if any
483
+ if (result.warnings.length > 0) {
484
+ result.warnings.forEach((warning) => {
485
+ console.log(` ${chalk.yellow("⚠")} ${warning}`);
486
+ });
487
+ }
488
+ // Show conflicts if any
489
+ if (result.conflicts && result.conflicts.length > 0) {
490
+ console.log(` ${chalk.yellow("⚠")} Found conflicting values in other files:`);
491
+ result.conflicts.forEach((conflict) => {
492
+ console.log(` ${conflict.file}: ${conflict.variable}="${conflict.value.substring(0, 20)}..."`);
493
+ });
494
+ console.log(` ${chalk.cyan("ℹ")} Using ${result.targetFile} as authoritative source`);
495
+ }
496
+ // Check gitignore
497
+ const filesToIgnore = [
498
+ result.targetFile,
499
+ ".mcp-identity.json",
500
+ // Also add common .env files to gitignore
501
+ ".env",
502
+ ".env.local",
503
+ ".env.development",
504
+ ".env.dev",
505
+ ];
506
+ const { missing } = envManager.checkGitignore(filesToIgnore);
507
+ if (missing.length > 0) {
508
+ envManager.addToGitignore(missing);
509
+ console.log(` ✓ Added to ${chalk.green(".gitignore")}: ${missing.join(", ")}`);
510
+ }
511
+ }
512
+ else {
513
+ showError(`Environment file setup failed: ${result.warnings.join(", ")}`);
490
514
  }
491
515
  }
492
516
  catch (error) {
493
517
  showError(`Failed to create environment files: ${error.message}`);
494
518
  }
495
519
  }
496
- // Show next steps
497
- console.log(`\n📋 ${chalk.bold("Next Steps:")}`);
498
- console.log("\n1. Install the MCP-I package:");
499
- console.log(` ${chalk.cyan(`${platformInfo.packageManager} install @kya-os/mcp-i`)}`);
500
- console.log("\n2. Add to your code:");
501
- console.log(` ${chalk.cyan('import "@kya-os/mcp-i/auto"')}`);
520
+ // 3. Combined Environment Configuration & Success screen
521
+ const envConfigContent = [
522
+ "📝 Created files:",
523
+ "",
524
+ ".env.local (for local development)",
525
+ " • Added to .gitignore automatically",
526
+ ];
527
+ const combinedScreen = `${createGradientBox(envConfigContent, {
528
+ title: "Environment Configuration",
529
+ gradientStyle: "cool",
530
+ })}
531
+
532
+ ${createSuccessBox("MCP-I initialization complete!", "Your AI agent now has a verifiable decentralized identity on the KYA-OS network.")}`;
533
+ await showScreen(combinedScreen, {
534
+ requireInput: true,
535
+ clearBefore: true,
536
+ prompt: "Press Enter to continue...",
537
+ });
538
+ // 4. Integration Guide (no rainbow colors)
539
+ const integrationContent = [
540
+ "📋 Next Steps:",
541
+ "",
542
+ "1. Install the MCP-I package:",
543
+ ` ${chalk.cyan(`${platformInfo.packageManager} install @kya-os/mcp-i`)}`,
544
+ "",
545
+ "2. Add to your code:",
546
+ ` ${chalk.cyan('import "@kya-os/mcp-i/auto"')}`,
547
+ "",
548
+ ];
502
549
  if (platformInfo.platform === "vercel" ||
503
550
  platformInfo.platform === "nextjs") {
504
- console.log("\n3. For production deployment:");
505
- console.log(" - Go to Vercel Dashboard → Settings → Environment Variables");
506
- console.log(" - Add all MCP_IDENTITY_* variables from .env.local");
507
- console.log(` - Run: ${chalk.cyan("npx kya-os env copy")} to copy them to clipboard`);
551
+ integrationContent.push("3. For production deployment:", " • Go to Vercel Dashboard → Settings → Environment Variables", " • Add all MCP_IDENTITY_* variables from .env.local", ` • Run: ${chalk.cyan("npx kya-os env copy")} to copy them to clipboard`, "");
552
+ }
553
+ // Add platform-specific instructions if any
554
+ if (platformConfig.instructions.length > 0) {
555
+ integrationContent.push(`${chalk.bold("Platform-specific notes:")}`, ...platformConfig.instructions.map((instruction, i) => `${i + 1}. ${instruction}`));
508
556
  }
509
- console.log(`\n${chalk.bold("Platform-specific notes:")}`);
510
- platformConfig.instructions.forEach((instruction, i) => {
511
- console.log(`${i + 1}. ${instruction}`);
557
+ await showScreen(createGradientBox(integrationContent, {
558
+ title: "Integration Guide",
559
+ gradientStyle: "cool", // Changed from rainbow to cool
560
+ }), {
561
+ requireInput: false,
562
+ clearBefore: true,
512
563
  });
513
- showSuccess("MCP-I initialization complete!");
514
564
  }
515
565
  catch (error) {
516
566
  showError(error.message || "Initialization failed");