@gurulu/cli 0.4.7 → 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 (182) 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 -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/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 -19
  45. package/dist/commands/chat.js +0 -118
  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 -371
  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 -77
  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/setup.d.ts +0 -21
  89. package/dist/commands/setup.js +0 -67
  90. package/dist/commands/sites.d.ts +0 -18
  91. package/dist/commands/sites.js +0 -139
  92. package/dist/commands/skad.d.ts +0 -18
  93. package/dist/commands/skad.js +0 -53
  94. package/dist/commands/sourcemap.d.ts +0 -33
  95. package/dist/commands/sourcemap.js +0 -204
  96. package/dist/commands/status.d.ts +0 -7
  97. package/dist/commands/status.js +0 -136
  98. package/dist/commands/upgrade.d.ts +0 -21
  99. package/dist/commands/upgrade.js +0 -183
  100. package/dist/commands/warehouse.d.ts +0 -20
  101. package/dist/commands/warehouse.js +0 -65
  102. package/dist/commands/warehouses.d.ts +0 -17
  103. package/dist/commands/warehouses.js +0 -182
  104. package/dist/commands/watch.d.ts +0 -45
  105. package/dist/commands/watch.js +0 -258
  106. package/dist/commands/whoami.d.ts +0 -9
  107. package/dist/commands/whoami.js +0 -50
  108. package/dist/config.d.ts +0 -75
  109. package/dist/config.js +0 -329
  110. package/dist/frameworks/detect.d.ts +0 -8
  111. package/dist/frameworks/detect.js +0 -458
  112. package/dist/install-intent-proposal.d.ts +0 -99
  113. package/dist/install-intent-proposal.js +0 -202
  114. package/dist/utils/api.d.ts +0 -20
  115. package/dist/utils/api.js +0 -47
  116. package/dist/utils/config.d.ts +0 -13
  117. package/dist/utils/config.js +0 -30
  118. package/dist/utils/confirm.d.ts +0 -17
  119. package/dist/utils/confirm.js +0 -40
  120. package/dist/utils/dry-run.d.ts +0 -20
  121. package/dist/utils/dry-run.js +0 -67
  122. package/dist/utils/from-file.d.ts +0 -9
  123. package/dist/utils/from-file.js +0 -72
  124. package/dist/utils/redact.d.ts +0 -14
  125. package/dist/utils/redact.js +0 -48
  126. package/dist/utils/ui.d.ts +0 -14
  127. package/dist/utils/ui.js +0 -59
  128. package/scripts/.gitkeep +0 -0
  129. package/scripts/README-gurulu-agentic-install.md +0 -114
  130. package/scripts/README-gurulu-scan.md +0 -98
  131. package/scripts/audit-cli-scopes.mjs +0 -204
  132. package/scripts/backfill-tenant-id.mjs +0 -172
  133. package/scripts/backfill-tenant-links.ts +0 -252
  134. package/scripts/backup-clickhouse.sh +0 -27
  135. package/scripts/backup-postgres.sh +0 -19
  136. package/scripts/bootstrap-runtime-schema.mjs +0 -87
  137. package/scripts/bootstrap-stripe.mjs +0 -158
  138. package/scripts/gurulu-agentic-install.lib.cjs +0 -762
  139. package/scripts/gurulu-agentic-install.mjs +0 -623
  140. package/scripts/gurulu-scan.lib.cjs +0 -1509
  141. package/scripts/gurulu-scan.mjs +0 -91
  142. package/scripts/gurulu-verify-install.lib.cjs +0 -334
  143. package/scripts/gurulu-verify-install.mjs +0 -59
  144. package/scripts/init-ssl.sh +0 -26
  145. package/scripts/migrate-flow-graph-enums.sh +0 -86
  146. package/scripts/monitor-disk.sh +0 -24
  147. package/scripts/patches/astro.patch.cjs +0 -74
  148. package/scripts/patches/auto-instrument/ast-helper.cjs +0 -480
  149. package/scripts/patches/auto-instrument/astro.cjs +0 -273
  150. package/scripts/patches/auto-instrument/express.cjs +0 -383
  151. package/scripts/patches/auto-instrument/fastify.cjs +0 -262
  152. package/scripts/patches/auto-instrument/hono.cjs +0 -392
  153. package/scripts/patches/auto-instrument/index.cjs +0 -80
  154. package/scripts/patches/auto-instrument/nestjs.cjs +0 -286
  155. package/scripts/patches/auto-instrument/nextjs-app-router.cjs +0 -345
  156. package/scripts/patches/auto-instrument/nextjs-pages.cjs +0 -361
  157. package/scripts/patches/auto-instrument/remix.cjs +0 -168
  158. package/scripts/patches/auto-instrument/sdk-helper-map.cjs +0 -241
  159. package/scripts/patches/auto-instrument/singleton-helper.cjs +0 -193
  160. package/scripts/patches/auto-instrument/sveltekit.cjs +0 -161
  161. package/scripts/patches/auto-instrument/vite-react.cjs +0 -37
  162. package/scripts/patches/auto-instrument/vue.cjs +0 -196
  163. package/scripts/patches/express.patch.cjs +0 -99
  164. package/scripts/patches/fastify.patch.cjs +0 -108
  165. package/scripts/patches/index.cjs +0 -300
  166. package/scripts/patches/nestjs.patch.cjs +0 -112
  167. package/scripts/patches/nextjs-app-router.patch.cjs +0 -97
  168. package/scripts/patches/nextjs-pages.patch.cjs +0 -97
  169. package/scripts/patches/remix.patch.cjs +0 -75
  170. package/scripts/patches/sveltekit.patch.cjs +0 -72
  171. package/scripts/patches/vite-react.patch.cjs +0 -73
  172. package/scripts/patches/vue.patch.cjs +0 -82
  173. package/scripts/renew-ssl.sh +0 -14
  174. package/scripts/resolve-migration.sh +0 -23
  175. package/scripts/seed-cli-dev-keys.mjs +0 -130
  176. package/scripts/seed-test-data.mjs +0 -391
  177. package/scripts/spike-browserless.ts +0 -65
  178. package/scripts/tenant-pivot-consistency-check.mjs +0 -205
  179. package/scripts/tenant-pivot-phase-3-cleanup.lib.cjs +0 -258
  180. package/scripts/tenant-pivot-phase-3-cleanup.mjs +0 -98
  181. package/scripts/test-identity-resolution.ts +0 -804
  182. 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
- }