@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,360 +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.doctorCommand = doctorCommand;
7
- const fs_1 = __importDefault(require("fs"));
8
- const path_1 = __importDefault(require("path"));
9
- const config_1 = require("../config");
10
- const api_client_1 = require("../api-client");
11
- const detect_1 = require("../frameworks/detect");
12
- const ui_1 = require("../utils/ui");
13
- async function doctorCommand(args) {
14
- let profile;
15
- try {
16
- profile = await (0, config_1.loadActiveProfile)({ profile: args.profile });
17
- }
18
- catch {
19
- profile = null;
20
- }
21
- const siteId = args.site;
22
- const projectDir = process.cwd();
23
- const checks = [];
24
- // 1. Framework detection
25
- const framework = (0, detect_1.detectFramework)(projectDir);
26
- // If the user explicitly passed --site, the cwd-derived checks should not
27
- // imply that the *production site* is broken — they're informational only.
28
- const isLocalProjectDetected = framework !== 'unknown';
29
- checks.push({
30
- name: 'Framework Detection',
31
- status: framework !== 'unknown' ? 'pass' : 'warn',
32
- message: framework !== 'unknown'
33
- ? `Detected ${(0, detect_1.getFrameworkDisplayName)(framework)}`
34
- : 'Could not detect framework',
35
- fix: framework === 'unknown' ? 'Run "gurulu init --framework <name>" to specify manually' : undefined,
36
- section: 'local',
37
- });
38
- // 2. SDK installed
39
- const pkgPath = path_1.default.join(projectDir, 'package.json');
40
- let hasWebSDK = false;
41
- let hasNodeSDK = false;
42
- let hasReactNativeSDK = false;
43
- if (fs_1.default.existsSync(pkgPath)) {
44
- const pkg = JSON.parse(fs_1.default.readFileSync(pkgPath, 'utf-8'));
45
- const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
46
- hasWebSDK = !!allDeps['@gurulu/web-sdk'];
47
- hasNodeSDK = !!allDeps['@gurulu/node'];
48
- hasReactNativeSDK = !!allDeps['@gurulu/react-native'];
49
- }
50
- // Mobile SDK detection
51
- let hasFlutterSDK = false;
52
- const pubspecPath = path_1.default.join(projectDir, 'pubspec.yaml');
53
- if (fs_1.default.existsSync(pubspecPath)) {
54
- const pubspec = fs_1.default.readFileSync(pubspecPath, 'utf-8');
55
- hasFlutterSDK = pubspec.includes('gurulu_flutter');
56
- }
57
- let hasIOSSDK = false;
58
- const swiftPkgPath = path_1.default.join(projectDir, 'Package.swift');
59
- if (fs_1.default.existsSync(swiftPkgPath)) {
60
- const swiftPkg = fs_1.default.readFileSync(swiftPkgPath, 'utf-8');
61
- hasIOSSDK = swiftPkg.includes('gurulu-ios-sdk');
62
- }
63
- let hasAndroidSDK = false;
64
- const gradleKtsPath = path_1.default.join(projectDir, 'build.gradle.kts');
65
- const gradlePath = path_1.default.join(projectDir, 'build.gradle');
66
- for (const gPath of [gradleKtsPath, gradlePath]) {
67
- if (fs_1.default.existsSync(gPath)) {
68
- const gradle = fs_1.default.readFileSync(gPath, 'utf-8');
69
- if (gradle.includes('gurulu') || gradle.includes('jitpack')) {
70
- hasAndroidSDK = true;
71
- break;
72
- }
73
- }
74
- }
75
- const hasMobileSDK = hasReactNativeSDK || hasFlutterSDK || hasIOSSDK || hasAndroidSDK;
76
- const setupFiles = findSetupFiles(projectDir);
77
- const hasSetup = setupFiles.length > 0 || hasWebSDK || hasMobileSDK;
78
- const sdkLabel = hasWebSDK ? 'Web SDK installed via npm'
79
- : hasReactNativeSDK ? 'React Native SDK installed via npm'
80
- : hasFlutterSDK ? 'Flutter SDK found in pubspec.yaml'
81
- : hasIOSSDK ? 'iOS SDK found in Package.swift'
82
- : hasAndroidSDK ? 'Android SDK found in build.gradle'
83
- : setupFiles.length > 0 ? `Setup file found: ${setupFiles[0]}`
84
- : 'No client SDK detected';
85
- // When --site was passed but cwd is not a Gurulu project, downgrade local
86
- // SDK failures to "skip" so they don't masquerade as production-site issues.
87
- const localChecksAreInformational = !!siteId && !isLocalProjectDetected;
88
- checks.push({
89
- name: 'Client SDK',
90
- status: hasSetup ? 'pass' : localChecksAreInformational ? 'skip' : 'fail',
91
- message: hasSetup
92
- ? sdkLabel
93
- : localChecksAreInformational
94
- ? 'No client SDK detected in this directory (informational — site checks below)'
95
- : sdkLabel,
96
- fix: !hasSetup && !localChecksAreInformational
97
- ? 'Run "gurulu init" to set up analytics'
98
- : undefined,
99
- section: 'local',
100
- });
101
- // 3. Server SDK
102
- checks.push({
103
- name: 'Server SDK',
104
- status: hasNodeSDK ? 'pass' : localChecksAreInformational ? 'skip' : 'warn',
105
- message: hasNodeSDK
106
- ? '@gurulu/node installed'
107
- : localChecksAreInformational
108
- ? 'Server SDK check skipped (no local project detected)'
109
- : 'Server SDK not installed (optional)',
110
- fix: !hasNodeSDK && !localChecksAreInformational
111
- ? 'Run "gurulu add-server" for server-side tracking'
112
- : undefined,
113
- section: 'local',
114
- });
115
- // 4. Site ID configured
116
- checks.push({
117
- name: 'Site ID',
118
- status: siteId ? 'pass' : 'fail',
119
- message: siteId ? `Site ID: ${siteId}` : 'No site ID configured',
120
- fix: !siteId ? 'Run "gurulu login" to authenticate and select a site' : undefined,
121
- });
122
- // 5. Authentication
123
- checks.push({
124
- name: 'Authentication',
125
- status: profile ? 'pass' : 'fail',
126
- message: profile ? 'Authenticated' : 'Not authenticated',
127
- fix: !profile ? 'Run "gurulu login" with your Personal API Key' : undefined,
128
- });
129
- // 6. Token validation (if we have a profile and siteId)
130
- if (profile && siteId) {
131
- try {
132
- const data = await (0, api_client_1.cliApiJson)(`/api/cli/sites/${encodeURIComponent(siteId)}`, { preloadedProfile: profile });
133
- const hasToken = !!data.site?.publishableKey;
134
- checks.push({
135
- name: 'Token Valid',
136
- status: hasToken ? 'pass' : 'fail',
137
- message: hasToken ? 'Site token is valid' : 'Token could not be verified',
138
- });
139
- }
140
- catch (err) {
141
- checks.push({
142
- name: 'Token Valid',
143
- status: 'fail',
144
- message: `Token validation failed: ${err.message}`,
145
- fix: 'Check your API key and site ID, or run "gurulu login" again',
146
- });
147
- }
148
- }
149
- else {
150
- checks.push({
151
- name: 'Token Valid',
152
- status: 'skip',
153
- message: 'Skipped (authentication required)',
154
- });
155
- }
156
- // 7. Ingest connection + 8. Events flowing — via /api/cli/sites/:id/health
157
- if (profile && siteId) {
158
- try {
159
- const health = await (0, api_client_1.cliApiJson)(`/api/cli/sites/${encodeURIComponent(siteId)}/health`, {
160
- preloadedProfile: profile,
161
- });
162
- checks.push({
163
- name: 'Ingest Connection',
164
- status: health.checks.ingest === 'ok' ? 'pass' : 'fail',
165
- message: health.checks.ingest === 'ok'
166
- ? 'Ingest endpoint is healthy'
167
- : 'Ingest check failed — site may be archived or missing a valid token',
168
- fix: health.checks.ingest !== 'ok'
169
- ? 'Verify site exists and has a valid publishable key'
170
- : undefined,
171
- });
172
- const chOk = health.checks.clickhouse === 'ok';
173
- const pgOk = health.checks.postgres === 'ok';
174
- const allOk = chOk && pgOk;
175
- checks.push({
176
- name: 'Events Flowing',
177
- status: allOk ? 'pass' : chOk || pgOk ? 'warn' : 'fail',
178
- message: allOk
179
- ? 'ClickHouse and Postgres are reachable'
180
- : `Backend health: postgres=${health.checks.postgres}, clickhouse=${health.checks.clickhouse}`,
181
- fix: !allOk ? 'Check server logs or contact support' : undefined,
182
- });
183
- }
184
- catch (err) {
185
- checks.push({
186
- name: 'Ingest Connection',
187
- status: 'fail',
188
- message: `Health check failed: ${err.message}`,
189
- fix: 'Check your API key and site ID, or run "gurulu login" again',
190
- });
191
- checks.push({
192
- name: 'Events Flowing',
193
- status: 'skip',
194
- message: 'Skipped (health check unavailable)',
195
- });
196
- }
197
- }
198
- else if (profile && !siteId) {
199
- // Try to resolve a site automatically
200
- try {
201
- const sitesData = await (0, api_client_1.cliApiJson)('/api/cli/sites', { preloadedProfile: profile });
202
- if (sitesData.sites?.length) {
203
- const resolvedId = sitesData.sites[0].id;
204
- const health = await (0, api_client_1.cliApiJson)(`/api/cli/sites/${encodeURIComponent(resolvedId)}/health`, {
205
- preloadedProfile: profile,
206
- });
207
- checks.push({
208
- name: 'Ingest Connection',
209
- status: health.checks.ingest === 'ok' ? 'pass' : 'fail',
210
- message: health.checks.ingest === 'ok'
211
- ? `Ingest healthy (auto-resolved site ${resolvedId})`
212
- : 'Ingest check failed',
213
- fix: health.checks.ingest !== 'ok'
214
- ? 'Verify site exists and has a valid publishable key'
215
- : undefined,
216
- });
217
- const chOk = health.checks.clickhouse === 'ok';
218
- const pgOk = health.checks.postgres === 'ok';
219
- const allOk = chOk && pgOk;
220
- checks.push({
221
- name: 'Events Flowing',
222
- status: allOk ? 'pass' : chOk || pgOk ? 'warn' : 'fail',
223
- message: allOk
224
- ? 'ClickHouse and Postgres are reachable'
225
- : `Backend health: postgres=${health.checks.postgres}, clickhouse=${health.checks.clickhouse}`,
226
- fix: !allOk ? 'Check server logs or contact support' : undefined,
227
- });
228
- }
229
- else {
230
- checks.push({
231
- name: 'Ingest Connection',
232
- status: 'skip',
233
- message: 'No sites found — create one with "gurulu init"',
234
- });
235
- checks.push({
236
- name: 'Events Flowing',
237
- status: 'skip',
238
- message: 'Skipped (no sites)',
239
- });
240
- }
241
- }
242
- catch {
243
- checks.push({
244
- name: 'Ingest Connection',
245
- status: 'skip',
246
- message: 'Could not resolve site automatically',
247
- fix: 'Pass --site <id> or run "gurulu init"',
248
- });
249
- checks.push({
250
- name: 'Events Flowing',
251
- status: 'skip',
252
- message: 'Skipped (no site resolved)',
253
- });
254
- }
255
- }
256
- else {
257
- checks.push({
258
- name: 'Ingest Connection',
259
- status: 'skip',
260
- message: 'Skipped (authentication required)',
261
- });
262
- checks.push({
263
- name: 'Events Flowing',
264
- status: 'skip',
265
- message: 'Skipped (authentication required)',
266
- });
267
- }
268
- // 9. Env file check
269
- const envFiles = ['.env.local', '.env', '.env.development'];
270
- let envHasSiteId = false;
271
- for (const envFile of envFiles) {
272
- const envPath = path_1.default.join(projectDir, envFile);
273
- if (fs_1.default.existsSync(envPath)) {
274
- const content = fs_1.default.readFileSync(envPath, 'utf-8');
275
- if (content.includes('GURULU_SITE_ID')) {
276
- envHasSiteId = true;
277
- break;
278
- }
279
- }
280
- }
281
- if (framework !== 'html' && framework !== 'unknown') {
282
- checks.push({
283
- name: 'Env Config',
284
- status: envHasSiteId ? 'pass' : 'warn',
285
- message: envHasSiteId ? 'Site ID found in env file' : 'No GURULU_SITE_ID in env files',
286
- fix: !envHasSiteId ? 'Run "gurulu init" to auto-configure .env.local' : undefined,
287
- section: 'local',
288
- });
289
- }
290
- // Output
291
- if (args.json) {
292
- console.log(JSON.stringify({ framework, checks }, null, 2));
293
- return;
294
- }
295
- (0, ui_1.banner)();
296
- console.log((0, ui_1.bold)(' Diagnostics'));
297
- console.log('');
298
- const icons = {
299
- pass: (0, ui_1.green)('\u2713'),
300
- fail: (0, ui_1.red)('\u2717'),
301
- warn: (0, ui_1.yellow)('\u26A0'),
302
- skip: (0, ui_1.dim)('-'),
303
- };
304
- let failCount = 0;
305
- let warnCount = 0;
306
- const localChecks = checks.filter((c) => c.section === 'local');
307
- const siteChecks = checks.filter((c) => c.section !== 'local');
308
- const printGroup = (title, items, note) => {
309
- if (items.length === 0)
310
- return;
311
- console.log(` ${(0, ui_1.bold)(title)}`);
312
- if (note)
313
- console.log(` ${(0, ui_1.dim)(note)}`);
314
- for (const check of items) {
315
- const icon = icons[check.status];
316
- console.log(` ${icon} ${(0, ui_1.bold)(check.name)}: ${check.message}`);
317
- if (check.fix) {
318
- console.log(` ${(0, ui_1.dim)('\u2192')} ${(0, ui_1.dim)(check.fix)}`);
319
- }
320
- if (check.status === 'fail')
321
- failCount++;
322
- if (check.status === 'warn')
323
- warnCount++;
324
- }
325
- console.log('');
326
- };
327
- if (localChecks.length > 0) {
328
- const localNote = siteId && !isLocalProjectDetected
329
- ? `(Local project not detected \u2014 running site-only checks for ${siteId}.)`
330
- : undefined;
331
- printGroup('Local Project', localChecks, localNote);
332
- }
333
- if (siteChecks.length > 0) {
334
- const siteTitle = siteId ? `Site (${siteId})` : 'Site';
335
- printGroup(siteTitle, siteChecks);
336
- }
337
- console.log('');
338
- if (failCount === 0 && warnCount === 0) {
339
- (0, ui_1.success)('All checks passed! Your setup looks good.');
340
- }
341
- else if (failCount === 0) {
342
- (0, ui_1.info)(`${warnCount} warning(s), but no critical issues.`);
343
- }
344
- else {
345
- (0, ui_1.error)(`${failCount} issue(s) found. Fix them to get analytics working.`);
346
- }
347
- console.log('');
348
- }
349
- function findSetupFiles(projectDir) {
350
- const candidates = [
351
- 'src/lib/gurulu.tsx',
352
- 'src/lib/gurulu.ts',
353
- 'src/gurulu.ts',
354
- 'src/plugins/gurulu.ts',
355
- 'plugins/gurulu.client.ts',
356
- 'src/components/Gurulu.astro',
357
- 'src/gurulu.middleware.ts',
358
- ];
359
- return candidates.filter(f => fs_1.default.existsSync(path_1.default.join(projectDir, f)));
360
- }
@@ -1,27 +0,0 @@
1
- /**
2
- * Sprint E SE-B — `gurulu errors list|detail|resolve|mute`.
3
- *
4
- * Mirror of MCP `gurulu.errors.list` / `.detail` plus two new write tools
5
- * (`.resolve`, `.mute`). Hits new `/api/cli/errors/*` proxy endpoints which
6
- * use CLI-auth instead of the session-auth used by `/api/analytics/error-groups`.
7
- *
8
- * Note: `gurulu errors upload-sourcemap` and `upload-native-symbols` are
9
- * documented aliases of `gurulu sourcemap upload [--platform=...]` — see
10
- * `commands/sourcemap.ts`.
11
- */
12
- export interface ErrorsArgs {
13
- action?: string;
14
- site?: string;
15
- fingerprint?: string;
16
- level?: string;
17
- resolved?: string;
18
- environment?: string;
19
- releaseId?: string;
20
- limit?: number;
21
- duration?: string;
22
- format?: string;
23
- json?: boolean;
24
- yes?: boolean;
25
- profile?: string;
26
- }
27
- export declare function errorsCommand(args: ErrorsArgs): Promise<void>;
@@ -1,121 +0,0 @@
1
- "use strict";
2
- /**
3
- * Sprint E SE-B — `gurulu errors list|detail|resolve|mute`.
4
- *
5
- * Mirror of MCP `gurulu.errors.list` / `.detail` plus two new write tools
6
- * (`.resolve`, `.mute`). Hits new `/api/cli/errors/*` proxy endpoints which
7
- * use CLI-auth instead of the session-auth used by `/api/analytics/error-groups`.
8
- *
9
- * Note: `gurulu errors upload-sourcemap` and `upload-native-symbols` are
10
- * documented aliases of `gurulu sourcemap upload [--platform=...]` — see
11
- * `commands/sourcemap.ts`.
12
- */
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.errorsCommand = errorsCommand;
15
- const api_client_1 = require("../api-client");
16
- const ui_1 = require("../utils/ui");
17
- const confirm_1 = require("../utils/confirm");
18
- async function errorsCommand(args) {
19
- const action = args.action || '';
20
- switch (action) {
21
- case 'list':
22
- return listCmd(args);
23
- case 'detail':
24
- return detailCmd(args);
25
- case 'resolve':
26
- return resolveCmd(args);
27
- case 'mute':
28
- return muteCmd(args);
29
- case 'upload-sourcemap':
30
- case 'upload-native-symbols':
31
- (0, ui_1.info)('Use `gurulu sourcemap upload [--platform=ios|android|web|server] ...` — these names are aliases.');
32
- return;
33
- default:
34
- (0, ui_1.error)(`Unknown errors action: ${action}`);
35
- (0, ui_1.info)('Usage: gurulu errors [list|detail|resolve|mute] --site=<id> [--fingerprint=<hash>] ...');
36
- process.exit(1);
37
- }
38
- }
39
- async function listCmd(args) {
40
- if (!args.site) {
41
- (0, ui_1.error)('Usage: gurulu errors list --site=<id> [--level=error|warning] [--resolved=false] [--limit=20]');
42
- process.exit(1);
43
- }
44
- const usp = new URLSearchParams();
45
- usp.set('site', args.site);
46
- if (args.level)
47
- usp.set('level', args.level);
48
- if (args.resolved !== undefined)
49
- usp.set('resolved', args.resolved);
50
- if (args.environment)
51
- usp.set('environment', args.environment);
52
- if (args.releaseId)
53
- usp.set('releaseId', args.releaseId);
54
- if (args.limit)
55
- usp.set('limit', String(args.limit));
56
- const body = await (0, api_client_1.cliApiJson)(`/api/cli/errors?${usp.toString()}`, {
57
- profile: args.profile,
58
- });
59
- if (args.format === 'table') {
60
- const rows = body.groups || [];
61
- process.stdout.write(['FINGERPRINT', 'COUNT', 'LEVEL', 'STATUS', 'TITLE'].join('\t') + '\n');
62
- for (const g of rows) {
63
- process.stdout.write([
64
- (g.fingerprint || '').slice(0, 16),
65
- g.count ?? 0,
66
- g.level ?? '-',
67
- g.status ?? 'unresolved',
68
- String(g.title || '-').slice(0, 80),
69
- ].join('\t') + '\n');
70
- }
71
- return;
72
- }
73
- process.stdout.write(JSON.stringify(body, null, 2) + '\n');
74
- }
75
- async function detailCmd(args) {
76
- if (!args.site || !args.fingerprint) {
77
- (0, ui_1.error)('Usage: gurulu errors detail --site=<id> --fingerprint=<hash>');
78
- process.exit(1);
79
- }
80
- const path = `/api/cli/errors/${encodeURIComponent(args.fingerprint)}?site=${encodeURIComponent(args.site)}`;
81
- const body = await (0, api_client_1.cliApiJson)(path, { profile: args.profile });
82
- process.stdout.write(JSON.stringify(body, null, 2) + '\n');
83
- }
84
- async function resolveCmd(args) {
85
- if (!args.site || !args.fingerprint) {
86
- (0, ui_1.error)('Usage: gurulu errors resolve --site=<id> --fingerprint=<hash>');
87
- process.exit(1);
88
- }
89
- const ok = await (0, confirm_1.promptConfirm)(`Mark error ${args.fingerprint.slice(0, 12)} as resolved?`, { yes: args.yes, defaultYes: true });
90
- if (!ok) {
91
- (0, ui_1.info)('Aborted.');
92
- return;
93
- }
94
- const body = await (0, api_client_1.cliApiJson)(`/api/cli/errors/${encodeURIComponent(args.fingerprint)}/resolve`, {
95
- profile: args.profile,
96
- method: 'POST',
97
- json: { siteId: args.site },
98
- });
99
- if (args.json) {
100
- process.stdout.write(JSON.stringify(body, null, 2) + '\n');
101
- return;
102
- }
103
- (0, ui_1.success)(`Resolved ${args.fingerprint.slice(0, 12)}.`);
104
- }
105
- async function muteCmd(args) {
106
- if (!args.site || !args.fingerprint) {
107
- (0, ui_1.error)('Usage: gurulu errors mute --site=<id> --fingerprint=<hash> [--duration=24h]');
108
- process.exit(1);
109
- }
110
- const duration = args.duration || '24h';
111
- const body = await (0, api_client_1.cliApiJson)(`/api/cli/errors/${encodeURIComponent(args.fingerprint)}/mute`, {
112
- profile: args.profile,
113
- method: 'POST',
114
- json: { siteId: args.site, duration },
115
- });
116
- if (args.json) {
117
- process.stdout.write(JSON.stringify(body, null, 2) + '\n');
118
- return;
119
- }
120
- (0, ui_1.success)(`Muted ${args.fingerprint.slice(0, 12)} for ${duration}.`);
121
- }
@@ -1,33 +0,0 @@
1
- /**
2
- * Phase 19.5 W2 B1 — `gurulu events list` / `gurulu events tail`.
3
- *
4
- * Replaces the legacy Phase 10 `events` command (which talked to a
5
- * now-defunct credential store) with CLI-bearer-auth subcommands that hit
6
- * `/api/cli/events` (list) and `/api/cli/events/tail` (SSE stream).
7
- *
8
- * All subcommands support `--json` for scripting + agent parsing.
9
- */
10
- import { loadActiveProfile } from '../config';
11
- export interface EventsArgs {
12
- action?: string;
13
- site?: string;
14
- eventName?: string;
15
- since?: string;
16
- filter?: string;
17
- limit?: number;
18
- json?: boolean;
19
- profile?: string;
20
- displayName?: string;
21
- description?: string;
22
- category?: string;
23
- properties?: string;
24
- event?: string;
25
- vertical?: string;
26
- }
27
- export declare function eventsCommand(args: EventsArgs): Promise<void>;
28
- export declare function legacyEventsCommand(args: {
29
- site?: string;
30
- json?: boolean;
31
- profile?: string;
32
- }): Promise<void>;
33
- export declare const _loadActiveProfile: typeof loadActiveProfile;