humanbehavior-js 0.4.7 → 0.4.8
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/angular/index.cjs +5 -6
- package/dist/cjs/angular/index.cjs.map +1 -1
- package/dist/cjs/index.cjs +5 -6
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/install-wizard.cjs +4 -2
- package/dist/cjs/install-wizard.cjs.map +1 -1
- package/dist/cjs/react/index.cjs +5 -6
- package/dist/cjs/react/index.cjs.map +1 -1
- package/dist/cjs/remix/index.cjs +5 -6
- package/dist/cjs/remix/index.cjs.map +1 -1
- package/dist/cjs/svelte/index.cjs +5 -6
- package/dist/cjs/svelte/index.cjs.map +1 -1
- package/dist/cjs/vue/index.cjs +5 -6
- package/dist/cjs/vue/index.cjs.map +1 -1
- package/dist/cjs/wizard/index.cjs +3208 -0
- package/dist/cjs/wizard/index.cjs.map +1 -0
- package/dist/cli/ai-auto-install.js +2024 -0
- package/dist/cli/ai-auto-install.js.map +1 -0
- package/dist/cli/auto-install.js +4 -2
- package/dist/cli/auto-install.js.map +1 -1
- package/dist/esm/angular/index.js +5 -6
- package/dist/esm/angular/index.js.map +1 -1
- package/dist/esm/index.js +5 -6
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/install-wizard.js +4 -2
- package/dist/esm/install-wizard.js.map +1 -1
- package/dist/esm/react/index.js +5 -6
- package/dist/esm/react/index.js.map +1 -1
- package/dist/esm/remix/index.js +5 -6
- package/dist/esm/remix/index.js.map +1 -1
- package/dist/esm/svelte/index.js +5 -6
- package/dist/esm/svelte/index.js.map +1 -1
- package/dist/esm/vue/index.js +5 -6
- package/dist/esm/vue/index.js.map +1 -1
- package/dist/esm/wizard/index.js +3178 -0
- package/dist/esm/wizard/index.js.map +1 -0
- package/dist/index.min.js.map +1 -1
- package/dist/types/install-wizard.d.ts +8 -8
- package/dist/types/wizard/index.d.ts +489 -0
- package/package.json +14 -8
- package/rollup.config.js +65 -3
- package/src/react/AutoInstallWizard.tsx +1 -1
- package/src/tracker.ts +5 -6
- package/src/wizard/README.md +114 -0
- package/src/wizard/ai/ai-install-wizard.ts +894 -0
- package/src/wizard/ai/manual-framework-wizard.ts +236 -0
- package/src/wizard/cli/ai-auto-install.ts +369 -0
- package/src/{cli → wizard/cli}/auto-install.ts +1 -1
- package/src/{install-wizard.ts → wizard/core/install-wizard.ts} +12 -10
- package/src/wizard/index.ts +23 -0
- package/src/wizard/services/centralized-ai-service.ts +668 -0
- package/src/wizard/services/remote-ai-service.ts +224 -0
|
@@ -0,0 +1,3178 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as readline from 'readline';
|
|
4
|
+
|
|
5
|
+
/******************************************************************************
|
|
6
|
+
Copyright (c) Microsoft Corporation.
|
|
7
|
+
|
|
8
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
9
|
+
purpose with or without fee is hereby granted.
|
|
10
|
+
|
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
13
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
18
|
+
***************************************************************************** */
|
|
19
|
+
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
23
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
24
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
25
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
26
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
27
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
28
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
33
|
+
var e = new Error(message);
|
|
34
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* HumanBehavior SDK Auto-Installation Wizard
|
|
39
|
+
*
|
|
40
|
+
* This wizard automatically detects the user's framework and modifies their codebase
|
|
41
|
+
* to integrate the SDK with minimal user intervention.
|
|
42
|
+
*/
|
|
43
|
+
class AutoInstallationWizard {
|
|
44
|
+
constructor(apiKey, projectRoot = process.cwd()) {
|
|
45
|
+
this.framework = null;
|
|
46
|
+
this.apiKey = apiKey;
|
|
47
|
+
this.projectRoot = projectRoot;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Main installation method - detects framework and auto-installs
|
|
51
|
+
*/
|
|
52
|
+
install() {
|
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
try {
|
|
55
|
+
// Step 1: Detect framework
|
|
56
|
+
this.framework = yield this.detectFramework();
|
|
57
|
+
// Step 2: Install package
|
|
58
|
+
yield this.installPackage();
|
|
59
|
+
// Step 3: Generate and apply code modifications
|
|
60
|
+
const modifications = yield this.generateModifications();
|
|
61
|
+
yield this.applyModifications(modifications);
|
|
62
|
+
// Step 4: Generate next steps
|
|
63
|
+
const nextSteps = this.generateNextSteps();
|
|
64
|
+
return {
|
|
65
|
+
success: true,
|
|
66
|
+
framework: this.framework,
|
|
67
|
+
modifications,
|
|
68
|
+
errors: [],
|
|
69
|
+
nextSteps
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
return {
|
|
74
|
+
success: false,
|
|
75
|
+
framework: this.framework || { name: 'unknown', type: 'vanilla' },
|
|
76
|
+
modifications: [],
|
|
77
|
+
errors: [error instanceof Error ? error.message : 'Unknown error'],
|
|
78
|
+
nextSteps: []
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Detect the current framework and project setup
|
|
85
|
+
*/
|
|
86
|
+
detectFramework() {
|
|
87
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
88
|
+
const packageJsonPath = path.join(this.projectRoot, 'package.json');
|
|
89
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
90
|
+
return {
|
|
91
|
+
name: 'vanilla',
|
|
92
|
+
type: 'vanilla',
|
|
93
|
+
projectRoot: this.projectRoot
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
97
|
+
const dependencies = Object.assign(Object.assign({}, packageJson.dependencies), packageJson.devDependencies);
|
|
98
|
+
// Detect framework
|
|
99
|
+
let framework = {
|
|
100
|
+
name: 'vanilla',
|
|
101
|
+
type: 'vanilla',
|
|
102
|
+
projectRoot: this.projectRoot
|
|
103
|
+
};
|
|
104
|
+
if (dependencies.nuxt) {
|
|
105
|
+
framework = {
|
|
106
|
+
name: 'nuxt',
|
|
107
|
+
type: 'nuxt',
|
|
108
|
+
hasTypeScript: !!dependencies.typescript,
|
|
109
|
+
hasRouter: true,
|
|
110
|
+
projectRoot: this.projectRoot
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
else if (dependencies.next) {
|
|
114
|
+
framework = {
|
|
115
|
+
name: 'nextjs',
|
|
116
|
+
type: 'nextjs',
|
|
117
|
+
hasTypeScript: !!dependencies.typescript || !!dependencies['@types/node'],
|
|
118
|
+
hasRouter: true,
|
|
119
|
+
projectRoot: this.projectRoot
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
else if (dependencies['@remix-run/react'] || dependencies['@remix-run/dev']) {
|
|
123
|
+
framework = {
|
|
124
|
+
name: 'remix',
|
|
125
|
+
type: 'remix',
|
|
126
|
+
hasTypeScript: !!dependencies.typescript || !!dependencies['@types/react'],
|
|
127
|
+
hasRouter: true,
|
|
128
|
+
projectRoot: this.projectRoot
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
else if (dependencies.react) {
|
|
132
|
+
framework = {
|
|
133
|
+
name: 'react',
|
|
134
|
+
type: 'react',
|
|
135
|
+
hasTypeScript: !!dependencies.typescript || !!dependencies['@types/react'],
|
|
136
|
+
hasRouter: !!dependencies['react-router-dom'] || !!dependencies['react-router'],
|
|
137
|
+
projectRoot: this.projectRoot
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
else if (dependencies.vue) {
|
|
141
|
+
framework = {
|
|
142
|
+
name: 'vue',
|
|
143
|
+
type: 'vue',
|
|
144
|
+
hasTypeScript: !!dependencies.typescript || !!dependencies['@vue/cli-service'],
|
|
145
|
+
hasRouter: !!dependencies['vue-router'],
|
|
146
|
+
projectRoot: this.projectRoot
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
else if (dependencies['@angular/core']) {
|
|
150
|
+
framework = {
|
|
151
|
+
name: 'angular',
|
|
152
|
+
type: 'angular',
|
|
153
|
+
hasTypeScript: true,
|
|
154
|
+
hasRouter: true,
|
|
155
|
+
projectRoot: this.projectRoot
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
else if (dependencies.svelte) {
|
|
159
|
+
framework = {
|
|
160
|
+
name: 'svelte',
|
|
161
|
+
type: 'svelte',
|
|
162
|
+
hasTypeScript: !!dependencies.typescript || !!dependencies['svelte-check'],
|
|
163
|
+
hasRouter: !!dependencies['svelte-routing'] || !!dependencies['@sveltejs/kit'],
|
|
164
|
+
projectRoot: this.projectRoot
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
// Detect bundler
|
|
168
|
+
if (dependencies.vite) {
|
|
169
|
+
framework.bundler = 'vite';
|
|
170
|
+
}
|
|
171
|
+
else if (dependencies.webpack) {
|
|
172
|
+
framework.bundler = 'webpack';
|
|
173
|
+
}
|
|
174
|
+
else if (dependencies.esbuild) {
|
|
175
|
+
framework.bundler = 'esbuild';
|
|
176
|
+
}
|
|
177
|
+
else if (dependencies.rollup) {
|
|
178
|
+
framework.bundler = 'rollup';
|
|
179
|
+
}
|
|
180
|
+
// Detect package manager
|
|
181
|
+
if (fs.existsSync(path.join(this.projectRoot, 'yarn.lock'))) {
|
|
182
|
+
framework.packageManager = 'yarn';
|
|
183
|
+
}
|
|
184
|
+
else if (fs.existsSync(path.join(this.projectRoot, 'pnpm-lock.yaml'))) {
|
|
185
|
+
framework.packageManager = 'pnpm';
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
framework.packageManager = 'npm';
|
|
189
|
+
}
|
|
190
|
+
return framework;
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Install the SDK package
|
|
195
|
+
*/
|
|
196
|
+
installPackage() {
|
|
197
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
198
|
+
var _a, _b;
|
|
199
|
+
const { execSync } = yield import('child_process');
|
|
200
|
+
const command = ((_a = this.framework) === null || _a === void 0 ? void 0 : _a.packageManager) === 'yarn'
|
|
201
|
+
? 'yarn add humanbehavior-js'
|
|
202
|
+
: ((_b = this.framework) === null || _b === void 0 ? void 0 : _b.packageManager) === 'pnpm'
|
|
203
|
+
? 'pnpm add humanbehavior-js'
|
|
204
|
+
: 'npm install humanbehavior-js';
|
|
205
|
+
try {
|
|
206
|
+
execSync(command, { cwd: this.projectRoot, stdio: 'inherit' });
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
throw new Error(`Failed to install humanbehavior-js: ${error}`);
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Generate code modifications based on framework
|
|
215
|
+
*/
|
|
216
|
+
generateModifications() {
|
|
217
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
218
|
+
var _a;
|
|
219
|
+
const modifications = [];
|
|
220
|
+
switch ((_a = this.framework) === null || _a === void 0 ? void 0 : _a.type) {
|
|
221
|
+
case 'react':
|
|
222
|
+
modifications.push(...yield this.generateReactModifications());
|
|
223
|
+
break;
|
|
224
|
+
case 'nextjs':
|
|
225
|
+
modifications.push(...yield this.generateNextJSModifications());
|
|
226
|
+
break;
|
|
227
|
+
case 'nuxt':
|
|
228
|
+
modifications.push(...yield this.generateNuxtModifications());
|
|
229
|
+
break;
|
|
230
|
+
case 'remix':
|
|
231
|
+
modifications.push(...yield this.generateRemixModifications());
|
|
232
|
+
break;
|
|
233
|
+
case 'vue':
|
|
234
|
+
modifications.push(...yield this.generateVueModifications());
|
|
235
|
+
break;
|
|
236
|
+
case 'angular':
|
|
237
|
+
modifications.push(...yield this.generateAngularModifications());
|
|
238
|
+
break;
|
|
239
|
+
case 'svelte':
|
|
240
|
+
modifications.push(...yield this.generateSvelteModifications());
|
|
241
|
+
break;
|
|
242
|
+
default:
|
|
243
|
+
modifications.push(...yield this.generateVanillaModifications());
|
|
244
|
+
}
|
|
245
|
+
return modifications;
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Generate React-specific modifications
|
|
250
|
+
*/
|
|
251
|
+
generateReactModifications() {
|
|
252
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
253
|
+
const modifications = [];
|
|
254
|
+
// Find main App component or index file
|
|
255
|
+
const appFile = this.findReactAppFile();
|
|
256
|
+
if (appFile) {
|
|
257
|
+
const content = fs.readFileSync(appFile, 'utf8');
|
|
258
|
+
const modifiedContent = this.injectReactProvider(content, appFile);
|
|
259
|
+
modifications.push({
|
|
260
|
+
filePath: appFile,
|
|
261
|
+
action: 'modify',
|
|
262
|
+
content: modifiedContent,
|
|
263
|
+
description: 'Added HumanBehaviorProvider to React app'
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
// Create or append to environment file
|
|
267
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
268
|
+
return modifications;
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Generate Next.js-specific modifications
|
|
273
|
+
*/
|
|
274
|
+
generateNextJSModifications() {
|
|
275
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
276
|
+
const modifications = [];
|
|
277
|
+
// Check for App Router
|
|
278
|
+
const appLayoutFile = path.join(this.projectRoot, 'src', 'app', 'layout.tsx');
|
|
279
|
+
const pagesLayoutFile = path.join(this.projectRoot, 'src', 'pages', '_app.tsx');
|
|
280
|
+
if (fs.existsSync(appLayoutFile)) {
|
|
281
|
+
// Create providers.tsx file for App Router
|
|
282
|
+
modifications.push({
|
|
283
|
+
filePath: path.join(this.projectRoot, 'src', 'app', 'providers.tsx'),
|
|
284
|
+
action: 'create',
|
|
285
|
+
content: `'use client';
|
|
286
|
+
|
|
287
|
+
import { HumanBehaviorProvider } from 'humanbehavior-js/react';
|
|
288
|
+
|
|
289
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
290
|
+
return (
|
|
291
|
+
<HumanBehaviorProvider apiKey={process.env.NEXT_PUBLIC_HUMANBEHAVIOR_API_KEY}>
|
|
292
|
+
{children}
|
|
293
|
+
</HumanBehaviorProvider>
|
|
294
|
+
);
|
|
295
|
+
}`,
|
|
296
|
+
description: 'Created providers.tsx file for Next.js App Router'
|
|
297
|
+
});
|
|
298
|
+
// Modify layout.tsx to use the provider
|
|
299
|
+
const content = fs.readFileSync(appLayoutFile, 'utf8');
|
|
300
|
+
const modifiedContent = this.injectNextJSAppRouter(content);
|
|
301
|
+
modifications.push({
|
|
302
|
+
filePath: appLayoutFile,
|
|
303
|
+
action: 'modify',
|
|
304
|
+
content: modifiedContent,
|
|
305
|
+
description: 'Added Providers wrapper to Next.js App Router layout'
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
else if (fs.existsSync(pagesLayoutFile)) {
|
|
309
|
+
// Create providers.tsx file for Pages Router
|
|
310
|
+
modifications.push({
|
|
311
|
+
filePath: path.join(this.projectRoot, 'src', 'components', 'providers.tsx'),
|
|
312
|
+
action: 'create',
|
|
313
|
+
content: `'use client';
|
|
314
|
+
|
|
315
|
+
import { HumanBehaviorProvider } from 'humanbehavior-js/react';
|
|
316
|
+
|
|
317
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
318
|
+
return (
|
|
319
|
+
<HumanBehaviorProvider apiKey={process.env.NEXT_PUBLIC_HUMANBEHAVIOR_API_KEY}>
|
|
320
|
+
{children}
|
|
321
|
+
</HumanBehaviorProvider>
|
|
322
|
+
);
|
|
323
|
+
}`,
|
|
324
|
+
description: 'Created providers.tsx file for Pages Router'
|
|
325
|
+
});
|
|
326
|
+
// Modify _app.tsx to use the provider
|
|
327
|
+
const content = fs.readFileSync(pagesLayoutFile, 'utf8');
|
|
328
|
+
const modifiedContent = this.injectNextJSPagesRouter(content);
|
|
329
|
+
modifications.push({
|
|
330
|
+
filePath: pagesLayoutFile,
|
|
331
|
+
action: 'modify',
|
|
332
|
+
content: modifiedContent,
|
|
333
|
+
description: 'Added Providers wrapper to Next.js Pages Router'
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
// Create or append to environment file
|
|
337
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
338
|
+
return modifications;
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Generate Nuxt-specific modifications
|
|
343
|
+
*/
|
|
344
|
+
generateNuxtModifications() {
|
|
345
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
346
|
+
const modifications = [];
|
|
347
|
+
// Create plugin file for Nuxt (in app directory)
|
|
348
|
+
const pluginFile = path.join(this.projectRoot, 'app', 'plugins', 'humanbehavior.client.ts');
|
|
349
|
+
modifications.push({
|
|
350
|
+
filePath: pluginFile,
|
|
351
|
+
action: 'create',
|
|
352
|
+
content: `import { HumanBehaviorTracker } from 'humanbehavior-js';
|
|
353
|
+
|
|
354
|
+
export default defineNuxtPlugin(() => {
|
|
355
|
+
const config = useRuntimeConfig();
|
|
356
|
+
|
|
357
|
+
// Initialize HumanBehavior SDK (client-side only)
|
|
358
|
+
if (typeof window !== 'undefined') {
|
|
359
|
+
const apiKey = config.public.humanBehaviorApiKey;
|
|
360
|
+
console.log('HumanBehavior: API key:', apiKey ? 'present' : 'missing');
|
|
361
|
+
|
|
362
|
+
if (apiKey) {
|
|
363
|
+
try {
|
|
364
|
+
const tracker = HumanBehaviorTracker.init(apiKey);
|
|
365
|
+
console.log('HumanBehavior: Tracker initialized successfully');
|
|
366
|
+
} catch (error) {
|
|
367
|
+
console.error('HumanBehavior: Failed to initialize tracker:', error);
|
|
368
|
+
}
|
|
369
|
+
} else {
|
|
370
|
+
console.error('HumanBehavior: No API key found in runtime config');
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
});`,
|
|
374
|
+
description: 'Created Nuxt plugin for HumanBehavior SDK in app directory'
|
|
375
|
+
});
|
|
376
|
+
// Create environment configuration
|
|
377
|
+
const nuxtConfigFile = path.join(this.projectRoot, 'nuxt.config.ts');
|
|
378
|
+
if (fs.existsSync(nuxtConfigFile)) {
|
|
379
|
+
const content = fs.readFileSync(nuxtConfigFile, 'utf8');
|
|
380
|
+
const modifiedContent = this.injectNuxtConfig(content);
|
|
381
|
+
modifications.push({
|
|
382
|
+
filePath: nuxtConfigFile,
|
|
383
|
+
action: 'modify',
|
|
384
|
+
content: modifiedContent,
|
|
385
|
+
description: 'Added HumanBehavior runtime config to Nuxt config'
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
// Create or append to environment file
|
|
389
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
390
|
+
return modifications;
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Generate Remix-specific modifications
|
|
395
|
+
*/
|
|
396
|
+
generateRemixModifications() {
|
|
397
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
398
|
+
const modifications = [];
|
|
399
|
+
// Find root.tsx file
|
|
400
|
+
const rootFile = path.join(this.projectRoot, 'app', 'root.tsx');
|
|
401
|
+
if (fs.existsSync(rootFile)) {
|
|
402
|
+
const content = fs.readFileSync(rootFile, 'utf8');
|
|
403
|
+
const modifiedContent = this.injectRemixProvider(content);
|
|
404
|
+
modifications.push({
|
|
405
|
+
filePath: rootFile,
|
|
406
|
+
action: 'modify',
|
|
407
|
+
content: modifiedContent,
|
|
408
|
+
description: 'Added HumanBehaviorProvider to Remix root component'
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
// Create or append to environment file
|
|
412
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
413
|
+
return modifications;
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Generate Vue-specific modifications
|
|
418
|
+
*/
|
|
419
|
+
generateVueModifications() {
|
|
420
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
421
|
+
const modifications = [];
|
|
422
|
+
// Find main.js or main.ts
|
|
423
|
+
const mainFile = this.findVueMainFile();
|
|
424
|
+
if (mainFile) {
|
|
425
|
+
const content = fs.readFileSync(mainFile, 'utf8');
|
|
426
|
+
const modifiedContent = this.injectVuePlugin(content);
|
|
427
|
+
modifications.push({
|
|
428
|
+
filePath: mainFile,
|
|
429
|
+
action: 'modify',
|
|
430
|
+
content: modifiedContent,
|
|
431
|
+
description: 'Added HumanBehaviorPlugin to Vue app'
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
// Create or append to environment file
|
|
435
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
436
|
+
return modifications;
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Generate Angular-specific modifications
|
|
441
|
+
*/
|
|
442
|
+
generateAngularModifications() {
|
|
443
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
444
|
+
const modifications = [];
|
|
445
|
+
// Check for modern Angular (standalone components) vs legacy (NgModule)
|
|
446
|
+
const appModuleFile = path.join(this.projectRoot, 'src', 'app', 'app.module.ts');
|
|
447
|
+
const appComponentFile = path.join(this.projectRoot, 'src', 'app', 'app.ts');
|
|
448
|
+
const mainFile = path.join(this.projectRoot, 'src', 'main.ts');
|
|
449
|
+
const isModernAngular = fs.existsSync(appComponentFile) && !fs.existsSync(appModuleFile);
|
|
450
|
+
if (isModernAngular) {
|
|
451
|
+
// Modern Angular 17+ with standalone components
|
|
452
|
+
if (fs.existsSync(mainFile)) {
|
|
453
|
+
const content = fs.readFileSync(mainFile, 'utf8');
|
|
454
|
+
const modifiedContent = this.injectAngularStandaloneInit(content);
|
|
455
|
+
modifications.push({
|
|
456
|
+
filePath: mainFile,
|
|
457
|
+
action: 'modify',
|
|
458
|
+
content: modifiedContent,
|
|
459
|
+
description: 'Added HumanBehavior initialization to Angular main.ts'
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
else if (fs.existsSync(appModuleFile)) {
|
|
464
|
+
// Legacy Angular with NgModule
|
|
465
|
+
const content = fs.readFileSync(appModuleFile, 'utf8');
|
|
466
|
+
const modifiedContent = this.injectAngularModule(content);
|
|
467
|
+
modifications.push({
|
|
468
|
+
filePath: appModuleFile,
|
|
469
|
+
action: 'modify',
|
|
470
|
+
content: modifiedContent,
|
|
471
|
+
description: 'Added HumanBehaviorModule to Angular app'
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
// Handle Angular environment file (legacy structure)
|
|
475
|
+
const envFile = path.join(this.projectRoot, 'src', 'environments', 'environment.ts');
|
|
476
|
+
if (fs.existsSync(envFile)) {
|
|
477
|
+
const content = fs.readFileSync(envFile, 'utf8');
|
|
478
|
+
if (!content.includes('humanBehaviorApiKey')) {
|
|
479
|
+
const modifiedContent = content.replace(/export const environment = {([\s\S]*?)};/, `export const environment = {
|
|
480
|
+
$1,
|
|
481
|
+
humanBehaviorApiKey: process.env['HUMANBEHAVIOR_API_KEY'] || ''
|
|
482
|
+
};`);
|
|
483
|
+
modifications.push({
|
|
484
|
+
filePath: envFile,
|
|
485
|
+
action: 'modify',
|
|
486
|
+
content: modifiedContent,
|
|
487
|
+
description: 'Added API key to Angular environment'
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
// Create or append to environment file
|
|
492
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
493
|
+
return modifications;
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Generate Svelte-specific modifications
|
|
498
|
+
*/
|
|
499
|
+
generateSvelteModifications() {
|
|
500
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
501
|
+
const modifications = [];
|
|
502
|
+
// Check for SvelteKit
|
|
503
|
+
const svelteConfigFile = path.join(this.projectRoot, 'svelte.config.js');
|
|
504
|
+
const isSvelteKit = fs.existsSync(svelteConfigFile);
|
|
505
|
+
if (isSvelteKit) {
|
|
506
|
+
// SvelteKit - create layout file
|
|
507
|
+
const layoutFile = path.join(this.projectRoot, 'src', 'routes', '+layout.svelte');
|
|
508
|
+
if (fs.existsSync(layoutFile)) {
|
|
509
|
+
const content = fs.readFileSync(layoutFile, 'utf8');
|
|
510
|
+
const modifiedContent = this.injectSvelteKitLayout(content);
|
|
511
|
+
modifications.push({
|
|
512
|
+
filePath: layoutFile,
|
|
513
|
+
action: 'modify',
|
|
514
|
+
content: modifiedContent,
|
|
515
|
+
description: 'Added HumanBehavior store to SvelteKit layout'
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
// Regular Svelte - modify main file
|
|
521
|
+
const mainFile = this.findSvelteMainFile();
|
|
522
|
+
if (mainFile) {
|
|
523
|
+
const content = fs.readFileSync(mainFile, 'utf8');
|
|
524
|
+
const modifiedContent = this.injectSvelteStore(content);
|
|
525
|
+
modifications.push({
|
|
526
|
+
filePath: mainFile,
|
|
527
|
+
action: 'modify',
|
|
528
|
+
content: modifiedContent,
|
|
529
|
+
description: 'Added HumanBehavior store to Svelte app'
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
// Create or append to environment file
|
|
534
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
535
|
+
return modifications;
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Generate vanilla JS/TS modifications
|
|
540
|
+
*/
|
|
541
|
+
generateVanillaModifications() {
|
|
542
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
543
|
+
const modifications = [];
|
|
544
|
+
// Find HTML file to inject script
|
|
545
|
+
const htmlFile = this.findHTMLFile();
|
|
546
|
+
if (htmlFile) {
|
|
547
|
+
const content = fs.readFileSync(htmlFile, 'utf8');
|
|
548
|
+
const modifiedContent = this.injectVanillaScript(content);
|
|
549
|
+
modifications.push({
|
|
550
|
+
filePath: htmlFile,
|
|
551
|
+
action: 'modify',
|
|
552
|
+
content: modifiedContent,
|
|
553
|
+
description: 'Added HumanBehavior CDN script to HTML file'
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
// Create or append to environment file
|
|
557
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
558
|
+
return modifications;
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Apply modifications to the codebase
|
|
563
|
+
*/
|
|
564
|
+
applyModifications(modifications) {
|
|
565
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
566
|
+
for (const modification of modifications) {
|
|
567
|
+
try {
|
|
568
|
+
const dir = path.dirname(modification.filePath);
|
|
569
|
+
if (!fs.existsSync(dir)) {
|
|
570
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
571
|
+
}
|
|
572
|
+
switch (modification.action) {
|
|
573
|
+
case 'create':
|
|
574
|
+
fs.writeFileSync(modification.filePath, modification.content);
|
|
575
|
+
break;
|
|
576
|
+
case 'modify':
|
|
577
|
+
fs.writeFileSync(modification.filePath, modification.content);
|
|
578
|
+
break;
|
|
579
|
+
case 'append':
|
|
580
|
+
fs.appendFileSync(modification.filePath, '\n' + modification.content);
|
|
581
|
+
break;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
catch (error) {
|
|
585
|
+
throw new Error(`Failed to apply modification to ${modification.filePath}: ${error}`);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Generate next steps for the user
|
|
592
|
+
*/
|
|
593
|
+
generateNextSteps() {
|
|
594
|
+
var _a, _b;
|
|
595
|
+
const steps = [
|
|
596
|
+
'✅ SDK installed and configured automatically!',
|
|
597
|
+
'🚀 Your app is now tracking user behavior',
|
|
598
|
+
'📊 View sessions in your HumanBehavior dashboard',
|
|
599
|
+
'🔧 Customize tracking in your code as needed'
|
|
600
|
+
];
|
|
601
|
+
if (((_a = this.framework) === null || _a === void 0 ? void 0 : _a.type) === 'react' || ((_b = this.framework) === null || _b === void 0 ? void 0 : _b.type) === 'nextjs') {
|
|
602
|
+
steps.push('💡 Use the useHumanBehavior() hook to track custom events');
|
|
603
|
+
}
|
|
604
|
+
return steps;
|
|
605
|
+
}
|
|
606
|
+
// Helper methods for file detection and content injection
|
|
607
|
+
findReactAppFile() {
|
|
608
|
+
const possibleFiles = [
|
|
609
|
+
'src/App.jsx', 'src/App.js', 'src/App.tsx', 'src/App.ts',
|
|
610
|
+
'src/index.js', 'src/index.tsx', 'src/main.js', 'src/main.tsx'
|
|
611
|
+
];
|
|
612
|
+
for (const file of possibleFiles) {
|
|
613
|
+
const fullPath = path.join(this.projectRoot, file);
|
|
614
|
+
if (fs.existsSync(fullPath)) {
|
|
615
|
+
return fullPath;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
return null;
|
|
619
|
+
}
|
|
620
|
+
findVueMainFile() {
|
|
621
|
+
const possibleFiles = [
|
|
622
|
+
'src/main.js', 'src/main.ts', 'src/main.jsx', 'src/main.tsx'
|
|
623
|
+
];
|
|
624
|
+
for (const file of possibleFiles) {
|
|
625
|
+
const fullPath = path.join(this.projectRoot, file);
|
|
626
|
+
if (fs.existsSync(fullPath)) {
|
|
627
|
+
return fullPath;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
return null;
|
|
631
|
+
}
|
|
632
|
+
findSvelteMainFile() {
|
|
633
|
+
const possibleFiles = [
|
|
634
|
+
'src/main.js', 'src/main.ts', 'src/main.svelte'
|
|
635
|
+
];
|
|
636
|
+
for (const file of possibleFiles) {
|
|
637
|
+
const fullPath = path.join(this.projectRoot, file);
|
|
638
|
+
if (fs.existsSync(fullPath)) {
|
|
639
|
+
return fullPath;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
return null;
|
|
643
|
+
}
|
|
644
|
+
findHTMLFile() {
|
|
645
|
+
const possibleFiles = ['index.html', 'public/index.html', 'dist/index.html'];
|
|
646
|
+
for (const file of possibleFiles) {
|
|
647
|
+
const fullPath = path.join(this.projectRoot, file);
|
|
648
|
+
if (fs.existsSync(fullPath)) {
|
|
649
|
+
return fullPath;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
return null;
|
|
653
|
+
}
|
|
654
|
+
injectReactProvider(content, filePath) {
|
|
655
|
+
var _a;
|
|
656
|
+
filePath.endsWith('.tsx') || filePath.endsWith('.ts');
|
|
657
|
+
// Check if already has HumanBehaviorProvider
|
|
658
|
+
if (content.includes('HumanBehaviorProvider')) {
|
|
659
|
+
return content;
|
|
660
|
+
}
|
|
661
|
+
// Determine the correct environment variable syntax based on bundler
|
|
662
|
+
const isVite = ((_a = this.framework) === null || _a === void 0 ? void 0 : _a.bundler) === 'vite';
|
|
663
|
+
const envVar = isVite
|
|
664
|
+
? 'import.meta.env.VITE_HUMANBEHAVIOR_API_KEY!'
|
|
665
|
+
: 'process.env.HUMANBEHAVIOR_API_KEY!';
|
|
666
|
+
const importStatement = `import { HumanBehaviorProvider } from 'humanbehavior-js/react';`;
|
|
667
|
+
// Simple injection - in production, you'd want more sophisticated parsing
|
|
668
|
+
if (content.includes('function App()') || content.includes('const App =')) {
|
|
669
|
+
return content.replace(/(function App\(\)|const App =)/, `${importStatement}\n\n$1`).replace(/return \(([\s\S]*?)\);/, `return (
|
|
670
|
+
<HumanBehaviorProvider apiKey={${envVar}}>
|
|
671
|
+
$1
|
|
672
|
+
</HumanBehaviorProvider>
|
|
673
|
+
);`);
|
|
674
|
+
}
|
|
675
|
+
return `${importStatement}\n\n${content}`;
|
|
676
|
+
}
|
|
677
|
+
injectNextJSAppRouter(content) {
|
|
678
|
+
if (content.includes('Providers')) {
|
|
679
|
+
return content;
|
|
680
|
+
}
|
|
681
|
+
const importStatement = `import { Providers } from './providers';`;
|
|
682
|
+
// First, add the import statement
|
|
683
|
+
let modifiedContent = content.replace(/export default function RootLayout/, `${importStatement}\n\nexport default function RootLayout`);
|
|
684
|
+
// Then wrap the body content with Providers
|
|
685
|
+
// Use a more specific approach to handle the body content
|
|
686
|
+
modifiedContent = modifiedContent.replace(/<body([^>]*)>([\s\S]*?)<\/body>/, (match, bodyAttrs, bodyContent) => {
|
|
687
|
+
// Trim whitespace and newlines from bodyContent
|
|
688
|
+
const trimmedContent = bodyContent.trim();
|
|
689
|
+
return `<body${bodyAttrs}>
|
|
690
|
+
<Providers>
|
|
691
|
+
${trimmedContent}
|
|
692
|
+
</Providers>
|
|
693
|
+
</body>`;
|
|
694
|
+
});
|
|
695
|
+
return modifiedContent;
|
|
696
|
+
}
|
|
697
|
+
injectNextJSPagesRouter(content) {
|
|
698
|
+
if (content.includes('Providers')) {
|
|
699
|
+
return content;
|
|
700
|
+
}
|
|
701
|
+
const importStatement = `import { Providers } from '../components/providers';`;
|
|
702
|
+
return content.replace(/function MyApp/, `${importStatement}\n\nfunction MyApp`).replace(/return \(([\s\S]*?)\);/, `return (
|
|
703
|
+
<Providers>
|
|
704
|
+
$1
|
|
705
|
+
</Providers>
|
|
706
|
+
);`);
|
|
707
|
+
}
|
|
708
|
+
injectRemixProvider(content) {
|
|
709
|
+
if (content.includes('HumanBehaviorProvider')) {
|
|
710
|
+
return content;
|
|
711
|
+
}
|
|
712
|
+
const importStatement = `import { HumanBehaviorProvider, createHumanBehaviorLoader } from 'humanbehavior-js/remix';`;
|
|
713
|
+
const useLoaderDataImport = `import { useLoaderData } from "@remix-run/react";`;
|
|
714
|
+
// Add imports more robustly
|
|
715
|
+
let modifiedContent = content;
|
|
716
|
+
// Add HumanBehaviorProvider import - find the last import and add after it
|
|
717
|
+
if (!content.includes('HumanBehaviorProvider')) {
|
|
718
|
+
const lastImportIndex = modifiedContent.lastIndexOf('import');
|
|
719
|
+
if (lastImportIndex !== -1) {
|
|
720
|
+
const nextLineIndex = modifiedContent.indexOf('\n', lastImportIndex);
|
|
721
|
+
if (nextLineIndex !== -1) {
|
|
722
|
+
modifiedContent = modifiedContent.slice(0, nextLineIndex + 1) +
|
|
723
|
+
importStatement + '\n' +
|
|
724
|
+
modifiedContent.slice(nextLineIndex + 1);
|
|
725
|
+
}
|
|
726
|
+
else {
|
|
727
|
+
modifiedContent = modifiedContent + '\n' + importStatement;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
else {
|
|
731
|
+
modifiedContent = importStatement + '\n' + modifiedContent;
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
// Add useLoaderData import - find the last import and add after it
|
|
735
|
+
if (!content.includes('useLoaderData')) {
|
|
736
|
+
const lastImportIndex = modifiedContent.lastIndexOf('import');
|
|
737
|
+
if (lastImportIndex !== -1) {
|
|
738
|
+
const nextLineIndex = modifiedContent.indexOf('\n', lastImportIndex);
|
|
739
|
+
if (nextLineIndex !== -1) {
|
|
740
|
+
modifiedContent = modifiedContent.slice(0, nextLineIndex + 1) +
|
|
741
|
+
useLoaderDataImport + '\n' +
|
|
742
|
+
modifiedContent.slice(nextLineIndex + 1);
|
|
743
|
+
}
|
|
744
|
+
else {
|
|
745
|
+
modifiedContent = modifiedContent + '\n' + useLoaderDataImport;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
else {
|
|
749
|
+
modifiedContent = useLoaderDataImport + '\n' + modifiedContent;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
// Add loader function before the App component
|
|
753
|
+
if (!content.includes('export const loader')) {
|
|
754
|
+
modifiedContent = modifiedContent.replace(/export default function App\(\)/, `export const loader = createHumanBehaviorLoader();
|
|
755
|
+
|
|
756
|
+
export default function App()`);
|
|
757
|
+
}
|
|
758
|
+
// Wrap the App component content with HumanBehaviorProvider
|
|
759
|
+
modifiedContent = modifiedContent.replace(/export default function App\(\) \{[\s\S]*?return \(([\s\S]*?)\);[\s\S]*?\}/, `export default function App() {
|
|
760
|
+
const data = useLoaderData<typeof loader>();
|
|
761
|
+
|
|
762
|
+
return (
|
|
763
|
+
<HumanBehaviorProvider apiKey={data.ENV.HUMANBEHAVIOR_API_KEY}>
|
|
764
|
+
$1
|
|
765
|
+
</HumanBehaviorProvider>
|
|
766
|
+
);
|
|
767
|
+
}`);
|
|
768
|
+
return modifiedContent;
|
|
769
|
+
}
|
|
770
|
+
injectVuePlugin(content) {
|
|
771
|
+
if (content.includes('HumanBehaviorPlugin')) {
|
|
772
|
+
return content;
|
|
773
|
+
}
|
|
774
|
+
const importStatement = `import { HumanBehaviorPlugin } from 'humanbehavior-js/vue';`;
|
|
775
|
+
const pluginUsage = `app.use(HumanBehaviorPlugin, {
|
|
776
|
+
apiKey: import.meta.env.VITE_HUMANBEHAVIOR_API_KEY
|
|
777
|
+
});`;
|
|
778
|
+
// Handle both Vue 2 and Vue 3 patterns
|
|
779
|
+
if (content.includes('createApp')) {
|
|
780
|
+
// Vue 3
|
|
781
|
+
return content.replace(/import.*from.*['"]vue['"]/, `$&\n${importStatement}`).replace(/app\.mount\(/, `${pluginUsage}\n\napp.mount(`);
|
|
782
|
+
}
|
|
783
|
+
else {
|
|
784
|
+
// Vue 2
|
|
785
|
+
return content.replace(/import.*from.*['"]vue['"]/, `$&\n${importStatement}`).replace(/new Vue\(/, `${pluginUsage}\n\nnew Vue(`);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
injectAngularModule(content) {
|
|
789
|
+
if (content.includes('HumanBehaviorModule')) {
|
|
790
|
+
return content;
|
|
791
|
+
}
|
|
792
|
+
const importStatement = `import { HumanBehaviorModule } from 'humanbehavior-js/angular';`;
|
|
793
|
+
const environmentImport = `import { environment } from '../environments/environment';`;
|
|
794
|
+
// Add environment import if not present
|
|
795
|
+
let modifiedContent = content;
|
|
796
|
+
if (!content.includes('environment')) {
|
|
797
|
+
modifiedContent = content.replace(/import.*from.*['"]@angular/, `${environmentImport}\n$&`);
|
|
798
|
+
}
|
|
799
|
+
return modifiedContent.replace(/imports:\s*\[([\s\S]*?)\]/, `imports: [
|
|
800
|
+
$1,
|
|
801
|
+
HumanBehaviorModule.forRoot({
|
|
802
|
+
apiKey: environment.humanBehaviorApiKey
|
|
803
|
+
})
|
|
804
|
+
]`).replace(/import.*from.*['"]@angular/, `$&\n${importStatement}`);
|
|
805
|
+
}
|
|
806
|
+
injectAngularStandaloneInit(content) {
|
|
807
|
+
if (content.includes('initializeHumanBehavior')) {
|
|
808
|
+
return content;
|
|
809
|
+
}
|
|
810
|
+
const importStatement = `import { initializeHumanBehavior } from 'humanbehavior-js/angular';`;
|
|
811
|
+
// Add import at the top
|
|
812
|
+
let modifiedContent = content.replace(/import.*from.*['"]@angular/, `${importStatement}\n$&`);
|
|
813
|
+
// Add initialization after bootstrapApplication
|
|
814
|
+
modifiedContent = modifiedContent.replace(/(bootstrapApplication\([^}]+\}?\)(?:\s*\.catch[^;]+;)?)/, `$1
|
|
815
|
+
|
|
816
|
+
// Initialize HumanBehavior SDK (client-side only)
|
|
817
|
+
if (typeof window !== 'undefined') {
|
|
818
|
+
const tracker = initializeHumanBehavior(
|
|
819
|
+
'${this.apiKey}'
|
|
820
|
+
);
|
|
821
|
+
}`);
|
|
822
|
+
return modifiedContent;
|
|
823
|
+
}
|
|
824
|
+
injectSvelteStore(content) {
|
|
825
|
+
if (content.includes('humanBehaviorStore')) {
|
|
826
|
+
return content;
|
|
827
|
+
}
|
|
828
|
+
const importStatement = `import { humanBehaviorStore } from 'humanbehavior-js/svelte';`;
|
|
829
|
+
const initCode = `humanBehaviorStore.init(process.env.PUBLIC_HUMANBEHAVIOR_API_KEY || '');`;
|
|
830
|
+
return `${importStatement}\n${initCode}\n\n${content}`;
|
|
831
|
+
}
|
|
832
|
+
injectSvelteKitLayout(content) {
|
|
833
|
+
if (content.includes('humanBehaviorStore')) {
|
|
834
|
+
return content;
|
|
835
|
+
}
|
|
836
|
+
const importStatement = `import { humanBehaviorStore } from 'humanbehavior-js/svelte';`;
|
|
837
|
+
const envImport = `import { PUBLIC_HUMANBEHAVIOR_API_KEY } from '$env/static/public';`;
|
|
838
|
+
const initCode = `humanBehaviorStore.init(PUBLIC_HUMANBEHAVIOR_API_KEY || '');`;
|
|
839
|
+
// Add to script section - handle different script tag patterns
|
|
840
|
+
if (content.includes('<script lang="ts">')) {
|
|
841
|
+
return content.replace(/<script lang="ts">/, `<script lang="ts">\n\t${envImport}\n\t${importStatement}\n\t${initCode}`);
|
|
842
|
+
}
|
|
843
|
+
else if (content.includes('<script>')) {
|
|
844
|
+
return content.replace(/<script>/, `<script>\n\t${envImport}\n\t${importStatement}\n\t${initCode}`);
|
|
845
|
+
}
|
|
846
|
+
else if (content.includes('<script context="module">')) {
|
|
847
|
+
return content.replace(/<script\s+context="module">/, `<script context="module">\n\t${envImport}\n\t${importStatement}\n\t${initCode}`);
|
|
848
|
+
}
|
|
849
|
+
else {
|
|
850
|
+
// If no script tag found, add one at the beginning
|
|
851
|
+
return content.replace(/<svelte:head>/, `<script lang="ts">\n\t${envImport}\n\t${importStatement}\n\t${initCode}\n</script>\n\n<svelte:head>`);
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
injectVanillaScript(content) {
|
|
855
|
+
if (content.includes('humanbehavior-js')) {
|
|
856
|
+
return content;
|
|
857
|
+
}
|
|
858
|
+
const cdnScript = `<script src="https://unpkg.com/humanbehavior-js@latest/dist/index.min.js"></script>`;
|
|
859
|
+
const initScript = `<script>
|
|
860
|
+
// Initialize HumanBehavior SDK
|
|
861
|
+
// Note: For vanilla HTML, the API key must be hardcoded since env vars aren't available
|
|
862
|
+
const tracker = HumanBehaviorTracker.init('${this.apiKey}');
|
|
863
|
+
</script>`;
|
|
864
|
+
return content.replace(/<\/head>/, ` ${cdnScript}\n ${initScript}\n</head>`);
|
|
865
|
+
}
|
|
866
|
+
injectNuxtConfig(content) {
|
|
867
|
+
if (content.includes('humanBehaviorApiKey')) {
|
|
868
|
+
return content;
|
|
869
|
+
}
|
|
870
|
+
// Add runtime config by inserting it after the opening brace
|
|
871
|
+
return content.replace(/export default defineNuxtConfig\(\{/, `export default defineNuxtConfig({
|
|
872
|
+
runtimeConfig: {
|
|
873
|
+
public: {
|
|
874
|
+
humanBehaviorApiKey: process.env.NUXT_PUBLIC_HUMANBEHAVIOR_API_KEY
|
|
875
|
+
}
|
|
876
|
+
},`);
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* Helper method to find the best environment file for a framework
|
|
880
|
+
*/
|
|
881
|
+
findBestEnvFile(framework) {
|
|
882
|
+
const possibleEnvFiles = [
|
|
883
|
+
'.env.local',
|
|
884
|
+
'.env.development.local',
|
|
885
|
+
'.env.development',
|
|
886
|
+
'.env.local.development',
|
|
887
|
+
'.env',
|
|
888
|
+
'.env.production',
|
|
889
|
+
'.env.staging'
|
|
890
|
+
];
|
|
891
|
+
// Framework-specific environment variable names
|
|
892
|
+
const getEnvVarName = (framework) => {
|
|
893
|
+
// Handle React+Vite specifically
|
|
894
|
+
if (framework.type === 'react' && framework.bundler === 'vite') {
|
|
895
|
+
return 'VITE_HUMANBEHAVIOR_API_KEY';
|
|
896
|
+
}
|
|
897
|
+
// Framework-specific mappings
|
|
898
|
+
const envVarNames = {
|
|
899
|
+
react: 'HUMANBEHAVIOR_API_KEY',
|
|
900
|
+
nextjs: 'NEXT_PUBLIC_HUMANBEHAVIOR_API_KEY',
|
|
901
|
+
vue: 'VITE_HUMANBEHAVIOR_API_KEY',
|
|
902
|
+
svelte: 'PUBLIC_HUMANBEHAVIOR_API_KEY',
|
|
903
|
+
angular: 'HUMANBEHAVIOR_API_KEY',
|
|
904
|
+
nuxt: 'NUXT_PUBLIC_HUMANBEHAVIOR_API_KEY',
|
|
905
|
+
remix: 'HUMANBEHAVIOR_API_KEY',
|
|
906
|
+
vanilla: 'HUMANBEHAVIOR_API_KEY',
|
|
907
|
+
node: 'HUMANBEHAVIOR_API_KEY',
|
|
908
|
+
auto: 'HUMANBEHAVIOR_API_KEY'
|
|
909
|
+
};
|
|
910
|
+
return envVarNames[framework.type] || 'HUMANBEHAVIOR_API_KEY';
|
|
911
|
+
};
|
|
912
|
+
const envVarName = getEnvVarName(framework);
|
|
913
|
+
// Check for existing files
|
|
914
|
+
for (const envFile of possibleEnvFiles) {
|
|
915
|
+
const fullPath = path.join(this.projectRoot, envFile);
|
|
916
|
+
if (fs.existsSync(fullPath)) {
|
|
917
|
+
return { filePath: fullPath, envVarName };
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
// Framework-specific default file creation
|
|
921
|
+
const defaultFiles = {
|
|
922
|
+
react: '.env.local',
|
|
923
|
+
nextjs: '.env.local',
|
|
924
|
+
vue: '.env.local',
|
|
925
|
+
svelte: '.env',
|
|
926
|
+
angular: '.env',
|
|
927
|
+
nuxt: '.env',
|
|
928
|
+
remix: '.env.local',
|
|
929
|
+
vanilla: '.env',
|
|
930
|
+
node: '.env',
|
|
931
|
+
auto: '.env'
|
|
932
|
+
};
|
|
933
|
+
const defaultFile = defaultFiles[framework.type] || '.env';
|
|
934
|
+
return {
|
|
935
|
+
filePath: path.join(this.projectRoot, defaultFile),
|
|
936
|
+
envVarName
|
|
937
|
+
};
|
|
938
|
+
}
|
|
939
|
+
/**
|
|
940
|
+
* Helper method to create or append to environment files
|
|
941
|
+
*/
|
|
942
|
+
createEnvironmentModification(framework) {
|
|
943
|
+
const { filePath, envVarName } = this.findBestEnvFile(framework);
|
|
944
|
+
if (fs.existsSync(filePath)) {
|
|
945
|
+
// Check if the variable already exists
|
|
946
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
947
|
+
if (content.includes(envVarName)) {
|
|
948
|
+
// Variable exists, don't modify
|
|
949
|
+
return {
|
|
950
|
+
filePath,
|
|
951
|
+
action: 'modify',
|
|
952
|
+
content: content, // No change
|
|
953
|
+
description: `API key already exists in ${path.basename(filePath)}`
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
else {
|
|
957
|
+
// Append to existing file
|
|
958
|
+
return {
|
|
959
|
+
filePath,
|
|
960
|
+
action: 'append',
|
|
961
|
+
content: `\n${envVarName}=${this.apiKey}`,
|
|
962
|
+
description: `Added API key to existing ${path.basename(filePath)}`
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
else {
|
|
967
|
+
// Create new file
|
|
968
|
+
return {
|
|
969
|
+
filePath,
|
|
970
|
+
action: 'create',
|
|
971
|
+
content: `${envVarName}=${this.apiKey}`,
|
|
972
|
+
description: `Created ${path.basename(filePath)} with API key`
|
|
973
|
+
};
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
/**
|
|
979
|
+
* AI-Enhanced HumanBehavior SDK Auto-Installation Wizard
|
|
980
|
+
*
|
|
981
|
+
* This wizard uses AI to intelligently detect frameworks, analyze code patterns,
|
|
982
|
+
* and generate optimal integration code that's both future-proof and backward-compatible.
|
|
983
|
+
*
|
|
984
|
+
* 🚀 KEY FEATURES:
|
|
985
|
+
* - AI-powered framework detection beyond package.json
|
|
986
|
+
* - Intelligent code pattern analysis
|
|
987
|
+
* - Future-proof integration strategies
|
|
988
|
+
* - Backward compatibility with legacy frameworks
|
|
989
|
+
* - Adaptive code generation for new frameworks
|
|
990
|
+
* - Smart conflict resolution
|
|
991
|
+
* - Learning from user feedback
|
|
992
|
+
* - Centralized AI service (no user API keys required)
|
|
993
|
+
*/
|
|
994
|
+
/**
|
|
995
|
+
* Default AI Service Implementation
|
|
996
|
+
* Uses heuristic analysis when centralized service is not available
|
|
997
|
+
*/
|
|
998
|
+
class DefaultAIService {
|
|
999
|
+
analyzeCodePatterns(codeSamples) {
|
|
1000
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1001
|
+
return this.analyzeWithHeuristics(codeSamples);
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
resolveConflicts(conflicts, framework) {
|
|
1005
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1006
|
+
// Default conflict resolution strategies
|
|
1007
|
+
const resolutions = [];
|
|
1008
|
+
for (const conflict of conflicts) {
|
|
1009
|
+
switch (conflict) {
|
|
1010
|
+
case 'existing_humanbehavior_code':
|
|
1011
|
+
resolutions.push('update_existing_integration');
|
|
1012
|
+
break;
|
|
1013
|
+
case 'existing_provider':
|
|
1014
|
+
resolutions.push('merge_providers');
|
|
1015
|
+
break;
|
|
1016
|
+
case 'module_system_conflict':
|
|
1017
|
+
resolutions.push('hybrid_module_support');
|
|
1018
|
+
break;
|
|
1019
|
+
default:
|
|
1020
|
+
resolutions.push('skip_conflict');
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
return resolutions;
|
|
1024
|
+
});
|
|
1025
|
+
}
|
|
1026
|
+
generateOptimizations(framework, patterns) {
|
|
1027
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1028
|
+
const optimizations = [];
|
|
1029
|
+
// Framework-specific optimizations
|
|
1030
|
+
switch (framework.type) {
|
|
1031
|
+
case 'react':
|
|
1032
|
+
optimizations.push('Use React.memo for performance optimization');
|
|
1033
|
+
optimizations.push('Implement error boundaries for better error tracking');
|
|
1034
|
+
optimizations.push('Consider using React.lazy for code splitting');
|
|
1035
|
+
break;
|
|
1036
|
+
case 'vue':
|
|
1037
|
+
optimizations.push('Use Vue 3 Composition API for better performance');
|
|
1038
|
+
optimizations.push('Implement proper error handling in components');
|
|
1039
|
+
optimizations.push('Consider using Vue Router for navigation tracking');
|
|
1040
|
+
break;
|
|
1041
|
+
case 'angular':
|
|
1042
|
+
optimizations.push('Use Angular standalone components for better tree-shaking');
|
|
1043
|
+
optimizations.push('Implement proper error handling with ErrorHandler');
|
|
1044
|
+
optimizations.push('Consider using Angular signals for state management');
|
|
1045
|
+
break;
|
|
1046
|
+
default:
|
|
1047
|
+
optimizations.push('Enable performance tracking');
|
|
1048
|
+
optimizations.push('Implement error tracking');
|
|
1049
|
+
optimizations.push('Consider progressive enhancement');
|
|
1050
|
+
}
|
|
1051
|
+
return optimizations;
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
1054
|
+
analyzeWithHeuristics(codeSamples) {
|
|
1055
|
+
const patterns = codeSamples.join(' ').toLowerCase();
|
|
1056
|
+
// Framework detection
|
|
1057
|
+
let framework = { name: 'vanilla', type: 'vanilla' };
|
|
1058
|
+
let confidence = 0.5;
|
|
1059
|
+
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')) {
|
|
1060
|
+
framework = { name: 'nuxt', type: 'nuxt' };
|
|
1061
|
+
confidence = 0.95;
|
|
1062
|
+
}
|
|
1063
|
+
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/')) {
|
|
1064
|
+
framework = { name: 'nextjs', type: 'nextjs' };
|
|
1065
|
+
confidence = 0.95;
|
|
1066
|
+
}
|
|
1067
|
+
else if (patterns.includes('react')) {
|
|
1068
|
+
framework = { name: 'react', type: 'react' };
|
|
1069
|
+
confidence = 0.9;
|
|
1070
|
+
}
|
|
1071
|
+
else if (patterns.includes('vue')) {
|
|
1072
|
+
framework = { name: 'vue', type: 'vue' };
|
|
1073
|
+
confidence = 0.9;
|
|
1074
|
+
}
|
|
1075
|
+
else if (patterns.includes('angular')) {
|
|
1076
|
+
framework = { name: 'angular', type: 'angular' };
|
|
1077
|
+
confidence = 0.9;
|
|
1078
|
+
}
|
|
1079
|
+
else if (patterns.includes('svelte')) {
|
|
1080
|
+
framework = { name: 'svelte', type: 'svelte' };
|
|
1081
|
+
confidence = 0.9;
|
|
1082
|
+
}
|
|
1083
|
+
// Integration strategy
|
|
1084
|
+
let integrationStrategy = 'script';
|
|
1085
|
+
if (framework.type === 'react' || framework.type === 'nextjs') {
|
|
1086
|
+
integrationStrategy = 'provider';
|
|
1087
|
+
}
|
|
1088
|
+
else if (framework.type === 'vue') {
|
|
1089
|
+
integrationStrategy = 'plugin';
|
|
1090
|
+
}
|
|
1091
|
+
else if (framework.type === 'angular') {
|
|
1092
|
+
integrationStrategy = 'module';
|
|
1093
|
+
}
|
|
1094
|
+
// Compatibility mode
|
|
1095
|
+
let compatibilityMode = 'modern';
|
|
1096
|
+
if (patterns.includes('require(') || patterns.includes('var ')) {
|
|
1097
|
+
compatibilityMode = 'legacy';
|
|
1098
|
+
}
|
|
1099
|
+
return {
|
|
1100
|
+
framework,
|
|
1101
|
+
confidence,
|
|
1102
|
+
patterns: codeSamples,
|
|
1103
|
+
conflicts: [],
|
|
1104
|
+
recommendations: [],
|
|
1105
|
+
integrationStrategy,
|
|
1106
|
+
compatibilityMode
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
class AIEnhancedInstallationWizard extends AutoInstallationWizard {
|
|
1111
|
+
constructor(apiKey, projectRoot = process.cwd(), aiService) {
|
|
1112
|
+
super(apiKey, projectRoot);
|
|
1113
|
+
this.learningCache = new Map();
|
|
1114
|
+
this.patternDatabase = new Map();
|
|
1115
|
+
this.aiService = aiService || new DefaultAIService();
|
|
1116
|
+
this.loadLearningData();
|
|
1117
|
+
}
|
|
1118
|
+
/**
|
|
1119
|
+
* AI-enhanced installation with intelligent analysis
|
|
1120
|
+
*/
|
|
1121
|
+
install() {
|
|
1122
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1123
|
+
try {
|
|
1124
|
+
// Step 1: AI-powered framework detection
|
|
1125
|
+
const aiAnalysis = yield this.performAICodeAnalysis();
|
|
1126
|
+
// Step 2: Smart framework detection with AI validation
|
|
1127
|
+
this.framework = yield this.detectFrameworkWithAI(aiAnalysis);
|
|
1128
|
+
// Step 3: Generate AI-optimized modifications
|
|
1129
|
+
const modifications = yield this.generateAIOptimizedModifications(aiAnalysis);
|
|
1130
|
+
// Step 4: Apply modifications with conflict resolution
|
|
1131
|
+
yield this.applyModificationsWithAI(modifications, aiAnalysis);
|
|
1132
|
+
// Step 5: Generate intelligent next steps
|
|
1133
|
+
const nextSteps = this.generateAINextSteps(aiAnalysis);
|
|
1134
|
+
// Step 6: Learn from this installation
|
|
1135
|
+
yield this.learnFromInstallation(aiAnalysis, modifications);
|
|
1136
|
+
return {
|
|
1137
|
+
success: true,
|
|
1138
|
+
framework: this.framework,
|
|
1139
|
+
modifications,
|
|
1140
|
+
errors: [],
|
|
1141
|
+
nextSteps,
|
|
1142
|
+
aiAnalysis,
|
|
1143
|
+
learningData: {
|
|
1144
|
+
patterns: aiAnalysis.patterns,
|
|
1145
|
+
framework: this.framework.name,
|
|
1146
|
+
success: true
|
|
1147
|
+
}
|
|
1148
|
+
};
|
|
1149
|
+
}
|
|
1150
|
+
catch (error) {
|
|
1151
|
+
return {
|
|
1152
|
+
success: false,
|
|
1153
|
+
framework: this.framework || { name: 'unknown', type: 'vanilla' },
|
|
1154
|
+
modifications: [],
|
|
1155
|
+
errors: [error instanceof Error ? error.message : 'Unknown error'],
|
|
1156
|
+
nextSteps: [],
|
|
1157
|
+
aiAnalysis: {
|
|
1158
|
+
framework: { name: 'unknown', type: 'vanilla' },
|
|
1159
|
+
confidence: 0,
|
|
1160
|
+
patterns: [],
|
|
1161
|
+
conflicts: [],
|
|
1162
|
+
recommendations: [],
|
|
1163
|
+
integrationStrategy: 'script',
|
|
1164
|
+
compatibilityMode: 'legacy'
|
|
1165
|
+
},
|
|
1166
|
+
learningData: {
|
|
1167
|
+
patterns: [],
|
|
1168
|
+
framework: 'unknown',
|
|
1169
|
+
success: false
|
|
1170
|
+
}
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* AI-powered code analysis using centralized service
|
|
1177
|
+
*/
|
|
1178
|
+
performAICodeAnalysis() {
|
|
1179
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1180
|
+
const projectFiles = yield this.scanProjectFiles();
|
|
1181
|
+
const codeSamples = yield this.extractCodeSamples(projectFiles);
|
|
1182
|
+
// Use centralized AI service (no user API key required)
|
|
1183
|
+
return yield this.aiService.analyzeCodePatterns(codeSamples);
|
|
1184
|
+
});
|
|
1185
|
+
}
|
|
1186
|
+
/**
|
|
1187
|
+
* Scan project files for analysis
|
|
1188
|
+
*/
|
|
1189
|
+
scanProjectFiles() {
|
|
1190
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1191
|
+
const files = [];
|
|
1192
|
+
const scanDir = (dir, depth = 0) => {
|
|
1193
|
+
if (depth > 3)
|
|
1194
|
+
return; // Limit depth
|
|
1195
|
+
try {
|
|
1196
|
+
const items = fs.readdirSync(dir);
|
|
1197
|
+
for (const item of items) {
|
|
1198
|
+
const fullPath = path.join(dir, item);
|
|
1199
|
+
const stat = fs.statSync(fullPath);
|
|
1200
|
+
if (stat.isDirectory() && !item.startsWith('.') && item !== 'node_modules') {
|
|
1201
|
+
scanDir(fullPath, depth + 1);
|
|
1202
|
+
}
|
|
1203
|
+
else if (stat.isFile() && this.isRelevantFile(item)) {
|
|
1204
|
+
files.push(fullPath);
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
catch (error) {
|
|
1209
|
+
// Skip inaccessible directories
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1212
|
+
scanDir(this.projectRoot);
|
|
1213
|
+
return files;
|
|
1214
|
+
});
|
|
1215
|
+
}
|
|
1216
|
+
/**
|
|
1217
|
+
* Check if file is relevant for analysis
|
|
1218
|
+
*/
|
|
1219
|
+
isRelevantFile(filename) {
|
|
1220
|
+
const relevantExtensions = [
|
|
1221
|
+
'.js', '.jsx', '.ts', '.tsx', '.vue', '.svelte', '.html',
|
|
1222
|
+
'.json', '.config.js', '.config.ts', '.babelrc', '.eslintrc'
|
|
1223
|
+
];
|
|
1224
|
+
const relevantNames = [
|
|
1225
|
+
'package.json', 'tsconfig.json', 'vite.config', 'webpack.config',
|
|
1226
|
+
'next.config', 'nuxt.config', 'angular.json', 'svelte.config',
|
|
1227
|
+
'app/layout', 'app/page', 'pages/index', 'pages/_app', 'pages/_document'
|
|
1228
|
+
];
|
|
1229
|
+
return relevantExtensions.some(ext => filename.endsWith(ext)) ||
|
|
1230
|
+
relevantNames.some(name => filename.includes(name));
|
|
1231
|
+
}
|
|
1232
|
+
/**
|
|
1233
|
+
* Extract code samples for AI analysis
|
|
1234
|
+
*/
|
|
1235
|
+
extractCodeSamples(files) {
|
|
1236
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1237
|
+
const samples = [];
|
|
1238
|
+
for (const file of files.slice(0, 20)) { // Limit to 20 files
|
|
1239
|
+
try {
|
|
1240
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
1241
|
+
const relativePath = path.relative(this.projectRoot, file);
|
|
1242
|
+
// Extract relevant code patterns
|
|
1243
|
+
const patterns = this.extractCodePatterns(content);
|
|
1244
|
+
if (patterns.length > 0) {
|
|
1245
|
+
samples.push(`File: ${relativePath}\n${patterns.join('\n')}`);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
catch (error) {
|
|
1249
|
+
// Skip unreadable files
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
return samples;
|
|
1253
|
+
});
|
|
1254
|
+
}
|
|
1255
|
+
/**
|
|
1256
|
+
* Extract relevant code patterns
|
|
1257
|
+
*/
|
|
1258
|
+
extractCodePatterns(content) {
|
|
1259
|
+
const patterns = [];
|
|
1260
|
+
// Framework-specific patterns
|
|
1261
|
+
const frameworkPatterns = {
|
|
1262
|
+
react: [
|
|
1263
|
+
/import\s+React\s+from\s+['"]react['"]/gi,
|
|
1264
|
+
/from\s+['"]react['"]/gi,
|
|
1265
|
+
/function\s+\w+\s*\(\s*\)\s*{/gi,
|
|
1266
|
+
/const\s+\w+\s*=\s*\(\s*\)\s*=>\s*{/gi
|
|
1267
|
+
],
|
|
1268
|
+
vue: [
|
|
1269
|
+
/import\s+{\s*createApp\s*}\s+from\s+['"]vue['"]/gi,
|
|
1270
|
+
/from\s+['"]vue['"]/gi,
|
|
1271
|
+
/<template>/gi,
|
|
1272
|
+
/<script\s+setup>/gi
|
|
1273
|
+
],
|
|
1274
|
+
angular: [
|
|
1275
|
+
/import\s+{\s*Component\s*}\s+from\s+['"]@angular\/core['"]/gi,
|
|
1276
|
+
/@Component\s*\(\s*{/gi,
|
|
1277
|
+
/from\s+['"]@angular/gi
|
|
1278
|
+
],
|
|
1279
|
+
svelte: [
|
|
1280
|
+
/<script>/gi,
|
|
1281
|
+
/import\s+.*\s+from\s+['"]svelte/gi,
|
|
1282
|
+
/from\s+['"]svelte/gi
|
|
1283
|
+
],
|
|
1284
|
+
nextjs: [
|
|
1285
|
+
/import\s+.*\s+from\s+['"]next/gi,
|
|
1286
|
+
/from\s+['"]next/gi,
|
|
1287
|
+
/export\s+default\s+function\s+Page/gi,
|
|
1288
|
+
/export\s+default\s+function\s+Layout/gi,
|
|
1289
|
+
/export\s+default\s+function\s+Loading/gi,
|
|
1290
|
+
/export\s+default\s+function\s+Error/gi,
|
|
1291
|
+
/export\s+default\s+function\s+Not-found/gi,
|
|
1292
|
+
/useRouter\s+from\s+['"]next\/navigation['"]/gi,
|
|
1293
|
+
/useRouter\s+from\s+['"]next\/router['"]/gi,
|
|
1294
|
+
/Link\s+from\s+['"]next\/link['"]/gi,
|
|
1295
|
+
/Image\s+from\s+['"]next\/image['"]/gi,
|
|
1296
|
+
/getServerSideProps/gi,
|
|
1297
|
+
/getStaticProps/gi,
|
|
1298
|
+
/getStaticPaths/gi,
|
|
1299
|
+
/next\.config/gi,
|
|
1300
|
+
/app\/layout\.tsx/gi,
|
|
1301
|
+
/app\/page\.tsx/gi,
|
|
1302
|
+
/pages\/.*\.tsx/gi,
|
|
1303
|
+
/pages\/.*\.jsx/gi,
|
|
1304
|
+
/pages\/.*\.ts/gi,
|
|
1305
|
+
/pages\/.*\.js/gi
|
|
1306
|
+
],
|
|
1307
|
+
nuxt: [
|
|
1308
|
+
/import\s+.*\s+from\s+['"]nuxt/gi,
|
|
1309
|
+
/from\s+['"]nuxt/gi,
|
|
1310
|
+
/export\s+default\s+defineNuxtConfig/gi,
|
|
1311
|
+
/defineNuxtConfig/gi,
|
|
1312
|
+
/nuxt\.config\.ts/gi,
|
|
1313
|
+
/nuxt\.config\.js/gi,
|
|
1314
|
+
/@nuxt\//gi,
|
|
1315
|
+
/#app/gi,
|
|
1316
|
+
/useNuxtApp/gi,
|
|
1317
|
+
/useRuntimeConfig/gi,
|
|
1318
|
+
/useSeoMeta/gi,
|
|
1319
|
+
/useHead/gi,
|
|
1320
|
+
/useLazyFetch/gi,
|
|
1321
|
+
/useFetch/gi,
|
|
1322
|
+
/useAsyncData/gi,
|
|
1323
|
+
/<NuxtLayout/gi,
|
|
1324
|
+
/<NuxtPage/gi,
|
|
1325
|
+
/NuxtLayout/gi,
|
|
1326
|
+
/NuxtPage/gi,
|
|
1327
|
+
/pages\/.*\.vue/gi,
|
|
1328
|
+
/layouts\/.*\.vue/gi,
|
|
1329
|
+
/components\/.*\.vue/gi,
|
|
1330
|
+
/composables\/.*\.ts/gi,
|
|
1331
|
+
/middleware\/.*\.ts/gi,
|
|
1332
|
+
/server\/.*\.ts/gi,
|
|
1333
|
+
/plugins\/.*\.ts/gi,
|
|
1334
|
+
/public\//gi,
|
|
1335
|
+
/assets\//gi,
|
|
1336
|
+
/content\//gi
|
|
1337
|
+
]
|
|
1338
|
+
};
|
|
1339
|
+
// Extract patterns for each framework
|
|
1340
|
+
for (const [framework, regexes] of Object.entries(frameworkPatterns)) {
|
|
1341
|
+
for (const regex of regexes) {
|
|
1342
|
+
const matches = content.match(regex);
|
|
1343
|
+
if (matches) {
|
|
1344
|
+
// Add raw patterns for heuristic analysis
|
|
1345
|
+
patterns.push(...matches.slice(0, 3));
|
|
1346
|
+
// Also add formatted patterns for debugging
|
|
1347
|
+
patterns.push(`${framework.toUpperCase()}: ${matches.slice(0, 3).join(', ')}`);
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
// Extract import patterns
|
|
1352
|
+
const importMatches = content.match(/import\s+.*\s+from\s+['"][^'"]+['"]/gi);
|
|
1353
|
+
if (importMatches) {
|
|
1354
|
+
patterns.push(`IMPORTS: ${importMatches.slice(0, 5).join(', ')}`);
|
|
1355
|
+
}
|
|
1356
|
+
// Extract export patterns
|
|
1357
|
+
const exportMatches = content.match(/export\s+.*/gi);
|
|
1358
|
+
if (exportMatches) {
|
|
1359
|
+
patterns.push(`EXPORTS: ${exportMatches.slice(0, 3).join(', ')}`);
|
|
1360
|
+
}
|
|
1361
|
+
return patterns;
|
|
1362
|
+
}
|
|
1363
|
+
/**
|
|
1364
|
+
* AI-enhanced framework detection
|
|
1365
|
+
*/
|
|
1366
|
+
detectFrameworkWithAI(aiAnalysis) {
|
|
1367
|
+
const _super = Object.create(null, {
|
|
1368
|
+
detectFramework: { get: () => super.detectFramework }
|
|
1369
|
+
});
|
|
1370
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1371
|
+
// Combine AI analysis with traditional detection
|
|
1372
|
+
const traditionalFramework = yield _super.detectFramework.call(this);
|
|
1373
|
+
// Use AI analysis if confidence is high, but preserve bundler info
|
|
1374
|
+
if (aiAnalysis.confidence > 0.8) {
|
|
1375
|
+
return Object.assign(Object.assign({}, aiAnalysis.framework), { bundler: traditionalFramework.bundler, packageManager: traditionalFramework.packageManager, hasTypeScript: traditionalFramework.hasTypeScript, hasRouter: traditionalFramework.hasRouter, projectRoot: this.projectRoot });
|
|
1376
|
+
}
|
|
1377
|
+
// Merge AI insights with traditional detection
|
|
1378
|
+
return Object.assign(Object.assign({}, traditionalFramework), (aiAnalysis.framework.type !== 'vanilla' && {
|
|
1379
|
+
type: aiAnalysis.framework.type,
|
|
1380
|
+
name: aiAnalysis.framework.name
|
|
1381
|
+
}));
|
|
1382
|
+
});
|
|
1383
|
+
}
|
|
1384
|
+
/**
|
|
1385
|
+
* Generate AI-optimized modifications
|
|
1386
|
+
*/
|
|
1387
|
+
generateAIOptimizedModifications(aiAnalysis) {
|
|
1388
|
+
const _super = Object.create(null, {
|
|
1389
|
+
generateModifications: { get: () => super.generateModifications }
|
|
1390
|
+
});
|
|
1391
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1392
|
+
const baseModifications = yield _super.generateModifications.call(this);
|
|
1393
|
+
// Enhance with AI recommendations
|
|
1394
|
+
const enhancedModifications = baseModifications.map(mod => {
|
|
1395
|
+
return this.enhanceModificationWithAI(mod, aiAnalysis);
|
|
1396
|
+
});
|
|
1397
|
+
// Add AI-specific optimizations
|
|
1398
|
+
const aiOptimizations = this.generateAIOptimizations(aiAnalysis);
|
|
1399
|
+
enhancedModifications.push(...aiOptimizations);
|
|
1400
|
+
return enhancedModifications;
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
/**
|
|
1404
|
+
* Enhance modification with AI insights
|
|
1405
|
+
*/
|
|
1406
|
+
enhanceModificationWithAI(mod, aiAnalysis) {
|
|
1407
|
+
let enhancedContent = mod.content;
|
|
1408
|
+
// Add compatibility comments
|
|
1409
|
+
if (aiAnalysis.compatibilityMode === 'legacy') {
|
|
1410
|
+
enhancedContent = `// HumanBehavior SDK - Legacy Compatibility Mode\n${enhancedContent}`;
|
|
1411
|
+
}
|
|
1412
|
+
// Add future-proofing comments
|
|
1413
|
+
if (aiAnalysis.integrationStrategy === 'provider') {
|
|
1414
|
+
enhancedContent = `// HumanBehavior SDK - Provider Pattern (Future-proof)\n${enhancedContent}`;
|
|
1415
|
+
}
|
|
1416
|
+
// Add conflict resolution
|
|
1417
|
+
if (aiAnalysis.conflicts.length > 0) {
|
|
1418
|
+
enhancedContent = `// Conflict Resolution: ${aiAnalysis.conflicts.join(', ')}\n${enhancedContent}`;
|
|
1419
|
+
}
|
|
1420
|
+
return Object.assign(Object.assign({}, mod), { content: enhancedContent, description: `${mod.description} (AI-optimized)` });
|
|
1421
|
+
}
|
|
1422
|
+
/**
|
|
1423
|
+
* Generate AI-specific optimizations
|
|
1424
|
+
*/
|
|
1425
|
+
generateAIOptimizations(aiAnalysis) {
|
|
1426
|
+
const optimizations = [];
|
|
1427
|
+
// AI optimizations are now handled through environment variables and code injection
|
|
1428
|
+
// No separate config file needed - everything is integrated into the existing codebase
|
|
1429
|
+
return optimizations;
|
|
1430
|
+
}
|
|
1431
|
+
/**
|
|
1432
|
+
* Apply modifications with AI conflict resolution
|
|
1433
|
+
*/
|
|
1434
|
+
applyModificationsWithAI(modifications, aiAnalysis) {
|
|
1435
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1436
|
+
for (const modification of modifications) {
|
|
1437
|
+
try {
|
|
1438
|
+
// Check for conflicts
|
|
1439
|
+
const conflicts = yield this.detectConflicts(modification);
|
|
1440
|
+
if (conflicts.length > 0) {
|
|
1441
|
+
// Resolve conflicts using centralized AI service
|
|
1442
|
+
const resolutions = yield this.aiService.resolveConflicts(conflicts, aiAnalysis.framework);
|
|
1443
|
+
const resolvedModification = yield this.resolveConflicts(modification, conflicts, resolutions, aiAnalysis);
|
|
1444
|
+
yield this.applyModification(resolvedModification);
|
|
1445
|
+
}
|
|
1446
|
+
else {
|
|
1447
|
+
yield this.applyModification(modification);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
catch (error) {
|
|
1451
|
+
throw new Error(`Failed to apply AI-optimized modification to ${modification.filePath}: ${error}`);
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
});
|
|
1455
|
+
}
|
|
1456
|
+
/**
|
|
1457
|
+
* Detect potential conflicts
|
|
1458
|
+
*/
|
|
1459
|
+
detectConflicts(modification) {
|
|
1460
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1461
|
+
const conflicts = [];
|
|
1462
|
+
if (fs.existsSync(modification.filePath)) {
|
|
1463
|
+
const existingContent = fs.readFileSync(modification.filePath, 'utf8');
|
|
1464
|
+
// Check for existing HumanBehavior code
|
|
1465
|
+
if (existingContent.includes('HumanBehavior') || existingContent.includes('humanbehavior')) {
|
|
1466
|
+
conflicts.push('existing_humanbehavior_code');
|
|
1467
|
+
}
|
|
1468
|
+
// Check for conflicting providers/plugins
|
|
1469
|
+
if (modification.content.includes('Provider') && existingContent.includes('Provider')) {
|
|
1470
|
+
conflicts.push('existing_provider');
|
|
1471
|
+
}
|
|
1472
|
+
// Check for TypeScript conflicts
|
|
1473
|
+
if (modification.content.includes('import') && existingContent.includes('require(')) {
|
|
1474
|
+
conflicts.push('module_system_conflict');
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
return conflicts;
|
|
1478
|
+
});
|
|
1479
|
+
}
|
|
1480
|
+
/**
|
|
1481
|
+
* Resolve conflicts with AI
|
|
1482
|
+
*/
|
|
1483
|
+
resolveConflicts(modification, conflicts, resolutions, aiAnalysis) {
|
|
1484
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1485
|
+
let resolvedContent = modification.content;
|
|
1486
|
+
for (let i = 0; i < conflicts.length; i++) {
|
|
1487
|
+
const conflict = conflicts[i];
|
|
1488
|
+
const resolution = resolutions[i];
|
|
1489
|
+
switch (resolution) {
|
|
1490
|
+
case 'update_existing_integration':
|
|
1491
|
+
resolvedContent = `// Updated HumanBehavior Integration\n${resolvedContent}`;
|
|
1492
|
+
break;
|
|
1493
|
+
case 'merge_providers':
|
|
1494
|
+
resolvedContent = resolvedContent.replace(/<HumanBehaviorProvider/g, '<HumanBehaviorProvider key="updated"');
|
|
1495
|
+
break;
|
|
1496
|
+
case 'hybrid_module_support':
|
|
1497
|
+
resolvedContent = `// Hybrid module system support\n${resolvedContent}`;
|
|
1498
|
+
break;
|
|
1499
|
+
case 'skip_conflict':
|
|
1500
|
+
// Skip this modification
|
|
1501
|
+
return Object.assign(Object.assign({}, modification), { content: '', description: `${modification.description} (skipped due to conflict)` });
|
|
1502
|
+
default:
|
|
1503
|
+
// Default resolution
|
|
1504
|
+
resolvedContent = `// Conflict resolved: ${conflict}\n${resolvedContent}`;
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
return Object.assign(Object.assign({}, modification), { content: resolvedContent, description: `${modification.description} (conflict-resolved)` });
|
|
1508
|
+
});
|
|
1509
|
+
}
|
|
1510
|
+
/**
|
|
1511
|
+
* Apply single modification
|
|
1512
|
+
*/
|
|
1513
|
+
applyModification(modification) {
|
|
1514
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1515
|
+
if (!modification.content)
|
|
1516
|
+
return; // Skip empty modifications
|
|
1517
|
+
const dir = path.dirname(modification.filePath);
|
|
1518
|
+
if (!fs.existsSync(dir)) {
|
|
1519
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
1520
|
+
}
|
|
1521
|
+
switch (modification.action) {
|
|
1522
|
+
case 'create':
|
|
1523
|
+
fs.writeFileSync(modification.filePath, modification.content);
|
|
1524
|
+
break;
|
|
1525
|
+
case 'modify':
|
|
1526
|
+
fs.writeFileSync(modification.filePath, modification.content);
|
|
1527
|
+
break;
|
|
1528
|
+
case 'append':
|
|
1529
|
+
fs.appendFileSync(modification.filePath, '\n' + modification.content);
|
|
1530
|
+
break;
|
|
1531
|
+
}
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1534
|
+
/**
|
|
1535
|
+
* Generate AI-enhanced next steps
|
|
1536
|
+
*/
|
|
1537
|
+
generateAINextSteps(aiAnalysis) {
|
|
1538
|
+
const steps = [
|
|
1539
|
+
'✅ AI-optimized SDK installation completed!',
|
|
1540
|
+
`🎯 Framework detected: ${aiAnalysis.framework.name} (confidence: ${Math.round(aiAnalysis.confidence * 100)}%)`,
|
|
1541
|
+
`🔧 Integration strategy: ${aiAnalysis.integrationStrategy}`,
|
|
1542
|
+
`🔄 Compatibility mode: ${aiAnalysis.compatibilityMode}`,
|
|
1543
|
+
'🚀 Your app is now tracking user behavior with AI-optimized configuration'
|
|
1544
|
+
];
|
|
1545
|
+
if (aiAnalysis.recommendations.length > 0) {
|
|
1546
|
+
steps.push('💡 AI Recommendations:');
|
|
1547
|
+
aiAnalysis.recommendations.forEach(rec => steps.push(` • ${rec}`));
|
|
1548
|
+
}
|
|
1549
|
+
return steps;
|
|
1550
|
+
}
|
|
1551
|
+
/**
|
|
1552
|
+
* Learn from installation for future improvements
|
|
1553
|
+
*/
|
|
1554
|
+
learnFromInstallation(aiAnalysis, modifications) {
|
|
1555
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1556
|
+
const learningData = {
|
|
1557
|
+
timestamp: new Date().toISOString(),
|
|
1558
|
+
framework: aiAnalysis.framework.name,
|
|
1559
|
+
patterns: aiAnalysis.patterns,
|
|
1560
|
+
integrationStrategy: aiAnalysis.integrationStrategy,
|
|
1561
|
+
compatibilityMode: aiAnalysis.compatibilityMode,
|
|
1562
|
+
modifications: modifications.length,
|
|
1563
|
+
success: true
|
|
1564
|
+
};
|
|
1565
|
+
// Store learning data
|
|
1566
|
+
this.learningCache.set(`${aiAnalysis.framework.name}_${Date.now()}`, learningData);
|
|
1567
|
+
// Update pattern database
|
|
1568
|
+
if (!this.patternDatabase.has(aiAnalysis.framework.name)) {
|
|
1569
|
+
this.patternDatabase.set(aiAnalysis.framework.name, []);
|
|
1570
|
+
}
|
|
1571
|
+
this.patternDatabase.get(aiAnalysis.framework.name).push(learningData);
|
|
1572
|
+
// Save to disk
|
|
1573
|
+
yield this.saveLearningData();
|
|
1574
|
+
});
|
|
1575
|
+
}
|
|
1576
|
+
/**
|
|
1577
|
+
* Load learning data from disk
|
|
1578
|
+
*/
|
|
1579
|
+
loadLearningData() {
|
|
1580
|
+
// Don't load learning data from user's project - keep it in memory only
|
|
1581
|
+
// This prevents cluttering the user's project with internal files
|
|
1582
|
+
}
|
|
1583
|
+
/**
|
|
1584
|
+
* Save learning data to disk
|
|
1585
|
+
*/
|
|
1586
|
+
saveLearningData() {
|
|
1587
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1588
|
+
// Don't save learning data to user's project - keep it in memory only
|
|
1589
|
+
// This prevents cluttering the user's project with internal files
|
|
1590
|
+
});
|
|
1591
|
+
}
|
|
1592
|
+
/**
|
|
1593
|
+
* Get AI insights for a specific framework
|
|
1594
|
+
*/
|
|
1595
|
+
getAIInsights(frameworkName) {
|
|
1596
|
+
return this.patternDatabase.get(frameworkName) || [];
|
|
1597
|
+
}
|
|
1598
|
+
/**
|
|
1599
|
+
* Get learning statistics
|
|
1600
|
+
*/
|
|
1601
|
+
getLearningStats() {
|
|
1602
|
+
const stats = {
|
|
1603
|
+
totalInstallations: this.learningCache.size,
|
|
1604
|
+
frameworks: {},
|
|
1605
|
+
patterns: {}
|
|
1606
|
+
};
|
|
1607
|
+
for (const [framework, data] of this.patternDatabase.entries()) {
|
|
1608
|
+
stats.frameworks[framework] = data.length;
|
|
1609
|
+
}
|
|
1610
|
+
return stats;
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
/**
|
|
1614
|
+
* Browser-based AI installation wizard
|
|
1615
|
+
*/
|
|
1616
|
+
class AIBrowserInstallationWizard {
|
|
1617
|
+
constructor(apiKey, aiService) {
|
|
1618
|
+
this.apiKey = apiKey;
|
|
1619
|
+
this.aiService = aiService || new DefaultAIService();
|
|
1620
|
+
}
|
|
1621
|
+
install() {
|
|
1622
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1623
|
+
try {
|
|
1624
|
+
// AI-powered browser detection
|
|
1625
|
+
const aiAnalysis = yield this.performBrowserAIAnalysis();
|
|
1626
|
+
// Generate AI-optimized browser modifications
|
|
1627
|
+
const modifications = this.generateAIBrowserModifications(aiAnalysis);
|
|
1628
|
+
return {
|
|
1629
|
+
success: true,
|
|
1630
|
+
framework: aiAnalysis.framework,
|
|
1631
|
+
modifications,
|
|
1632
|
+
errors: [],
|
|
1633
|
+
nextSteps: [
|
|
1634
|
+
'✅ AI-optimized browser integration ready!',
|
|
1635
|
+
`🎯 Framework detected: ${aiAnalysis.framework.name}`,
|
|
1636
|
+
`🔧 Integration strategy: ${aiAnalysis.integrationStrategy}`,
|
|
1637
|
+
'📋 Copy the generated code to your project',
|
|
1638
|
+
'🚀 Your app will be ready to track user behavior'
|
|
1639
|
+
],
|
|
1640
|
+
aiAnalysis,
|
|
1641
|
+
learningData: {
|
|
1642
|
+
patterns: aiAnalysis.patterns,
|
|
1643
|
+
framework: aiAnalysis.framework.name,
|
|
1644
|
+
success: true
|
|
1645
|
+
}
|
|
1646
|
+
};
|
|
1647
|
+
}
|
|
1648
|
+
catch (error) {
|
|
1649
|
+
return {
|
|
1650
|
+
success: false,
|
|
1651
|
+
framework: { name: 'unknown', type: 'vanilla' },
|
|
1652
|
+
modifications: [],
|
|
1653
|
+
errors: [error instanceof Error ? error.message : 'Unknown error'],
|
|
1654
|
+
nextSteps: [],
|
|
1655
|
+
aiAnalysis: {
|
|
1656
|
+
framework: { name: 'unknown', type: 'vanilla' },
|
|
1657
|
+
confidence: 0,
|
|
1658
|
+
patterns: [],
|
|
1659
|
+
conflicts: [],
|
|
1660
|
+
recommendations: [],
|
|
1661
|
+
integrationStrategy: 'script',
|
|
1662
|
+
compatibilityMode: 'legacy'
|
|
1663
|
+
},
|
|
1664
|
+
learningData: {
|
|
1665
|
+
patterns: [],
|
|
1666
|
+
framework: 'unknown',
|
|
1667
|
+
success: false
|
|
1668
|
+
}
|
|
1669
|
+
};
|
|
1670
|
+
}
|
|
1671
|
+
});
|
|
1672
|
+
}
|
|
1673
|
+
performBrowserAIAnalysis() {
|
|
1674
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1675
|
+
// Browser-based framework detection
|
|
1676
|
+
this.detectBrowserFramework();
|
|
1677
|
+
// Analyze browser environment
|
|
1678
|
+
const patterns = this.analyzeBrowserPatterns();
|
|
1679
|
+
// Use centralized AI service for analysis
|
|
1680
|
+
const codeSamples = [`Browser Environment: ${patterns.join(', ')}`];
|
|
1681
|
+
return yield this.aiService.analyzeCodePatterns(codeSamples);
|
|
1682
|
+
});
|
|
1683
|
+
}
|
|
1684
|
+
detectBrowserFramework() {
|
|
1685
|
+
if (typeof window !== 'undefined') {
|
|
1686
|
+
if (window.React) {
|
|
1687
|
+
return { name: 'react', type: 'react' };
|
|
1688
|
+
}
|
|
1689
|
+
if (window.Vue) {
|
|
1690
|
+
return { name: 'vue', type: 'vue' };
|
|
1691
|
+
}
|
|
1692
|
+
if (window.angular) {
|
|
1693
|
+
return { name: 'angular', type: 'angular' };
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
return { name: 'vanilla', type: 'vanilla' };
|
|
1697
|
+
}
|
|
1698
|
+
analyzeBrowserPatterns() {
|
|
1699
|
+
const patterns = [];
|
|
1700
|
+
if (typeof window !== 'undefined') {
|
|
1701
|
+
// Analyze global objects
|
|
1702
|
+
if (window.React)
|
|
1703
|
+
patterns.push('React global detected');
|
|
1704
|
+
if (window.Vue)
|
|
1705
|
+
patterns.push('Vue global detected');
|
|
1706
|
+
if (window.angular)
|
|
1707
|
+
patterns.push('Angular global detected');
|
|
1708
|
+
// Analyze DOM patterns
|
|
1709
|
+
if (document.querySelector('[data-reactroot]'))
|
|
1710
|
+
patterns.push('React DOM detected');
|
|
1711
|
+
if (document.querySelector('[data-vue]'))
|
|
1712
|
+
patterns.push('Vue DOM detected');
|
|
1713
|
+
// Analyze script patterns
|
|
1714
|
+
const scripts = document.querySelectorAll('script');
|
|
1715
|
+
scripts.forEach(script => {
|
|
1716
|
+
if (script.src.includes('react'))
|
|
1717
|
+
patterns.push('React script detected');
|
|
1718
|
+
if (script.src.includes('vue'))
|
|
1719
|
+
patterns.push('Vue script detected');
|
|
1720
|
+
});
|
|
1721
|
+
}
|
|
1722
|
+
return patterns;
|
|
1723
|
+
}
|
|
1724
|
+
generateAIBrowserModifications(aiAnalysis) {
|
|
1725
|
+
const modifications = [];
|
|
1726
|
+
switch (aiAnalysis.framework.type) {
|
|
1727
|
+
case 'react':
|
|
1728
|
+
modifications.push({
|
|
1729
|
+
filePath: 'App.jsx',
|
|
1730
|
+
action: 'create',
|
|
1731
|
+
content: `// AI-Optimized React Integration
|
|
1732
|
+
import { HumanBehaviorProvider } from 'humanbehavior-js/react';
|
|
1733
|
+
|
|
1734
|
+
function App() {
|
|
1735
|
+
return (
|
|
1736
|
+
<HumanBehaviorProvider
|
|
1737
|
+
apiKey="${this.apiKey}"
|
|
1738
|
+
config={{
|
|
1739
|
+
// AI-generated optimizations
|
|
1740
|
+
enablePerformanceTracking: true,
|
|
1741
|
+
enableErrorTracking: true,
|
|
1742
|
+
framework: '${aiAnalysis.framework.name}',
|
|
1743
|
+
integrationStrategy: '${aiAnalysis.integrationStrategy}'
|
|
1744
|
+
}}
|
|
1745
|
+
>
|
|
1746
|
+
{/* Your app components */}
|
|
1747
|
+
</HumanBehaviorProvider>
|
|
1748
|
+
);
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
export default App;`,
|
|
1752
|
+
description: 'AI-optimized React component with HumanBehaviorProvider'
|
|
1753
|
+
});
|
|
1754
|
+
break;
|
|
1755
|
+
default:
|
|
1756
|
+
modifications.push({
|
|
1757
|
+
filePath: 'humanbehavior-init.js',
|
|
1758
|
+
action: 'create',
|
|
1759
|
+
content: `// AI-Optimized Vanilla JS Integration
|
|
1760
|
+
import { HumanBehaviorTracker } from 'humanbehavior-js';
|
|
1761
|
+
|
|
1762
|
+
const tracker = HumanBehaviorTracker.init('${this.apiKey}', {
|
|
1763
|
+
// AI-generated configuration
|
|
1764
|
+
framework: '${aiAnalysis.framework.name}',
|
|
1765
|
+
integrationStrategy: '${aiAnalysis.integrationStrategy}',
|
|
1766
|
+
compatibilityMode: '${aiAnalysis.compatibilityMode}',
|
|
1767
|
+
enablePerformanceTracking: true,
|
|
1768
|
+
enableErrorTracking: true
|
|
1769
|
+
});`,
|
|
1770
|
+
description: 'AI-optimized vanilla JS initialization'
|
|
1771
|
+
});
|
|
1772
|
+
}
|
|
1773
|
+
return modifications;
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
/**
|
|
1778
|
+
* Remote AI Service Implementation
|
|
1779
|
+
*
|
|
1780
|
+
* This connects to your deployed Lambda function via API Gateway
|
|
1781
|
+
*/
|
|
1782
|
+
class RemoteAIService {
|
|
1783
|
+
constructor(config) {
|
|
1784
|
+
this.config = Object.assign({ timeout: 10000 }, config);
|
|
1785
|
+
}
|
|
1786
|
+
/**
|
|
1787
|
+
* Analyze code patterns using your deployed AI service
|
|
1788
|
+
*/
|
|
1789
|
+
analyzeCodePatterns(codeSamples) {
|
|
1790
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1791
|
+
try {
|
|
1792
|
+
const response = yield fetch(`${this.config.apiEndpoint}/analyze`, {
|
|
1793
|
+
method: 'POST',
|
|
1794
|
+
headers: {
|
|
1795
|
+
'Content-Type': 'application/json',
|
|
1796
|
+
},
|
|
1797
|
+
body: JSON.stringify({ codeSamples }),
|
|
1798
|
+
signal: AbortSignal.timeout(this.config.timeout || 10000)
|
|
1799
|
+
});
|
|
1800
|
+
if (!response.ok) {
|
|
1801
|
+
throw new Error(`AI service returned ${response.status}: ${response.statusText}`);
|
|
1802
|
+
}
|
|
1803
|
+
const result = yield response.json();
|
|
1804
|
+
return result.analysis;
|
|
1805
|
+
}
|
|
1806
|
+
catch (error) {
|
|
1807
|
+
console.warn('Remote AI service failed, falling back to heuristic analysis:', error);
|
|
1808
|
+
return this.performHeuristicAnalysis(codeSamples);
|
|
1809
|
+
}
|
|
1810
|
+
});
|
|
1811
|
+
}
|
|
1812
|
+
/**
|
|
1813
|
+
* Resolve conflicts using your deployed AI service
|
|
1814
|
+
*/
|
|
1815
|
+
resolveConflicts(conflicts, framework) {
|
|
1816
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1817
|
+
try {
|
|
1818
|
+
const response = yield fetch(`${this.config.apiEndpoint}/resolve-conflicts`, {
|
|
1819
|
+
method: 'POST',
|
|
1820
|
+
headers: {
|
|
1821
|
+
'Content-Type': 'application/json',
|
|
1822
|
+
},
|
|
1823
|
+
body: JSON.stringify({ conflicts, framework }),
|
|
1824
|
+
signal: AbortSignal.timeout(this.config.timeout || 10000)
|
|
1825
|
+
});
|
|
1826
|
+
if (!response.ok) {
|
|
1827
|
+
throw new Error(`AI service returned ${response.status}: ${response.statusText}`);
|
|
1828
|
+
}
|
|
1829
|
+
const result = yield response.json();
|
|
1830
|
+
return result.resolutions || [];
|
|
1831
|
+
}
|
|
1832
|
+
catch (error) {
|
|
1833
|
+
console.warn('Remote AI conflict resolution failed, using heuristic approach:', error);
|
|
1834
|
+
return this.resolveConflictsHeuristic(conflicts, framework);
|
|
1835
|
+
}
|
|
1836
|
+
});
|
|
1837
|
+
}
|
|
1838
|
+
/**
|
|
1839
|
+
* Generate optimizations using your deployed AI service
|
|
1840
|
+
*/
|
|
1841
|
+
generateOptimizations(framework, patterns) {
|
|
1842
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1843
|
+
try {
|
|
1844
|
+
const response = yield fetch(`${this.config.apiEndpoint}/optimize`, {
|
|
1845
|
+
method: 'POST',
|
|
1846
|
+
headers: {
|
|
1847
|
+
'Content-Type': 'application/json',
|
|
1848
|
+
},
|
|
1849
|
+
body: JSON.stringify({ framework, patterns }),
|
|
1850
|
+
signal: AbortSignal.timeout(this.config.timeout || 10000)
|
|
1851
|
+
});
|
|
1852
|
+
if (!response.ok) {
|
|
1853
|
+
throw new Error(`AI service returned ${response.status}: ${response.statusText}`);
|
|
1854
|
+
}
|
|
1855
|
+
const result = yield response.json();
|
|
1856
|
+
return result.optimizations || [];
|
|
1857
|
+
}
|
|
1858
|
+
catch (error) {
|
|
1859
|
+
console.warn('Remote AI optimization generation failed, using heuristic approach:', error);
|
|
1860
|
+
return this.generateOptimizationsHeuristic(framework, patterns);
|
|
1861
|
+
}
|
|
1862
|
+
});
|
|
1863
|
+
}
|
|
1864
|
+
/**
|
|
1865
|
+
* Heuristic analysis fallback
|
|
1866
|
+
*/
|
|
1867
|
+
performHeuristicAnalysis(codeSamples) {
|
|
1868
|
+
const patterns = codeSamples.join(' ').toLowerCase();
|
|
1869
|
+
// Framework detection
|
|
1870
|
+
let framework = { name: 'vanilla', type: 'vanilla' };
|
|
1871
|
+
let confidence = 0.5;
|
|
1872
|
+
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')) {
|
|
1873
|
+
framework = { name: 'nuxt', type: 'nuxt' };
|
|
1874
|
+
confidence = 0.95;
|
|
1875
|
+
}
|
|
1876
|
+
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/')) {
|
|
1877
|
+
framework = { name: 'nextjs', type: 'nextjs' };
|
|
1878
|
+
confidence = 0.95;
|
|
1879
|
+
}
|
|
1880
|
+
else if (patterns.includes('react')) {
|
|
1881
|
+
framework = { name: 'react', type: 'react' };
|
|
1882
|
+
confidence = 0.9;
|
|
1883
|
+
}
|
|
1884
|
+
else if (patterns.includes('vue')) {
|
|
1885
|
+
framework = { name: 'vue', type: 'vue' };
|
|
1886
|
+
confidence = 0.9;
|
|
1887
|
+
}
|
|
1888
|
+
else if (patterns.includes('angular')) {
|
|
1889
|
+
framework = { name: 'angular', type: 'angular' };
|
|
1890
|
+
confidence = 0.9;
|
|
1891
|
+
}
|
|
1892
|
+
else if (patterns.includes('svelte')) {
|
|
1893
|
+
framework = { name: 'svelte', type: 'svelte' };
|
|
1894
|
+
confidence = 0.9;
|
|
1895
|
+
}
|
|
1896
|
+
// Integration strategy
|
|
1897
|
+
let integrationStrategy = 'script';
|
|
1898
|
+
if (framework.type === 'react' || framework.type === 'nextjs') {
|
|
1899
|
+
integrationStrategy = 'provider';
|
|
1900
|
+
}
|
|
1901
|
+
else if (framework.type === 'vue') {
|
|
1902
|
+
integrationStrategy = 'plugin';
|
|
1903
|
+
}
|
|
1904
|
+
else if (framework.type === 'angular') {
|
|
1905
|
+
integrationStrategy = 'module';
|
|
1906
|
+
}
|
|
1907
|
+
// Compatibility mode
|
|
1908
|
+
let compatibilityMode = 'modern';
|
|
1909
|
+
if (patterns.includes('require(') || patterns.includes('var ')) {
|
|
1910
|
+
compatibilityMode = 'legacy';
|
|
1911
|
+
}
|
|
1912
|
+
return {
|
|
1913
|
+
framework,
|
|
1914
|
+
confidence,
|
|
1915
|
+
patterns: codeSamples,
|
|
1916
|
+
conflicts: [],
|
|
1917
|
+
recommendations: [],
|
|
1918
|
+
integrationStrategy,
|
|
1919
|
+
compatibilityMode
|
|
1920
|
+
};
|
|
1921
|
+
}
|
|
1922
|
+
/**
|
|
1923
|
+
* Heuristic conflict resolution
|
|
1924
|
+
*/
|
|
1925
|
+
resolveConflictsHeuristic(conflicts, framework) {
|
|
1926
|
+
const resolutions = [];
|
|
1927
|
+
for (const conflict of conflicts) {
|
|
1928
|
+
switch (conflict) {
|
|
1929
|
+
case 'existing_humanbehavior_code':
|
|
1930
|
+
resolutions.push('update_existing_integration');
|
|
1931
|
+
break;
|
|
1932
|
+
case 'existing_provider':
|
|
1933
|
+
resolutions.push('merge_providers');
|
|
1934
|
+
break;
|
|
1935
|
+
case 'module_system_conflict':
|
|
1936
|
+
resolutions.push('hybrid_module_support');
|
|
1937
|
+
break;
|
|
1938
|
+
default:
|
|
1939
|
+
resolutions.push('skip_conflict');
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
return resolutions;
|
|
1943
|
+
}
|
|
1944
|
+
/**
|
|
1945
|
+
* Heuristic optimization generation
|
|
1946
|
+
*/
|
|
1947
|
+
generateOptimizationsHeuristic(framework, patterns) {
|
|
1948
|
+
const optimizations = [];
|
|
1949
|
+
switch (framework.type) {
|
|
1950
|
+
case 'react':
|
|
1951
|
+
optimizations.push('Use React.memo for performance optimization');
|
|
1952
|
+
optimizations.push('Implement error boundaries for better error tracking');
|
|
1953
|
+
optimizations.push('Consider using React.lazy for code splitting');
|
|
1954
|
+
break;
|
|
1955
|
+
case 'vue':
|
|
1956
|
+
optimizations.push('Use Vue 3 Composition API for better performance');
|
|
1957
|
+
optimizations.push('Implement proper error handling in components');
|
|
1958
|
+
optimizations.push('Consider using Vue Router for navigation tracking');
|
|
1959
|
+
break;
|
|
1960
|
+
case 'angular':
|
|
1961
|
+
optimizations.push('Use Angular standalone components for better tree-shaking');
|
|
1962
|
+
optimizations.push('Implement proper error handling with ErrorHandler');
|
|
1963
|
+
optimizations.push('Consider using Angular signals for state management');
|
|
1964
|
+
break;
|
|
1965
|
+
default:
|
|
1966
|
+
optimizations.push('Enable performance tracking');
|
|
1967
|
+
optimizations.push('Implement error tracking');
|
|
1968
|
+
optimizations.push('Consider progressive enhancement');
|
|
1969
|
+
}
|
|
1970
|
+
return optimizations;
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1974
|
+
/**
|
|
1975
|
+
* Manual Framework Installation Wizard
|
|
1976
|
+
*
|
|
1977
|
+
* This wizard allows users to manually specify their framework instead of auto-detection.
|
|
1978
|
+
* Useful when auto-detection fails or users want more control.
|
|
1979
|
+
*/
|
|
1980
|
+
class ManualFrameworkInstallationWizard extends AutoInstallationWizard {
|
|
1981
|
+
constructor(apiKey, projectRoot = process.cwd(), framework) {
|
|
1982
|
+
super(apiKey, projectRoot);
|
|
1983
|
+
this.selectedFramework = framework.toLowerCase();
|
|
1984
|
+
this.framework = this.createFrameworkInfo(this.selectedFramework);
|
|
1985
|
+
}
|
|
1986
|
+
/**
|
|
1987
|
+
* Manual installation with user-specified framework
|
|
1988
|
+
*/
|
|
1989
|
+
install() {
|
|
1990
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1991
|
+
try {
|
|
1992
|
+
// Step 1: Handle framework selection
|
|
1993
|
+
if (this.selectedFramework === 'auto') {
|
|
1994
|
+
// Use full AI detection for "Other" option
|
|
1995
|
+
this.framework = yield this.runFullDetection();
|
|
1996
|
+
}
|
|
1997
|
+
else {
|
|
1998
|
+
// Set framework based on user selection
|
|
1999
|
+
this.framework = this.createFrameworkInfo(this.selectedFramework);
|
|
2000
|
+
if (!this.framework) {
|
|
2001
|
+
this.framework = { name: 'unknown', type: 'vanilla' };
|
|
2002
|
+
}
|
|
2003
|
+
// Step 2: Run full detection logic to find entry points, file names, etc.
|
|
2004
|
+
const detectedFramework = yield this.runFullDetection();
|
|
2005
|
+
// Step 3: Merge manual framework with detected details
|
|
2006
|
+
this.framework = Object.assign(Object.assign({}, detectedFramework), { name: this.framework.name, type: this.framework.type });
|
|
2007
|
+
}
|
|
2008
|
+
// Step 4: Install package
|
|
2009
|
+
yield this.installPackage();
|
|
2010
|
+
// Step 5: Generate and apply code modifications
|
|
2011
|
+
const modifications = yield this.generateModifications();
|
|
2012
|
+
yield this.applyModifications(modifications);
|
|
2013
|
+
// Step 6: Generate next steps
|
|
2014
|
+
const nextSteps = this.generateManualNextSteps();
|
|
2015
|
+
return {
|
|
2016
|
+
success: true,
|
|
2017
|
+
framework: this.framework,
|
|
2018
|
+
modifications,
|
|
2019
|
+
errors: [],
|
|
2020
|
+
nextSteps,
|
|
2021
|
+
selectedFramework: this.selectedFramework,
|
|
2022
|
+
manualMode: true
|
|
2023
|
+
};
|
|
2024
|
+
}
|
|
2025
|
+
catch (error) {
|
|
2026
|
+
return {
|
|
2027
|
+
success: false,
|
|
2028
|
+
framework: this.framework || { name: 'unknown', type: 'vanilla' },
|
|
2029
|
+
modifications: [],
|
|
2030
|
+
errors: [error instanceof Error ? error.message : 'Unknown error'],
|
|
2031
|
+
nextSteps: [],
|
|
2032
|
+
selectedFramework: this.selectedFramework,
|
|
2033
|
+
manualMode: true
|
|
2034
|
+
};
|
|
2035
|
+
}
|
|
2036
|
+
});
|
|
2037
|
+
}
|
|
2038
|
+
/**
|
|
2039
|
+
* Run full detection logic to find entry points, file names, bundler, etc.
|
|
2040
|
+
*/
|
|
2041
|
+
runFullDetection() {
|
|
2042
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2043
|
+
if (this.selectedFramework === 'auto') {
|
|
2044
|
+
// Use AI service for auto-detection
|
|
2045
|
+
const aiService = new RemoteAIService({
|
|
2046
|
+
apiEndpoint: 'https://ik3zxh4790.execute-api.us-east-1.amazonaws.com/prod'
|
|
2047
|
+
});
|
|
2048
|
+
// Use AI service directly for detection
|
|
2049
|
+
const projectFiles = yield this.scanProjectFiles();
|
|
2050
|
+
const codeSamples = yield this.extractCodeSamples(projectFiles);
|
|
2051
|
+
const aiAnalysis = yield aiService.analyzeCodePatterns(codeSamples);
|
|
2052
|
+
return aiAnalysis.framework;
|
|
2053
|
+
}
|
|
2054
|
+
else {
|
|
2055
|
+
// Use traditional detection for manual frameworks
|
|
2056
|
+
const tempWizard = new AutoInstallationWizard(this.apiKey, this.projectRoot);
|
|
2057
|
+
const detected = yield tempWizard.detectFramework();
|
|
2058
|
+
return detected;
|
|
2059
|
+
}
|
|
2060
|
+
});
|
|
2061
|
+
}
|
|
2062
|
+
/**
|
|
2063
|
+
* Scan project files for analysis
|
|
2064
|
+
*/
|
|
2065
|
+
scanProjectFiles() {
|
|
2066
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2067
|
+
const files = [];
|
|
2068
|
+
const scanDir = (dir, depth = 0) => {
|
|
2069
|
+
if (depth > 3)
|
|
2070
|
+
return; // Limit depth
|
|
2071
|
+
try {
|
|
2072
|
+
const items = fs.readdirSync(dir);
|
|
2073
|
+
for (const item of items) {
|
|
2074
|
+
const fullPath = path.join(dir, item);
|
|
2075
|
+
const stat = fs.statSync(fullPath);
|
|
2076
|
+
if (stat.isDirectory() && !item.startsWith('.') && item !== 'node_modules') {
|
|
2077
|
+
scanDir(fullPath, depth + 1);
|
|
2078
|
+
}
|
|
2079
|
+
else if (stat.isFile() && this.isRelevantFile(item)) {
|
|
2080
|
+
files.push(fullPath);
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
catch (error) {
|
|
2085
|
+
// Skip inaccessible directories
|
|
2086
|
+
}
|
|
2087
|
+
};
|
|
2088
|
+
scanDir(this.projectRoot);
|
|
2089
|
+
return files;
|
|
2090
|
+
});
|
|
2091
|
+
}
|
|
2092
|
+
/**
|
|
2093
|
+
* Check if file is relevant for analysis
|
|
2094
|
+
*/
|
|
2095
|
+
isRelevantFile(filename) {
|
|
2096
|
+
const relevantExtensions = [
|
|
2097
|
+
'.js', '.jsx', '.ts', '.tsx', '.vue', '.svelte', '.html',
|
|
2098
|
+
'.json', '.config.js', '.config.ts', '.babelrc', '.eslintrc'
|
|
2099
|
+
];
|
|
2100
|
+
const relevantNames = [
|
|
2101
|
+
'package.json', 'tsconfig.json', 'vite.config', 'webpack.config',
|
|
2102
|
+
'next.config', 'nuxt.config', 'angular.json', 'svelte.config'
|
|
2103
|
+
];
|
|
2104
|
+
return relevantExtensions.some(ext => filename.endsWith(ext)) ||
|
|
2105
|
+
relevantNames.some(name => filename.includes(name));
|
|
2106
|
+
}
|
|
2107
|
+
/**
|
|
2108
|
+
* Extract code samples for AI analysis
|
|
2109
|
+
*/
|
|
2110
|
+
extractCodeSamples(files) {
|
|
2111
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2112
|
+
const samples = [];
|
|
2113
|
+
for (const file of files.slice(0, 20)) { // Limit to 20 files
|
|
2114
|
+
try {
|
|
2115
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
2116
|
+
const relativePath = path.relative(this.projectRoot, file);
|
|
2117
|
+
samples.push(`File: ${relativePath}\n${content.substring(0, 1000)}`);
|
|
2118
|
+
}
|
|
2119
|
+
catch (error) {
|
|
2120
|
+
// Skip unreadable files
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
return samples;
|
|
2124
|
+
});
|
|
2125
|
+
}
|
|
2126
|
+
/**
|
|
2127
|
+
* Create framework info based on user selection
|
|
2128
|
+
*/
|
|
2129
|
+
createFrameworkInfo(framework) {
|
|
2130
|
+
const frameworkMap = {
|
|
2131
|
+
'react': { name: 'react', type: 'react' },
|
|
2132
|
+
'nextjs': { name: 'nextjs', type: 'nextjs' },
|
|
2133
|
+
'next': { name: 'nextjs', type: 'nextjs' },
|
|
2134
|
+
'vue': { name: 'vue', type: 'vue' },
|
|
2135
|
+
'nuxt': { name: 'nuxt', type: 'nuxt' },
|
|
2136
|
+
'nuxtjs': { name: 'nuxt', type: 'nuxt' },
|
|
2137
|
+
'angular': { name: 'angular', type: 'angular' },
|
|
2138
|
+
'svelte': { name: 'svelte', type: 'svelte' },
|
|
2139
|
+
'sveltekit': { name: 'svelte', type: 'svelte' },
|
|
2140
|
+
'remix': { name: 'remix', type: 'remix' },
|
|
2141
|
+
'vanilla': { name: 'vanilla', type: 'vanilla' },
|
|
2142
|
+
'node': { name: 'node', type: 'node' },
|
|
2143
|
+
'auto': { name: 'auto-detected', type: 'auto' }
|
|
2144
|
+
};
|
|
2145
|
+
return frameworkMap[framework] || { name: framework, type: 'vanilla' };
|
|
2146
|
+
}
|
|
2147
|
+
/**
|
|
2148
|
+
* Override framework detection to use manual selection
|
|
2149
|
+
*/
|
|
2150
|
+
detectFramework() {
|
|
2151
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2152
|
+
return this.framework || { name: 'unknown', type: 'vanilla' };
|
|
2153
|
+
});
|
|
2154
|
+
}
|
|
2155
|
+
/**
|
|
2156
|
+
* Generate next steps with manual mode info
|
|
2157
|
+
*/
|
|
2158
|
+
generateManualNextSteps() {
|
|
2159
|
+
var _a;
|
|
2160
|
+
return [
|
|
2161
|
+
'✅ Manual framework installation completed!',
|
|
2162
|
+
`🎯 Selected framework: ${((_a = this.framework) === null || _a === void 0 ? void 0 : _a.name) || 'unknown'}`,
|
|
2163
|
+
`🔧 Integration strategy: ${this.getIntegrationStrategy()}`,
|
|
2164
|
+
'🚀 Your app is now ready to track user behavior',
|
|
2165
|
+
'📊 View sessions in your HumanBehavior dashboard'
|
|
2166
|
+
];
|
|
2167
|
+
}
|
|
2168
|
+
/**
|
|
2169
|
+
* Get integration strategy based on framework
|
|
2170
|
+
*/
|
|
2171
|
+
getIntegrationStrategy() {
|
|
2172
|
+
var _a;
|
|
2173
|
+
if (!((_a = this.framework) === null || _a === void 0 ? void 0 : _a.type))
|
|
2174
|
+
return 'script';
|
|
2175
|
+
switch (this.framework.type) {
|
|
2176
|
+
case 'react':
|
|
2177
|
+
case 'nextjs':
|
|
2178
|
+
return 'provider';
|
|
2179
|
+
case 'vue':
|
|
2180
|
+
return 'plugin';
|
|
2181
|
+
case 'angular':
|
|
2182
|
+
return 'module';
|
|
2183
|
+
default:
|
|
2184
|
+
return 'script';
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
/**
|
|
2190
|
+
* AI-Enhanced HumanBehavior SDK Auto-Installation CLI
|
|
2191
|
+
*
|
|
2192
|
+
* Usage: npx humanbehavior-js ai-auto-install [api-key]
|
|
2193
|
+
*
|
|
2194
|
+
* This tool uses AI to intelligently detect frameworks, analyze code patterns,
|
|
2195
|
+
* and generate optimal integration code that's both future-proof and backward-compatible.
|
|
2196
|
+
*/
|
|
2197
|
+
class AIAutoInstallCLI {
|
|
2198
|
+
constructor(options) {
|
|
2199
|
+
this.options = options;
|
|
2200
|
+
this.rl = readline.createInterface({
|
|
2201
|
+
input: process.stdin,
|
|
2202
|
+
output: process.stdout
|
|
2203
|
+
});
|
|
2204
|
+
}
|
|
2205
|
+
run() {
|
|
2206
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2207
|
+
console.log('🤖 AI-Enhanced HumanBehavior SDK Auto-Installation');
|
|
2208
|
+
console.log('================================================\n');
|
|
2209
|
+
try {
|
|
2210
|
+
// Get API key
|
|
2211
|
+
const apiKey = yield this.getApiKey();
|
|
2212
|
+
if (!apiKey) {
|
|
2213
|
+
console.error('❌ API key is required');
|
|
2214
|
+
process.exit(1);
|
|
2215
|
+
}
|
|
2216
|
+
// Get project path
|
|
2217
|
+
const projectPath = this.options.projectPath || process.cwd();
|
|
2218
|
+
// Choose installation mode
|
|
2219
|
+
const installationMode = yield this.chooseInstallationMode();
|
|
2220
|
+
// Confirm installation
|
|
2221
|
+
if (!this.options.yes) {
|
|
2222
|
+
const confirmed = yield this.confirmInstallation(projectPath, installationMode);
|
|
2223
|
+
if (!confirmed) {
|
|
2224
|
+
console.log('Installation cancelled.');
|
|
2225
|
+
process.exit(0);
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2228
|
+
// Run installation
|
|
2229
|
+
console.log('🔍 Analyzing your project with AI...');
|
|
2230
|
+
let result;
|
|
2231
|
+
if (this.options.browser) {
|
|
2232
|
+
const wizard = new AIBrowserInstallationWizard(apiKey);
|
|
2233
|
+
result = yield wizard.install();
|
|
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
|
+
}
|
|
2251
|
+
// Display results
|
|
2252
|
+
this.displayResults(result, installationMode);
|
|
2253
|
+
}
|
|
2254
|
+
catch (error) {
|
|
2255
|
+
console.error('❌ Error:', error instanceof Error ? error.message : error);
|
|
2256
|
+
process.exit(1);
|
|
2257
|
+
}
|
|
2258
|
+
finally {
|
|
2259
|
+
this.rl.close();
|
|
2260
|
+
}
|
|
2261
|
+
});
|
|
2262
|
+
}
|
|
2263
|
+
getApiKey() {
|
|
2264
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2265
|
+
if (this.options.apiKey) {
|
|
2266
|
+
return this.options.apiKey;
|
|
2267
|
+
}
|
|
2268
|
+
return new Promise((resolve) => {
|
|
2269
|
+
this.rl.question('Enter your HumanBehavior API key: ', (answer) => {
|
|
2270
|
+
resolve(answer.trim());
|
|
2271
|
+
});
|
|
2272
|
+
});
|
|
2273
|
+
});
|
|
2274
|
+
}
|
|
2275
|
+
chooseInstallationMode() {
|
|
2276
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2277
|
+
if (this.options.manual && this.options.framework) {
|
|
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
|
+
});
|
|
2299
|
+
});
|
|
2300
|
+
});
|
|
2301
|
+
}
|
|
2302
|
+
confirmInstallation(projectPath, installationMode) {
|
|
2303
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2304
|
+
console.log(`📁 Project path: ${projectPath}`);
|
|
2305
|
+
console.log(`🤖 Installation mode: ${this.getInstallationModeDisplay(installationMode)}`);
|
|
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
|
+
});
|
|
2317
|
+
});
|
|
2318
|
+
});
|
|
2319
|
+
}
|
|
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
|
+
chooseFramework() {
|
|
2334
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2335
|
+
console.log('\n🎯 Choose your framework:');
|
|
2336
|
+
console.log('1. Vanilla JS (HTML)');
|
|
2337
|
+
console.log('2. React');
|
|
2338
|
+
console.log('3. Next.js');
|
|
2339
|
+
console.log('4. Vue');
|
|
2340
|
+
console.log('5. Nuxt');
|
|
2341
|
+
console.log('6. Angular');
|
|
2342
|
+
console.log('7. Svelte');
|
|
2343
|
+
console.log('8. Remix');
|
|
2344
|
+
console.log('9. Node.js');
|
|
2345
|
+
console.log('10. Other (Auto-detect)\n');
|
|
2346
|
+
return new Promise((resolve) => {
|
|
2347
|
+
this.rl.question('Select framework (1-10, default: 1): ', (answer) => {
|
|
2348
|
+
const choice = answer.trim() || '1';
|
|
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
|
+
});
|
|
2353
|
+
});
|
|
2354
|
+
});
|
|
2355
|
+
}
|
|
2356
|
+
displayResults(result, installationMode) {
|
|
2357
|
+
if (result.success) {
|
|
2358
|
+
console.log('\n✅ Installation completed successfully!');
|
|
2359
|
+
if (installationMode === 'ai' && result.aiAnalysis) {
|
|
2360
|
+
console.log(`🎯 AI Analysis Results:`);
|
|
2361
|
+
console.log(` Framework: ${result.aiAnalysis.framework.name} (confidence: ${Math.round(result.aiAnalysis.confidence * 100)}%)`);
|
|
2362
|
+
console.log(` Integration Strategy: ${result.aiAnalysis.integrationStrategy}`);
|
|
2363
|
+
console.log(` Compatibility Mode: ${result.aiAnalysis.compatibilityMode}`);
|
|
2364
|
+
if (result.aiAnalysis.patterns.length > 0) {
|
|
2365
|
+
console.log(` Detected Patterns: ${result.aiAnalysis.patterns.length} patterns`);
|
|
2366
|
+
}
|
|
2367
|
+
if (result.aiAnalysis.recommendations.length > 0) {
|
|
2368
|
+
console.log(` AI Recommendations:`);
|
|
2369
|
+
result.aiAnalysis.recommendations.forEach((rec) => {
|
|
2370
|
+
console.log(` • ${rec}`);
|
|
2371
|
+
});
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
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
|
+
}
|
|
2401
|
+
else {
|
|
2402
|
+
console.log('\n❌ Installation failed:');
|
|
2403
|
+
result.errors.forEach((error) => {
|
|
2404
|
+
console.log(` ${error}`);
|
|
2405
|
+
});
|
|
2406
|
+
console.log('\n💡 Try running with --help for more options');
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
// CLI argument parsing
|
|
2411
|
+
function parseArgs$1() {
|
|
2412
|
+
const args = process.argv.slice(2);
|
|
2413
|
+
const options = {};
|
|
2414
|
+
for (let i = 0; i < args.length; i++) {
|
|
2415
|
+
const arg = args[i];
|
|
2416
|
+
if (arg === '--yes' || arg === '-y') {
|
|
2417
|
+
options.yes = true;
|
|
2418
|
+
}
|
|
2419
|
+
else if (arg === '--dry-run' || arg === '-d') {
|
|
2420
|
+
options.dryRun = true;
|
|
2421
|
+
}
|
|
2422
|
+
else if (arg === '--project' || arg === '-p') {
|
|
2423
|
+
options.projectPath = args[i + 1];
|
|
2424
|
+
i++;
|
|
2425
|
+
}
|
|
2426
|
+
else if (arg === '--traditional' || arg === '-t') {
|
|
2427
|
+
options.useAI = false;
|
|
2428
|
+
}
|
|
2429
|
+
else if (arg === '--browser' || arg === '-b') {
|
|
2430
|
+
options.browser = true;
|
|
2431
|
+
}
|
|
2432
|
+
else if (arg === '--manual' || arg === '-m') {
|
|
2433
|
+
options.manual = true;
|
|
2434
|
+
}
|
|
2435
|
+
else if (arg === '--framework' || arg === '-f') {
|
|
2436
|
+
options.framework = args[i + 1];
|
|
2437
|
+
i++;
|
|
2438
|
+
}
|
|
2439
|
+
else if (arg === '--help' || arg === '-h') {
|
|
2440
|
+
showHelp$1();
|
|
2441
|
+
process.exit(0);
|
|
2442
|
+
}
|
|
2443
|
+
else if (!options.apiKey) {
|
|
2444
|
+
options.apiKey = arg;
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
return options;
|
|
2448
|
+
}
|
|
2449
|
+
function showHelp$1() {
|
|
2450
|
+
console.log(`
|
|
2451
|
+
AI-Enhanced HumanBehavior SDK Auto-Installation CLI
|
|
2452
|
+
|
|
2453
|
+
Usage: npx humanbehavior-js ai-auto-install [api-key] [options]
|
|
2454
|
+
|
|
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
|
+
Options:
|
|
2462
|
+
-y, --yes Skip all prompts and use defaults
|
|
2463
|
+
-d, --dry-run Show what would be changed without making changes
|
|
2464
|
+
-p, --project <path> Project directory (default: current directory)
|
|
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
|
|
2470
|
+
|
|
2471
|
+
Installation Modes:
|
|
2472
|
+
1. Manual AI-Enhanced (default): Choose your framework and use AI for optimization
|
|
2473
|
+
2. Traditional: Standard framework detection and installation
|
|
2474
|
+
3. Browser: Browser-based AI detection and code generation
|
|
2475
|
+
|
|
2476
|
+
Examples:
|
|
2477
|
+
npx humanbehavior-js ai-auto-install your-api-key
|
|
2478
|
+
npx humanbehavior-js ai-auto-install your-api-key --manual --framework react
|
|
2479
|
+
npx humanbehavior-js ai-auto-install your-api-key --traditional
|
|
2480
|
+
npx humanbehavior-js ai-auto-install your-api-key --browser
|
|
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
|
|
2510
|
+
`);
|
|
2511
|
+
}
|
|
2512
|
+
// Main execution
|
|
2513
|
+
const options$1 = parseArgs$1();
|
|
2514
|
+
// Check if we have enough arguments (api-key is required)
|
|
2515
|
+
if (process.argv.length < 3 || process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
2516
|
+
showHelp$1();
|
|
2517
|
+
process.exit(0);
|
|
2518
|
+
}
|
|
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
|
+
|
|
2525
|
+
/**
|
|
2526
|
+
* HumanBehavior SDK Auto-Installation CLI
|
|
2527
|
+
*
|
|
2528
|
+
* Usage: npx humanbehavior-js auto-install [api-key]
|
|
2529
|
+
*
|
|
2530
|
+
* This tool automatically detects the user's framework and modifies their codebase
|
|
2531
|
+
* to integrate the SDK with minimal user intervention.
|
|
2532
|
+
*/
|
|
2533
|
+
class AutoInstallCLI {
|
|
2534
|
+
constructor(options) {
|
|
2535
|
+
this.options = options;
|
|
2536
|
+
this.rl = readline.createInterface({
|
|
2537
|
+
input: process.stdin,
|
|
2538
|
+
output: process.stdout
|
|
2539
|
+
});
|
|
2540
|
+
}
|
|
2541
|
+
run() {
|
|
2542
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2543
|
+
console.log('🚀 HumanBehavior SDK Auto-Installation');
|
|
2544
|
+
console.log('=====================================\n');
|
|
2545
|
+
try {
|
|
2546
|
+
// Get API key
|
|
2547
|
+
const apiKey = yield this.getApiKey();
|
|
2548
|
+
if (!apiKey) {
|
|
2549
|
+
console.error('❌ API key is required');
|
|
2550
|
+
process.exit(1);
|
|
2551
|
+
}
|
|
2552
|
+
// Get project path
|
|
2553
|
+
const projectPath = this.options.projectPath || process.cwd();
|
|
2554
|
+
// Confirm installation
|
|
2555
|
+
if (!this.options.yes) {
|
|
2556
|
+
const confirmed = yield this.confirmInstallation(projectPath);
|
|
2557
|
+
if (!confirmed) {
|
|
2558
|
+
console.log('Installation cancelled.');
|
|
2559
|
+
process.exit(0);
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
// Run auto-installation
|
|
2563
|
+
console.log('🔍 Detecting your project setup...');
|
|
2564
|
+
const wizard = new AutoInstallationWizard(apiKey, projectPath);
|
|
2565
|
+
const result = yield wizard.install();
|
|
2566
|
+
// Display results
|
|
2567
|
+
this.displayResults(result);
|
|
2568
|
+
}
|
|
2569
|
+
catch (error) {
|
|
2570
|
+
console.error('❌ Error:', error instanceof Error ? error.message : error);
|
|
2571
|
+
process.exit(1);
|
|
2572
|
+
}
|
|
2573
|
+
finally {
|
|
2574
|
+
this.rl.close();
|
|
2575
|
+
}
|
|
2576
|
+
});
|
|
2577
|
+
}
|
|
2578
|
+
getApiKey() {
|
|
2579
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2580
|
+
if (this.options.apiKey) {
|
|
2581
|
+
return this.options.apiKey;
|
|
2582
|
+
}
|
|
2583
|
+
return new Promise((resolve) => {
|
|
2584
|
+
this.rl.question('Enter your HumanBehavior API key: ', (answer) => {
|
|
2585
|
+
resolve(answer.trim());
|
|
2586
|
+
});
|
|
2587
|
+
});
|
|
2588
|
+
});
|
|
2589
|
+
}
|
|
2590
|
+
confirmInstallation(projectPath) {
|
|
2591
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2592
|
+
console.log(`📁 Project path: ${projectPath}`);
|
|
2593
|
+
console.log('⚠️ This will modify your codebase to integrate HumanBehavior SDK.');
|
|
2594
|
+
console.log(' The following changes will be made:');
|
|
2595
|
+
console.log(' - Install humanbehavior-js package');
|
|
2596
|
+
console.log(' - Modify your main app file');
|
|
2597
|
+
console.log(' - Create environment files');
|
|
2598
|
+
console.log(' - Add SDK initialization code\n');
|
|
2599
|
+
return new Promise((resolve) => {
|
|
2600
|
+
this.rl.question('Continue with auto-installation? (y/n): ', (answer) => {
|
|
2601
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
2602
|
+
});
|
|
2603
|
+
});
|
|
2604
|
+
});
|
|
2605
|
+
}
|
|
2606
|
+
displayResults(result) {
|
|
2607
|
+
if (result.success) {
|
|
2608
|
+
console.log('\n✅ Installation completed successfully!');
|
|
2609
|
+
console.log(`📦 Framework detected: ${result.framework.name}`);
|
|
2610
|
+
if (result.framework.bundler) {
|
|
2611
|
+
console.log(`🔧 Bundler: ${result.framework.bundler}`);
|
|
2612
|
+
}
|
|
2613
|
+
if (result.framework.packageManager) {
|
|
2614
|
+
console.log(`📋 Package Manager: ${result.framework.packageManager}`);
|
|
2615
|
+
}
|
|
2616
|
+
console.log('\n📝 Changes made:');
|
|
2617
|
+
result.modifications.forEach((mod) => {
|
|
2618
|
+
console.log(` ${mod.action === 'create' ? '➕' : '✏️'} ${mod.description}`);
|
|
2619
|
+
console.log(` ${mod.filePath}`);
|
|
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');
|
|
2627
|
+
}
|
|
2628
|
+
else {
|
|
2629
|
+
console.log('\n❌ Installation failed:');
|
|
2630
|
+
result.errors.forEach((error) => {
|
|
2631
|
+
console.log(` ${error}`);
|
|
2632
|
+
});
|
|
2633
|
+
console.log('\n💡 Try running with --help for more options');
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
}
|
|
2637
|
+
// CLI argument parsing
|
|
2638
|
+
function parseArgs() {
|
|
2639
|
+
const args = process.argv.slice(2);
|
|
2640
|
+
const options = {};
|
|
2641
|
+
for (let i = 0; i < args.length; i++) {
|
|
2642
|
+
const arg = args[i];
|
|
2643
|
+
if (arg === '--yes' || arg === '-y') {
|
|
2644
|
+
options.yes = true;
|
|
2645
|
+
}
|
|
2646
|
+
else if (arg === '--dry-run' || arg === '-d') {
|
|
2647
|
+
options.dryRun = true;
|
|
2648
|
+
}
|
|
2649
|
+
else if (arg === '--project' || arg === '-p') {
|
|
2650
|
+
options.projectPath = args[i + 1];
|
|
2651
|
+
i++;
|
|
2652
|
+
}
|
|
2653
|
+
else if (arg === '--help' || arg === '-h') {
|
|
2654
|
+
showHelp();
|
|
2655
|
+
process.exit(0);
|
|
2656
|
+
}
|
|
2657
|
+
else if (!options.apiKey) {
|
|
2658
|
+
options.apiKey = arg;
|
|
2659
|
+
}
|
|
2660
|
+
}
|
|
2661
|
+
return options;
|
|
2662
|
+
}
|
|
2663
|
+
function showHelp() {
|
|
2664
|
+
console.log(`
|
|
2665
|
+
HumanBehavior SDK Auto-Installation CLI
|
|
2666
|
+
|
|
2667
|
+
Usage: npx humanbehavior-js [api-key] [options]
|
|
2668
|
+
|
|
2669
|
+
This tool automatically detects your project's framework and modifies your codebase
|
|
2670
|
+
to integrate the HumanBehavior SDK with minimal user intervention.
|
|
2671
|
+
|
|
2672
|
+
Arguments:
|
|
2673
|
+
api-key Your HumanBehavior API key
|
|
2674
|
+
|
|
2675
|
+
Options:
|
|
2676
|
+
-y, --yes Skip all prompts and use defaults
|
|
2677
|
+
-d, --dry-run Show what would be changed without making changes
|
|
2678
|
+
-p, --project <path> Project directory (default: current directory)
|
|
2679
|
+
-h, --help Show this help message
|
|
2680
|
+
|
|
2681
|
+
Examples:
|
|
2682
|
+
npx humanbehavior-js your-api-key
|
|
2683
|
+
npx humanbehavior-js your-api-key --yes
|
|
2684
|
+
npx humanbehavior-js your-api-key -p /path/to/project
|
|
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
|
|
2702
|
+
`);
|
|
2703
|
+
}
|
|
2704
|
+
// Main execution
|
|
2705
|
+
const options = parseArgs();
|
|
2706
|
+
// Check if we have enough arguments (api-key is required)
|
|
2707
|
+
if (process.argv.length < 3 || process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
2708
|
+
showHelp();
|
|
2709
|
+
process.exit(0);
|
|
2710
|
+
}
|
|
2711
|
+
const cli = new AutoInstallCLI(options);
|
|
2712
|
+
cli.run().catch((error) => {
|
|
2713
|
+
console.error('❌ Fatal error:', error);
|
|
2714
|
+
process.exit(1);
|
|
2715
|
+
});
|
|
2716
|
+
|
|
2717
|
+
/**
|
|
2718
|
+
* Centralized AI Service Implementation
|
|
2719
|
+
*
|
|
2720
|
+
* This service runs on your backend infrastructure and provides AI-powered
|
|
2721
|
+
* code analysis without requiring users to provide their own API keys.
|
|
2722
|
+
*
|
|
2723
|
+
* The service can be deployed as:
|
|
2724
|
+
* - AWS Lambda function
|
|
2725
|
+
* - Docker container
|
|
2726
|
+
* - Express.js server
|
|
2727
|
+
* - Cloud function
|
|
2728
|
+
*/
|
|
2729
|
+
/**
|
|
2730
|
+
* Centralized AI Service Implementation
|
|
2731
|
+
* This runs on your backend infrastructure
|
|
2732
|
+
*/
|
|
2733
|
+
class CentralizedAIService {
|
|
2734
|
+
constructor(config) {
|
|
2735
|
+
this.cache = new Map();
|
|
2736
|
+
this.config = Object.assign({ openaiModel: 'gpt-4', maxTokens: 2000, temperature: 0.3, enableCaching: true, cacheTTL: 3600 }, config);
|
|
2737
|
+
this.initializeOpenAI();
|
|
2738
|
+
}
|
|
2739
|
+
/**
|
|
2740
|
+
* Initialize OpenAI client
|
|
2741
|
+
*/
|
|
2742
|
+
initializeOpenAI() {
|
|
2743
|
+
try {
|
|
2744
|
+
// Import OpenAI dynamically to avoid bundling issues
|
|
2745
|
+
const { OpenAI } = require('openai');
|
|
2746
|
+
this.openai = new OpenAI({
|
|
2747
|
+
apiKey: this.config.openaiApiKey
|
|
2748
|
+
});
|
|
2749
|
+
}
|
|
2750
|
+
catch (error) {
|
|
2751
|
+
console.warn('OpenAI not available, falling back to heuristic analysis');
|
|
2752
|
+
this.openai = null;
|
|
2753
|
+
}
|
|
2754
|
+
}
|
|
2755
|
+
/**
|
|
2756
|
+
* Analyze code patterns using AI
|
|
2757
|
+
*/
|
|
2758
|
+
analyzeCodePatterns(codeSamples) {
|
|
2759
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2760
|
+
const request = {
|
|
2761
|
+
codeSamples,
|
|
2762
|
+
timestamp: new Date().toISOString()
|
|
2763
|
+
};
|
|
2764
|
+
// Check cache first
|
|
2765
|
+
const cacheKey = this.generateCacheKey(request);
|
|
2766
|
+
if (this.config.enableCaching) {
|
|
2767
|
+
const cached = this.cache.get(cacheKey);
|
|
2768
|
+
if (cached && this.isCacheValid(cached.timestamp)) {
|
|
2769
|
+
return cached.analysis;
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2772
|
+
const analysis = yield this.performAIAnalysis(request);
|
|
2773
|
+
// Cache the result
|
|
2774
|
+
if (this.config.enableCaching) {
|
|
2775
|
+
this.cache.set(cacheKey, {
|
|
2776
|
+
analysis,
|
|
2777
|
+
timestamp: Date.now()
|
|
2778
|
+
});
|
|
2779
|
+
}
|
|
2780
|
+
return analysis;
|
|
2781
|
+
});
|
|
2782
|
+
}
|
|
2783
|
+
/**
|
|
2784
|
+
* Resolve conflicts using AI
|
|
2785
|
+
*/
|
|
2786
|
+
resolveConflicts(conflicts, framework) {
|
|
2787
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2788
|
+
var _a, _b;
|
|
2789
|
+
const request = {
|
|
2790
|
+
conflicts,
|
|
2791
|
+
framework,
|
|
2792
|
+
codeContext: 'HumanBehavior SDK integration'
|
|
2793
|
+
};
|
|
2794
|
+
if (!this.openai) {
|
|
2795
|
+
return this.resolveConflictsHeuristic(conflicts, framework);
|
|
2796
|
+
}
|
|
2797
|
+
try {
|
|
2798
|
+
const prompt = this.buildConflictResolutionPrompt(request);
|
|
2799
|
+
const response = yield this.openai.chat.completions.create({
|
|
2800
|
+
model: this.config.openaiModel,
|
|
2801
|
+
messages: [
|
|
2802
|
+
{
|
|
2803
|
+
role: 'system',
|
|
2804
|
+
content: 'You are an expert at resolving code integration conflicts. Provide specific resolution strategies.'
|
|
2805
|
+
},
|
|
2806
|
+
{
|
|
2807
|
+
role: 'user',
|
|
2808
|
+
content: prompt
|
|
2809
|
+
}
|
|
2810
|
+
],
|
|
2811
|
+
max_tokens: this.config.maxTokens,
|
|
2812
|
+
temperature: this.config.temperature
|
|
2813
|
+
});
|
|
2814
|
+
const content = (_b = (_a = response.choices[0]) === null || _a === void 0 ? void 0 : _a.message) === null || _b === void 0 ? void 0 : _b.content;
|
|
2815
|
+
if (content && typeof content === 'string') {
|
|
2816
|
+
return this.parseConflictResolutions(content);
|
|
2817
|
+
}
|
|
2818
|
+
return [];
|
|
2819
|
+
}
|
|
2820
|
+
catch (error) {
|
|
2821
|
+
console.warn('AI conflict resolution failed, using heuristic approach:', error instanceof Error ? error.message : 'Unknown error');
|
|
2822
|
+
}
|
|
2823
|
+
return this.resolveConflictsHeuristic(conflicts, framework);
|
|
2824
|
+
});
|
|
2825
|
+
}
|
|
2826
|
+
/**
|
|
2827
|
+
* Generate optimizations using AI
|
|
2828
|
+
*/
|
|
2829
|
+
generateOptimizations(framework, patterns) {
|
|
2830
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2831
|
+
var _a, _b;
|
|
2832
|
+
const request = {
|
|
2833
|
+
framework,
|
|
2834
|
+
patterns,
|
|
2835
|
+
projectContext: 'HumanBehavior SDK integration'
|
|
2836
|
+
};
|
|
2837
|
+
if (!this.openai) {
|
|
2838
|
+
return this.generateOptimizationsHeuristic(framework, patterns);
|
|
2839
|
+
}
|
|
2840
|
+
try {
|
|
2841
|
+
const prompt = this.buildOptimizationPrompt(request);
|
|
2842
|
+
const response = yield this.openai.chat.completions.create({
|
|
2843
|
+
model: this.config.openaiModel,
|
|
2844
|
+
messages: [
|
|
2845
|
+
{
|
|
2846
|
+
role: 'system',
|
|
2847
|
+
content: 'You are an expert at optimizing code integration. Provide specific, actionable recommendations.'
|
|
2848
|
+
},
|
|
2849
|
+
{
|
|
2850
|
+
role: 'user',
|
|
2851
|
+
content: prompt
|
|
2852
|
+
}
|
|
2853
|
+
],
|
|
2854
|
+
max_tokens: this.config.maxTokens,
|
|
2855
|
+
temperature: this.config.temperature
|
|
2856
|
+
});
|
|
2857
|
+
const content = (_b = (_a = response.choices[0]) === null || _a === void 0 ? void 0 : _a.message) === null || _b === void 0 ? void 0 : _b.content;
|
|
2858
|
+
if (content) {
|
|
2859
|
+
return this.parseOptimizations(content);
|
|
2860
|
+
}
|
|
2861
|
+
}
|
|
2862
|
+
catch (error) {
|
|
2863
|
+
console.warn('AI optimization generation failed, using heuristic approach:', error instanceof Error ? error.message : 'Unknown error');
|
|
2864
|
+
}
|
|
2865
|
+
return this.generateOptimizationsHeuristic(framework, patterns);
|
|
2866
|
+
});
|
|
2867
|
+
}
|
|
2868
|
+
/**
|
|
2869
|
+
* Perform AI analysis
|
|
2870
|
+
*/
|
|
2871
|
+
performAIAnalysis(request) {
|
|
2872
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2873
|
+
var _a, _b;
|
|
2874
|
+
if (!this.openai) {
|
|
2875
|
+
return this.performHeuristicAnalysis(request);
|
|
2876
|
+
}
|
|
2877
|
+
try {
|
|
2878
|
+
const prompt = this.buildAnalysisPrompt(request);
|
|
2879
|
+
const response = yield this.openai.chat.completions.create({
|
|
2880
|
+
model: this.config.openaiModel,
|
|
2881
|
+
messages: [
|
|
2882
|
+
{
|
|
2883
|
+
role: 'system',
|
|
2884
|
+
content: 'You are an expert at analyzing code patterns and determining optimal integration strategies. Provide detailed analysis in JSON format.'
|
|
2885
|
+
},
|
|
2886
|
+
{
|
|
2887
|
+
role: 'user',
|
|
2888
|
+
content: prompt
|
|
2889
|
+
}
|
|
2890
|
+
],
|
|
2891
|
+
max_tokens: this.config.maxTokens,
|
|
2892
|
+
temperature: this.config.temperature,
|
|
2893
|
+
response_format: { type: 'json_object' }
|
|
2894
|
+
});
|
|
2895
|
+
const content = (_b = (_a = response.choices[0]) === null || _a === void 0 ? void 0 : _a.message) === null || _b === void 0 ? void 0 : _b.content;
|
|
2896
|
+
if (content) {
|
|
2897
|
+
return this.parseAnalysisResult(content);
|
|
2898
|
+
}
|
|
2899
|
+
}
|
|
2900
|
+
catch (error) {
|
|
2901
|
+
console.warn('AI analysis failed, using heuristic approach:', error instanceof Error ? error.message : 'Unknown error');
|
|
2902
|
+
}
|
|
2903
|
+
return this.performHeuristicAnalysis(request);
|
|
2904
|
+
});
|
|
2905
|
+
}
|
|
2906
|
+
/**
|
|
2907
|
+
* Build analysis prompt
|
|
2908
|
+
*/
|
|
2909
|
+
buildAnalysisPrompt(request) {
|
|
2910
|
+
return `Analyze these code samples to determine the framework and integration strategy:
|
|
2911
|
+
|
|
2912
|
+
${request.codeSamples.join('\n\n')}
|
|
2913
|
+
|
|
2914
|
+
Provide analysis in JSON format with:
|
|
2915
|
+
- framework: { name, type, confidence (0-1) }
|
|
2916
|
+
- patterns: array of detected patterns
|
|
2917
|
+
- conflicts: array of potential conflicts
|
|
2918
|
+
- recommendations: array of integration recommendations
|
|
2919
|
+
- integrationStrategy: "provider" | "plugin" | "module" | "script" | "standalone"
|
|
2920
|
+
- compatibilityMode: "modern" | "legacy" | "hybrid"
|
|
2921
|
+
|
|
2922
|
+
Focus on:
|
|
2923
|
+
1. Framework detection beyond package.json
|
|
2924
|
+
2. Code patterns and architecture
|
|
2925
|
+
3. Integration compatibility
|
|
2926
|
+
4. Future-proof strategies
|
|
2927
|
+
5. Backward compatibility needs
|
|
2928
|
+
|
|
2929
|
+
Respond with valid JSON only.`;
|
|
2930
|
+
}
|
|
2931
|
+
/**
|
|
2932
|
+
* Build conflict resolution prompt
|
|
2933
|
+
*/
|
|
2934
|
+
buildConflictResolutionPrompt(request) {
|
|
2935
|
+
return `Resolve these integration conflicts for ${request.framework.name}:
|
|
2936
|
+
|
|
2937
|
+
Conflicts: ${request.conflicts.join(', ')}
|
|
2938
|
+
|
|
2939
|
+
Framework: ${request.framework.name} (${request.framework.type})
|
|
2940
|
+
Context: ${request.codeContext}
|
|
2941
|
+
|
|
2942
|
+
Provide specific resolution strategies for each conflict. Options:
|
|
2943
|
+
- update_existing_integration: Update existing code
|
|
2944
|
+
- merge_providers: Merge multiple providers
|
|
2945
|
+
- hybrid_module_support: Support both module systems
|
|
2946
|
+
- skip_conflict: Skip the modification
|
|
2947
|
+
- custom_resolution: Custom resolution strategy
|
|
2948
|
+
|
|
2949
|
+
Respond with a JSON array of resolution strategies.`;
|
|
2950
|
+
}
|
|
2951
|
+
/**
|
|
2952
|
+
* Build optimization prompt
|
|
2953
|
+
*/
|
|
2954
|
+
buildOptimizationPrompt(request) {
|
|
2955
|
+
return `Generate optimizations for ${request.framework.name} integration:
|
|
2956
|
+
|
|
2957
|
+
Framework: ${request.framework.name} (${request.framework.type})
|
|
2958
|
+
Patterns: ${request.patterns.join(', ')}
|
|
2959
|
+
Context: ${request.projectContext}
|
|
2960
|
+
|
|
2961
|
+
Provide specific, actionable optimization recommendations for:
|
|
2962
|
+
1. Performance improvements
|
|
2963
|
+
2. Error handling
|
|
2964
|
+
3. Code organization
|
|
2965
|
+
4. Future-proofing
|
|
2966
|
+
5. Backward compatibility
|
|
2967
|
+
|
|
2968
|
+
Respond with a JSON array of optimization recommendations.`;
|
|
2969
|
+
}
|
|
2970
|
+
/**
|
|
2971
|
+
* Parse analysis result
|
|
2972
|
+
*/
|
|
2973
|
+
parseAnalysisResult(content) {
|
|
2974
|
+
try {
|
|
2975
|
+
const result = JSON.parse(content);
|
|
2976
|
+
return {
|
|
2977
|
+
framework: result.framework || { name: 'vanilla', type: 'vanilla' },
|
|
2978
|
+
confidence: result.confidence || 0.5,
|
|
2979
|
+
patterns: result.patterns || [],
|
|
2980
|
+
conflicts: result.conflicts || [],
|
|
2981
|
+
recommendations: result.recommendations || [],
|
|
2982
|
+
integrationStrategy: result.integrationStrategy || 'script',
|
|
2983
|
+
compatibilityMode: result.compatibilityMode || 'modern'
|
|
2984
|
+
};
|
|
2985
|
+
}
|
|
2986
|
+
catch (error) {
|
|
2987
|
+
console.warn('Failed to parse AI analysis result:', error);
|
|
2988
|
+
return this.getDefaultAnalysis();
|
|
2989
|
+
}
|
|
2990
|
+
}
|
|
2991
|
+
/**
|
|
2992
|
+
* Parse conflict resolutions
|
|
2993
|
+
*/
|
|
2994
|
+
parseConflictResolutions(content) {
|
|
2995
|
+
try {
|
|
2996
|
+
const result = JSON.parse(content);
|
|
2997
|
+
return Array.isArray(result) ? result : [];
|
|
2998
|
+
}
|
|
2999
|
+
catch (error) {
|
|
3000
|
+
console.warn('Failed to parse conflict resolutions:', error);
|
|
3001
|
+
return [];
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
3004
|
+
/**
|
|
3005
|
+
* Parse optimizations
|
|
3006
|
+
*/
|
|
3007
|
+
parseOptimizations(content) {
|
|
3008
|
+
try {
|
|
3009
|
+
const result = JSON.parse(content);
|
|
3010
|
+
return Array.isArray(result) ? result : [];
|
|
3011
|
+
}
|
|
3012
|
+
catch (error) {
|
|
3013
|
+
console.warn('Failed to parse optimizations:', error);
|
|
3014
|
+
return [];
|
|
3015
|
+
}
|
|
3016
|
+
}
|
|
3017
|
+
/**
|
|
3018
|
+
* Heuristic analysis fallback
|
|
3019
|
+
*/
|
|
3020
|
+
performHeuristicAnalysis(request) {
|
|
3021
|
+
const patterns = request.codeSamples.join(' ').toLowerCase();
|
|
3022
|
+
// Framework detection
|
|
3023
|
+
let framework = { name: 'vanilla', type: 'vanilla' };
|
|
3024
|
+
let confidence = 0.5;
|
|
3025
|
+
if (patterns.includes('react')) {
|
|
3026
|
+
framework = { name: 'react', type: 'react' };
|
|
3027
|
+
confidence = 0.9;
|
|
3028
|
+
}
|
|
3029
|
+
else if (patterns.includes('vue')) {
|
|
3030
|
+
framework = { name: 'vue', type: 'vue' };
|
|
3031
|
+
confidence = 0.9;
|
|
3032
|
+
}
|
|
3033
|
+
else if (patterns.includes('angular')) {
|
|
3034
|
+
framework = { name: 'angular', type: 'angular' };
|
|
3035
|
+
confidence = 0.9;
|
|
3036
|
+
}
|
|
3037
|
+
else if (patterns.includes('svelte')) {
|
|
3038
|
+
framework = { name: 'svelte', type: 'svelte' };
|
|
3039
|
+
confidence = 0.9;
|
|
3040
|
+
}
|
|
3041
|
+
else if (patterns.includes('next')) {
|
|
3042
|
+
framework = { name: 'nextjs', type: 'nextjs' };
|
|
3043
|
+
confidence = 0.9;
|
|
3044
|
+
}
|
|
3045
|
+
else if (patterns.includes('nuxt')) {
|
|
3046
|
+
framework = { name: 'nuxt', type: 'nuxt' };
|
|
3047
|
+
confidence = 0.9;
|
|
3048
|
+
}
|
|
3049
|
+
// Integration strategy
|
|
3050
|
+
let integrationStrategy = 'script';
|
|
3051
|
+
if (framework.type === 'react' || framework.type === 'nextjs') {
|
|
3052
|
+
integrationStrategy = 'provider';
|
|
3053
|
+
}
|
|
3054
|
+
else if (framework.type === 'vue') {
|
|
3055
|
+
integrationStrategy = 'plugin';
|
|
3056
|
+
}
|
|
3057
|
+
else if (framework.type === 'angular') {
|
|
3058
|
+
integrationStrategy = 'module';
|
|
3059
|
+
}
|
|
3060
|
+
// Compatibility mode
|
|
3061
|
+
let compatibilityMode = 'modern';
|
|
3062
|
+
if (patterns.includes('require(') || patterns.includes('var ')) {
|
|
3063
|
+
compatibilityMode = 'legacy';
|
|
3064
|
+
}
|
|
3065
|
+
return {
|
|
3066
|
+
framework,
|
|
3067
|
+
confidence,
|
|
3068
|
+
patterns: request.codeSamples,
|
|
3069
|
+
conflicts: [],
|
|
3070
|
+
recommendations: [],
|
|
3071
|
+
integrationStrategy,
|
|
3072
|
+
compatibilityMode
|
|
3073
|
+
};
|
|
3074
|
+
}
|
|
3075
|
+
/**
|
|
3076
|
+
* Heuristic conflict resolution
|
|
3077
|
+
*/
|
|
3078
|
+
resolveConflictsHeuristic(conflicts, framework) {
|
|
3079
|
+
const resolutions = [];
|
|
3080
|
+
for (const conflict of conflicts) {
|
|
3081
|
+
switch (conflict) {
|
|
3082
|
+
case 'existing_humanbehavior_code':
|
|
3083
|
+
resolutions.push('update_existing_integration');
|
|
3084
|
+
break;
|
|
3085
|
+
case 'existing_provider':
|
|
3086
|
+
resolutions.push('merge_providers');
|
|
3087
|
+
break;
|
|
3088
|
+
case 'module_system_conflict':
|
|
3089
|
+
resolutions.push('hybrid_module_support');
|
|
3090
|
+
break;
|
|
3091
|
+
default:
|
|
3092
|
+
resolutions.push('skip_conflict');
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
3095
|
+
return resolutions;
|
|
3096
|
+
}
|
|
3097
|
+
/**
|
|
3098
|
+
* Heuristic optimization generation
|
|
3099
|
+
*/
|
|
3100
|
+
generateOptimizationsHeuristic(framework, patterns) {
|
|
3101
|
+
const optimizations = [];
|
|
3102
|
+
switch (framework.type) {
|
|
3103
|
+
case 'react':
|
|
3104
|
+
optimizations.push('Use React.memo for performance optimization');
|
|
3105
|
+
optimizations.push('Implement error boundaries for better error tracking');
|
|
3106
|
+
optimizations.push('Consider using React.lazy for code splitting');
|
|
3107
|
+
break;
|
|
3108
|
+
case 'vue':
|
|
3109
|
+
optimizations.push('Use Vue 3 Composition API for better performance');
|
|
3110
|
+
optimizations.push('Implement proper error handling in components');
|
|
3111
|
+
optimizations.push('Consider using Vue Router for navigation tracking');
|
|
3112
|
+
break;
|
|
3113
|
+
case 'angular':
|
|
3114
|
+
optimizations.push('Use Angular standalone components for better tree-shaking');
|
|
3115
|
+
optimizations.push('Implement proper error handling with ErrorHandler');
|
|
3116
|
+
optimizations.push('Consider using Angular signals for state management');
|
|
3117
|
+
break;
|
|
3118
|
+
default:
|
|
3119
|
+
optimizations.push('Enable performance tracking');
|
|
3120
|
+
optimizations.push('Implement error tracking');
|
|
3121
|
+
optimizations.push('Consider progressive enhancement');
|
|
3122
|
+
}
|
|
3123
|
+
return optimizations;
|
|
3124
|
+
}
|
|
3125
|
+
/**
|
|
3126
|
+
* Generate cache key
|
|
3127
|
+
*/
|
|
3128
|
+
generateCacheKey(request) {
|
|
3129
|
+
const content = JSON.stringify(request);
|
|
3130
|
+
return Buffer.from(content).toString('base64').substring(0, 32);
|
|
3131
|
+
}
|
|
3132
|
+
/**
|
|
3133
|
+
* Check if cache is valid
|
|
3134
|
+
*/
|
|
3135
|
+
isCacheValid(timestamp) {
|
|
3136
|
+
const now = Date.now();
|
|
3137
|
+
const ttl = (this.config.cacheTTL || 3600) * 1000; // Convert to milliseconds
|
|
3138
|
+
return (now - timestamp) < ttl;
|
|
3139
|
+
}
|
|
3140
|
+
/**
|
|
3141
|
+
* Get default analysis
|
|
3142
|
+
*/
|
|
3143
|
+
getDefaultAnalysis() {
|
|
3144
|
+
return {
|
|
3145
|
+
framework: { name: 'vanilla', type: 'vanilla' },
|
|
3146
|
+
confidence: 0.5,
|
|
3147
|
+
patterns: [],
|
|
3148
|
+
conflicts: [],
|
|
3149
|
+
recommendations: [],
|
|
3150
|
+
integrationStrategy: 'script',
|
|
3151
|
+
compatibilityMode: 'modern'
|
|
3152
|
+
};
|
|
3153
|
+
}
|
|
3154
|
+
/**
|
|
3155
|
+
* Get service statistics
|
|
3156
|
+
*/
|
|
3157
|
+
getStats() {
|
|
3158
|
+
return {
|
|
3159
|
+
cacheSize: this.cache.size,
|
|
3160
|
+
config: {
|
|
3161
|
+
model: this.config.openaiModel,
|
|
3162
|
+
maxTokens: this.config.maxTokens,
|
|
3163
|
+
temperature: this.config.temperature,
|
|
3164
|
+
caching: this.config.enableCaching
|
|
3165
|
+
},
|
|
3166
|
+
openaiAvailable: !!this.openai
|
|
3167
|
+
};
|
|
3168
|
+
}
|
|
3169
|
+
/**
|
|
3170
|
+
* Clear cache
|
|
3171
|
+
*/
|
|
3172
|
+
clearCache() {
|
|
3173
|
+
this.cache.clear();
|
|
3174
|
+
}
|
|
3175
|
+
}
|
|
3176
|
+
|
|
3177
|
+
export { AIAutoInstallCLI, AIBrowserInstallationWizard, AIEnhancedInstallationWizard, AutoInstallCLI, AutoInstallationWizard, CentralizedAIService, AutoInstallationWizard as InstallWizard, RemoteAIService };
|
|
3178
|
+
//# sourceMappingURL=index.js.map
|