humanbehavior-js 0.4.27 → 0.5.0
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/README.md +151 -0
- package/package.json +114 -71
- package/packages/angular/dist/index.d.ts +46 -0
- package/packages/angular/dist/index.d.ts.map +1 -0
- package/packages/angular/dist/index.js +2 -0
- package/packages/angular/dist/index.js.map +1 -0
- package/packages/angular/dist/index.mjs +2 -0
- package/packages/angular/dist/index.mjs.map +1 -0
- package/packages/browser/dist/index.d.ts +5 -0
- package/packages/browser/dist/index.d.ts.map +1 -0
- package/packages/browser/dist/index.iife.js +12095 -0
- package/packages/browser/dist/index.iife.js.map +1 -0
- package/packages/browser/dist/index.js +2 -0
- package/packages/browser/dist/index.js.map +1 -0
- package/packages/browser/dist/index.min.js +2 -0
- package/packages/browser/dist/index.min.js.map +1 -0
- package/packages/browser/dist/index.mjs +2 -0
- package/packages/browser/dist/index.mjs.map +1 -0
- package/packages/react/dist/browser.d.ts +2 -0
- package/packages/react/dist/browser.d.ts.map +1 -0
- package/packages/react/dist/index.d.ts +48 -0
- package/packages/react/dist/index.d.ts.map +1 -0
- package/packages/react/dist/index.js +2 -0
- package/packages/react/dist/index.js.map +1 -0
- package/packages/react/dist/index.mjs +2 -0
- package/packages/react/dist/index.mjs.map +1 -0
- package/packages/remix/dist/index.d.ts +8 -0
- package/packages/remix/dist/index.d.ts.map +1 -0
- package/packages/remix/dist/index.js +2 -0
- package/packages/remix/dist/index.js.map +1 -0
- package/packages/remix/dist/index.mjs +2 -0
- package/packages/remix/dist/index.mjs.map +1 -0
- package/packages/svelte/dist/index.d.ts +11 -0
- package/packages/svelte/dist/index.d.ts.map +1 -0
- package/packages/svelte/dist/index.js +2 -0
- package/packages/svelte/dist/index.js.map +1 -0
- package/packages/svelte/dist/index.mjs +2 -0
- package/packages/svelte/dist/index.mjs.map +1 -0
- package/{dist/types/vue → packages/vue/dist}/index.d.ts +4 -5
- package/packages/vue/dist/index.d.ts.map +1 -0
- package/packages/vue/dist/index.js +2 -0
- package/packages/vue/dist/index.js.map +1 -0
- package/packages/vue/dist/index.mjs +2 -0
- package/packages/vue/dist/index.mjs.map +1 -0
- package/packages/wizard/dist/ai/ai-install-wizard.d.ts +145 -0
- package/packages/wizard/dist/ai/ai-install-wizard.d.ts.map +1 -0
- package/packages/wizard/dist/ai/manual-framework-wizard.d.ts +52 -0
- package/packages/wizard/dist/ai/manual-framework-wizard.d.ts.map +1 -0
- package/packages/wizard/dist/cli/ai-auto-install.d.ts +27 -0
- package/packages/wizard/dist/cli/ai-auto-install.d.ts.map +1 -0
- package/{dist → packages/wizard/dist}/cli/ai-auto-install.js +821 -905
- package/packages/wizard/dist/cli/ai-auto-install.js.map +1 -0
- package/packages/wizard/dist/cli/auto-install.d.ts +26 -0
- package/packages/wizard/dist/cli/auto-install.d.ts.map +1 -0
- package/{dist → packages/wizard/dist}/cli/auto-install.js +821 -905
- package/packages/wizard/dist/cli/auto-install.js.map +1 -0
- package/{dist/types → packages/wizard/dist/core}/install-wizard.d.ts +6 -8
- package/packages/wizard/dist/core/install-wizard.d.ts.map +1 -0
- package/packages/wizard/dist/index.d.ts +18 -0
- package/packages/wizard/dist/index.d.ts.map +1 -0
- package/packages/wizard/dist/index.js +2 -0
- package/packages/wizard/dist/index.js.map +1 -0
- package/packages/wizard/dist/index.mjs +2 -0
- package/packages/wizard/dist/index.mjs.map +1 -0
- package/packages/wizard/dist/services/centralized-ai-service.d.ts +159 -0
- package/packages/wizard/dist/services/centralized-ai-service.d.ts.map +1 -0
- package/packages/wizard/dist/services/remote-ai-service.d.ts +58 -0
- package/packages/wizard/dist/services/remote-ai-service.d.ts.map +1 -0
- package/WIZARD_USAGE_GUIDE.md +0 -381
- package/dist/cjs/angular/index.cjs +0 -14979
- package/dist/cjs/angular/index.cjs.map +0 -1
- package/dist/cjs/index.cjs +0 -14964
- package/dist/cjs/index.cjs.map +0 -1
- package/dist/cjs/install-wizard.cjs +0 -1576
- package/dist/cjs/install-wizard.cjs.map +0 -1
- package/dist/cjs/react/index.cjs +0 -15103
- package/dist/cjs/react/index.cjs.map +0 -1
- package/dist/cjs/remix/index.cjs +0 -15077
- package/dist/cjs/remix/index.cjs.map +0 -1
- package/dist/cjs/svelte/index.cjs +0 -14933
- package/dist/cjs/svelte/index.cjs.map +0 -1
- package/dist/cjs/vue/index.cjs +0 -14942
- package/dist/cjs/vue/index.cjs.map +0 -1
- package/dist/cjs/wizard/index.cjs +0 -3490
- package/dist/cjs/wizard/index.cjs.map +0 -1
- package/dist/cli/ai-auto-install.js.map +0 -1
- package/dist/cli/auto-install.js.map +0 -1
- package/dist/esm/angular/index.js +0 -14975
- package/dist/esm/angular/index.js.map +0 -1
- package/dist/esm/index.js +0 -14941
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/install-wizard.js +0 -1553
- package/dist/esm/install-wizard.js.map +0 -1
- package/dist/esm/react/index.js +0 -15097
- package/dist/esm/react/index.js.map +0 -1
- package/dist/esm/remix/index.js +0 -15073
- package/dist/esm/remix/index.js.map +0 -1
- package/dist/esm/svelte/index.js +0 -14931
- package/dist/esm/svelte/index.js.map +0 -1
- package/dist/esm/vue/index.js +0 -14940
- package/dist/esm/vue/index.js.map +0 -1
- package/dist/esm/wizard/index.js +0 -3459
- package/dist/esm/wizard/index.js.map +0 -1
- package/dist/index.min.js +0 -2
- package/dist/index.min.js.map +0 -1
- package/dist/types/angular/index.d.ts +0 -357
- package/dist/types/index.d.ts +0 -644
- package/dist/types/react/index.d.ts +0 -345
- package/dist/types/remix/index.d.ts +0 -336
- package/dist/types/svelte/index.d.ts +0 -322
- package/dist/types/wizard/index.d.ts +0 -523
- package/readme.md +0 -335
- package/rollup.config.js +0 -422
- package/simple-spa.html +0 -1000
- package/src/angular/index.ts +0 -79
- package/src/api.ts +0 -416
- package/src/index.ts +0 -35
- package/src/react/AutoInstallWizard.tsx +0 -557
- package/src/react/browser.ts +0 -8
- package/src/react/index.tsx +0 -308
- package/src/redact.ts +0 -327
- package/src/remix/index.ts +0 -16
- package/src/svelte/index.ts +0 -14
- package/src/tracker.ts +0 -1587
- package/src/types/clack.d.ts +0 -31
- package/src/utils/ip-detector.ts +0 -158
- package/src/utils/logger.ts +0 -144
- package/src/utils/property-detector.ts +0 -345
- package/src/utils/property-manager.ts +0 -274
- package/src/vue/index.ts +0 -29
- package/src/wizard/README.md +0 -114
- package/src/wizard/ai/ai-install-wizard.ts +0 -897
- package/src/wizard/ai/manual-framework-wizard.ts +0 -238
- package/src/wizard/cli/ai-auto-install.ts +0 -241
- package/src/wizard/cli/auto-install.ts +0 -224
- package/src/wizard/core/install-wizard.ts +0 -1794
- package/src/wizard/index.ts +0 -23
- package/src/wizard/services/centralized-ai-service.ts +0 -668
- package/src/wizard/services/remote-ai-service.ts +0 -240
- package/tsconfig.json +0 -24
|
@@ -3,38 +3,6 @@ import * as fs from 'fs';
|
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import * as clack from '@clack/prompts';
|
|
5
5
|
|
|
6
|
-
/******************************************************************************
|
|
7
|
-
Copyright (c) Microsoft Corporation.
|
|
8
|
-
|
|
9
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
10
|
-
purpose with or without fee is hereby granted.
|
|
11
|
-
|
|
12
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
13
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
14
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
15
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
16
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
17
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
18
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
19
|
-
***************************************************************************** */
|
|
20
|
-
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
24
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
25
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
26
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
27
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
28
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
29
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
34
|
-
var e = new Error(message);
|
|
35
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
6
|
/**
|
|
39
7
|
* HumanBehavior SDK Auto-Installation Wizard
|
|
40
8
|
*
|
|
@@ -72,324 +40,314 @@ class AutoInstallationWizard {
|
|
|
72
40
|
/**
|
|
73
41
|
* Main installation method - detects framework and auto-installs
|
|
74
42
|
*/
|
|
75
|
-
install() {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
});
|
|
43
|
+
async install() {
|
|
44
|
+
try {
|
|
45
|
+
// Step 1: Detect framework
|
|
46
|
+
this.framework = await this.detectFramework();
|
|
47
|
+
// Step 2: Install package
|
|
48
|
+
await this.installPackage();
|
|
49
|
+
// Step 3: Generate and apply code modifications
|
|
50
|
+
const modifications = await this.generateModifications();
|
|
51
|
+
await this.applyModifications(modifications);
|
|
52
|
+
// Step 4: Generate next steps
|
|
53
|
+
const nextSteps = this.generateNextSteps();
|
|
54
|
+
return {
|
|
55
|
+
success: true,
|
|
56
|
+
framework: this.framework,
|
|
57
|
+
modifications,
|
|
58
|
+
errors: [],
|
|
59
|
+
nextSteps
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
return {
|
|
64
|
+
success: false,
|
|
65
|
+
framework: this.framework || { name: 'unknown', type: 'vanilla' },
|
|
66
|
+
modifications: [],
|
|
67
|
+
errors: [error instanceof Error ? error.message : 'Unknown error'],
|
|
68
|
+
nextSteps: []
|
|
69
|
+
};
|
|
70
|
+
}
|
|
105
71
|
}
|
|
106
72
|
/**
|
|
107
73
|
* Detect the current framework and project setup
|
|
108
74
|
*/
|
|
109
|
-
detectFramework() {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return {
|
|
114
|
-
name: 'vanilla',
|
|
115
|
-
type: 'vanilla',
|
|
116
|
-
projectRoot: this.projectRoot
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
120
|
-
const dependencies = Object.assign(Object.assign({}, packageJson.dependencies), packageJson.devDependencies);
|
|
121
|
-
// Detect framework with version information
|
|
122
|
-
let framework = {
|
|
75
|
+
async detectFramework() {
|
|
76
|
+
const packageJsonPath = path.join(this.projectRoot, 'package.json');
|
|
77
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
78
|
+
return {
|
|
123
79
|
name: 'vanilla',
|
|
124
80
|
type: 'vanilla',
|
|
81
|
+
projectRoot: this.projectRoot
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
85
|
+
const dependencies = {
|
|
86
|
+
...packageJson.dependencies,
|
|
87
|
+
...packageJson.devDependencies
|
|
88
|
+
};
|
|
89
|
+
// Detect framework with version information
|
|
90
|
+
let framework = {
|
|
91
|
+
name: 'vanilla',
|
|
92
|
+
type: 'vanilla',
|
|
93
|
+
projectRoot: this.projectRoot,
|
|
94
|
+
features: {}
|
|
95
|
+
};
|
|
96
|
+
if (dependencies.nuxt) {
|
|
97
|
+
const nuxtVersion = dependencies.nuxt;
|
|
98
|
+
const isNuxt3 = this.isVersionGte(nuxtVersion, '3.0.0');
|
|
99
|
+
framework = {
|
|
100
|
+
name: 'nuxt',
|
|
101
|
+
type: 'nuxt',
|
|
102
|
+
version: nuxtVersion,
|
|
103
|
+
majorVersion: this.getMajorVersion(nuxtVersion),
|
|
104
|
+
hasTypeScript: !!dependencies.typescript,
|
|
105
|
+
hasRouter: true,
|
|
106
|
+
projectRoot: this.projectRoot,
|
|
107
|
+
features: {
|
|
108
|
+
hasNuxt3: isNuxt3
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
else if (dependencies.next) {
|
|
113
|
+
const nextVersion = dependencies.next;
|
|
114
|
+
const isNext13 = this.isVersionGte(nextVersion, '13.0.0');
|
|
115
|
+
framework = {
|
|
116
|
+
name: 'nextjs',
|
|
117
|
+
type: 'nextjs',
|
|
118
|
+
version: nextVersion,
|
|
119
|
+
majorVersion: this.getMajorVersion(nextVersion),
|
|
120
|
+
hasTypeScript: !!dependencies.typescript || !!dependencies['@types/node'],
|
|
121
|
+
hasRouter: true,
|
|
122
|
+
projectRoot: this.projectRoot,
|
|
123
|
+
features: {
|
|
124
|
+
hasNextAppRouter: isNext13
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
else if (dependencies['@remix-run/react'] || dependencies['@remix-run/dev']) {
|
|
129
|
+
const remixVersion = dependencies['@remix-run/react'] || dependencies['@remix-run/dev'];
|
|
130
|
+
framework = {
|
|
131
|
+
name: 'remix',
|
|
132
|
+
type: 'remix',
|
|
133
|
+
version: remixVersion,
|
|
134
|
+
majorVersion: this.getMajorVersion(remixVersion),
|
|
135
|
+
hasTypeScript: !!dependencies.typescript || !!dependencies['@types/react'],
|
|
136
|
+
hasRouter: true,
|
|
125
137
|
projectRoot: this.projectRoot,
|
|
126
138
|
features: {}
|
|
127
139
|
};
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
majorVersion: this.getMajorVersion(astroVersion),
|
|
244
|
-
hasTypeScript: !!dependencies.typescript || !!dependencies['@astrojs/ts-plugin'],
|
|
245
|
-
hasRouter: true,
|
|
246
|
-
projectRoot: this.projectRoot,
|
|
247
|
-
features: {}
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
else if (dependencies.gatsby) {
|
|
251
|
-
const gatsbyVersion = dependencies.gatsby;
|
|
252
|
-
framework = {
|
|
253
|
-
name: 'gatsby',
|
|
254
|
-
type: 'gatsby',
|
|
255
|
-
version: gatsbyVersion,
|
|
256
|
-
majorVersion: this.getMajorVersion(gatsbyVersion),
|
|
257
|
-
hasTypeScript: !!dependencies.typescript || !!dependencies['@types/react'],
|
|
258
|
-
hasRouter: true,
|
|
259
|
-
projectRoot: this.projectRoot,
|
|
260
|
-
features: {}
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
// Detect bundler
|
|
264
|
-
if (dependencies.vite) {
|
|
265
|
-
framework.bundler = 'vite';
|
|
266
|
-
}
|
|
267
|
-
else if (dependencies.webpack) {
|
|
268
|
-
framework.bundler = 'webpack';
|
|
269
|
-
}
|
|
270
|
-
else if (dependencies.esbuild) {
|
|
271
|
-
framework.bundler = 'esbuild';
|
|
272
|
-
}
|
|
273
|
-
else if (dependencies.rollup) {
|
|
274
|
-
framework.bundler = 'rollup';
|
|
275
|
-
}
|
|
276
|
-
// Detect package manager
|
|
277
|
-
if (fs.existsSync(path.join(this.projectRoot, 'yarn.lock'))) {
|
|
278
|
-
framework.packageManager = 'yarn';
|
|
279
|
-
}
|
|
280
|
-
else if (fs.existsSync(path.join(this.projectRoot, 'pnpm-lock.yaml'))) {
|
|
281
|
-
framework.packageManager = 'pnpm';
|
|
282
|
-
}
|
|
283
|
-
else {
|
|
284
|
-
framework.packageManager = 'npm';
|
|
285
|
-
}
|
|
286
|
-
return framework;
|
|
287
|
-
});
|
|
140
|
+
}
|
|
141
|
+
else if (dependencies.react) {
|
|
142
|
+
const reactVersion = dependencies.react;
|
|
143
|
+
const isReact18 = this.isVersionGte(reactVersion, '18.0.0');
|
|
144
|
+
framework = {
|
|
145
|
+
name: 'react',
|
|
146
|
+
type: 'react',
|
|
147
|
+
version: reactVersion,
|
|
148
|
+
majorVersion: this.getMajorVersion(reactVersion),
|
|
149
|
+
hasTypeScript: !!dependencies.typescript || !!dependencies['@types/react'],
|
|
150
|
+
hasRouter: !!dependencies['react-router-dom'] || !!dependencies['react-router'],
|
|
151
|
+
projectRoot: this.projectRoot,
|
|
152
|
+
features: {
|
|
153
|
+
hasReact18: isReact18
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
else if (dependencies.vue) {
|
|
158
|
+
const vueVersion = dependencies.vue;
|
|
159
|
+
const isVue3 = this.isVersionGte(vueVersion, '3.0.0');
|
|
160
|
+
framework = {
|
|
161
|
+
name: 'vue',
|
|
162
|
+
type: 'vue',
|
|
163
|
+
version: vueVersion,
|
|
164
|
+
majorVersion: this.getMajorVersion(vueVersion),
|
|
165
|
+
hasTypeScript: !!dependencies.typescript || !!dependencies['@vue/cli-service'],
|
|
166
|
+
hasRouter: !!dependencies['vue-router'],
|
|
167
|
+
projectRoot: this.projectRoot,
|
|
168
|
+
features: {
|
|
169
|
+
hasVue3: isVue3
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
else if (dependencies['@angular/core']) {
|
|
174
|
+
const angularVersion = dependencies['@angular/core'];
|
|
175
|
+
const isAngular17 = this.isVersionGte(angularVersion, '17.0.0');
|
|
176
|
+
framework = {
|
|
177
|
+
name: 'angular',
|
|
178
|
+
type: 'angular',
|
|
179
|
+
version: angularVersion,
|
|
180
|
+
majorVersion: this.getMajorVersion(angularVersion),
|
|
181
|
+
hasTypeScript: true,
|
|
182
|
+
hasRouter: true,
|
|
183
|
+
projectRoot: this.projectRoot,
|
|
184
|
+
features: {
|
|
185
|
+
hasAngularStandalone: isAngular17
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
else if (dependencies.svelte) {
|
|
190
|
+
const svelteVersion = dependencies.svelte;
|
|
191
|
+
const isSvelteKit = !!dependencies['@sveltejs/kit'];
|
|
192
|
+
framework = {
|
|
193
|
+
name: 'svelte',
|
|
194
|
+
type: 'svelte',
|
|
195
|
+
version: svelteVersion,
|
|
196
|
+
majorVersion: this.getMajorVersion(svelteVersion),
|
|
197
|
+
hasTypeScript: !!dependencies.typescript || !!dependencies['svelte-check'],
|
|
198
|
+
hasRouter: !!dependencies['svelte-routing'] || !!dependencies['@sveltejs/kit'],
|
|
199
|
+
projectRoot: this.projectRoot,
|
|
200
|
+
features: {
|
|
201
|
+
hasSvelteKit: isSvelteKit
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
else if (dependencies.astro) {
|
|
206
|
+
const astroVersion = dependencies.astro;
|
|
207
|
+
framework = {
|
|
208
|
+
name: 'astro',
|
|
209
|
+
type: 'astro',
|
|
210
|
+
version: astroVersion,
|
|
211
|
+
majorVersion: this.getMajorVersion(astroVersion),
|
|
212
|
+
hasTypeScript: !!dependencies.typescript || !!dependencies['@astrojs/ts-plugin'],
|
|
213
|
+
hasRouter: true,
|
|
214
|
+
projectRoot: this.projectRoot,
|
|
215
|
+
features: {}
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
else if (dependencies.gatsby) {
|
|
219
|
+
const gatsbyVersion = dependencies.gatsby;
|
|
220
|
+
framework = {
|
|
221
|
+
name: 'gatsby',
|
|
222
|
+
type: 'gatsby',
|
|
223
|
+
version: gatsbyVersion,
|
|
224
|
+
majorVersion: this.getMajorVersion(gatsbyVersion),
|
|
225
|
+
hasTypeScript: !!dependencies.typescript || !!dependencies['@types/react'],
|
|
226
|
+
hasRouter: true,
|
|
227
|
+
projectRoot: this.projectRoot,
|
|
228
|
+
features: {}
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
// Detect bundler
|
|
232
|
+
if (dependencies.vite) {
|
|
233
|
+
framework.bundler = 'vite';
|
|
234
|
+
}
|
|
235
|
+
else if (dependencies.webpack) {
|
|
236
|
+
framework.bundler = 'webpack';
|
|
237
|
+
}
|
|
238
|
+
else if (dependencies.esbuild) {
|
|
239
|
+
framework.bundler = 'esbuild';
|
|
240
|
+
}
|
|
241
|
+
else if (dependencies.rollup) {
|
|
242
|
+
framework.bundler = 'rollup';
|
|
243
|
+
}
|
|
244
|
+
// Detect package manager
|
|
245
|
+
if (fs.existsSync(path.join(this.projectRoot, 'yarn.lock'))) {
|
|
246
|
+
framework.packageManager = 'yarn';
|
|
247
|
+
}
|
|
248
|
+
else if (fs.existsSync(path.join(this.projectRoot, 'pnpm-lock.yaml'))) {
|
|
249
|
+
framework.packageManager = 'pnpm';
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
framework.packageManager = 'npm';
|
|
253
|
+
}
|
|
254
|
+
return framework;
|
|
288
255
|
}
|
|
289
256
|
/**
|
|
290
257
|
* Install the SDK package with latest version range
|
|
291
258
|
*/
|
|
292
|
-
installPackage() {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
? '
|
|
299
|
-
:
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
throw new Error(`Failed to install humanbehavior-js: ${error}`);
|
|
311
|
-
}
|
|
312
|
-
});
|
|
259
|
+
async installPackage() {
|
|
260
|
+
const { execSync } = await import('child_process');
|
|
261
|
+
// Build base command with latest version range
|
|
262
|
+
let command = this.framework?.packageManager === 'yarn'
|
|
263
|
+
? 'yarn add humanbehavior-js@latest'
|
|
264
|
+
: this.framework?.packageManager === 'pnpm'
|
|
265
|
+
? 'pnpm add humanbehavior-js@latest'
|
|
266
|
+
: 'npm install humanbehavior-js@latest';
|
|
267
|
+
// Add legacy peer deps flag for npm to handle dependency conflicts
|
|
268
|
+
if (this.framework?.packageManager !== 'yarn' && this.framework?.packageManager !== 'pnpm') {
|
|
269
|
+
command += ' --legacy-peer-deps';
|
|
270
|
+
}
|
|
271
|
+
try {
|
|
272
|
+
execSync(command, { cwd: this.projectRoot, stdio: 'inherit' });
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
throw new Error(`Failed to install humanbehavior-js: ${error}`);
|
|
276
|
+
}
|
|
313
277
|
}
|
|
314
278
|
/**
|
|
315
279
|
* Generate code modifications based on framework
|
|
316
280
|
*/
|
|
317
|
-
generateModifications() {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
}
|
|
352
|
-
return modifications;
|
|
353
|
-
});
|
|
281
|
+
async generateModifications() {
|
|
282
|
+
const modifications = [];
|
|
283
|
+
switch (this.framework?.type) {
|
|
284
|
+
case 'react':
|
|
285
|
+
modifications.push(...await this.generateReactModifications());
|
|
286
|
+
break;
|
|
287
|
+
case 'nextjs':
|
|
288
|
+
modifications.push(...await this.generateNextJSModifications());
|
|
289
|
+
break;
|
|
290
|
+
case 'nuxt':
|
|
291
|
+
modifications.push(...await this.generateNuxtModifications());
|
|
292
|
+
break;
|
|
293
|
+
case 'astro':
|
|
294
|
+
modifications.push(...await this.generateAstroModifications());
|
|
295
|
+
break;
|
|
296
|
+
case 'gatsby':
|
|
297
|
+
modifications.push(...await this.generateGatsbyModifications());
|
|
298
|
+
break;
|
|
299
|
+
case 'remix':
|
|
300
|
+
modifications.push(...await this.generateRemixModifications());
|
|
301
|
+
break;
|
|
302
|
+
case 'vue':
|
|
303
|
+
modifications.push(...await this.generateVueModifications());
|
|
304
|
+
break;
|
|
305
|
+
case 'angular':
|
|
306
|
+
modifications.push(...await this.generateAngularModifications());
|
|
307
|
+
break;
|
|
308
|
+
case 'svelte':
|
|
309
|
+
modifications.push(...await this.generateSvelteModifications());
|
|
310
|
+
break;
|
|
311
|
+
default:
|
|
312
|
+
modifications.push(...await this.generateVanillaModifications());
|
|
313
|
+
}
|
|
314
|
+
return modifications;
|
|
354
315
|
}
|
|
355
316
|
/**
|
|
356
317
|
* Generate React-specific modifications
|
|
357
318
|
*/
|
|
358
|
-
generateReactModifications() {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
return modifications;
|
|
376
|
-
});
|
|
319
|
+
async generateReactModifications() {
|
|
320
|
+
const modifications = [];
|
|
321
|
+
// Find main App component or index file
|
|
322
|
+
const appFile = this.findReactAppFile();
|
|
323
|
+
if (appFile) {
|
|
324
|
+
const content = fs.readFileSync(appFile, 'utf8');
|
|
325
|
+
const modifiedContent = this.injectReactProvider(content, appFile);
|
|
326
|
+
modifications.push({
|
|
327
|
+
filePath: appFile,
|
|
328
|
+
action: 'modify',
|
|
329
|
+
content: modifiedContent,
|
|
330
|
+
description: 'Added HumanBehaviorProvider to React app'
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
// Create or append to environment file
|
|
334
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
335
|
+
return modifications;
|
|
377
336
|
}
|
|
378
337
|
/**
|
|
379
338
|
* Generate Next.js-specific modifications
|
|
380
339
|
*/
|
|
381
|
-
generateNextJSModifications() {
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
content: `'use client';
|
|
340
|
+
async generateNextJSModifications() {
|
|
341
|
+
const modifications = [];
|
|
342
|
+
// Check for App Router
|
|
343
|
+
const appLayoutFile = path.join(this.projectRoot, 'src', 'app', 'layout.tsx');
|
|
344
|
+
const pagesLayoutFile = path.join(this.projectRoot, 'src', 'pages', '_app.tsx');
|
|
345
|
+
if (fs.existsSync(appLayoutFile)) {
|
|
346
|
+
// Create providers.tsx file for App Router
|
|
347
|
+
modifications.push({
|
|
348
|
+
filePath: path.join(this.projectRoot, 'src', 'app', 'providers.tsx'),
|
|
349
|
+
action: 'create',
|
|
350
|
+
content: `'use client';
|
|
393
351
|
|
|
394
352
|
import { HumanBehaviorProvider } from 'humanbehavior-js/react';
|
|
395
353
|
|
|
@@ -400,24 +358,24 @@ export function Providers({ children }: { children: React.ReactNode }) {
|
|
|
400
358
|
</HumanBehaviorProvider>
|
|
401
359
|
);
|
|
402
360
|
}`,
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
361
|
+
description: 'Created providers.tsx file for Next.js App Router'
|
|
362
|
+
});
|
|
363
|
+
// Modify layout.tsx to use the provider
|
|
364
|
+
const content = fs.readFileSync(appLayoutFile, 'utf8');
|
|
365
|
+
const modifiedContent = this.injectNextJSAppRouter(content);
|
|
366
|
+
modifications.push({
|
|
367
|
+
filePath: appLayoutFile,
|
|
368
|
+
action: 'modify',
|
|
369
|
+
content: modifiedContent,
|
|
370
|
+
description: 'Added Providers wrapper to Next.js App Router layout'
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
else if (fs.existsSync(pagesLayoutFile)) {
|
|
374
|
+
// Create providers.tsx file for Pages Router
|
|
375
|
+
modifications.push({
|
|
376
|
+
filePath: path.join(this.projectRoot, 'src', 'components', 'providers.tsx'),
|
|
377
|
+
action: 'create',
|
|
378
|
+
content: `'use client';
|
|
421
379
|
|
|
422
380
|
import { HumanBehaviorProvider } from 'humanbehavior-js/react';
|
|
423
381
|
|
|
@@ -428,32 +386,30 @@ export function Providers({ children }: { children: React.ReactNode }) {
|
|
|
428
386
|
</HumanBehaviorProvider>
|
|
429
387
|
);
|
|
430
388
|
}`,
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
});
|
|
389
|
+
description: 'Created providers.tsx file for Pages Router'
|
|
390
|
+
});
|
|
391
|
+
// Modify _app.tsx to use the provider
|
|
392
|
+
const content = fs.readFileSync(pagesLayoutFile, 'utf8');
|
|
393
|
+
const modifiedContent = this.injectNextJSPagesRouter(content);
|
|
394
|
+
modifications.push({
|
|
395
|
+
filePath: pagesLayoutFile,
|
|
396
|
+
action: 'modify',
|
|
397
|
+
content: modifiedContent,
|
|
398
|
+
description: 'Added Providers wrapper to Next.js Pages Router'
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
// Create or append to environment file
|
|
402
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
403
|
+
return modifications;
|
|
447
404
|
}
|
|
448
405
|
/**
|
|
449
406
|
* Generate Astro-specific modifications
|
|
450
407
|
*/
|
|
451
|
-
generateAstroModifications() {
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
const astroComponentContent = `---
|
|
408
|
+
async generateAstroModifications() {
|
|
409
|
+
const modifications = [];
|
|
410
|
+
// Create Astro component for HumanBehavior
|
|
411
|
+
const astroComponentPath = path.join(this.projectRoot, 'src', 'components', 'HumanBehavior.astro');
|
|
412
|
+
const astroComponentContent = `---
|
|
457
413
|
// This component will only run on the client side
|
|
458
414
|
---
|
|
459
415
|
|
|
@@ -489,52 +445,50 @@ export function Providers({ children }: { children: React.ReactNode }) {
|
|
|
489
445
|
console.error('HumanBehavior: No API key found');
|
|
490
446
|
}
|
|
491
447
|
</script>`;
|
|
448
|
+
modifications.push({
|
|
449
|
+
filePath: astroComponentPath,
|
|
450
|
+
action: 'create',
|
|
451
|
+
content: astroComponentContent,
|
|
452
|
+
description: 'Created Astro component for HumanBehavior SDK'
|
|
453
|
+
});
|
|
454
|
+
// Find and update layout file
|
|
455
|
+
const layoutFiles = [
|
|
456
|
+
path.join(this.projectRoot, 'src', 'layouts', 'Layout.astro'),
|
|
457
|
+
path.join(this.projectRoot, 'src', 'layouts', 'layout.astro'),
|
|
458
|
+
path.join(this.projectRoot, 'src', 'layouts', 'BaseLayout.astro')
|
|
459
|
+
];
|
|
460
|
+
let layoutFile = null;
|
|
461
|
+
for (const file of layoutFiles) {
|
|
462
|
+
if (fs.existsSync(file)) {
|
|
463
|
+
layoutFile = file;
|
|
464
|
+
break;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
if (layoutFile) {
|
|
468
|
+
const content = fs.readFileSync(layoutFile, 'utf8');
|
|
469
|
+
const modifiedContent = this.injectAstroLayout(content);
|
|
492
470
|
modifications.push({
|
|
493
|
-
filePath:
|
|
494
|
-
action: '
|
|
495
|
-
content:
|
|
496
|
-
description: '
|
|
471
|
+
filePath: layoutFile,
|
|
472
|
+
action: 'modify',
|
|
473
|
+
content: modifiedContent,
|
|
474
|
+
description: 'Added HumanBehavior component to Astro layout'
|
|
497
475
|
});
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
path.join(this.projectRoot, 'src', 'layouts', 'BaseLayout.astro')
|
|
503
|
-
];
|
|
504
|
-
let layoutFile = null;
|
|
505
|
-
for (const file of layoutFiles) {
|
|
506
|
-
if (fs.existsSync(file)) {
|
|
507
|
-
layoutFile = file;
|
|
508
|
-
break;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
if (layoutFile) {
|
|
512
|
-
const content = fs.readFileSync(layoutFile, 'utf8');
|
|
513
|
-
const modifiedContent = this.injectAstroLayout(content);
|
|
514
|
-
modifications.push({
|
|
515
|
-
filePath: layoutFile,
|
|
516
|
-
action: 'modify',
|
|
517
|
-
content: modifiedContent,
|
|
518
|
-
description: 'Added HumanBehavior component to Astro layout'
|
|
519
|
-
});
|
|
520
|
-
}
|
|
521
|
-
// Add environment variable
|
|
522
|
-
modifications.push(this.createEnvironmentModification(this.framework));
|
|
523
|
-
return modifications;
|
|
524
|
-
});
|
|
476
|
+
}
|
|
477
|
+
// Add environment variable
|
|
478
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
479
|
+
return modifications;
|
|
525
480
|
}
|
|
526
481
|
/**
|
|
527
482
|
* Generate Nuxt-specific modifications
|
|
528
483
|
*/
|
|
529
|
-
generateNuxtModifications() {
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
content: `import { HumanBehaviorTracker } from 'humanbehavior-js';
|
|
484
|
+
async generateNuxtModifications() {
|
|
485
|
+
const modifications = [];
|
|
486
|
+
// Create plugin file for Nuxt (in app directory)
|
|
487
|
+
const pluginFile = path.join(this.projectRoot, 'app', 'plugins', 'humanbehavior.client.ts');
|
|
488
|
+
modifications.push({
|
|
489
|
+
filePath: pluginFile,
|
|
490
|
+
action: 'create',
|
|
491
|
+
content: `import { HumanBehaviorTracker } from 'humanbehavior-js';
|
|
538
492
|
|
|
539
493
|
export default defineNuxtPlugin(() => {
|
|
540
494
|
const config = useRuntimeConfig();
|
|
@@ -556,264 +510,252 @@ export default defineNuxtPlugin(() => {
|
|
|
556
510
|
}
|
|
557
511
|
}
|
|
558
512
|
});`,
|
|
559
|
-
|
|
560
|
-
});
|
|
561
|
-
// Create environment configuration
|
|
562
|
-
const nuxtConfigFile = path.join(this.projectRoot, 'nuxt.config.ts');
|
|
563
|
-
if (fs.existsSync(nuxtConfigFile)) {
|
|
564
|
-
const content = fs.readFileSync(nuxtConfigFile, 'utf8');
|
|
565
|
-
const modifiedContent = this.injectNuxtConfig(content);
|
|
566
|
-
modifications.push({
|
|
567
|
-
filePath: nuxtConfigFile,
|
|
568
|
-
action: 'modify',
|
|
569
|
-
content: modifiedContent,
|
|
570
|
-
description: 'Added HumanBehavior runtime config to Nuxt config'
|
|
571
|
-
});
|
|
572
|
-
}
|
|
573
|
-
// Create or append to environment file
|
|
574
|
-
modifications.push(this.createEnvironmentModification(this.framework));
|
|
575
|
-
return modifications;
|
|
513
|
+
description: 'Created Nuxt plugin for HumanBehavior SDK in app directory'
|
|
576
514
|
});
|
|
515
|
+
// Create environment configuration
|
|
516
|
+
const nuxtConfigFile = path.join(this.projectRoot, 'nuxt.config.ts');
|
|
517
|
+
if (fs.existsSync(nuxtConfigFile)) {
|
|
518
|
+
const content = fs.readFileSync(nuxtConfigFile, 'utf8');
|
|
519
|
+
const modifiedContent = this.injectNuxtConfig(content);
|
|
520
|
+
modifications.push({
|
|
521
|
+
filePath: nuxtConfigFile,
|
|
522
|
+
action: 'modify',
|
|
523
|
+
content: modifiedContent,
|
|
524
|
+
description: 'Added HumanBehavior runtime config to Nuxt config'
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
// Create or append to environment file
|
|
528
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
529
|
+
return modifications;
|
|
577
530
|
}
|
|
578
531
|
/**
|
|
579
532
|
* Generate Remix-specific modifications
|
|
580
533
|
*/
|
|
581
|
-
generateRemixModifications() {
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
return modifications;
|
|
599
|
-
});
|
|
534
|
+
async generateRemixModifications() {
|
|
535
|
+
const modifications = [];
|
|
536
|
+
// Find root.tsx file
|
|
537
|
+
const rootFile = path.join(this.projectRoot, 'app', 'root.tsx');
|
|
538
|
+
if (fs.existsSync(rootFile)) {
|
|
539
|
+
const content = fs.readFileSync(rootFile, 'utf8');
|
|
540
|
+
const modifiedContent = this.injectRemixProvider(content);
|
|
541
|
+
modifications.push({
|
|
542
|
+
filePath: rootFile,
|
|
543
|
+
action: 'modify',
|
|
544
|
+
content: modifiedContent,
|
|
545
|
+
description: 'Added HumanBehaviorProvider to Remix root component'
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
// Create or append to environment file
|
|
549
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
550
|
+
return modifications;
|
|
600
551
|
}
|
|
601
552
|
/**
|
|
602
553
|
* Generate Vue-specific modifications
|
|
603
554
|
*/
|
|
604
|
-
generateVueModifications() {
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
return modifications;
|
|
622
|
-
});
|
|
555
|
+
async generateVueModifications() {
|
|
556
|
+
const modifications = [];
|
|
557
|
+
// Find main.js or main.ts
|
|
558
|
+
const mainFile = this.findVueMainFile();
|
|
559
|
+
if (mainFile) {
|
|
560
|
+
const content = fs.readFileSync(mainFile, 'utf8');
|
|
561
|
+
const modifiedContent = this.injectVuePlugin(content);
|
|
562
|
+
modifications.push({
|
|
563
|
+
filePath: mainFile,
|
|
564
|
+
action: 'modify',
|
|
565
|
+
content: modifiedContent,
|
|
566
|
+
description: 'Added HumanBehaviorPlugin to Vue app'
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
// Create or append to environment file
|
|
570
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
571
|
+
return modifications;
|
|
623
572
|
}
|
|
624
573
|
/**
|
|
625
574
|
* Generate Angular-specific modifications
|
|
626
575
|
*/
|
|
627
|
-
generateAngularModifications() {
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
const modifiedContent = this.injectAngularStandaloneInit(content);
|
|
640
|
-
modifications.push({
|
|
641
|
-
filePath: mainFile,
|
|
642
|
-
action: 'modify',
|
|
643
|
-
content: modifiedContent,
|
|
644
|
-
description: 'Added HumanBehavior initialization to Angular main.ts'
|
|
645
|
-
});
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
else if (fs.existsSync(appModuleFile)) {
|
|
649
|
-
// Legacy Angular with NgModule
|
|
650
|
-
const content = fs.readFileSync(appModuleFile, 'utf8');
|
|
651
|
-
const modifiedContent = this.injectAngularModule(content);
|
|
576
|
+
async generateAngularModifications() {
|
|
577
|
+
const modifications = [];
|
|
578
|
+
// Check for modern Angular (standalone components) vs legacy (NgModule)
|
|
579
|
+
const appModuleFile = path.join(this.projectRoot, 'src', 'app', 'app.module.ts');
|
|
580
|
+
const appComponentFile = path.join(this.projectRoot, 'src', 'app', 'app.ts');
|
|
581
|
+
const mainFile = path.join(this.projectRoot, 'src', 'main.ts');
|
|
582
|
+
const isModernAngular = fs.existsSync(appComponentFile) && !fs.existsSync(appModuleFile);
|
|
583
|
+
if (isModernAngular) {
|
|
584
|
+
// Modern Angular 17+ with standalone components
|
|
585
|
+
if (fs.existsSync(mainFile)) {
|
|
586
|
+
const content = fs.readFileSync(mainFile, 'utf8');
|
|
587
|
+
const modifiedContent = this.injectAngularStandaloneInit(content);
|
|
652
588
|
modifications.push({
|
|
653
|
-
filePath:
|
|
589
|
+
filePath: mainFile,
|
|
654
590
|
action: 'modify',
|
|
655
591
|
content: modifiedContent,
|
|
656
|
-
description: 'Added
|
|
592
|
+
description: 'Added HumanBehavior initialization to Angular main.ts'
|
|
657
593
|
});
|
|
658
594
|
}
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
const
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
595
|
+
}
|
|
596
|
+
else if (fs.existsSync(appModuleFile)) {
|
|
597
|
+
// Legacy Angular with NgModule
|
|
598
|
+
const content = fs.readFileSync(appModuleFile, 'utf8');
|
|
599
|
+
const modifiedContent = this.injectAngularModule(content);
|
|
600
|
+
modifications.push({
|
|
601
|
+
filePath: appModuleFile,
|
|
602
|
+
action: 'modify',
|
|
603
|
+
content: modifiedContent,
|
|
604
|
+
description: 'Added HumanBehaviorModule to Angular app'
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
// Handle Angular environment files (proper Angular way)
|
|
608
|
+
const envFile = path.join(this.projectRoot, 'src', 'environments', 'environment.ts');
|
|
609
|
+
const envProdFile = path.join(this.projectRoot, 'src', 'environments', 'environment.prod.ts');
|
|
610
|
+
// Create environments directory if it doesn't exist
|
|
611
|
+
const envDir = path.dirname(envFile);
|
|
612
|
+
if (!fs.existsSync(envDir)) {
|
|
613
|
+
fs.mkdirSync(envDir, { recursive: true });
|
|
614
|
+
}
|
|
615
|
+
// Create or update development environment
|
|
616
|
+
if (fs.existsSync(envFile)) {
|
|
617
|
+
const content = fs.readFileSync(envFile, 'utf8');
|
|
618
|
+
if (!content.includes('humanBehaviorApiKey')) {
|
|
619
|
+
const modifiedContent = content.replace(/export const environment = {([\s\S]*?)};/, `export const environment = {
|
|
672
620
|
$1,
|
|
673
621
|
humanBehaviorApiKey: '${this.apiKey}'
|
|
674
622
|
};`);
|
|
675
|
-
modifications.push({
|
|
676
|
-
filePath: envFile,
|
|
677
|
-
action: 'modify',
|
|
678
|
-
content: modifiedContent,
|
|
679
|
-
description: 'Added API key to Angular development environment'
|
|
680
|
-
});
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
else {
|
|
684
|
-
// Create new development environment file
|
|
685
623
|
modifications.push({
|
|
686
624
|
filePath: envFile,
|
|
687
|
-
action: '
|
|
688
|
-
content:
|
|
625
|
+
action: 'modify',
|
|
626
|
+
content: modifiedContent,
|
|
627
|
+
description: 'Added API key to Angular development environment'
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
else {
|
|
632
|
+
// Create new development environment file
|
|
633
|
+
modifications.push({
|
|
634
|
+
filePath: envFile,
|
|
635
|
+
action: 'create',
|
|
636
|
+
content: `export const environment = {
|
|
689
637
|
production: false,
|
|
690
638
|
humanBehaviorApiKey: '${this.apiKey}'
|
|
691
639
|
};`,
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
640
|
+
description: 'Created Angular development environment file'
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
// Create or update production environment
|
|
644
|
+
if (fs.existsSync(envProdFile)) {
|
|
645
|
+
const content = fs.readFileSync(envProdFile, 'utf8');
|
|
646
|
+
if (!content.includes('humanBehaviorApiKey')) {
|
|
647
|
+
const modifiedContent = content.replace(/export const environment = {([\s\S]*?)};/, `export const environment = {
|
|
700
648
|
$1,
|
|
701
649
|
humanBehaviorApiKey: '${this.apiKey}'
|
|
702
650
|
};`);
|
|
703
|
-
modifications.push({
|
|
704
|
-
filePath: envProdFile,
|
|
705
|
-
action: 'modify',
|
|
706
|
-
content: modifiedContent,
|
|
707
|
-
description: 'Added API key to Angular production environment'
|
|
708
|
-
});
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
else {
|
|
712
|
-
// Create new production environment file
|
|
713
651
|
modifications.push({
|
|
714
652
|
filePath: envProdFile,
|
|
715
|
-
action: '
|
|
716
|
-
content:
|
|
653
|
+
action: 'modify',
|
|
654
|
+
content: modifiedContent,
|
|
655
|
+
description: 'Added API key to Angular production environment'
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
else {
|
|
660
|
+
// Create new production environment file
|
|
661
|
+
modifications.push({
|
|
662
|
+
filePath: envProdFile,
|
|
663
|
+
action: 'create',
|
|
664
|
+
content: `export const environment = {
|
|
717
665
|
production: true,
|
|
718
666
|
humanBehaviorApiKey: '${this.apiKey}'
|
|
719
667
|
};`,
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
});
|
|
668
|
+
description: 'Created Angular production environment file'
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
// For Angular, we don't need .env files since we use environment.ts
|
|
672
|
+
// The environment files are already created above
|
|
673
|
+
return modifications;
|
|
727
674
|
}
|
|
728
675
|
/**
|
|
729
676
|
* Generate Svelte-specific modifications
|
|
730
677
|
*/
|
|
731
|
-
generateSvelteModifications() {
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
const modifiedContent = this.injectSvelteKitLayout(content);
|
|
743
|
-
modifications.push({
|
|
744
|
-
filePath: layoutFile,
|
|
745
|
-
action: 'modify',
|
|
746
|
-
content: modifiedContent,
|
|
747
|
-
description: 'Added HumanBehavior store to SvelteKit layout'
|
|
748
|
-
});
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
else {
|
|
752
|
-
// Regular Svelte - modify main file
|
|
753
|
-
const mainFile = this.findSvelteMainFile();
|
|
754
|
-
if (mainFile) {
|
|
755
|
-
const content = fs.readFileSync(mainFile, 'utf8');
|
|
756
|
-
const modifiedContent = this.injectSvelteStore(content);
|
|
757
|
-
modifications.push({
|
|
758
|
-
filePath: mainFile,
|
|
759
|
-
action: 'modify',
|
|
760
|
-
content: modifiedContent,
|
|
761
|
-
description: 'Added HumanBehavior store to Svelte app'
|
|
762
|
-
});
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
// Create or append to environment file
|
|
766
|
-
modifications.push(this.createEnvironmentModification(this.framework));
|
|
767
|
-
return modifications;
|
|
768
|
-
});
|
|
769
|
-
}
|
|
770
|
-
/**
|
|
771
|
-
* Generate vanilla JS/TS modifications
|
|
772
|
-
*/
|
|
773
|
-
generateVanillaModifications() {
|
|
774
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
775
|
-
const modifications = [];
|
|
776
|
-
// Find HTML file to inject script
|
|
777
|
-
const htmlFile = this.findHTMLFile();
|
|
778
|
-
if (htmlFile) {
|
|
779
|
-
const content = fs.readFileSync(htmlFile, 'utf8');
|
|
780
|
-
const modifiedContent = this.injectVanillaScript(content);
|
|
678
|
+
async generateSvelteModifications() {
|
|
679
|
+
const modifications = [];
|
|
680
|
+
// Check for SvelteKit
|
|
681
|
+
const svelteConfigFile = path.join(this.projectRoot, 'svelte.config.js');
|
|
682
|
+
const isSvelteKit = fs.existsSync(svelteConfigFile);
|
|
683
|
+
if (isSvelteKit) {
|
|
684
|
+
// SvelteKit - create layout file
|
|
685
|
+
const layoutFile = path.join(this.projectRoot, 'src', 'routes', '+layout.svelte');
|
|
686
|
+
if (fs.existsSync(layoutFile)) {
|
|
687
|
+
const content = fs.readFileSync(layoutFile, 'utf8');
|
|
688
|
+
const modifiedContent = this.injectSvelteKitLayout(content);
|
|
781
689
|
modifications.push({
|
|
782
|
-
filePath:
|
|
690
|
+
filePath: layoutFile,
|
|
783
691
|
action: 'modify',
|
|
784
692
|
content: modifiedContent,
|
|
785
|
-
description: 'Added HumanBehavior
|
|
693
|
+
description: 'Added HumanBehavior store to SvelteKit layout'
|
|
786
694
|
});
|
|
787
695
|
}
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
*/
|
|
796
|
-
generateGatsbyModifications() {
|
|
797
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
798
|
-
const modifications = [];
|
|
799
|
-
// Modify or create gatsby-browser.js for Gatsby
|
|
800
|
-
const gatsbyBrowserFile = path.join(this.projectRoot, 'gatsby-browser.js');
|
|
801
|
-
if (fs.existsSync(gatsbyBrowserFile)) {
|
|
802
|
-
const content = fs.readFileSync(gatsbyBrowserFile, 'utf8');
|
|
803
|
-
const modifiedContent = this.injectGatsbyBrowser(content);
|
|
696
|
+
}
|
|
697
|
+
else {
|
|
698
|
+
// Regular Svelte - modify main file
|
|
699
|
+
const mainFile = this.findSvelteMainFile();
|
|
700
|
+
if (mainFile) {
|
|
701
|
+
const content = fs.readFileSync(mainFile, 'utf8');
|
|
702
|
+
const modifiedContent = this.injectSvelteStore(content);
|
|
804
703
|
modifications.push({
|
|
805
|
-
filePath:
|
|
704
|
+
filePath: mainFile,
|
|
806
705
|
action: 'modify',
|
|
807
706
|
content: modifiedContent,
|
|
808
|
-
description: 'Added HumanBehavior
|
|
707
|
+
description: 'Added HumanBehavior store to Svelte app'
|
|
809
708
|
});
|
|
810
709
|
}
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
710
|
+
}
|
|
711
|
+
// Create or append to environment file
|
|
712
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
713
|
+
return modifications;
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* Generate vanilla JS/TS modifications
|
|
717
|
+
*/
|
|
718
|
+
async generateVanillaModifications() {
|
|
719
|
+
const modifications = [];
|
|
720
|
+
// Find HTML file to inject script
|
|
721
|
+
const htmlFile = this.findHTMLFile();
|
|
722
|
+
if (htmlFile) {
|
|
723
|
+
const content = fs.readFileSync(htmlFile, 'utf8');
|
|
724
|
+
const modifiedContent = this.injectVanillaScript(content);
|
|
725
|
+
modifications.push({
|
|
726
|
+
filePath: htmlFile,
|
|
727
|
+
action: 'modify',
|
|
728
|
+
content: modifiedContent,
|
|
729
|
+
description: 'Added HumanBehavior CDN script to HTML file'
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
// Create or append to environment file
|
|
733
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
734
|
+
return modifications;
|
|
735
|
+
}
|
|
736
|
+
/**
|
|
737
|
+
* Generate Gatsby-specific modifications
|
|
738
|
+
*/
|
|
739
|
+
async generateGatsbyModifications() {
|
|
740
|
+
const modifications = [];
|
|
741
|
+
// Modify or create gatsby-browser.js for Gatsby
|
|
742
|
+
const gatsbyBrowserFile = path.join(this.projectRoot, 'gatsby-browser.js');
|
|
743
|
+
if (fs.existsSync(gatsbyBrowserFile)) {
|
|
744
|
+
const content = fs.readFileSync(gatsbyBrowserFile, 'utf8');
|
|
745
|
+
const modifiedContent = this.injectGatsbyBrowser(content);
|
|
746
|
+
modifications.push({
|
|
747
|
+
filePath: gatsbyBrowserFile,
|
|
748
|
+
action: 'modify',
|
|
749
|
+
content: modifiedContent,
|
|
750
|
+
description: 'Added HumanBehavior initialization to Gatsby browser'
|
|
751
|
+
});
|
|
752
|
+
}
|
|
753
|
+
else {
|
|
754
|
+
// Create gatsby-browser.js if it doesn't exist
|
|
755
|
+
modifications.push({
|
|
756
|
+
filePath: gatsbyBrowserFile,
|
|
757
|
+
action: 'create',
|
|
758
|
+
content: `import { HumanBehaviorTracker } from 'humanbehavior-js';
|
|
817
759
|
|
|
818
760
|
export const onClientEntry = () => {
|
|
819
761
|
console.log('Gatsby browser entry point loaded');
|
|
@@ -826,55 +768,51 @@ export const onClientEntry = () => {
|
|
|
826
768
|
console.log('No API key found in environment variables');
|
|
827
769
|
}
|
|
828
770
|
};`,
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
});
|
|
771
|
+
description: 'Created gatsby-browser.js with HumanBehavior initialization'
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
// Create or append to environment file
|
|
775
|
+
modifications.push(this.createEnvironmentModification(this.framework));
|
|
776
|
+
return modifications;
|
|
836
777
|
}
|
|
837
778
|
/**
|
|
838
779
|
* Apply modifications to the codebase
|
|
839
780
|
*/
|
|
840
|
-
applyModifications(modifications) {
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
847
|
-
}
|
|
848
|
-
switch (modification.action) {
|
|
849
|
-
case 'create':
|
|
850
|
-
fs.writeFileSync(modification.filePath, modification.content);
|
|
851
|
-
break;
|
|
852
|
-
case 'modify':
|
|
853
|
-
fs.writeFileSync(modification.filePath, modification.content);
|
|
854
|
-
break;
|
|
855
|
-
case 'append':
|
|
856
|
-
fs.appendFileSync(modification.filePath, '\n' + modification.content);
|
|
857
|
-
break;
|
|
858
|
-
}
|
|
781
|
+
async applyModifications(modifications) {
|
|
782
|
+
for (const modification of modifications) {
|
|
783
|
+
try {
|
|
784
|
+
const dir = path.dirname(modification.filePath);
|
|
785
|
+
if (!fs.existsSync(dir)) {
|
|
786
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
859
787
|
}
|
|
860
|
-
|
|
861
|
-
|
|
788
|
+
switch (modification.action) {
|
|
789
|
+
case 'create':
|
|
790
|
+
fs.writeFileSync(modification.filePath, modification.content);
|
|
791
|
+
break;
|
|
792
|
+
case 'modify':
|
|
793
|
+
fs.writeFileSync(modification.filePath, modification.content);
|
|
794
|
+
break;
|
|
795
|
+
case 'append':
|
|
796
|
+
fs.appendFileSync(modification.filePath, '\n' + modification.content);
|
|
797
|
+
break;
|
|
862
798
|
}
|
|
863
799
|
}
|
|
864
|
-
|
|
800
|
+
catch (error) {
|
|
801
|
+
throw new Error(`Failed to apply modification to ${modification.filePath}: ${error}`);
|
|
802
|
+
}
|
|
803
|
+
}
|
|
865
804
|
}
|
|
866
805
|
/**
|
|
867
806
|
* Generate next steps for the user
|
|
868
807
|
*/
|
|
869
808
|
generateNextSteps() {
|
|
870
|
-
var _a, _b;
|
|
871
809
|
const steps = [
|
|
872
810
|
'✅ SDK installed and configured automatically!',
|
|
873
811
|
'🚀 Your app is now tracking user behavior',
|
|
874
812
|
'📊 View sessions in your HumanBehavior dashboard',
|
|
875
813
|
'🔧 Customize tracking in your code as needed'
|
|
876
814
|
];
|
|
877
|
-
if (
|
|
815
|
+
if (this.framework?.type === 'react' || this.framework?.type === 'nextjs') {
|
|
878
816
|
steps.push('💡 Use the useHumanBehavior() hook to track custom events');
|
|
879
817
|
}
|
|
880
818
|
return steps;
|
|
@@ -928,20 +866,19 @@ export const onClientEntry = () => {
|
|
|
928
866
|
return null;
|
|
929
867
|
}
|
|
930
868
|
injectReactProvider(content, filePath) {
|
|
931
|
-
var _a, _b, _c;
|
|
932
869
|
filePath.endsWith('.tsx') || filePath.endsWith('.ts');
|
|
933
870
|
// Check if already has HumanBehaviorProvider
|
|
934
871
|
if (content.includes('HumanBehaviorProvider')) {
|
|
935
872
|
return content;
|
|
936
873
|
}
|
|
937
874
|
// Determine the correct environment variable syntax based on bundler
|
|
938
|
-
const isVite =
|
|
875
|
+
const isVite = this.framework?.bundler === 'vite';
|
|
939
876
|
const envVar = isVite
|
|
940
877
|
? 'import.meta.env.VITE_HUMANBEHAVIOR_API_KEY!'
|
|
941
878
|
: 'process.env.HUMANBEHAVIOR_API_KEY!';
|
|
942
879
|
const importStatement = `import { HumanBehaviorProvider } from 'humanbehavior-js/react';`;
|
|
943
880
|
// Enhanced parsing for React 18+ features
|
|
944
|
-
const hasReact18 =
|
|
881
|
+
const hasReact18 = this.framework?.features?.hasReact18;
|
|
945
882
|
// Handle different React patterns
|
|
946
883
|
if (content.includes('function App()') || content.includes('const App =')) {
|
|
947
884
|
// Add import statement
|
|
@@ -1069,13 +1006,12 @@ export default function App()`);
|
|
|
1069
1006
|
return modifiedContent;
|
|
1070
1007
|
}
|
|
1071
1008
|
injectVuePlugin(content) {
|
|
1072
|
-
var _a, _b;
|
|
1073
1009
|
if (content.includes('HumanBehaviorPlugin')) {
|
|
1074
1010
|
return content;
|
|
1075
1011
|
}
|
|
1076
1012
|
const importStatement = `import { HumanBehaviorPlugin } from 'humanbehavior-js/vue';`;
|
|
1077
1013
|
// Enhanced Vue 3 support with version detection
|
|
1078
|
-
const hasVue3 =
|
|
1014
|
+
const hasVue3 = this.framework?.features?.hasVue3;
|
|
1079
1015
|
if (hasVue3) {
|
|
1080
1016
|
// Vue 3 with Composition API
|
|
1081
1017
|
const pluginUsage = `app.use(HumanBehaviorPlugin, {
|
|
@@ -1225,12 +1161,11 @@ if (typeof window !== 'undefined') {
|
|
|
1225
1161
|
return modifiedContent.slice(0, bodyCloseIndex) + ' <HumanBehavior />\n' + modifiedContent.slice(bodyCloseIndex);
|
|
1226
1162
|
}
|
|
1227
1163
|
injectNuxtConfig(content) {
|
|
1228
|
-
var _a, _b;
|
|
1229
1164
|
if (content.includes('humanBehaviorApiKey')) {
|
|
1230
1165
|
return content;
|
|
1231
1166
|
}
|
|
1232
1167
|
// Enhanced Nuxt 3 support with version detection
|
|
1233
|
-
const hasNuxt3 =
|
|
1168
|
+
const hasNuxt3 = this.framework?.features?.hasNuxt3;
|
|
1234
1169
|
if (hasNuxt3) {
|
|
1235
1170
|
// Nuxt 3 with runtime config
|
|
1236
1171
|
return content.replace(/export default defineNuxtConfig\(\{/, `export default defineNuxtConfig({
|
|
@@ -1400,85 +1335,82 @@ export const onClientEntry = () => {
|
|
|
1400
1335
|
*/
|
|
1401
1336
|
class RemoteAIService {
|
|
1402
1337
|
constructor(config) {
|
|
1403
|
-
this.config =
|
|
1338
|
+
this.config = {
|
|
1339
|
+
timeout: 10000, // 10 seconds
|
|
1340
|
+
...config
|
|
1341
|
+
};
|
|
1404
1342
|
}
|
|
1405
1343
|
/**
|
|
1406
1344
|
* Analyze code patterns using your deployed AI service
|
|
1407
1345
|
*/
|
|
1408
|
-
analyzeCodePatterns(codeSamples) {
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
throw new Error(`AI service returned ${response.status}: ${response.statusText}`);
|
|
1421
|
-
}
|
|
1422
|
-
const result = yield response.json();
|
|
1423
|
-
return result.analysis;
|
|
1424
|
-
}
|
|
1425
|
-
catch (error) {
|
|
1426
|
-
console.warn('Remote AI service failed, falling back to heuristic analysis:', error);
|
|
1427
|
-
return this.performHeuristicAnalysis(codeSamples);
|
|
1346
|
+
async analyzeCodePatterns(codeSamples) {
|
|
1347
|
+
try {
|
|
1348
|
+
const response = await fetch(`${this.config.apiEndpoint}/analyze`, {
|
|
1349
|
+
method: 'POST',
|
|
1350
|
+
headers: {
|
|
1351
|
+
'Content-Type': 'application/json',
|
|
1352
|
+
},
|
|
1353
|
+
body: JSON.stringify({ codeSamples }),
|
|
1354
|
+
signal: AbortSignal.timeout(this.config.timeout || 10000)
|
|
1355
|
+
});
|
|
1356
|
+
if (!response.ok) {
|
|
1357
|
+
throw new Error(`AI service returned ${response.status}: ${response.statusText}`);
|
|
1428
1358
|
}
|
|
1429
|
-
|
|
1359
|
+
const result = await response.json();
|
|
1360
|
+
return result.analysis;
|
|
1361
|
+
}
|
|
1362
|
+
catch (error) {
|
|
1363
|
+
console.warn('Remote AI service failed, falling back to heuristic analysis:', error);
|
|
1364
|
+
return this.performHeuristicAnalysis(codeSamples);
|
|
1365
|
+
}
|
|
1430
1366
|
}
|
|
1431
1367
|
/**
|
|
1432
1368
|
* Resolve conflicts using your deployed AI service
|
|
1433
1369
|
*/
|
|
1434
|
-
resolveConflicts(conflicts, framework) {
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
throw new Error(`AI service returned ${response.status}: ${response.statusText}`);
|
|
1447
|
-
}
|
|
1448
|
-
const result = yield response.json();
|
|
1449
|
-
return result.resolutions || [];
|
|
1450
|
-
}
|
|
1451
|
-
catch (error) {
|
|
1452
|
-
console.warn('Remote AI conflict resolution failed, using heuristic approach:', error);
|
|
1453
|
-
return this.resolveConflictsHeuristic(conflicts, framework);
|
|
1370
|
+
async resolveConflicts(conflicts, framework) {
|
|
1371
|
+
try {
|
|
1372
|
+
const response = await fetch(`${this.config.apiEndpoint}/resolve-conflicts`, {
|
|
1373
|
+
method: 'POST',
|
|
1374
|
+
headers: {
|
|
1375
|
+
'Content-Type': 'application/json',
|
|
1376
|
+
},
|
|
1377
|
+
body: JSON.stringify({ conflicts, framework }),
|
|
1378
|
+
signal: AbortSignal.timeout(this.config.timeout || 10000)
|
|
1379
|
+
});
|
|
1380
|
+
if (!response.ok) {
|
|
1381
|
+
throw new Error(`AI service returned ${response.status}: ${response.statusText}`);
|
|
1454
1382
|
}
|
|
1455
|
-
|
|
1383
|
+
const result = await response.json();
|
|
1384
|
+
return result.resolutions || [];
|
|
1385
|
+
}
|
|
1386
|
+
catch (error) {
|
|
1387
|
+
console.warn('Remote AI conflict resolution failed, using heuristic approach:', error);
|
|
1388
|
+
return this.resolveConflictsHeuristic(conflicts, framework);
|
|
1389
|
+
}
|
|
1456
1390
|
}
|
|
1457
1391
|
/**
|
|
1458
1392
|
* Generate optimizations using your deployed AI service
|
|
1459
1393
|
*/
|
|
1460
|
-
generateOptimizations(framework, patterns) {
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
throw new Error(`AI service returned ${response.status}: ${response.statusText}`);
|
|
1473
|
-
}
|
|
1474
|
-
const result = yield response.json();
|
|
1475
|
-
return result.optimizations || [];
|
|
1476
|
-
}
|
|
1477
|
-
catch (error) {
|
|
1478
|
-
console.warn('Remote AI optimization generation failed, using heuristic approach:', error);
|
|
1479
|
-
return this.generateOptimizationsHeuristic(framework, patterns);
|
|
1394
|
+
async generateOptimizations(framework, patterns) {
|
|
1395
|
+
try {
|
|
1396
|
+
const response = await fetch(`${this.config.apiEndpoint}/optimize`, {
|
|
1397
|
+
method: 'POST',
|
|
1398
|
+
headers: {
|
|
1399
|
+
'Content-Type': 'application/json',
|
|
1400
|
+
},
|
|
1401
|
+
body: JSON.stringify({ framework, patterns }),
|
|
1402
|
+
signal: AbortSignal.timeout(this.config.timeout || 10000)
|
|
1403
|
+
});
|
|
1404
|
+
if (!response.ok) {
|
|
1405
|
+
throw new Error(`AI service returned ${response.status}: ${response.statusText}`);
|
|
1480
1406
|
}
|
|
1481
|
-
|
|
1407
|
+
const result = await response.json();
|
|
1408
|
+
return result.optimizations || [];
|
|
1409
|
+
}
|
|
1410
|
+
catch (error) {
|
|
1411
|
+
console.warn('Remote AI optimization generation failed, using heuristic approach:', error);
|
|
1412
|
+
return this.generateOptimizationsHeuristic(framework, patterns);
|
|
1413
|
+
}
|
|
1482
1414
|
}
|
|
1483
1415
|
/**
|
|
1484
1416
|
* Heuristic analysis fallback
|
|
@@ -1613,108 +1545,106 @@ class ManualFrameworkInstallationWizard extends AutoInstallationWizard {
|
|
|
1613
1545
|
/**
|
|
1614
1546
|
* Manual installation with user-specified framework
|
|
1615
1547
|
*/
|
|
1616
|
-
install() {
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
this.framework = yield this.runFullDetection();
|
|
1623
|
-
}
|
|
1624
|
-
else {
|
|
1625
|
-
// Set framework based on user selection
|
|
1626
|
-
this.framework = this.createFrameworkInfo(this.selectedFramework);
|
|
1627
|
-
if (!this.framework) {
|
|
1628
|
-
this.framework = { name: 'unknown', type: 'vanilla' };
|
|
1629
|
-
}
|
|
1630
|
-
// Step 2: Run full detection logic to find entry points, file names, etc.
|
|
1631
|
-
const detectedFramework = yield this.runFullDetection();
|
|
1632
|
-
// Step 3: Merge manual framework with detected details
|
|
1633
|
-
this.framework = Object.assign(Object.assign({}, detectedFramework), { name: this.framework.name, type: this.framework.type });
|
|
1634
|
-
}
|
|
1635
|
-
// Step 4: Install package
|
|
1636
|
-
yield this.installPackage();
|
|
1637
|
-
// Step 5: Generate and apply code modifications
|
|
1638
|
-
const modifications = yield this.generateModifications();
|
|
1639
|
-
yield this.applyModifications(modifications);
|
|
1640
|
-
// Step 6: Generate next steps
|
|
1641
|
-
const nextSteps = this.generateManualNextSteps();
|
|
1642
|
-
return {
|
|
1643
|
-
success: true,
|
|
1644
|
-
framework: this.framework,
|
|
1645
|
-
modifications,
|
|
1646
|
-
errors: [],
|
|
1647
|
-
nextSteps,
|
|
1648
|
-
selectedFramework: this.selectedFramework,
|
|
1649
|
-
manualMode: true
|
|
1650
|
-
};
|
|
1548
|
+
async install() {
|
|
1549
|
+
try {
|
|
1550
|
+
// Step 1: Handle framework selection
|
|
1551
|
+
if (this.selectedFramework === 'auto') {
|
|
1552
|
+
// Use full AI detection for "Other" option
|
|
1553
|
+
this.framework = await this.runFullDetection();
|
|
1651
1554
|
}
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1555
|
+
else {
|
|
1556
|
+
// Set framework based on user selection
|
|
1557
|
+
this.framework = this.createFrameworkInfo(this.selectedFramework);
|
|
1558
|
+
if (!this.framework) {
|
|
1559
|
+
this.framework = { name: 'unknown', type: 'vanilla' };
|
|
1560
|
+
}
|
|
1561
|
+
// Step 2: Run full detection logic to find entry points, file names, etc.
|
|
1562
|
+
const detectedFramework = await this.runFullDetection();
|
|
1563
|
+
// Step 3: Merge manual framework with detected details
|
|
1564
|
+
this.framework = {
|
|
1565
|
+
...detectedFramework,
|
|
1566
|
+
name: this.framework.name,
|
|
1567
|
+
type: this.framework.type
|
|
1661
1568
|
};
|
|
1662
1569
|
}
|
|
1663
|
-
|
|
1570
|
+
// Step 4: Install package
|
|
1571
|
+
await this.installPackage();
|
|
1572
|
+
// Step 5: Generate and apply code modifications
|
|
1573
|
+
const modifications = await this.generateModifications();
|
|
1574
|
+
await this.applyModifications(modifications);
|
|
1575
|
+
// Step 6: Generate next steps
|
|
1576
|
+
const nextSteps = this.generateManualNextSteps();
|
|
1577
|
+
return {
|
|
1578
|
+
success: true,
|
|
1579
|
+
framework: this.framework,
|
|
1580
|
+
modifications,
|
|
1581
|
+
errors: [],
|
|
1582
|
+
nextSteps,
|
|
1583
|
+
selectedFramework: this.selectedFramework,
|
|
1584
|
+
manualMode: true
|
|
1585
|
+
};
|
|
1586
|
+
}
|
|
1587
|
+
catch (error) {
|
|
1588
|
+
return {
|
|
1589
|
+
success: false,
|
|
1590
|
+
framework: this.framework || { name: 'unknown', type: 'vanilla' },
|
|
1591
|
+
modifications: [],
|
|
1592
|
+
errors: [error instanceof Error ? error.message : 'Unknown error'],
|
|
1593
|
+
nextSteps: [],
|
|
1594
|
+
selectedFramework: this.selectedFramework,
|
|
1595
|
+
manualMode: true
|
|
1596
|
+
};
|
|
1597
|
+
}
|
|
1664
1598
|
}
|
|
1665
1599
|
/**
|
|
1666
1600
|
* Run full detection logic to find entry points, file names, bundler, etc.
|
|
1667
1601
|
*/
|
|
1668
|
-
runFullDetection() {
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
}
|
|
1687
|
-
});
|
|
1602
|
+
async runFullDetection() {
|
|
1603
|
+
if (this.selectedFramework === 'auto') {
|
|
1604
|
+
// Use AI service for auto-detection
|
|
1605
|
+
const aiService = new RemoteAIService({
|
|
1606
|
+
apiEndpoint: 'https://ik3zxh4790.execute-api.us-east-1.amazonaws.com/prod'
|
|
1607
|
+
});
|
|
1608
|
+
// Use AI service directly for detection
|
|
1609
|
+
const projectFiles = await this.scanProjectFiles();
|
|
1610
|
+
const codeSamples = await this.extractCodeSamples(projectFiles);
|
|
1611
|
+
const aiAnalysis = await aiService.analyzeCodePatterns(codeSamples);
|
|
1612
|
+
return aiAnalysis.framework;
|
|
1613
|
+
}
|
|
1614
|
+
else {
|
|
1615
|
+
// Use traditional detection for manual frameworks
|
|
1616
|
+
const tempWizard = new AutoInstallationWizard(this.apiKey, this.projectRoot);
|
|
1617
|
+
const detected = await tempWizard.detectFramework();
|
|
1618
|
+
return detected;
|
|
1619
|
+
}
|
|
1688
1620
|
}
|
|
1689
1621
|
/**
|
|
1690
1622
|
* Scan project files for analysis
|
|
1691
1623
|
*/
|
|
1692
|
-
scanProjectFiles() {
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
files.push(fullPath);
|
|
1708
|
-
}
|
|
1624
|
+
async scanProjectFiles() {
|
|
1625
|
+
const files = [];
|
|
1626
|
+
const scanDir = (dir, depth = 0) => {
|
|
1627
|
+
if (depth > 3)
|
|
1628
|
+
return; // Limit depth
|
|
1629
|
+
try {
|
|
1630
|
+
const items = fs.readdirSync(dir);
|
|
1631
|
+
for (const item of items) {
|
|
1632
|
+
const fullPath = path.join(dir, item);
|
|
1633
|
+
const stat = fs.statSync(fullPath);
|
|
1634
|
+
if (stat.isDirectory() && !item.startsWith('.') && item !== 'node_modules') {
|
|
1635
|
+
scanDir(fullPath, depth + 1);
|
|
1636
|
+
}
|
|
1637
|
+
else if (stat.isFile() && this.isRelevantFile(item)) {
|
|
1638
|
+
files.push(fullPath);
|
|
1709
1639
|
}
|
|
1710
1640
|
}
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
}
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1641
|
+
}
|
|
1642
|
+
catch (error) {
|
|
1643
|
+
// Skip inaccessible directories
|
|
1644
|
+
}
|
|
1645
|
+
};
|
|
1646
|
+
scanDir(this.projectRoot);
|
|
1647
|
+
return files;
|
|
1718
1648
|
}
|
|
1719
1649
|
/**
|
|
1720
1650
|
* Check if file is relevant for analysis
|
|
@@ -1734,21 +1664,19 @@ class ManualFrameworkInstallationWizard extends AutoInstallationWizard {
|
|
|
1734
1664
|
/**
|
|
1735
1665
|
* Extract code samples for AI analysis
|
|
1736
1666
|
*/
|
|
1737
|
-
extractCodeSamples(files) {
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
samples.push(`File: ${relativePath}\n${content.substring(0, 1000)}`);
|
|
1745
|
-
}
|
|
1746
|
-
catch (error) {
|
|
1747
|
-
// Skip unreadable files
|
|
1748
|
-
}
|
|
1667
|
+
async extractCodeSamples(files) {
|
|
1668
|
+
const samples = [];
|
|
1669
|
+
for (const file of files.slice(0, 20)) { // Limit to 20 files
|
|
1670
|
+
try {
|
|
1671
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
1672
|
+
const relativePath = path.relative(this.projectRoot, file);
|
|
1673
|
+
samples.push(`File: ${relativePath}\n${content.substring(0, 1000)}`);
|
|
1749
1674
|
}
|
|
1750
|
-
|
|
1751
|
-
|
|
1675
|
+
catch (error) {
|
|
1676
|
+
// Skip unreadable files
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
return samples;
|
|
1752
1680
|
}
|
|
1753
1681
|
/**
|
|
1754
1682
|
* Create framework info based on user selection
|
|
@@ -1776,19 +1704,16 @@ class ManualFrameworkInstallationWizard extends AutoInstallationWizard {
|
|
|
1776
1704
|
/**
|
|
1777
1705
|
* Override framework detection to use manual selection
|
|
1778
1706
|
*/
|
|
1779
|
-
detectFramework() {
|
|
1780
|
-
return
|
|
1781
|
-
return this.framework || { name: 'unknown', type: 'vanilla' };
|
|
1782
|
-
});
|
|
1707
|
+
async detectFramework() {
|
|
1708
|
+
return this.framework || { name: 'unknown', type: 'vanilla' };
|
|
1783
1709
|
}
|
|
1784
1710
|
/**
|
|
1785
1711
|
* Generate next steps with manual mode info
|
|
1786
1712
|
*/
|
|
1787
1713
|
generateManualNextSteps() {
|
|
1788
|
-
var _a;
|
|
1789
1714
|
return [
|
|
1790
1715
|
'✅ Manual framework installation completed!',
|
|
1791
|
-
`🎯 Selected framework: ${
|
|
1716
|
+
`🎯 Selected framework: ${this.framework?.name || 'unknown'}`,
|
|
1792
1717
|
`🔧 Integration strategy: ${this.getIntegrationStrategy()}`,
|
|
1793
1718
|
'🚀 Your app is now ready to track user behavior',
|
|
1794
1719
|
'📊 View sessions in your HumanBehavior dashboard'
|
|
@@ -1798,8 +1723,7 @@ class ManualFrameworkInstallationWizard extends AutoInstallationWizard {
|
|
|
1798
1723
|
* Get integration strategy based on framework
|
|
1799
1724
|
*/
|
|
1800
1725
|
getIntegrationStrategy() {
|
|
1801
|
-
|
|
1802
|
-
if (!((_a = this.framework) === null || _a === void 0 ? void 0 : _a.type))
|
|
1726
|
+
if (!this.framework?.type)
|
|
1803
1727
|
return 'script';
|
|
1804
1728
|
switch (this.framework.type) {
|
|
1805
1729
|
case 'react':
|
|
@@ -1827,93 +1751,85 @@ class AutoInstallCLI {
|
|
|
1827
1751
|
constructor(options) {
|
|
1828
1752
|
this.options = options;
|
|
1829
1753
|
}
|
|
1830
|
-
run() {
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1754
|
+
async run() {
|
|
1755
|
+
clack.intro('🚀 HumanBehavior SDK Auto-Installation');
|
|
1756
|
+
try {
|
|
1757
|
+
// Get API key
|
|
1758
|
+
const apiKey = await this.getApiKey();
|
|
1759
|
+
if (!apiKey) {
|
|
1760
|
+
clack.cancel('API key is required');
|
|
1761
|
+
process.exit(1);
|
|
1762
|
+
}
|
|
1763
|
+
// Get project path
|
|
1764
|
+
const projectPath = this.options.projectPath || process.cwd();
|
|
1765
|
+
// Choose framework
|
|
1766
|
+
const framework = await this.chooseFramework();
|
|
1767
|
+
if (!framework) {
|
|
1768
|
+
clack.cancel('Installation cancelled.');
|
|
1769
|
+
process.exit(0);
|
|
1770
|
+
}
|
|
1771
|
+
// Confirm installation
|
|
1772
|
+
if (!this.options.yes) {
|
|
1773
|
+
const confirmed = await this.confirmInstallation(projectPath, framework);
|
|
1774
|
+
if (!confirmed) {
|
|
1845
1775
|
clack.cancel('Installation cancelled.');
|
|
1846
1776
|
process.exit(0);
|
|
1847
1777
|
}
|
|
1848
|
-
// Confirm installation
|
|
1849
|
-
if (!this.options.yes) {
|
|
1850
|
-
const confirmed = yield this.confirmInstallation(projectPath, framework);
|
|
1851
|
-
if (!confirmed) {
|
|
1852
|
-
clack.cancel('Installation cancelled.');
|
|
1853
|
-
process.exit(0);
|
|
1854
|
-
}
|
|
1855
|
-
}
|
|
1856
|
-
// Run installation
|
|
1857
|
-
const spinner = clack.spinner();
|
|
1858
|
-
spinner.start('🔍 Analyzing your project...');
|
|
1859
|
-
const wizard = new ManualFrameworkInstallationWizard(apiKey, projectPath, framework);
|
|
1860
|
-
const result = yield wizard.install();
|
|
1861
|
-
spinner.stop('Detection complete!');
|
|
1862
|
-
// Display results
|
|
1863
|
-
this.displayResults(result);
|
|
1864
1778
|
}
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1779
|
+
// Run installation
|
|
1780
|
+
const spinner = clack.spinner();
|
|
1781
|
+
spinner.start('🔍 Analyzing your project...');
|
|
1782
|
+
const wizard = new ManualFrameworkInstallationWizard(apiKey, projectPath, framework);
|
|
1783
|
+
const result = await wizard.install();
|
|
1784
|
+
spinner.stop('Detection complete!');
|
|
1785
|
+
// Display results
|
|
1786
|
+
this.displayResults(result);
|
|
1787
|
+
}
|
|
1788
|
+
catch (error) {
|
|
1789
|
+
clack.cancel(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
1790
|
+
process.exit(1);
|
|
1791
|
+
}
|
|
1870
1792
|
}
|
|
1871
|
-
getApiKey() {
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1793
|
+
async getApiKey() {
|
|
1794
|
+
if (this.options.apiKey) {
|
|
1795
|
+
return this.options.apiKey;
|
|
1796
|
+
}
|
|
1797
|
+
const apiKey = await clack.text({
|
|
1798
|
+
message: 'Enter your HumanBehavior API key:',
|
|
1799
|
+
placeholder: 'hb_...',
|
|
1800
|
+
validate: (value) => {
|
|
1801
|
+
if (!value)
|
|
1802
|
+
return 'API key is required';
|
|
1803
|
+
if (!value.startsWith('hb_'))
|
|
1804
|
+
return 'API key should start with "hb_"';
|
|
1805
|
+
return undefined;
|
|
1875
1806
|
}
|
|
1876
|
-
const apiKey = yield clack.text({
|
|
1877
|
-
message: 'Enter your HumanBehavior API key:',
|
|
1878
|
-
placeholder: 'hb_...',
|
|
1879
|
-
validate: (value) => {
|
|
1880
|
-
if (!value)
|
|
1881
|
-
return 'API key is required';
|
|
1882
|
-
if (!value.startsWith('hb_'))
|
|
1883
|
-
return 'API key should start with "hb_"';
|
|
1884
|
-
return undefined;
|
|
1885
|
-
}
|
|
1886
|
-
});
|
|
1887
|
-
return apiKey;
|
|
1888
1807
|
});
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
});
|
|
1907
|
-
return framework;
|
|
1808
|
+
return apiKey;
|
|
1809
|
+
}
|
|
1810
|
+
async chooseFramework() {
|
|
1811
|
+
const framework = await clack.select({
|
|
1812
|
+
message: 'Select your framework:',
|
|
1813
|
+
options: [
|
|
1814
|
+
{ label: 'React', value: 'react' },
|
|
1815
|
+
{ label: 'Next.js', value: 'nextjs' },
|
|
1816
|
+
{ label: 'Vue', value: 'vue' },
|
|
1817
|
+
{ label: 'Angular', value: 'angular' },
|
|
1818
|
+
{ label: 'Svelte', value: 'svelte' },
|
|
1819
|
+
{ label: 'Nuxt.js', value: 'nuxt' },
|
|
1820
|
+
{ label: 'Remix', value: 'remix' },
|
|
1821
|
+
{ label: 'Astro', value: 'astro' },
|
|
1822
|
+
{ label: 'Gatsby', value: 'gatsby' },
|
|
1823
|
+
{ label: 'Vanilla JS/TS', value: 'vanilla' }
|
|
1824
|
+
]
|
|
1908
1825
|
});
|
|
1826
|
+
return framework;
|
|
1909
1827
|
}
|
|
1910
|
-
confirmInstallation(projectPath, framework) {
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
message: `Ready to install HumanBehavior SDK in ${projectPath} for ${framework}?`
|
|
1914
|
-
});
|
|
1915
|
-
return confirmed;
|
|
1828
|
+
async confirmInstallation(projectPath, framework) {
|
|
1829
|
+
const confirmed = await clack.confirm({
|
|
1830
|
+
message: `Ready to install HumanBehavior SDK in ${projectPath} for ${framework}?`
|
|
1916
1831
|
});
|
|
1832
|
+
return confirmed;
|
|
1917
1833
|
}
|
|
1918
1834
|
displayResults(result) {
|
|
1919
1835
|
if (result.success) {
|