@chimerai/cli 0.2.73

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 (129) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +293 -0
  3. package/dist/cli.d.ts +7 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +317 -0
  6. package/dist/commands/add.d.ts +11 -0
  7. package/dist/commands/add.d.ts.map +1 -0
  8. package/dist/commands/add.js +2126 -0
  9. package/dist/commands/create.d.ts +12 -0
  10. package/dist/commands/create.d.ts.map +1 -0
  11. package/dist/commands/create.js +1703 -0
  12. package/dist/commands/deploy.d.ts +11 -0
  13. package/dist/commands/deploy.d.ts.map +1 -0
  14. package/dist/commands/deploy.js +219 -0
  15. package/dist/commands/dev.d.ts +17 -0
  16. package/dist/commands/dev.d.ts.map +1 -0
  17. package/dist/commands/dev.js +206 -0
  18. package/dist/commands/doctor.d.ts +11 -0
  19. package/dist/commands/doctor.d.ts.map +1 -0
  20. package/dist/commands/doctor.js +728 -0
  21. package/dist/commands/generate.d.ts +19 -0
  22. package/dist/commands/generate.d.ts.map +1 -0
  23. package/dist/commands/generate.js +429 -0
  24. package/dist/commands/init.d.ts +11 -0
  25. package/dist/commands/init.d.ts.map +1 -0
  26. package/dist/commands/init.js +269 -0
  27. package/dist/commands/list.d.ts +12 -0
  28. package/dist/commands/list.d.ts.map +1 -0
  29. package/dist/commands/list.js +328 -0
  30. package/dist/commands/migrate.d.ts +14 -0
  31. package/dist/commands/migrate.d.ts.map +1 -0
  32. package/dist/commands/migrate.js +197 -0
  33. package/dist/commands/plugin.d.ts +10 -0
  34. package/dist/commands/plugin.d.ts.map +1 -0
  35. package/dist/commands/plugin.js +239 -0
  36. package/dist/commands/remove.d.ts +11 -0
  37. package/dist/commands/remove.d.ts.map +1 -0
  38. package/dist/commands/remove.js +472 -0
  39. package/dist/commands/secret.d.ts +12 -0
  40. package/dist/commands/secret.d.ts.map +1 -0
  41. package/dist/commands/secret.js +102 -0
  42. package/dist/commands/setup.d.ts +9 -0
  43. package/dist/commands/setup.d.ts.map +1 -0
  44. package/dist/commands/setup.js +788 -0
  45. package/dist/commands/update.d.ts +14 -0
  46. package/dist/commands/update.d.ts.map +1 -0
  47. package/dist/commands/update.js +211 -0
  48. package/dist/commands/use.d.ts +9 -0
  49. package/dist/commands/use.d.ts.map +1 -0
  50. package/dist/commands/use.js +51 -0
  51. package/dist/index.d.ts +22 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +45 -0
  54. package/dist/license.d.ts +55 -0
  55. package/dist/license.d.ts.map +1 -0
  56. package/dist/license.js +258 -0
  57. package/dist/scanner.d.ts +31 -0
  58. package/dist/scanner.d.ts.map +1 -0
  59. package/dist/scanner.js +113 -0
  60. package/dist/schema-manager.d.ts +26 -0
  61. package/dist/schema-manager.d.ts.map +1 -0
  62. package/dist/schema-manager.js +132 -0
  63. package/dist/templates/admin.d.ts +49 -0
  64. package/dist/templates/admin.d.ts.map +1 -0
  65. package/dist/templates/admin.js +1358 -0
  66. package/dist/templates/ai-routes.d.ts +17 -0
  67. package/dist/templates/ai-routes.d.ts.map +1 -0
  68. package/dist/templates/ai-routes.js +1130 -0
  69. package/dist/templates/ai-service-tools.d.ts +22 -0
  70. package/dist/templates/ai-service-tools.d.ts.map +1 -0
  71. package/dist/templates/ai-service-tools.js +1424 -0
  72. package/dist/templates/ai-service.d.ts +66 -0
  73. package/dist/templates/ai-service.d.ts.map +1 -0
  74. package/dist/templates/ai-service.js +2202 -0
  75. package/dist/templates/api-routes.d.ts +108 -0
  76. package/dist/templates/api-routes.d.ts.map +1 -0
  77. package/dist/templates/api-routes.js +1219 -0
  78. package/dist/templates/auth.d.ts +48 -0
  79. package/dist/templates/auth.d.ts.map +1 -0
  80. package/dist/templates/auth.js +381 -0
  81. package/dist/templates/billing.d.ts +44 -0
  82. package/dist/templates/billing.d.ts.map +1 -0
  83. package/dist/templates/billing.js +551 -0
  84. package/dist/templates/chat.d.ts +63 -0
  85. package/dist/templates/chat.d.ts.map +1 -0
  86. package/dist/templates/chat.js +1979 -0
  87. package/dist/templates/components.d.ts +22 -0
  88. package/dist/templates/components.d.ts.map +1 -0
  89. package/dist/templates/components.js +672 -0
  90. package/dist/templates/config.d.ts +6 -0
  91. package/dist/templates/config.d.ts.map +1 -0
  92. package/dist/templates/config.js +86 -0
  93. package/dist/templates/docker.d.ts +25 -0
  94. package/dist/templates/docker.d.ts.map +1 -0
  95. package/dist/templates/docker.js +165 -0
  96. package/dist/templates/gdpr.d.ts +16 -0
  97. package/dist/templates/gdpr.d.ts.map +1 -0
  98. package/dist/templates/gdpr.js +259 -0
  99. package/dist/templates/index.d.ts +77 -0
  100. package/dist/templates/index.d.ts.map +1 -0
  101. package/dist/templates/index.js +339 -0
  102. package/dist/templates/layout.d.ts +67 -0
  103. package/dist/templates/layout.d.ts.map +1 -0
  104. package/dist/templates/layout.js +670 -0
  105. package/dist/templates/mfa.d.ts +23 -0
  106. package/dist/templates/mfa.d.ts.map +1 -0
  107. package/dist/templates/mfa.js +353 -0
  108. package/dist/templates/middleware.d.ts +12 -0
  109. package/dist/templates/middleware.d.ts.map +1 -0
  110. package/dist/templates/middleware.js +116 -0
  111. package/dist/templates/prisma.d.ts +35 -0
  112. package/dist/templates/prisma.d.ts.map +1 -0
  113. package/dist/templates/prisma.js +724 -0
  114. package/dist/templates/provider-routes.d.ts +21 -0
  115. package/dist/templates/provider-routes.d.ts.map +1 -0
  116. package/dist/templates/provider-routes.js +1203 -0
  117. package/dist/templates/rag.d.ts +48 -0
  118. package/dist/templates/rag.d.ts.map +1 -0
  119. package/dist/templates/rag.js +532 -0
  120. package/dist/templates/widget.d.ts +64 -0
  121. package/dist/templates/widget.d.ts.map +1 -0
  122. package/dist/templates/widget.js +1360 -0
  123. package/dist/utils/provider-db.d.ts +63 -0
  124. package/dist/utils/provider-db.d.ts.map +1 -0
  125. package/dist/utils/provider-db.js +300 -0
  126. package/dist/utils.d.ts +78 -0
  127. package/dist/utils.d.ts.map +1 -0
  128. package/dist/utils.js +330 -0
  129. package/package.json +60 -0
@@ -0,0 +1,258 @@
1
+ "use strict";
2
+ /**
3
+ * ChimerAI License & Edition Management
4
+ *
5
+ * Drei Tiers: free < enterprise < enterprise-pro
6
+ * License keys werden via Lemon Squeezy ausgegeben und lokal gespeichert.
7
+ *
8
+ * Key-Präfixe (Konvention):
9
+ * ls_live_ent_... → Enterprise
10
+ * ls_live_entpro_... → Enterprise Pro
11
+ * chi_ent_... → Enterprise (interner Test-Key)
12
+ * chi_entpro_... → Enterprise Pro (interner Test-Key)
13
+ */
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.ENTERPRISE_PRO_COMPONENTS = exports.ENTERPRISE_COMPONENTS = exports.FREE_COMPONENTS = void 0;
19
+ exports.getRequiredEdition = getRequiredEdition;
20
+ exports.readLicense = readLicense;
21
+ exports.writeLicense = writeLicense;
22
+ exports.clearLicense = clearLicense;
23
+ exports.getEdition = getEdition;
24
+ exports.verifyLicenseToken = verifyLicenseToken;
25
+ exports.activateLicenseOnline = activateLicenseOnline;
26
+ exports.isEnterpriseOrHigher = isEnterpriseOrHigher;
27
+ exports.isEnterpriseProEdition = isEnterpriseProEdition;
28
+ exports.assertComponentAccess = assertComponentAccess;
29
+ exports.printLicenseStatus = printLicenseStatus;
30
+ const fs_extra_1 = __importDefault(require("fs-extra"));
31
+ const path_1 = __importDefault(require("path"));
32
+ const os_1 = __importDefault(require("os"));
33
+ const chalk_1 = __importDefault(require("chalk"));
34
+ const jose_1 = require("jose");
35
+ // ─── JWT Public Key (Ed25519) ─────────────────────────────────────────────────
36
+ // Private key lives only in Cloudflare Worker secret — never in binary.
37
+ // Public key is safe to embed: it can verify, but NOT sign.
38
+ const PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
39
+ MCowBQYDK2VwAyEAJVKs6IZX5OqyVSxaKpLK6leRpKHVAZF5nUUB6B9BqdI=
40
+ -----END PUBLIC KEY-----`;
41
+ const ACTIVATE_ENDPOINT = 'https://chimerai-activate-worker.chimerai.workers.dev/activate';
42
+ const LICENSE_DIR = path_1.default.join(os_1.default.homedir(), '.chimerai');
43
+ const LICENSE_PATH = path_1.default.join(LICENSE_DIR, 'license.json');
44
+ // ─── Tier-Hierarchie ─────────────────────────────────────────────────────────
45
+ // enterprise-pro ⊇ enterprise ⊇ free
46
+ // Ein höherer Tier hat immer Zugriff auf alle Features darunter.
47
+ const TIER_LEVEL = {
48
+ free: 0,
49
+ enterprise: 1,
50
+ 'enterprise-pro': 2,
51
+ };
52
+ function meetsRequirement(actual, required) {
53
+ return TIER_LEVEL[actual] >= TIER_LEVEL[required];
54
+ }
55
+ // ─── Komponenten-Definitionen ─────────────────────────────────────────────────
56
+ /** Free-Komponenten — immer verfügbar, kein Gate */
57
+ exports.FREE_COMPONENTS = new Set([
58
+ 'chat-ui',
59
+ 'chat-widget',
60
+ 'ai-chat',
61
+ 'rag',
62
+ 'model-providers',
63
+ 'prompt-management',
64
+ ]);
65
+ /** Enterprise-Komponenten (Enterprise + Enterprise Pro) */
66
+ exports.ENTERPRISE_COMPONENTS = {
67
+ auth: 'NextAuth Authentication + Session Management',
68
+ billing: 'Stripe Billing & Subscriptions',
69
+ 'admin-dashboard': 'Admin Dashboard Overview',
70
+ 'users-table': 'User Management CRUD',
71
+ 'roles-table': 'Role Management CRUD',
72
+ gdpr: 'GDPR Compliance (Export, Deletion, Consent)',
73
+ mfa: 'Multi-Factor Authentication (TOTP)',
74
+ 'audit-log': 'Audit Logging for Compliance',
75
+ analytics: 'API Usage Analytics',
76
+ sentry: 'Error Tracking & Monitoring',
77
+ };
78
+ /** Enterprise Pro-Komponenten (nur Enterprise Pro) */
79
+ exports.ENTERPRISE_PRO_COMPONENTS = {
80
+ webhooks: 'Webhook Dispatch with HMAC Signing',
81
+ theming: 'Dynamic Theme Engine',
82
+ guardrails: 'AI Content Safety & PII Detection',
83
+ 'ai-tools': 'AI Tools (Web Search, NLP, Vision)',
84
+ };
85
+ // ─── Hilfsfunktionen ─────────────────────────────────────────────────────────
86
+ function getRequiredEdition(component) {
87
+ if (exports.FREE_COMPONENTS.has(component))
88
+ return 'free';
89
+ if (exports.ENTERPRISE_COMPONENTS[component])
90
+ return 'enterprise';
91
+ if (exports.ENTERPRISE_PRO_COMPONENTS[component])
92
+ return 'enterprise-pro';
93
+ return null; // Unbekannte Komponente — wird anderswo behandelt
94
+ }
95
+ // ─── License File I/O ─────────────────────────────────────────────────────────
96
+ function readLicense() {
97
+ try {
98
+ if (!fs_extra_1.default.existsSync(LICENSE_PATH))
99
+ return null;
100
+ const raw = fs_extra_1.default.readFileSync(LICENSE_PATH, 'utf-8');
101
+ return JSON.parse(raw);
102
+ }
103
+ catch {
104
+ return null;
105
+ }
106
+ }
107
+ function writeLicense(license) {
108
+ fs_extra_1.default.ensureDirSync(LICENSE_DIR);
109
+ fs_extra_1.default.writeFileSync(LICENSE_PATH, JSON.stringify(license, null, 2));
110
+ }
111
+ function clearLicense() {
112
+ if (fs_extra_1.default.existsSync(LICENSE_PATH)) {
113
+ fs_extra_1.default.removeSync(LICENSE_PATH);
114
+ }
115
+ }
116
+ // ─── Edition Detection ────────────────────────────────────────────────────────
117
+ function getEdition() {
118
+ const license = readLicense();
119
+ if (!license)
120
+ return 'free';
121
+ if (license.edition !== 'enterprise' && license.edition !== 'enterprise-pro')
122
+ return 'free';
123
+ // If we have a JWT token, we trust only the locally cached edition
124
+ // (full async JWT verification happens in verifyLicenseToken)
125
+ // For sync gate checks we trust the stored edition — JWT is verified on activate
126
+ if (license.validUntil) {
127
+ const expiry = new Date(license.validUntil);
128
+ if (expiry < new Date())
129
+ return 'free';
130
+ }
131
+ return license.edition;
132
+ }
133
+ /** Verifies the JWT signature of a stored license token (async). */
134
+ async function verifyLicenseToken(token) {
135
+ try {
136
+ const publicKey = await (0, jose_1.importSPKI)(PUBLIC_KEY_PEM, 'EdDSA');
137
+ const { payload } = await (0, jose_1.jwtVerify)(token, publicKey, { issuer: 'chimerai.dev' });
138
+ const edition = payload['edition'];
139
+ const email = payload['email'] ?? '';
140
+ if (edition !== 'enterprise' && edition !== 'enterprise-pro')
141
+ return null;
142
+ return { edition, email };
143
+ }
144
+ catch {
145
+ return null;
146
+ }
147
+ }
148
+ /** Activates a license key by calling the chimerai.dev API. Returns error string or null on success. */
149
+ async function activateLicenseOnline(key) {
150
+ try {
151
+ const res = await fetch(ACTIVATE_ENDPOINT, {
152
+ method: 'POST',
153
+ headers: { 'Content-Type': 'application/json' },
154
+ body: JSON.stringify({ key, instance: os_1.default.hostname() }),
155
+ });
156
+ const data = (await res.json());
157
+ if (!res.ok || data['error']) {
158
+ return { error: String(data['error'] ?? 'Activation failed') };
159
+ }
160
+ const token = String(data['token'] ?? '');
161
+ const edition = String(data['edition'] ?? '');
162
+ const email = String(data['email'] ?? '');
163
+ // Verify JWT signature before trusting it
164
+ const publicKey = await (0, jose_1.importSPKI)(PUBLIC_KEY_PEM, 'EdDSA');
165
+ await (0, jose_1.jwtVerify)(token, publicKey, { issuer: 'chimerai.dev' });
166
+ return { edition, email, token };
167
+ }
168
+ catch (err) {
169
+ const msg = err instanceof Error ? err.message : String(err);
170
+ if (msg.includes('fetch') || msg.includes('ENOTFOUND') || msg.includes('network')) {
171
+ return { error: 'Network error — check your internet connection.' };
172
+ }
173
+ return { error: `Activation failed: ${msg}` };
174
+ }
175
+ }
176
+ function isEnterpriseOrHigher() {
177
+ return meetsRequirement(getEdition(), 'enterprise');
178
+ }
179
+ function isEnterpriseProEdition() {
180
+ return getEdition() === 'enterprise-pro';
181
+ }
182
+ // ─── Feature Gate ─────────────────────────────────────────────────────────────
183
+ /**
184
+ * Prüft ob eine Komponente in der aktuellen Edition zugänglich ist.
185
+ * Gibt kontextuelle Upsell-Meldung aus und beendet den Prozess wenn nicht.
186
+ */
187
+ function assertComponentAccess(component) {
188
+ const required = getRequiredEdition(component);
189
+ // Unbekannte Komponente — wird anderswo behandelt
190
+ if (required === null)
191
+ return;
192
+ // Free — immer erlaubt
193
+ if (required === 'free')
194
+ return;
195
+ const actual = getEdition();
196
+ // Zugriff erlaubt
197
+ if (meetsRequirement(actual, required))
198
+ return;
199
+ // --- Blockiert: kontextuelle Upsell-Meldung ---
200
+ if (actual === 'enterprise' && required === 'enterprise-pro') {
201
+ // Enterprise-Kunde will Enterprise-Pro-Feature
202
+ console.log(chalk_1.default.red(`\n 🔒 "${component}" is an Enterprise Pro feature.\n`));
203
+ console.log(chalk_1.default.bold(' Exclusive to ChimerAI Enterprise Pro:\n'));
204
+ for (const [name, desc] of Object.entries(exports.ENTERPRISE_PRO_COMPONENTS)) {
205
+ console.log(` ${chalk_1.default.yellow('•')} ${chalk_1.default.white(name.padEnd(22))} ${chalk_1.default.gray(desc)}`);
206
+ }
207
+ console.log(chalk_1.default.bold('\n You have Enterprise — upgrade to unlock these features:'));
208
+ console.log(chalk_1.default.bold('\n → Upgrade: ') + chalk_1.default.cyan('https://chimerai.dev/enterprise-pro'));
209
+ console.log(chalk_1.default.bold(' → Contact: ') + chalk_1.default.cyan('sales@chimerai.dev\n'));
210
+ throw new Error(`"${component}" requires an Enterprise Pro license.`);
211
+ }
212
+ else {
213
+ // Free-Kunde will Enterprise- oder Enterprise-Pro-Feature
214
+ const isEntPro = required === 'enterprise-pro';
215
+ console.log(chalk_1.default.red(`\n 🔒 "${component}" is an ${isEntPro ? 'Enterprise Pro' : 'Enterprise'} feature.\n`));
216
+ console.log(chalk_1.default.bold(' 🏢 ChimerAI Enterprise:\n'));
217
+ for (const [name, desc] of Object.entries(exports.ENTERPRISE_COMPONENTS)) {
218
+ console.log(` ${chalk_1.default.green('•')} ${chalk_1.default.white(name.padEnd(22))} ${chalk_1.default.gray(desc)}`);
219
+ }
220
+ console.log(chalk_1.default.bold('\n 🚀 ChimerAI Enterprise Pro:\n'));
221
+ for (const [name, desc] of Object.entries(exports.ENTERPRISE_PRO_COMPONENTS)) {
222
+ console.log(` ${chalk_1.default.yellow('•')} ${chalk_1.default.white(name.padEnd(22))} ${chalk_1.default.gray(desc)}`);
223
+ }
224
+ console.log(chalk_1.default.bold('\n → Enterprise: ') + chalk_1.default.cyan('https://chimerai.dev/enterprise'));
225
+ console.log(chalk_1.default.bold(' → Enterprise Pro: ') + chalk_1.default.cyan('https://chimerai.dev/enterprise-pro'));
226
+ console.log(chalk_1.default.bold(' → Activate: ') + chalk_1.default.white('chimerai activate <LICENSE-KEY>'));
227
+ console.log(chalk_1.default.bold(' → Contact: ') + chalk_1.default.cyan('sales@chimerai.dev\n'));
228
+ throw new Error(isEntPro
229
+ ? `"${component}" requires an Enterprise Pro license.`
230
+ : `"${component}" requires an Enterprise license.`);
231
+ }
232
+ }
233
+ // ─── License Info (für chimerai license) ─────────────────────────────────────
234
+ const EDITION_LABELS = {
235
+ free: 'Free',
236
+ enterprise: 'Enterprise',
237
+ 'enterprise-pro': 'Enterprise Pro',
238
+ };
239
+ function printLicenseStatus() {
240
+ const license = readLicense();
241
+ const edition = getEdition();
242
+ if (!license || edition === 'free') {
243
+ console.log(chalk_1.default.bold.yellow('\n 📋 Edition: ') + chalk_1.default.white('Free'));
244
+ console.log(chalk_1.default.gray(' No license key activated.'));
245
+ console.log(chalk_1.default.gray(' Enterprise: ') + chalk_1.default.cyan('https://chimerai.dev/enterprise'));
246
+ console.log(chalk_1.default.gray(' Activate with: ') + chalk_1.default.white('chimerai activate <KEY>\n'));
247
+ return;
248
+ }
249
+ const expiry = license.validUntil
250
+ ? new Date(license.validUntil).toLocaleDateString('de-AT')
251
+ : 'unbegrenzt';
252
+ const color = edition === 'enterprise-pro' ? chalk_1.default.bold.magenta : chalk_1.default.bold.green;
253
+ console.log(color('\n 📋 Edition: ') + chalk_1.default.white(`${EDITION_LABELS[edition]} ✅`));
254
+ if (license.email)
255
+ console.log(chalk_1.default.gray(` Licensed to: ${license.email}`));
256
+ console.log(chalk_1.default.gray(` Valid until: ${expiry}`));
257
+ console.log(chalk_1.default.gray(` Activated: ${new Date(license.activatedAt).toLocaleDateString('en-US')}\n`));
258
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Project Scanner - PHASE 3.1
3
+ * Analyzes existing Next.js projects to detect configuration, frameworks, and installed components
4
+ * Used by `add` and `dev` commands to make intelligent decisions
5
+ */
6
+ export interface ProjectInfo {
7
+ hasPackageJson: boolean;
8
+ packageManager: 'pnpm' | 'npm' | 'yarn' | 'bun' | 'unknown';
9
+ nextVersion: string | null;
10
+ hasAppRouter: boolean;
11
+ hasPagesRouter: boolean;
12
+ hasPrisma: boolean;
13
+ prismaProvider: 'postgresql' | 'mysql' | 'sqlite' | null;
14
+ prismaModels: string[];
15
+ hasNextAuth: boolean;
16
+ hasClerk: boolean;
17
+ hasSupabaseAuth: boolean;
18
+ hasShadcn: boolean;
19
+ hasTailwind: boolean;
20
+ hasChakra: boolean;
21
+ installedComponents: string[];
22
+ hasStripe: boolean;
23
+ hasLemonSqueezy: boolean;
24
+ }
25
+ /**
26
+ * Scan project for framework, dependencies, and installed components
27
+ * @param targetDir - Project root directory
28
+ * @returns ProjectInfo with detailed project configuration
29
+ */
30
+ export declare function scanProject(targetDir: string): Promise<ProjectInfo>;
31
+ //# sourceMappingURL=scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,WAAW,WAAW;IAE1B,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;IAG5D,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IAGxB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC;IACzD,YAAY,EAAE,MAAM,EAAE,CAAC;IAGvB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IAGzB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IAGnB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAG9B,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA0GzE"}
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ /**
3
+ * Project Scanner - PHASE 3.1
4
+ * Analyzes existing Next.js projects to detect configuration, frameworks, and installed components
5
+ * Used by `add` and `dev` commands to make intelligent decisions
6
+ */
7
+ var __importDefault = (this && this.__importDefault) || function (mod) {
8
+ return (mod && mod.__esModule) ? mod : { "default": mod };
9
+ };
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.scanProject = scanProject;
12
+ const path_1 = __importDefault(require("path"));
13
+ const fs_extra_1 = __importDefault(require("fs-extra"));
14
+ /**
15
+ * Scan project for framework, dependencies, and installed components
16
+ * @param targetDir - Project root directory
17
+ * @returns ProjectInfo with detailed project configuration
18
+ */
19
+ async function scanProject(targetDir) {
20
+ const info = {
21
+ hasPackageJson: false,
22
+ packageManager: 'unknown',
23
+ nextVersion: null,
24
+ hasAppRouter: false,
25
+ hasPagesRouter: false,
26
+ hasPrisma: false,
27
+ prismaProvider: null,
28
+ prismaModels: [],
29
+ hasNextAuth: false,
30
+ hasClerk: false,
31
+ hasSupabaseAuth: false,
32
+ hasShadcn: false,
33
+ hasTailwind: false,
34
+ hasChakra: false,
35
+ installedComponents: [],
36
+ hasStripe: false,
37
+ hasLemonSqueezy: false,
38
+ };
39
+ // 1. Check package.json
40
+ const pkgPath = path_1.default.join(targetDir, 'package.json');
41
+ if (await fs_extra_1.default.pathExists(pkgPath)) {
42
+ info.hasPackageJson = true;
43
+ const pkg = await fs_extra_1.default.readJson(pkgPath);
44
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
45
+ // Package Manager detection
46
+ if (await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'pnpm-lock.yaml'))) {
47
+ info.packageManager = 'pnpm';
48
+ }
49
+ else if (await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'yarn.lock'))) {
50
+ info.packageManager = 'yarn';
51
+ }
52
+ else if (await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'bun.lockb'))) {
53
+ info.packageManager = 'bun';
54
+ }
55
+ else if (await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'package-lock.json'))) {
56
+ info.packageManager = 'npm';
57
+ }
58
+ // Framework
59
+ info.nextVersion = allDeps['next'] || null;
60
+ // Auth systems
61
+ info.hasNextAuth = !!allDeps['next-auth'];
62
+ info.hasClerk = !!allDeps['@clerk/nextjs'];
63
+ info.hasSupabaseAuth = !!allDeps['@supabase/auth-helpers-nextjs'];
64
+ // UI frameworks
65
+ info.hasTailwind = !!allDeps['tailwindcss'];
66
+ info.hasShadcn =
67
+ !!allDeps['@radix-ui/react-dialog'] || !!allDeps['class-variance-authority'];
68
+ info.hasChakra = !!allDeps['@chakra-ui/react'];
69
+ // Billing
70
+ info.hasStripe = !!allDeps['stripe'];
71
+ info.hasLemonSqueezy = !!allDeps['@lemonsqueezy/lemonsqueezy.js'];
72
+ }
73
+ // 2. Check directory structure for routing
74
+ info.hasAppRouter = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'app'));
75
+ info.hasPagesRouter = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'pages'));
76
+ // 3. Check Prisma configuration
77
+ const schemaPath = path_1.default.join(targetDir, 'prisma', 'schema.prisma');
78
+ if (await fs_extra_1.default.pathExists(schemaPath)) {
79
+ info.hasPrisma = true;
80
+ const schema = await fs_extra_1.default.readFile(schemaPath, 'utf-8');
81
+ // Detect database provider
82
+ const providerMatch = schema.match(/provider\s*=\s*"(postgresql|mysql|sqlite)"/);
83
+ if (providerMatch) {
84
+ info.prismaProvider = providerMatch[1];
85
+ }
86
+ // Extract all model names
87
+ const modelMatches = schema.matchAll(/^model\s+(\w+)\s*\{/gm);
88
+ for (const match of modelMatches) {
89
+ info.prismaModels.push(match[1]);
90
+ }
91
+ }
92
+ // 4. Check installed ChimerAI components
93
+ // Map component names to key files that indicate their presence
94
+ const componentChecks = {
95
+ 'auth': ['lib/auth.ts', 'app/api/auth/[...nextauth]/route.ts'],
96
+ 'billing': ['lib/stripe.ts', 'app/billing/page.tsx'],
97
+ 'chat-ui': ['app/chat/page.tsx', 'components/StreamingChat.tsx'],
98
+ 'rbac': ['app/admin/users/page.tsx', 'lib/permissions.ts'],
99
+ 'mfa': ['app/api/auth/mfa/setup/route.ts'],
100
+ 'gdpr': ['app/api/gdpr/consent/route.ts'],
101
+ 'webhooks': ['app/api/webhooks/route.ts'],
102
+ 'audit-log': ['lib/audit-log.ts'],
103
+ 'analytics': ['lib/analytics.ts'],
104
+ 'admin': ['app/admin/page.tsx'],
105
+ };
106
+ for (const [name, files] of Object.entries(componentChecks)) {
107
+ const hasAny = await Promise.all(files.map((f) => fs_extra_1.default.pathExists(path_1.default.join(targetDir, f))));
108
+ if (hasAny.some(Boolean)) {
109
+ info.installedComponents.push(name);
110
+ }
111
+ }
112
+ return info;
113
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Schema Manager - PHASE 3.2
3
+ * Manages Prisma schema extensions without overwriting existing configurations
4
+ * Prevents duplicate models and intelligently merges schema changes
5
+ */
6
+ /**
7
+ * Extend Prisma schema with new models/enums without overwriting existing ones
8
+ * @param schemaPath - Path to prisma/schema.prisma
9
+ * @param newModels - Prisma model definitions to add
10
+ * @param newEnums - Optional Prisma enum definitions to add
11
+ */
12
+ export declare function extendPrismaSchema(schemaPath: string, newModels: string, newEnums?: string): Promise<void>;
13
+ /**
14
+ * Get all model names from a Prisma schema
15
+ * @param schemaPath - Path to prisma/schema.prisma
16
+ * @returns Array of model names
17
+ */
18
+ export declare function getPrismaModels(schemaPath: string): Promise<string[]>;
19
+ /**
20
+ * Check if a specific model exists in schema
21
+ * @param schemaPath - Path to prisma/schema.prisma
22
+ * @param modelName - Model name to check
23
+ * @returns true if model exists
24
+ */
25
+ export declare function modelExists(schemaPath: string, modelName: string): Promise<boolean>;
26
+ //# sourceMappingURL=schema-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-manager.d.ts","sourceRoot":"","sources":["../src/schema-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CA+Ff;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAQ3E;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGzF"}
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ /**
3
+ * Schema Manager - PHASE 3.2
4
+ * Manages Prisma schema extensions without overwriting existing configurations
5
+ * Prevents duplicate models and intelligently merges schema changes
6
+ */
7
+ var __importDefault = (this && this.__importDefault) || function (mod) {
8
+ return (mod && mod.__esModule) ? mod : { "default": mod };
9
+ };
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.extendPrismaSchema = extendPrismaSchema;
12
+ exports.getPrismaModels = getPrismaModels;
13
+ exports.modelExists = modelExists;
14
+ const fs_extra_1 = __importDefault(require("fs-extra"));
15
+ const chalk_1 = __importDefault(require("chalk"));
16
+ /**
17
+ * Extend Prisma schema with new models/enums without overwriting existing ones
18
+ * @param schemaPath - Path to prisma/schema.prisma
19
+ * @param newModels - Prisma model definitions to add
20
+ * @param newEnums - Optional Prisma enum definitions to add
21
+ */
22
+ async function extendPrismaSchema(schemaPath, newModels, newEnums) {
23
+ if (!(await fs_extra_1.default.pathExists(schemaPath))) {
24
+ throw new Error(`Prisma schema not found at ${schemaPath}`);
25
+ }
26
+ let schema = await fs_extra_1.default.readFile(schemaPath, 'utf-8');
27
+ // 1. Extract model names from both existing and new schemas
28
+ const existingModels = [...schema.matchAll(/^model\s+(\w+)\s*\{/gm)].map((m) => m[1]);
29
+ const newModelNames = [...newModels.matchAll(/^model\s+(\w+)\s*\{/gm)].map((m) => m[1]);
30
+ // 2. Check for duplicates
31
+ const duplicates = newModelNames.filter((m) => existingModels.includes(m));
32
+ let modelsToAdd = newModels;
33
+ if (duplicates.length > 0) {
34
+ console.log(chalk_1.default.yellow(`⚠️ Models already exist: ${duplicates.join(', ')} - skipping duplicates`));
35
+ // Remove duplicate models from the new schema
36
+ // Use brace-counting instead of regex to handle nested braces in @default("{}")
37
+ for (const dup of duplicates) {
38
+ const modelStart = modelsToAdd.search(new RegExp(`model\\s+${dup}\\s*\\{`));
39
+ if (modelStart === -1)
40
+ continue;
41
+ const braceStart = modelsToAdd.indexOf('{', modelStart);
42
+ let depth = 0;
43
+ let braceEnd = braceStart;
44
+ for (let i = braceStart; i < modelsToAdd.length; i++) {
45
+ if (modelsToAdd[i] === '{')
46
+ depth++;
47
+ if (modelsToAdd[i] === '}')
48
+ depth--;
49
+ if (depth === 0) {
50
+ braceEnd = i;
51
+ break;
52
+ }
53
+ }
54
+ modelsToAdd = (modelsToAdd.slice(0, modelStart) + modelsToAdd.slice(braceEnd + 1)).trim();
55
+ }
56
+ }
57
+ // 3. Extract existing enums
58
+ const existingEnums = [...schema.matchAll(/^enum\s+(\w+)\s*\{/gm)].map((m) => m[1]);
59
+ const newEnumNames = newEnums
60
+ ? [...newEnums.matchAll(/^enum\s+(\w+)\s*\{/gm)].map((m) => m[1])
61
+ : [];
62
+ const duplicateEnums = newEnumNames.filter((e) => existingEnums.includes(e));
63
+ let enumsToAdd = newEnums || '';
64
+ if (duplicateEnums.length > 0) {
65
+ console.log(chalk_1.default.yellow(`⚠️ Enums already exist: ${duplicateEnums.join(', ')} - skipping duplicates`));
66
+ // Remove duplicate enums using brace-counting
67
+ for (const dup of duplicateEnums) {
68
+ const enumStart = enumsToAdd.search(new RegExp(`enum\\s+${dup}\\s*\\{`));
69
+ if (enumStart === -1)
70
+ continue;
71
+ const braceStart = enumsToAdd.indexOf('{', enumStart);
72
+ let depth = 0;
73
+ let braceEnd = braceStart;
74
+ for (let i = braceStart; i < enumsToAdd.length; i++) {
75
+ if (enumsToAdd[i] === '{')
76
+ depth++;
77
+ if (enumsToAdd[i] === '}')
78
+ depth--;
79
+ if (depth === 0) {
80
+ braceEnd = i;
81
+ break;
82
+ }
83
+ }
84
+ enumsToAdd = (enumsToAdd.slice(0, enumStart) + enumsToAdd.slice(braceEnd + 1)).trim();
85
+ }
86
+ }
87
+ // 4. Add enums at beginning (before models)
88
+ if (enumsToAdd.trim()) {
89
+ // Find where models start
90
+ const firstModelIndex = schema.search(/^model\s+/m);
91
+ if (firstModelIndex !== -1) {
92
+ schema =
93
+ schema.slice(0, firstModelIndex) +
94
+ '\n' +
95
+ enumsToAdd +
96
+ '\n\n' +
97
+ schema.slice(firstModelIndex);
98
+ }
99
+ else {
100
+ schema += '\n\n' + enumsToAdd;
101
+ }
102
+ }
103
+ // 5. Add models at end
104
+ if (modelsToAdd.trim()) {
105
+ schema += '\n\n// Added by chimerai\n' + modelsToAdd;
106
+ }
107
+ // 6. Write updated schema
108
+ await fs_extra_1.default.writeFile(schemaPath, schema.trim() + '\n');
109
+ }
110
+ /**
111
+ * Get all model names from a Prisma schema
112
+ * @param schemaPath - Path to prisma/schema.prisma
113
+ * @returns Array of model names
114
+ */
115
+ async function getPrismaModels(schemaPath) {
116
+ if (!(await fs_extra_1.default.pathExists(schemaPath))) {
117
+ return [];
118
+ }
119
+ const schema = await fs_extra_1.default.readFile(schemaPath, 'utf-8');
120
+ const models = [...schema.matchAll(/^model\s+(\w+)\s*\{/gm)].map((m) => m[1]);
121
+ return models;
122
+ }
123
+ /**
124
+ * Check if a specific model exists in schema
125
+ * @param schemaPath - Path to prisma/schema.prisma
126
+ * @param modelName - Model name to check
127
+ * @returns true if model exists
128
+ */
129
+ async function modelExists(schemaPath, modelName) {
130
+ const models = await getPrismaModels(schemaPath);
131
+ return models.includes(modelName);
132
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Admin panel component templates
3
+ * Generates admin dashboard, users management page, roles management page, and admin layout guard
4
+ */
5
+ /**
6
+ * Generates the admin layout with session check and admin role guard.
7
+ * Redirects unauthenticated users to sign-in, unauthorized users to dashboard.
8
+ * @returns TypeScript/JSX content for app/admin/layout.tsx
9
+ */
10
+ export declare function generateAdminLayout(): string;
11
+ /**
12
+ * Generates the main admin dashboard
13
+ * Shows cards linking to RBAC, AI configuration, and system management sections
14
+ * @returns TypeScript/JSX content for app/admin/page.tsx
15
+ */
16
+ export declare function generateAdminDashboardPage(): string;
17
+ /**
18
+ * Generates the admin users management page
19
+ * Displays user list with search, create/edit/delete functionality
20
+ * @returns TypeScript/JSX content for app/admin/users/page.tsx
21
+ */
22
+ export declare function generateAdminUsersPage(): string;
23
+ /**
24
+ * Generates the admin roles management page
25
+ * Allows CRUD operations on roles and permission assignment
26
+ * @returns TypeScript/JSX content for app/admin/roles/page.tsx
27
+ */
28
+ export declare function generateAdminRolesPage(): string;
29
+ /**
30
+ * Generates the admin settings page
31
+ * Functional page for system configuration with save/reset
32
+ * @returns TypeScript/JSX content for app/admin/settings/page.tsx
33
+ */
34
+ export declare function generateAdminSettingsPage(): string;
35
+ /**
36
+ * Generates the admin activity logs page
37
+ * Full audit log table with filters for action, user, and date range
38
+ * @returns TypeScript/JSX content for app/admin/logs/page.tsx
39
+ */
40
+ export declare function generateAdminLogsPage(): string;
41
+ /**
42
+ * Generates the audit log helper utility.
43
+ * Provides logAuditAction() for recording actions across the app.
44
+ * @returns TypeScript content for lib/audit.ts
45
+ */
46
+ export declare function generatePermissionsLib(): string;
47
+ export declare function generateRequirePermissionLib(): string;
48
+ export declare function generateAuditLogHelper(): string;
49
+ //# sourceMappingURL=admin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/templates/admin.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CA6G5C;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAmEnD;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAuU/C;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CA+Q/C;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CA4LlD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CA6K9C;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAgE/C;AAED,wBAAgB,4BAA4B,IAAI,MAAM,CA+DrD;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAqC/C"}