@kya-os/cli 1.0.0 → 1.2.0

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 (81) hide show
  1. package/dist/commands/build.d.ts +5 -0
  2. package/dist/commands/build.d.ts.map +1 -0
  3. package/dist/commands/build.js +173 -0
  4. package/dist/commands/build.js.map +1 -0
  5. package/dist/commands/check.d.ts.map +1 -1
  6. package/dist/commands/check.js +9 -31
  7. package/dist/commands/check.js.map +1 -1
  8. package/dist/commands/claim.d.ts +7 -1
  9. package/dist/commands/claim.d.ts.map +1 -1
  10. package/dist/commands/claim.js +196 -44
  11. package/dist/commands/claim.js.map +1 -1
  12. package/dist/commands/demo.d.ts +10 -0
  13. package/dist/commands/demo.d.ts.map +1 -0
  14. package/dist/commands/demo.js +584 -0
  15. package/dist/commands/demo.js.map +1 -0
  16. package/dist/commands/dev.d.ts +5 -0
  17. package/dist/commands/dev.d.ts.map +1 -0
  18. package/dist/commands/dev.js +111 -0
  19. package/dist/commands/dev.js.map +1 -0
  20. package/dist/commands/doctor.d.ts +11 -0
  21. package/dist/commands/doctor.d.ts.map +1 -0
  22. package/dist/commands/doctor.js +530 -0
  23. package/dist/commands/doctor.js.map +1 -0
  24. package/dist/commands/env.d.ts +1 -1
  25. package/dist/commands/env.d.ts.map +1 -1
  26. package/dist/commands/env.js +113 -15
  27. package/dist/commands/env.js.map +1 -1
  28. package/dist/commands/identity.d.ts +14 -0
  29. package/dist/commands/identity.d.ts.map +1 -0
  30. package/dist/commands/identity.js +204 -0
  31. package/dist/commands/identity.js.map +1 -0
  32. package/dist/commands/init.d.ts +6 -2
  33. package/dist/commands/init.d.ts.map +1 -1
  34. package/dist/commands/init.js +86 -670
  35. package/dist/commands/init.js.map +1 -1
  36. package/dist/commands/receipts.d.ts +11 -0
  37. package/dist/commands/receipts.d.ts.map +1 -0
  38. package/dist/commands/receipts.js +179 -0
  39. package/dist/commands/receipts.js.map +1 -0
  40. package/dist/commands/register.d.ts +15 -0
  41. package/dist/commands/register.d.ts.map +1 -0
  42. package/dist/commands/register.js +220 -0
  43. package/dist/commands/register.js.map +1 -0
  44. package/dist/commands/rotate.d.ts +7 -1
  45. package/dist/commands/rotate.d.ts.map +1 -1
  46. package/dist/commands/rotate.js +149 -109
  47. package/dist/commands/rotate.js.map +1 -1
  48. package/dist/commands/start.d.ts +5 -0
  49. package/dist/commands/start.d.ts.map +1 -0
  50. package/dist/commands/start.js +129 -0
  51. package/dist/commands/start.js.map +1 -0
  52. package/dist/commands/status.d.ts +9 -0
  53. package/dist/commands/status.d.ts.map +1 -0
  54. package/dist/commands/status.js +177 -0
  55. package/dist/commands/status.js.map +1 -0
  56. package/dist/commands/verify.d.ts +22 -0
  57. package/dist/commands/verify.d.ts.map +1 -0
  58. package/dist/commands/verify.js +491 -0
  59. package/dist/commands/verify.js.map +1 -0
  60. package/dist/components/claim-experience.d.ts +21 -0
  61. package/dist/components/claim-experience.d.ts.map +1 -0
  62. package/dist/components/claim-experience.js +138 -0
  63. package/dist/components/claim-experience.js.map +1 -0
  64. package/dist/index.js +154 -19
  65. package/dist/utils/env-manager.d.ts +6 -7
  66. package/dist/utils/env-manager.d.ts.map +1 -1
  67. package/dist/utils/env-manager.js +52 -40
  68. package/dist/utils/env-manager.js.map +1 -1
  69. package/dist/utils/identity-manager.d.ts +41 -0
  70. package/dist/utils/identity-manager.d.ts.map +1 -0
  71. package/dist/utils/identity-manager.js +159 -0
  72. package/dist/utils/identity-manager.js.map +1 -0
  73. package/dist/utils/kta-api.d.ts +67 -0
  74. package/dist/utils/kta-api.d.ts.map +1 -0
  75. package/dist/utils/kta-api.js +137 -0
  76. package/dist/utils/kta-api.js.map +1 -0
  77. package/package.json +8 -6
  78. package/dist/utils/validation.d.ts +0 -101
  79. package/dist/utils/validation.d.ts.map +0 -1
  80. package/dist/utils/validation.js +0 -109
  81. package/dist/utils/validation.js.map +0 -1
@@ -1,685 +1,101 @@
1
- import { enableMCPIdentityCLI, } from "@kya-os/mcp-i/cli-internal";
1
+ // TODO: Import from mcpi once package is fixed
2
+ // import { ensureIdentity, IdentityManager } from "mcpi";
2
3
  import chalk from "chalk";
3
4
  import ora from "ora";
4
5
  import { detectPlatform, getPlatformSpecificConfig, } from "../utils/platform-detector.js";
5
- import { EnvManager } from "../utils/env-manager.js";
6
- import { promptForInit, showError, showWarning, confirmMcpVariableReplacement, } from "../utils/prompts.js";
7
- import { existsSync } from "fs";
8
- import { join } from "path";
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";
13
- async function checkRegistryHealth(verbose = false, endpoint = "https://knowthat.ai") {
14
- const healthSpinner = ora(`Checking registry status at ${endpoint}...`).start();
6
+ /**
7
+ * Initialize XMCP-I in the current project
8
+ * Requirements: 2.7 (init command), 4.1-4.4 (identity management)
9
+ */
10
+ export async function init(options = {}) {
11
+ console.log(chalk.cyan("\nšŸš€ Initializing XMCP-I Agent\n"));
15
12
  try {
16
- // Check the new health endpoint
17
- const healthResponse = await fetch(`${endpoint}/api/agents/auto-register/health`, {
18
- method: "GET",
19
- headers: {
20
- "User-Agent": "kya-os-cli",
21
- },
22
- signal: AbortSignal.timeout(10000), // 10 second timeout
23
- });
24
- if (healthResponse.ok) {
25
- const healthData = await healthResponse.json();
26
- healthSpinner.succeed("Registry is operational");
27
- if (verbose && healthData) {
28
- console.log(chalk.gray(` Service status: ${healthData.status || "healthy"}`));
29
- }
30
- return { available: true, shouldProceed: true };
31
- }
32
- else if (healthResponse.status === 503) {
33
- healthSpinner.fail("Registry is temporarily unavailable (maintenance mode)");
34
- console.log(chalk.yellow("\nāš ļø The registry is undergoing maintenance."));
35
- console.log(chalk.yellow(" This usually takes 5-15 minutes."));
36
- console.log(chalk.yellow("\nšŸ”§ Options:"));
37
- console.log(" 1. Wait and try again in a few minutes");
38
- console.log(" 2. Register manually at: https://knowthat.ai/submit-agent");
39
- console.log(" 3. Create local config only (skip registration for now)");
40
- return { available: false, shouldProceed: false };
41
- }
42
- else {
43
- healthSpinner.warn("Registry status unknown, proceeding with caution...");
44
- return { available: false, shouldProceed: true };
45
- }
46
- }
47
- catch (error) {
48
- if (error.name === "TimeoutError") {
49
- healthSpinner.fail("Registry health check timed out");
50
- console.log(chalk.yellow("\nāš ļø Could not reach the registry (network timeout)."));
51
- console.log(chalk.yellow(" Check your internet connection."));
52
- }
53
- else if (error.code === "ENOTFOUND" || error.code === "ECONNREFUSED") {
54
- healthSpinner.fail("Registry is unreachable");
55
- console.log(chalk.yellow("\nāš ļø Cannot connect to knowthat.ai registry."));
56
- console.log(chalk.yellow(" The service may be down or you may have network issues."));
57
- }
58
- else {
59
- healthSpinner.warn("Could not check registry status, proceeding anyway...");
60
- if (verbose) {
61
- console.log(chalk.gray(` Error: ${error.message}`));
62
- }
63
- }
64
- console.log(chalk.yellow("\nšŸ”§ Alternatives:"));
65
- console.log(" 1. Try again in a few minutes");
66
- console.log(" 2. Register manually at: https://knowthat.ai/submit-agent");
67
- console.log(" 3. Create local config only (we'll attempt registration anyway)");
68
- return { available: false, shouldProceed: true };
69
- }
70
- }
71
- async function sleep(ms) {
72
- return new Promise((resolve) => setTimeout(resolve, ms));
73
- }
74
- async function attemptRegistrationWithRetry(config, verbose = false, maxRetries = 3, onProgress) {
75
- const baseDelay = 2000; // Start with 2 seconds
76
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
77
- const isLastAttempt = attempt === maxRetries;
78
- const spinner = ora(`Connecting to KYA-OS network... (attempt ${attempt}/${maxRetries})`).start();
13
+ // Detect platform if not specified
14
+ const platformInfo = options.platform
15
+ ? { platform: options.platform }
16
+ : detectPlatform();
17
+ const platform = typeof platformInfo === "string" ? platformInfo : platformInfo.platform;
18
+ const platformConfig = getPlatformSpecificConfig(platform);
19
+ if (options.verbose) {
20
+ console.log(chalk.gray(`Detected platform: ${platform}`));
21
+ console.log(chalk.gray(`Platform config:`, platformConfig));
22
+ }
23
+ console.log(chalk.bold("šŸ“‹ Agent Configuration"));
24
+ console.log(` Name: ${options.name || "Auto-generated"}`);
25
+ console.log(` Platform: ${platform}`);
26
+ if (options.description) {
27
+ console.log(` Description: ${options.description}`);
28
+ }
29
+ if (options.repository) {
30
+ console.log(` Repository: ${options.repository}`);
31
+ }
32
+ // Initialize identity using new identity management system
33
+ const spinner = ora("Setting up agent identity...").start();
79
34
  try {
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,
35
+ // TODO: Replace with actual identity management once mcpi is fixed
36
+ // const identityManager = new IdentityManager({
37
+ // environment: "development",
38
+ // privacyMode: false, // Single public DID default (Requirement 4.4)
39
+ // });
40
+ // const identity = await identityManager.ensureIdentity();
41
+ // Placeholder implementation
42
+ const identity = {
43
+ did: "did:web:localhost:3000:agents:placeholder",
44
+ keyId: "key-placeholder",
45
+ createdAt: new Date().toISOString(),
113
46
  };
114
- }
115
- catch (error) {
116
- spinner.fail(`Registration attempt ${attempt} failed`);
117
- const errorInfo = categorizeError(error, verbose);
118
- if (errorInfo.category === "CRITICAL" || isLastAttempt) {
119
- // Don't retry for critical errors, or if this was the last attempt
120
- handleRegistrationError(error, errorInfo, verbose, isLastAttempt);
121
- return { success: false, error };
47
+ spinner.succeed("Identity created successfully!");
48
+ console.log(`\n${chalk.bold("šŸ”‘ Identity Information:")}`);
49
+ console.log(` DID: ${chalk.gray(identity.did)}`);
50
+ console.log(` Key ID: ${chalk.gray(identity.keyId)}`);
51
+ console.log(` Created: ${chalk.gray(identity.createdAt)}`);
52
+ // Show success message
53
+ console.log(chalk.green("\nāœ… Agent initialized successfully!"));
54
+ // Show next steps
55
+ console.log(`\n${chalk.bold("šŸš€ Next Steps:")}`);
56
+ console.log(` ${chalk.gray("1. Start development:")} ${chalk.cyan("mcpi dev")}`);
57
+ if (!options.skipRegistration) {
58
+ console.log(` ${chalk.gray("2. Register agent:")} ${chalk.cyan("mcpi register")}`);
59
+ console.log(` ${chalk.gray("3. Check status:")} ${chalk.cyan("mcpi status")}`);
122
60
  }
123
- else if (errorInfo.category === "RETRYABLE") {
124
- // Calculate exponential backoff delay
125
- const delay = baseDelay * Math.pow(2, attempt - 1);
126
- console.log(chalk.yellow(` ${errorInfo.message}`));
127
- console.log(chalk.gray(` Retrying in ${delay / 1000} seconds...`));
128
- if (attempt < maxRetries) {
129
- await sleep(delay);
130
- }
131
- }
132
- else {
133
- // Unknown error - try once more but show the error
134
- if (verbose) {
135
- console.log(chalk.gray(` ${errorInfo.debugInfo}`));
136
- }
137
- console.log(chalk.yellow(` ${errorInfo.message}`));
138
- if (attempt < maxRetries) {
139
- console.log(chalk.gray(` Trying again...`));
140
- await sleep(baseDelay);
141
- }
142
- }
143
- }
144
- }
145
- return { success: false };
146
- }
147
- function categorizeError(error, verbose = false) {
148
- const errorMessage = error.message || "";
149
- const status = error.response?.status || error.status;
150
- const responseData = error.response?.data;
151
- // Build debug info
152
- let debugInfo = "";
153
- if (verbose) {
154
- debugInfo = `Error type: ${error.constructor.name}, Status: ${status}`;
155
- if (responseData) {
156
- debugInfo += `, Response: ${JSON.stringify(responseData, null, 2)}`;
157
- }
158
- }
159
- // Rate limiting
160
- if (status === 429 ||
161
- errorMessage.includes("429") ||
162
- errorMessage.includes("rate limit")) {
163
- return {
164
- category: "RETRYABLE",
165
- message: "Rate limit exceeded. The registry is busy.",
166
- debugInfo,
167
- };
168
- }
169
- // Service temporarily unavailable
170
- if (status === 503 || errorMessage.includes("503")) {
171
- return {
172
- category: "RETRYABLE",
173
- message: "Registry is temporarily unavailable (maintenance or overload).",
174
- debugInfo,
175
- };
176
- }
177
- // Server errors that might be transient
178
- if (status === 500 ||
179
- status === 502 ||
180
- errorMessage.includes("500") ||
181
- errorMessage.includes("502")) {
182
- return {
183
- category: "RETRYABLE",
184
- message: "Registry server error. This may be temporary.",
185
- debugInfo,
186
- };
187
- }
188
- // Timeout errors
189
- if (error.name === "TimeoutError" || errorMessage.includes("timeout")) {
190
- return {
191
- category: "RETRYABLE",
192
- message: "Request timed out. Network or server may be slow.",
193
- debugInfo,
194
- };
195
- }
196
- // Network errors
197
- if (error.code === "ENOTFOUND" ||
198
- error.code === "ECONNREFUSED" ||
199
- errorMessage.includes("ENOTFOUND")) {
200
- return {
201
- category: "RETRYABLE",
202
- message: "Cannot reach the registry. Check your internet connection.",
203
- debugInfo,
204
- };
205
- }
206
- // Client errors that shouldn't be retried
207
- if (status >= 400 && status < 500 && status !== 429) {
208
- return {
209
- category: "CRITICAL",
210
- message: `Registration was rejected by the registry (${status}).`,
211
- debugInfo,
212
- };
213
- }
214
- // MCP-I specific errors
215
- if (errorMessage.includes("Failed to auto-register agent")) {
216
- return {
217
- category: "CRITICAL",
218
- message: "The registry rejected the registration request.",
219
- debugInfo,
220
- };
221
- }
222
- // Unknown error
223
- return {
224
- category: "UNKNOWN",
225
- message: errorMessage || "An unexpected error occurred during registration.",
226
- debugInfo,
227
- };
228
- }
229
- function handleRegistrationError(_error, errorInfo, verbose, isFinalAttempt) {
230
- // Show main error message
231
- showError(errorInfo.message);
232
- // Show debug info if verbose
233
- if (verbose && errorInfo.debugInfo) {
234
- console.log(chalk.gray("\nDebug information:"));
235
- console.log(chalk.gray(errorInfo.debugInfo));
236
- }
237
- // Show context-specific help
238
- if (errorInfo.category === "CRITICAL") {
239
- console.log(chalk.yellow("\nšŸ”§ This error cannot be resolved by retrying."));
240
- console.log(chalk.yellow(" Possible solutions:"));
241
- console.log(" 1. Register manually at: https://knowthat.ai/submit-agent");
242
- console.log(" 2. Check if your agent name is already taken");
243
- console.log(" 3. Verify your repository URL is accessible");
244
- console.log(" 4. Contact support if the problem persists");
245
- }
246
- else if (isFinalAttempt) {
247
- console.log(chalk.yellow("\nšŸ”§ Registration failed after multiple attempts."));
248
- console.log(chalk.yellow(" Next steps:"));
249
- console.log(" 1. Wait 5-10 minutes and try again");
250
- console.log(" 2. Check knowthat.ai status page (if available)");
251
- console.log(" 3. Register manually at: https://knowthat.ai/submit-agent");
252
- console.log(" 4. Create local config only: npx kya-os init --skip-registration");
253
- }
254
- // Show alternative registration method
255
- console.log(chalk.cyan("\nšŸ“ Manual registration process:"));
256
- console.log(" 1. Visit: https://knowthat.ai/submit-agent");
257
- console.log(" 2. Fill in your agent details");
258
- console.log(" 3. Get your DID and run: npx kya-os claim <your-agent-id>");
259
- }
260
- async function pollForClaimStatus(agentName, did, endpoint = "https://knowthat.ai", options) {
261
- const spinner = ora({
262
- text: "Waiting for you to claim your agent...",
263
- color: "yellow",
264
- }).start();
265
- const maxAttempts = 60; // 5 minutes (60 * 5 seconds)
266
- let attempts = 0;
267
- // Add ability to skip polling with Ctrl+C
268
- let skipPolling = false;
269
- const handleInterrupt = () => {
270
- skipPolling = true;
271
- spinner.warn(chalk.yellow("ā­ļø Skipping claim check..."));
272
- };
273
- process.on('SIGINT', handleInterrupt);
274
- while (attempts < maxAttempts && !skipPolling) {
275
- try {
276
- // Check if agent is claimed by checking the agent's profile endpoint
277
- // The API uses the agent name as the slug in the URL
278
- const response = await fetch(`${endpoint}/api/agents/${encodeURIComponent(agentName)}`, {
279
- method: "GET",
280
- headers: {
281
- "User-Agent": "kya-os-cli",
282
- Accept: "application/json",
283
- },
284
- });
285
- if (response.ok) {
286
- const data = await response.json();
287
- // Debug logging
288
- if (process.env.DEBUG || options?.verbose) {
289
- console.log(chalk.gray(`\n[DEBUG] Agent status response:`));
290
- console.log(chalk.gray(JSON.stringify(data, null, 2)));
291
- }
292
- // Check various indicators that the agent has been claimed
293
- // The agent is claimed if:
294
- // 1. It has a userId (owner)
295
- // 2. Its status is 'active' (not 'draft')
296
- // 3. It's not marked as a draft
297
- if (data && (data.userId ||
298
- data.status === 'active' ||
299
- data.owner ||
300
- data.claimedAt ||
301
- (data.isDraft === false) ||
302
- (!data.hasOwnProperty('isDraft') && data.id) // Some agents don't have isDraft field
303
- )) {
304
- spinner.succeed(chalk.green("āœ… Agent claimed successfully!"));
305
- console.log(chalk.gray(`\n You can now manage your agent at:`));
306
- console.log(chalk.cyan(` ${endpoint.replace('http://localhost:3000', 'https://knowthat.ai')}/agents/${agentName}`));
307
- return true;
308
- }
309
- }
310
- else if (response.status === 404) {
311
- // 404 might mean the agent hasn't been indexed yet after creation
312
- // Continue polling
313
- }
314
- // Wait 5 seconds before next check
315
- await sleep(5000);
316
- attempts++;
317
- // Update spinner text with countdown
318
- const remainingTime = (maxAttempts - attempts) * 5;
319
- const minutes = Math.floor(remainingTime / 60);
320
- const seconds = remainingTime % 60;
321
- spinner.text = `Waiting for you to claim your agent... (${minutes}:${seconds
322
- .toString()
323
- .padStart(2, "0")} remaining)`;
61
+ console.log(` ${chalk.gray("4. Build for production:")} ${chalk.cyan("mcpi build")}`);
62
+ // TODO: Fix platform config types
63
+ // if (platformConfig.deployCommand) {
64
+ // console.log(
65
+ // ` ${chalk.gray("5. Deploy:")} ${chalk.cyan(platformConfig.deployCommand)}`
66
+ // );
67
+ // }
68
+ // Show platform-specific environment variables
69
+ // if (platformConfig.envVars && platformConfig.envVars.length > 0) {
70
+ // console.log(`\n${chalk.bold("šŸ”§ Environment Variables:")}`);
71
+ // console.log(` ${chalk.gray("For production deployment, set:")}`);
72
+ // platformConfig.envVars.forEach((envVar) => {
73
+ // console.log(` ${chalk.cyan(envVar)}`);
74
+ // });
75
+ // console.log(
76
+ // `\n ${chalk.gray("Use")} ${chalk.cyan("mcpi env show")} ${chalk.gray("for platform-specific names")}`
77
+ // );
78
+ // }
79
+ console.log(`\n${chalk.gray("Documentation:")} ${chalk.cyan("https://docs.kya-os.ai/xmcp-i")}`);
324
80
  }
325
81
  catch (error) {
326
- // Ignore network errors and keep polling
327
- }
328
- }
329
- // Clean up interrupt handler
330
- process.removeListener('SIGINT', handleInterrupt);
331
- if (skipPolling) {
332
- console.log(chalk.gray("\n You can complete the claim process later."));
333
- console.log(chalk.gray(" The claim URL remains valid."));
334
- return false;
335
- }
336
- spinner.warn(chalk.yellow("ā±ļø Claim check timed out"));
337
- console.log(chalk.gray("\n Don't worry! You can still claim your agent."));
338
- console.log(chalk.gray(" The claim URL remains valid."));
339
- console.log(chalk.cyan(`\n Visit: ${endpoint.replace('http://localhost:3000', 'https://knowthat.ai')}/agents/${agentName}`));
340
- return false;
341
- }
342
- export async function init(options) {
343
- try {
344
- // Validate options
345
- const validatedOptions = validateInput(initOptionsSchema, options, "init options");
346
- // Show welcome banner
347
- try {
348
- const banner = await createWelcomeBanner("KYA-OS");
349
- console.log(banner);
350
- }
351
- catch (err) {
352
- // Fallback if figlet fails
353
- console.log(chalk.cyan.bold("\nšŸš€ MCP-I Initialization\n"));
354
- }
355
- // Detect platform
356
- const platformInfo = detectPlatform();
357
- console.log(chalk.cyan("\nšŸ” Detected environment:"));
358
- console.log(` Platform: ${chalk.bold(platformInfo.platform)}`);
359
- if (platformInfo.framework) {
360
- console.log(` Framework: ${chalk.bold(platformInfo.framework)}`);
361
- }
362
- console.log(` Package Manager: ${chalk.bold(platformInfo.packageManager)}`);
363
- // Check for existing configuration
364
- const envManager = new EnvManager();
365
- const existingIdentityFile = existsSync(join(process.cwd(), ".mcp-identity.json"));
366
- const existingEnvVars = envManager.getFromProcess();
367
- if ((existingIdentityFile || existingEnvVars.MCP_IDENTITY_AGENT_DID) &&
368
- !validatedOptions.force) {
369
- showWarning("MCP-I is already configured in this project.");
370
- console.log("Use --force to reconfigure.");
371
- // Show current configuration
372
- if (existingEnvVars.MCP_IDENTITY_AGENT_DID) {
373
- console.log(`\nCurrent DID: ${chalk.green(existingEnvVars.MCP_IDENTITY_AGENT_DID)}`);
374
- }
375
- return;
376
- }
377
- // Prompt for configuration
378
- const answers = await promptForInit({
379
- name: validatedOptions.name,
380
- description: validatedOptions.description,
381
- repository: validatedOptions.repository,
382
- });
383
- // Show blackhole animation immediately after repository URL input
384
- console.log("\n");
385
- const didGenerationText = `šŸ” "Generating Decentralized Identity"\n` +
386
- `\n` +
387
- `Creating cryptographic keys...`;
388
- await cliEffects.showCustomEffect("blackhole", didGenerationText, {
389
- config: {
390
- duration: 3000, // Shorter initial duration
391
- blackholeColor: "ffffff",
392
- starColors: [
393
- "ffcc0d",
394
- "ff7326",
395
- "ff194d",
396
- "bf2669",
397
- "702a8c",
398
- "049dbf",
399
- ],
400
- finalColor: "00ff00",
401
- useGradient: false,
402
- gradientDirection: "diagonal",
403
- blackholeSize: 0.3,
404
- },
405
- persistent: false,
406
- skipExitPrompt: true,
407
- });
408
- // Determine directories configuration
409
- let directories;
410
- if (answers.directories === "verified") {
411
- directories = "verified";
412
- }
413
- else if (answers.directories === "none") {
414
- directories = "none";
415
- }
416
- else {
417
- directories = answers.specificDirectories || [];
418
- }
419
- // Get platform-specific config
420
- const platformConfig = getPlatformSpecificConfig(platformInfo.platform);
421
- // Determine API endpoint
422
- const apiEndpoint = validatedOptions.endpoint ||
423
- (validatedOptions.local ? 'http://localhost:3000' : 'https://knowthat.ai');
424
- if (apiEndpoint !== 'https://knowthat.ai') {
425
- console.log(chalk.yellow(`\nāš ļø Using custom endpoint: ${apiEndpoint}`));
426
- }
427
- let identity;
428
- let envVars = null;
429
- if (!validatedOptions.skipRegistration && answers.confirmRegistration) {
430
- // Check registry health first
431
- const healthCheck = await checkRegistryHealth(validatedOptions.verbose, apiEndpoint);
432
- if (!healthCheck.available && !healthCheck.shouldProceed) {
433
- console.log("\nYou can still create the configuration files and register later.");
434
- answers.confirmEnvCreation = await promptForInit({
435
- confirmEnvCreation: true,
436
- }).then((a) => a.confirmEnvCreation);
437
- }
438
- else {
439
- // Register agent with retry logic and enhanced error handling
440
- let registrationResult;
441
- try {
442
- registrationResult = await attemptRegistrationWithRetry({
443
- name: answers.name,
444
- description: answers.description,
445
- repository: answers.repository,
446
- directories: directories,
447
- storage: platformConfig.storage,
448
- transport: platformConfig.transport,
449
- mode: "production",
450
- logLevel: "silent",
451
- apiEndpoint: apiEndpoint,
452
- registryEndpoint: "cli", // Use CLI endpoint for better CLI experience
453
- }, validatedOptions.verbose, 3, // maxRetries
454
- async (event) => {
455
- // Handle progress events for spinner updates
456
- // The blackhole effect will be shown after successful registration
457
- });
458
- }
459
- catch (registrationError) {
460
- // Enhanced error handling for common scenarios
461
- if (registrationError.message?.includes("already exists") ||
462
- registrationError.message?.includes("name taken") ||
463
- registrationError.response?.status === 409) {
464
- showError("Agent name already exists in the registry.");
465
- console.log(chalk.yellow("\nšŸ” This usually means:"));
466
- console.log(" 1. You previously registered this agent name");
467
- console.log(" 2. Your .env file was deleted/missing");
468
- console.log(" 3. Someone else is using this name\n");
469
- console.log(chalk.cyan("šŸ’” Solutions:"));
470
- console.log(" 1. If this is YOUR agent, restore your .env file:");
471
- console.log(` ${chalk.green('MCP_IDENTITY_AGENT_DID="did:web:knowthat.ai:agents:' +
472
- answers.name +
473
- '"')}`);
474
- console.log(` ${chalk.green('MCP_IDENTITY_AGENT_PUBLIC_KEY="your-public-key"')}`);
475
- console.log(` ${chalk.green('MCP_IDENTITY_AGENT_PRIVATE_KEY="your-private-key"')}`);
476
- console.log("\n 2. Or choose a different agent name");
477
- console.log(` 3. Or visit: ${chalk.blue("https://knowthat.ai/agents/claim")}\n`);
478
- process.exit(1);
479
- }
480
- // For other errors, show them and continue with config creation option
481
- showError(`Registration failed: ${registrationError.message}`);
482
- console.log("\nYou can still create the configuration files and register later.");
483
- answers.confirmEnvCreation = await promptForInit({
484
- confirmEnvCreation: true,
485
- }).then((a) => a.confirmEnvCreation);
486
- registrationResult = { success: false };
487
- }
488
- if (registrationResult.success && registrationResult.identity) {
489
- identity = registrationResult.identity;
490
- const metadata = registrationResult.metadata;
491
- // Extract environment variables
492
- envVars = {
493
- MCP_IDENTITY_AGENT_DID: identity.did,
494
- MCP_IDENTITY_AGENT_PUBLIC_KEY: identity.publicKey,
495
- MCP_IDENTITY_AGENT_PRIVATE_KEY: identity.privateKey || "",
496
- MCP_IDENTITY_AGENT_ID: identity.agentId || "",
497
- MCP_IDENTITY_AGENT_SLUG: identity.agentSlug || "",
498
- };
499
- // Show blackhole effect for successful registrations
500
- if (validatedOptions.verbose) {
501
- console.log(chalk.gray(`[DEBUG] metadata.isNewIdentity: ${metadata?.isNewIdentity}`));
502
- console.log(chalk.gray(`[DEBUG] Full metadata: ${JSON.stringify(metadata)}`));
503
- }
504
- // Show the actual DID now that we have it
505
- if (metadata?.did) {
506
- // Update the display with the actual DID
507
- console.log("\n");
508
- console.log(chalk.green(`āœ… Identity created: ${metadata.did}`));
509
- console.log();
510
- // 1. Claim Your Agent screen (FIRST)
511
- if (metadata?.claimUrl) {
512
- await showScreen(createClaimTable({ claimUrl: metadata.claimUrl }), {
513
- requireInput: true,
514
- clearBefore: true,
515
- prompt: "", // The table already has the prompt
516
- });
517
- // Dynamically import and open the claim URL in the browser
518
- try {
519
- const open = (await import("open")).default;
520
- await open(metadata.claimUrl);
521
- }
522
- catch (error) {
523
- console.log(chalk.yellow("\nāš ļø Could not open browser automatically"));
524
- console.log(chalk.cyan(` Please visit: ${metadata.claimUrl}`));
525
- }
526
- // Start polling for claim status (unless skipped)
527
- if (!validatedOptions.skipClaimCheck) {
528
- const claimed = await pollForClaimStatus(answers.name, metadata.did, apiEndpoint, { verbose: validatedOptions.verbose });
529
- }
530
- else {
531
- console.log(chalk.gray("\n Skipping claim check..."));
532
- console.log(chalk.gray(" You can claim your agent anytime at:"));
533
- console.log(chalk.cyan(` ${metadata.claimUrl}`));
534
- }
535
- // Clear screen after polling for clean transition
536
- console.clear();
537
- }
538
- // 2. Agent Identity Created screen (SECOND)
539
- const agentTable = createAgentTable({
540
- name: answers.name,
541
- description: answers.description,
542
- did: metadata?.did || envVars?.MCP_IDENTITY_AGENT_DID || "",
543
- privateKey: envVars?.MCP_IDENTITY_AGENT_PRIVATE_KEY || "",
544
- agentSlug: answers.name,
545
- profileUrl: `https://knowthat.ai/agents/${answers.name}`,
546
- });
547
- await showScreen(agentTable, {
548
- requireInput: true,
549
- clearBefore: true,
550
- prompt: "Press Enter to continue...",
551
- });
552
- }
553
- }
554
- }
555
- }
556
- // Create environment files
557
- if (answers.confirmEnvCreation && envVars) {
558
- console.log(`\nšŸ“„ ${chalk.bold("Creating environment files...")}`);
559
- try {
560
- // Check for existing MCP variables in env files
561
- const envFiles = envManager.scanEnvFiles();
562
- let hasExistingMcpVars = false;
563
- let existingDid = "";
564
- for (const envFile of envFiles) {
565
- if (envFile.exists &&
566
- envFile.hasMcpIdentity &&
567
- envFile.mcpVariables?.MCP_IDENTITY_AGENT_DID) {
568
- hasExistingMcpVars = true;
569
- existingDid = envFile.mcpVariables.MCP_IDENTITY_AGENT_DID;
570
- break;
571
- }
572
- }
573
- // If existing MCP variables found and not forcing, prompt for confirmation
574
- if (hasExistingMcpVars && !validatedOptions.force) {
575
- const shouldReplace = await confirmMcpVariableReplacement(existingDid);
576
- if (!shouldReplace) {
577
- console.log(chalk.yellow("\n⚠ Skipping environment file update."));
578
- console.log(" Your existing MCP identity has been preserved.");
579
- return;
580
- }
581
- }
582
- // Use smart insertion with best practices
583
- const result = await envManager.smartInsertMcpVariables(envVars, {
584
- force: validatedOptions.force,
585
- });
586
- if (result.success) {
587
- // Show operation result
588
- const operation = result.operation === "created"
589
- ? "Created"
590
- : result.operation === "updated"
591
- ? "Updated"
592
- : "Replaced variables in";
593
- console.log(` āœ“ ${operation} ${chalk.green(result.targetFile)}`);
594
- // Show warnings if any
595
- if (result.warnings.length > 0) {
596
- result.warnings.forEach((warning) => {
597
- console.log(` ${chalk.yellow("⚠")} ${warning}`);
598
- });
599
- }
600
- // Show conflicts if any
601
- if (result.conflicts && result.conflicts.length > 0) {
602
- console.log(` ${chalk.yellow("⚠")} Found conflicting values in other files:`);
603
- result.conflicts.forEach((conflict) => {
604
- console.log(` ${conflict.file}: ${conflict.variable}="${conflict.value.substring(0, 20)}..."`);
605
- });
606
- console.log(` ${chalk.cyan("ℹ")} Using ${result.targetFile} as authoritative source`);
607
- }
608
- // Check gitignore
609
- const filesToIgnore = [
610
- result.targetFile,
611
- ".mcp-identity.json",
612
- // Also add common .env files to gitignore
613
- ".env",
614
- ".env.local",
615
- ".env.development",
616
- ".env.dev",
617
- ];
618
- const { missing } = envManager.checkGitignore(filesToIgnore);
619
- if (missing.length > 0) {
620
- envManager.addToGitignore(missing);
621
- console.log(` āœ“ Added to ${chalk.green(".gitignore")}: ${missing.join(", ")}`);
622
- }
623
- }
624
- else {
625
- showError(`Environment file setup failed: ${result.warnings.join(", ")}`);
626
- }
627
- }
628
- catch (error) {
629
- showError(`Failed to create environment files: ${error.message}`);
630
- }
631
- }
632
- // 3. Combined Environment Configuration & Success screen
633
- const envConfigContent = [
634
- "šŸ“ Created files:",
635
- "",
636
- " • .env.local (for local development)",
637
- " • Added to .gitignore automatically",
638
- ];
639
- const combinedScreen = `${createGradientBox(envConfigContent, {
640
- title: "Environment Configuration",
641
- gradientStyle: "cool",
642
- })}
643
-
644
- ${createSuccessBox("MCP-I initialization complete!", "Your AI agent now has a verifiable decentralized identity on the KYA-OS network.")}`;
645
- await showScreen(combinedScreen, {
646
- requireInput: true,
647
- clearBefore: true,
648
- prompt: "Press Enter to continue...",
649
- });
650
- // 4. Integration Guide (no rainbow colors)
651
- const integrationContent = [
652
- "Next Steps: ",
653
- "",
654
- "1. Install the MCP-I package:",
655
- ` ${chalk.cyan(`${platformInfo.packageManager} install @kya-os/mcp-i`)}`,
656
- "",
657
- "2. Add to your code:",
658
- ` ${chalk.cyan('import "@kya-os/mcp-i/auto"')}`,
659
- "",
660
- ];
661
- if (platformInfo.platform === "vercel" ||
662
- platformInfo.platform === "nextjs") {
663
- 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`, "");
664
- }
665
- // Add platform-specific instructions if any
666
- if (platformConfig.instructions.length > 0) {
667
- integrationContent.push(`${chalk.bold("Platform-specific notes:")}`, ...platformConfig.instructions.map((instruction, i) => `${i + 1}. ${instruction}`));
82
+ spinner.fail("Failed to set up identity");
83
+ throw error;
668
84
  }
669
- await showScreen(createGradientBox(integrationContent, {
670
- title: "Integration Guide",
671
- gradientStyle: "cool", // Changed from rainbow to cool
672
- }), {
673
- requireInput: true,
674
- clearBefore: true,
675
- prompt: "Press Enter to exit...",
676
- });
677
- // Explicitly exit after showing the final screen
678
- process.exit(0);
679
85
  }
680
86
  catch (error) {
681
- showError(error.message || "Initialization failed");
682
- process.exit(1);
87
+ console.log(chalk.red("\nāŒ Initialization failed"));
88
+ console.log(chalk.red(` ${error.message}`));
89
+ if (options.verbose && error.stack) {
90
+ console.log(chalk.gray("\nStack trace:"));
91
+ console.log(chalk.gray(error.stack));
92
+ }
93
+ // Provide helpful guidance
94
+ console.log(`\n${chalk.gray("You can:")}`);
95
+ console.log(`${chalk.gray("• Try again with --verbose for more details")}`);
96
+ console.log(`${chalk.gray("• Check file permissions in current directory")}`);
97
+ console.log(`${chalk.gray("• Ensure you're in a valid project directory")}`);
98
+ process.exit(21); // XMCP_I_ENOIDENTITY
683
99
  }
684
100
  }
685
101
  //# sourceMappingURL=init.js.map