@kya-os/create-mcpi-app 1.7.38-canary.2 → 1.7.38

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 (67) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-test$colon$coverage.log +755 -0
  3. package/.turbo/turbo-test.log +200 -0
  4. package/dist/helpers/fetch-cloudflare-mcpi-template.d.ts.map +1 -1
  5. package/dist/helpers/fetch-cloudflare-mcpi-template.js +35 -914
  6. package/dist/helpers/fetch-cloudflare-mcpi-template.js.map +1 -1
  7. package/dist/utils/fetch-remote-config.d.ts.map +1 -1
  8. package/dist/utils/fetch-remote-config.js +2 -2
  9. package/dist/utils/fetch-remote-config.js.map +1 -1
  10. package/package/package.json +77 -0
  11. package/package.json +1 -1
  12. package/ARCHITECTURE_ANALYSIS.md +0 -392
  13. package/CHANGELOG.md +0 -372
  14. package/DEPRECATION_WARNINGS_ANALYSIS.md +0 -192
  15. package/IMPLEMENTATION_SUMMARY.md +0 -108
  16. package/REMEDIATION_PLAN.md +0 -99
  17. package/dist/.tsbuildinfo +0 -1
  18. package/scripts/prepare-pack.js +0 -47
  19. package/scripts/validate-no-workspace.js +0 -79
  20. package/src/__tests__/cloudflare-template.test.ts +0 -490
  21. package/src/__tests__/helpers/fetch-cloudflare-mcpi-template.test.ts +0 -337
  22. package/src/__tests__/helpers/generate-config.test.ts +0 -312
  23. package/src/__tests__/helpers/generate-identity.test.ts +0 -271
  24. package/src/__tests__/helpers/install.test.ts +0 -370
  25. package/src/__tests__/helpers/validate-project-structure.test.ts +0 -467
  26. package/src/__tests__.bak/regression.test.ts +0 -434
  27. package/src/effects/index.ts +0 -80
  28. package/src/helpers/__tests__/config-builder.spec.ts +0 -231
  29. package/src/helpers/apply-identity-preset.ts +0 -209
  30. package/src/helpers/config-builder.ts +0 -165
  31. package/src/helpers/copy-template.ts +0 -11
  32. package/src/helpers/create.ts +0 -239
  33. package/src/helpers/fetch-cloudflare-mcpi-template.ts +0 -2404
  34. package/src/helpers/fetch-cloudflare-template.ts +0 -361
  35. package/src/helpers/fetch-mcpi-template.ts +0 -236
  36. package/src/helpers/fetch-xmcp-template.ts +0 -153
  37. package/src/helpers/generate-config.ts +0 -118
  38. package/src/helpers/generate-identity.ts +0 -163
  39. package/src/helpers/identity-manager.ts +0 -186
  40. package/src/helpers/install.ts +0 -79
  41. package/src/helpers/rename.ts +0 -17
  42. package/src/helpers/validate-project-structure.ts +0 -127
  43. package/src/index.ts +0 -520
  44. package/src/utils/__tests__/fetch-remote-config.test.ts +0 -271
  45. package/src/utils/check-node.ts +0 -17
  46. package/src/utils/fetch-remote-config.ts +0 -179
  47. package/src/utils/is-folder-empty.ts +0 -60
  48. package/src/utils/validate-project-name.ts +0 -132
  49. package/test-cloudflare/README.md +0 -164
  50. package/test-cloudflare/package.json +0 -28
  51. package/test-cloudflare/src/index.ts +0 -341
  52. package/test-cloudflare/src/tools/greet.ts +0 -19
  53. package/test-cloudflare/tests/cache-invalidation.test.ts +0 -410
  54. package/test-cloudflare/tests/cors-security.test.ts +0 -349
  55. package/test-cloudflare/tests/delegation.test.ts +0 -335
  56. package/test-cloudflare/tests/do-routing.test.ts +0 -314
  57. package/test-cloudflare/tests/integration.test.ts +0 -205
  58. package/test-cloudflare/tests/session-management.test.ts +0 -359
  59. package/test-cloudflare/tsconfig.json +0 -16
  60. package/test-cloudflare/vitest.config.ts +0 -9
  61. package/test-cloudflare/wrangler.toml +0 -37
  62. package/test-node/README.md +0 -44
  63. package/test-node/package.json +0 -23
  64. package/test-node/src/tools/greet.ts +0 -25
  65. package/test-node/xmcp.config.ts +0 -20
  66. package/tsconfig.json +0 -26
  67. package/vitest.config.ts +0 -14
@@ -1,17 +0,0 @@
1
- import fs from "fs-extra";
2
- import path from "path";
3
-
4
- export function renameFiles(projectPath: string): void {
5
- const filesToRename = [
6
- { from: "_gitignore", to: ".gitignore" },
7
- ];
8
-
9
- filesToRename.forEach(({ from, to }) => {
10
- const fromPath = path.join(projectPath, from);
11
- const toPath = path.join(projectPath, to);
12
-
13
- if (fs.existsSync(fromPath)) {
14
- fs.renameSync(fromPath, toPath);
15
- }
16
- });
17
- }
@@ -1,127 +0,0 @@
1
- import fs from "fs-extra";
2
- import path from "path";
3
- import chalk from "chalk";
4
-
5
- interface ProjectStructureValidation {
6
- valid: boolean;
7
- issues: string[];
8
- }
9
-
10
- /**
11
- * Validate that the generated project structure meets requirements
12
- */
13
- export function validateProjectStructure(
14
- projectPath: string,
15
- identityEnabled: boolean
16
- ): ProjectStructureValidation {
17
- const issues: string[] = [];
18
-
19
- // Check package.json scripts
20
- const packageJsonPath = path.join(projectPath, "package.json");
21
- if (fs.existsSync(packageJsonPath)) {
22
- const packageJson = fs.readJsonSync(packageJsonPath);
23
- const scripts = packageJson.scripts || {};
24
- const scriptCount = Object.keys(scripts).length;
25
-
26
- if (identityEnabled) {
27
- // Should have exactly 8 scripts for identity-enabled projects
28
- if (scriptCount !== 8) {
29
- issues.push(
30
- `Expected exactly 8 scripts for identity project, found ${scriptCount}`
31
- );
32
- }
33
-
34
- const requiredScripts = [
35
- "dev",
36
- "build",
37
- "start",
38
- "init",
39
- "register",
40
- "keys:rotate",
41
- "identity:clean",
42
- "status",
43
- ];
44
-
45
- for (const script of requiredScripts) {
46
- if (!scripts[script]) {
47
- issues.push(`Missing required script: ${script}`);
48
- }
49
- }
50
- } else {
51
- // Should have exactly 3 scripts for vanilla XMCP projects
52
- if (scriptCount !== 3) {
53
- issues.push(
54
- `Expected exactly 3 scripts for vanilla project, found ${scriptCount}`
55
- );
56
- }
57
-
58
- const requiredScripts = ["dev", "build", "start"];
59
- for (const script of requiredScripts) {
60
- if (!scripts[script]) {
61
- issues.push(`Missing required script: ${script}`);
62
- }
63
- }
64
- }
65
- } else {
66
- issues.push("package.json not found");
67
- }
68
-
69
- // Check required files exist (based on actual XMCP upstream structure)
70
- const requiredFiles = [
71
- "src/tools/greet.ts", // XMCP creates greet.ts, not hello.ts
72
- ".gitignore",
73
- "xmcp.config.ts",
74
- ];
75
-
76
- for (const file of requiredFiles) {
77
- if (!fs.existsSync(path.join(projectPath, file))) {
78
- issues.push(`Missing required file: ${file}`);
79
- }
80
- }
81
-
82
- // Check .gitignore includes .mcpi/ for identity projects
83
- if (identityEnabled) {
84
- const gitignorePath = path.join(projectPath, ".gitignore");
85
- if (fs.existsSync(gitignorePath)) {
86
- const gitignoreContent = fs.readFileSync(gitignorePath, "utf8");
87
- if (!gitignoreContent.includes(".mcpi/")) {
88
- issues.push(".gitignore should include .mcpi/ directory");
89
- }
90
- }
91
- }
92
-
93
- return {
94
- valid: issues.length === 0,
95
- issues,
96
- };
97
- }
98
-
99
- /**
100
- * Ensure lockfile is written and not mutated post-generation
101
- */
102
- export function ensureLockfile(
103
- projectPath: string,
104
- packageManager: string
105
- ): void {
106
- const lockfiles = {
107
- npm: "package-lock.json",
108
- yarn: "yarn.lock",
109
- pnpm: "pnpm-lock.yaml",
110
- };
111
-
112
- const lockfileName = lockfiles[packageManager as keyof typeof lockfiles];
113
- if (!lockfileName) {
114
- console.warn(chalk.yellow(`Unknown package manager: ${packageManager}`));
115
- return;
116
- }
117
-
118
- const lockfilePath = path.join(projectPath, lockfileName);
119
-
120
- // The lockfile should be created during npm install
121
- // We just validate it exists after installation
122
- if (fs.existsSync(lockfilePath)) {
123
- console.log(chalk.green(`✅ Lockfile created: ${lockfileName}`));
124
- } else {
125
- console.warn(chalk.yellow(`⚠️ Lockfile not found: ${lockfileName}`));
126
- }
127
- }
package/src/index.ts DELETED
@@ -1,520 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import path from "path";
4
- import fs from "fs-extra";
5
- import chalk from "chalk";
6
- import { Command } from "commander";
7
- import inquirer from "inquirer";
8
- import ora from "ora";
9
- import { fileURLToPath } from "url";
10
- import { checkNodeVersion } from "./utils/check-node.js";
11
- import { createProject } from "./helpers/create.js";
12
- import { isFolderEmpty } from "./utils/is-folder-empty.js";
13
- import { createKYAOSBanner } from "./effects/index.js";
14
- import {
15
- validateProjectName,
16
- validateDirectoryAvailability,
17
- } from "./utils/validate-project-name.js";
18
- import {
19
- resetIdentity,
20
- regenerateIdentity,
21
- } from "./helpers/identity-manager.js";
22
-
23
- checkNodeVersion();
24
-
25
- const __filename = fileURLToPath(import.meta.url);
26
- const __dirname = path.dirname(__filename);
27
-
28
- const packageJson = JSON.parse(
29
- fs.readFileSync(path.join(__dirname, "../package.json"), "utf8")
30
- );
31
-
32
- const program = new Command()
33
- .name("create-mcpi-app")
34
- .description("Create a new MCP-I application with identity features built-in")
35
- .version(
36
- packageJson.version,
37
- "-v, --version",
38
- "Output the current version of create-mcpi-app."
39
- )
40
- .argument("[directory]")
41
- .usage("[directory] [options]")
42
- .helpOption("-h, --help", "Display help message.")
43
- .option("-y, --yes", "Skip confirmation prompt", false)
44
- .option("--use-npm", "Use npm as package manager (default: use npm)")
45
- .option("--use-yarn", "Use yarn as package manager")
46
- .option("--use-pnpm", "Use pnpm as package manager")
47
- .option("--skip-install", "Skip installing dependencies", false)
48
- .option("--skip-identity", "Skip identity generation", false)
49
- .option("--no-identity", "Create plain MCP project without identity features")
50
- .option("--vercel", "Add Vercel support for deployment", false)
51
- .option("--http", "Enable HTTP transport", false)
52
- .option("--stdio", "Enable STDIO transport", false)
53
- .option("--local", "Use local mcp-i dependency", false)
54
- .option("--mcpi-version <version>", "Specify MCP-I version (e.g., ^1.2.7)")
55
- .option("--no-animation", "Skip the black hole animation", false)
56
- .option("--fast", "Use shorter animation duration", false)
57
- .option(
58
- "--platform <name>",
59
- "Deployment platform: node (default), cloudflare",
60
- "node"
61
- )
62
- .option("--mode <name>", "Server mode: mcp-i (default), verifier", "mcp-i")
63
- .option("--template <name>", "[DEPRECATED] Use --platform and --mode instead")
64
- .option("--apikey <key>", "AgentShield API key for Cloudflare deployment")
65
- .option(
66
- "--project <id>",
67
- "AgentShield Project ID for Cloudflare deployment (enables project-scoped tool protection)"
68
- )
69
- .action(async (projectDir, options) => {
70
- console.log(chalk.bold(`\ncreate-mcpi-app@${packageJson.version}`));
71
-
72
- // Show KYA-OS banner
73
- const banner = await createKYAOSBanner();
74
- console.log(chalk.cyan(banner));
75
- console.log(chalk.dim("\nEnhanced with identity features by MCP-I\n"));
76
-
77
- // If project directory wasn't specified, ask for it
78
- if (!projectDir) {
79
- const answers = await inquirer.prompt([
80
- {
81
- type: "input",
82
- name: "projectDir",
83
- message: "What is your project named?",
84
- default: "my-mcpi-app",
85
- },
86
- ]);
87
- projectDir = answers.projectDir;
88
- }
89
-
90
- // Normalize project directory
91
- const resolvedProjectPath = path.resolve(process.cwd(), projectDir);
92
- const projectName = path.basename(resolvedProjectPath);
93
-
94
- // Validate project name
95
- const nameValidation = validateProjectName(projectName);
96
- if (!nameValidation.valid) {
97
- console.error(chalk.red("Invalid project name:"));
98
- for (const issue of nameValidation.issues) {
99
- console.error(chalk.red(` - ${issue}`));
100
- }
101
- process.exit(1);
102
- }
103
-
104
- // Validate directory availability
105
- const dirValidation = validateDirectoryAvailability(resolvedProjectPath);
106
- if (!dirValidation.valid) {
107
- console.error(chalk.red("Directory validation failed:"));
108
- for (const issue of dirValidation.issues) {
109
- console.error(chalk.red(` - ${issue}`));
110
- }
111
- process.exit(1);
112
- }
113
-
114
- let packageManager = "npm";
115
- let useLocalXmcp = options.local;
116
- let mcpiVersion = options.mcpiVersion;
117
- let deployToVercel = options.vercel;
118
- let skipInstall = options.skipInstall;
119
- let skipIdentity = options.skipIdentity || !options.identity;
120
- let transports = ["http"];
121
- let agentName = projectName;
122
- let agentDescription = "MCP-I server with identity features";
123
- let agentRepository = "";
124
-
125
- // Handle platform and mode flags (with backward compatibility for --template)
126
- let platform = options.platform || "node";
127
- let mode = options.mode || "mcp-i";
128
-
129
- // Backward compatibility: map --template to --platform/--mode
130
- if (options.template) {
131
- console.log(
132
- chalk.yellow(
133
- "⚠️ --template is deprecated. Use --platform and --mode instead."
134
- )
135
- );
136
- if (options.template === "cloudflare") {
137
- platform = "cloudflare";
138
- mode = "verifier";
139
- } else if (options.template === "default") {
140
- platform = "node";
141
- mode = "mcp-i";
142
- }
143
- }
144
-
145
- // Validate platform and mode combinations
146
- const validCombinations = [
147
- { platform: "node", mode: "mcp-i" },
148
- { platform: "cloudflare", mode: "mcp-i" },
149
- { platform: "cloudflare", mode: "verifier" },
150
- ];
151
-
152
- const isValid = validCombinations.some(
153
- (combo) => combo.platform === platform && combo.mode === mode
154
- );
155
-
156
- if (!isValid) {
157
- console.error(
158
- chalk.red(`\n❌ Invalid platform/mode combination: ${platform}/${mode}`)
159
- );
160
- console.log(chalk.yellow("\nSupported combinations:"));
161
- console.log(chalk.cyan(" - node + mcp-i (default)"));
162
- console.log(chalk.cyan(" - cloudflare + mcp-i"));
163
- console.log(chalk.cyan(" - cloudflare + verifier"));
164
- process.exit(1);
165
- }
166
-
167
- // Handle transport selection from CLI options
168
- if (options.http || options.stdio) {
169
- transports = [];
170
- if (options.http) transports.push("http");
171
- if (options.stdio) transports.push("stdio");
172
- }
173
-
174
- if (!options.yes) {
175
- // Package manager selection
176
- if (options.useYarn) packageManager = "yarn";
177
- if (options.usePnpm) packageManager = "pnpm";
178
-
179
- if (!options.useYarn && !options.usePnpm && !options.useNpm) {
180
- const pmAnswers = await inquirer.prompt([
181
- {
182
- type: "list",
183
- name: "packageManager",
184
- message: "Select a package manager:",
185
- choices: [
186
- { name: "npm", value: "npm" },
187
- { name: "yarn", value: "yarn" },
188
- { name: "pnpm", value: "pnpm" },
189
- ],
190
- default: "npm",
191
- },
192
- ]);
193
- packageManager = pmAnswers.packageManager;
194
- }
195
-
196
- // Transport selection (skip if already specified via CLI options)
197
- if (!options.http && !options.stdio) {
198
- const transportAnswers = await inquirer.prompt([
199
- {
200
- type: "checkbox",
201
- name: "transports",
202
- message: "Select the transports you want to use:",
203
- choices: [
204
- {
205
- name: "HTTP (runs on a server)",
206
- value: "http",
207
- checked: true,
208
- },
209
- {
210
- name: "STDIO (runs on the user's machine)",
211
- value: "stdio",
212
- checked: false,
213
- },
214
- ],
215
- validate: (input) => {
216
- if (input.length === 0) {
217
- return "You must select at least one transport.";
218
- }
219
- return true;
220
- },
221
- },
222
- ]);
223
- transports = transportAnswers.transports;
224
- }
225
-
226
- // Vercel deployment option (only for Node.js platform)
227
- if (
228
- !options.vercel &&
229
- transports.includes("http") &&
230
- platform === "node"
231
- ) {
232
- const vercelAnswers = await inquirer.prompt([
233
- {
234
- type: "confirm",
235
- name: "deployToVercel",
236
- message: "Add Vercel deployment support?",
237
- default: true,
238
- },
239
- ]);
240
- deployToVercel = vercelAnswers.deployToVercel;
241
- }
242
-
243
- // Agent information for identity generation
244
- if (!skipIdentity) {
245
- console.log(chalk.blue("\n🤖 Agent Configuration:"));
246
-
247
- const agentInfo = await inquirer.prompt([
248
- {
249
- type: "input",
250
- name: "name",
251
- message: "What's your agent name?",
252
- default: projectName,
253
- },
254
- {
255
- type: "input",
256
- name: "description",
257
- message: "Brief description of your agent:",
258
- default: "XMCP-I server with identity features",
259
- },
260
- {
261
- type: "input",
262
- name: "repository",
263
- message: "Repository URL (optional):",
264
- default: "",
265
- },
266
- ]);
267
-
268
- agentName = agentInfo.name;
269
- agentDescription = agentInfo.description;
270
- agentRepository = agentInfo.repository;
271
- }
272
-
273
- console.log();
274
- console.log(
275
- `Creating a new xmcp app in ${chalk.green(resolvedProjectPath)}.\n`
276
- );
277
-
278
- const { confirmed } = await inquirer.prompt([
279
- {
280
- type: "confirm",
281
- name: "confirmed",
282
- message: "Ok to continue?",
283
- default: true,
284
- },
285
- ]);
286
-
287
- if (!confirmed) {
288
- console.log(chalk.yellow("Aborting installation."));
289
- process.exit(0);
290
- }
291
- } else {
292
- // Use command-line options when --yes is provided
293
- if (options.useYarn) packageManager = "yarn";
294
- if (options.usePnpm) packageManager = "pnpm";
295
- }
296
-
297
- const spinner = ora(
298
- "Creating your xmcp-i app with identity features..."
299
- ).start();
300
-
301
- try {
302
- spinner.text = "Scaffolding project structure...";
303
-
304
- const result = await createProject({
305
- projectPath: resolvedProjectPath,
306
- projectName,
307
- packageManager,
308
- transports: transports,
309
- packageVersion: packageJson.version,
310
- useLocalXmcp,
311
- mcpiVersion,
312
- deployToVercel,
313
- skipInstall,
314
- agentName,
315
- agentDescription,
316
- agentRepository,
317
- skipIdentity,
318
- skipAnimation: options.noAnimation === false ? true : false, // Handle --no-animation flag
319
- fastAnimation: options.fast,
320
- spinner, // Pass spinner to stop it before animation
321
- platform, // Pass platform (node, cloudflare)
322
- mode, // Pass mode (mcp-i, verifier)
323
- template: options.template || "default", // Keep for backward compatibility
324
- apikey: options.apikey, // Pass AgentShield API key for Cloudflare
325
- projectId: options.project, // Pass AgentShield Project ID for Cloudflare
326
- });
327
-
328
- if (!result.success) {
329
- spinner.fail(chalk.red("Failed to create the project."));
330
- if (result.warnings) {
331
- for (const warning of result.warnings) {
332
- console.error(chalk.red(` ${warning}`));
333
- }
334
- }
335
- process.exit(1);
336
- }
337
-
338
- if (result.warnings && result.warnings.length > 0) {
339
- spinner.warn(chalk.yellow("Your xmcp-i app is ready with warnings"));
340
- for (const warning of result.warnings) {
341
- console.warn(chalk.yellow(` ⚠️ ${warning}`));
342
- }
343
- } else {
344
- spinner.succeed(chalk.green("Your xmcp-i app is ready"));
345
- }
346
-
347
- console.log();
348
- console.log("Next Steps:");
349
-
350
- // Show different instructions based on platform/mode
351
- if (platform === "cloudflare") {
352
- // Cloudflare Worker instructions (both verifier and mcp-i)
353
- console.log("1. Install dependencies:");
354
- if (resolvedProjectPath !== process.cwd()) {
355
- console.log(` cd ${chalk.cyan(projectDir)}`);
356
- }
357
- if (skipInstall) {
358
- if (packageManager === "yarn") {
359
- console.log(` ${chalk.cyan("yarn install")}`);
360
- } else if (packageManager === "pnpm") {
361
- console.log(` ${chalk.cyan("pnpm install")}`);
362
- } else {
363
- console.log(` ${chalk.cyan("npm install")}`);
364
- }
365
- }
366
- console.log();
367
- console.log("2. Create KV namespaces (creates both NONCE and PROOF):");
368
- console.log(
369
- ` ${chalk.cyan(`${packageManager === "npm" ? "npm run" : packageManager} kv:create`)}`
370
- );
371
- console.log(
372
- chalk.gray(
373
- " Copy both namespace IDs from output and update wrangler.toml"
374
- )
375
- );
376
- console.log();
377
- console.log("3. Test locally:");
378
- console.log(
379
- ` ${chalk.cyan(`${packageManager === "npm" ? "npm run" : packageManager} dev`)}`
380
- );
381
- console.log();
382
- console.log("4. Deploy to Cloudflare:");
383
- console.log(
384
- ` ${chalk.cyan("npx wrangler login")} ${chalk.gray("(first time only)")}`
385
- );
386
- console.log(
387
- ` ${chalk.cyan(`${packageManager === "npm" ? "npm run" : packageManager} deploy`)}`
388
- );
389
- } else {
390
- // Default MCP-I server instructions
391
- // Show agent management with claim URL first
392
- if (!skipIdentity) {
393
- console.log("Agent management:");
394
- console.log(" Follow the Claim URL above to claim your agent");
395
- if (resolvedProjectPath !== process.cwd()) {
396
- console.log(` cd ${chalk.cyan(projectDir)}`);
397
- }
398
- console.log(
399
- ` ${chalk.cyan(`${packageManager} run status`)} - Check agent status`
400
- );
401
- console.log(
402
- ` ${chalk.cyan(`${packageManager} run register`)} - Register with registry`
403
- );
404
- console.log();
405
- }
406
-
407
- console.log("Start agent:");
408
- if (resolvedProjectPath !== process.cwd()) {
409
- console.log(` cd ${chalk.cyan(projectDir)}`);
410
- }
411
-
412
- if (skipInstall) {
413
- if (packageManager === "yarn") {
414
- console.log(` ${chalk.cyan("yarn install")}`);
415
- } else if (packageManager === "pnpm") {
416
- console.log(` ${chalk.cyan("pnpm install")}`);
417
- } else {
418
- console.log(` ${chalk.cyan("npm install")}`);
419
- }
420
- }
421
-
422
- // Show appropriate command based on transport
423
- if (transports.includes("stdio")) {
424
- console.log(` ${chalk.cyan("npx xmcp build")}`);
425
- } else {
426
- // HTTP transport - show dev command
427
- if (packageManager === "yarn") {
428
- console.log(` ${chalk.cyan("yarn dev")}`);
429
- } else if (packageManager === "pnpm") {
430
- console.log(` ${chalk.cyan("pnpm dev")}`);
431
- } else {
432
- console.log(` ${chalk.cyan("npm run dev")}`);
433
- }
434
- }
435
-
436
- console.log();
437
- console.log("Manage identity:");
438
- if (resolvedProjectPath !== process.cwd()) {
439
- console.log(` cd ${chalk.cyan(projectDir)}`);
440
- }
441
-
442
- // Show identity management commands
443
- if (packageManager === "yarn") {
444
- console.log(
445
- ` ${chalk.cyan("yarn keys:rotate")} - Rotate cryptographic keys`
446
- );
447
- console.log(
448
- ` ${chalk.cyan("yarn identity:clean")} - Clean identity data`
449
- );
450
- } else if (packageManager === "pnpm") {
451
- console.log(
452
- ` ${chalk.cyan("pnpm keys:rotate")} - Rotate cryptographic keys`
453
- );
454
- console.log(
455
- ` ${chalk.cyan("pnpm identity:clean")} - Clean identity data`
456
- );
457
- } else {
458
- console.log(
459
- ` ${chalk.cyan("npm run keys:rotate")} - Rotate cryptographic keys`
460
- );
461
- console.log(
462
- ` ${chalk.cyan("npm run identity:clean")} - Clean identity data`
463
- );
464
- }
465
- }
466
-
467
- console.log();
468
-
469
- // Explicitly exit after successful completion
470
- process.exit(0);
471
- } catch (error) {
472
- spinner.fail(chalk.red("Failed to create the project."));
473
- console.error(error);
474
- process.exit(1);
475
- }
476
- });
477
-
478
- // Add subcommand for resetting identity
479
- program
480
- .command("reset-identity")
481
- .description("Reset the current project's identity (removes identity files)")
482
- .option(
483
- "-d, --dir <directory>",
484
- "Project directory (defaults to current directory)"
485
- )
486
- .action(async (options) => {
487
- try {
488
- const projectPath = options.dir
489
- ? path.resolve(process.cwd(), options.dir)
490
- : process.cwd();
491
- await resetIdentity(projectPath);
492
- } catch (error) {
493
- console.error(chalk.red("Failed to reset identity:"), error);
494
- process.exit(1);
495
- }
496
- });
497
-
498
- // Add subcommand for regenerating identity
499
- program
500
- .command("regenerate-identity")
501
- .description(
502
- "Regenerate the current project's identity (creates new DID and keys)"
503
- )
504
- .option(
505
- "-d, --dir <directory>",
506
- "Project directory (defaults to current directory)"
507
- )
508
- .action(async (options) => {
509
- try {
510
- const projectPath = options.dir
511
- ? path.resolve(process.cwd(), options.dir)
512
- : process.cwd();
513
- await regenerateIdentity(projectPath);
514
- } catch (error) {
515
- console.error(chalk.red("Failed to regenerate identity:"), error);
516
- process.exit(1);
517
- }
518
- });
519
-
520
- program.parse(process.argv);