@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,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>;