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.
- package/dist/cjs/install-wizard.cjs +396 -25
- package/dist/cjs/install-wizard.cjs.map +1 -1
- package/dist/cjs/wizard/index.cjs +633 -395
- package/dist/cjs/wizard/index.cjs.map +1 -1
- package/dist/cli/ai-auto-install.cjs +57161 -0
- package/dist/cli/ai-auto-install.cjs.map +1 -0
- package/dist/cli/ai-auto-install.js +520 -575
- package/dist/cli/ai-auto-install.js.map +1 -1
- package/dist/cli/auto-install.cjs +56352 -0
- package/dist/cli/auto-install.cjs.map +1 -0
- package/dist/cli/auto-install.js +925 -140
- package/dist/cli/auto-install.js.map +1 -1
- package/dist/esm/install-wizard.js +396 -25
- package/dist/esm/install-wizard.js.map +1 -1
- package/dist/esm/wizard/index.js +631 -394
- package/dist/esm/wizard/index.js.map +1 -1
- package/dist/types/install-wizard.d.ts +31 -1
- package/dist/types/wizard/index.d.ts +44 -10
- package/package.json +3 -1
- package/rollup.config.js +5 -1
- package/src/types/clack.d.ts +31 -0
- package/src/wizard/ai/ai-install-wizard.ts +4 -1
- package/src/wizard/ai/manual-framework-wizard.ts +2 -0
- package/src/wizard/cli/ai-auto-install.ts +122 -248
- package/src/wizard/cli/auto-install.ts +116 -117
- package/src/wizard/core/install-wizard.ts +498 -60
- package/src/wizard/services/centralized-ai-service.ts +1 -1
- package/src/wizard/services/remote-ai-service.ts +18 -2
- package/tsconfig.json +1 -1
package/dist/esm/wizard/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
-
import * as
|
|
3
|
+
import * as clack from '@clack/prompts';
|
|
4
4
|
|
|
5
5
|
/******************************************************************************
|
|
6
6
|
Copyright (c) Microsoft Corporation.
|
|
@@ -46,6 +46,28 @@ class AutoInstallationWizard {
|
|
|
46
46
|
this.apiKey = apiKey;
|
|
47
47
|
this.projectRoot = projectRoot;
|
|
48
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Simple version comparison utility
|
|
51
|
+
*/
|
|
52
|
+
compareVersions(version1, version2) {
|
|
53
|
+
const v1Parts = version1.split('.').map(Number);
|
|
54
|
+
const v2Parts = version2.split('.').map(Number);
|
|
55
|
+
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
|
|
56
|
+
const v1 = v1Parts[i] || 0;
|
|
57
|
+
const v2 = v2Parts[i] || 0;
|
|
58
|
+
if (v1 > v2)
|
|
59
|
+
return 1;
|
|
60
|
+
if (v1 < v2)
|
|
61
|
+
return -1;
|
|
62
|
+
}
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
isVersionGte(version, target) {
|
|
66
|
+
return this.compareVersions(version, target) >= 0;
|
|
67
|
+
}
|
|
68
|
+
getMajorVersion(version) {
|
|
69
|
+
return parseInt(version.split('.')[0]) || 0;
|
|
70
|
+
}
|
|
49
71
|
/**
|
|
50
72
|
* Main installation method - detects framework and auto-installs
|
|
51
73
|
*/
|
|
@@ -95,73 +117,146 @@ class AutoInstallationWizard {
|
|
|
95
117
|
}
|
|
96
118
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
97
119
|
const dependencies = Object.assign(Object.assign({}, packageJson.dependencies), packageJson.devDependencies);
|
|
98
|
-
// Detect framework
|
|
120
|
+
// Detect framework with version information
|
|
99
121
|
let framework = {
|
|
100
122
|
name: 'vanilla',
|
|
101
123
|
type: 'vanilla',
|
|
102
|
-
projectRoot: this.projectRoot
|
|
124
|
+
projectRoot: this.projectRoot,
|
|
125
|
+
features: {}
|
|
103
126
|
};
|
|
104
127
|
if (dependencies.nuxt) {
|
|
128
|
+
const nuxtVersion = dependencies.nuxt;
|
|
129
|
+
const isNuxt3 = this.isVersionGte(nuxtVersion, '3.0.0');
|
|
105
130
|
framework = {
|
|
106
131
|
name: 'nuxt',
|
|
107
132
|
type: 'nuxt',
|
|
133
|
+
version: nuxtVersion,
|
|
134
|
+
majorVersion: this.getMajorVersion(nuxtVersion),
|
|
108
135
|
hasTypeScript: !!dependencies.typescript,
|
|
109
136
|
hasRouter: true,
|
|
110
|
-
projectRoot: this.projectRoot
|
|
137
|
+
projectRoot: this.projectRoot,
|
|
138
|
+
features: {
|
|
139
|
+
hasNuxt3: isNuxt3
|
|
140
|
+
}
|
|
111
141
|
};
|
|
112
142
|
}
|
|
113
143
|
else if (dependencies.next) {
|
|
144
|
+
const nextVersion = dependencies.next;
|
|
145
|
+
const isNext13 = this.isVersionGte(nextVersion, '13.0.0');
|
|
114
146
|
framework = {
|
|
115
147
|
name: 'nextjs',
|
|
116
148
|
type: 'nextjs',
|
|
149
|
+
version: nextVersion,
|
|
150
|
+
majorVersion: this.getMajorVersion(nextVersion),
|
|
117
151
|
hasTypeScript: !!dependencies.typescript || !!dependencies['@types/node'],
|
|
118
152
|
hasRouter: true,
|
|
119
|
-
projectRoot: this.projectRoot
|
|
153
|
+
projectRoot: this.projectRoot,
|
|
154
|
+
features: {
|
|
155
|
+
hasNextAppRouter: isNext13
|
|
156
|
+
}
|
|
120
157
|
};
|
|
121
158
|
}
|
|
122
159
|
else if (dependencies['@remix-run/react'] || dependencies['@remix-run/dev']) {
|
|
160
|
+
const remixVersion = dependencies['@remix-run/react'] || dependencies['@remix-run/dev'];
|
|
123
161
|
framework = {
|
|
124
162
|
name: 'remix',
|
|
125
163
|
type: 'remix',
|
|
164
|
+
version: remixVersion,
|
|
165
|
+
majorVersion: this.getMajorVersion(remixVersion),
|
|
126
166
|
hasTypeScript: !!dependencies.typescript || !!dependencies['@types/react'],
|
|
127
167
|
hasRouter: true,
|
|
128
|
-
projectRoot: this.projectRoot
|
|
168
|
+
projectRoot: this.projectRoot,
|
|
169
|
+
features: {}
|
|
129
170
|
};
|
|
130
171
|
}
|
|
131
172
|
else if (dependencies.react) {
|
|
173
|
+
const reactVersion = dependencies.react;
|
|
174
|
+
const isReact18 = this.isVersionGte(reactVersion, '18.0.0');
|
|
132
175
|
framework = {
|
|
133
176
|
name: 'react',
|
|
134
177
|
type: 'react',
|
|
178
|
+
version: reactVersion,
|
|
179
|
+
majorVersion: this.getMajorVersion(reactVersion),
|
|
135
180
|
hasTypeScript: !!dependencies.typescript || !!dependencies['@types/react'],
|
|
136
181
|
hasRouter: !!dependencies['react-router-dom'] || !!dependencies['react-router'],
|
|
137
|
-
projectRoot: this.projectRoot
|
|
182
|
+
projectRoot: this.projectRoot,
|
|
183
|
+
features: {
|
|
184
|
+
hasReact18: isReact18
|
|
185
|
+
}
|
|
138
186
|
};
|
|
139
187
|
}
|
|
140
188
|
else if (dependencies.vue) {
|
|
189
|
+
const vueVersion = dependencies.vue;
|
|
190
|
+
const isVue3 = this.isVersionGte(vueVersion, '3.0.0');
|
|
141
191
|
framework = {
|
|
142
192
|
name: 'vue',
|
|
143
193
|
type: 'vue',
|
|
194
|
+
version: vueVersion,
|
|
195
|
+
majorVersion: this.getMajorVersion(vueVersion),
|
|
144
196
|
hasTypeScript: !!dependencies.typescript || !!dependencies['@vue/cli-service'],
|
|
145
197
|
hasRouter: !!dependencies['vue-router'],
|
|
146
|
-
projectRoot: this.projectRoot
|
|
198
|
+
projectRoot: this.projectRoot,
|
|
199
|
+
features: {
|
|
200
|
+
hasVue3: isVue3
|
|
201
|
+
}
|
|
147
202
|
};
|
|
148
203
|
}
|
|
149
204
|
else if (dependencies['@angular/core']) {
|
|
205
|
+
const angularVersion = dependencies['@angular/core'];
|
|
206
|
+
const isAngular17 = this.isVersionGte(angularVersion, '17.0.0');
|
|
150
207
|
framework = {
|
|
151
208
|
name: 'angular',
|
|
152
209
|
type: 'angular',
|
|
210
|
+
version: angularVersion,
|
|
211
|
+
majorVersion: this.getMajorVersion(angularVersion),
|
|
153
212
|
hasTypeScript: true,
|
|
154
213
|
hasRouter: true,
|
|
155
|
-
projectRoot: this.projectRoot
|
|
214
|
+
projectRoot: this.projectRoot,
|
|
215
|
+
features: {
|
|
216
|
+
hasAngularStandalone: isAngular17
|
|
217
|
+
}
|
|
156
218
|
};
|
|
157
219
|
}
|
|
158
220
|
else if (dependencies.svelte) {
|
|
221
|
+
const svelteVersion = dependencies.svelte;
|
|
222
|
+
const isSvelteKit = !!dependencies['@sveltejs/kit'];
|
|
159
223
|
framework = {
|
|
160
224
|
name: 'svelte',
|
|
161
225
|
type: 'svelte',
|
|
226
|
+
version: svelteVersion,
|
|
227
|
+
majorVersion: this.getMajorVersion(svelteVersion),
|
|
162
228
|
hasTypeScript: !!dependencies.typescript || !!dependencies['svelte-check'],
|
|
163
229
|
hasRouter: !!dependencies['svelte-routing'] || !!dependencies['@sveltejs/kit'],
|
|
164
|
-
projectRoot: this.projectRoot
|
|
230
|
+
projectRoot: this.projectRoot,
|
|
231
|
+
features: {
|
|
232
|
+
hasSvelteKit: isSvelteKit
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
else if (dependencies.astro) {
|
|
237
|
+
const astroVersion = dependencies.astro;
|
|
238
|
+
framework = {
|
|
239
|
+
name: 'astro',
|
|
240
|
+
type: 'astro',
|
|
241
|
+
version: astroVersion,
|
|
242
|
+
majorVersion: this.getMajorVersion(astroVersion),
|
|
243
|
+
hasTypeScript: !!dependencies.typescript || !!dependencies['@astrojs/ts-plugin'],
|
|
244
|
+
hasRouter: true,
|
|
245
|
+
projectRoot: this.projectRoot,
|
|
246
|
+
features: {}
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
else if (dependencies.gatsby) {
|
|
250
|
+
const gatsbyVersion = dependencies.gatsby;
|
|
251
|
+
framework = {
|
|
252
|
+
name: 'gatsby',
|
|
253
|
+
type: 'gatsby',
|
|
254
|
+
version: gatsbyVersion,
|
|
255
|
+
majorVersion: this.getMajorVersion(gatsbyVersion),
|
|
256
|
+
hasTypeScript: !!dependencies.typescript || !!dependencies['@types/react'],
|
|
257
|
+
hasRouter: true,
|
|
258
|
+
projectRoot: this.projectRoot,
|
|
259
|
+
features: {}
|
|
165
260
|
};
|
|
166
261
|
}
|
|
167
262
|
// Detect bundler
|
|
@@ -195,13 +290,18 @@ class AutoInstallationWizard {
|
|
|
195
290
|
*/
|
|
196
291
|
installPackage() {
|
|
197
292
|
return __awaiter(this, void 0, void 0, function* () {
|
|
198
|
-
var _a, _b;
|
|
293
|
+
var _a, _b, _c, _d;
|
|
199
294
|
const { execSync } = yield import('child_process');
|
|
200
|
-
|
|
295
|
+
// Build base command
|
|
296
|
+
let command = ((_a = this.framework) === null || _a === void 0 ? void 0 : _a.packageManager) === 'yarn'
|
|
201
297
|
? 'yarn add humanbehavior-js'
|
|
202
298
|
: ((_b = this.framework) === null || _b === void 0 ? void 0 : _b.packageManager) === 'pnpm'
|
|
203
299
|
? 'pnpm add humanbehavior-js'
|
|
204
300
|
: 'npm install humanbehavior-js';
|
|
301
|
+
// Add legacy peer deps flag for npm to handle dependency conflicts
|
|
302
|
+
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') {
|
|
303
|
+
command += ' --legacy-peer-deps';
|
|
304
|
+
}
|
|
205
305
|
try {
|
|
206
306
|
execSync(command, { cwd: this.projectRoot, stdio: 'inherit' });
|
|
207
307
|
}
|
|
@@ -227,6 +327,12 @@ class AutoInstallationWizard {
|
|
|
227
327
|
case 'nuxt':
|
|
228
328
|
modifications.push(...yield this.generateNuxtModifications());
|
|
229
329
|
break;
|
|
330
|
+
case 'astro':
|
|
331
|
+
modifications.push(...yield this.generateAstroModifications());
|
|
332
|
+
break;
|
|
333
|
+
case 'gatsby':
|
|
334
|
+
modifications.push(...yield this.generateGatsbyModifications());
|
|
335
|
+
break;
|
|
230
336
|
case 'remix':
|
|
231
337
|
modifications.push(...yield this.generateRemixModifications());
|
|
232
338
|
break;
|
|
@@ -338,6 +444,84 @@ export function Providers({ children }: { children: React.ReactNode }) {
|
|
|
338
444
|
return modifications;
|
|
339
445
|
});
|
|
340
446
|
}
|
|
447
|
+
/**
|
|
448
|
+
* Generate Astro-specific modifications
|
|
449
|
+
*/
|
|
450
|
+
generateAstroModifications() {
|
|
451
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
452
|
+
const modifications = [];
|
|
453
|
+
// Create Astro component for HumanBehavior
|
|
454
|
+
const astroComponentPath = path.join(this.projectRoot, 'src', 'components', 'HumanBehavior.astro');
|
|
455
|
+
const astroComponentContent = `---
|
|
456
|
+
// This component will only run on the client side
|
|
457
|
+
---
|
|
458
|
+
|
|
459
|
+
<script>
|
|
460
|
+
import { HumanBehaviorTracker } from 'humanbehavior-js';
|
|
461
|
+
|
|
462
|
+
// Get API key from environment variable
|
|
463
|
+
const apiKey = import.meta.env.PUBLIC_HUMANBEHAVIOR_API_KEY;
|
|
464
|
+
|
|
465
|
+
console.log('HumanBehavior: API key found:', apiKey ? 'Yes' : 'No');
|
|
466
|
+
|
|
467
|
+
if (apiKey) {
|
|
468
|
+
try {
|
|
469
|
+
const tracker = HumanBehaviorTracker.init(apiKey);
|
|
470
|
+
console.log('HumanBehavior: Tracker initialized successfully');
|
|
471
|
+
|
|
472
|
+
// Test event to verify tracking is working
|
|
473
|
+
setTimeout(() => {
|
|
474
|
+
tracker.customEvent('astro_page_view', {
|
|
475
|
+
page: window.location.pathname,
|
|
476
|
+
framework: 'astro'
|
|
477
|
+
}).then(() => {
|
|
478
|
+
console.log('HumanBehavior: Test event sent successfully');
|
|
479
|
+
}).catch((error) => {
|
|
480
|
+
console.error('HumanBehavior: Failed to send test event:', error);
|
|
481
|
+
});
|
|
482
|
+
}, 1000);
|
|
483
|
+
|
|
484
|
+
} catch (error) {
|
|
485
|
+
console.error('HumanBehavior: Failed to initialize tracker:', error);
|
|
486
|
+
}
|
|
487
|
+
} else {
|
|
488
|
+
console.error('HumanBehavior: No API key found');
|
|
489
|
+
}
|
|
490
|
+
</script>`;
|
|
491
|
+
modifications.push({
|
|
492
|
+
filePath: astroComponentPath,
|
|
493
|
+
action: 'create',
|
|
494
|
+
content: astroComponentContent,
|
|
495
|
+
description: 'Created Astro component for HumanBehavior SDK'
|
|
496
|
+
});
|
|
497
|
+
// Find and update layout file
|
|
498
|
+
const layoutFiles = [
|
|
499
|
+
path.join(this.projectRoot, 'src', 'layouts', 'Layout.astro'),
|
|
500
|
+
path.join(this.projectRoot, 'src', 'layouts', 'layout.astro'),
|
|
501
|
+
path.join(this.projectRoot, 'src', 'layouts', 'BaseLayout.astro')
|
|
502
|
+
];
|
|
503
|
+
let layoutFile = null;
|
|
504
|
+
for (const file of layoutFiles) {
|
|
505
|
+
if (fs.existsSync(file)) {
|
|
506
|
+
layoutFile = file;
|
|
507
|
+
break;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
if (layoutFile) {
|
|
511
|
+
const content = fs.readFileSync(layoutFile, 'utf8');
|
|
512
|
+
const modifiedContent = this.injectAstroLayout(content);
|
|
513
|
+
modifications.push({
|
|
514
|
+
filePath: layoutFile,
|
|
515
|
+
action: 'modify',
|
|
516
|
+
content: modifiedContent,
|
|
517
|
+
description: 'Added HumanBehavior component to Astro layout'
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
// Add environment variable
|
|
521
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
522
|
+
return modifications;
|
|
523
|
+
});
|
|
524
|
+
}
|
|
341
525
|
/**
|
|
342
526
|
* Generate Nuxt-specific modifications
|
|
343
527
|
*/
|
|
@@ -558,6 +742,50 @@ export default defineNuxtPlugin(() => {
|
|
|
558
742
|
return modifications;
|
|
559
743
|
});
|
|
560
744
|
}
|
|
745
|
+
/**
|
|
746
|
+
* Generate Gatsby-specific modifications
|
|
747
|
+
*/
|
|
748
|
+
generateGatsbyModifications() {
|
|
749
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
750
|
+
const modifications = [];
|
|
751
|
+
// Modify or create gatsby-browser.js for Gatsby
|
|
752
|
+
const gatsbyBrowserFile = path.join(this.projectRoot, 'gatsby-browser.js');
|
|
753
|
+
if (fs.existsSync(gatsbyBrowserFile)) {
|
|
754
|
+
const content = fs.readFileSync(gatsbyBrowserFile, 'utf8');
|
|
755
|
+
const modifiedContent = this.injectGatsbyBrowser(content);
|
|
756
|
+
modifications.push({
|
|
757
|
+
filePath: gatsbyBrowserFile,
|
|
758
|
+
action: 'modify',
|
|
759
|
+
content: modifiedContent,
|
|
760
|
+
description: 'Added HumanBehavior initialization to Gatsby browser'
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
else {
|
|
764
|
+
// Create gatsby-browser.js if it doesn't exist
|
|
765
|
+
modifications.push({
|
|
766
|
+
filePath: gatsbyBrowserFile,
|
|
767
|
+
action: 'create',
|
|
768
|
+
content: `import { HumanBehaviorTracker } from 'humanbehavior-js';
|
|
769
|
+
|
|
770
|
+
export const onClientEntry = () => {
|
|
771
|
+
console.log('Gatsby browser entry point loaded');
|
|
772
|
+
const apiKey = process.env.GATSBY_HUMANBEHAVIOR_API_KEY;
|
|
773
|
+
console.log('API Key found:', apiKey ? 'Yes' : 'No');
|
|
774
|
+
if (apiKey) {
|
|
775
|
+
const tracker = HumanBehaviorTracker.init(apiKey);
|
|
776
|
+
console.log('HumanBehavior SDK initialized for Gatsby');
|
|
777
|
+
} else {
|
|
778
|
+
console.log('No API key found in environment variables');
|
|
779
|
+
}
|
|
780
|
+
};`,
|
|
781
|
+
description: 'Created gatsby-browser.js with HumanBehavior initialization'
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
// Create or append to environment file
|
|
785
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
786
|
+
return modifications;
|
|
787
|
+
});
|
|
788
|
+
}
|
|
561
789
|
/**
|
|
562
790
|
* Apply modifications to the codebase
|
|
563
791
|
*/
|
|
@@ -652,7 +880,7 @@ export default defineNuxtPlugin(() => {
|
|
|
652
880
|
return null;
|
|
653
881
|
}
|
|
654
882
|
injectReactProvider(content, filePath) {
|
|
655
|
-
var _a;
|
|
883
|
+
var _a, _b, _c;
|
|
656
884
|
filePath.endsWith('.tsx') || filePath.endsWith('.ts');
|
|
657
885
|
// Check if already has HumanBehaviorProvider
|
|
658
886
|
if (content.includes('HumanBehaviorProvider')) {
|
|
@@ -664,14 +892,39 @@ export default defineNuxtPlugin(() => {
|
|
|
664
892
|
? 'import.meta.env.VITE_HUMANBEHAVIOR_API_KEY!'
|
|
665
893
|
: 'process.env.HUMANBEHAVIOR_API_KEY!';
|
|
666
894
|
const importStatement = `import { HumanBehaviorProvider } from 'humanbehavior-js/react';`;
|
|
667
|
-
//
|
|
895
|
+
// Enhanced parsing for React 18+ features
|
|
896
|
+
const hasReact18 = (_c = (_b = this.framework) === null || _b === void 0 ? void 0 : _b.features) === null || _c === void 0 ? void 0 : _c.hasReact18;
|
|
897
|
+
// Handle different React patterns
|
|
668
898
|
if (content.includes('function App()') || content.includes('const App =')) {
|
|
669
|
-
|
|
899
|
+
// Add import statement
|
|
900
|
+
let modifiedContent = content.replace(/(import.*?from.*?['"]react['"];?)/, `$1\n${importStatement}`);
|
|
901
|
+
// If no React import found, add it at the top
|
|
902
|
+
if (!modifiedContent.includes(importStatement)) {
|
|
903
|
+
modifiedContent = `${importStatement}\n\n${modifiedContent}`;
|
|
904
|
+
}
|
|
905
|
+
// Wrap the App component return with HumanBehaviorProvider
|
|
906
|
+
modifiedContent = modifiedContent.replace(/(return\s*\([\s\S]*?\)\s*;)/, `return (
|
|
670
907
|
<HumanBehaviorProvider apiKey={${envVar}}>
|
|
671
908
|
$1
|
|
672
909
|
</HumanBehaviorProvider>
|
|
673
910
|
);`);
|
|
911
|
+
return modifiedContent;
|
|
674
912
|
}
|
|
913
|
+
// Handle React 18+ createRoot pattern
|
|
914
|
+
if (hasReact18 && content.includes('createRoot')) {
|
|
915
|
+
let modifiedContent = content.replace(/(import.*?from.*?['"]react['"];?)/, `$1\n${importStatement}`);
|
|
916
|
+
if (!modifiedContent.includes(importStatement)) {
|
|
917
|
+
modifiedContent = `${importStatement}\n\n${modifiedContent}`;
|
|
918
|
+
}
|
|
919
|
+
// Wrap the root render with HumanBehaviorProvider
|
|
920
|
+
modifiedContent = modifiedContent.replace(/(root\.render\s*\([\s\S]*?\)\s*;)/, `root.render(
|
|
921
|
+
<HumanBehaviorProvider apiKey={${envVar}}>
|
|
922
|
+
$1
|
|
923
|
+
</HumanBehaviorProvider>
|
|
924
|
+
);`);
|
|
925
|
+
return modifiedContent;
|
|
926
|
+
}
|
|
927
|
+
// Fallback: simple injection
|
|
675
928
|
return `${importStatement}\n\n${content}`;
|
|
676
929
|
}
|
|
677
930
|
injectNextJSAppRouter(content) {
|
|
@@ -768,21 +1021,51 @@ export default function App()`);
|
|
|
768
1021
|
return modifiedContent;
|
|
769
1022
|
}
|
|
770
1023
|
injectVuePlugin(content) {
|
|
1024
|
+
var _a, _b;
|
|
771
1025
|
if (content.includes('HumanBehaviorPlugin')) {
|
|
772
1026
|
return content;
|
|
773
1027
|
}
|
|
774
1028
|
const importStatement = `import { HumanBehaviorPlugin } from 'humanbehavior-js/vue';`;
|
|
775
|
-
|
|
1029
|
+
// Enhanced Vue 3 support with version detection
|
|
1030
|
+
const hasVue3 = (_b = (_a = this.framework) === null || _a === void 0 ? void 0 : _a.features) === null || _b === void 0 ? void 0 : _b.hasVue3;
|
|
1031
|
+
if (hasVue3) {
|
|
1032
|
+
// Vue 3 with Composition API
|
|
1033
|
+
const pluginUsage = `app.use(HumanBehaviorPlugin, {
|
|
776
1034
|
apiKey: import.meta.env.VITE_HUMANBEHAVIOR_API_KEY
|
|
777
1035
|
});`;
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
1036
|
+
let modifiedContent = content;
|
|
1037
|
+
// Add import statement
|
|
1038
|
+
if (!content.includes(importStatement)) {
|
|
1039
|
+
modifiedContent = content.replace(/(import.*?from.*?['"]vue['"];?)/, `$1\n${importStatement}`);
|
|
1040
|
+
// If no Vue import found, add it at the top
|
|
1041
|
+
if (!modifiedContent.includes(importStatement)) {
|
|
1042
|
+
modifiedContent = `${importStatement}\n\n${modifiedContent}`;
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
// Handle createApp pattern
|
|
1046
|
+
if (content.includes('createApp')) {
|
|
1047
|
+
modifiedContent = modifiedContent.replace(/(app\.mount\(.*?\))/, `${pluginUsage}\n\n$1`);
|
|
1048
|
+
}
|
|
1049
|
+
return modifiedContent;
|
|
782
1050
|
}
|
|
783
1051
|
else {
|
|
784
|
-
// Vue 2
|
|
785
|
-
|
|
1052
|
+
// Vue 2 with Options API
|
|
1053
|
+
const pluginUsage = `Vue.use(HumanBehaviorPlugin, {
|
|
1054
|
+
apiKey: process.env.VUE_APP_HUMANBEHAVIOR_API_KEY
|
|
1055
|
+
});`;
|
|
1056
|
+
let modifiedContent = content;
|
|
1057
|
+
// Add import statement
|
|
1058
|
+
if (!content.includes(importStatement)) {
|
|
1059
|
+
modifiedContent = content.replace(/(import.*?from.*?['"]vue['"];?)/, `$1\n${importStatement}`);
|
|
1060
|
+
if (!modifiedContent.includes(importStatement)) {
|
|
1061
|
+
modifiedContent = `${importStatement}\n\n${modifiedContent}`;
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
// Handle new Vue pattern
|
|
1065
|
+
if (content.includes('new Vue')) {
|
|
1066
|
+
modifiedContent = modifiedContent.replace(/(new Vue\(.*?\))/, `${pluginUsage}\n\n$1`);
|
|
1067
|
+
}
|
|
1068
|
+
return modifiedContent;
|
|
786
1069
|
}
|
|
787
1070
|
}
|
|
788
1071
|
injectAngularModule(content) {
|
|
@@ -863,17 +1146,99 @@ if (typeof window !== 'undefined') {
|
|
|
863
1146
|
</script>`;
|
|
864
1147
|
return content.replace(/<\/head>/, ` ${cdnScript}\n ${initScript}\n</head>`);
|
|
865
1148
|
}
|
|
1149
|
+
/**
|
|
1150
|
+
* Inject Astro layout with HumanBehavior component
|
|
1151
|
+
*/
|
|
1152
|
+
injectAstroLayout(content) {
|
|
1153
|
+
// Check if HumanBehavior component is already imported
|
|
1154
|
+
if (content.includes('HumanBehavior') || content.includes('humanbehavior-js')) {
|
|
1155
|
+
return content; // Already has HumanBehavior
|
|
1156
|
+
}
|
|
1157
|
+
// Add import inside frontmatter if not present
|
|
1158
|
+
let modifiedContent = content;
|
|
1159
|
+
if (!content.includes('import HumanBehavior')) {
|
|
1160
|
+
const importStatement = 'import HumanBehavior from \'../components/HumanBehavior.astro\';';
|
|
1161
|
+
const frontmatterEndIndex = content.indexOf('---', 3);
|
|
1162
|
+
if (frontmatterEndIndex !== -1) {
|
|
1163
|
+
// Insert import inside frontmatter, before the closing ---
|
|
1164
|
+
modifiedContent = content.slice(0, frontmatterEndIndex) + '\n' + importStatement + '\n' + content.slice(frontmatterEndIndex);
|
|
1165
|
+
}
|
|
1166
|
+
else {
|
|
1167
|
+
// No frontmatter, add at the very beginning
|
|
1168
|
+
modifiedContent = '---\n' + importStatement + '\n---\n\n' + content;
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
// Find the closing </body> tag and add HumanBehavior component before it
|
|
1172
|
+
const bodyCloseIndex = modifiedContent.lastIndexOf('</body>');
|
|
1173
|
+
if (bodyCloseIndex === -1) {
|
|
1174
|
+
// No body tag found, append to end
|
|
1175
|
+
return modifiedContent + '\n\n<HumanBehavior />';
|
|
1176
|
+
}
|
|
1177
|
+
// Add component before closing body tag
|
|
1178
|
+
return modifiedContent.slice(0, bodyCloseIndex) + ' <HumanBehavior />\n' + modifiedContent.slice(bodyCloseIndex);
|
|
1179
|
+
}
|
|
866
1180
|
injectNuxtConfig(content) {
|
|
1181
|
+
var _a, _b;
|
|
867
1182
|
if (content.includes('humanBehaviorApiKey')) {
|
|
868
1183
|
return content;
|
|
869
1184
|
}
|
|
870
|
-
//
|
|
871
|
-
|
|
1185
|
+
// Enhanced Nuxt 3 support with version detection
|
|
1186
|
+
const hasNuxt3 = (_b = (_a = this.framework) === null || _a === void 0 ? void 0 : _a.features) === null || _b === void 0 ? void 0 : _b.hasNuxt3;
|
|
1187
|
+
if (hasNuxt3) {
|
|
1188
|
+
// Nuxt 3 with runtime config
|
|
1189
|
+
return content.replace(/export default defineNuxtConfig\(\{/, `export default defineNuxtConfig({
|
|
872
1190
|
runtimeConfig: {
|
|
873
1191
|
public: {
|
|
874
1192
|
humanBehaviorApiKey: process.env.NUXT_PUBLIC_HUMANBEHAVIOR_API_KEY
|
|
875
1193
|
}
|
|
876
1194
|
},`);
|
|
1195
|
+
}
|
|
1196
|
+
else {
|
|
1197
|
+
// Nuxt 2 with env config
|
|
1198
|
+
return content.replace(/export default \{/, `export default {
|
|
1199
|
+
env: {
|
|
1200
|
+
humanBehaviorApiKey: process.env.HUMANBEHAVIOR_API_KEY
|
|
1201
|
+
},`);
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
injectGatsbyLayout(content) {
|
|
1205
|
+
if (content.includes('HumanBehavior')) {
|
|
1206
|
+
return content;
|
|
1207
|
+
}
|
|
1208
|
+
const importStatement = `import HumanBehavior from './HumanBehavior';`;
|
|
1209
|
+
const componentUsage = `<HumanBehavior apiKey={process.env.GATSBY_HUMANBEHAVIOR_API_KEY || ''} />`;
|
|
1210
|
+
// Add import at the top
|
|
1211
|
+
let modifiedContent = content.replace(/import.*from.*['"]\./, `${importStatement}\n$&`);
|
|
1212
|
+
// Add component before closing body tag
|
|
1213
|
+
modifiedContent = modifiedContent.replace(/(\s*<\/body>)/, `\n ${componentUsage}\n$1`);
|
|
1214
|
+
return modifiedContent;
|
|
1215
|
+
}
|
|
1216
|
+
injectGatsbyBrowser(content) {
|
|
1217
|
+
if (content.includes('HumanBehaviorTracker')) {
|
|
1218
|
+
return content;
|
|
1219
|
+
}
|
|
1220
|
+
const importStatement = `import { HumanBehaviorTracker } from 'humanbehavior-js';`;
|
|
1221
|
+
const initCode = `
|
|
1222
|
+
// Initialize HumanBehavior SDK
|
|
1223
|
+
export const onClientEntry = () => {
|
|
1224
|
+
console.log('Gatsby browser entry point loaded');
|
|
1225
|
+
const apiKey = process.env.GATSBY_HUMANBEHAVIOR_API_KEY;
|
|
1226
|
+
console.log('API Key found:', apiKey ? 'Yes' : 'No');
|
|
1227
|
+
if (apiKey) {
|
|
1228
|
+
const tracker = HumanBehaviorTracker.init(apiKey);
|
|
1229
|
+
console.log('HumanBehavior SDK initialized for Gatsby');
|
|
1230
|
+
} else {
|
|
1231
|
+
console.log('No API key found in environment variables');
|
|
1232
|
+
}
|
|
1233
|
+
};`;
|
|
1234
|
+
// If the file already has content, add the import and init code
|
|
1235
|
+
if (content.trim()) {
|
|
1236
|
+
return `${importStatement}${initCode}\n\n${content}`;
|
|
1237
|
+
}
|
|
1238
|
+
else {
|
|
1239
|
+
// If file is empty, just return the new content
|
|
1240
|
+
return `${importStatement}${initCode}`;
|
|
1241
|
+
}
|
|
877
1242
|
}
|
|
878
1243
|
/**
|
|
879
1244
|
* Helper method to find the best environment file for a framework
|
|
@@ -904,6 +1269,8 @@ if (typeof window !== 'undefined') {
|
|
|
904
1269
|
nuxt: 'NUXT_PUBLIC_HUMANBEHAVIOR_API_KEY',
|
|
905
1270
|
remix: 'HUMANBEHAVIOR_API_KEY',
|
|
906
1271
|
vanilla: 'HUMANBEHAVIOR_API_KEY',
|
|
1272
|
+
astro: 'PUBLIC_HUMANBEHAVIOR_API_KEY',
|
|
1273
|
+
gatsby: 'GATSBY_HUMANBEHAVIOR_API_KEY',
|
|
907
1274
|
node: 'HUMANBEHAVIOR_API_KEY',
|
|
908
1275
|
auto: 'HUMANBEHAVIOR_API_KEY'
|
|
909
1276
|
};
|
|
@@ -927,6 +1294,8 @@ if (typeof window !== 'undefined') {
|
|
|
927
1294
|
nuxt: '.env',
|
|
928
1295
|
remix: '.env.local',
|
|
929
1296
|
vanilla: '.env',
|
|
1297
|
+
astro: '.env',
|
|
1298
|
+
gatsby: '.env.development',
|
|
930
1299
|
node: '.env',
|
|
931
1300
|
auto: '.env'
|
|
932
1301
|
};
|
|
@@ -941,6 +1310,8 @@ if (typeof window !== 'undefined') {
|
|
|
941
1310
|
*/
|
|
942
1311
|
createEnvironmentModification(framework) {
|
|
943
1312
|
const { filePath, envVarName } = this.findBestEnvFile(framework);
|
|
1313
|
+
// Clean the API key to prevent formatting issues
|
|
1314
|
+
const cleanApiKey = this.apiKey.trim();
|
|
944
1315
|
if (fs.existsSync(filePath)) {
|
|
945
1316
|
// Check if the variable already exists
|
|
946
1317
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
@@ -958,7 +1329,7 @@ if (typeof window !== 'undefined') {
|
|
|
958
1329
|
return {
|
|
959
1330
|
filePath,
|
|
960
1331
|
action: 'append',
|
|
961
|
-
content: `\n${envVarName}=${
|
|
1332
|
+
content: `\n${envVarName}=${cleanApiKey}`,
|
|
962
1333
|
description: `Added API key to existing ${path.basename(filePath)}`
|
|
963
1334
|
};
|
|
964
1335
|
}
|
|
@@ -968,7 +1339,7 @@ if (typeof window !== 'undefined') {
|
|
|
968
1339
|
return {
|
|
969
1340
|
filePath,
|
|
970
1341
|
action: 'create',
|
|
971
|
-
content: `${envVarName}=${
|
|
1342
|
+
content: `${envVarName}=${cleanApiKey}`,
|
|
972
1343
|
description: `Created ${path.basename(filePath)} with API key`
|
|
973
1344
|
};
|
|
974
1345
|
}
|
|
@@ -1064,6 +1435,10 @@ class DefaultAIService {
|
|
|
1064
1435
|
framework = { name: 'nextjs', type: 'nextjs' };
|
|
1065
1436
|
confidence = 0.95;
|
|
1066
1437
|
}
|
|
1438
|
+
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')) {
|
|
1439
|
+
framework = { name: 'gatsby', type: 'gatsby' };
|
|
1440
|
+
confidence = 0.95;
|
|
1441
|
+
}
|
|
1067
1442
|
else if (patterns.includes('react')) {
|
|
1068
1443
|
framework = { name: 'react', type: 'react' };
|
|
1069
1444
|
confidence = 0.9;
|
|
@@ -1082,7 +1457,7 @@ class DefaultAIService {
|
|
|
1082
1457
|
}
|
|
1083
1458
|
// Integration strategy
|
|
1084
1459
|
let integrationStrategy = 'script';
|
|
1085
|
-
if (framework.type === 'react' || framework.type === 'nextjs') {
|
|
1460
|
+
if (framework.type === 'react' || framework.type === 'nextjs' || framework.type === 'gatsby') {
|
|
1086
1461
|
integrationStrategy = 'provider';
|
|
1087
1462
|
}
|
|
1088
1463
|
else if (framework.type === 'vue') {
|
|
@@ -1877,6 +2252,10 @@ class RemoteAIService {
|
|
|
1877
2252
|
framework = { name: 'nextjs', type: 'nextjs' };
|
|
1878
2253
|
confidence = 0.95;
|
|
1879
2254
|
}
|
|
2255
|
+
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')) {
|
|
2256
|
+
framework = { name: 'gatsby', type: 'gatsby' };
|
|
2257
|
+
confidence = 0.95;
|
|
2258
|
+
}
|
|
1880
2259
|
else if (patterns.includes('react')) {
|
|
1881
2260
|
framework = { name: 'react', type: 'react' };
|
|
1882
2261
|
confidence = 0.9;
|
|
@@ -1893,9 +2272,13 @@ class RemoteAIService {
|
|
|
1893
2272
|
framework = { name: 'svelte', type: 'svelte' };
|
|
1894
2273
|
confidence = 0.9;
|
|
1895
2274
|
}
|
|
2275
|
+
else if (patterns.includes('astro')) {
|
|
2276
|
+
framework = { name: 'astro', type: 'astro' };
|
|
2277
|
+
confidence = 0.9;
|
|
2278
|
+
}
|
|
1896
2279
|
// Integration strategy
|
|
1897
2280
|
let integrationStrategy = 'script';
|
|
1898
|
-
if (framework.type === 'react' || framework.type === 'nextjs') {
|
|
2281
|
+
if (framework.type === 'react' || framework.type === 'nextjs' || framework.type === 'gatsby') {
|
|
1899
2282
|
integrationStrategy = 'provider';
|
|
1900
2283
|
}
|
|
1901
2284
|
else if (framework.type === 'vue') {
|
|
@@ -2138,6 +2521,8 @@ class ManualFrameworkInstallationWizard extends AutoInstallationWizard {
|
|
|
2138
2521
|
'svelte': { name: 'svelte', type: 'svelte' },
|
|
2139
2522
|
'sveltekit': { name: 'svelte', type: 'svelte' },
|
|
2140
2523
|
'remix': { name: 'remix', type: 'remix' },
|
|
2524
|
+
'astro': { name: 'astro', type: 'astro' },
|
|
2525
|
+
'gatsby': { name: 'gatsby', type: 'gatsby' },
|
|
2141
2526
|
'vanilla': { name: 'vanilla', type: 'vanilla' },
|
|
2142
2527
|
'node': { name: 'node', type: 'node' },
|
|
2143
2528
|
'auto': { name: 'auto-detected', type: 'auto' }
|
|
@@ -2197,67 +2582,46 @@ class ManualFrameworkInstallationWizard extends AutoInstallationWizard {
|
|
|
2197
2582
|
class AIAutoInstallCLI {
|
|
2198
2583
|
constructor(options) {
|
|
2199
2584
|
this.options = options;
|
|
2200
|
-
this.rl = readline.createInterface({
|
|
2201
|
-
input: process.stdin,
|
|
2202
|
-
output: process.stdout
|
|
2203
|
-
});
|
|
2204
2585
|
}
|
|
2205
2586
|
run() {
|
|
2206
2587
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2207
|
-
|
|
2208
|
-
console.log('================================================\n');
|
|
2588
|
+
clack.intro('š¤ AI-Enhanced HumanBehavior SDK Auto-Installation');
|
|
2209
2589
|
try {
|
|
2210
2590
|
// Get API key
|
|
2211
2591
|
const apiKey = yield this.getApiKey();
|
|
2212
2592
|
if (!apiKey) {
|
|
2213
|
-
|
|
2593
|
+
clack.cancel('API key is required');
|
|
2214
2594
|
process.exit(1);
|
|
2215
2595
|
}
|
|
2216
2596
|
// Get project path
|
|
2217
2597
|
const projectPath = this.options.projectPath || process.cwd();
|
|
2218
|
-
// Choose
|
|
2219
|
-
const
|
|
2598
|
+
// Choose framework
|
|
2599
|
+
const framework = yield this.chooseFramework();
|
|
2600
|
+
if (!framework) {
|
|
2601
|
+
clack.cancel('Installation cancelled.');
|
|
2602
|
+
process.exit(0);
|
|
2603
|
+
}
|
|
2220
2604
|
// Confirm installation
|
|
2221
2605
|
if (!this.options.yes) {
|
|
2222
|
-
const confirmed = yield this.confirmInstallation(projectPath,
|
|
2606
|
+
const confirmed = yield this.confirmInstallation(projectPath, framework);
|
|
2223
2607
|
if (!confirmed) {
|
|
2224
|
-
|
|
2608
|
+
clack.cancel('Installation cancelled.');
|
|
2225
2609
|
process.exit(0);
|
|
2226
2610
|
}
|
|
2227
2611
|
}
|
|
2228
2612
|
// Run installation
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
}
|
|
2235
|
-
else if (installationMode === 'manual') {
|
|
2236
|
-
// Manual AI-Enhanced framework selection
|
|
2237
|
-
const framework = yield this.chooseFramework();
|
|
2238
|
-
const wizard = new ManualFrameworkInstallationWizard(apiKey, projectPath, framework);
|
|
2239
|
-
result = yield wizard.install();
|
|
2240
|
-
}
|
|
2241
|
-
else if (installationMode.startsWith('manual:')) {
|
|
2242
|
-
// Manual framework selection with pre-selected framework
|
|
2243
|
-
const framework = installationMode.split(':')[1];
|
|
2244
|
-
const wizard = new ManualFrameworkInstallationWizard(apiKey, projectPath, framework);
|
|
2245
|
-
result = yield wizard.install();
|
|
2246
|
-
}
|
|
2247
|
-
else {
|
|
2248
|
-
const wizard = new AutoInstallationWizard(apiKey, projectPath);
|
|
2249
|
-
result = yield wizard.install();
|
|
2250
|
-
}
|
|
2613
|
+
const spinner = clack.spinner();
|
|
2614
|
+
spinner.start('š Analyzing your project with AI...');
|
|
2615
|
+
const wizard = new ManualFrameworkInstallationWizard(apiKey, projectPath, framework);
|
|
2616
|
+
const result = yield wizard.install();
|
|
2617
|
+
spinner.stop('Analysis complete!');
|
|
2251
2618
|
// Display results
|
|
2252
|
-
this.displayResults(result,
|
|
2619
|
+
this.displayResults(result, framework);
|
|
2253
2620
|
}
|
|
2254
2621
|
catch (error) {
|
|
2255
|
-
|
|
2622
|
+
clack.cancel(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
2256
2623
|
process.exit(1);
|
|
2257
2624
|
}
|
|
2258
|
-
finally {
|
|
2259
|
-
this.rl.close();
|
|
2260
|
-
}
|
|
2261
2625
|
});
|
|
2262
2626
|
}
|
|
2263
2627
|
getApiKey() {
|
|
@@ -2265,262 +2629,143 @@ class AIAutoInstallCLI {
|
|
|
2265
2629
|
if (this.options.apiKey) {
|
|
2266
2630
|
return this.options.apiKey;
|
|
2267
2631
|
}
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
return `manual:${this.options.framework}`;
|
|
2279
|
-
}
|
|
2280
|
-
if (this.options.useAI !== undefined) {
|
|
2281
|
-
return this.options.useAI ? 'ai' : 'traditional';
|
|
2282
|
-
}
|
|
2283
|
-
console.log('š¤ Choose installation mode:');
|
|
2284
|
-
console.log('1. Manual AI-Enhanced (recommended) - Choose your framework and use AI for optimization');
|
|
2285
|
-
console.log('2. Traditional - Standard framework detection and installation');
|
|
2286
|
-
console.log('3. Browser - Browser-based AI detection and code generation\n');
|
|
2287
|
-
return new Promise((resolve) => {
|
|
2288
|
-
this.rl.question('Select mode (1-3, default: 1): ', (answer) => {
|
|
2289
|
-
const choice = answer.trim() || '1';
|
|
2290
|
-
if (choice === '1')
|
|
2291
|
-
resolve('manual');
|
|
2292
|
-
else if (choice === '2')
|
|
2293
|
-
resolve('traditional');
|
|
2294
|
-
else if (choice === '3')
|
|
2295
|
-
resolve('browser');
|
|
2296
|
-
else
|
|
2297
|
-
resolve('manual');
|
|
2298
|
-
});
|
|
2632
|
+
const apiKey = yield clack.text({
|
|
2633
|
+
message: 'Enter your HumanBehavior API key:',
|
|
2634
|
+
placeholder: 'hb_...',
|
|
2635
|
+
validate: (value) => {
|
|
2636
|
+
if (!value)
|
|
2637
|
+
return 'API key is required';
|
|
2638
|
+
if (!value.startsWith('hb_'))
|
|
2639
|
+
return 'API key should start with "hb_"';
|
|
2640
|
+
return undefined;
|
|
2641
|
+
}
|
|
2299
2642
|
});
|
|
2643
|
+
return apiKey;
|
|
2300
2644
|
});
|
|
2301
2645
|
}
|
|
2302
|
-
confirmInstallation(projectPath,
|
|
2646
|
+
confirmInstallation(projectPath, framework) {
|
|
2303
2647
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
console.log('ā ļø This will modify your codebase to integrate HumanBehavior SDK.');
|
|
2307
|
-
console.log(' The following changes will be made:');
|
|
2308
|
-
console.log(' - Install humanbehavior-js package');
|
|
2309
|
-
console.log(' - Analyze code patterns with AI (if enabled)');
|
|
2310
|
-
console.log(' - Modify your main app file');
|
|
2311
|
-
console.log(' - Create environment files');
|
|
2312
|
-
console.log(' - Add AI-optimized SDK initialization code\n');
|
|
2313
|
-
return new Promise((resolve) => {
|
|
2314
|
-
this.rl.question('Continue with installation? (y/n): ', (answer) => {
|
|
2315
|
-
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
2316
|
-
});
|
|
2648
|
+
const confirmed = yield clack.confirm({
|
|
2649
|
+
message: `Ready to install HumanBehavior SDK in ${projectPath} for ${framework}?`
|
|
2317
2650
|
});
|
|
2651
|
+
return confirmed;
|
|
2318
2652
|
});
|
|
2319
2653
|
}
|
|
2320
|
-
getInstallationModeDisplay(mode) {
|
|
2321
|
-
if (mode === 'manual')
|
|
2322
|
-
return 'Manual AI-Enhanced';
|
|
2323
|
-
if (mode === 'traditional')
|
|
2324
|
-
return 'Traditional';
|
|
2325
|
-
if (mode.startsWith('manual:')) {
|
|
2326
|
-
const framework = mode.split(':')[1];
|
|
2327
|
-
return `Manual AI-Enhanced (${framework})`;
|
|
2328
|
-
}
|
|
2329
|
-
if (mode === 'browser')
|
|
2330
|
-
return 'Browser';
|
|
2331
|
-
return 'Unknown';
|
|
2332
|
-
}
|
|
2333
2654
|
chooseFramework() {
|
|
2334
2655
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
const frameworks = ['vanilla', 'react', 'nextjs', 'vue', 'nuxt', 'angular', 'svelte', 'remix', 'node', 'auto'];
|
|
2350
|
-
const index = parseInt(choice) - 1;
|
|
2351
|
-
resolve(frameworks[index] || 'vanilla');
|
|
2352
|
-
});
|
|
2656
|
+
const framework = yield clack.select({
|
|
2657
|
+
message: 'Select your framework:',
|
|
2658
|
+
options: [
|
|
2659
|
+
{ label: 'React', value: 'react' },
|
|
2660
|
+
{ label: 'Next.js', value: 'nextjs' },
|
|
2661
|
+
{ label: 'Vue', value: 'vue' },
|
|
2662
|
+
{ label: 'Angular', value: 'angular' },
|
|
2663
|
+
{ label: 'Svelte', value: 'svelte' },
|
|
2664
|
+
{ label: 'Nuxt.js', value: 'nuxt' },
|
|
2665
|
+
{ label: 'Remix', value: 'remix' },
|
|
2666
|
+
{ label: 'Astro', value: 'astro' },
|
|
2667
|
+
{ label: 'Gatsby', value: 'gatsby' },
|
|
2668
|
+
{ label: 'Vanilla JS/TS', value: 'vanilla' }
|
|
2669
|
+
]
|
|
2353
2670
|
});
|
|
2671
|
+
return framework;
|
|
2354
2672
|
});
|
|
2355
2673
|
}
|
|
2356
|
-
displayResults(result,
|
|
2674
|
+
displayResults(result, framework) {
|
|
2357
2675
|
if (result.success) {
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2676
|
+
clack.outro('š Installation completed successfully!');
|
|
2677
|
+
// Display framework info
|
|
2678
|
+
clack.note(`Framework detected: ${result.framework.name} (${result.framework.type})`, 'Framework Info');
|
|
2679
|
+
// Display modifications
|
|
2680
|
+
if (result.modifications && result.modifications.length > 0) {
|
|
2681
|
+
const modifications = result.modifications.map((mod) => `${mod.action}: ${mod.filePath} - ${mod.description}`);
|
|
2682
|
+
clack.note(modifications.join('\n'), 'Files Modified');
|
|
2683
|
+
}
|
|
2684
|
+
// Display next steps
|
|
2685
|
+
if (result.nextSteps && result.nextSteps.length > 0) {
|
|
2686
|
+
clack.note(result.nextSteps.join('\n'), 'Next Steps');
|
|
2687
|
+
}
|
|
2688
|
+
// Display AI insights if available
|
|
2689
|
+
if (result.aiAnalysis) {
|
|
2690
|
+
clack.note(`Confidence: ${Math.round(result.aiAnalysis.confidence * 100)}%`, 'AI Analysis');
|
|
2691
|
+
if (result.aiAnalysis.recommendations && result.aiAnalysis.recommendations.length > 0) {
|
|
2692
|
+
clack.note(result.aiAnalysis.recommendations.join('\n'), 'AI Recommendations');
|
|
2372
2693
|
}
|
|
2373
2694
|
}
|
|
2374
|
-
else {
|
|
2375
|
-
console.log(`š¦ Framework detected: ${result.framework.name}`);
|
|
2376
|
-
}
|
|
2377
|
-
if (result.framework.bundler) {
|
|
2378
|
-
console.log(`š§ Bundler: ${result.framework.bundler}`);
|
|
2379
|
-
}
|
|
2380
|
-
if (result.framework.packageManager) {
|
|
2381
|
-
console.log(`š Package Manager: ${result.framework.packageManager}`);
|
|
2382
|
-
}
|
|
2383
|
-
console.log('\nš Changes made:');
|
|
2384
|
-
result.modifications.forEach((mod) => {
|
|
2385
|
-
console.log(` ${mod.action === 'create' ? 'ā' : 'āļø'} ${mod.description}`);
|
|
2386
|
-
console.log(` ${mod.filePath}`);
|
|
2387
|
-
});
|
|
2388
|
-
console.log('\nšÆ Next steps:');
|
|
2389
|
-
result.nextSteps.forEach((step) => {
|
|
2390
|
-
console.log(` ${step}`);
|
|
2391
|
-
});
|
|
2392
|
-
if (installationMode === 'ai' && result.learningData) {
|
|
2393
|
-
console.log('\nš§ Learning Data:');
|
|
2394
|
-
console.log(` Framework: ${result.learningData.framework}`);
|
|
2395
|
-
console.log(` Patterns: ${result.learningData.patterns.length} detected`);
|
|
2396
|
-
console.log(` Success: ${result.learningData.success ? 'Yes' : 'No'}`);
|
|
2397
|
-
}
|
|
2398
|
-
console.log('\nš Your app is now ready to track user behavior!');
|
|
2399
|
-
console.log('š View sessions in your HumanBehavior dashboard');
|
|
2400
2695
|
}
|
|
2401
2696
|
else {
|
|
2402
|
-
|
|
2403
|
-
result.errors.
|
|
2404
|
-
|
|
2405
|
-
}
|
|
2406
|
-
console.log('\nš” Try running with --help for more options');
|
|
2697
|
+
clack.cancel('Installation failed');
|
|
2698
|
+
if (result.errors && result.errors.length > 0) {
|
|
2699
|
+
clack.note(result.errors.join('\n'), 'Errors');
|
|
2700
|
+
}
|
|
2407
2701
|
}
|
|
2408
2702
|
}
|
|
2409
2703
|
}
|
|
2410
|
-
// CLI argument parsing
|
|
2411
2704
|
function parseArgs$1() {
|
|
2412
2705
|
const args = process.argv.slice(2);
|
|
2413
2706
|
const options = {};
|
|
2414
2707
|
for (let i = 0; i < args.length; i++) {
|
|
2415
2708
|
const arg = args[i];
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
}
|
|
2443
|
-
else if (!options.apiKey) {
|
|
2444
|
-
options.apiKey = arg;
|
|
2709
|
+
switch (arg) {
|
|
2710
|
+
case '--help':
|
|
2711
|
+
case '-h':
|
|
2712
|
+
showHelp$1();
|
|
2713
|
+
process.exit(0);
|
|
2714
|
+
break;
|
|
2715
|
+
case '--yes':
|
|
2716
|
+
case '-y':
|
|
2717
|
+
options.yes = true;
|
|
2718
|
+
break;
|
|
2719
|
+
case '--dry-run':
|
|
2720
|
+
options.dryRun = true;
|
|
2721
|
+
break;
|
|
2722
|
+
case '--project':
|
|
2723
|
+
case '-p':
|
|
2724
|
+
options.projectPath = args[++i];
|
|
2725
|
+
break;
|
|
2726
|
+
case '--framework':
|
|
2727
|
+
case '-f':
|
|
2728
|
+
options.framework = args[++i];
|
|
2729
|
+
break;
|
|
2730
|
+
default:
|
|
2731
|
+
if (!options.apiKey && !arg.startsWith('-')) {
|
|
2732
|
+
options.apiKey = arg;
|
|
2733
|
+
}
|
|
2734
|
+
break;
|
|
2445
2735
|
}
|
|
2446
2736
|
}
|
|
2447
2737
|
return options;
|
|
2448
2738
|
}
|
|
2449
2739
|
function showHelp$1() {
|
|
2450
2740
|
console.log(`
|
|
2451
|
-
|
|
2741
|
+
š¤ HumanBehavior SDK AI Auto-Installation
|
|
2452
2742
|
|
|
2453
2743
|
Usage: npx humanbehavior-js ai-auto-install [api-key] [options]
|
|
2454
2744
|
|
|
2455
|
-
This tool uses AI to intelligently detect frameworks, analyze code patterns,
|
|
2456
|
-
and generate optimal integration code that's both future-proof and backward-compatible.
|
|
2457
|
-
|
|
2458
|
-
Arguments:
|
|
2459
|
-
api-key Your HumanBehavior API key
|
|
2460
|
-
|
|
2461
2745
|
Options:
|
|
2462
|
-
-
|
|
2463
|
-
-
|
|
2464
|
-
-
|
|
2465
|
-
-t, --traditional Force traditional installation mode
|
|
2466
|
-
-b, --browser Browser-based AI installation
|
|
2467
|
-
-m, --manual Manual framework selection
|
|
2468
|
-
-f, --framework <f> Specify framework for manual mode
|
|
2469
|
-
-h, --help Show this help message
|
|
2746
|
+
-h, --help Show this help message
|
|
2747
|
+
-y, --yes Skip all prompts and use defaults
|
|
2748
|
+
--dry-run Show what would be changed without making changes
|
|
2470
2749
|
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
2. Traditional: Standard framework detection and installation
|
|
2474
|
-
3. Browser: Browser-based AI detection and code generation
|
|
2750
|
+
-p, --project <path> Specify project directory
|
|
2751
|
+
-f, --framework <name> Specify framework manually
|
|
2475
2752
|
|
|
2476
2753
|
Examples:
|
|
2477
|
-
npx humanbehavior-js ai-auto-install
|
|
2478
|
-
npx humanbehavior-js ai-auto-install
|
|
2479
|
-
npx humanbehavior-js ai-auto-install
|
|
2480
|
-
npx humanbehavior-js ai-auto-install
|
|
2481
|
-
|
|
2482
|
-
Supported Frameworks:
|
|
2483
|
-
ā
React (CRA, Vite, Webpack)
|
|
2484
|
-
ā
Next.js (App Router, Pages Router)
|
|
2485
|
-
ā
Vue (Vue CLI, Vite)
|
|
2486
|
-
ā
Angular
|
|
2487
|
-
ā
Svelte (SvelteKit, Vite)
|
|
2488
|
-
ā
Remix
|
|
2489
|
-
ā
Vanilla JS/TS
|
|
2490
|
-
ā
Node.js (CommonJS & ESM)
|
|
2491
|
-
|
|
2492
|
-
AI Features:
|
|
2493
|
-
š Intelligent framework detection beyond package.json
|
|
2494
|
-
š Code pattern analysis and optimization
|
|
2495
|
-
š Future-proof integration strategies
|
|
2496
|
-
š Backward compatibility with legacy frameworks
|
|
2497
|
-
š§ Learning from installation patterns
|
|
2498
|
-
ā” Adaptive code generation for new frameworks
|
|
2499
|
-
š§ Smart conflict resolution
|
|
2500
|
-
š Performance optimization recommendations
|
|
2501
|
-
|
|
2502
|
-
The AI-enhanced tool will:
|
|
2503
|
-
1. š Analyze your codebase with AI to detect patterns
|
|
2504
|
-
2. šÆ Determine optimal integration strategy
|
|
2505
|
-
3. š¦ Install the humanbehavior-js package
|
|
2506
|
-
4. āļø Generate AI-optimized integration code
|
|
2507
|
-
5. š§ Apply modifications with conflict resolution
|
|
2508
|
-
6. š§ Learn from the installation for future improvements
|
|
2509
|
-
7. š Make your app ready to track user behavior
|
|
2754
|
+
npx humanbehavior-js ai-auto-install
|
|
2755
|
+
npx humanbehavior-js ai-auto-install hb_your_api_key_here
|
|
2756
|
+
npx humanbehavior-js ai-auto-install --project ./my-app --ai
|
|
2757
|
+
npx humanbehavior-js ai-auto-install --framework react --yes
|
|
2510
2758
|
`);
|
|
2511
2759
|
}
|
|
2512
2760
|
// Main execution
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2761
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
2762
|
+
const options = parseArgs$1();
|
|
2763
|
+
const cli = new AIAutoInstallCLI(options);
|
|
2764
|
+
cli.run().catch((error) => {
|
|
2765
|
+
clack.cancel(`Unexpected error: ${error.message}`);
|
|
2766
|
+
process.exit(1);
|
|
2767
|
+
});
|
|
2518
2768
|
}
|
|
2519
|
-
const cli$1 = new AIAutoInstallCLI(options$1);
|
|
2520
|
-
cli$1.run().catch((error) => {
|
|
2521
|
-
console.error('ā Fatal error:', error);
|
|
2522
|
-
process.exit(1);
|
|
2523
|
-
});
|
|
2524
2769
|
|
|
2525
2770
|
/**
|
|
2526
2771
|
* HumanBehavior SDK Auto-Installation CLI
|
|
@@ -2533,46 +2778,46 @@ cli$1.run().catch((error) => {
|
|
|
2533
2778
|
class AutoInstallCLI {
|
|
2534
2779
|
constructor(options) {
|
|
2535
2780
|
this.options = options;
|
|
2536
|
-
this.rl = readline.createInterface({
|
|
2537
|
-
input: process.stdin,
|
|
2538
|
-
output: process.stdout
|
|
2539
|
-
});
|
|
2540
2781
|
}
|
|
2541
2782
|
run() {
|
|
2542
2783
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2543
|
-
|
|
2544
|
-
console.log('=====================================\n');
|
|
2784
|
+
clack.intro('š HumanBehavior SDK Auto-Installation');
|
|
2545
2785
|
try {
|
|
2546
2786
|
// Get API key
|
|
2547
2787
|
const apiKey = yield this.getApiKey();
|
|
2548
2788
|
if (!apiKey) {
|
|
2549
|
-
|
|
2789
|
+
clack.cancel('API key is required');
|
|
2550
2790
|
process.exit(1);
|
|
2551
2791
|
}
|
|
2552
2792
|
// Get project path
|
|
2553
2793
|
const projectPath = this.options.projectPath || process.cwd();
|
|
2794
|
+
// Choose framework
|
|
2795
|
+
const framework = yield this.chooseFramework();
|
|
2796
|
+
if (!framework) {
|
|
2797
|
+
clack.cancel('Installation cancelled.');
|
|
2798
|
+
process.exit(0);
|
|
2799
|
+
}
|
|
2554
2800
|
// Confirm installation
|
|
2555
2801
|
if (!this.options.yes) {
|
|
2556
|
-
const confirmed = yield this.confirmInstallation(projectPath);
|
|
2802
|
+
const confirmed = yield this.confirmInstallation(projectPath, framework);
|
|
2557
2803
|
if (!confirmed) {
|
|
2558
|
-
|
|
2804
|
+
clack.cancel('Installation cancelled.');
|
|
2559
2805
|
process.exit(0);
|
|
2560
2806
|
}
|
|
2561
2807
|
}
|
|
2562
|
-
// Run
|
|
2563
|
-
|
|
2564
|
-
|
|
2808
|
+
// Run installation
|
|
2809
|
+
const spinner = clack.spinner();
|
|
2810
|
+
spinner.start('š Analyzing your project...');
|
|
2811
|
+
const wizard = new ManualFrameworkInstallationWizard(apiKey, projectPath, framework);
|
|
2565
2812
|
const result = yield wizard.install();
|
|
2813
|
+
spinner.stop('Detection complete!');
|
|
2566
2814
|
// Display results
|
|
2567
2815
|
this.displayResults(result);
|
|
2568
2816
|
}
|
|
2569
2817
|
catch (error) {
|
|
2570
|
-
|
|
2818
|
+
clack.cancel(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
2571
2819
|
process.exit(1);
|
|
2572
2820
|
}
|
|
2573
|
-
finally {
|
|
2574
|
-
this.rl.close();
|
|
2575
|
-
}
|
|
2576
2821
|
});
|
|
2577
2822
|
}
|
|
2578
2823
|
getApiKey() {
|
|
@@ -2580,139 +2825,131 @@ class AutoInstallCLI {
|
|
|
2580
2825
|
if (this.options.apiKey) {
|
|
2581
2826
|
return this.options.apiKey;
|
|
2582
2827
|
}
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2828
|
+
const apiKey = yield clack.text({
|
|
2829
|
+
message: 'Enter your HumanBehavior API key:',
|
|
2830
|
+
placeholder: 'hb_...',
|
|
2831
|
+
validate: (value) => {
|
|
2832
|
+
if (!value)
|
|
2833
|
+
return 'API key is required';
|
|
2834
|
+
if (!value.startsWith('hb_'))
|
|
2835
|
+
return 'API key should start with "hb_"';
|
|
2836
|
+
return undefined;
|
|
2837
|
+
}
|
|
2587
2838
|
});
|
|
2839
|
+
return apiKey;
|
|
2588
2840
|
});
|
|
2589
2841
|
}
|
|
2590
|
-
|
|
2842
|
+
chooseFramework() {
|
|
2591
2843
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2844
|
+
const framework = yield clack.select({
|
|
2845
|
+
message: 'Select your framework:',
|
|
2846
|
+
options: [
|
|
2847
|
+
{ label: 'React', value: 'react' },
|
|
2848
|
+
{ label: 'Next.js', value: 'nextjs' },
|
|
2849
|
+
{ label: 'Vue', value: 'vue' },
|
|
2850
|
+
{ label: 'Angular', value: 'angular' },
|
|
2851
|
+
{ label: 'Svelte', value: 'svelte' },
|
|
2852
|
+
{ label: 'Nuxt.js', value: 'nuxt' },
|
|
2853
|
+
{ label: 'Remix', value: 'remix' },
|
|
2854
|
+
{ label: 'Astro', value: 'astro' },
|
|
2855
|
+
{ label: 'Gatsby', value: 'gatsby' },
|
|
2856
|
+
{ label: 'Vanilla JS/TS', value: 'vanilla' }
|
|
2857
|
+
]
|
|
2858
|
+
});
|
|
2859
|
+
return framework;
|
|
2860
|
+
});
|
|
2861
|
+
}
|
|
2862
|
+
confirmInstallation(projectPath, framework) {
|
|
2863
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2864
|
+
const confirmed = yield clack.confirm({
|
|
2865
|
+
message: `Ready to install HumanBehavior SDK in ${projectPath} for ${framework}?`
|
|
2603
2866
|
});
|
|
2867
|
+
return confirmed;
|
|
2604
2868
|
});
|
|
2605
2869
|
}
|
|
2606
2870
|
displayResults(result) {
|
|
2607
2871
|
if (result.success) {
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
}
|
|
2616
|
-
|
|
2617
|
-
result.
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
});
|
|
2621
|
-
console.log('\nšÆ Next steps:');
|
|
2622
|
-
result.nextSteps.forEach((step) => {
|
|
2623
|
-
console.log(` ${step}`);
|
|
2624
|
-
});
|
|
2625
|
-
console.log('\nš Your app is now ready to track user behavior!');
|
|
2626
|
-
console.log('š View sessions in your HumanBehavior dashboard');
|
|
2872
|
+
clack.outro('š Installation completed successfully!');
|
|
2873
|
+
// Display framework info
|
|
2874
|
+
clack.note(`Framework detected: ${result.framework.name} (${result.framework.type})`, 'Framework Info');
|
|
2875
|
+
// Display modifications
|
|
2876
|
+
if (result.modifications && result.modifications.length > 0) {
|
|
2877
|
+
const modifications = result.modifications.map((mod) => `${mod.action}: ${mod.filePath} - ${mod.description}`);
|
|
2878
|
+
clack.note(modifications.join('\n'), 'Files Modified');
|
|
2879
|
+
}
|
|
2880
|
+
// Display next steps
|
|
2881
|
+
if (result.nextSteps && result.nextSteps.length > 0) {
|
|
2882
|
+
clack.note(result.nextSteps.join('\n'), 'Next Steps');
|
|
2883
|
+
}
|
|
2627
2884
|
}
|
|
2628
2885
|
else {
|
|
2629
|
-
|
|
2630
|
-
result.errors.
|
|
2631
|
-
|
|
2632
|
-
}
|
|
2633
|
-
console.log('\nš” Try running with --help for more options');
|
|
2886
|
+
clack.cancel('Installation failed');
|
|
2887
|
+
if (result.errors && result.errors.length > 0) {
|
|
2888
|
+
clack.note(result.errors.join('\n'), 'Errors');
|
|
2889
|
+
}
|
|
2634
2890
|
}
|
|
2635
2891
|
}
|
|
2636
2892
|
}
|
|
2637
|
-
// CLI argument parsing
|
|
2638
2893
|
function parseArgs() {
|
|
2639
2894
|
const args = process.argv.slice(2);
|
|
2640
2895
|
const options = {};
|
|
2641
2896
|
for (let i = 0; i < args.length; i++) {
|
|
2642
2897
|
const arg = args[i];
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2898
|
+
switch (arg) {
|
|
2899
|
+
case '--help':
|
|
2900
|
+
case '-h':
|
|
2901
|
+
showHelp();
|
|
2902
|
+
process.exit(0);
|
|
2903
|
+
break;
|
|
2904
|
+
case '--yes':
|
|
2905
|
+
case '-y':
|
|
2906
|
+
options.yes = true;
|
|
2907
|
+
break;
|
|
2908
|
+
case '--dry-run':
|
|
2909
|
+
options.dryRun = true;
|
|
2910
|
+
break;
|
|
2911
|
+
case '--project':
|
|
2912
|
+
case '-p':
|
|
2913
|
+
options.projectPath = args[++i];
|
|
2914
|
+
break;
|
|
2915
|
+
default:
|
|
2916
|
+
if (!options.apiKey && !arg.startsWith('-')) {
|
|
2917
|
+
options.apiKey = arg;
|
|
2918
|
+
}
|
|
2919
|
+
break;
|
|
2659
2920
|
}
|
|
2660
2921
|
}
|
|
2661
2922
|
return options;
|
|
2662
2923
|
}
|
|
2663
2924
|
function showHelp() {
|
|
2664
2925
|
console.log(`
|
|
2665
|
-
HumanBehavior SDK Auto-Installation
|
|
2926
|
+
š HumanBehavior SDK Auto-Installation
|
|
2666
2927
|
|
|
2667
|
-
Usage: npx humanbehavior-js [api-key] [options]
|
|
2928
|
+
Usage: npx humanbehavior-js auto-install [api-key] [options]
|
|
2668
2929
|
|
|
2669
|
-
This tool automatically detects your
|
|
2670
|
-
to integrate the HumanBehavior SDK with minimal user intervention.
|
|
2671
|
-
|
|
2672
|
-
Arguments:
|
|
2673
|
-
api-key Your HumanBehavior API key
|
|
2930
|
+
This tool automatically detects your framework and integrates the HumanBehavior SDK.
|
|
2674
2931
|
|
|
2675
2932
|
Options:
|
|
2676
|
-
-
|
|
2677
|
-
-
|
|
2678
|
-
-
|
|
2679
|
-
-
|
|
2933
|
+
-h, --help Show this help message
|
|
2934
|
+
-y, --yes Skip all prompts and use defaults
|
|
2935
|
+
--dry-run Show what would be changed without making changes
|
|
2936
|
+
-p, --project <path> Specify project directory
|
|
2680
2937
|
|
|
2681
2938
|
Examples:
|
|
2682
|
-
npx humanbehavior-js
|
|
2683
|
-
npx humanbehavior-js
|
|
2684
|
-
npx humanbehavior-js
|
|
2685
|
-
|
|
2686
|
-
Supported Frameworks:
|
|
2687
|
-
ā
React (CRA, Vite, Webpack)
|
|
2688
|
-
ā
Next.js (App Router, Pages Router)
|
|
2689
|
-
ā
Vue (Vue CLI, Vite)
|
|
2690
|
-
ā
Angular
|
|
2691
|
-
ā
Svelte (SvelteKit, Vite)
|
|
2692
|
-
ā
Remix
|
|
2693
|
-
ā
Vanilla JS/TS
|
|
2694
|
-
ā
Node.js (CommonJS & ESM)
|
|
2695
|
-
|
|
2696
|
-
The tool will:
|
|
2697
|
-
1. š Auto-detect your project's framework and setup
|
|
2698
|
-
2. š¦ Install the humanbehavior-js package
|
|
2699
|
-
3. āļø Modify your codebase to integrate the SDK
|
|
2700
|
-
4. š§ Create environment files with your API key
|
|
2701
|
-
5. š Make your app ready to track user behavior
|
|
2939
|
+
npx humanbehavior-js auto-install
|
|
2940
|
+
npx humanbehavior-js auto-install hb_your_api_key_here
|
|
2941
|
+
npx humanbehavior-js auto-install --project ./my-app --yes
|
|
2702
2942
|
`);
|
|
2703
2943
|
}
|
|
2704
2944
|
// Main execution
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2945
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
2946
|
+
const options = parseArgs();
|
|
2947
|
+
const cli = new AutoInstallCLI(options);
|
|
2948
|
+
cli.run().catch((error) => {
|
|
2949
|
+
clack.cancel(`Unexpected error: ${error.message}`);
|
|
2950
|
+
process.exit(1);
|
|
2951
|
+
});
|
|
2710
2952
|
}
|
|
2711
|
-
const cli = new AutoInstallCLI(options);
|
|
2712
|
-
cli.run().catch((error) => {
|
|
2713
|
-
console.error('ā Fatal error:', error);
|
|
2714
|
-
process.exit(1);
|
|
2715
|
-
});
|
|
2716
2953
|
|
|
2717
2954
|
/**
|
|
2718
2955
|
* Centralized AI Service Implementation
|