@gurulu/cli 0.4.7 → 1.0.1

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 (190) 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 +25751 -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 +33 -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 +25326 -876
  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/dist/lib/detect.d.ts +27 -0
  28. package/dist/lib/detect.d.ts.map +1 -0
  29. package/dist/lib/detect.js +106 -0
  30. package/dist/lib/exec-install.d.ts +21 -0
  31. package/dist/lib/exec-install.d.ts.map +1 -0
  32. package/dist/lib/install-plan.d.ts +25 -0
  33. package/dist/lib/install-plan.d.ts.map +1 -0
  34. package/dist/lib/install-plan.js +161 -0
  35. package/package.json +51 -20
  36. package/bin/gurulu.js +0 -2
  37. package/dist/api-client.d.ts +0 -33
  38. package/dist/api-client.js +0 -175
  39. package/dist/commands/add-server.d.ts +0 -9
  40. package/dist/commands/add-server.js +0 -162
  41. package/dist/commands/alerts.d.ts +0 -27
  42. package/dist/commands/alerts.js +0 -309
  43. package/dist/commands/api-keys.d.ts +0 -20
  44. package/dist/commands/api-keys.js +0 -130
  45. package/dist/commands/attribution.d.ts +0 -22
  46. package/dist/commands/attribution.js +0 -111
  47. package/dist/commands/audiences.d.ts +0 -23
  48. package/dist/commands/audiences.js +0 -243
  49. package/dist/commands/audit.d.ts +0 -20
  50. package/dist/commands/audit.js +0 -130
  51. package/dist/commands/auth.js +0 -249
  52. package/dist/commands/chat.d.ts +0 -19
  53. package/dist/commands/chat.js +0 -118
  54. package/dist/commands/config.d.ts +0 -10
  55. package/dist/commands/config.js +0 -92
  56. package/dist/commands/consent.d.ts +0 -27
  57. package/dist/commands/consent.js +0 -233
  58. package/dist/commands/conversion-paths.d.ts +0 -19
  59. package/dist/commands/conversion-paths.js +0 -55
  60. package/dist/commands/db.d.ts +0 -25
  61. package/dist/commands/db.js +0 -330
  62. package/dist/commands/destinations.d.ts +0 -20
  63. package/dist/commands/destinations.js +0 -191
  64. package/dist/commands/doctor.js +0 -360
  65. package/dist/commands/errors.d.ts +0 -27
  66. package/dist/commands/errors.js +0 -121
  67. package/dist/commands/events.d.ts +0 -33
  68. package/dist/commands/events.js +0 -371
  69. package/dist/commands/experiments.d.ts +0 -22
  70. package/dist/commands/experiments.js +0 -264
  71. package/dist/commands/funnels.d.ts +0 -17
  72. package/dist/commands/funnels.js +0 -203
  73. package/dist/commands/goals.d.ts +0 -18
  74. package/dist/commands/goals.js +0 -214
  75. package/dist/commands/heatmap.d.ts +0 -27
  76. package/dist/commands/heatmap.js +0 -112
  77. package/dist/commands/identity.d.ts +0 -29
  78. package/dist/commands/identity.js +0 -328
  79. package/dist/commands/init.js +0 -215
  80. package/dist/commands/insights.d.ts +0 -10
  81. package/dist/commands/insights.js +0 -77
  82. package/dist/commands/install.d.ts +0 -259
  83. package/dist/commands/install.js +0 -1590
  84. package/dist/commands/login.d.ts +0 -20
  85. package/dist/commands/login.js +0 -170
  86. package/dist/commands/logout.d.ts +0 -10
  87. package/dist/commands/logout.js +0 -41
  88. package/dist/commands/playground.d.ts +0 -11
  89. package/dist/commands/playground.js +0 -47
  90. package/dist/commands/releases.d.ts +0 -17
  91. package/dist/commands/releases.js +0 -54
  92. package/dist/commands/replay.d.ts +0 -18
  93. package/dist/commands/replay.js +0 -64
  94. package/dist/commands/secrets.d.ts +0 -19
  95. package/dist/commands/secrets.js +0 -145
  96. package/dist/commands/setup.d.ts +0 -21
  97. package/dist/commands/setup.js +0 -67
  98. package/dist/commands/sites.d.ts +0 -18
  99. package/dist/commands/sites.js +0 -139
  100. package/dist/commands/skad.d.ts +0 -18
  101. package/dist/commands/skad.js +0 -53
  102. package/dist/commands/sourcemap.d.ts +0 -33
  103. package/dist/commands/sourcemap.js +0 -204
  104. package/dist/commands/status.d.ts +0 -7
  105. package/dist/commands/status.js +0 -136
  106. package/dist/commands/upgrade.d.ts +0 -21
  107. package/dist/commands/upgrade.js +0 -183
  108. package/dist/commands/warehouse.d.ts +0 -20
  109. package/dist/commands/warehouse.js +0 -65
  110. package/dist/commands/warehouses.d.ts +0 -17
  111. package/dist/commands/warehouses.js +0 -182
  112. package/dist/commands/watch.d.ts +0 -45
  113. package/dist/commands/watch.js +0 -258
  114. package/dist/commands/whoami.d.ts +0 -9
  115. package/dist/commands/whoami.js +0 -50
  116. package/dist/config.d.ts +0 -75
  117. package/dist/config.js +0 -329
  118. package/dist/frameworks/detect.d.ts +0 -8
  119. package/dist/frameworks/detect.js +0 -458
  120. package/dist/install-intent-proposal.d.ts +0 -99
  121. package/dist/install-intent-proposal.js +0 -202
  122. package/dist/utils/api.d.ts +0 -20
  123. package/dist/utils/api.js +0 -47
  124. package/dist/utils/config.d.ts +0 -13
  125. package/dist/utils/config.js +0 -30
  126. package/dist/utils/confirm.d.ts +0 -17
  127. package/dist/utils/confirm.js +0 -40
  128. package/dist/utils/dry-run.d.ts +0 -20
  129. package/dist/utils/dry-run.js +0 -67
  130. package/dist/utils/from-file.d.ts +0 -9
  131. package/dist/utils/from-file.js +0 -72
  132. package/dist/utils/redact.d.ts +0 -14
  133. package/dist/utils/redact.js +0 -48
  134. package/dist/utils/ui.d.ts +0 -14
  135. package/dist/utils/ui.js +0 -59
  136. package/scripts/.gitkeep +0 -0
  137. package/scripts/README-gurulu-agentic-install.md +0 -114
  138. package/scripts/README-gurulu-scan.md +0 -98
  139. package/scripts/audit-cli-scopes.mjs +0 -204
  140. package/scripts/backfill-tenant-id.mjs +0 -172
  141. package/scripts/backfill-tenant-links.ts +0 -252
  142. package/scripts/backup-clickhouse.sh +0 -27
  143. package/scripts/backup-postgres.sh +0 -19
  144. package/scripts/bootstrap-runtime-schema.mjs +0 -87
  145. package/scripts/bootstrap-stripe.mjs +0 -158
  146. package/scripts/gurulu-agentic-install.lib.cjs +0 -762
  147. package/scripts/gurulu-agentic-install.mjs +0 -623
  148. package/scripts/gurulu-scan.lib.cjs +0 -1509
  149. package/scripts/gurulu-scan.mjs +0 -91
  150. package/scripts/gurulu-verify-install.lib.cjs +0 -334
  151. package/scripts/gurulu-verify-install.mjs +0 -59
  152. package/scripts/init-ssl.sh +0 -26
  153. package/scripts/migrate-flow-graph-enums.sh +0 -86
  154. package/scripts/monitor-disk.sh +0 -24
  155. package/scripts/patches/astro.patch.cjs +0 -74
  156. package/scripts/patches/auto-instrument/ast-helper.cjs +0 -480
  157. package/scripts/patches/auto-instrument/astro.cjs +0 -273
  158. package/scripts/patches/auto-instrument/express.cjs +0 -383
  159. package/scripts/patches/auto-instrument/fastify.cjs +0 -262
  160. package/scripts/patches/auto-instrument/hono.cjs +0 -392
  161. package/scripts/patches/auto-instrument/index.cjs +0 -80
  162. package/scripts/patches/auto-instrument/nestjs.cjs +0 -286
  163. package/scripts/patches/auto-instrument/nextjs-app-router.cjs +0 -345
  164. package/scripts/patches/auto-instrument/nextjs-pages.cjs +0 -361
  165. package/scripts/patches/auto-instrument/remix.cjs +0 -168
  166. package/scripts/patches/auto-instrument/sdk-helper-map.cjs +0 -241
  167. package/scripts/patches/auto-instrument/singleton-helper.cjs +0 -193
  168. package/scripts/patches/auto-instrument/sveltekit.cjs +0 -161
  169. package/scripts/patches/auto-instrument/vite-react.cjs +0 -37
  170. package/scripts/patches/auto-instrument/vue.cjs +0 -196
  171. package/scripts/patches/express.patch.cjs +0 -99
  172. package/scripts/patches/fastify.patch.cjs +0 -108
  173. package/scripts/patches/index.cjs +0 -300
  174. package/scripts/patches/nestjs.patch.cjs +0 -112
  175. package/scripts/patches/nextjs-app-router.patch.cjs +0 -97
  176. package/scripts/patches/nextjs-pages.patch.cjs +0 -97
  177. package/scripts/patches/remix.patch.cjs +0 -75
  178. package/scripts/patches/sveltekit.patch.cjs +0 -72
  179. package/scripts/patches/vite-react.patch.cjs +0 -73
  180. package/scripts/patches/vue.patch.cjs +0 -82
  181. package/scripts/renew-ssl.sh +0 -14
  182. package/scripts/resolve-migration.sh +0 -23
  183. package/scripts/seed-cli-dev-keys.mjs +0 -130
  184. package/scripts/seed-test-data.mjs +0 -391
  185. package/scripts/spike-browserless.ts +0 -65
  186. package/scripts/tenant-pivot-consistency-check.mjs +0 -205
  187. package/scripts/tenant-pivot-phase-3-cleanup.lib.cjs +0 -258
  188. package/scripts/tenant-pivot-phase-3-cleanup.mjs +0 -98
  189. package/scripts/test-identity-resolution.ts +0 -804
  190. package/scripts/validate-gurulu-schemas.mjs +0 -79
@@ -1,67 +0,0 @@
1
- "use strict";
2
- /**
3
- * 2026-05-05 DF-5 — `gurulu setup --vertical saas` zero-friction lifecycle.
4
- *
5
- * Tek komutta:
6
- * - vertical event taxonomy'sini define et (idempotent)
7
- * - default funnel'ları kur
8
- * - acquisition + revenue + retention event'lerine goal bağla
9
- *
10
- * 23 ayrı komut yerine 1.
11
- */
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.setupCommand = setupCommand;
14
- const api_client_1 = require("../api-client");
15
- const ui_1 = require("../utils/ui");
16
- async function setupCommand(args) {
17
- const vertical = (args.vertical || '').toLowerCase().trim();
18
- if (!vertical) {
19
- (0, ui_1.error)('--vertical required (e.g. saas, ecommerce, marketplace, fintech, healthcare, education, media, igaming, generic)');
20
- process.exitCode = 1;
21
- return;
22
- }
23
- if (!args.site) {
24
- (0, ui_1.error)('--site required');
25
- process.exitCode = 1;
26
- return;
27
- }
28
- const path = '/api/cli/setup/apply-template' + (args.dryRun ? '?dry_run=1' : '');
29
- const body = {
30
- siteId: args.site,
31
- vertical,
32
- includeFunnels: args.includeFunnels !== false,
33
- includeGoals: args.includeGoals !== false,
34
- };
35
- try {
36
- const res = await (0, api_client_1.cliApiJson)(path, {
37
- profile: args.profile,
38
- method: 'POST',
39
- json: body,
40
- });
41
- if (args.json) {
42
- process.stdout.write(JSON.stringify(res, null, 2) + '\n');
43
- return;
44
- }
45
- if ('dryRun' in res && res.dryRun) {
46
- const a = res.after;
47
- (0, ui_1.info)(`Dry-run preview — ${a.vertical} lifecycle taxonomy:`);
48
- process.stdout.write(`\n Events (${a.events.length}): ${a.events.join(', ')}\n`);
49
- process.stdout.write(` Funnels (${a.funnels.length}): ${a.funnels.join(', ')}\n`);
50
- process.stdout.write(` Goals (${a.goals.length}): ${a.goals.join(', ')}\n\n`);
51
- (0, ui_1.info)('Re-run without --dry-run to apply.');
52
- return;
53
- }
54
- const r = res;
55
- (0, ui_1.success)(`Applied ${r.vertical} lifecycle taxonomy to site ${args.site}`);
56
- process.stdout.write(` Events: ${r.events.created.length} created, ${r.events.skipped.length} skipped\n`);
57
- process.stdout.write(` Funnels: ${r.funnels.created.length} created, ${r.funnels.skipped.length} skipped\n`);
58
- process.stdout.write(` Goals: ${r.goals.created.length} created, ${r.goals.skipped.length} skipped\n`);
59
- if (r.events.created.length) {
60
- process.stdout.write(`\n New events: ${r.events.created.join(', ')}\n`);
61
- }
62
- }
63
- catch (err) {
64
- (0, ui_1.error)(`Setup failed: ${err?.message ?? String(err)}`);
65
- process.exitCode = 1;
66
- }
67
- }
@@ -1,18 +0,0 @@
1
- /**
2
- * Phase 18.5 W2 — `gurulu sites ...` subcommands.
3
- *
4
- * Resolves name-or-id arguments against `GET /api/cli/sites` first so users
5
- * can pass either form. All commands tolerate --json and support --yes for
6
- * non-interactive use.
7
- */
8
- export interface SitesArgs {
9
- action?: string;
10
- target?: string;
11
- name?: string;
12
- domain?: string;
13
- json?: boolean;
14
- yes?: boolean;
15
- archived?: boolean;
16
- profile?: string;
17
- }
18
- export declare function sitesCommand(args: SitesArgs): Promise<void>;
@@ -1,139 +0,0 @@
1
- "use strict";
2
- /**
3
- * Phase 18.5 W2 — `gurulu sites ...` subcommands.
4
- *
5
- * Resolves name-or-id arguments against `GET /api/cli/sites` first so users
6
- * can pass either form. All commands tolerate --json and support --yes for
7
- * non-interactive use.
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.sitesCommand = sitesCommand;
11
- const api_client_1 = require("../api-client");
12
- const ui_1 = require("../utils/ui");
13
- async function listSites(profile) {
14
- const body = await (0, api_client_1.cliApiJson)('/api/cli/sites', { profile });
15
- return body.sites || [];
16
- }
17
- async function resolveSiteId(target, profile) {
18
- if (!target)
19
- throw new Error('site name or id required');
20
- const sites = await listSites(profile);
21
- const byId = sites.find((s) => s.id === target);
22
- if (byId)
23
- return byId.id;
24
- const byName = sites.find((s) => s.name === target);
25
- if (byName)
26
- return byName.id;
27
- const prefix = sites.find((s) => s.id.startsWith(target));
28
- if (prefix)
29
- return prefix.id;
30
- throw new Error(`Site '${target}' not found.`);
31
- }
32
- async function sitesCommand(args) {
33
- const action = args.action || 'list';
34
- switch (action) {
35
- case 'list':
36
- return listCmd(args);
37
- case 'create':
38
- return createCmd(args);
39
- case 'show':
40
- return showCmd(args);
41
- case 'delete':
42
- return deleteCmd(args);
43
- case 'rotate-token':
44
- return rotateCmd(args);
45
- default:
46
- (0, ui_1.error)(`Unknown sites action: ${action}`);
47
- (0, ui_1.info)('Usage: gurulu sites [list|create|show|delete|rotate-token]');
48
- process.exit(1);
49
- }
50
- }
51
- async function listCmd(args) {
52
- const sites = await listSites(args.profile);
53
- if (args.json) {
54
- process.stdout.write(JSON.stringify(sites, null, 2) + '\n');
55
- return;
56
- }
57
- if (sites.length === 0) {
58
- (0, ui_1.info)('No sites yet. Run `gurulu sites create --name ... --domain ...`');
59
- return;
60
- }
61
- process.stdout.write(['NAME', 'ID', 'DOMAIN', 'CREATED'].join('\t') + '\n');
62
- for (const s of sites) {
63
- process.stdout.write([s.name || '-', s.id, s.domain, new Date(s.createdAt).toISOString().slice(0, 10)].join('\t') + '\n');
64
- }
65
- }
66
- async function createCmd(args) {
67
- if (!args.domain) {
68
- (0, ui_1.error)('--domain is required.');
69
- process.exit(1);
70
- }
71
- const body = await (0, api_client_1.cliApiJson)('/api/cli/sites', {
72
- method: 'POST',
73
- profile: args.profile,
74
- json: { name: args.name, domain: args.domain },
75
- });
76
- const site = body.site;
77
- if (args.json) {
78
- process.stdout.write(JSON.stringify(body, null, 2) + '\n');
79
- return;
80
- }
81
- (0, ui_1.success)('Site created');
82
- process.stdout.write(` ID: ${site.id}\n`);
83
- process.stdout.write(` Name: ${site.name || '-'}\n`);
84
- process.stdout.write(` Domain: ${site.domain}\n`);
85
- process.stdout.write(` Publishable key: ${site.publishableKey}\n\n`);
86
- (0, ui_1.info)('Add to your site:');
87
- process.stdout.write(`\n <script src="https://gurulu.io/t.js" data-gurulu-site-id="${site.id}" data-gurulu-publishable-key="${site.publishableKey}" async></script>\n\n`);
88
- (0, ui_1.info)(`Or run: ${(0, ui_1.dim)(`gurulu install --site ${site.name || site.id}`)}`);
89
- }
90
- async function showCmd(args) {
91
- if (!args.target) {
92
- (0, ui_1.error)('Usage: gurulu sites show <name-or-id>');
93
- process.exit(1);
94
- }
95
- const id = await resolveSiteId(args.target, args.profile);
96
- const body = await (0, api_client_1.cliApiJson)(`/api/cli/sites/${encodeURIComponent(id)}`, {
97
- profile: args.profile,
98
- });
99
- const site = body.site;
100
- if (args.json) {
101
- process.stdout.write(JSON.stringify(body, null, 2) + '\n');
102
- return;
103
- }
104
- process.stdout.write(`Site: ${site.name || '-'}\n`);
105
- process.stdout.write(`ID: ${site.id}\n`);
106
- process.stdout.write(`Domain: ${site.domain}\n`);
107
- process.stdout.write(`Publishable key: ${site.publishableKey}\n`);
108
- process.stdout.write(`Created: ${site.createdAt}\n`);
109
- }
110
- async function deleteCmd(args) {
111
- if (!args.target) {
112
- (0, ui_1.error)('Usage: gurulu sites delete <name-or-id>');
113
- process.exit(1);
114
- }
115
- const id = await resolveSiteId(args.target, args.profile);
116
- if (!args.yes) {
117
- const ans = await (0, ui_1.prompt)(`? Delete site '${args.target}'? [y/N] `);
118
- if (!ans.toLowerCase().startsWith('y')) {
119
- (0, ui_1.info)('Aborted.');
120
- return;
121
- }
122
- }
123
- await (0, api_client_1.cliApiJson)(`/api/cli/sites/${encodeURIComponent(id)}`, {
124
- method: 'DELETE',
125
- profile: args.profile,
126
- });
127
- (0, ui_1.success)(`Site '${args.target}' deleted.`);
128
- }
129
- async function rotateCmd(args) {
130
- if (!args.target) {
131
- (0, ui_1.error)('Usage: gurulu sites rotate-token <name-or-id>');
132
- process.exit(1);
133
- }
134
- const id = await resolveSiteId(args.target, args.profile);
135
- const body = await (0, api_client_1.cliApiJson)(`/api/cli/sites/${encodeURIComponent(id)}/rotate-token`, { method: 'POST', profile: args.profile, json: {} });
136
- (0, ui_1.warn)(`Rotating publishable key for '${args.target}'`);
137
- process.stdout.write(` New: ${body.publishableKey}\n`);
138
- (0, ui_1.warn)('Update your <script> tag before the 24h grace window expires.');
139
- }
@@ -1,18 +0,0 @@
1
- /**
2
- * Sprint E SE-B — `gurulu skad postbacks`.
3
- *
4
- * Mirror of MCP `gurulu.skad.list_postbacks`. Backend already exists at
5
- * `/api/cli/skad` (Sprint C C9).
6
- */
7
- export interface SkadArgs {
8
- action?: string;
9
- site?: string;
10
- from?: string;
11
- to?: string;
12
- goal?: string;
13
- limit?: number;
14
- format?: string;
15
- json?: boolean;
16
- profile?: string;
17
- }
18
- export declare function skadCommand(args: SkadArgs): Promise<void>;
@@ -1,53 +0,0 @@
1
- "use strict";
2
- /**
3
- * Sprint E SE-B — `gurulu skad postbacks`.
4
- *
5
- * Mirror of MCP `gurulu.skad.list_postbacks`. Backend already exists at
6
- * `/api/cli/skad` (Sprint C C9).
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.skadCommand = skadCommand;
10
- const api_client_1 = require("../api-client");
11
- const ui_1 = require("../utils/ui");
12
- async function skadCommand(args) {
13
- const action = args.action || '';
14
- switch (action) {
15
- case 'postbacks':
16
- return postbacksCmd(args);
17
- default:
18
- (0, ui_1.error)(`Unknown skad action: ${action}`);
19
- (0, ui_1.info)('Usage: gurulu skad postbacks --site=<id> [--from=...] [--goal=$purchase] [--limit=50]');
20
- process.exit(1);
21
- }
22
- }
23
- async function postbacksCmd(args) {
24
- const usp = new URLSearchParams();
25
- if (args.site)
26
- usp.set('site', args.site);
27
- if (args.from)
28
- usp.set('from', args.from);
29
- if (args.to)
30
- usp.set('to', args.to);
31
- if (args.goal)
32
- usp.set('goal', args.goal);
33
- if (args.limit)
34
- usp.set('limit', String(args.limit));
35
- const path = `/api/cli/skad${usp.toString() ? `?${usp.toString()}` : ''}`;
36
- const body = await (0, api_client_1.cliApiJson)(path, { profile: args.profile });
37
- if (args.format === 'table') {
38
- const rows = body.postbacks || [];
39
- process.stdout.write(['RECEIVED', 'NETWORK', 'GOAL', 'CV', 'WIN', 'VERIFIED'].join('\t') + '\n');
40
- for (const p of rows) {
41
- process.stdout.write([
42
- String(p.received_at ?? '-'),
43
- p.ad_network_id ?? '-',
44
- p.resolved_goal ?? '-',
45
- String(p.conversion_value ?? '-'),
46
- p.did_win ? 'yes' : 'no',
47
- p.signature_verified ? 'yes' : 'no',
48
- ].join('\t') + '\n');
49
- }
50
- return;
51
- }
52
- process.stdout.write(JSON.stringify(body, null, 2) + '\n');
53
- }
@@ -1,33 +0,0 @@
1
- /**
2
- * `gurulu sourcemap upload` — Upload source maps for error deobfuscation.
3
- *
4
- * Web (default):
5
- * gurulu sourcemap upload --release v1.0.0 --dir .next/static/
6
- *
7
- * Native (C3 — iOS dSYM / Android ProGuard):
8
- * gurulu sourcemap upload --platform=ios --version=1.4.2 --bundle-id=com.example.app --file=app.xcarchive/dSYMs/MyApp.dSYM.zip
9
- * gurulu sourcemap upload --platform=android --version=1.4.2 --bundle-id=com.example.app --file=app/build/outputs/mapping/release/mapping.txt
10
- *
11
- * The native variant POSTs a single `file` to `/api/sourcemap/native`, which
12
- * persists it under {SOURCEMAP_STORAGE_PATH}/native/{siteId}/{platform}/{release}/
13
- * and registers a `NativeSymbolFile` row.
14
- */
15
- import { loadActiveProfile } from '../config';
16
- export interface SourcemapArgs {
17
- action?: string;
18
- release?: string;
19
- /** Alias of --release for native uploads. */
20
- version?: string;
21
- dir?: string;
22
- /** Native uploads: path to the dSYM zip or `mapping.txt`. */
23
- file?: string;
24
- /** Native uploads: iOS bundleId or Android applicationId. */
25
- bundleId?: string;
26
- appId?: string;
27
- site?: string;
28
- profile?: string;
29
- json?: boolean;
30
- platform?: 'web' | 'server' | 'ios' | 'android';
31
- }
32
- export declare function sourcemapCommand(args: SourcemapArgs): Promise<void>;
33
- export declare const _loadActiveProfile: typeof loadActiveProfile;
@@ -1,204 +0,0 @@
1
- "use strict";
2
- /**
3
- * `gurulu sourcemap upload` — Upload source maps for error deobfuscation.
4
- *
5
- * Web (default):
6
- * gurulu sourcemap upload --release v1.0.0 --dir .next/static/
7
- *
8
- * Native (C3 — iOS dSYM / Android ProGuard):
9
- * gurulu sourcemap upload --platform=ios --version=1.4.2 --bundle-id=com.example.app --file=app.xcarchive/dSYMs/MyApp.dSYM.zip
10
- * gurulu sourcemap upload --platform=android --version=1.4.2 --bundle-id=com.example.app --file=app/build/outputs/mapping/release/mapping.txt
11
- *
12
- * The native variant POSTs a single `file` to `/api/sourcemap/native`, which
13
- * persists it under {SOURCEMAP_STORAGE_PATH}/native/{siteId}/{platform}/{release}/
14
- * and registers a `NativeSymbolFile` row.
15
- */
16
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
17
- if (k2 === undefined) k2 = k;
18
- var desc = Object.getOwnPropertyDescriptor(m, k);
19
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
20
- desc = { enumerable: true, get: function() { return m[k]; } };
21
- }
22
- Object.defineProperty(o, k2, desc);
23
- }) : (function(o, m, k, k2) {
24
- if (k2 === undefined) k2 = k;
25
- o[k2] = m[k];
26
- }));
27
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
28
- Object.defineProperty(o, "default", { enumerable: true, value: v });
29
- }) : function(o, v) {
30
- o["default"] = v;
31
- });
32
- var __importStar = (this && this.__importStar) || (function () {
33
- var ownKeys = function(o) {
34
- ownKeys = Object.getOwnPropertyNames || function (o) {
35
- var ar = [];
36
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
37
- return ar;
38
- };
39
- return ownKeys(o);
40
- };
41
- return function (mod) {
42
- if (mod && mod.__esModule) return mod;
43
- var result = {};
44
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
45
- __setModuleDefault(result, mod);
46
- return result;
47
- };
48
- })();
49
- Object.defineProperty(exports, "__esModule", { value: true });
50
- exports._loadActiveProfile = void 0;
51
- exports.sourcemapCommand = sourcemapCommand;
52
- const fs = __importStar(require("fs"));
53
- const path = __importStar(require("path"));
54
- const api_client_1 = require("../api-client");
55
- const config_1 = require("../config");
56
- const ui_1 = require("../utils/ui");
57
- async function sourcemapCommand(args) {
58
- const action = args.action || 'upload';
59
- if (action !== 'upload') {
60
- (0, ui_1.error)(`Unknown sourcemap action: ${action}`);
61
- (0, ui_1.info)('Usage: gurulu sourcemap upload --release <version> --dir <path>');
62
- (0, ui_1.info)(' gurulu sourcemap upload --platform=ios|android --version=<v> --bundle-id=<id> --file=<path>');
63
- process.exit(1);
64
- }
65
- if (args.platform === 'ios' || args.platform === 'android') {
66
- return uploadNativeCmd(args);
67
- }
68
- return uploadCmd(args);
69
- }
70
- async function uploadNativeCmd(args) {
71
- const version = args.version || args.release;
72
- if (!version) {
73
- (0, ui_1.error)('Missing --version flag. Example: --version=1.4.2');
74
- process.exit(1);
75
- }
76
- if (!args.file) {
77
- (0, ui_1.error)('Missing --file flag. For iOS pass the dSYM zip; for Android pass mapping.txt');
78
- process.exit(1);
79
- }
80
- const bundleId = args.bundleId || args.appId;
81
- if (!bundleId) {
82
- (0, ui_1.error)('Missing --bundle-id flag (iOS bundleId or Android applicationId)');
83
- process.exit(1);
84
- }
85
- const filePath = path.resolve(args.file);
86
- if (!fs.existsSync(filePath)) {
87
- (0, ui_1.error)(`File not found: ${filePath}`);
88
- process.exit(1);
89
- }
90
- const profile = await (0, config_1.loadActiveProfile)({ profile: args.profile });
91
- const siteId = args.site || profile.site_id;
92
- if (!siteId) {
93
- (0, ui_1.error)('Missing --site flag or default site in profile.');
94
- process.exit(1);
95
- }
96
- const fileName = path.basename(filePath);
97
- const content = fs.readFileSync(filePath);
98
- const blob = new Blob([content], { type: 'application/octet-stream' });
99
- const formData = new FormData();
100
- formData.append('platform', args.platform);
101
- formData.append('version', version);
102
- formData.append('bundleId', bundleId);
103
- formData.append('siteId', siteId);
104
- formData.append('file', blob, fileName);
105
- (0, ui_1.info)(`Uploading ${fileName} (${args.platform}) for ${bundleId}@${version}...`);
106
- const res = await (0, api_client_1.cliApi)('/api/sourcemap/native', {
107
- method: 'POST',
108
- body: formData,
109
- profile: args.profile,
110
- headers: {},
111
- });
112
- if (!res.ok) {
113
- const body = await res.json().catch(() => ({ error: 'Unknown error' }));
114
- (0, ui_1.error)(`Upload failed (${res.status}): ${body.error || res.statusText}`);
115
- process.exit(1);
116
- }
117
- const result = await res.json();
118
- if (args.json) {
119
- process.stdout.write(JSON.stringify(result, null, 2) + '\n');
120
- return;
121
- }
122
- (0, ui_1.success)(`Native symbols uploaded for ${args.platform} ${version}`);
123
- process.stdout.write((0, ui_1.dim)(` File: ${result.fileName}\n`));
124
- process.stdout.write((0, ui_1.dim)(` Path: ${result.storagePath}\n`));
125
- process.stdout.write((0, ui_1.dim)(` Size: ${result.sizeBytes} bytes\n`));
126
- }
127
- function findMapFiles(dir) {
128
- const results = [];
129
- function walk(d) {
130
- const entries = fs.readdirSync(d, { withFileTypes: true });
131
- for (const entry of entries) {
132
- const full = path.join(d, entry.name);
133
- if (entry.isDirectory()) {
134
- walk(full);
135
- }
136
- else if (entry.name.endsWith('.map')) {
137
- results.push(full);
138
- }
139
- }
140
- }
141
- walk(dir);
142
- return results;
143
- }
144
- async function uploadCmd(args) {
145
- if (!args.release) {
146
- (0, ui_1.error)('Missing --release flag. Example: gurulu sourcemap upload --release v1.0.0 --dir .next/static/');
147
- process.exit(1);
148
- }
149
- if (!args.dir) {
150
- (0, ui_1.error)('Missing --dir flag. Example: gurulu sourcemap upload --release v1.0.0 --dir .next/static/');
151
- process.exit(1);
152
- }
153
- const dir = path.resolve(args.dir);
154
- if (!fs.existsSync(dir)) {
155
- (0, ui_1.error)(`Directory not found: ${dir}`);
156
- process.exit(1);
157
- }
158
- const mapFiles = findMapFiles(dir);
159
- if (mapFiles.length === 0) {
160
- (0, ui_1.error)(`No .map files found in ${dir}`);
161
- process.exit(1);
162
- }
163
- (0, ui_1.info)(`Uploading ${mapFiles.length} source maps for ${args.release}...`);
164
- // Resolve siteId from profile config
165
- const profile = await (0, config_1.loadActiveProfile)({ profile: args.profile });
166
- const siteId = args.site || profile.site_id;
167
- if (!siteId) {
168
- (0, ui_1.error)('Missing --site flag or default site in profile. Use: gurulu sourcemap upload --site <site-id> ...');
169
- process.exit(1);
170
- }
171
- const platform = args.platform || 'web';
172
- // Build FormData
173
- const formData = new FormData();
174
- formData.append('release', args.release);
175
- formData.append('siteId', siteId);
176
- formData.append('platform', platform);
177
- for (const filePath of mapFiles) {
178
- const content = fs.readFileSync(filePath);
179
- const fileName = path.basename(filePath);
180
- const blob = new Blob([content], { type: 'application/json' });
181
- formData.append(fileName, blob, fileName);
182
- }
183
- const res = await (0, api_client_1.cliApi)('/api/tracker-config/sourcemaps', {
184
- method: 'POST',
185
- body: formData,
186
- profile: args.profile,
187
- // Do not set content-type — fetch will add multipart boundary automatically
188
- headers: {},
189
- });
190
- if (!res.ok) {
191
- const body = await res.json().catch(() => ({ error: 'Unknown error' }));
192
- (0, ui_1.error)(`Upload failed (${res.status}): ${body.error || res.statusText}`);
193
- process.exit(1);
194
- }
195
- const result = await res.json();
196
- if (args.json) {
197
- process.stdout.write(JSON.stringify(result, null, 2) + '\n');
198
- return;
199
- }
200
- (0, ui_1.success)(`${result.uploaded} source maps uploaded for release ${args.release}`);
201
- process.stdout.write((0, ui_1.dim)(` Site: ${result.siteId}\n`));
202
- process.stdout.write((0, ui_1.dim)(` Path: ${result.path}\n`));
203
- }
204
- exports._loadActiveProfile = config_1.loadActiveProfile;
@@ -1,7 +0,0 @@
1
- interface StatusArgs {
2
- site?: string;
3
- json?: boolean;
4
- profile?: string;
5
- }
6
- export declare function statusCommand(args: StatusArgs): Promise<void>;
7
- export {};
@@ -1,136 +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.statusCommand = statusCommand;
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 statusCommand(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
- if (args.json) {
24
- return statusJSON(siteId, profile, projectDir);
25
- }
26
- (0, ui_1.banner)();
27
- console.log((0, ui_1.bold)(' Status Check'));
28
- console.log('');
29
- // 1. Framework detection
30
- const framework = (0, detect_1.detectFramework)(projectDir);
31
- console.log(` ${(0, ui_1.dim)('Framework:')} ${(0, detect_1.getFrameworkDisplayName)(framework)}`);
32
- // 2. SDK installed check
33
- const pkgPath = path_1.default.join(projectDir, 'package.json');
34
- let sdkInstalled = false;
35
- if (fs_1.default.existsSync(pkgPath)) {
36
- const pkg = JSON.parse(fs_1.default.readFileSync(pkgPath, 'utf-8'));
37
- const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
38
- sdkInstalled = !!allDeps['@gurulu/web-sdk'] || !!allDeps['@gurulu/node'] || !!allDeps['@gurulu/react-native'];
39
- }
40
- // Check for mobile SDKs (non-npm based)
41
- let mobileSDKFound = false;
42
- const pubspecPath = path_1.default.join(projectDir, 'pubspec.yaml');
43
- if (fs_1.default.existsSync(pubspecPath) && fs_1.default.readFileSync(pubspecPath, 'utf-8').includes('gurulu_flutter')) {
44
- mobileSDKFound = true;
45
- }
46
- const swiftPkgPath = path_1.default.join(projectDir, 'Package.swift');
47
- if (!mobileSDKFound && fs_1.default.existsSync(swiftPkgPath) && fs_1.default.readFileSync(swiftPkgPath, 'utf-8').includes('gurulu-ios-sdk')) {
48
- mobileSDKFound = true;
49
- }
50
- for (const gFile of ['build.gradle.kts', 'build.gradle']) {
51
- const gPath = path_1.default.join(projectDir, gFile);
52
- if (!mobileSDKFound && fs_1.default.existsSync(gPath)) {
53
- const content = fs_1.default.readFileSync(gPath, 'utf-8');
54
- if (content.includes('gurulu') || content.includes('jitpack')) {
55
- mobileSDKFound = true;
56
- }
57
- }
58
- }
59
- // Also check for gurulu setup file
60
- const hasSetupFile = checkSetupFile(projectDir);
61
- const installed = sdkInstalled || hasSetupFile || mobileSDKFound;
62
- console.log(` ${(0, ui_1.dim)('SDK:')} ${installed ? (0, ui_1.green)('Installed') : (0, ui_1.yellow)('Not detected')}`);
63
- // 3. Auth check
64
- const authed = !!profile;
65
- console.log(` ${(0, ui_1.dim)('Auth:')} ${authed ? (0, ui_1.green)('Authenticated') : (0, ui_1.yellow)('Not authenticated')}`);
66
- // 4. Site check
67
- console.log(` ${(0, ui_1.dim)('Site ID:')} ${siteId ? siteId : (0, ui_1.yellow)('Not set')}`);
68
- // 5. Connection check via /api/cli/sites/:id/health
69
- if (siteId && profile) {
70
- try {
71
- const health = await (0, api_client_1.cliApiJson)(`/api/cli/sites/${siteId}/health`, { preloadedProfile: profile });
72
- if (health.healthy) {
73
- console.log(` ${(0, ui_1.dim)('Connection:')} ${(0, ui_1.green)('All services healthy')}`);
74
- }
75
- else {
76
- const failing = Object.entries(health.checks)
77
- .filter(([, s]) => s === 'fail')
78
- .map(([k]) => k)
79
- .join(', ');
80
- console.log(` ${(0, ui_1.dim)('Connection:')} ${(0, ui_1.red)(`Unhealthy: ${failing}`)}`);
81
- }
82
- }
83
- catch {
84
- console.log(` ${(0, ui_1.dim)('Connection:')} ${(0, ui_1.yellow)('Could not reach health endpoint')}`);
85
- }
86
- }
87
- else {
88
- if (!siteId) {
89
- console.log(` ${(0, ui_1.dim)('Connection:')} ${(0, ui_1.dim)('Skipped (no site)')}`);
90
- }
91
- else {
92
- console.log(` ${(0, ui_1.dim)('Connection:')} ${(0, ui_1.dim)('Skipped (not authenticated)')}`);
93
- }
94
- }
95
- console.log('');
96
- if (!installed) {
97
- (0, ui_1.info)(`Run ${(0, ui_1.cyan)('gurulu init')} to set up analytics`);
98
- }
99
- if (!authed) {
100
- (0, ui_1.info)(`Run ${(0, ui_1.cyan)('gurulu login')} to authenticate`);
101
- }
102
- console.log('');
103
- }
104
- function checkSetupFile(projectDir) {
105
- const candidates = [
106
- 'src/lib/gurulu.tsx',
107
- 'src/lib/gurulu.ts',
108
- 'src/gurulu.ts',
109
- 'src/plugins/gurulu.ts',
110
- 'plugins/gurulu.client.ts',
111
- 'src/components/Gurulu.astro',
112
- 'src/gurulu.middleware.ts',
113
- ];
114
- return candidates.some(f => fs_1.default.existsSync(path_1.default.join(projectDir, f)));
115
- }
116
- async function statusJSON(siteId, profile, projectDir) {
117
- const framework = (0, detect_1.detectFramework)(projectDir);
118
- const hasSetupFile = checkSetupFile(projectDir);
119
- const result = {
120
- framework,
121
- frameworkName: (0, detect_1.getFrameworkDisplayName)(framework),
122
- sdkDetected: hasSetupFile,
123
- authenticated: !!profile,
124
- siteId: siteId || null,
125
- connection: null,
126
- };
127
- if (siteId && profile) {
128
- try {
129
- result.connection = await (0, api_client_1.cliApiJson)(`/api/cli/sites/${siteId}/health`, { preloadedProfile: profile });
130
- }
131
- catch {
132
- // leave as null
133
- }
134
- }
135
- console.log(JSON.stringify(result, null, 2));
136
- }