@gurulu/cli 0.4.6 → 1.0.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.
Files changed (180) hide show
  1. package/LICENSE +92 -0
  2. package/README.md +35 -106
  3. package/dist/bin.d.ts +3 -0
  4. package/dist/bin.d.ts.map +1 -0
  5. package/dist/bin.js +25410 -0
  6. package/dist/commands/auth.d.ts +23 -20
  7. package/dist/commands/auth.d.ts.map +1 -0
  8. package/dist/commands/doctor.d.ts +20 -6
  9. package/dist/commands/doctor.d.ts.map +1 -0
  10. package/dist/commands/init.d.ts +25 -11
  11. package/dist/commands/init.d.ts.map +1 -0
  12. package/dist/commands/pull.d.ts +13 -0
  13. package/dist/commands/pull.d.ts.map +1 -0
  14. package/dist/commands/push.d.ts +40 -0
  15. package/dist/commands/push.d.ts.map +1 -0
  16. package/dist/commands/validate.d.ts +36 -0
  17. package/dist/commands/validate.d.ts.map +1 -0
  18. package/dist/index.d.ts +4 -1
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +24985 -853
  21. package/dist/lib/api.d.ts +139 -0
  22. package/dist/lib/api.d.ts.map +1 -0
  23. package/dist/lib/codegen.d.ts +4 -0
  24. package/dist/lib/codegen.d.ts.map +1 -0
  25. package/dist/lib/config.d.ts +43 -0
  26. package/dist/lib/config.d.ts.map +1 -0
  27. package/package.json +40 -20
  28. package/bin/gurulu.js +0 -2
  29. package/dist/api-client.d.ts +0 -33
  30. package/dist/api-client.js +0 -175
  31. package/dist/commands/add-server.d.ts +0 -9
  32. package/dist/commands/add-server.js +0 -162
  33. package/dist/commands/alerts.d.ts +0 -27
  34. package/dist/commands/alerts.js +0 -309
  35. package/dist/commands/api-keys.d.ts +0 -20
  36. package/dist/commands/api-keys.js +0 -130
  37. package/dist/commands/attribution.d.ts +0 -22
  38. package/dist/commands/attribution.js +0 -111
  39. package/dist/commands/audiences.d.ts +0 -23
  40. package/dist/commands/audiences.js +0 -243
  41. package/dist/commands/audit.d.ts +0 -20
  42. package/dist/commands/audit.js +0 -130
  43. package/dist/commands/auth.js +0 -249
  44. package/dist/commands/chat.d.ts +0 -18
  45. package/dist/commands/chat.js +0 -117
  46. package/dist/commands/config.d.ts +0 -10
  47. package/dist/commands/config.js +0 -92
  48. package/dist/commands/consent.d.ts +0 -27
  49. package/dist/commands/consent.js +0 -233
  50. package/dist/commands/conversion-paths.d.ts +0 -19
  51. package/dist/commands/conversion-paths.js +0 -55
  52. package/dist/commands/db.d.ts +0 -25
  53. package/dist/commands/db.js +0 -330
  54. package/dist/commands/destinations.d.ts +0 -20
  55. package/dist/commands/destinations.js +0 -191
  56. package/dist/commands/doctor.js +0 -360
  57. package/dist/commands/errors.d.ts +0 -27
  58. package/dist/commands/errors.js +0 -121
  59. package/dist/commands/events.d.ts +0 -33
  60. package/dist/commands/events.js +0 -349
  61. package/dist/commands/experiments.d.ts +0 -22
  62. package/dist/commands/experiments.js +0 -264
  63. package/dist/commands/funnels.d.ts +0 -17
  64. package/dist/commands/funnels.js +0 -203
  65. package/dist/commands/goals.d.ts +0 -18
  66. package/dist/commands/goals.js +0 -214
  67. package/dist/commands/heatmap.d.ts +0 -27
  68. package/dist/commands/heatmap.js +0 -112
  69. package/dist/commands/identity.d.ts +0 -29
  70. package/dist/commands/identity.js +0 -328
  71. package/dist/commands/init.js +0 -215
  72. package/dist/commands/insights.d.ts +0 -10
  73. package/dist/commands/insights.js +0 -65
  74. package/dist/commands/install.d.ts +0 -259
  75. package/dist/commands/install.js +0 -1590
  76. package/dist/commands/login.d.ts +0 -20
  77. package/dist/commands/login.js +0 -170
  78. package/dist/commands/logout.d.ts +0 -10
  79. package/dist/commands/logout.js +0 -41
  80. package/dist/commands/playground.d.ts +0 -11
  81. package/dist/commands/playground.js +0 -47
  82. package/dist/commands/releases.d.ts +0 -17
  83. package/dist/commands/releases.js +0 -54
  84. package/dist/commands/replay.d.ts +0 -18
  85. package/dist/commands/replay.js +0 -64
  86. package/dist/commands/secrets.d.ts +0 -19
  87. package/dist/commands/secrets.js +0 -145
  88. package/dist/commands/sites.d.ts +0 -18
  89. package/dist/commands/sites.js +0 -139
  90. package/dist/commands/skad.d.ts +0 -18
  91. package/dist/commands/skad.js +0 -53
  92. package/dist/commands/sourcemap.d.ts +0 -33
  93. package/dist/commands/sourcemap.js +0 -204
  94. package/dist/commands/status.d.ts +0 -7
  95. package/dist/commands/status.js +0 -136
  96. package/dist/commands/upgrade.d.ts +0 -21
  97. package/dist/commands/upgrade.js +0 -183
  98. package/dist/commands/warehouse.d.ts +0 -20
  99. package/dist/commands/warehouse.js +0 -65
  100. package/dist/commands/warehouses.d.ts +0 -17
  101. package/dist/commands/warehouses.js +0 -182
  102. package/dist/commands/watch.d.ts +0 -45
  103. package/dist/commands/watch.js +0 -258
  104. package/dist/commands/whoami.d.ts +0 -9
  105. package/dist/commands/whoami.js +0 -50
  106. package/dist/config.d.ts +0 -75
  107. package/dist/config.js +0 -329
  108. package/dist/frameworks/detect.d.ts +0 -8
  109. package/dist/frameworks/detect.js +0 -444
  110. package/dist/install-intent-proposal.d.ts +0 -99
  111. package/dist/install-intent-proposal.js +0 -202
  112. package/dist/utils/api.d.ts +0 -20
  113. package/dist/utils/api.js +0 -47
  114. package/dist/utils/config.d.ts +0 -13
  115. package/dist/utils/config.js +0 -30
  116. package/dist/utils/confirm.d.ts +0 -17
  117. package/dist/utils/confirm.js +0 -40
  118. package/dist/utils/dry-run.d.ts +0 -20
  119. package/dist/utils/dry-run.js +0 -67
  120. package/dist/utils/from-file.d.ts +0 -9
  121. package/dist/utils/from-file.js +0 -72
  122. package/dist/utils/redact.d.ts +0 -14
  123. package/dist/utils/redact.js +0 -48
  124. package/dist/utils/ui.d.ts +0 -14
  125. package/dist/utils/ui.js +0 -59
  126. package/scripts/.gitkeep +0 -0
  127. package/scripts/README-gurulu-agentic-install.md +0 -114
  128. package/scripts/README-gurulu-scan.md +0 -98
  129. package/scripts/audit-cli-scopes.mjs +0 -204
  130. package/scripts/backfill-tenant-id.mjs +0 -172
  131. package/scripts/backfill-tenant-links.ts +0 -252
  132. package/scripts/backup-clickhouse.sh +0 -27
  133. package/scripts/backup-postgres.sh +0 -19
  134. package/scripts/bootstrap-runtime-schema.mjs +0 -87
  135. package/scripts/bootstrap-stripe.mjs +0 -158
  136. package/scripts/gurulu-agentic-install.lib.cjs +0 -762
  137. package/scripts/gurulu-agentic-install.mjs +0 -623
  138. package/scripts/gurulu-scan.lib.cjs +0 -1509
  139. package/scripts/gurulu-scan.mjs +0 -91
  140. package/scripts/gurulu-verify-install.lib.cjs +0 -334
  141. package/scripts/gurulu-verify-install.mjs +0 -59
  142. package/scripts/init-ssl.sh +0 -26
  143. package/scripts/migrate-flow-graph-enums.sh +0 -86
  144. package/scripts/monitor-disk.sh +0 -24
  145. package/scripts/patches/astro.patch.cjs +0 -74
  146. package/scripts/patches/auto-instrument/ast-helper.cjs +0 -480
  147. package/scripts/patches/auto-instrument/astro.cjs +0 -273
  148. package/scripts/patches/auto-instrument/express.cjs +0 -383
  149. package/scripts/patches/auto-instrument/fastify.cjs +0 -262
  150. package/scripts/patches/auto-instrument/hono.cjs +0 -392
  151. package/scripts/patches/auto-instrument/index.cjs +0 -80
  152. package/scripts/patches/auto-instrument/nestjs.cjs +0 -286
  153. package/scripts/patches/auto-instrument/nextjs-app-router.cjs +0 -345
  154. package/scripts/patches/auto-instrument/nextjs-pages.cjs +0 -361
  155. package/scripts/patches/auto-instrument/remix.cjs +0 -168
  156. package/scripts/patches/auto-instrument/sdk-helper-map.cjs +0 -241
  157. package/scripts/patches/auto-instrument/singleton-helper.cjs +0 -193
  158. package/scripts/patches/auto-instrument/sveltekit.cjs +0 -161
  159. package/scripts/patches/auto-instrument/vite-react.cjs +0 -37
  160. package/scripts/patches/auto-instrument/vue.cjs +0 -196
  161. package/scripts/patches/express.patch.cjs +0 -99
  162. package/scripts/patches/fastify.patch.cjs +0 -108
  163. package/scripts/patches/index.cjs +0 -300
  164. package/scripts/patches/nestjs.patch.cjs +0 -112
  165. package/scripts/patches/nextjs-app-router.patch.cjs +0 -97
  166. package/scripts/patches/nextjs-pages.patch.cjs +0 -97
  167. package/scripts/patches/remix.patch.cjs +0 -75
  168. package/scripts/patches/sveltekit.patch.cjs +0 -72
  169. package/scripts/patches/vite-react.patch.cjs +0 -73
  170. package/scripts/patches/vue.patch.cjs +0 -82
  171. package/scripts/renew-ssl.sh +0 -14
  172. package/scripts/resolve-migration.sh +0 -23
  173. package/scripts/seed-cli-dev-keys.mjs +0 -130
  174. package/scripts/seed-test-data.mjs +0 -391
  175. package/scripts/spike-browserless.ts +0 -65
  176. package/scripts/tenant-pivot-consistency-check.mjs +0 -205
  177. package/scripts/tenant-pivot-phase-3-cleanup.lib.cjs +0 -258
  178. package/scripts/tenant-pivot-phase-3-cleanup.mjs +0 -98
  179. package/scripts/test-identity-resolution.ts +0 -804
  180. package/scripts/validate-gurulu-schemas.mjs +0 -79
@@ -1,444 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.detectFramework = detectFramework;
7
- exports.getSetupSnippet = getSetupSnippet;
8
- exports.getFrameworkDisplayName = getFrameworkDisplayName;
9
- const fs_1 = __importDefault(require("fs"));
10
- const path_1 = __importDefault(require("path"));
11
- function detectFramework(projectDir) {
12
- const pkgPath = path_1.default.join(projectDir, 'package.json');
13
- const hasPkgJson = fs_1.default.existsSync(pkgPath);
14
- // Read package.json early so we can dedupe iOS-vs-React-Native (RN repos
15
- // commonly host an `ios/MyApp.xcodeproj` and a top-level Package.swift in
16
- // monorepos — without the RN check first we'd return `ios-swift` and ship
17
- // the wrong SDK snippet).
18
- let deps = {};
19
- if (hasPkgJson) {
20
- try {
21
- const pkg = JSON.parse(fs_1.default.readFileSync(pkgPath, 'utf-8'));
22
- deps = { ...pkg.dependencies, ...pkg.devDependencies };
23
- }
24
- catch {
25
- /* malformed package.json — fall through to filesystem detection */
26
- }
27
- if (deps['react-native'])
28
- return 'react-native';
29
- }
30
- // Mobile framework detection (non-package.json based)
31
- if (fs_1.default.existsSync(path_1.default.join(projectDir, 'pubspec.yaml')))
32
- return 'flutter';
33
- const hasSwiftPkg = fs_1.default.existsSync(path_1.default.join(projectDir, 'Package.swift'));
34
- let hasXcodeProj = false;
35
- try {
36
- hasXcodeProj = fs_1.default
37
- .readdirSync(projectDir)
38
- .some((f) => f.endsWith('.xcodeproj') || f.endsWith('.xcworkspace'));
39
- }
40
- catch {
41
- /* unreadable dir — treat as no Xcode project */
42
- }
43
- if (hasSwiftPkg || hasXcodeProj)
44
- return 'ios-swift';
45
- if (!hasPkgJson) {
46
- // Android detection (no package.json means no RN false positive)
47
- if (fs_1.default.existsSync(path_1.default.join(projectDir, 'build.gradle.kts')) ||
48
- fs_1.default.existsSync(path_1.default.join(projectDir, 'build.gradle')) ||
49
- fs_1.default.existsSync(path_1.default.join(projectDir, 'app', 'build.gradle')) ||
50
- fs_1.default.existsSync(path_1.default.join(projectDir, 'app', 'build.gradle.kts'))) {
51
- return 'android-kotlin';
52
- }
53
- return 'html';
54
- }
55
- if (deps['next']) {
56
- // Check for app router
57
- if (fs_1.default.existsSync(path_1.default.join(projectDir, 'src', 'app')) || fs_1.default.existsSync(path_1.default.join(projectDir, 'app'))) {
58
- return 'nextjs-app';
59
- }
60
- return 'nextjs-pages';
61
- }
62
- if (deps['@nestjs/core'])
63
- return 'nestjs';
64
- if (deps['nuxt'])
65
- return 'nuxt3';
66
- if (deps['@sveltejs/kit'])
67
- return 'sveltekit';
68
- if (deps['svelte'])
69
- return 'svelte';
70
- if (deps['astro'])
71
- return 'astro';
72
- if (deps['vue'])
73
- return 'vue3';
74
- if (deps['@vitejs/plugin-react'])
75
- return 'react-vite';
76
- if (deps['react-scripts'])
77
- return 'react-cra';
78
- if (deps['fastify'])
79
- return 'fastify';
80
- if (deps['hono'])
81
- return 'hono';
82
- if (deps['express'])
83
- return 'express';
84
- return 'unknown';
85
- }
86
- function getSetupSnippet(framework, siteId, token) {
87
- switch (framework) {
88
- case 'nextjs-app':
89
- return {
90
- file: 'src/lib/gurulu.tsx',
91
- code: `'use client';
92
- import { useEffect } from 'react';
93
- import { usePathname, useSearchParams } from 'next/navigation';
94
-
95
- export function GuruluProvider() {
96
- const pathname = usePathname();
97
- const searchParams = useSearchParams();
98
-
99
- useEffect(() => {
100
- const script = document.createElement('script');
101
- script.src = 'https://cdn.gurulu.io/t.js';
102
- script.async = true;
103
- script.dataset.siteId = '${siteId}';
104
- script.dataset.token = '${token}';
105
- document.head.appendChild(script);
106
- return () => { document.head.removeChild(script); };
107
- }, []);
108
-
109
- useEffect(() => {
110
- if (typeof window !== 'undefined' && (window as any).gurulu) {
111
- (window as any).gurulu.track('pageview', {
112
- page_url: pathname + (searchParams?.toString() ? '?' + searchParams.toString() : ''),
113
- });
114
- }
115
- }, [pathname, searchParams]);
116
-
117
- return null;
118
- }`,
119
- instruction: 'Add <GuruluProvider /> inside <body> in your root layout.tsx',
120
- };
121
- case 'nextjs-pages':
122
- return {
123
- file: 'src/lib/gurulu.tsx',
124
- code: `import Script from 'next/script';
125
-
126
- export function GuruluScript() {
127
- return (
128
- <Script
129
- src="https://cdn.gurulu.io/t.js"
130
- data-site-id="${siteId}"
131
- data-token="${token}"
132
- strategy="afterInteractive"
133
- />
134
- );
135
- }`,
136
- instruction: 'Add <GuruluScript /> in your _app.tsx',
137
- };
138
- case 'react-vite':
139
- case 'react-cra':
140
- return {
141
- file: 'src/gurulu.ts',
142
- code: `// Gurulu.io Analytics
143
- export function initGurulu() {
144
- if (typeof document === 'undefined') return;
145
- const script = document.createElement('script');
146
- script.src = 'https://cdn.gurulu.io/t.js';
147
- script.async = true;
148
- script.dataset.siteId = '${siteId}';
149
- script.dataset.token = '${token}';
150
- document.head.appendChild(script);
151
- }`,
152
- instruction: 'Call initGurulu() in your main.tsx or index.tsx entry point',
153
- };
154
- case 'vue3':
155
- return {
156
- file: 'src/plugins/gurulu.ts',
157
- code: `// Gurulu.io Analytics Plugin
158
- import type { App } from 'vue';
159
-
160
- export const guruluPlugin = {
161
- install(app: App) {
162
- if (typeof document === 'undefined') return;
163
- const script = document.createElement('script');
164
- script.src = 'https://cdn.gurulu.io/t.js';
165
- script.async = true;
166
- script.dataset.siteId = '${siteId}';
167
- script.dataset.token = '${token}';
168
- document.head.appendChild(script);
169
- },
170
- };`,
171
- instruction: 'Add app.use(guruluPlugin) in your main.ts',
172
- };
173
- case 'nuxt3':
174
- return {
175
- file: 'plugins/gurulu.client.ts',
176
- code: `// Gurulu.io Analytics Plugin
177
- export default defineNuxtPlugin(() => {
178
- if (typeof document === 'undefined') return;
179
- const script = document.createElement('script');
180
- script.src = 'https://cdn.gurulu.io/t.js';
181
- script.async = true;
182
- script.dataset.siteId = '${siteId}';
183
- script.dataset.token = '${token}';
184
- document.head.appendChild(script);
185
- });`,
186
- instruction: 'Plugin auto-registered via plugins/ directory',
187
- };
188
- case 'svelte':
189
- return {
190
- file: 'src/lib/gurulu.ts',
191
- code: `// Gurulu.io Analytics
192
- import { onMount } from 'svelte';
193
-
194
- export function initGurulu() {
195
- onMount(() => {
196
- const script = document.createElement('script');
197
- script.src = 'https://cdn.gurulu.io/t.js';
198
- script.async = true;
199
- script.dataset.siteId = '${siteId}';
200
- script.dataset.token = '${token}';
201
- document.head.appendChild(script);
202
- });
203
- }`,
204
- instruction: 'Call initGurulu() in your root +layout.svelte or App.svelte',
205
- };
206
- case 'sveltekit':
207
- return {
208
- file: 'src/lib/gurulu.ts',
209
- code: `// Gurulu.io Analytics
210
- import { browser } from '$app/environment';
211
-
212
- export function initGurulu() {
213
- if (!browser) return;
214
- const script = document.createElement('script');
215
- script.src = 'https://cdn.gurulu.io/t.js';
216
- script.async = true;
217
- script.dataset.siteId = '${siteId}';
218
- script.dataset.token = '${token}';
219
- document.head.appendChild(script);
220
- }`,
221
- instruction: 'Call initGurulu() in your root +layout.svelte onMount',
222
- };
223
- case 'astro':
224
- return {
225
- file: 'src/components/Gurulu.astro',
226
- code: `---
227
- // Gurulu.io Analytics
228
- ---
229
- <script src="https://cdn.gurulu.io/t.js" data-site-id="${siteId}" data-token="${token}" async></script>`,
230
- instruction: 'Add <Gurulu /> in your Layout.astro <head>',
231
- };
232
- case 'express':
233
- return {
234
- file: 'src/gurulu.ts',
235
- code: `// Gurulu.io Server Analytics
236
- import type { Request, Response, NextFunction } from 'express';
237
-
238
- const SITE_ID = '${siteId}';
239
- const TOKEN = '${token}';
240
-
241
- export function guruluMiddleware(req: Request, res: Response, next: NextFunction) {
242
- // Track server-side pageview
243
- fetch('https://ingest.gurulu.io/api/events', {
244
- method: 'POST',
245
- headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + TOKEN },
246
- body: JSON.stringify({
247
- site_id: SITE_ID,
248
- event: 'pageview',
249
- url: req.originalUrl,
250
- referrer: req.headers.referer || '',
251
- user_agent: req.headers['user-agent'] || '',
252
- ip: req.ip,
253
- timestamp: new Date().toISOString(),
254
- }),
255
- }).catch(() => {});
256
- next();
257
- }`,
258
- instruction: 'Add app.use(guruluMiddleware) in your Express app',
259
- };
260
- case 'fastify':
261
- return {
262
- file: 'src/gurulu.ts',
263
- code: `// Gurulu.io Server Analytics — Fastify plugin
264
- import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
265
-
266
- const SITE_ID = '${siteId}';
267
- const TOKEN = '${token}';
268
-
269
- export async function guruluPlugin(fastify: FastifyInstance) {
270
- fastify.addHook('onRequest', async (req: FastifyRequest, _reply: FastifyReply) => {
271
- fetch('https://ingest.gurulu.io/api/events', {
272
- method: 'POST',
273
- headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + TOKEN },
274
- body: JSON.stringify({
275
- site_id: SITE_ID,
276
- event: 'pageview',
277
- url: req.url,
278
- referrer: (req.headers.referer as string) || '',
279
- user_agent: (req.headers['user-agent'] as string) || '',
280
- ip: req.ip,
281
- timestamp: new Date().toISOString(),
282
- }),
283
- }).catch(() => {});
284
- });
285
- }`,
286
- instruction: 'Register with fastify.register(guruluPlugin) in your Fastify app',
287
- };
288
- case 'hono':
289
- return {
290
- file: 'src/gurulu.ts',
291
- code: `// Gurulu.io Server Analytics — Hono middleware
292
- import type { MiddlewareHandler } from 'hono';
293
-
294
- const SITE_ID = '${siteId}';
295
- const TOKEN = '${token}';
296
-
297
- export const guruluMiddleware: MiddlewareHandler = async (c, next) => {
298
- fetch('https://ingest.gurulu.io/api/events', {
299
- method: 'POST',
300
- headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + TOKEN },
301
- body: JSON.stringify({
302
- site_id: SITE_ID,
303
- event: 'pageview',
304
- url: c.req.url,
305
- referrer: c.req.header('referer') || '',
306
- user_agent: c.req.header('user-agent') || '',
307
- timestamp: new Date().toISOString(),
308
- }),
309
- }).catch(() => {});
310
- await next();
311
- };`,
312
- instruction: 'Add app.use(guruluMiddleware) in your Hono app',
313
- };
314
- case 'nestjs':
315
- return {
316
- file: 'src/gurulu.middleware.ts',
317
- code: `// Gurulu.io Server Analytics Middleware
318
- import { Injectable, NestMiddleware } from '@nestjs/common';
319
- import { Request, Response, NextFunction } from 'express';
320
-
321
- const SITE_ID = '${siteId}';
322
- const TOKEN = '${token}';
323
-
324
- @Injectable()
325
- export class GuruluMiddleware implements NestMiddleware {
326
- use(req: Request, res: Response, next: NextFunction) {
327
- fetch('https://ingest.gurulu.io/api/events', {
328
- method: 'POST',
329
- headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + TOKEN },
330
- body: JSON.stringify({
331
- site_id: SITE_ID,
332
- event: 'pageview',
333
- url: req.originalUrl,
334
- referrer: req.headers.referer || '',
335
- user_agent: req.headers['user-agent'] || '',
336
- ip: req.ip,
337
- timestamp: new Date().toISOString(),
338
- }),
339
- }).catch(() => {});
340
- next();
341
- }
342
- }`,
343
- instruction: 'Apply GuruluMiddleware in your AppModule configure()',
344
- };
345
- case 'react-native':
346
- return {
347
- file: '',
348
- code: `// npm install @gurulu/react-native
349
- import Gurulu from '@gurulu/react-native';
350
-
351
- Gurulu.initialize({
352
- siteId: '${siteId}',
353
- token: '${token}',
354
- endpoint: 'https://ingest.gurulu.io/api/ingest/v1/collect',
355
- });`,
356
- instruction: 'Run "npm install @gurulu/react-native" and add initialization to your App entry point',
357
- };
358
- case 'ios-swift':
359
- return {
360
- file: '',
361
- code: `// Package.swift: add .package(url: "https://github.com/Preatan/gurulu-ios-sdk", from: "0.1.0")
362
- // AppDelegate.swift or @main App:
363
- import GuruluSDK
364
-
365
- GuruluSDK.shared.initialize(config: GuruluConfig(
366
- siteId: "${siteId}",
367
- token: "${token}",
368
- endpoint: URL(string: "https://ingest.gurulu.io/api/ingest/v1/collect")!
369
- ))`,
370
- instruction: 'Add the SPM dependency and initialize in your AppDelegate or @main App struct',
371
- };
372
- case 'android-kotlin':
373
- return {
374
- file: '',
375
- code: `// build.gradle.kts: implementation("com.github.Preatan:gurulu.io:android-sdk-0.1.0")
376
- // repositories: maven { url = uri("https://jitpack.io") }
377
- // Application.onCreate():
378
- import io.gurulu.sdk.GuruluSdk
379
- import io.gurulu.sdk.GuruluConfig
380
-
381
- GuruluSdk.initialize(GuruluConfig(
382
- siteId = "${siteId}",
383
- token = "${token}",
384
- endpoint = "https://ingest.gurulu.io/api/ingest/v1/collect"
385
- ))`,
386
- instruction: 'Add JitPack repository and dependency, then initialize in your Application.onCreate()',
387
- };
388
- case 'flutter':
389
- return {
390
- file: '',
391
- code: `// pubspec.yaml: gurulu_flutter: ^0.1.0
392
- import 'package:gurulu_flutter/gurulu_flutter.dart';
393
-
394
- await GuruluFlutter.initialize(config: {
395
- 'siteId': '${siteId}',
396
- 'token': '${token}',
397
- 'endpoint': 'https://ingest.gurulu.io/api/ingest/v1/collect',
398
- });`,
399
- instruction: 'Add gurulu_flutter to pubspec.yaml and initialize in your main() function',
400
- };
401
- case 'html':
402
- return {
403
- file: '',
404
- code: `<script src="https://cdn.gurulu.io/t.js" data-site-id="${siteId}" data-token="${token}" async></script>`,
405
- instruction: 'Add this script tag before </head> in your HTML',
406
- };
407
- default:
408
- return {
409
- file: 'src/gurulu.ts',
410
- code: `// Gurulu.io Analytics
411
- const script = document.createElement('script');
412
- script.src = 'https://cdn.gurulu.io/t.js';
413
- script.async = true;
414
- script.dataset.siteId = '${siteId}';
415
- script.dataset.token = '${token}';
416
- document.head.appendChild(script);`,
417
- instruction: 'Import this file in your app entry point',
418
- };
419
- }
420
- }
421
- function getFrameworkDisplayName(fw) {
422
- const names = {
423
- 'nextjs-app': 'Next.js (App Router)',
424
- 'nextjs-pages': 'Next.js (Pages Router)',
425
- 'react-vite': 'React (Vite)',
426
- 'react-cra': 'React (CRA)',
427
- 'vue3': 'Vue 3',
428
- 'nuxt3': 'Nuxt 3',
429
- 'svelte': 'Svelte',
430
- 'sveltekit': 'SvelteKit',
431
- 'astro': 'Astro',
432
- 'express': 'Express',
433
- 'fastify': 'Fastify',
434
- 'hono': 'Hono',
435
- 'nestjs': 'NestJS',
436
- 'html': 'HTML',
437
- 'react-native': 'React Native',
438
- 'ios-swift': 'iOS (Swift)',
439
- 'android-kotlin': 'Android (Kotlin)',
440
- 'flutter': 'Flutter',
441
- 'unknown': 'Unknown',
442
- };
443
- return names[fw];
444
- }
@@ -1,99 +0,0 @@
1
- /**
2
- * Phase 18.6 — CLI install-time intent proposal rendering + interaction.
3
- *
4
- * Pure UI logic (plus a small interactive loop) that turns an `InstallIntent`
5
- * payload into a human-readable proposal and lets the user toggle individual
6
- * events/funnels before sending the accepted subset to the backend. This file
7
- * has NO hard limit on event/funnel count — a full iGaming intent with 20
8
- * events is rendered in full.
9
- *
10
- * Testability: the render function returns a plain string so snapshot-style
11
- * tests can assert structure. The interactive runner accepts injected I/O so
12
- * tests can drive it without real stdin/stdout.
13
- */
14
- export type Confidence = 'high' | 'medium' | 'low';
15
- export interface ProposedEvent {
16
- name: string;
17
- category: 'acquisition' | 'activation' | 'retention' | 'revenue' | 'referral' | 'compliance' | 'support' | 'engagement';
18
- source: {
19
- route?: string;
20
- mutation?: string;
21
- inferred?: boolean;
22
- inferredFrom?: string;
23
- };
24
- properties: string[];
25
- confidence: Confidence;
26
- reasoning: string;
27
- }
28
- export interface ProposedFunnel {
29
- name: string;
30
- category: 'activation' | 'monetization' | 'retention' | 'compliance' | 'engagement';
31
- steps: string[];
32
- reasoning: string;
33
- }
34
- export interface InstallIntent {
35
- vertical: string;
36
- confidence: Confidence;
37
- reasoning: string;
38
- alternativeVerticals: Array<{
39
- name: string;
40
- confidence: Confidence;
41
- note?: string;
42
- }>;
43
- events: ProposedEvent[];
44
- funnels: ProposedFunnel[];
45
- analyzerMode: 'llm' | 'heuristic';
46
- modelVersion?: string;
47
- promptVersion?: string;
48
- }
49
- export interface ProposalState {
50
- intent: InstallIntent;
51
- eventSelected: boolean[];
52
- funnelSelected: boolean[];
53
- }
54
- export declare function initProposalState(intent: InstallIntent): ProposalState;
55
- /**
56
- * Render the proposal to a plain string (TTY colour escapes applied by the
57
- * caller if `colorize` is true). No truncation — every event/funnel is shown.
58
- */
59
- export declare function renderProposal(state: ProposalState, opts?: {
60
- colorize?: boolean;
61
- }): string;
62
- export interface ApplyCommandResult {
63
- state: ProposalState;
64
- done: boolean;
65
- quit: boolean;
66
- }
67
- /**
68
- * Apply a single user command to the proposal state. Exported so tests can
69
- * exercise the state machine directly without any I/O.
70
- */
71
- export declare function applyCommand(state: ProposalState, raw: string): ApplyCommandResult;
72
- export interface ProposalIo {
73
- print: (line: string) => void;
74
- prompt: (q: string) => Promise<string>;
75
- isPiped: boolean;
76
- }
77
- export interface ProposalDecision {
78
- accepted: {
79
- events: ProposedEvent[];
80
- funnels: ProposedFunnel[];
81
- };
82
- rejected: {
83
- events: ProposedEvent[];
84
- funnels: ProposedFunnel[];
85
- };
86
- quit: boolean;
87
- }
88
- export declare function splitDecision(state: ProposalState): ProposalDecision;
89
- export interface RunProposalOpts {
90
- intent: InstallIntent;
91
- io: ProposalIo;
92
- /** If true (piped / --yes / CI), skip interactive loop and accept everything. */
93
- nonInteractive?: boolean;
94
- }
95
- /**
96
- * Drive the interactive proposal loop. Returns the accepted + rejected split
97
- * plus a `quit` flag the caller uses to decide whether to continue the install.
98
- */
99
- export declare function runProposal(opts: RunProposalOpts): Promise<ProposalDecision>;