@kya-os/create-mcpi-app 1.7.19 → 1.7.20

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 (71) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-test$colon$coverage.log +315 -0
  3. package/.turbo/turbo-test.log +95 -0
  4. package/CHANGELOG.md +372 -0
  5. package/IMPLEMENTATION_SUMMARY.md +108 -0
  6. package/REMEDIATION_PLAN.md +99 -0
  7. package/coverage/base.css +224 -0
  8. package/coverage/block-navigation.js +87 -0
  9. package/coverage/clover.xml +252 -0
  10. package/coverage/config-builder.ts.html +580 -0
  11. package/coverage/coverage-final.json +7 -0
  12. package/coverage/favicon.png +0 -0
  13. package/coverage/fetch-cloudflare-mcpi-template.ts.html +7006 -0
  14. package/coverage/generate-config.ts.html +436 -0
  15. package/coverage/generate-identity.ts.html +574 -0
  16. package/coverage/index.html +191 -0
  17. package/coverage/install.ts.html +322 -0
  18. package/coverage/prettify.css +1 -0
  19. package/coverage/prettify.js +2 -0
  20. package/coverage/sort-arrow-sprite.png +0 -0
  21. package/coverage/sorter.js +210 -0
  22. package/coverage/validate-project-structure.ts.html +466 -0
  23. package/package.json +14 -7
  24. package/scripts/prepare-pack.js +47 -0
  25. package/scripts/validate-no-workspace.js +79 -0
  26. package/src/__tests__/cloudflare-template.test.ts +488 -0
  27. package/src/__tests__/helpers/fetch-cloudflare-mcpi-template.test.ts +337 -0
  28. package/src/__tests__/helpers/generate-config.test.ts +312 -0
  29. package/src/__tests__/helpers/generate-identity.test.ts +271 -0
  30. package/src/__tests__/helpers/install.test.ts +362 -0
  31. package/src/__tests__/helpers/validate-project-structure.test.ts +467 -0
  32. package/src/__tests__.bak/regression.test.ts +434 -0
  33. package/src/effects/index.ts +80 -0
  34. package/src/helpers/__tests__/config-builder.spec.ts +231 -0
  35. package/src/helpers/apply-identity-preset.ts +209 -0
  36. package/src/helpers/config-builder.ts +165 -0
  37. package/src/helpers/copy-template.ts +11 -0
  38. package/src/helpers/create.ts +239 -0
  39. package/src/helpers/fetch-cloudflare-mcpi-template.ts +2311 -0
  40. package/src/helpers/fetch-cloudflare-template.ts +361 -0
  41. package/src/helpers/fetch-mcpi-template.ts +236 -0
  42. package/src/helpers/fetch-xmcp-template.ts +153 -0
  43. package/src/helpers/generate-config.ts +117 -0
  44. package/src/helpers/generate-identity.ts +163 -0
  45. package/src/helpers/identity-manager.ts +186 -0
  46. package/src/helpers/install.ts +79 -0
  47. package/src/helpers/rename.ts +17 -0
  48. package/src/helpers/validate-project-structure.ts +127 -0
  49. package/src/index.ts +480 -0
  50. package/src/utils/check-node.ts +17 -0
  51. package/src/utils/is-folder-empty.ts +60 -0
  52. package/src/utils/validate-project-name.ts +132 -0
  53. package/test-cloudflare/README.md +164 -0
  54. package/test-cloudflare/package.json +28 -0
  55. package/test-cloudflare/src/index.ts +340 -0
  56. package/test-cloudflare/src/tools/greet.ts +19 -0
  57. package/test-cloudflare/tests/cache-invalidation.test.ts +410 -0
  58. package/test-cloudflare/tests/cors-security.test.ts +349 -0
  59. package/test-cloudflare/tests/delegation.test.ts +335 -0
  60. package/test-cloudflare/tests/do-routing.test.ts +314 -0
  61. package/test-cloudflare/tests/integration.test.ts +205 -0
  62. package/test-cloudflare/tests/session-management.test.ts +359 -0
  63. package/test-cloudflare/tsconfig.json +22 -0
  64. package/test-cloudflare/vitest.config.ts +9 -0
  65. package/test-cloudflare/wrangler.toml +37 -0
  66. package/test-node/README.md +44 -0
  67. package/test-node/package.json +23 -0
  68. package/test-node/src/tools/greet.ts +25 -0
  69. package/test-node/xmcp.config.ts +20 -0
  70. package/tsconfig.json +26 -0
  71. package/vitest.config.ts +14 -0
@@ -0,0 +1,239 @@
1
+ import path from "path";
2
+ import fs from "fs-extra";
3
+ import { fileURLToPath } from "url";
4
+ import { fetchMCPITemplate } from "./fetch-mcpi-template.js";
5
+ import { fetchCloudflareTemplate } from "./fetch-cloudflare-template.js";
6
+ import { fetchCloudflareMcpiTemplate } from "./fetch-cloudflare-mcpi-template.js";
7
+ import { renameFiles } from "./rename.js";
8
+ import { install } from "./install.js";
9
+ import {
10
+ validateProjectStructure,
11
+ ensureLockfile,
12
+ } from "./validate-project-structure.js";
13
+ import { ScaffolderResult } from "@kya-os/contracts";
14
+ import chalk from "chalk";
15
+ import crypto from "crypto";
16
+
17
+ const __filename = fileURLToPath(import.meta.url);
18
+ const __dirname = path.dirname(__filename);
19
+
20
+ // Function to generate claim URL
21
+ function generateClaimUrl(did: string, privateKeyBase64: string): string {
22
+ try {
23
+ const timestamp = Date.now();
24
+ const message = `${did}:${timestamp}`;
25
+
26
+ const privateKeyBuffer = Buffer.from(privateKeyBase64, "base64");
27
+ const privateKeyBytes =
28
+ privateKeyBuffer.length === 64
29
+ ? privateKeyBuffer.subarray(0, 32)
30
+ : privateKeyBuffer;
31
+
32
+ const privateKey = crypto.createPrivateKey({
33
+ key: Buffer.concat([
34
+ Buffer.from("302e020100300506032b657004220420", "hex"),
35
+ privateKeyBytes,
36
+ ]),
37
+ format: "der",
38
+ type: "pkcs8",
39
+ });
40
+
41
+ const signature = crypto.sign(null, Buffer.from(message), privateKey);
42
+ const signatureBase64 = signature.toString("base64");
43
+
44
+ const params = new URLSearchParams({
45
+ did: did,
46
+ timestamp: timestamp.toString(),
47
+ signature: signatureBase64,
48
+ });
49
+
50
+ return `https://knowthat.ai/agents/claim?${params.toString()}`;
51
+ } catch (error) {
52
+ console.error("Error generating claim URL:", error);
53
+ return "";
54
+ }
55
+ }
56
+
57
+ interface CreateProjectOptions {
58
+ projectPath: string;
59
+ projectName: string;
60
+ packageManager: string;
61
+ transports: string[];
62
+ packageVersion: string;
63
+ useLocalXmcp?: boolean;
64
+ mcpiVersion?: string;
65
+ deployToVercel?: boolean;
66
+ skipInstall?: boolean;
67
+ agentName?: string;
68
+ agentDescription?: string;
69
+ agentRepository?: string;
70
+ skipIdentity?: boolean;
71
+ skipAnimation?: boolean;
72
+ fastAnimation?: boolean;
73
+ spinner?: any; // ora spinner instance
74
+ platform?: string; // Platform: 'node' or 'cloudflare'
75
+ mode?: string; // Mode: 'mcp-i' or 'verifier'
76
+ template?: string; // [DEPRECATED] Template type: 'default' or 'cloudflare'
77
+ apikey?: string; // AgentShield API key for Cloudflare deployment
78
+ projectId?: string; // AgentShield Project ID for Cloudflare deployment
79
+ }
80
+
81
+ /**
82
+ * Create necessary project directories
83
+ */
84
+ function createProjectDirectories(projectPath: string): void {
85
+ fs.ensureDirSync(path.join(projectPath, ".mcpi"));
86
+ }
87
+
88
+ /**
89
+ * Create a new MCP-I project with identity features
90
+ */
91
+ export async function createProject(
92
+ options: CreateProjectOptions
93
+ ): Promise<ScaffolderResult> {
94
+ const {
95
+ projectPath,
96
+ projectName,
97
+ packageManager,
98
+ transports,
99
+ packageVersion,
100
+ useLocalXmcp,
101
+ mcpiVersion,
102
+ deployToVercel,
103
+ skipInstall,
104
+ agentName = projectName,
105
+ agentDescription = "MCP-I server with identity features",
106
+ agentRepository = "",
107
+ skipIdentity = false,
108
+ skipAnimation = false,
109
+ fastAnimation = false,
110
+ platform = "node",
111
+ mode = "mcp-i",
112
+ template = "default",
113
+ apikey,
114
+ projectId,
115
+ } = options;
116
+
117
+ const warnings: string[] = [];
118
+ let resolvedMcpiVersion = mcpiVersion;
119
+
120
+ try {
121
+ // Ensure the project directory exists
122
+ fs.ensureDirSync(projectPath);
123
+
124
+ // Scaffold project based on platform/mode
125
+ console.log(chalk.blue("\nšŸ“ Scaffolding project..."));
126
+
127
+ if (platform === "cloudflare" && mode === "verifier") {
128
+ // Cloudflare Worker verifier template (standalone verifier)
129
+ await fetchCloudflareTemplate(projectPath, {
130
+ packageManager,
131
+ });
132
+ } else if (platform === "cloudflare" && mode === "mcp-i") {
133
+ // Cloudflare Worker MCP-I server template (NEW)
134
+ await fetchCloudflareMcpiTemplate(projectPath, {
135
+ packageManager,
136
+ projectName,
137
+ apikey,
138
+ projectId,
139
+ skipIdentity,
140
+ });
141
+ } else if (platform === "node" && mode === "mcp-i") {
142
+ // Node.js MCP-I server template (default)
143
+ await fetchMCPITemplate(projectPath, {
144
+ mcpiVersion,
145
+ packageManager,
146
+ skipIdentity,
147
+ });
148
+ } else {
149
+ throw new Error(`Unsupported platform/mode combination: ${platform}/${mode}`);
150
+ }
151
+
152
+ // Capture the resolved version for the result
153
+ const packageJsonPath = path.join(projectPath, "package.json");
154
+ if (fs.existsSync(packageJsonPath)) {
155
+ const packageJson = fs.readJsonSync(packageJsonPath);
156
+ // Try to extract version from dependencies
157
+ resolvedMcpiVersion =
158
+ packageJson.dependencies?.["@kya-os/mcp-i"] || mcpiVersion || "unknown";
159
+ }
160
+
161
+ // Rename special files (e.g., _gitignore to .gitignore)
162
+ renameFiles(projectPath);
163
+
164
+ // Add vercel.json if deployToVercel is true
165
+ if (deployToVercel) {
166
+ // Create a basic vercel.json for MCP-I deployment
167
+ const vercelConfig = {
168
+ functions: {
169
+ "src/server.ts": {
170
+ runtime: "@vercel/node@3",
171
+ },
172
+ },
173
+ rewrites: [
174
+ {
175
+ source: "/(.*)",
176
+ destination: "/src/server.ts",
177
+ },
178
+ ],
179
+ };
180
+
181
+ fs.writeJsonSync(path.join(projectPath, "vercel.json"), vercelConfig, {
182
+ spaces: 2,
183
+ });
184
+ }
185
+
186
+ // Create necessary project directories (skip for cloudflare templates)
187
+ const isCloudflare = platform === "cloudflare";
188
+ if (!isCloudflare) {
189
+ createProjectDirectories(projectPath);
190
+ }
191
+
192
+ // Install project dependencies
193
+ if (!skipInstall) {
194
+ install(projectPath, packageManager, packageVersion);
195
+
196
+ // Ensure lockfile is properly created
197
+ ensureLockfile(projectPath, packageManager);
198
+ }
199
+
200
+ // Validate project structure meets requirements (skip for cloudflare)
201
+ if (!isCloudflare) {
202
+ const validation = validateProjectStructure(projectPath, !skipIdentity);
203
+ if (!validation.valid) {
204
+ console.warn(chalk.yellow("āš ļø Project structure validation issues:"));
205
+ for (const issue of validation.issues) {
206
+ console.warn(chalk.yellow(` - ${issue}`));
207
+ warnings.push(...validation.issues);
208
+ }
209
+ }
210
+ }
211
+
212
+ // Identity setup is now handled by the CLI after scaffolding (not for cloudflare)
213
+ if (!skipIdentity && !isCloudflare) {
214
+ console.log(chalk.blue("\nšŸ” Identity setup will be handled by the CLI"));
215
+ console.log(
216
+ chalk.gray(" Run 'mcpi init' after scaffolding to set up identity")
217
+ );
218
+ }
219
+
220
+ return {
221
+ success: true,
222
+ projectPath,
223
+ xmcpVersion: resolvedMcpiVersion || "unknown",
224
+ identityEnabled: !skipIdentity,
225
+ warnings: warnings.length > 0 ? warnings : undefined,
226
+ };
227
+ } catch (error) {
228
+ console.error(chalk.red("Failed to create project:"), error);
229
+ return {
230
+ success: false,
231
+ projectPath,
232
+ xmcpVersion: resolvedMcpiVersion || "unknown",
233
+ identityEnabled: !skipIdentity,
234
+ warnings: [
235
+ `Project creation failed: ${error instanceof Error ? error.message : String(error)}`,
236
+ ],
237
+ };
238
+ }
239
+ }