humanbehavior-js 0.4.13 → 0.4.15

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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import * as fs from 'fs';
3
3
  import * as path from 'path';
4
- import * as readline from 'readline';
4
+ import * as clack from '@clack/prompts';
5
5
 
6
6
  /******************************************************************************
7
7
  Copyright (c) Microsoft Corporation.
@@ -47,6 +47,28 @@ class AutoInstallationWizard {
47
47
  this.apiKey = apiKey;
48
48
  this.projectRoot = projectRoot;
49
49
  }
50
+ /**
51
+ * Simple version comparison utility
52
+ */
53
+ compareVersions(version1, version2) {
54
+ const v1Parts = version1.split('.').map(Number);
55
+ const v2Parts = version2.split('.').map(Number);
56
+ for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
57
+ const v1 = v1Parts[i] || 0;
58
+ const v2 = v2Parts[i] || 0;
59
+ if (v1 > v2)
60
+ return 1;
61
+ if (v1 < v2)
62
+ return -1;
63
+ }
64
+ return 0;
65
+ }
66
+ isVersionGte(version, target) {
67
+ return this.compareVersions(version, target) >= 0;
68
+ }
69
+ getMajorVersion(version) {
70
+ return parseInt(version.split('.')[0]) || 0;
71
+ }
50
72
  /**
51
73
  * Main installation method - detects framework and auto-installs
52
74
  */
@@ -96,73 +118,146 @@ class AutoInstallationWizard {
96
118
  }
97
119
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
98
120
  const dependencies = Object.assign(Object.assign({}, packageJson.dependencies), packageJson.devDependencies);
99
- // Detect framework
121
+ // Detect framework with version information
100
122
  let framework = {
101
123
  name: 'vanilla',
102
124
  type: 'vanilla',
103
- projectRoot: this.projectRoot
125
+ projectRoot: this.projectRoot,
126
+ features: {}
104
127
  };
105
128
  if (dependencies.nuxt) {
129
+ const nuxtVersion = dependencies.nuxt;
130
+ const isNuxt3 = this.isVersionGte(nuxtVersion, '3.0.0');
106
131
  framework = {
107
132
  name: 'nuxt',
108
133
  type: 'nuxt',
134
+ version: nuxtVersion,
135
+ majorVersion: this.getMajorVersion(nuxtVersion),
109
136
  hasTypeScript: !!dependencies.typescript,
110
137
  hasRouter: true,
111
- projectRoot: this.projectRoot
138
+ projectRoot: this.projectRoot,
139
+ features: {
140
+ hasNuxt3: isNuxt3
141
+ }
112
142
  };
113
143
  }
114
144
  else if (dependencies.next) {
145
+ const nextVersion = dependencies.next;
146
+ const isNext13 = this.isVersionGte(nextVersion, '13.0.0');
115
147
  framework = {
116
148
  name: 'nextjs',
117
149
  type: 'nextjs',
150
+ version: nextVersion,
151
+ majorVersion: this.getMajorVersion(nextVersion),
118
152
  hasTypeScript: !!dependencies.typescript || !!dependencies['@types/node'],
119
153
  hasRouter: true,
120
- projectRoot: this.projectRoot
154
+ projectRoot: this.projectRoot,
155
+ features: {
156
+ hasNextAppRouter: isNext13
157
+ }
121
158
  };
122
159
  }
123
160
  else if (dependencies['@remix-run/react'] || dependencies['@remix-run/dev']) {
161
+ const remixVersion = dependencies['@remix-run/react'] || dependencies['@remix-run/dev'];
124
162
  framework = {
125
163
  name: 'remix',
126
164
  type: 'remix',
165
+ version: remixVersion,
166
+ majorVersion: this.getMajorVersion(remixVersion),
127
167
  hasTypeScript: !!dependencies.typescript || !!dependencies['@types/react'],
128
168
  hasRouter: true,
129
- projectRoot: this.projectRoot
169
+ projectRoot: this.projectRoot,
170
+ features: {}
130
171
  };
131
172
  }
132
173
  else if (dependencies.react) {
174
+ const reactVersion = dependencies.react;
175
+ const isReact18 = this.isVersionGte(reactVersion, '18.0.0');
133
176
  framework = {
134
177
  name: 'react',
135
178
  type: 'react',
179
+ version: reactVersion,
180
+ majorVersion: this.getMajorVersion(reactVersion),
136
181
  hasTypeScript: !!dependencies.typescript || !!dependencies['@types/react'],
137
182
  hasRouter: !!dependencies['react-router-dom'] || !!dependencies['react-router'],
138
- projectRoot: this.projectRoot
183
+ projectRoot: this.projectRoot,
184
+ features: {
185
+ hasReact18: isReact18
186
+ }
139
187
  };
140
188
  }
141
189
  else if (dependencies.vue) {
190
+ const vueVersion = dependencies.vue;
191
+ const isVue3 = this.isVersionGte(vueVersion, '3.0.0');
142
192
  framework = {
143
193
  name: 'vue',
144
194
  type: 'vue',
195
+ version: vueVersion,
196
+ majorVersion: this.getMajorVersion(vueVersion),
145
197
  hasTypeScript: !!dependencies.typescript || !!dependencies['@vue/cli-service'],
146
198
  hasRouter: !!dependencies['vue-router'],
147
- projectRoot: this.projectRoot
199
+ projectRoot: this.projectRoot,
200
+ features: {
201
+ hasVue3: isVue3
202
+ }
148
203
  };
149
204
  }
150
205
  else if (dependencies['@angular/core']) {
206
+ const angularVersion = dependencies['@angular/core'];
207
+ const isAngular17 = this.isVersionGte(angularVersion, '17.0.0');
151
208
  framework = {
152
209
  name: 'angular',
153
210
  type: 'angular',
211
+ version: angularVersion,
212
+ majorVersion: this.getMajorVersion(angularVersion),
154
213
  hasTypeScript: true,
155
214
  hasRouter: true,
156
- projectRoot: this.projectRoot
215
+ projectRoot: this.projectRoot,
216
+ features: {
217
+ hasAngularStandalone: isAngular17
218
+ }
157
219
  };
158
220
  }
159
221
  else if (dependencies.svelte) {
222
+ const svelteVersion = dependencies.svelte;
223
+ const isSvelteKit = !!dependencies['@sveltejs/kit'];
160
224
  framework = {
161
225
  name: 'svelte',
162
226
  type: 'svelte',
227
+ version: svelteVersion,
228
+ majorVersion: this.getMajorVersion(svelteVersion),
163
229
  hasTypeScript: !!dependencies.typescript || !!dependencies['svelte-check'],
164
230
  hasRouter: !!dependencies['svelte-routing'] || !!dependencies['@sveltejs/kit'],
165
- projectRoot: this.projectRoot
231
+ projectRoot: this.projectRoot,
232
+ features: {
233
+ hasSvelteKit: isSvelteKit
234
+ }
235
+ };
236
+ }
237
+ else if (dependencies.astro) {
238
+ const astroVersion = dependencies.astro;
239
+ framework = {
240
+ name: 'astro',
241
+ type: 'astro',
242
+ version: astroVersion,
243
+ majorVersion: this.getMajorVersion(astroVersion),
244
+ hasTypeScript: !!dependencies.typescript || !!dependencies['@astrojs/ts-plugin'],
245
+ hasRouter: true,
246
+ projectRoot: this.projectRoot,
247
+ features: {}
248
+ };
249
+ }
250
+ else if (dependencies.gatsby) {
251
+ const gatsbyVersion = dependencies.gatsby;
252
+ framework = {
253
+ name: 'gatsby',
254
+ type: 'gatsby',
255
+ version: gatsbyVersion,
256
+ majorVersion: this.getMajorVersion(gatsbyVersion),
257
+ hasTypeScript: !!dependencies.typescript || !!dependencies['@types/react'],
258
+ hasRouter: true,
259
+ projectRoot: this.projectRoot,
260
+ features: {}
166
261
  };
167
262
  }
168
263
  // Detect bundler
@@ -196,13 +291,18 @@ class AutoInstallationWizard {
196
291
  */
197
292
  installPackage() {
198
293
  return __awaiter(this, void 0, void 0, function* () {
199
- var _a, _b;
294
+ var _a, _b, _c, _d;
200
295
  const { execSync } = yield import('child_process');
201
- const command = ((_a = this.framework) === null || _a === void 0 ? void 0 : _a.packageManager) === 'yarn'
296
+ // Build base command
297
+ let command = ((_a = this.framework) === null || _a === void 0 ? void 0 : _a.packageManager) === 'yarn'
202
298
  ? 'yarn add humanbehavior-js'
203
299
  : ((_b = this.framework) === null || _b === void 0 ? void 0 : _b.packageManager) === 'pnpm'
204
300
  ? 'pnpm add humanbehavior-js'
205
301
  : 'npm install humanbehavior-js';
302
+ // Add legacy peer deps flag for npm to handle dependency conflicts
303
+ if (((_c = this.framework) === null || _c === void 0 ? void 0 : _c.packageManager) !== 'yarn' && ((_d = this.framework) === null || _d === void 0 ? void 0 : _d.packageManager) !== 'pnpm') {
304
+ command += ' --legacy-peer-deps';
305
+ }
206
306
  try {
207
307
  execSync(command, { cwd: this.projectRoot, stdio: 'inherit' });
208
308
  }
@@ -228,6 +328,12 @@ class AutoInstallationWizard {
228
328
  case 'nuxt':
229
329
  modifications.push(...yield this.generateNuxtModifications());
230
330
  break;
331
+ case 'astro':
332
+ modifications.push(...yield this.generateAstroModifications());
333
+ break;
334
+ case 'gatsby':
335
+ modifications.push(...yield this.generateGatsbyModifications());
336
+ break;
231
337
  case 'remix':
232
338
  modifications.push(...yield this.generateRemixModifications());
233
339
  break;
@@ -339,6 +445,84 @@ export function Providers({ children }: { children: React.ReactNode }) {
339
445
  return modifications;
340
446
  });
341
447
  }
448
+ /**
449
+ * Generate Astro-specific modifications
450
+ */
451
+ generateAstroModifications() {
452
+ return __awaiter(this, void 0, void 0, function* () {
453
+ const modifications = [];
454
+ // Create Astro component for HumanBehavior
455
+ const astroComponentPath = path.join(this.projectRoot, 'src', 'components', 'HumanBehavior.astro');
456
+ const astroComponentContent = `---
457
+ // This component will only run on the client side
458
+ ---
459
+
460
+ <script>
461
+ import { HumanBehaviorTracker } from 'humanbehavior-js';
462
+
463
+ // Get API key from environment variable
464
+ const apiKey = import.meta.env.PUBLIC_HUMANBEHAVIOR_API_KEY;
465
+
466
+ console.log('HumanBehavior: API key found:', apiKey ? 'Yes' : 'No');
467
+
468
+ if (apiKey) {
469
+ try {
470
+ const tracker = HumanBehaviorTracker.init(apiKey);
471
+ console.log('HumanBehavior: Tracker initialized successfully');
472
+
473
+ // Test event to verify tracking is working
474
+ setTimeout(() => {
475
+ tracker.customEvent('astro_page_view', {
476
+ page: window.location.pathname,
477
+ framework: 'astro'
478
+ }).then(() => {
479
+ console.log('HumanBehavior: Test event sent successfully');
480
+ }).catch((error) => {
481
+ console.error('HumanBehavior: Failed to send test event:', error);
482
+ });
483
+ }, 1000);
484
+
485
+ } catch (error) {
486
+ console.error('HumanBehavior: Failed to initialize tracker:', error);
487
+ }
488
+ } else {
489
+ console.error('HumanBehavior: No API key found');
490
+ }
491
+ </script>`;
492
+ modifications.push({
493
+ filePath: astroComponentPath,
494
+ action: 'create',
495
+ content: astroComponentContent,
496
+ description: 'Created Astro component for HumanBehavior SDK'
497
+ });
498
+ // Find and update layout file
499
+ const layoutFiles = [
500
+ path.join(this.projectRoot, 'src', 'layouts', 'Layout.astro'),
501
+ path.join(this.projectRoot, 'src', 'layouts', 'layout.astro'),
502
+ path.join(this.projectRoot, 'src', 'layouts', 'BaseLayout.astro')
503
+ ];
504
+ let layoutFile = null;
505
+ for (const file of layoutFiles) {
506
+ if (fs.existsSync(file)) {
507
+ layoutFile = file;
508
+ break;
509
+ }
510
+ }
511
+ if (layoutFile) {
512
+ const content = fs.readFileSync(layoutFile, 'utf8');
513
+ const modifiedContent = this.injectAstroLayout(content);
514
+ modifications.push({
515
+ filePath: layoutFile,
516
+ action: 'modify',
517
+ content: modifiedContent,
518
+ description: 'Added HumanBehavior component to Astro layout'
519
+ });
520
+ }
521
+ // Add environment variable
522
+ modifications.push(this.createEnvironmentModification(this.framework));
523
+ return modifications;
524
+ });
525
+ }
342
526
  /**
343
527
  * Generate Nuxt-specific modifications
344
528
  */
@@ -559,6 +743,50 @@ export default defineNuxtPlugin(() => {
559
743
  return modifications;
560
744
  });
561
745
  }
746
+ /**
747
+ * Generate Gatsby-specific modifications
748
+ */
749
+ generateGatsbyModifications() {
750
+ return __awaiter(this, void 0, void 0, function* () {
751
+ const modifications = [];
752
+ // Modify or create gatsby-browser.js for Gatsby
753
+ const gatsbyBrowserFile = path.join(this.projectRoot, 'gatsby-browser.js');
754
+ if (fs.existsSync(gatsbyBrowserFile)) {
755
+ const content = fs.readFileSync(gatsbyBrowserFile, 'utf8');
756
+ const modifiedContent = this.injectGatsbyBrowser(content);
757
+ modifications.push({
758
+ filePath: gatsbyBrowserFile,
759
+ action: 'modify',
760
+ content: modifiedContent,
761
+ description: 'Added HumanBehavior initialization to Gatsby browser'
762
+ });
763
+ }
764
+ else {
765
+ // Create gatsby-browser.js if it doesn't exist
766
+ modifications.push({
767
+ filePath: gatsbyBrowserFile,
768
+ action: 'create',
769
+ content: `import { HumanBehaviorTracker } from 'humanbehavior-js';
770
+
771
+ export const onClientEntry = () => {
772
+ console.log('Gatsby browser entry point loaded');
773
+ const apiKey = process.env.GATSBY_HUMANBEHAVIOR_API_KEY;
774
+ console.log('API Key found:', apiKey ? 'Yes' : 'No');
775
+ if (apiKey) {
776
+ const tracker = HumanBehaviorTracker.init(apiKey);
777
+ console.log('HumanBehavior SDK initialized for Gatsby');
778
+ } else {
779
+ console.log('No API key found in environment variables');
780
+ }
781
+ };`,
782
+ description: 'Created gatsby-browser.js with HumanBehavior initialization'
783
+ });
784
+ }
785
+ // Create or append to environment file
786
+ modifications.push(this.createEnvironmentModification(this.framework));
787
+ return modifications;
788
+ });
789
+ }
562
790
  /**
563
791
  * Apply modifications to the codebase
564
792
  */
@@ -653,7 +881,7 @@ export default defineNuxtPlugin(() => {
653
881
  return null;
654
882
  }
655
883
  injectReactProvider(content, filePath) {
656
- var _a;
884
+ var _a, _b, _c;
657
885
  filePath.endsWith('.tsx') || filePath.endsWith('.ts');
658
886
  // Check if already has HumanBehaviorProvider
659
887
  if (content.includes('HumanBehaviorProvider')) {
@@ -665,14 +893,39 @@ export default defineNuxtPlugin(() => {
665
893
  ? 'import.meta.env.VITE_HUMANBEHAVIOR_API_KEY!'
666
894
  : 'process.env.HUMANBEHAVIOR_API_KEY!';
667
895
  const importStatement = `import { HumanBehaviorProvider } from 'humanbehavior-js/react';`;
668
- // Simple injection - in production, you'd want more sophisticated parsing
896
+ // Enhanced parsing for React 18+ features
897
+ const hasReact18 = (_c = (_b = this.framework) === null || _b === void 0 ? void 0 : _b.features) === null || _c === void 0 ? void 0 : _c.hasReact18;
898
+ // Handle different React patterns
669
899
  if (content.includes('function App()') || content.includes('const App =')) {
670
- return content.replace(/(function App\(\)|const App =)/, `${importStatement}\n\n$1`).replace(/return \(([\s\S]*?)\);/, `return (
900
+ // Add import statement
901
+ let modifiedContent = content.replace(/(import.*?from.*?['"]react['"];?)/, `$1\n${importStatement}`);
902
+ // If no React import found, add it at the top
903
+ if (!modifiedContent.includes(importStatement)) {
904
+ modifiedContent = `${importStatement}\n\n${modifiedContent}`;
905
+ }
906
+ // Wrap the App component return with HumanBehaviorProvider
907
+ modifiedContent = modifiedContent.replace(/(return\s*\([\s\S]*?\)\s*;)/, `return (
671
908
  <HumanBehaviorProvider apiKey={${envVar}}>
672
909
  $1
673
910
  </HumanBehaviorProvider>
674
911
  );`);
912
+ return modifiedContent;
675
913
  }
914
+ // Handle React 18+ createRoot pattern
915
+ if (hasReact18 && content.includes('createRoot')) {
916
+ let modifiedContent = content.replace(/(import.*?from.*?['"]react['"];?)/, `$1\n${importStatement}`);
917
+ if (!modifiedContent.includes(importStatement)) {
918
+ modifiedContent = `${importStatement}\n\n${modifiedContent}`;
919
+ }
920
+ // Wrap the root render with HumanBehaviorProvider
921
+ modifiedContent = modifiedContent.replace(/(root\.render\s*\([\s\S]*?\)\s*;)/, `root.render(
922
+ <HumanBehaviorProvider apiKey={${envVar}}>
923
+ $1
924
+ </HumanBehaviorProvider>
925
+ );`);
926
+ return modifiedContent;
927
+ }
928
+ // Fallback: simple injection
676
929
  return `${importStatement}\n\n${content}`;
677
930
  }
678
931
  injectNextJSAppRouter(content) {
@@ -769,21 +1022,51 @@ export default function App()`);
769
1022
  return modifiedContent;
770
1023
  }
771
1024
  injectVuePlugin(content) {
1025
+ var _a, _b;
772
1026
  if (content.includes('HumanBehaviorPlugin')) {
773
1027
  return content;
774
1028
  }
775
1029
  const importStatement = `import { HumanBehaviorPlugin } from 'humanbehavior-js/vue';`;
776
- const pluginUsage = `app.use(HumanBehaviorPlugin, {
1030
+ // Enhanced Vue 3 support with version detection
1031
+ const hasVue3 = (_b = (_a = this.framework) === null || _a === void 0 ? void 0 : _a.features) === null || _b === void 0 ? void 0 : _b.hasVue3;
1032
+ if (hasVue3) {
1033
+ // Vue 3 with Composition API
1034
+ const pluginUsage = `app.use(HumanBehaviorPlugin, {
777
1035
  apiKey: import.meta.env.VITE_HUMANBEHAVIOR_API_KEY
778
1036
  });`;
779
- // Handle both Vue 2 and Vue 3 patterns
780
- if (content.includes('createApp')) {
781
- // Vue 3
782
- return content.replace(/import.*from.*['"]vue['"]/, `$&\n${importStatement}`).replace(/app\.mount\(/, `${pluginUsage}\n\napp.mount(`);
1037
+ let modifiedContent = content;
1038
+ // Add import statement
1039
+ if (!content.includes(importStatement)) {
1040
+ modifiedContent = content.replace(/(import.*?from.*?['"]vue['"];?)/, `$1\n${importStatement}`);
1041
+ // If no Vue import found, add it at the top
1042
+ if (!modifiedContent.includes(importStatement)) {
1043
+ modifiedContent = `${importStatement}\n\n${modifiedContent}`;
1044
+ }
1045
+ }
1046
+ // Handle createApp pattern
1047
+ if (content.includes('createApp')) {
1048
+ modifiedContent = modifiedContent.replace(/(app\.mount\(.*?\))/, `${pluginUsage}\n\n$1`);
1049
+ }
1050
+ return modifiedContent;
783
1051
  }
784
1052
  else {
785
- // Vue 2
786
- return content.replace(/import.*from.*['"]vue['"]/, `$&\n${importStatement}`).replace(/new Vue\(/, `${pluginUsage}\n\nnew Vue(`);
1053
+ // Vue 2 with Options API
1054
+ const pluginUsage = `Vue.use(HumanBehaviorPlugin, {
1055
+ apiKey: process.env.VUE_APP_HUMANBEHAVIOR_API_KEY
1056
+ });`;
1057
+ let modifiedContent = content;
1058
+ // Add import statement
1059
+ if (!content.includes(importStatement)) {
1060
+ modifiedContent = content.replace(/(import.*?from.*?['"]vue['"];?)/, `$1\n${importStatement}`);
1061
+ if (!modifiedContent.includes(importStatement)) {
1062
+ modifiedContent = `${importStatement}\n\n${modifiedContent}`;
1063
+ }
1064
+ }
1065
+ // Handle new Vue pattern
1066
+ if (content.includes('new Vue')) {
1067
+ modifiedContent = modifiedContent.replace(/(new Vue\(.*?\))/, `${pluginUsage}\n\n$1`);
1068
+ }
1069
+ return modifiedContent;
787
1070
  }
788
1071
  }
789
1072
  injectAngularModule(content) {
@@ -864,17 +1147,99 @@ if (typeof window !== 'undefined') {
864
1147
  </script>`;
865
1148
  return content.replace(/<\/head>/, ` ${cdnScript}\n ${initScript}\n</head>`);
866
1149
  }
1150
+ /**
1151
+ * Inject Astro layout with HumanBehavior component
1152
+ */
1153
+ injectAstroLayout(content) {
1154
+ // Check if HumanBehavior component is already imported
1155
+ if (content.includes('HumanBehavior') || content.includes('humanbehavior-js')) {
1156
+ return content; // Already has HumanBehavior
1157
+ }
1158
+ // Add import inside frontmatter if not present
1159
+ let modifiedContent = content;
1160
+ if (!content.includes('import HumanBehavior')) {
1161
+ const importStatement = 'import HumanBehavior from \'../components/HumanBehavior.astro\';';
1162
+ const frontmatterEndIndex = content.indexOf('---', 3);
1163
+ if (frontmatterEndIndex !== -1) {
1164
+ // Insert import inside frontmatter, before the closing ---
1165
+ modifiedContent = content.slice(0, frontmatterEndIndex) + '\n' + importStatement + '\n' + content.slice(frontmatterEndIndex);
1166
+ }
1167
+ else {
1168
+ // No frontmatter, add at the very beginning
1169
+ modifiedContent = '---\n' + importStatement + '\n---\n\n' + content;
1170
+ }
1171
+ }
1172
+ // Find the closing </body> tag and add HumanBehavior component before it
1173
+ const bodyCloseIndex = modifiedContent.lastIndexOf('</body>');
1174
+ if (bodyCloseIndex === -1) {
1175
+ // No body tag found, append to end
1176
+ return modifiedContent + '\n\n<HumanBehavior />';
1177
+ }
1178
+ // Add component before closing body tag
1179
+ return modifiedContent.slice(0, bodyCloseIndex) + ' <HumanBehavior />\n' + modifiedContent.slice(bodyCloseIndex);
1180
+ }
867
1181
  injectNuxtConfig(content) {
1182
+ var _a, _b;
868
1183
  if (content.includes('humanBehaviorApiKey')) {
869
1184
  return content;
870
1185
  }
871
- // Add runtime config by inserting it after the opening brace
872
- return content.replace(/export default defineNuxtConfig\(\{/, `export default defineNuxtConfig({
1186
+ // Enhanced Nuxt 3 support with version detection
1187
+ const hasNuxt3 = (_b = (_a = this.framework) === null || _a === void 0 ? void 0 : _a.features) === null || _b === void 0 ? void 0 : _b.hasNuxt3;
1188
+ if (hasNuxt3) {
1189
+ // Nuxt 3 with runtime config
1190
+ return content.replace(/export default defineNuxtConfig\(\{/, `export default defineNuxtConfig({
873
1191
  runtimeConfig: {
874
1192
  public: {
875
1193
  humanBehaviorApiKey: process.env.NUXT_PUBLIC_HUMANBEHAVIOR_API_KEY
876
1194
  }
877
1195
  },`);
1196
+ }
1197
+ else {
1198
+ // Nuxt 2 with env config
1199
+ return content.replace(/export default \{/, `export default {
1200
+ env: {
1201
+ humanBehaviorApiKey: process.env.HUMANBEHAVIOR_API_KEY
1202
+ },`);
1203
+ }
1204
+ }
1205
+ injectGatsbyLayout(content) {
1206
+ if (content.includes('HumanBehavior')) {
1207
+ return content;
1208
+ }
1209
+ const importStatement = `import HumanBehavior from './HumanBehavior';`;
1210
+ const componentUsage = `<HumanBehavior apiKey={process.env.GATSBY_HUMANBEHAVIOR_API_KEY || ''} />`;
1211
+ // Add import at the top
1212
+ let modifiedContent = content.replace(/import.*from.*['"]\./, `${importStatement}\n$&`);
1213
+ // Add component before closing body tag
1214
+ modifiedContent = modifiedContent.replace(/(\s*<\/body>)/, `\n ${componentUsage}\n$1`);
1215
+ return modifiedContent;
1216
+ }
1217
+ injectGatsbyBrowser(content) {
1218
+ if (content.includes('HumanBehaviorTracker')) {
1219
+ return content;
1220
+ }
1221
+ const importStatement = `import { HumanBehaviorTracker } from 'humanbehavior-js';`;
1222
+ const initCode = `
1223
+ // Initialize HumanBehavior SDK
1224
+ export const onClientEntry = () => {
1225
+ console.log('Gatsby browser entry point loaded');
1226
+ const apiKey = process.env.GATSBY_HUMANBEHAVIOR_API_KEY;
1227
+ console.log('API Key found:', apiKey ? 'Yes' : 'No');
1228
+ if (apiKey) {
1229
+ const tracker = HumanBehaviorTracker.init(apiKey);
1230
+ console.log('HumanBehavior SDK initialized for Gatsby');
1231
+ } else {
1232
+ console.log('No API key found in environment variables');
1233
+ }
1234
+ };`;
1235
+ // If the file already has content, add the import and init code
1236
+ if (content.trim()) {
1237
+ return `${importStatement}${initCode}\n\n${content}`;
1238
+ }
1239
+ else {
1240
+ // If file is empty, just return the new content
1241
+ return `${importStatement}${initCode}`;
1242
+ }
878
1243
  }
879
1244
  /**
880
1245
  * Helper method to find the best environment file for a framework
@@ -905,6 +1270,8 @@ if (typeof window !== 'undefined') {
905
1270
  nuxt: 'NUXT_PUBLIC_HUMANBEHAVIOR_API_KEY',
906
1271
  remix: 'HUMANBEHAVIOR_API_KEY',
907
1272
  vanilla: 'HUMANBEHAVIOR_API_KEY',
1273
+ astro: 'PUBLIC_HUMANBEHAVIOR_API_KEY',
1274
+ gatsby: 'GATSBY_HUMANBEHAVIOR_API_KEY',
908
1275
  node: 'HUMANBEHAVIOR_API_KEY',
909
1276
  auto: 'HUMANBEHAVIOR_API_KEY'
910
1277
  };
@@ -928,6 +1295,8 @@ if (typeof window !== 'undefined') {
928
1295
  nuxt: '.env',
929
1296
  remix: '.env.local',
930
1297
  vanilla: '.env',
1298
+ astro: '.env',
1299
+ gatsby: '.env.development',
931
1300
  node: '.env',
932
1301
  auto: '.env'
933
1302
  };
@@ -942,6 +1311,8 @@ if (typeof window !== 'undefined') {
942
1311
  */
943
1312
  createEnvironmentModification(framework) {
944
1313
  const { filePath, envVarName } = this.findBestEnvFile(framework);
1314
+ // Clean the API key to prevent formatting issues
1315
+ const cleanApiKey = this.apiKey.trim();
945
1316
  if (fs.existsSync(filePath)) {
946
1317
  // Check if the variable already exists
947
1318
  const content = fs.readFileSync(filePath, 'utf8');
@@ -959,7 +1330,7 @@ if (typeof window !== 'undefined') {
959
1330
  return {
960
1331
  filePath,
961
1332
  action: 'append',
962
- content: `\n${envVarName}=${this.apiKey}`,
1333
+ content: `\n${envVarName}=${cleanApiKey}`,
963
1334
  description: `Added API key to existing ${path.basename(filePath)}`
964
1335
  };
965
1336
  }
@@ -969,309 +1340,13 @@ if (typeof window !== 'undefined') {
969
1340
  return {
970
1341
  filePath,
971
1342
  action: 'create',
972
- content: `${envVarName}=${this.apiKey}`,
1343
+ content: `${envVarName}=${cleanApiKey}`,
973
1344
  description: `Created ${path.basename(filePath)} with API key`
974
1345
  };
975
1346
  }
976
1347
  }
977
1348
  }
978
1349
 
979
- /**
980
- * AI-Enhanced HumanBehavior SDK Auto-Installation Wizard
981
- *
982
- * This wizard uses AI to intelligently detect frameworks, analyze code patterns,
983
- * and generate optimal integration code that's both future-proof and backward-compatible.
984
- *
985
- * 🚀 KEY FEATURES:
986
- * - AI-powered framework detection beyond package.json
987
- * - Intelligent code pattern analysis
988
- * - Future-proof integration strategies
989
- * - Backward compatibility with legacy frameworks
990
- * - Adaptive code generation for new frameworks
991
- * - Smart conflict resolution
992
- * - Learning from user feedback
993
- * - Centralized AI service (no user API keys required)
994
- */
995
- /**
996
- * Default AI Service Implementation
997
- * Uses heuristic analysis when centralized service is not available
998
- */
999
- class DefaultAIService {
1000
- analyzeCodePatterns(codeSamples) {
1001
- return __awaiter(this, void 0, void 0, function* () {
1002
- return this.analyzeWithHeuristics(codeSamples);
1003
- });
1004
- }
1005
- resolveConflicts(conflicts, framework) {
1006
- return __awaiter(this, void 0, void 0, function* () {
1007
- // Default conflict resolution strategies
1008
- const resolutions = [];
1009
- for (const conflict of conflicts) {
1010
- switch (conflict) {
1011
- case 'existing_humanbehavior_code':
1012
- resolutions.push('update_existing_integration');
1013
- break;
1014
- case 'existing_provider':
1015
- resolutions.push('merge_providers');
1016
- break;
1017
- case 'module_system_conflict':
1018
- resolutions.push('hybrid_module_support');
1019
- break;
1020
- default:
1021
- resolutions.push('skip_conflict');
1022
- }
1023
- }
1024
- return resolutions;
1025
- });
1026
- }
1027
- generateOptimizations(framework, patterns) {
1028
- return __awaiter(this, void 0, void 0, function* () {
1029
- const optimizations = [];
1030
- // Framework-specific optimizations
1031
- switch (framework.type) {
1032
- case 'react':
1033
- optimizations.push('Use React.memo for performance optimization');
1034
- optimizations.push('Implement error boundaries for better error tracking');
1035
- optimizations.push('Consider using React.lazy for code splitting');
1036
- break;
1037
- case 'vue':
1038
- optimizations.push('Use Vue 3 Composition API for better performance');
1039
- optimizations.push('Implement proper error handling in components');
1040
- optimizations.push('Consider using Vue Router for navigation tracking');
1041
- break;
1042
- case 'angular':
1043
- optimizations.push('Use Angular standalone components for better tree-shaking');
1044
- optimizations.push('Implement proper error handling with ErrorHandler');
1045
- optimizations.push('Consider using Angular signals for state management');
1046
- break;
1047
- default:
1048
- optimizations.push('Enable performance tracking');
1049
- optimizations.push('Implement error tracking');
1050
- optimizations.push('Consider progressive enhancement');
1051
- }
1052
- return optimizations;
1053
- });
1054
- }
1055
- analyzeWithHeuristics(codeSamples) {
1056
- const patterns = codeSamples.join(' ').toLowerCase();
1057
- // Framework detection
1058
- let framework = { name: 'vanilla', type: 'vanilla' };
1059
- let confidence = 0.5;
1060
- if (patterns.includes('nuxt') || patterns.includes('nuxtjs') || patterns.includes('defineNuxtConfig') || patterns.includes('nuxt.config') || patterns.includes('@nuxt/') || patterns.includes('useNuxtApp') || patterns.includes('useRuntimeConfig') || patterns.includes('useSeoMeta') || patterns.includes('useHead') || patterns.includes('useLazyFetch') || patterns.includes('useFetch') || patterns.includes('useAsyncData') || patterns.includes('#app')) {
1061
- framework = { name: 'nuxt', type: 'nuxt' };
1062
- confidence = 0.95;
1063
- }
1064
- else if (patterns.includes('next') || patterns.includes('nextjs') || patterns.includes('next/link') || patterns.includes('next/image') || patterns.includes('next/navigation') || patterns.includes('next/router') || patterns.includes('getserverSideProps') || patterns.includes('getstaticProps') || patterns.includes('getstaticPaths') || patterns.includes('app/layout') || patterns.includes('app/page') || patterns.includes('pages/')) {
1065
- framework = { name: 'nextjs', type: 'nextjs' };
1066
- confidence = 0.95;
1067
- }
1068
- else if (patterns.includes('react')) {
1069
- framework = { name: 'react', type: 'react' };
1070
- confidence = 0.9;
1071
- }
1072
- else if (patterns.includes('vue')) {
1073
- framework = { name: 'vue', type: 'vue' };
1074
- confidence = 0.9;
1075
- }
1076
- else if (patterns.includes('angular')) {
1077
- framework = { name: 'angular', type: 'angular' };
1078
- confidence = 0.9;
1079
- }
1080
- else if (patterns.includes('svelte')) {
1081
- framework = { name: 'svelte', type: 'svelte' };
1082
- confidence = 0.9;
1083
- }
1084
- // Integration strategy
1085
- let integrationStrategy = 'script';
1086
- if (framework.type === 'react' || framework.type === 'nextjs') {
1087
- integrationStrategy = 'provider';
1088
- }
1089
- else if (framework.type === 'vue') {
1090
- integrationStrategy = 'plugin';
1091
- }
1092
- else if (framework.type === 'angular') {
1093
- integrationStrategy = 'module';
1094
- }
1095
- // Compatibility mode
1096
- let compatibilityMode = 'modern';
1097
- if (patterns.includes('require(') || patterns.includes('var ')) {
1098
- compatibilityMode = 'legacy';
1099
- }
1100
- return {
1101
- framework,
1102
- confidence,
1103
- patterns: codeSamples,
1104
- conflicts: [],
1105
- recommendations: [],
1106
- integrationStrategy,
1107
- compatibilityMode
1108
- };
1109
- }
1110
- }
1111
- /**
1112
- * Browser-based AI installation wizard
1113
- */
1114
- class AIBrowserInstallationWizard {
1115
- constructor(apiKey, aiService) {
1116
- this.apiKey = apiKey;
1117
- this.aiService = aiService || new DefaultAIService();
1118
- }
1119
- install() {
1120
- return __awaiter(this, void 0, void 0, function* () {
1121
- try {
1122
- // AI-powered browser detection
1123
- const aiAnalysis = yield this.performBrowserAIAnalysis();
1124
- // Generate AI-optimized browser modifications
1125
- const modifications = this.generateAIBrowserModifications(aiAnalysis);
1126
- return {
1127
- success: true,
1128
- framework: aiAnalysis.framework,
1129
- modifications,
1130
- errors: [],
1131
- nextSteps: [
1132
- '✅ AI-optimized browser integration ready!',
1133
- `🎯 Framework detected: ${aiAnalysis.framework.name}`,
1134
- `🔧 Integration strategy: ${aiAnalysis.integrationStrategy}`,
1135
- '📋 Copy the generated code to your project',
1136
- '🚀 Your app will be ready to track user behavior'
1137
- ],
1138
- aiAnalysis,
1139
- learningData: {
1140
- patterns: aiAnalysis.patterns,
1141
- framework: aiAnalysis.framework.name,
1142
- success: true
1143
- }
1144
- };
1145
- }
1146
- catch (error) {
1147
- return {
1148
- success: false,
1149
- framework: { name: 'unknown', type: 'vanilla' },
1150
- modifications: [],
1151
- errors: [error instanceof Error ? error.message : 'Unknown error'],
1152
- nextSteps: [],
1153
- aiAnalysis: {
1154
- framework: { name: 'unknown', type: 'vanilla' },
1155
- confidence: 0,
1156
- patterns: [],
1157
- conflicts: [],
1158
- recommendations: [],
1159
- integrationStrategy: 'script',
1160
- compatibilityMode: 'legacy'
1161
- },
1162
- learningData: {
1163
- patterns: [],
1164
- framework: 'unknown',
1165
- success: false
1166
- }
1167
- };
1168
- }
1169
- });
1170
- }
1171
- performBrowserAIAnalysis() {
1172
- return __awaiter(this, void 0, void 0, function* () {
1173
- // Browser-based framework detection
1174
- this.detectBrowserFramework();
1175
- // Analyze browser environment
1176
- const patterns = this.analyzeBrowserPatterns();
1177
- // Use centralized AI service for analysis
1178
- const codeSamples = [`Browser Environment: ${patterns.join(', ')}`];
1179
- return yield this.aiService.analyzeCodePatterns(codeSamples);
1180
- });
1181
- }
1182
- detectBrowserFramework() {
1183
- if (typeof window !== 'undefined') {
1184
- if (window.React) {
1185
- return { name: 'react', type: 'react' };
1186
- }
1187
- if (window.Vue) {
1188
- return { name: 'vue', type: 'vue' };
1189
- }
1190
- if (window.angular) {
1191
- return { name: 'angular', type: 'angular' };
1192
- }
1193
- }
1194
- return { name: 'vanilla', type: 'vanilla' };
1195
- }
1196
- analyzeBrowserPatterns() {
1197
- const patterns = [];
1198
- if (typeof window !== 'undefined') {
1199
- // Analyze global objects
1200
- if (window.React)
1201
- patterns.push('React global detected');
1202
- if (window.Vue)
1203
- patterns.push('Vue global detected');
1204
- if (window.angular)
1205
- patterns.push('Angular global detected');
1206
- // Analyze DOM patterns
1207
- if (document.querySelector('[data-reactroot]'))
1208
- patterns.push('React DOM detected');
1209
- if (document.querySelector('[data-vue]'))
1210
- patterns.push('Vue DOM detected');
1211
- // Analyze script patterns
1212
- const scripts = document.querySelectorAll('script');
1213
- scripts.forEach(script => {
1214
- if (script.src.includes('react'))
1215
- patterns.push('React script detected');
1216
- if (script.src.includes('vue'))
1217
- patterns.push('Vue script detected');
1218
- });
1219
- }
1220
- return patterns;
1221
- }
1222
- generateAIBrowserModifications(aiAnalysis) {
1223
- const modifications = [];
1224
- switch (aiAnalysis.framework.type) {
1225
- case 'react':
1226
- modifications.push({
1227
- filePath: 'App.jsx',
1228
- action: 'create',
1229
- content: `// AI-Optimized React Integration
1230
- import { HumanBehaviorProvider } from 'humanbehavior-js/react';
1231
-
1232
- function App() {
1233
- return (
1234
- <HumanBehaviorProvider
1235
- apiKey="${this.apiKey}"
1236
- config={{
1237
- // AI-generated optimizations
1238
- enablePerformanceTracking: true,
1239
- enableErrorTracking: true,
1240
- framework: '${aiAnalysis.framework.name}',
1241
- integrationStrategy: '${aiAnalysis.integrationStrategy}'
1242
- }}
1243
- >
1244
- {/* Your app components */}
1245
- </HumanBehaviorProvider>
1246
- );
1247
- }
1248
-
1249
- export default App;`,
1250
- description: 'AI-optimized React component with HumanBehaviorProvider'
1251
- });
1252
- break;
1253
- default:
1254
- modifications.push({
1255
- filePath: 'humanbehavior-init.js',
1256
- action: 'create',
1257
- content: `// AI-Optimized Vanilla JS Integration
1258
- import { HumanBehaviorTracker } from 'humanbehavior-js';
1259
-
1260
- const tracker = HumanBehaviorTracker.init('${this.apiKey}', {
1261
- // AI-generated configuration
1262
- framework: '${aiAnalysis.framework.name}',
1263
- integrationStrategy: '${aiAnalysis.integrationStrategy}',
1264
- compatibilityMode: '${aiAnalysis.compatibilityMode}',
1265
- enablePerformanceTracking: true,
1266
- enableErrorTracking: true
1267
- });`,
1268
- description: 'AI-optimized vanilla JS initialization'
1269
- });
1270
- }
1271
- return modifications;
1272
- }
1273
- }
1274
-
1275
1350
  /**
1276
1351
  * Remote AI Service Implementation
1277
1352
  *
@@ -1375,6 +1450,10 @@ class RemoteAIService {
1375
1450
  framework = { name: 'nextjs', type: 'nextjs' };
1376
1451
  confidence = 0.95;
1377
1452
  }
1453
+ else if (patterns.includes('gatsby') || patterns.includes('gatsby-browser') || patterns.includes('gatsby-ssr') || patterns.includes('gatsby-node') || patterns.includes('gatsby-config') || patterns.includes('useStaticQuery') || patterns.includes('graphql')) {
1454
+ framework = { name: 'gatsby', type: 'gatsby' };
1455
+ confidence = 0.95;
1456
+ }
1378
1457
  else if (patterns.includes('react')) {
1379
1458
  framework = { name: 'react', type: 'react' };
1380
1459
  confidence = 0.9;
@@ -1391,9 +1470,13 @@ class RemoteAIService {
1391
1470
  framework = { name: 'svelte', type: 'svelte' };
1392
1471
  confidence = 0.9;
1393
1472
  }
1473
+ else if (patterns.includes('astro')) {
1474
+ framework = { name: 'astro', type: 'astro' };
1475
+ confidence = 0.9;
1476
+ }
1394
1477
  // Integration strategy
1395
1478
  let integrationStrategy = 'script';
1396
- if (framework.type === 'react' || framework.type === 'nextjs') {
1479
+ if (framework.type === 'react' || framework.type === 'nextjs' || framework.type === 'gatsby') {
1397
1480
  integrationStrategy = 'provider';
1398
1481
  }
1399
1482
  else if (framework.type === 'vue') {
@@ -1636,6 +1719,8 @@ class ManualFrameworkInstallationWizard extends AutoInstallationWizard {
1636
1719
  'svelte': { name: 'svelte', type: 'svelte' },
1637
1720
  'sveltekit': { name: 'svelte', type: 'svelte' },
1638
1721
  'remix': { name: 'remix', type: 'remix' },
1722
+ 'astro': { name: 'astro', type: 'astro' },
1723
+ 'gatsby': { name: 'gatsby', type: 'gatsby' },
1639
1724
  'vanilla': { name: 'vanilla', type: 'vanilla' },
1640
1725
  'node': { name: 'node', type: 'node' },
1641
1726
  'auto': { name: 'auto-detected', type: 'auto' }
@@ -1695,67 +1780,46 @@ class ManualFrameworkInstallationWizard extends AutoInstallationWizard {
1695
1780
  class AIAutoInstallCLI {
1696
1781
  constructor(options) {
1697
1782
  this.options = options;
1698
- this.rl = readline.createInterface({
1699
- input: process.stdin,
1700
- output: process.stdout
1701
- });
1702
1783
  }
1703
1784
  run() {
1704
1785
  return __awaiter(this, void 0, void 0, function* () {
1705
- console.log('🤖 AI-Enhanced HumanBehavior SDK Auto-Installation');
1706
- console.log('================================================\n');
1786
+ clack.intro('🤖 AI-Enhanced HumanBehavior SDK Auto-Installation');
1707
1787
  try {
1708
1788
  // Get API key
1709
1789
  const apiKey = yield this.getApiKey();
1710
1790
  if (!apiKey) {
1711
- console.error('API key is required');
1791
+ clack.cancel('API key is required');
1712
1792
  process.exit(1);
1713
1793
  }
1714
1794
  // Get project path
1715
1795
  const projectPath = this.options.projectPath || process.cwd();
1716
- // Choose installation mode
1717
- const installationMode = yield this.chooseInstallationMode();
1796
+ // Choose framework
1797
+ const framework = yield this.chooseFramework();
1798
+ if (!framework) {
1799
+ clack.cancel('Installation cancelled.');
1800
+ process.exit(0);
1801
+ }
1718
1802
  // Confirm installation
1719
1803
  if (!this.options.yes) {
1720
- const confirmed = yield this.confirmInstallation(projectPath, installationMode);
1804
+ const confirmed = yield this.confirmInstallation(projectPath, framework);
1721
1805
  if (!confirmed) {
1722
- console.log('Installation cancelled.');
1806
+ clack.cancel('Installation cancelled.');
1723
1807
  process.exit(0);
1724
1808
  }
1725
1809
  }
1726
1810
  // Run installation
1727
- console.log('🔍 Analyzing your project with AI...');
1728
- let result;
1729
- if (this.options.browser) {
1730
- const wizard = new AIBrowserInstallationWizard(apiKey);
1731
- result = yield wizard.install();
1732
- }
1733
- else if (installationMode === 'manual') {
1734
- // Manual AI-Enhanced framework selection
1735
- const framework = yield this.chooseFramework();
1736
- const wizard = new ManualFrameworkInstallationWizard(apiKey, projectPath, framework);
1737
- result = yield wizard.install();
1738
- }
1739
- else if (installationMode.startsWith('manual:')) {
1740
- // Manual framework selection with pre-selected framework
1741
- const framework = installationMode.split(':')[1];
1742
- const wizard = new ManualFrameworkInstallationWizard(apiKey, projectPath, framework);
1743
- result = yield wizard.install();
1744
- }
1745
- else {
1746
- const wizard = new AutoInstallationWizard(apiKey, projectPath);
1747
- result = yield wizard.install();
1748
- }
1811
+ const spinner = clack.spinner();
1812
+ spinner.start('🔍 Analyzing your project with AI...');
1813
+ const wizard = new ManualFrameworkInstallationWizard(apiKey, projectPath, framework);
1814
+ const result = yield wizard.install();
1815
+ spinner.stop('Analysis complete!');
1749
1816
  // Display results
1750
- this.displayResults(result, installationMode);
1817
+ this.displayResults(result, framework);
1751
1818
  }
1752
1819
  catch (error) {
1753
- console.error('❌ Error:', error instanceof Error ? error.message : error);
1820
+ clack.cancel(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
1754
1821
  process.exit(1);
1755
1822
  }
1756
- finally {
1757
- this.rl.close();
1758
- }
1759
1823
  });
1760
1824
  }
1761
1825
  getApiKey() {
@@ -1763,262 +1827,143 @@ class AIAutoInstallCLI {
1763
1827
  if (this.options.apiKey) {
1764
1828
  return this.options.apiKey;
1765
1829
  }
1766
- return new Promise((resolve) => {
1767
- this.rl.question('Enter your HumanBehavior API key: ', (answer) => {
1768
- resolve(answer.trim());
1769
- });
1770
- });
1771
- });
1772
- }
1773
- chooseInstallationMode() {
1774
- return __awaiter(this, void 0, void 0, function* () {
1775
- if (this.options.manual && this.options.framework) {
1776
- return `manual:${this.options.framework}`;
1777
- }
1778
- if (this.options.useAI !== undefined) {
1779
- return this.options.useAI ? 'ai' : 'traditional';
1780
- }
1781
- console.log('🤖 Choose installation mode:');
1782
- console.log('1. Manual AI-Enhanced (recommended) - Choose your framework and use AI for optimization');
1783
- console.log('2. Traditional - Standard framework detection and installation');
1784
- console.log('3. Browser - Browser-based AI detection and code generation\n');
1785
- return new Promise((resolve) => {
1786
- this.rl.question('Select mode (1-3, default: 1): ', (answer) => {
1787
- const choice = answer.trim() || '1';
1788
- if (choice === '1')
1789
- resolve('manual');
1790
- else if (choice === '2')
1791
- resolve('traditional');
1792
- else if (choice === '3')
1793
- resolve('browser');
1794
- else
1795
- resolve('manual');
1796
- });
1830
+ const apiKey = yield clack.text({
1831
+ message: 'Enter your HumanBehavior API key:',
1832
+ placeholder: 'hb_...',
1833
+ validate: (value) => {
1834
+ if (!value)
1835
+ return 'API key is required';
1836
+ if (!value.startsWith('hb_'))
1837
+ return 'API key should start with "hb_"';
1838
+ return undefined;
1839
+ }
1797
1840
  });
1841
+ return apiKey;
1798
1842
  });
1799
1843
  }
1800
- confirmInstallation(projectPath, installationMode) {
1844
+ confirmInstallation(projectPath, framework) {
1801
1845
  return __awaiter(this, void 0, void 0, function* () {
1802
- console.log(`📁 Project path: ${projectPath}`);
1803
- console.log(`🤖 Installation mode: ${this.getInstallationModeDisplay(installationMode)}`);
1804
- console.log('⚠️ This will modify your codebase to integrate HumanBehavior SDK.');
1805
- console.log(' The following changes will be made:');
1806
- console.log(' - Install humanbehavior-js package');
1807
- console.log(' - Analyze code patterns with AI (if enabled)');
1808
- console.log(' - Modify your main app file');
1809
- console.log(' - Create environment files');
1810
- console.log(' - Add AI-optimized SDK initialization code\n');
1811
- return new Promise((resolve) => {
1812
- this.rl.question('Continue with installation? (y/n): ', (answer) => {
1813
- resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
1814
- });
1846
+ const confirmed = yield clack.confirm({
1847
+ message: `Ready to install HumanBehavior SDK in ${projectPath} for ${framework}?`
1815
1848
  });
1849
+ return confirmed;
1816
1850
  });
1817
1851
  }
1818
- getInstallationModeDisplay(mode) {
1819
- if (mode === 'manual')
1820
- return 'Manual AI-Enhanced';
1821
- if (mode === 'traditional')
1822
- return 'Traditional';
1823
- if (mode.startsWith('manual:')) {
1824
- const framework = mode.split(':')[1];
1825
- return `Manual AI-Enhanced (${framework})`;
1826
- }
1827
- if (mode === 'browser')
1828
- return 'Browser';
1829
- return 'Unknown';
1830
- }
1831
1852
  chooseFramework() {
1832
1853
  return __awaiter(this, void 0, void 0, function* () {
1833
- console.log('\n🎯 Choose your framework:');
1834
- console.log('1. Vanilla JS (HTML)');
1835
- console.log('2. React');
1836
- console.log('3. Next.js');
1837
- console.log('4. Vue');
1838
- console.log('5. Nuxt');
1839
- console.log('6. Angular');
1840
- console.log('7. Svelte');
1841
- console.log('8. Remix');
1842
- console.log('9. Node.js');
1843
- console.log('10. Other (Auto-detect)\n');
1844
- return new Promise((resolve) => {
1845
- this.rl.question('Select framework (1-10, default: 1): ', (answer) => {
1846
- const choice = answer.trim() || '1';
1847
- const frameworks = ['vanilla', 'react', 'nextjs', 'vue', 'nuxt', 'angular', 'svelte', 'remix', 'node', 'auto'];
1848
- const index = parseInt(choice) - 1;
1849
- resolve(frameworks[index] || 'vanilla');
1850
- });
1854
+ const framework = yield clack.select({
1855
+ message: 'Select your framework:',
1856
+ options: [
1857
+ { label: 'React', value: 'react' },
1858
+ { label: 'Next.js', value: 'nextjs' },
1859
+ { label: 'Vue', value: 'vue' },
1860
+ { label: 'Angular', value: 'angular' },
1861
+ { label: 'Svelte', value: 'svelte' },
1862
+ { label: 'Nuxt.js', value: 'nuxt' },
1863
+ { label: 'Remix', value: 'remix' },
1864
+ { label: 'Astro', value: 'astro' },
1865
+ { label: 'Gatsby', value: 'gatsby' },
1866
+ { label: 'Vanilla JS/TS', value: 'vanilla' }
1867
+ ]
1851
1868
  });
1869
+ return framework;
1852
1870
  });
1853
1871
  }
1854
- displayResults(result, installationMode) {
1872
+ displayResults(result, framework) {
1855
1873
  if (result.success) {
1856
- console.log('\n✅ Installation completed successfully!');
1857
- if (installationMode === 'ai' && result.aiAnalysis) {
1858
- console.log(`🎯 AI Analysis Results:`);
1859
- console.log(` Framework: ${result.aiAnalysis.framework.name} (confidence: ${Math.round(result.aiAnalysis.confidence * 100)}%)`);
1860
- console.log(` Integration Strategy: ${result.aiAnalysis.integrationStrategy}`);
1861
- console.log(` Compatibility Mode: ${result.aiAnalysis.compatibilityMode}`);
1862
- if (result.aiAnalysis.patterns.length > 0) {
1863
- console.log(` Detected Patterns: ${result.aiAnalysis.patterns.length} patterns`);
1864
- }
1865
- if (result.aiAnalysis.recommendations.length > 0) {
1866
- console.log(` AI Recommendations:`);
1867
- result.aiAnalysis.recommendations.forEach((rec) => {
1868
- console.log(` • ${rec}`);
1869
- });
1874
+ clack.outro('🎉 Installation completed successfully!');
1875
+ // Display framework info
1876
+ clack.note(`Framework detected: ${result.framework.name} (${result.framework.type})`, 'Framework Info');
1877
+ // Display modifications
1878
+ if (result.modifications && result.modifications.length > 0) {
1879
+ const modifications = result.modifications.map((mod) => `${mod.action}: ${mod.filePath} - ${mod.description}`);
1880
+ clack.note(modifications.join('\n'), 'Files Modified');
1881
+ }
1882
+ // Display next steps
1883
+ if (result.nextSteps && result.nextSteps.length > 0) {
1884
+ clack.note(result.nextSteps.join('\n'), 'Next Steps');
1885
+ }
1886
+ // Display AI insights if available
1887
+ if (result.aiAnalysis) {
1888
+ clack.note(`Confidence: ${Math.round(result.aiAnalysis.confidence * 100)}%`, 'AI Analysis');
1889
+ if (result.aiAnalysis.recommendations && result.aiAnalysis.recommendations.length > 0) {
1890
+ clack.note(result.aiAnalysis.recommendations.join('\n'), 'AI Recommendations');
1870
1891
  }
1871
1892
  }
1872
- else {
1873
- console.log(`📦 Framework detected: ${result.framework.name}`);
1874
- }
1875
- if (result.framework.bundler) {
1876
- console.log(`🔧 Bundler: ${result.framework.bundler}`);
1877
- }
1878
- if (result.framework.packageManager) {
1879
- console.log(`📋 Package Manager: ${result.framework.packageManager}`);
1880
- }
1881
- console.log('\n📝 Changes made:');
1882
- result.modifications.forEach((mod) => {
1883
- console.log(` ${mod.action === 'create' ? '➕' : '✏️'} ${mod.description}`);
1884
- console.log(` ${mod.filePath}`);
1885
- });
1886
- console.log('\n🎯 Next steps:');
1887
- result.nextSteps.forEach((step) => {
1888
- console.log(` ${step}`);
1889
- });
1890
- if (installationMode === 'ai' && result.learningData) {
1891
- console.log('\n🧠 Learning Data:');
1892
- console.log(` Framework: ${result.learningData.framework}`);
1893
- console.log(` Patterns: ${result.learningData.patterns.length} detected`);
1894
- console.log(` Success: ${result.learningData.success ? 'Yes' : 'No'}`);
1895
- }
1896
- console.log('\n🚀 Your app is now ready to track user behavior!');
1897
- console.log('📊 View sessions in your HumanBehavior dashboard');
1898
1893
  }
1899
1894
  else {
1900
- console.log('\n❌ Installation failed:');
1901
- result.errors.forEach((error) => {
1902
- console.log(` ${error}`);
1903
- });
1904
- console.log('\n💡 Try running with --help for more options');
1895
+ clack.cancel('Installation failed');
1896
+ if (result.errors && result.errors.length > 0) {
1897
+ clack.note(result.errors.join('\n'), 'Errors');
1898
+ }
1905
1899
  }
1906
1900
  }
1907
1901
  }
1908
- // CLI argument parsing
1909
1902
  function parseArgs() {
1910
1903
  const args = process.argv.slice(2);
1911
1904
  const options = {};
1912
1905
  for (let i = 0; i < args.length; i++) {
1913
1906
  const arg = args[i];
1914
- if (arg === '--yes' || arg === '-y') {
1915
- options.yes = true;
1916
- }
1917
- else if (arg === '--dry-run' || arg === '-d') {
1918
- options.dryRun = true;
1919
- }
1920
- else if (arg === '--project' || arg === '-p') {
1921
- options.projectPath = args[i + 1];
1922
- i++;
1923
- }
1924
- else if (arg === '--traditional' || arg === '-t') {
1925
- options.useAI = false;
1926
- }
1927
- else if (arg === '--browser' || arg === '-b') {
1928
- options.browser = true;
1929
- }
1930
- else if (arg === '--manual' || arg === '-m') {
1931
- options.manual = true;
1932
- }
1933
- else if (arg === '--framework' || arg === '-f') {
1934
- options.framework = args[i + 1];
1935
- i++;
1936
- }
1937
- else if (arg === '--help' || arg === '-h') {
1938
- showHelp();
1939
- process.exit(0);
1940
- }
1941
- else if (!options.apiKey) {
1942
- options.apiKey = arg;
1907
+ switch (arg) {
1908
+ case '--help':
1909
+ case '-h':
1910
+ showHelp();
1911
+ process.exit(0);
1912
+ break;
1913
+ case '--yes':
1914
+ case '-y':
1915
+ options.yes = true;
1916
+ break;
1917
+ case '--dry-run':
1918
+ options.dryRun = true;
1919
+ break;
1920
+ case '--project':
1921
+ case '-p':
1922
+ options.projectPath = args[++i];
1923
+ break;
1924
+ case '--framework':
1925
+ case '-f':
1926
+ options.framework = args[++i];
1927
+ break;
1928
+ default:
1929
+ if (!options.apiKey && !arg.startsWith('-')) {
1930
+ options.apiKey = arg;
1931
+ }
1932
+ break;
1943
1933
  }
1944
1934
  }
1945
1935
  return options;
1946
1936
  }
1947
1937
  function showHelp() {
1948
1938
  console.log(`
1949
- AI-Enhanced HumanBehavior SDK Auto-Installation CLI
1939
+ 🤖 HumanBehavior SDK AI Auto-Installation
1950
1940
 
1951
1941
  Usage: npx humanbehavior-js ai-auto-install [api-key] [options]
1952
1942
 
1953
- This tool uses AI to intelligently detect frameworks, analyze code patterns,
1954
- and generate optimal integration code that's both future-proof and backward-compatible.
1955
-
1956
- Arguments:
1957
- api-key Your HumanBehavior API key
1958
-
1959
1943
  Options:
1960
- -y, --yes Skip all prompts and use defaults
1961
- -d, --dry-run Show what would be changed without making changes
1962
- -p, --project <path> Project directory (default: current directory)
1963
- -t, --traditional Force traditional installation mode
1964
- -b, --browser Browser-based AI installation
1965
- -m, --manual Manual framework selection
1966
- -f, --framework <f> Specify framework for manual mode
1967
- -h, --help Show this help message
1944
+ -h, --help Show this help message
1945
+ -y, --yes Skip all prompts and use defaults
1946
+ --dry-run Show what would be changed without making changes
1968
1947
 
1969
- Installation Modes:
1970
- 1. Manual AI-Enhanced (default): Choose your framework and use AI for optimization
1971
- 2. Traditional: Standard framework detection and installation
1972
- 3. Browser: Browser-based AI detection and code generation
1948
+ -p, --project <path> Specify project directory
1949
+ -f, --framework <name> Specify framework manually
1973
1950
 
1974
1951
  Examples:
1975
- npx humanbehavior-js ai-auto-install your-api-key
1976
- npx humanbehavior-js ai-auto-install your-api-key --manual --framework react
1977
- npx humanbehavior-js ai-auto-install your-api-key --traditional
1978
- npx humanbehavior-js ai-auto-install your-api-key --browser
1979
-
1980
- Supported Frameworks:
1981
- ✅ React (CRA, Vite, Webpack)
1982
- ✅ Next.js (App Router, Pages Router)
1983
- ✅ Vue (Vue CLI, Vite)
1984
- ✅ Angular
1985
- ✅ Svelte (SvelteKit, Vite)
1986
- ✅ Remix
1987
- ✅ Vanilla JS/TS
1988
- ✅ Node.js (CommonJS & ESM)
1989
-
1990
- AI Features:
1991
- 🔍 Intelligent framework detection beyond package.json
1992
- 📊 Code pattern analysis and optimization
1993
- 🔄 Future-proof integration strategies
1994
- 🔙 Backward compatibility with legacy frameworks
1995
- 🧠 Learning from installation patterns
1996
- ⚡ Adaptive code generation for new frameworks
1997
- 🔧 Smart conflict resolution
1998
- 📈 Performance optimization recommendations
1999
-
2000
- The AI-enhanced tool will:
2001
- 1. 🔍 Analyze your codebase with AI to detect patterns
2002
- 2. 🎯 Determine optimal integration strategy
2003
- 3. 📦 Install the humanbehavior-js package
2004
- 4. ✏️ Generate AI-optimized integration code
2005
- 5. 🔧 Apply modifications with conflict resolution
2006
- 6. 🧠 Learn from the installation for future improvements
2007
- 7. 🚀 Make your app ready to track user behavior
1952
+ npx humanbehavior-js ai-auto-install
1953
+ npx humanbehavior-js ai-auto-install hb_your_api_key_here
1954
+ npx humanbehavior-js ai-auto-install --project ./my-app --ai
1955
+ npx humanbehavior-js ai-auto-install --framework react --yes
2008
1956
  `);
2009
1957
  }
2010
1958
  // Main execution
2011
- const options = parseArgs();
2012
- // Check if we have enough arguments (api-key is required)
2013
- if (process.argv.length < 3 || process.argv.includes('--help') || process.argv.includes('-h')) {
2014
- showHelp();
2015
- process.exit(0);
1959
+ if (import.meta.url === `file://${process.argv[1]}`) {
1960
+ const options = parseArgs();
1961
+ const cli = new AIAutoInstallCLI(options);
1962
+ cli.run().catch((error) => {
1963
+ clack.cancel(`Unexpected error: ${error.message}`);
1964
+ process.exit(1);
1965
+ });
2016
1966
  }
2017
- const cli = new AIAutoInstallCLI(options);
2018
- cli.run().catch((error) => {
2019
- console.error('❌ Fatal error:', error);
2020
- process.exit(1);
2021
- });
2022
1967
 
2023
1968
  export { AIAutoInstallCLI };
2024
1969
  //# sourceMappingURL=ai-auto-install.js.map