@thinkingai/ae-cli 6.0.48 → 6.1.0-project-role-upsert.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 (82) hide show
  1. package/README.md +4 -1
  2. package/README.zh.md +4 -1
  3. package/dist/{capability-J4FU4JZW.js → capability-AXFQW5WM.js} +13 -10
  4. package/dist/{chunk-6KBBAPPP.js → chunk-JDPEVVHR.js} +4 -3
  5. package/dist/index.js +23 -13
  6. package/dist/{metadata-3J5ZAVMF.js → metadata-SOALPEA7.js} +3 -3
  7. package/dist/{personal-semantic-preference-32AAJ37M.js → personal-semantic-preference-LOF33N5X.js} +2 -2
  8. package/dist/project-semantic-RV6NA5LN.js +1113 -0
  9. package/dist/{te-analysis-WHYXHRJD.js → te-analysis-TV2YZ4IC.js} +23 -7
  10. package/dist/{te-engage-DHKNJ5BO.js → te-engage-EUVMTUDJ.js} +63 -5
  11. package/dist/te-experiment-ESEYE2SK.js +1059 -0
  12. package/package.json +2 -1
  13. package/skills/ae-analysis/SKILL.md +17 -1
  14. package/skills/ae-analysis/references/command_index.md +1 -1
  15. package/skills/ae-analysis/references/personal_semantic_preference_add.md +1 -1
  16. package/skills/ae-analysis/references/personal_semantic_preference_get.md +3 -1
  17. package/skills/ae-analysis/references/personal_semantic_preference_list.md +3 -1
  18. package/skills/ae-analysis/references/personal_semantic_preference_update.md +1 -1
  19. package/skills/ae-analysis/references/project_role_upsert.md +32 -2
  20. package/skills/ae-engage/SKILL.md +2 -0
  21. package/skills/ae-engage/references/save-flow.md +37 -1
  22. package/skills/ae-experiment/SKILL.md +117 -0
  23. package/skills/ae-experiment/references/batch_delete_experiment.md +11 -0
  24. package/skills/ae-experiment/references/batch_delete_feature.md +11 -0
  25. package/skills/ae-experiment/references/batch_delete_traffic_layer.md +11 -0
  26. package/skills/ae-experiment/references/cancel_experiment_query_by_request_id.md +11 -0
  27. package/skills/ae-experiment/references/check_experiment_ready.md +17 -0
  28. package/skills/ae-experiment/references/check_experiment_traffic_layer_conflict.md +37 -0
  29. package/skills/ae-experiment/references/delete_metric.md +13 -0
  30. package/skills/ae-experiment/references/manage_experiment.md +17 -0
  31. package/skills/ae-experiment/references/manage_feature_status.md +11 -0
  32. package/skills/ae-experiment/references/manage_feature_whitelist.md +66 -0
  33. package/skills/ae-experiment/references/manage_guardrail_metrics.md +26 -0
  34. package/skills/ae-experiment/references/query_bucket_list.md +12 -0
  35. package/skills/ae-experiment/references/query_experiment_detail.md +19 -0
  36. package/skills/ae-experiment/references/query_experiment_list.md +22 -0
  37. package/skills/ae-experiment/references/query_experiment_list_archived.md +18 -0
  38. package/skills/ae-experiment/references/query_experiment_metric_trend.md +12 -0
  39. package/skills/ae-experiment/references/query_experiment_operation_log.md +17 -0
  40. package/skills/ae-experiment/references/query_experiment_report_summary.md +12 -0
  41. package/skills/ae-experiment/references/query_experiment_sample_size_report.md +13 -0
  42. package/skills/ae-experiment/references/query_feature_detail.md +14 -0
  43. package/skills/ae-experiment/references/query_feature_list.md +12 -0
  44. package/skills/ae-experiment/references/query_feature_operation_log.md +19 -0
  45. package/skills/ae-experiment/references/query_feature_version_list.md +20 -0
  46. package/skills/ae-experiment/references/query_metric_detail.md +18 -0
  47. package/skills/ae-experiment/references/query_metric_list.md +15 -0
  48. package/skills/ae-experiment/references/query_traffic_layer_detail.md +13 -0
  49. package/skills/ae-experiment/references/query_traffic_layer_list.md +12 -0
  50. package/skills/ae-experiment/references/save_build_guide.md +39 -0
  51. package/skills/ae-experiment/references/save_experiment.md +210 -0
  52. package/skills/ae-experiment/references/save_feature.md +13 -0
  53. package/skills/ae-experiment/references/save_metric.md +91 -0
  54. package/skills/ae-experiment/references/save_submit_experiment.md +16 -0
  55. package/skills/ae-experiment/references/save_traffic_layer.md +13 -0
  56. package/skills/ae-experiment/references/save_validate.md +33 -0
  57. package/skills/ae-experiment/references/update_experiment_group.md +20 -0
  58. package/skills/ae-experiment-design/SKILL.md +149 -0
  59. package/skills/ae-experiment-design/agents/openai.yaml +4 -0
  60. package/skills/ae-experiment-design/references/client-experiment-sdk.md +147 -0
  61. package/skills/ae-experiment-design/references/experiment-creation.md +108 -0
  62. package/skills/ae-experiment-design/references/experiment-sdk-contract.md +100 -0
  63. package/skills/ae-experiment-design/references/exposure-contract.md +91 -0
  64. package/skills/ae-experiment-design/references/hybrid-experiment-sdk.md +74 -0
  65. package/skills/ae-experiment-design/references/metric-readiness.md +143 -0
  66. package/skills/ae-experiment-design/references/platform-operations.md +105 -0
  67. package/skills/ae-experiment-design/references/sdk-index.md +76 -0
  68. package/skills/ae-experiment-design/references/sdk-integration.md +114 -0
  69. package/skills/ae-experiment-design/references/sdk-troubleshooting.md +139 -0
  70. package/skills/ae-experiment-design/references/server-experiment-sdk.md +78 -0
  71. package/skills/ae-experiment-design/scripts/calculate_experiment_plan.py +450 -0
  72. package/skills/ae-experiment-insight/SKILL.md +149 -0
  73. package/skills/ae-experiment-insight/agents/openai.yaml +4 -0
  74. package/skills/ae-experiment-insight/references/decision-framework.md +69 -0
  75. package/skills/ae-experiment-insight/references/diagnostic-playbook.md +225 -0
  76. package/skills/ae-experiment-insight/references/platform-operations.md +82 -0
  77. package/skills/ae-experiment-insight/scripts/analyze_experiment.py +478 -0
  78. package/skills/ae-project-semantic/SKILL.md +193 -0
  79. package/skills/ae-project-semantic/references/query-routing-v5.md +165 -0
  80. package/skills/ae-project-semantic/references/recommendation-quality.md +68 -0
  81. package/dist/{chunk-HPLNYQPM.js → chunk-RSG4ONOI.js} +3 -3
  82. package/dist/{sync-2GTAKZYX.js → sync-YV3E66IF.js} +3 -3
@@ -0,0 +1,1059 @@
1
+ import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
+ import {
3
+ createCapabilityCommand
4
+ } from "./chunk-JDPEVVHR.js";
5
+ import "./chunk-QJQZH5GQ.js";
6
+ import {
7
+ registerCapabilityGatewayRoute
8
+ } from "./chunk-TKHSULJT.js";
9
+ import "./chunk-CZU3V3DQ.js";
10
+ import "./chunk-Y74WTIKJ.js";
11
+ import "./chunk-ATSM5XAW.js";
12
+ import "./chunk-WZ6YVQSF.js";
13
+ import "./chunk-4P355ZWB.js";
14
+
15
+ // src/commands/te-experiment/capability-shared.ts
16
+ function createExperimentCapabilityCommand(config) {
17
+ return createCapabilityCommand({
18
+ ...config,
19
+ cliService: "experiment",
20
+ gatewayDomain: "engage"
21
+ });
22
+ }
23
+ function readRequiredObject(ctx, name) {
24
+ const value = ctx.json(name);
25
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
26
+ throw new Error(`Flag --${name} must be a JSON object`);
27
+ }
28
+ return value;
29
+ }
30
+ function readRequiredStringArray(ctx, name) {
31
+ const value = ctx.json(name);
32
+ if (!Array.isArray(value) || value.length === 0 || !value.every((item) => typeof item === "string" && item.length > 0)) {
33
+ throw new Error(`Flag --${name} must be a non-empty JSON array of strings`);
34
+ }
35
+ return value;
36
+ }
37
+ function addOptionalString(input, name, value) {
38
+ if (value !== "") input[name] = value;
39
+ }
40
+ function addOptionalBoolean(input, ctx, flagName, fieldName) {
41
+ if (ctx.str(flagName) !== "") input[fieldName] = ctx.bool(flagName);
42
+ }
43
+
44
+ // src/commands/te-experiment/bucket/list.ts
45
+ var bucketList = createExperimentCapabilityCommand({
46
+ resource: "bucket",
47
+ command: "list",
48
+ capabilityId: "experiment.bucket.list",
49
+ description: "List split buckets in a project.",
50
+ flags: [{ name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." }],
51
+ risk: "read",
52
+ buildInput: (ctx) => ({ project_id: ctx.num("project-id") })
53
+ });
54
+
55
+ // src/commands/te-experiment/experiment/batch-delete.ts
56
+ var experimentBatchDelete = createExperimentCapabilityCommand({
57
+ resource: "experiment",
58
+ command: "batch-delete",
59
+ capabilityId: "experiment.experiment.batch-delete",
60
+ description: "Batch delete experiments.",
61
+ flags: [
62
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
63
+ { name: "exp-ids", type: "json", required: true, desc: "Experiment IDs as a JSON string array." }
64
+ ],
65
+ risk: "high-risk-write",
66
+ validate: (ctx) => {
67
+ readRequiredStringArray(ctx, "exp-ids");
68
+ },
69
+ buildInput: (ctx) => ({
70
+ project_id: ctx.num("project-id"),
71
+ exp_ids: readRequiredStringArray(ctx, "exp-ids")
72
+ })
73
+ });
74
+
75
+ // src/commands/te-experiment/experiment/conflict-check.ts
76
+ function buildInput(ctx) {
77
+ const input = {
78
+ project_id: ctx.num("project-id"),
79
+ feature_key_list: readRequiredStringArray(ctx, "feature-key-list"),
80
+ traffic_layer_id: ctx.str("traffic-layer-id")
81
+ };
82
+ addOptionalString(input, "exp_id", ctx.str("exp-id"));
83
+ return input;
84
+ }
85
+ var experimentConflictCheck = createExperimentCapabilityCommand({
86
+ resource: "experiment",
87
+ command: "conflict-check",
88
+ capabilityId: "experiment.experiment.conflict-check",
89
+ description: "Pre-submit check for cross-layer Feature conflicts on a non-mutex traffic layer.",
90
+ flags: [
91
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
92
+ {
93
+ name: "feature-key-list",
94
+ type: "json",
95
+ required: true,
96
+ desc: "Feature keys selected by the current experiment as a JSON string array."
97
+ },
98
+ {
99
+ name: "traffic-layer-id",
100
+ type: "string",
101
+ required: true,
102
+ desc: "Selected non-mutex traffic layer ID."
103
+ },
104
+ {
105
+ name: "exp-id",
106
+ type: "string",
107
+ required: false,
108
+ desc: "Current experiment ID when editing an existing draft."
109
+ }
110
+ ],
111
+ risk: "read",
112
+ validate: (ctx) => {
113
+ readRequiredStringArray(ctx, "feature-key-list");
114
+ if (ctx.str("traffic-layer-id") === "") {
115
+ throw new Error("Flag --traffic-layer-id is required");
116
+ }
117
+ },
118
+ buildInput
119
+ });
120
+
121
+ // src/commands/te-experiment/experiment/get.ts
122
+ var experimentGet = createExperimentCapabilityCommand({
123
+ resource: "experiment",
124
+ command: "get",
125
+ capabilityId: "experiment.experiment.get",
126
+ description: "Get one experiment by ID.",
127
+ flags: [
128
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
129
+ { name: "exp-id", type: "string", required: true, desc: "Experiment ID." }
130
+ ],
131
+ risk: "read",
132
+ buildInput: (ctx) => ({ project_id: ctx.num("project-id"), exp_id: ctx.str("exp-id") })
133
+ });
134
+
135
+ // src/commands/te-experiment/experiment/list.ts
136
+ function buildInput2(ctx) {
137
+ const input = {
138
+ project_id: ctx.num("project-id")
139
+ };
140
+ addOptionalString(input, "status", ctx.str("status"));
141
+ addOptionalString(input, "traffic_layer_id", ctx.str("traffic-layer-id"));
142
+ addOptionalString(input, "group_id", ctx.str("group-id"));
143
+ addOptionalString(input, "query_name", ctx.str("query-name"));
144
+ return input;
145
+ }
146
+ var experimentList = createExperimentCapabilityCommand({
147
+ resource: "experiment",
148
+ command: "list",
149
+ capabilityId: "experiment.experiment.list",
150
+ description: "List experiments in a project with optional status, traffic layer, group, and name filters.",
151
+ flags: [
152
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
153
+ {
154
+ name: "status",
155
+ type: "string",
156
+ required: false,
157
+ desc: "Experiment status filter: draft, testing, pending, running, paused, ended, or archive."
158
+ },
159
+ {
160
+ name: "traffic-layer-id",
161
+ type: "string",
162
+ required: false,
163
+ desc: "Traffic layer ID filter."
164
+ },
165
+ {
166
+ name: "group-id",
167
+ type: "string",
168
+ required: false,
169
+ desc: "Business group ID filter."
170
+ },
171
+ {
172
+ name: "query-name",
173
+ type: "string",
174
+ required: false,
175
+ desc: "Fuzzy match against experiment name (exp_name LIKE)."
176
+ }
177
+ ],
178
+ risk: "read",
179
+ buildInput: buildInput2
180
+ });
181
+
182
+ // src/commands/te-experiment/experiment/list-archived.ts
183
+ var experimentListArchived = createExperimentCapabilityCommand({
184
+ resource: "experiment",
185
+ command: "list-archived",
186
+ capabilityId: "experiment.experiment.list-archived",
187
+ description: "List archived experiments in a project.",
188
+ flags: [{ name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." }],
189
+ risk: "read",
190
+ buildInput: (ctx) => ({ project_id: ctx.num("project-id") })
191
+ });
192
+
193
+ // src/commands/te-experiment/experiment/manage.ts
194
+ var targetStatuses = ["draft", "testing", "pending", "running", "paused", "ended", "archive"];
195
+ function buildInput3(ctx) {
196
+ const input = {
197
+ project_id: ctx.num("project-id"),
198
+ exp_id: ctx.str("exp-id"),
199
+ target_status: ctx.str("target-status")
200
+ };
201
+ addOptionalString(input, "remark", ctx.str("remark"));
202
+ return input;
203
+ }
204
+ var experimentManage = createExperimentCapabilityCommand({
205
+ resource: "experiment",
206
+ command: "manage",
207
+ capabilityId: "experiment.experiment.manage",
208
+ description: "Update an experiment status.",
209
+ flags: [
210
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
211
+ { name: "exp-id", type: "string", required: true, desc: "Experiment ID." },
212
+ { name: "target-status", type: "string", required: true, desc: "Target experiment status." },
213
+ { name: "remark", type: "string", required: false, desc: "Operation remark." }
214
+ ],
215
+ risk: "write",
216
+ validate: (ctx) => {
217
+ const value = ctx.str("target-status");
218
+ if (!targetStatuses.includes(value)) {
219
+ throw new Error(`Flag --target-status must be one of: ${targetStatuses.join(", ")}`);
220
+ }
221
+ },
222
+ buildInput: buildInput3
223
+ });
224
+
225
+ // src/commands/te-experiment/experiment/ready-check.ts
226
+ var experimentReadyCheck = createExperimentCapabilityCommand({
227
+ resource: "experiment",
228
+ command: "ready-check",
229
+ capabilityId: "experiment.experiment.ready-check",
230
+ description: "Check whether an experiment is ready for an online status transition.",
231
+ flags: [
232
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
233
+ { name: "exp-id", type: "string", required: true, desc: "Experiment ID." }
234
+ ],
235
+ risk: "read",
236
+ buildInput: (ctx) => ({ project_id: ctx.num("project-id"), exp_id: ctx.str("exp-id") })
237
+ });
238
+
239
+ // src/commands/te-experiment/experiment/save.ts
240
+ var experimentSave = createExperimentCapabilityCommand({
241
+ resource: "experiment",
242
+ command: "save",
243
+ capabilityId: "experiment.experiment.save",
244
+ description: "Create or update an experiment draft.",
245
+ flags: [
246
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
247
+ {
248
+ name: "req",
249
+ type: "json",
250
+ required: true,
251
+ desc: "Native camelCase request; custom audiences use targeting.definitionRequest, never targetConfig."
252
+ }
253
+ ],
254
+ risk: "write",
255
+ validate: (ctx) => {
256
+ readRequiredObject(ctx, "req");
257
+ },
258
+ buildInput: (ctx) => ({ project_id: ctx.num("project-id"), req: readRequiredObject(ctx, "req") })
259
+ });
260
+
261
+ // src/commands/te-experiment/experiment/update-group.ts
262
+ var experimentUpdateGroup = createExperimentCapabilityCommand({
263
+ resource: "experiment",
264
+ command: "update-group",
265
+ capabilityId: "experiment.experiment.update-group",
266
+ description: "Update the business group of one experiment.",
267
+ flags: [
268
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
269
+ { name: "exp-id", type: "string", required: true, desc: "Experiment ID." },
270
+ {
271
+ name: "group-id",
272
+ type: "string",
273
+ required: true,
274
+ desc: 'Target business group ID. Use "0" for ungrouped.'
275
+ }
276
+ ],
277
+ risk: "write",
278
+ buildInput: (ctx) => ({
279
+ project_id: ctx.num("project-id"),
280
+ exp_id: ctx.str("exp-id"),
281
+ group_id: ctx.str("group-id")
282
+ })
283
+ });
284
+
285
+ // src/commands/te-experiment/experiment/update-metrics.ts
286
+ var METRIC_ROLES = /* @__PURE__ */ new Set(["primary", "secondary", "guardrail"]);
287
+ function readMetricBindings(ctx) {
288
+ const value = ctx.json("metrics");
289
+ if (!Array.isArray(value) || value.length === 0) {
290
+ throw new Error("Flag --metrics must be a non-empty JSON array");
291
+ }
292
+ for (let index = 0; index < value.length; index += 1) {
293
+ const item = value[index];
294
+ if (!item || typeof item !== "object" || Array.isArray(item)) {
295
+ throw new Error(`Flag --metrics[${index}] must be a JSON object`);
296
+ }
297
+ const metricId = item.metricId;
298
+ const metricRole = item.metricRole;
299
+ if (typeof metricId !== "string" || metricId.trim() === "") {
300
+ throw new Error(`Flag --metrics[${index}].metricId must be a non-empty string`);
301
+ }
302
+ if (typeof metricRole !== "string" || !METRIC_ROLES.has(metricRole)) {
303
+ throw new Error(`Flag --metrics[${index}].metricRole must be one of primary, secondary, guardrail`);
304
+ }
305
+ }
306
+ return value;
307
+ }
308
+ var experimentUpdateMetrics = createExperimentCapabilityCommand({
309
+ resource: "experiment",
310
+ command: "update-metrics",
311
+ capabilityId: "experiment.experiment.save",
312
+ description: "Replace experiment metric bindings and assign primary, secondary, or guardrail roles.",
313
+ flags: [
314
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
315
+ { name: "exp-id", type: "string", required: true, desc: "Experiment draft ID." },
316
+ {
317
+ name: "metrics",
318
+ type: "json",
319
+ required: true,
320
+ desc: "Non-empty metric binding array with camelCase metricId and metricRole fields; replaces all saved bindings."
321
+ }
322
+ ],
323
+ risk: "write",
324
+ validate: (ctx) => {
325
+ readMetricBindings(ctx);
326
+ },
327
+ buildInput: (ctx) => ({
328
+ project_id: ctx.num("project-id"),
329
+ req: { expId: ctx.str("exp-id"), metrics: readMetricBindings(ctx) }
330
+ })
331
+ });
332
+
333
+ // src/commands/te-experiment/feature/batch-delete.ts
334
+ var featureBatchDelete = createExperimentCapabilityCommand({
335
+ resource: "feature",
336
+ command: "batch-delete",
337
+ capabilityId: "experiment.feature.batch-delete",
338
+ description: "Batch delete Features.",
339
+ flags: [
340
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
341
+ { name: "req", type: "json", required: true, desc: "Native camelCase Feature delete request object." }
342
+ ],
343
+ risk: "high-risk-write",
344
+ validate: (ctx) => {
345
+ readRequiredObject(ctx, "req");
346
+ },
347
+ buildInput: (ctx) => ({ project_id: ctx.num("project-id"), req: readRequiredObject(ctx, "req") })
348
+ });
349
+
350
+ // src/commands/te-experiment/feature/get.ts
351
+ function buildInput4(ctx) {
352
+ const input = {
353
+ project_id: ctx.num("project-id"),
354
+ feature_key: ctx.str("feature-key")
355
+ };
356
+ addOptionalString(input, "version", ctx.str("version"));
357
+ return input;
358
+ }
359
+ var featureGet = createExperimentCapabilityCommand({
360
+ resource: "feature",
361
+ command: "get",
362
+ capabilityId: "experiment.feature.get",
363
+ description: "Get one Feature by key and optional version.",
364
+ flags: [
365
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
366
+ { name: "feature-key", type: "string", required: true, desc: "Feature key." },
367
+ { name: "version", type: "string", required: false, desc: "Feature version ID." }
368
+ ],
369
+ risk: "read",
370
+ buildInput: buildInput4
371
+ });
372
+
373
+ // src/commands/te-experiment/feature/list.ts
374
+ var featureList = createExperimentCapabilityCommand({
375
+ resource: "feature",
376
+ command: "list",
377
+ capabilityId: "experiment.feature.list",
378
+ description: "List Features in a project.",
379
+ flags: [{ name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." }],
380
+ risk: "read",
381
+ buildInput: (ctx) => ({ project_id: ctx.num("project-id") })
382
+ });
383
+
384
+ // src/commands/te-experiment/feature/save.ts
385
+ var featureSave = createExperimentCapabilityCommand({
386
+ resource: "feature",
387
+ command: "save",
388
+ capabilityId: "experiment.feature.save",
389
+ description: "Create or update a Feature.",
390
+ flags: [
391
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
392
+ { name: "req", type: "json", required: true, desc: "Native camelCase Feature save request object." }
393
+ ],
394
+ risk: "write",
395
+ validate: (ctx) => {
396
+ readRequiredObject(ctx, "req");
397
+ },
398
+ buildInput: (ctx) => ({ project_id: ctx.num("project-id"), req: readRequiredObject(ctx, "req") })
399
+ });
400
+
401
+ // src/commands/te-experiment/feature/update-status.ts
402
+ var featureUpdateStatus = createExperimentCapabilityCommand({
403
+ resource: "feature",
404
+ command: "update-status",
405
+ capabilityId: "experiment.feature.update-status",
406
+ description: "Update a Feature status.",
407
+ flags: [
408
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
409
+ { name: "req", type: "json", required: true, desc: "Native camelCase Feature status request object." }
410
+ ],
411
+ risk: "write",
412
+ validate: (ctx) => {
413
+ readRequiredObject(ctx, "req");
414
+ },
415
+ buildInput: (ctx) => ({ project_id: ctx.num("project-id"), req: readRequiredObject(ctx, "req") })
416
+ });
417
+
418
+ // src/commands/te-experiment/feature/version-list.ts
419
+ var featureVersionList = createExperimentCapabilityCommand({
420
+ resource: "feature",
421
+ command: "version-list",
422
+ capabilityId: "experiment.feature.version-list",
423
+ description: "List Feature version history for one Feature key.",
424
+ flags: [
425
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
426
+ { name: "feature-key", type: "string", required: true, desc: "Feature key." }
427
+ ],
428
+ risk: "read",
429
+ buildInput: (ctx) => ({
430
+ project_id: ctx.num("project-id"),
431
+ feature_key: ctx.str("feature-key")
432
+ })
433
+ });
434
+
435
+ // src/commands/te-experiment/feature/operation-log/query.ts
436
+ var featureOperationLogQuery = createExperimentCapabilityCommand({
437
+ resource: "feature operation-log",
438
+ command: "query",
439
+ capabilityId: "experiment.feature.operation-log.query",
440
+ description: "Query Feature operation logs for one Feature key.",
441
+ flags: [
442
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
443
+ { name: "feature-key", type: "string", required: true, desc: "Feature key." }
444
+ ],
445
+ risk: "read",
446
+ buildInput: (ctx) => ({
447
+ project_id: ctx.num("project-id"),
448
+ feature_key: ctx.str("feature-key")
449
+ })
450
+ });
451
+
452
+ // src/commands/te-experiment/feature-whitelist/shared.ts
453
+ function readRuleIds(ctx) {
454
+ const value = ctx.json("rule-ids");
455
+ if (!Array.isArray(value) || value.length === 0 || !value.every((item) => typeof item === "string" && item.trim() !== "")) {
456
+ throw new Error("Flag --rule-ids must be a non-empty JSON array of strings");
457
+ }
458
+ return value;
459
+ }
460
+ function readWhitelist(ctx) {
461
+ const value = ctx.json("whitelist");
462
+ if (!Array.isArray(value) || value.length === 0) {
463
+ throw new Error("Flag --whitelist must be a non-empty JSON array");
464
+ }
465
+ const bucketIds = /* @__PURE__ */ new Set();
466
+ value.forEach((bucket, bucketIndex) => {
467
+ if (!bucket || typeof bucket !== "object" || Array.isArray(bucket)) {
468
+ throw new Error(`Flag --whitelist[${bucketIndex}] must be a JSON object`);
469
+ }
470
+ const item = bucket;
471
+ if (typeof item.bucket_id !== "string" || item.bucket_id.trim() === "") {
472
+ throw new Error(`Flag --whitelist[${bucketIndex}].bucket_id must be a non-empty string`);
473
+ }
474
+ if (bucketIds.has(item.bucket_id)) {
475
+ throw new Error(`Flag --whitelist contains duplicate bucket_id: ${item.bucket_id}`);
476
+ }
477
+ bucketIds.add(item.bucket_id);
478
+ if (!Array.isArray(item.rules) || item.rules.length === 0) {
479
+ throw new Error(`Flag --whitelist[${bucketIndex}].rules must be a non-empty array`);
480
+ }
481
+ const bucketValueIds = /* @__PURE__ */ new Set();
482
+ item.rules.forEach((rule, ruleIndex) => {
483
+ if (!rule || typeof rule !== "object" || Array.isArray(rule)) {
484
+ throw new Error(`Flag --whitelist[${bucketIndex}].rules[${ruleIndex}] must be a JSON object`);
485
+ }
486
+ const row = rule;
487
+ if (!Array.isArray(row.ids) || row.ids.length === 0 || !row.ids.every((id) => typeof id === "string" && id.trim() !== "")) {
488
+ throw new Error(`Flag --whitelist[${bucketIndex}].rules[${ruleIndex}].ids must be a non-empty string array`);
489
+ }
490
+ row.ids.forEach((id) => {
491
+ if (bucketValueIds.has(id)) {
492
+ throw new Error(`Flag --whitelist bucket ${item.bucket_id} contains duplicate ID: ${id}`);
493
+ }
494
+ bucketValueIds.add(id);
495
+ });
496
+ if (typeof row.value !== "string") {
497
+ throw new Error(`Flag --whitelist[${bucketIndex}].rules[${ruleIndex}].value must be a string`);
498
+ }
499
+ });
500
+ });
501
+ return value;
502
+ }
503
+
504
+ // src/commands/te-experiment/feature-whitelist/batch-delete.ts
505
+ function buildBody(ctx) {
506
+ return { project_id: ctx.num("project-id"), rule_ids: readRuleIds(ctx) };
507
+ }
508
+ var featureWhitelistBatchDelete = createExperimentCapabilityCommand({
509
+ resource: "feature whitelist",
510
+ command: "batch-delete",
511
+ capabilityId: "experiment.feature_whitelist.batch_delete",
512
+ description: "Delete Feature whitelist rules; enabled whitelist rules are allowed and trigger RCC resync.",
513
+ flags: [
514
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
515
+ { name: "rule-ids", type: "json", required: true, desc: "Non-empty JSON array of whitelist rule IDs." }
516
+ ],
517
+ risk: "high-risk-write",
518
+ validate: (ctx) => {
519
+ buildBody(ctx);
520
+ },
521
+ buildInput: buildBody
522
+ });
523
+
524
+ // src/commands/te-experiment/feature-whitelist/list.ts
525
+ function buildInput5(ctx) {
526
+ return {
527
+ project_id: ctx.num("project-id"),
528
+ feature_key: ctx.str("feature-key")
529
+ };
530
+ }
531
+ var featureWhitelistList = createExperimentCapabilityCommand({
532
+ resource: "feature whitelist",
533
+ command: "list",
534
+ capabilityId: "experiment.feature_whitelist.list",
535
+ description: "List explicit whitelist rules for one Feature.",
536
+ flags: [
537
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
538
+ { name: "feature-key", type: "string", required: true, desc: "Existing Feature key." }
539
+ ],
540
+ risk: "read",
541
+ buildInput: buildInput5
542
+ });
543
+
544
+ // src/commands/te-experiment/feature-whitelist/save.ts
545
+ function buildInput6(ctx) {
546
+ const ruleId = ctx.str("rule-id").trim();
547
+ const status = ctx.str("status").trim() || "draft";
548
+ if (!["draft", "enable", "disable"].includes(status)) {
549
+ throw new Error("Flag --status must be one of draft, enable, disable");
550
+ }
551
+ const input = {
552
+ project_id: ctx.num("project-id"),
553
+ feature_key: ctx.str("feature-key"),
554
+ whitelist: readWhitelist(ctx),
555
+ status
556
+ };
557
+ if (ruleId) input.rule_id = ruleId;
558
+ const priority = ctx.str("priority");
559
+ if (priority !== "") input.priority = ctx.num("priority");
560
+ return input;
561
+ }
562
+ var featureWhitelistSave = createExperimentCapabilityCommand({
563
+ resource: "feature whitelist",
564
+ command: "save",
565
+ capabilityId: "experiment.feature_whitelist.save",
566
+ description: "Create or modify a Feature whitelist rule and optionally enable it.",
567
+ flags: [
568
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
569
+ { name: "feature-key", type: "string", required: true, desc: "Existing Feature key." },
570
+ { name: "rule-id", type: "string", desc: "Existing whitelist rule ID; omit to create a new rule." },
571
+ { name: "priority", type: "number", desc: "Rule priority; omitted create requests use the server-assigned next priority." },
572
+ { name: "status", type: "string", default: "draft", desc: "Rule status: draft, enable, or disable." },
573
+ {
574
+ name: "whitelist",
575
+ type: "json",
576
+ required: true,
577
+ desc: 'Whitelist bucket array: [{"bucket_id":"#user_id","rules":[{"ids":["u1"],"value":"on"}]}].'
578
+ }
579
+ ],
580
+ risk: "write",
581
+ validate: (ctx) => {
582
+ buildInput6(ctx);
583
+ },
584
+ buildInput: buildInput6
585
+ });
586
+
587
+ // src/commands/te-experiment/feature-whitelist/update-status.ts
588
+ function buildBody2(ctx) {
589
+ const status = ctx.str("status");
590
+ if (!["enable", "disable"].includes(status)) {
591
+ throw new Error("Flag --status must be one of enable, disable");
592
+ }
593
+ return { project_id: ctx.num("project-id"), rule_id: ctx.str("rule-id"), status };
594
+ }
595
+ var featureWhitelistUpdateStatus = createExperimentCapabilityCommand({
596
+ resource: "feature whitelist",
597
+ command: "update-status",
598
+ capabilityId: "experiment.feature_whitelist.update_status",
599
+ description: "Enable or disable a Feature whitelist rule; enabled rules sync an online Feature to RCC.",
600
+ flags: [
601
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
602
+ { name: "rule-id", type: "string", required: true, desc: "Whitelist rule ID." },
603
+ { name: "status", type: "string", required: true, desc: "Target status: enable or disable." }
604
+ ],
605
+ risk: "write",
606
+ validate: (ctx) => {
607
+ buildBody2(ctx);
608
+ },
609
+ buildInput: buildBody2
610
+ });
611
+
612
+ // src/commands/te-experiment/metric/delete.ts
613
+ var metricDelete = createExperimentCapabilityCommand({
614
+ resource: "metric",
615
+ command: "delete",
616
+ capabilityId: "experiment.metric.delete",
617
+ description: "Delete one experiment metric.",
618
+ flags: [
619
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
620
+ { name: "metric-id", type: "string", required: true, desc: "Metric ID." }
621
+ ],
622
+ risk: "high-risk-write",
623
+ buildInput: (ctx) => ({ project_id: ctx.num("project-id"), metric_id: ctx.str("metric-id") })
624
+ });
625
+
626
+ // src/commands/te-experiment/metric/get.ts
627
+ var metricGet = createExperimentCapabilityCommand({
628
+ resource: "metric",
629
+ command: "get",
630
+ capabilityId: "experiment.metric.get",
631
+ description: "Get one experiment metric by ID.",
632
+ flags: [
633
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
634
+ { name: "metric-id", type: "string", required: true, desc: "Metric ID." }
635
+ ],
636
+ risk: "read",
637
+ buildInput: (ctx) => ({ project_id: ctx.num("project-id"), metric_id: ctx.str("metric-id") })
638
+ });
639
+
640
+ // src/commands/te-experiment/metric/list.ts
641
+ var metricList = createExperimentCapabilityCommand({
642
+ resource: "metric",
643
+ command: "list",
644
+ capabilityId: "experiment.metric.list",
645
+ description: "List experiment metrics in a project.",
646
+ flags: [{ name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." }],
647
+ risk: "read",
648
+ buildInput: (ctx) => ({ project_id: ctx.num("project-id") })
649
+ });
650
+
651
+ // src/commands/te-experiment/metric/save.ts
652
+ var aggregations = /* @__PURE__ */ new Set([
653
+ "total_count",
654
+ "user_count",
655
+ "active_days",
656
+ "sum",
657
+ "avg",
658
+ "max",
659
+ "distinct_count"
660
+ ]);
661
+ var propertyAggregations = /* @__PURE__ */ new Set(["sum", "avg", "max", "distinct_count"]);
662
+ var metricDefinitionFields = /* @__PURE__ */ new Set([
663
+ "type",
664
+ "event",
665
+ "aggregation",
666
+ "property",
667
+ "filters"
668
+ ]);
669
+ function validateMetricFilters(rawFilters) {
670
+ if (rawFilters === void 0) return;
671
+ if (!rawFilters || typeof rawFilters !== "object" || Array.isArray(rawFilters)) {
672
+ throw new Error("Flag --req.metricDefinition.filters must be a JSON object");
673
+ }
674
+ const filters = rawFilters;
675
+ if (!["and", "or"].includes(String(filters.relation))) {
676
+ throw new Error("Flag --req.metricDefinition.filters.relation must be one of: and, or");
677
+ }
678
+ if (!Array.isArray(filters.items) || filters.items.length === 0) {
679
+ throw new Error("Flag --req.metricDefinition.filters.items must be a non-empty array");
680
+ }
681
+ filters.items.forEach((rawItem, index) => {
682
+ const path = `Flag --req.metricDefinition.filters.items[${index}]`;
683
+ if (!rawItem || typeof rawItem !== "object" || Array.isArray(rawItem)) {
684
+ throw new Error(`${path} must be a JSON object`);
685
+ }
686
+ const item = rawItem;
687
+ const field = item.field;
688
+ const validField = typeof field === "string" && field.trim() !== "" || Boolean(field && typeof field === "object" && !Array.isArray(field) && typeof field.name === "string" && String(field.name).trim() !== "");
689
+ if (!validField) throw new Error(`${path}.field is required`);
690
+ if (typeof item.operator !== "string" || item.operator.trim() === "") {
691
+ throw new Error(`${path}.operator is required and expresses the property comparison`);
692
+ }
693
+ if (!Array.isArray(item.values)) {
694
+ throw new Error(`${path}.values must be an array containing the comparison value(s)`);
695
+ }
696
+ });
697
+ }
698
+ function validateMetricSaveRequest(req) {
699
+ const rawDefinition = req.metricDefinition;
700
+ if (rawDefinition === void 0 && req.update === true) return;
701
+ if (!rawDefinition || typeof rawDefinition !== "object" || Array.isArray(rawDefinition)) {
702
+ throw new Error("Flag --req.metricDefinition must be a JSON object");
703
+ }
704
+ const definition = rawDefinition;
705
+ for (const field of Object.keys(definition)) {
706
+ if (!metricDefinitionFields.has(field)) {
707
+ throw new Error(`Flag --req.metricDefinition.${field} is not supported`);
708
+ }
709
+ }
710
+ if (definition.type !== "event") {
711
+ throw new Error("Flag --req.metricDefinition.type must be event");
712
+ }
713
+ if (typeof definition.event !== "string" || definition.event.trim() === "") {
714
+ throw new Error("Flag --req.metricDefinition.event is required");
715
+ }
716
+ if (typeof definition.aggregation !== "string" || !aggregations.has(definition.aggregation)) {
717
+ throw new Error(`Flag --req.metricDefinition.aggregation must be one of: ${[...aggregations].join(", ")}`);
718
+ }
719
+ if (propertyAggregations.has(definition.aggregation) && (typeof definition.property !== "string" || definition.property.trim() === "")) {
720
+ throw new Error(`Flag --req.metricDefinition.property is required for ${definition.aggregation}`);
721
+ }
722
+ validateMetricFilters(definition.filters);
723
+ }
724
+ var metricSave = createExperimentCapabilityCommand({
725
+ resource: "metric",
726
+ command: "save",
727
+ capabilityId: "experiment.metric.save",
728
+ description: "Create or update an experiment metric.",
729
+ flags: [
730
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
731
+ {
732
+ name: "req",
733
+ type: "json",
734
+ required: true,
735
+ desc: "Native camelCase request. Property comparisons use metricDefinition.filters={relation,items:[{field,operator,values}]}. Never use metricConfig, calcType, or raw filts."
736
+ }
737
+ ],
738
+ risk: "write",
739
+ validate: (ctx) => {
740
+ validateMetricSaveRequest(readRequiredObject(ctx, "req"));
741
+ },
742
+ buildInput: (ctx) => ({ project_id: ctx.num("project-id"), req: readRequiredObject(ctx, "req") })
743
+ });
744
+
745
+ // src/commands/te-experiment/operation-log/query.ts
746
+ var operationLogQuery = createExperimentCapabilityCommand({
747
+ resource: "operation-log",
748
+ command: "query",
749
+ capabilityId: "experiment.operation-log.query",
750
+ description: "Query full operation logs for one experiment, including remark and structured changes.",
751
+ flags: [
752
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
753
+ { name: "exp-id", type: "string", required: true, desc: "Experiment ID." }
754
+ ],
755
+ risk: "read",
756
+ buildInput: (ctx) => ({
757
+ project_id: ctx.num("project-id"),
758
+ exp_id: ctx.str("exp-id")
759
+ })
760
+ });
761
+
762
+ // src/commands/te-experiment/save/build-guide.ts
763
+ var saveBuildGuide = createExperimentCapabilityCommand({
764
+ resource: "save",
765
+ command: "build-guide",
766
+ capabilityId: "experiment.save.build-guide",
767
+ description: "Build a read-only save guide for feature, traffic layer, experiment, or metric saves. WARNING: data.guide.example_args.req keys are recursively snake_cased for display; do not copy them into --req. Final save DTOs require camelCase (e.g. expName). Prefer capability inspect <final-save-id> input_schema.properties.req.",
768
+ flags: [
769
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
770
+ {
771
+ name: "operation-mode",
772
+ type: "string",
773
+ required: true,
774
+ desc: "Save operation mode: save_feature, save_traffic_layer, save_experiment, or save_metric."
775
+ }
776
+ ],
777
+ risk: "read",
778
+ validate: (ctx) => {
779
+ const mode = ctx.str("operation-mode");
780
+ if (!["save_feature", "save_traffic_layer", "save_experiment", "save_metric"].includes(mode)) {
781
+ throw new Error("Flag --operation-mode must be one of: save_feature, save_traffic_layer, save_experiment, save_metric");
782
+ }
783
+ },
784
+ buildInput: (ctx) => ({
785
+ project_id: ctx.num("project-id"),
786
+ operation_mode: ctx.str("operation-mode")
787
+ })
788
+ });
789
+
790
+ // src/commands/te-experiment/save/validate.ts
791
+ var saveValidate = createExperimentCapabilityCommand({
792
+ resource: "save",
793
+ command: "validate",
794
+ capabilityId: "experiment.save.validate",
795
+ description: "Dry-run validation for feature, traffic layer, experiment, or metric save requests. WARNING: valid=true is not a final-save schema pass; snake_case req keys (e.g. exp_name) can still fail on experiment \u2026 save. Always pass camelCase --req. Do not copy example_args.req key casing from this response.",
796
+ flags: [
797
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
798
+ {
799
+ name: "operation-mode",
800
+ type: "string",
801
+ required: true,
802
+ desc: "Save operation mode: save_feature, save_traffic_layer, save_experiment, or save_metric."
803
+ },
804
+ {
805
+ name: "req",
806
+ type: "json",
807
+ required: true,
808
+ desc: "Candidate camelCase save request object (expName/metricId/\u2026). Never use snake_case DTO keys."
809
+ }
810
+ ],
811
+ risk: "read",
812
+ validate: (ctx) => {
813
+ const mode = ctx.str("operation-mode");
814
+ if (!["save_feature", "save_traffic_layer", "save_experiment", "save_metric"].includes(mode)) {
815
+ throw new Error("Flag --operation-mode must be one of: save_feature, save_traffic_layer, save_experiment, save_metric");
816
+ }
817
+ readRequiredObject(ctx, "req");
818
+ },
819
+ buildInput: (ctx) => ({
820
+ project_id: ctx.num("project-id"),
821
+ operation_mode: ctx.str("operation-mode"),
822
+ req: readRequiredObject(ctx, "req")
823
+ })
824
+ });
825
+
826
+ // src/commands/te-experiment/report/metric-trend.ts
827
+ var reportMetricTrend = createExperimentCapabilityCommand({
828
+ resource: "report",
829
+ command: "metric-trend",
830
+ capabilityId: "experiment.report.metric-trend",
831
+ description: "Query an experiment metric trend report for a date range.",
832
+ flags: [
833
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
834
+ { name: "exp-id", type: "string", required: true, desc: "Experiment ID." },
835
+ { name: "metric-id", type: "string", required: true, desc: "Metric ID." },
836
+ { name: "start-time", type: "string", required: true, desc: "Start date in yyyy-MM-dd format." },
837
+ { name: "end-time", type: "string", required: true, desc: "End date in yyyy-MM-dd format." },
838
+ {
839
+ name: "request-id",
840
+ type: "string",
841
+ required: false,
842
+ desc: "Optional caller-supplied cli_<32 lowercase hex> lifecycle ID. ae-cli generates and prints one before dispatch when omitted."
843
+ },
844
+ { name: "force-refresh", type: "boolean", required: false, desc: "Force refresh report data." }
845
+ ],
846
+ risk: "read",
847
+ buildInput: (ctx) => {
848
+ const input = {
849
+ project_id: ctx.num("project-id"),
850
+ exp_id: ctx.str("exp-id"),
851
+ metric_id: ctx.str("metric-id"),
852
+ start_time: ctx.str("start-time"),
853
+ end_time: ctx.str("end-time")
854
+ };
855
+ addOptionalString(input, "request_id", ctx.str("request-id"));
856
+ addOptionalBoolean(input, ctx, "force-refresh", "force_refresh");
857
+ return input;
858
+ }
859
+ });
860
+
861
+ // src/commands/te-experiment/report/sample-size.ts
862
+ var reportSampleSize = createExperimentCapabilityCommand({
863
+ resource: "report",
864
+ command: "sample-size",
865
+ capabilityId: "experiment.report.sample-size",
866
+ description: "Query an experiment sample-size report for a date range.",
867
+ flags: [
868
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
869
+ { name: "exp-id", type: "string", required: true, desc: "Experiment ID." },
870
+ { name: "start-time", type: "string", required: true, desc: "Start date in yyyy-MM-dd format." },
871
+ { name: "end-time", type: "string", required: true, desc: "End date in yyyy-MM-dd format." },
872
+ {
873
+ name: "request-id",
874
+ type: "string",
875
+ required: false,
876
+ desc: "Optional caller-supplied cli_<32 lowercase hex> lifecycle ID. ae-cli generates and prints one before dispatch when omitted."
877
+ },
878
+ { name: "force-refresh", type: "boolean", required: false, desc: "Force refresh report data." },
879
+ { name: "by-hour", type: "boolean", required: false, desc: "Break results down by hour." }
880
+ ],
881
+ risk: "read",
882
+ buildInput: (ctx) => {
883
+ const input = {
884
+ project_id: ctx.num("project-id"),
885
+ exp_id: ctx.str("exp-id"),
886
+ start_time: ctx.str("start-time"),
887
+ end_time: ctx.str("end-time")
888
+ };
889
+ addOptionalString(input, "request_id", ctx.str("request-id"));
890
+ addOptionalBoolean(input, ctx, "force-refresh", "force_refresh");
891
+ addOptionalBoolean(input, ctx, "by-hour", "by_hour");
892
+ return input;
893
+ }
894
+ });
895
+
896
+ // src/commands/te-experiment/report/summary.ts
897
+ var reportSummary = createExperimentCapabilityCommand({
898
+ resource: "report",
899
+ command: "summary",
900
+ capabilityId: "experiment.report.summary",
901
+ description: "Query an experiment report summary.",
902
+ flags: [
903
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
904
+ { name: "exp-id", type: "string", required: true, desc: "Experiment ID." },
905
+ { name: "force-refresh", type: "boolean", required: false, desc: "Force refresh report data." }
906
+ ],
907
+ risk: "read",
908
+ buildInput: (ctx) => {
909
+ const input = {
910
+ project_id: ctx.num("project-id"),
911
+ exp_id: ctx.str("exp-id")
912
+ };
913
+ addOptionalBoolean(input, ctx, "force-refresh", "force_refresh");
914
+ return input;
915
+ }
916
+ });
917
+
918
+ // src/commands/te-experiment/traffic-layer/batch-delete.ts
919
+ var trafficLayerBatchDelete = createExperimentCapabilityCommand({
920
+ resource: "traffic-layer",
921
+ command: "batch-delete",
922
+ capabilityId: "experiment.traffic-layer.batch-delete",
923
+ description: "Batch delete traffic layers.",
924
+ flags: [
925
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
926
+ { name: "layer-ids", type: "json", required: true, desc: "Traffic layer IDs as a JSON string array." }
927
+ ],
928
+ risk: "high-risk-write",
929
+ validate: (ctx) => {
930
+ readRequiredStringArray(ctx, "layer-ids");
931
+ },
932
+ buildInput: (ctx) => ({
933
+ project_id: ctx.num("project-id"),
934
+ layer_ids: readRequiredStringArray(ctx, "layer-ids")
935
+ })
936
+ });
937
+
938
+ // src/commands/te-experiment/traffic-layer/get.ts
939
+ var trafficLayerGet = createExperimentCapabilityCommand({
940
+ resource: "traffic-layer",
941
+ command: "get",
942
+ capabilityId: "experiment.traffic-layer.get",
943
+ description: "Get one traffic layer by ID.",
944
+ flags: [
945
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
946
+ { name: "layer-id", type: "string", required: true, desc: "Traffic layer ID." }
947
+ ],
948
+ risk: "read",
949
+ buildInput: (ctx) => ({ project_id: ctx.num("project-id"), layer_id: ctx.str("layer-id") })
950
+ });
951
+
952
+ // src/commands/te-experiment/traffic-layer/list.ts
953
+ var trafficLayerList = createExperimentCapabilityCommand({
954
+ resource: "traffic-layer",
955
+ command: "list",
956
+ capabilityId: "experiment.traffic-layer.list",
957
+ description: "List traffic layers in a project.",
958
+ flags: [{ name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." }],
959
+ risk: "read",
960
+ buildInput: (ctx) => ({ project_id: ctx.num("project-id") })
961
+ });
962
+
963
+ // src/commands/te-experiment/traffic-layer/save.ts
964
+ var trafficLayerSave = createExperimentCapabilityCommand({
965
+ resource: "traffic-layer",
966
+ command: "save",
967
+ capabilityId: "experiment.traffic-layer.save",
968
+ description: "Create or update a traffic layer.",
969
+ flags: [
970
+ { name: "project-id", type: "number", required: true, alias: "p", desc: "Numeric project ID." },
971
+ { name: "req", type: "json", required: true, desc: "Native camelCase traffic layer save request object." }
972
+ ],
973
+ risk: "write",
974
+ validate: (ctx) => {
975
+ readRequiredObject(ctx, "req");
976
+ },
977
+ buildInput: (ctx) => ({ project_id: ctx.num("project-id"), req: readRequiredObject(ctx, "req") })
978
+ });
979
+
980
+ // src/commands/te-experiment/index.ts
981
+ registerCapabilityGatewayRoute("experiment", { gatewayDomain: "engage" });
982
+ var commands = [
983
+ experimentSave,
984
+ experimentList,
985
+ experimentListArchived,
986
+ experimentGet,
987
+ experimentReadyCheck,
988
+ experimentConflictCheck,
989
+ experimentManage,
990
+ experimentUpdateGroup,
991
+ experimentUpdateMetrics,
992
+ experimentBatchDelete,
993
+ operationLogQuery,
994
+ saveBuildGuide,
995
+ saveValidate,
996
+ trafficLayerSave,
997
+ trafficLayerGet,
998
+ trafficLayerList,
999
+ trafficLayerBatchDelete,
1000
+ reportSummary,
1001
+ reportSampleSize,
1002
+ reportMetricTrend,
1003
+ metricSave,
1004
+ metricGet,
1005
+ metricList,
1006
+ metricDelete,
1007
+ featureSave,
1008
+ featureUpdateStatus,
1009
+ featureGet,
1010
+ featureList,
1011
+ featureVersionList,
1012
+ featureOperationLogQuery,
1013
+ featureBatchDelete,
1014
+ featureWhitelistList,
1015
+ featureWhitelistSave,
1016
+ featureWhitelistUpdateStatus,
1017
+ featureWhitelistBatchDelete,
1018
+ bucketList
1019
+ ];
1020
+ var te_experiment_default = commands;
1021
+ export {
1022
+ bucketList,
1023
+ te_experiment_default as default,
1024
+ experimentBatchDelete,
1025
+ experimentConflictCheck,
1026
+ experimentGet,
1027
+ experimentList,
1028
+ experimentListArchived,
1029
+ experimentManage,
1030
+ experimentReadyCheck,
1031
+ experimentSave,
1032
+ experimentUpdateGroup,
1033
+ experimentUpdateMetrics,
1034
+ featureBatchDelete,
1035
+ featureGet,
1036
+ featureList,
1037
+ featureOperationLogQuery,
1038
+ featureSave,
1039
+ featureUpdateStatus,
1040
+ featureVersionList,
1041
+ featureWhitelistBatchDelete,
1042
+ featureWhitelistList,
1043
+ featureWhitelistSave,
1044
+ featureWhitelistUpdateStatus,
1045
+ metricDelete,
1046
+ metricGet,
1047
+ metricList,
1048
+ metricSave,
1049
+ operationLogQuery,
1050
+ reportMetricTrend,
1051
+ reportSampleSize,
1052
+ reportSummary,
1053
+ saveBuildGuide,
1054
+ saveValidate,
1055
+ trafficLayerBatchDelete,
1056
+ trafficLayerGet,
1057
+ trafficLayerList,
1058
+ trafficLayerSave
1059
+ };