@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,27 +0,0 @@
1
- /**
2
- * Phase 19.5 W2 B4 — `gurulu alerts list|show|channels list`.
3
- * Phase 20 W2 B3 — `create|update|delete` + channels create/update/delete.
4
- */
5
- export interface AlertsArgs {
6
- action?: string;
7
- sub?: string;
8
- target?: string;
9
- severity?: string;
10
- acknowledged?: string;
11
- limit?: number;
12
- json?: boolean;
13
- profile?: string;
14
- fromFile?: string;
15
- site?: string;
16
- id?: string;
17
- name?: string;
18
- type?: string;
19
- metric?: string;
20
- thresholdType?: string;
21
- thresholdValue?: number;
22
- channel?: string;
23
- note?: string;
24
- yes?: boolean;
25
- dryRun?: boolean;
26
- }
27
- export declare function alertsCommand(args: AlertsArgs): Promise<void>;
@@ -1,309 +0,0 @@
1
- "use strict";
2
- /**
3
- * Phase 19.5 W2 B4 — `gurulu alerts list|show|channels list`.
4
- * Phase 20 W2 B3 — `create|update|delete` + channels create/update/delete.
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.alertsCommand = alertsCommand;
8
- const api_client_1 = require("../api-client");
9
- const ui_1 = require("../utils/ui");
10
- const confirm_1 = require("../utils/confirm");
11
- const dry_run_1 = require("../utils/dry-run");
12
- const from_file_1 = require("../utils/from-file");
13
- async function alertsCommand(args) {
14
- const action = args.action || 'list';
15
- switch (action) {
16
- case 'list':
17
- return listCmd(args);
18
- case 'show':
19
- return showCmd(args);
20
- case 'create':
21
- return createCmd(args);
22
- case 'update':
23
- return updateCmd(args);
24
- case 'delete':
25
- return deleteCmd(args);
26
- case 'channels':
27
- return channelsCmd(args);
28
- default:
29
- (0, ui_1.error)(`Unknown alerts action: ${action}`);
30
- (0, ui_1.info)('Usage: gurulu alerts [list|show|create|update|delete|channels]');
31
- process.exit(1);
32
- }
33
- }
34
- async function listCmd(args) {
35
- const qs = new URLSearchParams();
36
- if (args.site)
37
- qs.set('siteId', args.site);
38
- if (args.severity)
39
- qs.set('severity', args.severity);
40
- if (args.acknowledged)
41
- qs.set('acknowledged', args.acknowledged);
42
- if (args.limit)
43
- qs.set('limit', String(args.limit));
44
- const path = `/api/cli/alerts${qs.toString() ? `?${qs.toString()}` : ''}`;
45
- const body = await (0, api_client_1.cliApiJson)(path, { profile: args.profile });
46
- if (args.json) {
47
- process.stdout.write(JSON.stringify(body, null, 2) + '\n');
48
- return;
49
- }
50
- const rows = body.alerts || [];
51
- if (rows.length === 0) {
52
- (0, ui_1.info)('No alerts.');
53
- return;
54
- }
55
- process.stdout.write(['ID', 'METRIC', 'SEVERITY', 'DIRECTION', 'DETECTED'].join('\t') + '\n');
56
- for (const a of rows) {
57
- process.stdout.write([a.id, a.metric, a.severity, a.direction, String(a.detectedAt)].join('\t') + '\n');
58
- }
59
- }
60
- async function showCmd(args) {
61
- if (!args.target) {
62
- (0, ui_1.error)('Usage: gurulu alerts show <id>');
63
- process.exit(1);
64
- }
65
- const body = await (0, api_client_1.cliApiJson)(`/api/cli/alerts/${encodeURIComponent(args.target)}`, { profile: args.profile });
66
- if (args.json) {
67
- process.stdout.write(JSON.stringify(body, null, 2) + '\n');
68
- return;
69
- }
70
- const a = body.alert;
71
- process.stdout.write(`ID: ${a.id}\n`);
72
- process.stdout.write(`Metric: ${a.metric}\n`);
73
- process.stdout.write(`Severity: ${a.severity}\n`);
74
- process.stdout.write(`Direction: ${a.direction}\n`);
75
- process.stdout.write(`Observed: ${a.observed}\n`);
76
- process.stdout.write(`Baseline: ${a.baseline}\n`);
77
- process.stdout.write(`zScore: ${a.zScore}\n`);
78
- process.stdout.write(`Detected: ${a.detectedAt}\n`);
79
- process.stdout.write(`Ack'd: ${a.acknowledgedAt || '-'}\n`);
80
- process.stdout.write(`Deliveries: ${(a.deliveries || []).length}\n`);
81
- }
82
- async function createCmd(args) {
83
- let payload = {};
84
- if (args.fromFile)
85
- payload = (0, from_file_1.loadFromFile)(args.fromFile);
86
- if (args.site)
87
- payload.siteId = args.site;
88
- if (args.name)
89
- payload.name = args.name;
90
- if (args.type)
91
- payload.type = args.type;
92
- if (args.metric)
93
- payload.metric = args.metric;
94
- if (args.severity)
95
- payload.severity = args.severity;
96
- if (args.thresholdType)
97
- payload.thresholdType = args.thresholdType;
98
- if (args.thresholdValue !== undefined)
99
- payload.thresholdValue = args.thresholdValue;
100
- if (args.channel)
101
- payload.channelId = args.channel;
102
- if (!payload.name) {
103
- (0, ui_1.error)('name is required (pass --name or --from-file)');
104
- process.exit(1);
105
- }
106
- if (!payload.siteId) {
107
- (0, ui_1.error)('site is required (pass --site)');
108
- process.exit(1);
109
- }
110
- if (args.dryRun) {
111
- const body = await (0, api_client_1.cliApiJson)('/api/cli/alerts?dryRun=1', {
112
- profile: args.profile,
113
- method: 'POST',
114
- json: payload,
115
- });
116
- (0, dry_run_1.printDryRun)(body, args.json);
117
- return;
118
- }
119
- const ok = await (0, confirm_1.promptConfirm)(`Create alert '${payload.name}'?`, {
120
- yes: args.yes,
121
- defaultYes: true,
122
- });
123
- if (!ok)
124
- return (0, ui_1.info)('Aborted.');
125
- const body = await (0, api_client_1.cliApiJson)('/api/cli/alerts', {
126
- profile: args.profile,
127
- method: 'POST',
128
- json: payload,
129
- });
130
- if (args.json) {
131
- process.stdout.write(JSON.stringify(body, null, 2) + '\n');
132
- return;
133
- }
134
- (0, ui_1.success)(`Created alert ${body.alert?.id ?? ''}`);
135
- }
136
- async function updateCmd(args) {
137
- const resolveTarget = args.id || args.target;
138
- if (!resolveTarget) {
139
- (0, ui_1.error)('Usage: gurulu alerts update <id> [--id ...] [--name ...] [--threshold-value ...]');
140
- process.exit(1);
141
- }
142
- const payload = {};
143
- if (args.name)
144
- payload.name = args.name;
145
- if (args.note !== undefined)
146
- payload.note = args.note;
147
- if (args.thresholdType)
148
- payload.thresholdType = args.thresholdType;
149
- if (args.thresholdValue !== undefined)
150
- payload.thresholdValue = args.thresholdValue;
151
- if (args.channel)
152
- payload.channelId = args.channel;
153
- if (args.ack === true)
154
- payload.acknowledge = true;
155
- if (args.dryRun) {
156
- const body = await (0, api_client_1.cliApiJson)(`/api/cli/alerts/${encodeURIComponent(resolveTarget)}?dryRun=1`, { profile: args.profile, method: 'PATCH', json: payload });
157
- (0, dry_run_1.printDryRun)(body, args.json);
158
- return;
159
- }
160
- const ok = await (0, confirm_1.promptConfirm)(`Update alert '${resolveTarget}'?`, {
161
- yes: args.yes,
162
- defaultYes: true,
163
- });
164
- if (!ok)
165
- return (0, ui_1.info)('Aborted.');
166
- const body = await (0, api_client_1.cliApiJson)(`/api/cli/alerts/${encodeURIComponent(resolveTarget)}`, { profile: args.profile, method: 'PATCH', json: payload });
167
- if (args.json) {
168
- process.stdout.write(JSON.stringify(body, null, 2) + '\n');
169
- return;
170
- }
171
- (0, ui_1.success)(`Updated alert ${resolveTarget}`);
172
- }
173
- async function deleteCmd(args) {
174
- const resolveTarget = args.id || args.target;
175
- if (!resolveTarget) {
176
- (0, ui_1.error)('Usage: gurulu alerts delete <id> [--id ...]');
177
- process.exit(1);
178
- }
179
- if (args.dryRun) {
180
- const body = await (0, api_client_1.cliApiJson)(`/api/cli/alerts/${encodeURIComponent(resolveTarget)}?dryRun=1`, { profile: args.profile, method: 'DELETE' });
181
- (0, dry_run_1.printDryRun)(body, args.json);
182
- return;
183
- }
184
- const ok = await (0, confirm_1.promptConfirm)(`About to delete alert '${resolveTarget}'. Continue?`, { yes: args.yes, defaultYes: false });
185
- if (!ok)
186
- return (0, ui_1.info)('Aborted.');
187
- await (0, api_client_1.cliApiJson)(`/api/cli/alerts/${encodeURIComponent(resolveTarget)}`, {
188
- profile: args.profile,
189
- method: 'DELETE',
190
- });
191
- (0, ui_1.success)(`Deleted alert ${resolveTarget}`);
192
- }
193
- // ── channels ──────────────────────────────────────────────────────────────
194
- async function channelsCmd(args) {
195
- const sub = args.sub || 'list';
196
- switch (sub) {
197
- case 'list':
198
- return channelsList(args);
199
- case 'create':
200
- return channelsCreate(args);
201
- case 'update':
202
- return channelsUpdate(args);
203
- case 'delete':
204
- return channelsDelete(args);
205
- default:
206
- (0, ui_1.error)(`Unknown alerts channels sub: ${sub}`);
207
- process.exit(1);
208
- }
209
- }
210
- async function channelsList(args) {
211
- const body = await (0, api_client_1.cliApiJson)('/api/cli/alert-channels', {
212
- profile: args.profile,
213
- });
214
- if (args.json) {
215
- process.stdout.write(JSON.stringify(body, null, 2) + '\n');
216
- return;
217
- }
218
- const rows = body.channels || [];
219
- if (rows.length === 0) {
220
- (0, ui_1.info)('No alert channels configured.');
221
- return;
222
- }
223
- process.stdout.write(['ID', 'NAME', 'TYPE', 'ACTIVE', 'LAST_DELIVERY'].join('\t') + '\n');
224
- for (const c of rows) {
225
- process.stdout.write([c.id, c.name, c.type, c.isActive ? 'yes' : 'no', String(c.lastDeliveryAt || '-')].join('\t') + '\n');
226
- }
227
- }
228
- async function channelsCreate(args) {
229
- let payload = {};
230
- if (args.fromFile)
231
- payload = (0, from_file_1.loadFromFile)(args.fromFile);
232
- if (args.name)
233
- payload.name = args.name;
234
- if (args.type)
235
- payload.type = args.type;
236
- if (!payload.name || !payload.type) {
237
- (0, ui_1.error)('name and type are required.');
238
- process.exit(1);
239
- }
240
- if (args.dryRun) {
241
- const body = await (0, api_client_1.cliApiJson)('/api/cli/alert-channels?dryRun=1', {
242
- profile: args.profile,
243
- method: 'POST',
244
- json: payload,
245
- });
246
- (0, dry_run_1.printDryRun)(body, args.json);
247
- return;
248
- }
249
- const ok = await (0, confirm_1.promptConfirm)(`Create alert channel '${payload.name}'?`, {
250
- yes: args.yes,
251
- defaultYes: true,
252
- });
253
- if (!ok)
254
- return (0, ui_1.info)('Aborted.');
255
- const body = await (0, api_client_1.cliApiJson)('/api/cli/alert-channels', {
256
- profile: args.profile,
257
- method: 'POST',
258
- json: payload,
259
- });
260
- if (args.json) {
261
- process.stdout.write(JSON.stringify(body, null, 2) + '\n');
262
- return;
263
- }
264
- (0, ui_1.success)(`Created channel ${body.channel?.id ?? ''}`);
265
- }
266
- async function channelsUpdate(args) {
267
- if (!args.target) {
268
- (0, ui_1.error)('Usage: gurulu alerts channels update <id>');
269
- process.exit(1);
270
- }
271
- let payload = {};
272
- if (args.fromFile)
273
- payload = (0, from_file_1.loadFromFile)(args.fromFile);
274
- if (args.name)
275
- payload.name = args.name;
276
- if (args.dryRun) {
277
- const body = await (0, api_client_1.cliApiJson)(`/api/cli/alert-channels/${encodeURIComponent(args.target)}?dryRun=1`, { profile: args.profile, method: 'PATCH', json: payload });
278
- (0, dry_run_1.printDryRun)(body, args.json);
279
- return;
280
- }
281
- const ok = await (0, confirm_1.promptConfirm)(`Update channel '${args.target}'?`, {
282
- yes: args.yes,
283
- defaultYes: true,
284
- });
285
- if (!ok)
286
- return (0, ui_1.info)('Aborted.');
287
- const body = await (0, api_client_1.cliApiJson)(`/api/cli/alert-channels/${encodeURIComponent(args.target)}`, { profile: args.profile, method: 'PATCH', json: payload });
288
- if (args.json) {
289
- process.stdout.write(JSON.stringify(body, null, 2) + '\n');
290
- return;
291
- }
292
- (0, ui_1.success)(`Updated channel ${args.target}`);
293
- }
294
- async function channelsDelete(args) {
295
- if (!args.target) {
296
- (0, ui_1.error)('Usage: gurulu alerts channels delete <id>');
297
- process.exit(1);
298
- }
299
- if (args.dryRun) {
300
- const body = await (0, api_client_1.cliApiJson)(`/api/cli/alert-channels/${encodeURIComponent(args.target)}?dryRun=1`, { profile: args.profile, method: 'DELETE' });
301
- (0, dry_run_1.printDryRun)(body, args.json);
302
- return;
303
- }
304
- const ok = await (0, confirm_1.promptConfirm)(`About to delete channel '${args.target}'. Continue?`, { yes: args.yes, defaultYes: false });
305
- if (!ok)
306
- return (0, ui_1.info)('Aborted.');
307
- await (0, api_client_1.cliApiJson)(`/api/cli/alert-channels/${encodeURIComponent(args.target)}`, { profile: args.profile, method: 'DELETE' });
308
- (0, ui_1.success)(`Deleted channel ${args.target}`);
309
- }
@@ -1,20 +0,0 @@
1
- /**
2
- * Phase 18.5 W2 — `gurulu api-keys ...` subcommands.
3
- *
4
- * Thin wrappers around `/api/cli/api-keys` routes. TTY-aware output: when
5
- * piped, `create` emits the raw key on stdout so scripts can consume it
6
- * with `key=$(gurulu api-keys create ...)`.
7
- */
8
- export interface ApiKeysArgs {
9
- action?: string;
10
- id?: string;
11
- name?: string;
12
- mode?: 'live' | 'test';
13
- scopes?: string;
14
- filterMode?: 'live' | 'test';
15
- json?: boolean;
16
- format?: string;
17
- yes?: boolean;
18
- profile?: string;
19
- }
20
- export declare function apiKeysCommand(args: ApiKeysArgs): Promise<void>;
@@ -1,130 +0,0 @@
1
- "use strict";
2
- /**
3
- * Phase 18.5 W2 — `gurulu api-keys ...` subcommands.
4
- *
5
- * Thin wrappers around `/api/cli/api-keys` routes. TTY-aware output: when
6
- * piped, `create` emits the raw key on stdout so scripts can consume it
7
- * with `key=$(gurulu api-keys create ...)`.
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.apiKeysCommand = apiKeysCommand;
11
- const api_client_1 = require("../api-client");
12
- const ui_1 = require("../utils/ui");
13
- function timeAgo(iso) {
14
- if (!iso)
15
- return '-';
16
- const then = new Date(iso).getTime();
17
- if (Number.isNaN(then))
18
- return '-';
19
- const s = Math.floor((Date.now() - then) / 1000);
20
- if (s < 60)
21
- return `${s}s ago`;
22
- if (s < 3600)
23
- return `${Math.floor(s / 60)}m ago`;
24
- if (s < 86400)
25
- return `${Math.floor(s / 3600)}h ago`;
26
- return `${Math.floor(s / 86400)}d ago`;
27
- }
28
- async function apiKeysCommand(args) {
29
- const action = args.action || 'list';
30
- switch (action) {
31
- case 'list':
32
- return listKeys(args);
33
- case 'create':
34
- return createKey(args);
35
- case 'revoke':
36
- return revokeKey(args);
37
- case 'rotate':
38
- return rotateKey(args);
39
- default:
40
- (0, ui_1.error)(`Unknown api-keys action: ${action}`);
41
- (0, ui_1.info)('Usage: gurulu api-keys [list|create|revoke|rotate]');
42
- process.exit(1);
43
- }
44
- }
45
- async function listKeys(args) {
46
- const body = await (0, api_client_1.cliApiJson)('/api/cli/api-keys', { profile: args.profile });
47
- let keys = body.apiKeys || [];
48
- if (args.filterMode)
49
- keys = keys.filter((k) => k.mode === args.filterMode);
50
- if (args.json) {
51
- process.stdout.write(JSON.stringify(keys, null, 2) + '\n');
52
- return;
53
- }
54
- if (keys.length === 0) {
55
- (0, ui_1.info)('No API keys yet. Run `gurulu api-keys create --name ...` to add one.');
56
- return;
57
- }
58
- process.stdout.write(['NAME', 'PREFIX', 'MODE', 'SCOPES', 'LAST USED', 'CREATED', 'STATUS'].join('\t') + '\n');
59
- for (const k of keys) {
60
- const scopes = Array.isArray(k.scopes) ? k.scopes.join(',') : '';
61
- process.stdout.write([
62
- k.name,
63
- k.prefix,
64
- k.mode,
65
- scopes,
66
- timeAgo(k.lastUsedAt),
67
- new Date(k.createdAt).toISOString().slice(0, 10),
68
- k.revokedAt ? 'revoked' : 'active',
69
- ].join('\t') + '\n');
70
- }
71
- }
72
- async function createKey(args) {
73
- if (!args.name) {
74
- (0, ui_1.error)('--name is required.');
75
- process.exit(1);
76
- }
77
- const mode = args.mode || 'live';
78
- const scopes = (args.scopes || 'admin:*').split(',').map((s) => s.trim()).filter(Boolean);
79
- const body = await (0, api_client_1.cliApiJson)('/api/cli/api-keys', {
80
- method: 'POST',
81
- profile: args.profile,
82
- json: { name: args.name, mode, scopes },
83
- });
84
- const fullKey = body.secretKey || body.full_key || '';
85
- const isTty = !!process.stdout.isTTY;
86
- if (args.json || args.format === 'json') {
87
- process.stdout.write(JSON.stringify(body, null, 2) + '\n');
88
- return;
89
- }
90
- if (!isTty) {
91
- // Pipe-friendly: just the raw key so scripts can capture it.
92
- process.stdout.write(fullKey + '\n');
93
- return;
94
- }
95
- (0, ui_1.success)('Created new API key');
96
- process.stdout.write('\n ' + fullKey + '\n\n');
97
- (0, ui_1.warn)('This key will NOT be shown again. Copy it now.');
98
- (0, ui_1.info)('Add to your CI environment:');
99
- process.stdout.write(` GURULU_SECRET_KEY=${fullKey.slice(0, 12)}...\n`);
100
- }
101
- async function revokeKey(args) {
102
- if (!args.id) {
103
- (0, ui_1.error)('Usage: gurulu api-keys revoke <id>');
104
- process.exit(1);
105
- }
106
- if (!args.yes) {
107
- const ans = await (0, ui_1.prompt)(`? Revoke API key '${args.id}' permanently? [y/N] `);
108
- if (!ans.toLowerCase().startsWith('y')) {
109
- (0, ui_1.info)('Aborted.');
110
- return;
111
- }
112
- }
113
- await (0, api_client_1.cliApiJson)(`/api/cli/api-keys/${encodeURIComponent(args.id)}`, {
114
- method: 'DELETE',
115
- profile: args.profile,
116
- });
117
- (0, ui_1.success)(`Revoked ${args.id}.`);
118
- }
119
- async function rotateKey(args) {
120
- if (!args.id) {
121
- (0, ui_1.error)('Usage: gurulu api-keys rotate <id>');
122
- process.exit(1);
123
- }
124
- const body = await (0, api_client_1.cliApiJson)(`/api/cli/api-keys/${encodeURIComponent(args.id)}/rotate`, { method: 'POST', profile: args.profile, json: {} });
125
- const fullKey = body.secretKey || '';
126
- (0, ui_1.warn)(`Rotating key ${args.id}`);
127
- (0, ui_1.info)(` Old key: valid for 24 more hours`);
128
- process.stdout.write(` New key: ${(0, ui_1.dim)(fullKey)}\n`);
129
- (0, ui_1.warn)('Update your CI/production environments before the 24h grace window expires.');
130
- }
@@ -1,22 +0,0 @@
1
- /**
2
- * Sprint E SE-B — `gurulu attribution report|compare|channels`.
3
- *
4
- * Mirror of MCP tools `gurulu.attribution.report` / `.compare` / `.channels`.
5
- * Hits new `/api/cli/attribution/*` proxy endpoints (CLI-auth, not session-auth)
6
- * so the same surface is reachable from agents and humans.
7
- */
8
- export interface AttributionArgs {
9
- action?: string;
10
- site?: string;
11
- from?: string;
12
- to?: string;
13
- range?: string;
14
- model?: string;
15
- baselineModel?: string;
16
- variantModel?: string;
17
- conversionEvent?: string;
18
- format?: string;
19
- json?: boolean;
20
- profile?: string;
21
- }
22
- export declare function attributionCommand(args: AttributionArgs): Promise<void>;
@@ -1,111 +0,0 @@
1
- "use strict";
2
- /**
3
- * Sprint E SE-B — `gurulu attribution report|compare|channels`.
4
- *
5
- * Mirror of MCP tools `gurulu.attribution.report` / `.compare` / `.channels`.
6
- * Hits new `/api/cli/attribution/*` proxy endpoints (CLI-auth, not session-auth)
7
- * so the same surface is reachable from agents and humans.
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.attributionCommand = attributionCommand;
11
- const api_client_1 = require("../api-client");
12
- const ui_1 = require("../utils/ui");
13
- async function attributionCommand(args) {
14
- const action = args.action || '';
15
- switch (action) {
16
- case 'report':
17
- return reportCmd(args);
18
- case 'compare':
19
- return compareCmd(args);
20
- case 'channels':
21
- return channelsCmd(args);
22
- default:
23
- (0, ui_1.error)(`Unknown attribution action: ${action}`);
24
- (0, ui_1.info)('Usage: gurulu attribution [report|compare|channels] --site=<id> [...]');
25
- process.exit(1);
26
- }
27
- }
28
- function buildQuery(params) {
29
- const usp = new URLSearchParams();
30
- for (const [k, v] of Object.entries(params)) {
31
- if (v === undefined || v === '' || v === null)
32
- continue;
33
- usp.set(k, String(v));
34
- }
35
- const s = usp.toString();
36
- return s ? `?${s}` : '';
37
- }
38
- function emit(args, body, table) {
39
- const format = args.format || (args.json ? 'json' : 'json');
40
- if (format === 'table') {
41
- process.stdout.write(table());
42
- return;
43
- }
44
- process.stdout.write(JSON.stringify(body, null, 2) + '\n');
45
- }
46
- async function reportCmd(args) {
47
- if (!args.site) {
48
- (0, ui_1.error)('Usage: gurulu attribution report --site=<id> [--from=ISO --to=ISO | --range=7d|30d|90d] [--model=...]');
49
- process.exit(1);
50
- }
51
- const path = `/api/cli/attribution/report${buildQuery({
52
- site: args.site,
53
- from: args.from,
54
- to: args.to,
55
- range: args.range,
56
- model: args.model,
57
- conversionEvent: args.conversionEvent,
58
- })}`;
59
- const body = await (0, api_client_1.cliApiJson)(path, { profile: args.profile });
60
- emit(args, body, () => {
61
- const rows = body.results || [];
62
- const out = [['CHANNEL', 'CREDIT', 'CONVERSIONS', 'REVENUE'].join('\t')];
63
- for (const r of rows) {
64
- out.push([r.channel ?? '-', r.credit ?? 0, r.conversions ?? 0, r.revenue ?? 0].join('\t'));
65
- }
66
- return out.join('\n') + '\n';
67
- });
68
- }
69
- async function compareCmd(args) {
70
- if (!args.site || !args.baselineModel || !args.variantModel) {
71
- (0, ui_1.error)('Usage: gurulu attribution compare --site=<id> --baseline-model=<m> --variant-model=<m>');
72
- process.exit(1);
73
- }
74
- const path = `/api/cli/attribution/compare${buildQuery({
75
- site: args.site,
76
- baselineModel: args.baselineModel,
77
- variantModel: args.variantModel,
78
- from: args.from,
79
- to: args.to,
80
- range: args.range,
81
- conversionEvent: args.conversionEvent,
82
- })}`;
83
- const body = await (0, api_client_1.cliApiJson)(path, { profile: args.profile });
84
- emit(args, body, () => {
85
- const rows = body.comparison || body.results || [];
86
- const out = [['CHANNEL', 'BASELINE', 'VARIANT', 'DELTA'].join('\t')];
87
- for (const r of rows) {
88
- out.push([r.channel ?? '-', r.baseline ?? 0, r.variant ?? 0, r.delta ?? 0].join('\t'));
89
- }
90
- return out.join('\n') + '\n';
91
- });
92
- }
93
- async function channelsCmd(args) {
94
- if (!args.site) {
95
- (0, ui_1.error)('Usage: gurulu attribution channels --site=<id>');
96
- process.exit(1);
97
- }
98
- const path = `/api/cli/attribution/channels${buildQuery({
99
- site: args.site,
100
- range: args.range,
101
- })}`;
102
- const body = await (0, api_client_1.cliApiJson)(path, { profile: args.profile });
103
- emit(args, body, () => {
104
- const rows = body.channels || [];
105
- const out = [['CHANNEL', 'SESSIONS', 'CONVERSIONS'].join('\t')];
106
- for (const r of rows) {
107
- out.push([r.channel ?? '-', r.sessions ?? 0, r.conversions ?? 0].join('\t'));
108
- }
109
- return out.join('\n') + '\n';
110
- });
111
- }
@@ -1,23 +0,0 @@
1
- /**
2
- * Phase 19.5 W2 B2 — `gurulu audiences list|show`.
3
- * Phase 20 W2 B1 — `create|update|delete` (with `--dry-run`, `--yes`).
4
- */
5
- export interface AudiencesArgs {
6
- action?: string;
7
- target?: string;
8
- json?: boolean;
9
- profile?: string;
10
- fromFile?: string;
11
- site?: string;
12
- id?: string;
13
- name?: string;
14
- description?: string;
15
- rules?: string;
16
- yes?: boolean;
17
- dryRun?: boolean;
18
- format?: 'csv' | 'json' | string;
19
- output?: string;
20
- preview?: boolean;
21
- limit?: number;
22
- }
23
- export declare function audiencesCommand(args: AudiencesArgs): Promise<void>;